summaryrefslogtreecommitdiff
path: root/chromium/v8/src/builtins/string-iterator.tq
blob: eea7a621f0f8aed43d87a5fe600933074ed30979 (plain)
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
// 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 {

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

// ES6 #sec-string.prototype-@@iterator
transitioning javascript builtin StringPrototypeIterator(
    js-implicit context: NativeContext, receiver: JSAny)(): JSStringIterator {
  const name: String =
      ToThisString(receiver, 'String.prototype[Symbol.iterator]');
  const index: Smi = 0;
  return NewJSStringIterator(name, index);
}

// ES6 #sec-%stringiteratorprototype%.next
transitioning javascript builtin StringIteratorPrototypeNext(
    js-implicit context: NativeContext, receiver: JSAny)(): JSObject {
  const iterator = Cast<JSStringIterator>(receiver) otherwise ThrowTypeError(
      MessageTemplate::kIncompatibleMethodReceiver,
      'String Iterator.prototype.next', receiver);
  const string = iterator.string;
  const position: intptr = SmiUntag(iterator.index);
  const length: intptr = string.length_intptr;
  if (position >= length) {
    return AllocateJSIteratorResult(Undefined, True);
  }
  // Move to next codepoint.
  const encoding = UnicodeEncoding::UTF16;
  const ch = string::LoadSurrogatePairAt(string, length, position, encoding);
  const value: String = string::StringFromSingleUTF16EncodedCodePoint(ch);
  iterator.index = SmiTag(position + value.length_intptr);
  return AllocateJSIteratorResult(value, False);
}
}