Chromium Code Reviews| Index: src/parser.h |
| diff --git a/src/parser.h b/src/parser.h |
| index 8ff7b176f47f34dd7f7e8eb822d9dcd817388884..3893c2dc35d07e55606eab6d4d190d0bfc9d627c 100644 |
| --- a/src/parser.h |
| +++ b/src/parser.h |
| @@ -876,6 +876,14 @@ class ParserTraits { |
| ZoneList<v8::internal::Expression*>* args, |
| int pos); |
| + // Rewrite all DestructuringAssignments in the current FunctionState. |
| + V8_INLINE void RewriteDestructuringAssignments(); |
| + |
| + V8_INLINE Expression* RewriteDestructuringAssignmentExpression( |
| + Expression* expression); |
| + |
| + V8_INLINE void ShouldRewriteDestructuringAssignment(Expression* assignment); |
| + |
| private: |
| Parser* parser_; |
| }; |
| @@ -1024,6 +1032,10 @@ class Parser : public ParserBase<ParserTraits> { |
| const DeclarationParsingResult::Declaration* declaration, |
| ZoneList<const AstRawString*>* names, bool* ok); |
| + static void RewriteDestructuringAssignment(Parser* parser, |
| + Assignment* assignment, |
| + Scope* Scope, bool* ok); |
| + |
| void set_initializer_position(int pos) { initializer_position_ = pos; } |
| private: |
| @@ -1035,6 +1047,11 @@ class Parser : public ParserBase<ParserTraits> { |
| #undef DECLARE_VISIT |
| void Visit(AstNode* node) override; |
| + enum PatternContext { BINDING, INITIALIZER, ASSIGNMENT }; |
| + |
| + PatternContext context() const { return context_; } |
| + void set_context(PatternContext context) { context_ = context; } |
| + |
| void RecurseIntoSubpattern(AstNode* pattern, Expression* value) { |
| Expression* old_value = current_value_; |
| current_value_ = value; |
| @@ -1042,14 +1059,21 @@ class Parser : public ParserBase<ParserTraits> { |
| current_value_ = old_value; |
| } |
| + void VisitObjectLiteral(ObjectLiteral* node, Variable** temp_var); |
| + void VisitArrayLiteral(ArrayLiteral* node, Variable** temp_var); |
| + |
| Variable* CreateTempVar(Expression* value = nullptr); |
| - AstNodeFactory* factory() const { return descriptor_->parser->factory(); } |
| + AstNodeFactory* factory() const { return parser_->factory(); } |
| AstValueFactory* ast_value_factory() const { |
| - return descriptor_->parser->ast_value_factory(); |
| + return parser_->ast_value_factory(); |
| } |
| - Zone* zone() const { return descriptor_->parser->zone(); } |
| + Zone* zone() const { return parser_->zone(); } |
| + Scope* scope() const { return scope_; } |
| + Scope* scope_; |
| + Parser* parser_; |
| + PatternContext context_; |
| Expression* pattern_; |
| int initializer_position_; |
| Block* block_; |
| @@ -1199,6 +1223,13 @@ class Parser : public ParserBase<ParserTraits> { |
| void SetLanguageMode(Scope* scope, LanguageMode mode); |
| void RaiseLanguageMode(LanguageMode mode); |
| + V8_INLINE void RewriteDestructuringAssignments(); |
| + |
| + friend class InitializerRewriter; |
| + void RewriteParameterInitializer(Expression* expr, Scope* scope); |
| + |
| + Expression* RewriteDestructuringAssignmentExpression(Expression* expression); |
| + |
| Scanner scanner_; |
| PreParser* reusable_preparser_; |
| Scope* original_scope_; // for ES5 function declarations in sloppy eval |
| @@ -1387,6 +1418,55 @@ DoExpression* ParserTraits::ParseDoExpression(bool* ok) { |
| } |
| +void ParserTraits::RewriteDestructuringAssignments() { |
| + parser_->RewriteDestructuringAssignments(); |
| +} |
| + |
| + |
| +void Parser::RewriteDestructuringAssignments() { |
| + FunctionState* func = function_state_; |
| + typedef typename ParserBase<ParserTraits>::DestructuringAssignment Pair; |
| + const List<Pair>& assignments = func->destructuring_assignments_to_rewrite(); |
| + for (int i = assignments.length() - 1; i >= 0; --i) { |
|
adamk
2015/11/20 22:42:58
Any particular reason for iterating backwards here
|
| + Pair pair = assignments.at(i); |
| + Assignment* to_rewrite = pair.assignment->AsAssignment(); |
| + Scope* scope = pair.scope; |
| + AssignmentPattern* pattern = to_rewrite->target()->AsAssignmentPattern(); |
| + if (pattern && !pattern->is_rewritten()) { |
| + bool ok = true; |
| + PatternRewriter::RewriteDestructuringAssignment(this, to_rewrite, scope, |
| + &ok); |
| + DCHECK(ok); |
| + } |
| + } |
| +} |
| + |
| + |
| +Expression* ParserTraits::RewriteDestructuringAssignmentExpression( |
| + Expression* expression) { |
| + return parser_->RewriteDestructuringAssignmentExpression(expression); |
| +} |
| + |
| + |
| +void ParserTraits::ShouldRewriteDestructuringAssignment(Expression* expr) { |
|
adamk
2015/11/20 22:42:58
The name of this function doesn't make sense to me
|
| + DCHECK(expr->IsAssignment()); |
|
adamk
2015/11/20 22:42:58
Why can't this method just take an Assignment* to
|
| + Assignment* assignment = expr->AsAssignment(); |
| + DCHECK(assignment->target()->IsAssignmentPattern()); |
| + DCHECK_EQ(Token::ASSIGN, assignment->op()); |
| + parser_->function_state_->AddDestructuringAssignment( |
| + Parser::DestructuringAssignment(assignment, parser_->scope_)); |
| +} |
| + |
| +inline void Parser::PatternRewriter::VisitObjectLiteral(ObjectLiteral* node) { |
|
adamk
2015/11/20 22:42:58
Can these methods move to the .cc file? Seems like
|
| + Variable* temp_var = nullptr; |
| + VisitObjectLiteral(node, &temp_var); |
| +} |
| + |
| +inline void Parser::PatternRewriter::VisitArrayLiteral(ArrayLiteral* node) { |
| + Variable* temp_var = nullptr; |
| + VisitArrayLiteral(node, &temp_var); |
| +} |
| + |
| } // namespace internal |
| } // namespace v8 |