| Index: src/builtins/builtins-string.cc
|
| diff --git a/src/builtins/builtins-string.cc b/src/builtins/builtins-string.cc
|
| index f7413fc30ff6681293e0c8157c4fdc7b5f03e0c8..f1c60883743c22cfc55405c50116d7eeb1db068f 100644
|
| --- a/src/builtins/builtins-string.cc
|
| +++ b/src/builtins/builtins-string.cc
|
| @@ -607,5 +607,65 @@ void Builtins::Generate_StringPrototypeValueOf(CodeStubAssembler* assembler) {
|
| assembler->Return(result);
|
| }
|
|
|
| +BUILTIN(StringCreateIterator) {
|
| + HandleScope scope(isolate);
|
| + TO_THIS_STRING(object, "String.prototype[Symbol.iterator]");
|
| +
|
| + Handle<String> string;
|
| + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, string,
|
| + Object::ToString(isolate, object));
|
| +
|
| + return *isolate->factory()->NewJSStringIterator(string);
|
| +}
|
| +
|
| +BUILTIN(StringIteratorNext) {
|
| + HandleScope scope(isolate);
|
| +
|
| + if (!args.receiver()->IsJSStringIterator()) {
|
| + Handle<String> reason = isolate->factory()->NewStringFromAsciiChecked(
|
| + "String Iterator.prototype.next");
|
| + THROW_NEW_ERROR_RETURN_FAILURE(
|
| + isolate,
|
| + NewTypeError(MessageTemplate::kIncompatibleMethodReceiver, reason));
|
| + }
|
| + Handle<JSStringIterator> iterator =
|
| + Handle<JSStringIterator>::cast(args.receiver());
|
| + Handle<String> string(iterator->string());
|
| +
|
| + if (*string != isolate->heap()->empty_string()) {
|
| + int position;
|
| + int length = string->length();
|
| +
|
| + do {
|
| + if (!iterator->index()->ToUint32(reinterpret_cast<uint32_t*>(&position)))
|
| + break;
|
| + if (position >= length) break;
|
| +
|
| + uint16_t lead = string->Get(position);
|
| + if (lead >= 0xD800 && lead <= 0xDBFF && position + 1 < length) {
|
| + uint16_t trail = string->Get(position + 1);
|
| + if (V8_LIKELY(trail >= 0xDC00 && trail <= 0xDFFF)) {
|
| + // Return combined code units
|
| + iterator->set_index(Smi::FromInt(position + 2));
|
| + Handle<String> value = isolate->factory()->NewProperSubString(
|
| + string, position, position + 2);
|
| + return *isolate->factory()->NewJSIteratorResult(value, false);
|
| + }
|
| + }
|
| +
|
| + // Return single code unit
|
| + iterator->set_index(Smi::FromInt(position + 1));
|
| + Handle<String> value = isolate->factory()->NewProperSubString(
|
| + string, position, position + 1);
|
| + return *isolate->factory()->NewJSIteratorResult(value, false);
|
| + } while (false);
|
| +
|
| + iterator->set_string(isolate->heap()->empty_string());
|
| + }
|
| +
|
| + return *isolate->factory()->NewJSIteratorResult(
|
| + isolate->factory()->undefined_value(), true);
|
| +}
|
| +
|
| } // namespace internal
|
| } // namespace v8
|
|
|