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 "src/api.h" 8 #include "src/ast/ast.h" 9 #include "src/ast/ast-expression-rewriter.h" 10 #include "src/ast/ast-expression-visitor.h" 11 #include "src/ast/ast-literal-reindexer.h" 12 #include "src/ast/scopeinfo.h" 13 #include "src/bailout-reason.h" 14 #include "src/base/platform/platform.h" 15 #include "src/bootstrapper.h" 16 #include "src/char-predicates-inl.h" 17 #include "src/codegen.h" 18 #include "src/compiler.h" 19 #include "src/messages.h" 20 #include "src/parsing/parameter-initializer-rewriter.h" 21 #include "src/parsing/parser-base.h" 22 #include "src/parsing/rewriter.h" 23 #include "src/parsing/scanner-character-streams.h" 24 #include "src/runtime/runtime.h" 25 #include "src/string-stream.h" 26 #include "src/tracing/trace-event.h" 27 28 namespace v8 { 29 namespace internal { 30 31 ScriptData::ScriptData(const byte* data, int length) 32 : owns_data_(false), rejected_(false), data_(data), length_(length) { 33 if (!IsAligned(reinterpret_cast<intptr_t>(data), kPointerAlignment)) { 34 byte* copy = NewArray<byte>(length); 35 DCHECK(IsAligned(reinterpret_cast<intptr_t>(copy), kPointerAlignment)); 36 CopyBytes(copy, data, length); 37 data_ = copy; 38 AcquireDataOwnership(); 39 } 40 } 41 42 ParseInfo::ParseInfo(Zone* zone) 43 : zone_(zone), 44 flags_(0), 45 source_stream_(nullptr), 46 source_stream_encoding_(ScriptCompiler::StreamedSource::ONE_BYTE), 47 extension_(nullptr), 48 compile_options_(ScriptCompiler::kNoCompileOptions), 49 script_scope_(nullptr), 50 unicode_cache_(nullptr), 51 stack_limit_(0), 52 hash_seed_(0), 53 isolate_(nullptr), 54 cached_data_(nullptr), 55 ast_value_factory_(nullptr), 56 literal_(nullptr), 57 scope_(nullptr) {} 58 59 ParseInfo::ParseInfo(Zone* zone, Handle<JSFunction> function) 60 : ParseInfo(zone, Handle<SharedFunctionInfo>(function->shared())) { 61 set_context(Handle<Context>(function->context())); 62 } 63 64 65 ParseInfo::ParseInfo(Zone* zone, Handle<SharedFunctionInfo> shared) 66 : ParseInfo(zone) { 67 isolate_ = shared->GetIsolate(); 68 69 set_lazy(); 70 set_hash_seed(isolate_->heap()->HashSeed()); 71 set_stack_limit(isolate_->stack_guard()->real_climit()); 72 set_unicode_cache(isolate_->unicode_cache()); 73 set_language_mode(shared->language_mode()); 74 set_shared_info(shared); 75 76 Handle<Script> script(Script::cast(shared->script())); 77 set_script(script); 78 if (!script.is_null() && script->type() == Script::TYPE_NATIVE) { 79 set_native(); 80 } 81 } 82 83 84 ParseInfo::ParseInfo(Zone* zone, Handle<Script> script) : ParseInfo(zone) { 85 isolate_ = script->GetIsolate(); 86 87 set_hash_seed(isolate_->heap()->HashSeed()); 88 set_stack_limit(isolate_->stack_guard()->real_climit()); 89 set_unicode_cache(isolate_->unicode_cache()); 90 set_script(script); 91 92 if (script->type() == Script::TYPE_NATIVE) { 93 set_native(); 94 } 95 } 96 97 98 FunctionEntry ParseData::GetFunctionEntry(int start) { 99 // The current pre-data entry must be a FunctionEntry with the given 100 // start position. 101 if ((function_index_ + FunctionEntry::kSize <= Length()) && 102 (static_cast<int>(Data()[function_index_]) == start)) { 103 int index = function_index_; 104 function_index_ += FunctionEntry::kSize; 105 Vector<unsigned> subvector(&(Data()[index]), FunctionEntry::kSize); 106 return FunctionEntry(subvector); 107 } 108 return FunctionEntry(); 109 } 110 111 112 int ParseData::FunctionCount() { 113 int functions_size = FunctionsSize(); 114 if (functions_size < 0) return 0; 115 if (functions_size % FunctionEntry::kSize != 0) return 0; 116 return functions_size / FunctionEntry::kSize; 117 } 118 119 120 bool ParseData::IsSane() { 121 if (!IsAligned(script_data_->length(), sizeof(unsigned))) return false; 122 // Check that the header data is valid and doesn't specify 123 // point to positions outside the store. 124 int data_length = Length(); 125 if (data_length < PreparseDataConstants::kHeaderSize) return false; 126 if (Magic() != PreparseDataConstants::kMagicNumber) return false; 127 if (Version() != PreparseDataConstants::kCurrentVersion) return false; 128 if (HasError()) return false; 129 // Check that the space allocated for function entries is sane. 130 int functions_size = FunctionsSize(); 131 if (functions_size < 0) return false; 132 if (functions_size % FunctionEntry::kSize != 0) return false; 133 // Check that the total size has room for header and function entries. 134 int minimum_size = 135 PreparseDataConstants::kHeaderSize + functions_size; 136 if (data_length < minimum_size) return false; 137 return true; 138 } 139 140 141 void ParseData::Initialize() { 142 // Prepares state for use. 143 int data_length = Length(); 144 if (data_length >= PreparseDataConstants::kHeaderSize) { 145 function_index_ = PreparseDataConstants::kHeaderSize; 146 } 147 } 148 149 150 bool ParseData::HasError() { 151 return Data()[PreparseDataConstants::kHasErrorOffset]; 152 } 153 154 155 unsigned ParseData::Magic() { 156 return Data()[PreparseDataConstants::kMagicOffset]; 157 } 158 159 160 unsigned ParseData::Version() { 161 return Data()[PreparseDataConstants::kVersionOffset]; 162 } 163 164 165 int ParseData::FunctionsSize() { 166 return static_cast<int>(Data()[PreparseDataConstants::kFunctionsSizeOffset]); 167 } 168 169 170 void Parser::SetCachedData(ParseInfo* info) { 171 if (compile_options_ == ScriptCompiler::kNoCompileOptions) { 172 cached_parse_data_ = NULL; 173 } else { 174 DCHECK(info->cached_data() != NULL); 175 if (compile_options_ == ScriptCompiler::kConsumeParserCache) { 176 cached_parse_data_ = ParseData::FromCachedData(*info->cached_data()); 177 } 178 } 179 } 180 181 FunctionLiteral* Parser::DefaultConstructor(const AstRawString* name, 182 bool call_super, Scope* scope, 183 int pos, int end_pos, 184 LanguageMode language_mode) { 185 int materialized_literal_count = -1; 186 int expected_property_count = -1; 187 int parameter_count = 0; 188 if (name == nullptr) name = ast_value_factory()->empty_string(); 189 190 FunctionKind kind = call_super ? FunctionKind::kDefaultSubclassConstructor 191 : FunctionKind::kDefaultBaseConstructor; 192 Scope* function_scope = NewScope(scope, FUNCTION_SCOPE, kind); 193 SetLanguageMode(function_scope, 194 static_cast<LanguageMode>(language_mode | STRICT)); 195 // Set start and end position to the same value 196 function_scope->set_start_position(pos); 197 function_scope->set_end_position(pos); 198 ZoneList<Statement*>* body = NULL; 199 200 { 201 AstNodeFactory function_factory(ast_value_factory()); 202 FunctionState function_state(&function_state_, &scope_, function_scope, 203 kind, &function_factory); 204 205 body = new (zone()) ZoneList<Statement*>(call_super ? 2 : 1, zone()); 206 if (call_super) { 207 // $super_constructor = %_GetSuperConstructor(<this-function>) 208 // %reflect_construct( 209 // $super_constructor, InternalArray(...args), new.target) 210 auto constructor_args_name = ast_value_factory()->empty_string(); 211 bool is_duplicate; 212 bool is_rest = true; 213 bool is_optional = false; 214 Variable* constructor_args = 215 function_scope->DeclareParameter(constructor_args_name, TEMPORARY, 216 is_optional, is_rest, &is_duplicate); 217 218 ZoneList<Expression*>* args = 219 new (zone()) ZoneList<Expression*>(2, zone()); 220 VariableProxy* this_function_proxy = scope_->NewUnresolved( 221 factory(), ast_value_factory()->this_function_string(), 222 Variable::NORMAL, pos); 223 ZoneList<Expression*>* tmp = 224 new (zone()) ZoneList<Expression*>(1, zone()); 225 tmp->Add(this_function_proxy, zone()); 226 Expression* super_constructor = factory()->NewCallRuntime( 227 Runtime::kInlineGetSuperConstructor, tmp, pos); 228 args->Add(super_constructor, zone()); 229 Spread* spread_args = factory()->NewSpread( 230 factory()->NewVariableProxy(constructor_args), pos, pos); 231 ZoneList<Expression*>* spread_args_expr = 232 new (zone()) ZoneList<Expression*>(1, zone()); 233 spread_args_expr->Add(spread_args, zone()); 234 args->AddAll(*PrepareSpreadArguments(spread_args_expr), zone()); 235 VariableProxy* new_target_proxy = scope_->NewUnresolved( 236 factory(), ast_value_factory()->new_target_string(), Variable::NORMAL, 237 pos); 238 args->Add(new_target_proxy, zone()); 239 CallRuntime* call = factory()->NewCallRuntime( 240 Context::REFLECT_CONSTRUCT_INDEX, args, pos); 241 body->Add(factory()->NewReturnStatement(call, pos), zone()); 242 } 243 244 materialized_literal_count = function_state.materialized_literal_count(); 245 expected_property_count = function_state.expected_property_count(); 246 } 247 248 FunctionLiteral* function_literal = factory()->NewFunctionLiteral( 249 name, function_scope, body, materialized_literal_count, 250 expected_property_count, parameter_count, 251 FunctionLiteral::kNoDuplicateParameters, 252 FunctionLiteral::kAnonymousExpression, 253 FunctionLiteral::kShouldLazyCompile, kind, pos); 254 255 return function_literal; 256 } 257 258 259 // ---------------------------------------------------------------------------- 260 // Target is a support class to facilitate manipulation of the 261 // Parser's target_stack_ (the stack of potential 'break' and 262 // 'continue' statement targets). Upon construction, a new target is 263 // added; it is removed upon destruction. 264 265 class Target BASE_EMBEDDED { 266 public: 267 Target(Target** variable, BreakableStatement* statement) 268 : variable_(variable), statement_(statement), previous_(*variable) { 269 *variable = this; 270 } 271 272 ~Target() { 273 *variable_ = previous_; 274 } 275 276 Target* previous() { return previous_; } 277 BreakableStatement* statement() { return statement_; } 278 279 private: 280 Target** variable_; 281 BreakableStatement* statement_; 282 Target* previous_; 283 }; 284 285 286 class TargetScope BASE_EMBEDDED { 287 public: 288 explicit TargetScope(Target** variable) 289 : variable_(variable), previous_(*variable) { 290 *variable = NULL; 291 } 292 293 ~TargetScope() { 294 *variable_ = previous_; 295 } 296 297 private: 298 Target** variable_; 299 Target* previous_; 300 }; 301 302 303 // ---------------------------------------------------------------------------- 304 // The CHECK_OK macro is a convenient macro to enforce error 305 // handling for functions that may fail (by returning !*ok). 306 // 307 // CAUTION: This macro appends extra statements after a call, 308 // thus it must never be used where only a single statement 309 // is correct (e.g. an if statement branch w/o braces)! 310 311 #define CHECK_OK ok); \ 312 if (!*ok) return NULL; \ 313 ((void)0 314 #define DUMMY ) // to make indentation work 315 #undef DUMMY 316 317 #define CHECK_FAILED /**/); \ 318 if (failed_) return NULL; \ 319 ((void)0 320 #define DUMMY ) // to make indentation work 321 #undef DUMMY 322 323 // ---------------------------------------------------------------------------- 324 // Implementation of Parser 325 326 bool ParserTraits::IsEval(const AstRawString* identifier) const { 327 return identifier == parser_->ast_value_factory()->eval_string(); 328 } 329 330 331 bool ParserTraits::IsArguments(const AstRawString* identifier) const { 332 return identifier == parser_->ast_value_factory()->arguments_string(); 333 } 334 335 336 bool ParserTraits::IsEvalOrArguments(const AstRawString* identifier) const { 337 return IsEval(identifier) || IsArguments(identifier); 338 } 339 340 bool ParserTraits::IsUndefined(const AstRawString* identifier) const { 341 return identifier == parser_->ast_value_factory()->undefined_string(); 342 } 343 344 bool ParserTraits::IsAwait(const AstRawString* identifier) const { 345 return identifier == parser_->ast_value_factory()->await_string(); 346 } 347 348 bool ParserTraits::IsPrototype(const AstRawString* identifier) const { 349 return identifier == parser_->ast_value_factory()->prototype_string(); 350 } 351 352 353 bool ParserTraits::IsConstructor(const AstRawString* identifier) const { 354 return identifier == parser_->ast_value_factory()->constructor_string(); 355 } 356 357 358 bool ParserTraits::IsThisProperty(Expression* expression) { 359 DCHECK(expression != NULL); 360 Property* property = expression->AsProperty(); 361 return property != NULL && property->obj()->IsVariableProxy() && 362 property->obj()->AsVariableProxy()->is_this(); 363 } 364 365 366 bool ParserTraits::IsIdentifier(Expression* expression) { 367 VariableProxy* operand = expression->AsVariableProxy(); 368 return operand != NULL && !operand->is_this(); 369 } 370 371 372 void ParserTraits::PushPropertyName(FuncNameInferrer* fni, 373 Expression* expression) { 374 if (expression->IsPropertyName()) { 375 fni->PushLiteralName(expression->AsLiteral()->AsRawPropertyName()); 376 } else { 377 fni->PushLiteralName( 378 parser_->ast_value_factory()->anonymous_function_string()); 379 } 380 } 381 382 383 void ParserTraits::CheckAssigningFunctionLiteralToProperty(Expression* left, 384 Expression* right) { 385 DCHECK(left != NULL); 386 if (left->IsProperty() && right->IsFunctionLiteral()) { 387 right->AsFunctionLiteral()->set_pretenure(); 388 } 389 } 390 391 392 Expression* ParserTraits::MarkExpressionAsAssigned(Expression* expression) { 393 VariableProxy* proxy = 394 expression != NULL ? expression->AsVariableProxy() : NULL; 395 if (proxy != NULL) proxy->set_is_assigned(); 396 return expression; 397 } 398 399 400 bool ParserTraits::ShortcutNumericLiteralBinaryExpression( 401 Expression** x, Expression* y, Token::Value op, int pos, 402 AstNodeFactory* factory) { 403 if ((*x)->AsLiteral() && (*x)->AsLiteral()->raw_value()->IsNumber() && 404 y->AsLiteral() && y->AsLiteral()->raw_value()->IsNumber()) { 405 double x_val = (*x)->AsLiteral()->raw_value()->AsNumber(); 406 double y_val = y->AsLiteral()->raw_value()->AsNumber(); 407 bool x_has_dot = (*x)->AsLiteral()->raw_value()->ContainsDot(); 408 bool y_has_dot = y->AsLiteral()->raw_value()->ContainsDot(); 409 bool has_dot = x_has_dot || y_has_dot; 410 switch (op) { 411 case Token::ADD: 412 *x = factory->NewNumberLiteral(x_val + y_val, pos, has_dot); 413 return true; 414 case Token::SUB: 415 *x = factory->NewNumberLiteral(x_val - y_val, pos, has_dot); 416 return true; 417 case Token::MUL: 418 *x = factory->NewNumberLiteral(x_val * y_val, pos, has_dot); 419 return true; 420 case Token::DIV: 421 *x = factory->NewNumberLiteral(x_val / y_val, pos, has_dot); 422 return true; 423 case Token::BIT_OR: { 424 int value = DoubleToInt32(x_val) | DoubleToInt32(y_val); 425 *x = factory->NewNumberLiteral(value, pos, has_dot); 426 return true; 427 } 428 case Token::BIT_AND: { 429 int value = DoubleToInt32(x_val) & DoubleToInt32(y_val); 430 *x = factory->NewNumberLiteral(value, pos, has_dot); 431 return true; 432 } 433 case Token::BIT_XOR: { 434 int value = DoubleToInt32(x_val) ^ DoubleToInt32(y_val); 435 *x = factory->NewNumberLiteral(value, pos, has_dot); 436 return true; 437 } 438 case Token::SHL: { 439 int value = DoubleToInt32(x_val) << (DoubleToInt32(y_val) & 0x1f); 440 *x = factory->NewNumberLiteral(value, pos, has_dot); 441 return true; 442 } 443 case Token::SHR: { 444 uint32_t shift = DoubleToInt32(y_val) & 0x1f; 445 uint32_t value = DoubleToUint32(x_val) >> shift; 446 *x = factory->NewNumberLiteral(value, pos, has_dot); 447 return true; 448 } 449 case Token::SAR: { 450 uint32_t shift = DoubleToInt32(y_val) & 0x1f; 451 int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift); 452 *x = factory->NewNumberLiteral(value, pos, has_dot); 453 return true; 454 } 455 case Token::EXP: { 456 double value = Pow(x_val, y_val); 457 int int_value = static_cast<int>(value); 458 *x = factory->NewNumberLiteral( 459 int_value == value && value != -0.0 ? int_value : value, pos, 460 has_dot); 461 return true; 462 } 463 default: 464 break; 465 } 466 } 467 return false; 468 } 469 470 471 Expression* ParserTraits::BuildUnaryExpression(Expression* expression, 472 Token::Value op, int pos, 473 AstNodeFactory* factory) { 474 DCHECK(expression != NULL); 475 if (expression->IsLiteral()) { 476 const AstValue* literal = expression->AsLiteral()->raw_value(); 477 if (op == Token::NOT) { 478 // Convert the literal to a boolean condition and negate it. 479 bool condition = literal->BooleanValue(); 480 return factory->NewBooleanLiteral(!condition, pos); 481 } else if (literal->IsNumber()) { 482 // Compute some expressions involving only number literals. 483 double value = literal->AsNumber(); 484 bool has_dot = literal->ContainsDot(); 485 switch (op) { 486 case Token::ADD: 487 return expression; 488 case Token::SUB: 489 return factory->NewNumberLiteral(-value, pos, has_dot); 490 case Token::BIT_NOT: 491 return factory->NewNumberLiteral(~DoubleToInt32(value), pos, has_dot); 492 default: 493 break; 494 } 495 } 496 } 497 // Desugar '+foo' => 'foo*1' 498 if (op == Token::ADD) { 499 return factory->NewBinaryOperation( 500 Token::MUL, expression, factory->NewNumberLiteral(1, pos, true), pos); 501 } 502 // The same idea for '-foo' => 'foo*(-1)'. 503 if (op == Token::SUB) { 504 return factory->NewBinaryOperation( 505 Token::MUL, expression, factory->NewNumberLiteral(-1, pos), pos); 506 } 507 // ...and one more time for '~foo' => 'foo^(~0)'. 508 if (op == Token::BIT_NOT) { 509 return factory->NewBinaryOperation( 510 Token::BIT_XOR, expression, factory->NewNumberLiteral(~0, pos), pos); 511 } 512 return factory->NewUnaryOperation(op, expression, pos); 513 } 514 515 Expression* ParserTraits::BuildIteratorResult(Expression* value, bool done) { 516 int pos = RelocInfo::kNoPosition; 517 AstNodeFactory* factory = parser_->factory(); 518 Zone* zone = parser_->zone(); 519 520 if (value == nullptr) value = factory->NewUndefinedLiteral(pos); 521 522 auto args = new (zone) ZoneList<Expression*>(2, zone); 523 args->Add(value, zone); 524 args->Add(factory->NewBooleanLiteral(done, pos), zone); 525 526 return factory->NewCallRuntime(Runtime::kInlineCreateIterResultObject, args, 527 pos); 528 } 529 530 Expression* ParserTraits::NewThrowReferenceError( 531 MessageTemplate::Template message, int pos) { 532 return NewThrowError(Runtime::kNewReferenceError, message, 533 parser_->ast_value_factory()->empty_string(), pos); 534 } 535 536 537 Expression* ParserTraits::NewThrowSyntaxError(MessageTemplate::Template message, 538 const AstRawString* arg, 539 int pos) { 540 return NewThrowError(Runtime::kNewSyntaxError, message, arg, pos); 541 } 542 543 544 Expression* ParserTraits::NewThrowTypeError(MessageTemplate::Template message, 545 const AstRawString* arg, int pos) { 546 return NewThrowError(Runtime::kNewTypeError, message, arg, pos); 547 } 548 549 550 Expression* ParserTraits::NewThrowError(Runtime::FunctionId id, 551 MessageTemplate::Template message, 552 const AstRawString* arg, int pos) { 553 Zone* zone = parser_->zone(); 554 ZoneList<Expression*>* args = new (zone) ZoneList<Expression*>(2, zone); 555 args->Add(parser_->factory()->NewSmiLiteral(message, pos), zone); 556 args->Add(parser_->factory()->NewStringLiteral(arg, pos), zone); 557 CallRuntime* call_constructor = 558 parser_->factory()->NewCallRuntime(id, args, pos); 559 return parser_->factory()->NewThrow(call_constructor, pos); 560 } 561 562 563 void ParserTraits::ReportMessageAt(Scanner::Location source_location, 564 MessageTemplate::Template message, 565 const char* arg, ParseErrorType error_type) { 566 if (parser_->stack_overflow()) { 567 // Suppress the error message (syntax error or such) in the presence of a 568 // stack overflow. The isolate allows only one pending exception at at time 569 // and we want to report the stack overflow later. 570 return; 571 } 572 parser_->pending_error_handler_.ReportMessageAt(source_location.beg_pos, 573 source_location.end_pos, 574 message, arg, error_type); 575 } 576 577 578 void ParserTraits::ReportMessage(MessageTemplate::Template message, 579 const char* arg, ParseErrorType error_type) { 580 Scanner::Location source_location = parser_->scanner()->location(); 581 ReportMessageAt(source_location, message, arg, error_type); 582 } 583 584 585 void ParserTraits::ReportMessage(MessageTemplate::Template message, 586 const AstRawString* arg, 587 ParseErrorType error_type) { 588 Scanner::Location source_location = parser_->scanner()->location(); 589 ReportMessageAt(source_location, message, arg, error_type); 590 } 591 592 593 void ParserTraits::ReportMessageAt(Scanner::Location source_location, 594 MessageTemplate::Template message, 595 const AstRawString* arg, 596 ParseErrorType error_type) { 597 if (parser_->stack_overflow()) { 598 // Suppress the error message (syntax error or such) in the presence of a 599 // stack overflow. The isolate allows only one pending exception at at time 600 // and we want to report the stack overflow later. 601 return; 602 } 603 parser_->pending_error_handler_.ReportMessageAt(source_location.beg_pos, 604 source_location.end_pos, 605 message, arg, error_type); 606 } 607 608 609 const AstRawString* ParserTraits::GetSymbol(Scanner* scanner) { 610 const AstRawString* result = 611 parser_->scanner()->CurrentSymbol(parser_->ast_value_factory()); 612 DCHECK(result != NULL); 613 return result; 614 } 615 616 617 const AstRawString* ParserTraits::GetNumberAsSymbol(Scanner* scanner) { 618 double double_value = parser_->scanner()->DoubleValue(); 619 char array[100]; 620 const char* string = DoubleToCString(double_value, ArrayVector(array)); 621 return parser_->ast_value_factory()->GetOneByteString(string); 622 } 623 624 625 const AstRawString* ParserTraits::GetNextSymbol(Scanner* scanner) { 626 return parser_->scanner()->NextSymbol(parser_->ast_value_factory()); 627 } 628 629 630 Expression* ParserTraits::ThisExpression(Scope* scope, AstNodeFactory* factory, 631 int pos) { 632 return scope->NewUnresolved(factory, 633 parser_->ast_value_factory()->this_string(), 634 Variable::THIS, pos, pos + 4); 635 } 636 637 638 Expression* ParserTraits::SuperPropertyReference(Scope* scope, 639 AstNodeFactory* factory, 640 int pos) { 641 // this_function[home_object_symbol] 642 VariableProxy* this_function_proxy = scope->NewUnresolved( 643 factory, parser_->ast_value_factory()->this_function_string(), 644 Variable::NORMAL, pos); 645 Expression* home_object_symbol_literal = 646 factory->NewSymbolLiteral("home_object_symbol", RelocInfo::kNoPosition); 647 Expression* home_object = factory->NewProperty( 648 this_function_proxy, home_object_symbol_literal, pos); 649 return factory->NewSuperPropertyReference( 650 ThisExpression(scope, factory, pos)->AsVariableProxy(), home_object, pos); 651 } 652 653 654 Expression* ParserTraits::SuperCallReference(Scope* scope, 655 AstNodeFactory* factory, int pos) { 656 VariableProxy* new_target_proxy = scope->NewUnresolved( 657 factory, parser_->ast_value_factory()->new_target_string(), 658 Variable::NORMAL, pos); 659 VariableProxy* this_function_proxy = scope->NewUnresolved( 660 factory, parser_->ast_value_factory()->this_function_string(), 661 Variable::NORMAL, pos); 662 return factory->NewSuperCallReference( 663 ThisExpression(scope, factory, pos)->AsVariableProxy(), new_target_proxy, 664 this_function_proxy, pos); 665 } 666 667 668 Expression* ParserTraits::NewTargetExpression(Scope* scope, 669 AstNodeFactory* factory, 670 int pos) { 671 static const int kNewTargetStringLength = 10; 672 auto proxy = scope->NewUnresolved( 673 factory, parser_->ast_value_factory()->new_target_string(), 674 Variable::NORMAL, pos, pos + kNewTargetStringLength); 675 proxy->set_is_new_target(); 676 return proxy; 677 } 678 679 680 Expression* ParserTraits::FunctionSentExpression(Scope* scope, 681 AstNodeFactory* factory, 682 int pos) { 683 // We desugar function.sent into %_GeneratorGetInputOrDebugPos(generator). 684 Zone* zone = parser_->zone(); 685 ZoneList<Expression*>* args = new (zone) ZoneList<Expression*>(1, zone); 686 VariableProxy* generator = factory->NewVariableProxy( 687 parser_->function_state_->generator_object_variable()); 688 args->Add(generator, zone); 689 return factory->NewCallRuntime(Runtime::kInlineGeneratorGetInputOrDebugPos, 690 args, pos); 691 } 692 693 694 Literal* ParserTraits::ExpressionFromLiteral(Token::Value token, int pos, 695 Scanner* scanner, 696 AstNodeFactory* factory) { 697 switch (token) { 698 case Token::NULL_LITERAL: 699 return factory->NewNullLiteral(pos); 700 case Token::TRUE_LITERAL: 701 return factory->NewBooleanLiteral(true, pos); 702 case Token::FALSE_LITERAL: 703 return factory->NewBooleanLiteral(false, pos); 704 case Token::SMI: { 705 int value = scanner->smi_value(); 706 return factory->NewSmiLiteral(value, pos); 707 } 708 case Token::NUMBER: { 709 bool has_dot = scanner->ContainsDot(); 710 double value = scanner->DoubleValue(); 711 return factory->NewNumberLiteral(value, pos, has_dot); 712 } 713 default: 714 DCHECK(false); 715 } 716 return NULL; 717 } 718 719 720 Expression* ParserTraits::ExpressionFromIdentifier(const AstRawString* name, 721 int start_position, 722 int end_position, 723 Scope* scope, 724 AstNodeFactory* factory) { 725 if (parser_->fni_ != NULL) parser_->fni_->PushVariableName(name); 726 return scope->NewUnresolved(factory, name, Variable::NORMAL, start_position, 727 end_position); 728 } 729 730 731 Expression* ParserTraits::ExpressionFromString(int pos, Scanner* scanner, 732 AstNodeFactory* factory) { 733 const AstRawString* symbol = GetSymbol(scanner); 734 if (parser_->fni_ != NULL) parser_->fni_->PushLiteralName(symbol); 735 return factory->NewStringLiteral(symbol, pos); 736 } 737 738 739 Expression* ParserTraits::GetIterator(Expression* iterable, 740 AstNodeFactory* factory, int pos) { 741 Expression* iterator_symbol_literal = 742 factory->NewSymbolLiteral("iterator_symbol", RelocInfo::kNoPosition); 743 Expression* prop = 744 factory->NewProperty(iterable, iterator_symbol_literal, pos); 745 Zone* zone = parser_->zone(); 746 ZoneList<Expression*>* args = new (zone) ZoneList<Expression*>(0, zone); 747 return factory->NewCall(prop, args, pos); 748 } 749 750 751 Literal* ParserTraits::GetLiteralTheHole(int position, 752 AstNodeFactory* factory) { 753 return factory->NewTheHoleLiteral(RelocInfo::kNoPosition); 754 } 755 756 757 Expression* ParserTraits::ParseV8Intrinsic(bool* ok) { 758 return parser_->ParseV8Intrinsic(ok); 759 } 760 761 762 FunctionLiteral* ParserTraits::ParseFunctionLiteral( 763 const AstRawString* name, Scanner::Location function_name_location, 764 FunctionNameValidity function_name_validity, FunctionKind kind, 765 int function_token_position, FunctionLiteral::FunctionType type, 766 LanguageMode language_mode, bool* ok) { 767 return parser_->ParseFunctionLiteral( 768 name, function_name_location, function_name_validity, kind, 769 function_token_position, type, language_mode, ok); 770 } 771 772 ClassLiteral* ParserTraits::ParseClassLiteral( 773 Type::ExpressionClassifier* classifier, const AstRawString* name, 774 Scanner::Location class_name_location, bool name_is_strict_reserved, 775 int pos, bool* ok) { 776 return parser_->ParseClassLiteral(classifier, name, class_name_location, 777 name_is_strict_reserved, pos, ok); 778 } 779 780 void ParserTraits::MarkTailPosition(Expression* expression) { 781 expression->MarkTail(); 782 } 783 784 void ParserTraits::MarkCollectedTailCallExpressions() { 785 parser_->MarkCollectedTailCallExpressions(); 786 } 787 788 Parser::Parser(ParseInfo* info) 789 : ParserBase<ParserTraits>(info->zone(), &scanner_, info->stack_limit(), 790 info->extension(), info->ast_value_factory(), 791 NULL, this), 792 scanner_(info->unicode_cache()), 793 reusable_preparser_(NULL), 794 original_scope_(NULL), 795 target_stack_(NULL), 796 compile_options_(info->compile_options()), 797 cached_parse_data_(NULL), 798 total_preparse_skipped_(0), 799 pre_parse_timer_(NULL), 800 parsing_on_main_thread_(true) { 801 // Even though we were passed ParseInfo, we should not store it in 802 // Parser - this makes sure that Isolate is not accidentally accessed via 803 // ParseInfo during background parsing. 804 DCHECK(!info->script().is_null() || info->source_stream() != NULL); 805 set_allow_lazy(info->allow_lazy_parsing()); 806 set_allow_natives(FLAG_allow_natives_syntax || info->is_native()); 807 set_allow_tailcalls(FLAG_harmony_tailcalls && !info->is_native() && 808 info->isolate()->is_tail_call_elimination_enabled()); 809 set_allow_harmony_do_expressions(FLAG_harmony_do_expressions); 810 set_allow_harmony_for_in(FLAG_harmony_for_in); 811 set_allow_harmony_function_sent(FLAG_harmony_function_sent); 812 set_allow_harmony_restrictive_declarations( 813 FLAG_harmony_restrictive_declarations); 814 set_allow_harmony_exponentiation_operator( 815 FLAG_harmony_exponentiation_operator); 816 set_allow_harmony_async_await(FLAG_harmony_async_await); 817 set_allow_harmony_restrictive_generators(FLAG_harmony_restrictive_generators); 818 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; 819 ++feature) { 820 use_counts_[feature] = 0; 821 } 822 if (info->ast_value_factory() == NULL) { 823 // info takes ownership of AstValueFactory. 824 info->set_ast_value_factory(new AstValueFactory(zone(), info->hash_seed())); 825 info->set_ast_value_factory_owned(); 826 ast_value_factory_ = info->ast_value_factory(); 827 } 828 } 829 830 831 FunctionLiteral* Parser::ParseProgram(Isolate* isolate, ParseInfo* info) { 832 // TODO(bmeurer): We temporarily need to pass allow_nesting = true here, 833 // see comment for HistogramTimerScope class. 834 835 // It's OK to use the Isolate & counters here, since this function is only 836 // called in the main thread. 837 DCHECK(parsing_on_main_thread_); 838 839 HistogramTimerScope timer_scope(isolate->counters()->parse(), true); 840 RuntimeCallTimerScope runtime_timer(isolate, &RuntimeCallStats::Parse); 841 TRACE_EVENT0("v8", "V8.Parse"); 842 Handle<String> source(String::cast(info->script()->source())); 843 isolate->counters()->total_parse_size()->Increment(source->length()); 844 base::ElapsedTimer timer; 845 if (FLAG_trace_parse) { 846 timer.Start(); 847 } 848 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone()); 849 850 // Initialize parser state. 851 CompleteParserRecorder recorder; 852 853 if (produce_cached_parse_data()) { 854 log_ = &recorder; 855 } else if (consume_cached_parse_data()) { 856 cached_parse_data_->Initialize(); 857 } 858 859 source = String::Flatten(source); 860 FunctionLiteral* result; 861 862 if (source->IsExternalTwoByteString()) { 863 // Notice that the stream is destroyed at the end of the branch block. 864 // The last line of the blocks can't be moved outside, even though they're 865 // identical calls. 866 ExternalTwoByteStringUtf16CharacterStream stream( 867 Handle<ExternalTwoByteString>::cast(source), 0, source->length()); 868 scanner_.Initialize(&stream); 869 result = DoParseProgram(info); 870 } else { 871 GenericStringUtf16CharacterStream stream(source, 0, source->length()); 872 scanner_.Initialize(&stream); 873 result = DoParseProgram(info); 874 } 875 if (result != NULL) { 876 DCHECK_EQ(scanner_.peek_location().beg_pos, source->length()); 877 } 878 HandleSourceURLComments(isolate, info->script()); 879 880 if (FLAG_trace_parse && result != NULL) { 881 double ms = timer.Elapsed().InMillisecondsF(); 882 if (info->is_eval()) { 883 PrintF("[parsing eval"); 884 } else if (info->script()->name()->IsString()) { 885 String* name = String::cast(info->script()->name()); 886 base::SmartArrayPointer<char> name_chars = name->ToCString(); 887 PrintF("[parsing script: %s", name_chars.get()); 888 } else { 889 PrintF("[parsing script"); 890 } 891 PrintF(" - took %0.3f ms]\n", ms); 892 } 893 if (produce_cached_parse_data()) { 894 if (result != NULL) *info->cached_data() = recorder.GetScriptData(); 895 log_ = NULL; 896 } 897 return result; 898 } 899 900 901 FunctionLiteral* Parser::DoParseProgram(ParseInfo* info) { 902 // Note that this function can be called from the main thread or from a 903 // background thread. We should not access anything Isolate / heap dependent 904 // via ParseInfo, and also not pass it forward. 905 DCHECK(scope_ == NULL); 906 DCHECK(target_stack_ == NULL); 907 908 Mode parsing_mode = FLAG_lazy && allow_lazy() ? PARSE_LAZILY : PARSE_EAGERLY; 909 if (allow_natives() || extension_ != NULL) parsing_mode = PARSE_EAGERLY; 910 911 FunctionLiteral* result = NULL; 912 { 913 // TODO(wingo): Add an outer SCRIPT_SCOPE corresponding to the native 914 // context, which will have the "this" binding for script scopes. 915 Scope* scope = NewScope(scope_, SCRIPT_SCOPE); 916 info->set_script_scope(scope); 917 if (!info->context().is_null() && !info->context()->IsNativeContext()) { 918 scope = Scope::DeserializeScopeChain(info->isolate(), zone(), 919 *info->context(), scope); 920 // The Scope is backed up by ScopeInfo (which is in the V8 heap); this 921 // means the Parser cannot operate independent of the V8 heap. Tell the 922 // string table to internalize strings and values right after they're 923 // created. This kind of parsing can only be done in the main thread. 924 DCHECK(parsing_on_main_thread_); 925 ast_value_factory()->Internalize(info->isolate()); 926 } 927 original_scope_ = scope; 928 if (info->is_eval()) { 929 if (!scope->is_script_scope() || is_strict(info->language_mode())) { 930 parsing_mode = PARSE_EAGERLY; 931 } 932 scope = NewScope(scope, EVAL_SCOPE); 933 } else if (info->is_module()) { 934 scope = NewScope(scope, MODULE_SCOPE); 935 } 936 937 scope->set_start_position(0); 938 939 // Enter 'scope' with the given parsing mode. 940 ParsingModeScope parsing_mode_scope(this, parsing_mode); 941 AstNodeFactory function_factory(ast_value_factory()); 942 FunctionState function_state(&function_state_, &scope_, scope, 943 kNormalFunction, &function_factory); 944 945 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); 946 bool ok = true; 947 int beg_pos = scanner()->location().beg_pos; 948 parsing_module_ = info->is_module(); 949 if (parsing_module_) { 950 ParseModuleItemList(body, &ok); 951 } else { 952 // Don't count the mode in the use counters--give the program a chance 953 // to enable script-wide strict mode below. 954 scope_->SetLanguageMode(info->language_mode()); 955 ParseStatementList(body, Token::EOS, &ok); 956 } 957 958 // The parser will peek but not consume EOS. Our scope logically goes all 959 // the way to the EOS, though. 960 scope->set_end_position(scanner()->peek_location().beg_pos); 961 962 if (ok && is_strict(language_mode())) { 963 CheckStrictOctalLiteral(beg_pos, scanner()->location().end_pos, &ok); 964 CheckDecimalLiteralWithLeadingZero(use_counts_, beg_pos, 965 scanner()->location().end_pos); 966 } 967 if (ok && is_sloppy(language_mode())) { 968 // TODO(littledan): Function bindings on the global object that modify 969 // pre-existing bindings should be made writable, enumerable and 970 // nonconfigurable if possible, whereas this code will leave attributes 971 // unchanged if the property already exists. 972 InsertSloppyBlockFunctionVarBindings(scope, &ok); 973 } 974 if (ok) { 975 CheckConflictingVarDeclarations(scope_, &ok); 976 } 977 978 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) { 979 if (body->length() != 1 || 980 !body->at(0)->IsExpressionStatement() || 981 !body->at(0)->AsExpressionStatement()-> 982 expression()->IsFunctionLiteral()) { 983 ReportMessage(MessageTemplate::kSingleFunctionLiteral); 984 ok = false; 985 } 986 } 987 988 if (ok) { 989 ParserTraits::RewriteDestructuringAssignments(); 990 result = factory()->NewScriptOrEvalFunctionLiteral( 991 scope_, body, function_state.materialized_literal_count(), 992 function_state.expected_property_count()); 993 } 994 } 995 996 // Make sure the target stack is empty. 997 DCHECK(target_stack_ == NULL); 998 999 return result; 1000 } 1001 1002 1003 FunctionLiteral* Parser::ParseLazy(Isolate* isolate, ParseInfo* info) { 1004 // It's OK to use the Isolate & counters here, since this function is only 1005 // called in the main thread. 1006 DCHECK(parsing_on_main_thread_); 1007 RuntimeCallTimerScope runtime_timer(isolate, &RuntimeCallStats::ParseLazy); 1008 HistogramTimerScope timer_scope(isolate->counters()->parse_lazy()); 1009 TRACE_EVENT0("v8", "V8.ParseLazy"); 1010 Handle<String> source(String::cast(info->script()->source())); 1011 isolate->counters()->total_parse_size()->Increment(source->length()); 1012 base::ElapsedTimer timer; 1013 if (FLAG_trace_parse) { 1014 timer.Start(); 1015 } 1016 Handle<SharedFunctionInfo> shared_info = info->shared_info(); 1017 1018 // Initialize parser state. 1019 source = String::Flatten(source); 1020 FunctionLiteral* result; 1021 if (source->IsExternalTwoByteString()) { 1022 ExternalTwoByteStringUtf16CharacterStream stream( 1023 Handle<ExternalTwoByteString>::cast(source), 1024 shared_info->start_position(), 1025 shared_info->end_position()); 1026 result = ParseLazy(isolate, info, &stream); 1027 } else { 1028 GenericStringUtf16CharacterStream stream(source, 1029 shared_info->start_position(), 1030 shared_info->end_position()); 1031 result = ParseLazy(isolate, info, &stream); 1032 } 1033 1034 if (FLAG_trace_parse && result != NULL) { 1035 double ms = timer.Elapsed().InMillisecondsF(); 1036 base::SmartArrayPointer<char> name_chars = 1037 result->debug_name()->ToCString(); 1038 PrintF("[parsing function: %s - took %0.3f ms]\n", name_chars.get(), ms); 1039 } 1040 return result; 1041 } 1042 1043 static FunctionLiteral::FunctionType ComputeFunctionType( 1044 Handle<SharedFunctionInfo> shared_info) { 1045 if (shared_info->is_declaration()) { 1046 return FunctionLiteral::kDeclaration; 1047 } else if (shared_info->is_named_expression()) { 1048 return FunctionLiteral::kNamedExpression; 1049 } else if (IsConciseMethod(shared_info->kind()) || 1050 IsAccessorFunction(shared_info->kind())) { 1051 return FunctionLiteral::kAccessorOrMethod; 1052 } 1053 return FunctionLiteral::kAnonymousExpression; 1054 } 1055 1056 FunctionLiteral* Parser::ParseLazy(Isolate* isolate, ParseInfo* info, 1057 Utf16CharacterStream* source) { 1058 Handle<SharedFunctionInfo> shared_info = info->shared_info(); 1059 scanner_.Initialize(source); 1060 DCHECK(scope_ == NULL); 1061 DCHECK(target_stack_ == NULL); 1062 1063 Handle<String> name(String::cast(shared_info->name())); 1064 DCHECK(ast_value_factory()); 1065 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone()); 1066 const AstRawString* raw_name = ast_value_factory()->GetString(name); 1067 fni_->PushEnclosingName(raw_name); 1068 1069 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); 1070 1071 // Place holder for the result. 1072 FunctionLiteral* result = NULL; 1073 1074 { 1075 // Parse the function literal. 1076 Scope* scope = NewScope(scope_, SCRIPT_SCOPE); 1077 info->set_script_scope(scope); 1078 if (!info->context().is_null()) { 1079 // Ok to use Isolate here, since lazy function parsing is only done in the 1080 // main thread. 1081 DCHECK(parsing_on_main_thread_); 1082 scope = Scope::DeserializeScopeChain(isolate, zone(), *info->context(), 1083 scope); 1084 } 1085 original_scope_ = scope; 1086 AstNodeFactory function_factory(ast_value_factory()); 1087 FunctionState function_state(&function_state_, &scope_, scope, 1088 shared_info->kind(), &function_factory); 1089 DCHECK(is_sloppy(scope->language_mode()) || 1090 is_strict(info->language_mode())); 1091 DCHECK(info->language_mode() == shared_info->language_mode()); 1092 FunctionLiteral::FunctionType function_type = 1093 ComputeFunctionType(shared_info); 1094 bool ok = true; 1095 1096 if (shared_info->is_arrow()) { 1097 bool is_async = allow_harmony_async_await() && shared_info->is_async(); 1098 if (is_async) { 1099 DCHECK(!scanner()->HasAnyLineTerminatorAfterNext()); 1100 Consume(Token::ASYNC); 1101 DCHECK(peek_any_identifier() || peek() == Token::LPAREN); 1102 } 1103 1104 // TODO(adamk): We should construct this scope from the ScopeInfo. 1105 Scope* scope = 1106 NewScope(scope_, FUNCTION_SCOPE, FunctionKind::kArrowFunction); 1107 1108 // These two bits only need to be explicitly set because we're 1109 // not passing the ScopeInfo to the Scope constructor. 1110 // TODO(adamk): Remove these calls once the above NewScope call 1111 // passes the ScopeInfo. 1112 if (shared_info->scope_info()->CallsEval()) { 1113 scope->RecordEvalCall(); 1114 } 1115 SetLanguageMode(scope, shared_info->language_mode()); 1116 1117 scope->set_start_position(shared_info->start_position()); 1118 ExpressionClassifier formals_classifier(this); 1119 ParserFormalParameters formals(scope); 1120 Checkpoint checkpoint(this); 1121 { 1122 // Parsing patterns as variable reference expression creates 1123 // NewUnresolved references in current scope. Entrer arrow function 1124 // scope for formal parameter parsing. 1125 BlockState block_state(&scope_, scope); 1126 if (Check(Token::LPAREN)) { 1127 // '(' StrictFormalParameters ')' 1128 ParseFormalParameterList(&formals, &formals_classifier, &ok); 1129 if (ok) ok = Check(Token::RPAREN); 1130 } else { 1131 // BindingIdentifier 1132 ParseFormalParameter(&formals, &formals_classifier, &ok); 1133 if (ok) { 1134 DeclareFormalParameter(formals.scope, formals.at(0), 1135 &formals_classifier); 1136 } 1137 } 1138 } 1139 1140 if (ok) { 1141 checkpoint.Restore(&formals.materialized_literals_count); 1142 // Pass `accept_IN=true` to ParseArrowFunctionLiteral --- This should 1143 // not be observable, or else the preparser would have failed. 1144 Expression* expression = ParseArrowFunctionLiteral( 1145 true, formals, is_async, formals_classifier, &ok); 1146 if (ok) { 1147 // Scanning must end at the same position that was recorded 1148 // previously. If not, parsing has been interrupted due to a stack 1149 // overflow, at which point the partially parsed arrow function 1150 // concise body happens to be a valid expression. This is a problem 1151 // only for arrow functions with single expression bodies, since there 1152 // is no end token such as "}" for normal functions. 1153 if (scanner()->location().end_pos == shared_info->end_position()) { 1154 // The pre-parser saw an arrow function here, so the full parser 1155 // must produce a FunctionLiteral. 1156 DCHECK(expression->IsFunctionLiteral()); 1157 result = expression->AsFunctionLiteral(); 1158 } else { 1159 ok = false; 1160 } 1161 } 1162 } 1163 } else if (shared_info->is_default_constructor()) { 1164 result = DefaultConstructor( 1165 raw_name, IsSubclassConstructor(shared_info->kind()), scope, 1166 shared_info->start_position(), shared_info->end_position(), 1167 shared_info->language_mode()); 1168 } else { 1169 result = ParseFunctionLiteral(raw_name, Scanner::Location::invalid(), 1170 kSkipFunctionNameCheck, shared_info->kind(), 1171 RelocInfo::kNoPosition, function_type, 1172 shared_info->language_mode(), &ok); 1173 } 1174 // Make sure the results agree. 1175 DCHECK(ok == (result != NULL)); 1176 } 1177 1178 // Make sure the target stack is empty. 1179 DCHECK(target_stack_ == NULL); 1180 1181 if (result != NULL) { 1182 Handle<String> inferred_name(shared_info->inferred_name()); 1183 result->set_inferred_name(inferred_name); 1184 } 1185 return result; 1186 } 1187 1188 1189 void* Parser::ParseStatementList(ZoneList<Statement*>* body, int end_token, 1190 bool* ok) { 1191 // StatementList :: 1192 // (StatementListItem)* <end_token> 1193 1194 // Allocate a target stack to use for this set of source 1195 // elements. This way, all scripts and functions get their own 1196 // target stack thus avoiding illegal breaks and continues across 1197 // functions. 1198 TargetScope scope(&this->target_stack_); 1199 1200 DCHECK(body != NULL); 1201 bool directive_prologue = true; // Parsing directive prologue. 1202 1203 while (peek() != end_token) { 1204 if (directive_prologue && peek() != Token::STRING) { 1205 directive_prologue = false; 1206 } 1207 1208 Scanner::Location token_loc = scanner()->peek_location(); 1209 Statement* stat = ParseStatementListItem(CHECK_OK); 1210 if (stat == NULL || stat->IsEmpty()) { 1211 directive_prologue = false; // End of directive prologue. 1212 continue; 1213 } 1214 1215 if (directive_prologue) { 1216 // A shot at a directive. 1217 ExpressionStatement* e_stat; 1218 Literal* literal; 1219 // Still processing directive prologue? 1220 if ((e_stat = stat->AsExpressionStatement()) != NULL && 1221 (literal = e_stat->expression()->AsLiteral()) != NULL && 1222 literal->raw_value()->IsString()) { 1223 // Check "use strict" directive (ES5 14.1), "use asm" directive. 1224 bool use_strict_found = 1225 literal->raw_value()->AsString() == 1226 ast_value_factory()->use_strict_string() && 1227 token_loc.end_pos - token_loc.beg_pos == 1228 ast_value_factory()->use_strict_string()->length() + 2; 1229 if (use_strict_found) { 1230 if (is_sloppy(scope_->language_mode())) { 1231 RaiseLanguageMode(STRICT); 1232 } 1233 1234 if (!scope_->HasSimpleParameters()) { 1235 // TC39 deemed "use strict" directives to be an error when occurring 1236 // in the body of a function with non-simple parameter list, on 1237 // 29/7/2015. https://goo.gl/ueA7Ln 1238 const AstRawString* string = literal->raw_value()->AsString(); 1239 ParserTraits::ReportMessageAt( 1240 token_loc, MessageTemplate::kIllegalLanguageModeDirective, 1241 string); 1242 *ok = false; 1243 return nullptr; 1244 } 1245 // Because declarations in strict eval code don't leak into the scope 1246 // of the eval call, it is likely that functions declared in strict 1247 // eval code will be used within the eval code, so lazy parsing is 1248 // probably not a win. 1249 if (scope_->is_eval_scope()) mode_ = PARSE_EAGERLY; 1250 } else if (literal->raw_value()->AsString() == 1251 ast_value_factory()->use_asm_string() && 1252 token_loc.end_pos - token_loc.beg_pos == 1253 ast_value_factory()->use_asm_string()->length() + 2) { 1254 // Store the usage count; The actual use counter on the isolate is 1255 // incremented after parsing is done. 1256 ++use_counts_[v8::Isolate::kUseAsm]; 1257 scope_->SetAsmModule(); 1258 } else { 1259 // Should not change mode, but will increment UseCounter 1260 // if appropriate. Ditto usages below. 1261 RaiseLanguageMode(SLOPPY); 1262 } 1263 } else { 1264 // End of the directive prologue. 1265 directive_prologue = false; 1266 RaiseLanguageMode(SLOPPY); 1267 } 1268 } else { 1269 RaiseLanguageMode(SLOPPY); 1270 } 1271 1272 body->Add(stat, zone()); 1273 } 1274 1275 return 0; 1276 } 1277 1278 1279 Statement* Parser::ParseStatementListItem(bool* ok) { 1280 // (Ecma 262 6th Edition, 13.1): 1281 // StatementListItem: 1282 // Statement 1283 // Declaration 1284 const Token::Value peeked = peek(); 1285 switch (peeked) { 1286 case Token::FUNCTION: 1287 return ParseHoistableDeclaration(NULL, ok); 1288 case Token::CLASS: 1289 Consume(Token::CLASS); 1290 return ParseClassDeclaration(NULL, ok); 1291 case Token::CONST: 1292 return ParseVariableStatement(kStatementListItem, NULL, ok); 1293 case Token::VAR: 1294 return ParseVariableStatement(kStatementListItem, NULL, ok); 1295 case Token::LET: 1296 if (IsNextLetKeyword()) { 1297 return ParseVariableStatement(kStatementListItem, NULL, ok); 1298 } 1299 break; 1300 case Token::ASYNC: 1301 if (allow_harmony_async_await() && PeekAhead() == Token::FUNCTION && 1302 !scanner()->HasAnyLineTerminatorAfterNext()) { 1303 Consume(Token::ASYNC); 1304 return ParseAsyncFunctionDeclaration(NULL, ok); 1305 } 1306 /* falls through */ 1307 default: 1308 break; 1309 } 1310 return ParseStatement(NULL, kAllowLabelledFunctionStatement, ok); 1311 } 1312 1313 1314 Statement* Parser::ParseModuleItem(bool* ok) { 1315 // (Ecma 262 6th Edition, 15.2): 1316 // ModuleItem : 1317 // ImportDeclaration 1318 // ExportDeclaration 1319 // StatementListItem 1320 1321 switch (peek()) { 1322 case Token::IMPORT: 1323 return ParseImportDeclaration(ok); 1324 case Token::EXPORT: 1325 return ParseExportDeclaration(ok); 1326 default: 1327 return ParseStatementListItem(ok); 1328 } 1329 } 1330 1331 1332 void* Parser::ParseModuleItemList(ZoneList<Statement*>* body, bool* ok) { 1333 // (Ecma 262 6th Edition, 15.2): 1334 // Module : 1335 // ModuleBody? 1336 // 1337 // ModuleBody : 1338 // ModuleItem* 1339 1340 DCHECK(scope_->is_module_scope()); 1341 1342 while (peek() != Token::EOS) { 1343 Statement* stat = ParseModuleItem(CHECK_OK); 1344 if (stat && !stat->IsEmpty()) { 1345 body->Add(stat, zone()); 1346 } 1347 } 1348 1349 // Check that all exports are bound. 1350 ModuleDescriptor* descriptor = scope_->module(); 1351 for (ModuleDescriptor::Iterator it = descriptor->iterator(); !it.done(); 1352 it.Advance()) { 1353 if (scope_->LookupLocal(it.local_name()) == NULL) { 1354 // TODO(adamk): Pass both local_name and export_name once ParserTraits 1355 // supports multiple arg error messages. 1356 // Also try to report this at a better location. 1357 ParserTraits::ReportMessage(MessageTemplate::kModuleExportUndefined, 1358 it.local_name()); 1359 *ok = false; 1360 return NULL; 1361 } 1362 } 1363 1364 return NULL; 1365 } 1366 1367 1368 const AstRawString* Parser::ParseModuleSpecifier(bool* ok) { 1369 // ModuleSpecifier : 1370 // StringLiteral 1371 1372 Expect(Token::STRING, CHECK_OK); 1373 return GetSymbol(scanner()); 1374 } 1375 1376 1377 void* Parser::ParseExportClause(ZoneList<const AstRawString*>* export_names, 1378 ZoneList<Scanner::Location>* export_locations, 1379 ZoneList<const AstRawString*>* local_names, 1380 Scanner::Location* reserved_loc, bool* ok) { 1381 // ExportClause : 1382 // '{' '}' 1383 // '{' ExportsList '}' 1384 // '{' ExportsList ',' '}' 1385 // 1386 // ExportsList : 1387 // ExportSpecifier 1388 // ExportsList ',' ExportSpecifier 1389 // 1390 // ExportSpecifier : 1391 // IdentifierName 1392 // IdentifierName 'as' IdentifierName 1393 1394 Expect(Token::LBRACE, CHECK_OK); 1395 1396 Token::Value name_tok; 1397 while ((name_tok = peek()) != Token::RBRACE) { 1398 // Keep track of the first reserved word encountered in case our 1399 // caller needs to report an error. 1400 if (!reserved_loc->IsValid() && 1401 !Token::IsIdentifier(name_tok, STRICT, false, parsing_module_)) { 1402 *reserved_loc = scanner()->location(); 1403 } 1404 const AstRawString* local_name = ParseIdentifierName(CHECK_OK); 1405 const AstRawString* export_name = NULL; 1406 if (CheckContextualKeyword(CStrVector("as"))) { 1407 export_name = ParseIdentifierName(CHECK_OK); 1408 } 1409 if (export_name == NULL) { 1410 export_name = local_name; 1411 } 1412 export_names->Add(export_name, zone()); 1413 local_names->Add(local_name, zone()); 1414 export_locations->Add(scanner()->location(), zone()); 1415 if (peek() == Token::RBRACE) break; 1416 Expect(Token::COMMA, CHECK_OK); 1417 } 1418 1419 Expect(Token::RBRACE, CHECK_OK); 1420 1421 return 0; 1422 } 1423 1424 1425 ZoneList<ImportDeclaration*>* Parser::ParseNamedImports(int pos, bool* ok) { 1426 // NamedImports : 1427 // '{' '}' 1428 // '{' ImportsList '}' 1429 // '{' ImportsList ',' '}' 1430 // 1431 // ImportsList : 1432 // ImportSpecifier 1433 // ImportsList ',' ImportSpecifier 1434 // 1435 // ImportSpecifier : 1436 // BindingIdentifier 1437 // IdentifierName 'as' BindingIdentifier 1438 1439 Expect(Token::LBRACE, CHECK_OK); 1440 1441 ZoneList<ImportDeclaration*>* result = 1442 new (zone()) ZoneList<ImportDeclaration*>(1, zone()); 1443 while (peek() != Token::RBRACE) { 1444 const AstRawString* import_name = ParseIdentifierName(CHECK_OK); 1445 const AstRawString* local_name = import_name; 1446 // In the presence of 'as', the left-side of the 'as' can 1447 // be any IdentifierName. But without 'as', it must be a valid 1448 // BindingIdentifier. 1449 if (CheckContextualKeyword(CStrVector("as"))) { 1450 local_name = ParseIdentifierName(CHECK_OK); 1451 } 1452 if (!Token::IsIdentifier(scanner()->current_token(), STRICT, false, 1453 parsing_module_)) { 1454 *ok = false; 1455 ReportMessage(MessageTemplate::kUnexpectedReserved); 1456 return NULL; 1457 } else if (IsEvalOrArguments(local_name)) { 1458 *ok = false; 1459 ReportMessage(MessageTemplate::kStrictEvalArguments); 1460 return NULL; 1461 } 1462 VariableProxy* proxy = NewUnresolved(local_name, CONST); 1463 ImportDeclaration* declaration = 1464 factory()->NewImportDeclaration(proxy, import_name, NULL, scope_, pos); 1465 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK); 1466 result->Add(declaration, zone()); 1467 if (peek() == Token::RBRACE) break; 1468 Expect(Token::COMMA, CHECK_OK); 1469 } 1470 1471 Expect(Token::RBRACE, CHECK_OK); 1472 1473 return result; 1474 } 1475 1476 1477 Statement* Parser::ParseImportDeclaration(bool* ok) { 1478 // ImportDeclaration : 1479 // 'import' ImportClause 'from' ModuleSpecifier ';' 1480 // 'import' ModuleSpecifier ';' 1481 // 1482 // ImportClause : 1483 // NameSpaceImport 1484 // NamedImports 1485 // ImportedDefaultBinding 1486 // ImportedDefaultBinding ',' NameSpaceImport 1487 // ImportedDefaultBinding ',' NamedImports 1488 // 1489 // NameSpaceImport : 1490 // '*' 'as' ImportedBinding 1491 1492 int pos = peek_position(); 1493 Expect(Token::IMPORT, CHECK_OK); 1494 1495 Token::Value tok = peek(); 1496 1497 // 'import' ModuleSpecifier ';' 1498 if (tok == Token::STRING) { 1499 const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK); 1500 scope_->module()->AddModuleRequest(module_specifier, zone()); 1501 ExpectSemicolon(CHECK_OK); 1502 return factory()->NewEmptyStatement(pos); 1503 } 1504 1505 // Parse ImportedDefaultBinding if present. 1506 ImportDeclaration* import_default_declaration = NULL; 1507 if (tok != Token::MUL && tok != Token::LBRACE) { 1508 const AstRawString* local_name = 1509 ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK); 1510 VariableProxy* proxy = NewUnresolved(local_name, CONST); 1511 import_default_declaration = factory()->NewImportDeclaration( 1512 proxy, ast_value_factory()->default_string(), NULL, scope_, pos); 1513 Declare(import_default_declaration, DeclarationDescriptor::NORMAL, true, 1514 CHECK_OK); 1515 } 1516 1517 const AstRawString* module_instance_binding = NULL; 1518 ZoneList<ImportDeclaration*>* named_declarations = NULL; 1519 if (import_default_declaration == NULL || Check(Token::COMMA)) { 1520 switch (peek()) { 1521 case Token::MUL: { 1522 Consume(Token::MUL); 1523 ExpectContextualKeyword(CStrVector("as"), CHECK_OK); 1524 module_instance_binding = 1525 ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK); 1526 // TODO(ES6): Add an appropriate declaration. 1527 break; 1528 } 1529 1530 case Token::LBRACE: 1531 named_declarations = ParseNamedImports(pos, CHECK_OK); 1532 break; 1533 1534 default: 1535 *ok = false; 1536 ReportUnexpectedToken(scanner()->current_token()); 1537 return NULL; 1538 } 1539 } 1540 1541 ExpectContextualKeyword(CStrVector("from"), CHECK_OK); 1542 const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK); 1543 scope_->module()->AddModuleRequest(module_specifier, zone()); 1544 1545 if (module_instance_binding != NULL) { 1546 // TODO(ES6): Set the module specifier for the module namespace binding. 1547 } 1548 1549 if (import_default_declaration != NULL) { 1550 import_default_declaration->set_module_specifier(module_specifier); 1551 } 1552 1553 if (named_declarations != NULL) { 1554 for (int i = 0; i < named_declarations->length(); ++i) { 1555 named_declarations->at(i)->set_module_specifier(module_specifier); 1556 } 1557 } 1558 1559 ExpectSemicolon(CHECK_OK); 1560 return factory()->NewEmptyStatement(pos); 1561 } 1562 1563 1564 Statement* Parser::ParseExportDefault(bool* ok) { 1565 // Supports the following productions, starting after the 'default' token: 1566 // 'export' 'default' FunctionDeclaration 1567 // 'export' 'default' ClassDeclaration 1568 // 'export' 'default' AssignmentExpression[In] ';' 1569 1570 Expect(Token::DEFAULT, CHECK_OK); 1571 Scanner::Location default_loc = scanner()->location(); 1572 1573 const AstRawString* default_string = ast_value_factory()->default_string(); 1574 ZoneList<const AstRawString*> names(1, zone()); 1575 Statement* result = nullptr; 1576 Expression* default_export = nullptr; 1577 switch (peek()) { 1578 case Token::FUNCTION: { 1579 Consume(Token::FUNCTION); 1580 int pos = position(); 1581 bool is_generator = Check(Token::MUL); 1582 if (peek() == Token::LPAREN) { 1583 // FunctionDeclaration[+Default] :: 1584 // 'function' '(' FormalParameters ')' '{' FunctionBody '}' 1585 // 1586 // GeneratorDeclaration[+Default] :: 1587 // 'function' '*' '(' FormalParameters ')' '{' FunctionBody '}' 1588 default_export = ParseFunctionLiteral( 1589 default_string, Scanner::Location::invalid(), 1590 kSkipFunctionNameCheck, 1591 is_generator ? FunctionKind::kGeneratorFunction 1592 : FunctionKind::kNormalFunction, 1593 pos, FunctionLiteral::kDeclaration, language_mode(), CHECK_OK); 1594 result = factory()->NewEmptyStatement(RelocInfo::kNoPosition); 1595 } else { 1596 result = ParseHoistableDeclaration( 1597 pos, is_generator ? ParseFunctionFlags::kIsGenerator 1598 : ParseFunctionFlags::kIsNormal, 1599 &names, CHECK_OK); 1600 } 1601 break; 1602 } 1603 1604 case Token::CLASS: 1605 Consume(Token::CLASS); 1606 if (peek() == Token::EXTENDS || peek() == Token::LBRACE) { 1607 // ClassDeclaration[+Default] :: 1608 // 'class' ('extends' LeftHandExpression)? '{' ClassBody '}' 1609 default_export = ParseClassLiteral(nullptr, default_string, 1610 Scanner::Location::invalid(), false, 1611 position(), CHECK_OK); 1612 result = factory()->NewEmptyStatement(RelocInfo::kNoPosition); 1613 } else { 1614 result = ParseClassDeclaration(&names, CHECK_OK); 1615 } 1616 break; 1617 1618 case Token::ASYNC: 1619 if (allow_harmony_async_await() && PeekAhead() == Token::FUNCTION && 1620 !scanner()->HasAnyLineTerminatorAfterNext()) { 1621 Consume(Token::ASYNC); 1622 Consume(Token::FUNCTION); 1623 int pos = position(); 1624 if (peek() == Token::LPAREN) { 1625 // AsyncFunctionDeclaration[+Default] :: 1626 // async [no LineTerminator here] function ( FormalParameters ) { 1627 // AsyncFunctionBody 1628 // } 1629 default_export = ParseFunctionLiteral( 1630 default_string, Scanner::Location::invalid(), 1631 kSkipFunctionNameCheck, FunctionKind::kAsyncFunction, pos, 1632 FunctionLiteral::kDeclaration, language_mode(), CHECK_OK); 1633 result = factory()->NewEmptyStatement(RelocInfo::kNoPosition); 1634 } else { 1635 result = ParseHoistableDeclaration(pos, ParseFunctionFlags::kIsAsync, 1636 &names, CHECK_OK); 1637 } 1638 break; 1639 } 1640 /* falls through */ 1641 1642 default: { 1643 int pos = peek_position(); 1644 ExpressionClassifier classifier(this); 1645 Expression* expr = ParseAssignmentExpression(true, &classifier, CHECK_OK); 1646 RewriteNonPattern(&classifier, CHECK_OK); 1647 1648 ExpectSemicolon(CHECK_OK); 1649 result = factory()->NewExpressionStatement(expr, pos); 1650 break; 1651 } 1652 } 1653 1654 DCHECK_LE(names.length(), 1); 1655 if (names.length() == 1) { 1656 scope_->module()->AddLocalExport(default_string, names.first(), zone(), ok); 1657 if (!*ok) { 1658 ParserTraits::ReportMessageAt( 1659 default_loc, MessageTemplate::kDuplicateExport, default_string); 1660 return nullptr; 1661 } 1662 } else { 1663 // TODO(ES6): Assign result to a const binding with the name "*default*" 1664 // and add an export entry with "*default*" as the local name. 1665 USE(default_export); 1666 } 1667 1668 return result; 1669 } 1670 1671 1672 Statement* Parser::ParseExportDeclaration(bool* ok) { 1673 // ExportDeclaration: 1674 // 'export' '*' 'from' ModuleSpecifier ';' 1675 // 'export' ExportClause ('from' ModuleSpecifier)? ';' 1676 // 'export' VariableStatement 1677 // 'export' Declaration 1678 // 'export' 'default' ... (handled in ParseExportDefault) 1679 1680 int pos = peek_position(); 1681 Expect(Token::EXPORT, CHECK_OK); 1682 1683 Statement* result = NULL; 1684 ZoneList<const AstRawString*> names(1, zone()); 1685 switch (peek()) { 1686 case Token::DEFAULT: 1687 return ParseExportDefault(ok); 1688 1689 case Token::MUL: { 1690 Consume(Token::MUL); 1691 ExpectContextualKeyword(CStrVector("from"), CHECK_OK); 1692 const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK); 1693 scope_->module()->AddModuleRequest(module_specifier, zone()); 1694 // TODO(ES6): scope_->module()->AddStarExport(...) 1695 ExpectSemicolon(CHECK_OK); 1696 return factory()->NewEmptyStatement(pos); 1697 } 1698 1699 case Token::LBRACE: { 1700 // There are two cases here: 1701 // 1702 // 'export' ExportClause ';' 1703 // and 1704 // 'export' ExportClause FromClause ';' 1705 // 1706 // In the first case, the exported identifiers in ExportClause must 1707 // not be reserved words, while in the latter they may be. We 1708 // pass in a location that gets filled with the first reserved word 1709 // encountered, and then throw a SyntaxError if we are in the 1710 // non-FromClause case. 1711 Scanner::Location reserved_loc = Scanner::Location::invalid(); 1712 ZoneList<const AstRawString*> export_names(1, zone()); 1713 ZoneList<Scanner::Location> export_locations(1, zone()); 1714 ZoneList<const AstRawString*> local_names(1, zone()); 1715 ParseExportClause(&export_names, &export_locations, &local_names, 1716 &reserved_loc, CHECK_OK); 1717 const AstRawString* indirect_export_module_specifier = NULL; 1718 if (CheckContextualKeyword(CStrVector("from"))) { 1719 indirect_export_module_specifier = ParseModuleSpecifier(CHECK_OK); 1720 } else if (reserved_loc.IsValid()) { 1721 // No FromClause, so reserved words are invalid in ExportClause. 1722 *ok = false; 1723 ReportMessageAt(reserved_loc, MessageTemplate::kUnexpectedReserved); 1724 return NULL; 1725 } 1726 ExpectSemicolon(CHECK_OK); 1727 const int length = export_names.length(); 1728 DCHECK_EQ(length, local_names.length()); 1729 DCHECK_EQ(length, export_locations.length()); 1730 if (indirect_export_module_specifier == NULL) { 1731 for (int i = 0; i < length; ++i) { 1732 scope_->module()->AddLocalExport(export_names[i], local_names[i], 1733 zone(), ok); 1734 if (!*ok) { 1735 ParserTraits::ReportMessageAt(export_locations[i], 1736 MessageTemplate::kDuplicateExport, 1737 export_names[i]); 1738 return NULL; 1739 } 1740 } 1741 } else { 1742 scope_->module()->AddModuleRequest(indirect_export_module_specifier, 1743 zone()); 1744 for (int i = 0; i < length; ++i) { 1745 // TODO(ES6): scope_->module()->AddIndirectExport(...);( 1746 } 1747 } 1748 return factory()->NewEmptyStatement(pos); 1749 } 1750 1751 case Token::FUNCTION: 1752 result = ParseHoistableDeclaration(&names, CHECK_OK); 1753 break; 1754 1755 case Token::CLASS: 1756 Consume(Token::CLASS); 1757 result = ParseClassDeclaration(&names, CHECK_OK); 1758 break; 1759 1760 case Token::VAR: 1761 case Token::LET: 1762 case Token::CONST: 1763 result = ParseVariableStatement(kStatementListItem, &names, CHECK_OK); 1764 break; 1765 1766 case Token::ASYNC: 1767 if (allow_harmony_async_await()) { 1768 Consume(Token::ASYNC); 1769 result = ParseAsyncFunctionDeclaration(&names, CHECK_OK); 1770 break; 1771 } 1772 /* falls through */ 1773 1774 default: 1775 *ok = false; 1776 ReportUnexpectedToken(scanner()->current_token()); 1777 return NULL; 1778 } 1779 1780 // Extract declared names into export declarations. 1781 ModuleDescriptor* descriptor = scope_->module(); 1782 for (int i = 0; i < names.length(); ++i) { 1783 descriptor->AddLocalExport(names[i], names[i], zone(), ok); 1784 if (!*ok) { 1785 // TODO(adamk): Possibly report this error at the right place. 1786 ParserTraits::ReportMessage(MessageTemplate::kDuplicateExport, names[i]); 1787 return NULL; 1788 } 1789 } 1790 1791 DCHECK_NOT_NULL(result); 1792 return result; 1793 } 1794 1795 Statement* Parser::ParseStatement(ZoneList<const AstRawString*>* labels, 1796 AllowLabelledFunctionStatement allow_function, 1797 bool* ok) { 1798 // Statement :: 1799 // EmptyStatement 1800 // ... 1801 1802 if (peek() == Token::SEMICOLON) { 1803 Next(); 1804 return factory()->NewEmptyStatement(RelocInfo::kNoPosition); 1805 } 1806 return ParseSubStatement(labels, allow_function, ok); 1807 } 1808 1809 Statement* Parser::ParseSubStatement( 1810 ZoneList<const AstRawString*>* labels, 1811 AllowLabelledFunctionStatement allow_function, bool* ok) { 1812 // Statement :: 1813 // Block 1814 // VariableStatement 1815 // EmptyStatement 1816 // ExpressionStatement 1817 // IfStatement 1818 // IterationStatement 1819 // ContinueStatement 1820 // BreakStatement 1821 // ReturnStatement 1822 // WithStatement 1823 // LabelledStatement 1824 // SwitchStatement 1825 // ThrowStatement 1826 // TryStatement 1827 // DebuggerStatement 1828 1829 // Note: Since labels can only be used by 'break' and 'continue' 1830 // statements, which themselves are only valid within blocks, 1831 // iterations or 'switch' statements (i.e., BreakableStatements), 1832 // labels can be simply ignored in all other cases; except for 1833 // trivial labeled break statements 'label: break label' which is 1834 // parsed into an empty statement. 1835 switch (peek()) { 1836 case Token::LBRACE: 1837 return ParseBlock(labels, ok); 1838 1839 case Token::SEMICOLON: 1840 Next(); 1841 return factory()->NewEmptyStatement(RelocInfo::kNoPosition); 1842 1843 case Token::IF: 1844 return ParseIfStatement(labels, ok); 1845 1846 case Token::DO: 1847 return ParseDoWhileStatement(labels, ok); 1848 1849 case Token::WHILE: 1850 return ParseWhileStatement(labels, ok); 1851 1852 case Token::FOR: 1853 return ParseForStatement(labels, ok); 1854 1855 case Token::CONTINUE: 1856 case Token::BREAK: 1857 case Token::RETURN: 1858 case Token::THROW: 1859 case Token::TRY: { 1860 // These statements must have their labels preserved in an enclosing 1861 // block 1862 if (labels == NULL) { 1863 return ParseStatementAsUnlabelled(labels, ok); 1864 } else { 1865 Block* result = 1866 factory()->NewBlock(labels, 1, false, RelocInfo::kNoPosition); 1867 Target target(&this->target_stack_, result); 1868 Statement* statement = ParseStatementAsUnlabelled(labels, CHECK_OK); 1869 if (result) result->statements()->Add(statement, zone()); 1870 return result; 1871 } 1872 } 1873 1874 case Token::WITH: 1875 return ParseWithStatement(labels, ok); 1876 1877 case Token::SWITCH: 1878 return ParseSwitchStatement(labels, ok); 1879 1880 case Token::FUNCTION: 1881 // FunctionDeclaration only allowed as a StatementListItem, not in 1882 // an arbitrary Statement position. Exceptions such as 1883 // ES#sec-functiondeclarations-in-ifstatement-statement-clauses 1884 // are handled by calling ParseScopedStatement rather than 1885 // ParseSubStatement directly. 1886 ReportMessageAt(scanner()->peek_location(), 1887 is_strict(language_mode()) 1888 ? MessageTemplate::kStrictFunction 1889 : MessageTemplate::kSloppyFunction); 1890 *ok = false; 1891 return nullptr; 1892 1893 case Token::DEBUGGER: 1894 return ParseDebuggerStatement(ok); 1895 1896 case Token::VAR: 1897 return ParseVariableStatement(kStatement, NULL, ok); 1898 1899 default: 1900 return ParseExpressionOrLabelledStatement(labels, allow_function, ok); 1901 } 1902 } 1903 1904 Statement* Parser::ParseStatementAsUnlabelled( 1905 ZoneList<const AstRawString*>* labels, bool* ok) { 1906 switch (peek()) { 1907 case Token::CONTINUE: 1908 return ParseContinueStatement(ok); 1909 1910 case Token::BREAK: 1911 return ParseBreakStatement(labels, ok); 1912 1913 case Token::RETURN: 1914 return ParseReturnStatement(ok); 1915 1916 case Token::THROW: 1917 return ParseThrowStatement(ok); 1918 1919 case Token::TRY: 1920 return ParseTryStatement(ok); 1921 1922 default: 1923 UNREACHABLE(); 1924 return NULL; 1925 } 1926 } 1927 1928 1929 VariableProxy* Parser::NewUnresolved(const AstRawString* name, 1930 VariableMode mode) { 1931 // If we are inside a function, a declaration of a var/const variable is a 1932 // truly local variable, and the scope of the variable is always the function 1933 // scope. 1934 // Let/const variables in harmony mode are always added to the immediately 1935 // enclosing scope. 1936 Scope* scope = 1937 IsLexicalVariableMode(mode) ? scope_ : scope_->DeclarationScope(); 1938 return scope->NewUnresolved(factory(), name, Variable::NORMAL, 1939 scanner()->location().beg_pos, 1940 scanner()->location().end_pos); 1941 } 1942 1943 1944 Variable* Parser::Declare(Declaration* declaration, 1945 DeclarationDescriptor::Kind declaration_kind, 1946 bool resolve, bool* ok, Scope* scope) { 1947 VariableProxy* proxy = declaration->proxy(); 1948 DCHECK(proxy->raw_name() != NULL); 1949 const AstRawString* name = proxy->raw_name(); 1950 VariableMode mode = declaration->mode(); 1951 DCHECK(IsDeclaredVariableMode(mode) && mode != CONST_LEGACY); 1952 bool is_function_declaration = declaration->IsFunctionDeclaration(); 1953 if (scope == nullptr) scope = scope_; 1954 Scope* declaration_scope = 1955 IsLexicalVariableMode(mode) ? scope : scope->DeclarationScope(); 1956 Variable* var = NULL; 1957 1958 // If a suitable scope exists, then we can statically declare this 1959 // variable and also set its mode. In any case, a Declaration node 1960 // will be added to the scope so that the declaration can be added 1961 // to the corresponding activation frame at runtime if necessary. 1962 // For instance, var declarations inside a sloppy eval scope need 1963 // to be added to the calling function context. Similarly, strict 1964 // mode eval scope and lexical eval bindings do not leak variable 1965 // declarations to the caller's scope so we declare all locals, too. 1966 if (declaration_scope->is_function_scope() || 1967 declaration_scope->is_block_scope() || 1968 declaration_scope->is_module_scope() || 1969 declaration_scope->is_script_scope() || 1970 (declaration_scope->is_eval_scope() && 1971 (is_strict(declaration_scope->language_mode()) || 1972 IsLexicalVariableMode(mode)))) { 1973 // Declare the variable in the declaration scope. 1974 var = declaration_scope->LookupLocal(name); 1975 if (var == NULL) { 1976 // Declare the name. 1977 Variable::Kind kind = Variable::NORMAL; 1978 if (is_function_declaration) { 1979 kind = Variable::FUNCTION; 1980 } 1981 var = declaration_scope->DeclareLocal( 1982 name, mode, declaration->initialization(), kind, kNotAssigned); 1983 } else if (IsLexicalVariableMode(mode) || 1984 IsLexicalVariableMode(var->mode())) { 1985 // Allow duplicate function decls for web compat, see bug 4693. 1986 bool duplicate_allowed = false; 1987 if (is_sloppy(language_mode()) && is_function_declaration && 1988 var->is_function()) { 1989 DCHECK(IsLexicalVariableMode(mode) && 1990 IsLexicalVariableMode(var->mode())); 1991 // If the duplication is allowed, then the var will show up 1992 // in the SloppyBlockFunctionMap and the new FunctionKind 1993 // will be a permitted duplicate. 1994 FunctionKind function_kind = 1995 declaration->AsFunctionDeclaration()->fun()->kind(); 1996 duplicate_allowed = 1997 scope->DeclarationScope()->sloppy_block_function_map()->Lookup( 1998 const_cast<AstRawString*>(name), name->hash()) != nullptr && 1999 !IsAsyncFunction(function_kind) && 2000 !(allow_harmony_restrictive_generators() && 2001 IsGeneratorFunction(function_kind)); 2002 } 2003 if (duplicate_allowed) { 2004 ++use_counts_[v8::Isolate::kSloppyModeBlockScopedFunctionRedefinition]; 2005 } else { 2006 // The name was declared in this scope before; check for conflicting 2007 // re-declarations. We have a conflict if either of the declarations 2008 // is not a var (in script scope, we also have to ignore legacy const 2009 // for compatibility). There is similar code in runtime.cc in the 2010 // Declare functions. The function CheckConflictingVarDeclarations 2011 // checks for var and let bindings from different scopes whereas this 2012 // is a check for conflicting declarations within the same scope. This 2013 // check also covers the special case 2014 // 2015 // function () { let x; { var x; } } 2016 // 2017 // because the var declaration is hoisted to the function scope where 2018 // 'x' is already bound. 2019 DCHECK(IsDeclaredVariableMode(var->mode())); 2020 // In harmony we treat re-declarations as early errors. See 2021 // ES5 16 for a definition of early errors. 2022 if (declaration_kind == DeclarationDescriptor::NORMAL) { 2023 ParserTraits::ReportMessage(MessageTemplate::kVarRedeclaration, name); 2024 } else { 2025 ParserTraits::ReportMessage(MessageTemplate::kParamDupe); 2026 } 2027 *ok = false; 2028 return nullptr; 2029 } 2030 } else if (mode == VAR) { 2031 var->set_maybe_assigned(); 2032 } 2033 } else if (declaration_scope->is_eval_scope() && 2034 is_sloppy(declaration_scope->language_mode()) && 2035 !IsLexicalVariableMode(mode)) { 2036 // In a var binding in a sloppy direct eval, pollute the enclosing scope 2037 // with this new binding by doing the following: 2038 // The proxy is bound to a lookup variable to force a dynamic declaration 2039 // using the DeclareEvalVar or DeclareEvalFunction runtime functions. 2040 Variable::Kind kind = Variable::NORMAL; 2041 // TODO(sigurds) figure out if kNotAssigned is OK here 2042 var = new (zone()) Variable(declaration_scope, name, mode, kind, 2043 declaration->initialization(), kNotAssigned); 2044 var->AllocateTo(VariableLocation::LOOKUP, -1); 2045 resolve = true; 2046 } 2047 2048 2049 // We add a declaration node for every declaration. The compiler 2050 // will only generate code if necessary. In particular, declarations 2051 // for inner local variables that do not represent functions won't 2052 // result in any generated code. 2053 // 2054 // Note that we always add an unresolved proxy even if it's not 2055 // used, simply because we don't know in this method (w/o extra 2056 // parameters) if the proxy is needed or not. The proxy will be 2057 // bound during variable resolution time unless it was pre-bound 2058 // below. 2059 // 2060 // WARNING: This will lead to multiple declaration nodes for the 2061 // same variable if it is declared several times. This is not a 2062 // semantic issue as long as we keep the source order, but it may be 2063 // a performance issue since it may lead to repeated 2064 // DeclareEvalVar or DeclareEvalFunction calls. 2065 declaration_scope->AddDeclaration(declaration); 2066 2067 // If requested and we have a local variable, bind the proxy to the variable 2068 // at parse-time. This is used for functions (and consts) declared inside 2069 // statements: the corresponding function (or const) variable must be in the 2070 // function scope and not a statement-local scope, e.g. as provided with a 2071 // 'with' statement: 2072 // 2073 // with (obj) { 2074 // function f() {} 2075 // } 2076 // 2077 // which is translated into: 2078 // 2079 // with (obj) { 2080 // // in this case this is not: 'var f; f = function () {};' 2081 // var f = function () {}; 2082 // } 2083 // 2084 // Note that if 'f' is accessed from inside the 'with' statement, it 2085 // will be allocated in the context (because we must be able to look 2086 // it up dynamically) but it will also be accessed statically, i.e., 2087 // with a context slot index and a context chain length for this 2088 // initialization code. Thus, inside the 'with' statement, we need 2089 // both access to the static and the dynamic context chain; the 2090 // runtime needs to provide both. 2091 if (resolve && var != NULL) { 2092 proxy->BindTo(var); 2093 } 2094 return var; 2095 } 2096 2097 2098 // Language extension which is only enabled for source files loaded 2099 // through the API's extension mechanism. A native function 2100 // declaration is resolved by looking up the function through a 2101 // callback provided by the extension. 2102 Statement* Parser::ParseNativeDeclaration(bool* ok) { 2103 int pos = peek_position(); 2104 Expect(Token::FUNCTION, CHECK_OK); 2105 // Allow "eval" or "arguments" for backward compatibility. 2106 const AstRawString* name = 2107 ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK); 2108 Expect(Token::LPAREN, CHECK_OK); 2109 bool done = (peek() == Token::RPAREN); 2110 while (!done) { 2111 ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK); 2112 done = (peek() == Token::RPAREN); 2113 if (!done) { 2114 Expect(Token::COMMA, CHECK_OK); 2115 } 2116 } 2117 Expect(Token::RPAREN, CHECK_OK); 2118 Expect(Token::SEMICOLON, CHECK_OK); 2119 2120 // Make sure that the function containing the native declaration 2121 // isn't lazily compiled. The extension structures are only 2122 // accessible while parsing the first time not when reparsing 2123 // because of lazy compilation. 2124 // TODO(adamk): Should this be ClosureScope()? 2125 scope_->DeclarationScope()->ForceEagerCompilation(); 2126 2127 // TODO(1240846): It's weird that native function declarations are 2128 // introduced dynamically when we meet their declarations, whereas 2129 // other functions are set up when entering the surrounding scope. 2130 VariableProxy* proxy = NewUnresolved(name, VAR); 2131 Declaration* declaration = 2132 factory()->NewVariableDeclaration(proxy, VAR, scope_, pos); 2133 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK); 2134 NativeFunctionLiteral* lit = factory()->NewNativeFunctionLiteral( 2135 name, extension_, RelocInfo::kNoPosition); 2136 return factory()->NewExpressionStatement( 2137 factory()->NewAssignment(Token::INIT, proxy, lit, RelocInfo::kNoPosition), 2138 pos); 2139 } 2140 2141 2142 Statement* Parser::ParseHoistableDeclaration( 2143 ZoneList<const AstRawString*>* names, bool* ok) { 2144 Expect(Token::FUNCTION, CHECK_OK); 2145 int pos = position(); 2146 ParseFunctionFlags flags = ParseFunctionFlags::kIsNormal; 2147 if (Check(Token::MUL)) { 2148 flags |= ParseFunctionFlags::kIsGenerator; 2149 } 2150 return ParseHoistableDeclaration(pos, flags, names, ok); 2151 } 2152 2153 Statement* Parser::ParseAsyncFunctionDeclaration( 2154 ZoneList<const AstRawString*>* names, bool* ok) { 2155 DCHECK_EQ(scanner()->current_token(), Token::ASYNC); 2156 int pos = position(); 2157 if (scanner()->HasAnyLineTerminatorBeforeNext()) { 2158 *ok = false; 2159 ReportUnexpectedToken(scanner()->current_token()); 2160 return nullptr; 2161 } 2162 Expect(Token::FUNCTION, CHECK_OK); 2163 ParseFunctionFlags flags = ParseFunctionFlags::kIsAsync; 2164 return ParseHoistableDeclaration(pos, flags, names, ok); 2165 } 2166 2167 Statement* Parser::ParseHoistableDeclaration( 2168 int pos, ParseFunctionFlags flags, ZoneList<const AstRawString*>* names, 2169 bool* ok) { 2170 // FunctionDeclaration :: 2171 // 'function' Identifier '(' FormalParameters ')' '{' FunctionBody '}' 2172 // GeneratorDeclaration :: 2173 // 'function' '*' Identifier '(' FormalParameters ')' '{' FunctionBody '}' 2174 // 2175 // 'function' and '*' (if present) have been consumed by the caller. 2176 const bool is_generator = flags & ParseFunctionFlags::kIsGenerator; 2177 const bool is_async = flags & ParseFunctionFlags::kIsAsync; 2178 DCHECK(!is_generator || !is_async); 2179 2180 bool is_strict_reserved = false; 2181 const AstRawString* name = ParseIdentifierOrStrictReservedWord( 2182 &is_strict_reserved, CHECK_OK); 2183 2184 if (V8_UNLIKELY(is_async_function() && this->IsAwait(name))) { 2185 ReportMessageAt(scanner()->location(), 2186 MessageTemplate::kAwaitBindingIdentifier); 2187 *ok = false; 2188 return nullptr; 2189 } 2190 2191 FuncNameInferrer::State fni_state(fni_); 2192 if (fni_ != NULL) fni_->PushEnclosingName(name); 2193 FunctionLiteral* fun = ParseFunctionLiteral( 2194 name, scanner()->location(), 2195 is_strict_reserved ? kFunctionNameIsStrictReserved 2196 : kFunctionNameValidityUnknown, 2197 is_generator ? FunctionKind::kGeneratorFunction 2198 : is_async ? FunctionKind::kAsyncFunction 2199 : FunctionKind::kNormalFunction, 2200 pos, FunctionLiteral::kDeclaration, language_mode(), CHECK_OK); 2201 2202 // Even if we're not at the top-level of the global or a function 2203 // scope, we treat it as such and introduce the function with its 2204 // initial value upon entering the corresponding scope. 2205 // In ES6, a function behaves as a lexical binding, except in 2206 // a script scope, or the initial scope of eval or another function. 2207 VariableMode mode = 2208 (!scope_->is_declaration_scope() || scope_->is_module_scope()) ? LET 2209 : VAR; 2210 VariableProxy* proxy = NewUnresolved(name, mode); 2211 Declaration* declaration = 2212 factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos); 2213 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK); 2214 if (names) names->Add(name, zone()); 2215 EmptyStatement* empty = factory()->NewEmptyStatement(RelocInfo::kNoPosition); 2216 // Async functions don't undergo sloppy mode block scoped hoisting, and don't 2217 // allow duplicates in a block. Both are represented by the 2218 // sloppy_block_function_map. Don't add them to the map for async functions. 2219 // Generators are also supposed to be prohibited; currently doing this behind 2220 // a flag and UseCounting violations to assess web compatibility. 2221 if (is_sloppy(language_mode()) && !scope_->is_declaration_scope() && 2222 !is_async && !(allow_harmony_restrictive_generators() && is_generator)) { 2223 SloppyBlockFunctionStatement* delegate = 2224 factory()->NewSloppyBlockFunctionStatement(empty, scope_); 2225 scope_->DeclarationScope()->sloppy_block_function_map()->Declare(name, 2226 delegate); 2227 return delegate; 2228 } 2229 return empty; 2230 } 2231 2232 2233 Statement* Parser::ParseClassDeclaration(ZoneList<const AstRawString*>* names, 2234 bool* ok) { 2235 // ClassDeclaration :: 2236 // 'class' Identifier ('extends' LeftHandExpression)? '{' ClassBody '}' 2237 // 2238 // 'class' is expected to be consumed by the caller. 2239 // 2240 // A ClassDeclaration 2241 // 2242 // class C { ... } 2243 // 2244 // has the same semantics as: 2245 // 2246 // let C = class C { ... }; 2247 // 2248 // so rewrite it as such. 2249 2250 int pos = position(); 2251 bool is_strict_reserved = false; 2252 const AstRawString* name = 2253 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); 2254 ClassLiteral* value = ParseClassLiteral(nullptr, name, scanner()->location(), 2255 is_strict_reserved, pos, CHECK_OK); 2256 2257 VariableProxy* proxy = NewUnresolved(name, LET); 2258 Declaration* declaration = 2259 factory()->NewVariableDeclaration(proxy, LET, scope_, pos); 2260 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK); 2261 proxy->var()->set_initializer_position(position()); 2262 Assignment* assignment = 2263 factory()->NewAssignment(Token::INIT, proxy, value, pos); 2264 Statement* assignment_statement = 2265 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition); 2266 if (names) names->Add(name, zone()); 2267 return assignment_statement; 2268 } 2269 2270 2271 Block* Parser::ParseBlock(ZoneList<const AstRawString*>* labels, 2272 bool finalize_block_scope, bool* ok) { 2273 // The harmony mode uses block elements instead of statements. 2274 // 2275 // Block :: 2276 // '{' StatementList '}' 2277 2278 // Construct block expecting 16 statements. 2279 Block* body = 2280 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition); 2281 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE); 2282 2283 // Parse the statements and collect escaping labels. 2284 Expect(Token::LBRACE, CHECK_OK); 2285 block_scope->set_start_position(scanner()->location().beg_pos); 2286 { BlockState block_state(&scope_, block_scope); 2287 Target target(&this->target_stack_, body); 2288 2289 while (peek() != Token::RBRACE) { 2290 Statement* stat = ParseStatementListItem(CHECK_OK); 2291 if (stat && !stat->IsEmpty()) { 2292 body->statements()->Add(stat, zone()); 2293 } 2294 } 2295 } 2296 Expect(Token::RBRACE, CHECK_OK); 2297 block_scope->set_end_position(scanner()->location().end_pos); 2298 if (finalize_block_scope) { 2299 block_scope = block_scope->FinalizeBlockScope(); 2300 } 2301 body->set_scope(block_scope); 2302 return body; 2303 } 2304 2305 2306 Block* Parser::ParseBlock(ZoneList<const AstRawString*>* labels, bool* ok) { 2307 return ParseBlock(labels, true, ok); 2308 } 2309 2310 2311 Block* Parser::DeclarationParsingResult::BuildInitializationBlock( 2312 ZoneList<const AstRawString*>* names, bool* ok) { 2313 Block* result = descriptor.parser->factory()->NewBlock( 2314 NULL, 1, true, descriptor.declaration_pos); 2315 for (auto declaration : declarations) { 2316 PatternRewriter::DeclareAndInitializeVariables( 2317 result, &descriptor, &declaration, names, CHECK_OK); 2318 } 2319 return result; 2320 } 2321 2322 2323 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context, 2324 ZoneList<const AstRawString*>* names, 2325 bool* ok) { 2326 // VariableStatement :: 2327 // VariableDeclarations ';' 2328 2329 // The scope of a var/const declared variable anywhere inside a function 2330 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can 2331 // transform a source-level var/const declaration into a (Function) 2332 // Scope declaration, and rewrite the source-level initialization into an 2333 // assignment statement. We use a block to collect multiple assignments. 2334 // 2335 // We mark the block as initializer block because we don't want the 2336 // rewriter to add a '.result' assignment to such a block (to get compliant 2337 // behavior for code such as print(eval('var x = 7')), and for cosmetic 2338 // reasons when pretty-printing. Also, unless an assignment (initialization) 2339 // is inside an initializer block, it is ignored. 2340 2341 DeclarationParsingResult parsing_result; 2342 Block* result = 2343 ParseVariableDeclarations(var_context, &parsing_result, names, CHECK_OK); 2344 ExpectSemicolon(CHECK_OK); 2345 return result; 2346 } 2347 2348 Block* Parser::ParseVariableDeclarations( 2349 VariableDeclarationContext var_context, 2350 DeclarationParsingResult* parsing_result, 2351 ZoneList<const AstRawString*>* names, bool* ok) { 2352 // VariableDeclarations :: 2353 // ('var' | 'const' | 'let') (Identifier ('=' AssignmentExpression)?)+[','] 2354 // 2355 // The ES6 Draft Rev3 specifies the following grammar for const declarations 2356 // 2357 // ConstDeclaration :: 2358 // const ConstBinding (',' ConstBinding)* ';' 2359 // ConstBinding :: 2360 // Identifier '=' AssignmentExpression 2361 // 2362 // TODO(ES6): 2363 // ConstBinding :: 2364 // BindingPattern '=' AssignmentExpression 2365 2366 parsing_result->descriptor.parser = this; 2367 parsing_result->descriptor.declaration_kind = DeclarationDescriptor::NORMAL; 2368 parsing_result->descriptor.declaration_pos = peek_position(); 2369 parsing_result->descriptor.initialization_pos = peek_position(); 2370 parsing_result->descriptor.mode = VAR; 2371 2372 Block* init_block = nullptr; 2373 if (var_context != kForStatement) { 2374 init_block = factory()->NewBlock( 2375 NULL, 1, true, parsing_result->descriptor.declaration_pos); 2376 } 2377 2378 if (peek() == Token::VAR) { 2379 Consume(Token::VAR); 2380 } else if (peek() == Token::CONST) { 2381 Consume(Token::CONST); 2382 DCHECK(var_context != kStatement); 2383 parsing_result->descriptor.mode = CONST; 2384 } else if (peek() == Token::LET) { 2385 Consume(Token::LET); 2386 DCHECK(var_context != kStatement); 2387 parsing_result->descriptor.mode = LET; 2388 } else { 2389 UNREACHABLE(); // by current callers 2390 } 2391 2392 parsing_result->descriptor.scope = scope_; 2393 parsing_result->descriptor.hoist_scope = nullptr; 2394 2395 2396 bool first_declaration = true; 2397 int bindings_start = peek_position(); 2398 do { 2399 FuncNameInferrer::State fni_state(fni_); 2400 2401 // Parse name. 2402 if (!first_declaration) Consume(Token::COMMA); 2403 2404 Expression* pattern; 2405 int decl_pos = peek_position(); 2406 { 2407 ExpressionClassifier pattern_classifier(this); 2408 pattern = ParsePrimaryExpression(&pattern_classifier, CHECK_OK); 2409 ValidateBindingPattern(&pattern_classifier, CHECK_OK); 2410 if (IsLexicalVariableMode(parsing_result->descriptor.mode)) { 2411 ValidateLetPattern(&pattern_classifier, CHECK_OK); 2412 } 2413 } 2414 2415 Scanner::Location variable_loc = scanner()->location(); 2416 const AstRawString* single_name = 2417 pattern->IsVariableProxy() ? pattern->AsVariableProxy()->raw_name() 2418 : nullptr; 2419 if (single_name != nullptr) { 2420 if (fni_ != NULL) fni_->PushVariableName(single_name); 2421 } 2422 2423 Expression* value = NULL; 2424 int initializer_position = RelocInfo::kNoPosition; 2425 if (Check(Token::ASSIGN)) { 2426 ExpressionClassifier classifier(this); 2427 value = ParseAssignmentExpression(var_context != kForStatement, 2428 &classifier, CHECK_OK); 2429 RewriteNonPattern(&classifier, CHECK_OK); 2430 variable_loc.end_pos = scanner()->location().end_pos; 2431 2432 if (!parsing_result->first_initializer_loc.IsValid()) { 2433 parsing_result->first_initializer_loc = variable_loc; 2434 } 2435 2436 // Don't infer if it is "a = function(){...}();"-like expression. 2437 if (single_name) { 2438 if (fni_ != NULL && value->AsCall() == NULL && 2439 value->AsCallNew() == NULL) { 2440 fni_->Infer(); 2441 } else { 2442 fni_->RemoveLastFunction(); 2443 } 2444 } 2445 2446 ParserTraits::SetFunctionNameFromIdentifierRef(value, pattern); 2447 2448 // End position of the initializer is after the assignment expression. 2449 initializer_position = scanner()->location().end_pos; 2450 } else { 2451 // Initializers may be either required or implied unless this is a 2452 // for-in/of iteration variable. 2453 if (var_context != kForStatement || !PeekInOrOf()) { 2454 // ES6 'const' and binding patterns require initializers. 2455 if (parsing_result->descriptor.mode == CONST || 2456 !pattern->IsVariableProxy()) { 2457 ParserTraits::ReportMessageAt( 2458 Scanner::Location(decl_pos, scanner()->location().end_pos), 2459 MessageTemplate::kDeclarationMissingInitializer, 2460 !pattern->IsVariableProxy() ? "destructuring" : "const"); 2461 *ok = false; 2462 return nullptr; 2463 } 2464 2465 // 'let x' initializes 'x' to undefined. 2466 if (parsing_result->descriptor.mode == LET) { 2467 value = GetLiteralUndefined(position()); 2468 } 2469 } 2470 2471 // End position of the initializer is after the variable. 2472 initializer_position = position(); 2473 } 2474 2475 DeclarationParsingResult::Declaration decl(pattern, initializer_position, 2476 value); 2477 if (var_context == kForStatement) { 2478 // Save the declaration for further handling in ParseForStatement. 2479 parsing_result->declarations.Add(decl); 2480 } else { 2481 // Immediately declare the variable otherwise. This avoids O(N^2) 2482 // behavior (where N is the number of variables in a single 2483 // declaration) in the PatternRewriter having to do with removing 2484 // and adding VariableProxies to the Scope (see bug 4699). 2485 DCHECK_NOT_NULL(init_block); 2486 PatternRewriter::DeclareAndInitializeVariables( 2487 init_block, &parsing_result->descriptor, &decl, names, CHECK_OK); 2488 } 2489 first_declaration = false; 2490 } while (peek() == Token::COMMA); 2491 2492 parsing_result->bindings_loc = 2493 Scanner::Location(bindings_start, scanner()->location().end_pos); 2494 2495 DCHECK(*ok); 2496 return init_block; 2497 } 2498 2499 2500 static bool ContainsLabel(ZoneList<const AstRawString*>* labels, 2501 const AstRawString* label) { 2502 DCHECK(label != NULL); 2503 if (labels != NULL) { 2504 for (int i = labels->length(); i-- > 0; ) { 2505 if (labels->at(i) == label) { 2506 return true; 2507 } 2508 } 2509 } 2510 return false; 2511 } 2512 2513 Statement* Parser::ParseFunctionDeclaration(bool* ok) { 2514 Consume(Token::FUNCTION); 2515 int pos = position(); 2516 ParseFunctionFlags flags = ParseFunctionFlags::kIsNormal; 2517 if (Check(Token::MUL)) { 2518 flags |= ParseFunctionFlags::kIsGenerator; 2519 if (allow_harmony_restrictive_declarations()) { 2520 ParserTraits::ReportMessageAt(scanner()->location(), 2521 MessageTemplate::kGeneratorInLegacyContext); 2522 *ok = false; 2523 return nullptr; 2524 } 2525 } 2526 2527 return ParseHoistableDeclaration(pos, flags, nullptr, CHECK_OK); 2528 } 2529 2530 Statement* Parser::ParseExpressionOrLabelledStatement( 2531 ZoneList<const AstRawString*>* labels, 2532 AllowLabelledFunctionStatement allow_function, bool* ok) { 2533 // ExpressionStatement | LabelledStatement :: 2534 // Expression ';' 2535 // Identifier ':' Statement 2536 // 2537 // ExpressionStatement[Yield] : 2538 // [lookahead {{, function, class, let [}] Expression[In, ?Yield] ; 2539 2540 int pos = peek_position(); 2541 2542 switch (peek()) { 2543 case Token::FUNCTION: 2544 case Token::LBRACE: 2545 UNREACHABLE(); // Always handled by the callers. 2546 case Token::CLASS: 2547 ReportUnexpectedToken(Next()); 2548 *ok = false; 2549 return nullptr; 2550 default: 2551 break; 2552 } 2553 2554 bool starts_with_idenfifier = peek_any_identifier(); 2555 Expression* expr = ParseExpression(true, CHECK_OK); 2556 if (peek() == Token::COLON && starts_with_idenfifier && expr != NULL && 2557 expr->AsVariableProxy() != NULL && 2558 !expr->AsVariableProxy()->is_this()) { 2559 // Expression is a single identifier, and not, e.g., a parenthesized 2560 // identifier. 2561 VariableProxy* var = expr->AsVariableProxy(); 2562 const AstRawString* label = var->raw_name(); 2563 // TODO(1240780): We don't check for redeclaration of labels 2564 // during preparsing since keeping track of the set of active 2565 // labels requires nontrivial changes to the way scopes are 2566 // structured. However, these are probably changes we want to 2567 // make later anyway so we should go back and fix this then. 2568 if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) { 2569 ParserTraits::ReportMessage(MessageTemplate::kLabelRedeclaration, label); 2570 *ok = false; 2571 return NULL; 2572 } 2573 if (labels == NULL) { 2574 labels = new(zone()) ZoneList<const AstRawString*>(4, zone()); 2575 } 2576 labels->Add(label, zone()); 2577 // Remove the "ghost" variable that turned out to be a label 2578 // from the top scope. This way, we don't try to resolve it 2579 // during the scope processing. 2580 scope_->RemoveUnresolved(var); 2581 Expect(Token::COLON, CHECK_OK); 2582 // ES#sec-labelled-function-declarations Labelled Function Declarations 2583 if (peek() == Token::FUNCTION && is_sloppy(language_mode())) { 2584 if (allow_function == kAllowLabelledFunctionStatement) { 2585 return ParseFunctionDeclaration(ok); 2586 } else { 2587 return ParseScopedStatement(labels, true, ok); 2588 } 2589 } 2590 return ParseStatement(labels, kDisallowLabelledFunctionStatement, ok); 2591 } 2592 2593 // If we have an extension, we allow a native function declaration. 2594 // A native function declaration starts with "native function" with 2595 // no line-terminator between the two words. 2596 if (extension_ != NULL && peek() == Token::FUNCTION && 2597 !scanner()->HasAnyLineTerminatorBeforeNext() && expr != NULL && 2598 expr->AsVariableProxy() != NULL && 2599 expr->AsVariableProxy()->raw_name() == 2600 ast_value_factory()->native_string() && 2601 !scanner()->literal_contains_escapes()) { 2602 return ParseNativeDeclaration(ok); 2603 } 2604 2605 // Parsed expression statement, followed by semicolon. 2606 ExpectSemicolon(CHECK_OK); 2607 return factory()->NewExpressionStatement(expr, pos); 2608 } 2609 2610 2611 IfStatement* Parser::ParseIfStatement(ZoneList<const AstRawString*>* labels, 2612 bool* ok) { 2613 // IfStatement :: 2614 // 'if' '(' Expression ')' Statement ('else' Statement)? 2615 2616 int pos = peek_position(); 2617 Expect(Token::IF, CHECK_OK); 2618 Expect(Token::LPAREN, CHECK_OK); 2619 Expression* condition = ParseExpression(true, CHECK_OK); 2620 Expect(Token::RPAREN, CHECK_OK); 2621 Statement* then_statement = ParseScopedStatement(labels, false, CHECK_OK); 2622 Statement* else_statement = NULL; 2623 if (peek() == Token::ELSE) { 2624 Next(); 2625 else_statement = ParseScopedStatement(labels, false, CHECK_OK); 2626 } else { 2627 else_statement = factory()->NewEmptyStatement(RelocInfo::kNoPosition); 2628 } 2629 return factory()->NewIfStatement( 2630 condition, then_statement, else_statement, pos); 2631 } 2632 2633 2634 Statement* Parser::ParseContinueStatement(bool* ok) { 2635 // ContinueStatement :: 2636 // 'continue' Identifier? ';' 2637 2638 int pos = peek_position(); 2639 Expect(Token::CONTINUE, CHECK_OK); 2640 const AstRawString* label = NULL; 2641 Token::Value tok = peek(); 2642 if (!scanner()->HasAnyLineTerminatorBeforeNext() && 2643 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { 2644 // ECMA allows "eval" or "arguments" as labels even in strict mode. 2645 label = ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK); 2646 } 2647 IterationStatement* target = LookupContinueTarget(label, CHECK_OK); 2648 if (target == NULL) { 2649 // Illegal continue statement. 2650 MessageTemplate::Template message = MessageTemplate::kIllegalContinue; 2651 if (label != NULL) { 2652 message = MessageTemplate::kUnknownLabel; 2653 } 2654 ParserTraits::ReportMessage(message, label); 2655 *ok = false; 2656 return NULL; 2657 } 2658 ExpectSemicolon(CHECK_OK); 2659 return factory()->NewContinueStatement(target, pos); 2660 } 2661 2662 2663 Statement* Parser::ParseBreakStatement(ZoneList<const AstRawString*>* labels, 2664 bool* ok) { 2665 // BreakStatement :: 2666 // 'break' Identifier? ';' 2667 2668 int pos = peek_position(); 2669 Expect(Token::BREAK, CHECK_OK); 2670 const AstRawString* label = NULL; 2671 Token::Value tok = peek(); 2672 if (!scanner()->HasAnyLineTerminatorBeforeNext() && 2673 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { 2674 // ECMA allows "eval" or "arguments" as labels even in strict mode. 2675 label = ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK); 2676 } 2677 // Parse labeled break statements that target themselves into 2678 // empty statements, e.g. 'l1: l2: l3: break l2;' 2679 if (label != NULL && ContainsLabel(labels, label)) { 2680 ExpectSemicolon(CHECK_OK); 2681 return factory()->NewEmptyStatement(pos); 2682 } 2683 BreakableStatement* target = NULL; 2684 target = LookupBreakTarget(label, CHECK_OK); 2685 if (target == NULL) { 2686 // Illegal break statement. 2687 MessageTemplate::Template message = MessageTemplate::kIllegalBreak; 2688 if (label != NULL) { 2689 message = MessageTemplate::kUnknownLabel; 2690 } 2691 ParserTraits::ReportMessage(message, label); 2692 *ok = false; 2693 return NULL; 2694 } 2695 ExpectSemicolon(CHECK_OK); 2696 return factory()->NewBreakStatement(target, pos); 2697 } 2698 2699 2700 Statement* Parser::ParseReturnStatement(bool* ok) { 2701 // ReturnStatement :: 2702 // 'return' Expression? ';' 2703 2704 // Consume the return token. It is necessary to do that before 2705 // reporting any errors on it, because of the way errors are 2706 // reported (underlining). 2707 Expect(Token::RETURN, CHECK_OK); 2708 Scanner::Location loc = scanner()->location(); 2709 function_state_->set_return_location(loc); 2710 2711 Token::Value tok = peek(); 2712 Statement* result; 2713 Expression* return_value; 2714 if (scanner()->HasAnyLineTerminatorBeforeNext() || 2715 tok == Token::SEMICOLON || 2716 tok == Token::RBRACE || 2717 tok == Token::EOS) { 2718 if (IsSubclassConstructor(function_state_->kind())) { 2719 return_value = ThisExpression(scope_, factory(), loc.beg_pos); 2720 } else { 2721 return_value = GetLiteralUndefined(position()); 2722 } 2723 } else { 2724 int pos = peek_position(); 2725 2726 if (IsSubclassConstructor(function_state_->kind())) { 2727 // Because of the return code rewriting that happens in case of a subclass 2728 // constructor we don't want to accept tail calls, therefore we don't set 2729 // ReturnExprScope to kInsideValidReturnStatement here. 2730 return_value = ParseExpression(true, CHECK_OK); 2731 2732 // For subclass constructors we need to return this in case of undefined 2733 // return a Smi (transformed into an exception in the ConstructStub) 2734 // for a non object. 2735 // 2736 // return expr; 2737 // 2738 // Is rewritten as: 2739 // 2740 // return (temp = expr) === undefined ? this : 2741 // %_IsJSReceiver(temp) ? temp : 1; 2742 2743 // temp = expr 2744 Variable* temp = scope_->NewTemporary( 2745 ast_value_factory()->empty_string()); 2746 Assignment* assign = factory()->NewAssignment( 2747 Token::ASSIGN, factory()->NewVariableProxy(temp), return_value, pos); 2748 2749 // %_IsJSReceiver(temp) 2750 ZoneList<Expression*>* is_spec_object_args = 2751 new (zone()) ZoneList<Expression*>(1, zone()); 2752 is_spec_object_args->Add(factory()->NewVariableProxy(temp), zone()); 2753 Expression* is_spec_object_call = factory()->NewCallRuntime( 2754 Runtime::kInlineIsJSReceiver, is_spec_object_args, pos); 2755 2756 // %_IsJSReceiver(temp) ? temp : 1; 2757 Expression* is_object_conditional = factory()->NewConditional( 2758 is_spec_object_call, factory()->NewVariableProxy(temp), 2759 factory()->NewSmiLiteral(1, pos), pos); 2760 2761 // temp === undefined 2762 Expression* is_undefined = factory()->NewCompareOperation( 2763 Token::EQ_STRICT, assign, 2764 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition), pos); 2765 2766 // is_undefined ? this : is_object_conditional 2767 return_value = factory()->NewConditional( 2768 is_undefined, ThisExpression(scope_, factory(), pos), 2769 is_object_conditional, pos); 2770 } else { 2771 ReturnExprScope maybe_allow_tail_calls( 2772 function_state_, ReturnExprContext::kInsideValidReturnStatement); 2773 return_value = ParseExpression(true, CHECK_OK); 2774 2775 if (allow_tailcalls() && !is_sloppy(language_mode()) && !is_resumable()) { 2776 // ES6 14.6.1 Static Semantics: IsInTailPosition 2777 function_state_->AddImplicitTailCallExpression(return_value); 2778 } 2779 } 2780 } 2781 ExpectSemicolon(CHECK_OK); 2782 2783 if (is_generator()) { 2784 return_value = BuildIteratorResult(return_value, true); 2785 } else if (is_async_function()) { 2786 return_value = BuildPromiseResolve(return_value, return_value->position()); 2787 } 2788 2789 result = factory()->NewReturnStatement(return_value, loc.beg_pos); 2790 2791 Scope* decl_scope = scope_->DeclarationScope(); 2792 if (decl_scope->is_script_scope() || decl_scope->is_eval_scope()) { 2793 ReportMessageAt(loc, MessageTemplate::kIllegalReturn); 2794 *ok = false; 2795 return NULL; 2796 } 2797 return result; 2798 } 2799 2800 2801 Statement* Parser::ParseWithStatement(ZoneList<const AstRawString*>* labels, 2802 bool* ok) { 2803 // WithStatement :: 2804 // 'with' '(' Expression ')' Statement 2805 2806 Expect(Token::WITH, CHECK_OK); 2807 int pos = position(); 2808 2809 if (is_strict(language_mode())) { 2810 ReportMessage(MessageTemplate::kStrictWith); 2811 *ok = false; 2812 return NULL; 2813 } 2814 2815 Expect(Token::LPAREN, CHECK_OK); 2816 Expression* expr = ParseExpression(true, CHECK_OK); 2817 Expect(Token::RPAREN, CHECK_OK); 2818 2819 Scope* with_scope = NewScope(scope_, WITH_SCOPE); 2820 Statement* body; 2821 { BlockState block_state(&scope_, with_scope); 2822 with_scope->set_start_position(scanner()->peek_location().beg_pos); 2823 body = ParseScopedStatement(labels, true, CHECK_OK); 2824 with_scope->set_end_position(scanner()->location().end_pos); 2825 } 2826 return factory()->NewWithStatement(with_scope, expr, body, pos); 2827 } 2828 2829 2830 CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) { 2831 // CaseClause :: 2832 // 'case' Expression ':' StatementList 2833 // 'default' ':' StatementList 2834 2835 Expression* label = NULL; // NULL expression indicates default case 2836 if (peek() == Token::CASE) { 2837 Expect(Token::CASE, CHECK_OK); 2838 label = ParseExpression(true, CHECK_OK); 2839 } else { 2840 Expect(Token::DEFAULT, CHECK_OK); 2841 if (*default_seen_ptr) { 2842 ReportMessage(MessageTemplate::kMultipleDefaultsInSwitch); 2843 *ok = false; 2844 return NULL; 2845 } 2846 *default_seen_ptr = true; 2847 } 2848 Expect(Token::COLON, CHECK_OK); 2849 int pos = position(); 2850 ZoneList<Statement*>* statements = 2851 new(zone()) ZoneList<Statement*>(5, zone()); 2852 Statement* stat = NULL; 2853 while (peek() != Token::CASE && 2854 peek() != Token::DEFAULT && 2855 peek() != Token::RBRACE) { 2856 stat = ParseStatementListItem(CHECK_OK); 2857 statements->Add(stat, zone()); 2858 } 2859 return factory()->NewCaseClause(label, statements, pos); 2860 } 2861 2862 2863 Statement* Parser::ParseSwitchStatement(ZoneList<const AstRawString*>* labels, 2864 bool* ok) { 2865 // SwitchStatement :: 2866 // 'switch' '(' Expression ')' '{' CaseClause* '}' 2867 // In order to get the CaseClauses to execute in their own lexical scope, 2868 // but without requiring downstream code to have special scope handling 2869 // code for switch statements, desugar into blocks as follows: 2870 // { // To group the statements--harmless to evaluate Expression in scope 2871 // .tag_variable = Expression; 2872 // { // To give CaseClauses a scope 2873 // switch (.tag_variable) { CaseClause* } 2874 // } 2875 // } 2876 2877 Block* switch_block = 2878 factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition); 2879 int switch_pos = peek_position(); 2880 2881 Expect(Token::SWITCH, CHECK_OK); 2882 Expect(Token::LPAREN, CHECK_OK); 2883 Expression* tag = ParseExpression(true, CHECK_OK); 2884 Expect(Token::RPAREN, CHECK_OK); 2885 2886 Variable* tag_variable = 2887 scope_->NewTemporary(ast_value_factory()->dot_switch_tag_string()); 2888 Assignment* tag_assign = factory()->NewAssignment( 2889 Token::ASSIGN, factory()->NewVariableProxy(tag_variable), tag, 2890 tag->position()); 2891 Statement* tag_statement = 2892 factory()->NewExpressionStatement(tag_assign, RelocInfo::kNoPosition); 2893 switch_block->statements()->Add(tag_statement, zone()); 2894 2895 // make statement: undefined; 2896 // This is needed so the tag isn't returned as the value, in case the switch 2897 // statements don't have a value. 2898 switch_block->statements()->Add( 2899 factory()->NewExpressionStatement( 2900 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition), 2901 RelocInfo::kNoPosition), 2902 zone()); 2903 2904 Block* cases_block = 2905 factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition); 2906 Scope* cases_scope = NewScope(scope_, BLOCK_SCOPE); 2907 cases_scope->SetNonlinear(); 2908 2909 SwitchStatement* switch_statement = 2910 factory()->NewSwitchStatement(labels, switch_pos); 2911 2912 cases_scope->set_start_position(scanner()->location().beg_pos); 2913 { 2914 BlockState cases_block_state(&scope_, cases_scope); 2915 Target target(&this->target_stack_, switch_statement); 2916 2917 Expression* tag_read = factory()->NewVariableProxy(tag_variable); 2918 2919 bool default_seen = false; 2920 ZoneList<CaseClause*>* cases = 2921 new (zone()) ZoneList<CaseClause*>(4, zone()); 2922 Expect(Token::LBRACE, CHECK_OK); 2923 while (peek() != Token::RBRACE) { 2924 CaseClause* clause = ParseCaseClause(&default_seen, CHECK_OK); 2925 cases->Add(clause, zone()); 2926 } 2927 switch_statement->Initialize(tag_read, cases); 2928 cases_block->statements()->Add(switch_statement, zone()); 2929 } 2930 Expect(Token::RBRACE, CHECK_OK); 2931 2932 cases_scope->set_end_position(scanner()->location().end_pos); 2933 cases_scope = cases_scope->FinalizeBlockScope(); 2934 cases_block->set_scope(cases_scope); 2935 2936 switch_block->statements()->Add(cases_block, zone()); 2937 2938 return switch_block; 2939 } 2940 2941 2942 Statement* Parser::ParseThrowStatement(bool* ok) { 2943 // ThrowStatement :: 2944 // 'throw' Expression ';' 2945 2946 Expect(Token::THROW, CHECK_OK); 2947 int pos = position(); 2948 if (scanner()->HasAnyLineTerminatorBeforeNext()) { 2949 ReportMessage(MessageTemplate::kNewlineAfterThrow); 2950 *ok = false; 2951 return NULL; 2952 } 2953 Expression* exception = ParseExpression(true, CHECK_OK); 2954 ExpectSemicolon(CHECK_OK); 2955 2956 return factory()->NewExpressionStatement( 2957 factory()->NewThrow(exception, pos), pos); 2958 } 2959 2960 2961 TryStatement* Parser::ParseTryStatement(bool* ok) { 2962 // TryStatement :: 2963 // 'try' Block Catch 2964 // 'try' Block Finally 2965 // 'try' Block Catch Finally 2966 // 2967 // Catch :: 2968 // 'catch' '(' Identifier ')' Block 2969 // 2970 // Finally :: 2971 // 'finally' Block 2972 2973 Expect(Token::TRY, CHECK_OK); 2974 int pos = position(); 2975 2976 Block* try_block; 2977 { 2978 ReturnExprScope no_tail_calls(function_state_, 2979 ReturnExprContext::kInsideTryBlock); 2980 try_block = ParseBlock(NULL, CHECK_OK); 2981 } 2982 2983 Token::Value tok = peek(); 2984 if (tok != Token::CATCH && tok != Token::FINALLY) { 2985 ReportMessage(MessageTemplate::kNoCatchOrFinally); 2986 *ok = false; 2987 return NULL; 2988 } 2989 2990 Scope* catch_scope = NULL; 2991 Variable* catch_variable = NULL; 2992 Block* catch_block = NULL; 2993 TailCallExpressionList tail_call_expressions_in_catch_block(zone()); 2994 if (tok == Token::CATCH) { 2995 Consume(Token::CATCH); 2996 2997 Expect(Token::LPAREN, CHECK_OK); 2998 catch_scope = NewScope(scope_, CATCH_SCOPE); 2999 catch_scope->set_start_position(scanner()->location().beg_pos); 3000 3001 { 3002 CollectExpressionsInTailPositionToListScope 3003 collect_tail_call_expressions_scope( 3004 function_state_, &tail_call_expressions_in_catch_block); 3005 BlockState block_state(&scope_, catch_scope); 3006 3007 catch_block = 3008 factory()->NewBlock(nullptr, 16, false, RelocInfo::kNoPosition); 3009 3010 // Create a block scope to hold any lexical declarations created 3011 // as part of destructuring the catch parameter. 3012 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE); 3013 block_scope->set_start_position(scanner()->location().beg_pos); 3014 { 3015 BlockState block_state(&scope_, block_scope); 3016 Target target(&this->target_stack_, catch_block); 3017 3018 ExpressionClassifier pattern_classifier(this); 3019 Expression* pattern = 3020 ParsePrimaryExpression(&pattern_classifier, CHECK_OK); 3021 ValidateBindingPattern(&pattern_classifier, CHECK_OK); 3022 3023 const AstRawString* name = ast_value_factory()->dot_catch_string(); 3024 bool is_simple = pattern->IsVariableProxy(); 3025 if (is_simple) { 3026 auto proxy = pattern->AsVariableProxy(); 3027 scope_->RemoveUnresolved(proxy); 3028 name = proxy->raw_name(); 3029 } 3030 catch_variable = catch_scope->DeclareLocal( 3031 name, VAR, kCreatedInitialized, Variable::NORMAL); 3032 3033 Expect(Token::RPAREN, CHECK_OK); 3034 3035 if (!is_simple) { 3036 DeclarationDescriptor descriptor; 3037 descriptor.declaration_kind = DeclarationDescriptor::NORMAL; 3038 descriptor.parser = this; 3039 descriptor.scope = scope_; 3040 descriptor.hoist_scope = nullptr; 3041 descriptor.mode = LET; 3042 descriptor.declaration_pos = pattern->position(); 3043 descriptor.initialization_pos = pattern->position(); 3044 3045 // Initializer position for variables declared by the pattern. 3046 const int initializer_position = position(); 3047 3048 DeclarationParsingResult::Declaration decl( 3049 pattern, initializer_position, 3050 factory()->NewVariableProxy(catch_variable)); 3051 3052 Block* init_block = 3053 factory()->NewBlock(nullptr, 8, true, RelocInfo::kNoPosition); 3054 PatternRewriter::DeclareAndInitializeVariables( 3055 init_block, &descriptor, &decl, nullptr, CHECK_OK); 3056 catch_block->statements()->Add(init_block, zone()); 3057 } 3058 3059 // TODO(adamk): This should call ParseBlock in order to properly 3060 // add an additional block scope for the catch body. 3061 Expect(Token::LBRACE, CHECK_OK); 3062 while (peek() != Token::RBRACE) { 3063 Statement* stat = ParseStatementListItem(CHECK_OK); 3064 if (stat && !stat->IsEmpty()) { 3065 catch_block->statements()->Add(stat, zone()); 3066 } 3067 } 3068 Consume(Token::RBRACE); 3069 } 3070 block_scope->set_end_position(scanner()->location().end_pos); 3071 block_scope = block_scope->FinalizeBlockScope(); 3072 catch_block->set_scope(block_scope); 3073 } 3074 3075 catch_scope->set_end_position(scanner()->location().end_pos); 3076 tok = peek(); 3077 } 3078 3079 Block* finally_block = NULL; 3080 DCHECK(tok == Token::FINALLY || catch_block != NULL); 3081 if (tok == Token::FINALLY) { 3082 Consume(Token::FINALLY); 3083 finally_block = ParseBlock(NULL, CHECK_OK); 3084 } 3085 3086 // Simplify the AST nodes by converting: 3087 // 'try B0 catch B1 finally B2' 3088 // to: 3089 // 'try { try B0 catch B1 } finally B2' 3090 3091 if (catch_block != NULL && finally_block != NULL) { 3092 // If we have both, create an inner try/catch. 3093 DCHECK(catch_scope != NULL && catch_variable != NULL); 3094 TryCatchStatement* statement = 3095 factory()->NewTryCatchStatement(try_block, catch_scope, catch_variable, 3096 catch_block, RelocInfo::kNoPosition); 3097 try_block = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition); 3098 try_block->statements()->Add(statement, zone()); 3099 catch_block = NULL; // Clear to indicate it's been handled. 3100 } 3101 3102 TryStatement* result = NULL; 3103 if (catch_block != NULL) { 3104 // For a try-catch construct append return expressions from the catch block 3105 // to the list of return expressions. 3106 function_state_->tail_call_expressions().Append( 3107 tail_call_expressions_in_catch_block); 3108 3109 DCHECK(finally_block == NULL); 3110 DCHECK(catch_scope != NULL && catch_variable != NULL); 3111 result = factory()->NewTryCatchStatement(try_block, catch_scope, 3112 catch_variable, catch_block, pos); 3113 } else { 3114 if (FLAG_harmony_explicit_tailcalls && 3115 tail_call_expressions_in_catch_block.has_explicit_tail_calls()) { 3116 // TODO(ishell): update chapter number. 3117 // ES8 XX.YY.ZZ 3118 ReportMessageAt(tail_call_expressions_in_catch_block.location(), 3119 MessageTemplate::kUnexpectedTailCallInCatchBlock); 3120 *ok = false; 3121 return NULL; 3122 } 3123 DCHECK(finally_block != NULL); 3124 result = factory()->NewTryFinallyStatement(try_block, finally_block, pos); 3125 } 3126 3127 return result; 3128 } 3129 3130 3131 DoWhileStatement* Parser::ParseDoWhileStatement( 3132 ZoneList<const AstRawString*>* labels, bool* ok) { 3133 // DoStatement :: 3134 // 'do' Statement 'while' '(' Expression ')' ';' 3135 3136 DoWhileStatement* loop = 3137 factory()->NewDoWhileStatement(labels, peek_position()); 3138 Target target(&this->target_stack_, loop); 3139 3140 Expect(Token::DO, CHECK_OK); 3141 Statement* body = ParseScopedStatement(NULL, true, CHECK_OK); 3142 Expect(Token::WHILE, CHECK_OK); 3143 Expect(Token::LPAREN, CHECK_OK); 3144 3145 Expression* cond = ParseExpression(true, CHECK_OK); 3146 Expect(Token::RPAREN, CHECK_OK); 3147 3148 // Allow do-statements to be terminated with and without 3149 // semi-colons. This allows code such as 'do;while(0)return' to 3150 // parse, which would not be the case if we had used the 3151 // ExpectSemicolon() functionality here. 3152 if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON); 3153 3154 if (loop != NULL) loop->Initialize(cond, body); 3155 return loop; 3156 } 3157 3158 3159 WhileStatement* Parser::ParseWhileStatement( 3160 ZoneList<const AstRawString*>* labels, bool* ok) { 3161 // WhileStatement :: 3162 // 'while' '(' Expression ')' Statement 3163 3164 WhileStatement* loop = factory()->NewWhileStatement(labels, peek_position()); 3165 Target target(&this->target_stack_, loop); 3166 3167 Expect(Token::WHILE, CHECK_OK); 3168 Expect(Token::LPAREN, CHECK_OK); 3169 Expression* cond = ParseExpression(true, CHECK_OK); 3170 Expect(Token::RPAREN, CHECK_OK); 3171 Statement* body = ParseScopedStatement(NULL, true, CHECK_OK); 3172 3173 if (loop != NULL) loop->Initialize(cond, body); 3174 return loop; 3175 } 3176 3177 3178 // !%_IsJSReceiver(result = iterator.next()) && 3179 // %ThrowIteratorResultNotAnObject(result) 3180 Expression* Parser::BuildIteratorNextResult(Expression* iterator, 3181 Variable* result, int pos) { 3182 Expression* next_literal = factory()->NewStringLiteral( 3183 ast_value_factory()->next_string(), RelocInfo::kNoPosition); 3184 Expression* next_property = 3185 factory()->NewProperty(iterator, next_literal, RelocInfo::kNoPosition); 3186 ZoneList<Expression*>* next_arguments = 3187 new (zone()) ZoneList<Expression*>(0, zone()); 3188 Expression* next_call = 3189 factory()->NewCall(next_property, next_arguments, pos); 3190 Expression* result_proxy = factory()->NewVariableProxy(result); 3191 Expression* left = 3192 factory()->NewAssignment(Token::ASSIGN, result_proxy, next_call, pos); 3193 3194 // %_IsJSReceiver(...) 3195 ZoneList<Expression*>* is_spec_object_args = 3196 new (zone()) ZoneList<Expression*>(1, zone()); 3197 is_spec_object_args->Add(left, zone()); 3198 Expression* is_spec_object_call = factory()->NewCallRuntime( 3199 Runtime::kInlineIsJSReceiver, is_spec_object_args, pos); 3200 3201 // %ThrowIteratorResultNotAnObject(result) 3202 Expression* result_proxy_again = factory()->NewVariableProxy(result); 3203 ZoneList<Expression*>* throw_arguments = 3204 new (zone()) ZoneList<Expression*>(1, zone()); 3205 throw_arguments->Add(result_proxy_again, zone()); 3206 Expression* throw_call = factory()->NewCallRuntime( 3207 Runtime::kThrowIteratorResultNotAnObject, throw_arguments, pos); 3208 3209 return factory()->NewBinaryOperation( 3210 Token::AND, 3211 factory()->NewUnaryOperation(Token::NOT, is_spec_object_call, pos), 3212 throw_call, pos); 3213 } 3214 3215 void Parser::InitializeForEachStatement(ForEachStatement* stmt, 3216 Expression* each, Expression* subject, 3217 Statement* body, int each_keyword_pos) { 3218 ForOfStatement* for_of = stmt->AsForOfStatement(); 3219 if (for_of != NULL) { 3220 InitializeForOfStatement(for_of, each, subject, body, each_keyword_pos); 3221 } else { 3222 if (each->IsArrayLiteral() || each->IsObjectLiteral()) { 3223 Variable* temp = 3224 scope_->NewTemporary(ast_value_factory()->empty_string()); 3225 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); 3226 Expression* assign_each = PatternRewriter::RewriteDestructuringAssignment( 3227 this, factory()->NewAssignment(Token::ASSIGN, each, temp_proxy, 3228 RelocInfo::kNoPosition), 3229 scope_); 3230 auto block = 3231 factory()->NewBlock(nullptr, 2, false, RelocInfo::kNoPosition); 3232 block->statements()->Add(factory()->NewExpressionStatement( 3233 assign_each, RelocInfo::kNoPosition), 3234 zone()); 3235 block->statements()->Add(body, zone()); 3236 body = block; 3237 each = factory()->NewVariableProxy(temp); 3238 } 3239 stmt->AsForInStatement()->Initialize(each, subject, body); 3240 } 3241 } 3242 3243 void Parser::InitializeForOfStatement(ForOfStatement* for_of, Expression* each, 3244 Expression* iterable, Statement* body, 3245 int next_result_pos) { 3246 Variable* iterator = 3247 scope_->NewTemporary(ast_value_factory()->dot_iterator_string()); 3248 Variable* result = 3249 scope_->NewTemporary(ast_value_factory()->dot_result_string()); 3250 3251 Expression* assign_iterator; 3252 Expression* next_result; 3253 Expression* result_done; 3254 Expression* assign_each; 3255 3256 int get_iterator_pos = iterable->position(); 3257 3258 // iterator = iterable[Symbol.iterator]() 3259 assign_iterator = factory()->NewAssignment( 3260 Token::ASSIGN, factory()->NewVariableProxy(iterator), 3261 GetIterator(iterable, factory(), get_iterator_pos), iterable->position()); 3262 3263 // !%_IsJSReceiver(result = iterator.next()) && 3264 // %ThrowIteratorResultNotAnObject(result) 3265 { 3266 // result = iterator.next() 3267 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); 3268 next_result = 3269 BuildIteratorNextResult(iterator_proxy, result, next_result_pos); 3270 } 3271 3272 // result.done 3273 { 3274 Expression* done_literal = factory()->NewStringLiteral( 3275 ast_value_factory()->done_string(), RelocInfo::kNoPosition); 3276 Expression* result_proxy = factory()->NewVariableProxy(result); 3277 result_done = factory()->NewProperty(result_proxy, done_literal, 3278 RelocInfo::kNoPosition); 3279 } 3280 3281 // each = result.value 3282 { 3283 Expression* value_literal = factory()->NewStringLiteral( 3284 ast_value_factory()->value_string(), RelocInfo::kNoPosition); 3285 Expression* result_proxy = factory()->NewVariableProxy(result); 3286 Expression* result_value = factory()->NewProperty( 3287 result_proxy, value_literal, RelocInfo::kNoPosition); 3288 assign_each = factory()->NewAssignment(Token::ASSIGN, each, result_value, 3289 RelocInfo::kNoPosition); 3290 if (each->IsArrayLiteral() || each->IsObjectLiteral()) { 3291 assign_each = PatternRewriter::RewriteDestructuringAssignment( 3292 this, assign_each->AsAssignment(), scope_); 3293 } 3294 } 3295 3296 for_of->Initialize(body, iterator, assign_iterator, next_result, result_done, 3297 assign_each); 3298 } 3299 3300 Statement* Parser::DesugarLexicalBindingsInForStatement( 3301 Scope* inner_scope, VariableMode mode, ZoneList<const AstRawString*>* names, 3302 ForStatement* loop, Statement* init, Expression* cond, Statement* next, 3303 Statement* body, bool* ok) { 3304 // ES6 13.7.4.8 specifies that on each loop iteration the let variables are 3305 // copied into a new environment. Moreover, the "next" statement must be 3306 // evaluated not in the environment of the just completed iteration but in 3307 // that of the upcoming one. We achieve this with the following desugaring. 3308 // Extra care is needed to preserve the completion value of the original loop. 3309 // 3310 // We are given a for statement of the form 3311 // 3312 // labels: for (let/const x = i; cond; next) body 3313 // 3314 // and rewrite it as follows. Here we write {{ ... }} for init-blocks, ie., 3315 // blocks whose ignore_completion_value_ flag is set. 3316 // 3317 // { 3318 // let/const x = i; 3319 // temp_x = x; 3320 // first = 1; 3321 // undefined; 3322 // outer: for (;;) { 3323 // let/const x = temp_x; 3324 // {{ if (first == 1) { 3325 // first = 0; 3326 // } else { 3327 // next; 3328 // } 3329 // flag = 1; 3330 // if (!cond) break; 3331 // }} 3332 // labels: for (; flag == 1; flag = 0, temp_x = x) { 3333 // body 3334 // } 3335 // {{ if (flag == 1) // Body used break. 3336 // break; 3337 // }} 3338 // } 3339 // } 3340 3341 DCHECK(names->length() > 0); 3342 ZoneList<Variable*> temps(names->length(), zone()); 3343 3344 Block* outer_block = factory()->NewBlock(NULL, names->length() + 4, false, 3345 RelocInfo::kNoPosition); 3346 3347 // Add statement: let/const x = i. 3348 outer_block->statements()->Add(init, zone()); 3349 3350 const AstRawString* temp_name = ast_value_factory()->dot_for_string(); 3351 3352 // For each lexical variable x: 3353 // make statement: temp_x = x. 3354 for (int i = 0; i < names->length(); i++) { 3355 VariableProxy* proxy = NewUnresolved(names->at(i), LET); 3356 Variable* temp = scope_->NewTemporary(temp_name); 3357 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); 3358 Assignment* assignment = factory()->NewAssignment( 3359 Token::ASSIGN, temp_proxy, proxy, RelocInfo::kNoPosition); 3360 Statement* assignment_statement = factory()->NewExpressionStatement( 3361 assignment, RelocInfo::kNoPosition); 3362 outer_block->statements()->Add(assignment_statement, zone()); 3363 temps.Add(temp, zone()); 3364 } 3365 3366 Variable* first = NULL; 3367 // Make statement: first = 1. 3368 if (next) { 3369 first = scope_->NewTemporary(temp_name); 3370 VariableProxy* first_proxy = factory()->NewVariableProxy(first); 3371 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition); 3372 Assignment* assignment = factory()->NewAssignment( 3373 Token::ASSIGN, first_proxy, const1, RelocInfo::kNoPosition); 3374 Statement* assignment_statement = 3375 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition); 3376 outer_block->statements()->Add(assignment_statement, zone()); 3377 } 3378 3379 // make statement: undefined; 3380 outer_block->statements()->Add( 3381 factory()->NewExpressionStatement( 3382 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition), 3383 RelocInfo::kNoPosition), 3384 zone()); 3385 3386 // Make statement: outer: for (;;) 3387 // Note that we don't actually create the label, or set this loop up as an 3388 // explicit break target, instead handing it directly to those nodes that 3389 // need to know about it. This should be safe because we don't run any code 3390 // in this function that looks up break targets. 3391 ForStatement* outer_loop = 3392 factory()->NewForStatement(NULL, RelocInfo::kNoPosition); 3393 outer_block->statements()->Add(outer_loop, zone()); 3394 outer_block->set_scope(scope_); 3395 3396 Block* inner_block = 3397 factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition); 3398 { 3399 BlockState block_state(&scope_, inner_scope); 3400 3401 Block* ignore_completion_block = factory()->NewBlock( 3402 NULL, names->length() + 3, true, RelocInfo::kNoPosition); 3403 ZoneList<Variable*> inner_vars(names->length(), zone()); 3404 // For each let variable x: 3405 // make statement: let/const x = temp_x. 3406 for (int i = 0; i < names->length(); i++) { 3407 VariableProxy* proxy = NewUnresolved(names->at(i), mode); 3408 Declaration* declaration = factory()->NewVariableDeclaration( 3409 proxy, mode, scope_, RelocInfo::kNoPosition); 3410 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK); 3411 inner_vars.Add(declaration->proxy()->var(), zone()); 3412 VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i)); 3413 Assignment* assignment = factory()->NewAssignment( 3414 Token::INIT, proxy, temp_proxy, RelocInfo::kNoPosition); 3415 Statement* assignment_statement = 3416 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition); 3417 DCHECK(init->position() != RelocInfo::kNoPosition); 3418 proxy->var()->set_initializer_position(init->position()); 3419 ignore_completion_block->statements()->Add(assignment_statement, zone()); 3420 } 3421 3422 // Make statement: if (first == 1) { first = 0; } else { next; } 3423 if (next) { 3424 DCHECK(first); 3425 Expression* compare = NULL; 3426 // Make compare expression: first == 1. 3427 { 3428 Expression* const1 = 3429 factory()->NewSmiLiteral(1, RelocInfo::kNoPosition); 3430 VariableProxy* first_proxy = factory()->NewVariableProxy(first); 3431 compare = factory()->NewCompareOperation(Token::EQ, first_proxy, const1, 3432 RelocInfo::kNoPosition); 3433 } 3434 Statement* clear_first = NULL; 3435 // Make statement: first = 0. 3436 { 3437 VariableProxy* first_proxy = factory()->NewVariableProxy(first); 3438 Expression* const0 = 3439 factory()->NewSmiLiteral(0, RelocInfo::kNoPosition); 3440 Assignment* assignment = factory()->NewAssignment( 3441 Token::ASSIGN, first_proxy, const0, RelocInfo::kNoPosition); 3442 clear_first = factory()->NewExpressionStatement(assignment, 3443 RelocInfo::kNoPosition); 3444 } 3445 Statement* clear_first_or_next = factory()->NewIfStatement( 3446 compare, clear_first, next, RelocInfo::kNoPosition); 3447 ignore_completion_block->statements()->Add(clear_first_or_next, zone()); 3448 } 3449 3450 Variable* flag = scope_->NewTemporary(temp_name); 3451 // Make statement: flag = 1. 3452 { 3453 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag); 3454 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition); 3455 Assignment* assignment = factory()->NewAssignment( 3456 Token::ASSIGN, flag_proxy, const1, RelocInfo::kNoPosition); 3457 Statement* assignment_statement = 3458 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition); 3459 ignore_completion_block->statements()->Add(assignment_statement, zone()); 3460 } 3461 3462 // Make statement: if (!cond) break. 3463 if (cond) { 3464 Statement* stop = 3465 factory()->NewBreakStatement(outer_loop, RelocInfo::kNoPosition); 3466 Statement* noop = factory()->NewEmptyStatement(RelocInfo::kNoPosition); 3467 ignore_completion_block->statements()->Add( 3468 factory()->NewIfStatement(cond, noop, stop, cond->position()), 3469 zone()); 3470 } 3471 3472 inner_block->statements()->Add(ignore_completion_block, zone()); 3473 // Make cond expression for main loop: flag == 1. 3474 Expression* flag_cond = NULL; 3475 { 3476 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition); 3477 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag); 3478 flag_cond = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1, 3479 RelocInfo::kNoPosition); 3480 } 3481 3482 // Create chain of expressions "flag = 0, temp_x = x, ..." 3483 Statement* compound_next_statement = NULL; 3484 { 3485 Expression* compound_next = NULL; 3486 // Make expression: flag = 0. 3487 { 3488 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag); 3489 Expression* const0 = 3490 factory()->NewSmiLiteral(0, RelocInfo::kNoPosition); 3491 compound_next = factory()->NewAssignment( 3492 Token::ASSIGN, flag_proxy, const0, RelocInfo::kNoPosition); 3493 } 3494 3495 // Make the comma-separated list of temp_x = x assignments. 3496 int inner_var_proxy_pos = scanner()->location().beg_pos; 3497 for (int i = 0; i < names->length(); i++) { 3498 VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i)); 3499 VariableProxy* proxy = 3500 factory()->NewVariableProxy(inner_vars.at(i), inner_var_proxy_pos); 3501 Assignment* assignment = factory()->NewAssignment( 3502 Token::ASSIGN, temp_proxy, proxy, RelocInfo::kNoPosition); 3503 compound_next = factory()->NewBinaryOperation( 3504 Token::COMMA, compound_next, assignment, RelocInfo::kNoPosition); 3505 } 3506 3507 compound_next_statement = factory()->NewExpressionStatement( 3508 compound_next, RelocInfo::kNoPosition); 3509 } 3510 3511 // Make statement: labels: for (; flag == 1; flag = 0, temp_x = x) 3512 // Note that we re-use the original loop node, which retains its labels 3513 // and ensures that any break or continue statements in body point to 3514 // the right place. 3515 loop->Initialize(NULL, flag_cond, compound_next_statement, body); 3516 inner_block->statements()->Add(loop, zone()); 3517 3518 // Make statement: {{if (flag == 1) break;}} 3519 { 3520 Expression* compare = NULL; 3521 // Make compare expresion: flag == 1. 3522 { 3523 Expression* const1 = 3524 factory()->NewSmiLiteral(1, RelocInfo::kNoPosition); 3525 VariableProxy* flag_proxy = factory()->NewVariableProxy(flag); 3526 compare = factory()->NewCompareOperation(Token::EQ, flag_proxy, const1, 3527 RelocInfo::kNoPosition); 3528 } 3529 Statement* stop = 3530 factory()->NewBreakStatement(outer_loop, RelocInfo::kNoPosition); 3531 Statement* empty = factory()->NewEmptyStatement(RelocInfo::kNoPosition); 3532 Statement* if_flag_break = factory()->NewIfStatement( 3533 compare, stop, empty, RelocInfo::kNoPosition); 3534 Block* ignore_completion_block = 3535 factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition); 3536 ignore_completion_block->statements()->Add(if_flag_break, zone()); 3537 inner_block->statements()->Add(ignore_completion_block, zone()); 3538 } 3539 3540 inner_scope->set_end_position(scanner()->location().end_pos); 3541 inner_block->set_scope(inner_scope); 3542 } 3543 3544 outer_loop->Initialize(NULL, NULL, NULL, inner_block); 3545 return outer_block; 3546 } 3547 3548 Statement* Parser::ParseScopedStatement(ZoneList<const AstRawString*>* labels, 3549 bool legacy, bool* ok) { 3550 if (is_strict(language_mode()) || peek() != Token::FUNCTION || 3551 (legacy && allow_harmony_restrictive_declarations())) { 3552 return ParseSubStatement(labels, kDisallowLabelledFunctionStatement, ok); 3553 } else { 3554 if (legacy) { 3555 ++use_counts_[v8::Isolate::kLegacyFunctionDeclaration]; 3556 } 3557 // Make a block around the statement for a lexical binding 3558 // is introduced by a FunctionDeclaration. 3559 Scope* body_scope = NewScope(scope_, BLOCK_SCOPE); 3560 body_scope->set_start_position(scanner()->location().beg_pos); 3561 BlockState block_state(&scope_, body_scope); 3562 Block* block = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition); 3563 Statement* body = ParseFunctionDeclaration(CHECK_OK); 3564 block->statements()->Add(body, zone()); 3565 body_scope->set_end_position(scanner()->location().end_pos); 3566 body_scope = body_scope->FinalizeBlockScope(); 3567 block->set_scope(body_scope); 3568 return block; 3569 } 3570 } 3571 3572 Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels, 3573 bool* ok) { 3574 int stmt_pos = peek_position(); 3575 Statement* init = NULL; 3576 ZoneList<const AstRawString*> lexical_bindings(1, zone()); 3577 3578 // Create an in-between scope for let-bound iteration variables. 3579 Scope* for_scope = NewScope(scope_, BLOCK_SCOPE); 3580 3581 BlockState block_state(&scope_, for_scope); 3582 Expect(Token::FOR, CHECK_OK); 3583 Expect(Token::LPAREN, CHECK_OK); 3584 for_scope->set_start_position(scanner()->location().beg_pos); 3585 for_scope->set_is_hidden(); 3586 DeclarationParsingResult parsing_result; 3587 if (peek() != Token::SEMICOLON) { 3588 if (peek() == Token::VAR || peek() == Token::CONST || 3589 (peek() == Token::LET && IsNextLetKeyword())) { 3590 ParseVariableDeclarations(kForStatement, &parsing_result, nullptr, 3591 CHECK_OK); 3592 3593 ForEachStatement::VisitMode mode = ForEachStatement::ENUMERATE; 3594 int each_beg_pos = scanner()->location().beg_pos; 3595 int each_end_pos = scanner()->location().end_pos; 3596 3597 if (CheckInOrOf(&mode, ok)) { 3598 if (!*ok) return nullptr; 3599 if (parsing_result.declarations.length() != 1) { 3600 ParserTraits::ReportMessageAt( 3601 parsing_result.bindings_loc, 3602 MessageTemplate::kForInOfLoopMultiBindings, 3603 ForEachStatement::VisitModeString(mode)); 3604 *ok = false; 3605 return nullptr; 3606 } 3607 DeclarationParsingResult::Declaration& decl = 3608 parsing_result.declarations[0]; 3609 if (parsing_result.first_initializer_loc.IsValid() && 3610 (is_strict(language_mode()) || mode == ForEachStatement::ITERATE || 3611 IsLexicalVariableMode(parsing_result.descriptor.mode) || 3612 !decl.pattern->IsVariableProxy() || allow_harmony_for_in())) { 3613 // Only increment the use count if we would have let this through 3614 // without the flag. 3615 if (allow_harmony_for_in()) { 3616 ++use_counts_[v8::Isolate::kForInInitializer]; 3617 } 3618 ParserTraits::ReportMessageAt( 3619 parsing_result.first_initializer_loc, 3620 MessageTemplate::kForInOfLoopInitializer, 3621 ForEachStatement::VisitModeString(mode)); 3622 *ok = false; 3623 return nullptr; 3624 } 3625 3626 Block* init_block = nullptr; 3627 3628 // special case for legacy for (var/const x =.... in) 3629 if (!IsLexicalVariableMode(parsing_result.descriptor.mode) && 3630 decl.pattern->IsVariableProxy() && decl.initializer != nullptr) { 3631 DCHECK(!allow_harmony_for_in()); 3632 ++use_counts_[v8::Isolate::kForInInitializer]; 3633 const AstRawString* name = 3634 decl.pattern->AsVariableProxy()->raw_name(); 3635 VariableProxy* single_var = scope_->NewUnresolved( 3636 factory(), name, Variable::NORMAL, each_beg_pos, each_end_pos); 3637 init_block = factory()->NewBlock( 3638 nullptr, 2, true, parsing_result.descriptor.declaration_pos); 3639 init_block->statements()->Add( 3640 factory()->NewExpressionStatement( 3641 factory()->NewAssignment(Token::ASSIGN, single_var, 3642 decl.initializer, 3643 RelocInfo::kNoPosition), 3644 RelocInfo::kNoPosition), 3645 zone()); 3646 } 3647 3648 // Rewrite a for-in/of statement of the form 3649 // 3650 // for (let/const/var x in/of e) b 3651 // 3652 // into 3653 // 3654 // { 3655 // <let x' be a temporary variable> 3656 // for (x' in/of e) { 3657 // let/const/var x; 3658 // x = x'; 3659 // b; 3660 // } 3661 // let x; // for TDZ 3662 // } 3663 3664 Variable* temp = 3665 scope_->NewTemporary(ast_value_factory()->dot_for_string()); 3666 ForEachStatement* loop = 3667 factory()->NewForEachStatement(mode, labels, stmt_pos); 3668 Target target(&this->target_stack_, loop); 3669 3670 int each_keyword_position = scanner()->location().beg_pos; 3671 3672 Expression* enumerable; 3673 if (mode == ForEachStatement::ITERATE) { 3674 ExpressionClassifier classifier(this); 3675 enumerable = ParseAssignmentExpression(true, &classifier, CHECK_OK); 3676 RewriteNonPattern(&classifier, CHECK_OK); 3677 } else { 3678 enumerable = ParseExpression(true, CHECK_OK); 3679 } 3680 3681 Expect(Token::RPAREN, CHECK_OK); 3682 3683 Scope* body_scope = NewScope(scope_, BLOCK_SCOPE); 3684 body_scope->set_start_position(scanner()->location().beg_pos); 3685 3686 Block* body_block = 3687 factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition); 3688 3689 { 3690 ReturnExprScope no_tail_calls(function_state_, 3691 ReturnExprContext::kInsideForInOfBody); 3692 BlockState block_state(&scope_, body_scope); 3693 3694 Statement* body = ParseScopedStatement(NULL, true, CHECK_OK); 3695 3696 auto each_initialization_block = 3697 factory()->NewBlock(nullptr, 1, true, RelocInfo::kNoPosition); 3698 { 3699 auto descriptor = parsing_result.descriptor; 3700 descriptor.declaration_pos = RelocInfo::kNoPosition; 3701 descriptor.initialization_pos = RelocInfo::kNoPosition; 3702 decl.initializer = factory()->NewVariableProxy(temp); 3703 3704 PatternRewriter::DeclareAndInitializeVariables( 3705 each_initialization_block, &descriptor, &decl, 3706 IsLexicalVariableMode(descriptor.mode) ? &lexical_bindings 3707 : nullptr, 3708 CHECK_OK); 3709 } 3710 3711 body_block->statements()->Add(each_initialization_block, zone()); 3712 body_block->statements()->Add(body, zone()); 3713 VariableProxy* temp_proxy = 3714 factory()->NewVariableProxy(temp, each_beg_pos, each_end_pos); 3715 InitializeForEachStatement(loop, temp_proxy, enumerable, body_block, 3716 each_keyword_position); 3717 } 3718 body_scope->set_end_position(scanner()->location().end_pos); 3719 body_scope = body_scope->FinalizeBlockScope(); 3720 body_block->set_scope(body_scope); 3721 3722 // Create a TDZ for any lexically-bound names. 3723 if (IsLexicalVariableMode(parsing_result.descriptor.mode)) { 3724 DCHECK_NULL(init_block); 3725 3726 init_block = 3727 factory()->NewBlock(nullptr, 1, false, RelocInfo::kNoPosition); 3728 3729 for (int i = 0; i < lexical_bindings.length(); ++i) { 3730 // TODO(adamk): This needs to be some sort of special 3731 // INTERNAL variable that's invisible to the debugger 3732 // but visible to everything else. 3733 VariableProxy* tdz_proxy = 3734 NewUnresolved(lexical_bindings[i], LET); 3735 Declaration* tdz_decl = factory()->NewVariableDeclaration( 3736 tdz_proxy, LET, scope_, RelocInfo::kNoPosition); 3737 Variable* tdz_var = Declare( 3738 tdz_decl, DeclarationDescriptor::NORMAL, true, CHECK_OK); 3739 tdz_var->set_initializer_position(position()); 3740 } 3741 } 3742 3743 Statement* final_loop = loop->IsForOfStatement() 3744 ? FinalizeForOfStatement( 3745 loop->AsForOfStatement(), RelocInfo::kNoPosition) 3746 : loop; 3747 3748 for_scope->set_end_position(scanner()->location().end_pos); 3749 for_scope = for_scope->FinalizeBlockScope(); 3750 // Parsed for-in loop w/ variable declarations. 3751 if (init_block != nullptr) { 3752 init_block->statements()->Add(final_loop, zone()); 3753 init_block->set_scope(for_scope); 3754 return init_block; 3755 } else { 3756 DCHECK_NULL(for_scope); 3757 return final_loop; 3758 } 3759 } else { 3760 init = parsing_result.BuildInitializationBlock( 3761 IsLexicalVariableMode(parsing_result.descriptor.mode) 3762 ? &lexical_bindings 3763 : nullptr, 3764 CHECK_OK); 3765 } 3766 } else { 3767 int lhs_beg_pos = peek_position(); 3768 ExpressionClassifier classifier(this); 3769 Expression* expression = ParseExpression(false, &classifier, CHECK_OK); 3770 int lhs_end_pos = scanner()->location().end_pos; 3771 ForEachStatement::VisitMode mode = ForEachStatement::ENUMERATE; 3772 3773 bool is_for_each = CheckInOrOf(&mode, ok); 3774 if (!*ok) return nullptr; 3775 bool is_destructuring = is_for_each && (expression->IsArrayLiteral() || 3776 expression->IsObjectLiteral()); 3777 3778 if (is_destructuring) { 3779 ValidateAssignmentPattern(&classifier, CHECK_OK); 3780 } else { 3781 RewriteNonPattern(&classifier, CHECK_OK); 3782 } 3783 3784 if (is_for_each) { 3785 if (!is_destructuring) { 3786 expression = this->CheckAndRewriteReferenceExpression( 3787 expression, lhs_beg_pos, lhs_end_pos, 3788 MessageTemplate::kInvalidLhsInFor, kSyntaxError, CHECK_OK); 3789 } 3790 3791 ForEachStatement* loop = 3792 factory()->NewForEachStatement(mode, labels, stmt_pos); 3793 Target target(&this->target_stack_, loop); 3794 3795 int each_keyword_position = scanner()->location().beg_pos; 3796 3797 Expression* enumerable; 3798 if (mode == ForEachStatement::ITERATE) { 3799 ExpressionClassifier classifier(this); 3800 enumerable = ParseAssignmentExpression(true, &classifier, CHECK_OK); 3801 RewriteNonPattern(&classifier, CHECK_OK); 3802 } else { 3803 enumerable = ParseExpression(true, CHECK_OK); 3804 } 3805 3806 Expect(Token::RPAREN, CHECK_OK); 3807 3808 // For legacy compat reasons, give for loops similar treatment to 3809 // if statements in allowing a function declaration for a body 3810 Statement* body = ParseScopedStatement(NULL, true, CHECK_OK); 3811 InitializeForEachStatement(loop, expression, enumerable, body, 3812 each_keyword_position); 3813 3814 Statement* final_loop = loop->IsForOfStatement() 3815 ? FinalizeForOfStatement( 3816 loop->AsForOfStatement(), RelocInfo::kNoPosition) 3817 : loop; 3818 3819 for_scope->set_end_position(scanner()->location().end_pos); 3820 for_scope = for_scope->FinalizeBlockScope(); 3821 DCHECK(for_scope == nullptr); 3822 return final_loop; 3823 3824 } else { 3825 init = factory()->NewExpressionStatement(expression, lhs_beg_pos); 3826 } 3827 } 3828 } 3829 3830 // Standard 'for' loop 3831 ForStatement* loop = factory()->NewForStatement(labels, stmt_pos); 3832 Target target(&this->target_stack_, loop); 3833 3834 // Parsed initializer at this point. 3835 Expect(Token::SEMICOLON, CHECK_OK); 3836 3837 Expression* cond = NULL; 3838 Statement* next = NULL; 3839 Statement* body = NULL; 3840 3841 // If there are let bindings, then condition and the next statement of the 3842 // for loop must be parsed in a new scope. 3843 Scope* inner_scope = scope_; 3844 if (lexical_bindings.length() > 0) { 3845 inner_scope = NewScope(for_scope, BLOCK_SCOPE); 3846 inner_scope->set_start_position(scanner()->location().beg_pos); 3847 } 3848 { 3849 BlockState block_state(&scope_, inner_scope); 3850 3851 if (peek() != Token::SEMICOLON) { 3852 cond = ParseExpression(true, CHECK_OK); 3853 } 3854 Expect(Token::SEMICOLON, CHECK_OK); 3855 3856 if (peek() != Token::RPAREN) { 3857 Expression* exp = ParseExpression(true, CHECK_OK); 3858 next = factory()->NewExpressionStatement(exp, exp->position()); 3859 } 3860 Expect(Token::RPAREN, CHECK_OK); 3861 3862 body = ParseScopedStatement(NULL, true, CHECK_OK); 3863 } 3864 3865 Statement* result = NULL; 3866 if (lexical_bindings.length() > 0) { 3867 BlockState block_state(&scope_, for_scope); 3868 result = DesugarLexicalBindingsInForStatement( 3869 inner_scope, parsing_result.descriptor.mode, &lexical_bindings, loop, 3870 init, cond, next, body, CHECK_OK); 3871 for_scope->set_end_position(scanner()->location().end_pos); 3872 } else { 3873 for_scope->set_end_position(scanner()->location().end_pos); 3874 for_scope = for_scope->FinalizeBlockScope(); 3875 if (for_scope) { 3876 // Rewrite a for statement of the form 3877 // for (const x = i; c; n) b 3878 // 3879 // into 3880 // 3881 // { 3882 // const x = i; 3883 // for (; c; n) b 3884 // } 3885 // 3886 // or, desugar 3887 // for (; c; n) b 3888 // into 3889 // { 3890 // for (; c; n) b 3891 // } 3892 // just in case b introduces a lexical binding some other way, e.g., if b 3893 // is a FunctionDeclaration. 3894 Block* block = 3895 factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition); 3896 if (init != nullptr) { 3897 block->statements()->Add(init, zone()); 3898 } 3899 block->statements()->Add(loop, zone()); 3900 block->set_scope(for_scope); 3901 loop->Initialize(NULL, cond, next, body); 3902 result = block; 3903 } else { 3904 loop->Initialize(init, cond, next, body); 3905 result = loop; 3906 } 3907 } 3908 return result; 3909 } 3910 3911 3912 DebuggerStatement* Parser::ParseDebuggerStatement(bool* ok) { 3913 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser 3914 // contexts this is used as a statement which invokes the debugger as i a 3915 // break point is present. 3916 // DebuggerStatement :: 3917 // 'debugger' ';' 3918 3919 int pos = peek_position(); 3920 Expect(Token::DEBUGGER, CHECK_OK); 3921 ExpectSemicolon(CHECK_OK); 3922 return factory()->NewDebuggerStatement(pos); 3923 } 3924 3925 3926 bool CompileTimeValue::IsCompileTimeValue(Expression* expression) { 3927 if (expression->IsLiteral()) return true; 3928 MaterializedLiteral* lit = expression->AsMaterializedLiteral(); 3929 return lit != NULL && lit->is_simple(); 3930 } 3931 3932 3933 Handle<FixedArray> CompileTimeValue::GetValue(Isolate* isolate, 3934 Expression* expression) { 3935 Factory* factory = isolate->factory(); 3936 DCHECK(IsCompileTimeValue(expression)); 3937 Handle<FixedArray> result = factory->NewFixedArray(2, TENURED); 3938 ObjectLiteral* object_literal = expression->AsObjectLiteral(); 3939 if (object_literal != NULL) { 3940 DCHECK(object_literal->is_simple()); 3941 if (object_literal->fast_elements()) { 3942 result->set(kLiteralTypeSlot, Smi::FromInt(OBJECT_LITERAL_FAST_ELEMENTS)); 3943 } else { 3944 result->set(kLiteralTypeSlot, Smi::FromInt(OBJECT_LITERAL_SLOW_ELEMENTS)); 3945 } 3946 result->set(kElementsSlot, *object_literal->constant_properties()); 3947 } else { 3948 ArrayLiteral* array_literal = expression->AsArrayLiteral(); 3949 DCHECK(array_literal != NULL && array_literal->is_simple()); 3950 result->set(kLiteralTypeSlot, Smi::FromInt(ARRAY_LITERAL)); 3951 result->set(kElementsSlot, *array_literal->constant_elements()); 3952 } 3953 return result; 3954 } 3955 3956 3957 CompileTimeValue::LiteralType CompileTimeValue::GetLiteralType( 3958 Handle<FixedArray> value) { 3959 Smi* literal_type = Smi::cast(value->get(kLiteralTypeSlot)); 3960 return static_cast<LiteralType>(literal_type->value()); 3961 } 3962 3963 3964 Handle<FixedArray> CompileTimeValue::GetElements(Handle<FixedArray> value) { 3965 return Handle<FixedArray>(FixedArray::cast(value->get(kElementsSlot))); 3966 } 3967 3968 void ParserTraits::ParseArrowFunctionFormalParameters( 3969 ParserFormalParameters* parameters, Expression* expr, int end_pos, 3970 bool* ok) { 3971 // ArrowFunctionFormals :: 3972 // Binary(Token::COMMA, NonTailArrowFunctionFormals, Tail) 3973 // Tail 3974 // NonTailArrowFunctionFormals :: 3975 // Binary(Token::COMMA, NonTailArrowFunctionFormals, VariableProxy) 3976 // VariableProxy 3977 // Tail :: 3978 // VariableProxy 3979 // Spread(VariableProxy) 3980 // 3981 // As we need to visit the parameters in left-to-right order, we recurse on 3982 // the left-hand side of comma expressions. 3983 // 3984 if (expr->IsBinaryOperation()) { 3985 BinaryOperation* binop = expr->AsBinaryOperation(); 3986 // The classifier has already run, so we know that the expression is a valid 3987 // arrow function formals production. 3988 DCHECK_EQ(binop->op(), Token::COMMA); 3989 Expression* left = binop->left(); 3990 Expression* right = binop->right(); 3991 int comma_pos = binop->position(); 3992 ParseArrowFunctionFormalParameters(parameters, left, comma_pos, ok); 3993 if (!*ok) return; 3994 // LHS of comma expression should be unparenthesized. 3995 expr = right; 3996 } 3997 3998 // Only the right-most expression may be a rest parameter. 3999 DCHECK(!parameters->has_rest); 4000 4001 bool is_rest = expr->IsSpread(); 4002 if (is_rest) { 4003 expr = expr->AsSpread()->expression(); 4004 parameters->has_rest = true; 4005 } 4006 if (parameters->is_simple) { 4007 parameters->is_simple = !is_rest && expr->IsVariableProxy(); 4008 } 4009 4010 Expression* initializer = nullptr; 4011 if (expr->IsVariableProxy()) { 4012 // When the formal parameter was originally seen, it was parsed as a 4013 // VariableProxy and recorded as unresolved in the scope. Here we undo that 4014 // parse-time side-effect for parameters that are single-names (not 4015 // patterns; for patterns that happens uniformly in 4016 // PatternRewriter::VisitVariableProxy). 4017 parser_->scope_->RemoveUnresolved(expr->AsVariableProxy()); 4018 } else if (expr->IsAssignment()) { 4019 Assignment* assignment = expr->AsAssignment(); 4020 DCHECK(!assignment->is_compound()); 4021 initializer = assignment->value(); 4022 expr = assignment->target(); 4023 4024 // TODO(adamk): Only call this if necessary. 4025 RewriteParameterInitializerScope(parser_->stack_limit(), initializer, 4026 parser_->scope_, parameters->scope); 4027 } 4028 4029 AddFormalParameter(parameters, expr, initializer, end_pos, is_rest); 4030 } 4031 4032 void ParserTraits::ParseAsyncArrowSingleExpressionBody( 4033 ZoneList<Statement*>* body, bool accept_IN, 4034 Type::ExpressionClassifier* classifier, int pos, bool* ok) { 4035 parser_->DesugarAsyncFunctionBody( 4036 parser_->ast_value_factory()->empty_string(), parser_->scope_, body, 4037 classifier, kAsyncArrowFunction, FunctionBody::SingleExpression, 4038 accept_IN, pos, ok); 4039 } 4040 4041 void Parser::DesugarAsyncFunctionBody(const AstRawString* function_name, 4042 Scope* scope, ZoneList<Statement*>* body, 4043 ExpressionClassifier* classifier, 4044 FunctionKind kind, FunctionBody body_type, 4045 bool accept_IN, int pos, bool* ok) { 4046 // function async_function() { 4047 // try { 4048 // .generator_object = %CreateGeneratorObject(); 4049 // ... function body ... 4050 // } catch (e) { 4051 // return Promise.reject(e); 4052 // } 4053 // } 4054 scope->ForceContextAllocation(); 4055 Variable* temp = 4056 scope_->NewTemporary(ast_value_factory()->dot_generator_object_string()); 4057 function_state_->set_generator_object_variable(temp); 4058 4059 Expression* init_generator_variable = factory()->NewAssignment( 4060 Token::INIT, factory()->NewVariableProxy(temp), 4061 BuildCreateJSGeneratorObject(pos, kind), RelocInfo::kNoPosition); 4062 body->Add(factory()->NewExpressionStatement(init_generator_variable, 4063 RelocInfo::kNoPosition), 4064 zone()); 4065 4066 Block* try_block = factory()->NewBlock(NULL, 8, true, RelocInfo::kNoPosition); 4067 4068 ZoneList<Statement*>* inner_body = try_block->statements(); 4069 4070 Expression* return_value = nullptr; 4071 if (body_type == FunctionBody::Normal) { 4072 ParseStatementList(inner_body, Token::RBRACE, ok); 4073 if (!*ok) return; 4074 return_value = factory()->NewUndefinedLiteral(RelocInfo::kNoPosition); 4075 } else { 4076 return_value = ParseAssignmentExpression(accept_IN, classifier, ok); 4077 if (!*ok) return; 4078 ParserTraits::RewriteNonPattern(classifier, ok); 4079 if (!*ok) return; 4080 } 4081 4082 return_value = BuildPromiseResolve(return_value, return_value->position()); 4083 inner_body->Add( 4084 factory()->NewReturnStatement(return_value, return_value->position()), 4085 zone()); 4086 body->Add(BuildRejectPromiseOnException(try_block), zone()); 4087 scope->set_end_position(scanner()->location().end_pos); 4088 } 4089 4090 DoExpression* Parser::ParseDoExpression(bool* ok) { 4091 // AssignmentExpression :: 4092 // do '{' StatementList '}' 4093 int pos = peek_position(); 4094 4095 Expect(Token::DO, CHECK_OK); 4096 Variable* result = 4097 scope_->NewTemporary(ast_value_factory()->dot_result_string()); 4098 Block* block = ParseBlock(nullptr, false, CHECK_OK); 4099 DoExpression* expr = factory()->NewDoExpression(block, result, pos); 4100 if (!Rewriter::Rewrite(this, expr, ast_value_factory())) { 4101 *ok = false; 4102 return nullptr; 4103 } 4104 block->set_scope(block->scope()->FinalizeBlockScope()); 4105 return expr; 4106 } 4107 4108 4109 void ParserTraits::ParseArrowFunctionFormalParameterList( 4110 ParserFormalParameters* parameters, Expression* expr, 4111 const Scanner::Location& params_loc, 4112 Scanner::Location* duplicate_loc, bool* ok) { 4113 if (expr->IsEmptyParentheses()) return; 4114 4115 ParseArrowFunctionFormalParameters(parameters, expr, params_loc.end_pos, ok); 4116 if (!*ok) return; 4117 4118 if (parameters->Arity() > Code::kMaxArguments) { 4119 ReportMessageAt(params_loc, MessageTemplate::kMalformedArrowFunParamList); 4120 *ok = false; 4121 return; 4122 } 4123 4124 Type::ExpressionClassifier classifier(parser_); 4125 if (!parameters->is_simple) { 4126 classifier.RecordNonSimpleParameter(); 4127 } 4128 for (int i = 0; i < parameters->Arity(); ++i) { 4129 auto parameter = parameters->at(i); 4130 DeclareFormalParameter(parameters->scope, parameter, &classifier); 4131 if (!duplicate_loc->IsValid()) { 4132 *duplicate_loc = classifier.duplicate_formal_parameter_error().location; 4133 } 4134 } 4135 DCHECK_EQ(parameters->is_simple, parameters->scope->has_simple_parameters()); 4136 } 4137 4138 4139 void ParserTraits::ReindexLiterals(const ParserFormalParameters& parameters) { 4140 if (parser_->function_state_->materialized_literal_count() > 0) { 4141 AstLiteralReindexer reindexer; 4142 4143 for (const auto p : parameters.params) { 4144 if (p.pattern != nullptr) reindexer.Reindex(p.pattern); 4145 if (p.initializer != nullptr) reindexer.Reindex(p.initializer); 4146 } 4147 4148 DCHECK(reindexer.count() <= 4149 parser_->function_state_->materialized_literal_count()); 4150 } 4151 } 4152 4153 4154 FunctionLiteral* Parser::ParseFunctionLiteral( 4155 const AstRawString* function_name, Scanner::Location function_name_location, 4156 FunctionNameValidity function_name_validity, FunctionKind kind, 4157 int function_token_pos, FunctionLiteral::FunctionType function_type, 4158 LanguageMode language_mode, bool* ok) { 4159 // Function :: 4160 // '(' FormalParameterList? ')' '{' FunctionBody '}' 4161 // 4162 // Getter :: 4163 // '(' ')' '{' FunctionBody '}' 4164 // 4165 // Setter :: 4166 // '(' PropertySetParameterList ')' '{' FunctionBody '}' 4167 4168 int pos = function_token_pos == RelocInfo::kNoPosition 4169 ? peek_position() : function_token_pos; 4170 4171 bool is_generator = IsGeneratorFunction(kind); 4172 4173 // Anonymous functions were passed either the empty symbol or a null 4174 // handle as the function name. Remember if we were passed a non-empty 4175 // handle to decide whether to invoke function name inference. 4176 bool should_infer_name = function_name == NULL; 4177 4178 // We want a non-null handle as the function name. 4179 if (should_infer_name) { 4180 function_name = ast_value_factory()->empty_string(); 4181 } 4182 4183 Scope* scope = NewScope(scope_, FUNCTION_SCOPE, kind); 4184 SetLanguageMode(scope, language_mode); 4185 ZoneList<Statement*>* body = NULL; 4186 int arity = -1; 4187 int materialized_literal_count = -1; 4188 int expected_property_count = -1; 4189 DuplicateFinder duplicate_finder(scanner()->unicode_cache()); 4190 bool should_be_used_once_hint = false; 4191 bool has_duplicate_parameters; 4192 FunctionLiteral::EagerCompileHint eager_compile_hint; 4193 4194 // Parse function. 4195 { 4196 AstNodeFactory function_factory(ast_value_factory()); 4197 FunctionState function_state(&function_state_, &scope_, scope, kind, 4198 &function_factory); 4199 scope_->SetScopeName(function_name); 4200 ExpressionClassifier formals_classifier(this, &duplicate_finder); 4201 4202 eager_compile_hint = function_state_->this_function_is_parenthesized() 4203 ? FunctionLiteral::kShouldEagerCompile 4204 : FunctionLiteral::kShouldLazyCompile; 4205 4206 if (is_generator) { 4207 // For generators, allocating variables in contexts is currently a win 4208 // because it minimizes the work needed to suspend and resume an 4209 // activation. The machine code produced for generators (by full-codegen) 4210 // relies on this forced context allocation, but not in an essential way. 4211 scope_->ForceContextAllocation(); 4212 4213 // Calling a generator returns a generator object. That object is stored 4214 // in a temporary variable, a definition that is used by "yield" 4215 // expressions. This also marks the FunctionState as a generator. 4216 Variable* temp = scope_->NewTemporary( 4217 ast_value_factory()->dot_generator_object_string()); 4218 function_state.set_generator_object_variable(temp); 4219 } 4220 4221 Expect(Token::LPAREN, CHECK_OK); 4222 int start_position = scanner()->location().beg_pos; 4223 scope_->set_start_position(start_position); 4224 ParserFormalParameters formals(scope); 4225 ParseFormalParameterList(&formals, &formals_classifier, CHECK_OK); 4226 arity = formals.Arity(); 4227 Expect(Token::RPAREN, CHECK_OK); 4228 int formals_end_position = scanner()->location().end_pos; 4229 4230 CheckArityRestrictions(arity, kind, formals.has_rest, start_position, 4231 formals_end_position, CHECK_OK); 4232 Expect(Token::LBRACE, CHECK_OK); 4233 // Don't include the rest parameter into the function's formal parameter 4234 // count (esp. the SharedFunctionInfo::internal_formal_parameter_count, 4235 // which says whether we need to create an arguments adaptor frame). 4236 if (formals.has_rest) arity--; 4237 4238 // Determine if the function can be parsed lazily. Lazy parsing is different 4239 // from lazy compilation; we need to parse more eagerly than we compile. 4240 4241 // We can only parse lazily if we also compile lazily. The heuristics for 4242 // lazy compilation are: 4243 // - It must not have been prohibited by the caller to Parse (some callers 4244 // need a full AST). 4245 // - The outer scope must allow lazy compilation of inner functions. 4246 // - The function mustn't be a function expression with an open parenthesis 4247 // before; we consider that a hint that the function will be called 4248 // immediately, and it would be a waste of time to make it lazily 4249 // compiled. 4250 // These are all things we can know at this point, without looking at the 4251 // function itself. 4252 4253 // In addition, we need to distinguish between these cases: 4254 // (function foo() { 4255 // bar = function() { return 1; } 4256 // })(); 4257 // and 4258 // (function foo() { 4259 // var a = 1; 4260 // bar = function() { return a; } 4261 // })(); 4262 4263 // Now foo will be parsed eagerly and compiled eagerly (optimization: assume 4264 // parenthesis before the function means that it will be called 4265 // immediately). The inner function *must* be parsed eagerly to resolve the 4266 // possible reference to the variable in foo's scope. However, it's possible 4267 // that it will be compiled lazily. 4268 4269 // To make this additional case work, both Parser and PreParser implement a 4270 // logic where only top-level functions will be parsed lazily. 4271 bool is_lazily_parsed = mode() == PARSE_LAZILY && 4272 scope_->AllowsLazyParsing() && 4273 !function_state_->this_function_is_parenthesized(); 4274 4275 // Eager or lazy parse? 4276 // If is_lazily_parsed, we'll parse lazy. If we can set a bookmark, we'll 4277 // pass it to SkipLazyFunctionBody, which may use it to abort lazy 4278 // parsing if it suspect that wasn't a good idea. If so, or if we didn't 4279 // try to lazy parse in the first place, we'll have to parse eagerly. 4280 Scanner::BookmarkScope bookmark(scanner()); 4281 if (is_lazily_parsed) { 4282 Scanner::BookmarkScope* maybe_bookmark = 4283 bookmark.Set() ? &bookmark : nullptr; 4284 SkipLazyFunctionBody(&materialized_literal_count, 4285 &expected_property_count, /*CHECK_OK*/ ok, 4286 maybe_bookmark); 4287 4288 materialized_literal_count += formals.materialized_literals_count + 4289 function_state.materialized_literal_count(); 4290 4291 if (bookmark.HasBeenReset()) { 4292 // Trigger eager (re-)parsing, just below this block. 4293 is_lazily_parsed = false; 4294 4295 // This is probably an initialization function. Inform the compiler it 4296 // should also eager-compile this function, and that we expect it to be 4297 // used once. 4298 eager_compile_hint = FunctionLiteral::kShouldEagerCompile; 4299 should_be_used_once_hint = true; 4300 } 4301 } 4302 if (!is_lazily_parsed) { 4303 // Determine whether the function body can be discarded after parsing. 4304 // The preconditions are: 4305 // - Lazy compilation has to be enabled. 4306 // - Neither V8 natives nor native function declarations can be allowed, 4307 // since parsing one would retroactively force the function to be 4308 // eagerly compiled. 4309 // - The invoker of this parser can't depend on the AST being eagerly 4310 // built (either because the function is about to be compiled, or 4311 // because the AST is going to be inspected for some reason). 4312 // - Because of the above, we can't be attempting to parse a 4313 // FunctionExpression; even without enclosing parentheses it might be 4314 // immediately invoked. 4315 // - The function literal shouldn't be hinted to eagerly compile. 4316 // - For asm.js functions the body needs to be available when module 4317 // validation is active, because we examine the entire module at once. 4318 bool use_temp_zone = 4319 FLAG_lazy && !allow_natives() && extension_ == NULL && allow_lazy() && 4320 function_type == FunctionLiteral::kDeclaration && 4321 eager_compile_hint != FunctionLiteral::kShouldEagerCompile && 4322 !(FLAG_validate_asm && scope->asm_function()); 4323 // Open a new BodyScope, which sets our AstNodeFactory to allocate in the 4324 // new temporary zone if the preconditions are satisfied, and ensures that 4325 // the previous zone is always restored after parsing the body. 4326 // For the purpose of scope analysis, some ZoneObjects allocated by the 4327 // factory must persist after the function body is thrown away and 4328 // temp_zone is deallocated. These objects are instead allocated in a 4329 // parser-persistent zone (see parser_zone_ in AstNodeFactory). 4330 { 4331 Zone temp_zone(zone()->allocator()); 4332 AstNodeFactory::BodyScope inner(factory(), &temp_zone, use_temp_zone); 4333 4334 body = ParseEagerFunctionBody(function_name, pos, formals, kind, 4335 function_type, CHECK_OK); 4336 } 4337 materialized_literal_count = function_state.materialized_literal_count(); 4338 expected_property_count = function_state.expected_property_count(); 4339 if (use_temp_zone) { 4340 // If the preconditions are correct the function body should never be 4341 // accessed, but do this anyway for better behaviour if they're wrong. 4342 body = NULL; 4343 } 4344 } 4345 4346 // Parsing the body may change the language mode in our scope. 4347 language_mode = scope->language_mode(); 4348 4349 // Validate name and parameter names. We can do this only after parsing the 4350 // function, since the function can declare itself strict. 4351 CheckFunctionName(language_mode, function_name, function_name_validity, 4352 function_name_location, CHECK_OK); 4353 const bool allow_duplicate_parameters = 4354 is_sloppy(language_mode) && formals.is_simple && !IsConciseMethod(kind); 4355 ValidateFormalParameters(&formals_classifier, language_mode, 4356 allow_duplicate_parameters, CHECK_OK); 4357 4358 if (is_strict(language_mode)) { 4359 CheckStrictOctalLiteral(scope->start_position(), scope->end_position(), 4360 CHECK_OK); 4361 CheckDecimalLiteralWithLeadingZero(use_counts_, scope->start_position(), 4362 scope->end_position()); 4363 } 4364 if (is_sloppy(language_mode)) { 4365 InsertSloppyBlockFunctionVarBindings(scope, CHECK_OK); 4366 } 4367 CheckConflictingVarDeclarations(scope, CHECK_OK); 4368 4369 if (body) { 4370 // If body can be inspected, rewrite queued destructuring assignments 4371 ParserTraits::RewriteDestructuringAssignments(); 4372 } 4373 has_duplicate_parameters = 4374 !formals_classifier.is_valid_formal_parameter_list_without_duplicates(); 4375 } 4376 4377 FunctionLiteral::ParameterFlag duplicate_parameters = 4378 has_duplicate_parameters ? FunctionLiteral::kHasDuplicateParameters 4379 : FunctionLiteral::kNoDuplicateParameters; 4380 4381 FunctionLiteral* function_literal = factory()->NewFunctionLiteral( 4382 function_name, scope, body, materialized_literal_count, 4383 expected_property_count, arity, duplicate_parameters, function_type, 4384 eager_compile_hint, kind, pos); 4385 function_literal->set_function_token_position(function_token_pos); 4386 if (should_be_used_once_hint) 4387 function_literal->set_should_be_used_once_hint(); 4388 4389 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal); 4390 return function_literal; 4391 } 4392 4393 Expression* Parser::ParseAsyncFunctionExpression(bool* ok) { 4394 // AsyncFunctionDeclaration :: 4395 // async [no LineTerminator here] function ( FormalParameters[Await] ) 4396 // { AsyncFunctionBody } 4397 // 4398 // async [no LineTerminator here] function BindingIdentifier[Await] 4399 // ( FormalParameters[Await] ) { AsyncFunctionBody } 4400 DCHECK_EQ(scanner()->current_token(), Token::ASYNC); 4401 int pos = position(); 4402 Expect(Token::FUNCTION, CHECK_OK); 4403 bool is_strict_reserved = false; 4404 const AstRawString* name = nullptr; 4405 FunctionLiteral::FunctionType type = FunctionLiteral::kAnonymousExpression; 4406 4407 if (peek_any_identifier()) { 4408 type = FunctionLiteral::kNamedExpression; 4409 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); 4410 if (this->IsAwait(name)) { 4411 ReportMessageAt(scanner()->location(), 4412 MessageTemplate::kAwaitBindingIdentifier); 4413 *ok = false; 4414 return nullptr; 4415 } 4416 } 4417 return ParseFunctionLiteral(name, scanner()->location(), 4418 is_strict_reserved ? kFunctionNameIsStrictReserved 4419 : kFunctionNameValidityUnknown, 4420 FunctionKind::kAsyncFunction, pos, type, 4421 language_mode(), CHECK_OK); 4422 } 4423 4424 void Parser::SkipLazyFunctionBody(int* materialized_literal_count, 4425 int* expected_property_count, bool* ok, 4426 Scanner::BookmarkScope* bookmark) { 4427 DCHECK_IMPLIES(bookmark, bookmark->HasBeenSet()); 4428 if (produce_cached_parse_data()) CHECK(log_); 4429 4430 int function_block_pos = position(); 4431 if (consume_cached_parse_data() && !cached_parse_data_->rejected()) { 4432 // If we have cached data, we use it to skip parsing the function body. The 4433 // data contains the information we need to construct the lazy function. 4434 FunctionEntry entry = 4435 cached_parse_data_->GetFunctionEntry(function_block_pos); 4436 // Check that cached data is valid. If not, mark it as invalid (the embedder 4437 // handles it). Note that end position greater than end of stream is safe, 4438 // and hard to check. 4439 if (entry.is_valid() && entry.end_pos() > function_block_pos) { 4440 scanner()->SeekForward(entry.end_pos() - 1); 4441 4442 scope_->set_end_position(entry.end_pos()); 4443 Expect(Token::RBRACE, ok); 4444 if (!*ok) { 4445 return; 4446 } 4447 total_preparse_skipped_ += scope_->end_position() - function_block_pos; 4448 *materialized_literal_count = entry.literal_count(); 4449 *expected_property_count = entry.property_count(); 4450 SetLanguageMode(scope_, entry.language_mode()); 4451 if (entry.uses_super_property()) scope_->RecordSuperPropertyUsage(); 4452 if (entry.calls_eval()) scope_->RecordEvalCall(); 4453 return; 4454 } 4455 cached_parse_data_->Reject(); 4456 } 4457 // With no cached data, we partially parse the function, without building an 4458 // AST. This gathers the data needed to build a lazy function. 4459 SingletonLogger logger; 4460 PreParser::PreParseResult result = 4461 ParseLazyFunctionBodyWithPreParser(&logger, bookmark); 4462 if (bookmark && bookmark->HasBeenReset()) { 4463 return; // Return immediately if pre-parser devided to abort parsing. 4464 } 4465 if (result == PreParser::kPreParseStackOverflow) { 4466 // Propagate stack overflow. 4467 set_stack_overflow(); 4468 *ok = false; 4469 return; 4470 } 4471 if (logger.has_error()) { 4472 ParserTraits::ReportMessageAt( 4473 Scanner::Location(logger.start(), logger.end()), logger.message(), 4474 logger.argument_opt(), logger.error_type()); 4475 *ok = false; 4476 return; 4477 } 4478 scope_->set_end_position(logger.end()); 4479 Expect(Token::RBRACE, ok); 4480 if (!*ok) { 4481 return; 4482 } 4483 total_preparse_skipped_ += scope_->end_position() - function_block_pos; 4484 *materialized_literal_count = logger.literals(); 4485 *expected_property_count = logger.properties(); 4486 SetLanguageMode(scope_, logger.language_mode()); 4487 if (logger.uses_super_property()) { 4488 scope_->RecordSuperPropertyUsage(); 4489 } 4490 if (logger.calls_eval()) { 4491 scope_->RecordEvalCall(); 4492 } 4493 if (produce_cached_parse_data()) { 4494 DCHECK(log_); 4495 // Position right after terminal '}'. 4496 int body_end = scanner()->location().end_pos; 4497 log_->LogFunction(function_block_pos, body_end, *materialized_literal_count, 4498 *expected_property_count, scope_->language_mode(), 4499 scope_->uses_super_property(), scope_->calls_eval()); 4500 } 4501 } 4502 4503 4504 Statement* Parser::BuildAssertIsCoercible(Variable* var) { 4505 // if (var === null || var === undefined) 4506 // throw /* type error kNonCoercible) */; 4507 4508 Expression* condition = factory()->NewBinaryOperation( 4509 Token::OR, factory()->NewCompareOperation( 4510 Token::EQ_STRICT, factory()->NewVariableProxy(var), 4511 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition), 4512 RelocInfo::kNoPosition), 4513 factory()->NewCompareOperation( 4514 Token::EQ_STRICT, factory()->NewVariableProxy(var), 4515 factory()->NewNullLiteral(RelocInfo::kNoPosition), 4516 RelocInfo::kNoPosition), 4517 RelocInfo::kNoPosition); 4518 Expression* throw_type_error = this->NewThrowTypeError( 4519 MessageTemplate::kNonCoercible, ast_value_factory()->empty_string(), 4520 RelocInfo::kNoPosition); 4521 IfStatement* if_statement = factory()->NewIfStatement( 4522 condition, factory()->NewExpressionStatement(throw_type_error, 4523 RelocInfo::kNoPosition), 4524 factory()->NewEmptyStatement(RelocInfo::kNoPosition), 4525 RelocInfo::kNoPosition); 4526 return if_statement; 4527 } 4528 4529 4530 class InitializerRewriter : public AstExpressionVisitor { 4531 public: 4532 InitializerRewriter(uintptr_t stack_limit, Expression* root, Parser* parser, 4533 Scope* scope) 4534 : AstExpressionVisitor(stack_limit, root), 4535 parser_(parser), 4536 scope_(scope) {} 4537 4538 private: 4539 void VisitExpression(Expression* expr) override { 4540 RewritableExpression* to_rewrite = expr->AsRewritableExpression(); 4541 if (to_rewrite == nullptr || to_rewrite->is_rewritten()) return; 4542 4543 Parser::PatternRewriter::RewriteDestructuringAssignment(parser_, to_rewrite, 4544 scope_); 4545 } 4546 4547 // Code in function literals does not need to be eagerly rewritten, it will be 4548 // rewritten when scheduled. 4549 void VisitFunctionLiteral(FunctionLiteral* expr) override {} 4550 4551 private: 4552 Parser* parser_; 4553 Scope* scope_; 4554 }; 4555 4556 4557 void Parser::RewriteParameterInitializer(Expression* expr, Scope* scope) { 4558 InitializerRewriter rewriter(stack_limit_, expr, this, scope); 4559 rewriter.Run(); 4560 } 4561 4562 4563 Block* Parser::BuildParameterInitializationBlock( 4564 const ParserFormalParameters& parameters, bool* ok) { 4565 DCHECK(!parameters.is_simple); 4566 DCHECK(scope_->is_function_scope()); 4567 Block* init_block = 4568 factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition); 4569 for (int i = 0; i < parameters.params.length(); ++i) { 4570 auto parameter = parameters.params[i]; 4571 if (parameter.is_rest && parameter.pattern->IsVariableProxy()) break; 4572 DeclarationDescriptor descriptor; 4573 descriptor.declaration_kind = DeclarationDescriptor::PARAMETER; 4574 descriptor.parser = this; 4575 descriptor.scope = scope_; 4576 descriptor.hoist_scope = nullptr; 4577 descriptor.mode = LET; 4578 descriptor.declaration_pos = parameter.pattern->position(); 4579 // The position that will be used by the AssignmentExpression 4580 // which copies from the temp parameter to the pattern. 4581 // 4582 // TODO(adamk): Should this be RelocInfo::kNoPosition, since 4583 // it's just copying from a temp var to the real param var? 4584 descriptor.initialization_pos = parameter.pattern->position(); 4585 // The initializer position which will end up in, 4586 // Variable::initializer_position(), used for hole check elimination. 4587 int initializer_position = parameter.pattern->position(); 4588 Expression* initial_value = 4589 factory()->NewVariableProxy(parameters.scope->parameter(i)); 4590 if (parameter.initializer != nullptr) { 4591 // IS_UNDEFINED($param) ? initializer : $param 4592 4593 // Ensure initializer is rewritten 4594 RewriteParameterInitializer(parameter.initializer, scope_); 4595 4596 auto condition = factory()->NewCompareOperation( 4597 Token::EQ_STRICT, 4598 factory()->NewVariableProxy(parameters.scope->parameter(i)), 4599 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition), 4600 RelocInfo::kNoPosition); 4601 initial_value = factory()->NewConditional( 4602 condition, parameter.initializer, initial_value, 4603 RelocInfo::kNoPosition); 4604 descriptor.initialization_pos = parameter.initializer->position(); 4605 initializer_position = parameter.initializer_end_position; 4606 } 4607 4608 Scope* param_scope = scope_; 4609 Block* param_block = init_block; 4610 if (!parameter.is_simple() && scope_->calls_sloppy_eval()) { 4611 param_scope = NewScope(scope_, BLOCK_SCOPE); 4612 param_scope->set_is_declaration_scope(); 4613 param_scope->set_start_position(descriptor.initialization_pos); 4614 param_scope->set_end_position(parameter.initializer_end_position); 4615 param_scope->RecordEvalCall(); 4616 param_block = factory()->NewBlock(NULL, 8, true, RelocInfo::kNoPosition); 4617 param_block->set_scope(param_scope); 4618 descriptor.hoist_scope = scope_; 4619 // Pass the appropriate scope in so that PatternRewriter can appropriately 4620 // rewrite inner initializers of the pattern to param_scope 4621 descriptor.scope = param_scope; 4622 // Rewrite the outer initializer to point to param_scope 4623 RewriteParameterInitializerScope(stack_limit(), initial_value, scope_, 4624 param_scope); 4625 } 4626 4627 { 4628 BlockState block_state(&scope_, param_scope); 4629 DeclarationParsingResult::Declaration decl( 4630 parameter.pattern, initializer_position, initial_value); 4631 PatternRewriter::DeclareAndInitializeVariables(param_block, &descriptor, 4632 &decl, nullptr, CHECK_OK); 4633 } 4634 4635 if (!parameter.is_simple() && scope_->calls_sloppy_eval()) { 4636 param_scope = param_scope->FinalizeBlockScope(); 4637 if (param_scope != nullptr) { 4638 CheckConflictingVarDeclarations(param_scope, CHECK_OK); 4639 } 4640 init_block->statements()->Add(param_block, zone()); 4641 } 4642 } 4643 return init_block; 4644 } 4645 4646 Block* Parser::BuildRejectPromiseOnException(Block* block) { 4647 // try { <block> } catch (error) { return Promise.reject(error); } 4648 Block* try_block = block; 4649 Scope* catch_scope = NewScope(scope_, CATCH_SCOPE); 4650 catch_scope->set_is_hidden(); 4651 Variable* catch_variable = 4652 catch_scope->DeclareLocal(ast_value_factory()->dot_catch_string(), VAR, 4653 kCreatedInitialized, Variable::NORMAL); 4654 Block* catch_block = 4655 factory()->NewBlock(nullptr, 1, true, RelocInfo::kNoPosition); 4656 4657 Expression* promise_reject = BuildPromiseReject( 4658 factory()->NewVariableProxy(catch_variable), RelocInfo::kNoPosition); 4659 4660 ReturnStatement* return_promise_reject = 4661 factory()->NewReturnStatement(promise_reject, RelocInfo::kNoPosition); 4662 catch_block->statements()->Add(return_promise_reject, zone()); 4663 TryStatement* try_catch_statement = 4664 factory()->NewTryCatchStatement(try_block, catch_scope, catch_variable, 4665 catch_block, RelocInfo::kNoPosition); 4666 4667 block = factory()->NewBlock(nullptr, 1, true, RelocInfo::kNoPosition); 4668 block->statements()->Add(try_catch_statement, zone()); 4669 return block; 4670 } 4671 4672 Expression* Parser::BuildCreateJSGeneratorObject(int pos, FunctionKind kind) { 4673 DCHECK_NOT_NULL(function_state_->generator_object_variable()); 4674 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone()); 4675 args->Add(factory()->NewThisFunction(pos), zone()); 4676 args->Add(IsArrowFunction(kind) 4677 ? GetLiteralUndefined(pos) 4678 : ThisExpression(scope_, factory(), RelocInfo::kNoPosition), 4679 zone()); 4680 return factory()->NewCallRuntime(Runtime::kCreateJSGeneratorObject, args, 4681 pos); 4682 } 4683 4684 Expression* Parser::BuildPromiseResolve(Expression* value, int pos) { 4685 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(1, zone()); 4686 args->Add(value, zone()); 4687 return factory()->NewCallRuntime(Context::PROMISE_CREATE_RESOLVED_INDEX, args, 4688 pos); 4689 } 4690 4691 Expression* Parser::BuildPromiseReject(Expression* value, int pos) { 4692 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(1, zone()); 4693 args->Add(value, zone()); 4694 return factory()->NewCallRuntime(Context::PROMISE_CREATE_REJECTED_INDEX, args, 4695 pos); 4696 } 4697 4698 ZoneList<Statement*>* Parser::ParseEagerFunctionBody( 4699 const AstRawString* function_name, int pos, 4700 const ParserFormalParameters& parameters, FunctionKind kind, 4701 FunctionLiteral::FunctionType function_type, bool* ok) { 4702 // Everything inside an eagerly parsed function will be parsed eagerly 4703 // (see comment above). 4704 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); 4705 ZoneList<Statement*>* result = new(zone()) ZoneList<Statement*>(8, zone()); 4706 4707 static const int kFunctionNameAssignmentIndex = 0; 4708 if (function_type == FunctionLiteral::kNamedExpression) { 4709 DCHECK(function_name != NULL); 4710 // If we have a named function expression, we add a local variable 4711 // declaration to the body of the function with the name of the 4712 // function and let it refer to the function itself (closure). 4713 // Not having parsed the function body, the language mode may still change, 4714 // so we reserve a spot and create the actual const assignment later. 4715 DCHECK_EQ(kFunctionNameAssignmentIndex, result->length()); 4716 result->Add(NULL, zone()); 4717 } 4718 4719 ZoneList<Statement*>* body = result; 4720 Scope* inner_scope = scope_; 4721 Block* inner_block = nullptr; 4722 if (!parameters.is_simple) { 4723 inner_scope = NewScope(scope_, BLOCK_SCOPE); 4724 inner_scope->set_is_declaration_scope(); 4725 inner_scope->set_start_position(scanner()->location().beg_pos); 4726 inner_block = factory()->NewBlock(NULL, 8, true, RelocInfo::kNoPosition); 4727 inner_block->set_scope(inner_scope); 4728 body = inner_block->statements(); 4729 } 4730 4731 { 4732 BlockState block_state(&scope_, inner_scope); 4733 4734 if (IsGeneratorFunction(kind)) { 4735 // We produce: 4736 // 4737 // try { InitialYield; ...body...; return {value: undefined, done: true} } 4738 // finally { %_GeneratorClose(generator) } 4739 // 4740 // - InitialYield yields the actual generator object. 4741 // - Any return statement inside the body will have its argument wrapped 4742 // in a "done" iterator result object. 4743 // - If the generator terminates for whatever reason, we must close it. 4744 // Hence the finally clause. 4745 4746 Block* try_block = 4747 factory()->NewBlock(nullptr, 3, false, RelocInfo::kNoPosition); 4748 4749 { 4750 Expression* allocation = BuildCreateJSGeneratorObject(pos, kind); 4751 VariableProxy* init_proxy = factory()->NewVariableProxy( 4752 function_state_->generator_object_variable()); 4753 Assignment* assignment = factory()->NewAssignment( 4754 Token::INIT, init_proxy, allocation, RelocInfo::kNoPosition); 4755 VariableProxy* get_proxy = factory()->NewVariableProxy( 4756 function_state_->generator_object_variable()); 4757 // The position of the yield is important for reporting the exception 4758 // caused by calling the .throw method on a generator suspended at the 4759 // initial yield (i.e. right after generator instantiation). 4760 Yield* yield = factory()->NewYield(get_proxy, assignment, 4761 scope_->start_position()); 4762 try_block->statements()->Add( 4763 factory()->NewExpressionStatement(yield, RelocInfo::kNoPosition), 4764 zone()); 4765 } 4766 4767 ParseStatementList(try_block->statements(), Token::RBRACE, CHECK_OK); 4768 4769 Statement* final_return = factory()->NewReturnStatement( 4770 BuildIteratorResult(nullptr, true), RelocInfo::kNoPosition); 4771 try_block->statements()->Add(final_return, zone()); 4772 4773 Block* finally_block = 4774 factory()->NewBlock(nullptr, 1, false, RelocInfo::kNoPosition); 4775 ZoneList<Expression*>* args = 4776 new (zone()) ZoneList<Expression*>(1, zone()); 4777 VariableProxy* call_proxy = factory()->NewVariableProxy( 4778 function_state_->generator_object_variable()); 4779 args->Add(call_proxy, zone()); 4780 Expression* call = factory()->NewCallRuntime( 4781 Runtime::kInlineGeneratorClose, args, RelocInfo::kNoPosition); 4782 finally_block->statements()->Add( 4783 factory()->NewExpressionStatement(call, RelocInfo::kNoPosition), 4784 zone()); 4785 4786 body->Add(factory()->NewTryFinallyStatement(try_block, finally_block, 4787 RelocInfo::kNoPosition), 4788 zone()); 4789 } else if (IsAsyncFunction(kind)) { 4790 const bool accept_IN = true; 4791 DesugarAsyncFunctionBody(function_name, inner_scope, body, nullptr, kind, 4792 FunctionBody::Normal, accept_IN, pos, CHECK_OK); 4793 } else { 4794 ParseStatementList(body, Token::RBRACE, CHECK_OK); 4795 } 4796 4797 if (IsSubclassConstructor(kind)) { 4798 body->Add( 4799 factory()->NewReturnStatement( 4800 this->ThisExpression(scope_, factory(), RelocInfo::kNoPosition), 4801 RelocInfo::kNoPosition), 4802 zone()); 4803 } 4804 } 4805 4806 Expect(Token::RBRACE, CHECK_OK); 4807 scope_->set_end_position(scanner()->location().end_pos); 4808 4809 if (!parameters.is_simple) { 4810 DCHECK_NOT_NULL(inner_scope); 4811 DCHECK_EQ(body, inner_block->statements()); 4812 SetLanguageMode(scope_, inner_scope->language_mode()); 4813 Block* init_block = BuildParameterInitializationBlock(parameters, CHECK_OK); 4814 4815 if (IsAsyncFunction(kind)) { 4816 init_block = BuildRejectPromiseOnException(init_block); 4817 } 4818 4819 DCHECK_NOT_NULL(init_block); 4820 4821 inner_scope->set_end_position(scanner()->location().end_pos); 4822 inner_scope = inner_scope->FinalizeBlockScope(); 4823 if (inner_scope != nullptr) { 4824 CheckConflictingVarDeclarations(inner_scope, CHECK_OK); 4825 InsertShadowingVarBindingInitializers(inner_block); 4826 } 4827 4828 result->Add(init_block, zone()); 4829 result->Add(inner_block, zone()); 4830 } 4831 4832 if (function_type == FunctionLiteral::kNamedExpression) { 4833 // Now that we know the language mode, we can create the const assignment 4834 // in the previously reserved spot. 4835 // NOTE: We create a proxy and resolve it here so that in the 4836 // future we can change the AST to only refer to VariableProxies 4837 // instead of Variables and Proxies as is the case now. 4838 VariableMode fvar_mode = is_strict(language_mode()) ? CONST : CONST_LEGACY; 4839 Variable* fvar = new (zone()) 4840 Variable(scope_, function_name, fvar_mode, Variable::NORMAL, 4841 kCreatedInitialized, kNotAssigned); 4842 VariableProxy* proxy = factory()->NewVariableProxy(fvar); 4843 VariableDeclaration* fvar_declaration = factory()->NewVariableDeclaration( 4844 proxy, fvar_mode, scope_, RelocInfo::kNoPosition); 4845 scope_->DeclareFunctionVar(fvar_declaration); 4846 4847 VariableProxy* fproxy = factory()->NewVariableProxy(fvar); 4848 result->Set(kFunctionNameAssignmentIndex, 4849 factory()->NewExpressionStatement( 4850 factory()->NewAssignment(Token::INIT, fproxy, 4851 factory()->NewThisFunction(pos), 4852 RelocInfo::kNoPosition), 4853 RelocInfo::kNoPosition)); 4854 } 4855 4856 MarkCollectedTailCallExpressions(); 4857 return result; 4858 } 4859 4860 4861 PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser( 4862 SingletonLogger* logger, Scanner::BookmarkScope* bookmark) { 4863 // This function may be called on a background thread too; record only the 4864 // main thread preparse times. 4865 if (pre_parse_timer_ != NULL) { 4866 pre_parse_timer_->Start(); 4867 } 4868 TRACE_EVENT0("v8", "V8.PreParse"); 4869 4870 DCHECK_EQ(Token::LBRACE, scanner()->current_token()); 4871 4872 if (reusable_preparser_ == NULL) { 4873 reusable_preparser_ = new PreParser(zone(), &scanner_, ast_value_factory(), 4874 NULL, stack_limit_); 4875 reusable_preparser_->set_allow_lazy(true); 4876 #define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name()); 4877 SET_ALLOW(natives); 4878 SET_ALLOW(harmony_do_expressions); 4879 SET_ALLOW(harmony_for_in); 4880 SET_ALLOW(harmony_function_sent); 4881 SET_ALLOW(harmony_exponentiation_operator); 4882 SET_ALLOW(harmony_restrictive_declarations); 4883 SET_ALLOW(harmony_async_await); 4884 #undef SET_ALLOW 4885 } 4886 PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction( 4887 language_mode(), function_state_->kind(), scope_->has_simple_parameters(), 4888 parsing_module_, logger, bookmark, use_counts_); 4889 if (pre_parse_timer_ != NULL) { 4890 pre_parse_timer_->Stop(); 4891 } 4892 return result; 4893 } 4894 4895 ClassLiteral* Parser::ParseClassLiteral(ExpressionClassifier* classifier, 4896 const AstRawString* name, 4897 Scanner::Location class_name_location, 4898 bool name_is_strict_reserved, int pos, 4899 bool* ok) { 4900 // All parts of a ClassDeclaration and ClassExpression are strict code. 4901 if (name_is_strict_reserved) { 4902 ReportMessageAt(class_name_location, 4903 MessageTemplate::kUnexpectedStrictReserved); 4904 *ok = false; 4905 return NULL; 4906 } 4907 if (IsEvalOrArguments(name)) { 4908 ReportMessageAt(class_name_location, MessageTemplate::kStrictEvalArguments); 4909 *ok = false; 4910 return NULL; 4911 } 4912 4913 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE); 4914 BlockState block_state(&scope_, block_scope); 4915 RaiseLanguageMode(STRICT); 4916 scope_->SetScopeName(name); 4917 4918 VariableProxy* proxy = NULL; 4919 if (name != NULL) { 4920 proxy = NewUnresolved(name, CONST); 4921 Declaration* declaration = 4922 factory()->NewVariableDeclaration(proxy, CONST, block_scope, pos); 4923 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK); 4924 } 4925 4926 Expression* extends = NULL; 4927 if (Check(Token::EXTENDS)) { 4928 block_scope->set_start_position(scanner()->location().end_pos); 4929 ExpressionClassifier extends_classifier(this); 4930 extends = ParseLeftHandSideExpression(&extends_classifier, CHECK_OK); 4931 CheckNoTailCallExpressions(&extends_classifier, CHECK_OK); 4932 RewriteNonPattern(&extends_classifier, CHECK_OK); 4933 if (classifier != nullptr) { 4934 classifier->Accumulate(&extends_classifier, 4935 ExpressionClassifier::ExpressionProductions); 4936 } 4937 } else { 4938 block_scope->set_start_position(scanner()->location().end_pos); 4939 } 4940 4941 4942 ClassLiteralChecker checker(this); 4943 ZoneList<ObjectLiteral::Property*>* properties = NewPropertyList(4, zone()); 4944 FunctionLiteral* constructor = NULL; 4945 bool has_seen_constructor = false; 4946 4947 Expect(Token::LBRACE, CHECK_OK); 4948 4949 const bool has_extends = extends != nullptr; 4950 while (peek() != Token::RBRACE) { 4951 if (Check(Token::SEMICOLON)) continue; 4952 FuncNameInferrer::State fni_state(fni_); 4953 const bool in_class = true; 4954 bool is_computed_name = false; // Classes do not care about computed 4955 // property names here. 4956 ExpressionClassifier property_classifier(this); 4957 const AstRawString* property_name = nullptr; 4958 ObjectLiteral::Property* property = ParsePropertyDefinition( 4959 &checker, in_class, has_extends, MethodKind::Normal, &is_computed_name, 4960 &has_seen_constructor, &property_classifier, &property_name, CHECK_OK); 4961 RewriteNonPattern(&property_classifier, CHECK_OK); 4962 if (classifier != nullptr) { 4963 classifier->Accumulate(&property_classifier, 4964 ExpressionClassifier::ExpressionProductions); 4965 } 4966 4967 if (has_seen_constructor && constructor == NULL) { 4968 constructor = GetPropertyValue(property)->AsFunctionLiteral(); 4969 DCHECK_NOT_NULL(constructor); 4970 constructor->set_raw_name( 4971 name != nullptr ? name : ast_value_factory()->empty_string()); 4972 } else { 4973 properties->Add(property, zone()); 4974 } 4975 4976 if (fni_ != NULL) fni_->Infer(); 4977 4978 if (property_name != ast_value_factory()->constructor_string()) { 4979 SetFunctionNameFromPropertyName(property, property_name); 4980 } 4981 } 4982 4983 Expect(Token::RBRACE, CHECK_OK); 4984 int end_pos = scanner()->location().end_pos; 4985 4986 if (constructor == NULL) { 4987 constructor = DefaultConstructor(name, has_extends, block_scope, pos, 4988 end_pos, block_scope->language_mode()); 4989 } 4990 4991 // Note that we do not finalize this block scope because it is 4992 // used as a sentinel value indicating an anonymous class. 4993 block_scope->set_end_position(end_pos); 4994 4995 if (name != NULL) { 4996 DCHECK_NOT_NULL(proxy); 4997 proxy->var()->set_initializer_position(end_pos); 4998 } 4999 5000 return factory()->NewClassLiteral(block_scope, proxy, extends, constructor, 5001 properties, pos, end_pos); 5002 } 5003 5004 5005 Expression* Parser::ParseV8Intrinsic(bool* ok) { 5006 // CallRuntime :: 5007 // '%' Identifier Arguments 5008 5009 int pos = peek_position(); 5010 Expect(Token::MOD, CHECK_OK); 5011 // Allow "eval" or "arguments" for backward compatibility. 5012 const AstRawString* name = ParseIdentifier(kAllowRestrictedIdentifiers, 5013 CHECK_OK); 5014 Scanner::Location spread_pos; 5015 ExpressionClassifier classifier(this); 5016 ZoneList<Expression*>* args = 5017 ParseArguments(&spread_pos, &classifier, CHECK_OK); 5018 5019 DCHECK(!spread_pos.IsValid()); 5020 5021 if (extension_ != NULL) { 5022 // The extension structures are only accessible while parsing the 5023 // very first time not when reparsing because of lazy compilation. 5024 scope_->DeclarationScope()->ForceEagerCompilation(); 5025 } 5026 5027 const Runtime::Function* function = Runtime::FunctionForName(name->string()); 5028 5029 if (function != NULL) { 5030 // Check for possible name clash. 5031 DCHECK_EQ(Context::kNotFound, 5032 Context::IntrinsicIndexForName(name->string())); 5033 // Check for built-in IS_VAR macro. 5034 if (function->function_id == Runtime::kIS_VAR) { 5035 DCHECK_EQ(Runtime::RUNTIME, function->intrinsic_type); 5036 // %IS_VAR(x) evaluates to x if x is a variable, 5037 // leads to a parse error otherwise. Could be implemented as an 5038 // inline function %_IS_VAR(x) to eliminate this special case. 5039 if (args->length() == 1 && args->at(0)->AsVariableProxy() != NULL) { 5040 return args->at(0); 5041 } else { 5042 ReportMessage(MessageTemplate::kNotIsvar); 5043 *ok = false; 5044 return NULL; 5045 } 5046 } 5047 5048 // Check that the expected number of arguments are being passed. 5049 if (function->nargs != -1 && function->nargs != args->length()) { 5050 ReportMessage(MessageTemplate::kRuntimeWrongNumArgs); 5051 *ok = false; 5052 return NULL; 5053 } 5054 5055 return factory()->NewCallRuntime(function, args, pos); 5056 } 5057 5058 int context_index = Context::IntrinsicIndexForName(name->string()); 5059 5060 // Check that the function is defined. 5061 if (context_index == Context::kNotFound) { 5062 ParserTraits::ReportMessage(MessageTemplate::kNotDefined, name); 5063 *ok = false; 5064 return NULL; 5065 } 5066 5067 return factory()->NewCallRuntime(context_index, args, pos); 5068 } 5069 5070 5071 Literal* Parser::GetLiteralUndefined(int position) { 5072 return factory()->NewUndefinedLiteral(position); 5073 } 5074 5075 5076 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) { 5077 Declaration* decl = scope->CheckConflictingVarDeclarations(); 5078 if (decl != NULL) { 5079 // In ES6, conflicting variable bindings are early errors. 5080 const AstRawString* name = decl->proxy()->raw_name(); 5081 int position = decl->proxy()->position(); 5082 Scanner::Location location = position == RelocInfo::kNoPosition 5083 ? Scanner::Location::invalid() 5084 : Scanner::Location(position, position + 1); 5085 ParserTraits::ReportMessageAt(location, MessageTemplate::kVarRedeclaration, 5086 name); 5087 *ok = false; 5088 } 5089 } 5090 5091 5092 void Parser::InsertShadowingVarBindingInitializers(Block* inner_block) { 5093 // For each var-binding that shadows a parameter, insert an assignment 5094 // initializing the variable with the parameter. 5095 Scope* inner_scope = inner_block->scope(); 5096 DCHECK(inner_scope->is_declaration_scope()); 5097 Scope* function_scope = inner_scope->outer_scope(); 5098 DCHECK(function_scope->is_function_scope()); 5099 ZoneList<Declaration*>* decls = inner_scope->declarations(); 5100 for (int i = 0; i < decls->length(); ++i) { 5101 Declaration* decl = decls->at(i); 5102 if (decl->mode() != VAR || !decl->IsVariableDeclaration()) continue; 5103 const AstRawString* name = decl->proxy()->raw_name(); 5104 Variable* parameter = function_scope->LookupLocal(name); 5105 if (parameter == nullptr) continue; 5106 VariableProxy* to = inner_scope->NewUnresolved(factory(), name); 5107 VariableProxy* from = factory()->NewVariableProxy(parameter); 5108 Expression* assignment = factory()->NewAssignment( 5109 Token::ASSIGN, to, from, RelocInfo::kNoPosition); 5110 Statement* statement = factory()->NewExpressionStatement( 5111 assignment, RelocInfo::kNoPosition); 5112 inner_block->statements()->InsertAt(0, statement, zone()); 5113 } 5114 } 5115 5116 5117 void Parser::InsertSloppyBlockFunctionVarBindings(Scope* scope, bool* ok) { 5118 // For each variable which is used as a function declaration in a sloppy 5119 // block, 5120 DCHECK(scope->is_declaration_scope()); 5121 SloppyBlockFunctionMap* map = scope->sloppy_block_function_map(); 5122 for (ZoneHashMap::Entry* p = map->Start(); p != nullptr; p = map->Next(p)) { 5123 AstRawString* name = static_cast<AstRawString*>(p->key); 5124 // If the variable wouldn't conflict with a lexical declaration, 5125 Variable* var = scope->LookupLocal(name); 5126 if (var == nullptr || !IsLexicalVariableMode(var->mode())) { 5127 // Declare a var-style binding for the function in the outer scope 5128 VariableProxy* proxy = scope->NewUnresolved(factory(), name); 5129 Declaration* declaration = factory()->NewVariableDeclaration( 5130 proxy, VAR, scope, RelocInfo::kNoPosition); 5131 Declare(declaration, DeclarationDescriptor::NORMAL, true, ok, scope); 5132 DCHECK(ok); // Based on the preceding check, this should not fail 5133 if (!ok) return; 5134 5135 // Write in assignments to var for each block-scoped function declaration 5136 auto delegates = static_cast<SloppyBlockFunctionMap::Vector*>(p->value); 5137 for (SloppyBlockFunctionStatement* delegate : *delegates) { 5138 // Read from the local lexical scope and write to the function scope 5139 VariableProxy* to = scope->NewUnresolved(factory(), name); 5140 VariableProxy* from = delegate->scope()->NewUnresolved(factory(), name); 5141 Expression* assignment = factory()->NewAssignment( 5142 Token::ASSIGN, to, from, RelocInfo::kNoPosition); 5143 Statement* statement = factory()->NewExpressionStatement( 5144 assignment, RelocInfo::kNoPosition); 5145 delegate->set_statement(statement); 5146 } 5147 } 5148 } 5149 } 5150 5151 5152 // ---------------------------------------------------------------------------- 5153 // Parser support 5154 5155 bool Parser::TargetStackContainsLabel(const AstRawString* label) { 5156 for (Target* t = target_stack_; t != NULL; t = t->previous()) { 5157 if (ContainsLabel(t->statement()->labels(), label)) return true; 5158 } 5159 return false; 5160 } 5161 5162 5163 BreakableStatement* Parser::LookupBreakTarget(const AstRawString* label, 5164 bool* ok) { 5165 bool anonymous = label == NULL; 5166 for (Target* t = target_stack_; t != NULL; t = t->previous()) { 5167 BreakableStatement* stat = t->statement(); 5168 if ((anonymous && stat->is_target_for_anonymous()) || 5169 (!anonymous && ContainsLabel(stat->labels(), label))) { 5170 return stat; 5171 } 5172 } 5173 return NULL; 5174 } 5175 5176 5177 IterationStatement* Parser::LookupContinueTarget(const AstRawString* label, 5178 bool* ok) { 5179 bool anonymous = label == NULL; 5180 for (Target* t = target_stack_; t != NULL; t = t->previous()) { 5181 IterationStatement* stat = t->statement()->AsIterationStatement(); 5182 if (stat == NULL) continue; 5183 5184 DCHECK(stat->is_target_for_anonymous()); 5185 if (anonymous || ContainsLabel(stat->labels(), label)) { 5186 return stat; 5187 } 5188 } 5189 return NULL; 5190 } 5191 5192 5193 void Parser::HandleSourceURLComments(Isolate* isolate, Handle<Script> script) { 5194 if (scanner_.source_url()->length() > 0) { 5195 Handle<String> source_url = scanner_.source_url()->Internalize(isolate); 5196 script->set_source_url(*source_url); 5197 } 5198 if (scanner_.source_mapping_url()->length() > 0) { 5199 Handle<String> source_mapping_url = 5200 scanner_.source_mapping_url()->Internalize(isolate); 5201 script->set_source_mapping_url(*source_mapping_url); 5202 } 5203 } 5204 5205 5206 void Parser::Internalize(Isolate* isolate, Handle<Script> script, bool error) { 5207 // Internalize strings. 5208 ast_value_factory()->Internalize(isolate); 5209 5210 // Error processing. 5211 if (error) { 5212 if (stack_overflow()) { 5213 isolate->StackOverflow(); 5214 } else { 5215 DCHECK(pending_error_handler_.has_pending_error()); 5216 pending_error_handler_.ThrowPendingError(isolate, script); 5217 } 5218 } 5219 5220 // Move statistics to Isolate. 5221 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; 5222 ++feature) { 5223 if (use_counts_[feature] > 0) { 5224 isolate->CountUsage(v8::Isolate::UseCounterFeature(feature)); 5225 } 5226 } 5227 if (scanner_.FoundHtmlComment()) { 5228 isolate->CountUsage(v8::Isolate::kHtmlComment); 5229 if (script->line_offset() == 0 && script->column_offset() == 0) { 5230 isolate->CountUsage(v8::Isolate::kHtmlCommentInExternalScript); 5231 } 5232 } 5233 isolate->counters()->total_preparse_skipped()->Increment( 5234 total_preparse_skipped_); 5235 } 5236 5237 5238 // ---------------------------------------------------------------------------- 5239 // The Parser interface. 5240 5241 5242 bool Parser::ParseStatic(ParseInfo* info) { 5243 Parser parser(info); 5244 if (parser.Parse(info)) { 5245 info->set_language_mode(info->literal()->language_mode()); 5246 return true; 5247 } 5248 return false; 5249 } 5250 5251 5252 bool Parser::Parse(ParseInfo* info) { 5253 DCHECK(info->literal() == NULL); 5254 FunctionLiteral* result = NULL; 5255 // Ok to use Isolate here; this function is only called in the main thread. 5256 DCHECK(parsing_on_main_thread_); 5257 Isolate* isolate = info->isolate(); 5258 pre_parse_timer_ = isolate->counters()->pre_parse(); 5259 if (FLAG_trace_parse || allow_natives() || extension_ != NULL) { 5260 // If intrinsics are allowed, the Parser cannot operate independent of the 5261 // V8 heap because of Runtime. Tell the string table to internalize strings 5262 // and values right after they're created. 5263 ast_value_factory()->Internalize(isolate); 5264 } 5265 5266 if (info->is_lazy()) { 5267 DCHECK(!info->is_eval()); 5268 if (info->shared_info()->is_function()) { 5269 result = ParseLazy(isolate, info); 5270 } else { 5271 result = ParseProgram(isolate, info); 5272 } 5273 } else { 5274 SetCachedData(info); 5275 result = ParseProgram(isolate, info); 5276 } 5277 info->set_literal(result); 5278 5279 Internalize(isolate, info->script(), result == NULL); 5280 DCHECK(ast_value_factory()->IsInternalized()); 5281 return (result != NULL); 5282 } 5283 5284 5285 void Parser::ParseOnBackground(ParseInfo* info) { 5286 parsing_on_main_thread_ = false; 5287 5288 DCHECK(info->literal() == NULL); 5289 FunctionLiteral* result = NULL; 5290 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone()); 5291 5292 CompleteParserRecorder recorder; 5293 if (produce_cached_parse_data()) log_ = &recorder; 5294 5295 DCHECK(info->source_stream() != NULL); 5296 ExternalStreamingStream stream(info->source_stream(), 5297 info->source_stream_encoding()); 5298 scanner_.Initialize(&stream); 5299 DCHECK(info->context().is_null() || info->context()->IsNativeContext()); 5300 5301 // When streaming, we don't know the length of the source until we have parsed 5302 // it. The raw data can be UTF-8, so we wouldn't know the source length until 5303 // we have decoded it anyway even if we knew the raw data length (which we 5304 // don't). We work around this by storing all the scopes which need their end 5305 // position set at the end of the script (the top scope and possible eval 5306 // scopes) and set their end position after we know the script length. 5307 result = DoParseProgram(info); 5308 5309 info->set_literal(result); 5310 5311 // We cannot internalize on a background thread; a foreground task will take 5312 // care of calling Parser::Internalize just before compilation. 5313 5314 if (produce_cached_parse_data()) { 5315 if (result != NULL) *info->cached_data() = recorder.GetScriptData(); 5316 log_ = NULL; 5317 } 5318 } 5319 5320 5321 ParserTraits::TemplateLiteralState Parser::OpenTemplateLiteral(int pos) { 5322 return new (zone()) ParserTraits::TemplateLiteral(zone(), pos); 5323 } 5324 5325 5326 void Parser::AddTemplateSpan(TemplateLiteralState* state, bool tail) { 5327 int pos = scanner()->location().beg_pos; 5328 int end = scanner()->location().end_pos - (tail ? 1 : 2); 5329 const AstRawString* tv = scanner()->CurrentSymbol(ast_value_factory()); 5330 const AstRawString* trv = scanner()->CurrentRawSymbol(ast_value_factory()); 5331 Literal* cooked = factory()->NewStringLiteral(tv, pos); 5332 Literal* raw = factory()->NewStringLiteral(trv, pos); 5333 (*state)->AddTemplateSpan(cooked, raw, end, zone()); 5334 } 5335 5336 5337 void Parser::AddTemplateExpression(TemplateLiteralState* state, 5338 Expression* expression) { 5339 (*state)->AddExpression(expression, zone()); 5340 } 5341 5342 5343 Expression* Parser::CloseTemplateLiteral(TemplateLiteralState* state, int start, 5344 Expression* tag) { 5345 TemplateLiteral* lit = *state; 5346 int pos = lit->position(); 5347 const ZoneList<Expression*>* cooked_strings = lit->cooked(); 5348 const ZoneList<Expression*>* raw_strings = lit->raw(); 5349 const ZoneList<Expression*>* expressions = lit->expressions(); 5350 DCHECK_EQ(cooked_strings->length(), raw_strings->length()); 5351 DCHECK_EQ(cooked_strings->length(), expressions->length() + 1); 5352 5353 if (!tag) { 5354 // Build tree of BinaryOps to simplify code-generation 5355 Expression* expr = cooked_strings->at(0); 5356 int i = 0; 5357 while (i < expressions->length()) { 5358 Expression* sub = expressions->at(i++); 5359 Expression* cooked_str = cooked_strings->at(i); 5360 5361 // Let middle be ToString(sub). 5362 ZoneList<Expression*>* args = 5363 new (zone()) ZoneList<Expression*>(1, zone()); 5364 args->Add(sub, zone()); 5365 Expression* middle = factory()->NewCallRuntime(Runtime::kInlineToString, 5366 args, sub->position()); 5367 5368 expr = factory()->NewBinaryOperation( 5369 Token::ADD, factory()->NewBinaryOperation( 5370 Token::ADD, expr, middle, expr->position()), 5371 cooked_str, sub->position()); 5372 } 5373 return expr; 5374 } else { 5375 uint32_t hash = ComputeTemplateLiteralHash(lit); 5376 5377 int cooked_idx = function_state_->NextMaterializedLiteralIndex(); 5378 int raw_idx = function_state_->NextMaterializedLiteralIndex(); 5379 5380 // $getTemplateCallSite 5381 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(4, zone()); 5382 args->Add(factory()->NewArrayLiteral( 5383 const_cast<ZoneList<Expression*>*>(cooked_strings), 5384 cooked_idx, pos), 5385 zone()); 5386 args->Add( 5387 factory()->NewArrayLiteral( 5388 const_cast<ZoneList<Expression*>*>(raw_strings), raw_idx, pos), 5389 zone()); 5390 5391 // Ensure hash is suitable as a Smi value 5392 Smi* hash_obj = Smi::cast(Internals::IntToSmi(static_cast<int>(hash))); 5393 args->Add(factory()->NewSmiLiteral(hash_obj->value(), pos), zone()); 5394 5395 Expression* call_site = factory()->NewCallRuntime( 5396 Context::GET_TEMPLATE_CALL_SITE_INDEX, args, start); 5397 5398 // Call TagFn 5399 ZoneList<Expression*>* call_args = 5400 new (zone()) ZoneList<Expression*>(expressions->length() + 1, zone()); 5401 call_args->Add(call_site, zone()); 5402 call_args->AddAll(*expressions, zone()); 5403 return factory()->NewCall(tag, call_args, pos); 5404 } 5405 } 5406 5407 5408 uint32_t Parser::ComputeTemplateLiteralHash(const TemplateLiteral* lit) { 5409 const ZoneList<Expression*>* raw_strings = lit->raw(); 5410 int total = raw_strings->length(); 5411 DCHECK(total); 5412 5413 uint32_t running_hash = 0; 5414 5415 for (int index = 0; index < total; ++index) { 5416 if (index) { 5417 running_hash = StringHasher::ComputeRunningHashOneByte( 5418 running_hash, "${}", 3); 5419 } 5420 5421 const AstRawString* raw_string = 5422 raw_strings->at(index)->AsLiteral()->raw_value()->AsString(); 5423 if (raw_string->is_one_byte()) { 5424 const char* data = reinterpret_cast<const char*>(raw_string->raw_data()); 5425 running_hash = StringHasher::ComputeRunningHashOneByte( 5426 running_hash, data, raw_string->length()); 5427 } else { 5428 const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data()); 5429 running_hash = StringHasher::ComputeRunningHash(running_hash, data, 5430 raw_string->length()); 5431 } 5432 } 5433 5434 return running_hash; 5435 } 5436 5437 5438 ZoneList<v8::internal::Expression*>* Parser::PrepareSpreadArguments( 5439 ZoneList<v8::internal::Expression*>* list) { 5440 ZoneList<v8::internal::Expression*>* args = 5441 new (zone()) ZoneList<v8::internal::Expression*>(1, zone()); 5442 if (list->length() == 1) { 5443 // Spread-call with single spread argument produces an InternalArray 5444 // containing the values from the array. 5445 // 5446 // Function is called or constructed with the produced array of arguments 5447 // 5448 // EG: Apply(Func, Spread(spread0)) 5449 ZoneList<Expression*>* spread_list = 5450 new (zone()) ZoneList<Expression*>(0, zone()); 5451 spread_list->Add(list->at(0)->AsSpread()->expression(), zone()); 5452 args->Add(factory()->NewCallRuntime(Context::SPREAD_ITERABLE_INDEX, 5453 spread_list, RelocInfo::kNoPosition), 5454 zone()); 5455 return args; 5456 } else { 5457 // Spread-call with multiple arguments produces array literals for each 5458 // sequences of unspread arguments, and converts each spread iterable to 5459 // an Internal array. Finally, all of these produced arrays are flattened 5460 // into a single InternalArray, containing the arguments for the call. 5461 // 5462 // EG: Apply(Func, Flatten([unspread0, unspread1], Spread(spread0), 5463 // Spread(spread1), [unspread2, unspread3])) 5464 int i = 0; 5465 int n = list->length(); 5466 while (i < n) { 5467 if (!list->at(i)->IsSpread()) { 5468 ZoneList<v8::internal::Expression*>* unspread = 5469 new (zone()) ZoneList<v8::internal::Expression*>(1, zone()); 5470 5471 // Push array of unspread parameters 5472 while (i < n && !list->at(i)->IsSpread()) { 5473 unspread->Add(list->at(i++), zone()); 5474 } 5475 int literal_index = function_state_->NextMaterializedLiteralIndex(); 5476 args->Add(factory()->NewArrayLiteral(unspread, literal_index, 5477 RelocInfo::kNoPosition), 5478 zone()); 5479 5480 if (i == n) break; 5481 } 5482 5483 // Push eagerly spread argument 5484 ZoneList<v8::internal::Expression*>* spread_list = 5485 new (zone()) ZoneList<v8::internal::Expression*>(1, zone()); 5486 spread_list->Add(list->at(i++)->AsSpread()->expression(), zone()); 5487 args->Add(factory()->NewCallRuntime(Context::SPREAD_ITERABLE_INDEX, 5488 spread_list, RelocInfo::kNoPosition), 5489 zone()); 5490 } 5491 5492 list = new (zone()) ZoneList<v8::internal::Expression*>(1, zone()); 5493 list->Add(factory()->NewCallRuntime(Context::SPREAD_ARGUMENTS_INDEX, args, 5494 RelocInfo::kNoPosition), 5495 zone()); 5496 return list; 5497 } 5498 UNREACHABLE(); 5499 } 5500 5501 5502 Expression* Parser::SpreadCall(Expression* function, 5503 ZoneList<v8::internal::Expression*>* args, 5504 int pos) { 5505 if (function->IsSuperCallReference()) { 5506 // Super calls 5507 // $super_constructor = %_GetSuperConstructor(<this-function>) 5508 // %reflect_construct($super_constructor, args, new.target) 5509 ZoneList<Expression*>* tmp = new (zone()) ZoneList<Expression*>(1, zone()); 5510 tmp->Add(function->AsSuperCallReference()->this_function_var(), zone()); 5511 Expression* super_constructor = factory()->NewCallRuntime( 5512 Runtime::kInlineGetSuperConstructor, tmp, pos); 5513 args->InsertAt(0, super_constructor, zone()); 5514 args->Add(function->AsSuperCallReference()->new_target_var(), zone()); 5515 return factory()->NewCallRuntime(Context::REFLECT_CONSTRUCT_INDEX, args, 5516 pos); 5517 } else { 5518 if (function->IsProperty()) { 5519 // Method calls 5520 if (function->AsProperty()->IsSuperAccess()) { 5521 Expression* home = 5522 ThisExpression(scope_, factory(), RelocInfo::kNoPosition); 5523 args->InsertAt(0, function, zone()); 5524 args->InsertAt(1, home, zone()); 5525 } else { 5526 Variable* temp = 5527 scope_->NewTemporary(ast_value_factory()->empty_string()); 5528 VariableProxy* obj = factory()->NewVariableProxy(temp); 5529 Assignment* assign_obj = factory()->NewAssignment( 5530 Token::ASSIGN, obj, function->AsProperty()->obj(), 5531 RelocInfo::kNoPosition); 5532 function = factory()->NewProperty( 5533 assign_obj, function->AsProperty()->key(), RelocInfo::kNoPosition); 5534 args->InsertAt(0, function, zone()); 5535 obj = factory()->NewVariableProxy(temp); 5536 args->InsertAt(1, obj, zone()); 5537 } 5538 } else { 5539 // Non-method calls 5540 args->InsertAt(0, function, zone()); 5541 args->InsertAt(1, factory()->NewUndefinedLiteral(RelocInfo::kNoPosition), 5542 zone()); 5543 } 5544 return factory()->NewCallRuntime(Context::REFLECT_APPLY_INDEX, args, pos); 5545 } 5546 } 5547 5548 5549 Expression* Parser::SpreadCallNew(Expression* function, 5550 ZoneList<v8::internal::Expression*>* args, 5551 int pos) { 5552 args->InsertAt(0, function, zone()); 5553 5554 return factory()->NewCallRuntime(Context::REFLECT_CONSTRUCT_INDEX, args, pos); 5555 } 5556 5557 5558 void Parser::SetLanguageMode(Scope* scope, LanguageMode mode) { 5559 v8::Isolate::UseCounterFeature feature; 5560 if (is_sloppy(mode)) 5561 feature = v8::Isolate::kSloppyMode; 5562 else if (is_strict(mode)) 5563 feature = v8::Isolate::kStrictMode; 5564 else 5565 UNREACHABLE(); 5566 ++use_counts_[feature]; 5567 scope->SetLanguageMode(mode); 5568 } 5569 5570 5571 void Parser::RaiseLanguageMode(LanguageMode mode) { 5572 LanguageMode old = scope_->language_mode(); 5573 SetLanguageMode(scope_, old > mode ? old : mode); 5574 } 5575 5576 void Parser::MarkCollectedTailCallExpressions() { 5577 const ZoneList<Expression*>& tail_call_expressions = 5578 function_state_->tail_call_expressions().expressions(); 5579 for (int i = 0; i < tail_call_expressions.length(); ++i) { 5580 Expression* expression = tail_call_expressions[i]; 5581 // If only FLAG_harmony_explicit_tailcalls is enabled then expression 5582 // must be a Call expression. 5583 DCHECK(FLAG_harmony_tailcalls || !FLAG_harmony_explicit_tailcalls || 5584 expression->IsCall()); 5585 MarkTailPosition(expression); 5586 } 5587 } 5588 5589 Expression* ParserTraits::ExpressionListToExpression( 5590 ZoneList<Expression*>* args) { 5591 AstNodeFactory* factory = parser_->factory(); 5592 Expression* expr = args->at(0); 5593 for (int i = 1; i < args->length(); ++i) { 5594 expr = factory->NewBinaryOperation(Token::COMMA, expr, args->at(i), 5595 expr->position()); 5596 } 5597 return expr; 5598 } 5599 5600 void ParserTraits::RewriteDestructuringAssignments() { 5601 parser_->RewriteDestructuringAssignments(); 5602 } 5603 5604 Expression* ParserTraits::RewriteExponentiation(Expression* left, 5605 Expression* right, int pos) { 5606 return parser_->RewriteExponentiation(left, right, pos); 5607 } 5608 5609 Expression* ParserTraits::RewriteAssignExponentiation(Expression* left, 5610 Expression* right, 5611 int pos) { 5612 return parser_->RewriteAssignExponentiation(left, right, pos); 5613 } 5614 5615 void ParserTraits::RewriteNonPattern(Type::ExpressionClassifier* classifier, 5616 bool* ok) { 5617 parser_->RewriteNonPattern(classifier, ok); 5618 } 5619 5620 Expression* ParserTraits::RewriteAwaitExpression(Expression* value, 5621 int await_pos) { 5622 // yield %AsyncFunctionAwait(.generator_object, <operand>) 5623 Variable* generator_object_variable = 5624 parser_->function_state_->generator_object_variable(); 5625 5626 // If generator_object_variable is null, 5627 if (!generator_object_variable) return value; 5628 5629 auto factory = parser_->factory(); 5630 const int nopos = RelocInfo::kNoPosition; 5631 5632 Variable* temp_var = parser_->scope_->NewTemporary( 5633 parser_->ast_value_factory()->empty_string()); 5634 VariableProxy* temp_proxy = factory->NewVariableProxy(temp_var); 5635 Block* do_block = factory->NewBlock(nullptr, 2, false, nopos); 5636 5637 // Wrap value evaluation to provide a break location. 5638 Expression* value_assignment = 5639 factory->NewAssignment(Token::ASSIGN, temp_proxy, value, nopos); 5640 do_block->statements()->Add( 5641 factory->NewExpressionStatement(value_assignment, value->position()), 5642 zone()); 5643 5644 ZoneList<Expression*>* async_function_await_args = 5645 new (zone()) ZoneList<Expression*>(2, zone()); 5646 Expression* generator_object = 5647 factory->NewVariableProxy(generator_object_variable); 5648 async_function_await_args->Add(generator_object, zone()); 5649 async_function_await_args->Add(temp_proxy, zone()); 5650 Expression* async_function_await = parser_->factory()->NewCallRuntime( 5651 Context::ASYNC_FUNCTION_AWAIT_INDEX, async_function_await_args, nopos); 5652 // Wrap await to provide a break location between value evaluation and yield. 5653 Expression* await_assignment = factory->NewAssignment( 5654 Token::ASSIGN, temp_proxy, async_function_await, nopos); 5655 do_block->statements()->Add( 5656 factory->NewExpressionStatement(await_assignment, await_pos), zone()); 5657 Expression* do_expr = factory->NewDoExpression(do_block, temp_var, nopos); 5658 5659 generator_object = factory->NewVariableProxy(generator_object_variable); 5660 return factory->NewYield(generator_object, do_expr, nopos); 5661 } 5662 5663 ZoneList<Expression*>* ParserTraits::GetNonPatternList() const { 5664 return parser_->function_state_->non_patterns_to_rewrite(); 5665 } 5666 5667 5668 ZoneList<typename ParserTraits::Type::ExpressionClassifier::Error>* 5669 ParserTraits::GetReportedErrorList() const { 5670 return parser_->function_state_->GetReportedErrorList(); 5671 } 5672 5673 5674 Zone* ParserTraits::zone() const { 5675 return parser_->function_state_->scope()->zone(); 5676 } 5677 5678 5679 class NonPatternRewriter : public AstExpressionRewriter { 5680 public: 5681 NonPatternRewriter(uintptr_t stack_limit, Parser* parser) 5682 : AstExpressionRewriter(stack_limit), parser_(parser) {} 5683 ~NonPatternRewriter() override {} 5684 5685 private: 5686 bool RewriteExpression(Expression* expr) override { 5687 if (expr->IsRewritableExpression()) return true; 5688 // Rewrite only what could have been a pattern but is not. 5689 if (expr->IsArrayLiteral()) { 5690 // Spread rewriting in array literals. 5691 ArrayLiteral* lit = expr->AsArrayLiteral(); 5692 VisitExpressions(lit->values()); 5693 replacement_ = parser_->RewriteSpreads(lit); 5694 return false; 5695 } 5696 if (expr->IsObjectLiteral()) { 5697 return true; 5698 } 5699 if (expr->IsBinaryOperation() && 5700 expr->AsBinaryOperation()->op() == Token::COMMA) { 5701 return true; 5702 } 5703 // Everything else does not need rewriting. 5704 return false; 5705 } 5706 5707 void VisitObjectLiteralProperty(ObjectLiteralProperty* property) override { 5708 if (property == nullptr) return; 5709 // Do not rewrite (computed) key expressions 5710 AST_REWRITE_PROPERTY(Expression, property, value); 5711 } 5712 5713 Parser* parser_; 5714 }; 5715 5716 5717 void Parser::RewriteNonPattern(ExpressionClassifier* classifier, bool* ok) { 5718 ValidateExpression(classifier, ok); 5719 if (!*ok) return; 5720 auto non_patterns_to_rewrite = function_state_->non_patterns_to_rewrite(); 5721 int begin = classifier->GetNonPatternBegin(); 5722 int end = non_patterns_to_rewrite->length(); 5723 if (begin < end) { 5724 NonPatternRewriter rewriter(stack_limit_, this); 5725 for (int i = begin; i < end; i++) { 5726 DCHECK(non_patterns_to_rewrite->at(i)->IsRewritableExpression()); 5727 rewriter.Rewrite(non_patterns_to_rewrite->at(i)); 5728 } 5729 non_patterns_to_rewrite->Rewind(begin); 5730 } 5731 } 5732 5733 5734 void Parser::RewriteDestructuringAssignments() { 5735 const auto& assignments = 5736 function_state_->destructuring_assignments_to_rewrite(); 5737 for (int i = assignments.length() - 1; i >= 0; --i) { 5738 // Rewrite list in reverse, so that nested assignment patterns are rewritten 5739 // correctly. 5740 const DestructuringAssignment& pair = assignments.at(i); 5741 RewritableExpression* to_rewrite = 5742 pair.assignment->AsRewritableExpression(); 5743 DCHECK_NOT_NULL(to_rewrite); 5744 if (!to_rewrite->is_rewritten()) { 5745 PatternRewriter::RewriteDestructuringAssignment(this, to_rewrite, 5746 pair.scope); 5747 } 5748 } 5749 } 5750 5751 Expression* Parser::RewriteExponentiation(Expression* left, Expression* right, 5752 int pos) { 5753 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone()); 5754 args->Add(left, zone()); 5755 args->Add(right, zone()); 5756 return factory()->NewCallRuntime(Context::MATH_POW_METHOD_INDEX, args, pos); 5757 } 5758 5759 Expression* Parser::RewriteAssignExponentiation(Expression* left, 5760 Expression* right, int pos) { 5761 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone()); 5762 if (left->IsVariableProxy()) { 5763 VariableProxy* lhs = left->AsVariableProxy(); 5764 5765 Expression* result; 5766 DCHECK_NOT_NULL(lhs->raw_name()); 5767 result = 5768 this->ExpressionFromIdentifier(lhs->raw_name(), lhs->position(), 5769 lhs->end_position(), scope_, factory()); 5770 args->Add(left, zone()); 5771 args->Add(right, zone()); 5772 Expression* call = 5773 factory()->NewCallRuntime(Context::MATH_POW_METHOD_INDEX, args, pos); 5774 return factory()->NewAssignment(Token::ASSIGN, result, call, pos); 5775 } else if (left->IsProperty()) { 5776 Property* prop = left->AsProperty(); 5777 auto temp_obj = scope_->NewTemporary(ast_value_factory()->empty_string()); 5778 auto temp_key = scope_->NewTemporary(ast_value_factory()->empty_string()); 5779 Expression* assign_obj = factory()->NewAssignment( 5780 Token::ASSIGN, factory()->NewVariableProxy(temp_obj), prop->obj(), 5781 RelocInfo::kNoPosition); 5782 Expression* assign_key = factory()->NewAssignment( 5783 Token::ASSIGN, factory()->NewVariableProxy(temp_key), prop->key(), 5784 RelocInfo::kNoPosition); 5785 args->Add(factory()->NewProperty(factory()->NewVariableProxy(temp_obj), 5786 factory()->NewVariableProxy(temp_key), 5787 left->position()), 5788 zone()); 5789 args->Add(right, zone()); 5790 Expression* call = 5791 factory()->NewCallRuntime(Context::MATH_POW_METHOD_INDEX, args, pos); 5792 Expression* target = factory()->NewProperty( 5793 factory()->NewVariableProxy(temp_obj), 5794 factory()->NewVariableProxy(temp_key), RelocInfo::kNoPosition); 5795 Expression* assign = 5796 factory()->NewAssignment(Token::ASSIGN, target, call, pos); 5797 return factory()->NewBinaryOperation( 5798 Token::COMMA, assign_obj, 5799 factory()->NewBinaryOperation(Token::COMMA, assign_key, assign, pos), 5800 pos); 5801 } 5802 UNREACHABLE(); 5803 return nullptr; 5804 } 5805 5806 Expression* Parser::RewriteSpreads(ArrayLiteral* lit) { 5807 // Array literals containing spreads are rewritten using do expressions, e.g. 5808 // [1, 2, 3, ...x, 4, ...y, 5] 5809 // is roughly rewritten as: 5810 // do { 5811 // $R = [1, 2, 3]; 5812 // for ($i of x) %AppendElement($R, $i); 5813 // %AppendElement($R, 4); 5814 // for ($j of y) %AppendElement($R, $j); 5815 // %AppendElement($R, 5); 5816 // $R 5817 // } 5818 // where $R, $i and $j are fresh temporary variables. 5819 ZoneList<Expression*>::iterator s = lit->FirstSpread(); 5820 if (s == lit->EndValue()) return nullptr; // no spread, no rewriting... 5821 Variable* result = 5822 scope_->NewTemporary(ast_value_factory()->dot_result_string()); 5823 // NOTE: The value assigned to R is the whole original array literal, 5824 // spreads included. This will be fixed before the rewritten AST is returned. 5825 // $R = lit 5826 Expression* init_result = 5827 factory()->NewAssignment(Token::INIT, factory()->NewVariableProxy(result), 5828 lit, RelocInfo::kNoPosition); 5829 Block* do_block = 5830 factory()->NewBlock(nullptr, 16, false, RelocInfo::kNoPosition); 5831 do_block->statements()->Add( 5832 factory()->NewExpressionStatement(init_result, RelocInfo::kNoPosition), 5833 zone()); 5834 // Traverse the array literal starting from the first spread. 5835 while (s != lit->EndValue()) { 5836 Expression* value = *s++; 5837 Spread* spread = value->AsSpread(); 5838 if (spread == nullptr) { 5839 // If the element is not a spread, we're adding a single: 5840 // %AppendElement($R, value) 5841 ZoneList<Expression*>* append_element_args = NewExpressionList(2, zone()); 5842 append_element_args->Add(factory()->NewVariableProxy(result), zone()); 5843 append_element_args->Add(value, zone()); 5844 do_block->statements()->Add( 5845 factory()->NewExpressionStatement( 5846 factory()->NewCallRuntime(Runtime::kAppendElement, 5847 append_element_args, 5848 RelocInfo::kNoPosition), 5849 RelocInfo::kNoPosition), 5850 zone()); 5851 } else { 5852 // If it's a spread, we're adding a for/of loop iterating through it. 5853 Variable* each = 5854 scope_->NewTemporary(ast_value_factory()->dot_for_string()); 5855 Expression* subject = spread->expression(); 5856 // %AppendElement($R, each) 5857 Statement* append_body; 5858 { 5859 ZoneList<Expression*>* append_element_args = 5860 NewExpressionList(2, zone()); 5861 append_element_args->Add(factory()->NewVariableProxy(result), zone()); 5862 append_element_args->Add(factory()->NewVariableProxy(each), zone()); 5863 append_body = factory()->NewExpressionStatement( 5864 factory()->NewCallRuntime(Runtime::kAppendElement, 5865 append_element_args, 5866 RelocInfo::kNoPosition), 5867 RelocInfo::kNoPosition); 5868 } 5869 // for (each of spread) %AppendElement($R, each) 5870 ForEachStatement* loop = factory()->NewForEachStatement( 5871 ForEachStatement::ITERATE, nullptr, RelocInfo::kNoPosition); 5872 InitializeForOfStatement(loop->AsForOfStatement(), 5873 factory()->NewVariableProxy(each), subject, 5874 append_body); 5875 do_block->statements()->Add(loop, zone()); 5876 } 5877 } 5878 // Now, rewind the original array literal to truncate everything from the 5879 // first spread (included) until the end. This fixes $R's initialization. 5880 lit->RewindSpreads(); 5881 return factory()->NewDoExpression(do_block, result, lit->position()); 5882 } 5883 5884 5885 void ParserTraits::QueueDestructuringAssignmentForRewriting(Expression* expr) { 5886 DCHECK(expr->IsRewritableExpression()); 5887 parser_->function_state_->AddDestructuringAssignment( 5888 Parser::DestructuringAssignment(expr, parser_->scope_)); 5889 } 5890 5891 5892 void ParserTraits::QueueNonPatternForRewriting(Expression* expr, bool* ok) { 5893 DCHECK(expr->IsRewritableExpression()); 5894 parser_->function_state_->AddNonPatternForRewriting(expr, ok); 5895 } 5896 5897 5898 void ParserTraits::SetFunctionNameFromPropertyName( 5899 ObjectLiteralProperty* property, const AstRawString* name) { 5900 Expression* value = property->value(); 5901 5902 // Computed name setting must happen at runtime. 5903 if (property->is_computed_name()) return; 5904 5905 // Getter and setter names are handled here because their names 5906 // change in ES2015, even though they are not anonymous. 5907 auto function = value->AsFunctionLiteral(); 5908 if (function != nullptr) { 5909 bool is_getter = property->kind() == ObjectLiteralProperty::GETTER; 5910 bool is_setter = property->kind() == ObjectLiteralProperty::SETTER; 5911 if (is_getter || is_setter) { 5912 DCHECK_NOT_NULL(name); 5913 const AstRawString* prefix = 5914 is_getter ? parser_->ast_value_factory()->get_space_string() 5915 : parser_->ast_value_factory()->set_space_string(); 5916 function->set_raw_name( 5917 parser_->ast_value_factory()->NewConsString(prefix, name)); 5918 return; 5919 } 5920 } 5921 5922 if (!value->IsAnonymousFunctionDefinition()) return; 5923 DCHECK_NOT_NULL(name); 5924 5925 // Ignore "__proto__" as a name when it's being used to set the [[Prototype]] 5926 // of an object literal. 5927 if (property->kind() == ObjectLiteralProperty::PROTOTYPE) return; 5928 5929 if (function != nullptr) { 5930 function->set_raw_name(name); 5931 DCHECK_EQ(ObjectLiteralProperty::COMPUTED, property->kind()); 5932 } else { 5933 DCHECK(value->IsClassLiteral()); 5934 DCHECK_EQ(ObjectLiteralProperty::COMPUTED, property->kind()); 5935 value->AsClassLiteral()->constructor()->set_raw_name(name); 5936 } 5937 } 5938 5939 5940 void ParserTraits::SetFunctionNameFromIdentifierRef(Expression* value, 5941 Expression* identifier) { 5942 if (!value->IsAnonymousFunctionDefinition()) return; 5943 if (!identifier->IsVariableProxy()) return; 5944 5945 auto name = identifier->AsVariableProxy()->raw_name(); 5946 DCHECK_NOT_NULL(name); 5947 5948 auto function = value->AsFunctionLiteral(); 5949 if (function != nullptr) { 5950 function->set_raw_name(name); 5951 } else { 5952 DCHECK(value->IsClassLiteral()); 5953 value->AsClassLiteral()->constructor()->set_raw_name(name); 5954 } 5955 } 5956 5957 5958 // Desugaring of yield* 5959 // ==================== 5960 // 5961 // With the help of do-expressions and function.sent, we desugar yield* into a 5962 // loop containing a "raw" yield (a yield that doesn't wrap an iterator result 5963 // object around its argument). Concretely, "yield* iterable" turns into 5964 // roughly the following code: 5965 // 5966 // do { 5967 // const kNext = 0; 5968 // const kReturn = 1; 5969 // const kThrow = 2; 5970 // 5971 // let input = function.sent; 5972 // let mode = kNext; 5973 // let output = undefined; 5974 // 5975 // let iterator = iterable[Symbol.iterator](); 5976 // if (!IS_RECEIVER(iterator)) throw MakeTypeError(kSymbolIteratorInvalid); 5977 // 5978 // while (true) { 5979 // // From the generator to the iterator: 5980 // // Forward input according to resume mode and obtain output. 5981 // switch (mode) { 5982 // case kNext: 5983 // output = iterator.next(input); 5984 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output); 5985 // break; 5986 // case kReturn: 5987 // IteratorClose(iterator, input, output); // See below. 5988 // break; 5989 // case kThrow: 5990 // let iteratorThrow = iterator.throw; 5991 // if (IS_NULL_OR_UNDEFINED(iteratorThrow)) { 5992 // IteratorClose(iterator); // See below. 5993 // throw MakeTypeError(kThrowMethodMissing); 5994 // } 5995 // output = %_Call(iteratorThrow, iterator, input); 5996 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output); 5997 // break; 5998 // } 5999 // if (output.done) break; 6000 // 6001 // // From the generator to its user: 6002 // // Forward output, receive new input, and determine resume mode. 6003 // mode = kReturn; 6004 // try { 6005 // try { 6006 // RawYield(output); // See explanation above. 6007 // mode = kNext; 6008 // } catch (error) { 6009 // mode = kThrow; 6010 // } 6011 // } finally { 6012 // input = function.sent; 6013 // continue; 6014 // } 6015 // } 6016 // 6017 // if (mode === kReturn) { 6018 // return {value: output.value, done: true}; 6019 // } 6020 // output.value 6021 // } 6022 // 6023 // IteratorClose(iterator) expands to the following: 6024 // 6025 // let iteratorReturn = iterator.return; 6026 // if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) { 6027 // let output = %_Call(iteratorReturn, iterator); 6028 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output); 6029 // } 6030 // 6031 // IteratorClose(iterator, input, output) expands to the following: 6032 // 6033 // let iteratorReturn = iterator.return; 6034 // if (IS_NULL_OR_UNDEFINED(iteratorReturn)) return input; 6035 // output = %_Call(iteratorReturn, iterator, input); 6036 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output); 6037 6038 Expression* ParserTraits::RewriteYieldStar( 6039 Expression* generator, Expression* iterable, int pos) { 6040 6041 const int nopos = RelocInfo::kNoPosition; 6042 6043 auto factory = parser_->factory(); 6044 auto avfactory = parser_->ast_value_factory(); 6045 auto scope = parser_->scope_; 6046 auto zone = parser_->zone(); 6047 6048 6049 // Forward definition for break/continue statements. 6050 WhileStatement* loop = factory->NewWhileStatement(nullptr, nopos); 6051 6052 6053 // let input = undefined; 6054 Variable* var_input = scope->NewTemporary(avfactory->empty_string()); 6055 Statement* initialize_input; 6056 { 6057 Expression* input_proxy = factory->NewVariableProxy(var_input); 6058 Expression* assignment = factory->NewAssignment( 6059 Token::ASSIGN, input_proxy, factory->NewUndefinedLiteral(nopos), nopos); 6060 initialize_input = factory->NewExpressionStatement(assignment, nopos); 6061 } 6062 6063 6064 // let mode = kNext; 6065 Variable* var_mode = scope->NewTemporary(avfactory->empty_string()); 6066 Statement* initialize_mode; 6067 { 6068 Expression* mode_proxy = factory->NewVariableProxy(var_mode); 6069 Expression* knext = factory->NewSmiLiteral(JSGeneratorObject::kNext, nopos); 6070 Expression* assignment = 6071 factory->NewAssignment(Token::ASSIGN, mode_proxy, knext, nopos); 6072 initialize_mode = factory->NewExpressionStatement(assignment, nopos); 6073 } 6074 6075 6076 // let output = undefined; 6077 Variable* var_output = scope->NewTemporary(avfactory->empty_string()); 6078 Statement* initialize_output; 6079 { 6080 Expression* output_proxy = factory->NewVariableProxy(var_output); 6081 Expression* assignment = factory->NewAssignment( 6082 Token::ASSIGN, output_proxy, factory->NewUndefinedLiteral(nopos), 6083 nopos); 6084 initialize_output = factory->NewExpressionStatement(assignment, nopos); 6085 } 6086 6087 6088 // let iterator = iterable[Symbol.iterator]; 6089 Variable* var_iterator = scope->NewTemporary(avfactory->empty_string()); 6090 Statement* get_iterator; 6091 { 6092 Expression* iterator = GetIterator(iterable, factory, nopos); 6093 Expression* iterator_proxy = factory->NewVariableProxy(var_iterator); 6094 Expression* assignment = factory->NewAssignment( 6095 Token::ASSIGN, iterator_proxy, iterator, nopos); 6096 get_iterator = factory->NewExpressionStatement(assignment, nopos); 6097 } 6098 6099 6100 // if (!IS_RECEIVER(iterator)) throw MakeTypeError(kSymbolIteratorInvalid); 6101 Statement* validate_iterator; 6102 { 6103 Expression* is_receiver_call; 6104 { 6105 auto args = new (zone) ZoneList<Expression*>(1, zone); 6106 args->Add(factory->NewVariableProxy(var_iterator), zone); 6107 is_receiver_call = 6108 factory->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos); 6109 } 6110 6111 Statement* throw_call; 6112 { 6113 Expression* call = NewThrowTypeError( 6114 MessageTemplate::kSymbolIteratorInvalid, avfactory->empty_string(), 6115 nopos); 6116 throw_call = factory->NewExpressionStatement(call, nopos); 6117 } 6118 6119 validate_iterator = factory->NewIfStatement( 6120 is_receiver_call, factory->NewEmptyStatement(nopos), throw_call, nopos); 6121 } 6122 6123 6124 // output = iterator.next(input); 6125 Statement* call_next; 6126 { 6127 Expression* iterator_proxy = factory->NewVariableProxy(var_iterator); 6128 Expression* literal = 6129 factory->NewStringLiteral(avfactory->next_string(), nopos); 6130 Expression* next_property = 6131 factory->NewProperty(iterator_proxy, literal, nopos); 6132 Expression* input_proxy = factory->NewVariableProxy(var_input); 6133 auto args = new (zone) ZoneList<Expression*>(1, zone); 6134 args->Add(input_proxy, zone); 6135 Expression* call = factory->NewCall(next_property, args, nopos); 6136 Expression* output_proxy = factory->NewVariableProxy(var_output); 6137 Expression* assignment = 6138 factory->NewAssignment(Token::ASSIGN, output_proxy, call, nopos); 6139 call_next = factory->NewExpressionStatement(assignment, nopos); 6140 } 6141 6142 6143 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output); 6144 Statement* validate_next_output; 6145 { 6146 Expression* is_receiver_call; 6147 { 6148 auto args = new (zone) ZoneList<Expression*>(1, zone); 6149 args->Add(factory->NewVariableProxy(var_output), zone); 6150 is_receiver_call = 6151 factory->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos); 6152 } 6153 6154 Statement* throw_call; 6155 { 6156 auto args = new (zone) ZoneList<Expression*>(1, zone); 6157 args->Add(factory->NewVariableProxy(var_output), zone); 6158 Expression* call = factory->NewCallRuntime( 6159 Runtime::kThrowIteratorResultNotAnObject, args, nopos); 6160 throw_call = factory->NewExpressionStatement(call, nopos); 6161 } 6162 6163 validate_next_output = factory->NewIfStatement( 6164 is_receiver_call, factory->NewEmptyStatement(nopos), throw_call, nopos); 6165 } 6166 6167 6168 // let iteratorThrow = iterator.throw; 6169 Variable* var_throw = scope->NewTemporary(avfactory->empty_string()); 6170 Statement* get_throw; 6171 { 6172 Expression* iterator_proxy = factory->NewVariableProxy(var_iterator); 6173 Expression* literal = 6174 factory->NewStringLiteral(avfactory->throw_string(), nopos); 6175 Expression* property = 6176 factory->NewProperty(iterator_proxy, literal, nopos); 6177 Expression* throw_proxy = factory->NewVariableProxy(var_throw); 6178 Expression* assignment = factory->NewAssignment( 6179 Token::ASSIGN, throw_proxy, property, nopos); 6180 get_throw = factory->NewExpressionStatement(assignment, nopos); 6181 } 6182 6183 6184 // if (IS_NULL_OR_UNDEFINED(iteratorThrow) { 6185 // IteratorClose(iterator); 6186 // throw MakeTypeError(kThrowMethodMissing); 6187 // } 6188 Statement* check_throw; 6189 { 6190 Expression* condition = factory->NewCompareOperation( 6191 Token::EQ, factory->NewVariableProxy(var_throw), 6192 factory->NewNullLiteral(nopos), nopos); 6193 6194 Expression* call = NewThrowTypeError( 6195 MessageTemplate::kThrowMethodMissing, 6196 avfactory->empty_string(), nopos); 6197 Statement* throw_call = factory->NewExpressionStatement(call, nopos); 6198 6199 Block* then = factory->NewBlock(nullptr, 4+1, false, nopos); 6200 parser_->BuildIteratorCloseForCompletion( 6201 then->statements(), var_iterator, 6202 factory->NewSmiLiteral(Parser::kNormalCompletion, nopos)); 6203 then->statements()->Add(throw_call, zone); 6204 check_throw = factory->NewIfStatement( 6205 condition, then, factory->NewEmptyStatement(nopos), nopos); 6206 } 6207 6208 6209 // output = %_Call(iteratorThrow, iterator, input); 6210 Statement* call_throw; 6211 { 6212 auto args = new (zone) ZoneList<Expression*>(3, zone); 6213 args->Add(factory->NewVariableProxy(var_throw), zone); 6214 args->Add(factory->NewVariableProxy(var_iterator), zone); 6215 args->Add(factory->NewVariableProxy(var_input), zone); 6216 Expression* call = 6217 factory->NewCallRuntime(Runtime::kInlineCall, args, nopos); 6218 Expression* assignment = factory->NewAssignment( 6219 Token::ASSIGN, factory->NewVariableProxy(var_output), call, nopos); 6220 call_throw = factory->NewExpressionStatement(assignment, nopos); 6221 } 6222 6223 6224 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output); 6225 Statement* validate_throw_output; 6226 { 6227 Expression* is_receiver_call; 6228 { 6229 auto args = new (zone) ZoneList<Expression*>(1, zone); 6230 args->Add(factory->NewVariableProxy(var_output), zone); 6231 is_receiver_call = 6232 factory->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos); 6233 } 6234 6235 Statement* throw_call; 6236 { 6237 auto args = new (zone) ZoneList<Expression*>(1, zone); 6238 args->Add(factory->NewVariableProxy(var_output), zone); 6239 Expression* call = factory->NewCallRuntime( 6240 Runtime::kThrowIteratorResultNotAnObject, args, nopos); 6241 throw_call = factory->NewExpressionStatement(call, nopos); 6242 } 6243 6244 validate_throw_output = factory->NewIfStatement( 6245 is_receiver_call, factory->NewEmptyStatement(nopos), throw_call, nopos); 6246 } 6247 6248 6249 // if (output.done) break; 6250 Statement* if_done; 6251 { 6252 Expression* output_proxy = factory->NewVariableProxy(var_output); 6253 Expression* literal = 6254 factory->NewStringLiteral(avfactory->done_string(), nopos); 6255 Expression* property = factory->NewProperty(output_proxy, literal, nopos); 6256 BreakStatement* break_loop = factory->NewBreakStatement(loop, nopos); 6257 if_done = factory->NewIfStatement( 6258 property, break_loop, factory->NewEmptyStatement(nopos), nopos); 6259 } 6260 6261 6262 // mode = kReturn; 6263 Statement* set_mode_return; 6264 { 6265 Expression* mode_proxy = factory->NewVariableProxy(var_mode); 6266 Expression* kreturn = 6267 factory->NewSmiLiteral(JSGeneratorObject::kReturn, nopos); 6268 Expression* assignment = 6269 factory->NewAssignment(Token::ASSIGN, mode_proxy, kreturn, nopos); 6270 set_mode_return = factory->NewExpressionStatement(assignment, nopos); 6271 } 6272 6273 // Yield(output); 6274 Statement* yield_output; 6275 { 6276 Expression* output_proxy = factory->NewVariableProxy(var_output); 6277 Yield* yield = factory->NewYield(generator, output_proxy, nopos); 6278 yield_output = factory->NewExpressionStatement(yield, nopos); 6279 } 6280 6281 6282 // mode = kNext; 6283 Statement* set_mode_next; 6284 { 6285 Expression* mode_proxy = factory->NewVariableProxy(var_mode); 6286 Expression* knext = factory->NewSmiLiteral(JSGeneratorObject::kNext, nopos); 6287 Expression* assignment = 6288 factory->NewAssignment(Token::ASSIGN, mode_proxy, knext, nopos); 6289 set_mode_next = factory->NewExpressionStatement(assignment, nopos); 6290 } 6291 6292 6293 // mode = kThrow; 6294 Statement* set_mode_throw; 6295 { 6296 Expression* mode_proxy = factory->NewVariableProxy(var_mode); 6297 Expression* kthrow = 6298 factory->NewSmiLiteral(JSGeneratorObject::kThrow, nopos); 6299 Expression* assignment = 6300 factory->NewAssignment(Token::ASSIGN, mode_proxy, kthrow, nopos); 6301 set_mode_throw = factory->NewExpressionStatement(assignment, nopos); 6302 } 6303 6304 6305 // input = function.sent; 6306 Statement* get_input; 6307 { 6308 Expression* function_sent = FunctionSentExpression(scope, factory, nopos); 6309 Expression* input_proxy = factory->NewVariableProxy(var_input); 6310 Expression* assignment = factory->NewAssignment( 6311 Token::ASSIGN, input_proxy, function_sent, nopos); 6312 get_input = factory->NewExpressionStatement(assignment, nopos); 6313 } 6314 6315 6316 // if (mode === kReturn) { 6317 // return {value: output.value, done: true}; 6318 // } 6319 Statement* maybe_return_value; 6320 { 6321 Expression* mode_proxy = factory->NewVariableProxy(var_mode); 6322 Expression* kreturn = 6323 factory->NewSmiLiteral(JSGeneratorObject::kReturn, nopos); 6324 Expression* condition = factory->NewCompareOperation( 6325 Token::EQ_STRICT, mode_proxy, kreturn, nopos); 6326 6327 Expression* output_proxy = factory->NewVariableProxy(var_output); 6328 Expression* literal = 6329 factory->NewStringLiteral(avfactory->value_string(), nopos); 6330 Expression* property = factory->NewProperty(output_proxy, literal, nopos); 6331 Statement* return_value = 6332 factory->NewReturnStatement(BuildIteratorResult(property, true), nopos); 6333 6334 maybe_return_value = factory->NewIfStatement( 6335 condition, return_value, factory->NewEmptyStatement(nopos), nopos); 6336 } 6337 6338 6339 // output.value 6340 Statement* get_value; 6341 { 6342 Expression* output_proxy = factory->NewVariableProxy(var_output); 6343 Expression* literal = 6344 factory->NewStringLiteral(avfactory->value_string(), nopos); 6345 Expression* property = factory->NewProperty(output_proxy, literal, nopos); 6346 get_value = factory->NewExpressionStatement(property, nopos); 6347 } 6348 6349 6350 // Now put things together. 6351 6352 6353 // try { ... } catch(e) { ... } 6354 Statement* try_catch; 6355 { 6356 Block* try_block = factory->NewBlock(nullptr, 2, false, nopos); 6357 try_block->statements()->Add(yield_output, zone); 6358 try_block->statements()->Add(set_mode_next, zone); 6359 6360 Block* catch_block = factory->NewBlock(nullptr, 1, false, nopos); 6361 catch_block->statements()->Add(set_mode_throw, zone); 6362 6363 Scope* catch_scope = NewScope(scope, CATCH_SCOPE); 6364 catch_scope->set_is_hidden(); 6365 const AstRawString* name = avfactory->dot_catch_string(); 6366 Variable* catch_variable = 6367 catch_scope->DeclareLocal(name, VAR, kCreatedInitialized, 6368 Variable::NORMAL); 6369 6370 try_catch = factory->NewTryCatchStatement( 6371 try_block, catch_scope, catch_variable, catch_block, nopos); 6372 } 6373 6374 6375 // try { ... } finally { ... } 6376 Statement* try_finally; 6377 { 6378 Block* try_block = factory->NewBlock(nullptr, 1, false, nopos); 6379 try_block->statements()->Add(try_catch, zone); 6380 6381 Block* finally = factory->NewBlock(nullptr, 2, false, nopos); 6382 finally->statements()->Add(get_input, zone); 6383 finally->statements()->Add( 6384 factory->NewContinueStatement(loop, nopos), zone); 6385 6386 try_finally = factory->NewTryFinallyStatement(try_block, finally, nopos); 6387 } 6388 6389 6390 // switch (mode) { ... } 6391 SwitchStatement* switch_mode = factory->NewSwitchStatement(nullptr, nopos); 6392 { 6393 auto case_next = new (zone) ZoneList<Statement*>(3, zone); 6394 case_next->Add(call_next, zone); 6395 case_next->Add(validate_next_output, zone); 6396 case_next->Add(factory->NewBreakStatement(switch_mode, nopos), zone); 6397 6398 auto case_return = new (zone) ZoneList<Statement*>(5, zone); 6399 BuildIteratorClose(case_return, var_iterator, var_input, var_output); 6400 case_return->Add(factory->NewBreakStatement(switch_mode, nopos), zone); 6401 6402 auto case_throw = new (zone) ZoneList<Statement*>(5, zone); 6403 case_throw->Add(get_throw, zone); 6404 case_throw->Add(check_throw, zone); 6405 case_throw->Add(call_throw, zone); 6406 case_throw->Add(validate_throw_output, zone); 6407 case_throw->Add(factory->NewBreakStatement(switch_mode, nopos), zone); 6408 6409 auto cases = new (zone) ZoneList<CaseClause*>(3, zone); 6410 Expression* knext = factory->NewSmiLiteral(JSGeneratorObject::kNext, nopos); 6411 Expression* kreturn = 6412 factory->NewSmiLiteral(JSGeneratorObject::kReturn, nopos); 6413 Expression* kthrow = 6414 factory->NewSmiLiteral(JSGeneratorObject::kThrow, nopos); 6415 cases->Add(factory->NewCaseClause(knext, case_next, nopos), zone); 6416 cases->Add(factory->NewCaseClause(kreturn, case_return, nopos), zone); 6417 cases->Add(factory->NewCaseClause(kthrow, case_throw, nopos), zone); 6418 6419 switch_mode->Initialize(factory->NewVariableProxy(var_mode), cases); 6420 } 6421 6422 6423 // while (true) { ... } 6424 // Already defined earlier: WhileStatement* loop = ... 6425 { 6426 Block* loop_body = factory->NewBlock(nullptr, 4, false, nopos); 6427 loop_body->statements()->Add(switch_mode, zone); 6428 loop_body->statements()->Add(if_done, zone); 6429 loop_body->statements()->Add(set_mode_return, zone); 6430 loop_body->statements()->Add(try_finally, zone); 6431 6432 loop->Initialize(factory->NewBooleanLiteral(true, nopos), loop_body); 6433 } 6434 6435 6436 // do { ... } 6437 DoExpression* yield_star; 6438 { 6439 // The rewriter needs to process the get_value statement only, hence we 6440 // put the preceding statements into an init block. 6441 6442 Block* do_block_ = factory->NewBlock(nullptr, 7, true, nopos); 6443 do_block_->statements()->Add(initialize_input, zone); 6444 do_block_->statements()->Add(initialize_mode, zone); 6445 do_block_->statements()->Add(initialize_output, zone); 6446 do_block_->statements()->Add(get_iterator, zone); 6447 do_block_->statements()->Add(validate_iterator, zone); 6448 do_block_->statements()->Add(loop, zone); 6449 do_block_->statements()->Add(maybe_return_value, zone); 6450 6451 Block* do_block = factory->NewBlock(nullptr, 2, false, nopos); 6452 do_block->statements()->Add(do_block_, zone); 6453 do_block->statements()->Add(get_value, zone); 6454 6455 Variable* dot_result = scope->NewTemporary(avfactory->dot_result_string()); 6456 yield_star = factory->NewDoExpression(do_block, dot_result, nopos); 6457 Rewriter::Rewrite(parser_, yield_star, avfactory); 6458 } 6459 6460 return yield_star; 6461 } 6462 6463 Statement* ParserTraits::CheckCallable(Variable* var, Expression* error, 6464 int pos) { 6465 auto factory = parser_->factory(); 6466 auto avfactory = parser_->ast_value_factory(); 6467 const int nopos = RelocInfo::kNoPosition; 6468 Statement* validate_var; 6469 { 6470 Expression* type_of = factory->NewUnaryOperation( 6471 Token::TYPEOF, factory->NewVariableProxy(var), nopos); 6472 Expression* function_literal = 6473 factory->NewStringLiteral(avfactory->function_string(), nopos); 6474 Expression* condition = factory->NewCompareOperation( 6475 Token::EQ_STRICT, type_of, function_literal, nopos); 6476 6477 Statement* throw_call = factory->NewExpressionStatement(error, pos); 6478 6479 validate_var = factory->NewIfStatement( 6480 condition, factory->NewEmptyStatement(nopos), throw_call, nopos); 6481 } 6482 return validate_var; 6483 } 6484 6485 void ParserTraits::BuildIteratorClose(ZoneList<Statement*>* statements, 6486 Variable* iterator, Variable* input, 6487 Variable* var_output) { 6488 // 6489 // This function adds four statements to [statements], corresponding to the 6490 // following code: 6491 // 6492 // let iteratorReturn = iterator.return; 6493 // if (IS_NULL_OR_UNDEFINED(iteratorReturn) { 6494 // return {value: input, done: true}; 6495 // } 6496 // output = %_Call(iteratorReturn, iterator, input); 6497 // if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output); 6498 // 6499 6500 const int nopos = RelocInfo::kNoPosition; 6501 auto factory = parser_->factory(); 6502 auto avfactory = parser_->ast_value_factory(); 6503 auto zone = parser_->zone(); 6504 6505 // let iteratorReturn = iterator.return; 6506 Variable* var_return = var_output; // Reusing the output variable. 6507 Statement* get_return; 6508 { 6509 Expression* iterator_proxy = factory->NewVariableProxy(iterator); 6510 Expression* literal = 6511 factory->NewStringLiteral(avfactory->return_string(), nopos); 6512 Expression* property = 6513 factory->NewProperty(iterator_proxy, literal, nopos); 6514 Expression* return_proxy = factory->NewVariableProxy(var_return); 6515 Expression* assignment = factory->NewAssignment( 6516 Token::ASSIGN, return_proxy, property, nopos); 6517 get_return = factory->NewExpressionStatement(assignment, nopos); 6518 } 6519 6520 // if (IS_NULL_OR_UNDEFINED(iteratorReturn) { 6521 // return {value: input, done: true}; 6522 // } 6523 Statement* check_return; 6524 { 6525 Expression* condition = factory->NewCompareOperation( 6526 Token::EQ, factory->NewVariableProxy(var_return), 6527 factory->NewNullLiteral(nopos), nopos); 6528 6529 Expression* value = factory->NewVariableProxy(input); 6530 6531 Statement* return_input = 6532 factory->NewReturnStatement(BuildIteratorResult(value, true), nopos); 6533 6534 check_return = factory->NewIfStatement( 6535 condition, return_input, factory->NewEmptyStatement(nopos), nopos); 6536 } 6537 6538 // output = %_Call(iteratorReturn, iterator, input); 6539 Statement* call_return; 6540 { 6541 auto args = new (zone) ZoneList<Expression*>(3, zone); 6542 args->Add(factory->NewVariableProxy(var_return), zone); 6543 args->Add(factory->NewVariableProxy(iterator), zone); 6544 args->Add(factory->NewVariableProxy(input), zone); 6545 6546 Expression* call = 6547 factory->NewCallRuntime(Runtime::kInlineCall, args, nopos); 6548 Expression* output_proxy = factory->NewVariableProxy(var_output); 6549 Expression* assignment = factory->NewAssignment( 6550 Token::ASSIGN, output_proxy, call, nopos); 6551 call_return = factory->NewExpressionStatement(assignment, nopos); 6552 } 6553 6554 // if (!IS_RECEIVER(output)) %ThrowIteratorResultNotAnObject(output); 6555 Statement* validate_output; 6556 { 6557 Expression* is_receiver_call; 6558 { 6559 auto args = new (zone) ZoneList<Expression*>(1, zone); 6560 args->Add(factory->NewVariableProxy(var_output), zone); 6561 is_receiver_call = 6562 factory->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos); 6563 } 6564 6565 Statement* throw_call; 6566 { 6567 auto args = new (zone) ZoneList<Expression*>(1, zone); 6568 args->Add(factory->NewVariableProxy(var_output), zone); 6569 Expression* call = factory->NewCallRuntime( 6570 Runtime::kThrowIteratorResultNotAnObject, args, nopos); 6571 throw_call = factory->NewExpressionStatement(call, nopos); 6572 } 6573 6574 validate_output = factory->NewIfStatement( 6575 is_receiver_call, factory->NewEmptyStatement(nopos), throw_call, nopos); 6576 } 6577 6578 statements->Add(get_return, zone); 6579 statements->Add(check_return, zone); 6580 statements->Add(call_return, zone); 6581 statements->Add(validate_output, zone); 6582 } 6583 6584 void ParserTraits::FinalizeIteratorUse(Variable* completion, 6585 Expression* condition, Variable* iter, 6586 Block* iterator_use, Block* target) { 6587 // 6588 // This function adds two statements to [target], corresponding to the 6589 // following code: 6590 // 6591 // completion = kNormalCompletion; 6592 // try { 6593 // try { 6594 // iterator_use 6595 // } catch(e) { 6596 // if (completion === kAbruptCompletion) completion = kThrowCompletion; 6597 // %ReThrow(e); 6598 // } 6599 // } finally { 6600 // if (condition) { 6601 // #BuildIteratorCloseForCompletion(iter, completion) 6602 // } 6603 // } 6604 // 6605 6606 const int nopos = RelocInfo::kNoPosition; 6607 auto factory = parser_->factory(); 6608 auto avfactory = parser_->ast_value_factory(); 6609 auto scope = parser_->scope_; 6610 auto zone = parser_->zone(); 6611 6612 // completion = kNormalCompletion; 6613 Statement* initialize_completion; 6614 { 6615 Expression* proxy = factory->NewVariableProxy(completion); 6616 Expression* assignment = factory->NewAssignment( 6617 Token::ASSIGN, proxy, 6618 factory->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos); 6619 initialize_completion = factory->NewExpressionStatement(assignment, nopos); 6620 } 6621 6622 // if (completion === kAbruptCompletion) completion = kThrowCompletion; 6623 Statement* set_completion_throw; 6624 { 6625 Expression* condition = factory->NewCompareOperation( 6626 Token::EQ_STRICT, factory->NewVariableProxy(completion), 6627 factory->NewSmiLiteral(Parser::kAbruptCompletion, nopos), nopos); 6628 6629 Expression* proxy = factory->NewVariableProxy(completion); 6630 Expression* assignment = factory->NewAssignment( 6631 Token::ASSIGN, proxy, 6632 factory->NewSmiLiteral(Parser::kThrowCompletion, nopos), nopos); 6633 Statement* statement = factory->NewExpressionStatement(assignment, nopos); 6634 set_completion_throw = factory->NewIfStatement( 6635 condition, statement, factory->NewEmptyStatement(nopos), nopos); 6636 } 6637 6638 // if (condition) { 6639 // #BuildIteratorCloseForCompletion(iter, completion) 6640 // } 6641 Block* maybe_close; 6642 { 6643 Block* block = factory->NewBlock(nullptr, 2, true, nopos); 6644 Expression* proxy = factory->NewVariableProxy(completion); 6645 parser_->BuildIteratorCloseForCompletion(block->statements(), iter, proxy); 6646 DCHECK(block->statements()->length() == 2); 6647 6648 maybe_close = factory->NewBlock(nullptr, 1, true, nopos); 6649 maybe_close->statements()->Add( 6650 factory->NewIfStatement(condition, block, 6651 factory->NewEmptyStatement(nopos), nopos), 6652 zone); 6653 } 6654 6655 // try { #try_block } 6656 // catch(e) { 6657 // #set_completion_throw; 6658 // %ReThrow(e); 6659 // } 6660 Statement* try_catch; 6661 { 6662 Scope* catch_scope = parser_->NewScope(scope, CATCH_SCOPE); 6663 Variable* catch_variable = 6664 catch_scope->DeclareLocal(avfactory->dot_catch_string(), VAR, 6665 kCreatedInitialized, Variable::NORMAL); 6666 catch_scope->set_is_hidden(); 6667 6668 Statement* rethrow; 6669 // We use %ReThrow rather than the ordinary throw because we want to 6670 // preserve the original exception message. This is also why we create a 6671 // TryCatchStatementForReThrow below (which does not clear the pending 6672 // message), rather than a TryCatchStatement. 6673 { 6674 auto args = new (zone) ZoneList<Expression*>(1, zone); 6675 args->Add(factory->NewVariableProxy(catch_variable), zone); 6676 rethrow = factory->NewExpressionStatement( 6677 factory->NewCallRuntime(Runtime::kReThrow, args, nopos), nopos); 6678 } 6679 6680 Block* catch_block = factory->NewBlock(nullptr, 2, false, nopos); 6681 catch_block->statements()->Add(set_completion_throw, zone); 6682 catch_block->statements()->Add(rethrow, zone); 6683 6684 try_catch = factory->NewTryCatchStatementForReThrow( 6685 iterator_use, catch_scope, catch_variable, catch_block, nopos); 6686 } 6687 6688 // try { #try_catch } finally { #maybe_close } 6689 Statement* try_finally; 6690 { 6691 Block* try_block = factory->NewBlock(nullptr, 1, false, nopos); 6692 try_block->statements()->Add(try_catch, zone); 6693 6694 try_finally = 6695 factory->NewTryFinallyStatement(try_block, maybe_close, nopos); 6696 } 6697 6698 target->statements()->Add(initialize_completion, zone); 6699 target->statements()->Add(try_finally, zone); 6700 } 6701 6702 void ParserTraits::BuildIteratorCloseForCompletion( 6703 ZoneList<Statement*>* statements, Variable* iterator, 6704 Expression* completion) { 6705 // 6706 // This function adds two statements to [statements], corresponding to the 6707 // following code: 6708 // 6709 // let iteratorReturn = iterator.return; 6710 // if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) { 6711 // if (completion === kThrowCompletion) { 6712 // if (!IS_CALLABLE(iteratorReturn)) { 6713 // throw MakeTypeError(kReturnMethodNotCallable); 6714 // } 6715 // try { %_Call(iteratorReturn, iterator) } catch (_) { } 6716 // } else { 6717 // let output = %_Call(iteratorReturn, iterator); 6718 // if (!IS_RECEIVER(output)) { 6719 // %ThrowIterResultNotAnObject(output); 6720 // } 6721 // } 6722 // } 6723 // 6724 6725 const int nopos = RelocInfo::kNoPosition; 6726 auto factory = parser_->factory(); 6727 auto avfactory = parser_->ast_value_factory(); 6728 auto scope = parser_->scope_; 6729 auto zone = parser_->zone(); 6730 6731 6732 // let iteratorReturn = iterator.return; 6733 Variable* var_return = scope->NewTemporary(avfactory->empty_string()); 6734 Statement* get_return; 6735 { 6736 Expression* iterator_proxy = factory->NewVariableProxy(iterator); 6737 Expression* literal = 6738 factory->NewStringLiteral(avfactory->return_string(), nopos); 6739 Expression* property = 6740 factory->NewProperty(iterator_proxy, literal, nopos); 6741 Expression* return_proxy = factory->NewVariableProxy(var_return); 6742 Expression* assignment = factory->NewAssignment( 6743 Token::ASSIGN, return_proxy, property, nopos); 6744 get_return = factory->NewExpressionStatement(assignment, nopos); 6745 } 6746 6747 // if (!IS_CALLABLE(iteratorReturn)) { 6748 // throw MakeTypeError(kReturnMethodNotCallable); 6749 // } 6750 Statement* check_return_callable; 6751 { 6752 Expression* throw_expr = NewThrowTypeError( 6753 MessageTemplate::kReturnMethodNotCallable, 6754 avfactory->empty_string(), nopos); 6755 check_return_callable = CheckCallable(var_return, throw_expr, nopos); 6756 } 6757 6758 // try { %_Call(iteratorReturn, iterator) } catch (_) { } 6759 Statement* try_call_return; 6760 { 6761 auto args = new (zone) ZoneList<Expression*>(2, zone); 6762 args->Add(factory->NewVariableProxy(var_return), zone); 6763 args->Add(factory->NewVariableProxy(iterator), zone); 6764 6765 Expression* call = 6766 factory->NewCallRuntime(Runtime::kInlineCall, args, nopos); 6767 6768 Block* try_block = factory->NewBlock(nullptr, 1, false, nopos); 6769 try_block->statements()->Add(factory->NewExpressionStatement(call, nopos), 6770 zone); 6771 6772 Block* catch_block = factory->NewBlock(nullptr, 0, false, nopos); 6773 6774 Scope* catch_scope = NewScope(scope, CATCH_SCOPE); 6775 Variable* catch_variable = catch_scope->DeclareLocal( 6776 avfactory->dot_catch_string(), VAR, kCreatedInitialized, 6777 Variable::NORMAL); 6778 catch_scope->set_is_hidden(); 6779 6780 try_call_return = factory->NewTryCatchStatement( 6781 try_block, catch_scope, catch_variable, catch_block, nopos); 6782 } 6783 6784 // let output = %_Call(iteratorReturn, iterator); 6785 // if (!IS_RECEIVER(output)) { 6786 // %ThrowIteratorResultNotAnObject(output); 6787 // } 6788 Block* validate_return; 6789 { 6790 Variable* var_output = scope->NewTemporary(avfactory->empty_string()); 6791 Statement* call_return; 6792 { 6793 auto args = new (zone) ZoneList<Expression*>(2, zone); 6794 args->Add(factory->NewVariableProxy(var_return), zone); 6795 args->Add(factory->NewVariableProxy(iterator), zone); 6796 Expression* call = 6797 factory->NewCallRuntime(Runtime::kInlineCall, args, nopos); 6798 6799 Expression* output_proxy = factory->NewVariableProxy(var_output); 6800 Expression* assignment = 6801 factory->NewAssignment(Token::ASSIGN, output_proxy, call, nopos); 6802 call_return = factory->NewExpressionStatement(assignment, nopos); 6803 } 6804 6805 Expression* is_receiver_call; 6806 { 6807 auto args = new (zone) ZoneList<Expression*>(1, zone); 6808 args->Add(factory->NewVariableProxy(var_output), zone); 6809 is_receiver_call = 6810 factory->NewCallRuntime(Runtime::kInlineIsJSReceiver, args, nopos); 6811 } 6812 6813 Statement* throw_call; 6814 { 6815 auto args = new (zone) ZoneList<Expression*>(1, zone); 6816 args->Add(factory->NewVariableProxy(var_output), zone); 6817 Expression* call = factory->NewCallRuntime( 6818 Runtime::kThrowIteratorResultNotAnObject, args, nopos); 6819 throw_call = factory->NewExpressionStatement(call, nopos); 6820 } 6821 6822 Statement* check_return = factory->NewIfStatement( 6823 is_receiver_call, factory->NewEmptyStatement(nopos), throw_call, nopos); 6824 6825 validate_return = factory->NewBlock(nullptr, 2, false, nopos); 6826 validate_return->statements()->Add(call_return, zone); 6827 validate_return->statements()->Add(check_return, zone); 6828 } 6829 6830 // if (completion === kThrowCompletion) { 6831 // #check_return_callable; 6832 // #try_call_return; 6833 // } else { 6834 // #validate_return; 6835 // } 6836 Statement* call_return_carefully; 6837 { 6838 Expression* condition = factory->NewCompareOperation( 6839 Token::EQ_STRICT, completion, 6840 factory->NewSmiLiteral(Parser::kThrowCompletion, nopos), nopos); 6841 6842 Block* then_block = factory->NewBlock(nullptr, 2, false, nopos); 6843 then_block->statements()->Add(check_return_callable, zone); 6844 then_block->statements()->Add(try_call_return, zone); 6845 6846 call_return_carefully = 6847 factory->NewIfStatement(condition, then_block, validate_return, nopos); 6848 } 6849 6850 // if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) { ... } 6851 Statement* maybe_call_return; 6852 { 6853 Expression* condition = factory->NewCompareOperation( 6854 Token::EQ, factory->NewVariableProxy(var_return), 6855 factory->NewNullLiteral(nopos), nopos); 6856 6857 maybe_call_return = 6858 factory->NewIfStatement(condition, factory->NewEmptyStatement(nopos), 6859 call_return_carefully, nopos); 6860 } 6861 6862 6863 statements->Add(get_return, zone); 6864 statements->Add(maybe_call_return, zone); 6865 } 6866 6867 6868 Statement* ParserTraits::FinalizeForOfStatement(ForOfStatement* loop, int pos) { 6869 // 6870 // This function replaces the loop with the following wrapping: 6871 // 6872 // let each; 6873 // let completion = kNormalCompletion; 6874 // try { 6875 // try { 6876 // #loop; 6877 // } catch(e) { 6878 // if (completion === kAbruptCompletion) completion = kThrowCompletion; 6879 // %ReThrow(e); 6880 // } 6881 // } finally { 6882 // if (!(completion === kNormalCompletion || IS_UNDEFINED(#iterator))) { 6883 // #BuildIteratorCloseForCompletion(#iterator, completion) 6884 // } 6885 // } 6886 // 6887 // where the loop's body is wrapped as follows: 6888 // 6889 // { 6890 // #loop-body 6891 // {{completion = kNormalCompletion;}} 6892 // } 6893 // 6894 // and the loop's assign_each is wrapped as follows 6895 // 6896 // do { 6897 // {{completion = kAbruptCompletion;}} 6898 // #assign-each 6899 // } 6900 // 6901 6902 const int nopos = RelocInfo::kNoPosition; 6903 auto factory = parser_->factory(); 6904 auto avfactory = parser_->ast_value_factory(); 6905 auto scope = parser_->scope_; 6906 auto zone = parser_->zone(); 6907 6908 Variable* var_completion = scope->NewTemporary(avfactory->empty_string()); 6909 6910 // let each; 6911 Variable* var_each = scope->NewTemporary(avfactory->empty_string()); 6912 Statement* initialize_each; 6913 { 6914 Expression* proxy = factory->NewVariableProxy(var_each); 6915 Expression* assignment = factory->NewAssignment( 6916 Token::ASSIGN, proxy, 6917 factory->NewUndefinedLiteral(nopos), nopos); 6918 initialize_each = 6919 factory->NewExpressionStatement(assignment, nopos); 6920 } 6921 6922 // !(completion === kNormalCompletion || IS_UNDEFINED(#iterator)) 6923 Expression* closing_condition; 6924 { 6925 Expression* lhs = factory->NewCompareOperation( 6926 Token::EQ_STRICT, factory->NewVariableProxy(var_completion), 6927 factory->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos); 6928 Expression* rhs = factory->NewCompareOperation( 6929 Token::EQ_STRICT, factory->NewVariableProxy(loop->iterator()), 6930 factory->NewUndefinedLiteral(nopos), nopos); 6931 closing_condition = factory->NewUnaryOperation( 6932 Token::NOT, factory->NewBinaryOperation(Token::OR, lhs, rhs, nopos), 6933 nopos); 6934 } 6935 6936 // {{completion = kNormalCompletion;}} 6937 Statement* set_completion_normal; 6938 { 6939 Expression* proxy = factory->NewVariableProxy(var_completion); 6940 Expression* assignment = factory->NewAssignment( 6941 Token::ASSIGN, proxy, 6942 factory->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos); 6943 6944 Block* block = factory->NewBlock(nullptr, 1, true, nopos); 6945 block->statements()->Add( 6946 factory->NewExpressionStatement(assignment, nopos), zone); 6947 set_completion_normal = block; 6948 } 6949 6950 // {{completion = kAbruptCompletion;}} 6951 Statement* set_completion_abrupt; 6952 { 6953 Expression* proxy = factory->NewVariableProxy(var_completion); 6954 Expression* assignment = factory->NewAssignment( 6955 Token::ASSIGN, proxy, 6956 factory->NewSmiLiteral(Parser::kAbruptCompletion, nopos), nopos); 6957 6958 Block* block = factory->NewBlock(nullptr, 1, true, nopos); 6959 block->statements()->Add(factory->NewExpressionStatement(assignment, nopos), 6960 zone); 6961 set_completion_abrupt = block; 6962 } 6963 6964 // { #loop-body; #set_completion_normal } 6965 Block* new_body = factory->NewBlock(nullptr, 2, false, nopos); 6966 { 6967 new_body->statements()->Add(loop->body(), zone); 6968 new_body->statements()->Add(set_completion_normal, zone); 6969 } 6970 6971 // { #set_completion_abrupt; #assign-each } 6972 Block* new_assign_each = factory->NewBlock(nullptr, 2, false, nopos); 6973 { 6974 new_assign_each->statements()->Add(set_completion_abrupt, zone); 6975 new_assign_each->statements()->Add( 6976 factory->NewExpressionStatement(loop->assign_each(), nopos), zone); 6977 } 6978 6979 // Now put things together. 6980 6981 loop->set_body(new_body); 6982 loop->set_assign_each( 6983 factory->NewDoExpression(new_assign_each, var_each, nopos)); 6984 6985 Statement* final_loop; 6986 { 6987 Block* target = factory->NewBlock(nullptr, 3, false, nopos); 6988 target->statements()->Add(initialize_each, zone); 6989 6990 Block* try_block = factory->NewBlock(nullptr, 1, false, nopos); 6991 try_block->statements()->Add(loop, zone); 6992 6993 FinalizeIteratorUse(var_completion, closing_condition, loop->iterator(), 6994 try_block, target); 6995 final_loop = target; 6996 } 6997 6998 return final_loop; 6999 } 7000 7001 7002 } // namespace internal 7003 } // namespace v8 7004