Revert of Rework CallApi*Stubs. (patchset #5 id:100001 of https://codereview.chromium.org/1748123003/ )
Reason for revert: Breaks Chromium. Original issue's description: > Rework CallApi*Stubs. > > - Eliminate stubs with a variable number of arguments. > (That only worked due to their very limited use. These > stubs' interface descriptors were basically lying > about their number of args, which will fail when used > generically.) > - Fix all CallApi*Stubs' interface descriptors to no > longer lie about their arguments. > - Unify CallApi*Stub, for * in Function, Accessor, > FunctionWithFixedArgs. > (Since these are now all doing the same thing.) > - Rename the unified stub (and interface descriptors) to > *ApiCallback*, since that's really what they're doing. > - Refuse inlining an API callback if its number of > parameters exceeds the supported number of args. > > BUG= > > Committed: https://crrev.com/d238b953a474272c0e3ea22ef6a9b63fa9729340 > Cr-Commit-Position: refs/heads/master@{#34614} TBR=danno@chromium.org,jkummerow@chromium.org,mstarzinger@chromium.org # Skipping CQ checks because original CL landed less than 1 days ago. NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true BUG= Review URL: https://codereview.chromium.org/1775933005 Cr-Commit-Position: refs/heads/master@{#34624}
This commit is contained in:
parent
40a9b8d170
commit
52a741d18e
@ -5418,12 +5418,16 @@ static void CallApiFunctionAndReturn(MacroAssembler* masm,
|
||||
__ jmp(&leave_exit_frame);
|
||||
}
|
||||
|
||||
void CallApiCallbackStub::Generate(MacroAssembler* masm) {
|
||||
static void CallApiFunctionStubHelper(MacroAssembler* masm,
|
||||
const ParameterCount& argc,
|
||||
bool return_first_arg,
|
||||
bool call_data_undefined, bool is_lazy) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- r0 : callee
|
||||
// -- r4 : call_data
|
||||
// -- r2 : holder
|
||||
// -- r1 : api_function_address
|
||||
// -- r3 : number of arguments if argc is a register
|
||||
// -- cp : context
|
||||
// --
|
||||
// -- sp[0] : last argument
|
||||
@ -5449,9 +5453,11 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
|
||||
STATIC_ASSERT(FCA::kHolderIndex == 0);
|
||||
STATIC_ASSERT(FCA::kArgsLength == 7);
|
||||
|
||||
DCHECK(argc.is_immediate() || r3.is(argc.reg()));
|
||||
|
||||
// context save
|
||||
__ push(context);
|
||||
if (!is_lazy()) {
|
||||
if (!is_lazy) {
|
||||
// load context from callee
|
||||
__ ldr(context, FieldMemOperand(callee, JSFunction::kContextOffset));
|
||||
}
|
||||
@ -5463,7 +5469,7 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
|
||||
__ push(call_data);
|
||||
|
||||
Register scratch = call_data;
|
||||
if (!call_data_undefined()) {
|
||||
if (!call_data_undefined) {
|
||||
__ LoadRoot(scratch, Heap::kUndefinedValueRootIndex);
|
||||
}
|
||||
// return value
|
||||
@ -5492,15 +5498,29 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
|
||||
__ add(r0, sp, Operand(1 * kPointerSize));
|
||||
// FunctionCallbackInfo::implicit_args_
|
||||
__ str(scratch, MemOperand(r0, 0 * kPointerSize));
|
||||
// FunctionCallbackInfo::values_
|
||||
__ add(ip, scratch, Operand((FCA::kArgsLength - 1 + argc()) * kPointerSize));
|
||||
__ str(ip, MemOperand(r0, 1 * kPointerSize));
|
||||
// FunctionCallbackInfo::length_ = argc
|
||||
__ mov(ip, Operand(argc()));
|
||||
__ str(ip, MemOperand(r0, 2 * kPointerSize));
|
||||
// FunctionCallbackInfo::is_construct_call_ = 0
|
||||
__ mov(ip, Operand::Zero());
|
||||
__ str(ip, MemOperand(r0, 3 * kPointerSize));
|
||||
if (argc.is_immediate()) {
|
||||
// FunctionCallbackInfo::values_
|
||||
__ add(ip, scratch,
|
||||
Operand((FCA::kArgsLength - 1 + argc.immediate()) * kPointerSize));
|
||||
__ str(ip, MemOperand(r0, 1 * kPointerSize));
|
||||
// FunctionCallbackInfo::length_ = argc
|
||||
__ mov(ip, Operand(argc.immediate()));
|
||||
__ str(ip, MemOperand(r0, 2 * kPointerSize));
|
||||
// FunctionCallbackInfo::is_construct_call_ = 0
|
||||
__ mov(ip, Operand::Zero());
|
||||
__ str(ip, MemOperand(r0, 3 * kPointerSize));
|
||||
} else {
|
||||
// FunctionCallbackInfo::values_
|
||||
__ add(ip, scratch, Operand(argc.reg(), LSL, kPointerSizeLog2));
|
||||
__ add(ip, ip, Operand((FCA::kArgsLength - 1) * kPointerSize));
|
||||
__ str(ip, MemOperand(r0, 1 * kPointerSize));
|
||||
// FunctionCallbackInfo::length_ = argc
|
||||
__ str(argc.reg(), MemOperand(r0, 2 * kPointerSize));
|
||||
// FunctionCallbackInfo::is_construct_call_
|
||||
__ add(argc.reg(), argc.reg(), Operand(FCA::kArgsLength + 1));
|
||||
__ mov(ip, Operand(argc.reg(), LSL, kPointerSizeLog2));
|
||||
__ str(ip, MemOperand(r0, 3 * kPointerSize));
|
||||
}
|
||||
|
||||
ExternalReference thunk_ref =
|
||||
ExternalReference::invoke_function_callback(masm->isolate());
|
||||
@ -5510,7 +5530,7 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
|
||||
fp, (2 + FCA::kContextSaveIndex) * kPointerSize);
|
||||
// Stores return the first js argument
|
||||
int return_value_offset = 0;
|
||||
if (is_store()) {
|
||||
if (return_first_arg) {
|
||||
return_value_offset = 2 + FCA::kArgsLength;
|
||||
} else {
|
||||
return_value_offset = 2 + FCA::kReturnValueOffset;
|
||||
@ -5519,15 +5539,33 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
|
||||
int stack_space = 0;
|
||||
MemOperand is_construct_call_operand = MemOperand(sp, 4 * kPointerSize);
|
||||
MemOperand* stack_space_operand = &is_construct_call_operand;
|
||||
stack_space = argc() + FCA::kArgsLength + 1;
|
||||
stack_space_operand = NULL;
|
||||
|
||||
if (argc.is_immediate()) {
|
||||
stack_space = argc.immediate() + FCA::kArgsLength + 1;
|
||||
stack_space_operand = NULL;
|
||||
}
|
||||
CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, stack_space,
|
||||
stack_space_operand, return_value_operand,
|
||||
&context_restore_operand);
|
||||
}
|
||||
|
||||
|
||||
void CallApiFunctionStub::Generate(MacroAssembler* masm) {
|
||||
bool call_data_undefined = this->call_data_undefined();
|
||||
CallApiFunctionStubHelper(masm, ParameterCount(r3), false,
|
||||
call_data_undefined, false);
|
||||
}
|
||||
|
||||
|
||||
void CallApiAccessorStub::Generate(MacroAssembler* masm) {
|
||||
bool is_store = this->is_store();
|
||||
int argc = this->argc();
|
||||
bool call_data_undefined = this->call_data_undefined();
|
||||
bool is_lazy = this->is_lazy();
|
||||
CallApiFunctionStubHelper(masm, ParameterCount(argc), is_store,
|
||||
call_data_undefined, is_lazy);
|
||||
}
|
||||
|
||||
|
||||
void CallApiGetterStub::Generate(MacroAssembler* masm) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- sp[0] : name
|
||||
|
@ -401,7 +401,25 @@ void ArgumentAdaptorDescriptor::InitializePlatformSpecific(
|
||||
&default_descriptor);
|
||||
}
|
||||
|
||||
void ApiCallbackDescriptorBase::InitializePlatformSpecific(
|
||||
|
||||
void ApiFunctionDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
static PlatformInterfaceDescriptor default_descriptor =
|
||||
PlatformInterfaceDescriptor(CAN_INLINE_TARGET_ADDRESS);
|
||||
|
||||
Register registers[] = {
|
||||
r0, // callee
|
||||
r4, // call_data
|
||||
r2, // holder
|
||||
r1, // api_function_address
|
||||
r3, // actual number of arguments
|
||||
};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers,
|
||||
&default_descriptor);
|
||||
}
|
||||
|
||||
|
||||
void ApiAccessorDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
static PlatformInterfaceDescriptor default_descriptor =
|
||||
PlatformInterfaceDescriptor(CAN_INLINE_TARGET_ADDRESS);
|
||||
|
@ -5799,12 +5799,16 @@ static void CallApiFunctionAndReturn(
|
||||
__ B(&leave_exit_frame);
|
||||
}
|
||||
|
||||
void CallApiCallbackStub::Generate(MacroAssembler* masm) {
|
||||
static void CallApiFunctionStubHelper(MacroAssembler* masm,
|
||||
const ParameterCount& argc,
|
||||
bool return_first_arg,
|
||||
bool call_data_undefined, bool is_lazy) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- x0 : callee
|
||||
// -- x4 : call_data
|
||||
// -- x2 : holder
|
||||
// -- x1 : api_function_address
|
||||
// -- x3 : number of arguments if argc is a register
|
||||
// -- cp : context
|
||||
// --
|
||||
// -- sp[0] : last argument
|
||||
@ -5830,15 +5834,17 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
|
||||
STATIC_ASSERT(FCA::kHolderIndex == 0);
|
||||
STATIC_ASSERT(FCA::kArgsLength == 7);
|
||||
|
||||
DCHECK(argc.is_immediate() || x3.is(argc.reg()));
|
||||
|
||||
// FunctionCallbackArguments: context, callee and call data.
|
||||
__ Push(context, callee, call_data);
|
||||
|
||||
if (!is_lazy()) {
|
||||
if (!is_lazy) {
|
||||
// Load context from callee
|
||||
__ Ldr(context, FieldMemOperand(callee, JSFunction::kContextOffset));
|
||||
}
|
||||
|
||||
if (!call_data_undefined()) {
|
||||
if (!call_data_undefined) {
|
||||
__ LoadRoot(call_data, Heap::kUndefinedValueRootIndex);
|
||||
}
|
||||
Register isolate_reg = x5;
|
||||
@ -5867,13 +5873,26 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
|
||||
// x0 = FunctionCallbackInfo&
|
||||
// Arguments is after the return address.
|
||||
__ Add(x0, masm->StackPointer(), 1 * kPointerSize);
|
||||
// FunctionCallbackInfo::implicit_args_ and FunctionCallbackInfo::values_
|
||||
__ Add(x10, args, Operand((FCA::kArgsLength - 1 + argc()) * kPointerSize));
|
||||
__ Stp(args, x10, MemOperand(x0, 0 * kPointerSize));
|
||||
// FunctionCallbackInfo::length_ = argc and
|
||||
// FunctionCallbackInfo::is_construct_call = 0
|
||||
__ Mov(x10, argc());
|
||||
__ Stp(x10, xzr, MemOperand(x0, 2 * kPointerSize));
|
||||
if (argc.is_immediate()) {
|
||||
// FunctionCallbackInfo::implicit_args_ and FunctionCallbackInfo::values_
|
||||
__ Add(x10, args,
|
||||
Operand((FCA::kArgsLength - 1 + argc.immediate()) * kPointerSize));
|
||||
__ Stp(args, x10, MemOperand(x0, 0 * kPointerSize));
|
||||
// FunctionCallbackInfo::length_ = argc and
|
||||
// FunctionCallbackInfo::is_construct_call = 0
|
||||
__ Mov(x10, argc.immediate());
|
||||
__ Stp(x10, xzr, MemOperand(x0, 2 * kPointerSize));
|
||||
} else {
|
||||
// FunctionCallbackInfo::implicit_args_ and FunctionCallbackInfo::values_
|
||||
__ Add(x10, args, Operand(argc.reg(), LSL, kPointerSizeLog2));
|
||||
__ Add(x10, x10, (FCA::kArgsLength - 1) * kPointerSize);
|
||||
__ Stp(args, x10, MemOperand(x0, 0 * kPointerSize));
|
||||
// FunctionCallbackInfo::length_ = argc and
|
||||
// FunctionCallbackInfo::is_construct_call
|
||||
__ Add(x10, argc.reg(), FCA::kArgsLength + 1);
|
||||
__ Mov(x10, Operand(x10, LSL, kPointerSizeLog2));
|
||||
__ Stp(argc.reg(), x10, MemOperand(x0, 2 * kPointerSize));
|
||||
}
|
||||
|
||||
ExternalReference thunk_ref =
|
||||
ExternalReference::invoke_function_callback(masm->isolate());
|
||||
@ -5883,7 +5902,7 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
|
||||
fp, (2 + FCA::kContextSaveIndex) * kPointerSize);
|
||||
// Stores return the first js argument
|
||||
int return_value_offset = 0;
|
||||
if (is_store()) {
|
||||
if (return_first_arg) {
|
||||
return_value_offset = 2 + FCA::kArgsLength;
|
||||
} else {
|
||||
return_value_offset = 2 + FCA::kReturnValueOffset;
|
||||
@ -5893,8 +5912,10 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
|
||||
MemOperand is_construct_call_operand =
|
||||
MemOperand(masm->StackPointer(), 4 * kPointerSize);
|
||||
MemOperand* stack_space_operand = &is_construct_call_operand;
|
||||
stack_space = argc() + FCA::kArgsLength + 1;
|
||||
stack_space_operand = NULL;
|
||||
if (argc.is_immediate()) {
|
||||
stack_space = argc.immediate() + FCA::kArgsLength + 1;
|
||||
stack_space_operand = NULL;
|
||||
}
|
||||
|
||||
const int spill_offset = 1 + kApiStackSpace;
|
||||
CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, stack_space,
|
||||
@ -5903,6 +5924,23 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
|
||||
}
|
||||
|
||||
|
||||
void CallApiFunctionStub::Generate(MacroAssembler* masm) {
|
||||
bool call_data_undefined = this->call_data_undefined();
|
||||
CallApiFunctionStubHelper(masm, ParameterCount(x3), false,
|
||||
call_data_undefined, false);
|
||||
}
|
||||
|
||||
|
||||
void CallApiAccessorStub::Generate(MacroAssembler* masm) {
|
||||
bool is_store = this->is_store();
|
||||
int argc = this->argc();
|
||||
bool call_data_undefined = this->call_data_undefined();
|
||||
bool is_lazy = this->is_lazy();
|
||||
CallApiFunctionStubHelper(masm, ParameterCount(argc), is_store,
|
||||
call_data_undefined, is_lazy);
|
||||
}
|
||||
|
||||
|
||||
void CallApiGetterStub::Generate(MacroAssembler* masm) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- sp[0] : name
|
||||
|
@ -436,7 +436,25 @@ void ArgumentAdaptorDescriptor::InitializePlatformSpecific(
|
||||
&default_descriptor);
|
||||
}
|
||||
|
||||
void ApiCallbackDescriptorBase::InitializePlatformSpecific(
|
||||
|
||||
void ApiFunctionDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
static PlatformInterfaceDescriptor default_descriptor =
|
||||
PlatformInterfaceDescriptor(CAN_INLINE_TARGET_ADDRESS);
|
||||
|
||||
Register registers[] = {
|
||||
x0, // callee
|
||||
x4, // call_data
|
||||
x2, // holder
|
||||
x1, // api_function_address
|
||||
x3, // actual number of arguments
|
||||
};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers,
|
||||
&default_descriptor);
|
||||
}
|
||||
|
||||
|
||||
void ApiAccessorDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
static PlatformInterfaceDescriptor default_descriptor =
|
||||
PlatformInterfaceDescriptor(CAN_INLINE_TARGET_ADDRESS);
|
||||
|
@ -23,7 +23,8 @@ namespace internal {
|
||||
/* PlatformCodeStubs */ \
|
||||
V(ArrayConstructor) \
|
||||
V(BinaryOpICWithAllocationSite) \
|
||||
V(CallApiCallback) \
|
||||
V(CallApiFunction) \
|
||||
V(CallApiAccessor) \
|
||||
V(CallApiGetter) \
|
||||
V(CallConstruct) \
|
||||
V(CallIC) \
|
||||
@ -1532,36 +1533,48 @@ class StoreGlobalViaContextStub final : public PlatformCodeStub {
|
||||
DEFINE_PLATFORM_CODE_STUB(StoreGlobalViaContext, PlatformCodeStub);
|
||||
};
|
||||
|
||||
class CallApiCallbackStub : public PlatformCodeStub {
|
||||
|
||||
class CallApiFunctionStub : public PlatformCodeStub {
|
||||
public:
|
||||
static const int kArgBits = 3;
|
||||
static const int kArgMax = (1 << kArgBits) - 1;
|
||||
|
||||
// CallApiCallbackStub for regular setters and getters.
|
||||
CallApiCallbackStub(Isolate* isolate, bool is_store, bool call_data_undefined,
|
||||
bool is_lazy)
|
||||
: CallApiCallbackStub(isolate, is_store ? 1 : 0, is_store,
|
||||
call_data_undefined, is_lazy) {}
|
||||
|
||||
// CallApiCallbackStub for callback functions.
|
||||
CallApiCallbackStub(Isolate* isolate, int argc, bool call_data_undefined)
|
||||
: CallApiCallbackStub(isolate, argc, false, call_data_undefined, false) {}
|
||||
|
||||
CallInterfaceDescriptor GetCallInterfaceDescriptor() const override {
|
||||
return ApiCallbackDescriptorBase::ForArgs(isolate(), argc());
|
||||
explicit CallApiFunctionStub(Isolate* isolate, bool call_data_undefined)
|
||||
: PlatformCodeStub(isolate) {
|
||||
minor_key_ = CallDataUndefinedBits::encode(call_data_undefined);
|
||||
}
|
||||
|
||||
private:
|
||||
CallApiCallbackStub(Isolate* isolate, int argc, bool is_store,
|
||||
bool call_data_undefined, bool is_lazy)
|
||||
bool call_data_undefined() const {
|
||||
return CallDataUndefinedBits::decode(minor_key_);
|
||||
}
|
||||
|
||||
class CallDataUndefinedBits : public BitField<bool, 0, 1> {};
|
||||
|
||||
DEFINE_CALL_INTERFACE_DESCRIPTOR(ApiFunction);
|
||||
DEFINE_PLATFORM_CODE_STUB(CallApiFunction, PlatformCodeStub);
|
||||
};
|
||||
|
||||
|
||||
class CallApiAccessorStub : public PlatformCodeStub {
|
||||
public:
|
||||
CallApiAccessorStub(Isolate* isolate, bool is_store, bool call_data_undefined,
|
||||
bool is_lazy)
|
||||
: PlatformCodeStub(isolate) {
|
||||
CHECK(0 <= argc && argc <= kArgMax);
|
||||
minor_key_ = IsStoreBits::encode(is_store) |
|
||||
CallDataUndefinedBits::encode(call_data_undefined) |
|
||||
ArgumentBits::encode(argc) |
|
||||
ArgumentBits::encode(is_store ? 1 : 0) |
|
||||
IsLazyAccessorBits::encode(is_lazy);
|
||||
}
|
||||
|
||||
protected:
|
||||
// For CallApiFunctionWithFixedArgsStub, see below.
|
||||
static const int kArgBits = 3;
|
||||
CallApiAccessorStub(Isolate* isolate, int argc, bool call_data_undefined)
|
||||
: PlatformCodeStub(isolate) {
|
||||
minor_key_ = IsStoreBits::encode(false) |
|
||||
CallDataUndefinedBits::encode(call_data_undefined) |
|
||||
ArgumentBits::encode(argc);
|
||||
}
|
||||
|
||||
private:
|
||||
bool is_store() const { return IsStoreBits::decode(minor_key_); }
|
||||
bool is_lazy() const { return IsLazyAccessorBits::decode(minor_key_); }
|
||||
bool call_data_undefined() const {
|
||||
@ -1574,10 +1587,29 @@ class CallApiCallbackStub : public PlatformCodeStub {
|
||||
class ArgumentBits : public BitField<int, 2, kArgBits> {};
|
||||
class IsLazyAccessorBits : public BitField<bool, 3 + kArgBits, 1> {};
|
||||
|
||||
DEFINE_PLATFORM_CODE_STUB(CallApiCallback, PlatformCodeStub);
|
||||
DEFINE_CALL_INTERFACE_DESCRIPTOR(ApiAccessor);
|
||||
DEFINE_PLATFORM_CODE_STUB(CallApiAccessor, PlatformCodeStub);
|
||||
};
|
||||
|
||||
|
||||
// TODO(dcarney): see if it's possible to remove this later without performance
|
||||
// degradation.
|
||||
// This is not a real stub, but a way of generating the CallApiAccessorStub
|
||||
// (which has the same abi) which makes it clear that it is not an accessor.
|
||||
class CallApiFunctionWithFixedArgsStub : public CallApiAccessorStub {
|
||||
public:
|
||||
static const int kMaxFixedArgs = (1 << kArgBits) - 1;
|
||||
CallApiFunctionWithFixedArgsStub(Isolate* isolate, int argc,
|
||||
bool call_data_undefined)
|
||||
: CallApiAccessorStub(isolate, argc, call_data_undefined) {
|
||||
DCHECK(0 <= argc && argc <= kMaxFixedArgs);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
typedef ApiAccessorDescriptor ApiFunctionWithFixedArgsDescriptor;
|
||||
|
||||
|
||||
class CallApiGetterStub : public PlatformCodeStub {
|
||||
public:
|
||||
explicit CallApiGetterStub(Isolate* isolate) : PlatformCodeStub(isolate) {}
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include "src/compiler/fast-accessor-assembler.h"
|
||||
|
||||
#include "src/base/logging.h"
|
||||
#include "src/code-stubs.h" // For CallApiCallbackStub.
|
||||
#include "src/code-stubs.h" // For CallApiFunctionStub.
|
||||
#include "src/compiler/graph.h"
|
||||
#include "src/compiler/linkage.h"
|
||||
#include "src/compiler/pipeline.h"
|
||||
@ -172,8 +172,7 @@ FastAccessorAssembler::ValueId FastAccessorAssembler::Call(
|
||||
CHECK_EQ(kBuilding, state_);
|
||||
|
||||
// Create API function stub.
|
||||
CallApiCallbackStub stub(assembler_->isolate(), 1, true);
|
||||
DCHECK_EQ(1, stub.GetCallInterfaceDescriptor().GetStackParameterCount());
|
||||
CallApiFunctionStub stub(assembler_->isolate(), true);
|
||||
|
||||
// Wrap the FunctionCallback in an ExternalReference.
|
||||
ApiFunction callback_api_function(FUNCTION_ADDR(callback_function));
|
||||
@ -181,27 +180,30 @@ FastAccessorAssembler::ValueId FastAccessorAssembler::Call(
|
||||
ExternalReference::DIRECT_API_CALL,
|
||||
assembler_->isolate());
|
||||
|
||||
// The stub has 6 parameters.
|
||||
// See: ApiCallbackDescriptorBase::BuildCallInterfaceDescriptorFunctionType
|
||||
// The stub has 5 parameters, and kJSParam (here: 1) parameters to pass
|
||||
// through to the callback.
|
||||
// See: ApiFunctionDescriptor::BuildCallInterfaceDescriptorFunctionType
|
||||
static const int kStackParam = 1;
|
||||
Node* args[] = {
|
||||
// Stub/register parameters:
|
||||
assembler_->Parameter(0), /* receiver (use accessor's) */
|
||||
assembler_->UndefinedConstant(), /* call_data (undefined) */
|
||||
assembler_->NullConstant(), /* holder (null) */
|
||||
assembler_->ExternalConstant(callback), /* API callback function */
|
||||
assembler_->Parameter(0), /* receiver (use accessor's) */
|
||||
assembler_->UndefinedConstant(), /* call_data (undefined) */
|
||||
assembler_->NullConstant(), /* holder (null) */
|
||||
assembler_->ExternalConstant(callback), /* API callback function */
|
||||
assembler_->IntPtrConstant(kStackParam), /* # JS arguments */
|
||||
|
||||
// JS arguments, on stack:
|
||||
// kStackParam stack parameter(s):
|
||||
FromId(arg),
|
||||
|
||||
// Context parameter. (See Linkage::GetStubCallDescriptor.)
|
||||
assembler_->UndefinedConstant()};
|
||||
DCHECK_EQ(arraysize(args),
|
||||
1 + stub.GetCallInterfaceDescriptor().GetParameterCount());
|
||||
CHECK_EQ(5 + kStackParam + 1, arraysize(args));
|
||||
|
||||
Node* call = assembler_->CallN(
|
||||
Linkage::GetStubCallDescriptor(
|
||||
assembler_->isolate(), zone(), stub.GetCallInterfaceDescriptor(),
|
||||
stub.GetStackParameterCount(), CallDescriptor::kNoFlags),
|
||||
kStackParam + stub.GetStackParameterCount(),
|
||||
CallDescriptor::kNoFlags),
|
||||
assembler_->HeapConstant(stub.GetCode()), args);
|
||||
return FromRaw(call);
|
||||
}
|
||||
|
@ -9231,10 +9231,6 @@ bool HOptimizedGraphBuilder::TryInlineApiCall(
|
||||
if (syntactic_tail_call_mode == TailCallMode::kAllow) {
|
||||
return false;
|
||||
}
|
||||
if (argc > CallApiCallbackStub::kArgMax) {
|
||||
return false;
|
||||
}
|
||||
|
||||
CallOptimization optimization(function);
|
||||
if (!optimization.is_simple_api_call()) return false;
|
||||
Handle<Map> holder_map;
|
||||
@ -9330,23 +9326,34 @@ bool HOptimizedGraphBuilder::TryInlineApiCall(
|
||||
api_function_address, nullptr};
|
||||
|
||||
HInstruction* call = nullptr;
|
||||
CHECK(argc <= CallApiCallbackStub::kArgMax);
|
||||
if (!is_function) {
|
||||
CallApiCallbackStub stub(isolate(), is_store, call_data_undefined,
|
||||
CallApiAccessorStub stub(isolate(), is_store, call_data_undefined,
|
||||
!optimization.is_constant_call());
|
||||
Handle<Code> code = stub.GetCode();
|
||||
HConstant* code_value = Add<HConstant>(code);
|
||||
ApiAccessorDescriptor descriptor(isolate());
|
||||
call = New<HCallWithDescriptor>(
|
||||
code_value, argc + 1, stub.GetCallInterfaceDescriptor(),
|
||||
code_value, argc + 1, descriptor,
|
||||
Vector<HValue*>(op_vals, arraysize(op_vals) - 1));
|
||||
} else {
|
||||
CallApiCallbackStub stub(isolate(), argc, call_data_undefined);
|
||||
} else if (argc <= CallApiFunctionWithFixedArgsStub::kMaxFixedArgs) {
|
||||
CallApiFunctionWithFixedArgsStub stub(isolate(), argc, call_data_undefined);
|
||||
Handle<Code> code = stub.GetCode();
|
||||
HConstant* code_value = Add<HConstant>(code);
|
||||
ApiFunctionWithFixedArgsDescriptor descriptor(isolate());
|
||||
call = New<HCallWithDescriptor>(
|
||||
code_value, argc + 1, stub.GetCallInterfaceDescriptor(),
|
||||
code_value, argc + 1, descriptor,
|
||||
Vector<HValue*>(op_vals, arraysize(op_vals) - 1));
|
||||
Drop(1); // Drop function.
|
||||
} else {
|
||||
op_vals[arraysize(op_vals) - 1] = Add<HConstant>(argc);
|
||||
CallApiFunctionStub stub(isolate(), call_data_undefined);
|
||||
Handle<Code> code = stub.GetCode();
|
||||
HConstant* code_value = Add<HConstant>(code);
|
||||
ApiFunctionDescriptor descriptor(isolate());
|
||||
call =
|
||||
New<HCallWithDescriptor>(code_value, argc + 1, descriptor,
|
||||
Vector<HValue*>(op_vals, arraysize(op_vals)));
|
||||
Drop(1); // Drop function.
|
||||
}
|
||||
|
||||
ast_context()->ReturnInstruction(call, ast_id);
|
||||
|
@ -5688,13 +5688,17 @@ static void CallApiFunctionAndReturn(MacroAssembler* masm,
|
||||
__ jmp(&leave_exit_frame);
|
||||
}
|
||||
|
||||
void CallApiCallbackStub::Generate(MacroAssembler* masm) {
|
||||
static void CallApiFunctionStubHelper(MacroAssembler* masm,
|
||||
const ParameterCount& argc,
|
||||
bool return_first_arg,
|
||||
bool call_data_undefined, bool is_lazy) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- edi : callee
|
||||
// -- ebx : call_data
|
||||
// -- ecx : holder
|
||||
// -- edx : api_function_address
|
||||
// -- esi : context
|
||||
// -- eax : number of arguments if argc is a register
|
||||
// --
|
||||
// -- esp[0] : return address
|
||||
// -- esp[4] : last argument
|
||||
@ -5721,9 +5725,17 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
|
||||
STATIC_ASSERT(FCA::kHolderIndex == 0);
|
||||
STATIC_ASSERT(FCA::kArgsLength == 7);
|
||||
|
||||
__ pop(return_address);
|
||||
// context save.
|
||||
__ push(context);
|
||||
DCHECK(argc.is_immediate() || eax.is(argc.reg()));
|
||||
|
||||
if (argc.is_immediate()) {
|
||||
__ pop(return_address);
|
||||
// context save.
|
||||
__ push(context);
|
||||
} else {
|
||||
// pop return address and save context
|
||||
__ xchg(context, Operand(esp, 0));
|
||||
return_address = context;
|
||||
}
|
||||
|
||||
// callee
|
||||
__ push(callee);
|
||||
@ -5732,7 +5744,7 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
|
||||
__ push(call_data);
|
||||
|
||||
Register scratch = call_data;
|
||||
if (!call_data_undefined()) {
|
||||
if (!call_data_undefined) {
|
||||
// return value
|
||||
__ push(Immediate(masm->isolate()->factory()->undefined_value()));
|
||||
// return value default
|
||||
@ -5753,7 +5765,7 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
|
||||
// push return address
|
||||
__ push(return_address);
|
||||
|
||||
if (!is_lazy()) {
|
||||
if (!is_lazy) {
|
||||
// load context from callee
|
||||
__ mov(context, FieldOperand(callee, JSFunction::kContextOffset));
|
||||
}
|
||||
@ -5772,13 +5784,27 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
|
||||
|
||||
// FunctionCallbackInfo::implicit_args_.
|
||||
__ mov(ApiParameterOperand(2), scratch);
|
||||
__ add(scratch, Immediate((argc() + FCA::kArgsLength - 1) * kPointerSize));
|
||||
// FunctionCallbackInfo::values_.
|
||||
__ mov(ApiParameterOperand(3), scratch);
|
||||
// FunctionCallbackInfo::length_.
|
||||
__ Move(ApiParameterOperand(4), Immediate(argc()));
|
||||
// FunctionCallbackInfo::is_construct_call_.
|
||||
__ Move(ApiParameterOperand(5), Immediate(0));
|
||||
if (argc.is_immediate()) {
|
||||
__ add(scratch,
|
||||
Immediate((argc.immediate() + FCA::kArgsLength - 1) * kPointerSize));
|
||||
// FunctionCallbackInfo::values_.
|
||||
__ mov(ApiParameterOperand(3), scratch);
|
||||
// FunctionCallbackInfo::length_.
|
||||
__ Move(ApiParameterOperand(4), Immediate(argc.immediate()));
|
||||
// FunctionCallbackInfo::is_construct_call_.
|
||||
__ Move(ApiParameterOperand(5), Immediate(0));
|
||||
} else {
|
||||
__ lea(scratch, Operand(scratch, argc.reg(), times_pointer_size,
|
||||
(FCA::kArgsLength - 1) * kPointerSize));
|
||||
// FunctionCallbackInfo::values_.
|
||||
__ mov(ApiParameterOperand(3), scratch);
|
||||
// FunctionCallbackInfo::length_.
|
||||
__ mov(ApiParameterOperand(4), argc.reg());
|
||||
// FunctionCallbackInfo::is_construct_call_.
|
||||
__ lea(argc.reg(), Operand(argc.reg(), times_pointer_size,
|
||||
(FCA::kArgsLength + 1) * kPointerSize));
|
||||
__ mov(ApiParameterOperand(5), argc.reg());
|
||||
}
|
||||
|
||||
// v8::InvocationCallback's argument.
|
||||
__ lea(scratch, ApiParameterOperand(2));
|
||||
@ -5791,7 +5817,7 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
|
||||
(2 + FCA::kContextSaveIndex) * kPointerSize);
|
||||
// Stores return the first js argument
|
||||
int return_value_offset = 0;
|
||||
if (is_store()) {
|
||||
if (return_first_arg) {
|
||||
return_value_offset = 2 + FCA::kArgsLength;
|
||||
} else {
|
||||
return_value_offset = 2 + FCA::kReturnValueOffset;
|
||||
@ -5800,8 +5826,10 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
|
||||
int stack_space = 0;
|
||||
Operand is_construct_call_operand = ApiParameterOperand(5);
|
||||
Operand* stack_space_operand = &is_construct_call_operand;
|
||||
stack_space = argc() + FCA::kArgsLength + 1;
|
||||
stack_space_operand = nullptr;
|
||||
if (argc.is_immediate()) {
|
||||
stack_space = argc.immediate() + FCA::kArgsLength + 1;
|
||||
stack_space_operand = nullptr;
|
||||
}
|
||||
CallApiFunctionAndReturn(masm, api_function_address, thunk_ref,
|
||||
ApiParameterOperand(1), stack_space,
|
||||
stack_space_operand, return_value_operand,
|
||||
@ -5809,6 +5837,23 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
|
||||
}
|
||||
|
||||
|
||||
void CallApiFunctionStub::Generate(MacroAssembler* masm) {
|
||||
bool call_data_undefined = this->call_data_undefined();
|
||||
CallApiFunctionStubHelper(masm, ParameterCount(eax), false,
|
||||
call_data_undefined, false);
|
||||
}
|
||||
|
||||
|
||||
void CallApiAccessorStub::Generate(MacroAssembler* masm) {
|
||||
bool is_store = this->is_store();
|
||||
int argc = this->argc();
|
||||
bool call_data_undefined = this->call_data_undefined();
|
||||
bool is_lazy = this->is_lazy();
|
||||
CallApiFunctionStubHelper(masm, ParameterCount(argc), is_store,
|
||||
call_data_undefined, is_lazy);
|
||||
}
|
||||
|
||||
|
||||
void CallApiGetterStub::Generate(MacroAssembler* masm) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- esp[0] : return address
|
||||
|
@ -390,7 +390,21 @@ void ArgumentAdaptorDescriptor::InitializePlatformSpecific(
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void ApiCallbackDescriptorBase::InitializePlatformSpecific(
|
||||
|
||||
void ApiFunctionDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
edi, // callee
|
||||
ebx, // call_data
|
||||
ecx, // holder
|
||||
edx, // api_function_address
|
||||
eax, // actual number of arguments
|
||||
};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
|
||||
void ApiAccessorDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
edi, // callee
|
||||
|
@ -253,7 +253,7 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
|
||||
}
|
||||
DCHECK(optimization.is_simple_api_call());
|
||||
|
||||
// Abi for CallApiCallbackStub.
|
||||
// Abi for CallApiFunctionStub.
|
||||
Register callee = r0;
|
||||
Register data = r4;
|
||||
Register holder = r2;
|
||||
@ -322,7 +322,7 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
|
||||
__ mov(api_function_address, Operand(ref));
|
||||
|
||||
// Jump to stub.
|
||||
CallApiCallbackStub stub(isolate, is_store, call_data_undefined,
|
||||
CallApiAccessorStub stub(isolate, is_store, call_data_undefined,
|
||||
!optimization.is_constant_call());
|
||||
__ TailCallStub(&stub);
|
||||
}
|
||||
|
@ -160,7 +160,7 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
|
||||
|
||||
DCHECK(optimization.is_simple_api_call());
|
||||
|
||||
// Abi for CallApiCallbackStub.
|
||||
// Abi for CallApiFunctionStub.
|
||||
Register callee = x0;
|
||||
Register data = x4;
|
||||
Register holder = x2;
|
||||
@ -229,7 +229,7 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
|
||||
__ Mov(api_function_address, ref);
|
||||
|
||||
// Jump to stub.
|
||||
CallApiCallbackStub stub(isolate, is_store, call_data_undefined,
|
||||
CallApiAccessorStub stub(isolate, is_store, call_data_undefined,
|
||||
!optimization.is_constant_call());
|
||||
__ TailCallStub(&stub);
|
||||
}
|
||||
|
@ -161,7 +161,7 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
|
||||
// Stack now matches JSFunction abi.
|
||||
DCHECK(optimization.is_simple_api_call());
|
||||
|
||||
// Abi for CallApiCallbackStub.
|
||||
// Abi for CallApiFunctionStub.
|
||||
Register callee = edi;
|
||||
Register data = ebx;
|
||||
Register holder = ecx;
|
||||
@ -223,7 +223,7 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
|
||||
__ mov(api_function_address, Immediate(function_address));
|
||||
|
||||
// Jump to stub.
|
||||
CallApiCallbackStub stub(isolate, is_store, call_data_undefined,
|
||||
CallApiAccessorStub stub(isolate, is_store, call_data_undefined,
|
||||
!optimization.is_constant_call());
|
||||
__ TailCallStub(&stub);
|
||||
}
|
||||
|
@ -242,7 +242,7 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
|
||||
}
|
||||
DCHECK(optimization.is_simple_api_call());
|
||||
|
||||
// Abi for CallApiCallbackStub.
|
||||
// Abi for CallApiFunctionStub.
|
||||
Register callee = a0;
|
||||
Register data = t0;
|
||||
Register holder = a2;
|
||||
@ -309,7 +309,7 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
|
||||
__ li(api_function_address, Operand(ref));
|
||||
|
||||
// Jump to stub.
|
||||
CallApiCallbackStub stub(isolate, is_store, call_data_undefined,
|
||||
CallApiAccessorStub stub(isolate, is_store, call_data_undefined,
|
||||
!optimization.is_constant_call());
|
||||
__ TailCallStub(&stub);
|
||||
}
|
||||
|
@ -242,7 +242,7 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
|
||||
}
|
||||
DCHECK(optimization.is_simple_api_call());
|
||||
|
||||
// Abi for CallApiCallbackStub.
|
||||
// Abi for CallApiFunctionStub.
|
||||
Register callee = a0;
|
||||
Register data = a4;
|
||||
Register holder = a2;
|
||||
@ -309,7 +309,7 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
|
||||
__ li(api_function_address, Operand(ref));
|
||||
|
||||
// Jump to stub.
|
||||
CallApiCallbackStub stub(isolate, is_store, call_data_undefined,
|
||||
CallApiAccessorStub stub(isolate, is_store, call_data_undefined,
|
||||
!optimization.is_constant_call());
|
||||
__ TailCallStub(&stub);
|
||||
}
|
||||
|
@ -246,7 +246,7 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
|
||||
}
|
||||
DCHECK(optimization.is_simple_api_call());
|
||||
|
||||
// Abi for CallApiCallbackStub.
|
||||
// Abi for CallApiFunctionStub.
|
||||
Register callee = r3;
|
||||
Register data = r7;
|
||||
Register holder = r5;
|
||||
@ -315,7 +315,7 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
|
||||
__ mov(api_function_address, Operand(ref));
|
||||
|
||||
// Jump to stub.
|
||||
CallApiCallbackStub stub(isolate, is_store, call_data_undefined,
|
||||
CallApiAccessorStub stub(isolate, is_store, call_data_undefined,
|
||||
!optimization.is_constant_call());
|
||||
__ TailCallStub(&stub);
|
||||
}
|
||||
|
@ -231,7 +231,7 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
|
||||
}
|
||||
DCHECK(optimization.is_simple_api_call());
|
||||
|
||||
// Abi for CallApiCallbackStub.
|
||||
// Abi for CallApiFunctionStub.
|
||||
Register callee = r2;
|
||||
Register data = r6;
|
||||
Register holder = r4;
|
||||
@ -300,7 +300,7 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
|
||||
__ mov(api_function_address, Operand(ref));
|
||||
|
||||
// Jump to stub.
|
||||
CallApiCallbackStub stub(isolate, is_store, call_data_undefined,
|
||||
CallApiAccessorStub stub(isolate, is_store, call_data_undefined,
|
||||
!optimization.is_constant_call());
|
||||
__ TailCallStub(&stub);
|
||||
}
|
||||
|
@ -142,7 +142,7 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
|
||||
__ PushReturnAddressFrom(scratch);
|
||||
// Stack now matches JSFunction abi.
|
||||
|
||||
// Abi for CallApiCallbackStub.
|
||||
// Abi for CallApiFunctionStub.
|
||||
Register callee = rdi;
|
||||
Register data = rbx;
|
||||
Register holder = rcx;
|
||||
@ -209,7 +209,7 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
|
||||
RelocInfo::EXTERNAL_REFERENCE);
|
||||
|
||||
// Jump to stub.
|
||||
CallApiCallbackStub stub(isolate, is_store, call_data_undefined,
|
||||
CallApiAccessorStub stub(isolate, is_store, call_data_undefined,
|
||||
!optimization.is_constant_call());
|
||||
__ TailCallStub(&stub);
|
||||
}
|
||||
|
@ -158,7 +158,7 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
|
||||
// Stack now matches JSFunction abi.
|
||||
DCHECK(optimization.is_simple_api_call());
|
||||
|
||||
// Abi for CallApiCallbackStub.
|
||||
// Abi for CallApiFunctionStub.
|
||||
Register callee = edi;
|
||||
Register data = ebx;
|
||||
Register holder = ecx;
|
||||
@ -220,7 +220,7 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
|
||||
__ mov(api_function_address, Immediate(function_address));
|
||||
|
||||
// Jump to stub.
|
||||
CallApiCallbackStub stub(isolate, is_store, call_data_undefined,
|
||||
CallApiAccessorStub stub(isolate, is_store, call_data_undefined,
|
||||
!optimization.is_constant_call());
|
||||
__ TailCallStub(&stub);
|
||||
}
|
||||
|
@ -494,45 +494,28 @@ ArgumentAdaptorDescriptor::BuildCallInterfaceDescriptorFunctionType(
|
||||
return function;
|
||||
}
|
||||
|
||||
CallInterfaceDescriptor ApiCallbackDescriptorBase::ForArgs(Isolate* isolate,
|
||||
int argc) {
|
||||
switch (argc) {
|
||||
case 0:
|
||||
return ApiCallbackWith0ArgsDescriptor(isolate);
|
||||
case 1:
|
||||
return ApiCallbackWith1ArgsDescriptor(isolate);
|
||||
case 2:
|
||||
return ApiCallbackWith2ArgsDescriptor(isolate);
|
||||
case 3:
|
||||
return ApiCallbackWith3ArgsDescriptor(isolate);
|
||||
case 4:
|
||||
return ApiCallbackWith4ArgsDescriptor(isolate);
|
||||
case 5:
|
||||
return ApiCallbackWith5ArgsDescriptor(isolate);
|
||||
case 6:
|
||||
return ApiCallbackWith6ArgsDescriptor(isolate);
|
||||
case 7:
|
||||
return ApiCallbackWith7ArgsDescriptor(isolate);
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return VoidDescriptor(isolate);
|
||||
}
|
||||
}
|
||||
|
||||
FunctionType*
|
||||
ApiCallbackDescriptorBase::BuildCallInterfaceDescriptorFunctionTypeWithArg(
|
||||
Isolate* isolate, int parameter_count, int argc) {
|
||||
FunctionType* ApiFunctionDescriptor::BuildCallInterfaceDescriptorFunctionType(
|
||||
Isolate* isolate, int paramater_count) {
|
||||
Zone* zone = isolate->interface_descriptor_zone();
|
||||
FunctionType* function =
|
||||
Type::Function(AnyTagged(zone), Type::Undefined(), 4 + argc, zone)
|
||||
->AsFunction();
|
||||
Type::Function(AnyTagged(zone), Type::Undefined(), 5, zone)->AsFunction();
|
||||
function->InitParameter(0, AnyTagged(zone)); // callee
|
||||
function->InitParameter(1, AnyTagged(zone)); // call_data
|
||||
function->InitParameter(2, AnyTagged(zone)); // holder
|
||||
function->InitParameter(3, ExternalPointer(zone)); // api_function_address
|
||||
function->InitParameter(4, UntaggedIntegral32(zone)); // actual #arguments
|
||||
return function;
|
||||
}
|
||||
|
||||
FunctionType* ApiAccessorDescriptor::BuildCallInterfaceDescriptorFunctionType(
|
||||
Isolate* isolate, int paramater_count) {
|
||||
Zone* zone = isolate->interface_descriptor_zone();
|
||||
FunctionType* function =
|
||||
Type::Function(AnyTagged(zone), Type::Undefined(), 4, zone)->AsFunction();
|
||||
function->InitParameter(0, AnyTagged(zone)); // callee
|
||||
function->InitParameter(1, AnyTagged(zone)); // call_data
|
||||
function->InitParameter(2, AnyTagged(zone)); // holder
|
||||
function->InitParameter(3, ExternalPointer(zone)); // api_function_address
|
||||
for (int i = 0; i < argc; i++) {
|
||||
function->InitParameter(i, AnyTagged(zone));
|
||||
}
|
||||
return function;
|
||||
}
|
||||
|
||||
|
@ -67,14 +67,8 @@ class PlatformInterfaceDescriptor;
|
||||
V(Named) \
|
||||
V(CallHandler) \
|
||||
V(ArgumentAdaptor) \
|
||||
V(ApiCallbackWith0Args) \
|
||||
V(ApiCallbackWith1Args) \
|
||||
V(ApiCallbackWith2Args) \
|
||||
V(ApiCallbackWith3Args) \
|
||||
V(ApiCallbackWith4Args) \
|
||||
V(ApiCallbackWith5Args) \
|
||||
V(ApiCallbackWith6Args) \
|
||||
V(ApiCallbackWith7Args) \
|
||||
V(ApiFunction) \
|
||||
V(ApiAccessor) \
|
||||
V(ApiGetter) \
|
||||
V(LoadGlobalViaContext) \
|
||||
V(StoreGlobalViaContext) \
|
||||
@ -205,7 +199,6 @@ class CallInterfaceDescriptor {
|
||||
void Initialize(Isolate* isolate, CallDescriptors::Key key) {
|
||||
if (!data()->IsInitialized()) {
|
||||
CallInterfaceDescriptorData* d = isolate->call_descriptor_data(key);
|
||||
DCHECK(d == data()); // d should be a modifiable pointer to data().
|
||||
InitializePlatformSpecific(d);
|
||||
FunctionType* function_type = BuildCallInterfaceDescriptorFunctionType(
|
||||
isolate, d->register_param_count());
|
||||
@ -217,20 +210,18 @@ class CallInterfaceDescriptor {
|
||||
const CallInterfaceDescriptorData* data_;
|
||||
};
|
||||
|
||||
#define DECLARE_DESCRIPTOR_WITH_BASE(name, base) \
|
||||
public: \
|
||||
explicit name(Isolate* isolate) : base(isolate, key()) { \
|
||||
Initialize(isolate, key()); \
|
||||
} \
|
||||
static inline CallDescriptors::Key key();
|
||||
|
||||
#define DECLARE_DESCRIPTOR(name, base) \
|
||||
DECLARE_DESCRIPTOR_WITH_BASE(name, base) \
|
||||
explicit name(Isolate* isolate) : base(isolate, key()) { \
|
||||
Initialize(isolate, key()); \
|
||||
} \
|
||||
\
|
||||
protected: \
|
||||
void InitializePlatformSpecific(CallInterfaceDescriptorData* data) override; \
|
||||
name(Isolate* isolate, CallDescriptors::Key key) : base(isolate, key) {} \
|
||||
\
|
||||
public:
|
||||
public: \
|
||||
static inline CallDescriptors::Key key();
|
||||
|
||||
#define DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(name, base) \
|
||||
DECLARE_DESCRIPTOR(name, base) \
|
||||
@ -240,17 +231,6 @@ class CallInterfaceDescriptor {
|
||||
\
|
||||
public:
|
||||
|
||||
#define DECLARE_DESCRIPTOR_WITH_BASE_AND_FUNCTION_TYPE_ARG(name, base, arg) \
|
||||
DECLARE_DESCRIPTOR_WITH_BASE(name, base) \
|
||||
protected: \
|
||||
FunctionType* BuildCallInterfaceDescriptorFunctionType( \
|
||||
Isolate* isolate, int register_param_count) override { \
|
||||
return BuildCallInterfaceDescriptorFunctionTypeWithArg( \
|
||||
isolate, register_param_count, arg); \
|
||||
} \
|
||||
\
|
||||
public:
|
||||
|
||||
class VoidDescriptor : public CallInterfaceDescriptor {
|
||||
public:
|
||||
DECLARE_DESCRIPTOR(VoidDescriptor, CallInterfaceDescriptor)
|
||||
@ -709,75 +689,18 @@ class ArgumentAdaptorDescriptor : public CallInterfaceDescriptor {
|
||||
CallInterfaceDescriptor)
|
||||
};
|
||||
|
||||
// The ApiCallback*Descriptors have a lot of boilerplate. The superclass
|
||||
// ApiCallbackDescriptorBase contains all the logic, and the
|
||||
// ApiCallbackWith*ArgsDescriptor merely instantiate these with a
|
||||
// parameter for the number of args.
|
||||
//
|
||||
// The base class is not meant to be instantiated directly and has no
|
||||
// public constructors to ensure this is so.
|
||||
//
|
||||
// The simplest usage for all the ApiCallback*Descriptors is probably
|
||||
// ApiCallbackDescriptorBase::ForArgs(isolate, argc)
|
||||
//
|
||||
class ApiCallbackDescriptorBase : public CallInterfaceDescriptor {
|
||||
public:
|
||||
static CallInterfaceDescriptor ForArgs(Isolate* isolate, int argc);
|
||||
|
||||
protected:
|
||||
ApiCallbackDescriptorBase(Isolate* isolate, CallDescriptors::Key key)
|
||||
: CallInterfaceDescriptor(isolate, key) {}
|
||||
void InitializePlatformSpecific(CallInterfaceDescriptorData* data) override;
|
||||
FunctionType* BuildCallInterfaceDescriptorFunctionTypeWithArg(
|
||||
Isolate* isolate, int parameter_count, int argc);
|
||||
class ApiFunctionDescriptor : public CallInterfaceDescriptor {
|
||||
public:
|
||||
DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(ApiFunctionDescriptor,
|
||||
CallInterfaceDescriptor)
|
||||
};
|
||||
|
||||
class ApiCallbackWith0ArgsDescriptor : public ApiCallbackDescriptorBase {
|
||||
public:
|
||||
DECLARE_DESCRIPTOR_WITH_BASE_AND_FUNCTION_TYPE_ARG(
|
||||
ApiCallbackWith0ArgsDescriptor, ApiCallbackDescriptorBase, 0)
|
||||
};
|
||||
|
||||
class ApiCallbackWith1ArgsDescriptor : public ApiCallbackDescriptorBase {
|
||||
class ApiAccessorDescriptor : public CallInterfaceDescriptor {
|
||||
public:
|
||||
DECLARE_DESCRIPTOR_WITH_BASE_AND_FUNCTION_TYPE_ARG(
|
||||
ApiCallbackWith1ArgsDescriptor, ApiCallbackDescriptorBase, 1)
|
||||
};
|
||||
|
||||
class ApiCallbackWith2ArgsDescriptor : public ApiCallbackDescriptorBase {
|
||||
public:
|
||||
DECLARE_DESCRIPTOR_WITH_BASE_AND_FUNCTION_TYPE_ARG(
|
||||
ApiCallbackWith2ArgsDescriptor, ApiCallbackDescriptorBase, 2)
|
||||
};
|
||||
|
||||
class ApiCallbackWith3ArgsDescriptor : public ApiCallbackDescriptorBase {
|
||||
public:
|
||||
DECLARE_DESCRIPTOR_WITH_BASE_AND_FUNCTION_TYPE_ARG(
|
||||
ApiCallbackWith3ArgsDescriptor, ApiCallbackDescriptorBase, 3)
|
||||
};
|
||||
|
||||
class ApiCallbackWith4ArgsDescriptor : public ApiCallbackDescriptorBase {
|
||||
public:
|
||||
DECLARE_DESCRIPTOR_WITH_BASE_AND_FUNCTION_TYPE_ARG(
|
||||
ApiCallbackWith4ArgsDescriptor, ApiCallbackDescriptorBase, 4)
|
||||
};
|
||||
|
||||
class ApiCallbackWith5ArgsDescriptor : public ApiCallbackDescriptorBase {
|
||||
public:
|
||||
DECLARE_DESCRIPTOR_WITH_BASE_AND_FUNCTION_TYPE_ARG(
|
||||
ApiCallbackWith5ArgsDescriptor, ApiCallbackDescriptorBase, 5)
|
||||
};
|
||||
|
||||
class ApiCallbackWith6ArgsDescriptor : public ApiCallbackDescriptorBase {
|
||||
public:
|
||||
DECLARE_DESCRIPTOR_WITH_BASE_AND_FUNCTION_TYPE_ARG(
|
||||
ApiCallbackWith6ArgsDescriptor, ApiCallbackDescriptorBase, 6)
|
||||
};
|
||||
|
||||
class ApiCallbackWith7ArgsDescriptor : public ApiCallbackDescriptorBase {
|
||||
public:
|
||||
DECLARE_DESCRIPTOR_WITH_BASE_AND_FUNCTION_TYPE_ARG(
|
||||
ApiCallbackWith7ArgsDescriptor, ApiCallbackDescriptorBase, 7)
|
||||
DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(ApiAccessorDescriptor,
|
||||
CallInterfaceDescriptor)
|
||||
};
|
||||
|
||||
|
||||
@ -821,7 +744,7 @@ class GrowArrayElementsDescriptor : public CallInterfaceDescriptor {
|
||||
static const Register KeyRegister();
|
||||
};
|
||||
|
||||
class InterpreterDispatchDescriptor : public CallInterfaceDescriptor {
|
||||
class InterpreterDispatchDescriptor : public CallInterfaceDescriptor {
|
||||
public:
|
||||
DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(InterpreterDispatchDescriptor,
|
||||
CallInterfaceDescriptor)
|
||||
@ -854,10 +777,8 @@ class InterpreterCEntryDescriptor : public CallInterfaceDescriptor {
|
||||
DECLARE_DESCRIPTOR(InterpreterCEntryDescriptor, CallInterfaceDescriptor)
|
||||
};
|
||||
|
||||
#undef DECLARE_DESCRIPTOR_WITH_BASE
|
||||
#undef DECLARE_DESCRIPTOR
|
||||
#undef DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE
|
||||
#undef DECLARE_DESCRIPTOR_WITH_BASE_AND_FUNCTION_TYPE_ARG
|
||||
|
||||
|
||||
// We define the association between CallDescriptors::Key and the specialized
|
||||
// descriptor here to reduce boilerplate and mistakes.
|
||||
|
@ -5604,12 +5604,16 @@ static void CallApiFunctionAndReturn(
|
||||
__ jmp(&leave_exit_frame);
|
||||
}
|
||||
|
||||
void CallApiCallbackStub::Generate(MacroAssembler* masm) {
|
||||
static void CallApiFunctionStubHelper(MacroAssembler* masm,
|
||||
const ParameterCount& argc,
|
||||
bool return_first_arg,
|
||||
bool call_data_undefined, bool is_lazy) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- a0 : callee
|
||||
// -- t0 : call_data
|
||||
// -- a2 : holder
|
||||
// -- a1 : api_function_address
|
||||
// -- a3 : number of arguments if argc is a register
|
||||
// -- cp : context
|
||||
// --
|
||||
// -- sp[0] : last argument
|
||||
@ -5635,15 +5639,17 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
|
||||
STATIC_ASSERT(FCA::kHolderIndex == 0);
|
||||
STATIC_ASSERT(FCA::kArgsLength == 7);
|
||||
|
||||
DCHECK(argc.is_immediate() || a3.is(argc.reg()));
|
||||
|
||||
// Save context, callee and call data.
|
||||
__ Push(context, callee, call_data);
|
||||
if (!is_lazy()) {
|
||||
if (!is_lazy) {
|
||||
// Load context from callee.
|
||||
__ lw(context, FieldMemOperand(callee, JSFunction::kContextOffset));
|
||||
}
|
||||
|
||||
Register scratch = call_data;
|
||||
if (!call_data_undefined()) {
|
||||
if (!call_data_undefined) {
|
||||
__ LoadRoot(scratch, Heap::kUndefinedValueRootIndex);
|
||||
}
|
||||
// Push return value and default return value.
|
||||
@ -5668,14 +5674,29 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
|
||||
__ Addu(a0, sp, Operand(1 * kPointerSize));
|
||||
// FunctionCallbackInfo::implicit_args_
|
||||
__ sw(scratch, MemOperand(a0, 0 * kPointerSize));
|
||||
// FunctionCallbackInfo::values_
|
||||
__ Addu(at, scratch, Operand((FCA::kArgsLength - 1 + argc()) * kPointerSize));
|
||||
__ sw(at, MemOperand(a0, 1 * kPointerSize));
|
||||
// FunctionCallbackInfo::length_ = argc
|
||||
__ li(at, Operand(argc()));
|
||||
__ sw(at, MemOperand(a0, 2 * kPointerSize));
|
||||
// FunctionCallbackInfo::is_construct_call_ = 0
|
||||
__ sw(zero_reg, MemOperand(a0, 3 * kPointerSize));
|
||||
if (argc.is_immediate()) {
|
||||
// FunctionCallbackInfo::values_
|
||||
__ Addu(at, scratch,
|
||||
Operand((FCA::kArgsLength - 1 + argc.immediate()) * kPointerSize));
|
||||
__ sw(at, MemOperand(a0, 1 * kPointerSize));
|
||||
// FunctionCallbackInfo::length_ = argc
|
||||
__ li(at, Operand(argc.immediate()));
|
||||
__ sw(at, MemOperand(a0, 2 * kPointerSize));
|
||||
// FunctionCallbackInfo::is_construct_call_ = 0
|
||||
__ sw(zero_reg, MemOperand(a0, 3 * kPointerSize));
|
||||
} else {
|
||||
// FunctionCallbackInfo::values_
|
||||
__ sll(at, argc.reg(), kPointerSizeLog2);
|
||||
__ Addu(at, at, scratch);
|
||||
__ Addu(at, at, Operand((FCA::kArgsLength - 1) * kPointerSize));
|
||||
__ sw(at, MemOperand(a0, 1 * kPointerSize));
|
||||
// FunctionCallbackInfo::length_ = argc
|
||||
__ sw(argc.reg(), MemOperand(a0, 2 * kPointerSize));
|
||||
// FunctionCallbackInfo::is_construct_call_
|
||||
__ Addu(argc.reg(), argc.reg(), Operand(FCA::kArgsLength + 1));
|
||||
__ sll(at, argc.reg(), kPointerSizeLog2);
|
||||
__ sw(at, MemOperand(a0, 3 * kPointerSize));
|
||||
}
|
||||
|
||||
ExternalReference thunk_ref =
|
||||
ExternalReference::invoke_function_callback(masm->isolate());
|
||||
@ -5685,7 +5706,7 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
|
||||
fp, (2 + FCA::kContextSaveIndex) * kPointerSize);
|
||||
// Stores return the first js argument.
|
||||
int return_value_offset = 0;
|
||||
if (is_store()) {
|
||||
if (return_first_arg) {
|
||||
return_value_offset = 2 + FCA::kArgsLength;
|
||||
} else {
|
||||
return_value_offset = 2 + FCA::kReturnValueOffset;
|
||||
@ -5693,14 +5714,33 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
|
||||
MemOperand return_value_operand(fp, return_value_offset * kPointerSize);
|
||||
int stack_space = 0;
|
||||
int32_t stack_space_offset = 4 * kPointerSize;
|
||||
stack_space = argc() + FCA::kArgsLength + 1;
|
||||
stack_space_offset = kInvalidStackOffset;
|
||||
if (argc.is_immediate()) {
|
||||
stack_space = argc.immediate() + FCA::kArgsLength + 1;
|
||||
stack_space_offset = kInvalidStackOffset;
|
||||
}
|
||||
CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, stack_space,
|
||||
stack_space_offset, return_value_operand,
|
||||
&context_restore_operand);
|
||||
}
|
||||
|
||||
|
||||
void CallApiFunctionStub::Generate(MacroAssembler* masm) {
|
||||
bool call_data_undefined = this->call_data_undefined();
|
||||
CallApiFunctionStubHelper(masm, ParameterCount(a3), false,
|
||||
call_data_undefined, false);
|
||||
}
|
||||
|
||||
|
||||
void CallApiAccessorStub::Generate(MacroAssembler* masm) {
|
||||
bool is_store = this->is_store();
|
||||
int argc = this->argc();
|
||||
bool call_data_undefined = this->call_data_undefined();
|
||||
bool is_lazy = this->is_lazy();
|
||||
CallApiFunctionStubHelper(masm, ParameterCount(argc), is_store,
|
||||
call_data_undefined, is_lazy);
|
||||
}
|
||||
|
||||
|
||||
void CallApiGetterStub::Generate(MacroAssembler* masm) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- sp[0] : name
|
||||
|
@ -384,7 +384,21 @@ void ArgumentAdaptorDescriptor::InitializePlatformSpecific(
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void ApiCallbackDescriptorBase::InitializePlatformSpecific(
|
||||
|
||||
void ApiFunctionDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
a0, // callee
|
||||
t0, // call_data
|
||||
a2, // holder
|
||||
a1, // api_function_address
|
||||
a3, // actual number of arguments
|
||||
};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
|
||||
void ApiAccessorDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
a0, // callee
|
||||
|
@ -5628,12 +5628,16 @@ static void CallApiFunctionAndReturn(
|
||||
__ jmp(&leave_exit_frame);
|
||||
}
|
||||
|
||||
void CallApiCallbackStub::Generate(MacroAssembler* masm) {
|
||||
static void CallApiFunctionStubHelper(MacroAssembler* masm,
|
||||
const ParameterCount& argc,
|
||||
bool return_first_arg,
|
||||
bool call_data_undefined, bool is_lazy) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- a0 : callee
|
||||
// -- a4 : call_data
|
||||
// -- a2 : holder
|
||||
// -- a1 : api_function_address
|
||||
// -- a3 : number of arguments if argc is a register
|
||||
// -- cp : context
|
||||
// --
|
||||
// -- sp[0] : last argument
|
||||
@ -5659,15 +5663,17 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
|
||||
STATIC_ASSERT(FCA::kHolderIndex == 0);
|
||||
STATIC_ASSERT(FCA::kArgsLength == 7);
|
||||
|
||||
DCHECK(argc.is_immediate() || a3.is(argc.reg()));
|
||||
|
||||
// Save context, callee and call data.
|
||||
__ Push(context, callee, call_data);
|
||||
if (!is_lazy()) {
|
||||
if (!is_lazy) {
|
||||
// Load context from callee.
|
||||
__ ld(context, FieldMemOperand(callee, JSFunction::kContextOffset));
|
||||
}
|
||||
|
||||
Register scratch = call_data;
|
||||
if (!call_data_undefined()) {
|
||||
if (!call_data_undefined) {
|
||||
__ LoadRoot(scratch, Heap::kUndefinedValueRootIndex);
|
||||
}
|
||||
// Push return value and default return value.
|
||||
@ -5692,17 +5698,33 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
|
||||
__ Daddu(a0, sp, Operand(1 * kPointerSize));
|
||||
// FunctionCallbackInfo::implicit_args_
|
||||
__ sd(scratch, MemOperand(a0, 0 * kPointerSize));
|
||||
// FunctionCallbackInfo::values_
|
||||
__ Daddu(at, scratch,
|
||||
Operand((FCA::kArgsLength - 1 + argc()) * kPointerSize));
|
||||
__ sd(at, MemOperand(a0, 1 * kPointerSize));
|
||||
// FunctionCallbackInfo::length_ = argc
|
||||
// Stored as int field, 32-bit integers within struct on stack always left
|
||||
// justified by n64 ABI.
|
||||
__ li(at, Operand(argc()));
|
||||
__ sw(at, MemOperand(a0, 2 * kPointerSize));
|
||||
// FunctionCallbackInfo::is_construct_call_ = 0
|
||||
__ sw(zero_reg, MemOperand(a0, 2 * kPointerSize + kIntSize));
|
||||
if (argc.is_immediate()) {
|
||||
// FunctionCallbackInfo::values_
|
||||
__ Daddu(at, scratch,
|
||||
Operand((FCA::kArgsLength - 1 + argc.immediate()) * kPointerSize));
|
||||
__ sd(at, MemOperand(a0, 1 * kPointerSize));
|
||||
// FunctionCallbackInfo::length_ = argc
|
||||
// Stored as int field, 32-bit integers within struct on stack always left
|
||||
// justified by n64 ABI.
|
||||
__ li(at, Operand(argc.immediate()));
|
||||
__ sw(at, MemOperand(a0, 2 * kPointerSize));
|
||||
// FunctionCallbackInfo::is_construct_call_ = 0
|
||||
__ sw(zero_reg, MemOperand(a0, 2 * kPointerSize + kIntSize));
|
||||
} else {
|
||||
// FunctionCallbackInfo::values_
|
||||
__ dsll(at, argc.reg(), kPointerSizeLog2);
|
||||
__ Daddu(at, at, scratch);
|
||||
__ Daddu(at, at, Operand((FCA::kArgsLength - 1) * kPointerSize));
|
||||
__ sd(at, MemOperand(a0, 1 * kPointerSize));
|
||||
// FunctionCallbackInfo::length_ = argc
|
||||
// Stored as int field, 32-bit integers within struct on stack always left
|
||||
// justified by n64 ABI.
|
||||
__ sw(argc.reg(), MemOperand(a0, 2 * kPointerSize));
|
||||
// FunctionCallbackInfo::is_construct_call_
|
||||
__ Daddu(argc.reg(), argc.reg(), Operand(FCA::kArgsLength + 1));
|
||||
__ dsll(at, argc.reg(), kPointerSizeLog2);
|
||||
__ sw(at, MemOperand(a0, 2 * kPointerSize + kIntSize));
|
||||
}
|
||||
|
||||
ExternalReference thunk_ref =
|
||||
ExternalReference::invoke_function_callback(masm->isolate());
|
||||
@ -5712,7 +5734,7 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
|
||||
fp, (2 + FCA::kContextSaveIndex) * kPointerSize);
|
||||
// Stores return the first js argument.
|
||||
int return_value_offset = 0;
|
||||
if (is_store()) {
|
||||
if (return_first_arg) {
|
||||
return_value_offset = 2 + FCA::kArgsLength;
|
||||
} else {
|
||||
return_value_offset = 2 + FCA::kReturnValueOffset;
|
||||
@ -5720,14 +5742,33 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
|
||||
MemOperand return_value_operand(fp, return_value_offset * kPointerSize);
|
||||
int stack_space = 0;
|
||||
int32_t stack_space_offset = 4 * kPointerSize;
|
||||
stack_space = argc() + FCA::kArgsLength + 1;
|
||||
stack_space_offset = kInvalidStackOffset;
|
||||
if (argc.is_immediate()) {
|
||||
stack_space = argc.immediate() + FCA::kArgsLength + 1;
|
||||
stack_space_offset = kInvalidStackOffset;
|
||||
}
|
||||
CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, stack_space,
|
||||
stack_space_offset, return_value_operand,
|
||||
&context_restore_operand);
|
||||
}
|
||||
|
||||
|
||||
void CallApiFunctionStub::Generate(MacroAssembler* masm) {
|
||||
bool call_data_undefined = this->call_data_undefined();
|
||||
CallApiFunctionStubHelper(masm, ParameterCount(a3), false,
|
||||
call_data_undefined, false);
|
||||
}
|
||||
|
||||
|
||||
void CallApiAccessorStub::Generate(MacroAssembler* masm) {
|
||||
bool is_store = this->is_store();
|
||||
int argc = this->argc();
|
||||
bool call_data_undefined = this->call_data_undefined();
|
||||
bool is_lazy = this->is_lazy();
|
||||
CallApiFunctionStubHelper(masm, ParameterCount(argc), is_store,
|
||||
call_data_undefined, is_lazy);
|
||||
}
|
||||
|
||||
|
||||
void CallApiGetterStub::Generate(MacroAssembler* masm) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- sp[0] : name
|
||||
|
@ -384,7 +384,21 @@ void ArgumentAdaptorDescriptor::InitializePlatformSpecific(
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void ApiCallbackDescriptorBase::InitializePlatformSpecific(
|
||||
|
||||
void ApiFunctionDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
a0, // callee
|
||||
a4, // call_data
|
||||
a2, // holder
|
||||
a1, // api_function_address
|
||||
a3, // actual number of arguments
|
||||
};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
|
||||
void ApiAccessorDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
a0, // callee
|
||||
|
@ -5613,12 +5613,16 @@ static void CallApiFunctionAndReturn(MacroAssembler* masm,
|
||||
__ b(&leave_exit_frame);
|
||||
}
|
||||
|
||||
void CallApiCallbackStub::Generate(MacroAssembler* masm) {
|
||||
static void CallApiFunctionStubHelper(MacroAssembler* masm,
|
||||
const ParameterCount& argc,
|
||||
bool return_first_arg,
|
||||
bool call_data_undefined, bool is_lazy) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- r3 : callee
|
||||
// -- r7 : call_data
|
||||
// -- r5 : holder
|
||||
// -- r4 : api_function_address
|
||||
// -- r6 : number of arguments if argc is a register
|
||||
// -- cp : context
|
||||
// --
|
||||
// -- sp[0] : last argument
|
||||
@ -5648,7 +5652,7 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
|
||||
|
||||
// context save
|
||||
__ push(context);
|
||||
if (!is_lazy()) {
|
||||
if (!is_lazy) {
|
||||
// load context from callee
|
||||
__ LoadP(context, FieldMemOperand(callee, JSFunction::kContextOffset));
|
||||
}
|
||||
@ -5660,7 +5664,7 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
|
||||
__ push(call_data);
|
||||
|
||||
Register scratch = call_data;
|
||||
if (!call_data_undefined()) {
|
||||
if (!call_data_undefined) {
|
||||
__ LoadRoot(scratch, Heap::kUndefinedValueRootIndex);
|
||||
}
|
||||
// return value
|
||||
@ -5696,15 +5700,28 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
|
||||
__ addi(r3, sp, Operand(kFunctionCallbackInfoOffset));
|
||||
// FunctionCallbackInfo::implicit_args_
|
||||
__ StoreP(scratch, MemOperand(r3, 0 * kPointerSize));
|
||||
// FunctionCallbackInfo::values_
|
||||
__ addi(ip, scratch, Operand((FCA::kArgsLength - 1 + argc()) * kPointerSize));
|
||||
__ StoreP(ip, MemOperand(r3, 1 * kPointerSize));
|
||||
// FunctionCallbackInfo::length_ = argc
|
||||
__ li(ip, Operand(argc()));
|
||||
__ stw(ip, MemOperand(r3, 2 * kPointerSize));
|
||||
// FunctionCallbackInfo::is_construct_call_ = 0
|
||||
__ li(ip, Operand::Zero());
|
||||
__ stw(ip, MemOperand(r3, 2 * kPointerSize + kIntSize));
|
||||
if (argc.is_immediate()) {
|
||||
// FunctionCallbackInfo::values_
|
||||
__ addi(ip, scratch,
|
||||
Operand((FCA::kArgsLength - 1 + argc.immediate()) * kPointerSize));
|
||||
__ StoreP(ip, MemOperand(r3, 1 * kPointerSize));
|
||||
// FunctionCallbackInfo::length_ = argc
|
||||
__ li(ip, Operand(argc.immediate()));
|
||||
__ stw(ip, MemOperand(r3, 2 * kPointerSize));
|
||||
// FunctionCallbackInfo::is_construct_call_ = 0
|
||||
__ li(ip, Operand::Zero());
|
||||
__ stw(ip, MemOperand(r3, 2 * kPointerSize + kIntSize));
|
||||
} else {
|
||||
__ ShiftLeftImm(ip, argc.reg(), Operand(kPointerSizeLog2));
|
||||
__ addi(ip, ip, Operand((FCA::kArgsLength - 1) * kPointerSize));
|
||||
// FunctionCallbackInfo::values_
|
||||
__ add(r0, scratch, ip);
|
||||
__ StoreP(r0, MemOperand(r3, 1 * kPointerSize));
|
||||
// FunctionCallbackInfo::length_ = argc
|
||||
__ stw(argc.reg(), MemOperand(r3, 2 * kPointerSize));
|
||||
// FunctionCallbackInfo::is_construct_call_
|
||||
__ stw(ip, MemOperand(r3, 2 * kPointerSize + kIntSize));
|
||||
}
|
||||
|
||||
ExternalReference thunk_ref =
|
||||
ExternalReference::invoke_function_callback(masm->isolate());
|
||||
@ -5714,7 +5731,7 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
|
||||
fp, (2 + FCA::kContextSaveIndex) * kPointerSize);
|
||||
// Stores return the first js argument
|
||||
int return_value_offset = 0;
|
||||
if (is_store()) {
|
||||
if (return_first_arg) {
|
||||
return_value_offset = 2 + FCA::kArgsLength;
|
||||
} else {
|
||||
return_value_offset = 2 + FCA::kReturnValueOffset;
|
||||
@ -5724,14 +5741,33 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
|
||||
MemOperand is_construct_call_operand =
|
||||
MemOperand(sp, kFunctionCallbackInfoOffset + 2 * kPointerSize + kIntSize);
|
||||
MemOperand* stack_space_operand = &is_construct_call_operand;
|
||||
stack_space = argc() + FCA::kArgsLength + 1;
|
||||
stack_space_operand = NULL;
|
||||
if (argc.is_immediate()) {
|
||||
stack_space = argc.immediate() + FCA::kArgsLength + 1;
|
||||
stack_space_operand = NULL;
|
||||
}
|
||||
CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, stack_space,
|
||||
stack_space_operand, return_value_operand,
|
||||
&context_restore_operand);
|
||||
}
|
||||
|
||||
|
||||
void CallApiFunctionStub::Generate(MacroAssembler* masm) {
|
||||
bool call_data_undefined = this->call_data_undefined();
|
||||
CallApiFunctionStubHelper(masm, ParameterCount(r6), false,
|
||||
call_data_undefined, false);
|
||||
}
|
||||
|
||||
|
||||
void CallApiAccessorStub::Generate(MacroAssembler* masm) {
|
||||
bool is_store = this->is_store();
|
||||
int argc = this->argc();
|
||||
bool call_data_undefined = this->call_data_undefined();
|
||||
bool is_lazy = this->is_lazy();
|
||||
CallApiFunctionStubHelper(masm, ParameterCount(argc), is_store,
|
||||
call_data_undefined, is_lazy);
|
||||
}
|
||||
|
||||
|
||||
void CallApiGetterStub::Generate(MacroAssembler* masm) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- sp[0] : name
|
||||
|
@ -380,7 +380,21 @@ void ArgumentAdaptorDescriptor::InitializePlatformSpecific(
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void ApiCallbackDescriptorBase::InitializePlatformSpecific(
|
||||
|
||||
void ApiFunctionDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
r3, // callee
|
||||
r7, // call_data
|
||||
r5, // holder
|
||||
r4, // api_function_address
|
||||
r6, // actual number of arguments
|
||||
};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
|
||||
void ApiAccessorDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
r3, // callee
|
||||
|
@ -5543,12 +5543,16 @@ static void CallApiFunctionAndReturn(MacroAssembler* masm,
|
||||
__ b(&leave_exit_frame, Label::kNear);
|
||||
}
|
||||
|
||||
void CallApiCallbackStub::Generate(MacroAssembler* masm) {
|
||||
static void CallApiFunctionStubHelper(MacroAssembler* masm,
|
||||
const ParameterCount& argc,
|
||||
bool return_first_arg,
|
||||
bool call_data_undefined, bool is_lazy) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- r2 : callee
|
||||
// -- r6 : call_data
|
||||
// -- r4 : holder
|
||||
// -- r3 : api_function_address
|
||||
// -- r5 : number of arguments if argc is a register
|
||||
// -- cp : context
|
||||
// --
|
||||
// -- sp[0] : last argument
|
||||
@ -5574,6 +5578,8 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
|
||||
STATIC_ASSERT(FCA::kHolderIndex == 0);
|
||||
STATIC_ASSERT(FCA::kArgsLength == 7);
|
||||
|
||||
DCHECK(argc.is_immediate() || r2.is(argc.reg()));
|
||||
|
||||
// context save
|
||||
__ push(context);
|
||||
if (!is_lazy) {
|
||||
@ -5588,7 +5594,7 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
|
||||
__ push(call_data);
|
||||
|
||||
Register scratch = call_data;
|
||||
if (!call_data_undefined()) {
|
||||
if (!call_data_undefined) {
|
||||
__ LoadRoot(scratch, Heap::kUndefinedValueRootIndex);
|
||||
}
|
||||
// return value
|
||||
@ -5624,15 +5630,28 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
|
||||
__ AddP(r2, sp, Operand(kFunctionCallbackInfoOffset));
|
||||
// FunctionCallbackInfo::implicit_args_
|
||||
__ StoreP(scratch, MemOperand(r2, 0 * kPointerSize));
|
||||
// FunctionCallbackInfo::values_
|
||||
__ AddP(ip, scratch, Operand((FCA::kArgsLength - 1 + argc()) * kPointerSize));
|
||||
__ StoreP(ip, MemOperand(r2, 1 * kPointerSize));
|
||||
// FunctionCallbackInfo::length_ = argc
|
||||
__ LoadImmP(ip, Operand(argc()));
|
||||
__ StoreW(ip, MemOperand(r2, 2 * kPointerSize));
|
||||
// FunctionCallbackInfo::is_construct_call_ = 0
|
||||
__ LoadImmP(ip, Operand::Zero());
|
||||
__ StoreW(ip, MemOperand(r2, 2 * kPointerSize + kIntSize));
|
||||
if (argc.is_immediate()) {
|
||||
// FunctionCallbackInfo::values_
|
||||
__ AddP(ip, scratch,
|
||||
Operand((FCA::kArgsLength - 1 + argc.immediate()) * kPointerSize));
|
||||
__ StoreP(ip, MemOperand(r2, 1 * kPointerSize));
|
||||
// FunctionCallbackInfo::length_ = argc
|
||||
__ LoadImmP(ip, Operand(argc.immediate()));
|
||||
__ StoreW(ip, MemOperand(r2, 2 * kPointerSize));
|
||||
// FunctionCallbackInfo::is_construct_call_ = 0
|
||||
__ LoadImmP(ip, Operand::Zero());
|
||||
__ StoreW(ip, MemOperand(r2, 2 * kPointerSize + kIntSize));
|
||||
} else {
|
||||
__ ShiftLeftP(ip, argc.reg(), Operand(kPointerSizeLog2));
|
||||
__ AddP(ip, ip, Operand((FCA::kArgsLength - 1) * kPointerSize));
|
||||
// FunctionCallbackInfo::values_
|
||||
__ AddP(r0, scratch, ip);
|
||||
__ StoreP(r0, MemOperand(r2, 1 * kPointerSize));
|
||||
// FunctionCallbackInfo::length_ = argc
|
||||
__ StoreW(argc.reg(), MemOperand(r2, 2 * kPointerSize));
|
||||
// FunctionCallbackInfo::is_construct_call_
|
||||
__ StoreW(ip, MemOperand(r2, 2 * kPointerSize + kIntSize));
|
||||
}
|
||||
|
||||
ExternalReference thunk_ref =
|
||||
ExternalReference::invoke_function_callback(masm->isolate());
|
||||
@ -5642,7 +5661,7 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
|
||||
fp, (2 + FCA::kContextSaveIndex) * kPointerSize);
|
||||
// Stores return the first js argument
|
||||
int return_value_offset = 0;
|
||||
if (is_store()) {
|
||||
if (return_first_arg) {
|
||||
return_value_offset = 2 + FCA::kArgsLength;
|
||||
} else {
|
||||
return_value_offset = 2 + FCA::kReturnValueOffset;
|
||||
@ -5652,13 +5671,30 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
|
||||
MemOperand is_construct_call_operand =
|
||||
MemOperand(sp, kFunctionCallbackInfoOffset + 2 * kPointerSize + kIntSize);
|
||||
MemOperand* stack_space_operand = &is_construct_call_operand;
|
||||
stack_space = argc() + FCA::kArgsLength + 1;
|
||||
stack_space_operand = NULL;
|
||||
if (argc.is_immediate()) {
|
||||
stack_space = argc.immediate() + FCA::kArgsLength + 1;
|
||||
stack_space_operand = NULL;
|
||||
}
|
||||
CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, stack_space,
|
||||
stack_space_operand, return_value_operand,
|
||||
&context_restore_operand);
|
||||
}
|
||||
|
||||
void CallApiFunctionStub::Generate(MacroAssembler* masm) {
|
||||
bool call_data_undefined = this->call_data_undefined();
|
||||
CallApiFunctionStubHelper(masm, ParameterCount(r6), false,
|
||||
call_data_undefined, false);
|
||||
}
|
||||
|
||||
void CallApiAccessorStub::Generate(MacroAssembler* masm) {
|
||||
bool is_store = this->is_store();
|
||||
int argc = this->argc();
|
||||
bool call_data_undefined = this->call_data_undefined();
|
||||
bool is_lazy = this->is_lazy();
|
||||
CallApiFunctionStubHelper(masm, ParameterCount(argc), is_store,
|
||||
call_data_undefined, is_lazy);
|
||||
}
|
||||
|
||||
void CallApiGetterStub::Generate(MacroAssembler* masm) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- sp[0] : name
|
||||
|
@ -334,7 +334,19 @@ void ArgumentAdaptorDescriptor::InitializePlatformSpecific(
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void ApiCallbackDescriptorBase::InitializePlatformSpecific(
|
||||
void ApiFunctionDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
r2, // callee
|
||||
r6, // call_data
|
||||
r4, // holder
|
||||
r3, // api_function_address
|
||||
r5, // actual number of arguments
|
||||
};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void ApiAccessorDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
r2, // callee
|
||||
|
@ -5406,7 +5406,10 @@ static void CallApiFunctionAndReturn(MacroAssembler* masm,
|
||||
__ jmp(&leave_exit_frame);
|
||||
}
|
||||
|
||||
void CallApiCallbackStub::Generate(MacroAssembler* masm) {
|
||||
static void CallApiFunctionStubHelper(MacroAssembler* masm,
|
||||
const ParameterCount& argc,
|
||||
bool return_first_arg,
|
||||
bool call_data_undefined, bool is_lazy) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- rdi : callee
|
||||
// -- rbx : call_data
|
||||
@ -5439,6 +5442,8 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
|
||||
STATIC_ASSERT(FCA::kHolderIndex == 0);
|
||||
STATIC_ASSERT(FCA::kArgsLength == 7);
|
||||
|
||||
DCHECK(argc.is_immediate() || rax.is(argc.reg()));
|
||||
|
||||
__ PopReturnAddressTo(return_address);
|
||||
|
||||
// context save
|
||||
@ -5450,7 +5455,7 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
|
||||
// call data
|
||||
__ Push(call_data);
|
||||
Register scratch = call_data;
|
||||
if (!this->call_data_undefined()) {
|
||||
if (!call_data_undefined) {
|
||||
__ LoadRoot(scratch, Heap::kUndefinedValueRootIndex);
|
||||
}
|
||||
// return value
|
||||
@ -5467,7 +5472,7 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
|
||||
// Push return address back on stack.
|
||||
__ PushReturnAddressFrom(return_address);
|
||||
|
||||
if (!this->is_lazy()) {
|
||||
if (!is_lazy) {
|
||||
// load context from callee
|
||||
__ movp(context, FieldOperand(callee, JSFunction::kContextOffset));
|
||||
}
|
||||
@ -5479,15 +5484,28 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
|
||||
PrepareCallApiFunction(masm, kApiStackSpace);
|
||||
|
||||
// FunctionCallbackInfo::implicit_args_.
|
||||
int argc = this->argc();
|
||||
__ movp(StackSpaceOperand(0), scratch);
|
||||
__ addp(scratch, Immediate((argc + FCA::kArgsLength - 1) * kPointerSize));
|
||||
// FunctionCallbackInfo::values_.
|
||||
__ movp(StackSpaceOperand(1), scratch);
|
||||
// FunctionCallbackInfo::length_.
|
||||
__ Set(StackSpaceOperand(2), argc);
|
||||
// FunctionCallbackInfo::is_construct_call_.
|
||||
__ Set(StackSpaceOperand(3), 0);
|
||||
if (argc.is_immediate()) {
|
||||
__ addp(scratch, Immediate((argc.immediate() + FCA::kArgsLength - 1) *
|
||||
kPointerSize));
|
||||
// FunctionCallbackInfo::values_.
|
||||
__ movp(StackSpaceOperand(1), scratch);
|
||||
// FunctionCallbackInfo::length_.
|
||||
__ Set(StackSpaceOperand(2), argc.immediate());
|
||||
// FunctionCallbackInfo::is_construct_call_.
|
||||
__ Set(StackSpaceOperand(3), 0);
|
||||
} else {
|
||||
__ leap(scratch, Operand(scratch, argc.reg(), times_pointer_size,
|
||||
(FCA::kArgsLength - 1) * kPointerSize));
|
||||
// FunctionCallbackInfo::values_.
|
||||
__ movp(StackSpaceOperand(1), scratch);
|
||||
// FunctionCallbackInfo::length_.
|
||||
__ movp(StackSpaceOperand(2), argc.reg());
|
||||
// FunctionCallbackInfo::is_construct_call_.
|
||||
__ leap(argc.reg(), Operand(argc.reg(), times_pointer_size,
|
||||
(FCA::kArgsLength + 1) * kPointerSize));
|
||||
__ movp(StackSpaceOperand(3), argc.reg());
|
||||
}
|
||||
|
||||
#if defined(__MINGW64__) || defined(_WIN64)
|
||||
Register arguments_arg = rcx;
|
||||
@ -5514,17 +5532,36 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
|
||||
FCA::kArgsLength - FCA::kContextSaveIndex);
|
||||
Operand is_construct_call_operand = StackSpaceOperand(3);
|
||||
Operand return_value_operand = args_from_rbp.GetArgumentOperand(
|
||||
this->is_store() ? 0 : FCA::kArgsLength - FCA::kReturnValueOffset);
|
||||
return_first_arg ? 0 : FCA::kArgsLength - FCA::kReturnValueOffset);
|
||||
int stack_space = 0;
|
||||
Operand* stack_space_operand = &is_construct_call_operand;
|
||||
stack_space = argc + FCA::kArgsLength + 1;
|
||||
stack_space_operand = nullptr;
|
||||
if (argc.is_immediate()) {
|
||||
stack_space = argc.immediate() + FCA::kArgsLength + 1;
|
||||
stack_space_operand = nullptr;
|
||||
}
|
||||
CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, callback_arg,
|
||||
stack_space, stack_space_operand,
|
||||
return_value_operand, &context_restore_operand);
|
||||
}
|
||||
|
||||
|
||||
void CallApiFunctionStub::Generate(MacroAssembler* masm) {
|
||||
bool call_data_undefined = this->call_data_undefined();
|
||||
CallApiFunctionStubHelper(masm, ParameterCount(rax), false,
|
||||
call_data_undefined, false);
|
||||
}
|
||||
|
||||
|
||||
void CallApiAccessorStub::Generate(MacroAssembler* masm) {
|
||||
bool is_store = this->is_store();
|
||||
int argc = this->argc();
|
||||
bool call_data_undefined = this->call_data_undefined();
|
||||
bool is_lazy = this->is_lazy();
|
||||
CallApiFunctionStubHelper(masm, ParameterCount(argc), is_store,
|
||||
call_data_undefined, is_lazy);
|
||||
}
|
||||
|
||||
|
||||
void CallApiGetterStub::Generate(MacroAssembler* masm) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- rsp[0] : return address
|
||||
|
@ -381,7 +381,21 @@ void ArgumentAdaptorDescriptor::InitializePlatformSpecific(
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void ApiCallbackDescriptorBase::InitializePlatformSpecific(
|
||||
|
||||
void ApiFunctionDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
rdi, // callee
|
||||
rbx, // call_data
|
||||
rcx, // holder
|
||||
rdx, // api_function_address
|
||||
rax, // actual number of arguments
|
||||
};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
|
||||
void ApiAccessorDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
rdi, // callee
|
||||
|
@ -5346,13 +5346,17 @@ static void CallApiFunctionAndReturn(MacroAssembler* masm,
|
||||
__ jmp(&leave_exit_frame);
|
||||
}
|
||||
|
||||
void CallApiCallbackStub::Generate(MacroAssembler* masm) {
|
||||
static void CallApiFunctionStubHelper(MacroAssembler* masm,
|
||||
const ParameterCount& argc,
|
||||
bool return_first_arg,
|
||||
bool call_data_undefined, bool is_lazy) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- edi : callee
|
||||
// -- ebx : call_data
|
||||
// -- ecx : holder
|
||||
// -- edx : api_function_address
|
||||
// -- esi : context
|
||||
// -- eax : number of arguments if argc is a register
|
||||
// --
|
||||
// -- esp[0] : return address
|
||||
// -- esp[4] : last argument
|
||||
@ -5381,9 +5385,15 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
|
||||
|
||||
DCHECK(argc.is_immediate() || eax.is(argc.reg()));
|
||||
|
||||
__ pop(return_address);
|
||||
// context save.
|
||||
__ push(context);
|
||||
if (argc.is_immediate()) {
|
||||
__ pop(return_address);
|
||||
// context save.
|
||||
__ push(context);
|
||||
} else {
|
||||
// pop return address and save context
|
||||
__ xchg(context, Operand(esp, 0));
|
||||
return_address = context;
|
||||
}
|
||||
|
||||
// callee
|
||||
__ push(callee);
|
||||
@ -5392,7 +5402,7 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
|
||||
__ push(call_data);
|
||||
|
||||
Register scratch = call_data;
|
||||
if (!call_data_undefined()) {
|
||||
if (!call_data_undefined) {
|
||||
// return value
|
||||
__ push(Immediate(masm->isolate()->factory()->undefined_value()));
|
||||
// return value default
|
||||
@ -5413,7 +5423,7 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
|
||||
// push return address
|
||||
__ push(return_address);
|
||||
|
||||
if (!is_lazy()) {
|
||||
if (!is_lazy) {
|
||||
// load context from callee
|
||||
__ mov(context, FieldOperand(callee, JSFunction::kContextOffset));
|
||||
}
|
||||
@ -5432,13 +5442,27 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
|
||||
|
||||
// FunctionCallbackInfo::implicit_args_.
|
||||
__ mov(ApiParameterOperand(2), scratch);
|
||||
__ add(scratch, Immediate((argc() + FCA::kArgsLength - 1) * kPointerSize));
|
||||
// FunctionCallbackInfo::values_.
|
||||
__ mov(ApiParameterOperand(3), scratch);
|
||||
// FunctionCallbackInfo::length_.
|
||||
__ Move(ApiParameterOperand(4), Immediate(argc));
|
||||
// FunctionCallbackInfo::is_construct_call_.
|
||||
__ Move(ApiParameterOperand(5), Immediate(0));
|
||||
if (argc.is_immediate()) {
|
||||
__ add(scratch,
|
||||
Immediate((argc.immediate() + FCA::kArgsLength - 1) * kPointerSize));
|
||||
// FunctionCallbackInfo::values_.
|
||||
__ mov(ApiParameterOperand(3), scratch);
|
||||
// FunctionCallbackInfo::length_.
|
||||
__ Move(ApiParameterOperand(4), Immediate(argc.immediate()));
|
||||
// FunctionCallbackInfo::is_construct_call_.
|
||||
__ Move(ApiParameterOperand(5), Immediate(0));
|
||||
} else {
|
||||
__ lea(scratch, Operand(scratch, argc.reg(), times_pointer_size,
|
||||
(FCA::kArgsLength - 1) * kPointerSize));
|
||||
// FunctionCallbackInfo::values_.
|
||||
__ mov(ApiParameterOperand(3), scratch);
|
||||
// FunctionCallbackInfo::length_.
|
||||
__ mov(ApiParameterOperand(4), argc.reg());
|
||||
// FunctionCallbackInfo::is_construct_call_.
|
||||
__ lea(argc.reg(), Operand(argc.reg(), times_pointer_size,
|
||||
(FCA::kArgsLength + 1) * kPointerSize));
|
||||
__ mov(ApiParameterOperand(5), argc.reg());
|
||||
}
|
||||
|
||||
// v8::InvocationCallback's argument.
|
||||
__ lea(scratch, ApiParameterOperand(2));
|
||||
@ -5451,7 +5475,7 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
|
||||
(2 + FCA::kContextSaveIndex) * kPointerSize);
|
||||
// Stores return the first js argument
|
||||
int return_value_offset = 0;
|
||||
if (is_store()) {
|
||||
if (return_first_arg) {
|
||||
return_value_offset = 2 + FCA::kArgsLength;
|
||||
} else {
|
||||
return_value_offset = 2 + FCA::kReturnValueOffset;
|
||||
@ -5460,8 +5484,10 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
|
||||
int stack_space = 0;
|
||||
Operand is_construct_call_operand = ApiParameterOperand(5);
|
||||
Operand* stack_space_operand = &is_construct_call_operand;
|
||||
stack_space = argc() + FCA::kArgsLength + 1;
|
||||
stack_space_operand = nullptr;
|
||||
if (argc.is_immediate()) {
|
||||
stack_space = argc.immediate() + FCA::kArgsLength + 1;
|
||||
stack_space_operand = nullptr;
|
||||
}
|
||||
CallApiFunctionAndReturn(masm, api_function_address, thunk_ref,
|
||||
ApiParameterOperand(1), stack_space,
|
||||
stack_space_operand, return_value_operand,
|
||||
@ -5469,6 +5495,23 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
|
||||
}
|
||||
|
||||
|
||||
void CallApiFunctionStub::Generate(MacroAssembler* masm) {
|
||||
bool call_data_undefined = this->call_data_undefined();
|
||||
CallApiFunctionStubHelper(masm, ParameterCount(eax), false,
|
||||
call_data_undefined, false);
|
||||
}
|
||||
|
||||
|
||||
void CallApiAccessorStub::Generate(MacroAssembler* masm) {
|
||||
bool is_store = this->is_store();
|
||||
int argc = this->argc();
|
||||
bool call_data_undefined = this->call_data_undefined();
|
||||
bool is_lazy = this->is_lazy();
|
||||
CallApiFunctionStubHelper(masm, ParameterCount(argc), is_store,
|
||||
call_data_undefined, is_lazy);
|
||||
}
|
||||
|
||||
|
||||
void CallApiGetterStub::Generate(MacroAssembler* masm) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- esp[0] : return address
|
||||
|
@ -387,7 +387,21 @@ void ArgumentAdaptorDescriptor::InitializePlatformSpecific(
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void ApiCallbackDescriptorBase::InitializePlatformSpecific(
|
||||
|
||||
void ApiFunctionDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
edi, // callee
|
||||
ebx, // call_data
|
||||
ecx, // holder
|
||||
edx, // api_function_address
|
||||
eax, // actual number of arguments
|
||||
};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
|
||||
void ApiAccessorDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
edi, // callee
|
||||
|
Loading…
Reference in New Issue
Block a user