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