| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 515 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 526 | 526 |
| 527 #define CHECK_FAILED /**/); \ | 527 #define CHECK_FAILED /**/); \ |
| 528 if (failed_) return NULL; \ | 528 if (failed_) return NULL; \ |
| 529 ((void)0 | 529 ((void)0 |
| 530 #define DUMMY ) // to make indentation work | 530 #define DUMMY ) // to make indentation work |
| 531 #undef DUMMY | 531 #undef DUMMY |
| 532 | 532 |
| 533 // ---------------------------------------------------------------------------- | 533 // ---------------------------------------------------------------------------- |
| 534 // Implementation of Parser | 534 // Implementation of Parser |
| 535 | 535 |
| 536 bool ParserTraits::is_classic_mode() const { |
| 537 return parser_->top_scope_->is_classic_mode(); |
| 538 } |
| 539 |
| 540 |
| 541 bool ParserTraits::is_generator() const { |
| 542 return parser_->current_function_state_->is_generator(); |
| 543 } |
| 544 |
| 545 |
| 546 bool ParserTraits::IsEvalOrArguments(Handle<String> identifier) const { |
| 547 return identifier.is_identical_to( |
| 548 parser_->isolate()->factory()->eval_string()) || |
| 549 identifier.is_identical_to( |
| 550 parser_->isolate()->factory()->arguments_string()); |
| 551 } |
| 552 |
| 553 |
| 554 int ParserTraits::NextMaterializedLiteralIndex() { |
| 555 return parser_->current_function_state_->NextMaterializedLiteralIndex(); |
| 556 } |
| 557 |
| 558 |
| 559 void ParserTraits::ReportMessageAt(Scanner::Location source_location, |
| 560 const char* message, |
| 561 Vector<const char*> args) { |
| 562 MessageLocation location(parser_->script_, |
| 563 source_location.beg_pos, |
| 564 source_location.end_pos); |
| 565 Factory* factory = parser_->isolate()->factory(); |
| 566 Handle<FixedArray> elements = factory->NewFixedArray(args.length()); |
| 567 for (int i = 0; i < args.length(); i++) { |
| 568 Handle<String> arg_string = factory->NewStringFromUtf8(CStrVector(args[i])); |
| 569 elements->set(i, *arg_string); |
| 570 } |
| 571 Handle<JSArray> array = factory->NewJSArrayWithElements(elements); |
| 572 Handle<Object> result = factory->NewSyntaxError(message, array); |
| 573 parser_->isolate()->Throw(*result, &location); |
| 574 } |
| 575 |
| 576 |
| 577 void ParserTraits::ReportMessage(const char* message, |
| 578 Vector<Handle<String> > args) { |
| 579 Scanner::Location source_location = parser_->scanner().location(); |
| 580 ReportMessageAt(source_location, message, args); |
| 581 } |
| 582 |
| 583 |
| 584 void ParserTraits::ReportMessageAt(Scanner::Location source_location, |
| 585 const char* message, |
| 586 Vector<Handle<String> > args) { |
| 587 MessageLocation location(parser_->script_, |
| 588 source_location.beg_pos, |
| 589 source_location.end_pos); |
| 590 Factory* factory = parser_->isolate()->factory(); |
| 591 Handle<FixedArray> elements = factory->NewFixedArray(args.length()); |
| 592 for (int i = 0; i < args.length(); i++) { |
| 593 elements->set(i, *args[i]); |
| 594 } |
| 595 Handle<JSArray> array = factory->NewJSArrayWithElements(elements); |
| 596 Handle<Object> result = factory->NewSyntaxError(message, array); |
| 597 parser_->isolate()->Throw(*result, &location); |
| 598 } |
| 599 |
| 600 |
| 601 Handle<String> ParserTraits::GetSymbol() { |
| 602 int symbol_id = -1; |
| 603 if (parser_->pre_parse_data() != NULL) { |
| 604 symbol_id = parser_->pre_parse_data()->GetSymbolIdentifier(); |
| 605 } |
| 606 return parser_->LookupSymbol(symbol_id); |
| 607 } |
| 608 |
| 609 |
| 610 Handle<String> ParserTraits::NextLiteralString(PretenureFlag tenured) { |
| 611 Scanner& scanner = parser_->scanner(); |
| 612 if (scanner.is_next_literal_ascii()) { |
| 613 return parser_->isolate_->factory()->NewStringFromAscii( |
| 614 scanner.next_literal_ascii_string(), tenured); |
| 615 } else { |
| 616 return parser_->isolate_->factory()->NewStringFromTwoByte( |
| 617 scanner.next_literal_utf16_string(), tenured); |
| 618 } |
| 619 } |
| 620 |
| 621 |
| 622 Expression* ParserTraits::NewRegExpLiteral(Handle<String> js_pattern, |
| 623 Handle<String> js_flags, |
| 624 int literal_index, |
| 625 int pos) { |
| 626 return parser_->factory()->NewRegExpLiteral( |
| 627 js_pattern, js_flags, literal_index, pos); |
| 628 } |
| 629 |
| 536 Parser::Parser(CompilationInfo* info) | 630 Parser::Parser(CompilationInfo* info) |
| 537 : ParserBase(&scanner_, info->isolate()->stack_guard()->real_climit()), | 631 : ParserBase<ParserTraits>(&scanner_, |
| 632 info->isolate()->stack_guard()->real_climit(), |
| 633 this), |
| 538 isolate_(info->isolate()), | 634 isolate_(info->isolate()), |
| 539 symbol_cache_(0, info->zone()), | 635 symbol_cache_(0, info->zone()), |
| 540 script_(info->script()), | 636 script_(info->script()), |
| 541 scanner_(isolate_->unicode_cache()), | 637 scanner_(isolate_->unicode_cache()), |
| 542 reusable_preparser_(NULL), | 638 reusable_preparser_(NULL), |
| 543 top_scope_(NULL), | 639 top_scope_(NULL), |
| 544 original_scope_(NULL), | 640 original_scope_(NULL), |
| 545 current_function_state_(NULL), | 641 current_function_state_(NULL), |
| 546 target_stack_(NULL), | 642 target_stack_(NULL), |
| 547 extension_(info->extension()), | 643 extension_(info->extension()), |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 677 function_state.expected_property_count(), | 773 function_state.expected_property_count(), |
| 678 function_state.handler_count(), | 774 function_state.handler_count(), |
| 679 0, | 775 0, |
| 680 FunctionLiteral::kNoDuplicateParameters, | 776 FunctionLiteral::kNoDuplicateParameters, |
| 681 FunctionLiteral::ANONYMOUS_EXPRESSION, | 777 FunctionLiteral::ANONYMOUS_EXPRESSION, |
| 682 FunctionLiteral::kGlobalOrEval, | 778 FunctionLiteral::kGlobalOrEval, |
| 683 FunctionLiteral::kNotParenthesized, | 779 FunctionLiteral::kNotParenthesized, |
| 684 FunctionLiteral::kNotGenerator, | 780 FunctionLiteral::kNotGenerator, |
| 685 0); | 781 0); |
| 686 result->set_ast_properties(factory()->visitor()->ast_properties()); | 782 result->set_ast_properties(factory()->visitor()->ast_properties()); |
| 783 result->set_slot_processor(factory()->visitor()->slot_processor()); |
| 687 result->set_dont_optimize_reason( | 784 result->set_dont_optimize_reason( |
| 688 factory()->visitor()->dont_optimize_reason()); | 785 factory()->visitor()->dont_optimize_reason()); |
| 689 } else if (stack_overflow()) { | 786 } else if (stack_overflow()) { |
| 690 isolate()->StackOverflow(); | 787 isolate()->StackOverflow(); |
| 691 } | 788 } |
| 692 } | 789 } |
| 693 | 790 |
| 694 // Make sure the target stack is empty. | 791 // Make sure the target stack is empty. |
| 695 ASSERT(target_stack_ == NULL); | 792 ASSERT(target_stack_ == NULL); |
| 696 | 793 |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 786 if (result == NULL) { | 883 if (result == NULL) { |
| 787 if (stack_overflow()) isolate()->StackOverflow(); | 884 if (stack_overflow()) isolate()->StackOverflow(); |
| 788 } else { | 885 } else { |
| 789 Handle<String> inferred_name(shared_info->inferred_name()); | 886 Handle<String> inferred_name(shared_info->inferred_name()); |
| 790 result->set_inferred_name(inferred_name); | 887 result->set_inferred_name(inferred_name); |
| 791 } | 888 } |
| 792 return result; | 889 return result; |
| 793 } | 890 } |
| 794 | 891 |
| 795 | 892 |
| 796 Handle<String> Parser::GetSymbol() { | |
| 797 int symbol_id = -1; | |
| 798 if (pre_parse_data() != NULL) { | |
| 799 symbol_id = pre_parse_data()->GetSymbolIdentifier(); | |
| 800 } | |
| 801 return LookupSymbol(symbol_id); | |
| 802 } | |
| 803 | |
| 804 | |
| 805 void Parser::ReportMessage(const char* message, Vector<const char*> args) { | |
| 806 Scanner::Location source_location = scanner().location(); | |
| 807 ReportMessageAt(source_location, message, args); | |
| 808 } | |
| 809 | |
| 810 | |
| 811 void Parser::ReportMessage(const char* message, Vector<Handle<String> > args) { | |
| 812 Scanner::Location source_location = scanner().location(); | |
| 813 ReportMessageAt(source_location, message, args); | |
| 814 } | |
| 815 | |
| 816 | |
| 817 void Parser::ReportMessageAt(Scanner::Location source_location, | |
| 818 const char* message, | |
| 819 Vector<const char*> args) { | |
| 820 MessageLocation location(script_, | |
| 821 source_location.beg_pos, | |
| 822 source_location.end_pos); | |
| 823 Factory* factory = isolate()->factory(); | |
| 824 Handle<FixedArray> elements = factory->NewFixedArray(args.length()); | |
| 825 for (int i = 0; i < args.length(); i++) { | |
| 826 Handle<String> arg_string = factory->NewStringFromUtf8(CStrVector(args[i])); | |
| 827 elements->set(i, *arg_string); | |
| 828 } | |
| 829 Handle<JSArray> array = factory->NewJSArrayWithElements(elements); | |
| 830 Handle<Object> result = factory->NewSyntaxError(message, array); | |
| 831 isolate()->Throw(*result, &location); | |
| 832 } | |
| 833 | |
| 834 | |
| 835 void Parser::ReportMessageAt(Scanner::Location source_location, | |
| 836 const char* message, | |
| 837 Vector<Handle<String> > args) { | |
| 838 MessageLocation location(script_, | |
| 839 source_location.beg_pos, | |
| 840 source_location.end_pos); | |
| 841 Factory* factory = isolate()->factory(); | |
| 842 Handle<FixedArray> elements = factory->NewFixedArray(args.length()); | |
| 843 for (int i = 0; i < args.length(); i++) { | |
| 844 elements->set(i, *args[i]); | |
| 845 } | |
| 846 Handle<JSArray> array = factory->NewJSArrayWithElements(elements); | |
| 847 Handle<Object> result = factory->NewSyntaxError(message, array); | |
| 848 isolate()->Throw(*result, &location); | |
| 849 } | |
| 850 | |
| 851 | |
| 852 void* Parser::ParseSourceElements(ZoneList<Statement*>* processor, | 893 void* Parser::ParseSourceElements(ZoneList<Statement*>* processor, |
| 853 int end_token, | 894 int end_token, |
| 854 bool is_eval, | 895 bool is_eval, |
| 855 bool is_global, | 896 bool is_global, |
| 856 bool* ok) { | 897 bool* ok) { |
| 857 // SourceElements :: | 898 // SourceElements :: |
| 858 // (ModuleElement)* <end_token> | 899 // (ModuleElement)* <end_token> |
| 859 | 900 |
| 860 // Allocate a target stack to use for this set of source | 901 // Allocate a target stack to use for this set of source |
| 861 // elements. This way, all scripts and functions get their own | 902 // elements. This way, all scripts and functions get their own |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1074 Expect(Token::RBRACE, CHECK_OK); | 1115 Expect(Token::RBRACE, CHECK_OK); |
| 1075 scope->set_end_position(scanner().location().end_pos); | 1116 scope->set_end_position(scanner().location().end_pos); |
| 1076 body->set_scope(scope); | 1117 body->set_scope(scope); |
| 1077 | 1118 |
| 1078 // Check that all exports are bound. | 1119 // Check that all exports are bound. |
| 1079 Interface* interface = scope->interface(); | 1120 Interface* interface = scope->interface(); |
| 1080 for (Interface::Iterator it = interface->iterator(); | 1121 for (Interface::Iterator it = interface->iterator(); |
| 1081 !it.done(); it.Advance()) { | 1122 !it.done(); it.Advance()) { |
| 1082 if (scope->LocalLookup(it.name()) == NULL) { | 1123 if (scope->LocalLookup(it.name()) == NULL) { |
| 1083 Handle<String> name(it.name()); | 1124 Handle<String> name(it.name()); |
| 1084 ReportMessage("module_export_undefined", | 1125 ParserTraits::ReportMessage("module_export_undefined", |
| 1085 Vector<Handle<String> >(&name, 1)); | 1126 Vector<Handle<String> >(&name, 1)); |
| 1086 *ok = false; | 1127 *ok = false; |
| 1087 return NULL; | 1128 return NULL; |
| 1088 } | 1129 } |
| 1089 } | 1130 } |
| 1090 | 1131 |
| 1091 interface->MakeModule(ok); | 1132 interface->MakeModule(ok); |
| 1092 ASSERT(*ok); | 1133 ASSERT(*ok); |
| 1093 interface->Freeze(ok); | 1134 interface->Freeze(ok); |
| 1094 ASSERT(*ok); | 1135 ASSERT(*ok); |
| 1095 return factory()->NewModuleLiteral(body, interface, pos); | 1136 return factory()->NewModuleLiteral(body, interface, pos); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1114 if (!*ok) { | 1155 if (!*ok) { |
| 1115 #ifdef DEBUG | 1156 #ifdef DEBUG |
| 1116 if (FLAG_print_interfaces) { | 1157 if (FLAG_print_interfaces) { |
| 1117 PrintF("PATH TYPE ERROR at '%s'\n", name->ToAsciiArray()); | 1158 PrintF("PATH TYPE ERROR at '%s'\n", name->ToAsciiArray()); |
| 1118 PrintF("result: "); | 1159 PrintF("result: "); |
| 1119 result->interface()->Print(); | 1160 result->interface()->Print(); |
| 1120 PrintF("member: "); | 1161 PrintF("member: "); |
| 1121 member->interface()->Print(); | 1162 member->interface()->Print(); |
| 1122 } | 1163 } |
| 1123 #endif | 1164 #endif |
| 1124 ReportMessage("invalid_module_path", Vector<Handle<String> >(&name, 1)); | 1165 ParserTraits::ReportMessage("invalid_module_path", |
| 1166 Vector<Handle<String> >(&name, 1)); |
| 1125 return NULL; | 1167 return NULL; |
| 1126 } | 1168 } |
| 1127 result = member; | 1169 result = member; |
| 1128 } | 1170 } |
| 1129 | 1171 |
| 1130 return result; | 1172 return result; |
| 1131 } | 1173 } |
| 1132 | 1174 |
| 1133 | 1175 |
| 1134 Module* Parser::ParseModuleVariable(bool* ok) { | 1176 Module* Parser::ParseModuleVariable(bool* ok) { |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1224 Interface* interface = Interface::NewUnknown(zone()); | 1266 Interface* interface = Interface::NewUnknown(zone()); |
| 1225 module->interface()->Add(names[i], interface, zone(), ok); | 1267 module->interface()->Add(names[i], interface, zone(), ok); |
| 1226 if (!*ok) { | 1268 if (!*ok) { |
| 1227 #ifdef DEBUG | 1269 #ifdef DEBUG |
| 1228 if (FLAG_print_interfaces) { | 1270 if (FLAG_print_interfaces) { |
| 1229 PrintF("IMPORT TYPE ERROR at '%s'\n", names[i]->ToAsciiArray()); | 1271 PrintF("IMPORT TYPE ERROR at '%s'\n", names[i]->ToAsciiArray()); |
| 1230 PrintF("module: "); | 1272 PrintF("module: "); |
| 1231 module->interface()->Print(); | 1273 module->interface()->Print(); |
| 1232 } | 1274 } |
| 1233 #endif | 1275 #endif |
| 1234 ReportMessage("invalid_module_path", Vector<Handle<String> >(&name, 1)); | 1276 ParserTraits::ReportMessage("invalid_module_path", |
| 1277 Vector<Handle<String> >(&name, 1)); |
| 1235 return NULL; | 1278 return NULL; |
| 1236 } | 1279 } |
| 1237 VariableProxy* proxy = NewUnresolved(names[i], LET, interface); | 1280 VariableProxy* proxy = NewUnresolved(names[i], LET, interface); |
| 1238 Declaration* declaration = | 1281 Declaration* declaration = |
| 1239 factory()->NewImportDeclaration(proxy, module, top_scope_, pos); | 1282 factory()->NewImportDeclaration(proxy, module, top_scope_, pos); |
| 1240 Declare(declaration, true, CHECK_OK); | 1283 Declare(declaration, true, CHECK_OK); |
| 1241 } | 1284 } |
| 1242 | 1285 |
| 1243 return block; | 1286 return block; |
| 1244 } | 1287 } |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1432 // SourceElement: | 1475 // SourceElement: |
| 1433 // Statement | 1476 // Statement |
| 1434 // FunctionDeclaration | 1477 // FunctionDeclaration |
| 1435 // Common language extension is to allow function declaration in place | 1478 // Common language extension is to allow function declaration in place |
| 1436 // of any statement. This language extension is disabled in strict mode. | 1479 // of any statement. This language extension is disabled in strict mode. |
| 1437 // | 1480 // |
| 1438 // In Harmony mode, this case also handles the extension: | 1481 // In Harmony mode, this case also handles the extension: |
| 1439 // Statement: | 1482 // Statement: |
| 1440 // GeneratorDeclaration | 1483 // GeneratorDeclaration |
| 1441 if (!top_scope_->is_classic_mode()) { | 1484 if (!top_scope_->is_classic_mode()) { |
| 1442 ReportMessageAt(scanner().peek_location(), "strict_function", | 1485 ReportMessageAt(scanner().peek_location(), "strict_function"); |
| 1443 Vector<const char*>::empty()); | |
| 1444 *ok = false; | 1486 *ok = false; |
| 1445 return NULL; | 1487 return NULL; |
| 1446 } | 1488 } |
| 1447 return ParseFunctionDeclaration(NULL, ok); | 1489 return ParseFunctionDeclaration(NULL, ok); |
| 1448 } | 1490 } |
| 1449 | 1491 |
| 1450 case Token::DEBUGGER: | 1492 case Token::DEBUGGER: |
| 1451 return ParseDebuggerStatement(ok); | 1493 return ParseDebuggerStatement(ok); |
| 1452 | 1494 |
| 1453 default: | 1495 default: |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1612 if (!ok) { | 1654 if (!ok) { |
| 1613 #ifdef DEBUG | 1655 #ifdef DEBUG |
| 1614 if (FLAG_print_interfaces) { | 1656 if (FLAG_print_interfaces) { |
| 1615 PrintF("DECLARE TYPE ERROR\n"); | 1657 PrintF("DECLARE TYPE ERROR\n"); |
| 1616 PrintF("proxy: "); | 1658 PrintF("proxy: "); |
| 1617 proxy->interface()->Print(); | 1659 proxy->interface()->Print(); |
| 1618 PrintF("var: "); | 1660 PrintF("var: "); |
| 1619 var->interface()->Print(); | 1661 var->interface()->Print(); |
| 1620 } | 1662 } |
| 1621 #endif | 1663 #endif |
| 1622 ReportMessage("module_type_error", Vector<Handle<String> >(&name, 1)); | 1664 ParserTraits::ReportMessage("module_type_error", |
| 1665 Vector<Handle<String> >(&name, 1)); |
| 1623 } | 1666 } |
| 1624 } | 1667 } |
| 1625 } | 1668 } |
| 1626 } | 1669 } |
| 1627 | 1670 |
| 1628 | 1671 |
| 1629 // Language extension which is only enabled for source files loaded | 1672 // Language extension which is only enabled for source files loaded |
| 1630 // through the API's extension mechanism. A native function | 1673 // through the API's extension mechanism. A native function |
| 1631 // declaration is resolved by looking up the function through a | 1674 // declaration is resolved by looking up the function through a |
| 1632 // callback provided by the extension. | 1675 // callback provided by the extension. |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1770 // VariableDeclarations ';' | 1813 // VariableDeclarations ';' |
| 1771 | 1814 |
| 1772 Handle<String> ignore; | 1815 Handle<String> ignore; |
| 1773 Block* result = | 1816 Block* result = |
| 1774 ParseVariableDeclarations(var_context, NULL, names, &ignore, CHECK_OK); | 1817 ParseVariableDeclarations(var_context, NULL, names, &ignore, CHECK_OK); |
| 1775 ExpectSemicolon(CHECK_OK); | 1818 ExpectSemicolon(CHECK_OK); |
| 1776 return result; | 1819 return result; |
| 1777 } | 1820 } |
| 1778 | 1821 |
| 1779 | 1822 |
| 1780 bool Parser::IsEvalOrArguments(Handle<String> string) { | |
| 1781 return string.is_identical_to(isolate()->factory()->eval_string()) || | |
| 1782 string.is_identical_to(isolate()->factory()->arguments_string()); | |
| 1783 } | |
| 1784 | |
| 1785 | |
| 1786 // If the variable declaration declares exactly one non-const | 1823 // If the variable declaration declares exactly one non-const |
| 1787 // variable, then *out is set to that variable. In all other cases, | 1824 // variable, then *out is set to that variable. In all other cases, |
| 1788 // *out is untouched; in particular, it is the caller's responsibility | 1825 // *out is untouched; in particular, it is the caller's responsibility |
| 1789 // to initialize it properly. This mechanism is used for the parsing | 1826 // to initialize it properly. This mechanism is used for the parsing |
| 1790 // of 'for-in' loops. | 1827 // of 'for-in' loops. |
| 1791 Block* Parser::ParseVariableDeclarations( | 1828 Block* Parser::ParseVariableDeclarations( |
| 1792 VariableDeclarationContext var_context, | 1829 VariableDeclarationContext var_context, |
| 1793 VariableDeclarationProperties* decl_props, | 1830 VariableDeclarationProperties* decl_props, |
| 1794 ZoneStringList* names, | 1831 ZoneStringList* names, |
| 1795 Handle<String>* out, | 1832 Handle<String>* out, |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1921 // pre-resolve the proxy because it resides in the same scope as the | 1958 // pre-resolve the proxy because it resides in the same scope as the |
| 1922 // declaration. | 1959 // declaration. |
| 1923 Interface* interface = | 1960 Interface* interface = |
| 1924 is_const ? Interface::NewConst() : Interface::NewValue(); | 1961 is_const ? Interface::NewConst() : Interface::NewValue(); |
| 1925 VariableProxy* proxy = NewUnresolved(name, mode, interface); | 1962 VariableProxy* proxy = NewUnresolved(name, mode, interface); |
| 1926 Declaration* declaration = | 1963 Declaration* declaration = |
| 1927 factory()->NewVariableDeclaration(proxy, mode, top_scope_, pos); | 1964 factory()->NewVariableDeclaration(proxy, mode, top_scope_, pos); |
| 1928 Declare(declaration, mode != VAR, CHECK_OK); | 1965 Declare(declaration, mode != VAR, CHECK_OK); |
| 1929 nvars++; | 1966 nvars++; |
| 1930 if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) { | 1967 if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) { |
| 1931 ReportMessageAt(scanner().location(), "too_many_variables", | 1968 ReportMessageAt(scanner().location(), "too_many_variables"); |
| 1932 Vector<const char*>::empty()); | |
| 1933 *ok = false; | 1969 *ok = false; |
| 1934 return NULL; | 1970 return NULL; |
| 1935 } | 1971 } |
| 1936 if (names) names->Add(name, zone()); | 1972 if (names) names->Add(name, zone()); |
| 1937 | 1973 |
| 1938 // Parse initialization expression if present and/or needed. A | 1974 // Parse initialization expression if present and/or needed. A |
| 1939 // declaration of the form: | 1975 // declaration of the form: |
| 1940 // | 1976 // |
| 1941 // var v = x; | 1977 // var v = x; |
| 1942 // | 1978 // |
| (...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2225 IterationStatement* target = NULL; | 2261 IterationStatement* target = NULL; |
| 2226 target = LookupContinueTarget(label, CHECK_OK); | 2262 target = LookupContinueTarget(label, CHECK_OK); |
| 2227 if (target == NULL) { | 2263 if (target == NULL) { |
| 2228 // Illegal continue statement. | 2264 // Illegal continue statement. |
| 2229 const char* message = "illegal_continue"; | 2265 const char* message = "illegal_continue"; |
| 2230 Vector<Handle<String> > args; | 2266 Vector<Handle<String> > args; |
| 2231 if (!label.is_null()) { | 2267 if (!label.is_null()) { |
| 2232 message = "unknown_label"; | 2268 message = "unknown_label"; |
| 2233 args = Vector<Handle<String> >(&label, 1); | 2269 args = Vector<Handle<String> >(&label, 1); |
| 2234 } | 2270 } |
| 2235 ReportMessageAt(scanner().location(), message, args); | 2271 ParserTraits::ReportMessageAt(scanner().location(), message, args); |
| 2236 *ok = false; | 2272 *ok = false; |
| 2237 return NULL; | 2273 return NULL; |
| 2238 } | 2274 } |
| 2239 ExpectSemicolon(CHECK_OK); | 2275 ExpectSemicolon(CHECK_OK); |
| 2240 return factory()->NewContinueStatement(target, pos); | 2276 return factory()->NewContinueStatement(target, pos); |
| 2241 } | 2277 } |
| 2242 | 2278 |
| 2243 | 2279 |
| 2244 Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) { | 2280 Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) { |
| 2245 // BreakStatement :: | 2281 // BreakStatement :: |
| (...skipping 17 matching lines...) Expand all Loading... |
| 2263 BreakableStatement* target = NULL; | 2299 BreakableStatement* target = NULL; |
| 2264 target = LookupBreakTarget(label, CHECK_OK); | 2300 target = LookupBreakTarget(label, CHECK_OK); |
| 2265 if (target == NULL) { | 2301 if (target == NULL) { |
| 2266 // Illegal break statement. | 2302 // Illegal break statement. |
| 2267 const char* message = "illegal_break"; | 2303 const char* message = "illegal_break"; |
| 2268 Vector<Handle<String> > args; | 2304 Vector<Handle<String> > args; |
| 2269 if (!label.is_null()) { | 2305 if (!label.is_null()) { |
| 2270 message = "unknown_label"; | 2306 message = "unknown_label"; |
| 2271 args = Vector<Handle<String> >(&label, 1); | 2307 args = Vector<Handle<String> >(&label, 1); |
| 2272 } | 2308 } |
| 2273 ReportMessageAt(scanner().location(), message, args); | 2309 ParserTraits::ReportMessageAt(scanner().location(), message, args); |
| 2274 *ok = false; | 2310 *ok = false; |
| 2275 return NULL; | 2311 return NULL; |
| 2276 } | 2312 } |
| 2277 ExpectSemicolon(CHECK_OK); | 2313 ExpectSemicolon(CHECK_OK); |
| 2278 return factory()->NewBreakStatement(target, pos); | 2314 return factory()->NewBreakStatement(target, pos); |
| 2279 } | 2315 } |
| 2280 | 2316 |
| 2281 | 2317 |
| 2282 Statement* Parser::ParseReturnStatement(bool* ok) { | 2318 Statement* Parser::ParseReturnStatement(bool* ok) { |
| 2283 // ReturnStatement :: | 2319 // ReturnStatement :: |
| (...skipping 722 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3006 // In parsing the first assignment expression in conditional | 3042 // In parsing the first assignment expression in conditional |
| 3007 // expressions we always accept the 'in' keyword; see ECMA-262, | 3043 // expressions we always accept the 'in' keyword; see ECMA-262, |
| 3008 // section 11.12, page 58. | 3044 // section 11.12, page 58. |
| 3009 Expression* left = ParseAssignmentExpression(true, CHECK_OK); | 3045 Expression* left = ParseAssignmentExpression(true, CHECK_OK); |
| 3010 Expect(Token::COLON, CHECK_OK); | 3046 Expect(Token::COLON, CHECK_OK); |
| 3011 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); | 3047 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); |
| 3012 return factory()->NewConditional(expression, left, right, pos); | 3048 return factory()->NewConditional(expression, left, right, pos); |
| 3013 } | 3049 } |
| 3014 | 3050 |
| 3015 | 3051 |
| 3016 int ParserBase::Precedence(Token::Value tok, bool accept_IN) { | |
| 3017 if (tok == Token::IN && !accept_IN) | |
| 3018 return 0; // 0 precedence will terminate binary expression parsing | |
| 3019 | |
| 3020 return Token::Precedence(tok); | |
| 3021 } | |
| 3022 | |
| 3023 | |
| 3024 // Precedence >= 4 | 3052 // Precedence >= 4 |
| 3025 Expression* Parser::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) { | 3053 Expression* Parser::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) { |
| 3026 ASSERT(prec >= 4); | 3054 ASSERT(prec >= 4); |
| 3027 Expression* x = ParseUnaryExpression(CHECK_OK); | 3055 Expression* x = ParseUnaryExpression(CHECK_OK); |
| 3028 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { | 3056 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { |
| 3029 // prec1 >= 4 | 3057 // prec1 >= 4 |
| 3030 while (Precedence(peek(), accept_IN) == prec1) { | 3058 while (Precedence(peek(), accept_IN) == prec1) { |
| 3031 Token::Value op = Next(); | 3059 Token::Value op = Next(); |
| 3032 int pos = position(); | 3060 int pos = position(); |
| 3033 Expression* y = ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK); | 3061 Expression* y = ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK); |
| (...skipping 791 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3825 int literal_index = current_function_state_->NextMaterializedLiteralIndex(); | 3853 int literal_index = current_function_state_->NextMaterializedLiteralIndex(); |
| 3826 | 3854 |
| 3827 return factory()->NewObjectLiteral(properties, | 3855 return factory()->NewObjectLiteral(properties, |
| 3828 literal_index, | 3856 literal_index, |
| 3829 number_of_boilerplate_properties, | 3857 number_of_boilerplate_properties, |
| 3830 has_function, | 3858 has_function, |
| 3831 pos); | 3859 pos); |
| 3832 } | 3860 } |
| 3833 | 3861 |
| 3834 | 3862 |
| 3835 Expression* Parser::ParseRegExpLiteral(bool seen_equal, bool* ok) { | |
| 3836 int pos = peek_position(); | |
| 3837 if (!scanner().ScanRegExpPattern(seen_equal)) { | |
| 3838 Next(); | |
| 3839 ReportMessage("unterminated_regexp", Vector<const char*>::empty()); | |
| 3840 *ok = false; | |
| 3841 return NULL; | |
| 3842 } | |
| 3843 | |
| 3844 int literal_index = current_function_state_->NextMaterializedLiteralIndex(); | |
| 3845 | |
| 3846 Handle<String> js_pattern = NextLiteralString(TENURED); | |
| 3847 scanner().ScanRegExpFlags(); | |
| 3848 Handle<String> js_flags = NextLiteralString(TENURED); | |
| 3849 Next(); | |
| 3850 | |
| 3851 return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos); | |
| 3852 } | |
| 3853 | |
| 3854 | |
| 3855 ZoneList<Expression*>* Parser::ParseArguments(bool* ok) { | 3863 ZoneList<Expression*>* Parser::ParseArguments(bool* ok) { |
| 3856 // Arguments :: | 3864 // Arguments :: |
| 3857 // '(' (AssignmentExpression)*[','] ')' | 3865 // '(' (AssignmentExpression)*[','] ')' |
| 3858 | 3866 |
| 3859 ZoneList<Expression*>* result = new(zone()) ZoneList<Expression*>(4, zone()); | 3867 ZoneList<Expression*>* result = new(zone()) ZoneList<Expression*>(4, zone()); |
| 3860 Expect(Token::LPAREN, CHECK_OK); | 3868 Expect(Token::LPAREN, CHECK_OK); |
| 3861 bool done = (peek() == Token::RPAREN); | 3869 bool done = (peek() == Token::RPAREN); |
| 3862 while (!done) { | 3870 while (!done) { |
| 3863 Expression* argument = ParseAssignmentExpression(true, CHECK_OK); | 3871 Expression* argument = ParseAssignmentExpression(true, CHECK_OK); |
| 3864 result->Add(argument, zone()); | 3872 result->Add(argument, zone()); |
| 3865 if (result->length() > Code::kMaxArguments) { | 3873 if (result->length() > Code::kMaxArguments) { |
| 3866 ReportMessageAt(scanner().location(), "too_many_arguments", | 3874 ReportMessageAt(scanner().location(), "too_many_arguments"); |
| 3867 Vector<const char*>::empty()); | |
| 3868 *ok = false; | 3875 *ok = false; |
| 3869 return NULL; | 3876 return NULL; |
| 3870 } | 3877 } |
| 3871 done = (peek() == Token::RPAREN); | 3878 done = (peek() == Token::RPAREN); |
| 3872 if (!done) Expect(Token::COMMA, CHECK_OK); | 3879 if (!done) Expect(Token::COMMA, CHECK_OK); |
| 3873 } | 3880 } |
| 3874 Expect(Token::RPAREN, CHECK_OK); | 3881 Expect(Token::RPAREN, CHECK_OK); |
| 3875 return result; | 3882 return result; |
| 3876 } | 3883 } |
| 3877 | 3884 |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4034 int expected_property_count = -1; | 4041 int expected_property_count = -1; |
| 4035 int handler_count = 0; | 4042 int handler_count = 0; |
| 4036 FunctionLiteral::ParameterFlag duplicate_parameters = | 4043 FunctionLiteral::ParameterFlag duplicate_parameters = |
| 4037 FunctionLiteral::kNoDuplicateParameters; | 4044 FunctionLiteral::kNoDuplicateParameters; |
| 4038 FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_ | 4045 FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_ |
| 4039 ? FunctionLiteral::kIsParenthesized | 4046 ? FunctionLiteral::kIsParenthesized |
| 4040 : FunctionLiteral::kNotParenthesized; | 4047 : FunctionLiteral::kNotParenthesized; |
| 4041 FunctionLiteral::IsGeneratorFlag generator = is_generator | 4048 FunctionLiteral::IsGeneratorFlag generator = is_generator |
| 4042 ? FunctionLiteral::kIsGenerator | 4049 ? FunctionLiteral::kIsGenerator |
| 4043 : FunctionLiteral::kNotGenerator; | 4050 : FunctionLiteral::kNotGenerator; |
| 4051 DeferredFeedbackSlotProcessor* slot_processor; |
| 4044 AstProperties ast_properties; | 4052 AstProperties ast_properties; |
| 4045 BailoutReason dont_optimize_reason = kNoReason; | 4053 BailoutReason dont_optimize_reason = kNoReason; |
| 4046 // Parse function body. | 4054 // Parse function body. |
| 4047 { FunctionState function_state(this, scope); | 4055 { FunctionState function_state(this, scope); |
| 4048 top_scope_->SetScopeName(function_name); | 4056 top_scope_->SetScopeName(function_name); |
| 4049 | 4057 |
| 4050 if (is_generator) { | 4058 if (is_generator) { |
| 4051 // For generators, allocating variables in contexts is currently a win | 4059 // For generators, allocating variables in contexts is currently a win |
| 4052 // because it minimizes the work needed to suspend and resume an | 4060 // because it minimizes the work needed to suspend and resume an |
| 4053 // activation. | 4061 // activation. |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4088 reserved_loc = scanner().location(); | 4096 reserved_loc = scanner().location(); |
| 4089 } | 4097 } |
| 4090 if (!dupe_error_loc.IsValid() && top_scope_->IsDeclared(param_name)) { | 4098 if (!dupe_error_loc.IsValid() && top_scope_->IsDeclared(param_name)) { |
| 4091 duplicate_parameters = FunctionLiteral::kHasDuplicateParameters; | 4099 duplicate_parameters = FunctionLiteral::kHasDuplicateParameters; |
| 4092 dupe_error_loc = scanner().location(); | 4100 dupe_error_loc = scanner().location(); |
| 4093 } | 4101 } |
| 4094 | 4102 |
| 4095 top_scope_->DeclareParameter(param_name, VAR); | 4103 top_scope_->DeclareParameter(param_name, VAR); |
| 4096 num_parameters++; | 4104 num_parameters++; |
| 4097 if (num_parameters > Code::kMaxArguments) { | 4105 if (num_parameters > Code::kMaxArguments) { |
| 4098 ReportMessageAt(scanner().location(), "too_many_parameters", | 4106 ReportMessageAt(scanner().location(), "too_many_parameters"); |
| 4099 Vector<const char*>::empty()); | |
| 4100 *ok = false; | 4107 *ok = false; |
| 4101 return NULL; | 4108 return NULL; |
| 4102 } | 4109 } |
| 4103 done = (peek() == Token::RPAREN); | 4110 done = (peek() == Token::RPAREN); |
| 4104 if (!done) Expect(Token::COMMA, CHECK_OK); | 4111 if (!done) Expect(Token::COMMA, CHECK_OK); |
| 4105 } | 4112 } |
| 4106 Expect(Token::RPAREN, CHECK_OK); | 4113 Expect(Token::RPAREN, CHECK_OK); |
| 4107 | 4114 |
| 4108 Expect(Token::LBRACE, CHECK_OK); | 4115 Expect(Token::LBRACE, CHECK_OK); |
| 4109 | 4116 |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4180 set_stack_overflow(); | 4187 set_stack_overflow(); |
| 4181 *ok = false; | 4188 *ok = false; |
| 4182 return NULL; | 4189 return NULL; |
| 4183 } | 4190 } |
| 4184 if (logger.has_error()) { | 4191 if (logger.has_error()) { |
| 4185 const char* arg = logger.argument_opt(); | 4192 const char* arg = logger.argument_opt(); |
| 4186 Vector<const char*> args; | 4193 Vector<const char*> args; |
| 4187 if (arg != NULL) { | 4194 if (arg != NULL) { |
| 4188 args = Vector<const char*>(&arg, 1); | 4195 args = Vector<const char*>(&arg, 1); |
| 4189 } | 4196 } |
| 4190 ReportMessageAt(Scanner::Location(logger.start(), logger.end()), | 4197 ParserTraits::ReportMessageAt( |
| 4191 logger.message(), args); | 4198 Scanner::Location(logger.start(), logger.end()), |
| 4199 logger.message(), |
| 4200 args); |
| 4192 *ok = false; | 4201 *ok = false; |
| 4193 return NULL; | 4202 return NULL; |
| 4194 } | 4203 } |
| 4195 scope->set_end_position(logger.end()); | 4204 scope->set_end_position(logger.end()); |
| 4196 Expect(Token::RBRACE, CHECK_OK); | 4205 Expect(Token::RBRACE, CHECK_OK); |
| 4197 isolate()->counters()->total_preparse_skipped()->Increment( | 4206 isolate()->counters()->total_preparse_skipped()->Increment( |
| 4198 scope->end_position() - function_block_pos); | 4207 scope->end_position() - function_block_pos); |
| 4199 materialized_literal_count = logger.literals(); | 4208 materialized_literal_count = logger.literals(); |
| 4200 expected_property_count = logger.properties(); | 4209 expected_property_count = logger.properties(); |
| 4201 top_scope_->SetLanguageMode(logger.language_mode()); | 4210 top_scope_->SetLanguageMode(logger.language_mode()); |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4255 handler_count = function_state.handler_count(); | 4264 handler_count = function_state.handler_count(); |
| 4256 | 4265 |
| 4257 Expect(Token::RBRACE, CHECK_OK); | 4266 Expect(Token::RBRACE, CHECK_OK); |
| 4258 scope->set_end_position(scanner().location().end_pos); | 4267 scope->set_end_position(scanner().location().end_pos); |
| 4259 } | 4268 } |
| 4260 | 4269 |
| 4261 // Validate strict mode. We can do this only after parsing the function, | 4270 // Validate strict mode. We can do this only after parsing the function, |
| 4262 // since the function can declare itself strict. | 4271 // since the function can declare itself strict. |
| 4263 if (!top_scope_->is_classic_mode()) { | 4272 if (!top_scope_->is_classic_mode()) { |
| 4264 if (IsEvalOrArguments(function_name)) { | 4273 if (IsEvalOrArguments(function_name)) { |
| 4265 ReportMessageAt(function_name_location, | 4274 ReportMessageAt(function_name_location, "strict_eval_arguments"); |
| 4266 "strict_eval_arguments", | |
| 4267 Vector<const char*>::empty()); | |
| 4268 *ok = false; | 4275 *ok = false; |
| 4269 return NULL; | 4276 return NULL; |
| 4270 } | 4277 } |
| 4271 if (name_is_strict_reserved) { | 4278 if (name_is_strict_reserved) { |
| 4272 ReportMessageAt(function_name_location, "unexpected_strict_reserved", | 4279 ReportMessageAt(function_name_location, "unexpected_strict_reserved"); |
| 4273 Vector<const char*>::empty()); | |
| 4274 *ok = false; | 4280 *ok = false; |
| 4275 return NULL; | 4281 return NULL; |
| 4276 } | 4282 } |
| 4277 if (eval_args_error_log.IsValid()) { | 4283 if (eval_args_error_log.IsValid()) { |
| 4278 ReportMessageAt(eval_args_error_log, "strict_eval_arguments", | 4284 ReportMessageAt(eval_args_error_log, "strict_eval_arguments"); |
| 4279 Vector<const char*>::empty()); | |
| 4280 *ok = false; | 4285 *ok = false; |
| 4281 return NULL; | 4286 return NULL; |
| 4282 } | 4287 } |
| 4283 if (dupe_error_loc.IsValid()) { | 4288 if (dupe_error_loc.IsValid()) { |
| 4284 ReportMessageAt(dupe_error_loc, "strict_param_dupe", | 4289 ReportMessageAt(dupe_error_loc, "strict_param_dupe"); |
| 4285 Vector<const char*>::empty()); | |
| 4286 *ok = false; | 4290 *ok = false; |
| 4287 return NULL; | 4291 return NULL; |
| 4288 } | 4292 } |
| 4289 if (reserved_loc.IsValid()) { | 4293 if (reserved_loc.IsValid()) { |
| 4290 ReportMessageAt(reserved_loc, "unexpected_strict_reserved", | 4294 ReportMessageAt(reserved_loc, "unexpected_strict_reserved"); |
| 4291 Vector<const char*>::empty()); | |
| 4292 *ok = false; | 4295 *ok = false; |
| 4293 return NULL; | 4296 return NULL; |
| 4294 } | 4297 } |
| 4295 CheckOctalLiteral(scope->start_position(), | 4298 CheckOctalLiteral(scope->start_position(), |
| 4296 scope->end_position(), | 4299 scope->end_position(), |
| 4297 CHECK_OK); | 4300 CHECK_OK); |
| 4298 } | 4301 } |
| 4299 ast_properties = *factory()->visitor()->ast_properties(); | 4302 ast_properties = *factory()->visitor()->ast_properties(); |
| 4303 slot_processor = factory()->visitor()->slot_processor(); |
| 4300 dont_optimize_reason = factory()->visitor()->dont_optimize_reason(); | 4304 dont_optimize_reason = factory()->visitor()->dont_optimize_reason(); |
| 4301 } | 4305 } |
| 4302 | 4306 |
| 4303 if (is_extended_mode()) { | 4307 if (is_extended_mode()) { |
| 4304 CheckConflictingVarDeclarations(scope, CHECK_OK); | 4308 CheckConflictingVarDeclarations(scope, CHECK_OK); |
| 4305 } | 4309 } |
| 4306 | 4310 |
| 4307 FunctionLiteral* function_literal = | 4311 FunctionLiteral* function_literal = |
| 4308 factory()->NewFunctionLiteral(function_name, | 4312 factory()->NewFunctionLiteral(function_name, |
| 4309 scope, | 4313 scope, |
| 4310 body, | 4314 body, |
| 4311 materialized_literal_count, | 4315 materialized_literal_count, |
| 4312 expected_property_count, | 4316 expected_property_count, |
| 4313 handler_count, | 4317 handler_count, |
| 4314 num_parameters, | 4318 num_parameters, |
| 4315 duplicate_parameters, | 4319 duplicate_parameters, |
| 4316 function_type, | 4320 function_type, |
| 4317 FunctionLiteral::kIsFunction, | 4321 FunctionLiteral::kIsFunction, |
| 4318 parenthesized, | 4322 parenthesized, |
| 4319 generator, | 4323 generator, |
| 4320 pos); | 4324 pos); |
| 4321 function_literal->set_function_token_position(function_token_pos); | 4325 function_literal->set_function_token_position(function_token_pos); |
| 4322 function_literal->set_ast_properties(&ast_properties); | 4326 function_literal->set_ast_properties(&ast_properties); |
| 4327 function_literal->set_slot_processor(slot_processor); |
| 4323 function_literal->set_dont_optimize_reason(dont_optimize_reason); | 4328 function_literal->set_dont_optimize_reason(dont_optimize_reason); |
| 4324 | 4329 |
| 4325 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal); | 4330 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal); |
| 4326 return function_literal; | 4331 return function_literal; |
| 4327 } | 4332 } |
| 4328 | 4333 |
| 4329 | 4334 |
| 4330 PreParser::PreParseResult Parser::LazyParseFunctionLiteral( | 4335 PreParser::PreParseResult Parser::LazyParseFunctionLiteral( |
| 4331 SingletonLogger* logger) { | 4336 SingletonLogger* logger) { |
| 4332 HistogramTimerScope preparse_scope(isolate()->counters()->pre_parse()); | 4337 HistogramTimerScope preparse_scope(isolate()->counters()->pre_parse()); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4390 if (function != NULL && | 4395 if (function != NULL && |
| 4391 function->nargs != -1 && | 4396 function->nargs != -1 && |
| 4392 function->nargs != args->length()) { | 4397 function->nargs != args->length()) { |
| 4393 ReportMessage("illegal_access", Vector<const char*>::empty()); | 4398 ReportMessage("illegal_access", Vector<const char*>::empty()); |
| 4394 *ok = false; | 4399 *ok = false; |
| 4395 return NULL; | 4400 return NULL; |
| 4396 } | 4401 } |
| 4397 | 4402 |
| 4398 // Check that the function is defined if it's an inline runtime call. | 4403 // Check that the function is defined if it's an inline runtime call. |
| 4399 if (function == NULL && name->Get(0) == '_') { | 4404 if (function == NULL && name->Get(0) == '_') { |
| 4400 ReportMessage("not_defined", Vector<Handle<String> >(&name, 1)); | 4405 ParserTraits::ReportMessage("not_defined", |
| 4406 Vector<Handle<String> >(&name, 1)); |
| 4401 *ok = false; | 4407 *ok = false; |
| 4402 return NULL; | 4408 return NULL; |
| 4403 } | 4409 } |
| 4404 | 4410 |
| 4405 // We have a valid intrinsics call or a call to a builtin. | 4411 // We have a valid intrinsics call or a call to a builtin. |
| 4406 return factory()->NewCallRuntime(name, function, args, pos); | 4412 return factory()->NewCallRuntime(name, function, args, pos); |
| 4407 } | 4413 } |
| 4408 | 4414 |
| 4409 | 4415 |
| 4410 bool ParserBase::peek_any_identifier() { | |
| 4411 Token::Value next = peek(); | |
| 4412 return next == Token::IDENTIFIER || | |
| 4413 next == Token::FUTURE_RESERVED_WORD || | |
| 4414 next == Token::FUTURE_STRICT_RESERVED_WORD || | |
| 4415 next == Token::YIELD; | |
| 4416 } | |
| 4417 | |
| 4418 | |
| 4419 bool ParserBase::CheckContextualKeyword(Vector<const char> keyword) { | |
| 4420 if (peek() == Token::IDENTIFIER && | |
| 4421 scanner()->is_next_contextual_keyword(keyword)) { | |
| 4422 Consume(Token::IDENTIFIER); | |
| 4423 return true; | |
| 4424 } | |
| 4425 return false; | |
| 4426 } | |
| 4427 | |
| 4428 | |
| 4429 void ParserBase::ExpectSemicolon(bool* ok) { | |
| 4430 // Check for automatic semicolon insertion according to | |
| 4431 // the rules given in ECMA-262, section 7.9, page 21. | |
| 4432 Token::Value tok = peek(); | |
| 4433 if (tok == Token::SEMICOLON) { | |
| 4434 Next(); | |
| 4435 return; | |
| 4436 } | |
| 4437 if (scanner()->HasAnyLineTerminatorBeforeNext() || | |
| 4438 tok == Token::RBRACE || | |
| 4439 tok == Token::EOS) { | |
| 4440 return; | |
| 4441 } | |
| 4442 Expect(Token::SEMICOLON, ok); | |
| 4443 } | |
| 4444 | |
| 4445 | |
| 4446 void ParserBase::ExpectContextualKeyword(Vector<const char> keyword, bool* ok) { | |
| 4447 Expect(Token::IDENTIFIER, ok); | |
| 4448 if (!*ok) return; | |
| 4449 if (!scanner()->is_literal_contextual_keyword(keyword)) { | |
| 4450 ReportUnexpectedToken(scanner()->current_token()); | |
| 4451 *ok = false; | |
| 4452 } | |
| 4453 } | |
| 4454 | |
| 4455 | |
| 4456 void ParserBase::ReportUnexpectedToken(Token::Value token) { | |
| 4457 // We don't report stack overflows here, to avoid increasing the | |
| 4458 // stack depth even further. Instead we report it after parsing is | |
| 4459 // over, in ParseProgram. | |
| 4460 if (token == Token::ILLEGAL && stack_overflow()) { | |
| 4461 return; | |
| 4462 } | |
| 4463 Scanner::Location source_location = scanner()->location(); | |
| 4464 | |
| 4465 // Four of the tokens are treated specially | |
| 4466 switch (token) { | |
| 4467 case Token::EOS: | |
| 4468 return ReportMessageAt(source_location, "unexpected_eos"); | |
| 4469 case Token::NUMBER: | |
| 4470 return ReportMessageAt(source_location, "unexpected_token_number"); | |
| 4471 case Token::STRING: | |
| 4472 return ReportMessageAt(source_location, "unexpected_token_string"); | |
| 4473 case Token::IDENTIFIER: | |
| 4474 return ReportMessageAt(source_location, | |
| 4475 "unexpected_token_identifier"); | |
| 4476 case Token::FUTURE_RESERVED_WORD: | |
| 4477 return ReportMessageAt(source_location, "unexpected_reserved"); | |
| 4478 case Token::YIELD: | |
| 4479 case Token::FUTURE_STRICT_RESERVED_WORD: | |
| 4480 return ReportMessageAt(source_location, | |
| 4481 is_classic_mode() ? "unexpected_token_identifier" | |
| 4482 : "unexpected_strict_reserved"); | |
| 4483 default: | |
| 4484 const char* name = Token::String(token); | |
| 4485 ASSERT(name != NULL); | |
| 4486 ReportMessageAt( | |
| 4487 source_location, "unexpected_token", Vector<const char*>(&name, 1)); | |
| 4488 } | |
| 4489 } | |
| 4490 | |
| 4491 | |
| 4492 Literal* Parser::GetLiteralUndefined(int position) { | 4416 Literal* Parser::GetLiteralUndefined(int position) { |
| 4493 return factory()->NewLiteral( | 4417 return factory()->NewLiteral( |
| 4494 isolate()->factory()->undefined_value(), position); | 4418 isolate()->factory()->undefined_value(), position); |
| 4495 } | 4419 } |
| 4496 | 4420 |
| 4497 | 4421 |
| 4498 Literal* Parser::GetLiteralTheHole(int position) { | 4422 Literal* Parser::GetLiteralTheHole(int position) { |
| 4499 return factory()->NewLiteral( | 4423 return factory()->NewLiteral( |
| 4500 isolate()->factory()->the_hole_value(), RelocInfo::kNoPosition); | 4424 isolate()->factory()->the_hole_value(), RelocInfo::kNoPosition); |
| 4501 } | 4425 } |
| 4502 | 4426 |
| 4503 | 4427 |
| 4504 // Parses an identifier that is valid for the current scope, in particular it | |
| 4505 // fails on strict mode future reserved keywords in a strict scope. If | |
| 4506 // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or | |
| 4507 // "arguments" as identifier even in strict mode (this is needed in cases like | |
| 4508 // "var foo = eval;"). | |
| 4509 Handle<String> Parser::ParseIdentifier( | |
| 4510 AllowEvalOrArgumentsAsIdentifier allow_eval_or_arguments, | |
| 4511 bool* ok) { | |
| 4512 Token::Value next = Next(); | |
| 4513 if (next == Token::IDENTIFIER) { | |
| 4514 Handle<String> name = GetSymbol(); | |
| 4515 if (allow_eval_or_arguments == kDontAllowEvalOrArguments && | |
| 4516 !top_scope_->is_classic_mode() && IsEvalOrArguments(name)) { | |
| 4517 ReportMessage("strict_eval_arguments", Vector<const char*>::empty()); | |
| 4518 *ok = false; | |
| 4519 } | |
| 4520 return name; | |
| 4521 } else if (top_scope_->is_classic_mode() && | |
| 4522 (next == Token::FUTURE_STRICT_RESERVED_WORD || | |
| 4523 (next == Token::YIELD && !is_generator()))) { | |
| 4524 return GetSymbol(); | |
| 4525 } else { | |
| 4526 ReportUnexpectedToken(next); | |
| 4527 *ok = false; | |
| 4528 return Handle<String>(); | |
| 4529 } | |
| 4530 } | |
| 4531 | |
| 4532 | |
| 4533 // Parses and identifier or a strict mode future reserved word, and indicate | |
| 4534 // whether it is strict mode future reserved. | |
| 4535 Handle<String> Parser::ParseIdentifierOrStrictReservedWord( | |
| 4536 bool* is_strict_reserved, bool* ok) { | |
| 4537 Token::Value next = Next(); | |
| 4538 if (next == Token::IDENTIFIER) { | |
| 4539 *is_strict_reserved = false; | |
| 4540 } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || | |
| 4541 (next == Token::YIELD && !is_generator())) { | |
| 4542 *is_strict_reserved = true; | |
| 4543 } else { | |
| 4544 ReportUnexpectedToken(next); | |
| 4545 *ok = false; | |
| 4546 return Handle<String>(); | |
| 4547 } | |
| 4548 return GetSymbol(); | |
| 4549 } | |
| 4550 | |
| 4551 | |
| 4552 Handle<String> Parser::ParseIdentifierName(bool* ok) { | |
| 4553 Token::Value next = Next(); | |
| 4554 if (next != Token::IDENTIFIER && | |
| 4555 next != Token::FUTURE_RESERVED_WORD && | |
| 4556 next != Token::FUTURE_STRICT_RESERVED_WORD && | |
| 4557 !Token::IsKeyword(next)) { | |
| 4558 ReportUnexpectedToken(next); | |
| 4559 *ok = false; | |
| 4560 return Handle<String>(); | |
| 4561 } | |
| 4562 return GetSymbol(); | |
| 4563 } | |
| 4564 | |
| 4565 | |
| 4566 void Parser::MarkAsLValue(Expression* expression) { | 4428 void Parser::MarkAsLValue(Expression* expression) { |
| 4567 VariableProxy* proxy = expression != NULL | 4429 VariableProxy* proxy = expression != NULL |
| 4568 ? expression->AsVariableProxy() | 4430 ? expression->AsVariableProxy() |
| 4569 : NULL; | 4431 : NULL; |
| 4570 | 4432 |
| 4571 if (proxy != NULL) proxy->MarkAsLValue(); | 4433 if (proxy != NULL) proxy->MarkAsLValue(); |
| 4572 } | 4434 } |
| 4573 | 4435 |
| 4574 | 4436 |
| 4575 // Checks LHS expression for assignment and prefix/postfix increment/decrement | 4437 // Checks LHS expression for assignment and prefix/postfix increment/decrement |
| 4576 // in strict mode. | 4438 // in strict mode. |
| 4577 void Parser::CheckStrictModeLValue(Expression* expression, | 4439 void Parser::CheckStrictModeLValue(Expression* expression, |
| 4578 bool* ok) { | 4440 bool* ok) { |
| 4579 ASSERT(!top_scope_->is_classic_mode()); | 4441 ASSERT(!top_scope_->is_classic_mode()); |
| 4580 VariableProxy* lhs = expression != NULL | 4442 VariableProxy* lhs = expression != NULL |
| 4581 ? expression->AsVariableProxy() | 4443 ? expression->AsVariableProxy() |
| 4582 : NULL; | 4444 : NULL; |
| 4583 | 4445 |
| 4584 if (lhs != NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) { | 4446 if (lhs != NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) { |
| 4585 ReportMessage("strict_eval_arguments", Vector<const char*>::empty()); | 4447 ReportMessage("strict_eval_arguments", Vector<const char*>::empty()); |
| 4586 *ok = false; | 4448 *ok = false; |
| 4587 } | 4449 } |
| 4588 } | 4450 } |
| 4589 | 4451 |
| 4590 | 4452 |
| 4591 // Checks whether an octal literal was last seen between beg_pos and end_pos. | |
| 4592 // If so, reports an error. Only called for strict mode. | |
| 4593 void ParserBase::CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) { | |
| 4594 Scanner::Location octal = scanner()->octal_position(); | |
| 4595 if (octal.IsValid() && beg_pos <= octal.beg_pos && octal.end_pos <= end_pos) { | |
| 4596 ReportMessageAt(octal, "strict_octal_literal"); | |
| 4597 scanner()->clear_octal_position(); | |
| 4598 *ok = false; | |
| 4599 } | |
| 4600 } | |
| 4601 | |
| 4602 | |
| 4603 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) { | 4453 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) { |
| 4604 Declaration* decl = scope->CheckConflictingVarDeclarations(); | 4454 Declaration* decl = scope->CheckConflictingVarDeclarations(); |
| 4605 if (decl != NULL) { | 4455 if (decl != NULL) { |
| 4606 // In harmony mode we treat conflicting variable bindinds as early | 4456 // In harmony mode we treat conflicting variable bindinds as early |
| 4607 // errors. See ES5 16 for a definition of early errors. | 4457 // errors. See ES5 16 for a definition of early errors. |
| 4608 Handle<String> name = decl->proxy()->name(); | 4458 Handle<String> name = decl->proxy()->name(); |
| 4609 SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS); | 4459 SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS); |
| 4610 const char* elms[2] = { "Variable", c_string.get() }; | 4460 const char* elms[2] = { "Variable", c_string.get() }; |
| 4611 Vector<const char*> args(elms, 2); | 4461 Vector<const char*> args(elms, 2); |
| 4612 int position = decl->proxy()->position(); | 4462 int position = decl->proxy()->position(); |
| 4613 Scanner::Location location = position == RelocInfo::kNoPosition | 4463 Scanner::Location location = position == RelocInfo::kNoPosition |
| 4614 ? Scanner::Location::invalid() | 4464 ? Scanner::Location::invalid() |
| 4615 : Scanner::Location(position, position + 1); | 4465 : Scanner::Location(position, position + 1); |
| 4616 ReportMessageAt(location, "redeclaration", args); | 4466 ParserTraits::ReportMessageAt(location, "redeclaration", args); |
| 4617 *ok = false; | 4467 *ok = false; |
| 4618 } | 4468 } |
| 4619 } | 4469 } |
| 4620 | 4470 |
| 4621 | 4471 |
| 4622 // This function reads an identifier name and determines whether or not it | |
| 4623 // is 'get' or 'set'. | |
| 4624 Handle<String> Parser::ParseIdentifierNameOrGetOrSet(bool* is_get, | |
| 4625 bool* is_set, | |
| 4626 bool* ok) { | |
| 4627 Handle<String> result = ParseIdentifierName(ok); | |
| 4628 if (!*ok) return Handle<String>(); | |
| 4629 if (scanner().is_literal_ascii() && scanner().literal_length() == 3) { | |
| 4630 const char* token = scanner().literal_ascii_string().start(); | |
| 4631 *is_get = strncmp(token, "get", 3) == 0; | |
| 4632 *is_set = !*is_get && strncmp(token, "set", 3) == 0; | |
| 4633 } | |
| 4634 return result; | |
| 4635 } | |
| 4636 | |
| 4637 | |
| 4638 // ---------------------------------------------------------------------------- | 4472 // ---------------------------------------------------------------------------- |
| 4639 // Parser support | 4473 // Parser support |
| 4640 | 4474 |
| 4641 | 4475 |
| 4642 bool Parser::TargetStackContainsLabel(Handle<String> label) { | 4476 bool Parser::TargetStackContainsLabel(Handle<String> label) { |
| 4643 for (Target* t = target_stack_; t != NULL; t = t->previous()) { | 4477 for (Target* t = target_stack_; t != NULL; t = t->previous()) { |
| 4644 BreakableStatement* stat = t->node()->AsBreakableStatement(); | 4478 BreakableStatement* stat = t->node()->AsBreakableStatement(); |
| 4645 if (stat != NULL && ContainsLabel(stat->labels(), label)) | 4479 if (stat != NULL && ContainsLabel(stat->labels(), label)) |
| 4646 return true; | 4480 return true; |
| 4647 } | 4481 } |
| (...skipping 1028 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5676 } else { | 5510 } else { |
| 5677 result = ParseProgram(); | 5511 result = ParseProgram(); |
| 5678 } | 5512 } |
| 5679 } else { | 5513 } else { |
| 5680 ScriptDataImpl* pre_parse_data = info()->pre_parse_data(); | 5514 ScriptDataImpl* pre_parse_data = info()->pre_parse_data(); |
| 5681 set_pre_parse_data(pre_parse_data); | 5515 set_pre_parse_data(pre_parse_data); |
| 5682 if (pre_parse_data != NULL && pre_parse_data->has_error()) { | 5516 if (pre_parse_data != NULL && pre_parse_data->has_error()) { |
| 5683 Scanner::Location loc = pre_parse_data->MessageLocation(); | 5517 Scanner::Location loc = pre_parse_data->MessageLocation(); |
| 5684 const char* message = pre_parse_data->BuildMessage(); | 5518 const char* message = pre_parse_data->BuildMessage(); |
| 5685 Vector<const char*> args = pre_parse_data->BuildArgs(); | 5519 Vector<const char*> args = pre_parse_data->BuildArgs(); |
| 5686 ReportMessageAt(loc, message, args); | 5520 ParserTraits::ReportMessageAt(loc, message, args); |
| 5687 DeleteArray(message); | 5521 DeleteArray(message); |
| 5688 for (int i = 0; i < args.length(); i++) { | 5522 for (int i = 0; i < args.length(); i++) { |
| 5689 DeleteArray(args[i]); | 5523 DeleteArray(args[i]); |
| 5690 } | 5524 } |
| 5691 DeleteArray(args.start()); | 5525 DeleteArray(args.start()); |
| 5692 ASSERT(info()->isolate()->has_pending_exception()); | 5526 ASSERT(info()->isolate()->has_pending_exception()); |
| 5693 } else { | 5527 } else { |
| 5694 result = ParseProgram(); | 5528 result = ParseProgram(); |
| 5695 } | 5529 } |
| 5696 } | 5530 } |
| 5697 info()->SetFunction(result); | 5531 info()->SetFunction(result); |
| 5698 return (result != NULL); | 5532 return (result != NULL); |
| 5699 } | 5533 } |
| 5700 | 5534 |
| 5701 } } // namespace v8::internal | 5535 } } // namespace v8::internal |
| OLD | NEW |