Index: src/arm/macro-assembler-arm.cc |
diff --git a/src/arm/macro-assembler-arm.cc b/src/arm/macro-assembler-arm.cc |
index 6e0b4a7040ae080faa5e91b814338956924ddca0..9deae6bdddda581a4739f921022c4e3a83818d6d 100644 |
--- a/src/arm/macro-assembler-arm.cc |
+++ b/src/arm/macro-assembler-arm.cc |
@@ -2267,8 +2267,12 @@ static int AddressOffset(ExternalReference ref0, ExternalReference ref1) { |
} |
-void MacroAssembler::CallApiFunctionAndReturn(ExternalReference function, |
- int stack_space) { |
+void MacroAssembler::CallApiFunctionAndReturn( |
+ void* function_address, |
+ ExternalReference::Type function_type, |
+ int stack_space, |
+ int return_value_operand, |
+ int return_value_offset) { |
ExternalReference next_address = |
ExternalReference::handle_scope_next_address(isolate()); |
const int kNextOffset = 0; |
@@ -2300,7 +2304,13 @@ void MacroAssembler::CallApiFunctionAndReturn(ExternalReference function, |
// return address pushed on stack (could have moved after GC). |
// DirectCEntry stub itself is generated early and never moves. |
DirectCEntryStub stub; |
- stub.GenerateCall(this, function); |
+ { |
+ Address address = |
+ v8::ToCData<Address>(reinterpret_cast<Object*>(function_address)); |
+ ApiFunction fun(address); |
+ ExternalReference ref(&fun, function_type, isolate()); |
+ stub.GenerateCall(this, ref); |
+ } |
if (FLAG_log_timer_events) { |
FrameScope frame(this, StackFrame::MANUAL); |
@@ -2314,13 +2324,21 @@ void MacroAssembler::CallApiFunctionAndReturn(ExternalReference function, |
Label promote_scheduled_exception; |
Label delete_allocated_handles; |
Label leave_exit_frame; |
- |
- // If result is non-zero, dereference to get the result value |
- // otherwise set it to undefined. |
- cmp(r0, Operand::Zero()); |
- LoadRoot(r0, Heap::kUndefinedValueRootIndex, eq); |
- ldr(r0, MemOperand(r0), ne); |
- |
+ Label return_value_loaded; |
+ |
+ if (!CallbackTable::ReturnsVoid(isolate(), function_address)) { |
+ Label load_return_value; |
+ cmp(r0, Operand::Zero()); |
+ b(eq, &load_return_value); |
+ // derefernce returned value |
+ ldr(r0, MemOperand(r0)); |
+ b(&return_value_loaded); |
+ bind(&load_return_value); |
+ } |
+ // load value from ReturnValue |
+ ldr(r0, MemOperand(sp, return_value_operand*kPointerSize)); |
+ ldr(r0, MemOperand(r0, return_value_offset*kPointerSize)); |
+ bind(&return_value_loaded); |
// No more valid handles (the result handle was the last one). Restore |
// previous handle scope. |
str(r4, MemOperand(r7, kNextOffset)); |