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 void ParserTraits::ReportMessageAt(Scanner::Location source_location, | |
555 const char* message, | |
556 Vector<const char*> args) { | |
557 MessageLocation location(parser_->script_, | |
558 source_location.beg_pos, | |
559 source_location.end_pos); | |
560 Factory* factory = parser_->isolate()->factory(); | |
561 Handle<FixedArray> elements = factory->NewFixedArray(args.length()); | |
562 for (int i = 0; i < args.length(); i++) { | |
563 Handle<String> arg_string = factory->NewStringFromUtf8(CStrVector(args[i])); | |
564 elements->set(i, *arg_string); | |
565 } | |
566 Handle<JSArray> array = factory->NewJSArrayWithElements(elements); | |
567 Handle<Object> result = factory->NewSyntaxError(message, array); | |
568 parser_->isolate()->Throw(*result, &location); | |
569 } | |
570 | |
571 | |
572 void ParserTraits::ReportMessage(const char* message, | |
573 Vector<Handle<String> > args) { | |
574 Scanner::Location source_location = parser_->scanner().location(); | |
575 ReportMessageAt(source_location, message, args); | |
576 } | |
577 | |
578 | |
579 void ParserTraits::ReportMessageAt(Scanner::Location source_location, | |
580 const char* message, | |
581 Vector<Handle<String> > args) { | |
582 MessageLocation location(parser_->script_, | |
583 source_location.beg_pos, | |
584 source_location.end_pos); | |
585 Factory* factory = parser_->isolate()->factory(); | |
586 Handle<FixedArray> elements = factory->NewFixedArray(args.length()); | |
587 for (int i = 0; i < args.length(); i++) { | |
588 elements->set(i, *args[i]); | |
589 } | |
590 Handle<JSArray> array = factory->NewJSArrayWithElements(elements); | |
591 Handle<Object> result = factory->NewSyntaxError(message, array); | |
592 parser_->isolate()->Throw(*result, &location); | |
593 } | |
594 | |
595 | |
596 Handle<String> ParserTraits::GetSymbol() { | |
597 int symbol_id = -1; | |
598 if (parser_->pre_parse_data() != NULL) { | |
599 symbol_id = parser_->pre_parse_data()->GetSymbolIdentifier(); | |
600 } | |
601 return parser_->LookupSymbol(symbol_id); | |
602 } | |
603 | |
604 Parser::Parser(CompilationInfo* info) | 536 Parser::Parser(CompilationInfo* info) |
605 : ParserBase(&scanner_, | 537 : ParserBase(&scanner_, info->isolate()->stack_guard()->real_climit()), |
606 info->isolate()->stack_guard()->real_climit(), | |
607 this), | |
608 isolate_(info->isolate()), | 538 isolate_(info->isolate()), |
609 symbol_cache_(0, info->zone()), | 539 symbol_cache_(0, info->zone()), |
610 script_(info->script()), | 540 script_(info->script()), |
611 scanner_(isolate_->unicode_cache()), | 541 scanner_(isolate_->unicode_cache()), |
612 reusable_preparser_(NULL), | 542 reusable_preparser_(NULL), |
613 top_scope_(NULL), | 543 top_scope_(NULL), |
614 original_scope_(NULL), | 544 original_scope_(NULL), |
615 current_function_state_(NULL), | 545 current_function_state_(NULL), |
616 target_stack_(NULL), | 546 target_stack_(NULL), |
617 extension_(info->extension()), | 547 extension_(info->extension()), |
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
856 if (result == NULL) { | 786 if (result == NULL) { |
857 if (stack_overflow()) isolate()->StackOverflow(); | 787 if (stack_overflow()) isolate()->StackOverflow(); |
858 } else { | 788 } else { |
859 Handle<String> inferred_name(shared_info->inferred_name()); | 789 Handle<String> inferred_name(shared_info->inferred_name()); |
860 result->set_inferred_name(inferred_name); | 790 result->set_inferred_name(inferred_name); |
861 } | 791 } |
862 return result; | 792 return result; |
863 } | 793 } |
864 | 794 |
865 | 795 |
| 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 |
866 void* Parser::ParseSourceElements(ZoneList<Statement*>* processor, | 852 void* Parser::ParseSourceElements(ZoneList<Statement*>* processor, |
867 int end_token, | 853 int end_token, |
868 bool is_eval, | 854 bool is_eval, |
869 bool is_global, | 855 bool is_global, |
870 bool* ok) { | 856 bool* ok) { |
871 // SourceElements :: | 857 // SourceElements :: |
872 // (ModuleElement)* <end_token> | 858 // (ModuleElement)* <end_token> |
873 | 859 |
874 // Allocate a target stack to use for this set of source | 860 // Allocate a target stack to use for this set of source |
875 // elements. This way, all scripts and functions get their own | 861 // elements. This way, all scripts and functions get their own |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1088 Expect(Token::RBRACE, CHECK_OK); | 1074 Expect(Token::RBRACE, CHECK_OK); |
1089 scope->set_end_position(scanner().location().end_pos); | 1075 scope->set_end_position(scanner().location().end_pos); |
1090 body->set_scope(scope); | 1076 body->set_scope(scope); |
1091 | 1077 |
1092 // Check that all exports are bound. | 1078 // Check that all exports are bound. |
1093 Interface* interface = scope->interface(); | 1079 Interface* interface = scope->interface(); |
1094 for (Interface::Iterator it = interface->iterator(); | 1080 for (Interface::Iterator it = interface->iterator(); |
1095 !it.done(); it.Advance()) { | 1081 !it.done(); it.Advance()) { |
1096 if (scope->LocalLookup(it.name()) == NULL) { | 1082 if (scope->LocalLookup(it.name()) == NULL) { |
1097 Handle<String> name(it.name()); | 1083 Handle<String> name(it.name()); |
1098 ParserTraits::ReportMessage("module_export_undefined", | 1084 ReportMessage("module_export_undefined", |
1099 Vector<Handle<String> >(&name, 1)); | 1085 Vector<Handle<String> >(&name, 1)); |
1100 *ok = false; | 1086 *ok = false; |
1101 return NULL; | 1087 return NULL; |
1102 } | 1088 } |
1103 } | 1089 } |
1104 | 1090 |
1105 interface->MakeModule(ok); | 1091 interface->MakeModule(ok); |
1106 ASSERT(*ok); | 1092 ASSERT(*ok); |
1107 interface->Freeze(ok); | 1093 interface->Freeze(ok); |
1108 ASSERT(*ok); | 1094 ASSERT(*ok); |
1109 return factory()->NewModuleLiteral(body, interface, pos); | 1095 return factory()->NewModuleLiteral(body, interface, pos); |
(...skipping 18 matching lines...) Expand all Loading... |
1128 if (!*ok) { | 1114 if (!*ok) { |
1129 #ifdef DEBUG | 1115 #ifdef DEBUG |
1130 if (FLAG_print_interfaces) { | 1116 if (FLAG_print_interfaces) { |
1131 PrintF("PATH TYPE ERROR at '%s'\n", name->ToAsciiArray()); | 1117 PrintF("PATH TYPE ERROR at '%s'\n", name->ToAsciiArray()); |
1132 PrintF("result: "); | 1118 PrintF("result: "); |
1133 result->interface()->Print(); | 1119 result->interface()->Print(); |
1134 PrintF("member: "); | 1120 PrintF("member: "); |
1135 member->interface()->Print(); | 1121 member->interface()->Print(); |
1136 } | 1122 } |
1137 #endif | 1123 #endif |
1138 ParserTraits::ReportMessage("invalid_module_path", | 1124 ReportMessage("invalid_module_path", Vector<Handle<String> >(&name, 1)); |
1139 Vector<Handle<String> >(&name, 1)); | |
1140 return NULL; | 1125 return NULL; |
1141 } | 1126 } |
1142 result = member; | 1127 result = member; |
1143 } | 1128 } |
1144 | 1129 |
1145 return result; | 1130 return result; |
1146 } | 1131 } |
1147 | 1132 |
1148 | 1133 |
1149 Module* Parser::ParseModuleVariable(bool* ok) { | 1134 Module* Parser::ParseModuleVariable(bool* ok) { |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1239 Interface* interface = Interface::NewUnknown(zone()); | 1224 Interface* interface = Interface::NewUnknown(zone()); |
1240 module->interface()->Add(names[i], interface, zone(), ok); | 1225 module->interface()->Add(names[i], interface, zone(), ok); |
1241 if (!*ok) { | 1226 if (!*ok) { |
1242 #ifdef DEBUG | 1227 #ifdef DEBUG |
1243 if (FLAG_print_interfaces) { | 1228 if (FLAG_print_interfaces) { |
1244 PrintF("IMPORT TYPE ERROR at '%s'\n", names[i]->ToAsciiArray()); | 1229 PrintF("IMPORT TYPE ERROR at '%s'\n", names[i]->ToAsciiArray()); |
1245 PrintF("module: "); | 1230 PrintF("module: "); |
1246 module->interface()->Print(); | 1231 module->interface()->Print(); |
1247 } | 1232 } |
1248 #endif | 1233 #endif |
1249 ParserTraits::ReportMessage("invalid_module_path", | 1234 ReportMessage("invalid_module_path", Vector<Handle<String> >(&name, 1)); |
1250 Vector<Handle<String> >(&name, 1)); | |
1251 return NULL; | 1235 return NULL; |
1252 } | 1236 } |
1253 VariableProxy* proxy = NewUnresolved(names[i], LET, interface); | 1237 VariableProxy* proxy = NewUnresolved(names[i], LET, interface); |
1254 Declaration* declaration = | 1238 Declaration* declaration = |
1255 factory()->NewImportDeclaration(proxy, module, top_scope_, pos); | 1239 factory()->NewImportDeclaration(proxy, module, top_scope_, pos); |
1256 Declare(declaration, true, CHECK_OK); | 1240 Declare(declaration, true, CHECK_OK); |
1257 } | 1241 } |
1258 | 1242 |
1259 return block; | 1243 return block; |
1260 } | 1244 } |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1448 // SourceElement: | 1432 // SourceElement: |
1449 // Statement | 1433 // Statement |
1450 // FunctionDeclaration | 1434 // FunctionDeclaration |
1451 // Common language extension is to allow function declaration in place | 1435 // Common language extension is to allow function declaration in place |
1452 // of any statement. This language extension is disabled in strict mode. | 1436 // of any statement. This language extension is disabled in strict mode. |
1453 // | 1437 // |
1454 // In Harmony mode, this case also handles the extension: | 1438 // In Harmony mode, this case also handles the extension: |
1455 // Statement: | 1439 // Statement: |
1456 // GeneratorDeclaration | 1440 // GeneratorDeclaration |
1457 if (!top_scope_->is_classic_mode()) { | 1441 if (!top_scope_->is_classic_mode()) { |
1458 ReportMessageAt(scanner().peek_location(), "strict_function"); | 1442 ReportMessageAt(scanner().peek_location(), "strict_function", |
| 1443 Vector<const char*>::empty()); |
1459 *ok = false; | 1444 *ok = false; |
1460 return NULL; | 1445 return NULL; |
1461 } | 1446 } |
1462 return ParseFunctionDeclaration(NULL, ok); | 1447 return ParseFunctionDeclaration(NULL, ok); |
1463 } | 1448 } |
1464 | 1449 |
1465 case Token::DEBUGGER: | 1450 case Token::DEBUGGER: |
1466 return ParseDebuggerStatement(ok); | 1451 return ParseDebuggerStatement(ok); |
1467 | 1452 |
1468 default: | 1453 default: |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1627 if (!ok) { | 1612 if (!ok) { |
1628 #ifdef DEBUG | 1613 #ifdef DEBUG |
1629 if (FLAG_print_interfaces) { | 1614 if (FLAG_print_interfaces) { |
1630 PrintF("DECLARE TYPE ERROR\n"); | 1615 PrintF("DECLARE TYPE ERROR\n"); |
1631 PrintF("proxy: "); | 1616 PrintF("proxy: "); |
1632 proxy->interface()->Print(); | 1617 proxy->interface()->Print(); |
1633 PrintF("var: "); | 1618 PrintF("var: "); |
1634 var->interface()->Print(); | 1619 var->interface()->Print(); |
1635 } | 1620 } |
1636 #endif | 1621 #endif |
1637 ParserTraits::ReportMessage("module_type_error", | 1622 ReportMessage("module_type_error", Vector<Handle<String> >(&name, 1)); |
1638 Vector<Handle<String> >(&name, 1)); | |
1639 } | 1623 } |
1640 } | 1624 } |
1641 } | 1625 } |
1642 } | 1626 } |
1643 | 1627 |
1644 | 1628 |
1645 // Language extension which is only enabled for source files loaded | 1629 // Language extension which is only enabled for source files loaded |
1646 // through the API's extension mechanism. A native function | 1630 // through the API's extension mechanism. A native function |
1647 // declaration is resolved by looking up the function through a | 1631 // declaration is resolved by looking up the function through a |
1648 // callback provided by the extension. | 1632 // callback provided by the extension. |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1786 // VariableDeclarations ';' | 1770 // VariableDeclarations ';' |
1787 | 1771 |
1788 Handle<String> ignore; | 1772 Handle<String> ignore; |
1789 Block* result = | 1773 Block* result = |
1790 ParseVariableDeclarations(var_context, NULL, names, &ignore, CHECK_OK); | 1774 ParseVariableDeclarations(var_context, NULL, names, &ignore, CHECK_OK); |
1791 ExpectSemicolon(CHECK_OK); | 1775 ExpectSemicolon(CHECK_OK); |
1792 return result; | 1776 return result; |
1793 } | 1777 } |
1794 | 1778 |
1795 | 1779 |
| 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 |
1796 // If the variable declaration declares exactly one non-const | 1786 // If the variable declaration declares exactly one non-const |
1797 // variable, then *out is set to that variable. In all other cases, | 1787 // variable, then *out is set to that variable. In all other cases, |
1798 // *out is untouched; in particular, it is the caller's responsibility | 1788 // *out is untouched; in particular, it is the caller's responsibility |
1799 // to initialize it properly. This mechanism is used for the parsing | 1789 // to initialize it properly. This mechanism is used for the parsing |
1800 // of 'for-in' loops. | 1790 // of 'for-in' loops. |
1801 Block* Parser::ParseVariableDeclarations( | 1791 Block* Parser::ParseVariableDeclarations( |
1802 VariableDeclarationContext var_context, | 1792 VariableDeclarationContext var_context, |
1803 VariableDeclarationProperties* decl_props, | 1793 VariableDeclarationProperties* decl_props, |
1804 ZoneStringList* names, | 1794 ZoneStringList* names, |
1805 Handle<String>* out, | 1795 Handle<String>* out, |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1931 // pre-resolve the proxy because it resides in the same scope as the | 1921 // pre-resolve the proxy because it resides in the same scope as the |
1932 // declaration. | 1922 // declaration. |
1933 Interface* interface = | 1923 Interface* interface = |
1934 is_const ? Interface::NewConst() : Interface::NewValue(); | 1924 is_const ? Interface::NewConst() : Interface::NewValue(); |
1935 VariableProxy* proxy = NewUnresolved(name, mode, interface); | 1925 VariableProxy* proxy = NewUnresolved(name, mode, interface); |
1936 Declaration* declaration = | 1926 Declaration* declaration = |
1937 factory()->NewVariableDeclaration(proxy, mode, top_scope_, pos); | 1927 factory()->NewVariableDeclaration(proxy, mode, top_scope_, pos); |
1938 Declare(declaration, mode != VAR, CHECK_OK); | 1928 Declare(declaration, mode != VAR, CHECK_OK); |
1939 nvars++; | 1929 nvars++; |
1940 if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) { | 1930 if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) { |
1941 ReportMessageAt(scanner().location(), "too_many_variables"); | 1931 ReportMessageAt(scanner().location(), "too_many_variables", |
| 1932 Vector<const char*>::empty()); |
1942 *ok = false; | 1933 *ok = false; |
1943 return NULL; | 1934 return NULL; |
1944 } | 1935 } |
1945 if (names) names->Add(name, zone()); | 1936 if (names) names->Add(name, zone()); |
1946 | 1937 |
1947 // Parse initialization expression if present and/or needed. A | 1938 // Parse initialization expression if present and/or needed. A |
1948 // declaration of the form: | 1939 // declaration of the form: |
1949 // | 1940 // |
1950 // var v = x; | 1941 // var v = x; |
1951 // | 1942 // |
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2234 IterationStatement* target = NULL; | 2225 IterationStatement* target = NULL; |
2235 target = LookupContinueTarget(label, CHECK_OK); | 2226 target = LookupContinueTarget(label, CHECK_OK); |
2236 if (target == NULL) { | 2227 if (target == NULL) { |
2237 // Illegal continue statement. | 2228 // Illegal continue statement. |
2238 const char* message = "illegal_continue"; | 2229 const char* message = "illegal_continue"; |
2239 Vector<Handle<String> > args; | 2230 Vector<Handle<String> > args; |
2240 if (!label.is_null()) { | 2231 if (!label.is_null()) { |
2241 message = "unknown_label"; | 2232 message = "unknown_label"; |
2242 args = Vector<Handle<String> >(&label, 1); | 2233 args = Vector<Handle<String> >(&label, 1); |
2243 } | 2234 } |
2244 ParserTraits::ReportMessageAt(scanner().location(), message, args); | 2235 ReportMessageAt(scanner().location(), message, args); |
2245 *ok = false; | 2236 *ok = false; |
2246 return NULL; | 2237 return NULL; |
2247 } | 2238 } |
2248 ExpectSemicolon(CHECK_OK); | 2239 ExpectSemicolon(CHECK_OK); |
2249 return factory()->NewContinueStatement(target, pos); | 2240 return factory()->NewContinueStatement(target, pos); |
2250 } | 2241 } |
2251 | 2242 |
2252 | 2243 |
2253 Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) { | 2244 Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) { |
2254 // BreakStatement :: | 2245 // BreakStatement :: |
(...skipping 17 matching lines...) Expand all Loading... |
2272 BreakableStatement* target = NULL; | 2263 BreakableStatement* target = NULL; |
2273 target = LookupBreakTarget(label, CHECK_OK); | 2264 target = LookupBreakTarget(label, CHECK_OK); |
2274 if (target == NULL) { | 2265 if (target == NULL) { |
2275 // Illegal break statement. | 2266 // Illegal break statement. |
2276 const char* message = "illegal_break"; | 2267 const char* message = "illegal_break"; |
2277 Vector<Handle<String> > args; | 2268 Vector<Handle<String> > args; |
2278 if (!label.is_null()) { | 2269 if (!label.is_null()) { |
2279 message = "unknown_label"; | 2270 message = "unknown_label"; |
2280 args = Vector<Handle<String> >(&label, 1); | 2271 args = Vector<Handle<String> >(&label, 1); |
2281 } | 2272 } |
2282 ParserTraits::ReportMessageAt(scanner().location(), message, args); | 2273 ReportMessageAt(scanner().location(), message, args); |
2283 *ok = false; | 2274 *ok = false; |
2284 return NULL; | 2275 return NULL; |
2285 } | 2276 } |
2286 ExpectSemicolon(CHECK_OK); | 2277 ExpectSemicolon(CHECK_OK); |
2287 return factory()->NewBreakStatement(target, pos); | 2278 return factory()->NewBreakStatement(target, pos); |
2288 } | 2279 } |
2289 | 2280 |
2290 | 2281 |
2291 Statement* Parser::ParseReturnStatement(bool* ok) { | 2282 Statement* Parser::ParseReturnStatement(bool* ok) { |
2292 // ReturnStatement :: | 2283 // ReturnStatement :: |
(...skipping 722 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3015 // In parsing the first assignment expression in conditional | 3006 // In parsing the first assignment expression in conditional |
3016 // expressions we always accept the 'in' keyword; see ECMA-262, | 3007 // expressions we always accept the 'in' keyword; see ECMA-262, |
3017 // section 11.12, page 58. | 3008 // section 11.12, page 58. |
3018 Expression* left = ParseAssignmentExpression(true, CHECK_OK); | 3009 Expression* left = ParseAssignmentExpression(true, CHECK_OK); |
3019 Expect(Token::COLON, CHECK_OK); | 3010 Expect(Token::COLON, CHECK_OK); |
3020 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); | 3011 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); |
3021 return factory()->NewConditional(expression, left, right, pos); | 3012 return factory()->NewConditional(expression, left, right, pos); |
3022 } | 3013 } |
3023 | 3014 |
3024 | 3015 |
| 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 |
3025 // Precedence >= 4 | 3024 // Precedence >= 4 |
3026 Expression* Parser::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) { | 3025 Expression* Parser::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) { |
3027 ASSERT(prec >= 4); | 3026 ASSERT(prec >= 4); |
3028 Expression* x = ParseUnaryExpression(CHECK_OK); | 3027 Expression* x = ParseUnaryExpression(CHECK_OK); |
3029 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { | 3028 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { |
3030 // prec1 >= 4 | 3029 // prec1 >= 4 |
3031 while (Precedence(peek(), accept_IN) == prec1) { | 3030 while (Precedence(peek(), accept_IN) == prec1) { |
3032 Token::Value op = Next(); | 3031 Token::Value op = Next(); |
3033 int pos = position(); | 3032 int pos = position(); |
3034 Expression* y = ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK); | 3033 Expression* y = ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK); |
(...skipping 822 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3857 // Arguments :: | 3856 // Arguments :: |
3858 // '(' (AssignmentExpression)*[','] ')' | 3857 // '(' (AssignmentExpression)*[','] ')' |
3859 | 3858 |
3860 ZoneList<Expression*>* result = new(zone()) ZoneList<Expression*>(4, zone()); | 3859 ZoneList<Expression*>* result = new(zone()) ZoneList<Expression*>(4, zone()); |
3861 Expect(Token::LPAREN, CHECK_OK); | 3860 Expect(Token::LPAREN, CHECK_OK); |
3862 bool done = (peek() == Token::RPAREN); | 3861 bool done = (peek() == Token::RPAREN); |
3863 while (!done) { | 3862 while (!done) { |
3864 Expression* argument = ParseAssignmentExpression(true, CHECK_OK); | 3863 Expression* argument = ParseAssignmentExpression(true, CHECK_OK); |
3865 result->Add(argument, zone()); | 3864 result->Add(argument, zone()); |
3866 if (result->length() > Code::kMaxArguments) { | 3865 if (result->length() > Code::kMaxArguments) { |
3867 ReportMessageAt(scanner().location(), "too_many_arguments"); | 3866 ReportMessageAt(scanner().location(), "too_many_arguments", |
| 3867 Vector<const char*>::empty()); |
3868 *ok = false; | 3868 *ok = false; |
3869 return NULL; | 3869 return NULL; |
3870 } | 3870 } |
3871 done = (peek() == Token::RPAREN); | 3871 done = (peek() == Token::RPAREN); |
3872 if (!done) Expect(Token::COMMA, CHECK_OK); | 3872 if (!done) Expect(Token::COMMA, CHECK_OK); |
3873 } | 3873 } |
3874 Expect(Token::RPAREN, CHECK_OK); | 3874 Expect(Token::RPAREN, CHECK_OK); |
3875 return result; | 3875 return result; |
3876 } | 3876 } |
3877 | 3877 |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4088 reserved_loc = scanner().location(); | 4088 reserved_loc = scanner().location(); |
4089 } | 4089 } |
4090 if (!dupe_error_loc.IsValid() && top_scope_->IsDeclared(param_name)) { | 4090 if (!dupe_error_loc.IsValid() && top_scope_->IsDeclared(param_name)) { |
4091 duplicate_parameters = FunctionLiteral::kHasDuplicateParameters; | 4091 duplicate_parameters = FunctionLiteral::kHasDuplicateParameters; |
4092 dupe_error_loc = scanner().location(); | 4092 dupe_error_loc = scanner().location(); |
4093 } | 4093 } |
4094 | 4094 |
4095 top_scope_->DeclareParameter(param_name, VAR); | 4095 top_scope_->DeclareParameter(param_name, VAR); |
4096 num_parameters++; | 4096 num_parameters++; |
4097 if (num_parameters > Code::kMaxArguments) { | 4097 if (num_parameters > Code::kMaxArguments) { |
4098 ReportMessageAt(scanner().location(), "too_many_parameters"); | 4098 ReportMessageAt(scanner().location(), "too_many_parameters", |
| 4099 Vector<const char*>::empty()); |
4099 *ok = false; | 4100 *ok = false; |
4100 return NULL; | 4101 return NULL; |
4101 } | 4102 } |
4102 done = (peek() == Token::RPAREN); | 4103 done = (peek() == Token::RPAREN); |
4103 if (!done) Expect(Token::COMMA, CHECK_OK); | 4104 if (!done) Expect(Token::COMMA, CHECK_OK); |
4104 } | 4105 } |
4105 Expect(Token::RPAREN, CHECK_OK); | 4106 Expect(Token::RPAREN, CHECK_OK); |
4106 | 4107 |
4107 Expect(Token::LBRACE, CHECK_OK); | 4108 Expect(Token::LBRACE, CHECK_OK); |
4108 | 4109 |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4179 set_stack_overflow(); | 4180 set_stack_overflow(); |
4180 *ok = false; | 4181 *ok = false; |
4181 return NULL; | 4182 return NULL; |
4182 } | 4183 } |
4183 if (logger.has_error()) { | 4184 if (logger.has_error()) { |
4184 const char* arg = logger.argument_opt(); | 4185 const char* arg = logger.argument_opt(); |
4185 Vector<const char*> args; | 4186 Vector<const char*> args; |
4186 if (arg != NULL) { | 4187 if (arg != NULL) { |
4187 args = Vector<const char*>(&arg, 1); | 4188 args = Vector<const char*>(&arg, 1); |
4188 } | 4189 } |
4189 ParserTraits::ReportMessageAt( | 4190 ReportMessageAt(Scanner::Location(logger.start(), logger.end()), |
4190 Scanner::Location(logger.start(), logger.end()), | 4191 logger.message(), args); |
4191 logger.message(), | |
4192 args); | |
4193 *ok = false; | 4192 *ok = false; |
4194 return NULL; | 4193 return NULL; |
4195 } | 4194 } |
4196 scope->set_end_position(logger.end()); | 4195 scope->set_end_position(logger.end()); |
4197 Expect(Token::RBRACE, CHECK_OK); | 4196 Expect(Token::RBRACE, CHECK_OK); |
4198 isolate()->counters()->total_preparse_skipped()->Increment( | 4197 isolate()->counters()->total_preparse_skipped()->Increment( |
4199 scope->end_position() - function_block_pos); | 4198 scope->end_position() - function_block_pos); |
4200 materialized_literal_count = logger.literals(); | 4199 materialized_literal_count = logger.literals(); |
4201 expected_property_count = logger.properties(); | 4200 expected_property_count = logger.properties(); |
4202 top_scope_->SetLanguageMode(logger.language_mode()); | 4201 top_scope_->SetLanguageMode(logger.language_mode()); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4256 handler_count = function_state.handler_count(); | 4255 handler_count = function_state.handler_count(); |
4257 | 4256 |
4258 Expect(Token::RBRACE, CHECK_OK); | 4257 Expect(Token::RBRACE, CHECK_OK); |
4259 scope->set_end_position(scanner().location().end_pos); | 4258 scope->set_end_position(scanner().location().end_pos); |
4260 } | 4259 } |
4261 | 4260 |
4262 // Validate strict mode. We can do this only after parsing the function, | 4261 // Validate strict mode. We can do this only after parsing the function, |
4263 // since the function can declare itself strict. | 4262 // since the function can declare itself strict. |
4264 if (!top_scope_->is_classic_mode()) { | 4263 if (!top_scope_->is_classic_mode()) { |
4265 if (IsEvalOrArguments(function_name)) { | 4264 if (IsEvalOrArguments(function_name)) { |
4266 ReportMessageAt(function_name_location, "strict_eval_arguments"); | 4265 ReportMessageAt(function_name_location, |
| 4266 "strict_eval_arguments", |
| 4267 Vector<const char*>::empty()); |
4267 *ok = false; | 4268 *ok = false; |
4268 return NULL; | 4269 return NULL; |
4269 } | 4270 } |
4270 if (name_is_strict_reserved) { | 4271 if (name_is_strict_reserved) { |
4271 ReportMessageAt(function_name_location, "unexpected_strict_reserved"); | 4272 ReportMessageAt(function_name_location, "unexpected_strict_reserved", |
| 4273 Vector<const char*>::empty()); |
4272 *ok = false; | 4274 *ok = false; |
4273 return NULL; | 4275 return NULL; |
4274 } | 4276 } |
4275 if (eval_args_error_log.IsValid()) { | 4277 if (eval_args_error_log.IsValid()) { |
4276 ReportMessageAt(eval_args_error_log, "strict_eval_arguments"); | 4278 ReportMessageAt(eval_args_error_log, "strict_eval_arguments", |
| 4279 Vector<const char*>::empty()); |
4277 *ok = false; | 4280 *ok = false; |
4278 return NULL; | 4281 return NULL; |
4279 } | 4282 } |
4280 if (dupe_error_loc.IsValid()) { | 4283 if (dupe_error_loc.IsValid()) { |
4281 ReportMessageAt(dupe_error_loc, "strict_param_dupe"); | 4284 ReportMessageAt(dupe_error_loc, "strict_param_dupe", |
| 4285 Vector<const char*>::empty()); |
4282 *ok = false; | 4286 *ok = false; |
4283 return NULL; | 4287 return NULL; |
4284 } | 4288 } |
4285 if (reserved_loc.IsValid()) { | 4289 if (reserved_loc.IsValid()) { |
4286 ReportMessageAt(reserved_loc, "unexpected_strict_reserved"); | 4290 ReportMessageAt(reserved_loc, "unexpected_strict_reserved", |
| 4291 Vector<const char*>::empty()); |
4287 *ok = false; | 4292 *ok = false; |
4288 return NULL; | 4293 return NULL; |
4289 } | 4294 } |
4290 CheckOctalLiteral(scope->start_position(), | 4295 CheckOctalLiteral(scope->start_position(), |
4291 scope->end_position(), | 4296 scope->end_position(), |
4292 CHECK_OK); | 4297 CHECK_OK); |
4293 } | 4298 } |
4294 ast_properties = *factory()->visitor()->ast_properties(); | 4299 ast_properties = *factory()->visitor()->ast_properties(); |
4295 dont_optimize_reason = factory()->visitor()->dont_optimize_reason(); | 4300 dont_optimize_reason = factory()->visitor()->dont_optimize_reason(); |
4296 } | 4301 } |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4385 if (function != NULL && | 4390 if (function != NULL && |
4386 function->nargs != -1 && | 4391 function->nargs != -1 && |
4387 function->nargs != args->length()) { | 4392 function->nargs != args->length()) { |
4388 ReportMessage("illegal_access", Vector<const char*>::empty()); | 4393 ReportMessage("illegal_access", Vector<const char*>::empty()); |
4389 *ok = false; | 4394 *ok = false; |
4390 return NULL; | 4395 return NULL; |
4391 } | 4396 } |
4392 | 4397 |
4393 // Check that the function is defined if it's an inline runtime call. | 4398 // Check that the function is defined if it's an inline runtime call. |
4394 if (function == NULL && name->Get(0) == '_') { | 4399 if (function == NULL && name->Get(0) == '_') { |
4395 ParserTraits::ReportMessage("not_defined", | 4400 ReportMessage("not_defined", Vector<Handle<String> >(&name, 1)); |
4396 Vector<Handle<String> >(&name, 1)); | |
4397 *ok = false; | 4401 *ok = false; |
4398 return NULL; | 4402 return NULL; |
4399 } | 4403 } |
4400 | 4404 |
4401 // We have a valid intrinsics call or a call to a builtin. | 4405 // We have a valid intrinsics call or a call to a builtin. |
4402 return factory()->NewCallRuntime(name, function, args, pos); | 4406 return factory()->NewCallRuntime(name, function, args, pos); |
4403 } | 4407 } |
4404 | 4408 |
4405 | 4409 |
| 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 |
4406 Literal* Parser::GetLiteralUndefined(int position) { | 4492 Literal* Parser::GetLiteralUndefined(int position) { |
4407 return factory()->NewLiteral( | 4493 return factory()->NewLiteral( |
4408 isolate()->factory()->undefined_value(), position); | 4494 isolate()->factory()->undefined_value(), position); |
4409 } | 4495 } |
4410 | 4496 |
4411 | 4497 |
4412 Literal* Parser::GetLiteralTheHole(int position) { | 4498 Literal* Parser::GetLiteralTheHole(int position) { |
4413 return factory()->NewLiteral( | 4499 return factory()->NewLiteral( |
4414 isolate()->factory()->the_hole_value(), RelocInfo::kNoPosition); | 4500 isolate()->factory()->the_hole_value(), RelocInfo::kNoPosition); |
4415 } | 4501 } |
4416 | 4502 |
4417 | 4503 |
| 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 |
4418 void Parser::MarkAsLValue(Expression* expression) { | 4566 void Parser::MarkAsLValue(Expression* expression) { |
4419 VariableProxy* proxy = expression != NULL | 4567 VariableProxy* proxy = expression != NULL |
4420 ? expression->AsVariableProxy() | 4568 ? expression->AsVariableProxy() |
4421 : NULL; | 4569 : NULL; |
4422 | 4570 |
4423 if (proxy != NULL) proxy->MarkAsLValue(); | 4571 if (proxy != NULL) proxy->MarkAsLValue(); |
4424 } | 4572 } |
4425 | 4573 |
4426 | 4574 |
4427 // Checks LHS expression for assignment and prefix/postfix increment/decrement | 4575 // Checks LHS expression for assignment and prefix/postfix increment/decrement |
4428 // in strict mode. | 4576 // in strict mode. |
4429 void Parser::CheckStrictModeLValue(Expression* expression, | 4577 void Parser::CheckStrictModeLValue(Expression* expression, |
4430 bool* ok) { | 4578 bool* ok) { |
4431 ASSERT(!top_scope_->is_classic_mode()); | 4579 ASSERT(!top_scope_->is_classic_mode()); |
4432 VariableProxy* lhs = expression != NULL | 4580 VariableProxy* lhs = expression != NULL |
4433 ? expression->AsVariableProxy() | 4581 ? expression->AsVariableProxy() |
4434 : NULL; | 4582 : NULL; |
4435 | 4583 |
4436 if (lhs != NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) { | 4584 if (lhs != NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) { |
4437 ReportMessage("strict_eval_arguments", Vector<const char*>::empty()); | 4585 ReportMessage("strict_eval_arguments", Vector<const char*>::empty()); |
4438 *ok = false; | 4586 *ok = false; |
4439 } | 4587 } |
4440 } | 4588 } |
4441 | 4589 |
4442 | 4590 |
| 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 |
4443 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) { | 4603 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) { |
4444 Declaration* decl = scope->CheckConflictingVarDeclarations(); | 4604 Declaration* decl = scope->CheckConflictingVarDeclarations(); |
4445 if (decl != NULL) { | 4605 if (decl != NULL) { |
4446 // In harmony mode we treat conflicting variable bindinds as early | 4606 // In harmony mode we treat conflicting variable bindinds as early |
4447 // errors. See ES5 16 for a definition of early errors. | 4607 // errors. See ES5 16 for a definition of early errors. |
4448 Handle<String> name = decl->proxy()->name(); | 4608 Handle<String> name = decl->proxy()->name(); |
4449 SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS); | 4609 SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS); |
4450 const char* elms[2] = { "Variable", c_string.get() }; | 4610 const char* elms[2] = { "Variable", c_string.get() }; |
4451 Vector<const char*> args(elms, 2); | 4611 Vector<const char*> args(elms, 2); |
4452 int position = decl->proxy()->position(); | 4612 int position = decl->proxy()->position(); |
4453 Scanner::Location location = position == RelocInfo::kNoPosition | 4613 Scanner::Location location = position == RelocInfo::kNoPosition |
4454 ? Scanner::Location::invalid() | 4614 ? Scanner::Location::invalid() |
4455 : Scanner::Location(position, position + 1); | 4615 : Scanner::Location(position, position + 1); |
4456 ParserTraits::ReportMessageAt(location, "redeclaration", args); | 4616 ReportMessageAt(location, "redeclaration", args); |
4457 *ok = false; | 4617 *ok = false; |
4458 } | 4618 } |
4459 } | 4619 } |
4460 | 4620 |
4461 | 4621 |
| 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 |
4462 // ---------------------------------------------------------------------------- | 4638 // ---------------------------------------------------------------------------- |
4463 // Parser support | 4639 // Parser support |
4464 | 4640 |
4465 | 4641 |
4466 bool Parser::TargetStackContainsLabel(Handle<String> label) { | 4642 bool Parser::TargetStackContainsLabel(Handle<String> label) { |
4467 for (Target* t = target_stack_; t != NULL; t = t->previous()) { | 4643 for (Target* t = target_stack_; t != NULL; t = t->previous()) { |
4468 BreakableStatement* stat = t->node()->AsBreakableStatement(); | 4644 BreakableStatement* stat = t->node()->AsBreakableStatement(); |
4469 if (stat != NULL && ContainsLabel(stat->labels(), label)) | 4645 if (stat != NULL && ContainsLabel(stat->labels(), label)) |
4470 return true; | 4646 return true; |
4471 } | 4647 } |
(...skipping 1028 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5500 } else { | 5676 } else { |
5501 result = ParseProgram(); | 5677 result = ParseProgram(); |
5502 } | 5678 } |
5503 } else { | 5679 } else { |
5504 ScriptDataImpl* pre_parse_data = info()->pre_parse_data(); | 5680 ScriptDataImpl* pre_parse_data = info()->pre_parse_data(); |
5505 set_pre_parse_data(pre_parse_data); | 5681 set_pre_parse_data(pre_parse_data); |
5506 if (pre_parse_data != NULL && pre_parse_data->has_error()) { | 5682 if (pre_parse_data != NULL && pre_parse_data->has_error()) { |
5507 Scanner::Location loc = pre_parse_data->MessageLocation(); | 5683 Scanner::Location loc = pre_parse_data->MessageLocation(); |
5508 const char* message = pre_parse_data->BuildMessage(); | 5684 const char* message = pre_parse_data->BuildMessage(); |
5509 Vector<const char*> args = pre_parse_data->BuildArgs(); | 5685 Vector<const char*> args = pre_parse_data->BuildArgs(); |
5510 ParserTraits::ReportMessageAt(loc, message, args); | 5686 ReportMessageAt(loc, message, args); |
5511 DeleteArray(message); | 5687 DeleteArray(message); |
5512 for (int i = 0; i < args.length(); i++) { | 5688 for (int i = 0; i < args.length(); i++) { |
5513 DeleteArray(args[i]); | 5689 DeleteArray(args[i]); |
5514 } | 5690 } |
5515 DeleteArray(args.start()); | 5691 DeleteArray(args.start()); |
5516 ASSERT(info()->isolate()->has_pending_exception()); | 5692 ASSERT(info()->isolate()->has_pending_exception()); |
5517 } else { | 5693 } else { |
5518 result = ParseProgram(); | 5694 result = ParseProgram(); |
5519 } | 5695 } |
5520 } | 5696 } |
5521 info()->SetFunction(result); | 5697 info()->SetFunction(result); |
5522 return (result != NULL); | 5698 return (result != NULL); |
5523 } | 5699 } |
5524 | 5700 |
5525 } } // namespace v8::internal | 5701 } } // namespace v8::internal |
OLD | NEW |