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 <algorithm>
8 #include <memory>
9 
10 #include "src/api.h"
11 #include "src/ast/ast-function-literal-id-reindexer.h"
12 #include "src/ast/ast-traversal-visitor.h"
13 #include "src/ast/ast.h"
14 #include "src/ast/source-range-ast-visitor.h"
15 #include "src/bailout-reason.h"
16 #include "src/base/platform/platform.h"
17 #include "src/char-predicates-inl.h"
18 #include "src/compiler-dispatcher/compiler-dispatcher.h"
19 #include "src/log.h"
20 #include "src/messages.h"
21 #include "src/objects-inl.h"
22 #include "src/parsing/duplicate-finder.h"
23 #include "src/parsing/expression-scope-reparenter.h"
24 #include "src/parsing/parse-info.h"
25 #include "src/parsing/rewriter.h"
26 #include "src/runtime/runtime.h"
27 #include "src/string-stream.h"
28 #include "src/tracing/trace-event.h"
29 
30 namespace v8 {
31 namespace internal {
32 
33 
34 
35 // Helper for putting parts of the parse results into a temporary zone when
36 // parsing inner function bodies.
37 class DiscardableZoneScope {
38  public:
DiscardableZoneScope(Parser * parser,Zone * temp_zone,bool use_temp_zone)39   DiscardableZoneScope(Parser* parser, Zone* temp_zone, bool use_temp_zone)
40       : fni_(parser->ast_value_factory_, temp_zone),
41         parser_(parser),
42         prev_fni_(parser->fni_),
43         prev_zone_(parser->zone_),
44         prev_allow_lazy_(parser->allow_lazy_),
45         prev_temp_zoned_(parser->temp_zoned_) {
46     if (use_temp_zone) {
47       DCHECK(!parser_->temp_zoned_);
48       parser_->allow_lazy_ = false;
49       parser_->temp_zoned_ = true;
50       parser_->fni_ = &fni_;
51       parser_->zone_ = temp_zone;
52       parser_->factory()->set_zone(temp_zone);
53       if (parser_->reusable_preparser_ != nullptr) {
54         parser_->reusable_preparser_->zone_ = temp_zone;
55         parser_->reusable_preparser_->factory()->set_zone(temp_zone);
56       }
57     }
58   }
Reset()59   void Reset() {
60     parser_->fni_ = prev_fni_;
61     parser_->zone_ = prev_zone_;
62     parser_->factory()->set_zone(prev_zone_);
63     parser_->allow_lazy_ = prev_allow_lazy_;
64     parser_->temp_zoned_ = prev_temp_zoned_;
65     if (parser_->reusable_preparser_ != nullptr) {
66       parser_->reusable_preparser_->zone_ = prev_zone_;
67       parser_->reusable_preparser_->factory()->set_zone(prev_zone_);
68     }
69   }
~DiscardableZoneScope()70   ~DiscardableZoneScope() { Reset(); }
71 
72  private:
73   FuncNameInferrer fni_;
74   Parser* parser_;
75   FuncNameInferrer* prev_fni_;
76   Zone* prev_zone_;
77   bool prev_allow_lazy_;
78   bool prev_temp_zoned_;
79 
80   DISALLOW_COPY_AND_ASSIGN(DiscardableZoneScope);
81 };
82 
DefaultConstructor(const AstRawString * name,bool call_super,int pos,int end_pos)83 FunctionLiteral* Parser::DefaultConstructor(const AstRawString* name,
84                                             bool call_super, int pos,
85                                             int end_pos) {
86   int expected_property_count = -1;
87   const int parameter_count = 0;
88 
89   FunctionKind kind = call_super ? FunctionKind::kDefaultDerivedConstructor
90                                  : FunctionKind::kDefaultBaseConstructor;
91   DeclarationScope* function_scope = NewFunctionScope(kind);
92   SetLanguageMode(function_scope, LanguageMode::kStrict);
93   // Set start and end position to the same value
94   function_scope->set_start_position(pos);
95   function_scope->set_end_position(pos);
96   ZonePtrList<Statement>* body = nullptr;
97 
98   {
99     FunctionState function_state(&function_state_, &scope_, function_scope);
100 
101     body = new (zone()) ZonePtrList<Statement>(call_super ? 2 : 1, zone());
102     if (call_super) {
103       // Create a SuperCallReference and handle in BytecodeGenerator.
104       auto constructor_args_name = ast_value_factory()->empty_string();
105       bool is_duplicate;
106       bool is_rest = true;
107       bool is_optional = false;
108       Variable* constructor_args = function_scope->DeclareParameter(
109           constructor_args_name, TEMPORARY, is_optional, is_rest, &is_duplicate,
110           ast_value_factory(), pos);
111 
112       ZonePtrList<Expression>* args =
113           new (zone()) ZonePtrList<Expression>(1, zone());
114       Spread* spread_args = factory()->NewSpread(
115           factory()->NewVariableProxy(constructor_args), pos, pos);
116 
117       args->Add(spread_args, zone());
118       Expression* super_call_ref = NewSuperCallReference(pos);
119       Expression* call = factory()->NewCall(super_call_ref, args, pos);
120       body->Add(factory()->NewReturnStatement(call, pos), zone());
121     }
122 
123     expected_property_count = function_state.expected_property_count();
124   }
125 
126   FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
127       name, function_scope, body, expected_property_count, parameter_count,
128       parameter_count, FunctionLiteral::kNoDuplicateParameters,
129       FunctionLiteral::kAnonymousExpression, default_eager_compile_hint(), pos,
130       true, GetNextFunctionLiteralId());
131   return function_literal;
132 }
133 
134 // ----------------------------------------------------------------------------
135 // The CHECK_OK macro is a convenient macro to enforce error
136 // handling for functions that may fail (by returning !*ok).
137 //
138 // CAUTION: This macro appends extra statements after a call,
139 // thus it must never be used where only a single statement
140 // is correct (e.g. an if statement branch w/o braces)!
141 
142 #define CHECK_OK_VALUE(x) ok); \
143   if (!*ok) return x;          \
144   ((void)0
145 #define DUMMY )  // to make indentation work
146 #undef DUMMY
147 
148 #define CHECK_OK CHECK_OK_VALUE(nullptr)
149 #define CHECK_OK_VOID CHECK_OK_VALUE(this->Void())
150 
151 #define CHECK_FAILED /**/); \
152   if (failed_) return nullptr;  \
153   ((void)0
154 #define DUMMY )  // to make indentation work
155 #undef DUMMY
156 
157 // ----------------------------------------------------------------------------
158 // Implementation of Parser
159 
ShortcutNumericLiteralBinaryExpression(Expression ** x,Expression * y,Token::Value op,int pos)160 bool Parser::ShortcutNumericLiteralBinaryExpression(Expression** x,
161                                                     Expression* y,
162                                                     Token::Value op, int pos) {
163   if ((*x)->IsNumberLiteral() && y->IsNumberLiteral()) {
164     double x_val = (*x)->AsLiteral()->AsNumber();
165     double y_val = y->AsLiteral()->AsNumber();
166     switch (op) {
167       case Token::ADD:
168         *x = factory()->NewNumberLiteral(x_val + y_val, pos);
169         return true;
170       case Token::SUB:
171         *x = factory()->NewNumberLiteral(x_val - y_val, pos);
172         return true;
173       case Token::MUL:
174         *x = factory()->NewNumberLiteral(x_val * y_val, pos);
175         return true;
176       case Token::DIV:
177         *x = factory()->NewNumberLiteral(x_val / y_val, pos);
178         return true;
179       case Token::BIT_OR: {
180         int value = DoubleToInt32(x_val) | DoubleToInt32(y_val);
181         *x = factory()->NewNumberLiteral(value, pos);
182         return true;
183       }
184       case Token::BIT_AND: {
185         int value = DoubleToInt32(x_val) & DoubleToInt32(y_val);
186         *x = factory()->NewNumberLiteral(value, pos);
187         return true;
188       }
189       case Token::BIT_XOR: {
190         int value = DoubleToInt32(x_val) ^ DoubleToInt32(y_val);
191         *x = factory()->NewNumberLiteral(value, pos);
192         return true;
193       }
194       case Token::SHL: {
195         int value = DoubleToInt32(x_val) << (DoubleToInt32(y_val) & 0x1F);
196         *x = factory()->NewNumberLiteral(value, pos);
197         return true;
198       }
199       case Token::SHR: {
200         uint32_t shift = DoubleToInt32(y_val) & 0x1F;
201         uint32_t value = DoubleToUint32(x_val) >> shift;
202         *x = factory()->NewNumberLiteral(value, pos);
203         return true;
204       }
205       case Token::SAR: {
206         uint32_t shift = DoubleToInt32(y_val) & 0x1F;
207         int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift);
208         *x = factory()->NewNumberLiteral(value, pos);
209         return true;
210       }
211       case Token::EXP: {
212         double value = Pow(x_val, y_val);
213         int int_value = static_cast<int>(value);
214         *x = factory()->NewNumberLiteral(
215             int_value == value && value != -0.0 ? int_value : value, pos);
216         return true;
217       }
218       default:
219         break;
220     }
221   }
222   return false;
223 }
224 
CollapseNaryExpression(Expression ** x,Expression * y,Token::Value op,int pos,const SourceRange & range)225 bool Parser::CollapseNaryExpression(Expression** x, Expression* y,
226                                     Token::Value op, int pos,
227                                     const SourceRange& range) {
228   // Filter out unsupported ops.
229   if (!Token::IsBinaryOp(op) || op == Token::EXP) return false;
230 
231   // Convert *x into an nary operation with the given op, returning false if
232   // this is not possible.
233   NaryOperation* nary = nullptr;
234   if ((*x)->IsBinaryOperation()) {
235     BinaryOperation* binop = (*x)->AsBinaryOperation();
236     if (binop->op() != op) return false;
237 
238     nary = factory()->NewNaryOperation(op, binop->left(), 2);
239     nary->AddSubsequent(binop->right(), binop->position());
240     ConvertBinaryToNaryOperationSourceRange(binop, nary);
241     *x = nary;
242   } else if ((*x)->IsNaryOperation()) {
243     nary = (*x)->AsNaryOperation();
244     if (nary->op() != op) return false;
245   } else {
246     return false;
247   }
248 
249   // Append our current expression to the nary operation.
250   // TODO(leszeks): Do some literal collapsing here if we're appending Smi or
251   // String literals.
252   nary->AddSubsequent(y, pos);
253   AppendNaryOperationSourceRange(nary, range);
254 
255   return true;
256 }
257 
BuildUnaryExpression(Expression * expression,Token::Value op,int pos)258 Expression* Parser::BuildUnaryExpression(Expression* expression,
259                                          Token::Value op, int pos) {
260   DCHECK_NOT_NULL(expression);
261   const Literal* literal = expression->AsLiteral();
262   if (literal != nullptr) {
263     if (op == Token::NOT) {
264       // Convert the literal to a boolean condition and negate it.
265       return factory()->NewBooleanLiteral(literal->ToBooleanIsFalse(), pos);
266     } else if (literal->IsNumberLiteral()) {
267       // Compute some expressions involving only number literals.
268       double value = literal->AsNumber();
269       switch (op) {
270         case Token::ADD:
271           return expression;
272         case Token::SUB:
273           return factory()->NewNumberLiteral(-value, pos);
274         case Token::BIT_NOT:
275           return factory()->NewNumberLiteral(~DoubleToInt32(value), pos);
276         default:
277           break;
278       }
279     }
280   }
281   return factory()->NewUnaryOperation(op, expression, pos);
282 }
283 
NewThrowError(Runtime::FunctionId id,MessageTemplate::Template message,const AstRawString * arg,int pos)284 Expression* Parser::NewThrowError(Runtime::FunctionId id,
285                                   MessageTemplate::Template message,
286                                   const AstRawString* arg, int pos) {
287   ZonePtrList<Expression>* args =
288       new (zone()) ZonePtrList<Expression>(2, zone());
289   args->Add(factory()->NewSmiLiteral(message, pos), zone());
290   args->Add(factory()->NewStringLiteral(arg, pos), zone());
291   CallRuntime* call_constructor = factory()->NewCallRuntime(id, args, pos);
292   return factory()->NewThrow(call_constructor, pos);
293 }
294 
NewSuperPropertyReference(int pos)295 Expression* Parser::NewSuperPropertyReference(int pos) {
296   // this_function[home_object_symbol]
297   VariableProxy* this_function_proxy =
298       NewUnresolved(ast_value_factory()->this_function_string(), pos);
299   Expression* home_object_symbol_literal = factory()->NewSymbolLiteral(
300       AstSymbol::kHomeObjectSymbol, kNoSourcePosition);
301   Expression* home_object = factory()->NewProperty(
302       this_function_proxy, home_object_symbol_literal, pos);
303   return factory()->NewSuperPropertyReference(
304       ThisExpression(pos)->AsVariableProxy(), home_object, pos);
305 }
306 
NewSuperCallReference(int pos)307 Expression* Parser::NewSuperCallReference(int pos) {
308   VariableProxy* new_target_proxy =
309       NewUnresolved(ast_value_factory()->new_target_string(), pos);
310   VariableProxy* this_function_proxy =
311       NewUnresolved(ast_value_factory()->this_function_string(), pos);
312   return factory()->NewSuperCallReference(
313       ThisExpression(pos)->AsVariableProxy(), new_target_proxy,
314       this_function_proxy, pos);
315 }
316 
NewTargetExpression(int pos)317 Expression* Parser::NewTargetExpression(int pos) {
318   auto proxy = NewUnresolved(ast_value_factory()->new_target_string(), pos);
319   proxy->set_is_new_target();
320   return proxy;
321 }
322 
ImportMetaExpression(int pos)323 Expression* Parser::ImportMetaExpression(int pos) {
324   return factory()->NewCallRuntime(
325       Runtime::kInlineGetImportMetaObject,
326       new (zone()) ZonePtrList<Expression>(0, zone()), pos);
327 }
328 
ExpressionFromLiteral(Token::Value token,int pos)329 Literal* Parser::ExpressionFromLiteral(Token::Value token, int pos) {
330   switch (token) {
331     case Token::NULL_LITERAL:
332       return factory()->NewNullLiteral(pos);
333     case Token::TRUE_LITERAL:
334       return factory()->NewBooleanLiteral(true, pos);
335     case Token::FALSE_LITERAL:
336       return factory()->NewBooleanLiteral(false, pos);
337     case Token::SMI: {
338       uint32_t value = scanner()->smi_value();
339       return factory()->NewSmiLiteral(value, pos);
340     }
341     case Token::NUMBER: {
342       double value = scanner()->DoubleValue();
343       return factory()->NewNumberLiteral(value, pos);
344     }
345     case Token::BIGINT:
346       return factory()->NewBigIntLiteral(
347           AstBigInt(scanner()->CurrentLiteralAsCString(zone())), pos);
348     default:
349       DCHECK(false);
350   }
351   return nullptr;
352 }
353 
NewV8Intrinsic(const AstRawString * name,ZonePtrList<Expression> * args,int pos,bool * ok)354 Expression* Parser::NewV8Intrinsic(const AstRawString* name,
355                                    ZonePtrList<Expression>* args, int pos,
356                                    bool* ok) {
357   if (extension_ != nullptr) {
358     // The extension structures are only accessible while parsing the
359     // very first time, not when reparsing because of lazy compilation.
360     GetClosureScope()->ForceEagerCompilation();
361   }
362 
363   DCHECK(name->is_one_byte());
364   const Runtime::Function* function =
365       Runtime::FunctionForName(name->raw_data(), name->length());
366 
367   if (function != nullptr) {
368     // Check for possible name clash.
369     DCHECK_EQ(Context::kNotFound,
370               Context::IntrinsicIndexForName(name->raw_data(), name->length()));
371     // Check for built-in IS_VAR macro.
372     if (function->function_id == Runtime::kIS_VAR) {
373       DCHECK_EQ(Runtime::RUNTIME, function->intrinsic_type);
374       // %IS_VAR(x) evaluates to x if x is a variable,
375       // leads to a parse error otherwise.  Could be implemented as an
376       // inline function %_IS_VAR(x) to eliminate this special case.
377       if (args->length() == 1 && args->at(0)->AsVariableProxy() != nullptr) {
378         return args->at(0);
379       } else {
380         ReportMessage(MessageTemplate::kNotIsvar);
381         *ok = false;
382         return nullptr;
383       }
384     }
385 
386     // Check that the expected number of arguments are being passed.
387     if (function->nargs != -1 && function->nargs != args->length()) {
388       ReportMessage(MessageTemplate::kRuntimeWrongNumArgs);
389       *ok = false;
390       return nullptr;
391     }
392 
393     return factory()->NewCallRuntime(function, args, pos);
394   }
395 
396   int context_index =
397       Context::IntrinsicIndexForName(name->raw_data(), name->length());
398 
399   // Check that the function is defined.
400   if (context_index == Context::kNotFound) {
401     ReportMessage(MessageTemplate::kNotDefined, name);
402     *ok = false;
403     return nullptr;
404   }
405 
406   return factory()->NewCallRuntime(context_index, args, pos);
407 }
408 
Parser(ParseInfo * info)409 Parser::Parser(ParseInfo* info)
410     : ParserBase<Parser>(info->zone(), &scanner_, info->stack_limit(),
411                          info->extension(), info->GetOrCreateAstValueFactory(),
412                          info->pending_error_handler(),
413                          info->runtime_call_stats(), info->logger(),
414                          info->script().is_null() ? -1 : info->script()->id(),
415                          info->is_module(), true),
416       scanner_(info->unicode_cache()),
417       reusable_preparser_(nullptr),
418       mode_(PARSE_EAGERLY),  // Lazy mode must be set explicitly.
419       source_range_map_(info->source_range_map()),
420       target_stack_(nullptr),
421       total_preparse_skipped_(0),
422       temp_zoned_(false),
423       consumed_preparsed_scope_data_(info->consumed_preparsed_scope_data()),
424       parameters_end_pos_(info->parameters_end_pos()) {
425   // Even though we were passed ParseInfo, we should not store it in
426   // Parser - this makes sure that Isolate is not accidentally accessed via
427   // ParseInfo during background parsing.
428   DCHECK_NOT_NULL(info->character_stream());
429   // Determine if functions can be lazily compiled. This is necessary to
430   // allow some of our builtin JS files to be lazily compiled. These
431   // builtins cannot be handled lazily by the parser, since we have to know
432   // if a function uses the special natives syntax, which is something the
433   // parser records.
434   // If the debugger requests compilation for break points, we cannot be
435   // aggressive about lazy compilation, because it might trigger compilation
436   // of functions without an outer context when setting a breakpoint through
437   // Debug::FindSharedFunctionInfoInScript
438   // We also compile eagerly for kProduceExhaustiveCodeCache.
439   bool can_compile_lazily = FLAG_lazy && !info->is_eager();
440 
441   set_default_eager_compile_hint(can_compile_lazily
442                                      ? FunctionLiteral::kShouldLazyCompile
443                                      : FunctionLiteral::kShouldEagerCompile);
444   allow_lazy_ = FLAG_lazy && info->allow_lazy_parsing() && !info->is_native() &&
445                 info->extension() == nullptr && can_compile_lazily;
446   set_allow_natives(FLAG_allow_natives_syntax || info->is_native());
447   set_allow_harmony_do_expressions(FLAG_harmony_do_expressions);
448   set_allow_harmony_public_fields(FLAG_harmony_public_fields);
449   set_allow_harmony_static_fields(FLAG_harmony_static_fields);
450   set_allow_harmony_dynamic_import(FLAG_harmony_dynamic_import);
451   set_allow_harmony_import_meta(FLAG_harmony_import_meta);
452   set_allow_harmony_bigint(FLAG_harmony_bigint);
453   set_allow_harmony_numeric_separator(FLAG_harmony_numeric_separator);
454   set_allow_harmony_optional_catch_binding(FLAG_harmony_optional_catch_binding);
455   set_allow_harmony_private_fields(FLAG_harmony_private_fields);
456   for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
457        ++feature) {
458     use_counts_[feature] = 0;
459   }
460 }
461 
DeserializeScopeChain(ParseInfo * info,MaybeHandle<ScopeInfo> maybe_outer_scope_info)462 void Parser::DeserializeScopeChain(
463     ParseInfo* info, MaybeHandle<ScopeInfo> maybe_outer_scope_info) {
464   // TODO(wingo): Add an outer SCRIPT_SCOPE corresponding to the native
465   // context, which will have the "this" binding for script scopes.
466   DeclarationScope* script_scope = NewScriptScope();
467   info->set_script_scope(script_scope);
468   Scope* scope = script_scope;
469   Handle<ScopeInfo> outer_scope_info;
470   if (maybe_outer_scope_info.ToHandle(&outer_scope_info)) {
471     DCHECK(ThreadId::Current().Equals(
472         outer_scope_info->GetIsolate()->thread_id()));
473     scope = Scope::DeserializeScopeChain(
474         zone(), *outer_scope_info, script_scope, ast_value_factory(),
475         Scope::DeserializationMode::kScopesOnly);
476   }
477   original_scope_ = scope;
478 }
479 
480 namespace {
481 
MaybeResetCharacterStream(ParseInfo * info,FunctionLiteral * literal)482 void MaybeResetCharacterStream(ParseInfo* info, FunctionLiteral* literal) {
483   // Don't reset the character stream if there is an asm.js module since it will
484   // be used again by the asm-parser.
485   if (!FLAG_stress_validate_asm &&
486       (literal == nullptr || !literal->scope()->ContainsAsmModule())) {
487     info->ResetCharacterStream();
488   }
489 }
490 
MaybeProcessSourceRanges(ParseInfo * parse_info,Expression * root,uintptr_t stack_limit_)491 void MaybeProcessSourceRanges(ParseInfo* parse_info, Expression* root,
492                               uintptr_t stack_limit_) {
493   if (root != nullptr && parse_info->source_range_map() != nullptr) {
494     SourceRangeAstVisitor visitor(stack_limit_, root,
495                                   parse_info->source_range_map());
496     visitor.Run();
497   }
498 }
499 
500 }  // namespace
501 
ParseProgram(Isolate * isolate,ParseInfo * info)502 FunctionLiteral* Parser::ParseProgram(Isolate* isolate, ParseInfo* info) {
503   // TODO(bmeurer): We temporarily need to pass allow_nesting = true here,
504   // see comment for HistogramTimerScope class.
505 
506   // It's OK to use the Isolate & counters here, since this function is only
507   // called in the main thread.
508   DCHECK(parsing_on_main_thread_);
509   RuntimeCallTimerScope runtime_timer(
510       runtime_call_stats_, info->is_eval()
511                                ? RuntimeCallCounterId::kParseEval
512                                : RuntimeCallCounterId::kParseProgram);
513   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.ParseProgram");
514   base::ElapsedTimer timer;
515   if (V8_UNLIKELY(FLAG_log_function_events)) timer.Start();
516   fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
517 
518   // Initialize parser state.
519   DeserializeScopeChain(info, info->maybe_outer_scope_info());
520 
521   scanner_.Initialize(info->character_stream(), info->is_module());
522   FunctionLiteral* result = DoParseProgram(isolate, info);
523   MaybeResetCharacterStream(info, result);
524   MaybeProcessSourceRanges(info, result, stack_limit_);
525 
526   HandleSourceURLComments(isolate, info->script());
527 
528   if (V8_UNLIKELY(FLAG_log_function_events) && result != nullptr) {
529     double ms = timer.Elapsed().InMillisecondsF();
530     const char* event_name = "parse-eval";
531     Script* script = *info->script();
532     int start = -1;
533     int end = -1;
534     if (!info->is_eval()) {
535       event_name = "parse-script";
536       start = 0;
537       end = String::cast(script->source())->length();
538     }
539     LOG(script->GetIsolate(),
540         FunctionEvent(event_name, script, -1, ms, start, end, "", 0));
541   }
542   return result;
543 }
544 
DoParseProgram(Isolate * isolate,ParseInfo * info)545 FunctionLiteral* Parser::DoParseProgram(Isolate* isolate, ParseInfo* info) {
546   // Note that this function can be called from the main thread or from a
547   // background thread. We should not access anything Isolate / heap dependent
548   // via ParseInfo, and also not pass it forward. If not on the main thread
549   // isolate will be nullptr.
550   DCHECK_EQ(parsing_on_main_thread_, isolate != nullptr);
551   DCHECK_NULL(scope_);
552   DCHECK_NULL(target_stack_);
553 
554   ParsingModeScope mode(this, allow_lazy_ ? PARSE_LAZILY : PARSE_EAGERLY);
555   ResetFunctionLiteralId();
556   DCHECK(info->function_literal_id() == FunctionLiteral::kIdTypeTopLevel ||
557          info->function_literal_id() == FunctionLiteral::kIdTypeInvalid);
558 
559   FunctionLiteral* result = nullptr;
560   {
561     Scope* outer = original_scope_;
562     DCHECK_NOT_NULL(outer);
563     if (info->is_eval()) {
564       outer = NewEvalScope(outer);
565     } else if (parsing_module_) {
566       DCHECK_EQ(outer, info->script_scope());
567       outer = NewModuleScope(info->script_scope());
568     }
569 
570     DeclarationScope* scope = outer->AsDeclarationScope();
571     scope->set_start_position(0);
572 
573     FunctionState function_state(&function_state_, &scope_, scope);
574     ZonePtrList<Statement>* body =
575         new (zone()) ZonePtrList<Statement>(16, zone());
576     bool ok = true;
577     int beg_pos = scanner()->location().beg_pos;
578     if (parsing_module_) {
579       DCHECK(info->is_module());
580       // Declare the special module parameter.
581       auto name = ast_value_factory()->empty_string();
582       bool is_duplicate = false;
583       bool is_rest = false;
584       bool is_optional = false;
585       auto var =
586           scope->DeclareParameter(name, VAR, is_optional, is_rest,
587                                   &is_duplicate, ast_value_factory(), beg_pos);
588       DCHECK(!is_duplicate);
589       var->AllocateTo(VariableLocation::PARAMETER, 0);
590 
591       PrepareGeneratorVariables();
592       Expression* initial_yield =
593           BuildInitialYield(kNoSourcePosition, kGeneratorFunction);
594       body->Add(
595           factory()->NewExpressionStatement(initial_yield, kNoSourcePosition),
596           zone());
597 
598       ParseModuleItemList(body, &ok);
599       ok = ok && module()->Validate(this->scope()->AsModuleScope(),
600                                     pending_error_handler(), zone());
601     } else if (info->is_wrapped_as_function()) {
602       ParseWrapped(isolate, info, body, scope, zone(), &ok);
603     } else {
604       // Don't count the mode in the use counters--give the program a chance
605       // to enable script-wide strict mode below.
606       this->scope()->SetLanguageMode(info->language_mode());
607       ParseStatementList(body, Token::EOS, &ok);
608     }
609 
610     // The parser will peek but not consume EOS.  Our scope logically goes all
611     // the way to the EOS, though.
612     scope->set_end_position(scanner()->peek_location().beg_pos);
613 
614     if (ok && is_strict(language_mode())) {
615       CheckStrictOctalLiteral(beg_pos, scanner()->location().end_pos, &ok);
616     }
617     if (ok && is_sloppy(language_mode())) {
618       // TODO(littledan): Function bindings on the global object that modify
619       // pre-existing bindings should be made writable, enumerable and
620       // nonconfigurable if possible, whereas this code will leave attributes
621       // unchanged if the property already exists.
622       InsertSloppyBlockFunctionVarBindings(scope);
623     }
624     if (ok) {
625       CheckConflictingVarDeclarations(scope, &ok);
626     }
627 
628     if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) {
629       if (body->length() != 1 ||
630           !body->at(0)->IsExpressionStatement() ||
631           !body->at(0)->AsExpressionStatement()->
632               expression()->IsFunctionLiteral()) {
633         ReportMessage(MessageTemplate::kSingleFunctionLiteral);
634         ok = false;
635       }
636     }
637 
638     if (ok) {
639       RewriteDestructuringAssignments();
640       int parameter_count = parsing_module_ ? 1 : 0;
641       result = factory()->NewScriptOrEvalFunctionLiteral(
642           scope, body, function_state.expected_property_count(),
643           parameter_count);
644       result->set_suspend_count(function_state.suspend_count());
645     }
646   }
647 
648   info->set_max_function_literal_id(GetLastFunctionLiteralId());
649 
650   // Make sure the target stack is empty.
651   DCHECK_NULL(target_stack_);
652 
653   return result;
654 }
655 
PrepareWrappedArguments(Isolate * isolate,ParseInfo * info,Zone * zone)656 ZonePtrList<const AstRawString>* Parser::PrepareWrappedArguments(
657     Isolate* isolate, ParseInfo* info, Zone* zone) {
658   DCHECK(parsing_on_main_thread_);
659   DCHECK_NOT_NULL(isolate);
660   Handle<FixedArray> arguments(info->script()->wrapped_arguments(), isolate);
661   int arguments_length = arguments->length();
662   ZonePtrList<const AstRawString>* arguments_for_wrapped_function =
663       new (zone) ZonePtrList<const AstRawString>(arguments_length, zone);
664   for (int i = 0; i < arguments_length; i++) {
665     const AstRawString* argument_string = ast_value_factory()->GetString(
666         Handle<String>(String::cast(arguments->get(i)), isolate));
667     arguments_for_wrapped_function->Add(argument_string, zone);
668   }
669   return arguments_for_wrapped_function;
670 }
671 
ParseWrapped(Isolate * isolate,ParseInfo * info,ZonePtrList<Statement> * body,DeclarationScope * outer_scope,Zone * zone,bool * ok)672 void Parser::ParseWrapped(Isolate* isolate, ParseInfo* info,
673                           ZonePtrList<Statement>* body,
674                           DeclarationScope* outer_scope, Zone* zone, bool* ok) {
675   DCHECK_EQ(parsing_on_main_thread_, isolate != nullptr);
676   DCHECK(info->is_wrapped_as_function());
677   ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
678 
679   // Set function and block state for the outer eval scope.
680   DCHECK(outer_scope->is_eval_scope());
681   FunctionState function_state(&function_state_, &scope_, outer_scope);
682 
683   const AstRawString* function_name = nullptr;
684   Scanner::Location location(0, 0);
685 
686   ZonePtrList<const AstRawString>* arguments_for_wrapped_function =
687       PrepareWrappedArguments(isolate, info, zone);
688 
689   FunctionLiteral* function_literal = ParseFunctionLiteral(
690       function_name, location, kSkipFunctionNameCheck, kNormalFunction,
691       kNoSourcePosition, FunctionLiteral::kWrapped, LanguageMode::kSloppy,
692       arguments_for_wrapped_function, CHECK_OK_VOID);
693 
694   Statement* return_statement = factory()->NewReturnStatement(
695       function_literal, kNoSourcePosition, kNoSourcePosition);
696   body->Add(return_statement, zone);
697 }
698 
ParseFunction(Isolate * isolate,ParseInfo * info,Handle<SharedFunctionInfo> shared_info)699 FunctionLiteral* Parser::ParseFunction(Isolate* isolate, ParseInfo* info,
700                                        Handle<SharedFunctionInfo> shared_info) {
701   // It's OK to use the Isolate & counters here, since this function is only
702   // called in the main thread.
703   DCHECK(parsing_on_main_thread_);
704   RuntimeCallTimerScope runtime_timer(runtime_call_stats_,
705                                       RuntimeCallCounterId::kParseFunction);
706   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.ParseFunction");
707   base::ElapsedTimer timer;
708   if (V8_UNLIKELY(FLAG_log_function_events)) timer.Start();
709 
710   DeserializeScopeChain(info, info->maybe_outer_scope_info());
711   DCHECK_EQ(factory()->zone(), info->zone());
712 
713   // Initialize parser state.
714   Handle<String> name(shared_info->Name(), isolate);
715   info->set_function_name(ast_value_factory()->GetString(name));
716   scanner_.Initialize(info->character_stream(), info->is_module());
717 
718   FunctionLiteral* result =
719       DoParseFunction(isolate, info, info->function_name());
720   MaybeResetCharacterStream(info, result);
721   MaybeProcessSourceRanges(info, result, stack_limit_);
722   if (result != nullptr) {
723     Handle<String> inferred_name(shared_info->inferred_name(), isolate);
724     result->set_inferred_name(inferred_name);
725   }
726 
727   if (V8_UNLIKELY(FLAG_log_function_events) && result != nullptr) {
728     double ms = timer.Elapsed().InMillisecondsF();
729     // We need to make sure that the debug-name is available.
730     ast_value_factory()->Internalize(isolate);
731     DeclarationScope* function_scope = result->scope();
732     Script* script = *info->script();
733     std::unique_ptr<char[]> function_name = result->GetDebugName();
734     LOG(script->GetIsolate(),
735         FunctionEvent("parse-function", script, -1, ms,
736                       function_scope->start_position(),
737                       function_scope->end_position(), function_name.get(),
738                       strlen(function_name.get())));
739   }
740   return result;
741 }
742 
ComputeFunctionType(ParseInfo * info)743 static FunctionLiteral::FunctionType ComputeFunctionType(ParseInfo* info) {
744   if (info->is_wrapped_as_function()) {
745     return FunctionLiteral::kWrapped;
746   } else if (info->is_declaration()) {
747     return FunctionLiteral::kDeclaration;
748   } else if (info->is_named_expression()) {
749     return FunctionLiteral::kNamedExpression;
750   } else if (IsConciseMethod(info->function_kind()) ||
751              IsAccessorFunction(info->function_kind())) {
752     return FunctionLiteral::kAccessorOrMethod;
753   }
754   return FunctionLiteral::kAnonymousExpression;
755 }
756 
DoParseFunction(Isolate * isolate,ParseInfo * info,const AstRawString * raw_name)757 FunctionLiteral* Parser::DoParseFunction(Isolate* isolate, ParseInfo* info,
758                                          const AstRawString* raw_name) {
759   DCHECK_EQ(parsing_on_main_thread_, isolate != nullptr);
760   DCHECK_NOT_NULL(raw_name);
761   DCHECK_NULL(scope_);
762   DCHECK_NULL(target_stack_);
763 
764   DCHECK(ast_value_factory());
765   fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
766   fni_->PushEnclosingName(raw_name);
767 
768   ResetFunctionLiteralId();
769   DCHECK_LT(0, info->function_literal_id());
770   SkipFunctionLiterals(info->function_literal_id() - 1);
771 
772   ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
773 
774   // Place holder for the result.
775   FunctionLiteral* result = nullptr;
776 
777   {
778     // Parse the function literal.
779     Scope* outer = original_scope_;
780     DeclarationScope* outer_function = outer->GetClosureScope();
781     DCHECK(outer);
782     FunctionState function_state(&function_state_, &scope_, outer_function);
783     BlockState block_state(&scope_, outer);
784     DCHECK(is_sloppy(outer->language_mode()) ||
785            is_strict(info->language_mode()));
786     FunctionLiteral::FunctionType function_type = ComputeFunctionType(info);
787     FunctionKind kind = info->function_kind();
788     bool ok = true;
789 
790     if (IsArrowFunction(kind)) {
791       if (IsAsyncFunction(kind)) {
792         DCHECK(!scanner()->HasAnyLineTerminatorAfterNext());
793         if (!Check(Token::ASYNC)) {
794           CHECK(stack_overflow());
795           return nullptr;
796         }
797         if (!(peek_any_identifier() || peek() == Token::LPAREN)) {
798           CHECK(stack_overflow());
799           return nullptr;
800         }
801       }
802 
803       // TODO(adamk): We should construct this scope from the ScopeInfo.
804       DeclarationScope* scope = NewFunctionScope(kind);
805 
806       // This bit only needs to be explicitly set because we're
807       // not passing the ScopeInfo to the Scope constructor.
808       SetLanguageMode(scope, info->language_mode());
809 
810       scope->set_start_position(info->start_position());
811       ExpressionClassifier formals_classifier(this);
812       ParserFormalParameters formals(scope);
813       // The outer FunctionState should not contain destructuring assignments.
814       DCHECK_EQ(0,
815                 function_state.destructuring_assignments_to_rewrite().length());
816       {
817         // Parsing patterns as variable reference expression creates
818         // NewUnresolved references in current scope. Enter arrow function
819         // scope for formal parameter parsing.
820         BlockState block_state(&scope_, scope);
821         if (Check(Token::LPAREN)) {
822           // '(' StrictFormalParameters ')'
823           ParseFormalParameterList(&formals, &ok);
824           if (ok) ok = Check(Token::RPAREN);
825         } else {
826           // BindingIdentifier
827           ParseFormalParameter(&formals, &ok);
828           if (ok) {
829             DeclareFormalParameters(formals.scope, formals.params,
830                                     formals.is_simple);
831           }
832         }
833       }
834 
835       if (ok) {
836         if (GetLastFunctionLiteralId() != info->function_literal_id() - 1) {
837           // If there were FunctionLiterals in the parameters, we need to
838           // renumber them to shift down so the next function literal id for
839           // the arrow function is the one requested.
840           AstFunctionLiteralIdReindexer reindexer(
841               stack_limit_,
842               (info->function_literal_id() - 1) - GetLastFunctionLiteralId());
843           for (auto p : formals.params) {
844             if (p->pattern != nullptr) reindexer.Reindex(p->pattern);
845             if (p->initializer != nullptr) reindexer.Reindex(p->initializer);
846           }
847           ResetFunctionLiteralId();
848           SkipFunctionLiterals(info->function_literal_id() - 1);
849         }
850 
851         // Pass `accept_IN=true` to ParseArrowFunctionLiteral --- This should
852         // not be observable, or else the preparser would have failed.
853         const bool accept_IN = true;
854         // Any destructuring assignments in the current FunctionState
855         // actually belong to the arrow function itself.
856         const int rewritable_length = 0;
857         Expression* expression = ParseArrowFunctionLiteral(
858             accept_IN, formals, rewritable_length, &ok);
859         if (ok) {
860           // Scanning must end at the same position that was recorded
861           // previously. If not, parsing has been interrupted due to a stack
862           // overflow, at which point the partially parsed arrow function
863           // concise body happens to be a valid expression. This is a problem
864           // only for arrow functions with single expression bodies, since there
865           // is no end token such as "}" for normal functions.
866           if (scanner()->location().end_pos == info->end_position()) {
867             // The pre-parser saw an arrow function here, so the full parser
868             // must produce a FunctionLiteral.
869             DCHECK(expression->IsFunctionLiteral());
870             result = expression->AsFunctionLiteral();
871           } else {
872             ok = false;
873           }
874         }
875       }
876     } else if (IsDefaultConstructor(kind)) {
877       DCHECK_EQ(scope(), outer);
878       result = DefaultConstructor(raw_name, IsDerivedConstructor(kind),
879                                   info->start_position(), info->end_position());
880     } else {
881       ZonePtrList<const AstRawString>* arguments_for_wrapped_function =
882           info->is_wrapped_as_function()
883               ? PrepareWrappedArguments(isolate, info, zone())
884               : nullptr;
885       result = ParseFunctionLiteral(
886           raw_name, Scanner::Location::invalid(), kSkipFunctionNameCheck, kind,
887           kNoSourcePosition, function_type, info->language_mode(),
888           arguments_for_wrapped_function, &ok);
889     }
890 
891     if (ok) {
892       result->set_requires_instance_fields_initializer(
893           info->requires_instance_fields_initializer());
894     }
895     // Make sure the results agree.
896     DCHECK(ok == (result != nullptr));
897   }
898 
899   // Make sure the target stack is empty.
900   DCHECK_NULL(target_stack_);
901   DCHECK_IMPLIES(result,
902                  info->function_literal_id() == result->function_literal_id());
903   return result;
904 }
905 
ParseModuleItem(bool * ok)906 Statement* Parser::ParseModuleItem(bool* ok) {
907   // ecma262/#prod-ModuleItem
908   // ModuleItem :
909   //    ImportDeclaration
910   //    ExportDeclaration
911   //    StatementListItem
912 
913   Token::Value next = peek();
914 
915   if (next == Token::EXPORT) {
916     return ParseExportDeclaration(ok);
917   }
918 
919   if (next == Token::IMPORT) {
920     // We must be careful not to parse a dynamic import expression as an import
921     // declaration. Same for import.meta expressions.
922     Token::Value peek_ahead = PeekAhead();
923     if ((!allow_harmony_dynamic_import() || peek_ahead != Token::LPAREN) &&
924         (!allow_harmony_import_meta() || peek_ahead != Token::PERIOD)) {
925       ParseImportDeclaration(CHECK_OK);
926       return factory()->NewEmptyStatement(kNoSourcePosition);
927     }
928   }
929 
930   return ParseStatementListItem(ok);
931 }
932 
ParseModuleItemList(ZonePtrList<Statement> * body,bool * ok)933 void Parser::ParseModuleItemList(ZonePtrList<Statement>* body, bool* ok) {
934   // ecma262/#prod-Module
935   // Module :
936   //    ModuleBody?
937   //
938   // ecma262/#prod-ModuleItemList
939   // ModuleBody :
940   //    ModuleItem*
941 
942   DCHECK(scope()->is_module_scope());
943   while (peek() != Token::EOS) {
944     Statement* stat = ParseModuleItem(CHECK_OK_VOID);
945     if (stat && !stat->IsEmpty()) {
946       body->Add(stat, zone());
947     }
948   }
949 }
950 
951 
ParseModuleSpecifier(bool * ok)952 const AstRawString* Parser::ParseModuleSpecifier(bool* ok) {
953   // ModuleSpecifier :
954   //    StringLiteral
955 
956   Expect(Token::STRING, CHECK_OK);
957   return GetSymbol();
958 }
959 
ParseExportClause(ZonePtrList<const AstRawString> * export_names,ZoneList<Scanner::Location> * export_locations,ZonePtrList<const AstRawString> * local_names,Scanner::Location * reserved_loc,bool * ok)960 void Parser::ParseExportClause(ZonePtrList<const AstRawString>* export_names,
961                                ZoneList<Scanner::Location>* export_locations,
962                                ZonePtrList<const AstRawString>* local_names,
963                                Scanner::Location* reserved_loc, bool* ok) {
964   // ExportClause :
965   //   '{' '}'
966   //   '{' ExportsList '}'
967   //   '{' ExportsList ',' '}'
968   //
969   // ExportsList :
970   //   ExportSpecifier
971   //   ExportsList ',' ExportSpecifier
972   //
973   // ExportSpecifier :
974   //   IdentifierName
975   //   IdentifierName 'as' IdentifierName
976 
977   Expect(Token::LBRACE, CHECK_OK_VOID);
978 
979   Token::Value name_tok;
980   while ((name_tok = peek()) != Token::RBRACE) {
981     // Keep track of the first reserved word encountered in case our
982     // caller needs to report an error.
983     if (!reserved_loc->IsValid() &&
984         !Token::IsIdentifier(name_tok, LanguageMode::kStrict, false,
985                              parsing_module_)) {
986       *reserved_loc = scanner()->location();
987     }
988     const AstRawString* local_name = ParseIdentifierName(CHECK_OK_VOID);
989     const AstRawString* export_name = nullptr;
990     Scanner::Location location = scanner()->location();
991     if (CheckContextualKeyword(Token::AS)) {
992       export_name = ParseIdentifierName(CHECK_OK_VOID);
993       // Set the location to the whole "a as b" string, so that it makes sense
994       // both for errors due to "a" and for errors due to "b".
995       location.end_pos = scanner()->location().end_pos;
996     }
997     if (export_name == nullptr) {
998       export_name = local_name;
999     }
1000     export_names->Add(export_name, zone());
1001     local_names->Add(local_name, zone());
1002     export_locations->Add(location, zone());
1003     if (peek() == Token::RBRACE) break;
1004     Expect(Token::COMMA, CHECK_OK_VOID);
1005   }
1006 
1007   Expect(Token::RBRACE, CHECK_OK_VOID);
1008 }
1009 
ParseNamedImports(int pos,bool * ok)1010 ZonePtrList<const Parser::NamedImport>* Parser::ParseNamedImports(int pos,
1011                                                                   bool* ok) {
1012   // NamedImports :
1013   //   '{' '}'
1014   //   '{' ImportsList '}'
1015   //   '{' ImportsList ',' '}'
1016   //
1017   // ImportsList :
1018   //   ImportSpecifier
1019   //   ImportsList ',' ImportSpecifier
1020   //
1021   // ImportSpecifier :
1022   //   BindingIdentifier
1023   //   IdentifierName 'as' BindingIdentifier
1024 
1025   Expect(Token::LBRACE, CHECK_OK);
1026 
1027   auto result = new (zone()) ZonePtrList<const NamedImport>(1, zone());
1028   while (peek() != Token::RBRACE) {
1029     const AstRawString* import_name = ParseIdentifierName(CHECK_OK);
1030     const AstRawString* local_name = import_name;
1031     Scanner::Location location = scanner()->location();
1032     // In the presence of 'as', the left-side of the 'as' can
1033     // be any IdentifierName. But without 'as', it must be a valid
1034     // BindingIdentifier.
1035     if (CheckContextualKeyword(Token::AS)) {
1036       local_name = ParseIdentifierName(CHECK_OK);
1037     }
1038     if (!Token::IsIdentifier(scanner()->current_token(), LanguageMode::kStrict,
1039                              false, parsing_module_)) {
1040       *ok = false;
1041       ReportMessage(MessageTemplate::kUnexpectedReserved);
1042       return nullptr;
1043     } else if (IsEvalOrArguments(local_name)) {
1044       *ok = false;
1045       ReportMessage(MessageTemplate::kStrictEvalArguments);
1046       return nullptr;
1047     }
1048 
1049     DeclareVariable(local_name, CONST, kNeedsInitialization, position(),
1050                     CHECK_OK);
1051 
1052     NamedImport* import =
1053         new (zone()) NamedImport(import_name, local_name, location);
1054     result->Add(import, zone());
1055 
1056     if (peek() == Token::RBRACE) break;
1057     Expect(Token::COMMA, CHECK_OK);
1058   }
1059 
1060   Expect(Token::RBRACE, CHECK_OK);
1061   return result;
1062 }
1063 
1064 
ParseImportDeclaration(bool * ok)1065 void Parser::ParseImportDeclaration(bool* ok) {
1066   // ImportDeclaration :
1067   //   'import' ImportClause 'from' ModuleSpecifier ';'
1068   //   'import' ModuleSpecifier ';'
1069   //
1070   // ImportClause :
1071   //   ImportedDefaultBinding
1072   //   NameSpaceImport
1073   //   NamedImports
1074   //   ImportedDefaultBinding ',' NameSpaceImport
1075   //   ImportedDefaultBinding ',' NamedImports
1076   //
1077   // NameSpaceImport :
1078   //   '*' 'as' ImportedBinding
1079 
1080   int pos = peek_position();
1081   Expect(Token::IMPORT, CHECK_OK_VOID);
1082 
1083   Token::Value tok = peek();
1084 
1085   // 'import' ModuleSpecifier ';'
1086   if (tok == Token::STRING) {
1087     Scanner::Location specifier_loc = scanner()->peek_location();
1088     const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK_VOID);
1089     ExpectSemicolon(CHECK_OK_VOID);
1090     module()->AddEmptyImport(module_specifier, specifier_loc);
1091     return;
1092   }
1093 
1094   // Parse ImportedDefaultBinding if present.
1095   const AstRawString* import_default_binding = nullptr;
1096   Scanner::Location import_default_binding_loc;
1097   if (tok != Token::MUL && tok != Token::LBRACE) {
1098     import_default_binding =
1099         ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK_VOID);
1100     import_default_binding_loc = scanner()->location();
1101     DeclareVariable(import_default_binding, CONST, kNeedsInitialization, pos,
1102                     CHECK_OK_VOID);
1103   }
1104 
1105   // Parse NameSpaceImport or NamedImports if present.
1106   const AstRawString* module_namespace_binding = nullptr;
1107   Scanner::Location module_namespace_binding_loc;
1108   const ZonePtrList<const NamedImport>* named_imports = nullptr;
1109   if (import_default_binding == nullptr || Check(Token::COMMA)) {
1110     switch (peek()) {
1111       case Token::MUL: {
1112         Consume(Token::MUL);
1113         ExpectContextualKeyword(Token::AS, CHECK_OK_VOID);
1114         module_namespace_binding =
1115             ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK_VOID);
1116         module_namespace_binding_loc = scanner()->location();
1117         DeclareVariable(module_namespace_binding, CONST, kCreatedInitialized,
1118                         pos, CHECK_OK_VOID);
1119         break;
1120       }
1121 
1122       case Token::LBRACE:
1123         named_imports = ParseNamedImports(pos, CHECK_OK_VOID);
1124         break;
1125 
1126       default:
1127         *ok = false;
1128         ReportUnexpectedToken(scanner()->current_token());
1129         return;
1130     }
1131   }
1132 
1133   ExpectContextualKeyword(Token::FROM, CHECK_OK_VOID);
1134   Scanner::Location specifier_loc = scanner()->peek_location();
1135   const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK_VOID);
1136   ExpectSemicolon(CHECK_OK_VOID);
1137 
1138   // Now that we have all the information, we can make the appropriate
1139   // declarations.
1140 
1141   // TODO(neis): Would prefer to call DeclareVariable for each case below rather
1142   // than above and in ParseNamedImports, but then a possible error message
1143   // would point to the wrong location.  Maybe have a DeclareAt version of
1144   // Declare that takes a location?
1145 
1146   if (module_namespace_binding != nullptr) {
1147     module()->AddStarImport(module_namespace_binding, module_specifier,
1148                             module_namespace_binding_loc, specifier_loc,
1149                             zone());
1150   }
1151 
1152   if (import_default_binding != nullptr) {
1153     module()->AddImport(ast_value_factory()->default_string(),
1154                         import_default_binding, module_specifier,
1155                         import_default_binding_loc, specifier_loc, zone());
1156   }
1157 
1158   if (named_imports != nullptr) {
1159     if (named_imports->length() == 0) {
1160       module()->AddEmptyImport(module_specifier, specifier_loc);
1161     } else {
1162       for (int i = 0; i < named_imports->length(); ++i) {
1163         const NamedImport* import = named_imports->at(i);
1164         module()->AddImport(import->import_name, import->local_name,
1165                             module_specifier, import->location, specifier_loc,
1166                             zone());
1167       }
1168     }
1169   }
1170 }
1171 
1172 
ParseExportDefault(bool * ok)1173 Statement* Parser::ParseExportDefault(bool* ok) {
1174   //  Supports the following productions, starting after the 'default' token:
1175   //    'export' 'default' HoistableDeclaration
1176   //    'export' 'default' ClassDeclaration
1177   //    'export' 'default' AssignmentExpression[In] ';'
1178 
1179   Expect(Token::DEFAULT, CHECK_OK);
1180   Scanner::Location default_loc = scanner()->location();
1181 
1182   ZonePtrList<const AstRawString> local_names(1, zone());
1183   Statement* result = nullptr;
1184   switch (peek()) {
1185     case Token::FUNCTION:
1186       result = ParseHoistableDeclaration(&local_names, true, CHECK_OK);
1187       break;
1188 
1189     case Token::CLASS:
1190       Consume(Token::CLASS);
1191       result = ParseClassDeclaration(&local_names, true, CHECK_OK);
1192       break;
1193 
1194     case Token::ASYNC:
1195       if (PeekAhead() == Token::FUNCTION &&
1196           !scanner()->HasAnyLineTerminatorAfterNext()) {
1197         Consume(Token::ASYNC);
1198         result = ParseAsyncFunctionDeclaration(&local_names, true, CHECK_OK);
1199         break;
1200       }
1201       V8_FALLTHROUGH;
1202 
1203     default: {
1204       int pos = position();
1205       ExpressionClassifier classifier(this);
1206       Expression* value = ParseAssignmentExpression(true, CHECK_OK);
1207       ValidateExpression(CHECK_OK);
1208       SetFunctionName(value, ast_value_factory()->default_string());
1209 
1210       const AstRawString* local_name =
1211           ast_value_factory()->star_default_star_string();
1212       local_names.Add(local_name, zone());
1213 
1214       // It's fine to declare this as CONST because the user has no way of
1215       // writing to it.
1216       Declaration* decl = DeclareVariable(local_name, CONST, pos, CHECK_OK);
1217       decl->proxy()->var()->set_initializer_position(position());
1218 
1219       Assignment* assignment = factory()->NewAssignment(
1220           Token::INIT, decl->proxy(), value, kNoSourcePosition);
1221       result = IgnoreCompletion(
1222           factory()->NewExpressionStatement(assignment, kNoSourcePosition));
1223 
1224       ExpectSemicolon(CHECK_OK);
1225       break;
1226     }
1227   }
1228 
1229   DCHECK_EQ(local_names.length(), 1);
1230   module()->AddExport(local_names.first(),
1231                       ast_value_factory()->default_string(), default_loc,
1232                       zone());
1233 
1234   DCHECK_NOT_NULL(result);
1235   return result;
1236 }
1237 
ParseExportDeclaration(bool * ok)1238 Statement* Parser::ParseExportDeclaration(bool* ok) {
1239   // ExportDeclaration:
1240   //    'export' '*' 'from' ModuleSpecifier ';'
1241   //    'export' ExportClause ('from' ModuleSpecifier)? ';'
1242   //    'export' VariableStatement
1243   //    'export' Declaration
1244   //    'export' 'default' ... (handled in ParseExportDefault)
1245 
1246   Expect(Token::EXPORT, CHECK_OK);
1247   int pos = position();
1248 
1249   Statement* result = nullptr;
1250   ZonePtrList<const AstRawString> names(1, zone());
1251   Scanner::Location loc = scanner()->peek_location();
1252   switch (peek()) {
1253     case Token::DEFAULT:
1254       return ParseExportDefault(ok);
1255 
1256     case Token::MUL: {
1257       Consume(Token::MUL);
1258       loc = scanner()->location();
1259       ExpectContextualKeyword(Token::FROM, CHECK_OK);
1260       Scanner::Location specifier_loc = scanner()->peek_location();
1261       const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK);
1262       ExpectSemicolon(CHECK_OK);
1263       module()->AddStarExport(module_specifier, loc, specifier_loc, zone());
1264       return factory()->NewEmptyStatement(pos);
1265     }
1266 
1267     case Token::LBRACE: {
1268       // There are two cases here:
1269       //
1270       // 'export' ExportClause ';'
1271       // and
1272       // 'export' ExportClause FromClause ';'
1273       //
1274       // In the first case, the exported identifiers in ExportClause must
1275       // not be reserved words, while in the latter they may be. We
1276       // pass in a location that gets filled with the first reserved word
1277       // encountered, and then throw a SyntaxError if we are in the
1278       // non-FromClause case.
1279       Scanner::Location reserved_loc = Scanner::Location::invalid();
1280       ZonePtrList<const AstRawString> export_names(1, zone());
1281       ZoneList<Scanner::Location> export_locations(1, zone());
1282       ZonePtrList<const AstRawString> original_names(1, zone());
1283       ParseExportClause(&export_names, &export_locations, &original_names,
1284                         &reserved_loc, CHECK_OK);
1285       const AstRawString* module_specifier = nullptr;
1286       Scanner::Location specifier_loc;
1287       if (CheckContextualKeyword(Token::FROM)) {
1288         specifier_loc = scanner()->peek_location();
1289         module_specifier = ParseModuleSpecifier(CHECK_OK);
1290       } else if (reserved_loc.IsValid()) {
1291         // No FromClause, so reserved words are invalid in ExportClause.
1292         *ok = false;
1293         ReportMessageAt(reserved_loc, MessageTemplate::kUnexpectedReserved);
1294         return nullptr;
1295       }
1296       ExpectSemicolon(CHECK_OK);
1297       const int length = export_names.length();
1298       DCHECK_EQ(length, original_names.length());
1299       DCHECK_EQ(length, export_locations.length());
1300       if (module_specifier == nullptr) {
1301         for (int i = 0; i < length; ++i) {
1302           module()->AddExport(original_names[i], export_names[i],
1303                               export_locations[i], zone());
1304         }
1305       } else if (length == 0) {
1306         module()->AddEmptyImport(module_specifier, specifier_loc);
1307       } else {
1308         for (int i = 0; i < length; ++i) {
1309           module()->AddExport(original_names[i], export_names[i],
1310                               module_specifier, export_locations[i],
1311                               specifier_loc, zone());
1312         }
1313       }
1314       return factory()->NewEmptyStatement(pos);
1315     }
1316 
1317     case Token::FUNCTION:
1318       result = ParseHoistableDeclaration(&names, false, CHECK_OK);
1319       break;
1320 
1321     case Token::CLASS:
1322       Consume(Token::CLASS);
1323       result = ParseClassDeclaration(&names, false, CHECK_OK);
1324       break;
1325 
1326     case Token::VAR:
1327     case Token::LET:
1328     case Token::CONST:
1329       result = ParseVariableStatement(kStatementListItem, &names, CHECK_OK);
1330       break;
1331 
1332     case Token::ASYNC:
1333       // TODO(neis): Why don't we have the same check here as in
1334       // ParseStatementListItem?
1335       Consume(Token::ASYNC);
1336       result = ParseAsyncFunctionDeclaration(&names, false, CHECK_OK);
1337       break;
1338 
1339     default:
1340       *ok = false;
1341       ReportUnexpectedToken(scanner()->current_token());
1342       return nullptr;
1343   }
1344   loc.end_pos = scanner()->location().end_pos;
1345 
1346   ModuleDescriptor* descriptor = module();
1347   for (int i = 0; i < names.length(); ++i) {
1348     descriptor->AddExport(names[i], names[i], loc, zone());
1349   }
1350 
1351   DCHECK_NOT_NULL(result);
1352   return result;
1353 }
1354 
NewUnresolved(const AstRawString * name,int begin_pos,VariableKind kind)1355 VariableProxy* Parser::NewUnresolved(const AstRawString* name, int begin_pos,
1356                                      VariableKind kind) {
1357   return scope()->NewUnresolved(factory(), name, begin_pos, kind);
1358 }
1359 
NewUnresolved(const AstRawString * name)1360 VariableProxy* Parser::NewUnresolved(const AstRawString* name) {
1361   return scope()->NewUnresolved(factory(), name, scanner()->location().beg_pos);
1362 }
1363 
DeclareVariable(const AstRawString * name,VariableMode mode,int pos,bool * ok)1364 Declaration* Parser::DeclareVariable(const AstRawString* name,
1365                                      VariableMode mode, int pos, bool* ok) {
1366   return DeclareVariable(name, mode, Variable::DefaultInitializationFlag(mode),
1367                          pos, ok);
1368 }
1369 
DeclareVariable(const AstRawString * name,VariableMode mode,InitializationFlag init,int pos,bool * ok)1370 Declaration* Parser::DeclareVariable(const AstRawString* name,
1371                                      VariableMode mode, InitializationFlag init,
1372                                      int pos, bool* ok) {
1373   DCHECK_NOT_NULL(name);
1374   VariableProxy* proxy = factory()->NewVariableProxy(
1375       name, NORMAL_VARIABLE, scanner()->location().beg_pos);
1376   Declaration* declaration;
1377   if (mode == VAR && !scope()->is_declaration_scope()) {
1378     DCHECK(scope()->is_block_scope() || scope()->is_with_scope());
1379     declaration = factory()->NewNestedVariableDeclaration(proxy, scope(), pos);
1380   } else {
1381     declaration = factory()->NewVariableDeclaration(proxy, pos);
1382   }
1383   Declare(declaration, DeclarationDescriptor::NORMAL, mode, init, ok, nullptr,
1384           scanner()->location().end_pos);
1385   if (!*ok) return nullptr;
1386   return declaration;
1387 }
1388 
Declare(Declaration * declaration,DeclarationDescriptor::Kind declaration_kind,VariableMode mode,InitializationFlag init,bool * ok,Scope * scope,int var_end_pos)1389 Variable* Parser::Declare(Declaration* declaration,
1390                           DeclarationDescriptor::Kind declaration_kind,
1391                           VariableMode mode, InitializationFlag init, bool* ok,
1392                           Scope* scope, int var_end_pos) {
1393   if (scope == nullptr) {
1394     scope = this->scope();
1395   }
1396   bool sloppy_mode_block_scope_function_redefinition = false;
1397   Variable* variable = scope->DeclareVariable(
1398       declaration, mode, init, &sloppy_mode_block_scope_function_redefinition,
1399       ok);
1400   if (!*ok) {
1401     // If we only have the start position of a proxy, we can't highlight the
1402     // whole variable name.  Pretend its length is 1 so that we highlight at
1403     // least the first character.
1404     Scanner::Location loc(declaration->proxy()->position(),
1405                           var_end_pos != kNoSourcePosition
1406                               ? var_end_pos
1407                               : declaration->proxy()->position() + 1);
1408     if (declaration_kind == DeclarationDescriptor::PARAMETER) {
1409       ReportMessageAt(loc, MessageTemplate::kParamDupe);
1410     } else {
1411       ReportMessageAt(loc, MessageTemplate::kVarRedeclaration,
1412                       declaration->proxy()->raw_name());
1413     }
1414     return nullptr;
1415   }
1416   if (sloppy_mode_block_scope_function_redefinition) {
1417     ++use_counts_[v8::Isolate::kSloppyModeBlockScopedFunctionRedefinition];
1418   }
1419   return variable;
1420 }
1421 
BuildInitializationBlock(DeclarationParsingResult * parsing_result,ZonePtrList<const AstRawString> * names,bool * ok)1422 Block* Parser::BuildInitializationBlock(
1423     DeclarationParsingResult* parsing_result,
1424     ZonePtrList<const AstRawString>* names, bool* ok) {
1425   Block* result = factory()->NewBlock(1, true);
1426   for (auto declaration : parsing_result->declarations) {
1427     DeclareAndInitializeVariables(result, &(parsing_result->descriptor),
1428                                   &declaration, names, CHECK_OK);
1429   }
1430   return result;
1431 }
1432 
DeclareFunction(const AstRawString * variable_name,FunctionLiteral * function,VariableMode mode,int pos,bool is_sloppy_block_function,ZonePtrList<const AstRawString> * names,bool * ok)1433 Statement* Parser::DeclareFunction(const AstRawString* variable_name,
1434                                    FunctionLiteral* function, VariableMode mode,
1435                                    int pos, bool is_sloppy_block_function,
1436                                    ZonePtrList<const AstRawString>* names,
1437                                    bool* ok) {
1438   VariableProxy* proxy =
1439       factory()->NewVariableProxy(variable_name, NORMAL_VARIABLE, pos);
1440   Declaration* declaration =
1441       factory()->NewFunctionDeclaration(proxy, function, pos);
1442   Declare(declaration, DeclarationDescriptor::NORMAL, mode, kCreatedInitialized,
1443           CHECK_OK);
1444   if (names) names->Add(variable_name, zone());
1445   if (is_sloppy_block_function) {
1446     SloppyBlockFunctionStatement* statement =
1447         factory()->NewSloppyBlockFunctionStatement();
1448     GetDeclarationScope()->DeclareSloppyBlockFunction(variable_name, scope(),
1449                                                       statement);
1450     return statement;
1451   }
1452   return factory()->NewEmptyStatement(kNoSourcePosition);
1453 }
1454 
DeclareClass(const AstRawString * variable_name,Expression * value,ZonePtrList<const AstRawString> * names,int class_token_pos,int end_pos,bool * ok)1455 Statement* Parser::DeclareClass(const AstRawString* variable_name,
1456                                 Expression* value,
1457                                 ZonePtrList<const AstRawString>* names,
1458                                 int class_token_pos, int end_pos, bool* ok) {
1459   Declaration* decl =
1460       DeclareVariable(variable_name, LET, class_token_pos, CHECK_OK);
1461   decl->proxy()->var()->set_initializer_position(end_pos);
1462   if (names) names->Add(variable_name, zone());
1463 
1464   Assignment* assignment = factory()->NewAssignment(Token::INIT, decl->proxy(),
1465                                                     value, class_token_pos);
1466   return IgnoreCompletion(
1467       factory()->NewExpressionStatement(assignment, kNoSourcePosition));
1468 }
1469 
DeclareNative(const AstRawString * name,int pos,bool * ok)1470 Statement* Parser::DeclareNative(const AstRawString* name, int pos, bool* ok) {
1471   // Make sure that the function containing the native declaration
1472   // isn't lazily compiled. The extension structures are only
1473   // accessible while parsing the first time not when reparsing
1474   // because of lazy compilation.
1475   GetClosureScope()->ForceEagerCompilation();
1476 
1477   // TODO(1240846): It's weird that native function declarations are
1478   // introduced dynamically when we meet their declarations, whereas
1479   // other functions are set up when entering the surrounding scope.
1480   Declaration* decl = DeclareVariable(name, VAR, pos, CHECK_OK);
1481   NativeFunctionLiteral* lit =
1482       factory()->NewNativeFunctionLiteral(name, extension_, kNoSourcePosition);
1483   return factory()->NewExpressionStatement(
1484       factory()->NewAssignment(Token::INIT, decl->proxy(), lit,
1485                                kNoSourcePosition),
1486       pos);
1487 }
1488 
DeclareLabel(ZonePtrList<const AstRawString> * labels,VariableProxy * var,bool * ok)1489 ZonePtrList<const AstRawString>* Parser::DeclareLabel(
1490     ZonePtrList<const AstRawString>* labels, VariableProxy* var, bool* ok) {
1491   DCHECK(IsIdentifier(var));
1492   const AstRawString* label = var->raw_name();
1493   // TODO(1240780): We don't check for redeclaration of labels
1494   // during preparsing since keeping track of the set of active
1495   // labels requires nontrivial changes to the way scopes are
1496   // structured.  However, these are probably changes we want to
1497   // make later anyway so we should go back and fix this then.
1498   if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) {
1499     ReportMessage(MessageTemplate::kLabelRedeclaration, label);
1500     *ok = false;
1501     return nullptr;
1502   }
1503   if (labels == nullptr) {
1504     labels = new (zone()) ZonePtrList<const AstRawString>(1, zone());
1505   }
1506   labels->Add(label, zone());
1507   // Remove the "ghost" variable that turned out to be a label
1508   // from the top scope. This way, we don't try to resolve it
1509   // during the scope processing.
1510   scope()->RemoveUnresolved(var);
1511   return labels;
1512 }
1513 
ContainsLabel(ZonePtrList<const AstRawString> * labels,const AstRawString * label)1514 bool Parser::ContainsLabel(ZonePtrList<const AstRawString>* labels,
1515                            const AstRawString* label) {
1516   DCHECK_NOT_NULL(label);
1517   if (labels != nullptr) {
1518     for (int i = labels->length(); i-- > 0;) {
1519       if (labels->at(i) == label) return true;
1520     }
1521   }
1522   return false;
1523 }
1524 
IgnoreCompletion(Statement * statement)1525 Block* Parser::IgnoreCompletion(Statement* statement) {
1526   Block* block = factory()->NewBlock(1, true);
1527   block->statements()->Add(statement, zone());
1528   return block;
1529 }
1530 
RewriteReturn(Expression * return_value,int pos)1531 Expression* Parser::RewriteReturn(Expression* return_value, int pos) {
1532   if (IsDerivedConstructor(function_state_->kind())) {
1533     // For subclass constructors we need to return this in case of undefined;
1534     // other primitive values trigger an exception in the ConstructStub.
1535     //
1536     //   return expr;
1537     //
1538     // Is rewritten as:
1539     //
1540     //   return (temp = expr) === undefined ? this : temp;
1541 
1542     // temp = expr
1543     Variable* temp = NewTemporary(ast_value_factory()->empty_string());
1544     Assignment* assign = factory()->NewAssignment(
1545         Token::ASSIGN, factory()->NewVariableProxy(temp), return_value, pos);
1546 
1547     // temp === undefined
1548     Expression* is_undefined = factory()->NewCompareOperation(
1549         Token::EQ_STRICT, assign,
1550         factory()->NewUndefinedLiteral(kNoSourcePosition), pos);
1551 
1552     // is_undefined ? this : temp
1553     return_value =
1554         factory()->NewConditional(is_undefined, ThisExpression(pos),
1555                                   factory()->NewVariableProxy(temp), pos);
1556   }
1557   return return_value;
1558 }
1559 
RewriteDoExpression(Block * body,int pos,bool * ok)1560 Expression* Parser::RewriteDoExpression(Block* body, int pos, bool* ok) {
1561   Variable* result = NewTemporary(ast_value_factory()->dot_result_string());
1562   DoExpression* expr = factory()->NewDoExpression(body, result, pos);
1563   if (!Rewriter::Rewrite(this, GetClosureScope(), expr, ast_value_factory())) {
1564     *ok = false;
1565     return nullptr;
1566   }
1567   return expr;
1568 }
1569 
RewriteSwitchStatement(SwitchStatement * switch_statement,Scope * scope)1570 Statement* Parser::RewriteSwitchStatement(SwitchStatement* switch_statement,
1571                                           Scope* scope) {
1572   // In order to get the CaseClauses to execute in their own lexical scope,
1573   // but without requiring downstream code to have special scope handling
1574   // code for switch statements, desugar into blocks as follows:
1575   // {  // To group the statements--harmless to evaluate Expression in scope
1576   //   .tag_variable = Expression;
1577   //   {  // To give CaseClauses a scope
1578   //     switch (.tag_variable) { CaseClause* }
1579   //   }
1580   // }
1581   DCHECK_NOT_NULL(scope);
1582   DCHECK(scope->is_block_scope());
1583   DCHECK_GE(switch_statement->position(), scope->start_position());
1584   DCHECK_LT(switch_statement->position(), scope->end_position());
1585 
1586   Block* switch_block = factory()->NewBlock(2, false);
1587 
1588   Expression* tag = switch_statement->tag();
1589   Variable* tag_variable =
1590       NewTemporary(ast_value_factory()->dot_switch_tag_string());
1591   Assignment* tag_assign = factory()->NewAssignment(
1592       Token::ASSIGN, factory()->NewVariableProxy(tag_variable), tag,
1593       tag->position());
1594   // Wrap with IgnoreCompletion so the tag isn't returned as the completion
1595   // value, in case the switch statements don't have a value.
1596   Statement* tag_statement = IgnoreCompletion(
1597       factory()->NewExpressionStatement(tag_assign, kNoSourcePosition));
1598   switch_block->statements()->Add(tag_statement, zone());
1599 
1600   switch_statement->set_tag(factory()->NewVariableProxy(tag_variable));
1601   Block* cases_block = factory()->NewBlock(1, false);
1602   cases_block->statements()->Add(switch_statement, zone());
1603   cases_block->set_scope(scope);
1604   switch_block->statements()->Add(cases_block, zone());
1605   return switch_block;
1606 }
1607 
RewriteCatchPattern(CatchInfo * catch_info,bool * ok)1608 void Parser::RewriteCatchPattern(CatchInfo* catch_info, bool* ok) {
1609   if (catch_info->name == nullptr) {
1610     DCHECK_NOT_NULL(catch_info->pattern);
1611     catch_info->name = ast_value_factory()->dot_catch_string();
1612   }
1613   Variable* catch_variable =
1614       catch_info->scope->DeclareLocal(catch_info->name, VAR);
1615   if (catch_info->pattern != nullptr) {
1616     DeclarationDescriptor descriptor;
1617     descriptor.declaration_kind = DeclarationDescriptor::NORMAL;
1618     descriptor.scope = scope();
1619     descriptor.mode = LET;
1620     descriptor.declaration_pos = catch_info->pattern->position();
1621     descriptor.initialization_pos = catch_info->pattern->position();
1622 
1623     // Initializer position for variables declared by the pattern.
1624     const int initializer_position = position();
1625 
1626     DeclarationParsingResult::Declaration decl(
1627         catch_info->pattern, initializer_position,
1628         factory()->NewVariableProxy(catch_variable));
1629 
1630     catch_info->init_block = factory()->NewBlock(8, true);
1631     DeclareAndInitializeVariables(catch_info->init_block, &descriptor, &decl,
1632                                   &catch_info->bound_names, ok);
1633   } else {
1634     catch_info->bound_names.Add(catch_info->name, zone());
1635   }
1636 }
1637 
ValidateCatchBlock(const CatchInfo & catch_info,bool * ok)1638 void Parser::ValidateCatchBlock(const CatchInfo& catch_info, bool* ok) {
1639   // Check for `catch(e) { let e; }` and similar errors.
1640   Scope* inner_block_scope = catch_info.inner_block->scope();
1641   if (inner_block_scope != nullptr) {
1642     Declaration* decl = inner_block_scope->CheckLexDeclarationsConflictingWith(
1643         catch_info.bound_names);
1644     if (decl != nullptr) {
1645       const AstRawString* name = decl->proxy()->raw_name();
1646       int position = decl->proxy()->position();
1647       Scanner::Location location =
1648           position == kNoSourcePosition
1649               ? Scanner::Location::invalid()
1650               : Scanner::Location(position, position + 1);
1651       ReportMessageAt(location, MessageTemplate::kVarRedeclaration, name);
1652       *ok = false;
1653     }
1654   }
1655 }
1656 
RewriteTryStatement(Block * try_block,Block * catch_block,const SourceRange & catch_range,Block * finally_block,const SourceRange & finally_range,const CatchInfo & catch_info,int pos)1657 Statement* Parser::RewriteTryStatement(Block* try_block, Block* catch_block,
1658                                        const SourceRange& catch_range,
1659                                        Block* finally_block,
1660                                        const SourceRange& finally_range,
1661                                        const CatchInfo& catch_info, int pos) {
1662   // Simplify the AST nodes by converting:
1663   //   'try B0 catch B1 finally B2'
1664   // to:
1665   //   'try { try B0 catch B1 } finally B2'
1666 
1667   if (catch_block != nullptr && finally_block != nullptr) {
1668     // If we have both, create an inner try/catch.
1669     TryCatchStatement* statement;
1670     statement = factory()->NewTryCatchStatement(try_block, catch_info.scope,
1671                                                 catch_block, kNoSourcePosition);
1672     RecordTryCatchStatementSourceRange(statement, catch_range);
1673 
1674     try_block = factory()->NewBlock(1, false);
1675     try_block->statements()->Add(statement, zone());
1676     catch_block = nullptr;  // Clear to indicate it's been handled.
1677   }
1678 
1679   if (catch_block != nullptr) {
1680     DCHECK_NULL(finally_block);
1681     TryCatchStatement* stmt = factory()->NewTryCatchStatement(
1682         try_block, catch_info.scope, catch_block, pos);
1683     RecordTryCatchStatementSourceRange(stmt, catch_range);
1684     return stmt;
1685   } else {
1686     DCHECK_NOT_NULL(finally_block);
1687     TryFinallyStatement* stmt =
1688         factory()->NewTryFinallyStatement(try_block, finally_block, pos);
1689     RecordTryFinallyStatementSourceRange(stmt, finally_range);
1690     return stmt;
1691   }
1692 }
1693 
ParseAndRewriteGeneratorFunctionBody(int pos,FunctionKind kind,ZonePtrList<Statement> * body,bool * ok)1694 void Parser::ParseAndRewriteGeneratorFunctionBody(int pos, FunctionKind kind,
1695                                                   ZonePtrList<Statement>* body,
1696                                                   bool* ok) {
1697   // For ES6 Generators, we just prepend the initial yield.
1698   Expression* initial_yield = BuildInitialYield(pos, kind);
1699   body->Add(factory()->NewExpressionStatement(initial_yield, kNoSourcePosition),
1700             zone());
1701   ParseStatementList(body, Token::RBRACE, ok);
1702 }
1703 
ParseAndRewriteAsyncGeneratorFunctionBody(int pos,FunctionKind kind,ZonePtrList<Statement> * body,bool * ok)1704 void Parser::ParseAndRewriteAsyncGeneratorFunctionBody(
1705     int pos, FunctionKind kind, ZonePtrList<Statement>* body, bool* ok) {
1706   // For ES2017 Async Generators, we produce:
1707   //
1708   // try {
1709   //   InitialYield;
1710   //   ...body...;
1711   //   return undefined; // See comment below
1712   // } catch (.catch) {
1713   //   %AsyncGeneratorReject(generator, .catch);
1714   // } finally {
1715   //   %_GeneratorClose(generator);
1716   // }
1717   //
1718   // - InitialYield yields the actual generator object.
1719   // - Any return statement inside the body will have its argument wrapped
1720   //   in an iterator result object with a "done" property set to `true`.
1721   // - If the generator terminates for whatever reason, we must close it.
1722   //   Hence the finally clause.
1723   // - BytecodeGenerator performs special handling for ReturnStatements in
1724   //   async generator functions, resolving the appropriate Promise with an
1725   //   "done" iterator result object containing a Promise-unwrapped value.
1726   DCHECK(IsAsyncGeneratorFunction(kind));
1727 
1728   Block* try_block = factory()->NewBlock(3, false);
1729   Expression* initial_yield = BuildInitialYield(pos, kind);
1730   try_block->statements()->Add(
1731       factory()->NewExpressionStatement(initial_yield, kNoSourcePosition),
1732       zone());
1733   ParseStatementList(try_block->statements(), Token::RBRACE, ok);
1734   if (!*ok) return;
1735 
1736   // Don't create iterator result for async generators, as the resume methods
1737   // will create it.
1738   // TODO(leszeks): This will create another suspend point, which is unnecessary
1739   // if there is already an unconditional return in the body.
1740   Statement* final_return = BuildReturnStatement(
1741       factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition);
1742   try_block->statements()->Add(final_return, zone());
1743 
1744   // For AsyncGenerators, a top-level catch block will reject the Promise.
1745   Scope* catch_scope = NewHiddenCatchScope();
1746 
1747   ZonePtrList<Expression>* reject_args =
1748       new (zone()) ZonePtrList<Expression>(2, zone());
1749   reject_args->Add(factory()->NewVariableProxy(
1750                        function_state_->scope()->generator_object_var()),
1751                    zone());
1752   reject_args->Add(factory()->NewVariableProxy(catch_scope->catch_variable()),
1753                    zone());
1754 
1755   Expression* reject_call = factory()->NewCallRuntime(
1756       Runtime::kInlineAsyncGeneratorReject, reject_args, kNoSourcePosition);
1757   Block* catch_block = IgnoreCompletion(
1758       factory()->NewReturnStatement(reject_call, kNoSourcePosition));
1759 
1760   TryStatement* try_catch = factory()->NewTryCatchStatementForAsyncAwait(
1761       try_block, catch_scope, catch_block, kNoSourcePosition);
1762 
1763   try_block = factory()->NewBlock(1, false);
1764   try_block->statements()->Add(try_catch, zone());
1765 
1766   Block* finally_block = factory()->NewBlock(1, false);
1767   ZonePtrList<Expression>* close_args =
1768       new (zone()) ZonePtrList<Expression>(1, zone());
1769   VariableProxy* call_proxy = factory()->NewVariableProxy(
1770       function_state_->scope()->generator_object_var());
1771   close_args->Add(call_proxy, zone());
1772   Expression* close_call = factory()->NewCallRuntime(
1773       Runtime::kInlineGeneratorClose, close_args, kNoSourcePosition);
1774   finally_block->statements()->Add(
1775       factory()->NewExpressionStatement(close_call, kNoSourcePosition), zone());
1776 
1777   body->Add(factory()->NewTryFinallyStatement(try_block, finally_block,
1778                                               kNoSourcePosition),
1779             zone());
1780 }
1781 
DeclareFunctionNameVar(const AstRawString * function_name,FunctionLiteral::FunctionType function_type,DeclarationScope * function_scope)1782 void Parser::DeclareFunctionNameVar(const AstRawString* function_name,
1783                                     FunctionLiteral::FunctionType function_type,
1784                                     DeclarationScope* function_scope) {
1785   if (function_type == FunctionLiteral::kNamedExpression &&
1786       function_scope->LookupLocal(function_name) == nullptr) {
1787     DCHECK_EQ(function_scope, scope());
1788     function_scope->DeclareFunctionVar(function_name);
1789   }
1790 }
1791 
1792 // [if (IteratorType == kNormal)]
1793 //     !%_IsJSReceiver(result = iterator.next()) &&
1794 //         %ThrowIteratorResultNotAnObject(result)
1795 // [else if (IteratorType == kAsync)]
1796 //     !%_IsJSReceiver(result = Await(iterator.next())) &&
1797 //         %ThrowIteratorResultNotAnObject(result)
1798 // [endif]
BuildIteratorNextResult(VariableProxy * iterator,VariableProxy * next,Variable * result,IteratorType type,int pos)1799 Expression* Parser::BuildIteratorNextResult(VariableProxy* iterator,
1800                                             VariableProxy* next,
1801                                             Variable* result, IteratorType type,
1802                                             int pos) {
1803   Expression* next_property = factory()->NewResolvedProperty(iterator, next);
1804   ZonePtrList<Expression>* next_arguments =
1805       new (zone()) ZonePtrList<Expression>(0, zone());
1806   Expression* next_call =
1807       factory()->NewCall(next_property, next_arguments, kNoSourcePosition);
1808   if (type == IteratorType::kAsync) {
1809     function_state_->AddSuspend();
1810     next_call = factory()->NewAwait(next_call, pos);
1811   }
1812   Expression* result_proxy = factory()->NewVariableProxy(result);
1813   Expression* left =
1814       factory()->NewAssignment(Token::ASSIGN, result_proxy, next_call, pos);
1815 
1816   // %_IsJSReceiver(...)
1817   ZonePtrList<Expression>* is_spec_object_args =
1818       new (zone()) ZonePtrList<Expression>(1, zone());
1819   is_spec_object_args->Add(left, zone());
1820   Expression* is_spec_object_call = factory()->NewCallRuntime(
1821       Runtime::kInlineIsJSReceiver, is_spec_object_args, pos);
1822 
1823   // %ThrowIteratorResultNotAnObject(result)
1824   Expression* result_proxy_again = factory()->NewVariableProxy(result);
1825   ZonePtrList<Expression>* throw_arguments =
1826       new (zone()) ZonePtrList<Expression>(1, zone());
1827   throw_arguments->Add(result_proxy_again, zone());
1828   Expression* throw_call = factory()->NewCallRuntime(
1829       Runtime::kThrowIteratorResultNotAnObject, throw_arguments, pos);
1830 
1831   return factory()->NewBinaryOperation(
1832       Token::AND,
1833       factory()->NewUnaryOperation(Token::NOT, is_spec_object_call, pos),
1834       throw_call, pos);
1835 }
1836 
InitializeForEachStatement(ForEachStatement * stmt,Expression * each,Expression * subject,Statement * body)1837 Statement* Parser::InitializeForEachStatement(ForEachStatement* stmt,
1838                                               Expression* each,
1839                                               Expression* subject,
1840                                               Statement* body) {
1841   ForOfStatement* for_of = stmt->AsForOfStatement();
1842   if (for_of != nullptr) {
1843     const bool finalize = true;
1844     return InitializeForOfStatement(for_of, each, subject, body, finalize,
1845                                     IteratorType::kNormal, each->position());
1846   } else {
1847     if (each->IsArrayLiteral() || each->IsObjectLiteral()) {
1848       Variable* temp = NewTemporary(ast_value_factory()->empty_string());
1849       VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
1850       Expression* assign_each =
1851           RewriteDestructuringAssignment(factory()->NewAssignment(
1852               Token::ASSIGN, each, temp_proxy, kNoSourcePosition));
1853       auto block = factory()->NewBlock(2, false);
1854       block->statements()->Add(
1855           factory()->NewExpressionStatement(assign_each, kNoSourcePosition),
1856           zone());
1857       block->statements()->Add(body, zone());
1858       body = block;
1859       each = factory()->NewVariableProxy(temp);
1860     }
1861     MarkExpressionAsAssigned(each);
1862     stmt->AsForInStatement()->Initialize(each, subject, body);
1863   }
1864   return stmt;
1865 }
1866 
1867 // Special case for legacy for
1868 //
1869 //    for (var x = initializer in enumerable) body
1870 //
1871 // An initialization block of the form
1872 //
1873 //    {
1874 //      x = initializer;
1875 //    }
1876 //
1877 // is returned in this case.  It has reserved space for two statements,
1878 // so that (later on during parsing), the equivalent of
1879 //
1880 //   for (x in enumerable) body
1881 //
1882 // is added as a second statement to it.
RewriteForVarInLegacy(const ForInfo & for_info)1883 Block* Parser::RewriteForVarInLegacy(const ForInfo& for_info) {
1884   const DeclarationParsingResult::Declaration& decl =
1885       for_info.parsing_result.declarations[0];
1886   if (!IsLexicalVariableMode(for_info.parsing_result.descriptor.mode) &&
1887       decl.pattern->IsVariableProxy() && decl.initializer != nullptr) {
1888     ++use_counts_[v8::Isolate::kForInInitializer];
1889     const AstRawString* name = decl.pattern->AsVariableProxy()->raw_name();
1890     VariableProxy* single_var = NewUnresolved(name);
1891     Block* init_block = factory()->NewBlock(2, true);
1892     init_block->statements()->Add(
1893         factory()->NewExpressionStatement(
1894             factory()->NewAssignment(Token::ASSIGN, single_var,
1895                                      decl.initializer, kNoSourcePosition),
1896             kNoSourcePosition),
1897         zone());
1898     return init_block;
1899   }
1900   return nullptr;
1901 }
1902 
1903 // Rewrite a for-in/of statement of the form
1904 //
1905 //   for (let/const/var x in/of e) b
1906 //
1907 // into
1908 //
1909 //   {
1910 //     var temp;
1911 //     for (temp in/of e) {
1912 //       let/const/var x = temp;
1913 //       b;
1914 //     }
1915 //     let x;  // for TDZ
1916 //   }
DesugarBindingInForEachStatement(ForInfo * for_info,Block ** body_block,Expression ** each_variable,bool * ok)1917 void Parser::DesugarBindingInForEachStatement(ForInfo* for_info,
1918                                               Block** body_block,
1919                                               Expression** each_variable,
1920                                               bool* ok) {
1921   DCHECK_EQ(1, for_info->parsing_result.declarations.size());
1922   DeclarationParsingResult::Declaration& decl =
1923       for_info->parsing_result.declarations[0];
1924   Variable* temp = NewTemporary(ast_value_factory()->dot_for_string());
1925   auto each_initialization_block = factory()->NewBlock(1, true);
1926   {
1927     auto descriptor = for_info->parsing_result.descriptor;
1928     descriptor.declaration_pos = kNoSourcePosition;
1929     descriptor.initialization_pos = kNoSourcePosition;
1930     descriptor.scope = scope();
1931     decl.initializer = factory()->NewVariableProxy(temp);
1932 
1933     bool is_for_var_of =
1934         for_info->mode == ForEachStatement::ITERATE &&
1935         for_info->parsing_result.descriptor.mode == VariableMode::VAR;
1936     bool collect_names =
1937         IsLexicalVariableMode(for_info->parsing_result.descriptor.mode) ||
1938         is_for_var_of;
1939 
1940     DeclareAndInitializeVariables(
1941         each_initialization_block, &descriptor, &decl,
1942         collect_names ? &for_info->bound_names : nullptr, CHECK_OK_VOID);
1943 
1944     // Annex B.3.5 prohibits the form
1945     // `try {} catch(e) { for (var e of {}); }`
1946     // So if we are parsing a statement like `for (var ... of ...)`
1947     // we need to walk up the scope chain and look for catch scopes
1948     // which have a simple binding, then compare their binding against
1949     // all of the names declared in the init of the for-of we're
1950     // parsing.
1951     if (is_for_var_of) {
1952       Scope* catch_scope = scope();
1953       while (catch_scope != nullptr && !catch_scope->is_declaration_scope()) {
1954         if (catch_scope->is_catch_scope()) {
1955           auto name = catch_scope->catch_variable()->raw_name();
1956           // If it's a simple binding and the name is declared in the for loop.
1957           if (name != ast_value_factory()->dot_catch_string() &&
1958               for_info->bound_names.Contains(name)) {
1959             ReportMessageAt(for_info->parsing_result.bindings_loc,
1960                             MessageTemplate::kVarRedeclaration, name);
1961             *ok = false;
1962             return;
1963           }
1964         }
1965         catch_scope = catch_scope->outer_scope();
1966       }
1967     }
1968   }
1969 
1970   *body_block = factory()->NewBlock(3, false);
1971   (*body_block)->statements()->Add(each_initialization_block, zone());
1972   *each_variable = factory()->NewVariableProxy(temp, for_info->position);
1973 }
1974 
1975 // Create a TDZ for any lexically-bound names in for in/of statements.
CreateForEachStatementTDZ(Block * init_block,const ForInfo & for_info,bool * ok)1976 Block* Parser::CreateForEachStatementTDZ(Block* init_block,
1977                                          const ForInfo& for_info, bool* ok) {
1978   if (IsLexicalVariableMode(for_info.parsing_result.descriptor.mode)) {
1979     DCHECK_NULL(init_block);
1980 
1981     init_block = factory()->NewBlock(1, false);
1982 
1983     for (int i = 0; i < for_info.bound_names.length(); ++i) {
1984       // TODO(adamk): This needs to be some sort of special
1985       // INTERNAL variable that's invisible to the debugger
1986       // but visible to everything else.
1987       Declaration* tdz_decl = DeclareVariable(for_info.bound_names[i], LET,
1988                                               kNoSourcePosition, CHECK_OK);
1989       tdz_decl->proxy()->var()->set_initializer_position(position());
1990     }
1991   }
1992   return init_block;
1993 }
1994 
InitializeForOfStatement(ForOfStatement * for_of,Expression * each,Expression * iterable,Statement * body,bool finalize,IteratorType type,int next_result_pos)1995 Statement* Parser::InitializeForOfStatement(
1996     ForOfStatement* for_of, Expression* each, Expression* iterable,
1997     Statement* body, bool finalize, IteratorType type, int next_result_pos) {
1998   // Create the auxiliary expressions needed for iterating over the iterable,
1999   // and initialize the given ForOfStatement with them.
2000   // If finalize is true, also instrument the loop with code that performs the
2001   // proper ES6 iterator finalization.  In that case, the result is not
2002   // immediately a ForOfStatement.
2003   const int nopos = kNoSourcePosition;
2004   auto avfactory = ast_value_factory();
2005 
2006   Variable* iterator = NewTemporary(avfactory->dot_iterator_string());
2007   Variable* next = NewTemporary(avfactory->empty_string());
2008   Variable* result = NewTemporary(avfactory->dot_result_string());
2009   Variable* completion = NewTemporary(avfactory->empty_string());
2010 
2011   // iterator = GetIterator(iterable, type)
2012   Expression* assign_iterator;
2013   {
2014     assign_iterator = factory()->NewAssignment(
2015         Token::ASSIGN, factory()->NewVariableProxy(iterator),
2016         factory()->NewGetIterator(iterable, type, iterable->position()),
2017         iterable->position());
2018   }
2019 
2020   Expression* assign_next;
2021   {
2022     assign_next = factory()->NewAssignment(
2023         Token::ASSIGN, factory()->NewVariableProxy(next),
2024         factory()->NewProperty(factory()->NewVariableProxy(iterator),
2025                                factory()->NewStringLiteral(
2026                                    avfactory->next_string(), kNoSourcePosition),
2027                                kNoSourcePosition),
2028         kNoSourcePosition);
2029   }
2030 
2031   // [if (IteratorType == kNormal)]
2032   //     !%_IsJSReceiver(result = iterator.next()) &&
2033   //         %ThrowIteratorResultNotAnObject(result)
2034   // [else if (IteratorType == kAsync)]
2035   //     !%_IsJSReceiver(result = Await(iterator.next())) &&
2036   //         %ThrowIteratorResultNotAnObject(result)
2037   // [endif]
2038   Expression* next_result;
2039   {
2040     VariableProxy* iterator_proxy = factory()->NewVariableProxy(iterator);
2041     VariableProxy* next_proxy = factory()->NewVariableProxy(next);
2042     next_result = BuildIteratorNextResult(iterator_proxy, next_proxy, result,
2043                                           type, next_result_pos);
2044   }
2045 
2046   // result.done
2047   Expression* result_done;
2048   {
2049     Expression* done_literal = factory()->NewStringLiteral(
2050         ast_value_factory()->done_string(), kNoSourcePosition);
2051     Expression* result_proxy = factory()->NewVariableProxy(result);
2052     result_done =
2053         factory()->NewProperty(result_proxy, done_literal, kNoSourcePosition);
2054   }
2055 
2056   // result.value
2057   Expression* result_value;
2058   {
2059     Expression* value_literal =
2060         factory()->NewStringLiteral(avfactory->value_string(), nopos);
2061     Expression* result_proxy = factory()->NewVariableProxy(result);
2062     result_value = factory()->NewProperty(result_proxy, value_literal, nopos);
2063   }
2064 
2065   // {{tmp = #result_value, completion = kAbruptCompletion, tmp}}
2066   // Expression* result_value (gets overwritten)
2067   if (finalize) {
2068     Variable* tmp = NewTemporary(avfactory->empty_string());
2069     Expression* save_result = factory()->NewAssignment(
2070         Token::ASSIGN, factory()->NewVariableProxy(tmp), result_value, nopos);
2071 
2072     Expression* set_completion_abrupt = factory()->NewAssignment(
2073         Token::ASSIGN, factory()->NewVariableProxy(completion),
2074         factory()->NewSmiLiteral(Parser::kAbruptCompletion, nopos), nopos);
2075 
2076     result_value = factory()->NewBinaryOperation(Token::COMMA, save_result,
2077                                                  set_completion_abrupt, nopos);
2078     result_value = factory()->NewBinaryOperation(
2079         Token::COMMA, result_value, factory()->NewVariableProxy(tmp), nopos);
2080   }
2081 
2082   // each = #result_value;
2083   Expression* assign_each;
2084   {
2085     assign_each =
2086         factory()->NewAssignment(Token::ASSIGN, each, result_value, nopos);
2087     if (each->IsArrayLiteral() || each->IsObjectLiteral()) {
2088       assign_each = RewriteDestructuringAssignment(assign_each->AsAssignment());
2089     }
2090   }
2091 
2092   // {{completion = kNormalCompletion;}}
2093   Statement* set_completion_normal;
2094   if (finalize) {
2095     Expression* proxy = factory()->NewVariableProxy(completion);
2096     Expression* assignment = factory()->NewAssignment(
2097         Token::ASSIGN, proxy,
2098         factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos);
2099 
2100     set_completion_normal =
2101         IgnoreCompletion(factory()->NewExpressionStatement(assignment, nopos));
2102   }
2103 
2104   // { #loop-body; #set_completion_normal }
2105   // Statement* body (gets overwritten)
2106   if (finalize) {
2107     Block* block = factory()->NewBlock(2, false);
2108     block->statements()->Add(body, zone());
2109     block->statements()->Add(set_completion_normal, zone());
2110     body = block;
2111   }
2112 
2113   for_of->Initialize(body, iterator, assign_iterator, assign_next, next_result,
2114                      result_done, assign_each);
2115   return finalize ? FinalizeForOfStatement(for_of, completion, type, nopos)
2116                   : for_of;
2117 }
2118 
DesugarLexicalBindingsInForStatement(ForStatement * loop,Statement * init,Expression * cond,Statement * next,Statement * body,Scope * inner_scope,const ForInfo & for_info,bool * ok)2119 Statement* Parser::DesugarLexicalBindingsInForStatement(
2120     ForStatement* loop, Statement* init, Expression* cond, Statement* next,
2121     Statement* body, Scope* inner_scope, const ForInfo& for_info, bool* ok) {
2122   // ES6 13.7.4.8 specifies that on each loop iteration the let variables are
2123   // copied into a new environment.  Moreover, the "next" statement must be
2124   // evaluated not in the environment of the just completed iteration but in
2125   // that of the upcoming one.  We achieve this with the following desugaring.
2126   // Extra care is needed to preserve the completion value of the original loop.
2127   //
2128   // We are given a for statement of the form
2129   //
2130   //  labels: for (let/const x = i; cond; next) body
2131   //
2132   // and rewrite it as follows.  Here we write {{ ... }} for init-blocks, ie.,
2133   // blocks whose ignore_completion_value_ flag is set.
2134   //
2135   //  {
2136   //    let/const x = i;
2137   //    temp_x = x;
2138   //    first = 1;
2139   //    undefined;
2140   //    outer: for (;;) {
2141   //      let/const x = temp_x;
2142   //      {{ if (first == 1) {
2143   //           first = 0;
2144   //         } else {
2145   //           next;
2146   //         }
2147   //         flag = 1;
2148   //         if (!cond) break;
2149   //      }}
2150   //      labels: for (; flag == 1; flag = 0, temp_x = x) {
2151   //        body
2152   //      }
2153   //      {{ if (flag == 1)  // Body used break.
2154   //           break;
2155   //      }}
2156   //    }
2157   //  }
2158 
2159   DCHECK_GT(for_info.bound_names.length(), 0);
2160   ZonePtrList<Variable> temps(for_info.bound_names.length(), zone());
2161 
2162   Block* outer_block =
2163       factory()->NewBlock(for_info.bound_names.length() + 4, false);
2164 
2165   // Add statement: let/const x = i.
2166   outer_block->statements()->Add(init, zone());
2167 
2168   const AstRawString* temp_name = ast_value_factory()->dot_for_string();
2169 
2170   // For each lexical variable x:
2171   //   make statement: temp_x = x.
2172   for (int i = 0; i < for_info.bound_names.length(); i++) {
2173     VariableProxy* proxy = NewUnresolved(for_info.bound_names[i]);
2174     Variable* temp = NewTemporary(temp_name);
2175     VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
2176     Assignment* assignment = factory()->NewAssignment(Token::ASSIGN, temp_proxy,
2177                                                       proxy, kNoSourcePosition);
2178     Statement* assignment_statement =
2179         factory()->NewExpressionStatement(assignment, kNoSourcePosition);
2180     outer_block->statements()->Add(assignment_statement, zone());
2181     temps.Add(temp, zone());
2182   }
2183 
2184   Variable* first = nullptr;
2185   // Make statement: first = 1.
2186   if (next) {
2187     first = NewTemporary(temp_name);
2188     VariableProxy* first_proxy = factory()->NewVariableProxy(first);
2189     Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
2190     Assignment* assignment = factory()->NewAssignment(
2191         Token::ASSIGN, first_proxy, const1, kNoSourcePosition);
2192     Statement* assignment_statement =
2193         factory()->NewExpressionStatement(assignment, kNoSourcePosition);
2194     outer_block->statements()->Add(assignment_statement, zone());
2195   }
2196 
2197   // make statement: undefined;
2198   outer_block->statements()->Add(
2199       factory()->NewExpressionStatement(
2200           factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition),
2201       zone());
2202 
2203   // Make statement: outer: for (;;)
2204   // Note that we don't actually create the label, or set this loop up as an
2205   // explicit break target, instead handing it directly to those nodes that
2206   // need to know about it. This should be safe because we don't run any code
2207   // in this function that looks up break targets.
2208   ForStatement* outer_loop =
2209       factory()->NewForStatement(nullptr, kNoSourcePosition);
2210   outer_block->statements()->Add(outer_loop, zone());
2211   outer_block->set_scope(scope());
2212 
2213   Block* inner_block = factory()->NewBlock(3, false);
2214   {
2215     BlockState block_state(&scope_, inner_scope);
2216 
2217     Block* ignore_completion_block =
2218         factory()->NewBlock(for_info.bound_names.length() + 3, true);
2219     ZonePtrList<Variable> inner_vars(for_info.bound_names.length(), zone());
2220     // For each let variable x:
2221     //    make statement: let/const x = temp_x.
2222     for (int i = 0; i < for_info.bound_names.length(); i++) {
2223       Declaration* decl = DeclareVariable(
2224           for_info.bound_names[i], for_info.parsing_result.descriptor.mode,
2225           kNoSourcePosition, CHECK_OK);
2226       inner_vars.Add(decl->proxy()->var(), zone());
2227       VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
2228       Assignment* assignment = factory()->NewAssignment(
2229           Token::INIT, decl->proxy(), temp_proxy, kNoSourcePosition);
2230       Statement* assignment_statement =
2231           factory()->NewExpressionStatement(assignment, kNoSourcePosition);
2232       int declaration_pos = for_info.parsing_result.descriptor.declaration_pos;
2233       DCHECK_NE(declaration_pos, kNoSourcePosition);
2234       decl->proxy()->var()->set_initializer_position(declaration_pos);
2235       ignore_completion_block->statements()->Add(assignment_statement, zone());
2236     }
2237 
2238     // Make statement: if (first == 1) { first = 0; } else { next; }
2239     if (next) {
2240       DCHECK(first);
2241       Expression* compare = nullptr;
2242       // Make compare expression: first == 1.
2243       {
2244         Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
2245         VariableProxy* first_proxy = factory()->NewVariableProxy(first);
2246         compare = factory()->NewCompareOperation(Token::EQ, first_proxy, const1,
2247                                                  kNoSourcePosition);
2248       }
2249       Statement* clear_first = nullptr;
2250       // Make statement: first = 0.
2251       {
2252         VariableProxy* first_proxy = factory()->NewVariableProxy(first);
2253         Expression* const0 = factory()->NewSmiLiteral(0, kNoSourcePosition);
2254         Assignment* assignment = factory()->NewAssignment(
2255             Token::ASSIGN, first_proxy, const0, kNoSourcePosition);
2256         clear_first =
2257             factory()->NewExpressionStatement(assignment, kNoSourcePosition);
2258       }
2259       Statement* clear_first_or_next = factory()->NewIfStatement(
2260           compare, clear_first, next, kNoSourcePosition);
2261       ignore_completion_block->statements()->Add(clear_first_or_next, zone());
2262     }
2263 
2264     Variable* flag = NewTemporary(temp_name);
2265     // Make statement: flag = 1.
2266     {
2267       VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
2268       Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
2269       Assignment* assignment = factory()->NewAssignment(
2270           Token::ASSIGN, flag_proxy, const1, kNoSourcePosition);
2271       Statement* assignment_statement =
2272           factory()->NewExpressionStatement(assignment, kNoSourcePosition);
2273       ignore_completion_block->statements()->Add(assignment_statement, zone());
2274     }
2275 
2276     // Make statement: if (!cond) break.
2277     if (cond) {
2278       Statement* stop =
2279           factory()->NewBreakStatement(outer_loop, kNoSourcePosition);
2280       Statement* noop = factory()->NewEmptyStatement(kNoSourcePosition);
2281       ignore_completion_block->statements()->Add(
2282           factory()->NewIfStatement(cond, noop, stop, cond->position()),
2283           zone());
2284     }
2285 
2286     inner_block->statements()->Add(ignore_completion_block, zone());
2287     // Make cond expression for main loop: flag == 1.
2288     Expression* flag_cond = nullptr;
2289     {
2290       Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
2291       VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
2292       flag_cond = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1,
2293                                                  kNoSourcePosition);
2294     }
2295 
2296     // Create chain of expressions "flag = 0, temp_x = x, ..."
2297     Statement* compound_next_statement = nullptr;
2298     {
2299       Expression* compound_next = nullptr;
2300       // Make expression: flag = 0.
2301       {
2302         VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
2303         Expression* const0 = factory()->NewSmiLiteral(0, kNoSourcePosition);
2304         compound_next = factory()->NewAssignment(Token::ASSIGN, flag_proxy,
2305                                                  const0, kNoSourcePosition);
2306       }
2307 
2308       // Make the comma-separated list of temp_x = x assignments.
2309       int inner_var_proxy_pos = scanner()->location().beg_pos;
2310       for (int i = 0; i < for_info.bound_names.length(); i++) {
2311         VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
2312         VariableProxy* proxy =
2313             factory()->NewVariableProxy(inner_vars.at(i), inner_var_proxy_pos);
2314         Assignment* assignment = factory()->NewAssignment(
2315             Token::ASSIGN, temp_proxy, proxy, kNoSourcePosition);
2316         compound_next = factory()->NewBinaryOperation(
2317             Token::COMMA, compound_next, assignment, kNoSourcePosition);
2318       }
2319 
2320       compound_next_statement =
2321           factory()->NewExpressionStatement(compound_next, kNoSourcePosition);
2322     }
2323 
2324     // Make statement: labels: for (; flag == 1; flag = 0, temp_x = x)
2325     // Note that we re-use the original loop node, which retains its labels
2326     // and ensures that any break or continue statements in body point to
2327     // the right place.
2328     loop->Initialize(nullptr, flag_cond, compound_next_statement, body);
2329     inner_block->statements()->Add(loop, zone());
2330 
2331     // Make statement: {{if (flag == 1) break;}}
2332     {
2333       Expression* compare = nullptr;
2334       // Make compare expresion: flag == 1.
2335       {
2336         Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
2337         VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
2338         compare = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1,
2339                                                  kNoSourcePosition);
2340       }
2341       Statement* stop =
2342           factory()->NewBreakStatement(outer_loop, kNoSourcePosition);
2343       Statement* empty = factory()->NewEmptyStatement(kNoSourcePosition);
2344       Statement* if_flag_break =
2345           factory()->NewIfStatement(compare, stop, empty, kNoSourcePosition);
2346       inner_block->statements()->Add(IgnoreCompletion(if_flag_break), zone());
2347     }
2348 
2349     inner_block->set_scope(inner_scope);
2350   }
2351 
2352   outer_loop->Initialize(nullptr, nullptr, nullptr, inner_block);
2353 
2354   return outer_block;
2355 }
2356 
AddArrowFunctionFormalParameters(ParserFormalParameters * parameters,Expression * expr,int end_pos,bool * ok)2357 void Parser::AddArrowFunctionFormalParameters(
2358     ParserFormalParameters* parameters, Expression* expr, int end_pos,
2359     bool* ok) {
2360   // ArrowFunctionFormals ::
2361   //    Nary(Token::COMMA, VariableProxy*, Tail)
2362   //    Binary(Token::COMMA, NonTailArrowFunctionFormals, Tail)
2363   //    Tail
2364   // NonTailArrowFunctionFormals ::
2365   //    Binary(Token::COMMA, NonTailArrowFunctionFormals, VariableProxy)
2366   //    VariableProxy
2367   // Tail ::
2368   //    VariableProxy
2369   //    Spread(VariableProxy)
2370   //
2371   // We need to visit the parameters in left-to-right order
2372   //
2373 
2374   // For the Nary case, we simply visit the parameters in a loop.
2375   if (expr->IsNaryOperation()) {
2376     NaryOperation* nary = expr->AsNaryOperation();
2377     // The classifier has already run, so we know that the expression is a valid
2378     // arrow function formals production.
2379     DCHECK_EQ(nary->op(), Token::COMMA);
2380     // Each op position is the end position of the *previous* expr, with the
2381     // second (i.e. first "subsequent") op position being the end position of
2382     // the first child expression.
2383     Expression* next = nary->first();
2384     for (size_t i = 0; i < nary->subsequent_length(); ++i) {
2385       AddArrowFunctionFormalParameters(
2386           parameters, next, nary->subsequent_op_position(i), CHECK_OK_VOID);
2387       next = nary->subsequent(i);
2388     }
2389     AddArrowFunctionFormalParameters(parameters, next, end_pos, CHECK_OK_VOID);
2390     return;
2391   }
2392 
2393   // For the binary case, we recurse on the left-hand side of binary comma
2394   // expressions.
2395   if (expr->IsBinaryOperation()) {
2396     BinaryOperation* binop = expr->AsBinaryOperation();
2397     // The classifier has already run, so we know that the expression is a valid
2398     // arrow function formals production.
2399     DCHECK_EQ(binop->op(), Token::COMMA);
2400     Expression* left = binop->left();
2401     Expression* right = binop->right();
2402     int comma_pos = binop->position();
2403     AddArrowFunctionFormalParameters(parameters, left, comma_pos,
2404                                      CHECK_OK_VOID);
2405     // LHS of comma expression should be unparenthesized.
2406     expr = right;
2407   }
2408 
2409   // Only the right-most expression may be a rest parameter.
2410   DCHECK(!parameters->has_rest);
2411 
2412   bool is_rest = expr->IsSpread();
2413   if (is_rest) {
2414     expr = expr->AsSpread()->expression();
2415     parameters->has_rest = true;
2416   }
2417   DCHECK_IMPLIES(parameters->is_simple, !is_rest);
2418   DCHECK_IMPLIES(parameters->is_simple, expr->IsVariableProxy());
2419 
2420   Expression* initializer = nullptr;
2421   if (expr->IsAssignment()) {
2422     if (expr->IsRewritableExpression()) {
2423       // This expression was parsed as a possible destructuring assignment.
2424       // Mark it as already-rewritten to avoid an unnecessary visit later.
2425       expr->AsRewritableExpression()->set_rewritten();
2426     }
2427     Assignment* assignment = expr->AsAssignment();
2428     DCHECK(!assignment->IsCompoundAssignment());
2429     initializer = assignment->value();
2430     expr = assignment->target();
2431   }
2432 
2433   AddFormalParameter(parameters, expr, initializer,
2434                      end_pos, is_rest);
2435 }
2436 
DeclareArrowFunctionFormalParameters(ParserFormalParameters * parameters,Expression * expr,const Scanner::Location & params_loc,Scanner::Location * duplicate_loc,bool * ok)2437 void Parser::DeclareArrowFunctionFormalParameters(
2438     ParserFormalParameters* parameters, Expression* expr,
2439     const Scanner::Location& params_loc, Scanner::Location* duplicate_loc,
2440     bool* ok) {
2441   if (expr->IsEmptyParentheses()) return;
2442 
2443   AddArrowFunctionFormalParameters(parameters, expr, params_loc.end_pos,
2444                                    CHECK_OK_VOID);
2445 
2446   if (parameters->arity > Code::kMaxArguments) {
2447     ReportMessageAt(params_loc, MessageTemplate::kMalformedArrowFunParamList);
2448     *ok = false;
2449     return;
2450   }
2451 
2452   bool has_duplicate = false;
2453   DeclareFormalParameters(parameters->scope, parameters->params,
2454                           parameters->is_simple, &has_duplicate);
2455   if (has_duplicate) {
2456     *duplicate_loc = scanner()->location();
2457   }
2458   DCHECK_EQ(parameters->is_simple, parameters->scope->has_simple_parameters());
2459 }
2460 
PrepareGeneratorVariables()2461 void Parser::PrepareGeneratorVariables() {
2462   // The code produced for generators relies on forced context allocation of
2463   // parameters (it does not restore the frame's parameters upon resume).
2464   function_state_->scope()->ForceContextAllocationForParameters();
2465 
2466   // Calling a generator returns a generator object.  That object is stored
2467   // in a temporary variable, a definition that is used by "yield"
2468   // expressions.
2469   function_state_->scope()->DeclareGeneratorObjectVar(
2470       ast_value_factory()->dot_generator_object_string());
2471 }
2472 
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,ZonePtrList<const AstRawString> * arguments_for_wrapped_function,bool * ok)2473 FunctionLiteral* Parser::ParseFunctionLiteral(
2474     const AstRawString* function_name, Scanner::Location function_name_location,
2475     FunctionNameValidity function_name_validity, FunctionKind kind,
2476     int function_token_pos, FunctionLiteral::FunctionType function_type,
2477     LanguageMode language_mode,
2478     ZonePtrList<const AstRawString>* arguments_for_wrapped_function, bool* ok) {
2479   // Function ::
2480   //   '(' FormalParameterList? ')' '{' FunctionBody '}'
2481   //
2482   // Getter ::
2483   //   '(' ')' '{' FunctionBody '}'
2484   //
2485   // Setter ::
2486   //   '(' PropertySetParameterList ')' '{' FunctionBody '}'
2487 
2488   bool is_wrapped = function_type == FunctionLiteral::kWrapped;
2489   DCHECK_EQ(is_wrapped, arguments_for_wrapped_function != nullptr);
2490 
2491   int pos = function_token_pos == kNoSourcePosition ? peek_position()
2492                                                     : function_token_pos;
2493   DCHECK_NE(kNoSourcePosition, pos);
2494 
2495   // Anonymous functions were passed either the empty symbol or a null
2496   // handle as the function name.  Remember if we were passed a non-empty
2497   // handle to decide whether to invoke function name inference.
2498   bool should_infer_name = function_name == nullptr;
2499 
2500   // We want a non-null handle as the function name by default. We will handle
2501   // the "function does not have a shared name" case later.
2502   if (should_infer_name) {
2503     function_name = ast_value_factory()->empty_string();
2504   }
2505 
2506   FunctionLiteral::EagerCompileHint eager_compile_hint =
2507       function_state_->next_function_is_likely_called() || is_wrapped
2508           ? FunctionLiteral::kShouldEagerCompile
2509           : default_eager_compile_hint();
2510 
2511   // Determine if the function can be parsed lazily. Lazy parsing is
2512   // different from lazy compilation; we need to parse more eagerly than we
2513   // compile.
2514 
2515   // We can only parse lazily if we also compile lazily. The heuristics for lazy
2516   // compilation are:
2517   // - It must not have been prohibited by the caller to Parse (some callers
2518   //   need a full AST).
2519   // - The outer scope must allow lazy compilation of inner functions.
2520   // - The function mustn't be a function expression with an open parenthesis
2521   //   before; we consider that a hint that the function will be called
2522   //   immediately, and it would be a waste of time to make it lazily
2523   //   compiled.
2524   // These are all things we can know at this point, without looking at the
2525   // function itself.
2526 
2527   // We separate between lazy parsing top level functions and lazy parsing inner
2528   // functions, because the latter needs to do more work. In particular, we need
2529   // to track unresolved variables to distinguish between these cases:
2530   // (function foo() {
2531   //   bar = function() { return 1; }
2532   //  })();
2533   // and
2534   // (function foo() {
2535   //   var a = 1;
2536   //   bar = function() { return a; }
2537   //  })();
2538 
2539   // Now foo will be parsed eagerly and compiled eagerly (optimization: assume
2540   // parenthesis before the function means that it will be called
2541   // immediately). bar can be parsed lazily, but we need to parse it in a mode
2542   // that tracks unresolved variables.
2543   DCHECK_IMPLIES(parse_lazily(), FLAG_lazy);
2544   DCHECK_IMPLIES(parse_lazily(), allow_lazy_);
2545   DCHECK_IMPLIES(parse_lazily(), extension_ == nullptr);
2546 
2547   const bool is_lazy =
2548       eager_compile_hint == FunctionLiteral::kShouldLazyCompile;
2549   const bool is_top_level = AllowsLazyParsingWithoutUnresolvedVariables();
2550   const bool is_lazy_top_level_function = is_lazy && is_top_level;
2551   const bool is_lazy_inner_function = is_lazy && !is_top_level;
2552   const bool is_expression =
2553       function_type == FunctionLiteral::kAnonymousExpression ||
2554       function_type == FunctionLiteral::kNamedExpression;
2555 
2556   RuntimeCallTimerScope runtime_timer(
2557       runtime_call_stats_,
2558       parsing_on_main_thread_
2559           ? RuntimeCallCounterId::kParseFunctionLiteral
2560           : RuntimeCallCounterId::kParseBackgroundFunctionLiteral);
2561   base::ElapsedTimer timer;
2562   if (V8_UNLIKELY(FLAG_log_function_events)) timer.Start();
2563 
2564   // Determine whether we can still lazy parse the inner function.
2565   // The preconditions are:
2566   // - Lazy compilation has to be enabled.
2567   // - Neither V8 natives nor native function declarations can be allowed,
2568   //   since parsing one would retroactively force the function to be
2569   //   eagerly compiled.
2570   // - The invoker of this parser can't depend on the AST being eagerly
2571   //   built (either because the function is about to be compiled, or
2572   //   because the AST is going to be inspected for some reason).
2573   // - Because of the above, we can't be attempting to parse a
2574   //   FunctionExpression; even without enclosing parentheses it might be
2575   //   immediately invoked.
2576   // - The function literal shouldn't be hinted to eagerly compile.
2577 
2578   // Inner functions will be parsed using a temporary Zone. After parsing, we
2579   // will migrate unresolved variable into a Scope in the main Zone.
2580 
2581   const bool should_preparse_inner =
2582       parse_lazily() && FLAG_lazy_inner_functions && is_lazy_inner_function &&
2583       (!is_expression || FLAG_aggressive_lazy_inner_functions);
2584 
2585   // This may be modified later to reflect preparsing decision taken
2586   bool should_preparse =
2587       (parse_lazily() && is_lazy_top_level_function) || should_preparse_inner;
2588 
2589   ZonePtrList<Statement>* body = nullptr;
2590   int expected_property_count = -1;
2591   int suspend_count = -1;
2592   int num_parameters = -1;
2593   int function_length = -1;
2594   bool has_duplicate_parameters = false;
2595   int function_literal_id = GetNextFunctionLiteralId();
2596   ProducedPreParsedScopeData* produced_preparsed_scope_data = nullptr;
2597 
2598   Zone* outer_zone = zone();
2599   DeclarationScope* scope;
2600 
2601   {
2602     // Temporary zones can nest. When we migrate free variables (see below), we
2603     // need to recreate them in the previous Zone.
2604     AstNodeFactory previous_zone_ast_node_factory(ast_value_factory(), zone());
2605 
2606     // Open a new zone scope, which sets our AstNodeFactory to allocate in the
2607     // new temporary zone if the preconditions are satisfied, and ensures that
2608     // the previous zone is always restored after parsing the body. To be able
2609     // to do scope analysis correctly after full parsing, we migrate needed
2610     // information when the function is parsed.
2611     Zone temp_zone(zone()->allocator(), ZONE_NAME);
2612     DiscardableZoneScope zone_scope(this, &temp_zone, should_preparse);
2613 
2614     // This Scope lives in the main zone. We'll migrate data into that zone
2615     // later.
2616     scope = NewFunctionScope(kind, outer_zone);
2617     SetLanguageMode(scope, language_mode);
2618 #ifdef DEBUG
2619     scope->SetScopeName(function_name);
2620     if (should_preparse) scope->set_needs_migration();
2621 #endif
2622 
2623     if (!is_wrapped) Expect(Token::LPAREN, CHECK_OK);
2624     scope->set_start_position(scanner()->location().beg_pos);
2625 
2626     // Eager or lazy parse? If is_lazy_top_level_function, we'll parse
2627     // lazily. We'll call SkipFunction, which may decide to
2628     // abort lazy parsing if it suspects that wasn't a good idea. If so (in
2629     // which case the parser is expected to have backtracked), or if we didn't
2630     // try to lazy parse in the first place, we'll have to parse eagerly.
2631     if (should_preparse) {
2632       DCHECK(parse_lazily());
2633       DCHECK(is_lazy_top_level_function || is_lazy_inner_function);
2634       DCHECK(!is_wrapped);
2635       Scanner::BookmarkScope bookmark(scanner());
2636       bookmark.Set();
2637       LazyParsingResult result = SkipFunction(
2638           function_name, kind, function_type, scope, &num_parameters,
2639           &produced_preparsed_scope_data, is_lazy_inner_function,
2640           is_lazy_top_level_function, CHECK_OK);
2641 
2642       if (result == kLazyParsingAborted) {
2643         DCHECK(is_lazy_top_level_function);
2644         bookmark.Apply();
2645         // This is probably an initialization function. Inform the compiler it
2646         // should also eager-compile this function.
2647         eager_compile_hint = FunctionLiteral::kShouldEagerCompile;
2648         scope->ResetAfterPreparsing(ast_value_factory(), true);
2649         zone_scope.Reset();
2650         // Trigger eager (re-)parsing, just below this block.
2651         should_preparse = false;
2652       }
2653     }
2654 
2655     if (should_preparse) {
2656       scope->AnalyzePartially(&previous_zone_ast_node_factory);
2657     } else {
2658       body = ParseFunction(
2659           function_name, pos, kind, function_type, scope, &num_parameters,
2660           &function_length, &has_duplicate_parameters, &expected_property_count,
2661           &suspend_count, arguments_for_wrapped_function, CHECK_OK);
2662     }
2663 
2664     DCHECK_EQ(should_preparse, temp_zoned_);
2665     if (V8_UNLIKELY(FLAG_log_function_events)) {
2666       double ms = timer.Elapsed().InMillisecondsF();
2667       const char* event_name = should_preparse
2668                                    ? (is_top_level ? "preparse-no-resolution"
2669                                                    : "preparse-resolution")
2670                                    : "full-parse";
2671       logger_->FunctionEvent(
2672           event_name, nullptr, script_id(), ms, scope->start_position(),
2673           scope->end_position(),
2674           reinterpret_cast<const char*>(function_name->raw_data()),
2675           function_name->byte_length());
2676     }
2677     if (V8_UNLIKELY(FLAG_runtime_stats)) {
2678       if (should_preparse) {
2679         RuntimeCallCounterId counter_id =
2680             parsing_on_main_thread_
2681                 ? RuntimeCallCounterId::kPreParseWithVariableResolution
2682                 : RuntimeCallCounterId::
2683                       kPreParseBackgroundWithVariableResolution;
2684         if (is_top_level) {
2685           counter_id = parsing_on_main_thread_
2686                            ? RuntimeCallCounterId::kPreParseNoVariableResolution
2687                            : RuntimeCallCounterId::
2688                                  kPreParseBackgroundNoVariableResolution;
2689         }
2690         if (runtime_call_stats_) {
2691           runtime_call_stats_->CorrectCurrentCounterId(counter_id);
2692         }
2693       }
2694     }
2695 
2696     // Validate function name. We can do this only after parsing the function,
2697     // since the function can declare itself strict.
2698     language_mode = scope->language_mode();
2699     CheckFunctionName(language_mode, function_name, function_name_validity,
2700                       function_name_location, CHECK_OK);
2701 
2702     if (is_strict(language_mode)) {
2703       CheckStrictOctalLiteral(scope->start_position(), scope->end_position(),
2704                               CHECK_OK);
2705     }
2706     CheckConflictingVarDeclarations(scope, CHECK_OK);
2707   }  // DiscardableZoneScope goes out of scope.
2708 
2709   FunctionLiteral::ParameterFlag duplicate_parameters =
2710       has_duplicate_parameters ? FunctionLiteral::kHasDuplicateParameters
2711                                : FunctionLiteral::kNoDuplicateParameters;
2712 
2713   // Note that the FunctionLiteral needs to be created in the main Zone again.
2714   FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
2715       function_name, scope, body, expected_property_count, num_parameters,
2716       function_length, duplicate_parameters, function_type, eager_compile_hint,
2717       pos, true, function_literal_id, produced_preparsed_scope_data);
2718   function_literal->set_function_token_position(function_token_pos);
2719   function_literal->set_suspend_count(suspend_count);
2720 
2721   if (should_infer_name) {
2722     DCHECK_NOT_NULL(fni_);
2723     fni_->AddFunction(function_literal);
2724   }
2725   return function_literal;
2726 }
2727 
SkipFunction(const AstRawString * function_name,FunctionKind kind,FunctionLiteral::FunctionType function_type,DeclarationScope * function_scope,int * num_parameters,ProducedPreParsedScopeData ** produced_preparsed_scope_data,bool is_inner_function,bool may_abort,bool * ok)2728 Parser::LazyParsingResult Parser::SkipFunction(
2729     const AstRawString* function_name, FunctionKind kind,
2730     FunctionLiteral::FunctionType function_type,
2731     DeclarationScope* function_scope, int* num_parameters,
2732     ProducedPreParsedScopeData** produced_preparsed_scope_data,
2733     bool is_inner_function, bool may_abort, bool* ok) {
2734   FunctionState function_state(&function_state_, &scope_, function_scope);
2735 
2736   DCHECK_NE(kNoSourcePosition, function_scope->start_position());
2737   DCHECK_EQ(kNoSourcePosition, parameters_end_pos_);
2738 
2739   DCHECK_IMPLIES(IsArrowFunction(kind),
2740                  scanner()->current_token() == Token::ARROW);
2741 
2742   // FIXME(marja): There are 2 ways to skip functions now. Unify them.
2743   DCHECK_NOT_NULL(consumed_preparsed_scope_data_);
2744   if (consumed_preparsed_scope_data_->HasData()) {
2745     DCHECK(FLAG_preparser_scope_analysis);
2746     int end_position;
2747     LanguageMode language_mode;
2748     int num_inner_functions;
2749     bool uses_super_property;
2750     *produced_preparsed_scope_data =
2751         consumed_preparsed_scope_data_->GetDataForSkippableFunction(
2752             main_zone(), function_scope->start_position(), &end_position,
2753             num_parameters, &num_inner_functions, &uses_super_property,
2754             &language_mode);
2755 
2756     function_scope->outer_scope()->SetMustUsePreParsedScopeData();
2757     function_scope->set_is_skipped_function(true);
2758     function_scope->set_end_position(end_position);
2759     scanner()->SeekForward(end_position - 1);
2760     Expect(Token::RBRACE, CHECK_OK_VALUE(kLazyParsingComplete));
2761     SetLanguageMode(function_scope, language_mode);
2762     if (uses_super_property) {
2763       function_scope->RecordSuperPropertyUsage();
2764     }
2765     SkipFunctionLiterals(num_inner_functions);
2766     return kLazyParsingComplete;
2767   }
2768 
2769   // With no cached data, we partially parse the function, without building an
2770   // AST. This gathers the data needed to build a lazy function.
2771   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.PreParse");
2772 
2773   // Aborting inner function preparsing would leave scopes in an inconsistent
2774   // state; we don't parse inner functions in the abortable mode anyway.
2775   DCHECK(!is_inner_function || !may_abort);
2776 
2777   PreParser::PreParseResult result = reusable_preparser()->PreParseFunction(
2778       function_name, kind, function_type, function_scope, is_inner_function,
2779       may_abort, use_counts_, produced_preparsed_scope_data, this->script_id());
2780 
2781   // Return immediately if pre-parser decided to abort parsing.
2782   if (result == PreParser::kPreParseAbort) return kLazyParsingAborted;
2783   if (result == PreParser::kPreParseStackOverflow) {
2784     // Propagate stack overflow.
2785     set_stack_overflow();
2786     *ok = false;
2787     return kLazyParsingComplete;
2788   }
2789   if (pending_error_handler()->has_pending_error()) {
2790     *ok = false;
2791     return kLazyParsingComplete;
2792   }
2793 
2794   set_allow_eval_cache(reusable_preparser()->allow_eval_cache());
2795 
2796   PreParserLogger* logger = reusable_preparser()->logger();
2797   function_scope->set_end_position(logger->end());
2798   Expect(Token::RBRACE, CHECK_OK_VALUE(kLazyParsingComplete));
2799   total_preparse_skipped_ +=
2800       function_scope->end_position() - function_scope->start_position();
2801   *num_parameters = logger->num_parameters();
2802   SkipFunctionLiterals(logger->num_inner_functions());
2803   return kLazyParsingComplete;
2804 }
2805 
BuildAssertIsCoercible(Variable * var,ObjectLiteral * pattern)2806 Statement* Parser::BuildAssertIsCoercible(Variable* var,
2807                                           ObjectLiteral* pattern) {
2808   // if (var === null || var === undefined)
2809   //     throw /* type error kNonCoercible) */;
2810   auto source_position = pattern->position();
2811   const AstRawString* property = ast_value_factory()->empty_string();
2812   MessageTemplate::Template msg = MessageTemplate::kNonCoercible;
2813   for (ObjectLiteralProperty* literal_property : *pattern->properties()) {
2814     Expression* key = literal_property->key();
2815     if (key->IsPropertyName()) {
2816       property = key->AsLiteral()->AsRawPropertyName();
2817       msg = MessageTemplate::kNonCoercibleWithProperty;
2818       source_position = key->position();
2819       break;
2820     }
2821   }
2822 
2823   Expression* condition = factory()->NewBinaryOperation(
2824       Token::OR,
2825       factory()->NewCompareOperation(
2826           Token::EQ_STRICT, factory()->NewVariableProxy(var),
2827           factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition),
2828       factory()->NewCompareOperation(
2829           Token::EQ_STRICT, factory()->NewVariableProxy(var),
2830           factory()->NewNullLiteral(kNoSourcePosition), kNoSourcePosition),
2831       kNoSourcePosition);
2832   Expression* throw_type_error =
2833       NewThrowTypeError(msg, property, source_position);
2834   IfStatement* if_statement = factory()->NewIfStatement(
2835       condition,
2836       factory()->NewExpressionStatement(throw_type_error, kNoSourcePosition),
2837       factory()->NewEmptyStatement(kNoSourcePosition), kNoSourcePosition);
2838   return if_statement;
2839 }
2840 
2841 class InitializerRewriter final
2842     : public AstTraversalVisitor<InitializerRewriter> {
2843  public:
InitializerRewriter(uintptr_t stack_limit,Expression * root,Parser * parser)2844   InitializerRewriter(uintptr_t stack_limit, Expression* root, Parser* parser)
2845       : AstTraversalVisitor(stack_limit, root), parser_(parser) {}
2846 
2847  private:
2848   // This is required so that the overriden Visit* methods can be
2849   // called by the base class (template).
2850   friend class AstTraversalVisitor<InitializerRewriter>;
2851 
2852   // Just rewrite destructuring assignments wrapped in RewritableExpressions.
VisitRewritableExpression(RewritableExpression * to_rewrite)2853   void VisitRewritableExpression(RewritableExpression* to_rewrite) {
2854     if (to_rewrite->is_rewritten()) return;
2855     parser_->RewriteDestructuringAssignment(to_rewrite);
2856     AstTraversalVisitor::VisitRewritableExpression(to_rewrite);
2857   }
2858 
2859   // Code in function literals does not need to be eagerly rewritten, it will be
2860   // rewritten when scheduled.
VisitFunctionLiteral(FunctionLiteral * expr)2861   void VisitFunctionLiteral(FunctionLiteral* expr) {}
2862 
2863   Parser* parser_;
2864 };
2865 
RewriteParameterInitializer(Expression * expr)2866 void Parser::RewriteParameterInitializer(Expression* expr) {
2867   InitializerRewriter rewriter(stack_limit_, expr, this);
2868   rewriter.Run();
2869 }
2870 
2871 
BuildParameterInitializationBlock(const ParserFormalParameters & parameters,bool * ok)2872 Block* Parser::BuildParameterInitializationBlock(
2873     const ParserFormalParameters& parameters, bool* ok) {
2874   DCHECK(!parameters.is_simple);
2875   DCHECK(scope()->is_function_scope());
2876   DCHECK_EQ(scope(), parameters.scope);
2877   Block* init_block = factory()->NewBlock(1, true);
2878   int index = 0;
2879   for (auto parameter : parameters.params) {
2880     DeclarationDescriptor descriptor;
2881     descriptor.declaration_kind = DeclarationDescriptor::PARAMETER;
2882     descriptor.scope = scope();
2883     descriptor.mode = LET;
2884     descriptor.declaration_pos = parameter->pattern->position();
2885     // The position that will be used by the AssignmentExpression
2886     // which copies from the temp parameter to the pattern.
2887     //
2888     // TODO(adamk): Should this be kNoSourcePosition, since
2889     // it's just copying from a temp var to the real param var?
2890     descriptor.initialization_pos = parameter->pattern->position();
2891     Expression* initial_value =
2892         factory()->NewVariableProxy(parameters.scope->parameter(index));
2893     if (parameter->initializer != nullptr) {
2894       // IS_UNDEFINED($param) ? initializer : $param
2895 
2896       // Ensure initializer is rewritten
2897       RewriteParameterInitializer(parameter->initializer);
2898 
2899       auto condition = factory()->NewCompareOperation(
2900           Token::EQ_STRICT,
2901           factory()->NewVariableProxy(parameters.scope->parameter(index)),
2902           factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition);
2903       initial_value = factory()->NewConditional(
2904           condition, parameter->initializer, initial_value, kNoSourcePosition);
2905       descriptor.initialization_pos = parameter->initializer->position();
2906     }
2907 
2908     Scope* param_scope = scope();
2909     Block* param_block = init_block;
2910     if (!parameter->is_simple() &&
2911         scope()->AsDeclarationScope()->calls_sloppy_eval()) {
2912       param_scope = NewVarblockScope();
2913       param_scope->set_start_position(descriptor.initialization_pos);
2914       param_scope->set_end_position(parameter->initializer_end_position);
2915       param_scope->RecordEvalCall();
2916       param_block = factory()->NewBlock(8, true);
2917       param_block->set_scope(param_scope);
2918       // Pass the appropriate scope in so that PatternRewriter can appropriately
2919       // rewrite inner initializers of the pattern to param_scope
2920       descriptor.scope = param_scope;
2921       // Rewrite the outer initializer to point to param_scope
2922       ReparentExpressionScope(stack_limit(), initial_value, param_scope);
2923     }
2924 
2925     BlockState block_state(&scope_, param_scope);
2926     DeclarationParsingResult::Declaration decl(
2927         parameter->pattern, parameter->initializer_end_position, initial_value);
2928     DeclareAndInitializeVariables(param_block, &descriptor, &decl, nullptr,
2929                                   CHECK_OK);
2930 
2931     if (param_block != init_block) {
2932       param_scope = param_scope->FinalizeBlockScope();
2933       if (param_scope != nullptr) {
2934         CheckConflictingVarDeclarations(param_scope, CHECK_OK);
2935       }
2936       init_block->statements()->Add(param_block, zone());
2937     }
2938     ++index;
2939   }
2940   return init_block;
2941 }
2942 
NewHiddenCatchScope()2943 Scope* Parser::NewHiddenCatchScope() {
2944   Scope* catch_scope = NewScopeWithParent(scope(), CATCH_SCOPE);
2945   catch_scope->DeclareLocal(ast_value_factory()->dot_catch_string(), VAR);
2946   catch_scope->set_is_hidden();
2947   return catch_scope;
2948 }
2949 
BuildRejectPromiseOnException(Block * inner_block)2950 Block* Parser::BuildRejectPromiseOnException(Block* inner_block) {
2951   // .promise = %AsyncFunctionPromiseCreate();
2952   // try {
2953   //   <inner_block>
2954   // } catch (.catch) {
2955   //   %RejectPromise(.promise, .catch);
2956   //   return .promise;
2957   // } finally {
2958   //   %AsyncFunctionPromiseRelease(.promise);
2959   // }
2960   Block* result = factory()->NewBlock(2, true);
2961 
2962   // .promise = %AsyncFunctionPromiseCreate();
2963   Statement* set_promise;
2964   {
2965     Expression* create_promise = factory()->NewCallRuntime(
2966         Context::ASYNC_FUNCTION_PROMISE_CREATE_INDEX,
2967         new (zone()) ZonePtrList<Expression>(0, zone()), kNoSourcePosition);
2968     Assignment* assign_promise = factory()->NewAssignment(
2969         Token::ASSIGN, factory()->NewVariableProxy(PromiseVariable()),
2970         create_promise, kNoSourcePosition);
2971     set_promise =
2972         factory()->NewExpressionStatement(assign_promise, kNoSourcePosition);
2973   }
2974   result->statements()->Add(set_promise, zone());
2975 
2976   // catch (.catch) { return %RejectPromise(.promise, .catch), .promise }
2977   Scope* catch_scope = NewHiddenCatchScope();
2978 
2979   Expression* promise_reject = BuildRejectPromise(
2980       factory()->NewVariableProxy(catch_scope->catch_variable()),
2981       kNoSourcePosition);
2982   Block* catch_block = IgnoreCompletion(
2983       factory()->NewReturnStatement(promise_reject, kNoSourcePosition));
2984 
2985   TryStatement* try_catch_statement =
2986       factory()->NewTryCatchStatementForAsyncAwait(
2987           inner_block, catch_scope, catch_block, kNoSourcePosition);
2988 
2989   // There is no TryCatchFinally node, so wrap it in an outer try/finally
2990   Block* outer_try_block = IgnoreCompletion(try_catch_statement);
2991 
2992   // finally { %AsyncFunctionPromiseRelease(.promise) }
2993   Block* finally_block;
2994   {
2995     ZonePtrList<Expression>* args =
2996         new (zone()) ZonePtrList<Expression>(1, zone());
2997     args->Add(factory()->NewVariableProxy(PromiseVariable()), zone());
2998     Expression* call_promise_release = factory()->NewCallRuntime(
2999         Context::ASYNC_FUNCTION_PROMISE_RELEASE_INDEX, args, kNoSourcePosition);
3000     Statement* promise_release = factory()->NewExpressionStatement(
3001         call_promise_release, kNoSourcePosition);
3002     finally_block = IgnoreCompletion(promise_release);
3003   }
3004 
3005   Statement* try_finally_statement = factory()->NewTryFinallyStatement(
3006       outer_try_block, finally_block, kNoSourcePosition);
3007 
3008   result->statements()->Add(try_finally_statement, zone());
3009   return result;
3010 }
3011 
BuildResolvePromise(Expression * value,int pos)3012 Expression* Parser::BuildResolvePromise(Expression* value, int pos) {
3013   // %ResolvePromise(.promise, value), .promise
3014   ZonePtrList<Expression>* args =
3015       new (zone()) ZonePtrList<Expression>(2, zone());
3016   args->Add(factory()->NewVariableProxy(PromiseVariable()), zone());
3017   args->Add(value, zone());
3018   Expression* call_runtime =
3019       factory()->NewCallRuntime(Runtime::kInlineResolvePromise, args, pos);
3020   return factory()->NewBinaryOperation(
3021       Token::COMMA, call_runtime,
3022       factory()->NewVariableProxy(PromiseVariable()), pos);
3023 }
3024 
BuildRejectPromise(Expression * value,int pos)3025 Expression* Parser::BuildRejectPromise(Expression* value, int pos) {
3026   // %promise_internal_reject(.promise, value, false), .promise
3027   // Disables the additional debug event for the rejection since a debug event
3028   // already happened for the exception that got us here.
3029   ZonePtrList<Expression>* args =
3030       new (zone()) ZonePtrList<Expression>(3, zone());
3031   args->Add(factory()->NewVariableProxy(PromiseVariable()), zone());
3032   args->Add(value, zone());
3033   args->Add(factory()->NewBooleanLiteral(false, pos), zone());
3034   Expression* call_runtime =
3035       factory()->NewCallRuntime(Runtime::kInlineRejectPromise, args, pos);
3036   return factory()->NewBinaryOperation(
3037       Token::COMMA, call_runtime,
3038       factory()->NewVariableProxy(PromiseVariable()), pos);
3039 }
3040 
PromiseVariable()3041 Variable* Parser::PromiseVariable() {
3042   // Based on the various compilation paths, there are many different code
3043   // paths which may be the first to access the Promise temporary. Whichever
3044   // comes first should create it and stash it in the FunctionState.
3045   Variable* promise = function_state_->scope()->promise_var();
3046   if (promise == nullptr) {
3047     promise = function_state_->scope()->DeclarePromiseVar(
3048         ast_value_factory()->empty_string());
3049   }
3050   return promise;
3051 }
3052 
BuildInitialYield(int pos,FunctionKind kind)3053 Expression* Parser::BuildInitialYield(int pos, FunctionKind kind) {
3054   Expression* yield_result = factory()->NewVariableProxy(
3055       function_state_->scope()->generator_object_var());
3056   // The position of the yield is important for reporting the exception
3057   // caused by calling the .throw method on a generator suspended at the
3058   // initial yield (i.e. right after generator instantiation).
3059   function_state_->AddSuspend();
3060   return factory()->NewYield(yield_result, scope()->start_position(),
3061                              Suspend::kOnExceptionThrow);
3062 }
3063 
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 * expected_property_count,int * suspend_count,ZonePtrList<const AstRawString> * arguments_for_wrapped_function,bool * ok)3064 ZonePtrList<Statement>* Parser::ParseFunction(
3065     const AstRawString* function_name, int pos, FunctionKind kind,
3066     FunctionLiteral::FunctionType function_type,
3067     DeclarationScope* function_scope, int* num_parameters, int* function_length,
3068     bool* has_duplicate_parameters, int* expected_property_count,
3069     int* suspend_count,
3070     ZonePtrList<const AstRawString>* arguments_for_wrapped_function, bool* ok) {
3071   ParsingModeScope mode(this, allow_lazy_ ? PARSE_LAZILY : PARSE_EAGERLY);
3072 
3073   FunctionState function_state(&function_state_, &scope_, function_scope);
3074 
3075   bool is_wrapped = function_type == FunctionLiteral::kWrapped;
3076 
3077   DuplicateFinder duplicate_finder;
3078   ExpressionClassifier formals_classifier(this, &duplicate_finder);
3079 
3080   int expected_parameters_end_pos = parameters_end_pos_;
3081   if (expected_parameters_end_pos != kNoSourcePosition) {
3082     // This is the first function encountered in a CreateDynamicFunction eval.
3083     parameters_end_pos_ = kNoSourcePosition;
3084     // The function name should have been ignored, giving us the empty string
3085     // here.
3086     DCHECK_EQ(function_name, ast_value_factory()->empty_string());
3087   }
3088 
3089   ParserFormalParameters formals(function_scope);
3090 
3091   if (is_wrapped) {
3092     // For a function implicitly wrapped in function header and footer, the
3093     // function arguments are provided separately to the source, and are
3094     // declared directly here.
3095     int arguments_length = arguments_for_wrapped_function->length();
3096     for (int i = 0; i < arguments_length; i++) {
3097       const bool is_rest = false;
3098       Expression* argument = ExpressionFromIdentifier(
3099           arguments_for_wrapped_function->at(i), kNoSourcePosition);
3100       AddFormalParameter(&formals, argument, NullExpression(),
3101                          kNoSourcePosition, is_rest);
3102     }
3103     DCHECK_EQ(arguments_length, formals.num_parameters());
3104     DeclareFormalParameters(formals.scope, formals.params, formals.is_simple);
3105   } else {
3106     // For a regular function, the function arguments are parsed from source.
3107     DCHECK_NULL(arguments_for_wrapped_function);
3108     ParseFormalParameterList(&formals, CHECK_OK);
3109     if (expected_parameters_end_pos != kNoSourcePosition) {
3110       // Check for '(' or ')' shenanigans in the parameter string for dynamic
3111       // functions.
3112       int position = peek_position();
3113       if (position < expected_parameters_end_pos) {
3114         ReportMessageAt(Scanner::Location(position, position + 1),
3115                         MessageTemplate::kArgStringTerminatesParametersEarly);
3116         *ok = false;
3117         return nullptr;
3118       } else if (position > expected_parameters_end_pos) {
3119         ReportMessageAt(Scanner::Location(expected_parameters_end_pos - 2,
3120                                           expected_parameters_end_pos),
3121                         MessageTemplate::kUnexpectedEndOfArgString);
3122         *ok = false;
3123         return nullptr;
3124       }
3125     }
3126     Expect(Token::RPAREN, CHECK_OK);
3127     int formals_end_position = scanner()->location().end_pos;
3128 
3129     CheckArityRestrictions(formals.arity, kind, formals.has_rest,
3130                            function_scope->start_position(),
3131                            formals_end_position, CHECK_OK);
3132     Expect(Token::LBRACE, CHECK_OK);
3133   }
3134   *num_parameters = formals.num_parameters();
3135   *function_length = formals.function_length;
3136 
3137   ZonePtrList<Statement>* body = new (zone()) ZonePtrList<Statement>(8, zone());
3138   ParseFunctionBody(body, function_name, pos, formals, kind, function_type, ok);
3139 
3140   // Validate parameter names. We can do this only after parsing the function,
3141   // since the function can declare itself strict.
3142   const bool allow_duplicate_parameters =
3143       is_sloppy(function_scope->language_mode()) && formals.is_simple &&
3144       !IsConciseMethod(kind);
3145   ValidateFormalParameters(function_scope->language_mode(),
3146                            allow_duplicate_parameters, CHECK_OK);
3147 
3148   RewriteDestructuringAssignments();
3149 
3150   *has_duplicate_parameters =
3151       !classifier()->is_valid_formal_parameter_list_without_duplicates();
3152 
3153   *expected_property_count = function_state.expected_property_count();
3154   *suspend_count = function_state.suspend_count();
3155   return body;
3156 }
3157 
DeclareClassVariable(const AstRawString * name,ClassInfo * class_info,int class_token_pos,bool * ok)3158 void Parser::DeclareClassVariable(const AstRawString* name,
3159                                   ClassInfo* class_info, int class_token_pos,
3160                                   bool* ok) {
3161 #ifdef DEBUG
3162   scope()->SetScopeName(name);
3163 #endif
3164 
3165   if (name != nullptr) {
3166     VariableProxy* proxy = factory()->NewVariableProxy(name, NORMAL_VARIABLE);
3167     Declaration* declaration =
3168         factory()->NewVariableDeclaration(proxy, class_token_pos);
3169     class_info->variable =
3170         Declare(declaration, DeclarationDescriptor::NORMAL, CONST,
3171                 Variable::DefaultInitializationFlag(CONST), ok);
3172   }
3173 }
3174 
3175 // TODO(gsathya): Ideally, this should just bypass scope analysis and
3176 // allocate a slot directly on the context. We should just store this
3177 // index in the AST, instead of storing the variable.
CreateSyntheticContextVariable(const AstRawString * name,bool * ok)3178 Variable* Parser::CreateSyntheticContextVariable(const AstRawString* name,
3179                                                  bool* ok) {
3180   VariableProxy* proxy = factory()->NewVariableProxy(name, NORMAL_VARIABLE);
3181   Declaration* declaration =
3182       factory()->NewVariableDeclaration(proxy, kNoSourcePosition);
3183   Variable* var = Declare(declaration, DeclarationDescriptor::NORMAL, CONST,
3184                           Variable::DefaultInitializationFlag(CONST), CHECK_OK);
3185   var->ForceContextAllocation();
3186   return var;
3187 }
3188 
3189 // This method declares a property of the given class.  It updates the
3190 // following fields of class_info, as appropriate:
3191 //   - constructor
3192 //   - properties
DeclareClassProperty(const AstRawString * class_name,ClassLiteralProperty * property,const AstRawString * property_name,ClassLiteralProperty::Kind kind,bool is_static,bool is_constructor,bool is_computed_name,ClassInfo * class_info,bool * ok)3193 void Parser::DeclareClassProperty(const AstRawString* class_name,
3194                                   ClassLiteralProperty* property,
3195                                   const AstRawString* property_name,
3196                                   ClassLiteralProperty::Kind kind,
3197                                   bool is_static, bool is_constructor,
3198                                   bool is_computed_name, ClassInfo* class_info,
3199                                   bool* ok) {
3200   if (is_constructor) {
3201     DCHECK(!class_info->constructor);
3202     class_info->constructor = property->value()->AsFunctionLiteral();
3203     DCHECK_NOT_NULL(class_info->constructor);
3204     class_info->constructor->set_raw_name(
3205         class_name != nullptr ? ast_value_factory()->NewConsString(class_name)
3206                               : nullptr);
3207     return;
3208   }
3209 
3210   if (kind != ClassLiteralProperty::PUBLIC_FIELD &&
3211       kind != ClassLiteralProperty::PRIVATE_FIELD) {
3212     class_info->properties->Add(property, zone());
3213     return;
3214   }
3215 
3216   DCHECK(allow_harmony_public_fields() || allow_harmony_private_fields());
3217 
3218   if (is_static) {
3219     DCHECK(allow_harmony_static_fields());
3220     DCHECK_EQ(kind, ClassLiteralProperty::PUBLIC_FIELD);
3221     class_info->static_fields->Add(property, zone());
3222   } else {
3223     class_info->instance_fields->Add(property, zone());
3224   }
3225 
3226   if (is_computed_name) {
3227     DCHECK_EQ(kind, ClassLiteralProperty::PUBLIC_FIELD);
3228     // We create a synthetic variable name here so that scope
3229     // analysis doesn't dedupe the vars.
3230     Variable* computed_name_var = CreateSyntheticContextVariable(
3231         ClassFieldVariableName(ast_value_factory(),
3232                                class_info->computed_field_count),
3233         CHECK_OK_VOID);
3234     property->set_computed_name_var(computed_name_var);
3235     class_info->properties->Add(property, zone());
3236   }
3237 
3238   if (kind == ClassLiteralProperty::PRIVATE_FIELD) {
3239     Variable* private_field_name_var =
3240         CreateSyntheticContextVariable(property_name, CHECK_OK_VOID);
3241     property->set_private_field_name_var(private_field_name_var);
3242     class_info->properties->Add(property, zone());
3243   }
3244 }
3245 
CreateInitializerFunction(DeclarationScope * scope,ZonePtrList<ClassLiteral::Property> * fields)3246 FunctionLiteral* Parser::CreateInitializerFunction(
3247     DeclarationScope* scope, ZonePtrList<ClassLiteral::Property>* fields) {
3248   DCHECK_EQ(scope->function_kind(),
3249             FunctionKind::kClassFieldsInitializerFunction);
3250   // function() { .. class fields initializer .. }
3251   ZonePtrList<Statement>* statements = NewStatementList(1);
3252   InitializeClassFieldsStatement* static_fields =
3253       factory()->NewInitializeClassFieldsStatement(fields, kNoSourcePosition);
3254   statements->Add(static_fields, zone());
3255   return factory()->NewFunctionLiteral(
3256       ast_value_factory()->empty_string(), scope, statements, 0, 0, 0,
3257       FunctionLiteral::kNoDuplicateParameters,
3258       FunctionLiteral::kAnonymousExpression,
3259       FunctionLiteral::kShouldEagerCompile, scope->start_position(), true,
3260       GetNextFunctionLiteralId());
3261 }
3262 
3263 // This method generates a ClassLiteral AST node.
3264 // It uses the following fields of class_info:
3265 //   - constructor (if missing, it updates it with a default constructor)
3266 //   - proxy
3267 //   - extends
3268 //   - properties
3269 //   - has_name_static_property
3270 //   - has_static_computed_names
RewriteClassLiteral(Scope * block_scope,const AstRawString * name,ClassInfo * class_info,int pos,int end_pos,bool * ok)3271 Expression* Parser::RewriteClassLiteral(Scope* block_scope,
3272                                         const AstRawString* name,
3273                                         ClassInfo* class_info, int pos,
3274                                         int end_pos, bool* ok) {
3275   DCHECK_NOT_NULL(block_scope);
3276   DCHECK_EQ(block_scope->scope_type(), BLOCK_SCOPE);
3277   DCHECK_EQ(block_scope->language_mode(), LanguageMode::kStrict);
3278 
3279   bool has_extends = class_info->extends != nullptr;
3280   bool has_default_constructor = class_info->constructor == nullptr;
3281   if (has_default_constructor) {
3282     class_info->constructor =
3283         DefaultConstructor(name, has_extends, pos, end_pos);
3284   }
3285 
3286   if (name != nullptr) {
3287     DCHECK_NOT_NULL(class_info->variable);
3288     class_info->variable->set_initializer_position(end_pos);
3289   }
3290 
3291   FunctionLiteral* static_fields_initializer = nullptr;
3292   if (class_info->has_static_class_fields) {
3293     static_fields_initializer = CreateInitializerFunction(
3294         class_info->static_fields_scope, class_info->static_fields);
3295   }
3296 
3297   FunctionLiteral* instance_fields_initializer_function = nullptr;
3298   if (class_info->has_instance_class_fields) {
3299     instance_fields_initializer_function = CreateInitializerFunction(
3300         class_info->instance_fields_scope, class_info->instance_fields);
3301     class_info->constructor->set_requires_instance_fields_initializer(true);
3302   }
3303 
3304   ClassLiteral* class_literal = factory()->NewClassLiteral(
3305       block_scope, class_info->variable, class_info->extends,
3306       class_info->constructor, class_info->properties,
3307       static_fields_initializer, instance_fields_initializer_function, pos,
3308       end_pos, class_info->has_name_static_property,
3309       class_info->has_static_computed_names, class_info->is_anonymous);
3310 
3311   AddFunctionForNameInference(class_info->constructor);
3312   return class_literal;
3313 }
3314 
CheckConflictingVarDeclarations(Scope * scope,bool * ok)3315 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) {
3316   Declaration* decl = scope->CheckConflictingVarDeclarations();
3317   if (decl != nullptr) {
3318     // In ES6, conflicting variable bindings are early errors.
3319     const AstRawString* name = decl->proxy()->raw_name();
3320     int position = decl->proxy()->position();
3321     Scanner::Location location =
3322         position == kNoSourcePosition
3323             ? Scanner::Location::invalid()
3324             : Scanner::Location(position, position + 1);
3325     ReportMessageAt(location, MessageTemplate::kVarRedeclaration, name);
3326     *ok = false;
3327   }
3328 }
3329 
IsPropertyWithPrivateFieldKey(Expression * expression)3330 bool Parser::IsPropertyWithPrivateFieldKey(Expression* expression) {
3331   if (!expression->IsProperty()) return false;
3332   Property* property = expression->AsProperty();
3333 
3334   if (!property->key()->IsVariableProxy()) return false;
3335   VariableProxy* key = property->key()->AsVariableProxy();
3336 
3337   return key->is_private_field();
3338 }
3339 
InsertShadowingVarBindingInitializers(Block * inner_block)3340 void Parser::InsertShadowingVarBindingInitializers(Block* inner_block) {
3341   // For each var-binding that shadows a parameter, insert an assignment
3342   // initializing the variable with the parameter.
3343   Scope* inner_scope = inner_block->scope();
3344   DCHECK(inner_scope->is_declaration_scope());
3345   Scope* function_scope = inner_scope->outer_scope();
3346   DCHECK(function_scope->is_function_scope());
3347   BlockState block_state(&scope_, inner_scope);
3348   for (Declaration* decl : *inner_scope->declarations()) {
3349     if (decl->proxy()->var()->mode() != VAR || !decl->IsVariableDeclaration()) {
3350       continue;
3351     }
3352     const AstRawString* name = decl->proxy()->raw_name();
3353     Variable* parameter = function_scope->LookupLocal(name);
3354     if (parameter == nullptr) continue;
3355     VariableProxy* to = NewUnresolved(name);
3356     VariableProxy* from = factory()->NewVariableProxy(parameter);
3357     Expression* assignment =
3358         factory()->NewAssignment(Token::ASSIGN, to, from, kNoSourcePosition);
3359     Statement* statement =
3360         factory()->NewExpressionStatement(assignment, kNoSourcePosition);
3361     inner_block->statements()->InsertAt(0, statement, zone());
3362   }
3363 }
3364 
InsertSloppyBlockFunctionVarBindings(DeclarationScope * scope)3365 void Parser::InsertSloppyBlockFunctionVarBindings(DeclarationScope* scope) {
3366   // For the outermost eval scope, we cannot hoist during parsing: let
3367   // declarations in the surrounding scope may prevent hoisting, but the
3368   // information is unaccessible during parsing. In this case, we hoist later in
3369   // DeclarationScope::Analyze.
3370   if (scope->is_eval_scope() && scope->outer_scope() == original_scope_) {
3371     return;
3372   }
3373   scope->HoistSloppyBlockFunctions(factory());
3374 }
3375 
3376 // ----------------------------------------------------------------------------
3377 // Parser support
3378 
TargetStackContainsLabel(const AstRawString * label)3379 bool Parser::TargetStackContainsLabel(const AstRawString* label) {
3380   for (ParserTarget* t = target_stack_; t != nullptr; t = t->previous()) {
3381     if (ContainsLabel(t->statement()->labels(), label)) return true;
3382   }
3383   return false;
3384 }
3385 
3386 
LookupBreakTarget(const AstRawString * label,bool * ok)3387 BreakableStatement* Parser::LookupBreakTarget(const AstRawString* label,
3388                                               bool* ok) {
3389   bool anonymous = label == nullptr;
3390   for (ParserTarget* t = target_stack_; t != nullptr; t = t->previous()) {
3391     BreakableStatement* stat = t->statement();
3392     if ((anonymous && stat->is_target_for_anonymous()) ||
3393         (!anonymous && ContainsLabel(stat->labels(), label))) {
3394       return stat;
3395     }
3396   }
3397   return nullptr;
3398 }
3399 
3400 
LookupContinueTarget(const AstRawString * label,bool * ok)3401 IterationStatement* Parser::LookupContinueTarget(const AstRawString* label,
3402                                                  bool* ok) {
3403   bool anonymous = label == nullptr;
3404   for (ParserTarget* t = target_stack_; t != nullptr; t = t->previous()) {
3405     IterationStatement* stat = t->statement()->AsIterationStatement();
3406     if (stat == nullptr) continue;
3407 
3408     DCHECK(stat->is_target_for_anonymous());
3409     if (anonymous || ContainsLabel(stat->labels(), label)) {
3410       return stat;
3411     }
3412   }
3413   return nullptr;
3414 }
3415 
3416 
HandleSourceURLComments(Isolate * isolate,Handle<Script> script)3417 void Parser::HandleSourceURLComments(Isolate* isolate, Handle<Script> script) {
3418   Handle<String> source_url = scanner_.SourceUrl(isolate);
3419   if (!source_url.is_null()) {
3420     script->set_source_url(*source_url);
3421   }
3422   Handle<String> source_mapping_url = scanner_.SourceMappingUrl(isolate);
3423   if (!source_mapping_url.is_null()) {
3424     script->set_source_mapping_url(*source_mapping_url);
3425   }
3426 }
3427 
UpdateStatistics(Isolate * isolate,Handle<Script> script)3428 void Parser::UpdateStatistics(Isolate* isolate, Handle<Script> script) {
3429   // Move statistics to Isolate.
3430   for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
3431        ++feature) {
3432     if (use_counts_[feature] > 0) {
3433       isolate->CountUsage(v8::Isolate::UseCounterFeature(feature));
3434     }
3435   }
3436   if (scanner_.FoundHtmlComment()) {
3437     isolate->CountUsage(v8::Isolate::kHtmlComment);
3438     if (script->line_offset() == 0 && script->column_offset() == 0) {
3439       isolate->CountUsage(v8::Isolate::kHtmlCommentInExternalScript);
3440     }
3441   }
3442   isolate->counters()->total_preparse_skipped()->Increment(
3443       total_preparse_skipped_);
3444 }
3445 
ParseOnBackground(ParseInfo * info)3446 void Parser::ParseOnBackground(ParseInfo* info) {
3447   RuntimeCallTimerScope runtimeTimer(
3448       runtime_call_stats_, RuntimeCallCounterId::kParseBackgroundProgram);
3449   parsing_on_main_thread_ = false;
3450   if (!info->script().is_null()) {
3451     set_script_id(info->script()->id());
3452   }
3453 
3454   DCHECK_NULL(info->literal());
3455   FunctionLiteral* result = nullptr;
3456 
3457   scanner_.Initialize(info->character_stream(), info->is_module());
3458   DCHECK(info->maybe_outer_scope_info().is_null());
3459 
3460   DCHECK(original_scope_);
3461 
3462   // When streaming, we don't know the length of the source until we have parsed
3463   // it. The raw data can be UTF-8, so we wouldn't know the source length until
3464   // we have decoded it anyway even if we knew the raw data length (which we
3465   // don't). We work around this by storing all the scopes which need their end
3466   // position set at the end of the script (the top scope and possible eval
3467   // scopes) and set their end position after we know the script length.
3468   if (info->is_toplevel()) {
3469     fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
3470     result = DoParseProgram(/* isolate = */ nullptr, info);
3471   } else {
3472     result =
3473         DoParseFunction(/* isolate = */ nullptr, info, info->function_name());
3474   }
3475   MaybeResetCharacterStream(info, result);
3476 
3477   info->set_literal(result);
3478 
3479   // We cannot internalize on a background thread; a foreground task will take
3480   // care of calling AstValueFactory::Internalize just before compilation.
3481 }
3482 
OpenTemplateLiteral(int pos)3483 Parser::TemplateLiteralState Parser::OpenTemplateLiteral(int pos) {
3484   return new (zone()) TemplateLiteral(zone(), pos);
3485 }
3486 
AddTemplateSpan(TemplateLiteralState * state,bool should_cook,bool tail)3487 void Parser::AddTemplateSpan(TemplateLiteralState* state, bool should_cook,
3488                              bool tail) {
3489   int end = scanner()->location().end_pos - (tail ? 1 : 2);
3490   const AstRawString* raw = scanner()->CurrentRawSymbol(ast_value_factory());
3491   if (should_cook) {
3492     const AstRawString* cooked = scanner()->CurrentSymbol(ast_value_factory());
3493     (*state)->AddTemplateSpan(cooked, raw, end, zone());
3494   } else {
3495     (*state)->AddTemplateSpan(nullptr, raw, end, zone());
3496   }
3497 }
3498 
3499 
AddTemplateExpression(TemplateLiteralState * state,Expression * expression)3500 void Parser::AddTemplateExpression(TemplateLiteralState* state,
3501                                    Expression* expression) {
3502   (*state)->AddExpression(expression, zone());
3503 }
3504 
3505 
CloseTemplateLiteral(TemplateLiteralState * state,int start,Expression * tag)3506 Expression* Parser::CloseTemplateLiteral(TemplateLiteralState* state, int start,
3507                                          Expression* tag) {
3508   TemplateLiteral* lit = *state;
3509   int pos = lit->position();
3510   const ZonePtrList<const AstRawString>* cooked_strings = lit->cooked();
3511   const ZonePtrList<const AstRawString>* raw_strings = lit->raw();
3512   const ZonePtrList<Expression>* expressions = lit->expressions();
3513   DCHECK_EQ(cooked_strings->length(), raw_strings->length());
3514   DCHECK_EQ(cooked_strings->length(), expressions->length() + 1);
3515 
3516   if (!tag) {
3517     if (cooked_strings->length() == 1) {
3518       return factory()->NewStringLiteral(cooked_strings->first(), pos);
3519     }
3520     return factory()->NewTemplateLiteral(cooked_strings, expressions, pos);
3521   } else {
3522     // GetTemplateObject
3523     Expression* template_object =
3524         factory()->NewGetTemplateObject(cooked_strings, raw_strings, pos);
3525 
3526     // Call TagFn
3527     ZonePtrList<Expression>* call_args =
3528         new (zone()) ZonePtrList<Expression>(expressions->length() + 1, zone());
3529     call_args->Add(template_object, zone());
3530     call_args->AddAll(*expressions, zone());
3531     return factory()->NewTaggedTemplate(tag, call_args, pos);
3532   }
3533 }
3534 
3535 namespace {
3536 
OnlyLastArgIsSpread(ZonePtrList<Expression> * args)3537 bool OnlyLastArgIsSpread(ZonePtrList<Expression>* args) {
3538   for (int i = 0; i < args->length() - 1; i++) {
3539     if (args->at(i)->IsSpread()) {
3540       return false;
3541     }
3542   }
3543   return args->at(args->length() - 1)->IsSpread();
3544 }
3545 
3546 }  // namespace
3547 
ArrayLiteralFromListWithSpread(ZonePtrList<Expression> * list)3548 ArrayLiteral* Parser::ArrayLiteralFromListWithSpread(
3549     ZonePtrList<Expression>* list) {
3550   // If there's only a single spread argument, a fast path using CallWithSpread
3551   // is taken.
3552   DCHECK_LT(1, list->length());
3553 
3554   // The arguments of the spread call become a single ArrayLiteral.
3555   int first_spread = 0;
3556   for (; first_spread < list->length() && !list->at(first_spread)->IsSpread();
3557        ++first_spread) {
3558   }
3559 
3560   DCHECK_LT(first_spread, list->length());
3561   return factory()->NewArrayLiteral(list, first_spread, kNoSourcePosition);
3562 }
3563 
SpreadCall(Expression * function,ZonePtrList<Expression> * args_list,int pos,Call::PossiblyEval is_possibly_eval)3564 Expression* Parser::SpreadCall(Expression* function,
3565                                ZonePtrList<Expression>* args_list, int pos,
3566                                Call::PossiblyEval is_possibly_eval) {
3567   // Handle this case in BytecodeGenerator.
3568   if (OnlyLastArgIsSpread(args_list) || function->IsSuperCallReference()) {
3569     return factory()->NewCall(function, args_list, pos);
3570   }
3571 
3572   ZonePtrList<Expression>* args =
3573       new (zone()) ZonePtrList<Expression>(3, zone());
3574   if (function->IsProperty()) {
3575     // Method calls
3576     if (function->AsProperty()->IsSuperAccess()) {
3577       Expression* home = ThisExpression(kNoSourcePosition);
3578       args->Add(function, zone());
3579       args->Add(home, zone());
3580     } else {
3581       Variable* temp = NewTemporary(ast_value_factory()->empty_string());
3582       VariableProxy* obj = factory()->NewVariableProxy(temp);
3583       Assignment* assign_obj = factory()->NewAssignment(
3584           Token::ASSIGN, obj, function->AsProperty()->obj(), kNoSourcePosition);
3585       function = factory()->NewProperty(
3586           assign_obj, function->AsProperty()->key(), kNoSourcePosition);
3587       args->Add(function, zone());
3588       obj = factory()->NewVariableProxy(temp);
3589       args->Add(obj, zone());
3590     }
3591   } else {
3592     // Non-method calls
3593     args->Add(function, zone());
3594     args->Add(factory()->NewUndefinedLiteral(kNoSourcePosition), zone());
3595   }
3596   args->Add(ArrayLiteralFromListWithSpread(args_list), zone());
3597   return factory()->NewCallRuntime(Context::REFLECT_APPLY_INDEX, args, pos);
3598 }
3599 
SpreadCallNew(Expression * function,ZonePtrList<Expression> * args_list,int pos)3600 Expression* Parser::SpreadCallNew(Expression* function,
3601                                   ZonePtrList<Expression>* args_list, int pos) {
3602   if (OnlyLastArgIsSpread(args_list)) {
3603     // Handle in BytecodeGenerator.
3604     return factory()->NewCallNew(function, args_list, pos);
3605   }
3606   ZonePtrList<Expression>* args =
3607       new (zone()) ZonePtrList<Expression>(2, zone());
3608   args->Add(function, zone());
3609   args->Add(ArrayLiteralFromListWithSpread(args_list), zone());
3610 
3611   return factory()->NewCallRuntime(Context::REFLECT_CONSTRUCT_INDEX, args, pos);
3612 }
3613 
3614 
SetLanguageMode(Scope * scope,LanguageMode mode)3615 void Parser::SetLanguageMode(Scope* scope, LanguageMode mode) {
3616   v8::Isolate::UseCounterFeature feature;
3617   if (is_sloppy(mode))
3618     feature = v8::Isolate::kSloppyMode;
3619   else if (is_strict(mode))
3620     feature = v8::Isolate::kStrictMode;
3621   else
3622     UNREACHABLE();
3623   ++use_counts_[feature];
3624   scope->SetLanguageMode(mode);
3625 }
3626 
SetAsmModule()3627 void Parser::SetAsmModule() {
3628   // Store the usage count; The actual use counter on the isolate is
3629   // incremented after parsing is done.
3630   ++use_counts_[v8::Isolate::kUseAsm];
3631   DCHECK(scope()->is_declaration_scope());
3632   scope()->AsDeclarationScope()->set_asm_module();
3633 }
3634 
ExpressionListToExpression(ZonePtrList<Expression> * args)3635 Expression* Parser::ExpressionListToExpression(ZonePtrList<Expression>* args) {
3636   Expression* expr = args->at(0);
3637   for (int i = 1; i < args->length(); ++i) {
3638     expr = factory()->NewBinaryOperation(Token::COMMA, expr, args->at(i),
3639                                          expr->position());
3640   }
3641   return expr;
3642 }
3643 
3644 // This method completes the desugaring of the body of async_function.
RewriteAsyncFunctionBody(ZonePtrList<Statement> * body,Block * block,Expression * return_value,bool * ok)3645 void Parser::RewriteAsyncFunctionBody(ZonePtrList<Statement>* body,
3646                                       Block* block, Expression* return_value,
3647                                       bool* ok) {
3648   // function async_function() {
3649   //   .generator_object = %CreateJSGeneratorObject();
3650   //   BuildRejectPromiseOnException({
3651   //     ... block ...
3652   //     return %ResolvePromise(.promise, expr), .promise;
3653   //   })
3654   // }
3655 
3656   return_value = BuildResolvePromise(return_value, return_value->position());
3657   block->statements()->Add(
3658       factory()->NewReturnStatement(return_value, return_value->position()),
3659       zone());
3660   block = BuildRejectPromiseOnException(block);
3661   body->Add(block, zone());
3662 }
3663 
RewriteDestructuringAssignments()3664 void Parser::RewriteDestructuringAssignments() {
3665   const auto& assignments =
3666       function_state_->destructuring_assignments_to_rewrite();
3667   for (int i = assignments.length() - 1; i >= 0; --i) {
3668     // Rewrite list in reverse, so that nested assignment patterns are rewritten
3669     // correctly.
3670     RewritableExpression* to_rewrite = assignments[i];
3671     DCHECK_NOT_NULL(to_rewrite);
3672     if (!to_rewrite->is_rewritten()) {
3673       // Since this function is called at the end of parsing the program,
3674       // pair.scope may already have been removed by FinalizeBlockScope in the
3675       // meantime.
3676       Scope* scope = to_rewrite->scope()->GetUnremovedScope();
3677       // Scope at the time of the rewriting and the original parsing
3678       // should be in the same function.
3679       DCHECK(scope->GetClosureScope() == scope_->GetClosureScope());
3680       BlockState block_state(&scope_, scope);
3681       RewriteDestructuringAssignment(to_rewrite);
3682     }
3683   }
3684 }
3685 
QueueDestructuringAssignmentForRewriting(RewritableExpression * expr)3686 void Parser::QueueDestructuringAssignmentForRewriting(
3687     RewritableExpression* expr) {
3688   function_state_->AddDestructuringAssignment(expr);
3689 }
3690 
SetFunctionNameFromPropertyName(LiteralProperty * property,const AstRawString * name,const AstRawString * prefix)3691 void Parser::SetFunctionNameFromPropertyName(LiteralProperty* property,
3692                                              const AstRawString* name,
3693                                              const AstRawString* prefix) {
3694   // Ensure that the function we are going to create has shared name iff
3695   // we are not going to set it later.
3696   if (property->NeedsSetFunctionName()) {
3697     name = nullptr;
3698     prefix = nullptr;
3699   } else {
3700     // If the property value is an anonymous function or an anonymous class or
3701     // a concise method or an accessor function which doesn't require the name
3702     // to be set then the shared name must be provided.
3703     DCHECK_IMPLIES(property->value()->IsAnonymousFunctionDefinition() ||
3704                        property->value()->IsConciseMethodDefinition() ||
3705                        property->value()->IsAccessorFunctionDefinition(),
3706                    name != nullptr);
3707   }
3708 
3709   Expression* value = property->value();
3710   SetFunctionName(value, name, prefix);
3711 }
3712 
SetFunctionNameFromPropertyName(ObjectLiteralProperty * property,const AstRawString * name,const AstRawString * prefix)3713 void Parser::SetFunctionNameFromPropertyName(ObjectLiteralProperty* property,
3714                                              const AstRawString* name,
3715                                              const AstRawString* prefix) {
3716   // Ignore "__proto__" as a name when it's being used to set the [[Prototype]]
3717   // of an object literal.
3718   // See ES #sec-__proto__-property-names-in-object-initializers.
3719   if (property->IsPrototype()) return;
3720 
3721   DCHECK(!property->value()->IsAnonymousFunctionDefinition() ||
3722          property->kind() == ObjectLiteralProperty::COMPUTED);
3723 
3724   SetFunctionNameFromPropertyName(static_cast<LiteralProperty*>(property), name,
3725                                   prefix);
3726 }
3727 
SetFunctionNameFromIdentifierRef(Expression * value,Expression * identifier)3728 void Parser::SetFunctionNameFromIdentifierRef(Expression* value,
3729                                               Expression* identifier) {
3730   if (!identifier->IsVariableProxy()) return;
3731   SetFunctionName(value, identifier->AsVariableProxy()->raw_name());
3732 }
3733 
SetFunctionName(Expression * value,const AstRawString * name,const AstRawString * prefix)3734 void Parser::SetFunctionName(Expression* value, const AstRawString* name,
3735                              const AstRawString* prefix) {
3736   if (!value->IsAnonymousFunctionDefinition() &&
3737       !value->IsConciseMethodDefinition() &&
3738       !value->IsAccessorFunctionDefinition()) {
3739     return;
3740   }
3741   auto function = value->AsFunctionLiteral();
3742   if (value->IsClassLiteral()) {
3743     function = value->AsClassLiteral()->constructor();
3744   }
3745   if (function != nullptr) {
3746     AstConsString* cons_name = nullptr;
3747     if (name != nullptr) {
3748       if (prefix != nullptr) {
3749         cons_name = ast_value_factory()->NewConsString(prefix, name);
3750       } else {
3751         cons_name = ast_value_factory()->NewConsString(name);
3752       }
3753     } else {
3754       DCHECK_NULL(prefix);
3755     }
3756     function->set_raw_name(cons_name);
3757   }
3758 }
3759 
CheckCallable(Variable * var,Expression * error,int pos)3760 Statement* Parser::CheckCallable(Variable* var, Expression* error, int pos) {
3761   const int nopos = kNoSourcePosition;
3762   Statement* validate_var;
3763   {
3764     Expression* type_of = factory()->NewUnaryOperation(
3765         Token::TYPEOF, factory()->NewVariableProxy(var), nopos);
3766     Expression* function_literal = factory()->NewStringLiteral(
3767         ast_value_factory()->function_string(), nopos);
3768     Expression* condition = factory()->NewCompareOperation(
3769         Token::EQ_STRICT, type_of, function_literal, nopos);
3770 
3771     Statement* throw_call = factory()->NewExpressionStatement(error, pos);
3772 
3773     validate_var = factory()->NewIfStatement(
3774         condition, factory()->NewEmptyStatement(nopos), throw_call, nopos);
3775   }
3776   return validate_var;
3777 }
3778 
BuildIteratorClose(ZonePtrList<Statement> * statements,Variable * iterator,Variable * input,Variable * var_output,IteratorType type)3779 void Parser::BuildIteratorClose(ZonePtrList<Statement>* statements,
3780                                 Variable* iterator, Variable* input,
3781                                 Variable* var_output, IteratorType type) {
3782   //
3783   // This function adds four statements to [statements], corresponding to the
3784   // following code:
3785   //
3786   //   let iteratorReturn = iterator.return;
3787   //   if (IS_NULL_OR_UNDEFINED(iteratorReturn) {
3788   //     return {value: input, done: true};
3789   //   }
3790   //   output = %_Call(iteratorReturn, iterator, input);
3791   //   if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
3792   //
3793 
3794   const int nopos = kNoSourcePosition;
3795 
3796   // let iteratorReturn = iterator.return;
3797   Variable* var_return = var_output;  // Reusing the output variable.
3798   Statement* get_return;
3799   {
3800     Expression* iterator_proxy = factory()->NewVariableProxy(iterator);
3801     Expression* literal = factory()->NewStringLiteral(
3802         ast_value_factory()->return_string(), nopos);
3803     Expression* property =
3804         factory()->NewProperty(iterator_proxy, literal, nopos);
3805     Expression* return_proxy = factory()->NewVariableProxy(var_return);
3806     Expression* assignment =
3807         factory()->NewAssignment(Token::ASSIGN, return_proxy, property, nopos);
3808     get_return = factory()->NewExpressionStatement(assignment, nopos);
3809   }
3810 
3811   // if (IS_NULL_OR_UNDEFINED(iteratorReturn) {
3812   //   return {value: input, done: true};
3813   // }
3814   Statement* check_return;
3815   {
3816     Expression* condition = factory()->NewCompareOperation(
3817         Token::EQ, factory()->NewVariableProxy(var_return),
3818         factory()->NewNullLiteral(nopos), nopos);
3819 
3820     Expression* value = factory()->NewVariableProxy(input);
3821 
3822     Statement* return_input = BuildReturnStatement(value, nopos);
3823 
3824     check_return = factory()->NewIfStatement(
3825         condition, return_input, factory()->NewEmptyStatement(nopos), nopos);
3826   }
3827 
3828   // output = %_Call(iteratorReturn, iterator, input);
3829   Statement* call_return;
3830   {
3831     auto args = new (zone()) ZonePtrList<Expression>(3, zone());
3832     args->Add(factory()->NewVariableProxy(var_return), zone());
3833     args->Add(factory()->NewVariableProxy(iterator), zone());
3834     args->Add(factory()->NewVariableProxy(input), zone());
3835 
3836     Expression* call =
3837         factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos);
3838     if (type == IteratorType::kAsync) {
3839       function_state_->AddSuspend();
3840       call = factory()->NewAwait(call, nopos);
3841     }
3842     Expression* output_proxy = factory()->NewVariableProxy(var_output);
3843     Expression* assignment =
3844         factory()->NewAssignment(Token::ASSIGN, output_proxy, call, nopos);
3845     call_return = factory()->NewExpressionStatement(assignment, nopos);
3846   }
3847 
3848   // if (!IS_RECEIVER(output)) %ThrowIteratorResultNotAnObject(output);
3849   Statement* validate_output;
3850   {
3851     Expression* is_receiver_call;
3852     {
3853       auto args = new (zone()) ZonePtrList<Expression>(1, zone());
3854       args->Add(factory()->NewVariableProxy(var_output), zone());
3855       is_receiver_call =
3856           factory()->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos);
3857     }
3858 
3859     Statement* throw_call;
3860     {
3861       auto args = new (zone()) ZonePtrList<Expression>(1, zone());
3862       args->Add(factory()->NewVariableProxy(var_output), zone());
3863       Expression* call = factory()->NewCallRuntime(
3864           Runtime::kThrowIteratorResultNotAnObject, args, nopos);
3865       throw_call = factory()->NewExpressionStatement(call, nopos);
3866     }
3867 
3868     validate_output = factory()->NewIfStatement(
3869         is_receiver_call, factory()->NewEmptyStatement(nopos), throw_call,
3870         nopos);
3871   }
3872 
3873   statements->Add(get_return, zone());
3874   statements->Add(check_return, zone());
3875   statements->Add(call_return, zone());
3876   statements->Add(validate_output, zone());
3877 }
3878 
FinalizeIteratorUse(Variable * completion,Expression * condition,Variable * iter,Block * iterator_use,Block * target,IteratorType type)3879 void Parser::FinalizeIteratorUse(Variable* completion, Expression* condition,
3880                                  Variable* iter, Block* iterator_use,
3881                                  Block* target, IteratorType type) {
3882   //
3883   // This function adds two statements to [target], corresponding to the
3884   // following code:
3885   //
3886   //   completion = kNormalCompletion;
3887   //   try {
3888   //     try {
3889   //       iterator_use
3890   //     } catch(e) {
3891   //       if (completion === kAbruptCompletion) completion = kThrowCompletion;
3892   //       %ReThrow(e);
3893   //     }
3894   //   } finally {
3895   //     if (condition) {
3896   //       #BuildIteratorCloseForCompletion(iter, completion)
3897   //     }
3898   //   }
3899   //
3900 
3901   const int nopos = kNoSourcePosition;
3902 
3903   // completion = kNormalCompletion;
3904   Statement* initialize_completion;
3905   {
3906     Expression* proxy = factory()->NewVariableProxy(completion);
3907     Expression* assignment = factory()->NewAssignment(
3908         Token::ASSIGN, proxy,
3909         factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos);
3910     initialize_completion =
3911         factory()->NewExpressionStatement(assignment, nopos);
3912   }
3913 
3914   // if (completion === kAbruptCompletion) completion = kThrowCompletion;
3915   Statement* set_completion_throw;
3916   {
3917     Expression* condition = factory()->NewCompareOperation(
3918         Token::EQ_STRICT, factory()->NewVariableProxy(completion),
3919         factory()->NewSmiLiteral(Parser::kAbruptCompletion, nopos), nopos);
3920 
3921     Expression* proxy = factory()->NewVariableProxy(completion);
3922     Expression* assignment = factory()->NewAssignment(
3923         Token::ASSIGN, proxy,
3924         factory()->NewSmiLiteral(Parser::kThrowCompletion, nopos), nopos);
3925     Statement* statement = factory()->NewExpressionStatement(assignment, nopos);
3926     set_completion_throw = factory()->NewIfStatement(
3927         condition, statement, factory()->NewEmptyStatement(nopos), nopos);
3928   }
3929 
3930   // if (condition) {
3931   //   #BuildIteratorCloseForCompletion(iter, completion)
3932   // }
3933   Block* maybe_close;
3934   {
3935     Block* block = factory()->NewBlock(2, true);
3936     Expression* proxy = factory()->NewVariableProxy(completion);
3937     BuildIteratorCloseForCompletion(block->statements(), iter, proxy, type);
3938     DCHECK_EQ(block->statements()->length(), 2);
3939 
3940     maybe_close = IgnoreCompletion(factory()->NewIfStatement(
3941         condition, block, factory()->NewEmptyStatement(nopos), nopos));
3942   }
3943 
3944   // try { #try_block }
3945   // catch(e) {
3946   //   #set_completion_throw;
3947   //   %ReThrow(e);
3948   // }
3949   Statement* try_catch;
3950   {
3951     Scope* catch_scope = NewHiddenCatchScope();
3952 
3953     Statement* rethrow;
3954     // We use %ReThrow rather than the ordinary throw because we want to
3955     // preserve the original exception message.  This is also why we create a
3956     // TryCatchStatementForReThrow below (which does not clear the pending
3957     // message), rather than a TryCatchStatement.
3958     {
3959       auto args = new (zone()) ZonePtrList<Expression>(1, zone());
3960       args->Add(factory()->NewVariableProxy(catch_scope->catch_variable()),
3961                 zone());
3962       rethrow = factory()->NewExpressionStatement(
3963           factory()->NewCallRuntime(Runtime::kReThrow, args, nopos), nopos);
3964     }
3965 
3966     Block* catch_block = factory()->NewBlock(2, false);
3967     catch_block->statements()->Add(set_completion_throw, zone());
3968     catch_block->statements()->Add(rethrow, zone());
3969 
3970     try_catch = factory()->NewTryCatchStatementForReThrow(
3971         iterator_use, catch_scope, catch_block, nopos);
3972   }
3973 
3974   // try { #try_catch } finally { #maybe_close }
3975   Statement* try_finally;
3976   {
3977     Block* try_block = factory()->NewBlock(1, false);
3978     try_block->statements()->Add(try_catch, zone());
3979 
3980     try_finally =
3981         factory()->NewTryFinallyStatement(try_block, maybe_close, nopos);
3982   }
3983 
3984   target->statements()->Add(initialize_completion, zone());
3985   target->statements()->Add(try_finally, zone());
3986 }
3987 
BuildIteratorCloseForCompletion(ZonePtrList<Statement> * statements,Variable * iterator,Expression * completion,IteratorType type)3988 void Parser::BuildIteratorCloseForCompletion(ZonePtrList<Statement>* statements,
3989                                              Variable* iterator,
3990                                              Expression* completion,
3991                                              IteratorType type) {
3992   //
3993   // This function adds two statements to [statements], corresponding to the
3994   // following code:
3995   //
3996   //   let iteratorReturn = iterator.return;
3997   //   if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) {
3998   //     if (completion === kThrowCompletion) {
3999   //       if (!IS_CALLABLE(iteratorReturn)) {
4000   //         throw MakeTypeError(kReturnMethodNotCallable);
4001   //       }
4002   //       [if (IteratorType == kAsync)]
4003   //           try { Await(%_Call(iteratorReturn, iterator) } catch (_) { }
4004   //       [else]
4005   //           try { %_Call(iteratorReturn, iterator) } catch (_) { }
4006   //       [endif]
4007   //     } else {
4008   //       [if (IteratorType == kAsync)]
4009   //           let output = Await(%_Call(iteratorReturn, iterator));
4010   //       [else]
4011   //           let output = %_Call(iteratorReturn, iterator);
4012   //       [endif]
4013   //       if (!IS_RECEIVER(output)) {
4014   //         %ThrowIterResultNotAnObject(output);
4015   //       }
4016   //     }
4017   //   }
4018   //
4019 
4020   const int nopos = kNoSourcePosition;
4021   // let iteratorReturn = iterator.return;
4022   Variable* var_return = NewTemporary(ast_value_factory()->empty_string());
4023   Statement* get_return;
4024   {
4025     Expression* iterator_proxy = factory()->NewVariableProxy(iterator);
4026     Expression* literal = factory()->NewStringLiteral(
4027         ast_value_factory()->return_string(), nopos);
4028     Expression* property =
4029         factory()->NewProperty(iterator_proxy, literal, nopos);
4030     Expression* return_proxy = factory()->NewVariableProxy(var_return);
4031     Expression* assignment =
4032         factory()->NewAssignment(Token::ASSIGN, return_proxy, property, nopos);
4033     get_return = factory()->NewExpressionStatement(assignment, nopos);
4034   }
4035 
4036   // if (!IS_CALLABLE(iteratorReturn)) {
4037   //   throw MakeTypeError(kReturnMethodNotCallable);
4038   // }
4039   Statement* check_return_callable;
4040   {
4041     Expression* throw_expr =
4042         NewThrowTypeError(MessageTemplate::kReturnMethodNotCallable,
4043                           ast_value_factory()->empty_string(), nopos);
4044     check_return_callable = CheckCallable(var_return, throw_expr, nopos);
4045   }
4046 
4047   // try { %_Call(iteratorReturn, iterator) } catch (_) { }
4048   Statement* try_call_return;
4049   {
4050     auto args = new (zone()) ZonePtrList<Expression>(2, zone());
4051     args->Add(factory()->NewVariableProxy(var_return), zone());
4052     args->Add(factory()->NewVariableProxy(iterator), zone());
4053 
4054     Expression* call =
4055         factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos);
4056 
4057     if (type == IteratorType::kAsync) {
4058       function_state_->AddSuspend();
4059       call = factory()->NewAwait(call, nopos);
4060     }
4061 
4062     Block* try_block = factory()->NewBlock(1, false);
4063     try_block->statements()->Add(factory()->NewExpressionStatement(call, nopos),
4064                                  zone());
4065 
4066     Block* catch_block = factory()->NewBlock(0, false);
4067     try_call_return =
4068         factory()->NewTryCatchStatement(try_block, nullptr, catch_block, nopos);
4069   }
4070 
4071   // let output = %_Call(iteratorReturn, iterator);
4072   // if (!IS_RECEIVER(output)) {
4073   //   %ThrowIteratorResultNotAnObject(output);
4074   // }
4075   Block* validate_return;
4076   {
4077     Variable* var_output = NewTemporary(ast_value_factory()->empty_string());
4078     Statement* call_return;
4079     {
4080       auto args = new (zone()) ZonePtrList<Expression>(2, zone());
4081       args->Add(factory()->NewVariableProxy(var_return), zone());
4082       args->Add(factory()->NewVariableProxy(iterator), zone());
4083       Expression* call =
4084           factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos);
4085       if (type == IteratorType::kAsync) {
4086         function_state_->AddSuspend();
4087         call = factory()->NewAwait(call, nopos);
4088       }
4089 
4090       Expression* output_proxy = factory()->NewVariableProxy(var_output);
4091       Expression* assignment =
4092           factory()->NewAssignment(Token::ASSIGN, output_proxy, call, nopos);
4093       call_return = factory()->NewExpressionStatement(assignment, nopos);
4094     }
4095 
4096     Expression* is_receiver_call;
4097     {
4098       auto args = new (zone()) ZonePtrList<Expression>(1, zone());
4099       args->Add(factory()->NewVariableProxy(var_output), zone());
4100       is_receiver_call =
4101           factory()->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos);
4102     }
4103 
4104     Statement* throw_call;
4105     {
4106       auto args = new (zone()) ZonePtrList<Expression>(1, zone());
4107       args->Add(factory()->NewVariableProxy(var_output), zone());
4108       Expression* call = factory()->NewCallRuntime(
4109           Runtime::kThrowIteratorResultNotAnObject, args, nopos);
4110       throw_call = factory()->NewExpressionStatement(call, nopos);
4111     }
4112 
4113     Statement* check_return = factory()->NewIfStatement(
4114         is_receiver_call, factory()->NewEmptyStatement(nopos), throw_call,
4115         nopos);
4116 
4117     validate_return = factory()->NewBlock(2, false);
4118     validate_return->statements()->Add(call_return, zone());
4119     validate_return->statements()->Add(check_return, zone());
4120   }
4121 
4122   // if (completion === kThrowCompletion) {
4123   //   #check_return_callable;
4124   //   #try_call_return;
4125   // } else {
4126   //   #validate_return;
4127   // }
4128   Statement* call_return_carefully;
4129   {
4130     Expression* condition = factory()->NewCompareOperation(
4131         Token::EQ_STRICT, completion,
4132         factory()->NewSmiLiteral(Parser::kThrowCompletion, nopos), nopos);
4133 
4134     Block* then_block = factory()->NewBlock(2, false);
4135     then_block->statements()->Add(check_return_callable, zone());
4136     then_block->statements()->Add(try_call_return, zone());
4137 
4138     call_return_carefully = factory()->NewIfStatement(condition, then_block,
4139                                                       validate_return, nopos);
4140   }
4141 
4142   // if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) { ... }
4143   Statement* maybe_call_return;
4144   {
4145     Expression* condition = factory()->NewCompareOperation(
4146         Token::EQ, factory()->NewVariableProxy(var_return),
4147         factory()->NewNullLiteral(nopos), nopos);
4148 
4149     maybe_call_return = factory()->NewIfStatement(
4150         condition, factory()->NewEmptyStatement(nopos), call_return_carefully,
4151         nopos);
4152   }
4153 
4154   statements->Add(get_return, zone());
4155   statements->Add(maybe_call_return, zone());
4156 }
4157 
FinalizeForOfStatement(ForOfStatement * loop,Variable * var_completion,IteratorType type,int pos)4158 Statement* Parser::FinalizeForOfStatement(ForOfStatement* loop,
4159                                           Variable* var_completion,
4160                                           IteratorType type, int pos) {
4161   //
4162   // This function replaces the loop with the following wrapping:
4163   //
4164   //   completion = kNormalCompletion;
4165   //   try {
4166   //     try {
4167   //       #loop;
4168   //     } catch(e) {
4169   //       if (completion === kAbruptCompletion) completion = kThrowCompletion;
4170   //       %ReThrow(e);
4171   //     }
4172   //   } finally {
4173   //     if (!(completion === kNormalCompletion)) {
4174   //       #BuildIteratorCloseForCompletion(#iterator, completion)
4175   //     }
4176   //   }
4177   //
4178   // Note that the loop's body and its assign_each already contain appropriate
4179   // assignments to completion (see InitializeForOfStatement).
4180   //
4181 
4182   const int nopos = kNoSourcePosition;
4183 
4184   // !(completion === kNormalCompletion)
4185   Expression* closing_condition;
4186   {
4187     Expression* cmp = factory()->NewCompareOperation(
4188         Token::EQ_STRICT, factory()->NewVariableProxy(var_completion),
4189         factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos);
4190     closing_condition = factory()->NewUnaryOperation(Token::NOT, cmp, nopos);
4191   }
4192 
4193   Block* final_loop = factory()->NewBlock(2, false);
4194   {
4195     Block* try_block = factory()->NewBlock(1, false);
4196     try_block->statements()->Add(loop, zone());
4197 
4198     FinalizeIteratorUse(var_completion, closing_condition, loop->iterator(),
4199                         try_block, final_loop, type);
4200   }
4201 
4202   return final_loop;
4203 }
4204 
4205 #undef CHECK_OK
4206 #undef CHECK_OK_VOID
4207 #undef CHECK_FAILED
4208 
4209 }  // namespace internal
4210 }  // namespace v8
4211