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(function(global, utils) { 6 7"use strict"; 8 9%CheckIsBootstrapping(); 10 11// ------------------------------------------------------------------- 12// Imports 13 14var GlobalString = global.String; 15var IteratorPrototype = utils.ImportNow("IteratorPrototype"); 16var iteratorSymbol = utils.ImportNow("iterator_symbol"); 17var MakeTypeError; 18var stringIteratorIteratedStringSymbol = 19 utils.ImportNow("string_iterator_iterated_string_symbol"); 20var stringIteratorNextIndexSymbol = 21 utils.ImportNow("string_iterator_next_index_symbol"); 22var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol"); 23 24utils.Import(function(from) { 25 MakeTypeError = from.MakeTypeError; 26}); 27 28// ------------------------------------------------------------------- 29 30function StringIterator() {} 31 32 33// 21.1.5.1 CreateStringIterator Abstract Operation 34function CreateStringIterator(string) { 35 var s = TO_STRING(string); 36 var iterator = new StringIterator; 37 SET_PRIVATE(iterator, stringIteratorIteratedStringSymbol, s); 38 SET_PRIVATE(iterator, stringIteratorNextIndexSymbol, 0); 39 return iterator; 40} 41 42 43// ES6 section 21.1.5.2.1 %StringIteratorPrototype%.next ( ) 44function StringIteratorNext() { 45 var iterator = this; 46 var value = UNDEFINED; 47 var done = true; 48 49 if (!IS_RECEIVER(iterator) || 50 !HAS_DEFINED_PRIVATE(iterator, stringIteratorNextIndexSymbol)) { 51 throw MakeTypeError(kIncompatibleMethodReceiver, 52 'String Iterator.prototype.next'); 53 } 54 55 var s = GET_PRIVATE(iterator, stringIteratorIteratedStringSymbol); 56 if (!IS_UNDEFINED(s)) { 57 var position = GET_PRIVATE(iterator, stringIteratorNextIndexSymbol); 58 var length = TO_UINT32(s.length); 59 if (position >= length) { 60 SET_PRIVATE(iterator, stringIteratorIteratedStringSymbol, UNDEFINED); 61 } else { 62 var first = %_StringCharCodeAt(s, position); 63 value = %_StringCharFromCode(first); 64 done = false; 65 position++; 66 67 if (first >= 0xD800 && first <= 0xDBFF && position < length) { 68 var second = %_StringCharCodeAt(s, position); 69 if (second >= 0xDC00 && second <= 0xDFFF) { 70 value += %_StringCharFromCode(second); 71 position++; 72 } 73 } 74 75 SET_PRIVATE(iterator, stringIteratorNextIndexSymbol, position); 76 } 77 } 78 return %_CreateIterResultObject(value, done); 79} 80 81 82// 21.1.3.27 String.prototype [ @@iterator ]( ) 83function StringPrototypeIterator() { 84 return CreateStringIterator(this); 85} 86 87//------------------------------------------------------------------- 88 89%FunctionSetPrototype(StringIterator, {__proto__: IteratorPrototype}); 90%FunctionSetInstanceClassName(StringIterator, 'String Iterator'); 91 92utils.InstallFunctions(StringIterator.prototype, DONT_ENUM, [ 93 'next', StringIteratorNext 94]); 95%AddNamedProperty(StringIterator.prototype, toStringTagSymbol, 96 "String Iterator", READ_ONLY | DONT_ENUM); 97 98utils.SetFunctionName(StringPrototypeIterator, iteratorSymbol); 99%AddNamedProperty(GlobalString.prototype, iteratorSymbol, 100 StringPrototypeIterator, DONT_ENUM); 101 102}) 103