Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(113)

Unified Diff: src/fast-codegen.cc

Issue 501076: Fast-codegen: Adding support for try/catch and throw. (Closed)
Patch Set: Created 11 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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.
}
« src/compiler.cc ('K') | « src/fast-codegen.h ('k') | src/ia32/fast-codegen-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698