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