| 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 518 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 529 #define CHECK_FAILED /**/); \ | 529 #define CHECK_FAILED /**/); \ |
| 530 if (failed_) return NULL; \ | 530 if (failed_) return NULL; \ |
| 531 ((void)0 | 531 ((void)0 |
| 532 #define DUMMY ) // to make indentation work | 532 #define DUMMY ) // to make indentation work |
| 533 #undef DUMMY | 533 #undef DUMMY |
| 534 | 534 |
| 535 // ---------------------------------------------------------------------------- | 535 // ---------------------------------------------------------------------------- |
| 536 // Implementation of Parser | 536 // Implementation of Parser |
| 537 | 537 |
| 538 Parser::Parser(CompilationInfo* info) | 538 Parser::Parser(CompilationInfo* info) |
| 539 : isolate_(info->isolate()), | 539 : ParserBase(&scanner_, info->isolate()->stack_guard()->real_climit()), |
| 540 isolate_(info->isolate()), |
| 540 symbol_cache_(0, info->zone()), | 541 symbol_cache_(0, info->zone()), |
| 541 script_(info->script()), | 542 script_(info->script()), |
| 542 scanner_(isolate_->unicode_cache()), | 543 scanner_(isolate_->unicode_cache()), |
| 543 reusable_preparser_(NULL), | 544 reusable_preparser_(NULL), |
| 544 top_scope_(NULL), | 545 top_scope_(NULL), |
| 545 original_scope_(NULL), | 546 original_scope_(NULL), |
| 546 current_function_state_(NULL), | 547 current_function_state_(NULL), |
| 547 target_stack_(NULL), | 548 target_stack_(NULL), |
| 548 extension_(info->extension()), | 549 extension_(info->extension()), |
| 549 pre_parse_data_(NULL), | 550 pre_parse_data_(NULL), |
| 550 fni_(NULL), | 551 fni_(NULL), |
| 551 allow_natives_syntax_(false), | |
| 552 allow_lazy_(false), | |
| 553 allow_generators_(false), | |
| 554 allow_for_of_(false), | |
| 555 stack_overflow_(false), | |
| 556 parenthesized_function_(false), | 552 parenthesized_function_(false), |
| 557 zone_(info->zone()), | 553 zone_(info->zone()), |
| 558 info_(info) { | 554 info_(info) { |
| 559 ASSERT(!script_.is_null()); | 555 ASSERT(!script_.is_null()); |
| 560 isolate_->set_ast_node_id(0); | 556 isolate_->set_ast_node_id(0); |
| 561 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); | 557 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); |
| 562 set_allow_modules(!info->is_native() && FLAG_harmony_modules); | 558 set_allow_modules(!info->is_native() && FLAG_harmony_modules); |
| 563 set_allow_natives_syntax(FLAG_allow_natives_syntax || info->is_native()); | 559 set_allow_natives_syntax(FLAG_allow_natives_syntax || info->is_native()); |
| 564 set_allow_lazy(false); // Must be explicitly enabled. | 560 set_allow_lazy(false); // Must be explicitly enabled. |
| 565 set_allow_generators(FLAG_harmony_generators); | 561 set_allow_generators(FLAG_harmony_generators); |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 645 mode = PARSE_EAGERLY; | 641 mode = PARSE_EAGERLY; |
| 646 } | 642 } |
| 647 ParsingModeScope parsing_mode(this, mode); | 643 ParsingModeScope parsing_mode(this, mode); |
| 648 | 644 |
| 649 // Enters 'scope'. | 645 // Enters 'scope'. |
| 650 FunctionState function_state(this, scope, isolate()); | 646 FunctionState function_state(this, scope, isolate()); |
| 651 | 647 |
| 652 top_scope_->SetLanguageMode(info->language_mode()); | 648 top_scope_->SetLanguageMode(info->language_mode()); |
| 653 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); | 649 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); |
| 654 bool ok = true; | 650 bool ok = true; |
| 655 int beg_loc = scanner().location().beg_pos; | 651 int beg_pos = scanner().location().beg_pos; |
| 656 ParseSourceElements(body, Token::EOS, info->is_eval(), true, &ok); | 652 ParseSourceElements(body, Token::EOS, info->is_eval(), true, &ok); |
| 657 if (ok && !top_scope_->is_classic_mode()) { | 653 if (ok && !top_scope_->is_classic_mode()) { |
| 658 CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok); | 654 CheckOctalLiteral(beg_pos, scanner().location().end_pos, &ok); |
| 659 } | 655 } |
| 660 | 656 |
| 661 if (ok && is_extended_mode()) { | 657 if (ok && is_extended_mode()) { |
| 662 CheckConflictingVarDeclarations(top_scope_, &ok); | 658 CheckConflictingVarDeclarations(top_scope_, &ok); |
| 663 } | 659 } |
| 664 | 660 |
| 665 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) { | 661 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) { |
| 666 if (body->length() != 1 || | 662 if (body->length() != 1 || |
| 667 !body->at(0)->IsExpressionStatement() || | 663 !body->at(0)->IsExpressionStatement() || |
| 668 !body->at(0)->AsExpressionStatement()-> | 664 !body->at(0)->AsExpressionStatement()-> |
| 669 expression()->IsFunctionLiteral()) { | 665 expression()->IsFunctionLiteral()) { |
| 670 ReportMessage("single_function_literal", Vector<const char*>::empty()); | 666 ReportMessage("single_function_literal", Vector<const char*>::empty()); |
| 671 ok = false; | 667 ok = false; |
| 672 } | 668 } |
| 673 } | 669 } |
| 674 | 670 |
| 675 if (ok) { | 671 if (ok) { |
| 676 result = factory()->NewFunctionLiteral( | 672 result = factory()->NewFunctionLiteral( |
| 677 no_name, | 673 no_name, |
| 678 top_scope_, | 674 top_scope_, |
| 679 body, | 675 body, |
| 680 function_state.materialized_literal_count(), | 676 function_state.materialized_literal_count(), |
| 681 function_state.expected_property_count(), | 677 function_state.expected_property_count(), |
| 682 function_state.handler_count(), | 678 function_state.handler_count(), |
| 683 0, | 679 0, |
| 684 FunctionLiteral::kNoDuplicateParameters, | 680 FunctionLiteral::kNoDuplicateParameters, |
| 685 FunctionLiteral::ANONYMOUS_EXPRESSION, | 681 FunctionLiteral::ANONYMOUS_EXPRESSION, |
| 686 FunctionLiteral::kGlobalOrEval, | 682 FunctionLiteral::kGlobalOrEval, |
| 687 FunctionLiteral::kNotParenthesized, | 683 FunctionLiteral::kNotParenthesized, |
| 688 FunctionLiteral::kNotGenerator); | 684 FunctionLiteral::kNotGenerator, |
| 685 0); |
| 689 result->set_ast_properties(factory()->visitor()->ast_properties()); | 686 result->set_ast_properties(factory()->visitor()->ast_properties()); |
| 690 result->set_dont_optimize_reason( | 687 result->set_dont_optimize_reason( |
| 691 factory()->visitor()->dont_optimize_reason()); | 688 factory()->visitor()->dont_optimize_reason()); |
| 692 } else if (stack_overflow_) { | 689 } else if (stack_overflow()) { |
| 693 isolate()->StackOverflow(); | 690 isolate()->StackOverflow(); |
| 694 } | 691 } |
| 695 } | 692 } |
| 696 | 693 |
| 697 // Make sure the target stack is empty. | 694 // Make sure the target stack is empty. |
| 698 ASSERT(target_stack_ == NULL); | 695 ASSERT(target_stack_ == NULL); |
| 699 | 696 |
| 700 return result; | 697 return result; |
| 701 } | 698 } |
| 702 | 699 |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 779 function_type, | 776 function_type, |
| 780 &ok); | 777 &ok); |
| 781 // Make sure the results agree. | 778 // Make sure the results agree. |
| 782 ASSERT(ok == (result != NULL)); | 779 ASSERT(ok == (result != NULL)); |
| 783 } | 780 } |
| 784 | 781 |
| 785 // Make sure the target stack is empty. | 782 // Make sure the target stack is empty. |
| 786 ASSERT(target_stack_ == NULL); | 783 ASSERT(target_stack_ == NULL); |
| 787 | 784 |
| 788 if (result == NULL) { | 785 if (result == NULL) { |
| 789 if (stack_overflow_) isolate()->StackOverflow(); | 786 if (stack_overflow()) isolate()->StackOverflow(); |
| 790 } else { | 787 } else { |
| 791 Handle<String> inferred_name(shared_info->inferred_name()); | 788 Handle<String> inferred_name(shared_info->inferred_name()); |
| 792 result->set_inferred_name(inferred_name); | 789 result->set_inferred_name(inferred_name); |
| 793 } | 790 } |
| 794 return result; | 791 return result; |
| 795 } | 792 } |
| 796 | 793 |
| 797 | 794 |
| 798 Handle<String> Parser::GetSymbol() { | 795 Handle<String> Parser::GetSymbol() { |
| 799 int symbol_id = -1; | 796 int symbol_id = -1; |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 977 return stmt; | 974 return stmt; |
| 978 } | 975 } |
| 979 } | 976 } |
| 980 } | 977 } |
| 981 | 978 |
| 982 | 979 |
| 983 Statement* Parser::ParseModuleDeclaration(ZoneStringList* names, bool* ok) { | 980 Statement* Parser::ParseModuleDeclaration(ZoneStringList* names, bool* ok) { |
| 984 // ModuleDeclaration: | 981 // ModuleDeclaration: |
| 985 // 'module' Identifier Module | 982 // 'module' Identifier Module |
| 986 | 983 |
| 984 int pos = peek_position(); |
| 987 Handle<String> name = ParseIdentifier(CHECK_OK); | 985 Handle<String> name = ParseIdentifier(CHECK_OK); |
| 988 | 986 |
| 989 #ifdef DEBUG | 987 #ifdef DEBUG |
| 990 if (FLAG_print_interface_details) | 988 if (FLAG_print_interface_details) |
| 991 PrintF("# Module %s...\n", name->ToAsciiArray()); | 989 PrintF("# Module %s...\n", name->ToAsciiArray()); |
| 992 #endif | 990 #endif |
| 993 | 991 |
| 994 Module* module = ParseModule(CHECK_OK); | 992 Module* module = ParseModule(CHECK_OK); |
| 995 VariableProxy* proxy = NewUnresolved(name, MODULE, module->interface()); | 993 VariableProxy* proxy = NewUnresolved(name, MODULE, module->interface()); |
| 996 Declaration* declaration = | 994 Declaration* declaration = |
| 997 factory()->NewModuleDeclaration(proxy, module, top_scope_); | 995 factory()->NewModuleDeclaration(proxy, module, top_scope_, pos); |
| 998 Declare(declaration, true, CHECK_OK); | 996 Declare(declaration, true, CHECK_OK); |
| 999 | 997 |
| 1000 #ifdef DEBUG | 998 #ifdef DEBUG |
| 1001 if (FLAG_print_interface_details) | 999 if (FLAG_print_interface_details) |
| 1002 PrintF("# Module %s.\n", name->ToAsciiArray()); | 1000 PrintF("# Module %s.\n", name->ToAsciiArray()); |
| 1003 | 1001 |
| 1004 if (FLAG_print_interfaces) { | 1002 if (FLAG_print_interfaces) { |
| 1005 PrintF("module %s : ", name->ToAsciiArray()); | 1003 PrintF("module %s : ", name->ToAsciiArray()); |
| 1006 module->interface()->Print(); | 1004 module->interface()->Print(); |
| 1007 } | 1005 } |
| 1008 #endif | 1006 #endif |
| 1009 | 1007 |
| 1010 if (names) names->Add(name, zone()); | 1008 if (names) names->Add(name, zone()); |
| 1011 if (module->body() == NULL) | 1009 if (module->body() == NULL) |
| 1012 return factory()->NewEmptyStatement(); | 1010 return factory()->NewEmptyStatement(pos); |
| 1013 else | 1011 else |
| 1014 return factory()->NewModuleStatement(proxy, module->body()); | 1012 return factory()->NewModuleStatement(proxy, module->body(), pos); |
| 1015 } | 1013 } |
| 1016 | 1014 |
| 1017 | 1015 |
| 1018 Module* Parser::ParseModule(bool* ok) { | 1016 Module* Parser::ParseModule(bool* ok) { |
| 1019 // Module: | 1017 // Module: |
| 1020 // '{' ModuleElement '}' | 1018 // '{' ModuleElement '}' |
| 1021 // '=' ModulePath ';' | 1019 // '=' ModulePath ';' |
| 1022 // 'at' String ';' | 1020 // 'at' String ';' |
| 1023 | 1021 |
| 1024 switch (peek()) { | 1022 switch (peek()) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1039 return result; | 1037 return result; |
| 1040 } | 1038 } |
| 1041 } | 1039 } |
| 1042 } | 1040 } |
| 1043 | 1041 |
| 1044 | 1042 |
| 1045 Module* Parser::ParseModuleLiteral(bool* ok) { | 1043 Module* Parser::ParseModuleLiteral(bool* ok) { |
| 1046 // Module: | 1044 // Module: |
| 1047 // '{' ModuleElement '}' | 1045 // '{' ModuleElement '}' |
| 1048 | 1046 |
| 1047 int pos = peek_position(); |
| 1049 // Construct block expecting 16 statements. | 1048 // Construct block expecting 16 statements. |
| 1050 Block* body = factory()->NewBlock(NULL, 16, false); | 1049 Block* body = factory()->NewBlock(NULL, 16, false, RelocInfo::kNoPosition); |
| 1051 #ifdef DEBUG | 1050 #ifdef DEBUG |
| 1052 if (FLAG_print_interface_details) PrintF("# Literal "); | 1051 if (FLAG_print_interface_details) PrintF("# Literal "); |
| 1053 #endif | 1052 #endif |
| 1054 Scope* scope = NewScope(top_scope_, MODULE_SCOPE); | 1053 Scope* scope = NewScope(top_scope_, MODULE_SCOPE); |
| 1055 | 1054 |
| 1056 Expect(Token::LBRACE, CHECK_OK); | 1055 Expect(Token::LBRACE, CHECK_OK); |
| 1057 scope->set_start_position(scanner().location().beg_pos); | 1056 scope->set_start_position(scanner().location().beg_pos); |
| 1058 scope->SetLanguageMode(EXTENDED_MODE); | 1057 scope->SetLanguageMode(EXTENDED_MODE); |
| 1059 | 1058 |
| 1060 { | 1059 { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1085 Vector<Handle<String> >(&name, 1)); | 1084 Vector<Handle<String> >(&name, 1)); |
| 1086 *ok = false; | 1085 *ok = false; |
| 1087 return NULL; | 1086 return NULL; |
| 1088 } | 1087 } |
| 1089 } | 1088 } |
| 1090 | 1089 |
| 1091 interface->MakeModule(ok); | 1090 interface->MakeModule(ok); |
| 1092 ASSERT(*ok); | 1091 ASSERT(*ok); |
| 1093 interface->Freeze(ok); | 1092 interface->Freeze(ok); |
| 1094 ASSERT(*ok); | 1093 ASSERT(*ok); |
| 1095 return factory()->NewModuleLiteral(body, interface); | 1094 return factory()->NewModuleLiteral(body, interface, pos); |
| 1096 } | 1095 } |
| 1097 | 1096 |
| 1098 | 1097 |
| 1099 Module* Parser::ParseModulePath(bool* ok) { | 1098 Module* Parser::ParseModulePath(bool* ok) { |
| 1100 // ModulePath: | 1099 // ModulePath: |
| 1101 // Identifier | 1100 // Identifier |
| 1102 // ModulePath '.' Identifier | 1101 // ModulePath '.' Identifier |
| 1103 | 1102 |
| 1103 int pos = peek_position(); |
| 1104 Module* result = ParseModuleVariable(CHECK_OK); | 1104 Module* result = ParseModuleVariable(CHECK_OK); |
| 1105 while (Check(Token::PERIOD)) { | 1105 while (Check(Token::PERIOD)) { |
| 1106 Handle<String> name = ParseIdentifierName(CHECK_OK); | 1106 Handle<String> name = ParseIdentifierName(CHECK_OK); |
| 1107 #ifdef DEBUG | 1107 #ifdef DEBUG |
| 1108 if (FLAG_print_interface_details) | 1108 if (FLAG_print_interface_details) |
| 1109 PrintF("# Path .%s ", name->ToAsciiArray()); | 1109 PrintF("# Path .%s ", name->ToAsciiArray()); |
| 1110 #endif | 1110 #endif |
| 1111 Module* member = factory()->NewModulePath(result, name); | 1111 Module* member = factory()->NewModulePath(result, name, pos); |
| 1112 result->interface()->Add(name, member->interface(), zone(), ok); | 1112 result->interface()->Add(name, member->interface(), zone(), ok); |
| 1113 if (!*ok) { | 1113 if (!*ok) { |
| 1114 #ifdef DEBUG | 1114 #ifdef DEBUG |
| 1115 if (FLAG_print_interfaces) { | 1115 if (FLAG_print_interfaces) { |
| 1116 PrintF("PATH TYPE ERROR at '%s'\n", name->ToAsciiArray()); | 1116 PrintF("PATH TYPE ERROR at '%s'\n", name->ToAsciiArray()); |
| 1117 PrintF("result: "); | 1117 PrintF("result: "); |
| 1118 result->interface()->Print(); | 1118 result->interface()->Print(); |
| 1119 PrintF("member: "); | 1119 PrintF("member: "); |
| 1120 member->interface()->Print(); | 1120 member->interface()->Print(); |
| 1121 } | 1121 } |
| 1122 #endif | 1122 #endif |
| 1123 ReportMessage("invalid_module_path", Vector<Handle<String> >(&name, 1)); | 1123 ReportMessage("invalid_module_path", Vector<Handle<String> >(&name, 1)); |
| 1124 return NULL; | 1124 return NULL; |
| 1125 } | 1125 } |
| 1126 result = member; | 1126 result = member; |
| 1127 } | 1127 } |
| 1128 | 1128 |
| 1129 return result; | 1129 return result; |
| 1130 } | 1130 } |
| 1131 | 1131 |
| 1132 | 1132 |
| 1133 Module* Parser::ParseModuleVariable(bool* ok) { | 1133 Module* Parser::ParseModuleVariable(bool* ok) { |
| 1134 // ModulePath: | 1134 // ModulePath: |
| 1135 // Identifier | 1135 // Identifier |
| 1136 | 1136 |
| 1137 int pos = peek_position(); |
| 1137 Handle<String> name = ParseIdentifier(CHECK_OK); | 1138 Handle<String> name = ParseIdentifier(CHECK_OK); |
| 1138 #ifdef DEBUG | 1139 #ifdef DEBUG |
| 1139 if (FLAG_print_interface_details) | 1140 if (FLAG_print_interface_details) |
| 1140 PrintF("# Module variable %s ", name->ToAsciiArray()); | 1141 PrintF("# Module variable %s ", name->ToAsciiArray()); |
| 1141 #endif | 1142 #endif |
| 1142 VariableProxy* proxy = top_scope_->NewUnresolved( | 1143 VariableProxy* proxy = top_scope_->NewUnresolved( |
| 1143 factory(), name, Interface::NewModule(zone()), | 1144 factory(), name, Interface::NewModule(zone()), |
| 1144 scanner().location().beg_pos); | 1145 scanner().location().beg_pos); |
| 1145 | 1146 |
| 1146 return factory()->NewModuleVariable(proxy); | 1147 return factory()->NewModuleVariable(proxy, pos); |
| 1147 } | 1148 } |
| 1148 | 1149 |
| 1149 | 1150 |
| 1150 Module* Parser::ParseModuleUrl(bool* ok) { | 1151 Module* Parser::ParseModuleUrl(bool* ok) { |
| 1151 // Module: | 1152 // Module: |
| 1152 // String | 1153 // String |
| 1153 | 1154 |
| 1155 int pos = peek_position(); |
| 1154 Expect(Token::STRING, CHECK_OK); | 1156 Expect(Token::STRING, CHECK_OK); |
| 1155 Handle<String> symbol = GetSymbol(); | 1157 Handle<String> symbol = GetSymbol(); |
| 1156 | 1158 |
| 1157 // TODO(ES6): Request JS resource from environment... | 1159 // TODO(ES6): Request JS resource from environment... |
| 1158 | 1160 |
| 1159 #ifdef DEBUG | 1161 #ifdef DEBUG |
| 1160 if (FLAG_print_interface_details) PrintF("# Url "); | 1162 if (FLAG_print_interface_details) PrintF("# Url "); |
| 1161 #endif | 1163 #endif |
| 1162 | 1164 |
| 1163 // Create an empty literal as long as the feature isn't finished. | 1165 // Create an empty literal as long as the feature isn't finished. |
| 1164 USE(symbol); | 1166 USE(symbol); |
| 1165 Scope* scope = NewScope(top_scope_, MODULE_SCOPE); | 1167 Scope* scope = NewScope(top_scope_, MODULE_SCOPE); |
| 1166 Block* body = factory()->NewBlock(NULL, 1, false); | 1168 Block* body = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition); |
| 1167 body->set_scope(scope); | 1169 body->set_scope(scope); |
| 1168 Interface* interface = scope->interface(); | 1170 Interface* interface = scope->interface(); |
| 1169 Module* result = factory()->NewModuleLiteral(body, interface); | 1171 Module* result = factory()->NewModuleLiteral(body, interface, pos); |
| 1170 interface->Freeze(ok); | 1172 interface->Freeze(ok); |
| 1171 ASSERT(*ok); | 1173 ASSERT(*ok); |
| 1172 interface->Unify(scope->interface(), zone(), ok); | 1174 interface->Unify(scope->interface(), zone(), ok); |
| 1173 ASSERT(*ok); | 1175 ASSERT(*ok); |
| 1174 return result; | 1176 return result; |
| 1175 } | 1177 } |
| 1176 | 1178 |
| 1177 | 1179 |
| 1178 Module* Parser::ParseModuleSpecifier(bool* ok) { | 1180 Module* Parser::ParseModuleSpecifier(bool* ok) { |
| 1179 // ModuleSpecifier: | 1181 // ModuleSpecifier: |
| 1180 // String | 1182 // String |
| 1181 // ModulePath | 1183 // ModulePath |
| 1182 | 1184 |
| 1183 if (peek() == Token::STRING) { | 1185 if (peek() == Token::STRING) { |
| 1184 return ParseModuleUrl(ok); | 1186 return ParseModuleUrl(ok); |
| 1185 } else { | 1187 } else { |
| 1186 return ParseModulePath(ok); | 1188 return ParseModulePath(ok); |
| 1187 } | 1189 } |
| 1188 } | 1190 } |
| 1189 | 1191 |
| 1190 | 1192 |
| 1191 Block* Parser::ParseImportDeclaration(bool* ok) { | 1193 Block* Parser::ParseImportDeclaration(bool* ok) { |
| 1192 // ImportDeclaration: | 1194 // ImportDeclaration: |
| 1193 // 'import' IdentifierName (',' IdentifierName)* 'from' ModuleSpecifier ';' | 1195 // 'import' IdentifierName (',' IdentifierName)* 'from' ModuleSpecifier ';' |
| 1194 // | 1196 // |
| 1195 // TODO(ES6): implement destructuring ImportSpecifiers | 1197 // TODO(ES6): implement destructuring ImportSpecifiers |
| 1196 | 1198 |
| 1199 int pos = peek_position(); |
| 1197 Expect(Token::IMPORT, CHECK_OK); | 1200 Expect(Token::IMPORT, CHECK_OK); |
| 1198 ZoneStringList names(1, zone()); | 1201 ZoneStringList names(1, zone()); |
| 1199 | 1202 |
| 1200 Handle<String> name = ParseIdentifierName(CHECK_OK); | 1203 Handle<String> name = ParseIdentifierName(CHECK_OK); |
| 1201 names.Add(name, zone()); | 1204 names.Add(name, zone()); |
| 1202 while (peek() == Token::COMMA) { | 1205 while (peek() == Token::COMMA) { |
| 1203 Consume(Token::COMMA); | 1206 Consume(Token::COMMA); |
| 1204 name = ParseIdentifierName(CHECK_OK); | 1207 name = ParseIdentifierName(CHECK_OK); |
| 1205 names.Add(name, zone()); | 1208 names.Add(name, zone()); |
| 1206 } | 1209 } |
| 1207 | 1210 |
| 1208 ExpectContextualKeyword(CStrVector("from"), CHECK_OK); | 1211 ExpectContextualKeyword(CStrVector("from"), CHECK_OK); |
| 1209 Module* module = ParseModuleSpecifier(CHECK_OK); | 1212 Module* module = ParseModuleSpecifier(CHECK_OK); |
| 1210 ExpectSemicolon(CHECK_OK); | 1213 ExpectSemicolon(CHECK_OK); |
| 1211 | 1214 |
| 1212 // Generate a separate declaration for each identifier. | 1215 // Generate a separate declaration for each identifier. |
| 1213 // TODO(ES6): once we implement destructuring, make that one declaration. | 1216 // TODO(ES6): once we implement destructuring, make that one declaration. |
| 1214 Block* block = factory()->NewBlock(NULL, 1, true); | 1217 Block* block = factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition); |
| 1215 for (int i = 0; i < names.length(); ++i) { | 1218 for (int i = 0; i < names.length(); ++i) { |
| 1216 #ifdef DEBUG | 1219 #ifdef DEBUG |
| 1217 if (FLAG_print_interface_details) | 1220 if (FLAG_print_interface_details) |
| 1218 PrintF("# Import %s ", names[i]->ToAsciiArray()); | 1221 PrintF("# Import %s ", names[i]->ToAsciiArray()); |
| 1219 #endif | 1222 #endif |
| 1220 Interface* interface = Interface::NewUnknown(zone()); | 1223 Interface* interface = Interface::NewUnknown(zone()); |
| 1221 module->interface()->Add(names[i], interface, zone(), ok); | 1224 module->interface()->Add(names[i], interface, zone(), ok); |
| 1222 if (!*ok) { | 1225 if (!*ok) { |
| 1223 #ifdef DEBUG | 1226 #ifdef DEBUG |
| 1224 if (FLAG_print_interfaces) { | 1227 if (FLAG_print_interfaces) { |
| 1225 PrintF("IMPORT TYPE ERROR at '%s'\n", names[i]->ToAsciiArray()); | 1228 PrintF("IMPORT TYPE ERROR at '%s'\n", names[i]->ToAsciiArray()); |
| 1226 PrintF("module: "); | 1229 PrintF("module: "); |
| 1227 module->interface()->Print(); | 1230 module->interface()->Print(); |
| 1228 } | 1231 } |
| 1229 #endif | 1232 #endif |
| 1230 ReportMessage("invalid_module_path", Vector<Handle<String> >(&name, 1)); | 1233 ReportMessage("invalid_module_path", Vector<Handle<String> >(&name, 1)); |
| 1231 return NULL; | 1234 return NULL; |
| 1232 } | 1235 } |
| 1233 VariableProxy* proxy = NewUnresolved(names[i], LET, interface); | 1236 VariableProxy* proxy = NewUnresolved(names[i], LET, interface); |
| 1234 Declaration* declaration = | 1237 Declaration* declaration = |
| 1235 factory()->NewImportDeclaration(proxy, module, top_scope_); | 1238 factory()->NewImportDeclaration(proxy, module, top_scope_, pos); |
| 1236 Declare(declaration, true, CHECK_OK); | 1239 Declare(declaration, true, CHECK_OK); |
| 1237 } | 1240 } |
| 1238 | 1241 |
| 1239 return block; | 1242 return block; |
| 1240 } | 1243 } |
| 1241 | 1244 |
| 1242 | 1245 |
| 1243 Statement* Parser::ParseExportDeclaration(bool* ok) { | 1246 Statement* Parser::ParseExportDeclaration(bool* ok) { |
| 1244 // ExportDeclaration: | 1247 // ExportDeclaration: |
| 1245 // 'export' Identifier (',' Identifier)* ';' | 1248 // 'export' Identifier (',' Identifier)* ';' |
| 1246 // 'export' VariableDeclaration | 1249 // 'export' VariableDeclaration |
| 1247 // 'export' FunctionDeclaration | 1250 // 'export' FunctionDeclaration |
| 1248 // 'export' GeneratorDeclaration | 1251 // 'export' GeneratorDeclaration |
| 1249 // 'export' ModuleDeclaration | 1252 // 'export' ModuleDeclaration |
| 1250 // | 1253 // |
| 1251 // TODO(ES6): implement structuring ExportSpecifiers | 1254 // TODO(ES6): implement structuring ExportSpecifiers |
| 1252 | 1255 |
| 1253 Expect(Token::EXPORT, CHECK_OK); | 1256 Expect(Token::EXPORT, CHECK_OK); |
| 1254 | 1257 |
| 1255 Statement* result = NULL; | 1258 Statement* result = NULL; |
| 1256 ZoneStringList names(1, zone()); | 1259 ZoneStringList names(1, zone()); |
| 1257 switch (peek()) { | 1260 switch (peek()) { |
| 1258 case Token::IDENTIFIER: { | 1261 case Token::IDENTIFIER: { |
| 1262 int pos = position(); |
| 1259 Handle<String> name = ParseIdentifier(CHECK_OK); | 1263 Handle<String> name = ParseIdentifier(CHECK_OK); |
| 1260 // Handle 'module' as a context-sensitive keyword. | 1264 // Handle 'module' as a context-sensitive keyword. |
| 1261 if (!name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("module"))) { | 1265 if (!name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("module"))) { |
| 1262 names.Add(name, zone()); | 1266 names.Add(name, zone()); |
| 1263 while (peek() == Token::COMMA) { | 1267 while (peek() == Token::COMMA) { |
| 1264 Consume(Token::COMMA); | 1268 Consume(Token::COMMA); |
| 1265 name = ParseIdentifier(CHECK_OK); | 1269 name = ParseIdentifier(CHECK_OK); |
| 1266 names.Add(name, zone()); | 1270 names.Add(name, zone()); |
| 1267 } | 1271 } |
| 1268 ExpectSemicolon(CHECK_OK); | 1272 ExpectSemicolon(CHECK_OK); |
| 1269 result = factory()->NewEmptyStatement(); | 1273 result = factory()->NewEmptyStatement(pos); |
| 1270 } else { | 1274 } else { |
| 1271 result = ParseModuleDeclaration(&names, CHECK_OK); | 1275 result = ParseModuleDeclaration(&names, CHECK_OK); |
| 1272 } | 1276 } |
| 1273 break; | 1277 break; |
| 1274 } | 1278 } |
| 1275 | 1279 |
| 1276 case Token::FUNCTION: | 1280 case Token::FUNCTION: |
| 1277 result = ParseFunctionDeclaration(&names, CHECK_OK); | 1281 result = ParseFunctionDeclaration(&names, CHECK_OK); |
| 1278 break; | 1282 break; |
| 1279 | 1283 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1298 #endif | 1302 #endif |
| 1299 Interface* inner = Interface::NewUnknown(zone()); | 1303 Interface* inner = Interface::NewUnknown(zone()); |
| 1300 interface->Add(names[i], inner, zone(), CHECK_OK); | 1304 interface->Add(names[i], inner, zone(), CHECK_OK); |
| 1301 if (!*ok) | 1305 if (!*ok) |
| 1302 return NULL; | 1306 return NULL; |
| 1303 VariableProxy* proxy = NewUnresolved(names[i], LET, inner); | 1307 VariableProxy* proxy = NewUnresolved(names[i], LET, inner); |
| 1304 USE(proxy); | 1308 USE(proxy); |
| 1305 // TODO(rossberg): Rethink whether we actually need to store export | 1309 // TODO(rossberg): Rethink whether we actually need to store export |
| 1306 // declarations (for compilation?). | 1310 // declarations (for compilation?). |
| 1307 // ExportDeclaration* declaration = | 1311 // ExportDeclaration* declaration = |
| 1308 // factory()->NewExportDeclaration(proxy, top_scope_); | 1312 // factory()->NewExportDeclaration(proxy, top_scope_, position); |
| 1309 // top_scope_->AddDeclaration(declaration); | 1313 // top_scope_->AddDeclaration(declaration); |
| 1310 } | 1314 } |
| 1311 | 1315 |
| 1312 ASSERT(result != NULL); | 1316 ASSERT(result != NULL); |
| 1313 return result; | 1317 return result; |
| 1314 } | 1318 } |
| 1315 | 1319 |
| 1316 | 1320 |
| 1317 Statement* Parser::ParseBlockElement(ZoneStringList* labels, | 1321 Statement* Parser::ParseBlockElement(ZoneStringList* labels, |
| 1318 bool* ok) { | 1322 bool* ok) { |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1356 // ThrowStatement | 1360 // ThrowStatement |
| 1357 // TryStatement | 1361 // TryStatement |
| 1358 // DebuggerStatement | 1362 // DebuggerStatement |
| 1359 | 1363 |
| 1360 // Note: Since labels can only be used by 'break' and 'continue' | 1364 // Note: Since labels can only be used by 'break' and 'continue' |
| 1361 // statements, which themselves are only valid within blocks, | 1365 // statements, which themselves are only valid within blocks, |
| 1362 // iterations or 'switch' statements (i.e., BreakableStatements), | 1366 // iterations or 'switch' statements (i.e., BreakableStatements), |
| 1363 // labels can be simply ignored in all other cases; except for | 1367 // labels can be simply ignored in all other cases; except for |
| 1364 // trivial labeled break statements 'label: break label' which is | 1368 // trivial labeled break statements 'label: break label' which is |
| 1365 // parsed into an empty statement. | 1369 // parsed into an empty statement. |
| 1366 | |
| 1367 // Keep the source position of the statement | |
| 1368 int statement_pos = scanner().peek_location().beg_pos; | |
| 1369 Statement* stmt = NULL; | |
| 1370 switch (peek()) { | 1370 switch (peek()) { |
| 1371 case Token::LBRACE: | 1371 case Token::LBRACE: |
| 1372 return ParseBlock(labels, ok); | 1372 return ParseBlock(labels, ok); |
| 1373 | 1373 |
| 1374 case Token::CONST: // fall through | 1374 case Token::CONST: // fall through |
| 1375 case Token::LET: | 1375 case Token::LET: |
| 1376 case Token::VAR: | 1376 case Token::VAR: |
| 1377 stmt = ParseVariableStatement(kStatement, NULL, ok); | 1377 return ParseVariableStatement(kStatement, NULL, ok); |
| 1378 break; | |
| 1379 | 1378 |
| 1380 case Token::SEMICOLON: | 1379 case Token::SEMICOLON: |
| 1381 Next(); | 1380 Next(); |
| 1382 return factory()->NewEmptyStatement(); | 1381 return factory()->NewEmptyStatement(RelocInfo::kNoPosition); |
| 1383 | 1382 |
| 1384 case Token::IF: | 1383 case Token::IF: |
| 1385 stmt = ParseIfStatement(labels, ok); | 1384 return ParseIfStatement(labels, ok); |
| 1386 break; | |
| 1387 | 1385 |
| 1388 case Token::DO: | 1386 case Token::DO: |
| 1389 stmt = ParseDoWhileStatement(labels, ok); | 1387 return ParseDoWhileStatement(labels, ok); |
| 1390 break; | |
| 1391 | 1388 |
| 1392 case Token::WHILE: | 1389 case Token::WHILE: |
| 1393 stmt = ParseWhileStatement(labels, ok); | 1390 return ParseWhileStatement(labels, ok); |
| 1394 break; | |
| 1395 | 1391 |
| 1396 case Token::FOR: | 1392 case Token::FOR: |
| 1397 stmt = ParseForStatement(labels, ok); | 1393 return ParseForStatement(labels, ok); |
| 1398 break; | |
| 1399 | 1394 |
| 1400 case Token::CONTINUE: | 1395 case Token::CONTINUE: |
| 1401 stmt = ParseContinueStatement(ok); | 1396 return ParseContinueStatement(ok); |
| 1402 break; | |
| 1403 | 1397 |
| 1404 case Token::BREAK: | 1398 case Token::BREAK: |
| 1405 stmt = ParseBreakStatement(labels, ok); | 1399 return ParseBreakStatement(labels, ok); |
| 1406 break; | |
| 1407 | 1400 |
| 1408 case Token::RETURN: | 1401 case Token::RETURN: |
| 1409 stmt = ParseReturnStatement(ok); | 1402 return ParseReturnStatement(ok); |
| 1410 break; | |
| 1411 | 1403 |
| 1412 case Token::WITH: | 1404 case Token::WITH: |
| 1413 stmt = ParseWithStatement(labels, ok); | 1405 return ParseWithStatement(labels, ok); |
| 1414 break; | |
| 1415 | 1406 |
| 1416 case Token::SWITCH: | 1407 case Token::SWITCH: |
| 1417 stmt = ParseSwitchStatement(labels, ok); | 1408 return ParseSwitchStatement(labels, ok); |
| 1418 break; | |
| 1419 | 1409 |
| 1420 case Token::THROW: | 1410 case Token::THROW: |
| 1421 stmt = ParseThrowStatement(ok); | 1411 return ParseThrowStatement(ok); |
| 1422 break; | |
| 1423 | 1412 |
| 1424 case Token::TRY: { | 1413 case Token::TRY: { |
| 1425 // NOTE: It is somewhat complicated to have labels on | 1414 // NOTE: It is somewhat complicated to have labels on |
| 1426 // try-statements. When breaking out of a try-finally statement, | 1415 // try-statements. When breaking out of a try-finally statement, |
| 1427 // one must take great care not to treat it as a | 1416 // one must take great care not to treat it as a |
| 1428 // fall-through. It is much easier just to wrap the entire | 1417 // fall-through. It is much easier just to wrap the entire |
| 1429 // try-statement in a statement block and put the labels there | 1418 // try-statement in a statement block and put the labels there |
| 1430 Block* result = factory()->NewBlock(labels, 1, false); | 1419 Block* result = |
| 1420 factory()->NewBlock(labels, 1, false, RelocInfo::kNoPosition); |
| 1431 Target target(&this->target_stack_, result); | 1421 Target target(&this->target_stack_, result); |
| 1432 TryStatement* statement = ParseTryStatement(CHECK_OK); | 1422 TryStatement* statement = ParseTryStatement(CHECK_OK); |
| 1433 if (statement) { | |
| 1434 statement->set_statement_pos(statement_pos); | |
| 1435 } | |
| 1436 if (result) result->AddStatement(statement, zone()); | 1423 if (result) result->AddStatement(statement, zone()); |
| 1437 return result; | 1424 return result; |
| 1438 } | 1425 } |
| 1439 | 1426 |
| 1440 case Token::FUNCTION: { | 1427 case Token::FUNCTION: { |
| 1441 // FunctionDeclaration is only allowed in the context of SourceElements | 1428 // FunctionDeclaration is only allowed in the context of SourceElements |
| 1442 // (Ecma 262 5th Edition, clause 14): | 1429 // (Ecma 262 5th Edition, clause 14): |
| 1443 // SourceElement: | 1430 // SourceElement: |
| 1444 // Statement | 1431 // Statement |
| 1445 // FunctionDeclaration | 1432 // FunctionDeclaration |
| 1446 // Common language extension is to allow function declaration in place | 1433 // Common language extension is to allow function declaration in place |
| 1447 // of any statement. This language extension is disabled in strict mode. | 1434 // of any statement. This language extension is disabled in strict mode. |
| 1448 // | 1435 // |
| 1449 // In Harmony mode, this case also handles the extension: | 1436 // In Harmony mode, this case also handles the extension: |
| 1450 // Statement: | 1437 // Statement: |
| 1451 // GeneratorDeclaration | 1438 // GeneratorDeclaration |
| 1452 if (!top_scope_->is_classic_mode()) { | 1439 if (!top_scope_->is_classic_mode()) { |
| 1453 ReportMessageAt(scanner().peek_location(), "strict_function", | 1440 ReportMessageAt(scanner().peek_location(), "strict_function", |
| 1454 Vector<const char*>::empty()); | 1441 Vector<const char*>::empty()); |
| 1455 *ok = false; | 1442 *ok = false; |
| 1456 return NULL; | 1443 return NULL; |
| 1457 } | 1444 } |
| 1458 return ParseFunctionDeclaration(NULL, ok); | 1445 return ParseFunctionDeclaration(NULL, ok); |
| 1459 } | 1446 } |
| 1460 | 1447 |
| 1461 case Token::DEBUGGER: | 1448 case Token::DEBUGGER: |
| 1462 stmt = ParseDebuggerStatement(ok); | 1449 return ParseDebuggerStatement(ok); |
| 1463 break; | |
| 1464 | 1450 |
| 1465 default: | 1451 default: |
| 1466 stmt = ParseExpressionOrLabelledStatement(labels, ok); | 1452 return ParseExpressionOrLabelledStatement(labels, ok); |
| 1467 } | 1453 } |
| 1468 | |
| 1469 // Store the source position of the statement | |
| 1470 if (stmt != NULL) stmt->set_statement_pos(statement_pos); | |
| 1471 return stmt; | |
| 1472 } | 1454 } |
| 1473 | 1455 |
| 1474 | 1456 |
| 1475 VariableProxy* Parser::NewUnresolved( | 1457 VariableProxy* Parser::NewUnresolved( |
| 1476 Handle<String> name, VariableMode mode, Interface* interface) { | 1458 Handle<String> name, VariableMode mode, Interface* interface) { |
| 1477 // If we are inside a function, a declaration of a var/const variable is a | 1459 // If we are inside a function, a declaration of a var/const variable is a |
| 1478 // truly local variable, and the scope of the variable is always the function | 1460 // truly local variable, and the scope of the variable is always the function |
| 1479 // scope. | 1461 // scope. |
| 1480 // Let/const variables in harmony mode are always added to the immediately | 1462 // Let/const variables in harmony mode are always added to the immediately |
| 1481 // enclosing scope. | 1463 // enclosing scope. |
| 1482 return DeclarationScope(mode)->NewUnresolved( | 1464 return DeclarationScope(mode)->NewUnresolved( |
| 1483 factory(), name, interface, scanner().location().beg_pos); | 1465 factory(), name, interface, position()); |
| 1484 } | 1466 } |
| 1485 | 1467 |
| 1486 | 1468 |
| 1487 void Parser::Declare(Declaration* declaration, bool resolve, bool* ok) { | 1469 void Parser::Declare(Declaration* declaration, bool resolve, bool* ok) { |
| 1488 VariableProxy* proxy = declaration->proxy(); | 1470 VariableProxy* proxy = declaration->proxy(); |
| 1489 Handle<String> name = proxy->name(); | 1471 Handle<String> name = proxy->name(); |
| 1490 VariableMode mode = declaration->mode(); | 1472 VariableMode mode = declaration->mode(); |
| 1491 Scope* declaration_scope = DeclarationScope(mode); | 1473 Scope* declaration_scope = DeclarationScope(mode); |
| 1492 Variable* var = NULL; | 1474 Variable* var = NULL; |
| 1493 | 1475 |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1640 } | 1622 } |
| 1641 } | 1623 } |
| 1642 } | 1624 } |
| 1643 | 1625 |
| 1644 | 1626 |
| 1645 // Language extension which is only enabled for source files loaded | 1627 // Language extension which is only enabled for source files loaded |
| 1646 // through the API's extension mechanism. A native function | 1628 // through the API's extension mechanism. A native function |
| 1647 // declaration is resolved by looking up the function through a | 1629 // declaration is resolved by looking up the function through a |
| 1648 // callback provided by the extension. | 1630 // callback provided by the extension. |
| 1649 Statement* Parser::ParseNativeDeclaration(bool* ok) { | 1631 Statement* Parser::ParseNativeDeclaration(bool* ok) { |
| 1632 int pos = peek_position(); |
| 1650 Expect(Token::FUNCTION, CHECK_OK); | 1633 Expect(Token::FUNCTION, CHECK_OK); |
| 1651 Handle<String> name = ParseIdentifier(CHECK_OK); | 1634 Handle<String> name = ParseIdentifier(CHECK_OK); |
| 1652 Expect(Token::LPAREN, CHECK_OK); | 1635 Expect(Token::LPAREN, CHECK_OK); |
| 1653 bool done = (peek() == Token::RPAREN); | 1636 bool done = (peek() == Token::RPAREN); |
| 1654 while (!done) { | 1637 while (!done) { |
| 1655 ParseIdentifier(CHECK_OK); | 1638 ParseIdentifier(CHECK_OK); |
| 1656 done = (peek() == Token::RPAREN); | 1639 done = (peek() == Token::RPAREN); |
| 1657 if (!done) { | 1640 if (!done) { |
| 1658 Expect(Token::COMMA, CHECK_OK); | 1641 Expect(Token::COMMA, CHECK_OK); |
| 1659 } | 1642 } |
| 1660 } | 1643 } |
| 1661 Expect(Token::RPAREN, CHECK_OK); | 1644 Expect(Token::RPAREN, CHECK_OK); |
| 1662 Expect(Token::SEMICOLON, CHECK_OK); | 1645 Expect(Token::SEMICOLON, CHECK_OK); |
| 1663 | 1646 |
| 1664 // Make sure that the function containing the native declaration | 1647 // Make sure that the function containing the native declaration |
| 1665 // isn't lazily compiled. The extension structures are only | 1648 // isn't lazily compiled. The extension structures are only |
| 1666 // accessible while parsing the first time not when reparsing | 1649 // accessible while parsing the first time not when reparsing |
| 1667 // because of lazy compilation. | 1650 // because of lazy compilation. |
| 1668 DeclarationScope(VAR)->ForceEagerCompilation(); | 1651 DeclarationScope(VAR)->ForceEagerCompilation(); |
| 1669 | 1652 |
| 1670 // TODO(1240846): It's weird that native function declarations are | 1653 // TODO(1240846): It's weird that native function declarations are |
| 1671 // introduced dynamically when we meet their declarations, whereas | 1654 // introduced dynamically when we meet their declarations, whereas |
| 1672 // other functions are set up when entering the surrounding scope. | 1655 // other functions are set up when entering the surrounding scope. |
| 1673 VariableProxy* proxy = NewUnresolved(name, VAR, Interface::NewValue()); | 1656 VariableProxy* proxy = NewUnresolved(name, VAR, Interface::NewValue()); |
| 1674 Declaration* declaration = | 1657 Declaration* declaration = |
| 1675 factory()->NewVariableDeclaration(proxy, VAR, top_scope_); | 1658 factory()->NewVariableDeclaration(proxy, VAR, top_scope_, pos); |
| 1676 Declare(declaration, true, CHECK_OK); | 1659 Declare(declaration, true, CHECK_OK); |
| 1677 NativeFunctionLiteral* lit = | 1660 NativeFunctionLiteral* lit = factory()->NewNativeFunctionLiteral( |
| 1678 factory()->NewNativeFunctionLiteral(name, extension_); | 1661 name, extension_, RelocInfo::kNoPosition); |
| 1679 return factory()->NewExpressionStatement( | 1662 return factory()->NewExpressionStatement( |
| 1680 factory()->NewAssignment( | 1663 factory()->NewAssignment( |
| 1681 Token::INIT_VAR, proxy, lit, RelocInfo::kNoPosition)); | 1664 Token::INIT_VAR, proxy, lit, RelocInfo::kNoPosition), |
| 1665 pos); |
| 1682 } | 1666 } |
| 1683 | 1667 |
| 1684 | 1668 |
| 1685 Statement* Parser::ParseFunctionDeclaration(ZoneStringList* names, bool* ok) { | 1669 Statement* Parser::ParseFunctionDeclaration(ZoneStringList* names, bool* ok) { |
| 1686 // FunctionDeclaration :: | 1670 // FunctionDeclaration :: |
| 1687 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' | 1671 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' |
| 1688 // GeneratorDeclaration :: | 1672 // GeneratorDeclaration :: |
| 1689 // 'function' '*' Identifier '(' FormalParameterListopt ')' | 1673 // 'function' '*' Identifier '(' FormalParameterListopt ')' |
| 1690 // '{' FunctionBody '}' | 1674 // '{' FunctionBody '}' |
| 1691 Expect(Token::FUNCTION, CHECK_OK); | 1675 Expect(Token::FUNCTION, CHECK_OK); |
| 1692 int function_token_position = scanner().location().beg_pos; | 1676 int pos = position(); |
| 1693 bool is_generator = allow_generators() && Check(Token::MUL); | 1677 bool is_generator = allow_generators() && Check(Token::MUL); |
| 1694 bool is_strict_reserved = false; | 1678 bool is_strict_reserved = false; |
| 1695 Handle<String> name = ParseIdentifierOrStrictReservedWord( | 1679 Handle<String> name = ParseIdentifierOrStrictReservedWord( |
| 1696 &is_strict_reserved, CHECK_OK); | 1680 &is_strict_reserved, CHECK_OK); |
| 1697 FunctionLiteral* fun = ParseFunctionLiteral(name, | 1681 FunctionLiteral* fun = ParseFunctionLiteral(name, |
| 1698 is_strict_reserved, | 1682 is_strict_reserved, |
| 1699 is_generator, | 1683 is_generator, |
| 1700 function_token_position, | 1684 pos, |
| 1701 FunctionLiteral::DECLARATION, | 1685 FunctionLiteral::DECLARATION, |
| 1702 CHECK_OK); | 1686 CHECK_OK); |
| 1703 // Even if we're not at the top-level of the global or a function | 1687 // Even if we're not at the top-level of the global or a function |
| 1704 // scope, we treat it as such and introduce the function with its | 1688 // scope, we treat it as such and introduce the function with its |
| 1705 // initial value upon entering the corresponding scope. | 1689 // initial value upon entering the corresponding scope. |
| 1706 // In extended mode, a function behaves as a lexical binding, except in the | 1690 // In extended mode, a function behaves as a lexical binding, except in the |
| 1707 // global scope. | 1691 // global scope. |
| 1708 VariableMode mode = | 1692 VariableMode mode = |
| 1709 is_extended_mode() && !top_scope_->is_global_scope() ? LET : VAR; | 1693 is_extended_mode() && !top_scope_->is_global_scope() ? LET : VAR; |
| 1710 VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue()); | 1694 VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue()); |
| 1711 Declaration* declaration = | 1695 Declaration* declaration = |
| 1712 factory()->NewFunctionDeclaration(proxy, mode, fun, top_scope_); | 1696 factory()->NewFunctionDeclaration(proxy, mode, fun, top_scope_, pos); |
| 1713 Declare(declaration, true, CHECK_OK); | 1697 Declare(declaration, true, CHECK_OK); |
| 1714 if (names) names->Add(name, zone()); | 1698 if (names) names->Add(name, zone()); |
| 1715 return factory()->NewEmptyStatement(); | 1699 return factory()->NewEmptyStatement(RelocInfo::kNoPosition); |
| 1716 } | 1700 } |
| 1717 | 1701 |
| 1718 | 1702 |
| 1719 Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) { | 1703 Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) { |
| 1720 if (top_scope_->is_extended_mode()) return ParseScopedBlock(labels, ok); | 1704 if (top_scope_->is_extended_mode()) return ParseScopedBlock(labels, ok); |
| 1721 | 1705 |
| 1722 // Block :: | 1706 // Block :: |
| 1723 // '{' Statement* '}' | 1707 // '{' Statement* '}' |
| 1724 | 1708 |
| 1725 // Note that a Block does not introduce a new execution scope! | 1709 // Note that a Block does not introduce a new execution scope! |
| 1726 // (ECMA-262, 3rd, 12.2) | 1710 // (ECMA-262, 3rd, 12.2) |
| 1727 // | 1711 // |
| 1728 // Construct block expecting 16 statements. | 1712 // Construct block expecting 16 statements. |
| 1729 Block* result = factory()->NewBlock(labels, 16, false); | 1713 Block* result = |
| 1714 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition); |
| 1730 Target target(&this->target_stack_, result); | 1715 Target target(&this->target_stack_, result); |
| 1731 Expect(Token::LBRACE, CHECK_OK); | 1716 Expect(Token::LBRACE, CHECK_OK); |
| 1732 while (peek() != Token::RBRACE) { | 1717 while (peek() != Token::RBRACE) { |
| 1733 Statement* stat = ParseStatement(NULL, CHECK_OK); | 1718 Statement* stat = ParseStatement(NULL, CHECK_OK); |
| 1734 if (stat && !stat->IsEmpty()) { | 1719 if (stat && !stat->IsEmpty()) { |
| 1735 result->AddStatement(stat, zone()); | 1720 result->AddStatement(stat, zone()); |
| 1736 } | 1721 } |
| 1737 } | 1722 } |
| 1738 Expect(Token::RBRACE, CHECK_OK); | 1723 Expect(Token::RBRACE, CHECK_OK); |
| 1739 return result; | 1724 return result; |
| 1740 } | 1725 } |
| 1741 | 1726 |
| 1742 | 1727 |
| 1743 Block* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) { | 1728 Block* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) { |
| 1744 // The harmony mode uses block elements instead of statements. | 1729 // The harmony mode uses block elements instead of statements. |
| 1745 // | 1730 // |
| 1746 // Block :: | 1731 // Block :: |
| 1747 // '{' BlockElement* '}' | 1732 // '{' BlockElement* '}' |
| 1748 | 1733 |
| 1749 // Construct block expecting 16 statements. | 1734 // Construct block expecting 16 statements. |
| 1750 Block* body = factory()->NewBlock(labels, 16, false); | 1735 Block* body = |
| 1736 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition); |
| 1751 Scope* block_scope = NewScope(top_scope_, BLOCK_SCOPE); | 1737 Scope* block_scope = NewScope(top_scope_, BLOCK_SCOPE); |
| 1752 | 1738 |
| 1753 // Parse the statements and collect escaping labels. | 1739 // Parse the statements and collect escaping labels. |
| 1754 Expect(Token::LBRACE, CHECK_OK); | 1740 Expect(Token::LBRACE, CHECK_OK); |
| 1755 block_scope->set_start_position(scanner().location().beg_pos); | 1741 block_scope->set_start_position(scanner().location().beg_pos); |
| 1756 { BlockState block_state(this, block_scope); | 1742 { BlockState block_state(this, block_scope); |
| 1757 TargetCollector collector(zone()); | 1743 TargetCollector collector(zone()); |
| 1758 Target target(&this->target_stack_, &collector); | 1744 Target target(&this->target_stack_, &collector); |
| 1759 Target target_body(&this->target_stack_, body); | 1745 Target target_body(&this->target_stack_, body); |
| 1760 | 1746 |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1810 // The ES6 Draft Rev3 specifies the following grammar for const declarations | 1796 // The ES6 Draft Rev3 specifies the following grammar for const declarations |
| 1811 // | 1797 // |
| 1812 // ConstDeclaration :: | 1798 // ConstDeclaration :: |
| 1813 // const ConstBinding (',' ConstBinding)* ';' | 1799 // const ConstBinding (',' ConstBinding)* ';' |
| 1814 // ConstBinding :: | 1800 // ConstBinding :: |
| 1815 // Identifier '=' AssignmentExpression | 1801 // Identifier '=' AssignmentExpression |
| 1816 // | 1802 // |
| 1817 // TODO(ES6): | 1803 // TODO(ES6): |
| 1818 // ConstBinding :: | 1804 // ConstBinding :: |
| 1819 // BindingPattern '=' AssignmentExpression | 1805 // BindingPattern '=' AssignmentExpression |
| 1806 |
| 1807 int pos = peek_position(); |
| 1820 VariableMode mode = VAR; | 1808 VariableMode mode = VAR; |
| 1821 // True if the binding needs initialization. 'let' and 'const' declared | 1809 // True if the binding needs initialization. 'let' and 'const' declared |
| 1822 // bindings are created uninitialized by their declaration nodes and | 1810 // bindings are created uninitialized by their declaration nodes and |
| 1823 // need initialization. 'var' declared bindings are always initialized | 1811 // need initialization. 'var' declared bindings are always initialized |
| 1824 // immediately by their declaration nodes. | 1812 // immediately by their declaration nodes. |
| 1825 bool needs_init = false; | 1813 bool needs_init = false; |
| 1826 bool is_const = false; | 1814 bool is_const = false; |
| 1827 Token::Value init_op = Token::INIT_VAR; | 1815 Token::Value init_op = Token::INIT_VAR; |
| 1828 if (peek() == Token::VAR) { | 1816 if (peek() == Token::VAR) { |
| 1829 Consume(Token::VAR); | 1817 Consume(Token::VAR); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1895 // Scope declaration, and rewrite the source-level initialization into an | 1883 // Scope declaration, and rewrite the source-level initialization into an |
| 1896 // assignment statement. We use a block to collect multiple assignments. | 1884 // assignment statement. We use a block to collect multiple assignments. |
| 1897 // | 1885 // |
| 1898 // We mark the block as initializer block because we don't want the | 1886 // We mark the block as initializer block because we don't want the |
| 1899 // rewriter to add a '.result' assignment to such a block (to get compliant | 1887 // rewriter to add a '.result' assignment to such a block (to get compliant |
| 1900 // behavior for code such as print(eval('var x = 7')), and for cosmetic | 1888 // behavior for code such as print(eval('var x = 7')), and for cosmetic |
| 1901 // reasons when pretty-printing. Also, unless an assignment (initialization) | 1889 // reasons when pretty-printing. Also, unless an assignment (initialization) |
| 1902 // is inside an initializer block, it is ignored. | 1890 // is inside an initializer block, it is ignored. |
| 1903 // | 1891 // |
| 1904 // Create new block with one expected declaration. | 1892 // Create new block with one expected declaration. |
| 1905 Block* block = factory()->NewBlock(NULL, 1, true); | 1893 Block* block = factory()->NewBlock(NULL, 1, true, pos); |
| 1906 int nvars = 0; // the number of variables declared | 1894 int nvars = 0; // the number of variables declared |
| 1907 Handle<String> name; | 1895 Handle<String> name; |
| 1908 do { | 1896 do { |
| 1909 if (fni_ != NULL) fni_->Enter(); | 1897 if (fni_ != NULL) fni_->Enter(); |
| 1910 | 1898 |
| 1911 // Parse variable name. | 1899 // Parse variable name. |
| 1912 if (nvars > 0) Consume(Token::COMMA); | 1900 if (nvars > 0) Consume(Token::COMMA); |
| 1913 name = ParseIdentifier(CHECK_OK); | 1901 name = ParseIdentifier(CHECK_OK); |
| 1914 if (fni_ != NULL) fni_->PushVariableName(name); | 1902 if (fni_ != NULL) fni_->PushVariableName(name); |
| 1915 | 1903 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1932 // If we have a const declaration, in an inner scope, the proxy is always | 1920 // If we have a const declaration, in an inner scope, the proxy is always |
| 1933 // bound to the declared variable (independent of possibly surrounding with | 1921 // bound to the declared variable (independent of possibly surrounding with |
| 1934 // statements). | 1922 // statements). |
| 1935 // For let/const declarations in harmony mode, we can also immediately | 1923 // For let/const declarations in harmony mode, we can also immediately |
| 1936 // pre-resolve the proxy because it resides in the same scope as the | 1924 // pre-resolve the proxy because it resides in the same scope as the |
| 1937 // declaration. | 1925 // declaration. |
| 1938 Interface* interface = | 1926 Interface* interface = |
| 1939 is_const ? Interface::NewConst() : Interface::NewValue(); | 1927 is_const ? Interface::NewConst() : Interface::NewValue(); |
| 1940 VariableProxy* proxy = NewUnresolved(name, mode, interface); | 1928 VariableProxy* proxy = NewUnresolved(name, mode, interface); |
| 1941 Declaration* declaration = | 1929 Declaration* declaration = |
| 1942 factory()->NewVariableDeclaration(proxy, mode, top_scope_); | 1930 factory()->NewVariableDeclaration(proxy, mode, top_scope_, pos); |
| 1943 Declare(declaration, mode != VAR, CHECK_OK); | 1931 Declare(declaration, mode != VAR, CHECK_OK); |
| 1944 nvars++; | 1932 nvars++; |
| 1945 if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) { | 1933 if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) { |
| 1946 ReportMessageAt(scanner().location(), "too_many_variables", | 1934 ReportMessageAt(scanner().location(), "too_many_variables", |
| 1947 Vector<const char*>::empty()); | 1935 Vector<const char*>::empty()); |
| 1948 *ok = false; | 1936 *ok = false; |
| 1949 return NULL; | 1937 return NULL; |
| 1950 } | 1938 } |
| 1951 if (names) names->Add(name, zone()); | 1939 if (names) names->Add(name, zone()); |
| 1952 | 1940 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1972 // is *not* syntactic sugar for: | 1960 // is *not* syntactic sugar for: |
| 1973 // | 1961 // |
| 1974 // const c; c = x; | 1962 // const c; c = x; |
| 1975 // | 1963 // |
| 1976 // The "variable" c initialized to x is the same as the declared | 1964 // The "variable" c initialized to x is the same as the declared |
| 1977 // one - there is no re-lookup (see the last parameter of the | 1965 // one - there is no re-lookup (see the last parameter of the |
| 1978 // Declare() call above). | 1966 // Declare() call above). |
| 1979 | 1967 |
| 1980 Scope* initialization_scope = is_const ? declaration_scope : top_scope_; | 1968 Scope* initialization_scope = is_const ? declaration_scope : top_scope_; |
| 1981 Expression* value = NULL; | 1969 Expression* value = NULL; |
| 1982 int position = -1; | 1970 int pos = -1; |
| 1983 // Harmony consts have non-optional initializers. | 1971 // Harmony consts have non-optional initializers. |
| 1984 if (peek() == Token::ASSIGN || mode == CONST_HARMONY) { | 1972 if (peek() == Token::ASSIGN || mode == CONST_HARMONY) { |
| 1985 Expect(Token::ASSIGN, CHECK_OK); | 1973 Expect(Token::ASSIGN, CHECK_OK); |
| 1986 position = scanner().location().beg_pos; | 1974 pos = position(); |
| 1987 value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); | 1975 value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); |
| 1988 // Don't infer if it is "a = function(){...}();"-like expression. | 1976 // Don't infer if it is "a = function(){...}();"-like expression. |
| 1989 if (fni_ != NULL && | 1977 if (fni_ != NULL && |
| 1990 value->AsCall() == NULL && | 1978 value->AsCall() == NULL && |
| 1991 value->AsCallNew() == NULL) { | 1979 value->AsCallNew() == NULL) { |
| 1992 fni_->Infer(); | 1980 fni_->Infer(); |
| 1993 } else { | 1981 } else { |
| 1994 fni_->RemoveLastFunction(); | 1982 fni_->RemoveLastFunction(); |
| 1995 } | 1983 } |
| 1996 if (decl_props != NULL) *decl_props = kHasInitializers; | 1984 if (decl_props != NULL) *decl_props = kHasInitializers; |
| 1997 } | 1985 } |
| 1998 | 1986 |
| 1999 // Record the end position of the initializer. | 1987 // Record the end position of the initializer. |
| 2000 if (proxy->var() != NULL) { | 1988 if (proxy->var() != NULL) { |
| 2001 proxy->var()->set_initializer_position(scanner().location().end_pos); | 1989 proxy->var()->set_initializer_position(position()); |
| 2002 } | 1990 } |
| 2003 | 1991 |
| 2004 // Make sure that 'const x' and 'let x' initialize 'x' to undefined. | 1992 // Make sure that 'const x' and 'let x' initialize 'x' to undefined. |
| 2005 if (value == NULL && needs_init) { | 1993 if (value == NULL && needs_init) { |
| 2006 value = GetLiteralUndefined(); | 1994 value = GetLiteralUndefined(position()); |
| 2007 } | 1995 } |
| 2008 | 1996 |
| 2009 // Global variable declarations must be compiled in a specific | 1997 // Global variable declarations must be compiled in a specific |
| 2010 // way. When the script containing the global variable declaration | 1998 // way. When the script containing the global variable declaration |
| 2011 // is entered, the global variable must be declared, so that if it | 1999 // is entered, the global variable must be declared, so that if it |
| 2012 // doesn't exist (on the global object itself, see ES5 errata) it | 2000 // doesn't exist (on the global object itself, see ES5 errata) it |
| 2013 // gets created with an initial undefined value. This is handled | 2001 // gets created with an initial undefined value. This is handled |
| 2014 // by the declarations part of the function representing the | 2002 // by the declarations part of the function representing the |
| 2015 // top-level global code; see Runtime::DeclareGlobalVariable. If | 2003 // top-level global code; see Runtime::DeclareGlobalVariable. If |
| 2016 // it already exists (in the object or in a prototype), it is | 2004 // it already exists (in the object or in a prototype), it is |
| 2017 // *not* touched until the variable declaration statement is | 2005 // *not* touched until the variable declaration statement is |
| 2018 // executed. | 2006 // executed. |
| 2019 // | 2007 // |
| 2020 // Executing the variable declaration statement will always | 2008 // Executing the variable declaration statement will always |
| 2021 // guarantee to give the global object a "local" variable; a | 2009 // guarantee to give the global object a "local" variable; a |
| 2022 // variable defined in the global object and not in any | 2010 // variable defined in the global object and not in any |
| 2023 // prototype. This way, global variable declarations can shadow | 2011 // prototype. This way, global variable declarations can shadow |
| 2024 // properties in the prototype chain, but only after the variable | 2012 // properties in the prototype chain, but only after the variable |
| 2025 // declaration statement has been executed. This is important in | 2013 // declaration statement has been executed. This is important in |
| 2026 // browsers where the global object (window) has lots of | 2014 // browsers where the global object (window) has lots of |
| 2027 // properties defined in prototype objects. | 2015 // properties defined in prototype objects. |
| 2028 if (initialization_scope->is_global_scope() && | 2016 if (initialization_scope->is_global_scope() && |
| 2029 !IsLexicalVariableMode(mode)) { | 2017 !IsLexicalVariableMode(mode)) { |
| 2030 // Compute the arguments for the runtime call. | 2018 // Compute the arguments for the runtime call. |
| 2031 ZoneList<Expression*>* arguments = | 2019 ZoneList<Expression*>* arguments = |
| 2032 new(zone()) ZoneList<Expression*>(3, zone()); | 2020 new(zone()) ZoneList<Expression*>(3, zone()); |
| 2033 // We have at least 1 parameter. | 2021 // We have at least 1 parameter. |
| 2034 arguments->Add(factory()->NewLiteral(name), zone()); | 2022 arguments->Add(factory()->NewLiteral(name, pos), zone()); |
| 2035 CallRuntime* initialize; | 2023 CallRuntime* initialize; |
| 2036 | 2024 |
| 2037 if (is_const) { | 2025 if (is_const) { |
| 2038 arguments->Add(value, zone()); | 2026 arguments->Add(value, zone()); |
| 2039 value = NULL; // zap the value to avoid the unnecessary assignment | 2027 value = NULL; // zap the value to avoid the unnecessary assignment |
| 2040 | 2028 |
| 2041 // Construct the call to Runtime_InitializeConstGlobal | 2029 // Construct the call to Runtime_InitializeConstGlobal |
| 2042 // and add it to the initialization statement block. | 2030 // and add it to the initialization statement block. |
| 2043 // Note that the function does different things depending on | 2031 // Note that the function does different things depending on |
| 2044 // the number of arguments (1 or 2). | 2032 // the number of arguments (1 or 2). |
| 2045 initialize = factory()->NewCallRuntime( | 2033 initialize = factory()->NewCallRuntime( |
| 2046 isolate()->factory()->InitializeConstGlobal_string(), | 2034 isolate()->factory()->InitializeConstGlobal_string(), |
| 2047 Runtime::FunctionForId(Runtime::kInitializeConstGlobal), | 2035 Runtime::FunctionForId(Runtime::kInitializeConstGlobal), |
| 2048 arguments); | 2036 arguments, pos); |
| 2049 } else { | 2037 } else { |
| 2050 // Add strict mode. | 2038 // Add strict mode. |
| 2051 // We may want to pass singleton to avoid Literal allocations. | 2039 // We may want to pass singleton to avoid Literal allocations. |
| 2052 LanguageMode language_mode = initialization_scope->language_mode(); | 2040 LanguageMode language_mode = initialization_scope->language_mode(); |
| 2053 arguments->Add(factory()->NewNumberLiteral(language_mode), zone()); | 2041 arguments->Add(factory()->NewNumberLiteral(language_mode, pos), zone()); |
| 2054 | 2042 |
| 2055 // Be careful not to assign a value to the global variable if | 2043 // Be careful not to assign a value to the global variable if |
| 2056 // we're in a with. The initialization value should not | 2044 // we're in a with. The initialization value should not |
| 2057 // necessarily be stored in the global object in that case, | 2045 // necessarily be stored in the global object in that case, |
| 2058 // which is why we need to generate a separate assignment node. | 2046 // which is why we need to generate a separate assignment node. |
| 2059 if (value != NULL && !inside_with()) { | 2047 if (value != NULL && !inside_with()) { |
| 2060 arguments->Add(value, zone()); | 2048 arguments->Add(value, zone()); |
| 2061 value = NULL; // zap the value to avoid the unnecessary assignment | 2049 value = NULL; // zap the value to avoid the unnecessary assignment |
| 2062 } | 2050 } |
| 2063 | 2051 |
| 2064 // Construct the call to Runtime_InitializeVarGlobal | 2052 // Construct the call to Runtime_InitializeVarGlobal |
| 2065 // and add it to the initialization statement block. | 2053 // and add it to the initialization statement block. |
| 2066 // Note that the function does different things depending on | 2054 // Note that the function does different things depending on |
| 2067 // the number of arguments (2 or 3). | 2055 // the number of arguments (2 or 3). |
| 2068 initialize = factory()->NewCallRuntime( | 2056 initialize = factory()->NewCallRuntime( |
| 2069 isolate()->factory()->InitializeVarGlobal_string(), | 2057 isolate()->factory()->InitializeVarGlobal_string(), |
| 2070 Runtime::FunctionForId(Runtime::kInitializeVarGlobal), | 2058 Runtime::FunctionForId(Runtime::kInitializeVarGlobal), |
| 2071 arguments); | 2059 arguments, pos); |
| 2072 } | 2060 } |
| 2073 | 2061 |
| 2074 block->AddStatement(factory()->NewExpressionStatement(initialize), | 2062 block->AddStatement( |
| 2075 zone()); | 2063 factory()->NewExpressionStatement(initialize, RelocInfo::kNoPosition), |
| 2064 zone()); |
| 2076 } else if (needs_init) { | 2065 } else if (needs_init) { |
| 2077 // Constant initializations always assign to the declared constant which | 2066 // Constant initializations always assign to the declared constant which |
| 2078 // is always at the function scope level. This is only relevant for | 2067 // is always at the function scope level. This is only relevant for |
| 2079 // dynamically looked-up variables and constants (the start context for | 2068 // dynamically looked-up variables and constants (the start context for |
| 2080 // constant lookups is always the function context, while it is the top | 2069 // constant lookups is always the function context, while it is the top |
| 2081 // context for var declared variables). Sigh... | 2070 // context for var declared variables). Sigh... |
| 2082 // For 'let' and 'const' declared variables in harmony mode the | 2071 // For 'let' and 'const' declared variables in harmony mode the |
| 2083 // initialization also always assigns to the declared variable. | 2072 // initialization also always assigns to the declared variable. |
| 2084 ASSERT(proxy != NULL); | 2073 ASSERT(proxy != NULL); |
| 2085 ASSERT(proxy->var() != NULL); | 2074 ASSERT(proxy->var() != NULL); |
| 2086 ASSERT(value != NULL); | 2075 ASSERT(value != NULL); |
| 2087 Assignment* assignment = | 2076 Assignment* assignment = |
| 2088 factory()->NewAssignment(init_op, proxy, value, position); | 2077 factory()->NewAssignment(init_op, proxy, value, pos); |
| 2089 block->AddStatement(factory()->NewExpressionStatement(assignment), | 2078 block->AddStatement( |
| 2090 zone()); | 2079 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition), |
| 2080 zone()); |
| 2091 value = NULL; | 2081 value = NULL; |
| 2092 } | 2082 } |
| 2093 | 2083 |
| 2094 // Add an assignment node to the initialization statement block if we still | 2084 // Add an assignment node to the initialization statement block if we still |
| 2095 // have a pending initialization value. | 2085 // have a pending initialization value. |
| 2096 if (value != NULL) { | 2086 if (value != NULL) { |
| 2097 ASSERT(mode == VAR); | 2087 ASSERT(mode == VAR); |
| 2098 // 'var' initializations are simply assignments (with all the consequences | 2088 // 'var' initializations are simply assignments (with all the consequences |
| 2099 // if they are inside a 'with' statement - they may change a 'with' object | 2089 // if they are inside a 'with' statement - they may change a 'with' object |
| 2100 // property). | 2090 // property). |
| 2101 VariableProxy* proxy = | 2091 VariableProxy* proxy = |
| 2102 initialization_scope->NewUnresolved(factory(), name, interface); | 2092 initialization_scope->NewUnresolved(factory(), name, interface); |
| 2103 Assignment* assignment = | 2093 Assignment* assignment = |
| 2104 factory()->NewAssignment(init_op, proxy, value, position); | 2094 factory()->NewAssignment(init_op, proxy, value, pos); |
| 2105 block->AddStatement(factory()->NewExpressionStatement(assignment), | 2095 block->AddStatement( |
| 2106 zone()); | 2096 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition), |
| 2097 zone()); |
| 2107 } | 2098 } |
| 2108 | 2099 |
| 2109 if (fni_ != NULL) fni_->Leave(); | 2100 if (fni_ != NULL) fni_->Leave(); |
| 2110 } while (peek() == Token::COMMA); | 2101 } while (peek() == Token::COMMA); |
| 2111 | 2102 |
| 2112 // If there was a single non-const declaration, return it in the output | 2103 // If there was a single non-const declaration, return it in the output |
| 2113 // parameter for possible use by for/in. | 2104 // parameter for possible use by for/in. |
| 2114 if (nvars == 1 && !is_const) { | 2105 if (nvars == 1 && !is_const) { |
| 2115 *out = name; | 2106 *out = name; |
| 2116 } | 2107 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 2128 | 2119 |
| 2129 return false; | 2120 return false; |
| 2130 } | 2121 } |
| 2131 | 2122 |
| 2132 | 2123 |
| 2133 Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels, | 2124 Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels, |
| 2134 bool* ok) { | 2125 bool* ok) { |
| 2135 // ExpressionStatement | LabelledStatement :: | 2126 // ExpressionStatement | LabelledStatement :: |
| 2136 // Expression ';' | 2127 // Expression ';' |
| 2137 // Identifier ':' Statement | 2128 // Identifier ':' Statement |
| 2129 int pos = peek_position(); |
| 2138 bool starts_with_idenfifier = peek_any_identifier(); | 2130 bool starts_with_idenfifier = peek_any_identifier(); |
| 2139 Expression* expr = ParseExpression(true, CHECK_OK); | 2131 Expression* expr = ParseExpression(true, CHECK_OK); |
| 2140 if (peek() == Token::COLON && starts_with_idenfifier && expr != NULL && | 2132 if (peek() == Token::COLON && starts_with_idenfifier && expr != NULL && |
| 2141 expr->AsVariableProxy() != NULL && | 2133 expr->AsVariableProxy() != NULL && |
| 2142 !expr->AsVariableProxy()->is_this()) { | 2134 !expr->AsVariableProxy()->is_this()) { |
| 2143 // Expression is a single identifier, and not, e.g., a parenthesized | 2135 // Expression is a single identifier, and not, e.g., a parenthesized |
| 2144 // identifier. | 2136 // identifier. |
| 2145 VariableProxy* var = expr->AsVariableProxy(); | 2137 VariableProxy* var = expr->AsVariableProxy(); |
| 2146 Handle<String> label = var->name(); | 2138 Handle<String> label = var->name(); |
| 2147 // TODO(1240780): We don't check for redeclaration of labels | 2139 // TODO(1240780): We don't check for redeclaration of labels |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2187 // Only expect semicolon in the former case. | 2179 // Only expect semicolon in the former case. |
| 2188 if (!FLAG_harmony_modules || | 2180 if (!FLAG_harmony_modules || |
| 2189 peek() != Token::IDENTIFIER || | 2181 peek() != Token::IDENTIFIER || |
| 2190 scanner().HasAnyLineTerminatorBeforeNext() || | 2182 scanner().HasAnyLineTerminatorBeforeNext() || |
| 2191 expr->AsVariableProxy() == NULL || | 2183 expr->AsVariableProxy() == NULL || |
| 2192 !expr->AsVariableProxy()->name()->Equals( | 2184 !expr->AsVariableProxy()->name()->Equals( |
| 2193 isolate()->heap()->module_string()) || | 2185 isolate()->heap()->module_string()) || |
| 2194 scanner().literal_contains_escapes()) { | 2186 scanner().literal_contains_escapes()) { |
| 2195 ExpectSemicolon(CHECK_OK); | 2187 ExpectSemicolon(CHECK_OK); |
| 2196 } | 2188 } |
| 2197 return factory()->NewExpressionStatement(expr); | 2189 return factory()->NewExpressionStatement(expr, pos); |
| 2198 } | 2190 } |
| 2199 | 2191 |
| 2200 | 2192 |
| 2201 IfStatement* Parser::ParseIfStatement(ZoneStringList* labels, bool* ok) { | 2193 IfStatement* Parser::ParseIfStatement(ZoneStringList* labels, bool* ok) { |
| 2202 // IfStatement :: | 2194 // IfStatement :: |
| 2203 // 'if' '(' Expression ')' Statement ('else' Statement)? | 2195 // 'if' '(' Expression ')' Statement ('else' Statement)? |
| 2204 | 2196 |
| 2197 int pos = peek_position(); |
| 2205 Expect(Token::IF, CHECK_OK); | 2198 Expect(Token::IF, CHECK_OK); |
| 2206 Expect(Token::LPAREN, CHECK_OK); | 2199 Expect(Token::LPAREN, CHECK_OK); |
| 2207 Expression* condition = ParseExpression(true, CHECK_OK); | 2200 Expression* condition = ParseExpression(true, CHECK_OK); |
| 2208 Expect(Token::RPAREN, CHECK_OK); | 2201 Expect(Token::RPAREN, CHECK_OK); |
| 2209 Statement* then_statement = ParseStatement(labels, CHECK_OK); | 2202 Statement* then_statement = ParseStatement(labels, CHECK_OK); |
| 2210 Statement* else_statement = NULL; | 2203 Statement* else_statement = NULL; |
| 2211 if (peek() == Token::ELSE) { | 2204 if (peek() == Token::ELSE) { |
| 2212 Next(); | 2205 Next(); |
| 2213 else_statement = ParseStatement(labels, CHECK_OK); | 2206 else_statement = ParseStatement(labels, CHECK_OK); |
| 2214 } else { | 2207 } else { |
| 2215 else_statement = factory()->NewEmptyStatement(); | 2208 else_statement = factory()->NewEmptyStatement(RelocInfo::kNoPosition); |
| 2216 } | 2209 } |
| 2217 return factory()->NewIfStatement(condition, then_statement, else_statement); | 2210 return factory()->NewIfStatement( |
| 2211 condition, then_statement, else_statement, pos); |
| 2218 } | 2212 } |
| 2219 | 2213 |
| 2220 | 2214 |
| 2221 Statement* Parser::ParseContinueStatement(bool* ok) { | 2215 Statement* Parser::ParseContinueStatement(bool* ok) { |
| 2222 // ContinueStatement :: | 2216 // ContinueStatement :: |
| 2223 // 'continue' Identifier? ';' | 2217 // 'continue' Identifier? ';' |
| 2224 | 2218 |
| 2219 int pos = peek_position(); |
| 2225 Expect(Token::CONTINUE, CHECK_OK); | 2220 Expect(Token::CONTINUE, CHECK_OK); |
| 2226 Handle<String> label = Handle<String>::null(); | 2221 Handle<String> label = Handle<String>::null(); |
| 2227 Token::Value tok = peek(); | 2222 Token::Value tok = peek(); |
| 2228 if (!scanner().HasAnyLineTerminatorBeforeNext() && | 2223 if (!scanner().HasAnyLineTerminatorBeforeNext() && |
| 2229 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { | 2224 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { |
| 2230 label = ParseIdentifier(CHECK_OK); | 2225 label = ParseIdentifier(CHECK_OK); |
| 2231 } | 2226 } |
| 2232 IterationStatement* target = NULL; | 2227 IterationStatement* target = NULL; |
| 2233 target = LookupContinueTarget(label, CHECK_OK); | 2228 target = LookupContinueTarget(label, CHECK_OK); |
| 2234 if (target == NULL) { | 2229 if (target == NULL) { |
| 2235 // Illegal continue statement. | 2230 // Illegal continue statement. |
| 2236 const char* message = "illegal_continue"; | 2231 const char* message = "illegal_continue"; |
| 2237 Vector<Handle<String> > args; | 2232 Vector<Handle<String> > args; |
| 2238 if (!label.is_null()) { | 2233 if (!label.is_null()) { |
| 2239 message = "unknown_label"; | 2234 message = "unknown_label"; |
| 2240 args = Vector<Handle<String> >(&label, 1); | 2235 args = Vector<Handle<String> >(&label, 1); |
| 2241 } | 2236 } |
| 2242 ReportMessageAt(scanner().location(), message, args); | 2237 ReportMessageAt(scanner().location(), message, args); |
| 2243 *ok = false; | 2238 *ok = false; |
| 2244 return NULL; | 2239 return NULL; |
| 2245 } | 2240 } |
| 2246 ExpectSemicolon(CHECK_OK); | 2241 ExpectSemicolon(CHECK_OK); |
| 2247 return factory()->NewContinueStatement(target); | 2242 return factory()->NewContinueStatement(target, pos); |
| 2248 } | 2243 } |
| 2249 | 2244 |
| 2250 | 2245 |
| 2251 Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) { | 2246 Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) { |
| 2252 // BreakStatement :: | 2247 // BreakStatement :: |
| 2253 // 'break' Identifier? ';' | 2248 // 'break' Identifier? ';' |
| 2254 | 2249 |
| 2250 int pos = peek_position(); |
| 2255 Expect(Token::BREAK, CHECK_OK); | 2251 Expect(Token::BREAK, CHECK_OK); |
| 2256 Handle<String> label; | 2252 Handle<String> label; |
| 2257 Token::Value tok = peek(); | 2253 Token::Value tok = peek(); |
| 2258 if (!scanner().HasAnyLineTerminatorBeforeNext() && | 2254 if (!scanner().HasAnyLineTerminatorBeforeNext() && |
| 2259 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { | 2255 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { |
| 2260 label = ParseIdentifier(CHECK_OK); | 2256 label = ParseIdentifier(CHECK_OK); |
| 2261 } | 2257 } |
| 2262 // Parse labeled break statements that target themselves into | 2258 // Parse labeled break statements that target themselves into |
| 2263 // empty statements, e.g. 'l1: l2: l3: break l2;' | 2259 // empty statements, e.g. 'l1: l2: l3: break l2;' |
| 2264 if (!label.is_null() && ContainsLabel(labels, label)) { | 2260 if (!label.is_null() && ContainsLabel(labels, label)) { |
| 2265 ExpectSemicolon(CHECK_OK); | 2261 ExpectSemicolon(CHECK_OK); |
| 2266 return factory()->NewEmptyStatement(); | 2262 return factory()->NewEmptyStatement(pos); |
| 2267 } | 2263 } |
| 2268 BreakableStatement* target = NULL; | 2264 BreakableStatement* target = NULL; |
| 2269 target = LookupBreakTarget(label, CHECK_OK); | 2265 target = LookupBreakTarget(label, CHECK_OK); |
| 2270 if (target == NULL) { | 2266 if (target == NULL) { |
| 2271 // Illegal break statement. | 2267 // Illegal break statement. |
| 2272 const char* message = "illegal_break"; | 2268 const char* message = "illegal_break"; |
| 2273 Vector<Handle<String> > args; | 2269 Vector<Handle<String> > args; |
| 2274 if (!label.is_null()) { | 2270 if (!label.is_null()) { |
| 2275 message = "unknown_label"; | 2271 message = "unknown_label"; |
| 2276 args = Vector<Handle<String> >(&label, 1); | 2272 args = Vector<Handle<String> >(&label, 1); |
| 2277 } | 2273 } |
| 2278 ReportMessageAt(scanner().location(), message, args); | 2274 ReportMessageAt(scanner().location(), message, args); |
| 2279 *ok = false; | 2275 *ok = false; |
| 2280 return NULL; | 2276 return NULL; |
| 2281 } | 2277 } |
| 2282 ExpectSemicolon(CHECK_OK); | 2278 ExpectSemicolon(CHECK_OK); |
| 2283 return factory()->NewBreakStatement(target); | 2279 return factory()->NewBreakStatement(target, pos); |
| 2284 } | 2280 } |
| 2285 | 2281 |
| 2286 | 2282 |
| 2287 Statement* Parser::ParseReturnStatement(bool* ok) { | 2283 Statement* Parser::ParseReturnStatement(bool* ok) { |
| 2288 // ReturnStatement :: | 2284 // ReturnStatement :: |
| 2289 // 'return' Expression? ';' | 2285 // 'return' Expression? ';' |
| 2290 | 2286 |
| 2291 // Consume the return token. It is necessary to do the before | 2287 // Consume the return token. It is necessary to do that before |
| 2292 // reporting any errors on it, because of the way errors are | 2288 // reporting any errors on it, because of the way errors are |
| 2293 // reported (underlining). | 2289 // reported (underlining). |
| 2294 Expect(Token::RETURN, CHECK_OK); | 2290 Expect(Token::RETURN, CHECK_OK); |
| 2291 int pos = position(); |
| 2295 | 2292 |
| 2296 Token::Value tok = peek(); | 2293 Token::Value tok = peek(); |
| 2297 Statement* result; | 2294 Statement* result; |
| 2298 Expression* return_value; | 2295 Expression* return_value; |
| 2299 if (scanner().HasAnyLineTerminatorBeforeNext() || | 2296 if (scanner().HasAnyLineTerminatorBeforeNext() || |
| 2300 tok == Token::SEMICOLON || | 2297 tok == Token::SEMICOLON || |
| 2301 tok == Token::RBRACE || | 2298 tok == Token::RBRACE || |
| 2302 tok == Token::EOS) { | 2299 tok == Token::EOS) { |
| 2303 return_value = GetLiteralUndefined(); | 2300 return_value = GetLiteralUndefined(position()); |
| 2304 } else { | 2301 } else { |
| 2305 return_value = ParseExpression(true, CHECK_OK); | 2302 return_value = ParseExpression(true, CHECK_OK); |
| 2306 } | 2303 } |
| 2307 ExpectSemicolon(CHECK_OK); | 2304 ExpectSemicolon(CHECK_OK); |
| 2308 if (is_generator()) { | 2305 if (is_generator()) { |
| 2309 Expression* generator = factory()->NewVariableProxy( | 2306 Expression* generator = factory()->NewVariableProxy( |
| 2310 current_function_state_->generator_object_variable()); | 2307 current_function_state_->generator_object_variable()); |
| 2311 Expression* yield = factory()->NewYield( | 2308 Expression* yield = factory()->NewYield( |
| 2312 generator, return_value, Yield::FINAL, RelocInfo::kNoPosition); | 2309 generator, return_value, Yield::FINAL, pos); |
| 2313 result = factory()->NewExpressionStatement(yield); | 2310 result = factory()->NewExpressionStatement(yield, pos); |
| 2314 } else { | 2311 } else { |
| 2315 result = factory()->NewReturnStatement(return_value); | 2312 result = factory()->NewReturnStatement(return_value, pos); |
| 2316 } | 2313 } |
| 2317 | 2314 |
| 2318 // An ECMAScript program is considered syntactically incorrect if it | 2315 // An ECMAScript program is considered syntactically incorrect if it |
| 2319 // contains a return statement that is not within the body of a | 2316 // contains a return statement that is not within the body of a |
| 2320 // function. See ECMA-262, section 12.9, page 67. | 2317 // function. See ECMA-262, section 12.9, page 67. |
| 2321 // | 2318 // |
| 2322 // To be consistent with KJS we report the syntax error at runtime. | 2319 // To be consistent with KJS we report the syntax error at runtime. |
| 2323 Scope* declaration_scope = top_scope_->DeclarationScope(); | 2320 Scope* declaration_scope = top_scope_->DeclarationScope(); |
| 2324 if (declaration_scope->is_global_scope() || | 2321 if (declaration_scope->is_global_scope() || |
| 2325 declaration_scope->is_eval_scope()) { | 2322 declaration_scope->is_eval_scope()) { |
| 2326 Handle<String> message = isolate()->factory()->illegal_return_string(); | 2323 Handle<String> message = isolate()->factory()->illegal_return_string(); |
| 2327 Expression* throw_error = | 2324 Expression* throw_error = |
| 2328 NewThrowSyntaxError(message, Handle<Object>::null()); | 2325 NewThrowSyntaxError(message, Handle<Object>::null()); |
| 2329 return factory()->NewExpressionStatement(throw_error); | 2326 return factory()->NewExpressionStatement(throw_error, pos); |
| 2330 } | 2327 } |
| 2331 return result; | 2328 return result; |
| 2332 } | 2329 } |
| 2333 | 2330 |
| 2334 | 2331 |
| 2335 Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) { | 2332 Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) { |
| 2336 // WithStatement :: | 2333 // WithStatement :: |
| 2337 // 'with' '(' Expression ')' Statement | 2334 // 'with' '(' Expression ')' Statement |
| 2338 | 2335 |
| 2339 Expect(Token::WITH, CHECK_OK); | 2336 Expect(Token::WITH, CHECK_OK); |
| 2337 int pos = position(); |
| 2340 | 2338 |
| 2341 if (!top_scope_->is_classic_mode()) { | 2339 if (!top_scope_->is_classic_mode()) { |
| 2342 ReportMessage("strict_mode_with", Vector<const char*>::empty()); | 2340 ReportMessage("strict_mode_with", Vector<const char*>::empty()); |
| 2343 *ok = false; | 2341 *ok = false; |
| 2344 return NULL; | 2342 return NULL; |
| 2345 } | 2343 } |
| 2346 | 2344 |
| 2347 Expect(Token::LPAREN, CHECK_OK); | 2345 Expect(Token::LPAREN, CHECK_OK); |
| 2348 Expression* expr = ParseExpression(true, CHECK_OK); | 2346 Expression* expr = ParseExpression(true, CHECK_OK); |
| 2349 Expect(Token::RPAREN, CHECK_OK); | 2347 Expect(Token::RPAREN, CHECK_OK); |
| 2350 | 2348 |
| 2351 top_scope_->DeclarationScope()->RecordWithStatement(); | 2349 top_scope_->DeclarationScope()->RecordWithStatement(); |
| 2352 Scope* with_scope = NewScope(top_scope_, WITH_SCOPE); | 2350 Scope* with_scope = NewScope(top_scope_, WITH_SCOPE); |
| 2353 Statement* stmt; | 2351 Statement* stmt; |
| 2354 { BlockState block_state(this, with_scope); | 2352 { BlockState block_state(this, with_scope); |
| 2355 with_scope->set_start_position(scanner().peek_location().beg_pos); | 2353 with_scope->set_start_position(scanner().peek_location().beg_pos); |
| 2356 stmt = ParseStatement(labels, CHECK_OK); | 2354 stmt = ParseStatement(labels, CHECK_OK); |
| 2357 with_scope->set_end_position(scanner().location().end_pos); | 2355 with_scope->set_end_position(scanner().location().end_pos); |
| 2358 } | 2356 } |
| 2359 return factory()->NewWithStatement(with_scope, expr, stmt); | 2357 return factory()->NewWithStatement(with_scope, expr, stmt, pos); |
| 2360 } | 2358 } |
| 2361 | 2359 |
| 2362 | 2360 |
| 2363 CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) { | 2361 CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) { |
| 2364 // CaseClause :: | 2362 // CaseClause :: |
| 2365 // 'case' Expression ':' Statement* | 2363 // 'case' Expression ':' Statement* |
| 2366 // 'default' ':' Statement* | 2364 // 'default' ':' Statement* |
| 2367 | 2365 |
| 2368 Expression* label = NULL; // NULL expression indicates default case | 2366 Expression* label = NULL; // NULL expression indicates default case |
| 2369 if (peek() == Token::CASE) { | 2367 if (peek() == Token::CASE) { |
| 2370 Expect(Token::CASE, CHECK_OK); | 2368 Expect(Token::CASE, CHECK_OK); |
| 2371 label = ParseExpression(true, CHECK_OK); | 2369 label = ParseExpression(true, CHECK_OK); |
| 2372 } else { | 2370 } else { |
| 2373 Expect(Token::DEFAULT, CHECK_OK); | 2371 Expect(Token::DEFAULT, CHECK_OK); |
| 2374 if (*default_seen_ptr) { | 2372 if (*default_seen_ptr) { |
| 2375 ReportMessage("multiple_defaults_in_switch", | 2373 ReportMessage("multiple_defaults_in_switch", |
| 2376 Vector<const char*>::empty()); | 2374 Vector<const char*>::empty()); |
| 2377 *ok = false; | 2375 *ok = false; |
| 2378 return NULL; | 2376 return NULL; |
| 2379 } | 2377 } |
| 2380 *default_seen_ptr = true; | 2378 *default_seen_ptr = true; |
| 2381 } | 2379 } |
| 2382 Expect(Token::COLON, CHECK_OK); | 2380 Expect(Token::COLON, CHECK_OK); |
| 2383 int pos = scanner().location().beg_pos; | 2381 int pos = position(); |
| 2384 ZoneList<Statement*>* statements = | 2382 ZoneList<Statement*>* statements = |
| 2385 new(zone()) ZoneList<Statement*>(5, zone()); | 2383 new(zone()) ZoneList<Statement*>(5, zone()); |
| 2386 while (peek() != Token::CASE && | 2384 while (peek() != Token::CASE && |
| 2387 peek() != Token::DEFAULT && | 2385 peek() != Token::DEFAULT && |
| 2388 peek() != Token::RBRACE) { | 2386 peek() != Token::RBRACE) { |
| 2389 Statement* stat = ParseStatement(NULL, CHECK_OK); | 2387 Statement* stat = ParseStatement(NULL, CHECK_OK); |
| 2390 statements->Add(stat, zone()); | 2388 statements->Add(stat, zone()); |
| 2391 } | 2389 } |
| 2392 | 2390 |
| 2393 return new(zone()) CaseClause(isolate(), label, statements, pos); | 2391 return factory()->NewCaseClause(label, statements, pos); |
| 2394 } | 2392 } |
| 2395 | 2393 |
| 2396 | 2394 |
| 2397 SwitchStatement* Parser::ParseSwitchStatement(ZoneStringList* labels, | 2395 SwitchStatement* Parser::ParseSwitchStatement(ZoneStringList* labels, |
| 2398 bool* ok) { | 2396 bool* ok) { |
| 2399 // SwitchStatement :: | 2397 // SwitchStatement :: |
| 2400 // 'switch' '(' Expression ')' '{' CaseClause* '}' | 2398 // 'switch' '(' Expression ')' '{' CaseClause* '}' |
| 2401 | 2399 |
| 2402 SwitchStatement* statement = factory()->NewSwitchStatement(labels); | 2400 SwitchStatement* statement = |
| 2401 factory()->NewSwitchStatement(labels, peek_position()); |
| 2403 Target target(&this->target_stack_, statement); | 2402 Target target(&this->target_stack_, statement); |
| 2404 | 2403 |
| 2405 Expect(Token::SWITCH, CHECK_OK); | 2404 Expect(Token::SWITCH, CHECK_OK); |
| 2406 Expect(Token::LPAREN, CHECK_OK); | 2405 Expect(Token::LPAREN, CHECK_OK); |
| 2407 Expression* tag = ParseExpression(true, CHECK_OK); | 2406 Expression* tag = ParseExpression(true, CHECK_OK); |
| 2408 Expect(Token::RPAREN, CHECK_OK); | 2407 Expect(Token::RPAREN, CHECK_OK); |
| 2409 | 2408 |
| 2410 bool default_seen = false; | 2409 bool default_seen = false; |
| 2411 ZoneList<CaseClause*>* cases = new(zone()) ZoneList<CaseClause*>(4, zone()); | 2410 ZoneList<CaseClause*>* cases = new(zone()) ZoneList<CaseClause*>(4, zone()); |
| 2412 Expect(Token::LBRACE, CHECK_OK); | 2411 Expect(Token::LBRACE, CHECK_OK); |
| 2413 while (peek() != Token::RBRACE) { | 2412 while (peek() != Token::RBRACE) { |
| 2414 CaseClause* clause = ParseCaseClause(&default_seen, CHECK_OK); | 2413 CaseClause* clause = ParseCaseClause(&default_seen, CHECK_OK); |
| 2415 cases->Add(clause, zone()); | 2414 cases->Add(clause, zone()); |
| 2416 } | 2415 } |
| 2417 Expect(Token::RBRACE, CHECK_OK); | 2416 Expect(Token::RBRACE, CHECK_OK); |
| 2418 | 2417 |
| 2419 if (statement) statement->Initialize(tag, cases); | 2418 if (statement) statement->Initialize(tag, cases); |
| 2420 return statement; | 2419 return statement; |
| 2421 } | 2420 } |
| 2422 | 2421 |
| 2423 | 2422 |
| 2424 Statement* Parser::ParseThrowStatement(bool* ok) { | 2423 Statement* Parser::ParseThrowStatement(bool* ok) { |
| 2425 // ThrowStatement :: | 2424 // ThrowStatement :: |
| 2426 // 'throw' Expression ';' | 2425 // 'throw' Expression ';' |
| 2427 | 2426 |
| 2428 Expect(Token::THROW, CHECK_OK); | 2427 Expect(Token::THROW, CHECK_OK); |
| 2429 int pos = scanner().location().beg_pos; | 2428 int pos = position(); |
| 2430 if (scanner().HasAnyLineTerminatorBeforeNext()) { | 2429 if (scanner().HasAnyLineTerminatorBeforeNext()) { |
| 2431 ReportMessage("newline_after_throw", Vector<const char*>::empty()); | 2430 ReportMessage("newline_after_throw", Vector<const char*>::empty()); |
| 2432 *ok = false; | 2431 *ok = false; |
| 2433 return NULL; | 2432 return NULL; |
| 2434 } | 2433 } |
| 2435 Expression* exception = ParseExpression(true, CHECK_OK); | 2434 Expression* exception = ParseExpression(true, CHECK_OK); |
| 2436 ExpectSemicolon(CHECK_OK); | 2435 ExpectSemicolon(CHECK_OK); |
| 2437 | 2436 |
| 2438 return factory()->NewExpressionStatement(factory()->NewThrow(exception, pos)); | 2437 return factory()->NewExpressionStatement( |
| 2438 factory()->NewThrow(exception, pos), pos); |
| 2439 } | 2439 } |
| 2440 | 2440 |
| 2441 | 2441 |
| 2442 TryStatement* Parser::ParseTryStatement(bool* ok) { | 2442 TryStatement* Parser::ParseTryStatement(bool* ok) { |
| 2443 // TryStatement :: | 2443 // TryStatement :: |
| 2444 // 'try' Block Catch | 2444 // 'try' Block Catch |
| 2445 // 'try' Block Finally | 2445 // 'try' Block Finally |
| 2446 // 'try' Block Catch Finally | 2446 // 'try' Block Catch Finally |
| 2447 // | 2447 // |
| 2448 // Catch :: | 2448 // Catch :: |
| 2449 // 'catch' '(' Identifier ')' Block | 2449 // 'catch' '(' Identifier ')' Block |
| 2450 // | 2450 // |
| 2451 // Finally :: | 2451 // Finally :: |
| 2452 // 'finally' Block | 2452 // 'finally' Block |
| 2453 | 2453 |
| 2454 Expect(Token::TRY, CHECK_OK); | 2454 Expect(Token::TRY, CHECK_OK); |
| 2455 int pos = position(); |
| 2455 | 2456 |
| 2456 TargetCollector try_collector(zone()); | 2457 TargetCollector try_collector(zone()); |
| 2457 Block* try_block; | 2458 Block* try_block; |
| 2458 | 2459 |
| 2459 { Target target(&this->target_stack_, &try_collector); | 2460 { Target target(&this->target_stack_, &try_collector); |
| 2460 try_block = ParseBlock(NULL, CHECK_OK); | 2461 try_block = ParseBlock(NULL, CHECK_OK); |
| 2461 } | 2462 } |
| 2462 | 2463 |
| 2463 Token::Value tok = peek(); | 2464 Token::Value tok = peek(); |
| 2464 if (tok != Token::CATCH && tok != Token::FINALLY) { | 2465 if (tok != Token::CATCH && tok != Token::FINALLY) { |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2516 // Simplify the AST nodes by converting: | 2517 // Simplify the AST nodes by converting: |
| 2517 // 'try B0 catch B1 finally B2' | 2518 // 'try B0 catch B1 finally B2' |
| 2518 // to: | 2519 // to: |
| 2519 // 'try { try B0 catch B1 } finally B2' | 2520 // 'try { try B0 catch B1 } finally B2' |
| 2520 | 2521 |
| 2521 if (catch_block != NULL && finally_block != NULL) { | 2522 if (catch_block != NULL && finally_block != NULL) { |
| 2522 // If we have both, create an inner try/catch. | 2523 // If we have both, create an inner try/catch. |
| 2523 ASSERT(catch_scope != NULL && catch_variable != NULL); | 2524 ASSERT(catch_scope != NULL && catch_variable != NULL); |
| 2524 int index = current_function_state_->NextHandlerIndex(); | 2525 int index = current_function_state_->NextHandlerIndex(); |
| 2525 TryCatchStatement* statement = factory()->NewTryCatchStatement( | 2526 TryCatchStatement* statement = factory()->NewTryCatchStatement( |
| 2526 index, try_block, catch_scope, catch_variable, catch_block); | 2527 index, try_block, catch_scope, catch_variable, catch_block, |
| 2528 RelocInfo::kNoPosition); |
| 2527 statement->set_escaping_targets(try_collector.targets()); | 2529 statement->set_escaping_targets(try_collector.targets()); |
| 2528 try_block = factory()->NewBlock(NULL, 1, false); | 2530 try_block = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition); |
| 2529 try_block->AddStatement(statement, zone()); | 2531 try_block->AddStatement(statement, zone()); |
| 2530 catch_block = NULL; // Clear to indicate it's been handled. | 2532 catch_block = NULL; // Clear to indicate it's been handled. |
| 2531 } | 2533 } |
| 2532 | 2534 |
| 2533 TryStatement* result = NULL; | 2535 TryStatement* result = NULL; |
| 2534 if (catch_block != NULL) { | 2536 if (catch_block != NULL) { |
| 2535 ASSERT(finally_block == NULL); | 2537 ASSERT(finally_block == NULL); |
| 2536 ASSERT(catch_scope != NULL && catch_variable != NULL); | 2538 ASSERT(catch_scope != NULL && catch_variable != NULL); |
| 2537 int index = current_function_state_->NextHandlerIndex(); | 2539 int index = current_function_state_->NextHandlerIndex(); |
| 2538 result = factory()->NewTryCatchStatement( | 2540 result = factory()->NewTryCatchStatement( |
| 2539 index, try_block, catch_scope, catch_variable, catch_block); | 2541 index, try_block, catch_scope, catch_variable, catch_block, pos); |
| 2540 } else { | 2542 } else { |
| 2541 ASSERT(finally_block != NULL); | 2543 ASSERT(finally_block != NULL); |
| 2542 int index = current_function_state_->NextHandlerIndex(); | 2544 int index = current_function_state_->NextHandlerIndex(); |
| 2543 result = factory()->NewTryFinallyStatement(index, try_block, finally_block); | 2545 result = factory()->NewTryFinallyStatement( |
| 2546 index, try_block, finally_block, pos); |
| 2544 // Combine the jump targets of the try block and the possible catch block. | 2547 // Combine the jump targets of the try block and the possible catch block. |
| 2545 try_collector.targets()->AddAll(*catch_collector.targets(), zone()); | 2548 try_collector.targets()->AddAll(*catch_collector.targets(), zone()); |
| 2546 } | 2549 } |
| 2547 | 2550 |
| 2548 result->set_escaping_targets(try_collector.targets()); | 2551 result->set_escaping_targets(try_collector.targets()); |
| 2549 return result; | 2552 return result; |
| 2550 } | 2553 } |
| 2551 | 2554 |
| 2552 | 2555 |
| 2553 DoWhileStatement* Parser::ParseDoWhileStatement(ZoneStringList* labels, | 2556 DoWhileStatement* Parser::ParseDoWhileStatement(ZoneStringList* labels, |
| 2554 bool* ok) { | 2557 bool* ok) { |
| 2555 // DoStatement :: | 2558 // DoStatement :: |
| 2556 // 'do' Statement 'while' '(' Expression ')' ';' | 2559 // 'do' Statement 'while' '(' Expression ')' ';' |
| 2557 | 2560 |
| 2558 DoWhileStatement* loop = factory()->NewDoWhileStatement(labels); | 2561 DoWhileStatement* loop = |
| 2562 factory()->NewDoWhileStatement(labels, peek_position()); |
| 2559 Target target(&this->target_stack_, loop); | 2563 Target target(&this->target_stack_, loop); |
| 2560 | 2564 |
| 2561 Expect(Token::DO, CHECK_OK); | 2565 Expect(Token::DO, CHECK_OK); |
| 2562 Statement* body = ParseStatement(NULL, CHECK_OK); | 2566 Statement* body = ParseStatement(NULL, CHECK_OK); |
| 2563 Expect(Token::WHILE, CHECK_OK); | 2567 Expect(Token::WHILE, CHECK_OK); |
| 2564 Expect(Token::LPAREN, CHECK_OK); | 2568 Expect(Token::LPAREN, CHECK_OK); |
| 2565 | 2569 |
| 2566 if (loop != NULL) { | |
| 2567 int position = scanner().location().beg_pos; | |
| 2568 loop->set_condition_position(position); | |
| 2569 } | |
| 2570 | |
| 2571 Expression* cond = ParseExpression(true, CHECK_OK); | 2570 Expression* cond = ParseExpression(true, CHECK_OK); |
| 2572 Expect(Token::RPAREN, CHECK_OK); | 2571 Expect(Token::RPAREN, CHECK_OK); |
| 2573 | 2572 |
| 2574 // Allow do-statements to be terminated with and without | 2573 // Allow do-statements to be terminated with and without |
| 2575 // semi-colons. This allows code such as 'do;while(0)return' to | 2574 // semi-colons. This allows code such as 'do;while(0)return' to |
| 2576 // parse, which would not be the case if we had used the | 2575 // parse, which would not be the case if we had used the |
| 2577 // ExpectSemicolon() functionality here. | 2576 // ExpectSemicolon() functionality here. |
| 2578 if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON); | 2577 if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON); |
| 2579 | 2578 |
| 2580 if (loop != NULL) loop->Initialize(cond, body); | 2579 if (loop != NULL) loop->Initialize(cond, body); |
| 2581 return loop; | 2580 return loop; |
| 2582 } | 2581 } |
| 2583 | 2582 |
| 2584 | 2583 |
| 2585 WhileStatement* Parser::ParseWhileStatement(ZoneStringList* labels, bool* ok) { | 2584 WhileStatement* Parser::ParseWhileStatement(ZoneStringList* labels, bool* ok) { |
| 2586 // WhileStatement :: | 2585 // WhileStatement :: |
| 2587 // 'while' '(' Expression ')' Statement | 2586 // 'while' '(' Expression ')' Statement |
| 2588 | 2587 |
| 2589 WhileStatement* loop = factory()->NewWhileStatement(labels); | 2588 WhileStatement* loop = factory()->NewWhileStatement(labels, peek_position()); |
| 2590 Target target(&this->target_stack_, loop); | 2589 Target target(&this->target_stack_, loop); |
| 2591 | 2590 |
| 2592 Expect(Token::WHILE, CHECK_OK); | 2591 Expect(Token::WHILE, CHECK_OK); |
| 2593 Expect(Token::LPAREN, CHECK_OK); | 2592 Expect(Token::LPAREN, CHECK_OK); |
| 2594 Expression* cond = ParseExpression(true, CHECK_OK); | 2593 Expression* cond = ParseExpression(true, CHECK_OK); |
| 2595 Expect(Token::RPAREN, CHECK_OK); | 2594 Expect(Token::RPAREN, CHECK_OK); |
| 2596 Statement* body = ParseStatement(NULL, CHECK_OK); | 2595 Statement* body = ParseStatement(NULL, CHECK_OK); |
| 2597 | 2596 |
| 2598 if (loop != NULL) loop->Initialize(cond, body); | 2597 if (loop != NULL) loop->Initialize(cond, body); |
| 2599 return loop; | 2598 return loop; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2638 // var iterator = iterable; | 2637 // var iterator = iterable; |
| 2639 { | 2638 { |
| 2640 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); | 2639 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); |
| 2641 assign_iterator = factory()->NewAssignment( | 2640 assign_iterator = factory()->NewAssignment( |
| 2642 Token::ASSIGN, iterator_proxy, subject, RelocInfo::kNoPosition); | 2641 Token::ASSIGN, iterator_proxy, subject, RelocInfo::kNoPosition); |
| 2643 } | 2642 } |
| 2644 | 2643 |
| 2645 // var result = iterator.next(); | 2644 // var result = iterator.next(); |
| 2646 { | 2645 { |
| 2647 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); | 2646 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); |
| 2648 Expression* next_literal = | 2647 Expression* next_literal = factory()->NewLiteral( |
| 2649 factory()->NewLiteral(heap_factory->next_string()); | 2648 heap_factory->next_string(), RelocInfo::kNoPosition); |
| 2650 Expression* next_property = factory()->NewProperty( | 2649 Expression* next_property = factory()->NewProperty( |
| 2651 iterator_proxy, next_literal, RelocInfo::kNoPosition); | 2650 iterator_proxy, next_literal, RelocInfo::kNoPosition); |
| 2652 ZoneList<Expression*>* next_arguments = | 2651 ZoneList<Expression*>* next_arguments = |
| 2653 new(zone()) ZoneList<Expression*>(0, zone()); | 2652 new(zone()) ZoneList<Expression*>(0, zone()); |
| 2654 Expression* next_call = factory()->NewCall( | 2653 Expression* next_call = factory()->NewCall( |
| 2655 next_property, next_arguments, RelocInfo::kNoPosition); | 2654 next_property, next_arguments, RelocInfo::kNoPosition); |
| 2656 Expression* result_proxy = factory()->NewVariableProxy(result); | 2655 Expression* result_proxy = factory()->NewVariableProxy(result); |
| 2657 next_result = factory()->NewAssignment( | 2656 next_result = factory()->NewAssignment( |
| 2658 Token::ASSIGN, result_proxy, next_call, RelocInfo::kNoPosition); | 2657 Token::ASSIGN, result_proxy, next_call, RelocInfo::kNoPosition); |
| 2659 } | 2658 } |
| 2660 | 2659 |
| 2661 // result.done | 2660 // result.done |
| 2662 { | 2661 { |
| 2663 Expression* done_literal = | 2662 Expression* done_literal = factory()->NewLiteral( |
| 2664 factory()->NewLiteral(heap_factory->done_string()); | 2663 heap_factory->done_string(), RelocInfo::kNoPosition); |
| 2665 Expression* result_proxy = factory()->NewVariableProxy(result); | 2664 Expression* result_proxy = factory()->NewVariableProxy(result); |
| 2666 result_done = factory()->NewProperty( | 2665 result_done = factory()->NewProperty( |
| 2667 result_proxy, done_literal, RelocInfo::kNoPosition); | 2666 result_proxy, done_literal, RelocInfo::kNoPosition); |
| 2668 } | 2667 } |
| 2669 | 2668 |
| 2670 // each = result.value | 2669 // each = result.value |
| 2671 { | 2670 { |
| 2672 Expression* value_literal = | 2671 Expression* value_literal = factory()->NewLiteral( |
| 2673 factory()->NewLiteral(heap_factory->value_string()); | 2672 heap_factory->value_string(), RelocInfo::kNoPosition); |
| 2674 Expression* result_proxy = factory()->NewVariableProxy(result); | 2673 Expression* result_proxy = factory()->NewVariableProxy(result); |
| 2675 Expression* result_value = factory()->NewProperty( | 2674 Expression* result_value = factory()->NewProperty( |
| 2676 result_proxy, value_literal, RelocInfo::kNoPosition); | 2675 result_proxy, value_literal, RelocInfo::kNoPosition); |
| 2677 assign_each = factory()->NewAssignment( | 2676 assign_each = factory()->NewAssignment( |
| 2678 Token::ASSIGN, each, result_value, RelocInfo::kNoPosition); | 2677 Token::ASSIGN, each, result_value, RelocInfo::kNoPosition); |
| 2679 } | 2678 } |
| 2680 | 2679 |
| 2681 for_of->Initialize(each, subject, body, | 2680 for_of->Initialize(each, subject, body, |
| 2682 assign_iterator, next_result, result_done, assign_each); | 2681 assign_iterator, next_result, result_done, assign_each); |
| 2683 } else { | 2682 } else { |
| 2684 stmt->Initialize(each, subject, body); | 2683 stmt->Initialize(each, subject, body); |
| 2685 } | 2684 } |
| 2686 } | 2685 } |
| 2687 | 2686 |
| 2688 | 2687 |
| 2689 Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { | 2688 Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { |
| 2690 // ForStatement :: | 2689 // ForStatement :: |
| 2691 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement | 2690 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement |
| 2692 | 2691 |
| 2692 int pos = peek_position(); |
| 2693 Statement* init = NULL; | 2693 Statement* init = NULL; |
| 2694 | 2694 |
| 2695 // Create an in-between scope for let-bound iteration variables. | 2695 // Create an in-between scope for let-bound iteration variables. |
| 2696 Scope* saved_scope = top_scope_; | 2696 Scope* saved_scope = top_scope_; |
| 2697 Scope* for_scope = NewScope(top_scope_, BLOCK_SCOPE); | 2697 Scope* for_scope = NewScope(top_scope_, BLOCK_SCOPE); |
| 2698 top_scope_ = for_scope; | 2698 top_scope_ = for_scope; |
| 2699 | 2699 |
| 2700 Expect(Token::FOR, CHECK_OK); | 2700 Expect(Token::FOR, CHECK_OK); |
| 2701 Expect(Token::LPAREN, CHECK_OK); | 2701 Expect(Token::LPAREN, CHECK_OK); |
| 2702 for_scope->set_start_position(scanner().location().beg_pos); | 2702 for_scope->set_start_position(scanner().location().beg_pos); |
| 2703 if (peek() != Token::SEMICOLON) { | 2703 if (peek() != Token::SEMICOLON) { |
| 2704 if (peek() == Token::VAR || peek() == Token::CONST) { | 2704 if (peek() == Token::VAR || peek() == Token::CONST) { |
| 2705 bool is_const = peek() == Token::CONST; | 2705 bool is_const = peek() == Token::CONST; |
| 2706 Handle<String> name; | 2706 Handle<String> name; |
| 2707 VariableDeclarationProperties decl_props = kHasNoInitializers; | 2707 VariableDeclarationProperties decl_props = kHasNoInitializers; |
| 2708 Block* variable_statement = | 2708 Block* variable_statement = |
| 2709 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name, | 2709 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name, |
| 2710 CHECK_OK); | 2710 CHECK_OK); |
| 2711 bool accept_OF = decl_props == kHasNoInitializers; | 2711 bool accept_OF = decl_props == kHasNoInitializers; |
| 2712 ForEachStatement::VisitMode mode; | 2712 ForEachStatement::VisitMode mode; |
| 2713 | 2713 |
| 2714 if (!name.is_null() && CheckInOrOf(accept_OF, &mode)) { | 2714 if (!name.is_null() && CheckInOrOf(accept_OF, &mode)) { |
| 2715 Interface* interface = | 2715 Interface* interface = |
| 2716 is_const ? Interface::NewConst() : Interface::NewValue(); | 2716 is_const ? Interface::NewConst() : Interface::NewValue(); |
| 2717 ForEachStatement* loop = factory()->NewForEachStatement(mode, labels); | 2717 ForEachStatement* loop = |
| 2718 factory()->NewForEachStatement(mode, labels, pos); |
| 2718 Target target(&this->target_stack_, loop); | 2719 Target target(&this->target_stack_, loop); |
| 2719 | 2720 |
| 2720 Expression* enumerable = ParseExpression(true, CHECK_OK); | 2721 Expression* enumerable = ParseExpression(true, CHECK_OK); |
| 2721 Expect(Token::RPAREN, CHECK_OK); | 2722 Expect(Token::RPAREN, CHECK_OK); |
| 2722 | 2723 |
| 2723 VariableProxy* each = | 2724 VariableProxy* each = |
| 2724 top_scope_->NewUnresolved(factory(), name, interface); | 2725 top_scope_->NewUnresolved(factory(), name, interface); |
| 2725 Statement* body = ParseStatement(NULL, CHECK_OK); | 2726 Statement* body = ParseStatement(NULL, CHECK_OK); |
| 2726 InitializeForEachStatement(loop, each, enumerable, body); | 2727 InitializeForEachStatement(loop, each, enumerable, body); |
| 2727 Block* result = factory()->NewBlock(NULL, 2, false); | 2728 Block* result = |
| 2729 factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition); |
| 2728 result->AddStatement(variable_statement, zone()); | 2730 result->AddStatement(variable_statement, zone()); |
| 2729 result->AddStatement(loop, zone()); | 2731 result->AddStatement(loop, zone()); |
| 2730 top_scope_ = saved_scope; | 2732 top_scope_ = saved_scope; |
| 2731 for_scope->set_end_position(scanner().location().end_pos); | 2733 for_scope->set_end_position(scanner().location().end_pos); |
| 2732 for_scope = for_scope->FinalizeBlockScope(); | 2734 for_scope = for_scope->FinalizeBlockScope(); |
| 2733 ASSERT(for_scope == NULL); | 2735 ASSERT(for_scope == NULL); |
| 2734 // Parsed for-in loop w/ variable/const declaration. | 2736 // Parsed for-in loop w/ variable/const declaration. |
| 2735 return result; | 2737 return result; |
| 2736 } else { | 2738 } else { |
| 2737 init = variable_statement; | 2739 init = variable_statement; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 2761 // } | 2763 // } |
| 2762 | 2764 |
| 2763 // TODO(keuchel): Move the temporary variable to the block scope, after | 2765 // TODO(keuchel): Move the temporary variable to the block scope, after |
| 2764 // implementing stack allocated block scoped variables. | 2766 // implementing stack allocated block scoped variables. |
| 2765 Factory* heap_factory = isolate()->factory(); | 2767 Factory* heap_factory = isolate()->factory(); |
| 2766 Handle<String> tempstr = | 2768 Handle<String> tempstr = |
| 2767 heap_factory->NewConsString(heap_factory->dot_for_string(), name); | 2769 heap_factory->NewConsString(heap_factory->dot_for_string(), name); |
| 2768 Handle<String> tempname = heap_factory->InternalizeString(tempstr); | 2770 Handle<String> tempname = heap_factory->InternalizeString(tempstr); |
| 2769 Variable* temp = top_scope_->DeclarationScope()->NewTemporary(tempname); | 2771 Variable* temp = top_scope_->DeclarationScope()->NewTemporary(tempname); |
| 2770 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); | 2772 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); |
| 2771 ForEachStatement* loop = factory()->NewForEachStatement(mode, labels); | 2773 ForEachStatement* loop = |
| 2774 factory()->NewForEachStatement(mode, labels, pos); |
| 2772 Target target(&this->target_stack_, loop); | 2775 Target target(&this->target_stack_, loop); |
| 2773 | 2776 |
| 2774 // The expression does not see the loop variable. | 2777 // The expression does not see the loop variable. |
| 2775 top_scope_ = saved_scope; | 2778 top_scope_ = saved_scope; |
| 2776 Expression* enumerable = ParseExpression(true, CHECK_OK); | 2779 Expression* enumerable = ParseExpression(true, CHECK_OK); |
| 2777 top_scope_ = for_scope; | 2780 top_scope_ = for_scope; |
| 2778 Expect(Token::RPAREN, CHECK_OK); | 2781 Expect(Token::RPAREN, CHECK_OK); |
| 2779 | 2782 |
| 2780 VariableProxy* each = | 2783 VariableProxy* each = |
| 2781 top_scope_->NewUnresolved(factory(), name, Interface::NewValue()); | 2784 top_scope_->NewUnresolved(factory(), name, Interface::NewValue()); |
| 2782 Statement* body = ParseStatement(NULL, CHECK_OK); | 2785 Statement* body = ParseStatement(NULL, CHECK_OK); |
| 2783 Block* body_block = factory()->NewBlock(NULL, 3, false); | 2786 Block* body_block = |
| 2787 factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition); |
| 2784 Assignment* assignment = factory()->NewAssignment( | 2788 Assignment* assignment = factory()->NewAssignment( |
| 2785 Token::ASSIGN, each, temp_proxy, RelocInfo::kNoPosition); | 2789 Token::ASSIGN, each, temp_proxy, RelocInfo::kNoPosition); |
| 2786 Statement* assignment_statement = | 2790 Statement* assignment_statement = factory()->NewExpressionStatement( |
| 2787 factory()->NewExpressionStatement(assignment); | 2791 assignment, RelocInfo::kNoPosition); |
| 2788 body_block->AddStatement(variable_statement, zone()); | 2792 body_block->AddStatement(variable_statement, zone()); |
| 2789 body_block->AddStatement(assignment_statement, zone()); | 2793 body_block->AddStatement(assignment_statement, zone()); |
| 2790 body_block->AddStatement(body, zone()); | 2794 body_block->AddStatement(body, zone()); |
| 2791 InitializeForEachStatement(loop, temp_proxy, enumerable, body_block); | 2795 InitializeForEachStatement(loop, temp_proxy, enumerable, body_block); |
| 2792 top_scope_ = saved_scope; | 2796 top_scope_ = saved_scope; |
| 2793 for_scope->set_end_position(scanner().location().end_pos); | 2797 for_scope->set_end_position(scanner().location().end_pos); |
| 2794 for_scope = for_scope->FinalizeBlockScope(); | 2798 for_scope = for_scope->FinalizeBlockScope(); |
| 2795 body_block->set_scope(for_scope); | 2799 body_block->set_scope(for_scope); |
| 2796 // Parsed for-in loop w/ let declaration. | 2800 // Parsed for-in loop w/ let declaration. |
| 2797 return loop; | 2801 return loop; |
| 2798 | 2802 |
| 2799 } else { | 2803 } else { |
| 2800 init = variable_statement; | 2804 init = variable_statement; |
| 2801 } | 2805 } |
| 2802 } else { | 2806 } else { |
| 2803 Expression* expression = ParseExpression(false, CHECK_OK); | 2807 Expression* expression = ParseExpression(false, CHECK_OK); |
| 2804 ForEachStatement::VisitMode mode; | 2808 ForEachStatement::VisitMode mode; |
| 2805 bool accept_OF = expression->AsVariableProxy(); | 2809 bool accept_OF = expression->AsVariableProxy(); |
| 2806 | 2810 |
| 2807 if (CheckInOrOf(accept_OF, &mode)) { | 2811 if (CheckInOrOf(accept_OF, &mode)) { |
| 2808 // Signal a reference error if the expression is an invalid | 2812 // Signal a reference error if the expression is an invalid |
| 2809 // left-hand side expression. We could report this as a syntax | 2813 // left-hand side expression. We could report this as a syntax |
| 2810 // error here but for compatibility with JSC we choose to report | 2814 // error here but for compatibility with JSC we choose to report |
| 2811 // the error at runtime. | 2815 // the error at runtime. |
| 2812 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 2816 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
| 2813 Handle<String> message = | 2817 Handle<String> message = |
| 2814 isolate()->factory()->invalid_lhs_in_for_in_string(); | 2818 isolate()->factory()->invalid_lhs_in_for_in_string(); |
| 2815 expression = NewThrowReferenceError(message); | 2819 expression = NewThrowReferenceError(message); |
| 2816 } | 2820 } |
| 2817 ForEachStatement* loop = factory()->NewForEachStatement(mode, labels); | 2821 ForEachStatement* loop = |
| 2822 factory()->NewForEachStatement(mode, labels, pos); |
| 2818 Target target(&this->target_stack_, loop); | 2823 Target target(&this->target_stack_, loop); |
| 2819 | 2824 |
| 2820 Expression* enumerable = ParseExpression(true, CHECK_OK); | 2825 Expression* enumerable = ParseExpression(true, CHECK_OK); |
| 2821 Expect(Token::RPAREN, CHECK_OK); | 2826 Expect(Token::RPAREN, CHECK_OK); |
| 2822 | 2827 |
| 2823 Statement* body = ParseStatement(NULL, CHECK_OK); | 2828 Statement* body = ParseStatement(NULL, CHECK_OK); |
| 2824 InitializeForEachStatement(loop, expression, enumerable, body); | 2829 InitializeForEachStatement(loop, expression, enumerable, body); |
| 2825 top_scope_ = saved_scope; | 2830 top_scope_ = saved_scope; |
| 2826 for_scope->set_end_position(scanner().location().end_pos); | 2831 for_scope->set_end_position(scanner().location().end_pos); |
| 2827 for_scope = for_scope->FinalizeBlockScope(); | 2832 for_scope = for_scope->FinalizeBlockScope(); |
| 2828 ASSERT(for_scope == NULL); | 2833 ASSERT(for_scope == NULL); |
| 2829 // Parsed for-in loop. | 2834 // Parsed for-in loop. |
| 2830 return loop; | 2835 return loop; |
| 2831 | 2836 |
| 2832 } else { | 2837 } else { |
| 2833 init = factory()->NewExpressionStatement(expression); | 2838 init = factory()->NewExpressionStatement( |
| 2839 expression, RelocInfo::kNoPosition); |
| 2834 } | 2840 } |
| 2835 } | 2841 } |
| 2836 } | 2842 } |
| 2837 | 2843 |
| 2838 // Standard 'for' loop | 2844 // Standard 'for' loop |
| 2839 ForStatement* loop = factory()->NewForStatement(labels); | 2845 ForStatement* loop = factory()->NewForStatement(labels, pos); |
| 2840 Target target(&this->target_stack_, loop); | 2846 Target target(&this->target_stack_, loop); |
| 2841 | 2847 |
| 2842 // Parsed initializer at this point. | 2848 // Parsed initializer at this point. |
| 2843 Expect(Token::SEMICOLON, CHECK_OK); | 2849 Expect(Token::SEMICOLON, CHECK_OK); |
| 2844 | 2850 |
| 2845 Expression* cond = NULL; | 2851 Expression* cond = NULL; |
| 2846 if (peek() != Token::SEMICOLON) { | 2852 if (peek() != Token::SEMICOLON) { |
| 2847 cond = ParseExpression(true, CHECK_OK); | 2853 cond = ParseExpression(true, CHECK_OK); |
| 2848 } | 2854 } |
| 2849 Expect(Token::SEMICOLON, CHECK_OK); | 2855 Expect(Token::SEMICOLON, CHECK_OK); |
| 2850 | 2856 |
| 2851 Statement* next = NULL; | 2857 Statement* next = NULL; |
| 2852 if (peek() != Token::RPAREN) { | 2858 if (peek() != Token::RPAREN) { |
| 2853 Expression* exp = ParseExpression(true, CHECK_OK); | 2859 Expression* exp = ParseExpression(true, CHECK_OK); |
| 2854 next = factory()->NewExpressionStatement(exp); | 2860 next = factory()->NewExpressionStatement(exp, RelocInfo::kNoPosition); |
| 2855 } | 2861 } |
| 2856 Expect(Token::RPAREN, CHECK_OK); | 2862 Expect(Token::RPAREN, CHECK_OK); |
| 2857 | 2863 |
| 2858 Statement* body = ParseStatement(NULL, CHECK_OK); | 2864 Statement* body = ParseStatement(NULL, CHECK_OK); |
| 2859 top_scope_ = saved_scope; | 2865 top_scope_ = saved_scope; |
| 2860 for_scope->set_end_position(scanner().location().end_pos); | 2866 for_scope->set_end_position(scanner().location().end_pos); |
| 2861 for_scope = for_scope->FinalizeBlockScope(); | 2867 for_scope = for_scope->FinalizeBlockScope(); |
| 2862 if (for_scope != NULL) { | 2868 if (for_scope != NULL) { |
| 2863 // Rewrite a for statement of the form | 2869 // Rewrite a for statement of the form |
| 2864 // | 2870 // |
| 2865 // for (let x = i; c; n) b | 2871 // for (let x = i; c; n) b |
| 2866 // | 2872 // |
| 2867 // into | 2873 // into |
| 2868 // | 2874 // |
| 2869 // { | 2875 // { |
| 2870 // let x = i; | 2876 // let x = i; |
| 2871 // for (; c; n) b | 2877 // for (; c; n) b |
| 2872 // } | 2878 // } |
| 2873 ASSERT(init != NULL); | 2879 ASSERT(init != NULL); |
| 2874 Block* result = factory()->NewBlock(NULL, 2, false); | 2880 Block* result = factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition); |
| 2875 result->AddStatement(init, zone()); | 2881 result->AddStatement(init, zone()); |
| 2876 result->AddStatement(loop, zone()); | 2882 result->AddStatement(loop, zone()); |
| 2877 result->set_scope(for_scope); | 2883 result->set_scope(for_scope); |
| 2878 loop->Initialize(NULL, cond, next, body); | 2884 loop->Initialize(NULL, cond, next, body); |
| 2879 return result; | 2885 return result; |
| 2880 } else { | 2886 } else { |
| 2881 loop->Initialize(init, cond, next, body); | 2887 loop->Initialize(init, cond, next, body); |
| 2882 return loop; | 2888 return loop; |
| 2883 } | 2889 } |
| 2884 } | 2890 } |
| 2885 | 2891 |
| 2886 | 2892 |
| 2887 // Precedence = 1 | 2893 // Precedence = 1 |
| 2888 Expression* Parser::ParseExpression(bool accept_IN, bool* ok) { | 2894 Expression* Parser::ParseExpression(bool accept_IN, bool* ok) { |
| 2889 // Expression :: | 2895 // Expression :: |
| 2890 // AssignmentExpression | 2896 // AssignmentExpression |
| 2891 // Expression ',' AssignmentExpression | 2897 // Expression ',' AssignmentExpression |
| 2892 | 2898 |
| 2893 Expression* result = ParseAssignmentExpression(accept_IN, CHECK_OK); | 2899 Expression* result = ParseAssignmentExpression(accept_IN, CHECK_OK); |
| 2894 while (peek() == Token::COMMA) { | 2900 while (peek() == Token::COMMA) { |
| 2895 Expect(Token::COMMA, CHECK_OK); | 2901 Expect(Token::COMMA, CHECK_OK); |
| 2896 int position = scanner().location().beg_pos; | 2902 int pos = position(); |
| 2897 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); | 2903 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); |
| 2898 result = | 2904 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos); |
| 2899 factory()->NewBinaryOperation(Token::COMMA, result, right, position); | |
| 2900 } | 2905 } |
| 2901 return result; | 2906 return result; |
| 2902 } | 2907 } |
| 2903 | 2908 |
| 2904 | 2909 |
| 2905 // Precedence = 2 | 2910 // Precedence = 2 |
| 2906 Expression* Parser::ParseAssignmentExpression(bool accept_IN, bool* ok) { | 2911 Expression* Parser::ParseAssignmentExpression(bool accept_IN, bool* ok) { |
| 2907 // AssignmentExpression :: | 2912 // AssignmentExpression :: |
| 2908 // ConditionalExpression | 2913 // ConditionalExpression |
| 2909 // YieldExpression | 2914 // YieldExpression |
| (...skipping 23 matching lines...) Expand all Loading... |
| 2933 expression = NewThrowReferenceError(message); | 2938 expression = NewThrowReferenceError(message); |
| 2934 } | 2939 } |
| 2935 | 2940 |
| 2936 if (!top_scope_->is_classic_mode()) { | 2941 if (!top_scope_->is_classic_mode()) { |
| 2937 // Assignment to eval or arguments is disallowed in strict mode. | 2942 // Assignment to eval or arguments is disallowed in strict mode. |
| 2938 CheckStrictModeLValue(expression, "strict_lhs_assignment", CHECK_OK); | 2943 CheckStrictModeLValue(expression, "strict_lhs_assignment", CHECK_OK); |
| 2939 } | 2944 } |
| 2940 MarkAsLValue(expression); | 2945 MarkAsLValue(expression); |
| 2941 | 2946 |
| 2942 Token::Value op = Next(); // Get assignment operator. | 2947 Token::Value op = Next(); // Get assignment operator. |
| 2943 int pos = scanner().location().beg_pos; | 2948 int pos = position(); |
| 2944 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); | 2949 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); |
| 2945 | 2950 |
| 2946 // TODO(1231235): We try to estimate the set of properties set by | 2951 // TODO(1231235): We try to estimate the set of properties set by |
| 2947 // constructors. We define a new property whenever there is an | 2952 // constructors. We define a new property whenever there is an |
| 2948 // assignment to a property of 'this'. We should probably only add | 2953 // assignment to a property of 'this'. We should probably only add |
| 2949 // properties if we haven't seen them before. Otherwise we'll | 2954 // properties if we haven't seen them before. Otherwise we'll |
| 2950 // probably overestimate the number of properties. | 2955 // probably overestimate the number of properties. |
| 2951 Property* property = expression ? expression->AsProperty() : NULL; | 2956 Property* property = expression ? expression->AsProperty() : NULL; |
| 2952 if (op == Token::ASSIGN && | 2957 if (op == Token::ASSIGN && |
| 2953 property != NULL && | 2958 property != NULL && |
| (...skipping 23 matching lines...) Expand all Loading... |
| 2977 fni_->Leave(); | 2982 fni_->Leave(); |
| 2978 } | 2983 } |
| 2979 | 2984 |
| 2980 return factory()->NewAssignment(op, expression, right, pos); | 2985 return factory()->NewAssignment(op, expression, right, pos); |
| 2981 } | 2986 } |
| 2982 | 2987 |
| 2983 | 2988 |
| 2984 Expression* Parser::ParseYieldExpression(bool* ok) { | 2989 Expression* Parser::ParseYieldExpression(bool* ok) { |
| 2985 // YieldExpression :: | 2990 // YieldExpression :: |
| 2986 // 'yield' '*'? AssignmentExpression | 2991 // 'yield' '*'? AssignmentExpression |
| 2987 int position = scanner().peek_location().beg_pos; | 2992 int pos = peek_position(); |
| 2988 Expect(Token::YIELD, CHECK_OK); | 2993 Expect(Token::YIELD, CHECK_OK); |
| 2989 Yield::Kind kind = | 2994 Yield::Kind kind = |
| 2990 Check(Token::MUL) ? Yield::DELEGATING : Yield::SUSPEND; | 2995 Check(Token::MUL) ? Yield::DELEGATING : Yield::SUSPEND; |
| 2991 Expression* generator_object = factory()->NewVariableProxy( | 2996 Expression* generator_object = factory()->NewVariableProxy( |
| 2992 current_function_state_->generator_object_variable()); | 2997 current_function_state_->generator_object_variable()); |
| 2993 Expression* expression = ParseAssignmentExpression(false, CHECK_OK); | 2998 Expression* expression = ParseAssignmentExpression(false, CHECK_OK); |
| 2994 Yield* yield = | 2999 Yield* yield = factory()->NewYield(generator_object, expression, kind, pos); |
| 2995 factory()->NewYield(generator_object, expression, kind, position); | |
| 2996 if (kind == Yield::DELEGATING) { | 3000 if (kind == Yield::DELEGATING) { |
| 2997 yield->set_index(current_function_state_->NextHandlerIndex()); | 3001 yield->set_index(current_function_state_->NextHandlerIndex()); |
| 2998 } | 3002 } |
| 2999 return yield; | 3003 return yield; |
| 3000 } | 3004 } |
| 3001 | 3005 |
| 3002 | 3006 |
| 3003 // Precedence = 3 | 3007 // Precedence = 3 |
| 3004 Expression* Parser::ParseConditionalExpression(bool accept_IN, bool* ok) { | 3008 Expression* Parser::ParseConditionalExpression(bool accept_IN, bool* ok) { |
| 3005 // ConditionalExpression :: | 3009 // ConditionalExpression :: |
| 3006 // LogicalOrExpression | 3010 // LogicalOrExpression |
| 3007 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression | 3011 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression |
| 3008 | 3012 |
| 3013 int pos = peek_position(); |
| 3009 // We start using the binary expression parser for prec >= 4 only! | 3014 // We start using the binary expression parser for prec >= 4 only! |
| 3010 Expression* expression = ParseBinaryExpression(4, accept_IN, CHECK_OK); | 3015 Expression* expression = ParseBinaryExpression(4, accept_IN, CHECK_OK); |
| 3011 if (peek() != Token::CONDITIONAL) return expression; | 3016 if (peek() != Token::CONDITIONAL) return expression; |
| 3012 Consume(Token::CONDITIONAL); | 3017 Consume(Token::CONDITIONAL); |
| 3013 // In parsing the first assignment expression in conditional | 3018 // In parsing the first assignment expression in conditional |
| 3014 // expressions we always accept the 'in' keyword; see ECMA-262, | 3019 // expressions we always accept the 'in' keyword; see ECMA-262, |
| 3015 // section 11.12, page 58. | 3020 // section 11.12, page 58. |
| 3016 int left_position = scanner().peek_location().beg_pos; | |
| 3017 Expression* left = ParseAssignmentExpression(true, CHECK_OK); | 3021 Expression* left = ParseAssignmentExpression(true, CHECK_OK); |
| 3018 Expect(Token::COLON, CHECK_OK); | 3022 Expect(Token::COLON, CHECK_OK); |
| 3019 int right_position = scanner().peek_location().beg_pos; | |
| 3020 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); | 3023 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); |
| 3021 return factory()->NewConditional( | 3024 return factory()->NewConditional(expression, left, right, pos); |
| 3022 expression, left, right, left_position, right_position); | |
| 3023 } | 3025 } |
| 3024 | 3026 |
| 3025 | 3027 |
| 3026 static int Precedence(Token::Value tok, bool accept_IN) { | 3028 int ParserBase::Precedence(Token::Value tok, bool accept_IN) { |
| 3027 if (tok == Token::IN && !accept_IN) | 3029 if (tok == Token::IN && !accept_IN) |
| 3028 return 0; // 0 precedence will terminate binary expression parsing | 3030 return 0; // 0 precedence will terminate binary expression parsing |
| 3029 | 3031 |
| 3030 return Token::Precedence(tok); | 3032 return Token::Precedence(tok); |
| 3031 } | 3033 } |
| 3032 | 3034 |
| 3033 | 3035 |
| 3034 // Precedence >= 4 | 3036 // Precedence >= 4 |
| 3035 Expression* Parser::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) { | 3037 Expression* Parser::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) { |
| 3036 ASSERT(prec >= 4); | 3038 ASSERT(prec >= 4); |
| 3037 Expression* x = ParseUnaryExpression(CHECK_OK); | 3039 Expression* x = ParseUnaryExpression(CHECK_OK); |
| 3038 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { | 3040 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { |
| 3039 // prec1 >= 4 | 3041 // prec1 >= 4 |
| 3040 while (Precedence(peek(), accept_IN) == prec1) { | 3042 while (Precedence(peek(), accept_IN) == prec1) { |
| 3041 Token::Value op = Next(); | 3043 Token::Value op = Next(); |
| 3042 int position = scanner().location().beg_pos; | 3044 int pos = position(); |
| 3043 Expression* y = ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK); | 3045 Expression* y = ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK); |
| 3044 | 3046 |
| 3045 // Compute some expressions involving only number literals. | 3047 // Compute some expressions involving only number literals. |
| 3046 if (x && x->AsLiteral() && x->AsLiteral()->value()->IsNumber() && | 3048 if (x && x->AsLiteral() && x->AsLiteral()->value()->IsNumber() && |
| 3047 y && y->AsLiteral() && y->AsLiteral()->value()->IsNumber()) { | 3049 y && y->AsLiteral() && y->AsLiteral()->value()->IsNumber()) { |
| 3048 double x_val = x->AsLiteral()->value()->Number(); | 3050 double x_val = x->AsLiteral()->value()->Number(); |
| 3049 double y_val = y->AsLiteral()->value()->Number(); | 3051 double y_val = y->AsLiteral()->value()->Number(); |
| 3050 | 3052 |
| 3051 switch (op) { | 3053 switch (op) { |
| 3052 case Token::ADD: | 3054 case Token::ADD: |
| 3053 x = factory()->NewNumberLiteral(x_val + y_val); | 3055 x = factory()->NewNumberLiteral(x_val + y_val, pos); |
| 3054 continue; | 3056 continue; |
| 3055 case Token::SUB: | 3057 case Token::SUB: |
| 3056 x = factory()->NewNumberLiteral(x_val - y_val); | 3058 x = factory()->NewNumberLiteral(x_val - y_val, pos); |
| 3057 continue; | 3059 continue; |
| 3058 case Token::MUL: | 3060 case Token::MUL: |
| 3059 x = factory()->NewNumberLiteral(x_val * y_val); | 3061 x = factory()->NewNumberLiteral(x_val * y_val, pos); |
| 3060 continue; | 3062 continue; |
| 3061 case Token::DIV: | 3063 case Token::DIV: |
| 3062 x = factory()->NewNumberLiteral(x_val / y_val); | 3064 x = factory()->NewNumberLiteral(x_val / y_val, pos); |
| 3063 continue; | 3065 continue; |
| 3064 case Token::BIT_OR: { | 3066 case Token::BIT_OR: { |
| 3065 int value = DoubleToInt32(x_val) | DoubleToInt32(y_val); | 3067 int value = DoubleToInt32(x_val) | DoubleToInt32(y_val); |
| 3066 x = factory()->NewNumberLiteral(value); | 3068 x = factory()->NewNumberLiteral(value, pos); |
| 3067 continue; | 3069 continue; |
| 3068 } | 3070 } |
| 3069 case Token::BIT_AND: { | 3071 case Token::BIT_AND: { |
| 3070 int value = DoubleToInt32(x_val) & DoubleToInt32(y_val); | 3072 int value = DoubleToInt32(x_val) & DoubleToInt32(y_val); |
| 3071 x = factory()->NewNumberLiteral(value); | 3073 x = factory()->NewNumberLiteral(value, pos); |
| 3072 continue; | 3074 continue; |
| 3073 } | 3075 } |
| 3074 case Token::BIT_XOR: { | 3076 case Token::BIT_XOR: { |
| 3075 int value = DoubleToInt32(x_val) ^ DoubleToInt32(y_val); | 3077 int value = DoubleToInt32(x_val) ^ DoubleToInt32(y_val); |
| 3076 x = factory()->NewNumberLiteral(value); | 3078 x = factory()->NewNumberLiteral(value, pos); |
| 3077 continue; | 3079 continue; |
| 3078 } | 3080 } |
| 3079 case Token::SHL: { | 3081 case Token::SHL: { |
| 3080 int value = DoubleToInt32(x_val) << (DoubleToInt32(y_val) & 0x1f); | 3082 int value = DoubleToInt32(x_val) << (DoubleToInt32(y_val) & 0x1f); |
| 3081 x = factory()->NewNumberLiteral(value); | 3083 x = factory()->NewNumberLiteral(value, pos); |
| 3082 continue; | 3084 continue; |
| 3083 } | 3085 } |
| 3084 case Token::SHR: { | 3086 case Token::SHR: { |
| 3085 uint32_t shift = DoubleToInt32(y_val) & 0x1f; | 3087 uint32_t shift = DoubleToInt32(y_val) & 0x1f; |
| 3086 uint32_t value = DoubleToUint32(x_val) >> shift; | 3088 uint32_t value = DoubleToUint32(x_val) >> shift; |
| 3087 x = factory()->NewNumberLiteral(value); | 3089 x = factory()->NewNumberLiteral(value, pos); |
| 3088 continue; | 3090 continue; |
| 3089 } | 3091 } |
| 3090 case Token::SAR: { | 3092 case Token::SAR: { |
| 3091 uint32_t shift = DoubleToInt32(y_val) & 0x1f; | 3093 uint32_t shift = DoubleToInt32(y_val) & 0x1f; |
| 3092 int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift); | 3094 int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift); |
| 3093 x = factory()->NewNumberLiteral(value); | 3095 x = factory()->NewNumberLiteral(value, pos); |
| 3094 continue; | 3096 continue; |
| 3095 } | 3097 } |
| 3096 default: | 3098 default: |
| 3097 break; | 3099 break; |
| 3098 } | 3100 } |
| 3099 } | 3101 } |
| 3100 | 3102 |
| 3101 // For now we distinguish between comparisons and other binary | 3103 // For now we distinguish between comparisons and other binary |
| 3102 // operations. (We could combine the two and get rid of this | 3104 // operations. (We could combine the two and get rid of this |
| 3103 // code and AST node eventually.) | 3105 // code and AST node eventually.) |
| 3104 if (Token::IsCompareOp(op)) { | 3106 if (Token::IsCompareOp(op)) { |
| 3105 // We have a comparison. | 3107 // We have a comparison. |
| 3106 Token::Value cmp = op; | 3108 Token::Value cmp = op; |
| 3107 switch (op) { | 3109 switch (op) { |
| 3108 case Token::NE: cmp = Token::EQ; break; | 3110 case Token::NE: cmp = Token::EQ; break; |
| 3109 case Token::NE_STRICT: cmp = Token::EQ_STRICT; break; | 3111 case Token::NE_STRICT: cmp = Token::EQ_STRICT; break; |
| 3110 default: break; | 3112 default: break; |
| 3111 } | 3113 } |
| 3112 x = factory()->NewCompareOperation(cmp, x, y, position); | 3114 x = factory()->NewCompareOperation(cmp, x, y, pos); |
| 3113 if (cmp != op) { | 3115 if (cmp != op) { |
| 3114 // The comparison was negated - add a NOT. | 3116 // The comparison was negated - add a NOT. |
| 3115 x = factory()->NewUnaryOperation(Token::NOT, x, position); | 3117 x = factory()->NewUnaryOperation(Token::NOT, x, pos); |
| 3116 } | 3118 } |
| 3117 | 3119 |
| 3118 } else { | 3120 } else { |
| 3119 // We have a "normal" binary operation. | 3121 // We have a "normal" binary operation. |
| 3120 x = factory()->NewBinaryOperation(op, x, y, position); | 3122 x = factory()->NewBinaryOperation(op, x, y, pos); |
| 3121 } | 3123 } |
| 3122 } | 3124 } |
| 3123 } | 3125 } |
| 3124 return x; | 3126 return x; |
| 3125 } | 3127 } |
| 3126 | 3128 |
| 3127 | 3129 |
| 3128 Expression* Parser::ParseUnaryExpression(bool* ok) { | 3130 Expression* Parser::ParseUnaryExpression(bool* ok) { |
| 3129 // UnaryExpression :: | 3131 // UnaryExpression :: |
| 3130 // PostfixExpression | 3132 // PostfixExpression |
| 3131 // 'delete' UnaryExpression | 3133 // 'delete' UnaryExpression |
| 3132 // 'void' UnaryExpression | 3134 // 'void' UnaryExpression |
| 3133 // 'typeof' UnaryExpression | 3135 // 'typeof' UnaryExpression |
| 3134 // '++' UnaryExpression | 3136 // '++' UnaryExpression |
| 3135 // '--' UnaryExpression | 3137 // '--' UnaryExpression |
| 3136 // '+' UnaryExpression | 3138 // '+' UnaryExpression |
| 3137 // '-' UnaryExpression | 3139 // '-' UnaryExpression |
| 3138 // '~' UnaryExpression | 3140 // '~' UnaryExpression |
| 3139 // '!' UnaryExpression | 3141 // '!' UnaryExpression |
| 3140 | 3142 |
| 3141 Token::Value op = peek(); | 3143 Token::Value op = peek(); |
| 3142 if (Token::IsUnaryOp(op)) { | 3144 if (Token::IsUnaryOp(op)) { |
| 3143 op = Next(); | 3145 op = Next(); |
| 3144 int position = scanner().location().beg_pos; | 3146 int pos = position(); |
| 3145 Expression* expression = ParseUnaryExpression(CHECK_OK); | 3147 Expression* expression = ParseUnaryExpression(CHECK_OK); |
| 3146 | 3148 |
| 3147 if (expression != NULL && (expression->AsLiteral() != NULL)) { | 3149 if (expression != NULL && (expression->AsLiteral() != NULL)) { |
| 3148 Handle<Object> literal = expression->AsLiteral()->value(); | 3150 Handle<Object> literal = expression->AsLiteral()->value(); |
| 3149 if (op == Token::NOT) { | 3151 if (op == Token::NOT) { |
| 3150 // Convert the literal to a boolean condition and negate it. | 3152 // Convert the literal to a boolean condition and negate it. |
| 3151 bool condition = literal->BooleanValue(); | 3153 bool condition = literal->BooleanValue(); |
| 3152 Handle<Object> result = isolate()->factory()->ToBoolean(!condition); | 3154 Handle<Object> result = isolate()->factory()->ToBoolean(!condition); |
| 3153 return factory()->NewLiteral(result); | 3155 return factory()->NewLiteral(result, pos); |
| 3154 } else if (literal->IsNumber()) { | 3156 } else if (literal->IsNumber()) { |
| 3155 // Compute some expressions involving only number literals. | 3157 // Compute some expressions involving only number literals. |
| 3156 double value = literal->Number(); | 3158 double value = literal->Number(); |
| 3157 switch (op) { | 3159 switch (op) { |
| 3158 case Token::ADD: | 3160 case Token::ADD: |
| 3159 return expression; | 3161 return expression; |
| 3160 case Token::SUB: | 3162 case Token::SUB: |
| 3161 return factory()->NewNumberLiteral(-value); | 3163 return factory()->NewNumberLiteral(-value, pos); |
| 3162 case Token::BIT_NOT: | 3164 case Token::BIT_NOT: |
| 3163 return factory()->NewNumberLiteral(~DoubleToInt32(value)); | 3165 return factory()->NewNumberLiteral(~DoubleToInt32(value), pos); |
| 3164 default: | 3166 default: |
| 3165 break; | 3167 break; |
| 3166 } | 3168 } |
| 3167 } | 3169 } |
| 3168 } | 3170 } |
| 3169 | 3171 |
| 3170 // "delete identifier" is a syntax error in strict mode. | 3172 // "delete identifier" is a syntax error in strict mode. |
| 3171 if (op == Token::DELETE && !top_scope_->is_classic_mode()) { | 3173 if (op == Token::DELETE && !top_scope_->is_classic_mode()) { |
| 3172 VariableProxy* operand = expression->AsVariableProxy(); | 3174 VariableProxy* operand = expression->AsVariableProxy(); |
| 3173 if (operand != NULL && !operand->is_this()) { | 3175 if (operand != NULL && !operand->is_this()) { |
| 3174 ReportMessage("strict_delete", Vector<const char*>::empty()); | 3176 ReportMessage("strict_delete", Vector<const char*>::empty()); |
| 3175 *ok = false; | 3177 *ok = false; |
| 3176 return NULL; | 3178 return NULL; |
| 3177 } | 3179 } |
| 3178 } | 3180 } |
| 3179 | 3181 |
| 3180 // Desugar '+foo' into 'foo*1', this enables the collection of type feedback | 3182 // Desugar '+foo' into 'foo*1', this enables the collection of type feedback |
| 3181 // without any special stub and the multiplication is removed later in | 3183 // without any special stub and the multiplication is removed later in |
| 3182 // Crankshaft's canonicalization pass. | 3184 // Crankshaft's canonicalization pass. |
| 3183 if (op == Token::ADD) { | 3185 if (op == Token::ADD) { |
| 3184 return factory()->NewBinaryOperation(Token::MUL, | 3186 return factory()->NewBinaryOperation(Token::MUL, |
| 3185 expression, | 3187 expression, |
| 3186 factory()->NewNumberLiteral(1), | 3188 factory()->NewNumberLiteral(1, pos), |
| 3187 position); | 3189 pos); |
| 3188 } | 3190 } |
| 3189 // The same idea for '-foo' => 'foo*(-1)'. | 3191 // The same idea for '-foo' => 'foo*(-1)'. |
| 3190 if (op == Token::SUB) { | 3192 if (op == Token::SUB) { |
| 3191 return factory()->NewBinaryOperation(Token::MUL, | 3193 return factory()->NewBinaryOperation(Token::MUL, |
| 3192 expression, | 3194 expression, |
| 3193 factory()->NewNumberLiteral(-1), | 3195 factory()->NewNumberLiteral(-1, pos), |
| 3194 position); | 3196 pos); |
| 3195 } | 3197 } |
| 3196 // ...and one more time for '~foo' => 'foo^(~0)'. | 3198 // ...and one more time for '~foo' => 'foo^(~0)'. |
| 3197 if (op == Token::BIT_NOT) { | 3199 if (op == Token::BIT_NOT) { |
| 3198 return factory()->NewBinaryOperation(Token::BIT_XOR, | 3200 return factory()->NewBinaryOperation(Token::BIT_XOR, |
| 3199 expression, | 3201 expression, |
| 3200 factory()->NewNumberLiteral(~0), | 3202 factory()->NewNumberLiteral(~0, pos), |
| 3201 position); | 3203 pos); |
| 3202 } | 3204 } |
| 3203 | 3205 |
| 3204 return factory()->NewUnaryOperation(op, expression, position); | 3206 return factory()->NewUnaryOperation(op, expression, pos); |
| 3205 | 3207 |
| 3206 } else if (Token::IsCountOp(op)) { | 3208 } else if (Token::IsCountOp(op)) { |
| 3207 op = Next(); | 3209 op = Next(); |
| 3208 Expression* expression = ParseUnaryExpression(CHECK_OK); | 3210 Expression* expression = ParseUnaryExpression(CHECK_OK); |
| 3209 // Signal a reference error if the expression is an invalid | 3211 // Signal a reference error if the expression is an invalid |
| 3210 // left-hand side expression. We could report this as a syntax | 3212 // left-hand side expression. We could report this as a syntax |
| 3211 // error here but for compatibility with JSC we choose to report the | 3213 // error here but for compatibility with JSC we choose to report the |
| 3212 // error at runtime. | 3214 // error at runtime. |
| 3213 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 3215 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
| 3214 Handle<String> message = | 3216 Handle<String> message = |
| 3215 isolate()->factory()->invalid_lhs_in_prefix_op_string(); | 3217 isolate()->factory()->invalid_lhs_in_prefix_op_string(); |
| 3216 expression = NewThrowReferenceError(message); | 3218 expression = NewThrowReferenceError(message); |
| 3217 } | 3219 } |
| 3218 | 3220 |
| 3219 if (!top_scope_->is_classic_mode()) { | 3221 if (!top_scope_->is_classic_mode()) { |
| 3220 // Prefix expression operand in strict mode may not be eval or arguments. | 3222 // Prefix expression operand in strict mode may not be eval or arguments. |
| 3221 CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK); | 3223 CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK); |
| 3222 } | 3224 } |
| 3223 MarkAsLValue(expression); | 3225 MarkAsLValue(expression); |
| 3224 | 3226 |
| 3225 int position = scanner().location().beg_pos; | |
| 3226 return factory()->NewCountOperation(op, | 3227 return factory()->NewCountOperation(op, |
| 3227 true /* prefix */, | 3228 true /* prefix */, |
| 3228 expression, | 3229 expression, |
| 3229 position); | 3230 position()); |
| 3230 | 3231 |
| 3231 } else { | 3232 } else { |
| 3232 return ParsePostfixExpression(ok); | 3233 return ParsePostfixExpression(ok); |
| 3233 } | 3234 } |
| 3234 } | 3235 } |
| 3235 | 3236 |
| 3236 | 3237 |
| 3237 Expression* Parser::ParsePostfixExpression(bool* ok) { | 3238 Expression* Parser::ParsePostfixExpression(bool* ok) { |
| 3238 // PostfixExpression :: | 3239 // PostfixExpression :: |
| 3239 // LeftHandSideExpression ('++' | '--')? | 3240 // LeftHandSideExpression ('++' | '--')? |
| (...skipping 11 matching lines...) Expand all Loading... |
| 3251 expression = NewThrowReferenceError(message); | 3252 expression = NewThrowReferenceError(message); |
| 3252 } | 3253 } |
| 3253 | 3254 |
| 3254 if (!top_scope_->is_classic_mode()) { | 3255 if (!top_scope_->is_classic_mode()) { |
| 3255 // Postfix expression operand in strict mode may not be eval or arguments. | 3256 // Postfix expression operand in strict mode may not be eval or arguments. |
| 3256 CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK); | 3257 CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK); |
| 3257 } | 3258 } |
| 3258 MarkAsLValue(expression); | 3259 MarkAsLValue(expression); |
| 3259 | 3260 |
| 3260 Token::Value next = Next(); | 3261 Token::Value next = Next(); |
| 3261 int position = scanner().location().beg_pos; | |
| 3262 expression = | 3262 expression = |
| 3263 factory()->NewCountOperation(next, | 3263 factory()->NewCountOperation(next, |
| 3264 false /* postfix */, | 3264 false /* postfix */, |
| 3265 expression, | 3265 expression, |
| 3266 position); | 3266 position()); |
| 3267 } | 3267 } |
| 3268 return expression; | 3268 return expression; |
| 3269 } | 3269 } |
| 3270 | 3270 |
| 3271 | 3271 |
| 3272 Expression* Parser::ParseLeftHandSideExpression(bool* ok) { | 3272 Expression* Parser::ParseLeftHandSideExpression(bool* ok) { |
| 3273 // LeftHandSideExpression :: | 3273 // LeftHandSideExpression :: |
| 3274 // (NewExpression | MemberExpression) ... | 3274 // (NewExpression | MemberExpression) ... |
| 3275 | 3275 |
| 3276 Expression* result; | 3276 Expression* result; |
| 3277 if (peek() == Token::NEW) { | 3277 if (peek() == Token::NEW) { |
| 3278 result = ParseNewExpression(CHECK_OK); | 3278 result = ParseNewExpression(CHECK_OK); |
| 3279 } else { | 3279 } else { |
| 3280 result = ParseMemberExpression(CHECK_OK); | 3280 result = ParseMemberExpression(CHECK_OK); |
| 3281 } | 3281 } |
| 3282 | 3282 |
| 3283 while (true) { | 3283 while (true) { |
| 3284 switch (peek()) { | 3284 switch (peek()) { |
| 3285 case Token::LBRACK: { | 3285 case Token::LBRACK: { |
| 3286 Consume(Token::LBRACK); | 3286 Consume(Token::LBRACK); |
| 3287 int pos = scanner().location().beg_pos; | 3287 int pos = position(); |
| 3288 Expression* index = ParseExpression(true, CHECK_OK); | 3288 Expression* index = ParseExpression(true, CHECK_OK); |
| 3289 result = factory()->NewProperty(result, index, pos); | 3289 result = factory()->NewProperty(result, index, pos); |
| 3290 Expect(Token::RBRACK, CHECK_OK); | 3290 Expect(Token::RBRACK, CHECK_OK); |
| 3291 break; | 3291 break; |
| 3292 } | 3292 } |
| 3293 | 3293 |
| 3294 case Token::LPAREN: { | 3294 case Token::LPAREN: { |
| 3295 int pos; | 3295 int pos; |
| 3296 if (scanner().current_token() == Token::IDENTIFIER) { | 3296 if (scanner().current_token() == Token::IDENTIFIER) { |
| 3297 // For call of an identifier we want to report position of | 3297 // For call of an identifier we want to report position of |
| 3298 // the identifier as position of the call in the stack trace. | 3298 // the identifier as position of the call in the stack trace. |
| 3299 pos = scanner().location().beg_pos; | 3299 pos = position(); |
| 3300 } else { | 3300 } else { |
| 3301 // For other kinds of calls we record position of the parenthesis as | 3301 // For other kinds of calls we record position of the parenthesis as |
| 3302 // position of the call. Note that this is extremely important for | 3302 // position of the call. Note that this is extremely important for |
| 3303 // expressions of the form function(){...}() for which call position | 3303 // expressions of the form function(){...}() for which call position |
| 3304 // should not point to the closing brace otherwise it will intersect | 3304 // should not point to the closing brace otherwise it will intersect |
| 3305 // with positions recorded for function literal and confuse debugger. | 3305 // with positions recorded for function literal and confuse debugger. |
| 3306 pos = scanner().peek_location().beg_pos; | 3306 pos = peek_position(); |
| 3307 // Also the trailing parenthesis are a hint that the function will | 3307 // Also the trailing parenthesis are a hint that the function will |
| 3308 // be called immediately. If we happen to have parsed a preceding | 3308 // be called immediately. If we happen to have parsed a preceding |
| 3309 // function literal eagerly, we can also compile it eagerly. | 3309 // function literal eagerly, we can also compile it eagerly. |
| 3310 if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { | 3310 if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { |
| 3311 result->AsFunctionLiteral()->set_parenthesized(); | 3311 result->AsFunctionLiteral()->set_parenthesized(); |
| 3312 } | 3312 } |
| 3313 } | 3313 } |
| 3314 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); | 3314 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); |
| 3315 | 3315 |
| 3316 // Keep track of eval() calls since they disable all local variable | 3316 // Keep track of eval() calls since they disable all local variable |
| 3317 // optimizations. | 3317 // optimizations. |
| 3318 // The calls that need special treatment are the | 3318 // The calls that need special treatment are the |
| 3319 // direct eval calls. These calls are all of the form eval(...), with | 3319 // direct eval calls. These calls are all of the form eval(...), with |
| 3320 // no explicit receiver. | 3320 // no explicit receiver. |
| 3321 // These calls are marked as potentially direct eval calls. Whether | 3321 // These calls are marked as potentially direct eval calls. Whether |
| 3322 // they are actually direct calls to eval is determined at run time. | 3322 // they are actually direct calls to eval is determined at run time. |
| 3323 VariableProxy* callee = result->AsVariableProxy(); | 3323 VariableProxy* callee = result->AsVariableProxy(); |
| 3324 if (callee != NULL && | 3324 if (callee != NULL && |
| 3325 callee->IsVariable(isolate()->factory()->eval_string())) { | 3325 callee->IsVariable(isolate()->factory()->eval_string())) { |
| 3326 top_scope_->DeclarationScope()->RecordEvalCall(); | 3326 top_scope_->DeclarationScope()->RecordEvalCall(); |
| 3327 } | 3327 } |
| 3328 result = factory()->NewCall(result, args, pos); | 3328 result = factory()->NewCall(result, args, pos); |
| 3329 if (fni_ != NULL) fni_->RemoveLastFunction(); | 3329 if (fni_ != NULL) fni_->RemoveLastFunction(); |
| 3330 break; | 3330 break; |
| 3331 } | 3331 } |
| 3332 | 3332 |
| 3333 case Token::PERIOD: { | 3333 case Token::PERIOD: { |
| 3334 Consume(Token::PERIOD); | 3334 Consume(Token::PERIOD); |
| 3335 int pos = scanner().location().beg_pos; | 3335 int pos = position(); |
| 3336 Handle<String> name = ParseIdentifierName(CHECK_OK); | 3336 Handle<String> name = ParseIdentifierName(CHECK_OK); |
| 3337 result = | 3337 result = factory()->NewProperty( |
| 3338 factory()->NewProperty(result, factory()->NewLiteral(name), pos); | 3338 result, factory()->NewLiteral(name, pos), pos); |
| 3339 if (fni_ != NULL) fni_->PushLiteralName(name); | 3339 if (fni_ != NULL) fni_->PushLiteralName(name); |
| 3340 break; | 3340 break; |
| 3341 } | 3341 } |
| 3342 | 3342 |
| 3343 default: | 3343 default: |
| 3344 return result; | 3344 return result; |
| 3345 } | 3345 } |
| 3346 } | 3346 } |
| 3347 } | 3347 } |
| 3348 | 3348 |
| 3349 | 3349 |
| 3350 Expression* Parser::ParseNewPrefix(PositionStack* stack, bool* ok) { | 3350 Expression* Parser::ParseNewPrefix(PositionStack* stack, bool* ok) { |
| 3351 // NewExpression :: | 3351 // NewExpression :: |
| 3352 // ('new')+ MemberExpression | 3352 // ('new')+ MemberExpression |
| 3353 | 3353 |
| 3354 // The grammar for new expressions is pretty warped. The keyword | 3354 // The grammar for new expressions is pretty warped. The keyword |
| 3355 // 'new' can either be a part of the new expression (where it isn't | 3355 // 'new' can either be a part of the new expression (where it isn't |
| 3356 // followed by an argument list) or a part of the member expression, | 3356 // followed by an argument list) or a part of the member expression, |
| 3357 // where it must be followed by an argument list. To accommodate | 3357 // where it must be followed by an argument list. To accommodate |
| 3358 // this, we parse the 'new' keywords greedily and keep track of how | 3358 // this, we parse the 'new' keywords greedily and keep track of how |
| 3359 // many we have parsed. This information is then passed on to the | 3359 // many we have parsed. This information is then passed on to the |
| 3360 // member expression parser, which is only allowed to match argument | 3360 // member expression parser, which is only allowed to match argument |
| 3361 // lists as long as it has 'new' prefixes left | 3361 // lists as long as it has 'new' prefixes left |
| 3362 Expect(Token::NEW, CHECK_OK); | 3362 Expect(Token::NEW, CHECK_OK); |
| 3363 PositionStack::Element pos(stack, scanner().location().beg_pos); | 3363 PositionStack::Element pos(stack, position()); |
| 3364 | 3364 |
| 3365 Expression* result; | 3365 Expression* result; |
| 3366 if (peek() == Token::NEW) { | 3366 if (peek() == Token::NEW) { |
| 3367 result = ParseNewPrefix(stack, CHECK_OK); | 3367 result = ParseNewPrefix(stack, CHECK_OK); |
| 3368 } else { | 3368 } else { |
| 3369 result = ParseMemberWithNewPrefixesExpression(stack, CHECK_OK); | 3369 result = ParseMemberWithNewPrefixesExpression(stack, CHECK_OK); |
| 3370 } | 3370 } |
| 3371 | 3371 |
| 3372 if (!stack->is_empty()) { | 3372 if (!stack->is_empty()) { |
| 3373 int last = stack->pop(); | 3373 int last = stack->pop(); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 3392 Expression* Parser::ParseMemberWithNewPrefixesExpression(PositionStack* stack, | 3392 Expression* Parser::ParseMemberWithNewPrefixesExpression(PositionStack* stack, |
| 3393 bool* ok) { | 3393 bool* ok) { |
| 3394 // MemberExpression :: | 3394 // MemberExpression :: |
| 3395 // (PrimaryExpression | FunctionLiteral) | 3395 // (PrimaryExpression | FunctionLiteral) |
| 3396 // ('[' Expression ']' | '.' Identifier | Arguments)* | 3396 // ('[' Expression ']' | '.' Identifier | Arguments)* |
| 3397 | 3397 |
| 3398 // Parse the initial primary or function expression. | 3398 // Parse the initial primary or function expression. |
| 3399 Expression* result = NULL; | 3399 Expression* result = NULL; |
| 3400 if (peek() == Token::FUNCTION) { | 3400 if (peek() == Token::FUNCTION) { |
| 3401 Expect(Token::FUNCTION, CHECK_OK); | 3401 Expect(Token::FUNCTION, CHECK_OK); |
| 3402 int function_token_position = scanner().location().beg_pos; | 3402 int function_token_position = position(); |
| 3403 bool is_generator = allow_generators() && Check(Token::MUL); | 3403 bool is_generator = allow_generators() && Check(Token::MUL); |
| 3404 Handle<String> name; | 3404 Handle<String> name; |
| 3405 bool is_strict_reserved_name = false; | 3405 bool is_strict_reserved_name = false; |
| 3406 if (peek_any_identifier()) { | 3406 if (peek_any_identifier()) { |
| 3407 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, | 3407 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, |
| 3408 CHECK_OK); | 3408 CHECK_OK); |
| 3409 } | 3409 } |
| 3410 FunctionLiteral::FunctionType function_type = name.is_null() | 3410 FunctionLiteral::FunctionType function_type = name.is_null() |
| 3411 ? FunctionLiteral::ANONYMOUS_EXPRESSION | 3411 ? FunctionLiteral::ANONYMOUS_EXPRESSION |
| 3412 : FunctionLiteral::NAMED_EXPRESSION; | 3412 : FunctionLiteral::NAMED_EXPRESSION; |
| 3413 result = ParseFunctionLiteral(name, | 3413 result = ParseFunctionLiteral(name, |
| 3414 is_strict_reserved_name, | 3414 is_strict_reserved_name, |
| 3415 is_generator, | 3415 is_generator, |
| 3416 function_token_position, | 3416 function_token_position, |
| 3417 function_type, | 3417 function_type, |
| 3418 CHECK_OK); | 3418 CHECK_OK); |
| 3419 } else { | 3419 } else { |
| 3420 result = ParsePrimaryExpression(CHECK_OK); | 3420 result = ParsePrimaryExpression(CHECK_OK); |
| 3421 } | 3421 } |
| 3422 | 3422 |
| 3423 while (true) { | 3423 while (true) { |
| 3424 switch (peek()) { | 3424 switch (peek()) { |
| 3425 case Token::LBRACK: { | 3425 case Token::LBRACK: { |
| 3426 Consume(Token::LBRACK); | 3426 Consume(Token::LBRACK); |
| 3427 int pos = scanner().location().beg_pos; | 3427 int pos = position(); |
| 3428 Expression* index = ParseExpression(true, CHECK_OK); | 3428 Expression* index = ParseExpression(true, CHECK_OK); |
| 3429 result = factory()->NewProperty(result, index, pos); | 3429 result = factory()->NewProperty(result, index, pos); |
| 3430 if (fni_ != NULL) { | 3430 if (fni_ != NULL) { |
| 3431 if (index->IsPropertyName()) { | 3431 if (index->IsPropertyName()) { |
| 3432 fni_->PushLiteralName(index->AsLiteral()->AsPropertyName()); | 3432 fni_->PushLiteralName(index->AsLiteral()->AsPropertyName()); |
| 3433 } else { | 3433 } else { |
| 3434 fni_->PushLiteralName( | 3434 fni_->PushLiteralName( |
| 3435 isolate()->factory()->anonymous_function_string()); | 3435 isolate()->factory()->anonymous_function_string()); |
| 3436 } | 3436 } |
| 3437 } | 3437 } |
| 3438 Expect(Token::RBRACK, CHECK_OK); | 3438 Expect(Token::RBRACK, CHECK_OK); |
| 3439 break; | 3439 break; |
| 3440 } | 3440 } |
| 3441 case Token::PERIOD: { | 3441 case Token::PERIOD: { |
| 3442 Consume(Token::PERIOD); | 3442 Consume(Token::PERIOD); |
| 3443 int pos = scanner().location().beg_pos; | 3443 int pos = position(); |
| 3444 Handle<String> name = ParseIdentifierName(CHECK_OK); | 3444 Handle<String> name = ParseIdentifierName(CHECK_OK); |
| 3445 result = | 3445 result = factory()->NewProperty( |
| 3446 factory()->NewProperty(result, factory()->NewLiteral(name), pos); | 3446 result, factory()->NewLiteral(name, pos), pos); |
| 3447 if (fni_ != NULL) fni_->PushLiteralName(name); | 3447 if (fni_ != NULL) fni_->PushLiteralName(name); |
| 3448 break; | 3448 break; |
| 3449 } | 3449 } |
| 3450 case Token::LPAREN: { | 3450 case Token::LPAREN: { |
| 3451 if ((stack == NULL) || stack->is_empty()) return result; | 3451 if ((stack == NULL) || stack->is_empty()) return result; |
| 3452 // Consume one of the new prefixes (already parsed). | 3452 // Consume one of the new prefixes (already parsed). |
| 3453 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); | 3453 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); |
| 3454 int last = stack->pop(); | 3454 int pos = stack->pop(); |
| 3455 result = factory()->NewCallNew(result, args, last); | 3455 result = factory()->NewCallNew(result, args, pos); |
| 3456 break; | 3456 break; |
| 3457 } | 3457 } |
| 3458 default: | 3458 default: |
| 3459 return result; | 3459 return result; |
| 3460 } | 3460 } |
| 3461 } | 3461 } |
| 3462 } | 3462 } |
| 3463 | 3463 |
| 3464 | 3464 |
| 3465 DebuggerStatement* Parser::ParseDebuggerStatement(bool* ok) { | 3465 DebuggerStatement* Parser::ParseDebuggerStatement(bool* ok) { |
| 3466 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser | 3466 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser |
| 3467 // contexts this is used as a statement which invokes the debugger as i a | 3467 // contexts this is used as a statement which invokes the debugger as i a |
| 3468 // break point is present. | 3468 // break point is present. |
| 3469 // DebuggerStatement :: | 3469 // DebuggerStatement :: |
| 3470 // 'debugger' ';' | 3470 // 'debugger' ';' |
| 3471 | 3471 |
| 3472 int pos = peek_position(); |
| 3472 Expect(Token::DEBUGGER, CHECK_OK); | 3473 Expect(Token::DEBUGGER, CHECK_OK); |
| 3473 ExpectSemicolon(CHECK_OK); | 3474 ExpectSemicolon(CHECK_OK); |
| 3474 return factory()->NewDebuggerStatement(); | 3475 return factory()->NewDebuggerStatement(pos); |
| 3475 } | 3476 } |
| 3476 | 3477 |
| 3477 | 3478 |
| 3478 void Parser::ReportUnexpectedToken(Token::Value token) { | 3479 void Parser::ReportUnexpectedToken(Token::Value token) { |
| 3479 // We don't report stack overflows here, to avoid increasing the | 3480 // We don't report stack overflows here, to avoid increasing the |
| 3480 // stack depth even further. Instead we report it after parsing is | 3481 // stack depth even further. Instead we report it after parsing is |
| 3481 // over, in ParseProgram/ParseJson. | 3482 // over, in ParseProgram/ParseJson. |
| 3482 if (token == Token::ILLEGAL && stack_overflow_) return; | 3483 if (token == Token::ILLEGAL && stack_overflow()) return; |
| 3483 // Four of the tokens are treated specially | 3484 // Four of the tokens are treated specially |
| 3484 switch (token) { | 3485 switch (token) { |
| 3485 case Token::EOS: | 3486 case Token::EOS: |
| 3486 return ReportMessage("unexpected_eos", Vector<const char*>::empty()); | 3487 return ReportMessage("unexpected_eos", Vector<const char*>::empty()); |
| 3487 case Token::NUMBER: | 3488 case Token::NUMBER: |
| 3488 return ReportMessage("unexpected_token_number", | 3489 return ReportMessage("unexpected_token_number", |
| 3489 Vector<const char*>::empty()); | 3490 Vector<const char*>::empty()); |
| 3490 case Token::STRING: | 3491 case Token::STRING: |
| 3491 return ReportMessage("unexpected_token_string", | 3492 return ReportMessage("unexpected_token_string", |
| 3492 Vector<const char*>::empty()); | 3493 Vector<const char*>::empty()); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3526 // 'true' | 3527 // 'true' |
| 3527 // 'false' | 3528 // 'false' |
| 3528 // Identifier | 3529 // Identifier |
| 3529 // Number | 3530 // Number |
| 3530 // String | 3531 // String |
| 3531 // ArrayLiteral | 3532 // ArrayLiteral |
| 3532 // ObjectLiteral | 3533 // ObjectLiteral |
| 3533 // RegExpLiteral | 3534 // RegExpLiteral |
| 3534 // '(' Expression ')' | 3535 // '(' Expression ')' |
| 3535 | 3536 |
| 3537 int pos = peek_position(); |
| 3536 Expression* result = NULL; | 3538 Expression* result = NULL; |
| 3537 switch (peek()) { | 3539 switch (peek()) { |
| 3538 case Token::THIS: { | 3540 case Token::THIS: { |
| 3539 Consume(Token::THIS); | 3541 Consume(Token::THIS); |
| 3540 result = factory()->NewVariableProxy(top_scope_->receiver()); | 3542 result = factory()->NewVariableProxy(top_scope_->receiver()); |
| 3541 break; | 3543 break; |
| 3542 } | 3544 } |
| 3543 | 3545 |
| 3544 case Token::NULL_LITERAL: | 3546 case Token::NULL_LITERAL: |
| 3545 Consume(Token::NULL_LITERAL); | 3547 Consume(Token::NULL_LITERAL); |
| 3546 result = factory()->NewLiteral(isolate()->factory()->null_value()); | 3548 result = factory()->NewLiteral(isolate()->factory()->null_value(), pos); |
| 3547 break; | 3549 break; |
| 3548 | 3550 |
| 3549 case Token::TRUE_LITERAL: | 3551 case Token::TRUE_LITERAL: |
| 3550 Consume(Token::TRUE_LITERAL); | 3552 Consume(Token::TRUE_LITERAL); |
| 3551 result = factory()->NewLiteral(isolate()->factory()->true_value()); | 3553 result = factory()->NewLiteral(isolate()->factory()->true_value(), pos); |
| 3552 break; | 3554 break; |
| 3553 | 3555 |
| 3554 case Token::FALSE_LITERAL: | 3556 case Token::FALSE_LITERAL: |
| 3555 Consume(Token::FALSE_LITERAL); | 3557 Consume(Token::FALSE_LITERAL); |
| 3556 result = factory()->NewLiteral(isolate()->factory()->false_value()); | 3558 result = factory()->NewLiteral(isolate()->factory()->false_value(), pos); |
| 3557 break; | 3559 break; |
| 3558 | 3560 |
| 3559 case Token::IDENTIFIER: | 3561 case Token::IDENTIFIER: |
| 3560 case Token::YIELD: | 3562 case Token::YIELD: |
| 3561 case Token::FUTURE_STRICT_RESERVED_WORD: { | 3563 case Token::FUTURE_STRICT_RESERVED_WORD: { |
| 3562 Handle<String> name = ParseIdentifier(CHECK_OK); | 3564 Handle<String> name = ParseIdentifier(CHECK_OK); |
| 3563 if (fni_ != NULL) fni_->PushVariableName(name); | 3565 if (fni_ != NULL) fni_->PushVariableName(name); |
| 3564 // The name may refer to a module instance object, so its type is unknown. | 3566 // The name may refer to a module instance object, so its type is unknown. |
| 3565 #ifdef DEBUG | 3567 #ifdef DEBUG |
| 3566 if (FLAG_print_interface_details) | 3568 if (FLAG_print_interface_details) |
| 3567 PrintF("# Variable %s ", name->ToAsciiArray()); | 3569 PrintF("# Variable %s ", name->ToAsciiArray()); |
| 3568 #endif | 3570 #endif |
| 3569 Interface* interface = Interface::NewUnknown(zone()); | 3571 Interface* interface = Interface::NewUnknown(zone()); |
| 3570 result = top_scope_->NewUnresolved( | 3572 result = top_scope_->NewUnresolved(factory(), name, interface, pos); |
| 3571 factory(), name, interface, scanner().location().beg_pos); | |
| 3572 break; | 3573 break; |
| 3573 } | 3574 } |
| 3574 | 3575 |
| 3575 case Token::NUMBER: { | 3576 case Token::NUMBER: { |
| 3576 Consume(Token::NUMBER); | 3577 Consume(Token::NUMBER); |
| 3577 ASSERT(scanner().is_literal_ascii()); | 3578 ASSERT(scanner().is_literal_ascii()); |
| 3578 double value = StringToDouble(isolate()->unicode_cache(), | 3579 double value = StringToDouble(isolate()->unicode_cache(), |
| 3579 scanner().literal_ascii_string(), | 3580 scanner().literal_ascii_string(), |
| 3580 ALLOW_HEX | ALLOW_OCTAL | | 3581 ALLOW_HEX | ALLOW_OCTAL | |
| 3581 ALLOW_IMPLICIT_OCTAL | ALLOW_BINARY); | 3582 ALLOW_IMPLICIT_OCTAL | ALLOW_BINARY); |
| 3582 result = factory()->NewNumberLiteral(value); | 3583 result = factory()->NewNumberLiteral(value, pos); |
| 3583 break; | 3584 break; |
| 3584 } | 3585 } |
| 3585 | 3586 |
| 3586 case Token::STRING: { | 3587 case Token::STRING: { |
| 3587 Consume(Token::STRING); | 3588 Consume(Token::STRING); |
| 3588 Handle<String> symbol = GetSymbol(); | 3589 Handle<String> symbol = GetSymbol(); |
| 3589 result = factory()->NewLiteral(symbol); | 3590 result = factory()->NewLiteral(symbol, pos); |
| 3590 if (fni_ != NULL) fni_->PushLiteralName(symbol); | 3591 if (fni_ != NULL) fni_->PushLiteralName(symbol); |
| 3591 break; | 3592 break; |
| 3592 } | 3593 } |
| 3593 | 3594 |
| 3594 case Token::ASSIGN_DIV: | 3595 case Token::ASSIGN_DIV: |
| 3595 result = ParseRegExpLiteral(true, CHECK_OK); | 3596 result = ParseRegExpLiteral(true, CHECK_OK); |
| 3596 break; | 3597 break; |
| 3597 | 3598 |
| 3598 case Token::DIV: | 3599 case Token::DIV: |
| 3599 result = ParseRegExpLiteral(false, CHECK_OK); | 3600 result = ParseRegExpLiteral(false, CHECK_OK); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3633 } | 3634 } |
| 3634 | 3635 |
| 3635 return result; | 3636 return result; |
| 3636 } | 3637 } |
| 3637 | 3638 |
| 3638 | 3639 |
| 3639 Expression* Parser::ParseArrayLiteral(bool* ok) { | 3640 Expression* Parser::ParseArrayLiteral(bool* ok) { |
| 3640 // ArrayLiteral :: | 3641 // ArrayLiteral :: |
| 3641 // '[' Expression? (',' Expression?)* ']' | 3642 // '[' Expression? (',' Expression?)* ']' |
| 3642 | 3643 |
| 3644 int pos = peek_position(); |
| 3643 ZoneList<Expression*>* values = new(zone()) ZoneList<Expression*>(4, zone()); | 3645 ZoneList<Expression*>* values = new(zone()) ZoneList<Expression*>(4, zone()); |
| 3644 Expect(Token::LBRACK, CHECK_OK); | 3646 Expect(Token::LBRACK, CHECK_OK); |
| 3645 while (peek() != Token::RBRACK) { | 3647 while (peek() != Token::RBRACK) { |
| 3646 Expression* elem; | 3648 Expression* elem; |
| 3647 if (peek() == Token::COMMA) { | 3649 if (peek() == Token::COMMA) { |
| 3648 elem = GetLiteralTheHole(); | 3650 elem = GetLiteralTheHole(peek_position()); |
| 3649 } else { | 3651 } else { |
| 3650 elem = ParseAssignmentExpression(true, CHECK_OK); | 3652 elem = ParseAssignmentExpression(true, CHECK_OK); |
| 3651 } | 3653 } |
| 3652 values->Add(elem, zone()); | 3654 values->Add(elem, zone()); |
| 3653 if (peek() != Token::RBRACK) { | 3655 if (peek() != Token::RBRACK) { |
| 3654 Expect(Token::COMMA, CHECK_OK); | 3656 Expect(Token::COMMA, CHECK_OK); |
| 3655 } | 3657 } |
| 3656 } | 3658 } |
| 3657 Expect(Token::RBRACK, CHECK_OK); | 3659 Expect(Token::RBRACK, CHECK_OK); |
| 3658 | 3660 |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3700 // in a 2-element FixedArray. | 3702 // in a 2-element FixedArray. |
| 3701 Handle<FixedArray> literals = isolate()->factory()->NewFixedArray(2, TENURED); | 3703 Handle<FixedArray> literals = isolate()->factory()->NewFixedArray(2, TENURED); |
| 3702 | 3704 |
| 3703 ElementsKind kind = array->GetElementsKind(); | 3705 ElementsKind kind = array->GetElementsKind(); |
| 3704 kind = is_holey ? GetHoleyElementsKind(kind) : GetPackedElementsKind(kind); | 3706 kind = is_holey ? GetHoleyElementsKind(kind) : GetPackedElementsKind(kind); |
| 3705 | 3707 |
| 3706 literals->set(0, Smi::FromInt(kind)); | 3708 literals->set(0, Smi::FromInt(kind)); |
| 3707 literals->set(1, *element_values); | 3709 literals->set(1, *element_values); |
| 3708 | 3710 |
| 3709 return factory()->NewArrayLiteral( | 3711 return factory()->NewArrayLiteral( |
| 3710 literals, values, literal_index, is_simple, depth); | 3712 literals, values, literal_index, is_simple, depth, pos); |
| 3711 } | 3713 } |
| 3712 | 3714 |
| 3713 | 3715 |
| 3714 bool Parser::IsBoilerplateProperty(ObjectLiteral::Property* property) { | 3716 bool Parser::IsBoilerplateProperty(ObjectLiteral::Property* property) { |
| 3715 return property != NULL && | 3717 return property != NULL && |
| 3716 property->kind() != ObjectLiteral::Property::PROTOTYPE; | 3718 property->kind() != ObjectLiteral::Property::PROTOTYPE; |
| 3717 } | 3719 } |
| 3718 | 3720 |
| 3719 | 3721 |
| 3720 bool CompileTimeValue::IsCompileTimeValue(Expression* expression) { | 3722 bool CompileTimeValue::IsCompileTimeValue(Expression* expression) { |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3836 constant_properties->set(position++, *key); | 3838 constant_properties->set(position++, *key); |
| 3837 constant_properties->set(position++, *value); | 3839 constant_properties->set(position++, *value); |
| 3838 } | 3840 } |
| 3839 *fast_elements = | 3841 *fast_elements = |
| 3840 (max_element_index <= 32) || ((2 * elements) >= max_element_index); | 3842 (max_element_index <= 32) || ((2 * elements) >= max_element_index); |
| 3841 *is_simple = is_simple_acc; | 3843 *is_simple = is_simple_acc; |
| 3842 *depth = depth_acc; | 3844 *depth = depth_acc; |
| 3843 } | 3845 } |
| 3844 | 3846 |
| 3845 | 3847 |
| 3846 // Force instantiation of template instances class. | |
| 3847 template void ObjectLiteralChecker<Parser>::CheckProperty( | |
| 3848 Token::Value property, PropertyKind type, bool* ok); | |
| 3849 | |
| 3850 | |
| 3851 Expression* Parser::ParseObjectLiteral(bool* ok) { | 3848 Expression* Parser::ParseObjectLiteral(bool* ok) { |
| 3852 // ObjectLiteral :: | 3849 // ObjectLiteral :: |
| 3853 // '{' ( | 3850 // '{' ( |
| 3854 // ((IdentifierName | String | Number) ':' AssignmentExpression) | 3851 // ((IdentifierName | String | Number) ':' AssignmentExpression) |
| 3855 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) | 3852 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) |
| 3856 // )*[','] '}' | 3853 // )*[','] '}' |
| 3857 | 3854 |
| 3855 int pos = peek_position(); |
| 3858 ZoneList<ObjectLiteral::Property*>* properties = | 3856 ZoneList<ObjectLiteral::Property*>* properties = |
| 3859 new(zone()) ZoneList<ObjectLiteral::Property*>(4, zone()); | 3857 new(zone()) ZoneList<ObjectLiteral::Property*>(4, zone()); |
| 3860 int number_of_boilerplate_properties = 0; | 3858 int number_of_boilerplate_properties = 0; |
| 3861 bool has_function = false; | 3859 bool has_function = false; |
| 3862 | 3860 |
| 3863 ObjectLiteralChecker<Parser> checker(this, &scanner_, | 3861 ObjectLiteralChecker checker(this, top_scope_->language_mode()); |
| 3864 top_scope_->language_mode()); | |
| 3865 | 3862 |
| 3866 Expect(Token::LBRACE, CHECK_OK); | 3863 Expect(Token::LBRACE, CHECK_OK); |
| 3867 | 3864 |
| 3868 while (peek() != Token::RBRACE) { | 3865 while (peek() != Token::RBRACE) { |
| 3869 if (fni_ != NULL) fni_->Enter(); | 3866 if (fni_ != NULL) fni_->Enter(); |
| 3870 | 3867 |
| 3871 Literal* key = NULL; | 3868 Literal* key = NULL; |
| 3872 Token::Value next = peek(); | 3869 Token::Value next = peek(); |
| 3870 int next_pos = peek_position(); |
| 3873 | 3871 |
| 3874 switch (next) { | 3872 switch (next) { |
| 3875 case Token::FUTURE_RESERVED_WORD: | 3873 case Token::FUTURE_RESERVED_WORD: |
| 3876 case Token::FUTURE_STRICT_RESERVED_WORD: | 3874 case Token::FUTURE_STRICT_RESERVED_WORD: |
| 3877 case Token::IDENTIFIER: { | 3875 case Token::IDENTIFIER: { |
| 3878 bool is_getter = false; | 3876 bool is_getter = false; |
| 3879 bool is_setter = false; | 3877 bool is_setter = false; |
| 3880 Handle<String> id = | 3878 Handle<String> id = |
| 3881 ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter, CHECK_OK); | 3879 ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter, CHECK_OK); |
| 3882 if (fni_ != NULL) fni_->PushLiteralName(id); | 3880 if (fni_ != NULL) fni_->PushLiteralName(id); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 3907 FunctionLiteral* value = | 3905 FunctionLiteral* value = |
| 3908 ParseFunctionLiteral(name, | 3906 ParseFunctionLiteral(name, |
| 3909 false, // reserved words are allowed here | 3907 false, // reserved words are allowed here |
| 3910 false, // not a generator | 3908 false, // not a generator |
| 3911 RelocInfo::kNoPosition, | 3909 RelocInfo::kNoPosition, |
| 3912 FunctionLiteral::ANONYMOUS_EXPRESSION, | 3910 FunctionLiteral::ANONYMOUS_EXPRESSION, |
| 3913 CHECK_OK); | 3911 CHECK_OK); |
| 3914 // Allow any number of parameters for compatibilty with JSC. | 3912 // Allow any number of parameters for compatibilty with JSC. |
| 3915 // Specification only allows zero parameters for get and one for set. | 3913 // Specification only allows zero parameters for get and one for set. |
| 3916 ObjectLiteral::Property* property = | 3914 ObjectLiteral::Property* property = |
| 3917 factory()->NewObjectLiteralProperty(is_getter, value); | 3915 factory()->NewObjectLiteralProperty(is_getter, value, next_pos); |
| 3918 if (IsBoilerplateProperty(property)) { | 3916 if (IsBoilerplateProperty(property)) { |
| 3919 number_of_boilerplate_properties++; | 3917 number_of_boilerplate_properties++; |
| 3920 } | 3918 } |
| 3921 properties->Add(property, zone()); | 3919 properties->Add(property, zone()); |
| 3922 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK); | 3920 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK); |
| 3923 | 3921 |
| 3924 if (fni_ != NULL) { | 3922 if (fni_ != NULL) { |
| 3925 fni_->Infer(); | 3923 fni_->Infer(); |
| 3926 fni_->Leave(); | 3924 fni_->Leave(); |
| 3927 } | 3925 } |
| 3928 continue; // restart the while | 3926 continue; // restart the while |
| 3929 } | 3927 } |
| 3930 // Failed to parse as get/set property, so it's just a property | 3928 // Failed to parse as get/set property, so it's just a property |
| 3931 // called "get" or "set". | 3929 // called "get" or "set". |
| 3932 key = factory()->NewLiteral(id); | 3930 key = factory()->NewLiteral(id, next_pos); |
| 3933 break; | 3931 break; |
| 3934 } | 3932 } |
| 3935 case Token::STRING: { | 3933 case Token::STRING: { |
| 3936 Consume(Token::STRING); | 3934 Consume(Token::STRING); |
| 3937 Handle<String> string = GetSymbol(); | 3935 Handle<String> string = GetSymbol(); |
| 3938 if (fni_ != NULL) fni_->PushLiteralName(string); | 3936 if (fni_ != NULL) fni_->PushLiteralName(string); |
| 3939 uint32_t index; | 3937 uint32_t index; |
| 3940 if (!string.is_null() && string->AsArrayIndex(&index)) { | 3938 if (!string.is_null() && string->AsArrayIndex(&index)) { |
| 3941 key = factory()->NewNumberLiteral(index); | 3939 key = factory()->NewNumberLiteral(index, next_pos); |
| 3942 break; | 3940 break; |
| 3943 } | 3941 } |
| 3944 key = factory()->NewLiteral(string); | 3942 key = factory()->NewLiteral(string, next_pos); |
| 3945 break; | 3943 break; |
| 3946 } | 3944 } |
| 3947 case Token::NUMBER: { | 3945 case Token::NUMBER: { |
| 3948 Consume(Token::NUMBER); | 3946 Consume(Token::NUMBER); |
| 3949 ASSERT(scanner().is_literal_ascii()); | 3947 ASSERT(scanner().is_literal_ascii()); |
| 3950 double value = StringToDouble(isolate()->unicode_cache(), | 3948 double value = StringToDouble(isolate()->unicode_cache(), |
| 3951 scanner().literal_ascii_string(), | 3949 scanner().literal_ascii_string(), |
| 3952 ALLOW_HEX | ALLOW_OCTAL | | 3950 ALLOW_HEX | ALLOW_OCTAL | |
| 3953 ALLOW_IMPLICIT_OCTAL | ALLOW_BINARY); | 3951 ALLOW_IMPLICIT_OCTAL | ALLOW_BINARY); |
| 3954 key = factory()->NewNumberLiteral(value); | 3952 key = factory()->NewNumberLiteral(value, next_pos); |
| 3955 break; | 3953 break; |
| 3956 } | 3954 } |
| 3957 default: | 3955 default: |
| 3958 if (Token::IsKeyword(next)) { | 3956 if (Token::IsKeyword(next)) { |
| 3959 Consume(next); | 3957 Consume(next); |
| 3960 Handle<String> string = GetSymbol(); | 3958 Handle<String> string = GetSymbol(); |
| 3961 key = factory()->NewLiteral(string); | 3959 key = factory()->NewLiteral(string, next_pos); |
| 3962 } else { | 3960 } else { |
| 3963 // Unexpected token. | 3961 // Unexpected token. |
| 3964 Token::Value next = Next(); | 3962 Token::Value next = Next(); |
| 3965 ReportUnexpectedToken(next); | 3963 ReportUnexpectedToken(next); |
| 3966 *ok = false; | 3964 *ok = false; |
| 3967 return NULL; | 3965 return NULL; |
| 3968 } | 3966 } |
| 3969 } | 3967 } |
| 3970 | 3968 |
| 3971 // Validate the property | 3969 // Validate the property |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4016 &fast_elements, | 4014 &fast_elements, |
| 4017 &depth, | 4015 &depth, |
| 4018 &may_store_doubles); | 4016 &may_store_doubles); |
| 4019 return factory()->NewObjectLiteral(constant_properties, | 4017 return factory()->NewObjectLiteral(constant_properties, |
| 4020 properties, | 4018 properties, |
| 4021 literal_index, | 4019 literal_index, |
| 4022 is_simple, | 4020 is_simple, |
| 4023 fast_elements, | 4021 fast_elements, |
| 4024 depth, | 4022 depth, |
| 4025 may_store_doubles, | 4023 may_store_doubles, |
| 4026 has_function); | 4024 has_function, |
| 4025 pos); |
| 4027 } | 4026 } |
| 4028 | 4027 |
| 4029 | 4028 |
| 4030 Expression* Parser::ParseRegExpLiteral(bool seen_equal, bool* ok) { | 4029 Expression* Parser::ParseRegExpLiteral(bool seen_equal, bool* ok) { |
| 4030 int pos = peek_position(); |
| 4031 if (!scanner().ScanRegExpPattern(seen_equal)) { | 4031 if (!scanner().ScanRegExpPattern(seen_equal)) { |
| 4032 Next(); | 4032 Next(); |
| 4033 ReportMessage("unterminated_regexp", Vector<const char*>::empty()); | 4033 ReportMessage("unterminated_regexp", Vector<const char*>::empty()); |
| 4034 *ok = false; | 4034 *ok = false; |
| 4035 return NULL; | 4035 return NULL; |
| 4036 } | 4036 } |
| 4037 | 4037 |
| 4038 int literal_index = current_function_state_->NextMaterializedLiteralIndex(); | 4038 int literal_index = current_function_state_->NextMaterializedLiteralIndex(); |
| 4039 | 4039 |
| 4040 Handle<String> js_pattern = NextLiteralString(TENURED); | 4040 Handle<String> js_pattern = NextLiteralString(TENURED); |
| 4041 scanner().ScanRegExpFlags(); | 4041 scanner().ScanRegExpFlags(); |
| 4042 Handle<String> js_flags = NextLiteralString(TENURED); | 4042 Handle<String> js_flags = NextLiteralString(TENURED); |
| 4043 Next(); | 4043 Next(); |
| 4044 | 4044 |
| 4045 return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index); | 4045 return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos); |
| 4046 } | 4046 } |
| 4047 | 4047 |
| 4048 | 4048 |
| 4049 ZoneList<Expression*>* Parser::ParseArguments(bool* ok) { | 4049 ZoneList<Expression*>* Parser::ParseArguments(bool* ok) { |
| 4050 // Arguments :: | 4050 // Arguments :: |
| 4051 // '(' (AssignmentExpression)*[','] ')' | 4051 // '(' (AssignmentExpression)*[','] ')' |
| 4052 | 4052 |
| 4053 ZoneList<Expression*>* result = new(zone()) ZoneList<Expression*>(4, zone()); | 4053 ZoneList<Expression*>* result = new(zone()) ZoneList<Expression*>(4, zone()); |
| 4054 Expect(Token::LPAREN, CHECK_OK); | 4054 Expect(Token::LPAREN, CHECK_OK); |
| 4055 bool done = (peek() == Token::RPAREN); | 4055 bool done = (peek() == Token::RPAREN); |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4160 // For error messages. | 4160 // For error messages. |
| 4161 const char* message_; | 4161 const char* message_; |
| 4162 const char* argument_opt_; | 4162 const char* argument_opt_; |
| 4163 }; | 4163 }; |
| 4164 | 4164 |
| 4165 | 4165 |
| 4166 FunctionLiteral* Parser::ParseFunctionLiteral( | 4166 FunctionLiteral* Parser::ParseFunctionLiteral( |
| 4167 Handle<String> function_name, | 4167 Handle<String> function_name, |
| 4168 bool name_is_strict_reserved, | 4168 bool name_is_strict_reserved, |
| 4169 bool is_generator, | 4169 bool is_generator, |
| 4170 int function_token_position, | 4170 int function_token_pos, |
| 4171 FunctionLiteral::FunctionType function_type, | 4171 FunctionLiteral::FunctionType function_type, |
| 4172 bool* ok) { | 4172 bool* ok) { |
| 4173 // Function :: | 4173 // Function :: |
| 4174 // '(' FormalParameterList? ')' '{' FunctionBody '}' | 4174 // '(' FormalParameterList? ')' '{' FunctionBody '}' |
| 4175 | 4175 |
| 4176 int pos = function_token_pos == RelocInfo::kNoPosition |
| 4177 ? peek_position() : function_token_pos; |
| 4178 |
| 4176 // Anonymous functions were passed either the empty symbol or a null | 4179 // Anonymous functions were passed either the empty symbol or a null |
| 4177 // handle as the function name. Remember if we were passed a non-empty | 4180 // handle as the function name. Remember if we were passed a non-empty |
| 4178 // handle to decide whether to invoke function name inference. | 4181 // handle to decide whether to invoke function name inference. |
| 4179 bool should_infer_name = function_name.is_null(); | 4182 bool should_infer_name = function_name.is_null(); |
| 4180 | 4183 |
| 4181 // We want a non-null handle as the function name. | 4184 // We want a non-null handle as the function name. |
| 4182 if (should_infer_name) { | 4185 if (should_infer_name) { |
| 4183 function_name = isolate()->factory()->empty_string(); | 4186 function_name = isolate()->factory()->empty_string(); |
| 4184 } | 4187 } |
| 4185 | 4188 |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4303 // instead of Variables and Proxis as is the case now. | 4306 // instead of Variables and Proxis as is the case now. |
| 4304 Variable* fvar = NULL; | 4307 Variable* fvar = NULL; |
| 4305 Token::Value fvar_init_op = Token::INIT_CONST; | 4308 Token::Value fvar_init_op = Token::INIT_CONST; |
| 4306 if (function_type == FunctionLiteral::NAMED_EXPRESSION) { | 4309 if (function_type == FunctionLiteral::NAMED_EXPRESSION) { |
| 4307 if (is_extended_mode()) fvar_init_op = Token::INIT_CONST_HARMONY; | 4310 if (is_extended_mode()) fvar_init_op = Token::INIT_CONST_HARMONY; |
| 4308 VariableMode fvar_mode = is_extended_mode() ? CONST_HARMONY : CONST; | 4311 VariableMode fvar_mode = is_extended_mode() ? CONST_HARMONY : CONST; |
| 4309 fvar = new(zone()) Variable(top_scope_, | 4312 fvar = new(zone()) Variable(top_scope_, |
| 4310 function_name, fvar_mode, true /* is valid LHS */, | 4313 function_name, fvar_mode, true /* is valid LHS */, |
| 4311 Variable::NORMAL, kCreatedInitialized, Interface::NewConst()); | 4314 Variable::NORMAL, kCreatedInitialized, Interface::NewConst()); |
| 4312 VariableProxy* proxy = factory()->NewVariableProxy(fvar); | 4315 VariableProxy* proxy = factory()->NewVariableProxy(fvar); |
| 4313 VariableDeclaration* fvar_declaration = | 4316 VariableDeclaration* fvar_declaration = factory()->NewVariableDeclaration( |
| 4314 factory()->NewVariableDeclaration(proxy, fvar_mode, top_scope_); | 4317 proxy, fvar_mode, top_scope_, RelocInfo::kNoPosition); |
| 4315 top_scope_->DeclareFunctionVar(fvar_declaration); | 4318 top_scope_->DeclareFunctionVar(fvar_declaration); |
| 4316 } | 4319 } |
| 4317 | 4320 |
| 4318 // Determine whether the function will be lazily compiled. | 4321 // Determine whether the function will be lazily compiled. |
| 4319 // The heuristics are: | 4322 // The heuristics are: |
| 4320 // - It must not have been prohibited by the caller to Parse (some callers | 4323 // - It must not have been prohibited by the caller to Parse (some callers |
| 4321 // need a full AST). | 4324 // need a full AST). |
| 4322 // - The outer scope must allow lazy compilation of inner functions. | 4325 // - The outer scope must allow lazy compilation of inner functions. |
| 4323 // - The function mustn't be a function expression with an open parenthesis | 4326 // - The function mustn't be a function expression with an open parenthesis |
| 4324 // before; we consider that a hint that the function will be called | 4327 // before; we consider that a hint that the function will be called |
| 4325 // immediately, and it would be a waste of time to make it lazily | 4328 // immediately, and it would be a waste of time to make it lazily |
| 4326 // compiled. | 4329 // compiled. |
| 4327 // These are all things we can know at this point, without looking at the | 4330 // These are all things we can know at this point, without looking at the |
| 4328 // function itself. | 4331 // function itself. |
| 4329 bool is_lazily_compiled = (mode() == PARSE_LAZILY && | 4332 bool is_lazily_compiled = (mode() == PARSE_LAZILY && |
| 4330 top_scope_->AllowsLazyCompilation() && | 4333 top_scope_->AllowsLazyCompilation() && |
| 4331 !parenthesized_function_); | 4334 !parenthesized_function_); |
| 4332 parenthesized_function_ = false; // The bit was set for this function only. | 4335 parenthesized_function_ = false; // The bit was set for this function only. |
| 4333 | 4336 |
| 4334 if (is_lazily_compiled) { | 4337 if (is_lazily_compiled) { |
| 4335 int function_block_pos = scanner().location().beg_pos; | 4338 int function_block_pos = position(); |
| 4336 FunctionEntry entry; | 4339 FunctionEntry entry; |
| 4337 if (pre_parse_data_ != NULL) { | 4340 if (pre_parse_data_ != NULL) { |
| 4338 // If we have pre_parse_data_, we use it to skip parsing the function | 4341 // If we have pre_parse_data_, we use it to skip parsing the function |
| 4339 // body. The preparser data contains the information we need to | 4342 // body. The preparser data contains the information we need to |
| 4340 // construct the lazy function. | 4343 // construct the lazy function. |
| 4341 entry = pre_parse_data()->GetFunctionEntry(function_block_pos); | 4344 entry = pre_parse_data()->GetFunctionEntry(function_block_pos); |
| 4342 if (entry.is_valid()) { | 4345 if (entry.is_valid()) { |
| 4343 if (entry.end_pos() <= function_block_pos) { | 4346 if (entry.end_pos() <= function_block_pos) { |
| 4344 // End position greater than end of stream is safe, and hard | 4347 // End position greater than end of stream is safe, and hard |
| 4345 // to check. | 4348 // to check. |
| 4346 ReportInvalidPreparseData(function_name, CHECK_OK); | 4349 ReportInvalidPreparseData(function_name, CHECK_OK); |
| 4347 } | 4350 } |
| 4348 scanner().SeekForward(entry.end_pos() - 1); | 4351 scanner().SeekForward(entry.end_pos() - 1); |
| 4349 | 4352 |
| 4350 scope->set_end_position(entry.end_pos()); | 4353 scope->set_end_position(entry.end_pos()); |
| 4351 Expect(Token::RBRACE, CHECK_OK); | 4354 Expect(Token::RBRACE, CHECK_OK); |
| 4352 isolate()->counters()->total_preparse_skipped()->Increment( | 4355 isolate()->counters()->total_preparse_skipped()->Increment( |
| 4353 scope->end_position() - function_block_pos); | 4356 scope->end_position() - function_block_pos); |
| 4354 materialized_literal_count = entry.literal_count(); | 4357 materialized_literal_count = entry.literal_count(); |
| 4355 expected_property_count = entry.property_count(); | 4358 expected_property_count = entry.property_count(); |
| 4356 top_scope_->SetLanguageMode(entry.language_mode()); | 4359 top_scope_->SetLanguageMode(entry.language_mode()); |
| 4357 } else { | 4360 } else { |
| 4358 is_lazily_compiled = false; | 4361 is_lazily_compiled = false; |
| 4359 } | 4362 } |
| 4360 } else { | 4363 } else { |
| 4361 // With no preparser data, we partially parse the function, without | 4364 // With no preparser data, we partially parse the function, without |
| 4362 // building an AST. This gathers the data needed to build a lazy | 4365 // building an AST. This gathers the data needed to build a lazy |
| 4363 // function. | 4366 // function. |
| 4364 SingletonLogger logger; | 4367 SingletonLogger logger; |
| 4365 preparser::PreParser::PreParseResult result = | 4368 PreParser::PreParseResult result = LazyParseFunctionLiteral(&logger); |
| 4366 LazyParseFunctionLiteral(&logger); | 4369 if (result == PreParser::kPreParseStackOverflow) { |
| 4367 if (result == preparser::PreParser::kPreParseStackOverflow) { | |
| 4368 // Propagate stack overflow. | 4370 // Propagate stack overflow. |
| 4369 stack_overflow_ = true; | 4371 set_stack_overflow(); |
| 4370 *ok = false; | 4372 *ok = false; |
| 4371 return NULL; | 4373 return NULL; |
| 4372 } | 4374 } |
| 4373 if (logger.has_error()) { | 4375 if (logger.has_error()) { |
| 4374 const char* arg = logger.argument_opt(); | 4376 const char* arg = logger.argument_opt(); |
| 4375 Vector<const char*> args; | 4377 Vector<const char*> args; |
| 4376 if (arg != NULL) { | 4378 if (arg != NULL) { |
| 4377 args = Vector<const char*>(&arg, 1); | 4379 args = Vector<const char*>(&arg, 1); |
| 4378 } | 4380 } |
| 4379 ReportMessageAt(Scanner::Location(logger.start(), logger.end()), | 4381 ReportMessageAt(Scanner::Location(logger.start(), logger.end()), |
| (...skipping 14 matching lines...) Expand all Loading... |
| 4394 if (!is_lazily_compiled) { | 4396 if (!is_lazily_compiled) { |
| 4395 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); | 4397 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); |
| 4396 body = new(zone()) ZoneList<Statement*>(8, zone()); | 4398 body = new(zone()) ZoneList<Statement*>(8, zone()); |
| 4397 if (fvar != NULL) { | 4399 if (fvar != NULL) { |
| 4398 VariableProxy* fproxy = top_scope_->NewUnresolved( | 4400 VariableProxy* fproxy = top_scope_->NewUnresolved( |
| 4399 factory(), function_name, Interface::NewConst()); | 4401 factory(), function_name, Interface::NewConst()); |
| 4400 fproxy->BindTo(fvar); | 4402 fproxy->BindTo(fvar); |
| 4401 body->Add(factory()->NewExpressionStatement( | 4403 body->Add(factory()->NewExpressionStatement( |
| 4402 factory()->NewAssignment(fvar_init_op, | 4404 factory()->NewAssignment(fvar_init_op, |
| 4403 fproxy, | 4405 fproxy, |
| 4404 factory()->NewThisFunction(), | 4406 factory()->NewThisFunction(pos), |
| 4405 RelocInfo::kNoPosition)), | 4407 RelocInfo::kNoPosition), |
| 4406 zone()); | 4408 RelocInfo::kNoPosition), zone()); |
| 4407 } | 4409 } |
| 4408 | 4410 |
| 4409 // For generators, allocate and yield an iterator on function entry. | 4411 // For generators, allocate and yield an iterator on function entry. |
| 4410 if (is_generator) { | 4412 if (is_generator) { |
| 4411 ZoneList<Expression*>* arguments = | 4413 ZoneList<Expression*>* arguments = |
| 4412 new(zone()) ZoneList<Expression*>(0, zone()); | 4414 new(zone()) ZoneList<Expression*>(0, zone()); |
| 4413 CallRuntime* allocation = factory()->NewCallRuntime( | 4415 CallRuntime* allocation = factory()->NewCallRuntime( |
| 4414 isolate()->factory()->empty_string(), | 4416 isolate()->factory()->empty_string(), |
| 4415 Runtime::FunctionForId(Runtime::kCreateJSGeneratorObject), | 4417 Runtime::FunctionForId(Runtime::kCreateJSGeneratorObject), |
| 4416 arguments); | 4418 arguments, pos); |
| 4417 VariableProxy* init_proxy = factory()->NewVariableProxy( | 4419 VariableProxy* init_proxy = factory()->NewVariableProxy( |
| 4418 current_function_state_->generator_object_variable()); | 4420 current_function_state_->generator_object_variable()); |
| 4419 Assignment* assignment = factory()->NewAssignment( | 4421 Assignment* assignment = factory()->NewAssignment( |
| 4420 Token::INIT_VAR, init_proxy, allocation, RelocInfo::kNoPosition); | 4422 Token::INIT_VAR, init_proxy, allocation, RelocInfo::kNoPosition); |
| 4421 VariableProxy* get_proxy = factory()->NewVariableProxy( | 4423 VariableProxy* get_proxy = factory()->NewVariableProxy( |
| 4422 current_function_state_->generator_object_variable()); | 4424 current_function_state_->generator_object_variable()); |
| 4423 Yield* yield = factory()->NewYield( | 4425 Yield* yield = factory()->NewYield( |
| 4424 get_proxy, assignment, Yield::INITIAL, RelocInfo::kNoPosition); | 4426 get_proxy, assignment, Yield::INITIAL, RelocInfo::kNoPosition); |
| 4425 body->Add(factory()->NewExpressionStatement(yield), zone()); | 4427 body->Add(factory()->NewExpressionStatement( |
| 4428 yield, RelocInfo::kNoPosition), zone()); |
| 4426 } | 4429 } |
| 4427 | 4430 |
| 4428 ParseSourceElements(body, Token::RBRACE, false, false, CHECK_OK); | 4431 ParseSourceElements(body, Token::RBRACE, false, false, CHECK_OK); |
| 4429 | 4432 |
| 4430 if (is_generator) { | 4433 if (is_generator) { |
| 4431 VariableProxy* get_proxy = factory()->NewVariableProxy( | 4434 VariableProxy* get_proxy = factory()->NewVariableProxy( |
| 4432 current_function_state_->generator_object_variable()); | 4435 current_function_state_->generator_object_variable()); |
| 4433 Expression *undefined = factory()->NewLiteral( | 4436 Expression *undefined = factory()->NewLiteral( |
| 4434 isolate()->factory()->undefined_value()); | 4437 isolate()->factory()->undefined_value(), RelocInfo::kNoPosition); |
| 4435 Yield* yield = factory()->NewYield( | 4438 Yield* yield = factory()->NewYield( |
| 4436 get_proxy, undefined, Yield::FINAL, RelocInfo::kNoPosition); | 4439 get_proxy, undefined, Yield::FINAL, RelocInfo::kNoPosition); |
| 4437 body->Add(factory()->NewExpressionStatement(yield), zone()); | 4440 body->Add(factory()->NewExpressionStatement( |
| 4441 yield, RelocInfo::kNoPosition), zone()); |
| 4438 } | 4442 } |
| 4439 | 4443 |
| 4440 materialized_literal_count = function_state.materialized_literal_count(); | 4444 materialized_literal_count = function_state.materialized_literal_count(); |
| 4441 expected_property_count = function_state.expected_property_count(); | 4445 expected_property_count = function_state.expected_property_count(); |
| 4442 handler_count = function_state.handler_count(); | 4446 handler_count = function_state.handler_count(); |
| 4443 | 4447 |
| 4444 Expect(Token::RBRACE, CHECK_OK); | 4448 Expect(Token::RBRACE, CHECK_OK); |
| 4445 scope->set_end_position(scanner().location().end_pos); | 4449 scope->set_end_position(scanner().location().end_pos); |
| 4446 } | 4450 } |
| 4447 | 4451 |
| 4448 // Validate strict mode. | 4452 // Validate strict mode. |
| 4449 if (!top_scope_->is_classic_mode()) { | 4453 if (!top_scope_->is_classic_mode()) { |
| 4450 if (IsEvalOrArguments(function_name)) { | 4454 if (IsEvalOrArguments(function_name)) { |
| 4451 int start_pos = scope->start_position(); | 4455 int start_pos = scope->start_position(); |
| 4452 int position = function_token_position != RelocInfo::kNoPosition | 4456 int position = function_token_pos != RelocInfo::kNoPosition |
| 4453 ? function_token_position | 4457 ? function_token_pos : (start_pos > 0 ? start_pos - 1 : start_pos); |
| 4454 : (start_pos > 0 ? start_pos - 1 : start_pos); | |
| 4455 Scanner::Location location = Scanner::Location(position, start_pos); | 4458 Scanner::Location location = Scanner::Location(position, start_pos); |
| 4456 ReportMessageAt(location, | 4459 ReportMessageAt(location, |
| 4457 "strict_function_name", Vector<const char*>::empty()); | 4460 "strict_function_name", Vector<const char*>::empty()); |
| 4458 *ok = false; | 4461 *ok = false; |
| 4459 return NULL; | 4462 return NULL; |
| 4460 } | 4463 } |
| 4461 if (name_loc.IsValid()) { | 4464 if (name_loc.IsValid()) { |
| 4462 ReportMessageAt(name_loc, "strict_param_name", | 4465 ReportMessageAt(name_loc, "strict_param_name", |
| 4463 Vector<const char*>::empty()); | 4466 Vector<const char*>::empty()); |
| 4464 *ok = false; | 4467 *ok = false; |
| 4465 return NULL; | 4468 return NULL; |
| 4466 } | 4469 } |
| 4467 if (dupe_loc.IsValid()) { | 4470 if (dupe_loc.IsValid()) { |
| 4468 ReportMessageAt(dupe_loc, "strict_param_dupe", | 4471 ReportMessageAt(dupe_loc, "strict_param_dupe", |
| 4469 Vector<const char*>::empty()); | 4472 Vector<const char*>::empty()); |
| 4470 *ok = false; | 4473 *ok = false; |
| 4471 return NULL; | 4474 return NULL; |
| 4472 } | 4475 } |
| 4473 if (name_is_strict_reserved) { | 4476 if (name_is_strict_reserved) { |
| 4474 int start_pos = scope->start_position(); | 4477 int start_pos = scope->start_position(); |
| 4475 int position = function_token_position != RelocInfo::kNoPosition | 4478 int position = function_token_pos != RelocInfo::kNoPosition |
| 4476 ? function_token_position | 4479 ? function_token_pos : (start_pos > 0 ? start_pos - 1 : start_pos); |
| 4477 : (start_pos > 0 ? start_pos - 1 : start_pos); | |
| 4478 Scanner::Location location = Scanner::Location(position, start_pos); | 4480 Scanner::Location location = Scanner::Location(position, start_pos); |
| 4479 ReportMessageAt(location, "strict_reserved_word", | 4481 ReportMessageAt(location, "strict_reserved_word", |
| 4480 Vector<const char*>::empty()); | 4482 Vector<const char*>::empty()); |
| 4481 *ok = false; | 4483 *ok = false; |
| 4482 return NULL; | 4484 return NULL; |
| 4483 } | 4485 } |
| 4484 if (reserved_loc.IsValid()) { | 4486 if (reserved_loc.IsValid()) { |
| 4485 ReportMessageAt(reserved_loc, "strict_reserved_word", | 4487 ReportMessageAt(reserved_loc, "strict_reserved_word", |
| 4486 Vector<const char*>::empty()); | 4488 Vector<const char*>::empty()); |
| 4487 *ok = false; | 4489 *ok = false; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 4504 scope, | 4506 scope, |
| 4505 body, | 4507 body, |
| 4506 materialized_literal_count, | 4508 materialized_literal_count, |
| 4507 expected_property_count, | 4509 expected_property_count, |
| 4508 handler_count, | 4510 handler_count, |
| 4509 num_parameters, | 4511 num_parameters, |
| 4510 duplicate_parameters, | 4512 duplicate_parameters, |
| 4511 function_type, | 4513 function_type, |
| 4512 FunctionLiteral::kIsFunction, | 4514 FunctionLiteral::kIsFunction, |
| 4513 parenthesized, | 4515 parenthesized, |
| 4514 generator); | 4516 generator, |
| 4515 function_literal->set_function_token_position(function_token_position); | 4517 pos); |
| 4518 function_literal->set_function_token_position(function_token_pos); |
| 4516 function_literal->set_ast_properties(&ast_properties); | 4519 function_literal->set_ast_properties(&ast_properties); |
| 4517 function_literal->set_dont_optimize_reason(dont_optimize_reason); | 4520 function_literal->set_dont_optimize_reason(dont_optimize_reason); |
| 4518 | 4521 |
| 4519 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal); | 4522 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal); |
| 4520 return function_literal; | 4523 return function_literal; |
| 4521 } | 4524 } |
| 4522 | 4525 |
| 4523 | 4526 |
| 4524 preparser::PreParser::PreParseResult Parser::LazyParseFunctionLiteral( | 4527 PreParser::PreParseResult Parser::LazyParseFunctionLiteral( |
| 4525 SingletonLogger* logger) { | 4528 SingletonLogger* logger) { |
| 4526 HistogramTimerScope preparse_scope(isolate()->counters()->pre_parse()); | 4529 HistogramTimerScope preparse_scope(isolate()->counters()->pre_parse()); |
| 4527 ASSERT_EQ(Token::LBRACE, scanner().current_token()); | 4530 ASSERT_EQ(Token::LBRACE, scanner().current_token()); |
| 4528 | 4531 |
| 4529 if (reusable_preparser_ == NULL) { | 4532 if (reusable_preparser_ == NULL) { |
| 4530 intptr_t stack_limit = isolate()->stack_guard()->real_climit(); | 4533 intptr_t stack_limit = isolate()->stack_guard()->real_climit(); |
| 4531 reusable_preparser_ = new preparser::PreParser(&scanner_, | 4534 reusable_preparser_ = new PreParser(&scanner_, NULL, stack_limit); |
| 4532 NULL, | |
| 4533 stack_limit); | |
| 4534 reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping()); | 4535 reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping()); |
| 4535 reusable_preparser_->set_allow_modules(allow_modules()); | 4536 reusable_preparser_->set_allow_modules(allow_modules()); |
| 4536 reusable_preparser_->set_allow_natives_syntax(allow_natives_syntax()); | 4537 reusable_preparser_->set_allow_natives_syntax(allow_natives_syntax()); |
| 4537 reusable_preparser_->set_allow_lazy(true); | 4538 reusable_preparser_->set_allow_lazy(true); |
| 4538 reusable_preparser_->set_allow_generators(allow_generators()); | 4539 reusable_preparser_->set_allow_generators(allow_generators()); |
| 4539 reusable_preparser_->set_allow_for_of(allow_for_of()); | 4540 reusable_preparser_->set_allow_for_of(allow_for_of()); |
| 4540 reusable_preparser_->set_allow_harmony_numeric_literals( | 4541 reusable_preparser_->set_allow_harmony_numeric_literals( |
| 4541 allow_harmony_numeric_literals()); | 4542 allow_harmony_numeric_literals()); |
| 4542 } | 4543 } |
| 4543 preparser::PreParser::PreParseResult result = | 4544 PreParser::PreParseResult result = |
| 4544 reusable_preparser_->PreParseLazyFunction(top_scope_->language_mode(), | 4545 reusable_preparser_->PreParseLazyFunction(top_scope_->language_mode(), |
| 4545 is_generator(), | 4546 is_generator(), |
| 4546 logger); | 4547 logger); |
| 4547 return result; | 4548 return result; |
| 4548 } | 4549 } |
| 4549 | 4550 |
| 4550 | 4551 |
| 4551 Expression* Parser::ParseV8Intrinsic(bool* ok) { | 4552 Expression* Parser::ParseV8Intrinsic(bool* ok) { |
| 4552 // CallRuntime :: | 4553 // CallRuntime :: |
| 4553 // '%' Identifier Arguments | 4554 // '%' Identifier Arguments |
| 4554 | 4555 |
| 4556 int pos = peek_position(); |
| 4555 Expect(Token::MOD, CHECK_OK); | 4557 Expect(Token::MOD, CHECK_OK); |
| 4556 Handle<String> name = ParseIdentifier(CHECK_OK); | 4558 Handle<String> name = ParseIdentifier(CHECK_OK); |
| 4557 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); | 4559 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); |
| 4558 | 4560 |
| 4559 if (extension_ != NULL) { | 4561 if (extension_ != NULL) { |
| 4560 // The extension structures are only accessible while parsing the | 4562 // The extension structures are only accessible while parsing the |
| 4561 // very first time not when reparsing because of lazy compilation. | 4563 // very first time not when reparsing because of lazy compilation. |
| 4562 top_scope_->DeclarationScope()->ForceEagerCompilation(); | 4564 top_scope_->DeclarationScope()->ForceEagerCompilation(); |
| 4563 } | 4565 } |
| 4564 | 4566 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 4590 } | 4592 } |
| 4591 | 4593 |
| 4592 // Check that the function is defined if it's an inline runtime call. | 4594 // Check that the function is defined if it's an inline runtime call. |
| 4593 if (function == NULL && name->Get(0) == '_') { | 4595 if (function == NULL && name->Get(0) == '_') { |
| 4594 ReportMessage("not_defined", Vector<Handle<String> >(&name, 1)); | 4596 ReportMessage("not_defined", Vector<Handle<String> >(&name, 1)); |
| 4595 *ok = false; | 4597 *ok = false; |
| 4596 return NULL; | 4598 return NULL; |
| 4597 } | 4599 } |
| 4598 | 4600 |
| 4599 // We have a valid intrinsics call or a call to a builtin. | 4601 // We have a valid intrinsics call or a call to a builtin. |
| 4600 return factory()->NewCallRuntime(name, function, args); | 4602 return factory()->NewCallRuntime(name, function, args, pos); |
| 4601 } | 4603 } |
| 4602 | 4604 |
| 4603 | 4605 |
| 4604 bool Parser::peek_any_identifier() { | 4606 bool ParserBase::peek_any_identifier() { |
| 4605 Token::Value next = peek(); | 4607 Token::Value next = peek(); |
| 4606 return next == Token::IDENTIFIER || | 4608 return next == Token::IDENTIFIER || |
| 4607 next == Token::FUTURE_RESERVED_WORD || | 4609 next == Token::FUTURE_RESERVED_WORD || |
| 4608 next == Token::FUTURE_STRICT_RESERVED_WORD || | 4610 next == Token::FUTURE_STRICT_RESERVED_WORD || |
| 4609 next == Token::YIELD; | 4611 next == Token::YIELD; |
| 4610 } | 4612 } |
| 4611 | 4613 |
| 4612 | 4614 |
| 4613 void Parser::Consume(Token::Value token) { | 4615 bool ParserBase::CheckContextualKeyword(Vector<const char> keyword) { |
| 4614 Token::Value next = Next(); | |
| 4615 USE(next); | |
| 4616 USE(token); | |
| 4617 ASSERT(next == token); | |
| 4618 } | |
| 4619 | |
| 4620 | |
| 4621 void Parser::Expect(Token::Value token, bool* ok) { | |
| 4622 Token::Value next = Next(); | |
| 4623 if (next == token) return; | |
| 4624 ReportUnexpectedToken(next); | |
| 4625 *ok = false; | |
| 4626 } | |
| 4627 | |
| 4628 | |
| 4629 bool Parser::Check(Token::Value token) { | |
| 4630 Token::Value next = peek(); | |
| 4631 if (next == token) { | |
| 4632 Consume(next); | |
| 4633 return true; | |
| 4634 } | |
| 4635 return false; | |
| 4636 } | |
| 4637 | |
| 4638 | |
| 4639 bool Parser::CheckContextualKeyword(Vector<const char> keyword) { | |
| 4640 if (peek() == Token::IDENTIFIER && | 4616 if (peek() == Token::IDENTIFIER && |
| 4641 scanner().is_next_contextual_keyword(keyword)) { | 4617 scanner()->is_next_contextual_keyword(keyword)) { |
| 4642 Consume(Token::IDENTIFIER); | 4618 Consume(Token::IDENTIFIER); |
| 4643 return true; | 4619 return true; |
| 4644 } | 4620 } |
| 4645 return false; | 4621 return false; |
| 4646 } | 4622 } |
| 4647 | 4623 |
| 4648 | 4624 |
| 4649 void Parser::ExpectSemicolon(bool* ok) { | 4625 void ParserBase::ExpectSemicolon(bool* ok) { |
| 4650 // Check for automatic semicolon insertion according to | 4626 // Check for automatic semicolon insertion according to |
| 4651 // the rules given in ECMA-262, section 7.9, page 21. | 4627 // the rules given in ECMA-262, section 7.9, page 21. |
| 4652 Token::Value tok = peek(); | 4628 Token::Value tok = peek(); |
| 4653 if (tok == Token::SEMICOLON) { | 4629 if (tok == Token::SEMICOLON) { |
| 4654 Next(); | 4630 Next(); |
| 4655 return; | 4631 return; |
| 4656 } | 4632 } |
| 4657 if (scanner().HasAnyLineTerminatorBeforeNext() || | 4633 if (scanner()->HasAnyLineTerminatorBeforeNext() || |
| 4658 tok == Token::RBRACE || | 4634 tok == Token::RBRACE || |
| 4659 tok == Token::EOS) { | 4635 tok == Token::EOS) { |
| 4660 return; | 4636 return; |
| 4661 } | 4637 } |
| 4662 Expect(Token::SEMICOLON, ok); | 4638 Expect(Token::SEMICOLON, ok); |
| 4663 } | 4639 } |
| 4664 | 4640 |
| 4665 | 4641 |
| 4666 void Parser::ExpectContextualKeyword(Vector<const char> keyword, bool* ok) { | 4642 void ParserBase::ExpectContextualKeyword(Vector<const char> keyword, bool* ok) { |
| 4667 Expect(Token::IDENTIFIER, ok); | 4643 Expect(Token::IDENTIFIER, ok); |
| 4668 if (!*ok) return; | 4644 if (!*ok) return; |
| 4669 if (!scanner().is_literal_contextual_keyword(keyword)) { | 4645 if (!scanner()->is_literal_contextual_keyword(keyword)) { |
| 4646 ReportUnexpectedToken(scanner()->current_token()); |
| 4670 *ok = false; | 4647 *ok = false; |
| 4671 ReportUnexpectedToken(scanner().current_token()); | |
| 4672 } | 4648 } |
| 4673 } | 4649 } |
| 4674 | 4650 |
| 4675 | 4651 |
| 4676 Literal* Parser::GetLiteralUndefined() { | 4652 Literal* Parser::GetLiteralUndefined(int position) { |
| 4677 return factory()->NewLiteral(isolate()->factory()->undefined_value()); | 4653 return factory()->NewLiteral( |
| 4654 isolate()->factory()->undefined_value(), position); |
| 4678 } | 4655 } |
| 4679 | 4656 |
| 4680 | 4657 |
| 4681 Literal* Parser::GetLiteralTheHole() { | 4658 Literal* Parser::GetLiteralTheHole(int position) { |
| 4682 return factory()->NewLiteral(isolate()->factory()->the_hole_value()); | 4659 return factory()->NewLiteral( |
| 4660 isolate()->factory()->the_hole_value(), RelocInfo::kNoPosition); |
| 4683 } | 4661 } |
| 4684 | 4662 |
| 4685 | 4663 |
| 4686 // Parses an identifier that is valid for the current scope, in particular it | 4664 // Parses an identifier that is valid for the current scope, in particular it |
| 4687 // fails on strict mode future reserved keywords in a strict scope. | 4665 // fails on strict mode future reserved keywords in a strict scope. |
| 4688 Handle<String> Parser::ParseIdentifier(bool* ok) { | 4666 Handle<String> Parser::ParseIdentifier(bool* ok) { |
| 4689 Token::Value next = Next(); | 4667 Token::Value next = Next(); |
| 4690 if (next == Token::IDENTIFIER || | 4668 if (next == Token::IDENTIFIER || |
| 4691 (top_scope_->is_classic_mode() && | 4669 (top_scope_->is_classic_mode() && |
| 4692 (next == Token::FUTURE_STRICT_RESERVED_WORD || | 4670 (next == Token::FUTURE_STRICT_RESERVED_WORD || |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4754 | 4732 |
| 4755 if (lhs != NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) { | 4733 if (lhs != NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) { |
| 4756 ReportMessage(error, Vector<const char*>::empty()); | 4734 ReportMessage(error, Vector<const char*>::empty()); |
| 4757 *ok = false; | 4735 *ok = false; |
| 4758 } | 4736 } |
| 4759 } | 4737 } |
| 4760 | 4738 |
| 4761 | 4739 |
| 4762 // Checks whether an octal literal was last seen between beg_pos and end_pos. | 4740 // Checks whether an octal literal was last seen between beg_pos and end_pos. |
| 4763 // If so, reports an error. Only called for strict mode. | 4741 // If so, reports an error. Only called for strict mode. |
| 4764 void Parser::CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) { | 4742 void ParserBase::CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) { |
| 4765 Scanner::Location octal = scanner().octal_position(); | 4743 Scanner::Location octal = scanner()->octal_position(); |
| 4766 if (octal.IsValid() && | 4744 if (octal.IsValid() && beg_pos <= octal.beg_pos && octal.end_pos <= end_pos) { |
| 4767 beg_pos <= octal.beg_pos && | 4745 ReportMessageAt(octal, "strict_octal_literal"); |
| 4768 octal.end_pos <= end_pos) { | 4746 scanner()->clear_octal_position(); |
| 4769 ReportMessageAt(octal, "strict_octal_literal", | |
| 4770 Vector<const char*>::empty()); | |
| 4771 scanner().clear_octal_position(); | |
| 4772 *ok = false; | 4747 *ok = false; |
| 4773 } | 4748 } |
| 4774 } | 4749 } |
| 4775 | 4750 |
| 4776 | 4751 |
| 4777 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) { | 4752 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) { |
| 4778 Declaration* decl = scope->CheckConflictingVarDeclarations(); | 4753 Declaration* decl = scope->CheckConflictingVarDeclarations(); |
| 4779 if (decl != NULL) { | 4754 if (decl != NULL) { |
| 4780 // In harmony mode we treat conflicting variable bindinds as early | 4755 // In harmony mode we treat conflicting variable bindinds as early |
| 4781 // errors. See ES5 16 for a definition of early errors. | 4756 // errors. See ES5 16 for a definition of early errors. |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4901 TENURED); | 4876 TENURED); |
| 4902 for (int i = 0; i < argc; i++) { | 4877 for (int i = 0; i < argc; i++) { |
| 4903 Handle<Object> element = arguments[i]; | 4878 Handle<Object> element = arguments[i]; |
| 4904 if (!element.is_null()) { | 4879 if (!element.is_null()) { |
| 4905 elements->set(i, *element); | 4880 elements->set(i, *element); |
| 4906 } | 4881 } |
| 4907 } | 4882 } |
| 4908 Handle<JSArray> array = isolate()->factory()->NewJSArrayWithElements( | 4883 Handle<JSArray> array = isolate()->factory()->NewJSArrayWithElements( |
| 4909 elements, FAST_ELEMENTS, TENURED); | 4884 elements, FAST_ELEMENTS, TENURED); |
| 4910 | 4885 |
| 4886 int pos = position(); |
| 4911 ZoneList<Expression*>* args = new(zone()) ZoneList<Expression*>(2, zone()); | 4887 ZoneList<Expression*>* args = new(zone()) ZoneList<Expression*>(2, zone()); |
| 4912 args->Add(factory()->NewLiteral(message), zone()); | 4888 args->Add(factory()->NewLiteral(message, pos), zone()); |
| 4913 args->Add(factory()->NewLiteral(array), zone()); | 4889 args->Add(factory()->NewLiteral(array, pos), zone()); |
| 4914 CallRuntime* call_constructor = | 4890 CallRuntime* call_constructor = |
| 4915 factory()->NewCallRuntime(constructor, NULL, args); | 4891 factory()->NewCallRuntime(constructor, NULL, args, pos); |
| 4916 return factory()->NewThrow(call_constructor, scanner().location().beg_pos); | 4892 return factory()->NewThrow(call_constructor, pos); |
| 4917 } | 4893 } |
| 4918 | 4894 |
| 4919 | 4895 |
| 4920 // ---------------------------------------------------------------------------- | 4896 // ---------------------------------------------------------------------------- |
| 4921 // Regular expressions | 4897 // Regular expressions |
| 4922 | 4898 |
| 4923 | 4899 |
| 4924 RegExpParser::RegExpParser(FlatStringReader* in, | 4900 RegExpParser::RegExpParser(FlatStringReader* in, |
| 4925 Handle<String>* error, | 4901 Handle<String>* error, |
| 4926 bool multiline, | 4902 bool multiline, |
| (...skipping 869 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5796 } | 5772 } |
| 5797 | 5773 |
| 5798 | 5774 |
| 5799 // Create a Scanner for the preparser to use as input, and preparse the source. | 5775 // Create a Scanner for the preparser to use as input, and preparse the source. |
| 5800 ScriptDataImpl* PreParserApi::PreParse(Isolate* isolate, | 5776 ScriptDataImpl* PreParserApi::PreParse(Isolate* isolate, |
| 5801 Utf16CharacterStream* source) { | 5777 Utf16CharacterStream* source) { |
| 5802 CompleteParserRecorder recorder; | 5778 CompleteParserRecorder recorder; |
| 5803 HistogramTimerScope timer(isolate->counters()->pre_parse()); | 5779 HistogramTimerScope timer(isolate->counters()->pre_parse()); |
| 5804 Scanner scanner(isolate->unicode_cache()); | 5780 Scanner scanner(isolate->unicode_cache()); |
| 5805 intptr_t stack_limit = isolate->stack_guard()->real_climit(); | 5781 intptr_t stack_limit = isolate->stack_guard()->real_climit(); |
| 5806 preparser::PreParser preparser(&scanner, &recorder, stack_limit); | 5782 PreParser preparser(&scanner, &recorder, stack_limit); |
| 5807 preparser.set_allow_lazy(true); | 5783 preparser.set_allow_lazy(true); |
| 5808 preparser.set_allow_generators(FLAG_harmony_generators); | 5784 preparser.set_allow_generators(FLAG_harmony_generators); |
| 5809 preparser.set_allow_for_of(FLAG_harmony_iteration); | 5785 preparser.set_allow_for_of(FLAG_harmony_iteration); |
| 5810 preparser.set_allow_harmony_scoping(FLAG_harmony_scoping); | 5786 preparser.set_allow_harmony_scoping(FLAG_harmony_scoping); |
| 5811 preparser.set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals); | 5787 preparser.set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals); |
| 5812 scanner.Initialize(source); | 5788 scanner.Initialize(source); |
| 5813 preparser::PreParser::PreParseResult result = preparser.PreParseProgram(); | 5789 PreParser::PreParseResult result = preparser.PreParseProgram(); |
| 5814 if (result == preparser::PreParser::kPreParseStackOverflow) { | 5790 if (result == PreParser::kPreParseStackOverflow) { |
| 5815 isolate->StackOverflow(); | 5791 isolate->StackOverflow(); |
| 5816 return NULL; | 5792 return NULL; |
| 5817 } | 5793 } |
| 5818 | 5794 |
| 5819 // Extract the accumulated data from the recorder as a single | 5795 // Extract the accumulated data from the recorder as a single |
| 5820 // contiguous vector that we are responsible for disposing. | 5796 // contiguous vector that we are responsible for disposing. |
| 5821 Vector<unsigned> store = recorder.ExtractData(); | 5797 Vector<unsigned> store = recorder.ExtractData(); |
| 5822 return new ScriptDataImpl(store); | 5798 return new ScriptDataImpl(store); |
| 5823 } | 5799 } |
| 5824 | 5800 |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5872 ASSERT(info()->isolate()->has_pending_exception()); | 5848 ASSERT(info()->isolate()->has_pending_exception()); |
| 5873 } else { | 5849 } else { |
| 5874 result = ParseProgram(); | 5850 result = ParseProgram(); |
| 5875 } | 5851 } |
| 5876 } | 5852 } |
| 5877 info()->SetFunction(result); | 5853 info()->SetFunction(result); |
| 5878 return (result != NULL); | 5854 return (result != NULL); |
| 5879 } | 5855 } |
| 5880 | 5856 |
| 5881 } } // namespace v8::internal | 5857 } } // namespace v8::internal |
| OLD | NEW |