1014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Copyright 2015 the V8 project authors. All rights reserved.
2014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Use of this source code is governed by a BSD-style license that can be
3014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// found in the LICENSE file.
4014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/ast/ast.h"
6014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/messages.h"
7014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/parsing/parameter-initializer-rewriter.h"
8014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/parsing/parser.h"
9014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
10014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace v8 {
11014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
12014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace internal {
13014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
14014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Parser::PatternRewriter::DeclareAndInitializeVariables(
15014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Block* block, const DeclarationDescriptor* declaration_descriptor,
16014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    const DeclarationParsingResult::Declaration* declaration,
17014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ZoneList<const AstRawString*>* names, bool* ok) {
18014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  PatternRewriter rewriter;
19014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
20014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  rewriter.scope_ = declaration_descriptor->scope;
21014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  rewriter.parser_ = declaration_descriptor->parser;
22014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  rewriter.context_ = BINDING;
23014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  rewriter.pattern_ = declaration->pattern;
24014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  rewriter.initializer_position_ = declaration->initializer_position;
25014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  rewriter.block_ = block;
26014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  rewriter.descriptor_ = declaration_descriptor;
27014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  rewriter.names_ = names;
28014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  rewriter.ok_ = ok;
29014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  rewriter.recursion_level_ = 0;
30014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
31014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  rewriter.RecurseIntoSubpattern(rewriter.pattern_, declaration->initializer);
32014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
33014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
34014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
35014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Parser::PatternRewriter::RewriteDestructuringAssignment(
36014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Parser* parser, RewritableAssignmentExpression* to_rewrite, Scope* scope) {
37014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  PatternRewriter rewriter;
38014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
39014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!to_rewrite->is_rewritten());
40014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
41014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool ok = true;
42014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  rewriter.scope_ = scope;
43014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  rewriter.parser_ = parser;
44014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  rewriter.context_ = ASSIGNMENT;
45014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  rewriter.pattern_ = to_rewrite;
46014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  rewriter.block_ = nullptr;
47014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  rewriter.descriptor_ = nullptr;
48014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  rewriter.names_ = nullptr;
49014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  rewriter.ok_ = &ok;
50014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  rewriter.recursion_level_ = 0;
51014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
52014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  rewriter.RecurseIntoSubpattern(rewriter.pattern_, nullptr);
53014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(ok);
54014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
55014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
56014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
57014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochExpression* Parser::PatternRewriter::RewriteDestructuringAssignment(
58014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Parser* parser, Assignment* assignment, Scope* scope) {
59014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_NOT_NULL(assignment);
60014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_EQ(Token::ASSIGN, assignment->op());
61014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  auto to_rewrite =
62014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      parser->factory()->NewRewritableAssignmentExpression(assignment);
63014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  RewriteDestructuringAssignment(parser, to_rewrite, scope);
64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return to_rewrite->expression();
65014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
66014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
67014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
68014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool Parser::PatternRewriter::IsAssignmentContext(PatternContext c) const {
69014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return c == ASSIGNMENT || c == ASSIGNMENT_INITIALIZER;
70014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
71014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
72014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
73014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool Parser::PatternRewriter::IsBindingContext(PatternContext c) const {
74014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return c == BINDING || c == INITIALIZER;
75014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
76014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
77014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
78014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochParser::PatternRewriter::PatternContext
79014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochParser::PatternRewriter::SetAssignmentContextIfNeeded(Expression* node) {
80014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  PatternContext old_context = context();
81014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (node->IsAssignment() && node->AsAssignment()->op() == Token::ASSIGN) {
82014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    set_context(ASSIGNMENT);
83014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
84014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return old_context;
85014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
86014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
87014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
88014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochParser::PatternRewriter::PatternContext
89014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochParser::PatternRewriter::SetInitializerContextIfNeeded(Expression* node) {
90014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Set appropriate initializer context for BindingElement and
91014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // AssignmentElement nodes
92014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  PatternContext old_context = context();
93014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool is_destructuring_assignment =
94014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      node->IsRewritableAssignmentExpression() &&
95014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      !node->AsRewritableAssignmentExpression()->is_rewritten();
96014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool is_assignment =
97014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      node->IsAssignment() && node->AsAssignment()->op() == Token::ASSIGN;
98014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (is_destructuring_assignment || is_assignment) {
99014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    switch (old_context) {
100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case BINDING:
101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        set_context(INITIALIZER);
102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case ASSIGNMENT:
104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        set_context(ASSIGNMENT_INITIALIZER);
105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      default:
107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return old_context;
111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Parser::PatternRewriter::VisitVariableProxy(VariableProxy* pattern) {
115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Expression* value = current_value_;
116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (IsAssignmentContext()) {
118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // In an assignment context, simply perform the assignment
119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Assignment* assignment = factory()->NewAssignment(
120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Token::ASSIGN, pattern, value, pattern->position());
121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    block_->statements()->Add(
122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        factory()->NewExpressionStatement(assignment, pattern->position()),
123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        zone());
124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return;
125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  descriptor_->scope->RemoveUnresolved(pattern);
128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Declare variable.
130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Note that we *always* must treat the initial value via a separate init
131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // assignment for variables and constants because the value must be assigned
132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // when the variable is encountered in the source. But the variable/constant
133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // is declared (and set to 'undefined') upon entering the function within
134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // which the variable or constant is declared. Only function variables have
135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // an initial value in the declaration (because they are initialized upon
136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // entering the function).
137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //
138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // If we have a legacy const declaration, in an inner scope, the proxy
139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // is always bound to the declared variable (independent of possibly
140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // surrounding 'with' statements).
141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // For let/const declarations in harmony mode, we can also immediately
142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // pre-resolve the proxy because it resides in the same scope as the
143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // declaration.
144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const AstRawString* name = pattern->raw_name();
145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VariableProxy* proxy = parser_->NewUnresolved(name, descriptor_->mode);
146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Declaration* declaration = factory()->NewVariableDeclaration(
147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      proxy, descriptor_->mode, descriptor_->scope,
148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      descriptor_->declaration_pos);
149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Variable* var =
150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      parser_->Declare(declaration, descriptor_->declaration_kind,
151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                       descriptor_->mode != VAR, ok_, descriptor_->hoist_scope);
152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!*ok_) return;
153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_NOT_NULL(var);
154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!proxy->is_resolved() || proxy->var() == var);
155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  var->set_initializer_position(initializer_position_);
156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(initializer_position_ != RelocInfo::kNoPosition);
158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Scope* declaration_scope = IsLexicalVariableMode(descriptor_->mode)
160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 ? descriptor_->scope
161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 : descriptor_->scope->DeclarationScope();
162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) {
163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    parser_->ReportMessage(MessageTemplate::kTooManyVariables);
164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    *ok_ = false;
165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return;
166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (names_) {
168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    names_->Add(name, zone());
169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Initialize variables if needed. A
172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // declaration of the form:
173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //
174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //    var v = x;
175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //
176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // is syntactic sugar for:
177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //
178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //    var v; v = x;
179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //
180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // In particular, we need to re-lookup 'v' (in scope_, not
181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // declaration_scope) as it may be a different 'v' than the 'v' in the
182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // declaration (e.g., if we are inside a 'with' statement or 'catch'
183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // block).
184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //
185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // However, note that const declarations are different! A const
186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // declaration of the form:
187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //
188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //   const c = x;
189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //
190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // is *not* syntactic sugar for:
191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //
192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //   const c; c = x;
193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //
194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // The "variable" c initialized to x is the same as the declared
195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // one - there is no re-lookup (see the last parameter of the
196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Declare() call above).
197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Scope* initialization_scope = IsImmutableVariableMode(descriptor_->mode)
198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                    ? declaration_scope
199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                    : descriptor_->scope;
200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Global variable declarations must be compiled in a specific
203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // way. When the script containing the global variable declaration
204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // is entered, the global variable must be declared, so that if it
205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // doesn't exist (on the global object itself, see ES5 errata) it
206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // gets created with an initial undefined value. This is handled
207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // by the declarations part of the function representing the
208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // top-level global code; see Runtime::DeclareGlobalVariable. If
209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // it already exists (in the object or in a prototype), it is
210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // *not* touched until the variable declaration statement is
211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // executed.
212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //
213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Executing the variable declaration statement will always
214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // guarantee to give the global object an own property.
215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // This way, global variable declarations can shadow
216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // properties in the prototype chain, but only after the variable
217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // declaration statement has been executed. This is important in
218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // browsers where the global object (window) has lots of
219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // properties defined in prototype objects.
220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (initialization_scope->is_script_scope() &&
221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      !IsLexicalVariableMode(descriptor_->mode)) {
222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Compute the arguments for the runtime
223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // call.test-parsing/InitializedDeclarationsInStrictForOfError
224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ZoneList<Expression*>* arguments =
225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        new (zone()) ZoneList<Expression*>(3, zone());
226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // We have at least 1 parameter.
227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    arguments->Add(
228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        factory()->NewStringLiteral(name, descriptor_->declaration_pos),
229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        zone());
230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CallRuntime* initialize;
231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (IsImmutableVariableMode(descriptor_->mode)) {
233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      arguments->Add(value, zone());
234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      value = NULL;  // zap the value to avoid the unnecessary assignment
235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Construct the call to Runtime_InitializeConstGlobal
237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // and add it to the initialization statement block.
238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Note that the function does different things depending on
239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // the number of arguments (1 or 2).
240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      initialize =
241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          factory()->NewCallRuntime(Runtime::kInitializeConstGlobal, arguments,
242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                    descriptor_->initialization_pos);
243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {
244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Add language mode.
245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // We may want to pass singleton to avoid Literal allocations.
246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      LanguageMode language_mode = initialization_scope->language_mode();
247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      arguments->Add(factory()->NewNumberLiteral(language_mode,
248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                 descriptor_->declaration_pos),
249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                     zone());
250014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
251014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Be careful not to assign a value to the global variable if
252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // we're in a with. The initialization value should not
253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // necessarily be stored in the global object in that case,
254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // which is why we need to generate a separate assignment node.
255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (value != NULL && !descriptor_->scope->inside_with()) {
256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        arguments->Add(value, zone());
257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        value = NULL;  // zap the value to avoid the unnecessary assignment
258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // Construct the call to Runtime_InitializeVarGlobal
259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // and add it to the initialization statement block.
260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        initialize =
261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            factory()->NewCallRuntime(Runtime::kInitializeVarGlobal, arguments,
262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                      descriptor_->declaration_pos);
263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        initialize = NULL;
265014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
267014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (initialize != NULL) {
269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      block_->statements()->Add(
270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          factory()->NewExpressionStatement(initialize, RelocInfo::kNoPosition),
271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          zone());
272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (value != nullptr && (descriptor_->mode == CONST_LEGACY ||
274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                  IsLexicalVariableMode(descriptor_->mode))) {
275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Constant initializations always assign to the declared constant which
276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // is always at the function scope level. This is only relevant for
277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // dynamically looked-up variables and constants (the
278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // start context for constant lookups is always the function context,
279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // while it is the top context for var declared variables). Sigh...
280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // For 'let' and 'const' declared variables in harmony mode the
281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // initialization also always assigns to the declared variable.
282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK_NOT_NULL(proxy);
283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK_NOT_NULL(proxy->var());
284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK_NOT_NULL(value);
285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Add break location for destructured sub-pattern.
286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int pos = IsSubPattern() ? pattern->position() : RelocInfo::kNoPosition;
287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Assignment* assignment =
288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        factory()->NewAssignment(Token::INIT, proxy, value, pos);
289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    block_->statements()->Add(
290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        factory()->NewExpressionStatement(assignment, pos), zone());
291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    value = NULL;
292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Add an assignment node to the initialization statement block if we still
295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // have a pending initialization value.
296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (value != NULL) {
297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(descriptor_->mode == VAR);
298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // 'var' initializations are simply assignments (with all the consequences
299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // if they are inside a 'with' statement - they may change a 'with' object
300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // property).
301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    VariableProxy* proxy = initialization_scope->NewUnresolved(factory(), name);
302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Add break location for destructured sub-pattern.
303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int pos = IsSubPattern() ? pattern->position() : RelocInfo::kNoPosition;
304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Assignment* assignment =
305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        factory()->NewAssignment(Token::INIT, proxy, value, pos);
306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    block_->statements()->Add(
307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        factory()->NewExpressionStatement(assignment, pos), zone());
308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochVariable* Parser::PatternRewriter::CreateTempVar(Expression* value) {
313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  auto temp = scope()->NewTemporary(ast_value_factory()->empty_string());
314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (value != nullptr) {
315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    auto assignment = factory()->NewAssignment(
316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Token::ASSIGN, factory()->NewVariableProxy(temp), value,
317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        RelocInfo::kNoPosition);
318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    block_->statements()->Add(
320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition),
321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        zone());
322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return temp;
324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Parser::PatternRewriter::VisitRewritableAssignmentExpression(
328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    RewritableAssignmentExpression* node) {
329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!IsAssignmentContext()) {
330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Mark the assignment as rewritten to prevent redundant rewriting, and
331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // perform BindingPattern rewriting
332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(!node->is_rewritten());
333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    node->Rewrite(node->expression());
334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return node->expression()->Accept(this);
335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (node->is_rewritten()) return;
338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(IsAssignmentContext());
339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Assignment* assign = node->expression()->AsAssignment();
340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_NOT_NULL(assign);
341014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_EQ(Token::ASSIGN, assign->op());
342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  auto initializer = assign->value();
344014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  auto value = initializer;
345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (IsInitializerContext()) {
347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // let {<pattern> = <init>} = <value>
348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    //   becomes
349014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // temp = <value>;
350014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // <pattern> = temp === undefined ? <init> : temp;
351014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    auto temp_var = CreateTempVar(current_value_);
352014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Expression* is_undefined = factory()->NewCompareOperation(
353014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Token::EQ_STRICT, factory()->NewVariableProxy(temp_var),
354014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        factory()->NewUndefinedLiteral(RelocInfo::kNoPosition),
355014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        RelocInfo::kNoPosition);
356014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    value = factory()->NewConditional(is_undefined, initializer,
357014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                      factory()->NewVariableProxy(temp_var),
358014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                      RelocInfo::kNoPosition);
359014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  PatternContext old_context = SetAssignmentContextIfNeeded(initializer);
362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int pos = assign->position();
363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Block* old_block = block_;
364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  block_ = factory()->NewBlock(nullptr, 8, false, pos);
365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Variable* temp = nullptr;
366014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Expression* pattern = assign->target();
367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Expression* old_value = current_value_;
368014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  current_value_ = value;
369014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (pattern->IsObjectLiteral()) {
370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    VisitObjectLiteral(pattern->AsObjectLiteral(), &temp);
371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(pattern->IsArrayLiteral());
373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    VisitArrayLiteral(pattern->AsArrayLiteral(), &temp);
374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_NOT_NULL(temp);
376014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  current_value_ = old_value;
377014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Expression* expr = factory()->NewDoExpression(block_, temp, pos);
378014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  node->Rewrite(expr);
379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  block_ = old_block;
380014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (block_) {
381014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    block_->statements()->Add(factory()->NewExpressionStatement(expr, pos),
382014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                              zone());
383014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
384014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return set_context(old_context);
385014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
387014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
388014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Parser::PatternRewriter::VisitObjectLiteral(ObjectLiteral* pattern,
389014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                 Variable** temp_var) {
390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  auto temp = *temp_var = CreateTempVar(current_value_);
391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  block_->statements()->Add(parser_->BuildAssertIsCoercible(temp), zone());
393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
394014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (ObjectLiteralProperty* property : *pattern->properties()) {
395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    PatternContext context = SetInitializerContextIfNeeded(property->value());
396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    RecurseIntoSubpattern(
397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        property->value(),
398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        factory()->NewProperty(factory()->NewVariableProxy(temp),
399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                               property->key(), RelocInfo::kNoPosition));
400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    set_context(context);
401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Parser::PatternRewriter::VisitObjectLiteral(ObjectLiteral* node) {
406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Variable* temp_var = nullptr;
407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VisitObjectLiteral(node, &temp_var);
408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
411014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Parser::PatternRewriter::VisitArrayLiteral(ArrayLiteral* node,
412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                Variable** temp_var) {
413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  auto temp = *temp_var = CreateTempVar(current_value_);
414014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  block_->statements()->Add(parser_->BuildAssertIsCoercible(temp), zone());
416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  auto iterator = CreateTempVar(parser_->GetIterator(
418014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      factory()->NewVariableProxy(temp), factory(), RelocInfo::kNoPosition));
419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  auto done = CreateTempVar(
420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      factory()->NewBooleanLiteral(false, RelocInfo::kNoPosition));
421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  auto result = CreateTempVar();
422014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  auto v = CreateTempVar();
423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
424014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Spread* spread = nullptr;
425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (Expression* value : *node->values()) {
426014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (value->IsSpread()) {
427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      spread = value->AsSpread();
428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
429014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
431014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    PatternContext context = SetInitializerContextIfNeeded(value);
432014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // if (!done) {
433014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    //   result = IteratorNext(iterator);
434014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    //   v = (done = result.done) ? undefined : result.value;
435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // }
436014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    auto next_block =
437014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        factory()->NewBlock(nullptr, 2, true, RelocInfo::kNoPosition);
438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    next_block->statements()->Add(factory()->NewExpressionStatement(
439014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                      parser_->BuildIteratorNextResult(
440014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                          factory()->NewVariableProxy(iterator),
441014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                          result, RelocInfo::kNoPosition),
442014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                      RelocInfo::kNoPosition),
443014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                  zone());
444014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
445014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    auto assign_to_done = factory()->NewAssignment(
446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Token::ASSIGN, factory()->NewVariableProxy(done),
447014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        factory()->NewProperty(
448014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            factory()->NewVariableProxy(result),
449014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            factory()->NewStringLiteral(ast_value_factory()->done_string(),
450014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                        RelocInfo::kNoPosition),
451014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            RelocInfo::kNoPosition),
452014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        RelocInfo::kNoPosition);
453014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    auto next_value = factory()->NewConditional(
454014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        assign_to_done, factory()->NewUndefinedLiteral(RelocInfo::kNoPosition),
455014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        factory()->NewProperty(
456014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            factory()->NewVariableProxy(result),
457014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            factory()->NewStringLiteral(ast_value_factory()->value_string(),
458014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                        RelocInfo::kNoPosition),
459014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            RelocInfo::kNoPosition),
460014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        RelocInfo::kNoPosition);
461014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    next_block->statements()->Add(
462014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        factory()->NewExpressionStatement(
463014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            factory()->NewAssignment(Token::ASSIGN,
464014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                     factory()->NewVariableProxy(v), next_value,
465014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                     RelocInfo::kNoPosition),
466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            RelocInfo::kNoPosition),
467014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        zone());
468014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
469014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    auto if_statement = factory()->NewIfStatement(
470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        factory()->NewUnaryOperation(Token::NOT,
471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                     factory()->NewVariableProxy(done),
472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                     RelocInfo::kNoPosition),
473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        next_block, factory()->NewEmptyStatement(RelocInfo::kNoPosition),
474014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        RelocInfo::kNoPosition);
475014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    block_->statements()->Add(if_statement, zone());
476014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
477014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!(value->IsLiteral() && value->AsLiteral()->raw_value()->IsTheHole())) {
478014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      RecurseIntoSubpattern(value, factory()->NewVariableProxy(v));
479014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
480014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    set_context(context);
481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
482014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (spread != nullptr) {
484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // array = [];
485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // if (!done) %concat_iterable_to_array(array, iterator);
486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    auto empty_exprs = new (zone()) ZoneList<Expression*>(0, zone());
487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    auto array = CreateTempVar(factory()->NewArrayLiteral(
488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        empty_exprs,
489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // Reuse pattern's literal index - it is unused since there is no
490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // actual literal allocated.
491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        node->literal_index(), is_strong(scope()->language_mode()),
492014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        RelocInfo::kNoPosition));
493014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
494014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    auto arguments = new (zone()) ZoneList<Expression*>(2, zone());
495014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    arguments->Add(factory()->NewVariableProxy(array), zone());
496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    arguments->Add(factory()->NewVariableProxy(iterator), zone());
497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    auto spread_into_array_call =
498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        factory()->NewCallRuntime(Context::CONCAT_ITERABLE_TO_ARRAY_INDEX,
499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                  arguments, RelocInfo::kNoPosition);
500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    auto if_statement = factory()->NewIfStatement(
502014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        factory()->NewUnaryOperation(Token::NOT,
503014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                     factory()->NewVariableProxy(done),
504014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                     RelocInfo::kNoPosition),
505014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        factory()->NewExpressionStatement(spread_into_array_call,
506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                          RelocInfo::kNoPosition),
507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        factory()->NewEmptyStatement(RelocInfo::kNoPosition),
508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        RelocInfo::kNoPosition);
509014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    block_->statements()->Add(if_statement, zone());
510014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    RecurseIntoSubpattern(spread->expression(),
512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                          factory()->NewVariableProxy(array));
513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
515014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
516014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
517014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Parser::PatternRewriter::VisitArrayLiteral(ArrayLiteral* node) {
518014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Variable* temp_var = nullptr;
519014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VisitArrayLiteral(node, &temp_var);
520014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
521014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
522014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
523014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Parser::PatternRewriter::VisitAssignment(Assignment* node) {
524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // let {<pattern> = <init>} = <value>
525014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //   becomes
526014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // temp = <value>;
527014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // <pattern> = temp === undefined ? <init> : temp;
528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_EQ(Token::ASSIGN, node->op());
529014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
530014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  auto initializer = node->value();
531014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  auto value = initializer;
532014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  auto temp = CreateTempVar(current_value_);
533014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
534014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (IsInitializerContext()) {
535014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Expression* is_undefined = factory()->NewCompareOperation(
536014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Token::EQ_STRICT, factory()->NewVariableProxy(temp),
537014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        factory()->NewUndefinedLiteral(RelocInfo::kNoPosition),
538014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        RelocInfo::kNoPosition);
539014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    value = factory()->NewConditional(is_undefined, initializer,
540014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                      factory()->NewVariableProxy(temp),
541014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                      RelocInfo::kNoPosition);
542014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
543014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
544014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (IsBindingContext() &&
545014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      descriptor_->declaration_kind == DeclarationDescriptor::PARAMETER &&
546014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      scope()->is_arrow_scope()) {
547014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    RewriteParameterInitializerScope(parser_->stack_limit(), initializer,
548014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                     scope()->outer_scope(), scope());
549014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  PatternContext old_context = SetAssignmentContextIfNeeded(initializer);
552014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  RecurseIntoSubpattern(node->target(), value);
553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  set_context(old_context);
554014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
555014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
557014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// =============== AssignmentPattern only ==================
558014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
559014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Parser::PatternRewriter::VisitProperty(v8::internal::Property* node) {
560014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(IsAssignmentContext());
561014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  auto value = current_value_;
562014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
563014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Assignment* assignment =
564014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      factory()->NewAssignment(Token::ASSIGN, node, value, node->position());
565014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
566014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  block_->statements()->Add(
567014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition),
568014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      zone());
569014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
570014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
571014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
572014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// =============== UNREACHABLE =============================
573014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
574014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Parser::PatternRewriter::Visit(AstNode* node) { UNREACHABLE(); }
575014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
576014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define NOT_A_PATTERN(Node)                                        \
577014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void Parser::PatternRewriter::Visit##Node(v8::internal::Node*) { \
578014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    UNREACHABLE();                                                 \
579014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
580014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
581014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNOT_A_PATTERN(BinaryOperation)
582014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNOT_A_PATTERN(Block)
583014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNOT_A_PATTERN(BreakStatement)
584014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNOT_A_PATTERN(Call)
585014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNOT_A_PATTERN(CallNew)
586014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNOT_A_PATTERN(CallRuntime)
587014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNOT_A_PATTERN(CaseClause)
588014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNOT_A_PATTERN(ClassLiteral)
589014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNOT_A_PATTERN(CompareOperation)
590014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNOT_A_PATTERN(Conditional)
591014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNOT_A_PATTERN(ContinueStatement)
592014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNOT_A_PATTERN(CountOperation)
593014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNOT_A_PATTERN(DebuggerStatement)
594014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNOT_A_PATTERN(DoExpression)
595014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNOT_A_PATTERN(DoWhileStatement)
596014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNOT_A_PATTERN(EmptyStatement)
597014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNOT_A_PATTERN(EmptyParentheses)
598014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNOT_A_PATTERN(ExportDeclaration)
599014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNOT_A_PATTERN(ExpressionStatement)
600014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNOT_A_PATTERN(ForInStatement)
601014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNOT_A_PATTERN(ForOfStatement)
602014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNOT_A_PATTERN(ForStatement)
603014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNOT_A_PATTERN(FunctionDeclaration)
604014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNOT_A_PATTERN(FunctionLiteral)
605014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNOT_A_PATTERN(IfStatement)
606014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNOT_A_PATTERN(ImportDeclaration)
607014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNOT_A_PATTERN(Literal)
608014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNOT_A_PATTERN(NativeFunctionLiteral)
609014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNOT_A_PATTERN(RegExpLiteral)
610014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNOT_A_PATTERN(ReturnStatement)
611014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNOT_A_PATTERN(SloppyBlockFunctionStatement)
612014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNOT_A_PATTERN(Spread)
613014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNOT_A_PATTERN(SuperPropertyReference)
614014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNOT_A_PATTERN(SuperCallReference)
615014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNOT_A_PATTERN(SwitchStatement)
616014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNOT_A_PATTERN(ThisFunction)
617014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNOT_A_PATTERN(Throw)
618014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNOT_A_PATTERN(TryCatchStatement)
619014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNOT_A_PATTERN(TryFinallyStatement)
620014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNOT_A_PATTERN(UnaryOperation)
621014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNOT_A_PATTERN(VariableDeclaration)
622014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNOT_A_PATTERN(WhileStatement)
623014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNOT_A_PATTERN(WithStatement)
624014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochNOT_A_PATTERN(Yield)
625014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
626014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef NOT_A_PATTERN
627014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace internal
628014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace v8
629