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 |