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 | |
536 Parser::Parser(CompilationInfo* info) | 605 Parser::Parser(CompilationInfo* info) |
537 : ParserBase(&scanner_, info->isolate()->stack_guard()->real_climit()), | 606 : ParserBase(&scanner_, info->isolate()->stack_guard()->real_climit(), |
607 new ParserTraits(this)), | |
Michael Starzinger
2014/02/10 13:28:03
If we make the ParserBase inherit from ParserTrait
marja
2014/02/10 15:02:07
Done.
| |
538 isolate_(info->isolate()), | 608 isolate_(info->isolate()), |
539 symbol_cache_(0, info->zone()), | 609 symbol_cache_(0, info->zone()), |
540 script_(info->script()), | 610 script_(info->script()), |
541 scanner_(isolate_->unicode_cache()), | 611 scanner_(isolate_->unicode_cache()), |
542 reusable_preparser_(NULL), | 612 reusable_preparser_(NULL), |
543 top_scope_(NULL), | 613 top_scope_(NULL), |
544 original_scope_(NULL), | 614 original_scope_(NULL), |
545 current_function_state_(NULL), | 615 current_function_state_(NULL), |
546 target_stack_(NULL), | 616 target_stack_(NULL), |
547 extension_(info->extension()), | 617 extension_(info->extension()), |
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
786 if (result == NULL) { | 856 if (result == NULL) { |
787 if (stack_overflow()) isolate()->StackOverflow(); | 857 if (stack_overflow()) isolate()->StackOverflow(); |
788 } else { | 858 } else { |
789 Handle<String> inferred_name(shared_info->inferred_name()); | 859 Handle<String> inferred_name(shared_info->inferred_name()); |
790 result->set_inferred_name(inferred_name); | 860 result->set_inferred_name(inferred_name); |
791 } | 861 } |
792 return result; | 862 return result; |
793 } | 863 } |
794 | 864 |
795 | 865 |
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, | 866 void* Parser::ParseSourceElements(ZoneList<Statement*>* processor, |
853 int end_token, | 867 int end_token, |
854 bool is_eval, | 868 bool is_eval, |
855 bool is_global, | 869 bool is_global, |
856 bool* ok) { | 870 bool* ok) { |
857 // SourceElements :: | 871 // SourceElements :: |
858 // (ModuleElement)* <end_token> | 872 // (ModuleElement)* <end_token> |
859 | 873 |
860 // Allocate a target stack to use for this set of source | 874 // Allocate a target stack to use for this set of source |
861 // elements. This way, all scripts and functions get their own | 875 // 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); | 1088 Expect(Token::RBRACE, CHECK_OK); |
1075 scope->set_end_position(scanner().location().end_pos); | 1089 scope->set_end_position(scanner().location().end_pos); |
1076 body->set_scope(scope); | 1090 body->set_scope(scope); |
1077 | 1091 |
1078 // Check that all exports are bound. | 1092 // Check that all exports are bound. |
1079 Interface* interface = scope->interface(); | 1093 Interface* interface = scope->interface(); |
1080 for (Interface::Iterator it = interface->iterator(); | 1094 for (Interface::Iterator it = interface->iterator(); |
1081 !it.done(); it.Advance()) { | 1095 !it.done(); it.Advance()) { |
1082 if (scope->LocalLookup(it.name()) == NULL) { | 1096 if (scope->LocalLookup(it.name()) == NULL) { |
1083 Handle<String> name(it.name()); | 1097 Handle<String> name(it.name()); |
1084 ReportMessage("module_export_undefined", | 1098 traits_->ReportMessage("module_export_undefined", |
Michael Starzinger
2014/02/10 13:28:03
Likewise calling ReportMessage() wouldn't need an
marja
2014/02/10 15:02:07
Done.
| |
1085 Vector<Handle<String> >(&name, 1)); | 1099 Vector<Handle<String> >(&name, 1)); |
1086 *ok = false; | 1100 *ok = false; |
1087 return NULL; | 1101 return NULL; |
1088 } | 1102 } |
1089 } | 1103 } |
1090 | 1104 |
1091 interface->MakeModule(ok); | 1105 interface->MakeModule(ok); |
1092 ASSERT(*ok); | 1106 ASSERT(*ok); |
1093 interface->Freeze(ok); | 1107 interface->Freeze(ok); |
1094 ASSERT(*ok); | 1108 ASSERT(*ok); |
1095 return factory()->NewModuleLiteral(body, interface, pos); | 1109 return factory()->NewModuleLiteral(body, interface, pos); |
(...skipping 18 matching lines...) Expand all Loading... | |
1114 if (!*ok) { | 1128 if (!*ok) { |
1115 #ifdef DEBUG | 1129 #ifdef DEBUG |
1116 if (FLAG_print_interfaces) { | 1130 if (FLAG_print_interfaces) { |
1117 PrintF("PATH TYPE ERROR at '%s'\n", name->ToAsciiArray()); | 1131 PrintF("PATH TYPE ERROR at '%s'\n", name->ToAsciiArray()); |
1118 PrintF("result: "); | 1132 PrintF("result: "); |
1119 result->interface()->Print(); | 1133 result->interface()->Print(); |
1120 PrintF("member: "); | 1134 PrintF("member: "); |
1121 member->interface()->Print(); | 1135 member->interface()->Print(); |
1122 } | 1136 } |
1123 #endif | 1137 #endif |
1124 ReportMessage("invalid_module_path", Vector<Handle<String> >(&name, 1)); | 1138 traits_->ReportMessage("invalid_module_path", |
1139 Vector<Handle<String> >(&name, 1)); | |
1125 return NULL; | 1140 return NULL; |
1126 } | 1141 } |
1127 result = member; | 1142 result = member; |
1128 } | 1143 } |
1129 | 1144 |
1130 return result; | 1145 return result; |
1131 } | 1146 } |
1132 | 1147 |
1133 | 1148 |
1134 Module* Parser::ParseModuleVariable(bool* ok) { | 1149 Module* Parser::ParseModuleVariable(bool* ok) { |
(...skipping 13 matching lines...) Expand all Loading... | |
1148 return factory()->NewModuleVariable(proxy, pos); | 1163 return factory()->NewModuleVariable(proxy, pos); |
1149 } | 1164 } |
1150 | 1165 |
1151 | 1166 |
1152 Module* Parser::ParseModuleUrl(bool* ok) { | 1167 Module* Parser::ParseModuleUrl(bool* ok) { |
1153 // Module: | 1168 // Module: |
1154 // String | 1169 // String |
1155 | 1170 |
1156 int pos = peek_position(); | 1171 int pos = peek_position(); |
1157 Expect(Token::STRING, CHECK_OK); | 1172 Expect(Token::STRING, CHECK_OK); |
1158 Handle<String> symbol = GetSymbol(); | 1173 Handle<String> symbol = traits_->GetSymbol(); |
1159 | 1174 |
1160 // TODO(ES6): Request JS resource from environment... | 1175 // TODO(ES6): Request JS resource from environment... |
1161 | 1176 |
1162 #ifdef DEBUG | 1177 #ifdef DEBUG |
1163 if (FLAG_print_interface_details) PrintF("# Url "); | 1178 if (FLAG_print_interface_details) PrintF("# Url "); |
1164 #endif | 1179 #endif |
1165 | 1180 |
1166 // Create an empty literal as long as the feature isn't finished. | 1181 // Create an empty literal as long as the feature isn't finished. |
1167 USE(symbol); | 1182 USE(symbol); |
1168 Scope* scope = NewScope(top_scope_, MODULE_SCOPE); | 1183 Scope* scope = NewScope(top_scope_, MODULE_SCOPE); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1224 Interface* interface = Interface::NewUnknown(zone()); | 1239 Interface* interface = Interface::NewUnknown(zone()); |
1225 module->interface()->Add(names[i], interface, zone(), ok); | 1240 module->interface()->Add(names[i], interface, zone(), ok); |
1226 if (!*ok) { | 1241 if (!*ok) { |
1227 #ifdef DEBUG | 1242 #ifdef DEBUG |
1228 if (FLAG_print_interfaces) { | 1243 if (FLAG_print_interfaces) { |
1229 PrintF("IMPORT TYPE ERROR at '%s'\n", names[i]->ToAsciiArray()); | 1244 PrintF("IMPORT TYPE ERROR at '%s'\n", names[i]->ToAsciiArray()); |
1230 PrintF("module: "); | 1245 PrintF("module: "); |
1231 module->interface()->Print(); | 1246 module->interface()->Print(); |
1232 } | 1247 } |
1233 #endif | 1248 #endif |
1234 ReportMessage("invalid_module_path", Vector<Handle<String> >(&name, 1)); | 1249 traits_->ReportMessage("invalid_module_path", |
1250 Vector<Handle<String> >(&name, 1)); | |
1235 return NULL; | 1251 return NULL; |
1236 } | 1252 } |
1237 VariableProxy* proxy = NewUnresolved(names[i], LET, interface); | 1253 VariableProxy* proxy = NewUnresolved(names[i], LET, interface); |
1238 Declaration* declaration = | 1254 Declaration* declaration = |
1239 factory()->NewImportDeclaration(proxy, module, top_scope_, pos); | 1255 factory()->NewImportDeclaration(proxy, module, top_scope_, pos); |
1240 Declare(declaration, true, CHECK_OK); | 1256 Declare(declaration, true, CHECK_OK); |
1241 } | 1257 } |
1242 | 1258 |
1243 return block; | 1259 return block; |
1244 } | 1260 } |
(...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1612 if (!ok) { | 1628 if (!ok) { |
1613 #ifdef DEBUG | 1629 #ifdef DEBUG |
1614 if (FLAG_print_interfaces) { | 1630 if (FLAG_print_interfaces) { |
1615 PrintF("DECLARE TYPE ERROR\n"); | 1631 PrintF("DECLARE TYPE ERROR\n"); |
1616 PrintF("proxy: "); | 1632 PrintF("proxy: "); |
1617 proxy->interface()->Print(); | 1633 proxy->interface()->Print(); |
1618 PrintF("var: "); | 1634 PrintF("var: "); |
1619 var->interface()->Print(); | 1635 var->interface()->Print(); |
1620 } | 1636 } |
1621 #endif | 1637 #endif |
1622 ReportMessage("module_type_error", Vector<Handle<String> >(&name, 1)); | 1638 traits_->ReportMessage("module_type_error", |
1639 Vector<Handle<String> >(&name, 1)); | |
1623 } | 1640 } |
1624 } | 1641 } |
1625 } | 1642 } |
1626 } | 1643 } |
1627 | 1644 |
1628 | 1645 |
1629 // Language extension which is only enabled for source files loaded | 1646 // Language extension which is only enabled for source files loaded |
1630 // through the API's extension mechanism. A native function | 1647 // through the API's extension mechanism. A native function |
1631 // declaration is resolved by looking up the function through a | 1648 // declaration is resolved by looking up the function through a |
1632 // callback provided by the extension. | 1649 // callback provided by the extension. |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1770 // VariableDeclarations ';' | 1787 // VariableDeclarations ';' |
1771 | 1788 |
1772 Handle<String> ignore; | 1789 Handle<String> ignore; |
1773 Block* result = | 1790 Block* result = |
1774 ParseVariableDeclarations(var_context, NULL, names, &ignore, CHECK_OK); | 1791 ParseVariableDeclarations(var_context, NULL, names, &ignore, CHECK_OK); |
1775 ExpectSemicolon(CHECK_OK); | 1792 ExpectSemicolon(CHECK_OK); |
1776 return result; | 1793 return result; |
1777 } | 1794 } |
1778 | 1795 |
1779 | 1796 |
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 | 1797 // If the variable declaration declares exactly one non-const |
1787 // variable, then *out is set to that variable. In all other cases, | 1798 // variable, then *out is set to that variable. In all other cases, |
1788 // *out is untouched; in particular, it is the caller's responsibility | 1799 // *out is untouched; in particular, it is the caller's responsibility |
1789 // to initialize it properly. This mechanism is used for the parsing | 1800 // to initialize it properly. This mechanism is used for the parsing |
1790 // of 'for-in' loops. | 1801 // of 'for-in' loops. |
1791 Block* Parser::ParseVariableDeclarations( | 1802 Block* Parser::ParseVariableDeclarations( |
1792 VariableDeclarationContext var_context, | 1803 VariableDeclarationContext var_context, |
1793 VariableDeclarationProperties* decl_props, | 1804 VariableDeclarationProperties* decl_props, |
1794 ZoneStringList* names, | 1805 ZoneStringList* names, |
1795 Handle<String>* out, | 1806 Handle<String>* out, |
(...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2225 IterationStatement* target = NULL; | 2236 IterationStatement* target = NULL; |
2226 target = LookupContinueTarget(label, CHECK_OK); | 2237 target = LookupContinueTarget(label, CHECK_OK); |
2227 if (target == NULL) { | 2238 if (target == NULL) { |
2228 // Illegal continue statement. | 2239 // Illegal continue statement. |
2229 const char* message = "illegal_continue"; | 2240 const char* message = "illegal_continue"; |
2230 Vector<Handle<String> > args; | 2241 Vector<Handle<String> > args; |
2231 if (!label.is_null()) { | 2242 if (!label.is_null()) { |
2232 message = "unknown_label"; | 2243 message = "unknown_label"; |
2233 args = Vector<Handle<String> >(&label, 1); | 2244 args = Vector<Handle<String> >(&label, 1); |
2234 } | 2245 } |
2235 ReportMessageAt(scanner().location(), message, args); | 2246 traits_->ReportMessageAt(scanner().location(), message, args); |
2236 *ok = false; | 2247 *ok = false; |
2237 return NULL; | 2248 return NULL; |
2238 } | 2249 } |
2239 ExpectSemicolon(CHECK_OK); | 2250 ExpectSemicolon(CHECK_OK); |
2240 return factory()->NewContinueStatement(target, pos); | 2251 return factory()->NewContinueStatement(target, pos); |
2241 } | 2252 } |
2242 | 2253 |
2243 | 2254 |
2244 Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) { | 2255 Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) { |
2245 // BreakStatement :: | 2256 // BreakStatement :: |
(...skipping 17 matching lines...) Expand all Loading... | |
2263 BreakableStatement* target = NULL; | 2274 BreakableStatement* target = NULL; |
2264 target = LookupBreakTarget(label, CHECK_OK); | 2275 target = LookupBreakTarget(label, CHECK_OK); |
2265 if (target == NULL) { | 2276 if (target == NULL) { |
2266 // Illegal break statement. | 2277 // Illegal break statement. |
2267 const char* message = "illegal_break"; | 2278 const char* message = "illegal_break"; |
2268 Vector<Handle<String> > args; | 2279 Vector<Handle<String> > args; |
2269 if (!label.is_null()) { | 2280 if (!label.is_null()) { |
2270 message = "unknown_label"; | 2281 message = "unknown_label"; |
2271 args = Vector<Handle<String> >(&label, 1); | 2282 args = Vector<Handle<String> >(&label, 1); |
2272 } | 2283 } |
2273 ReportMessageAt(scanner().location(), message, args); | 2284 traits_->ReportMessageAt(scanner().location(), message, args); |
2274 *ok = false; | 2285 *ok = false; |
2275 return NULL; | 2286 return NULL; |
2276 } | 2287 } |
2277 ExpectSemicolon(CHECK_OK); | 2288 ExpectSemicolon(CHECK_OK); |
2278 return factory()->NewBreakStatement(target, pos); | 2289 return factory()->NewBreakStatement(target, pos); |
2279 } | 2290 } |
2280 | 2291 |
2281 | 2292 |
2282 Statement* Parser::ParseReturnStatement(bool* ok) { | 2293 Statement* Parser::ParseReturnStatement(bool* ok) { |
2283 // ReturnStatement :: | 2294 // ReturnStatement :: |
(...skipping 10 matching lines...) Expand all Loading... | |
2294 Expression* return_value; | 2305 Expression* return_value; |
2295 if (scanner().HasAnyLineTerminatorBeforeNext() || | 2306 if (scanner().HasAnyLineTerminatorBeforeNext() || |
2296 tok == Token::SEMICOLON || | 2307 tok == Token::SEMICOLON || |
2297 tok == Token::RBRACE || | 2308 tok == Token::RBRACE || |
2298 tok == Token::EOS) { | 2309 tok == Token::EOS) { |
2299 return_value = GetLiteralUndefined(position()); | 2310 return_value = GetLiteralUndefined(position()); |
2300 } else { | 2311 } else { |
2301 return_value = ParseExpression(true, CHECK_OK); | 2312 return_value = ParseExpression(true, CHECK_OK); |
2302 } | 2313 } |
2303 ExpectSemicolon(CHECK_OK); | 2314 ExpectSemicolon(CHECK_OK); |
2304 if (is_generator()) { | 2315 if (traits_->is_generator()) { |
2305 Expression* generator = factory()->NewVariableProxy( | 2316 Expression* generator = factory()->NewVariableProxy( |
2306 current_function_state_->generator_object_variable()); | 2317 current_function_state_->generator_object_variable()); |
2307 Expression* yield = factory()->NewYield( | 2318 Expression* yield = factory()->NewYield( |
2308 generator, return_value, Yield::FINAL, pos); | 2319 generator, return_value, Yield::FINAL, pos); |
2309 result = factory()->NewExpressionStatement(yield, pos); | 2320 result = factory()->NewExpressionStatement(yield, pos); |
2310 } else { | 2321 } else { |
2311 result = factory()->NewReturnStatement(return_value, pos); | 2322 result = factory()->NewReturnStatement(return_value, pos); |
2312 } | 2323 } |
2313 | 2324 |
2314 // An ECMAScript program is considered syntactically incorrect if it | 2325 // An ECMAScript program is considered syntactically incorrect if it |
(...skipping 580 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2895 } | 2906 } |
2896 | 2907 |
2897 | 2908 |
2898 // Precedence = 2 | 2909 // Precedence = 2 |
2899 Expression* Parser::ParseAssignmentExpression(bool accept_IN, bool* ok) { | 2910 Expression* Parser::ParseAssignmentExpression(bool accept_IN, bool* ok) { |
2900 // AssignmentExpression :: | 2911 // AssignmentExpression :: |
2901 // ConditionalExpression | 2912 // ConditionalExpression |
2902 // YieldExpression | 2913 // YieldExpression |
2903 // LeftHandSideExpression AssignmentOperator AssignmentExpression | 2914 // LeftHandSideExpression AssignmentOperator AssignmentExpression |
2904 | 2915 |
2905 if (peek() == Token::YIELD && is_generator()) { | 2916 if (peek() == Token::YIELD && traits_->is_generator()) { |
2906 return ParseYieldExpression(ok); | 2917 return ParseYieldExpression(ok); |
2907 } | 2918 } |
2908 | 2919 |
2909 if (fni_ != NULL) fni_->Enter(); | 2920 if (fni_ != NULL) fni_->Enter(); |
2910 Expression* expression = ParseConditionalExpression(accept_IN, CHECK_OK); | 2921 Expression* expression = ParseConditionalExpression(accept_IN, CHECK_OK); |
2911 | 2922 |
2912 if (!Token::IsAssignmentOp(peek())) { | 2923 if (!Token::IsAssignmentOp(peek())) { |
2913 if (fni_ != NULL) fni_->Leave(); | 2924 if (fni_ != NULL) fni_->Leave(); |
2914 // Parsed conditional expression only (no assignment). | 2925 // Parsed conditional expression only (no assignment). |
2915 return expression; | 2926 return expression; |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3006 // In parsing the first assignment expression in conditional | 3017 // In parsing the first assignment expression in conditional |
3007 // expressions we always accept the 'in' keyword; see ECMA-262, | 3018 // expressions we always accept the 'in' keyword; see ECMA-262, |
3008 // section 11.12, page 58. | 3019 // section 11.12, page 58. |
3009 Expression* left = ParseAssignmentExpression(true, CHECK_OK); | 3020 Expression* left = ParseAssignmentExpression(true, CHECK_OK); |
3010 Expect(Token::COLON, CHECK_OK); | 3021 Expect(Token::COLON, CHECK_OK); |
3011 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); | 3022 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); |
3012 return factory()->NewConditional(expression, left, right, pos); | 3023 return factory()->NewConditional(expression, left, right, pos); |
3013 } | 3024 } |
3014 | 3025 |
3015 | 3026 |
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 | 3027 // Precedence >= 4 |
3025 Expression* Parser::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) { | 3028 Expression* Parser::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) { |
3026 ASSERT(prec >= 4); | 3029 ASSERT(prec >= 4); |
3027 Expression* x = ParseUnaryExpression(CHECK_OK); | 3030 Expression* x = ParseUnaryExpression(CHECK_OK); |
3028 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { | 3031 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { |
3029 // prec1 >= 4 | 3032 // prec1 >= 4 |
3030 while (Precedence(peek(), accept_IN) == prec1) { | 3033 while (Precedence(peek(), accept_IN) == prec1) { |
3031 Token::Value op = Next(); | 3034 Token::Value op = Next(); |
3032 int pos = position(); | 3035 int pos = position(); |
3033 Expression* y = ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK); | 3036 Expression* y = ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK); |
(...skipping 502 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3536 double value = StringToDouble(isolate()->unicode_cache(), | 3539 double value = StringToDouble(isolate()->unicode_cache(), |
3537 scanner().literal_ascii_string(), | 3540 scanner().literal_ascii_string(), |
3538 ALLOW_HEX | ALLOW_OCTAL | | 3541 ALLOW_HEX | ALLOW_OCTAL | |
3539 ALLOW_IMPLICIT_OCTAL | ALLOW_BINARY); | 3542 ALLOW_IMPLICIT_OCTAL | ALLOW_BINARY); |
3540 result = factory()->NewNumberLiteral(value, pos); | 3543 result = factory()->NewNumberLiteral(value, pos); |
3541 break; | 3544 break; |
3542 } | 3545 } |
3543 | 3546 |
3544 case Token::STRING: { | 3547 case Token::STRING: { |
3545 Consume(Token::STRING); | 3548 Consume(Token::STRING); |
3546 Handle<String> symbol = GetSymbol(); | 3549 Handle<String> symbol = traits_->GetSymbol(); |
3547 result = factory()->NewLiteral(symbol, pos); | 3550 result = factory()->NewLiteral(symbol, pos); |
3548 if (fni_ != NULL) fni_->PushLiteralName(symbol); | 3551 if (fni_ != NULL) fni_->PushLiteralName(symbol); |
3549 break; | 3552 break; |
3550 } | 3553 } |
3551 | 3554 |
3552 case Token::ASSIGN_DIV: | 3555 case Token::ASSIGN_DIV: |
3553 result = ParseRegExpLiteral(true, CHECK_OK); | 3556 result = ParseRegExpLiteral(true, CHECK_OK); |
3554 break; | 3557 break; |
3555 | 3558 |
3556 case Token::DIV: | 3559 case Token::DIV: |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3714 // Unexpected token. | 3717 // Unexpected token. |
3715 ReportUnexpectedToken(next); | 3718 ReportUnexpectedToken(next); |
3716 *ok = false; | 3719 *ok = false; |
3717 return NULL; | 3720 return NULL; |
3718 } | 3721 } |
3719 // Validate the property. | 3722 // Validate the property. |
3720 PropertyKind type = is_getter ? kGetterProperty : kSetterProperty; | 3723 PropertyKind type = is_getter ? kGetterProperty : kSetterProperty; |
3721 checker.CheckProperty(next, type, CHECK_OK); | 3724 checker.CheckProperty(next, type, CHECK_OK); |
3722 Handle<String> name = is_keyword | 3725 Handle<String> name = is_keyword |
3723 ? isolate_->factory()->InternalizeUtf8String(Token::String(next)) | 3726 ? isolate_->factory()->InternalizeUtf8String(Token::String(next)) |
3724 : GetSymbol(); | 3727 : traits_->GetSymbol(); |
3725 FunctionLiteral* value = | 3728 FunctionLiteral* value = |
3726 ParseFunctionLiteral(name, | 3729 ParseFunctionLiteral(name, |
3727 scanner().location(), | 3730 scanner().location(), |
3728 false, // reserved words are allowed here | 3731 false, // reserved words are allowed here |
3729 false, // not a generator | 3732 false, // not a generator |
3730 RelocInfo::kNoPosition, | 3733 RelocInfo::kNoPosition, |
3731 FunctionLiteral::ANONYMOUS_EXPRESSION, | 3734 FunctionLiteral::ANONYMOUS_EXPRESSION, |
3732 CHECK_OK); | 3735 CHECK_OK); |
3733 // Allow any number of parameters for compatibilty with JSC. | 3736 // Allow any number of parameters for compatibilty with JSC. |
3734 // Specification only allows zero parameters for get and one for set. | 3737 // Specification only allows zero parameters for get and one for set. |
(...skipping 11 matching lines...) Expand all Loading... | |
3746 } | 3749 } |
3747 continue; // restart the while | 3750 continue; // restart the while |
3748 } | 3751 } |
3749 // Failed to parse as get/set property, so it's just a property | 3752 // Failed to parse as get/set property, so it's just a property |
3750 // called "get" or "set". | 3753 // called "get" or "set". |
3751 key = factory()->NewLiteral(id, next_pos); | 3754 key = factory()->NewLiteral(id, next_pos); |
3752 break; | 3755 break; |
3753 } | 3756 } |
3754 case Token::STRING: { | 3757 case Token::STRING: { |
3755 Consume(Token::STRING); | 3758 Consume(Token::STRING); |
3756 Handle<String> string = GetSymbol(); | 3759 Handle<String> string = traits_->GetSymbol(); |
3757 if (fni_ != NULL) fni_->PushLiteralName(string); | 3760 if (fni_ != NULL) fni_->PushLiteralName(string); |
3758 uint32_t index; | 3761 uint32_t index; |
3759 if (!string.is_null() && string->AsArrayIndex(&index)) { | 3762 if (!string.is_null() && string->AsArrayIndex(&index)) { |
3760 key = factory()->NewNumberLiteral(index, next_pos); | 3763 key = factory()->NewNumberLiteral(index, next_pos); |
3761 break; | 3764 break; |
3762 } | 3765 } |
3763 key = factory()->NewLiteral(string, next_pos); | 3766 key = factory()->NewLiteral(string, next_pos); |
3764 break; | 3767 break; |
3765 } | 3768 } |
3766 case Token::NUMBER: { | 3769 case Token::NUMBER: { |
3767 Consume(Token::NUMBER); | 3770 Consume(Token::NUMBER); |
3768 ASSERT(scanner().is_literal_ascii()); | 3771 ASSERT(scanner().is_literal_ascii()); |
3769 double value = StringToDouble(isolate()->unicode_cache(), | 3772 double value = StringToDouble(isolate()->unicode_cache(), |
3770 scanner().literal_ascii_string(), | 3773 scanner().literal_ascii_string(), |
3771 ALLOW_HEX | ALLOW_OCTAL | | 3774 ALLOW_HEX | ALLOW_OCTAL | |
3772 ALLOW_IMPLICIT_OCTAL | ALLOW_BINARY); | 3775 ALLOW_IMPLICIT_OCTAL | ALLOW_BINARY); |
3773 key = factory()->NewNumberLiteral(value, next_pos); | 3776 key = factory()->NewNumberLiteral(value, next_pos); |
3774 break; | 3777 break; |
3775 } | 3778 } |
3776 default: | 3779 default: |
3777 if (Token::IsKeyword(next)) { | 3780 if (Token::IsKeyword(next)) { |
3778 Consume(next); | 3781 Consume(next); |
3779 Handle<String> string = GetSymbol(); | 3782 Handle<String> string = traits_->GetSymbol(); |
3780 key = factory()->NewLiteral(string, next_pos); | 3783 key = factory()->NewLiteral(string, next_pos); |
3781 } else { | 3784 } else { |
3782 // Unexpected token. | 3785 // Unexpected token. |
3783 Token::Value next = Next(); | 3786 Token::Value next = Next(); |
3784 ReportUnexpectedToken(next); | 3787 ReportUnexpectedToken(next); |
3785 *ok = false; | 3788 *ok = false; |
3786 return NULL; | 3789 return NULL; |
3787 } | 3790 } |
3788 } | 3791 } |
3789 | 3792 |
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4074 Scanner::Location dupe_error_loc = Scanner::Location::invalid(); | 4077 Scanner::Location dupe_error_loc = Scanner::Location::invalid(); |
4075 Scanner::Location reserved_loc = Scanner::Location::invalid(); | 4078 Scanner::Location reserved_loc = Scanner::Location::invalid(); |
4076 | 4079 |
4077 bool done = (peek() == Token::RPAREN); | 4080 bool done = (peek() == Token::RPAREN); |
4078 while (!done) { | 4081 while (!done) { |
4079 bool is_strict_reserved = false; | 4082 bool is_strict_reserved = false; |
4080 Handle<String> param_name = | 4083 Handle<String> param_name = |
4081 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); | 4084 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); |
4082 | 4085 |
4083 // Store locations for possible future error reports. | 4086 // Store locations for possible future error reports. |
4084 if (!eval_args_error_log.IsValid() && IsEvalOrArguments(param_name)) { | 4087 if (!eval_args_error_log.IsValid() && |
4088 traits_->IsEvalOrArguments(param_name)) { | |
4085 eval_args_error_log = scanner().location(); | 4089 eval_args_error_log = scanner().location(); |
4086 } | 4090 } |
4087 if (!reserved_loc.IsValid() && is_strict_reserved) { | 4091 if (!reserved_loc.IsValid() && is_strict_reserved) { |
4088 reserved_loc = scanner().location(); | 4092 reserved_loc = scanner().location(); |
4089 } | 4093 } |
4090 if (!dupe_error_loc.IsValid() && top_scope_->IsDeclared(param_name)) { | 4094 if (!dupe_error_loc.IsValid() && top_scope_->IsDeclared(param_name)) { |
4091 duplicate_parameters = FunctionLiteral::kHasDuplicateParameters; | 4095 duplicate_parameters = FunctionLiteral::kHasDuplicateParameters; |
4092 dupe_error_loc = scanner().location(); | 4096 dupe_error_loc = scanner().location(); |
4093 } | 4097 } |
4094 | 4098 |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4254 expected_property_count = function_state.expected_property_count(); | 4258 expected_property_count = function_state.expected_property_count(); |
4255 handler_count = function_state.handler_count(); | 4259 handler_count = function_state.handler_count(); |
4256 | 4260 |
4257 Expect(Token::RBRACE, CHECK_OK); | 4261 Expect(Token::RBRACE, CHECK_OK); |
4258 scope->set_end_position(scanner().location().end_pos); | 4262 scope->set_end_position(scanner().location().end_pos); |
4259 } | 4263 } |
4260 | 4264 |
4261 // Validate strict mode. We can do this only after parsing the function, | 4265 // Validate strict mode. We can do this only after parsing the function, |
4262 // since the function can declare itself strict. | 4266 // since the function can declare itself strict. |
4263 if (!top_scope_->is_classic_mode()) { | 4267 if (!top_scope_->is_classic_mode()) { |
4264 if (IsEvalOrArguments(function_name)) { | 4268 if (traits_->IsEvalOrArguments(function_name)) { |
4265 ReportMessageAt(function_name_location, | 4269 ReportMessageAt(function_name_location, |
4266 "strict_eval_arguments", | 4270 "strict_eval_arguments", |
4267 Vector<const char*>::empty()); | 4271 Vector<const char*>::empty()); |
4268 *ok = false; | 4272 *ok = false; |
4269 return NULL; | 4273 return NULL; |
4270 } | 4274 } |
4271 if (name_is_strict_reserved) { | 4275 if (name_is_strict_reserved) { |
4272 ReportMessageAt(function_name_location, "unexpected_strict_reserved", | 4276 ReportMessageAt(function_name_location, "unexpected_strict_reserved", |
4273 Vector<const char*>::empty()); | 4277 Vector<const char*>::empty()); |
4274 *ok = false; | 4278 *ok = false; |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4337 reusable_preparser_ = new PreParser(&scanner_, NULL, stack_limit); | 4341 reusable_preparser_ = new PreParser(&scanner_, NULL, stack_limit); |
4338 reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping()); | 4342 reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping()); |
4339 reusable_preparser_->set_allow_modules(allow_modules()); | 4343 reusable_preparser_->set_allow_modules(allow_modules()); |
4340 reusable_preparser_->set_allow_natives_syntax(allow_natives_syntax()); | 4344 reusable_preparser_->set_allow_natives_syntax(allow_natives_syntax()); |
4341 reusable_preparser_->set_allow_lazy(true); | 4345 reusable_preparser_->set_allow_lazy(true); |
4342 reusable_preparser_->set_allow_generators(allow_generators()); | 4346 reusable_preparser_->set_allow_generators(allow_generators()); |
4343 reusable_preparser_->set_allow_for_of(allow_for_of()); | 4347 reusable_preparser_->set_allow_for_of(allow_for_of()); |
4344 reusable_preparser_->set_allow_harmony_numeric_literals( | 4348 reusable_preparser_->set_allow_harmony_numeric_literals( |
4345 allow_harmony_numeric_literals()); | 4349 allow_harmony_numeric_literals()); |
4346 } | 4350 } |
4347 PreParser::PreParseResult result = | 4351 PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction( |
4348 reusable_preparser_->PreParseLazyFunction(top_scope_->language_mode(), | 4352 top_scope_->language_mode(), traits_->is_generator(), logger); |
4349 is_generator(), | |
4350 logger); | |
4351 return result; | 4353 return result; |
4352 } | 4354 } |
4353 | 4355 |
4354 | 4356 |
4355 Expression* Parser::ParseV8Intrinsic(bool* ok) { | 4357 Expression* Parser::ParseV8Intrinsic(bool* ok) { |
4356 // CallRuntime :: | 4358 // CallRuntime :: |
4357 // '%' Identifier Arguments | 4359 // '%' Identifier Arguments |
4358 | 4360 |
4359 int pos = peek_position(); | 4361 int pos = peek_position(); |
4360 Expect(Token::MOD, CHECK_OK); | 4362 Expect(Token::MOD, CHECK_OK); |
(...skipping 29 matching lines...) Expand all Loading... | |
4390 if (function != NULL && | 4392 if (function != NULL && |
4391 function->nargs != -1 && | 4393 function->nargs != -1 && |
4392 function->nargs != args->length()) { | 4394 function->nargs != args->length()) { |
4393 ReportMessage("illegal_access", Vector<const char*>::empty()); | 4395 ReportMessage("illegal_access", Vector<const char*>::empty()); |
4394 *ok = false; | 4396 *ok = false; |
4395 return NULL; | 4397 return NULL; |
4396 } | 4398 } |
4397 | 4399 |
4398 // Check that the function is defined if it's an inline runtime call. | 4400 // Check that the function is defined if it's an inline runtime call. |
4399 if (function == NULL && name->Get(0) == '_') { | 4401 if (function == NULL && name->Get(0) == '_') { |
4400 ReportMessage("not_defined", Vector<Handle<String> >(&name, 1)); | 4402 traits_->ReportMessage("not_defined", Vector<Handle<String> >(&name, 1)); |
4401 *ok = false; | 4403 *ok = false; |
4402 return NULL; | 4404 return NULL; |
4403 } | 4405 } |
4404 | 4406 |
4405 // We have a valid intrinsics call or a call to a builtin. | 4407 // We have a valid intrinsics call or a call to a builtin. |
4406 return factory()->NewCallRuntime(name, function, args, pos); | 4408 return factory()->NewCallRuntime(name, function, args, pos); |
4407 } | 4409 } |
4408 | 4410 |
4409 | 4411 |
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) { | 4412 Literal* Parser::GetLiteralUndefined(int position) { |
4493 return factory()->NewLiteral( | 4413 return factory()->NewLiteral( |
4494 isolate()->factory()->undefined_value(), position); | 4414 isolate()->factory()->undefined_value(), position); |
4495 } | 4415 } |
4496 | 4416 |
4497 | 4417 |
4498 Literal* Parser::GetLiteralTheHole(int position) { | 4418 Literal* Parser::GetLiteralTheHole(int position) { |
4499 return factory()->NewLiteral( | 4419 return factory()->NewLiteral( |
4500 isolate()->factory()->the_hole_value(), RelocInfo::kNoPosition); | 4420 isolate()->factory()->the_hole_value(), RelocInfo::kNoPosition); |
4501 } | 4421 } |
4502 | 4422 |
4503 | 4423 |
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) { | 4424 void Parser::MarkAsLValue(Expression* expression) { |
4567 VariableProxy* proxy = expression != NULL | 4425 VariableProxy* proxy = expression != NULL |
4568 ? expression->AsVariableProxy() | 4426 ? expression->AsVariableProxy() |
4569 : NULL; | 4427 : NULL; |
4570 | 4428 |
4571 if (proxy != NULL) proxy->MarkAsLValue(); | 4429 if (proxy != NULL) proxy->MarkAsLValue(); |
4572 } | 4430 } |
4573 | 4431 |
4574 | 4432 |
4575 // Checks LHS expression for assignment and prefix/postfix increment/decrement | 4433 // Checks LHS expression for assignment and prefix/postfix increment/decrement |
4576 // in strict mode. | 4434 // in strict mode. |
4577 void Parser::CheckStrictModeLValue(Expression* expression, | 4435 void Parser::CheckStrictModeLValue(Expression* expression, |
4578 bool* ok) { | 4436 bool* ok) { |
4579 ASSERT(!top_scope_->is_classic_mode()); | 4437 ASSERT(!top_scope_->is_classic_mode()); |
4580 VariableProxy* lhs = expression != NULL | 4438 VariableProxy* lhs = expression != NULL |
4581 ? expression->AsVariableProxy() | 4439 ? expression->AsVariableProxy() |
4582 : NULL; | 4440 : NULL; |
4583 | 4441 |
4584 if (lhs != NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) { | 4442 if (lhs != NULL && !lhs->is_this() && |
4443 traits_->IsEvalOrArguments(lhs->name())) { | |
4585 ReportMessage("strict_eval_arguments", Vector<const char*>::empty()); | 4444 ReportMessage("strict_eval_arguments", Vector<const char*>::empty()); |
4586 *ok = false; | 4445 *ok = false; |
4587 } | 4446 } |
4588 } | 4447 } |
4589 | 4448 |
4590 | 4449 |
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) { | 4450 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) { |
4604 Declaration* decl = scope->CheckConflictingVarDeclarations(); | 4451 Declaration* decl = scope->CheckConflictingVarDeclarations(); |
4605 if (decl != NULL) { | 4452 if (decl != NULL) { |
4606 // In harmony mode we treat conflicting variable bindinds as early | 4453 // In harmony mode we treat conflicting variable bindinds as early |
4607 // errors. See ES5 16 for a definition of early errors. | 4454 // errors. See ES5 16 for a definition of early errors. |
4608 Handle<String> name = decl->proxy()->name(); | 4455 Handle<String> name = decl->proxy()->name(); |
4609 SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS); | 4456 SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS); |
4610 const char* elms[2] = { "Variable", c_string.get() }; | 4457 const char* elms[2] = { "Variable", c_string.get() }; |
4611 Vector<const char*> args(elms, 2); | 4458 Vector<const char*> args(elms, 2); |
4612 int position = decl->proxy()->position(); | 4459 int position = decl->proxy()->position(); |
4613 Scanner::Location location = position == RelocInfo::kNoPosition | 4460 Scanner::Location location = position == RelocInfo::kNoPosition |
4614 ? Scanner::Location::invalid() | 4461 ? Scanner::Location::invalid() |
4615 : Scanner::Location(position, position + 1); | 4462 : Scanner::Location(position, position + 1); |
4616 ReportMessageAt(location, "redeclaration", args); | 4463 ReportMessageAt(location, "redeclaration", args); |
4617 *ok = false; | 4464 *ok = false; |
4618 } | 4465 } |
4619 } | 4466 } |
4620 | 4467 |
4621 | 4468 |
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 // ---------------------------------------------------------------------------- | 4469 // ---------------------------------------------------------------------------- |
4639 // Parser support | 4470 // Parser support |
4640 | 4471 |
4641 | 4472 |
4642 bool Parser::TargetStackContainsLabel(Handle<String> label) { | 4473 bool Parser::TargetStackContainsLabel(Handle<String> label) { |
4643 for (Target* t = target_stack_; t != NULL; t = t->previous()) { | 4474 for (Target* t = target_stack_; t != NULL; t = t->previous()) { |
4644 BreakableStatement* stat = t->node()->AsBreakableStatement(); | 4475 BreakableStatement* stat = t->node()->AsBreakableStatement(); |
4645 if (stat != NULL && ContainsLabel(stat->labels(), label)) | 4476 if (stat != NULL && ContainsLabel(stat->labels(), label)) |
4646 return true; | 4477 return true; |
4647 } | 4478 } |
(...skipping 1044 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5692 ASSERT(info()->isolate()->has_pending_exception()); | 5523 ASSERT(info()->isolate()->has_pending_exception()); |
5693 } else { | 5524 } else { |
5694 result = ParseProgram(); | 5525 result = ParseProgram(); |
5695 } | 5526 } |
5696 } | 5527 } |
5697 info()->SetFunction(result); | 5528 info()->SetFunction(result); |
5698 return (result != NULL); | 5529 return (result != NULL); |
5699 } | 5530 } |
5700 | 5531 |
5701 } } // namespace v8::internal | 5532 } } // namespace v8::internal |
OLD | NEW |