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