Index: src/builtins/builtins-string.cc |
diff --git a/src/builtins/builtins-string.cc b/src/builtins/builtins-string.cc |
index f7413fc30ff6681293e0c8157c4fdc7b5f03e0c8..22844fe38fe9dba52bb6b8aaedc4e7c10e43ca14 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(StringPrototypeIterator) { |
+ 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(StringIteratorPrototypeNext) { |
+ 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( |
caitp
2016/09/15 19:02:39
I was expecting NewProperSubString to create Slice
Benedikt Meurer
2016/09/16 03:16:37
Sliced strings would be really a waste of time/spa
|
+ 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 |