Home | History | Annotate | Download | only in src
      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 
     13 var stringIteratorIteratedStringSymbol =
     14     GLOBAL_PRIVATE("StringIterator#iteratedString");
     15 var stringIteratorNextIndexSymbol = GLOBAL_PRIVATE("StringIterator#next");
     16 
     17 
     18 function StringIterator() {}
     19 
     20 
     21 // 21.1.5.1 CreateStringIterator Abstract Operation
     22 function 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]
     32 function StringIteratorIterator() {
     33   return this;
     34 }
     35 
     36 
     37 // 21.1.5.2.1 %StringIteratorPrototype%.next( )
     38 function 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 
     78 function 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 }
     91 SetUpStringIterator();
     92 
     93 
     94 // 21.1.3.27 String.prototype [ @@iterator ]( )
     95 function StringPrototypeIterator() {
     96   return CreateStringIterator(this);
     97 }
     98 
     99 
    100 function ExtendStringPrototypeWithIterator() {
    101   %CheckIsBootstrapping();
    102 
    103   %FunctionSetName(StringPrototypeIterator, '[Symbol.iterator]');
    104   %AddNamedProperty($String.prototype, symbolIterator,
    105                     StringPrototypeIterator, DONT_ENUM);
    106 }
    107 ExtendStringPrototypeWithIterator();
    108