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

Side by Side Diff: src/parser.cc

Issue 8417035: Introduce extended mode. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebased to tip of tree. 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
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 591 matching lines...) Expand 10 before | Expand all | Expand 10 after
602 allow_natives_syntax_(allow_natives_syntax), 602 allow_natives_syntax_(allow_natives_syntax),
603 stack_overflow_(false), 603 stack_overflow_(false),
604 parenthesized_function_(false), 604 parenthesized_function_(false),
605 harmony_scoping_(false) { 605 harmony_scoping_(false) {
606 AstNode::ResetIds(); 606 AstNode::ResetIds();
607 } 607 }
608 608
609 609
610 FunctionLiteral* Parser::ParseProgram(Handle<String> source, 610 FunctionLiteral* Parser::ParseProgram(Handle<String> source,
611 bool in_global_context, 611 bool in_global_context,
612 StrictModeFlag strict_mode) { 612 LanguageMode language_mode) {
613 ZoneScope zone_scope(isolate(), DONT_DELETE_ON_EXIT); 613 ZoneScope zone_scope(isolate(), DONT_DELETE_ON_EXIT);
614 614
615 HistogramTimerScope timer(isolate()->counters()->parse()); 615 HistogramTimerScope timer(isolate()->counters()->parse());
616 isolate()->counters()->total_parse_size()->Increment(source->length()); 616 isolate()->counters()->total_parse_size()->Increment(source->length());
617 fni_ = new(zone()) FuncNameInferrer(isolate()); 617 fni_ = new(zone()) FuncNameInferrer(isolate());
618 618
619 // Initialize parser state. 619 // Initialize parser state.
620 source->TryFlatten(); 620 source->TryFlatten();
621 if (source->IsExternalTwoByteString()) { 621 if (source->IsExternalTwoByteString()) {
622 // Notice that the stream is destroyed at the end of the branch block. 622 // Notice that the stream is destroyed at the end of the branch block.
623 // The last line of the blocks can't be moved outside, even though they're 623 // The last line of the blocks can't be moved outside, even though they're
624 // identical calls. 624 // identical calls.
625 ExternalTwoByteStringUC16CharacterStream stream( 625 ExternalTwoByteStringUC16CharacterStream stream(
626 Handle<ExternalTwoByteString>::cast(source), 0, source->length()); 626 Handle<ExternalTwoByteString>::cast(source), 0, source->length());
627 scanner_.Initialize(&stream); 627 scanner_.Initialize(&stream);
628 return DoParseProgram(source, in_global_context, strict_mode, &zone_scope); 628 return
629 DoParseProgram(source, in_global_context, language_mode, &zone_scope);
629 } else { 630 } else {
630 GenericStringUC16CharacterStream stream(source, 0, source->length()); 631 GenericStringUC16CharacterStream stream(source, 0, source->length());
631 scanner_.Initialize(&stream); 632 scanner_.Initialize(&stream);
632 return DoParseProgram(source, in_global_context, strict_mode, &zone_scope); 633 return
634 DoParseProgram(source, in_global_context, language_mode, &zone_scope);
633 } 635 }
634 } 636 }
635 637
636 638
637 FunctionLiteral* Parser::DoParseProgram(Handle<String> source, 639 FunctionLiteral* Parser::DoParseProgram(Handle<String> source,
638 bool in_global_context, 640 bool in_global_context,
639 StrictModeFlag strict_mode, 641 LanguageMode language_mode,
640 ZoneScope* zone_scope) { 642 ZoneScope* zone_scope) {
641 ASSERT(top_scope_ == NULL); 643 ASSERT(top_scope_ == NULL);
642 ASSERT(target_stack_ == NULL); 644 ASSERT(target_stack_ == NULL);
643 if (pre_data_ != NULL) pre_data_->Initialize(); 645 if (pre_data_ != NULL) pre_data_->Initialize();
644 646
645 // Compute the parsing mode. 647 // Compute the parsing mode.
646 mode_ = FLAG_lazy ? PARSE_LAZILY : PARSE_EAGERLY; 648 mode_ = FLAG_lazy ? PARSE_LAZILY : PARSE_EAGERLY;
647 if (allow_natives_syntax_ || extension_ != NULL) mode_ = PARSE_EAGERLY; 649 if (allow_natives_syntax_ || extension_ != NULL) mode_ = PARSE_EAGERLY;
648 650
649 ScopeType type = in_global_context ? GLOBAL_SCOPE : EVAL_SCOPE; 651 ScopeType type = in_global_context ? GLOBAL_SCOPE : EVAL_SCOPE;
650 Handle<String> no_name = isolate()->factory()->empty_symbol(); 652 Handle<String> no_name = isolate()->factory()->empty_symbol();
651 653
652 FunctionLiteral* result = NULL; 654 FunctionLiteral* result = NULL;
653 { Scope* scope = NewScope(top_scope_, type); 655 { Scope* scope = NewScope(top_scope_, type);
654 scope->set_start_position(0); 656 scope->set_start_position(0);
655 scope->set_end_position(source->length()); 657 scope->set_end_position(source->length());
656 FunctionState function_state(this, scope, isolate()); 658 FunctionState function_state(this, scope, isolate());
657 ASSERT(top_scope_->strict_mode_flag() == kNonStrictMode); 659 ASSERT(top_scope_->language_mode() == CLASSIC_MODE);
658 top_scope_->SetStrictModeFlag(strict_mode); 660 top_scope_->SetLanguageMode(language_mode);
659 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16); 661 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16);
660 bool ok = true; 662 bool ok = true;
661 int beg_loc = scanner().location().beg_pos; 663 int beg_loc = scanner().location().beg_pos;
662 ParseSourceElements(body, Token::EOS, &ok); 664 ParseSourceElements(body, Token::EOS, &ok);
663 if (ok && top_scope_->is_strict_mode()) { 665 if (ok && !top_scope_->is_classic_mode()) {
664 CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok); 666 CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok);
665 } 667 }
666 668
667 if (ok && harmony_scoping_) { 669 if (ok && harmony_scoping_) {
668 CheckConflictingVarDeclarations(scope, &ok); 670 CheckConflictingVarDeclarations(scope, &ok);
669 } 671 }
670 672
671 if (ok) { 673 if (ok) {
672 result = new(zone()) FunctionLiteral( 674 result = new(zone()) FunctionLiteral(
673 isolate(), 675 isolate(),
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
739 // Place holder for the result. 741 // Place holder for the result.
740 FunctionLiteral* result = NULL; 742 FunctionLiteral* result = NULL;
741 743
742 { 744 {
743 // Parse the function literal. 745 // Parse the function literal.
744 Scope* scope = NewScope(top_scope_, GLOBAL_SCOPE); 746 Scope* scope = NewScope(top_scope_, GLOBAL_SCOPE);
745 if (!info->closure().is_null()) { 747 if (!info->closure().is_null()) {
746 scope = Scope::DeserializeScopeChain(info, scope); 748 scope = Scope::DeserializeScopeChain(info, scope);
747 } 749 }
748 FunctionState function_state(this, scope, isolate()); 750 FunctionState function_state(this, scope, isolate());
749 ASSERT(scope->strict_mode_flag() == kNonStrictMode || 751 ASSERT(scope->language_mode() != STRICT_MODE || !info->is_classic_mode());
750 scope->strict_mode_flag() == info->strict_mode_flag()); 752 ASSERT(scope->language_mode() != EXTENDED_MODE ||
751 ASSERT(info->strict_mode_flag() == shared_info->strict_mode_flag()); 753 info->is_extended_mode());
752 scope->SetStrictModeFlag(shared_info->strict_mode_flag()); 754 ASSERT(info->language_mode() == shared_info->language_mode());
755 scope->SetLanguageMode(shared_info->language_mode());
753 FunctionLiteral::Type type = shared_info->is_expression() 756 FunctionLiteral::Type type = shared_info->is_expression()
754 ? (shared_info->is_anonymous() 757 ? (shared_info->is_anonymous()
755 ? FunctionLiteral::ANONYMOUS_EXPRESSION 758 ? FunctionLiteral::ANONYMOUS_EXPRESSION
756 : FunctionLiteral::NAMED_EXPRESSION) 759 : FunctionLiteral::NAMED_EXPRESSION)
757 : FunctionLiteral::DECLARATION; 760 : FunctionLiteral::DECLARATION;
758 bool ok = true; 761 bool ok = true;
759 result = ParseFunctionLiteral(name, 762 result = ParseFunctionLiteral(name,
760 false, // Strict mode name already checked. 763 false, // Strict mode name already checked.
761 RelocInfo::kNoPosition, 764 RelocInfo::kNoPosition,
762 type, 765 type,
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after
1185 // A shot at a directive. 1188 // A shot at a directive.
1186 ExpressionStatement *e_stat; 1189 ExpressionStatement *e_stat;
1187 Literal *literal; 1190 Literal *literal;
1188 // Still processing directive prologue? 1191 // Still processing directive prologue?
1189 if ((e_stat = stat->AsExpressionStatement()) != NULL && 1192 if ((e_stat = stat->AsExpressionStatement()) != NULL &&
1190 (literal = e_stat->expression()->AsLiteral()) != NULL && 1193 (literal = e_stat->expression()->AsLiteral()) != NULL &&
1191 literal->handle()->IsString()) { 1194 literal->handle()->IsString()) {
1192 Handle<String> directive = Handle<String>::cast(literal->handle()); 1195 Handle<String> directive = Handle<String>::cast(literal->handle());
1193 1196
1194 // Check "use strict" directive (ES5 14.1). 1197 // Check "use strict" directive (ES5 14.1).
1195 if (!top_scope_->is_strict_mode() && 1198 if (top_scope_->is_classic_mode() &&
1196 directive->Equals(isolate()->heap()->use_strict()) && 1199 directive->Equals(isolate()->heap()->use_strict()) &&
1197 token_loc.end_pos - token_loc.beg_pos == 1200 token_loc.end_pos - token_loc.beg_pos ==
1198 isolate()->heap()->use_strict()->length() + 2) { 1201 isolate()->heap()->use_strict()->length() + 2) {
1199 top_scope_->SetStrictModeFlag(kStrictMode); 1202 top_scope_->SetLanguageMode(harmony_scoping_
1203 ? EXTENDED_MODE : STRICT_MODE);
1200 // "use strict" is the only directive for now. 1204 // "use strict" is the only directive for now.
1201 directive_prologue = false; 1205 directive_prologue = false;
1202 } 1206 }
1203 } else { 1207 } else {
1204 // End of the directive prologue. 1208 // End of the directive prologue.
1205 directive_prologue = false; 1209 directive_prologue = false;
1206 } 1210 }
1207 } 1211 }
1208 1212
1209 block_finder.Update(stat); 1213 block_finder.Update(stat);
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
1327 } 1331 }
1328 1332
1329 case Token::FUNCTION: { 1333 case Token::FUNCTION: {
1330 // FunctionDeclaration is only allowed in the context of SourceElements 1334 // FunctionDeclaration is only allowed in the context of SourceElements
1331 // (Ecma 262 5th Edition, clause 14): 1335 // (Ecma 262 5th Edition, clause 14):
1332 // SourceElement: 1336 // SourceElement:
1333 // Statement 1337 // Statement
1334 // FunctionDeclaration 1338 // FunctionDeclaration
1335 // Common language extension is to allow function declaration in place 1339 // Common language extension is to allow function declaration in place
1336 // of any statement. This language extension is disabled in strict mode. 1340 // of any statement. This language extension is disabled in strict mode.
1337 if (top_scope_->is_strict_mode() || harmony_scoping_) { 1341 if (!top_scope_->is_classic_mode()) {
1338 ReportMessageAt(scanner().peek_location(), "strict_function", 1342 ReportMessageAt(scanner().peek_location(), "strict_function",
1339 Vector<const char*>::empty()); 1343 Vector<const char*>::empty());
1340 *ok = false; 1344 *ok = false;
1341 return NULL; 1345 return NULL;
1342 } 1346 }
1343 return ParseFunctionDeclaration(ok); 1347 return ParseFunctionDeclaration(ok);
1344 } 1348 }
1345 1349
1346 case Token::DEBUGGER: 1350 case Token::DEBUGGER:
1347 stmt = ParseDebuggerStatement(ok); 1351 stmt = ParseDebuggerStatement(ok);
(...skipping 27 matching lines...) Expand all
1375 // variable and also set its mode. In any case, a Declaration node 1379 // variable and also set its mode. In any case, a Declaration node
1376 // will be added to the scope so that the declaration can be added 1380 // will be added to the scope so that the declaration can be added
1377 // to the corresponding activation frame at runtime if necessary. 1381 // to the corresponding activation frame at runtime if necessary.
1378 // For instance declarations inside an eval scope need to be added 1382 // For instance declarations inside an eval scope need to be added
1379 // to the calling function context. 1383 // to the calling function context.
1380 // Similarly, strict mode eval scope does not leak variable declarations to 1384 // Similarly, strict mode eval scope does not leak variable declarations to
1381 // the caller's scope so we declare all locals, too. 1385 // the caller's scope so we declare all locals, too.
1382 // Also for block scoped let/const bindings the variable can be 1386 // Also for block scoped let/const bindings the variable can be
1383 // statically declared. 1387 // statically declared.
1384 if (declaration_scope->is_function_scope() || 1388 if (declaration_scope->is_function_scope() ||
1385 declaration_scope->is_strict_mode_eval_scope() || 1389 declaration_scope->is_strict_or_extended_eval_scope() ||
1386 declaration_scope->is_block_scope()) { 1390 declaration_scope->is_block_scope()) {
1387 // Declare the variable in the function scope. 1391 // Declare the variable in the function scope.
1388 var = declaration_scope->LocalLookup(name); 1392 var = declaration_scope->LocalLookup(name);
1389 if (var == NULL) { 1393 if (var == NULL) {
1390 // Declare the name. 1394 // Declare the name.
1391 InitializationFlag init_flag = (fun != NULL || mode == VAR) 1395 InitializationFlag init_flag = (fun != NULL || mode == VAR)
1392 ? kCreatedInitialized : kNeedsInitialization; 1396 ? kCreatedInitialized : kNeedsInitialization;
1393 var = declaration_scope->DeclareLocal(name, mode, init_flag); 1397 var = declaration_scope->DeclareLocal(name, mode, init_flag);
1394 } else { 1398 } else {
1395 // The name was declared in this scope before; check for conflicting 1399 // The name was declared in this scope before; check for conflicting
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
1567 // Even if we're not at the top-level of the global or a function 1571 // Even if we're not at the top-level of the global or a function
1568 // scope, we treat is as such and introduce the function with it's 1572 // scope, we treat is as such and introduce the function with it's
1569 // initial value upon entering the corresponding scope. 1573 // initial value upon entering the corresponding scope.
1570 VariableMode mode = harmony_scoping_ ? LET : VAR; 1574 VariableMode mode = harmony_scoping_ ? LET : VAR;
1571 Declare(name, mode, fun, true, CHECK_OK); 1575 Declare(name, mode, fun, true, CHECK_OK);
1572 return EmptyStatement(); 1576 return EmptyStatement();
1573 } 1577 }
1574 1578
1575 1579
1576 Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) { 1580 Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) {
1577 if (harmony_scoping_) return ParseScopedBlock(labels, ok); 1581 if (top_scope_->is_extended_mode()) return ParseScopedBlock(labels, ok);
1578 1582
1579 // Block :: 1583 // Block ::
1580 // '{' Statement* '}' 1584 // '{' Statement* '}'
1581 1585
1582 // Note that a Block does not introduce a new execution scope! 1586 // Note that a Block does not introduce a new execution scope!
1583 // (ECMA-262, 3rd, 12.2) 1587 // (ECMA-262, 3rd, 12.2)
1584 // 1588 //
1585 // Construct block expecting 16 statements. 1589 // Construct block expecting 16 statements.
1586 Block* result = new(zone()) Block(isolate(), labels, 16, false); 1590 Block* result = new(zone()) Block(isolate(), labels, 16, false);
1587 Target target(&this->target_stack_, result); 1591 Target target(&this->target_stack_, result);
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
1683 // bindings are created uninitialized by their declaration nodes and 1687 // bindings are created uninitialized by their declaration nodes and
1684 // need initialization. 'var' declared bindings are always initialized 1688 // need initialization. 'var' declared bindings are always initialized
1685 // immediately by their declaration nodes. 1689 // immediately by their declaration nodes.
1686 bool needs_init = false; 1690 bool needs_init = false;
1687 bool is_const = false; 1691 bool is_const = false;
1688 Token::Value init_op = Token::INIT_VAR; 1692 Token::Value init_op = Token::INIT_VAR;
1689 if (peek() == Token::VAR) { 1693 if (peek() == Token::VAR) {
1690 Consume(Token::VAR); 1694 Consume(Token::VAR);
1691 } else if (peek() == Token::CONST) { 1695 } else if (peek() == Token::CONST) {
1692 Consume(Token::CONST); 1696 Consume(Token::CONST);
1693 if (harmony_scoping_) { 1697 switch (top_scope_->language_mode()) {
1694 if (var_context != kSourceElement && 1698 case CLASSIC_MODE:
1695 var_context != kForStatement) { 1699 mode = CONST;
1696 // In harmony mode 'const' declarations are only allowed in source 1700 init_op = Token::INIT_CONST;
1697 // element positions. 1701 break;
1698 ReportMessage("unprotected_const", Vector<const char*>::empty()); 1702 case STRICT_MODE:
1703 ReportMessage("strict_const", Vector<const char*>::empty());
1699 *ok = false; 1704 *ok = false;
1700 return NULL; 1705 return NULL;
1701 } 1706 case EXTENDED_MODE:
1702 mode = CONST_HARMONY; 1707 if (var_context != kSourceElement &&
1703 init_op = Token::INIT_CONST_HARMONY; 1708 var_context != kForStatement) {
1704 } else if (top_scope_->is_strict_mode()) { 1709 // In extended mode 'const' declarations are only allowed in source
1705 ReportMessage("strict_const", Vector<const char*>::empty()); 1710 // element positions.
1706 *ok = false; 1711 ReportMessage("unprotected_const", Vector<const char*>::empty());
1707 return NULL; 1712 *ok = false;
1708 } else { 1713 return NULL;
1709 mode = CONST; 1714 }
1710 init_op = Token::INIT_CONST; 1715 mode = CONST_HARMONY;
1716 init_op = Token::INIT_CONST_HARMONY;
1711 } 1717 }
1712 is_const = true; 1718 is_const = true;
1713 needs_init = true; 1719 needs_init = true;
1714 } else if (peek() == Token::LET) { 1720 } else if (peek() == Token::LET) {
1721 ASSERT(top_scope_->is_extended_mode());
1715 Consume(Token::LET); 1722 Consume(Token::LET);
1716 if (var_context != kSourceElement && 1723 if (var_context != kSourceElement &&
1717 var_context != kForStatement) { 1724 var_context != kForStatement) {
1718 // Let declarations are only allowed in source element positions. 1725 // Let declarations are only allowed in source element positions.
1719 ASSERT(var_context == kStatement); 1726 ASSERT(var_context == kStatement);
1720 ReportMessage("unprotected_let", Vector<const char*>::empty()); 1727 ReportMessage("unprotected_let", Vector<const char*>::empty());
1721 *ok = false; 1728 *ok = false;
1722 return NULL; 1729 return NULL;
1723 } 1730 }
1724 mode = LET; 1731 mode = LET;
(...skipping 23 matching lines...) Expand all
1748 Handle<String> name; 1755 Handle<String> name;
1749 do { 1756 do {
1750 if (fni_ != NULL) fni_->Enter(); 1757 if (fni_ != NULL) fni_->Enter();
1751 1758
1752 // Parse variable name. 1759 // Parse variable name.
1753 if (nvars > 0) Consume(Token::COMMA); 1760 if (nvars > 0) Consume(Token::COMMA);
1754 name = ParseIdentifier(CHECK_OK); 1761 name = ParseIdentifier(CHECK_OK);
1755 if (fni_ != NULL) fni_->PushVariableName(name); 1762 if (fni_ != NULL) fni_->PushVariableName(name);
1756 1763
1757 // Strict mode variables may not be named eval or arguments 1764 // Strict mode variables may not be named eval or arguments
1758 if (declaration_scope->is_strict_mode() && IsEvalOrArguments(name)) { 1765 if (!declaration_scope->is_classic_mode() && IsEvalOrArguments(name)) {
1759 ReportMessage("strict_var_name", Vector<const char*>::empty()); 1766 ReportMessage("strict_var_name", Vector<const char*>::empty());
1760 *ok = false; 1767 *ok = false;
1761 return NULL; 1768 return NULL;
1762 } 1769 }
1763 1770
1764 // Declare variable. 1771 // Declare variable.
1765 // Note that we *always* must treat the initial value via a separate init 1772 // Note that we *always* must treat the initial value via a separate init
1766 // assignment for variables and constants because the value must be assigned 1773 // assignment for variables and constants because the value must be assigned
1767 // when the variable is encountered in the source. But the variable/constant 1774 // when the variable is encountered in the source. But the variable/constant
1768 // is declared (and set to 'undefined') upon entering the function within 1775 // is declared (and set to 'undefined') upon entering the function within
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
1877 // the number of arguments (1 or 2). 1884 // the number of arguments (1 or 2).
1878 initialize = 1885 initialize =
1879 new(zone()) CallRuntime( 1886 new(zone()) CallRuntime(
1880 isolate(), 1887 isolate(),
1881 isolate()->factory()->InitializeConstGlobal_symbol(), 1888 isolate()->factory()->InitializeConstGlobal_symbol(),
1882 Runtime::FunctionForId(Runtime::kInitializeConstGlobal), 1889 Runtime::FunctionForId(Runtime::kInitializeConstGlobal),
1883 arguments); 1890 arguments);
1884 } else { 1891 } else {
1885 // Add strict mode. 1892 // Add strict mode.
1886 // We may want to pass singleton to avoid Literal allocations. 1893 // We may want to pass singleton to avoid Literal allocations.
1887 StrictModeFlag flag = initialization_scope->strict_mode_flag(); 1894 LanguageMode language_mode = initialization_scope->language_mode();
1888 arguments->Add(NewNumberLiteral(flag)); 1895 arguments->Add(NewNumberLiteral(language_mode));
1889 1896
1890 // Be careful not to assign a value to the global variable if 1897 // Be careful not to assign a value to the global variable if
1891 // we're in a with. The initialization value should not 1898 // we're in a with. The initialization value should not
1892 // necessarily be stored in the global object in that case, 1899 // necessarily be stored in the global object in that case,
1893 // which is why we need to generate a separate assignment node. 1900 // which is why we need to generate a separate assignment node.
1894 if (value != NULL && !inside_with()) { 1901 if (value != NULL && !inside_with()) {
1895 arguments->Add(value); 1902 arguments->Add(value);
1896 value = NULL; // zap the value to avoid the unnecessary assignment 1903 value = NULL; // zap the value to avoid the unnecessary assignment
1897 } 1904 }
1898 1905
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
2134 return new(zone()) ReturnStatement(expr); 2141 return new(zone()) ReturnStatement(expr);
2135 } 2142 }
2136 2143
2137 2144
2138 Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) { 2145 Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) {
2139 // WithStatement :: 2146 // WithStatement ::
2140 // 'with' '(' Expression ')' Statement 2147 // 'with' '(' Expression ')' Statement
2141 2148
2142 Expect(Token::WITH, CHECK_OK); 2149 Expect(Token::WITH, CHECK_OK);
2143 2150
2144 if (top_scope_->is_strict_mode()) { 2151 if (!top_scope_->is_classic_mode()) {
2145 ReportMessage("strict_mode_with", Vector<const char*>::empty()); 2152 ReportMessage("strict_mode_with", Vector<const char*>::empty());
2146 *ok = false; 2153 *ok = false;
2147 return NULL; 2154 return NULL;
2148 } 2155 }
2149 2156
2150 Expect(Token::LPAREN, CHECK_OK); 2157 Expect(Token::LPAREN, CHECK_OK);
2151 Expression* expr = ParseExpression(true, CHECK_OK); 2158 Expression* expr = ParseExpression(true, CHECK_OK);
2152 Expect(Token::RPAREN, CHECK_OK); 2159 Expect(Token::RPAREN, CHECK_OK);
2153 2160
2154 top_scope_->DeclarationScope()->RecordWithStatement(); 2161 top_scope_->DeclarationScope()->RecordWithStatement();
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
2280 Block* catch_block = NULL; 2287 Block* catch_block = NULL;
2281 Handle<String> name; 2288 Handle<String> name;
2282 if (tok == Token::CATCH) { 2289 if (tok == Token::CATCH) {
2283 Consume(Token::CATCH); 2290 Consume(Token::CATCH);
2284 2291
2285 Expect(Token::LPAREN, CHECK_OK); 2292 Expect(Token::LPAREN, CHECK_OK);
2286 catch_scope = NewScope(top_scope_, CATCH_SCOPE); 2293 catch_scope = NewScope(top_scope_, CATCH_SCOPE);
2287 catch_scope->set_start_position(scanner().location().beg_pos); 2294 catch_scope->set_start_position(scanner().location().beg_pos);
2288 name = ParseIdentifier(CHECK_OK); 2295 name = ParseIdentifier(CHECK_OK);
2289 2296
2290 if (top_scope_->is_strict_mode() && IsEvalOrArguments(name)) { 2297 if (!top_scope_->is_classic_mode() && IsEvalOrArguments(name)) {
2291 ReportMessage("strict_catch_variable", Vector<const char*>::empty()); 2298 ReportMessage("strict_catch_variable", Vector<const char*>::empty());
2292 *ok = false; 2299 *ok = false;
2293 return NULL; 2300 return NULL;
2294 } 2301 }
2295 2302
2296 Expect(Token::RPAREN, CHECK_OK); 2303 Expect(Token::RPAREN, CHECK_OK);
2297 2304
2298 if (peek() == Token::LBRACE) { 2305 if (peek() == Token::LBRACE) {
2299 Target target(&this->target_stack_, &catch_collector); 2306 Target target(&this->target_stack_, &catch_collector);
2300 VariableMode mode = harmony_scoping_ ? LET : VAR; 2307 VariableMode mode = harmony_scoping_ ? LET : VAR;
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after
2631 // Signal a reference error if the expression is an invalid left-hand 2638 // Signal a reference error if the expression is an invalid left-hand
2632 // side expression. We could report this as a syntax error here but 2639 // side expression. We could report this as a syntax error here but
2633 // for compatibility with JSC we choose to report the error at 2640 // for compatibility with JSC we choose to report the error at
2634 // runtime. 2641 // runtime.
2635 if (expression == NULL || !expression->IsValidLeftHandSide()) { 2642 if (expression == NULL || !expression->IsValidLeftHandSide()) {
2636 Handle<String> type = 2643 Handle<String> type =
2637 isolate()->factory()->invalid_lhs_in_assignment_symbol(); 2644 isolate()->factory()->invalid_lhs_in_assignment_symbol();
2638 expression = NewThrowReferenceError(type); 2645 expression = NewThrowReferenceError(type);
2639 } 2646 }
2640 2647
2641 if (top_scope_->is_strict_mode()) { 2648 if (!top_scope_->is_classic_mode()) {
2642 // Assignment to eval or arguments is disallowed in strict mode. 2649 // Assignment to eval or arguments is disallowed in strict mode.
2643 CheckStrictModeLValue(expression, "strict_lhs_assignment", CHECK_OK); 2650 CheckStrictModeLValue(expression, "strict_lhs_assignment", CHECK_OK);
2644 } 2651 }
2645 2652
2646 Token::Value op = Next(); // Get assignment operator. 2653 Token::Value op = Next(); // Get assignment operator.
2647 int pos = scanner().location().beg_pos; 2654 int pos = scanner().location().beg_pos;
2648 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); 2655 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK);
2649 2656
2650 // TODO(1231235): We try to estimate the set of properties set by 2657 // TODO(1231235): We try to estimate the set of properties set by
2651 // constructors. We define a new property whenever there is an 2658 // constructors. We define a new property whenever there is an
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
2840 return NewNumberLiteral(-value); 2847 return NewNumberLiteral(-value);
2841 case Token::BIT_NOT: 2848 case Token::BIT_NOT:
2842 return NewNumberLiteral(~DoubleToInt32(value)); 2849 return NewNumberLiteral(~DoubleToInt32(value));
2843 default: 2850 default:
2844 break; 2851 break;
2845 } 2852 }
2846 } 2853 }
2847 } 2854 }
2848 2855
2849 // "delete identifier" is a syntax error in strict mode. 2856 // "delete identifier" is a syntax error in strict mode.
2850 if (op == Token::DELETE && top_scope_->is_strict_mode()) { 2857 if (op == Token::DELETE && !top_scope_->is_classic_mode()) {
2851 VariableProxy* operand = expression->AsVariableProxy(); 2858 VariableProxy* operand = expression->AsVariableProxy();
2852 if (operand != NULL && !operand->is_this()) { 2859 if (operand != NULL && !operand->is_this()) {
2853 ReportMessage("strict_delete", Vector<const char*>::empty()); 2860 ReportMessage("strict_delete", Vector<const char*>::empty());
2854 *ok = false; 2861 *ok = false;
2855 return NULL; 2862 return NULL;
2856 } 2863 }
2857 } 2864 }
2858 2865
2859 return new(zone()) UnaryOperation(isolate(), op, expression, position); 2866 return new(zone()) UnaryOperation(isolate(), op, expression, position);
2860 2867
2861 } else if (Token::IsCountOp(op)) { 2868 } else if (Token::IsCountOp(op)) {
2862 op = Next(); 2869 op = Next();
2863 Expression* expression = ParseUnaryExpression(CHECK_OK); 2870 Expression* expression = ParseUnaryExpression(CHECK_OK);
2864 // Signal a reference error if the expression is an invalid 2871 // Signal a reference error if the expression is an invalid
2865 // left-hand side expression. We could report this as a syntax 2872 // left-hand side expression. We could report this as a syntax
2866 // error here but for compatibility with JSC we choose to report the 2873 // error here but for compatibility with JSC we choose to report the
2867 // error at runtime. 2874 // error at runtime.
2868 if (expression == NULL || !expression->IsValidLeftHandSide()) { 2875 if (expression == NULL || !expression->IsValidLeftHandSide()) {
2869 Handle<String> type = 2876 Handle<String> type =
2870 isolate()->factory()->invalid_lhs_in_prefix_op_symbol(); 2877 isolate()->factory()->invalid_lhs_in_prefix_op_symbol();
2871 expression = NewThrowReferenceError(type); 2878 expression = NewThrowReferenceError(type);
2872 } 2879 }
2873 2880
2874 if (top_scope_->is_strict_mode()) { 2881 if (!top_scope_->is_classic_mode()) {
2875 // Prefix expression operand in strict mode may not be eval or arguments. 2882 // Prefix expression operand in strict mode may not be eval or arguments.
2876 CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK); 2883 CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK);
2877 } 2884 }
2878 2885
2879 int position = scanner().location().beg_pos; 2886 int position = scanner().location().beg_pos;
2880 return new(zone()) CountOperation(isolate(), 2887 return new(zone()) CountOperation(isolate(),
2881 op, 2888 op,
2882 true /* prefix */, 2889 true /* prefix */,
2883 expression, 2890 expression,
2884 position); 2891 position);
(...skipping 14 matching lines...) Expand all
2899 // Signal a reference error if the expression is an invalid 2906 // Signal a reference error if the expression is an invalid
2900 // left-hand side expression. We could report this as a syntax 2907 // left-hand side expression. We could report this as a syntax
2901 // error here but for compatibility with JSC we choose to report the 2908 // error here but for compatibility with JSC we choose to report the
2902 // error at runtime. 2909 // error at runtime.
2903 if (expression == NULL || !expression->IsValidLeftHandSide()) { 2910 if (expression == NULL || !expression->IsValidLeftHandSide()) {
2904 Handle<String> type = 2911 Handle<String> type =
2905 isolate()->factory()->invalid_lhs_in_postfix_op_symbol(); 2912 isolate()->factory()->invalid_lhs_in_postfix_op_symbol();
2906 expression = NewThrowReferenceError(type); 2913 expression = NewThrowReferenceError(type);
2907 } 2914 }
2908 2915
2909 if (top_scope_->is_strict_mode()) { 2916 if (!top_scope_->is_classic_mode()) {
2910 // Postfix expression operand in strict mode may not be eval or arguments. 2917 // Postfix expression operand in strict mode may not be eval or arguments.
2911 CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK); 2918 CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK);
2912 } 2919 }
2913 2920
2914 Token::Value next = Next(); 2921 Token::Value next = Next();
2915 int position = scanner().location().beg_pos; 2922 int position = scanner().location().beg_pos;
2916 expression = 2923 expression =
2917 new(zone()) CountOperation(isolate(), 2924 new(zone()) CountOperation(isolate(),
2918 next, 2925 next,
2919 false /* postfix */, 2926 false /* postfix */,
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
3130 case Token::STRING: 3137 case Token::STRING:
3131 return ReportMessage("unexpected_token_string", 3138 return ReportMessage("unexpected_token_string",
3132 Vector<const char*>::empty()); 3139 Vector<const char*>::empty());
3133 case Token::IDENTIFIER: 3140 case Token::IDENTIFIER:
3134 return ReportMessage("unexpected_token_identifier", 3141 return ReportMessage("unexpected_token_identifier",
3135 Vector<const char*>::empty()); 3142 Vector<const char*>::empty());
3136 case Token::FUTURE_RESERVED_WORD: 3143 case Token::FUTURE_RESERVED_WORD:
3137 return ReportMessage("unexpected_reserved", 3144 return ReportMessage("unexpected_reserved",
3138 Vector<const char*>::empty()); 3145 Vector<const char*>::empty());
3139 case Token::FUTURE_STRICT_RESERVED_WORD: 3146 case Token::FUTURE_STRICT_RESERVED_WORD:
3140 return ReportMessage(top_scope_->is_strict_mode() ? 3147 return ReportMessage(top_scope_->is_classic_mode() ?
3141 "unexpected_strict_reserved" : 3148 "unexpected_token_identifier" :
3142 "unexpected_token_identifier", 3149 "unexpected_strict_reserved",
3143 Vector<const char*>::empty()); 3150 Vector<const char*>::empty());
3144 default: 3151 default:
3145 const char* name = Token::String(token); 3152 const char* name = Token::String(token);
3146 ASSERT(name != NULL); 3153 ASSERT(name != NULL);
3147 ReportMessage("unexpected_token", Vector<const char*>(&name, 1)); 3154 ReportMessage("unexpected_token", Vector<const char*>(&name, 1));
3148 } 3155 }
3149 } 3156 }
3150 3157
3151 3158
3152 void Parser::ReportInvalidPreparseData(Handle<String> name, bool* ok) { 3159 void Parser::ReportInvalidPreparseData(Handle<String> name, bool* ok) {
(...skipping 545 matching lines...) Expand 10 before | Expand all | Expand 10 after
3698 // '{' ( 3705 // '{' (
3699 // ((IdentifierName | String | Number) ':' AssignmentExpression) 3706 // ((IdentifierName | String | Number) ':' AssignmentExpression)
3700 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) 3707 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral)
3701 // )*[','] '}' 3708 // )*[','] '}'
3702 3709
3703 ZoneList<ObjectLiteral::Property*>* properties = 3710 ZoneList<ObjectLiteral::Property*>* properties =
3704 new(zone()) ZoneList<ObjectLiteral::Property*>(4); 3711 new(zone()) ZoneList<ObjectLiteral::Property*>(4);
3705 int number_of_boilerplate_properties = 0; 3712 int number_of_boilerplate_properties = 0;
3706 bool has_function = false; 3713 bool has_function = false;
3707 3714
3708 ObjectLiteralPropertyChecker checker(this, top_scope_->is_strict_mode()); 3715 ObjectLiteralPropertyChecker checker(
3716 this, !top_scope_->is_classic_mode());
Rico 2011/11/15 08:25:07 How about just having the mode in the class, every
Steven 2011/11/15 13:33:30 Done.
3709 3717
3710 Expect(Token::LBRACE, CHECK_OK); 3718 Expect(Token::LBRACE, CHECK_OK);
3711 3719
3712 while (peek() != Token::RBRACE) { 3720 while (peek() != Token::RBRACE) {
3713 if (fni_ != NULL) fni_->Enter(); 3721 if (fni_ != NULL) fni_->Enter();
3714 3722
3715 Literal* key = NULL; 3723 Literal* key = NULL;
3716 Token::Value next = peek(); 3724 Token::Value next = peek();
3717 3725
3718 // Location of the property name token 3726 // Location of the property name token
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after
4004 if (scope->end_position() <= function_block_pos) { 4012 if (scope->end_position() <= function_block_pos) {
4005 // End position greater than end of stream is safe, and hard to check. 4013 // End position greater than end of stream is safe, and hard to check.
4006 ReportInvalidPreparseData(function_name, CHECK_OK); 4014 ReportInvalidPreparseData(function_name, CHECK_OK);
4007 } 4015 }
4008 isolate()->counters()->total_preparse_skipped()->Increment( 4016 isolate()->counters()->total_preparse_skipped()->Increment(
4009 scope->end_position() - function_block_pos); 4017 scope->end_position() - function_block_pos);
4010 // Seek to position just before terminal '}'. 4018 // Seek to position just before terminal '}'.
4011 scanner().SeekForward(scope->end_position() - 1); 4019 scanner().SeekForward(scope->end_position() - 1);
4012 materialized_literal_count = entry.literal_count(); 4020 materialized_literal_count = entry.literal_count();
4013 expected_property_count = entry.property_count(); 4021 expected_property_count = entry.property_count();
4014 top_scope_->SetStrictModeFlag(entry.strict_mode_flag()); 4022 top_scope_->SetLanguageMode(entry.language_mode());
4015 only_simple_this_property_assignments = false; 4023 only_simple_this_property_assignments = false;
4016 this_property_assignments = isolate()->factory()->empty_fixed_array(); 4024 this_property_assignments = isolate()->factory()->empty_fixed_array();
4017 Expect(Token::RBRACE, CHECK_OK); 4025 Expect(Token::RBRACE, CHECK_OK);
4018 } 4026 }
4019 } 4027 }
4020 4028
4021 if (!is_lazily_compiled) { 4029 if (!is_lazily_compiled) {
4022 body = new(zone()) ZoneList<Statement*>(8); 4030 body = new(zone()) ZoneList<Statement*>(8);
4023 if (fvar != NULL) { 4031 if (fvar != NULL) {
4024 VariableProxy* fproxy = top_scope_->NewUnresolved(function_name); 4032 VariableProxy* fproxy = top_scope_->NewUnresolved(function_name);
(...skipping 12 matching lines...) Expand all
4037 handler_count = function_state.handler_count(); 4045 handler_count = function_state.handler_count();
4038 only_simple_this_property_assignments = 4046 only_simple_this_property_assignments =
4039 function_state.only_simple_this_property_assignments(); 4047 function_state.only_simple_this_property_assignments();
4040 this_property_assignments = function_state.this_property_assignments(); 4048 this_property_assignments = function_state.this_property_assignments();
4041 4049
4042 Expect(Token::RBRACE, CHECK_OK); 4050 Expect(Token::RBRACE, CHECK_OK);
4043 scope->set_end_position(scanner().location().end_pos); 4051 scope->set_end_position(scanner().location().end_pos);
4044 } 4052 }
4045 4053
4046 // Validate strict mode. 4054 // Validate strict mode.
4047 if (top_scope_->is_strict_mode()) { 4055 if (!top_scope_->is_classic_mode()) {
4048 if (IsEvalOrArguments(function_name)) { 4056 if (IsEvalOrArguments(function_name)) {
4049 int start_pos = scope->start_position(); 4057 int start_pos = scope->start_position();
4050 int position = function_token_position != RelocInfo::kNoPosition 4058 int position = function_token_position != RelocInfo::kNoPosition
4051 ? function_token_position 4059 ? function_token_position
4052 : (start_pos > 0 ? start_pos - 1 : start_pos); 4060 : (start_pos > 0 ? start_pos - 1 : start_pos);
4053 Scanner::Location location = Scanner::Location(position, start_pos); 4061 Scanner::Location location = Scanner::Location(position, start_pos);
4054 ReportMessageAt(location, 4062 ReportMessageAt(location,
4055 "strict_function_name", Vector<const char*>::empty()); 4063 "strict_function_name", Vector<const char*>::empty());
4056 *ok = false; 4064 *ok = false;
4057 return NULL; 4065 return NULL;
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
4223 4231
4224 4232
4225 Literal* Parser::GetLiteralNumber(double value) { 4233 Literal* Parser::GetLiteralNumber(double value) {
4226 return NewNumberLiteral(value); 4234 return NewNumberLiteral(value);
4227 } 4235 }
4228 4236
4229 4237
4230 // Parses an identifier that is valid for the current scope, in particular it 4238 // Parses an identifier that is valid for the current scope, in particular it
4231 // fails on strict mode future reserved keywords in a strict scope. 4239 // fails on strict mode future reserved keywords in a strict scope.
4232 Handle<String> Parser::ParseIdentifier(bool* ok) { 4240 Handle<String> Parser::ParseIdentifier(bool* ok) {
4233 if (top_scope_->is_strict_mode()) { 4241 if (!top_scope_->is_classic_mode()) {
4234 Expect(Token::IDENTIFIER, ok); 4242 Expect(Token::IDENTIFIER, ok);
4235 } else if (!Check(Token::IDENTIFIER)) { 4243 } else if (!Check(Token::IDENTIFIER)) {
4236 Expect(Token::FUTURE_STRICT_RESERVED_WORD, ok); 4244 Expect(Token::FUTURE_STRICT_RESERVED_WORD, ok);
4237 } 4245 }
4238 if (!*ok) return Handle<String>(); 4246 if (!*ok) return Handle<String>();
4239 return GetSymbol(ok); 4247 return GetSymbol(ok);
4240 } 4248 }
4241 4249
4242 4250
4243 // Parses and identifier or a strict mode future reserved word, and indicate 4251 // Parses and identifier or a strict mode future reserved word, and indicate
(...skipping 22 matching lines...) Expand all
4266 } 4274 }
4267 return GetSymbol(ok); 4275 return GetSymbol(ok);
4268 } 4276 }
4269 4277
4270 4278
4271 // Checks LHS expression for assignment and prefix/postfix increment/decrement 4279 // Checks LHS expression for assignment and prefix/postfix increment/decrement
4272 // in strict mode. 4280 // in strict mode.
4273 void Parser::CheckStrictModeLValue(Expression* expression, 4281 void Parser::CheckStrictModeLValue(Expression* expression,
4274 const char* error, 4282 const char* error,
4275 bool* ok) { 4283 bool* ok) {
4276 ASSERT(top_scope_->is_strict_mode()); 4284 ASSERT(!top_scope_->is_classic_mode());
4277 VariableProxy* lhs = expression != NULL 4285 VariableProxy* lhs = expression != NULL
4278 ? expression->AsVariableProxy() 4286 ? expression->AsVariableProxy()
4279 : NULL; 4287 : NULL;
4280 4288
4281 if (lhs != NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) { 4289 if (lhs != NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) {
4282 ReportMessage(error, Vector<const char*>::empty()); 4290 ReportMessage(error, Vector<const char*>::empty());
4283 *ok = false; 4291 *ok = false;
4284 } 4292 }
4285 } 4293 }
4286 4294
(...skipping 1142 matching lines...) Expand 10 before | Expand all | Expand 10 after
5429 DeleteArray(message); 5437 DeleteArray(message);
5430 for (int i = 0; i < args.length(); i++) { 5438 for (int i = 0; i < args.length(); i++) {
5431 DeleteArray(args[i]); 5439 DeleteArray(args[i]);
5432 } 5440 }
5433 DeleteArray(args.start()); 5441 DeleteArray(args.start());
5434 ASSERT(info->isolate()->has_pending_exception()); 5442 ASSERT(info->isolate()->has_pending_exception());
5435 } else { 5443 } else {
5436 Handle<String> source = Handle<String>(String::cast(script->source())); 5444 Handle<String> source = Handle<String>(String::cast(script->source()));
5437 result = parser.ParseProgram(source, 5445 result = parser.ParseProgram(source,
5438 info->is_global(), 5446 info->is_global(),
5439 info->strict_mode_flag()); 5447 info->language_mode());
5440 } 5448 }
5441 } 5449 }
5442 info->SetFunction(result); 5450 info->SetFunction(result);
5443 return (result != NULL); 5451 return (result != NULL);
5444 } 5452 }
5445 5453
5446 } } // namespace v8::internal 5454 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698