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

Side by Side Diff: src/parser.cc

Issue 149913006: Traitify ParserBase and move functions there. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: . Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698