• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/ast/ast-function-literal-id-reindexer.h"
11 #include "src/ast/ast-traversal-visitor.h"
12 #include "src/ast/ast.h"
13 #include "src/ast/source-range-ast-visitor.h"
14 #include "src/base/ieee754.h"
15 #include "src/base/overflowing-math.h"
16 #include "src/base/platform/platform.h"
17 #include "src/codegen/bailout-reason.h"
18 #include "src/common/globals.h"
19 #include "src/common/message-template.h"
20 #include "src/compiler-dispatcher/lazy-compile-dispatcher.h"
21 #include "src/heap/parked-scope.h"
22 #include "src/logging/counters.h"
23 #include "src/logging/log.h"
24 #include "src/logging/runtime-call-stats-scope.h"
25 #include "src/numbers/conversions-inl.h"
26 #include "src/objects/scope-info.h"
27 #include "src/parsing/parse-info.h"
28 #include "src/parsing/rewriter.h"
29 #include "src/runtime/runtime.h"
30 #include "src/strings/char-predicates-inl.h"
31 #include "src/strings/string-stream.h"
32 #include "src/strings/unicode-inl.h"
33 #include "src/tracing/trace-event.h"
34 #include "src/zone/zone-list-inl.h"
35 
36 namespace v8 {
37 namespace internal {
38 
DefaultConstructor(const AstRawString * name,bool call_super,int pos,int end_pos)39 FunctionLiteral* Parser::DefaultConstructor(const AstRawString* name,
40                                             bool call_super, int pos,
41                                             int end_pos) {
42   int expected_property_count = 0;
43   const int parameter_count = 0;
44 
45   FunctionKind kind = call_super ? FunctionKind::kDefaultDerivedConstructor
46                                  : FunctionKind::kDefaultBaseConstructor;
47   DeclarationScope* function_scope = NewFunctionScope(kind);
48   SetLanguageMode(function_scope, LanguageMode::kStrict);
49   // Set start and end position to the same value
50   function_scope->set_start_position(pos);
51   function_scope->set_end_position(pos);
52   ScopedPtrList<Statement> body(pointer_buffer());
53 
54   {
55     FunctionState function_state(&function_state_, &scope_, function_scope);
56 
57     if (call_super) {
58       // Create a SuperCallReference and handle in BytecodeGenerator.
59       auto constructor_args_name = ast_value_factory()->empty_string();
60       bool is_rest = true;
61       bool is_optional = false;
62       Variable* constructor_args = function_scope->DeclareParameter(
63           constructor_args_name, VariableMode::kTemporary, is_optional, is_rest,
64           ast_value_factory(), pos);
65 
66       Expression* call;
67       {
68         ScopedPtrList<Expression> args(pointer_buffer());
69         Spread* spread_args = factory()->NewSpread(
70             factory()->NewVariableProxy(constructor_args), pos, pos);
71 
72         args.Add(spread_args);
73         Expression* super_call_ref = NewSuperCallReference(pos);
74         constexpr bool has_spread = true;
75         call = factory()->NewCall(super_call_ref, args, pos, has_spread);
76       }
77       body.Add(factory()->NewReturnStatement(call, pos));
78     }
79 
80     expected_property_count = function_state.expected_property_count();
81   }
82 
83   FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
84       name, function_scope, body, expected_property_count, parameter_count,
85       parameter_count, FunctionLiteral::kNoDuplicateParameters,
86       FunctionSyntaxKind::kAnonymousExpression, default_eager_compile_hint(),
87       pos, true, GetNextFunctionLiteralId());
88   return function_literal;
89 }
90 
ReportUnexpectedTokenAt(Scanner::Location location,Token::Value token,MessageTemplate message)91 void Parser::ReportUnexpectedTokenAt(Scanner::Location location,
92                                      Token::Value token,
93                                      MessageTemplate message) {
94   const char* arg = nullptr;
95   switch (token) {
96     case Token::EOS:
97       message = MessageTemplate::kUnexpectedEOS;
98       break;
99     case Token::SMI:
100     case Token::NUMBER:
101     case Token::BIGINT:
102       message = MessageTemplate::kUnexpectedTokenNumber;
103       break;
104     case Token::STRING:
105       message = MessageTemplate::kUnexpectedTokenString;
106       break;
107     case Token::PRIVATE_NAME:
108     case Token::IDENTIFIER:
109       message = MessageTemplate::kUnexpectedTokenIdentifier;
110       break;
111     case Token::AWAIT:
112     case Token::ENUM:
113       message = MessageTemplate::kUnexpectedReserved;
114       break;
115     case Token::LET:
116     case Token::STATIC:
117     case Token::YIELD:
118     case Token::FUTURE_STRICT_RESERVED_WORD:
119       message = is_strict(language_mode())
120                     ? MessageTemplate::kUnexpectedStrictReserved
121                     : MessageTemplate::kUnexpectedTokenIdentifier;
122       break;
123     case Token::TEMPLATE_SPAN:
124     case Token::TEMPLATE_TAIL:
125       message = MessageTemplate::kUnexpectedTemplateString;
126       break;
127     case Token::ESCAPED_STRICT_RESERVED_WORD:
128     case Token::ESCAPED_KEYWORD:
129       message = MessageTemplate::kInvalidEscapedReservedWord;
130       break;
131     case Token::ILLEGAL:
132       if (scanner()->has_error()) {
133         message = scanner()->error();
134         location = scanner()->error_location();
135       } else {
136         message = MessageTemplate::kInvalidOrUnexpectedToken;
137       }
138       break;
139     case Token::REGEXP_LITERAL:
140       message = MessageTemplate::kUnexpectedTokenRegExp;
141       break;
142     default:
143       const char* name = Token::String(token);
144       DCHECK_NOT_NULL(name);
145       arg = name;
146       break;
147   }
148   ReportMessageAt(location, message, arg);
149 }
150 
151 // ----------------------------------------------------------------------------
152 // Implementation of Parser
153 
ShortcutNumericLiteralBinaryExpression(Expression ** x,Expression * y,Token::Value op,int pos)154 bool Parser::ShortcutNumericLiteralBinaryExpression(Expression** x,
155                                                     Expression* y,
156                                                     Token::Value op, int pos) {
157   if ((*x)->IsNumberLiteral() && y->IsNumberLiteral()) {
158     double x_val = (*x)->AsLiteral()->AsNumber();
159     double y_val = y->AsLiteral()->AsNumber();
160     switch (op) {
161       case Token::ADD:
162         *x = factory()->NewNumberLiteral(x_val + y_val, pos);
163         return true;
164       case Token::SUB:
165         *x = factory()->NewNumberLiteral(x_val - y_val, pos);
166         return true;
167       case Token::MUL:
168         *x = factory()->NewNumberLiteral(x_val * y_val, pos);
169         return true;
170       case Token::DIV:
171         *x = factory()->NewNumberLiteral(base::Divide(x_val, y_val), pos);
172         return true;
173       case Token::BIT_OR: {
174         int value = DoubleToInt32(x_val) | DoubleToInt32(y_val);
175         *x = factory()->NewNumberLiteral(value, pos);
176         return true;
177       }
178       case Token::BIT_AND: {
179         int value = DoubleToInt32(x_val) & DoubleToInt32(y_val);
180         *x = factory()->NewNumberLiteral(value, pos);
181         return true;
182       }
183       case Token::BIT_XOR: {
184         int value = DoubleToInt32(x_val) ^ DoubleToInt32(y_val);
185         *x = factory()->NewNumberLiteral(value, pos);
186         return true;
187       }
188       case Token::SHL: {
189         int value =
190             base::ShlWithWraparound(DoubleToInt32(x_val), DoubleToInt32(y_val));
191         *x = factory()->NewNumberLiteral(value, pos);
192         return true;
193       }
194       case Token::SHR: {
195         uint32_t shift = DoubleToInt32(y_val) & 0x1F;
196         uint32_t value = DoubleToUint32(x_val) >> shift;
197         *x = factory()->NewNumberLiteral(value, pos);
198         return true;
199       }
200       case Token::SAR: {
201         uint32_t shift = DoubleToInt32(y_val) & 0x1F;
202         int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift);
203         *x = factory()->NewNumberLiteral(value, pos);
204         return true;
205       }
206       case Token::EXP:
207         *x = factory()->NewNumberLiteral(base::ieee754::pow(x_val, y_val), pos);
208         return true;
209       default:
210         break;
211     }
212   }
213   return false;
214 }
215 
CollapseNaryExpression(Expression ** x,Expression * y,Token::Value op,int pos,const SourceRange & range)216 bool Parser::CollapseNaryExpression(Expression** x, Expression* y,
217                                     Token::Value op, int pos,
218                                     const SourceRange& range) {
219   // Filter out unsupported ops.
220   if (!Token::IsBinaryOp(op) || op == Token::EXP) return false;
221 
222   // Convert *x into an nary operation with the given op, returning false if
223   // this is not possible.
224   NaryOperation* nary = nullptr;
225   if ((*x)->IsBinaryOperation()) {
226     BinaryOperation* binop = (*x)->AsBinaryOperation();
227     if (binop->op() != op) return false;
228 
229     nary = factory()->NewNaryOperation(op, binop->left(), 2);
230     nary->AddSubsequent(binop->right(), binop->position());
231     ConvertBinaryToNaryOperationSourceRange(binop, nary);
232     *x = nary;
233   } else if ((*x)->IsNaryOperation()) {
234     nary = (*x)->AsNaryOperation();
235     if (nary->op() != op) return false;
236   } else {
237     return false;
238   }
239 
240   // Append our current expression to the nary operation.
241   // TODO(leszeks): Do some literal collapsing here if we're appending Smi or
242   // String literals.
243   nary->AddSubsequent(y, pos);
244   nary->clear_parenthesized();
245   AppendNaryOperationSourceRange(nary, range);
246 
247   return true;
248 }
249 
GetBigIntAsSymbol()250 const AstRawString* Parser::GetBigIntAsSymbol() {
251   base::Vector<const uint8_t> literal = scanner()->BigIntLiteral();
252   if (literal[0] != '0' || literal.length() == 1) {
253     return ast_value_factory()->GetOneByteString(literal);
254   }
255   std::unique_ptr<char[]> decimal =
256       BigIntLiteralToDecimal(local_isolate_, literal);
257   return ast_value_factory()->GetOneByteString(decimal.get());
258 }
259 
BuildUnaryExpression(Expression * expression,Token::Value op,int pos)260 Expression* Parser::BuildUnaryExpression(Expression* expression,
261                                          Token::Value op, int pos) {
262   DCHECK_NOT_NULL(expression);
263   const Literal* literal = expression->AsLiteral();
264   if (literal != nullptr) {
265     if (op == Token::NOT) {
266       // Convert the literal to a boolean condition and negate it.
267       return factory()->NewBooleanLiteral(literal->ToBooleanIsFalse(), pos);
268     } else if (literal->IsNumberLiteral()) {
269       // Compute some expressions involving only number literals.
270       double value = literal->AsNumber();
271       switch (op) {
272         case Token::ADD:
273           return expression;
274         case Token::SUB:
275           return factory()->NewNumberLiteral(-value, pos);
276         case Token::BIT_NOT:
277           return factory()->NewNumberLiteral(~DoubleToInt32(value), pos);
278         default:
279           break;
280       }
281     }
282   }
283   return factory()->NewUnaryOperation(op, expression, pos);
284 }
285 
NewThrowError(Runtime::FunctionId id,MessageTemplate message,const AstRawString * arg,int pos)286 Expression* Parser::NewThrowError(Runtime::FunctionId id,
287                                   MessageTemplate message,
288                                   const AstRawString* arg, int pos) {
289   ScopedPtrList<Expression> args(pointer_buffer());
290   args.Add(factory()->NewSmiLiteral(static_cast<int>(message), pos));
291   args.Add(factory()->NewStringLiteral(arg, pos));
292   CallRuntime* call_constructor = factory()->NewCallRuntime(id, args, pos);
293   return factory()->NewThrow(call_constructor, pos);
294 }
295 
NewSuperPropertyReference(Scope * home_object_scope,int pos)296 Expression* Parser::NewSuperPropertyReference(Scope* home_object_scope,
297                                               int pos) {
298   const AstRawString* home_object_name;
299   if (IsStatic(scope()->GetReceiverScope()->function_kind())) {
300     home_object_name = ast_value_factory_->dot_static_home_object_string();
301   } else {
302     home_object_name = ast_value_factory_->dot_home_object_string();
303   }
304   return factory()->NewSuperPropertyReference(
305       home_object_scope->NewHomeObjectVariableProxy(factory(), home_object_name,
306                                                     pos),
307       pos);
308 }
309 
NewSuperCallReference(int pos)310 Expression* Parser::NewSuperCallReference(int pos) {
311   VariableProxy* new_target_proxy =
312       NewUnresolved(ast_value_factory()->new_target_string(), pos);
313   VariableProxy* this_function_proxy =
314       NewUnresolved(ast_value_factory()->this_function_string(), pos);
315   return factory()->NewSuperCallReference(new_target_proxy, this_function_proxy,
316                                           pos);
317 }
318 
NewTargetExpression(int pos)319 Expression* Parser::NewTargetExpression(int pos) {
320   auto proxy = NewUnresolved(ast_value_factory()->new_target_string(), pos);
321   proxy->set_is_new_target();
322   return proxy;
323 }
324 
ImportMetaExpression(int pos)325 Expression* Parser::ImportMetaExpression(int pos) {
326   ScopedPtrList<Expression> args(pointer_buffer());
327   return factory()->NewCallRuntime(Runtime::kInlineGetImportMetaObject, args,
328                                    pos);
329 }
330 
ExpressionFromLiteral(Token::Value token,int pos)331 Expression* Parser::ExpressionFromLiteral(Token::Value token, int pos) {
332   switch (token) {
333     case Token::NULL_LITERAL:
334       return factory()->NewNullLiteral(pos);
335     case Token::TRUE_LITERAL:
336       return factory()->NewBooleanLiteral(true, pos);
337     case Token::FALSE_LITERAL:
338       return factory()->NewBooleanLiteral(false, pos);
339     case Token::SMI: {
340       uint32_t value = scanner()->smi_value();
341       return factory()->NewSmiLiteral(value, pos);
342     }
343     case Token::NUMBER: {
344       double value = scanner()->DoubleValue();
345       return factory()->NewNumberLiteral(value, pos);
346     }
347     case Token::BIGINT:
348       return factory()->NewBigIntLiteral(
349           AstBigInt(scanner()->CurrentLiteralAsCString(zone())), pos);
350     case Token::STRING: {
351       return factory()->NewStringLiteral(GetSymbol(), pos);
352     }
353     default:
354       DCHECK(false);
355   }
356   return FailureExpression();
357 }
358 
NewV8Intrinsic(const AstRawString * name,const ScopedPtrList<Expression> & args,int pos)359 Expression* Parser::NewV8Intrinsic(const AstRawString* name,
360                                    const ScopedPtrList<Expression>& args,
361                                    int pos) {
362   if (ParsingExtension()) {
363     // The extension structures are only accessible while parsing the
364     // very first time, not when reparsing because of lazy compilation.
365     GetClosureScope()->ForceEagerCompilation();
366   }
367 
368   if (!name->is_one_byte()) {
369     // There are no two-byte named intrinsics.
370     ReportMessage(MessageTemplate::kNotDefined, name);
371     return FailureExpression();
372   }
373 
374   const Runtime::Function* function =
375       Runtime::FunctionForName(name->raw_data(), name->length());
376 
377   // Be more permissive when fuzzing. Intrinsics are not supported.
378   if (FLAG_fuzzing) {
379     return NewV8RuntimeFunctionForFuzzing(function, args, pos);
380   }
381 
382   if (function != nullptr) {
383     // Check for possible name clash.
384     DCHECK_EQ(Context::kNotFound,
385               Context::IntrinsicIndexForName(name->raw_data(), name->length()));
386 
387     // Check that the expected number of arguments are being passed.
388     if (function->nargs != -1 && function->nargs != args.length()) {
389       ReportMessage(MessageTemplate::kRuntimeWrongNumArgs);
390       return FailureExpression();
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     return FailureExpression();
403   }
404 
405   return factory()->NewCallRuntime(context_index, args, pos);
406 }
407 
408 // More permissive runtime-function creation on fuzzers.
NewV8RuntimeFunctionForFuzzing(const Runtime::Function * function,const ScopedPtrList<Expression> & args,int pos)409 Expression* Parser::NewV8RuntimeFunctionForFuzzing(
410     const Runtime::Function* function, const ScopedPtrList<Expression>& args,
411     int pos) {
412   CHECK(FLAG_fuzzing);
413 
414   // Intrinsics are not supported for fuzzing. Only allow allowlisted runtime
415   // functions. Also prevent later errors due to too few arguments and just
416   // ignore this call.
417   if (function == nullptr ||
418       !Runtime::IsAllowListedForFuzzing(function->function_id) ||
419       function->nargs > args.length()) {
420     return factory()->NewUndefinedLiteral(kNoSourcePosition);
421   }
422 
423   // Flexible number of arguments permitted.
424   if (function->nargs == -1) {
425     return factory()->NewCallRuntime(function, args, pos);
426   }
427 
428   // Otherwise ignore superfluous arguments.
429   ScopedPtrList<Expression> permissive_args(pointer_buffer());
430   for (int i = 0; i < function->nargs; i++) {
431     permissive_args.Add(args.at(i));
432   }
433   return factory()->NewCallRuntime(function, permissive_args, pos);
434 }
435 
Parser(LocalIsolate * local_isolate,ParseInfo * info,Handle<Script> script)436 Parser::Parser(LocalIsolate* local_isolate, ParseInfo* info,
437                Handle<Script> script)
438     : ParserBase<Parser>(
439           info->zone(), &scanner_, info->stack_limit(),
440           info->ast_value_factory(), info->pending_error_handler(),
441           info->runtime_call_stats(), info->logger(), info->flags(), true),
442       local_isolate_(local_isolate),
443       info_(info),
444       script_(script),
445       scanner_(info->character_stream(), flags()),
446       preparser_zone_(info->zone()->allocator(), "pre-parser-zone"),
447       reusable_preparser_(nullptr),
448       mode_(PARSE_EAGERLY),  // Lazy mode must be set explicitly.
449       source_range_map_(info->source_range_map()),
450       total_preparse_skipped_(0),
451       consumed_preparse_data_(info->consumed_preparse_data()),
452       preparse_data_buffer_(),
453       parameters_end_pos_(info->parameters_end_pos()) {
454   // Even though we were passed ParseInfo, we should not store it in
455   // Parser - this makes sure that Isolate is not accidentally accessed via
456   // ParseInfo during background parsing.
457   DCHECK_NOT_NULL(info->character_stream());
458   // Determine if functions can be lazily compiled. This is necessary to
459   // allow some of our builtin JS files to be lazily compiled. These
460   // builtins cannot be handled lazily by the parser, since we have to know
461   // if a function uses the special natives syntax, which is something the
462   // parser records.
463   // If the debugger requests compilation for break points, we cannot be
464   // aggressive about lazy compilation, because it might trigger compilation
465   // of functions without an outer context when setting a breakpoint through
466   // Debug::FindSharedFunctionInfoInScript
467   // We also compile eagerly for kProduceExhaustiveCodeCache.
468   bool can_compile_lazily = flags().allow_lazy_compile() && !flags().is_eager();
469 
470   set_default_eager_compile_hint(can_compile_lazily
471                                      ? FunctionLiteral::kShouldLazyCompile
472                                      : FunctionLiteral::kShouldEagerCompile);
473   allow_lazy_ = flags().allow_lazy_compile() && flags().allow_lazy_parsing() &&
474                 info->extension() == nullptr && can_compile_lazily;
475   for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
476        ++feature) {
477     use_counts_[feature] = 0;
478   }
479 }
480 
InitializeEmptyScopeChain(ParseInfo * info)481 void Parser::InitializeEmptyScopeChain(ParseInfo* info) {
482   DCHECK_NULL(original_scope_);
483   DCHECK_NULL(info->script_scope());
484   DeclarationScope* script_scope =
485       NewScriptScope(flags().is_repl_mode() ? REPLMode::kYes : REPLMode::kNo);
486   info->set_script_scope(script_scope);
487   original_scope_ = script_scope;
488 }
489 
490 template <typename IsolateT>
DeserializeScopeChain(IsolateT * isolate,ParseInfo * info,MaybeHandle<ScopeInfo> maybe_outer_scope_info,Scope::DeserializationMode mode)491 void Parser::DeserializeScopeChain(
492     IsolateT* isolate, ParseInfo* info,
493     MaybeHandle<ScopeInfo> maybe_outer_scope_info,
494     Scope::DeserializationMode mode) {
495   InitializeEmptyScopeChain(info);
496   Handle<ScopeInfo> outer_scope_info;
497   if (maybe_outer_scope_info.ToHandle(&outer_scope_info)) {
498     DCHECK_EQ(ThreadId::Current(), isolate->thread_id());
499     original_scope_ = Scope::DeserializeScopeChain(
500         isolate, zone(), *outer_scope_info, info->script_scope(),
501         ast_value_factory(), mode);
502     if (flags().is_eval() || IsArrowFunction(flags().function_kind())) {
503       original_scope_->GetReceiverScope()->DeserializeReceiver(
504           ast_value_factory());
505     }
506   }
507 }
508 
509 template void Parser::DeserializeScopeChain(
510     Isolate* isolate, ParseInfo* info,
511     MaybeHandle<ScopeInfo> maybe_outer_scope_info,
512     Scope::DeserializationMode mode);
513 template void Parser::DeserializeScopeChain(
514     LocalIsolate* isolate, ParseInfo* info,
515     MaybeHandle<ScopeInfo> maybe_outer_scope_info,
516     Scope::DeserializationMode mode);
517 
518 namespace {
519 
MaybeProcessSourceRanges(ParseInfo * parse_info,Expression * root,uintptr_t stack_limit_)520 void MaybeProcessSourceRanges(ParseInfo* parse_info, Expression* root,
521                               uintptr_t stack_limit_) {
522   if (root != nullptr && parse_info->source_range_map() != nullptr) {
523     SourceRangeAstVisitor visitor(stack_limit_, root,
524                                   parse_info->source_range_map());
525     visitor.Run();
526   }
527 }
528 
529 }  // namespace
530 
ParseProgram(Isolate * isolate,Handle<Script> script,ParseInfo * info,MaybeHandle<ScopeInfo> maybe_outer_scope_info)531 void Parser::ParseProgram(Isolate* isolate, Handle<Script> script,
532                           ParseInfo* info,
533                           MaybeHandle<ScopeInfo> maybe_outer_scope_info) {
534   DCHECK_EQ(script->id(), flags().script_id());
535 
536   // It's OK to use the Isolate & counters here, since this function is only
537   // called in the main thread.
538   DCHECK(parsing_on_main_thread_);
539   RCS_SCOPE(runtime_call_stats_, flags().is_eval()
540                                      ? RuntimeCallCounterId::kParseEval
541                                      : RuntimeCallCounterId::kParseProgram);
542   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.ParseProgram");
543   base::ElapsedTimer timer;
544   if (V8_UNLIKELY(FLAG_log_function_events)) timer.Start();
545 
546   // Initialize parser state.
547   DeserializeScopeChain(isolate, info, maybe_outer_scope_info,
548                         Scope::DeserializationMode::kIncludingVariables);
549 
550   DCHECK_EQ(script->is_wrapped(), info->is_wrapped_as_function());
551   if (script->is_wrapped()) {
552     maybe_wrapped_arguments_ = handle(script->wrapped_arguments(), isolate);
553   }
554 
555   scanner_.Initialize();
556   FunctionLiteral* result = DoParseProgram(isolate, info);
557   MaybeProcessSourceRanges(info, result, stack_limit_);
558   PostProcessParseResult(isolate, info, result);
559 
560   HandleSourceURLComments(isolate, script);
561 
562   if (V8_UNLIKELY(FLAG_log_function_events) && result != nullptr) {
563     double ms = timer.Elapsed().InMillisecondsF();
564     const char* event_name = "parse-eval";
565     int start = -1;
566     int end = -1;
567     if (!flags().is_eval()) {
568       event_name = "parse-script";
569       start = 0;
570       end = String::cast(script->source()).length();
571     }
572     LOG(isolate,
573         FunctionEvent(event_name, flags().script_id(), ms, start, end, "", 0));
574   }
575 }
576 
DoParseProgram(Isolate * isolate,ParseInfo * info)577 FunctionLiteral* Parser::DoParseProgram(Isolate* isolate, ParseInfo* info) {
578   // Note that this function can be called from the main thread or from a
579   // background thread. We should not access anything Isolate / heap dependent
580   // via ParseInfo, and also not pass it forward. If not on the main thread
581   // isolate will be nullptr.
582   DCHECK_EQ(parsing_on_main_thread_, isolate != nullptr);
583   DCHECK_NULL(scope_);
584 
585   ParsingModeScope mode(this, allow_lazy_ ? PARSE_LAZILY : PARSE_EAGERLY);
586   ResetFunctionLiteralId();
587 
588   FunctionLiteral* result = nullptr;
589   {
590     Scope* outer = original_scope_;
591     DCHECK_NOT_NULL(outer);
592     if (flags().is_eval()) {
593       outer = NewEvalScope(outer);
594     } else if (flags().is_module()) {
595       DCHECK_EQ(outer, info->script_scope());
596       outer = NewModuleScope(info->script_scope());
597     }
598 
599     DeclarationScope* scope = outer->AsDeclarationScope();
600     scope->set_start_position(0);
601 
602     FunctionState function_state(&function_state_, &scope_, scope);
603     ScopedPtrList<Statement> body(pointer_buffer());
604     int beg_pos = scanner()->location().beg_pos;
605     if (flags().is_module()) {
606       DCHECK(flags().is_module());
607 
608       PrepareGeneratorVariables();
609       Expression* initial_yield = BuildInitialYield(
610           kNoSourcePosition, FunctionKind::kGeneratorFunction);
611       body.Add(
612           factory()->NewExpressionStatement(initial_yield, kNoSourcePosition));
613       // First parse statements into a buffer. Then, if there was a
614       // top level await, create an inner block and rewrite the body of the
615       // module as an async function. Otherwise merge the statements back
616       // into the main body.
617       BlockT block = impl()->NullBlock();
618       {
619         StatementListT statements(pointer_buffer());
620         ParseModuleItemList(&statements);
621         // Modules will always have an initial yield. If there are any
622         // additional suspends, i.e. awaits, then we treat the module as an
623         // AsyncModule.
624         if (function_state.suspend_count() > 1) {
625           scope->set_is_async_module();
626           block = factory()->NewBlock(true, statements);
627         } else {
628           statements.MergeInto(&body);
629         }
630       }
631       if (IsAsyncModule(scope->function_kind())) {
632         impl()->RewriteAsyncFunctionBody(
633             &body, block, factory()->NewUndefinedLiteral(kNoSourcePosition));
634       }
635       if (!has_error() &&
636           !module()->Validate(this->scope()->AsModuleScope(),
637                               pending_error_handler(), zone())) {
638         scanner()->set_parser_error();
639       }
640     } else if (info->is_wrapped_as_function()) {
641       DCHECK(parsing_on_main_thread_);
642       ParseWrapped(isolate, info, &body, scope, zone());
643     } else if (flags().is_repl_mode()) {
644       ParseREPLProgram(info, &body, scope);
645     } else {
646       // Don't count the mode in the use counters--give the program a chance
647       // to enable script-wide strict mode below.
648       this->scope()->SetLanguageMode(info->language_mode());
649       ParseStatementList(&body, Token::EOS);
650     }
651 
652     // The parser will peek but not consume EOS.  Our scope logically goes all
653     // the way to the EOS, though.
654     scope->set_end_position(peek_position());
655 
656     if (is_strict(language_mode())) {
657       CheckStrictOctalLiteral(beg_pos, end_position());
658     }
659     if (is_sloppy(language_mode())) {
660       // TODO(littledan): Function bindings on the global object that modify
661       // pre-existing bindings should be made writable, enumerable and
662       // nonconfigurable if possible, whereas this code will leave attributes
663       // unchanged if the property already exists.
664       InsertSloppyBlockFunctionVarBindings(scope);
665     }
666     // Internalize the ast strings in the case of eval so we can check for
667     // conflicting var declarations with outer scope-info-backed scopes.
668     if (flags().is_eval()) {
669       DCHECK(parsing_on_main_thread_);
670       DCHECK(!overall_parse_is_parked_);
671       info->ast_value_factory()->Internalize(isolate);
672     }
673     CheckConflictingVarDeclarations(scope);
674 
675     if (flags().parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) {
676       if (body.length() != 1 || !body.at(0)->IsExpressionStatement() ||
677           !body.at(0)
678                ->AsExpressionStatement()
679                ->expression()
680                ->IsFunctionLiteral()) {
681         ReportMessage(MessageTemplate::kSingleFunctionLiteral);
682       }
683     }
684 
685     int parameter_count = 0;
686     result = factory()->NewScriptOrEvalFunctionLiteral(
687         scope, body, function_state.expected_property_count(), parameter_count);
688     result->set_suspend_count(function_state.suspend_count());
689   }
690 
691   info->set_max_function_literal_id(GetLastFunctionLiteralId());
692 
693   if (has_error()) return nullptr;
694 
695   RecordFunctionLiteralSourceRange(result);
696 
697   return result;
698 }
699 
700 template <typename IsolateT>
PostProcessParseResult(IsolateT * isolate,ParseInfo * info,FunctionLiteral * literal)701 void Parser::PostProcessParseResult(IsolateT* isolate, ParseInfo* info,
702                                     FunctionLiteral* literal) {
703   if (literal == nullptr) return;
704 
705   info->set_literal(literal);
706   info->set_language_mode(literal->language_mode());
707   if (info->flags().is_eval()) {
708     info->set_allow_eval_cache(allow_eval_cache());
709   }
710 
711   info->ast_value_factory()->Internalize(isolate);
712 
713   {
714     RCS_SCOPE(info->runtime_call_stats(), RuntimeCallCounterId::kCompileAnalyse,
715               RuntimeCallStats::kThreadSpecific);
716     if (!Rewriter::Rewrite(info) || !DeclarationScope::Analyze(info)) {
717       // Null out the literal to indicate that something failed.
718       info->set_literal(nullptr);
719       return;
720     }
721   }
722 }
723 
724 template void Parser::PostProcessParseResult(Isolate* isolate, ParseInfo* info,
725                                              FunctionLiteral* literal);
726 template void Parser::PostProcessParseResult(LocalIsolate* isolate,
727                                              ParseInfo* info,
728                                              FunctionLiteral* literal);
729 
PrepareWrappedArguments(Isolate * isolate,ParseInfo * info,Zone * zone)730 ZonePtrList<const AstRawString>* Parser::PrepareWrappedArguments(
731     Isolate* isolate, ParseInfo* info, Zone* zone) {
732   DCHECK(parsing_on_main_thread_);
733   DCHECK_NOT_NULL(isolate);
734   Handle<FixedArray> arguments = maybe_wrapped_arguments_.ToHandleChecked();
735   int arguments_length = arguments->length();
736   ZonePtrList<const AstRawString>* arguments_for_wrapped_function =
737       zone->New<ZonePtrList<const AstRawString>>(arguments_length, zone);
738   for (int i = 0; i < arguments_length; i++) {
739     const AstRawString* argument_string = ast_value_factory()->GetString(
740         String::cast(arguments->get(i)),
741         SharedStringAccessGuardIfNeeded(isolate));
742     arguments_for_wrapped_function->Add(argument_string, zone);
743   }
744   return arguments_for_wrapped_function;
745 }
746 
ParseWrapped(Isolate * isolate,ParseInfo * info,ScopedPtrList<Statement> * body,DeclarationScope * outer_scope,Zone * zone)747 void Parser::ParseWrapped(Isolate* isolate, ParseInfo* info,
748                           ScopedPtrList<Statement>* body,
749                           DeclarationScope* outer_scope, Zone* zone) {
750   DCHECK(parsing_on_main_thread_);
751   DCHECK(info->is_wrapped_as_function());
752   ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
753 
754   // Set function and block state for the outer eval scope.
755   DCHECK(outer_scope->is_eval_scope());
756   FunctionState function_state(&function_state_, &scope_, outer_scope);
757 
758   const AstRawString* function_name = nullptr;
759   Scanner::Location location(0, 0);
760 
761   ZonePtrList<const AstRawString>* arguments_for_wrapped_function =
762       PrepareWrappedArguments(isolate, info, zone);
763 
764   FunctionLiteral* function_literal =
765       ParseFunctionLiteral(function_name, location, kSkipFunctionNameCheck,
766                            FunctionKind::kNormalFunction, kNoSourcePosition,
767                            FunctionSyntaxKind::kWrapped, LanguageMode::kSloppy,
768                            arguments_for_wrapped_function);
769 
770   Statement* return_statement =
771       factory()->NewReturnStatement(function_literal, kNoSourcePosition);
772   body->Add(return_statement);
773 }
774 
ParseREPLProgram(ParseInfo * info,ScopedPtrList<Statement> * body,DeclarationScope * scope)775 void Parser::ParseREPLProgram(ParseInfo* info, ScopedPtrList<Statement>* body,
776                               DeclarationScope* scope) {
777   // REPL scripts are handled nearly the same way as the body of an async
778   // function. The difference is the value used to resolve the async
779   // promise.
780   // For a REPL script this is the completion value of the
781   // script instead of the expression of some "return" statement. The
782   // completion value of the script is obtained by manually invoking
783   // the {Rewriter} which will return a VariableProxy referencing the
784   // result.
785   DCHECK(flags().is_repl_mode());
786   this->scope()->SetLanguageMode(info->language_mode());
787   PrepareGeneratorVariables();
788 
789   BlockT block = impl()->NullBlock();
790   {
791     StatementListT statements(pointer_buffer());
792     ParseStatementList(&statements, Token::EOS);
793     block = factory()->NewBlock(true, statements);
794   }
795 
796   if (has_error()) return;
797 
798   base::Optional<VariableProxy*> maybe_result =
799       Rewriter::RewriteBody(info, scope, block->statements());
800   Expression* result_value =
801       (maybe_result && *maybe_result)
802           ? static_cast<Expression*>(*maybe_result)
803           : factory()->NewUndefinedLiteral(kNoSourcePosition);
804 
805   impl()->RewriteAsyncFunctionBody(body, block, WrapREPLResult(result_value),
806                                    REPLMode::kYes);
807 }
808 
WrapREPLResult(Expression * value)809 Expression* Parser::WrapREPLResult(Expression* value) {
810   // REPL scripts additionally wrap the ".result" variable in an
811   // object literal:
812   //
813   //     return %_AsyncFunctionResolve(
814   //                .generator_object, {.repl_result: .result});
815   //
816   // Should ".result" be a resolved promise itself, the async return
817   // would chain the promises and return the resolve value instead of
818   // the promise.
819 
820   Literal* property_name = factory()->NewStringLiteral(
821       ast_value_factory()->dot_repl_result_string(), kNoSourcePosition);
822   ObjectLiteralProperty* property =
823       factory()->NewObjectLiteralProperty(property_name, value, true);
824 
825   ScopedPtrList<ObjectLiteralProperty> properties(pointer_buffer());
826   properties.Add(property);
827   return factory()->NewObjectLiteral(properties, false, kNoSourcePosition,
828                                      false);
829 }
830 
ParseFunction(Isolate * isolate,ParseInfo * info,Handle<SharedFunctionInfo> shared_info)831 void Parser::ParseFunction(Isolate* isolate, ParseInfo* info,
832                            Handle<SharedFunctionInfo> shared_info) {
833   // It's OK to use the Isolate & counters here, since this function is only
834   // called in the main thread.
835   DCHECK(parsing_on_main_thread_);
836   RCS_SCOPE(runtime_call_stats_, RuntimeCallCounterId::kParseFunction);
837   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.ParseFunction");
838   base::ElapsedTimer timer;
839   if (V8_UNLIKELY(FLAG_log_function_events)) timer.Start();
840 
841   MaybeHandle<ScopeInfo> maybe_outer_scope_info;
842   if (shared_info->HasOuterScopeInfo()) {
843     maybe_outer_scope_info = handle(shared_info->GetOuterScopeInfo(), isolate);
844   }
845   int start_position = shared_info->StartPosition();
846   int end_position = shared_info->EndPosition();
847 
848   MaybeHandle<ScopeInfo> deserialize_start_scope = maybe_outer_scope_info;
849   bool needs_script_scope_finalization = false;
850   // If the function is a class member initializer and there isn't a
851   // scope mismatch, we will only deserialize up to the outer scope of
852   // the class scope, and regenerate the class scope during reparsing.
853   if (flags().function_kind() ==
854           FunctionKind::kClassMembersInitializerFunction &&
855       shared_info->HasOuterScopeInfo() &&
856       maybe_outer_scope_info.ToHandleChecked()->scope_type() == CLASS_SCOPE &&
857       maybe_outer_scope_info.ToHandleChecked()->StartPosition() ==
858           start_position) {
859     Handle<ScopeInfo> outer_scope_info =
860         maybe_outer_scope_info.ToHandleChecked();
861     if (outer_scope_info->HasOuterScopeInfo()) {
862       deserialize_start_scope =
863           handle(outer_scope_info->OuterScopeInfo(), isolate);
864     } else {
865       // If the class scope doesn't have an outer scope to deserialize, we need
866       // to finalize the script scope without using
867       // Scope::DeserializeScopeChain().
868       deserialize_start_scope = MaybeHandle<ScopeInfo>();
869       needs_script_scope_finalization = true;
870     }
871   }
872 
873   DeserializeScopeChain(isolate, info, deserialize_start_scope,
874                         Scope::DeserializationMode::kIncludingVariables);
875   if (needs_script_scope_finalization) {
876     DCHECK_EQ(original_scope_, info->script_scope());
877     Scope::SetScriptScopeInfo(isolate, info->script_scope());
878   }
879   DCHECK_EQ(factory()->zone(), info->zone());
880 
881   Handle<Script> script = handle(Script::cast(shared_info->script()), isolate);
882   if (shared_info->is_wrapped()) {
883     maybe_wrapped_arguments_ = handle(script->wrapped_arguments(), isolate);
884   }
885 
886   int function_literal_id = shared_info->function_literal_id();
887   if V8_UNLIKELY (script->type() == Script::TYPE_WEB_SNAPSHOT) {
888     // Function literal IDs for inner functions haven't been allocated when
889     // deserializing. Put the inner function SFIs to the end of the list;
890     // they'll be deduplicated later (if the corresponding SFIs exist already)
891     // in Script::FindSharedFunctionInfo. (-1 here because function_literal_id
892     // is the parent's id. The inner function will get ids starting from
893     // function_literal_id + 1.)
894     function_literal_id = script->shared_function_info_count() - 1;
895   }
896 
897   // Initialize parser state.
898   info->set_function_name(ast_value_factory()->GetString(
899       shared_info->Name(), SharedStringAccessGuardIfNeeded(isolate)));
900   scanner_.Initialize();
901 
902   FunctionLiteral* result;
903   if (V8_UNLIKELY(shared_info->private_name_lookup_skips_outer_class() &&
904                   original_scope_->is_class_scope())) {
905     // If the function skips the outer class and the outer scope is a class, the
906     // function is in heritage position. Otherwise the function scope's skip bit
907     // will be correctly inherited from the outer scope.
908     ClassScope::HeritageParsingScope heritage(original_scope_->AsClassScope());
909     result = DoParseDeserializedFunction(
910         isolate, maybe_outer_scope_info, info, start_position, end_position,
911         function_literal_id, info->function_name());
912   } else {
913     result = DoParseDeserializedFunction(
914         isolate, maybe_outer_scope_info, info, start_position, end_position,
915         function_literal_id, info->function_name());
916   }
917   MaybeProcessSourceRanges(info, result, stack_limit_);
918   if (result != nullptr) {
919     Handle<String> inferred_name(shared_info->inferred_name(), isolate);
920     result->set_inferred_name(inferred_name);
921     // Fix the function_literal_id in case we changed it earlier.
922     result->set_function_literal_id(shared_info->function_literal_id());
923   }
924   PostProcessParseResult(isolate, info, result);
925   if (V8_UNLIKELY(FLAG_log_function_events) && result != nullptr) {
926     double ms = timer.Elapsed().InMillisecondsF();
927     // We should already be internalized by now, so the debug name will be
928     // available.
929     DeclarationScope* function_scope = result->scope();
930     std::unique_ptr<char[]> function_name = result->GetDebugName();
931     LOG(isolate,
932         FunctionEvent("parse-function", flags().script_id(), ms,
933                       function_scope->start_position(),
934                       function_scope->end_position(), function_name.get(),
935                       strlen(function_name.get())));
936   }
937 }
938 
DoParseFunction(Isolate * isolate,ParseInfo * info,int start_position,int end_position,int function_literal_id,const AstRawString * raw_name)939 FunctionLiteral* Parser::DoParseFunction(Isolate* isolate, ParseInfo* info,
940                                          int start_position, int end_position,
941                                          int function_literal_id,
942                                          const AstRawString* raw_name) {
943   DCHECK_EQ(parsing_on_main_thread_, isolate != nullptr);
944   DCHECK_NOT_NULL(raw_name);
945   DCHECK_NULL(scope_);
946 
947   DCHECK(ast_value_factory());
948   fni_.PushEnclosingName(raw_name);
949 
950   ResetFunctionLiteralId();
951   DCHECK_LT(0, function_literal_id);
952   SkipFunctionLiterals(function_literal_id - 1);
953 
954   ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
955 
956   // Place holder for the result.
957   FunctionLiteral* result = nullptr;
958 
959   {
960     // Parse the function literal.
961     Scope* outer = original_scope_;
962     DeclarationScope* outer_function = outer->GetClosureScope();
963     DCHECK(outer);
964     FunctionState function_state(&function_state_, &scope_, outer_function);
965     BlockState block_state(&scope_, outer);
966     DCHECK(is_sloppy(outer->language_mode()) ||
967            is_strict(info->language_mode()));
968     FunctionKind kind = flags().function_kind();
969     DCHECK_IMPLIES(IsConciseMethod(kind) || IsAccessorFunction(kind),
970                    flags().function_syntax_kind() ==
971                        FunctionSyntaxKind::kAccessorOrMethod);
972 
973     if (IsArrowFunction(kind)) {
974       if (IsAsyncFunction(kind)) {
975         DCHECK(!scanner()->HasLineTerminatorAfterNext());
976         if (!Check(Token::ASYNC)) {
977           CHECK(stack_overflow());
978           return nullptr;
979         }
980         if (!(peek_any_identifier() || peek() == Token::LPAREN)) {
981           CHECK(stack_overflow());
982           return nullptr;
983         }
984       }
985 
986       // TODO(adamk): We should construct this scope from the ScopeInfo.
987       DeclarationScope* scope = NewFunctionScope(kind);
988       scope->set_has_checked_syntax(true);
989 
990       // This bit only needs to be explicitly set because we're
991       // not passing the ScopeInfo to the Scope constructor.
992       SetLanguageMode(scope, info->language_mode());
993 
994       scope->set_start_position(start_position);
995       ParserFormalParameters formals(scope);
996       {
997         ParameterDeclarationParsingScope formals_scope(this);
998         // Parsing patterns as variable reference expression creates
999         // NewUnresolved references in current scope. Enter arrow function
1000         // scope for formal parameter parsing.
1001         BlockState inner_block_state(&scope_, scope);
1002         if (Check(Token::LPAREN)) {
1003           // '(' StrictFormalParameters ')'
1004           ParseFormalParameterList(&formals);
1005           Expect(Token::RPAREN);
1006         } else {
1007           // BindingIdentifier
1008           ParameterParsingScope parameter_parsing_scope(impl(), &formals);
1009           ParseFormalParameter(&formals);
1010           DeclareFormalParameters(&formals);
1011         }
1012         formals.duplicate_loc = formals_scope.duplicate_location();
1013       }
1014 
1015       if (GetLastFunctionLiteralId() != function_literal_id - 1) {
1016         if (has_error()) return nullptr;
1017         // If there were FunctionLiterals in the parameters, we need to
1018         // renumber them to shift down so the next function literal id for
1019         // the arrow function is the one requested.
1020         AstFunctionLiteralIdReindexer reindexer(
1021             stack_limit_,
1022             (function_literal_id - 1) - GetLastFunctionLiteralId());
1023         for (auto p : formals.params) {
1024           if (p->pattern != nullptr) reindexer.Reindex(p->pattern);
1025           if (p->initializer() != nullptr) {
1026             reindexer.Reindex(p->initializer());
1027           }
1028           if (reindexer.HasStackOverflow()) {
1029             set_stack_overflow();
1030             return nullptr;
1031           }
1032         }
1033         ResetFunctionLiteralId();
1034         SkipFunctionLiterals(function_literal_id - 1);
1035       }
1036 
1037       Expression* expression = ParseArrowFunctionLiteral(formals);
1038       // Scanning must end at the same position that was recorded
1039       // previously. If not, parsing has been interrupted due to a stack
1040       // overflow, at which point the partially parsed arrow function
1041       // concise body happens to be a valid expression. This is a problem
1042       // only for arrow functions with single expression bodies, since there
1043       // is no end token such as "}" for normal functions.
1044       if (scanner()->location().end_pos == end_position) {
1045         // The pre-parser saw an arrow function here, so the full parser
1046         // must produce a FunctionLiteral.
1047         DCHECK(expression->IsFunctionLiteral());
1048         result = expression->AsFunctionLiteral();
1049       }
1050     } else if (IsDefaultConstructor(kind)) {
1051       DCHECK_EQ(scope(), outer);
1052       result = DefaultConstructor(raw_name, IsDerivedConstructor(kind),
1053                                   start_position, end_position);
1054     } else {
1055       ZonePtrList<const AstRawString>* arguments_for_wrapped_function =
1056           info->is_wrapped_as_function()
1057               ? PrepareWrappedArguments(isolate, info, zone())
1058               : nullptr;
1059       result = ParseFunctionLiteral(
1060           raw_name, Scanner::Location::invalid(), kSkipFunctionNameCheck, kind,
1061           kNoSourcePosition, flags().function_syntax_kind(),
1062           info->language_mode(), arguments_for_wrapped_function);
1063     }
1064 
1065     if (has_error()) return nullptr;
1066     result->set_requires_instance_members_initializer(
1067         flags().requires_instance_members_initializer());
1068     result->set_class_scope_has_private_brand(
1069         flags().class_scope_has_private_brand());
1070     result->set_has_static_private_methods_or_accessors(
1071         flags().has_static_private_methods_or_accessors());
1072   }
1073 
1074   DCHECK_IMPLIES(result, function_literal_id == result->function_literal_id());
1075   return result;
1076 }
1077 
DoParseDeserializedFunction(Isolate * isolate,MaybeHandle<ScopeInfo> maybe_outer_scope_info,ParseInfo * info,int start_position,int end_position,int function_literal_id,const AstRawString * raw_name)1078 FunctionLiteral* Parser::DoParseDeserializedFunction(
1079     Isolate* isolate, MaybeHandle<ScopeInfo> maybe_outer_scope_info,
1080     ParseInfo* info, int start_position, int end_position,
1081     int function_literal_id, const AstRawString* raw_name) {
1082   if (flags().function_kind() ==
1083       FunctionKind::kClassMembersInitializerFunction) {
1084     return ParseClassForInstanceMemberInitialization(
1085         isolate, maybe_outer_scope_info, start_position, function_literal_id,
1086         end_position);
1087   }
1088 
1089   return DoParseFunction(isolate, info, start_position, end_position,
1090                          function_literal_id, raw_name);
1091 }
1092 
ParseClassForInstanceMemberInitialization(Isolate * isolate,MaybeHandle<ScopeInfo> maybe_class_scope_info,int initializer_pos,int initializer_id,int initializer_end_pos)1093 FunctionLiteral* Parser::ParseClassForInstanceMemberInitialization(
1094     Isolate* isolate, MaybeHandle<ScopeInfo> maybe_class_scope_info,
1095     int initializer_pos, int initializer_id, int initializer_end_pos) {
1096   // When the function is a kClassMembersInitializerFunction, we record the
1097   // source range of the entire class as its positions in its SFI, so at this
1098   // point the scanner should be rewound to the position of the class token.
1099   int class_token_pos = initializer_pos;
1100   DCHECK_EQ(peek_position(), class_token_pos);
1101 
1102   // Insert a FunctionState with the closest outer Declaration scope
1103   DeclarationScope* nearest_decl_scope = original_scope_->GetDeclarationScope();
1104   DCHECK_NOT_NULL(nearest_decl_scope);
1105   FunctionState function_state(&function_state_, &scope_, nearest_decl_scope);
1106   // We will reindex the function literals later.
1107   ResetFunctionLiteralId();
1108 
1109   // We preparse the class members that are not fields with initializers
1110   // in order to collect the function literal ids.
1111   ParsingModeScope mode(this, PARSE_LAZILY);
1112 
1113   ExpressionParsingScope no_expression_scope(impl());
1114 
1115   // Reparse the class as an expression to build the instance member
1116   // initializer function.
1117   Expression* expr = ParseClassExpression(original_scope_);
1118 
1119   DCHECK(expr->IsClassLiteral());
1120   ClassLiteral* literal = expr->AsClassLiteral();
1121   FunctionLiteral* initializer =
1122       literal->instance_members_initializer_function();
1123 
1124   // Reindex so that the function literal ids match.
1125   AstFunctionLiteralIdReindexer reindexer(
1126       stack_limit_, initializer_id - initializer->function_literal_id());
1127   reindexer.Reindex(expr);
1128 
1129   no_expression_scope.ValidateExpression();
1130 
1131   // If the class scope was not optimized away, we know that it allocated
1132   // some variables and we need to fix up the allocation info for them.
1133   bool needs_allocation_fixup =
1134       !maybe_class_scope_info.is_null() &&
1135       maybe_class_scope_info.ToHandleChecked()->scope_type() == CLASS_SCOPE &&
1136       maybe_class_scope_info.ToHandleChecked()->StartPosition() ==
1137           class_token_pos;
1138 
1139   ClassScope* reparsed_scope = literal->scope();
1140   reparsed_scope->FinalizeReparsedClassScope(isolate, maybe_class_scope_info,
1141                                              ast_value_factory(),
1142                                              needs_allocation_fixup);
1143   original_scope_ = reparsed_scope;
1144 
1145   DCHECK_EQ(initializer->kind(),
1146             FunctionKind::kClassMembersInitializerFunction);
1147   DCHECK_EQ(initializer->function_literal_id(), initializer_id);
1148   DCHECK_EQ(initializer->end_position(), initializer_end_pos);
1149 
1150   return initializer;
1151 }
1152 
ParseModuleItem()1153 Statement* Parser::ParseModuleItem() {
1154   // ecma262/#prod-ModuleItem
1155   // ModuleItem :
1156   //    ImportDeclaration
1157   //    ExportDeclaration
1158   //    StatementListItem
1159 
1160   Token::Value next = peek();
1161 
1162   if (next == Token::EXPORT) {
1163     return ParseExportDeclaration();
1164   }
1165 
1166   if (next == Token::IMPORT) {
1167     // We must be careful not to parse a dynamic import expression as an import
1168     // declaration. Same for import.meta expressions.
1169     Token::Value peek_ahead = PeekAhead();
1170     if (peek_ahead != Token::LPAREN && peek_ahead != Token::PERIOD) {
1171       ParseImportDeclaration();
1172       return factory()->EmptyStatement();
1173     }
1174   }
1175 
1176   return ParseStatementListItem();
1177 }
1178 
ParseModuleItemList(ScopedPtrList<Statement> * body)1179 void Parser::ParseModuleItemList(ScopedPtrList<Statement>* body) {
1180   // ecma262/#prod-Module
1181   // Module :
1182   //    ModuleBody?
1183   //
1184   // ecma262/#prod-ModuleItemList
1185   // ModuleBody :
1186   //    ModuleItem*
1187 
1188   DCHECK(scope()->is_module_scope());
1189   while (peek() != Token::EOS) {
1190     Statement* stat = ParseModuleItem();
1191     if (stat == nullptr) return;
1192     if (stat->IsEmptyStatement()) continue;
1193     body->Add(stat);
1194   }
1195 }
1196 
ParseModuleSpecifier()1197 const AstRawString* Parser::ParseModuleSpecifier() {
1198   // ModuleSpecifier :
1199   //    StringLiteral
1200 
1201   Expect(Token::STRING);
1202   return GetSymbol();
1203 }
1204 
ParseExportClause(Scanner::Location * reserved_loc,Scanner::Location * string_literal_local_name_loc)1205 ZoneChunkList<Parser::ExportClauseData>* Parser::ParseExportClause(
1206     Scanner::Location* reserved_loc,
1207     Scanner::Location* string_literal_local_name_loc) {
1208   // ExportClause :
1209   //   '{' '}'
1210   //   '{' ExportsList '}'
1211   //   '{' ExportsList ',' '}'
1212   //
1213   // ExportsList :
1214   //   ExportSpecifier
1215   //   ExportsList ',' ExportSpecifier
1216   //
1217   // ExportSpecifier :
1218   //   IdentifierName
1219   //   IdentifierName 'as' IdentifierName
1220   //   IdentifierName 'as' ModuleExportName
1221   //   ModuleExportName
1222   //   ModuleExportName 'as' ModuleExportName
1223   //
1224   // ModuleExportName :
1225   //   StringLiteral
1226   ZoneChunkList<ExportClauseData>* export_data =
1227       zone()->New<ZoneChunkList<ExportClauseData>>(zone());
1228 
1229   Expect(Token::LBRACE);
1230 
1231   Token::Value name_tok;
1232   while ((name_tok = peek()) != Token::RBRACE) {
1233     const AstRawString* local_name = ParseExportSpecifierName();
1234     if (!string_literal_local_name_loc->IsValid() &&
1235         name_tok == Token::STRING) {
1236       // Keep track of the first string literal local name exported for error
1237       // reporting. These must be followed by a 'from' clause.
1238       *string_literal_local_name_loc = scanner()->location();
1239     } else if (!reserved_loc->IsValid() &&
1240                !Token::IsValidIdentifier(name_tok, LanguageMode::kStrict, false,
1241                                          flags().is_module())) {
1242       // Keep track of the first reserved word encountered in case our
1243       // caller needs to report an error.
1244       *reserved_loc = scanner()->location();
1245     }
1246     const AstRawString* export_name;
1247     Scanner::Location location = scanner()->location();
1248     if (CheckContextualKeyword(ast_value_factory()->as_string())) {
1249       export_name = ParseExportSpecifierName();
1250       // Set the location to the whole "a as b" string, so that it makes sense
1251       // both for errors due to "a" and for errors due to "b".
1252       location.end_pos = scanner()->location().end_pos;
1253     } else {
1254       export_name = local_name;
1255     }
1256     export_data->push_back({export_name, local_name, location});
1257     if (peek() == Token::RBRACE) break;
1258     if (V8_UNLIKELY(!Check(Token::COMMA))) {
1259       ReportUnexpectedToken(Next());
1260       break;
1261     }
1262   }
1263 
1264   Expect(Token::RBRACE);
1265   return export_data;
1266 }
1267 
ParseExportSpecifierName()1268 const AstRawString* Parser::ParseExportSpecifierName() {
1269   Token::Value next = Next();
1270 
1271   // IdentifierName
1272   if (V8_LIKELY(Token::IsPropertyName(next))) {
1273     return GetSymbol();
1274   }
1275 
1276   // ModuleExportName
1277   if (next == Token::STRING) {
1278     const AstRawString* export_name = GetSymbol();
1279     if (V8_LIKELY(export_name->is_one_byte())) return export_name;
1280     if (!unibrow::Utf16::HasUnpairedSurrogate(
1281             reinterpret_cast<const uint16_t*>(export_name->raw_data()),
1282             export_name->length())) {
1283       return export_name;
1284     }
1285     ReportMessage(MessageTemplate::kInvalidModuleExportName);
1286     return EmptyIdentifierString();
1287   }
1288 
1289   ReportUnexpectedToken(next);
1290   return EmptyIdentifierString();
1291 }
1292 
ParseNamedImports(int pos)1293 ZonePtrList<const Parser::NamedImport>* Parser::ParseNamedImports(int pos) {
1294   // NamedImports :
1295   //   '{' '}'
1296   //   '{' ImportsList '}'
1297   //   '{' ImportsList ',' '}'
1298   //
1299   // ImportsList :
1300   //   ImportSpecifier
1301   //   ImportsList ',' ImportSpecifier
1302   //
1303   // ImportSpecifier :
1304   //   BindingIdentifier
1305   //   IdentifierName 'as' BindingIdentifier
1306   //   ModuleExportName 'as' BindingIdentifier
1307 
1308   Expect(Token::LBRACE);
1309 
1310   auto result = zone()->New<ZonePtrList<const NamedImport>>(1, zone());
1311   while (peek() != Token::RBRACE) {
1312     const AstRawString* import_name = ParseExportSpecifierName();
1313     const AstRawString* local_name = import_name;
1314     Scanner::Location location = scanner()->location();
1315     // In the presence of 'as', the left-side of the 'as' can
1316     // be any IdentifierName. But without 'as', it must be a valid
1317     // BindingIdentifier.
1318     if (CheckContextualKeyword(ast_value_factory()->as_string())) {
1319       local_name = ParsePropertyName();
1320     }
1321     if (!Token::IsValidIdentifier(scanner()->current_token(),
1322                                   LanguageMode::kStrict, false,
1323                                   flags().is_module())) {
1324       ReportMessage(MessageTemplate::kUnexpectedReserved);
1325       return nullptr;
1326     } else if (IsEvalOrArguments(local_name)) {
1327       ReportMessage(MessageTemplate::kStrictEvalArguments);
1328       return nullptr;
1329     }
1330 
1331     DeclareUnboundVariable(local_name, VariableMode::kConst,
1332                            kNeedsInitialization, position());
1333 
1334     NamedImport* import =
1335         zone()->New<NamedImport>(import_name, local_name, location);
1336     result->Add(import, zone());
1337 
1338     if (peek() == Token::RBRACE) break;
1339     Expect(Token::COMMA);
1340   }
1341 
1342   Expect(Token::RBRACE);
1343   return result;
1344 }
1345 
ParseImportAssertClause()1346 ImportAssertions* Parser::ParseImportAssertClause() {
1347   // WithClause :
1348   //    with '{' '}'
1349   //    with '{' WithEntries ','? '}'
1350 
1351   // WithEntries :
1352   //    LiteralPropertyName
1353   //    LiteralPropertyName ':' StringLiteral , WithEntries
1354 
1355   // (DEPRECATED)
1356   // AssertClause :
1357   //    assert '{' '}'
1358   //    assert '{' WithEntries ','? '}'
1359 
1360   auto import_assertions = zone()->New<ImportAssertions>(zone());
1361 
1362   if (FLAG_harmony_import_attributes && Check(Token::WITH)) {
1363     // 'with' keyword consumed
1364   } else if (FLAG_harmony_import_assertions &&
1365              !scanner()->HasLineTerminatorBeforeNext() &&
1366              CheckContextualKeyword(ast_value_factory()->assert_string())) {
1367     // The 'assert' contextual keyword is deprecated in favor of 'with', and we
1368     // need to investigate feasibility of unshipping.
1369     //
1370     // TODO(v8:13856): Remove once decision is made to unship 'assert' or keep.
1371 
1372     // NOTE(Node.js): Commented out to avoid backporting this use counter to Node.js 18
1373     // ++use_counts_[v8::Isolate::kImportAssertionDeprecatedSyntax];
1374   } else {
1375     return import_assertions;
1376   }
1377 
1378   Expect(Token::LBRACE);
1379 
1380   while (peek() != Token::RBRACE) {
1381     const AstRawString* attribute_key =
1382         Check(Token::STRING) ? GetSymbol() : ParsePropertyName();
1383 
1384     Scanner::Location location = scanner()->location();
1385 
1386     Expect(Token::COLON);
1387     Expect(Token::STRING);
1388 
1389     const AstRawString* attribute_value = GetSymbol();
1390 
1391     // Set the location to the whole "key: 'value'"" string, so that it makes
1392     // sense both for errors due to the key and errors due to the value.
1393     location.end_pos = scanner()->location().end_pos;
1394 
1395     auto result = import_assertions->insert(std::make_pair(
1396         attribute_key, std::make_pair(attribute_value, location)));
1397     if (!result.second) {
1398       // It is a syntax error if two AssertEntries have the same key.
1399       ReportMessageAt(location, MessageTemplate::kImportAssertionDuplicateKey,
1400                       attribute_key);
1401       break;
1402     }
1403 
1404     if (peek() == Token::RBRACE) break;
1405     if (V8_UNLIKELY(!Check(Token::COMMA))) {
1406       ReportUnexpectedToken(Next());
1407       break;
1408     }
1409   }
1410 
1411   Expect(Token::RBRACE);
1412 
1413   return import_assertions;
1414 }
1415 
ParseImportDeclaration()1416 void Parser::ParseImportDeclaration() {
1417   // ImportDeclaration :
1418   //   'import' ImportClause 'from' ModuleSpecifier ';'
1419   //   'import' ModuleSpecifier ';'
1420   //   'import' ImportClause 'from' ModuleSpecifier [no LineTerminator here]
1421   //       AssertClause ';'
1422   //   'import' ModuleSpecifier [no LineTerminator here] AssertClause';'
1423   //
1424   // ImportClause :
1425   //   ImportedDefaultBinding
1426   //   NameSpaceImport
1427   //   NamedImports
1428   //   ImportedDefaultBinding ',' NameSpaceImport
1429   //   ImportedDefaultBinding ',' NamedImports
1430   //
1431   // NameSpaceImport :
1432   //   '*' 'as' ImportedBinding
1433 
1434   int pos = peek_position();
1435   Expect(Token::IMPORT);
1436 
1437   Token::Value tok = peek();
1438 
1439   // 'import' ModuleSpecifier ';'
1440   if (tok == Token::STRING) {
1441     Scanner::Location specifier_loc = scanner()->peek_location();
1442     const AstRawString* module_specifier = ParseModuleSpecifier();
1443     const ImportAssertions* import_assertions = ParseImportAssertClause();
1444     ExpectSemicolon();
1445     module()->AddEmptyImport(module_specifier, import_assertions, specifier_loc,
1446                              zone());
1447     return;
1448   }
1449 
1450   // Parse ImportedDefaultBinding if present.
1451   const AstRawString* import_default_binding = nullptr;
1452   Scanner::Location import_default_binding_loc;
1453   if (tok != Token::MUL && tok != Token::LBRACE) {
1454     import_default_binding = ParseNonRestrictedIdentifier();
1455     import_default_binding_loc = scanner()->location();
1456     DeclareUnboundVariable(import_default_binding, VariableMode::kConst,
1457                            kNeedsInitialization, pos);
1458   }
1459 
1460   // Parse NameSpaceImport or NamedImports if present.
1461   const AstRawString* module_namespace_binding = nullptr;
1462   Scanner::Location module_namespace_binding_loc;
1463   const ZonePtrList<const NamedImport>* named_imports = nullptr;
1464   if (import_default_binding == nullptr || Check(Token::COMMA)) {
1465     switch (peek()) {
1466       case Token::MUL: {
1467         Consume(Token::MUL);
1468         ExpectContextualKeyword(ast_value_factory()->as_string());
1469         module_namespace_binding = ParseNonRestrictedIdentifier();
1470         module_namespace_binding_loc = scanner()->location();
1471         DeclareUnboundVariable(module_namespace_binding, VariableMode::kConst,
1472                                kCreatedInitialized, pos);
1473         break;
1474       }
1475 
1476       case Token::LBRACE:
1477         named_imports = ParseNamedImports(pos);
1478         break;
1479 
1480       default:
1481         ReportUnexpectedToken(scanner()->current_token());
1482         return;
1483     }
1484   }
1485 
1486   ExpectContextualKeyword(ast_value_factory()->from_string());
1487   Scanner::Location specifier_loc = scanner()->peek_location();
1488   const AstRawString* module_specifier = ParseModuleSpecifier();
1489   const ImportAssertions* import_assertions = ParseImportAssertClause();
1490   ExpectSemicolon();
1491 
1492   // Now that we have all the information, we can make the appropriate
1493   // declarations.
1494 
1495   // TODO(neis): Would prefer to call DeclareVariable for each case below rather
1496   // than above and in ParseNamedImports, but then a possible error message
1497   // would point to the wrong location.  Maybe have a DeclareAt version of
1498   // Declare that takes a location?
1499 
1500   if (module_namespace_binding != nullptr) {
1501     module()->AddStarImport(module_namespace_binding, module_specifier,
1502                             import_assertions, module_namespace_binding_loc,
1503                             specifier_loc, zone());
1504   }
1505 
1506   if (import_default_binding != nullptr) {
1507     module()->AddImport(ast_value_factory()->default_string(),
1508                         import_default_binding, module_specifier,
1509                         import_assertions, import_default_binding_loc,
1510                         specifier_loc, zone());
1511   }
1512 
1513   if (named_imports != nullptr) {
1514     if (named_imports->length() == 0) {
1515       module()->AddEmptyImport(module_specifier, import_assertions,
1516                                specifier_loc, zone());
1517     } else {
1518       for (const NamedImport* import : *named_imports) {
1519         module()->AddImport(import->import_name, import->local_name,
1520                             module_specifier, import_assertions,
1521                             import->location, specifier_loc, zone());
1522       }
1523     }
1524   }
1525 }
1526 
ParseExportDefault()1527 Statement* Parser::ParseExportDefault() {
1528   //  Supports the following productions, starting after the 'default' token:
1529   //    'export' 'default' HoistableDeclaration
1530   //    'export' 'default' ClassDeclaration
1531   //    'export' 'default' AssignmentExpression[In] ';'
1532 
1533   Expect(Token::DEFAULT);
1534   Scanner::Location default_loc = scanner()->location();
1535 
1536   ZonePtrList<const AstRawString> local_names(1, zone());
1537   Statement* result = nullptr;
1538   switch (peek()) {
1539     case Token::FUNCTION:
1540       result = ParseHoistableDeclaration(&local_names, true);
1541       break;
1542 
1543     case Token::CLASS:
1544       Consume(Token::CLASS);
1545       result = ParseClassDeclaration(&local_names, true);
1546       break;
1547 
1548     case Token::ASYNC:
1549       if (PeekAhead() == Token::FUNCTION &&
1550           !scanner()->HasLineTerminatorAfterNext()) {
1551         Consume(Token::ASYNC);
1552         result = ParseAsyncFunctionDeclaration(&local_names, true);
1553         break;
1554       }
1555       V8_FALLTHROUGH;
1556 
1557     default: {
1558       int pos = position();
1559       AcceptINScope scope(this, true);
1560       Expression* value = ParseAssignmentExpression();
1561       SetFunctionName(value, ast_value_factory()->default_string());
1562 
1563       const AstRawString* local_name =
1564           ast_value_factory()->dot_default_string();
1565       local_names.Add(local_name, zone());
1566 
1567       // It's fine to declare this as VariableMode::kConst because the user has
1568       // no way of writing to it.
1569       VariableProxy* proxy =
1570           DeclareBoundVariable(local_name, VariableMode::kConst, pos);
1571       proxy->var()->set_initializer_position(position());
1572 
1573       Assignment* assignment = factory()->NewAssignment(
1574           Token::INIT, proxy, value, kNoSourcePosition);
1575       result = IgnoreCompletion(
1576           factory()->NewExpressionStatement(assignment, kNoSourcePosition));
1577 
1578       ExpectSemicolon();
1579       break;
1580     }
1581   }
1582 
1583   if (result != nullptr) {
1584     DCHECK_EQ(local_names.length(), 1);
1585     module()->AddExport(local_names.first(),
1586                         ast_value_factory()->default_string(), default_loc,
1587                         zone());
1588   }
1589 
1590   return result;
1591 }
1592 
NextInternalNamespaceExportName()1593 const AstRawString* Parser::NextInternalNamespaceExportName() {
1594   const char* prefix = ".ns-export";
1595   std::string s(prefix);
1596   s.append(std::to_string(number_of_named_namespace_exports_++));
1597   return ast_value_factory()->GetOneByteString(s.c_str());
1598 }
1599 
ParseExportStar()1600 void Parser::ParseExportStar() {
1601   int pos = position();
1602   Consume(Token::MUL);
1603 
1604   if (!PeekContextualKeyword(ast_value_factory()->as_string())) {
1605     // 'export' '*' 'from' ModuleSpecifier ';'
1606     Scanner::Location loc = scanner()->location();
1607     ExpectContextualKeyword(ast_value_factory()->from_string());
1608     Scanner::Location specifier_loc = scanner()->peek_location();
1609     const AstRawString* module_specifier = ParseModuleSpecifier();
1610     const ImportAssertions* import_assertions = ParseImportAssertClause();
1611     ExpectSemicolon();
1612     module()->AddStarExport(module_specifier, import_assertions, loc,
1613                             specifier_loc, zone());
1614     return;
1615   }
1616 
1617   // 'export' '*' 'as' IdentifierName 'from' ModuleSpecifier ';'
1618   //
1619   // Desugaring:
1620   //   export * as x from "...";
1621   // ~>
1622   //   import * as .x from "..."; export {.x as x};
1623   //
1624   // Note that the desugared internal namespace export name (.x above) will
1625   // never conflict with a string literal export name, as literal string export
1626   // names in local name positions (i.e. left of 'as' or in a clause without
1627   // 'as') are disallowed without a following 'from' clause.
1628 
1629   ExpectContextualKeyword(ast_value_factory()->as_string());
1630   const AstRawString* export_name = ParseExportSpecifierName();
1631   Scanner::Location export_name_loc = scanner()->location();
1632   const AstRawString* local_name = NextInternalNamespaceExportName();
1633   Scanner::Location local_name_loc = Scanner::Location::invalid();
1634   DeclareUnboundVariable(local_name, VariableMode::kConst, kCreatedInitialized,
1635                          pos);
1636 
1637   ExpectContextualKeyword(ast_value_factory()->from_string());
1638   Scanner::Location specifier_loc = scanner()->peek_location();
1639   const AstRawString* module_specifier = ParseModuleSpecifier();
1640   const ImportAssertions* import_assertions = ParseImportAssertClause();
1641   ExpectSemicolon();
1642 
1643   module()->AddStarImport(local_name, module_specifier, import_assertions,
1644                           local_name_loc, specifier_loc, zone());
1645   module()->AddExport(local_name, export_name, export_name_loc, zone());
1646 }
1647 
ParseExportDeclaration()1648 Statement* Parser::ParseExportDeclaration() {
1649   // ExportDeclaration:
1650   //    'export' '*' 'from' ModuleSpecifier ';'
1651   //    'export' '*' 'from' ModuleSpecifier [no LineTerminator here]
1652   //        AssertClause ';'
1653   //    'export' '*' 'as' IdentifierName 'from' ModuleSpecifier ';'
1654   //    'export' '*' 'as' IdentifierName 'from' ModuleSpecifier
1655   //        [no LineTerminator here] AssertClause ';'
1656   //    'export' '*' 'as' ModuleExportName 'from' ModuleSpecifier ';'
1657   //    'export' '*' 'as' ModuleExportName 'from' ModuleSpecifier ';'
1658   //        [no LineTerminator here] AssertClause ';'
1659   //    'export' ExportClause ('from' ModuleSpecifier)? ';'
1660   //    'export' ExportClause ('from' ModuleSpecifier [no LineTerminator here]
1661   //        AssertClause)? ';'
1662   //    'export' VariableStatement
1663   //    'export' Declaration
1664   //    'export' 'default' ... (handled in ParseExportDefault)
1665   //
1666   // ModuleExportName :
1667   //   StringLiteral
1668 
1669   Expect(Token::EXPORT);
1670   Statement* result = nullptr;
1671   ZonePtrList<const AstRawString> names(1, zone());
1672   Scanner::Location loc = scanner()->peek_location();
1673   switch (peek()) {
1674     case Token::DEFAULT:
1675       return ParseExportDefault();
1676 
1677     case Token::MUL:
1678       ParseExportStar();
1679       return factory()->EmptyStatement();
1680 
1681     case Token::LBRACE: {
1682       // There are two cases here:
1683       //
1684       // 'export' ExportClause ';'
1685       // and
1686       // 'export' ExportClause FromClause ';'
1687       //
1688       // In the first case, the exported identifiers in ExportClause must
1689       // not be reserved words, while in the latter they may be. We
1690       // pass in a location that gets filled with the first reserved word
1691       // encountered, and then throw a SyntaxError if we are in the
1692       // non-FromClause case.
1693       Scanner::Location reserved_loc = Scanner::Location::invalid();
1694       Scanner::Location string_literal_local_name_loc =
1695           Scanner::Location::invalid();
1696       ZoneChunkList<ExportClauseData>* export_data =
1697           ParseExportClause(&reserved_loc, &string_literal_local_name_loc);
1698       if (CheckContextualKeyword(ast_value_factory()->from_string())) {
1699         Scanner::Location specifier_loc = scanner()->peek_location();
1700         const AstRawString* module_specifier = ParseModuleSpecifier();
1701         const ImportAssertions* import_assertions = ParseImportAssertClause();
1702         ExpectSemicolon();
1703 
1704         if (export_data->is_empty()) {
1705           module()->AddEmptyImport(module_specifier, import_assertions,
1706                                    specifier_loc, zone());
1707         } else {
1708           for (const ExportClauseData& data : *export_data) {
1709             module()->AddExport(data.local_name, data.export_name,
1710                                 module_specifier, import_assertions,
1711                                 data.location, specifier_loc, zone());
1712           }
1713         }
1714       } else {
1715         if (reserved_loc.IsValid()) {
1716           // No FromClause, so reserved words are invalid in ExportClause.
1717           ReportMessageAt(reserved_loc, MessageTemplate::kUnexpectedReserved);
1718           return nullptr;
1719         } else if (string_literal_local_name_loc.IsValid()) {
1720           ReportMessageAt(string_literal_local_name_loc,
1721                           MessageTemplate::kModuleExportNameWithoutFromClause);
1722           return nullptr;
1723         }
1724 
1725         ExpectSemicolon();
1726 
1727         for (const ExportClauseData& data : *export_data) {
1728           module()->AddExport(data.local_name, data.export_name, data.location,
1729                               zone());
1730         }
1731       }
1732       return factory()->EmptyStatement();
1733     }
1734 
1735     case Token::FUNCTION:
1736       result = ParseHoistableDeclaration(&names, false);
1737       break;
1738 
1739     case Token::CLASS:
1740       Consume(Token::CLASS);
1741       result = ParseClassDeclaration(&names, false);
1742       break;
1743 
1744     case Token::VAR:
1745     case Token::LET:
1746     case Token::CONST:
1747       result = ParseVariableStatement(kStatementListItem, &names);
1748       break;
1749 
1750     case Token::ASYNC:
1751       Consume(Token::ASYNC);
1752       if (peek() == Token::FUNCTION &&
1753           !scanner()->HasLineTerminatorBeforeNext()) {
1754         result = ParseAsyncFunctionDeclaration(&names, false);
1755         break;
1756       }
1757       V8_FALLTHROUGH;
1758 
1759     default:
1760       ReportUnexpectedToken(scanner()->current_token());
1761       return nullptr;
1762   }
1763   loc.end_pos = scanner()->location().end_pos;
1764 
1765   SourceTextModuleDescriptor* descriptor = module();
1766   for (const AstRawString* name : names) {
1767     descriptor->AddExport(name, name, loc, zone());
1768   }
1769 
1770   return result;
1771 }
1772 
DeclareUnboundVariable(const AstRawString * name,VariableMode mode,InitializationFlag init,int pos)1773 void Parser::DeclareUnboundVariable(const AstRawString* name, VariableMode mode,
1774                                     InitializationFlag init, int pos) {
1775   bool was_added;
1776   Variable* var = DeclareVariable(name, NORMAL_VARIABLE, mode, init, scope(),
1777                                   &was_added, pos, end_position());
1778   // The variable will be added to the declarations list, but since we are not
1779   // binding it to anything, we can simply ignore it here.
1780   USE(var);
1781 }
1782 
DeclareBoundVariable(const AstRawString * name,VariableMode mode,int pos)1783 VariableProxy* Parser::DeclareBoundVariable(const AstRawString* name,
1784                                             VariableMode mode, int pos) {
1785   DCHECK_NOT_NULL(name);
1786   VariableProxy* proxy =
1787       factory()->NewVariableProxy(name, NORMAL_VARIABLE, position());
1788   bool was_added;
1789   Variable* var = DeclareVariable(name, NORMAL_VARIABLE, mode,
1790                                   Variable::DefaultInitializationFlag(mode),
1791                                   scope(), &was_added, pos, end_position());
1792   proxy->BindTo(var);
1793   return proxy;
1794 }
1795 
DeclareAndBindVariable(VariableProxy * proxy,VariableKind kind,VariableMode mode,Scope * scope,bool * was_added,int initializer_position)1796 void Parser::DeclareAndBindVariable(VariableProxy* proxy, VariableKind kind,
1797                                     VariableMode mode, Scope* scope,
1798                                     bool* was_added, int initializer_position) {
1799   Variable* var = DeclareVariable(
1800       proxy->raw_name(), kind, mode, Variable::DefaultInitializationFlag(mode),
1801       scope, was_added, proxy->position(), kNoSourcePosition);
1802   var->set_initializer_position(initializer_position);
1803   proxy->BindTo(var);
1804 }
1805 
DeclareVariable(const AstRawString * name,VariableKind kind,VariableMode mode,InitializationFlag init,Scope * scope,bool * was_added,int begin,int end)1806 Variable* Parser::DeclareVariable(const AstRawString* name, VariableKind kind,
1807                                   VariableMode mode, InitializationFlag init,
1808                                   Scope* scope, bool* was_added, int begin,
1809                                   int end) {
1810   Declaration* declaration;
1811   if (mode == VariableMode::kVar && !scope->is_declaration_scope()) {
1812     DCHECK(scope->is_block_scope() || scope->is_with_scope());
1813     declaration = factory()->NewNestedVariableDeclaration(scope, begin);
1814   } else {
1815     declaration = factory()->NewVariableDeclaration(begin);
1816   }
1817   Declare(declaration, name, kind, mode, init, scope, was_added, begin, end);
1818   return declaration->var();
1819 }
1820 
Declare(Declaration * declaration,const AstRawString * name,VariableKind variable_kind,VariableMode mode,InitializationFlag init,Scope * scope,bool * was_added,int var_begin_pos,int var_end_pos)1821 void Parser::Declare(Declaration* declaration, const AstRawString* name,
1822                      VariableKind variable_kind, VariableMode mode,
1823                      InitializationFlag init, Scope* scope, bool* was_added,
1824                      int var_begin_pos, int var_end_pos) {
1825   bool local_ok = true;
1826   bool sloppy_mode_block_scope_function_redefinition = false;
1827   scope->DeclareVariable(
1828       declaration, name, var_begin_pos, mode, variable_kind, init, was_added,
1829       &sloppy_mode_block_scope_function_redefinition, &local_ok);
1830   if (!local_ok) {
1831     // If we only have the start position of a proxy, we can't highlight the
1832     // whole variable name.  Pretend its length is 1 so that we highlight at
1833     // least the first character.
1834     Scanner::Location loc(var_begin_pos, var_end_pos != kNoSourcePosition
1835                                              ? var_end_pos
1836                                              : var_begin_pos + 1);
1837     if (variable_kind == PARAMETER_VARIABLE) {
1838       ReportMessageAt(loc, MessageTemplate::kParamDupe);
1839     } else {
1840       ReportMessageAt(loc, MessageTemplate::kVarRedeclaration,
1841                       declaration->var()->raw_name());
1842     }
1843   } else if (sloppy_mode_block_scope_function_redefinition) {
1844     ++use_counts_[v8::Isolate::kSloppyModeBlockScopedFunctionRedefinition];
1845   }
1846 }
1847 
BuildInitializationBlock(DeclarationParsingResult * parsing_result)1848 Statement* Parser::BuildInitializationBlock(
1849     DeclarationParsingResult* parsing_result) {
1850   ScopedPtrList<Statement> statements(pointer_buffer());
1851   for (const auto& declaration : parsing_result->declarations) {
1852     if (!declaration.initializer) continue;
1853     InitializeVariables(&statements, parsing_result->descriptor.kind,
1854                         &declaration);
1855   }
1856   return factory()->NewBlock(true, statements);
1857 }
1858 
DeclareFunction(const AstRawString * variable_name,FunctionLiteral * function,VariableMode mode,VariableKind kind,int beg_pos,int end_pos,ZonePtrList<const AstRawString> * names)1859 Statement* Parser::DeclareFunction(const AstRawString* variable_name,
1860                                    FunctionLiteral* function, VariableMode mode,
1861                                    VariableKind kind, int beg_pos, int end_pos,
1862                                    ZonePtrList<const AstRawString>* names) {
1863   Declaration* declaration =
1864       factory()->NewFunctionDeclaration(function, beg_pos);
1865   bool was_added;
1866   Declare(declaration, variable_name, kind, mode, kCreatedInitialized, scope(),
1867           &was_added, beg_pos);
1868   if (info()->flags().coverage_enabled()) {
1869     // Force the function to be allocated when collecting source coverage, so
1870     // that even dead functions get source coverage data.
1871     declaration->var()->set_is_used();
1872   }
1873   if (names) names->Add(variable_name, zone());
1874   if (kind == SLOPPY_BLOCK_FUNCTION_VARIABLE) {
1875     Token::Value init = loop_nesting_depth() > 0 ? Token::ASSIGN : Token::INIT;
1876     SloppyBlockFunctionStatement* statement =
1877         factory()->NewSloppyBlockFunctionStatement(end_pos, declaration->var(),
1878                                                    init);
1879     GetDeclarationScope()->DeclareSloppyBlockFunction(statement);
1880     return statement;
1881   }
1882   return factory()->EmptyStatement();
1883 }
1884 
DeclareClass(const AstRawString * variable_name,Expression * value,ZonePtrList<const AstRawString> * names,int class_token_pos,int end_pos)1885 Statement* Parser::DeclareClass(const AstRawString* variable_name,
1886                                 Expression* value,
1887                                 ZonePtrList<const AstRawString>* names,
1888                                 int class_token_pos, int end_pos) {
1889   VariableProxy* proxy =
1890       DeclareBoundVariable(variable_name, VariableMode::kLet, class_token_pos);
1891   proxy->var()->set_initializer_position(end_pos);
1892   if (names) names->Add(variable_name, zone());
1893 
1894   Assignment* assignment =
1895       factory()->NewAssignment(Token::INIT, proxy, value, class_token_pos);
1896   return IgnoreCompletion(
1897       factory()->NewExpressionStatement(assignment, kNoSourcePosition));
1898 }
1899 
DeclareNative(const AstRawString * name,int pos)1900 Statement* Parser::DeclareNative(const AstRawString* name, int pos) {
1901   // Make sure that the function containing the native declaration
1902   // isn't lazily compiled. The extension structures are only
1903   // accessible while parsing the first time not when reparsing
1904   // because of lazy compilation.
1905   GetClosureScope()->ForceEagerCompilation();
1906 
1907   // TODO(1240846): It's weird that native function declarations are
1908   // introduced dynamically when we meet their declarations, whereas
1909   // other functions are set up when entering the surrounding scope.
1910   VariableProxy* proxy = DeclareBoundVariable(name, VariableMode::kVar, pos);
1911   NativeFunctionLiteral* lit =
1912       factory()->NewNativeFunctionLiteral(name, extension(), kNoSourcePosition);
1913   return factory()->NewExpressionStatement(
1914       factory()->NewAssignment(Token::INIT, proxy, lit, kNoSourcePosition),
1915       pos);
1916 }
1917 
IgnoreCompletion(Statement * statement)1918 Block* Parser::IgnoreCompletion(Statement* statement) {
1919   Block* block = factory()->NewBlock(1, true);
1920   block->statements()->Add(statement, zone());
1921   return block;
1922 }
1923 
RewriteReturn(Expression * return_value,int pos)1924 Expression* Parser::RewriteReturn(Expression* return_value, int pos) {
1925   if (IsDerivedConstructor(function_state_->kind())) {
1926     // For subclass constructors we need to return this in case of undefined;
1927     // other primitive values trigger an exception in the ConstructStub.
1928     //
1929     //   return expr;
1930     //
1931     // Is rewritten as:
1932     //
1933     //   return (temp = expr) === undefined ? this : temp;
1934 
1935     // temp = expr
1936     Variable* temp = NewTemporary(ast_value_factory()->empty_string());
1937     Assignment* assign = factory()->NewAssignment(
1938         Token::ASSIGN, factory()->NewVariableProxy(temp), return_value, pos);
1939 
1940     // temp === undefined
1941     Expression* is_undefined = factory()->NewCompareOperation(
1942         Token::EQ_STRICT, assign,
1943         factory()->NewUndefinedLiteral(kNoSourcePosition), pos);
1944 
1945     // is_undefined ? this : temp
1946     // We don't need to call UseThis() since it's guaranteed to be called
1947     // for derived constructors after parsing the constructor in
1948     // ParseFunctionBody.
1949     return_value =
1950         factory()->NewConditional(is_undefined, factory()->ThisExpression(),
1951                                   factory()->NewVariableProxy(temp), pos);
1952   }
1953   return return_value;
1954 }
1955 
RewriteSwitchStatement(SwitchStatement * switch_statement,Scope * scope)1956 Statement* Parser::RewriteSwitchStatement(SwitchStatement* switch_statement,
1957                                           Scope* scope) {
1958   // In order to get the CaseClauses to execute in their own lexical scope,
1959   // but without requiring downstream code to have special scope handling
1960   // code for switch statements, desugar into blocks as follows:
1961   // {  // To group the statements--harmless to evaluate Expression in scope
1962   //   .tag_variable = Expression;
1963   //   {  // To give CaseClauses a scope
1964   //     switch (.tag_variable) { CaseClause* }
1965   //   }
1966   // }
1967   DCHECK_NOT_NULL(scope);
1968   DCHECK(scope->is_block_scope());
1969   DCHECK_GE(switch_statement->position(), scope->start_position());
1970   DCHECK_LT(switch_statement->position(), scope->end_position());
1971 
1972   Block* switch_block = factory()->NewBlock(2, false);
1973 
1974   Expression* tag = switch_statement->tag();
1975   Variable* tag_variable =
1976       NewTemporary(ast_value_factory()->dot_switch_tag_string());
1977   Assignment* tag_assign = factory()->NewAssignment(
1978       Token::ASSIGN, factory()->NewVariableProxy(tag_variable), tag,
1979       tag->position());
1980   // Wrap with IgnoreCompletion so the tag isn't returned as the completion
1981   // value, in case the switch statements don't have a value.
1982   Statement* tag_statement = IgnoreCompletion(
1983       factory()->NewExpressionStatement(tag_assign, kNoSourcePosition));
1984   switch_block->statements()->Add(tag_statement, zone());
1985 
1986   switch_statement->set_tag(factory()->NewVariableProxy(tag_variable));
1987   Block* cases_block = factory()->NewBlock(1, false);
1988   cases_block->statements()->Add(switch_statement, zone());
1989   cases_block->set_scope(scope);
1990   switch_block->statements()->Add(cases_block, zone());
1991   return switch_block;
1992 }
1993 
InitializeVariables(ScopedPtrList<Statement> * statements,VariableKind kind,const DeclarationParsingResult::Declaration * declaration)1994 void Parser::InitializeVariables(
1995     ScopedPtrList<Statement>* statements, VariableKind kind,
1996     const DeclarationParsingResult::Declaration* declaration) {
1997   if (has_error()) return;
1998 
1999   DCHECK_NOT_NULL(declaration->initializer);
2000 
2001   int pos = declaration->value_beg_pos;
2002   if (pos == kNoSourcePosition) {
2003     pos = declaration->initializer->position();
2004   }
2005   Assignment* assignment = factory()->NewAssignment(
2006       Token::INIT, declaration->pattern, declaration->initializer, pos);
2007   statements->Add(factory()->NewExpressionStatement(assignment, pos));
2008 }
2009 
RewriteCatchPattern(CatchInfo * catch_info)2010 Block* Parser::RewriteCatchPattern(CatchInfo* catch_info) {
2011   DCHECK_NOT_NULL(catch_info->pattern);
2012 
2013   DeclarationParsingResult::Declaration decl(
2014       catch_info->pattern, factory()->NewVariableProxy(catch_info->variable));
2015 
2016   ScopedPtrList<Statement> init_statements(pointer_buffer());
2017   InitializeVariables(&init_statements, NORMAL_VARIABLE, &decl);
2018   return factory()->NewBlock(true, init_statements);
2019 }
2020 
ReportVarRedeclarationIn(const AstRawString * name,Scope * scope)2021 void Parser::ReportVarRedeclarationIn(const AstRawString* name, Scope* scope) {
2022   for (Declaration* decl : *scope->declarations()) {
2023     if (decl->var()->raw_name() == name) {
2024       int position = decl->position();
2025       Scanner::Location location =
2026           position == kNoSourcePosition
2027               ? Scanner::Location::invalid()
2028               : Scanner::Location(position, position + name->length());
2029       ReportMessageAt(location, MessageTemplate::kVarRedeclaration, name);
2030       return;
2031     }
2032   }
2033   UNREACHABLE();
2034 }
2035 
RewriteTryStatement(Block * try_block,Block * catch_block,const SourceRange & catch_range,Block * finally_block,const SourceRange & finally_range,const CatchInfo & catch_info,int pos)2036 Statement* Parser::RewriteTryStatement(Block* try_block, Block* catch_block,
2037                                        const SourceRange& catch_range,
2038                                        Block* finally_block,
2039                                        const SourceRange& finally_range,
2040                                        const CatchInfo& catch_info, int pos) {
2041   // Simplify the AST nodes by converting:
2042   //   'try B0 catch B1 finally B2'
2043   // to:
2044   //   'try { try B0 catch B1 } finally B2'
2045 
2046   if (catch_block != nullptr && finally_block != nullptr) {
2047     // If we have both, create an inner try/catch.
2048     TryCatchStatement* statement;
2049     statement = factory()->NewTryCatchStatement(try_block, catch_info.scope,
2050                                                 catch_block, kNoSourcePosition);
2051     RecordTryCatchStatementSourceRange(statement, catch_range);
2052 
2053     try_block = factory()->NewBlock(1, false);
2054     try_block->statements()->Add(statement, zone());
2055     catch_block = nullptr;  // Clear to indicate it's been handled.
2056   }
2057 
2058   if (catch_block != nullptr) {
2059     DCHECK_NULL(finally_block);
2060     TryCatchStatement* stmt = factory()->NewTryCatchStatement(
2061         try_block, catch_info.scope, catch_block, pos);
2062     RecordTryCatchStatementSourceRange(stmt, catch_range);
2063     return stmt;
2064   } else {
2065     DCHECK_NOT_NULL(finally_block);
2066     TryFinallyStatement* stmt =
2067         factory()->NewTryFinallyStatement(try_block, finally_block, pos);
2068     RecordTryFinallyStatementSourceRange(stmt, finally_range);
2069     return stmt;
2070   }
2071 }
2072 
ParseAndRewriteGeneratorFunctionBody(int pos,FunctionKind kind,ScopedPtrList<Statement> * body)2073 void Parser::ParseAndRewriteGeneratorFunctionBody(
2074     int pos, FunctionKind kind, ScopedPtrList<Statement>* body) {
2075   // For ES6 Generators, we just prepend the initial yield.
2076   Expression* initial_yield = BuildInitialYield(pos, kind);
2077   body->Add(
2078       factory()->NewExpressionStatement(initial_yield, kNoSourcePosition));
2079   ParseStatementList(body, Token::RBRACE);
2080 }
2081 
ParseAndRewriteAsyncGeneratorFunctionBody(int pos,FunctionKind kind,ScopedPtrList<Statement> * body)2082 void Parser::ParseAndRewriteAsyncGeneratorFunctionBody(
2083     int pos, FunctionKind kind, ScopedPtrList<Statement>* body) {
2084   // For ES2017 Async Generators, we produce:
2085   //
2086   // try {
2087   //   InitialYield;
2088   //   ...body...;
2089   //   // fall through to the implicit return after the try-finally
2090   // } catch (.catch) {
2091   //   %AsyncGeneratorReject(generator, .catch);
2092   // } finally {
2093   //   %_GeneratorClose(generator);
2094   // }
2095   //
2096   // - InitialYield yields the actual generator object.
2097   // - Any return statement inside the body will have its argument wrapped
2098   //   in an iterator result object with a "done" property set to `true`.
2099   // - If the generator terminates for whatever reason, we must close it.
2100   //   Hence the finally clause.
2101   // - BytecodeGenerator performs special handling for ReturnStatements in
2102   //   async generator functions, resolving the appropriate Promise with an
2103   //   "done" iterator result object containing a Promise-unwrapped value.
2104   DCHECK(IsAsyncGeneratorFunction(kind));
2105 
2106   Block* try_block;
2107   {
2108     ScopedPtrList<Statement> statements(pointer_buffer());
2109     Expression* initial_yield = BuildInitialYield(pos, kind);
2110     statements.Add(
2111         factory()->NewExpressionStatement(initial_yield, kNoSourcePosition));
2112     ParseStatementList(&statements, Token::RBRACE);
2113     // Since the whole body is wrapped in a try-catch, make the implicit
2114     // end-of-function return explicit to ensure BytecodeGenerator's special
2115     // handling for ReturnStatements in async generators applies.
2116     statements.Add(factory()->NewSyntheticAsyncReturnStatement(
2117         factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition));
2118 
2119     // Don't create iterator result for async generators, as the resume methods
2120     // will create it.
2121     try_block = factory()->NewBlock(false, statements);
2122   }
2123 
2124   // For AsyncGenerators, a top-level catch block will reject the Promise.
2125   Scope* catch_scope = NewHiddenCatchScope();
2126 
2127   Block* catch_block;
2128   {
2129     ScopedPtrList<Expression> reject_args(pointer_buffer());
2130     reject_args.Add(factory()->NewVariableProxy(
2131         function_state_->scope()->generator_object_var()));
2132     reject_args.Add(factory()->NewVariableProxy(catch_scope->catch_variable()));
2133 
2134     Expression* reject_call = factory()->NewCallRuntime(
2135         Runtime::kInlineAsyncGeneratorReject, reject_args, kNoSourcePosition);
2136     catch_block = IgnoreCompletion(factory()->NewReturnStatement(
2137         reject_call, kNoSourcePosition, kNoSourcePosition));
2138   }
2139 
2140   {
2141     ScopedPtrList<Statement> statements(pointer_buffer());
2142     TryStatement* try_catch = factory()->NewTryCatchStatementForAsyncAwait(
2143         try_block, catch_scope, catch_block, kNoSourcePosition);
2144     statements.Add(try_catch);
2145     try_block = factory()->NewBlock(false, statements);
2146   }
2147 
2148   Expression* close_call;
2149   {
2150     ScopedPtrList<Expression> close_args(pointer_buffer());
2151     VariableProxy* call_proxy = factory()->NewVariableProxy(
2152         function_state_->scope()->generator_object_var());
2153     close_args.Add(call_proxy);
2154     close_call = factory()->NewCallRuntime(Runtime::kInlineGeneratorClose,
2155                                            close_args, kNoSourcePosition);
2156   }
2157 
2158   Block* finally_block;
2159   {
2160     ScopedPtrList<Statement> statements(pointer_buffer());
2161     statements.Add(
2162         factory()->NewExpressionStatement(close_call, kNoSourcePosition));
2163     finally_block = factory()->NewBlock(false, statements);
2164   }
2165 
2166   body->Add(factory()->NewTryFinallyStatement(try_block, finally_block,
2167                                               kNoSourcePosition));
2168 }
2169 
DeclareFunctionNameVar(const AstRawString * function_name,FunctionSyntaxKind function_syntax_kind,DeclarationScope * function_scope)2170 void Parser::DeclareFunctionNameVar(const AstRawString* function_name,
2171                                     FunctionSyntaxKind function_syntax_kind,
2172                                     DeclarationScope* function_scope) {
2173   if (function_syntax_kind == FunctionSyntaxKind::kNamedExpression &&
2174       function_scope->LookupLocal(function_name) == nullptr) {
2175     DCHECK_EQ(function_scope, scope());
2176     function_scope->DeclareFunctionVar(function_name);
2177   }
2178 }
2179 
2180 // Special case for legacy for
2181 //
2182 //    for (var x = initializer in enumerable) body
2183 //
2184 // An initialization block of the form
2185 //
2186 //    {
2187 //      x = initializer;
2188 //    }
2189 //
2190 // is returned in this case.  It has reserved space for two statements,
2191 // so that (later on during parsing), the equivalent of
2192 //
2193 //   for (x in enumerable) body
2194 //
2195 // is added as a second statement to it.
RewriteForVarInLegacy(const ForInfo & for_info)2196 Block* Parser::RewriteForVarInLegacy(const ForInfo& for_info) {
2197   const DeclarationParsingResult::Declaration& decl =
2198       for_info.parsing_result.declarations[0];
2199   if (!IsLexicalVariableMode(for_info.parsing_result.descriptor.mode) &&
2200       decl.initializer != nullptr && decl.pattern->IsVariableProxy()) {
2201     ++use_counts_[v8::Isolate::kForInInitializer];
2202     const AstRawString* name = decl.pattern->AsVariableProxy()->raw_name();
2203     VariableProxy* single_var = NewUnresolved(name);
2204     Block* init_block = factory()->NewBlock(2, true);
2205     init_block->statements()->Add(
2206         factory()->NewExpressionStatement(
2207             factory()->NewAssignment(Token::ASSIGN, single_var,
2208                                      decl.initializer, decl.value_beg_pos),
2209             kNoSourcePosition),
2210         zone());
2211     return init_block;
2212   }
2213   return nullptr;
2214 }
2215 
2216 // Rewrite a for-in/of statement of the form
2217 //
2218 //   for (let/const/var x in/of e) b
2219 //
2220 // into
2221 //
2222 //   {
2223 //     var temp;
2224 //     for (temp in/of e) {
2225 //       let/const/var x = temp;
2226 //       b;
2227 //     }
2228 //     let x;  // for TDZ
2229 //   }
DesugarBindingInForEachStatement(ForInfo * for_info,Block ** body_block,Expression ** each_variable)2230 void Parser::DesugarBindingInForEachStatement(ForInfo* for_info,
2231                                               Block** body_block,
2232                                               Expression** each_variable) {
2233   DCHECK_EQ(1, for_info->parsing_result.declarations.size());
2234   DeclarationParsingResult::Declaration& decl =
2235       for_info->parsing_result.declarations[0];
2236   Variable* temp = NewTemporary(ast_value_factory()->dot_for_string());
2237   ScopedPtrList<Statement> each_initialization_statements(pointer_buffer());
2238   DCHECK_IMPLIES(!has_error(), decl.pattern != nullptr);
2239   decl.initializer = factory()->NewVariableProxy(temp, for_info->position);
2240   InitializeVariables(&each_initialization_statements, NORMAL_VARIABLE, &decl);
2241 
2242   *body_block = factory()->NewBlock(3, false);
2243   (*body_block)
2244       ->statements()
2245       ->Add(factory()->NewBlock(true, each_initialization_statements), zone());
2246   *each_variable = factory()->NewVariableProxy(temp, for_info->position);
2247 }
2248 
2249 // Create a TDZ for any lexically-bound names in for in/of statements.
CreateForEachStatementTDZ(Block * init_block,const ForInfo & for_info)2250 Block* Parser::CreateForEachStatementTDZ(Block* init_block,
2251                                          const ForInfo& for_info) {
2252   if (IsLexicalVariableMode(for_info.parsing_result.descriptor.mode)) {
2253     DCHECK_NULL(init_block);
2254 
2255     init_block = factory()->NewBlock(1, false);
2256 
2257     for (const AstRawString* bound_name : for_info.bound_names) {
2258       // TODO(adamk): This needs to be some sort of special
2259       // INTERNAL variable that's invisible to the debugger
2260       // but visible to everything else.
2261       VariableProxy* tdz_proxy = DeclareBoundVariable(
2262           bound_name, VariableMode::kLet, kNoSourcePosition);
2263       tdz_proxy->var()->set_initializer_position(position());
2264     }
2265   }
2266   return init_block;
2267 }
2268 
DesugarLexicalBindingsInForStatement(ForStatement * loop,Statement * init,Expression * cond,Statement * next,Statement * body,Scope * inner_scope,const ForInfo & for_info)2269 Statement* Parser::DesugarLexicalBindingsInForStatement(
2270     ForStatement* loop, Statement* init, Expression* cond, Statement* next,
2271     Statement* body, Scope* inner_scope, const ForInfo& for_info) {
2272   // ES6 13.7.4.8 specifies that on each loop iteration the let variables are
2273   // copied into a new environment.  Moreover, the "next" statement must be
2274   // evaluated not in the environment of the just completed iteration but in
2275   // that of the upcoming one.  We achieve this with the following desugaring.
2276   // Extra care is needed to preserve the completion value of the original loop.
2277   //
2278   // We are given a for statement of the form
2279   //
2280   //  labels: for (let/const x = i; cond; next) body
2281   //
2282   // and rewrite it as follows.  Here we write {{ ... }} for init-blocks, ie.,
2283   // blocks whose ignore_completion_value_ flag is set.
2284   //
2285   //  {
2286   //    let/const x = i;
2287   //    temp_x = x;
2288   //    first = 1;
2289   //    undefined;
2290   //    outer: for (;;) {
2291   //      let/const x = temp_x;
2292   //      {{ if (first == 1) {
2293   //           first = 0;
2294   //         } else {
2295   //           next;
2296   //         }
2297   //         flag = 1;
2298   //         if (!cond) break;
2299   //      }}
2300   //      labels: for (; flag == 1; flag = 0, temp_x = x) {
2301   //        body
2302   //      }
2303   //      {{ if (flag == 1)  // Body used break.
2304   //           break;
2305   //      }}
2306   //    }
2307   //  }
2308 
2309   DCHECK_GT(for_info.bound_names.length(), 0);
2310   ScopedPtrList<Variable> temps(pointer_buffer());
2311 
2312   Block* outer_block =
2313       factory()->NewBlock(for_info.bound_names.length() + 4, false);
2314 
2315   // Add statement: let/const x = i.
2316   outer_block->statements()->Add(init, zone());
2317 
2318   const AstRawString* temp_name = ast_value_factory()->dot_for_string();
2319 
2320   // For each lexical variable x:
2321   //   make statement: temp_x = x.
2322   for (const AstRawString* bound_name : for_info.bound_names) {
2323     VariableProxy* proxy = NewUnresolved(bound_name);
2324     Variable* temp = NewTemporary(temp_name);
2325     VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
2326     Assignment* assignment = factory()->NewAssignment(Token::ASSIGN, temp_proxy,
2327                                                       proxy, kNoSourcePosition);
2328     Statement* assignment_statement =
2329         factory()->NewExpressionStatement(assignment, kNoSourcePosition);
2330     outer_block->statements()->Add(assignment_statement, zone());
2331     temps.Add(temp);
2332   }
2333 
2334   Variable* first = nullptr;
2335   // Make statement: first = 1.
2336   if (next) {
2337     first = NewTemporary(temp_name);
2338     VariableProxy* first_proxy = factory()->NewVariableProxy(first);
2339     Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
2340     Assignment* assignment = factory()->NewAssignment(
2341         Token::ASSIGN, first_proxy, const1, kNoSourcePosition);
2342     Statement* assignment_statement =
2343         factory()->NewExpressionStatement(assignment, kNoSourcePosition);
2344     outer_block->statements()->Add(assignment_statement, zone());
2345   }
2346 
2347   // make statement: undefined;
2348   outer_block->statements()->Add(
2349       factory()->NewExpressionStatement(
2350           factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition),
2351       zone());
2352 
2353   // Make statement: outer: for (;;)
2354   // Note that we don't actually create the label, or set this loop up as an
2355   // explicit break target, instead handing it directly to those nodes that
2356   // need to know about it. This should be safe because we don't run any code
2357   // in this function that looks up break targets.
2358   ForStatement* outer_loop = factory()->NewForStatement(kNoSourcePosition);
2359   outer_block->statements()->Add(outer_loop, zone());
2360   outer_block->set_scope(scope());
2361 
2362   Block* inner_block = factory()->NewBlock(3, false);
2363   {
2364     BlockState block_state(&scope_, inner_scope);
2365 
2366     Block* ignore_completion_block =
2367         factory()->NewBlock(for_info.bound_names.length() + 3, true);
2368     ScopedPtrList<Variable> inner_vars(pointer_buffer());
2369     // For each let variable x:
2370     //    make statement: let/const x = temp_x.
2371     for (int i = 0; i < for_info.bound_names.length(); i++) {
2372       VariableProxy* proxy = DeclareBoundVariable(
2373           for_info.bound_names[i], for_info.parsing_result.descriptor.mode,
2374           kNoSourcePosition);
2375       inner_vars.Add(proxy->var());
2376       VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
2377       Assignment* assignment = factory()->NewAssignment(
2378           Token::INIT, proxy, temp_proxy, kNoSourcePosition);
2379       Statement* assignment_statement =
2380           factory()->NewExpressionStatement(assignment, kNoSourcePosition);
2381       int declaration_pos = for_info.parsing_result.descriptor.declaration_pos;
2382       DCHECK_NE(declaration_pos, kNoSourcePosition);
2383       proxy->var()->set_initializer_position(declaration_pos);
2384       ignore_completion_block->statements()->Add(assignment_statement, zone());
2385     }
2386 
2387     // Make statement: if (first == 1) { first = 0; } else { next; }
2388     if (next) {
2389       DCHECK(first);
2390       Expression* compare = nullptr;
2391       // Make compare expression: first == 1.
2392       {
2393         Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
2394         VariableProxy* first_proxy = factory()->NewVariableProxy(first);
2395         compare = factory()->NewCompareOperation(Token::EQ, first_proxy, const1,
2396                                                  kNoSourcePosition);
2397       }
2398       Statement* clear_first = nullptr;
2399       // Make statement: first = 0.
2400       {
2401         VariableProxy* first_proxy = factory()->NewVariableProxy(first);
2402         Expression* const0 = factory()->NewSmiLiteral(0, kNoSourcePosition);
2403         Assignment* assignment = factory()->NewAssignment(
2404             Token::ASSIGN, first_proxy, const0, kNoSourcePosition);
2405         clear_first =
2406             factory()->NewExpressionStatement(assignment, kNoSourcePosition);
2407       }
2408       Statement* clear_first_or_next = factory()->NewIfStatement(
2409           compare, clear_first, next, kNoSourcePosition);
2410       ignore_completion_block->statements()->Add(clear_first_or_next, zone());
2411     }
2412 
2413     Variable* flag = NewTemporary(temp_name);
2414     // Make statement: flag = 1.
2415     {
2416       VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
2417       Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
2418       Assignment* assignment = factory()->NewAssignment(
2419           Token::ASSIGN, flag_proxy, const1, kNoSourcePosition);
2420       Statement* assignment_statement =
2421           factory()->NewExpressionStatement(assignment, kNoSourcePosition);
2422       ignore_completion_block->statements()->Add(assignment_statement, zone());
2423     }
2424 
2425     // Make statement: if (!cond) break.
2426     if (cond) {
2427       Statement* stop =
2428           factory()->NewBreakStatement(outer_loop, kNoSourcePosition);
2429       Statement* noop = factory()->EmptyStatement();
2430       ignore_completion_block->statements()->Add(
2431           factory()->NewIfStatement(cond, noop, stop, cond->position()),
2432           zone());
2433     }
2434 
2435     inner_block->statements()->Add(ignore_completion_block, zone());
2436     // Make cond expression for main loop: flag == 1.
2437     Expression* flag_cond = nullptr;
2438     {
2439       Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
2440       VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
2441       flag_cond = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1,
2442                                                  kNoSourcePosition);
2443     }
2444 
2445     // Create chain of expressions "flag = 0, temp_x = x, ..."
2446     Statement* compound_next_statement = nullptr;
2447     {
2448       Expression* compound_next = nullptr;
2449       // Make expression: flag = 0.
2450       {
2451         VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
2452         Expression* const0 = factory()->NewSmiLiteral(0, kNoSourcePosition);
2453         compound_next = factory()->NewAssignment(Token::ASSIGN, flag_proxy,
2454                                                  const0, kNoSourcePosition);
2455       }
2456 
2457       // Make the comma-separated list of temp_x = x assignments.
2458       int inner_var_proxy_pos = scanner()->location().beg_pos;
2459       for (int i = 0; i < for_info.bound_names.length(); i++) {
2460         VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
2461         VariableProxy* proxy =
2462             factory()->NewVariableProxy(inner_vars.at(i), inner_var_proxy_pos);
2463         Assignment* assignment = factory()->NewAssignment(
2464             Token::ASSIGN, temp_proxy, proxy, kNoSourcePosition);
2465         compound_next = factory()->NewBinaryOperation(
2466             Token::COMMA, compound_next, assignment, kNoSourcePosition);
2467       }
2468 
2469       compound_next_statement =
2470           factory()->NewExpressionStatement(compound_next, kNoSourcePosition);
2471     }
2472 
2473     // Make statement: labels: for (; flag == 1; flag = 0, temp_x = x)
2474     // Note that we re-use the original loop node, which retains its labels
2475     // and ensures that any break or continue statements in body point to
2476     // the right place.
2477     loop->Initialize(nullptr, flag_cond, compound_next_statement, body);
2478     inner_block->statements()->Add(loop, zone());
2479 
2480     // Make statement: {{if (flag == 1) break;}}
2481     {
2482       Expression* compare = nullptr;
2483       // Make compare expresion: flag == 1.
2484       {
2485         Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition);
2486         VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
2487         compare = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1,
2488                                                  kNoSourcePosition);
2489       }
2490       Statement* stop =
2491           factory()->NewBreakStatement(outer_loop, kNoSourcePosition);
2492       Statement* empty = factory()->EmptyStatement();
2493       Statement* if_flag_break =
2494           factory()->NewIfStatement(compare, stop, empty, kNoSourcePosition);
2495       inner_block->statements()->Add(IgnoreCompletion(if_flag_break), zone());
2496     }
2497 
2498     inner_block->set_scope(inner_scope);
2499   }
2500 
2501   outer_loop->Initialize(nullptr, nullptr, nullptr, inner_block);
2502 
2503   return outer_block;
2504 }
2505 
ValidateDuplicate(Parser * parser) const2506 void ParserFormalParameters::ValidateDuplicate(Parser* parser) const {
2507   if (has_duplicate()) {
2508     parser->ReportMessageAt(duplicate_loc, MessageTemplate::kParamDupe);
2509   }
2510 }
ValidateStrictMode(Parser * parser) const2511 void ParserFormalParameters::ValidateStrictMode(Parser* parser) const {
2512   if (strict_error_loc.IsValid()) {
2513     parser->ReportMessageAt(strict_error_loc, strict_error_message);
2514   }
2515 }
2516 
AddArrowFunctionFormalParameters(ParserFormalParameters * parameters,Expression * expr,int end_pos)2517 void Parser::AddArrowFunctionFormalParameters(
2518     ParserFormalParameters* parameters, Expression* expr, int end_pos) {
2519   // ArrowFunctionFormals ::
2520   //    Nary(Token::COMMA, VariableProxy*, Tail)
2521   //    Binary(Token::COMMA, NonTailArrowFunctionFormals, Tail)
2522   //    Tail
2523   // NonTailArrowFunctionFormals ::
2524   //    Binary(Token::COMMA, NonTailArrowFunctionFormals, VariableProxy)
2525   //    VariableProxy
2526   // Tail ::
2527   //    VariableProxy
2528   //    Spread(VariableProxy)
2529   //
2530   // We need to visit the parameters in left-to-right order
2531   //
2532 
2533   // For the Nary case, we simply visit the parameters in a loop.
2534   if (expr->IsNaryOperation()) {
2535     NaryOperation* nary = expr->AsNaryOperation();
2536     // The classifier has already run, so we know that the expression is a valid
2537     // arrow function formals production.
2538     DCHECK_EQ(nary->op(), Token::COMMA);
2539     // Each op position is the end position of the *previous* expr, with the
2540     // second (i.e. first "subsequent") op position being the end position of
2541     // the first child expression.
2542     Expression* next = nary->first();
2543     for (size_t i = 0; i < nary->subsequent_length(); ++i) {
2544       AddArrowFunctionFormalParameters(parameters, next,
2545                                        nary->subsequent_op_position(i));
2546       next = nary->subsequent(i);
2547     }
2548     AddArrowFunctionFormalParameters(parameters, next, end_pos);
2549     return;
2550   }
2551 
2552   // For the binary case, we recurse on the left-hand side of binary comma
2553   // expressions.
2554   if (expr->IsBinaryOperation()) {
2555     BinaryOperation* binop = expr->AsBinaryOperation();
2556     // The classifier has already run, so we know that the expression is a valid
2557     // arrow function formals production.
2558     DCHECK_EQ(binop->op(), Token::COMMA);
2559     Expression* left = binop->left();
2560     Expression* right = binop->right();
2561     int comma_pos = binop->position();
2562     AddArrowFunctionFormalParameters(parameters, left, comma_pos);
2563     // LHS of comma expression should be unparenthesized.
2564     expr = right;
2565   }
2566 
2567   // Only the right-most expression may be a rest parameter.
2568   DCHECK(!parameters->has_rest);
2569 
2570   bool is_rest = expr->IsSpread();
2571   if (is_rest) {
2572     expr = expr->AsSpread()->expression();
2573     parameters->has_rest = true;
2574   }
2575   DCHECK_IMPLIES(parameters->is_simple, !is_rest);
2576   DCHECK_IMPLIES(parameters->is_simple, expr->IsVariableProxy());
2577 
2578   Expression* initializer = nullptr;
2579   if (expr->IsAssignment()) {
2580     Assignment* assignment = expr->AsAssignment();
2581     DCHECK(!assignment->IsCompoundAssignment());
2582     initializer = assignment->value();
2583     expr = assignment->target();
2584   }
2585 
2586   AddFormalParameter(parameters, expr, initializer, end_pos, is_rest);
2587 }
2588 
DeclareArrowFunctionFormalParameters(ParserFormalParameters * parameters,Expression * expr,const Scanner::Location & params_loc)2589 void Parser::DeclareArrowFunctionFormalParameters(
2590     ParserFormalParameters* parameters, Expression* expr,
2591     const Scanner::Location& params_loc) {
2592   if (expr->IsEmptyParentheses() || has_error()) return;
2593 
2594   AddArrowFunctionFormalParameters(parameters, expr, params_loc.end_pos);
2595 
2596   if (parameters->arity > Code::kMaxArguments) {
2597     ReportMessageAt(params_loc, MessageTemplate::kMalformedArrowFunParamList);
2598     return;
2599   }
2600 
2601   DeclareFormalParameters(parameters);
2602   DCHECK_IMPLIES(parameters->is_simple,
2603                  parameters->scope->has_simple_parameters());
2604 }
2605 
PrepareGeneratorVariables()2606 void Parser::PrepareGeneratorVariables() {
2607   // Calling a generator returns a generator object.  That object is stored
2608   // in a temporary variable, a definition that is used by "yield"
2609   // expressions.
2610   function_state_->scope()->DeclareGeneratorObjectVar(
2611       ast_value_factory()->dot_generator_object_string());
2612 }
2613 
ParseFunctionLiteral(const AstRawString * function_name,Scanner::Location function_name_location,FunctionNameValidity function_name_validity,FunctionKind kind,int function_token_pos,FunctionSyntaxKind function_syntax_kind,LanguageMode language_mode,ZonePtrList<const AstRawString> * arguments_for_wrapped_function)2614 FunctionLiteral* Parser::ParseFunctionLiteral(
2615     const AstRawString* function_name, Scanner::Location function_name_location,
2616     FunctionNameValidity function_name_validity, FunctionKind kind,
2617     int function_token_pos, FunctionSyntaxKind function_syntax_kind,
2618     LanguageMode language_mode,
2619     ZonePtrList<const AstRawString>* arguments_for_wrapped_function) {
2620   // Function ::
2621   //   '(' FormalParameterList? ')' '{' FunctionBody '}'
2622   //
2623   // Getter ::
2624   //   '(' ')' '{' FunctionBody '}'
2625   //
2626   // Setter ::
2627   //   '(' PropertySetParameterList ')' '{' FunctionBody '}'
2628 
2629   bool is_wrapped = function_syntax_kind == FunctionSyntaxKind::kWrapped;
2630   DCHECK_EQ(is_wrapped, arguments_for_wrapped_function != nullptr);
2631 
2632   int pos = function_token_pos == kNoSourcePosition ? peek_position()
2633                                                     : function_token_pos;
2634   DCHECK_NE(kNoSourcePosition, pos);
2635 
2636   // Anonymous functions were passed either the empty symbol or a null
2637   // handle as the function name.  Remember if we were passed a non-empty
2638   // handle to decide whether to invoke function name inference.
2639   bool should_infer_name = function_name == nullptr;
2640 
2641   // We want a non-null handle as the function name by default. We will handle
2642   // the "function does not have a shared name" case later.
2643   if (should_infer_name) {
2644     function_name = ast_value_factory()->empty_string();
2645   }
2646 
2647   FunctionLiteral::EagerCompileHint eager_compile_hint =
2648       function_state_->next_function_is_likely_called() || is_wrapped
2649           ? FunctionLiteral::kShouldEagerCompile
2650           : default_eager_compile_hint();
2651 
2652   // Determine if the function can be parsed lazily. Lazy parsing is
2653   // different from lazy compilation; we need to parse more eagerly than we
2654   // compile.
2655 
2656   // We can only parse lazily if we also compile lazily. The heuristics for lazy
2657   // compilation are:
2658   // - It must not have been prohibited by the caller to Parse (some callers
2659   //   need a full AST).
2660   // - The outer scope must allow lazy compilation of inner functions.
2661   // - The function mustn't be a function expression with an open parenthesis
2662   //   before; we consider that a hint that the function will be called
2663   //   immediately, and it would be a waste of time to make it lazily
2664   //   compiled.
2665   // These are all things we can know at this point, without looking at the
2666   // function itself.
2667 
2668   // We separate between lazy parsing top level functions and lazy parsing inner
2669   // functions, because the latter needs to do more work. In particular, we need
2670   // to track unresolved variables to distinguish between these cases:
2671   // (function foo() {
2672   //   bar = function() { return 1; }
2673   //  })();
2674   // and
2675   // (function foo() {
2676   //   var a = 1;
2677   //   bar = function() { return a; }
2678   //  })();
2679 
2680   // Now foo will be parsed eagerly and compiled eagerly (optimization: assume
2681   // parenthesis before the function means that it will be called
2682   // immediately). bar can be parsed lazily, but we need to parse it in a mode
2683   // that tracks unresolved variables.
2684   DCHECK_IMPLIES(parse_lazily(), info()->flags().allow_lazy_compile());
2685   DCHECK_IMPLIES(parse_lazily(), has_error() || allow_lazy_);
2686   DCHECK_IMPLIES(parse_lazily(), extension() == nullptr);
2687 
2688   const bool is_lazy =
2689       eager_compile_hint == FunctionLiteral::kShouldLazyCompile;
2690   const bool is_top_level = AllowsLazyParsingWithoutUnresolvedVariables();
2691   const bool is_eager_top_level_function = !is_lazy && is_top_level;
2692 
2693   RCS_SCOPE(runtime_call_stats_, RuntimeCallCounterId::kParseFunctionLiteral,
2694             RuntimeCallStats::kThreadSpecific);
2695   base::ElapsedTimer timer;
2696   if (V8_UNLIKELY(FLAG_log_function_events)) timer.Start();
2697 
2698   // Determine whether we can lazy parse the inner function. Lazy compilation
2699   // has to be enabled, which is either forced by overall parse flags or via a
2700   // ParsingModeScope.
2701   const bool can_preparse = parse_lazily();
2702 
2703   // Determine whether we can post any parallel compile tasks. Preparsing must
2704   // be possible, there has to be a dispatcher, and the character stream must be
2705   // cloneable.
2706   const bool can_post_parallel_task =
2707       can_preparse && info()->dispatcher() &&
2708       scanner()->stream()->can_be_cloned_for_parallel_access();
2709 
2710   // If parallel compile tasks are enabled, enable parallel compile for the
2711   // subset of functions as defined by flags.
2712   bool should_post_parallel_task =
2713       can_post_parallel_task &&
2714       ((is_eager_top_level_function &&
2715         flags().post_parallel_compile_tasks_for_eager_toplevel()) ||
2716        (is_lazy && flags().post_parallel_compile_tasks_for_lazy()));
2717 
2718   // Determine whether we should lazy parse the inner function. This will be
2719   // when either the function is lazy by inspection, or when we force it to be
2720   // preparsed now so that we can then post a parallel full parse & compile task
2721   // for it.
2722   const bool should_preparse =
2723       can_preparse && (is_lazy || should_post_parallel_task);
2724 
2725   ScopedPtrList<Statement> body(pointer_buffer());
2726   int expected_property_count = 0;
2727   int suspend_count = -1;
2728   int num_parameters = -1;
2729   int function_length = -1;
2730   bool has_duplicate_parameters = false;
2731   int function_literal_id = GetNextFunctionLiteralId();
2732   ProducedPreparseData* produced_preparse_data = nullptr;
2733 
2734   // Inner functions will be parsed using a temporary Zone. After parsing, we
2735   // will migrate unresolved variable into a Scope in the main Zone.
2736   Zone* parse_zone = should_preparse ? &preparser_zone_ : zone();
2737   // This Scope lives in the main zone. We'll migrate data into that zone later.
2738   DeclarationScope* scope = NewFunctionScope(kind, parse_zone);
2739   SetLanguageMode(scope, language_mode);
2740 #ifdef DEBUG
2741   scope->SetScopeName(function_name);
2742 #endif
2743 
2744   if (!is_wrapped && V8_UNLIKELY(!Check(Token::LPAREN))) {
2745     ReportUnexpectedToken(Next());
2746     return nullptr;
2747   }
2748   scope->set_start_position(position());
2749 
2750   // Eager or lazy parse? If is_lazy_top_level_function, we'll parse
2751   // lazily. We'll call SkipFunction, which may decide to
2752   // abort lazy parsing if it suspects that wasn't a good idea. If so (in
2753   // which case the parser is expected to have backtracked), or if we didn't
2754   // try to lazy parse in the first place, we'll have to parse eagerly.
2755   bool did_preparse_successfully =
2756       should_preparse &&
2757       SkipFunction(function_name, kind, function_syntax_kind, scope,
2758                    &num_parameters, &function_length, &produced_preparse_data);
2759 
2760   if (!did_preparse_successfully) {
2761     // If skipping aborted, it rewound the scanner until before the LPAREN.
2762     // Consume it in that case.
2763     if (should_preparse) Consume(Token::LPAREN);
2764     should_post_parallel_task = false;
2765     ParseFunction(&body, function_name, pos, kind, function_syntax_kind, scope,
2766                   &num_parameters, &function_length, &has_duplicate_parameters,
2767                   &expected_property_count, &suspend_count,
2768                   arguments_for_wrapped_function);
2769   }
2770 
2771   if (V8_UNLIKELY(FLAG_log_function_events)) {
2772     double ms = timer.Elapsed().InMillisecondsF();
2773     const char* event_name =
2774         should_preparse
2775             ? (is_top_level ? "preparse-no-resolution" : "preparse-resolution")
2776             : "full-parse";
2777     logger_->FunctionEvent(
2778         event_name, flags().script_id(), ms, scope->start_position(),
2779         scope->end_position(),
2780         reinterpret_cast<const char*>(function_name->raw_data()),
2781         function_name->byte_length(), function_name->is_one_byte());
2782   }
2783 #ifdef V8_RUNTIME_CALL_STATS
2784   if (did_preparse_successfully && runtime_call_stats_ &&
2785       V8_UNLIKELY(TracingFlags::is_runtime_stats_enabled())) {
2786     runtime_call_stats_->CorrectCurrentCounterId(
2787         RuntimeCallCounterId::kPreParseWithVariableResolution,
2788         RuntimeCallStats::kThreadSpecific);
2789   }
2790 #endif  // V8_RUNTIME_CALL_STATS
2791 
2792   // Validate function name. We can do this only after parsing the function,
2793   // since the function can declare itself strict.
2794   language_mode = scope->language_mode();
2795   CheckFunctionName(language_mode, function_name, function_name_validity,
2796                     function_name_location);
2797 
2798   if (is_strict(language_mode)) {
2799     CheckStrictOctalLiteral(scope->start_position(), scope->end_position());
2800   }
2801 
2802   FunctionLiteral::ParameterFlag duplicate_parameters =
2803       has_duplicate_parameters ? FunctionLiteral::kHasDuplicateParameters
2804                                : FunctionLiteral::kNoDuplicateParameters;
2805 
2806   // Note that the FunctionLiteral needs to be created in the main Zone again.
2807   FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
2808       function_name, scope, body, expected_property_count, num_parameters,
2809       function_length, duplicate_parameters, function_syntax_kind,
2810       eager_compile_hint, pos, true, function_literal_id,
2811       produced_preparse_data);
2812   function_literal->set_function_token_position(function_token_pos);
2813   function_literal->set_suspend_count(suspend_count);
2814 
2815   RecordFunctionLiteralSourceRange(function_literal);
2816 
2817   if (should_post_parallel_task && !has_error()) {
2818     function_literal->set_should_parallel_compile();
2819   }
2820 
2821   if (should_infer_name) {
2822     fni_.AddFunction(function_literal);
2823   }
2824   return function_literal;
2825 }
2826 
SkipFunction(const AstRawString * function_name,FunctionKind kind,FunctionSyntaxKind function_syntax_kind,DeclarationScope * function_scope,int * num_parameters,int * function_length,ProducedPreparseData ** produced_preparse_data)2827 bool Parser::SkipFunction(const AstRawString* function_name, FunctionKind kind,
2828                           FunctionSyntaxKind function_syntax_kind,
2829                           DeclarationScope* function_scope, int* num_parameters,
2830                           int* function_length,
2831                           ProducedPreparseData** produced_preparse_data) {
2832   FunctionState function_state(&function_state_, &scope_, function_scope);
2833   function_scope->set_zone(&preparser_zone_);
2834 
2835   DCHECK_NE(kNoSourcePosition, function_scope->start_position());
2836   DCHECK_EQ(kNoSourcePosition, parameters_end_pos_);
2837 
2838   DCHECK_IMPLIES(IsArrowFunction(kind),
2839                  scanner()->current_token() == Token::ARROW);
2840 
2841   // FIXME(marja): There are 2 ways to skip functions now. Unify them.
2842   if (consumed_preparse_data_) {
2843     int end_position;
2844     LanguageMode language_mode;
2845     int num_inner_functions;
2846     bool uses_super_property;
2847     if (stack_overflow()) return true;
2848     {
2849       base::Optional<UnparkedScope> unparked_scope;
2850       if (overall_parse_is_parked_) {
2851         unparked_scope.emplace(local_isolate_);
2852       }
2853       *produced_preparse_data =
2854           consumed_preparse_data_->GetDataForSkippableFunction(
2855               main_zone(), function_scope->start_position(), &end_position,
2856               num_parameters, function_length, &num_inner_functions,
2857               &uses_super_property, &language_mode);
2858     }
2859 
2860     function_scope->outer_scope()->SetMustUsePreparseData();
2861     function_scope->set_is_skipped_function(true);
2862     function_scope->set_end_position(end_position);
2863     scanner()->SeekForward(end_position - 1);
2864     Expect(Token::RBRACE);
2865     SetLanguageMode(function_scope, language_mode);
2866     if (uses_super_property) {
2867       function_scope->RecordSuperPropertyUsage();
2868     }
2869     SkipFunctionLiterals(num_inner_functions);
2870     function_scope->ResetAfterPreparsing(ast_value_factory_, false);
2871     return true;
2872   }
2873 
2874   Scanner::BookmarkScope bookmark(scanner());
2875   bookmark.Set(function_scope->start_position());
2876 
2877   UnresolvedList::Iterator unresolved_private_tail;
2878   PrivateNameScopeIterator private_name_scope_iter(function_scope);
2879   if (!private_name_scope_iter.Done()) {
2880     unresolved_private_tail =
2881         private_name_scope_iter.GetScope()->GetUnresolvedPrivateNameTail();
2882   }
2883 
2884   // With no cached data, we partially parse the function, without building an
2885   // AST. This gathers the data needed to build a lazy function.
2886   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.PreParse");
2887 
2888   PreParser::PreParseResult result = reusable_preparser()->PreParseFunction(
2889       function_name, kind, function_syntax_kind, function_scope, use_counts_,
2890       produced_preparse_data);
2891 
2892   if (result == PreParser::kPreParseStackOverflow) {
2893     // Propagate stack overflow.
2894     set_stack_overflow();
2895   } else if (pending_error_handler()->has_error_unidentifiable_by_preparser()) {
2896     // Make sure we don't re-preparse inner functions of the aborted function.
2897     // The error might be in an inner function.
2898     allow_lazy_ = false;
2899     mode_ = PARSE_EAGERLY;
2900     DCHECK(!pending_error_handler()->stack_overflow());
2901     // If we encounter an error that the preparser can not identify we reset to
2902     // the state before preparsing. The caller may then fully parse the function
2903     // to identify the actual error.
2904     bookmark.Apply();
2905     if (!private_name_scope_iter.Done()) {
2906       private_name_scope_iter.GetScope()->ResetUnresolvedPrivateNameTail(
2907           unresolved_private_tail);
2908     }
2909     function_scope->ResetAfterPreparsing(ast_value_factory_, true);
2910     pending_error_handler()->clear_unidentifiable_error();
2911     return false;
2912   } else if (pending_error_handler()->has_pending_error()) {
2913     DCHECK(!pending_error_handler()->stack_overflow());
2914     DCHECK(has_error());
2915   } else {
2916     DCHECK(!pending_error_handler()->stack_overflow());
2917     set_allow_eval_cache(reusable_preparser()->allow_eval_cache());
2918 
2919     PreParserLogger* logger = reusable_preparser()->logger();
2920     function_scope->set_end_position(logger->end());
2921     Expect(Token::RBRACE);
2922     total_preparse_skipped_ +=
2923         function_scope->end_position() - function_scope->start_position();
2924     *num_parameters = logger->num_parameters();
2925     *function_length = logger->function_length();
2926     SkipFunctionLiterals(logger->num_inner_functions());
2927     if (!private_name_scope_iter.Done()) {
2928       private_name_scope_iter.GetScope()->MigrateUnresolvedPrivateNameTail(
2929           factory(), unresolved_private_tail);
2930     }
2931     function_scope->AnalyzePartially(this, factory(), MaybeParsingArrowhead());
2932   }
2933 
2934   return true;
2935 }
2936 
BuildParameterInitializationBlock(const ParserFormalParameters & parameters)2937 Block* Parser::BuildParameterInitializationBlock(
2938     const ParserFormalParameters& parameters) {
2939   DCHECK(!parameters.is_simple);
2940   DCHECK(scope()->is_function_scope());
2941   DCHECK_EQ(scope(), parameters.scope);
2942   ScopedPtrList<Statement> init_statements(pointer_buffer());
2943   int index = 0;
2944   for (auto parameter : parameters.params) {
2945     Expression* initial_value =
2946         factory()->NewVariableProxy(parameters.scope->parameter(index));
2947     if (parameter->initializer() != nullptr) {
2948       // IS_UNDEFINED($param) ? initializer : $param
2949 
2950       auto condition = factory()->NewCompareOperation(
2951           Token::EQ_STRICT,
2952           factory()->NewVariableProxy(parameters.scope->parameter(index)),
2953           factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition);
2954       initial_value =
2955           factory()->NewConditional(condition, parameter->initializer(),
2956                                     initial_value, kNoSourcePosition);
2957     }
2958 
2959     BlockState block_state(&scope_, scope()->AsDeclarationScope());
2960     DeclarationParsingResult::Declaration decl(parameter->pattern,
2961                                                initial_value);
2962     InitializeVariables(&init_statements, PARAMETER_VARIABLE, &decl);
2963 
2964     ++index;
2965   }
2966   return factory()->NewBlock(true, init_statements);
2967 }
2968 
NewHiddenCatchScope()2969 Scope* Parser::NewHiddenCatchScope() {
2970   Scope* catch_scope = NewScopeWithParent(scope(), CATCH_SCOPE);
2971   bool was_added;
2972   catch_scope->DeclareLocal(ast_value_factory()->dot_catch_string(),
2973                             VariableMode::kVar, NORMAL_VARIABLE, &was_added);
2974   DCHECK(was_added);
2975   catch_scope->set_is_hidden();
2976   return catch_scope;
2977 }
2978 
BuildRejectPromiseOnException(Block * inner_block,REPLMode repl_mode)2979 Block* Parser::BuildRejectPromiseOnException(Block* inner_block,
2980                                              REPLMode repl_mode) {
2981   // try {
2982   //   <inner_block>
2983   // } catch (.catch) {
2984   //   return %_AsyncFunctionReject(.generator_object, .catch, can_suspend);
2985   // }
2986   Block* result = factory()->NewBlock(1, true);
2987 
2988   // catch (.catch) {
2989   //   return %_AsyncFunctionReject(.generator_object, .catch, can_suspend)
2990   // }
2991   Scope* catch_scope = NewHiddenCatchScope();
2992 
2993   Expression* reject_promise;
2994   {
2995     ScopedPtrList<Expression> args(pointer_buffer());
2996     args.Add(factory()->NewVariableProxy(
2997         function_state_->scope()->generator_object_var()));
2998     args.Add(factory()->NewVariableProxy(catch_scope->catch_variable()));
2999     reject_promise = factory()->NewCallRuntime(
3000         Runtime::kInlineAsyncFunctionReject, args, kNoSourcePosition);
3001   }
3002   Block* catch_block = IgnoreCompletion(factory()->NewReturnStatement(
3003       reject_promise, kNoSourcePosition, kNoSourcePosition));
3004 
3005   // Treat the exception for REPL mode scripts as UNCAUGHT. This will
3006   // keep the corresponding JSMessageObject alive on the Isolate. The
3007   // message object is used by the inspector to provide better error
3008   // messages for REPL inputs that throw.
3009   TryStatement* try_catch_statement =
3010       repl_mode == REPLMode::kYes
3011           ? factory()->NewTryCatchStatementForReplAsyncAwait(
3012                 inner_block, catch_scope, catch_block, kNoSourcePosition)
3013           : factory()->NewTryCatchStatementForAsyncAwait(
3014                 inner_block, catch_scope, catch_block, kNoSourcePosition);
3015   result->statements()->Add(try_catch_statement, zone());
3016   return result;
3017 }
3018 
BuildInitialYield(int pos,FunctionKind kind)3019 Expression* Parser::BuildInitialYield(int pos, FunctionKind kind) {
3020   Expression* yield_result = factory()->NewVariableProxy(
3021       function_state_->scope()->generator_object_var());
3022   // The position of the yield is important for reporting the exception
3023   // caused by calling the .throw method on a generator suspended at the
3024   // initial yield (i.e. right after generator instantiation).
3025   function_state_->AddSuspend();
3026   return factory()->NewYield(yield_result, scope()->start_position(),
3027                              Suspend::kOnExceptionThrow);
3028 }
3029 
ParseFunction(ScopedPtrList<Statement> * body,const AstRawString * function_name,int pos,FunctionKind kind,FunctionSyntaxKind function_syntax_kind,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)3030 void Parser::ParseFunction(
3031     ScopedPtrList<Statement>* body, const AstRawString* function_name, int pos,
3032     FunctionKind kind, FunctionSyntaxKind function_syntax_kind,
3033     DeclarationScope* function_scope, int* num_parameters, int* function_length,
3034     bool* has_duplicate_parameters, int* expected_property_count,
3035     int* suspend_count,
3036     ZonePtrList<const AstRawString>* arguments_for_wrapped_function) {
3037   FunctionParsingScope function_parsing_scope(this);
3038   ParsingModeScope mode(this, allow_lazy_ ? PARSE_LAZILY : PARSE_EAGERLY);
3039 
3040   FunctionState function_state(&function_state_, &scope_, function_scope);
3041 
3042   bool is_wrapped = function_syntax_kind == FunctionSyntaxKind::kWrapped;
3043 
3044   int expected_parameters_end_pos = parameters_end_pos_;
3045   if (expected_parameters_end_pos != kNoSourcePosition) {
3046     // This is the first function encountered in a CreateDynamicFunction eval.
3047     parameters_end_pos_ = kNoSourcePosition;
3048     // The function name should have been ignored, giving us the empty string
3049     // here.
3050     DCHECK_EQ(function_name, ast_value_factory()->empty_string());
3051   }
3052 
3053   ParserFormalParameters formals(function_scope);
3054 
3055   {
3056     ParameterDeclarationParsingScope formals_scope(this);
3057     if (is_wrapped) {
3058       // For a function implicitly wrapped in function header and footer, the
3059       // function arguments are provided separately to the source, and are
3060       // declared directly here.
3061       for (const AstRawString* arg : *arguments_for_wrapped_function) {
3062         const bool is_rest = false;
3063         Expression* argument = ExpressionFromIdentifier(arg, kNoSourcePosition);
3064         AddFormalParameter(&formals, argument, NullExpression(),
3065                            kNoSourcePosition, is_rest);
3066       }
3067       DCHECK_EQ(arguments_for_wrapped_function->length(),
3068                 formals.num_parameters());
3069       DeclareFormalParameters(&formals);
3070     } else {
3071       // For a regular function, the function arguments are parsed from source.
3072       DCHECK_NULL(arguments_for_wrapped_function);
3073       ParseFormalParameterList(&formals);
3074       if (expected_parameters_end_pos != kNoSourcePosition) {
3075         // Check for '(' or ')' shenanigans in the parameter string for dynamic
3076         // functions.
3077         int position = peek_position();
3078         if (position < expected_parameters_end_pos) {
3079           ReportMessageAt(Scanner::Location(position, position + 1),
3080                           MessageTemplate::kArgStringTerminatesParametersEarly);
3081           return;
3082         } else if (position > expected_parameters_end_pos) {
3083           ReportMessageAt(Scanner::Location(expected_parameters_end_pos - 2,
3084                                             expected_parameters_end_pos),
3085                           MessageTemplate::kUnexpectedEndOfArgString);
3086           return;
3087         }
3088       }
3089       Expect(Token::RPAREN);
3090       int formals_end_position = scanner()->location().end_pos;
3091 
3092       CheckArityRestrictions(formals.arity, kind, formals.has_rest,
3093                              function_scope->start_position(),
3094                              formals_end_position);
3095       Expect(Token::LBRACE);
3096     }
3097     formals.duplicate_loc = formals_scope.duplicate_location();
3098   }
3099 
3100   *num_parameters = formals.num_parameters();
3101   *function_length = formals.function_length;
3102 
3103   AcceptINScope scope(this, true);
3104   ParseFunctionBody(body, function_name, pos, formals, kind,
3105                     function_syntax_kind, FunctionBodyType::kBlock);
3106 
3107   *has_duplicate_parameters = formals.has_duplicate();
3108 
3109   *expected_property_count = function_state.expected_property_count();
3110   *suspend_count = function_state.suspend_count();
3111 }
3112 
DeclareClassVariable(ClassScope * scope,const AstRawString * name,ClassInfo * class_info,int class_token_pos)3113 void Parser::DeclareClassVariable(ClassScope* scope, const AstRawString* name,
3114                                   ClassInfo* class_info, int class_token_pos) {
3115 #ifdef DEBUG
3116   scope->SetScopeName(name);
3117 #endif
3118 
3119   DCHECK_IMPLIES(name == nullptr, class_info->is_anonymous);
3120   // Declare a special class variable for anonymous classes with the dot
3121   // if we need to save it for static private method access.
3122   Variable* class_variable =
3123       scope->DeclareClassVariable(ast_value_factory(), name, class_token_pos);
3124   Declaration* declaration = factory()->NewVariableDeclaration(class_token_pos);
3125   scope->declarations()->Add(declaration);
3126   declaration->set_var(class_variable);
3127 }
3128 
3129 // TODO(gsathya): Ideally, this should just bypass scope analysis and
3130 // allocate a slot directly on the context. We should just store this
3131 // index in the AST, instead of storing the variable.
CreateSyntheticContextVariable(const AstRawString * name)3132 Variable* Parser::CreateSyntheticContextVariable(const AstRawString* name) {
3133   VariableProxy* proxy =
3134       DeclareBoundVariable(name, VariableMode::kConst, kNoSourcePosition);
3135   proxy->var()->ForceContextAllocation();
3136   return proxy->var();
3137 }
3138 
CreatePrivateNameVariable(ClassScope * scope,VariableMode mode,IsStaticFlag is_static_flag,const AstRawString * name)3139 Variable* Parser::CreatePrivateNameVariable(ClassScope* scope,
3140                                             VariableMode mode,
3141                                             IsStaticFlag is_static_flag,
3142                                             const AstRawString* name) {
3143   DCHECK_NOT_NULL(name);
3144   int begin = position();
3145   int end = end_position();
3146   bool was_added = false;
3147   DCHECK(IsConstVariableMode(mode));
3148   Variable* var =
3149       scope->DeclarePrivateName(name, mode, is_static_flag, &was_added);
3150   if (!was_added) {
3151     Scanner::Location loc(begin, end);
3152     ReportMessageAt(loc, MessageTemplate::kVarRedeclaration, var->raw_name());
3153   }
3154   VariableProxy* proxy = factory()->NewVariableProxy(var, begin);
3155   return proxy->var();
3156 }
3157 
DeclarePublicClassField(ClassScope * scope,ClassLiteralProperty * property,bool is_static,bool is_computed_name,ClassInfo * class_info)3158 void Parser::DeclarePublicClassField(ClassScope* scope,
3159                                      ClassLiteralProperty* property,
3160                                      bool is_static, bool is_computed_name,
3161                                      ClassInfo* class_info) {
3162   if (is_static) {
3163     class_info->static_elements->Add(
3164         factory()->NewClassLiteralStaticElement(property), zone());
3165   } else {
3166     class_info->instance_fields->Add(property, zone());
3167   }
3168 
3169   if (is_computed_name) {
3170     // We create a synthetic variable name here so that scope
3171     // analysis doesn't dedupe the vars.
3172     Variable* computed_name_var =
3173         CreateSyntheticContextVariable(ClassFieldVariableName(
3174             ast_value_factory(), class_info->computed_field_count));
3175     property->set_computed_name_var(computed_name_var);
3176     class_info->public_members->Add(property, zone());
3177   }
3178 }
3179 
DeclarePrivateClassMember(ClassScope * scope,const AstRawString * property_name,ClassLiteralProperty * property,ClassLiteralProperty::Kind kind,bool is_static,ClassInfo * class_info)3180 void Parser::DeclarePrivateClassMember(ClassScope* scope,
3181                                        const AstRawString* property_name,
3182                                        ClassLiteralProperty* property,
3183                                        ClassLiteralProperty::Kind kind,
3184                                        bool is_static, ClassInfo* class_info) {
3185   if (kind == ClassLiteralProperty::Kind::FIELD) {
3186     if (is_static) {
3187       class_info->static_elements->Add(
3188           factory()->NewClassLiteralStaticElement(property), zone());
3189     } else {
3190       class_info->instance_fields->Add(property, zone());
3191     }
3192   }
3193 
3194   Variable* private_name_var = CreatePrivateNameVariable(
3195       scope, GetVariableMode(kind),
3196       is_static ? IsStaticFlag::kStatic : IsStaticFlag::kNotStatic,
3197       property_name);
3198   int pos = property->value()->position();
3199   if (pos == kNoSourcePosition) {
3200     pos = property->key()->position();
3201   }
3202   private_name_var->set_initializer_position(pos);
3203   property->set_private_name_var(private_name_var);
3204   class_info->private_members->Add(property, zone());
3205 }
3206 
3207 // This method declares a property of the given class.  It updates the
3208 // following fields of class_info, as appropriate:
3209 //   - constructor
3210 //   - properties
DeclarePublicClassMethod(const AstRawString * class_name,ClassLiteralProperty * property,bool is_constructor,ClassInfo * class_info)3211 void Parser::DeclarePublicClassMethod(const AstRawString* class_name,
3212                                       ClassLiteralProperty* property,
3213                                       bool is_constructor,
3214                                       ClassInfo* class_info) {
3215   if (is_constructor) {
3216     DCHECK(!class_info->constructor);
3217     class_info->constructor = property->value()->AsFunctionLiteral();
3218     DCHECK_NOT_NULL(class_info->constructor);
3219     class_info->constructor->set_raw_name(
3220         class_name != nullptr ? ast_value_factory()->NewConsString(class_name)
3221                               : nullptr);
3222     return;
3223   }
3224 
3225   class_info->public_members->Add(property, zone());
3226 }
3227 
AddClassStaticBlock(Block * block,ClassInfo * class_info)3228 void Parser::AddClassStaticBlock(Block* block, ClassInfo* class_info) {
3229   DCHECK(class_info->has_static_elements);
3230   class_info->static_elements->Add(
3231       factory()->NewClassLiteralStaticElement(block), zone());
3232 }
3233 
CreateInitializerFunction(const char * name,DeclarationScope * scope,Statement * initializer_stmt)3234 FunctionLiteral* Parser::CreateInitializerFunction(
3235     const char* name, DeclarationScope* scope, Statement* initializer_stmt) {
3236   DCHECK(IsClassMembersInitializerFunction(scope->function_kind()));
3237   // function() { .. class fields initializer .. }
3238   ScopedPtrList<Statement> statements(pointer_buffer());
3239   statements.Add(initializer_stmt);
3240   FunctionLiteral* result = factory()->NewFunctionLiteral(
3241       ast_value_factory()->GetOneByteString(name), scope, statements, 0, 0, 0,
3242       FunctionLiteral::kNoDuplicateParameters,
3243       FunctionSyntaxKind::kAccessorOrMethod,
3244       FunctionLiteral::kShouldEagerCompile, scope->start_position(), false,
3245       GetNextFunctionLiteralId());
3246 #ifdef DEBUG
3247   scope->SetScopeName(ast_value_factory()->GetOneByteString(name));
3248 #endif
3249   RecordFunctionLiteralSourceRange(result);
3250 
3251   return result;
3252 }
3253 
3254 // This method generates a ClassLiteral AST node.
3255 // It uses the following fields of class_info:
3256 //   - constructor (if missing, it updates it with a default constructor)
3257 //   - proxy
3258 //   - extends
3259 //   - properties
3260 //   - has_static_computed_names
RewriteClassLiteral(ClassScope * block_scope,const AstRawString * name,ClassInfo * class_info,int pos,int end_pos)3261 Expression* Parser::RewriteClassLiteral(ClassScope* block_scope,
3262                                         const AstRawString* name,
3263                                         ClassInfo* class_info, int pos,
3264                                         int end_pos) {
3265   DCHECK_NOT_NULL(block_scope);
3266   DCHECK_EQ(block_scope->scope_type(), CLASS_SCOPE);
3267   DCHECK_EQ(block_scope->language_mode(), LanguageMode::kStrict);
3268 
3269   bool has_extends = class_info->extends != nullptr;
3270   bool has_default_constructor = class_info->constructor == nullptr;
3271   if (has_default_constructor) {
3272     class_info->constructor =
3273         DefaultConstructor(name, has_extends, pos, end_pos);
3274   }
3275 
3276   if (name != nullptr) {
3277     DCHECK_NOT_NULL(block_scope->class_variable());
3278     block_scope->class_variable()->set_initializer_position(end_pos);
3279   }
3280 
3281   FunctionLiteral* static_initializer = nullptr;
3282   if (class_info->has_static_elements) {
3283     static_initializer = CreateInitializerFunction(
3284         "<static_initializer>", class_info->static_elements_scope,
3285         factory()->NewInitializeClassStaticElementsStatement(
3286             class_info->static_elements, kNoSourcePosition));
3287   }
3288 
3289   FunctionLiteral* instance_members_initializer_function = nullptr;
3290   if (class_info->has_instance_members) {
3291     instance_members_initializer_function = CreateInitializerFunction(
3292         "<instance_members_initializer>", class_info->instance_members_scope,
3293         factory()->NewInitializeClassMembersStatement(
3294             class_info->instance_fields, kNoSourcePosition));
3295     class_info->constructor->set_requires_instance_members_initializer(true);
3296     class_info->constructor->add_expected_properties(
3297         class_info->instance_fields->length());
3298   }
3299 
3300   if (class_info->requires_brand) {
3301     class_info->constructor->set_class_scope_has_private_brand(true);
3302   }
3303   if (class_info->has_static_private_methods) {
3304     class_info->constructor->set_has_static_private_methods_or_accessors(true);
3305   }
3306   ClassLiteral* class_literal = factory()->NewClassLiteral(
3307       block_scope, class_info->extends, class_info->constructor,
3308       class_info->public_members, class_info->private_members,
3309       static_initializer, instance_members_initializer_function, pos, end_pos,
3310       class_info->has_static_computed_names, class_info->is_anonymous,
3311       class_info->has_private_methods, class_info->home_object_variable,
3312       class_info->static_home_object_variable);
3313 
3314   AddFunctionForNameInference(class_info->constructor);
3315   return class_literal;
3316 }
3317 
InsertShadowingVarBindingInitializers(Block * inner_block)3318 void Parser::InsertShadowingVarBindingInitializers(Block* inner_block) {
3319   // For each var-binding that shadows a parameter, insert an assignment
3320   // initializing the variable with the parameter.
3321   Scope* inner_scope = inner_block->scope();
3322   DCHECK(inner_scope->is_declaration_scope());
3323   Scope* function_scope = inner_scope->outer_scope();
3324   DCHECK(function_scope->is_function_scope());
3325   BlockState block_state(&scope_, inner_scope);
3326   for (Declaration* decl : *inner_scope->declarations()) {
3327     if (decl->var()->mode() != VariableMode::kVar ||
3328         !decl->IsVariableDeclaration()) {
3329       continue;
3330     }
3331     const AstRawString* name = decl->var()->raw_name();
3332     Variable* parameter = function_scope->LookupLocal(name);
3333     if (parameter == nullptr) continue;
3334     VariableProxy* to = NewUnresolved(name);
3335     VariableProxy* from = factory()->NewVariableProxy(parameter);
3336     Expression* assignment =
3337         factory()->NewAssignment(Token::ASSIGN, to, from, kNoSourcePosition);
3338     Statement* statement =
3339         factory()->NewExpressionStatement(assignment, kNoSourcePosition);
3340     inner_block->statements()->InsertAt(0, statement, zone());
3341   }
3342 }
3343 
InsertSloppyBlockFunctionVarBindings(DeclarationScope * scope)3344 void Parser::InsertSloppyBlockFunctionVarBindings(DeclarationScope* scope) {
3345   // For the outermost eval scope, we cannot hoist during parsing: let
3346   // declarations in the surrounding scope may prevent hoisting, but the
3347   // information is unaccessible during parsing. In this case, we hoist later in
3348   // DeclarationScope::Analyze.
3349   if (scope->is_eval_scope() && scope->outer_scope() == original_scope_) {
3350     return;
3351   }
3352   scope->HoistSloppyBlockFunctions(factory());
3353 }
3354 
3355 // ----------------------------------------------------------------------------
3356 // Parser support
3357 
3358 template <typename IsolateT>
HandleSourceURLComments(IsolateT * isolate,Handle<Script> script)3359 void Parser::HandleSourceURLComments(IsolateT* isolate, Handle<Script> script) {
3360   Handle<String> source_url = scanner_.SourceUrl(isolate);
3361   if (!source_url.is_null()) {
3362     script->set_source_url(*source_url);
3363   }
3364   Handle<String> source_mapping_url = scanner_.SourceMappingUrl(isolate);
3365   if (!source_mapping_url.is_null()) {
3366     script->set_source_mapping_url(*source_mapping_url);
3367   }
3368 }
3369 
3370 template void Parser::HandleSourceURLComments(Isolate* isolate,
3371                                               Handle<Script> script);
3372 template void Parser::HandleSourceURLComments(LocalIsolate* isolate,
3373                                               Handle<Script> script);
3374 
UpdateStatistics(Isolate * isolate,Handle<Script> script)3375 void Parser::UpdateStatistics(Isolate* isolate, Handle<Script> script) {
3376   CHECK_NOT_NULL(isolate);
3377 
3378   // Move statistics to Isolate.
3379   for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
3380        ++feature) {
3381     if (use_counts_[feature] > 0) {
3382       isolate->CountUsage(v8::Isolate::UseCounterFeature(feature));
3383     }
3384   }
3385   if (scanner_.FoundHtmlComment()) {
3386     isolate->CountUsage(v8::Isolate::kHtmlComment);
3387     if (script->line_offset() == 0 && script->column_offset() == 0) {
3388       isolate->CountUsage(v8::Isolate::kHtmlCommentInExternalScript);
3389     }
3390   }
3391   isolate->counters()->total_preparse_skipped()->Increment(
3392       total_preparse_skipped_);
3393 }
3394 
UpdateStatistics(Handle<Script> script,base::SmallVector<v8::Isolate::UseCounterFeature,8> * use_counts,int * preparse_skipped)3395 void Parser::UpdateStatistics(
3396     Handle<Script> script,
3397     base::SmallVector<v8::Isolate::UseCounterFeature, 8>* use_counts,
3398     int* preparse_skipped) {
3399   // Move statistics to Isolate.
3400   for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
3401        ++feature) {
3402     if (use_counts_[feature] > 0) {
3403       use_counts->emplace_back(v8::Isolate::UseCounterFeature(feature));
3404     }
3405   }
3406   if (scanner_.FoundHtmlComment()) {
3407     use_counts->emplace_back(v8::Isolate::kHtmlComment);
3408     if (script->line_offset() == 0 && script->column_offset() == 0) {
3409       use_counts->emplace_back(v8::Isolate::kHtmlCommentInExternalScript);
3410     }
3411   }
3412   *preparse_skipped = total_preparse_skipped_;
3413 }
3414 
ParseOnBackground(LocalIsolate * isolate,ParseInfo * info,int start_position,int end_position,int function_literal_id)3415 void Parser::ParseOnBackground(LocalIsolate* isolate, ParseInfo* info,
3416                                int start_position, int end_position,
3417                                int function_literal_id) {
3418   RCS_SCOPE(isolate, RuntimeCallCounterId::kParseProgram,
3419             RuntimeCallStats::CounterMode::kThreadSpecific);
3420   parsing_on_main_thread_ = false;
3421 
3422   DCHECK_NULL(info->literal());
3423   FunctionLiteral* result = nullptr;
3424   {
3425     // We can park the isolate while parsing, it doesn't need to allocate or
3426     // access the main thread.
3427     ParkedScope parked_scope(isolate);
3428     overall_parse_is_parked_ = true;
3429 
3430     scanner_.Initialize();
3431 
3432     DCHECK(original_scope_);
3433 
3434     // When streaming, we don't know the length of the source until we have
3435     // parsed it. The raw data can be UTF-8, so we wouldn't know the source
3436     // length until we have decoded it anyway even if we knew the raw data
3437     // length (which we don't). We work around this by storing all the scopes
3438     // which need their end position set at the end of the script (the top scope
3439     // and possible eval scopes) and set their end position after we know the
3440     // script length.
3441     if (flags().is_toplevel()) {
3442       DCHECK_EQ(start_position, 0);
3443       DCHECK_EQ(end_position, 0);
3444       DCHECK_EQ(function_literal_id, kFunctionLiteralIdTopLevel);
3445       result = DoParseProgram(/* isolate = */ nullptr, info);
3446     } else {
3447       base::Optional<ClassScope::HeritageParsingScope> heritage;
3448       if (V8_UNLIKELY(flags().private_name_lookup_skips_outer_class() &&
3449                       original_scope_->is_class_scope())) {
3450         // If the function skips the outer class and the outer scope is a class,
3451         // the function is in heritage position. Otherwise the function scope's
3452         // skip bit will be correctly inherited from the outer scope.
3453         heritage.emplace(original_scope_->AsClassScope());
3454       }
3455       result = DoParseFunction(/* isolate = */ nullptr, info, start_position,
3456                                end_position, function_literal_id,
3457                                info->function_name());
3458     }
3459     MaybeProcessSourceRanges(info, result, stack_limit_);
3460   }
3461   // We need to unpark by now though, to be able to internalize.
3462   PostProcessParseResult(isolate, info, result);
3463   if (flags().is_toplevel()) {
3464     HandleSourceURLComments(isolate, script_);
3465   }
3466 }
3467 
OpenTemplateLiteral(int pos)3468 Parser::TemplateLiteralState Parser::OpenTemplateLiteral(int pos) {
3469   return zone()->New<TemplateLiteral>(zone(), pos);
3470 }
3471 
AddTemplateSpan(TemplateLiteralState * state,bool should_cook,bool tail)3472 void Parser::AddTemplateSpan(TemplateLiteralState* state, bool should_cook,
3473                              bool tail) {
3474   int end = scanner()->location().end_pos - (tail ? 1 : 2);
3475   const AstRawString* raw = scanner()->CurrentRawSymbol(ast_value_factory());
3476   if (should_cook) {
3477     const AstRawString* cooked = scanner()->CurrentSymbol(ast_value_factory());
3478     (*state)->AddTemplateSpan(cooked, raw, end, zone());
3479   } else {
3480     (*state)->AddTemplateSpan(nullptr, raw, end, zone());
3481   }
3482 }
3483 
AddTemplateExpression(TemplateLiteralState * state,Expression * expression)3484 void Parser::AddTemplateExpression(TemplateLiteralState* state,
3485                                    Expression* expression) {
3486   (*state)->AddExpression(expression, zone());
3487 }
3488 
CloseTemplateLiteral(TemplateLiteralState * state,int start,Expression * tag)3489 Expression* Parser::CloseTemplateLiteral(TemplateLiteralState* state, int start,
3490                                          Expression* tag) {
3491   TemplateLiteral* lit = *state;
3492   int pos = lit->position();
3493   const ZonePtrList<const AstRawString>* cooked_strings = lit->cooked();
3494   const ZonePtrList<const AstRawString>* raw_strings = lit->raw();
3495   const ZonePtrList<Expression>* expressions = lit->expressions();
3496   DCHECK_EQ(cooked_strings->length(), raw_strings->length());
3497   DCHECK_EQ(cooked_strings->length(), expressions->length() + 1);
3498 
3499   if (!tag) {
3500     if (cooked_strings->length() == 1) {
3501       return factory()->NewStringLiteral(cooked_strings->first(), pos);
3502     }
3503     return factory()->NewTemplateLiteral(cooked_strings, expressions, pos);
3504   } else {
3505     // GetTemplateObject
3506     Expression* template_object =
3507         factory()->NewGetTemplateObject(cooked_strings, raw_strings, pos);
3508 
3509     // Call TagFn
3510     ScopedPtrList<Expression> call_args(pointer_buffer());
3511     call_args.Add(template_object);
3512     call_args.AddAll(expressions->ToConstVector());
3513     return factory()->NewTaggedTemplate(tag, call_args, pos);
3514   }
3515 }
3516 
ArrayLiteralFromListWithSpread(const ScopedPtrList<Expression> & list)3517 ArrayLiteral* Parser::ArrayLiteralFromListWithSpread(
3518     const ScopedPtrList<Expression>& list) {
3519   // If there's only a single spread argument, a fast path using CallWithSpread
3520   // is taken.
3521   DCHECK_LT(1, list.length());
3522 
3523   // The arguments of the spread call become a single ArrayLiteral.
3524   int first_spread = 0;
3525   for (; first_spread < list.length() && !list.at(first_spread)->IsSpread();
3526        ++first_spread) {
3527   }
3528 
3529   DCHECK_LT(first_spread, list.length());
3530   return factory()->NewArrayLiteral(list, first_spread, kNoSourcePosition);
3531 }
3532 
SetLanguageMode(Scope * scope,LanguageMode mode)3533 void Parser::SetLanguageMode(Scope* scope, LanguageMode mode) {
3534   v8::Isolate::UseCounterFeature feature;
3535   if (is_sloppy(mode))
3536     feature = v8::Isolate::kSloppyMode;
3537   else if (is_strict(mode))
3538     feature = v8::Isolate::kStrictMode;
3539   else
3540     UNREACHABLE();
3541   ++use_counts_[feature];
3542   scope->SetLanguageMode(mode);
3543 }
3544 
3545 #if V8_ENABLE_WEBASSEMBLY
SetAsmModule()3546 void Parser::SetAsmModule() {
3547   // Store the usage count; The actual use counter on the isolate is
3548   // incremented after parsing is done.
3549   ++use_counts_[v8::Isolate::kUseAsm];
3550   DCHECK(scope()->is_declaration_scope());
3551   scope()->AsDeclarationScope()->set_is_asm_module();
3552   info_->set_contains_asm_module(true);
3553 }
3554 #endif  // V8_ENABLE_WEBASSEMBLY
3555 
ExpressionListToExpression(const ScopedPtrList<Expression> & args)3556 Expression* Parser::ExpressionListToExpression(
3557     const ScopedPtrList<Expression>& args) {
3558   Expression* expr = args.at(0);
3559   if (args.length() == 1) return expr;
3560   if (args.length() == 2) {
3561     return factory()->NewBinaryOperation(Token::COMMA, expr, args.at(1),
3562                                          args.at(1)->position());
3563   }
3564   NaryOperation* result =
3565       factory()->NewNaryOperation(Token::COMMA, expr, args.length() - 1);
3566   for (int i = 1; i < args.length(); i++) {
3567     result->AddSubsequent(args.at(i), args.at(i)->position());
3568   }
3569   return result;
3570 }
3571 
3572 // This method completes the desugaring of the body of async_function.
RewriteAsyncFunctionBody(ScopedPtrList<Statement> * body,Block * block,Expression * return_value,REPLMode repl_mode)3573 void Parser::RewriteAsyncFunctionBody(ScopedPtrList<Statement>* body,
3574                                       Block* block, Expression* return_value,
3575                                       REPLMode repl_mode) {
3576   // function async_function() {
3577   //   .generator_object = %_AsyncFunctionEnter();
3578   //   BuildRejectPromiseOnException({
3579   //     ... block ...
3580   //     return %_AsyncFunctionResolve(.generator_object, expr);
3581   //   })
3582   // }
3583 
3584   block->statements()->Add(factory()->NewSyntheticAsyncReturnStatement(
3585                                return_value, return_value->position()),
3586                            zone());
3587   block = BuildRejectPromiseOnException(block, repl_mode);
3588   body->Add(block);
3589 }
3590 
SetFunctionNameFromPropertyName(LiteralProperty * property,const AstRawString * name,const AstRawString * prefix)3591 void Parser::SetFunctionNameFromPropertyName(LiteralProperty* property,
3592                                              const AstRawString* name,
3593                                              const AstRawString* prefix) {
3594   if (has_error()) return;
3595   // Ensure that the function we are going to create has shared name iff
3596   // we are not going to set it later.
3597   if (property->NeedsSetFunctionName()) {
3598     name = nullptr;
3599     prefix = nullptr;
3600   } else {
3601     // If the property value is an anonymous function or an anonymous class or
3602     // a concise method or an accessor function which doesn't require the name
3603     // to be set then the shared name must be provided.
3604     DCHECK_IMPLIES(property->value()->IsAnonymousFunctionDefinition() ||
3605                        property->value()->IsConciseMethodDefinition() ||
3606                        property->value()->IsAccessorFunctionDefinition(),
3607                    name != nullptr);
3608   }
3609 
3610   Expression* value = property->value();
3611   SetFunctionName(value, name, prefix);
3612 }
3613 
SetFunctionNameFromPropertyName(ObjectLiteralProperty * property,const AstRawString * name,const AstRawString * prefix)3614 void Parser::SetFunctionNameFromPropertyName(ObjectLiteralProperty* property,
3615                                              const AstRawString* name,
3616                                              const AstRawString* prefix) {
3617   // Ignore "__proto__" as a name when it's being used to set the [[Prototype]]
3618   // of an object literal.
3619   // See ES #sec-__proto__-property-names-in-object-initializers.
3620   if (property->IsPrototype() || has_error()) return;
3621 
3622   DCHECK(!property->value()->IsAnonymousFunctionDefinition() ||
3623          property->kind() == ObjectLiteralProperty::COMPUTED);
3624 
3625   SetFunctionNameFromPropertyName(static_cast<LiteralProperty*>(property), name,
3626                                   prefix);
3627 }
3628 
SetFunctionNameFromIdentifierRef(Expression * value,Expression * identifier)3629 void Parser::SetFunctionNameFromIdentifierRef(Expression* value,
3630                                               Expression* identifier) {
3631   if (!identifier->IsVariableProxy()) return;
3632   // IsIdentifierRef of parenthesized expressions is false.
3633   if (identifier->is_parenthesized()) return;
3634   SetFunctionName(value, identifier->AsVariableProxy()->raw_name());
3635 }
3636 
SetFunctionName(Expression * value,const AstRawString * name,const AstRawString * prefix)3637 void Parser::SetFunctionName(Expression* value, const AstRawString* name,
3638                              const AstRawString* prefix) {
3639   if (!value->IsAnonymousFunctionDefinition() &&
3640       !value->IsConciseMethodDefinition() &&
3641       !value->IsAccessorFunctionDefinition()) {
3642     return;
3643   }
3644   auto function = value->AsFunctionLiteral();
3645   if (value->IsClassLiteral()) {
3646     function = value->AsClassLiteral()->constructor();
3647   }
3648   if (function != nullptr) {
3649     AstConsString* cons_name = nullptr;
3650     if (name != nullptr) {
3651       if (prefix != nullptr) {
3652         cons_name = ast_value_factory()->NewConsString(prefix, name);
3653       } else {
3654         cons_name = ast_value_factory()->NewConsString(name);
3655       }
3656     } else {
3657       DCHECK_NULL(prefix);
3658     }
3659     function->set_raw_name(cons_name);
3660   }
3661 }
3662 
CheckCallable(Variable * var,Expression * error,int pos)3663 Statement* Parser::CheckCallable(Variable* var, Expression* error, int pos) {
3664   const int nopos = kNoSourcePosition;
3665   Statement* validate_var;
3666   {
3667     Expression* type_of = factory()->NewUnaryOperation(
3668         Token::TYPEOF, factory()->NewVariableProxy(var), nopos);
3669     Expression* function_literal = factory()->NewStringLiteral(
3670         ast_value_factory()->function_string(), nopos);
3671     Expression* condition = factory()->NewCompareOperation(
3672         Token::EQ_STRICT, type_of, function_literal, nopos);
3673 
3674     Statement* throw_call = factory()->NewExpressionStatement(error, pos);
3675 
3676     validate_var = factory()->NewIfStatement(
3677         condition, factory()->EmptyStatement(), throw_call, nopos);
3678   }
3679   return validate_var;
3680 }
3681 
3682 }  // namespace internal
3683 }  // namespace v8
3684