diff options
Diffstat (limited to 'deps/v8/src/builtins/builtins-array.cc')
-rw-r--r-- | deps/v8/src/builtins/builtins-array.cc | 1806 |
1 files changed, 968 insertions, 838 deletions
diff --git a/deps/v8/src/builtins/builtins-array.cc b/deps/v8/src/builtins/builtins-array.cc index c09f11b2e8..047d88ecea 100644 --- a/deps/v8/src/builtins/builtins-array.cc +++ b/deps/v8/src/builtins/builtins-array.cc @@ -6,6 +6,7 @@ #include "src/builtins/builtins-utils.h" #include "src/code-factory.h" +#include "src/code-stub-assembler.h" #include "src/contexts.h" #include "src/elements.h" @@ -32,7 +33,7 @@ inline bool ClampedToInteger(Isolate* isolate, Object* object, int* out) { *out = static_cast<int>(value); } return true; - } else if (object->IsUndefined(isolate) || object->IsNull(isolate)) { + } else if (object->IsNullOrUndefined(isolate)) { *out = 0; return true; } else if (object->IsBoolean()) { @@ -55,7 +56,13 @@ inline bool GetSloppyArgumentsLength(Isolate* isolate, Handle<JSObject> object, Object* len_obj = object->InObjectPropertyAt(JSArgumentsObject::kLengthIndex); if (!len_obj->IsSmi()) return false; *out = Max(0, Smi::cast(len_obj)->value()); - return *out <= object->elements()->length(); + + FixedArray* parameters = FixedArray::cast(object->elements()); + if (object->HasSloppyArgumentsElements()) { + FixedArray* arguments = FixedArray::cast(parameters->get(1)); + return *out <= arguments->length(); + } + return *out <= parameters->length(); } inline bool IsJSArrayFastElementMovingAllowed(Isolate* isolate, @@ -144,14 +151,15 @@ MUST_USE_RESULT static Object* CallJsIntrinsic(Isolate* isolate, int argc = args.length() - 1; ScopedVector<Handle<Object>> argv(argc); for (int i = 0; i < argc; ++i) { - argv[i] = args.at<Object>(i + 1); + argv[i] = args.at(i + 1); } RETURN_RESULT_OR_FAILURE( isolate, Execution::Call(isolate, function, args.receiver(), argc, argv.start())); } +} // namespace -Object* DoArrayPush(Isolate* isolate, BuiltinArguments args) { +BUILTIN(ArrayPush) { HandleScope scope(isolate); Handle<Object> receiver = args.receiver(); if (!EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 1)) { @@ -174,19 +182,158 @@ Object* DoArrayPush(Isolate* isolate, BuiltinArguments args) { int new_length = accessor->Push(array, &args, to_add); return Smi::FromInt(new_length); } -} // namespace -BUILTIN(ArrayPush) { return DoArrayPush(isolate, args); } - -// TODO(verwaest): This is a temporary helper until the FastArrayPush stub can -// tailcall to the builtin directly. -RUNTIME_FUNCTION(Runtime_ArrayPush) { - DCHECK_EQ(2, args.length()); - Arguments* incoming = reinterpret_cast<Arguments*>(args[0]); - // Rewrap the arguments as builtins arguments. - int argc = incoming->length() + BuiltinArguments::kNumExtraArgsWithReceiver; - BuiltinArguments caller_args(argc, incoming->arguments() + 1); - return DoArrayPush(isolate, caller_args); +void Builtins::Generate_FastArrayPush(compiler::CodeAssemblerState* state) { + typedef compiler::Node Node; + typedef CodeStubAssembler::Label Label; + typedef CodeStubAssembler::Variable Variable; + CodeStubAssembler assembler(state); + Variable arg_index(&assembler, MachineType::PointerRepresentation()); + Label default_label(&assembler, &arg_index); + Label smi_transition(&assembler); + Label object_push_pre(&assembler); + Label object_push(&assembler, &arg_index); + Label double_push(&assembler, &arg_index); + Label double_transition(&assembler); + Label runtime(&assembler, Label::kDeferred); + + Node* argc = assembler.Parameter(BuiltinDescriptor::kArgumentsCount); + Node* context = assembler.Parameter(BuiltinDescriptor::kContext); + Node* new_target = assembler.Parameter(BuiltinDescriptor::kNewTarget); + + CodeStubArguments args(&assembler, argc); + Node* receiver = args.GetReceiver(); + Node* kind = nullptr; + + Label fast(&assembler); + { + assembler.BranchIfFastJSArray( + receiver, context, CodeStubAssembler::FastJSArrayAccessMode::ANY_ACCESS, + &fast, &runtime); + } + + assembler.Bind(&fast); + { + // Disallow pushing onto prototypes. It might be the JSArray prototype. + // Disallow pushing onto non-extensible objects. + assembler.Comment("Disallow pushing onto prototypes"); + Node* map = assembler.LoadMap(receiver); + Node* bit_field2 = assembler.LoadMapBitField2(map); + int mask = static_cast<int>(Map::IsPrototypeMapBits::kMask) | + (1 << Map::kIsExtensible); + Node* test = assembler.Word32And(bit_field2, assembler.Int32Constant(mask)); + assembler.GotoIf( + assembler.Word32NotEqual( + test, assembler.Int32Constant(1 << Map::kIsExtensible)), + &runtime); + + // Disallow pushing onto arrays in dictionary named property mode. We need + // to figure out whether the length property is still writable. + assembler.Comment( + "Disallow pushing onto arrays in dictionary named property mode"); + assembler.GotoIf(assembler.IsDictionaryMap(map), &runtime); + + // Check whether the length property is writable. The length property is the + // only default named property on arrays. It's nonconfigurable, hence is + // guaranteed to stay the first property. + Node* descriptors = assembler.LoadMapDescriptors(map); + Node* details = assembler.LoadFixedArrayElement( + descriptors, DescriptorArray::ToDetailsIndex(0)); + assembler.GotoIf( + assembler.IsSetSmi(details, PropertyDetails::kAttributesReadOnlyMask), + &runtime); + + arg_index.Bind(assembler.IntPtrConstant(0)); + kind = assembler.DecodeWord32<Map::ElementsKindBits>(bit_field2); + + assembler.GotoIf( + assembler.Int32GreaterThan( + kind, assembler.Int32Constant(FAST_HOLEY_SMI_ELEMENTS)), + &object_push_pre); + + Node* new_length = assembler.BuildAppendJSArray( + FAST_SMI_ELEMENTS, context, receiver, args, arg_index, &smi_transition); + args.PopAndReturn(new_length); + } + + // If the argument is not a smi, then use a heavyweight SetProperty to + // transition the array for only the single next element. If the argument is + // a smi, the failure is due to some other reason and we should fall back on + // the most generic implementation for the rest of the array. + assembler.Bind(&smi_transition); + { + Node* arg = args.AtIndex(arg_index.value()); + assembler.GotoIf(assembler.TaggedIsSmi(arg), &default_label); + Node* length = assembler.LoadJSArrayLength(receiver); + // TODO(danno): Use the KeyedStoreGeneric stub here when possible, + // calling into the runtime to do the elements transition is overkill. + assembler.CallRuntime(Runtime::kSetProperty, context, receiver, length, arg, + assembler.SmiConstant(STRICT)); + assembler.Increment(arg_index); + assembler.GotoIfNotNumber(arg, &object_push); + assembler.Goto(&double_push); + } + + assembler.Bind(&object_push_pre); + { + assembler.Branch(assembler.Int32GreaterThan( + kind, assembler.Int32Constant(FAST_HOLEY_ELEMENTS)), + &double_push, &object_push); + } + + assembler.Bind(&object_push); + { + Node* new_length = assembler.BuildAppendJSArray( + FAST_ELEMENTS, context, receiver, args, arg_index, &default_label); + args.PopAndReturn(new_length); + } + + assembler.Bind(&double_push); + { + Node* new_length = + assembler.BuildAppendJSArray(FAST_DOUBLE_ELEMENTS, context, receiver, + args, arg_index, &double_transition); + args.PopAndReturn(new_length); + } + + // If the argument is not a double, then use a heavyweight SetProperty to + // transition the array for only the single next element. If the argument is + // a double, the failure is due to some other reason and we should fall back + // on the most generic implementation for the rest of the array. + assembler.Bind(&double_transition); + { + Node* arg = args.AtIndex(arg_index.value()); + assembler.GotoIfNumber(arg, &default_label); + Node* length = assembler.LoadJSArrayLength(receiver); + // TODO(danno): Use the KeyedStoreGeneric stub here when possible, + // calling into the runtime to do the elements transition is overkill. + assembler.CallRuntime(Runtime::kSetProperty, context, receiver, length, arg, + assembler.SmiConstant(STRICT)); + assembler.Increment(arg_index); + assembler.Goto(&object_push); + } + + // Fallback that stores un-processed arguments using the full, heavyweight + // SetProperty machinery. + assembler.Bind(&default_label); + { + args.ForEach( + [&assembler, receiver, context, &arg_index](Node* arg) { + Node* length = assembler.LoadJSArrayLength(receiver); + assembler.CallRuntime(Runtime::kSetProperty, context, receiver, + length, arg, assembler.SmiConstant(STRICT)); + }, + arg_index.value()); + args.PopAndReturn(assembler.LoadJSArrayLength(receiver)); + } + + assembler.Bind(&runtime); + { + Node* target = assembler.LoadFromFrame( + StandardFrameConstants::kFunctionOffset, MachineType::TaggedPointer()); + assembler.TailCallStub(CodeFactory::ArrayPush(assembler.isolate()), context, + target, new_target, argc); + } } BUILTIN(ArrayPop) { @@ -461,8 +608,9 @@ class ArrayConcatVisitor { SeededNumberDictionary::cast(*storage_)); // The object holding this backing store has just been allocated, so // it cannot yet be used as a prototype. - Handle<SeededNumberDictionary> result = - SeededNumberDictionary::AtNumberPut(dict, index, elm, false); + Handle<JSObject> not_a_prototype_holder; + Handle<SeededNumberDictionary> result = SeededNumberDictionary::AtNumberPut( + dict, index, elm, not_a_prototype_holder); if (!result.is_identical_to(dict)) { // Dictionary needed to grow. clear_storage(); @@ -533,9 +681,10 @@ class ArrayConcatVisitor { if (!element->IsTheHole(isolate_)) { // The object holding this backing store has just been allocated, so // it cannot yet be used as a prototype. + Handle<JSObject> not_a_prototype_holder; Handle<SeededNumberDictionary> new_storage = SeededNumberDictionary::AtNumberPut(slow_storage, i, element, - false); + not_a_prototype_holder); if (!new_storage.is_identical_to(slow_storage)) { slow_storage = loop_scope.CloseAndEscape(new_storage); } @@ -1001,8 +1150,9 @@ Object* Slow_ArrayConcat(BuiltinArguments* args, Handle<Object> species, // If estimated number of elements is more than half of length, a // fixed array (fast case) is more time and space-efficient than a // dictionary. - bool fast_case = - is_array_species && (estimate_nof_elements * 2) >= estimate_result_length; + bool fast_case = is_array_species && + (estimate_nof_elements * 2) >= estimate_result_length && + isolate->IsIsConcatSpreadableLookupChainIntact(); if (fast_case && kind == FAST_DOUBLE_ELEMENTS) { Handle<FixedArrayBase> storage = @@ -1202,7 +1352,7 @@ BUILTIN(ArrayConcat) { Handle<Object> receiver = args.receiver(); // TODO(bmeurer): Do we really care about the exact exception message here? - if (receiver->IsNull(isolate) || receiver->IsUndefined(isolate)) { + if (receiver->IsNullOrUndefined(isolate)) { THROW_NEW_ERROR_RETURN_FAILURE( isolate, NewTypeError(MessageTemplate::kCalledOnNullOrUndefined, isolate->factory()->NewStringFromAsciiChecked( @@ -1237,146 +1387,149 @@ BUILTIN(ArrayConcat) { return Slow_ArrayConcat(&args, species, isolate); } -void Builtins::Generate_ArrayIsArray(CodeStubAssembler* assembler) { +void Builtins::Generate_ArrayIsArray(compiler::CodeAssemblerState* state) { typedef compiler::Node Node; typedef CodeStubAssembler::Label Label; + CodeStubAssembler assembler(state); - Node* object = assembler->Parameter(1); - Node* context = assembler->Parameter(4); + Node* object = assembler.Parameter(1); + Node* context = assembler.Parameter(4); - Label call_runtime(assembler), return_true(assembler), - return_false(assembler); + Label call_runtime(&assembler), return_true(&assembler), + return_false(&assembler); - assembler->GotoIf(assembler->TaggedIsSmi(object), &return_false); - Node* instance_type = assembler->LoadInstanceType(object); + assembler.GotoIf(assembler.TaggedIsSmi(object), &return_false); + Node* instance_type = assembler.LoadInstanceType(object); - assembler->GotoIf(assembler->Word32Equal( - instance_type, assembler->Int32Constant(JS_ARRAY_TYPE)), - &return_true); + assembler.GotoIf(assembler.Word32Equal( + instance_type, assembler.Int32Constant(JS_ARRAY_TYPE)), + &return_true); // TODO(verwaest): Handle proxies in-place. - assembler->Branch(assembler->Word32Equal( - instance_type, assembler->Int32Constant(JS_PROXY_TYPE)), - &call_runtime, &return_false); + assembler.Branch(assembler.Word32Equal( + instance_type, assembler.Int32Constant(JS_PROXY_TYPE)), + &call_runtime, &return_false); - assembler->Bind(&return_true); - assembler->Return(assembler->BooleanConstant(true)); + assembler.Bind(&return_true); + assembler.Return(assembler.BooleanConstant(true)); - assembler->Bind(&return_false); - assembler->Return(assembler->BooleanConstant(false)); + assembler.Bind(&return_false); + assembler.Return(assembler.BooleanConstant(false)); - assembler->Bind(&call_runtime); - assembler->Return( - assembler->CallRuntime(Runtime::kArrayIsArray, context, object)); + assembler.Bind(&call_runtime); + assembler.Return( + assembler.CallRuntime(Runtime::kArrayIsArray, context, object)); } -void Builtins::Generate_ArrayIncludes(CodeStubAssembler* assembler) { +void Builtins::Generate_ArrayIncludes(compiler::CodeAssemblerState* state) { typedef compiler::Node Node; typedef CodeStubAssembler::Label Label; typedef CodeStubAssembler::Variable Variable; + CodeStubAssembler assembler(state); - Node* array = assembler->Parameter(0); - Node* search_element = assembler->Parameter(1); - Node* start_from = assembler->Parameter(2); - Node* context = assembler->Parameter(3 + 2); + Node* array = assembler.Parameter(0); + Node* search_element = assembler.Parameter(1); + Node* start_from = assembler.Parameter(2); + Node* context = assembler.Parameter(3 + 2); - Node* intptr_zero = assembler->IntPtrConstant(0); - Node* intptr_one = assembler->IntPtrConstant(1); + Node* intptr_zero = assembler.IntPtrConstant(0); + Node* intptr_one = assembler.IntPtrConstant(1); - Node* the_hole = assembler->TheHoleConstant(); - Node* undefined = assembler->UndefinedConstant(); - Node* heap_number_map = assembler->HeapNumberMapConstant(); + Node* the_hole = assembler.TheHoleConstant(); + Node* undefined = assembler.UndefinedConstant(); - Variable len_var(assembler, MachineType::PointerRepresentation()), - index_var(assembler, MachineType::PointerRepresentation()), - start_from_var(assembler, MachineType::PointerRepresentation()); + Variable len_var(&assembler, MachineType::PointerRepresentation()), + index_var(&assembler, MachineType::PointerRepresentation()), + start_from_var(&assembler, MachineType::PointerRepresentation()); - Label init_k(assembler), return_true(assembler), return_false(assembler), - call_runtime(assembler); + Label init_k(&assembler), return_true(&assembler), return_false(&assembler), + call_runtime(&assembler); - Label init_len(assembler); + Label init_len(&assembler); index_var.Bind(intptr_zero); len_var.Bind(intptr_zero); // Take slow path if not a JSArray, if retrieving elements requires // traversing prototype, or if access checks are required. - assembler->BranchIfFastJSArray(array, context, &init_len, &call_runtime); + assembler.BranchIfFastJSArray( + array, context, CodeStubAssembler::FastJSArrayAccessMode::INBOUNDS_READ, + &init_len, &call_runtime); - assembler->Bind(&init_len); + assembler.Bind(&init_len); { // Handle case where JSArray length is not an Smi in the runtime - Node* len = assembler->LoadObjectField(array, JSArray::kLengthOffset); - assembler->GotoUnless(assembler->TaggedIsSmi(len), &call_runtime); + Node* len = assembler.LoadObjectField(array, JSArray::kLengthOffset); + assembler.GotoUnless(assembler.TaggedIsSmi(len), &call_runtime); - len_var.Bind(assembler->SmiToWord(len)); - assembler->Branch(assembler->WordEqual(len_var.value(), intptr_zero), - &return_false, &init_k); + len_var.Bind(assembler.SmiToWord(len)); + assembler.Branch(assembler.WordEqual(len_var.value(), intptr_zero), + &return_false, &init_k); } - assembler->Bind(&init_k); + assembler.Bind(&init_k); { - Label done(assembler), init_k_smi(assembler), init_k_heap_num(assembler), - init_k_zero(assembler), init_k_n(assembler); - Node* tagged_n = assembler->ToInteger(context, start_from); + Label done(&assembler), init_k_smi(&assembler), init_k_heap_num(&assembler), + init_k_zero(&assembler), init_k_n(&assembler); + Node* tagged_n = assembler.ToInteger(context, start_from); - assembler->Branch(assembler->TaggedIsSmi(tagged_n), &init_k_smi, - &init_k_heap_num); + assembler.Branch(assembler.TaggedIsSmi(tagged_n), &init_k_smi, + &init_k_heap_num); - assembler->Bind(&init_k_smi); + assembler.Bind(&init_k_smi); { - start_from_var.Bind(assembler->SmiUntag(tagged_n)); - assembler->Goto(&init_k_n); + start_from_var.Bind(assembler.SmiUntag(tagged_n)); + assembler.Goto(&init_k_n); } - assembler->Bind(&init_k_heap_num); + assembler.Bind(&init_k_heap_num); { - Label do_return_false(assembler); + Label do_return_false(&assembler); // This round is lossless for all valid lengths. - Node* fp_len = assembler->RoundIntPtrToFloat64(len_var.value()); - Node* fp_n = assembler->LoadHeapNumberValue(tagged_n); - assembler->GotoIf(assembler->Float64GreaterThanOrEqual(fp_n, fp_len), - &do_return_false); - start_from_var.Bind(assembler->ChangeInt32ToIntPtr( - assembler->TruncateFloat64ToWord32(fp_n))); - assembler->Goto(&init_k_n); - - assembler->Bind(&do_return_false); + Node* fp_len = assembler.RoundIntPtrToFloat64(len_var.value()); + Node* fp_n = assembler.LoadHeapNumberValue(tagged_n); + assembler.GotoIf(assembler.Float64GreaterThanOrEqual(fp_n, fp_len), + &do_return_false); + start_from_var.Bind(assembler.ChangeInt32ToIntPtr( + assembler.TruncateFloat64ToWord32(fp_n))); + assembler.Goto(&init_k_n); + + assembler.Bind(&do_return_false); { index_var.Bind(intptr_zero); - assembler->Goto(&return_false); + assembler.Goto(&return_false); } } - assembler->Bind(&init_k_n); + assembler.Bind(&init_k_n); { - Label if_positive(assembler), if_negative(assembler), done(assembler); - assembler->Branch( - assembler->IntPtrLessThan(start_from_var.value(), intptr_zero), + Label if_positive(&assembler), if_negative(&assembler), done(&assembler); + assembler.Branch( + assembler.IntPtrLessThan(start_from_var.value(), intptr_zero), &if_negative, &if_positive); - assembler->Bind(&if_positive); + assembler.Bind(&if_positive); { index_var.Bind(start_from_var.value()); - assembler->Goto(&done); + assembler.Goto(&done); } - assembler->Bind(&if_negative); + assembler.Bind(&if_negative); { index_var.Bind( - assembler->IntPtrAdd(len_var.value(), start_from_var.value())); - assembler->Branch( - assembler->IntPtrLessThan(index_var.value(), intptr_zero), + assembler.IntPtrAdd(len_var.value(), start_from_var.value())); + assembler.Branch( + assembler.IntPtrLessThan(index_var.value(), intptr_zero), &init_k_zero, &done); } - assembler->Bind(&init_k_zero); + assembler.Bind(&init_k_zero); { index_var.Bind(intptr_zero); - assembler->Goto(&done); + assembler.Goto(&done); } - assembler->Bind(&done); + assembler.Bind(&done); } } @@ -1385,443 +1538,435 @@ void Builtins::Generate_ArrayIncludes(CodeStubAssembler* assembler) { FAST_HOLEY_ELEMENTS, FAST_DOUBLE_ELEMENTS, FAST_HOLEY_DOUBLE_ELEMENTS, }; - Label if_smiorobjects(assembler), if_packed_doubles(assembler), - if_holey_doubles(assembler); + Label if_smiorobjects(&assembler), if_packed_doubles(&assembler), + if_holey_doubles(&assembler); Label* element_kind_handlers[] = {&if_smiorobjects, &if_smiorobjects, &if_smiorobjects, &if_smiorobjects, &if_packed_doubles, &if_holey_doubles}; - Node* map = assembler->LoadMap(array); - Node* elements_kind = assembler->LoadMapElementsKind(map); - Node* elements = assembler->LoadElements(array); - assembler->Switch(elements_kind, &return_false, kElementsKind, - element_kind_handlers, arraysize(kElementsKind)); + Node* map = assembler.LoadMap(array); + Node* elements_kind = assembler.LoadMapElementsKind(map); + Node* elements = assembler.LoadElements(array); + assembler.Switch(elements_kind, &return_false, kElementsKind, + element_kind_handlers, arraysize(kElementsKind)); - assembler->Bind(&if_smiorobjects); + assembler.Bind(&if_smiorobjects); { - Variable search_num(assembler, MachineRepresentation::kFloat64); - Label ident_loop(assembler, &index_var), - heap_num_loop(assembler, &search_num), - string_loop(assembler, &index_var), simd_loop(assembler), - undef_loop(assembler, &index_var), not_smi(assembler), - not_heap_num(assembler); - - assembler->GotoUnless(assembler->TaggedIsSmi(search_element), ¬_smi); - search_num.Bind(assembler->SmiToFloat64(search_element)); - assembler->Goto(&heap_num_loop); - - assembler->Bind(¬_smi); - assembler->GotoIf(assembler->WordEqual(search_element, undefined), - &undef_loop); - Node* map = assembler->LoadMap(search_element); - assembler->GotoIf(assembler->WordNotEqual(map, heap_number_map), - ¬_heap_num); - search_num.Bind(assembler->LoadHeapNumberValue(search_element)); - assembler->Goto(&heap_num_loop); - - assembler->Bind(¬_heap_num); - Node* search_type = assembler->LoadMapInstanceType(map); - assembler->GotoIf(assembler->IsStringInstanceType(search_type), - &string_loop); - assembler->GotoIf( - assembler->Word32Equal(search_type, - assembler->Int32Constant(SIMD128_VALUE_TYPE)), + Variable search_num(&assembler, MachineRepresentation::kFloat64); + Label ident_loop(&assembler, &index_var), + heap_num_loop(&assembler, &search_num), + string_loop(&assembler, &index_var), simd_loop(&assembler), + undef_loop(&assembler, &index_var), not_smi(&assembler), + not_heap_num(&assembler); + + assembler.GotoUnless(assembler.TaggedIsSmi(search_element), ¬_smi); + search_num.Bind(assembler.SmiToFloat64(search_element)); + assembler.Goto(&heap_num_loop); + + assembler.Bind(¬_smi); + assembler.GotoIf(assembler.WordEqual(search_element, undefined), + &undef_loop); + Node* map = assembler.LoadMap(search_element); + assembler.GotoUnless(assembler.IsHeapNumberMap(map), ¬_heap_num); + search_num.Bind(assembler.LoadHeapNumberValue(search_element)); + assembler.Goto(&heap_num_loop); + + assembler.Bind(¬_heap_num); + Node* search_type = assembler.LoadMapInstanceType(map); + assembler.GotoIf(assembler.IsStringInstanceType(search_type), &string_loop); + assembler.GotoIf( + assembler.Word32Equal(search_type, + assembler.Int32Constant(SIMD128_VALUE_TYPE)), &simd_loop); - assembler->Goto(&ident_loop); + assembler.Goto(&ident_loop); - assembler->Bind(&ident_loop); + assembler.Bind(&ident_loop); { - assembler->GotoUnless( - assembler->UintPtrLessThan(index_var.value(), len_var.value()), + assembler.GotoUnless( + assembler.UintPtrLessThan(index_var.value(), len_var.value()), &return_false); - Node* element_k = assembler->LoadFixedArrayElement( - elements, index_var.value(), 0, CodeStubAssembler::INTPTR_PARAMETERS); - assembler->GotoIf(assembler->WordEqual(element_k, search_element), - &return_true); + Node* element_k = + assembler.LoadFixedArrayElement(elements, index_var.value()); + assembler.GotoIf(assembler.WordEqual(element_k, search_element), + &return_true); - index_var.Bind(assembler->IntPtrAdd(index_var.value(), intptr_one)); - assembler->Goto(&ident_loop); + index_var.Bind(assembler.IntPtrAdd(index_var.value(), intptr_one)); + assembler.Goto(&ident_loop); } - assembler->Bind(&undef_loop); + assembler.Bind(&undef_loop); { - assembler->GotoUnless( - assembler->UintPtrLessThan(index_var.value(), len_var.value()), + assembler.GotoUnless( + assembler.UintPtrLessThan(index_var.value(), len_var.value()), &return_false); - Node* element_k = assembler->LoadFixedArrayElement( - elements, index_var.value(), 0, CodeStubAssembler::INTPTR_PARAMETERS); - assembler->GotoIf(assembler->WordEqual(element_k, undefined), - &return_true); - assembler->GotoIf(assembler->WordEqual(element_k, the_hole), - &return_true); + Node* element_k = + assembler.LoadFixedArrayElement(elements, index_var.value()); + assembler.GotoIf(assembler.WordEqual(element_k, undefined), &return_true); + assembler.GotoIf(assembler.WordEqual(element_k, the_hole), &return_true); - index_var.Bind(assembler->IntPtrAdd(index_var.value(), intptr_one)); - assembler->Goto(&undef_loop); + index_var.Bind(assembler.IntPtrAdd(index_var.value(), intptr_one)); + assembler.Goto(&undef_loop); } - assembler->Bind(&heap_num_loop); + assembler.Bind(&heap_num_loop); { - Label nan_loop(assembler, &index_var), - not_nan_loop(assembler, &index_var); - assembler->BranchIfFloat64IsNaN(search_num.value(), &nan_loop, - ¬_nan_loop); + Label nan_loop(&assembler, &index_var), + not_nan_loop(&assembler, &index_var); + assembler.BranchIfFloat64IsNaN(search_num.value(), &nan_loop, + ¬_nan_loop); - assembler->Bind(¬_nan_loop); + assembler.Bind(¬_nan_loop); { - Label continue_loop(assembler), not_smi(assembler); - assembler->GotoUnless( - assembler->UintPtrLessThan(index_var.value(), len_var.value()), + Label continue_loop(&assembler), not_smi(&assembler); + assembler.GotoUnless( + assembler.UintPtrLessThan(index_var.value(), len_var.value()), &return_false); - Node* element_k = assembler->LoadFixedArrayElement( - elements, index_var.value(), 0, - CodeStubAssembler::INTPTR_PARAMETERS); - assembler->GotoUnless(assembler->TaggedIsSmi(element_k), ¬_smi); - assembler->Branch( - assembler->Float64Equal(search_num.value(), - assembler->SmiToFloat64(element_k)), + Node* element_k = + assembler.LoadFixedArrayElement(elements, index_var.value()); + assembler.GotoUnless(assembler.TaggedIsSmi(element_k), ¬_smi); + assembler.Branch( + assembler.Float64Equal(search_num.value(), + assembler.SmiToFloat64(element_k)), &return_true, &continue_loop); - assembler->Bind(¬_smi); - assembler->GotoIf(assembler->WordNotEqual(assembler->LoadMap(element_k), - heap_number_map), - &continue_loop); - assembler->Branch( - assembler->Float64Equal(search_num.value(), - assembler->LoadHeapNumberValue(element_k)), + assembler.Bind(¬_smi); + assembler.GotoUnless( + assembler.IsHeapNumberMap(assembler.LoadMap(element_k)), + &continue_loop); + assembler.Branch( + assembler.Float64Equal(search_num.value(), + assembler.LoadHeapNumberValue(element_k)), &return_true, &continue_loop); - assembler->Bind(&continue_loop); - index_var.Bind(assembler->IntPtrAdd(index_var.value(), intptr_one)); - assembler->Goto(¬_nan_loop); + assembler.Bind(&continue_loop); + index_var.Bind(assembler.IntPtrAdd(index_var.value(), intptr_one)); + assembler.Goto(¬_nan_loop); } - assembler->Bind(&nan_loop); + assembler.Bind(&nan_loop); { - Label continue_loop(assembler); - assembler->GotoUnless( - assembler->UintPtrLessThan(index_var.value(), len_var.value()), + Label continue_loop(&assembler); + assembler.GotoUnless( + assembler.UintPtrLessThan(index_var.value(), len_var.value()), &return_false); - Node* element_k = assembler->LoadFixedArrayElement( - elements, index_var.value(), 0, - CodeStubAssembler::INTPTR_PARAMETERS); - assembler->GotoIf(assembler->TaggedIsSmi(element_k), &continue_loop); - assembler->GotoIf(assembler->WordNotEqual(assembler->LoadMap(element_k), - heap_number_map), - &continue_loop); - assembler->BranchIfFloat64IsNaN( - assembler->LoadHeapNumberValue(element_k), &return_true, + Node* element_k = + assembler.LoadFixedArrayElement(elements, index_var.value()); + assembler.GotoIf(assembler.TaggedIsSmi(element_k), &continue_loop); + assembler.GotoUnless( + assembler.IsHeapNumberMap(assembler.LoadMap(element_k)), &continue_loop); + assembler.BranchIfFloat64IsNaN(assembler.LoadHeapNumberValue(element_k), + &return_true, &continue_loop); - assembler->Bind(&continue_loop); - index_var.Bind(assembler->IntPtrAdd(index_var.value(), intptr_one)); - assembler->Goto(&nan_loop); + assembler.Bind(&continue_loop); + index_var.Bind(assembler.IntPtrAdd(index_var.value(), intptr_one)); + assembler.Goto(&nan_loop); } } - assembler->Bind(&string_loop); + assembler.Bind(&string_loop); { - Label continue_loop(assembler); - assembler->GotoUnless( - assembler->UintPtrLessThan(index_var.value(), len_var.value()), + Label continue_loop(&assembler); + assembler.GotoUnless( + assembler.UintPtrLessThan(index_var.value(), len_var.value()), &return_false); - Node* element_k = assembler->LoadFixedArrayElement( - elements, index_var.value(), 0, CodeStubAssembler::INTPTR_PARAMETERS); - assembler->GotoIf(assembler->TaggedIsSmi(element_k), &continue_loop); - assembler->GotoUnless(assembler->IsStringInstanceType( - assembler->LoadInstanceType(element_k)), - &continue_loop); + Node* element_k = + assembler.LoadFixedArrayElement(elements, index_var.value()); + assembler.GotoIf(assembler.TaggedIsSmi(element_k), &continue_loop); + assembler.GotoUnless( + assembler.IsStringInstanceType(assembler.LoadInstanceType(element_k)), + &continue_loop); // TODO(bmeurer): Consider inlining the StringEqual logic here. - Callable callable = CodeFactory::StringEqual(assembler->isolate()); + Callable callable = CodeFactory::StringEqual(assembler.isolate()); Node* result = - assembler->CallStub(callable, context, search_element, element_k); - assembler->Branch( - assembler->WordEqual(assembler->BooleanConstant(true), result), + assembler.CallStub(callable, context, search_element, element_k); + assembler.Branch( + assembler.WordEqual(assembler.BooleanConstant(true), result), &return_true, &continue_loop); - assembler->Bind(&continue_loop); - index_var.Bind(assembler->IntPtrAdd(index_var.value(), intptr_one)); - assembler->Goto(&string_loop); + assembler.Bind(&continue_loop); + index_var.Bind(assembler.IntPtrAdd(index_var.value(), intptr_one)); + assembler.Goto(&string_loop); } - assembler->Bind(&simd_loop); + assembler.Bind(&simd_loop); { - Label continue_loop(assembler, &index_var), - loop_body(assembler, &index_var); - Node* map = assembler->LoadMap(search_element); - - assembler->Goto(&loop_body); - assembler->Bind(&loop_body); - assembler->GotoUnless( - assembler->UintPtrLessThan(index_var.value(), len_var.value()), + Label continue_loop(&assembler, &index_var), + loop_body(&assembler, &index_var); + Node* map = assembler.LoadMap(search_element); + + assembler.Goto(&loop_body); + assembler.Bind(&loop_body); + assembler.GotoUnless( + assembler.UintPtrLessThan(index_var.value(), len_var.value()), &return_false); - Node* element_k = assembler->LoadFixedArrayElement( - elements, index_var.value(), 0, CodeStubAssembler::INTPTR_PARAMETERS); - assembler->GotoIf(assembler->TaggedIsSmi(element_k), &continue_loop); + Node* element_k = + assembler.LoadFixedArrayElement(elements, index_var.value()); + assembler.GotoIf(assembler.TaggedIsSmi(element_k), &continue_loop); - Node* map_k = assembler->LoadMap(element_k); - assembler->BranchIfSimd128Equal(search_element, map, element_k, map_k, - &return_true, &continue_loop); + Node* map_k = assembler.LoadMap(element_k); + assembler.BranchIfSimd128Equal(search_element, map, element_k, map_k, + &return_true, &continue_loop); - assembler->Bind(&continue_loop); - index_var.Bind(assembler->IntPtrAdd(index_var.value(), intptr_one)); - assembler->Goto(&loop_body); + assembler.Bind(&continue_loop); + index_var.Bind(assembler.IntPtrAdd(index_var.value(), intptr_one)); + assembler.Goto(&loop_body); } } - assembler->Bind(&if_packed_doubles); + assembler.Bind(&if_packed_doubles); { - Label nan_loop(assembler, &index_var), not_nan_loop(assembler, &index_var), - hole_loop(assembler, &index_var), search_notnan(assembler); - Variable search_num(assembler, MachineRepresentation::kFloat64); + Label nan_loop(&assembler, &index_var), + not_nan_loop(&assembler, &index_var), hole_loop(&assembler, &index_var), + search_notnan(&assembler); + Variable search_num(&assembler, MachineRepresentation::kFloat64); - assembler->GotoUnless(assembler->TaggedIsSmi(search_element), - &search_notnan); - search_num.Bind(assembler->SmiToFloat64(search_element)); - assembler->Goto(¬_nan_loop); + assembler.GotoUnless(assembler.TaggedIsSmi(search_element), &search_notnan); + search_num.Bind(assembler.SmiToFloat64(search_element)); + assembler.Goto(¬_nan_loop); - assembler->Bind(&search_notnan); - assembler->GotoIf(assembler->WordNotEqual( - assembler->LoadMap(search_element), heap_number_map), - &return_false); + assembler.Bind(&search_notnan); + assembler.GotoUnless( + assembler.IsHeapNumberMap(assembler.LoadMap(search_element)), + &return_false); - search_num.Bind(assembler->LoadHeapNumberValue(search_element)); + search_num.Bind(assembler.LoadHeapNumberValue(search_element)); - assembler->BranchIfFloat64IsNaN(search_num.value(), &nan_loop, - ¬_nan_loop); + assembler.BranchIfFloat64IsNaN(search_num.value(), &nan_loop, + ¬_nan_loop); // Search for HeapNumber - assembler->Bind(¬_nan_loop); + assembler.Bind(¬_nan_loop); { - Label continue_loop(assembler); - assembler->GotoUnless( - assembler->UintPtrLessThan(index_var.value(), len_var.value()), + Label continue_loop(&assembler); + assembler.GotoUnless( + assembler.UintPtrLessThan(index_var.value(), len_var.value()), &return_false); - Node* element_k = assembler->LoadFixedDoubleArrayElement( - elements, index_var.value(), MachineType::Float64(), 0, - CodeStubAssembler::INTPTR_PARAMETERS); - assembler->Branch(assembler->Float64Equal(element_k, search_num.value()), - &return_true, &continue_loop); - assembler->Bind(&continue_loop); - index_var.Bind(assembler->IntPtrAdd(index_var.value(), intptr_one)); - assembler->Goto(¬_nan_loop); + Node* element_k = assembler.LoadFixedDoubleArrayElement( + elements, index_var.value(), MachineType::Float64()); + assembler.Branch(assembler.Float64Equal(element_k, search_num.value()), + &return_true, &continue_loop); + assembler.Bind(&continue_loop); + index_var.Bind(assembler.IntPtrAdd(index_var.value(), intptr_one)); + assembler.Goto(¬_nan_loop); } // Search for NaN - assembler->Bind(&nan_loop); + assembler.Bind(&nan_loop); { - Label continue_loop(assembler); - assembler->GotoUnless( - assembler->UintPtrLessThan(index_var.value(), len_var.value()), + Label continue_loop(&assembler); + assembler.GotoUnless( + assembler.UintPtrLessThan(index_var.value(), len_var.value()), &return_false); - Node* element_k = assembler->LoadFixedDoubleArrayElement( - elements, index_var.value(), MachineType::Float64(), 0, - CodeStubAssembler::INTPTR_PARAMETERS); - assembler->BranchIfFloat64IsNaN(element_k, &return_true, &continue_loop); - assembler->Bind(&continue_loop); - index_var.Bind(assembler->IntPtrAdd(index_var.value(), intptr_one)); - assembler->Goto(&nan_loop); + Node* element_k = assembler.LoadFixedDoubleArrayElement( + elements, index_var.value(), MachineType::Float64()); + assembler.BranchIfFloat64IsNaN(element_k, &return_true, &continue_loop); + assembler.Bind(&continue_loop); + index_var.Bind(assembler.IntPtrAdd(index_var.value(), intptr_one)); + assembler.Goto(&nan_loop); } } - assembler->Bind(&if_holey_doubles); + assembler.Bind(&if_holey_doubles); { - Label nan_loop(assembler, &index_var), not_nan_loop(assembler, &index_var), - hole_loop(assembler, &index_var), search_notnan(assembler); - Variable search_num(assembler, MachineRepresentation::kFloat64); + Label nan_loop(&assembler, &index_var), + not_nan_loop(&assembler, &index_var), hole_loop(&assembler, &index_var), + search_notnan(&assembler); + Variable search_num(&assembler, MachineRepresentation::kFloat64); - assembler->GotoUnless(assembler->TaggedIsSmi(search_element), - &search_notnan); - search_num.Bind(assembler->SmiToFloat64(search_element)); - assembler->Goto(¬_nan_loop); + assembler.GotoUnless(assembler.TaggedIsSmi(search_element), &search_notnan); + search_num.Bind(assembler.SmiToFloat64(search_element)); + assembler.Goto(¬_nan_loop); - assembler->Bind(&search_notnan); - assembler->GotoIf(assembler->WordEqual(search_element, undefined), - &hole_loop); - assembler->GotoIf(assembler->WordNotEqual( - assembler->LoadMap(search_element), heap_number_map), - &return_false); + assembler.Bind(&search_notnan); + assembler.GotoIf(assembler.WordEqual(search_element, undefined), + &hole_loop); + assembler.GotoUnless( + assembler.IsHeapNumberMap(assembler.LoadMap(search_element)), + &return_false); - search_num.Bind(assembler->LoadHeapNumberValue(search_element)); + search_num.Bind(assembler.LoadHeapNumberValue(search_element)); - assembler->BranchIfFloat64IsNaN(search_num.value(), &nan_loop, - ¬_nan_loop); + assembler.BranchIfFloat64IsNaN(search_num.value(), &nan_loop, + ¬_nan_loop); // Search for HeapNumber - assembler->Bind(¬_nan_loop); + assembler.Bind(¬_nan_loop); { - Label continue_loop(assembler); - assembler->GotoUnless( - assembler->UintPtrLessThan(index_var.value(), len_var.value()), + Label continue_loop(&assembler); + assembler.GotoUnless( + assembler.UintPtrLessThan(index_var.value(), len_var.value()), &return_false); // Load double value or continue if it contains a double hole. - Node* element_k = assembler->LoadFixedDoubleArrayElement( + Node* element_k = assembler.LoadFixedDoubleArrayElement( elements, index_var.value(), MachineType::Float64(), 0, CodeStubAssembler::INTPTR_PARAMETERS, &continue_loop); - assembler->Branch(assembler->Float64Equal(element_k, search_num.value()), - &return_true, &continue_loop); - assembler->Bind(&continue_loop); - index_var.Bind(assembler->IntPtrAdd(index_var.value(), intptr_one)); - assembler->Goto(¬_nan_loop); + assembler.Branch(assembler.Float64Equal(element_k, search_num.value()), + &return_true, &continue_loop); + assembler.Bind(&continue_loop); + index_var.Bind(assembler.IntPtrAdd(index_var.value(), intptr_one)); + assembler.Goto(¬_nan_loop); } // Search for NaN - assembler->Bind(&nan_loop); + assembler.Bind(&nan_loop); { - Label continue_loop(assembler); - assembler->GotoUnless( - assembler->UintPtrLessThan(index_var.value(), len_var.value()), + Label continue_loop(&assembler); + assembler.GotoUnless( + assembler.UintPtrLessThan(index_var.value(), len_var.value()), &return_false); // Load double value or continue if it contains a double hole. - Node* element_k = assembler->LoadFixedDoubleArrayElement( + Node* element_k = assembler.LoadFixedDoubleArrayElement( elements, index_var.value(), MachineType::Float64(), 0, CodeStubAssembler::INTPTR_PARAMETERS, &continue_loop); - assembler->BranchIfFloat64IsNaN(element_k, &return_true, &continue_loop); - assembler->Bind(&continue_loop); - index_var.Bind(assembler->IntPtrAdd(index_var.value(), intptr_one)); - assembler->Goto(&nan_loop); + assembler.BranchIfFloat64IsNaN(element_k, &return_true, &continue_loop); + assembler.Bind(&continue_loop); + index_var.Bind(assembler.IntPtrAdd(index_var.value(), intptr_one)); + assembler.Goto(&nan_loop); } // Search for the Hole - assembler->Bind(&hole_loop); + assembler.Bind(&hole_loop); { - assembler->GotoUnless( - assembler->UintPtrLessThan(index_var.value(), len_var.value()), + assembler.GotoUnless( + assembler.UintPtrLessThan(index_var.value(), len_var.value()), &return_false); // Check if the element is a double hole, but don't load it. - assembler->LoadFixedDoubleArrayElement( + assembler.LoadFixedDoubleArrayElement( elements, index_var.value(), MachineType::None(), 0, CodeStubAssembler::INTPTR_PARAMETERS, &return_true); - index_var.Bind(assembler->IntPtrAdd(index_var.value(), intptr_one)); - assembler->Goto(&hole_loop); + index_var.Bind(assembler.IntPtrAdd(index_var.value(), intptr_one)); + assembler.Goto(&hole_loop); } } - assembler->Bind(&return_true); - assembler->Return(assembler->BooleanConstant(true)); + assembler.Bind(&return_true); + assembler.Return(assembler.BooleanConstant(true)); - assembler->Bind(&return_false); - assembler->Return(assembler->BooleanConstant(false)); + assembler.Bind(&return_false); + assembler.Return(assembler.BooleanConstant(false)); - assembler->Bind(&call_runtime); - assembler->Return(assembler->CallRuntime(Runtime::kArrayIncludes_Slow, - context, array, search_element, - start_from)); + assembler.Bind(&call_runtime); + assembler.Return(assembler.CallRuntime(Runtime::kArrayIncludes_Slow, context, + array, search_element, start_from)); } -void Builtins::Generate_ArrayIndexOf(CodeStubAssembler* assembler) { +void Builtins::Generate_ArrayIndexOf(compiler::CodeAssemblerState* state) { typedef compiler::Node Node; typedef CodeStubAssembler::Label Label; typedef CodeStubAssembler::Variable Variable; + CodeStubAssembler assembler(state); - Node* array = assembler->Parameter(0); - Node* search_element = assembler->Parameter(1); - Node* start_from = assembler->Parameter(2); - Node* context = assembler->Parameter(3 + 2); + Node* array = assembler.Parameter(0); + Node* search_element = assembler.Parameter(1); + Node* start_from = assembler.Parameter(2); + Node* context = assembler.Parameter(3 + 2); - Node* intptr_zero = assembler->IntPtrConstant(0); - Node* intptr_one = assembler->IntPtrConstant(1); + Node* intptr_zero = assembler.IntPtrConstant(0); + Node* intptr_one = assembler.IntPtrConstant(1); - Node* undefined = assembler->UndefinedConstant(); - Node* heap_number_map = assembler->HeapNumberMapConstant(); + Node* undefined = assembler.UndefinedConstant(); - Variable len_var(assembler, MachineType::PointerRepresentation()), - index_var(assembler, MachineType::PointerRepresentation()), - start_from_var(assembler, MachineType::PointerRepresentation()); + Variable len_var(&assembler, MachineType::PointerRepresentation()), + index_var(&assembler, MachineType::PointerRepresentation()), + start_from_var(&assembler, MachineType::PointerRepresentation()); - Label init_k(assembler), return_found(assembler), return_not_found(assembler), - call_runtime(assembler); + Label init_k(&assembler), return_found(&assembler), + return_not_found(&assembler), call_runtime(&assembler); - Label init_len(assembler); + Label init_len(&assembler); index_var.Bind(intptr_zero); len_var.Bind(intptr_zero); // Take slow path if not a JSArray, if retrieving elements requires // traversing prototype, or if access checks are required. - assembler->BranchIfFastJSArray(array, context, &init_len, &call_runtime); + assembler.BranchIfFastJSArray( + array, context, CodeStubAssembler::FastJSArrayAccessMode::INBOUNDS_READ, + &init_len, &call_runtime); - assembler->Bind(&init_len); + assembler.Bind(&init_len); { // Handle case where JSArray length is not an Smi in the runtime - Node* len = assembler->LoadObjectField(array, JSArray::kLengthOffset); - assembler->GotoUnless(assembler->TaggedIsSmi(len), &call_runtime); + Node* len = assembler.LoadObjectField(array, JSArray::kLengthOffset); + assembler.GotoUnless(assembler.TaggedIsSmi(len), &call_runtime); - len_var.Bind(assembler->SmiToWord(len)); - assembler->Branch(assembler->WordEqual(len_var.value(), intptr_zero), - &return_not_found, &init_k); + len_var.Bind(assembler.SmiToWord(len)); + assembler.Branch(assembler.WordEqual(len_var.value(), intptr_zero), + &return_not_found, &init_k); } - assembler->Bind(&init_k); + assembler.Bind(&init_k); { - Label done(assembler), init_k_smi(assembler), init_k_heap_num(assembler), - init_k_zero(assembler), init_k_n(assembler); - Node* tagged_n = assembler->ToInteger(context, start_from); + Label done(&assembler), init_k_smi(&assembler), init_k_heap_num(&assembler), + init_k_zero(&assembler), init_k_n(&assembler); + Node* tagged_n = assembler.ToInteger(context, start_from); - assembler->Branch(assembler->TaggedIsSmi(tagged_n), &init_k_smi, - &init_k_heap_num); + assembler.Branch(assembler.TaggedIsSmi(tagged_n), &init_k_smi, + &init_k_heap_num); - assembler->Bind(&init_k_smi); + assembler.Bind(&init_k_smi); { - start_from_var.Bind(assembler->SmiUntag(tagged_n)); - assembler->Goto(&init_k_n); + start_from_var.Bind(assembler.SmiUntag(tagged_n)); + assembler.Goto(&init_k_n); } - assembler->Bind(&init_k_heap_num); + assembler.Bind(&init_k_heap_num); { - Label do_return_not_found(assembler); + Label do_return_not_found(&assembler); // This round is lossless for all valid lengths. - Node* fp_len = assembler->RoundIntPtrToFloat64(len_var.value()); - Node* fp_n = assembler->LoadHeapNumberValue(tagged_n); - assembler->GotoIf(assembler->Float64GreaterThanOrEqual(fp_n, fp_len), - &do_return_not_found); - start_from_var.Bind(assembler->ChangeInt32ToIntPtr( - assembler->TruncateFloat64ToWord32(fp_n))); - assembler->Goto(&init_k_n); - - assembler->Bind(&do_return_not_found); + Node* fp_len = assembler.RoundIntPtrToFloat64(len_var.value()); + Node* fp_n = assembler.LoadHeapNumberValue(tagged_n); + assembler.GotoIf(assembler.Float64GreaterThanOrEqual(fp_n, fp_len), + &do_return_not_found); + start_from_var.Bind(assembler.ChangeInt32ToIntPtr( + assembler.TruncateFloat64ToWord32(fp_n))); + assembler.Goto(&init_k_n); + + assembler.Bind(&do_return_not_found); { index_var.Bind(intptr_zero); - assembler->Goto(&return_not_found); + assembler.Goto(&return_not_found); } } - assembler->Bind(&init_k_n); + assembler.Bind(&init_k_n); { - Label if_positive(assembler), if_negative(assembler), done(assembler); - assembler->Branch( - assembler->IntPtrLessThan(start_from_var.value(), intptr_zero), + Label if_positive(&assembler), if_negative(&assembler), done(&assembler); + assembler.Branch( + assembler.IntPtrLessThan(start_from_var.value(), intptr_zero), &if_negative, &if_positive); - assembler->Bind(&if_positive); + assembler.Bind(&if_positive); { index_var.Bind(start_from_var.value()); - assembler->Goto(&done); + assembler.Goto(&done); } - assembler->Bind(&if_negative); + assembler.Bind(&if_negative); { index_var.Bind( - assembler->IntPtrAdd(len_var.value(), start_from_var.value())); - assembler->Branch( - assembler->IntPtrLessThan(index_var.value(), intptr_zero), + assembler.IntPtrAdd(len_var.value(), start_from_var.value())); + assembler.Branch( + assembler.IntPtrLessThan(index_var.value(), intptr_zero), &init_k_zero, &done); } - assembler->Bind(&init_k_zero); + assembler.Bind(&init_k_zero); { index_var.Bind(intptr_zero); - assembler->Goto(&done); + assembler.Goto(&done); } - assembler->Bind(&done); + assembler.Bind(&done); } } @@ -1830,384 +1975,387 @@ void Builtins::Generate_ArrayIndexOf(CodeStubAssembler* assembler) { FAST_HOLEY_ELEMENTS, FAST_DOUBLE_ELEMENTS, FAST_HOLEY_DOUBLE_ELEMENTS, }; - Label if_smiorobjects(assembler), if_packed_doubles(assembler), - if_holey_doubles(assembler); + Label if_smiorobjects(&assembler), if_packed_doubles(&assembler), + if_holey_doubles(&assembler); Label* element_kind_handlers[] = {&if_smiorobjects, &if_smiorobjects, &if_smiorobjects, &if_smiorobjects, &if_packed_doubles, &if_holey_doubles}; - Node* map = assembler->LoadMap(array); - Node* elements_kind = assembler->LoadMapElementsKind(map); - Node* elements = assembler->LoadElements(array); - assembler->Switch(elements_kind, &return_not_found, kElementsKind, - element_kind_handlers, arraysize(kElementsKind)); + Node* map = assembler.LoadMap(array); + Node* elements_kind = assembler.LoadMapElementsKind(map); + Node* elements = assembler.LoadElements(array); + assembler.Switch(elements_kind, &return_not_found, kElementsKind, + element_kind_handlers, arraysize(kElementsKind)); - assembler->Bind(&if_smiorobjects); + assembler.Bind(&if_smiorobjects); { - Variable search_num(assembler, MachineRepresentation::kFloat64); - Label ident_loop(assembler, &index_var), - heap_num_loop(assembler, &search_num), - string_loop(assembler, &index_var), simd_loop(assembler), - undef_loop(assembler, &index_var), not_smi(assembler), - not_heap_num(assembler); - - assembler->GotoUnless(assembler->TaggedIsSmi(search_element), ¬_smi); - search_num.Bind(assembler->SmiToFloat64(search_element)); - assembler->Goto(&heap_num_loop); - - assembler->Bind(¬_smi); - assembler->GotoIf(assembler->WordEqual(search_element, undefined), - &undef_loop); - Node* map = assembler->LoadMap(search_element); - assembler->GotoIf(assembler->WordNotEqual(map, heap_number_map), - ¬_heap_num); - search_num.Bind(assembler->LoadHeapNumberValue(search_element)); - assembler->Goto(&heap_num_loop); - - assembler->Bind(¬_heap_num); - Node* search_type = assembler->LoadMapInstanceType(map); - assembler->GotoIf(assembler->IsStringInstanceType(search_type), - &string_loop); - assembler->GotoIf( - assembler->Word32Equal(search_type, - assembler->Int32Constant(SIMD128_VALUE_TYPE)), + Variable search_num(&assembler, MachineRepresentation::kFloat64); + Label ident_loop(&assembler, &index_var), + heap_num_loop(&assembler, &search_num), + string_loop(&assembler, &index_var), simd_loop(&assembler), + undef_loop(&assembler, &index_var), not_smi(&assembler), + not_heap_num(&assembler); + + assembler.GotoUnless(assembler.TaggedIsSmi(search_element), ¬_smi); + search_num.Bind(assembler.SmiToFloat64(search_element)); + assembler.Goto(&heap_num_loop); + + assembler.Bind(¬_smi); + assembler.GotoIf(assembler.WordEqual(search_element, undefined), + &undef_loop); + Node* map = assembler.LoadMap(search_element); + assembler.GotoUnless(assembler.IsHeapNumberMap(map), ¬_heap_num); + search_num.Bind(assembler.LoadHeapNumberValue(search_element)); + assembler.Goto(&heap_num_loop); + + assembler.Bind(¬_heap_num); + Node* search_type = assembler.LoadMapInstanceType(map); + assembler.GotoIf(assembler.IsStringInstanceType(search_type), &string_loop); + assembler.GotoIf( + assembler.Word32Equal(search_type, + assembler.Int32Constant(SIMD128_VALUE_TYPE)), &simd_loop); - assembler->Goto(&ident_loop); + assembler.Goto(&ident_loop); - assembler->Bind(&ident_loop); + assembler.Bind(&ident_loop); { - assembler->GotoUnless( - assembler->UintPtrLessThan(index_var.value(), len_var.value()), + assembler.GotoUnless( + assembler.UintPtrLessThan(index_var.value(), len_var.value()), &return_not_found); - Node* element_k = assembler->LoadFixedArrayElement( - elements, index_var.value(), 0, CodeStubAssembler::INTPTR_PARAMETERS); - assembler->GotoIf(assembler->WordEqual(element_k, search_element), - &return_found); + Node* element_k = + assembler.LoadFixedArrayElement(elements, index_var.value()); + assembler.GotoIf(assembler.WordEqual(element_k, search_element), + &return_found); - index_var.Bind(assembler->IntPtrAdd(index_var.value(), intptr_one)); - assembler->Goto(&ident_loop); + index_var.Bind(assembler.IntPtrAdd(index_var.value(), intptr_one)); + assembler.Goto(&ident_loop); } - assembler->Bind(&undef_loop); + assembler.Bind(&undef_loop); { - assembler->GotoUnless( - assembler->UintPtrLessThan(index_var.value(), len_var.value()), + assembler.GotoUnless( + assembler.UintPtrLessThan(index_var.value(), len_var.value()), &return_not_found); - Node* element_k = assembler->LoadFixedArrayElement( - elements, index_var.value(), 0, CodeStubAssembler::INTPTR_PARAMETERS); - assembler->GotoIf(assembler->WordEqual(element_k, undefined), - &return_found); + Node* element_k = + assembler.LoadFixedArrayElement(elements, index_var.value()); + assembler.GotoIf(assembler.WordEqual(element_k, undefined), + &return_found); - index_var.Bind(assembler->IntPtrAdd(index_var.value(), intptr_one)); - assembler->Goto(&undef_loop); + index_var.Bind(assembler.IntPtrAdd(index_var.value(), intptr_one)); + assembler.Goto(&undef_loop); } - assembler->Bind(&heap_num_loop); + assembler.Bind(&heap_num_loop); { - Label not_nan_loop(assembler, &index_var); - assembler->BranchIfFloat64IsNaN(search_num.value(), &return_not_found, - ¬_nan_loop); + Label not_nan_loop(&assembler, &index_var); + assembler.BranchIfFloat64IsNaN(search_num.value(), &return_not_found, + ¬_nan_loop); - assembler->Bind(¬_nan_loop); + assembler.Bind(¬_nan_loop); { - Label continue_loop(assembler), not_smi(assembler); - assembler->GotoUnless( - assembler->UintPtrLessThan(index_var.value(), len_var.value()), + Label continue_loop(&assembler), not_smi(&assembler); + assembler.GotoUnless( + assembler.UintPtrLessThan(index_var.value(), len_var.value()), &return_not_found); - Node* element_k = assembler->LoadFixedArrayElement( - elements, index_var.value(), 0, - CodeStubAssembler::INTPTR_PARAMETERS); - assembler->GotoUnless(assembler->TaggedIsSmi(element_k), ¬_smi); - assembler->Branch( - assembler->Float64Equal(search_num.value(), - assembler->SmiToFloat64(element_k)), + Node* element_k = + assembler.LoadFixedArrayElement(elements, index_var.value()); + assembler.GotoUnless(assembler.TaggedIsSmi(element_k), ¬_smi); + assembler.Branch( + assembler.Float64Equal(search_num.value(), + assembler.SmiToFloat64(element_k)), &return_found, &continue_loop); - assembler->Bind(¬_smi); - assembler->GotoIf(assembler->WordNotEqual(assembler->LoadMap(element_k), - heap_number_map), - &continue_loop); - assembler->Branch( - assembler->Float64Equal(search_num.value(), - assembler->LoadHeapNumberValue(element_k)), + assembler.Bind(¬_smi); + assembler.GotoUnless( + assembler.IsHeapNumberMap(assembler.LoadMap(element_k)), + &continue_loop); + assembler.Branch( + assembler.Float64Equal(search_num.value(), + assembler.LoadHeapNumberValue(element_k)), &return_found, &continue_loop); - assembler->Bind(&continue_loop); - index_var.Bind(assembler->IntPtrAdd(index_var.value(), intptr_one)); - assembler->Goto(¬_nan_loop); + assembler.Bind(&continue_loop); + index_var.Bind(assembler.IntPtrAdd(index_var.value(), intptr_one)); + assembler.Goto(¬_nan_loop); } } - assembler->Bind(&string_loop); + assembler.Bind(&string_loop); { - Label continue_loop(assembler); - assembler->GotoUnless( - assembler->UintPtrLessThan(index_var.value(), len_var.value()), + Label continue_loop(&assembler); + assembler.GotoUnless( + assembler.UintPtrLessThan(index_var.value(), len_var.value()), &return_not_found); - Node* element_k = assembler->LoadFixedArrayElement( - elements, index_var.value(), 0, CodeStubAssembler::INTPTR_PARAMETERS); - assembler->GotoIf(assembler->TaggedIsSmi(element_k), &continue_loop); - assembler->GotoUnless(assembler->IsStringInstanceType( - assembler->LoadInstanceType(element_k)), - &continue_loop); + Node* element_k = + assembler.LoadFixedArrayElement(elements, index_var.value()); + assembler.GotoIf(assembler.TaggedIsSmi(element_k), &continue_loop); + assembler.GotoUnless( + assembler.IsStringInstanceType(assembler.LoadInstanceType(element_k)), + &continue_loop); // TODO(bmeurer): Consider inlining the StringEqual logic here. - Callable callable = CodeFactory::StringEqual(assembler->isolate()); + Callable callable = CodeFactory::StringEqual(assembler.isolate()); Node* result = - assembler->CallStub(callable, context, search_element, element_k); - assembler->Branch( - assembler->WordEqual(assembler->BooleanConstant(true), result), + assembler.CallStub(callable, context, search_element, element_k); + assembler.Branch( + assembler.WordEqual(assembler.BooleanConstant(true), result), &return_found, &continue_loop); - assembler->Bind(&continue_loop); - index_var.Bind(assembler->IntPtrAdd(index_var.value(), intptr_one)); - assembler->Goto(&string_loop); + assembler.Bind(&continue_loop); + index_var.Bind(assembler.IntPtrAdd(index_var.value(), intptr_one)); + assembler.Goto(&string_loop); } - assembler->Bind(&simd_loop); + assembler.Bind(&simd_loop); { - Label continue_loop(assembler, &index_var), - loop_body(assembler, &index_var); - Node* map = assembler->LoadMap(search_element); - - assembler->Goto(&loop_body); - assembler->Bind(&loop_body); - assembler->GotoUnless( - assembler->UintPtrLessThan(index_var.value(), len_var.value()), + Label continue_loop(&assembler, &index_var), + loop_body(&assembler, &index_var); + Node* map = assembler.LoadMap(search_element); + + assembler.Goto(&loop_body); + assembler.Bind(&loop_body); + assembler.GotoUnless( + assembler.UintPtrLessThan(index_var.value(), len_var.value()), &return_not_found); - Node* element_k = assembler->LoadFixedArrayElement( - elements, index_var.value(), 0, CodeStubAssembler::INTPTR_PARAMETERS); - assembler->GotoIf(assembler->TaggedIsSmi(element_k), &continue_loop); + Node* element_k = + assembler.LoadFixedArrayElement(elements, index_var.value()); + assembler.GotoIf(assembler.TaggedIsSmi(element_k), &continue_loop); - Node* map_k = assembler->LoadMap(element_k); - assembler->BranchIfSimd128Equal(search_element, map, element_k, map_k, - &return_found, &continue_loop); + Node* map_k = assembler.LoadMap(element_k); + assembler.BranchIfSimd128Equal(search_element, map, element_k, map_k, + &return_found, &continue_loop); - assembler->Bind(&continue_loop); - index_var.Bind(assembler->IntPtrAdd(index_var.value(), intptr_one)); - assembler->Goto(&loop_body); + assembler.Bind(&continue_loop); + index_var.Bind(assembler.IntPtrAdd(index_var.value(), intptr_one)); + assembler.Goto(&loop_body); } } - assembler->Bind(&if_packed_doubles); + assembler.Bind(&if_packed_doubles); { - Label not_nan_loop(assembler, &index_var), search_notnan(assembler); - Variable search_num(assembler, MachineRepresentation::kFloat64); + Label not_nan_loop(&assembler, &index_var), search_notnan(&assembler); + Variable search_num(&assembler, MachineRepresentation::kFloat64); - assembler->GotoUnless(assembler->TaggedIsSmi(search_element), - &search_notnan); - search_num.Bind(assembler->SmiToFloat64(search_element)); - assembler->Goto(¬_nan_loop); + assembler.GotoUnless(assembler.TaggedIsSmi(search_element), &search_notnan); + search_num.Bind(assembler.SmiToFloat64(search_element)); + assembler.Goto(¬_nan_loop); - assembler->Bind(&search_notnan); - assembler->GotoIf(assembler->WordNotEqual( - assembler->LoadMap(search_element), heap_number_map), - &return_not_found); + assembler.Bind(&search_notnan); + assembler.GotoUnless( + assembler.IsHeapNumberMap(assembler.LoadMap(search_element)), + &return_not_found); - search_num.Bind(assembler->LoadHeapNumberValue(search_element)); + search_num.Bind(assembler.LoadHeapNumberValue(search_element)); - assembler->BranchIfFloat64IsNaN(search_num.value(), &return_not_found, - ¬_nan_loop); + assembler.BranchIfFloat64IsNaN(search_num.value(), &return_not_found, + ¬_nan_loop); // Search for HeapNumber - assembler->Bind(¬_nan_loop); + assembler.Bind(¬_nan_loop); { - Label continue_loop(assembler); - assembler->GotoUnless( - assembler->UintPtrLessThan(index_var.value(), len_var.value()), + Label continue_loop(&assembler); + assembler.GotoUnless( + assembler.UintPtrLessThan(index_var.value(), len_var.value()), &return_not_found); - Node* element_k = assembler->LoadFixedDoubleArrayElement( - elements, index_var.value(), MachineType::Float64(), 0, - CodeStubAssembler::INTPTR_PARAMETERS); - assembler->Branch(assembler->Float64Equal(element_k, search_num.value()), - &return_found, &continue_loop); - assembler->Bind(&continue_loop); - index_var.Bind(assembler->IntPtrAdd(index_var.value(), intptr_one)); - assembler->Goto(¬_nan_loop); + Node* element_k = assembler.LoadFixedDoubleArrayElement( + elements, index_var.value(), MachineType::Float64()); + assembler.Branch(assembler.Float64Equal(element_k, search_num.value()), + &return_found, &continue_loop); + assembler.Bind(&continue_loop); + index_var.Bind(assembler.IntPtrAdd(index_var.value(), intptr_one)); + assembler.Goto(¬_nan_loop); } } - assembler->Bind(&if_holey_doubles); + assembler.Bind(&if_holey_doubles); { - Label not_nan_loop(assembler, &index_var), search_notnan(assembler); - Variable search_num(assembler, MachineRepresentation::kFloat64); + Label not_nan_loop(&assembler, &index_var), search_notnan(&assembler); + Variable search_num(&assembler, MachineRepresentation::kFloat64); - assembler->GotoUnless(assembler->TaggedIsSmi(search_element), - &search_notnan); - search_num.Bind(assembler->SmiToFloat64(search_element)); - assembler->Goto(¬_nan_loop); + assembler.GotoUnless(assembler.TaggedIsSmi(search_element), &search_notnan); + search_num.Bind(assembler.SmiToFloat64(search_element)); + assembler.Goto(¬_nan_loop); - assembler->Bind(&search_notnan); - assembler->GotoIf(assembler->WordNotEqual( - assembler->LoadMap(search_element), heap_number_map), - &return_not_found); + assembler.Bind(&search_notnan); + assembler.GotoUnless( + assembler.IsHeapNumberMap(assembler.LoadMap(search_element)), + &return_not_found); - search_num.Bind(assembler->LoadHeapNumberValue(search_element)); + search_num.Bind(assembler.LoadHeapNumberValue(search_element)); - assembler->BranchIfFloat64IsNaN(search_num.value(), &return_not_found, - ¬_nan_loop); + assembler.BranchIfFloat64IsNaN(search_num.value(), &return_not_found, + ¬_nan_loop); // Search for HeapNumber - assembler->Bind(¬_nan_loop); + assembler.Bind(¬_nan_loop); { - Label continue_loop(assembler); - assembler->GotoUnless( - assembler->UintPtrLessThan(index_var.value(), len_var.value()), + Label continue_loop(&assembler); + assembler.GotoUnless( + assembler.UintPtrLessThan(index_var.value(), len_var.value()), &return_not_found); // Load double value or continue if it contains a double hole. - Node* element_k = assembler->LoadFixedDoubleArrayElement( + Node* element_k = assembler.LoadFixedDoubleArrayElement( elements, index_var.value(), MachineType::Float64(), 0, CodeStubAssembler::INTPTR_PARAMETERS, &continue_loop); - assembler->Branch(assembler->Float64Equal(element_k, search_num.value()), - &return_found, &continue_loop); - assembler->Bind(&continue_loop); - index_var.Bind(assembler->IntPtrAdd(index_var.value(), intptr_one)); - assembler->Goto(¬_nan_loop); + assembler.Branch(assembler.Float64Equal(element_k, search_num.value()), + &return_found, &continue_loop); + assembler.Bind(&continue_loop); + index_var.Bind(assembler.IntPtrAdd(index_var.value(), intptr_one)); + assembler.Goto(¬_nan_loop); } } - assembler->Bind(&return_found); - assembler->Return(assembler->ChangeInt32ToTagged(index_var.value())); + assembler.Bind(&return_found); + assembler.Return(assembler.SmiTag(index_var.value())); - assembler->Bind(&return_not_found); - assembler->Return(assembler->NumberConstant(-1)); + assembler.Bind(&return_not_found); + assembler.Return(assembler.NumberConstant(-1)); - assembler->Bind(&call_runtime); - assembler->Return(assembler->CallRuntime(Runtime::kArrayIndexOf, context, - array, search_element, start_from)); + assembler.Bind(&call_runtime); + assembler.Return(assembler.CallRuntime(Runtime::kArrayIndexOf, context, array, + search_element, start_from)); } namespace { template <IterationKind kIterationKind> -void Generate_ArrayPrototypeIterationMethod(CodeStubAssembler* assembler) { +void Generate_ArrayPrototypeIterationMethod( + compiler::CodeAssemblerState* state) { typedef compiler::Node Node; typedef CodeStubAssembler::Label Label; typedef CodeStubAssembler::Variable Variable; + CodeStubAssembler assembler(state); - Node* receiver = assembler->Parameter(0); - Node* context = assembler->Parameter(3); + Node* receiver = assembler.Parameter(0); + Node* context = assembler.Parameter(3); - Variable var_array(assembler, MachineRepresentation::kTagged); - Variable var_map(assembler, MachineRepresentation::kTagged); - Variable var_type(assembler, MachineRepresentation::kWord32); + Variable var_array(&assembler, MachineRepresentation::kTagged); + Variable var_map(&assembler, MachineRepresentation::kTagged); + Variable var_type(&assembler, MachineRepresentation::kWord32); - Label if_isnotobject(assembler, Label::kDeferred); - Label create_array_iterator(assembler); + Label if_isnotobject(&assembler, Label::kDeferred); + Label create_array_iterator(&assembler); - assembler->GotoIf(assembler->TaggedIsSmi(receiver), &if_isnotobject); + assembler.GotoIf(assembler.TaggedIsSmi(receiver), &if_isnotobject); var_array.Bind(receiver); - var_map.Bind(assembler->LoadMap(receiver)); - var_type.Bind(assembler->LoadMapInstanceType(var_map.value())); - assembler->Branch(assembler->IsJSReceiverInstanceType(var_type.value()), - &create_array_iterator, &if_isnotobject); + var_map.Bind(assembler.LoadMap(receiver)); + var_type.Bind(assembler.LoadMapInstanceType(var_map.value())); + assembler.Branch(assembler.IsJSReceiverInstanceType(var_type.value()), + &create_array_iterator, &if_isnotobject); - assembler->Bind(&if_isnotobject); + assembler.Bind(&if_isnotobject); { - Callable callable = CodeFactory::ToObject(assembler->isolate()); - Node* result = assembler->CallStub(callable, context, receiver); + Callable callable = CodeFactory::ToObject(assembler.isolate()); + Node* result = assembler.CallStub(callable, context, receiver); var_array.Bind(result); - var_map.Bind(assembler->LoadMap(result)); - var_type.Bind(assembler->LoadMapInstanceType(var_map.value())); - assembler->Goto(&create_array_iterator); + var_map.Bind(assembler.LoadMap(result)); + var_type.Bind(assembler.LoadMapInstanceType(var_map.value())); + assembler.Goto(&create_array_iterator); } - assembler->Bind(&create_array_iterator); - assembler->Return(assembler->CreateArrayIterator( - var_array.value(), var_map.value(), var_type.value(), context, - kIterationKind)); + assembler.Bind(&create_array_iterator); + assembler.Return( + assembler.CreateArrayIterator(var_array.value(), var_map.value(), + var_type.value(), context, kIterationKind)); } } // namespace -void Builtins::Generate_ArrayPrototypeValues(CodeStubAssembler* assembler) { - Generate_ArrayPrototypeIterationMethod<IterationKind::kValues>(assembler); +void Builtins::Generate_ArrayPrototypeValues( + compiler::CodeAssemblerState* state) { + Generate_ArrayPrototypeIterationMethod<IterationKind::kValues>(state); } -void Builtins::Generate_ArrayPrototypeEntries(CodeStubAssembler* assembler) { - Generate_ArrayPrototypeIterationMethod<IterationKind::kEntries>(assembler); +void Builtins::Generate_ArrayPrototypeEntries( + compiler::CodeAssemblerState* state) { + Generate_ArrayPrototypeIterationMethod<IterationKind::kEntries>(state); } -void Builtins::Generate_ArrayPrototypeKeys(CodeStubAssembler* assembler) { - Generate_ArrayPrototypeIterationMethod<IterationKind::kKeys>(assembler); +void Builtins::Generate_ArrayPrototypeKeys( + compiler::CodeAssemblerState* state) { + Generate_ArrayPrototypeIterationMethod<IterationKind::kKeys>(state); } void Builtins::Generate_ArrayIteratorPrototypeNext( - CodeStubAssembler* assembler) { + compiler::CodeAssemblerState* state) { typedef compiler::Node Node; typedef CodeStubAssembler::Label Label; typedef CodeStubAssembler::Variable Variable; + CodeStubAssembler assembler(state); + + Handle<String> operation = assembler.factory()->NewStringFromAsciiChecked( + "Array Iterator.prototype.next", TENURED); - Node* iterator = assembler->Parameter(0); - Node* context = assembler->Parameter(3); + Node* iterator = assembler.Parameter(0); + Node* context = assembler.Parameter(3); - Variable var_value(assembler, MachineRepresentation::kTagged); - Variable var_done(assembler, MachineRepresentation::kTagged); + Variable var_value(&assembler, MachineRepresentation::kTagged); + Variable var_done(&assembler, MachineRepresentation::kTagged); // Required, or else `throw_bad_receiver` fails a DCHECK due to these // variables not being bound along all paths, despite not being used. - var_done.Bind(assembler->TrueConstant()); - var_value.Bind(assembler->UndefinedConstant()); + var_done.Bind(assembler.TrueConstant()); + var_value.Bind(assembler.UndefinedConstant()); - Label throw_bad_receiver(assembler, Label::kDeferred); - Label set_done(assembler); - Label allocate_key_result(assembler); - Label allocate_entry_if_needed(assembler); - Label allocate_iterator_result(assembler); - Label generic_values(assembler); + Label throw_bad_receiver(&assembler, Label::kDeferred); + Label set_done(&assembler); + Label allocate_key_result(&assembler); + Label allocate_entry_if_needed(&assembler); + Label allocate_iterator_result(&assembler); + Label generic_values(&assembler); // If O does not have all of the internal slots of an Array Iterator Instance // (22.1.5.3), throw a TypeError exception - assembler->GotoIf(assembler->TaggedIsSmi(iterator), &throw_bad_receiver); - Node* instance_type = assembler->LoadInstanceType(iterator); - assembler->GotoIf( - assembler->Uint32LessThan( - assembler->Int32Constant(LAST_ARRAY_ITERATOR_TYPE - - FIRST_ARRAY_ITERATOR_TYPE), - assembler->Int32Sub(instance_type, assembler->Int32Constant( - FIRST_ARRAY_ITERATOR_TYPE))), + assembler.GotoIf(assembler.TaggedIsSmi(iterator), &throw_bad_receiver); + Node* instance_type = assembler.LoadInstanceType(iterator); + assembler.GotoIf( + assembler.Uint32LessThan( + assembler.Int32Constant(LAST_ARRAY_ITERATOR_TYPE - + FIRST_ARRAY_ITERATOR_TYPE), + assembler.Int32Sub(instance_type, assembler.Int32Constant( + FIRST_ARRAY_ITERATOR_TYPE))), &throw_bad_receiver); // Let a be O.[[IteratedObject]]. - Node* array = assembler->LoadObjectField( + Node* array = assembler.LoadObjectField( iterator, JSArrayIterator::kIteratedObjectOffset); // Let index be O.[[ArrayIteratorNextIndex]]. Node* index = - assembler->LoadObjectField(iterator, JSArrayIterator::kNextIndexOffset); - Node* orig_map = assembler->LoadObjectField( + assembler.LoadObjectField(iterator, JSArrayIterator::kNextIndexOffset); + Node* orig_map = assembler.LoadObjectField( iterator, JSArrayIterator::kIteratedObjectMapOffset); - Node* array_map = assembler->LoadMap(array); + Node* array_map = assembler.LoadMap(array); - Label if_isfastarray(assembler), if_isnotfastarray(assembler); + Label if_isfastarray(&assembler), if_isnotfastarray(&assembler), + if_isdetached(&assembler, Label::kDeferred); - assembler->Branch(assembler->WordEqual(orig_map, array_map), &if_isfastarray, - &if_isnotfastarray); + assembler.Branch(assembler.WordEqual(orig_map, array_map), &if_isfastarray, + &if_isnotfastarray); - assembler->Bind(&if_isfastarray); + assembler.Bind(&if_isfastarray); { - CSA_ASSERT(assembler, - assembler->Word32Equal(assembler->LoadMapInstanceType(array_map), - assembler->Int32Constant(JS_ARRAY_TYPE))); + CSA_ASSERT(&assembler, + assembler.Word32Equal(assembler.LoadMapInstanceType(array_map), + assembler.Int32Constant(JS_ARRAY_TYPE))); - Node* length = assembler->LoadObjectField(array, JSArray::kLengthOffset); + Node* length = assembler.LoadObjectField(array, JSArray::kLengthOffset); - CSA_ASSERT(assembler, assembler->TaggedIsSmi(length)); - CSA_ASSERT(assembler, assembler->TaggedIsSmi(index)); + CSA_ASSERT(&assembler, assembler.TaggedIsSmi(length)); + CSA_ASSERT(&assembler, assembler.TaggedIsSmi(index)); - assembler->GotoUnless(assembler->SmiBelow(index, length), &set_done); + assembler.GotoUnless(assembler.SmiBelow(index, length), &set_done); - Node* one = assembler->SmiConstant(Smi::FromInt(1)); - assembler->StoreObjectFieldNoWriteBarrier( - iterator, JSArrayIterator::kNextIndexOffset, - assembler->IntPtrAdd(assembler->BitcastTaggedToWord(index), - assembler->BitcastTaggedToWord(one))); + Node* one = assembler.SmiConstant(Smi::FromInt(1)); + assembler.StoreObjectFieldNoWriteBarrier(iterator, + JSArrayIterator::kNextIndexOffset, + assembler.SmiAdd(index, one)); - var_done.Bind(assembler->FalseConstant()); - Node* elements = assembler->LoadElements(array); + var_done.Bind(assembler.FalseConstant()); + Node* elements = assembler.LoadElements(array); static int32_t kInstanceType[] = { JS_FAST_ARRAY_KEY_ITERATOR_TYPE, @@ -2225,8 +2373,8 @@ void Builtins::Generate_ArrayIteratorPrototypeNext( JS_FAST_HOLEY_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE, }; - Label packed_object_values(assembler), holey_object_values(assembler), - packed_double_values(assembler), holey_double_values(assembler); + Label packed_object_values(&assembler), holey_object_values(&assembler), + packed_double_values(&assembler), holey_double_values(&assembler); Label* kInstanceTypeHandlers[] = { &allocate_key_result, &packed_object_values, &holey_object_values, &packed_object_values, &holey_object_values, &packed_double_values, @@ -2234,216 +2382,192 @@ void Builtins::Generate_ArrayIteratorPrototypeNext( &packed_object_values, &holey_object_values, &packed_double_values, &holey_double_values}; - assembler->Switch(instance_type, &throw_bad_receiver, kInstanceType, - kInstanceTypeHandlers, arraysize(kInstanceType)); + assembler.Switch(instance_type, &throw_bad_receiver, kInstanceType, + kInstanceTypeHandlers, arraysize(kInstanceType)); - assembler->Bind(&packed_object_values); + assembler.Bind(&packed_object_values); { - var_value.Bind(assembler->LoadFixedArrayElement( + var_value.Bind(assembler.LoadFixedArrayElement( elements, index, 0, CodeStubAssembler::SMI_PARAMETERS)); - assembler->Goto(&allocate_entry_if_needed); + assembler.Goto(&allocate_entry_if_needed); } - assembler->Bind(&packed_double_values); + assembler.Bind(&packed_double_values); { - Node* value = assembler->LoadFixedDoubleArrayElement( + Node* value = assembler.LoadFixedDoubleArrayElement( elements, index, MachineType::Float64(), 0, CodeStubAssembler::SMI_PARAMETERS); - var_value.Bind(assembler->AllocateHeapNumberWithValue(value)); - assembler->Goto(&allocate_entry_if_needed); + var_value.Bind(assembler.AllocateHeapNumberWithValue(value)); + assembler.Goto(&allocate_entry_if_needed); } - assembler->Bind(&holey_object_values); + assembler.Bind(&holey_object_values); { // Check the array_protector cell, and take the slow path if it's invalid. Node* invalid = - assembler->SmiConstant(Smi::FromInt(Isolate::kProtectorInvalid)); - Node* cell = assembler->LoadRoot(Heap::kArrayProtectorRootIndex); + assembler.SmiConstant(Smi::FromInt(Isolate::kProtectorInvalid)); + Node* cell = assembler.LoadRoot(Heap::kArrayProtectorRootIndex); Node* cell_value = - assembler->LoadObjectField(cell, PropertyCell::kValueOffset); - assembler->GotoIf(assembler->WordEqual(cell_value, invalid), - &generic_values); + assembler.LoadObjectField(cell, PropertyCell::kValueOffset); + assembler.GotoIf(assembler.WordEqual(cell_value, invalid), + &generic_values); - var_value.Bind(assembler->UndefinedConstant()); - Node* value = assembler->LoadFixedArrayElement( + var_value.Bind(assembler.UndefinedConstant()); + Node* value = assembler.LoadFixedArrayElement( elements, index, 0, CodeStubAssembler::SMI_PARAMETERS); - assembler->GotoIf( - assembler->WordEqual(value, assembler->TheHoleConstant()), - &allocate_entry_if_needed); + assembler.GotoIf(assembler.WordEqual(value, assembler.TheHoleConstant()), + &allocate_entry_if_needed); var_value.Bind(value); - assembler->Goto(&allocate_entry_if_needed); + assembler.Goto(&allocate_entry_if_needed); } - assembler->Bind(&holey_double_values); + assembler.Bind(&holey_double_values); { // Check the array_protector cell, and take the slow path if it's invalid. Node* invalid = - assembler->SmiConstant(Smi::FromInt(Isolate::kProtectorInvalid)); - Node* cell = assembler->LoadRoot(Heap::kArrayProtectorRootIndex); + assembler.SmiConstant(Smi::FromInt(Isolate::kProtectorInvalid)); + Node* cell = assembler.LoadRoot(Heap::kArrayProtectorRootIndex); Node* cell_value = - assembler->LoadObjectField(cell, PropertyCell::kValueOffset); - assembler->GotoIf(assembler->WordEqual(cell_value, invalid), - &generic_values); + assembler.LoadObjectField(cell, PropertyCell::kValueOffset); + assembler.GotoIf(assembler.WordEqual(cell_value, invalid), + &generic_values); - var_value.Bind(assembler->UndefinedConstant()); - Node* value = assembler->LoadFixedDoubleArrayElement( + var_value.Bind(assembler.UndefinedConstant()); + Node* value = assembler.LoadFixedDoubleArrayElement( elements, index, MachineType::Float64(), 0, CodeStubAssembler::SMI_PARAMETERS, &allocate_entry_if_needed); - var_value.Bind(assembler->AllocateHeapNumberWithValue(value)); - assembler->Goto(&allocate_entry_if_needed); + var_value.Bind(assembler.AllocateHeapNumberWithValue(value)); + assembler.Goto(&allocate_entry_if_needed); } } - assembler->Bind(&if_isnotfastarray); + assembler.Bind(&if_isnotfastarray); { - Label if_istypedarray(assembler), if_isgeneric(assembler); + Label if_istypedarray(&assembler), if_isgeneric(&assembler); // If a is undefined, return CreateIterResultObject(undefined, true) - assembler->GotoIf( - assembler->WordEqual(array, assembler->UndefinedConstant()), - &allocate_iterator_result); + assembler.GotoIf(assembler.WordEqual(array, assembler.UndefinedConstant()), + &allocate_iterator_result); - Node* array_type = assembler->LoadInstanceType(array); - assembler->Branch( - assembler->Word32Equal(array_type, - assembler->Int32Constant(JS_TYPED_ARRAY_TYPE)), + Node* array_type = assembler.LoadInstanceType(array); + assembler.Branch( + assembler.Word32Equal(array_type, + assembler.Int32Constant(JS_TYPED_ARRAY_TYPE)), &if_istypedarray, &if_isgeneric); - assembler->Bind(&if_isgeneric); + assembler.Bind(&if_isgeneric); { - Label if_wasfastarray(assembler); + Label if_wasfastarray(&assembler); Node* length = nullptr; { - Variable var_length(assembler, MachineRepresentation::kTagged); - Label if_isarray(assembler), if_isnotarray(assembler), done(assembler); - assembler->Branch( - assembler->Word32Equal(array_type, - assembler->Int32Constant(JS_ARRAY_TYPE)), + Variable var_length(&assembler, MachineRepresentation::kTagged); + Label if_isarray(&assembler), if_isnotarray(&assembler), + done(&assembler); + assembler.Branch( + assembler.Word32Equal(array_type, + assembler.Int32Constant(JS_ARRAY_TYPE)), &if_isarray, &if_isnotarray); - assembler->Bind(&if_isarray); + assembler.Bind(&if_isarray); { var_length.Bind( - assembler->LoadObjectField(array, JSArray::kLengthOffset)); + assembler.LoadObjectField(array, JSArray::kLengthOffset)); // Invalidate protector cell if needed - assembler->Branch( - assembler->WordNotEqual(orig_map, assembler->UndefinedConstant()), + assembler.Branch( + assembler.WordNotEqual(orig_map, assembler.UndefinedConstant()), &if_wasfastarray, &done); - assembler->Bind(&if_wasfastarray); + assembler.Bind(&if_wasfastarray); { - Label if_invalid(assembler, Label::kDeferred); + Label if_invalid(&assembler, Label::kDeferred); // A fast array iterator transitioned to a slow iterator during // iteration. Invalidate fast_array_iteration_prtoector cell to // prevent potential deopt loops. - assembler->StoreObjectFieldNoWriteBarrier( + assembler.StoreObjectFieldNoWriteBarrier( iterator, JSArrayIterator::kIteratedObjectMapOffset, - assembler->UndefinedConstant()); - assembler->GotoIf( - assembler->Uint32LessThanOrEqual( - instance_type, assembler->Int32Constant( + assembler.UndefinedConstant()); + assembler.GotoIf( + assembler.Uint32LessThanOrEqual( + instance_type, assembler.Int32Constant( JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE)), &done); - Node* invalid = assembler->SmiConstant( - Smi::FromInt(Isolate::kProtectorInvalid)); - Node* cell = assembler->LoadRoot( - Heap::kFastArrayIterationProtectorRootIndex); - assembler->StoreObjectFieldNoWriteBarrier(cell, Cell::kValueOffset, - invalid); - assembler->Goto(&done); + Node* invalid = + assembler.SmiConstant(Smi::FromInt(Isolate::kProtectorInvalid)); + Node* cell = + assembler.LoadRoot(Heap::kFastArrayIterationProtectorRootIndex); + assembler.StoreObjectFieldNoWriteBarrier(cell, Cell::kValueOffset, + invalid); + assembler.Goto(&done); } } - assembler->Bind(&if_isnotarray); + assembler.Bind(&if_isnotarray); { - Node* length_string = assembler->HeapConstant( - assembler->isolate()->factory()->length_string()); - Callable get_property = - CodeFactory::GetProperty(assembler->isolate()); + Node* length_string = assembler.HeapConstant( + assembler.isolate()->factory()->length_string()); + Callable get_property = CodeFactory::GetProperty(assembler.isolate()); Node* length = - assembler->CallStub(get_property, context, array, length_string); - Callable to_length = CodeFactory::ToLength(assembler->isolate()); - var_length.Bind(assembler->CallStub(to_length, context, length)); - assembler->Goto(&done); + assembler.CallStub(get_property, context, array, length_string); + Callable to_length = CodeFactory::ToLength(assembler.isolate()); + var_length.Bind(assembler.CallStub(to_length, context, length)); + assembler.Goto(&done); } - assembler->Bind(&done); + assembler.Bind(&done); length = var_length.value(); } - assembler->GotoUnlessNumberLessThan(index, length, &set_done); + assembler.GotoUnlessNumberLessThan(index, length, &set_done); - assembler->StoreObjectField(iterator, JSArrayIterator::kNextIndexOffset, - assembler->NumberInc(index)); - var_done.Bind(assembler->FalseConstant()); + assembler.StoreObjectField(iterator, JSArrayIterator::kNextIndexOffset, + assembler.NumberInc(index)); + var_done.Bind(assembler.FalseConstant()); - assembler->Branch( - assembler->Uint32LessThanOrEqual( + assembler.Branch( + assembler.Uint32LessThanOrEqual( instance_type, - assembler->Int32Constant(JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE)), + assembler.Int32Constant(JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE)), &allocate_key_result, &generic_values); - assembler->Bind(&generic_values); + assembler.Bind(&generic_values); { - Callable get_property = CodeFactory::GetProperty(assembler->isolate()); - var_value.Bind( - assembler->CallStub(get_property, context, array, index)); - assembler->Goto(&allocate_entry_if_needed); + Callable get_property = CodeFactory::GetProperty(assembler.isolate()); + var_value.Bind(assembler.CallStub(get_property, context, array, index)); + assembler.Goto(&allocate_entry_if_needed); } } - assembler->Bind(&if_istypedarray); + assembler.Bind(&if_istypedarray); { - Node* length = nullptr; - { - Variable var_length(assembler, MachineRepresentation::kTagged); - Label if_isdetached(assembler, Label::kDeferred), - if_isnotdetached(assembler), done(assembler); + Node* buffer = + assembler.LoadObjectField(array, JSTypedArray::kBufferOffset); + assembler.GotoIf(assembler.IsDetachedBuffer(buffer), &if_isdetached); - Node* buffer = - assembler->LoadObjectField(array, JSTypedArray::kBufferOffset); - assembler->Branch(assembler->IsDetachedBuffer(buffer), &if_isdetached, - &if_isnotdetached); + Node* length = + assembler.LoadObjectField(array, JSTypedArray::kLengthOffset); - assembler->Bind(&if_isnotdetached); - { - var_length.Bind( - assembler->LoadObjectField(array, JSTypedArray::kLengthOffset)); - assembler->Goto(&done); - } + CSA_ASSERT(&assembler, assembler.TaggedIsSmi(length)); + CSA_ASSERT(&assembler, assembler.TaggedIsSmi(index)); - assembler->Bind(&if_isdetached); - { - // TODO(caitp): If IsDetached(buffer) is true, throw a TypeError, per - // https://github.com/tc39/ecma262/issues/713 - var_length.Bind(assembler->SmiConstant(Smi::kZero)); - assembler->Goto(&done); - } - - assembler->Bind(&done); - length = var_length.value(); - } - CSA_ASSERT(assembler, assembler->TaggedIsSmi(length)); - CSA_ASSERT(assembler, assembler->TaggedIsSmi(index)); - - assembler->GotoUnless(assembler->SmiBelow(index, length), &set_done); + assembler.GotoUnless(assembler.SmiBelow(index, length), &set_done); - Node* one = assembler->SmiConstant(Smi::FromInt(1)); - assembler->StoreObjectFieldNoWriteBarrier( + Node* one = assembler.SmiConstant(1); + assembler.StoreObjectFieldNoWriteBarrier( iterator, JSArrayIterator::kNextIndexOffset, - assembler->IntPtrAdd(assembler->BitcastTaggedToWord(index), - assembler->BitcastTaggedToWord(one))); - var_done.Bind(assembler->FalseConstant()); + assembler.SmiAdd(index, one)); + var_done.Bind(assembler.FalseConstant()); - Node* elements = assembler->LoadElements(array); - Node* base_ptr = assembler->LoadObjectField( + Node* elements = assembler.LoadElements(array); + Node* base_ptr = assembler.LoadObjectField( elements, FixedTypedArrayBase::kBasePointerOffset); - Node* external_ptr = assembler->LoadObjectField( - elements, FixedTypedArrayBase::kExternalPointerOffset); - Node* data_ptr = assembler->IntPtrAdd(base_ptr, external_ptr); + Node* external_ptr = assembler.LoadObjectField( + elements, FixedTypedArrayBase::kExternalPointerOffset, + MachineType::Pointer()); + Node* data_ptr = assembler.IntPtrAdd( + assembler.BitcastTaggedToWord(base_ptr), external_ptr); static int32_t kInstanceType[] = { JS_TYPED_ARRAY_KEY_ITERATOR_TYPE, @@ -2467,10 +2591,10 @@ void Builtins::Generate_ArrayIteratorPrototypeNext( JS_FLOAT64_ARRAY_VALUE_ITERATOR_TYPE, }; - Label uint8_values(assembler), int8_values(assembler), - uint16_values(assembler), int16_values(assembler), - uint32_values(assembler), int32_values(assembler), - float32_values(assembler), float64_values(assembler); + Label uint8_values(&assembler), int8_values(&assembler), + uint16_values(&assembler), int16_values(&assembler), + uint32_values(&assembler), int32_values(&assembler), + float32_values(&assembler), float64_values(&assembler); Label* kInstanceTypeHandlers[] = { &allocate_key_result, &uint8_values, &uint8_values, &int8_values, &uint16_values, &int16_values, @@ -2481,152 +2605,158 @@ void Builtins::Generate_ArrayIteratorPrototypeNext( &float64_values, }; - var_done.Bind(assembler->FalseConstant()); - assembler->Switch(instance_type, &throw_bad_receiver, kInstanceType, - kInstanceTypeHandlers, arraysize(kInstanceType)); + var_done.Bind(assembler.FalseConstant()); + assembler.Switch(instance_type, &throw_bad_receiver, kInstanceType, + kInstanceTypeHandlers, arraysize(kInstanceType)); - assembler->Bind(&uint8_values); + assembler.Bind(&uint8_values); { - Node* value_uint8 = assembler->LoadFixedTypedArrayElement( + Node* value_uint8 = assembler.LoadFixedTypedArrayElement( data_ptr, index, UINT8_ELEMENTS, CodeStubAssembler::SMI_PARAMETERS); - var_value.Bind(assembler->SmiFromWord(value_uint8)); - assembler->Goto(&allocate_entry_if_needed); + var_value.Bind(assembler.SmiFromWord32(value_uint8)); + assembler.Goto(&allocate_entry_if_needed); } - assembler->Bind(&int8_values); + assembler.Bind(&int8_values); { - Node* value_int8 = assembler->LoadFixedTypedArrayElement( + Node* value_int8 = assembler.LoadFixedTypedArrayElement( data_ptr, index, INT8_ELEMENTS, CodeStubAssembler::SMI_PARAMETERS); - var_value.Bind(assembler->SmiFromWord(value_int8)); - assembler->Goto(&allocate_entry_if_needed); + var_value.Bind(assembler.SmiFromWord32(value_int8)); + assembler.Goto(&allocate_entry_if_needed); } - assembler->Bind(&uint16_values); + assembler.Bind(&uint16_values); { - Node* value_uint16 = assembler->LoadFixedTypedArrayElement( + Node* value_uint16 = assembler.LoadFixedTypedArrayElement( data_ptr, index, UINT16_ELEMENTS, CodeStubAssembler::SMI_PARAMETERS); - var_value.Bind(assembler->SmiFromWord(value_uint16)); - assembler->Goto(&allocate_entry_if_needed); + var_value.Bind(assembler.SmiFromWord32(value_uint16)); + assembler.Goto(&allocate_entry_if_needed); } - assembler->Bind(&int16_values); + assembler.Bind(&int16_values); { - Node* value_int16 = assembler->LoadFixedTypedArrayElement( + Node* value_int16 = assembler.LoadFixedTypedArrayElement( data_ptr, index, INT16_ELEMENTS, CodeStubAssembler::SMI_PARAMETERS); - var_value.Bind(assembler->SmiFromWord(value_int16)); - assembler->Goto(&allocate_entry_if_needed); + var_value.Bind(assembler.SmiFromWord32(value_int16)); + assembler.Goto(&allocate_entry_if_needed); } - assembler->Bind(&uint32_values); + assembler.Bind(&uint32_values); { - Node* value_uint32 = assembler->LoadFixedTypedArrayElement( + Node* value_uint32 = assembler.LoadFixedTypedArrayElement( data_ptr, index, UINT32_ELEMENTS, CodeStubAssembler::SMI_PARAMETERS); - var_value.Bind(assembler->ChangeUint32ToTagged(value_uint32)); - assembler->Goto(&allocate_entry_if_needed); + var_value.Bind(assembler.ChangeUint32ToTagged(value_uint32)); + assembler.Goto(&allocate_entry_if_needed); } - assembler->Bind(&int32_values); + assembler.Bind(&int32_values); { - Node* value_int32 = assembler->LoadFixedTypedArrayElement( + Node* value_int32 = assembler.LoadFixedTypedArrayElement( data_ptr, index, INT32_ELEMENTS, CodeStubAssembler::SMI_PARAMETERS); - var_value.Bind(assembler->ChangeInt32ToTagged(value_int32)); - assembler->Goto(&allocate_entry_if_needed); + var_value.Bind(assembler.ChangeInt32ToTagged(value_int32)); + assembler.Goto(&allocate_entry_if_needed); } - assembler->Bind(&float32_values); + assembler.Bind(&float32_values); { - Node* value_float32 = assembler->LoadFixedTypedArrayElement( + Node* value_float32 = assembler.LoadFixedTypedArrayElement( data_ptr, index, FLOAT32_ELEMENTS, CodeStubAssembler::SMI_PARAMETERS); - var_value.Bind(assembler->AllocateHeapNumberWithValue( - assembler->ChangeFloat32ToFloat64(value_float32))); - assembler->Goto(&allocate_entry_if_needed); + var_value.Bind(assembler.AllocateHeapNumberWithValue( + assembler.ChangeFloat32ToFloat64(value_float32))); + assembler.Goto(&allocate_entry_if_needed); } - assembler->Bind(&float64_values); + assembler.Bind(&float64_values); { - Node* value_float64 = assembler->LoadFixedTypedArrayElement( + Node* value_float64 = assembler.LoadFixedTypedArrayElement( data_ptr, index, FLOAT64_ELEMENTS, CodeStubAssembler::SMI_PARAMETERS); - var_value.Bind(assembler->AllocateHeapNumberWithValue(value_float64)); - assembler->Goto(&allocate_entry_if_needed); + var_value.Bind(assembler.AllocateHeapNumberWithValue(value_float64)); + assembler.Goto(&allocate_entry_if_needed); } } } - assembler->Bind(&set_done); + assembler.Bind(&set_done); { - assembler->StoreObjectFieldNoWriteBarrier( + assembler.StoreObjectFieldNoWriteBarrier( iterator, JSArrayIterator::kIteratedObjectOffset, - assembler->UndefinedConstant()); - assembler->Goto(&allocate_iterator_result); + assembler.UndefinedConstant()); + assembler.Goto(&allocate_iterator_result); } - assembler->Bind(&allocate_key_result); + assembler.Bind(&allocate_key_result); { var_value.Bind(index); - var_done.Bind(assembler->FalseConstant()); - assembler->Goto(&allocate_iterator_result); + var_done.Bind(assembler.FalseConstant()); + assembler.Goto(&allocate_iterator_result); } - assembler->Bind(&allocate_entry_if_needed); + assembler.Bind(&allocate_entry_if_needed); { - assembler->GotoIf( - assembler->Int32GreaterThan( + assembler.GotoIf( + assembler.Int32GreaterThan( instance_type, - assembler->Int32Constant(LAST_ARRAY_KEY_VALUE_ITERATOR_TYPE)), + assembler.Int32Constant(LAST_ARRAY_KEY_VALUE_ITERATOR_TYPE)), &allocate_iterator_result); - Node* elements = assembler->AllocateFixedArray(FAST_ELEMENTS, - assembler->Int32Constant(2)); - assembler->StoreFixedArrayElement(elements, assembler->Int32Constant(0), - index, SKIP_WRITE_BARRIER); - assembler->StoreFixedArrayElement(elements, assembler->Int32Constant(1), - var_value.value(), SKIP_WRITE_BARRIER); - - Node* entry = assembler->Allocate(JSArray::kSize); - Node* map = assembler->LoadContextElement( - assembler->LoadNativeContext(context), - Context::JS_ARRAY_FAST_ELEMENTS_MAP_INDEX); - - assembler->StoreMapNoWriteBarrier(entry, map); - assembler->StoreObjectFieldRoot(entry, JSArray::kPropertiesOffset, - Heap::kEmptyFixedArrayRootIndex); - assembler->StoreObjectFieldNoWriteBarrier(entry, JSArray::kElementsOffset, - elements); - assembler->StoreObjectFieldNoWriteBarrier( - entry, JSArray::kLengthOffset, assembler->SmiConstant(Smi::FromInt(2))); + Node* elements = assembler.AllocateFixedArray(FAST_ELEMENTS, + assembler.IntPtrConstant(2)); + assembler.StoreFixedArrayElement(elements, 0, index, SKIP_WRITE_BARRIER); + assembler.StoreFixedArrayElement(elements, 1, var_value.value(), + SKIP_WRITE_BARRIER); + + Node* entry = assembler.Allocate(JSArray::kSize); + Node* map = + assembler.LoadContextElement(assembler.LoadNativeContext(context), + Context::JS_ARRAY_FAST_ELEMENTS_MAP_INDEX); + + assembler.StoreMapNoWriteBarrier(entry, map); + assembler.StoreObjectFieldRoot(entry, JSArray::kPropertiesOffset, + Heap::kEmptyFixedArrayRootIndex); + assembler.StoreObjectFieldNoWriteBarrier(entry, JSArray::kElementsOffset, + elements); + assembler.StoreObjectFieldNoWriteBarrier( + entry, JSArray::kLengthOffset, assembler.SmiConstant(Smi::FromInt(2))); var_value.Bind(entry); - assembler->Goto(&allocate_iterator_result); + assembler.Goto(&allocate_iterator_result); } - assembler->Bind(&allocate_iterator_result); + assembler.Bind(&allocate_iterator_result); { - Node* result = assembler->Allocate(JSIteratorResult::kSize); + Node* result = assembler.Allocate(JSIteratorResult::kSize); Node* map = - assembler->LoadContextElement(assembler->LoadNativeContext(context), - Context::ITERATOR_RESULT_MAP_INDEX); - assembler->StoreMapNoWriteBarrier(result, map); - assembler->StoreObjectFieldRoot(result, JSIteratorResult::kPropertiesOffset, - Heap::kEmptyFixedArrayRootIndex); - assembler->StoreObjectFieldRoot(result, JSIteratorResult::kElementsOffset, - Heap::kEmptyFixedArrayRootIndex); - assembler->StoreObjectFieldNoWriteBarrier( + assembler.LoadContextElement(assembler.LoadNativeContext(context), + Context::ITERATOR_RESULT_MAP_INDEX); + assembler.StoreMapNoWriteBarrier(result, map); + assembler.StoreObjectFieldRoot(result, JSIteratorResult::kPropertiesOffset, + Heap::kEmptyFixedArrayRootIndex); + assembler.StoreObjectFieldRoot(result, JSIteratorResult::kElementsOffset, + Heap::kEmptyFixedArrayRootIndex); + assembler.StoreObjectFieldNoWriteBarrier( result, JSIteratorResult::kValueOffset, var_value.value()); - assembler->StoreObjectFieldNoWriteBarrier( + assembler.StoreObjectFieldNoWriteBarrier( result, JSIteratorResult::kDoneOffset, var_done.value()); - assembler->Return(result); + assembler.Return(result); } - assembler->Bind(&throw_bad_receiver); + assembler.Bind(&throw_bad_receiver); { // The {receiver} is not a valid JSArrayIterator. - Node* result = assembler->CallRuntime( + Node* result = assembler.CallRuntime( Runtime::kThrowIncompatibleMethodReceiver, context, - assembler->HeapConstant(assembler->factory()->NewStringFromAsciiChecked( - "Array Iterator.prototype.next", TENURED)), - iterator); - assembler->Return(result); + assembler.HeapConstant(operation), iterator); + assembler.Return(result); + } + + assembler.Bind(&if_isdetached); + { + Node* message = assembler.SmiConstant(MessageTemplate::kDetachedOperation); + Node* result = + assembler.CallRuntime(Runtime::kThrowTypeError, context, message, + assembler.HeapConstant(operation)); + assembler.Return(result); } } |