1// Copyright 2019 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 5namespace string { 6 7macro NewJSStringIterator(implicit context: Context)( 8 string: String, nextIndex: Smi): JSStringIterator { 9 return new JSStringIterator{ 10 map: GetInitialStringIteratorMap(), 11 properties_or_hash: kEmptyFixedArray, 12 elements: kEmptyFixedArray, 13 string: string, 14 index: nextIndex 15 }; 16} 17 18// ES6 #sec-string.prototype-@@iterator 19transitioning javascript builtin StringPrototypeIterator( 20 js-implicit context: NativeContext, receiver: JSAny)(): JSStringIterator { 21 const name: String = 22 ToThisString(receiver, 'String.prototype[Symbol.iterator]'); 23 const index: Smi = 0; 24 return NewJSStringIterator(name, index); 25} 26 27// ES6 #sec-%stringiteratorprototype%.next 28transitioning javascript builtin StringIteratorPrototypeNext( 29 js-implicit context: NativeContext, receiver: JSAny)(): JSObject { 30 const iterator = Cast<JSStringIterator>(receiver) otherwise ThrowTypeError( 31 MessageTemplate::kIncompatibleMethodReceiver, 32 'String Iterator.prototype.next', receiver); 33 const string = iterator.string; 34 const position: intptr = SmiUntag(iterator.index); 35 const length: intptr = string.length_intptr; 36 if (position >= length) { 37 return AllocateJSIteratorResult(Undefined, True); 38 } 39 // Move to next codepoint. 40 const encoding = UnicodeEncoding::UTF16; 41 const ch = string::LoadSurrogatePairAt(string, length, position, encoding); 42 const value: String = string::StringFromSingleUTF16EncodedCodePoint(ch); 43 iterator.index = SmiTag(position + value.length_intptr); 44 return AllocateJSIteratorResult(value, False); 45} 46} 47