| Index: src/builtins/builtins-function.cc
|
| diff --git a/src/builtins/builtins-function.cc b/src/builtins/builtins-function.cc
|
| index e58cad30d8b451b84d9a188c4f8ae4fb4f0e302c..d08b109d112a4ce0d428699db48a57e1dc0ee221 100644
|
| --- a/src/builtins/builtins-function.cc
|
| +++ b/src/builtins/builtins-function.cc
|
| @@ -272,182 +272,160 @@ Object* DoFunctionBind(Isolate* isolate, BuiltinArguments args) {
|
| // ES6 section 19.2.3.2 Function.prototype.bind ( thisArg, ...args )
|
| BUILTIN(FunctionPrototypeBind) { return DoFunctionBind(isolate, args); }
|
|
|
| -void Builtins::Generate_FastFunctionPrototypeBind(
|
| - compiler::CodeAssemblerState* state) {
|
| - using compiler::Node;
|
| - typedef CodeStubAssembler::Label Label;
|
| - typedef CodeStubAssembler::Variable Variable;
|
| +TF_BUILTIN(FastFunctionPrototypeBind, CodeStubAssembler) {
|
| + Label slow(this);
|
|
|
| - CodeStubAssembler assembler(state);
|
| - Label slow(&assembler);
|
| + Node* argc = Parameter(BuiltinDescriptor::kArgumentsCount);
|
| + Node* context = Parameter(BuiltinDescriptor::kContext);
|
| + Node* new_target = Parameter(BuiltinDescriptor::kNewTarget);
|
|
|
| - Node* argc = assembler.Parameter(BuiltinDescriptor::kArgumentsCount);
|
| - Node* context = assembler.Parameter(BuiltinDescriptor::kContext);
|
| - Node* new_target = assembler.Parameter(BuiltinDescriptor::kNewTarget);
|
| -
|
| - CodeStubArguments args(&assembler, assembler.ChangeInt32ToIntPtr(argc));
|
| + CodeStubArguments args(this, ChangeInt32ToIntPtr(argc));
|
|
|
| // Check that receiver has instance type of JS_FUNCTION_TYPE
|
| Node* receiver = args.GetReceiver();
|
| - assembler.GotoIf(assembler.TaggedIsSmi(receiver), &slow);
|
| + GotoIf(TaggedIsSmi(receiver), &slow);
|
|
|
| - Node* receiver_map = assembler.LoadMap(receiver);
|
| - Node* instance_type = assembler.LoadMapInstanceType(receiver_map);
|
| - assembler.GotoIf(
|
| - assembler.Word32NotEqual(instance_type,
|
| - assembler.Int32Constant(JS_FUNCTION_TYPE)),
|
| - &slow);
|
| + Node* receiver_map = LoadMap(receiver);
|
| + Node* instance_type = LoadMapInstanceType(receiver_map);
|
| + GotoIf(Word32NotEqual(instance_type, Int32Constant(JS_FUNCTION_TYPE)), &slow);
|
|
|
| // Disallow binding of slow-mode functions. We need to figure out whether the
|
| // length and name property are in the original state.
|
| - assembler.Comment("Disallow binding of slow-mode functions");
|
| - assembler.GotoIf(assembler.IsDictionaryMap(receiver_map), &slow);
|
| + Comment("Disallow binding of slow-mode functions");
|
| + GotoIf(IsDictionaryMap(receiver_map), &slow);
|
|
|
| // Check whether the length and name properties are still present as
|
| // AccessorInfo objects. In that case, their value can be recomputed even if
|
| // the actual value on the object changes.
|
| - assembler.Comment("Check descriptor array length");
|
| - Node* descriptors = assembler.LoadMapDescriptors(receiver_map);
|
| - Node* descriptors_length = assembler.LoadFixedArrayBaseLength(descriptors);
|
| - assembler.GotoIf(assembler.SmiLessThanOrEqual(descriptors_length,
|
| - assembler.SmiConstant(1)),
|
| - &slow);
|
| + Comment("Check descriptor array length");
|
| + Node* descriptors = LoadMapDescriptors(receiver_map);
|
| + Node* descriptors_length = LoadFixedArrayBaseLength(descriptors);
|
| + GotoIf(SmiLessThanOrEqual(descriptors_length, SmiConstant(1)), &slow);
|
|
|
| // Check whether the length and name properties are still present as
|
| // AccessorInfo objects. In that case, their value can be recomputed even if
|
| // the actual value on the object changes.
|
| - assembler.Comment("Check name and length properties");
|
| + Comment("Check name and length properties");
|
| const int length_index = JSFunction::kLengthDescriptorIndex;
|
| - Node* maybe_length = assembler.LoadFixedArrayElement(
|
| + Node* maybe_length = LoadFixedArrayElement(
|
| descriptors, DescriptorArray::ToKeyIndex(length_index));
|
| - assembler.GotoIf(
|
| - assembler.WordNotEqual(maybe_length,
|
| - assembler.LoadRoot(Heap::klength_stringRootIndex)),
|
| - &slow);
|
| + GotoIf(WordNotEqual(maybe_length, LoadRoot(Heap::klength_stringRootIndex)),
|
| + &slow);
|
|
|
| - Node* maybe_length_accessor = assembler.LoadFixedArrayElement(
|
| + Node* maybe_length_accessor = LoadFixedArrayElement(
|
| descriptors, DescriptorArray::ToValueIndex(length_index));
|
| - assembler.GotoIf(assembler.TaggedIsSmi(maybe_length_accessor), &slow);
|
| - Node* length_value_map = assembler.LoadMap(maybe_length_accessor);
|
| - assembler.GotoIfNot(assembler.IsAccessorInfoMap(length_value_map), &slow);
|
| + GotoIf(TaggedIsSmi(maybe_length_accessor), &slow);
|
| + Node* length_value_map = LoadMap(maybe_length_accessor);
|
| + GotoIfNot(IsAccessorInfoMap(length_value_map), &slow);
|
|
|
| const int name_index = JSFunction::kNameDescriptorIndex;
|
| - Node* maybe_name = assembler.LoadFixedArrayElement(
|
| + Node* maybe_name = LoadFixedArrayElement(
|
| descriptors, DescriptorArray::ToKeyIndex(name_index));
|
| - assembler.GotoIf(
|
| - assembler.WordNotEqual(maybe_name,
|
| - assembler.LoadRoot(Heap::kname_stringRootIndex)),
|
| - &slow);
|
| + GotoIf(WordNotEqual(maybe_name, LoadRoot(Heap::kname_stringRootIndex)),
|
| + &slow);
|
|
|
| - Node* maybe_name_accessor = assembler.LoadFixedArrayElement(
|
| + Node* maybe_name_accessor = LoadFixedArrayElement(
|
| descriptors, DescriptorArray::ToValueIndex(name_index));
|
| - assembler.GotoIf(assembler.TaggedIsSmi(maybe_name_accessor), &slow);
|
| - Node* name_value_map = assembler.LoadMap(maybe_name_accessor);
|
| - assembler.GotoIfNot(assembler.IsAccessorInfoMap(name_value_map), &slow);
|
| + GotoIf(TaggedIsSmi(maybe_name_accessor), &slow);
|
| + Node* name_value_map = LoadMap(maybe_name_accessor);
|
| + GotoIfNot(IsAccessorInfoMap(name_value_map), &slow);
|
|
|
| // Choose the right bound function map based on whether the target is
|
| // constructable.
|
| - assembler.Comment("Choose the right bound function map");
|
| - Variable bound_function_map(&assembler, MachineRepresentation::kTagged);
|
| - Label with_constructor(&assembler);
|
| - CodeStubAssembler::VariableList vars({&bound_function_map}, assembler.zone());
|
| - Node* native_context = assembler.LoadNativeContext(context);
|
| -
|
| - Label map_done(&assembler, vars);
|
| - Node* bit_field = assembler.LoadMapBitField(receiver_map);
|
| + Comment("Choose the right bound function map");
|
| + Variable bound_function_map(this, MachineRepresentation::kTagged);
|
| + Label with_constructor(this);
|
| + VariableList vars({&bound_function_map}, zone());
|
| + Node* native_context = LoadNativeContext(context);
|
| +
|
| + Label map_done(this, vars);
|
| + Node* bit_field = LoadMapBitField(receiver_map);
|
| int mask = static_cast<int>(1 << Map::kIsConstructor);
|
| - assembler.GotoIf(assembler.IsSetWord32(bit_field, mask), &with_constructor);
|
| + GotoIf(IsSetWord32(bit_field, mask), &with_constructor);
|
|
|
| - bound_function_map.Bind(assembler.LoadContextElement(
|
| + bound_function_map.Bind(LoadContextElement(
|
| native_context, Context::BOUND_FUNCTION_WITHOUT_CONSTRUCTOR_MAP_INDEX));
|
| - assembler.Goto(&map_done);
|
| + Goto(&map_done);
|
|
|
| - assembler.Bind(&with_constructor);
|
| - bound_function_map.Bind(assembler.LoadContextElement(
|
| + Bind(&with_constructor);
|
| + bound_function_map.Bind(LoadContextElement(
|
| native_context, Context::BOUND_FUNCTION_WITH_CONSTRUCTOR_MAP_INDEX));
|
| - assembler.Goto(&map_done);
|
| + Goto(&map_done);
|
|
|
| - assembler.Bind(&map_done);
|
| + Bind(&map_done);
|
|
|
| // Verify that __proto__ matches that of a the target bound function.
|
| - assembler.Comment("Verify that __proto__ matches target bound function");
|
| - Node* prototype = assembler.LoadMapPrototype(receiver_map);
|
| - Node* expected_prototype =
|
| - assembler.LoadMapPrototype(bound_function_map.value());
|
| - assembler.GotoIf(assembler.WordNotEqual(prototype, expected_prototype),
|
| - &slow);
|
| + Comment("Verify that __proto__ matches target bound function");
|
| + Node* prototype = LoadMapPrototype(receiver_map);
|
| + Node* expected_prototype = LoadMapPrototype(bound_function_map.value());
|
| + GotoIf(WordNotEqual(prototype, expected_prototype), &slow);
|
|
|
| // Allocate the arguments array.
|
| - assembler.Comment("Allocate the arguments array");
|
| - Variable argument_array(&assembler, MachineRepresentation::kTagged);
|
| - Label empty_arguments(&assembler);
|
| - Label arguments_done(&assembler, &argument_array);
|
| - assembler.GotoIf(
|
| - assembler.Uint32LessThanOrEqual(argc, assembler.Int32Constant(1)),
|
| - &empty_arguments);
|
| - Node* elements_length = assembler.ChangeUint32ToWord(
|
| - assembler.Int32Sub(argc, assembler.Int32Constant(1)));
|
| - Node* elements = assembler.AllocateFixedArray(FAST_ELEMENTS, elements_length);
|
| - Variable index(&assembler, MachineType::PointerRepresentation());
|
| - index.Bind(assembler.IntPtrConstant(0));
|
| - CodeStubAssembler::VariableList foreach_vars({&index}, assembler.zone());
|
| + Comment("Allocate the arguments array");
|
| + Variable argument_array(this, MachineRepresentation::kTagged);
|
| + Label empty_arguments(this);
|
| + Label arguments_done(this, &argument_array);
|
| + GotoIf(Uint32LessThanOrEqual(argc, Int32Constant(1)), &empty_arguments);
|
| + Node* elements_length = ChangeUint32ToWord(Int32Sub(argc, Int32Constant(1)));
|
| + Node* elements = AllocateFixedArray(FAST_ELEMENTS, elements_length);
|
| + Variable index(this, MachineType::PointerRepresentation());
|
| + index.Bind(IntPtrConstant(0));
|
| + VariableList foreach_vars({&index}, zone());
|
| args.ForEach(foreach_vars,
|
| - [&assembler, elements, &index](compiler::Node* arg) {
|
| - assembler.StoreFixedArrayElement(elements, index.value(), arg);
|
| - assembler.Increment(index);
|
| + [this, elements, &index](Node* arg) {
|
| + StoreFixedArrayElement(elements, index.value(), arg);
|
| + Increment(index);
|
| },
|
| - assembler.IntPtrConstant(1));
|
| + IntPtrConstant(1));
|
| argument_array.Bind(elements);
|
| - assembler.Goto(&arguments_done);
|
| + Goto(&arguments_done);
|
|
|
| - assembler.Bind(&empty_arguments);
|
| - argument_array.Bind(assembler.EmptyFixedArrayConstant());
|
| - assembler.Goto(&arguments_done);
|
| + Bind(&empty_arguments);
|
| + argument_array.Bind(EmptyFixedArrayConstant());
|
| + Goto(&arguments_done);
|
|
|
| - assembler.Bind(&arguments_done);
|
| + Bind(&arguments_done);
|
|
|
| // Determine bound receiver.
|
| - assembler.Comment("Determine bound receiver");
|
| - Variable bound_receiver(&assembler, MachineRepresentation::kTagged);
|
| - Label has_receiver(&assembler);
|
| - Label receiver_done(&assembler, &bound_receiver);
|
| - assembler.GotoIf(assembler.Word32NotEqual(argc, assembler.Int32Constant(0)),
|
| - &has_receiver);
|
| - bound_receiver.Bind(assembler.UndefinedConstant());
|
| - assembler.Goto(&receiver_done);
|
| -
|
| - assembler.Bind(&has_receiver);
|
| + Comment("Determine bound receiver");
|
| + Variable bound_receiver(this, MachineRepresentation::kTagged);
|
| + Label has_receiver(this);
|
| + Label receiver_done(this, &bound_receiver);
|
| + GotoIf(Word32NotEqual(argc, Int32Constant(0)), &has_receiver);
|
| + bound_receiver.Bind(UndefinedConstant());
|
| + Goto(&receiver_done);
|
| +
|
| + Bind(&has_receiver);
|
| bound_receiver.Bind(args.AtIndex(0));
|
| - assembler.Goto(&receiver_done);
|
| + Goto(&receiver_done);
|
|
|
| - assembler.Bind(&receiver_done);
|
| + Bind(&receiver_done);
|
|
|
| // Allocate the resulting bound function.
|
| - assembler.Comment("Allocate the resulting bound function");
|
| - Node* bound_function = assembler.Allocate(JSBoundFunction::kSize);
|
| - assembler.StoreMapNoWriteBarrier(bound_function, bound_function_map.value());
|
| - assembler.StoreObjectFieldNoWriteBarrier(
|
| + Comment("Allocate the resulting bound function");
|
| + Node* bound_function = Allocate(JSBoundFunction::kSize);
|
| + StoreMapNoWriteBarrier(bound_function, bound_function_map.value());
|
| + StoreObjectFieldNoWriteBarrier(
|
| bound_function, JSBoundFunction::kBoundTargetFunctionOffset, receiver);
|
| - assembler.StoreObjectFieldNoWriteBarrier(bound_function,
|
| - JSBoundFunction::kBoundThisOffset,
|
| - bound_receiver.value());
|
| - assembler.StoreObjectFieldNoWriteBarrier(
|
| - bound_function, JSBoundFunction::kBoundArgumentsOffset,
|
| - argument_array.value());
|
| - Node* empty_fixed_array = assembler.EmptyFixedArrayConstant();
|
| - assembler.StoreObjectFieldNoWriteBarrier(
|
| - bound_function, JSObject::kPropertiesOffset, empty_fixed_array);
|
| - assembler.StoreObjectFieldNoWriteBarrier(
|
| - bound_function, JSObject::kElementsOffset, empty_fixed_array);
|
| + StoreObjectFieldNoWriteBarrier(bound_function,
|
| + JSBoundFunction::kBoundThisOffset,
|
| + bound_receiver.value());
|
| + StoreObjectFieldNoWriteBarrier(bound_function,
|
| + JSBoundFunction::kBoundArgumentsOffset,
|
| + argument_array.value());
|
| + Node* empty_fixed_array = EmptyFixedArrayConstant();
|
| + StoreObjectFieldNoWriteBarrier(bound_function, JSObject::kPropertiesOffset,
|
| + empty_fixed_array);
|
| + StoreObjectFieldNoWriteBarrier(bound_function, JSObject::kElementsOffset,
|
| + empty_fixed_array);
|
|
|
| args.PopAndReturn(bound_function);
|
| - assembler.Bind(&slow);
|
| + Bind(&slow);
|
|
|
| - Node* target = assembler.LoadFromFrame(
|
| - StandardFrameConstants::kFunctionOffset, MachineType::TaggedPointer());
|
| - assembler.TailCallStub(
|
| - CodeFactory::FunctionPrototypeBind(assembler.isolate()), context, target,
|
| - new_target, argc);
|
| + Node* target = LoadFromFrame(StandardFrameConstants::kFunctionOffset,
|
| + MachineType::TaggedPointer());
|
| + TailCallStub(CodeFactory::FunctionPrototypeBind(isolate()), context, target,
|
| + new_target, argc);
|
| }
|
|
|
| // TODO(verwaest): This is a temporary helper until the FastFunctionBind stub
|
| @@ -477,16 +455,12 @@ BUILTIN(FunctionPrototypeToString) {
|
| }
|
|
|
| // ES6 section 19.2.3.6 Function.prototype [ @@hasInstance ] ( V )
|
| -void Builtins::Generate_FunctionPrototypeHasInstance(
|
| - compiler::CodeAssemblerState* state) {
|
| - using compiler::Node;
|
| - CodeStubAssembler assembler(state);
|
| -
|
| - Node* f = assembler.Parameter(0);
|
| - Node* v = assembler.Parameter(1);
|
| - Node* context = assembler.Parameter(4);
|
| - Node* result = assembler.OrdinaryHasInstance(context, f, v);
|
| - assembler.Return(result);
|
| +TF_BUILTIN(FunctionPrototypeHasInstance, CodeStubAssembler) {
|
| + Node* f = Parameter(0);
|
| + Node* v = Parameter(1);
|
| + Node* context = Parameter(4);
|
| + Node* result = OrdinaryHasInstance(context, f, v);
|
| + Return(result);
|
| }
|
|
|
| } // namespace internal
|
|
|