blob: 5b8f864661295a8b92366c8c8ce036ca3a259b5a [file] [log] [blame]
// 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(
js-implicit context: Context)(receiver: Object): 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: Context)(receiver: Object): JSObject {
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 AllocateJSIteratorResult(Undefined, True);
}
// Move to next codepoint.
const encoding = UTF16;
const ch = string::LoadSurrogatePairAt(string, length, position, encoding);
const value: String = string::StringFromSingleUTF16EncodedCodePoint(ch);
iterator.next_index = SmiTag(position + value.length_intptr);
return AllocateJSIteratorResult(value, False);
}
}