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