Commit af33cccf authored by neis's avatar neis Committed by Commit bot

Enable visitor in rewriter to replace statements.

This is in preparation of implementing ES6 completion semantics and
depends on #1362333002.

R=rossberg
BUG=

Review URL: https://codereview.chromium.org/1362363002

Cr-Commit-Position: refs/heads/master@{#31041}
parent 7a6f47fe
...@@ -640,6 +640,7 @@ class IterationStatement : public BreakableStatement { ...@@ -640,6 +640,7 @@ class IterationStatement : public BreakableStatement {
IterationStatement* AsIterationStatement() final { return this; } IterationStatement* AsIterationStatement() final { return this; }
Statement* body() const { return body_; } Statement* body() const { return body_; }
void set_body(Statement* s) { body_ = s; }
static int num_ids() { return parent_num_ids() + 1; } static int num_ids() { return parent_num_ids() + 1; }
BailoutId OsrEntryId() const { return BailoutId(local_id(0)); } BailoutId OsrEntryId() const { return BailoutId(local_id(0)); }
...@@ -988,6 +989,7 @@ class WithStatement final : public Statement { ...@@ -988,6 +989,7 @@ class WithStatement final : public Statement {
Scope* scope() { return scope_; } Scope* scope() { return scope_; }
Expression* expression() const { return expression_; } Expression* expression() const { return expression_; }
Statement* statement() const { return statement_; } Statement* statement() const { return statement_; }
void set_statement(Statement* s) { statement_ = s; }
void set_base_id(int id) { base_id_ = id; } void set_base_id(int id) { base_id_ = id; }
static int num_ids() { return parent_num_ids() + 1; } static int num_ids() { return parent_num_ids() + 1; }
...@@ -1092,6 +1094,9 @@ class IfStatement final : public Statement { ...@@ -1092,6 +1094,9 @@ class IfStatement final : public Statement {
Statement* then_statement() const { return then_statement_; } Statement* then_statement() const { return then_statement_; }
Statement* else_statement() const { return else_statement_; } Statement* else_statement() const { return else_statement_; }
void set_then_statement(Statement* s) { then_statement_ = s; }
void set_else_statement(Statement* s) { else_statement_ = s; }
bool IsJump() const override { bool IsJump() const override {
return HasThenStatement() && then_statement()->IsJump() return HasThenStatement() && then_statement()->IsJump()
&& HasElseStatement() && else_statement()->IsJump(); && HasElseStatement() && else_statement()->IsJump();
...@@ -1131,6 +1136,7 @@ class IfStatement final : public Statement { ...@@ -1131,6 +1136,7 @@ class IfStatement final : public Statement {
class TryStatement : public Statement { class TryStatement : public Statement {
public: public:
Block* try_block() const { return try_block_; } Block* try_block() const { return try_block_; }
void set_try_block(Block* b) { try_block_ = b; }
void set_base_id(int id) { base_id_ = id; } void set_base_id(int id) { base_id_ = id; }
static int num_ids() { return parent_num_ids() + 1; } static int num_ids() { return parent_num_ids() + 1; }
...@@ -1163,6 +1169,7 @@ class TryCatchStatement final : public TryStatement { ...@@ -1163,6 +1169,7 @@ class TryCatchStatement final : public TryStatement {
Scope* scope() { return scope_; } Scope* scope() { return scope_; }
Variable* variable() { return variable_; } Variable* variable() { return variable_; }
Block* catch_block() const { return catch_block_; } Block* catch_block() const { return catch_block_; }
void set_catch_block(Block* b) { catch_block_ = b; }
protected: protected:
TryCatchStatement(Zone* zone, Block* try_block, Scope* scope, TryCatchStatement(Zone* zone, Block* try_block, Scope* scope,
...@@ -1184,6 +1191,7 @@ class TryFinallyStatement final : public TryStatement { ...@@ -1184,6 +1191,7 @@ class TryFinallyStatement final : public TryStatement {
DECLARE_NODE_TYPE(TryFinallyStatement) DECLARE_NODE_TYPE(TryFinallyStatement)
Block* finally_block() const { return finally_block_; } Block* finally_block() const { return finally_block_; }
void set_finally_block(Block* b) { finally_block_ = b; }
protected: protected:
TryFinallyStatement(Zone* zone, Block* try_block, Block* finally_block, TryFinallyStatement(Zone* zone, Block* try_block, Block* finally_block,
......
...@@ -17,6 +17,7 @@ class Processor: public AstVisitor { ...@@ -17,6 +17,7 @@ class Processor: public AstVisitor {
AstValueFactory* ast_value_factory) AstValueFactory* ast_value_factory)
: result_(result), : result_(result),
result_assigned_(false), result_assigned_(false),
replacement_(nullptr),
is_set_(false), is_set_(false),
factory_(ast_value_factory) { factory_(ast_value_factory) {
InitializeAstVisitor(isolate, ast_value_factory->zone()); InitializeAstVisitor(isolate, ast_value_factory->zone());
...@@ -38,6 +39,10 @@ class Processor: public AstVisitor { ...@@ -38,6 +39,10 @@ class Processor: public AstVisitor {
// there was ever an assignment to result_. // there was ever an assignment to result_.
bool result_assigned_; bool result_assigned_;
// 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 // 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 // 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 // will be overwritten anyway. This is a bit more tricky than what I
...@@ -67,6 +72,7 @@ class Processor: public AstVisitor { ...@@ -67,6 +72,7 @@ class Processor: public AstVisitor {
void Processor::Process(ZoneList<Statement*>* statements) { void Processor::Process(ZoneList<Statement*>* statements) {
for (int i = statements->length() - 1; i >= 0; --i) { for (int i = statements->length() - 1; i >= 0; --i) {
Visit(statements->at(i)); Visit(statements->at(i));
statements->Set(i, replacement_);
} }
} }
...@@ -81,6 +87,7 @@ void Processor::VisitBlock(Block* node) { ...@@ -81,6 +87,7 @@ void Processor::VisitBlock(Block* node) {
// returns 'undefined'. To obtain the same behavior with v8, we need // returns 'undefined'. To obtain the same behavior with v8, we need
// to prevent rewriting in that case. // to prevent rewriting in that case.
if (!node->ignore_completion_value()) Process(node->statements()); if (!node->ignore_completion_value()) Process(node->statements());
replacement_ = node;
} }
...@@ -90,6 +97,7 @@ void Processor::VisitExpressionStatement(ExpressionStatement* node) { ...@@ -90,6 +97,7 @@ void Processor::VisitExpressionStatement(ExpressionStatement* node) {
node->set_expression(SetResult(node->expression())); node->set_expression(SetResult(node->expression()));
is_set_ = true; is_set_ = true;
} }
replacement_ = node;
} }
...@@ -97,10 +105,13 @@ void Processor::VisitIfStatement(IfStatement* node) { ...@@ -97,10 +105,13 @@ void Processor::VisitIfStatement(IfStatement* node) {
// Rewrite both branches. // Rewrite both branches.
bool set_after = is_set_; bool set_after = is_set_;
Visit(node->then_statement()); Visit(node->then_statement());
node->set_then_statement(replacement_);
bool set_in_then = is_set_; bool set_in_then = is_set_;
is_set_ = set_after; is_set_ = set_after;
Visit(node->else_statement()); Visit(node->else_statement());
node->set_else_statement(replacement_);
is_set_ = is_set_ && set_in_then; is_set_ = is_set_ && set_in_then;
replacement_ = node;
} }
...@@ -109,7 +120,9 @@ void Processor::VisitIterationStatement(IterationStatement* node) { ...@@ -109,7 +120,9 @@ void Processor::VisitIterationStatement(IterationStatement* node) {
bool set_after = is_set_; bool set_after = is_set_;
is_set_ = false; // We are in a loop, so we can't rely on [set_after]. is_set_ = false; // We are in a loop, so we can't rely on [set_after].
Visit(node->body()); Visit(node->body());
node->set_body(replacement_);
is_set_ = is_set_ && set_after; is_set_ = is_set_ && set_after;
replacement_ = node;
} }
...@@ -142,17 +155,23 @@ void Processor::VisitTryCatchStatement(TryCatchStatement* node) { ...@@ -142,17 +155,23 @@ void Processor::VisitTryCatchStatement(TryCatchStatement* node) {
// Rewrite both try and catch block. // Rewrite both try and catch block.
bool set_after = is_set_; bool set_after = is_set_;
Visit(node->try_block()); Visit(node->try_block());
node->set_try_block(static_cast<Block*>(replacement_));
bool set_in_try = is_set_; bool set_in_try = is_set_;
is_set_ = set_after; is_set_ = set_after;
Visit(node->catch_block()); Visit(node->catch_block());
node->set_catch_block(static_cast<Block*>(replacement_));
is_set_ = is_set_ && set_in_try; is_set_ = is_set_ && set_in_try;
replacement_ = node;
} }
void Processor::VisitTryFinallyStatement(TryFinallyStatement* node) { void Processor::VisitTryFinallyStatement(TryFinallyStatement* node) {
// Rewrite both try and finally block (in reverse order). // Rewrite both try and finally block (in reverse order).
Visit(node->finally_block()); Visit(node->finally_block());
Visit(node->try_block()); node->set_finally_block(replacement_->AsBlock());
Visit(node->try_block()); // Exception will not be caught.
node->set_try_block(replacement_->AsBlock());
replacement_ = node;
} }
...@@ -165,36 +184,51 @@ void Processor::VisitSwitchStatement(SwitchStatement* node) { ...@@ -165,36 +184,51 @@ void Processor::VisitSwitchStatement(SwitchStatement* node) {
Process(clause->statements()); Process(clause->statements());
} }
is_set_ = is_set_ && set_after; is_set_ = is_set_ && set_after;
replacement_ = node;
} }
void Processor::VisitContinueStatement(ContinueStatement* node) { void Processor::VisitContinueStatement(ContinueStatement* node) {
is_set_ = false; is_set_ = false;
replacement_ = node;
} }
void Processor::VisitBreakStatement(BreakStatement* node) { void Processor::VisitBreakStatement(BreakStatement* node) {
is_set_ = false; is_set_ = false;
replacement_ = node;
} }
void Processor::VisitWithStatement(WithStatement* node) { void Processor::VisitWithStatement(WithStatement* node) {
Visit(node->statement()); Visit(node->statement());
node->set_statement(replacement_);
replacement_ = node;
} }
void Processor::VisitSloppyBlockFunctionStatement( void Processor::VisitSloppyBlockFunctionStatement(
SloppyBlockFunctionStatement* node) { SloppyBlockFunctionStatement* node) {
Visit(node->statement()); 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::VisitReturnStatement(ReturnStatement* node) {
void Processor::VisitEmptyStatement(EmptyStatement* node) {} is_set_ = true;
void Processor::VisitDebuggerStatement(DebuggerStatement* node) {} replacement_ = node;
}
void Processor::VisitDebuggerStatement(DebuggerStatement* node) {
replacement_ = node;
}
// Expressions are never visited. // Expressions are never visited.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment