Index: src/fast-codegen.cc |
diff --git a/src/fast-codegen.cc b/src/fast-codegen.cc |
index 1bdc367137e1e8392532667287ec0445bd471bc4..e01da2d5e9bac67ad9e2ec2d406d8aebcb6bc10d 100644 |
--- a/src/fast-codegen.cc |
+++ b/src/fast-codegen.cc |
@@ -36,7 +36,7 @@ |
namespace v8 { |
namespace internal { |
-#define __ ACCESS_MASM(masm_) |
+#define __ ACCESS_MASM(masm()) |
Handle<Code> FastCodeGenerator::MakeCode(FunctionLiteral* fun, |
Handle<Script> script, |
@@ -232,8 +232,11 @@ void FastCodeGenerator::EmitLogicalOperation(BinaryOperation* expr) { |
void FastCodeGenerator::VisitBlock(Block* stmt) { |
Comment cmnt(masm_, "[ Block"); |
+ Label end_of_block; |
+ Breakable nested_statement(this, stmt, &end_of_block); |
Kevin Millikin (Chromium)
2009/12/10 13:09:26
If the label is part of the state of the Breakable
|
SetStatementPosition(stmt); |
VisitStatements(stmt->statements()); |
+ __ bind(&end_of_block); |
Kevin Millikin (Chromium)
2009/12/10 13:09:26
And
__ bind(nested_statement.break_target());
|
} |
@@ -278,15 +281,60 @@ void FastCodeGenerator::VisitIfStatement(IfStatement* stmt) { |
void FastCodeGenerator::VisitContinueStatement(ContinueStatement* stmt) { |
- UNREACHABLE(); |
+ NestedStatement* current = nesting_stack_; |
Kevin Millikin (Chromium)
2009/12/10 13:09:26
Might be nice to have a codegen comment "[ Continu
Lasse Reichstein
2009/12/10 13:55:32
Fixed
|
+ int stack_depth = 0; |
+ while (!current->IsContinueTarget(stmt->target())) { |
+ stack_depth = current->Exit(stack_depth); |
+ current = current->outer(); |
+ } |
+ __ Drop(stack_depth); |
+ |
+ Iteration* loop = current->AsIteration(); |
+ __ jmp(loop->continue_target()); |
} |
void FastCodeGenerator::VisitBreakStatement(BreakStatement* stmt) { |
- UNREACHABLE(); |
+ NestedStatement* current = nesting_stack_; |
+ int stack_depth = 0; |
+ while (!current->IsBreakTarget(stmt->target())) { |
+ stack_depth = current->Exit(stack_depth); |
+ current = current->outer(); |
+ } |
+ __ Drop(stack_depth); |
+ |
+ Breakable* target = current->AsBreakable(); |
+ __ jmp(target->break_target()); |
} |
+void FastCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { |
+ Comment cmnt(masm_, "[ ReturnStatement"); |
+ Expression* expr = stmt->expression(); |
+ // Complete the statement based on the type of the subexpression. |
+ if (expr->AsLiteral() != NULL) { |
+ __ Move(result_register(), expr->AsLiteral()->handle()); |
+ } else { |
+ ASSERT_EQ(Expression::kValue, expr->context()); |
+ Visit(expr); |
+ __ pop(result_register()); |
+ } |
+ |
+ // Exit all nested statements. |
+ NestedStatement* current = nesting_stack_; |
+ int stack_depth = 0; |
+ while (current != NULL) { |
+ stack_depth = current->Exit(stack_depth); |
+ current = current->outer(); |
+ } |
+ __ Drop(stack_depth); |
+ |
+ EmitReturnSequence(stmt->statement_pos()); |
+} |
+ |
+ |
+ |
+ |
void FastCodeGenerator::VisitWithEnterStatement(WithEnterStatement* stmt) { |
UNREACHABLE(); |
} |
@@ -304,10 +352,12 @@ void FastCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { |
void FastCodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) { |
Comment cmnt(masm_, "[ DoWhileStatement"); |
+ Label body, test, exit, stack_limit_hit, stack_check_success; |
Kevin Millikin (Chromium)
2009/12/10 13:09:26
exit and test could be fields of the Iteration.
|
+ |
increment_loop_depth(); |
Kevin Millikin (Chromium)
2009/12/10 13:28:28
Another comment: it seems nicer to properly nest t
Lasse Reichstein
2009/12/10 13:55:32
Fixed
|
- Label body, exit, stack_limit_hit, stack_check_success; |
__ bind(&body); |
+ Iteration loop_statement(this, stmt, &exit, &test); |
Visit(stmt->body()); |
// Check stack before looping. |
@@ -316,6 +366,7 @@ void FastCodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) { |
// We are not in an expression context because we have been compiling |
// statements. Set up a test expression context for the condition. |
+ __ bind(&test); |
Kevin Millikin (Chromium)
2009/12/10 13:09:26
__ bind(loop_statement.continue_target());
|
ASSERT_EQ(NULL, true_label_); |
ASSERT_EQ(NULL, false_label_); |
true_label_ = &body; |
@@ -338,13 +389,15 @@ void FastCodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) { |
void FastCodeGenerator::VisitWhileStatement(WhileStatement* stmt) { |
Comment cmnt(masm_, "[ WhileStatement"); |
- increment_loop_depth(); |
Label test, body, exit, stack_limit_hit, stack_check_success; |
+ increment_loop_depth(); |
+ |
// Emit the test at the bottom of the loop. |
__ jmp(&test); |
__ bind(&body); |
+ Iteration loop_stamt(this, stmt, &exit, &test); |
Kevin Millikin (Chromium)
2009/12/10 13:09:26
loop_statement? loop_stmt?
Lasse Reichstein
2009/12/10 13:55:32
Odd typo. Fixed.
|
Visit(stmt->body()); |
__ bind(&test); |
@@ -369,26 +422,30 @@ void FastCodeGenerator::VisitWhileStatement(WhileStatement* stmt) { |
__ jmp(&stack_check_success); |
__ bind(&exit); |
- |
decrement_loop_depth(); |
} |
void FastCodeGenerator::VisitForStatement(ForStatement* stmt) { |
Comment cmnt(masm_, "[ ForStatement"); |
- Label test, body, exit, stack_limit_hit, stack_check_success; |
+ Label test, body, next, exit, stack_limit_hit, stack_check_success; |
if (stmt->init() != NULL) Visit(stmt->init()); |
increment_loop_depth(); |
+ |
// Emit the test at the bottom of the loop (even if empty). |
__ jmp(&test); |
+ |
__ bind(&body); |
+ Iteration loop_stamt(this, stmt, &exit, &next); |
Kevin Millikin (Chromium)
2009/12/10 13:09:26
loop_statement?
|
Visit(stmt->body()); |
// Check stack before looping. |
__ StackLimitCheck(&stack_limit_hit); |
__ bind(&stack_check_success); |
+ __ bind(&next); |
+ |
if (stmt->next() != NULL) Visit(stmt->next()); |
__ bind(&test); |
@@ -416,6 +473,7 @@ void FastCodeGenerator::VisitForStatement(ForStatement* stmt) { |
__ jmp(&stack_check_success); |
__ bind(&exit); |
+ |
decrement_loop_depth(); |
} |
@@ -554,6 +612,21 @@ void FastCodeGenerator::VisitThrow(Throw* expr) { |
} |
+int FastCodeGenerator::TryFinally::Exit(int stack_depth) { |
+ __ Drop(stack_depth); |
Kevin Millikin (Chromium)
2009/12/10 13:09:26
Good. I much prefer adjusting the stack pointer t
|
+ __ PopTryHandler(); |
+ __ Call(finally_entry_); |
+ return 0; |
+} |
+ |
+ |
+int FastCodeGenerator::TryCatch::Exit(int stack_depth) { |
+ __ Drop(stack_depth); |
+ __ PopTryHandler(); |
+ return 0; |
+} |
+ |
+ |
#undef __ |