Index: src/ia32/code-stubs-ia32.cc |
diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc |
index 7d70ac343cd0ef368e5959fcfd9db8e746774904..7bf390c60166934caaa22a2dc7ede442f197f6a6 100644 |
--- a/src/ia32/code-stubs-ia32.cc |
+++ b/src/ia32/code-stubs-ia32.cc |
@@ -3887,7 +3887,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) { |
__ IncrementCounter(&Counters::regexp_entry_native, 1); |
static const int kRegExpExecuteArguments = 7; |
- __ PrepareCallCFunction(kRegExpExecuteArguments, ecx); |
+ __ EnterApiExitFrame(kRegExpExecuteArguments); |
// Argument 7: Indicate that this is a direct call from JavaScript. |
__ mov(Operand(esp, 6 * kPointerSize), Immediate(1)); |
@@ -3932,7 +3932,10 @@ void RegExpExecStub::Generate(MacroAssembler* masm) { |
// Locate the code entry and call it. |
__ add(Operand(edx), Immediate(Code::kHeaderSize - kHeapObjectTag)); |
- __ CallCFunction(edx, kRegExpExecuteArguments); |
+ __ call(Operand(edx)); |
+ |
+ // Drop arguments and come back to JS mode. |
+ __ LeaveApiExitFrame(); |
// Check the result. |
Label success; |
@@ -3949,12 +3952,30 @@ void RegExpExecStub::Generate(MacroAssembler* masm) { |
// haven't created the exception yet. Handle that in the runtime system. |
// TODO(592): Rerunning the RegExp to get the stack overflow exception. |
ExternalReference pending_exception(Top::k_pending_exception_address); |
- __ mov(eax, |
+ __ mov(edx, |
Operand::StaticVariable(ExternalReference::the_hole_value_location())); |
- __ cmp(eax, Operand::StaticVariable(pending_exception)); |
+ __ mov(eax, Operand::StaticVariable(pending_exception)); |
+ __ cmp(edx, Operand(eax)); |
__ j(equal, &runtime); |
+ // For exception, throw the exception again. |
+ |
+ // Clear the pending exception variable. |
+ __ mov(Operand::StaticVariable(pending_exception), edx); |
+ |
+ // Special handling of termination exceptions which are uncatchable |
+ // by javascript code. |
+ __ cmp(eax, Factory::termination_exception()); |
+ Label throw_termination_exception; |
+ __ j(equal, &throw_termination_exception); |
+ |
+ // Handle normal exception by following handler chain. |
+ __ Throw(eax); |
+ |
+ __ bind(&throw_termination_exception); |
+ __ ThrowUncatchable(TERMINATION, eax); |
+ |
__ bind(&failure); |
- // For failure and exception return null. |
+ // For failure to match, return null. |
__ mov(Operand(eax), Factory::null_value()); |
__ ret(4 * kPointerSize); |
@@ -4628,34 +4649,7 @@ void CallFunctionStub::Generate(MacroAssembler* masm) { |
void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) { |
- // eax holds the exception. |
- |
- // Adjust this code if not the case. |
- STATIC_ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize); |
- |
- // Drop the sp to the top of the handler. |
- ExternalReference handler_address(Top::k_handler_address); |
- __ mov(esp, Operand::StaticVariable(handler_address)); |
- |
- // Restore next handler and frame pointer, discard handler state. |
- STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); |
- __ pop(Operand::StaticVariable(handler_address)); |
- STATIC_ASSERT(StackHandlerConstants::kFPOffset == 1 * kPointerSize); |
- __ pop(ebp); |
- __ pop(edx); // Remove state. |
- |
- // Before returning we restore the context from the frame pointer if |
- // not NULL. The frame pointer is NULL in the exception handler of |
- // a JS entry frame. |
- __ Set(esi, Immediate(0)); // Tentatively set context pointer to NULL. |
- NearLabel skip; |
- __ cmp(ebp, 0); |
- __ j(equal, &skip, not_taken); |
- __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
- __ bind(&skip); |
- |
- STATIC_ASSERT(StackHandlerConstants::kPCOffset == 3 * kPointerSize); |
- __ ret(0); |
+ __ Throw(eax); |
} |
@@ -4778,52 +4772,7 @@ void CEntryStub::GenerateCore(MacroAssembler* masm, |
void CEntryStub::GenerateThrowUncatchable(MacroAssembler* masm, |
UncatchableExceptionType type) { |
- // Adjust this code if not the case. |
- STATIC_ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize); |
- |
- // Drop sp to the top stack handler. |
- ExternalReference handler_address(Top::k_handler_address); |
- __ mov(esp, Operand::StaticVariable(handler_address)); |
- |
- // Unwind the handlers until the ENTRY handler is found. |
- NearLabel loop, done; |
- __ bind(&loop); |
- // Load the type of the current stack handler. |
- const int kStateOffset = StackHandlerConstants::kStateOffset; |
- __ cmp(Operand(esp, kStateOffset), Immediate(StackHandler::ENTRY)); |
- __ j(equal, &done); |
- // Fetch the next handler in the list. |
- const int kNextOffset = StackHandlerConstants::kNextOffset; |
- __ mov(esp, Operand(esp, kNextOffset)); |
- __ jmp(&loop); |
- __ bind(&done); |
- |
- // Set the top handler address to next handler past the current ENTRY handler. |
- STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); |
- __ pop(Operand::StaticVariable(handler_address)); |
- |
- if (type == OUT_OF_MEMORY) { |
- // Set external caught exception to false. |
- ExternalReference external_caught(Top::k_external_caught_exception_address); |
- __ mov(eax, false); |
- __ mov(Operand::StaticVariable(external_caught), eax); |
- |
- // Set pending exception and eax to out of memory exception. |
- ExternalReference pending_exception(Top::k_pending_exception_address); |
- __ mov(eax, reinterpret_cast<int32_t>(Failure::OutOfMemoryException())); |
- __ mov(Operand::StaticVariable(pending_exception), eax); |
- } |
- |
- // Clear the context pointer. |
- __ Set(esi, Immediate(0)); |
- |
- // Restore fp from handler and discard handler state. |
- STATIC_ASSERT(StackHandlerConstants::kFPOffset == 1 * kPointerSize); |
- __ pop(ebp); |
- __ pop(edx); // State. |
- |
- STATIC_ASSERT(StackHandlerConstants::kPCOffset == 3 * kPointerSize); |
- __ ret(0); |
+ __ ThrowUncatchable(type, eax); |
} |