| 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)),
|
|
|