1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "src/parsing/parser.h"
6 
7 #include <memory>
8 
9 #include "src/api.h"
10 #include "src/ast/ast-expression-rewriter.h"
11 #include "src/ast/ast-literal-reindexer.h"
12 #include "src/ast/ast-traversal-visitor.h"
13 #include "src/ast/ast.h"
14 #include "src/bailout-reason.h"
15 #include "src/base/platform/platform.h"
16 #include "src/char-predicates-inl.h"
17 #include "src/messages.h"
18 #include "src/parsing/duplicate-finder.h"
19 #include "src/parsing/parameter-initializer-rewriter.h"
20 #include "src/parsing/parse-info.h"
21 #include "src/parsing/rewriter.h"
22 #include "src/parsing/scanner-character-streams.h"
23 #include "src/runtime/runtime.h"
24 #include "src/string-stream.h"
25 #include "src/tracing/trace-event.h"
26 
27 namespace v8 {
28 namespace internal {
29 
ScriptData(const byte * data,int length)30 ScriptData::ScriptData(const byte* data, int length)
31     : owns_data_(false), rejected_(false), data_(data), length_(length) {
32   if (!IsAligned(reinterpret_cast<intptr_t>(data), kPointerAlignment)) {
33     byte* copy = NewArray<byte>(length);
34     DCHECK(IsAligned(reinterpret_cast<intptr_t>(copy), kPointerAlignment));
35     CopyBytes(copy, data, length);
36     data_ = copy;
37     AcquireDataOwnership();
38   }
39 }
40 
GetFunctionEntry(int start)41 FunctionEntry ParseData::GetFunctionEntry(int start) {
42   // The current pre-data entry must be a FunctionEntry with the given
43   // start position.
44   if ((function_index_ + FunctionEntry::kSize <= Length()) &&
45       (static_cast<int>(Data()[function_index_]) == start)) {
46     int index = function_index_;
47     function_index_ += FunctionEntry::kSize;
48     Vector<unsigned> subvector(&(Data()[index]), FunctionEntry::kSize);
49     return FunctionEntry(subvector);
50   }
51   return FunctionEntry();
52 }
53 
54 
FunctionCount()55 int ParseData::FunctionCount() {
56   int functions_size = FunctionsSize();
57   if (functions_size < 0) return 0;
58   if (functions_size % FunctionEntry::kSize != 0) return 0;
59   return functions_size / FunctionEntry::kSize;
60 }
61 
62 
IsSane()63 bool ParseData::IsSane() {
64   if (!IsAligned(script_data_->length(), sizeof(unsigned))) return false;
65   // Check that the header data is valid and doesn't specify
66   // point to positions outside the store.
67   int data_length = Length();
68   if (data_length < PreparseDataConstants::kHeaderSize) return false;
69   if (Magic() != PreparseDataConstants::kMagicNumber) return false;
70   if (Version() != PreparseDataConstants::kCurrentVersion) return false;
71   // Check that the space allocated for function entries is sane.
72   int functions_size = FunctionsSize();
73   if (functions_size < 0) return false;
74   if (functions_size % FunctionEntry::kSize != 0) return false;
75   // Check that the total size has room for header and function entries.
76   int minimum_size =
77       PreparseDataConstants::kHeaderSize + functions_size;
78   if (data_length < minimum_size) return false;
79   return true;
80 }
81 
82 
Initialize()83 void ParseData::Initialize() {
84   // Prepares state for use.
85   int data_length = Length();
86   if (data_length >= PreparseDataConstants::kHeaderSize) {
87     function_index_ = PreparseDataConstants::kHeaderSize;
88   }
89 }
90 
91 
Magic()92 unsigned ParseData::Magic() {
93   return Data()[PreparseDataConstants::kMagicOffset];
94 }
95 
96 
Version()97 unsigned ParseData::Version() {
98   return Data()[PreparseDataConstants::kVersionOffset];
99 }
100 
101 
FunctionsSize()102 int ParseData::FunctionsSize() {
103   return static_cast<int>(Data()[PreparseDataConstants::kFunctionsSizeOffset]);
104 }
105 
106 // Helper for putting parts of the parse results into a temporary zone when
107 // parsing inner function bodies.
108 class DiscardableZoneScope {
109  public:
DiscardableZoneScope(Parser * parser,Zone * temp_zone,bool use_temp_zone)110   DiscardableZoneScope(Parser* parser, Zone* temp_zone, bool use_temp_zone)
111       : ast_node_factory_scope_(parser->factory(), temp_zone, use_temp_zone),
112         fni_(parser->ast_value_factory_, temp_zone),
113         parser_(parser),
114         prev_fni_(parser->fni_),
115         prev_zone_(parser->zone_) {
116     if (use_temp_zone) {
117       parser_->fni_ = &fni_;
118       parser_->zone_ = temp_zone;
119       if (parser_->reusable_preparser_ != nullptr) {
120         parser_->reusable_preparser_->zone_ = temp_zone;
121         parser_->reusable_preparser_->factory()->set_zone(temp_zone);
122       }
123     }
124   }
Reset()125   void Reset() {
126     parser_->fni_ = prev_fni_;
127     parser_->zone_ = prev_zone_;
128     if (parser_->reusable_preparser_ != nullptr) {
129       parser_->reusable_preparser_->zone_ = prev_zone_;
130       parser_->reusable_preparser_->factory()->set_zone(prev_zone_);
131     }
132     ast_node_factory_scope_.Reset();
133   }
~DiscardableZoneScope()134   ~DiscardableZoneScope() { Reset(); }
135 
136  private:
137   AstNodeFactory::BodyScope ast_node_factory_scope_;
138   FuncNameInferrer fni_;
139   Parser* parser_;
140   FuncNameInferrer* prev_fni_;
141   Zone* prev_zone_;
142 
143   DISALLOW_COPY_AND_ASSIGN(DiscardableZoneScope);
144 };
145 
SetCachedData(ParseInfo * info)146 void Parser::SetCachedData(ParseInfo* info) {
147   DCHECK_NULL(cached_parse_data_);
148   if (consume_cached_parse_data()) {
149     cached_parse_data_ = ParseData::FromCachedData(*info->cached_data());
150     if (cached_parse_data_ == nullptr) {
151       compile_options_ = ScriptCompiler::kNoCompileOptions;
152     }
153   }
154 }
155 
CallClassFieldInitializer(Scope * scope,Expression * this_expr)156 Expression* Parser::CallClassFieldInitializer(Scope* scope,
157                                               Expression* this_expr) {
158   // This produces the expression
159   // `.class_field_intializer(this_expr)`, where '.class_field_intializer' is
160   // the name
161   // of a synthetic variable.
162   // 'this_expr' will be 'this' in a base constructor and the result of calling
163   // 'super' in a derived one.
164   const AstRawString* init_fn_name =
165       ast_value_factory()->dot_class_field_init_string();
166   VariableProxy* init_fn_proxy = scope->NewUnresolved(factory(), init_fn_name);
167   ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
168   args->Add(init_fn_proxy, zone());
169   args->Add(this_expr, zone());
170   return factory()->NewCallRuntime(Runtime::kInlineCall, args,
171                                    kNoSourcePosition);
172 }
173 
RewriteSuperCall(Expression * super_call)174 Expression* Parser::RewriteSuperCall(Expression* super_call) {
175   // TODO(bakkot) find a way to avoid this for classes without fields.
176   if (!allow_harmony_class_fields()) {
177     return super_call;
178   }
179   // This turns a super call `super()` into a do expression of the form
180   // do {
181   //   tmp x = super();
182   //   if (.class-field-init)
183   //     .class-field-init(x)
184   //   x; // This isn't actually present; our do-expression representation
185   // allows specifying that the expression returns x directly.
186   // }
187   Variable* var_tmp =
188       scope()->NewTemporary(ast_value_factory()->empty_string());
189   Block* block = factory()->NewBlock(nullptr, 1, false, kNoSourcePosition);
190   Assignment* assignment = factory()->NewAssignment(
191       Token::ASSIGN, factory()->NewVariableProxy(var_tmp), super_call,
192       kNoSourcePosition);
193   block->statements()->Add(
194       factory()->NewExpressionStatement(assignment, kNoSourcePosition), zone());
195   const AstRawString* init_fn_name =
196       ast_value_factory()->dot_class_field_init_string();
197   VariableProxy* init_fn_proxy =
198       scope()->NewUnresolved(factory(), init_fn_name);
199   Expression* condition = init_fn_proxy;
200   Statement* initialize = factory()->NewExpressionStatement(
201       CallClassFieldInitializer(scope(), factory()->NewVariableProxy(var_tmp)),
202       kNoSourcePosition);
203   IfStatement* if_statement = factory()->NewIfStatement(
204       condition, initialize, factory()->NewEmptyStatement(kNoSourcePosition),
205       kNoSourcePosition);
206   block->statements()->Add(if_statement, zone());
207   return factory()->NewDoExpression(block, var_tmp, kNoSourcePosition);
208 }
209 
DefaultConstructor(const AstRawString * name,bool call_super,bool requires_class_field_init,int pos,int end_pos,LanguageMode language_mode)210 FunctionLiteral* Parser::DefaultConstructor(const AstRawString* name,
211                                             bool call_super,
212                                             bool requires_class_field_init,
213                                             int pos, int end_pos,
214                                             LanguageMode language_mode) {
215   int materialized_literal_count = -1;
216   int expected_property_count = -1;
217   const int parameter_count = 0;
218   if (name == nullptr) name = ast_value_factory()->empty_string();
219 
220   FunctionKind kind = call_super ? FunctionKind::kDefaultSubclassConstructor
221                                  : FunctionKind::kDefaultBaseConstructor;
222   DeclarationScope* function_scope = NewFunctionScope(kind);
223   SetLanguageMode(function_scope,
224                   static_cast<LanguageMode>(language_mode | STRICT));
225   // Set start and end position to the same value
226   function_scope->set_start_position(pos);
227   function_scope->set_end_position(pos);
228   ZoneList<Statement*>* body = NULL;
229 
230   {
231     FunctionState function_state(&function_state_, &scope_state_,
232                                  function_scope);
233 
234     body = new (zone()) ZoneList<Statement*>(call_super ? 2 : 1, zone());
235     if (call_super) {
236       // $super_constructor = %_GetSuperConstructor(<this-function>)
237       // %reflect_construct(
238       //     $super_constructor, InternalArray(...args), new.target)
239       auto constructor_args_name = ast_value_factory()->empty_string();
240       bool is_duplicate;
241       bool is_rest = true;
242       bool is_optional = false;
243       Variable* constructor_args = function_scope->DeclareParameter(
244           constructor_args_name, TEMPORARY, is_optional, is_rest, &is_duplicate,
245           ast_value_factory());
246 
247       ZoneList<Expression*>* args =
248           new (zone()) ZoneList<Expression*>(2, zone());
249       VariableProxy* this_function_proxy =
250           NewUnresolved(ast_value_factory()->this_function_string(), pos);
251       ZoneList<Expression*>* tmp =
252           new (zone()) ZoneList<Expression*>(1, zone());
253       tmp->Add(this_function_proxy, zone());
254       Expression* super_constructor = factory()->NewCallRuntime(
255           Runtime::kInlineGetSuperConstructor, tmp, pos);
256       args->Add(super_constructor, zone());
257       Spread* spread_args = factory()->NewSpread(
258           factory()->NewVariableProxy(constructor_args), pos, pos);
259       ZoneList<Expression*>* spread_args_expr =
260           new (zone()) ZoneList<Expression*>(1, zone());
261       spread_args_expr->Add(spread_args, zone());
262       args->AddAll(*PrepareSpreadArguments(spread_args_expr), zone());
263       VariableProxy* new_target_proxy =
264           NewUnresolved(ast_value_factory()->new_target_string(), pos);
265       args->Add(new_target_proxy, zone());
266       Expression* call = factory()->NewCallRuntime(
267           Context::REFLECT_CONSTRUCT_INDEX, args, pos);
268       if (requires_class_field_init) {
269         call = CallClassFieldInitializer(scope(), call);
270       }
271       body->Add(factory()->NewReturnStatement(call, pos), zone());
272     }
273 
274     materialized_literal_count = function_state.materialized_literal_count();
275     expected_property_count = function_state.expected_property_count();
276   }
277 
278   FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
279       name, function_scope, body, materialized_literal_count,
280       expected_property_count, parameter_count, parameter_count,
281       FunctionLiteral::kNoDuplicateParameters,
282       FunctionLiteral::kAnonymousExpression, default_eager_compile_hint(), pos,
283       true);
284 
285   function_literal->set_requires_class_field_init(requires_class_field_init);
286 
287   return function_literal;
288 }
289 
290 // ----------------------------------------------------------------------------
291 // The CHECK_OK macro is a convenient macro to enforce error
292 // handling for functions that may fail (by returning !*ok).
293 //
294 // CAUTION: This macro appends extra statements after a call,
295 // thus it must never be used where only a single statement
296 // is correct (e.g. an if statement branch w/o braces)!
297 
298 #define CHECK_OK_VALUE(x) ok); \
299   if (!*ok) return x;          \
300   ((void)0
301 #define DUMMY )  // to make indentation work
302 #undef DUMMY
303 
304 #define CHECK_OK CHECK_OK_VALUE(nullptr)
305 #define CHECK_OK_VOID CHECK_OK_VALUE(this->Void())
306 
307 #define CHECK_FAILED /**/); \
308   if (failed_) return nullptr;  \
309   ((void)0
310 #define DUMMY )  // to make indentation work
311 #undef DUMMY
312 
313 // ----------------------------------------------------------------------------
314 // Implementation of Parser
315 
ShortcutNumericLiteralBinaryExpression(Expression ** x,Expression * y,Token::Value op,int pos)316 bool Parser::ShortcutNumericLiteralBinaryExpression(Expression** x,
317                                                     Expression* y,
318                                                     Token::Value op, int pos) {
319   if ((*x)->AsLiteral() && (*x)->AsLiteral()->raw_value()->IsNumber() &&
320       y->AsLiteral() && y->AsLiteral()->raw_value()->IsNumber()) {
321     double x_val = (*x)->AsLiteral()->raw_value()->AsNumber();
322     double y_val = y->AsLiteral()->raw_value()->AsNumber();
323     bool x_has_dot = (*x)->AsLiteral()->raw_value()->ContainsDot();
324     bool y_has_dot = y->AsLiteral()->raw_value()->ContainsDot();
325     bool has_dot = x_has_dot || y_has_dot;
326     switch (op) {
327       case Token::ADD:
328         *x = factory()->NewNumberLiteral(x_val + y_val, pos, has_dot);
329         return true;
330       case Token::SUB:
331         *x = factory()->NewNumberLiteral(x_val - y_val, pos, has_dot);
332         return true;
333       case Token::MUL:
334         *x = factory()->NewNumberLiteral(x_val * y_val, pos, has_dot);
335         return true;
336       case Token::DIV:
337         *x = factory()->NewNumberLiteral(x_val / y_val, pos, has_dot);
338         return true;
339       case Token::BIT_OR: {
340         int value = DoubleToInt32(x_val) | DoubleToInt32(y_val);
341         *x = factory()->NewNumberLiteral(value, pos, has_dot);
342         return true;
343       }
344       case Token::BIT_AND: {
345         int value = DoubleToInt32(x_val) & DoubleToInt32(y_val);
346         *x = factory()->NewNumberLiteral(value, pos, has_dot);
347         return true;
348       }
349       case Token::BIT_XOR: {
350         int value = DoubleToInt32(x_val) ^ DoubleToInt32(y_val);
351         *x = factory()->NewNumberLiteral(value, pos, has_dot);
352         return true;
353       }
354       case Token::SHL: {
355         int value = DoubleToInt32(x_val) << (DoubleToInt32(y_val) & 0x1f);
356         *x = factory()->NewNumberLiteral(value, pos, has_dot);
357         return true;
358       }
359       case Token::SHR: {
360         uint32_t shift = DoubleToInt32(y_val) & 0x1f;
361         uint32_t value = DoubleToUint32(x_val) >> shift;
362         *x = factory()->NewNumberLiteral(value, pos, has_dot);
363         return true;
364       }
365       case Token::SAR: {
366         uint32_t shift = DoubleToInt32(y_val) & 0x1f;
367         int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift);
368         *x = factory()->NewNumberLiteral(value, pos, has_dot);
369         return true;
370       }
371       case Token::EXP: {
372         double value = Pow(x_val, y_val);
373         int int_value = static_cast<int>(value);
374         *x = factory()->NewNumberLiteral(
375             int_value == value && value != -0.0 ? int_value : value, pos,
376             has_dot);
377         return true;
378       }
379       default:
380         break;
381     }
382   }
383   return false;
384 }
385 
BuildUnaryExpression(Expression * expression,Token::Value op,int pos)386 Expression* Parser::BuildUnaryExpression(Expression* expression,
387                                          Token::Value op, int pos) {
388   DCHECK(expression != NULL);
389   if (expression->IsLiteral()) {
390     const AstValue* literal = expression->AsLiteral()->raw_value();
391     if (op == Token::NOT) {
392       // Convert the literal to a boolean condition and negate it.
393       bool condition = literal->BooleanValue();
394       return factory()->NewBooleanLiteral(!condition, pos);
395     } else if (literal->IsNumber()) {
396       // Compute some expressions involving only number literals.
397       double value = literal->AsNumber();
398       bool has_dot = literal->ContainsDot();
399       switch (op) {
400         case Token::ADD:
401           return expression;
402         case Token::SUB:
403           return factory()->NewNumberLiteral(-value, pos, has_dot);
404         case Token::BIT_NOT:
405           return factory()->NewNumberLiteral(~DoubleToInt32(value), pos,
406                                              has_dot);
407         default:
408           break;
409       }
410     }
411   }
412   // Desugar '+foo' => 'foo*1'
413   if (op == Token::ADD) {
414     return factory()->NewBinaryOperation(
415         Token::MUL, expression, factory()->NewNumberLiteral(1, pos, true), pos);
416   }
417   // The same idea for '-foo' => 'foo*(-1)'.
418   if (op == Token::SUB) {
419     return factory()->NewBinaryOperation(
420         Token::MUL, expression, factory()->NewNumberLiteral(-1, pos), pos);
421   }
422   // ...and one more time for '~foo' => 'foo^(~0)'.
423   if (op == Token::BIT_NOT) {
424     return factory()->NewBinaryOperation(
425         Token::BIT_XOR, expression, factory()->NewNumberLiteral(~0, pos), pos);
426   }
427   return factory()->NewUnaryOperation(op, expression, pos);
428 }
429 
BuildIteratorResult(Expression * value,bool done)430 Expression* Parser::BuildIteratorResult(Expression* value, bool done) {
431   int pos = kNoSourcePosition;
432 
433   if (value == nullptr) value = factory()->NewUndefinedLiteral(pos);
434 
435   auto args = new (zone()) ZoneList<Expression*>(2, zone());
436   args->Add(value, zone());
437   args->Add(factory()->NewBooleanLiteral(done, pos), zone());
438 
439   return factory()->NewCallRuntime(Runtime::kInlineCreateIterResultObject, args,
440                                    pos);
441 }
442 
NewThrowError(Runtime::FunctionId id,MessageTemplate::Template message,const AstRawString * arg,int pos)443 Expression* Parser::NewThrowError(Runtime::FunctionId id,
444                                   MessageTemplate::Template message,
445                                   const AstRawString* arg, int pos) {
446   ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
447   args->Add(factory()->NewSmiLiteral(message, pos), zone());
448   args->Add(factory()->NewStringLiteral(arg, pos), zone());
449   CallRuntime* call_constructor = factory()->NewCallRuntime(id, args, pos);
450   return factory()->NewThrow(call_constructor, pos);
451 }
452 
NewSuperPropertyReference(int pos)453 Expression* Parser::NewSuperPropertyReference(int pos) {
454   // this_function[home_object_symbol]
455   VariableProxy* this_function_proxy =
456       NewUnresolved(ast_value_factory()->this_function_string(), pos);
457   Expression* home_object_symbol_literal =
458       factory()->NewSymbolLiteral("home_object_symbol", kNoSourcePosition);
459   Expression* home_object = factory()->NewProperty(
460       this_function_proxy, home_object_symbol_literal, pos);
461   return factory()->NewSuperPropertyReference(
462       ThisExpression(pos)->AsVariableProxy(), home_object, pos);
463 }
464 
NewSuperCallReference(int pos)465 Expression* Parser::NewSuperCallReference(int pos) {
466   VariableProxy* new_target_proxy =
467       NewUnresolved(ast_value_factory()->new_target_string(), pos);
468   VariableProxy* this_function_proxy =
469       NewUnresolved(ast_value_factory()->this_function_string(), pos);
470   return factory()->NewSuperCallReference(
471       ThisExpression(pos)->AsVariableProxy(), new_target_proxy,
472       this_function_proxy, pos);
473 }
474 
NewTargetExpression(int pos)475 Expression* Parser::NewTargetExpression(int pos) {
476   auto proxy = NewUnresolved(ast_value_factory()->new_target_string(), pos);
477   proxy->set_is_new_target();
478   return proxy;
479 }
480 
FunctionSentExpression(int pos)481 Expression* Parser::FunctionSentExpression(int pos) {
482   // We desugar function.sent into %_GeneratorGetInputOrDebugPos(generator).
483   ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(1, zone());
484   VariableProxy* generator =
485       factory()->NewVariableProxy(function_state_->generator_object_variable());
486   args->Add(generator, zone());
487   return factory()->NewCallRuntime(Runtime::kInlineGeneratorGetInputOrDebugPos,
488                                    args, pos);
489 }
490 
ExpressionFromLiteral(Token::Value token,int pos)491 Literal* Parser::ExpressionFromLiteral(Token::Value token, int pos) {
492   switch (token) {
493     case Token::NULL_LITERAL:
494       return factory()->NewNullLiteral(pos);
495     case Token::TRUE_LITERAL:
496       return factory()->NewBooleanLiteral(true, pos);
497     case Token::FALSE_LITERAL:
498       return factory()->NewBooleanLiteral(false, pos);
499     case Token::SMI: {
500       uint32_t value = scanner()->smi_value();
501       return factory()->NewSmiLiteral(value, pos);
502     }
503     case Token::NUMBER: {
504       bool has_dot = scanner()->ContainsDot();
505       double value = scanner()->DoubleValue();
506       return factory()->NewNumberLiteral(value, pos, has_dot);
507     }
508     default:
509       DCHECK(false);
510   }
511   return NULL;
512 }
513 
GetIterator(Expression * iterable,int pos)514 Expression* Parser::GetIterator(Expression* iterable, int pos) {
515   Expression* iterator_symbol_literal =
516       factory()->NewSymbolLiteral("iterator_symbol", kNoSourcePosition);
517   Expression* prop =
518       factory()->NewProperty(iterable, iterator_symbol_literal, pos);
519   ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(0, zone());
520   return factory()->NewCall(prop, args, pos);
521 }
522 
MarkTailPosition(Expression * expression)523 void Parser::MarkTailPosition(Expression* expression) {
524   expression->MarkTail();
525 }
526 
NewV8Intrinsic(const AstRawString * name,ZoneList<Expression * > * args,int pos,bool * ok)527 Expression* Parser::NewV8Intrinsic(const AstRawString* name,
528                                    ZoneList<Expression*>* args, int pos,
529                                    bool* ok) {
530   if (extension_ != nullptr) {
531     // The extension structures are only accessible while parsing the
532     // very first time, not when reparsing because of lazy compilation.
533     GetClosureScope()->ForceEagerCompilation();
534   }
535 
536   DCHECK(name->is_one_byte());
537   const Runtime::Function* function =
538       Runtime::FunctionForName(name->raw_data(), name->length());
539 
540   if (function != nullptr) {
541     // Check for possible name clash.
542     DCHECK_EQ(Context::kNotFound,
543               Context::IntrinsicIndexForName(name->raw_data(), name->length()));
544     // Check for built-in IS_VAR macro.
545     if (function->function_id == Runtime::kIS_VAR) {
546       DCHECK_EQ(Runtime::RUNTIME, function->intrinsic_type);
547       // %IS_VAR(x) evaluates to x if x is a variable,
548       // leads to a parse error otherwise.  Could be implemented as an
549       // inline function %_IS_VAR(x) to eliminate this special case.
550       if (args->length() == 1 && args->at(0)->AsVariableProxy() != nullptr) {
551         return args->at(0);
552       } else {
553         ReportMessage(MessageTemplate::kNotIsvar);
554         *ok = false;
555         return nullptr;
556       }
557     }
558 
559     // Check that the expected number of arguments are being passed.
560     if (function->nargs != -1 && function->nargs != args->length()) {
561       ReportMessage(MessageTemplate::kRuntimeWrongNumArgs);
562       *ok = false;
563       return nullptr;
564     }
565 
566     return factory()->NewCallRuntime(function, args, pos);
567   }
568 
569   int context_index =
570       Context::IntrinsicIndexForName(name->raw_data(), name->length());
571 
572   // Check that the function is defined.
573   if (context_index == Context::kNotFound) {
574     ReportMessage(MessageTemplate::kNotDefined, name);
575     *ok = false;
576     return nullptr;
577   }
578 
579   return factory()->NewCallRuntime(context_index, args, pos);
580 }
581 
Parser(ParseInfo * info)582 Parser::Parser(ParseInfo* info)
583     : ParserBase<Parser>(info->zone(), &scanner_, info->stack_limit(),
584                          info->extension(), info->ast_value_factory(),
585                          info->isolate()->counters()->runtime_call_stats()),
586       scanner_(info->unicode_cache()),
587       reusable_preparser_(nullptr),
588       original_scope_(nullptr),
589       mode_(PARSE_EAGERLY),  // Lazy mode must be set explicitly.
590       target_stack_(nullptr),
591       compile_options_(info->compile_options()),
592       cached_parse_data_(nullptr),
593       total_preparse_skipped_(0),
594       parsing_on_main_thread_(true),
595       log_(nullptr) {
596   // Even though we were passed ParseInfo, we should not store it in
597   // Parser - this makes sure that Isolate is not accidentally accessed via
598   // ParseInfo during background parsing.
599   DCHECK(!info->script().is_null() || info->source_stream() != nullptr ||
600          info->character_stream() != nullptr);
601   // Determine if functions can be lazily compiled. This is necessary to
602   // allow some of our builtin JS files to be lazily compiled. These
603   // builtins cannot be handled lazily by the parser, since we have to know
604   // if a function uses the special natives syntax, which is something the
605   // parser records.
606   // If the debugger requests compilation for break points, we cannot be
607   // aggressive about lazy compilation, because it might trigger compilation
608   // of functions without an outer context when setting a breakpoint through
609   // Debug::FindSharedFunctionInfoInScript
610   bool can_compile_lazily = FLAG_lazy && !info->is_debug();
611 
612   // Consider compiling eagerly when targeting the code cache.
613   can_compile_lazily &= !(FLAG_serialize_eager && info->will_serialize());
614 
615   set_default_eager_compile_hint(can_compile_lazily
616                                      ? FunctionLiteral::kShouldLazyCompile
617                                      : FunctionLiteral::kShouldEagerCompile);
618   set_allow_lazy(FLAG_lazy && info->allow_lazy_parsing() &&
619                  !info->is_native() && info->extension() == nullptr &&
620                  can_compile_lazily);
621   set_allow_natives(FLAG_allow_natives_syntax || info->is_native());
622   set_allow_tailcalls(FLAG_harmony_tailcalls && !info->is_native() &&
623                       info->isolate()->is_tail_call_elimination_enabled());
624   set_allow_harmony_do_expressions(FLAG_harmony_do_expressions);
625   set_allow_harmony_function_sent(FLAG_harmony_function_sent);
626   set_allow_harmony_async_await(FLAG_harmony_async_await);
627   set_allow_harmony_restrictive_generators(FLAG_harmony_restrictive_generators);
628   set_allow_harmony_trailing_commas(FLAG_harmony_trailing_commas);
629   set_allow_harmony_class_fields(FLAG_harmony_class_fields);
630   for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
631        ++feature) {
632     use_counts_[feature] = 0;
633   }
634   if (info->ast_value_factory() == NULL) {
635     // info takes ownership of AstValueFactory.
636     info->set_ast_value_factory(new AstValueFactory(zone(), info->hash_seed()));
637     info->set_ast_value_factory_owned();
638     ast_value_factory_ = info->ast_value_factory();
639     ast_node_factory_.set_ast_value_factory(ast_value_factory_);
640   }
641 }
642 
DeserializeScopeChain(ParseInfo * info,MaybeHandle<ScopeInfo> maybe_outer_scope_info)643 void Parser::DeserializeScopeChain(
644     ParseInfo* info, MaybeHandle<ScopeInfo> maybe_outer_scope_info) {
645   DCHECK(ThreadId::Current().Equals(info->isolate()->thread_id()));
646   // TODO(wingo): Add an outer SCRIPT_SCOPE corresponding to the native
647   // context, which will have the "this" binding for script scopes.
648   DeclarationScope* script_scope = NewScriptScope();
649   info->set_script_scope(script_scope);
650   Scope* scope = script_scope;
651   Handle<ScopeInfo> outer_scope_info;
652   if (maybe_outer_scope_info.ToHandle(&outer_scope_info)) {
653     scope = Scope::DeserializeScopeChain(
654         info->isolate(), zone(), *outer_scope_info, script_scope,
655         ast_value_factory(), Scope::DeserializationMode::kScopesOnly);
656     DCHECK(!info->is_module() || scope->is_module_scope());
657   }
658   original_scope_ = scope;
659 }
660 
ParseProgram(Isolate * isolate,ParseInfo * info)661 FunctionLiteral* Parser::ParseProgram(Isolate* isolate, ParseInfo* info) {
662   // TODO(bmeurer): We temporarily need to pass allow_nesting = true here,
663   // see comment for HistogramTimerScope class.
664 
665   // It's OK to use the Isolate & counters here, since this function is only
666   // called in the main thread.
667   DCHECK(parsing_on_main_thread_);
668 
669   RuntimeCallTimerScope runtime_timer(
670       runtime_call_stats_, info->is_eval() ? &RuntimeCallStats::ParseEval
671                                            : &RuntimeCallStats::ParseProgram);
672   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.ParseProgram");
673   Handle<String> source(String::cast(info->script()->source()));
674   isolate->counters()->total_parse_size()->Increment(source->length());
675   base::ElapsedTimer timer;
676   if (FLAG_trace_parse) {
677     timer.Start();
678   }
679   fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
680 
681   // Initialize parser state.
682   ParserLogger logger;
683 
684   if (produce_cached_parse_data()) {
685     log_ = &logger;
686   } else if (consume_cached_parse_data()) {
687     cached_parse_data_->Initialize();
688   }
689 
690   DeserializeScopeChain(info, info->maybe_outer_scope_info());
691 
692   source = String::Flatten(source);
693   FunctionLiteral* result;
694 
695   {
696     std::unique_ptr<Utf16CharacterStream> stream(ScannerStream::For(source));
697     scanner_.Initialize(stream.get());
698     result = DoParseProgram(info);
699   }
700   if (result != NULL) {
701     DCHECK_EQ(scanner_.peek_location().beg_pos, source->length());
702   }
703   HandleSourceURLComments(isolate, info->script());
704 
705   if (FLAG_trace_parse && result != nullptr) {
706     double ms = timer.Elapsed().InMillisecondsF();
707     if (info->is_eval()) {
708       PrintF("[parsing eval");
709     } else if (info->script()->name()->IsString()) {
710       String* name = String::cast(info->script()->name());
711       std::unique_ptr<char[]> name_chars = name->ToCString();
712       PrintF("[parsing script: %s", name_chars.get());
713     } else {
714       PrintF("[parsing script");
715     }
716     PrintF(" - took %0.3f ms]\n", ms);
717   }
718   if (produce_cached_parse_data() && result != nullptr) {
719     *info->cached_data() = logger.GetScriptData();
720   }
721   log_ = nullptr;
722   return result;
723 }
724 
725 
DoParseProgram(ParseInfo * info)726 FunctionLiteral* Parser::DoParseProgram(ParseInfo* info) {
727   // Note that this function can be called from the main thread or from a
728   // background thread. We should not access anything Isolate / heap dependent
729   // via ParseInfo, and also not pass it forward.
730   DCHECK_NULL(scope_state_);
731   DCHECK_NULL(target_stack_);
732 
733   ParsingModeScope mode(this, allow_lazy() ? PARSE_LAZILY : PARSE_EAGERLY);
734 
735   FunctionLiteral* result = NULL;
736   {
737     Scope* outer = original_scope_;
738     DCHECK_NOT_NULL(outer);
739     parsing_module_ = info->is_module();
740     if (info->is_eval()) {
741       outer = NewEvalScope(outer);
742     } else if (parsing_module_) {
743       DCHECK_EQ(outer, info->script_scope());
744       outer = NewModuleScope(info->script_scope());
745     }
746 
747     DeclarationScope* scope = outer->AsDeclarationScope();
748 
749     scope->set_start_position(0);
750 
751     FunctionState function_state(&function_state_, &scope_state_, scope);
752 
753     ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone());
754     bool ok = true;
755     int beg_pos = scanner()->location().beg_pos;
756     if (parsing_module_) {
757       // Declare the special module parameter.
758       auto name = ast_value_factory()->empty_string();
759       bool is_duplicate;
760       bool is_rest = false;
761       bool is_optional = false;
762       auto var = scope->DeclareParameter(name, VAR, is_optional, is_rest,
763                                          &is_duplicate, ast_value_factory());
764       DCHECK(!is_duplicate);
765       var->AllocateTo(VariableLocation::PARAMETER, 0);
766 
767       PrepareGeneratorVariables(&function_state);
768       Expression* initial_yield =
769           BuildInitialYield(kNoSourcePosition, kGeneratorFunction);
770       body->Add(
771           factory()->NewExpressionStatement(initial_yield, kNoSourcePosition),
772           zone());
773 
774       ParseModuleItemList(body, &ok);
775       ok = ok &&
776            module()->Validate(this->scope()->AsModuleScope(),
777                               &pending_error_handler_, zone());
778     } else {
779       // Don't count the mode in the use counters--give the program a chance
780       // to enable script-wide strict mode below.
781       this->scope()->SetLanguageMode(info->language_mode());
782       ParseStatementList(body, Token::EOS, &ok);
783     }
784 
785     // The parser will peek but not consume EOS.  Our scope logically goes all
786     // the way to the EOS, though.
787     scope->set_end_position(scanner()->peek_location().beg_pos);
788 
789     if (ok && is_strict(language_mode())) {
790       CheckStrictOctalLiteral(beg_pos, scanner()->location().end_pos, &ok);
791       CheckDecimalLiteralWithLeadingZero(beg_pos,
792                                          scanner()->location().end_pos);
793     }
794     if (ok && is_sloppy(language_mode())) {
795       // TODO(littledan): Function bindings on the global object that modify
796       // pre-existing bindings should be made writable, enumerable and
797       // nonconfigurable if possible, whereas this code will leave attributes
798       // unchanged if the property already exists.
799       InsertSloppyBlockFunctionVarBindings(scope);
800     }
801     if (ok) {
802       CheckConflictingVarDeclarations(scope, &ok);
803     }
804 
805     if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) {
806       if (body->length() != 1 ||
807           !body->at(0)->IsExpressionStatement() ||
808           !body->at(0)->AsExpressionStatement()->
809               expression()->IsFunctionLiteral()) {
810         ReportMessage(MessageTemplate::kSingleFunctionLiteral);
811         ok = false;
812       }
813     }
814 
815     if (ok) {
816       RewriteDestructuringAssignments();
817       int parameter_count = parsing_module_ ? 1 : 0;
818       result = factory()->NewScriptOrEvalFunctionLiteral(
819           scope, body, function_state.materialized_literal_count(),
820           function_state.expected_property_count(), parameter_count);
821     }
822   }
823 
824   // Make sure the target stack is empty.
825   DCHECK(target_stack_ == NULL);
826 
827   return result;
828 }
829 
ParseFunction(Isolate * isolate,ParseInfo * info)830 FunctionLiteral* Parser::ParseFunction(Isolate* isolate, ParseInfo* info) {
831   // It's OK to use the Isolate & counters here, since this function is only
832   // called in the main thread.
833   DCHECK(parsing_on_main_thread_);
834   RuntimeCallTimerScope runtime_timer(runtime_call_stats_,
835                                       &RuntimeCallStats::ParseFunction);
836   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.ParseFunction");
837   Handle<String> source(String::cast(info->script()->source()));
838   isolate->counters()->total_parse_size()->Increment(source->length());
839   base::ElapsedTimer timer;
840   if (FLAG_trace_parse) {
841     timer.Start();
842   }
843   Handle<SharedFunctionInfo> shared_info = info->shared_info();
844   DeserializeScopeChain(info, info->maybe_outer_scope_info());
845 
846   // Initialize parser state.
847   source = String::Flatten(source);
848   FunctionLiteral* result;
849   {
850     std::unique_ptr<Utf16CharacterStream> stream(ScannerStream::For(
851         source, shared_info->start_position(), shared_info->end_position()));
852     Handle<String> name(String::cast(shared_info->name()));
853     result = DoParseFunction(info, ast_value_factory()->GetString(name),
854                              stream.get());
855     if (result != nullptr) {
856       Handle<String> inferred_name(shared_info->inferred_name());
857       result->set_inferred_name(inferred_name);
858     }
859   }
860 
861   if (FLAG_trace_parse && result != NULL) {
862     double ms = timer.Elapsed().InMillisecondsF();
863     // We need to make sure that the debug-name is available.
864     ast_value_factory()->Internalize(isolate);
865     std::unique_ptr<char[]> name_chars = result->debug_name()->ToCString();
866     PrintF("[parsing function: %s - took %0.3f ms]\n", name_chars.get(), ms);
867   }
868   return result;
869 }
870 
ComputeFunctionType(ParseInfo * info)871 static FunctionLiteral::FunctionType ComputeFunctionType(ParseInfo* info) {
872   if (info->is_declaration()) {
873     return FunctionLiteral::kDeclaration;
874   } else if (info->is_named_expression()) {
875     return FunctionLiteral::kNamedExpression;
876   } else if (IsConciseMethod(info->function_kind()) ||
877              IsAccessorFunction(info->function_kind())) {
878     return FunctionLiteral::kAccessorOrMethod;
879   }
880   return FunctionLiteral::kAnonymousExpression;
881 }
882 
DoParseFunction(ParseInfo * info,const AstRawString * raw_name,Utf16CharacterStream * source)883 FunctionLiteral* Parser::DoParseFunction(ParseInfo* info,
884                                          const AstRawString* raw_name,
885                                          Utf16CharacterStream* source) {
886   scanner_.Initialize(source);
887   DCHECK_NULL(scope_state_);
888   DCHECK_NULL(target_stack_);
889 
890   DCHECK(ast_value_factory());
891   fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
892   fni_->PushEnclosingName(raw_name);
893 
894   ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
895 
896   // Place holder for the result.
897   FunctionLiteral* result = nullptr;
898 
899   {
900     // Parse the function literal.
901     Scope* outer = original_scope_;
902     DeclarationScope* outer_function = outer->GetClosureScope();
903     DCHECK(outer);
904     FunctionState function_state(&function_state_, &scope_state_,
905                                  outer_function);
906     BlockState block_state(&scope_state_, outer);
907     DCHECK(is_sloppy(outer->language_mode()) ||
908            is_strict(info->language_mode()));
909     FunctionLiteral::FunctionType function_type = ComputeFunctionType(info);
910     FunctionKind kind = info->function_kind();
911     bool ok = true;
912 
913     if (IsArrowFunction(kind)) {
914       if (allow_harmony_async_await() && IsAsyncFunction(kind)) {
915         DCHECK(!scanner()->HasAnyLineTerminatorAfterNext());
916         if (!Check(Token::ASYNC)) {
917           CHECK(stack_overflow());
918           return nullptr;
919         }
920         if (!(peek_any_identifier() || peek() == Token::LPAREN)) {
921           CHECK(stack_overflow());
922           return nullptr;
923         }
924       }
925 
926       // TODO(adamk): We should construct this scope from the ScopeInfo.
927       DeclarationScope* scope = NewFunctionScope(kind);
928 
929       // These two bits only need to be explicitly set because we're
930       // not passing the ScopeInfo to the Scope constructor.
931       // TODO(adamk): Remove these calls once the above NewScope call
932       // passes the ScopeInfo.
933       if (info->calls_eval()) {
934         scope->RecordEvalCall();
935       }
936       SetLanguageMode(scope, info->language_mode());
937 
938       scope->set_start_position(info->start_position());
939       ExpressionClassifier formals_classifier(this);
940       ParserFormalParameters formals(scope);
941       Checkpoint checkpoint(this);
942       {
943         // Parsing patterns as variable reference expression creates
944         // NewUnresolved references in current scope. Entrer arrow function
945         // scope for formal parameter parsing.
946         BlockState block_state(&scope_state_, scope);
947         if (Check(Token::LPAREN)) {
948           // '(' StrictFormalParameters ')'
949           ParseFormalParameterList(&formals, &ok);
950           if (ok) ok = Check(Token::RPAREN);
951         } else {
952           // BindingIdentifier
953           ParseFormalParameter(&formals, &ok);
954           if (ok) DeclareFormalParameter(formals.scope, formals.at(0));
955         }
956       }
957 
958       if (ok) {
959         checkpoint.Restore(&formals.materialized_literals_count);
960         // Pass `accept_IN=true` to ParseArrowFunctionLiteral --- This should
961         // not be observable, or else the preparser would have failed.
962         Expression* expression = ParseArrowFunctionLiteral(true, formals, &ok);
963         if (ok) {
964           // Scanning must end at the same position that was recorded
965           // previously. If not, parsing has been interrupted due to a stack
966           // overflow, at which point the partially parsed arrow function
967           // concise body happens to be a valid expression. This is a problem
968           // only for arrow functions with single expression bodies, since there
969           // is no end token such as "}" for normal functions.
970           if (scanner()->location().end_pos == info->end_position()) {
971             // The pre-parser saw an arrow function here, so the full parser
972             // must produce a FunctionLiteral.
973             DCHECK(expression->IsFunctionLiteral());
974             result = expression->AsFunctionLiteral();
975           } else {
976             ok = false;
977           }
978         }
979       }
980     } else if (IsDefaultConstructor(kind)) {
981       DCHECK_EQ(scope(), outer);
982       bool is_subclass_constructor = IsSubclassConstructor(kind);
983       result = DefaultConstructor(
984           raw_name, is_subclass_constructor, info->requires_class_field_init(),
985           info->start_position(), info->end_position(), info->language_mode());
986       if (!is_subclass_constructor && info->requires_class_field_init()) {
987         result = InsertClassFieldInitializer(result);
988       }
989     } else if (info->is_class_field_initializer()) {
990       Handle<SharedFunctionInfo> shared_info = info->shared_info();
991       DCHECK(!shared_info.is_null());
992       if (shared_info->length() == 0) {
993         result = ParseClassFieldForInitializer(
994             info->start_position() != info->end_position(), &ok);
995       } else {
996         result = SynthesizeClassFieldInitializer(shared_info->length());
997       }
998     } else {
999       result = ParseFunctionLiteral(
1000           raw_name, Scanner::Location::invalid(), kSkipFunctionNameCheck, kind,
1001           kNoSourcePosition, function_type, info->language_mode(), &ok);
1002       if (info->requires_class_field_init()) {
1003         result = InsertClassFieldInitializer(result);
1004       }
1005     }
1006     // Make sure the results agree.
1007     DCHECK(ok == (result != nullptr));
1008   }
1009 
1010   // Make sure the target stack is empty.
1011   DCHECK_NULL(target_stack_);
1012   return result;
1013 }
1014 
ParseModuleItem(bool * ok)1015 Statement* Parser::ParseModuleItem(bool* ok) {
1016   // ecma262/#prod-ModuleItem
1017   // ModuleItem :
1018   //    ImportDeclaration
1019   //    ExportDeclaration
1020   //    StatementListItem
1021 
1022   switch (peek()) {
1023     case Token::IMPORT:
1024       ParseImportDeclaration(CHECK_OK);
1025       return factory()->NewEmptyStatement(kNoSourcePosition);
1026     case Token::EXPORT:
1027       return ParseExportDeclaration(ok);
1028     default:
1029       return ParseStatementListItem(ok);
1030   }
1031 }
1032 
1033 
ParseModuleItemList(ZoneList<Statement * > * body,bool * ok)1034 void Parser::ParseModuleItemList(ZoneList<Statement*>* body, bool* ok) {
1035   // ecma262/#prod-Module
1036   // Module :
1037   //    ModuleBody?
1038   //
1039   // ecma262/#prod-ModuleItemList
1040   // ModuleBody :
1041   //    ModuleItem*
1042 
1043   DCHECK(scope()->is_module_scope());
1044   while (peek() != Token::EOS) {
1045     Statement* stat = ParseModuleItem(CHECK_OK_VOID);
1046     if (stat && !stat->IsEmpty()) {
1047       body->Add(stat, zone());
1048     }
1049   }
1050 }
1051 
1052 
ParseModuleSpecifier(bool * ok)1053 const AstRawString* Parser::ParseModuleSpecifier(bool* ok) {
1054   // ModuleSpecifier :
1055   //    StringLiteral
1056 
1057   Expect(Token::STRING, CHECK_OK);
1058   return GetSymbol();
1059 }
1060 
1061 
ParseExportClause(ZoneList<const AstRawString * > * export_names,ZoneList<Scanner::Location> * export_locations,ZoneList<const AstRawString * > * local_names,Scanner::Location * reserved_loc,bool * ok)1062 void Parser::ParseExportClause(ZoneList<const AstRawString*>* export_names,
1063                                ZoneList<Scanner::Location>* export_locations,
1064                                ZoneList<const AstRawString*>* local_names,
1065                                Scanner::Location* reserved_loc, bool* ok) {
1066   // ExportClause :
1067   //   '{' '}'
1068   //   '{' ExportsList '}'
1069   //   '{' ExportsList ',' '}'
1070   //
1071   // ExportsList :
1072   //   ExportSpecifier
1073   //   ExportsList ',' ExportSpecifier
1074   //
1075   // ExportSpecifier :
1076   //   IdentifierName
1077   //   IdentifierName 'as' IdentifierName
1078 
1079   Expect(Token::LBRACE, CHECK_OK_VOID);
1080 
1081   Token::Value name_tok;
1082   while ((name_tok = peek()) != Token::RBRACE) {
1083     // Keep track of the first reserved word encountered in case our
1084     // caller needs to report an error.
1085     if (!reserved_loc->IsValid() &&
1086         !Token::IsIdentifier(name_tok, STRICT, false, parsing_module_)) {
1087       *reserved_loc = scanner()->location();
1088     }
1089     const AstRawString* local_name = ParseIdentifierName(CHECK_OK_VOID);
1090     const AstRawString* export_name = NULL;
1091     Scanner::Location location = scanner()->location();
1092     if (CheckContextualKeyword(CStrVector("as"))) {
1093       export_name = ParseIdentifierName(CHECK_OK_VOID);
1094       // Set the location to the whole "a as b" string, so that it makes sense
1095       // both for errors due to "a" and for errors due to "b".
1096       location.end_pos = scanner()->location().end_pos;
1097     }
1098     if (export_name == NULL) {
1099       export_name = local_name;
1100     }
1101     export_names->Add(export_name, zone());
1102     local_names->Add(local_name, zone());
1103     export_locations->Add(location, zone());
1104     if (peek() == Token::RBRACE) break;
1105     Expect(Token::COMMA, CHECK_OK_VOID);
1106   }
1107 
1108   Expect(Token::RBRACE, CHECK_OK_VOID);
1109 }
1110 
1111 
ParseNamedImports(int pos,bool * ok)1112 ZoneList<const Parser::NamedImport*>* Parser::ParseNamedImports(
1113     int pos, bool* ok) {
1114   // NamedImports :
1115   //   '{' '}'
1116   //   '{' ImportsList '}'
1117   //   '{' ImportsList ',' '}'
1118   //
1119   // ImportsList :
1120   //   ImportSpecifier
1121   //   ImportsList ',' ImportSpecifier
1122   //
1123   // ImportSpecifier :
1124   //   BindingIdentifier
1125   //   IdentifierName 'as' BindingIdentifier
1126 
1127   Expect(Token::LBRACE, CHECK_OK);
1128 
1129   auto result = new (zone()) ZoneList<const NamedImport*>(1, zone());
1130   while (peek() != Token::RBRACE) {
1131     const AstRawString* import_name = ParseIdentifierName(CHECK_OK);
1132     const AstRawString* local_name = import_name;
1133     Scanner::Location location = scanner()->location();
1134     // In the presence of 'as', the left-side of the 'as' can
1135     // be any IdentifierName. But without 'as', it must be a valid
1136     // BindingIdentifier.
1137     if (CheckContextualKeyword(CStrVector("as"))) {
1138       local_name = ParseIdentifierName(CHECK_OK);
1139     }
1140     if (!Token::IsIdentifier(scanner()->current_token(), STRICT, false,
1141                              parsing_module_)) {
1142       *ok = false;
1143       ReportMessage(MessageTemplate::kUnexpectedReserved);
1144       return nullptr;
1145     } else if (IsEvalOrArguments(local_name)) {
1146       *ok = false;
1147       ReportMessage(MessageTemplate::kStrictEvalArguments);
1148       return nullptr;
1149     }
1150 
1151     DeclareVariable(local_name, CONST, kNeedsInitialization, position(),
1152                     CHECK_OK);
1153 
1154     NamedImport* import =
1155         new (zone()) NamedImport(import_name, local_name, location);
1156     result->Add(import, zone());
1157 
1158     if (peek() == Token::RBRACE) break;
1159     Expect(Token::COMMA, CHECK_OK);
1160   }
1161 
1162   Expect(Token::RBRACE, CHECK_OK);
1163   return result;
1164 }
1165 
1166 
ParseImportDeclaration(bool * ok)1167 void Parser::ParseImportDeclaration(bool* ok) {
1168   // ImportDeclaration :
1169   //   'import' ImportClause 'from' ModuleSpecifier ';'
1170   //   'import' ModuleSpecifier ';'
1171   //
1172   // ImportClause :
1173   //   ImportedDefaultBinding
1174   //   NameSpaceImport
1175   //   NamedImports
1176   //   ImportedDefaultBinding ',' NameSpaceImport
1177   //   ImportedDefaultBinding ',' NamedImports
1178   //
1179   // NameSpaceImport :
1180   //   '*' 'as' ImportedBinding
1181 
1182   int pos = peek_position();
1183   Expect(Token::IMPORT, CHECK_OK_VOID);
1184 
1185   Token::Value tok = peek();
1186 
1187   // 'import' ModuleSpecifier ';'
1188   if (tok == Token::STRING) {
1189     const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK_VOID);
1190     ExpectSemicolon(CHECK_OK_VOID);
1191     module()->AddEmptyImport(module_specifier);
1192     return;
1193   }
1194 
1195   // Parse ImportedDefaultBinding if present.
1196   const AstRawString* import_default_binding = nullptr;
1197   Scanner::Location import_default_binding_loc;
1198   if (tok != Token::MUL && tok != Token::LBRACE) {
1199     import_default_binding =
1200         ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK_VOID);
1201     import_default_binding_loc = scanner()->location();
1202     DeclareVariable(import_default_binding, CONST, kNeedsInitialization, pos,
1203                     CHECK_OK_VOID);
1204   }
1205 
1206   // Parse NameSpaceImport or NamedImports if present.
1207   const AstRawString* module_namespace_binding = nullptr;
1208   Scanner::Location module_namespace_binding_loc;
1209   const ZoneList<const NamedImport*>* named_imports = nullptr;
1210   if (import_default_binding == nullptr || Check(Token::COMMA)) {
1211     switch (peek()) {
1212       case Token::MUL: {
1213         Consume(Token::MUL);
1214         ExpectContextualKeyword(CStrVector("as"), CHECK_OK_VOID);
1215         module_namespace_binding =
1216             ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK_VOID);
1217         module_namespace_binding_loc = scanner()->location();
1218         DeclareVariable(module_namespace_binding, CONST, kCreatedInitialized,
1219                         pos, CHECK_OK_VOID);
1220         break;
1221       }
1222 
1223       case Token::LBRACE:
1224         named_imports = ParseNamedImports(pos, CHECK_OK_VOID);
1225         break;
1226 
1227       default:
1228         *ok = false;
1229         ReportUnexpectedToken(scanner()->current_token());
1230         return;
1231     }
1232   }
1233 
1234   ExpectContextualKeyword(CStrVector("from"), CHECK_OK_VOID);
1235   const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK_VOID);
1236   ExpectSemicolon(CHECK_OK_VOID);
1237 
1238   // Now that we have all the information, we can make the appropriate
1239   // declarations.
1240 
1241   // TODO(neis): Would prefer to call DeclareVariable for each case below rather
1242   // than above and in ParseNamedImports, but then a possible error message
1243   // would point to the wrong location.  Maybe have a DeclareAt version of
1244   // Declare that takes a location?
1245 
1246   if (module_namespace_binding != nullptr) {
1247     module()->AddStarImport(module_namespace_binding, module_specifier,
1248                             module_namespace_binding_loc, zone());
1249   }
1250 
1251   if (import_default_binding != nullptr) {
1252     module()->AddImport(ast_value_factory()->default_string(),
1253                         import_default_binding, module_specifier,
1254                         import_default_binding_loc, zone());
1255   }
1256 
1257   if (named_imports != nullptr) {
1258     if (named_imports->length() == 0) {
1259       module()->AddEmptyImport(module_specifier);
1260     } else {
1261       for (int i = 0; i < named_imports->length(); ++i) {
1262         const NamedImport* import = named_imports->at(i);
1263         module()->AddImport(import->import_name, import->local_name,
1264                             module_specifier, import->location, zone());
1265       }
1266     }
1267   }
1268 }
1269 
1270 
ParseExportDefault(bool * ok)1271 Statement* Parser::ParseExportDefault(bool* ok) {
1272   //  Supports the following productions, starting after the 'default' token:
1273   //    'export' 'default' HoistableDeclaration
1274   //    'export' 'default' ClassDeclaration
1275   //    'export' 'default' AssignmentExpression[In] ';'
1276 
1277   Expect(Token::DEFAULT, CHECK_OK);
1278   Scanner::Location default_loc = scanner()->location();
1279 
1280   ZoneList<const AstRawString*> local_names(1, zone());
1281   Statement* result = nullptr;
1282   switch (peek()) {
1283     case Token::FUNCTION:
1284       result = ParseHoistableDeclaration(&local_names, true, CHECK_OK);
1285       break;
1286 
1287     case Token::CLASS:
1288       Consume(Token::CLASS);
1289       result = ParseClassDeclaration(&local_names, true, CHECK_OK);
1290       break;
1291 
1292     case Token::ASYNC:
1293       if (allow_harmony_async_await() && PeekAhead() == Token::FUNCTION &&
1294           !scanner()->HasAnyLineTerminatorAfterNext()) {
1295         Consume(Token::ASYNC);
1296         result = ParseAsyncFunctionDeclaration(&local_names, true, CHECK_OK);
1297         break;
1298       }
1299     /* falls through */
1300 
1301     default: {
1302       int pos = position();
1303       ExpressionClassifier classifier(this);
1304       Expression* value = ParseAssignmentExpression(true, CHECK_OK);
1305       RewriteNonPattern(CHECK_OK);
1306       SetFunctionName(value, ast_value_factory()->default_string());
1307 
1308       const AstRawString* local_name =
1309           ast_value_factory()->star_default_star_string();
1310       local_names.Add(local_name, zone());
1311 
1312       // It's fine to declare this as CONST because the user has no way of
1313       // writing to it.
1314       Declaration* decl = DeclareVariable(local_name, CONST, pos, CHECK_OK);
1315       decl->proxy()->var()->set_initializer_position(position());
1316 
1317       Assignment* assignment = factory()->NewAssignment(
1318           Token::INIT, decl->proxy(), value, kNoSourcePosition);
1319       result = factory()->NewExpressionStatement(assignment, kNoSourcePosition);
1320 
1321       ExpectSemicolon(CHECK_OK);
1322       break;
1323     }
1324   }
1325 
1326   DCHECK_EQ(local_names.length(), 1);
1327   module()->AddExport(local_names.first(),
1328                       ast_value_factory()->default_string(), default_loc,
1329                       zone());
1330 
1331   DCHECK_NOT_NULL(result);
1332   return result;
1333 }
1334 
ParseExportDeclaration(bool * ok)1335 Statement* Parser::ParseExportDeclaration(bool* ok) {
1336   // ExportDeclaration:
1337   //    'export' '*' 'from' ModuleSpecifier ';'
1338   //    'export' ExportClause ('from' ModuleSpecifier)? ';'
1339   //    'export' VariableStatement
1340   //    'export' Declaration
1341   //    'export' 'default' ... (handled in ParseExportDefault)
1342 
1343   Expect(Token::EXPORT, CHECK_OK);
1344   int pos = position();
1345 
1346   Statement* result = nullptr;
1347   ZoneList<const AstRawString*> names(1, zone());
1348   Scanner::Location loc = scanner()->peek_location();
1349   switch (peek()) {
1350     case Token::DEFAULT:
1351       return ParseExportDefault(ok);
1352 
1353     case Token::MUL: {
1354       Consume(Token::MUL);
1355       loc = scanner()->location();
1356       ExpectContextualKeyword(CStrVector("from"), CHECK_OK);
1357       const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK);
1358       ExpectSemicolon(CHECK_OK);
1359       module()->AddStarExport(module_specifier, loc, zone());
1360       return factory()->NewEmptyStatement(pos);
1361     }
1362 
1363     case Token::LBRACE: {
1364       // There are two cases here:
1365       //
1366       // 'export' ExportClause ';'
1367       // and
1368       // 'export' ExportClause FromClause ';'
1369       //
1370       // In the first case, the exported identifiers in ExportClause must
1371       // not be reserved words, while in the latter they may be. We
1372       // pass in a location that gets filled with the first reserved word
1373       // encountered, and then throw a SyntaxError if we are in the
1374       // non-FromClause case.
1375       Scanner::Location reserved_loc = Scanner::Location::invalid();
1376       ZoneList<const AstRawString*> export_names(1, zone());
1377       ZoneList<Scanner::Location> export_locations(1, zone());
1378       ZoneList<const AstRawString*> original_names(1, zone());
1379       ParseExportClause(&export_names, &export_locations, &original_names,
1380                         &reserved_loc, CHECK_OK);
1381       const AstRawString* module_specifier = nullptr;
1382       if (CheckContextualKeyword(CStrVector("from"))) {
1383         module_specifier = ParseModuleSpecifier(CHECK_OK);
1384       } else if (reserved_loc.IsValid()) {
1385         // No FromClause, so reserved words are invalid in ExportClause.
1386         *ok = false;
1387         ReportMessageAt(reserved_loc, MessageTemplate::kUnexpectedReserved);
1388         return nullptr;
1389       }
1390       ExpectSemicolon(CHECK_OK);
1391       const int length = export_names.length();
1392       DCHECK_EQ(length, original_names.length());
1393       DCHECK_EQ(length, export_locations.length());
1394       if (module_specifier == nullptr) {
1395         for (int i = 0; i < length; ++i) {
1396           module()->AddExport(original_names[i], export_names[i],
1397                               export_locations[i], zone());
1398         }
1399       } else if (length == 0) {
1400         module()->AddEmptyImport(module_specifier);
1401       } else {
1402         for (int i = 0; i < length; ++i) {
1403           module()->AddExport(original_names[i], export_names[i],
1404                               module_specifier, export_locations[i], zone());
1405         }
1406       }
1407       return factory()->NewEmptyStatement(pos);
1408     }
1409 
1410     case Token::FUNCTION:
1411       result = ParseHoistableDeclaration(&names, false, CHECK_OK);
1412       break;
1413 
1414     case Token::CLASS:
1415       Consume(Token::CLASS);
1416       result = ParseClassDeclaration(&names, false, CHECK_OK);
1417       break;
1418 
1419     case Token::VAR:
1420     case Token::LET:
1421     case Token::CONST:
1422       result = ParseVariableStatement(kStatementListItem, &names, CHECK_OK);
1423       break;
1424 
1425     case Token::ASYNC:
1426       if (allow_harmony_async_await()) {
1427         // TODO(neis): Why don't we have the same check here as in
1428         // ParseStatementListItem?
1429         Consume(Token::ASYNC);
1430         result = ParseAsyncFunctionDeclaration(&names, false, CHECK_OK);
1431         break;
1432       }
1433     /* falls through */
1434 
1435     default:
1436       *ok = false;
1437       ReportUnexpectedToken(scanner()->current_token());
1438       return nullptr;
1439   }
1440   loc.end_pos = scanner()->location().end_pos;
1441 
1442   ModuleDescriptor* descriptor = module();
1443   for (int i = 0; i < names.length(); ++i) {
1444     descriptor->AddExport(names[i], names[i], loc, zone());
1445   }
1446 
1447   DCHECK_NOT_NULL(result);
1448   return result;
1449 }
1450 
NewUnresolved(const AstRawString * name,int begin_pos,VariableKind kind)1451 VariableProxy* Parser::NewUnresolved(const AstRawString* name, int begin_pos,
1452                                      VariableKind kind) {
1453   return scope()->NewUnresolved(factory(), name, begin_pos, kind);
1454 }
1455 
NewUnresolved(const AstRawString * name)1456 VariableProxy* Parser::NewUnresolved(const AstRawString* name) {
1457   return scope()->NewUnresolved(factory(), name, scanner()->location().beg_pos);
1458 }
1459 
DeclareVariable(const AstRawString * name,VariableMode mode,int pos,bool * ok)1460 Declaration* Parser::DeclareVariable(const AstRawString* name,
1461                                      VariableMode mode, int pos, bool* ok) {
1462   return DeclareVariable(name, mode, Variable::DefaultInitializationFlag(mode),
1463                          pos, ok);
1464 }
1465 
DeclareVariable(const AstRawString * name,VariableMode mode,InitializationFlag init,int pos,bool * ok)1466 Declaration* Parser::DeclareVariable(const AstRawString* name,
1467                                      VariableMode mode, InitializationFlag init,
1468                                      int pos, bool* ok) {
1469   DCHECK_NOT_NULL(name);
1470   VariableProxy* proxy = factory()->NewVariableProxy(
1471       name, NORMAL_VARIABLE, scanner()->location().beg_pos);
1472   Declaration* declaration =
1473       factory()->NewVariableDeclaration(proxy, this->scope(), pos);
1474   Declare(declaration, DeclarationDescriptor::NORMAL, mode, init, ok, nullptr,
1475           scanner()->location().end_pos);
1476   if (!*ok) return nullptr;
1477   return declaration;
1478 }
1479 
Declare(Declaration * declaration,DeclarationDescriptor::Kind declaration_kind,VariableMode mode,InitializationFlag init,bool * ok,Scope * scope,int var_end_pos)1480 Variable* Parser::Declare(Declaration* declaration,
1481                           DeclarationDescriptor::Kind declaration_kind,
1482                           VariableMode mode, InitializationFlag init, bool* ok,
1483                           Scope* scope, int var_end_pos) {
1484   if (scope == nullptr) {
1485     scope = this->scope();
1486   }
1487   bool sloppy_mode_block_scope_function_redefinition = false;
1488   Variable* variable = scope->DeclareVariable(
1489       declaration, mode, init, allow_harmony_restrictive_generators(),
1490       &sloppy_mode_block_scope_function_redefinition, ok);
1491   if (!*ok) {
1492     // If we only have the start position of a proxy, we can't highlight the
1493     // whole variable name.  Pretend its length is 1 so that we highlight at
1494     // least the first character.
1495     Scanner::Location loc(declaration->proxy()->position(),
1496                           var_end_pos != kNoSourcePosition
1497                               ? var_end_pos
1498                               : declaration->proxy()->position() + 1);
1499     if (declaration_kind == DeclarationDescriptor::NORMAL) {
1500       ReportMessageAt(loc, MessageTemplate::kVarRedeclaration,
1501                       declaration->proxy()->raw_name());
1502     } else {
1503       ReportMessageAt(loc, MessageTemplate::kParamDupe);
1504     }
1505     return nullptr;
1506   }
1507   if (sloppy_mode_block_scope_function_redefinition) {
1508     ++use_counts_[v8::Isolate::kSloppyModeBlockScopedFunctionRedefinition];
1509   }
1510   return variable;
1511 }
1512 
BuildInitializationBlock(DeclarationParsingResult * parsing_result,ZoneList<const AstRawString * > * names,bool * ok)1513 Block* Parser::BuildInitializationBlock(
1514     DeclarationParsingResult* parsing_result,
1515     ZoneList<const AstRawString*>* names, bool* ok) {
1516   Block* result = factory()->NewBlock(
1517       NULL, 1, true, parsing_result->descriptor.declaration_pos);
1518   for (auto declaration : parsing_result->declarations) {
1519     PatternRewriter::DeclareAndInitializeVariables(
1520         this, result, &(parsing_result->descriptor), &declaration, names,
1521         CHECK_OK);
1522   }
1523   return result;
1524 }
1525 
DeclareAndInitializeVariables(Block * block,const DeclarationDescriptor * declaration_descriptor,const DeclarationParsingResult::Declaration * declaration,ZoneList<const AstRawString * > * names,bool * ok)1526 void Parser::DeclareAndInitializeVariables(
1527     Block* block, const DeclarationDescriptor* declaration_descriptor,
1528     const DeclarationParsingResult::Declaration* declaration,
1529     ZoneList<const AstRawString*>* names, bool* ok) {
1530   DCHECK_NOT_NULL(block);
1531   PatternRewriter::DeclareAndInitializeVariables(
1532       this, block, declaration_descriptor, declaration, names, ok);
1533 }
1534 
DeclareFunction(const AstRawString * variable_name,FunctionLiteral * function,int pos,bool is_generator,bool is_async,ZoneList<const AstRawString * > * names,bool * ok)1535 Statement* Parser::DeclareFunction(const AstRawString* variable_name,
1536                                    FunctionLiteral* function, int pos,
1537                                    bool is_generator, bool is_async,
1538                                    ZoneList<const AstRawString*>* names,
1539                                    bool* ok) {
1540   // In ES6, a function behaves as a lexical binding, except in
1541   // a script scope, or the initial scope of eval or another function.
1542   VariableMode mode =
1543       (!scope()->is_declaration_scope() || scope()->is_module_scope()) ? LET
1544                                                                        : VAR;
1545   VariableProxy* proxy =
1546       factory()->NewVariableProxy(variable_name, NORMAL_VARIABLE);
1547   Declaration* declaration =
1548       factory()->NewFunctionDeclaration(proxy, function, scope(), pos);
1549   Declare(declaration, DeclarationDescriptor::NORMAL, mode, kCreatedInitialized,
1550           CHECK_OK);
1551   if (names) names->Add(variable_name, zone());
1552   // Async functions don't undergo sloppy mode block scoped hoisting, and don't
1553   // allow duplicates in a block. Both are represented by the
1554   // sloppy_block_function_map. Don't add them to the map for async functions.
1555   // Generators are also supposed to be prohibited; currently doing this behind
1556   // a flag and UseCounting violations to assess web compatibility.
1557   if (is_sloppy(language_mode()) && !scope()->is_declaration_scope() &&
1558       !is_async && !(allow_harmony_restrictive_generators() && is_generator)) {
1559     SloppyBlockFunctionStatement* delegate =
1560         factory()->NewSloppyBlockFunctionStatement(scope());
1561     DeclarationScope* target_scope = GetDeclarationScope();
1562     target_scope->DeclareSloppyBlockFunction(variable_name, delegate);
1563     return delegate;
1564   }
1565   return factory()->NewEmptyStatement(kNoSourcePosition);
1566 }
1567 
DeclareClass(const AstRawString * variable_name,Expression * value,ZoneList<const AstRawString * > * names,int class_token_pos,int end_pos,bool * ok)1568 Statement* Parser::DeclareClass(const AstRawString* variable_name,
1569                                 Expression* value,
1570                                 ZoneList<const AstRawString*>* names,
1571                                 int class_token_pos, int end_pos, bool* ok) {
1572   Declaration* decl =
1573       DeclareVariable(variable_name, LET, class_token_pos, CHECK_OK);
1574   decl->proxy()->var()->set_initializer_position(end_pos);
1575   Assignment* assignment = factory()->NewAssignment(Token::INIT, decl->proxy(),
1576                                                     value, class_token_pos);
1577   Statement* assignment_statement =
1578       factory()->NewExpressionStatement(assignment, kNoSourcePosition);
1579   if (names) names->Add(variable_name, zone());
1580   return assignment_statement;
1581 }
1582 
DeclareNative(const AstRawString * name,int pos,bool * ok)1583 Statement* Parser::DeclareNative(const AstRawString* name, int pos, bool* ok) {
1584   // Make sure that the function containing the native declaration
1585   // isn't lazily compiled. The extension structures are only
1586   // accessible while parsing the first time not when reparsing
1587   // because of lazy compilation.
1588   GetClosureScope()->ForceEagerCompilation();
1589 
1590   // TODO(1240846): It's weird that native function declarations are
1591   // introduced dynamically when we meet their declarations, whereas
1592   // other functions are set up when entering the surrounding scope.
1593   Declaration* decl = DeclareVariable(name, VAR, pos, CHECK_OK);
1594   NativeFunctionLiteral* lit =
1595       factory()->NewNativeFunctionLiteral(name, extension_, kNoSourcePosition);
1596   return factory()->NewExpressionStatement(
1597       factory()->NewAssignment(Token::INIT, decl->proxy(), lit,
1598                                kNoSourcePosition),
1599       pos);
1600 }
1601 
DeclareLabel(ZoneList<const AstRawString * > * labels,VariableProxy * var,bool * ok)1602 ZoneList<const AstRawString*>* Parser::DeclareLabel(
1603     ZoneList<const AstRawString*>* labels, VariableProxy* var, bool* ok) {
1604   const AstRawString* label = var->raw_name();
1605   // TODO(1240780): We don't check for redeclaration of labels
1606   // during preparsing since keeping track of the set of active
1607   // labels requires nontrivial changes to the way scopes are
1608   // structured.  However, these are probably changes we want to
1609   // make later anyway so we should go back and fix this then.
1610   if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) {
1611     ReportMessage(MessageTemplate::kLabelRedeclaration, label);
1612     *ok = false;
1613     return nullptr;
1614   }
1615   if (labels == nullptr) {
1616     labels = new (zone()) ZoneList<const AstRawString*>(1, zone());
1617   }
1618   labels->Add(label, zone());
1619   // Remove the "ghost" variable that turned out to be a label
1620   // from the top scope. This way, we don't try to resolve it
1621   // during the scope processing.
1622   scope()->RemoveUnresolved(var);
1623   return labels;
1624 }
1625 
ContainsLabel(ZoneList<const AstRawString * > * labels,const AstRawString * label)1626 bool Parser::ContainsLabel(ZoneList<const AstRawString*>* labels,
1627                            const AstRawString* label) {
1628   DCHECK_NOT_NULL(label);
1629   if (labels != nullptr) {
1630     for (int i = labels->length(); i-- > 0;) {
1631       if (labels->at(i) == label) return true;
1632     }
1633   }
1634   return false;
1635 }
1636 
RewriteReturn(Expression * return_value,int pos)1637 Expression* Parser::RewriteReturn(Expression* return_value, int pos) {
1638   if (IsSubclassConstructor(function_state_->kind())) {
1639     // For subclass constructors we need to return this in case of undefined
1640     // return a Smi (transformed into an exception in the ConstructStub)
1641     // for a non object.
1642     //
1643     //   return expr;
1644     //
1645     // Is rewritten as:
1646     //
1647     //   return (temp = expr) === undefined ? this :
1648     //       %_IsJSReceiver(temp) ? temp : 1;
1649 
1650     // temp = expr
1651     Variable* temp = NewTemporary(ast_value_factory()->empty_string());
1652     Assignment* assign = factory()->NewAssignment(
1653         Token::ASSIGN, factory()->NewVariableProxy(temp), return_value, pos);
1654 
1655     // %_IsJSReceiver(temp)
1656     ZoneList<Expression*>* is_spec_object_args =
1657         new (zone()) ZoneList<Expression*>(1, zone());
1658     is_spec_object_args->Add(factory()->NewVariableProxy(temp), zone());
1659     Expression* is_spec_object_call = factory()->NewCallRuntime(
1660         Runtime::kInlineIsJSReceiver, is_spec_object_args, pos);
1661 
1662     // %_IsJSReceiver(temp) ? temp : 1;
1663     Expression* is_object_conditional = factory()->NewConditional(
1664         is_spec_object_call, factory()->NewVariableProxy(temp),
1665         factory()->NewSmiLiteral(1, pos), pos);
1666 
1667     // temp === undefined
1668     Expression* is_undefined = factory()->NewCompareOperation(
1669         Token::EQ_STRICT, assign,
1670         factory()->NewUndefinedLiteral(kNoSourcePosition), pos);
1671 
1672     // is_undefined ? this : is_object_conditional
1673     return_value = factory()->NewConditional(is_undefined, ThisExpression(pos),
1674                                              is_object_conditional, pos);
1675   }
1676   if (is_generator()) {
1677     return_value = BuildIteratorResult(return_value, true);
1678   } else if (is_async_function()) {
1679     return_value = BuildResolvePromise(return_value, return_value->position());
1680   }
1681   return return_value;
1682 }
1683 
RewriteDoExpression(Block * body,int pos,bool * ok)1684 Expression* Parser::RewriteDoExpression(Block* body, int pos, bool* ok) {
1685   Variable* result = NewTemporary(ast_value_factory()->dot_result_string());
1686   DoExpression* expr = factory()->NewDoExpression(body, result, pos);
1687   if (!Rewriter::Rewrite(this, GetClosureScope(), expr, ast_value_factory())) {
1688     *ok = false;
1689     return nullptr;
1690   }
1691   return expr;
1692 }
1693 
RewriteSwitchStatement(Expression * tag,SwitchStatement * switch_statement,ZoneList<CaseClause * > * cases,Scope * scope)1694 Statement* Parser::RewriteSwitchStatement(Expression* tag,
1695                                           SwitchStatement* switch_statement,
1696                                           ZoneList<CaseClause*>* cases,
1697                                           Scope* scope) {
1698   // In order to get the CaseClauses to execute in their own lexical scope,
1699   // but without requiring downstream code to have special scope handling
1700   // code for switch statements, desugar into blocks as follows:
1701   // {  // To group the statements--harmless to evaluate Expression in scope
1702   //   .tag_variable = Expression;
1703   //   {  // To give CaseClauses a scope
1704   //     switch (.tag_variable) { CaseClause* }
1705   //   }
1706   // }
1707 
1708   Block* switch_block = factory()->NewBlock(NULL, 2, false, kNoSourcePosition);
1709 
1710   Variable* tag_variable =
1711       NewTemporary(ast_value_factory()->dot_switch_tag_string());
1712   Assignment* tag_assign = factory()->NewAssignment(
1713       Token::ASSIGN, factory()->NewVariableProxy(tag_variable), tag,
1714       tag->position());
1715   Statement* tag_statement =
1716       factory()->NewExpressionStatement(tag_assign, kNoSourcePosition);
1717   switch_block->statements()->Add(tag_statement, zone());
1718 
1719   // make statement: undefined;
1720   // This is needed so the tag isn't returned as the value, in case the switch
1721   // statements don't have a value.
1722   switch_block->statements()->Add(
1723       factory()->NewExpressionStatement(
1724           factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition),
1725       zone());
1726 
1727   Expression* tag_read = factory()->NewVariableProxy(tag_variable);
1728   switch_statement->Initialize(tag_read, cases);
1729   Block* cases_block = factory()->NewBlock(NULL, 1, false, kNoSourcePosition);
1730   cases_block->statements()->Add(switch_statement, zone());
1731   cases_block->set_scope(scope);
1732   switch_block->statements()->Add(cases_block, zone());
1733   return switch_block;
1734 }
1735 
RewriteCatchPattern(CatchInfo * catch_info,bool * ok)1736 void Parser::RewriteCatchPattern(CatchInfo* catch_info, bool* ok) {
1737   if (catch_info->name == nullptr) {
1738     DCHECK_NOT_NULL(catch_info->pattern);
1739     catch_info->name = ast_value_factory()->dot_catch_string();
1740   }
1741   catch_info->variable = catch_info->scope->DeclareLocal(
1742       catch_info->name, VAR, kCreatedInitialized, NORMAL_VARIABLE);
1743   if (catch_info->pattern != nullptr) {
1744     DeclarationDescriptor descriptor;
1745     descriptor.declaration_kind = DeclarationDescriptor::NORMAL;
1746     descriptor.scope = scope();
1747     descriptor.hoist_scope = nullptr;
1748     descriptor.mode = LET;
1749     descriptor.declaration_pos = catch_info->pattern->position();
1750     descriptor.initialization_pos = catch_info->pattern->position();
1751 
1752     // Initializer position for variables declared by the pattern.
1753     const int initializer_position = position();
1754 
1755     DeclarationParsingResult::Declaration decl(
1756         catch_info->pattern, initializer_position,
1757         factory()->NewVariableProxy(catch_info->variable));
1758 
1759     catch_info->init_block =
1760         factory()->NewBlock(nullptr, 8, true, kNoSourcePosition);
1761     PatternRewriter::DeclareAndInitializeVariables(
1762         this, catch_info->init_block, &descriptor, &decl,
1763         &catch_info->bound_names, ok);
1764   } else {
1765     catch_info->bound_names.Add(catch_info->name, zone());
1766   }
1767 }
1768 
ValidateCatchBlock(const CatchInfo & catch_info,bool * ok)1769 void Parser::ValidateCatchBlock(const CatchInfo& catch_info, bool* ok) {
1770   // Check for `catch(e) { let e; }` and similar errors.
1771   Scope* inner_block_scope = catch_info.inner_block->scope();
1772   if (inner_block_scope != nullptr) {
1773     Declaration* decl = inner_block_scope->CheckLexDeclarationsConflictingWith(
1774         catch_info.bound_names);
1775     if (decl != nullptr) {
1776       const AstRawString* name = decl->proxy()->raw_name();
1777       int position = decl->proxy()->position();
1778       Scanner::Location location =
1779           position == kNoSourcePosition
1780               ? Scanner::Location::invalid()
1781               : Scanner::Location(position, position + 1);
1782       ReportMessageAt(location, MessageTemplate::kVarRedeclaration, name);
1783       *ok = false;
1784     }
1785   }
1786 }
1787 
RewriteTryStatement(Block * try_block,Block * catch_block,Block * finally_block,const CatchInfo & catch_info,int pos)1788 Statement* Parser::RewriteTryStatement(Block* try_block, Block* catch_block,
1789                                        Block* finally_block,
1790                                        const CatchInfo& catch_info, int pos) {
1791   // Simplify the AST nodes by converting:
1792   //   'try B0 catch B1 finally B2'
1793   // to:
1794   //   'try { try B0 catch B1 } finally B2'
1795 
1796   if (catch_block != nullptr && finally_block != nullptr) {
1797     // If we have both, create an inner try/catch.
1798     DCHECK_NOT_NULL(catch_info.scope);
1799     DCHECK_NOT_NULL(catch_info.variable);
1800     TryCatchStatement* statement;
1801     if (catch_info.for_promise_reject) {
1802       statement = factory()->NewTryCatchStatementForPromiseReject(
1803           try_block, catch_info.scope, catch_info.variable, catch_block,
1804           kNoSourcePosition);
1805     } else {
1806       statement = factory()->NewTryCatchStatement(
1807           try_block, catch_info.scope, catch_info.variable, catch_block,
1808           kNoSourcePosition);
1809     }
1810 
1811     try_block = factory()->NewBlock(nullptr, 1, false, kNoSourcePosition);
1812     try_block->statements()->Add(statement, zone());
1813     catch_block = nullptr;  // Clear to indicate it's been handled.
1814   }
1815 
1816   if (catch_block != nullptr) {
1817     // For a try-catch construct append return expressions from the catch block
1818     // to the list of return expressions.
1819     function_state_->tail_call_expressions().Append(
1820         catch_info.tail_call_expressions);
1821 
1822     DCHECK_NULL(finally_block);
1823     DCHECK_NOT_NULL(catch_info.scope);
1824     DCHECK_NOT_NULL(catch_info.variable);
1825     return factory()->NewTryCatchStatement(
1826         try_block, catch_info.scope, catch_info.variable, catch_block, pos);
1827   } else {
1828     DCHECK_NOT_NULL(finally_block);
1829     return factory()->NewTryFinallyStatement(try_block, finally_block, pos);
1830   }
1831 }
1832 
1833 // !%_IsJSReceiver(result = iterator.next()) &&
1834 //     %ThrowIteratorResultNotAnObject(result)
BuildIteratorNextResult(Expression * iterator,Variable * result,int pos)1835 Expression* Parser::BuildIteratorNextResult(Expression* iterator,
1836                                             Variable* result, int pos) {
1837   Expression* next_literal = factory()->NewStringLiteral(
1838       ast_value_factory()->next_string(), kNoSourcePosition);
1839   Expression* next_property =
1840       factory()->NewProperty(iterator, next_literal, kNoSourcePosition);
1841   ZoneList<Expression*>* next_arguments =
1842       new (zone()) ZoneList<Expression*>(0, zone());
1843   Expression* next_call =
1844       factory()->NewCall(next_property, next_arguments, pos);
1845   Expression* result_proxy = factory()->NewVariableProxy(result);
1846   Expression* left =
1847       factory()->NewAssignment(Token::ASSIGN, result_proxy, next_call, pos);
1848 
1849   // %_IsJSReceiver(...)
1850   ZoneList<Expression*>* is_spec_object_args =
1851       new (zone()) ZoneList<Expression*>(1, zone());
1852   is_spec_object_args->Add(left, zone());
1853   Expression* is_spec_object_call = factory()->NewCallRuntime(
1854       Runtime::kInlineIsJSReceiver, is_spec_object_args, pos);
1855 
1856   // %ThrowIteratorResultNotAnObject(result)
1857   Expression* result_proxy_again = factory()->NewVariableProxy(result);
1858   ZoneList<Expression*>* throw_arguments =
1859       new (zone()) ZoneList<Expression*>(1, zone());
1860   throw_arguments->Add(result_proxy_again, zone());
1861   Expression* throw_call = factory()->NewCallRuntime(
1862       Runtime::kThrowIteratorResultNotAnObject, throw_arguments, pos);
1863 
1864   return factory()->NewBinaryOperation(
1865       Token::AND,
1866       factory()->NewUnaryOperation(Token::NOT, is_spec_object_call, pos),
1867       throw_call, pos);
1868 }
1869 
InitializeForEachStatement(ForEachStatement * stmt,Expression * each,Expression * subject,Statement * body,int each_keyword_pos)1870 Statement* Parser::InitializeForEachStatement(ForEachStatement* stmt,
1871                                               Expression* each,
1872                                               Expression* subject,
1873                                               Statement* body,
1874                                               int each_keyword_pos) {
1875   ForOfStatement* for_of = stmt->AsForOfStatement();
1876   if (for_of != NULL) {
1877     const bool finalize = true;
1878     return InitializeForOfStatement(for_of, each, subject, body, finalize,
1879                                     each_keyword_pos);
1880   } else {
1881     if (each->IsArrayLiteral() || each->IsObjectLiteral()) {
1882       Variable* temp = NewTemporary(ast_value_factory()->empty_string());
1883       VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
1884       Expression* assign_each = PatternRewriter::RewriteDestructuringAssignment(
1885           this, factory()->NewAssignment(Token::ASSIGN, each, temp_proxy,
1886                                          kNoSourcePosition),
1887           scope());
1888       auto block = factory()->NewBlock(nullptr, 2, false, kNoSourcePosition);
1889       block->statements()->Add(
1890           factory()->NewExpressionStatement(assign_each, kNoSourcePosition),
1891           zone());
1892       block->statements()->Add(body, zone());
1893       body = block;
1894       each = factory()->NewVariableProxy(temp);
1895     }
1896     stmt->AsForInStatement()->Initialize(each, subject, body);
1897   }
1898   return stmt;
1899 }
1900 
1901 // Special case for legacy for
1902 //
1903 //    for (var x = initializer in enumerable) body
1904 //
1905 // An initialization block of the form
1906 //
1907 //    {
1908 //      x = initializer;
1909 //    }
1910 //
1911 // is returned in this case.  It has reserved space for two statements,
1912 // so that (later on during parsing), the equivalent of
1913 //
1914 //   for (x in enumerable) body
1915 //
1916 // is added as a second statement to it.
RewriteForVarInLegacy(const ForInfo & for_info)1917 Block* Parser::RewriteForVarInLegacy(const ForInfo& for_info) {
1918   const DeclarationParsingResult::Declaration& decl =
1919       for_info.parsing_result.declarations[0];
1920   if (!IsLexicalVariableMode(for_info.parsing_result.descriptor.mode) &&
1921       decl.pattern->IsVariableProxy() && decl.initializer != nullptr) {
1922     ++use_counts_[v8::Isolate::kForInInitializer];
1923     const AstRawString* name = decl.pattern->AsVariableProxy()->raw_name();
1924     VariableProxy* single_var = NewUnresolved(name);
1925     Block* init_block = factory()->NewBlock(
1926         nullptr, 2, true, for_info.parsing_result.descriptor.declaration_pos);
1927     init_block->statements()->Add(
1928         factory()->NewExpressionStatement(
1929             factory()->NewAssignment(Token::ASSIGN, single_var,
1930                                      decl.initializer, kNoSourcePosition),
1931             kNoSourcePosition),
1932         zone());
1933     return init_block;
1934   }
1935   return nullptr;
1936 }
1937 
1938 // Rewrite a for-in/of statement of the form
1939 //
1940 //   for (let/const/var x in/of e) b
1941 //
1942 // into
1943 //
1944 //   {
1945 //     <let x' be a temporary variable>
1946 //     for (x' in/of e) {
1947 //       let/const/var x;
1948 //       x = x';
1949 //       b;
1950 //     }
1951 //     let x;  // for TDZ
1952 //   }
DesugarBindingInForEachStatement(ForInfo * for_info,Block ** body_block,Expression ** each_variable,bool * ok)1953 void Parser::DesugarBindingInForEachStatement(ForInfo* for_info,
1954                                               Block** body_block,
1955                                               Expression** each_variable,
1956                                               bool* ok) {
1957   DeclarationParsingResult::Declaration& decl =
1958       for_info->parsing_result.declarations[0];
1959   Variable* temp = NewTemporary(ast_value_factory()->dot_for_string());
1960   auto each_initialization_block =
1961       factory()->NewBlock(nullptr, 1, true, kNoSourcePosition);
1962   {
1963     auto descriptor = for_info->parsing_result.descriptor;
1964     descriptor.declaration_pos = kNoSourcePosition;
1965     descriptor.initialization_pos = kNoSourcePosition;
1966     decl.initializer = factory()->NewVariableProxy(temp);
1967 
1968     bool is_for_var_of =
1969         for_info->mode == ForEachStatement::ITERATE &&
1970         for_info->parsing_result.descriptor.mode == VariableMode::VAR;
1971 
1972     PatternRewriter::DeclareAndInitializeVariables(
1973         this, each_initialization_block, &descriptor, &decl,
1974         (IsLexicalVariableMode(for_info->parsing_result.descriptor.mode) ||
1975          is_for_var_of)
1976             ? &for_info->bound_names
1977             : nullptr,
1978         CHECK_OK_VOID);
1979 
1980     // Annex B.3.5 prohibits the form
1981     // `try {} catch(e) { for (var e of {}); }`
1982     // So if we are parsing a statement like `for (var ... of ...)`
1983     // we need to walk up the scope chain and look for catch scopes
1984     // which have a simple binding, then compare their binding against
1985     // all of the names declared in the init of the for-of we're
1986     // parsing.
1987     if (is_for_var_of) {
1988       Scope* catch_scope = scope();
1989       while (catch_scope != nullptr && !catch_scope->is_declaration_scope()) {
1990         if (catch_scope->is_catch_scope()) {
1991           auto name = catch_scope->catch_variable_name();
1992           // If it's a simple binding and the name is declared in the for loop.
1993           if (name != ast_value_factory()->dot_catch_string() &&
1994               for_info->bound_names.Contains(name)) {
1995             ReportMessageAt(for_info->parsing_result.bindings_loc,
1996                             MessageTemplate::kVarRedeclaration, name);
1997             *ok = false;
1998             return;
1999           }
2000         }
2001         catch_scope = catch_scope->outer_scope();
2002       }
2003     }
2004   }
2005 
2006   *body_block = factory()->NewBlock(nullptr, 3, false, kNoSourcePosition);
2007   (*body_block)->statements()->Add(each_initialization_block, zone());
2008   *each_variable = factory()->NewVariableProxy(temp, for_info->position);
2009 }
2010 
2011 // Create a TDZ for any lexically-bound names in for in/of statements.
CreateForEachStatementTDZ(Block * init_block,const ForInfo & for_info,bool * ok)2012 Block* Parser::CreateForEachStatementTDZ(Block* init_block,
2013                                          const ForInfo& for_info, bool* ok) {
2014   if (IsLexicalVariableMode(for_info.parsing_result.descriptor.mode)) {
2015     DCHECK_NULL(init_block);
2016 
2017     init_block = factory()->NewBlock(nullptr, 1, false, kNoSourcePosition);
2018 
2019     for (int i = 0; i < for_info.bound_names.length(); ++i) {
2020       // TODO(adamk): This needs to be some sort of special
2021       // INTERNAL variable that's invisible to the debugger
2022       // but visible to everything else.
2023       Declaration* tdz_decl = DeclareVariable(for_info.bound_names[i], LET,
2024                                               kNoSourcePosition, CHECK_OK);
2025       tdz_decl->proxy()->var()->set_initializer_position(position());
2026     }
2027   }
2028   return init_block;
2029 }
2030 
InitializeForOfStatement(ForOfStatement * for_of,Expression * each,Expression * iterable,Statement * body,bool finalize,int next_result_pos)2031 Statement* Parser::InitializeForOfStatement(ForOfStatement* for_of,
2032                                             Expression* each,
2033                                             Expression* iterable,
2034                                             Statement* body, bool finalize,
2035                                             int next_result_pos) {
2036   // Create the auxiliary expressions needed for iterating over the iterable,
2037   // and initialize the given ForOfStatement with them.
2038   // If finalize is true, also instrument the loop with code that performs the
2039   // proper ES6 iterator finalization.  In that case, the result is not
2040   // immediately a ForOfStatement.
2041 
2042   const int nopos = kNoSourcePosition;
2043   auto avfactory = ast_value_factory();
2044 
2045   Variable* iterator = NewTemporary(ast_value_factory()->dot_iterator_string());
2046   Variable* result = NewTemporary(ast_value_factory()->dot_result_string());
2047   Variable* completion = NewTemporary(avfactory->empty_string());
2048 
2049   // iterator = iterable[Symbol.iterator]()
2050   Expression* assign_iterator;
2051   {
2052     assign_iterator = factory()->NewAssignment(
2053         Token::ASSIGN, factory()->NewVariableProxy(iterator),
2054         GetIterator(iterable, iterable->position()), iterable->position());
2055   }
2056 
2057   // !%_IsJSReceiver(result = iterator.next()) &&
2058   //     %ThrowIteratorResultNotAnObject(result)
2059   Expression* next_result;
2060   {
2061     Expression* iterator_proxy = factory()->NewVariableProxy(iterator);
2062     next_result =
2063         BuildIteratorNextResult(iterator_proxy, result, next_result_pos);
2064   }
2065 
2066   // result.done
2067   Expression* result_done;
2068   {
2069     Expression* done_literal = factory()->NewStringLiteral(
2070         ast_value_factory()->done_string(), kNoSourcePosition);
2071     Expression* result_proxy = factory()->NewVariableProxy(result);
2072     result_done =
2073         factory()->NewProperty(result_proxy, done_literal, kNoSourcePosition);
2074   }
2075 
2076   // result.value
2077   Expression* result_value;
2078   {
2079     Expression* value_literal =
2080         factory()->NewStringLiteral(avfactory->value_string(), nopos);
2081     Expression* result_proxy = factory()->NewVariableProxy(result);
2082     result_value = factory()->NewProperty(result_proxy, value_literal, nopos);
2083   }
2084 
2085   // {{completion = kAbruptCompletion;}}
2086   Statement* set_completion_abrupt;
2087   if (finalize) {
2088     Expression* proxy = factory()->NewVariableProxy(completion);
2089     Expression* assignment = factory()->NewAssignment(
2090         Token::ASSIGN, proxy,
2091         factory()->NewSmiLiteral(Parser::kAbruptCompletion, nopos), nopos);
2092 
2093     Block* block = factory()->NewBlock(nullptr, 1, true, nopos);
2094     block->statements()->Add(
2095         factory()->NewExpressionStatement(assignment, nopos), zone());
2096     set_completion_abrupt = block;
2097   }
2098 
2099   // do { let tmp = #result_value; #set_completion_abrupt; tmp }
2100   // Expression* result_value (gets overwritten)
2101   if (finalize) {
2102     Variable* var_tmp = NewTemporary(avfactory->empty_string());
2103     Expression* tmp = factory()->NewVariableProxy(var_tmp);
2104     Expression* assignment =
2105         factory()->NewAssignment(Token::ASSIGN, tmp, result_value, nopos);
2106 
2107     Block* block = factory()->NewBlock(nullptr, 2, false, nopos);
2108     block->statements()->Add(
2109         factory()->NewExpressionStatement(assignment, nopos), zone());
2110     block->statements()->Add(set_completion_abrupt, zone());
2111 
2112     result_value = factory()->NewDoExpression(block, var_tmp, nopos);
2113   }
2114 
2115   // each = #result_value;
2116   Expression* assign_each;
2117   {
2118     assign_each =
2119         factory()->NewAssignment(Token::ASSIGN, each, result_value, nopos);
2120     if (each->IsArrayLiteral() || each->IsObjectLiteral()) {
2121       assign_each = PatternRewriter::RewriteDestructuringAssignment(
2122           this, assign_each->AsAssignment(), scope());
2123     }
2124   }
2125 
2126   // {{completion = kNormalCompletion;}}
2127   Statement* set_completion_normal;
2128   if (finalize) {
2129     Expression* proxy = factory()->NewVariableProxy(completion);
2130     Expression* assignment = factory()->NewAssignment(
2131         Token::ASSIGN, proxy,
2132         factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos);
2133 
2134     Block* block = factory()->NewBlock(nullptr, 1, true, nopos);
2135     block->statements()->Add(
2136         factory()->NewExpressionStatement(assignment, nopos), zone());
2137     set_completion_normal = block;
2138   }
2139 
2140   // { #loop-body; #set_completion_normal }
2141   // Statement* body (gets overwritten)
2142   if (finalize) {
2143     Block* block = factory()->NewBlock(nullptr, 2, false, nopos);
2144     block->statements()->Add(body, zone());
2145     block->statements()->Add(set_completion_normal, zone());
2146     body = block;
2147   }
2148 
2149   for_of->Initialize(body, iterator, assign_iterator, next_result, result_done,
2150                      assign_each);
2151   return finalize ? FinalizeForOfStatement(for_of, completion, nopos) : for_of;
2152 }
2153 
DesugarLexicalBindingsInForStatement(ForStatement * loop,Statement * init,Expression * cond,Statement * next,Statement * body,Scope * inner_scope,const ForInfo & for_info,bool * ok)2154 Statement* Parser::DesugarLexicalBindingsInForStatement(
2155     ForStatement* loop, Statement* init, Expression* cond, Statement* next,
2156     Statement* body, Scope* inner_scope, const ForInfo& for_info, bool* ok) {
2157   // ES6 13.7.4.8 specifies that on each loop iteration the let variables are
2158   // copied into a new environment.  Moreover, the "next" statement must be
2159   // evaluated not in the environment of the just completed iteration but in
2160   // that of the upcoming one.  We achieve this with the following desugaring.
2161   // Extra care is needed to preserve the completion value of the original loop.
2162   //
2163   // We are given a for statement of the form
2164   //
2165   //  labels: for (let/const x = i; cond; next) body
2166   //
2167   // and rewrite it as follows.  Here we write {{ ... }} for init-blocks, ie.,
2168   // blocks whose ignore_completion_value_ flag is set.
2169   //
2170   //  {
2171   //    let/const x = i;
2172   //    temp_x = x;
2173   //    first = 1;
2174   //    undefined;
2175   //    outer: for (;;) {
2176   //      let/const x = temp_x;
2177   //      {{ if (first == 1) {
2178   //           first = 0;
2179   //         } else {
2180   //           next;
2181   //         }
2182   //         flag = 1;
2183   //         if (!cond) break;
2184   //      }}
2185   //      labels: for (; flag == 1; flag = 0, temp_x = x) {
2186   //        body
2187   //      }
2188   //      {{ if (flag == 1)  // Body used break.
2189   //           break;
2190   //      }}
2191   //    }
2192   //  }
2193 
2194   DCHECK(for_info.bound_names.length() > 0);
2195   ZoneList<Variable*> temps(for_info.bound_names.length(), zone());
2196 
2197   Block* outer_block = factory()->NewBlock(
2198       nullptr, for_info.bound_names.length() + 4, false, kNoSourcePosition);
2199 
2200   // Add statement: let/const x = i.
2201   outer_block->statements()->Add(init, zone());
2202 
2203   const AstRawString* temp_name = ast_value_factory()->dot_for_string();
2204 
2205   // For each lexical variable x:
2206   //   make statement: temp_x = x.
2207   for (int i = 0; i < for_info.bound_names.length(); i++) {
2208     VariableProxy* proxy = NewUnresolved(for_info.bound_names[i]);
2209     Variable* temp = NewTemporary(temp_name);
2210     VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
2211     Assignment* assignment = factory()->NewAssignment(Token::ASSIGN, temp_proxy,
2212                                                       proxy, kNoSourcePosition);
2213     Statement* assignment_statement =
2214         factory()->NewExpressionStatement(assignment, kNoSourcePosition);
2215     outer_block->statements()->Add(assignment_statement, zone());
2216     temps.Add(temp, zone());
2217   }
2218 
2219   Variable* first = NULL;
2220   // Make statement: first = 1.
2221   if (next) {
2222     first = NewTemporary(temp_name);
2223     VariableProxy* first_proxy = factory()->NewVariableProxy(first);
2224     Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
2225     Assignment* assignment = factory()->NewAssignment(
2226         Token::ASSIGN, first_proxy, const1, kNoSourcePosition);
2227     Statement* assignment_statement =
2228         factory()->NewExpressionStatement(assignment, kNoSourcePosition);
2229     outer_block->statements()->Add(assignment_statement, zone());
2230   }
2231 
2232   // make statement: undefined;
2233   outer_block->statements()->Add(
2234       factory()->NewExpressionStatement(
2235           factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition),
2236       zone());
2237 
2238   // Make statement: outer: for (;;)
2239   // Note that we don't actually create the label, or set this loop up as an
2240   // explicit break target, instead handing it directly to those nodes that
2241   // need to know about it. This should be safe because we don't run any code
2242   // in this function that looks up break targets.
2243   ForStatement* outer_loop =
2244       factory()->NewForStatement(NULL, kNoSourcePosition);
2245   outer_block->statements()->Add(outer_loop, zone());
2246   outer_block->set_scope(scope());
2247 
2248   Block* inner_block = factory()->NewBlock(NULL, 3, false, kNoSourcePosition);
2249   {
2250     BlockState block_state(&scope_state_, inner_scope);
2251 
2252     Block* ignore_completion_block = factory()->NewBlock(
2253         nullptr, for_info.bound_names.length() + 3, true, kNoSourcePosition);
2254     ZoneList<Variable*> inner_vars(for_info.bound_names.length(), zone());
2255     // For each let variable x:
2256     //    make statement: let/const x = temp_x.
2257     for (int i = 0; i < for_info.bound_names.length(); i++) {
2258       Declaration* decl = DeclareVariable(
2259           for_info.bound_names[i], for_info.parsing_result.descriptor.mode,
2260           kNoSourcePosition, CHECK_OK);
2261       inner_vars.Add(decl->proxy()->var(), zone());
2262       VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
2263       Assignment* assignment = factory()->NewAssignment(
2264           Token::INIT, decl->proxy(), temp_proxy, kNoSourcePosition);
2265       Statement* assignment_statement =
2266           factory()->NewExpressionStatement(assignment, kNoSourcePosition);
2267       DCHECK(init->position() != kNoSourcePosition);
2268       decl->proxy()->var()->set_initializer_position(init->position());
2269       ignore_completion_block->statements()->Add(assignment_statement, zone());
2270     }
2271 
2272     // Make statement: if (first == 1) { first = 0; } else { next; }
2273     if (next) {
2274       DCHECK(first);
2275       Expression* compare = NULL;
2276       // Make compare expression: first == 1.
2277       {
2278         Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
2279         VariableProxy* first_proxy = factory()->NewVariableProxy(first);
2280         compare = factory()->NewCompareOperation(Token::EQ, first_proxy, const1,
2281                                                  kNoSourcePosition);
2282       }
2283       Statement* clear_first = NULL;
2284       // Make statement: first = 0.
2285       {
2286         VariableProxy* first_proxy = factory()->NewVariableProxy(first);
2287         Expression* const0 = factory()->NewSmiLiteral(0, kNoSourcePosition);
2288         Assignment* assignment = factory()->NewAssignment(
2289             Token::ASSIGN, first_proxy, const0, kNoSourcePosition);
2290         clear_first =
2291             factory()->NewExpressionStatement(assignment, kNoSourcePosition);
2292       }
2293       Statement* clear_first_or_next = factory()->NewIfStatement(
2294           compare, clear_first, next, kNoSourcePosition);
2295       ignore_completion_block->statements()->Add(clear_first_or_next, zone());
2296     }
2297 
2298     Variable* flag = NewTemporary(temp_name);
2299     // Make statement: flag = 1.
2300     {
2301       VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
2302       Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
2303       Assignment* assignment = factory()->NewAssignment(
2304           Token::ASSIGN, flag_proxy, const1, kNoSourcePosition);
2305       Statement* assignment_statement =
2306           factory()->NewExpressionStatement(assignment, kNoSourcePosition);
2307       ignore_completion_block->statements()->Add(assignment_statement, zone());
2308     }
2309 
2310     // Make statement: if (!cond) break.
2311     if (cond) {
2312       Statement* stop =
2313           factory()->NewBreakStatement(outer_loop, kNoSourcePosition);
2314       Statement* noop = factory()->NewEmptyStatement(kNoSourcePosition);
2315       ignore_completion_block->statements()->Add(
2316           factory()->NewIfStatement(cond, noop, stop, cond->position()),
2317           zone());
2318     }
2319 
2320     inner_block->statements()->Add(ignore_completion_block, zone());
2321     // Make cond expression for main loop: flag == 1.
2322     Expression* flag_cond = NULL;
2323     {
2324       Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
2325       VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
2326       flag_cond = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1,
2327                                                  kNoSourcePosition);
2328     }
2329 
2330     // Create chain of expressions "flag = 0, temp_x = x, ..."
2331     Statement* compound_next_statement = NULL;
2332     {
2333       Expression* compound_next = NULL;
2334       // Make expression: flag = 0.
2335       {
2336         VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
2337         Expression* const0 = factory()->NewSmiLiteral(0, kNoSourcePosition);
2338         compound_next = factory()->NewAssignment(Token::ASSIGN, flag_proxy,
2339                                                  const0, kNoSourcePosition);
2340       }
2341 
2342       // Make the comma-separated list of temp_x = x assignments.
2343       int inner_var_proxy_pos = scanner()->location().beg_pos;
2344       for (int i = 0; i < for_info.bound_names.length(); i++) {
2345         VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
2346         VariableProxy* proxy =
2347             factory()->NewVariableProxy(inner_vars.at(i), inner_var_proxy_pos);
2348         Assignment* assignment = factory()->NewAssignment(
2349             Token::ASSIGN, temp_proxy, proxy, kNoSourcePosition);
2350         compound_next = factory()->NewBinaryOperation(
2351             Token::COMMA, compound_next, assignment, kNoSourcePosition);
2352       }
2353 
2354       compound_next_statement =
2355           factory()->NewExpressionStatement(compound_next, kNoSourcePosition);
2356     }
2357 
2358     // Make statement: labels: for (; flag == 1; flag = 0, temp_x = x)
2359     // Note that we re-use the original loop node, which retains its labels
2360     // and ensures that any break or continue statements in body point to
2361     // the right place.
2362     loop->Initialize(NULL, flag_cond, compound_next_statement, body);
2363     inner_block->statements()->Add(loop, zone());
2364 
2365     // Make statement: {{if (flag == 1) break;}}
2366     {
2367       Expression* compare = NULL;
2368       // Make compare expresion: flag == 1.
2369       {
2370         Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
2371         VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
2372         compare = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1,
2373                                                  kNoSourcePosition);
2374       }
2375       Statement* stop =
2376           factory()->NewBreakStatement(outer_loop, kNoSourcePosition);
2377       Statement* empty = factory()->NewEmptyStatement(kNoSourcePosition);
2378       Statement* if_flag_break =
2379           factory()->NewIfStatement(compare, stop, empty, kNoSourcePosition);
2380       Block* ignore_completion_block =
2381           factory()->NewBlock(NULL, 1, true, kNoSourcePosition);
2382       ignore_completion_block->statements()->Add(if_flag_break, zone());
2383       inner_block->statements()->Add(ignore_completion_block, zone());
2384     }
2385 
2386     inner_scope->set_end_position(scanner()->location().end_pos);
2387     inner_block->set_scope(inner_scope);
2388   }
2389 
2390   outer_loop->Initialize(NULL, NULL, NULL, inner_block);
2391   return outer_block;
2392 }
2393 
AddArrowFunctionFormalParameters(ParserFormalParameters * parameters,Expression * expr,int end_pos,bool * ok)2394 void Parser::AddArrowFunctionFormalParameters(
2395     ParserFormalParameters* parameters, Expression* expr, int end_pos,
2396     bool* ok) {
2397   // ArrowFunctionFormals ::
2398   //    Binary(Token::COMMA, NonTailArrowFunctionFormals, Tail)
2399   //    Tail
2400   // NonTailArrowFunctionFormals ::
2401   //    Binary(Token::COMMA, NonTailArrowFunctionFormals, VariableProxy)
2402   //    VariableProxy
2403   // Tail ::
2404   //    VariableProxy
2405   //    Spread(VariableProxy)
2406   //
2407   // As we need to visit the parameters in left-to-right order, we recurse on
2408   // the left-hand side of comma expressions.
2409   //
2410   if (expr->IsBinaryOperation()) {
2411     BinaryOperation* binop = expr->AsBinaryOperation();
2412     // The classifier has already run, so we know that the expression is a valid
2413     // arrow function formals production.
2414     DCHECK_EQ(binop->op(), Token::COMMA);
2415     Expression* left = binop->left();
2416     Expression* right = binop->right();
2417     int comma_pos = binop->position();
2418     AddArrowFunctionFormalParameters(parameters, left, comma_pos,
2419                                      CHECK_OK_VOID);
2420     // LHS of comma expression should be unparenthesized.
2421     expr = right;
2422   }
2423 
2424   // Only the right-most expression may be a rest parameter.
2425   DCHECK(!parameters->has_rest);
2426 
2427   bool is_rest = expr->IsSpread();
2428   if (is_rest) {
2429     expr = expr->AsSpread()->expression();
2430     parameters->has_rest = true;
2431   }
2432   if (parameters->is_simple) {
2433     parameters->is_simple = !is_rest && expr->IsVariableProxy();
2434   }
2435 
2436   Expression* initializer = nullptr;
2437   if (expr->IsAssignment()) {
2438     Assignment* assignment = expr->AsAssignment();
2439     DCHECK(!assignment->is_compound());
2440     initializer = assignment->value();
2441     expr = assignment->target();
2442   }
2443 
2444   AddFormalParameter(parameters, expr, initializer, end_pos, is_rest);
2445 }
2446 
DeclareArrowFunctionFormalParameters(ParserFormalParameters * parameters,Expression * expr,const Scanner::Location & params_loc,Scanner::Location * duplicate_loc,bool * ok)2447 void Parser::DeclareArrowFunctionFormalParameters(
2448     ParserFormalParameters* parameters, Expression* expr,
2449     const Scanner::Location& params_loc, Scanner::Location* duplicate_loc,
2450     bool* ok) {
2451   if (expr->IsEmptyParentheses()) return;
2452 
2453   AddArrowFunctionFormalParameters(parameters, expr, params_loc.end_pos,
2454                                    CHECK_OK_VOID);
2455 
2456   if (parameters->arity > Code::kMaxArguments) {
2457     ReportMessageAt(params_loc, MessageTemplate::kMalformedArrowFunParamList);
2458     *ok = false;
2459     return;
2460   }
2461 
2462   ExpressionClassifier classifier(this);
2463   if (!parameters->is_simple) {
2464     this->classifier()->RecordNonSimpleParameter();
2465   }
2466   for (int i = 0; i < parameters->arity; ++i) {
2467     auto parameter = parameters->at(i);
2468     DeclareFormalParameter(parameters->scope, parameter);
2469     if (!this->classifier()
2470              ->is_valid_formal_parameter_list_without_duplicates() &&
2471         !duplicate_loc->IsValid()) {
2472       *duplicate_loc =
2473           this->classifier()->duplicate_formal_parameter_error().location;
2474     }
2475   }
2476   DCHECK_EQ(parameters->is_simple, parameters->scope->has_simple_parameters());
2477 }
2478 
ReindexLiterals(const ParserFormalParameters & parameters)2479 void Parser::ReindexLiterals(const ParserFormalParameters& parameters) {
2480   if (function_state_->materialized_literal_count() > 0) {
2481     AstLiteralReindexer reindexer;
2482 
2483     for (const auto p : parameters.params) {
2484       if (p.pattern != nullptr) reindexer.Reindex(p.pattern);
2485       if (p.initializer != nullptr) reindexer.Reindex(p.initializer);
2486     }
2487 
2488     DCHECK(reindexer.count() <= function_state_->materialized_literal_count());
2489   }
2490 }
2491 
PrepareGeneratorVariables(FunctionState * function_state)2492 void Parser::PrepareGeneratorVariables(FunctionState* function_state) {
2493   // For generators, allocating variables in contexts is currently a win
2494   // because it minimizes the work needed to suspend and resume an
2495   // activation.  The machine code produced for generators (by full-codegen)
2496   // relies on this forced context allocation, but not in an essential way.
2497   scope()->ForceContextAllocation();
2498 
2499   // Calling a generator returns a generator object.  That object is stored
2500   // in a temporary variable, a definition that is used by "yield"
2501   // expressions.
2502   Variable* temp =
2503       NewTemporary(ast_value_factory()->dot_generator_object_string());
2504   function_state->set_generator_object_variable(temp);
2505 }
2506 
ParseFunctionLiteral(const AstRawString * function_name,Scanner::Location function_name_location,FunctionNameValidity function_name_validity,FunctionKind kind,int function_token_pos,FunctionLiteral::FunctionType function_type,LanguageMode language_mode,bool * ok)2507 FunctionLiteral* Parser::ParseFunctionLiteral(
2508     const AstRawString* function_name, Scanner::Location function_name_location,
2509     FunctionNameValidity function_name_validity, FunctionKind kind,
2510     int function_token_pos, FunctionLiteral::FunctionType function_type,
2511     LanguageMode language_mode, bool* ok) {
2512   // Function ::
2513   //   '(' FormalParameterList? ')' '{' FunctionBody '}'
2514   //
2515   // Getter ::
2516   //   '(' ')' '{' FunctionBody '}'
2517   //
2518   // Setter ::
2519   //   '(' PropertySetParameterList ')' '{' FunctionBody '}'
2520 
2521   int pos = function_token_pos == kNoSourcePosition ? peek_position()
2522                                                     : function_token_pos;
2523 
2524   // Anonymous functions were passed either the empty symbol or a null
2525   // handle as the function name.  Remember if we were passed a non-empty
2526   // handle to decide whether to invoke function name inference.
2527   bool should_infer_name = function_name == NULL;
2528 
2529   // We want a non-null handle as the function name.
2530   if (should_infer_name) {
2531     function_name = ast_value_factory()->empty_string();
2532   }
2533 
2534   FunctionLiteral::EagerCompileHint eager_compile_hint =
2535       function_state_->next_function_is_parenthesized()
2536           ? FunctionLiteral::kShouldEagerCompile
2537           : default_eager_compile_hint();
2538 
2539   // Determine if the function can be parsed lazily. Lazy parsing is
2540   // different from lazy compilation; we need to parse more eagerly than we
2541   // compile.
2542 
2543   // We can only parse lazily if we also compile lazily. The heuristics for lazy
2544   // compilation are:
2545   // - It must not have been prohibited by the caller to Parse (some callers
2546   //   need a full AST).
2547   // - The outer scope must allow lazy compilation of inner functions.
2548   // - The function mustn't be a function expression with an open parenthesis
2549   //   before; we consider that a hint that the function will be called
2550   //   immediately, and it would be a waste of time to make it lazily
2551   //   compiled.
2552   // These are all things we can know at this point, without looking at the
2553   // function itself.
2554 
2555   // We separate between lazy parsing top level functions and lazy parsing inner
2556   // functions, because the latter needs to do more work. In particular, we need
2557   // to track unresolved variables to distinguish between these cases:
2558   // (function foo() {
2559   //   bar = function() { return 1; }
2560   //  })();
2561   // and
2562   // (function foo() {
2563   //   var a = 1;
2564   //   bar = function() { return a; }
2565   //  })();
2566 
2567   // Now foo will be parsed eagerly and compiled eagerly (optimization: assume
2568   // parenthesis before the function means that it will be called
2569   // immediately). bar can be parsed lazily, but we need to parse it in a mode
2570   // that tracks unresolved variables.
2571   DCHECK_IMPLIES(parse_lazily(), FLAG_lazy);
2572   DCHECK_IMPLIES(parse_lazily(), allow_lazy());
2573   DCHECK_IMPLIES(parse_lazily(), extension_ == nullptr);
2574 
2575   bool can_preparse = parse_lazily() &&
2576                       eager_compile_hint == FunctionLiteral::kShouldLazyCompile;
2577 
2578   bool is_lazy_top_level_function =
2579       can_preparse && impl()->AllowsLazyParsingWithoutUnresolvedVariables();
2580 
2581   RuntimeCallTimerScope runtime_timer(runtime_call_stats_,
2582                                       &RuntimeCallStats::ParseFunctionLiteral);
2583 
2584   // Determine whether we can still lazy parse the inner function.
2585   // The preconditions are:
2586   // - Lazy compilation has to be enabled.
2587   // - Neither V8 natives nor native function declarations can be allowed,
2588   //   since parsing one would retroactively force the function to be
2589   //   eagerly compiled.
2590   // - The invoker of this parser can't depend on the AST being eagerly
2591   //   built (either because the function is about to be compiled, or
2592   //   because the AST is going to be inspected for some reason).
2593   // - Because of the above, we can't be attempting to parse a
2594   //   FunctionExpression; even without enclosing parentheses it might be
2595   //   immediately invoked.
2596   // - The function literal shouldn't be hinted to eagerly compile.
2597   // - For asm.js functions the body needs to be available when module
2598   //   validation is active, because we examine the entire module at once.
2599 
2600   // Inner functions will be parsed using a temporary Zone. After parsing, we
2601   // will migrate unresolved variable into a Scope in the main Zone.
2602   // TODO(marja): Refactor parsing modes: simplify this.
2603   bool use_temp_zone =
2604       (FLAG_lazy_inner_functions
2605            ? can_preparse
2606            : (is_lazy_top_level_function ||
2607               (allow_lazy() && function_type == FunctionLiteral::kDeclaration &&
2608                eager_compile_hint == FunctionLiteral::kShouldLazyCompile))) &&
2609       !(FLAG_validate_asm && scope()->IsAsmModule());
2610   bool is_lazy_inner_function =
2611       use_temp_zone && FLAG_lazy_inner_functions && !is_lazy_top_level_function;
2612 
2613   // This Scope lives in the main zone. We'll migrate data into that zone later.
2614   DeclarationScope* scope = NewFunctionScope(kind);
2615   SetLanguageMode(scope, language_mode);
2616 #ifdef DEBUG
2617   scope->SetScopeName(function_name);
2618 #endif
2619 
2620   ZoneList<Statement*>* body = nullptr;
2621   int materialized_literal_count = -1;
2622   int expected_property_count = -1;
2623   bool should_be_used_once_hint = false;
2624   int num_parameters = -1;
2625   int function_length = -1;
2626   bool has_duplicate_parameters = false;
2627 
2628   Expect(Token::LPAREN, CHECK_OK);
2629   scope->set_start_position(scanner()->location().beg_pos);
2630 
2631   {
2632     // Temporary zones can nest. When we migrate free variables (see below), we
2633     // need to recreate them in the previous Zone.
2634     AstNodeFactory previous_zone_ast_node_factory(ast_value_factory());
2635     previous_zone_ast_node_factory.set_zone(zone());
2636 
2637     // Open a new zone scope, which sets our AstNodeFactory to allocate in the
2638     // new temporary zone if the preconditions are satisfied, and ensures that
2639     // the previous zone is always restored after parsing the body. To be able
2640     // to do scope analysis correctly after full parsing, we migrate needed
2641     // information when the function is parsed.
2642     Zone temp_zone(zone()->allocator(), ZONE_NAME);
2643     DiscardableZoneScope zone_scope(this, &temp_zone, use_temp_zone);
2644 #ifdef DEBUG
2645     if (use_temp_zone) scope->set_needs_migration();
2646 #endif
2647 
2648     // Eager or lazy parse? If is_lazy_top_level_function, we'll parse
2649     // lazily. We'll call SkipFunction, which may decide to
2650     // abort lazy parsing if it suspects that wasn't a good idea. If so (in
2651     // which case the parser is expected to have backtracked), or if we didn't
2652     // try to lazy parse in the first place, we'll have to parse eagerly.
2653     if (is_lazy_top_level_function || is_lazy_inner_function) {
2654       Scanner::BookmarkScope bookmark(scanner());
2655       bookmark.Set();
2656       LazyParsingResult result =
2657           SkipFunction(kind, scope, &num_parameters, &function_length,
2658                        &has_duplicate_parameters, &materialized_literal_count,
2659                        &expected_property_count, is_lazy_inner_function,
2660                        is_lazy_top_level_function, CHECK_OK);
2661 
2662       if (result == kLazyParsingAborted) {
2663         DCHECK(is_lazy_top_level_function);
2664         bookmark.Apply();
2665         // Trigger eager (re-)parsing, just below this block.
2666         is_lazy_top_level_function = false;
2667 
2668         // This is probably an initialization function. Inform the compiler it
2669         // should also eager-compile this function, and that we expect it to be
2670         // used once.
2671         eager_compile_hint = FunctionLiteral::kShouldEagerCompile;
2672         should_be_used_once_hint = true;
2673         scope->ResetAfterPreparsing(ast_value_factory(), true);
2674         zone_scope.Reset();
2675         use_temp_zone = false;
2676       }
2677     }
2678 
2679     if (!is_lazy_top_level_function && !is_lazy_inner_function) {
2680       body = ParseFunction(
2681           function_name, pos, kind, function_type, scope, &num_parameters,
2682           &function_length, &has_duplicate_parameters,
2683           &materialized_literal_count, &expected_property_count, CHECK_OK);
2684     }
2685 
2686     DCHECK(use_temp_zone || !is_lazy_top_level_function);
2687     if (use_temp_zone) {
2688       // If the preconditions are correct the function body should never be
2689       // accessed, but do this anyway for better behaviour if they're wrong.
2690       body = nullptr;
2691       scope->AnalyzePartially(&previous_zone_ast_node_factory);
2692     }
2693 
2694     if (FLAG_trace_preparse) {
2695       PrintF("  [%s]: %i-%i %.*s\n",
2696              is_lazy_top_level_function
2697                  ? "Preparse no-resolution"
2698                  : (use_temp_zone ? "Preparse resolution" : "Full parse"),
2699              scope->start_position(), scope->end_position(),
2700              function_name->byte_length(), function_name->raw_data());
2701       if (is_lazy_top_level_function) {
2702         CHANGE_CURRENT_RUNTIME_COUNTER(runtime_call_stats_,
2703                                        PreParseNoVariableResolution);
2704       } else if (use_temp_zone) {
2705         CHANGE_CURRENT_RUNTIME_COUNTER(runtime_call_stats_,
2706                                        PreParseWithVariableResolution);
2707       }
2708     }
2709 
2710     // Validate function name. We can do this only after parsing the function,
2711     // since the function can declare itself strict.
2712     language_mode = scope->language_mode();
2713     CheckFunctionName(language_mode, function_name, function_name_validity,
2714                       function_name_location, CHECK_OK);
2715 
2716     if (is_strict(language_mode)) {
2717       CheckStrictOctalLiteral(scope->start_position(), scope->end_position(),
2718                               CHECK_OK);
2719       CheckDecimalLiteralWithLeadingZero(scope->start_position(),
2720                                          scope->end_position());
2721     }
2722     CheckConflictingVarDeclarations(scope, CHECK_OK);
2723   }  // DiscardableZoneScope goes out of scope.
2724 
2725   FunctionLiteral::ParameterFlag duplicate_parameters =
2726       has_duplicate_parameters ? FunctionLiteral::kHasDuplicateParameters
2727                                : FunctionLiteral::kNoDuplicateParameters;
2728 
2729   // Note that the FunctionLiteral needs to be created in the main Zone again.
2730   FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
2731       function_name, scope, body, materialized_literal_count,
2732       expected_property_count, num_parameters, function_length,
2733       duplicate_parameters, function_type, eager_compile_hint, pos, true);
2734   function_literal->set_function_token_position(function_token_pos);
2735   if (should_be_used_once_hint)
2736     function_literal->set_should_be_used_once_hint();
2737 
2738   if (should_infer_name) {
2739     DCHECK_NOT_NULL(fni_);
2740     fni_->AddFunction(function_literal);
2741   }
2742   return function_literal;
2743 }
2744 
SkipFunction(FunctionKind kind,DeclarationScope * function_scope,int * num_parameters,int * function_length,bool * has_duplicate_parameters,int * materialized_literal_count,int * expected_property_count,bool is_inner_function,bool may_abort,bool * ok)2745 Parser::LazyParsingResult Parser::SkipFunction(
2746     FunctionKind kind, DeclarationScope* function_scope, int* num_parameters,
2747     int* function_length, bool* has_duplicate_parameters,
2748     int* materialized_literal_count, int* expected_property_count,
2749     bool is_inner_function, bool may_abort, bool* ok) {
2750   DCHECK_NE(kNoSourcePosition, function_scope->start_position());
2751   if (produce_cached_parse_data()) CHECK(log_);
2752 
2753   DCHECK_IMPLIES(IsArrowFunction(kind),
2754                  scanner()->current_token() == Token::ARROW);
2755 
2756   // Inner functions are not part of the cached data.
2757   if (!is_inner_function && consume_cached_parse_data() &&
2758       !cached_parse_data_->rejected()) {
2759     // If we have cached data, we use it to skip parsing the function. The data
2760     // contains the information we need to construct the lazy function.
2761     FunctionEntry entry =
2762         cached_parse_data_->GetFunctionEntry(function_scope->start_position());
2763     // Check that cached data is valid. If not, mark it as invalid (the embedder
2764     // handles it). Note that end position greater than end of stream is safe,
2765     // and hard to check.
2766     if (entry.is_valid() &&
2767         entry.end_pos() > function_scope->start_position()) {
2768       total_preparse_skipped_ += entry.end_pos() - position();
2769       function_scope->set_end_position(entry.end_pos());
2770       scanner()->SeekForward(entry.end_pos() - 1);
2771       Expect(Token::RBRACE, CHECK_OK_VALUE(kLazyParsingComplete));
2772       *num_parameters = entry.num_parameters();
2773       *function_length = entry.function_length();
2774       *has_duplicate_parameters = entry.has_duplicate_parameters();
2775       *materialized_literal_count = entry.literal_count();
2776       *expected_property_count = entry.property_count();
2777       SetLanguageMode(function_scope, entry.language_mode());
2778       if (entry.uses_super_property())
2779         function_scope->RecordSuperPropertyUsage();
2780       if (entry.calls_eval()) function_scope->RecordEvalCall();
2781       return kLazyParsingComplete;
2782     }
2783     cached_parse_data_->Reject();
2784   }
2785 
2786   // With no cached data, we partially parse the function, without building an
2787   // AST. This gathers the data needed to build a lazy function.
2788   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.PreParse");
2789 
2790   if (reusable_preparser_ == NULL) {
2791     reusable_preparser_ = new PreParser(zone(), &scanner_, ast_value_factory(),
2792                                         &pending_error_handler_,
2793                                         runtime_call_stats_, stack_limit_);
2794     reusable_preparser_->set_allow_lazy(true);
2795 #define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name());
2796     SET_ALLOW(natives);
2797     SET_ALLOW(harmony_do_expressions);
2798     SET_ALLOW(harmony_function_sent);
2799     SET_ALLOW(harmony_async_await);
2800     SET_ALLOW(harmony_trailing_commas);
2801     SET_ALLOW(harmony_class_fields);
2802 #undef SET_ALLOW
2803   }
2804   // Aborting inner function preparsing would leave scopes in an inconsistent
2805   // state; we don't parse inner functions in the abortable mode anyway.
2806   DCHECK(!is_inner_function || !may_abort);
2807 
2808   PreParser::PreParseResult result = reusable_preparser_->PreParseFunction(
2809       kind, function_scope, parsing_module_, is_inner_function, may_abort,
2810       use_counts_);
2811 
2812   // Return immediately if pre-parser decided to abort parsing.
2813   if (result == PreParser::kPreParseAbort) return kLazyParsingAborted;
2814   if (result == PreParser::kPreParseStackOverflow) {
2815     // Propagate stack overflow.
2816     set_stack_overflow();
2817     *ok = false;
2818     return kLazyParsingComplete;
2819   }
2820   if (pending_error_handler_.has_pending_error()) {
2821     *ok = false;
2822     return kLazyParsingComplete;
2823   }
2824   PreParserLogger* logger = reusable_preparser_->logger();
2825   function_scope->set_end_position(logger->end());
2826   Expect(Token::RBRACE, CHECK_OK_VALUE(kLazyParsingComplete));
2827   total_preparse_skipped_ +=
2828       function_scope->end_position() - function_scope->start_position();
2829   *num_parameters = logger->num_parameters();
2830   *function_length = logger->function_length();
2831   *has_duplicate_parameters = logger->has_duplicate_parameters();
2832   *materialized_literal_count = logger->literals();
2833   *expected_property_count = logger->properties();
2834   if (!is_inner_function && produce_cached_parse_data()) {
2835     DCHECK(log_);
2836     log_->LogFunction(
2837         function_scope->start_position(), function_scope->end_position(),
2838         *num_parameters, *function_length, *has_duplicate_parameters,
2839         *materialized_literal_count, *expected_property_count, language_mode(),
2840         function_scope->uses_super_property(), function_scope->calls_eval());
2841   }
2842   return kLazyParsingComplete;
2843 }
2844 
2845 
BuildAssertIsCoercible(Variable * var)2846 Statement* Parser::BuildAssertIsCoercible(Variable* var) {
2847   // if (var === null || var === undefined)
2848   //     throw /* type error kNonCoercible) */;
2849 
2850   Expression* condition = factory()->NewBinaryOperation(
2851       Token::OR,
2852       factory()->NewCompareOperation(
2853           Token::EQ_STRICT, factory()->NewVariableProxy(var),
2854           factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition),
2855       factory()->NewCompareOperation(
2856           Token::EQ_STRICT, factory()->NewVariableProxy(var),
2857           factory()->NewNullLiteral(kNoSourcePosition), kNoSourcePosition),
2858       kNoSourcePosition);
2859   Expression* throw_type_error =
2860       NewThrowTypeError(MessageTemplate::kNonCoercible,
2861                         ast_value_factory()->empty_string(), kNoSourcePosition);
2862   IfStatement* if_statement = factory()->NewIfStatement(
2863       condition,
2864       factory()->NewExpressionStatement(throw_type_error, kNoSourcePosition),
2865       factory()->NewEmptyStatement(kNoSourcePosition), kNoSourcePosition);
2866   return if_statement;
2867 }
2868 
2869 
2870 class InitializerRewriter final
2871     : public AstTraversalVisitor<InitializerRewriter> {
2872  public:
InitializerRewriter(uintptr_t stack_limit,Expression * root,Parser * parser,Scope * scope)2873   InitializerRewriter(uintptr_t stack_limit, Expression* root, Parser* parser,
2874                       Scope* scope)
2875       : AstTraversalVisitor(stack_limit, root),
2876         parser_(parser),
2877         scope_(scope) {}
2878 
2879  private:
2880   // This is required so that the overriden Visit* methods can be
2881   // called by the base class (template).
2882   friend class AstTraversalVisitor<InitializerRewriter>;
2883 
2884   // Just rewrite destructuring assignments wrapped in RewritableExpressions.
VisitRewritableExpression(RewritableExpression * to_rewrite)2885   void VisitRewritableExpression(RewritableExpression* to_rewrite) {
2886     if (to_rewrite->is_rewritten()) return;
2887     Parser::PatternRewriter::RewriteDestructuringAssignment(parser_, to_rewrite,
2888                                                             scope_);
2889   }
2890 
2891   // Code in function literals does not need to be eagerly rewritten, it will be
2892   // rewritten when scheduled.
VisitFunctionLiteral(FunctionLiteral * expr)2893   void VisitFunctionLiteral(FunctionLiteral* expr) {}
2894 
2895   Parser* parser_;
2896   Scope* scope_;
2897 };
2898 
2899 
RewriteParameterInitializer(Expression * expr,Scope * scope)2900 void Parser::RewriteParameterInitializer(Expression* expr, Scope* scope) {
2901   InitializerRewriter rewriter(stack_limit_, expr, this, scope);
2902   rewriter.Run();
2903 }
2904 
2905 
BuildParameterInitializationBlock(const ParserFormalParameters & parameters,bool * ok)2906 Block* Parser::BuildParameterInitializationBlock(
2907     const ParserFormalParameters& parameters, bool* ok) {
2908   DCHECK(!parameters.is_simple);
2909   DCHECK(scope()->is_function_scope());
2910   Block* init_block = factory()->NewBlock(NULL, 1, true, kNoSourcePosition);
2911   for (int i = 0; i < parameters.params.length(); ++i) {
2912     auto parameter = parameters.params[i];
2913     if (parameter.is_rest && parameter.pattern->IsVariableProxy()) break;
2914     DeclarationDescriptor descriptor;
2915     descriptor.declaration_kind = DeclarationDescriptor::PARAMETER;
2916     descriptor.scope = scope();
2917     descriptor.hoist_scope = nullptr;
2918     descriptor.mode = LET;
2919     descriptor.declaration_pos = parameter.pattern->position();
2920     // The position that will be used by the AssignmentExpression
2921     // which copies from the temp parameter to the pattern.
2922     //
2923     // TODO(adamk): Should this be kNoSourcePosition, since
2924     // it's just copying from a temp var to the real param var?
2925     descriptor.initialization_pos = parameter.pattern->position();
2926     Expression* initial_value =
2927         factory()->NewVariableProxy(parameters.scope->parameter(i));
2928     if (parameter.initializer != nullptr) {
2929       // IS_UNDEFINED($param) ? initializer : $param
2930 
2931       // Ensure initializer is rewritten
2932       RewriteParameterInitializer(parameter.initializer, scope());
2933 
2934       auto condition = factory()->NewCompareOperation(
2935           Token::EQ_STRICT,
2936           factory()->NewVariableProxy(parameters.scope->parameter(i)),
2937           factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition);
2938       initial_value = factory()->NewConditional(
2939           condition, parameter.initializer, initial_value, kNoSourcePosition);
2940       descriptor.initialization_pos = parameter.initializer->position();
2941     }
2942 
2943     Scope* param_scope = scope();
2944     Block* param_block = init_block;
2945     if (!parameter.is_simple() && scope()->calls_sloppy_eval()) {
2946       param_scope = NewVarblockScope();
2947       param_scope->set_start_position(descriptor.initialization_pos);
2948       param_scope->set_end_position(parameter.initializer_end_position);
2949       param_scope->RecordEvalCall();
2950       param_block = factory()->NewBlock(NULL, 8, true, kNoSourcePosition);
2951       param_block->set_scope(param_scope);
2952       descriptor.hoist_scope = scope();
2953       // Pass the appropriate scope in so that PatternRewriter can appropriately
2954       // rewrite inner initializers of the pattern to param_scope
2955       descriptor.scope = param_scope;
2956       // Rewrite the outer initializer to point to param_scope
2957       ReparentParameterExpressionScope(stack_limit(), initial_value,
2958                                        param_scope);
2959     }
2960 
2961     BlockState block_state(&scope_state_, param_scope);
2962     DeclarationParsingResult::Declaration decl(
2963         parameter.pattern, parameter.initializer_end_position, initial_value);
2964     PatternRewriter::DeclareAndInitializeVariables(
2965         this, param_block, &descriptor, &decl, nullptr, CHECK_OK);
2966 
2967     if (param_block != init_block) {
2968       param_scope = block_state.FinalizedBlockScope();
2969       if (param_scope != nullptr) {
2970         CheckConflictingVarDeclarations(param_scope, CHECK_OK);
2971       }
2972       init_block->statements()->Add(param_block, zone());
2973     }
2974   }
2975   return init_block;
2976 }
2977 
BuildRejectPromiseOnException(Block * inner_block,bool * ok)2978 Block* Parser::BuildRejectPromiseOnException(Block* inner_block, bool* ok) {
2979   // .promise = %AsyncFunctionPromiseCreate();
2980   // try {
2981   //   <inner_block>
2982   // } catch (.catch) {
2983   //   %RejectPromise(.promise, .catch);
2984   //   return .promise;
2985   // } finally {
2986   //   %AsyncFunctionPromiseRelease(.promise);
2987   // }
2988   Block* result = factory()->NewBlock(nullptr, 2, true, kNoSourcePosition);
2989 
2990   // .promise = %AsyncFunctionPromiseCreate();
2991   Statement* set_promise;
2992   {
2993     Expression* create_promise = factory()->NewCallRuntime(
2994         Context::ASYNC_FUNCTION_PROMISE_CREATE_INDEX,
2995         new (zone()) ZoneList<Expression*>(0, zone()), kNoSourcePosition);
2996     Assignment* assign_promise = factory()->NewAssignment(
2997         Token::INIT, factory()->NewVariableProxy(PromiseVariable()),
2998         create_promise, kNoSourcePosition);
2999     set_promise =
3000         factory()->NewExpressionStatement(assign_promise, kNoSourcePosition);
3001   }
3002   result->statements()->Add(set_promise, zone());
3003 
3004   // catch (.catch) { return %RejectPromise(.promise, .catch), .promise }
3005   Scope* catch_scope = NewScope(CATCH_SCOPE);
3006   catch_scope->set_is_hidden();
3007   Variable* catch_variable =
3008       catch_scope->DeclareLocal(ast_value_factory()->dot_catch_string(), VAR,
3009                                 kCreatedInitialized, NORMAL_VARIABLE);
3010   Block* catch_block = factory()->NewBlock(nullptr, 1, true, kNoSourcePosition);
3011 
3012   Expression* promise_reject = BuildRejectPromise(
3013       factory()->NewVariableProxy(catch_variable), kNoSourcePosition);
3014   ReturnStatement* return_promise_reject =
3015       factory()->NewReturnStatement(promise_reject, kNoSourcePosition);
3016   catch_block->statements()->Add(return_promise_reject, zone());
3017 
3018   TryStatement* try_catch_statement =
3019       factory()->NewTryCatchStatementForAsyncAwait(inner_block, catch_scope,
3020                                                    catch_variable, catch_block,
3021                                                    kNoSourcePosition);
3022 
3023   // There is no TryCatchFinally node, so wrap it in an outer try/finally
3024   Block* outer_try_block =
3025       factory()->NewBlock(nullptr, 1, true, kNoSourcePosition);
3026   outer_try_block->statements()->Add(try_catch_statement, zone());
3027 
3028   // finally { %AsyncFunctionPromiseRelease(.promise) }
3029   Block* finally_block =
3030       factory()->NewBlock(nullptr, 1, true, kNoSourcePosition);
3031   {
3032     ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(1, zone());
3033     args->Add(factory()->NewVariableProxy(PromiseVariable()), zone());
3034     Expression* call_promise_release = factory()->NewCallRuntime(
3035         Context::ASYNC_FUNCTION_PROMISE_RELEASE_INDEX, args, kNoSourcePosition);
3036     Statement* promise_release = factory()->NewExpressionStatement(
3037         call_promise_release, kNoSourcePosition);
3038     finally_block->statements()->Add(promise_release, zone());
3039   }
3040 
3041   Statement* try_finally_statement = factory()->NewTryFinallyStatement(
3042       outer_try_block, finally_block, kNoSourcePosition);
3043 
3044   result->statements()->Add(try_finally_statement, zone());
3045   return result;
3046 }
3047 
BuildCreateJSGeneratorObject(int pos,FunctionKind kind)3048 Expression* Parser::BuildCreateJSGeneratorObject(int pos, FunctionKind kind) {
3049   DCHECK_NOT_NULL(function_state_->generator_object_variable());
3050   ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
3051   args->Add(factory()->NewThisFunction(pos), zone());
3052   args->Add(IsArrowFunction(kind) ? GetLiteralUndefined(pos)
3053                                   : ThisExpression(kNoSourcePosition),
3054             zone());
3055   return factory()->NewCallRuntime(Runtime::kCreateJSGeneratorObject, args,
3056                                    pos);
3057 }
3058 
BuildResolvePromise(Expression * value,int pos)3059 Expression* Parser::BuildResolvePromise(Expression* value, int pos) {
3060   // %ResolvePromise(.promise, value), .promise
3061   ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
3062   args->Add(factory()->NewVariableProxy(PromiseVariable()), zone());
3063   args->Add(value, zone());
3064   Expression* call_runtime =
3065       factory()->NewCallRuntime(Context::PROMISE_RESOLVE_INDEX, args, pos);
3066   return factory()->NewBinaryOperation(
3067       Token::COMMA, call_runtime,
3068       factory()->NewVariableProxy(PromiseVariable()), pos);
3069 }
3070 
BuildRejectPromise(Expression * value,int pos)3071 Expression* Parser::BuildRejectPromise(Expression* value, int pos) {
3072   // %RejectPromiseNoDebugEvent(.promise, value, true), .promise
3073   // The NoDebugEvent variant disables the additional debug event for the
3074   // rejection since a debug event already happened for the exception that got
3075   // us here.
3076   ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
3077   args->Add(factory()->NewVariableProxy(PromiseVariable()), zone());
3078   args->Add(value, zone());
3079   Expression* call_runtime = factory()->NewCallRuntime(
3080       Context::REJECT_PROMISE_NO_DEBUG_EVENT_INDEX, args, pos);
3081   return factory()->NewBinaryOperation(
3082       Token::COMMA, call_runtime,
3083       factory()->NewVariableProxy(PromiseVariable()), pos);
3084 }
3085 
PromiseVariable()3086 Variable* Parser::PromiseVariable() {
3087   // Based on the various compilation paths, there are many different code
3088   // paths which may be the first to access the Promise temporary. Whichever
3089   // comes first should create it and stash it in the FunctionState.
3090   Variable* promise = function_state_->promise_variable();
3091   if (function_state_->promise_variable() == nullptr) {
3092     promise = scope()->NewTemporary(ast_value_factory()->empty_string());
3093     function_state_->set_promise_variable(promise);
3094   }
3095   return promise;
3096 }
3097 
BuildInitialYield(int pos,FunctionKind kind)3098 Expression* Parser::BuildInitialYield(int pos, FunctionKind kind) {
3099   Expression* allocation = BuildCreateJSGeneratorObject(pos, kind);
3100   VariableProxy* init_proxy =
3101       factory()->NewVariableProxy(function_state_->generator_object_variable());
3102   Assignment* assignment = factory()->NewAssignment(
3103       Token::INIT, init_proxy, allocation, kNoSourcePosition);
3104   VariableProxy* get_proxy =
3105       factory()->NewVariableProxy(function_state_->generator_object_variable());
3106   // The position of the yield is important for reporting the exception
3107   // caused by calling the .throw method on a generator suspended at the
3108   // initial yield (i.e. right after generator instantiation).
3109   return factory()->NewYield(get_proxy, assignment, scope()->start_position(),
3110                              Yield::kOnExceptionThrow);
3111 }
3112 
ParseFunction(const AstRawString * function_name,int pos,FunctionKind kind,FunctionLiteral::FunctionType function_type,DeclarationScope * function_scope,int * num_parameters,int * function_length,bool * has_duplicate_parameters,int * materialized_literal_count,int * expected_property_count,bool * ok)3113 ZoneList<Statement*>* Parser::ParseFunction(
3114     const AstRawString* function_name, int pos, FunctionKind kind,
3115     FunctionLiteral::FunctionType function_type,
3116     DeclarationScope* function_scope, int* num_parameters, int* function_length,
3117     bool* has_duplicate_parameters, int* materialized_literal_count,
3118     int* expected_property_count, bool* ok) {
3119   FunctionState function_state(&function_state_, &scope_state_, function_scope);
3120 
3121   DuplicateFinder duplicate_finder(scanner()->unicode_cache());
3122   ExpressionClassifier formals_classifier(this, &duplicate_finder);
3123 
3124   if (IsGeneratorFunction(kind)) PrepareGeneratorVariables(&function_state);
3125 
3126   ParserFormalParameters formals(function_scope);
3127   ParseFormalParameterList(&formals, CHECK_OK);
3128   Expect(Token::RPAREN, CHECK_OK);
3129   int formals_end_position = scanner()->location().end_pos;
3130   *num_parameters = formals.num_parameters();
3131   *function_length = formals.function_length;
3132 
3133   CheckArityRestrictions(formals.arity, kind, formals.has_rest,
3134                          function_scope->start_position(), formals_end_position,
3135                          CHECK_OK);
3136   Expect(Token::LBRACE, CHECK_OK);
3137 
3138   ZoneList<Statement*>* body = ParseEagerFunctionBody(
3139       function_name, pos, formals, kind, function_type, ok);
3140 
3141   // Validate parameter names. We can do this only after parsing the function,
3142   // since the function can declare itself strict.
3143   const bool allow_duplicate_parameters =
3144       is_sloppy(function_scope->language_mode()) && formals.is_simple &&
3145       !IsConciseMethod(kind);
3146   ValidateFormalParameters(function_scope->language_mode(),
3147                            allow_duplicate_parameters, CHECK_OK);
3148 
3149   RewriteDestructuringAssignments();
3150 
3151   *has_duplicate_parameters =
3152       !classifier()->is_valid_formal_parameter_list_without_duplicates();
3153 
3154   *materialized_literal_count = function_state.materialized_literal_count();
3155   *expected_property_count = function_state.expected_property_count();
3156   return body;
3157 }
3158 
ParseEagerFunctionBody(const AstRawString * function_name,int pos,const ParserFormalParameters & parameters,FunctionKind kind,FunctionLiteral::FunctionType function_type,bool * ok)3159 ZoneList<Statement*>* Parser::ParseEagerFunctionBody(
3160     const AstRawString* function_name, int pos,
3161     const ParserFormalParameters& parameters, FunctionKind kind,
3162     FunctionLiteral::FunctionType function_type, bool* ok) {
3163   ParsingModeScope mode(this, allow_lazy() ? PARSE_LAZILY : PARSE_EAGERLY);
3164   ZoneList<Statement*>* result = new(zone()) ZoneList<Statement*>(8, zone());
3165 
3166   static const int kFunctionNameAssignmentIndex = 0;
3167   if (function_type == FunctionLiteral::kNamedExpression) {
3168     DCHECK(function_name != NULL);
3169     // If we have a named function expression, we add a local variable
3170     // declaration to the body of the function with the name of the
3171     // function and let it refer to the function itself (closure).
3172     // Not having parsed the function body, the language mode may still change,
3173     // so we reserve a spot and create the actual const assignment later.
3174     DCHECK_EQ(kFunctionNameAssignmentIndex, result->length());
3175     result->Add(NULL, zone());
3176   }
3177 
3178   ZoneList<Statement*>* body = result;
3179   DeclarationScope* function_scope = scope()->AsDeclarationScope();
3180   DeclarationScope* inner_scope = function_scope;
3181   Block* inner_block = nullptr;
3182   if (!parameters.is_simple) {
3183     inner_scope = NewVarblockScope();
3184     inner_scope->set_start_position(scanner()->location().beg_pos);
3185     inner_block = factory()->NewBlock(NULL, 8, true, kNoSourcePosition);
3186     inner_block->set_scope(inner_scope);
3187     body = inner_block->statements();
3188   }
3189 
3190   {
3191     BlockState block_state(&scope_state_, inner_scope);
3192 
3193     if (IsGeneratorFunction(kind)) {
3194       // We produce:
3195       //
3196       // try { InitialYield; ...body...; return {value: undefined, done: true} }
3197       // finally { %_GeneratorClose(generator) }
3198       //
3199       // - InitialYield yields the actual generator object.
3200       // - Any return statement inside the body will have its argument wrapped
3201       //   in a "done" iterator result object.
3202       // - If the generator terminates for whatever reason, we must close it.
3203       //   Hence the finally clause.
3204 
3205       Block* try_block =
3206           factory()->NewBlock(nullptr, 3, false, kNoSourcePosition);
3207       Expression* initial_yield = BuildInitialYield(pos, kind);
3208       try_block->statements()->Add(
3209           factory()->NewExpressionStatement(initial_yield, kNoSourcePosition),
3210           zone());
3211       ParseStatementList(try_block->statements(), Token::RBRACE, CHECK_OK);
3212 
3213       Statement* final_return = factory()->NewReturnStatement(
3214           BuildIteratorResult(nullptr, true), kNoSourcePosition);
3215       try_block->statements()->Add(final_return, zone());
3216 
3217       Block* finally_block =
3218           factory()->NewBlock(nullptr, 1, false, kNoSourcePosition);
3219       ZoneList<Expression*>* args =
3220           new (zone()) ZoneList<Expression*>(1, zone());
3221       VariableProxy* call_proxy = factory()->NewVariableProxy(
3222           function_state_->generator_object_variable());
3223       args->Add(call_proxy, zone());
3224       Expression* call = factory()->NewCallRuntime(
3225           Runtime::kInlineGeneratorClose, args, kNoSourcePosition);
3226       finally_block->statements()->Add(
3227           factory()->NewExpressionStatement(call, kNoSourcePosition), zone());
3228 
3229       body->Add(factory()->NewTryFinallyStatement(try_block, finally_block,
3230                                                   kNoSourcePosition),
3231                 zone());
3232     } else if (IsAsyncFunction(kind)) {
3233       const bool accept_IN = true;
3234       ParseAsyncFunctionBody(inner_scope, body, kind, FunctionBodyType::kNormal,
3235                              accept_IN, pos, CHECK_OK);
3236     } else {
3237       ParseStatementList(body, Token::RBRACE, CHECK_OK);
3238     }
3239 
3240     if (IsSubclassConstructor(kind)) {
3241       body->Add(factory()->NewReturnStatement(ThisExpression(kNoSourcePosition),
3242                                               kNoSourcePosition),
3243                 zone());
3244     }
3245   }
3246 
3247   Expect(Token::RBRACE, CHECK_OK);
3248   scope()->set_end_position(scanner()->location().end_pos);
3249 
3250   if (!parameters.is_simple) {
3251     DCHECK_NOT_NULL(inner_scope);
3252     DCHECK_EQ(function_scope, scope());
3253     DCHECK_EQ(function_scope, inner_scope->outer_scope());
3254     DCHECK_EQ(body, inner_block->statements());
3255     SetLanguageMode(function_scope, inner_scope->language_mode());
3256     Block* init_block = BuildParameterInitializationBlock(parameters, CHECK_OK);
3257 
3258     if (is_sloppy(inner_scope->language_mode())) {
3259       InsertSloppyBlockFunctionVarBindings(inner_scope);
3260     }
3261 
3262     // TODO(littledan): Merge the two rejection blocks into one
3263     if (IsAsyncFunction(kind)) {
3264       init_block = BuildRejectPromiseOnException(init_block, CHECK_OK);
3265     }
3266 
3267     DCHECK_NOT_NULL(init_block);
3268 
3269     inner_scope->set_end_position(scanner()->location().end_pos);
3270     if (inner_scope->FinalizeBlockScope() != nullptr) {
3271       CheckConflictingVarDeclarations(inner_scope, CHECK_OK);
3272       InsertShadowingVarBindingInitializers(inner_block);
3273     }
3274     inner_scope = nullptr;
3275 
3276     result->Add(init_block, zone());
3277     result->Add(inner_block, zone());
3278   } else {
3279     DCHECK_EQ(inner_scope, function_scope);
3280     if (is_sloppy(function_scope->language_mode())) {
3281       InsertSloppyBlockFunctionVarBindings(function_scope);
3282     }
3283   }
3284 
3285   if (!IsArrowFunction(kind)) {
3286     // Declare arguments after parsing the function since lexical 'arguments'
3287     // masks the arguments object. Declare arguments before declaring the
3288     // function var since the arguments object masks 'function arguments'.
3289     function_scope->DeclareArguments(ast_value_factory());
3290   }
3291 
3292   if (function_type == FunctionLiteral::kNamedExpression) {
3293     Statement* statement;
3294     if (function_scope->LookupLocal(function_name) == nullptr) {
3295       // Now that we know the language mode, we can create the const assignment
3296       // in the previously reserved spot.
3297       DCHECK_EQ(function_scope, scope());
3298       Variable* fvar = function_scope->DeclareFunctionVar(function_name);
3299       VariableProxy* fproxy = factory()->NewVariableProxy(fvar);
3300       statement = factory()->NewExpressionStatement(
3301           factory()->NewAssignment(Token::INIT, fproxy,
3302                                    factory()->NewThisFunction(pos),
3303                                    kNoSourcePosition),
3304           kNoSourcePosition);
3305     } else {
3306       statement = factory()->NewEmptyStatement(kNoSourcePosition);
3307     }
3308     result->Set(kFunctionNameAssignmentIndex, statement);
3309   }
3310 
3311   MarkCollectedTailCallExpressions();
3312   return result;
3313 }
3314 
InstallHomeObject(Expression * function_literal,Expression * home_object)3315 Expression* Parser::InstallHomeObject(Expression* function_literal,
3316                                       Expression* home_object) {
3317   Block* do_block = factory()->NewBlock(nullptr, 1, false, kNoSourcePosition);
3318   Variable* result_var =
3319       scope()->NewTemporary(ast_value_factory()->empty_string());
3320   DoExpression* do_expr =
3321       factory()->NewDoExpression(do_block, result_var, kNoSourcePosition);
3322   Assignment* init = factory()->NewAssignment(
3323       Token::ASSIGN, factory()->NewVariableProxy(result_var), function_literal,
3324       kNoSourcePosition);
3325   do_block->statements()->Add(
3326       factory()->NewExpressionStatement(init, kNoSourcePosition), zone());
3327   Property* home_object_property = factory()->NewProperty(
3328       factory()->NewVariableProxy(result_var),
3329       factory()->NewSymbolLiteral("home_object_symbol", kNoSourcePosition),
3330       kNoSourcePosition);
3331   Assignment* assignment = factory()->NewAssignment(
3332       Token::ASSIGN, home_object_property, home_object, kNoSourcePosition);
3333   do_block->statements()->Add(
3334       factory()->NewExpressionStatement(assignment, kNoSourcePosition), zone());
3335   return do_expr;
3336 }
3337 
ClassFieldVariableName(bool is_name,AstValueFactory * ast_value_factory,int index)3338 const AstRawString* ClassFieldVariableName(bool is_name,
3339                                            AstValueFactory* ast_value_factory,
3340                                            int index) {
3341   std::string name =
3342       ".class-field-" + std::to_string(index) + (is_name ? "-name" : "-func");
3343   return ast_value_factory->GetOneByteString(name.c_str());
3344 }
3345 
SynthesizeClassFieldInitializer(int count)3346 FunctionLiteral* Parser::SynthesizeClassFieldInitializer(int count) {
3347   DCHECK(count > 0);
3348   // Makes a function which reads the names and initializers for each class
3349   // field out of deterministically named local variables and sets each property
3350   // to the result of evaluating its corresponding initializer in turn.
3351 
3352   // This produces a function which looks like
3353   // function () {
3354   //   this[.class-field-0-name] = .class-field-0-func();
3355   //   this[.class-field-1-name] = .class-field-1-func();
3356   //   [...]
3357   //   this[.class-field-n-name] = .class-field-n-func();
3358   //   return this;
3359   // }
3360   // except that it performs defineProperty, so that instead of '=' it has
3361   // %DefineDataPropertyInLiteral(this, .class-field-0-name,
3362   // .class-field-0-func(),
3363   //   DONT_ENUM, false)
3364 
3365   RaiseLanguageMode(STRICT);
3366   FunctionKind kind = FunctionKind::kConciseMethod;
3367   DeclarationScope* initializer_scope = NewFunctionScope(kind);
3368   SetLanguageMode(initializer_scope, language_mode());
3369   initializer_scope->set_start_position(scanner()->location().end_pos);
3370   initializer_scope->set_end_position(scanner()->location().end_pos);
3371   FunctionState initializer_state(&function_state_, &scope_state_,
3372                                   initializer_scope);
3373   ZoneList<Statement*>* body = new (zone()) ZoneList<Statement*>(count, zone());
3374   for (int i = 0; i < count; ++i) {
3375     const AstRawString* name =
3376         ClassFieldVariableName(true, ast_value_factory(), i);
3377     VariableProxy* name_proxy = scope()->NewUnresolved(factory(), name);
3378     const AstRawString* function_name =
3379         ClassFieldVariableName(false, ast_value_factory(), i);
3380     VariableProxy* function_proxy =
3381         scope()->NewUnresolved(factory(), function_name);
3382     ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
3383     args->Add(function_proxy, zone());
3384     args->Add(ThisExpression(kNoSourcePosition), zone());
3385     Expression* call = factory()->NewCallRuntime(Runtime::kInlineCall, args,
3386                                                  kNoSourcePosition);
3387     ZoneList<Expression*>* define_property_args =
3388         new (zone()) ZoneList<Expression*>(5, zone());
3389     define_property_args->Add(ThisExpression(kNoSourcePosition), zone());
3390     define_property_args->Add(name_proxy, zone());
3391     define_property_args->Add(call, zone());
3392     define_property_args->Add(
3393         factory()->NewNumberLiteral(DONT_ENUM, kNoSourcePosition), zone());
3394     define_property_args->Add(
3395         factory()->NewNumberLiteral(
3396             false,  // TODO(bakkot) function name inference a la class { x =
3397                     // function(){}; static y = function(){}; }
3398             kNoSourcePosition),
3399         zone());
3400     body->Add(factory()->NewExpressionStatement(
3401                   factory()->NewCallRuntime(
3402                       Runtime::kDefineDataProperty,
3403                       define_property_args,  // TODO(bakkot) verify that this is
3404                       // the same as object_define_property
3405                       kNoSourcePosition),
3406                   kNoSourcePosition),
3407               zone());
3408   }
3409   body->Add(factory()->NewReturnStatement(ThisExpression(kNoSourcePosition),
3410                                           kNoSourcePosition),
3411             zone());
3412   FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
3413       ast_value_factory()->empty_string(), initializer_scope, body,
3414       initializer_state.materialized_literal_count(),
3415       initializer_state.expected_property_count(), 0, count,
3416       FunctionLiteral::kNoDuplicateParameters,
3417       FunctionLiteral::kAnonymousExpression,
3418       FunctionLiteral::kShouldLazyCompile, initializer_scope->start_position(),
3419       true);
3420   function_literal->set_is_class_field_initializer(true);
3421   return function_literal;
3422 }
3423 
InsertClassFieldInitializer(FunctionLiteral * constructor)3424 FunctionLiteral* Parser::InsertClassFieldInitializer(
3425     FunctionLiteral* constructor) {
3426   Statement* call_initializer = factory()->NewExpressionStatement(
3427       CallClassFieldInitializer(
3428           constructor->scope(),
3429           constructor->scope()->NewUnresolved(
3430               factory(), ast_value_factory()->this_string(), kNoSourcePosition,
3431               THIS_VARIABLE)),
3432       kNoSourcePosition);
3433   constructor->body()->InsertAt(0, call_initializer, zone());
3434   return constructor;
3435 }
3436 
3437 // If a class name is specified, this method declares the class variable
3438 // and sets class_info->proxy to point to that name.
DeclareClassVariable(const AstRawString * name,Scope * block_scope,ClassInfo * class_info,int class_token_pos,bool * ok)3439 void Parser::DeclareClassVariable(const AstRawString* name, Scope* block_scope,
3440                                   ClassInfo* class_info, int class_token_pos,
3441                                   bool* ok) {
3442 #ifdef DEBUG
3443   scope()->SetScopeName(name);
3444 #endif
3445 
3446   if (name != nullptr) {
3447     class_info->proxy = factory()->NewVariableProxy(name, NORMAL_VARIABLE);
3448     Declaration* declaration = factory()->NewVariableDeclaration(
3449         class_info->proxy, block_scope, class_token_pos);
3450     Declare(declaration, DeclarationDescriptor::NORMAL, CONST,
3451             Variable::DefaultInitializationFlag(CONST), ok);
3452   }
3453 }
3454 
3455 // This method declares a property of the given class.  It updates the
3456 // following fields of class_info, as appropriate:
3457 //   - constructor
3458 //   - static_initializer_var
3459 //   - instance_field_initializers
3460 //   - properties
DeclareClassProperty(const AstRawString * class_name,ClassLiteralProperty * property,ClassInfo * class_info,bool * ok)3461 void Parser::DeclareClassProperty(const AstRawString* class_name,
3462                                   ClassLiteralProperty* property,
3463                                   ClassInfo* class_info, bool* ok) {
3464   if (class_info->has_seen_constructor && class_info->constructor == nullptr) {
3465     class_info->constructor = GetPropertyValue(property)->AsFunctionLiteral();
3466     DCHECK_NOT_NULL(class_info->constructor);
3467     class_info->constructor->set_raw_name(
3468         class_name != nullptr ? class_name
3469                               : ast_value_factory()->empty_string());
3470     return;
3471   }
3472 
3473   if (property->kind() == ClassLiteralProperty::FIELD) {
3474     DCHECK(allow_harmony_class_fields());
3475     if (property->is_static()) {
3476       if (class_info->static_initializer_var == nullptr) {
3477         class_info->static_initializer_var =
3478             NewTemporary(ast_value_factory()->empty_string());
3479       }
3480       // TODO(bakkot) only do this conditionally
3481       Expression* function = InstallHomeObject(
3482           property->value(),
3483           factory()->NewVariableProxy(class_info->static_initializer_var));
3484       ZoneList<Expression*>* args =
3485           new (zone()) ZoneList<Expression*>(2, zone());
3486       args->Add(function, zone());
3487       args->Add(factory()->NewVariableProxy(class_info->static_initializer_var),
3488                 zone());
3489       Expression* call = factory()->NewCallRuntime(Runtime::kInlineCall, args,
3490                                                    kNoSourcePosition);
3491       property->set_value(call);
3492     } else {
3493       // if (is_computed_name) { // TODO(bakkot) figure out why this is
3494       // necessary for non-computed names in full-codegen
3495       ZoneList<Expression*>* to_name_args =
3496           new (zone()) ZoneList<Expression*>(1, zone());
3497       to_name_args->Add(property->key(), zone());
3498       property->set_key(factory()->NewCallRuntime(
3499           Runtime::kToName, to_name_args, kNoSourcePosition));
3500       //}
3501       const AstRawString* name = ClassFieldVariableName(
3502           true, ast_value_factory(),
3503           class_info->instance_field_initializers->length());
3504       VariableProxy* name_proxy =
3505           factory()->NewVariableProxy(name, NORMAL_VARIABLE);
3506       Declaration* name_declaration = factory()->NewVariableDeclaration(
3507           name_proxy, scope(), kNoSourcePosition);
3508       Variable* name_var =
3509           Declare(name_declaration, DeclarationDescriptor::NORMAL, CONST,
3510                   kNeedsInitialization, ok, scope());
3511       DCHECK(*ok);
3512       if (!*ok) return;
3513       class_info->instance_field_initializers->Add(property->value(), zone());
3514       property->set_value(factory()->NewVariableProxy(name_var));
3515     }
3516   }
3517   class_info->properties->Add(property, zone());
3518 }
3519 
3520 // This method rewrites a class literal into a do-expression.
3521 // It uses the following fields of class_info:
3522 //   - constructor (if missing, it updates it with a default constructor)
3523 //   - proxy
3524 //   - extends
3525 //   - static_initializer_var
3526 //   - instance_field_initializers
3527 //   - properties
RewriteClassLiteral(const AstRawString * name,ClassInfo * class_info,int pos,bool * ok)3528 Expression* Parser::RewriteClassLiteral(const AstRawString* name,
3529                                         ClassInfo* class_info, int pos,
3530                                         bool* ok) {
3531   int end_pos = scanner()->location().end_pos;
3532   Block* do_block = factory()->NewBlock(nullptr, 1, false, pos);
3533   Variable* result_var = NewTemporary(ast_value_factory()->empty_string());
3534   DoExpression* do_expr = factory()->NewDoExpression(do_block, result_var, pos);
3535 
3536   bool has_extends = class_info->extends != nullptr;
3537   bool has_instance_fields =
3538       class_info->instance_field_initializers->length() > 0;
3539   DCHECK(!has_instance_fields || allow_harmony_class_fields());
3540   bool has_default_constructor = class_info->constructor == nullptr;
3541   if (has_default_constructor) {
3542     class_info->constructor =
3543         DefaultConstructor(name, has_extends, has_instance_fields, pos, end_pos,
3544                            scope()->language_mode());
3545   }
3546 
3547   if (has_instance_fields && !has_extends) {
3548     class_info->constructor =
3549         InsertClassFieldInitializer(class_info->constructor);
3550     class_info->constructor->set_requires_class_field_init(true);
3551   }  // The derived case is handled by rewriting super calls.
3552 
3553   scope()->set_end_position(end_pos);
3554 
3555   if (name != nullptr) {
3556     DCHECK_NOT_NULL(class_info->proxy);
3557     class_info->proxy->var()->set_initializer_position(end_pos);
3558   }
3559 
3560   ClassLiteral* class_literal = factory()->NewClassLiteral(
3561       class_info->proxy, class_info->extends, class_info->constructor,
3562       class_info->properties, pos, end_pos);
3563 
3564   if (class_info->static_initializer_var != nullptr) {
3565     class_literal->set_static_initializer_proxy(
3566         factory()->NewVariableProxy(class_info->static_initializer_var));
3567   }
3568 
3569   do_block->statements()->Add(
3570       factory()->NewExpressionStatement(
3571           factory()->NewAssignment(Token::ASSIGN,
3572                                    factory()->NewVariableProxy(result_var),
3573                                    class_literal, kNoSourcePosition),
3574           pos),
3575       zone());
3576   if (allow_harmony_class_fields() &&
3577       (has_instance_fields || (has_extends && !has_default_constructor))) {
3578     // Default constructors for derived classes without fields will not try to
3579     // read this variable, so there's no need to create it.
3580     const AstRawString* init_fn_name =
3581         ast_value_factory()->dot_class_field_init_string();
3582     Variable* init_fn_var = scope()->DeclareLocal(
3583         init_fn_name, CONST, kCreatedInitialized, NORMAL_VARIABLE);
3584     Expression* initializer =
3585         has_instance_fields
3586             ? static_cast<Expression*>(SynthesizeClassFieldInitializer(
3587                   class_info->instance_field_initializers->length()))
3588             : factory()->NewBooleanLiteral(false, kNoSourcePosition);
3589     Assignment* assignment = factory()->NewAssignment(
3590         Token::INIT, factory()->NewVariableProxy(init_fn_var), initializer,
3591         kNoSourcePosition);
3592     do_block->statements()->Add(
3593         factory()->NewExpressionStatement(assignment, kNoSourcePosition),
3594         zone());
3595   }
3596   for (int i = 0; i < class_info->instance_field_initializers->length(); ++i) {
3597     const AstRawString* function_name =
3598         ClassFieldVariableName(false, ast_value_factory(), i);
3599     VariableProxy* function_proxy =
3600         factory()->NewVariableProxy(function_name, NORMAL_VARIABLE);
3601     Declaration* function_declaration = factory()->NewVariableDeclaration(
3602         function_proxy, scope(), kNoSourcePosition);
3603     Variable* function_var =
3604         Declare(function_declaration, DeclarationDescriptor::NORMAL, CONST,
3605                 kNeedsInitialization, ok, scope());
3606     if (!*ok) return nullptr;
3607     Property* prototype_property = factory()->NewProperty(
3608         factory()->NewVariableProxy(result_var),
3609         factory()->NewStringLiteral(ast_value_factory()->prototype_string(),
3610                                     kNoSourcePosition),
3611         kNoSourcePosition);
3612     Expression* function_value = InstallHomeObject(
3613         class_info->instance_field_initializers->at(i),
3614         prototype_property);  // TODO(bakkot) ideally this would be conditional,
3615                               // especially in trivial cases
3616     Assignment* function_assignment = factory()->NewAssignment(
3617         Token::INIT, factory()->NewVariableProxy(function_var), function_value,
3618         kNoSourcePosition);
3619     do_block->statements()->Add(factory()->NewExpressionStatement(
3620                                     function_assignment, kNoSourcePosition),
3621                                 zone());
3622   }
3623   do_block->set_scope(scope()->FinalizeBlockScope());
3624   do_expr->set_represented_function(class_info->constructor);
3625   AddFunctionForNameInference(class_info->constructor);
3626 
3627   return do_expr;
3628 }
3629 
GetLiteralUndefined(int position)3630 Literal* Parser::GetLiteralUndefined(int position) {
3631   return factory()->NewUndefinedLiteral(position);
3632 }
3633 
3634 
CheckConflictingVarDeclarations(Scope * scope,bool * ok)3635 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) {
3636   Declaration* decl = scope->CheckConflictingVarDeclarations();
3637   if (decl != NULL) {
3638     // In ES6, conflicting variable bindings are early errors.
3639     const AstRawString* name = decl->proxy()->raw_name();
3640     int position = decl->proxy()->position();
3641     Scanner::Location location =
3642         position == kNoSourcePosition
3643             ? Scanner::Location::invalid()
3644             : Scanner::Location(position, position + 1);
3645     ReportMessageAt(location, MessageTemplate::kVarRedeclaration, name);
3646     *ok = false;
3647   }
3648 }
3649 
3650 
InsertShadowingVarBindingInitializers(Block * inner_block)3651 void Parser::InsertShadowingVarBindingInitializers(Block* inner_block) {
3652   // For each var-binding that shadows a parameter, insert an assignment
3653   // initializing the variable with the parameter.
3654   Scope* inner_scope = inner_block->scope();
3655   DCHECK(inner_scope->is_declaration_scope());
3656   Scope* function_scope = inner_scope->outer_scope();
3657   DCHECK(function_scope->is_function_scope());
3658   BlockState block_state(&scope_state_, inner_scope);
3659   for (Declaration* decl : *inner_scope->declarations()) {
3660     if (decl->proxy()->var()->mode() != VAR || !decl->IsVariableDeclaration()) {
3661       continue;
3662     }
3663     const AstRawString* name = decl->proxy()->raw_name();
3664     Variable* parameter = function_scope->LookupLocal(name);
3665     if (parameter == nullptr) continue;
3666     VariableProxy* to = NewUnresolved(name);
3667     VariableProxy* from = factory()->NewVariableProxy(parameter);
3668     Expression* assignment =
3669         factory()->NewAssignment(Token::ASSIGN, to, from, kNoSourcePosition);
3670     Statement* statement =
3671         factory()->NewExpressionStatement(assignment, kNoSourcePosition);
3672     inner_block->statements()->InsertAt(0, statement, zone());
3673   }
3674 }
3675 
InsertSloppyBlockFunctionVarBindings(DeclarationScope * scope)3676 void Parser::InsertSloppyBlockFunctionVarBindings(DeclarationScope* scope) {
3677   // For the outermost eval scope, we cannot hoist during parsing: let
3678   // declarations in the surrounding scope may prevent hoisting, but the
3679   // information is unaccessible during parsing. In this case, we hoist later in
3680   // DeclarationScope::Analyze.
3681   if (scope->is_eval_scope() && scope->outer_scope() == original_scope_) {
3682     return;
3683   }
3684   scope->HoistSloppyBlockFunctions(factory());
3685 }
3686 
3687 // ----------------------------------------------------------------------------
3688 // Parser support
3689 
TargetStackContainsLabel(const AstRawString * label)3690 bool Parser::TargetStackContainsLabel(const AstRawString* label) {
3691   for (ParserTarget* t = target_stack_; t != NULL; t = t->previous()) {
3692     if (ContainsLabel(t->statement()->labels(), label)) return true;
3693   }
3694   return false;
3695 }
3696 
3697 
LookupBreakTarget(const AstRawString * label,bool * ok)3698 BreakableStatement* Parser::LookupBreakTarget(const AstRawString* label,
3699                                               bool* ok) {
3700   bool anonymous = label == NULL;
3701   for (ParserTarget* t = target_stack_; t != NULL; t = t->previous()) {
3702     BreakableStatement* stat = t->statement();
3703     if ((anonymous && stat->is_target_for_anonymous()) ||
3704         (!anonymous && ContainsLabel(stat->labels(), label))) {
3705       return stat;
3706     }
3707   }
3708   return NULL;
3709 }
3710 
3711 
LookupContinueTarget(const AstRawString * label,bool * ok)3712 IterationStatement* Parser::LookupContinueTarget(const AstRawString* label,
3713                                                  bool* ok) {
3714   bool anonymous = label == NULL;
3715   for (ParserTarget* t = target_stack_; t != NULL; t = t->previous()) {
3716     IterationStatement* stat = t->statement()->AsIterationStatement();
3717     if (stat == NULL) continue;
3718 
3719     DCHECK(stat->is_target_for_anonymous());
3720     if (anonymous || ContainsLabel(stat->labels(), label)) {
3721       return stat;
3722     }
3723   }
3724   return NULL;
3725 }
3726 
3727 
HandleSourceURLComments(Isolate * isolate,Handle<Script> script)3728 void Parser::HandleSourceURLComments(Isolate* isolate, Handle<Script> script) {
3729   Handle<String> source_url = scanner_.SourceUrl(isolate);
3730   if (!source_url.is_null()) {
3731     script->set_source_url(*source_url);
3732   }
3733   Handle<String> source_mapping_url = scanner_.SourceMappingUrl(isolate);
3734   if (!source_mapping_url.is_null()) {
3735     script->set_source_mapping_url(*source_mapping_url);
3736   }
3737 }
3738 
3739 
Internalize(Isolate * isolate,Handle<Script> script,bool error)3740 void Parser::Internalize(Isolate* isolate, Handle<Script> script, bool error) {
3741   // Internalize strings and values.
3742   ast_value_factory()->Internalize(isolate);
3743 
3744   // Error processing.
3745   if (error) {
3746     if (stack_overflow()) {
3747       isolate->StackOverflow();
3748     } else {
3749       DCHECK(pending_error_handler_.has_pending_error());
3750       pending_error_handler_.ThrowPendingError(isolate, script);
3751     }
3752   }
3753 
3754   // Move statistics to Isolate.
3755   for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
3756        ++feature) {
3757     if (use_counts_[feature] > 0) {
3758       isolate->CountUsage(v8::Isolate::UseCounterFeature(feature));
3759     }
3760   }
3761   if (scanner_.FoundHtmlComment()) {
3762     isolate->CountUsage(v8::Isolate::kHtmlComment);
3763     if (script->line_offset() == 0 && script->column_offset() == 0) {
3764       isolate->CountUsage(v8::Isolate::kHtmlCommentInExternalScript);
3765     }
3766   }
3767   isolate->counters()->total_preparse_skipped()->Increment(
3768       total_preparse_skipped_);
3769   if (!parsing_on_main_thread_ &&
3770       FLAG_runtime_stats ==
3771           v8::tracing::TracingCategoryObserver::ENABLED_BY_NATIVE) {
3772     // Copy over the counters from the background thread to the main counters on
3773     // the isolate.
3774     // TODO(cbruni,lpy): properly attach the runtime stats to the trace for
3775     // background parsing.
3776     isolate->counters()->runtime_call_stats()->Add(runtime_call_stats_);
3777   }
3778 }
3779 
3780 
3781 // ----------------------------------------------------------------------------
3782 // The Parser interface.
3783 
3784 
ParseStatic(ParseInfo * info)3785 bool Parser::ParseStatic(ParseInfo* info) {
3786   Parser parser(info);
3787   if (parser.Parse(info)) {
3788     info->set_language_mode(info->literal()->language_mode());
3789     return true;
3790   }
3791   return false;
3792 }
3793 
3794 
Parse(ParseInfo * info)3795 bool Parser::Parse(ParseInfo* info) {
3796   DCHECK(info->literal() == NULL);
3797   FunctionLiteral* result = NULL;
3798   // Ok to use Isolate here; this function is only called in the main thread.
3799   DCHECK(parsing_on_main_thread_);
3800   Isolate* isolate = info->isolate();
3801 
3802   if (info->is_toplevel()) {
3803     SetCachedData(info);
3804     result = ParseProgram(isolate, info);
3805   } else {
3806     result = ParseFunction(isolate, info);
3807   }
3808   info->set_literal(result);
3809 
3810   Internalize(isolate, info->script(), result == NULL);
3811   return (result != NULL);
3812 }
3813 
3814 
ParseOnBackground(ParseInfo * info)3815 void Parser::ParseOnBackground(ParseInfo* info) {
3816   parsing_on_main_thread_ = false;
3817 
3818   DCHECK(info->literal() == NULL);
3819   FunctionLiteral* result = NULL;
3820 
3821   ParserLogger logger;
3822   if (produce_cached_parse_data()) log_ = &logger;
3823   if (FLAG_runtime_stats) {
3824     // Create separate runtime stats for background parsing.
3825     runtime_call_stats_ = new (zone()) RuntimeCallStats();
3826   }
3827 
3828   std::unique_ptr<Utf16CharacterStream> stream;
3829   Utf16CharacterStream* stream_ptr;
3830   if (info->character_stream()) {
3831     DCHECK(info->source_stream() == nullptr);
3832     stream_ptr = info->character_stream();
3833   } else {
3834     DCHECK(info->character_stream() == nullptr);
3835     stream.reset(ScannerStream::For(info->source_stream(),
3836                                     info->source_stream_encoding()));
3837     stream_ptr = stream.get();
3838   }
3839   DCHECK(info->maybe_outer_scope_info().is_null());
3840 
3841   DCHECK(original_scope_);
3842 
3843   // When streaming, we don't know the length of the source until we have parsed
3844   // it. The raw data can be UTF-8, so we wouldn't know the source length until
3845   // we have decoded it anyway even if we knew the raw data length (which we
3846   // don't). We work around this by storing all the scopes which need their end
3847   // position set at the end of the script (the top scope and possible eval
3848   // scopes) and set their end position after we know the script length.
3849   if (info->is_toplevel()) {
3850     fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
3851     scanner_.Initialize(stream_ptr);
3852     result = DoParseProgram(info);
3853   } else {
3854     result = DoParseFunction(info, info->function_name(), stream_ptr);
3855   }
3856 
3857   info->set_literal(result);
3858 
3859   // We cannot internalize on a background thread; a foreground task will take
3860   // care of calling Parser::Internalize just before compilation.
3861 
3862   if (produce_cached_parse_data()) {
3863     if (result != NULL) *info->cached_data() = logger.GetScriptData();
3864     log_ = NULL;
3865   }
3866   if (FLAG_runtime_stats) {
3867     // TODO(cbruni,lpy): properly attach the runtime stats to the trace for
3868     // background parsing.
3869   }
3870 }
3871 
OpenTemplateLiteral(int pos)3872 Parser::TemplateLiteralState Parser::OpenTemplateLiteral(int pos) {
3873   return new (zone()) TemplateLiteral(zone(), pos);
3874 }
3875 
3876 
AddTemplateSpan(TemplateLiteralState * state,bool tail)3877 void Parser::AddTemplateSpan(TemplateLiteralState* state, bool tail) {
3878   int pos = scanner()->location().beg_pos;
3879   int end = scanner()->location().end_pos - (tail ? 1 : 2);
3880   const AstRawString* tv = scanner()->CurrentSymbol(ast_value_factory());
3881   const AstRawString* trv = scanner()->CurrentRawSymbol(ast_value_factory());
3882   Literal* cooked = factory()->NewStringLiteral(tv, pos);
3883   Literal* raw = factory()->NewStringLiteral(trv, pos);
3884   (*state)->AddTemplateSpan(cooked, raw, end, zone());
3885 }
3886 
3887 
AddTemplateExpression(TemplateLiteralState * state,Expression * expression)3888 void Parser::AddTemplateExpression(TemplateLiteralState* state,
3889                                    Expression* expression) {
3890   (*state)->AddExpression(expression, zone());
3891 }
3892 
3893 
CloseTemplateLiteral(TemplateLiteralState * state,int start,Expression * tag)3894 Expression* Parser::CloseTemplateLiteral(TemplateLiteralState* state, int start,
3895                                          Expression* tag) {
3896   TemplateLiteral* lit = *state;
3897   int pos = lit->position();
3898   const ZoneList<Expression*>* cooked_strings = lit->cooked();
3899   const ZoneList<Expression*>* raw_strings = lit->raw();
3900   const ZoneList<Expression*>* expressions = lit->expressions();
3901   DCHECK_EQ(cooked_strings->length(), raw_strings->length());
3902   DCHECK_EQ(cooked_strings->length(), expressions->length() + 1);
3903 
3904   if (!tag) {
3905     // Build tree of BinaryOps to simplify code-generation
3906     Expression* expr = cooked_strings->at(0);
3907     int i = 0;
3908     while (i < expressions->length()) {
3909       Expression* sub = expressions->at(i++);
3910       Expression* cooked_str = cooked_strings->at(i);
3911 
3912       // Let middle be ToString(sub).
3913       ZoneList<Expression*>* args =
3914           new (zone()) ZoneList<Expression*>(1, zone());
3915       args->Add(sub, zone());
3916       Expression* middle = factory()->NewCallRuntime(Runtime::kInlineToString,
3917                                                      args, sub->position());
3918 
3919       expr = factory()->NewBinaryOperation(
3920           Token::ADD, factory()->NewBinaryOperation(
3921                           Token::ADD, expr, middle, expr->position()),
3922           cooked_str, sub->position());
3923     }
3924     return expr;
3925   } else {
3926     uint32_t hash = ComputeTemplateLiteralHash(lit);
3927 
3928     int cooked_idx = function_state_->NextMaterializedLiteralIndex();
3929     int raw_idx = function_state_->NextMaterializedLiteralIndex();
3930 
3931     // $getTemplateCallSite
3932     ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(4, zone());
3933     args->Add(factory()->NewArrayLiteral(
3934                   const_cast<ZoneList<Expression*>*>(cooked_strings),
3935                   cooked_idx, pos),
3936               zone());
3937     args->Add(
3938         factory()->NewArrayLiteral(
3939             const_cast<ZoneList<Expression*>*>(raw_strings), raw_idx, pos),
3940         zone());
3941 
3942     // Truncate hash to Smi-range.
3943     Smi* hash_obj = Smi::cast(Internals::IntToSmi(static_cast<int>(hash)));
3944     args->Add(factory()->NewNumberLiteral(hash_obj->value(), pos), zone());
3945 
3946     Expression* call_site = factory()->NewCallRuntime(
3947         Context::GET_TEMPLATE_CALL_SITE_INDEX, args, start);
3948 
3949     // Call TagFn
3950     ZoneList<Expression*>* call_args =
3951         new (zone()) ZoneList<Expression*>(expressions->length() + 1, zone());
3952     call_args->Add(call_site, zone());
3953     call_args->AddAll(*expressions, zone());
3954     return factory()->NewCall(tag, call_args, pos);
3955   }
3956 }
3957 
3958 
ComputeTemplateLiteralHash(const TemplateLiteral * lit)3959 uint32_t Parser::ComputeTemplateLiteralHash(const TemplateLiteral* lit) {
3960   const ZoneList<Expression*>* raw_strings = lit->raw();
3961   int total = raw_strings->length();
3962   DCHECK(total);
3963 
3964   uint32_t running_hash = 0;
3965 
3966   for (int index = 0; index < total; ++index) {
3967     if (index) {
3968       running_hash = StringHasher::ComputeRunningHashOneByte(
3969           running_hash, "${}", 3);
3970     }
3971 
3972     const AstRawString* raw_string =
3973         raw_strings->at(index)->AsLiteral()->raw_value()->AsString();
3974     if (raw_string->is_one_byte()) {
3975       const char* data = reinterpret_cast<const char*>(raw_string->raw_data());
3976       running_hash = StringHasher::ComputeRunningHashOneByte(
3977           running_hash, data, raw_string->length());
3978     } else {
3979       const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data());
3980       running_hash = StringHasher::ComputeRunningHash(running_hash, data,
3981                                                       raw_string->length());
3982     }
3983   }
3984 
3985   return running_hash;
3986 }
3987 
PrepareSpreadArguments(ZoneList<Expression * > * list)3988 ZoneList<Expression*>* Parser::PrepareSpreadArguments(
3989     ZoneList<Expression*>* list) {
3990   ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(1, zone());
3991   if (list->length() == 1) {
3992     // Spread-call with single spread argument produces an InternalArray
3993     // containing the values from the array.
3994     //
3995     // Function is called or constructed with the produced array of arguments
3996     //
3997     // EG: Apply(Func, Spread(spread0))
3998     ZoneList<Expression*>* spread_list =
3999         new (zone()) ZoneList<Expression*>(0, zone());
4000     spread_list->Add(list->at(0)->AsSpread()->expression(), zone());
4001     args->Add(factory()->NewCallRuntime(Runtime::kSpreadIterablePrepare,
4002                                         spread_list, kNoSourcePosition),
4003               zone());
4004     return args;
4005   } else {
4006     // Spread-call with multiple arguments produces array literals for each
4007     // sequences of unspread arguments, and converts each spread iterable to
4008     // an Internal array. Finally, all of these produced arrays are flattened
4009     // into a single InternalArray, containing the arguments for the call.
4010     //
4011     // EG: Apply(Func, Flatten([unspread0, unspread1], Spread(spread0),
4012     //                         Spread(spread1), [unspread2, unspread3]))
4013     int i = 0;
4014     int n = list->length();
4015     while (i < n) {
4016       if (!list->at(i)->IsSpread()) {
4017         ZoneList<Expression*>* unspread =
4018             new (zone()) ZoneList<Expression*>(1, zone());
4019 
4020         // Push array of unspread parameters
4021         while (i < n && !list->at(i)->IsSpread()) {
4022           unspread->Add(list->at(i++), zone());
4023         }
4024         int literal_index = function_state_->NextMaterializedLiteralIndex();
4025         args->Add(factory()->NewArrayLiteral(unspread, literal_index,
4026                                              kNoSourcePosition),
4027                   zone());
4028 
4029         if (i == n) break;
4030       }
4031 
4032       // Push eagerly spread argument
4033       ZoneList<Expression*>* spread_list =
4034           new (zone()) ZoneList<Expression*>(1, zone());
4035       spread_list->Add(list->at(i++)->AsSpread()->expression(), zone());
4036       args->Add(factory()->NewCallRuntime(Context::SPREAD_ITERABLE_INDEX,
4037                                           spread_list, kNoSourcePosition),
4038                 zone());
4039     }
4040 
4041     list = new (zone()) ZoneList<Expression*>(1, zone());
4042     list->Add(factory()->NewCallRuntime(Context::SPREAD_ARGUMENTS_INDEX, args,
4043                                         kNoSourcePosition),
4044               zone());
4045     return list;
4046   }
4047   UNREACHABLE();
4048 }
4049 
SpreadCall(Expression * function,ZoneList<Expression * > * args,int pos)4050 Expression* Parser::SpreadCall(Expression* function,
4051                                ZoneList<Expression*>* args, int pos) {
4052   if (function->IsSuperCallReference()) {
4053     // Super calls
4054     // $super_constructor = %_GetSuperConstructor(<this-function>)
4055     // %reflect_construct($super_constructor, args, new.target)
4056     ZoneList<Expression*>* tmp = new (zone()) ZoneList<Expression*>(1, zone());
4057     tmp->Add(function->AsSuperCallReference()->this_function_var(), zone());
4058     Expression* super_constructor = factory()->NewCallRuntime(
4059         Runtime::kInlineGetSuperConstructor, tmp, pos);
4060     args->InsertAt(0, super_constructor, zone());
4061     args->Add(function->AsSuperCallReference()->new_target_var(), zone());
4062     return factory()->NewCallRuntime(Context::REFLECT_CONSTRUCT_INDEX, args,
4063                                      pos);
4064   } else {
4065     if (function->IsProperty()) {
4066       // Method calls
4067       if (function->AsProperty()->IsSuperAccess()) {
4068         Expression* home = ThisExpression(kNoSourcePosition);
4069         args->InsertAt(0, function, zone());
4070         args->InsertAt(1, home, zone());
4071       } else {
4072         Variable* temp = NewTemporary(ast_value_factory()->empty_string());
4073         VariableProxy* obj = factory()->NewVariableProxy(temp);
4074         Assignment* assign_obj = factory()->NewAssignment(
4075             Token::ASSIGN, obj, function->AsProperty()->obj(),
4076             kNoSourcePosition);
4077         function = factory()->NewProperty(
4078             assign_obj, function->AsProperty()->key(), kNoSourcePosition);
4079         args->InsertAt(0, function, zone());
4080         obj = factory()->NewVariableProxy(temp);
4081         args->InsertAt(1, obj, zone());
4082       }
4083     } else {
4084       // Non-method calls
4085       args->InsertAt(0, function, zone());
4086       args->InsertAt(1, factory()->NewUndefinedLiteral(kNoSourcePosition),
4087                      zone());
4088     }
4089     return factory()->NewCallRuntime(Context::REFLECT_APPLY_INDEX, args, pos);
4090   }
4091 }
4092 
SpreadCallNew(Expression * function,ZoneList<Expression * > * args,int pos)4093 Expression* Parser::SpreadCallNew(Expression* function,
4094                                   ZoneList<Expression*>* args, int pos) {
4095   args->InsertAt(0, function, zone());
4096 
4097   return factory()->NewCallRuntime(Context::REFLECT_CONSTRUCT_INDEX, args, pos);
4098 }
4099 
4100 
SetLanguageMode(Scope * scope,LanguageMode mode)4101 void Parser::SetLanguageMode(Scope* scope, LanguageMode mode) {
4102   v8::Isolate::UseCounterFeature feature;
4103   if (is_sloppy(mode))
4104     feature = v8::Isolate::kSloppyMode;
4105   else if (is_strict(mode))
4106     feature = v8::Isolate::kStrictMode;
4107   else
4108     UNREACHABLE();
4109   ++use_counts_[feature];
4110   scope->SetLanguageMode(mode);
4111 }
4112 
SetAsmModule()4113 void Parser::SetAsmModule() {
4114   // Store the usage count; The actual use counter on the isolate is
4115   // incremented after parsing is done.
4116   ++use_counts_[v8::Isolate::kUseAsm];
4117   DCHECK(scope()->is_declaration_scope());
4118   scope()->AsDeclarationScope()->set_asm_module();
4119 }
4120 
MarkCollectedTailCallExpressions()4121 void Parser::MarkCollectedTailCallExpressions() {
4122   const ZoneList<Expression*>& tail_call_expressions =
4123       function_state_->tail_call_expressions().expressions();
4124   for (int i = 0; i < tail_call_expressions.length(); ++i) {
4125     MarkTailPosition(tail_call_expressions[i]);
4126   }
4127 }
4128 
ExpressionListToExpression(ZoneList<Expression * > * args)4129 Expression* Parser::ExpressionListToExpression(ZoneList<Expression*>* args) {
4130   Expression* expr = args->at(0);
4131   for (int i = 1; i < args->length(); ++i) {
4132     expr = factory()->NewBinaryOperation(Token::COMMA, expr, args->at(i),
4133                                          expr->position());
4134   }
4135   return expr;
4136 }
4137 
4138 // This method intoduces the line initializing the generator object
4139 // when desugaring the body of async_function.
PrepareAsyncFunctionBody(ZoneList<Statement * > * body,FunctionKind kind,int pos)4140 void Parser::PrepareAsyncFunctionBody(ZoneList<Statement*>* body,
4141                                       FunctionKind kind, int pos) {
4142   // function async_function() {
4143   //   .generator_object = %CreateGeneratorObject();
4144   //   BuildRejectPromiseOnException({
4145   //     ... block ...
4146   //     return %ResolvePromise(.promise, expr), .promise;
4147   //   })
4148   // }
4149 
4150   Variable* temp =
4151       NewTemporary(ast_value_factory()->dot_generator_object_string());
4152   function_state_->set_generator_object_variable(temp);
4153 
4154   Expression* init_generator_variable = factory()->NewAssignment(
4155       Token::INIT, factory()->NewVariableProxy(temp),
4156       BuildCreateJSGeneratorObject(pos, kind), kNoSourcePosition);
4157   body->Add(factory()->NewExpressionStatement(init_generator_variable,
4158                                               kNoSourcePosition),
4159             zone());
4160 }
4161 
4162 // This method completes the desugaring of the body of async_function.
RewriteAsyncFunctionBody(ZoneList<Statement * > * body,Block * block,Expression * return_value,bool * ok)4163 void Parser::RewriteAsyncFunctionBody(ZoneList<Statement*>* body, Block* block,
4164                                       Expression* return_value, bool* ok) {
4165   // function async_function() {
4166   //   .generator_object = %CreateGeneratorObject();
4167   //   BuildRejectPromiseOnException({
4168   //     ... block ...
4169   //     return %ResolvePromise(.promise, expr), .promise;
4170   //   })
4171   // }
4172 
4173   return_value = BuildResolvePromise(return_value, return_value->position());
4174   block->statements()->Add(
4175       factory()->NewReturnStatement(return_value, return_value->position()),
4176       zone());
4177   block = BuildRejectPromiseOnException(block, CHECK_OK_VOID);
4178   body->Add(block, zone());
4179 }
4180 
RewriteAwaitExpression(Expression * value,int await_pos)4181 Expression* Parser::RewriteAwaitExpression(Expression* value, int await_pos) {
4182   // yield do {
4183   //   tmp = <operand>;
4184   //   %AsyncFunctionAwait(.generator_object, tmp, .promise);
4185   //   .promise
4186   // }
4187   // The value of the expression is returned to the caller of the async
4188   // function for the first yield statement; for this, .promise is the
4189   // appropriate return value, being a Promise that will be fulfilled or
4190   // rejected with the appropriate value by the desugaring. Subsequent yield
4191   // occurrences will return to the AsyncFunctionNext call within the
4192   // implemementation of the intermediate throwaway Promise's then handler.
4193   // This handler has nothing useful to do with the value, as the Promise is
4194   // ignored. If we yielded the value of the throwawayPromise that
4195   // AsyncFunctionAwait creates as an intermediate, it would create a memory
4196   // leak; we must return .promise instead;
4197   // The operand needs to be evaluated on a separate statement in order to get
4198   // a break location, and the .promise needs to be read earlier so that it
4199   // doesn't insert a false location.
4200   // TODO(littledan): investigate why this ordering is needed in more detail.
4201   Variable* generator_object_variable =
4202       function_state_->generator_object_variable();
4203 
4204   // If generator_object_variable is null,
4205   // TODO(littledan): Is this necessary?
4206   if (!generator_object_variable) return value;
4207 
4208   const int nopos = kNoSourcePosition;
4209 
4210   Block* do_block = factory()->NewBlock(nullptr, 2, false, nopos);
4211 
4212   Variable* promise = PromiseVariable();
4213 
4214   // Wrap value evaluation to provide a break location.
4215   Variable* temp_var = NewTemporary(ast_value_factory()->empty_string());
4216   Expression* value_assignment = factory()->NewAssignment(
4217       Token::ASSIGN, factory()->NewVariableProxy(temp_var), value, nopos);
4218   do_block->statements()->Add(
4219       factory()->NewExpressionStatement(value_assignment, value->position()),
4220       zone());
4221 
4222   ZoneList<Expression*>* async_function_await_args =
4223       new (zone()) ZoneList<Expression*>(3, zone());
4224   Expression* generator_object =
4225       factory()->NewVariableProxy(generator_object_variable);
4226   async_function_await_args->Add(generator_object, zone());
4227   async_function_await_args->Add(factory()->NewVariableProxy(temp_var), zone());
4228   async_function_await_args->Add(factory()->NewVariableProxy(promise), zone());
4229 
4230   // The parser emits calls to AsyncFunctionAwaitCaught, but the
4231   // AstNumberingVisitor will rewrite this to AsyncFunctionAwaitUncaught
4232   // if there is no local enclosing try/catch block.
4233   Expression* async_function_await =
4234       factory()->NewCallRuntime(Context::ASYNC_FUNCTION_AWAIT_CAUGHT_INDEX,
4235                                 async_function_await_args, nopos);
4236   do_block->statements()->Add(
4237       factory()->NewExpressionStatement(async_function_await, await_pos),
4238       zone());
4239 
4240   // Wrap await to provide a break location between value evaluation and yield.
4241   Expression* do_expr = factory()->NewDoExpression(do_block, promise, nopos);
4242 
4243   generator_object = factory()->NewVariableProxy(generator_object_variable);
4244   return factory()->NewYield(generator_object, do_expr, nopos,
4245                              Yield::kOnExceptionRethrow);
4246 }
4247 
4248 class NonPatternRewriter : public AstExpressionRewriter {
4249  public:
NonPatternRewriter(uintptr_t stack_limit,Parser * parser)4250   NonPatternRewriter(uintptr_t stack_limit, Parser* parser)
4251       : AstExpressionRewriter(stack_limit), parser_(parser) {}
~NonPatternRewriter()4252   ~NonPatternRewriter() override {}
4253 
4254  private:
RewriteExpression(Expression * expr)4255   bool RewriteExpression(Expression* expr) override {
4256     if (expr->IsRewritableExpression()) return true;
4257     // Rewrite only what could have been a pattern but is not.
4258     if (expr->IsArrayLiteral()) {
4259       // Spread rewriting in array literals.
4260       ArrayLiteral* lit = expr->AsArrayLiteral();
4261       VisitExpressions(lit->values());
4262       replacement_ = parser_->RewriteSpreads(lit);
4263       return false;
4264     }
4265     if (expr->IsObjectLiteral()) {
4266       return true;
4267     }
4268     if (expr->IsBinaryOperation() &&
4269         expr->AsBinaryOperation()->op() == Token::COMMA) {
4270       return true;
4271     }
4272     // Everything else does not need rewriting.
4273     return false;
4274   }
4275 
VisitLiteralProperty(LiteralProperty * property)4276   void VisitLiteralProperty(LiteralProperty* property) override {
4277     if (property == nullptr) return;
4278     // Do not rewrite (computed) key expressions
4279     AST_REWRITE_PROPERTY(Expression, property, value);
4280   }
4281 
4282   Parser* parser_;
4283 };
4284 
RewriteNonPattern(bool * ok)4285 void Parser::RewriteNonPattern(bool* ok) {
4286   ValidateExpression(CHECK_OK_VOID);
4287   auto non_patterns_to_rewrite = function_state_->non_patterns_to_rewrite();
4288   int begin = classifier()->GetNonPatternBegin();
4289   int end = non_patterns_to_rewrite->length();
4290   if (begin < end) {
4291     NonPatternRewriter rewriter(stack_limit_, this);
4292     for (int i = begin; i < end; i++) {
4293       DCHECK(non_patterns_to_rewrite->at(i)->IsRewritableExpression());
4294       rewriter.Rewrite(non_patterns_to_rewrite->at(i));
4295     }
4296     non_patterns_to_rewrite->Rewind(begin);
4297   }
4298 }
4299 
4300 
RewriteDestructuringAssignments()4301 void Parser::RewriteDestructuringAssignments() {
4302   const auto& assignments =
4303       function_state_->destructuring_assignments_to_rewrite();
4304   for (int i = assignments.length() - 1; i >= 0; --i) {
4305     // Rewrite list in reverse, so that nested assignment patterns are rewritten
4306     // correctly.
4307     const DestructuringAssignment& pair = assignments.at(i);
4308     RewritableExpression* to_rewrite =
4309         pair.assignment->AsRewritableExpression();
4310     DCHECK_NOT_NULL(to_rewrite);
4311     if (!to_rewrite->is_rewritten()) {
4312       // Since this function is called at the end of parsing the program,
4313       // pair.scope may already have been removed by FinalizeBlockScope in the
4314       // meantime.
4315       Scope* scope = pair.scope->GetUnremovedScope();
4316       PatternRewriter::RewriteDestructuringAssignment(this, to_rewrite, scope);
4317     }
4318   }
4319 }
4320 
RewriteExponentiation(Expression * left,Expression * right,int pos)4321 Expression* Parser::RewriteExponentiation(Expression* left, Expression* right,
4322                                           int pos) {
4323   ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
4324   args->Add(left, zone());
4325   args->Add(right, zone());
4326   return factory()->NewCallRuntime(Context::MATH_POW_INDEX, args, pos);
4327 }
4328 
RewriteAssignExponentiation(Expression * left,Expression * right,int pos)4329 Expression* Parser::RewriteAssignExponentiation(Expression* left,
4330                                                 Expression* right, int pos) {
4331   ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
4332   if (left->IsVariableProxy()) {
4333     VariableProxy* lhs = left->AsVariableProxy();
4334 
4335     Expression* result;
4336     DCHECK_NOT_NULL(lhs->raw_name());
4337     result = ExpressionFromIdentifier(lhs->raw_name(), lhs->position());
4338     args->Add(left, zone());
4339     args->Add(right, zone());
4340     Expression* call =
4341         factory()->NewCallRuntime(Context::MATH_POW_INDEX, args, pos);
4342     return factory()->NewAssignment(Token::ASSIGN, result, call, pos);
4343   } else if (left->IsProperty()) {
4344     Property* prop = left->AsProperty();
4345     auto temp_obj = NewTemporary(ast_value_factory()->empty_string());
4346     auto temp_key = NewTemporary(ast_value_factory()->empty_string());
4347     Expression* assign_obj = factory()->NewAssignment(
4348         Token::ASSIGN, factory()->NewVariableProxy(temp_obj), prop->obj(),
4349         kNoSourcePosition);
4350     Expression* assign_key = factory()->NewAssignment(
4351         Token::ASSIGN, factory()->NewVariableProxy(temp_key), prop->key(),
4352         kNoSourcePosition);
4353     args->Add(factory()->NewProperty(factory()->NewVariableProxy(temp_obj),
4354                                      factory()->NewVariableProxy(temp_key),
4355                                      left->position()),
4356               zone());
4357     args->Add(right, zone());
4358     Expression* call =
4359         factory()->NewCallRuntime(Context::MATH_POW_INDEX, args, pos);
4360     Expression* target = factory()->NewProperty(
4361         factory()->NewVariableProxy(temp_obj),
4362         factory()->NewVariableProxy(temp_key), kNoSourcePosition);
4363     Expression* assign =
4364         factory()->NewAssignment(Token::ASSIGN, target, call, pos);
4365     return factory()->NewBinaryOperation(
4366         Token::COMMA, assign_obj,
4367         factory()->NewBinaryOperation(Token::COMMA, assign_key, assign, pos),
4368         pos);
4369   }
4370   UNREACHABLE();
4371   return nullptr;
4372 }
4373 
RewriteSpreads(ArrayLiteral * lit)4374 Expression* Parser::RewriteSpreads(ArrayLiteral* lit) {
4375   // Array literals containing spreads are rewritten using do expressions, e.g.
4376   //    [1, 2, 3, ...x, 4, ...y, 5]
4377   // is roughly rewritten as:
4378   //    do {
4379   //      $R = [1, 2, 3];
4380   //      for ($i of x) %AppendElement($R, $i);
4381   //      %AppendElement($R, 4);
4382   //      for ($j of y) %AppendElement($R, $j);
4383   //      %AppendElement($R, 5);
4384   //      $R
4385   //    }
4386   // where $R, $i and $j are fresh temporary variables.
4387   ZoneList<Expression*>::iterator s = lit->FirstSpread();
4388   if (s == lit->EndValue()) return nullptr;  // no spread, no rewriting...
4389   Variable* result = NewTemporary(ast_value_factory()->dot_result_string());
4390   // NOTE: The value assigned to R is the whole original array literal,
4391   // spreads included. This will be fixed before the rewritten AST is returned.
4392   // $R = lit
4393   Expression* init_result = factory()->NewAssignment(
4394       Token::INIT, factory()->NewVariableProxy(result), lit, kNoSourcePosition);
4395   Block* do_block = factory()->NewBlock(nullptr, 16, false, kNoSourcePosition);
4396   do_block->statements()->Add(
4397       factory()->NewExpressionStatement(init_result, kNoSourcePosition),
4398       zone());
4399   // Traverse the array literal starting from the first spread.
4400   while (s != lit->EndValue()) {
4401     Expression* value = *s++;
4402     Spread* spread = value->AsSpread();
4403     if (spread == nullptr) {
4404       // If the element is not a spread, we're adding a single:
4405       // %AppendElement($R, value)
4406       // or, in case of a hole,
4407       // ++($R.length)
4408       if (!value->IsLiteral() ||
4409           !value->AsLiteral()->raw_value()->IsTheHole()) {
4410         ZoneList<Expression*>* append_element_args = NewExpressionList(2);
4411         append_element_args->Add(factory()->NewVariableProxy(result), zone());
4412         append_element_args->Add(value, zone());
4413         do_block->statements()->Add(
4414             factory()->NewExpressionStatement(
4415                 factory()->NewCallRuntime(Runtime::kAppendElement,
4416                                           append_element_args,
4417                                           kNoSourcePosition),
4418                 kNoSourcePosition),
4419             zone());
4420       } else {
4421         Property* length_property = factory()->NewProperty(
4422             factory()->NewVariableProxy(result),
4423             factory()->NewStringLiteral(ast_value_factory()->length_string(),
4424                                         kNoSourcePosition),
4425             kNoSourcePosition);
4426         CountOperation* count_op = factory()->NewCountOperation(
4427             Token::INC, true /* prefix */, length_property, kNoSourcePosition);
4428         do_block->statements()->Add(
4429             factory()->NewExpressionStatement(count_op, kNoSourcePosition),
4430             zone());
4431       }
4432     } else {
4433       // If it's a spread, we're adding a for/of loop iterating through it.
4434       Variable* each = NewTemporary(ast_value_factory()->dot_for_string());
4435       Expression* subject = spread->expression();
4436       // %AppendElement($R, each)
4437       Statement* append_body;
4438       {
4439         ZoneList<Expression*>* append_element_args = NewExpressionList(2);
4440         append_element_args->Add(factory()->NewVariableProxy(result), zone());
4441         append_element_args->Add(factory()->NewVariableProxy(each), zone());
4442         append_body = factory()->NewExpressionStatement(
4443             factory()->NewCallRuntime(Runtime::kAppendElement,
4444                                       append_element_args, kNoSourcePosition),
4445             kNoSourcePosition);
4446       }
4447       // for (each of spread) %AppendElement($R, each)
4448       ForEachStatement* loop = factory()->NewForEachStatement(
4449           ForEachStatement::ITERATE, nullptr, kNoSourcePosition);
4450       const bool finalize = false;
4451       InitializeForOfStatement(loop->AsForOfStatement(),
4452                                factory()->NewVariableProxy(each), subject,
4453                                append_body, finalize);
4454       do_block->statements()->Add(loop, zone());
4455     }
4456   }
4457   // Now, rewind the original array literal to truncate everything from the
4458   // first spread (included) until the end. This fixes $R's initialization.
4459   lit->RewindSpreads();
4460   return factory()->NewDoExpression(do_block, result, lit->position());
4461 }
4462 
QueueDestructuringAssignmentForRewriting(Expression * expr)4463 void Parser::QueueDestructuringAssignmentForRewriting(Expression* expr) {
4464   DCHECK(expr->IsRewritableExpression());
4465   function_state_->AddDestructuringAssignment(
4466       DestructuringAssignment(expr, scope()));
4467 }
4468 
QueueNonPatternForRewriting(Expression * expr,bool * ok)4469 void Parser::QueueNonPatternForRewriting(Expression* expr, bool* ok) {
4470   DCHECK(expr->IsRewritableExpression());
4471   function_state_->AddNonPatternForRewriting(expr, ok);
4472 }
4473 
AddAccessorPrefixToFunctionName(bool is_get,FunctionLiteral * function,const AstRawString * name)4474 void Parser::AddAccessorPrefixToFunctionName(bool is_get,
4475                                              FunctionLiteral* function,
4476                                              const AstRawString* name) {
4477   DCHECK_NOT_NULL(name);
4478   const AstRawString* prefix = is_get ? ast_value_factory()->get_space_string()
4479                                       : ast_value_factory()->set_space_string();
4480   function->set_raw_name(ast_value_factory()->NewConsString(prefix, name));
4481 }
4482 
SetFunctionNameFromPropertyName(ObjectLiteralProperty * property,const AstRawString * name)4483 void Parser::SetFunctionNameFromPropertyName(ObjectLiteralProperty* property,
4484                                              const AstRawString* name) {
4485   DCHECK(property->kind() != ObjectLiteralProperty::GETTER);
4486   DCHECK(property->kind() != ObjectLiteralProperty::SETTER);
4487 
4488   // Computed name setting must happen at runtime.
4489   DCHECK(!property->is_computed_name());
4490 
4491   // Ignore "__proto__" as a name when it's being used to set the [[Prototype]]
4492   // of an object literal.
4493   if (property->kind() == ObjectLiteralProperty::PROTOTYPE) return;
4494 
4495   Expression* value = property->value();
4496 
4497   DCHECK(!value->IsAnonymousFunctionDefinition() ||
4498          property->kind() == ObjectLiteralProperty::COMPUTED);
4499   SetFunctionName(value, name);
4500 }
4501 
SetFunctionNameFromIdentifierRef(Expression * value,Expression * identifier)4502 void Parser::SetFunctionNameFromIdentifierRef(Expression* value,
4503                                               Expression* identifier) {
4504   if (!identifier->IsVariableProxy()) return;
4505   SetFunctionName(value, identifier->AsVariableProxy()->raw_name());
4506 }
4507 
SetFunctionName(Expression * value,const AstRawString * name)4508 void Parser::SetFunctionName(Expression* value, const AstRawString* name) {
4509   DCHECK_NOT_NULL(name);
4510   if (!value->IsAnonymousFunctionDefinition()) return;
4511   auto function = value->AsFunctionLiteral();
4512   if (function != nullptr) {
4513     function->set_raw_name(name);
4514   } else {
4515     DCHECK(value->IsDoExpression());
4516     value->AsDoExpression()->represented_function()->set_raw_name(name);
4517   }
4518 }
4519 
4520 
4521 // Desugaring of yield*
4522 // ====================
4523 //
4524 // With the help of do-expressions and function.sent, we desugar yield* into a
4525 // loop containing a "raw" yield (a yield that doesn't wrap an iterator result
4526 // object around its argument).  Concretely, "yield* iterable" turns into
4527 // roughly the following code:
4528 //
4529 //   do {
4530 //     const kNext = 0;
4531 //     const kReturn = 1;
4532 //     const kThrow = 2;
4533 //
4534 //     let input = function.sent;
4535 //     let mode = kNext;
4536 //     let output = undefined;
4537 //
4538 //     let iterator = iterable[Symbol.iterator]();
4539 //     if (!IS_RECEIVER(iterator)) throw MakeTypeError(kSymbolIteratorInvalid);
4540 //
4541 //     while (true) {
4542 //       // From the generator to the iterator:
4543 //       // Forward input according to resume mode and obtain output.
4544 //       switch (mode) {
4545 //         case kNext:
4546 //           output = iterator.next(input);
4547 //           if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
4548 //           break;
4549 //         case kReturn:
4550 //           IteratorClose(iterator, input, output);  // See below.
4551 //           break;
4552 //         case kThrow:
4553 //           let iteratorThrow = iterator.throw;
4554 //           if (IS_NULL_OR_UNDEFINED(iteratorThrow)) {
4555 //             IteratorClose(iterator);  // See below.
4556 //             throw MakeTypeError(kThrowMethodMissing);
4557 //           }
4558 //           output = %_Call(iteratorThrow, iterator, input);
4559 //           if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
4560 //           break;
4561 //       }
4562 //       if (output.done) break;
4563 //
4564 //       // From the generator to its user:
4565 //       // Forward output, receive new input, and determine resume mode.
4566 //       mode = kReturn;
4567 //       try {
4568 //         try {
4569 //           RawYield(output);  // See explanation above.
4570 //           mode = kNext;
4571 //         } catch (error) {
4572 //           mode = kThrow;
4573 //         }
4574 //       } finally {
4575 //         input = function.sent;
4576 //         continue;
4577 //       }
4578 //     }
4579 //
4580 //     if (mode === kReturn) {
4581 //       return {value: output.value, done: true};
4582 //     }
4583 //     output.value
4584 //   }
4585 //
4586 // IteratorClose(iterator) expands to the following:
4587 //
4588 //   let iteratorReturn = iterator.return;
4589 //   if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) {
4590 //     let output = %_Call(iteratorReturn, iterator);
4591 //     if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
4592 //   }
4593 //
4594 // IteratorClose(iterator, input, output) expands to the following:
4595 //
4596 //   let iteratorReturn = iterator.return;
4597 //   if (IS_NULL_OR_UNDEFINED(iteratorReturn)) return input;
4598 //   output = %_Call(iteratorReturn, iterator, input);
4599 //   if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
4600 
RewriteYieldStar(Expression * generator,Expression * iterable,int pos)4601 Expression* Parser::RewriteYieldStar(Expression* generator,
4602                                      Expression* iterable, int pos) {
4603   const int nopos = kNoSourcePosition;
4604 
4605   // Forward definition for break/continue statements.
4606   WhileStatement* loop = factory()->NewWhileStatement(nullptr, nopos);
4607 
4608   // let input = undefined;
4609   Variable* var_input = NewTemporary(ast_value_factory()->empty_string());
4610   Statement* initialize_input;
4611   {
4612     Expression* input_proxy = factory()->NewVariableProxy(var_input);
4613     Expression* assignment =
4614         factory()->NewAssignment(Token::ASSIGN, input_proxy,
4615                                  factory()->NewUndefinedLiteral(nopos), nopos);
4616     initialize_input = factory()->NewExpressionStatement(assignment, nopos);
4617   }
4618 
4619   // let mode = kNext;
4620   Variable* var_mode = NewTemporary(ast_value_factory()->empty_string());
4621   Statement* initialize_mode;
4622   {
4623     Expression* mode_proxy = factory()->NewVariableProxy(var_mode);
4624     Expression* knext =
4625         factory()->NewSmiLiteral(JSGeneratorObject::kNext, nopos);
4626     Expression* assignment =
4627         factory()->NewAssignment(Token::ASSIGN, mode_proxy, knext, nopos);
4628     initialize_mode = factory()->NewExpressionStatement(assignment, nopos);
4629   }
4630 
4631   // let output = undefined;
4632   Variable* var_output = NewTemporary(ast_value_factory()->empty_string());
4633   Statement* initialize_output;
4634   {
4635     Expression* output_proxy = factory()->NewVariableProxy(var_output);
4636     Expression* assignment =
4637         factory()->NewAssignment(Token::ASSIGN, output_proxy,
4638                                  factory()->NewUndefinedLiteral(nopos), nopos);
4639     initialize_output = factory()->NewExpressionStatement(assignment, nopos);
4640   }
4641 
4642   // let iterator = iterable[Symbol.iterator];
4643   Variable* var_iterator = NewTemporary(ast_value_factory()->empty_string());
4644   Statement* get_iterator;
4645   {
4646     Expression* iterator = GetIterator(iterable, nopos);
4647     Expression* iterator_proxy = factory()->NewVariableProxy(var_iterator);
4648     Expression* assignment = factory()->NewAssignment(
4649         Token::ASSIGN, iterator_proxy, iterator, nopos);
4650     get_iterator = factory()->NewExpressionStatement(assignment, nopos);
4651   }
4652 
4653   // if (!IS_RECEIVER(iterator)) throw MakeTypeError(kSymbolIteratorInvalid);
4654   Statement* validate_iterator;
4655   {
4656     Expression* is_receiver_call;
4657     {
4658       auto args = new (zone()) ZoneList<Expression*>(1, zone());
4659       args->Add(factory()->NewVariableProxy(var_iterator), zone());
4660       is_receiver_call =
4661           factory()->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos);
4662     }
4663 
4664     Statement* throw_call;
4665     {
4666       Expression* call =
4667           NewThrowTypeError(MessageTemplate::kSymbolIteratorInvalid,
4668                             ast_value_factory()->empty_string(), nopos);
4669       throw_call = factory()->NewExpressionStatement(call, nopos);
4670     }
4671 
4672     validate_iterator = factory()->NewIfStatement(
4673         is_receiver_call, factory()->NewEmptyStatement(nopos), throw_call,
4674         nopos);
4675   }
4676 
4677   // output = iterator.next(input);
4678   Statement* call_next;
4679   {
4680     Expression* iterator_proxy = factory()->NewVariableProxy(var_iterator);
4681     Expression* literal =
4682         factory()->NewStringLiteral(ast_value_factory()->next_string(), nopos);
4683     Expression* next_property =
4684         factory()->NewProperty(iterator_proxy, literal, nopos);
4685     Expression* input_proxy = factory()->NewVariableProxy(var_input);
4686     auto args = new (zone()) ZoneList<Expression*>(1, zone());
4687     args->Add(input_proxy, zone());
4688     Expression* call = factory()->NewCall(next_property, args, nopos);
4689     Expression* output_proxy = factory()->NewVariableProxy(var_output);
4690     Expression* assignment =
4691         factory()->NewAssignment(Token::ASSIGN, output_proxy, call, nopos);
4692     call_next = factory()->NewExpressionStatement(assignment, nopos);
4693   }
4694 
4695   // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
4696   Statement* validate_next_output;
4697   {
4698     Expression* is_receiver_call;
4699     {
4700       auto args = new (zone()) ZoneList<Expression*>(1, zone());
4701       args->Add(factory()->NewVariableProxy(var_output), zone());
4702       is_receiver_call =
4703           factory()->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos);
4704     }
4705 
4706     Statement* throw_call;
4707     {
4708       auto args = new (zone()) ZoneList<Expression*>(1, zone());
4709       args->Add(factory()->NewVariableProxy(var_output), zone());
4710       Expression* call = factory()->NewCallRuntime(
4711           Runtime::kThrowIteratorResultNotAnObject, args, nopos);
4712       throw_call = factory()->NewExpressionStatement(call, nopos);
4713     }
4714 
4715     validate_next_output = factory()->NewIfStatement(
4716         is_receiver_call, factory()->NewEmptyStatement(nopos), throw_call,
4717         nopos);
4718   }
4719 
4720   // let iteratorThrow = iterator.throw;
4721   Variable* var_throw = NewTemporary(ast_value_factory()->empty_string());
4722   Statement* get_throw;
4723   {
4724     Expression* iterator_proxy = factory()->NewVariableProxy(var_iterator);
4725     Expression* literal =
4726         factory()->NewStringLiteral(ast_value_factory()->throw_string(), nopos);
4727     Expression* property =
4728         factory()->NewProperty(iterator_proxy, literal, nopos);
4729     Expression* throw_proxy = factory()->NewVariableProxy(var_throw);
4730     Expression* assignment =
4731         factory()->NewAssignment(Token::ASSIGN, throw_proxy, property, nopos);
4732     get_throw = factory()->NewExpressionStatement(assignment, nopos);
4733   }
4734 
4735   // if (IS_NULL_OR_UNDEFINED(iteratorThrow) {
4736   //   IteratorClose(iterator);
4737   //   throw MakeTypeError(kThrowMethodMissing);
4738   // }
4739   Statement* check_throw;
4740   {
4741     Expression* condition = factory()->NewCompareOperation(
4742         Token::EQ, factory()->NewVariableProxy(var_throw),
4743         factory()->NewNullLiteral(nopos), nopos);
4744     Expression* call =
4745         NewThrowTypeError(MessageTemplate::kThrowMethodMissing,
4746                           ast_value_factory()->empty_string(), nopos);
4747     Statement* throw_call = factory()->NewExpressionStatement(call, nopos);
4748 
4749     Block* then = factory()->NewBlock(nullptr, 4 + 1, false, nopos);
4750     BuildIteratorCloseForCompletion(
4751         scope(), then->statements(), var_iterator,
4752         factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos));
4753     then->statements()->Add(throw_call, zone());
4754     check_throw = factory()->NewIfStatement(
4755         condition, then, factory()->NewEmptyStatement(nopos), nopos);
4756   }
4757 
4758   // output = %_Call(iteratorThrow, iterator, input);
4759   Statement* call_throw;
4760   {
4761     auto args = new (zone()) ZoneList<Expression*>(3, zone());
4762     args->Add(factory()->NewVariableProxy(var_throw), zone());
4763     args->Add(factory()->NewVariableProxy(var_iterator), zone());
4764     args->Add(factory()->NewVariableProxy(var_input), zone());
4765     Expression* call =
4766         factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos);
4767     Expression* assignment = factory()->NewAssignment(
4768         Token::ASSIGN, factory()->NewVariableProxy(var_output), call, nopos);
4769     call_throw = factory()->NewExpressionStatement(assignment, nopos);
4770   }
4771 
4772   // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
4773   Statement* validate_throw_output;
4774   {
4775     Expression* is_receiver_call;
4776     {
4777       auto args = new (zone()) ZoneList<Expression*>(1, zone());
4778       args->Add(factory()->NewVariableProxy(var_output), zone());
4779       is_receiver_call =
4780           factory()->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos);
4781     }
4782 
4783     Statement* throw_call;
4784     {
4785       auto args = new (zone()) ZoneList<Expression*>(1, zone());
4786       args->Add(factory()->NewVariableProxy(var_output), zone());
4787       Expression* call = factory()->NewCallRuntime(
4788           Runtime::kThrowIteratorResultNotAnObject, args, nopos);
4789       throw_call = factory()->NewExpressionStatement(call, nopos);
4790     }
4791 
4792     validate_throw_output = factory()->NewIfStatement(
4793         is_receiver_call, factory()->NewEmptyStatement(nopos), throw_call,
4794         nopos);
4795   }
4796 
4797   // if (output.done) break;
4798   Statement* if_done;
4799   {
4800     Expression* output_proxy = factory()->NewVariableProxy(var_output);
4801     Expression* literal =
4802         factory()->NewStringLiteral(ast_value_factory()->done_string(), nopos);
4803     Expression* property = factory()->NewProperty(output_proxy, literal, nopos);
4804     BreakStatement* break_loop = factory()->NewBreakStatement(loop, nopos);
4805     if_done = factory()->NewIfStatement(
4806         property, break_loop, factory()->NewEmptyStatement(nopos), nopos);
4807   }
4808 
4809 
4810   // mode = kReturn;
4811   Statement* set_mode_return;
4812   {
4813     Expression* mode_proxy = factory()->NewVariableProxy(var_mode);
4814     Expression* kreturn =
4815         factory()->NewSmiLiteral(JSGeneratorObject::kReturn, nopos);
4816     Expression* assignment =
4817         factory()->NewAssignment(Token::ASSIGN, mode_proxy, kreturn, nopos);
4818     set_mode_return = factory()->NewExpressionStatement(assignment, nopos);
4819   }
4820 
4821   // Yield(output);
4822   Statement* yield_output;
4823   {
4824     Expression* output_proxy = factory()->NewVariableProxy(var_output);
4825     Yield* yield = factory()->NewYield(generator, output_proxy, nopos,
4826                                        Yield::kOnExceptionThrow);
4827     yield_output = factory()->NewExpressionStatement(yield, nopos);
4828   }
4829 
4830   // mode = kNext;
4831   Statement* set_mode_next;
4832   {
4833     Expression* mode_proxy = factory()->NewVariableProxy(var_mode);
4834     Expression* knext =
4835         factory()->NewSmiLiteral(JSGeneratorObject::kNext, nopos);
4836     Expression* assignment =
4837         factory()->NewAssignment(Token::ASSIGN, mode_proxy, knext, nopos);
4838     set_mode_next = factory()->NewExpressionStatement(assignment, nopos);
4839   }
4840 
4841   // mode = kThrow;
4842   Statement* set_mode_throw;
4843   {
4844     Expression* mode_proxy = factory()->NewVariableProxy(var_mode);
4845     Expression* kthrow =
4846         factory()->NewSmiLiteral(JSGeneratorObject::kThrow, nopos);
4847     Expression* assignment =
4848         factory()->NewAssignment(Token::ASSIGN, mode_proxy, kthrow, nopos);
4849     set_mode_throw = factory()->NewExpressionStatement(assignment, nopos);
4850   }
4851 
4852   // input = function.sent;
4853   Statement* get_input;
4854   {
4855     Expression* function_sent = FunctionSentExpression(nopos);
4856     Expression* input_proxy = factory()->NewVariableProxy(var_input);
4857     Expression* assignment = factory()->NewAssignment(
4858         Token::ASSIGN, input_proxy, function_sent, nopos);
4859     get_input = factory()->NewExpressionStatement(assignment, nopos);
4860   }
4861 
4862   // if (mode === kReturn) {
4863   //   return {value: output.value, done: true};
4864   // }
4865   Statement* maybe_return_value;
4866   {
4867     Expression* mode_proxy = factory()->NewVariableProxy(var_mode);
4868     Expression* kreturn =
4869         factory()->NewSmiLiteral(JSGeneratorObject::kReturn, nopos);
4870     Expression* condition = factory()->NewCompareOperation(
4871         Token::EQ_STRICT, mode_proxy, kreturn, nopos);
4872 
4873     Expression* output_proxy = factory()->NewVariableProxy(var_output);
4874     Expression* literal =
4875         factory()->NewStringLiteral(ast_value_factory()->value_string(), nopos);
4876     Expression* property = factory()->NewProperty(output_proxy, literal, nopos);
4877     Statement* return_value = factory()->NewReturnStatement(
4878         BuildIteratorResult(property, true), nopos);
4879 
4880     maybe_return_value = factory()->NewIfStatement(
4881         condition, return_value, factory()->NewEmptyStatement(nopos), nopos);
4882   }
4883 
4884   // output.value
4885   Statement* get_value;
4886   {
4887     Expression* output_proxy = factory()->NewVariableProxy(var_output);
4888     Expression* literal =
4889         factory()->NewStringLiteral(ast_value_factory()->value_string(), nopos);
4890     Expression* property = factory()->NewProperty(output_proxy, literal, nopos);
4891     get_value = factory()->NewExpressionStatement(property, nopos);
4892   }
4893 
4894   // Now put things together.
4895 
4896   // try { ... } catch(e) { ... }
4897   Statement* try_catch;
4898   {
4899     Block* try_block = factory()->NewBlock(nullptr, 2, false, nopos);
4900     try_block->statements()->Add(yield_output, zone());
4901     try_block->statements()->Add(set_mode_next, zone());
4902 
4903     Block* catch_block = factory()->NewBlock(nullptr, 1, false, nopos);
4904     catch_block->statements()->Add(set_mode_throw, zone());
4905 
4906     Scope* catch_scope = NewScope(CATCH_SCOPE);
4907     catch_scope->set_is_hidden();
4908     const AstRawString* name = ast_value_factory()->dot_catch_string();
4909     Variable* catch_variable = catch_scope->DeclareLocal(
4910         name, VAR, kCreatedInitialized, NORMAL_VARIABLE);
4911 
4912     try_catch = factory()->NewTryCatchStatementForDesugaring(
4913         try_block, catch_scope, catch_variable, catch_block, nopos);
4914   }
4915 
4916   // try { ... } finally { ... }
4917   Statement* try_finally;
4918   {
4919     Block* try_block = factory()->NewBlock(nullptr, 1, false, nopos);
4920     try_block->statements()->Add(try_catch, zone());
4921 
4922     Block* finally = factory()->NewBlock(nullptr, 2, false, nopos);
4923     finally->statements()->Add(get_input, zone());
4924     finally->statements()->Add(factory()->NewContinueStatement(loop, nopos),
4925                                zone());
4926 
4927     try_finally = factory()->NewTryFinallyStatement(try_block, finally, nopos);
4928   }
4929 
4930   // switch (mode) { ... }
4931   SwitchStatement* switch_mode = factory()->NewSwitchStatement(nullptr, nopos);
4932   {
4933     auto case_next = new (zone()) ZoneList<Statement*>(3, zone());
4934     case_next->Add(call_next, zone());
4935     case_next->Add(validate_next_output, zone());
4936     case_next->Add(factory()->NewBreakStatement(switch_mode, nopos), zone());
4937 
4938     auto case_return = new (zone()) ZoneList<Statement*>(5, zone());
4939     BuildIteratorClose(case_return, var_iterator, var_input, var_output);
4940     case_return->Add(factory()->NewBreakStatement(switch_mode, nopos), zone());
4941 
4942     auto case_throw = new (zone()) ZoneList<Statement*>(5, zone());
4943     case_throw->Add(get_throw, zone());
4944     case_throw->Add(check_throw, zone());
4945     case_throw->Add(call_throw, zone());
4946     case_throw->Add(validate_throw_output, zone());
4947     case_throw->Add(factory()->NewBreakStatement(switch_mode, nopos), zone());
4948 
4949     auto cases = new (zone()) ZoneList<CaseClause*>(3, zone());
4950     Expression* knext =
4951         factory()->NewSmiLiteral(JSGeneratorObject::kNext, nopos);
4952     Expression* kreturn =
4953         factory()->NewSmiLiteral(JSGeneratorObject::kReturn, nopos);
4954     Expression* kthrow =
4955         factory()->NewSmiLiteral(JSGeneratorObject::kThrow, nopos);
4956     cases->Add(factory()->NewCaseClause(knext, case_next, nopos), zone());
4957     cases->Add(factory()->NewCaseClause(kreturn, case_return, nopos), zone());
4958     cases->Add(factory()->NewCaseClause(kthrow, case_throw, nopos), zone());
4959 
4960     switch_mode->Initialize(factory()->NewVariableProxy(var_mode), cases);
4961   }
4962 
4963   // while (true) { ... }
4964   // Already defined earlier: WhileStatement* loop = ...
4965   {
4966     Block* loop_body = factory()->NewBlock(nullptr, 4, false, nopos);
4967     loop_body->statements()->Add(switch_mode, zone());
4968     loop_body->statements()->Add(if_done, zone());
4969     loop_body->statements()->Add(set_mode_return, zone());
4970     loop_body->statements()->Add(try_finally, zone());
4971 
4972     loop->Initialize(factory()->NewBooleanLiteral(true, nopos), loop_body);
4973   }
4974 
4975   // do { ... }
4976   DoExpression* yield_star;
4977   {
4978     // The rewriter needs to process the get_value statement only, hence we
4979     // put the preceding statements into an init block.
4980 
4981     Block* do_block_ = factory()->NewBlock(nullptr, 7, true, nopos);
4982     do_block_->statements()->Add(initialize_input, zone());
4983     do_block_->statements()->Add(initialize_mode, zone());
4984     do_block_->statements()->Add(initialize_output, zone());
4985     do_block_->statements()->Add(get_iterator, zone());
4986     do_block_->statements()->Add(validate_iterator, zone());
4987     do_block_->statements()->Add(loop, zone());
4988     do_block_->statements()->Add(maybe_return_value, zone());
4989 
4990     Block* do_block = factory()->NewBlock(nullptr, 2, false, nopos);
4991     do_block->statements()->Add(do_block_, zone());
4992     do_block->statements()->Add(get_value, zone());
4993 
4994     Variable* dot_result =
4995         NewTemporary(ast_value_factory()->dot_result_string());
4996     yield_star = factory()->NewDoExpression(do_block, dot_result, nopos);
4997     Rewriter::Rewrite(this, GetClosureScope(), yield_star, ast_value_factory());
4998   }
4999 
5000   return yield_star;
5001 }
5002 
CheckCallable(Variable * var,Expression * error,int pos)5003 Statement* Parser::CheckCallable(Variable* var, Expression* error, int pos) {
5004   const int nopos = kNoSourcePosition;
5005   Statement* validate_var;
5006   {
5007     Expression* type_of = factory()->NewUnaryOperation(
5008         Token::TYPEOF, factory()->NewVariableProxy(var), nopos);
5009     Expression* function_literal = factory()->NewStringLiteral(
5010         ast_value_factory()->function_string(), nopos);
5011     Expression* condition = factory()->NewCompareOperation(
5012         Token::EQ_STRICT, type_of, function_literal, nopos);
5013 
5014     Statement* throw_call = factory()->NewExpressionStatement(error, pos);
5015 
5016     validate_var = factory()->NewIfStatement(
5017         condition, factory()->NewEmptyStatement(nopos), throw_call, nopos);
5018   }
5019   return validate_var;
5020 }
5021 
BuildIteratorClose(ZoneList<Statement * > * statements,Variable * iterator,Variable * input,Variable * var_output)5022 void Parser::BuildIteratorClose(ZoneList<Statement*>* statements,
5023                                 Variable* iterator, Variable* input,
5024                                 Variable* var_output) {
5025   //
5026   // This function adds four statements to [statements], corresponding to the
5027   // following code:
5028   //
5029   //   let iteratorReturn = iterator.return;
5030   //   if (IS_NULL_OR_UNDEFINED(iteratorReturn) {
5031   //     return {value: input, done: true};
5032   //   }
5033   //   output = %_Call(iteratorReturn, iterator, input);
5034   //   if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
5035   //
5036 
5037   const int nopos = kNoSourcePosition;
5038 
5039   // let iteratorReturn = iterator.return;
5040   Variable* var_return = var_output;  // Reusing the output variable.
5041   Statement* get_return;
5042   {
5043     Expression* iterator_proxy = factory()->NewVariableProxy(iterator);
5044     Expression* literal = factory()->NewStringLiteral(
5045         ast_value_factory()->return_string(), nopos);
5046     Expression* property =
5047         factory()->NewProperty(iterator_proxy, literal, nopos);
5048     Expression* return_proxy = factory()->NewVariableProxy(var_return);
5049     Expression* assignment =
5050         factory()->NewAssignment(Token::ASSIGN, return_proxy, property, nopos);
5051     get_return = factory()->NewExpressionStatement(assignment, nopos);
5052   }
5053 
5054   // if (IS_NULL_OR_UNDEFINED(iteratorReturn) {
5055   //   return {value: input, done: true};
5056   // }
5057   Statement* check_return;
5058   {
5059     Expression* condition = factory()->NewCompareOperation(
5060         Token::EQ, factory()->NewVariableProxy(var_return),
5061         factory()->NewNullLiteral(nopos), nopos);
5062 
5063     Expression* value = factory()->NewVariableProxy(input);
5064 
5065     Statement* return_input =
5066         factory()->NewReturnStatement(BuildIteratorResult(value, true), nopos);
5067 
5068     check_return = factory()->NewIfStatement(
5069         condition, return_input, factory()->NewEmptyStatement(nopos), nopos);
5070   }
5071 
5072   // output = %_Call(iteratorReturn, iterator, input);
5073   Statement* call_return;
5074   {
5075     auto args = new (zone()) ZoneList<Expression*>(3, zone());
5076     args->Add(factory()->NewVariableProxy(var_return), zone());
5077     args->Add(factory()->NewVariableProxy(iterator), zone());
5078     args->Add(factory()->NewVariableProxy(input), zone());
5079 
5080     Expression* call =
5081         factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos);
5082     Expression* output_proxy = factory()->NewVariableProxy(var_output);
5083     Expression* assignment =
5084         factory()->NewAssignment(Token::ASSIGN, output_proxy, call, nopos);
5085     call_return = factory()->NewExpressionStatement(assignment, nopos);
5086   }
5087 
5088   // if (!IS_RECEIVER(output)) %ThrowIteratorResultNotAnObject(output);
5089   Statement* validate_output;
5090   {
5091     Expression* is_receiver_call;
5092     {
5093       auto args = new (zone()) ZoneList<Expression*>(1, zone());
5094       args->Add(factory()->NewVariableProxy(var_output), zone());
5095       is_receiver_call =
5096           factory()->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos);
5097     }
5098 
5099     Statement* throw_call;
5100     {
5101       auto args = new (zone()) ZoneList<Expression*>(1, zone());
5102       args->Add(factory()->NewVariableProxy(var_output), zone());
5103       Expression* call = factory()->NewCallRuntime(
5104           Runtime::kThrowIteratorResultNotAnObject, args, nopos);
5105       throw_call = factory()->NewExpressionStatement(call, nopos);
5106     }
5107 
5108     validate_output = factory()->NewIfStatement(
5109         is_receiver_call, factory()->NewEmptyStatement(nopos), throw_call,
5110         nopos);
5111   }
5112 
5113   statements->Add(get_return, zone());
5114   statements->Add(check_return, zone());
5115   statements->Add(call_return, zone());
5116   statements->Add(validate_output, zone());
5117 }
5118 
FinalizeIteratorUse(Scope * use_scope,Variable * completion,Expression * condition,Variable * iter,Block * iterator_use,Block * target)5119 void Parser::FinalizeIteratorUse(Scope* use_scope, Variable* completion,
5120                                  Expression* condition, Variable* iter,
5121                                  Block* iterator_use, Block* target) {
5122   //
5123   // This function adds two statements to [target], corresponding to the
5124   // following code:
5125   //
5126   //   completion = kNormalCompletion;
5127   //   try {
5128   //     try {
5129   //       iterator_use
5130   //     } catch(e) {
5131   //       if (completion === kAbruptCompletion) completion = kThrowCompletion;
5132   //       %ReThrow(e);
5133   //     }
5134   //   } finally {
5135   //     if (condition) {
5136   //       #BuildIteratorCloseForCompletion(iter, completion)
5137   //     }
5138   //   }
5139   //
5140 
5141   const int nopos = kNoSourcePosition;
5142 
5143   // completion = kNormalCompletion;
5144   Statement* initialize_completion;
5145   {
5146     Expression* proxy = factory()->NewVariableProxy(completion);
5147     Expression* assignment = factory()->NewAssignment(
5148         Token::ASSIGN, proxy,
5149         factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos);
5150     initialize_completion =
5151         factory()->NewExpressionStatement(assignment, nopos);
5152   }
5153 
5154   // if (completion === kAbruptCompletion) completion = kThrowCompletion;
5155   Statement* set_completion_throw;
5156   {
5157     Expression* condition = factory()->NewCompareOperation(
5158         Token::EQ_STRICT, factory()->NewVariableProxy(completion),
5159         factory()->NewSmiLiteral(Parser::kAbruptCompletion, nopos), nopos);
5160 
5161     Expression* proxy = factory()->NewVariableProxy(completion);
5162     Expression* assignment = factory()->NewAssignment(
5163         Token::ASSIGN, proxy,
5164         factory()->NewSmiLiteral(Parser::kThrowCompletion, nopos), nopos);
5165     Statement* statement = factory()->NewExpressionStatement(assignment, nopos);
5166     set_completion_throw = factory()->NewIfStatement(
5167         condition, statement, factory()->NewEmptyStatement(nopos), nopos);
5168   }
5169 
5170   // if (condition) {
5171   //   #BuildIteratorCloseForCompletion(iter, completion)
5172   // }
5173   Block* maybe_close;
5174   {
5175     Block* block = factory()->NewBlock(nullptr, 2, true, nopos);
5176     Expression* proxy = factory()->NewVariableProxy(completion);
5177     BuildIteratorCloseForCompletion(use_scope, block->statements(), iter,
5178                                     proxy);
5179     DCHECK(block->statements()->length() == 2);
5180 
5181     maybe_close = factory()->NewBlock(nullptr, 1, true, nopos);
5182     maybe_close->statements()->Add(
5183         factory()->NewIfStatement(condition, block,
5184                                   factory()->NewEmptyStatement(nopos), nopos),
5185         zone());
5186   }
5187 
5188   // try { #try_block }
5189   // catch(e) {
5190   //   #set_completion_throw;
5191   //   %ReThrow(e);
5192   // }
5193   Statement* try_catch;
5194   {
5195     Scope* catch_scope = NewScopeWithParent(use_scope, CATCH_SCOPE);
5196     Variable* catch_variable =
5197         catch_scope->DeclareLocal(ast_value_factory()->dot_catch_string(), VAR,
5198                                   kCreatedInitialized, NORMAL_VARIABLE);
5199     catch_scope->set_is_hidden();
5200 
5201     Statement* rethrow;
5202     // We use %ReThrow rather than the ordinary throw because we want to
5203     // preserve the original exception message.  This is also why we create a
5204     // TryCatchStatementForReThrow below (which does not clear the pending
5205     // message), rather than a TryCatchStatement.
5206     {
5207       auto args = new (zone()) ZoneList<Expression*>(1, zone());
5208       args->Add(factory()->NewVariableProxy(catch_variable), zone());
5209       rethrow = factory()->NewExpressionStatement(
5210           factory()->NewCallRuntime(Runtime::kReThrow, args, nopos), nopos);
5211     }
5212 
5213     Block* catch_block = factory()->NewBlock(nullptr, 2, false, nopos);
5214     catch_block->statements()->Add(set_completion_throw, zone());
5215     catch_block->statements()->Add(rethrow, zone());
5216 
5217     try_catch = factory()->NewTryCatchStatementForReThrow(
5218         iterator_use, catch_scope, catch_variable, catch_block, nopos);
5219   }
5220 
5221   // try { #try_catch } finally { #maybe_close }
5222   Statement* try_finally;
5223   {
5224     Block* try_block = factory()->NewBlock(nullptr, 1, false, nopos);
5225     try_block->statements()->Add(try_catch, zone());
5226 
5227     try_finally =
5228         factory()->NewTryFinallyStatement(try_block, maybe_close, nopos);
5229   }
5230 
5231   target->statements()->Add(initialize_completion, zone());
5232   target->statements()->Add(try_finally, zone());
5233 }
5234 
BuildIteratorCloseForCompletion(Scope * scope,ZoneList<Statement * > * statements,Variable * iterator,Expression * completion)5235 void Parser::BuildIteratorCloseForCompletion(Scope* scope,
5236                                              ZoneList<Statement*>* statements,
5237                                              Variable* iterator,
5238                                              Expression* completion) {
5239   //
5240   // This function adds two statements to [statements], corresponding to the
5241   // following code:
5242   //
5243   //   let iteratorReturn = iterator.return;
5244   //   if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) {
5245   //     if (completion === kThrowCompletion) {
5246   //       if (!IS_CALLABLE(iteratorReturn)) {
5247   //         throw MakeTypeError(kReturnMethodNotCallable);
5248   //       }
5249   //       try { %_Call(iteratorReturn, iterator) } catch (_) { }
5250   //     } else {
5251   //       let output = %_Call(iteratorReturn, iterator);
5252   //       if (!IS_RECEIVER(output)) {
5253   //         %ThrowIterResultNotAnObject(output);
5254   //       }
5255   //     }
5256   //   }
5257   //
5258 
5259   const int nopos = kNoSourcePosition;
5260   // let iteratorReturn = iterator.return;
5261   Variable* var_return = NewTemporary(ast_value_factory()->empty_string());
5262   Statement* get_return;
5263   {
5264     Expression* iterator_proxy = factory()->NewVariableProxy(iterator);
5265     Expression* literal = factory()->NewStringLiteral(
5266         ast_value_factory()->return_string(), nopos);
5267     Expression* property =
5268         factory()->NewProperty(iterator_proxy, literal, nopos);
5269     Expression* return_proxy = factory()->NewVariableProxy(var_return);
5270     Expression* assignment =
5271         factory()->NewAssignment(Token::ASSIGN, return_proxy, property, nopos);
5272     get_return = factory()->NewExpressionStatement(assignment, nopos);
5273   }
5274 
5275   // if (!IS_CALLABLE(iteratorReturn)) {
5276   //   throw MakeTypeError(kReturnMethodNotCallable);
5277   // }
5278   Statement* check_return_callable;
5279   {
5280     Expression* throw_expr =
5281         NewThrowTypeError(MessageTemplate::kReturnMethodNotCallable,
5282                           ast_value_factory()->empty_string(), nopos);
5283     check_return_callable = CheckCallable(var_return, throw_expr, nopos);
5284   }
5285 
5286   // try { %_Call(iteratorReturn, iterator) } catch (_) { }
5287   Statement* try_call_return;
5288   {
5289     auto args = new (zone()) ZoneList<Expression*>(2, zone());
5290     args->Add(factory()->NewVariableProxy(var_return), zone());
5291     args->Add(factory()->NewVariableProxy(iterator), zone());
5292 
5293     Expression* call =
5294         factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos);
5295 
5296     Block* try_block = factory()->NewBlock(nullptr, 1, false, nopos);
5297     try_block->statements()->Add(factory()->NewExpressionStatement(call, nopos),
5298                                  zone());
5299 
5300     Block* catch_block = factory()->NewBlock(nullptr, 0, false, nopos);
5301 
5302     Scope* catch_scope = NewScopeWithParent(scope, CATCH_SCOPE);
5303     Variable* catch_variable =
5304         catch_scope->DeclareLocal(ast_value_factory()->dot_catch_string(), VAR,
5305                                   kCreatedInitialized, NORMAL_VARIABLE);
5306     catch_scope->set_is_hidden();
5307 
5308     try_call_return = factory()->NewTryCatchStatement(
5309         try_block, catch_scope, catch_variable, catch_block, nopos);
5310   }
5311 
5312   // let output = %_Call(iteratorReturn, iterator);
5313   // if (!IS_RECEIVER(output)) {
5314   //   %ThrowIteratorResultNotAnObject(output);
5315   // }
5316   Block* validate_return;
5317   {
5318     Variable* var_output = NewTemporary(ast_value_factory()->empty_string());
5319     Statement* call_return;
5320     {
5321       auto args = new (zone()) ZoneList<Expression*>(2, zone());
5322       args->Add(factory()->NewVariableProxy(var_return), zone());
5323       args->Add(factory()->NewVariableProxy(iterator), zone());
5324       Expression* call =
5325           factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos);
5326 
5327       Expression* output_proxy = factory()->NewVariableProxy(var_output);
5328       Expression* assignment =
5329           factory()->NewAssignment(Token::ASSIGN, output_proxy, call, nopos);
5330       call_return = factory()->NewExpressionStatement(assignment, nopos);
5331     }
5332 
5333     Expression* is_receiver_call;
5334     {
5335       auto args = new (zone()) ZoneList<Expression*>(1, zone());
5336       args->Add(factory()->NewVariableProxy(var_output), zone());
5337       is_receiver_call =
5338           factory()->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos);
5339     }
5340 
5341     Statement* throw_call;
5342     {
5343       auto args = new (zone()) ZoneList<Expression*>(1, zone());
5344       args->Add(factory()->NewVariableProxy(var_output), zone());
5345       Expression* call = factory()->NewCallRuntime(
5346           Runtime::kThrowIteratorResultNotAnObject, args, nopos);
5347       throw_call = factory()->NewExpressionStatement(call, nopos);
5348     }
5349 
5350     Statement* check_return = factory()->NewIfStatement(
5351         is_receiver_call, factory()->NewEmptyStatement(nopos), throw_call,
5352         nopos);
5353 
5354     validate_return = factory()->NewBlock(nullptr, 2, false, nopos);
5355     validate_return->statements()->Add(call_return, zone());
5356     validate_return->statements()->Add(check_return, zone());
5357   }
5358 
5359   // if (completion === kThrowCompletion) {
5360   //   #check_return_callable;
5361   //   #try_call_return;
5362   // } else {
5363   //   #validate_return;
5364   // }
5365   Statement* call_return_carefully;
5366   {
5367     Expression* condition = factory()->NewCompareOperation(
5368         Token::EQ_STRICT, completion,
5369         factory()->NewSmiLiteral(Parser::kThrowCompletion, nopos), nopos);
5370 
5371     Block* then_block = factory()->NewBlock(nullptr, 2, false, nopos);
5372     then_block->statements()->Add(check_return_callable, zone());
5373     then_block->statements()->Add(try_call_return, zone());
5374 
5375     call_return_carefully = factory()->NewIfStatement(condition, then_block,
5376                                                       validate_return, nopos);
5377   }
5378 
5379   // if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) { ... }
5380   Statement* maybe_call_return;
5381   {
5382     Expression* condition = factory()->NewCompareOperation(
5383         Token::EQ, factory()->NewVariableProxy(var_return),
5384         factory()->NewNullLiteral(nopos), nopos);
5385 
5386     maybe_call_return = factory()->NewIfStatement(
5387         condition, factory()->NewEmptyStatement(nopos), call_return_carefully,
5388         nopos);
5389   }
5390 
5391   statements->Add(get_return, zone());
5392   statements->Add(maybe_call_return, zone());
5393 }
5394 
FinalizeForOfStatement(ForOfStatement * loop,Variable * var_completion,int pos)5395 Statement* Parser::FinalizeForOfStatement(ForOfStatement* loop,
5396                                           Variable* var_completion, int pos) {
5397   //
5398   // This function replaces the loop with the following wrapping:
5399   //
5400   //   completion = kNormalCompletion;
5401   //   try {
5402   //     try {
5403   //       #loop;
5404   //     } catch(e) {
5405   //       if (completion === kAbruptCompletion) completion = kThrowCompletion;
5406   //       %ReThrow(e);
5407   //     }
5408   //   } finally {
5409   //     if (!(completion === kNormalCompletion || IS_UNDEFINED(#iterator))) {
5410   //       #BuildIteratorCloseForCompletion(#iterator, completion)
5411   //     }
5412   //   }
5413   //
5414   // Note that the loop's body and its assign_each already contain appropriate
5415   // assignments to completion (see InitializeForOfStatement).
5416   //
5417 
5418   const int nopos = kNoSourcePosition;
5419 
5420   // !(completion === kNormalCompletion || IS_UNDEFINED(#iterator))
5421   Expression* closing_condition;
5422   {
5423     Expression* lhs = factory()->NewCompareOperation(
5424         Token::EQ_STRICT, factory()->NewVariableProxy(var_completion),
5425         factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos);
5426     Expression* rhs = factory()->NewCompareOperation(
5427         Token::EQ_STRICT, factory()->NewVariableProxy(loop->iterator()),
5428         factory()->NewUndefinedLiteral(nopos), nopos);
5429     closing_condition = factory()->NewUnaryOperation(
5430         Token::NOT, factory()->NewBinaryOperation(Token::OR, lhs, rhs, nopos),
5431         nopos);
5432   }
5433 
5434   Block* final_loop = factory()->NewBlock(nullptr, 2, false, nopos);
5435   {
5436     Block* try_block = factory()->NewBlock(nullptr, 1, false, nopos);
5437     try_block->statements()->Add(loop, zone());
5438 
5439     // The scope in which the parser creates this loop.
5440     Scope* loop_scope = scope()->outer_scope();
5441     DCHECK_EQ(loop_scope->scope_type(), BLOCK_SCOPE);
5442     DCHECK_EQ(scope()->scope_type(), BLOCK_SCOPE);
5443 
5444     FinalizeIteratorUse(loop_scope, var_completion, closing_condition,
5445                         loop->iterator(), try_block, final_loop);
5446   }
5447 
5448   return final_loop;
5449 }
5450 
5451 #undef CHECK_OK
5452 #undef CHECK_OK_VOID
5453 #undef CHECK_FAILED
5454 
5455 }  // namespace internal
5456 }  // namespace v8
5457