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