Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(188)

Side by Side Diff: src/parser.cc

Issue 8404030: Version 3.7.1 (Closed) Base URL: http://v8.googlecode.com/svn/trunk/
Patch Set: Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/parser.h ('k') | src/preparser.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after
400 unsigned ScriptDataImpl::Read(int position) { 400 unsigned ScriptDataImpl::Read(int position) {
401 return store_[PreparseDataConstants::kHeaderSize + position]; 401 return store_[PreparseDataConstants::kHeaderSize + position];
402 } 402 }
403 403
404 404
405 unsigned* ScriptDataImpl::ReadAddress(int position) { 405 unsigned* ScriptDataImpl::ReadAddress(int position) {
406 return &store_[PreparseDataConstants::kHeaderSize + position]; 406 return &store_[PreparseDataConstants::kHeaderSize + position];
407 } 407 }
408 408
409 409
410 Scope* Parser::NewScope(Scope* parent, Scope::Type type, bool inside_with) { 410 Scope* Parser::NewScope(Scope* parent, ScopeType type) {
411 Scope* result = new(zone()) Scope(parent, type); 411 Scope* result = new(zone()) Scope(parent, type);
412 result->Initialize(inside_with); 412 result->Initialize();
413 return result; 413 return result;
414 } 414 }
415 415
416 416
417 // ---------------------------------------------------------------------------- 417 // ----------------------------------------------------------------------------
418 // Target is a support class to facilitate manipulation of the 418 // Target is a support class to facilitate manipulation of the
419 // Parser's target_stack_ (the stack of potential 'break' and 419 // Parser's target_stack_ (the stack of potential 'break' and
420 // 'continue' statement targets). Upon construction, a new target is 420 // 'continue' statement targets). Upon construction, a new target is
421 // added; it is removed upon destruction. 421 // added; it is removed upon destruction.
422 422
(...skipping 29 matching lines...) Expand all
452 *variable_ = previous_; 452 *variable_ = previous_;
453 } 453 }
454 454
455 private: 455 private:
456 Target** variable_; 456 Target** variable_;
457 Target* previous_; 457 Target* previous_;
458 }; 458 };
459 459
460 460
461 // ---------------------------------------------------------------------------- 461 // ----------------------------------------------------------------------------
462 // LexicalScope is a support class to facilitate manipulation of the 462 // LexicalScope and SaveScope are stack allocated support classes to facilitate
463 // Parser's scope stack. The constructor sets the parser's top scope 463 // anipulation of the Parser's scope stack. The constructor sets the parser's
464 // to the incoming scope, and the destructor resets it. 464 // top scope to the incoming scope, and the destructor resets it. Additionally,
465 // 465 // LexicalScope stores transient information used during parsing.
466 // Additionally, it stores transient information used during parsing. 466
467 // These scopes are not kept around after parsing or referenced by syntax 467
468 // trees so they can be stack-allocated and hence used by the pre-parser. 468 class SaveScope BASE_EMBEDDED {
469 public:
470 SaveScope(Parser* parser, Scope* scope)
471 : parser_(parser),
472 previous_top_scope_(parser->top_scope_) {
473 parser->top_scope_ = scope;
474 }
475
476 ~SaveScope() {
477 parser_->top_scope_ = previous_top_scope_;
478 }
479
480 private:
481 // Bookkeeping
482 Parser* parser_;
483 // Previous values
484 Scope* previous_top_scope_;
485 };
486
469 487
470 class LexicalScope BASE_EMBEDDED { 488 class LexicalScope BASE_EMBEDDED {
471 public: 489 public:
472 LexicalScope(Parser* parser, Scope* scope, Isolate* isolate); 490 LexicalScope(Parser* parser, Scope* scope, Isolate* isolate);
473 ~LexicalScope(); 491 ~LexicalScope();
474 492
475 int NextMaterializedLiteralIndex() { 493 int NextMaterializedLiteralIndex() {
476 int next_index = 494 int next_index =
477 materialized_literal_count_ + JSFunction::kLiteralsPrefixSize; 495 materialized_literal_count_ + JSFunction::kLiteralsPrefixSize;
478 materialized_literal_count_++; 496 materialized_literal_count_++;
(...skipping 30 matching lines...) Expand all
509 // Keeps track of assignments to properties of this. Used for 527 // Keeps track of assignments to properties of this. Used for
510 // optimizing constructors. 528 // optimizing constructors.
511 bool only_simple_this_property_assignments_; 529 bool only_simple_this_property_assignments_;
512 Handle<FixedArray> this_property_assignments_; 530 Handle<FixedArray> this_property_assignments_;
513 531
514 // Bookkeeping 532 // Bookkeeping
515 Parser* parser_; 533 Parser* parser_;
516 // Previous values 534 // Previous values
517 LexicalScope* lexical_scope_parent_; 535 LexicalScope* lexical_scope_parent_;
518 Scope* previous_scope_; 536 Scope* previous_scope_;
519 int previous_with_nesting_level_;
520 unsigned previous_ast_node_id_; 537 unsigned previous_ast_node_id_;
521 }; 538 };
522 539
523 540
524 LexicalScope::LexicalScope(Parser* parser, Scope* scope, Isolate* isolate) 541 LexicalScope::LexicalScope(Parser* parser, Scope* scope, Isolate* isolate)
525 : materialized_literal_count_(0), 542 : materialized_literal_count_(0),
526 expected_property_count_(0), 543 expected_property_count_(0),
527 only_simple_this_property_assignments_(false), 544 only_simple_this_property_assignments_(false),
528 this_property_assignments_(isolate->factory()->empty_fixed_array()), 545 this_property_assignments_(isolate->factory()->empty_fixed_array()),
529 parser_(parser), 546 parser_(parser),
530 lexical_scope_parent_(parser->lexical_scope_), 547 lexical_scope_parent_(parser->lexical_scope_),
531 previous_scope_(parser->top_scope_), 548 previous_scope_(parser->top_scope_),
532 previous_with_nesting_level_(parser->with_nesting_level_),
533 previous_ast_node_id_(isolate->ast_node_id()) { 549 previous_ast_node_id_(isolate->ast_node_id()) {
534 parser->top_scope_ = scope; 550 parser->top_scope_ = scope;
535 parser->lexical_scope_ = this; 551 parser->lexical_scope_ = this;
536 parser->with_nesting_level_ = 0;
537 isolate->set_ast_node_id(AstNode::kDeclarationsId + 1); 552 isolate->set_ast_node_id(AstNode::kDeclarationsId + 1);
538 } 553 }
539 554
540 555
541 LexicalScope::~LexicalScope() { 556 LexicalScope::~LexicalScope() {
542 parser_->top_scope_ = previous_scope_; 557 parser_->top_scope_ = previous_scope_;
543 parser_->lexical_scope_ = lexical_scope_parent_; 558 parser_->lexical_scope_ = lexical_scope_parent_;
544 parser_->with_nesting_level_ = previous_with_nesting_level_;
545 parser_->isolate()->set_ast_node_id(previous_ast_node_id_); 559 parser_->isolate()->set_ast_node_id(previous_ast_node_id_);
546 } 560 }
547 561
548 562
549 // ---------------------------------------------------------------------------- 563 // ----------------------------------------------------------------------------
550 // The CHECK_OK macro is a convenient macro to enforce error 564 // The CHECK_OK macro is a convenient macro to enforce error
551 // handling for functions that may fail (by returning !*ok). 565 // handling for functions that may fail (by returning !*ok).
552 // 566 //
553 // CAUTION: This macro appends extra statements after a call, 567 // CAUTION: This macro appends extra statements after a call,
554 // thus it must never be used where only a single statement 568 // thus it must never be used where only a single statement
(...skipping 16 matching lines...) Expand all
571 585
572 Parser::Parser(Handle<Script> script, 586 Parser::Parser(Handle<Script> script,
573 bool allow_natives_syntax, 587 bool allow_natives_syntax,
574 v8::Extension* extension, 588 v8::Extension* extension,
575 ScriptDataImpl* pre_data) 589 ScriptDataImpl* pre_data)
576 : isolate_(script->GetIsolate()), 590 : isolate_(script->GetIsolate()),
577 symbol_cache_(pre_data ? pre_data->symbol_count() : 0), 591 symbol_cache_(pre_data ? pre_data->symbol_count() : 0),
578 script_(script), 592 script_(script),
579 scanner_(isolate_->unicode_cache()), 593 scanner_(isolate_->unicode_cache()),
580 top_scope_(NULL), 594 top_scope_(NULL),
581 with_nesting_level_(0),
582 lexical_scope_(NULL), 595 lexical_scope_(NULL),
583 target_stack_(NULL), 596 target_stack_(NULL),
584 allow_natives_syntax_(allow_natives_syntax), 597 allow_natives_syntax_(allow_natives_syntax),
585 extension_(extension), 598 extension_(extension),
586 pre_data_(pre_data), 599 pre_data_(pre_data),
587 fni_(NULL), 600 fni_(NULL),
588 stack_overflow_(false), 601 stack_overflow_(false),
589 parenthesized_function_(false), 602 parenthesized_function_(false),
590 harmony_scoping_(false) { 603 harmony_scoping_(false) {
591 AstNode::ResetIds(); 604 AstNode::ResetIds();
(...skipping 24 matching lines...) Expand all
616 scanner_.Initialize(&stream); 629 scanner_.Initialize(&stream);
617 return DoParseProgram(source, in_global_context, strict_mode, &zone_scope); 630 return DoParseProgram(source, in_global_context, strict_mode, &zone_scope);
618 } 631 }
619 } 632 }
620 633
621 634
622 FunctionLiteral* Parser::DoParseProgram(Handle<String> source, 635 FunctionLiteral* Parser::DoParseProgram(Handle<String> source,
623 bool in_global_context, 636 bool in_global_context,
624 StrictModeFlag strict_mode, 637 StrictModeFlag strict_mode,
625 ZoneScope* zone_scope) { 638 ZoneScope* zone_scope) {
639 ASSERT(top_scope_ == NULL);
626 ASSERT(target_stack_ == NULL); 640 ASSERT(target_stack_ == NULL);
627 if (pre_data_ != NULL) pre_data_->Initialize(); 641 if (pre_data_ != NULL) pre_data_->Initialize();
628 642
629 // Compute the parsing mode. 643 // Compute the parsing mode.
630 mode_ = FLAG_lazy ? PARSE_LAZILY : PARSE_EAGERLY; 644 mode_ = FLAG_lazy ? PARSE_LAZILY : PARSE_EAGERLY;
631 if (allow_natives_syntax_ || extension_ != NULL) mode_ = PARSE_EAGERLY; 645 if (allow_natives_syntax_ || extension_ != NULL) mode_ = PARSE_EAGERLY;
632 646
633 Scope::Type type = 647 ScopeType type = in_global_context ? GLOBAL_SCOPE : EVAL_SCOPE;
634 in_global_context
635 ? Scope::GLOBAL_SCOPE
636 : Scope::EVAL_SCOPE;
637 Handle<String> no_name = isolate()->factory()->empty_symbol(); 648 Handle<String> no_name = isolate()->factory()->empty_symbol();
638 649
639 FunctionLiteral* result = NULL; 650 FunctionLiteral* result = NULL;
640 { Scope* scope = NewScope(top_scope_, type, inside_with()); 651 { Scope* scope = NewScope(top_scope_, type);
652 scope->set_start_position(0);
653 scope->set_end_position(source->length());
641 LexicalScope lexical_scope(this, scope, isolate()); 654 LexicalScope lexical_scope(this, scope, isolate());
642 if (strict_mode == kStrictMode) { 655 ASSERT(top_scope_->strict_mode_flag() == kNonStrictMode);
643 top_scope_->EnableStrictMode(); 656 top_scope_->SetStrictModeFlag(strict_mode);
644 }
645 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16); 657 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16);
646 bool ok = true; 658 bool ok = true;
647 int beg_loc = scanner().location().beg_pos; 659 int beg_loc = scanner().location().beg_pos;
648 ParseSourceElements(body, Token::EOS, &ok); 660 ParseSourceElements(body, Token::EOS, &ok);
649 if (ok && top_scope_->is_strict_mode()) { 661 if (ok && top_scope_->is_strict_mode()) {
650 CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok); 662 CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok);
651 } 663 }
652 664
653 if (ok && harmony_scoping_) { 665 if (ok && harmony_scoping_) {
654 CheckConflictingVarDeclarations(scope, &ok); 666 CheckConflictingVarDeclarations(scope, &ok);
655 } 667 }
656 668
657 if (ok) { 669 if (ok) {
658 result = new(zone()) FunctionLiteral( 670 result = new(zone()) FunctionLiteral(
659 isolate(), 671 isolate(),
660 no_name, 672 no_name,
661 top_scope_, 673 top_scope_,
662 body, 674 body,
663 lexical_scope.materialized_literal_count(), 675 lexical_scope.materialized_literal_count(),
664 lexical_scope.expected_property_count(), 676 lexical_scope.expected_property_count(),
665 lexical_scope.only_simple_this_property_assignments(), 677 lexical_scope.only_simple_this_property_assignments(),
666 lexical_scope.this_property_assignments(), 678 lexical_scope.this_property_assignments(),
667 0, 679 0,
668 0,
669 source->length(),
670 FunctionLiteral::ANONYMOUS_EXPRESSION, 680 FunctionLiteral::ANONYMOUS_EXPRESSION,
671 false); // Does not have duplicate parameters. 681 false); // Does not have duplicate parameters.
672 } else if (stack_overflow_) { 682 } else if (stack_overflow_) {
673 isolate()->StackOverflow(); 683 isolate()->StackOverflow();
674 } 684 }
675 } 685 }
676 686
677 // Make sure the target stack is empty. 687 // Make sure the target stack is empty.
678 ASSERT(target_stack_ == NULL); 688 ASSERT(target_stack_ == NULL);
679 689
(...skipping 27 matching lines...) Expand all
707 return result; 717 return result;
708 } 718 }
709 } 719 }
710 720
711 721
712 FunctionLiteral* Parser::ParseLazy(CompilationInfo* info, 722 FunctionLiteral* Parser::ParseLazy(CompilationInfo* info,
713 UC16CharacterStream* source, 723 UC16CharacterStream* source,
714 ZoneScope* zone_scope) { 724 ZoneScope* zone_scope) {
715 Handle<SharedFunctionInfo> shared_info = info->shared_info(); 725 Handle<SharedFunctionInfo> shared_info = info->shared_info();
716 scanner_.Initialize(source); 726 scanner_.Initialize(source);
727 ASSERT(top_scope_ == NULL);
717 ASSERT(target_stack_ == NULL); 728 ASSERT(target_stack_ == NULL);
718 729
719 Handle<String> name(String::cast(shared_info->name())); 730 Handle<String> name(String::cast(shared_info->name()));
720 fni_ = new(zone()) FuncNameInferrer(isolate()); 731 fni_ = new(zone()) FuncNameInferrer(isolate());
721 fni_->PushEnclosingName(name); 732 fni_->PushEnclosingName(name);
722 733
723 mode_ = PARSE_EAGERLY; 734 mode_ = PARSE_EAGERLY;
724 735
725 // Place holder for the result. 736 // Place holder for the result.
726 FunctionLiteral* result = NULL; 737 FunctionLiteral* result = NULL;
727 738
728 { 739 {
729 // Parse the function literal. 740 // Parse the function literal.
730 Scope* scope = NewScope(top_scope_, Scope::GLOBAL_SCOPE, inside_with()); 741 Scope* scope = NewScope(top_scope_, GLOBAL_SCOPE);
731 if (!info->closure().is_null()) { 742 if (!info->closure().is_null()) {
732 scope = Scope::DeserializeScopeChain(info, scope); 743 scope = Scope::DeserializeScopeChain(info, scope);
733 } 744 }
734 LexicalScope lexical_scope(this, scope, isolate()); 745 LexicalScope lexical_scope(this, scope, isolate());
735 746 ASSERT(scope->strict_mode_flag() == kNonStrictMode ||
736 if (shared_info->strict_mode()) { 747 scope->strict_mode_flag() == info->strict_mode_flag());
737 top_scope_->EnableStrictMode(); 748 ASSERT(info->strict_mode_flag() == shared_info->strict_mode_flag());
738 } 749 scope->SetStrictModeFlag(shared_info->strict_mode_flag());
739
740 FunctionLiteral::Type type = shared_info->is_expression() 750 FunctionLiteral::Type type = shared_info->is_expression()
741 ? (shared_info->is_anonymous() 751 ? (shared_info->is_anonymous()
742 ? FunctionLiteral::ANONYMOUS_EXPRESSION 752 ? FunctionLiteral::ANONYMOUS_EXPRESSION
743 : FunctionLiteral::NAMED_EXPRESSION) 753 : FunctionLiteral::NAMED_EXPRESSION)
744 : FunctionLiteral::DECLARATION; 754 : FunctionLiteral::DECLARATION;
745 bool ok = true; 755 bool ok = true;
746 result = ParseFunctionLiteral(name, 756 result = ParseFunctionLiteral(name,
747 false, // Strict mode name already checked. 757 false, // Strict mode name already checked.
748 RelocInfo::kNoPosition, 758 RelocInfo::kNoPosition,
749 type, 759 type,
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after
1121 Statement* Parser::ParseSourceElement(ZoneStringList* labels, 1131 Statement* Parser::ParseSourceElement(ZoneStringList* labels,
1122 bool* ok) { 1132 bool* ok) {
1123 // (Ecma 262 5th Edition, clause 14): 1133 // (Ecma 262 5th Edition, clause 14):
1124 // SourceElement: 1134 // SourceElement:
1125 // Statement 1135 // Statement
1126 // FunctionDeclaration 1136 // FunctionDeclaration
1127 // 1137 //
1128 // In harmony mode we allow additionally the following productions 1138 // In harmony mode we allow additionally the following productions
1129 // SourceElement: 1139 // SourceElement:
1130 // LetDeclaration 1140 // LetDeclaration
1141 // ConstDeclaration
1131 1142
1132 if (peek() == Token::FUNCTION) { 1143 if (peek() == Token::FUNCTION) {
1133 return ParseFunctionDeclaration(ok); 1144 return ParseFunctionDeclaration(ok);
1134 } else if (peek() == Token::LET) { 1145 } else if (peek() == Token::LET || peek() == Token::CONST) {
1135 return ParseVariableStatement(kSourceElement, ok); 1146 return ParseVariableStatement(kSourceElement, ok);
1136 } else {
1137 return ParseStatement(labels, ok);
1138 } 1147 }
1148 return ParseStatement(labels, ok);
1139 } 1149 }
1140 1150
1141 1151
1142 void* Parser::ParseSourceElements(ZoneList<Statement*>* processor, 1152 void* Parser::ParseSourceElements(ZoneList<Statement*>* processor,
1143 int end_token, 1153 int end_token,
1144 bool* ok) { 1154 bool* ok) {
1145 // SourceElements :: 1155 // SourceElements ::
1146 // (SourceElement)* <end_token> 1156 // (SourceElement)* <end_token>
1147 1157
1148 // Allocate a target stack to use for this set of source 1158 // Allocate a target stack to use for this set of source
(...skipping 27 matching lines...) Expand all
1176 if ((e_stat = stat->AsExpressionStatement()) != NULL && 1186 if ((e_stat = stat->AsExpressionStatement()) != NULL &&
1177 (literal = e_stat->expression()->AsLiteral()) != NULL && 1187 (literal = e_stat->expression()->AsLiteral()) != NULL &&
1178 literal->handle()->IsString()) { 1188 literal->handle()->IsString()) {
1179 Handle<String> directive = Handle<String>::cast(literal->handle()); 1189 Handle<String> directive = Handle<String>::cast(literal->handle());
1180 1190
1181 // Check "use strict" directive (ES5 14.1). 1191 // Check "use strict" directive (ES5 14.1).
1182 if (!top_scope_->is_strict_mode() && 1192 if (!top_scope_->is_strict_mode() &&
1183 directive->Equals(isolate()->heap()->use_strict()) && 1193 directive->Equals(isolate()->heap()->use_strict()) &&
1184 token_loc.end_pos - token_loc.beg_pos == 1194 token_loc.end_pos - token_loc.beg_pos ==
1185 isolate()->heap()->use_strict()->length() + 2) { 1195 isolate()->heap()->use_strict()->length() + 2) {
1186 top_scope_->EnableStrictMode(); 1196 top_scope_->SetStrictModeFlag(kStrictMode);
1187 // "use strict" is the only directive for now. 1197 // "use strict" is the only directive for now.
1188 directive_prologue = false; 1198 directive_prologue = false;
1189 } 1199 }
1190 } else { 1200 } else {
1191 // End of the directive prologue. 1201 // End of the directive prologue.
1192 directive_prologue = false; 1202 directive_prologue = false;
1193 } 1203 }
1194 } 1204 }
1195 1205
1196 block_finder.Update(stat); 1206 block_finder.Update(stat);
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
1314 } 1324 }
1315 1325
1316 case Token::FUNCTION: { 1326 case Token::FUNCTION: {
1317 // FunctionDeclaration is only allowed in the context of SourceElements 1327 // FunctionDeclaration is only allowed in the context of SourceElements
1318 // (Ecma 262 5th Edition, clause 14): 1328 // (Ecma 262 5th Edition, clause 14):
1319 // SourceElement: 1329 // SourceElement:
1320 // Statement 1330 // Statement
1321 // FunctionDeclaration 1331 // FunctionDeclaration
1322 // Common language extension is to allow function declaration in place 1332 // Common language extension is to allow function declaration in place
1323 // of any statement. This language extension is disabled in strict mode. 1333 // of any statement. This language extension is disabled in strict mode.
1324 if (top_scope_->is_strict_mode()) { 1334 if (top_scope_->is_strict_mode() || harmony_scoping_) {
1325 ReportMessageAt(scanner().peek_location(), "strict_function", 1335 ReportMessageAt(scanner().peek_location(), "strict_function",
1326 Vector<const char*>::empty()); 1336 Vector<const char*>::empty());
1327 *ok = false; 1337 *ok = false;
1328 return NULL; 1338 return NULL;
1329 } 1339 }
1330 return ParseFunctionDeclaration(ok); 1340 return ParseFunctionDeclaration(ok);
1331 } 1341 }
1332 1342
1333 case Token::DEBUGGER: 1343 case Token::DEBUGGER:
1334 stmt = ParseDebuggerStatement(ok); 1344 stmt = ParseDebuggerStatement(ok);
(...skipping 11 matching lines...) Expand all
1346 1356
1347 VariableProxy* Parser::Declare(Handle<String> name, 1357 VariableProxy* Parser::Declare(Handle<String> name,
1348 VariableMode mode, 1358 VariableMode mode,
1349 FunctionLiteral* fun, 1359 FunctionLiteral* fun,
1350 bool resolve, 1360 bool resolve,
1351 bool* ok) { 1361 bool* ok) {
1352 Variable* var = NULL; 1362 Variable* var = NULL;
1353 // If we are inside a function, a declaration of a var/const variable is a 1363 // If we are inside a function, a declaration of a var/const variable is a
1354 // truly local variable, and the scope of the variable is always the function 1364 // truly local variable, and the scope of the variable is always the function
1355 // scope. 1365 // scope.
1366 // Let/const variables in harmony mode are always added to the immediately
1367 // enclosing scope.
1368 Scope* declaration_scope = (mode == LET || mode == CONST_HARMONY)
1369 ? top_scope_ : top_scope_->DeclarationScope();
1356 1370
1357 // If a function scope exists, then we can statically declare this 1371 // If a function scope exists, then we can statically declare this
1358 // variable and also set its mode. In any case, a Declaration node 1372 // variable and also set its mode. In any case, a Declaration node
1359 // will be added to the scope so that the declaration can be added 1373 // will be added to the scope so that the declaration can be added
1360 // to the corresponding activation frame at runtime if necessary. 1374 // to the corresponding activation frame at runtime if necessary.
1361 // For instance declarations inside an eval scope need to be added 1375 // For instance declarations inside an eval scope need to be added
1362 // to the calling function context. 1376 // to the calling function context.
1363 // Similarly, strict mode eval scope does not leak variable declarations to 1377 // Similarly, strict mode eval scope does not leak variable declarations to
1364 // the caller's scope so we declare all locals, too. 1378 // the caller's scope so we declare all locals, too.
1365 1379 // Also for block scoped let/const bindings the variable can be
1366 Scope* declaration_scope = mode == LET ? top_scope_ 1380 // statically declared.
1367 : top_scope_->DeclarationScope();
1368 if (declaration_scope->is_function_scope() || 1381 if (declaration_scope->is_function_scope() ||
1369 declaration_scope->is_strict_mode_eval_scope() || 1382 declaration_scope->is_strict_mode_eval_scope() ||
1370 declaration_scope->is_block_scope()) { 1383 declaration_scope->is_block_scope()) {
1371 // Declare the variable in the function scope. 1384 // Declare the variable in the function scope.
1372 var = declaration_scope->LocalLookup(name); 1385 var = declaration_scope->LocalLookup(name);
1373 if (var == NULL) { 1386 if (var == NULL) {
1374 // Declare the name. 1387 // Declare the name.
1375 var = declaration_scope->DeclareLocal(name, mode); 1388 var = declaration_scope->DeclareLocal(name, mode);
1376 } else { 1389 } else {
1377 // The name was declared in this scope before; check for conflicting 1390 // The name was declared in this scope before; check for conflicting
1378 // re-declarations. We have a conflict if either of the declarations is 1391 // re-declarations. We have a conflict if either of the declarations is
1379 // not a var. There is similar code in runtime.cc in the Declare 1392 // not a var. There is similar code in runtime.cc in the Declare
1380 // functions. The function CheckNonConflictingScope checks for conflicting 1393 // functions. The function CheckNonConflictingScope checks for conflicting
1381 // var and let bindings from different scopes whereas this is a check for 1394 // var and let bindings from different scopes whereas this is a check for
1382 // conflicting declarations within the same scope. This check also covers 1395 // conflicting declarations within the same scope. This check also covers
1383 // 1396 //
1384 // function () { let x; { var x; } } 1397 // function () { let x; { var x; } }
1385 // 1398 //
1386 // because the var declaration is hoisted to the function scope where 'x' 1399 // because the var declaration is hoisted to the function scope where 'x'
1387 // is already bound. 1400 // is already bound.
1388 if ((mode != VAR) || (var->mode() != VAR)) { 1401 if ((mode != VAR) || (var->mode() != VAR)) {
1389 // We only have vars, consts and lets in declarations. 1402 // We only have vars, consts and lets in declarations.
1390 ASSERT(var->mode() == VAR || 1403 ASSERT(var->mode() == VAR ||
1391 var->mode() == CONST || 1404 var->mode() == CONST ||
1405 var->mode() == CONST_HARMONY ||
1392 var->mode() == LET); 1406 var->mode() == LET);
1393 if (harmony_scoping_) { 1407 if (harmony_scoping_) {
1394 // In harmony mode we treat re-declarations as early errors. See 1408 // In harmony mode we treat re-declarations as early errors. See
1395 // ES5 16 for a definition of early errors. 1409 // ES5 16 for a definition of early errors.
1396 SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS); 1410 SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS);
1397 const char* elms[2] = { "Variable", *c_string }; 1411 const char* elms[2] = { "Variable", *c_string };
1398 Vector<const char*> args(elms, 2); 1412 Vector<const char*> args(elms, 2);
1399 ReportMessage("redeclaration", args); 1413 ReportMessage("redeclaration", args);
1400 *ok = false; 1414 *ok = false;
1401 return NULL; 1415 return NULL;
1402 } 1416 }
1403 const char* type = (var->mode() == VAR) ? "var" : 1417 const char* type = (var->mode() == VAR)
1404 (var->mode() == CONST) ? "const" : "let"; 1418 ? "var" : var->is_const_mode() ? "const" : "let";
1405 Handle<String> type_string = 1419 Handle<String> type_string =
1406 isolate()->factory()->NewStringFromUtf8(CStrVector(type), TENURED); 1420 isolate()->factory()->NewStringFromUtf8(CStrVector(type), TENURED);
1407 Expression* expression = 1421 Expression* expression =
1408 NewThrowTypeError(isolate()->factory()->redeclaration_symbol(), 1422 NewThrowTypeError(isolate()->factory()->redeclaration_symbol(),
1409 type_string, name); 1423 type_string, name);
1410 declaration_scope->SetIllegalRedeclaration(expression); 1424 declaration_scope->SetIllegalRedeclaration(expression);
1411 } 1425 }
1412 } 1426 }
1413 } 1427 }
1414 1428
1415 // We add a declaration node for every declaration. The compiler 1429 // We add a declaration node for every declaration. The compiler
1416 // will only generate code if necessary. In particular, declarations 1430 // will only generate code if necessary. In particular, declarations
1417 // for inner local variables that do not represent functions won't 1431 // for inner local variables that do not represent functions won't
1418 // result in any generated code. 1432 // result in any generated code.
1419 // 1433 //
1420 // Note that we always add an unresolved proxy even if it's not 1434 // Note that we always add an unresolved proxy even if it's not
1421 // used, simply because we don't know in this method (w/o extra 1435 // used, simply because we don't know in this method (w/o extra
1422 // parameters) if the proxy is needed or not. The proxy will be 1436 // parameters) if the proxy is needed or not. The proxy will be
1423 // bound during variable resolution time unless it was pre-bound 1437 // bound during variable resolution time unless it was pre-bound
1424 // below. 1438 // below.
1425 // 1439 //
1426 // WARNING: This will lead to multiple declaration nodes for the 1440 // WARNING: This will lead to multiple declaration nodes for the
1427 // same variable if it is declared several times. This is not a 1441 // same variable if it is declared several times. This is not a
1428 // semantic issue as long as we keep the source order, but it may be 1442 // semantic issue as long as we keep the source order, but it may be
1429 // a performance issue since it may lead to repeated 1443 // a performance issue since it may lead to repeated
1430 // Runtime::DeclareContextSlot() calls. 1444 // Runtime::DeclareContextSlot() calls.
1431 VariableProxy* proxy = declaration_scope->NewUnresolved( 1445 VariableProxy* proxy = declaration_scope->NewUnresolved(
1432 name, false, scanner().location().beg_pos); 1446 name, scanner().location().beg_pos);
1433 declaration_scope->AddDeclaration( 1447 declaration_scope->AddDeclaration(
1434 new(zone()) Declaration(proxy, mode, fun, top_scope_)); 1448 new(zone()) Declaration(proxy, mode, fun, top_scope_));
1435 1449
1436 // For global const variables we bind the proxy to a variable. 1450 // For global const variables we bind the proxy to a variable.
1437 if (mode == CONST && declaration_scope->is_global_scope()) { 1451 if ((mode == CONST || mode == CONST_HARMONY) &&
1452 declaration_scope->is_global_scope()) {
1438 ASSERT(resolve); // should be set by all callers 1453 ASSERT(resolve); // should be set by all callers
1439 Variable::Kind kind = Variable::NORMAL; 1454 Variable::Kind kind = Variable::NORMAL;
1440 var = new(zone()) Variable(declaration_scope, name, CONST, true, kind); 1455 var = new(zone()) Variable(declaration_scope, name, CONST, true, kind);
1441 } 1456 }
1442 1457
1443 // If requested and we have a local variable, bind the proxy to the variable 1458 // If requested and we have a local variable, bind the proxy to the variable
1444 // at parse-time. This is used for functions (and consts) declared inside 1459 // at parse-time. This is used for functions (and consts) declared inside
1445 // statements: the corresponding function (or const) variable must be in the 1460 // statements: the corresponding function (or const) variable must be in the
1446 // function scope and not a statement-local scope, e.g. as provided with a 1461 // function scope and not a statement-local scope, e.g. as provided with a
1447 // 'with' statement: 1462 // 'with' statement:
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
1575 1590
1576 1591
1577 Block* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) { 1592 Block* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) {
1578 // The harmony mode uses source elements instead of statements. 1593 // The harmony mode uses source elements instead of statements.
1579 // 1594 //
1580 // Block :: 1595 // Block ::
1581 // '{' SourceElement* '}' 1596 // '{' SourceElement* '}'
1582 1597
1583 // Construct block expecting 16 statements. 1598 // Construct block expecting 16 statements.
1584 Block* body = new(zone()) Block(isolate(), labels, 16, false); 1599 Block* body = new(zone()) Block(isolate(), labels, 16, false);
1585 Scope* saved_scope = top_scope_; 1600 Scope* block_scope = NewScope(top_scope_, BLOCK_SCOPE);
1586 Scope* block_scope = NewScope(top_scope_,
1587 Scope::BLOCK_SCOPE,
1588 inside_with());
1589 if (top_scope_->is_strict_mode()) {
1590 block_scope->EnableStrictMode();
1591 }
1592 top_scope_ = block_scope;
1593 1601
1594 // Parse the statements and collect escaping labels. 1602 // Parse the statements and collect escaping labels.
1595 TargetCollector collector;
1596 Target target(&this->target_stack_, &collector);
1597 Expect(Token::LBRACE, CHECK_OK); 1603 Expect(Token::LBRACE, CHECK_OK);
1598 { 1604 block_scope->set_start_position(scanner().location().beg_pos);
1605 { SaveScope save_scope(this, block_scope);
1606 TargetCollector collector;
1607 Target target(&this->target_stack_, &collector);
1599 Target target_body(&this->target_stack_, body); 1608 Target target_body(&this->target_stack_, body);
1600 InitializationBlockFinder block_finder(top_scope_, target_stack_); 1609 InitializationBlockFinder block_finder(top_scope_, target_stack_);
1601 1610
1602 while (peek() != Token::RBRACE) { 1611 while (peek() != Token::RBRACE) {
1603 Statement* stat = ParseSourceElement(NULL, CHECK_OK); 1612 Statement* stat = ParseSourceElement(NULL, CHECK_OK);
1604 if (stat && !stat->IsEmpty()) { 1613 if (stat && !stat->IsEmpty()) {
1605 body->AddStatement(stat); 1614 body->AddStatement(stat);
1606 block_finder.Update(stat); 1615 block_finder.Update(stat);
1607 } 1616 }
1608 } 1617 }
1609 } 1618 }
1610 Expect(Token::RBRACE, CHECK_OK); 1619 Expect(Token::RBRACE, CHECK_OK);
1611 top_scope_ = saved_scope; 1620 block_scope->set_end_position(scanner().location().end_pos);
1612
1613 block_scope = block_scope->FinalizeBlockScope(); 1621 block_scope = block_scope->FinalizeBlockScope();
1614 body->set_block_scope(block_scope); 1622 body->set_block_scope(block_scope);
1615 return body; 1623 return body;
1616 } 1624 }
1617 1625
1618 1626
1619 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context, 1627 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context,
1620 bool* ok) { 1628 bool* ok) {
1621 // VariableStatement :: 1629 // VariableStatement ::
1622 // VariableDeclarations ';' 1630 // VariableDeclarations ';'
1623 1631
1624 Handle<String> ignore; 1632 Handle<String> ignore;
1625 Block* result = ParseVariableDeclarations(var_context, 1633 Block* result = ParseVariableDeclarations(var_context,
1634 NULL,
1626 &ignore, 1635 &ignore,
1627 CHECK_OK); 1636 CHECK_OK);
1628 ExpectSemicolon(CHECK_OK); 1637 ExpectSemicolon(CHECK_OK);
1629 return result; 1638 return result;
1630 } 1639 }
1631 1640
1632 1641
1633 bool Parser::IsEvalOrArguments(Handle<String> string) { 1642 bool Parser::IsEvalOrArguments(Handle<String> string) {
1634 return string.is_identical_to(isolate()->factory()->eval_symbol()) || 1643 return string.is_identical_to(isolate()->factory()->eval_symbol()) ||
1635 string.is_identical_to(isolate()->factory()->arguments_symbol()); 1644 string.is_identical_to(isolate()->factory()->arguments_symbol());
1636 } 1645 }
1637 1646
1638 1647
1639 // If the variable declaration declares exactly one non-const 1648 // If the variable declaration declares exactly one non-const
1640 // variable, then *var is set to that variable. In all other cases, 1649 // variable, then *var is set to that variable. In all other cases,
1641 // *var is untouched; in particular, it is the caller's responsibility 1650 // *var is untouched; in particular, it is the caller's responsibility
1642 // to initialize it properly. This mechanism is used for the parsing 1651 // to initialize it properly. This mechanism is used for the parsing
1643 // of 'for-in' loops. 1652 // of 'for-in' loops.
1644 Block* Parser::ParseVariableDeclarations(VariableDeclarationContext var_context, 1653 Block* Parser::ParseVariableDeclarations(
1645 Handle<String>* out, 1654 VariableDeclarationContext var_context,
1646 bool* ok) { 1655 VariableDeclarationProperties* decl_props,
1656 Handle<String>* out,
1657 bool* ok) {
1647 // VariableDeclarations :: 1658 // VariableDeclarations ::
1648 // ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[','] 1659 // ('var' | 'const' | 'let') (Identifier ('=' AssignmentExpression)?)+[',']
1649 1660 //
1661 // The ES6 Draft Rev3 specifies the following grammar for const declarations
1662 //
1663 // ConstDeclaration ::
1664 // const ConstBinding (',' ConstBinding)* ';'
1665 // ConstBinding ::
1666 // Identifier '=' AssignmentExpression
1667 //
1668 // TODO(ES6):
1669 // ConstBinding ::
1670 // BindingPattern '=' AssignmentExpression
1650 VariableMode mode = VAR; 1671 VariableMode mode = VAR;
1651 // True if the binding needs initialization. 'let' and 'const' declared 1672 // True if the binding needs initialization. 'let' and 'const' declared
1652 // bindings are created uninitialized by their declaration nodes and 1673 // bindings are created uninitialized by their declaration nodes and
1653 // need initialization. 'var' declared bindings are always initialized 1674 // need initialization. 'var' declared bindings are always initialized
1654 // immediately by their declaration nodes. 1675 // immediately by their declaration nodes.
1655 bool needs_init = false; 1676 bool needs_init = false;
1656 bool is_const = false; 1677 bool is_const = false;
1657 Token::Value init_op = Token::INIT_VAR; 1678 Token::Value init_op = Token::INIT_VAR;
1658 if (peek() == Token::VAR) { 1679 if (peek() == Token::VAR) {
1659 Consume(Token::VAR); 1680 Consume(Token::VAR);
1660 } else if (peek() == Token::CONST) { 1681 } else if (peek() == Token::CONST) {
1661 Consume(Token::CONST); 1682 Consume(Token::CONST);
1662 if (top_scope_->is_strict_mode()) { 1683 if (harmony_scoping_) {
1684 if (var_context != kSourceElement &&
1685 var_context != kForStatement) {
1686 // In harmony mode 'const' declarations are only allowed in source
1687 // element positions.
1688 ReportMessage("unprotected_const", Vector<const char*>::empty());
1689 *ok = false;
1690 return NULL;
1691 }
1692 mode = CONST_HARMONY;
1693 init_op = Token::INIT_CONST_HARMONY;
1694 } else if (top_scope_->is_strict_mode()) {
1663 ReportMessage("strict_const", Vector<const char*>::empty()); 1695 ReportMessage("strict_const", Vector<const char*>::empty());
1664 *ok = false; 1696 *ok = false;
1665 return NULL; 1697 return NULL;
1698 } else {
1699 mode = CONST;
1700 init_op = Token::INIT_CONST;
1666 } 1701 }
1667 mode = CONST;
1668 is_const = true; 1702 is_const = true;
1669 needs_init = true; 1703 needs_init = true;
1670 init_op = Token::INIT_CONST;
1671 } else if (peek() == Token::LET) { 1704 } else if (peek() == Token::LET) {
1672 Consume(Token::LET); 1705 Consume(Token::LET);
1673 if (var_context != kSourceElement && 1706 if (var_context != kSourceElement &&
1674 var_context != kForStatement) { 1707 var_context != kForStatement) {
1708 // Let declarations are only allowed in source element positions.
1675 ASSERT(var_context == kStatement); 1709 ASSERT(var_context == kStatement);
1676 ReportMessage("unprotected_let", Vector<const char*>::empty()); 1710 ReportMessage("unprotected_let", Vector<const char*>::empty());
1677 *ok = false; 1711 *ok = false;
1678 return NULL; 1712 return NULL;
1679 } 1713 }
1680 mode = LET; 1714 mode = LET;
1681 needs_init = true; 1715 needs_init = true;
1682 init_op = Token::INIT_LET; 1716 init_op = Token::INIT_LET;
1683 } else { 1717 } else {
1684 UNREACHABLE(); // by current callers 1718 UNREACHABLE(); // by current callers
1685 } 1719 }
1686 1720
1687 Scope* declaration_scope = (mode == LET) 1721 Scope* declaration_scope = (mode == LET || mode == CONST_HARMONY)
1688 ? top_scope_ : top_scope_->DeclarationScope(); 1722 ? top_scope_ : top_scope_->DeclarationScope();
1689 // The scope of a var/const declared variable anywhere inside a function 1723 // The scope of a var/const declared variable anywhere inside a function
1690 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can 1724 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can
1691 // transform a source-level var/const declaration into a (Function) 1725 // transform a source-level var/const declaration into a (Function)
1692 // Scope declaration, and rewrite the source-level initialization into an 1726 // Scope declaration, and rewrite the source-level initialization into an
1693 // assignment statement. We use a block to collect multiple assignments. 1727 // assignment statement. We use a block to collect multiple assignments.
1694 // 1728 //
1695 // We mark the block as initializer block because we don't want the 1729 // We mark the block as initializer block because we don't want the
1696 // rewriter to add a '.result' assignment to such a block (to get compliant 1730 // rewriter to add a '.result' assignment to such a block (to get compliant
1697 // behavior for code such as print(eval('var x = 7')), and for cosmetic 1731 // behavior for code such as print(eval('var x = 7')), and for cosmetic
(...skipping 24 matching lines...) Expand all
1722 // assignment for variables and constants because the value must be assigned 1756 // assignment for variables and constants because the value must be assigned
1723 // when the variable is encountered in the source. But the variable/constant 1757 // when the variable is encountered in the source. But the variable/constant
1724 // is declared (and set to 'undefined') upon entering the function within 1758 // is declared (and set to 'undefined') upon entering the function within
1725 // which the variable or constant is declared. Only function variables have 1759 // which the variable or constant is declared. Only function variables have
1726 // an initial value in the declaration (because they are initialized upon 1760 // an initial value in the declaration (because they are initialized upon
1727 // entering the function). 1761 // entering the function).
1728 // 1762 //
1729 // If we have a const declaration, in an inner scope, the proxy is always 1763 // If we have a const declaration, in an inner scope, the proxy is always
1730 // bound to the declared variable (independent of possibly surrounding with 1764 // bound to the declared variable (independent of possibly surrounding with
1731 // statements). 1765 // statements).
1732 Declare(name, mode, NULL, is_const /* always bound for CONST! */, 1766 // For let/const declarations in harmony mode, we can also immediately
1733 CHECK_OK); 1767 // pre-resolve the proxy because it resides in the same scope as the
1768 // declaration.
1769 Declare(name, mode, NULL, mode != VAR, CHECK_OK);
1734 nvars++; 1770 nvars++;
1735 if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) { 1771 if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) {
1736 ReportMessageAt(scanner().location(), "too_many_variables", 1772 ReportMessageAt(scanner().location(), "too_many_variables",
1737 Vector<const char*>::empty()); 1773 Vector<const char*>::empty());
1738 *ok = false; 1774 *ok = false;
1739 return NULL; 1775 return NULL;
1740 } 1776 }
1741 1777
1742 // Parse initialization expression if present and/or needed. A 1778 // Parse initialization expression if present and/or needed. A
1743 // declaration of the form: 1779 // declaration of the form:
(...skipping 18 matching lines...) Expand all
1762 // 1798 //
1763 // const c; c = x; 1799 // const c; c = x;
1764 // 1800 //
1765 // The "variable" c initialized to x is the same as the declared 1801 // The "variable" c initialized to x is the same as the declared
1766 // one - there is no re-lookup (see the last parameter of the 1802 // one - there is no re-lookup (see the last parameter of the
1767 // Declare() call above). 1803 // Declare() call above).
1768 1804
1769 Scope* initialization_scope = is_const ? declaration_scope : top_scope_; 1805 Scope* initialization_scope = is_const ? declaration_scope : top_scope_;
1770 Expression* value = NULL; 1806 Expression* value = NULL;
1771 int position = -1; 1807 int position = -1;
1772 if (peek() == Token::ASSIGN) { 1808 // Harmony consts have non-optional initializers.
1809 if (peek() == Token::ASSIGN || mode == CONST_HARMONY) {
1773 Expect(Token::ASSIGN, CHECK_OK); 1810 Expect(Token::ASSIGN, CHECK_OK);
1774 position = scanner().location().beg_pos; 1811 position = scanner().location().beg_pos;
1775 value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); 1812 value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK);
1776 // Don't infer if it is "a = function(){...}();"-like expression. 1813 // Don't infer if it is "a = function(){...}();"-like expression.
1777 if (fni_ != NULL && 1814 if (fni_ != NULL &&
1778 value->AsCall() == NULL && 1815 value->AsCall() == NULL &&
1779 value->AsCallNew() == NULL) { 1816 value->AsCallNew() == NULL) {
1780 fni_->Infer(); 1817 fni_->Infer();
1781 } else { 1818 } else {
1782 fni_->RemoveLastFunction(); 1819 fni_->RemoveLastFunction();
1783 } 1820 }
1821 if (decl_props != NULL) *decl_props = kHasInitializers;
1784 } 1822 }
1785 1823
1786 // Make sure that 'const x' and 'let x' initialize 'x' to undefined. 1824 // Make sure that 'const x' and 'let x' initialize 'x' to undefined.
1787 if (value == NULL && needs_init) { 1825 if (value == NULL && needs_init) {
1788 value = GetLiteralUndefined(); 1826 value = GetLiteralUndefined();
1789 } 1827 }
1790 1828
1791 // Global variable declarations must be compiled in a specific 1829 // Global variable declarations must be compiled in a specific
1792 // way. When the script containing the global variable declaration 1830 // way. When the script containing the global variable declaration
1793 // is entered, the global variable must be declared, so that if it 1831 // is entered, the global variable must be declared, so that if it
1794 // doesn't exist (not even in a prototype of the global object) it 1832 // doesn't exist (not even in a prototype of the global object) it
1795 // gets created with an initial undefined value. This is handled 1833 // gets created with an initial undefined value. This is handled
1796 // by the declarations part of the function representing the 1834 // by the declarations part of the function representing the
1797 // top-level global code; see Runtime::DeclareGlobalVariable. If 1835 // top-level global code; see Runtime::DeclareGlobalVariable. If
1798 // it already exists (in the object or in a prototype), it is 1836 // it already exists (in the object or in a prototype), it is
1799 // *not* touched until the variable declaration statement is 1837 // *not* touched until the variable declaration statement is
1800 // executed. 1838 // executed.
1801 // 1839 //
1802 // Executing the variable declaration statement will always 1840 // Executing the variable declaration statement will always
1803 // guarantee to give the global object a "local" variable; a 1841 // guarantee to give the global object a "local" variable; a
1804 // variable defined in the global object and not in any 1842 // variable defined in the global object and not in any
1805 // prototype. This way, global variable declarations can shadow 1843 // prototype. This way, global variable declarations can shadow
1806 // properties in the prototype chain, but only after the variable 1844 // properties in the prototype chain, but only after the variable
1807 // declaration statement has been executed. This is important in 1845 // declaration statement has been executed. This is important in
1808 // browsers where the global object (window) has lots of 1846 // browsers where the global object (window) has lots of
1809 // properties defined in prototype objects. 1847 // properties defined in prototype objects.
1810
1811 if (initialization_scope->is_global_scope()) { 1848 if (initialization_scope->is_global_scope()) {
1812 // Compute the arguments for the runtime call. 1849 // Compute the arguments for the runtime call.
1813 ZoneList<Expression*>* arguments = new(zone()) ZoneList<Expression*>(3); 1850 ZoneList<Expression*>* arguments = new(zone()) ZoneList<Expression*>(3);
1814 // We have at least 1 parameter. 1851 // We have at least 1 parameter.
1815 arguments->Add(NewLiteral(name)); 1852 arguments->Add(NewLiteral(name));
1816 CallRuntime* initialize; 1853 CallRuntime* initialize;
1817 1854
1818 if (is_const) { 1855 if (is_const) {
1819 arguments->Add(value); 1856 arguments->Add(value);
1820 value = NULL; // zap the value to avoid the unnecessary assignment 1857 value = NULL; // zap the value to avoid the unnecessary assignment
1821 1858
1822 // Construct the call to Runtime_InitializeConstGlobal 1859 // Construct the call to Runtime_InitializeConstGlobal
1823 // and add it to the initialization statement block. 1860 // and add it to the initialization statement block.
1824 // Note that the function does different things depending on 1861 // Note that the function does different things depending on
1825 // the number of arguments (1 or 2). 1862 // the number of arguments (1 or 2).
1826 initialize = 1863 initialize =
1827 new(zone()) CallRuntime( 1864 new(zone()) CallRuntime(
1828 isolate(), 1865 isolate(),
1829 isolate()->factory()->InitializeConstGlobal_symbol(), 1866 isolate()->factory()->InitializeConstGlobal_symbol(),
1830 Runtime::FunctionForId(Runtime::kInitializeConstGlobal), 1867 Runtime::FunctionForId(Runtime::kInitializeConstGlobal),
1831 arguments); 1868 arguments);
1832 } else { 1869 } else {
1833 // Add strict mode. 1870 // Add strict mode.
1834 // We may want to pass singleton to avoid Literal allocations. 1871 // We may want to pass singleton to avoid Literal allocations.
1835 StrictModeFlag flag = initialization_scope->is_strict_mode() 1872 StrictModeFlag flag = initialization_scope->strict_mode_flag();
1836 ? kStrictMode
1837 : kNonStrictMode;
1838 arguments->Add(NewNumberLiteral(flag)); 1873 arguments->Add(NewNumberLiteral(flag));
1839 1874
1840 // Be careful not to assign a value to the global variable if 1875 // Be careful not to assign a value to the global variable if
1841 // we're in a with. The initialization value should not 1876 // we're in a with. The initialization value should not
1842 // necessarily be stored in the global object in that case, 1877 // necessarily be stored in the global object in that case,
1843 // which is why we need to generate a separate assignment node. 1878 // which is why we need to generate a separate assignment node.
1844 if (value != NULL && !inside_with()) { 1879 if (value != NULL && !inside_with()) {
1845 arguments->Add(value); 1880 arguments->Add(value);
1846 value = NULL; // zap the value to avoid the unnecessary assignment 1881 value = NULL; // zap the value to avoid the unnecessary assignment
1847 } 1882 }
(...skipping 16 matching lines...) Expand all
1864 // Add an assignment node to the initialization statement block if we still 1899 // Add an assignment node to the initialization statement block if we still
1865 // have a pending initialization value. We must distinguish between 1900 // have a pending initialization value. We must distinguish between
1866 // different kinds of declarations: 'var' initializations are simply 1901 // different kinds of declarations: 'var' initializations are simply
1867 // assignments (with all the consequences if they are inside a 'with' 1902 // assignments (with all the consequences if they are inside a 'with'
1868 // statement - they may change a 'with' object property). Constant 1903 // statement - they may change a 'with' object property). Constant
1869 // initializations always assign to the declared constant which is 1904 // initializations always assign to the declared constant which is
1870 // always at the function scope level. This is only relevant for 1905 // always at the function scope level. This is only relevant for
1871 // dynamically looked-up variables and constants (the start context 1906 // dynamically looked-up variables and constants (the start context
1872 // for constant lookups is always the function context, while it is 1907 // for constant lookups is always the function context, while it is
1873 // the top context for var declared variables). Sigh... 1908 // the top context for var declared variables). Sigh...
1874 // For 'let' declared variables the initialization is in the same scope 1909 // For 'let' and 'const' declared variables in harmony mode the
1875 // as the declaration. Thus dynamic lookups are unnecessary even if the 1910 // initialization is in the same scope as the declaration. Thus dynamic
1876 // block scope is inside a with. 1911 // lookups are unnecessary even if the block scope is inside a with.
1877 if (value != NULL) { 1912 if (value != NULL) {
1878 bool in_with = (mode == VAR) ? inside_with() : false; 1913 VariableProxy* proxy = initialization_scope->NewUnresolved(name);
1879 VariableProxy* proxy =
1880 initialization_scope->NewUnresolved(name, in_with);
1881 Assignment* assignment = 1914 Assignment* assignment =
1882 new(zone()) Assignment(isolate(), init_op, proxy, value, position); 1915 new(zone()) Assignment(isolate(), init_op, proxy, value, position);
1883 if (block) { 1916 block->AddStatement(new(zone()) ExpressionStatement(assignment));
1884 block->AddStatement(new(zone()) ExpressionStatement(assignment));
1885 }
1886 } 1917 }
1887 1918
1888 if (fni_ != NULL) fni_->Leave(); 1919 if (fni_ != NULL) fni_->Leave();
1889 } while (peek() == Token::COMMA); 1920 } while (peek() == Token::COMMA);
1890 1921
1891 // If there was a single non-const declaration, return it in the output 1922 // If there was a single non-const declaration, return it in the output
1892 // parameter for possible use by for/in. 1923 // parameter for possible use by for/in.
1893 if (nvars == 1 && !is_const) { 1924 if (nvars == 1 && !is_const) {
1894 *out = name; 1925 *out = name;
1895 } 1926 }
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
2098 if (top_scope_->is_strict_mode()) { 2129 if (top_scope_->is_strict_mode()) {
2099 ReportMessage("strict_mode_with", Vector<const char*>::empty()); 2130 ReportMessage("strict_mode_with", Vector<const char*>::empty());
2100 *ok = false; 2131 *ok = false;
2101 return NULL; 2132 return NULL;
2102 } 2133 }
2103 2134
2104 Expect(Token::LPAREN, CHECK_OK); 2135 Expect(Token::LPAREN, CHECK_OK);
2105 Expression* expr = ParseExpression(true, CHECK_OK); 2136 Expression* expr = ParseExpression(true, CHECK_OK);
2106 Expect(Token::RPAREN, CHECK_OK); 2137 Expect(Token::RPAREN, CHECK_OK);
2107 2138
2108 ++with_nesting_level_;
2109 top_scope_->DeclarationScope()->RecordWithStatement(); 2139 top_scope_->DeclarationScope()->RecordWithStatement();
2110 Statement* stmt = ParseStatement(labels, CHECK_OK); 2140 Scope* with_scope = NewScope(top_scope_, WITH_SCOPE);
2111 --with_nesting_level_; 2141 Statement* stmt;
2142 { SaveScope save_scope(this, with_scope);
2143 with_scope->set_start_position(scanner().peek_location().beg_pos);
2144 stmt = ParseStatement(labels, CHECK_OK);
2145 with_scope->set_end_position(scanner().location().end_pos);
2146 }
2112 return new(zone()) WithStatement(expr, stmt); 2147 return new(zone()) WithStatement(expr, stmt);
2113 } 2148 }
2114 2149
2115 2150
2116 CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) { 2151 CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) {
2117 // CaseClause :: 2152 // CaseClause ::
2118 // 'case' Expression ':' Statement* 2153 // 'case' Expression ':' Statement*
2119 // 'default' ':' Statement* 2154 // 'default' ':' Statement*
2120 2155
2121 Expression* label = NULL; // NULL expression indicates default case 2156 Expression* label = NULL; // NULL expression indicates default case
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
2226 // always collect the targets. 2261 // always collect the targets.
2227 TargetCollector catch_collector; 2262 TargetCollector catch_collector;
2228 Scope* catch_scope = NULL; 2263 Scope* catch_scope = NULL;
2229 Variable* catch_variable = NULL; 2264 Variable* catch_variable = NULL;
2230 Block* catch_block = NULL; 2265 Block* catch_block = NULL;
2231 Handle<String> name; 2266 Handle<String> name;
2232 if (tok == Token::CATCH) { 2267 if (tok == Token::CATCH) {
2233 Consume(Token::CATCH); 2268 Consume(Token::CATCH);
2234 2269
2235 Expect(Token::LPAREN, CHECK_OK); 2270 Expect(Token::LPAREN, CHECK_OK);
2271 catch_scope = NewScope(top_scope_, CATCH_SCOPE);
2272 catch_scope->set_start_position(scanner().location().beg_pos);
2236 name = ParseIdentifier(CHECK_OK); 2273 name = ParseIdentifier(CHECK_OK);
2237 2274
2238 if (top_scope_->is_strict_mode() && IsEvalOrArguments(name)) { 2275 if (top_scope_->is_strict_mode() && IsEvalOrArguments(name)) {
2239 ReportMessage("strict_catch_variable", Vector<const char*>::empty()); 2276 ReportMessage("strict_catch_variable", Vector<const char*>::empty());
2240 *ok = false; 2277 *ok = false;
2241 return NULL; 2278 return NULL;
2242 } 2279 }
2243 2280
2244 Expect(Token::RPAREN, CHECK_OK); 2281 Expect(Token::RPAREN, CHECK_OK);
2245 2282
2246 if (peek() == Token::LBRACE) { 2283 if (peek() == Token::LBRACE) {
2247 Target target(&this->target_stack_, &catch_collector); 2284 Target target(&this->target_stack_, &catch_collector);
2248 catch_scope = NewScope(top_scope_, Scope::CATCH_SCOPE, inside_with());
2249 if (top_scope_->is_strict_mode()) {
2250 catch_scope->EnableStrictMode();
2251 }
2252 VariableMode mode = harmony_scoping_ ? LET : VAR; 2285 VariableMode mode = harmony_scoping_ ? LET : VAR;
2253 catch_variable = catch_scope->DeclareLocal(name, mode); 2286 catch_variable = catch_scope->DeclareLocal(name, mode);
2254 2287
2255 Scope* saved_scope = top_scope_; 2288 SaveScope save_scope(this, catch_scope);
2256 top_scope_ = catch_scope;
2257 catch_block = ParseBlock(NULL, CHECK_OK); 2289 catch_block = ParseBlock(NULL, CHECK_OK);
2258 top_scope_ = saved_scope;
2259 } else { 2290 } else {
2260 Expect(Token::LBRACE, CHECK_OK); 2291 Expect(Token::LBRACE, CHECK_OK);
2261 } 2292 }
2262 2293 catch_scope->set_end_position(scanner().location().end_pos);
2263 tok = peek(); 2294 tok = peek();
2264 } 2295 }
2265 2296
2266 Block* finally_block = NULL; 2297 Block* finally_block = NULL;
2267 if (tok == Token::FINALLY || catch_block == NULL) { 2298 if (tok == Token::FINALLY || catch_block == NULL) {
2268 Consume(Token::FINALLY); 2299 Consume(Token::FINALLY);
2269 finally_block = ParseBlock(NULL, CHECK_OK); 2300 finally_block = ParseBlock(NULL, CHECK_OK);
2270 } 2301 }
2271 2302
2272 // Simplify the AST nodes by converting: 2303 // Simplify the AST nodes by converting:
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
2358 return loop; 2389 return loop;
2359 } 2390 }
2360 2391
2361 2392
2362 Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { 2393 Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) {
2363 // ForStatement :: 2394 // ForStatement ::
2364 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement 2395 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
2365 2396
2366 Statement* init = NULL; 2397 Statement* init = NULL;
2367 2398
2399 // Create an in-between scope for let-bound iteration variables.
2400 Scope* saved_scope = top_scope_;
2401 Scope* for_scope = NewScope(top_scope_, BLOCK_SCOPE);
2402 top_scope_ = for_scope;
2403
2368 Expect(Token::FOR, CHECK_OK); 2404 Expect(Token::FOR, CHECK_OK);
2369 Expect(Token::LPAREN, CHECK_OK); 2405 Expect(Token::LPAREN, CHECK_OK);
2406 for_scope->set_start_position(scanner().location().beg_pos);
2370 if (peek() != Token::SEMICOLON) { 2407 if (peek() != Token::SEMICOLON) {
2371 if (peek() == Token::VAR || peek() == Token::CONST) { 2408 if (peek() == Token::VAR || peek() == Token::CONST) {
2372 Handle<String> name; 2409 Handle<String> name;
2373 Block* variable_statement = 2410 Block* variable_statement =
2374 ParseVariableDeclarations(kForStatement, &name, CHECK_OK); 2411 ParseVariableDeclarations(kForStatement, NULL, &name, CHECK_OK);
2375 2412
2376 if (peek() == Token::IN && !name.is_null()) { 2413 if (peek() == Token::IN && !name.is_null()) {
2377 VariableProxy* each = top_scope_->NewUnresolved(name, inside_with()); 2414 VariableProxy* each = top_scope_->NewUnresolved(name);
2378 ForInStatement* loop = new(zone()) ForInStatement(isolate(), labels); 2415 ForInStatement* loop = new(zone()) ForInStatement(isolate(), labels);
2379 Target target(&this->target_stack_, loop); 2416 Target target(&this->target_stack_, loop);
2380 2417
2381 Expect(Token::IN, CHECK_OK); 2418 Expect(Token::IN, CHECK_OK);
2382 Expression* enumerable = ParseExpression(true, CHECK_OK); 2419 Expression* enumerable = ParseExpression(true, CHECK_OK);
2383 Expect(Token::RPAREN, CHECK_OK); 2420 Expect(Token::RPAREN, CHECK_OK);
2384 2421
2385 Statement* body = ParseStatement(NULL, CHECK_OK); 2422 Statement* body = ParseStatement(NULL, CHECK_OK);
2386 loop->Initialize(each, enumerable, body); 2423 loop->Initialize(each, enumerable, body);
2387 Block* result = new(zone()) Block(isolate(), NULL, 2, false); 2424 Block* result = new(zone()) Block(isolate(), NULL, 2, false);
2388 result->AddStatement(variable_statement); 2425 result->AddStatement(variable_statement);
2389 result->AddStatement(loop); 2426 result->AddStatement(loop);
2427 top_scope_ = saved_scope;
2428 for_scope->set_end_position(scanner().location().end_pos);
2429 for_scope = for_scope->FinalizeBlockScope();
2430 ASSERT(for_scope == NULL);
2390 // Parsed for-in loop w/ variable/const declaration. 2431 // Parsed for-in loop w/ variable/const declaration.
2391 return result; 2432 return result;
2392 } else { 2433 } else {
2393 init = variable_statement; 2434 init = variable_statement;
2394 } 2435 }
2436 } else if (peek() == Token::LET) {
2437 Handle<String> name;
2438 VariableDeclarationProperties decl_props = kHasNoInitializers;
2439 Block* variable_statement =
2440 ParseVariableDeclarations(kForStatement,
2441 &decl_props,
2442 &name,
2443 CHECK_OK);
2444 bool accept_IN = !name.is_null() && decl_props != kHasInitializers;
2445 if (peek() == Token::IN && accept_IN) {
2446 // Rewrite a for-in statement of the form
2447 //
2448 // for (let x in e) b
2449 //
2450 // into
2451 //
2452 // <let x' be a temporary variable>
2453 // for (x' in e) {
2454 // let x;
2455 // x = x';
2456 // b;
2457 // }
2395 2458
2459 // TODO(keuchel): Move the temporary variable to the block scope, after
2460 // implementing stack allocated block scoped variables.
2461 Variable* temp = top_scope_->DeclarationScope()->NewTemporary(name);
2462 VariableProxy* temp_proxy = new(zone()) VariableProxy(isolate(), temp);
2463 VariableProxy* each = top_scope_->NewUnresolved(name, inside_with());
2464 ForInStatement* loop = new(zone()) ForInStatement(isolate(), labels);
2465 Target target(&this->target_stack_, loop);
2466
2467 Expect(Token::IN, CHECK_OK);
2468 Expression* enumerable = ParseExpression(true, CHECK_OK);
2469 Expect(Token::RPAREN, CHECK_OK);
2470
2471 Statement* body = ParseStatement(NULL, CHECK_OK);
2472 Block* body_block = new(zone()) Block(isolate(), NULL, 3, false);
2473 Assignment* assignment = new(zone()) Assignment(isolate(),
2474 Token::ASSIGN,
2475 each,
2476 temp_proxy,
2477 RelocInfo::kNoPosition);
2478 Statement* assignment_statement =
2479 new(zone()) ExpressionStatement(assignment);
2480 body_block->AddStatement(variable_statement);
2481 body_block->AddStatement(assignment_statement);
2482 body_block->AddStatement(body);
2483 loop->Initialize(temp_proxy, enumerable, body_block);
2484 top_scope_ = saved_scope;
2485 for_scope->set_end_position(scanner().location().end_pos);
2486 for_scope = for_scope->FinalizeBlockScope();
2487 body_block->set_block_scope(for_scope);
2488 // Parsed for-in loop w/ let declaration.
2489 return loop;
2490
2491 } else {
2492 init = variable_statement;
2493 }
2396 } else { 2494 } else {
2397 Expression* expression = ParseExpression(false, CHECK_OK); 2495 Expression* expression = ParseExpression(false, CHECK_OK);
2398 if (peek() == Token::IN) { 2496 if (peek() == Token::IN) {
2399 // Signal a reference error if the expression is an invalid 2497 // Signal a reference error if the expression is an invalid
2400 // left-hand side expression. We could report this as a syntax 2498 // left-hand side expression. We could report this as a syntax
2401 // error here but for compatibility with JSC we choose to report 2499 // error here but for compatibility with JSC we choose to report
2402 // the error at runtime. 2500 // the error at runtime.
2403 if (expression == NULL || !expression->IsValidLeftHandSide()) { 2501 if (expression == NULL || !expression->IsValidLeftHandSide()) {
2404 Handle<String> type = 2502 Handle<String> type =
2405 isolate()->factory()->invalid_lhs_in_for_in_symbol(); 2503 isolate()->factory()->invalid_lhs_in_for_in_symbol();
2406 expression = NewThrowReferenceError(type); 2504 expression = NewThrowReferenceError(type);
2407 } 2505 }
2408 ForInStatement* loop = new(zone()) ForInStatement(isolate(), labels); 2506 ForInStatement* loop = new(zone()) ForInStatement(isolate(), labels);
2409 Target target(&this->target_stack_, loop); 2507 Target target(&this->target_stack_, loop);
2410 2508
2411 Expect(Token::IN, CHECK_OK); 2509 Expect(Token::IN, CHECK_OK);
2412 Expression* enumerable = ParseExpression(true, CHECK_OK); 2510 Expression* enumerable = ParseExpression(true, CHECK_OK);
2413 Expect(Token::RPAREN, CHECK_OK); 2511 Expect(Token::RPAREN, CHECK_OK);
2414 2512
2415 Statement* body = ParseStatement(NULL, CHECK_OK); 2513 Statement* body = ParseStatement(NULL, CHECK_OK);
2416 if (loop) loop->Initialize(expression, enumerable, body); 2514 if (loop) loop->Initialize(expression, enumerable, body);
2515 top_scope_ = saved_scope;
2516 for_scope->set_end_position(scanner().location().end_pos);
2517 for_scope = for_scope->FinalizeBlockScope();
2518 ASSERT(for_scope == NULL);
2417 // Parsed for-in loop. 2519 // Parsed for-in loop.
2418 return loop; 2520 return loop;
2419 2521
2420 } else { 2522 } else {
2421 init = new(zone()) ExpressionStatement(expression); 2523 init = new(zone()) ExpressionStatement(expression);
2422 } 2524 }
2423 } 2525 }
2424 } 2526 }
2425 2527
2426 // Standard 'for' loop 2528 // Standard 'for' loop
(...skipping 10 matching lines...) Expand all
2437 Expect(Token::SEMICOLON, CHECK_OK); 2539 Expect(Token::SEMICOLON, CHECK_OK);
2438 2540
2439 Statement* next = NULL; 2541 Statement* next = NULL;
2440 if (peek() != Token::RPAREN) { 2542 if (peek() != Token::RPAREN) {
2441 Expression* exp = ParseExpression(true, CHECK_OK); 2543 Expression* exp = ParseExpression(true, CHECK_OK);
2442 next = new(zone()) ExpressionStatement(exp); 2544 next = new(zone()) ExpressionStatement(exp);
2443 } 2545 }
2444 Expect(Token::RPAREN, CHECK_OK); 2546 Expect(Token::RPAREN, CHECK_OK);
2445 2547
2446 Statement* body = ParseStatement(NULL, CHECK_OK); 2548 Statement* body = ParseStatement(NULL, CHECK_OK);
2447 if (loop) loop->Initialize(init, cond, next, body); 2549 top_scope_ = saved_scope;
2448 return loop; 2550 for_scope->set_end_position(scanner().location().end_pos);
2551 for_scope = for_scope->FinalizeBlockScope();
2552 if (for_scope != NULL) {
2553 // Rewrite a for statement of the form
2554 //
2555 // for (let x = i; c; n) b
2556 //
2557 // into
2558 //
2559 // {
2560 // let x = i;
2561 // for (; c; n) b
2562 // }
2563 ASSERT(init != NULL);
2564 Block* result = new(zone()) Block(isolate(), NULL, 2, false);
2565 result->AddStatement(init);
2566 result->AddStatement(loop);
2567 result->set_block_scope(for_scope);
2568 if (loop) loop->Initialize(NULL, cond, next, body);
2569 return result;
2570 } else {
2571 if (loop) loop->Initialize(init, cond, next, body);
2572 return loop;
2573 }
2449 } 2574 }
2450 2575
2451 2576
2452 // Precedence = 1 2577 // Precedence = 1
2453 Expression* Parser::ParseExpression(bool accept_IN, bool* ok) { 2578 Expression* Parser::ParseExpression(bool accept_IN, bool* ok) {
2454 // Expression :: 2579 // Expression ::
2455 // AssignmentExpression 2580 // AssignmentExpression
2456 // Expression ',' AssignmentExpression 2581 // Expression ',' AssignmentExpression
2457 2582
2458 Expression* result = ParseAssignmentExpression(accept_IN, CHECK_OK); 2583 Expression* result = ParseAssignmentExpression(accept_IN, CHECK_OK);
(...skipping 599 matching lines...) Expand 10 before | Expand all | Expand 10 after
3058 case Token::FALSE_LITERAL: 3183 case Token::FALSE_LITERAL:
3059 Consume(Token::FALSE_LITERAL); 3184 Consume(Token::FALSE_LITERAL);
3060 result = new(zone()) Literal( 3185 result = new(zone()) Literal(
3061 isolate(), isolate()->factory()->false_value()); 3186 isolate(), isolate()->factory()->false_value());
3062 break; 3187 break;
3063 3188
3064 case Token::IDENTIFIER: 3189 case Token::IDENTIFIER:
3065 case Token::FUTURE_STRICT_RESERVED_WORD: { 3190 case Token::FUTURE_STRICT_RESERVED_WORD: {
3066 Handle<String> name = ParseIdentifier(CHECK_OK); 3191 Handle<String> name = ParseIdentifier(CHECK_OK);
3067 if (fni_ != NULL) fni_->PushVariableName(name); 3192 if (fni_ != NULL) fni_->PushVariableName(name);
3068 result = top_scope_->NewUnresolved(name, 3193 result = top_scope_->NewUnresolved(name, scanner().location().beg_pos);
3069 inside_with(),
3070 scanner().location().beg_pos);
3071 break; 3194 break;
3072 } 3195 }
3073 3196
3074 case Token::NUMBER: { 3197 case Token::NUMBER: {
3075 Consume(Token::NUMBER); 3198 Consume(Token::NUMBER);
3076 ASSERT(scanner().is_literal_ascii()); 3199 ASSERT(scanner().is_literal_ascii());
3077 double value = StringToDouble(isolate()->unicode_cache(), 3200 double value = StringToDouble(isolate()->unicode_cache(),
3078 scanner().literal_ascii_string(), 3201 scanner().literal_ascii_string(),
3079 ALLOW_HEX | ALLOW_OCTALS); 3202 ALLOW_HEX | ALLOW_OCTALS);
3080 result = NewNumberLiteral(value); 3203 result = NewNumberLiteral(value);
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
3177 values->Add(elem); 3300 values->Add(elem);
3178 if (peek() != Token::RBRACK) { 3301 if (peek() != Token::RBRACK) {
3179 Expect(Token::COMMA, CHECK_OK); 3302 Expect(Token::COMMA, CHECK_OK);
3180 } 3303 }
3181 } 3304 }
3182 Expect(Token::RBRACK, CHECK_OK); 3305 Expect(Token::RBRACK, CHECK_OK);
3183 3306
3184 // Update the scope information before the pre-parsing bailout. 3307 // Update the scope information before the pre-parsing bailout.
3185 int literal_index = lexical_scope_->NextMaterializedLiteralIndex(); 3308 int literal_index = lexical_scope_->NextMaterializedLiteralIndex();
3186 3309
3187 // Allocate a fixed array with all the literals. 3310 // Allocate a fixed array to hold all the object literals.
3188 Handle<FixedArray> literals = 3311 Handle<FixedArray> object_literals =
3189 isolate()->factory()->NewFixedArray(values->length(), TENURED); 3312 isolate()->factory()->NewFixedArray(values->length(), TENURED);
3313 Handle<FixedDoubleArray> double_literals;
3314 ElementsKind elements_kind = FAST_SMI_ONLY_ELEMENTS;
3190 3315
3191 // Fill in the literals. 3316 // Fill in the literals.
3192 bool is_simple = true; 3317 bool is_simple = true;
3193 int depth = 1; 3318 int depth = 1;
3194 for (int i = 0, n = values->length(); i < n; i++) { 3319 for (int i = 0, n = values->length(); i < n; i++) {
3195 MaterializedLiteral* m_literal = values->at(i)->AsMaterializedLiteral(); 3320 MaterializedLiteral* m_literal = values->at(i)->AsMaterializedLiteral();
3196 if (m_literal != NULL && m_literal->depth() + 1 > depth) { 3321 if (m_literal != NULL && m_literal->depth() + 1 > depth) {
3197 depth = m_literal->depth() + 1; 3322 depth = m_literal->depth() + 1;
3198 } 3323 }
3199 Handle<Object> boilerplate_value = GetBoilerplateValue(values->at(i)); 3324 Handle<Object> boilerplate_value = GetBoilerplateValue(values->at(i));
3200 if (boilerplate_value->IsUndefined()) { 3325 if (boilerplate_value->IsUndefined()) {
3201 literals->set_the_hole(i); 3326 object_literals->set_the_hole(i);
3327 if (elements_kind == FAST_DOUBLE_ELEMENTS) {
3328 double_literals->set_the_hole(i);
3329 }
3202 is_simple = false; 3330 is_simple = false;
3203 } else { 3331 } else {
3204 literals->set(i, *boilerplate_value); 3332 // Examine each literal element, and adjust the ElementsKind if the
3333 // literal element is not of a type that can be stored in the current
3334 // ElementsKind. Start with FAST_SMI_ONLY_ELEMENTS, and transition to
3335 // FAST_DOUBLE_ELEMENTS and FAST_ELEMENTS as necessary. Always remember
3336 // the tagged value, no matter what the ElementsKind is in case we
3337 // ultimately end up in FAST_ELEMENTS.
3338 object_literals->set(i, *boilerplate_value);
3339 if (elements_kind == FAST_SMI_ONLY_ELEMENTS) {
3340 // Smi only elements. Notice if a transition to FAST_DOUBLE_ELEMENTS or
3341 // FAST_ELEMENTS is required.
3342 if (!boilerplate_value->IsSmi()) {
3343 if (boilerplate_value->IsNumber() && FLAG_smi_only_arrays) {
3344 // Allocate a double array on the FAST_DOUBLE_ELEMENTS transition to
3345 // avoid over-allocating in TENURED space.
3346 double_literals = isolate()->factory()->NewFixedDoubleArray(
3347 values->length(), TENURED);
3348 // Copy the contents of the FAST_SMI_ONLY_ELEMENT array to the
3349 // FAST_DOUBLE_ELEMENTS array so that they are in sync.
3350 for (int j = 0; j < i; ++j) {
3351 Object* smi_value = object_literals->get(j);
3352 if (smi_value->IsTheHole()) {
3353 double_literals->set_the_hole(j);
3354 } else {
3355 double_literals->set(j, Smi::cast(smi_value)->value());
3356 }
3357 }
3358 double_literals->set(i, boilerplate_value->Number());
3359 elements_kind = FAST_DOUBLE_ELEMENTS;
3360 } else {
3361 elements_kind = FAST_ELEMENTS;
3362 }
3363 }
3364 } else if (elements_kind == FAST_DOUBLE_ELEMENTS) {
3365 // Continue to store double values in to FAST_DOUBLE_ELEMENTS arrays
3366 // until the first value is seen that can't be stored as a double.
3367 if (boilerplate_value->IsNumber()) {
3368 double_literals->set(i, boilerplate_value->Number());
3369 } else {
3370 elements_kind = FAST_ELEMENTS;
3371 }
3372 }
3205 } 3373 }
3206 } 3374 }
3207 3375
3208 // Simple and shallow arrays can be lazily copied, we transform the 3376 // Simple and shallow arrays can be lazily copied, we transform the
3209 // elements array to a copy-on-write array. 3377 // elements array to a copy-on-write array.
3210 if (is_simple && depth == 1 && values->length() > 0) { 3378 if (is_simple && depth == 1 && values->length() > 0 &&
3211 literals->set_map(isolate()->heap()->fixed_cow_array_map()); 3379 elements_kind != FAST_DOUBLE_ELEMENTS) {
3380 object_literals->set_map(isolate()->heap()->fixed_cow_array_map());
3212 } 3381 }
3213 3382
3383 Handle<FixedArrayBase> element_values = elements_kind == FAST_DOUBLE_ELEMENTS
3384 ? Handle<FixedArrayBase>(double_literals)
3385 : Handle<FixedArrayBase>(object_literals);
3386
3387 // Remember both the literal's constant values as well as the ElementsKind
3388 // in a 2-element FixedArray.
3389 Handle<FixedArray> literals =
3390 isolate()->factory()->NewFixedArray(2, TENURED);
3391
3392 literals->set(0, Smi::FromInt(elements_kind));
3393 literals->set(1, *element_values);
3394
3214 return new(zone()) ArrayLiteral( 3395 return new(zone()) ArrayLiteral(
3215 isolate(), literals, values, literal_index, is_simple, depth); 3396 isolate(), literals, values, literal_index, is_simple, depth);
3216 } 3397 }
3217 3398
3218 3399
3219 bool Parser::IsBoilerplateProperty(ObjectLiteral::Property* property) { 3400 bool Parser::IsBoilerplateProperty(ObjectLiteral::Property* property) {
3220 return property != NULL && 3401 return property != NULL &&
3221 property->kind() != ObjectLiteral::Property::PROTOTYPE; 3402 property->kind() != ObjectLiteral::Property::PROTOTYPE;
3222 } 3403 }
3223 3404
(...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after
3708 // We want a non-null handle as the function name. 3889 // We want a non-null handle as the function name.
3709 if (should_infer_name) { 3890 if (should_infer_name) {
3710 function_name = isolate()->factory()->empty_symbol(); 3891 function_name = isolate()->factory()->empty_symbol();
3711 } 3892 }
3712 3893
3713 int num_parameters = 0; 3894 int num_parameters = 0;
3714 // Function declarations are function scoped in normal mode, so they are 3895 // Function declarations are function scoped in normal mode, so they are
3715 // hoisted. In harmony block scoping mode they are block scoped, so they 3896 // hoisted. In harmony block scoping mode they are block scoped, so they
3716 // are not hoisted. 3897 // are not hoisted.
3717 Scope* scope = (type == FunctionLiteral::DECLARATION && !harmony_scoping_) 3898 Scope* scope = (type == FunctionLiteral::DECLARATION && !harmony_scoping_)
3718 ? NewScope(top_scope_->DeclarationScope(), Scope::FUNCTION_SCOPE, false) 3899 ? NewScope(top_scope_->DeclarationScope(), FUNCTION_SCOPE)
3719 : NewScope(top_scope_, Scope::FUNCTION_SCOPE, inside_with()); 3900 : NewScope(top_scope_, FUNCTION_SCOPE);
3720 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(8); 3901 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(8);
3721 int materialized_literal_count; 3902 int materialized_literal_count;
3722 int expected_property_count; 3903 int expected_property_count;
3723 int start_pos;
3724 int end_pos;
3725 bool only_simple_this_property_assignments; 3904 bool only_simple_this_property_assignments;
3726 Handle<FixedArray> this_property_assignments; 3905 Handle<FixedArray> this_property_assignments;
3727 bool has_duplicate_parameters = false; 3906 bool has_duplicate_parameters = false;
3728 // Parse function body. 3907 // Parse function body.
3729 { LexicalScope lexical_scope(this, scope, isolate()); 3908 { LexicalScope lexical_scope(this, scope, isolate());
3730 top_scope_->SetScopeName(function_name); 3909 top_scope_->SetScopeName(function_name);
3731 3910
3732 // FormalParameterList :: 3911 // FormalParameterList ::
3733 // '(' (Identifier)*[','] ')' 3912 // '(' (Identifier)*[','] ')'
3734 Expect(Token::LPAREN, CHECK_OK); 3913 Expect(Token::LPAREN, CHECK_OK);
3735 start_pos = scanner().location().beg_pos; 3914 scope->set_start_position(scanner().location().beg_pos);
3736 Scanner::Location name_loc = Scanner::Location::invalid(); 3915 Scanner::Location name_loc = Scanner::Location::invalid();
3737 Scanner::Location dupe_loc = Scanner::Location::invalid(); 3916 Scanner::Location dupe_loc = Scanner::Location::invalid();
3738 Scanner::Location reserved_loc = Scanner::Location::invalid(); 3917 Scanner::Location reserved_loc = Scanner::Location::invalid();
3739 3918
3740 bool done = (peek() == Token::RPAREN); 3919 bool done = (peek() == Token::RPAREN);
3741 while (!done) { 3920 while (!done) {
3742 bool is_strict_reserved = false; 3921 bool is_strict_reserved = false;
3743 Handle<String> param_name = 3922 Handle<String> param_name =
3744 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, 3923 ParseIdentifierOrStrictReservedWord(&is_strict_reserved,
3745 CHECK_OK); 3924 CHECK_OK);
(...skipping 25 matching lines...) Expand all
3771 3950
3772 Expect(Token::LBRACE, CHECK_OK); 3951 Expect(Token::LBRACE, CHECK_OK);
3773 3952
3774 // If we have a named function expression, we add a local variable 3953 // If we have a named function expression, we add a local variable
3775 // declaration to the body of the function with the name of the 3954 // declaration to the body of the function with the name of the
3776 // function and let it refer to the function itself (closure). 3955 // function and let it refer to the function itself (closure).
3777 // NOTE: We create a proxy and resolve it here so that in the 3956 // NOTE: We create a proxy and resolve it here so that in the
3778 // future we can change the AST to only refer to VariableProxies 3957 // future we can change the AST to only refer to VariableProxies
3779 // instead of Variables and Proxis as is the case now. 3958 // instead of Variables and Proxis as is the case now.
3780 if (type == FunctionLiteral::NAMED_EXPRESSION) { 3959 if (type == FunctionLiteral::NAMED_EXPRESSION) {
3781 Variable* fvar = top_scope_->DeclareFunctionVar(function_name); 3960 VariableMode fvar_mode;
3782 VariableProxy* fproxy = 3961 Token::Value fvar_init_op;
3783 top_scope_->NewUnresolved(function_name, inside_with()); 3962 if (harmony_scoping_) {
3963 fvar_mode = CONST_HARMONY;
3964 fvar_init_op = Token::INIT_CONST_HARMONY;
3965 } else {
3966 fvar_mode = CONST;
3967 fvar_init_op = Token::INIT_CONST;
3968 }
3969 Variable* fvar = top_scope_->DeclareFunctionVar(function_name, fvar_mode);
3970 VariableProxy* fproxy = top_scope_->NewUnresolved(function_name);
3784 fproxy->BindTo(fvar); 3971 fproxy->BindTo(fvar);
3785 body->Add(new(zone()) ExpressionStatement( 3972 body->Add(new(zone()) ExpressionStatement(
3786 new(zone()) Assignment(isolate(), 3973 new(zone()) Assignment(isolate(),
3787 Token::INIT_CONST, 3974 fvar_init_op,
3788 fproxy, 3975 fproxy,
3789 new(zone()) ThisFunction(isolate()), 3976 new(zone()) ThisFunction(isolate()),
3790 RelocInfo::kNoPosition))); 3977 RelocInfo::kNoPosition)));
3791 } 3978 }
3792 3979
3793 // Determine if the function will be lazily compiled. The mode can only 3980 // Determine if the function will be lazily compiled. The mode can only
3794 // be PARSE_LAZILY if the --lazy flag is true. We will not lazily 3981 // be PARSE_LAZILY if the --lazy flag is true. We will not lazily
3795 // compile if we do not have preparser data for the function. 3982 // compile if we do not have preparser data for the function.
3796 bool is_lazily_compiled = (mode() == PARSE_LAZILY && 3983 bool is_lazily_compiled = (mode() == PARSE_LAZILY &&
3797 top_scope_->outer_scope()->is_global_scope() && 3984 top_scope_->outer_scope()->is_global_scope() &&
3798 top_scope_->HasTrivialOuterContext() && 3985 top_scope_->HasTrivialOuterContext() &&
3799 !parenthesized_function_ && 3986 !parenthesized_function_ &&
3800 pre_data() != NULL); 3987 pre_data() != NULL);
3801 parenthesized_function_ = false; // The bit was set for this function only. 3988 parenthesized_function_ = false; // The bit was set for this function only.
3802 3989
3803 if (is_lazily_compiled) { 3990 if (is_lazily_compiled) {
3804 int function_block_pos = scanner().location().beg_pos; 3991 int function_block_pos = scanner().location().beg_pos;
3805 FunctionEntry entry = pre_data()->GetFunctionEntry(function_block_pos); 3992 FunctionEntry entry = pre_data()->GetFunctionEntry(function_block_pos);
3806 if (!entry.is_valid()) { 3993 if (!entry.is_valid()) {
3807 // There is no preparser data for the function, we will not lazily 3994 // There is no preparser data for the function, we will not lazily
3808 // compile after all. 3995 // compile after all.
3809 is_lazily_compiled = false; 3996 is_lazily_compiled = false;
3810 } else { 3997 } else {
3811 end_pos = entry.end_pos(); 3998 scope->set_end_position(entry.end_pos());
3812 if (end_pos <= function_block_pos) { 3999 if (scope->end_position() <= function_block_pos) {
3813 // End position greater than end of stream is safe, and hard to check. 4000 // End position greater than end of stream is safe, and hard to check.
3814 ReportInvalidPreparseData(function_name, CHECK_OK); 4001 ReportInvalidPreparseData(function_name, CHECK_OK);
3815 } 4002 }
3816 isolate()->counters()->total_preparse_skipped()->Increment( 4003 isolate()->counters()->total_preparse_skipped()->Increment(
3817 end_pos - function_block_pos); 4004 scope->end_position() - function_block_pos);
3818 // Seek to position just before terminal '}'. 4005 // Seek to position just before terminal '}'.
3819 scanner().SeekForward(end_pos - 1); 4006 scanner().SeekForward(scope->end_position() - 1);
3820 materialized_literal_count = entry.literal_count(); 4007 materialized_literal_count = entry.literal_count();
3821 expected_property_count = entry.property_count(); 4008 expected_property_count = entry.property_count();
3822 if (entry.strict_mode()) top_scope_->EnableStrictMode(); 4009 if (entry.strict_mode()) top_scope_->SetStrictModeFlag(kStrictMode);
3823 only_simple_this_property_assignments = false; 4010 only_simple_this_property_assignments = false;
3824 this_property_assignments = isolate()->factory()->empty_fixed_array(); 4011 this_property_assignments = isolate()->factory()->empty_fixed_array();
3825 Expect(Token::RBRACE, CHECK_OK); 4012 Expect(Token::RBRACE, CHECK_OK);
3826 } 4013 }
3827 } 4014 }
3828 4015
3829 if (!is_lazily_compiled) { 4016 if (!is_lazily_compiled) {
3830 ParseSourceElements(body, Token::RBRACE, CHECK_OK); 4017 ParseSourceElements(body, Token::RBRACE, CHECK_OK);
3831 4018
3832 materialized_literal_count = lexical_scope.materialized_literal_count(); 4019 materialized_literal_count = lexical_scope.materialized_literal_count();
3833 expected_property_count = lexical_scope.expected_property_count(); 4020 expected_property_count = lexical_scope.expected_property_count();
3834 only_simple_this_property_assignments = 4021 only_simple_this_property_assignments =
3835 lexical_scope.only_simple_this_property_assignments(); 4022 lexical_scope.only_simple_this_property_assignments();
3836 this_property_assignments = lexical_scope.this_property_assignments(); 4023 this_property_assignments = lexical_scope.this_property_assignments();
3837 4024
3838 Expect(Token::RBRACE, CHECK_OK); 4025 Expect(Token::RBRACE, CHECK_OK);
3839 end_pos = scanner().location().end_pos; 4026 scope->set_end_position(scanner().location().end_pos);
3840 } 4027 }
3841 4028
3842 // Validate strict mode. 4029 // Validate strict mode.
3843 if (top_scope_->is_strict_mode()) { 4030 if (top_scope_->is_strict_mode()) {
3844 if (IsEvalOrArguments(function_name)) { 4031 if (IsEvalOrArguments(function_name)) {
4032 int start_pos = scope->start_position();
3845 int position = function_token_position != RelocInfo::kNoPosition 4033 int position = function_token_position != RelocInfo::kNoPosition
3846 ? function_token_position 4034 ? function_token_position
3847 : (start_pos > 0 ? start_pos - 1 : start_pos); 4035 : (start_pos > 0 ? start_pos - 1 : start_pos);
3848 Scanner::Location location = Scanner::Location(position, start_pos); 4036 Scanner::Location location = Scanner::Location(position, start_pos);
3849 ReportMessageAt(location, 4037 ReportMessageAt(location,
3850 "strict_function_name", Vector<const char*>::empty()); 4038 "strict_function_name", Vector<const char*>::empty());
3851 *ok = false; 4039 *ok = false;
3852 return NULL; 4040 return NULL;
3853 } 4041 }
3854 if (name_loc.IsValid()) { 4042 if (name_loc.IsValid()) {
3855 ReportMessageAt(name_loc, "strict_param_name", 4043 ReportMessageAt(name_loc, "strict_param_name",
3856 Vector<const char*>::empty()); 4044 Vector<const char*>::empty());
3857 *ok = false; 4045 *ok = false;
3858 return NULL; 4046 return NULL;
3859 } 4047 }
3860 if (dupe_loc.IsValid()) { 4048 if (dupe_loc.IsValid()) {
3861 ReportMessageAt(dupe_loc, "strict_param_dupe", 4049 ReportMessageAt(dupe_loc, "strict_param_dupe",
3862 Vector<const char*>::empty()); 4050 Vector<const char*>::empty());
3863 *ok = false; 4051 *ok = false;
3864 return NULL; 4052 return NULL;
3865 } 4053 }
3866 if (name_is_strict_reserved) { 4054 if (name_is_strict_reserved) {
4055 int start_pos = scope->start_position();
3867 int position = function_token_position != RelocInfo::kNoPosition 4056 int position = function_token_position != RelocInfo::kNoPosition
3868 ? function_token_position 4057 ? function_token_position
3869 : (start_pos > 0 ? start_pos - 1 : start_pos); 4058 : (start_pos > 0 ? start_pos - 1 : start_pos);
3870 Scanner::Location location = Scanner::Location(position, start_pos); 4059 Scanner::Location location = Scanner::Location(position, start_pos);
3871 ReportMessageAt(location, "strict_reserved_word", 4060 ReportMessageAt(location, "strict_reserved_word",
3872 Vector<const char*>::empty()); 4061 Vector<const char*>::empty());
3873 *ok = false; 4062 *ok = false;
3874 return NULL; 4063 return NULL;
3875 } 4064 }
3876 if (reserved_loc.IsValid()) { 4065 if (reserved_loc.IsValid()) {
3877 ReportMessageAt(reserved_loc, "strict_reserved_word", 4066 ReportMessageAt(reserved_loc, "strict_reserved_word",
3878 Vector<const char*>::empty()); 4067 Vector<const char*>::empty());
3879 *ok = false; 4068 *ok = false;
3880 return NULL; 4069 return NULL;
3881 } 4070 }
3882 CheckOctalLiteral(start_pos, end_pos, CHECK_OK); 4071 CheckOctalLiteral(scope->start_position(),
4072 scope->end_position(),
4073 CHECK_OK);
3883 } 4074 }
3884 } 4075 }
3885 4076
3886 if (harmony_scoping_) { 4077 if (harmony_scoping_) {
3887 CheckConflictingVarDeclarations(scope, CHECK_OK); 4078 CheckConflictingVarDeclarations(scope, CHECK_OK);
3888 } 4079 }
3889 4080
3890 FunctionLiteral* function_literal = 4081 FunctionLiteral* function_literal =
3891 new(zone()) FunctionLiteral(isolate(), 4082 new(zone()) FunctionLiteral(isolate(),
3892 function_name, 4083 function_name,
3893 scope, 4084 scope,
3894 body, 4085 body,
3895 materialized_literal_count, 4086 materialized_literal_count,
3896 expected_property_count, 4087 expected_property_count,
3897 only_simple_this_property_assignments, 4088 only_simple_this_property_assignments,
3898 this_property_assignments, 4089 this_property_assignments,
3899 num_parameters, 4090 num_parameters,
3900 start_pos,
3901 end_pos,
3902 type, 4091 type,
3903 has_duplicate_parameters); 4092 has_duplicate_parameters);
3904 function_literal->set_function_token_position(function_token_position); 4093 function_literal->set_function_token_position(function_token_position);
3905 4094
3906 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal); 4095 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal);
3907 return function_literal; 4096 return function_literal;
3908 } 4097 }
3909 4098
3910 4099
3911 Expression* Parser::ParseV8Intrinsic(bool* ok) { 4100 Expression* Parser::ParseV8Intrinsic(bool* ok) {
(...skipping 1200 matching lines...) Expand 10 before | Expand all | Expand 10 after
5112 result = (result << 7) | (input & 0x7f); 5301 result = (result << 7) | (input & 0x7f);
5113 data++; 5302 data++;
5114 } 5303 }
5115 *source = data; 5304 *source = data;
5116 return result; 5305 return result;
5117 } 5306 }
5118 5307
5119 5308
5120 // Create a Scanner for the preparser to use as input, and preparse the source. 5309 // Create a Scanner for the preparser to use as input, and preparse the source.
5121 static ScriptDataImpl* DoPreParse(UC16CharacterStream* source, 5310 static ScriptDataImpl* DoPreParse(UC16CharacterStream* source,
5122 bool allow_lazy, 5311 int flags,
5123 ParserRecorder* recorder, 5312 ParserRecorder* recorder) {
5124 bool harmony_scoping) {
5125 Isolate* isolate = Isolate::Current(); 5313 Isolate* isolate = Isolate::Current();
5126 JavaScriptScanner scanner(isolate->unicode_cache()); 5314 JavaScriptScanner scanner(isolate->unicode_cache());
5127 scanner.SetHarmonyScoping(harmony_scoping); 5315 scanner.SetHarmonyScoping((flags & kHarmonyScoping) != 0);
5128 scanner.Initialize(source); 5316 scanner.Initialize(source);
5129 intptr_t stack_limit = isolate->stack_guard()->real_climit(); 5317 intptr_t stack_limit = isolate->stack_guard()->real_climit();
5130 if (!preparser::PreParser::PreParseProgram(&scanner, 5318 if (!preparser::PreParser::PreParseProgram(&scanner,
5131 recorder, 5319 recorder,
5132 allow_lazy, 5320 flags,
5133 stack_limit)) { 5321 stack_limit)) {
5134 isolate->StackOverflow(); 5322 isolate->StackOverflow();
5135 return NULL; 5323 return NULL;
5136 } 5324 }
5137 5325
5138 // Extract the accumulated data from the recorder as a single 5326 // Extract the accumulated data from the recorder as a single
5139 // contiguous vector that we are responsible for disposing. 5327 // contiguous vector that we are responsible for disposing.
5140 Vector<unsigned> store = recorder->ExtractData(); 5328 Vector<unsigned> store = recorder->ExtractData();
5141 return new ScriptDataImpl(store); 5329 return new ScriptDataImpl(store);
5142 } 5330 }
5143 5331
5144 5332
5145 // Preparse, but only collect data that is immediately useful, 5333 // Preparse, but only collect data that is immediately useful,
5146 // even if the preparser data is only used once. 5334 // even if the preparser data is only used once.
5147 ScriptDataImpl* ParserApi::PartialPreParse(UC16CharacterStream* source, 5335 ScriptDataImpl* ParserApi::PartialPreParse(UC16CharacterStream* source,
5148 v8::Extension* extension, 5336 v8::Extension* extension,
5149 bool harmony_scoping) { 5337 int flags) {
5150 bool allow_lazy = FLAG_lazy && (extension == NULL); 5338 bool allow_lazy = FLAG_lazy && (extension == NULL);
5151 if (!allow_lazy) { 5339 if (!allow_lazy) {
5152 // Partial preparsing is only about lazily compiled functions. 5340 // Partial preparsing is only about lazily compiled functions.
5153 // If we don't allow lazy compilation, the log data will be empty. 5341 // If we don't allow lazy compilation, the log data will be empty.
5154 return NULL; 5342 return NULL;
5155 } 5343 }
5344 flags |= kAllowLazy;
5156 PartialParserRecorder recorder; 5345 PartialParserRecorder recorder;
5157 return DoPreParse(source, allow_lazy, &recorder, harmony_scoping); 5346 return DoPreParse(source, flags, &recorder);
5158 } 5347 }
5159 5348
5160 5349
5161 ScriptDataImpl* ParserApi::PreParse(UC16CharacterStream* source, 5350 ScriptDataImpl* ParserApi::PreParse(UC16CharacterStream* source,
5162 v8::Extension* extension, 5351 v8::Extension* extension,
5163 bool harmony_scoping) { 5352 int flags) {
5164 Handle<Script> no_script; 5353 Handle<Script> no_script;
5165 bool allow_lazy = FLAG_lazy && (extension == NULL); 5354 if (FLAG_lazy && (extension == NULL)) {
5355 flags |= kAllowLazy;
5356 }
5166 CompleteParserRecorder recorder; 5357 CompleteParserRecorder recorder;
5167 return DoPreParse(source, allow_lazy, &recorder, harmony_scoping); 5358 return DoPreParse(source, flags, &recorder);
5168 } 5359 }
5169 5360
5170 5361
5171 bool RegExpParser::ParseRegExp(FlatStringReader* input, 5362 bool RegExpParser::ParseRegExp(FlatStringReader* input,
5172 bool multiline, 5363 bool multiline,
5173 RegExpCompileData* result) { 5364 RegExpCompileData* result) {
5174 ASSERT(result != NULL); 5365 ASSERT(result != NULL);
5175 RegExpParser parser(input, &result->error, multiline); 5366 RegExpParser parser(input, &result->error, multiline);
5176 RegExpTree* tree = parser.ParsePattern(); 5367 RegExpTree* tree = parser.ParsePattern();
5177 if (parser.failed()) { 5368 if (parser.failed()) {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
5220 DeleteArray(message); 5411 DeleteArray(message);
5221 for (int i = 0; i < args.length(); i++) { 5412 for (int i = 0; i < args.length(); i++) {
5222 DeleteArray(args[i]); 5413 DeleteArray(args[i]);
5223 } 5414 }
5224 DeleteArray(args.start()); 5415 DeleteArray(args.start());
5225 ASSERT(info->isolate()->has_pending_exception()); 5416 ASSERT(info->isolate()->has_pending_exception());
5226 } else { 5417 } else {
5227 Handle<String> source = Handle<String>(String::cast(script->source())); 5418 Handle<String> source = Handle<String>(String::cast(script->source()));
5228 result = parser.ParseProgram(source, 5419 result = parser.ParseProgram(source,
5229 info->is_global(), 5420 info->is_global(),
5230 info->StrictMode()); 5421 info->strict_mode_flag());
5231 } 5422 }
5232 } 5423 }
5233 info->SetFunction(result); 5424 info->SetFunction(result);
5234 return (result != NULL); 5425 return (result != NULL);
5235 } 5426 }
5236 5427
5237 } } // namespace v8::internal 5428 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/parser.h ('k') | src/preparser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698