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 36namespace v8 { 37namespace internal { 38 39FunctionLiteral* 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 91void 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 154bool 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 216bool 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 250const 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 260Expression* 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 286Expression* 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 296Expression* 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 310Expression* 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 319Expression* 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 325Expression* Parser::ImportMetaExpression(int pos) { 326 ScopedPtrList<Expression> args(pointer_buffer()); 327 return factory()->NewCallRuntime(Runtime::kInlineGetImportMetaObject, args, 328 pos); 329} 330 331Expression* 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 359Expression* 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. 409Expression* 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 436Parser::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 481void 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 490template <typename IsolateT> 491void 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 509template void Parser::DeserializeScopeChain( 510 Isolate* isolate, ParseInfo* info, 511 MaybeHandle<ScopeInfo> maybe_outer_scope_info, 512 Scope::DeserializationMode mode); 513template void Parser::DeserializeScopeChain( 514 LocalIsolate* isolate, ParseInfo* info, 515 MaybeHandle<ScopeInfo> maybe_outer_scope_info, 516 Scope::DeserializationMode mode); 517 518namespace { 519 520void 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 531void 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 577FunctionLiteral* 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 700template <typename IsolateT> 701void 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 724template void Parser::PostProcessParseResult(Isolate* isolate, ParseInfo* info, 725 FunctionLiteral* literal); 726template void Parser::PostProcessParseResult(LocalIsolate* isolate, 727 ParseInfo* info, 728 FunctionLiteral* literal); 729 730ZonePtrList<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 747void 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 775void 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 809Expression* 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 831void 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 939FunctionLiteral* 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 1078FunctionLiteral* 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 1093FunctionLiteral* 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 1153Statement* 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 1179void 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 1197const AstRawString* Parser::ParseModuleSpecifier() { 1198 // ModuleSpecifier : 1199 // StringLiteral 1200 1201 Expect(Token::STRING); 1202 return GetSymbol(); 1203} 1204 1205ZoneChunkList<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 1268const 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 1293ZonePtrList<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 1346ImportAssertions* 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 1416void 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 1527Statement* 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 1593const 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 1600void 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 1648Statement* 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 1773void 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 1783VariableProxy* 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 1796void 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 1806Variable* 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 1821void 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 1848Statement* 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 1859Statement* 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 1885Statement* 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 1900Statement* 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 1918Block* Parser::IgnoreCompletion(Statement* statement) { 1919 Block* block = factory()->NewBlock(1, true); 1920 block->statements()->Add(statement, zone()); 1921 return block; 1922} 1923 1924Expression* 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 1956Statement* 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 1994void 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 2010Block* 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 2021void 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 2036Statement* 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 2073void 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 2082void 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 2170void 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. 2196Block* 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// } 2230void 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. 2250Block* 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 2269Statement* 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 2506void ParserFormalParameters::ValidateDuplicate(Parser* parser) const { 2507 if (has_duplicate()) { 2508 parser->ReportMessageAt(duplicate_loc, MessageTemplate::kParamDupe); 2509 } 2510} 2511void ParserFormalParameters::ValidateStrictMode(Parser* parser) const { 2512 if (strict_error_loc.IsValid()) { 2513 parser->ReportMessageAt(strict_error_loc, strict_error_message); 2514 } 2515} 2516 2517void 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 2589void 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 2606void 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 2614FunctionLiteral* 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 2827bool 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 2937Block* 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 2969Scope* 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 2979Block* 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 3019Expression* 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 3030void 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 3113void 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. 3132Variable* Parser::CreateSyntheticContextVariable(const AstRawString* name) { 3133 VariableProxy* proxy = 3134 DeclareBoundVariable(name, VariableMode::kConst, kNoSourcePosition); 3135 proxy->var()->ForceContextAllocation(); 3136 return proxy->var(); 3137} 3138 3139Variable* 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 3158void 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 3180void 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 3211void 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 3228void 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 3234FunctionLiteral* 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 3261Expression* 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 3318void 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 3344void 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 3358template <typename IsolateT> 3359void 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 3370template void Parser::HandleSourceURLComments(Isolate* isolate, 3371 Handle<Script> script); 3372template void Parser::HandleSourceURLComments(LocalIsolate* isolate, 3373 Handle<Script> script); 3374 3375void 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 3395void 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 3415void 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 3468Parser::TemplateLiteralState Parser::OpenTemplateLiteral(int pos) { 3469 return zone()->New<TemplateLiteral>(zone(), pos); 3470} 3471 3472void 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 3484void Parser::AddTemplateExpression(TemplateLiteralState* state, 3485 Expression* expression) { 3486 (*state)->AddExpression(expression, zone()); 3487} 3488 3489Expression* 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 3517ArrayLiteral* 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 3533void 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 3546void 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 3556Expression* 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. 3573void 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 3591void 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 3614void 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 3629void 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 3637void 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 3663Statement* 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