MIPS: Fix DIRECT_API_CALL_NEW and DIRECT_GETTER_CALL_NEW call.
This commit fixes the register usage of DIRECT_API_CALL_NEW and DIRECT_GETTER_CALL_NEW: * These functions expect arguments in a0-a1 and not in a1-a2 as the and DIRECT_API_CALL and DIRECT_GETTER_CALL do. * Fixes the simulator to expect *_NEW arguments in a0-a1. * Adds more comment to simulator to better explain the register usage. TEST=cctest/test-api/LoadICFastApi_DirectCall_GCMoveStub,cctest/test-api/SimpleCallback BUG= Review URL: https://codereview.chromium.org/15813005 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14813 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
eaa793604f
commit
f2350072bd
@ -3944,7 +3944,9 @@ void MacroAssembler::CallApiFunctionAndReturn(ExternalReference function,
|
||||
// (4 bytes) will be placed. This is also built into the Simulator.
|
||||
// Set up the pointer to the returned value (a0). It was allocated in
|
||||
// EnterExitFrame.
|
||||
if (returns_handle) {
|
||||
addiu(a0, fp, ExitFrameConstants::kStackSpaceOffset);
|
||||
}
|
||||
|
||||
// Native call returns to the DirectCEntry stub which redirects to the
|
||||
// return address pushed on stack (could have moved after GC).
|
||||
|
@ -1387,12 +1387,19 @@ typedef double (*SimulatorRuntimeFPIntCall)(double darg0, int32_t arg0);
|
||||
|
||||
// This signature supports direct call in to API function native callback
|
||||
// (refer to InvocationCallback in v8.h).
|
||||
// NOTE: the O32 abi requires a0 to hold a special pointer when returning a
|
||||
// struct from the function (which is currently the case). This means we pass
|
||||
// the first argument in a1 instead of a0.
|
||||
typedef v8::Handle<v8::Value> (*SimulatorRuntimeDirectApiCall)(int32_t arg0);
|
||||
// Here, we pass the first argument in a0, because this function
|
||||
// does not return a struct.
|
||||
typedef void (*SimulatorRuntimeDirectApiCallNew)(int32_t arg0);
|
||||
|
||||
// This signature supports direct call to accessor getter callback.
|
||||
// See comment at SimulatorRuntimeDirectApiCall.
|
||||
typedef v8::Handle<v8::Value> (*SimulatorRuntimeDirectGetterCall)(int32_t arg0,
|
||||
int32_t arg1);
|
||||
// See comment at SimulatorRuntimeDirectApiCallNew.
|
||||
typedef void (*SimulatorRuntimeDirectGetterCallNew)(int32_t arg0,
|
||||
int32_t arg1);
|
||||
|
||||
@ -1542,40 +1549,50 @@ void Simulator::SoftwareInterrupt(Instruction* instr) {
|
||||
} else if (
|
||||
redirection->type() == ExternalReference::DIRECT_API_CALL ||
|
||||
redirection->type() == ExternalReference::DIRECT_API_CALL_NEW) {
|
||||
// See DirectCEntryStub::GenerateCall for explanation of register usage.
|
||||
if (redirection->type() == ExternalReference::DIRECT_API_CALL) {
|
||||
// See comment at type definition of SimulatorRuntimeDirectApiCall
|
||||
// for explanation of register usage.
|
||||
if (::v8::internal::FLAG_trace_sim) {
|
||||
PrintF("Call to host function at %p args %08x\n",
|
||||
reinterpret_cast<void*>(external), arg1);
|
||||
}
|
||||
if (redirection->type() == ExternalReference::DIRECT_API_CALL) {
|
||||
SimulatorRuntimeDirectApiCall target =
|
||||
reinterpret_cast<SimulatorRuntimeDirectApiCall>(external);
|
||||
v8::Handle<v8::Value> result = target(arg1);
|
||||
*(reinterpret_cast<int*>(arg0)) = reinterpret_cast<int32_t>(*result);
|
||||
set_register(v0, arg0);
|
||||
} else {
|
||||
if (::v8::internal::FLAG_trace_sim) {
|
||||
PrintF("Call to host function at %p args %08x\n",
|
||||
reinterpret_cast<void*>(external), arg0);
|
||||
}
|
||||
SimulatorRuntimeDirectApiCallNew target =
|
||||
reinterpret_cast<SimulatorRuntimeDirectApiCallNew>(external);
|
||||
target(arg1);
|
||||
target(arg0);
|
||||
}
|
||||
} else if (
|
||||
redirection->type() == ExternalReference::DIRECT_GETTER_CALL ||
|
||||
redirection->type() == ExternalReference::DIRECT_GETTER_CALL_NEW) {
|
||||
// See DirectCEntryStub::GenerateCall for explanation of register usage.
|
||||
if (redirection->type() == ExternalReference::DIRECT_GETTER_CALL) {
|
||||
// See comment at type definition of SimulatorRuntimeDirectGetterCall
|
||||
// for explanation of register usage.
|
||||
if (::v8::internal::FLAG_trace_sim) {
|
||||
PrintF("Call to host function at %p args %08x %08x\n",
|
||||
reinterpret_cast<void*>(external), arg1, arg2);
|
||||
}
|
||||
if (redirection->type() == ExternalReference::DIRECT_GETTER_CALL) {
|
||||
SimulatorRuntimeDirectGetterCall target =
|
||||
reinterpret_cast<SimulatorRuntimeDirectGetterCall>(external);
|
||||
v8::Handle<v8::Value> result = target(arg1, arg2);
|
||||
*(reinterpret_cast<int*>(arg0)) = reinterpret_cast<int32_t>(*result);
|
||||
set_register(v0, arg0);
|
||||
} else {
|
||||
if (::v8::internal::FLAG_trace_sim) {
|
||||
PrintF("Call to host function at %p args %08x %08x\n",
|
||||
reinterpret_cast<void*>(external), arg0, arg1);
|
||||
}
|
||||
SimulatorRuntimeDirectGetterCallNew target =
|
||||
reinterpret_cast<SimulatorRuntimeDirectGetterCallNew>(external);
|
||||
target(arg1, arg2);
|
||||
target(arg0, arg1);
|
||||
}
|
||||
} else {
|
||||
SimulatorRuntimeCall target =
|
||||
|
@ -924,28 +924,31 @@ static void GenerateFastApiDirectCall(MacroAssembler* masm,
|
||||
|
||||
// NOTE: the O32 abi requires a0 to hold a special pointer when returning a
|
||||
// struct from the function (which is currently the case). This means we pass
|
||||
// the first argument in a1 instead of a0. TryCallApiFunctionAndReturn
|
||||
// will handle setting up a0.
|
||||
// the first argument in a1 instead of a0, if returns_handle is true.
|
||||
// CallApiFunctionAndReturn will set up a0.
|
||||
|
||||
// a1 = v8::Arguments&
|
||||
// Arguments is built at sp + 1 (sp is a reserved spot for ra).
|
||||
__ Addu(a1, sp, kPointerSize);
|
||||
|
||||
// v8::Arguments::implicit_args_
|
||||
__ sw(a2, MemOperand(a1, 0 * kPointerSize));
|
||||
// v8::Arguments::values_
|
||||
__ Addu(t0, a2, Operand(argc * kPointerSize));
|
||||
__ sw(t0, MemOperand(a1, 1 * kPointerSize));
|
||||
// v8::Arguments::length_ = argc
|
||||
__ li(t0, Operand(argc));
|
||||
__ sw(t0, MemOperand(a1, 2 * kPointerSize));
|
||||
// v8::Arguments::is_construct_call = 0
|
||||
__ sw(zero_reg, MemOperand(a1, 3 * kPointerSize));
|
||||
|
||||
const int kStackUnwindSpace = argc + kFastApiCallArguments + 1;
|
||||
Address function_address = v8::ToCData<Address>(api_call_info->callback());
|
||||
bool returns_handle =
|
||||
!CallbackTable::ReturnsVoid(masm->isolate(), function_address);
|
||||
|
||||
Register first_arg = returns_handle ? a1 : a0;
|
||||
|
||||
// first_arg = v8::Arguments&
|
||||
// Arguments is built at sp + 1 (sp is a reserved spot for ra).
|
||||
__ Addu(first_arg, sp, kPointerSize);
|
||||
|
||||
// v8::Arguments::implicit_args_
|
||||
__ sw(a2, MemOperand(first_arg, 0 * kPointerSize));
|
||||
// v8::Arguments::values_
|
||||
__ Addu(t0, a2, Operand(argc * kPointerSize));
|
||||
__ sw(t0, MemOperand(first_arg, 1 * kPointerSize));
|
||||
// v8::Arguments::length_ = argc
|
||||
__ li(t0, Operand(argc));
|
||||
__ sw(t0, MemOperand(first_arg, 2 * kPointerSize));
|
||||
// v8::Arguments::is_construct_call = 0
|
||||
__ sw(zero_reg, MemOperand(first_arg, 3 * kPointerSize));
|
||||
|
||||
const int kStackUnwindSpace = argc + kFastApiCallArguments + 1;
|
||||
ApiFunction fun(function_address);
|
||||
ExternalReference::Type type =
|
||||
returns_handle ?
|
||||
@ -1442,13 +1445,20 @@ void BaseLoadStubCompiler::GenerateLoadCallback(
|
||||
__ sw(scratch4(), MemOperand(sp, 1 * kPointerSize));
|
||||
__ sw(name(), MemOperand(sp, 0 * kPointerSize));
|
||||
|
||||
Address getter_address = v8::ToCData<Address>(callback->getter());
|
||||
bool returns_handle =
|
||||
!CallbackTable::ReturnsVoid(isolate(), getter_address);
|
||||
|
||||
Register first_arg = returns_handle ? a1 : a0;
|
||||
Register second_arg = returns_handle ? a2 : a1;
|
||||
|
||||
__ mov(a2, scratch2()); // Saved in case scratch2 == a1.
|
||||
__ mov(a1, sp); // a1 (first argument - see note below) = Handle<Name>
|
||||
__ mov(first_arg, sp); // (first argument - see note below) = Handle<Name>
|
||||
|
||||
// NOTE: the O32 abi requires a0 to hold a special pointer when returning a
|
||||
// struct from the function (which is currently the case). This means we pass
|
||||
// the arguments in a1-a2 instead of a0-a1. TryCallApiFunctionAndReturn
|
||||
// will handle setting up a0.
|
||||
// the arguments in a1-a2 instead of a0-a1, if returns_handle is true.
|
||||
// CallApiFunctionAndReturn will set up a0.
|
||||
|
||||
const int kApiStackSpace = 1;
|
||||
FrameScope frame_scope(masm(), StackFrame::MANUAL);
|
||||
@ -1457,13 +1467,10 @@ void BaseLoadStubCompiler::GenerateLoadCallback(
|
||||
// Create AccessorInfo instance on the stack above the exit frame with
|
||||
// scratch2 (internal::Object** args_) as the data.
|
||||
__ sw(a2, MemOperand(sp, kPointerSize));
|
||||
// a2 (second argument - see note above) = AccessorInfo&
|
||||
__ Addu(a2, sp, kPointerSize);
|
||||
// (second argument - see note above) = AccessorInfo&
|
||||
__ Addu(second_arg, sp, kPointerSize);
|
||||
|
||||
const int kStackUnwindSpace = kFastApiCallArguments + 1;
|
||||
Address getter_address = v8::ToCData<Address>(callback->getter());
|
||||
bool returns_handle =
|
||||
!CallbackTable::ReturnsVoid(isolate(), getter_address);
|
||||
ApiFunction fun(getter_address);
|
||||
ExternalReference::Type type =
|
||||
returns_handle ?
|
||||
|
Loading…
Reference in New Issue
Block a user