Index: src/parser.cc |
diff --git a/src/parser.cc b/src/parser.cc |
index 2ee9444054e12d8a54d306e6ba112dffe0a958f7..868bec941531debed8bd9ad9d6762ff760650ae6 100644 |
--- a/src/parser.cc |
+++ b/src/parser.cc |
@@ -21,6 +21,7 @@ |
#include "src/scanner-character-streams.h" |
#include "src/scopeinfo.h" |
#include "src/string-stream.h" |
+#include "src/ast-expression-visitor.h" |
namespace v8 { |
namespace internal { |
@@ -920,6 +921,8 @@ Parser::Parser(ParseInfo* info) |
set_allow_harmony_rest_parameters(FLAG_harmony_rest_parameters); |
set_allow_harmony_default_parameters(FLAG_harmony_default_parameters); |
set_allow_harmony_destructuring(FLAG_harmony_destructuring); |
+ set_allow_harmony_destructuring_assignment( |
+ FLAG_harmony_destructuring_assignment); |
set_allow_strong_mode(FLAG_strong_mode); |
set_allow_legacy_const(FLAG_legacy_const); |
set_allow_harmony_do_expressions(FLAG_harmony_do_expressions); |
@@ -1090,6 +1093,7 @@ FunctionLiteral* Parser::DoParseProgram(ParseInfo* info) { |
} |
if (ok) { |
+ ParserTraits::RewriteDestructuringAssignments(); |
result = factory()->NewFunctionLiteral( |
ast_value_factory()->empty_string(), ast_value_factory(), scope_, |
body, function_state.materialized_literal_count(), |
@@ -3398,6 +3402,12 @@ void Parser::InitializeForEachStatement(ForEachStatement* stmt, |
} |
+Expression* Parser::RewriteDestructuringAssignmentExpression( |
+ Expression* expression) { |
+ return expression; |
+} |
+ |
+ |
Statement* Parser::DesugarLexicalBindingsInForStatement( |
Scope* inner_scope, bool is_const, ZoneList<const AstRawString*>* names, |
ForStatement* loop, Statement* init, Expression* cond, Statement* next, |
@@ -4412,6 +4422,8 @@ FunctionLiteral* Parser::ParseFunctionLiteral( |
allow_harmony_destructuring()) { |
CheckConflictingVarDeclarations(scope, CHECK_OK); |
} |
+ |
+ ParserTraits::RewriteDestructuringAssignments(); |
} |
bool has_duplicate_parameters = |
@@ -4540,6 +4552,70 @@ Statement* Parser::BuildAssertIsCoercible(Variable* var) { |
} |
+class InitializerRewriter : public AstExpressionVisitor { |
+ public: |
+ InitializerRewriter(uintptr_t stack_limit, Expression* root, Parser* parser, |
+ Scope* scope) |
+ : AstExpressionVisitor(stack_limit, root), |
+ parser_(parser), |
+ scope_(scope) {} |
+ |
+ private: |
+ void VisitExpression(Expression* expr) { |
+ if (expr->IsAssignment()) { |
+ Assignment* node = expr->AsAssignment(); |
+ Expression* target = node->target(); |
+ if (node->op() == Token::ASSIGN && target->IsAssignmentPattern() && |
+ !target->AsAssignmentPattern()->is_rewritten()) { |
+ bool ok = true; |
+ Parser::PatternRewriter::RewriteDestructuringAssignment(parser_, node, |
+ scope_, &ok); |
+ DCHECK(ok); |
+ } |
+ } |
+ } |
+ /* |
+ #define NOT_INITIALIZER(T) void Visit##T(T* node) {} |
+ NOT_INITIALIZER(FunctionLiteral) |
+ NOT_INITIALIZER(ClassLiteral) |
+ NOT_INITIALIZER(NativeFunctionLiteral) |
+ NOT_INITIALIZER(Conditional) |
+ NOT_INITIALIZER(VariableProxy) |
+ NOT_INITIALIZER(Literal) |
+ NOT_INITIALIZER(RegExpLiteral) |
+ NOT_INITIALIZER(ObjectLiteral) |
+ NOT_INITIALIZER(ArrayLiteral) |
+ NOT_INITIALIZER(AssignmentPattern) |
+ NOT_INITIALIZER(Yield) |
+ NOT_INITIALIZER(Throw) |
+ NOT_INITIALIZER(Property) |
+ NOT_INITIALIZER(Call) |
+ NOT_INITIALIZER(CallNew) |
+ NOT_INITIALIZER(CallRuntime) |
+ NOT_INITIALIZER(UnaryOperation) |
+ NOT_INITIALIZER(CountOperation) |
+ NOT_INITIALIZER(BinaryOperation) |
+ NOT_INITIALIZER(CompareOperation) |
+ NOT_INITIALIZER(Spread) |
+ NOT_INITIALIZER(ThisFunction) |
+ NOT_INITIALIZER(SuperPropertyReference) |
+ NOT_INITIALIZER(SuperCallReference) |
+ NOT_INITIALIZER(CaseClause) |
+ NOT_INITIALIZER(EmptyParentheses) |
+ NOT_INITIALIZER(DoExpression) |
+ #undef NOT_INITIALIZER*/ |
+ private: |
+ Parser* parser_; |
+ Scope* scope_; |
+}; |
+ |
+ |
+void Parser::RewriteParameterInitializer(Expression* expr, Scope* scope) { |
+ InitializerRewriter rewriter(stack_limit_, expr, this, scope); |
+ rewriter.Run(); |
+} |
+ |
+ |
Block* Parser::BuildParameterInitializationBlock( |
const ParserFormalParameters& parameters, bool* ok) { |
DCHECK(!parameters.is_simple); |
@@ -4565,6 +4641,10 @@ Block* Parser::BuildParameterInitializationBlock( |
if (parameter.initializer != nullptr) { |
// IS_UNDEFINED($param) ? initializer : $param |
DCHECK(!parameter.is_rest); |
+ |
+ // Ensure initializer is rewritten |
+ RewriteParameterInitializer(parameter.initializer, scope_); |
+ |
auto condition = factory()->NewCompareOperation( |
Token::EQ_STRICT, |
factory()->NewVariableProxy(parameters.scope->parameter(i)), |