string-iterator.tq 1.74 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

namespace string_iterator {

  macro NewJSStringIterator(implicit context: Context)(
      string: String, nextIndex: Smi): JSStringIterator {
    return new JSStringIterator{
      map: GetInitialStringIteratorMap(),
      properties_or_hash: kEmptyFixedArray,
      elements: kEmptyFixedArray,
      string: string,
      next_index: nextIndex
    };
  }

  // ES6 #sec-string.prototype-@@iterator
  transitioning javascript builtin StringPrototypeIterator(
      implicit context: Context)(receiver: Object): JSStringIterator {
    const name: String =
        ToThisString(receiver, 'String.prototype[Symbol.iterator]');
    const index: Smi = 0;
    return NewJSStringIterator(name, index);
  }
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40

  // ES6 #sec-%stringiteratorprototype%.next
  transitioning javascript builtin StringIteratorPrototypeNext(
      implicit context: Context)(receiver: Object): JSIteratorResult {
    const iterator = Cast<JSStringIterator>(receiver) otherwise ThrowTypeError(
        kIncompatibleMethodReceiver, 'String Iterator.prototype.next',
        receiver);
    const string = iterator.string;
    const position: intptr = SmiUntag(iterator.next_index);
    const length: intptr = string.length_intptr;
    if (position >= length) {
      return NewJSIteratorResult(Undefined, True);
    }
    // Move to next codepoint.
    const encoding = UTF16;
41 42
    const ch = string::LoadSurrogatePairAt(string, length, position, encoding);
    const value: String = string::StringFromSingleCodePoint(ch, encoding);
43 44 45
    iterator.next_index = SmiTag(position + value.length_intptr);
    return NewJSIteratorResult(value, False);
  }
46
}