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 <memory> 8 9 #include "src/api.h" 10 #include "src/ast/ast-expression-rewriter.h" 11 #include "src/ast/ast-function-literal-id-reindexer.h" 12 #include "src/ast/ast-traversal-visitor.h" 13 #include "src/ast/ast.h" 14 #include "src/bailout-reason.h" 15 #include "src/base/platform/platform.h" 16 #include "src/char-predicates-inl.h" 17 #include "src/messages.h" 18 #include "src/objects-inl.h" 19 #include "src/parsing/duplicate-finder.h" 20 #include "src/parsing/parameter-initializer-rewriter.h" 21 #include "src/parsing/parse-info.h" 22 #include "src/parsing/rewriter.h" 23 #include "src/parsing/scanner-character-streams.h" 24 #include "src/runtime/runtime.h" 25 #include "src/string-stream.h" 26 #include "src/tracing/trace-event.h" 27 28 namespace v8 { 29 namespace internal { 30 31 ScriptData::ScriptData(const byte* data, int length) 32 : owns_data_(false), rejected_(false), data_(data), length_(length) { 33 if (!IsAligned(reinterpret_cast<intptr_t>(data), kPointerAlignment)) { 34 byte* copy = NewArray<byte>(length); 35 DCHECK(IsAligned(reinterpret_cast<intptr_t>(copy), kPointerAlignment)); 36 CopyBytes(copy, data, length); 37 data_ = copy; 38 AcquireDataOwnership(); 39 } 40 } 41 42 FunctionEntry ParseData::GetFunctionEntry(int start) { 43 // The current pre-data entry must be a FunctionEntry with the given 44 // start position. 45 if ((function_index_ + FunctionEntry::kSize <= Length()) && 46 (static_cast<int>(Data()[function_index_]) == start)) { 47 int index = function_index_; 48 function_index_ += FunctionEntry::kSize; 49 Vector<unsigned> subvector(&(Data()[index]), FunctionEntry::kSize); 50 return FunctionEntry(subvector); 51 } 52 return FunctionEntry(); 53 } 54 55 56 int ParseData::FunctionCount() { 57 int functions_size = FunctionsSize(); 58 if (functions_size < 0) return 0; 59 if (functions_size % FunctionEntry::kSize != 0) return 0; 60 return functions_size / FunctionEntry::kSize; 61 } 62 63 64 bool ParseData::IsSane() { 65 if (!IsAligned(script_data_->length(), sizeof(unsigned))) return false; 66 // Check that the header data is valid and doesn't specify 67 // point to positions outside the store. 68 int data_length = Length(); 69 if (data_length < PreparseDataConstants::kHeaderSize) return false; 70 if (Magic() != PreparseDataConstants::kMagicNumber) return false; 71 if (Version() != PreparseDataConstants::kCurrentVersion) return false; 72 // Check that the space allocated for function entries is sane. 73 int functions_size = FunctionsSize(); 74 if (functions_size < 0) return false; 75 if (functions_size % FunctionEntry::kSize != 0) return false; 76 // Check that the total size has room for header and function entries. 77 int minimum_size = 78 PreparseDataConstants::kHeaderSize + functions_size; 79 if (data_length < minimum_size) return false; 80 return true; 81 } 82 83 84 void ParseData::Initialize() { 85 // Prepares state for use. 86 int data_length = Length(); 87 if (data_length >= PreparseDataConstants::kHeaderSize) { 88 function_index_ = PreparseDataConstants::kHeaderSize; 89 } 90 } 91 92 93 unsigned ParseData::Magic() { 94 return Data()[PreparseDataConstants::kMagicOffset]; 95 } 96 97 98 unsigned ParseData::Version() { 99 return Data()[PreparseDataConstants::kVersionOffset]; 100 } 101 102 103 int ParseData::FunctionsSize() { 104 return static_cast<int>(Data()[PreparseDataConstants::kFunctionsSizeOffset]); 105 } 106 107 // Helper for putting parts of the parse results into a temporary zone when 108 // parsing inner function bodies. 109 class DiscardableZoneScope { 110 public: 111 DiscardableZoneScope(Parser* parser, Zone* temp_zone, bool use_temp_zone) 112 : ast_node_factory_scope_(parser->factory(), temp_zone, use_temp_zone), 113 fni_(parser->ast_value_factory_, temp_zone), 114 parser_(parser), 115 prev_fni_(parser->fni_), 116 prev_zone_(parser->zone_), 117 prev_allow_lazy_(parser->allow_lazy_), 118 prev_temp_zoned_(parser->temp_zoned_) { 119 if (use_temp_zone) { 120 DCHECK(!parser_->temp_zoned_); 121 parser_->allow_lazy_ = false; 122 parser_->temp_zoned_ = true; 123 parser_->fni_ = &fni_; 124 parser_->zone_ = temp_zone; 125 if (parser_->reusable_preparser_ != nullptr) { 126 parser_->reusable_preparser_->zone_ = temp_zone; 127 parser_->reusable_preparser_->factory()->set_zone(temp_zone); 128 } 129 } 130 } 131 void Reset() { 132 parser_->fni_ = prev_fni_; 133 parser_->zone_ = prev_zone_; 134 parser_->allow_lazy_ = prev_allow_lazy_; 135 parser_->temp_zoned_ = prev_temp_zoned_; 136 if (parser_->reusable_preparser_ != nullptr) { 137 parser_->reusable_preparser_->zone_ = prev_zone_; 138 parser_->reusable_preparser_->factory()->set_zone(prev_zone_); 139 } 140 ast_node_factory_scope_.Reset(); 141 } 142 ~DiscardableZoneScope() { Reset(); } 143 144 private: 145 AstNodeFactory::BodyScope ast_node_factory_scope_; 146 FuncNameInferrer fni_; 147 Parser* parser_; 148 FuncNameInferrer* prev_fni_; 149 Zone* prev_zone_; 150 bool prev_allow_lazy_; 151 bool prev_temp_zoned_; 152 153 DISALLOW_COPY_AND_ASSIGN(DiscardableZoneScope); 154 }; 155 156 void Parser::SetCachedData(ParseInfo* info) { 157 DCHECK_NULL(cached_parse_data_); 158 if (consume_cached_parse_data()) { 159 if (allow_lazy_) { 160 cached_parse_data_ = ParseData::FromCachedData(*info->cached_data()); 161 if (cached_parse_data_ != nullptr) return; 162 } 163 compile_options_ = ScriptCompiler::kNoCompileOptions; 164 } 165 } 166 167 FunctionLiteral* Parser::DefaultConstructor(const AstRawString* name, 168 bool call_super, int pos, 169 int end_pos) { 170 int expected_property_count = -1; 171 const int parameter_count = 0; 172 if (name == nullptr) name = ast_value_factory()->empty_string(); 173 174 FunctionKind kind = call_super ? FunctionKind::kDefaultDerivedConstructor 175 : FunctionKind::kDefaultBaseConstructor; 176 DeclarationScope* function_scope = NewFunctionScope(kind); 177 SetLanguageMode(function_scope, STRICT); 178 // Set start and end position to the same value 179 function_scope->set_start_position(pos); 180 function_scope->set_end_position(pos); 181 ZoneList<Statement*>* body = NULL; 182 183 { 184 FunctionState function_state(&function_state_, &scope_, function_scope); 185 186 body = new (zone()) ZoneList<Statement*>(call_super ? 2 : 1, zone()); 187 if (call_super) { 188 // Create a SuperCallReference and handle in BytecodeGenerator. 189 auto constructor_args_name = ast_value_factory()->empty_string(); 190 bool is_duplicate; 191 bool is_rest = true; 192 bool is_optional = false; 193 Variable* constructor_args = function_scope->DeclareParameter( 194 constructor_args_name, TEMPORARY, is_optional, is_rest, &is_duplicate, 195 ast_value_factory()); 196 197 ZoneList<Expression*>* args = 198 new (zone()) ZoneList<Expression*>(1, zone()); 199 Spread* spread_args = factory()->NewSpread( 200 factory()->NewVariableProxy(constructor_args), pos, pos); 201 202 args->Add(spread_args, zone()); 203 Expression* super_call_ref = NewSuperCallReference(pos); 204 Expression* call = factory()->NewCall(super_call_ref, args, pos); 205 body->Add(factory()->NewReturnStatement(call, pos), zone()); 206 } 207 208 expected_property_count = function_state.expected_property_count(); 209 } 210 211 FunctionLiteral* function_literal = factory()->NewFunctionLiteral( 212 name, function_scope, body, expected_property_count, parameter_count, 213 parameter_count, FunctionLiteral::kNoDuplicateParameters, 214 FunctionLiteral::kAnonymousExpression, default_eager_compile_hint(), pos, 215 true, GetNextFunctionLiteralId()); 216 217 return function_literal; 218 } 219 220 // ---------------------------------------------------------------------------- 221 // The CHECK_OK macro is a convenient macro to enforce error 222 // handling for functions that may fail (by returning !*ok). 223 // 224 // CAUTION: This macro appends extra statements after a call, 225 // thus it must never be used where only a single statement 226 // is correct (e.g. an if statement branch w/o braces)! 227 228 #define CHECK_OK_VALUE(x) ok); \ 229 if (!*ok) return x; \ 230 ((void)0 231 #define DUMMY ) // to make indentation work 232 #undef DUMMY 233 234 #define CHECK_OK CHECK_OK_VALUE(nullptr) 235 #define CHECK_OK_VOID CHECK_OK_VALUE(this->Void()) 236 237 #define CHECK_FAILED /**/); \ 238 if (failed_) return nullptr; \ 239 ((void)0 240 #define DUMMY ) // to make indentation work 241 #undef DUMMY 242 243 // ---------------------------------------------------------------------------- 244 // Implementation of Parser 245 246 bool Parser::ShortcutNumericLiteralBinaryExpression(Expression** x, 247 Expression* y, 248 Token::Value op, int pos) { 249 if ((*x)->AsLiteral() && (*x)->AsLiteral()->raw_value()->IsNumber() && 250 y->AsLiteral() && y->AsLiteral()->raw_value()->IsNumber()) { 251 double x_val = (*x)->AsLiteral()->raw_value()->AsNumber(); 252 double y_val = y->AsLiteral()->raw_value()->AsNumber(); 253 bool x_has_dot = (*x)->AsLiteral()->raw_value()->ContainsDot(); 254 bool y_has_dot = y->AsLiteral()->raw_value()->ContainsDot(); 255 bool has_dot = x_has_dot || y_has_dot; 256 switch (op) { 257 case Token::ADD: 258 *x = factory()->NewNumberLiteral(x_val + y_val, pos, has_dot); 259 return true; 260 case Token::SUB: 261 *x = factory()->NewNumberLiteral(x_val - y_val, pos, has_dot); 262 return true; 263 case Token::MUL: 264 *x = factory()->NewNumberLiteral(x_val * y_val, pos, has_dot); 265 return true; 266 case Token::DIV: 267 *x = factory()->NewNumberLiteral(x_val / y_val, pos, has_dot); 268 return true; 269 case Token::BIT_OR: { 270 int value = DoubleToInt32(x_val) | DoubleToInt32(y_val); 271 *x = factory()->NewNumberLiteral(value, pos, has_dot); 272 return true; 273 } 274 case Token::BIT_AND: { 275 int value = DoubleToInt32(x_val) & DoubleToInt32(y_val); 276 *x = factory()->NewNumberLiteral(value, pos, has_dot); 277 return true; 278 } 279 case Token::BIT_XOR: { 280 int value = DoubleToInt32(x_val) ^ DoubleToInt32(y_val); 281 *x = factory()->NewNumberLiteral(value, pos, has_dot); 282 return true; 283 } 284 case Token::SHL: { 285 int value = DoubleToInt32(x_val) << (DoubleToInt32(y_val) & 0x1f); 286 *x = factory()->NewNumberLiteral(value, pos, has_dot); 287 return true; 288 } 289 case Token::SHR: { 290 uint32_t shift = DoubleToInt32(y_val) & 0x1f; 291 uint32_t value = DoubleToUint32(x_val) >> shift; 292 *x = factory()->NewNumberLiteral(value, pos, has_dot); 293 return true; 294 } 295 case Token::SAR: { 296 uint32_t shift = DoubleToInt32(y_val) & 0x1f; 297 int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift); 298 *x = factory()->NewNumberLiteral(value, pos, has_dot); 299 return true; 300 } 301 case Token::EXP: { 302 double value = Pow(x_val, y_val); 303 int int_value = static_cast<int>(value); 304 *x = factory()->NewNumberLiteral( 305 int_value == value && value != -0.0 ? int_value : value, pos, 306 has_dot); 307 return true; 308 } 309 default: 310 break; 311 } 312 } 313 return false; 314 } 315 316 Expression* Parser::BuildUnaryExpression(Expression* expression, 317 Token::Value op, int pos) { 318 DCHECK(expression != NULL); 319 if (expression->IsLiteral()) { 320 const AstValue* literal = expression->AsLiteral()->raw_value(); 321 if (op == Token::NOT) { 322 // Convert the literal to a boolean condition and negate it. 323 bool condition = literal->BooleanValue(); 324 return factory()->NewBooleanLiteral(!condition, pos); 325 } else if (literal->IsNumber()) { 326 // Compute some expressions involving only number literals. 327 double value = literal->AsNumber(); 328 bool has_dot = literal->ContainsDot(); 329 switch (op) { 330 case Token::ADD: 331 return expression; 332 case Token::SUB: 333 return factory()->NewNumberLiteral(-value, pos, has_dot); 334 case Token::BIT_NOT: 335 return factory()->NewNumberLiteral(~DoubleToInt32(value), pos, 336 has_dot); 337 default: 338 break; 339 } 340 } 341 } 342 // Desugar '+foo' => 'foo*1' 343 if (op == Token::ADD) { 344 return factory()->NewBinaryOperation( 345 Token::MUL, expression, factory()->NewNumberLiteral(1, pos, true), pos); 346 } 347 // The same idea for '-foo' => 'foo*(-1)'. 348 if (op == Token::SUB) { 349 return factory()->NewBinaryOperation( 350 Token::MUL, expression, factory()->NewNumberLiteral(-1, pos), pos); 351 } 352 // ...and one more time for '~foo' => 'foo^(~0)'. 353 if (op == Token::BIT_NOT) { 354 return factory()->NewBinaryOperation( 355 Token::BIT_XOR, expression, factory()->NewNumberLiteral(~0, pos), pos); 356 } 357 return factory()->NewUnaryOperation(op, expression, pos); 358 } 359 360 Expression* Parser::BuildIteratorResult(Expression* value, bool done) { 361 int pos = kNoSourcePosition; 362 363 if (value == nullptr) value = factory()->NewUndefinedLiteral(pos); 364 365 auto args = new (zone()) ZoneList<Expression*>(2, zone()); 366 args->Add(value, zone()); 367 args->Add(factory()->NewBooleanLiteral(done, pos), zone()); 368 369 return factory()->NewCallRuntime(Runtime::kInlineCreateIterResultObject, args, 370 pos); 371 } 372 373 Expression* Parser::NewThrowError(Runtime::FunctionId id, 374 MessageTemplate::Template message, 375 const AstRawString* arg, int pos) { 376 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone()); 377 args->Add(factory()->NewSmiLiteral(message, pos), zone()); 378 args->Add(factory()->NewStringLiteral(arg, pos), zone()); 379 CallRuntime* call_constructor = factory()->NewCallRuntime(id, args, pos); 380 return factory()->NewThrow(call_constructor, pos); 381 } 382 383 Expression* Parser::NewSuperPropertyReference(int pos) { 384 // this_function[home_object_symbol] 385 VariableProxy* this_function_proxy = 386 NewUnresolved(ast_value_factory()->this_function_string(), pos); 387 Expression* home_object_symbol_literal = factory()->NewSymbolLiteral( 388 AstSymbol::kHomeObjectSymbol, kNoSourcePosition); 389 Expression* home_object = factory()->NewProperty( 390 this_function_proxy, home_object_symbol_literal, pos); 391 return factory()->NewSuperPropertyReference( 392 ThisExpression(pos)->AsVariableProxy(), home_object, pos); 393 } 394 395 Expression* Parser::NewSuperCallReference(int pos) { 396 VariableProxy* new_target_proxy = 397 NewUnresolved(ast_value_factory()->new_target_string(), pos); 398 VariableProxy* this_function_proxy = 399 NewUnresolved(ast_value_factory()->this_function_string(), pos); 400 return factory()->NewSuperCallReference( 401 ThisExpression(pos)->AsVariableProxy(), new_target_proxy, 402 this_function_proxy, pos); 403 } 404 405 Expression* Parser::NewTargetExpression(int pos) { 406 auto proxy = NewUnresolved(ast_value_factory()->new_target_string(), pos); 407 proxy->set_is_new_target(); 408 return proxy; 409 } 410 411 Expression* Parser::FunctionSentExpression(int pos) { 412 // We desugar function.sent into %_GeneratorGetInputOrDebugPos(generator). 413 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(1, zone()); 414 VariableProxy* generator = 415 factory()->NewVariableProxy(function_state_->generator_object_variable()); 416 args->Add(generator, zone()); 417 return factory()->NewCallRuntime(Runtime::kInlineGeneratorGetInputOrDebugPos, 418 args, pos); 419 } 420 421 Literal* Parser::ExpressionFromLiteral(Token::Value token, int pos) { 422 switch (token) { 423 case Token::NULL_LITERAL: 424 return factory()->NewNullLiteral(pos); 425 case Token::TRUE_LITERAL: 426 return factory()->NewBooleanLiteral(true, pos); 427 case Token::FALSE_LITERAL: 428 return factory()->NewBooleanLiteral(false, pos); 429 case Token::SMI: { 430 uint32_t value = scanner()->smi_value(); 431 return factory()->NewSmiLiteral(value, pos); 432 } 433 case Token::NUMBER: { 434 bool has_dot = scanner()->ContainsDot(); 435 double value = scanner()->DoubleValue(); 436 return factory()->NewNumberLiteral(value, pos, has_dot); 437 } 438 default: 439 DCHECK(false); 440 } 441 return NULL; 442 } 443 444 void Parser::MarkTailPosition(Expression* expression) { 445 expression->MarkTail(); 446 } 447 448 Expression* Parser::NewV8Intrinsic(const AstRawString* name, 449 ZoneList<Expression*>* args, int pos, 450 bool* ok) { 451 if (extension_ != nullptr) { 452 // The extension structures are only accessible while parsing the 453 // very first time, not when reparsing because of lazy compilation. 454 GetClosureScope()->ForceEagerCompilation(); 455 } 456 457 DCHECK(name->is_one_byte()); 458 const Runtime::Function* function = 459 Runtime::FunctionForName(name->raw_data(), name->length()); 460 461 if (function != nullptr) { 462 // Check for possible name clash. 463 DCHECK_EQ(Context::kNotFound, 464 Context::IntrinsicIndexForName(name->raw_data(), name->length())); 465 // Check for built-in IS_VAR macro. 466 if (function->function_id == Runtime::kIS_VAR) { 467 DCHECK_EQ(Runtime::RUNTIME, function->intrinsic_type); 468 // %IS_VAR(x) evaluates to x if x is a variable, 469 // leads to a parse error otherwise. Could be implemented as an 470 // inline function %_IS_VAR(x) to eliminate this special case. 471 if (args->length() == 1 && args->at(0)->AsVariableProxy() != nullptr) { 472 return args->at(0); 473 } else { 474 ReportMessage(MessageTemplate::kNotIsvar); 475 *ok = false; 476 return nullptr; 477 } 478 } 479 480 // Check that the expected number of arguments are being passed. 481 if (function->nargs != -1 && function->nargs != args->length()) { 482 ReportMessage(MessageTemplate::kRuntimeWrongNumArgs); 483 *ok = false; 484 return nullptr; 485 } 486 487 return factory()->NewCallRuntime(function, args, pos); 488 } 489 490 int context_index = 491 Context::IntrinsicIndexForName(name->raw_data(), name->length()); 492 493 // Check that the function is defined. 494 if (context_index == Context::kNotFound) { 495 ReportMessage(MessageTemplate::kNotDefined, name); 496 *ok = false; 497 return nullptr; 498 } 499 500 return factory()->NewCallRuntime(context_index, args, pos); 501 } 502 503 Parser::Parser(ParseInfo* info) 504 : ParserBase<Parser>(info->zone(), &scanner_, info->stack_limit(), 505 info->extension(), info->ast_value_factory(), 506 info->isolate()->counters()->runtime_call_stats(), 507 true), 508 scanner_(info->unicode_cache()), 509 reusable_preparser_(nullptr), 510 original_scope_(nullptr), 511 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly. 512 target_stack_(nullptr), 513 compile_options_(info->compile_options()), 514 cached_parse_data_(nullptr), 515 total_preparse_skipped_(0), 516 temp_zoned_(false), 517 log_(nullptr), 518 preparsed_scope_data_(info->preparsed_scope_data()), 519 parameters_end_pos_(info->parameters_end_pos()) { 520 // Even though we were passed ParseInfo, we should not store it in 521 // Parser - this makes sure that Isolate is not accidentally accessed via 522 // ParseInfo during background parsing. 523 DCHECK(!info->script().is_null() || info->source_stream() != nullptr || 524 info->character_stream() != nullptr); 525 // Determine if functions can be lazily compiled. This is necessary to 526 // allow some of our builtin JS files to be lazily compiled. These 527 // builtins cannot be handled lazily by the parser, since we have to know 528 // if a function uses the special natives syntax, which is something the 529 // parser records. 530 // If the debugger requests compilation for break points, we cannot be 531 // aggressive about lazy compilation, because it might trigger compilation 532 // of functions without an outer context when setting a breakpoint through 533 // Debug::FindSharedFunctionInfoInScript 534 bool can_compile_lazily = FLAG_lazy && !info->is_debug(); 535 536 // Consider compiling eagerly when targeting the code cache. 537 can_compile_lazily &= !(FLAG_serialize_eager && info->will_serialize()); 538 539 set_default_eager_compile_hint(can_compile_lazily 540 ? FunctionLiteral::kShouldLazyCompile 541 : FunctionLiteral::kShouldEagerCompile); 542 allow_lazy_ = FLAG_lazy && info->allow_lazy_parsing() && !info->is_native() && 543 info->extension() == nullptr && can_compile_lazily; 544 set_allow_natives(FLAG_allow_natives_syntax || info->is_native()); 545 set_allow_tailcalls(FLAG_harmony_tailcalls && !info->is_native() && 546 info->isolate()->is_tail_call_elimination_enabled()); 547 set_allow_harmony_do_expressions(FLAG_harmony_do_expressions); 548 set_allow_harmony_function_sent(FLAG_harmony_function_sent); 549 set_allow_harmony_restrictive_generators(FLAG_harmony_restrictive_generators); 550 set_allow_harmony_trailing_commas(FLAG_harmony_trailing_commas); 551 set_allow_harmony_class_fields(FLAG_harmony_class_fields); 552 set_allow_harmony_object_rest_spread(FLAG_harmony_object_rest_spread); 553 set_allow_harmony_dynamic_import(FLAG_harmony_dynamic_import); 554 set_allow_harmony_async_iteration(FLAG_harmony_async_iteration); 555 set_allow_harmony_template_escapes(FLAG_harmony_template_escapes); 556 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; 557 ++feature) { 558 use_counts_[feature] = 0; 559 } 560 if (info->ast_value_factory() == NULL) { 561 // info takes ownership of AstValueFactory. 562 info->set_ast_value_factory(new AstValueFactory( 563 zone(), info->isolate()->ast_string_constants(), info->hash_seed())); 564 info->set_ast_value_factory_owned(); 565 ast_value_factory_ = info->ast_value_factory(); 566 ast_node_factory_.set_ast_value_factory(ast_value_factory_); 567 } 568 } 569 570 void Parser::DeserializeScopeChain( 571 ParseInfo* info, MaybeHandle<ScopeInfo> maybe_outer_scope_info) { 572 DCHECK(ThreadId::Current().Equals(info->isolate()->thread_id())); 573 // TODO(wingo): Add an outer SCRIPT_SCOPE corresponding to the native 574 // context, which will have the "this" binding for script scopes. 575 DeclarationScope* script_scope = NewScriptScope(); 576 info->set_script_scope(script_scope); 577 Scope* scope = script_scope; 578 Handle<ScopeInfo> outer_scope_info; 579 if (maybe_outer_scope_info.ToHandle(&outer_scope_info)) { 580 scope = Scope::DeserializeScopeChain( 581 info->isolate(), zone(), *outer_scope_info, script_scope, 582 ast_value_factory(), Scope::DeserializationMode::kScopesOnly); 583 DCHECK(!info->is_module() || scope->is_module_scope()); 584 } 585 original_scope_ = scope; 586 } 587 588 FunctionLiteral* Parser::ParseProgram(Isolate* isolate, ParseInfo* info) { 589 // TODO(bmeurer): We temporarily need to pass allow_nesting = true here, 590 // see comment for HistogramTimerScope class. 591 592 // It's OK to use the Isolate & counters here, since this function is only 593 // called in the main thread. 594 DCHECK(parsing_on_main_thread_); 595 RuntimeCallTimerScope runtime_timer( 596 runtime_call_stats_, info->is_eval() ? &RuntimeCallStats::ParseEval 597 : &RuntimeCallStats::ParseProgram); 598 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.ParseProgram"); 599 Handle<String> source(String::cast(info->script()->source())); 600 isolate->counters()->total_parse_size()->Increment(source->length()); 601 base::ElapsedTimer timer; 602 if (FLAG_trace_parse) { 603 timer.Start(); 604 } 605 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone()); 606 607 // Initialize parser state. 608 ParserLogger logger; 609 610 if (produce_cached_parse_data()) { 611 if (allow_lazy_) { 612 log_ = &logger; 613 } else { 614 compile_options_ = ScriptCompiler::kNoCompileOptions; 615 } 616 } else if (consume_cached_parse_data()) { 617 cached_parse_data_->Initialize(); 618 } 619 620 DeserializeScopeChain(info, info->maybe_outer_scope_info()); 621 622 source = String::Flatten(source); 623 FunctionLiteral* result; 624 625 { 626 std::unique_ptr<Utf16CharacterStream> stream(ScannerStream::For(source)); 627 scanner_.Initialize(stream.get()); 628 result = DoParseProgram(info); 629 } 630 if (result != NULL) { 631 DCHECK_EQ(scanner_.peek_location().beg_pos, source->length()); 632 } 633 HandleSourceURLComments(isolate, info->script()); 634 635 if (FLAG_trace_parse && result != nullptr) { 636 double ms = timer.Elapsed().InMillisecondsF(); 637 if (info->is_eval()) { 638 PrintF("[parsing eval"); 639 } else if (info->script()->name()->IsString()) { 640 String* name = String::cast(info->script()->name()); 641 std::unique_ptr<char[]> name_chars = name->ToCString(); 642 PrintF("[parsing script: %s", name_chars.get()); 643 } else { 644 PrintF("[parsing script"); 645 } 646 PrintF(" - took %0.3f ms]\n", ms); 647 } 648 if (produce_cached_parse_data() && result != nullptr) { 649 *info->cached_data() = logger.GetScriptData(); 650 } 651 log_ = nullptr; 652 return result; 653 } 654 655 656 FunctionLiteral* Parser::DoParseProgram(ParseInfo* info) { 657 // Note that this function can be called from the main thread or from a 658 // background thread. We should not access anything Isolate / heap dependent 659 // via ParseInfo, and also not pass it forward. 660 DCHECK_NULL(scope_); 661 DCHECK_NULL(target_stack_); 662 663 ParsingModeScope mode(this, allow_lazy_ ? PARSE_LAZILY : PARSE_EAGERLY); 664 ResetFunctionLiteralId(); 665 DCHECK(info->function_literal_id() == FunctionLiteral::kIdTypeTopLevel || 666 info->function_literal_id() == FunctionLiteral::kIdTypeInvalid); 667 668 FunctionLiteral* result = NULL; 669 { 670 Scope* outer = original_scope_; 671 DCHECK_NOT_NULL(outer); 672 parsing_module_ = info->is_module(); 673 if (info->is_eval()) { 674 outer = NewEvalScope(outer); 675 } else if (parsing_module_) { 676 DCHECK_EQ(outer, info->script_scope()); 677 outer = NewModuleScope(info->script_scope()); 678 } 679 680 DeclarationScope* scope = outer->AsDeclarationScope(); 681 682 scope->set_start_position(0); 683 684 FunctionState function_state(&function_state_, &scope_, scope); 685 686 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); 687 bool ok = true; 688 int beg_pos = scanner()->location().beg_pos; 689 if (parsing_module_) { 690 // Declare the special module parameter. 691 auto name = ast_value_factory()->empty_string(); 692 bool is_duplicate; 693 bool is_rest = false; 694 bool is_optional = false; 695 auto var = scope->DeclareParameter(name, VAR, is_optional, is_rest, 696 &is_duplicate, ast_value_factory()); 697 DCHECK(!is_duplicate); 698 var->AllocateTo(VariableLocation::PARAMETER, 0); 699 700 PrepareGeneratorVariables(); 701 Expression* initial_yield = 702 BuildInitialYield(kNoSourcePosition, kGeneratorFunction); 703 body->Add( 704 factory()->NewExpressionStatement(initial_yield, kNoSourcePosition), 705 zone()); 706 707 ParseModuleItemList(body, &ok); 708 ok = ok && 709 module()->Validate(this->scope()->AsModuleScope(), 710 &pending_error_handler_, zone()); 711 } else { 712 // Don't count the mode in the use counters--give the program a chance 713 // to enable script-wide strict mode below. 714 this->scope()->SetLanguageMode(info->language_mode()); 715 ParseStatementList(body, Token::EOS, &ok); 716 } 717 718 // The parser will peek but not consume EOS. Our scope logically goes all 719 // the way to the EOS, though. 720 scope->set_end_position(scanner()->peek_location().beg_pos); 721 722 if (ok && is_strict(language_mode())) { 723 CheckStrictOctalLiteral(beg_pos, scanner()->location().end_pos, &ok); 724 } 725 if (ok && is_sloppy(language_mode())) { 726 // TODO(littledan): Function bindings on the global object that modify 727 // pre-existing bindings should be made writable, enumerable and 728 // nonconfigurable if possible, whereas this code will leave attributes 729 // unchanged if the property already exists. 730 InsertSloppyBlockFunctionVarBindings(scope); 731 } 732 if (ok) { 733 CheckConflictingVarDeclarations(scope, &ok); 734 } 735 736 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) { 737 if (body->length() != 1 || 738 !body->at(0)->IsExpressionStatement() || 739 !body->at(0)->AsExpressionStatement()-> 740 expression()->IsFunctionLiteral()) { 741 ReportMessage(MessageTemplate::kSingleFunctionLiteral); 742 ok = false; 743 } 744 } 745 746 if (ok) { 747 RewriteDestructuringAssignments(); 748 int parameter_count = parsing_module_ ? 1 : 0; 749 result = factory()->NewScriptOrEvalFunctionLiteral( 750 scope, body, function_state.expected_property_count(), 751 parameter_count); 752 } 753 } 754 755 info->set_max_function_literal_id(GetLastFunctionLiteralId()); 756 757 // Make sure the target stack is empty. 758 DCHECK(target_stack_ == NULL); 759 760 return result; 761 } 762 763 FunctionLiteral* Parser::ParseFunction(Isolate* isolate, ParseInfo* info) { 764 // It's OK to use the Isolate & counters here, since this function is only 765 // called in the main thread. 766 DCHECK(parsing_on_main_thread_); 767 RuntimeCallTimerScope runtime_timer(runtime_call_stats_, 768 &RuntimeCallStats::ParseFunction); 769 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.ParseFunction"); 770 Handle<String> source(String::cast(info->script()->source())); 771 isolate->counters()->total_parse_size()->Increment(source->length()); 772 base::ElapsedTimer timer; 773 if (FLAG_trace_parse) { 774 timer.Start(); 775 } 776 Handle<SharedFunctionInfo> shared_info = info->shared_info(); 777 DeserializeScopeChain(info, info->maybe_outer_scope_info()); 778 if (info->asm_function_scope()) { 779 original_scope_ = info->asm_function_scope(); 780 factory()->set_zone(info->zone()); 781 } else { 782 DCHECK_EQ(factory()->zone(), info->zone()); 783 } 784 785 // Initialize parser state. 786 source = String::Flatten(source); 787 FunctionLiteral* result; 788 { 789 std::unique_ptr<Utf16CharacterStream> stream(ScannerStream::For( 790 source, shared_info->start_position(), shared_info->end_position())); 791 Handle<String> name(String::cast(shared_info->name())); 792 result = DoParseFunction(info, ast_value_factory()->GetString(name), 793 stream.get()); 794 if (result != nullptr) { 795 Handle<String> inferred_name(shared_info->inferred_name()); 796 result->set_inferred_name(inferred_name); 797 } 798 } 799 800 if (FLAG_trace_parse && result != NULL) { 801 double ms = timer.Elapsed().InMillisecondsF(); 802 // We need to make sure that the debug-name is available. 803 ast_value_factory()->Internalize(isolate); 804 std::unique_ptr<char[]> name_chars = result->debug_name()->ToCString(); 805 PrintF("[parsing function: %s - took %0.3f ms]\n", name_chars.get(), ms); 806 } 807 return result; 808 } 809 810 static FunctionLiteral::FunctionType ComputeFunctionType(ParseInfo* info) { 811 if (info->is_declaration()) { 812 return FunctionLiteral::kDeclaration; 813 } else if (info->is_named_expression()) { 814 return FunctionLiteral::kNamedExpression; 815 } else if (IsConciseMethod(info->function_kind()) || 816 IsAccessorFunction(info->function_kind())) { 817 return FunctionLiteral::kAccessorOrMethod; 818 } 819 return FunctionLiteral::kAnonymousExpression; 820 } 821 822 FunctionLiteral* Parser::DoParseFunction(ParseInfo* info, 823 const AstRawString* raw_name, 824 Utf16CharacterStream* source) { 825 scanner_.Initialize(source); 826 DCHECK_NULL(scope_); 827 DCHECK_NULL(target_stack_); 828 829 DCHECK(ast_value_factory()); 830 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone()); 831 fni_->PushEnclosingName(raw_name); 832 833 ResetFunctionLiteralId(); 834 DCHECK_LT(0, info->function_literal_id()); 835 SkipFunctionLiterals(info->function_literal_id() - 1); 836 837 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); 838 839 // Place holder for the result. 840 FunctionLiteral* result = nullptr; 841 842 { 843 // Parse the function literal. 844 Scope* outer = original_scope_; 845 DeclarationScope* outer_function = outer->GetClosureScope(); 846 DCHECK(outer); 847 FunctionState function_state(&function_state_, &scope_, outer_function); 848 BlockState block_state(&scope_, outer); 849 DCHECK(is_sloppy(outer->language_mode()) || 850 is_strict(info->language_mode())); 851 FunctionLiteral::FunctionType function_type = ComputeFunctionType(info); 852 FunctionKind kind = info->function_kind(); 853 bool ok = true; 854 855 if (IsArrowFunction(kind)) { 856 if (IsAsyncFunction(kind)) { 857 DCHECK(!scanner()->HasAnyLineTerminatorAfterNext()); 858 if (!Check(Token::ASYNC)) { 859 CHECK(stack_overflow()); 860 return nullptr; 861 } 862 if (!(peek_any_identifier() || peek() == Token::LPAREN)) { 863 CHECK(stack_overflow()); 864 return nullptr; 865 } 866 } 867 868 // TODO(adamk): We should construct this scope from the ScopeInfo. 869 DeclarationScope* scope = NewFunctionScope(kind); 870 871 // These two bits only need to be explicitly set because we're 872 // not passing the ScopeInfo to the Scope constructor. 873 // TODO(adamk): Remove these calls once the above NewScope call 874 // passes the ScopeInfo. 875 if (info->calls_eval()) { 876 scope->RecordEvalCall(); 877 } 878 SetLanguageMode(scope, info->language_mode()); 879 880 scope->set_start_position(info->start_position()); 881 ExpressionClassifier formals_classifier(this); 882 ParserFormalParameters formals(scope); 883 int rewritable_length = 884 function_state.destructuring_assignments_to_rewrite().length(); 885 Checkpoint checkpoint(this); 886 { 887 // Parsing patterns as variable reference expression creates 888 // NewUnresolved references in current scope. Entrer arrow function 889 // scope for formal parameter parsing. 890 BlockState block_state(&scope_, scope); 891 if (Check(Token::LPAREN)) { 892 // '(' StrictFormalParameters ')' 893 ParseFormalParameterList(&formals, &ok); 894 if (ok) ok = Check(Token::RPAREN); 895 } else { 896 // BindingIdentifier 897 ParseFormalParameter(&formals, &ok); 898 if (ok) DeclareFormalParameters(formals.scope, formals.params); 899 } 900 } 901 902 if (ok) { 903 checkpoint.Restore(&formals.materialized_literals_count); 904 if (GetLastFunctionLiteralId() != info->function_literal_id() - 1) { 905 // If there were FunctionLiterals in the parameters, we need to 906 // renumber them to shift down so the next function literal id for 907 // the arrow function is the one requested. 908 AstFunctionLiteralIdReindexer reindexer( 909 stack_limit_, 910 (info->function_literal_id() - 1) - GetLastFunctionLiteralId()); 911 for (auto p : formals.params) { 912 if (p->pattern != nullptr) reindexer.Reindex(p->pattern); 913 if (p->initializer != nullptr) reindexer.Reindex(p->initializer); 914 } 915 ResetFunctionLiteralId(); 916 SkipFunctionLiterals(info->function_literal_id() - 1); 917 } 918 919 // Pass `accept_IN=true` to ParseArrowFunctionLiteral --- This should 920 // not be observable, or else the preparser would have failed. 921 Expression* expression = 922 ParseArrowFunctionLiteral(true, formals, rewritable_length, &ok); 923 if (ok) { 924 // Scanning must end at the same position that was recorded 925 // previously. If not, parsing has been interrupted due to a stack 926 // overflow, at which point the partially parsed arrow function 927 // concise body happens to be a valid expression. This is a problem 928 // only for arrow functions with single expression bodies, since there 929 // is no end token such as "}" for normal functions. 930 if (scanner()->location().end_pos == info->end_position()) { 931 // The pre-parser saw an arrow function here, so the full parser 932 // must produce a FunctionLiteral. 933 DCHECK(expression->IsFunctionLiteral()); 934 result = expression->AsFunctionLiteral(); 935 // Rewrite destructuring assignments in the parameters. (The ones 936 // inside the function body are rewritten by 937 // ParseArrowFunctionLiteral.) 938 RewriteDestructuringAssignments(); 939 } else { 940 ok = false; 941 } 942 } 943 } 944 } else if (IsDefaultConstructor(kind)) { 945 DCHECK_EQ(scope(), outer); 946 result = DefaultConstructor(raw_name, IsDerivedConstructor(kind), 947 info->start_position(), info->end_position()); 948 } else { 949 result = ParseFunctionLiteral( 950 raw_name, Scanner::Location::invalid(), kSkipFunctionNameCheck, kind, 951 kNoSourcePosition, function_type, info->language_mode(), &ok); 952 } 953 // Make sure the results agree. 954 DCHECK(ok == (result != nullptr)); 955 } 956 957 // Make sure the target stack is empty. 958 DCHECK_NULL(target_stack_); 959 DCHECK_IMPLIES(result, 960 info->function_literal_id() == result->function_literal_id()); 961 return result; 962 } 963 964 Statement* Parser::ParseModuleItem(bool* ok) { 965 // ecma262/#prod-ModuleItem 966 // ModuleItem : 967 // ImportDeclaration 968 // ExportDeclaration 969 // StatementListItem 970 971 Token::Value next = peek(); 972 973 if (next == Token::EXPORT) { 974 return ParseExportDeclaration(ok); 975 } 976 977 // We must be careful not to parse a dynamic import expression as an import 978 // declaration. 979 if (next == Token::IMPORT && 980 (!allow_harmony_dynamic_import() || PeekAhead() != Token::LPAREN)) { 981 ParseImportDeclaration(CHECK_OK); 982 return factory()->NewEmptyStatement(kNoSourcePosition); 983 } 984 985 return ParseStatementListItem(ok); 986 } 987 988 989 void Parser::ParseModuleItemList(ZoneList<Statement*>* body, bool* ok) { 990 // ecma262/#prod-Module 991 // Module : 992 // ModuleBody? 993 // 994 // ecma262/#prod-ModuleItemList 995 // ModuleBody : 996 // ModuleItem* 997 998 DCHECK(scope()->is_module_scope()); 999 while (peek() != Token::EOS) { 1000 Statement* stat = ParseModuleItem(CHECK_OK_VOID); 1001 if (stat && !stat->IsEmpty()) { 1002 body->Add(stat, zone()); 1003 } 1004 } 1005 } 1006 1007 1008 const AstRawString* Parser::ParseModuleSpecifier(bool* ok) { 1009 // ModuleSpecifier : 1010 // StringLiteral 1011 1012 Expect(Token::STRING, CHECK_OK); 1013 return GetSymbol(); 1014 } 1015 1016 1017 void Parser::ParseExportClause(ZoneList<const AstRawString*>* export_names, 1018 ZoneList<Scanner::Location>* export_locations, 1019 ZoneList<const AstRawString*>* local_names, 1020 Scanner::Location* reserved_loc, bool* ok) { 1021 // ExportClause : 1022 // '{' '}' 1023 // '{' ExportsList '}' 1024 // '{' ExportsList ',' '}' 1025 // 1026 // ExportsList : 1027 // ExportSpecifier 1028 // ExportsList ',' ExportSpecifier 1029 // 1030 // ExportSpecifier : 1031 // IdentifierName 1032 // IdentifierName 'as' IdentifierName 1033 1034 Expect(Token::LBRACE, CHECK_OK_VOID); 1035 1036 Token::Value name_tok; 1037 while ((name_tok = peek()) != Token::RBRACE) { 1038 // Keep track of the first reserved word encountered in case our 1039 // caller needs to report an error. 1040 if (!reserved_loc->IsValid() && 1041 !Token::IsIdentifier(name_tok, STRICT, false, parsing_module_)) { 1042 *reserved_loc = scanner()->location(); 1043 } 1044 const AstRawString* local_name = ParseIdentifierName(CHECK_OK_VOID); 1045 const AstRawString* export_name = NULL; 1046 Scanner::Location location = scanner()->location(); 1047 if (CheckContextualKeyword(CStrVector("as"))) { 1048 export_name = ParseIdentifierName(CHECK_OK_VOID); 1049 // Set the location to the whole "a as b" string, so that it makes sense 1050 // both for errors due to "a" and for errors due to "b". 1051 location.end_pos = scanner()->location().end_pos; 1052 } 1053 if (export_name == NULL) { 1054 export_name = local_name; 1055 } 1056 export_names->Add(export_name, zone()); 1057 local_names->Add(local_name, zone()); 1058 export_locations->Add(location, zone()); 1059 if (peek() == Token::RBRACE) break; 1060 Expect(Token::COMMA, CHECK_OK_VOID); 1061 } 1062 1063 Expect(Token::RBRACE, CHECK_OK_VOID); 1064 } 1065 1066 1067 ZoneList<const Parser::NamedImport*>* Parser::ParseNamedImports( 1068 int pos, bool* ok) { 1069 // NamedImports : 1070 // '{' '}' 1071 // '{' ImportsList '}' 1072 // '{' ImportsList ',' '}' 1073 // 1074 // ImportsList : 1075 // ImportSpecifier 1076 // ImportsList ',' ImportSpecifier 1077 // 1078 // ImportSpecifier : 1079 // BindingIdentifier 1080 // IdentifierName 'as' BindingIdentifier 1081 1082 Expect(Token::LBRACE, CHECK_OK); 1083 1084 auto result = new (zone()) ZoneList<const NamedImport*>(1, zone()); 1085 while (peek() != Token::RBRACE) { 1086 const AstRawString* import_name = ParseIdentifierName(CHECK_OK); 1087 const AstRawString* local_name = import_name; 1088 Scanner::Location location = scanner()->location(); 1089 // In the presence of 'as', the left-side of the 'as' can 1090 // be any IdentifierName. But without 'as', it must be a valid 1091 // BindingIdentifier. 1092 if (CheckContextualKeyword(CStrVector("as"))) { 1093 local_name = ParseIdentifierName(CHECK_OK); 1094 } 1095 if (!Token::IsIdentifier(scanner()->current_token(), STRICT, false, 1096 parsing_module_)) { 1097 *ok = false; 1098 ReportMessage(MessageTemplate::kUnexpectedReserved); 1099 return nullptr; 1100 } else if (IsEvalOrArguments(local_name)) { 1101 *ok = false; 1102 ReportMessage(MessageTemplate::kStrictEvalArguments); 1103 return nullptr; 1104 } 1105 1106 DeclareVariable(local_name, CONST, kNeedsInitialization, position(), 1107 CHECK_OK); 1108 1109 NamedImport* import = 1110 new (zone()) NamedImport(import_name, local_name, location); 1111 result->Add(import, zone()); 1112 1113 if (peek() == Token::RBRACE) break; 1114 Expect(Token::COMMA, CHECK_OK); 1115 } 1116 1117 Expect(Token::RBRACE, CHECK_OK); 1118 return result; 1119 } 1120 1121 1122 void Parser::ParseImportDeclaration(bool* ok) { 1123 // ImportDeclaration : 1124 // 'import' ImportClause 'from' ModuleSpecifier ';' 1125 // 'import' ModuleSpecifier ';' 1126 // 1127 // ImportClause : 1128 // ImportedDefaultBinding 1129 // NameSpaceImport 1130 // NamedImports 1131 // ImportedDefaultBinding ',' NameSpaceImport 1132 // ImportedDefaultBinding ',' NamedImports 1133 // 1134 // NameSpaceImport : 1135 // '*' 'as' ImportedBinding 1136 1137 int pos = peek_position(); 1138 Expect(Token::IMPORT, CHECK_OK_VOID); 1139 1140 Token::Value tok = peek(); 1141 1142 // 'import' ModuleSpecifier ';' 1143 if (tok == Token::STRING) { 1144 const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK_VOID); 1145 ExpectSemicolon(CHECK_OK_VOID); 1146 module()->AddEmptyImport(module_specifier); 1147 return; 1148 } 1149 1150 // Parse ImportedDefaultBinding if present. 1151 const AstRawString* import_default_binding = nullptr; 1152 Scanner::Location import_default_binding_loc; 1153 if (tok != Token::MUL && tok != Token::LBRACE) { 1154 import_default_binding = 1155 ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK_VOID); 1156 import_default_binding_loc = scanner()->location(); 1157 DeclareVariable(import_default_binding, CONST, kNeedsInitialization, pos, 1158 CHECK_OK_VOID); 1159 } 1160 1161 // Parse NameSpaceImport or NamedImports if present. 1162 const AstRawString* module_namespace_binding = nullptr; 1163 Scanner::Location module_namespace_binding_loc; 1164 const ZoneList<const NamedImport*>* named_imports = nullptr; 1165 if (import_default_binding == nullptr || Check(Token::COMMA)) { 1166 switch (peek()) { 1167 case Token::MUL: { 1168 Consume(Token::MUL); 1169 ExpectContextualKeyword(CStrVector("as"), CHECK_OK_VOID); 1170 module_namespace_binding = 1171 ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK_VOID); 1172 module_namespace_binding_loc = scanner()->location(); 1173 DeclareVariable(module_namespace_binding, CONST, kCreatedInitialized, 1174 pos, CHECK_OK_VOID); 1175 break; 1176 } 1177 1178 case Token::LBRACE: 1179 named_imports = ParseNamedImports(pos, CHECK_OK_VOID); 1180 break; 1181 1182 default: 1183 *ok = false; 1184 ReportUnexpectedToken(scanner()->current_token()); 1185 return; 1186 } 1187 } 1188 1189 ExpectContextualKeyword(CStrVector("from"), CHECK_OK_VOID); 1190 const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK_VOID); 1191 ExpectSemicolon(CHECK_OK_VOID); 1192 1193 // Now that we have all the information, we can make the appropriate 1194 // declarations. 1195 1196 // TODO(neis): Would prefer to call DeclareVariable for each case below rather 1197 // than above and in ParseNamedImports, but then a possible error message 1198 // would point to the wrong location. Maybe have a DeclareAt version of 1199 // Declare that takes a location? 1200 1201 if (module_namespace_binding != nullptr) { 1202 module()->AddStarImport(module_namespace_binding, module_specifier, 1203 module_namespace_binding_loc, zone()); 1204 } 1205 1206 if (import_default_binding != nullptr) { 1207 module()->AddImport(ast_value_factory()->default_string(), 1208 import_default_binding, module_specifier, 1209 import_default_binding_loc, zone()); 1210 } 1211 1212 if (named_imports != nullptr) { 1213 if (named_imports->length() == 0) { 1214 module()->AddEmptyImport(module_specifier); 1215 } else { 1216 for (int i = 0; i < named_imports->length(); ++i) { 1217 const NamedImport* import = named_imports->at(i); 1218 module()->AddImport(import->import_name, import->local_name, 1219 module_specifier, import->location, zone()); 1220 } 1221 } 1222 } 1223 } 1224 1225 1226 Statement* Parser::ParseExportDefault(bool* ok) { 1227 // Supports the following productions, starting after the 'default' token: 1228 // 'export' 'default' HoistableDeclaration 1229 // 'export' 'default' ClassDeclaration 1230 // 'export' 'default' AssignmentExpression[In] ';' 1231 1232 Expect(Token::DEFAULT, CHECK_OK); 1233 Scanner::Location default_loc = scanner()->location(); 1234 1235 ZoneList<const AstRawString*> local_names(1, zone()); 1236 Statement* result = nullptr; 1237 switch (peek()) { 1238 case Token::FUNCTION: 1239 result = ParseHoistableDeclaration(&local_names, true, CHECK_OK); 1240 break; 1241 1242 case Token::CLASS: 1243 Consume(Token::CLASS); 1244 result = ParseClassDeclaration(&local_names, true, CHECK_OK); 1245 break; 1246 1247 case Token::ASYNC: 1248 if (PeekAhead() == Token::FUNCTION && 1249 !scanner()->HasAnyLineTerminatorAfterNext()) { 1250 Consume(Token::ASYNC); 1251 result = ParseAsyncFunctionDeclaration(&local_names, true, CHECK_OK); 1252 break; 1253 } 1254 /* falls through */ 1255 1256 default: { 1257 int pos = position(); 1258 ExpressionClassifier classifier(this); 1259 Expression* value = ParseAssignmentExpression(true, CHECK_OK); 1260 RewriteNonPattern(CHECK_OK); 1261 SetFunctionName(value, ast_value_factory()->default_string()); 1262 1263 const AstRawString* local_name = 1264 ast_value_factory()->star_default_star_string(); 1265 local_names.Add(local_name, zone()); 1266 1267 // It's fine to declare this as CONST because the user has no way of 1268 // writing to it. 1269 Declaration* decl = DeclareVariable(local_name, CONST, pos, CHECK_OK); 1270 decl->proxy()->var()->set_initializer_position(position()); 1271 1272 Assignment* assignment = factory()->NewAssignment( 1273 Token::INIT, decl->proxy(), value, kNoSourcePosition); 1274 result = factory()->NewExpressionStatement(assignment, kNoSourcePosition); 1275 1276 ExpectSemicolon(CHECK_OK); 1277 break; 1278 } 1279 } 1280 1281 DCHECK_EQ(local_names.length(), 1); 1282 module()->AddExport(local_names.first(), 1283 ast_value_factory()->default_string(), default_loc, 1284 zone()); 1285 1286 DCHECK_NOT_NULL(result); 1287 return result; 1288 } 1289 1290 Statement* Parser::ParseExportDeclaration(bool* ok) { 1291 // ExportDeclaration: 1292 // 'export' '*' 'from' ModuleSpecifier ';' 1293 // 'export' ExportClause ('from' ModuleSpecifier)? ';' 1294 // 'export' VariableStatement 1295 // 'export' Declaration 1296 // 'export' 'default' ... (handled in ParseExportDefault) 1297 1298 Expect(Token::EXPORT, CHECK_OK); 1299 int pos = position(); 1300 1301 Statement* result = nullptr; 1302 ZoneList<const AstRawString*> names(1, zone()); 1303 Scanner::Location loc = scanner()->peek_location(); 1304 switch (peek()) { 1305 case Token::DEFAULT: 1306 return ParseExportDefault(ok); 1307 1308 case Token::MUL: { 1309 Consume(Token::MUL); 1310 loc = scanner()->location(); 1311 ExpectContextualKeyword(CStrVector("from"), CHECK_OK); 1312 const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK); 1313 ExpectSemicolon(CHECK_OK); 1314 module()->AddStarExport(module_specifier, loc, zone()); 1315 return factory()->NewEmptyStatement(pos); 1316 } 1317 1318 case Token::LBRACE: { 1319 // There are two cases here: 1320 // 1321 // 'export' ExportClause ';' 1322 // and 1323 // 'export' ExportClause FromClause ';' 1324 // 1325 // In the first case, the exported identifiers in ExportClause must 1326 // not be reserved words, while in the latter they may be. We 1327 // pass in a location that gets filled with the first reserved word 1328 // encountered, and then throw a SyntaxError if we are in the 1329 // non-FromClause case. 1330 Scanner::Location reserved_loc = Scanner::Location::invalid(); 1331 ZoneList<const AstRawString*> export_names(1, zone()); 1332 ZoneList<Scanner::Location> export_locations(1, zone()); 1333 ZoneList<const AstRawString*> original_names(1, zone()); 1334 ParseExportClause(&export_names, &export_locations, &original_names, 1335 &reserved_loc, CHECK_OK); 1336 const AstRawString* module_specifier = nullptr; 1337 if (CheckContextualKeyword(CStrVector("from"))) { 1338 module_specifier = ParseModuleSpecifier(CHECK_OK); 1339 } else if (reserved_loc.IsValid()) { 1340 // No FromClause, so reserved words are invalid in ExportClause. 1341 *ok = false; 1342 ReportMessageAt(reserved_loc, MessageTemplate::kUnexpectedReserved); 1343 return nullptr; 1344 } 1345 ExpectSemicolon(CHECK_OK); 1346 const int length = export_names.length(); 1347 DCHECK_EQ(length, original_names.length()); 1348 DCHECK_EQ(length, export_locations.length()); 1349 if (module_specifier == nullptr) { 1350 for (int i = 0; i < length; ++i) { 1351 module()->AddExport(original_names[i], export_names[i], 1352 export_locations[i], zone()); 1353 } 1354 } else if (length == 0) { 1355 module()->AddEmptyImport(module_specifier); 1356 } else { 1357 for (int i = 0; i < length; ++i) { 1358 module()->AddExport(original_names[i], export_names[i], 1359 module_specifier, export_locations[i], zone()); 1360 } 1361 } 1362 return factory()->NewEmptyStatement(pos); 1363 } 1364 1365 case Token::FUNCTION: 1366 result = ParseHoistableDeclaration(&names, false, CHECK_OK); 1367 break; 1368 1369 case Token::CLASS: 1370 Consume(Token::CLASS); 1371 result = ParseClassDeclaration(&names, false, CHECK_OK); 1372 break; 1373 1374 case Token::VAR: 1375 case Token::LET: 1376 case Token::CONST: 1377 result = ParseVariableStatement(kStatementListItem, &names, CHECK_OK); 1378 break; 1379 1380 case Token::ASYNC: 1381 // TODO(neis): Why don't we have the same check here as in 1382 // ParseStatementListItem? 1383 Consume(Token::ASYNC); 1384 result = ParseAsyncFunctionDeclaration(&names, false, CHECK_OK); 1385 break; 1386 1387 default: 1388 *ok = false; 1389 ReportUnexpectedToken(scanner()->current_token()); 1390 return nullptr; 1391 } 1392 loc.end_pos = scanner()->location().end_pos; 1393 1394 ModuleDescriptor* descriptor = module(); 1395 for (int i = 0; i < names.length(); ++i) { 1396 descriptor->AddExport(names[i], names[i], loc, zone()); 1397 } 1398 1399 DCHECK_NOT_NULL(result); 1400 return result; 1401 } 1402 1403 VariableProxy* Parser::NewUnresolved(const AstRawString* name, int begin_pos, 1404 VariableKind kind) { 1405 return scope()->NewUnresolved(factory(), name, begin_pos, kind); 1406 } 1407 1408 VariableProxy* Parser::NewUnresolved(const AstRawString* name) { 1409 return scope()->NewUnresolved(factory(), name, scanner()->location().beg_pos); 1410 } 1411 1412 Declaration* Parser::DeclareVariable(const AstRawString* name, 1413 VariableMode mode, int pos, bool* ok) { 1414 return DeclareVariable(name, mode, Variable::DefaultInitializationFlag(mode), 1415 pos, ok); 1416 } 1417 1418 Declaration* Parser::DeclareVariable(const AstRawString* name, 1419 VariableMode mode, InitializationFlag init, 1420 int pos, bool* ok) { 1421 DCHECK_NOT_NULL(name); 1422 VariableProxy* proxy = factory()->NewVariableProxy( 1423 name, NORMAL_VARIABLE, scanner()->location().beg_pos); 1424 Declaration* declaration = 1425 factory()->NewVariableDeclaration(proxy, this->scope(), pos); 1426 Declare(declaration, DeclarationDescriptor::NORMAL, mode, init, ok, nullptr, 1427 scanner()->location().end_pos); 1428 if (!*ok) return nullptr; 1429 return declaration; 1430 } 1431 1432 Variable* Parser::Declare(Declaration* declaration, 1433 DeclarationDescriptor::Kind declaration_kind, 1434 VariableMode mode, InitializationFlag init, bool* ok, 1435 Scope* scope, int var_end_pos) { 1436 if (scope == nullptr) { 1437 scope = this->scope(); 1438 } 1439 bool sloppy_mode_block_scope_function_redefinition = false; 1440 Variable* variable = scope->DeclareVariable( 1441 declaration, mode, init, allow_harmony_restrictive_generators(), 1442 &sloppy_mode_block_scope_function_redefinition, ok); 1443 if (!*ok) { 1444 // If we only have the start position of a proxy, we can't highlight the 1445 // whole variable name. Pretend its length is 1 so that we highlight at 1446 // least the first character. 1447 Scanner::Location loc(declaration->proxy()->position(), 1448 var_end_pos != kNoSourcePosition 1449 ? var_end_pos 1450 : declaration->proxy()->position() + 1); 1451 if (declaration_kind == DeclarationDescriptor::NORMAL) { 1452 ReportMessageAt(loc, MessageTemplate::kVarRedeclaration, 1453 declaration->proxy()->raw_name()); 1454 } else { 1455 ReportMessageAt(loc, MessageTemplate::kParamDupe); 1456 } 1457 return nullptr; 1458 } 1459 if (sloppy_mode_block_scope_function_redefinition) { 1460 ++use_counts_[v8::Isolate::kSloppyModeBlockScopedFunctionRedefinition]; 1461 } 1462 return variable; 1463 } 1464 1465 Block* Parser::BuildInitializationBlock( 1466 DeclarationParsingResult* parsing_result, 1467 ZoneList<const AstRawString*>* names, bool* ok) { 1468 Block* result = factory()->NewBlock( 1469 NULL, 1, true, parsing_result->descriptor.declaration_pos); 1470 for (auto declaration : parsing_result->declarations) { 1471 PatternRewriter::DeclareAndInitializeVariables( 1472 this, result, &(parsing_result->descriptor), &declaration, names, 1473 CHECK_OK); 1474 } 1475 return result; 1476 } 1477 1478 void Parser::DeclareAndInitializeVariables( 1479 Block* block, const DeclarationDescriptor* declaration_descriptor, 1480 const DeclarationParsingResult::Declaration* declaration, 1481 ZoneList<const AstRawString*>* names, bool* ok) { 1482 DCHECK_NOT_NULL(block); 1483 PatternRewriter::DeclareAndInitializeVariables( 1484 this, block, declaration_descriptor, declaration, names, ok); 1485 } 1486 1487 Statement* Parser::DeclareFunction(const AstRawString* variable_name, 1488 FunctionLiteral* function, VariableMode mode, 1489 int pos, bool is_sloppy_block_function, 1490 ZoneList<const AstRawString*>* names, 1491 bool* ok) { 1492 VariableProxy* proxy = 1493 factory()->NewVariableProxy(variable_name, NORMAL_VARIABLE); 1494 1495 Declaration* declaration = 1496 factory()->NewFunctionDeclaration(proxy, function, scope(), pos); 1497 Declare(declaration, DeclarationDescriptor::NORMAL, mode, kCreatedInitialized, 1498 CHECK_OK); 1499 if (names) names->Add(variable_name, zone()); 1500 if (is_sloppy_block_function) { 1501 SloppyBlockFunctionStatement* statement = 1502 factory()->NewSloppyBlockFunctionStatement(); 1503 GetDeclarationScope()->DeclareSloppyBlockFunction(variable_name, scope(), 1504 statement); 1505 return statement; 1506 } 1507 return factory()->NewEmptyStatement(kNoSourcePosition); 1508 } 1509 1510 Statement* Parser::DeclareClass(const AstRawString* variable_name, 1511 Expression* value, 1512 ZoneList<const AstRawString*>* names, 1513 int class_token_pos, int end_pos, bool* ok) { 1514 Declaration* decl = 1515 DeclareVariable(variable_name, LET, class_token_pos, CHECK_OK); 1516 decl->proxy()->var()->set_initializer_position(end_pos); 1517 Assignment* assignment = factory()->NewAssignment(Token::INIT, decl->proxy(), 1518 value, class_token_pos); 1519 Statement* assignment_statement = 1520 factory()->NewExpressionStatement(assignment, kNoSourcePosition); 1521 if (names) names->Add(variable_name, zone()); 1522 return assignment_statement; 1523 } 1524 1525 Statement* Parser::DeclareNative(const AstRawString* name, int pos, bool* ok) { 1526 // Make sure that the function containing the native declaration 1527 // isn't lazily compiled. The extension structures are only 1528 // accessible while parsing the first time not when reparsing 1529 // because of lazy compilation. 1530 GetClosureScope()->ForceEagerCompilation(); 1531 1532 // TODO(1240846): It's weird that native function declarations are 1533 // introduced dynamically when we meet their declarations, whereas 1534 // other functions are set up when entering the surrounding scope. 1535 Declaration* decl = DeclareVariable(name, VAR, pos, CHECK_OK); 1536 NativeFunctionLiteral* lit = 1537 factory()->NewNativeFunctionLiteral(name, extension_, kNoSourcePosition); 1538 return factory()->NewExpressionStatement( 1539 factory()->NewAssignment(Token::INIT, decl->proxy(), lit, 1540 kNoSourcePosition), 1541 pos); 1542 } 1543 1544 ZoneList<const AstRawString*>* Parser::DeclareLabel( 1545 ZoneList<const AstRawString*>* labels, VariableProxy* var, bool* ok) { 1546 DCHECK(IsIdentifier(var)); 1547 const AstRawString* label = var->raw_name(); 1548 // TODO(1240780): We don't check for redeclaration of labels 1549 // during preparsing since keeping track of the set of active 1550 // labels requires nontrivial changes to the way scopes are 1551 // structured. However, these are probably changes we want to 1552 // make later anyway so we should go back and fix this then. 1553 if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) { 1554 ReportMessage(MessageTemplate::kLabelRedeclaration, label); 1555 *ok = false; 1556 return nullptr; 1557 } 1558 if (labels == nullptr) { 1559 labels = new (zone()) ZoneList<const AstRawString*>(1, zone()); 1560 } 1561 labels->Add(label, zone()); 1562 // Remove the "ghost" variable that turned out to be a label 1563 // from the top scope. This way, we don't try to resolve it 1564 // during the scope processing. 1565 scope()->RemoveUnresolved(var); 1566 return labels; 1567 } 1568 1569 bool Parser::ContainsLabel(ZoneList<const AstRawString*>* labels, 1570 const AstRawString* label) { 1571 DCHECK_NOT_NULL(label); 1572 if (labels != nullptr) { 1573 for (int i = labels->length(); i-- > 0;) { 1574 if (labels->at(i) == label) return true; 1575 } 1576 } 1577 return false; 1578 } 1579 1580 Expression* Parser::RewriteReturn(Expression* return_value, int pos) { 1581 if (IsDerivedConstructor(function_state_->kind())) { 1582 // For subclass constructors we need to return this in case of undefined 1583 // return a Smi (transformed into an exception in the ConstructStub) 1584 // for a non object. 1585 // 1586 // return expr; 1587 // 1588 // Is rewritten as: 1589 // 1590 // return (temp = expr) === undefined ? this : 1591 // %_IsJSReceiver(temp) ? temp : 1; 1592 1593 // temp = expr 1594 Variable* temp = NewTemporary(ast_value_factory()->empty_string()); 1595 Assignment* assign = factory()->NewAssignment( 1596 Token::ASSIGN, factory()->NewVariableProxy(temp), return_value, pos); 1597 1598 // %_IsJSReceiver(temp) 1599 ZoneList<Expression*>* is_spec_object_args = 1600 new (zone()) ZoneList<Expression*>(1, zone()); 1601 is_spec_object_args->Add(factory()->NewVariableProxy(temp), zone()); 1602 Expression* is_spec_object_call = factory()->NewCallRuntime( 1603 Runtime::kInlineIsJSReceiver, is_spec_object_args, pos); 1604 1605 // %_IsJSReceiver(temp) ? temp : 1; 1606 Expression* is_object_conditional = factory()->NewConditional( 1607 is_spec_object_call, factory()->NewVariableProxy(temp), 1608 factory()->NewSmiLiteral(1, pos), pos); 1609 1610 // temp === undefined 1611 Expression* is_undefined = factory()->NewCompareOperation( 1612 Token::EQ_STRICT, assign, 1613 factory()->NewUndefinedLiteral(kNoSourcePosition), pos); 1614 1615 // is_undefined ? this : is_object_conditional 1616 return_value = factory()->NewConditional(is_undefined, ThisExpression(pos), 1617 is_object_conditional, pos); 1618 } 1619 if (is_generator()) { 1620 return_value = BuildIteratorResult(return_value, true); 1621 } 1622 return return_value; 1623 } 1624 1625 Expression* Parser::RewriteDoExpression(Block* body, int pos, bool* ok) { 1626 Variable* result = NewTemporary(ast_value_factory()->dot_result_string()); 1627 DoExpression* expr = factory()->NewDoExpression(body, result, pos); 1628 if (!Rewriter::Rewrite(this, GetClosureScope(), expr, ast_value_factory())) { 1629 *ok = false; 1630 return nullptr; 1631 } 1632 return expr; 1633 } 1634 1635 Statement* Parser::RewriteSwitchStatement(Expression* tag, 1636 SwitchStatement* switch_statement, 1637 ZoneList<CaseClause*>* cases, 1638 Scope* scope) { 1639 // In order to get the CaseClauses to execute in their own lexical scope, 1640 // but without requiring downstream code to have special scope handling 1641 // code for switch statements, desugar into blocks as follows: 1642 // { // To group the statements--harmless to evaluate Expression in scope 1643 // .tag_variable = Expression; 1644 // { // To give CaseClauses a scope 1645 // switch (.tag_variable) { CaseClause* } 1646 // } 1647 // } 1648 1649 Block* switch_block = factory()->NewBlock(NULL, 2, false, kNoSourcePosition); 1650 1651 Variable* tag_variable = 1652 NewTemporary(ast_value_factory()->dot_switch_tag_string()); 1653 Assignment* tag_assign = factory()->NewAssignment( 1654 Token::ASSIGN, factory()->NewVariableProxy(tag_variable), tag, 1655 tag->position()); 1656 Statement* tag_statement = 1657 factory()->NewExpressionStatement(tag_assign, kNoSourcePosition); 1658 switch_block->statements()->Add(tag_statement, zone()); 1659 1660 // make statement: undefined; 1661 // This is needed so the tag isn't returned as the value, in case the switch 1662 // statements don't have a value. 1663 switch_block->statements()->Add( 1664 factory()->NewExpressionStatement( 1665 factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition), 1666 zone()); 1667 1668 Expression* tag_read = factory()->NewVariableProxy(tag_variable); 1669 switch_statement->Initialize(tag_read, cases); 1670 Block* cases_block = factory()->NewBlock(NULL, 1, false, kNoSourcePosition); 1671 cases_block->statements()->Add(switch_statement, zone()); 1672 cases_block->set_scope(scope); 1673 DCHECK_IMPLIES(scope != nullptr, 1674 switch_statement->position() >= scope->start_position()); 1675 DCHECK_IMPLIES(scope != nullptr, 1676 switch_statement->position() < scope->end_position()); 1677 switch_block->statements()->Add(cases_block, zone()); 1678 return switch_block; 1679 } 1680 1681 void Parser::RewriteCatchPattern(CatchInfo* catch_info, bool* ok) { 1682 if (catch_info->name == nullptr) { 1683 DCHECK_NOT_NULL(catch_info->pattern); 1684 catch_info->name = ast_value_factory()->dot_catch_string(); 1685 } 1686 catch_info->variable = catch_info->scope->DeclareLocal(catch_info->name, VAR); 1687 if (catch_info->pattern != nullptr) { 1688 DeclarationDescriptor descriptor; 1689 descriptor.declaration_kind = DeclarationDescriptor::NORMAL; 1690 descriptor.scope = scope(); 1691 descriptor.mode = LET; 1692 descriptor.declaration_pos = catch_info->pattern->position(); 1693 descriptor.initialization_pos = catch_info->pattern->position(); 1694 1695 // Initializer position for variables declared by the pattern. 1696 const int initializer_position = position(); 1697 1698 DeclarationParsingResult::Declaration decl( 1699 catch_info->pattern, initializer_position, 1700 factory()->NewVariableProxy(catch_info->variable)); 1701 1702 catch_info->init_block = 1703 factory()->NewBlock(nullptr, 8, true, kNoSourcePosition); 1704 PatternRewriter::DeclareAndInitializeVariables( 1705 this, catch_info->init_block, &descriptor, &decl, 1706 &catch_info->bound_names, ok); 1707 } else { 1708 catch_info->bound_names.Add(catch_info->name, zone()); 1709 } 1710 } 1711 1712 void Parser::ValidateCatchBlock(const CatchInfo& catch_info, bool* ok) { 1713 // Check for `catch(e) { let e; }` and similar errors. 1714 Scope* inner_block_scope = catch_info.inner_block->scope(); 1715 if (inner_block_scope != nullptr) { 1716 Declaration* decl = inner_block_scope->CheckLexDeclarationsConflictingWith( 1717 catch_info.bound_names); 1718 if (decl != nullptr) { 1719 const AstRawString* name = decl->proxy()->raw_name(); 1720 int position = decl->proxy()->position(); 1721 Scanner::Location location = 1722 position == kNoSourcePosition 1723 ? Scanner::Location::invalid() 1724 : Scanner::Location(position, position + 1); 1725 ReportMessageAt(location, MessageTemplate::kVarRedeclaration, name); 1726 *ok = false; 1727 } 1728 } 1729 } 1730 1731 Statement* Parser::RewriteTryStatement(Block* try_block, Block* catch_block, 1732 Block* finally_block, 1733 const CatchInfo& catch_info, int pos) { 1734 // Simplify the AST nodes by converting: 1735 // 'try B0 catch B1 finally B2' 1736 // to: 1737 // 'try { try B0 catch B1 } finally B2' 1738 1739 if (catch_block != nullptr && finally_block != nullptr) { 1740 // If we have both, create an inner try/catch. 1741 DCHECK_NOT_NULL(catch_info.scope); 1742 DCHECK_NOT_NULL(catch_info.variable); 1743 TryCatchStatement* statement; 1744 statement = factory()->NewTryCatchStatement(try_block, catch_info.scope, 1745 catch_info.variable, 1746 catch_block, kNoSourcePosition); 1747 1748 try_block = factory()->NewBlock(nullptr, 1, false, kNoSourcePosition); 1749 try_block->statements()->Add(statement, zone()); 1750 catch_block = nullptr; // Clear to indicate it's been handled. 1751 } 1752 1753 if (catch_block != nullptr) { 1754 // For a try-catch construct append return expressions from the catch block 1755 // to the list of return expressions. 1756 function_state_->tail_call_expressions().Append( 1757 catch_info.tail_call_expressions); 1758 1759 DCHECK_NULL(finally_block); 1760 DCHECK_NOT_NULL(catch_info.scope); 1761 DCHECK_NOT_NULL(catch_info.variable); 1762 return factory()->NewTryCatchStatement( 1763 try_block, catch_info.scope, catch_info.variable, catch_block, pos); 1764 } else { 1765 DCHECK_NOT_NULL(finally_block); 1766 return factory()->NewTryFinallyStatement(try_block, finally_block, pos); 1767 } 1768 } 1769 1770 void Parser::ParseAndRewriteGeneratorFunctionBody(int pos, FunctionKind kind, 1771 ZoneList<Statement*>* body, 1772 bool* ok) { 1773 // We produce: 1774 // 1775 // try { InitialYield; ...body...; return {value: undefined, done: true} } 1776 // finally { %_GeneratorClose(generator) } 1777 // 1778 // - InitialYield yields the actual generator object. 1779 // - Any return statement inside the body will have its argument wrapped 1780 // in a "done" iterator result object. 1781 // - If the generator terminates for whatever reason, we must close it. 1782 // Hence the finally clause. 1783 1784 Block* try_block = factory()->NewBlock(nullptr, 3, false, kNoSourcePosition); 1785 Expression* initial_yield = BuildInitialYield(pos, kind); 1786 try_block->statements()->Add( 1787 factory()->NewExpressionStatement(initial_yield, kNoSourcePosition), 1788 zone()); 1789 ParseStatementList(try_block->statements(), Token::RBRACE, ok); 1790 if (!*ok) return; 1791 1792 Statement* final_return = factory()->NewReturnStatement( 1793 BuildIteratorResult(nullptr, true), kNoSourcePosition); 1794 try_block->statements()->Add(final_return, zone()); 1795 1796 Block* finally_block = 1797 factory()->NewBlock(nullptr, 1, false, kNoSourcePosition); 1798 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(1, zone()); 1799 VariableProxy* call_proxy = 1800 factory()->NewVariableProxy(function_state_->generator_object_variable()); 1801 args->Add(call_proxy, zone()); 1802 Expression* call = factory()->NewCallRuntime(Runtime::kInlineGeneratorClose, 1803 args, kNoSourcePosition); 1804 finally_block->statements()->Add( 1805 factory()->NewExpressionStatement(call, kNoSourcePosition), zone()); 1806 1807 body->Add(factory()->NewTryFinallyStatement(try_block, finally_block, 1808 kNoSourcePosition), 1809 zone()); 1810 } 1811 1812 void Parser::CreateFunctionNameAssignment( 1813 const AstRawString* function_name, int pos, 1814 FunctionLiteral::FunctionType function_type, 1815 DeclarationScope* function_scope, ZoneList<Statement*>* result, int index) { 1816 if (function_type == FunctionLiteral::kNamedExpression) { 1817 StatementT statement = factory()->NewEmptyStatement(kNoSourcePosition); 1818 if (function_scope->LookupLocal(function_name) == nullptr) { 1819 // Now that we know the language mode, we can create the const assignment 1820 // in the previously reserved spot. 1821 DCHECK_EQ(function_scope, scope()); 1822 Variable* fvar = function_scope->DeclareFunctionVar(function_name); 1823 VariableProxy* fproxy = factory()->NewVariableProxy(fvar); 1824 statement = factory()->NewExpressionStatement( 1825 factory()->NewAssignment(Token::INIT, fproxy, 1826 factory()->NewThisFunction(pos), 1827 kNoSourcePosition), 1828 kNoSourcePosition); 1829 } 1830 result->Set(index, statement); 1831 } 1832 } 1833 1834 // [if (IteratorType == kNormal)] 1835 // !%_IsJSReceiver(result = iterator.next()) && 1836 // %ThrowIteratorResultNotAnObject(result) 1837 // [else if (IteratorType == kAsync)] 1838 // !%_IsJSReceiver(result = Await(iterator.next())) && 1839 // %ThrowIteratorResultNotAnObject(result) 1840 // [endif] 1841 Expression* Parser::BuildIteratorNextResult(Expression* iterator, 1842 Variable* result, IteratorType type, 1843 int pos) { 1844 Expression* next_literal = factory()->NewStringLiteral( 1845 ast_value_factory()->next_string(), kNoSourcePosition); 1846 Expression* next_property = 1847 factory()->NewProperty(iterator, next_literal, kNoSourcePosition); 1848 ZoneList<Expression*>* next_arguments = 1849 new (zone()) ZoneList<Expression*>(0, zone()); 1850 Expression* next_call = 1851 factory()->NewCall(next_property, next_arguments, pos); 1852 if (type == IteratorType::kAsync) { 1853 next_call = RewriteAwaitExpression(next_call, pos); 1854 } 1855 Expression* result_proxy = factory()->NewVariableProxy(result); 1856 Expression* left = 1857 factory()->NewAssignment(Token::ASSIGN, result_proxy, next_call, pos); 1858 1859 // %_IsJSReceiver(...) 1860 ZoneList<Expression*>* is_spec_object_args = 1861 new (zone()) ZoneList<Expression*>(1, zone()); 1862 is_spec_object_args->Add(left, zone()); 1863 Expression* is_spec_object_call = factory()->NewCallRuntime( 1864 Runtime::kInlineIsJSReceiver, is_spec_object_args, pos); 1865 1866 // %ThrowIteratorResultNotAnObject(result) 1867 Expression* result_proxy_again = factory()->NewVariableProxy(result); 1868 ZoneList<Expression*>* throw_arguments = 1869 new (zone()) ZoneList<Expression*>(1, zone()); 1870 throw_arguments->Add(result_proxy_again, zone()); 1871 Expression* throw_call = factory()->NewCallRuntime( 1872 Runtime::kThrowIteratorResultNotAnObject, throw_arguments, pos); 1873 1874 return factory()->NewBinaryOperation( 1875 Token::AND, 1876 factory()->NewUnaryOperation(Token::NOT, is_spec_object_call, pos), 1877 throw_call, pos); 1878 } 1879 1880 Statement* Parser::InitializeForEachStatement(ForEachStatement* stmt, 1881 Expression* each, 1882 Expression* subject, 1883 Statement* body, 1884 int each_keyword_pos) { 1885 ForOfStatement* for_of = stmt->AsForOfStatement(); 1886 if (for_of != NULL) { 1887 const bool finalize = true; 1888 return InitializeForOfStatement(for_of, each, subject, body, finalize, 1889 IteratorType::kNormal, each_keyword_pos); 1890 } else { 1891 if (each->IsArrayLiteral() || each->IsObjectLiteral()) { 1892 Variable* temp = NewTemporary(ast_value_factory()->empty_string()); 1893 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); 1894 Expression* assign_each = PatternRewriter::RewriteDestructuringAssignment( 1895 this, factory()->NewAssignment(Token::ASSIGN, each, temp_proxy, 1896 kNoSourcePosition), 1897 scope()); 1898 auto block = factory()->NewBlock(nullptr, 2, false, kNoSourcePosition); 1899 block->statements()->Add( 1900 factory()->NewExpressionStatement(assign_each, kNoSourcePosition), 1901 zone()); 1902 block->statements()->Add(body, zone()); 1903 body = block; 1904 each = factory()->NewVariableProxy(temp); 1905 } 1906 MarkExpressionAsAssigned(each); 1907 stmt->AsForInStatement()->Initialize(each, subject, body); 1908 } 1909 return stmt; 1910 } 1911 1912 // Special case for legacy for 1913 // 1914 // for (var x = initializer in enumerable) body 1915 // 1916 // An initialization block of the form 1917 // 1918 // { 1919 // x = initializer; 1920 // } 1921 // 1922 // is returned in this case. It has reserved space for two statements, 1923 // so that (later on during parsing), the equivalent of 1924 // 1925 // for (x in enumerable) body 1926 // 1927 // is added as a second statement to it. 1928 Block* Parser::RewriteForVarInLegacy(const ForInfo& for_info) { 1929 const DeclarationParsingResult::Declaration& decl = 1930 for_info.parsing_result.declarations[0]; 1931 if (!IsLexicalVariableMode(for_info.parsing_result.descriptor.mode) && 1932 decl.pattern->IsVariableProxy() && decl.initializer != nullptr) { 1933 ++use_counts_[v8::Isolate::kForInInitializer]; 1934 const AstRawString* name = decl.pattern->AsVariableProxy()->raw_name(); 1935 VariableProxy* single_var = NewUnresolved(name); 1936 Block* init_block = factory()->NewBlock( 1937 nullptr, 2, true, for_info.parsing_result.descriptor.declaration_pos); 1938 init_block->statements()->Add( 1939 factory()->NewExpressionStatement( 1940 factory()->NewAssignment(Token::ASSIGN, single_var, 1941 decl.initializer, kNoSourcePosition), 1942 kNoSourcePosition), 1943 zone()); 1944 return init_block; 1945 } 1946 return nullptr; 1947 } 1948 1949 // Rewrite a for-in/of statement of the form 1950 // 1951 // for (let/const/var x in/of e) b 1952 // 1953 // into 1954 // 1955 // { 1956 // <let x' be a temporary variable> 1957 // for (x' in/of e) { 1958 // let/const/var x; 1959 // x = x'; 1960 // b; 1961 // } 1962 // let x; // for TDZ 1963 // } 1964 void Parser::DesugarBindingInForEachStatement(ForInfo* for_info, 1965 Block** body_block, 1966 Expression** each_variable, 1967 bool* ok) { 1968 DCHECK(for_info->parsing_result.declarations.length() == 1); 1969 DeclarationParsingResult::Declaration& decl = 1970 for_info->parsing_result.declarations[0]; 1971 Variable* temp = NewTemporary(ast_value_factory()->dot_for_string()); 1972 auto each_initialization_block = 1973 factory()->NewBlock(nullptr, 1, true, kNoSourcePosition); 1974 { 1975 auto descriptor = for_info->parsing_result.descriptor; 1976 descriptor.declaration_pos = kNoSourcePosition; 1977 descriptor.initialization_pos = kNoSourcePosition; 1978 decl.initializer = factory()->NewVariableProxy(temp); 1979 1980 bool is_for_var_of = 1981 for_info->mode == ForEachStatement::ITERATE && 1982 for_info->parsing_result.descriptor.mode == VariableMode::VAR; 1983 bool collect_names = 1984 IsLexicalVariableMode(for_info->parsing_result.descriptor.mode) || 1985 is_for_var_of; 1986 1987 PatternRewriter::DeclareAndInitializeVariables( 1988 this, each_initialization_block, &descriptor, &decl, 1989 collect_names ? &for_info->bound_names : nullptr, CHECK_OK_VOID); 1990 1991 // Annex B.3.5 prohibits the form 1992 // `try {} catch(e) { for (var e of {}); }` 1993 // So if we are parsing a statement like `for (var ... of ...)` 1994 // we need to walk up the scope chain and look for catch scopes 1995 // which have a simple binding, then compare their binding against 1996 // all of the names declared in the init of the for-of we're 1997 // parsing. 1998 if (is_for_var_of) { 1999 Scope* catch_scope = scope(); 2000 while (catch_scope != nullptr && !catch_scope->is_declaration_scope()) { 2001 if (catch_scope->is_catch_scope()) { 2002 auto name = catch_scope->catch_variable_name(); 2003 // If it's a simple binding and the name is declared in the for loop. 2004 if (name != ast_value_factory()->dot_catch_string() && 2005 for_info->bound_names.Contains(name)) { 2006 ReportMessageAt(for_info->parsing_result.bindings_loc, 2007 MessageTemplate::kVarRedeclaration, name); 2008 *ok = false; 2009 return; 2010 } 2011 } 2012 catch_scope = catch_scope->outer_scope(); 2013 } 2014 } 2015 } 2016 2017 *body_block = factory()->NewBlock(nullptr, 3, false, kNoSourcePosition); 2018 (*body_block)->statements()->Add(each_initialization_block, zone()); 2019 *each_variable = factory()->NewVariableProxy(temp, for_info->position); 2020 } 2021 2022 // Create a TDZ for any lexically-bound names in for in/of statements. 2023 Block* Parser::CreateForEachStatementTDZ(Block* init_block, 2024 const ForInfo& for_info, bool* ok) { 2025 if (IsLexicalVariableMode(for_info.parsing_result.descriptor.mode)) { 2026 DCHECK_NULL(init_block); 2027 2028 init_block = factory()->NewBlock(nullptr, 1, false, kNoSourcePosition); 2029 2030 for (int i = 0; i < for_info.bound_names.length(); ++i) { 2031 // TODO(adamk): This needs to be some sort of special 2032 // INTERNAL variable that's invisible to the debugger 2033 // but visible to everything else. 2034 Declaration* tdz_decl = DeclareVariable(for_info.bound_names[i], LET, 2035 kNoSourcePosition, CHECK_OK); 2036 tdz_decl->proxy()->var()->set_initializer_position(position()); 2037 } 2038 } 2039 return init_block; 2040 } 2041 2042 Statement* Parser::InitializeForOfStatement( 2043 ForOfStatement* for_of, Expression* each, Expression* iterable, 2044 Statement* body, bool finalize, IteratorType type, int next_result_pos) { 2045 // Create the auxiliary expressions needed for iterating over the iterable, 2046 // and initialize the given ForOfStatement with them. 2047 // If finalize is true, also instrument the loop with code that performs the 2048 // proper ES6 iterator finalization. In that case, the result is not 2049 // immediately a ForOfStatement. 2050 const int nopos = kNoSourcePosition; 2051 auto avfactory = ast_value_factory(); 2052 2053 Variable* iterator = NewTemporary(avfactory->dot_iterator_string()); 2054 Variable* result = NewTemporary(avfactory->dot_result_string()); 2055 Variable* completion = NewTemporary(avfactory->empty_string()); 2056 2057 // iterator = GetIterator(iterable, type) 2058 Expression* assign_iterator; 2059 { 2060 assign_iterator = factory()->NewAssignment( 2061 Token::ASSIGN, factory()->NewVariableProxy(iterator), 2062 factory()->NewGetIterator(iterable, type, iterable->position()), 2063 iterable->position()); 2064 } 2065 2066 // [if (IteratorType == kNormal)] 2067 // !%_IsJSReceiver(result = iterator.next()) && 2068 // %ThrowIteratorResultNotAnObject(result) 2069 // [else if (IteratorType == kAsync)] 2070 // !%_IsJSReceiver(result = Await(iterator.next())) && 2071 // %ThrowIteratorResultNotAnObject(result) 2072 // [endif] 2073 Expression* next_result; 2074 { 2075 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); 2076 next_result = 2077 BuildIteratorNextResult(iterator_proxy, result, type, next_result_pos); 2078 } 2079 2080 // result.done 2081 Expression* result_done; 2082 { 2083 Expression* done_literal = factory()->NewStringLiteral( 2084 ast_value_factory()->done_string(), kNoSourcePosition); 2085 Expression* result_proxy = factory()->NewVariableProxy(result); 2086 result_done = 2087 factory()->NewProperty(result_proxy, done_literal, kNoSourcePosition); 2088 } 2089 2090 // result.value 2091 Expression* result_value; 2092 { 2093 Expression* value_literal = 2094 factory()->NewStringLiteral(avfactory->value_string(), nopos); 2095 Expression* result_proxy = factory()->NewVariableProxy(result); 2096 result_value = factory()->NewProperty(result_proxy, value_literal, nopos); 2097 } 2098 2099 // {{completion = kAbruptCompletion;}} 2100 Statement* set_completion_abrupt; 2101 if (finalize) { 2102 Expression* proxy = factory()->NewVariableProxy(completion); 2103 Expression* assignment = factory()->NewAssignment( 2104 Token::ASSIGN, proxy, 2105 factory()->NewSmiLiteral(Parser::kAbruptCompletion, nopos), nopos); 2106 2107 Block* block = factory()->NewBlock(nullptr, 1, true, nopos); 2108 block->statements()->Add( 2109 factory()->NewExpressionStatement(assignment, nopos), zone()); 2110 set_completion_abrupt = block; 2111 } 2112 2113 // do { let tmp = #result_value; #set_completion_abrupt; tmp } 2114 // Expression* result_value (gets overwritten) 2115 if (finalize) { 2116 Variable* var_tmp = NewTemporary(avfactory->empty_string()); 2117 Expression* tmp = factory()->NewVariableProxy(var_tmp); 2118 Expression* assignment = 2119 factory()->NewAssignment(Token::ASSIGN, tmp, result_value, nopos); 2120 2121 Block* block = factory()->NewBlock(nullptr, 2, false, nopos); 2122 block->statements()->Add( 2123 factory()->NewExpressionStatement(assignment, nopos), zone()); 2124 block->statements()->Add(set_completion_abrupt, zone()); 2125 2126 result_value = factory()->NewDoExpression(block, var_tmp, nopos); 2127 } 2128 2129 // each = #result_value; 2130 Expression* assign_each; 2131 { 2132 assign_each = 2133 factory()->NewAssignment(Token::ASSIGN, each, result_value, nopos); 2134 if (each->IsArrayLiteral() || each->IsObjectLiteral()) { 2135 assign_each = PatternRewriter::RewriteDestructuringAssignment( 2136 this, assign_each->AsAssignment(), scope()); 2137 } 2138 } 2139 2140 // {{completion = kNormalCompletion;}} 2141 Statement* set_completion_normal; 2142 if (finalize) { 2143 Expression* proxy = factory()->NewVariableProxy(completion); 2144 Expression* assignment = factory()->NewAssignment( 2145 Token::ASSIGN, proxy, 2146 factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos); 2147 2148 Block* block = factory()->NewBlock(nullptr, 1, true, nopos); 2149 block->statements()->Add( 2150 factory()->NewExpressionStatement(assignment, nopos), zone()); 2151 set_completion_normal = block; 2152 } 2153 2154 // { #loop-body; #set_completion_normal } 2155 // Statement* body (gets overwritten) 2156 if (finalize) { 2157 Block* block = factory()->NewBlock(nullptr, 2, false, nopos); 2158 block->statements()->Add(body, zone()); 2159 block->statements()->Add(set_completion_normal, zone()); 2160 body = block; 2161 } 2162 2163 for_of->Initialize(body, iterator, assign_iterator, next_result, result_done, 2164 assign_each); 2165 return finalize ? FinalizeForOfStatement(for_of, completion, type, nopos) 2166 : for_of; 2167 } 2168 2169 Statement* Parser::DesugarLexicalBindingsInForStatement( 2170 ForStatement* loop, Statement* init, Expression* cond, Statement* next, 2171 Statement* body, Scope* inner_scope, const ForInfo& for_info, bool* ok) { 2172 // ES6 13.7.4.8 specifies that on each loop iteration the let variables are 2173 // copied into a new environment. Moreover, the "next" statement must be 2174 // evaluated not in the environment of the just completed iteration but in 2175 // that of the upcoming one. We achieve this with the following desugaring. 2176 // Extra care is needed to preserve the completion value of the original loop. 2177 // 2178 // We are given a for statement of the form 2179 // 2180 // labels: for (let/const x = i; cond; next) body 2181 // 2182 // and rewrite it as follows. Here we write {{ ... }} for init-blocks, ie., 2183 // blocks whose ignore_completion_value_ flag is set. 2184 // 2185 // { 2186 // let/const x = i; 2187 // temp_x = x; 2188 // first = 1; 2189 // undefined; 2190 // outer: for (;;) { 2191 // let/const x = temp_x; 2192 // {{ if (first == 1) { 2193 // first = 0; 2194 // } else { 2195 // next; 2196 // } 2197 // flag = 1; 2198 // if (!cond) break; 2199 // }} 2200 // labels: for (; flag == 1; flag = 0, temp_x = x) { 2201 // body 2202 // } 2203 // {{ if (flag == 1) // Body used break. 2204 // break; 2205 // }} 2206 // } 2207 // } 2208 2209 DCHECK(for_info.bound_names.length() > 0); 2210 ZoneList<Variable*> temps(for_info.bound_names.length(), zone()); 2211 2212 Block* outer_block = factory()->NewBlock( 2213 nullptr, for_info.bound_names.length() + 4, false, kNoSourcePosition); 2214 2215 // Add statement: let/const x = i. 2216 outer_block->statements()->Add(init, zone()); 2217 2218 const AstRawString* temp_name = ast_value_factory()->dot_for_string(); 2219 2220 // For each lexical variable x: 2221 // make statement: temp_x = x. 2222 for (int i = 0; i < for_info.bound_names.length(); i++) { 2223 VariableProxy* proxy = NewUnresolved(for_info.bound_names[i]); 2224 Variable* temp = NewTemporary(temp_name); 2225 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); 2226 Assignment* assignment = factory()->NewAssignment(Token::ASSIGN, temp_proxy, 2227 proxy, kNoSourcePosition); 2228 Statement* assignment_statement = 2229 factory()->NewExpressionStatement(assignment, kNoSourcePosition); 2230 outer_block->statements()->Add(assignment_statement, zone()); 2231 temps.Add(temp, zone()); 2232 } 2233 2234 Variable* first = NULL; 2235 // Make statement: first = 1. 2236 if (next) { 2237 first = NewTemporary(temp_name); 2238 VariableProxy* first_proxy = factory()->NewVariableProxy(first); 2239 Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition); 2240 Assignment* assignment = factory()->NewAssignment( 2241 Token::ASSIGN, first_proxy, const1, kNoSourcePosition); 2242 Statement* assignment_statement = 2243 factory()->NewExpressionStatement(assignment, kNoSourcePosition); 2244 outer_block->statements()->Add(assignment_statement, zone()); 2245 } 2246 2247 // make statement: undefined; 2248 outer_block->statements()->Add( 2249 factory()->NewExpressionStatement( 2250 factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition), 2251 zone()); 2252 2253 // Make statement: outer: for (;;) 2254 // Note that we don't actually create the label, or set this loop up as an 2255 // explicit break target, instead handing it directly to those nodes that 2256 // need to know about it. This should be safe because we don't run any code 2257 // in this function that looks up break targets. 2258 ForStatement* outer_loop = 2259 factory()->NewForStatement(NULL, kNoSourcePosition); 2260 outer_block->statements()->Add(outer_loop, zone()); 2261 outer_block->set_scope(scope()); 2262 2263 Block* inner_block = factory()->NewBlock(NULL, 3, false, kNoSourcePosition); 2264 { 2265 BlockState block_state(&scope_, inner_scope); 2266 2267 Block* ignore_completion_block = factory()->NewBlock( 2268 nullptr, for_info.bound_names.length() + 3, true, kNoSourcePosition); 2269 ZoneList<Variable*> inner_vars(for_info.bound_names.length(), zone()); 2270 // For each let variable x: 2271 // make statement: let/const x = temp_x. 2272 for (int i = 0; i < for_info.bound_names.length(); i++) { 2273 Declaration* decl = DeclareVariable( 2274 for_info.bound_names[i], for_info.parsing_result.descriptor.mode, 2275 kNoSourcePosition, CHECK_OK); 2276 inner_vars.Add(decl->proxy()->var(), zone()); 2277 VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i)); 2278 Assignment* assignment = factory()->NewAssignment( 2279 Token::INIT, decl->proxy(), temp_proxy, kNoSourcePosition); 2280 Statement* assignment_statement = 2281 factory()->NewExpressionStatement(assignment, kNoSourcePosition); 2282 DCHECK(init->position() != kNoSourcePosition); 2283 decl->proxy()->var()->set_initializer_position(init->position()); 2284 ignore_completion_block->statements()->Add(assignment_statement, zone()); 2285 } 2286 2287 // Make statement: if (first == 1) { first = 0; } else { next; } 2288 if (next) { 2289 DCHECK(first); 2290 Expression* compare = NULL; 2291 // Make compare expression: first == 1. 2292 { 2293 Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition); 2294 VariableProxy* first_proxy = factory()->NewVariableProxy(first); 2295 compare = factory()->NewCompareOperation(Token::EQ, first_proxy, const1, 2296 kNoSourcePosition); 2297 } 2298 Statement* clear_first = NULL; 2299 // Make statement: first = 0. 2300 { 2301 VariableProxy* first_proxy = factory()->NewVariableProxy(first); 2302 Expression* const0 = factory()->NewSmiLiteral(0, kNoSourcePosition); 2303 Assignment* assignment = factory()->NewAssignment( 2304 Token::ASSIGN, first_proxy, const0, kNoSourcePosition); 2305 clear_first = 2306 factory()->NewExpressionStatement(assignment, kNoSourcePosition); 2307 } 2308 Statement* clear_first_or_next = factory()->NewIfStatement( 2309 compare, clear_first, next, kNoSourcePosition); 2310 ignore_completion_block->statements()->Add(clear_first_or_next, zone()); 2311 } 2312 2313 Variable* flag = NewTemporary(temp_name); 2314 // Make statement: flag = 1. 2315 { 2316 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag); 2317 Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition); 2318 Assignment* assignment = factory()->NewAssignment( 2319 Token::ASSIGN, flag_proxy, const1, kNoSourcePosition); 2320 Statement* assignment_statement = 2321 factory()->NewExpressionStatement(assignment, kNoSourcePosition); 2322 ignore_completion_block->statements()->Add(assignment_statement, zone()); 2323 } 2324 2325 // Make statement: if (!cond) break. 2326 if (cond) { 2327 Statement* stop = 2328 factory()->NewBreakStatement(outer_loop, kNoSourcePosition); 2329 Statement* noop = factory()->NewEmptyStatement(kNoSourcePosition); 2330 ignore_completion_block->statements()->Add( 2331 factory()->NewIfStatement(cond, noop, stop, cond->position()), 2332 zone()); 2333 } 2334 2335 inner_block->statements()->Add(ignore_completion_block, zone()); 2336 // Make cond expression for main loop: flag == 1. 2337 Expression* flag_cond = NULL; 2338 { 2339 Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition); 2340 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag); 2341 flag_cond = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1, 2342 kNoSourcePosition); 2343 } 2344 2345 // Create chain of expressions "flag = 0, temp_x = x, ..." 2346 Statement* compound_next_statement = NULL; 2347 { 2348 Expression* compound_next = NULL; 2349 // Make expression: flag = 0. 2350 { 2351 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag); 2352 Expression* const0 = factory()->NewSmiLiteral(0, kNoSourcePosition); 2353 compound_next = factory()->NewAssignment(Token::ASSIGN, flag_proxy, 2354 const0, kNoSourcePosition); 2355 } 2356 2357 // Make the comma-separated list of temp_x = x assignments. 2358 int inner_var_proxy_pos = scanner()->location().beg_pos; 2359 for (int i = 0; i < for_info.bound_names.length(); i++) { 2360 VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i)); 2361 VariableProxy* proxy = 2362 factory()->NewVariableProxy(inner_vars.at(i), inner_var_proxy_pos); 2363 Assignment* assignment = factory()->NewAssignment( 2364 Token::ASSIGN, temp_proxy, proxy, kNoSourcePosition); 2365 compound_next = factory()->NewBinaryOperation( 2366 Token::COMMA, compound_next, assignment, kNoSourcePosition); 2367 } 2368 2369 compound_next_statement = 2370 factory()->NewExpressionStatement(compound_next, kNoSourcePosition); 2371 } 2372 2373 // Make statement: labels: for (; flag == 1; flag = 0, temp_x = x) 2374 // Note that we re-use the original loop node, which retains its labels 2375 // and ensures that any break or continue statements in body point to 2376 // the right place. 2377 loop->Initialize(NULL, flag_cond, compound_next_statement, body); 2378 inner_block->statements()->Add(loop, zone()); 2379 2380 // Make statement: {{if (flag == 1) break;}} 2381 { 2382 Expression* compare = NULL; 2383 // Make compare expresion: flag == 1. 2384 { 2385 Expression* const1 = factory()->NewSmiLiteral(1, kNoSourcePosition); 2386 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag); 2387 compare = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1, 2388 kNoSourcePosition); 2389 } 2390 Statement* stop = 2391 factory()->NewBreakStatement(outer_loop, kNoSourcePosition); 2392 Statement* empty = factory()->NewEmptyStatement(kNoSourcePosition); 2393 Statement* if_flag_break = 2394 factory()->NewIfStatement(compare, stop, empty, kNoSourcePosition); 2395 Block* ignore_completion_block = 2396 factory()->NewBlock(NULL, 1, true, kNoSourcePosition); 2397 ignore_completion_block->statements()->Add(if_flag_break, zone()); 2398 inner_block->statements()->Add(ignore_completion_block, zone()); 2399 } 2400 2401 inner_block->set_scope(inner_scope); 2402 } 2403 2404 outer_loop->Initialize(NULL, NULL, NULL, inner_block); 2405 return outer_block; 2406 } 2407 2408 void Parser::AddArrowFunctionFormalParameters( 2409 ParserFormalParameters* parameters, Expression* expr, int end_pos, 2410 bool* ok) { 2411 // ArrowFunctionFormals :: 2412 // Binary(Token::COMMA, NonTailArrowFunctionFormals, Tail) 2413 // Tail 2414 // NonTailArrowFunctionFormals :: 2415 // Binary(Token::COMMA, NonTailArrowFunctionFormals, VariableProxy) 2416 // VariableProxy 2417 // Tail :: 2418 // VariableProxy 2419 // Spread(VariableProxy) 2420 // 2421 // As we need to visit the parameters in left-to-right order, we recurse on 2422 // the left-hand side of comma expressions. 2423 // 2424 if (expr->IsBinaryOperation()) { 2425 BinaryOperation* binop = expr->AsBinaryOperation(); 2426 // The classifier has already run, so we know that the expression is a valid 2427 // arrow function formals production. 2428 DCHECK_EQ(binop->op(), Token::COMMA); 2429 Expression* left = binop->left(); 2430 Expression* right = binop->right(); 2431 int comma_pos = binop->position(); 2432 AddArrowFunctionFormalParameters(parameters, left, comma_pos, 2433 CHECK_OK_VOID); 2434 // LHS of comma expression should be unparenthesized. 2435 expr = right; 2436 } 2437 2438 // Only the right-most expression may be a rest parameter. 2439 DCHECK(!parameters->has_rest); 2440 2441 bool is_rest = expr->IsSpread(); 2442 if (is_rest) { 2443 expr = expr->AsSpread()->expression(); 2444 parameters->has_rest = true; 2445 } 2446 if (parameters->is_simple) { 2447 parameters->is_simple = !is_rest && expr->IsVariableProxy(); 2448 } 2449 2450 Expression* initializer = nullptr; 2451 if (expr->IsAssignment()) { 2452 Assignment* assignment = expr->AsAssignment(); 2453 DCHECK(!assignment->is_compound()); 2454 initializer = assignment->value(); 2455 expr = assignment->target(); 2456 } 2457 2458 AddFormalParameter(parameters, expr, initializer, 2459 end_pos, is_rest); 2460 } 2461 2462 void Parser::DeclareArrowFunctionFormalParameters( 2463 ParserFormalParameters* parameters, Expression* expr, 2464 const Scanner::Location& params_loc, Scanner::Location* duplicate_loc, 2465 bool* ok) { 2466 if (expr->IsEmptyParentheses()) return; 2467 2468 AddArrowFunctionFormalParameters(parameters, expr, params_loc.end_pos, 2469 CHECK_OK_VOID); 2470 2471 if (parameters->arity > Code::kMaxArguments) { 2472 ReportMessageAt(params_loc, MessageTemplate::kMalformedArrowFunParamList); 2473 *ok = false; 2474 return; 2475 } 2476 2477 ExpressionClassifier classifier(this); 2478 if (!parameters->is_simple) { 2479 this->classifier()->RecordNonSimpleParameter(); 2480 } 2481 DeclareFormalParameters(parameters->scope, parameters->params); 2482 if (!this->classifier() 2483 ->is_valid_formal_parameter_list_without_duplicates()) { 2484 *duplicate_loc = 2485 this->classifier()->duplicate_formal_parameter_error().location; 2486 } 2487 DCHECK_EQ(parameters->is_simple, parameters->scope->has_simple_parameters()); 2488 } 2489 2490 void Parser::PrepareGeneratorVariables() { 2491 // For generators, allocating variables in contexts is currently a win because 2492 // it minimizes the work needed to suspend and resume an activation. The 2493 // code produced for generators relies on this forced context allocation (it 2494 // does not restore the frame's parameters upon resume). 2495 function_state_->scope()->ForceContextAllocation(); 2496 2497 // Calling a generator returns a generator object. That object is stored 2498 // in a temporary variable, a definition that is used by "yield" 2499 // expressions. 2500 function_state_->scope()->DeclareGeneratorObjectVar( 2501 ast_value_factory()->dot_generator_object_string()); 2502 } 2503 2504 FunctionLiteral* Parser::ParseFunctionLiteral( 2505 const AstRawString* function_name, Scanner::Location function_name_location, 2506 FunctionNameValidity function_name_validity, FunctionKind kind, 2507 int function_token_pos, FunctionLiteral::FunctionType function_type, 2508 LanguageMode language_mode, bool* ok) { 2509 // Function :: 2510 // '(' FormalParameterList? ')' '{' FunctionBody '}' 2511 // 2512 // Getter :: 2513 // '(' ')' '{' FunctionBody '}' 2514 // 2515 // Setter :: 2516 // '(' PropertySetParameterList ')' '{' FunctionBody '}' 2517 2518 int pos = function_token_pos == kNoSourcePosition ? peek_position() 2519 : function_token_pos; 2520 2521 // Anonymous functions were passed either the empty symbol or a null 2522 // handle as the function name. Remember if we were passed a non-empty 2523 // handle to decide whether to invoke function name inference. 2524 bool should_infer_name = function_name == NULL; 2525 2526 // We want a non-null handle as the function name. 2527 if (should_infer_name) { 2528 function_name = ast_value_factory()->empty_string(); 2529 } 2530 2531 FunctionLiteral::EagerCompileHint eager_compile_hint = 2532 function_state_->next_function_is_likely_called() 2533 ? FunctionLiteral::kShouldEagerCompile 2534 : default_eager_compile_hint(); 2535 2536 // Determine if the function can be parsed lazily. Lazy parsing is 2537 // different from lazy compilation; we need to parse more eagerly than we 2538 // compile. 2539 2540 // We can only parse lazily if we also compile lazily. The heuristics for lazy 2541 // compilation are: 2542 // - It must not have been prohibited by the caller to Parse (some callers 2543 // need a full AST). 2544 // - The outer scope must allow lazy compilation of inner functions. 2545 // - The function mustn't be a function expression with an open parenthesis 2546 // before; we consider that a hint that the function will be called 2547 // immediately, and it would be a waste of time to make it lazily 2548 // compiled. 2549 // These are all things we can know at this point, without looking at the 2550 // function itself. 2551 2552 // We separate between lazy parsing top level functions and lazy parsing inner 2553 // functions, because the latter needs to do more work. In particular, we need 2554 // to track unresolved variables to distinguish between these cases: 2555 // (function foo() { 2556 // bar = function() { return 1; } 2557 // })(); 2558 // and 2559 // (function foo() { 2560 // var a = 1; 2561 // bar = function() { return a; } 2562 // })(); 2563 2564 // Now foo will be parsed eagerly and compiled eagerly (optimization: assume 2565 // parenthesis before the function means that it will be called 2566 // immediately). bar can be parsed lazily, but we need to parse it in a mode 2567 // that tracks unresolved variables. 2568 DCHECK_IMPLIES(parse_lazily(), FLAG_lazy); 2569 DCHECK_IMPLIES(parse_lazily(), allow_lazy_); 2570 DCHECK_IMPLIES(parse_lazily(), extension_ == nullptr); 2571 2572 bool can_preparse = parse_lazily() && 2573 eager_compile_hint == FunctionLiteral::kShouldLazyCompile; 2574 2575 bool is_lazy_top_level_function = 2576 can_preparse && impl()->AllowsLazyParsingWithoutUnresolvedVariables(); 2577 2578 RuntimeCallTimerScope runtime_timer( 2579 runtime_call_stats_, 2580 parsing_on_main_thread_ 2581 ? &RuntimeCallStats::ParseFunctionLiteral 2582 : &RuntimeCallStats::ParseBackgroundFunctionLiteral); 2583 2584 // Determine whether we can still lazy parse the inner function. 2585 // The preconditions are: 2586 // - Lazy compilation has to be enabled. 2587 // - Neither V8 natives nor native function declarations can be allowed, 2588 // since parsing one would retroactively force the function to be 2589 // eagerly compiled. 2590 // - The invoker of this parser can't depend on the AST being eagerly 2591 // built (either because the function is about to be compiled, or 2592 // because the AST is going to be inspected for some reason). 2593 // - Because of the above, we can't be attempting to parse a 2594 // FunctionExpression; even without enclosing parentheses it might be 2595 // immediately invoked. 2596 // - The function literal shouldn't be hinted to eagerly compile. 2597 2598 // Inner functions will be parsed using a temporary Zone. After parsing, we 2599 // will migrate unresolved variable into a Scope in the main Zone. 2600 // TODO(marja): Refactor parsing modes: simplify this. 2601 bool use_temp_zone = 2602 (FLAG_aggressive_lazy_inner_functions 2603 ? can_preparse 2604 : (is_lazy_top_level_function || 2605 (parse_lazily() && 2606 function_type == FunctionLiteral::kDeclaration && 2607 eager_compile_hint == FunctionLiteral::kShouldLazyCompile))); 2608 2609 DCHECK_IMPLIES( 2610 (is_lazy_top_level_function || 2611 (parse_lazily() && function_type == FunctionLiteral::kDeclaration && 2612 eager_compile_hint == FunctionLiteral::kShouldLazyCompile)), 2613 can_preparse); 2614 bool is_lazy_inner_function = 2615 use_temp_zone && FLAG_lazy_inner_functions && !is_lazy_top_level_function; 2616 2617 ZoneList<Statement*>* body = nullptr; 2618 int expected_property_count = -1; 2619 bool should_be_used_once_hint = false; 2620 int num_parameters = -1; 2621 int function_length = -1; 2622 bool has_duplicate_parameters = false; 2623 int function_literal_id = GetNextFunctionLiteralId(); 2624 2625 Zone* outer_zone = zone(); 2626 DeclarationScope* scope; 2627 2628 { 2629 // Temporary zones can nest. When we migrate free variables (see below), we 2630 // need to recreate them in the previous Zone. 2631 AstNodeFactory previous_zone_ast_node_factory(ast_value_factory()); 2632 previous_zone_ast_node_factory.set_zone(zone()); 2633 2634 // Open a new zone scope, which sets our AstNodeFactory to allocate in the 2635 // new temporary zone if the preconditions are satisfied, and ensures that 2636 // the previous zone is always restored after parsing the body. To be able 2637 // to do scope analysis correctly after full parsing, we migrate needed 2638 // information when the function is parsed. 2639 Zone temp_zone(zone()->allocator(), ZONE_NAME); 2640 DiscardableZoneScope zone_scope(this, &temp_zone, use_temp_zone); 2641 2642 // This Scope lives in the main zone. We'll migrate data into that zone 2643 // later. 2644 scope = NewFunctionScope(kind, outer_zone); 2645 SetLanguageMode(scope, language_mode); 2646 #ifdef DEBUG 2647 scope->SetScopeName(function_name); 2648 if (use_temp_zone) scope->set_needs_migration(); 2649 #endif 2650 2651 Expect(Token::LPAREN, CHECK_OK); 2652 scope->set_start_position(scanner()->location().beg_pos); 2653 2654 // Eager or lazy parse? If is_lazy_top_level_function, we'll parse 2655 // lazily. We'll call SkipFunction, which may decide to 2656 // abort lazy parsing if it suspects that wasn't a good idea. If so (in 2657 // which case the parser is expected to have backtracked), or if we didn't 2658 // try to lazy parse in the first place, we'll have to parse eagerly. 2659 if (is_lazy_top_level_function || is_lazy_inner_function) { 2660 Scanner::BookmarkScope bookmark(scanner()); 2661 bookmark.Set(); 2662 LazyParsingResult result = SkipFunction( 2663 kind, scope, &num_parameters, &function_length, 2664 &has_duplicate_parameters, &expected_property_count, 2665 is_lazy_inner_function, is_lazy_top_level_function, CHECK_OK); 2666 2667 if (result == kLazyParsingAborted) { 2668 DCHECK(is_lazy_top_level_function); 2669 bookmark.Apply(); 2670 // Trigger eager (re-)parsing, just below this block. 2671 is_lazy_top_level_function = false; 2672 2673 // This is probably an initialization function. Inform the compiler it 2674 // should also eager-compile this function, and that we expect it to be 2675 // used once. 2676 eager_compile_hint = FunctionLiteral::kShouldEagerCompile; 2677 should_be_used_once_hint = true; 2678 scope->ResetAfterPreparsing(ast_value_factory(), true); 2679 zone_scope.Reset(); 2680 use_temp_zone = false; 2681 } 2682 } 2683 2684 if (!is_lazy_top_level_function && !is_lazy_inner_function) { 2685 body = ParseFunction(function_name, pos, kind, function_type, scope, 2686 &num_parameters, &function_length, 2687 &has_duplicate_parameters, &expected_property_count, 2688 CHECK_OK); 2689 } 2690 2691 DCHECK(use_temp_zone || !is_lazy_top_level_function); 2692 if (use_temp_zone) { 2693 // If the preconditions are correct the function body should never be 2694 // accessed, but do this anyway for better behaviour if they're wrong. 2695 body = nullptr; 2696 scope->AnalyzePartially(&previous_zone_ast_node_factory, 2697 preparsed_scope_data_); 2698 } 2699 2700 DCHECK_IMPLIES(use_temp_zone, temp_zoned_); 2701 if (FLAG_trace_preparse) { 2702 PrintF(" [%s]: %i-%i %.*s\n", 2703 is_lazy_top_level_function 2704 ? "Preparse no-resolution" 2705 : (temp_zoned_ ? "Preparse resolution" : "Full parse"), 2706 scope->start_position(), scope->end_position(), 2707 function_name->byte_length(), function_name->raw_data()); 2708 } 2709 if (V8_UNLIKELY(FLAG_runtime_stats)) { 2710 if (is_lazy_top_level_function) { 2711 RuntimeCallStats::CorrectCurrentCounterId( 2712 runtime_call_stats_, 2713 parsing_on_main_thread_ 2714 ? &RuntimeCallStats::PreParseNoVariableResolution 2715 : &RuntimeCallStats::PreParseBackgroundNoVariableResolution); 2716 } else if (temp_zoned_) { 2717 RuntimeCallStats::CorrectCurrentCounterId( 2718 runtime_call_stats_, 2719 parsing_on_main_thread_ 2720 ? &RuntimeCallStats::PreParseWithVariableResolution 2721 : &RuntimeCallStats::PreParseBackgroundWithVariableResolution); 2722 } 2723 } 2724 2725 // Validate function name. We can do this only after parsing the function, 2726 // since the function can declare itself strict. 2727 language_mode = scope->language_mode(); 2728 CheckFunctionName(language_mode, function_name, function_name_validity, 2729 function_name_location, CHECK_OK); 2730 2731 if (is_strict(language_mode)) { 2732 CheckStrictOctalLiteral(scope->start_position(), scope->end_position(), 2733 CHECK_OK); 2734 } 2735 CheckConflictingVarDeclarations(scope, CHECK_OK); 2736 } // DiscardableZoneScope goes out of scope. 2737 2738 FunctionLiteral::ParameterFlag duplicate_parameters = 2739 has_duplicate_parameters ? FunctionLiteral::kHasDuplicateParameters 2740 : FunctionLiteral::kNoDuplicateParameters; 2741 2742 // Note that the FunctionLiteral needs to be created in the main Zone again. 2743 FunctionLiteral* function_literal = factory()->NewFunctionLiteral( 2744 function_name, scope, body, expected_property_count, num_parameters, 2745 function_length, duplicate_parameters, function_type, eager_compile_hint, 2746 pos, true, function_literal_id); 2747 function_literal->set_function_token_position(function_token_pos); 2748 if (should_be_used_once_hint) 2749 function_literal->set_should_be_used_once_hint(); 2750 2751 if (should_infer_name) { 2752 DCHECK_NOT_NULL(fni_); 2753 fni_->AddFunction(function_literal); 2754 } 2755 return function_literal; 2756 } 2757 2758 Parser::LazyParsingResult Parser::SkipFunction( 2759 FunctionKind kind, DeclarationScope* function_scope, int* num_parameters, 2760 int* function_length, bool* has_duplicate_parameters, 2761 int* expected_property_count, bool is_inner_function, bool may_abort, 2762 bool* ok) { 2763 DCHECK_NE(kNoSourcePosition, function_scope->start_position()); 2764 DCHECK_EQ(kNoSourcePosition, parameters_end_pos_); 2765 if (produce_cached_parse_data()) CHECK(log_); 2766 2767 DCHECK_IMPLIES(IsArrowFunction(kind), 2768 scanner()->current_token() == Token::ARROW); 2769 2770 // Inner functions are not part of the cached data. 2771 if (!is_inner_function && consume_cached_parse_data() && 2772 !cached_parse_data_->rejected()) { 2773 // If we have cached data, we use it to skip parsing the function. The data 2774 // contains the information we need to construct the lazy function. 2775 FunctionEntry entry = 2776 cached_parse_data_->GetFunctionEntry(function_scope->start_position()); 2777 // Check that cached data is valid. If not, mark it as invalid (the embedder 2778 // handles it). Note that end position greater than end of stream is safe, 2779 // and hard to check. 2780 if (entry.is_valid() && 2781 entry.end_pos() > function_scope->start_position()) { 2782 total_preparse_skipped_ += entry.end_pos() - position(); 2783 function_scope->set_end_position(entry.end_pos()); 2784 scanner()->SeekForward(entry.end_pos() - 1); 2785 Expect(Token::RBRACE, CHECK_OK_VALUE(kLazyParsingComplete)); 2786 *num_parameters = entry.num_parameters(); 2787 *function_length = entry.function_length(); 2788 *has_duplicate_parameters = entry.has_duplicate_parameters(); 2789 *expected_property_count = entry.property_count(); 2790 SetLanguageMode(function_scope, entry.language_mode()); 2791 if (entry.uses_super_property()) 2792 function_scope->RecordSuperPropertyUsage(); 2793 if (entry.calls_eval()) function_scope->RecordEvalCall(); 2794 SkipFunctionLiterals(entry.num_inner_functions()); 2795 return kLazyParsingComplete; 2796 } 2797 cached_parse_data_->Reject(); 2798 } 2799 2800 // With no cached data, we partially parse the function, without building an 2801 // AST. This gathers the data needed to build a lazy function. 2802 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.PreParse"); 2803 2804 if (reusable_preparser_ == NULL) { 2805 reusable_preparser_ = new PreParser( 2806 zone(), &scanner_, stack_limit_, ast_value_factory(), 2807 &pending_error_handler_, runtime_call_stats_, parsing_on_main_thread_); 2808 #define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name()); 2809 SET_ALLOW(natives); 2810 SET_ALLOW(harmony_do_expressions); 2811 SET_ALLOW(harmony_function_sent); 2812 SET_ALLOW(harmony_trailing_commas); 2813 SET_ALLOW(harmony_class_fields); 2814 SET_ALLOW(harmony_object_rest_spread); 2815 SET_ALLOW(harmony_dynamic_import); 2816 SET_ALLOW(harmony_async_iteration); 2817 #undef SET_ALLOW 2818 } 2819 // Aborting inner function preparsing would leave scopes in an inconsistent 2820 // state; we don't parse inner functions in the abortable mode anyway. 2821 DCHECK(!is_inner_function || !may_abort); 2822 2823 PreParser::PreParseResult result = reusable_preparser_->PreParseFunction( 2824 kind, function_scope, parsing_module_, is_inner_function, may_abort, 2825 use_counts_); 2826 2827 // Return immediately if pre-parser decided to abort parsing. 2828 if (result == PreParser::kPreParseAbort) return kLazyParsingAborted; 2829 if (result == PreParser::kPreParseStackOverflow) { 2830 // Propagate stack overflow. 2831 set_stack_overflow(); 2832 *ok = false; 2833 return kLazyParsingComplete; 2834 } 2835 if (pending_error_handler_.has_pending_error()) { 2836 *ok = false; 2837 return kLazyParsingComplete; 2838 } 2839 PreParserLogger* logger = reusable_preparser_->logger(); 2840 function_scope->set_end_position(logger->end()); 2841 Expect(Token::RBRACE, CHECK_OK_VALUE(kLazyParsingComplete)); 2842 total_preparse_skipped_ += 2843 function_scope->end_position() - function_scope->start_position(); 2844 *num_parameters = logger->num_parameters(); 2845 *function_length = logger->function_length(); 2846 *has_duplicate_parameters = logger->has_duplicate_parameters(); 2847 *expected_property_count = logger->properties(); 2848 SkipFunctionLiterals(logger->num_inner_functions()); 2849 if (!is_inner_function && produce_cached_parse_data()) { 2850 DCHECK(log_); 2851 log_->LogFunction( 2852 function_scope->start_position(), function_scope->end_position(), 2853 *num_parameters, *function_length, *has_duplicate_parameters, 2854 *expected_property_count, language_mode(), 2855 function_scope->uses_super_property(), function_scope->calls_eval(), 2856 logger->num_inner_functions()); 2857 } 2858 return kLazyParsingComplete; 2859 } 2860 2861 2862 Statement* Parser::BuildAssertIsCoercible(Variable* var) { 2863 // if (var === null || var === undefined) 2864 // throw /* type error kNonCoercible) */; 2865 2866 Expression* condition = factory()->NewBinaryOperation( 2867 Token::OR, 2868 factory()->NewCompareOperation( 2869 Token::EQ_STRICT, factory()->NewVariableProxy(var), 2870 factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition), 2871 factory()->NewCompareOperation( 2872 Token::EQ_STRICT, factory()->NewVariableProxy(var), 2873 factory()->NewNullLiteral(kNoSourcePosition), kNoSourcePosition), 2874 kNoSourcePosition); 2875 Expression* throw_type_error = 2876 NewThrowTypeError(MessageTemplate::kNonCoercible, 2877 ast_value_factory()->empty_string(), kNoSourcePosition); 2878 IfStatement* if_statement = factory()->NewIfStatement( 2879 condition, 2880 factory()->NewExpressionStatement(throw_type_error, kNoSourcePosition), 2881 factory()->NewEmptyStatement(kNoSourcePosition), kNoSourcePosition); 2882 return if_statement; 2883 } 2884 2885 2886 class InitializerRewriter final 2887 : public AstTraversalVisitor<InitializerRewriter> { 2888 public: 2889 InitializerRewriter(uintptr_t stack_limit, Expression* root, Parser* parser, 2890 Scope* scope) 2891 : AstTraversalVisitor(stack_limit, root), 2892 parser_(parser), 2893 scope_(scope) {} 2894 2895 private: 2896 // This is required so that the overriden Visit* methods can be 2897 // called by the base class (template). 2898 friend class AstTraversalVisitor<InitializerRewriter>; 2899 2900 // Just rewrite destructuring assignments wrapped in RewritableExpressions. 2901 void VisitRewritableExpression(RewritableExpression* to_rewrite) { 2902 if (to_rewrite->is_rewritten()) return; 2903 Parser::PatternRewriter::RewriteDestructuringAssignment(parser_, to_rewrite, 2904 scope_); 2905 AstTraversalVisitor::VisitRewritableExpression(to_rewrite); 2906 } 2907 2908 // Code in function literals does not need to be eagerly rewritten, it will be 2909 // rewritten when scheduled. 2910 void VisitFunctionLiteral(FunctionLiteral* expr) {} 2911 2912 Parser* parser_; 2913 Scope* scope_; 2914 }; 2915 2916 2917 void Parser::RewriteParameterInitializer(Expression* expr, Scope* scope) { 2918 InitializerRewriter rewriter(stack_limit_, expr, this, scope); 2919 rewriter.Run(); 2920 } 2921 2922 2923 Block* Parser::BuildParameterInitializationBlock( 2924 const ParserFormalParameters& parameters, bool* ok) { 2925 DCHECK(!parameters.is_simple); 2926 DCHECK(scope()->is_function_scope()); 2927 Block* init_block = factory()->NewBlock(NULL, 1, true, kNoSourcePosition); 2928 int index = 0; 2929 for (auto parameter : parameters.params) { 2930 if (parameter->is_nondestructuring_rest()) break; 2931 DeclarationDescriptor descriptor; 2932 descriptor.declaration_kind = DeclarationDescriptor::PARAMETER; 2933 descriptor.scope = scope(); 2934 descriptor.mode = LET; 2935 descriptor.declaration_pos = parameter->pattern->position(); 2936 // The position that will be used by the AssignmentExpression 2937 // which copies from the temp parameter to the pattern. 2938 // 2939 // TODO(adamk): Should this be kNoSourcePosition, since 2940 // it's just copying from a temp var to the real param var? 2941 descriptor.initialization_pos = parameter->pattern->position(); 2942 Expression* initial_value = 2943 factory()->NewVariableProxy(parameters.scope->parameter(index)); 2944 if (parameter->initializer != nullptr) { 2945 // IS_UNDEFINED($param) ? initializer : $param 2946 2947 // Ensure initializer is rewritten 2948 RewriteParameterInitializer(parameter->initializer, scope()); 2949 2950 auto condition = factory()->NewCompareOperation( 2951 Token::EQ_STRICT, 2952 factory()->NewVariableProxy(parameters.scope->parameter(index)), 2953 factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition); 2954 initial_value = factory()->NewConditional( 2955 condition, parameter->initializer, initial_value, kNoSourcePosition); 2956 descriptor.initialization_pos = parameter->initializer->position(); 2957 } 2958 2959 Scope* param_scope = scope(); 2960 Block* param_block = init_block; 2961 if (!parameter->is_simple() && scope()->calls_sloppy_eval()) { 2962 param_scope = NewVarblockScope(); 2963 param_scope->set_start_position(descriptor.initialization_pos); 2964 param_scope->set_end_position(parameter->initializer_end_position); 2965 param_scope->RecordEvalCall(); 2966 param_block = factory()->NewBlock(NULL, 8, true, kNoSourcePosition); 2967 param_block->set_scope(param_scope); 2968 // Pass the appropriate scope in so that PatternRewriter can appropriately 2969 // rewrite inner initializers of the pattern to param_scope 2970 descriptor.scope = param_scope; 2971 // Rewrite the outer initializer to point to param_scope 2972 ReparentParameterExpressionScope(stack_limit(), initial_value, 2973 param_scope); 2974 } 2975 2976 BlockState block_state(&scope_, param_scope); 2977 DeclarationParsingResult::Declaration decl( 2978 parameter->pattern, parameter->initializer_end_position, initial_value); 2979 PatternRewriter::DeclareAndInitializeVariables( 2980 this, param_block, &descriptor, &decl, nullptr, CHECK_OK); 2981 2982 if (param_block != init_block) { 2983 param_scope = param_scope->FinalizeBlockScope(); 2984 if (param_scope != nullptr) { 2985 CheckConflictingVarDeclarations(param_scope, CHECK_OK); 2986 } 2987 init_block->statements()->Add(param_block, zone()); 2988 } 2989 ++index; 2990 } 2991 return init_block; 2992 } 2993 2994 Block* Parser::BuildRejectPromiseOnException(Block* inner_block) { 2995 // .promise = %AsyncFunctionPromiseCreate(); 2996 // try { 2997 // <inner_block> 2998 // } catch (.catch) { 2999 // %RejectPromise(.promise, .catch); 3000 // return .promise; 3001 // } finally { 3002 // %AsyncFunctionPromiseRelease(.promise); 3003 // } 3004 Block* result = factory()->NewBlock(nullptr, 2, true, kNoSourcePosition); 3005 3006 // .promise = %AsyncFunctionPromiseCreate(); 3007 Statement* set_promise; 3008 { 3009 Expression* create_promise = factory()->NewCallRuntime( 3010 Context::ASYNC_FUNCTION_PROMISE_CREATE_INDEX, 3011 new (zone()) ZoneList<Expression*>(0, zone()), kNoSourcePosition); 3012 Assignment* assign_promise = factory()->NewAssignment( 3013 Token::ASSIGN, factory()->NewVariableProxy(PromiseVariable()), 3014 create_promise, kNoSourcePosition); 3015 set_promise = 3016 factory()->NewExpressionStatement(assign_promise, kNoSourcePosition); 3017 } 3018 result->statements()->Add(set_promise, zone()); 3019 3020 // catch (.catch) { return %RejectPromise(.promise, .catch), .promise } 3021 Scope* catch_scope = NewScope(CATCH_SCOPE); 3022 catch_scope->set_is_hidden(); 3023 Variable* catch_variable = 3024 catch_scope->DeclareLocal(ast_value_factory()->dot_catch_string(), VAR); 3025 Block* catch_block = factory()->NewBlock(nullptr, 1, true, kNoSourcePosition); 3026 3027 Expression* promise_reject = BuildRejectPromise( 3028 factory()->NewVariableProxy(catch_variable), kNoSourcePosition); 3029 ReturnStatement* return_promise_reject = 3030 factory()->NewReturnStatement(promise_reject, kNoSourcePosition); 3031 catch_block->statements()->Add(return_promise_reject, zone()); 3032 3033 TryStatement* try_catch_statement = 3034 factory()->NewTryCatchStatementForAsyncAwait(inner_block, catch_scope, 3035 catch_variable, catch_block, 3036 kNoSourcePosition); 3037 3038 // There is no TryCatchFinally node, so wrap it in an outer try/finally 3039 Block* outer_try_block = 3040 factory()->NewBlock(nullptr, 1, true, kNoSourcePosition); 3041 outer_try_block->statements()->Add(try_catch_statement, zone()); 3042 3043 // finally { %AsyncFunctionPromiseRelease(.promise) } 3044 Block* finally_block = 3045 factory()->NewBlock(nullptr, 1, true, kNoSourcePosition); 3046 { 3047 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(1, zone()); 3048 args->Add(factory()->NewVariableProxy(PromiseVariable()), zone()); 3049 Expression* call_promise_release = factory()->NewCallRuntime( 3050 Context::ASYNC_FUNCTION_PROMISE_RELEASE_INDEX, args, kNoSourcePosition); 3051 Statement* promise_release = factory()->NewExpressionStatement( 3052 call_promise_release, kNoSourcePosition); 3053 finally_block->statements()->Add(promise_release, zone()); 3054 } 3055 3056 Statement* try_finally_statement = factory()->NewTryFinallyStatement( 3057 outer_try_block, finally_block, kNoSourcePosition); 3058 3059 result->statements()->Add(try_finally_statement, zone()); 3060 return result; 3061 } 3062 3063 Assignment* Parser::BuildCreateJSGeneratorObject(int pos, FunctionKind kind) { 3064 // .generator = %CreateJSGeneratorObject(...); 3065 DCHECK_NOT_NULL(function_state_->generator_object_variable()); 3066 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone()); 3067 args->Add(factory()->NewThisFunction(pos), zone()); 3068 args->Add(IsArrowFunction(kind) ? GetLiteralUndefined(pos) 3069 : ThisExpression(kNoSourcePosition), 3070 zone()); 3071 Expression* allocation = 3072 factory()->NewCallRuntime(Runtime::kCreateJSGeneratorObject, args, pos); 3073 VariableProxy* proxy = 3074 factory()->NewVariableProxy(function_state_->generator_object_variable()); 3075 return factory()->NewAssignment(Token::INIT, proxy, allocation, 3076 kNoSourcePosition); 3077 } 3078 3079 Expression* Parser::BuildResolvePromise(Expression* value, int pos) { 3080 // %ResolvePromise(.promise, value), .promise 3081 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone()); 3082 args->Add(factory()->NewVariableProxy(PromiseVariable()), zone()); 3083 args->Add(value, zone()); 3084 Expression* call_runtime = 3085 factory()->NewCallRuntime(Context::PROMISE_RESOLVE_INDEX, args, pos); 3086 return factory()->NewBinaryOperation( 3087 Token::COMMA, call_runtime, 3088 factory()->NewVariableProxy(PromiseVariable()), pos); 3089 } 3090 3091 Expression* Parser::BuildRejectPromise(Expression* value, int pos) { 3092 // %promise_internal_reject(.promise, value, false), .promise 3093 // Disables the additional debug event for the rejection since a debug event 3094 // already happened for the exception that got us here. 3095 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(3, zone()); 3096 args->Add(factory()->NewVariableProxy(PromiseVariable()), zone()); 3097 args->Add(value, zone()); 3098 args->Add(factory()->NewBooleanLiteral(false, pos), zone()); 3099 Expression* call_runtime = factory()->NewCallRuntime( 3100 Context::PROMISE_INTERNAL_REJECT_INDEX, args, pos); 3101 return factory()->NewBinaryOperation( 3102 Token::COMMA, call_runtime, 3103 factory()->NewVariableProxy(PromiseVariable()), pos); 3104 } 3105 3106 Variable* Parser::PromiseVariable() { 3107 // Based on the various compilation paths, there are many different code 3108 // paths which may be the first to access the Promise temporary. Whichever 3109 // comes first should create it and stash it in the FunctionState. 3110 Variable* promise = function_state_->promise_variable(); 3111 if (function_state_->promise_variable() == nullptr) { 3112 promise = function_state_->scope()->DeclarePromiseVar( 3113 ast_value_factory()->empty_string()); 3114 } 3115 return promise; 3116 } 3117 3118 Expression* Parser::BuildInitialYield(int pos, FunctionKind kind) { 3119 Assignment* assignment = BuildCreateJSGeneratorObject(pos, kind); 3120 VariableProxy* generator = 3121 factory()->NewVariableProxy(function_state_->generator_object_variable()); 3122 // The position of the yield is important for reporting the exception 3123 // caused by calling the .throw method on a generator suspended at the 3124 // initial yield (i.e. right after generator instantiation). 3125 return factory()->NewYield(generator, assignment, scope()->start_position(), 3126 Yield::kOnExceptionThrow); 3127 } 3128 3129 ZoneList<Statement*>* Parser::ParseFunction( 3130 const AstRawString* function_name, int pos, FunctionKind kind, 3131 FunctionLiteral::FunctionType function_type, 3132 DeclarationScope* function_scope, int* num_parameters, int* function_length, 3133 bool* has_duplicate_parameters, int* expected_property_count, bool* ok) { 3134 ParsingModeScope mode(this, allow_lazy_ ? PARSE_LAZILY : PARSE_EAGERLY); 3135 3136 FunctionState function_state(&function_state_, &scope_, function_scope); 3137 3138 DuplicateFinder duplicate_finder; 3139 ExpressionClassifier formals_classifier(this, &duplicate_finder); 3140 3141 if (IsResumableFunction(kind)) PrepareGeneratorVariables(); 3142 3143 int expected_parameters_end_pos = parameters_end_pos_; 3144 if (expected_parameters_end_pos != kNoSourcePosition) { 3145 // This is the first function encountered in a CreateDynamicFunction eval. 3146 parameters_end_pos_ = kNoSourcePosition; 3147 // The function name should have been ignored, giving us the empty string 3148 // here. 3149 DCHECK_EQ(function_name, ast_value_factory()->empty_string()); 3150 } 3151 3152 ParserFormalParameters formals(function_scope); 3153 ParseFormalParameterList(&formals, CHECK_OK); 3154 if (expected_parameters_end_pos != kNoSourcePosition) { 3155 // Check for '(' or ')' shenanigans in the parameter string for dynamic 3156 // functions. 3157 int position = peek_position(); 3158 if (position < expected_parameters_end_pos) { 3159 ReportMessageAt(Scanner::Location(position, position + 1), 3160 MessageTemplate::kArgStringTerminatesParametersEarly); 3161 *ok = false; 3162 return nullptr; 3163 } else if (position > expected_parameters_end_pos) { 3164 ReportMessageAt(Scanner::Location(expected_parameters_end_pos - 2, 3165 expected_parameters_end_pos), 3166 MessageTemplate::kUnexpectedEndOfArgString); 3167 *ok = false; 3168 return nullptr; 3169 } 3170 } 3171 Expect(Token::RPAREN, CHECK_OK); 3172 int formals_end_position = scanner()->location().end_pos; 3173 *num_parameters = formals.num_parameters(); 3174 *function_length = formals.function_length; 3175 3176 CheckArityRestrictions(formals.arity, kind, formals.has_rest, 3177 function_scope->start_position(), formals_end_position, 3178 CHECK_OK); 3179 Expect(Token::LBRACE, CHECK_OK); 3180 3181 ZoneList<Statement*>* body = new (zone()) ZoneList<Statement*>(8, zone()); 3182 ParseFunctionBody(body, function_name, pos, formals, kind, function_type, ok); 3183 3184 // Validate parameter names. We can do this only after parsing the function, 3185 // since the function can declare itself strict. 3186 const bool allow_duplicate_parameters = 3187 is_sloppy(function_scope->language_mode()) && formals.is_simple && 3188 !IsConciseMethod(kind); 3189 ValidateFormalParameters(function_scope->language_mode(), 3190 allow_duplicate_parameters, CHECK_OK); 3191 3192 RewriteDestructuringAssignments(); 3193 3194 *has_duplicate_parameters = 3195 !classifier()->is_valid_formal_parameter_list_without_duplicates(); 3196 3197 *expected_property_count = function_state.expected_property_count(); 3198 return body; 3199 } 3200 3201 void Parser::DeclareClassVariable(const AstRawString* name, 3202 ClassInfo* class_info, int class_token_pos, 3203 bool* ok) { 3204 #ifdef DEBUG 3205 scope()->SetScopeName(name); 3206 #endif 3207 3208 if (name != nullptr) { 3209 class_info->proxy = factory()->NewVariableProxy(name, NORMAL_VARIABLE); 3210 Declaration* declaration = factory()->NewVariableDeclaration( 3211 class_info->proxy, scope(), class_token_pos); 3212 Declare(declaration, DeclarationDescriptor::NORMAL, CONST, 3213 Variable::DefaultInitializationFlag(CONST), ok); 3214 } 3215 } 3216 3217 // This method declares a property of the given class. It updates the 3218 // following fields of class_info, as appropriate: 3219 // - constructor 3220 // - properties 3221 void Parser::DeclareClassProperty(const AstRawString* class_name, 3222 ClassLiteralProperty* property, 3223 ClassLiteralProperty::Kind kind, 3224 bool is_static, bool is_constructor, 3225 ClassInfo* class_info, bool* ok) { 3226 if (is_constructor) { 3227 DCHECK(!class_info->constructor); 3228 class_info->constructor = GetPropertyValue(property)->AsFunctionLiteral(); 3229 DCHECK_NOT_NULL(class_info->constructor); 3230 class_info->constructor->set_raw_name( 3231 class_name != nullptr ? class_name 3232 : ast_value_factory()->empty_string()); 3233 return; 3234 } 3235 3236 if (property->kind() == ClassLiteralProperty::FIELD) { 3237 DCHECK(allow_harmony_class_fields()); 3238 // TODO(littledan): Implement class fields 3239 } 3240 class_info->properties->Add(property, zone()); 3241 } 3242 3243 // This method rewrites a class literal into a do-expression. 3244 // It uses the following fields of class_info: 3245 // - constructor (if missing, it updates it with a default constructor) 3246 // - proxy 3247 // - extends 3248 // - properties 3249 // - has_name_static_property 3250 // - has_static_computed_names 3251 Expression* Parser::RewriteClassLiteral(const AstRawString* name, 3252 ClassInfo* class_info, int pos, 3253 bool* ok) { 3254 int end_pos = scanner()->location().end_pos; 3255 Block* do_block = factory()->NewBlock(nullptr, 1, false, pos); 3256 Variable* result_var = NewTemporary(ast_value_factory()->empty_string()); 3257 DoExpression* do_expr = factory()->NewDoExpression(do_block, result_var, pos); 3258 3259 bool has_extends = class_info->extends != nullptr; 3260 bool has_default_constructor = class_info->constructor == nullptr; 3261 if (has_default_constructor) { 3262 class_info->constructor = 3263 DefaultConstructor(name, has_extends, pos, end_pos); 3264 } 3265 3266 scope()->set_end_position(end_pos); 3267 3268 if (name != nullptr) { 3269 DCHECK_NOT_NULL(class_info->proxy); 3270 class_info->proxy->var()->set_initializer_position(end_pos); 3271 } 3272 3273 ClassLiteral* class_literal = factory()->NewClassLiteral( 3274 class_info->proxy, class_info->extends, class_info->constructor, 3275 class_info->properties, pos, end_pos, 3276 class_info->has_name_static_property, 3277 class_info->has_static_computed_names); 3278 3279 do_block->statements()->Add( 3280 factory()->NewExpressionStatement( 3281 factory()->NewAssignment(Token::ASSIGN, 3282 factory()->NewVariableProxy(result_var), 3283 class_literal, kNoSourcePosition), 3284 pos), 3285 zone()); 3286 do_block->set_scope(scope()->FinalizeBlockScope()); 3287 do_expr->set_represented_function(class_info->constructor); 3288 AddFunctionForNameInference(class_info->constructor); 3289 3290 return do_expr; 3291 } 3292 3293 Literal* Parser::GetLiteralUndefined(int position) { 3294 return factory()->NewUndefinedLiteral(position); 3295 } 3296 3297 3298 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) { 3299 Declaration* decl = scope->CheckConflictingVarDeclarations(); 3300 if (decl != NULL) { 3301 // In ES6, conflicting variable bindings are early errors. 3302 const AstRawString* name = decl->proxy()->raw_name(); 3303 int position = decl->proxy()->position(); 3304 Scanner::Location location = 3305 position == kNoSourcePosition 3306 ? Scanner::Location::invalid() 3307 : Scanner::Location(position, position + 1); 3308 ReportMessageAt(location, MessageTemplate::kVarRedeclaration, name); 3309 *ok = false; 3310 } 3311 } 3312 3313 3314 void Parser::InsertShadowingVarBindingInitializers(Block* inner_block) { 3315 // For each var-binding that shadows a parameter, insert an assignment 3316 // initializing the variable with the parameter. 3317 Scope* inner_scope = inner_block->scope(); 3318 DCHECK(inner_scope->is_declaration_scope()); 3319 Scope* function_scope = inner_scope->outer_scope(); 3320 DCHECK(function_scope->is_function_scope()); 3321 BlockState block_state(&scope_, inner_scope); 3322 for (Declaration* decl : *inner_scope->declarations()) { 3323 if (decl->proxy()->var()->mode() != VAR || !decl->IsVariableDeclaration()) { 3324 continue; 3325 } 3326 const AstRawString* name = decl->proxy()->raw_name(); 3327 Variable* parameter = function_scope->LookupLocal(name); 3328 if (parameter == nullptr) continue; 3329 VariableProxy* to = NewUnresolved(name); 3330 VariableProxy* from = factory()->NewVariableProxy(parameter); 3331 Expression* assignment = 3332 factory()->NewAssignment(Token::ASSIGN, to, from, kNoSourcePosition); 3333 Statement* statement = 3334 factory()->NewExpressionStatement(assignment, kNoSourcePosition); 3335 inner_block->statements()->InsertAt(0, statement, zone()); 3336 } 3337 } 3338 3339 void Parser::InsertSloppyBlockFunctionVarBindings(DeclarationScope* scope) { 3340 // For the outermost eval scope, we cannot hoist during parsing: let 3341 // declarations in the surrounding scope may prevent hoisting, but the 3342 // information is unaccessible during parsing. In this case, we hoist later in 3343 // DeclarationScope::Analyze. 3344 if (scope->is_eval_scope() && scope->outer_scope() == original_scope_) { 3345 return; 3346 } 3347 scope->HoistSloppyBlockFunctions(factory()); 3348 } 3349 3350 // ---------------------------------------------------------------------------- 3351 // Parser support 3352 3353 bool Parser::TargetStackContainsLabel(const AstRawString* label) { 3354 for (ParserTarget* t = target_stack_; t != NULL; t = t->previous()) { 3355 if (ContainsLabel(t->statement()->labels(), label)) return true; 3356 } 3357 return false; 3358 } 3359 3360 3361 BreakableStatement* Parser::LookupBreakTarget(const AstRawString* label, 3362 bool* ok) { 3363 bool anonymous = label == NULL; 3364 for (ParserTarget* t = target_stack_; t != NULL; t = t->previous()) { 3365 BreakableStatement* stat = t->statement(); 3366 if ((anonymous && stat->is_target_for_anonymous()) || 3367 (!anonymous && ContainsLabel(stat->labels(), label))) { 3368 return stat; 3369 } 3370 } 3371 return NULL; 3372 } 3373 3374 3375 IterationStatement* Parser::LookupContinueTarget(const AstRawString* label, 3376 bool* ok) { 3377 bool anonymous = label == NULL; 3378 for (ParserTarget* t = target_stack_; t != NULL; t = t->previous()) { 3379 IterationStatement* stat = t->statement()->AsIterationStatement(); 3380 if (stat == NULL) continue; 3381 3382 DCHECK(stat->is_target_for_anonymous()); 3383 if (anonymous || ContainsLabel(stat->labels(), label)) { 3384 return stat; 3385 } 3386 } 3387 return NULL; 3388 } 3389 3390 3391 void Parser::HandleSourceURLComments(Isolate* isolate, Handle<Script> script) { 3392 Handle<String> source_url = scanner_.SourceUrl(isolate); 3393 if (!source_url.is_null()) { 3394 script->set_source_url(*source_url); 3395 } 3396 Handle<String> source_mapping_url = scanner_.SourceMappingUrl(isolate); 3397 if (!source_mapping_url.is_null()) { 3398 script->set_source_mapping_url(*source_mapping_url); 3399 } 3400 } 3401 3402 void Parser::ReportErrors(Isolate* isolate, Handle<Script> script) { 3403 if (stack_overflow()) { 3404 isolate->StackOverflow(); 3405 } else { 3406 DCHECK(pending_error_handler_.has_pending_error()); 3407 // Internalize ast values for throwing the pending error. 3408 ast_value_factory()->Internalize(isolate); 3409 pending_error_handler_.ThrowPendingError(isolate, script); 3410 } 3411 } 3412 3413 void Parser::UpdateStatistics(Isolate* isolate, Handle<Script> script) { 3414 // Move statistics to Isolate. 3415 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; 3416 ++feature) { 3417 if (use_counts_[feature] > 0) { 3418 isolate->CountUsage(v8::Isolate::UseCounterFeature(feature)); 3419 } 3420 } 3421 if (scanner_.FoundHtmlComment()) { 3422 isolate->CountUsage(v8::Isolate::kHtmlComment); 3423 if (script->line_offset() == 0 && script->column_offset() == 0) { 3424 isolate->CountUsage(v8::Isolate::kHtmlCommentInExternalScript); 3425 } 3426 } 3427 isolate->counters()->total_preparse_skipped()->Increment( 3428 total_preparse_skipped_); 3429 if (!parsing_on_main_thread_ && 3430 FLAG_runtime_stats == 3431 v8::tracing::TracingCategoryObserver::ENABLED_BY_NATIVE) { 3432 // Copy over the counters from the background thread to the main counters on 3433 // the isolate. 3434 isolate->counters()->runtime_call_stats()->Add(runtime_call_stats_); 3435 } 3436 } 3437 3438 void Parser::ParseOnBackground(ParseInfo* info) { 3439 parsing_on_main_thread_ = false; 3440 3441 DCHECK(info->literal() == NULL); 3442 FunctionLiteral* result = NULL; 3443 3444 ParserLogger logger; 3445 if (produce_cached_parse_data()) { 3446 if (allow_lazy_) { 3447 log_ = &logger; 3448 } else { 3449 compile_options_ = ScriptCompiler::kNoCompileOptions; 3450 } 3451 } 3452 if (FLAG_runtime_stats) { 3453 // Create separate runtime stats for background parsing. 3454 runtime_call_stats_ = new (zone()) RuntimeCallStats(); 3455 } 3456 3457 std::unique_ptr<Utf16CharacterStream> stream; 3458 Utf16CharacterStream* stream_ptr; 3459 if (info->character_stream()) { 3460 DCHECK(info->source_stream() == nullptr); 3461 stream_ptr = info->character_stream(); 3462 } else { 3463 DCHECK(info->character_stream() == nullptr); 3464 stream.reset(ScannerStream::For(info->source_stream(), 3465 info->source_stream_encoding(), 3466 runtime_call_stats_)); 3467 stream_ptr = stream.get(); 3468 } 3469 DCHECK(info->maybe_outer_scope_info().is_null()); 3470 3471 DCHECK(original_scope_); 3472 3473 // When streaming, we don't know the length of the source until we have parsed 3474 // it. The raw data can be UTF-8, so we wouldn't know the source length until 3475 // we have decoded it anyway even if we knew the raw data length (which we 3476 // don't). We work around this by storing all the scopes which need their end 3477 // position set at the end of the script (the top scope and possible eval 3478 // scopes) and set their end position after we know the script length. 3479 if (info->is_toplevel()) { 3480 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone()); 3481 scanner_.Initialize(stream_ptr); 3482 result = DoParseProgram(info); 3483 } else { 3484 result = DoParseFunction(info, info->function_name(), stream_ptr); 3485 } 3486 3487 info->set_literal(result); 3488 3489 // We cannot internalize on a background thread; a foreground task will take 3490 // care of calling Parser::Internalize just before compilation. 3491 3492 if (produce_cached_parse_data()) { 3493 if (result != NULL) *info->cached_data() = logger.GetScriptData(); 3494 log_ = NULL; 3495 } 3496 if (FLAG_runtime_stats & 3497 v8::tracing::TracingCategoryObserver::ENABLED_BY_TRACING) { 3498 auto value = v8::tracing::TracedValue::Create(); 3499 runtime_call_stats_->Dump(value.get()); 3500 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("v8.runtime_stats"), 3501 "V8.RuntimeStats", TRACE_EVENT_SCOPE_THREAD, 3502 "runtime-call-stats", std::move(value)); 3503 } 3504 } 3505 3506 Parser::TemplateLiteralState Parser::OpenTemplateLiteral(int pos) { 3507 return new (zone()) TemplateLiteral(zone(), pos); 3508 } 3509 3510 void Parser::AddTemplateSpan(TemplateLiteralState* state, bool should_cook, 3511 bool tail) { 3512 DCHECK(should_cook || allow_harmony_template_escapes()); 3513 int pos = scanner()->location().beg_pos; 3514 int end = scanner()->location().end_pos - (tail ? 1 : 2); 3515 const AstRawString* trv = scanner()->CurrentRawSymbol(ast_value_factory()); 3516 Literal* raw = factory()->NewStringLiteral(trv, pos); 3517 if (should_cook) { 3518 const AstRawString* tv = scanner()->CurrentSymbol(ast_value_factory()); 3519 Literal* cooked = factory()->NewStringLiteral(tv, pos); 3520 (*state)->AddTemplateSpan(cooked, raw, end, zone()); 3521 } else { 3522 (*state)->AddTemplateSpan(GetLiteralUndefined(pos), raw, end, zone()); 3523 } 3524 } 3525 3526 3527 void Parser::AddTemplateExpression(TemplateLiteralState* state, 3528 Expression* expression) { 3529 (*state)->AddExpression(expression, zone()); 3530 } 3531 3532 3533 Expression* Parser::CloseTemplateLiteral(TemplateLiteralState* state, int start, 3534 Expression* tag) { 3535 TemplateLiteral* lit = *state; 3536 int pos = lit->position(); 3537 const ZoneList<Expression*>* cooked_strings = lit->cooked(); 3538 const ZoneList<Expression*>* raw_strings = lit->raw(); 3539 const ZoneList<Expression*>* expressions = lit->expressions(); 3540 DCHECK_EQ(cooked_strings->length(), raw_strings->length()); 3541 DCHECK_EQ(cooked_strings->length(), expressions->length() + 1); 3542 3543 if (!tag) { 3544 // Build tree of BinaryOps to simplify code-generation 3545 Expression* expr = cooked_strings->at(0); 3546 int i = 0; 3547 while (i < expressions->length()) { 3548 Expression* sub = expressions->at(i++); 3549 Expression* cooked_str = cooked_strings->at(i); 3550 3551 // Let middle be ToString(sub). 3552 ZoneList<Expression*>* args = 3553 new (zone()) ZoneList<Expression*>(1, zone()); 3554 args->Add(sub, zone()); 3555 Expression* middle = factory()->NewCallRuntime(Runtime::kInlineToString, 3556 args, sub->position()); 3557 3558 expr = factory()->NewBinaryOperation( 3559 Token::ADD, factory()->NewBinaryOperation( 3560 Token::ADD, expr, middle, expr->position()), 3561 cooked_str, sub->position()); 3562 } 3563 return expr; 3564 } else { 3565 uint32_t hash = ComputeTemplateLiteralHash(lit); 3566 3567 // $getTemplateCallSite 3568 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(4, zone()); 3569 args->Add(factory()->NewArrayLiteral( 3570 const_cast<ZoneList<Expression*>*>(cooked_strings), pos), 3571 zone()); 3572 args->Add(factory()->NewArrayLiteral( 3573 const_cast<ZoneList<Expression*>*>(raw_strings), pos), 3574 zone()); 3575 3576 // Truncate hash to Smi-range. 3577 Smi* hash_obj = Smi::cast(Internals::IntToSmi(static_cast<int>(hash))); 3578 args->Add(factory()->NewNumberLiteral(hash_obj->value(), pos), zone()); 3579 3580 Expression* call_site = factory()->NewCallRuntime( 3581 Context::GET_TEMPLATE_CALL_SITE_INDEX, args, start); 3582 3583 // Call TagFn 3584 ZoneList<Expression*>* call_args = 3585 new (zone()) ZoneList<Expression*>(expressions->length() + 1, zone()); 3586 call_args->Add(call_site, zone()); 3587 call_args->AddAll(*expressions, zone()); 3588 return factory()->NewCall(tag, call_args, pos); 3589 } 3590 } 3591 3592 3593 uint32_t Parser::ComputeTemplateLiteralHash(const TemplateLiteral* lit) { 3594 const ZoneList<Expression*>* raw_strings = lit->raw(); 3595 int total = raw_strings->length(); 3596 DCHECK(total); 3597 3598 uint32_t running_hash = 0; 3599 3600 for (int index = 0; index < total; ++index) { 3601 if (index) { 3602 running_hash = StringHasher::ComputeRunningHashOneByte( 3603 running_hash, "${}", 3); 3604 } 3605 3606 const AstRawString* raw_string = 3607 raw_strings->at(index)->AsLiteral()->raw_value()->AsString(); 3608 if (raw_string->is_one_byte()) { 3609 const char* data = reinterpret_cast<const char*>(raw_string->raw_data()); 3610 running_hash = StringHasher::ComputeRunningHashOneByte( 3611 running_hash, data, raw_string->length()); 3612 } else { 3613 const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data()); 3614 running_hash = StringHasher::ComputeRunningHash(running_hash, data, 3615 raw_string->length()); 3616 } 3617 } 3618 3619 return running_hash; 3620 } 3621 3622 namespace { 3623 3624 bool OnlyLastArgIsSpread(ZoneList<Expression*>* args) { 3625 for (int i = 0; i < args->length() - 1; i++) { 3626 if (args->at(i)->IsSpread()) { 3627 return false; 3628 } 3629 } 3630 return args->at(args->length() - 1)->IsSpread(); 3631 } 3632 3633 } // namespace 3634 3635 ZoneList<Expression*>* Parser::PrepareSpreadArguments( 3636 ZoneList<Expression*>* list) { 3637 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(1, zone()); 3638 if (list->length() == 1) { 3639 // Spread-call with single spread argument produces an InternalArray 3640 // containing the values from the array. 3641 // 3642 // Function is called or constructed with the produced array of arguments 3643 // 3644 // EG: Apply(Func, Spread(spread0)) 3645 ZoneList<Expression*>* spread_list = 3646 new (zone()) ZoneList<Expression*>(0, zone()); 3647 spread_list->Add(list->at(0)->AsSpread()->expression(), zone()); 3648 args->Add(factory()->NewCallRuntime(Runtime::kSpreadIterablePrepare, 3649 spread_list, kNoSourcePosition), 3650 zone()); 3651 return args; 3652 } else { 3653 // Spread-call with multiple arguments produces array literals for each 3654 // sequences of unspread arguments, and converts each spread iterable to 3655 // an Internal array. Finally, all of these produced arrays are flattened 3656 // into a single InternalArray, containing the arguments for the call. 3657 // 3658 // EG: Apply(Func, Flatten([unspread0, unspread1], Spread(spread0), 3659 // Spread(spread1), [unspread2, unspread3])) 3660 int i = 0; 3661 int n = list->length(); 3662 while (i < n) { 3663 if (!list->at(i)->IsSpread()) { 3664 ZoneList<Expression*>* unspread = 3665 new (zone()) ZoneList<Expression*>(1, zone()); 3666 3667 // Push array of unspread parameters 3668 while (i < n && !list->at(i)->IsSpread()) { 3669 unspread->Add(list->at(i++), zone()); 3670 } 3671 args->Add(factory()->NewArrayLiteral(unspread, kNoSourcePosition), 3672 zone()); 3673 3674 if (i == n) break; 3675 } 3676 3677 // Push eagerly spread argument 3678 ZoneList<Expression*>* spread_list = 3679 new (zone()) ZoneList<Expression*>(1, zone()); 3680 spread_list->Add(list->at(i++)->AsSpread()->expression(), zone()); 3681 args->Add(factory()->NewCallRuntime(Context::SPREAD_ITERABLE_INDEX, 3682 spread_list, kNoSourcePosition), 3683 zone()); 3684 } 3685 3686 list = new (zone()) ZoneList<Expression*>(1, zone()); 3687 list->Add(factory()->NewCallRuntime(Context::SPREAD_ARGUMENTS_INDEX, args, 3688 kNoSourcePosition), 3689 zone()); 3690 return list; 3691 } 3692 UNREACHABLE(); 3693 } 3694 3695 Expression* Parser::SpreadCall(Expression* function, 3696 ZoneList<Expression*>* args, int pos, 3697 Call::PossiblyEval is_possibly_eval) { 3698 // Handle these cases in BytecodeGenerator. 3699 // [Call,New]WithSpread bytecodes aren't used with tailcalls - see 3700 // https://crbug.com/v8/5867 3701 if (!allow_tailcalls() && OnlyLastArgIsSpread(args)) { 3702 return factory()->NewCall(function, args, pos); 3703 } 3704 3705 if (function->IsSuperCallReference()) { 3706 // Super calls 3707 // $super_constructor = %_GetSuperConstructor(<this-function>) 3708 // %reflect_construct($super_constructor, args, new.target) 3709 3710 args = PrepareSpreadArguments(args); 3711 ZoneList<Expression*>* tmp = new (zone()) ZoneList<Expression*>(1, zone()); 3712 tmp->Add(function->AsSuperCallReference()->this_function_var(), zone()); 3713 Expression* super_constructor = factory()->NewCallRuntime( 3714 Runtime::kInlineGetSuperConstructor, tmp, pos); 3715 args->InsertAt(0, super_constructor, zone()); 3716 args->Add(function->AsSuperCallReference()->new_target_var(), zone()); 3717 return factory()->NewCallRuntime(Context::REFLECT_CONSTRUCT_INDEX, args, 3718 pos); 3719 } else { 3720 args = PrepareSpreadArguments(args); 3721 if (function->IsProperty()) { 3722 // Method calls 3723 if (function->AsProperty()->IsSuperAccess()) { 3724 Expression* home = ThisExpression(kNoSourcePosition); 3725 args->InsertAt(0, function, zone()); 3726 args->InsertAt(1, home, zone()); 3727 } else { 3728 Variable* temp = NewTemporary(ast_value_factory()->empty_string()); 3729 VariableProxy* obj = factory()->NewVariableProxy(temp); 3730 Assignment* assign_obj = factory()->NewAssignment( 3731 Token::ASSIGN, obj, function->AsProperty()->obj(), 3732 kNoSourcePosition); 3733 function = factory()->NewProperty( 3734 assign_obj, function->AsProperty()->key(), kNoSourcePosition); 3735 args->InsertAt(0, function, zone()); 3736 obj = factory()->NewVariableProxy(temp); 3737 args->InsertAt(1, obj, zone()); 3738 } 3739 } else { 3740 // Non-method calls 3741 args->InsertAt(0, function, zone()); 3742 args->InsertAt(1, factory()->NewUndefinedLiteral(kNoSourcePosition), 3743 zone()); 3744 } 3745 return factory()->NewCallRuntime(Context::REFLECT_APPLY_INDEX, args, pos); 3746 } 3747 } 3748 3749 Expression* Parser::SpreadCallNew(Expression* function, 3750 ZoneList<Expression*>* args, int pos) { 3751 if (OnlyLastArgIsSpread(args)) { 3752 // Handle in BytecodeGenerator. 3753 return factory()->NewCallNew(function, args, pos); 3754 } 3755 args = PrepareSpreadArguments(args); 3756 args->InsertAt(0, function, zone()); 3757 3758 return factory()->NewCallRuntime(Context::REFLECT_CONSTRUCT_INDEX, args, pos); 3759 } 3760 3761 3762 void Parser::SetLanguageMode(Scope* scope, LanguageMode mode) { 3763 v8::Isolate::UseCounterFeature feature; 3764 if (is_sloppy(mode)) 3765 feature = v8::Isolate::kSloppyMode; 3766 else if (is_strict(mode)) 3767 feature = v8::Isolate::kStrictMode; 3768 else 3769 UNREACHABLE(); 3770 ++use_counts_[feature]; 3771 scope->SetLanguageMode(mode); 3772 } 3773 3774 void Parser::SetAsmModule() { 3775 // Store the usage count; The actual use counter on the isolate is 3776 // incremented after parsing is done. 3777 ++use_counts_[v8::Isolate::kUseAsm]; 3778 DCHECK(scope()->is_declaration_scope()); 3779 scope()->AsDeclarationScope()->set_asm_module(); 3780 } 3781 3782 void Parser::MarkCollectedTailCallExpressions() { 3783 const ZoneList<Expression*>& tail_call_expressions = 3784 function_state_->tail_call_expressions().expressions(); 3785 for (int i = 0; i < tail_call_expressions.length(); ++i) { 3786 MarkTailPosition(tail_call_expressions[i]); 3787 } 3788 } 3789 3790 Expression* Parser::ExpressionListToExpression(ZoneList<Expression*>* args) { 3791 Expression* expr = args->at(0); 3792 for (int i = 1; i < args->length(); ++i) { 3793 expr = factory()->NewBinaryOperation(Token::COMMA, expr, args->at(i), 3794 expr->position()); 3795 } 3796 return expr; 3797 } 3798 3799 // This method intoduces the line initializing the generator object 3800 // when desugaring the body of async_function. 3801 void Parser::PrepareAsyncFunctionBody(ZoneList<Statement*>* body, 3802 FunctionKind kind, int pos) { 3803 // When parsing an async arrow function, we get here without having called 3804 // PrepareGeneratorVariables yet, so do it now. 3805 if (function_state_->generator_object_variable() == nullptr) { 3806 PrepareGeneratorVariables(); 3807 } 3808 body->Add(factory()->NewExpressionStatement( 3809 BuildCreateJSGeneratorObject(pos, kind), kNoSourcePosition), 3810 zone()); 3811 } 3812 3813 // This method completes the desugaring of the body of async_function. 3814 void Parser::RewriteAsyncFunctionBody(ZoneList<Statement*>* body, Block* block, 3815 Expression* return_value, bool* ok) { 3816 // function async_function() { 3817 // .generator_object = %CreateJSGeneratorObject(); 3818 // BuildRejectPromiseOnException({ 3819 // ... block ... 3820 // return %ResolvePromise(.promise, expr), .promise; 3821 // }) 3822 // } 3823 3824 return_value = BuildResolvePromise(return_value, return_value->position()); 3825 block->statements()->Add( 3826 factory()->NewReturnStatement(return_value, return_value->position()), 3827 zone()); 3828 block = BuildRejectPromiseOnException(block); 3829 body->Add(block, zone()); 3830 } 3831 3832 Expression* Parser::RewriteAwaitExpression(Expression* value, int await_pos) { 3833 // yield do { 3834 // tmp = <operand>; 3835 // %AsyncFunctionAwait(.generator_object, tmp, .promise); 3836 // .promise 3837 // } 3838 // The value of the expression is returned to the caller of the async 3839 // function for the first yield statement; for this, .promise is the 3840 // appropriate return value, being a Promise that will be fulfilled or 3841 // rejected with the appropriate value by the desugaring. Subsequent yield 3842 // occurrences will return to the AsyncFunctionNext call within the 3843 // implemementation of the intermediate throwaway Promise's then handler. 3844 // This handler has nothing useful to do with the value, as the Promise is 3845 // ignored. If we yielded the value of the throwawayPromise that 3846 // AsyncFunctionAwait creates as an intermediate, it would create a memory 3847 // leak; we must return .promise instead; 3848 // The operand needs to be evaluated on a separate statement in order to get 3849 // a break location, and the .promise needs to be read earlier so that it 3850 // doesn't insert a false location. 3851 // TODO(littledan): investigate why this ordering is needed in more detail. 3852 Variable* generator_object_variable = 3853 function_state_->generator_object_variable(); 3854 DCHECK_NOT_NULL(generator_object_variable); 3855 3856 const int nopos = kNoSourcePosition; 3857 3858 Block* do_block = factory()->NewBlock(nullptr, 2, false, nopos); 3859 3860 Variable* promise = PromiseVariable(); 3861 3862 // Wrap value evaluation to provide a break location. 3863 Variable* temp_var = NewTemporary(ast_value_factory()->empty_string()); 3864 Expression* value_assignment = factory()->NewAssignment( 3865 Token::ASSIGN, factory()->NewVariableProxy(temp_var), value, nopos); 3866 do_block->statements()->Add( 3867 factory()->NewExpressionStatement(value_assignment, value->position()), 3868 zone()); 3869 3870 ZoneList<Expression*>* async_function_await_args = 3871 new (zone()) ZoneList<Expression*>(3, zone()); 3872 Expression* generator_object = 3873 factory()->NewVariableProxy(generator_object_variable); 3874 async_function_await_args->Add(generator_object, zone()); 3875 async_function_await_args->Add(factory()->NewVariableProxy(temp_var), zone()); 3876 async_function_await_args->Add(factory()->NewVariableProxy(promise), zone()); 3877 3878 // The parser emits calls to AsyncFunctionAwaitCaught, but the 3879 // AstNumberingVisitor will rewrite this to AsyncFunctionAwaitUncaught 3880 // if there is no local enclosing try/catch block. 3881 Expression* async_function_await = 3882 factory()->NewCallRuntime(Context::ASYNC_FUNCTION_AWAIT_CAUGHT_INDEX, 3883 async_function_await_args, nopos); 3884 do_block->statements()->Add( 3885 factory()->NewExpressionStatement(async_function_await, await_pos), 3886 zone()); 3887 3888 // Wrap await to provide a break location between value evaluation and yield. 3889 Expression* do_expr = factory()->NewDoExpression(do_block, promise, nopos); 3890 3891 generator_object = factory()->NewVariableProxy(generator_object_variable); 3892 return factory()->NewYield(generator_object, do_expr, nopos, 3893 Yield::kOnExceptionRethrow); 3894 } 3895 3896 class NonPatternRewriter : public AstExpressionRewriter { 3897 public: 3898 NonPatternRewriter(uintptr_t stack_limit, Parser* parser) 3899 : AstExpressionRewriter(stack_limit), parser_(parser) {} 3900 ~NonPatternRewriter() override {} 3901 3902 private: 3903 bool RewriteExpression(Expression* expr) override { 3904 if (expr->IsRewritableExpression()) return true; 3905 // Rewrite only what could have been a pattern but is not. 3906 if (expr->IsArrayLiteral()) { 3907 // Spread rewriting in array literals. 3908 ArrayLiteral* lit = expr->AsArrayLiteral(); 3909 VisitExpressions(lit->values()); 3910 replacement_ = parser_->RewriteSpreads(lit); 3911 return false; 3912 } 3913 if (expr->IsObjectLiteral()) { 3914 return true; 3915 } 3916 if (expr->IsBinaryOperation() && 3917 expr->AsBinaryOperation()->op() == Token::COMMA) { 3918 return true; 3919 } 3920 // Everything else does not need rewriting. 3921 return false; 3922 } 3923 3924 void VisitLiteralProperty(LiteralProperty* property) override { 3925 if (property == nullptr) return; 3926 // Do not rewrite (computed) key expressions 3927 AST_REWRITE_PROPERTY(Expression, property, value); 3928 } 3929 3930 Parser* parser_; 3931 }; 3932 3933 void Parser::RewriteNonPattern(bool* ok) { 3934 ValidateExpression(CHECK_OK_VOID); 3935 auto non_patterns_to_rewrite = function_state_->non_patterns_to_rewrite(); 3936 int begin = classifier()->GetNonPatternBegin(); 3937 int end = non_patterns_to_rewrite->length(); 3938 if (begin < end) { 3939 NonPatternRewriter rewriter(stack_limit_, this); 3940 for (int i = begin; i < end; i++) { 3941 DCHECK(non_patterns_to_rewrite->at(i)->IsRewritableExpression()); 3942 rewriter.Rewrite(non_patterns_to_rewrite->at(i)); 3943 } 3944 non_patterns_to_rewrite->Rewind(begin); 3945 } 3946 } 3947 3948 3949 void Parser::RewriteDestructuringAssignments() { 3950 const auto& assignments = 3951 function_state_->destructuring_assignments_to_rewrite(); 3952 for (int i = assignments.length() - 1; i >= 0; --i) { 3953 // Rewrite list in reverse, so that nested assignment patterns are rewritten 3954 // correctly. 3955 const DestructuringAssignment& pair = assignments.at(i); 3956 RewritableExpression* to_rewrite = 3957 pair.assignment->AsRewritableExpression(); 3958 DCHECK_NOT_NULL(to_rewrite); 3959 if (!to_rewrite->is_rewritten()) { 3960 // Since this function is called at the end of parsing the program, 3961 // pair.scope may already have been removed by FinalizeBlockScope in the 3962 // meantime. 3963 Scope* scope = pair.scope->GetUnremovedScope(); 3964 PatternRewriter::RewriteDestructuringAssignment(this, to_rewrite, scope); 3965 } 3966 } 3967 } 3968 3969 Expression* Parser::RewriteExponentiation(Expression* left, Expression* right, 3970 int pos) { 3971 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone()); 3972 args->Add(left, zone()); 3973 args->Add(right, zone()); 3974 return factory()->NewCallRuntime(Context::MATH_POW_INDEX, args, pos); 3975 } 3976 3977 Expression* Parser::RewriteAssignExponentiation(Expression* left, 3978 Expression* right, int pos) { 3979 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone()); 3980 if (left->IsVariableProxy()) { 3981 VariableProxy* lhs = left->AsVariableProxy(); 3982 3983 Expression* result; 3984 DCHECK_NOT_NULL(lhs->raw_name()); 3985 result = ExpressionFromIdentifier(lhs->raw_name(), lhs->position()); 3986 args->Add(left, zone()); 3987 args->Add(right, zone()); 3988 Expression* call = 3989 factory()->NewCallRuntime(Context::MATH_POW_INDEX, args, pos); 3990 return factory()->NewAssignment(Token::ASSIGN, result, call, pos); 3991 } else if (left->IsProperty()) { 3992 Property* prop = left->AsProperty(); 3993 auto temp_obj = NewTemporary(ast_value_factory()->empty_string()); 3994 auto temp_key = NewTemporary(ast_value_factory()->empty_string()); 3995 Expression* assign_obj = factory()->NewAssignment( 3996 Token::ASSIGN, factory()->NewVariableProxy(temp_obj), prop->obj(), 3997 kNoSourcePosition); 3998 Expression* assign_key = factory()->NewAssignment( 3999 Token::ASSIGN, factory()->NewVariableProxy(temp_key), prop->key(), 4000 kNoSourcePosition); 4001 args->Add(factory()->NewProperty(factory()->NewVariableProxy(temp_obj), 4002 factory()->NewVariableProxy(temp_key), 4003 left->position()), 4004 zone()); 4005 args->Add(right, zone()); 4006 Expression* call = 4007 factory()->NewCallRuntime(Context::MATH_POW_INDEX, args, pos); 4008 Expression* target = factory()->NewProperty( 4009 factory()->NewVariableProxy(temp_obj), 4010 factory()->NewVariableProxy(temp_key), kNoSourcePosition); 4011 Expression* assign = 4012 factory()->NewAssignment(Token::ASSIGN, target, call, pos); 4013 return factory()->NewBinaryOperation( 4014 Token::COMMA, assign_obj, 4015 factory()->NewBinaryOperation(Token::COMMA, assign_key, assign, pos), 4016 pos); 4017 } 4018 UNREACHABLE(); 4019 return nullptr; 4020 } 4021 4022 Expression* Parser::RewriteSpreads(ArrayLiteral* lit) { 4023 // Array literals containing spreads are rewritten using do expressions, e.g. 4024 // [1, 2, 3, ...x, 4, ...y, 5] 4025 // is roughly rewritten as: 4026 // do { 4027 // $R = [1, 2, 3]; 4028 // for ($i of x) %AppendElement($R, $i); 4029 // %AppendElement($R, 4); 4030 // for ($j of y) %AppendElement($R, $j); 4031 // %AppendElement($R, 5); 4032 // $R 4033 // } 4034 // where $R, $i and $j are fresh temporary variables. 4035 ZoneList<Expression*>::iterator s = lit->FirstSpread(); 4036 if (s == lit->EndValue()) return nullptr; // no spread, no rewriting... 4037 Variable* result = NewTemporary(ast_value_factory()->dot_result_string()); 4038 // NOTE: The value assigned to R is the whole original array literal, 4039 // spreads included. This will be fixed before the rewritten AST is returned. 4040 // $R = lit 4041 Expression* init_result = factory()->NewAssignment( 4042 Token::INIT, factory()->NewVariableProxy(result), lit, kNoSourcePosition); 4043 Block* do_block = factory()->NewBlock(nullptr, 16, false, kNoSourcePosition); 4044 do_block->statements()->Add( 4045 factory()->NewExpressionStatement(init_result, kNoSourcePosition), 4046 zone()); 4047 // Traverse the array literal starting from the first spread. 4048 while (s != lit->EndValue()) { 4049 Expression* value = *s++; 4050 Spread* spread = value->AsSpread(); 4051 if (spread == nullptr) { 4052 // If the element is not a spread, we're adding a single: 4053 // %AppendElement($R, value) 4054 // or, in case of a hole, 4055 // ++($R.length) 4056 if (!value->IsLiteral() || 4057 !value->AsLiteral()->raw_value()->IsTheHole()) { 4058 ZoneList<Expression*>* append_element_args = NewExpressionList(2); 4059 append_element_args->Add(factory()->NewVariableProxy(result), zone()); 4060 append_element_args->Add(value, zone()); 4061 do_block->statements()->Add( 4062 factory()->NewExpressionStatement( 4063 factory()->NewCallRuntime(Runtime::kAppendElement, 4064 append_element_args, 4065 kNoSourcePosition), 4066 kNoSourcePosition), 4067 zone()); 4068 } else { 4069 Property* length_property = factory()->NewProperty( 4070 factory()->NewVariableProxy(result), 4071 factory()->NewStringLiteral(ast_value_factory()->length_string(), 4072 kNoSourcePosition), 4073 kNoSourcePosition); 4074 CountOperation* count_op = factory()->NewCountOperation( 4075 Token::INC, true /* prefix */, length_property, kNoSourcePosition); 4076 do_block->statements()->Add( 4077 factory()->NewExpressionStatement(count_op, kNoSourcePosition), 4078 zone()); 4079 } 4080 } else { 4081 // If it's a spread, we're adding a for/of loop iterating through it. 4082 Variable* each = NewTemporary(ast_value_factory()->dot_for_string()); 4083 Expression* subject = spread->expression(); 4084 // %AppendElement($R, each) 4085 Statement* append_body; 4086 { 4087 ZoneList<Expression*>* append_element_args = NewExpressionList(2); 4088 append_element_args->Add(factory()->NewVariableProxy(result), zone()); 4089 append_element_args->Add(factory()->NewVariableProxy(each), zone()); 4090 append_body = factory()->NewExpressionStatement( 4091 factory()->NewCallRuntime(Runtime::kAppendElement, 4092 append_element_args, kNoSourcePosition), 4093 kNoSourcePosition); 4094 } 4095 // for (each of spread) %AppendElement($R, each) 4096 ForOfStatement* loop = 4097 factory()->NewForOfStatement(nullptr, kNoSourcePosition); 4098 const bool finalize = false; 4099 InitializeForOfStatement(loop, factory()->NewVariableProxy(each), subject, 4100 append_body, finalize, IteratorType::kNormal); 4101 do_block->statements()->Add(loop, zone()); 4102 } 4103 } 4104 // Now, rewind the original array literal to truncate everything from the 4105 // first spread (included) until the end. This fixes $R's initialization. 4106 lit->RewindSpreads(); 4107 return factory()->NewDoExpression(do_block, result, lit->position()); 4108 } 4109 4110 void Parser::QueueDestructuringAssignmentForRewriting(Expression* expr) { 4111 DCHECK(expr->IsRewritableExpression()); 4112 function_state_->AddDestructuringAssignment( 4113 DestructuringAssignment(expr, scope())); 4114 } 4115 4116 void Parser::QueueNonPatternForRewriting(Expression* expr, bool* ok) { 4117 DCHECK(expr->IsRewritableExpression()); 4118 function_state_->AddNonPatternForRewriting(expr, ok); 4119 } 4120 4121 void Parser::AddAccessorPrefixToFunctionName(bool is_get, 4122 FunctionLiteral* function, 4123 const AstRawString* name) { 4124 DCHECK_NOT_NULL(name); 4125 const AstRawString* prefix = is_get ? ast_value_factory()->get_space_string() 4126 : ast_value_factory()->set_space_string(); 4127 function->set_raw_name(ast_value_factory()->NewConsString(prefix, name)); 4128 } 4129 4130 void Parser::SetFunctionNameFromPropertyName(ObjectLiteralProperty* property, 4131 const AstRawString* name) { 4132 DCHECK(property->kind() != ObjectLiteralProperty::GETTER); 4133 DCHECK(property->kind() != ObjectLiteralProperty::SETTER); 4134 4135 // Computed name setting must happen at runtime. 4136 DCHECK(!property->is_computed_name()); 4137 4138 // Ignore "__proto__" as a name when it's being used to set the [[Prototype]] 4139 // of an object literal. 4140 if (property->kind() == ObjectLiteralProperty::PROTOTYPE) return; 4141 4142 Expression* value = property->value(); 4143 4144 DCHECK(!value->IsAnonymousFunctionDefinition() || 4145 property->kind() == ObjectLiteralProperty::COMPUTED); 4146 SetFunctionName(value, name); 4147 } 4148 4149 void Parser::SetFunctionNameFromIdentifierRef(Expression* value, 4150 Expression* identifier) { 4151 if (!identifier->IsVariableProxy()) return; 4152 SetFunctionName(value, identifier->AsVariableProxy()->raw_name()); 4153 } 4154 4155 void Parser::SetFunctionName(Expression* value, const AstRawString* name) { 4156 DCHECK_NOT_NULL(name); 4157 if (!value->IsAnonymousFunctionDefinition()) return; 4158 auto function = value->AsFunctionLiteral(); 4159 if (function != nullptr) { 4160 function->set_raw_name(name); 4161 } else { 4162 DCHECK(value->IsDoExpression()); 4163 value->AsDoExpression()->represented_function()->set_raw_name(name); 4164 } 4165 } 4166 4167 4168 // Desugaring of yield* 4169 // ==================== 4170 // 4171 // With the help of do-expressions and function.sent, we desugar yield* into a 4172 // loop containing a "raw" yield (a yield that doesn't wrap an iterator result 4173 // object around its argument). Concretely, "yield* iterable" turns into 4174 // roughly the following code: 4175 // 4176 // do { 4177 // const kNext = 0; 4178 // const kReturn = 1; 4179 // const kThrow = 2; 4180 // 4181 // let input = undefined; 4182 // let mode = kNext; 4183 // let output = undefined; 4184 // 4185 // let iterator = GetIterator(iterable); 4186 // 4187 // while (true) { 4188 // // From the generator to the iterator: 4189 // // Forward input according to resume mode and obtain output. 4190 // switch (mode) { 4191 // case kNext: 4192 // output = iterator.next(input); 4193 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output); 4194 // break; 4195 // case kReturn: 4196 // IteratorClose(iterator, input, output); // See below. 4197 // break; 4198 // case kThrow: 4199 // let iteratorThrow = iterator.throw; 4200 // if (IS_NULL_OR_UNDEFINED(iteratorThrow)) { 4201 // IteratorClose(iterator); // See below. 4202 // throw MakeTypeError(kThrowMethodMissing); 4203 // } 4204 // output = %_Call(iteratorThrow, iterator, input); 4205 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output); 4206 // break; 4207 // } 4208 // if (output.done) break; 4209 // 4210 // // From the generator to its user: 4211 // // Forward output, receive new input, and determine resume mode. 4212 // mode = kReturn; 4213 // try { 4214 // try { 4215 // RawYield(output); // See explanation above. 4216 // mode = kNext; 4217 // } catch (error) { 4218 // mode = kThrow; 4219 // } 4220 // } finally { 4221 // input = function.sent; 4222 // continue; 4223 // } 4224 // } 4225 // 4226 // if (mode === kReturn) { 4227 // return {value: output.value, done: true}; 4228 // } 4229 // output.value 4230 // } 4231 // 4232 // IteratorClose(iterator) expands to the following: 4233 // 4234 // let iteratorReturn = iterator.return; 4235 // if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) { 4236 // let output = %_Call(iteratorReturn, iterator); 4237 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output); 4238 // } 4239 // 4240 // IteratorClose(iterator, input, output) expands to the following: 4241 // 4242 // let iteratorReturn = iterator.return; 4243 // if (IS_NULL_OR_UNDEFINED(iteratorReturn)) return input; 4244 // output = %_Call(iteratorReturn, iterator, input); 4245 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output); 4246 4247 Expression* Parser::RewriteYieldStar(Expression* generator, 4248 Expression* iterable, int pos) { 4249 const int nopos = kNoSourcePosition; 4250 4251 // Forward definition for break/continue statements. 4252 WhileStatement* loop = factory()->NewWhileStatement(nullptr, nopos); 4253 4254 // let input = undefined; 4255 Variable* var_input = NewTemporary(ast_value_factory()->empty_string()); 4256 Statement* initialize_input; 4257 { 4258 Expression* input_proxy = factory()->NewVariableProxy(var_input); 4259 Expression* assignment = 4260 factory()->NewAssignment(Token::ASSIGN, input_proxy, 4261 factory()->NewUndefinedLiteral(nopos), nopos); 4262 initialize_input = factory()->NewExpressionStatement(assignment, nopos); 4263 } 4264 4265 // let mode = kNext; 4266 Variable* var_mode = NewTemporary(ast_value_factory()->empty_string()); 4267 Statement* initialize_mode; 4268 { 4269 Expression* mode_proxy = factory()->NewVariableProxy(var_mode); 4270 Expression* knext = 4271 factory()->NewSmiLiteral(JSGeneratorObject::kNext, nopos); 4272 Expression* assignment = 4273 factory()->NewAssignment(Token::ASSIGN, mode_proxy, knext, nopos); 4274 initialize_mode = factory()->NewExpressionStatement(assignment, nopos); 4275 } 4276 4277 // let output = undefined; 4278 Variable* var_output = NewTemporary(ast_value_factory()->empty_string()); 4279 Statement* initialize_output; 4280 { 4281 Expression* output_proxy = factory()->NewVariableProxy(var_output); 4282 Expression* assignment = 4283 factory()->NewAssignment(Token::ASSIGN, output_proxy, 4284 factory()->NewUndefinedLiteral(nopos), nopos); 4285 initialize_output = factory()->NewExpressionStatement(assignment, nopos); 4286 } 4287 4288 // let iterator = GetIterator(iterable); 4289 Variable* var_iterator = NewTemporary(ast_value_factory()->empty_string()); 4290 Statement* get_iterator; 4291 { 4292 Expression* iterator = 4293 factory()->NewGetIterator(iterable, IteratorType::kNormal, nopos); 4294 Expression* iterator_proxy = factory()->NewVariableProxy(var_iterator); 4295 Expression* assignment = factory()->NewAssignment( 4296 Token::ASSIGN, iterator_proxy, iterator, nopos); 4297 get_iterator = factory()->NewExpressionStatement(assignment, nopos); 4298 } 4299 4300 // output = iterator.next(input); 4301 Statement* call_next; 4302 { 4303 Expression* iterator_proxy = factory()->NewVariableProxy(var_iterator); 4304 Expression* literal = 4305 factory()->NewStringLiteral(ast_value_factory()->next_string(), nopos); 4306 Expression* next_property = 4307 factory()->NewProperty(iterator_proxy, literal, nopos); 4308 Expression* input_proxy = factory()->NewVariableProxy(var_input); 4309 auto args = new (zone()) ZoneList<Expression*>(1, zone()); 4310 args->Add(input_proxy, zone()); 4311 Expression* call = factory()->NewCall(next_property, args, nopos); 4312 Expression* output_proxy = factory()->NewVariableProxy(var_output); 4313 Expression* assignment = 4314 factory()->NewAssignment(Token::ASSIGN, output_proxy, call, nopos); 4315 call_next = factory()->NewExpressionStatement(assignment, nopos); 4316 } 4317 4318 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output); 4319 Statement* validate_next_output; 4320 { 4321 Expression* is_receiver_call; 4322 { 4323 auto args = new (zone()) ZoneList<Expression*>(1, zone()); 4324 args->Add(factory()->NewVariableProxy(var_output), zone()); 4325 is_receiver_call = 4326 factory()->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos); 4327 } 4328 4329 Statement* throw_call; 4330 { 4331 auto args = new (zone()) ZoneList<Expression*>(1, zone()); 4332 args->Add(factory()->NewVariableProxy(var_output), zone()); 4333 Expression* call = factory()->NewCallRuntime( 4334 Runtime::kThrowIteratorResultNotAnObject, args, nopos); 4335 throw_call = factory()->NewExpressionStatement(call, nopos); 4336 } 4337 4338 validate_next_output = factory()->NewIfStatement( 4339 is_receiver_call, factory()->NewEmptyStatement(nopos), throw_call, 4340 nopos); 4341 } 4342 4343 // let iteratorThrow = iterator.throw; 4344 Variable* var_throw = NewTemporary(ast_value_factory()->empty_string()); 4345 Statement* get_throw; 4346 { 4347 Expression* iterator_proxy = factory()->NewVariableProxy(var_iterator); 4348 Expression* literal = 4349 factory()->NewStringLiteral(ast_value_factory()->throw_string(), nopos); 4350 Expression* property = 4351 factory()->NewProperty(iterator_proxy, literal, nopos); 4352 Expression* throw_proxy = factory()->NewVariableProxy(var_throw); 4353 Expression* assignment = 4354 factory()->NewAssignment(Token::ASSIGN, throw_proxy, property, nopos); 4355 get_throw = factory()->NewExpressionStatement(assignment, nopos); 4356 } 4357 4358 // if (IS_NULL_OR_UNDEFINED(iteratorThrow) { 4359 // IteratorClose(iterator); 4360 // throw MakeTypeError(kThrowMethodMissing); 4361 // } 4362 Statement* check_throw; 4363 { 4364 Expression* condition = factory()->NewCompareOperation( 4365 Token::EQ, factory()->NewVariableProxy(var_throw), 4366 factory()->NewNullLiteral(nopos), nopos); 4367 Expression* call = 4368 NewThrowTypeError(MessageTemplate::kThrowMethodMissing, 4369 ast_value_factory()->empty_string(), nopos); 4370 Statement* throw_call = factory()->NewExpressionStatement(call, nopos); 4371 4372 Block* then = factory()->NewBlock(nullptr, 4 + 1, false, nopos); 4373 BuildIteratorCloseForCompletion( 4374 scope(), then->statements(), var_iterator, 4375 factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos), 4376 IteratorType::kNormal); 4377 then->statements()->Add(throw_call, zone()); 4378 check_throw = factory()->NewIfStatement( 4379 condition, then, factory()->NewEmptyStatement(nopos), nopos); 4380 } 4381 4382 // output = %_Call(iteratorThrow, iterator, input); 4383 Statement* call_throw; 4384 { 4385 auto args = new (zone()) ZoneList<Expression*>(3, zone()); 4386 args->Add(factory()->NewVariableProxy(var_throw), zone()); 4387 args->Add(factory()->NewVariableProxy(var_iterator), zone()); 4388 args->Add(factory()->NewVariableProxy(var_input), zone()); 4389 Expression* call = 4390 factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos); 4391 Expression* assignment = factory()->NewAssignment( 4392 Token::ASSIGN, factory()->NewVariableProxy(var_output), call, nopos); 4393 call_throw = factory()->NewExpressionStatement(assignment, nopos); 4394 } 4395 4396 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output); 4397 Statement* validate_throw_output; 4398 { 4399 Expression* is_receiver_call; 4400 { 4401 auto args = new (zone()) ZoneList<Expression*>(1, zone()); 4402 args->Add(factory()->NewVariableProxy(var_output), zone()); 4403 is_receiver_call = 4404 factory()->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos); 4405 } 4406 4407 Statement* throw_call; 4408 { 4409 auto args = new (zone()) ZoneList<Expression*>(1, zone()); 4410 args->Add(factory()->NewVariableProxy(var_output), zone()); 4411 Expression* call = factory()->NewCallRuntime( 4412 Runtime::kThrowIteratorResultNotAnObject, args, nopos); 4413 throw_call = factory()->NewExpressionStatement(call, nopos); 4414 } 4415 4416 validate_throw_output = factory()->NewIfStatement( 4417 is_receiver_call, factory()->NewEmptyStatement(nopos), throw_call, 4418 nopos); 4419 } 4420 4421 // if (output.done) break; 4422 Statement* if_done; 4423 { 4424 Expression* output_proxy = factory()->NewVariableProxy(var_output); 4425 Expression* literal = 4426 factory()->NewStringLiteral(ast_value_factory()->done_string(), nopos); 4427 Expression* property = factory()->NewProperty(output_proxy, literal, nopos); 4428 BreakStatement* break_loop = factory()->NewBreakStatement(loop, nopos); 4429 if_done = factory()->NewIfStatement( 4430 property, break_loop, factory()->NewEmptyStatement(nopos), nopos); 4431 } 4432 4433 4434 // mode = kReturn; 4435 Statement* set_mode_return; 4436 { 4437 Expression* mode_proxy = factory()->NewVariableProxy(var_mode); 4438 Expression* kreturn = 4439 factory()->NewSmiLiteral(JSGeneratorObject::kReturn, nopos); 4440 Expression* assignment = 4441 factory()->NewAssignment(Token::ASSIGN, mode_proxy, kreturn, nopos); 4442 set_mode_return = factory()->NewExpressionStatement(assignment, nopos); 4443 } 4444 4445 // Yield(output); 4446 Statement* yield_output; 4447 { 4448 Expression* output_proxy = factory()->NewVariableProxy(var_output); 4449 Yield* yield = factory()->NewYield(generator, output_proxy, nopos, 4450 Yield::kOnExceptionThrow); 4451 yield_output = factory()->NewExpressionStatement(yield, nopos); 4452 } 4453 4454 // mode = kNext; 4455 Statement* set_mode_next; 4456 { 4457 Expression* mode_proxy = factory()->NewVariableProxy(var_mode); 4458 Expression* knext = 4459 factory()->NewSmiLiteral(JSGeneratorObject::kNext, nopos); 4460 Expression* assignment = 4461 factory()->NewAssignment(Token::ASSIGN, mode_proxy, knext, nopos); 4462 set_mode_next = factory()->NewExpressionStatement(assignment, nopos); 4463 } 4464 4465 // mode = kThrow; 4466 Statement* set_mode_throw; 4467 { 4468 Expression* mode_proxy = factory()->NewVariableProxy(var_mode); 4469 Expression* kthrow = 4470 factory()->NewSmiLiteral(JSGeneratorObject::kThrow, nopos); 4471 Expression* assignment = 4472 factory()->NewAssignment(Token::ASSIGN, mode_proxy, kthrow, nopos); 4473 set_mode_throw = factory()->NewExpressionStatement(assignment, nopos); 4474 } 4475 4476 // input = function.sent; 4477 Statement* get_input; 4478 { 4479 Expression* function_sent = FunctionSentExpression(nopos); 4480 Expression* input_proxy = factory()->NewVariableProxy(var_input); 4481 Expression* assignment = factory()->NewAssignment( 4482 Token::ASSIGN, input_proxy, function_sent, nopos); 4483 get_input = factory()->NewExpressionStatement(assignment, nopos); 4484 } 4485 4486 // if (mode === kReturn) { 4487 // return {value: output.value, done: true}; 4488 // } 4489 Statement* maybe_return_value; 4490 { 4491 Expression* mode_proxy = factory()->NewVariableProxy(var_mode); 4492 Expression* kreturn = 4493 factory()->NewSmiLiteral(JSGeneratorObject::kReturn, nopos); 4494 Expression* condition = factory()->NewCompareOperation( 4495 Token::EQ_STRICT, mode_proxy, kreturn, nopos); 4496 4497 Expression* output_proxy = factory()->NewVariableProxy(var_output); 4498 Expression* literal = 4499 factory()->NewStringLiteral(ast_value_factory()->value_string(), nopos); 4500 Expression* property = factory()->NewProperty(output_proxy, literal, nopos); 4501 Statement* return_value = factory()->NewReturnStatement( 4502 BuildIteratorResult(property, true), nopos); 4503 4504 maybe_return_value = factory()->NewIfStatement( 4505 condition, return_value, factory()->NewEmptyStatement(nopos), nopos); 4506 } 4507 4508 // output.value 4509 Statement* get_value; 4510 { 4511 Expression* output_proxy = factory()->NewVariableProxy(var_output); 4512 Expression* literal = 4513 factory()->NewStringLiteral(ast_value_factory()->value_string(), nopos); 4514 Expression* property = factory()->NewProperty(output_proxy, literal, nopos); 4515 get_value = factory()->NewExpressionStatement(property, nopos); 4516 } 4517 4518 // Now put things together. 4519 4520 // try { ... } catch(e) { ... } 4521 Statement* try_catch; 4522 { 4523 Block* try_block = factory()->NewBlock(nullptr, 2, false, nopos); 4524 try_block->statements()->Add(yield_output, zone()); 4525 try_block->statements()->Add(set_mode_next, zone()); 4526 4527 Block* catch_block = factory()->NewBlock(nullptr, 1, false, nopos); 4528 catch_block->statements()->Add(set_mode_throw, zone()); 4529 4530 Scope* catch_scope = NewScope(CATCH_SCOPE); 4531 catch_scope->set_is_hidden(); 4532 const AstRawString* name = ast_value_factory()->dot_catch_string(); 4533 Variable* catch_variable = catch_scope->DeclareLocal(name, VAR); 4534 4535 try_catch = factory()->NewTryCatchStatementForDesugaring( 4536 try_block, catch_scope, catch_variable, catch_block, nopos); 4537 } 4538 4539 // try { ... } finally { ... } 4540 Statement* try_finally; 4541 { 4542 Block* try_block = factory()->NewBlock(nullptr, 1, false, nopos); 4543 try_block->statements()->Add(try_catch, zone()); 4544 4545 Block* finally = factory()->NewBlock(nullptr, 2, false, nopos); 4546 finally->statements()->Add(get_input, zone()); 4547 finally->statements()->Add(factory()->NewContinueStatement(loop, nopos), 4548 zone()); 4549 4550 try_finally = factory()->NewTryFinallyStatement(try_block, finally, nopos); 4551 } 4552 4553 // switch (mode) { ... } 4554 SwitchStatement* switch_mode = factory()->NewSwitchStatement(nullptr, nopos); 4555 { 4556 auto case_next = new (zone()) ZoneList<Statement*>(3, zone()); 4557 case_next->Add(call_next, zone()); 4558 case_next->Add(validate_next_output, zone()); 4559 case_next->Add(factory()->NewBreakStatement(switch_mode, nopos), zone()); 4560 4561 auto case_return = new (zone()) ZoneList<Statement*>(5, zone()); 4562 BuildIteratorClose(case_return, var_iterator, var_input, var_output); 4563 case_return->Add(factory()->NewBreakStatement(switch_mode, nopos), zone()); 4564 4565 auto case_throw = new (zone()) ZoneList<Statement*>(5, zone()); 4566 case_throw->Add(get_throw, zone()); 4567 case_throw->Add(check_throw, zone()); 4568 case_throw->Add(call_throw, zone()); 4569 case_throw->Add(validate_throw_output, zone()); 4570 case_throw->Add(factory()->NewBreakStatement(switch_mode, nopos), zone()); 4571 4572 auto cases = new (zone()) ZoneList<CaseClause*>(3, zone()); 4573 Expression* knext = 4574 factory()->NewSmiLiteral(JSGeneratorObject::kNext, nopos); 4575 Expression* kreturn = 4576 factory()->NewSmiLiteral(JSGeneratorObject::kReturn, nopos); 4577 Expression* kthrow = 4578 factory()->NewSmiLiteral(JSGeneratorObject::kThrow, nopos); 4579 cases->Add(factory()->NewCaseClause(knext, case_next, nopos), zone()); 4580 cases->Add(factory()->NewCaseClause(kreturn, case_return, nopos), zone()); 4581 cases->Add(factory()->NewCaseClause(kthrow, case_throw, nopos), zone()); 4582 4583 switch_mode->Initialize(factory()->NewVariableProxy(var_mode), cases); 4584 } 4585 4586 // while (true) { ... } 4587 // Already defined earlier: WhileStatement* loop = ... 4588 { 4589 Block* loop_body = factory()->NewBlock(nullptr, 4, false, nopos); 4590 loop_body->statements()->Add(switch_mode, zone()); 4591 loop_body->statements()->Add(if_done, zone()); 4592 loop_body->statements()->Add(set_mode_return, zone()); 4593 loop_body->statements()->Add(try_finally, zone()); 4594 4595 loop->Initialize(factory()->NewBooleanLiteral(true, nopos), loop_body); 4596 } 4597 4598 // do { ... } 4599 DoExpression* yield_star; 4600 { 4601 // The rewriter needs to process the get_value statement only, hence we 4602 // put the preceding statements into an init block. 4603 4604 Block* do_block_ = factory()->NewBlock(nullptr, 6, true, nopos); 4605 do_block_->statements()->Add(initialize_input, zone()); 4606 do_block_->statements()->Add(initialize_mode, zone()); 4607 do_block_->statements()->Add(initialize_output, zone()); 4608 do_block_->statements()->Add(get_iterator, zone()); 4609 do_block_->statements()->Add(loop, zone()); 4610 do_block_->statements()->Add(maybe_return_value, zone()); 4611 4612 Block* do_block = factory()->NewBlock(nullptr, 2, false, nopos); 4613 do_block->statements()->Add(do_block_, zone()); 4614 do_block->statements()->Add(get_value, zone()); 4615 4616 Variable* dot_result = 4617 NewTemporary(ast_value_factory()->dot_result_string()); 4618 yield_star = factory()->NewDoExpression(do_block, dot_result, nopos); 4619 Rewriter::Rewrite(this, GetClosureScope(), yield_star, ast_value_factory()); 4620 } 4621 4622 return yield_star; 4623 } 4624 4625 Statement* Parser::CheckCallable(Variable* var, Expression* error, int pos) { 4626 const int nopos = kNoSourcePosition; 4627 Statement* validate_var; 4628 { 4629 Expression* type_of = factory()->NewUnaryOperation( 4630 Token::TYPEOF, factory()->NewVariableProxy(var), nopos); 4631 Expression* function_literal = factory()->NewStringLiteral( 4632 ast_value_factory()->function_string(), nopos); 4633 Expression* condition = factory()->NewCompareOperation( 4634 Token::EQ_STRICT, type_of, function_literal, nopos); 4635 4636 Statement* throw_call = factory()->NewExpressionStatement(error, pos); 4637 4638 validate_var = factory()->NewIfStatement( 4639 condition, factory()->NewEmptyStatement(nopos), throw_call, nopos); 4640 } 4641 return validate_var; 4642 } 4643 4644 void Parser::BuildIteratorClose(ZoneList<Statement*>* statements, 4645 Variable* iterator, Variable* input, 4646 Variable* var_output) { 4647 // 4648 // This function adds four statements to [statements], corresponding to the 4649 // following code: 4650 // 4651 // let iteratorReturn = iterator.return; 4652 // if (IS_NULL_OR_UNDEFINED(iteratorReturn) { 4653 // return {value: input, done: true}; 4654 // } 4655 // output = %_Call(iteratorReturn, iterator, input); 4656 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output); 4657 // 4658 4659 const int nopos = kNoSourcePosition; 4660 4661 // let iteratorReturn = iterator.return; 4662 Variable* var_return = var_output; // Reusing the output variable. 4663 Statement* get_return; 4664 { 4665 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); 4666 Expression* literal = factory()->NewStringLiteral( 4667 ast_value_factory()->return_string(), nopos); 4668 Expression* property = 4669 factory()->NewProperty(iterator_proxy, literal, nopos); 4670 Expression* return_proxy = factory()->NewVariableProxy(var_return); 4671 Expression* assignment = 4672 factory()->NewAssignment(Token::ASSIGN, return_proxy, property, nopos); 4673 get_return = factory()->NewExpressionStatement(assignment, nopos); 4674 } 4675 4676 // if (IS_NULL_OR_UNDEFINED(iteratorReturn) { 4677 // return {value: input, done: true}; 4678 // } 4679 Statement* check_return; 4680 { 4681 Expression* condition = factory()->NewCompareOperation( 4682 Token::EQ, factory()->NewVariableProxy(var_return), 4683 factory()->NewNullLiteral(nopos), nopos); 4684 4685 Expression* value = factory()->NewVariableProxy(input); 4686 4687 Statement* return_input = 4688 factory()->NewReturnStatement(BuildIteratorResult(value, true), nopos); 4689 4690 check_return = factory()->NewIfStatement( 4691 condition, return_input, factory()->NewEmptyStatement(nopos), nopos); 4692 } 4693 4694 // output = %_Call(iteratorReturn, iterator, input); 4695 Statement* call_return; 4696 { 4697 auto args = new (zone()) ZoneList<Expression*>(3, zone()); 4698 args->Add(factory()->NewVariableProxy(var_return), zone()); 4699 args->Add(factory()->NewVariableProxy(iterator), zone()); 4700 args->Add(factory()->NewVariableProxy(input), zone()); 4701 4702 Expression* call = 4703 factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos); 4704 Expression* output_proxy = factory()->NewVariableProxy(var_output); 4705 Expression* assignment = 4706 factory()->NewAssignment(Token::ASSIGN, output_proxy, call, nopos); 4707 call_return = factory()->NewExpressionStatement(assignment, nopos); 4708 } 4709 4710 // if (!IS_RECEIVER(output)) %ThrowIteratorResultNotAnObject(output); 4711 Statement* validate_output; 4712 { 4713 Expression* is_receiver_call; 4714 { 4715 auto args = new (zone()) ZoneList<Expression*>(1, zone()); 4716 args->Add(factory()->NewVariableProxy(var_output), zone()); 4717 is_receiver_call = 4718 factory()->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos); 4719 } 4720 4721 Statement* throw_call; 4722 { 4723 auto args = new (zone()) ZoneList<Expression*>(1, zone()); 4724 args->Add(factory()->NewVariableProxy(var_output), zone()); 4725 Expression* call = factory()->NewCallRuntime( 4726 Runtime::kThrowIteratorResultNotAnObject, args, nopos); 4727 throw_call = factory()->NewExpressionStatement(call, nopos); 4728 } 4729 4730 validate_output = factory()->NewIfStatement( 4731 is_receiver_call, factory()->NewEmptyStatement(nopos), throw_call, 4732 nopos); 4733 } 4734 4735 statements->Add(get_return, zone()); 4736 statements->Add(check_return, zone()); 4737 statements->Add(call_return, zone()); 4738 statements->Add(validate_output, zone()); 4739 } 4740 4741 void Parser::FinalizeIteratorUse(Scope* use_scope, Variable* completion, 4742 Expression* condition, Variable* iter, 4743 Block* iterator_use, Block* target, 4744 IteratorType type) { 4745 // 4746 // This function adds two statements to [target], corresponding to the 4747 // following code: 4748 // 4749 // completion = kNormalCompletion; 4750 // try { 4751 // try { 4752 // iterator_use 4753 // } catch(e) { 4754 // if (completion === kAbruptCompletion) completion = kThrowCompletion; 4755 // %ReThrow(e); 4756 // } 4757 // } finally { 4758 // if (condition) { 4759 // #BuildIteratorCloseForCompletion(iter, completion) 4760 // } 4761 // } 4762 // 4763 4764 const int nopos = kNoSourcePosition; 4765 4766 // completion = kNormalCompletion; 4767 Statement* initialize_completion; 4768 { 4769 Expression* proxy = factory()->NewVariableProxy(completion); 4770 Expression* assignment = factory()->NewAssignment( 4771 Token::ASSIGN, proxy, 4772 factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos); 4773 initialize_completion = 4774 factory()->NewExpressionStatement(assignment, nopos); 4775 } 4776 4777 // if (completion === kAbruptCompletion) completion = kThrowCompletion; 4778 Statement* set_completion_throw; 4779 { 4780 Expression* condition = factory()->NewCompareOperation( 4781 Token::EQ_STRICT, factory()->NewVariableProxy(completion), 4782 factory()->NewSmiLiteral(Parser::kAbruptCompletion, nopos), nopos); 4783 4784 Expression* proxy = factory()->NewVariableProxy(completion); 4785 Expression* assignment = factory()->NewAssignment( 4786 Token::ASSIGN, proxy, 4787 factory()->NewSmiLiteral(Parser::kThrowCompletion, nopos), nopos); 4788 Statement* statement = factory()->NewExpressionStatement(assignment, nopos); 4789 set_completion_throw = factory()->NewIfStatement( 4790 condition, statement, factory()->NewEmptyStatement(nopos), nopos); 4791 } 4792 4793 // if (condition) { 4794 // #BuildIteratorCloseForCompletion(iter, completion) 4795 // } 4796 Block* maybe_close; 4797 { 4798 Block* block = factory()->NewBlock(nullptr, 2, true, nopos); 4799 Expression* proxy = factory()->NewVariableProxy(completion); 4800 BuildIteratorCloseForCompletion(use_scope, block->statements(), iter, proxy, 4801 type); 4802 DCHECK(block->statements()->length() == 2); 4803 4804 maybe_close = factory()->NewBlock(nullptr, 1, true, nopos); 4805 maybe_close->statements()->Add( 4806 factory()->NewIfStatement(condition, block, 4807 factory()->NewEmptyStatement(nopos), nopos), 4808 zone()); 4809 } 4810 4811 // try { #try_block } 4812 // catch(e) { 4813 // #set_completion_throw; 4814 // %ReThrow(e); 4815 // } 4816 Statement* try_catch; 4817 { 4818 Scope* catch_scope = NewScopeWithParent(use_scope, CATCH_SCOPE); 4819 Variable* catch_variable = 4820 catch_scope->DeclareLocal(ast_value_factory()->dot_catch_string(), VAR); 4821 catch_scope->set_is_hidden(); 4822 4823 Statement* rethrow; 4824 // We use %ReThrow rather than the ordinary throw because we want to 4825 // preserve the original exception message. This is also why we create a 4826 // TryCatchStatementForReThrow below (which does not clear the pending 4827 // message), rather than a TryCatchStatement. 4828 { 4829 auto args = new (zone()) ZoneList<Expression*>(1, zone()); 4830 args->Add(factory()->NewVariableProxy(catch_variable), zone()); 4831 rethrow = factory()->NewExpressionStatement( 4832 factory()->NewCallRuntime(Runtime::kReThrow, args, nopos), nopos); 4833 } 4834 4835 Block* catch_block = factory()->NewBlock(nullptr, 2, false, nopos); 4836 catch_block->statements()->Add(set_completion_throw, zone()); 4837 catch_block->statements()->Add(rethrow, zone()); 4838 4839 try_catch = factory()->NewTryCatchStatementForReThrow( 4840 iterator_use, catch_scope, catch_variable, catch_block, nopos); 4841 } 4842 4843 // try { #try_catch } finally { #maybe_close } 4844 Statement* try_finally; 4845 { 4846 Block* try_block = factory()->NewBlock(nullptr, 1, false, nopos); 4847 try_block->statements()->Add(try_catch, zone()); 4848 4849 try_finally = 4850 factory()->NewTryFinallyStatement(try_block, maybe_close, nopos); 4851 } 4852 4853 target->statements()->Add(initialize_completion, zone()); 4854 target->statements()->Add(try_finally, zone()); 4855 } 4856 4857 void Parser::BuildIteratorCloseForCompletion(Scope* scope, 4858 ZoneList<Statement*>* statements, 4859 Variable* iterator, 4860 Expression* completion, 4861 IteratorType type) { 4862 // 4863 // This function adds two statements to [statements], corresponding to the 4864 // following code: 4865 // 4866 // let iteratorReturn = iterator.return; 4867 // if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) { 4868 // if (completion === kThrowCompletion) { 4869 // if (!IS_CALLABLE(iteratorReturn)) { 4870 // throw MakeTypeError(kReturnMethodNotCallable); 4871 // } 4872 // [if (IteratorType == kAsync)] 4873 // try { Await(%_Call(iteratorReturn, iterator) } catch (_) { } 4874 // [else] 4875 // try { %_Call(iteratorReturn, iterator) } catch (_) { } 4876 // [endif] 4877 // } else { 4878 // [if (IteratorType == kAsync)] 4879 // let output = Await(%_Call(iteratorReturn, iterator)); 4880 // [else] 4881 // let output = %_Call(iteratorReturn, iterator); 4882 // [endif] 4883 // if (!IS_RECEIVER(output)) { 4884 // %ThrowIterResultNotAnObject(output); 4885 // } 4886 // } 4887 // } 4888 // 4889 4890 const int nopos = kNoSourcePosition; 4891 // let iteratorReturn = iterator.return; 4892 Variable* var_return = NewTemporary(ast_value_factory()->empty_string()); 4893 Statement* get_return; 4894 { 4895 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); 4896 Expression* literal = factory()->NewStringLiteral( 4897 ast_value_factory()->return_string(), nopos); 4898 Expression* property = 4899 factory()->NewProperty(iterator_proxy, literal, nopos); 4900 Expression* return_proxy = factory()->NewVariableProxy(var_return); 4901 Expression* assignment = 4902 factory()->NewAssignment(Token::ASSIGN, return_proxy, property, nopos); 4903 get_return = factory()->NewExpressionStatement(assignment, nopos); 4904 } 4905 4906 // if (!IS_CALLABLE(iteratorReturn)) { 4907 // throw MakeTypeError(kReturnMethodNotCallable); 4908 // } 4909 Statement* check_return_callable; 4910 { 4911 Expression* throw_expr = 4912 NewThrowTypeError(MessageTemplate::kReturnMethodNotCallable, 4913 ast_value_factory()->empty_string(), nopos); 4914 check_return_callable = CheckCallable(var_return, throw_expr, nopos); 4915 } 4916 4917 // try { %_Call(iteratorReturn, iterator) } catch (_) { } 4918 Statement* try_call_return; 4919 { 4920 auto args = new (zone()) ZoneList<Expression*>(2, zone()); 4921 args->Add(factory()->NewVariableProxy(var_return), zone()); 4922 args->Add(factory()->NewVariableProxy(iterator), zone()); 4923 4924 Expression* call = 4925 factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos); 4926 4927 if (type == IteratorType::kAsync) { 4928 call = RewriteAwaitExpression(call, nopos); 4929 } 4930 4931 Block* try_block = factory()->NewBlock(nullptr, 1, false, nopos); 4932 try_block->statements()->Add(factory()->NewExpressionStatement(call, nopos), 4933 zone()); 4934 4935 Block* catch_block = factory()->NewBlock(nullptr, 0, false, nopos); 4936 4937 Scope* catch_scope = NewScopeWithParent(scope, CATCH_SCOPE); 4938 Variable* catch_variable = 4939 catch_scope->DeclareLocal(ast_value_factory()->dot_catch_string(), VAR); 4940 catch_scope->set_is_hidden(); 4941 4942 try_call_return = factory()->NewTryCatchStatement( 4943 try_block, catch_scope, catch_variable, catch_block, nopos); 4944 } 4945 4946 // let output = %_Call(iteratorReturn, iterator); 4947 // if (!IS_RECEIVER(output)) { 4948 // %ThrowIteratorResultNotAnObject(output); 4949 // } 4950 Block* validate_return; 4951 { 4952 Variable* var_output = NewTemporary(ast_value_factory()->empty_string()); 4953 Statement* call_return; 4954 { 4955 auto args = new (zone()) ZoneList<Expression*>(2, zone()); 4956 args->Add(factory()->NewVariableProxy(var_return), zone()); 4957 args->Add(factory()->NewVariableProxy(iterator), zone()); 4958 Expression* call = 4959 factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos); 4960 if (type == IteratorType::kAsync) { 4961 call = RewriteAwaitExpression(call, nopos); 4962 } 4963 4964 Expression* output_proxy = factory()->NewVariableProxy(var_output); 4965 Expression* assignment = 4966 factory()->NewAssignment(Token::ASSIGN, output_proxy, call, nopos); 4967 call_return = factory()->NewExpressionStatement(assignment, nopos); 4968 } 4969 4970 Expression* is_receiver_call; 4971 { 4972 auto args = new (zone()) ZoneList<Expression*>(1, zone()); 4973 args->Add(factory()->NewVariableProxy(var_output), zone()); 4974 is_receiver_call = 4975 factory()->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos); 4976 } 4977 4978 Statement* throw_call; 4979 { 4980 auto args = new (zone()) ZoneList<Expression*>(1, zone()); 4981 args->Add(factory()->NewVariableProxy(var_output), zone()); 4982 Expression* call = factory()->NewCallRuntime( 4983 Runtime::kThrowIteratorResultNotAnObject, args, nopos); 4984 throw_call = factory()->NewExpressionStatement(call, nopos); 4985 } 4986 4987 Statement* check_return = factory()->NewIfStatement( 4988 is_receiver_call, factory()->NewEmptyStatement(nopos), throw_call, 4989 nopos); 4990 4991 validate_return = factory()->NewBlock(nullptr, 2, false, nopos); 4992 validate_return->statements()->Add(call_return, zone()); 4993 validate_return->statements()->Add(check_return, zone()); 4994 } 4995 4996 // if (completion === kThrowCompletion) { 4997 // #check_return_callable; 4998 // #try_call_return; 4999 // } else { 5000 // #validate_return; 5001 // } 5002 Statement* call_return_carefully; 5003 { 5004 Expression* condition = factory()->NewCompareOperation( 5005 Token::EQ_STRICT, completion, 5006 factory()->NewSmiLiteral(Parser::kThrowCompletion, nopos), nopos); 5007 5008 Block* then_block = factory()->NewBlock(nullptr, 2, false, nopos); 5009 then_block->statements()->Add(check_return_callable, zone()); 5010 then_block->statements()->Add(try_call_return, zone()); 5011 5012 call_return_carefully = factory()->NewIfStatement(condition, then_block, 5013 validate_return, nopos); 5014 } 5015 5016 // if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) { ... } 5017 Statement* maybe_call_return; 5018 { 5019 Expression* condition = factory()->NewCompareOperation( 5020 Token::EQ, factory()->NewVariableProxy(var_return), 5021 factory()->NewNullLiteral(nopos), nopos); 5022 5023 maybe_call_return = factory()->NewIfStatement( 5024 condition, factory()->NewEmptyStatement(nopos), call_return_carefully, 5025 nopos); 5026 } 5027 5028 statements->Add(get_return, zone()); 5029 statements->Add(maybe_call_return, zone()); 5030 } 5031 5032 Statement* Parser::FinalizeForOfStatement(ForOfStatement* loop, 5033 Variable* var_completion, 5034 IteratorType type, int pos) { 5035 // 5036 // This function replaces the loop with the following wrapping: 5037 // 5038 // completion = kNormalCompletion; 5039 // try { 5040 // try { 5041 // #loop; 5042 // } catch(e) { 5043 // if (completion === kAbruptCompletion) completion = kThrowCompletion; 5044 // %ReThrow(e); 5045 // } 5046 // } finally { 5047 // if (!(completion === kNormalCompletion)) { 5048 // #BuildIteratorCloseForCompletion(#iterator, completion) 5049 // } 5050 // } 5051 // 5052 // Note that the loop's body and its assign_each already contain appropriate 5053 // assignments to completion (see InitializeForOfStatement). 5054 // 5055 5056 const int nopos = kNoSourcePosition; 5057 5058 // !(completion === kNormalCompletion) 5059 Expression* closing_condition; 5060 { 5061 Expression* cmp = factory()->NewCompareOperation( 5062 Token::EQ_STRICT, factory()->NewVariableProxy(var_completion), 5063 factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos); 5064 closing_condition = factory()->NewUnaryOperation(Token::NOT, cmp, nopos); 5065 } 5066 5067 Block* final_loop = factory()->NewBlock(nullptr, 2, false, nopos); 5068 { 5069 Block* try_block = factory()->NewBlock(nullptr, 1, false, nopos); 5070 try_block->statements()->Add(loop, zone()); 5071 5072 // The scope in which the parser creates this loop. 5073 Scope* loop_scope = scope()->outer_scope(); 5074 DCHECK_EQ(loop_scope->scope_type(), BLOCK_SCOPE); 5075 DCHECK_EQ(scope()->scope_type(), BLOCK_SCOPE); 5076 5077 FinalizeIteratorUse(loop_scope, var_completion, closing_condition, 5078 loop->iterator(), try_block, final_loop, type); 5079 } 5080 5081 return final_loop; 5082 } 5083 5084 #undef CHECK_OK 5085 #undef CHECK_OK_VOID 5086 #undef CHECK_FAILED 5087 5088 } // namespace internal 5089 } // namespace v8 5090