Index: src/fast-codegen.cc |
diff --git a/src/fast-codegen.cc b/src/fast-codegen.cc |
index b15a673552b9725aed766af96d9a78d9d02245cd..b2f62b68294025bb9b3c4c71128eaef1aa8c5ed0 100644 |
--- a/src/fast-codegen.cc |
+++ b/src/fast-codegen.cc |
@@ -457,11 +457,44 @@ void FastCodeGenerator::VisitForInStatement(ForInStatement* stmt) { |
void FastCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) { |
- UNREACHABLE(); |
+ Comment cmnt(masm_, "[ TryCatchStatement"); |
+ SetStatementPosition(stmt); |
+ |
+ Label setup_try_handler, catch_entry, done; |
Kevin Millikin (Chromium)
2009/12/17 14:36:16
This isn't as complicated as TryFinally, but I mis
|
+ |
+ __ Call(&setup_try_handler); |
Kevin Millikin (Chromium)
2009/12/17 14:36:16
You called this 'try_handler_setup' in TryFinally
|
+ // Try handler code, exception in result register. |
+ |
+ // Store exception in local .catch variable before executing catch block. |
+ { |
+ // The catch variable is *always* a variable proxy for a local variable. |
+ Variable* catch_var = stmt->catch_var()->AsVariableProxy()->AsVariable(); |
+ ASSERT_NOT_NULL(catch_var); |
+ ASSERT_EQ(Variable::TEMPORARY, catch_var->mode()); |
Kevin Millikin (Chromium)
2009/12/17 14:36:16
I think this is true, but the code doesn't depend
|
+ Slot* variable_slot = catch_var->rewrite()->AsSlot(); |
Kevin Millikin (Chromium)
2009/12/17 14:36:16
No need for catch_var->rewrite()->AsSlot(), catch_
|
+ ASSERT_NOT_NULL(variable_slot); |
+ ASSERT_EQ(Slot::LOCAL, variable_slot->type()); |
+ StoreToFrameField(SlotOffset(variable_slot), result_register()); |
+ } |
+ |
+ Visit(stmt->catch_block()); |
+ __ jmp(&done); |
+ |
+ // Try block code. Sets up the exception handler chain. |
+ __ bind(&setup_try_handler); |
+ { |
+ TryCatch try_block(this, &catch_entry); |
+ __ PushTryHandler(IN_JAVASCRIPT, TRY_CATCH_HANDLER); |
+ Visit(stmt->try_block()); |
+ __ PopTryHandler(); |
+ } |
+ __ bind(&done); |
} |
void FastCodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) { |
+ Comment cmnt(masm_, "[ TryFinallyStatement"); |
+ SetStatementPosition(stmt); |
// Try finally is compiled by setting up a try-handler on the stack while |
// executing the try body, and removing it again afterwards. |
// |
@@ -497,14 +530,15 @@ void FastCodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) { |
// is retained by the finally block. |
// Call the finally block and then rethrow the exception. |
__ Call(&finally_entry); |
- ThrowException(); |
+ __ push(result_register()); |
+ __ CallRuntime(Runtime::kReThrow, 1); |
} |
__ bind(&finally_entry); |
{ |
// Finally block implementation. |
- EnterFinallyBlock(); |
Finally finally_block(this); |
+ EnterFinallyBlock(); |
Visit(stmt->finally_block()); |
ExitFinallyBlock(); // Return to the calling code. |
} |
@@ -512,9 +546,9 @@ void FastCodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) { |
__ bind(&try_handler_setup); |
{ |
// Setup try handler (stack pointer registers). |
- __ PushTryHandler(IN_JAVASCRIPT, TRY_FINALLY_HANDLER); |
TryFinally try_block(this, &finally_entry); |
- VisitStatements(stmt->try_block()->statements()); |
+ __ PushTryHandler(IN_JAVASCRIPT, TRY_FINALLY_HANDLER); |
+ Visit(stmt->try_block()); |
__ PopTryHandler(); |
} |
// Execute the finally block on the way out. |
@@ -665,12 +699,37 @@ void FastCodeGenerator::VisitAssignment(Assignment* expr) { |
void FastCodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* expr) { |
- UNREACHABLE(); |
+ // Call runtime routine to allocate the catch extension object and |
+ // assign the exception value to the catch variable. |
+ Comment cmnt(masm_, "[ CatchExtensionObject"); |
+ |
+ // Push key string. |
+ Move(Expression::kValue, expr->key()); |
Kevin Millikin (Chromium)
2009/12/17 14:36:16
Seems just as simple to compile the key and variab
|
+ |
+ // Push .catch variable content. |
+ Variable* exception_variable = expr->value()->AsVariable(); |
+ // The variable is always a temporary local. |
+ ASSERT_NOT_NULL(exception_variable); |
+ ASSERT_EQ(Variable::TEMPORARY, exception_variable->mode()); |
+ Slot* variable_slot = exception_variable->rewrite()->AsSlot(); |
+ ASSERT_NOT_NULL(variable_slot); |
+ ASSERT_EQ(Slot::LOCAL, variable_slot->type()); |
+ // Use result register as scratch register (if necessary). |
+ Move(Expression::kValue, variable_slot, result_register()); |
+ |
+ // Create catch extension object. |
+ __ CallRuntime(Runtime::kCreateCatchExtensionObject, 2); |
+ |
+ __ push(result_register()); |
} |
void FastCodeGenerator::VisitThrow(Throw* expr) { |
- UNREACHABLE(); |
+ Comment cmnt(masm_, "[ Throw"); |
+ Visit(expr->exception()); |
Kevin Millikin (Chromium)
2009/12/17 14:36:16
Might assert the expression context is value.
|
+ // Exception is on stack. |
+ __ CallRuntime(Runtime::kThrow, 1); |
+ // Never returns here. |
} |