Index: src/x64/macro-assembler-x64.cc |
diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc |
index 0c605d826dd1f80fa4db3dec59fed95477c350c2..050b6a88a428719eefc8d1236894b07e950e4444 100644 |
--- a/src/x64/macro-assembler-x64.cc |
+++ b/src/x64/macro-assembler-x64.cc |
@@ -694,9 +694,11 @@ void MacroAssembler::CallApiFunctionAndReturn(Address function_address, |
Address thunk_address, |
Register thunk_last_arg, |
int stack_space, |
- int return_value_offset) { |
+ int return_value_offset, |
+ int restore_context_offset) { |
Label prologue; |
Label promote_scheduled_exception; |
+ Label exception_handled; |
Label delete_allocated_handles; |
Label leave_exit_frame; |
Label write_back; |
@@ -782,6 +784,7 @@ void MacroAssembler::CallApiFunctionAndReturn(Address function_address, |
movq(rsi, scheduled_exception_address); |
Cmp(Operand(rsi, 0), factory->the_hole_value()); |
j(not_equal, &promote_scheduled_exception); |
+ bind(&exception_handled); |
#if ENABLE_EXTRA_CHECKS |
// Check if the function returned a valid JavaScript value. |
@@ -818,11 +821,16 @@ void MacroAssembler::CallApiFunctionAndReturn(Address function_address, |
bind(&ok); |
#endif |
- LeaveApiExitFrame(); |
+ bool restore_context = restore_context_offset != 0; |
Michael Starzinger
2013/09/12 18:38:51
Hmpf! The context is not restored when the offset
|
+ if (restore_context) { |
+ movq(rsi, Operand(rbp, restore_context_offset * kPointerSize)); |
+ } |
+ LeaveApiExitFrame(!restore_context); |
ret(stack_space * kPointerSize); |
bind(&promote_scheduled_exception); |
- TailCallRuntime(Runtime::kPromoteScheduledException, 0, 1); |
+ CallRuntime(Runtime::kPromoteScheduledException, 0); |
+ jmp(&exception_handled); |
// HandleScope limit has changed. Delete allocated extensions. |
bind(&delete_allocated_handles); |
@@ -3571,23 +3579,25 @@ void MacroAssembler::LeaveExitFrame(bool save_doubles) { |
PushReturnAddressFrom(rcx); |
- LeaveExitFrameEpilogue(); |
+ LeaveExitFrameEpilogue(true); |
} |
-void MacroAssembler::LeaveApiExitFrame() { |
+void MacroAssembler::LeaveApiExitFrame(bool restore_context) { |
movq(rsp, rbp); |
pop(rbp); |
- LeaveExitFrameEpilogue(); |
+ LeaveExitFrameEpilogue(restore_context); |
} |
-void MacroAssembler::LeaveExitFrameEpilogue() { |
+void MacroAssembler::LeaveExitFrameEpilogue(bool restore_context) { |
// Restore current context from top and clear it in debug mode. |
ExternalReference context_address(Isolate::kContextAddress, isolate()); |
Operand context_operand = ExternalOperand(context_address); |
- movq(rsi, context_operand); |
+ if (restore_context) { |
+ movq(rsi, context_operand); |
+ } |
#ifdef DEBUG |
movq(context_operand, Immediate(0)); |
#endif |