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/bailout-reason.h" 14 #include "src/base/platform/platform.h" 15 #include "src/char-predicates-inl.h" 16 #include "src/compiler-dispatcher/compiler-dispatcher.h" 17 #include "src/conversions-inl.h" 18 #include "src/log.h" 19 #include "src/messages.h" 20 #include "src/objects/scope-info.h" 21 #include "src/parsing/duplicate-finder.h" 22 #include "src/parsing/expression-scope-reparenter.h" 23 #include "src/parsing/parse-info.h" 24 #include "src/parsing/rewriter.h" 25 #include "src/runtime/runtime.h" 26 #include "src/string-stream.h" 27 #include "src/tracing/trace-event.h" 28 29 namespace v8 { 30 namespace internal { 31 32 33 34 // Helper for putting parts of the parse results into a temporary zone when 35 // parsing inner function bodies. 36 class DiscardableZoneScope { 37 public: 38 DiscardableZoneScope(Parser* parser, Zone* temp_zone, bool use_temp_zone) 39 : fni_(parser->ast_value_factory_, temp_zone), 40 parser_(parser), 41 prev_fni_(parser->fni_), 42 prev_zone_(parser->zone_), 43 prev_allow_lazy_(parser->allow_lazy_), 44 prev_temp_zoned_(parser->temp_zoned_) { 45 if (use_temp_zone) { 46 DCHECK(!parser_->temp_zoned_); 47 parser_->allow_lazy_ = false; 48 parser_->temp_zoned_ = true; 49 parser_->fni_ = &fni_; 50 parser_->zone_ = temp_zone; 51 parser_->factory()->set_zone(temp_zone); 52 if (parser_->reusable_preparser_ != nullptr) { 53 parser_->reusable_preparser_->zone_ = temp_zone; 54 parser_->reusable_preparser_->factory()->set_zone(temp_zone); 55 } 56 } 57 } 58 void Reset() { 59 parser_->fni_ = prev_fni_; 60 parser_->zone_ = prev_zone_; 61 parser_->factory()->set_zone(prev_zone_); 62 parser_->allow_lazy_ = prev_allow_lazy_; 63 parser_->temp_zoned_ = prev_temp_zoned_; 64 if (parser_->reusable_preparser_ != nullptr) { 65 parser_->reusable_preparser_->zone_ = prev_zone_; 66 parser_->reusable_preparser_->factory()->set_zone(prev_zone_); 67 } 68 } 69 ~DiscardableZoneScope() { Reset(); } 70 71 private: 72 FuncNameInferrer fni_; 73 Parser* parser_; 74 FuncNameInferrer* prev_fni_; 75 Zone* prev_zone_; 76 bool prev_allow_lazy_; 77 bool prev_temp_zoned_; 78 79 DISALLOW_COPY_AND_ASSIGN(DiscardableZoneScope); 80 }; 81 82 FunctionLiteral* Parser::DefaultConstructor(const AstRawString* name, 83 bool call_super, int pos, 84 int end_pos) { 85 int expected_property_count = -1; 86 const int parameter_count = 0; 87 88 FunctionKind kind = call_super ? FunctionKind::kDefaultDerivedConstructor 89 : FunctionKind::kDefaultBaseConstructor; 90 DeclarationScope* function_scope = NewFunctionScope(kind); 91 SetLanguageMode(function_scope, LanguageMode::kStrict); 92 // Set start and end position to the same value 93 function_scope->set_start_position(pos); 94 function_scope->set_end_position(pos); 95 ZonePtrList<Statement>* body = nullptr; 96 97 { 98 FunctionState function_state(&function_state_, &scope_, function_scope); 99 100 body = new (zone()) ZonePtrList<Statement>(call_super ? 2 : 1, zone()); 101 if (call_super) { 102 // Create a SuperCallReference and handle in BytecodeGenerator. 103 auto constructor_args_name = ast_value_factory()->empty_string(); 104 bool is_duplicate; 105 bool is_rest = true; 106 bool is_optional = false; 107 Variable* constructor_args = function_scope->DeclareParameter( 108 constructor_args_name, VariableMode::kTemporary, is_optional, is_rest, 109 &is_duplicate, ast_value_factory(), pos); 110 111 ZonePtrList<Expression>* args = 112 new (zone()) ZonePtrList<Expression>(1, zone()); 113 Spread* spread_args = factory()->NewSpread( 114 factory()->NewVariableProxy(constructor_args), pos, pos); 115 116 args->Add(spread_args, zone()); 117 Expression* super_call_ref = NewSuperCallReference(pos); 118 Expression* call = factory()->NewCall(super_call_ref, args, pos); 119 body->Add(factory()->NewReturnStatement(call, pos), zone()); 120 } 121 122 expected_property_count = function_state.expected_property_count(); 123 } 124 125 FunctionLiteral* function_literal = factory()->NewFunctionLiteral( 126 name, function_scope, body, expected_property_count, parameter_count, 127 parameter_count, FunctionLiteral::kNoDuplicateParameters, 128 FunctionLiteral::kAnonymousExpression, default_eager_compile_hint(), pos, 129 true, GetNextFunctionLiteralId()); 130 return function_literal; 131 } 132 133 // ---------------------------------------------------------------------------- 134 // The CHECK_OK macro is a convenient macro to enforce error 135 // handling for functions that may fail (by returning !*ok). 136 // 137 // CAUTION: This macro appends extra statements after a call, 138 // thus it must never be used where only a single statement 139 // is correct (e.g. an if statement branch w/o braces)! 140 141 #define CHECK_OK_VALUE(x) ok); \ 142 if (!*ok) return x; \ 143 ((void)0 144 #define DUMMY ) // to make indentation work 145 #undef DUMMY 146 147 #define CHECK_OK CHECK_OK_VALUE(nullptr) 148 #define CHECK_OK_VOID CHECK_OK_VALUE(this->Void()) 149 150 #define CHECK_FAILED /**/); \ 151 if (failed_) return nullptr; \ 152 ((void)0 153 #define DUMMY ) // to make indentation work 154 #undef DUMMY 155 156 // ---------------------------------------------------------------------------- 157 // Implementation of Parser 158 159 bool Parser::ShortcutNumericLiteralBinaryExpression(Expression** x, 160 Expression* y, 161 Token::Value op, int pos) { 162 if ((*x)->IsNumberLiteral() && y->IsNumberLiteral()) { 163 double x_val = (*x)->AsLiteral()->AsNumber(); 164 double y_val = y->AsLiteral()->AsNumber(); 165 switch (op) { 166 case Token::ADD: 167 *x = factory()->NewNumberLiteral(x_val + y_val, pos); 168 return true; 169 case Token::SUB: 170 *x = factory()->NewNumberLiteral(x_val - y_val, pos); 171 return true; 172 case Token::MUL: 173 *x = factory()->NewNumberLiteral(x_val * y_val, pos); 174 return true; 175 case Token::DIV: 176 *x = factory()->NewNumberLiteral(x_val / y_val, pos); 177 return true; 178 case Token::BIT_OR: { 179 int value = DoubleToInt32(x_val) | DoubleToInt32(y_val); 180 *x = factory()->NewNumberLiteral(value, pos); 181 return true; 182 } 183 case Token::BIT_AND: { 184 int value = DoubleToInt32(x_val) & DoubleToInt32(y_val); 185 *x = factory()->NewNumberLiteral(value, pos); 186 return true; 187 } 188 case Token::BIT_XOR: { 189 int value = DoubleToInt32(x_val) ^ DoubleToInt32(y_val); 190 *x = factory()->NewNumberLiteral(value, pos); 191 return true; 192 } 193 case Token::SHL: { 194 int value = DoubleToInt32(x_val) << (DoubleToInt32(y_val) & 0x1F); 195 *x = factory()->NewNumberLiteral(value, pos); 196 return true; 197 } 198 case Token::SHR: { 199 uint32_t shift = DoubleToInt32(y_val) & 0x1F; 200 uint32_t value = DoubleToUint32(x_val) >> shift; 201 *x = factory()->NewNumberLiteral(value, pos); 202 return true; 203 } 204 case Token::SAR: { 205 uint32_t shift = DoubleToInt32(y_val) & 0x1F; 206 int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift); 207 *x = factory()->NewNumberLiteral(value, pos); 208 return true; 209 } 210 case Token::EXP: { 211 double value = Pow(x_val, y_val); 212 int int_value = static_cast<int>(value); 213 *x = factory()->NewNumberLiteral( 214 int_value == value && value != -0.0 ? int_value : value, pos); 215 return true; 216 } 217 default: 218 break; 219 } 220 } 221 return false; 222 } 223 224 bool Parser::CollapseNaryExpression(Expression** x, Expression* y, 225 Token::Value op, int pos, 226 const SourceRange& range) { 227 // Filter out unsupported ops. 228 if (!Token::IsBinaryOp(op) || op == Token::EXP) return false; 229 230 // Convert *x into an nary operation with the given op, returning false if 231 // this is not possible. 232 NaryOperation* nary = nullptr; 233 if ((*x)->IsBinaryOperation()) { 234 BinaryOperation* binop = (*x)->AsBinaryOperation(); 235 if (binop->op() != op) return false; 236 237 nary = factory()->NewNaryOperation(op, binop->left(), 2); 238 nary->AddSubsequent(binop->right(), binop->position()); 239 ConvertBinaryToNaryOperationSourceRange(binop, nary); 240 *x = nary; 241 } else if ((*x)->IsNaryOperation()) { 242 nary = (*x)->AsNaryOperation(); 243 if (nary->op() != op) return false; 244 } else { 245 return false; 246 } 247 248 // Append our current expression to the nary operation. 249 // TODO(leszeks): Do some literal collapsing here if we're appending Smi or 250 // String literals. 251 nary->AddSubsequent(y, pos); 252 AppendNaryOperationSourceRange(nary, range); 253 254 return true; 255 } 256 257 Expression* Parser::BuildUnaryExpression(Expression* expression, 258 Token::Value op, int pos) { 259 DCHECK_NOT_NULL(expression); 260 const Literal* literal = expression->AsLiteral(); 261 if (literal != nullptr) { 262 if (op == Token::NOT) { 263 // Convert the literal to a boolean condition and negate it. 264 return factory()->NewBooleanLiteral(literal->ToBooleanIsFalse(), pos); 265 } else if (literal->IsNumberLiteral()) { 266 // Compute some expressions involving only number literals. 267 double value = literal->AsNumber(); 268 switch (op) { 269 case Token::ADD: 270 return expression; 271 case Token::SUB: 272 return factory()->NewNumberLiteral(-value, pos); 273 case Token::BIT_NOT: 274 return factory()->NewNumberLiteral(~DoubleToInt32(value), pos); 275 default: 276 break; 277 } 278 } 279 } 280 return factory()->NewUnaryOperation(op, expression, pos); 281 } 282 283 Expression* Parser::NewThrowError(Runtime::FunctionId id, 284 MessageTemplate::Template message, 285 const AstRawString* arg, int pos) { 286 ZonePtrList<Expression>* args = 287 new (zone()) ZonePtrList<Expression>(2, zone()); 288 args->Add(factory()->NewSmiLiteral(message, pos), zone()); 289 args->Add(factory()->NewStringLiteral(arg, pos), zone()); 290 CallRuntime* call_constructor = factory()->NewCallRuntime(id, args, pos); 291 return factory()->NewThrow(call_constructor, pos); 292 } 293 294 Expression* Parser::NewSuperPropertyReference(int pos) { 295 // this_function[home_object_symbol] 296 VariableProxy* this_function_proxy = 297 NewUnresolved(ast_value_factory()->this_function_string(), pos); 298 Expression* home_object_symbol_literal = factory()->NewSymbolLiteral( 299 AstSymbol::kHomeObjectSymbol, kNoSourcePosition); 300 Expression* home_object = factory()->NewProperty( 301 this_function_proxy, home_object_symbol_literal, pos); 302 return factory()->NewSuperPropertyReference( 303 ThisExpression(pos)->AsVariableProxy(), home_object, pos); 304 } 305 306 Expression* Parser::NewSuperCallReference(int pos) { 307 VariableProxy* new_target_proxy = 308 NewUnresolved(ast_value_factory()->new_target_string(), pos); 309 VariableProxy* this_function_proxy = 310 NewUnresolved(ast_value_factory()->this_function_string(), pos); 311 return factory()->NewSuperCallReference( 312 ThisExpression(pos)->AsVariableProxy(), new_target_proxy, 313 this_function_proxy, pos); 314 } 315 316 Expression* Parser::NewTargetExpression(int pos) { 317 auto proxy = NewUnresolved(ast_value_factory()->new_target_string(), pos); 318 proxy->set_is_new_target(); 319 return proxy; 320 } 321 322 Expression* Parser::ImportMetaExpression(int pos) { 323 return factory()->NewCallRuntime( 324 Runtime::kInlineGetImportMetaObject, 325 new (zone()) ZonePtrList<Expression>(0, zone()), pos); 326 } 327 328 Literal* Parser::ExpressionFromLiteral(Token::Value token, int pos) { 329 switch (token) { 330 case Token::NULL_LITERAL: 331 return factory()->NewNullLiteral(pos); 332 case Token::TRUE_LITERAL: 333 return factory()->NewBooleanLiteral(true, pos); 334 case Token::FALSE_LITERAL: 335 return factory()->NewBooleanLiteral(false, pos); 336 case Token::SMI: { 337 uint32_t value = scanner()->smi_value(); 338 return factory()->NewSmiLiteral(value, pos); 339 } 340 case Token::NUMBER: { 341 double value = scanner()->DoubleValue(); 342 return factory()->NewNumberLiteral(value, pos); 343 } 344 case Token::BIGINT: 345 return factory()->NewBigIntLiteral( 346 AstBigInt(scanner()->CurrentLiteralAsCString(zone())), pos); 347 default: 348 DCHECK(false); 349 } 350 return nullptr; 351 } 352 353 Expression* Parser::NewV8Intrinsic(const AstRawString* name, 354 ZonePtrList<Expression>* args, int pos, 355 bool* ok) { 356 if (extension_ != nullptr) { 357 // The extension structures are only accessible while parsing the 358 // very first time, not when reparsing because of lazy compilation. 359 GetClosureScope()->ForceEagerCompilation(); 360 } 361 362 DCHECK(name->is_one_byte()); 363 const Runtime::Function* function = 364 Runtime::FunctionForName(name->raw_data(), name->length()); 365 366 if (function != nullptr) { 367 // Check for possible name clash. 368 DCHECK_EQ(Context::kNotFound, 369 Context::IntrinsicIndexForName(name->raw_data(), name->length())); 370 // Check for built-in IS_VAR macro. 371 if (function->function_id == Runtime::kIS_VAR) { 372 DCHECK_EQ(Runtime::RUNTIME, function->intrinsic_type); 373 // %IS_VAR(x) evaluates to x if x is a variable, 374 // leads to a parse error otherwise. Could be implemented as an 375 // inline function %_IS_VAR(x) to eliminate this special case. 376 if (args->length() == 1 && args->at(0)->AsVariableProxy() != nullptr) { 377 return args->at(0); 378 } else { 379 ReportMessage(MessageTemplate::kNotIsvar); 380 *ok = false; 381 return nullptr; 382 } 383 } 384 385 // Check that the expected number of arguments are being passed. 386 if (function->nargs != -1 && function->nargs != args->length()) { 387 ReportMessage(MessageTemplate::kRuntimeWrongNumArgs); 388 *ok = false; 389 return nullptr; 390 } 391 392 return factory()->NewCallRuntime(function, args, pos); 393 } 394 395 int context_index = 396 Context::IntrinsicIndexForName(name->raw_data(), name->length()); 397 398 // Check that the function is defined. 399 if (context_index == Context::kNotFound) { 400 ReportMessage(MessageTemplate::kNotDefined, name); 401 *ok = false; 402 return nullptr; 403 } 404 405 return factory()->NewCallRuntime(context_index, args, pos); 406 } 407 408 Parser::Parser(ParseInfo* info) 409 : ParserBase<Parser>(info->zone(), &scanner_, info->stack_limit(), 410 info->extension(), info->GetOrCreateAstValueFactory(), 411 info->pending_error_handler(), 412 info->runtime_call_stats(), info->logger(), 413 info->script().is_null() ? -1 : info->script()->id(), 414 info->is_module(), true), 415 scanner_(info->unicode_cache(), info->character_stream(), 416 info->is_module()), 417 reusable_preparser_(nullptr), 418 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly. 419 source_range_map_(info->source_range_map()), 420 target_stack_(nullptr), 421 total_preparse_skipped_(0), 422 temp_zoned_(false), 423 consumed_preparsed_scope_data_(info->consumed_preparsed_scope_data()), 424 parameters_end_pos_(info->parameters_end_pos()) { 425 // Even though we were passed ParseInfo, we should not store it in 426 // Parser - this makes sure that Isolate is not accidentally accessed via 427 // ParseInfo during background parsing. 428 DCHECK_NOT_NULL(info->character_stream()); 429 // Determine if functions can be lazily compiled. This is necessary to 430 // allow some of our builtin JS files to be lazily compiled. These 431 // builtins cannot be handled lazily by the parser, since we have to know 432 // if a function uses the special natives syntax, which is something the 433 // parser records. 434 // If the debugger requests compilation for break points, we cannot be 435 // aggressive about lazy compilation, because it might trigger compilation 436 // of functions without an outer context when setting a breakpoint through 437 // Debug::FindSharedFunctionInfoInScript 438 // We also compile eagerly for kProduceExhaustiveCodeCache. 439 bool can_compile_lazily = FLAG_lazy && !info->is_eager(); 440 441 set_default_eager_compile_hint(can_compile_lazily 442 ? FunctionLiteral::kShouldLazyCompile 443 : FunctionLiteral::kShouldEagerCompile); 444 allow_lazy_ = FLAG_lazy && info->allow_lazy_parsing() && !info->is_native() && 445 info->extension() == nullptr && can_compile_lazily; 446 set_allow_natives(FLAG_allow_natives_syntax || info->is_native()); 447 set_allow_harmony_do_expressions(FLAG_harmony_do_expressions); 448 set_allow_harmony_public_fields(FLAG_harmony_public_fields); 449 set_allow_harmony_static_fields(FLAG_harmony_static_fields); 450 set_allow_harmony_dynamic_import(FLAG_harmony_dynamic_import); 451 set_allow_harmony_import_meta(FLAG_harmony_import_meta); 452 set_allow_harmony_bigint(FLAG_harmony_bigint); 453 set_allow_harmony_numeric_separator(FLAG_harmony_numeric_separator); 454 set_allow_harmony_private_fields(FLAG_harmony_private_fields); 455 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; 456 ++feature) { 457 use_counts_[feature] = 0; 458 } 459 } 460 461 void Parser::DeserializeScopeChain( 462 Isolate* isolate, ParseInfo* info, 463 MaybeHandle<ScopeInfo> maybe_outer_scope_info) { 464 // TODO(wingo): Add an outer SCRIPT_SCOPE corresponding to the native 465 // context, which will have the "this" binding for script scopes. 466 DeclarationScope* script_scope = NewScriptScope(); 467 info->set_script_scope(script_scope); 468 Scope* scope = script_scope; 469 Handle<ScopeInfo> outer_scope_info; 470 if (maybe_outer_scope_info.ToHandle(&outer_scope_info)) { 471 DCHECK(ThreadId::Current().Equals(isolate->thread_id())); 472 scope = Scope::DeserializeScopeChain( 473 isolate, zone(), *outer_scope_info, script_scope, ast_value_factory(), 474 Scope::DeserializationMode::kScopesOnly); 475 } 476 original_scope_ = scope; 477 } 478 479 namespace { 480 481 void MaybeResetCharacterStream(ParseInfo* info, FunctionLiteral* literal) { 482 // Don't reset the character stream if there is an asm.js module since it will 483 // be used again by the asm-parser. 484 if (!FLAG_stress_validate_asm && 485 (literal == nullptr || !literal->scope()->ContainsAsmModule())) { 486 info->ResetCharacterStream(); 487 } 488 } 489 490 } // namespace 491 492 FunctionLiteral* Parser::ParseProgram(Isolate* isolate, ParseInfo* info) { 493 // TODO(bmeurer): We temporarily need to pass allow_nesting = true here, 494 // see comment for HistogramTimerScope class. 495 496 // It's OK to use the Isolate & counters here, since this function is only 497 // called in the main thread. 498 DCHECK(parsing_on_main_thread_); 499 RuntimeCallTimerScope runtime_timer( 500 runtime_call_stats_, info->is_eval() 501 ? RuntimeCallCounterId::kParseEval 502 : RuntimeCallCounterId::kParseProgram); 503 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.ParseProgram"); 504 base::ElapsedTimer timer; 505 if (V8_UNLIKELY(FLAG_log_function_events)) timer.Start(); 506 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone()); 507 508 // Initialize parser state. 509 DeserializeScopeChain(isolate, info, info->maybe_outer_scope_info()); 510 511 scanner_.Initialize(); 512 FunctionLiteral* result = DoParseProgram(isolate, info); 513 MaybeResetCharacterStream(info, result); 514 515 HandleSourceURLComments(isolate, info->script()); 516 517 if (V8_UNLIKELY(FLAG_log_function_events) && result != nullptr) { 518 double ms = timer.Elapsed().InMillisecondsF(); 519 const char* event_name = "parse-eval"; 520 Script* script = *info->script(); 521 int start = -1; 522 int end = -1; 523 if (!info->is_eval()) { 524 event_name = "parse-script"; 525 start = 0; 526 end = String::cast(script->source())->length(); 527 } 528 LOG(isolate, 529 FunctionEvent(event_name, script->id(), ms, start, end, "", 0)); 530 } 531 return result; 532 } 533 534 FunctionLiteral* Parser::DoParseProgram(Isolate* isolate, ParseInfo* info) { 535 // Note that this function can be called from the main thread or from a 536 // background thread. We should not access anything Isolate / heap dependent 537 // via ParseInfo, and also not pass it forward. If not on the main thread 538 // isolate will be nullptr. 539 DCHECK_EQ(parsing_on_main_thread_, isolate != nullptr); 540 DCHECK_NULL(scope_); 541 DCHECK_NULL(target_stack_); 542 543 ParsingModeScope mode(this, allow_lazy_ ? PARSE_LAZILY : PARSE_EAGERLY); 544 ResetFunctionLiteralId(); 545 DCHECK(info->function_literal_id() == FunctionLiteral::kIdTypeTopLevel || 546 info->function_literal_id() == FunctionLiteral::kIdTypeInvalid); 547 548 FunctionLiteral* result = nullptr; 549 { 550 Scope* outer = original_scope_; 551 DCHECK_NOT_NULL(outer); 552 if (info->is_eval()) { 553 outer = NewEvalScope(outer); 554 } else if (parsing_module_) { 555 DCHECK_EQ(outer, info->script_scope()); 556 outer = NewModuleScope(info->script_scope()); 557 } 558 559 DeclarationScope* scope = outer->AsDeclarationScope(); 560 scope->set_start_position(0); 561 562 FunctionState function_state(&function_state_, &scope_, scope); 563 ZonePtrList<Statement>* body = 564 new (zone()) ZonePtrList<Statement>(16, zone()); 565 bool ok = true; 566 int beg_pos = scanner()->location().beg_pos; 567 if (parsing_module_) { 568 DCHECK(info->is_module()); 569 // Declare the special module parameter. 570 auto name = ast_value_factory()->empty_string(); 571 bool is_duplicate = false; 572 bool is_rest = false; 573 bool is_optional = false; 574 auto var = scope->DeclareParameter(name, VariableMode::kVar, is_optional, 575 is_rest, &is_duplicate, 576 ast_value_factory(), beg_pos); 577 DCHECK(!is_duplicate); 578 var->AllocateTo(VariableLocation::PARAMETER, 0); 579 580 PrepareGeneratorVariables(); 581 Expression* initial_yield = 582 BuildInitialYield(kNoSourcePosition, kGeneratorFunction); 583 body->Add( 584 factory()->NewExpressionStatement(initial_yield, kNoSourcePosition), 585 zone()); 586 587 ParseModuleItemList(body, &ok); 588 ok = ok && module()->Validate(this->scope()->AsModuleScope(), 589 pending_error_handler(), zone()); 590 } else if (info->is_wrapped_as_function()) { 591 ParseWrapped(isolate, info, body, scope, zone(), &ok); 592 } else { 593 // Don't count the mode in the use counters--give the program a chance 594 // to enable script-wide strict mode below. 595 this->scope()->SetLanguageMode(info->language_mode()); 596 ParseStatementList(body, Token::EOS, &ok); 597 } 598 599 // The parser will peek but not consume EOS. Our scope logically goes all 600 // the way to the EOS, though. 601 scope->set_end_position(scanner()->peek_location().beg_pos); 602 603 if (ok && is_strict(language_mode())) { 604 CheckStrictOctalLiteral(beg_pos, scanner()->location().end_pos, &ok); 605 } 606 if (ok && is_sloppy(language_mode())) { 607 // TODO(littledan): Function bindings on the global object that modify 608 // pre-existing bindings should be made writable, enumerable and 609 // nonconfigurable if possible, whereas this code will leave attributes 610 // unchanged if the property already exists. 611 InsertSloppyBlockFunctionVarBindings(scope); 612 } 613 if (ok) { 614 CheckConflictingVarDeclarations(scope, &ok); 615 } 616 617 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) { 618 if (body->length() != 1 || 619 !body->at(0)->IsExpressionStatement() || 620 !body->at(0)->AsExpressionStatement()-> 621 expression()->IsFunctionLiteral()) { 622 ReportMessage(MessageTemplate::kSingleFunctionLiteral); 623 ok = false; 624 } 625 } 626 627 if (ok) { 628 RewriteDestructuringAssignments(); 629 int parameter_count = parsing_module_ ? 1 : 0; 630 result = factory()->NewScriptOrEvalFunctionLiteral( 631 scope, body, function_state.expected_property_count(), 632 parameter_count); 633 result->set_suspend_count(function_state.suspend_count()); 634 } 635 } 636 637 info->set_max_function_literal_id(GetLastFunctionLiteralId()); 638 639 // Make sure the target stack is empty. 640 DCHECK_NULL(target_stack_); 641 642 return result; 643 } 644 645 ZonePtrList<const AstRawString>* Parser::PrepareWrappedArguments( 646 Isolate* isolate, ParseInfo* info, Zone* zone) { 647 DCHECK(parsing_on_main_thread_); 648 DCHECK_NOT_NULL(isolate); 649 Handle<FixedArray> arguments(info->script()->wrapped_arguments(), isolate); 650 int arguments_length = arguments->length(); 651 ZonePtrList<const AstRawString>* arguments_for_wrapped_function = 652 new (zone) ZonePtrList<const AstRawString>(arguments_length, zone); 653 for (int i = 0; i < arguments_length; i++) { 654 const AstRawString* argument_string = ast_value_factory()->GetString( 655 Handle<String>(String::cast(arguments->get(i)), isolate)); 656 arguments_for_wrapped_function->Add(argument_string, zone); 657 } 658 return arguments_for_wrapped_function; 659 } 660 661 void Parser::ParseWrapped(Isolate* isolate, ParseInfo* info, 662 ZonePtrList<Statement>* body, 663 DeclarationScope* outer_scope, Zone* zone, bool* ok) { 664 DCHECK_EQ(parsing_on_main_thread_, isolate != nullptr); 665 DCHECK(info->is_wrapped_as_function()); 666 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); 667 668 // Set function and block state for the outer eval scope. 669 DCHECK(outer_scope->is_eval_scope()); 670 FunctionState function_state(&function_state_, &scope_, outer_scope); 671 672 const AstRawString* function_name = nullptr; 673 Scanner::Location location(0, 0); 674 675 ZonePtrList<const AstRawString>* arguments_for_wrapped_function = 676 PrepareWrappedArguments(isolate, info, zone); 677 678 FunctionLiteral* function_literal = ParseFunctionLiteral( 679 function_name, location, kSkipFunctionNameCheck, kNormalFunction, 680 kNoSourcePosition, FunctionLiteral::kWrapped, LanguageMode::kSloppy, 681 arguments_for_wrapped_function, CHECK_OK_VOID); 682 683 Statement* return_statement = factory()->NewReturnStatement( 684 function_literal, kNoSourcePosition, kNoSourcePosition); 685 body->Add(return_statement, zone); 686 } 687 688 FunctionLiteral* Parser::ParseFunction(Isolate* isolate, ParseInfo* info, 689 Handle<SharedFunctionInfo> shared_info) { 690 // It's OK to use the Isolate & counters here, since this function is only 691 // called in the main thread. 692 DCHECK(parsing_on_main_thread_); 693 RuntimeCallTimerScope runtime_timer(runtime_call_stats_, 694 RuntimeCallCounterId::kParseFunction); 695 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.ParseFunction"); 696 base::ElapsedTimer timer; 697 if (V8_UNLIKELY(FLAG_log_function_events)) timer.Start(); 698 699 DeserializeScopeChain(isolate, info, info->maybe_outer_scope_info()); 700 DCHECK_EQ(factory()->zone(), info->zone()); 701 702 // Initialize parser state. 703 Handle<String> name(shared_info->Name(), isolate); 704 info->set_function_name(ast_value_factory()->GetString(name)); 705 scanner_.Initialize(); 706 707 FunctionLiteral* result = 708 DoParseFunction(isolate, info, info->function_name()); 709 MaybeResetCharacterStream(info, result); 710 if (result != nullptr) { 711 Handle<String> inferred_name(shared_info->inferred_name(), isolate); 712 result->set_inferred_name(inferred_name); 713 } 714 715 if (V8_UNLIKELY(FLAG_log_function_events) && result != nullptr) { 716 double ms = timer.Elapsed().InMillisecondsF(); 717 // We need to make sure that the debug-name is available. 718 ast_value_factory()->Internalize(isolate); 719 DeclarationScope* function_scope = result->scope(); 720 std::unique_ptr<char[]> function_name = result->GetDebugName(); 721 LOG(isolate, 722 FunctionEvent("parse-function", info->script()->id(), ms, 723 function_scope->start_position(), 724 function_scope->end_position(), function_name.get(), 725 strlen(function_name.get()))); 726 } 727 return result; 728 } 729 730 static FunctionLiteral::FunctionType ComputeFunctionType(ParseInfo* info) { 731 if (info->is_wrapped_as_function()) { 732 return FunctionLiteral::kWrapped; 733 } else if (info->is_declaration()) { 734 return FunctionLiteral::kDeclaration; 735 } else if (info->is_named_expression()) { 736 return FunctionLiteral::kNamedExpression; 737 } else if (IsConciseMethod(info->function_kind()) || 738 IsAccessorFunction(info->function_kind())) { 739 return FunctionLiteral::kAccessorOrMethod; 740 } 741 return FunctionLiteral::kAnonymousExpression; 742 } 743 744 FunctionLiteral* Parser::DoParseFunction(Isolate* isolate, ParseInfo* info, 745 const AstRawString* raw_name) { 746 DCHECK_EQ(parsing_on_main_thread_, isolate != nullptr); 747 DCHECK_NOT_NULL(raw_name); 748 DCHECK_NULL(scope_); 749 DCHECK_NULL(target_stack_); 750 751 DCHECK(ast_value_factory()); 752 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone()); 753 fni_->PushEnclosingName(raw_name); 754 755 ResetFunctionLiteralId(); 756 DCHECK_LT(0, info->function_literal_id()); 757 SkipFunctionLiterals(info->function_literal_id() - 1); 758 759 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); 760 761 // Place holder for the result. 762 FunctionLiteral* result = nullptr; 763 764 { 765 // Parse the function literal. 766 Scope* outer = original_scope_; 767 DeclarationScope* outer_function = outer->GetClosureScope(); 768 DCHECK(outer); 769 FunctionState function_state(&function_state_, &scope_, outer_function); 770 BlockState block_state(&scope_, outer); 771 DCHECK(is_sloppy(outer->language_mode()) || 772 is_strict(info->language_mode())); 773 FunctionLiteral::FunctionType function_type = ComputeFunctionType(info); 774 FunctionKind kind = info->function_kind(); 775 bool ok = true; 776 777 if (IsArrowFunction(kind)) { 778 if (IsAsyncFunction(kind)) { 779 DCHECK(!scanner()->HasLineTerminatorAfterNext()); 780 if (!Check(Token::ASYNC)) { 781 CHECK(stack_overflow()); 782 return nullptr; 783 } 784 if (!(peek_any_identifier() || peek() == Token::LPAREN)) { 785 CHECK(stack_overflow()); 786 return nullptr; 787 } 788 } 789 790 // TODO(adamk): We should construct this scope from the ScopeInfo. 791 DeclarationScope* scope = NewFunctionScope(kind); 792 793 // This bit only needs to be explicitly set because we're 794 // not passing the ScopeInfo to the Scope constructor. 795 SetLanguageMode(scope, info->language_mode()); 796 797 scope->set_start_position(info->start_position()); 798 ExpressionClassifier formals_classifier(this); 799 ParserFormalParameters formals(scope); 800 // The outer FunctionState should not contain destructuring assignments. 801 DCHECK_EQ(0, 802 function_state.destructuring_assignments_to_rewrite().size()); 803 { 804 // Parsing patterns as variable reference expression creates 805 // NewUnresolved references in current scope. Enter arrow function 806 // scope for formal parameter parsing. 807 BlockState block_state(&scope_, scope); 808 if (Check(Token::LPAREN)) { 809 // '(' StrictFormalParameters ')' 810 ParseFormalParameterList(&formals, &ok); 811 if (ok) ok = Check(Token::RPAREN); 812 } else { 813 // BindingIdentifier 814 ParseFormalParameter(&formals, &ok); 815 if (ok) { 816 DeclareFormalParameters(formals.scope, formals.params, 817 formals.is_simple); 818 } 819 } 820 } 821 822 if (ok) { 823 if (GetLastFunctionLiteralId() != info->function_literal_id() - 1) { 824 // If there were FunctionLiterals in the parameters, we need to 825 // renumber them to shift down so the next function literal id for 826 // the arrow function is the one requested. 827 AstFunctionLiteralIdReindexer reindexer( 828 stack_limit_, 829 (info->function_literal_id() - 1) - GetLastFunctionLiteralId()); 830 for (auto p : formals.params) { 831 if (p->pattern != nullptr) reindexer.Reindex(p->pattern); 832 if (p->initializer != nullptr) reindexer.Reindex(p->initializer); 833 } 834 ResetFunctionLiteralId(); 835 SkipFunctionLiterals(info->function_literal_id() - 1); 836 } 837 838 // Pass `accept_IN=true` to ParseArrowFunctionLiteral --- This should 839 // not be observable, or else the preparser would have failed. 840 const bool accept_IN = true; 841 // Any destructuring assignments in the current FunctionState 842 // actually belong to the arrow function itself. 843 const int rewritable_length = 0; 844 Expression* expression = ParseArrowFunctionLiteral( 845 accept_IN, formals, rewritable_length, &ok); 846 if (ok) { 847 // Scanning must end at the same position that was recorded 848 // previously. If not, parsing has been interrupted due to a stack 849 // overflow, at which point the partially parsed arrow function 850 // concise body happens to be a valid expression. This is a problem 851 // only for arrow functions with single expression bodies, since there 852 // is no end token such as "}" for normal functions. 853 if (scanner()->location().end_pos == info->end_position()) { 854 // The pre-parser saw an arrow function here, so the full parser 855 // must produce a FunctionLiteral. 856 DCHECK(expression->IsFunctionLiteral()); 857 result = expression->AsFunctionLiteral(); 858 } else { 859 ok = false; 860 } 861 } 862 } 863 } else if (IsDefaultConstructor(kind)) { 864 DCHECK_EQ(scope(), outer); 865 result = DefaultConstructor(raw_name, IsDerivedConstructor(kind), 866 info->start_position(), info->end_position()); 867 } else { 868 ZonePtrList<const AstRawString>* arguments_for_wrapped_function = 869 info->is_wrapped_as_function() 870 ? PrepareWrappedArguments(isolate, info, zone()) 871 : nullptr; 872 result = ParseFunctionLiteral( 873 raw_name, Scanner::Location::invalid(), kSkipFunctionNameCheck, kind, 874 kNoSourcePosition, function_type, info->language_mode(), 875 arguments_for_wrapped_function, &ok); 876 } 877 878 if (ok) { 879 result->set_requires_instance_fields_initializer( 880 info->requires_instance_fields_initializer()); 881 } 882 // Make sure the results agree. 883 DCHECK(ok == (result != nullptr)); 884 } 885 886 // Make sure the target stack is empty. 887 DCHECK_NULL(target_stack_); 888 DCHECK_IMPLIES(result, 889 info->function_literal_id() == result->function_literal_id()); 890 return result; 891 } 892 893 Statement* Parser::ParseModuleItem(bool* ok) { 894 // ecma262/#prod-ModuleItem 895 // ModuleItem : 896 // ImportDeclaration 897 // ExportDeclaration 898 // StatementListItem 899 900 Token::Value next = peek(); 901 902 if (next == Token::EXPORT) { 903 return ParseExportDeclaration(ok); 904 } 905 906 if (next == Token::IMPORT) { 907 // We must be careful not to parse a dynamic import expression as an import 908 // declaration. Same for import.meta expressions. 909 Token::Value peek_ahead = PeekAhead(); 910 if ((!allow_harmony_dynamic_import() || peek_ahead != Token::LPAREN) && 911 (!allow_harmony_import_meta() || peek_ahead != Token::PERIOD)) { 912 ParseImportDeclaration(CHECK_OK); 913 return factory()->NewEmptyStatement(kNoSourcePosition); 914 } 915 } 916 917 return ParseStatementListItem(ok); 918 } 919 920 void Parser::ParseModuleItemList(ZonePtrList<Statement>* body, bool* ok) { 921 // ecma262/#prod-Module 922 // Module : 923 // ModuleBody? 924 // 925 // ecma262/#prod-ModuleItemList 926 // ModuleBody : 927 // ModuleItem* 928 929 DCHECK(scope()->is_module_scope()); 930 while (peek() != Token::EOS) { 931 Statement* stat = ParseModuleItem(CHECK_OK_VOID); 932 if (stat && !stat->IsEmpty()) { 933 body->Add(stat, zone()); 934 } 935 } 936 } 937 938 939 const AstRawString* Parser::ParseModuleSpecifier(bool* ok) { 940 // ModuleSpecifier : 941 // StringLiteral 942 943 Expect(Token::STRING, CHECK_OK); 944 return GetSymbol(); 945 } 946 947 ZoneChunkList<Parser::ExportClauseData>* Parser::ParseExportClause( 948 Scanner::Location* reserved_loc, bool* ok) { 949 // ExportClause : 950 // '{' '}' 951 // '{' ExportsList '}' 952 // '{' ExportsList ',' '}' 953 // 954 // ExportsList : 955 // ExportSpecifier 956 // ExportsList ',' ExportSpecifier 957 // 958 // ExportSpecifier : 959 // IdentifierName 960 // IdentifierName 'as' IdentifierName 961 ZoneChunkList<ExportClauseData>* export_data = 962 new (zone()) ZoneChunkList<ExportClauseData>(zone()); 963 964 Expect(Token::LBRACE, CHECK_OK); 965 966 Token::Value name_tok; 967 while ((name_tok = peek()) != Token::RBRACE) { 968 // Keep track of the first reserved word encountered in case our 969 // caller needs to report an error. 970 if (!reserved_loc->IsValid() && 971 !Token::IsIdentifier(name_tok, LanguageMode::kStrict, false, 972 parsing_module_)) { 973 *reserved_loc = scanner()->location(); 974 } 975 const AstRawString* local_name = ParseIdentifierName(CHECK_OK); 976 const AstRawString* export_name = nullptr; 977 Scanner::Location location = scanner()->location(); 978 if (CheckContextualKeyword(Token::AS)) { 979 export_name = ParseIdentifierName(CHECK_OK); 980 // Set the location to the whole "a as b" string, so that it makes sense 981 // both for errors due to "a" and for errors due to "b". 982 location.end_pos = scanner()->location().end_pos; 983 } 984 if (export_name == nullptr) { 985 export_name = local_name; 986 } 987 export_data->push_back({export_name, local_name, location}); 988 if (peek() == Token::RBRACE) break; 989 Expect(Token::COMMA, CHECK_OK); 990 } 991 992 Expect(Token::RBRACE, CHECK_OK); 993 return export_data; 994 } 995 996 ZonePtrList<const Parser::NamedImport>* Parser::ParseNamedImports(int pos, 997 bool* ok) { 998 // NamedImports : 999 // '{' '}' 1000 // '{' ImportsList '}' 1001 // '{' ImportsList ',' '}' 1002 // 1003 // ImportsList : 1004 // ImportSpecifier 1005 // ImportsList ',' ImportSpecifier 1006 // 1007 // ImportSpecifier : 1008 // BindingIdentifier 1009 // IdentifierName 'as' BindingIdentifier 1010 1011 Expect(Token::LBRACE, CHECK_OK); 1012 1013 auto result = new (zone()) ZonePtrList<const NamedImport>(1, zone()); 1014 while (peek() != Token::RBRACE) { 1015 const AstRawString* import_name = ParseIdentifierName(CHECK_OK); 1016 const AstRawString* local_name = import_name; 1017 Scanner::Location location = scanner()->location(); 1018 // In the presence of 'as', the left-side of the 'as' can 1019 // be any IdentifierName. But without 'as', it must be a valid 1020 // BindingIdentifier. 1021 if (CheckContextualKeyword(Token::AS)) { 1022 local_name = ParseIdentifierName(CHECK_OK); 1023 } 1024 if (!Token::IsIdentifier(scanner()->current_token(), LanguageMode::kStrict, 1025 false, parsing_module_)) { 1026 *ok = false; 1027 ReportMessage(MessageTemplate::kUnexpectedReserved); 1028 return nullptr; 1029 } else if (IsEvalOrArguments(local_name)) { 1030 *ok = false; 1031 ReportMessage(MessageTemplate::kStrictEvalArguments); 1032 return nullptr; 1033 } 1034 1035 DeclareVariable(local_name, VariableMode::kConst, kNeedsInitialization, 1036 position(), CHECK_OK); 1037 1038 NamedImport* import = 1039 new (zone()) NamedImport(import_name, local_name, location); 1040 result->Add(import, zone()); 1041 1042 if (peek() == Token::RBRACE) break; 1043 Expect(Token::COMMA, CHECK_OK); 1044 } 1045 1046 Expect(Token::RBRACE, CHECK_OK); 1047 return result; 1048 } 1049 1050 1051 void Parser::ParseImportDeclaration(bool* ok) { 1052 // ImportDeclaration : 1053 // 'import' ImportClause 'from' ModuleSpecifier ';' 1054 // 'import' ModuleSpecifier ';' 1055 // 1056 // ImportClause : 1057 // ImportedDefaultBinding 1058 // NameSpaceImport 1059 // NamedImports 1060 // ImportedDefaultBinding ',' NameSpaceImport 1061 // ImportedDefaultBinding ',' NamedImports 1062 // 1063 // NameSpaceImport : 1064 // '*' 'as' ImportedBinding 1065 1066 int pos = peek_position(); 1067 Expect(Token::IMPORT, CHECK_OK_VOID); 1068 1069 Token::Value tok = peek(); 1070 1071 // 'import' ModuleSpecifier ';' 1072 if (tok == Token::STRING) { 1073 Scanner::Location specifier_loc = scanner()->peek_location(); 1074 const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK_VOID); 1075 ExpectSemicolon(CHECK_OK_VOID); 1076 module()->AddEmptyImport(module_specifier, specifier_loc); 1077 return; 1078 } 1079 1080 // Parse ImportedDefaultBinding if present. 1081 const AstRawString* import_default_binding = nullptr; 1082 Scanner::Location import_default_binding_loc; 1083 if (tok != Token::MUL && tok != Token::LBRACE) { 1084 import_default_binding = 1085 ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK_VOID); 1086 import_default_binding_loc = scanner()->location(); 1087 DeclareVariable(import_default_binding, VariableMode::kConst, 1088 kNeedsInitialization, pos, CHECK_OK_VOID); 1089 } 1090 1091 // Parse NameSpaceImport or NamedImports if present. 1092 const AstRawString* module_namespace_binding = nullptr; 1093 Scanner::Location module_namespace_binding_loc; 1094 const ZonePtrList<const NamedImport>* named_imports = nullptr; 1095 if (import_default_binding == nullptr || Check(Token::COMMA)) { 1096 switch (peek()) { 1097 case Token::MUL: { 1098 Consume(Token::MUL); 1099 ExpectContextualKeyword(Token::AS, CHECK_OK_VOID); 1100 module_namespace_binding = 1101 ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK_VOID); 1102 module_namespace_binding_loc = scanner()->location(); 1103 DeclareVariable(module_namespace_binding, VariableMode::kConst, 1104 kCreatedInitialized, pos, CHECK_OK_VOID); 1105 break; 1106 } 1107 1108 case Token::LBRACE: 1109 named_imports = ParseNamedImports(pos, CHECK_OK_VOID); 1110 break; 1111 1112 default: 1113 *ok = false; 1114 ReportUnexpectedToken(scanner()->current_token()); 1115 return; 1116 } 1117 } 1118 1119 ExpectContextualKeyword(Token::FROM, CHECK_OK_VOID); 1120 Scanner::Location specifier_loc = scanner()->peek_location(); 1121 const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK_VOID); 1122 ExpectSemicolon(CHECK_OK_VOID); 1123 1124 // Now that we have all the information, we can make the appropriate 1125 // declarations. 1126 1127 // TODO(neis): Would prefer to call DeclareVariable for each case below rather 1128 // than above and in ParseNamedImports, but then a possible error message 1129 // would point to the wrong location. Maybe have a DeclareAt version of 1130 // Declare that takes a location? 1131 1132 if (module_namespace_binding != nullptr) { 1133 module()->AddStarImport(module_namespace_binding, module_specifier, 1134 module_namespace_binding_loc, specifier_loc, 1135 zone()); 1136 } 1137 1138 if (import_default_binding != nullptr) { 1139 module()->AddImport(ast_value_factory()->default_string(), 1140 import_default_binding, module_specifier, 1141 import_default_binding_loc, specifier_loc, zone()); 1142 } 1143 1144 if (named_imports != nullptr) { 1145 if (named_imports->length() == 0) { 1146 module()->AddEmptyImport(module_specifier, specifier_loc); 1147 } else { 1148 for (int i = 0; i < named_imports->length(); ++i) { 1149 const NamedImport* import = named_imports->at(i); 1150 module()->AddImport(import->import_name, import->local_name, 1151 module_specifier, import->location, specifier_loc, 1152 zone()); 1153 } 1154 } 1155 } 1156 } 1157 1158 1159 Statement* Parser::ParseExportDefault(bool* ok) { 1160 // Supports the following productions, starting after the 'default' token: 1161 // 'export' 'default' HoistableDeclaration 1162 // 'export' 'default' ClassDeclaration 1163 // 'export' 'default' AssignmentExpression[In] ';' 1164 1165 Expect(Token::DEFAULT, CHECK_OK); 1166 Scanner::Location default_loc = scanner()->location(); 1167 1168 ZonePtrList<const AstRawString> local_names(1, zone()); 1169 Statement* result = nullptr; 1170 switch (peek()) { 1171 case Token::FUNCTION: 1172 result = ParseHoistableDeclaration(&local_names, true, CHECK_OK); 1173 break; 1174 1175 case Token::CLASS: 1176 Consume(Token::CLASS); 1177 result = ParseClassDeclaration(&local_names, true, CHECK_OK); 1178 break; 1179 1180 case Token::ASYNC: 1181 if (PeekAhead() == Token::FUNCTION && 1182 !scanner()->HasLineTerminatorAfterNext()) { 1183 Consume(Token::ASYNC); 1184 result = ParseAsyncFunctionDeclaration(&local_names, true, CHECK_OK); 1185 break; 1186 } 1187 V8_FALLTHROUGH; 1188 1189 default: { 1190 int pos = position(); 1191 ExpressionClassifier classifier(this); 1192 Expression* value = ParseAssignmentExpression(true, CHECK_OK); 1193 ValidateExpression(CHECK_OK); 1194 SetFunctionName(value, ast_value_factory()->default_string()); 1195 1196 const AstRawString* local_name = 1197 ast_value_factory()->star_default_star_string(); 1198 local_names.Add(local_name, zone()); 1199 1200 // It's fine to declare this as VariableMode::kConst because the user has 1201 // no way of writing to it. 1202 Declaration* decl = 1203 DeclareVariable(local_name, VariableMode::kConst, pos, CHECK_OK); 1204 decl->proxy()->var()->set_initializer_position(position()); 1205 1206 Assignment* assignment = factory()->NewAssignment( 1207 Token::INIT, decl->proxy(), value, kNoSourcePosition); 1208 result = IgnoreCompletion( 1209 factory()->NewExpressionStatement(assignment, kNoSourcePosition)); 1210 1211 ExpectSemicolon(CHECK_OK); 1212 break; 1213 } 1214 } 1215 1216 DCHECK_EQ(local_names.length(), 1); 1217 module()->AddExport(local_names.first(), 1218 ast_value_factory()->default_string(), default_loc, 1219 zone()); 1220 1221 DCHECK_NOT_NULL(result); 1222 return result; 1223 } 1224 1225 Statement* Parser::ParseExportDeclaration(bool* ok) { 1226 // ExportDeclaration: 1227 // 'export' '*' 'from' ModuleSpecifier ';' 1228 // 'export' ExportClause ('from' ModuleSpecifier)? ';' 1229 // 'export' VariableStatement 1230 // 'export' Declaration 1231 // 'export' 'default' ... (handled in ParseExportDefault) 1232 1233 Expect(Token::EXPORT, CHECK_OK); 1234 int pos = position(); 1235 1236 Statement* result = nullptr; 1237 ZonePtrList<const AstRawString> names(1, zone()); 1238 Scanner::Location loc = scanner()->peek_location(); 1239 switch (peek()) { 1240 case Token::DEFAULT: 1241 return ParseExportDefault(ok); 1242 1243 case Token::MUL: { 1244 Consume(Token::MUL); 1245 loc = scanner()->location(); 1246 ExpectContextualKeyword(Token::FROM, CHECK_OK); 1247 Scanner::Location specifier_loc = scanner()->peek_location(); 1248 const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK); 1249 ExpectSemicolon(CHECK_OK); 1250 module()->AddStarExport(module_specifier, loc, specifier_loc, zone()); 1251 return factory()->NewEmptyStatement(pos); 1252 } 1253 1254 case Token::LBRACE: { 1255 // There are two cases here: 1256 // 1257 // 'export' ExportClause ';' 1258 // and 1259 // 'export' ExportClause FromClause ';' 1260 // 1261 // In the first case, the exported identifiers in ExportClause must 1262 // not be reserved words, while in the latter they may be. We 1263 // pass in a location that gets filled with the first reserved word 1264 // encountered, and then throw a SyntaxError if we are in the 1265 // non-FromClause case. 1266 Scanner::Location reserved_loc = Scanner::Location::invalid(); 1267 ZoneChunkList<ExportClauseData>* export_data = 1268 ParseExportClause(&reserved_loc, CHECK_OK); 1269 const AstRawString* module_specifier = nullptr; 1270 Scanner::Location specifier_loc; 1271 if (CheckContextualKeyword(Token::FROM)) { 1272 specifier_loc = scanner()->peek_location(); 1273 module_specifier = ParseModuleSpecifier(CHECK_OK); 1274 } else if (reserved_loc.IsValid()) { 1275 // No FromClause, so reserved words are invalid in ExportClause. 1276 *ok = false; 1277 ReportMessageAt(reserved_loc, MessageTemplate::kUnexpectedReserved); 1278 return nullptr; 1279 } 1280 ExpectSemicolon(CHECK_OK); 1281 if (module_specifier == nullptr) { 1282 for (const ExportClauseData& data : *export_data) { 1283 module()->AddExport(data.local_name, data.export_name, data.location, 1284 zone()); 1285 } 1286 } else if (export_data->is_empty()) { 1287 module()->AddEmptyImport(module_specifier, specifier_loc); 1288 } else { 1289 for (const ExportClauseData& data : *export_data) { 1290 module()->AddExport(data.local_name, data.export_name, 1291 module_specifier, data.location, specifier_loc, 1292 zone()); 1293 } 1294 } 1295 return factory()->NewEmptyStatement(pos); 1296 } 1297 1298 case Token::FUNCTION: 1299 result = ParseHoistableDeclaration(&names, false, CHECK_OK); 1300 break; 1301 1302 case Token::CLASS: 1303 Consume(Token::CLASS); 1304 result = ParseClassDeclaration(&names, false, CHECK_OK); 1305 break; 1306 1307 case Token::VAR: 1308 case Token::LET: 1309 case Token::CONST: 1310 result = ParseVariableStatement(kStatementListItem, &names, CHECK_OK); 1311 break; 1312 1313 case Token::ASYNC: 1314 // TODO(neis): Why don't we have the same check here as in 1315 // ParseStatementListItem? 1316 Consume(Token::ASYNC); 1317 result = ParseAsyncFunctionDeclaration(&names, false, CHECK_OK); 1318 break; 1319 1320 default: 1321 *ok = false; 1322 ReportUnexpectedToken(scanner()->current_token()); 1323 return nullptr; 1324 } 1325 loc.end_pos = scanner()->location().end_pos; 1326 1327 ModuleDescriptor* descriptor = module(); 1328 for (int i = 0; i < names.length(); ++i) { 1329 descriptor->AddExport(names[i], names[i], loc, zone()); 1330 } 1331 1332 DCHECK_NOT_NULL(result); 1333 return result; 1334 } 1335 1336 VariableProxy* Parser::NewUnresolved(const AstRawString* name, int begin_pos, 1337 VariableKind kind) { 1338 return scope()->NewUnresolved(factory(), name, begin_pos, kind); 1339 } 1340 1341 VariableProxy* Parser::NewUnresolved(const AstRawString* name) { 1342 return scope()->NewUnresolved(factory(), name, scanner()->location().beg_pos); 1343 } 1344 1345 Declaration* Parser::DeclareVariable(const AstRawString* name, 1346 VariableMode mode, int pos, bool* ok) { 1347 return DeclareVariable(name, mode, Variable::DefaultInitializationFlag(mode), 1348 pos, ok); 1349 } 1350 1351 Declaration* Parser::DeclareVariable(const AstRawString* name, 1352 VariableMode mode, InitializationFlag init, 1353 int pos, bool* ok) { 1354 DCHECK_NOT_NULL(name); 1355 VariableProxy* proxy = factory()->NewVariableProxy( 1356 name, NORMAL_VARIABLE, scanner()->location().beg_pos); 1357 Declaration* declaration; 1358 if (mode == VariableMode::kVar && !scope()->is_declaration_scope()) { 1359 DCHECK(scope()->is_block_scope() || scope()->is_with_scope()); 1360 declaration = factory()->NewNestedVariableDeclaration(proxy, scope(), pos); 1361 } else { 1362 declaration = factory()->NewVariableDeclaration(proxy, pos); 1363 } 1364 Declare(declaration, DeclarationDescriptor::NORMAL, mode, init, ok, nullptr, 1365 scanner()->location().end_pos); 1366 if (!*ok) return nullptr; 1367 return declaration; 1368 } 1369 1370 Variable* Parser::Declare(Declaration* declaration, 1371 DeclarationDescriptor::Kind declaration_kind, 1372 VariableMode mode, InitializationFlag init, bool* ok, 1373 Scope* scope, int var_end_pos) { 1374 if (scope == nullptr) { 1375 scope = this->scope(); 1376 } 1377 bool sloppy_mode_block_scope_function_redefinition = false; 1378 Variable* variable = scope->DeclareVariable( 1379 declaration, mode, init, &sloppy_mode_block_scope_function_redefinition, 1380 ok); 1381 if (!*ok) { 1382 // If we only have the start position of a proxy, we can't highlight the 1383 // whole variable name. Pretend its length is 1 so that we highlight at 1384 // least the first character. 1385 Scanner::Location loc(declaration->proxy()->position(), 1386 var_end_pos != kNoSourcePosition 1387 ? var_end_pos 1388 : declaration->proxy()->position() + 1); 1389 if (declaration_kind == DeclarationDescriptor::PARAMETER) { 1390 ReportMessageAt(loc, MessageTemplate::kParamDupe); 1391 } else { 1392 ReportMessageAt(loc, MessageTemplate::kVarRedeclaration, 1393 declaration->proxy()->raw_name()); 1394 } 1395 return nullptr; 1396 } 1397 if (sloppy_mode_block_scope_function_redefinition) { 1398 ++use_counts_[v8::Isolate::kSloppyModeBlockScopedFunctionRedefinition]; 1399 } 1400 return variable; 1401 } 1402 1403 Block* Parser::BuildInitializationBlock( 1404 DeclarationParsingResult* parsing_result, 1405 ZonePtrList<const AstRawString>* names, bool* ok) { 1406 Block* result = factory()->NewBlock(1, true); 1407 for (const auto& declaration : parsing_result->declarations) { 1408 DeclareAndInitializeVariables(result, &(parsing_result->descriptor), 1409 &declaration, names, CHECK_OK); 1410 } 1411 return result; 1412 } 1413 1414 Statement* Parser::DeclareFunction(const AstRawString* variable_name, 1415 FunctionLiteral* function, VariableMode mode, 1416 int pos, bool is_sloppy_block_function, 1417 ZonePtrList<const AstRawString>* names, 1418 bool* ok) { 1419 VariableProxy* proxy = 1420 factory()->NewVariableProxy(variable_name, NORMAL_VARIABLE, pos); 1421 Declaration* declaration = 1422 factory()->NewFunctionDeclaration(proxy, function, pos); 1423 Declare(declaration, DeclarationDescriptor::NORMAL, mode, kCreatedInitialized, 1424 CHECK_OK); 1425 if (names) names->Add(variable_name, zone()); 1426 if (is_sloppy_block_function) { 1427 SloppyBlockFunctionStatement* statement = 1428 factory()->NewSloppyBlockFunctionStatement(); 1429 GetDeclarationScope()->DeclareSloppyBlockFunction(variable_name, scope(), 1430 statement); 1431 return statement; 1432 } 1433 return factory()->NewEmptyStatement(kNoSourcePosition); 1434 } 1435 1436 Statement* Parser::DeclareClass(const AstRawString* variable_name, 1437 Expression* value, 1438 ZonePtrList<const AstRawString>* names, 1439 int class_token_pos, int end_pos, bool* ok) { 1440 Declaration* decl = DeclareVariable(variable_name, VariableMode::kLet, 1441 class_token_pos, CHECK_OK); 1442 decl->proxy()->var()->set_initializer_position(end_pos); 1443 if (names) names->Add(variable_name, zone()); 1444 1445 Assignment* assignment = factory()->NewAssignment(Token::INIT, decl->proxy(), 1446 value, class_token_pos); 1447 return IgnoreCompletion( 1448 factory()->NewExpressionStatement(assignment, kNoSourcePosition)); 1449 } 1450 1451 Statement* Parser::DeclareNative(const AstRawString* name, int pos, bool* ok) { 1452 // Make sure that the function containing the native declaration 1453 // isn't lazily compiled. The extension structures are only 1454 // accessible while parsing the first time not when reparsing 1455 // because of lazy compilation. 1456 GetClosureScope()->ForceEagerCompilation(); 1457 1458 // TODO(1240846): It's weird that native function declarations are 1459 // introduced dynamically when we meet their declarations, whereas 1460 // other functions are set up when entering the surrounding scope. 1461 Declaration* decl = DeclareVariable(name, VariableMode::kVar, pos, CHECK_OK); 1462 NativeFunctionLiteral* lit = 1463 factory()->NewNativeFunctionLiteral(name, extension_, kNoSourcePosition); 1464 return factory()->NewExpressionStatement( 1465 factory()->NewAssignment(Token::INIT, decl->proxy(), lit, 1466 kNoSourcePosition), 1467 pos); 1468 } 1469 1470 void Parser::DeclareLabel(ZonePtrList<const AstRawString>** labels, 1471 ZonePtrList<const AstRawString>** own_labels, 1472 VariableProxy* var, bool* ok) { 1473 DCHECK(IsIdentifier(var)); 1474 const AstRawString* label = var->raw_name(); 1475 1476 // TODO(1240780): We don't check for redeclaration of labels 1477 // during preparsing since keeping track of the set of active 1478 // labels requires nontrivial changes to the way scopes are 1479 // structured. However, these are probably changes we want to 1480 // make later anyway so we should go back and fix this then. 1481 if (ContainsLabel(*labels, label) || TargetStackContainsLabel(label)) { 1482 ReportMessage(MessageTemplate::kLabelRedeclaration, label); 1483 *ok = false; 1484 return; 1485 } 1486 1487 // Add {label} to both {labels} and {own_labels}. 1488 if (*labels == nullptr) { 1489 DCHECK_NULL(*own_labels); 1490 *labels = new (zone()) ZonePtrList<const AstRawString>(1, zone()); 1491 *own_labels = new (zone()) ZonePtrList<const AstRawString>(1, zone()); 1492 } else { 1493 if (*own_labels == nullptr) { 1494 *own_labels = new (zone()) ZonePtrList<const AstRawString>(1, zone()); 1495 } 1496 } 1497 (*labels)->Add(label, zone()); 1498 (*own_labels)->Add(label, zone()); 1499 1500 // Remove the "ghost" variable that turned out to be a label 1501 // from the top scope. This way, we don't try to resolve it 1502 // during the scope processing. 1503 scope()->RemoveUnresolved(var); 1504 } 1505 1506 bool Parser::ContainsLabel(ZonePtrList<const AstRawString>* labels, 1507 const AstRawString* label) { 1508 DCHECK_NOT_NULL(label); 1509 if (labels != nullptr) { 1510 for (int i = labels->length(); i-- > 0;) { 1511 if (labels->at(i) == label) return true; 1512 } 1513 } 1514 return false; 1515 } 1516 1517 Block* Parser::IgnoreCompletion(Statement* statement) { 1518 Block* block = factory()->NewBlock(1, true); 1519 block->statements()->Add(statement, zone()); 1520 return block; 1521 } 1522 1523 Expression* Parser::RewriteReturn(Expression* return_value, int pos) { 1524 if (IsDerivedConstructor(function_state_->kind())) { 1525 // For subclass constructors we need to return this in case of undefined; 1526 // other primitive values trigger an exception in the ConstructStub. 1527 // 1528 // return expr; 1529 // 1530 // Is rewritten as: 1531 // 1532 // return (temp = expr) === undefined ? this : temp; 1533 1534 // temp = expr 1535 Variable* temp = NewTemporary(ast_value_factory()->empty_string()); 1536 Assignment* assign = factory()->NewAssignment( 1537 Token::ASSIGN, factory()->NewVariableProxy(temp), return_value, pos); 1538 1539 // temp === undefined 1540 Expression* is_undefined = factory()->NewCompareOperation( 1541 Token::EQ_STRICT, assign, 1542 factory()->NewUndefinedLiteral(kNoSourcePosition), pos); 1543 1544 // is_undefined ? this : temp 1545 return_value = 1546 factory()->NewConditional(is_undefined, ThisExpression(pos), 1547 factory()->NewVariableProxy(temp), pos); 1548 } 1549 return return_value; 1550 } 1551 1552 Expression* Parser::RewriteDoExpression(Block* body, int pos, bool* ok) { 1553 Variable* result = NewTemporary(ast_value_factory()->dot_result_string()); 1554 DoExpression* expr = factory()->NewDoExpression(body, result, pos); 1555 if (!Rewriter::Rewrite(this, GetClosureScope(), expr, ast_value_factory())) { 1556 *ok = false; 1557 return nullptr; 1558 } 1559 return expr; 1560 } 1561 1562 Statement* Parser::RewriteSwitchStatement(SwitchStatement* switch_statement, 1563 Scope* scope) { 1564 // In order to get the CaseClauses to execute in their own lexical scope, 1565 // but without requiring downstream code to have special scope handling 1566 // code for switch statements, desugar into blocks as follows: 1567 // { // To group the statements--harmless to evaluate Expression in scope 1568 // .tag_variable = Expression; 1569 // { // To give CaseClauses a scope 1570 // switch (.tag_variable) { CaseClause* } 1571 // } 1572 // } 1573 DCHECK_NOT_NULL(scope); 1574 DCHECK(scope->is_block_scope()); 1575 DCHECK_GE(switch_statement->position(), scope->start_position()); 1576 DCHECK_LT(switch_statement->position(), scope->end_position()); 1577 1578 Block* switch_block = factory()->NewBlock(2, false); 1579 1580 Expression* tag = switch_statement->tag(); 1581 Variable* tag_variable = 1582 NewTemporary(ast_value_factory()->dot_switch_tag_string()); 1583 Assignment* tag_assign = factory()->NewAssignment( 1584 Token::ASSIGN, factory()->NewVariableProxy(tag_variable), tag, 1585 tag->position()); 1586 // Wrap with IgnoreCompletion so the tag isn't returned as the completion 1587 // value, in case the switch statements don't have a value. 1588 Statement* tag_statement = IgnoreCompletion( 1589 factory()->NewExpressionStatement(tag_assign, kNoSourcePosition)); 1590 switch_block->statements()->Add(tag_statement, zone()); 1591 1592 switch_statement->set_tag(factory()->NewVariableProxy(tag_variable)); 1593 Block* cases_block = factory()->NewBlock(1, false); 1594 cases_block->statements()->Add(switch_statement, zone()); 1595 cases_block->set_scope(scope); 1596 switch_block->statements()->Add(cases_block, zone()); 1597 return switch_block; 1598 } 1599 1600 void Parser::RewriteCatchPattern(CatchInfo* catch_info, bool* ok) { 1601 if (catch_info->name == nullptr) { 1602 DCHECK_NOT_NULL(catch_info->pattern); 1603 catch_info->name = ast_value_factory()->dot_catch_string(); 1604 } 1605 Variable* catch_variable = 1606 catch_info->scope->DeclareLocal(catch_info->name, VariableMode::kVar); 1607 if (catch_info->pattern != nullptr) { 1608 DeclarationDescriptor descriptor; 1609 descriptor.declaration_kind = DeclarationDescriptor::NORMAL; 1610 descriptor.scope = scope(); 1611 descriptor.mode = VariableMode::kLet; 1612 descriptor.declaration_pos = catch_info->pattern->position(); 1613 descriptor.initialization_pos = catch_info->pattern->position(); 1614 1615 // Initializer position for variables declared by the pattern. 1616 const int initializer_position = position(); 1617 1618 DeclarationParsingResult::Declaration decl( 1619 catch_info->pattern, initializer_position, 1620 factory()->NewVariableProxy(catch_variable)); 1621 1622 catch_info->init_block = factory()->NewBlock(8, true); 1623 DeclareAndInitializeVariables(catch_info->init_block, &descriptor, &decl, 1624 &catch_info->bound_names, ok); 1625 } else { 1626 catch_info->bound_names.Add(catch_info->name, zone()); 1627 } 1628 } 1629 1630 void Parser::ValidateCatchBlock(const CatchInfo& catch_info, bool* ok) { 1631 // Check for `catch(e) { let e; }` and similar errors. 1632 Scope* inner_block_scope = catch_info.inner_block->scope(); 1633 if (inner_block_scope != nullptr) { 1634 Declaration* decl = inner_block_scope->CheckLexDeclarationsConflictingWith( 1635 catch_info.bound_names); 1636 if (decl != nullptr) { 1637 const AstRawString* name = decl->proxy()->raw_name(); 1638 int position = decl->proxy()->position(); 1639 Scanner::Location location = 1640 position == kNoSourcePosition 1641 ? Scanner::Location::invalid() 1642 : Scanner::Location(position, position + 1); 1643 ReportMessageAt(location, MessageTemplate::kVarRedeclaration, name); 1644 *ok = false; 1645 } 1646 } 1647 } 1648 1649 Statement* Parser::RewriteTryStatement(Block* try_block, Block* catch_block, 1650 const SourceRange& catch_range, 1651 Block* finally_block, 1652 const SourceRange& finally_range, 1653 const CatchInfo& catch_info, int pos) { 1654 // Simplify the AST nodes by converting: 1655 // 'try B0 catch B1 finally B2' 1656 // to: 1657 // 'try { try B0 catch B1 } finally B2' 1658 1659 if (catch_block != nullptr && finally_block != nullptr) { 1660 // If we have both, create an inner try/catch. 1661 TryCatchStatement* statement; 1662 statement = factory()->NewTryCatchStatement(try_block, catch_info.scope, 1663 catch_block, kNoSourcePosition); 1664 RecordTryCatchStatementSourceRange(statement, catch_range); 1665 1666 try_block = factory()->NewBlock(1, false); 1667 try_block->statements()->Add(statement, zone()); 1668 catch_block = nullptr; // Clear to indicate it's been handled. 1669 } 1670 1671 if (catch_block != nullptr) { 1672 DCHECK_NULL(finally_block); 1673 TryCatchStatement* stmt = factory()->NewTryCatchStatement( 1674 try_block, catch_info.scope, catch_block, pos); 1675 RecordTryCatchStatementSourceRange(stmt, catch_range); 1676 return stmt; 1677 } else { 1678 DCHECK_NOT_NULL(finally_block); 1679 TryFinallyStatement* stmt = 1680 factory()->NewTryFinallyStatement(try_block, finally_block, pos); 1681 RecordTryFinallyStatementSourceRange(stmt, finally_range); 1682 return stmt; 1683 } 1684 } 1685 1686 void Parser::ParseAndRewriteGeneratorFunctionBody(int pos, FunctionKind kind, 1687 ZonePtrList<Statement>* body, 1688 bool* ok) { 1689 // For ES6 Generators, we just prepend the initial yield. 1690 Expression* initial_yield = BuildInitialYield(pos, kind); 1691 body->Add(factory()->NewExpressionStatement(initial_yield, kNoSourcePosition), 1692 zone()); 1693 ParseStatementList(body, Token::RBRACE, ok); 1694 } 1695 1696 void Parser::ParseAndRewriteAsyncGeneratorFunctionBody( 1697 int pos, FunctionKind kind, ZonePtrList<Statement>* body, bool* ok) { 1698 // For ES2017 Async Generators, we produce: 1699 // 1700 // try { 1701 // InitialYield; 1702 // ...body...; 1703 // return undefined; // See comment below 1704 // } catch (.catch) { 1705 // %AsyncGeneratorReject(generator, .catch); 1706 // } finally { 1707 // %_GeneratorClose(generator); 1708 // } 1709 // 1710 // - InitialYield yields the actual generator object. 1711 // - Any return statement inside the body will have its argument wrapped 1712 // in an iterator result object with a "done" property set to `true`. 1713 // - If the generator terminates for whatever reason, we must close it. 1714 // Hence the finally clause. 1715 // - BytecodeGenerator performs special handling for ReturnStatements in 1716 // async generator functions, resolving the appropriate Promise with an 1717 // "done" iterator result object containing a Promise-unwrapped value. 1718 DCHECK(IsAsyncGeneratorFunction(kind)); 1719 1720 Block* try_block = factory()->NewBlock(3, false); 1721 Expression* initial_yield = BuildInitialYield(pos, kind); 1722 try_block->statements()->Add( 1723 factory()->NewExpressionStatement(initial_yield, kNoSourcePosition), 1724 zone()); 1725 ParseStatementList(try_block->statements(), Token::RBRACE, ok); 1726 if (!*ok) return; 1727 1728 // Don't create iterator result for async generators, as the resume methods 1729 // will create it. 1730 // TODO(leszeks): This will create another suspend point, which is unnecessary 1731 // if there is already an unconditional return in the body. 1732 Statement* final_return = BuildReturnStatement( 1733 factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition); 1734 try_block->statements()->Add(final_return, zone()); 1735 1736 // For AsyncGenerators, a top-level catch block will reject the Promise. 1737 Scope* catch_scope = NewHiddenCatchScope(); 1738 1739 ZonePtrList<Expression>* reject_args = 1740 new (zone()) ZonePtrList<Expression>(2, zone()); 1741 reject_args->Add(factory()->NewVariableProxy( 1742 function_state_->scope()->generator_object_var()), 1743 zone()); 1744 reject_args->Add(factory()->NewVariableProxy(catch_scope->catch_variable()), 1745 zone()); 1746 1747 Expression* reject_call = factory()->NewCallRuntime( 1748 Runtime::kInlineAsyncGeneratorReject, reject_args, kNoSourcePosition); 1749 Block* catch_block = IgnoreCompletion( 1750 factory()->NewReturnStatement(reject_call, kNoSourcePosition)); 1751 1752 TryStatement* try_catch = factory()->NewTryCatchStatementForAsyncAwait( 1753 try_block, catch_scope, catch_block, kNoSourcePosition); 1754 1755 try_block = factory()->NewBlock(1, false); 1756 try_block->statements()->Add(try_catch, zone()); 1757 1758 Block* finally_block = factory()->NewBlock(1, false); 1759 ZonePtrList<Expression>* close_args = 1760 new (zone()) ZonePtrList<Expression>(1, zone()); 1761 VariableProxy* call_proxy = factory()->NewVariableProxy( 1762 function_state_->scope()->generator_object_var()); 1763 close_args->Add(call_proxy, zone()); 1764 Expression* close_call = factory()->NewCallRuntime( 1765 Runtime::kInlineGeneratorClose, close_args, kNoSourcePosition); 1766 finally_block->statements()->Add( 1767 factory()->NewExpressionStatement(close_call, kNoSourcePosition), zone()); 1768 1769 body->Add(factory()->NewTryFinallyStatement(try_block, finally_block, 1770 kNoSourcePosition), 1771 zone()); 1772 } 1773 1774 void Parser::DeclareFunctionNameVar(const AstRawString* function_name, 1775 FunctionLiteral::FunctionType function_type, 1776 DeclarationScope* function_scope) { 1777 if (function_type == FunctionLiteral::kNamedExpression && 1778 function_scope->LookupLocal(function_name) == nullptr) { 1779 DCHECK_EQ(function_scope, scope()); 1780 function_scope->DeclareFunctionVar(function_name); 1781 } 1782 } 1783 1784 // [if (IteratorType == kNormal)] 1785 // !%_IsJSReceiver(result = iterator.next()) && 1786 // %ThrowIteratorResultNotAnObject(result) 1787 // [else if (IteratorType == kAsync)] 1788 // !%_IsJSReceiver(result = Await(iterator.next())) && 1789 // %ThrowIteratorResultNotAnObject(result) 1790 // [endif] 1791 Expression* Parser::BuildIteratorNextResult(VariableProxy* iterator, 1792 VariableProxy* next, 1793 Variable* result, IteratorType type, 1794 int pos) { 1795 Expression* next_property = factory()->NewResolvedProperty(iterator, next); 1796 ZonePtrList<Expression>* next_arguments = 1797 new (zone()) ZonePtrList<Expression>(0, zone()); 1798 Expression* next_call = 1799 factory()->NewCall(next_property, next_arguments, kNoSourcePosition); 1800 if (type == IteratorType::kAsync) { 1801 function_state_->AddSuspend(); 1802 next_call = factory()->NewAwait(next_call, pos); 1803 } 1804 Expression* result_proxy = factory()->NewVariableProxy(result); 1805 Expression* left = 1806 factory()->NewAssignment(Token::ASSIGN, result_proxy, next_call, pos); 1807 1808 // %_IsJSReceiver(...) 1809 ZonePtrList<Expression>* is_spec_object_args = 1810 new (zone()) ZonePtrList<Expression>(1, zone()); 1811 is_spec_object_args->Add(left, zone()); 1812 Expression* is_spec_object_call = factory()->NewCallRuntime( 1813 Runtime::kInlineIsJSReceiver, is_spec_object_args, pos); 1814 1815 // %ThrowIteratorResultNotAnObject(result) 1816 Expression* result_proxy_again = factory()->NewVariableProxy(result); 1817 ZonePtrList<Expression>* throw_arguments = 1818 new (zone()) ZonePtrList<Expression>(1, zone()); 1819 throw_arguments->Add(result_proxy_again, zone()); 1820 Expression* throw_call = factory()->NewCallRuntime( 1821 Runtime::kThrowIteratorResultNotAnObject, throw_arguments, pos); 1822 1823 return factory()->NewBinaryOperation( 1824 Token::AND, 1825 factory()->NewUnaryOperation(Token::NOT, is_spec_object_call, pos), 1826 throw_call, pos); 1827 } 1828 1829 Statement* Parser::InitializeForEachStatement(ForEachStatement* stmt, 1830 Expression* each, 1831 Expression* subject, 1832 Statement* body) { 1833 ForOfStatement* for_of = stmt->AsForOfStatement(); 1834 if (for_of != nullptr) { 1835 const bool finalize = true; 1836 return InitializeForOfStatement(for_of, each, subject, body, finalize, 1837 IteratorType::kNormal, each->position()); 1838 } else { 1839 if (each->IsArrayLiteral() || each->IsObjectLiteral()) { 1840 Variable* temp = NewTemporary(ast_value_factory()->empty_string()); 1841 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); 1842 Expression* assign_each = 1843 RewriteDestructuringAssignment(factory()->NewAssignment( 1844 Token::ASSIGN, each, temp_proxy, kNoSourcePosition)); 1845 auto block = factory()->NewBlock(2, false); 1846 block->statements()->Add( 1847 factory()->NewExpressionStatement(assign_each, kNoSourcePosition), 1848 zone()); 1849 block->statements()->Add(body, zone()); 1850 body = block; 1851 each = factory()->NewVariableProxy(temp); 1852 } 1853 MarkExpressionAsAssigned(each); 1854 stmt->AsForInStatement()->Initialize(each, subject, body); 1855 } 1856 return stmt; 1857 } 1858 1859 // Special case for legacy for 1860 // 1861 // for (var x = initializer in enumerable) body 1862 // 1863 // An initialization block of the form 1864 // 1865 // { 1866 // x = initializer; 1867 // } 1868 // 1869 // is returned in this case. It has reserved space for two statements, 1870 // so that (later on during parsing), the equivalent of 1871 // 1872 // for (x in enumerable) body 1873 // 1874 // is added as a second statement to it. 1875 Block* Parser::RewriteForVarInLegacy(const ForInfo& for_info) { 1876 const DeclarationParsingResult::Declaration& decl = 1877 for_info.parsing_result.declarations[0]; 1878 if (!IsLexicalVariableMode(for_info.parsing_result.descriptor.mode) && 1879 decl.pattern->IsVariableProxy() && decl.initializer != nullptr) { 1880 ++use_counts_[v8::Isolate::kForInInitializer]; 1881 const AstRawString* name = decl.pattern->AsVariableProxy()->raw_name(); 1882 VariableProxy* single_var = NewUnresolved(name); 1883 Block* init_block = factory()->NewBlock(2, true); 1884 init_block->statements()->Add( 1885 factory()->NewExpressionStatement( 1886 factory()->NewAssignment(Token::ASSIGN, single_var, 1887 decl.initializer, kNoSourcePosition), 1888 kNoSourcePosition), 1889 zone()); 1890 return init_block; 1891 } 1892 return nullptr; 1893 } 1894 1895 // Rewrite a for-in/of statement of the form 1896 // 1897 // for (let/const/var x in/of e) b 1898 // 1899 // into 1900 // 1901 // { 1902 // var temp; 1903 // for (temp in/of e) { 1904 // let/const/var x = temp; 1905 // b; 1906 // } 1907 // let x; // for TDZ 1908 // } 1909 void Parser::DesugarBindingInForEachStatement(ForInfo* for_info, 1910 Block** body_block, 1911 Expression** each_variable, 1912 bool* ok) { 1913 DCHECK_EQ(1, for_info->parsing_result.declarations.size()); 1914 DeclarationParsingResult::Declaration& decl = 1915 for_info->parsing_result.declarations[0]; 1916 Variable* temp = NewTemporary(ast_value_factory()->dot_for_string()); 1917 auto each_initialization_block = factory()->NewBlock(1, true); 1918 { 1919 auto descriptor = for_info->parsing_result.descriptor; 1920 descriptor.declaration_pos = kNoSourcePosition; 1921 descriptor.initialization_pos = kNoSourcePosition; 1922 descriptor.scope = scope(); 1923 decl.initializer = factory()->NewVariableProxy(temp); 1924 1925 bool is_for_var_of = 1926 for_info->mode == ForEachStatement::ITERATE && 1927 for_info->parsing_result.descriptor.mode == VariableMode::kVar; 1928 bool collect_names = 1929 IsLexicalVariableMode(for_info->parsing_result.descriptor.mode) || 1930 is_for_var_of; 1931 1932 DeclareAndInitializeVariables( 1933 each_initialization_block, &descriptor, &decl, 1934 collect_names ? &for_info->bound_names : nullptr, CHECK_OK_VOID); 1935 1936 // Annex B.3.5 prohibits the form 1937 // `try {} catch(e) { for (var e of {}); }` 1938 // So if we are parsing a statement like `for (var ... of ...)` 1939 // we need to walk up the scope chain and look for catch scopes 1940 // which have a simple binding, then compare their binding against 1941 // all of the names declared in the init of the for-of we're 1942 // parsing. 1943 if (is_for_var_of) { 1944 Scope* catch_scope = scope(); 1945 while (catch_scope != nullptr && !catch_scope->is_declaration_scope()) { 1946 if (catch_scope->is_catch_scope()) { 1947 auto name = catch_scope->catch_variable()->raw_name(); 1948 // If it's a simple binding and the name is declared in the for loop. 1949 if (name != ast_value_factory()->dot_catch_string() && 1950 for_info->bound_names.Contains(name)) { 1951 ReportMessageAt(for_info->parsing_result.bindings_loc, 1952 MessageTemplate::kVarRedeclaration, name); 1953 *ok = false; 1954 return; 1955 } 1956 } 1957 catch_scope = catch_scope->outer_scope(); 1958 } 1959 } 1960 } 1961 1962 *body_block = factory()->NewBlock(3, false); 1963 (*body_block)->statements()->Add(each_initialization_block, zone()); 1964 *each_variable = factory()->NewVariableProxy(temp, for_info->position); 1965 } 1966 1967 // Create a TDZ for any lexically-bound names in for in/of statements. 1968 Block* Parser::CreateForEachStatementTDZ(Block* init_block, 1969 const ForInfo& for_info, bool* ok) { 1970 if (IsLexicalVariableMode(for_info.parsing_result.descriptor.mode)) { 1971 DCHECK_NULL(init_block); 1972 1973 init_block = factory()->NewBlock(1, false); 1974 1975 for (int i = 0; i < for_info.bound_names.length(); ++i) { 1976 // TODO(adamk): This needs to be some sort of special 1977 // INTERNAL variable that's invisible to the debugger 1978 // but visible to everything else. 1979 Declaration* tdz_decl = 1980 DeclareVariable(for_info.bound_names[i], VariableMode::kLet, 1981 kNoSourcePosition, CHECK_OK); 1982 tdz_decl->proxy()->var()->set_initializer_position(position()); 1983 } 1984 } 1985 return init_block; 1986 } 1987 1988 Statement* Parser::InitializeForOfStatement( 1989 ForOfStatement* for_of, Expression* each, Expression* iterable, 1990 Statement* body, bool finalize, IteratorType type, int next_result_pos) { 1991 // Create the auxiliary expressions needed for iterating over the iterable, 1992 // and initialize the given ForOfStatement with them. 1993 // If finalize is true, also instrument the loop with code that performs the 1994 // proper ES6 iterator finalization. In that case, the result is not 1995 // immediately a ForOfStatement. 1996 const int nopos = kNoSourcePosition; 1997 auto avfactory = ast_value_factory(); 1998 1999 Variable* iterator = NewTemporary(avfactory->dot_iterator_string()); 2000 Variable* next = NewTemporary(avfactory->empty_string()); 2001 Variable* result = NewTemporary(avfactory->dot_result_string()); 2002 Variable* completion = NewTemporary(avfactory->empty_string()); 2003 2004 // iterator = GetIterator(iterable, type) 2005 Expression* assign_iterator; 2006 { 2007 assign_iterator = factory()->NewAssignment( 2008 Token::ASSIGN, factory()->NewVariableProxy(iterator), 2009 factory()->NewGetIterator(iterable, type, iterable->position()), 2010 iterable->position()); 2011 } 2012 2013 Expression* assign_next; 2014 { 2015 assign_next = factory()->NewAssignment( 2016 Token::ASSIGN, factory()->NewVariableProxy(next), 2017 factory()->NewProperty(factory()->NewVariableProxy(iterator), 2018 factory()->NewStringLiteral( 2019 avfactory->next_string(), kNoSourcePosition), 2020 kNoSourcePosition), 2021 kNoSourcePosition); 2022 } 2023 2024 // [if (IteratorType == kNormal)] 2025 // !%_IsJSReceiver(result = iterator.next()) && 2026 // %ThrowIteratorResultNotAnObject(result) 2027 // [else if (IteratorType == kAsync)] 2028 // !%_IsJSReceiver(result = Await(iterator.next())) && 2029 // %ThrowIteratorResultNotAnObject(result) 2030 // [endif] 2031 Expression* next_result; 2032 { 2033 VariableProxy* iterator_proxy = factory()->NewVariableProxy(iterator); 2034 VariableProxy* next_proxy = factory()->NewVariableProxy(next); 2035 next_result = BuildIteratorNextResult(iterator_proxy, next_proxy, result, 2036 type, next_result_pos); 2037 } 2038 2039 // result.done 2040 Expression* result_done; 2041 { 2042 Expression* done_literal = factory()->NewStringLiteral( 2043 ast_value_factory()->done_string(), kNoSourcePosition); 2044 Expression* result_proxy = factory()->NewVariableProxy(result); 2045 result_done = 2046 factory()->NewProperty(result_proxy, done_literal, kNoSourcePosition); 2047 } 2048 2049 // result.value 2050 Expression* result_value; 2051 { 2052 Expression* value_literal = 2053 factory()->NewStringLiteral(avfactory->value_string(), nopos); 2054 Expression* result_proxy = factory()->NewVariableProxy(result); 2055 result_value = factory()->NewProperty(result_proxy, value_literal, nopos); 2056 } 2057 2058 // {{tmp = #result_value, completion = kAbruptCompletion, tmp}} 2059 // Expression* result_value (gets overwritten) 2060 if (finalize) { 2061 Variable* tmp = NewTemporary(avfactory->empty_string()); 2062 Expression* save_result = factory()->NewAssignment( 2063 Token::ASSIGN, factory()->NewVariableProxy(tmp), result_value, nopos); 2064 2065 Expression* set_completion_abrupt = factory()->NewAssignment( 2066 Token::ASSIGN, factory()->NewVariableProxy(completion), 2067 factory()->NewSmiLiteral(Parser::kAbruptCompletion, nopos), nopos); 2068 2069 result_value = factory()->NewBinaryOperation(Token::COMMA, save_result, 2070 set_completion_abrupt, nopos); 2071 result_value = factory()->NewBinaryOperation( 2072 Token::COMMA, result_value, factory()->NewVariableProxy(tmp), nopos); 2073 } 2074 2075 // each = #result_value; 2076 Expression* assign_each; 2077 { 2078 assign_each = 2079 factory()->NewAssignment(Token::ASSIGN, each, result_value, nopos); 2080 if (each->IsArrayLiteral() || each->IsObjectLiteral()) { 2081 assign_each = RewriteDestructuringAssignment(assign_each->AsAssignment()); 2082 } 2083 } 2084 2085 // {{completion = kNormalCompletion;}} 2086 Statement* set_completion_normal; 2087 if (finalize) { 2088 Expression* proxy = factory()->NewVariableProxy(completion); 2089 Expression* assignment = factory()->NewAssignment( 2090 Token::ASSIGN, proxy, 2091 factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos); 2092 2093 set_completion_normal = 2094 IgnoreCompletion(factory()->NewExpressionStatement(assignment, nopos)); 2095 } 2096 2097 // { #loop-body; #set_completion_normal } 2098 // Statement* body (gets overwritten) 2099 if (finalize) { 2100 Block* block = factory()->NewBlock(2, false); 2101 block->statements()->Add(body, zone()); 2102 block->statements()->Add(set_completion_normal, zone()); 2103 body = block; 2104 } 2105 2106 for_of->Initialize(body, iterator, assign_iterator, assign_next, next_result, 2107 result_done, assign_each); 2108 return finalize ? FinalizeForOfStatement(for_of, completion, type, nopos) 2109 : for_of; 2110 } 2111 2112 Statement* Parser::DesugarLexicalBindingsInForStatement( 2113 ForStatement* loop, Statement* init, Expression* cond, Statement* next, 2114 Statement* body, Scope* inner_scope, const ForInfo& for_info, bool* ok) { 2115 // ES6 13.7.4.8 specifies that on each loop iteration the let variables are 2116 // copied into a new environment. Moreover, the "next" statement must be 2117 // evaluated not in the environment of the just completed iteration but in 2118 // that of the upcoming one. We achieve this with the following desugaring. 2119 // Extra care is needed to preserve the completion value of the original loop. 2120 // 2121 // We are given a for statement of the form 2122 // 2123 // labels: for (let/const x = i; cond; next) body 2124 // 2125 // and rewrite it as follows. Here we write {{ ... }} for init-blocks, ie., 2126 // blocks whose ignore_completion_value_ flag is set. 2127 // 2128 // { 2129 // let/const x = i; 2130 // temp_x = x; 2131 // first = 1; 2132 // undefined; 2133 // outer: for (;;) { 2134 // let/const x = temp_x; 2135 // {{ if (first == 1) { 2136 // first = 0; 2137 // } else { 2138 // next; 2139 // } 2140 // flag = 1; 2141 // if (!cond) break; 2142 // }} 2143 // labels: for (; flag == 1; flag = 0, temp_x = x) { 2144 // body 2145 // } 2146 // {{ if (flag == 1) // Body used break. 2147 // break; 2148 // }} 2149 // } 2150 // } 2151 2152 DCHECK_GT(for_info.bound_names.length(), 0); 2153 ZonePtrList<Variable> temps(for_info.bound_names.length(), zone()); 2154 2155 Block* outer_block = 2156 factory()->NewBlock(for_info.bound_names.length() + 4, false); 2157 2158 // Add statement: let/const x = i. 2159 outer_block->statements()->Add(init, zone()); 2160 2161 const AstRawString* temp_name = ast_value_factory()->dot_for_string(); 2162 2163 // For each lexical variable x: 2164 // make statement: temp_x = x. 2165 for (int i = 0; i < for_info.bound_names.length(); i++) { 2166 VariableProxy* proxy = NewUnresolved(for_info.bound_names[i]); 2167 Variable* temp = NewTemporary(temp_name); 2168 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); 2169 Assignment* assignment = factory()->NewAssignment(Token::ASSIGN, temp_proxy, 2170 proxy, kNoSourcePosition); 2171 Statement* assignment_statement = 2172 factory()->NewExpressionStatement(assignment, kNoSourcePosition); 2173 outer_block->statements()->Add(assignment_statement, zone()); 2174 temps.Add(temp, zone()); 2175 } 2176 2177 Variable* first = nullptr; 2178 // Make statement: first = 1. 2179 if (next) { 2180 first = NewTemporary(temp_name); 2181 VariableProxy* first_proxy = factory()->NewVariableProxy(first); 2182 Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition); 2183 Assignment* assignment = factory()->NewAssignment( 2184 Token::ASSIGN, first_proxy, const1, kNoSourcePosition); 2185 Statement* assignment_statement = 2186 factory()->NewExpressionStatement(assignment, kNoSourcePosition); 2187 outer_block->statements()->Add(assignment_statement, zone()); 2188 } 2189 2190 // make statement: undefined; 2191 outer_block->statements()->Add( 2192 factory()->NewExpressionStatement( 2193 factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition), 2194 zone()); 2195 2196 // Make statement: outer: for (;;) 2197 // Note that we don't actually create the label, or set this loop up as an 2198 // explicit break target, instead handing it directly to those nodes that 2199 // need to know about it. This should be safe because we don't run any code 2200 // in this function that looks up break targets. 2201 ForStatement* outer_loop = 2202 factory()->NewForStatement(nullptr, nullptr, kNoSourcePosition); 2203 outer_block->statements()->Add(outer_loop, zone()); 2204 outer_block->set_scope(scope()); 2205 2206 Block* inner_block = factory()->NewBlock(3, false); 2207 { 2208 BlockState block_state(&scope_, inner_scope); 2209 2210 Block* ignore_completion_block = 2211 factory()->NewBlock(for_info.bound_names.length() + 3, true); 2212 ZonePtrList<Variable> inner_vars(for_info.bound_names.length(), zone()); 2213 // For each let variable x: 2214 // make statement: let/const x = temp_x. 2215 for (int i = 0; i < for_info.bound_names.length(); i++) { 2216 Declaration* decl = DeclareVariable( 2217 for_info.bound_names[i], for_info.parsing_result.descriptor.mode, 2218 kNoSourcePosition, CHECK_OK); 2219 inner_vars.Add(decl->proxy()->var(), zone()); 2220 VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i)); 2221 Assignment* assignment = factory()->NewAssignment( 2222 Token::INIT, decl->proxy(), temp_proxy, kNoSourcePosition); 2223 Statement* assignment_statement = 2224 factory()->NewExpressionStatement(assignment, kNoSourcePosition); 2225 int declaration_pos = for_info.parsing_result.descriptor.declaration_pos; 2226 DCHECK_NE(declaration_pos, kNoSourcePosition); 2227 decl->proxy()->var()->set_initializer_position(declaration_pos); 2228 ignore_completion_block->statements()->Add(assignment_statement, zone()); 2229 } 2230 2231 // Make statement: if (first == 1) { first = 0; } else { next; } 2232 if (next) { 2233 DCHECK(first); 2234 Expression* compare = nullptr; 2235 // Make compare expression: first == 1. 2236 { 2237 Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition); 2238 VariableProxy* first_proxy = factory()->NewVariableProxy(first); 2239 compare = factory()->NewCompareOperation(Token::EQ, first_proxy, const1, 2240 kNoSourcePosition); 2241 } 2242 Statement* clear_first = nullptr; 2243 // Make statement: first = 0. 2244 { 2245 VariableProxy* first_proxy = factory()->NewVariableProxy(first); 2246 Expression* const0 = factory()->NewSmiLiteral(0, kNoSourcePosition); 2247 Assignment* assignment = factory()->NewAssignment( 2248 Token::ASSIGN, first_proxy, const0, kNoSourcePosition); 2249 clear_first = 2250 factory()->NewExpressionStatement(assignment, kNoSourcePosition); 2251 } 2252 Statement* clear_first_or_next = factory()->NewIfStatement( 2253 compare, clear_first, next, kNoSourcePosition); 2254 ignore_completion_block->statements()->Add(clear_first_or_next, zone()); 2255 } 2256 2257 Variable* flag = NewTemporary(temp_name); 2258 // Make statement: flag = 1. 2259 { 2260 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag); 2261 Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition); 2262 Assignment* assignment = factory()->NewAssignment( 2263 Token::ASSIGN, flag_proxy, const1, kNoSourcePosition); 2264 Statement* assignment_statement = 2265 factory()->NewExpressionStatement(assignment, kNoSourcePosition); 2266 ignore_completion_block->statements()->Add(assignment_statement, zone()); 2267 } 2268 2269 // Make statement: if (!cond) break. 2270 if (cond) { 2271 Statement* stop = 2272 factory()->NewBreakStatement(outer_loop, kNoSourcePosition); 2273 Statement* noop = factory()->NewEmptyStatement(kNoSourcePosition); 2274 ignore_completion_block->statements()->Add( 2275 factory()->NewIfStatement(cond, noop, stop, cond->position()), 2276 zone()); 2277 } 2278 2279 inner_block->statements()->Add(ignore_completion_block, zone()); 2280 // Make cond expression for main loop: flag == 1. 2281 Expression* flag_cond = nullptr; 2282 { 2283 Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition); 2284 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag); 2285 flag_cond = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1, 2286 kNoSourcePosition); 2287 } 2288 2289 // Create chain of expressions "flag = 0, temp_x = x, ..." 2290 Statement* compound_next_statement = nullptr; 2291 { 2292 Expression* compound_next = nullptr; 2293 // Make expression: flag = 0. 2294 { 2295 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag); 2296 Expression* const0 = factory()->NewSmiLiteral(0, kNoSourcePosition); 2297 compound_next = factory()->NewAssignment(Token::ASSIGN, flag_proxy, 2298 const0, kNoSourcePosition); 2299 } 2300 2301 // Make the comma-separated list of temp_x = x assignments. 2302 int inner_var_proxy_pos = scanner()->location().beg_pos; 2303 for (int i = 0; i < for_info.bound_names.length(); i++) { 2304 VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i)); 2305 VariableProxy* proxy = 2306 factory()->NewVariableProxy(inner_vars.at(i), inner_var_proxy_pos); 2307 Assignment* assignment = factory()->NewAssignment( 2308 Token::ASSIGN, temp_proxy, proxy, kNoSourcePosition); 2309 compound_next = factory()->NewBinaryOperation( 2310 Token::COMMA, compound_next, assignment, kNoSourcePosition); 2311 } 2312 2313 compound_next_statement = 2314 factory()->NewExpressionStatement(compound_next, kNoSourcePosition); 2315 } 2316 2317 // Make statement: labels: for (; flag == 1; flag = 0, temp_x = x) 2318 // Note that we re-use the original loop node, which retains its labels 2319 // and ensures that any break or continue statements in body point to 2320 // the right place. 2321 loop->Initialize(nullptr, flag_cond, compound_next_statement, body); 2322 inner_block->statements()->Add(loop, zone()); 2323 2324 // Make statement: {{if (flag == 1) break;}} 2325 { 2326 Expression* compare = nullptr; 2327 // Make compare expresion: flag == 1. 2328 { 2329 Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition); 2330 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag); 2331 compare = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1, 2332 kNoSourcePosition); 2333 } 2334 Statement* stop = 2335 factory()->NewBreakStatement(outer_loop, kNoSourcePosition); 2336 Statement* empty = factory()->NewEmptyStatement(kNoSourcePosition); 2337 Statement* if_flag_break = 2338 factory()->NewIfStatement(compare, stop, empty, kNoSourcePosition); 2339 inner_block->statements()->Add(IgnoreCompletion(if_flag_break), zone()); 2340 } 2341 2342 inner_block->set_scope(inner_scope); 2343 } 2344 2345 outer_loop->Initialize(nullptr, nullptr, nullptr, inner_block); 2346 2347 return outer_block; 2348 } 2349 2350 void Parser::AddArrowFunctionFormalParameters( 2351 ParserFormalParameters* parameters, Expression* expr, int end_pos, 2352 bool* ok) { 2353 // ArrowFunctionFormals :: 2354 // Nary(Token::COMMA, VariableProxy*, Tail) 2355 // Binary(Token::COMMA, NonTailArrowFunctionFormals, Tail) 2356 // Tail 2357 // NonTailArrowFunctionFormals :: 2358 // Binary(Token::COMMA, NonTailArrowFunctionFormals, VariableProxy) 2359 // VariableProxy 2360 // Tail :: 2361 // VariableProxy 2362 // Spread(VariableProxy) 2363 // 2364 // We need to visit the parameters in left-to-right order 2365 // 2366 2367 // For the Nary case, we simply visit the parameters in a loop. 2368 if (expr->IsNaryOperation()) { 2369 NaryOperation* nary = expr->AsNaryOperation(); 2370 // The classifier has already run, so we know that the expression is a valid 2371 // arrow function formals production. 2372 DCHECK_EQ(nary->op(), Token::COMMA); 2373 // Each op position is the end position of the *previous* expr, with the 2374 // second (i.e. first "subsequent") op position being the end position of 2375 // the first child expression. 2376 Expression* next = nary->first(); 2377 for (size_t i = 0; i < nary->subsequent_length(); ++i) { 2378 AddArrowFunctionFormalParameters( 2379 parameters, next, nary->subsequent_op_position(i), CHECK_OK_VOID); 2380 next = nary->subsequent(i); 2381 } 2382 AddArrowFunctionFormalParameters(parameters, next, end_pos, CHECK_OK_VOID); 2383 return; 2384 } 2385 2386 // For the binary case, we recurse on the left-hand side of binary comma 2387 // expressions. 2388 if (expr->IsBinaryOperation()) { 2389 BinaryOperation* binop = expr->AsBinaryOperation(); 2390 // The classifier has already run, so we know that the expression is a valid 2391 // arrow function formals production. 2392 DCHECK_EQ(binop->op(), Token::COMMA); 2393 Expression* left = binop->left(); 2394 Expression* right = binop->right(); 2395 int comma_pos = binop->position(); 2396 AddArrowFunctionFormalParameters(parameters, left, comma_pos, 2397 CHECK_OK_VOID); 2398 // LHS of comma expression should be unparenthesized. 2399 expr = right; 2400 } 2401 2402 // Only the right-most expression may be a rest parameter. 2403 DCHECK(!parameters->has_rest); 2404 2405 bool is_rest = expr->IsSpread(); 2406 if (is_rest) { 2407 expr = expr->AsSpread()->expression(); 2408 parameters->has_rest = true; 2409 } 2410 DCHECK_IMPLIES(parameters->is_simple, !is_rest); 2411 DCHECK_IMPLIES(parameters->is_simple, expr->IsVariableProxy()); 2412 2413 Expression* initializer = nullptr; 2414 if (expr->IsAssignment()) { 2415 if (expr->IsRewritableExpression()) { 2416 // This expression was parsed as a possible destructuring assignment. 2417 // Mark it as already-rewritten to avoid an unnecessary visit later. 2418 expr->AsRewritableExpression()->set_rewritten(); 2419 } 2420 Assignment* assignment = expr->AsAssignment(); 2421 DCHECK(!assignment->IsCompoundAssignment()); 2422 initializer = assignment->value(); 2423 expr = assignment->target(); 2424 } 2425 2426 AddFormalParameter(parameters, expr, initializer, 2427 end_pos, is_rest); 2428 } 2429 2430 void Parser::DeclareArrowFunctionFormalParameters( 2431 ParserFormalParameters* parameters, Expression* expr, 2432 const Scanner::Location& params_loc, Scanner::Location* duplicate_loc, 2433 bool* ok) { 2434 if (expr->IsEmptyParentheses()) return; 2435 2436 AddArrowFunctionFormalParameters(parameters, expr, params_loc.end_pos, 2437 CHECK_OK_VOID); 2438 2439 if (parameters->arity > Code::kMaxArguments) { 2440 ReportMessageAt(params_loc, MessageTemplate::kMalformedArrowFunParamList); 2441 *ok = false; 2442 return; 2443 } 2444 2445 bool has_duplicate = false; 2446 DeclareFormalParameters(parameters->scope, parameters->params, 2447 parameters->is_simple, &has_duplicate); 2448 if (has_duplicate) { 2449 *duplicate_loc = scanner()->location(); 2450 } 2451 DCHECK_EQ(parameters->is_simple, parameters->scope->has_simple_parameters()); 2452 } 2453 2454 void Parser::PrepareGeneratorVariables() { 2455 // Calling a generator returns a generator object. That object is stored 2456 // in a temporary variable, a definition that is used by "yield" 2457 // expressions. 2458 function_state_->scope()->DeclareGeneratorObjectVar( 2459 ast_value_factory()->dot_generator_object_string()); 2460 } 2461 2462 FunctionLiteral* Parser::ParseFunctionLiteral( 2463 const AstRawString* function_name, Scanner::Location function_name_location, 2464 FunctionNameValidity function_name_validity, FunctionKind kind, 2465 int function_token_pos, FunctionLiteral::FunctionType function_type, 2466 LanguageMode language_mode, 2467 ZonePtrList<const AstRawString>* arguments_for_wrapped_function, bool* ok) { 2468 // Function :: 2469 // '(' FormalParameterList? ')' '{' FunctionBody '}' 2470 // 2471 // Getter :: 2472 // '(' ')' '{' FunctionBody '}' 2473 // 2474 // Setter :: 2475 // '(' PropertySetParameterList ')' '{' FunctionBody '}' 2476 2477 bool is_wrapped = function_type == FunctionLiteral::kWrapped; 2478 DCHECK_EQ(is_wrapped, arguments_for_wrapped_function != nullptr); 2479 2480 int pos = function_token_pos == kNoSourcePosition ? peek_position() 2481 : function_token_pos; 2482 DCHECK_NE(kNoSourcePosition, pos); 2483 2484 // Anonymous functions were passed either the empty symbol or a null 2485 // handle as the function name. Remember if we were passed a non-empty 2486 // handle to decide whether to invoke function name inference. 2487 bool should_infer_name = function_name == nullptr; 2488 2489 // We want a non-null handle as the function name by default. We will handle 2490 // the "function does not have a shared name" case later. 2491 if (should_infer_name) { 2492 function_name = ast_value_factory()->empty_string(); 2493 } 2494 2495 FunctionLiteral::EagerCompileHint eager_compile_hint = 2496 function_state_->next_function_is_likely_called() || is_wrapped 2497 ? FunctionLiteral::kShouldEagerCompile 2498 : default_eager_compile_hint(); 2499 2500 // Determine if the function can be parsed lazily. Lazy parsing is 2501 // different from lazy compilation; we need to parse more eagerly than we 2502 // compile. 2503 2504 // We can only parse lazily if we also compile lazily. The heuristics for lazy 2505 // compilation are: 2506 // - It must not have been prohibited by the caller to Parse (some callers 2507 // need a full AST). 2508 // - The outer scope must allow lazy compilation of inner functions. 2509 // - The function mustn't be a function expression with an open parenthesis 2510 // before; we consider that a hint that the function will be called 2511 // immediately, and it would be a waste of time to make it lazily 2512 // compiled. 2513 // These are all things we can know at this point, without looking at the 2514 // function itself. 2515 2516 // We separate between lazy parsing top level functions and lazy parsing inner 2517 // functions, because the latter needs to do more work. In particular, we need 2518 // to track unresolved variables to distinguish between these cases: 2519 // (function foo() { 2520 // bar = function() { return 1; } 2521 // })(); 2522 // and 2523 // (function foo() { 2524 // var a = 1; 2525 // bar = function() { return a; } 2526 // })(); 2527 2528 // Now foo will be parsed eagerly and compiled eagerly (optimization: assume 2529 // parenthesis before the function means that it will be called 2530 // immediately). bar can be parsed lazily, but we need to parse it in a mode 2531 // that tracks unresolved variables. 2532 DCHECK_IMPLIES(parse_lazily(), FLAG_lazy); 2533 DCHECK_IMPLIES(parse_lazily(), allow_lazy_); 2534 DCHECK_IMPLIES(parse_lazily(), extension_ == nullptr); 2535 2536 const bool is_lazy = 2537 eager_compile_hint == FunctionLiteral::kShouldLazyCompile; 2538 const bool is_top_level = AllowsLazyParsingWithoutUnresolvedVariables(); 2539 const bool is_lazy_top_level_function = is_lazy && is_top_level; 2540 const bool is_lazy_inner_function = is_lazy && !is_top_level; 2541 const bool is_expression = 2542 function_type == FunctionLiteral::kAnonymousExpression || 2543 function_type == FunctionLiteral::kNamedExpression; 2544 2545 RuntimeCallTimerScope runtime_timer( 2546 runtime_call_stats_, 2547 parsing_on_main_thread_ 2548 ? RuntimeCallCounterId::kParseFunctionLiteral 2549 : RuntimeCallCounterId::kParseBackgroundFunctionLiteral); 2550 base::ElapsedTimer timer; 2551 if (V8_UNLIKELY(FLAG_log_function_events)) timer.Start(); 2552 2553 // Determine whether we can still lazy parse the inner function. 2554 // The preconditions are: 2555 // - Lazy compilation has to be enabled. 2556 // - Neither V8 natives nor native function declarations can be allowed, 2557 // since parsing one would retroactively force the function to be 2558 // eagerly compiled. 2559 // - The invoker of this parser can't depend on the AST being eagerly 2560 // built (either because the function is about to be compiled, or 2561 // because the AST is going to be inspected for some reason). 2562 // - Because of the above, we can't be attempting to parse a 2563 // FunctionExpression; even without enclosing parentheses it might be 2564 // immediately invoked. 2565 // - The function literal shouldn't be hinted to eagerly compile. 2566 2567 // Inner functions will be parsed using a temporary Zone. After parsing, we 2568 // will migrate unresolved variable into a Scope in the main Zone. 2569 2570 const bool should_preparse_inner = 2571 parse_lazily() && FLAG_lazy_inner_functions && is_lazy_inner_function && 2572 (!is_expression || FLAG_aggressive_lazy_inner_functions); 2573 2574 // This may be modified later to reflect preparsing decision taken 2575 bool should_preparse = 2576 (parse_lazily() && is_lazy_top_level_function) || should_preparse_inner; 2577 2578 ZonePtrList<Statement>* body = nullptr; 2579 int expected_property_count = -1; 2580 int suspend_count = -1; 2581 int num_parameters = -1; 2582 int function_length = -1; 2583 bool has_duplicate_parameters = false; 2584 int function_literal_id = GetNextFunctionLiteralId(); 2585 ProducedPreParsedScopeData* produced_preparsed_scope_data = nullptr; 2586 2587 Zone* outer_zone = zone(); 2588 DeclarationScope* scope; 2589 2590 { 2591 // Temporary zones can nest. When we migrate free variables (see below), we 2592 // need to recreate them in the previous Zone. 2593 AstNodeFactory previous_zone_ast_node_factory(ast_value_factory(), zone()); 2594 2595 // Open a new zone scope, which sets our AstNodeFactory to allocate in the 2596 // new temporary zone if the preconditions are satisfied, and ensures that 2597 // the previous zone is always restored after parsing the body. To be able 2598 // to do scope analysis correctly after full parsing, we migrate needed 2599 // information when the function is parsed. 2600 Zone temp_zone(zone()->allocator(), ZONE_NAME); 2601 DiscardableZoneScope zone_scope(this, &temp_zone, should_preparse); 2602 2603 // This Scope lives in the main zone. We'll migrate data into that zone 2604 // later. 2605 scope = NewFunctionScope(kind, outer_zone); 2606 SetLanguageMode(scope, language_mode); 2607 #ifdef DEBUG 2608 scope->SetScopeName(function_name); 2609 if (should_preparse) scope->set_needs_migration(); 2610 #endif 2611 2612 if (!is_wrapped) Expect(Token::LPAREN, CHECK_OK); 2613 scope->set_start_position(scanner()->location().beg_pos); 2614 2615 // Eager or lazy parse? If is_lazy_top_level_function, we'll parse 2616 // lazily. We'll call SkipFunction, which may decide to 2617 // abort lazy parsing if it suspects that wasn't a good idea. If so (in 2618 // which case the parser is expected to have backtracked), or if we didn't 2619 // try to lazy parse in the first place, we'll have to parse eagerly. 2620 if (should_preparse) { 2621 DCHECK(parse_lazily()); 2622 DCHECK(is_lazy_top_level_function || is_lazy_inner_function); 2623 DCHECK(!is_wrapped); 2624 Scanner::BookmarkScope bookmark(scanner()); 2625 bookmark.Set(); 2626 LazyParsingResult result = SkipFunction( 2627 function_name, kind, function_type, scope, &num_parameters, 2628 &produced_preparsed_scope_data, is_lazy_inner_function, 2629 is_lazy_top_level_function, CHECK_OK); 2630 2631 if (result == kLazyParsingAborted) { 2632 DCHECK(is_lazy_top_level_function); 2633 bookmark.Apply(); 2634 // This is probably an initialization function. Inform the compiler it 2635 // should also eager-compile this function. 2636 eager_compile_hint = FunctionLiteral::kShouldEagerCompile; 2637 scope->ResetAfterPreparsing(ast_value_factory(), true); 2638 zone_scope.Reset(); 2639 // Trigger eager (re-)parsing, just below this block. 2640 should_preparse = false; 2641 } 2642 } 2643 2644 if (should_preparse) { 2645 scope->AnalyzePartially(&previous_zone_ast_node_factory); 2646 } else { 2647 body = ParseFunction( 2648 function_name, pos, kind, function_type, scope, &num_parameters, 2649 &function_length, &has_duplicate_parameters, &expected_property_count, 2650 &suspend_count, arguments_for_wrapped_function, CHECK_OK); 2651 } 2652 2653 DCHECK_EQ(should_preparse, temp_zoned_); 2654 if (V8_UNLIKELY(FLAG_log_function_events)) { 2655 double ms = timer.Elapsed().InMillisecondsF(); 2656 const char* event_name = should_preparse 2657 ? (is_top_level ? "preparse-no-resolution" 2658 : "preparse-resolution") 2659 : "full-parse"; 2660 logger_->FunctionEvent( 2661 event_name, script_id(), ms, scope->start_position(), 2662 scope->end_position(), 2663 reinterpret_cast<const char*>(function_name->raw_data()), 2664 function_name->byte_length()); 2665 } 2666 if (V8_UNLIKELY(FLAG_runtime_stats)) { 2667 if (should_preparse) { 2668 RuntimeCallCounterId counter_id = 2669 parsing_on_main_thread_ 2670 ? RuntimeCallCounterId::kPreParseWithVariableResolution 2671 : RuntimeCallCounterId:: 2672 kPreParseBackgroundWithVariableResolution; 2673 if (is_top_level) { 2674 counter_id = parsing_on_main_thread_ 2675 ? RuntimeCallCounterId::kPreParseNoVariableResolution 2676 : RuntimeCallCounterId:: 2677 kPreParseBackgroundNoVariableResolution; 2678 } 2679 if (runtime_call_stats_) { 2680 runtime_call_stats_->CorrectCurrentCounterId(counter_id); 2681 } 2682 } 2683 } 2684 2685 // Validate function name. We can do this only after parsing the function, 2686 // since the function can declare itself strict. 2687 language_mode = scope->language_mode(); 2688 CheckFunctionName(language_mode, function_name, function_name_validity, 2689 function_name_location, CHECK_OK); 2690 2691 if (is_strict(language_mode)) { 2692 CheckStrictOctalLiteral(scope->start_position(), scope->end_position(), 2693 CHECK_OK); 2694 } 2695 CheckConflictingVarDeclarations(scope, CHECK_OK); 2696 } // DiscardableZoneScope goes out of scope. 2697 2698 FunctionLiteral::ParameterFlag duplicate_parameters = 2699 has_duplicate_parameters ? FunctionLiteral::kHasDuplicateParameters 2700 : FunctionLiteral::kNoDuplicateParameters; 2701 2702 // Note that the FunctionLiteral needs to be created in the main Zone again. 2703 FunctionLiteral* function_literal = factory()->NewFunctionLiteral( 2704 function_name, scope, body, expected_property_count, num_parameters, 2705 function_length, duplicate_parameters, function_type, eager_compile_hint, 2706 pos, true, function_literal_id, produced_preparsed_scope_data); 2707 function_literal->set_function_token_position(function_token_pos); 2708 function_literal->set_suspend_count(suspend_count); 2709 2710 if (should_infer_name) { 2711 DCHECK_NOT_NULL(fni_); 2712 fni_->AddFunction(function_literal); 2713 } 2714 return function_literal; 2715 } 2716 2717 Parser::LazyParsingResult Parser::SkipFunction( 2718 const AstRawString* function_name, FunctionKind kind, 2719 FunctionLiteral::FunctionType function_type, 2720 DeclarationScope* function_scope, int* num_parameters, 2721 ProducedPreParsedScopeData** produced_preparsed_scope_data, 2722 bool is_inner_function, bool may_abort, bool* ok) { 2723 FunctionState function_state(&function_state_, &scope_, function_scope); 2724 2725 DCHECK_NE(kNoSourcePosition, function_scope->start_position()); 2726 DCHECK_EQ(kNoSourcePosition, parameters_end_pos_); 2727 2728 DCHECK_IMPLIES(IsArrowFunction(kind), 2729 scanner()->current_token() == Token::ARROW); 2730 2731 // FIXME(marja): There are 2 ways to skip functions now. Unify them. 2732 DCHECK_NOT_NULL(consumed_preparsed_scope_data_); 2733 if (consumed_preparsed_scope_data_->HasData()) { 2734 DCHECK(FLAG_preparser_scope_analysis); 2735 int end_position; 2736 LanguageMode language_mode; 2737 int num_inner_functions; 2738 bool uses_super_property; 2739 *produced_preparsed_scope_data = 2740 consumed_preparsed_scope_data_->GetDataForSkippableFunction( 2741 main_zone(), function_scope->start_position(), &end_position, 2742 num_parameters, &num_inner_functions, &uses_super_property, 2743 &language_mode); 2744 2745 function_scope->outer_scope()->SetMustUsePreParsedScopeData(); 2746 function_scope->set_is_skipped_function(true); 2747 function_scope->set_end_position(end_position); 2748 scanner()->SeekForward(end_position - 1); 2749 Expect(Token::RBRACE, CHECK_OK_VALUE(kLazyParsingComplete)); 2750 SetLanguageMode(function_scope, language_mode); 2751 if (uses_super_property) { 2752 function_scope->RecordSuperPropertyUsage(); 2753 } 2754 SkipFunctionLiterals(num_inner_functions); 2755 return kLazyParsingComplete; 2756 } 2757 2758 // With no cached data, we partially parse the function, without building an 2759 // AST. This gathers the data needed to build a lazy function. 2760 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.PreParse"); 2761 2762 // Aborting inner function preparsing would leave scopes in an inconsistent 2763 // state; we don't parse inner functions in the abortable mode anyway. 2764 DCHECK(!is_inner_function || !may_abort); 2765 2766 PreParser::PreParseResult result = reusable_preparser()->PreParseFunction( 2767 function_name, kind, function_type, function_scope, is_inner_function, 2768 may_abort, use_counts_, produced_preparsed_scope_data, this->script_id()); 2769 2770 // Return immediately if pre-parser decided to abort parsing. 2771 if (result == PreParser::kPreParseAbort) return kLazyParsingAborted; 2772 if (result == PreParser::kPreParseStackOverflow) { 2773 // Propagate stack overflow. 2774 set_stack_overflow(); 2775 *ok = false; 2776 return kLazyParsingComplete; 2777 } 2778 if (pending_error_handler()->has_pending_error()) { 2779 *ok = false; 2780 return kLazyParsingComplete; 2781 } 2782 2783 set_allow_eval_cache(reusable_preparser()->allow_eval_cache()); 2784 2785 PreParserLogger* logger = reusable_preparser()->logger(); 2786 function_scope->set_end_position(logger->end()); 2787 Expect(Token::RBRACE, CHECK_OK_VALUE(kLazyParsingComplete)); 2788 total_preparse_skipped_ += 2789 function_scope->end_position() - function_scope->start_position(); 2790 *num_parameters = logger->num_parameters(); 2791 SkipFunctionLiterals(logger->num_inner_functions()); 2792 return kLazyParsingComplete; 2793 } 2794 2795 Statement* Parser::BuildAssertIsCoercible(Variable* var, 2796 ObjectLiteral* pattern) { 2797 // if (var === null || var === undefined) 2798 // throw /* type error kNonCoercible) */; 2799 auto source_position = pattern->position(); 2800 const AstRawString* property = ast_value_factory()->empty_string(); 2801 MessageTemplate::Template msg = MessageTemplate::kNonCoercible; 2802 for (ObjectLiteralProperty* literal_property : *pattern->properties()) { 2803 Expression* key = literal_property->key(); 2804 if (key->IsPropertyName()) { 2805 property = key->AsLiteral()->AsRawPropertyName(); 2806 msg = MessageTemplate::kNonCoercibleWithProperty; 2807 source_position = key->position(); 2808 break; 2809 } 2810 } 2811 2812 Expression* condition = factory()->NewBinaryOperation( 2813 Token::OR, 2814 factory()->NewCompareOperation( 2815 Token::EQ_STRICT, factory()->NewVariableProxy(var), 2816 factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition), 2817 factory()->NewCompareOperation( 2818 Token::EQ_STRICT, factory()->NewVariableProxy(var), 2819 factory()->NewNullLiteral(kNoSourcePosition), kNoSourcePosition), 2820 kNoSourcePosition); 2821 Expression* throw_type_error = 2822 NewThrowTypeError(msg, property, source_position); 2823 IfStatement* if_statement = factory()->NewIfStatement( 2824 condition, 2825 factory()->NewExpressionStatement(throw_type_error, kNoSourcePosition), 2826 factory()->NewEmptyStatement(kNoSourcePosition), kNoSourcePosition); 2827 return if_statement; 2828 } 2829 2830 class InitializerRewriter final 2831 : public AstTraversalVisitor<InitializerRewriter> { 2832 public: 2833 InitializerRewriter(uintptr_t stack_limit, Expression* root, Parser* parser) 2834 : AstTraversalVisitor(stack_limit, root), parser_(parser) {} 2835 2836 private: 2837 // This is required so that the overriden Visit* methods can be 2838 // called by the base class (template). 2839 friend class AstTraversalVisitor<InitializerRewriter>; 2840 2841 // Just rewrite destructuring assignments wrapped in RewritableExpressions. 2842 void VisitRewritableExpression(RewritableExpression* to_rewrite) { 2843 if (to_rewrite->is_rewritten()) return; 2844 parser_->RewriteDestructuringAssignment(to_rewrite); 2845 AstTraversalVisitor::VisitRewritableExpression(to_rewrite); 2846 } 2847 2848 // Code in function literals does not need to be eagerly rewritten, it will be 2849 // rewritten when scheduled. 2850 void VisitFunctionLiteral(FunctionLiteral* expr) {} 2851 2852 Parser* parser_; 2853 }; 2854 2855 void Parser::RewriteParameterInitializer(Expression* expr) { 2856 InitializerRewriter rewriter(stack_limit_, expr, this); 2857 rewriter.Run(); 2858 } 2859 2860 2861 Block* Parser::BuildParameterInitializationBlock( 2862 const ParserFormalParameters& parameters, bool* ok) { 2863 DCHECK(!parameters.is_simple); 2864 DCHECK(scope()->is_function_scope()); 2865 DCHECK_EQ(scope(), parameters.scope); 2866 Block* init_block = factory()->NewBlock(1, true); 2867 int index = 0; 2868 for (auto parameter : parameters.params) { 2869 DeclarationDescriptor descriptor; 2870 descriptor.declaration_kind = DeclarationDescriptor::PARAMETER; 2871 descriptor.scope = scope(); 2872 descriptor.mode = VariableMode::kLet; 2873 descriptor.declaration_pos = parameter->pattern->position(); 2874 // The position that will be used by the AssignmentExpression 2875 // which copies from the temp parameter to the pattern. 2876 // 2877 // TODO(adamk): Should this be kNoSourcePosition, since 2878 // it's just copying from a temp var to the real param var? 2879 descriptor.initialization_pos = parameter->pattern->position(); 2880 Expression* initial_value = 2881 factory()->NewVariableProxy(parameters.scope->parameter(index)); 2882 if (parameter->initializer != nullptr) { 2883 // IS_UNDEFINED($param) ? initializer : $param 2884 2885 // Ensure initializer is rewritten 2886 RewriteParameterInitializer(parameter->initializer); 2887 2888 auto condition = factory()->NewCompareOperation( 2889 Token::EQ_STRICT, 2890 factory()->NewVariableProxy(parameters.scope->parameter(index)), 2891 factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition); 2892 initial_value = factory()->NewConditional( 2893 condition, parameter->initializer, initial_value, kNoSourcePosition); 2894 descriptor.initialization_pos = parameter->initializer->position(); 2895 } 2896 2897 Scope* param_scope = scope(); 2898 Block* param_block = init_block; 2899 if (!parameter->is_simple() && 2900 scope()->AsDeclarationScope()->calls_sloppy_eval()) { 2901 param_scope = NewVarblockScope(); 2902 param_scope->set_start_position(descriptor.initialization_pos); 2903 param_scope->set_end_position(parameter->initializer_end_position); 2904 param_scope->RecordEvalCall(); 2905 param_block = factory()->NewBlock(8, true); 2906 param_block->set_scope(param_scope); 2907 // Pass the appropriate scope in so that PatternRewriter can appropriately 2908 // rewrite inner initializers of the pattern to param_scope 2909 descriptor.scope = param_scope; 2910 // Rewrite the outer initializer to point to param_scope 2911 ReparentExpressionScope(stack_limit(), initial_value, param_scope); 2912 } 2913 2914 BlockState block_state(&scope_, param_scope); 2915 DeclarationParsingResult::Declaration decl( 2916 parameter->pattern, parameter->initializer_end_position, initial_value); 2917 DeclareAndInitializeVariables(param_block, &descriptor, &decl, nullptr, 2918 CHECK_OK); 2919 2920 if (param_block != init_block) { 2921 param_scope = param_scope->FinalizeBlockScope(); 2922 if (param_scope != nullptr) { 2923 CheckConflictingVarDeclarations(param_scope, CHECK_OK); 2924 } 2925 init_block->statements()->Add(param_block, zone()); 2926 } 2927 ++index; 2928 } 2929 return init_block; 2930 } 2931 2932 Scope* Parser::NewHiddenCatchScope() { 2933 Scope* catch_scope = NewScopeWithParent(scope(), CATCH_SCOPE); 2934 catch_scope->DeclareLocal(ast_value_factory()->dot_catch_string(), 2935 VariableMode::kVar); 2936 catch_scope->set_is_hidden(); 2937 return catch_scope; 2938 } 2939 2940 Block* Parser::BuildRejectPromiseOnException(Block* inner_block) { 2941 // .promise = %AsyncFunctionPromiseCreate(); 2942 // try { 2943 // <inner_block> 2944 // } catch (.catch) { 2945 // %RejectPromise(.promise, .catch); 2946 // return .promise; 2947 // } finally { 2948 // %AsyncFunctionPromiseRelease(.promise); 2949 // } 2950 Block* result = factory()->NewBlock(2, true); 2951 2952 // .promise = %AsyncFunctionPromiseCreate(); 2953 Statement* set_promise; 2954 { 2955 Expression* create_promise = factory()->NewCallRuntime( 2956 Context::ASYNC_FUNCTION_PROMISE_CREATE_INDEX, 2957 new (zone()) ZonePtrList<Expression>(0, zone()), kNoSourcePosition); 2958 Assignment* assign_promise = factory()->NewAssignment( 2959 Token::ASSIGN, factory()->NewVariableProxy(PromiseVariable()), 2960 create_promise, kNoSourcePosition); 2961 set_promise = 2962 factory()->NewExpressionStatement(assign_promise, kNoSourcePosition); 2963 } 2964 result->statements()->Add(set_promise, zone()); 2965 2966 // catch (.catch) { return %RejectPromise(.promise, .catch), .promise } 2967 Scope* catch_scope = NewHiddenCatchScope(); 2968 2969 Expression* promise_reject = BuildRejectPromise( 2970 factory()->NewVariableProxy(catch_scope->catch_variable()), 2971 kNoSourcePosition); 2972 Block* catch_block = IgnoreCompletion( 2973 factory()->NewReturnStatement(promise_reject, kNoSourcePosition)); 2974 2975 TryStatement* try_catch_statement = 2976 factory()->NewTryCatchStatementForAsyncAwait( 2977 inner_block, catch_scope, catch_block, kNoSourcePosition); 2978 2979 // There is no TryCatchFinally node, so wrap it in an outer try/finally 2980 Block* outer_try_block = IgnoreCompletion(try_catch_statement); 2981 2982 // finally { %AsyncFunctionPromiseRelease(.promise, can_suspend) } 2983 Block* finally_block; 2984 { 2985 ZonePtrList<Expression>* args = 2986 new (zone()) ZonePtrList<Expression>(1, zone()); 2987 args->Add(factory()->NewVariableProxy(PromiseVariable()), zone()); 2988 args->Add(factory()->NewBooleanLiteral(function_state_->CanSuspend(), 2989 kNoSourcePosition), 2990 zone()); 2991 Expression* call_promise_release = factory()->NewCallRuntime( 2992 Context::ASYNC_FUNCTION_PROMISE_RELEASE_INDEX, args, kNoSourcePosition); 2993 Statement* promise_release = factory()->NewExpressionStatement( 2994 call_promise_release, kNoSourcePosition); 2995 finally_block = IgnoreCompletion(promise_release); 2996 } 2997 2998 Statement* try_finally_statement = factory()->NewTryFinallyStatement( 2999 outer_try_block, finally_block, kNoSourcePosition); 3000 3001 result->statements()->Add(try_finally_statement, zone()); 3002 return result; 3003 } 3004 3005 Expression* Parser::BuildResolvePromise(Expression* value, int pos) { 3006 // %ResolvePromise(.promise, value), .promise 3007 ZonePtrList<Expression>* args = 3008 new (zone()) ZonePtrList<Expression>(2, zone()); 3009 args->Add(factory()->NewVariableProxy(PromiseVariable()), zone()); 3010 args->Add(value, zone()); 3011 Expression* call_runtime = 3012 factory()->NewCallRuntime(Runtime::kInlineResolvePromise, args, pos); 3013 return factory()->NewBinaryOperation( 3014 Token::COMMA, call_runtime, 3015 factory()->NewVariableProxy(PromiseVariable()), pos); 3016 } 3017 3018 Expression* Parser::BuildRejectPromise(Expression* value, int pos) { 3019 // %promise_internal_reject(.promise, value, false), .promise 3020 // Disables the additional debug event for the rejection since a debug event 3021 // already happened for the exception that got us here. 3022 ZonePtrList<Expression>* args = 3023 new (zone()) ZonePtrList<Expression>(3, zone()); 3024 args->Add(factory()->NewVariableProxy(PromiseVariable()), zone()); 3025 args->Add(value, zone()); 3026 args->Add(factory()->NewBooleanLiteral(false, pos), zone()); 3027 Expression* call_runtime = 3028 factory()->NewCallRuntime(Runtime::kInlineRejectPromise, args, pos); 3029 return factory()->NewBinaryOperation( 3030 Token::COMMA, call_runtime, 3031 factory()->NewVariableProxy(PromiseVariable()), pos); 3032 } 3033 3034 Variable* Parser::PromiseVariable() { 3035 // Based on the various compilation paths, there are many different code 3036 // paths which may be the first to access the Promise temporary. Whichever 3037 // comes first should create it and stash it in the FunctionState. 3038 Variable* promise = function_state_->scope()->promise_var(); 3039 if (promise == nullptr) { 3040 promise = function_state_->scope()->DeclarePromiseVar( 3041 ast_value_factory()->empty_string()); 3042 } 3043 return promise; 3044 } 3045 3046 Expression* Parser::BuildInitialYield(int pos, FunctionKind kind) { 3047 Expression* yield_result = factory()->NewVariableProxy( 3048 function_state_->scope()->generator_object_var()); 3049 // The position of the yield is important for reporting the exception 3050 // caused by calling the .throw method on a generator suspended at the 3051 // initial yield (i.e. right after generator instantiation). 3052 function_state_->AddSuspend(); 3053 return factory()->NewYield(yield_result, scope()->start_position(), 3054 Suspend::kOnExceptionThrow); 3055 } 3056 3057 ZonePtrList<Statement>* Parser::ParseFunction( 3058 const AstRawString* function_name, int pos, FunctionKind kind, 3059 FunctionLiteral::FunctionType function_type, 3060 DeclarationScope* function_scope, int* num_parameters, int* function_length, 3061 bool* has_duplicate_parameters, int* expected_property_count, 3062 int* suspend_count, 3063 ZonePtrList<const AstRawString>* arguments_for_wrapped_function, bool* ok) { 3064 ParsingModeScope mode(this, allow_lazy_ ? PARSE_LAZILY : PARSE_EAGERLY); 3065 3066 FunctionState function_state(&function_state_, &scope_, function_scope); 3067 3068 bool is_wrapped = function_type == FunctionLiteral::kWrapped; 3069 3070 DuplicateFinder duplicate_finder; 3071 ExpressionClassifier formals_classifier(this, &duplicate_finder); 3072 3073 int expected_parameters_end_pos = parameters_end_pos_; 3074 if (expected_parameters_end_pos != kNoSourcePosition) { 3075 // This is the first function encountered in a CreateDynamicFunction eval. 3076 parameters_end_pos_ = kNoSourcePosition; 3077 // The function name should have been ignored, giving us the empty string 3078 // here. 3079 DCHECK_EQ(function_name, ast_value_factory()->empty_string()); 3080 } 3081 3082 ParserFormalParameters formals(function_scope); 3083 3084 if (is_wrapped) { 3085 // For a function implicitly wrapped in function header and footer, the 3086 // function arguments are provided separately to the source, and are 3087 // declared directly here. 3088 int arguments_length = arguments_for_wrapped_function->length(); 3089 for (int i = 0; i < arguments_length; i++) { 3090 const bool is_rest = false; 3091 Expression* argument = ExpressionFromIdentifier( 3092 arguments_for_wrapped_function->at(i), kNoSourcePosition); 3093 AddFormalParameter(&formals, argument, NullExpression(), 3094 kNoSourcePosition, is_rest); 3095 } 3096 DCHECK_EQ(arguments_length, formals.num_parameters()); 3097 DeclareFormalParameters(formals.scope, formals.params, formals.is_simple); 3098 } else { 3099 // For a regular function, the function arguments are parsed from source. 3100 DCHECK_NULL(arguments_for_wrapped_function); 3101 ParseFormalParameterList(&formals, CHECK_OK); 3102 if (expected_parameters_end_pos != kNoSourcePosition) { 3103 // Check for '(' or ')' shenanigans in the parameter string for dynamic 3104 // functions. 3105 int position = peek_position(); 3106 if (position < expected_parameters_end_pos) { 3107 ReportMessageAt(Scanner::Location(position, position + 1), 3108 MessageTemplate::kArgStringTerminatesParametersEarly); 3109 *ok = false; 3110 return nullptr; 3111 } else if (position > expected_parameters_end_pos) { 3112 ReportMessageAt(Scanner::Location(expected_parameters_end_pos - 2, 3113 expected_parameters_end_pos), 3114 MessageTemplate::kUnexpectedEndOfArgString); 3115 *ok = false; 3116 return nullptr; 3117 } 3118 } 3119 Expect(Token::RPAREN, CHECK_OK); 3120 int formals_end_position = scanner()->location().end_pos; 3121 3122 CheckArityRestrictions(formals.arity, kind, formals.has_rest, 3123 function_scope->start_position(), 3124 formals_end_position, CHECK_OK); 3125 Expect(Token::LBRACE, CHECK_OK); 3126 } 3127 *num_parameters = formals.num_parameters(); 3128 *function_length = formals.function_length; 3129 3130 ZonePtrList<Statement>* body = new (zone()) ZonePtrList<Statement>(8, zone()); 3131 ParseFunctionBody(body, function_name, pos, formals, kind, function_type, ok); 3132 3133 // Validate parameter names. We can do this only after parsing the function, 3134 // since the function can declare itself strict. 3135 const bool allow_duplicate_parameters = 3136 is_sloppy(function_scope->language_mode()) && formals.is_simple && 3137 !IsConciseMethod(kind); 3138 ValidateFormalParameters(function_scope->language_mode(), 3139 allow_duplicate_parameters, CHECK_OK); 3140 3141 RewriteDestructuringAssignments(); 3142 3143 *has_duplicate_parameters = 3144 !classifier()->is_valid_formal_parameter_list_without_duplicates(); 3145 3146 *expected_property_count = function_state.expected_property_count(); 3147 *suspend_count = function_state.suspend_count(); 3148 return body; 3149 } 3150 3151 void Parser::DeclareClassVariable(const AstRawString* name, 3152 ClassInfo* class_info, int class_token_pos, 3153 bool* ok) { 3154 #ifdef DEBUG 3155 scope()->SetScopeName(name); 3156 #endif 3157 3158 if (name != nullptr) { 3159 VariableProxy* proxy = factory()->NewVariableProxy(name, NORMAL_VARIABLE); 3160 Declaration* declaration = 3161 factory()->NewVariableDeclaration(proxy, class_token_pos); 3162 class_info->variable = Declare( 3163 declaration, DeclarationDescriptor::NORMAL, VariableMode::kConst, 3164 Variable::DefaultInitializationFlag(VariableMode::kConst), ok); 3165 } 3166 } 3167 3168 // TODO(gsathya): Ideally, this should just bypass scope analysis and 3169 // allocate a slot directly on the context. We should just store this 3170 // index in the AST, instead of storing the variable. 3171 Variable* Parser::CreateSyntheticContextVariable(const AstRawString* name, 3172 bool* ok) { 3173 VariableProxy* proxy = factory()->NewVariableProxy(name, NORMAL_VARIABLE); 3174 Declaration* declaration = 3175 factory()->NewVariableDeclaration(proxy, kNoSourcePosition); 3176 Variable* var = Declare( 3177 declaration, DeclarationDescriptor::NORMAL, VariableMode::kConst, 3178 Variable::DefaultInitializationFlag(VariableMode::kConst), CHECK_OK); 3179 var->ForceContextAllocation(); 3180 return var; 3181 } 3182 3183 // This method declares a property of the given class. It updates the 3184 // following fields of class_info, as appropriate: 3185 // - constructor 3186 // - properties 3187 void Parser::DeclareClassProperty(const AstRawString* class_name, 3188 ClassLiteralProperty* property, 3189 const AstRawString* property_name, 3190 ClassLiteralProperty::Kind kind, 3191 bool is_static, bool is_constructor, 3192 bool is_computed_name, ClassInfo* class_info, 3193 bool* ok) { 3194 if (is_constructor) { 3195 DCHECK(!class_info->constructor); 3196 class_info->constructor = property->value()->AsFunctionLiteral(); 3197 DCHECK_NOT_NULL(class_info->constructor); 3198 class_info->constructor->set_raw_name( 3199 class_name != nullptr ? ast_value_factory()->NewConsString(class_name) 3200 : nullptr); 3201 return; 3202 } 3203 3204 if (kind != ClassLiteralProperty::PUBLIC_FIELD && 3205 kind != ClassLiteralProperty::PRIVATE_FIELD) { 3206 class_info->properties->Add(property, zone()); 3207 return; 3208 } 3209 3210 DCHECK(allow_harmony_public_fields() || allow_harmony_private_fields()); 3211 3212 if (is_static) { 3213 DCHECK(allow_harmony_static_fields()); 3214 DCHECK_EQ(kind, ClassLiteralProperty::PUBLIC_FIELD); 3215 class_info->static_fields->Add(property, zone()); 3216 } else { 3217 class_info->instance_fields->Add(property, zone()); 3218 } 3219 3220 if (is_computed_name) { 3221 DCHECK_EQ(kind, ClassLiteralProperty::PUBLIC_FIELD); 3222 // We create a synthetic variable name here so that scope 3223 // analysis doesn't dedupe the vars. 3224 Variable* computed_name_var = CreateSyntheticContextVariable( 3225 ClassFieldVariableName(ast_value_factory(), 3226 class_info->computed_field_count), 3227 CHECK_OK_VOID); 3228 property->set_computed_name_var(computed_name_var); 3229 class_info->properties->Add(property, zone()); 3230 } 3231 3232 if (kind == ClassLiteralProperty::PRIVATE_FIELD) { 3233 Variable* private_field_name_var = 3234 CreateSyntheticContextVariable(property_name, CHECK_OK_VOID); 3235 property->set_private_field_name_var(private_field_name_var); 3236 class_info->properties->Add(property, zone()); 3237 } 3238 } 3239 3240 FunctionLiteral* Parser::CreateInitializerFunction( 3241 DeclarationScope* scope, ZonePtrList<ClassLiteral::Property>* fields) { 3242 DCHECK_EQ(scope->function_kind(), 3243 FunctionKind::kClassFieldsInitializerFunction); 3244 // function() { .. class fields initializer .. } 3245 ZonePtrList<Statement>* statements = NewStatementList(1); 3246 InitializeClassFieldsStatement* static_fields = 3247 factory()->NewInitializeClassFieldsStatement(fields, kNoSourcePosition); 3248 statements->Add(static_fields, zone()); 3249 return factory()->NewFunctionLiteral( 3250 ast_value_factory()->empty_string(), scope, statements, 0, 0, 0, 3251 FunctionLiteral::kNoDuplicateParameters, 3252 FunctionLiteral::kAnonymousExpression, 3253 FunctionLiteral::kShouldEagerCompile, scope->start_position(), true, 3254 GetNextFunctionLiteralId()); 3255 } 3256 3257 // This method generates a ClassLiteral AST node. 3258 // It uses the following fields of class_info: 3259 // - constructor (if missing, it updates it with a default constructor) 3260 // - proxy 3261 // - extends 3262 // - properties 3263 // - has_name_static_property 3264 // - has_static_computed_names 3265 Expression* Parser::RewriteClassLiteral(Scope* block_scope, 3266 const AstRawString* name, 3267 ClassInfo* class_info, int pos, 3268 int end_pos, bool* ok) { 3269 DCHECK_NOT_NULL(block_scope); 3270 DCHECK_EQ(block_scope->scope_type(), BLOCK_SCOPE); 3271 DCHECK_EQ(block_scope->language_mode(), LanguageMode::kStrict); 3272 3273 bool has_extends = class_info->extends != nullptr; 3274 bool has_default_constructor = class_info->constructor == nullptr; 3275 if (has_default_constructor) { 3276 class_info->constructor = 3277 DefaultConstructor(name, has_extends, pos, end_pos); 3278 } 3279 3280 if (name != nullptr) { 3281 DCHECK_NOT_NULL(class_info->variable); 3282 class_info->variable->set_initializer_position(end_pos); 3283 } 3284 3285 FunctionLiteral* static_fields_initializer = nullptr; 3286 if (class_info->has_static_class_fields) { 3287 static_fields_initializer = CreateInitializerFunction( 3288 class_info->static_fields_scope, class_info->static_fields); 3289 } 3290 3291 FunctionLiteral* instance_fields_initializer_function = nullptr; 3292 if (class_info->has_instance_class_fields) { 3293 instance_fields_initializer_function = CreateInitializerFunction( 3294 class_info->instance_fields_scope, class_info->instance_fields); 3295 class_info->constructor->set_requires_instance_fields_initializer(true); 3296 } 3297 3298 ClassLiteral* class_literal = factory()->NewClassLiteral( 3299 block_scope, class_info->variable, class_info->extends, 3300 class_info->constructor, class_info->properties, 3301 static_fields_initializer, instance_fields_initializer_function, pos, 3302 end_pos, class_info->has_name_static_property, 3303 class_info->has_static_computed_names, class_info->is_anonymous); 3304 3305 AddFunctionForNameInference(class_info->constructor); 3306 return class_literal; 3307 } 3308 3309 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) { 3310 Declaration* decl = scope->CheckConflictingVarDeclarations(); 3311 if (decl != nullptr) { 3312 // In ES6, conflicting variable bindings are early errors. 3313 const AstRawString* name = decl->proxy()->raw_name(); 3314 int position = decl->proxy()->position(); 3315 Scanner::Location location = 3316 position == kNoSourcePosition 3317 ? Scanner::Location::invalid() 3318 : Scanner::Location(position, position + 1); 3319 ReportMessageAt(location, MessageTemplate::kVarRedeclaration, name); 3320 *ok = false; 3321 } 3322 } 3323 3324 bool Parser::IsPropertyWithPrivateFieldKey(Expression* expression) { 3325 if (!expression->IsProperty()) return false; 3326 Property* property = expression->AsProperty(); 3327 3328 if (!property->key()->IsVariableProxy()) return false; 3329 VariableProxy* key = property->key()->AsVariableProxy(); 3330 3331 return key->is_private_field(); 3332 } 3333 3334 void Parser::InsertShadowingVarBindingInitializers(Block* inner_block) { 3335 // For each var-binding that shadows a parameter, insert an assignment 3336 // initializing the variable with the parameter. 3337 Scope* inner_scope = inner_block->scope(); 3338 DCHECK(inner_scope->is_declaration_scope()); 3339 Scope* function_scope = inner_scope->outer_scope(); 3340 DCHECK(function_scope->is_function_scope()); 3341 BlockState block_state(&scope_, inner_scope); 3342 for (Declaration* decl : *inner_scope->declarations()) { 3343 if (decl->proxy()->var()->mode() != VariableMode::kVar || 3344 !decl->IsVariableDeclaration()) { 3345 continue; 3346 } 3347 const AstRawString* name = decl->proxy()->raw_name(); 3348 Variable* parameter = function_scope->LookupLocal(name); 3349 if (parameter == nullptr) continue; 3350 VariableProxy* to = NewUnresolved(name); 3351 VariableProxy* from = factory()->NewVariableProxy(parameter); 3352 Expression* assignment = 3353 factory()->NewAssignment(Token::ASSIGN, to, from, kNoSourcePosition); 3354 Statement* statement = 3355 factory()->NewExpressionStatement(assignment, kNoSourcePosition); 3356 inner_block->statements()->InsertAt(0, statement, zone()); 3357 } 3358 } 3359 3360 void Parser::InsertSloppyBlockFunctionVarBindings(DeclarationScope* scope) { 3361 // For the outermost eval scope, we cannot hoist during parsing: let 3362 // declarations in the surrounding scope may prevent hoisting, but the 3363 // information is unaccessible during parsing. In this case, we hoist later in 3364 // DeclarationScope::Analyze. 3365 if (scope->is_eval_scope() && scope->outer_scope() == original_scope_) { 3366 return; 3367 } 3368 scope->HoistSloppyBlockFunctions(factory()); 3369 } 3370 3371 // ---------------------------------------------------------------------------- 3372 // Parser support 3373 3374 bool Parser::TargetStackContainsLabel(const AstRawString* label) { 3375 for (ParserTarget* t = target_stack_; t != nullptr; t = t->previous()) { 3376 if (ContainsLabel(t->statement()->labels(), label)) return true; 3377 } 3378 return false; 3379 } 3380 3381 3382 BreakableStatement* Parser::LookupBreakTarget(const AstRawString* label, 3383 bool* ok) { 3384 bool anonymous = label == nullptr; 3385 for (ParserTarget* t = target_stack_; t != nullptr; t = t->previous()) { 3386 BreakableStatement* stat = t->statement(); 3387 if ((anonymous && stat->is_target_for_anonymous()) || 3388 (!anonymous && ContainsLabel(stat->labels(), label))) { 3389 return stat; 3390 } 3391 } 3392 return nullptr; 3393 } 3394 3395 3396 IterationStatement* Parser::LookupContinueTarget(const AstRawString* label, 3397 bool* ok) { 3398 bool anonymous = label == nullptr; 3399 for (ParserTarget* t = target_stack_; t != nullptr; t = t->previous()) { 3400 IterationStatement* stat = t->statement()->AsIterationStatement(); 3401 if (stat == nullptr) continue; 3402 3403 DCHECK(stat->is_target_for_anonymous()); 3404 if (anonymous || ContainsLabel(stat->own_labels(), label)) { 3405 return stat; 3406 } 3407 if (ContainsLabel(stat->labels(), label)) break; 3408 } 3409 return nullptr; 3410 } 3411 3412 3413 void Parser::HandleSourceURLComments(Isolate* isolate, Handle<Script> script) { 3414 Handle<String> source_url = scanner_.SourceUrl(isolate); 3415 if (!source_url.is_null()) { 3416 script->set_source_url(*source_url); 3417 } 3418 Handle<String> source_mapping_url = scanner_.SourceMappingUrl(isolate); 3419 if (!source_mapping_url.is_null()) { 3420 script->set_source_mapping_url(*source_mapping_url); 3421 } 3422 } 3423 3424 void Parser::UpdateStatistics(Isolate* isolate, Handle<Script> script) { 3425 // Move statistics to Isolate. 3426 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; 3427 ++feature) { 3428 if (use_counts_[feature] > 0) { 3429 isolate->CountUsage(v8::Isolate::UseCounterFeature(feature)); 3430 } 3431 } 3432 if (scanner_.FoundHtmlComment()) { 3433 isolate->CountUsage(v8::Isolate::kHtmlComment); 3434 if (script->line_offset() == 0 && script->column_offset() == 0) { 3435 isolate->CountUsage(v8::Isolate::kHtmlCommentInExternalScript); 3436 } 3437 } 3438 isolate->counters()->total_preparse_skipped()->Increment( 3439 total_preparse_skipped_); 3440 } 3441 3442 void Parser::ParseOnBackground(ParseInfo* info) { 3443 RuntimeCallTimerScope runtimeTimer( 3444 runtime_call_stats_, RuntimeCallCounterId::kParseBackgroundProgram); 3445 parsing_on_main_thread_ = false; 3446 set_script_id(info->script_id()); 3447 3448 DCHECK_NULL(info->literal()); 3449 FunctionLiteral* result = nullptr; 3450 3451 scanner_.Initialize(); 3452 DCHECK(info->maybe_outer_scope_info().is_null()); 3453 3454 DCHECK(original_scope_); 3455 3456 // When streaming, we don't know the length of the source until we have parsed 3457 // it. The raw data can be UTF-8, so we wouldn't know the source length until 3458 // we have decoded it anyway even if we knew the raw data length (which we 3459 // don't). We work around this by storing all the scopes which need their end 3460 // position set at the end of the script (the top scope and possible eval 3461 // scopes) and set their end position after we know the script length. 3462 if (info->is_toplevel()) { 3463 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone()); 3464 result = DoParseProgram(/* isolate = */ nullptr, info); 3465 } else { 3466 result = 3467 DoParseFunction(/* isolate = */ nullptr, info, info->function_name()); 3468 } 3469 MaybeResetCharacterStream(info, result); 3470 3471 info->set_literal(result); 3472 3473 // We cannot internalize on a background thread; a foreground task will take 3474 // care of calling AstValueFactory::Internalize just before compilation. 3475 } 3476 3477 Parser::TemplateLiteralState Parser::OpenTemplateLiteral(int pos) { 3478 return new (zone()) TemplateLiteral(zone(), pos); 3479 } 3480 3481 void Parser::AddTemplateSpan(TemplateLiteralState* state, bool should_cook, 3482 bool tail) { 3483 int end = scanner()->location().end_pos - (tail ? 1 : 2); 3484 const AstRawString* raw = scanner()->CurrentRawSymbol(ast_value_factory()); 3485 if (should_cook) { 3486 const AstRawString* cooked = scanner()->CurrentSymbol(ast_value_factory()); 3487 (*state)->AddTemplateSpan(cooked, raw, end, zone()); 3488 } else { 3489 (*state)->AddTemplateSpan(nullptr, raw, end, zone()); 3490 } 3491 } 3492 3493 3494 void Parser::AddTemplateExpression(TemplateLiteralState* state, 3495 Expression* expression) { 3496 (*state)->AddExpression(expression, zone()); 3497 } 3498 3499 3500 Expression* Parser::CloseTemplateLiteral(TemplateLiteralState* state, int start, 3501 Expression* tag) { 3502 TemplateLiteral* lit = *state; 3503 int pos = lit->position(); 3504 const ZonePtrList<const AstRawString>* cooked_strings = lit->cooked(); 3505 const ZonePtrList<const AstRawString>* raw_strings = lit->raw(); 3506 const ZonePtrList<Expression>* expressions = lit->expressions(); 3507 DCHECK_EQ(cooked_strings->length(), raw_strings->length()); 3508 DCHECK_EQ(cooked_strings->length(), expressions->length() + 1); 3509 3510 if (!tag) { 3511 if (cooked_strings->length() == 1) { 3512 return factory()->NewStringLiteral(cooked_strings->first(), pos); 3513 } 3514 return factory()->NewTemplateLiteral(cooked_strings, expressions, pos); 3515 } else { 3516 // GetTemplateObject 3517 Expression* template_object = 3518 factory()->NewGetTemplateObject(cooked_strings, raw_strings, pos); 3519 3520 // Call TagFn 3521 ZonePtrList<Expression>* call_args = 3522 new (zone()) ZonePtrList<Expression>(expressions->length() + 1, zone()); 3523 call_args->Add(template_object, zone()); 3524 call_args->AddAll(*expressions, zone()); 3525 return factory()->NewTaggedTemplate(tag, call_args, pos); 3526 } 3527 } 3528 3529 namespace { 3530 3531 bool OnlyLastArgIsSpread(ZonePtrList<Expression>* args) { 3532 for (int i = 0; i < args->length() - 1; i++) { 3533 if (args->at(i)->IsSpread()) { 3534 return false; 3535 } 3536 } 3537 return args->at(args->length() - 1)->IsSpread(); 3538 } 3539 3540 } // namespace 3541 3542 ArrayLiteral* Parser::ArrayLiteralFromListWithSpread( 3543 ZonePtrList<Expression>* list) { 3544 // If there's only a single spread argument, a fast path using CallWithSpread 3545 // is taken. 3546 DCHECK_LT(1, list->length()); 3547 3548 // The arguments of the spread call become a single ArrayLiteral. 3549 int first_spread = 0; 3550 for (; first_spread < list->length() && !list->at(first_spread)->IsSpread(); 3551 ++first_spread) { 3552 } 3553 3554 DCHECK_LT(first_spread, list->length()); 3555 return factory()->NewArrayLiteral(list, first_spread, kNoSourcePosition); 3556 } 3557 3558 Expression* Parser::SpreadCall(Expression* function, 3559 ZonePtrList<Expression>* args_list, int pos, 3560 Call::PossiblyEval is_possibly_eval) { 3561 // Handle this case in BytecodeGenerator. 3562 if (OnlyLastArgIsSpread(args_list) || function->IsSuperCallReference()) { 3563 return factory()->NewCall(function, args_list, pos); 3564 } 3565 3566 ZonePtrList<Expression>* args = 3567 new (zone()) ZonePtrList<Expression>(3, zone()); 3568 if (function->IsProperty()) { 3569 // Method calls 3570 if (function->AsProperty()->IsSuperAccess()) { 3571 Expression* home = ThisExpression(kNoSourcePosition); 3572 args->Add(function, zone()); 3573 args->Add(home, zone()); 3574 } else { 3575 Variable* temp = NewTemporary(ast_value_factory()->empty_string()); 3576 VariableProxy* obj = factory()->NewVariableProxy(temp); 3577 Assignment* assign_obj = factory()->NewAssignment( 3578 Token::ASSIGN, obj, function->AsProperty()->obj(), kNoSourcePosition); 3579 function = factory()->NewProperty( 3580 assign_obj, function->AsProperty()->key(), kNoSourcePosition); 3581 args->Add(function, zone()); 3582 obj = factory()->NewVariableProxy(temp); 3583 args->Add(obj, zone()); 3584 } 3585 } else { 3586 // Non-method calls 3587 args->Add(function, zone()); 3588 args->Add(factory()->NewUndefinedLiteral(kNoSourcePosition), zone()); 3589 } 3590 args->Add(ArrayLiteralFromListWithSpread(args_list), zone()); 3591 return factory()->NewCallRuntime(Context::REFLECT_APPLY_INDEX, args, pos); 3592 } 3593 3594 Expression* Parser::SpreadCallNew(Expression* function, 3595 ZonePtrList<Expression>* args_list, int pos) { 3596 if (OnlyLastArgIsSpread(args_list)) { 3597 // Handle in BytecodeGenerator. 3598 return factory()->NewCallNew(function, args_list, pos); 3599 } 3600 ZonePtrList<Expression>* args = 3601 new (zone()) ZonePtrList<Expression>(2, zone()); 3602 args->Add(function, zone()); 3603 args->Add(ArrayLiteralFromListWithSpread(args_list), zone()); 3604 3605 return factory()->NewCallRuntime(Context::REFLECT_CONSTRUCT_INDEX, args, pos); 3606 } 3607 3608 3609 void Parser::SetLanguageMode(Scope* scope, LanguageMode mode) { 3610 v8::Isolate::UseCounterFeature feature; 3611 if (is_sloppy(mode)) 3612 feature = v8::Isolate::kSloppyMode; 3613 else if (is_strict(mode)) 3614 feature = v8::Isolate::kStrictMode; 3615 else 3616 UNREACHABLE(); 3617 ++use_counts_[feature]; 3618 scope->SetLanguageMode(mode); 3619 } 3620 3621 void Parser::SetAsmModule() { 3622 // Store the usage count; The actual use counter on the isolate is 3623 // incremented after parsing is done. 3624 ++use_counts_[v8::Isolate::kUseAsm]; 3625 DCHECK(scope()->is_declaration_scope()); 3626 scope()->AsDeclarationScope()->set_asm_module(); 3627 } 3628 3629 Expression* Parser::ExpressionListToExpression(ZonePtrList<Expression>* args) { 3630 Expression* expr = args->at(0); 3631 for (int i = 1; i < args->length(); ++i) { 3632 expr = factory()->NewBinaryOperation(Token::COMMA, expr, args->at(i), 3633 expr->position()); 3634 } 3635 return expr; 3636 } 3637 3638 // This method completes the desugaring of the body of async_function. 3639 void Parser::RewriteAsyncFunctionBody(ZonePtrList<Statement>* body, 3640 Block* block, Expression* return_value, 3641 bool* ok) { 3642 // function async_function() { 3643 // .generator_object = %CreateJSGeneratorObject(); 3644 // BuildRejectPromiseOnException({ 3645 // ... block ... 3646 // return %ResolvePromise(.promise, expr), .promise; 3647 // }) 3648 // } 3649 3650 return_value = BuildResolvePromise(return_value, return_value->position()); 3651 block->statements()->Add( 3652 factory()->NewReturnStatement(return_value, return_value->position()), 3653 zone()); 3654 block = BuildRejectPromiseOnException(block); 3655 body->Add(block, zone()); 3656 } 3657 3658 void Parser::RewriteDestructuringAssignments() { 3659 const auto& assignments = 3660 function_state_->destructuring_assignments_to_rewrite(); 3661 auto it = assignments.rbegin(); 3662 for (; it != assignments.rend(); ++it) { 3663 // Rewrite list in reverse, so that nested assignment patterns are rewritten 3664 // correctly. 3665 RewritableExpression* to_rewrite = *it; 3666 DCHECK_NOT_NULL(to_rewrite); 3667 if (!to_rewrite->is_rewritten()) { 3668 // Since this function is called at the end of parsing the program, 3669 // pair.scope may already have been removed by FinalizeBlockScope in the 3670 // meantime. 3671 Scope* scope = to_rewrite->scope()->GetUnremovedScope(); 3672 // Scope at the time of the rewriting and the original parsing 3673 // should be in the same function. 3674 DCHECK(scope->GetClosureScope() == scope_->GetClosureScope()); 3675 BlockState block_state(&scope_, scope); 3676 RewriteDestructuringAssignment(to_rewrite); 3677 } 3678 } 3679 } 3680 3681 void Parser::QueueDestructuringAssignmentForRewriting( 3682 RewritableExpression* expr) { 3683 function_state_->AddDestructuringAssignment(expr); 3684 } 3685 3686 void Parser::SetFunctionNameFromPropertyName(LiteralProperty* property, 3687 const AstRawString* name, 3688 const AstRawString* prefix) { 3689 // Ensure that the function we are going to create has shared name iff 3690 // we are not going to set it later. 3691 if (property->NeedsSetFunctionName()) { 3692 name = nullptr; 3693 prefix = nullptr; 3694 } else { 3695 // If the property value is an anonymous function or an anonymous class or 3696 // a concise method or an accessor function which doesn't require the name 3697 // to be set then the shared name must be provided. 3698 DCHECK_IMPLIES(property->value()->IsAnonymousFunctionDefinition() || 3699 property->value()->IsConciseMethodDefinition() || 3700 property->value()->IsAccessorFunctionDefinition(), 3701 name != nullptr); 3702 } 3703 3704 Expression* value = property->value(); 3705 SetFunctionName(value, name, prefix); 3706 } 3707 3708 void Parser::SetFunctionNameFromPropertyName(ObjectLiteralProperty* property, 3709 const AstRawString* name, 3710 const AstRawString* prefix) { 3711 // Ignore "__proto__" as a name when it's being used to set the [[Prototype]] 3712 // of an object literal. 3713 // See ES #sec-__proto__-property-names-in-object-initializers. 3714 if (property->IsPrototype()) return; 3715 3716 DCHECK(!property->value()->IsAnonymousFunctionDefinition() || 3717 property->kind() == ObjectLiteralProperty::COMPUTED); 3718 3719 SetFunctionNameFromPropertyName(static_cast<LiteralProperty*>(property), name, 3720 prefix); 3721 } 3722 3723 void Parser::SetFunctionNameFromIdentifierRef(Expression* value, 3724 Expression* identifier) { 3725 if (!identifier->IsVariableProxy()) return; 3726 SetFunctionName(value, identifier->AsVariableProxy()->raw_name()); 3727 } 3728 3729 void Parser::SetFunctionName(Expression* value, const AstRawString* name, 3730 const AstRawString* prefix) { 3731 if (!value->IsAnonymousFunctionDefinition() && 3732 !value->IsConciseMethodDefinition() && 3733 !value->IsAccessorFunctionDefinition()) { 3734 return; 3735 } 3736 auto function = value->AsFunctionLiteral(); 3737 if (value->IsClassLiteral()) { 3738 function = value->AsClassLiteral()->constructor(); 3739 } 3740 if (function != nullptr) { 3741 AstConsString* cons_name = nullptr; 3742 if (name != nullptr) { 3743 if (prefix != nullptr) { 3744 cons_name = ast_value_factory()->NewConsString(prefix, name); 3745 } else { 3746 cons_name = ast_value_factory()->NewConsString(name); 3747 } 3748 } else { 3749 DCHECK_NULL(prefix); 3750 } 3751 function->set_raw_name(cons_name); 3752 } 3753 } 3754 3755 Statement* Parser::CheckCallable(Variable* var, Expression* error, int pos) { 3756 const int nopos = kNoSourcePosition; 3757 Statement* validate_var; 3758 { 3759 Expression* type_of = factory()->NewUnaryOperation( 3760 Token::TYPEOF, factory()->NewVariableProxy(var), nopos); 3761 Expression* function_literal = factory()->NewStringLiteral( 3762 ast_value_factory()->function_string(), nopos); 3763 Expression* condition = factory()->NewCompareOperation( 3764 Token::EQ_STRICT, type_of, function_literal, nopos); 3765 3766 Statement* throw_call = factory()->NewExpressionStatement(error, pos); 3767 3768 validate_var = factory()->NewIfStatement( 3769 condition, factory()->NewEmptyStatement(nopos), throw_call, nopos); 3770 } 3771 return validate_var; 3772 } 3773 3774 void Parser::BuildIteratorClose(ZonePtrList<Statement>* statements, 3775 Variable* iterator, Variable* input, 3776 Variable* var_output, IteratorType type) { 3777 // 3778 // This function adds four statements to [statements], corresponding to the 3779 // following code: 3780 // 3781 // let iteratorReturn = iterator.return; 3782 // if (IS_NULL_OR_UNDEFINED(iteratorReturn) { 3783 // return {value: input, done: true}; 3784 // } 3785 // output = %_Call(iteratorReturn, iterator, input); 3786 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output); 3787 // 3788 3789 const int nopos = kNoSourcePosition; 3790 3791 // let iteratorReturn = iterator.return; 3792 Variable* var_return = var_output; // Reusing the output variable. 3793 Statement* get_return; 3794 { 3795 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); 3796 Expression* literal = factory()->NewStringLiteral( 3797 ast_value_factory()->return_string(), nopos); 3798 Expression* property = 3799 factory()->NewProperty(iterator_proxy, literal, nopos); 3800 Expression* return_proxy = factory()->NewVariableProxy(var_return); 3801 Expression* assignment = 3802 factory()->NewAssignment(Token::ASSIGN, return_proxy, property, nopos); 3803 get_return = factory()->NewExpressionStatement(assignment, nopos); 3804 } 3805 3806 // if (IS_NULL_OR_UNDEFINED(iteratorReturn) { 3807 // return {value: input, done: true}; 3808 // } 3809 Statement* check_return; 3810 { 3811 Expression* condition = factory()->NewCompareOperation( 3812 Token::EQ, factory()->NewVariableProxy(var_return), 3813 factory()->NewNullLiteral(nopos), nopos); 3814 3815 Expression* value = factory()->NewVariableProxy(input); 3816 3817 Statement* return_input = BuildReturnStatement(value, nopos); 3818 3819 check_return = factory()->NewIfStatement( 3820 condition, return_input, factory()->NewEmptyStatement(nopos), nopos); 3821 } 3822 3823 // output = %_Call(iteratorReturn, iterator, input); 3824 Statement* call_return; 3825 { 3826 auto args = new (zone()) ZonePtrList<Expression>(3, zone()); 3827 args->Add(factory()->NewVariableProxy(var_return), zone()); 3828 args->Add(factory()->NewVariableProxy(iterator), zone()); 3829 args->Add(factory()->NewVariableProxy(input), zone()); 3830 3831 Expression* call = 3832 factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos); 3833 if (type == IteratorType::kAsync) { 3834 function_state_->AddSuspend(); 3835 call = factory()->NewAwait(call, nopos); 3836 } 3837 Expression* output_proxy = factory()->NewVariableProxy(var_output); 3838 Expression* assignment = 3839 factory()->NewAssignment(Token::ASSIGN, output_proxy, call, nopos); 3840 call_return = factory()->NewExpressionStatement(assignment, nopos); 3841 } 3842 3843 // if (!IS_RECEIVER(output)) %ThrowIteratorResultNotAnObject(output); 3844 Statement* validate_output; 3845 { 3846 Expression* is_receiver_call; 3847 { 3848 auto args = new (zone()) ZonePtrList<Expression>(1, zone()); 3849 args->Add(factory()->NewVariableProxy(var_output), zone()); 3850 is_receiver_call = 3851 factory()->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos); 3852 } 3853 3854 Statement* throw_call; 3855 { 3856 auto args = new (zone()) ZonePtrList<Expression>(1, zone()); 3857 args->Add(factory()->NewVariableProxy(var_output), zone()); 3858 Expression* call = factory()->NewCallRuntime( 3859 Runtime::kThrowIteratorResultNotAnObject, args, nopos); 3860 throw_call = factory()->NewExpressionStatement(call, nopos); 3861 } 3862 3863 validate_output = factory()->NewIfStatement( 3864 is_receiver_call, factory()->NewEmptyStatement(nopos), throw_call, 3865 nopos); 3866 } 3867 3868 statements->Add(get_return, zone()); 3869 statements->Add(check_return, zone()); 3870 statements->Add(call_return, zone()); 3871 statements->Add(validate_output, zone()); 3872 } 3873 3874 void Parser::FinalizeIteratorUse(Variable* completion, Expression* condition, 3875 Variable* iter, Block* iterator_use, 3876 Block* target, IteratorType type) { 3877 // 3878 // This function adds two statements to [target], corresponding to the 3879 // following code: 3880 // 3881 // completion = kNormalCompletion; 3882 // try { 3883 // try { 3884 // iterator_use 3885 // } catch(e) { 3886 // if (completion === kAbruptCompletion) completion = kThrowCompletion; 3887 // %ReThrow(e); 3888 // } 3889 // } finally { 3890 // if (condition) { 3891 // #BuildIteratorCloseForCompletion(iter, completion) 3892 // } 3893 // } 3894 // 3895 3896 const int nopos = kNoSourcePosition; 3897 3898 // completion = kNormalCompletion; 3899 Statement* initialize_completion; 3900 { 3901 Expression* proxy = factory()->NewVariableProxy(completion); 3902 Expression* assignment = factory()->NewAssignment( 3903 Token::ASSIGN, proxy, 3904 factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos); 3905 initialize_completion = 3906 factory()->NewExpressionStatement(assignment, nopos); 3907 } 3908 3909 // if (completion === kAbruptCompletion) completion = kThrowCompletion; 3910 Statement* set_completion_throw; 3911 { 3912 Expression* condition = factory()->NewCompareOperation( 3913 Token::EQ_STRICT, factory()->NewVariableProxy(completion), 3914 factory()->NewSmiLiteral(Parser::kAbruptCompletion, nopos), nopos); 3915 3916 Expression* proxy = factory()->NewVariableProxy(completion); 3917 Expression* assignment = factory()->NewAssignment( 3918 Token::ASSIGN, proxy, 3919 factory()->NewSmiLiteral(Parser::kThrowCompletion, nopos), nopos); 3920 Statement* statement = factory()->NewExpressionStatement(assignment, nopos); 3921 set_completion_throw = factory()->NewIfStatement( 3922 condition, statement, factory()->NewEmptyStatement(nopos), nopos); 3923 } 3924 3925 // if (condition) { 3926 // #BuildIteratorCloseForCompletion(iter, completion) 3927 // } 3928 Block* maybe_close; 3929 { 3930 Block* block = factory()->NewBlock(2, true); 3931 Expression* proxy = factory()->NewVariableProxy(completion); 3932 BuildIteratorCloseForCompletion(block->statements(), iter, proxy, type); 3933 DCHECK_EQ(block->statements()->length(), 2); 3934 3935 maybe_close = IgnoreCompletion(factory()->NewIfStatement( 3936 condition, block, factory()->NewEmptyStatement(nopos), nopos)); 3937 } 3938 3939 // try { #try_block } 3940 // catch(e) { 3941 // #set_completion_throw; 3942 // %ReThrow(e); 3943 // } 3944 Statement* try_catch; 3945 { 3946 Scope* catch_scope = NewHiddenCatchScope(); 3947 3948 Statement* rethrow; 3949 // We use %ReThrow rather than the ordinary throw because we want to 3950 // preserve the original exception message. This is also why we create a 3951 // TryCatchStatementForReThrow below (which does not clear the pending 3952 // message), rather than a TryCatchStatement. 3953 { 3954 auto args = new (zone()) ZonePtrList<Expression>(1, zone()); 3955 args->Add(factory()->NewVariableProxy(catch_scope->catch_variable()), 3956 zone()); 3957 rethrow = factory()->NewExpressionStatement( 3958 factory()->NewCallRuntime(Runtime::kReThrow, args, nopos), nopos); 3959 } 3960 3961 Block* catch_block = factory()->NewBlock(2, false); 3962 catch_block->statements()->Add(set_completion_throw, zone()); 3963 catch_block->statements()->Add(rethrow, zone()); 3964 3965 try_catch = factory()->NewTryCatchStatementForReThrow( 3966 iterator_use, catch_scope, catch_block, nopos); 3967 } 3968 3969 // try { #try_catch } finally { #maybe_close } 3970 Statement* try_finally; 3971 { 3972 Block* try_block = factory()->NewBlock(1, false); 3973 try_block->statements()->Add(try_catch, zone()); 3974 3975 try_finally = 3976 factory()->NewTryFinallyStatement(try_block, maybe_close, nopos); 3977 } 3978 3979 target->statements()->Add(initialize_completion, zone()); 3980 target->statements()->Add(try_finally, zone()); 3981 } 3982 3983 void Parser::BuildIteratorCloseForCompletion(ZonePtrList<Statement>* statements, 3984 Variable* iterator, 3985 Expression* completion, 3986 IteratorType type) { 3987 // 3988 // This function adds two statements to [statements], corresponding to the 3989 // following code: 3990 // 3991 // let iteratorReturn = iterator.return; 3992 // if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) { 3993 // if (completion === kThrowCompletion) { 3994 // if (!IS_CALLABLE(iteratorReturn)) { 3995 // throw MakeTypeError(kReturnMethodNotCallable); 3996 // } 3997 // [if (IteratorType == kAsync)] 3998 // try { Await(%_Call(iteratorReturn, iterator) } catch (_) { } 3999 // [else] 4000 // try { %_Call(iteratorReturn, iterator) } catch (_) { } 4001 // [endif] 4002 // } else { 4003 // [if (IteratorType == kAsync)] 4004 // let output = Await(%_Call(iteratorReturn, iterator)); 4005 // [else] 4006 // let output = %_Call(iteratorReturn, iterator); 4007 // [endif] 4008 // if (!IS_RECEIVER(output)) { 4009 // %ThrowIterResultNotAnObject(output); 4010 // } 4011 // } 4012 // } 4013 // 4014 4015 const int nopos = kNoSourcePosition; 4016 // let iteratorReturn = iterator.return; 4017 Variable* var_return = NewTemporary(ast_value_factory()->empty_string()); 4018 Statement* get_return; 4019 { 4020 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); 4021 Expression* literal = factory()->NewStringLiteral( 4022 ast_value_factory()->return_string(), nopos); 4023 Expression* property = 4024 factory()->NewProperty(iterator_proxy, literal, nopos); 4025 Expression* return_proxy = factory()->NewVariableProxy(var_return); 4026 Expression* assignment = 4027 factory()->NewAssignment(Token::ASSIGN, return_proxy, property, nopos); 4028 get_return = factory()->NewExpressionStatement(assignment, nopos); 4029 } 4030 4031 // if (!IS_CALLABLE(iteratorReturn)) { 4032 // throw MakeTypeError(kReturnMethodNotCallable); 4033 // } 4034 Statement* check_return_callable; 4035 { 4036 Expression* throw_expr = 4037 NewThrowTypeError(MessageTemplate::kReturnMethodNotCallable, 4038 ast_value_factory()->empty_string(), nopos); 4039 check_return_callable = CheckCallable(var_return, throw_expr, nopos); 4040 } 4041 4042 // try { %_Call(iteratorReturn, iterator) } catch (_) { } 4043 Statement* try_call_return; 4044 { 4045 auto args = new (zone()) ZonePtrList<Expression>(2, zone()); 4046 args->Add(factory()->NewVariableProxy(var_return), zone()); 4047 args->Add(factory()->NewVariableProxy(iterator), zone()); 4048 4049 Expression* call = 4050 factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos); 4051 4052 if (type == IteratorType::kAsync) { 4053 function_state_->AddSuspend(); 4054 call = factory()->NewAwait(call, nopos); 4055 } 4056 4057 Block* try_block = factory()->NewBlock(1, false); 4058 try_block->statements()->Add(factory()->NewExpressionStatement(call, nopos), 4059 zone()); 4060 4061 Block* catch_block = factory()->NewBlock(0, false); 4062 try_call_return = 4063 factory()->NewTryCatchStatement(try_block, nullptr, catch_block, nopos); 4064 } 4065 4066 // let output = %_Call(iteratorReturn, iterator); 4067 // if (!IS_RECEIVER(output)) { 4068 // %ThrowIteratorResultNotAnObject(output); 4069 // } 4070 Block* validate_return; 4071 { 4072 Variable* var_output = NewTemporary(ast_value_factory()->empty_string()); 4073 Statement* call_return; 4074 { 4075 auto args = new (zone()) ZonePtrList<Expression>(2, zone()); 4076 args->Add(factory()->NewVariableProxy(var_return), zone()); 4077 args->Add(factory()->NewVariableProxy(iterator), zone()); 4078 Expression* call = 4079 factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos); 4080 if (type == IteratorType::kAsync) { 4081 function_state_->AddSuspend(); 4082 call = factory()->NewAwait(call, nopos); 4083 } 4084 4085 Expression* output_proxy = factory()->NewVariableProxy(var_output); 4086 Expression* assignment = 4087 factory()->NewAssignment(Token::ASSIGN, output_proxy, call, nopos); 4088 call_return = factory()->NewExpressionStatement(assignment, nopos); 4089 } 4090 4091 Expression* is_receiver_call; 4092 { 4093 auto args = new (zone()) ZonePtrList<Expression>(1, zone()); 4094 args->Add(factory()->NewVariableProxy(var_output), zone()); 4095 is_receiver_call = 4096 factory()->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos); 4097 } 4098 4099 Statement* throw_call; 4100 { 4101 auto args = new (zone()) ZonePtrList<Expression>(1, zone()); 4102 args->Add(factory()->NewVariableProxy(var_output), zone()); 4103 Expression* call = factory()->NewCallRuntime( 4104 Runtime::kThrowIteratorResultNotAnObject, args, nopos); 4105 throw_call = factory()->NewExpressionStatement(call, nopos); 4106 } 4107 4108 Statement* check_return = factory()->NewIfStatement( 4109 is_receiver_call, factory()->NewEmptyStatement(nopos), throw_call, 4110 nopos); 4111 4112 validate_return = factory()->NewBlock(2, false); 4113 validate_return->statements()->Add(call_return, zone()); 4114 validate_return->statements()->Add(check_return, zone()); 4115 } 4116 4117 // if (completion === kThrowCompletion) { 4118 // #check_return_callable; 4119 // #try_call_return; 4120 // } else { 4121 // #validate_return; 4122 // } 4123 Statement* call_return_carefully; 4124 { 4125 Expression* condition = factory()->NewCompareOperation( 4126 Token::EQ_STRICT, completion, 4127 factory()->NewSmiLiteral(Parser::kThrowCompletion, nopos), nopos); 4128 4129 Block* then_block = factory()->NewBlock(2, false); 4130 then_block->statements()->Add(check_return_callable, zone()); 4131 then_block->statements()->Add(try_call_return, zone()); 4132 4133 call_return_carefully = factory()->NewIfStatement(condition, then_block, 4134 validate_return, nopos); 4135 } 4136 4137 // if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) { ... } 4138 Statement* maybe_call_return; 4139 { 4140 Expression* condition = factory()->NewCompareOperation( 4141 Token::EQ, factory()->NewVariableProxy(var_return), 4142 factory()->NewNullLiteral(nopos), nopos); 4143 4144 maybe_call_return = factory()->NewIfStatement( 4145 condition, factory()->NewEmptyStatement(nopos), call_return_carefully, 4146 nopos); 4147 } 4148 4149 statements->Add(get_return, zone()); 4150 statements->Add(maybe_call_return, zone()); 4151 } 4152 4153 Statement* Parser::FinalizeForOfStatement(ForOfStatement* loop, 4154 Variable* var_completion, 4155 IteratorType type, int pos) { 4156 // 4157 // This function replaces the loop with the following wrapping: 4158 // 4159 // completion = kNormalCompletion; 4160 // try { 4161 // try { 4162 // #loop; 4163 // } catch(e) { 4164 // if (completion === kAbruptCompletion) completion = kThrowCompletion; 4165 // %ReThrow(e); 4166 // } 4167 // } finally { 4168 // if (!(completion === kNormalCompletion)) { 4169 // #BuildIteratorCloseForCompletion(#iterator, completion) 4170 // } 4171 // } 4172 // 4173 // Note that the loop's body and its assign_each already contain appropriate 4174 // assignments to completion (see InitializeForOfStatement). 4175 // 4176 4177 const int nopos = kNoSourcePosition; 4178 4179 // !(completion === kNormalCompletion) 4180 Expression* closing_condition; 4181 { 4182 Expression* cmp = factory()->NewCompareOperation( 4183 Token::EQ_STRICT, factory()->NewVariableProxy(var_completion), 4184 factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos); 4185 closing_condition = factory()->NewUnaryOperation(Token::NOT, cmp, nopos); 4186 } 4187 4188 Block* final_loop = factory()->NewBlock(2, false); 4189 { 4190 Block* try_block = factory()->NewBlock(1, false); 4191 try_block->statements()->Add(loop, zone()); 4192 4193 FinalizeIteratorUse(var_completion, closing_condition, loop->iterator(), 4194 try_block, final_loop, type); 4195 } 4196 4197 return final_loop; 4198 } 4199 4200 #undef CHECK_OK 4201 #undef CHECK_OK_VOID 4202 #undef CHECK_FAILED 4203 4204 } // namespace internal 4205 } // namespace v8 4206