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 CHECK_OBJECT_COERCIBLE(string, 'String.prototype[Symbol.iterator]'); 36 var s = TO_STRING(string); 37 var iterator = new StringIterator; 38 SET_PRIVATE(iterator, stringIteratorIteratedStringSymbol, s); 39 SET_PRIVATE(iterator, stringIteratorNextIndexSymbol, 0); 40 return iterator; 41} 42 43 44// ES6 section 21.1.5.2.1 %StringIteratorPrototype%.next ( ) 45function StringIteratorNext() { 46 var iterator = this; 47 var value = UNDEFINED; 48 var done = true; 49 50 if (!IS_RECEIVER(iterator) || 51 !HAS_DEFINED_PRIVATE(iterator, stringIteratorNextIndexSymbol)) { 52 throw MakeTypeError(kIncompatibleMethodReceiver, 53 'String Iterator.prototype.next'); 54 } 55 56 var s = GET_PRIVATE(iterator, stringIteratorIteratedStringSymbol); 57 if (!IS_UNDEFINED(s)) { 58 var position = GET_PRIVATE(iterator, stringIteratorNextIndexSymbol); 59 var length = TO_UINT32(s.length); 60 if (position >= length) { 61 SET_PRIVATE(iterator, stringIteratorIteratedStringSymbol, UNDEFINED); 62 } else { 63 var first = %_StringCharCodeAt(s, position); 64 value = %_StringCharFromCode(first); 65 done = false; 66 position++; 67 68 if (first >= 0xD800 && first <= 0xDBFF && position < length) { 69 var second = %_StringCharCodeAt(s, position); 70 if (second >= 0xDC00 && second <= 0xDFFF) { 71 value += %_StringCharFromCode(second); 72 position++; 73 } 74 } 75 76 SET_PRIVATE(iterator, stringIteratorNextIndexSymbol, position); 77 } 78 } 79 return %_CreateIterResultObject(value, done); 80} 81 82 83// 21.1.3.27 String.prototype [ @@iterator ]( ) 84function StringPrototypeIterator() { 85 return CreateStringIterator(this); 86} 87 88//------------------------------------------------------------------- 89 90%FunctionSetPrototype(StringIterator, {__proto__: IteratorPrototype}); 91%FunctionSetInstanceClassName(StringIterator, 'String Iterator'); 92 93utils.InstallFunctions(StringIterator.prototype, DONT_ENUM, [ 94 'next', StringIteratorNext 95]); 96%AddNamedProperty(StringIterator.prototype, toStringTagSymbol, 97 "String Iterator", READ_ONLY | DONT_ENUM); 98 99utils.SetFunctionName(StringPrototypeIterator, iteratorSymbol); 100%AddNamedProperty(GlobalString.prototype, iteratorSymbol, 101 StringPrototypeIterator, DONT_ENUM); 102 103}) 104