Index: src/rewriter.cc |
diff --git a/src/rewriter.cc b/src/rewriter.cc |
index 110a6ccdf98b99ea7928592582c518978463cb95..2de25407e3fe608bb95857be826023be69b83ac4 100644 |
--- a/src/rewriter.cc |
+++ b/src/rewriter.cc |
@@ -16,6 +16,7 @@ class Processor: public AstVisitor { |
Processor(Isolate* isolate, Variable* result, |
AstValueFactory* ast_value_factory) |
: result_(result), |
+ replacement_(nullptr), |
is_set_(false), |
factory_(ast_value_factory) { |
InitializeAstVisitor(isolate, ast_value_factory->zone()); |
@@ -30,6 +31,10 @@ class Processor: public AstVisitor { |
private: |
Variable* result_; |
+ // When visiting a node, we "return" a replacement for that node in |
+ // [replacement_]. In many cases this will just be the original node. |
+ Statement* replacement_; |
+ |
// To avoid storing to .result all the time, we eliminate some of |
// the stores by keeping track of whether or not we're sure .result |
// will be overwritten anyway. This is a bit more tricky than what I |
@@ -58,6 +63,7 @@ class Processor: public AstVisitor { |
void Processor::Process(ZoneList<Statement*>* statements) { |
for (int i = statements->length() - 1; i >= 0; --i) { |
Visit(statements->at(i)); |
+ statements->Set(i, replacement_); |
rossberg
2015/09/28 11:42:15
How about treating replacement_ as an option and c
|
} |
} |
@@ -72,6 +78,7 @@ void Processor::VisitBlock(Block* node) { |
// returns 'undefined'. To obtain the same behavior with v8, we need |
// to prevent rewriting in that case. |
if (!node->ignore_completion_value()) Process(node->statements()); |
+ replacement_ = node; |
} |
@@ -81,6 +88,7 @@ void Processor::VisitExpressionStatement(ExpressionStatement* node) { |
node->set_expression(SetResult(node->expression())); |
is_set_ = true; |
} |
+ replacement_ = node; |
} |
@@ -88,10 +96,13 @@ void Processor::VisitIfStatement(IfStatement* node) { |
// Rewrite both branches. |
bool set_after = is_set_; |
Visit(node->then_statement()); |
+ node->set_then_statement(replacement_); |
bool set_in_then = is_set_; |
is_set_ = set_after; |
Visit(node->else_statement()); |
+ node->set_else_statement(replacement_); |
is_set_ = is_set_ && set_in_then; |
+ replacement_ = node; |
} |
@@ -100,7 +111,9 @@ void Processor::VisitIterationStatement(IterationStatement* node) { |
bool set_after = is_set_; |
is_set_ = false; // We are in a loop, so we can't rely on [set_after]. |
Visit(node->body()); |
+ node->set_body(replacement_); |
is_set_ = is_set_ && set_after; |
+ replacement_ = node; |
} |
@@ -133,17 +146,23 @@ void Processor::VisitTryCatchStatement(TryCatchStatement* node) { |
// Rewrite both try and catch block. |
bool set_after = is_set_; |
Visit(node->try_block()); |
+ node->set_try_block(static_cast<Block*>(replacement_)); |
bool set_in_try = is_set_; |
is_set_ = set_after; |
Visit(node->catch_block()); |
+ node->set_catch_block(static_cast<Block*>(replacement_)); |
is_set_ = is_set_ && set_in_try; |
+ replacement_ = node; |
} |
void Processor::VisitTryFinallyStatement(TryFinallyStatement* node) { |
// Rewrite both try and finally block (in reverse order). |
Visit(node->finally_block()); |
- Visit(node->try_block()); |
+ node->set_finally_block(static_cast<Block*>(replacement_)); |
+ Visit(node->try_block()); // Exception will not be caught. |
+ node->set_try_block(static_cast<Block*>(replacement_)); |
+ replacement_ = node; |
} |
@@ -156,36 +175,51 @@ void Processor::VisitSwitchStatement(SwitchStatement* node) { |
Process(clause->statements()); |
} |
is_set_ = is_set_ && set_after; |
+ replacement_ = node; |
} |
void Processor::VisitContinueStatement(ContinueStatement* node) { |
is_set_ = false; |
+ replacement_ = node; |
} |
void Processor::VisitBreakStatement(BreakStatement* node) { |
is_set_ = false; |
+ replacement_ = node; |
} |
void Processor::VisitWithStatement(WithStatement* node) { |
Visit(node->statement()); |
+ node->set_statement(replacement_); |
+ replacement_ = node; |
} |
void Processor::VisitSloppyBlockFunctionStatement( |
SloppyBlockFunctionStatement* node) { |
Visit(node->statement()); |
+ node->set_statement(replacement_); |
+ replacement_ = node; |
} |
-void Processor::VisitReturnStatement(ReturnStatement* node) { is_set_ = true; } |
+void Processor::VisitEmptyStatement(EmptyStatement* node) { |
+ replacement_ = node; |
+} |
-// Do nothing: |
-void Processor::VisitEmptyStatement(EmptyStatement* node) {} |
-void Processor::VisitDebuggerStatement(DebuggerStatement* node) {} |
+void Processor::VisitReturnStatement(ReturnStatement* node) { |
+ is_set_ = true; |
+ replacement_ = node; |
+} |
+ |
+ |
+void Processor::VisitDebuggerStatement(DebuggerStatement* node) { |
+ replacement_ = node; |
+} |
// Expressions are never visited. |