| Index: src/parsing/parser.cc
|
| diff --git a/src/parsing/parser.cc b/src/parsing/parser.cc
|
| index dc23e3835913f241efe4374f830b2a39b0b52b73..293d59b2187563104952d7755bb48effaa13551d 100644
|
| --- a/src/parsing/parser.cc
|
| +++ b/src/parsing/parser.cc
|
| @@ -6,6 +6,7 @@
|
|
|
| #include "src/api.h"
|
| #include "src/ast/ast.h"
|
| +#include "src/ast/ast-expression-visitor.h"
|
| #include "src/ast/ast-literal-reindexer.h"
|
| #include "src/ast/scopeinfo.h"
|
| #include "src/bailout-reason.h"
|
| @@ -923,6 +924,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_bind(FLAG_harmony_destructuring_bind);
|
| + 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);
|
| @@ -1093,6 +1096,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(),
|
| @@ -4404,6 +4408,11 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
|
| allow_harmony_destructuring_bind()) {
|
| CheckConflictingVarDeclarations(scope, CHECK_OK);
|
| }
|
| +
|
| + if (body) {
|
| + // If body can be inspected, rewrite queued destructuring assignments
|
| + ParserTraits::RewriteDestructuringAssignments();
|
| + }
|
| }
|
|
|
| bool has_duplicate_parameters =
|
| @@ -4532,6 +4541,38 @@ 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) {
|
| + RewritableAssignmentExpression* to_rewrite =
|
| + expr->AsRewritableAssignmentExpression();
|
| + if (to_rewrite == nullptr || to_rewrite->is_rewritten()) return;
|
| +
|
| + bool ok = true;
|
| + Parser::PatternRewriter::RewriteDestructuringAssignment(parser_, to_rewrite,
|
| + scope_, &ok);
|
| + DCHECK(ok);
|
| + }
|
| +
|
| + 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);
|
| @@ -4562,6 +4603,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)),
|
| @@ -6465,5 +6510,41 @@ void Parser::RaiseLanguageMode(LanguageMode mode) {
|
| static_cast<LanguageMode>(scope_->language_mode() | mode));
|
| }
|
|
|
| +
|
| +void ParserTraits::RewriteDestructuringAssignments() {
|
| + parser_->RewriteDestructuringAssignments();
|
| +}
|
| +
|
| +
|
| +void Parser::RewriteDestructuringAssignments() {
|
| + FunctionState* func = function_state_;
|
| + if (!allow_harmony_destructuring_assignment()) return;
|
| + const List<DestructuringAssignment>& assignments =
|
| + func->destructuring_assignments_to_rewrite();
|
| + for (int i = assignments.length() - 1; i >= 0; --i) {
|
| + // Rewrite list in reverse, so that nested assignment patterns are rewritten
|
| + // correctly.
|
| + DestructuringAssignment pair = assignments.at(i);
|
| + RewritableAssignmentExpression* to_rewrite =
|
| + pair.assignment->AsRewritableAssignmentExpression();
|
| + Scope* scope = pair.scope;
|
| + DCHECK_NOT_NULL(to_rewrite);
|
| + if (!to_rewrite->is_rewritten()) {
|
| + bool ok = true;
|
| + PatternRewriter::RewriteDestructuringAssignment(this, to_rewrite, scope,
|
| + &ok);
|
| + DCHECK(ok);
|
| + }
|
| + }
|
| +}
|
| +
|
| +
|
| +void ParserTraits::QueueDestructuringAssignmentForRewriting(Expression* expr) {
|
| + DCHECK(expr->IsRewritableAssignmentExpression());
|
| + parser_->function_state_->AddDestructuringAssignment(
|
| + Parser::DestructuringAssignment(expr, parser_->scope_));
|
| +}
|
| +
|
| +
|
| } // namespace internal
|
| } // namespace v8
|
|
|