Chromium Code Reviews| Index: src/rewriter.cc |
| diff --git a/src/rewriter.cc b/src/rewriter.cc |
| index 9df46c9beef236551026f893d1c89da3cefb970d..612a08081cedafb867cca9681bc16b33e8bebe58 100644 |
| --- a/src/rewriter.cc |
| +++ b/src/rewriter.cc |
| @@ -24,6 +24,18 @@ class Processor: public AstVisitor { |
| InitializeAstVisitor(isolate, ast_value_factory->zone()); |
| } |
| + Processor(Parser* parser, Scope* scope, Variable* result, |
| + AstValueFactory* ast_value_factory) |
| + : result_(result), |
| + result_assigned_(false), |
| + replacement_(nullptr), |
| + is_set_(false), |
| + scope_(scope), |
| + factory_(ast_value_factory) { |
| + InitializeAstVisitor(nullptr, ast_value_factory->zone()); |
| + parser_ = parser; |
| + } |
| + |
| virtual ~Processor() { } |
| void Process(ZoneList<Statement*>* statements); |
| @@ -32,6 +44,17 @@ class Processor: public AstVisitor { |
| Scope* scope() { return scope_; } |
| AstNodeFactory* factory() { return &factory_; } |
| + // Returns ".result = value" |
|
rossberg
2015/10/13 10:44:33
Why are these public now?
caitp (gmail)
2015/10/13 15:05:59
SetResult is used by the do expression rewriter, i
|
| + Expression* SetResult(Expression* value) { |
| + result_assigned_ = true; |
| + VariableProxy* result_proxy = factory()->NewVariableProxy(result_); |
| + return factory()->NewAssignment(Token::ASSIGN, result_proxy, value, |
| + RelocInfo::kNoPosition); |
| + } |
| + |
| + // Inserts '.result = undefined' in front of the given statement. |
| + Statement* AssignUndefinedBefore(Statement* s); |
| + |
| private: |
| Variable* result_; |
| @@ -54,17 +77,6 @@ class Processor: public AstVisitor { |
| Scope* scope_; |
| AstNodeFactory factory_; |
| - // Returns ".result = value" |
| - Expression* SetResult(Expression* value) { |
| - result_assigned_ = true; |
| - VariableProxy* result_proxy = factory()->NewVariableProxy(result_); |
| - return factory()->NewAssignment( |
| - Token::ASSIGN, result_proxy, value, RelocInfo::kNoPosition); |
| - } |
| - |
| - // Inserts '.result = undefined' in front of the given statement. |
| - Statement* AssignUndefinedBefore(Statement* s); |
| - |
| // Node visitors. |
| #define DEF_VISIT(type) virtual void Visit##type(type* node) override; |
| AST_NODE_LIST(DEF_VISIT) |
| @@ -72,7 +84,41 @@ class Processor: public AstVisitor { |
| void VisitIterationStatement(IterationStatement* stmt); |
| - DEFINE_AST_VISITOR_SUBCLASS_MEMBERS(); |
| + public: |
| + void Visit(AstNode* node) final { |
| + if (!CheckStackOverflow()) node->Accept(this); |
| + } |
| + |
| + void SetStackOverflow() { stack_overflow_ = true; } |
| + void ClearStackOverflow() { stack_overflow_ = false; } |
| + bool HasStackOverflow() const { return stack_overflow_; } |
| + |
| + bool CheckStackOverflow() { |
| + if (stack_overflow_) return true; |
| + if (isolate_) { |
| + StackLimitCheck check(isolate_); |
| + if (!check.HasOverflowed()) return false; |
| + stack_overflow_ = true; |
| + } else { |
| + if (!parser_->CheckStackOverflow()) return false; |
| + stack_overflow_ = true; |
| + } |
| + return true; |
| + } |
| + |
| + private: |
| + void InitializeAstVisitor(Isolate* isolate, Zone* zone) { |
| + isolate_ = isolate; |
| + zone_ = zone; |
| + stack_overflow_ = false; |
| + } |
| + Zone* zone() { return zone_; } |
| + Isolate* isolate() { return isolate_; } |
| + |
| + Isolate* isolate_; |
| + Parser* parser_; |
| + Zone* zone_; |
| + bool stack_overflow_; |
| }; |
| @@ -359,5 +405,31 @@ bool Rewriter::Rewrite(ParseInfo* info) { |
| } |
| +bool Rewriter::Rewrite(Parser* parser, DoExpression* expr, |
| + AstValueFactory* factory) { |
| + Block* block = expr->block(); |
| + Scope* scope = block->scope(); |
| + ZoneList<Statement*>* body = block->statements(); |
| + VariableProxy* result = expr->result(); |
| + Variable* result_var = result->var(); |
| + |
| + if (!body->is_empty()) { |
| + Processor processor(parser, scope, result_var, factory); |
| + processor.Process(body); |
| + if (processor.HasStackOverflow()) return false; |
| + |
| + if (!processor.result_assigned()) { |
| + AstNodeFactory* node_factory = processor.factory(); |
| + Expression* undef = |
| + node_factory->NewUndefinedLiteral(RelocInfo::kNoPosition); |
| + Statement* completion = node_factory->NewExpressionStatement( |
| + processor.SetResult(undef), expr->position()); |
| + body->Add(completion, factory->zone()); |
| + } |
| + } |
| + return true; |
| +} |
| + |
| + |
| } // namespace internal |
| } // namespace v8 |