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