Index: src/full-codegen.cc |
diff --git a/src/full-codegen.cc b/src/full-codegen.cc |
index c9bf2b355cf186bb2aee69e44b69f4da16562ec9..03c55d118ca29114e059adfc06005b58ffa8e82a 100644 |
--- a/src/full-codegen.cc |
+++ b/src/full-codegen.cc |
@@ -21,269 +21,6 @@ |
namespace v8 { |
namespace internal { |
-void BreakableStatementChecker::Check(Statement* stmt) { |
- Visit(stmt); |
-} |
- |
- |
-void BreakableStatementChecker::Check(Expression* expr) { |
- Visit(expr); |
-} |
- |
- |
-void BreakableStatementChecker::VisitVariableDeclaration( |
- VariableDeclaration* decl) { |
-} |
- |
- |
-void BreakableStatementChecker::VisitFunctionDeclaration( |
- FunctionDeclaration* decl) { |
-} |
- |
- |
-void BreakableStatementChecker::VisitImportDeclaration( |
- ImportDeclaration* decl) { |
-} |
- |
- |
-void BreakableStatementChecker::VisitExportDeclaration( |
- ExportDeclaration* decl) { |
-} |
- |
- |
-void BreakableStatementChecker::VisitBlock(Block* stmt) { |
-} |
- |
- |
-void BreakableStatementChecker::VisitExpressionStatement( |
- ExpressionStatement* stmt) { |
- // Check if expression is breakable. |
- Visit(stmt->expression()); |
-} |
- |
- |
-void BreakableStatementChecker::VisitEmptyStatement(EmptyStatement* stmt) { |
-} |
- |
- |
-void BreakableStatementChecker::VisitIfStatement(IfStatement* stmt) { |
- // If the condition is breakable the if statement is breakable. |
- Visit(stmt->condition()); |
-} |
- |
- |
-void BreakableStatementChecker::VisitContinueStatement( |
- ContinueStatement* stmt) { |
-} |
- |
- |
-void BreakableStatementChecker::VisitBreakStatement(BreakStatement* stmt) { |
-} |
- |
- |
-void BreakableStatementChecker::VisitReturnStatement(ReturnStatement* stmt) { |
- // Return is breakable if the expression is. |
- Visit(stmt->expression()); |
-} |
- |
- |
-void BreakableStatementChecker::VisitWithStatement(WithStatement* stmt) { |
- Visit(stmt->expression()); |
-} |
- |
- |
-void BreakableStatementChecker::VisitSwitchStatement(SwitchStatement* stmt) { |
- // Switch statements breakable if the tag expression is. |
- Visit(stmt->tag()); |
-} |
- |
- |
-void BreakableStatementChecker::VisitDoWhileStatement(DoWhileStatement* stmt) { |
- // Mark do while as breakable to avoid adding a break slot in front of it. |
- is_breakable_ = true; |
-} |
- |
- |
-void BreakableStatementChecker::VisitWhileStatement(WhileStatement* stmt) { |
- // Mark while statements breakable if the condition expression is. |
- Visit(stmt->cond()); |
-} |
- |
- |
-void BreakableStatementChecker::VisitForStatement(ForStatement* stmt) { |
- // We set positions for both init and condition, if they exist. |
- if (stmt->cond() != NULL || stmt->init() != NULL) is_breakable_ = true; |
-} |
- |
- |
-void BreakableStatementChecker::VisitForInStatement(ForInStatement* stmt) { |
- // For-in is breakable because we set the position for the enumerable. |
- is_breakable_ = true; |
-} |
- |
- |
-void BreakableStatementChecker::VisitForOfStatement(ForOfStatement* stmt) { |
- // For-of is breakable because we set the position for the next() call. |
- is_breakable_ = true; |
-} |
- |
- |
-void BreakableStatementChecker::VisitTryCatchStatement( |
- TryCatchStatement* stmt) { |
- // Mark try catch as breakable to avoid adding a break slot in front of it. |
- is_breakable_ = true; |
-} |
- |
- |
-void BreakableStatementChecker::VisitTryFinallyStatement( |
- TryFinallyStatement* stmt) { |
- // Mark try finally as breakable to avoid adding a break slot in front of it. |
- is_breakable_ = true; |
-} |
- |
- |
-void BreakableStatementChecker::VisitDebuggerStatement( |
- DebuggerStatement* stmt) { |
- // The debugger statement is breakable. |
- is_breakable_ = true; |
-} |
- |
- |
-void BreakableStatementChecker::VisitCaseClause(CaseClause* clause) { |
-} |
- |
- |
-void BreakableStatementChecker::VisitFunctionLiteral(FunctionLiteral* expr) { |
-} |
- |
- |
-void BreakableStatementChecker::VisitClassLiteral(ClassLiteral* expr) { |
- if (expr->extends() != NULL) { |
- Visit(expr->extends()); |
- } |
-} |
- |
- |
-void BreakableStatementChecker::VisitNativeFunctionLiteral( |
- NativeFunctionLiteral* expr) { |
-} |
- |
- |
-void BreakableStatementChecker::VisitConditional(Conditional* expr) { |
-} |
- |
- |
-void BreakableStatementChecker::VisitVariableProxy(VariableProxy* expr) { |
-} |
- |
- |
-void BreakableStatementChecker::VisitLiteral(Literal* expr) { |
-} |
- |
- |
-void BreakableStatementChecker::VisitRegExpLiteral(RegExpLiteral* expr) { |
-} |
- |
- |
-void BreakableStatementChecker::VisitObjectLiteral(ObjectLiteral* expr) { |
-} |
- |
- |
-void BreakableStatementChecker::VisitArrayLiteral(ArrayLiteral* expr) { |
-} |
- |
- |
-void BreakableStatementChecker::VisitAssignment(Assignment* expr) { |
- // If assigning to a property (including a global property) the assignment is |
- // breakable. |
- VariableProxy* proxy = expr->target()->AsVariableProxy(); |
- Property* prop = expr->target()->AsProperty(); |
- if (prop != NULL || (proxy != NULL && proxy->var()->IsUnallocated())) { |
- is_breakable_ = true; |
- return; |
- } |
- |
- // Otherwise the assignment is breakable if the assigned value is. |
- Visit(expr->value()); |
-} |
- |
- |
-void BreakableStatementChecker::VisitYield(Yield* expr) { |
- // Yield is breakable if the expression is. |
- Visit(expr->expression()); |
-} |
- |
- |
-void BreakableStatementChecker::VisitThrow(Throw* expr) { |
- // Throw is breakable if the expression is. |
- Visit(expr->exception()); |
-} |
- |
- |
-void BreakableStatementChecker::VisitProperty(Property* expr) { |
- // Property load is breakable. |
- is_breakable_ = true; |
-} |
- |
- |
-void BreakableStatementChecker::VisitCall(Call* expr) { |
- // Function calls both through IC and call stub are breakable. |
- is_breakable_ = true; |
-} |
- |
- |
-void BreakableStatementChecker::VisitCallNew(CallNew* expr) { |
- // Function calls through new are breakable. |
- is_breakable_ = true; |
-} |
- |
- |
-void BreakableStatementChecker::VisitCallRuntime(CallRuntime* expr) { |
-} |
- |
- |
-void BreakableStatementChecker::VisitUnaryOperation(UnaryOperation* expr) { |
- Visit(expr->expression()); |
-} |
- |
- |
-void BreakableStatementChecker::VisitCountOperation(CountOperation* expr) { |
- Visit(expr->expression()); |
-} |
- |
- |
-void BreakableStatementChecker::VisitBinaryOperation(BinaryOperation* expr) { |
- Visit(expr->left()); |
- if (expr->op() != Token::AND && |
- expr->op() != Token::OR) { |
- Visit(expr->right()); |
- } |
-} |
- |
- |
-void BreakableStatementChecker::VisitCompareOperation(CompareOperation* expr) { |
- Visit(expr->left()); |
- Visit(expr->right()); |
-} |
- |
- |
-void BreakableStatementChecker::VisitSpread(Spread* expr) { |
- Visit(expr->expression()); |
-} |
- |
- |
-void BreakableStatementChecker::VisitThisFunction(ThisFunction* expr) { |
-} |
- |
- |
-void BreakableStatementChecker::VisitSuperPropertyReference( |
- SuperPropertyReference* expr) {} |
- |
- |
-void BreakableStatementChecker::VisitSuperCallReference( |
- SuperCallReference* expr) {} |
- |
- |
#define __ ACCESS_MASM(masm()) |
bool FullCodeGenerator::MakeCode(CompilationInfo* info) { |
@@ -670,79 +407,67 @@ int FullCodeGenerator::DeclareGlobalsFlags() { |
} |
+bool RecordStatementPosition(MacroAssembler* masm, int pos) { |
+ if (pos == RelocInfo::kNoPosition) return false; |
+ masm->positions_recorder()->RecordStatementPosition(pos); |
+ masm->positions_recorder()->RecordPosition(pos); |
+ return masm->positions_recorder()->WriteRecordedPositions(); |
+} |
+ |
+ |
+bool RecordPosition(MacroAssembler* masm, int pos) { |
+ if (pos == RelocInfo::kNoPosition) return false; |
+ masm->positions_recorder()->RecordPosition(pos); |
+ return masm->positions_recorder()->WriteRecordedPositions(); |
+} |
+ |
+ |
void FullCodeGenerator::SetFunctionPosition(FunctionLiteral* fun) { |
- CodeGenerator::RecordPositions(masm_, fun->start_position()); |
+ RecordPosition(masm_, fun->start_position()); |
} |
void FullCodeGenerator::SetReturnPosition(FunctionLiteral* fun) { |
- CodeGenerator::RecordPositions(masm_, fun->end_position() - 1); |
+ RecordStatementPosition(masm_, fun->end_position() - 1); |
} |
-void FullCodeGenerator::SetStatementPosition(Statement* stmt) { |
- if (!info_->is_debug()) { |
- CodeGenerator::RecordPositions(masm_, stmt->position()); |
- } else { |
- // Check if the statement will be breakable without adding a debug break |
- // slot. |
- BreakableStatementChecker checker(info_->isolate(), zone()); |
- checker.Check(stmt); |
- // Record the statement position right here if the statement is not |
- // breakable. For breakable statements the actual recording of the |
- // position will be postponed to the breakable code (typically an IC). |
- bool position_recorded = CodeGenerator::RecordPositions( |
- masm_, stmt->position(), !checker.is_breakable()); |
- // If the position recording did record a new position generate a debug |
- // break slot to make the statement breakable. |
- if (position_recorded) { |
- DebugCodegen::GenerateSlot(masm_); |
- } |
+void FullCodeGenerator::SetStatementPosition( |
+ Statement* stmt, FullCodeGenerator::InsertBreak insert_break) { |
+ if (stmt->position() == RelocInfo::kNoPosition) return; |
+ bool recorded = RecordStatementPosition(masm_, stmt->position()); |
+ if (recorded && insert_break == INSERT_BREAK && info_->is_debug() && |
+ !stmt->IsDebuggerStatement()) { |
+ DebugCodegen::GenerateSlot(masm_); |
} |
} |
-void FullCodeGenerator::VisitSuperPropertyReference( |
- SuperPropertyReference* super) { |
- __ CallRuntime(Runtime::kThrowUnsupportedSuperError, 0); |
+void FullCodeGenerator::SetExpressionPosition( |
+ Expression* expr, FullCodeGenerator::InsertBreak insert_break) { |
+ if (expr->position() == RelocInfo::kNoPosition) return; |
+ bool recorded = RecordPosition(masm_, expr->position()); |
+ if (recorded && insert_break == INSERT_BREAK && info_->is_debug()) { |
+ DebugCodegen::GenerateSlot(masm_); |
+ } |
} |
-void FullCodeGenerator::VisitSuperCallReference(SuperCallReference* super) { |
- __ CallRuntime(Runtime::kThrowUnsupportedSuperError, 0); |
+void FullCodeGenerator::SetExpressionAsStatementPosition(Expression* expr) { |
+ if (expr->position() == RelocInfo::kNoPosition) return; |
+ bool recorded = RecordStatementPosition(masm_, expr->position()); |
+ if (recorded && info_->is_debug()) DebugCodegen::GenerateSlot(masm_); |
} |
-void FullCodeGenerator::SetExpressionPosition(Expression* expr) { |
- if (!info_->is_debug()) { |
- CodeGenerator::RecordPositions(masm_, expr->position()); |
- } else { |
- // Check if the expression will be breakable without adding a debug break |
- // slot. |
- BreakableStatementChecker checker(info_->isolate(), zone()); |
- checker.Check(expr); |
- // Record a statement position right here if the expression is not |
- // breakable. For breakable expressions the actual recording of the |
- // position will be postponed to the breakable code (typically an IC). |
- // NOTE this will record a statement position for something which might |
- // not be a statement. As stepping in the debugger will only stop at |
- // statement positions this is used for e.g. the condition expression of |
- // a do while loop. |
- bool position_recorded = CodeGenerator::RecordPositions( |
- masm_, expr->position(), !checker.is_breakable()); |
- // If the position recording did record a new position generate a debug |
- // break slot to make the statement breakable. |
- if (position_recorded) { |
- DebugCodegen::GenerateSlot(masm_); |
- } |
- } |
+void FullCodeGenerator::VisitSuperPropertyReference( |
+ SuperPropertyReference* super) { |
+ __ CallRuntime(Runtime::kThrowUnsupportedSuperError, 0); |
} |
-void FullCodeGenerator::SetSourcePosition(int pos) { |
- if (pos != RelocInfo::kNoPosition) { |
- masm_->positions_recorder()->RecordPosition(pos); |
- } |
+void FullCodeGenerator::VisitSuperCallReference(SuperCallReference* super) { |
+ __ CallRuntime(Runtime::kThrowUnsupportedSuperError, 0); |
} |
@@ -878,7 +603,7 @@ void FullCodeGenerator::VisitArithmeticExpression(BinaryOperation* expr) { |
VisitForStackValue(left); |
VisitForAccumulatorValue(right); |
- SetSourcePosition(expr->position()); |
+ SetExpressionPosition(expr); |
if (ShouldInlineSmiCase(op)) { |
EmitInlineSmiBinaryOp(expr, op, left, right); |
} else { |
@@ -1060,7 +785,9 @@ void FullCodeGenerator::VisitWithStatement(WithStatement* stmt) { |
void FullCodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) { |
Comment cmnt(masm_, "[ DoWhileStatement"); |
- SetStatementPosition(stmt); |
+ // Do not insert break location as we do that below. |
+ SetStatementPosition(stmt, SKIP_BREAK); |
+ |
Label body, book_keeping; |
Iteration loop_statement(this, stmt); |
@@ -1073,7 +800,9 @@ void FullCodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) { |
// possible to break on the condition. |
__ bind(loop_statement.continue_label()); |
PrepareForBailoutForId(stmt->ContinueId(), NO_REGISTERS); |
- SetExpressionPosition(stmt->cond()); |
+ |
+ // Here is the actual 'while' keyword. |
+ SetExpressionAsStatementPosition(stmt->cond()); |
VisitForControl(stmt->cond(), |
&book_keeping, |
loop_statement.break_label(), |
@@ -1100,7 +829,7 @@ void FullCodeGenerator::VisitWhileStatement(WhileStatement* stmt) { |
__ bind(&loop); |
- SetExpressionPosition(stmt->cond()); |
+ SetExpressionAsStatementPosition(stmt->cond()); |
VisitForControl(stmt->cond(), |
&body, |
loop_statement.break_label(), |
@@ -1124,13 +853,13 @@ void FullCodeGenerator::VisitWhileStatement(WhileStatement* stmt) { |
void FullCodeGenerator::VisitForStatement(ForStatement* stmt) { |
Comment cmnt(masm_, "[ ForStatement"); |
+ // Do not insert break location as we do it below. |
+ SetStatementPosition(stmt, SKIP_BREAK); |
+ |
Label test, body; |
Iteration loop_statement(this, stmt); |
- // Set statement position for a break slot before entering the for-body. |
- SetStatementPosition(stmt); |
- |
if (stmt->init() != NULL) { |
SetStatementPosition(stmt->init()); |
Visit(stmt->init()); |
@@ -1151,16 +880,12 @@ void FullCodeGenerator::VisitForStatement(ForStatement* stmt) { |
Visit(stmt->next()); |
} |
- // Emit the statement position here as this is where the for |
- // statement code starts. |
- SetStatementPosition(stmt); |
- |
// Check stack before looping. |
EmitBackEdgeBookkeeping(stmt, &body); |
__ bind(&test); |
if (stmt->cond() != NULL) { |
- SetExpressionPosition(stmt->cond()); |
+ SetExpressionAsStatementPosition(stmt->cond()); |
VisitForControl(stmt->cond(), |
&body, |
loop_statement.break_label(), |
@@ -1177,7 +902,6 @@ void FullCodeGenerator::VisitForStatement(ForStatement* stmt) { |
void FullCodeGenerator::VisitForOfStatement(ForOfStatement* stmt) { |
Comment cmnt(masm_, "[ ForOfStatement"); |
- SetStatementPosition(stmt); |
Iteration loop_statement(this, stmt); |
increment_loop_depth(); |
@@ -1189,7 +913,7 @@ void FullCodeGenerator::VisitForOfStatement(ForOfStatement* stmt) { |
__ bind(loop_statement.continue_label()); |
// result = iterator.next() |
- SetExpressionPosition(stmt->next_result()); |
+ SetExpressionAsStatementPosition(stmt->next_result()); |
VisitForEffect(stmt->next_result()); |
// if (result.done) break; |
@@ -1218,7 +942,8 @@ void FullCodeGenerator::VisitForOfStatement(ForOfStatement* stmt) { |
void FullCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) { |
Comment cmnt(masm_, "[ TryCatchStatement"); |
- SetStatementPosition(stmt); |
+ SetStatementPosition(stmt, SKIP_BREAK); |
+ |
// 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, the handler is consumed |
@@ -1271,7 +996,8 @@ void FullCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) { |
void FullCodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) { |
Comment cmnt(masm_, "[ TryFinallyStatement"); |
- SetStatementPosition(stmt); |
+ SetStatementPosition(stmt, SKIP_BREAK); |
+ |
// Try finally is compiled by setting up a try-handler on the stack while |
// executing the try body, and removing it again afterwards. |
// |
@@ -1487,7 +1213,7 @@ void FullCodeGenerator::VisitNativeFunctionLiteral( |
void FullCodeGenerator::VisitThrow(Throw* expr) { |
Comment cmnt(masm_, "[ Throw"); |
VisitForStackValue(expr->exception()); |
- SetSourcePosition(expr->position()); |
+ SetExpressionPosition(expr); |
__ CallRuntime(Runtime::kThrow, 1); |
// Never returns here. |
} |