[v8] r3498 committed - Fast-codegen: Adding support for try/catch and throw....

1 view
Skip to first unread message

codesite...@google.com

unread,
Dec 18, 2009, 8:43:22 AM12/18/09
to v8-...@googlegroups.com
Revision: 3498
Author: l...@chromium.org
Date: Fri Dec 18 05:38:28 2009
Log: Fast-codegen: Adding support for try/catch and throw.
Still no support for lookup-variables, so we bailout if using the catch
variable.

Review URL: http://codereview.chromium.org/501076

http://code.google.com/p/v8/source/detail?r=3498

Modified:
/branches/bleeding_edge/src/arm/fast-codegen-arm.cc
/branches/bleeding_edge/src/compiler.cc
/branches/bleeding_edge/src/fast-codegen.cc
/branches/bleeding_edge/src/fast-codegen.h
/branches/bleeding_edge/src/ia32/fast-codegen-ia32.cc
/branches/bleeding_edge/src/x64/fast-codegen-x64.cc

=======================================
--- /branches/bleeding_edge/src/arm/fast-codegen-arm.cc Thu Dec 17 02:23:20
2009
+++ /branches/bleeding_edge/src/arm/fast-codegen-arm.cc Fri Dec 18 05:38:28
2009
@@ -1733,12 +1733,6 @@
__ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value.
__ add(pc, r1, Operand(masm_->CodeObject()));
}
-
-
-void FastCodeGenerator::ThrowException() {
- __ push(result_register());
- __ CallRuntime(Runtime::kThrow, 1);
-}


#undef __
=======================================
--- /branches/bleeding_edge/src/compiler.cc Thu Dec 17 22:38:12 2009
+++ /branches/bleeding_edge/src/compiler.cc Fri Dec 18 05:38:28 2009
@@ -746,7 +746,9 @@


void CodeGenSelector::VisitTryCatchStatement(TryCatchStatement* stmt) {
- BAILOUT("TryCatchStatement");
+ Visit(stmt->try_block());
+ CHECK_BAILOUT;
+ Visit(stmt->catch_block());
}


@@ -876,7 +878,9 @@


void CodeGenSelector::VisitCatchExtensionObject(CatchExtensionObject*
expr) {
- BAILOUT("CatchExtensionObject");
+ ProcessExpression(expr->key(), Expression::kValue);
+ CHECK_BAILOUT;
+ ProcessExpression(expr->value(), Expression::kValue);
}


@@ -926,7 +930,7 @@


void CodeGenSelector::VisitThrow(Throw* expr) {
- BAILOUT("Throw");
+ ProcessExpression(expr->exception(), Expression::kValue);
}


=======================================
--- /branches/bleeding_edge/src/fast-codegen.cc Wed Dec 16 01:51:07 2009
+++ /branches/bleeding_edge/src/fast-codegen.cc Fri Dec 18 05:38:28 2009
@@ -457,11 +457,52 @@


void FastCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) {
- UNREACHABLE();
+ Comment cmnt(masm_, "[ TryCatchStatement");
+ SetStatementPosition(stmt);
+ // The try block adds a handler to the exception handler chain
+ // before entering, and removes it again when exiting normally.
+ // If an exception is thrown during execution of the try block,
+ // control is passed to the handler, which also consumes the handler.
+ // At this point, the exception is in a register, and store it in
+ // the temporary local variable (prints as ".catch-var") before
+ // executing the catch block. The catch block has been rewritten
+ // to introduce a new scope to bind the catch variable and to remove
+ // that scope again afterwards.
+
+ Label try_handler_setup, catch_entry, done;
+
+ __ Call(&try_handler_setup);
+ // 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);
+ Slot* variable_slot = catch_var->slot();
+ 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(&try_handler_setup);
+ {
+ 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.
//
@@ -474,7 +515,7 @@
// its outward control transfer.
// 3. by exiting the try-block with a thrown exception.
// This can happen in nested function calls. It traverses the
try-handler
- // chaing and consumes the try-handler entry before jumping to the
+ // chain and consumes the try-handler entry before jumping to the
// handler code. The handler code then calls the finally-block before
// rethrowing the exception.
//
@@ -497,14 +538,15 @@
// 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 +554,9 @@
__ 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 +707,29 @@


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.
+ ASSERT_EQ(Expression::kValue, expr->key()->context());
+ Visit(expr->key());
+ ASSERT_EQ(Expression::kValue, expr->value()->context());
+ Visit(expr->value());
+
+ // Create catch extension object.
+ __ CallRuntime(Runtime::kCreateCatchExtensionObject, 2);
+
+ __ push(result_register());
}


void FastCodeGenerator::VisitThrow(Throw* expr) {
- UNREACHABLE();
+ Comment cmnt(masm_, "[ Throw");
+ Visit(expr->exception());
+ // Exception is on stack.
+ __ CallRuntime(Runtime::kThrow, 1);
+ // Never returns here.
}


=======================================
--- /branches/bleeding_edge/src/fast-codegen.h Thu Dec 17 02:23:20 2009
+++ /branches/bleeding_edge/src/fast-codegen.h Fri Dec 18 05:38:28 2009
@@ -279,7 +279,6 @@
// Non-local control flow support.
void EnterFinallyBlock();
void ExitFinallyBlock();
- void ThrowException();

// Loop nesting counter.
int loop_depth() { return loop_depth_; }
=======================================
--- /branches/bleeding_edge/src/ia32/fast-codegen-ia32.cc Thu Dec 17
02:23:20 2009
+++ /branches/bleeding_edge/src/ia32/fast-codegen-ia32.cc Fri Dec 18
05:38:28 2009
@@ -1706,11 +1706,6 @@
}


-void FastCodeGenerator::ThrowException() {
- __ push(result_register());
- __ CallRuntime(Runtime::kThrow, 1);
-}
-
#undef __

} } // namespace v8::internal
=======================================
--- /branches/bleeding_edge/src/x64/fast-codegen-x64.cc Thu Dec 17 02:23:20
2009
+++ /branches/bleeding_edge/src/x64/fast-codegen-x64.cc Fri Dec 18 05:38:28
2009
@@ -1723,11 +1723,6 @@
}


-void FastCodeGenerator::ThrowException() {
- __ push(result_register());
- __ CallRuntime(Runtime::kThrow, 1);
-}
-
#undef __


Reply all
Reply to author
Forward
0 new messages