1// Copyright 2014 the V8 project authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5'use strict'; 6 7 8// This file relies on the fact that the following declaration has been made 9// in runtime.js: 10// var $String = global.String; 11 12 13var stringIteratorIteratedStringSymbol = 14 GLOBAL_PRIVATE("StringIterator#iteratedString"); 15var stringIteratorNextIndexSymbol = GLOBAL_PRIVATE("StringIterator#next"); 16 17 18function StringIterator() {} 19 20 21// 21.1.5.1 CreateStringIterator Abstract Operation 22function CreateStringIterator(string) { 23 var s = TO_STRING_INLINE(string); 24 var iterator = new StringIterator; 25 SET_PRIVATE(iterator, stringIteratorIteratedStringSymbol, s); 26 SET_PRIVATE(iterator, stringIteratorNextIndexSymbol, 0); 27 return iterator; 28} 29 30 31// 21.1.5.2.2 %StringIteratorPrototype%[@@iterator] 32function StringIteratorIterator() { 33 return this; 34} 35 36 37// 21.1.5.2.1 %StringIteratorPrototype%.next( ) 38function StringIteratorNext() { 39 var iterator = ToObject(this); 40 41 if (!HAS_DEFINED_PRIVATE(iterator, stringIteratorNextIndexSymbol)) { 42 throw MakeTypeError('incompatible_method_receiver', 43 ['String Iterator.prototype.next']); 44 } 45 46 var s = GET_PRIVATE(iterator, stringIteratorIteratedStringSymbol); 47 if (IS_UNDEFINED(s)) { 48 return CreateIteratorResultObject(UNDEFINED, true); 49 } 50 51 var position = GET_PRIVATE(iterator, stringIteratorNextIndexSymbol); 52 var length = TO_UINT32(s.length); 53 54 if (position >= length) { 55 SET_PRIVATE(iterator, stringIteratorIteratedStringSymbol, 56 UNDEFINED); 57 return CreateIteratorResultObject(UNDEFINED, true); 58 } 59 60 var first = %_StringCharCodeAt(s, position); 61 var resultString = %_StringCharFromCode(first); 62 position++; 63 64 if (first >= 0xD800 && first <= 0xDBFF && position < length) { 65 var second = %_StringCharCodeAt(s, position); 66 if (second >= 0xDC00 && second <= 0xDFFF) { 67 resultString += %_StringCharFromCode(second); 68 position++; 69 } 70 } 71 72 SET_PRIVATE(iterator, stringIteratorNextIndexSymbol, position); 73 74 return CreateIteratorResultObject(resultString, false); 75} 76 77 78function SetUpStringIterator() { 79 %CheckIsBootstrapping(); 80 81 %FunctionSetPrototype(StringIterator, new $Object()); 82 %FunctionSetInstanceClassName(StringIterator, 'String Iterator'); 83 84 InstallFunctions(StringIterator.prototype, DONT_ENUM, $Array( 85 'next', StringIteratorNext 86 )); 87 %FunctionSetName(StringIteratorIterator, '[Symbol.iterator]'); 88 %AddNamedProperty(StringIterator.prototype, symbolIterator, 89 StringIteratorIterator, DONT_ENUM); 90} 91SetUpStringIterator(); 92 93 94// 21.1.3.27 String.prototype [ @@iterator ]( ) 95function StringPrototypeIterator() { 96 return CreateStringIterator(this); 97} 98 99 100function ExtendStringPrototypeWithIterator() { 101 %CheckIsBootstrapping(); 102 103 %FunctionSetName(StringPrototypeIterator, '[Symbol.iterator]'); 104 %AddNamedProperty($String.prototype, symbolIterator, 105 StringPrototypeIterator, DONT_ENUM); 106} 107ExtendStringPrototypeWithIterator(); 108