OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3478 } | 3485 } |
3479 | 3486 |
3480 // Defined in ast.cc | 3487 // Defined in ast.cc |
3481 bool IsEqualString(void* first, void* second); | 3488 bool IsEqualString(void* first, void* second); |
3482 bool IsEqualNumber(void* first, void* second); | 3489 bool IsEqualNumber(void* first, void* second); |
3483 | 3490 |
3484 | 3491 |
3485 // Validation per 11.1.5 Object Initialiser | 3492 // Validation per 11.1.5 Object Initialiser |
3486 class ObjectLiteralPropertyChecker { | 3493 class ObjectLiteralPropertyChecker { |
3487 public: | 3494 public: |
3488 ObjectLiteralPropertyChecker(Parser* parser, bool strict) : | 3495 ObjectLiteralPropertyChecker(Parser* parser, LanguageMode language_mode) : |
3489 props(&IsEqualString), | 3496 props(&IsEqualString), |
3490 elems(&IsEqualNumber), | 3497 elems(&IsEqualNumber), |
3491 parser_(parser), | 3498 parser_(parser), |
3492 strict_(strict) { | 3499 language_mode_(language_mode) { |
3493 } | 3500 } |
3494 | 3501 |
3495 void CheckProperty( | 3502 void CheckProperty( |
3496 ObjectLiteral::Property* property, | 3503 ObjectLiteral::Property* property, |
3497 Scanner::Location loc, | 3504 Scanner::Location loc, |
3498 bool* ok); | 3505 bool* ok); |
3499 | 3506 |
3500 private: | 3507 private: |
3501 enum PropertyKind { | 3508 enum PropertyKind { |
3502 kGetAccessor = 0x01, | 3509 kGetAccessor = 0x01, |
3503 kSetAccessor = 0x02, | 3510 kSetAccessor = 0x02, |
3504 kAccessor = kGetAccessor | kSetAccessor, | 3511 kAccessor = kGetAccessor | kSetAccessor, |
3505 kData = 0x04 | 3512 kData = 0x04 |
3506 }; | 3513 }; |
3507 | 3514 |
3508 static intptr_t GetPropertyKind(ObjectLiteral::Property* property) { | 3515 static intptr_t GetPropertyKind(ObjectLiteral::Property* property) { |
3509 switch (property->kind()) { | 3516 switch (property->kind()) { |
3510 case ObjectLiteral::Property::GETTER: | 3517 case ObjectLiteral::Property::GETTER: |
3511 return kGetAccessor; | 3518 return kGetAccessor; |
3512 case ObjectLiteral::Property::SETTER: | 3519 case ObjectLiteral::Property::SETTER: |
3513 return kSetAccessor; | 3520 return kSetAccessor; |
3514 default: | 3521 default: |
3515 return kData; | 3522 return kData; |
3516 } | 3523 } |
3517 } | 3524 } |
3518 | 3525 |
3519 HashMap props; | 3526 HashMap props; |
3520 HashMap elems; | 3527 HashMap elems; |
3521 Parser* parser_; | 3528 Parser* parser_; |
3522 bool strict_; | 3529 LanguageMode language_mode_; |
3523 }; | 3530 }; |
3524 | 3531 |
3525 | 3532 |
3526 void ObjectLiteralPropertyChecker::CheckProperty( | 3533 void ObjectLiteralPropertyChecker::CheckProperty( |
3527 ObjectLiteral::Property* property, | 3534 ObjectLiteral::Property* property, |
3528 Scanner::Location loc, | 3535 Scanner::Location loc, |
3529 bool* ok) { | 3536 bool* ok) { |
3530 | 3537 |
3531 ASSERT(property != NULL); | 3538 ASSERT(property != NULL); |
3532 | 3539 |
(...skipping 28 matching lines...) Expand all Loading... |
3561 key = name.location(); | 3568 key = name.location(); |
3562 hash = name->Hash(); | 3569 hash = name->Hash(); |
3563 map = &props; | 3570 map = &props; |
3564 } | 3571 } |
3565 | 3572 |
3566 // Lookup property previously defined, if any. | 3573 // Lookup property previously defined, if any. |
3567 HashMap::Entry* entry = map->Lookup(key, hash, true); | 3574 HashMap::Entry* entry = map->Lookup(key, hash, true); |
3568 intptr_t prev = reinterpret_cast<intptr_t> (entry->value); | 3575 intptr_t prev = reinterpret_cast<intptr_t> (entry->value); |
3569 intptr_t curr = GetPropertyKind(property); | 3576 intptr_t curr = GetPropertyKind(property); |
3570 | 3577 |
3571 // Duplicate data properties are illegal in strict mode. | 3578 // Duplicate data properties are illegal in strict or extended mode. |
3572 if (strict_ && (curr & prev & kData) != 0) { | 3579 if (language_mode_ != CLASSIC_MODE && (curr & prev & kData) != 0) { |
3573 parser_->ReportMessageAt(loc, "strict_duplicate_property", | 3580 parser_->ReportMessageAt(loc, "strict_duplicate_property", |
3574 Vector<const char*>::empty()); | 3581 Vector<const char*>::empty()); |
3575 *ok = false; | 3582 *ok = false; |
3576 return; | 3583 return; |
3577 } | 3584 } |
3578 // Data property conflicting with an accessor. | 3585 // Data property conflicting with an accessor. |
3579 if (((curr & kData) && (prev & kAccessor)) || | 3586 if (((curr & kData) && (prev & kAccessor)) || |
3580 ((prev & kData) && (curr & kAccessor))) { | 3587 ((prev & kData) && (curr & kAccessor))) { |
3581 parser_->ReportMessageAt(loc, "accessor_data_property", | 3588 parser_->ReportMessageAt(loc, "accessor_data_property", |
3582 Vector<const char*>::empty()); | 3589 Vector<const char*>::empty()); |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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(this, top_scope_->language_mode()); |
3709 | 3716 |
3710 Expect(Token::LBRACE, CHECK_OK); | 3717 Expect(Token::LBRACE, CHECK_OK); |
3711 | 3718 |
3712 while (peek() != Token::RBRACE) { | 3719 while (peek() != Token::RBRACE) { |
3713 if (fni_ != NULL) fni_->Enter(); | 3720 if (fni_ != NULL) fni_->Enter(); |
3714 | 3721 |
3715 Literal* key = NULL; | 3722 Literal* key = NULL; |
3716 Token::Value next = peek(); | 3723 Token::Value next = peek(); |
3717 | 3724 |
3718 // Location of the property name token | 3725 // Location of the property name token |
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4004 if (scope->end_position() <= function_block_pos) { | 4011 if (scope->end_position() <= function_block_pos) { |
4005 // End position greater than end of stream is safe, and hard to check. | 4012 // End position greater than end of stream is safe, and hard to check. |
4006 ReportInvalidPreparseData(function_name, CHECK_OK); | 4013 ReportInvalidPreparseData(function_name, CHECK_OK); |
4007 } | 4014 } |
4008 isolate()->counters()->total_preparse_skipped()->Increment( | 4015 isolate()->counters()->total_preparse_skipped()->Increment( |
4009 scope->end_position() - function_block_pos); | 4016 scope->end_position() - function_block_pos); |
4010 // Seek to position just before terminal '}'. | 4017 // Seek to position just before terminal '}'. |
4011 scanner().SeekForward(scope->end_position() - 1); | 4018 scanner().SeekForward(scope->end_position() - 1); |
4012 materialized_literal_count = entry.literal_count(); | 4019 materialized_literal_count = entry.literal_count(); |
4013 expected_property_count = entry.property_count(); | 4020 expected_property_count = entry.property_count(); |
4014 top_scope_->SetStrictModeFlag(entry.strict_mode_flag()); | 4021 top_scope_->SetLanguageMode(entry.language_mode()); |
4015 only_simple_this_property_assignments = false; | 4022 only_simple_this_property_assignments = false; |
4016 this_property_assignments = isolate()->factory()->empty_fixed_array(); | 4023 this_property_assignments = isolate()->factory()->empty_fixed_array(); |
4017 Expect(Token::RBRACE, CHECK_OK); | 4024 Expect(Token::RBRACE, CHECK_OK); |
4018 } | 4025 } |
4019 } | 4026 } |
4020 | 4027 |
4021 if (!is_lazily_compiled) { | 4028 if (!is_lazily_compiled) { |
4022 body = new(zone()) ZoneList<Statement*>(8); | 4029 body = new(zone()) ZoneList<Statement*>(8); |
4023 if (fvar != NULL) { | 4030 if (fvar != NULL) { |
4024 VariableProxy* fproxy = top_scope_->NewUnresolved(function_name); | 4031 VariableProxy* fproxy = top_scope_->NewUnresolved(function_name); |
(...skipping 12 matching lines...) Expand all Loading... |
4037 handler_count = function_state.handler_count(); | 4044 handler_count = function_state.handler_count(); |
4038 only_simple_this_property_assignments = | 4045 only_simple_this_property_assignments = |
4039 function_state.only_simple_this_property_assignments(); | 4046 function_state.only_simple_this_property_assignments(); |
4040 this_property_assignments = function_state.this_property_assignments(); | 4047 this_property_assignments = function_state.this_property_assignments(); |
4041 | 4048 |
4042 Expect(Token::RBRACE, CHECK_OK); | 4049 Expect(Token::RBRACE, CHECK_OK); |
4043 scope->set_end_position(scanner().location().end_pos); | 4050 scope->set_end_position(scanner().location().end_pos); |
4044 } | 4051 } |
4045 | 4052 |
4046 // Validate strict mode. | 4053 // Validate strict mode. |
4047 if (top_scope_->is_strict_mode()) { | 4054 if (!top_scope_->is_classic_mode()) { |
4048 if (IsEvalOrArguments(function_name)) { | 4055 if (IsEvalOrArguments(function_name)) { |
4049 int start_pos = scope->start_position(); | 4056 int start_pos = scope->start_position(); |
4050 int position = function_token_position != RelocInfo::kNoPosition | 4057 int position = function_token_position != RelocInfo::kNoPosition |
4051 ? function_token_position | 4058 ? function_token_position |
4052 : (start_pos > 0 ? start_pos - 1 : start_pos); | 4059 : (start_pos > 0 ? start_pos - 1 : start_pos); |
4053 Scanner::Location location = Scanner::Location(position, start_pos); | 4060 Scanner::Location location = Scanner::Location(position, start_pos); |
4054 ReportMessageAt(location, | 4061 ReportMessageAt(location, |
4055 "strict_function_name", Vector<const char*>::empty()); | 4062 "strict_function_name", Vector<const char*>::empty()); |
4056 *ok = false; | 4063 *ok = false; |
4057 return NULL; | 4064 return NULL; |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4223 | 4230 |
4224 | 4231 |
4225 Literal* Parser::GetLiteralNumber(double value) { | 4232 Literal* Parser::GetLiteralNumber(double value) { |
4226 return NewNumberLiteral(value); | 4233 return NewNumberLiteral(value); |
4227 } | 4234 } |
4228 | 4235 |
4229 | 4236 |
4230 // Parses an identifier that is valid for the current scope, in particular it | 4237 // 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. | 4238 // fails on strict mode future reserved keywords in a strict scope. |
4232 Handle<String> Parser::ParseIdentifier(bool* ok) { | 4239 Handle<String> Parser::ParseIdentifier(bool* ok) { |
4233 if (top_scope_->is_strict_mode()) { | 4240 if (!top_scope_->is_classic_mode()) { |
4234 Expect(Token::IDENTIFIER, ok); | 4241 Expect(Token::IDENTIFIER, ok); |
4235 } else if (!Check(Token::IDENTIFIER)) { | 4242 } else if (!Check(Token::IDENTIFIER)) { |
4236 Expect(Token::FUTURE_STRICT_RESERVED_WORD, ok); | 4243 Expect(Token::FUTURE_STRICT_RESERVED_WORD, ok); |
4237 } | 4244 } |
4238 if (!*ok) return Handle<String>(); | 4245 if (!*ok) return Handle<String>(); |
4239 return GetSymbol(ok); | 4246 return GetSymbol(ok); |
4240 } | 4247 } |
4241 | 4248 |
4242 | 4249 |
4243 // Parses and identifier or a strict mode future reserved word, and indicate | 4250 // Parses and identifier or a strict mode future reserved word, and indicate |
(...skipping 22 matching lines...) Expand all Loading... |
4266 } | 4273 } |
4267 return GetSymbol(ok); | 4274 return GetSymbol(ok); |
4268 } | 4275 } |
4269 | 4276 |
4270 | 4277 |
4271 // Checks LHS expression for assignment and prefix/postfix increment/decrement | 4278 // Checks LHS expression for assignment and prefix/postfix increment/decrement |
4272 // in strict mode. | 4279 // in strict mode. |
4273 void Parser::CheckStrictModeLValue(Expression* expression, | 4280 void Parser::CheckStrictModeLValue(Expression* expression, |
4274 const char* error, | 4281 const char* error, |
4275 bool* ok) { | 4282 bool* ok) { |
4276 ASSERT(top_scope_->is_strict_mode()); | 4283 ASSERT(!top_scope_->is_classic_mode()); |
4277 VariableProxy* lhs = expression != NULL | 4284 VariableProxy* lhs = expression != NULL |
4278 ? expression->AsVariableProxy() | 4285 ? expression->AsVariableProxy() |
4279 : NULL; | 4286 : NULL; |
4280 | 4287 |
4281 if (lhs != NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) { | 4288 if (lhs != NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) { |
4282 ReportMessage(error, Vector<const char*>::empty()); | 4289 ReportMessage(error, Vector<const char*>::empty()); |
4283 *ok = false; | 4290 *ok = false; |
4284 } | 4291 } |
4285 } | 4292 } |
4286 | 4293 |
(...skipping 1142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5429 DeleteArray(message); | 5436 DeleteArray(message); |
5430 for (int i = 0; i < args.length(); i++) { | 5437 for (int i = 0; i < args.length(); i++) { |
5431 DeleteArray(args[i]); | 5438 DeleteArray(args[i]); |
5432 } | 5439 } |
5433 DeleteArray(args.start()); | 5440 DeleteArray(args.start()); |
5434 ASSERT(info->isolate()->has_pending_exception()); | 5441 ASSERT(info->isolate()->has_pending_exception()); |
5435 } else { | 5442 } else { |
5436 Handle<String> source = Handle<String>(String::cast(script->source())); | 5443 Handle<String> source = Handle<String>(String::cast(script->source())); |
5437 result = parser.ParseProgram(source, | 5444 result = parser.ParseProgram(source, |
5438 info->is_global(), | 5445 info->is_global(), |
5439 info->strict_mode_flag()); | 5446 info->language_mode()); |
5440 } | 5447 } |
5441 } | 5448 } |
5442 info->SetFunction(result); | 5449 info->SetFunction(result); |
5443 return (result != NULL); | 5450 return (result != NULL); |
5444 } | 5451 } |
5445 | 5452 |
5446 } } // namespace v8::internal | 5453 } } // namespace v8::internal |
OLD | NEW |