Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1598)

Unified Diff: src/builtins/builtins-string.cc

Issue 2358263002: [builtins] migrate C++ String Iterator builtins to baseline TurboFan (Closed)
Patch Set: v6 (fix toString() behaviour in S.p[@@iterator]) Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/builtins/builtins.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/builtins/builtins-string.cc
diff --git a/src/builtins/builtins-string.cc b/src/builtins/builtins-string.cc
index 640e425d23e47b6678af913a5da40d04ab055dc5..83d2a94bceb5bedfbc98beb2718a7b850a2be3c1 100644
--- a/src/builtins/builtins-string.cc
+++ b/src/builtins/builtins-string.cc
@@ -616,58 +616,545 @@ void Builtins::Generate_StringPrototypeValueOf(CodeStubAssembler* assembler) {
assembler->Return(result);
}
-BUILTIN(StringPrototypeIterator) {
- HandleScope scope(isolate);
- TO_THIS_STRING(object, "String.prototype[Symbol.iterator]");
+void Builtins::Generate_StringPrototypeIterator(CodeStubAssembler* assembler) {
+ typedef CodeStubAssembler::Label Label;
+ typedef compiler::Node Node;
+ typedef CodeStubAssembler::Variable Variable;
+
+ Variable var_string(assembler, MachineRepresentation::kTagged);
+ Variable var_index(assembler, MachineRepresentation::kWord32);
+
+ Variable* loop_inputs[] = {&var_string, &var_index};
+ Label loop(assembler, 2, loop_inputs);
+ Label allocate_iterator(assembler);
+
+ Node* receiver = assembler->Parameter(0);
+ Node* context = assembler->Parameter(3);
+
+ Node* string = assembler->ToThisString(context, receiver,
+ "String.prototype[Symbol.iterator]");
+ var_string.Bind(string);
+ var_index.Bind(assembler->Int32Constant(0));
+
+ assembler->Goto(&loop);
+ assembler->Bind(&loop);
+ {
+ // Load the instance type of the {string}.
+ Node* string_instance_type = assembler->LoadInstanceType(string);
+
+ // Check if the {string} is a SeqString.
+ Label if_stringisnotsequential(assembler);
+ assembler->Branch(assembler->Word32Equal(
+ assembler->Word32And(string_instance_type,
+ assembler->Int32Constant(
+ kStringRepresentationMask)),
+ assembler->Int32Constant(kSeqStringTag)),
+ &allocate_iterator, &if_stringisnotsequential);
+
+ assembler->Bind(&if_stringisnotsequential);
+ {
+ // Check if the {string} is a ConsString.
+ Label if_stringiscons(assembler), if_stringisnotcons(assembler);
+ assembler->Branch(
+ assembler->Word32Equal(
+ assembler->Word32And(
+ string_instance_type,
+ assembler->Int32Constant(kStringRepresentationMask)),
+ assembler->Int32Constant(kConsStringTag)),
+ &if_stringiscons, &if_stringisnotcons);
+
+ assembler->Bind(&if_stringiscons);
+ {
+ // Flatten cons-string and finish.
+ var_string.Bind(assembler->CallRuntime(
+ Runtime::kFlattenString, assembler->NoContextConstant(), string));
+ assembler->Goto(&allocate_iterator);
+ }
- Handle<String> string;
- ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, string,
- Object::ToString(isolate, object));
+ assembler->Bind(&if_stringisnotcons);
+ {
+ // Check if the {string} is an ExternalString.
+ Label if_stringisnotexternal(assembler);
+ assembler->Branch(
+ assembler->Word32Equal(
+ assembler->Word32And(
+ string_instance_type,
+ assembler->Int32Constant(kStringRepresentationMask)),
+ assembler->Int32Constant(kExternalStringTag)),
+ &allocate_iterator, &if_stringisnotexternal);
+
+ assembler->Bind(&if_stringisnotexternal);
+ {
+ // The {string} is a SlicedString, continue with its parent.
+ Node* index = var_index.value();
+ Node* string_offset = assembler->LoadAndUntagObjectField(
+ string, SlicedString::kOffsetOffset);
+ Node* string_parent =
+ assembler->LoadObjectField(string, SlicedString::kParentOffset);
+ var_index.Bind(assembler->IntPtrAdd(index, string_offset));
+ var_string.Bind(string_parent);
+ assembler->Goto(&loop);
+ }
+ }
+ }
+ }
- return *isolate->factory()->NewJSStringIterator(string);
+ assembler->Bind(&allocate_iterator);
+ {
+ Node* native_context = assembler->LoadNativeContext(context);
+ Node* index = assembler->Int32Constant(Context::STRING_ITERATOR_MAP_INDEX);
+ Node* map = assembler->LoadFixedArrayElement(
+ native_context, index, 0, CodeStubAssembler::INTPTR_PARAMETERS);
+ Node* iterator = assembler->Allocate(JSStringIterator::kSize);
+ assembler->StoreMapNoWriteBarrier(iterator, map);
+ assembler->StoreObjectFieldRoot(iterator, JSValue::kPropertiesOffset,
+ Heap::kEmptyFixedArrayRootIndex);
+ assembler->StoreObjectFieldRoot(iterator, JSObject::kElementsOffset,
+ Heap::kEmptyFixedArrayRootIndex);
+ assembler->StoreObjectField(iterator, JSStringIterator::kStringOffset,
Benedikt Meurer 2016/09/23 18:14:53 This doesn't need a write barrier, since the objec
caitp 2016/09/23 19:14:16 Done.
+ var_string.value());
+
+ assembler->StoreObjectField(iterator, JSStringIterator::kNextIndexOffset,
Benedikt Meurer 2016/09/23 18:14:53 This doesn't need a write barrier, you can safely
caitp 2016/09/23 19:14:16 Done.
+ assembler->SmiFromWord32(var_index.value()));
+ assembler->Return(iterator);
+ }
}
-BUILTIN(StringIteratorPrototypeNext) {
- HandleScope scope(isolate);
+namespace {
- if (!args.receiver()->IsJSStringIterator()) {
- Handle<String> reason = isolate->factory()->NewStringFromAsciiChecked(
- "String Iterator.prototype.next");
- THROW_NEW_ERROR_RETURN_FAILURE(
- isolate,
- NewTypeError(MessageTemplate::kIncompatibleMethodReceiver, reason));
+enum class UnicodeEncoding {
+ UTF16, // high 16bits trail surrogate, low 16bits lead surrogate
+ UTF32
+};
+
+// Return the |String| containing a single {codepoint}, which may be encoded
+// as one of the following: a single UTF16 code unit, a |word32| with the
+// high 16 bits set to the trailing surrogate, and low 16 bits set to the lead
+// surrogate, or a single UTF32-encoded codepoint.
+static compiler::Node* CreateStringFromCodePointInternal(
Benedikt Meurer 2016/09/23 03:46:24 You don't need static inside an anonymous namespac
caitp 2016/09/23 10:14:28 The UnicodeEncoding thing is there to control how
caitp 2016/09/23 19:14:16 The UnicodeEncoding thing is there to control how
Benedikt Meurer 2016/09/26 04:15:40 Acknowledged.
+ CodeStubAssembler* assembler, compiler::Node* codepoint,
+ UnicodeEncoding encoding) {
+ typedef CodeStubAssembler::Label Label;
+ typedef compiler::Node Node;
+ typedef CodeStubAssembler::Variable Variable;
+
+ Variable var_result(assembler, MachineRepresentation::kTagged);
+ var_result.Bind(assembler->EmptyStringConstant());
+
+ Label if_isonebyte(assembler), if_istwobyte(assembler),
+ return_result(assembler);
+
+ assembler->Branch(
+ assembler->Uint32LessThan(codepoint, assembler->Int32Constant(0x100)),
+ &if_isonebyte, &if_istwobyte);
+
+ assembler->Bind(&if_isonebyte);
+ {
+ Node* value = assembler->AllocateSeqOneByteString(1);
+ assembler->StoreNoWriteBarrier(
+ MachineRepresentation::kWord8, value,
+ assembler->IntPtrConstant(SeqOneByteString::kHeaderSize -
+ kHeapObjectTag),
+ codepoint);
+ var_result.Bind(value);
+ assembler->Goto(&return_result);
}
- Handle<JSStringIterator> iterator =
- Handle<JSStringIterator>::cast(args.receiver());
- Handle<String> string(iterator->string());
-
- int position = iterator->index();
- int length = string->length();
-
- if (position < length) {
- 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 surrogate pair code units
- iterator->set_index(position + 2);
- Handle<String> value =
- isolate->factory()->NewSurrogatePairString(lead, trail);
- return *isolate->factory()->NewJSIteratorResult(value, false);
+
+ assembler->Bind(&if_istwobyte);
+ {
+ Label if_isdouble(assembler), if_issingle(assembler);
+ assembler->Branch(
+ assembler->Uint32LessThan(codepoint, assembler->Int32Constant(0x10000)),
+ &if_issingle, &if_isdouble);
+
+ assembler->Bind(&if_issingle);
+ {
+ Node* value = assembler->AllocateSeqTwoByteString(1);
+ assembler->StoreNoWriteBarrier(
+ MachineRepresentation::kWord16, value,
+ assembler->IntPtrConstant(SeqTwoByteString::kHeaderSize -
+ kHeapObjectTag),
+ codepoint);
+ var_result.Bind(value);
+ assembler->Goto(&return_result);
+ }
+
+ assembler->Bind(&if_isdouble);
+ {
+ switch (encoding) {
+ case UnicodeEncoding::UTF16:
+ break;
+ case UnicodeEncoding::UTF32: {
+ // Convert UTF32 to UTF16 code units, and store as a 32 bit word.
+ Node* lead_offset =
caitp 2016/09/23 19:14:16 This code here in particular should be very useful
+ assembler->Int32Constant(0xD800 - (0x10000 >> 10));
+
+ Node* lead = assembler->Int32Add(
+ assembler->WordShr(codepoint, assembler->Int32Constant(10)),
+ lead_offset);
+
+ Node* trail = assembler->Int32Add(
+ assembler->Word32And(codepoint, assembler->Int32Constant(0x3FF)),
+ assembler->Int32Constant(0xDC00));
+
+ codepoint = assembler->Word32Or(
+ assembler->WordShl(trail, assembler->Int32Constant(16)), lead);
+ }
+ default:
+ UNREACHABLE();
}
+
+ Node* value = assembler->AllocateSeqTwoByteString(2);
+ assembler->StoreNoWriteBarrier(
+ MachineRepresentation::kWord32, value,
+ assembler->IntPtrConstant(SeqTwoByteString::kHeaderSize -
+ kHeapObjectTag),
+ codepoint);
+ var_result.Bind(value);
+ assembler->Goto(&return_result);
}
+ }
+
+ assembler->Bind(&return_result);
+ return var_result.value();
+}
- // Return single code unit
- iterator->set_index(position + 1);
- Handle<String> value =
- isolate->factory()->LookupSingleCharacterStringFromCode(lead);
- return *isolate->factory()->NewJSIteratorResult(value, false);
+static compiler::Node* CreateStringFromSurrogatePair(
+ CodeStubAssembler* assembler, compiler::Node* code_units) {
+ return CreateStringFromCodePointInternal(assembler, code_units,
+ UnicodeEncoding::UTF16);
+}
+
+// Return the |word32| codepoint at {index}. Supports SeqStrings and
+// ExternalStrings.
+static compiler::Node* LoadSurrogatePairInternal(CodeStubAssembler* assembler,
+ compiler::Node* string,
+ compiler::Node* length,
+ compiler::Node* index,
+ UnicodeEncoding encoding) {
+ typedef CodeStubAssembler::Label Label;
+ typedef compiler::Node Node;
+ typedef CodeStubAssembler::Variable Variable;
+ Label handle_surrogate_pair(assembler), return_result(assembler);
+ Variable var_result(assembler, MachineRepresentation::kWord32);
+ Variable var_trail(assembler, MachineRepresentation::kWord16);
+ var_result.Bind(assembler->Int32Constant(0));
+ var_trail.Bind(assembler->Int32Constant(0));
+
+ Node* string_instance_type = assembler->LoadInstanceType(string);
+
+ Label if_stringissequential(assembler), if_stringisexternal(assembler);
+ assembler->Branch(assembler->Word32Equal(
+ assembler->Word32And(string_instance_type,
+ assembler->Int32Constant(
+ kStringRepresentationMask)),
+ assembler->Int32Constant(kSeqStringTag)),
+ &if_stringissequential, &if_stringisexternal);
+
+ assembler->Bind(&if_stringissequential);
+ {
+ Label if_stringisonebyte(assembler), if_stringistwobyte(assembler);
+ assembler->Branch(
+ assembler->Word32Equal(
+ assembler->Word32And(string_instance_type,
+ assembler->Int32Constant(kStringEncodingMask)),
+ assembler->Int32Constant(kOneByteStringTag)),
+ &if_stringisonebyte, &if_stringistwobyte);
+
+ assembler->Bind(&if_stringisonebyte);
+ {
+ var_result.Bind(assembler->Load(
+ MachineType::Uint8(), string,
+ assembler->IntPtrAdd(
+ index, assembler->IntPtrConstant(SeqOneByteString::kHeaderSize -
+ kHeapObjectTag))));
+ assembler->Goto(&return_result);
+ }
+
+ assembler->Bind(&if_stringistwobyte);
+ {
+ Node* lead = assembler->Load(
+ MachineType::Uint16(), string,
+ assembler->IntPtrAdd(
+ assembler->WordShl(index, assembler->IntPtrConstant(1)),
+ assembler->IntPtrConstant(SeqTwoByteString::kHeaderSize -
+ kHeapObjectTag)));
+ var_result.Bind(lead);
+ Node* next_pos = assembler->Int32Add(index, assembler->Int32Constant(1));
+
+ Label if_isdoublecodeunit(assembler);
+ assembler->GotoIf(assembler->Int32GreaterThanOrEqual(next_pos, length),
+ &return_result);
+ assembler->GotoIf(
+ assembler->Uint32LessThan(lead, assembler->Int32Constant(0xD800)),
+ &return_result);
+ assembler->Branch(
+ assembler->Uint32LessThan(lead, assembler->Int32Constant(0xDC00)),
+ &if_isdoublecodeunit, &return_result);
+
+ assembler->Bind(&if_isdoublecodeunit);
+ {
+ Node* trail = assembler->Load(
+ MachineType::Uint16(), string,
+ assembler->IntPtrAdd(
+ assembler->WordShl(next_pos, assembler->IntPtrConstant(1)),
+ assembler->IntPtrConstant(SeqTwoByteString::kHeaderSize -
+ kHeapObjectTag)));
+ assembler->GotoIf(
+ assembler->Uint32LessThan(trail, assembler->Int32Constant(0xDC00)),
+ &return_result);
+ assembler->GotoIf(assembler->Uint32GreaterThanOrEqual(
+ trail, assembler->Int32Constant(0xE000)),
+ &return_result);
+
+ var_trail.Bind(trail);
+ assembler->Goto(&handle_surrogate_pair);
+ }
+ }
}
- iterator->set_string(isolate->heap()->empty_string());
+ assembler->Bind(&if_stringisexternal);
+ {
+ assembler->Assert(assembler->Word32Equal(
+ assembler->Word32And(
+ string_instance_type,
+ assembler->Int32Constant(kStringRepresentationMask)),
+ assembler->Int32Constant(kExternalStringTag)));
+ Label if_stringisshort(assembler), if_stringisnotshort(assembler);
+
+ assembler->Branch(assembler->Word32Equal(
+ assembler->Word32And(string_instance_type,
+ assembler->Int32Constant(
+ kShortExternalStringMask)),
+ assembler->Int32Constant(0)),
+ &if_stringisshort, &if_stringisnotshort);
+
+ assembler->Bind(&if_stringisshort);
+ {
+ // Load the actual resource data from the {string}.
+ Node* string_resource_data = assembler->LoadObjectField(
+ string, ExternalString::kResourceDataOffset, MachineType::Pointer());
+
+ Label if_stringistwobyte(assembler), if_stringisonebyte(assembler);
+ assembler->Branch(assembler->Word32Equal(
+ assembler->Word32And(
+ string_instance_type,
+ assembler->Int32Constant(kStringEncodingMask)),
+ assembler->Int32Constant(kTwoByteStringTag)),
+ &if_stringistwobyte, &if_stringisonebyte);
+
+ assembler->Bind(&if_stringisonebyte);
+ {
+ var_result.Bind(
+ assembler->Load(MachineType::Uint8(), string_resource_data, index));
+ assembler->Goto(&return_result);
+ }
+
+ assembler->Bind(&if_stringistwobyte);
+ {
+ Label if_isdoublecodeunit(assembler);
+ Node* lead = assembler->Load(
+ MachineType::Uint16(), string_resource_data,
+ assembler->WordShl(index, assembler->IntPtrConstant(1)));
+ var_result.Bind(lead);
+ Node* next_pos =
+ assembler->Int32Add(index, assembler->Int32Constant(1));
+
+ assembler->GotoIf(assembler->Int32GreaterThanOrEqual(next_pos, length),
+ &return_result);
+ assembler->GotoIf(
+ assembler->Uint32LessThan(lead, assembler->Int32Constant(0xD800)),
+ &return_result);
+ assembler->Branch(
+ assembler->Uint32LessThan(lead, assembler->Int32Constant(0xDC00)),
+ &if_isdoublecodeunit, &return_result);
+
+ assembler->Bind(&if_isdoublecodeunit);
+ {
+ Node* trail = assembler->Load(
+ MachineType::Uint16(), string,
+ assembler->IntPtrAdd(
+ assembler->WordShl(next_pos, assembler->IntPtrConstant(1)),
+ assembler->IntPtrConstant(SeqTwoByteString::kHeaderSize -
+ kHeapObjectTag)));
+ assembler->GotoIf(assembler->Uint32LessThan(
+ trail, assembler->Int32Constant(0xDC00)),
+ &return_result);
+ assembler->GotoIf(assembler->Uint32GreaterThanOrEqual(
+ trail, assembler->Int32Constant(0xE000)),
+ &return_result);
+
+ var_trail.Bind(trail);
+ assembler->Goto(&handle_surrogate_pair);
+ }
+ }
+ }
+
+ assembler->Bind(&if_stringisnotshort);
+ {
+ Label if_isdoublecodeunit(assembler);
+ Node* lead = assembler->SmiToWord32(assembler->CallRuntime(
+ Runtime::kExternalStringGetChar, assembler->NoContextConstant(),
+ string, assembler->SmiTag(index)));
+ var_result.Bind(lead);
+ Node* next_pos = assembler->Int32Add(index, assembler->Int32Constant(1));
+
+ assembler->GotoIf(assembler->Int32GreaterThanOrEqual(next_pos, length),
+ &return_result);
+ assembler->GotoIf(
+ assembler->Uint32LessThan(lead, assembler->Int32Constant(0xD800)),
+ &return_result);
+ assembler->Branch(assembler->Uint32GreaterThanOrEqual(
+ lead, assembler->Int32Constant(0xDC00)),
+ &return_result, &if_isdoublecodeunit);
+
+ assembler->Bind(&if_isdoublecodeunit);
+ {
+ Node* trail = assembler->SmiToWord32(assembler->CallRuntime(
+ Runtime::kExternalStringGetChar, assembler->NoContextConstant(),
+ string, assembler->SmiTag(next_pos)));
+ assembler->GotoIf(
+ assembler->Uint32LessThan(trail, assembler->Int32Constant(0xDC00)),
+ &return_result);
+ assembler->GotoIf(assembler->Uint32GreaterThanOrEqual(
+ trail, assembler->Int32Constant(0xE000)),
+ &return_result);
+ var_trail.Bind(trail);
+ assembler->Goto(&handle_surrogate_pair);
+ }
+ }
+ }
- return *isolate->factory()->NewJSIteratorResult(
- isolate->factory()->undefined_value(), true);
+ assembler->Bind(&handle_surrogate_pair);
+ {
+ Node* lead = var_result.value();
+ Node* trail = var_trail.value();
+#ifdef ENABLE_SLOW_DCHECKS
+ // Check that this path is only taken if a surrogate pair is found
+ assembler->Assert(assembler->Uint32GreaterThanOrEqual(
+ lead, assembler->Int32Constant(0xD800)));
+ assembler->Assert(
+ assembler->Uint32LessThan(lead, assembler->Int32Constant(0xDC00)));
+ assembler->Assert(assembler->Uint32GreaterThanOrEqual(
+ trail, assembler->Int32Constant(0xDC00)));
+ assembler->Assert(
+ assembler->Uint32LessThan(trail, assembler->Int32Constant(0xE000)));
+#endif
+
+ switch (encoding) {
+ case UnicodeEncoding::UTF16:
+ var_result.Bind(assembler->WordOr(
+ assembler->WordShl(trail, assembler->Int32Constant(16)), lead));
+ break;
+
+ case UnicodeEncoding::UTF32: {
+ // Convert UTF16 surrogate pair into |word32| code point, encoded as
+ // UTF32.
+ Node* surrogate_offset =
+ assembler->Int32Constant(0x10000 - (0xD800 << 10) - 0xDC00);
+
+ // (lead << 10) + trail + SURROGATE_OFFSET
+ var_result.Bind(assembler->Int32Add(
+ assembler->WordShl(lead, assembler->Int32Constant(10)),
+ assembler->Int32Add(trail, surrogate_offset)));
+ break;
+ }
+ }
+ assembler->Goto(&return_result);
+ }
+
+ assembler->Bind(&return_result);
+ return var_result.value();
+}
+
+static compiler::Node* LoadSurrogatePairAt(CodeStubAssembler* assembler,
+ compiler::Node* string,
+ compiler::Node* length,
+ compiler::Node* index) {
+ return LoadSurrogatePairInternal(assembler, string, length, index,
+ UnicodeEncoding::UTF16);
+}
+
+} // namespace
+
+void Builtins::Generate_StringIteratorPrototypeNext(
+ CodeStubAssembler* assembler) {
+ typedef CodeStubAssembler::Label Label;
+ typedef compiler::Node Node;
+ typedef CodeStubAssembler::Variable Variable;
+
+ Variable var_value(assembler, MachineRepresentation::kTagged);
+ Variable var_done(assembler, MachineRepresentation::kTagged);
+
+ var_value.Bind(assembler->UndefinedConstant());
+ var_done.Bind(assembler->BooleanConstant(true));
+
+ Label throw_bad_receiver(assembler), next_codepoint(assembler),
+ return_result(assembler);
+
+ Node* iterator = assembler->Parameter(0);
+ Node* context = assembler->Parameter(3);
+
+ assembler->GotoIf(assembler->WordIsSmi(iterator), &throw_bad_receiver);
+ assembler->GotoUnless(
+ assembler->WordEqual(assembler->LoadInstanceType(iterator),
+ assembler->Int32Constant(JS_STRING_ITERATOR_TYPE)),
+ &throw_bad_receiver);
+
+ Node* string =
+ assembler->LoadObjectField(iterator, JSStringIterator::kStringOffset);
+ Node* position = assembler->LoadAndUntagObjectField(
+ iterator, JSStringIterator::kNextIndexOffset);
+ Node* length =
+ assembler->LoadAndUntagObjectField(string, String::kLengthOffset);
+
+ assembler->Branch(assembler->Int32LessThan(position, length), &next_codepoint,
+ &return_result);
+
+ assembler->Bind(&next_codepoint);
+ {
+ Node* ch = LoadSurrogatePairAt(assembler, string, length, position);
+ Node* value = CreateStringFromSurrogatePair(assembler, ch);
+ var_value.Bind(value);
+ Node* length =
+ assembler->LoadAndUntagObjectField(value, String::kLengthOffset);
+ assembler->StoreObjectFieldNoWriteBarrier(
+ iterator, JSStringIterator::kNextIndexOffset,
+ assembler->SmiFromWord32(assembler->Int32Add(position, length)));
+ var_done.Bind(assembler->BooleanConstant(false));
+ assembler->Goto(&return_result);
+ }
+
+ assembler->Bind(&return_result);
+ {
+ Node* native_context = assembler->LoadNativeContext(context);
+ Node* map = assembler->LoadFixedArrayElement(
+ native_context,
+ assembler->IntPtrConstant(Context::ITERATOR_RESULT_MAP_INDEX), 0,
+ CodeStubAssembler::INTPTR_PARAMETERS);
+ Node* result = assembler->Allocate(JSIteratorResult::kSize);
+ assembler->StoreMapNoWriteBarrier(result, map);
+ assembler->StoreObjectFieldRoot(result, JSIteratorResult::kPropertiesOffset,
+ Heap::kEmptyFixedArrayRootIndex);
+ assembler->StoreObjectFieldRoot(result, JSIteratorResult::kElementsOffset,
+ Heap::kEmptyFixedArrayRootIndex);
+ assembler->StoreObjectField(result, JSIteratorResult::kValueOffset,
Benedikt Meurer 2016/09/23 18:14:53 You can skip write barrier for these two stores be
caitp 2016/09/23 19:14:16 Done.
+ var_value.value());
+ assembler->StoreObjectField(result, JSIteratorResult::kDoneOffset,
+ var_done.value());
+ assembler->Return(result);
+ }
+
+ assembler->Bind(&throw_bad_receiver);
+ {
+ // The {receiver} is not a valid JSGeneratorObject.
+ Node* result = assembler->CallRuntime(
+ Runtime::kThrowIncompatibleMethodReceiver, context,
+ assembler->HeapConstant(assembler->factory()->NewStringFromAsciiChecked(
+ "String Iterator.prototype.next", TENURED)),
+ iterator);
+ assembler->Return(result); // Never reached.
+ }
}
} // namespace internal
« no previous file with comments | « src/builtins/builtins.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698