From 4013a8df54d2cd6073cb6a92446d95b9ca97c967 Mon Sep 17 00:00:00 2001 From: bmeurer Date: Wed, 2 Dec 2015 04:01:22 -0800 Subject: [PATCH] [builtins] Some refactoring on the builtin mechanism. Allow to pass new.target (in addition to target) to C++ builtins, and remove some obsolete/dangerous code from the C++ builtins. R=yangguo@chromium.org Review URL: https://codereview.chromium.org/1491883002 Cr-Commit-Position: refs/heads/master@{#32505} --- src/arm/builtins-arm.cc | 23 +++- src/arm64/builtins-arm64.cc | 23 +++- src/builtins.cc | 203 +++++++++++++++------------------- src/builtins.h | 87 ++++++++------- src/ia32/builtins-ia32.cc | 22 ++-- src/mips/builtins-mips.cc | 23 +++- src/mips64/builtins-mips64.cc | 23 +++- src/ppc/builtins-ppc.cc | 23 +++- src/x64/builtins-x64.cc | 17 ++- src/x87/builtins-x87.cc | 22 ++-- 10 files changed, 256 insertions(+), 210 deletions(-) diff --git a/src/arm/builtins-arm.cc b/src/arm/builtins-arm.cc index a2d5f75709..fc27816a18 100644 --- a/src/arm/builtins-arm.cc +++ b/src/arm/builtins-arm.cc @@ -22,7 +22,8 @@ void Builtins::Generate_Adaptor(MacroAssembler* masm, BuiltinExtraArguments extra_args) { // ----------- S t a t e ------------- // -- r0 : number of arguments excluding receiver - // -- r1 : called function + // -- r1 : target + // -- r3 : new.target // -- sp[0] : last argument // -- ... // -- sp[4 * (argc - 1)] : first argument @@ -32,11 +33,21 @@ void Builtins::Generate_Adaptor(MacroAssembler* masm, // Insert extra arguments. int num_extra_args = 0; - if (extra_args == NEEDS_CALLED_FUNCTION) { - num_extra_args = 1; - __ push(r1); - } else { - DCHECK(extra_args == NO_EXTRA_ARGUMENTS); + switch (extra_args) { + case BuiltinExtraArguments::kTarget: + __ Push(r1); + ++num_extra_args; + break; + case BuiltinExtraArguments::kNewTarget: + __ Push(r3); + ++num_extra_args; + break; + case BuiltinExtraArguments::kTargetAndNewTarget: + __ Push(r1, r3); + num_extra_args += 2; + break; + case BuiltinExtraArguments::kNone: + break; } // JumpToExternalReference expects r0 to contain the number of arguments diff --git a/src/arm64/builtins-arm64.cc b/src/arm64/builtins-arm64.cc index f0f92c344b..ac4d8881ee 100644 --- a/src/arm64/builtins-arm64.cc +++ b/src/arm64/builtins-arm64.cc @@ -38,7 +38,8 @@ void Builtins::Generate_Adaptor(MacroAssembler* masm, BuiltinExtraArguments extra_args) { // ----------- S t a t e ------------- // -- x0 : number of arguments excluding receiver - // -- x1 : called function + // -- x1 : target + // -- x3 : new target // -- sp[0] : last argument // -- ... // -- sp[4 * (argc - 1)] : first argument @@ -48,11 +49,21 @@ void Builtins::Generate_Adaptor(MacroAssembler* masm, // Insert extra arguments. int num_extra_args = 0; - if (extra_args == NEEDS_CALLED_FUNCTION) { - num_extra_args = 1; - __ Push(x1); - } else { - DCHECK(extra_args == NO_EXTRA_ARGUMENTS); + switch (extra_args) { + case BuiltinExtraArguments::kTarget: + __ Push(x1); + ++num_extra_args; + break; + case BuiltinExtraArguments::kNewTarget: + __ Push(x3); + ++num_extra_args; + break; + case BuiltinExtraArguments::kTargetAndNewTarget: + __ Push(x1, x3); + num_extra_args += 2; + break; + case BuiltinExtraArguments::kNone: + break; } // JumpToExternalReference expects x0 to contain the number of arguments diff --git a/src/builtins.cc b/src/builtins.cc index 22ad3fa22c..269736b76a 100644 --- a/src/builtins.cc +++ b/src/builtins.cc @@ -31,7 +31,10 @@ template class BuiltinArguments : public Arguments { public: BuiltinArguments(int length, Object** arguments) - : Arguments(length, arguments) { } + : Arguments(length, arguments) { + // Check we have at least the receiver. + DCHECK_LE(1, this->length()); + } Object*& operator[] (int index) { DCHECK(index < length()); @@ -47,47 +50,64 @@ class BuiltinArguments : public Arguments { return Arguments::at(0); } - Handle called_function() { - STATIC_ASSERT(extra_args == NEEDS_CALLED_FUNCTION); - return Arguments::at(Arguments::length() - 1); - } + Handle target(); + Handle new_target(); // Gets the total number of arguments including the receiver (but // excluding extra arguments). - int length() const { - STATIC_ASSERT(extra_args == NO_EXTRA_ARGUMENTS); - return Arguments::length(); - } - -#ifdef DEBUG - void Verify() { - // Check we have at least the receiver. - DCHECK(Arguments::length() >= 1); - } -#endif + int length() const; }; -// Specialize BuiltinArguments for the called function extra argument. +// Specialize BuiltinArguments for the extra arguments. template <> -int BuiltinArguments::length() const { +int BuiltinArguments::length() const { + return Arguments::length(); +} + +template <> +int BuiltinArguments::length() const { return Arguments::length() - 1; } -#ifdef DEBUG template <> -void BuiltinArguments::Verify() { - // Check we have at least the receiver and the called function. - DCHECK(Arguments::length() >= 2); - // Make sure cast to JSFunction succeeds. - called_function(); +Handle BuiltinArguments::target() { + return Arguments::at(Arguments::length() - 1); +} + +template <> +int BuiltinArguments::length() const { + return Arguments::length() - 1; +} + +template <> +Handle +BuiltinArguments::new_target() { + return Arguments::at(Arguments::length() - 1); +} + +template <> +int BuiltinArguments::length() + const { + return Arguments::length() - 2; +} + +template <> +Handle +BuiltinArguments::target() { + return Arguments::at(Arguments::length() - 2); +} + +template <> +Handle +BuiltinArguments::new_target() { + return Arguments::at(Arguments::length() - 1); } -#endif -#define DEF_ARG_TYPE(name, spec) \ - typedef BuiltinArguments name##ArgumentsType; +#define DEF_ARG_TYPE(name, spec) \ + typedef BuiltinArguments name##ArgumentsType; BUILTIN_LIST_C(DEF_ARG_TYPE) #undef DEF_ARG_TYPE @@ -105,63 +125,17 @@ BUILTIN_LIST_C(DEF_ARG_TYPE) // In the body of the builtin function the arguments can be accessed // through the BuiltinArguments object args. -#ifdef DEBUG - #define BUILTIN(name) \ MUST_USE_RESULT static Object* Builtin_Impl_##name( \ name##ArgumentsType args, Isolate* isolate); \ MUST_USE_RESULT static Object* Builtin_##name( \ int args_length, Object** args_object, Isolate* isolate) { \ name##ArgumentsType args(args_length, args_object); \ - args.Verify(); \ return Builtin_Impl_##name(args, isolate); \ } \ MUST_USE_RESULT static Object* Builtin_Impl_##name( \ name##ArgumentsType args, Isolate* isolate) -#else // For release mode. - -#define BUILTIN(name) \ - static Object* Builtin_impl##name( \ - name##ArgumentsType args, Isolate* isolate); \ - static Object* Builtin_##name( \ - int args_length, Object** args_object, Isolate* isolate) { \ - name##ArgumentsType args(args_length, args_object); \ - return Builtin_impl##name(args, isolate); \ - } \ - static Object* Builtin_impl##name( \ - name##ArgumentsType args, Isolate* isolate) -#endif - - -#ifdef DEBUG -inline bool CalledAsConstructor(Isolate* isolate) { - // Calculate the result using a full stack frame iterator and check - // that the state of the stack is as we assume it to be in the - // code below. - StackFrameIterator it(isolate); - DCHECK(it.frame()->is_exit()); - it.Advance(); - StackFrame* frame = it.frame(); - bool reference_result = frame->is_construct(); - Address fp = Isolate::c_entry_fp(isolate->thread_local_top()); - // Because we know fp points to an exit frame we can use the relevant - // part of ExitFrame::ComputeCallerState directly. - const int kCallerOffset = ExitFrameConstants::kCallerFPOffset; - Address caller_fp = Memory::Address_at(fp + kCallerOffset); - // This inlines the part of StackFrame::ComputeType that grabs the - // type of the current frame. Note that StackFrame::ComputeType - // has been specialized for each architecture so if any one of them - // changes this code has to be changed as well. - const int kMarkerOffset = StandardFrameConstants::kMarkerOffset; - const Smi* kConstructMarker = Smi::FromInt(StackFrame::CONSTRUCT); - Object* marker = Memory::Object_at(caller_fp + kMarkerOffset); - bool result = (marker == kConstructMarker); - DCHECK_EQ(result, reference_result); - return result; -} -#endif - // ---------------------------------------------------------------------------- @@ -306,7 +280,7 @@ inline MaybeHandle EnsureJSArrayWithWritableFastElements( MUST_USE_RESULT static Object* CallJsIntrinsic( Isolate* isolate, Handle function, - BuiltinArguments args) { + BuiltinArguments args) { HandleScope handleScope(isolate); int argc = args.length() - 1; ScopedVector > argv(argc); @@ -1764,7 +1738,7 @@ BUILTIN(SymbolConstructor_ConstructStub) { HandleScope scope(isolate); // The ConstructStub is executed in the context of the caller, so we need // to enter the callee context first before raising an exception. - isolate->set_context(args.called_function()->context()); + isolate->set_context(args.target()->context()); THROW_NEW_ERROR_RETURN_FAILURE( isolate, NewTypeError(MessageTemplate::kNotConstructor, isolate->factory()->Symbol_string())); @@ -1794,11 +1768,13 @@ BUILTIN(RestrictedStrictArgumentsPropertiesThrower) { // +namespace { + template -MUST_USE_RESULT static MaybeHandle HandleApiCallHelper( - Isolate* isolate, BuiltinArguments& args) { +MUST_USE_RESULT MaybeHandle HandleApiCallHelper( + Isolate* isolate, BuiltinArguments args) { HandleScope scope(isolate); - Handle function = args.called_function(); + Handle function = args.target(); // TODO(ishell): turn this back to a DCHECK. CHECK(function->shared()->IsApiFunction()); @@ -1873,10 +1849,11 @@ MUST_USE_RESULT static MaybeHandle HandleApiCallHelper( return scope.CloseAndEscape(args.receiver()); } +} // namespace + BUILTIN(HandleApiCall) { HandleScope scope(isolate); - DCHECK(!CalledAsConstructor(isolate)); Handle result; ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, HandleApiCallHelper(isolate, args)); @@ -1886,7 +1863,6 @@ BUILTIN(HandleApiCall) { BUILTIN(HandleApiCallConstruct) { HandleScope scope(isolate); - DCHECK(CalledAsConstructor(isolate)); Handle result; ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, HandleApiCallHelper(isolate, args)); @@ -1924,11 +1900,12 @@ Handle Builtins::Call(ConvertReceiverMode mode) { namespace { -class RelocatableArguments : public BuiltinArguments, - public Relocatable { +class RelocatableArguments + : public BuiltinArguments, + public Relocatable { public: RelocatableArguments(Isolate* isolate, int length, Object** arguments) - : BuiltinArguments(length, arguments), + : BuiltinArguments(length, arguments), Relocatable(isolate) {} virtual inline void IterateInstance(ObjectVisitor* v) { @@ -1978,12 +1955,8 @@ MaybeHandle Builtins::InvokeApiFunction(Handle function, // API. The object can be called as either a constructor (using new) or just as // a function (without new). MUST_USE_RESULT static Object* HandleApiCallAsFunctionOrConstructor( - Isolate* isolate, - bool is_construct_call, - BuiltinArguments args) { - // Non-functions are never called as constructors. Even if this is an object - // called as a constructor the delegate call is not a construct call. - DCHECK(!CalledAsConstructor(isolate)); + Isolate* isolate, bool is_construct_call, + BuiltinArguments args) { Heap* heap = isolate->heap(); Handle receiver = args.receiver(); @@ -2240,36 +2213,34 @@ void Builtins::InitBuiltinFunctionTable() { functions[builtin_count].s_name = NULL; functions[builtin_count].name = builtin_count; functions[builtin_count].flags = static_cast(0); - functions[builtin_count].extra_args = NO_EXTRA_ARGUMENTS; + functions[builtin_count].extra_args = BuiltinExtraArguments::kNone; -#define DEF_FUNCTION_PTR_C(aname, aextra_args) \ - functions->generator = FUNCTION_ADDR(Generate_Adaptor); \ - functions->c_code = FUNCTION_ADDR(Builtin_##aname); \ - functions->s_name = #aname; \ - functions->name = c_##aname; \ - functions->flags = Code::ComputeFlags(Code::BUILTIN); \ - functions->extra_args = aextra_args; \ - ++functions; +#define DEF_FUNCTION_PTR_C(aname, aextra_args) \ + functions->generator = FUNCTION_ADDR(Generate_Adaptor); \ + functions->c_code = FUNCTION_ADDR(Builtin_##aname); \ + functions->s_name = #aname; \ + functions->name = c_##aname; \ + functions->flags = Code::ComputeFlags(Code::BUILTIN); \ + functions->extra_args = BuiltinExtraArguments::aextra_args; \ + ++functions; -#define DEF_FUNCTION_PTR_A(aname, kind, state, extra) \ - functions->generator = FUNCTION_ADDR(Generate_##aname); \ - functions->c_code = NULL; \ - functions->s_name = #aname; \ - functions->name = k##aname; \ - functions->flags = Code::ComputeFlags(Code::kind, \ - state, \ - extra); \ - functions->extra_args = NO_EXTRA_ARGUMENTS; \ - ++functions; +#define DEF_FUNCTION_PTR_A(aname, kind, state, extra) \ + functions->generator = FUNCTION_ADDR(Generate_##aname); \ + functions->c_code = NULL; \ + functions->s_name = #aname; \ + functions->name = k##aname; \ + functions->flags = Code::ComputeFlags(Code::kind, state, extra); \ + functions->extra_args = BuiltinExtraArguments::kNone; \ + ++functions; -#define DEF_FUNCTION_PTR_H(aname, kind) \ - functions->generator = FUNCTION_ADDR(Generate_##aname); \ - functions->c_code = NULL; \ - functions->s_name = #aname; \ - functions->name = k##aname; \ - functions->flags = Code::ComputeHandlerFlags(Code::kind); \ - functions->extra_args = NO_EXTRA_ARGUMENTS; \ - ++functions; +#define DEF_FUNCTION_PTR_H(aname, kind) \ + functions->generator = FUNCTION_ADDR(Generate_##aname); \ + functions->c_code = NULL; \ + functions->s_name = #aname; \ + functions->name = k##aname; \ + functions->flags = Code::ComputeHandlerFlags(Code::kind); \ + functions->extra_args = BuiltinExtraArguments::kNone; \ + ++functions; BUILTIN_LIST_C(DEF_FUNCTION_PTR_C) BUILTIN_LIST_A(DEF_FUNCTION_PTR_A) diff --git a/src/builtins.h b/src/builtins.h index 02259599cd..315c277cbc 100644 --- a/src/builtins.h +++ b/src/builtins.h @@ -5,17 +5,24 @@ #ifndef V8_BUILTINS_H_ #define V8_BUILTINS_H_ +#include "src/base/flags.h" #include "src/handles.h" namespace v8 { namespace internal { // Specifies extra arguments required by a C++ builtin. -enum BuiltinExtraArguments { - NO_EXTRA_ARGUMENTS = 0, - NEEDS_CALLED_FUNCTION = 1 +enum class BuiltinExtraArguments : uint8_t { + kNone = 0u, + kTarget = 1u << 0, + kNewTarget = 1u << 1, + kTargetAndNewTarget = kTarget | kNewTarget }; +inline bool operator&(BuiltinExtraArguments lhs, BuiltinExtraArguments rhs) { + return static_cast(lhs) & static_cast(rhs); +} + #define CODE_AGE_LIST_WITH_ARG(V, A) \ V(Quadragenarian, A) \ @@ -44,43 +51,43 @@ enum BuiltinExtraArguments { // Define list of builtins implemented in C++. -#define BUILTIN_LIST_C(V) \ - V(Illegal, NO_EXTRA_ARGUMENTS) \ - \ - V(EmptyFunction, NO_EXTRA_ARGUMENTS) \ - \ - V(ArrayPush, NO_EXTRA_ARGUMENTS) \ - V(ArrayPop, NO_EXTRA_ARGUMENTS) \ - V(ArrayShift, NO_EXTRA_ARGUMENTS) \ - V(ArrayUnshift, NO_EXTRA_ARGUMENTS) \ - V(ArraySlice, NO_EXTRA_ARGUMENTS) \ - V(ArraySplice, NO_EXTRA_ARGUMENTS) \ - V(ArrayConcat, NO_EXTRA_ARGUMENTS) \ - \ - V(DateToPrimitive, NO_EXTRA_ARGUMENTS) \ - \ - V(ReflectDefineProperty, NO_EXTRA_ARGUMENTS) \ - V(ReflectDeleteProperty, NO_EXTRA_ARGUMENTS) \ - V(ReflectGet, NO_EXTRA_ARGUMENTS) \ - V(ReflectGetOwnPropertyDescriptor, NO_EXTRA_ARGUMENTS) \ - V(ReflectGetPrototypeOf, NO_EXTRA_ARGUMENTS) \ - V(ReflectHas, NO_EXTRA_ARGUMENTS) \ - V(ReflectIsExtensible, NO_EXTRA_ARGUMENTS) \ - V(ReflectOwnKeys, NO_EXTRA_ARGUMENTS) \ - V(ReflectPreventExtensions, NO_EXTRA_ARGUMENTS) \ - V(ReflectSet, NO_EXTRA_ARGUMENTS) \ - V(ReflectSetPrototypeOf, NO_EXTRA_ARGUMENTS) \ - \ - V(SymbolConstructor, NO_EXTRA_ARGUMENTS) \ - V(SymbolConstructor_ConstructStub, NEEDS_CALLED_FUNCTION) \ - \ - V(HandleApiCall, NEEDS_CALLED_FUNCTION) \ - V(HandleApiCallConstruct, NEEDS_CALLED_FUNCTION) \ - V(HandleApiCallAsFunction, NO_EXTRA_ARGUMENTS) \ - V(HandleApiCallAsConstructor, NO_EXTRA_ARGUMENTS) \ - \ - V(RestrictedFunctionPropertiesThrower, NO_EXTRA_ARGUMENTS) \ - V(RestrictedStrictArgumentsPropertiesThrower, NO_EXTRA_ARGUMENTS) +#define BUILTIN_LIST_C(V) \ + V(Illegal, kNone) \ + \ + V(EmptyFunction, kNone) \ + \ + V(ArrayPush, kNone) \ + V(ArrayPop, kNone) \ + V(ArrayShift, kNone) \ + V(ArrayUnshift, kNone) \ + V(ArraySlice, kNone) \ + V(ArraySplice, kNone) \ + V(ArrayConcat, kNone) \ + \ + V(DateToPrimitive, kNone) \ + \ + V(ReflectDefineProperty, kNone) \ + V(ReflectDeleteProperty, kNone) \ + V(ReflectGet, kNone) \ + V(ReflectGetOwnPropertyDescriptor, kNone) \ + V(ReflectGetPrototypeOf, kNone) \ + V(ReflectHas, kNone) \ + V(ReflectIsExtensible, kNone) \ + V(ReflectOwnKeys, kNone) \ + V(ReflectPreventExtensions, kNone) \ + V(ReflectSet, kNone) \ + V(ReflectSetPrototypeOf, kNone) \ + \ + V(SymbolConstructor, kNone) \ + V(SymbolConstructor_ConstructStub, kTarget) \ + \ + V(HandleApiCall, kTarget) \ + V(HandleApiCallConstruct, kTarget) \ + V(HandleApiCallAsFunction, kNone) \ + V(HandleApiCallAsConstructor, kNone) \ + \ + V(RestrictedFunctionPropertiesThrower, kNone) \ + V(RestrictedStrictArgumentsPropertiesThrower, kNone) // Define list of builtins implemented in assembly. #define BUILTIN_LIST_A(V) \ diff --git a/src/ia32/builtins-ia32.cc b/src/ia32/builtins-ia32.cc index b877277726..688ef13b1f 100644 --- a/src/ia32/builtins-ia32.cc +++ b/src/ia32/builtins-ia32.cc @@ -22,7 +22,8 @@ void Builtins::Generate_Adaptor(MacroAssembler* masm, BuiltinExtraArguments extra_args) { // ----------- S t a t e ------------- // -- eax : number of arguments excluding receiver - // -- edi : called function + // -- edi : target + // -- edx : new.target // -- esp[0] : return address // -- esp[4] : last argument // -- ... @@ -33,14 +34,17 @@ void Builtins::Generate_Adaptor(MacroAssembler* masm, // Insert extra arguments. int num_extra_args = 0; - if (extra_args == NEEDS_CALLED_FUNCTION) { - num_extra_args = 1; - Register scratch = ebx; - __ pop(scratch); // Save return address. - __ push(edi); - __ push(scratch); // Restore return address. - } else { - DCHECK(extra_args == NO_EXTRA_ARGUMENTS); + if (extra_args != BuiltinExtraArguments::kNone) { + __ PopReturnAddressTo(ecx); + if (extra_args & BuiltinExtraArguments::kTarget) { + ++num_extra_args; + __ Push(edi); + } + if (extra_args & BuiltinExtraArguments::kNewTarget) { + ++num_extra_args; + __ Push(edx); + } + __ PushReturnAddressFrom(ecx); } // JumpToExternalReference expects eax to contain the number of arguments diff --git a/src/mips/builtins-mips.cc b/src/mips/builtins-mips.cc index 5f3d3e2012..b4c2f8dcab 100644 --- a/src/mips/builtins-mips.cc +++ b/src/mips/builtins-mips.cc @@ -23,7 +23,8 @@ void Builtins::Generate_Adaptor(MacroAssembler* masm, BuiltinExtraArguments extra_args) { // ----------- S t a t e ------------- // -- a0 : number of arguments excluding receiver - // -- a1 : called function + // -- a1 : target + // -- a3 : new.target // -- sp[0] : last argument // -- ... // -- sp[4 * (argc - 1)] : first argument @@ -33,11 +34,21 @@ void Builtins::Generate_Adaptor(MacroAssembler* masm, // Insert extra arguments. int num_extra_args = 0; - if (extra_args == NEEDS_CALLED_FUNCTION) { - num_extra_args = 1; - __ push(a1); - } else { - DCHECK(extra_args == NO_EXTRA_ARGUMENTS); + switch (extra_args) { + case BuiltinExtraArguments::kTarget: + __ Push(a1); + ++num_extra_args; + break; + case BuiltinExtraArguments::kNewTarget: + __ Push(a3); + ++num_extra_args; + break; + case BuiltinExtraArguments::kTargetAndNewTarget: + __ Push(a1, a3); + num_extra_args += 2; + break; + case BuiltinExtraArguments::kNone: + break; } // JumpToExternalReference expects a0 to contain the number of arguments diff --git a/src/mips64/builtins-mips64.cc b/src/mips64/builtins-mips64.cc index 7fe52b9db5..bf8db9fc64 100644 --- a/src/mips64/builtins-mips64.cc +++ b/src/mips64/builtins-mips64.cc @@ -22,7 +22,8 @@ void Builtins::Generate_Adaptor(MacroAssembler* masm, BuiltinExtraArguments extra_args) { // ----------- S t a t e ------------- // -- a0 : number of arguments excluding receiver - // -- a1 : called function + // -- a1 : target + // -- a3 : new.target // -- sp[0] : last argument // -- ... // -- sp[8 * (argc - 1)] : first argument @@ -32,11 +33,21 @@ void Builtins::Generate_Adaptor(MacroAssembler* masm, // Insert extra arguments. int num_extra_args = 0; - if (extra_args == NEEDS_CALLED_FUNCTION) { - num_extra_args = 1; - __ push(a1); - } else { - DCHECK(extra_args == NO_EXTRA_ARGUMENTS); + switch (extra_args) { + case BuiltinExtraArguments::kTarget: + __ Push(a1); + ++num_extra_args; + break; + case BuiltinExtraArguments::kNewTarget: + __ Push(a3); + ++num_extra_args; + break; + case BuiltinExtraArguments::kTargetAndNewTarget: + __ Push(a1, a3); + num_extra_args += 2; + break; + case BuiltinExtraArguments::kNone: + break; } // JumpToExternalReference expects a0 to contain the number of arguments diff --git a/src/ppc/builtins-ppc.cc b/src/ppc/builtins-ppc.cc index 4e23f38102..8009411343 100644 --- a/src/ppc/builtins-ppc.cc +++ b/src/ppc/builtins-ppc.cc @@ -21,7 +21,8 @@ void Builtins::Generate_Adaptor(MacroAssembler* masm, CFunctionId id, BuiltinExtraArguments extra_args) { // ----------- S t a t e ------------- // -- r3 : number of arguments excluding receiver - // -- r4 : called function + // -- r4 : target + // -- r6 : new.target // -- sp[0] : last argument // -- ... // -- sp[4 * (argc - 1)] : first argument @@ -31,11 +32,21 @@ void Builtins::Generate_Adaptor(MacroAssembler* masm, CFunctionId id, // Insert extra arguments. int num_extra_args = 0; - if (extra_args == NEEDS_CALLED_FUNCTION) { - num_extra_args = 1; - __ push(r4); - } else { - DCHECK(extra_args == NO_EXTRA_ARGUMENTS); + switch (extra_args) { + case BuiltinExtraArguments::kTarget: + __ Push(r4); + ++num_extra_args; + break; + case BuiltinExtraArguments::kNewTarget: + __ Push(r6); + ++num_extra_args; + break; + case BuiltinExtraArguments::kTargetAndNewTarget: + __ Push(r4, r6); + num_extra_args += 2; + break; + case BuiltinExtraArguments::kNone: + break; } // JumpToExternalReference expects r3 to contain the number of arguments diff --git a/src/x64/builtins-x64.cc b/src/x64/builtins-x64.cc index 22153f6d8e..b83840b822 100644 --- a/src/x64/builtins-x64.cc +++ b/src/x64/builtins-x64.cc @@ -21,7 +21,8 @@ void Builtins::Generate_Adaptor(MacroAssembler* masm, BuiltinExtraArguments extra_args) { // ----------- S t a t e ------------- // -- rax : number of arguments excluding receiver - // -- rdi : called function + // -- rdi : target + // -- rdx : new.target // -- rsp[0] : return address // -- rsp[8] : last argument // -- ... @@ -32,13 +33,17 @@ void Builtins::Generate_Adaptor(MacroAssembler* masm, // Insert extra arguments. int num_extra_args = 0; - if (extra_args == NEEDS_CALLED_FUNCTION) { - num_extra_args = 1; + if (extra_args != BuiltinExtraArguments::kNone) { __ PopReturnAddressTo(kScratchRegister); - __ Push(rdi); + if (extra_args & BuiltinExtraArguments::kTarget) { + ++num_extra_args; + __ Push(rdi); + } + if (extra_args & BuiltinExtraArguments::kNewTarget) { + ++num_extra_args; + __ Push(rdx); + } __ PushReturnAddressFrom(kScratchRegister); - } else { - DCHECK(extra_args == NO_EXTRA_ARGUMENTS); } // JumpToExternalReference expects rax to contain the number of arguments diff --git a/src/x87/builtins-x87.cc b/src/x87/builtins-x87.cc index 185a9a62dd..9ee0da85c8 100644 --- a/src/x87/builtins-x87.cc +++ b/src/x87/builtins-x87.cc @@ -22,7 +22,8 @@ void Builtins::Generate_Adaptor(MacroAssembler* masm, BuiltinExtraArguments extra_args) { // ----------- S t a t e ------------- // -- eax : number of arguments excluding receiver - // -- edi : called function + // -- edi : target + // -- edx : new.target // -- esp[0] : return address // -- esp[4] : last argument // -- ... @@ -33,14 +34,17 @@ void Builtins::Generate_Adaptor(MacroAssembler* masm, // Insert extra arguments. int num_extra_args = 0; - if (extra_args == NEEDS_CALLED_FUNCTION) { - num_extra_args = 1; - Register scratch = ebx; - __ pop(scratch); // Save return address. - __ push(edi); - __ push(scratch); // Restore return address. - } else { - DCHECK(extra_args == NO_EXTRA_ARGUMENTS); + if (extra_args != BuiltinExtraArguments::kNone) { + __ PopReturnAddressTo(ecx); + if (extra_args & BuiltinExtraArguments::kTarget) { + ++num_extra_args; + __ Push(edi); + } + if (extra_args & BuiltinExtraArguments::kNewTarget) { + ++num_extra_args; + __ Push(edx); + } + __ PushReturnAddressFrom(ecx); } // JumpToExternalReference expects eax to contain the number of arguments