| Index: src/x64/macro-assembler-x64.cc
|
| diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc
|
| index 691894c0e2cb4eb92fdad51bf9cbbed5c0c29fc1..31796b12838e9245ea814b5fba6182dfeb050b5e 100644
|
| --- a/src/x64/macro-assembler-x64.cc
|
| +++ b/src/x64/macro-assembler-x64.cc
|
| @@ -677,8 +677,13 @@ static int Offset(ExternalReference ref0, ExternalReference ref1) {
|
| }
|
|
|
|
|
| -void MacroAssembler::PrepareCallApiFunction(int arg_stack_space) {
|
| +void MacroAssembler::PrepareCallApiFunction(int arg_stack_space,
|
| + bool returns_handle) {
|
| #if defined(_WIN64) && !defined(__MINGW64__)
|
| + if (!returns_handle) {
|
| + EnterApiExitFrame(arg_stack_space);
|
| + return;
|
| + }
|
| // We need to prepare a slot for result handle on stack and put
|
| // a pointer to it into 1st arg register.
|
| EnterApiExitFrame(arg_stack_space + 1);
|
| @@ -692,8 +697,9 @@ void MacroAssembler::PrepareCallApiFunction(int arg_stack_space) {
|
|
|
|
|
| void MacroAssembler::CallApiFunctionAndReturn(Address function_address,
|
| - int stack_space) {
|
| - Label empty_result;
|
| + int stack_space,
|
| + bool returns_handle,
|
| + int return_value_offset) {
|
| Label prologue;
|
| Label promote_scheduled_exception;
|
| Label delete_allocated_handles;
|
| @@ -745,15 +751,25 @@ void MacroAssembler::CallApiFunctionAndReturn(Address function_address,
|
| PopSafepointRegisters();
|
| }
|
|
|
| + // Can skip the result check for new-style callbacks
|
| + // TODO(dcarney): may need to pass this information down
|
| + // as some function_addresses might not have been registered
|
| + if (returns_handle) {
|
| + Label empty_result;
|
| #if defined(_WIN64) && !defined(__MINGW64__)
|
| - // rax keeps a pointer to v8::Handle, unpack it.
|
| - movq(rax, Operand(rax, 0));
|
| + // rax keeps a pointer to v8::Handle, unpack it.
|
| + movq(rax, Operand(rax, 0));
|
| #endif
|
| - // Check if the result handle holds 0.
|
| - testq(rax, rax);
|
| - j(zero, &empty_result);
|
| - // It was non-zero. Dereference to get the result value.
|
| - movq(rax, Operand(rax, 0));
|
| + // Check if the result handle holds 0.
|
| + testq(rax, rax);
|
| + j(zero, &empty_result);
|
| + // It was non-zero. Dereference to get the result value.
|
| + movq(rax, Operand(rax, 0));
|
| + jmp(&prologue);
|
| + bind(&empty_result);
|
| + }
|
| + // Load the value from ReturnValue
|
| + movq(rax, Operand(rbp, return_value_offset * kPointerSize));
|
| bind(&prologue);
|
|
|
| // No more valid handles (the result handle was the last one). Restore
|
| @@ -807,11 +823,6 @@ void MacroAssembler::CallApiFunctionAndReturn(Address function_address,
|
| LeaveApiExitFrame();
|
| ret(stack_space * kPointerSize);
|
|
|
| - bind(&empty_result);
|
| - // It was zero; the result is undefined.
|
| - LoadRoot(rax, Heap::kUndefinedValueRootIndex);
|
| - jmp(&prologue);
|
| -
|
| bind(&promote_scheduled_exception);
|
| TailCallRuntime(Runtime::kPromoteScheduledException, 0, 1);
|
|
|
|
|