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 634 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
645 mode = PARSE_EAGERLY; | 645 mode = PARSE_EAGERLY; |
646 } | 646 } |
647 ParsingModeScope parsing_mode(this, mode); | 647 ParsingModeScope parsing_mode(this, mode); |
648 | 648 |
649 // Enters 'scope'. | 649 // Enters 'scope'. |
650 FunctionState function_state(this, scope, isolate()); | 650 FunctionState function_state(this, scope, isolate()); |
651 | 651 |
652 top_scope_->SetLanguageMode(info->language_mode()); | 652 top_scope_->SetLanguageMode(info->language_mode()); |
653 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); | 653 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); |
654 bool ok = true; | 654 bool ok = true; |
655 int beg_loc = scanner().location().beg_pos; | 655 int beg_pos = scanner().location().beg_pos; |
Yang
2013/09/24 16:04:16
you could just use position() here, right?
| |
656 ParseSourceElements(body, Token::EOS, info->is_eval(), true, &ok); | 656 ParseSourceElements(body, Token::EOS, info->is_eval(), true, &ok); |
657 if (ok && !top_scope_->is_classic_mode()) { | 657 if (ok && !top_scope_->is_classic_mode()) { |
658 CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok); | 658 CheckOctalLiteral(beg_pos, scanner().location().end_pos, &ok); |
659 } | 659 } |
660 | 660 |
661 if (ok && is_extended_mode()) { | 661 if (ok && is_extended_mode()) { |
662 CheckConflictingVarDeclarations(top_scope_, &ok); | 662 CheckConflictingVarDeclarations(top_scope_, &ok); |
663 } | 663 } |
664 | 664 |
665 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) { | 665 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) { |
666 if (body->length() != 1 || | 666 if (body->length() != 1 || |
667 !body->at(0)->IsExpressionStatement() || | 667 !body->at(0)->IsExpressionStatement() || |
668 !body->at(0)->AsExpressionStatement()-> | 668 !body->at(0)->AsExpressionStatement()-> |
669 expression()->IsFunctionLiteral()) { | 669 expression()->IsFunctionLiteral()) { |
670 ReportMessage("single_function_literal", Vector<const char*>::empty()); | 670 ReportMessage("single_function_literal", Vector<const char*>::empty()); |
671 ok = false; | 671 ok = false; |
672 } | 672 } |
673 } | 673 } |
674 | 674 |
675 if (ok) { | 675 if (ok) { |
676 result = factory()->NewFunctionLiteral( | 676 result = factory()->NewFunctionLiteral( |
677 no_name, | 677 no_name, |
678 top_scope_, | 678 top_scope_, |
679 body, | 679 body, |
680 function_state.materialized_literal_count(), | 680 function_state.materialized_literal_count(), |
681 function_state.expected_property_count(), | 681 function_state.expected_property_count(), |
682 function_state.handler_count(), | 682 function_state.handler_count(), |
683 0, | 683 0, |
684 FunctionLiteral::kNoDuplicateParameters, | 684 FunctionLiteral::kNoDuplicateParameters, |
685 FunctionLiteral::ANONYMOUS_EXPRESSION, | 685 FunctionLiteral::ANONYMOUS_EXPRESSION, |
686 FunctionLiteral::kGlobalOrEval, | 686 FunctionLiteral::kGlobalOrEval, |
687 FunctionLiteral::kNotParenthesized, | 687 FunctionLiteral::kNotParenthesized, |
688 FunctionLiteral::kNotGenerator); | 688 FunctionLiteral::kNotGenerator, |
689 0); | |
689 result->set_ast_properties(factory()->visitor()->ast_properties()); | 690 result->set_ast_properties(factory()->visitor()->ast_properties()); |
690 result->set_dont_optimize_reason( | 691 result->set_dont_optimize_reason( |
691 factory()->visitor()->dont_optimize_reason()); | 692 factory()->visitor()->dont_optimize_reason()); |
692 } else if (stack_overflow_) { | 693 } else if (stack_overflow_) { |
693 isolate()->StackOverflow(); | 694 isolate()->StackOverflow(); |
694 } | 695 } |
695 } | 696 } |
696 | 697 |
697 // Make sure the target stack is empty. | 698 // Make sure the target stack is empty. |
698 ASSERT(target_stack_ == NULL); | 699 ASSERT(target_stack_ == NULL); |
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
977 return stmt; | 978 return stmt; |
978 } | 979 } |
979 } | 980 } |
980 } | 981 } |
981 | 982 |
982 | 983 |
983 Statement* Parser::ParseModuleDeclaration(ZoneStringList* names, bool* ok) { | 984 Statement* Parser::ParseModuleDeclaration(ZoneStringList* names, bool* ok) { |
984 // ModuleDeclaration: | 985 // ModuleDeclaration: |
985 // 'module' Identifier Module | 986 // 'module' Identifier Module |
986 | 987 |
988 int pos = peek_position(); | |
987 Handle<String> name = ParseIdentifier(CHECK_OK); | 989 Handle<String> name = ParseIdentifier(CHECK_OK); |
988 | 990 |
989 #ifdef DEBUG | 991 #ifdef DEBUG |
990 if (FLAG_print_interface_details) | 992 if (FLAG_print_interface_details) |
991 PrintF("# Module %s...\n", name->ToAsciiArray()); | 993 PrintF("# Module %s...\n", name->ToAsciiArray()); |
992 #endif | 994 #endif |
993 | 995 |
994 Module* module = ParseModule(CHECK_OK); | 996 Module* module = ParseModule(CHECK_OK); |
995 VariableProxy* proxy = NewUnresolved(name, MODULE, module->interface()); | 997 VariableProxy* proxy = NewUnresolved(name, MODULE, module->interface()); |
996 Declaration* declaration = | 998 Declaration* declaration = |
997 factory()->NewModuleDeclaration(proxy, module, top_scope_); | 999 factory()->NewModuleDeclaration(proxy, module, top_scope_, pos); |
998 Declare(declaration, true, CHECK_OK); | 1000 Declare(declaration, true, CHECK_OK); |
999 | 1001 |
1000 #ifdef DEBUG | 1002 #ifdef DEBUG |
1001 if (FLAG_print_interface_details) | 1003 if (FLAG_print_interface_details) |
1002 PrintF("# Module %s.\n", name->ToAsciiArray()); | 1004 PrintF("# Module %s.\n", name->ToAsciiArray()); |
1003 | 1005 |
1004 if (FLAG_print_interfaces) { | 1006 if (FLAG_print_interfaces) { |
1005 PrintF("module %s : ", name->ToAsciiArray()); | 1007 PrintF("module %s : ", name->ToAsciiArray()); |
1006 module->interface()->Print(); | 1008 module->interface()->Print(); |
1007 } | 1009 } |
1008 #endif | 1010 #endif |
1009 | 1011 |
1010 if (names) names->Add(name, zone()); | 1012 if (names) names->Add(name, zone()); |
1011 if (module->body() == NULL) | 1013 if (module->body() == NULL) |
1012 return factory()->NewEmptyStatement(); | 1014 return factory()->NewEmptyStatement(pos); |
1013 else | 1015 else |
1014 return factory()->NewModuleStatement(proxy, module->body()); | 1016 return factory()->NewModuleStatement(proxy, module->body(), pos); |
1015 } | 1017 } |
1016 | 1018 |
1017 | 1019 |
1018 Module* Parser::ParseModule(bool* ok) { | 1020 Module* Parser::ParseModule(bool* ok) { |
1019 // Module: | 1021 // Module: |
1020 // '{' ModuleElement '}' | 1022 // '{' ModuleElement '}' |
1021 // '=' ModulePath ';' | 1023 // '=' ModulePath ';' |
1022 // 'at' String ';' | 1024 // 'at' String ';' |
1023 | 1025 |
1024 switch (peek()) { | 1026 switch (peek()) { |
(...skipping 14 matching lines...) Expand all Loading... | |
1039 return result; | 1041 return result; |
1040 } | 1042 } |
1041 } | 1043 } |
1042 } | 1044 } |
1043 | 1045 |
1044 | 1046 |
1045 Module* Parser::ParseModuleLiteral(bool* ok) { | 1047 Module* Parser::ParseModuleLiteral(bool* ok) { |
1046 // Module: | 1048 // Module: |
1047 // '{' ModuleElement '}' | 1049 // '{' ModuleElement '}' |
1048 | 1050 |
1051 int pos = peek_position(); | |
1049 // Construct block expecting 16 statements. | 1052 // Construct block expecting 16 statements. |
1050 Block* body = factory()->NewBlock(NULL, 16, false); | 1053 Block* body = factory()->NewBlock(NULL, 16, false, RelocInfo::kNoPosition); |
1051 #ifdef DEBUG | 1054 #ifdef DEBUG |
1052 if (FLAG_print_interface_details) PrintF("# Literal "); | 1055 if (FLAG_print_interface_details) PrintF("# Literal "); |
1053 #endif | 1056 #endif |
1054 Scope* scope = NewScope(top_scope_, MODULE_SCOPE); | 1057 Scope* scope = NewScope(top_scope_, MODULE_SCOPE); |
1055 | 1058 |
1056 Expect(Token::LBRACE, CHECK_OK); | 1059 Expect(Token::LBRACE, CHECK_OK); |
1057 scope->set_start_position(scanner().location().beg_pos); | 1060 scope->set_start_position(scanner().location().beg_pos); |
1058 scope->SetLanguageMode(EXTENDED_MODE); | 1061 scope->SetLanguageMode(EXTENDED_MODE); |
1059 | 1062 |
1060 { | 1063 { |
(...skipping 24 matching lines...) Expand all Loading... | |
1085 Vector<Handle<String> >(&name, 1)); | 1088 Vector<Handle<String> >(&name, 1)); |
1086 *ok = false; | 1089 *ok = false; |
1087 return NULL; | 1090 return NULL; |
1088 } | 1091 } |
1089 } | 1092 } |
1090 | 1093 |
1091 interface->MakeModule(ok); | 1094 interface->MakeModule(ok); |
1092 ASSERT(*ok); | 1095 ASSERT(*ok); |
1093 interface->Freeze(ok); | 1096 interface->Freeze(ok); |
1094 ASSERT(*ok); | 1097 ASSERT(*ok); |
1095 return factory()->NewModuleLiteral(body, interface); | 1098 return factory()->NewModuleLiteral(body, interface, pos); |
1096 } | 1099 } |
1097 | 1100 |
1098 | 1101 |
1099 Module* Parser::ParseModulePath(bool* ok) { | 1102 Module* Parser::ParseModulePath(bool* ok) { |
1100 // ModulePath: | 1103 // ModulePath: |
1101 // Identifier | 1104 // Identifier |
1102 // ModulePath '.' Identifier | 1105 // ModulePath '.' Identifier |
1103 | 1106 |
1107 int pos = peek_position(); | |
1104 Module* result = ParseModuleVariable(CHECK_OK); | 1108 Module* result = ParseModuleVariable(CHECK_OK); |
1105 while (Check(Token::PERIOD)) { | 1109 while (Check(Token::PERIOD)) { |
1106 Handle<String> name = ParseIdentifierName(CHECK_OK); | 1110 Handle<String> name = ParseIdentifierName(CHECK_OK); |
1107 #ifdef DEBUG | 1111 #ifdef DEBUG |
1108 if (FLAG_print_interface_details) | 1112 if (FLAG_print_interface_details) |
1109 PrintF("# Path .%s ", name->ToAsciiArray()); | 1113 PrintF("# Path .%s ", name->ToAsciiArray()); |
1110 #endif | 1114 #endif |
1111 Module* member = factory()->NewModulePath(result, name); | 1115 Module* member = factory()->NewModulePath(result, name, pos); |
1112 result->interface()->Add(name, member->interface(), zone(), ok); | 1116 result->interface()->Add(name, member->interface(), zone(), ok); |
1113 if (!*ok) { | 1117 if (!*ok) { |
1114 #ifdef DEBUG | 1118 #ifdef DEBUG |
1115 if (FLAG_print_interfaces) { | 1119 if (FLAG_print_interfaces) { |
1116 PrintF("PATH TYPE ERROR at '%s'\n", name->ToAsciiArray()); | 1120 PrintF("PATH TYPE ERROR at '%s'\n", name->ToAsciiArray()); |
1117 PrintF("result: "); | 1121 PrintF("result: "); |
1118 result->interface()->Print(); | 1122 result->interface()->Print(); |
1119 PrintF("member: "); | 1123 PrintF("member: "); |
1120 member->interface()->Print(); | 1124 member->interface()->Print(); |
1121 } | 1125 } |
1122 #endif | 1126 #endif |
1123 ReportMessage("invalid_module_path", Vector<Handle<String> >(&name, 1)); | 1127 ReportMessage("invalid_module_path", Vector<Handle<String> >(&name, 1)); |
1124 return NULL; | 1128 return NULL; |
1125 } | 1129 } |
1126 result = member; | 1130 result = member; |
1127 } | 1131 } |
1128 | 1132 |
1129 return result; | 1133 return result; |
1130 } | 1134 } |
1131 | 1135 |
1132 | 1136 |
1133 Module* Parser::ParseModuleVariable(bool* ok) { | 1137 Module* Parser::ParseModuleVariable(bool* ok) { |
1134 // ModulePath: | 1138 // ModulePath: |
1135 // Identifier | 1139 // Identifier |
1136 | 1140 |
1141 int pos = peek_position(); | |
1137 Handle<String> name = ParseIdentifier(CHECK_OK); | 1142 Handle<String> name = ParseIdentifier(CHECK_OK); |
1138 #ifdef DEBUG | 1143 #ifdef DEBUG |
1139 if (FLAG_print_interface_details) | 1144 if (FLAG_print_interface_details) |
1140 PrintF("# Module variable %s ", name->ToAsciiArray()); | 1145 PrintF("# Module variable %s ", name->ToAsciiArray()); |
1141 #endif | 1146 #endif |
1142 VariableProxy* proxy = top_scope_->NewUnresolved( | 1147 VariableProxy* proxy = top_scope_->NewUnresolved( |
1143 factory(), name, Interface::NewModule(zone()), | 1148 factory(), name, Interface::NewModule(zone()), |
1144 scanner().location().beg_pos); | 1149 scanner().location().beg_pos); |
1145 | 1150 |
1146 return factory()->NewModuleVariable(proxy); | 1151 return factory()->NewModuleVariable(proxy, pos); |
1147 } | 1152 } |
1148 | 1153 |
1149 | 1154 |
1150 Module* Parser::ParseModuleUrl(bool* ok) { | 1155 Module* Parser::ParseModuleUrl(bool* ok) { |
1151 // Module: | 1156 // Module: |
1152 // String | 1157 // String |
1153 | 1158 |
1159 int pos = peek_position(); | |
1154 Expect(Token::STRING, CHECK_OK); | 1160 Expect(Token::STRING, CHECK_OK); |
1155 Handle<String> symbol = GetSymbol(); | 1161 Handle<String> symbol = GetSymbol(); |
1156 | 1162 |
1157 // TODO(ES6): Request JS resource from environment... | 1163 // TODO(ES6): Request JS resource from environment... |
1158 | 1164 |
1159 #ifdef DEBUG | 1165 #ifdef DEBUG |
1160 if (FLAG_print_interface_details) PrintF("# Url "); | 1166 if (FLAG_print_interface_details) PrintF("# Url "); |
1161 #endif | 1167 #endif |
1162 | 1168 |
1163 // Create an empty literal as long as the feature isn't finished. | 1169 // Create an empty literal as long as the feature isn't finished. |
1164 USE(symbol); | 1170 USE(symbol); |
1165 Scope* scope = NewScope(top_scope_, MODULE_SCOPE); | 1171 Scope* scope = NewScope(top_scope_, MODULE_SCOPE); |
1166 Block* body = factory()->NewBlock(NULL, 1, false); | 1172 Block* body = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition); |
1167 body->set_scope(scope); | 1173 body->set_scope(scope); |
1168 Interface* interface = scope->interface(); | 1174 Interface* interface = scope->interface(); |
1169 Module* result = factory()->NewModuleLiteral(body, interface); | 1175 Module* result = factory()->NewModuleLiteral(body, interface, pos); |
1170 interface->Freeze(ok); | 1176 interface->Freeze(ok); |
1171 ASSERT(*ok); | 1177 ASSERT(*ok); |
1172 interface->Unify(scope->interface(), zone(), ok); | 1178 interface->Unify(scope->interface(), zone(), ok); |
1173 ASSERT(*ok); | 1179 ASSERT(*ok); |
1174 return result; | 1180 return result; |
1175 } | 1181 } |
1176 | 1182 |
1177 | 1183 |
1178 Module* Parser::ParseModuleSpecifier(bool* ok) { | 1184 Module* Parser::ParseModuleSpecifier(bool* ok) { |
1179 // ModuleSpecifier: | 1185 // ModuleSpecifier: |
1180 // String | 1186 // String |
1181 // ModulePath | 1187 // ModulePath |
1182 | 1188 |
1183 if (peek() == Token::STRING) { | 1189 if (peek() == Token::STRING) { |
1184 return ParseModuleUrl(ok); | 1190 return ParseModuleUrl(ok); |
1185 } else { | 1191 } else { |
1186 return ParseModulePath(ok); | 1192 return ParseModulePath(ok); |
1187 } | 1193 } |
1188 } | 1194 } |
1189 | 1195 |
1190 | 1196 |
1191 Block* Parser::ParseImportDeclaration(bool* ok) { | 1197 Block* Parser::ParseImportDeclaration(bool* ok) { |
1192 // ImportDeclaration: | 1198 // ImportDeclaration: |
1193 // 'import' IdentifierName (',' IdentifierName)* 'from' ModuleSpecifier ';' | 1199 // 'import' IdentifierName (',' IdentifierName)* 'from' ModuleSpecifier ';' |
1194 // | 1200 // |
1195 // TODO(ES6): implement destructuring ImportSpecifiers | 1201 // TODO(ES6): implement destructuring ImportSpecifiers |
1196 | 1202 |
1203 int pos = peek_position(); | |
1197 Expect(Token::IMPORT, CHECK_OK); | 1204 Expect(Token::IMPORT, CHECK_OK); |
1198 ZoneStringList names(1, zone()); | 1205 ZoneStringList names(1, zone()); |
1199 | 1206 |
1200 Handle<String> name = ParseIdentifierName(CHECK_OK); | 1207 Handle<String> name = ParseIdentifierName(CHECK_OK); |
1201 names.Add(name, zone()); | 1208 names.Add(name, zone()); |
1202 while (peek() == Token::COMMA) { | 1209 while (peek() == Token::COMMA) { |
1203 Consume(Token::COMMA); | 1210 Consume(Token::COMMA); |
1204 name = ParseIdentifierName(CHECK_OK); | 1211 name = ParseIdentifierName(CHECK_OK); |
1205 names.Add(name, zone()); | 1212 names.Add(name, zone()); |
1206 } | 1213 } |
1207 | 1214 |
1208 ExpectContextualKeyword(CStrVector("from"), CHECK_OK); | 1215 ExpectContextualKeyword(CStrVector("from"), CHECK_OK); |
1209 Module* module = ParseModuleSpecifier(CHECK_OK); | 1216 Module* module = ParseModuleSpecifier(CHECK_OK); |
1210 ExpectSemicolon(CHECK_OK); | 1217 ExpectSemicolon(CHECK_OK); |
1211 | 1218 |
1212 // Generate a separate declaration for each identifier. | 1219 // Generate a separate declaration for each identifier. |
1213 // TODO(ES6): once we implement destructuring, make that one declaration. | 1220 // TODO(ES6): once we implement destructuring, make that one declaration. |
1214 Block* block = factory()->NewBlock(NULL, 1, true); | 1221 Block* block = factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition); |
1215 for (int i = 0; i < names.length(); ++i) { | 1222 for (int i = 0; i < names.length(); ++i) { |
1216 #ifdef DEBUG | 1223 #ifdef DEBUG |
1217 if (FLAG_print_interface_details) | 1224 if (FLAG_print_interface_details) |
1218 PrintF("# Import %s ", names[i]->ToAsciiArray()); | 1225 PrintF("# Import %s ", names[i]->ToAsciiArray()); |
1219 #endif | 1226 #endif |
1220 Interface* interface = Interface::NewUnknown(zone()); | 1227 Interface* interface = Interface::NewUnknown(zone()); |
1221 module->interface()->Add(names[i], interface, zone(), ok); | 1228 module->interface()->Add(names[i], interface, zone(), ok); |
1222 if (!*ok) { | 1229 if (!*ok) { |
1223 #ifdef DEBUG | 1230 #ifdef DEBUG |
1224 if (FLAG_print_interfaces) { | 1231 if (FLAG_print_interfaces) { |
1225 PrintF("IMPORT TYPE ERROR at '%s'\n", names[i]->ToAsciiArray()); | 1232 PrintF("IMPORT TYPE ERROR at '%s'\n", names[i]->ToAsciiArray()); |
1226 PrintF("module: "); | 1233 PrintF("module: "); |
1227 module->interface()->Print(); | 1234 module->interface()->Print(); |
1228 } | 1235 } |
1229 #endif | 1236 #endif |
1230 ReportMessage("invalid_module_path", Vector<Handle<String> >(&name, 1)); | 1237 ReportMessage("invalid_module_path", Vector<Handle<String> >(&name, 1)); |
1231 return NULL; | 1238 return NULL; |
1232 } | 1239 } |
1233 VariableProxy* proxy = NewUnresolved(names[i], LET, interface); | 1240 VariableProxy* proxy = NewUnresolved(names[i], LET, interface); |
1234 Declaration* declaration = | 1241 Declaration* declaration = |
1235 factory()->NewImportDeclaration(proxy, module, top_scope_); | 1242 factory()->NewImportDeclaration(proxy, module, top_scope_, pos); |
1236 Declare(declaration, true, CHECK_OK); | 1243 Declare(declaration, true, CHECK_OK); |
1237 } | 1244 } |
1238 | 1245 |
1239 return block; | 1246 return block; |
1240 } | 1247 } |
1241 | 1248 |
1242 | 1249 |
1243 Statement* Parser::ParseExportDeclaration(bool* ok) { | 1250 Statement* Parser::ParseExportDeclaration(bool* ok) { |
1244 // ExportDeclaration: | 1251 // ExportDeclaration: |
1245 // 'export' Identifier (',' Identifier)* ';' | 1252 // 'export' Identifier (',' Identifier)* ';' |
1246 // 'export' VariableDeclaration | 1253 // 'export' VariableDeclaration |
1247 // 'export' FunctionDeclaration | 1254 // 'export' FunctionDeclaration |
1248 // 'export' GeneratorDeclaration | 1255 // 'export' GeneratorDeclaration |
1249 // 'export' ModuleDeclaration | 1256 // 'export' ModuleDeclaration |
1250 // | 1257 // |
1251 // TODO(ES6): implement structuring ExportSpecifiers | 1258 // TODO(ES6): implement structuring ExportSpecifiers |
1252 | 1259 |
1253 Expect(Token::EXPORT, CHECK_OK); | 1260 Expect(Token::EXPORT, CHECK_OK); |
1254 | 1261 |
1255 Statement* result = NULL; | 1262 Statement* result = NULL; |
1256 ZoneStringList names(1, zone()); | 1263 ZoneStringList names(1, zone()); |
1257 switch (peek()) { | 1264 switch (peek()) { |
1258 case Token::IDENTIFIER: { | 1265 case Token::IDENTIFIER: { |
1266 int pos = position(); | |
1259 Handle<String> name = ParseIdentifier(CHECK_OK); | 1267 Handle<String> name = ParseIdentifier(CHECK_OK); |
1260 // Handle 'module' as a context-sensitive keyword. | 1268 // Handle 'module' as a context-sensitive keyword. |
1261 if (!name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("module"))) { | 1269 if (!name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("module"))) { |
1262 names.Add(name, zone()); | 1270 names.Add(name, zone()); |
1263 while (peek() == Token::COMMA) { | 1271 while (peek() == Token::COMMA) { |
1264 Consume(Token::COMMA); | 1272 Consume(Token::COMMA); |
1265 name = ParseIdentifier(CHECK_OK); | 1273 name = ParseIdentifier(CHECK_OK); |
1266 names.Add(name, zone()); | 1274 names.Add(name, zone()); |
1267 } | 1275 } |
1268 ExpectSemicolon(CHECK_OK); | 1276 ExpectSemicolon(CHECK_OK); |
1269 result = factory()->NewEmptyStatement(); | 1277 result = factory()->NewEmptyStatement(pos); |
1270 } else { | 1278 } else { |
1271 result = ParseModuleDeclaration(&names, CHECK_OK); | 1279 result = ParseModuleDeclaration(&names, CHECK_OK); |
1272 } | 1280 } |
1273 break; | 1281 break; |
1274 } | 1282 } |
1275 | 1283 |
1276 case Token::FUNCTION: | 1284 case Token::FUNCTION: |
1277 result = ParseFunctionDeclaration(&names, CHECK_OK); | 1285 result = ParseFunctionDeclaration(&names, CHECK_OK); |
1278 break; | 1286 break; |
1279 | 1287 |
(...skipping 18 matching lines...) Expand all Loading... | |
1298 #endif | 1306 #endif |
1299 Interface* inner = Interface::NewUnknown(zone()); | 1307 Interface* inner = Interface::NewUnknown(zone()); |
1300 interface->Add(names[i], inner, zone(), CHECK_OK); | 1308 interface->Add(names[i], inner, zone(), CHECK_OK); |
1301 if (!*ok) | 1309 if (!*ok) |
1302 return NULL; | 1310 return NULL; |
1303 VariableProxy* proxy = NewUnresolved(names[i], LET, inner); | 1311 VariableProxy* proxy = NewUnresolved(names[i], LET, inner); |
1304 USE(proxy); | 1312 USE(proxy); |
1305 // TODO(rossberg): Rethink whether we actually need to store export | 1313 // TODO(rossberg): Rethink whether we actually need to store export |
1306 // declarations (for compilation?). | 1314 // declarations (for compilation?). |
1307 // ExportDeclaration* declaration = | 1315 // ExportDeclaration* declaration = |
1308 // factory()->NewExportDeclaration(proxy, top_scope_); | 1316 // factory()->NewExportDeclaration(proxy, top_scope_, position); |
1309 // top_scope_->AddDeclaration(declaration); | 1317 // top_scope_->AddDeclaration(declaration); |
1310 } | 1318 } |
1311 | 1319 |
1312 ASSERT(result != NULL); | 1320 ASSERT(result != NULL); |
1313 return result; | 1321 return result; |
1314 } | 1322 } |
1315 | 1323 |
1316 | 1324 |
1317 Statement* Parser::ParseBlockElement(ZoneStringList* labels, | 1325 Statement* Parser::ParseBlockElement(ZoneStringList* labels, |
1318 bool* ok) { | 1326 bool* ok) { |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1356 // ThrowStatement | 1364 // ThrowStatement |
1357 // TryStatement | 1365 // TryStatement |
1358 // DebuggerStatement | 1366 // DebuggerStatement |
1359 | 1367 |
1360 // Note: Since labels can only be used by 'break' and 'continue' | 1368 // Note: Since labels can only be used by 'break' and 'continue' |
1361 // statements, which themselves are only valid within blocks, | 1369 // statements, which themselves are only valid within blocks, |
1362 // iterations or 'switch' statements (i.e., BreakableStatements), | 1370 // iterations or 'switch' statements (i.e., BreakableStatements), |
1363 // labels can be simply ignored in all other cases; except for | 1371 // labels can be simply ignored in all other cases; except for |
1364 // trivial labeled break statements 'label: break label' which is | 1372 // trivial labeled break statements 'label: break label' which is |
1365 // parsed into an empty statement. | 1373 // 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()) { | 1374 switch (peek()) { |
1371 case Token::LBRACE: | 1375 case Token::LBRACE: |
1372 return ParseBlock(labels, ok); | 1376 return ParseBlock(labels, ok); |
1373 | 1377 |
1374 case Token::CONST: // fall through | 1378 case Token::CONST: // fall through |
1375 case Token::LET: | 1379 case Token::LET: |
1376 case Token::VAR: | 1380 case Token::VAR: |
1377 stmt = ParseVariableStatement(kStatement, NULL, ok); | 1381 return ParseVariableStatement(kStatement, NULL, ok); |
1378 break; | |
1379 | 1382 |
1380 case Token::SEMICOLON: | 1383 case Token::SEMICOLON: |
1381 Next(); | 1384 Next(); |
1382 return factory()->NewEmptyStatement(); | 1385 return factory()->NewEmptyStatement(RelocInfo::kNoPosition); |
1383 | 1386 |
1384 case Token::IF: | 1387 case Token::IF: |
1385 stmt = ParseIfStatement(labels, ok); | 1388 return ParseIfStatement(labels, ok); |
1386 break; | |
1387 | 1389 |
1388 case Token::DO: | 1390 case Token::DO: |
1389 stmt = ParseDoWhileStatement(labels, ok); | 1391 return ParseDoWhileStatement(labels, ok); |
1390 break; | |
1391 | 1392 |
1392 case Token::WHILE: | 1393 case Token::WHILE: |
1393 stmt = ParseWhileStatement(labels, ok); | 1394 return ParseWhileStatement(labels, ok); |
1394 break; | |
1395 | 1395 |
1396 case Token::FOR: | 1396 case Token::FOR: |
1397 stmt = ParseForStatement(labels, ok); | 1397 return ParseForStatement(labels, ok); |
1398 break; | |
1399 | 1398 |
1400 case Token::CONTINUE: | 1399 case Token::CONTINUE: |
1401 stmt = ParseContinueStatement(ok); | 1400 return ParseContinueStatement(ok); |
1402 break; | |
1403 | 1401 |
1404 case Token::BREAK: | 1402 case Token::BREAK: |
1405 stmt = ParseBreakStatement(labels, ok); | 1403 return ParseBreakStatement(labels, ok); |
1406 break; | |
1407 | 1404 |
1408 case Token::RETURN: | 1405 case Token::RETURN: |
1409 stmt = ParseReturnStatement(ok); | 1406 return ParseReturnStatement(ok); |
1410 break; | |
1411 | 1407 |
1412 case Token::WITH: | 1408 case Token::WITH: |
1413 stmt = ParseWithStatement(labels, ok); | 1409 return ParseWithStatement(labels, ok); |
1414 break; | |
1415 | 1410 |
1416 case Token::SWITCH: | 1411 case Token::SWITCH: |
1417 stmt = ParseSwitchStatement(labels, ok); | 1412 return ParseSwitchStatement(labels, ok); |
1418 break; | |
1419 | 1413 |
1420 case Token::THROW: | 1414 case Token::THROW: |
1421 stmt = ParseThrowStatement(ok); | 1415 return ParseThrowStatement(ok); |
1422 break; | |
1423 | 1416 |
1424 case Token::TRY: { | 1417 case Token::TRY: { |
1425 // NOTE: It is somewhat complicated to have labels on | 1418 // NOTE: It is somewhat complicated to have labels on |
1426 // try-statements. When breaking out of a try-finally statement, | 1419 // try-statements. When breaking out of a try-finally statement, |
1427 // one must take great care not to treat it as a | 1420 // one must take great care not to treat it as a |
1428 // fall-through. It is much easier just to wrap the entire | 1421 // fall-through. It is much easier just to wrap the entire |
1429 // try-statement in a statement block and put the labels there | 1422 // try-statement in a statement block and put the labels there |
1430 Block* result = factory()->NewBlock(labels, 1, false); | 1423 Block* result = |
1424 factory()->NewBlock(labels, 1, false, RelocInfo::kNoPosition); | |
1431 Target target(&this->target_stack_, result); | 1425 Target target(&this->target_stack_, result); |
1432 TryStatement* statement = ParseTryStatement(CHECK_OK); | 1426 TryStatement* statement = ParseTryStatement(CHECK_OK); |
1433 if (statement) { | |
1434 statement->set_statement_pos(statement_pos); | |
1435 } | |
1436 if (result) result->AddStatement(statement, zone()); | 1427 if (result) result->AddStatement(statement, zone()); |
1437 return result; | 1428 return result; |
1438 } | 1429 } |
1439 | 1430 |
1440 case Token::FUNCTION: { | 1431 case Token::FUNCTION: { |
1441 // FunctionDeclaration is only allowed in the context of SourceElements | 1432 // FunctionDeclaration is only allowed in the context of SourceElements |
1442 // (Ecma 262 5th Edition, clause 14): | 1433 // (Ecma 262 5th Edition, clause 14): |
1443 // SourceElement: | 1434 // SourceElement: |
1444 // Statement | 1435 // Statement |
1445 // FunctionDeclaration | 1436 // FunctionDeclaration |
1446 // Common language extension is to allow function declaration in place | 1437 // Common language extension is to allow function declaration in place |
1447 // of any statement. This language extension is disabled in strict mode. | 1438 // of any statement. This language extension is disabled in strict mode. |
1448 // | 1439 // |
1449 // In Harmony mode, this case also handles the extension: | 1440 // In Harmony mode, this case also handles the extension: |
1450 // Statement: | 1441 // Statement: |
1451 // GeneratorDeclaration | 1442 // GeneratorDeclaration |
1452 if (!top_scope_->is_classic_mode()) { | 1443 if (!top_scope_->is_classic_mode()) { |
1453 ReportMessageAt(scanner().peek_location(), "strict_function", | 1444 ReportMessageAt(scanner().peek_location(), "strict_function", |
1454 Vector<const char*>::empty()); | 1445 Vector<const char*>::empty()); |
1455 *ok = false; | 1446 *ok = false; |
1456 return NULL; | 1447 return NULL; |
1457 } | 1448 } |
1458 return ParseFunctionDeclaration(NULL, ok); | 1449 return ParseFunctionDeclaration(NULL, ok); |
1459 } | 1450 } |
1460 | 1451 |
1461 case Token::DEBUGGER: | 1452 case Token::DEBUGGER: |
1462 stmt = ParseDebuggerStatement(ok); | 1453 return ParseDebuggerStatement(ok); |
1463 break; | |
1464 | 1454 |
1465 default: | 1455 default: |
1466 stmt = ParseExpressionOrLabelledStatement(labels, ok); | 1456 return ParseExpressionOrLabelledStatement(labels, ok); |
1467 } | 1457 } |
1468 | |
1469 // Store the source position of the statement | |
1470 if (stmt != NULL) stmt->set_statement_pos(statement_pos); | |
1471 return stmt; | |
1472 } | 1458 } |
1473 | 1459 |
1474 | 1460 |
1475 VariableProxy* Parser::NewUnresolved( | 1461 VariableProxy* Parser::NewUnresolved( |
1476 Handle<String> name, VariableMode mode, Interface* interface) { | 1462 Handle<String> name, VariableMode mode, Interface* interface) { |
1477 // If we are inside a function, a declaration of a var/const variable is a | 1463 // 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 | 1464 // truly local variable, and the scope of the variable is always the function |
1479 // scope. | 1465 // scope. |
1480 // Let/const variables in harmony mode are always added to the immediately | 1466 // Let/const variables in harmony mode are always added to the immediately |
1481 // enclosing scope. | 1467 // enclosing scope. |
1482 return DeclarationScope(mode)->NewUnresolved( | 1468 return DeclarationScope(mode)->NewUnresolved( |
1483 factory(), name, interface, scanner().location().beg_pos); | 1469 factory(), name, interface, position()); |
1484 } | 1470 } |
1485 | 1471 |
1486 | 1472 |
1487 void Parser::Declare(Declaration* declaration, bool resolve, bool* ok) { | 1473 void Parser::Declare(Declaration* declaration, bool resolve, bool* ok) { |
1488 VariableProxy* proxy = declaration->proxy(); | 1474 VariableProxy* proxy = declaration->proxy(); |
1489 Handle<String> name = proxy->name(); | 1475 Handle<String> name = proxy->name(); |
1490 VariableMode mode = declaration->mode(); | 1476 VariableMode mode = declaration->mode(); |
1491 Scope* declaration_scope = DeclarationScope(mode); | 1477 Scope* declaration_scope = DeclarationScope(mode); |
1492 Variable* var = NULL; | 1478 Variable* var = NULL; |
1493 | 1479 |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1640 } | 1626 } |
1641 } | 1627 } |
1642 } | 1628 } |
1643 | 1629 |
1644 | 1630 |
1645 // Language extension which is only enabled for source files loaded | 1631 // Language extension which is only enabled for source files loaded |
1646 // through the API's extension mechanism. A native function | 1632 // through the API's extension mechanism. A native function |
1647 // declaration is resolved by looking up the function through a | 1633 // declaration is resolved by looking up the function through a |
1648 // callback provided by the extension. | 1634 // callback provided by the extension. |
1649 Statement* Parser::ParseNativeDeclaration(bool* ok) { | 1635 Statement* Parser::ParseNativeDeclaration(bool* ok) { |
1636 int pos = peek_position(); | |
1650 Expect(Token::FUNCTION, CHECK_OK); | 1637 Expect(Token::FUNCTION, CHECK_OK); |
1651 Handle<String> name = ParseIdentifier(CHECK_OK); | 1638 Handle<String> name = ParseIdentifier(CHECK_OK); |
1652 Expect(Token::LPAREN, CHECK_OK); | 1639 Expect(Token::LPAREN, CHECK_OK); |
1653 bool done = (peek() == Token::RPAREN); | 1640 bool done = (peek() == Token::RPAREN); |
1654 while (!done) { | 1641 while (!done) { |
1655 ParseIdentifier(CHECK_OK); | 1642 ParseIdentifier(CHECK_OK); |
1656 done = (peek() == Token::RPAREN); | 1643 done = (peek() == Token::RPAREN); |
1657 if (!done) { | 1644 if (!done) { |
1658 Expect(Token::COMMA, CHECK_OK); | 1645 Expect(Token::COMMA, CHECK_OK); |
1659 } | 1646 } |
(...skipping 26 matching lines...) Expand all Loading... | |
1686 // Copy the function data to the shared function info. | 1673 // Copy the function data to the shared function info. |
1687 shared->set_function_data(fun->shared()->function_data()); | 1674 shared->set_function_data(fun->shared()->function_data()); |
1688 int parameters = fun->shared()->formal_parameter_count(); | 1675 int parameters = fun->shared()->formal_parameter_count(); |
1689 shared->set_formal_parameter_count(parameters); | 1676 shared->set_formal_parameter_count(parameters); |
1690 | 1677 |
1691 // TODO(1240846): It's weird that native function declarations are | 1678 // TODO(1240846): It's weird that native function declarations are |
1692 // introduced dynamically when we meet their declarations, whereas | 1679 // introduced dynamically when we meet their declarations, whereas |
1693 // other functions are set up when entering the surrounding scope. | 1680 // other functions are set up when entering the surrounding scope. |
1694 VariableProxy* proxy = NewUnresolved(name, VAR, Interface::NewValue()); | 1681 VariableProxy* proxy = NewUnresolved(name, VAR, Interface::NewValue()); |
1695 Declaration* declaration = | 1682 Declaration* declaration = |
1696 factory()->NewVariableDeclaration(proxy, VAR, top_scope_); | 1683 factory()->NewVariableDeclaration(proxy, VAR, top_scope_, pos); |
1697 Declare(declaration, true, CHECK_OK); | 1684 Declare(declaration, true, CHECK_OK); |
1698 SharedFunctionInfoLiteral* lit = | 1685 SharedFunctionInfoLiteral* lit = |
1699 factory()->NewSharedFunctionInfoLiteral(shared); | 1686 factory()->NewSharedFunctionInfoLiteral(shared, RelocInfo::kNoPosition); |
1700 return factory()->NewExpressionStatement( | 1687 return factory()->NewExpressionStatement( |
1701 factory()->NewAssignment( | 1688 factory()->NewAssignment( |
1702 Token::INIT_VAR, proxy, lit, RelocInfo::kNoPosition)); | 1689 Token::INIT_VAR, proxy, lit, RelocInfo::kNoPosition), |
1690 pos); | |
1703 } | 1691 } |
1704 | 1692 |
1705 | 1693 |
1706 Statement* Parser::ParseFunctionDeclaration(ZoneStringList* names, bool* ok) { | 1694 Statement* Parser::ParseFunctionDeclaration(ZoneStringList* names, bool* ok) { |
1707 // FunctionDeclaration :: | 1695 // FunctionDeclaration :: |
1708 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' | 1696 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' |
1709 // GeneratorDeclaration :: | 1697 // GeneratorDeclaration :: |
1710 // 'function' '*' Identifier '(' FormalParameterListopt ')' | 1698 // 'function' '*' Identifier '(' FormalParameterListopt ')' |
1711 // '{' FunctionBody '}' | 1699 // '{' FunctionBody '}' |
1712 Expect(Token::FUNCTION, CHECK_OK); | 1700 Expect(Token::FUNCTION, CHECK_OK); |
1713 int function_token_position = scanner().location().beg_pos; | 1701 int pos = position(); |
1714 bool is_generator = allow_generators() && Check(Token::MUL); | 1702 bool is_generator = allow_generators() && Check(Token::MUL); |
1715 bool is_strict_reserved = false; | 1703 bool is_strict_reserved = false; |
1716 Handle<String> name = ParseIdentifierOrStrictReservedWord( | 1704 Handle<String> name = ParseIdentifierOrStrictReservedWord( |
1717 &is_strict_reserved, CHECK_OK); | 1705 &is_strict_reserved, CHECK_OK); |
1718 FunctionLiteral* fun = ParseFunctionLiteral(name, | 1706 FunctionLiteral* fun = ParseFunctionLiteral(name, |
1719 is_strict_reserved, | 1707 is_strict_reserved, |
1720 is_generator, | 1708 is_generator, |
1721 function_token_position, | 1709 pos, |
1722 FunctionLiteral::DECLARATION, | 1710 FunctionLiteral::DECLARATION, |
1723 CHECK_OK); | 1711 CHECK_OK); |
1724 // Even if we're not at the top-level of the global or a function | 1712 // Even if we're not at the top-level of the global or a function |
1725 // scope, we treat it as such and introduce the function with its | 1713 // scope, we treat it as such and introduce the function with its |
1726 // initial value upon entering the corresponding scope. | 1714 // initial value upon entering the corresponding scope. |
1727 // In extended mode, a function behaves as a lexical binding, except in the | 1715 // In extended mode, a function behaves as a lexical binding, except in the |
1728 // global scope. | 1716 // global scope. |
1729 VariableMode mode = | 1717 VariableMode mode = |
1730 is_extended_mode() && !top_scope_->is_global_scope() ? LET : VAR; | 1718 is_extended_mode() && !top_scope_->is_global_scope() ? LET : VAR; |
1731 VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue()); | 1719 VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue()); |
1732 Declaration* declaration = | 1720 Declaration* declaration = |
1733 factory()->NewFunctionDeclaration(proxy, mode, fun, top_scope_); | 1721 factory()->NewFunctionDeclaration(proxy, mode, fun, top_scope_, pos); |
1734 Declare(declaration, true, CHECK_OK); | 1722 Declare(declaration, true, CHECK_OK); |
1735 if (names) names->Add(name, zone()); | 1723 if (names) names->Add(name, zone()); |
1736 return factory()->NewEmptyStatement(); | 1724 return factory()->NewEmptyStatement(RelocInfo::kNoPosition); |
1737 } | 1725 } |
1738 | 1726 |
1739 | 1727 |
1740 Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) { | 1728 Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) { |
1741 if (top_scope_->is_extended_mode()) return ParseScopedBlock(labels, ok); | 1729 if (top_scope_->is_extended_mode()) return ParseScopedBlock(labels, ok); |
1742 | 1730 |
1743 // Block :: | 1731 // Block :: |
1744 // '{' Statement* '}' | 1732 // '{' Statement* '}' |
1745 | 1733 |
1746 // Note that a Block does not introduce a new execution scope! | 1734 // Note that a Block does not introduce a new execution scope! |
1747 // (ECMA-262, 3rd, 12.2) | 1735 // (ECMA-262, 3rd, 12.2) |
1748 // | 1736 // |
1749 // Construct block expecting 16 statements. | 1737 // Construct block expecting 16 statements. |
1750 Block* result = factory()->NewBlock(labels, 16, false); | 1738 Block* result = |
1739 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition); | |
1751 Target target(&this->target_stack_, result); | 1740 Target target(&this->target_stack_, result); |
1752 Expect(Token::LBRACE, CHECK_OK); | 1741 Expect(Token::LBRACE, CHECK_OK); |
1753 while (peek() != Token::RBRACE) { | 1742 while (peek() != Token::RBRACE) { |
1754 Statement* stat = ParseStatement(NULL, CHECK_OK); | 1743 Statement* stat = ParseStatement(NULL, CHECK_OK); |
1755 if (stat && !stat->IsEmpty()) { | 1744 if (stat && !stat->IsEmpty()) { |
1756 result->AddStatement(stat, zone()); | 1745 result->AddStatement(stat, zone()); |
1757 } | 1746 } |
1758 } | 1747 } |
1759 Expect(Token::RBRACE, CHECK_OK); | 1748 Expect(Token::RBRACE, CHECK_OK); |
1760 return result; | 1749 return result; |
1761 } | 1750 } |
1762 | 1751 |
1763 | 1752 |
1764 Block* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) { | 1753 Block* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) { |
1765 // The harmony mode uses block elements instead of statements. | 1754 // The harmony mode uses block elements instead of statements. |
1766 // | 1755 // |
1767 // Block :: | 1756 // Block :: |
1768 // '{' BlockElement* '}' | 1757 // '{' BlockElement* '}' |
1769 | 1758 |
1770 // Construct block expecting 16 statements. | 1759 // Construct block expecting 16 statements. |
1771 Block* body = factory()->NewBlock(labels, 16, false); | 1760 Block* body = |
1761 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition); | |
1772 Scope* block_scope = NewScope(top_scope_, BLOCK_SCOPE); | 1762 Scope* block_scope = NewScope(top_scope_, BLOCK_SCOPE); |
1773 | 1763 |
1774 // Parse the statements and collect escaping labels. | 1764 // Parse the statements and collect escaping labels. |
1775 Expect(Token::LBRACE, CHECK_OK); | 1765 Expect(Token::LBRACE, CHECK_OK); |
1776 block_scope->set_start_position(scanner().location().beg_pos); | 1766 block_scope->set_start_position(scanner().location().beg_pos); |
1777 { BlockState block_state(this, block_scope); | 1767 { BlockState block_state(this, block_scope); |
1778 TargetCollector collector(zone()); | 1768 TargetCollector collector(zone()); |
1779 Target target(&this->target_stack_, &collector); | 1769 Target target(&this->target_stack_, &collector); |
1780 Target target_body(&this->target_stack_, body); | 1770 Target target_body(&this->target_stack_, body); |
1781 | 1771 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1831 // The ES6 Draft Rev3 specifies the following grammar for const declarations | 1821 // The ES6 Draft Rev3 specifies the following grammar for const declarations |
1832 // | 1822 // |
1833 // ConstDeclaration :: | 1823 // ConstDeclaration :: |
1834 // const ConstBinding (',' ConstBinding)* ';' | 1824 // const ConstBinding (',' ConstBinding)* ';' |
1835 // ConstBinding :: | 1825 // ConstBinding :: |
1836 // Identifier '=' AssignmentExpression | 1826 // Identifier '=' AssignmentExpression |
1837 // | 1827 // |
1838 // TODO(ES6): | 1828 // TODO(ES6): |
1839 // ConstBinding :: | 1829 // ConstBinding :: |
1840 // BindingPattern '=' AssignmentExpression | 1830 // BindingPattern '=' AssignmentExpression |
1831 | |
1832 int pos = peek_position(); | |
1841 VariableMode mode = VAR; | 1833 VariableMode mode = VAR; |
1842 // True if the binding needs initialization. 'let' and 'const' declared | 1834 // True if the binding needs initialization. 'let' and 'const' declared |
1843 // bindings are created uninitialized by their declaration nodes and | 1835 // bindings are created uninitialized by their declaration nodes and |
1844 // need initialization. 'var' declared bindings are always initialized | 1836 // need initialization. 'var' declared bindings are always initialized |
1845 // immediately by their declaration nodes. | 1837 // immediately by their declaration nodes. |
1846 bool needs_init = false; | 1838 bool needs_init = false; |
1847 bool is_const = false; | 1839 bool is_const = false; |
1848 Token::Value init_op = Token::INIT_VAR; | 1840 Token::Value init_op = Token::INIT_VAR; |
1849 if (peek() == Token::VAR) { | 1841 if (peek() == Token::VAR) { |
1850 Consume(Token::VAR); | 1842 Consume(Token::VAR); |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1916 // Scope declaration, and rewrite the source-level initialization into an | 1908 // Scope declaration, and rewrite the source-level initialization into an |
1917 // assignment statement. We use a block to collect multiple assignments. | 1909 // assignment statement. We use a block to collect multiple assignments. |
1918 // | 1910 // |
1919 // We mark the block as initializer block because we don't want the | 1911 // We mark the block as initializer block because we don't want the |
1920 // rewriter to add a '.result' assignment to such a block (to get compliant | 1912 // rewriter to add a '.result' assignment to such a block (to get compliant |
1921 // behavior for code such as print(eval('var x = 7')), and for cosmetic | 1913 // behavior for code such as print(eval('var x = 7')), and for cosmetic |
1922 // reasons when pretty-printing. Also, unless an assignment (initialization) | 1914 // reasons when pretty-printing. Also, unless an assignment (initialization) |
1923 // is inside an initializer block, it is ignored. | 1915 // is inside an initializer block, it is ignored. |
1924 // | 1916 // |
1925 // Create new block with one expected declaration. | 1917 // Create new block with one expected declaration. |
1926 Block* block = factory()->NewBlock(NULL, 1, true); | 1918 Block* block = factory()->NewBlock(NULL, 1, true, pos); |
1927 int nvars = 0; // the number of variables declared | 1919 int nvars = 0; // the number of variables declared |
1928 Handle<String> name; | 1920 Handle<String> name; |
1929 do { | 1921 do { |
1930 if (fni_ != NULL) fni_->Enter(); | 1922 if (fni_ != NULL) fni_->Enter(); |
1931 | 1923 |
1932 // Parse variable name. | 1924 // Parse variable name. |
1933 if (nvars > 0) Consume(Token::COMMA); | 1925 if (nvars > 0) Consume(Token::COMMA); |
1934 name = ParseIdentifier(CHECK_OK); | 1926 name = ParseIdentifier(CHECK_OK); |
1935 if (fni_ != NULL) fni_->PushVariableName(name); | 1927 if (fni_ != NULL) fni_->PushVariableName(name); |
1936 | 1928 |
(...skipping 16 matching lines...) Expand all Loading... | |
1953 // If we have a const declaration, in an inner scope, the proxy is always | 1945 // If we have a const declaration, in an inner scope, the proxy is always |
1954 // bound to the declared variable (independent of possibly surrounding with | 1946 // bound to the declared variable (independent of possibly surrounding with |
1955 // statements). | 1947 // statements). |
1956 // For let/const declarations in harmony mode, we can also immediately | 1948 // For let/const declarations in harmony mode, we can also immediately |
1957 // pre-resolve the proxy because it resides in the same scope as the | 1949 // pre-resolve the proxy because it resides in the same scope as the |
1958 // declaration. | 1950 // declaration. |
1959 Interface* interface = | 1951 Interface* interface = |
1960 is_const ? Interface::NewConst() : Interface::NewValue(); | 1952 is_const ? Interface::NewConst() : Interface::NewValue(); |
1961 VariableProxy* proxy = NewUnresolved(name, mode, interface); | 1953 VariableProxy* proxy = NewUnresolved(name, mode, interface); |
1962 Declaration* declaration = | 1954 Declaration* declaration = |
1963 factory()->NewVariableDeclaration(proxy, mode, top_scope_); | 1955 factory()->NewVariableDeclaration(proxy, mode, top_scope_, pos); |
1964 Declare(declaration, mode != VAR, CHECK_OK); | 1956 Declare(declaration, mode != VAR, CHECK_OK); |
1965 nvars++; | 1957 nvars++; |
1966 if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) { | 1958 if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) { |
1967 ReportMessageAt(scanner().location(), "too_many_variables", | 1959 ReportMessageAt(scanner().location(), "too_many_variables", |
1968 Vector<const char*>::empty()); | 1960 Vector<const char*>::empty()); |
1969 *ok = false; | 1961 *ok = false; |
1970 return NULL; | 1962 return NULL; |
1971 } | 1963 } |
1972 if (names) names->Add(name, zone()); | 1964 if (names) names->Add(name, zone()); |
1973 | 1965 |
(...skipping 19 matching lines...) Expand all Loading... | |
1993 // is *not* syntactic sugar for: | 1985 // is *not* syntactic sugar for: |
1994 // | 1986 // |
1995 // const c; c = x; | 1987 // const c; c = x; |
1996 // | 1988 // |
1997 // The "variable" c initialized to x is the same as the declared | 1989 // The "variable" c initialized to x is the same as the declared |
1998 // one - there is no re-lookup (see the last parameter of the | 1990 // one - there is no re-lookup (see the last parameter of the |
1999 // Declare() call above). | 1991 // Declare() call above). |
2000 | 1992 |
2001 Scope* initialization_scope = is_const ? declaration_scope : top_scope_; | 1993 Scope* initialization_scope = is_const ? declaration_scope : top_scope_; |
2002 Expression* value = NULL; | 1994 Expression* value = NULL; |
2003 int position = -1; | 1995 int pos = -1; |
2004 // Harmony consts have non-optional initializers. | 1996 // Harmony consts have non-optional initializers. |
2005 if (peek() == Token::ASSIGN || mode == CONST_HARMONY) { | 1997 if (peek() == Token::ASSIGN || mode == CONST_HARMONY) { |
2006 Expect(Token::ASSIGN, CHECK_OK); | 1998 Expect(Token::ASSIGN, CHECK_OK); |
2007 position = scanner().location().beg_pos; | 1999 pos = position(); |
2008 value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); | 2000 value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); |
2009 // Don't infer if it is "a = function(){...}();"-like expression. | 2001 // Don't infer if it is "a = function(){...}();"-like expression. |
2010 if (fni_ != NULL && | 2002 if (fni_ != NULL && |
2011 value->AsCall() == NULL && | 2003 value->AsCall() == NULL && |
2012 value->AsCallNew() == NULL) { | 2004 value->AsCallNew() == NULL) { |
2013 fni_->Infer(); | 2005 fni_->Infer(); |
2014 } else { | 2006 } else { |
2015 fni_->RemoveLastFunction(); | 2007 fni_->RemoveLastFunction(); |
2016 } | 2008 } |
2017 if (decl_props != NULL) *decl_props = kHasInitializers; | 2009 if (decl_props != NULL) *decl_props = kHasInitializers; |
2018 } | 2010 } |
2019 | 2011 |
2020 // Record the end position of the initializer. | 2012 // Record the end position of the initializer. |
2021 if (proxy->var() != NULL) { | 2013 if (proxy->var() != NULL) { |
2022 proxy->var()->set_initializer_position(scanner().location().end_pos); | 2014 proxy->var()->set_initializer_position(position()); |
2023 } | 2015 } |
2024 | 2016 |
2025 // Make sure that 'const x' and 'let x' initialize 'x' to undefined. | 2017 // Make sure that 'const x' and 'let x' initialize 'x' to undefined. |
2026 if (value == NULL && needs_init) { | 2018 if (value == NULL && needs_init) { |
2027 value = GetLiteralUndefined(); | 2019 value = GetLiteralUndefined(position()); |
2028 } | 2020 } |
2029 | 2021 |
2030 // Global variable declarations must be compiled in a specific | 2022 // Global variable declarations must be compiled in a specific |
2031 // way. When the script containing the global variable declaration | 2023 // way. When the script containing the global variable declaration |
2032 // is entered, the global variable must be declared, so that if it | 2024 // is entered, the global variable must be declared, so that if it |
2033 // doesn't exist (on the global object itself, see ES5 errata) it | 2025 // doesn't exist (on the global object itself, see ES5 errata) it |
2034 // gets created with an initial undefined value. This is handled | 2026 // gets created with an initial undefined value. This is handled |
2035 // by the declarations part of the function representing the | 2027 // by the declarations part of the function representing the |
2036 // top-level global code; see Runtime::DeclareGlobalVariable. If | 2028 // top-level global code; see Runtime::DeclareGlobalVariable. If |
2037 // it already exists (in the object or in a prototype), it is | 2029 // it already exists (in the object or in a prototype), it is |
2038 // *not* touched until the variable declaration statement is | 2030 // *not* touched until the variable declaration statement is |
2039 // executed. | 2031 // executed. |
2040 // | 2032 // |
2041 // Executing the variable declaration statement will always | 2033 // Executing the variable declaration statement will always |
2042 // guarantee to give the global object a "local" variable; a | 2034 // guarantee to give the global object a "local" variable; a |
2043 // variable defined in the global object and not in any | 2035 // variable defined in the global object and not in any |
2044 // prototype. This way, global variable declarations can shadow | 2036 // prototype. This way, global variable declarations can shadow |
2045 // properties in the prototype chain, but only after the variable | 2037 // properties in the prototype chain, but only after the variable |
2046 // declaration statement has been executed. This is important in | 2038 // declaration statement has been executed. This is important in |
2047 // browsers where the global object (window) has lots of | 2039 // browsers where the global object (window) has lots of |
2048 // properties defined in prototype objects. | 2040 // properties defined in prototype objects. |
2049 if (initialization_scope->is_global_scope() && | 2041 if (initialization_scope->is_global_scope() && |
2050 !IsLexicalVariableMode(mode)) { | 2042 !IsLexicalVariableMode(mode)) { |
2051 // Compute the arguments for the runtime call. | 2043 // Compute the arguments for the runtime call. |
2052 ZoneList<Expression*>* arguments = | 2044 ZoneList<Expression*>* arguments = |
2053 new(zone()) ZoneList<Expression*>(3, zone()); | 2045 new(zone()) ZoneList<Expression*>(3, zone()); |
2054 // We have at least 1 parameter. | 2046 // We have at least 1 parameter. |
2055 arguments->Add(factory()->NewLiteral(name), zone()); | 2047 arguments->Add(factory()->NewLiteral(name, pos), zone()); |
2056 CallRuntime* initialize; | 2048 CallRuntime* initialize; |
2057 | 2049 |
2058 if (is_const) { | 2050 if (is_const) { |
2059 arguments->Add(value, zone()); | 2051 arguments->Add(value, zone()); |
2060 value = NULL; // zap the value to avoid the unnecessary assignment | 2052 value = NULL; // zap the value to avoid the unnecessary assignment |
2061 | 2053 |
2062 // Construct the call to Runtime_InitializeConstGlobal | 2054 // Construct the call to Runtime_InitializeConstGlobal |
2063 // and add it to the initialization statement block. | 2055 // and add it to the initialization statement block. |
2064 // Note that the function does different things depending on | 2056 // Note that the function does different things depending on |
2065 // the number of arguments (1 or 2). | 2057 // the number of arguments (1 or 2). |
2066 initialize = factory()->NewCallRuntime( | 2058 initialize = factory()->NewCallRuntime( |
2067 isolate()->factory()->InitializeConstGlobal_string(), | 2059 isolate()->factory()->InitializeConstGlobal_string(), |
2068 Runtime::FunctionForId(Runtime::kInitializeConstGlobal), | 2060 Runtime::FunctionForId(Runtime::kInitializeConstGlobal), |
2069 arguments); | 2061 arguments, pos); |
2070 } else { | 2062 } else { |
2071 // Add strict mode. | 2063 // Add strict mode. |
2072 // We may want to pass singleton to avoid Literal allocations. | 2064 // We may want to pass singleton to avoid Literal allocations. |
2073 LanguageMode language_mode = initialization_scope->language_mode(); | 2065 LanguageMode language_mode = initialization_scope->language_mode(); |
2074 arguments->Add(factory()->NewNumberLiteral(language_mode), zone()); | 2066 arguments->Add(factory()->NewNumberLiteral(language_mode, pos), zone()); |
2075 | 2067 |
2076 // Be careful not to assign a value to the global variable if | 2068 // Be careful not to assign a value to the global variable if |
2077 // we're in a with. The initialization value should not | 2069 // we're in a with. The initialization value should not |
2078 // necessarily be stored in the global object in that case, | 2070 // necessarily be stored in the global object in that case, |
2079 // which is why we need to generate a separate assignment node. | 2071 // which is why we need to generate a separate assignment node. |
2080 if (value != NULL && !inside_with()) { | 2072 if (value != NULL && !inside_with()) { |
2081 arguments->Add(value, zone()); | 2073 arguments->Add(value, zone()); |
2082 value = NULL; // zap the value to avoid the unnecessary assignment | 2074 value = NULL; // zap the value to avoid the unnecessary assignment |
2083 } | 2075 } |
2084 | 2076 |
2085 // Construct the call to Runtime_InitializeVarGlobal | 2077 // Construct the call to Runtime_InitializeVarGlobal |
2086 // and add it to the initialization statement block. | 2078 // and add it to the initialization statement block. |
2087 // Note that the function does different things depending on | 2079 // Note that the function does different things depending on |
2088 // the number of arguments (2 or 3). | 2080 // the number of arguments (2 or 3). |
2089 initialize = factory()->NewCallRuntime( | 2081 initialize = factory()->NewCallRuntime( |
2090 isolate()->factory()->InitializeVarGlobal_string(), | 2082 isolate()->factory()->InitializeVarGlobal_string(), |
2091 Runtime::FunctionForId(Runtime::kInitializeVarGlobal), | 2083 Runtime::FunctionForId(Runtime::kInitializeVarGlobal), |
2092 arguments); | 2084 arguments, pos); |
2093 } | 2085 } |
2094 | 2086 |
2095 block->AddStatement(factory()->NewExpressionStatement(initialize), | 2087 block->AddStatement( |
2096 zone()); | 2088 factory()->NewExpressionStatement(initialize, RelocInfo::kNoPosition), |
2089 zone()); | |
2097 } else if (needs_init) { | 2090 } else if (needs_init) { |
2098 // Constant initializations always assign to the declared constant which | 2091 // Constant initializations always assign to the declared constant which |
2099 // is always at the function scope level. This is only relevant for | 2092 // is always at the function scope level. This is only relevant for |
2100 // dynamically looked-up variables and constants (the start context for | 2093 // dynamically looked-up variables and constants (the start context for |
2101 // constant lookups is always the function context, while it is the top | 2094 // constant lookups is always the function context, while it is the top |
2102 // context for var declared variables). Sigh... | 2095 // context for var declared variables). Sigh... |
2103 // For 'let' and 'const' declared variables in harmony mode the | 2096 // For 'let' and 'const' declared variables in harmony mode the |
2104 // initialization also always assigns to the declared variable. | 2097 // initialization also always assigns to the declared variable. |
2105 ASSERT(proxy != NULL); | 2098 ASSERT(proxy != NULL); |
2106 ASSERT(proxy->var() != NULL); | 2099 ASSERT(proxy->var() != NULL); |
2107 ASSERT(value != NULL); | 2100 ASSERT(value != NULL); |
2108 Assignment* assignment = | 2101 Assignment* assignment = |
2109 factory()->NewAssignment(init_op, proxy, value, position); | 2102 factory()->NewAssignment(init_op, proxy, value, pos); |
2110 block->AddStatement(factory()->NewExpressionStatement(assignment), | 2103 block->AddStatement( |
2111 zone()); | 2104 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition), |
2105 zone()); | |
2112 value = NULL; | 2106 value = NULL; |
2113 } | 2107 } |
2114 | 2108 |
2115 // Add an assignment node to the initialization statement block if we still | 2109 // Add an assignment node to the initialization statement block if we still |
2116 // have a pending initialization value. | 2110 // have a pending initialization value. |
2117 if (value != NULL) { | 2111 if (value != NULL) { |
2118 ASSERT(mode == VAR); | 2112 ASSERT(mode == VAR); |
2119 // 'var' initializations are simply assignments (with all the consequences | 2113 // 'var' initializations are simply assignments (with all the consequences |
2120 // if they are inside a 'with' statement - they may change a 'with' object | 2114 // if they are inside a 'with' statement - they may change a 'with' object |
2121 // property). | 2115 // property). |
2122 VariableProxy* proxy = | 2116 VariableProxy* proxy = |
2123 initialization_scope->NewUnresolved(factory(), name, interface); | 2117 initialization_scope->NewUnresolved(factory(), name, interface); |
2124 Assignment* assignment = | 2118 Assignment* assignment = |
2125 factory()->NewAssignment(init_op, proxy, value, position); | 2119 factory()->NewAssignment(init_op, proxy, value, pos); |
2126 block->AddStatement(factory()->NewExpressionStatement(assignment), | 2120 block->AddStatement( |
2127 zone()); | 2121 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition), |
2122 zone()); | |
2128 } | 2123 } |
2129 | 2124 |
2130 if (fni_ != NULL) fni_->Leave(); | 2125 if (fni_ != NULL) fni_->Leave(); |
2131 } while (peek() == Token::COMMA); | 2126 } while (peek() == Token::COMMA); |
2132 | 2127 |
2133 // If there was a single non-const declaration, return it in the output | 2128 // If there was a single non-const declaration, return it in the output |
2134 // parameter for possible use by for/in. | 2129 // parameter for possible use by for/in. |
2135 if (nvars == 1 && !is_const) { | 2130 if (nvars == 1 && !is_const) { |
2136 *out = name; | 2131 *out = name; |
2137 } | 2132 } |
(...skipping 11 matching lines...) Expand all Loading... | |
2149 | 2144 |
2150 return false; | 2145 return false; |
2151 } | 2146 } |
2152 | 2147 |
2153 | 2148 |
2154 Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels, | 2149 Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels, |
2155 bool* ok) { | 2150 bool* ok) { |
2156 // ExpressionStatement | LabelledStatement :: | 2151 // ExpressionStatement | LabelledStatement :: |
2157 // Expression ';' | 2152 // Expression ';' |
2158 // Identifier ':' Statement | 2153 // Identifier ':' Statement |
2154 int pos = peek_position(); | |
2159 bool starts_with_idenfifier = peek_any_identifier(); | 2155 bool starts_with_idenfifier = peek_any_identifier(); |
2160 Expression* expr = ParseExpression(true, CHECK_OK); | 2156 Expression* expr = ParseExpression(true, CHECK_OK); |
2161 if (peek() == Token::COLON && starts_with_idenfifier && expr != NULL && | 2157 if (peek() == Token::COLON && starts_with_idenfifier && expr != NULL && |
2162 expr->AsVariableProxy() != NULL && | 2158 expr->AsVariableProxy() != NULL && |
2163 !expr->AsVariableProxy()->is_this()) { | 2159 !expr->AsVariableProxy()->is_this()) { |
2164 // Expression is a single identifier, and not, e.g., a parenthesized | 2160 // Expression is a single identifier, and not, e.g., a parenthesized |
2165 // identifier. | 2161 // identifier. |
2166 VariableProxy* var = expr->AsVariableProxy(); | 2162 VariableProxy* var = expr->AsVariableProxy(); |
2167 Handle<String> label = var->name(); | 2163 Handle<String> label = var->name(); |
2168 // TODO(1240780): We don't check for redeclaration of labels | 2164 // TODO(1240780): We don't check for redeclaration of labels |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2208 // Only expect semicolon in the former case. | 2204 // Only expect semicolon in the former case. |
2209 if (!FLAG_harmony_modules || | 2205 if (!FLAG_harmony_modules || |
2210 peek() != Token::IDENTIFIER || | 2206 peek() != Token::IDENTIFIER || |
2211 scanner().HasAnyLineTerminatorBeforeNext() || | 2207 scanner().HasAnyLineTerminatorBeforeNext() || |
2212 expr->AsVariableProxy() == NULL || | 2208 expr->AsVariableProxy() == NULL || |
2213 !expr->AsVariableProxy()->name()->Equals( | 2209 !expr->AsVariableProxy()->name()->Equals( |
2214 isolate()->heap()->module_string()) || | 2210 isolate()->heap()->module_string()) || |
2215 scanner().literal_contains_escapes()) { | 2211 scanner().literal_contains_escapes()) { |
2216 ExpectSemicolon(CHECK_OK); | 2212 ExpectSemicolon(CHECK_OK); |
2217 } | 2213 } |
2218 return factory()->NewExpressionStatement(expr); | 2214 return factory()->NewExpressionStatement(expr, pos); |
2219 } | 2215 } |
2220 | 2216 |
2221 | 2217 |
2222 IfStatement* Parser::ParseIfStatement(ZoneStringList* labels, bool* ok) { | 2218 IfStatement* Parser::ParseIfStatement(ZoneStringList* labels, bool* ok) { |
2223 // IfStatement :: | 2219 // IfStatement :: |
2224 // 'if' '(' Expression ')' Statement ('else' Statement)? | 2220 // 'if' '(' Expression ')' Statement ('else' Statement)? |
2225 | 2221 |
2222 int pos = peek_position(); | |
2226 Expect(Token::IF, CHECK_OK); | 2223 Expect(Token::IF, CHECK_OK); |
2227 Expect(Token::LPAREN, CHECK_OK); | 2224 Expect(Token::LPAREN, CHECK_OK); |
2228 Expression* condition = ParseExpression(true, CHECK_OK); | 2225 Expression* condition = ParseExpression(true, CHECK_OK); |
2229 Expect(Token::RPAREN, CHECK_OK); | 2226 Expect(Token::RPAREN, CHECK_OK); |
2230 Statement* then_statement = ParseStatement(labels, CHECK_OK); | 2227 Statement* then_statement = ParseStatement(labels, CHECK_OK); |
2231 Statement* else_statement = NULL; | 2228 Statement* else_statement = NULL; |
2232 if (peek() == Token::ELSE) { | 2229 if (peek() == Token::ELSE) { |
2233 Next(); | 2230 Next(); |
2234 else_statement = ParseStatement(labels, CHECK_OK); | 2231 else_statement = ParseStatement(labels, CHECK_OK); |
2235 } else { | 2232 } else { |
2236 else_statement = factory()->NewEmptyStatement(); | 2233 else_statement = factory()->NewEmptyStatement(RelocInfo::kNoPosition); |
2237 } | 2234 } |
2238 return factory()->NewIfStatement(condition, then_statement, else_statement); | 2235 return factory()->NewIfStatement( |
2236 condition, then_statement, else_statement, pos); | |
2239 } | 2237 } |
2240 | 2238 |
2241 | 2239 |
2242 Statement* Parser::ParseContinueStatement(bool* ok) { | 2240 Statement* Parser::ParseContinueStatement(bool* ok) { |
2243 // ContinueStatement :: | 2241 // ContinueStatement :: |
2244 // 'continue' Identifier? ';' | 2242 // 'continue' Identifier? ';' |
2245 | 2243 |
2244 int pos = peek_position(); | |
2246 Expect(Token::CONTINUE, CHECK_OK); | 2245 Expect(Token::CONTINUE, CHECK_OK); |
2247 Handle<String> label = Handle<String>::null(); | 2246 Handle<String> label = Handle<String>::null(); |
2248 Token::Value tok = peek(); | 2247 Token::Value tok = peek(); |
2249 if (!scanner().HasAnyLineTerminatorBeforeNext() && | 2248 if (!scanner().HasAnyLineTerminatorBeforeNext() && |
2250 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { | 2249 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { |
2251 label = ParseIdentifier(CHECK_OK); | 2250 label = ParseIdentifier(CHECK_OK); |
2252 } | 2251 } |
2253 IterationStatement* target = NULL; | 2252 IterationStatement* target = NULL; |
2254 target = LookupContinueTarget(label, CHECK_OK); | 2253 target = LookupContinueTarget(label, CHECK_OK); |
2255 if (target == NULL) { | 2254 if (target == NULL) { |
2256 // Illegal continue statement. | 2255 // Illegal continue statement. |
2257 const char* message = "illegal_continue"; | 2256 const char* message = "illegal_continue"; |
2258 Vector<Handle<String> > args; | 2257 Vector<Handle<String> > args; |
2259 if (!label.is_null()) { | 2258 if (!label.is_null()) { |
2260 message = "unknown_label"; | 2259 message = "unknown_label"; |
2261 args = Vector<Handle<String> >(&label, 1); | 2260 args = Vector<Handle<String> >(&label, 1); |
2262 } | 2261 } |
2263 ReportMessageAt(scanner().location(), message, args); | 2262 ReportMessageAt(scanner().location(), message, args); |
2264 *ok = false; | 2263 *ok = false; |
2265 return NULL; | 2264 return NULL; |
2266 } | 2265 } |
2267 ExpectSemicolon(CHECK_OK); | 2266 ExpectSemicolon(CHECK_OK); |
2268 return factory()->NewContinueStatement(target); | 2267 return factory()->NewContinueStatement(target, pos); |
2269 } | 2268 } |
2270 | 2269 |
2271 | 2270 |
2272 Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) { | 2271 Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) { |
2273 // BreakStatement :: | 2272 // BreakStatement :: |
2274 // 'break' Identifier? ';' | 2273 // 'break' Identifier? ';' |
2275 | 2274 |
2275 int pos = peek_position(); | |
2276 Expect(Token::BREAK, CHECK_OK); | 2276 Expect(Token::BREAK, CHECK_OK); |
2277 Handle<String> label; | 2277 Handle<String> label; |
2278 Token::Value tok = peek(); | 2278 Token::Value tok = peek(); |
2279 if (!scanner().HasAnyLineTerminatorBeforeNext() && | 2279 if (!scanner().HasAnyLineTerminatorBeforeNext() && |
2280 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { | 2280 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { |
2281 label = ParseIdentifier(CHECK_OK); | 2281 label = ParseIdentifier(CHECK_OK); |
2282 } | 2282 } |
2283 // Parse labeled break statements that target themselves into | 2283 // Parse labeled break statements that target themselves into |
2284 // empty statements, e.g. 'l1: l2: l3: break l2;' | 2284 // empty statements, e.g. 'l1: l2: l3: break l2;' |
2285 if (!label.is_null() && ContainsLabel(labels, label)) { | 2285 if (!label.is_null() && ContainsLabel(labels, label)) { |
2286 ExpectSemicolon(CHECK_OK); | 2286 ExpectSemicolon(CHECK_OK); |
2287 return factory()->NewEmptyStatement(); | 2287 return factory()->NewEmptyStatement(pos); |
2288 } | 2288 } |
2289 BreakableStatement* target = NULL; | 2289 BreakableStatement* target = NULL; |
2290 target = LookupBreakTarget(label, CHECK_OK); | 2290 target = LookupBreakTarget(label, CHECK_OK); |
2291 if (target == NULL) { | 2291 if (target == NULL) { |
2292 // Illegal break statement. | 2292 // Illegal break statement. |
2293 const char* message = "illegal_break"; | 2293 const char* message = "illegal_break"; |
2294 Vector<Handle<String> > args; | 2294 Vector<Handle<String> > args; |
2295 if (!label.is_null()) { | 2295 if (!label.is_null()) { |
2296 message = "unknown_label"; | 2296 message = "unknown_label"; |
2297 args = Vector<Handle<String> >(&label, 1); | 2297 args = Vector<Handle<String> >(&label, 1); |
2298 } | 2298 } |
2299 ReportMessageAt(scanner().location(), message, args); | 2299 ReportMessageAt(scanner().location(), message, args); |
2300 *ok = false; | 2300 *ok = false; |
2301 return NULL; | 2301 return NULL; |
2302 } | 2302 } |
2303 ExpectSemicolon(CHECK_OK); | 2303 ExpectSemicolon(CHECK_OK); |
2304 return factory()->NewBreakStatement(target); | 2304 return factory()->NewBreakStatement(target, pos); |
2305 } | 2305 } |
2306 | 2306 |
2307 | 2307 |
2308 Statement* Parser::ParseReturnStatement(bool* ok) { | 2308 Statement* Parser::ParseReturnStatement(bool* ok) { |
2309 // ReturnStatement :: | 2309 // ReturnStatement :: |
2310 // 'return' Expression? ';' | 2310 // 'return' Expression? ';' |
2311 | 2311 |
2312 // Consume the return token. It is necessary to do the before | 2312 // Consume the return token. It is necessary to do that before |
2313 // reporting any errors on it, because of the way errors are | 2313 // reporting any errors on it, because of the way errors are |
2314 // reported (underlining). | 2314 // reported (underlining). |
2315 Expect(Token::RETURN, CHECK_OK); | 2315 Expect(Token::RETURN, CHECK_OK); |
2316 int pos = position(); | |
2316 | 2317 |
2317 Token::Value tok = peek(); | 2318 Token::Value tok = peek(); |
2318 Statement* result; | 2319 Statement* result; |
2319 Expression* return_value; | 2320 Expression* return_value; |
2320 if (scanner().HasAnyLineTerminatorBeforeNext() || | 2321 if (scanner().HasAnyLineTerminatorBeforeNext() || |
2321 tok == Token::SEMICOLON || | 2322 tok == Token::SEMICOLON || |
2322 tok == Token::RBRACE || | 2323 tok == Token::RBRACE || |
2323 tok == Token::EOS) { | 2324 tok == Token::EOS) { |
2324 return_value = GetLiteralUndefined(); | 2325 return_value = GetLiteralUndefined(position()); |
2325 } else { | 2326 } else { |
2326 return_value = ParseExpression(true, CHECK_OK); | 2327 return_value = ParseExpression(true, CHECK_OK); |
2327 } | 2328 } |
2328 ExpectSemicolon(CHECK_OK); | 2329 ExpectSemicolon(CHECK_OK); |
2329 if (is_generator()) { | 2330 if (is_generator()) { |
2330 Expression* generator = factory()->NewVariableProxy( | 2331 Expression* generator = factory()->NewVariableProxy( |
2331 current_function_state_->generator_object_variable()); | 2332 current_function_state_->generator_object_variable()); |
2332 Expression* yield = factory()->NewYield( | 2333 Expression* yield = factory()->NewYield( |
2333 generator, return_value, Yield::FINAL, RelocInfo::kNoPosition); | 2334 generator, return_value, Yield::FINAL, pos); |
2334 result = factory()->NewExpressionStatement(yield); | 2335 result = factory()->NewExpressionStatement(yield, pos); |
2335 } else { | 2336 } else { |
2336 result = factory()->NewReturnStatement(return_value); | 2337 result = factory()->NewReturnStatement(return_value, pos); |
2337 } | 2338 } |
2338 | 2339 |
2339 // An ECMAScript program is considered syntactically incorrect if it | 2340 // An ECMAScript program is considered syntactically incorrect if it |
2340 // contains a return statement that is not within the body of a | 2341 // contains a return statement that is not within the body of a |
2341 // function. See ECMA-262, section 12.9, page 67. | 2342 // function. See ECMA-262, section 12.9, page 67. |
2342 // | 2343 // |
2343 // To be consistent with KJS we report the syntax error at runtime. | 2344 // To be consistent with KJS we report the syntax error at runtime. |
2344 Scope* declaration_scope = top_scope_->DeclarationScope(); | 2345 Scope* declaration_scope = top_scope_->DeclarationScope(); |
2345 if (declaration_scope->is_global_scope() || | 2346 if (declaration_scope->is_global_scope() || |
2346 declaration_scope->is_eval_scope()) { | 2347 declaration_scope->is_eval_scope()) { |
2347 Handle<String> message = isolate()->factory()->illegal_return_string(); | 2348 Handle<String> message = isolate()->factory()->illegal_return_string(); |
2348 Expression* throw_error = | 2349 Expression* throw_error = |
2349 NewThrowSyntaxError(message, Handle<Object>::null()); | 2350 NewThrowSyntaxError(message, Handle<Object>::null()); |
2350 return factory()->NewExpressionStatement(throw_error); | 2351 return factory()->NewExpressionStatement(throw_error, pos); |
2351 } | 2352 } |
2352 return result; | 2353 return result; |
2353 } | 2354 } |
2354 | 2355 |
2355 | 2356 |
2356 Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) { | 2357 Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) { |
2357 // WithStatement :: | 2358 // WithStatement :: |
2358 // 'with' '(' Expression ')' Statement | 2359 // 'with' '(' Expression ')' Statement |
2359 | 2360 |
2360 Expect(Token::WITH, CHECK_OK); | 2361 Expect(Token::WITH, CHECK_OK); |
2362 int pos = position(); | |
2361 | 2363 |
2362 if (!top_scope_->is_classic_mode()) { | 2364 if (!top_scope_->is_classic_mode()) { |
2363 ReportMessage("strict_mode_with", Vector<const char*>::empty()); | 2365 ReportMessage("strict_mode_with", Vector<const char*>::empty()); |
2364 *ok = false; | 2366 *ok = false; |
2365 return NULL; | 2367 return NULL; |
2366 } | 2368 } |
2367 | 2369 |
2368 Expect(Token::LPAREN, CHECK_OK); | 2370 Expect(Token::LPAREN, CHECK_OK); |
2369 Expression* expr = ParseExpression(true, CHECK_OK); | 2371 Expression* expr = ParseExpression(true, CHECK_OK); |
2370 Expect(Token::RPAREN, CHECK_OK); | 2372 Expect(Token::RPAREN, CHECK_OK); |
2371 | 2373 |
2372 top_scope_->DeclarationScope()->RecordWithStatement(); | 2374 top_scope_->DeclarationScope()->RecordWithStatement(); |
2373 Scope* with_scope = NewScope(top_scope_, WITH_SCOPE); | 2375 Scope* with_scope = NewScope(top_scope_, WITH_SCOPE); |
2374 Statement* stmt; | 2376 Statement* stmt; |
2375 { BlockState block_state(this, with_scope); | 2377 { BlockState block_state(this, with_scope); |
2376 with_scope->set_start_position(scanner().peek_location().beg_pos); | 2378 with_scope->set_start_position(scanner().peek_location().beg_pos); |
2377 stmt = ParseStatement(labels, CHECK_OK); | 2379 stmt = ParseStatement(labels, CHECK_OK); |
2378 with_scope->set_end_position(scanner().location().end_pos); | 2380 with_scope->set_end_position(scanner().location().end_pos); |
2379 } | 2381 } |
2380 return factory()->NewWithStatement(with_scope, expr, stmt); | 2382 return factory()->NewWithStatement(with_scope, expr, stmt, pos); |
2381 } | 2383 } |
2382 | 2384 |
2383 | 2385 |
2384 CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) { | 2386 CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) { |
2385 // CaseClause :: | 2387 // CaseClause :: |
2386 // 'case' Expression ':' Statement* | 2388 // 'case' Expression ':' Statement* |
2387 // 'default' ':' Statement* | 2389 // 'default' ':' Statement* |
2388 | 2390 |
2389 Expression* label = NULL; // NULL expression indicates default case | 2391 Expression* label = NULL; // NULL expression indicates default case |
2390 if (peek() == Token::CASE) { | 2392 if (peek() == Token::CASE) { |
2391 Expect(Token::CASE, CHECK_OK); | 2393 Expect(Token::CASE, CHECK_OK); |
2392 label = ParseExpression(true, CHECK_OK); | 2394 label = ParseExpression(true, CHECK_OK); |
2393 } else { | 2395 } else { |
2394 Expect(Token::DEFAULT, CHECK_OK); | 2396 Expect(Token::DEFAULT, CHECK_OK); |
2395 if (*default_seen_ptr) { | 2397 if (*default_seen_ptr) { |
2396 ReportMessage("multiple_defaults_in_switch", | 2398 ReportMessage("multiple_defaults_in_switch", |
2397 Vector<const char*>::empty()); | 2399 Vector<const char*>::empty()); |
2398 *ok = false; | 2400 *ok = false; |
2399 return NULL; | 2401 return NULL; |
2400 } | 2402 } |
2401 *default_seen_ptr = true; | 2403 *default_seen_ptr = true; |
2402 } | 2404 } |
2403 Expect(Token::COLON, CHECK_OK); | 2405 Expect(Token::COLON, CHECK_OK); |
2404 int pos = scanner().location().beg_pos; | 2406 int pos = position(); |
2405 ZoneList<Statement*>* statements = | 2407 ZoneList<Statement*>* statements = |
2406 new(zone()) ZoneList<Statement*>(5, zone()); | 2408 new(zone()) ZoneList<Statement*>(5, zone()); |
2407 while (peek() != Token::CASE && | 2409 while (peek() != Token::CASE && |
2408 peek() != Token::DEFAULT && | 2410 peek() != Token::DEFAULT && |
2409 peek() != Token::RBRACE) { | 2411 peek() != Token::RBRACE) { |
2410 Statement* stat = ParseStatement(NULL, CHECK_OK); | 2412 Statement* stat = ParseStatement(NULL, CHECK_OK); |
2411 statements->Add(stat, zone()); | 2413 statements->Add(stat, zone()); |
2412 } | 2414 } |
2413 | 2415 |
2414 return new(zone()) CaseClause(isolate(), label, statements, pos); | 2416 return new(zone()) CaseClause(isolate(), label, statements, pos); |
2415 } | 2417 } |
2416 | 2418 |
2417 | 2419 |
2418 SwitchStatement* Parser::ParseSwitchStatement(ZoneStringList* labels, | 2420 SwitchStatement* Parser::ParseSwitchStatement(ZoneStringList* labels, |
2419 bool* ok) { | 2421 bool* ok) { |
2420 // SwitchStatement :: | 2422 // SwitchStatement :: |
2421 // 'switch' '(' Expression ')' '{' CaseClause* '}' | 2423 // 'switch' '(' Expression ')' '{' CaseClause* '}' |
2422 | 2424 |
2423 SwitchStatement* statement = factory()->NewSwitchStatement(labels); | 2425 SwitchStatement* statement = |
2426 factory()->NewSwitchStatement(labels, peek_position()); | |
2424 Target target(&this->target_stack_, statement); | 2427 Target target(&this->target_stack_, statement); |
2425 | 2428 |
2426 Expect(Token::SWITCH, CHECK_OK); | 2429 Expect(Token::SWITCH, CHECK_OK); |
2427 Expect(Token::LPAREN, CHECK_OK); | 2430 Expect(Token::LPAREN, CHECK_OK); |
2428 Expression* tag = ParseExpression(true, CHECK_OK); | 2431 Expression* tag = ParseExpression(true, CHECK_OK); |
2429 Expect(Token::RPAREN, CHECK_OK); | 2432 Expect(Token::RPAREN, CHECK_OK); |
2430 | 2433 |
2431 bool default_seen = false; | 2434 bool default_seen = false; |
2432 ZoneList<CaseClause*>* cases = new(zone()) ZoneList<CaseClause*>(4, zone()); | 2435 ZoneList<CaseClause*>* cases = new(zone()) ZoneList<CaseClause*>(4, zone()); |
2433 Expect(Token::LBRACE, CHECK_OK); | 2436 Expect(Token::LBRACE, CHECK_OK); |
2434 while (peek() != Token::RBRACE) { | 2437 while (peek() != Token::RBRACE) { |
2435 CaseClause* clause = ParseCaseClause(&default_seen, CHECK_OK); | 2438 CaseClause* clause = ParseCaseClause(&default_seen, CHECK_OK); |
2436 cases->Add(clause, zone()); | 2439 cases->Add(clause, zone()); |
2437 } | 2440 } |
2438 Expect(Token::RBRACE, CHECK_OK); | 2441 Expect(Token::RBRACE, CHECK_OK); |
2439 | 2442 |
2440 if (statement) statement->Initialize(tag, cases); | 2443 if (statement) statement->Initialize(tag, cases); |
2441 return statement; | 2444 return statement; |
2442 } | 2445 } |
2443 | 2446 |
2444 | 2447 |
2445 Statement* Parser::ParseThrowStatement(bool* ok) { | 2448 Statement* Parser::ParseThrowStatement(bool* ok) { |
2446 // ThrowStatement :: | 2449 // ThrowStatement :: |
2447 // 'throw' Expression ';' | 2450 // 'throw' Expression ';' |
2448 | 2451 |
2449 Expect(Token::THROW, CHECK_OK); | 2452 Expect(Token::THROW, CHECK_OK); |
2450 int pos = scanner().location().beg_pos; | 2453 int pos = position(); |
2451 if (scanner().HasAnyLineTerminatorBeforeNext()) { | 2454 if (scanner().HasAnyLineTerminatorBeforeNext()) { |
2452 ReportMessage("newline_after_throw", Vector<const char*>::empty()); | 2455 ReportMessage("newline_after_throw", Vector<const char*>::empty()); |
2453 *ok = false; | 2456 *ok = false; |
2454 return NULL; | 2457 return NULL; |
2455 } | 2458 } |
2456 Expression* exception = ParseExpression(true, CHECK_OK); | 2459 Expression* exception = ParseExpression(true, CHECK_OK); |
2457 ExpectSemicolon(CHECK_OK); | 2460 ExpectSemicolon(CHECK_OK); |
2458 | 2461 |
2459 return factory()->NewExpressionStatement(factory()->NewThrow(exception, pos)); | 2462 return factory()->NewExpressionStatement( |
2463 factory()->NewThrow(exception, pos), pos); | |
2460 } | 2464 } |
2461 | 2465 |
2462 | 2466 |
2463 TryStatement* Parser::ParseTryStatement(bool* ok) { | 2467 TryStatement* Parser::ParseTryStatement(bool* ok) { |
2464 // TryStatement :: | 2468 // TryStatement :: |
2465 // 'try' Block Catch | 2469 // 'try' Block Catch |
2466 // 'try' Block Finally | 2470 // 'try' Block Finally |
2467 // 'try' Block Catch Finally | 2471 // 'try' Block Catch Finally |
2468 // | 2472 // |
2469 // Catch :: | 2473 // Catch :: |
2470 // 'catch' '(' Identifier ')' Block | 2474 // 'catch' '(' Identifier ')' Block |
2471 // | 2475 // |
2472 // Finally :: | 2476 // Finally :: |
2473 // 'finally' Block | 2477 // 'finally' Block |
2474 | 2478 |
2475 Expect(Token::TRY, CHECK_OK); | 2479 Expect(Token::TRY, CHECK_OK); |
2480 int pos = position(); | |
2476 | 2481 |
2477 TargetCollector try_collector(zone()); | 2482 TargetCollector try_collector(zone()); |
2478 Block* try_block; | 2483 Block* try_block; |
2479 | 2484 |
2480 { Target target(&this->target_stack_, &try_collector); | 2485 { Target target(&this->target_stack_, &try_collector); |
2481 try_block = ParseBlock(NULL, CHECK_OK); | 2486 try_block = ParseBlock(NULL, CHECK_OK); |
2482 } | 2487 } |
2483 | 2488 |
2484 Token::Value tok = peek(); | 2489 Token::Value tok = peek(); |
2485 if (tok != Token::CATCH && tok != Token::FINALLY) { | 2490 if (tok != Token::CATCH && tok != Token::FINALLY) { |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2537 // Simplify the AST nodes by converting: | 2542 // Simplify the AST nodes by converting: |
2538 // 'try B0 catch B1 finally B2' | 2543 // 'try B0 catch B1 finally B2' |
2539 // to: | 2544 // to: |
2540 // 'try { try B0 catch B1 } finally B2' | 2545 // 'try { try B0 catch B1 } finally B2' |
2541 | 2546 |
2542 if (catch_block != NULL && finally_block != NULL) { | 2547 if (catch_block != NULL && finally_block != NULL) { |
2543 // If we have both, create an inner try/catch. | 2548 // If we have both, create an inner try/catch. |
2544 ASSERT(catch_scope != NULL && catch_variable != NULL); | 2549 ASSERT(catch_scope != NULL && catch_variable != NULL); |
2545 int index = current_function_state_->NextHandlerIndex(); | 2550 int index = current_function_state_->NextHandlerIndex(); |
2546 TryCatchStatement* statement = factory()->NewTryCatchStatement( | 2551 TryCatchStatement* statement = factory()->NewTryCatchStatement( |
2547 index, try_block, catch_scope, catch_variable, catch_block); | 2552 index, try_block, catch_scope, catch_variable, catch_block, |
2553 RelocInfo::kNoPosition); | |
2548 statement->set_escaping_targets(try_collector.targets()); | 2554 statement->set_escaping_targets(try_collector.targets()); |
2549 try_block = factory()->NewBlock(NULL, 1, false); | 2555 try_block = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition); |
2550 try_block->AddStatement(statement, zone()); | 2556 try_block->AddStatement(statement, zone()); |
2551 catch_block = NULL; // Clear to indicate it's been handled. | 2557 catch_block = NULL; // Clear to indicate it's been handled. |
2552 } | 2558 } |
2553 | 2559 |
2554 TryStatement* result = NULL; | 2560 TryStatement* result = NULL; |
2555 if (catch_block != NULL) { | 2561 if (catch_block != NULL) { |
2556 ASSERT(finally_block == NULL); | 2562 ASSERT(finally_block == NULL); |
2557 ASSERT(catch_scope != NULL && catch_variable != NULL); | 2563 ASSERT(catch_scope != NULL && catch_variable != NULL); |
2558 int index = current_function_state_->NextHandlerIndex(); | 2564 int index = current_function_state_->NextHandlerIndex(); |
2559 result = factory()->NewTryCatchStatement( | 2565 result = factory()->NewTryCatchStatement( |
2560 index, try_block, catch_scope, catch_variable, catch_block); | 2566 index, try_block, catch_scope, catch_variable, catch_block, pos); |
2561 } else { | 2567 } else { |
2562 ASSERT(finally_block != NULL); | 2568 ASSERT(finally_block != NULL); |
2563 int index = current_function_state_->NextHandlerIndex(); | 2569 int index = current_function_state_->NextHandlerIndex(); |
2564 result = factory()->NewTryFinallyStatement(index, try_block, finally_block); | 2570 result = factory()->NewTryFinallyStatement( |
2571 index, try_block, finally_block, pos); | |
2565 // Combine the jump targets of the try block and the possible catch block. | 2572 // Combine the jump targets of the try block and the possible catch block. |
2566 try_collector.targets()->AddAll(*catch_collector.targets(), zone()); | 2573 try_collector.targets()->AddAll(*catch_collector.targets(), zone()); |
2567 } | 2574 } |
2568 | 2575 |
2569 result->set_escaping_targets(try_collector.targets()); | 2576 result->set_escaping_targets(try_collector.targets()); |
2570 return result; | 2577 return result; |
2571 } | 2578 } |
2572 | 2579 |
2573 | 2580 |
2574 DoWhileStatement* Parser::ParseDoWhileStatement(ZoneStringList* labels, | 2581 DoWhileStatement* Parser::ParseDoWhileStatement(ZoneStringList* labels, |
2575 bool* ok) { | 2582 bool* ok) { |
2576 // DoStatement :: | 2583 // DoStatement :: |
2577 // 'do' Statement 'while' '(' Expression ')' ';' | 2584 // 'do' Statement 'while' '(' Expression ')' ';' |
2578 | 2585 |
2579 DoWhileStatement* loop = factory()->NewDoWhileStatement(labels); | 2586 DoWhileStatement* loop = |
2587 factory()->NewDoWhileStatement(labels, peek_position()); | |
2580 Target target(&this->target_stack_, loop); | 2588 Target target(&this->target_stack_, loop); |
2581 | 2589 |
2582 Expect(Token::DO, CHECK_OK); | 2590 Expect(Token::DO, CHECK_OK); |
2583 Statement* body = ParseStatement(NULL, CHECK_OK); | 2591 Statement* body = ParseStatement(NULL, CHECK_OK); |
2584 Expect(Token::WHILE, CHECK_OK); | 2592 Expect(Token::WHILE, CHECK_OK); |
2585 Expect(Token::LPAREN, CHECK_OK); | 2593 Expect(Token::LPAREN, CHECK_OK); |
2586 | 2594 |
2587 if (loop != NULL) { | 2595 if (loop != NULL) loop->set_condition_position(position()); |
2588 int position = scanner().location().beg_pos; | |
2589 loop->set_condition_position(position); | |
2590 } | |
2591 | 2596 |
2592 Expression* cond = ParseExpression(true, CHECK_OK); | 2597 Expression* cond = ParseExpression(true, CHECK_OK); |
2593 Expect(Token::RPAREN, CHECK_OK); | 2598 Expect(Token::RPAREN, CHECK_OK); |
2594 | 2599 |
2595 // Allow do-statements to be terminated with and without | 2600 // Allow do-statements to be terminated with and without |
2596 // semi-colons. This allows code such as 'do;while(0)return' to | 2601 // semi-colons. This allows code such as 'do;while(0)return' to |
2597 // parse, which would not be the case if we had used the | 2602 // parse, which would not be the case if we had used the |
2598 // ExpectSemicolon() functionality here. | 2603 // ExpectSemicolon() functionality here. |
2599 if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON); | 2604 if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON); |
2600 | 2605 |
2601 if (loop != NULL) loop->Initialize(cond, body); | 2606 if (loop != NULL) loop->Initialize(cond, body); |
2602 return loop; | 2607 return loop; |
2603 } | 2608 } |
2604 | 2609 |
2605 | 2610 |
2606 WhileStatement* Parser::ParseWhileStatement(ZoneStringList* labels, bool* ok) { | 2611 WhileStatement* Parser::ParseWhileStatement(ZoneStringList* labels, bool* ok) { |
2607 // WhileStatement :: | 2612 // WhileStatement :: |
2608 // 'while' '(' Expression ')' Statement | 2613 // 'while' '(' Expression ')' Statement |
2609 | 2614 |
2610 WhileStatement* loop = factory()->NewWhileStatement(labels); | 2615 WhileStatement* loop = factory()->NewWhileStatement(labels, peek_position()); |
2611 Target target(&this->target_stack_, loop); | 2616 Target target(&this->target_stack_, loop); |
2612 | 2617 |
2613 Expect(Token::WHILE, CHECK_OK); | 2618 Expect(Token::WHILE, CHECK_OK); |
2614 Expect(Token::LPAREN, CHECK_OK); | 2619 Expect(Token::LPAREN, CHECK_OK); |
2615 Expression* cond = ParseExpression(true, CHECK_OK); | 2620 Expression* cond = ParseExpression(true, CHECK_OK); |
2616 Expect(Token::RPAREN, CHECK_OK); | 2621 Expect(Token::RPAREN, CHECK_OK); |
2617 Statement* body = ParseStatement(NULL, CHECK_OK); | 2622 Statement* body = ParseStatement(NULL, CHECK_OK); |
2618 | 2623 |
2619 if (loop != NULL) loop->Initialize(cond, body); | 2624 if (loop != NULL) loop->Initialize(cond, body); |
2620 return loop; | 2625 return loop; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2659 // var iterator = iterable; | 2664 // var iterator = iterable; |
2660 { | 2665 { |
2661 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); | 2666 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); |
2662 assign_iterator = factory()->NewAssignment( | 2667 assign_iterator = factory()->NewAssignment( |
2663 Token::ASSIGN, iterator_proxy, subject, RelocInfo::kNoPosition); | 2668 Token::ASSIGN, iterator_proxy, subject, RelocInfo::kNoPosition); |
2664 } | 2669 } |
2665 | 2670 |
2666 // var result = iterator.next(); | 2671 // var result = iterator.next(); |
2667 { | 2672 { |
2668 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); | 2673 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); |
2669 Expression* next_literal = | 2674 Expression* next_literal = factory()->NewLiteral( |
2670 factory()->NewLiteral(heap_factory->next_string()); | 2675 heap_factory->next_string(), RelocInfo::kNoPosition); |
2671 Expression* next_property = factory()->NewProperty( | 2676 Expression* next_property = factory()->NewProperty( |
2672 iterator_proxy, next_literal, RelocInfo::kNoPosition); | 2677 iterator_proxy, next_literal, RelocInfo::kNoPosition); |
2673 ZoneList<Expression*>* next_arguments = | 2678 ZoneList<Expression*>* next_arguments = |
2674 new(zone()) ZoneList<Expression*>(0, zone()); | 2679 new(zone()) ZoneList<Expression*>(0, zone()); |
2675 Expression* next_call = factory()->NewCall( | 2680 Expression* next_call = factory()->NewCall( |
2676 next_property, next_arguments, RelocInfo::kNoPosition); | 2681 next_property, next_arguments, RelocInfo::kNoPosition); |
2677 Expression* result_proxy = factory()->NewVariableProxy(result); | 2682 Expression* result_proxy = factory()->NewVariableProxy(result); |
2678 next_result = factory()->NewAssignment( | 2683 next_result = factory()->NewAssignment( |
2679 Token::ASSIGN, result_proxy, next_call, RelocInfo::kNoPosition); | 2684 Token::ASSIGN, result_proxy, next_call, RelocInfo::kNoPosition); |
2680 } | 2685 } |
2681 | 2686 |
2682 // result.done | 2687 // result.done |
2683 { | 2688 { |
2684 Expression* done_literal = | 2689 Expression* done_literal = factory()->NewLiteral( |
2685 factory()->NewLiteral(heap_factory->done_string()); | 2690 heap_factory->done_string(), RelocInfo::kNoPosition); |
2686 Expression* result_proxy = factory()->NewVariableProxy(result); | 2691 Expression* result_proxy = factory()->NewVariableProxy(result); |
2687 result_done = factory()->NewProperty( | 2692 result_done = factory()->NewProperty( |
2688 result_proxy, done_literal, RelocInfo::kNoPosition); | 2693 result_proxy, done_literal, RelocInfo::kNoPosition); |
2689 } | 2694 } |
2690 | 2695 |
2691 // each = result.value | 2696 // each = result.value |
2692 { | 2697 { |
2693 Expression* value_literal = | 2698 Expression* value_literal = factory()->NewLiteral( |
2694 factory()->NewLiteral(heap_factory->value_string()); | 2699 heap_factory->value_string(), RelocInfo::kNoPosition); |
2695 Expression* result_proxy = factory()->NewVariableProxy(result); | 2700 Expression* result_proxy = factory()->NewVariableProxy(result); |
2696 Expression* result_value = factory()->NewProperty( | 2701 Expression* result_value = factory()->NewProperty( |
2697 result_proxy, value_literal, RelocInfo::kNoPosition); | 2702 result_proxy, value_literal, RelocInfo::kNoPosition); |
2698 assign_each = factory()->NewAssignment( | 2703 assign_each = factory()->NewAssignment( |
2699 Token::ASSIGN, each, result_value, RelocInfo::kNoPosition); | 2704 Token::ASSIGN, each, result_value, RelocInfo::kNoPosition); |
2700 } | 2705 } |
2701 | 2706 |
2702 for_of->Initialize(each, subject, body, | 2707 for_of->Initialize(each, subject, body, |
2703 assign_iterator, next_result, result_done, assign_each); | 2708 assign_iterator, next_result, result_done, assign_each); |
2704 } else { | 2709 } else { |
2705 stmt->Initialize(each, subject, body); | 2710 stmt->Initialize(each, subject, body); |
2706 } | 2711 } |
2707 } | 2712 } |
2708 | 2713 |
2709 | 2714 |
2710 Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { | 2715 Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { |
2711 // ForStatement :: | 2716 // ForStatement :: |
2712 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement | 2717 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement |
2713 | 2718 |
2719 int pos = peek_position(); | |
2714 Statement* init = NULL; | 2720 Statement* init = NULL; |
2715 | 2721 |
2716 // Create an in-between scope for let-bound iteration variables. | 2722 // Create an in-between scope for let-bound iteration variables. |
2717 Scope* saved_scope = top_scope_; | 2723 Scope* saved_scope = top_scope_; |
2718 Scope* for_scope = NewScope(top_scope_, BLOCK_SCOPE); | 2724 Scope* for_scope = NewScope(top_scope_, BLOCK_SCOPE); |
2719 top_scope_ = for_scope; | 2725 top_scope_ = for_scope; |
2720 | 2726 |
2721 Expect(Token::FOR, CHECK_OK); | 2727 Expect(Token::FOR, CHECK_OK); |
2722 Expect(Token::LPAREN, CHECK_OK); | 2728 Expect(Token::LPAREN, CHECK_OK); |
2723 for_scope->set_start_position(scanner().location().beg_pos); | 2729 for_scope->set_start_position(scanner().location().beg_pos); |
2724 if (peek() != Token::SEMICOLON) { | 2730 if (peek() != Token::SEMICOLON) { |
2725 if (peek() == Token::VAR || peek() == Token::CONST) { | 2731 if (peek() == Token::VAR || peek() == Token::CONST) { |
2726 bool is_const = peek() == Token::CONST; | 2732 bool is_const = peek() == Token::CONST; |
2727 Handle<String> name; | 2733 Handle<String> name; |
2728 VariableDeclarationProperties decl_props = kHasNoInitializers; | 2734 VariableDeclarationProperties decl_props = kHasNoInitializers; |
2729 Block* variable_statement = | 2735 Block* variable_statement = |
2730 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name, | 2736 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name, |
2731 CHECK_OK); | 2737 CHECK_OK); |
2732 bool accept_OF = decl_props == kHasNoInitializers; | 2738 bool accept_OF = decl_props == kHasNoInitializers; |
2733 ForEachStatement::VisitMode mode; | 2739 ForEachStatement::VisitMode mode; |
2734 | 2740 |
2735 if (!name.is_null() && CheckInOrOf(accept_OF, &mode)) { | 2741 if (!name.is_null() && CheckInOrOf(accept_OF, &mode)) { |
2736 Interface* interface = | 2742 Interface* interface = |
2737 is_const ? Interface::NewConst() : Interface::NewValue(); | 2743 is_const ? Interface::NewConst() : Interface::NewValue(); |
2738 ForEachStatement* loop = factory()->NewForEachStatement(mode, labels); | 2744 ForEachStatement* loop = |
2745 factory()->NewForEachStatement(mode, labels, pos); | |
2739 Target target(&this->target_stack_, loop); | 2746 Target target(&this->target_stack_, loop); |
2740 | 2747 |
2741 Expression* enumerable = ParseExpression(true, CHECK_OK); | 2748 Expression* enumerable = ParseExpression(true, CHECK_OK); |
2742 Expect(Token::RPAREN, CHECK_OK); | 2749 Expect(Token::RPAREN, CHECK_OK); |
2743 | 2750 |
2744 VariableProxy* each = | 2751 VariableProxy* each = |
2745 top_scope_->NewUnresolved(factory(), name, interface); | 2752 top_scope_->NewUnresolved(factory(), name, interface); |
2746 Statement* body = ParseStatement(NULL, CHECK_OK); | 2753 Statement* body = ParseStatement(NULL, CHECK_OK); |
2747 InitializeForEachStatement(loop, each, enumerable, body); | 2754 InitializeForEachStatement(loop, each, enumerable, body); |
2748 Block* result = factory()->NewBlock(NULL, 2, false); | 2755 Block* result = |
2756 factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition); | |
2749 result->AddStatement(variable_statement, zone()); | 2757 result->AddStatement(variable_statement, zone()); |
2750 result->AddStatement(loop, zone()); | 2758 result->AddStatement(loop, zone()); |
2751 top_scope_ = saved_scope; | 2759 top_scope_ = saved_scope; |
2752 for_scope->set_end_position(scanner().location().end_pos); | 2760 for_scope->set_end_position(scanner().location().end_pos); |
2753 for_scope = for_scope->FinalizeBlockScope(); | 2761 for_scope = for_scope->FinalizeBlockScope(); |
2754 ASSERT(for_scope == NULL); | 2762 ASSERT(for_scope == NULL); |
2755 // Parsed for-in loop w/ variable/const declaration. | 2763 // Parsed for-in loop w/ variable/const declaration. |
2756 return result; | 2764 return result; |
2757 } else { | 2765 } else { |
2758 init = variable_statement; | 2766 init = variable_statement; |
(...skipping 23 matching lines...) Expand all Loading... | |
2782 // } | 2790 // } |
2783 | 2791 |
2784 // TODO(keuchel): Move the temporary variable to the block scope, after | 2792 // TODO(keuchel): Move the temporary variable to the block scope, after |
2785 // implementing stack allocated block scoped variables. | 2793 // implementing stack allocated block scoped variables. |
2786 Factory* heap_factory = isolate()->factory(); | 2794 Factory* heap_factory = isolate()->factory(); |
2787 Handle<String> tempstr = | 2795 Handle<String> tempstr = |
2788 heap_factory->NewConsString(heap_factory->dot_for_string(), name); | 2796 heap_factory->NewConsString(heap_factory->dot_for_string(), name); |
2789 Handle<String> tempname = heap_factory->InternalizeString(tempstr); | 2797 Handle<String> tempname = heap_factory->InternalizeString(tempstr); |
2790 Variable* temp = top_scope_->DeclarationScope()->NewTemporary(tempname); | 2798 Variable* temp = top_scope_->DeclarationScope()->NewTemporary(tempname); |
2791 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); | 2799 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); |
2792 ForEachStatement* loop = factory()->NewForEachStatement(mode, labels); | 2800 ForEachStatement* loop = |
2801 factory()->NewForEachStatement(mode, labels, pos); | |
2793 Target target(&this->target_stack_, loop); | 2802 Target target(&this->target_stack_, loop); |
2794 | 2803 |
2795 // The expression does not see the loop variable. | 2804 // The expression does not see the loop variable. |
2796 top_scope_ = saved_scope; | 2805 top_scope_ = saved_scope; |
2797 Expression* enumerable = ParseExpression(true, CHECK_OK); | 2806 Expression* enumerable = ParseExpression(true, CHECK_OK); |
2798 top_scope_ = for_scope; | 2807 top_scope_ = for_scope; |
2799 Expect(Token::RPAREN, CHECK_OK); | 2808 Expect(Token::RPAREN, CHECK_OK); |
2800 | 2809 |
2801 VariableProxy* each = | 2810 VariableProxy* each = |
2802 top_scope_->NewUnresolved(factory(), name, Interface::NewValue()); | 2811 top_scope_->NewUnresolved(factory(), name, Interface::NewValue()); |
2803 Statement* body = ParseStatement(NULL, CHECK_OK); | 2812 Statement* body = ParseStatement(NULL, CHECK_OK); |
2804 Block* body_block = factory()->NewBlock(NULL, 3, false); | 2813 Block* body_block = |
2814 factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition); | |
2805 Assignment* assignment = factory()->NewAssignment( | 2815 Assignment* assignment = factory()->NewAssignment( |
2806 Token::ASSIGN, each, temp_proxy, RelocInfo::kNoPosition); | 2816 Token::ASSIGN, each, temp_proxy, RelocInfo::kNoPosition); |
2807 Statement* assignment_statement = | 2817 Statement* assignment_statement = factory()->NewExpressionStatement( |
2808 factory()->NewExpressionStatement(assignment); | 2818 assignment, RelocInfo::kNoPosition); |
2809 body_block->AddStatement(variable_statement, zone()); | 2819 body_block->AddStatement(variable_statement, zone()); |
2810 body_block->AddStatement(assignment_statement, zone()); | 2820 body_block->AddStatement(assignment_statement, zone()); |
2811 body_block->AddStatement(body, zone()); | 2821 body_block->AddStatement(body, zone()); |
2812 InitializeForEachStatement(loop, temp_proxy, enumerable, body_block); | 2822 InitializeForEachStatement(loop, temp_proxy, enumerable, body_block); |
2813 top_scope_ = saved_scope; | 2823 top_scope_ = saved_scope; |
2814 for_scope->set_end_position(scanner().location().end_pos); | 2824 for_scope->set_end_position(scanner().location().end_pos); |
2815 for_scope = for_scope->FinalizeBlockScope(); | 2825 for_scope = for_scope->FinalizeBlockScope(); |
2816 body_block->set_scope(for_scope); | 2826 body_block->set_scope(for_scope); |
2817 // Parsed for-in loop w/ let declaration. | 2827 // Parsed for-in loop w/ let declaration. |
2818 return loop; | 2828 return loop; |
2819 | 2829 |
2820 } else { | 2830 } else { |
2821 init = variable_statement; | 2831 init = variable_statement; |
2822 } | 2832 } |
2823 } else { | 2833 } else { |
2824 Expression* expression = ParseExpression(false, CHECK_OK); | 2834 Expression* expression = ParseExpression(false, CHECK_OK); |
2825 ForEachStatement::VisitMode mode; | 2835 ForEachStatement::VisitMode mode; |
2826 bool accept_OF = expression->AsVariableProxy(); | 2836 bool accept_OF = expression->AsVariableProxy(); |
2827 | 2837 |
2828 if (CheckInOrOf(accept_OF, &mode)) { | 2838 if (CheckInOrOf(accept_OF, &mode)) { |
2829 // Signal a reference error if the expression is an invalid | 2839 // Signal a reference error if the expression is an invalid |
2830 // left-hand side expression. We could report this as a syntax | 2840 // left-hand side expression. We could report this as a syntax |
2831 // error here but for compatibility with JSC we choose to report | 2841 // error here but for compatibility with JSC we choose to report |
2832 // the error at runtime. | 2842 // the error at runtime. |
2833 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 2843 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
2834 Handle<String> message = | 2844 Handle<String> message = |
2835 isolate()->factory()->invalid_lhs_in_for_in_string(); | 2845 isolate()->factory()->invalid_lhs_in_for_in_string(); |
2836 expression = NewThrowReferenceError(message); | 2846 expression = NewThrowReferenceError(message); |
2837 } | 2847 } |
2838 ForEachStatement* loop = factory()->NewForEachStatement(mode, labels); | 2848 ForEachStatement* loop = |
2849 factory()->NewForEachStatement(mode, labels, pos); | |
2839 Target target(&this->target_stack_, loop); | 2850 Target target(&this->target_stack_, loop); |
2840 | 2851 |
2841 Expression* enumerable = ParseExpression(true, CHECK_OK); | 2852 Expression* enumerable = ParseExpression(true, CHECK_OK); |
2842 Expect(Token::RPAREN, CHECK_OK); | 2853 Expect(Token::RPAREN, CHECK_OK); |
2843 | 2854 |
2844 Statement* body = ParseStatement(NULL, CHECK_OK); | 2855 Statement* body = ParseStatement(NULL, CHECK_OK); |
2845 InitializeForEachStatement(loop, expression, enumerable, body); | 2856 InitializeForEachStatement(loop, expression, enumerable, body); |
2846 top_scope_ = saved_scope; | 2857 top_scope_ = saved_scope; |
2847 for_scope->set_end_position(scanner().location().end_pos); | 2858 for_scope->set_end_position(scanner().location().end_pos); |
2848 for_scope = for_scope->FinalizeBlockScope(); | 2859 for_scope = for_scope->FinalizeBlockScope(); |
2849 ASSERT(for_scope == NULL); | 2860 ASSERT(for_scope == NULL); |
2850 // Parsed for-in loop. | 2861 // Parsed for-in loop. |
2851 return loop; | 2862 return loop; |
2852 | 2863 |
2853 } else { | 2864 } else { |
2854 init = factory()->NewExpressionStatement(expression); | 2865 init = factory()->NewExpressionStatement( |
2866 expression, RelocInfo::kNoPosition); | |
2855 } | 2867 } |
2856 } | 2868 } |
2857 } | 2869 } |
2858 | 2870 |
2859 // Standard 'for' loop | 2871 // Standard 'for' loop |
2860 ForStatement* loop = factory()->NewForStatement(labels); | 2872 ForStatement* loop = factory()->NewForStatement(labels, pos); |
2861 Target target(&this->target_stack_, loop); | 2873 Target target(&this->target_stack_, loop); |
2862 | 2874 |
2863 // Parsed initializer at this point. | 2875 // Parsed initializer at this point. |
2864 Expect(Token::SEMICOLON, CHECK_OK); | 2876 Expect(Token::SEMICOLON, CHECK_OK); |
2865 | 2877 |
2866 Expression* cond = NULL; | 2878 Expression* cond = NULL; |
2867 if (peek() != Token::SEMICOLON) { | 2879 if (peek() != Token::SEMICOLON) { |
2868 cond = ParseExpression(true, CHECK_OK); | 2880 cond = ParseExpression(true, CHECK_OK); |
2869 } | 2881 } |
2870 Expect(Token::SEMICOLON, CHECK_OK); | 2882 Expect(Token::SEMICOLON, CHECK_OK); |
2871 | 2883 |
2872 Statement* next = NULL; | 2884 Statement* next = NULL; |
2873 if (peek() != Token::RPAREN) { | 2885 if (peek() != Token::RPAREN) { |
2874 Expression* exp = ParseExpression(true, CHECK_OK); | 2886 Expression* exp = ParseExpression(true, CHECK_OK); |
2875 next = factory()->NewExpressionStatement(exp); | 2887 next = factory()->NewExpressionStatement(exp, RelocInfo::kNoPosition); |
2876 } | 2888 } |
2877 Expect(Token::RPAREN, CHECK_OK); | 2889 Expect(Token::RPAREN, CHECK_OK); |
2878 | 2890 |
2879 Statement* body = ParseStatement(NULL, CHECK_OK); | 2891 Statement* body = ParseStatement(NULL, CHECK_OK); |
2880 top_scope_ = saved_scope; | 2892 top_scope_ = saved_scope; |
2881 for_scope->set_end_position(scanner().location().end_pos); | 2893 for_scope->set_end_position(scanner().location().end_pos); |
2882 for_scope = for_scope->FinalizeBlockScope(); | 2894 for_scope = for_scope->FinalizeBlockScope(); |
2883 if (for_scope != NULL) { | 2895 if (for_scope != NULL) { |
2884 // Rewrite a for statement of the form | 2896 // Rewrite a for statement of the form |
2885 // | 2897 // |
2886 // for (let x = i; c; n) b | 2898 // for (let x = i; c; n) b |
2887 // | 2899 // |
2888 // into | 2900 // into |
2889 // | 2901 // |
2890 // { | 2902 // { |
2891 // let x = i; | 2903 // let x = i; |
2892 // for (; c; n) b | 2904 // for (; c; n) b |
2893 // } | 2905 // } |
2894 ASSERT(init != NULL); | 2906 ASSERT(init != NULL); |
2895 Block* result = factory()->NewBlock(NULL, 2, false); | 2907 Block* result = factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition); |
2896 result->AddStatement(init, zone()); | 2908 result->AddStatement(init, zone()); |
2897 result->AddStatement(loop, zone()); | 2909 result->AddStatement(loop, zone()); |
2898 result->set_scope(for_scope); | 2910 result->set_scope(for_scope); |
2899 loop->Initialize(NULL, cond, next, body); | 2911 loop->Initialize(NULL, cond, next, body); |
2900 return result; | 2912 return result; |
2901 } else { | 2913 } else { |
2902 loop->Initialize(init, cond, next, body); | 2914 loop->Initialize(init, cond, next, body); |
2903 return loop; | 2915 return loop; |
2904 } | 2916 } |
2905 } | 2917 } |
2906 | 2918 |
2907 | 2919 |
2908 // Precedence = 1 | 2920 // Precedence = 1 |
2909 Expression* Parser::ParseExpression(bool accept_IN, bool* ok) { | 2921 Expression* Parser::ParseExpression(bool accept_IN, bool* ok) { |
2910 // Expression :: | 2922 // Expression :: |
2911 // AssignmentExpression | 2923 // AssignmentExpression |
2912 // Expression ',' AssignmentExpression | 2924 // Expression ',' AssignmentExpression |
2913 | 2925 |
2914 Expression* result = ParseAssignmentExpression(accept_IN, CHECK_OK); | 2926 Expression* result = ParseAssignmentExpression(accept_IN, CHECK_OK); |
2915 while (peek() == Token::COMMA) { | 2927 while (peek() == Token::COMMA) { |
2916 Expect(Token::COMMA, CHECK_OK); | 2928 Expect(Token::COMMA, CHECK_OK); |
2917 int position = scanner().location().beg_pos; | 2929 int pos = position(); |
2918 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); | 2930 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); |
2919 result = | 2931 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos); |
2920 factory()->NewBinaryOperation(Token::COMMA, result, right, position); | |
2921 } | 2932 } |
2922 return result; | 2933 return result; |
2923 } | 2934 } |
2924 | 2935 |
2925 | 2936 |
2926 // Precedence = 2 | 2937 // Precedence = 2 |
2927 Expression* Parser::ParseAssignmentExpression(bool accept_IN, bool* ok) { | 2938 Expression* Parser::ParseAssignmentExpression(bool accept_IN, bool* ok) { |
2928 // AssignmentExpression :: | 2939 // AssignmentExpression :: |
2929 // ConditionalExpression | 2940 // ConditionalExpression |
2930 // YieldExpression | 2941 // YieldExpression |
(...skipping 23 matching lines...) Expand all Loading... | |
2954 expression = NewThrowReferenceError(message); | 2965 expression = NewThrowReferenceError(message); |
2955 } | 2966 } |
2956 | 2967 |
2957 if (!top_scope_->is_classic_mode()) { | 2968 if (!top_scope_->is_classic_mode()) { |
2958 // Assignment to eval or arguments is disallowed in strict mode. | 2969 // Assignment to eval or arguments is disallowed in strict mode. |
2959 CheckStrictModeLValue(expression, "strict_lhs_assignment", CHECK_OK); | 2970 CheckStrictModeLValue(expression, "strict_lhs_assignment", CHECK_OK); |
2960 } | 2971 } |
2961 MarkAsLValue(expression); | 2972 MarkAsLValue(expression); |
2962 | 2973 |
2963 Token::Value op = Next(); // Get assignment operator. | 2974 Token::Value op = Next(); // Get assignment operator. |
2964 int pos = scanner().location().beg_pos; | 2975 int pos = position(); |
2965 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); | 2976 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); |
2966 | 2977 |
2967 // TODO(1231235): We try to estimate the set of properties set by | 2978 // TODO(1231235): We try to estimate the set of properties set by |
2968 // constructors. We define a new property whenever there is an | 2979 // constructors. We define a new property whenever there is an |
2969 // assignment to a property of 'this'. We should probably only add | 2980 // assignment to a property of 'this'. We should probably only add |
2970 // properties if we haven't seen them before. Otherwise we'll | 2981 // properties if we haven't seen them before. Otherwise we'll |
2971 // probably overestimate the number of properties. | 2982 // probably overestimate the number of properties. |
2972 Property* property = expression ? expression->AsProperty() : NULL; | 2983 Property* property = expression ? expression->AsProperty() : NULL; |
2973 if (op == Token::ASSIGN && | 2984 if (op == Token::ASSIGN && |
2974 property != NULL && | 2985 property != NULL && |
(...skipping 23 matching lines...) Expand all Loading... | |
2998 fni_->Leave(); | 3009 fni_->Leave(); |
2999 } | 3010 } |
3000 | 3011 |
3001 return factory()->NewAssignment(op, expression, right, pos); | 3012 return factory()->NewAssignment(op, expression, right, pos); |
3002 } | 3013 } |
3003 | 3014 |
3004 | 3015 |
3005 Expression* Parser::ParseYieldExpression(bool* ok) { | 3016 Expression* Parser::ParseYieldExpression(bool* ok) { |
3006 // YieldExpression :: | 3017 // YieldExpression :: |
3007 // 'yield' '*'? AssignmentExpression | 3018 // 'yield' '*'? AssignmentExpression |
3008 int position = scanner().peek_location().beg_pos; | 3019 int pos = peek_position(); |
3009 Expect(Token::YIELD, CHECK_OK); | 3020 Expect(Token::YIELD, CHECK_OK); |
3010 Yield::Kind kind = | 3021 Yield::Kind kind = |
3011 Check(Token::MUL) ? Yield::DELEGATING : Yield::SUSPEND; | 3022 Check(Token::MUL) ? Yield::DELEGATING : Yield::SUSPEND; |
3012 Expression* generator_object = factory()->NewVariableProxy( | 3023 Expression* generator_object = factory()->NewVariableProxy( |
3013 current_function_state_->generator_object_variable()); | 3024 current_function_state_->generator_object_variable()); |
3014 Expression* expression = ParseAssignmentExpression(false, CHECK_OK); | 3025 Expression* expression = ParseAssignmentExpression(false, CHECK_OK); |
3015 Yield* yield = | 3026 Yield* yield = factory()->NewYield(generator_object, expression, kind, pos); |
3016 factory()->NewYield(generator_object, expression, kind, position); | |
3017 if (kind == Yield::DELEGATING) { | 3027 if (kind == Yield::DELEGATING) { |
3018 yield->set_index(current_function_state_->NextHandlerIndex()); | 3028 yield->set_index(current_function_state_->NextHandlerIndex()); |
3019 } | 3029 } |
3020 return yield; | 3030 return yield; |
3021 } | 3031 } |
3022 | 3032 |
3023 | 3033 |
3024 // Precedence = 3 | 3034 // Precedence = 3 |
3025 Expression* Parser::ParseConditionalExpression(bool accept_IN, bool* ok) { | 3035 Expression* Parser::ParseConditionalExpression(bool accept_IN, bool* ok) { |
3026 // ConditionalExpression :: | 3036 // ConditionalExpression :: |
3027 // LogicalOrExpression | 3037 // LogicalOrExpression |
3028 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression | 3038 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression |
3029 | 3039 |
3040 int pos = peek_position(); | |
3030 // We start using the binary expression parser for prec >= 4 only! | 3041 // We start using the binary expression parser for prec >= 4 only! |
3031 Expression* expression = ParseBinaryExpression(4, accept_IN, CHECK_OK); | 3042 Expression* expression = ParseBinaryExpression(4, accept_IN, CHECK_OK); |
3032 if (peek() != Token::CONDITIONAL) return expression; | 3043 if (peek() != Token::CONDITIONAL) return expression; |
3033 Consume(Token::CONDITIONAL); | 3044 Consume(Token::CONDITIONAL); |
3034 // In parsing the first assignment expression in conditional | 3045 // In parsing the first assignment expression in conditional |
3035 // expressions we always accept the 'in' keyword; see ECMA-262, | 3046 // expressions we always accept the 'in' keyword; see ECMA-262, |
3036 // section 11.12, page 58. | 3047 // section 11.12, page 58. |
3037 int left_position = scanner().peek_location().beg_pos; | 3048 int left_position = peek_position(); |
3038 Expression* left = ParseAssignmentExpression(true, CHECK_OK); | 3049 Expression* left = ParseAssignmentExpression(true, CHECK_OK); |
3039 Expect(Token::COLON, CHECK_OK); | 3050 Expect(Token::COLON, CHECK_OK); |
3040 int right_position = scanner().peek_location().beg_pos; | 3051 int right_position = peek_position(); |
3041 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); | 3052 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); |
3042 return factory()->NewConditional( | 3053 return factory()->NewConditional( |
3043 expression, left, right, left_position, right_position); | 3054 expression, left, right, left_position, right_position, pos); |
3044 } | 3055 } |
3045 | 3056 |
3046 | 3057 |
3047 static int Precedence(Token::Value tok, bool accept_IN) { | 3058 static int Precedence(Token::Value tok, bool accept_IN) { |
3048 if (tok == Token::IN && !accept_IN) | 3059 if (tok == Token::IN && !accept_IN) |
3049 return 0; // 0 precedence will terminate binary expression parsing | 3060 return 0; // 0 precedence will terminate binary expression parsing |
3050 | 3061 |
3051 return Token::Precedence(tok); | 3062 return Token::Precedence(tok); |
3052 } | 3063 } |
3053 | 3064 |
3054 | 3065 |
3055 // Precedence >= 4 | 3066 // Precedence >= 4 |
3056 Expression* Parser::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) { | 3067 Expression* Parser::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) { |
3057 ASSERT(prec >= 4); | 3068 ASSERT(prec >= 4); |
3058 Expression* x = ParseUnaryExpression(CHECK_OK); | 3069 Expression* x = ParseUnaryExpression(CHECK_OK); |
3059 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { | 3070 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { |
3060 // prec1 >= 4 | 3071 // prec1 >= 4 |
3061 while (Precedence(peek(), accept_IN) == prec1) { | 3072 while (Precedence(peek(), accept_IN) == prec1) { |
3062 Token::Value op = Next(); | 3073 Token::Value op = Next(); |
3063 int position = scanner().location().beg_pos; | 3074 int pos = position(); |
3064 Expression* y = ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK); | 3075 Expression* y = ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK); |
3065 | 3076 |
3066 // Compute some expressions involving only number literals. | 3077 // Compute some expressions involving only number literals. |
3067 if (x && x->AsLiteral() && x->AsLiteral()->value()->IsNumber() && | 3078 if (x && x->AsLiteral() && x->AsLiteral()->value()->IsNumber() && |
3068 y && y->AsLiteral() && y->AsLiteral()->value()->IsNumber()) { | 3079 y && y->AsLiteral() && y->AsLiteral()->value()->IsNumber()) { |
3069 double x_val = x->AsLiteral()->value()->Number(); | 3080 double x_val = x->AsLiteral()->value()->Number(); |
3070 double y_val = y->AsLiteral()->value()->Number(); | 3081 double y_val = y->AsLiteral()->value()->Number(); |
3071 | 3082 |
3072 switch (op) { | 3083 switch (op) { |
3073 case Token::ADD: | 3084 case Token::ADD: |
3074 x = factory()->NewNumberLiteral(x_val + y_val); | 3085 x = factory()->NewNumberLiteral(x_val + y_val, pos); |
3075 continue; | 3086 continue; |
3076 case Token::SUB: | 3087 case Token::SUB: |
3077 x = factory()->NewNumberLiteral(x_val - y_val); | 3088 x = factory()->NewNumberLiteral(x_val - y_val, pos); |
3078 continue; | 3089 continue; |
3079 case Token::MUL: | 3090 case Token::MUL: |
3080 x = factory()->NewNumberLiteral(x_val * y_val); | 3091 x = factory()->NewNumberLiteral(x_val * y_val, pos); |
3081 continue; | 3092 continue; |
3082 case Token::DIV: | 3093 case Token::DIV: |
3083 x = factory()->NewNumberLiteral(x_val / y_val); | 3094 x = factory()->NewNumberLiteral(x_val / y_val, pos); |
3084 continue; | 3095 continue; |
3085 case Token::BIT_OR: { | 3096 case Token::BIT_OR: { |
3086 int value = DoubleToInt32(x_val) | DoubleToInt32(y_val); | 3097 int value = DoubleToInt32(x_val) | DoubleToInt32(y_val); |
3087 x = factory()->NewNumberLiteral(value); | 3098 x = factory()->NewNumberLiteral(value, pos); |
3088 continue; | 3099 continue; |
3089 } | 3100 } |
3090 case Token::BIT_AND: { | 3101 case Token::BIT_AND: { |
3091 int value = DoubleToInt32(x_val) & DoubleToInt32(y_val); | 3102 int value = DoubleToInt32(x_val) & DoubleToInt32(y_val); |
3092 x = factory()->NewNumberLiteral(value); | 3103 x = factory()->NewNumberLiteral(value, pos); |
3093 continue; | 3104 continue; |
3094 } | 3105 } |
3095 case Token::BIT_XOR: { | 3106 case Token::BIT_XOR: { |
3096 int value = DoubleToInt32(x_val) ^ DoubleToInt32(y_val); | 3107 int value = DoubleToInt32(x_val) ^ DoubleToInt32(y_val); |
3097 x = factory()->NewNumberLiteral(value); | 3108 x = factory()->NewNumberLiteral(value, pos); |
3098 continue; | 3109 continue; |
3099 } | 3110 } |
3100 case Token::SHL: { | 3111 case Token::SHL: { |
3101 int value = DoubleToInt32(x_val) << (DoubleToInt32(y_val) & 0x1f); | 3112 int value = DoubleToInt32(x_val) << (DoubleToInt32(y_val) & 0x1f); |
3102 x = factory()->NewNumberLiteral(value); | 3113 x = factory()->NewNumberLiteral(value, pos); |
3103 continue; | 3114 continue; |
3104 } | 3115 } |
3105 case Token::SHR: { | 3116 case Token::SHR: { |
3106 uint32_t shift = DoubleToInt32(y_val) & 0x1f; | 3117 uint32_t shift = DoubleToInt32(y_val) & 0x1f; |
3107 uint32_t value = DoubleToUint32(x_val) >> shift; | 3118 uint32_t value = DoubleToUint32(x_val) >> shift; |
3108 x = factory()->NewNumberLiteral(value); | 3119 x = factory()->NewNumberLiteral(value, pos); |
3109 continue; | 3120 continue; |
3110 } | 3121 } |
3111 case Token::SAR: { | 3122 case Token::SAR: { |
3112 uint32_t shift = DoubleToInt32(y_val) & 0x1f; | 3123 uint32_t shift = DoubleToInt32(y_val) & 0x1f; |
3113 int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift); | 3124 int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift); |
3114 x = factory()->NewNumberLiteral(value); | 3125 x = factory()->NewNumberLiteral(value, pos); |
3115 continue; | 3126 continue; |
3116 } | 3127 } |
3117 default: | 3128 default: |
3118 break; | 3129 break; |
3119 } | 3130 } |
3120 } | 3131 } |
3121 | 3132 |
3122 // For now we distinguish between comparisons and other binary | 3133 // For now we distinguish between comparisons and other binary |
3123 // operations. (We could combine the two and get rid of this | 3134 // operations. (We could combine the two and get rid of this |
3124 // code and AST node eventually.) | 3135 // code and AST node eventually.) |
3125 if (Token::IsCompareOp(op)) { | 3136 if (Token::IsCompareOp(op)) { |
3126 // We have a comparison. | 3137 // We have a comparison. |
3127 Token::Value cmp = op; | 3138 Token::Value cmp = op; |
3128 switch (op) { | 3139 switch (op) { |
3129 case Token::NE: cmp = Token::EQ; break; | 3140 case Token::NE: cmp = Token::EQ; break; |
3130 case Token::NE_STRICT: cmp = Token::EQ_STRICT; break; | 3141 case Token::NE_STRICT: cmp = Token::EQ_STRICT; break; |
3131 default: break; | 3142 default: break; |
3132 } | 3143 } |
3133 x = factory()->NewCompareOperation(cmp, x, y, position); | 3144 x = factory()->NewCompareOperation(cmp, x, y, pos); |
3134 if (cmp != op) { | 3145 if (cmp != op) { |
3135 // The comparison was negated - add a NOT. | 3146 // The comparison was negated - add a NOT. |
3136 x = factory()->NewUnaryOperation(Token::NOT, x, position); | 3147 x = factory()->NewUnaryOperation(Token::NOT, x, pos); |
3137 } | 3148 } |
3138 | 3149 |
3139 } else { | 3150 } else { |
3140 // We have a "normal" binary operation. | 3151 // We have a "normal" binary operation. |
3141 x = factory()->NewBinaryOperation(op, x, y, position); | 3152 x = factory()->NewBinaryOperation(op, x, y, pos); |
3142 } | 3153 } |
3143 } | 3154 } |
3144 } | 3155 } |
3145 return x; | 3156 return x; |
3146 } | 3157 } |
3147 | 3158 |
3148 | 3159 |
3149 Expression* Parser::ParseUnaryExpression(bool* ok) { | 3160 Expression* Parser::ParseUnaryExpression(bool* ok) { |
3150 // UnaryExpression :: | 3161 // UnaryExpression :: |
3151 // PostfixExpression | 3162 // PostfixExpression |
3152 // 'delete' UnaryExpression | 3163 // 'delete' UnaryExpression |
3153 // 'void' UnaryExpression | 3164 // 'void' UnaryExpression |
3154 // 'typeof' UnaryExpression | 3165 // 'typeof' UnaryExpression |
3155 // '++' UnaryExpression | 3166 // '++' UnaryExpression |
3156 // '--' UnaryExpression | 3167 // '--' UnaryExpression |
3157 // '+' UnaryExpression | 3168 // '+' UnaryExpression |
3158 // '-' UnaryExpression | 3169 // '-' UnaryExpression |
3159 // '~' UnaryExpression | 3170 // '~' UnaryExpression |
3160 // '!' UnaryExpression | 3171 // '!' UnaryExpression |
3161 | 3172 |
3162 Token::Value op = peek(); | 3173 Token::Value op = peek(); |
3163 if (Token::IsUnaryOp(op)) { | 3174 if (Token::IsUnaryOp(op)) { |
3164 op = Next(); | 3175 op = Next(); |
3165 int position = scanner().location().beg_pos; | 3176 int pos = position(); |
3166 Expression* expression = ParseUnaryExpression(CHECK_OK); | 3177 Expression* expression = ParseUnaryExpression(CHECK_OK); |
3167 | 3178 |
3168 if (expression != NULL && (expression->AsLiteral() != NULL)) { | 3179 if (expression != NULL && (expression->AsLiteral() != NULL)) { |
3169 Handle<Object> literal = expression->AsLiteral()->value(); | 3180 Handle<Object> literal = expression->AsLiteral()->value(); |
3170 if (op == Token::NOT) { | 3181 if (op == Token::NOT) { |
3171 // Convert the literal to a boolean condition and negate it. | 3182 // Convert the literal to a boolean condition and negate it. |
3172 bool condition = literal->BooleanValue(); | 3183 bool condition = literal->BooleanValue(); |
3173 Handle<Object> result(isolate()->heap()->ToBoolean(!condition), | 3184 Handle<Object> result(isolate()->heap()->ToBoolean(!condition), |
3174 isolate()); | 3185 isolate()); |
3175 return factory()->NewLiteral(result); | 3186 return factory()->NewLiteral(result, pos); |
3176 } else if (literal->IsNumber()) { | 3187 } else if (literal->IsNumber()) { |
3177 // Compute some expressions involving only number literals. | 3188 // Compute some expressions involving only number literals. |
3178 double value = literal->Number(); | 3189 double value = literal->Number(); |
3179 switch (op) { | 3190 switch (op) { |
3180 case Token::ADD: | 3191 case Token::ADD: |
3181 return expression; | 3192 return expression; |
3182 case Token::SUB: | 3193 case Token::SUB: |
3183 return factory()->NewNumberLiteral(-value); | 3194 return factory()->NewNumberLiteral(-value, pos); |
3184 case Token::BIT_NOT: | 3195 case Token::BIT_NOT: |
3185 return factory()->NewNumberLiteral(~DoubleToInt32(value)); | 3196 return factory()->NewNumberLiteral(~DoubleToInt32(value), pos); |
3186 default: | 3197 default: |
3187 break; | 3198 break; |
3188 } | 3199 } |
3189 } | 3200 } |
3190 } | 3201 } |
3191 | 3202 |
3192 // "delete identifier" is a syntax error in strict mode. | 3203 // "delete identifier" is a syntax error in strict mode. |
3193 if (op == Token::DELETE && !top_scope_->is_classic_mode()) { | 3204 if (op == Token::DELETE && !top_scope_->is_classic_mode()) { |
3194 VariableProxy* operand = expression->AsVariableProxy(); | 3205 VariableProxy* operand = expression->AsVariableProxy(); |
3195 if (operand != NULL && !operand->is_this()) { | 3206 if (operand != NULL && !operand->is_this()) { |
3196 ReportMessage("strict_delete", Vector<const char*>::empty()); | 3207 ReportMessage("strict_delete", Vector<const char*>::empty()); |
3197 *ok = false; | 3208 *ok = false; |
3198 return NULL; | 3209 return NULL; |
3199 } | 3210 } |
3200 } | 3211 } |
3201 | 3212 |
3202 // Desugar '+foo' into 'foo*1', this enables the collection of type feedback | 3213 // Desugar '+foo' into 'foo*1', this enables the collection of type feedback |
3203 // without any special stub and the multiplication is removed later in | 3214 // without any special stub and the multiplication is removed later in |
3204 // Crankshaft's canonicalization pass. | 3215 // Crankshaft's canonicalization pass. |
3205 if (op == Token::ADD) { | 3216 if (op == Token::ADD) { |
3206 return factory()->NewBinaryOperation(Token::MUL, | 3217 return factory()->NewBinaryOperation(Token::MUL, |
3207 expression, | 3218 expression, |
3208 factory()->NewNumberLiteral(1), | 3219 factory()->NewNumberLiteral(1, pos), |
3209 position); | 3220 pos); |
3210 } | 3221 } |
3211 // The same idea for '-foo' => 'foo*(-1)'. | 3222 // The same idea for '-foo' => 'foo*(-1)'. |
3212 if (op == Token::SUB) { | 3223 if (op == Token::SUB) { |
3213 return factory()->NewBinaryOperation(Token::MUL, | 3224 return factory()->NewBinaryOperation(Token::MUL, |
3214 expression, | 3225 expression, |
3215 factory()->NewNumberLiteral(-1), | 3226 factory()->NewNumberLiteral(-1, pos), |
3216 position); | 3227 pos); |
3217 } | 3228 } |
3218 // ...and one more time for '~foo' => 'foo^(~0)'. | 3229 // ...and one more time for '~foo' => 'foo^(~0)'. |
3219 if (op == Token::BIT_NOT) { | 3230 if (op == Token::BIT_NOT) { |
3220 return factory()->NewBinaryOperation(Token::BIT_XOR, | 3231 return factory()->NewBinaryOperation(Token::BIT_XOR, |
3221 expression, | 3232 expression, |
3222 factory()->NewNumberLiteral(~0), | 3233 factory()->NewNumberLiteral(~0, pos), |
3223 position); | 3234 pos); |
3224 } | 3235 } |
3225 | 3236 |
3226 return factory()->NewUnaryOperation(op, expression, position); | 3237 return factory()->NewUnaryOperation(op, expression, pos); |
3227 | 3238 |
3228 } else if (Token::IsCountOp(op)) { | 3239 } else if (Token::IsCountOp(op)) { |
3229 op = Next(); | 3240 op = Next(); |
3230 Expression* expression = ParseUnaryExpression(CHECK_OK); | 3241 Expression* expression = ParseUnaryExpression(CHECK_OK); |
3231 // Signal a reference error if the expression is an invalid | 3242 // Signal a reference error if the expression is an invalid |
3232 // left-hand side expression. We could report this as a syntax | 3243 // left-hand side expression. We could report this as a syntax |
3233 // error here but for compatibility with JSC we choose to report the | 3244 // error here but for compatibility with JSC we choose to report the |
3234 // error at runtime. | 3245 // error at runtime. |
3235 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 3246 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
3236 Handle<String> message = | 3247 Handle<String> message = |
3237 isolate()->factory()->invalid_lhs_in_prefix_op_string(); | 3248 isolate()->factory()->invalid_lhs_in_prefix_op_string(); |
3238 expression = NewThrowReferenceError(message); | 3249 expression = NewThrowReferenceError(message); |
3239 } | 3250 } |
3240 | 3251 |
3241 if (!top_scope_->is_classic_mode()) { | 3252 if (!top_scope_->is_classic_mode()) { |
3242 // Prefix expression operand in strict mode may not be eval or arguments. | 3253 // Prefix expression operand in strict mode may not be eval or arguments. |
3243 CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK); | 3254 CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK); |
3244 } | 3255 } |
3245 MarkAsLValue(expression); | 3256 MarkAsLValue(expression); |
3246 | 3257 |
3247 int position = scanner().location().beg_pos; | |
3248 return factory()->NewCountOperation(op, | 3258 return factory()->NewCountOperation(op, |
3249 true /* prefix */, | 3259 true /* prefix */, |
3250 expression, | 3260 expression, |
3251 position); | 3261 position()); // TODO(rossberg): ??? |
Yang
2013/09/24 16:04:16
What does this mean?
| |
3252 | 3262 |
3253 } else { | 3263 } else { |
3254 return ParsePostfixExpression(ok); | 3264 return ParsePostfixExpression(ok); |
3255 } | 3265 } |
3256 } | 3266 } |
3257 | 3267 |
3258 | 3268 |
3259 Expression* Parser::ParsePostfixExpression(bool* ok) { | 3269 Expression* Parser::ParsePostfixExpression(bool* ok) { |
3260 // PostfixExpression :: | 3270 // PostfixExpression :: |
3261 // LeftHandSideExpression ('++' | '--')? | 3271 // LeftHandSideExpression ('++' | '--')? |
(...skipping 11 matching lines...) Expand all Loading... | |
3273 expression = NewThrowReferenceError(message); | 3283 expression = NewThrowReferenceError(message); |
3274 } | 3284 } |
3275 | 3285 |
3276 if (!top_scope_->is_classic_mode()) { | 3286 if (!top_scope_->is_classic_mode()) { |
3277 // Postfix expression operand in strict mode may not be eval or arguments. | 3287 // Postfix expression operand in strict mode may not be eval or arguments. |
3278 CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK); | 3288 CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK); |
3279 } | 3289 } |
3280 MarkAsLValue(expression); | 3290 MarkAsLValue(expression); |
3281 | 3291 |
3282 Token::Value next = Next(); | 3292 Token::Value next = Next(); |
3283 int position = scanner().location().beg_pos; | |
3284 expression = | 3293 expression = |
3285 factory()->NewCountOperation(next, | 3294 factory()->NewCountOperation(next, |
3286 false /* postfix */, | 3295 false /* postfix */, |
3287 expression, | 3296 expression, |
3288 position); | 3297 position()); // TODO(rossberg): ??? |
Yang
2013/09/24 16:04:16
Ditto.
| |
3289 } | 3298 } |
3290 return expression; | 3299 return expression; |
3291 } | 3300 } |
3292 | 3301 |
3293 | 3302 |
3294 Expression* Parser::ParseLeftHandSideExpression(bool* ok) { | 3303 Expression* Parser::ParseLeftHandSideExpression(bool* ok) { |
3295 // LeftHandSideExpression :: | 3304 // LeftHandSideExpression :: |
3296 // (NewExpression | MemberExpression) ... | 3305 // (NewExpression | MemberExpression) ... |
3297 | 3306 |
3298 Expression* result; | 3307 Expression* result; |
3299 if (peek() == Token::NEW) { | 3308 if (peek() == Token::NEW) { |
3300 result = ParseNewExpression(CHECK_OK); | 3309 result = ParseNewExpression(CHECK_OK); |
3301 } else { | 3310 } else { |
3302 result = ParseMemberExpression(CHECK_OK); | 3311 result = ParseMemberExpression(CHECK_OK); |
3303 } | 3312 } |
3304 | 3313 |
3305 while (true) { | 3314 while (true) { |
3306 switch (peek()) { | 3315 switch (peek()) { |
3307 case Token::LBRACK: { | 3316 case Token::LBRACK: { |
3308 Consume(Token::LBRACK); | 3317 Consume(Token::LBRACK); |
3309 int pos = scanner().location().beg_pos; | 3318 int pos = position(); |
3310 Expression* index = ParseExpression(true, CHECK_OK); | 3319 Expression* index = ParseExpression(true, CHECK_OK); |
3311 result = factory()->NewProperty(result, index, pos); | 3320 result = factory()->NewProperty(result, index, pos); |
3312 Expect(Token::RBRACK, CHECK_OK); | 3321 Expect(Token::RBRACK, CHECK_OK); |
3313 break; | 3322 break; |
3314 } | 3323 } |
3315 | 3324 |
3316 case Token::LPAREN: { | 3325 case Token::LPAREN: { |
3317 int pos; | 3326 int pos; |
3318 if (scanner().current_token() == Token::IDENTIFIER) { | 3327 if (scanner().current_token() == Token::IDENTIFIER) { |
3319 // For call of an identifier we want to report position of | 3328 // For call of an identifier we want to report position of |
3320 // the identifier as position of the call in the stack trace. | 3329 // the identifier as position of the call in the stack trace. |
3321 pos = scanner().location().beg_pos; | 3330 pos = position(); |
3322 } else { | 3331 } else { |
3323 // For other kinds of calls we record position of the parenthesis as | 3332 // For other kinds of calls we record position of the parenthesis as |
3324 // position of the call. Note that this is extremely important for | 3333 // position of the call. Note that this is extremely important for |
3325 // expressions of the form function(){...}() for which call position | 3334 // expressions of the form function(){...}() for which call position |
3326 // should not point to the closing brace otherwise it will intersect | 3335 // should not point to the closing brace otherwise it will intersect |
3327 // with positions recorded for function literal and confuse debugger. | 3336 // with positions recorded for function literal and confuse debugger. |
3328 pos = scanner().peek_location().beg_pos; | 3337 pos = peek_position(); |
3329 // Also the trailing parenthesis are a hint that the function will | 3338 // Also the trailing parenthesis are a hint that the function will |
3330 // be called immediately. If we happen to have parsed a preceding | 3339 // be called immediately. If we happen to have parsed a preceding |
3331 // function literal eagerly, we can also compile it eagerly. | 3340 // function literal eagerly, we can also compile it eagerly. |
3332 if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { | 3341 if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { |
3333 result->AsFunctionLiteral()->set_parenthesized(); | 3342 result->AsFunctionLiteral()->set_parenthesized(); |
3334 } | 3343 } |
3335 } | 3344 } |
3336 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); | 3345 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); |
3337 | 3346 |
3338 // Keep track of eval() calls since they disable all local variable | 3347 // Keep track of eval() calls since they disable all local variable |
3339 // optimizations. | 3348 // optimizations. |
3340 // The calls that need special treatment are the | 3349 // The calls that need special treatment are the |
3341 // direct eval calls. These calls are all of the form eval(...), with | 3350 // direct eval calls. These calls are all of the form eval(...), with |
3342 // no explicit receiver. | 3351 // no explicit receiver. |
3343 // These calls are marked as potentially direct eval calls. Whether | 3352 // These calls are marked as potentially direct eval calls. Whether |
3344 // they are actually direct calls to eval is determined at run time. | 3353 // they are actually direct calls to eval is determined at run time. |
3345 VariableProxy* callee = result->AsVariableProxy(); | 3354 VariableProxy* callee = result->AsVariableProxy(); |
3346 if (callee != NULL && | 3355 if (callee != NULL && |
3347 callee->IsVariable(isolate()->factory()->eval_string())) { | 3356 callee->IsVariable(isolate()->factory()->eval_string())) { |
3348 top_scope_->DeclarationScope()->RecordEvalCall(); | 3357 top_scope_->DeclarationScope()->RecordEvalCall(); |
3349 } | 3358 } |
3350 result = factory()->NewCall(result, args, pos); | 3359 result = factory()->NewCall(result, args, pos); |
3351 if (fni_ != NULL) fni_->RemoveLastFunction(); | 3360 if (fni_ != NULL) fni_->RemoveLastFunction(); |
3352 break; | 3361 break; |
3353 } | 3362 } |
3354 | 3363 |
3355 case Token::PERIOD: { | 3364 case Token::PERIOD: { |
3356 Consume(Token::PERIOD); | 3365 Consume(Token::PERIOD); |
3357 int pos = scanner().location().beg_pos; | 3366 int pos = position(); |
3358 Handle<String> name = ParseIdentifierName(CHECK_OK); | 3367 Handle<String> name = ParseIdentifierName(CHECK_OK); |
3359 result = | 3368 result = factory()->NewProperty( |
3360 factory()->NewProperty(result, factory()->NewLiteral(name), pos); | 3369 result, factory()->NewLiteral(name, pos), pos); |
3361 if (fni_ != NULL) fni_->PushLiteralName(name); | 3370 if (fni_ != NULL) fni_->PushLiteralName(name); |
3362 break; | 3371 break; |
3363 } | 3372 } |
3364 | 3373 |
3365 default: | 3374 default: |
3366 return result; | 3375 return result; |
3367 } | 3376 } |
3368 } | 3377 } |
3369 } | 3378 } |
3370 | 3379 |
3371 | 3380 |
3372 Expression* Parser::ParseNewPrefix(PositionStack* stack, bool* ok) { | 3381 Expression* Parser::ParseNewPrefix(PositionStack* stack, bool* ok) { |
3373 // NewExpression :: | 3382 // NewExpression :: |
3374 // ('new')+ MemberExpression | 3383 // ('new')+ MemberExpression |
3375 | 3384 |
3376 // The grammar for new expressions is pretty warped. The keyword | 3385 // The grammar for new expressions is pretty warped. The keyword |
3377 // 'new' can either be a part of the new expression (where it isn't | 3386 // 'new' can either be a part of the new expression (where it isn't |
3378 // followed by an argument list) or a part of the member expression, | 3387 // followed by an argument list) or a part of the member expression, |
3379 // where it must be followed by an argument list. To accommodate | 3388 // where it must be followed by an argument list. To accommodate |
3380 // this, we parse the 'new' keywords greedily and keep track of how | 3389 // this, we parse the 'new' keywords greedily and keep track of how |
3381 // many we have parsed. This information is then passed on to the | 3390 // many we have parsed. This information is then passed on to the |
3382 // member expression parser, which is only allowed to match argument | 3391 // member expression parser, which is only allowed to match argument |
3383 // lists as long as it has 'new' prefixes left | 3392 // lists as long as it has 'new' prefixes left |
3384 Expect(Token::NEW, CHECK_OK); | 3393 Expect(Token::NEW, CHECK_OK); |
3385 PositionStack::Element pos(stack, scanner().location().beg_pos); | 3394 PositionStack::Element pos(stack, position()); |
3386 | 3395 |
3387 Expression* result; | 3396 Expression* result; |
3388 if (peek() == Token::NEW) { | 3397 if (peek() == Token::NEW) { |
3389 result = ParseNewPrefix(stack, CHECK_OK); | 3398 result = ParseNewPrefix(stack, CHECK_OK); |
3390 } else { | 3399 } else { |
3391 result = ParseMemberWithNewPrefixesExpression(stack, CHECK_OK); | 3400 result = ParseMemberWithNewPrefixesExpression(stack, CHECK_OK); |
3392 } | 3401 } |
3393 | 3402 |
3394 if (!stack->is_empty()) { | 3403 if (!stack->is_empty()) { |
3395 int last = stack->pop(); | 3404 int last = stack->pop(); |
(...skipping 18 matching lines...) Expand all Loading... | |
3414 Expression* Parser::ParseMemberWithNewPrefixesExpression(PositionStack* stack, | 3423 Expression* Parser::ParseMemberWithNewPrefixesExpression(PositionStack* stack, |
3415 bool* ok) { | 3424 bool* ok) { |
3416 // MemberExpression :: | 3425 // MemberExpression :: |
3417 // (PrimaryExpression | FunctionLiteral) | 3426 // (PrimaryExpression | FunctionLiteral) |
3418 // ('[' Expression ']' | '.' Identifier | Arguments)* | 3427 // ('[' Expression ']' | '.' Identifier | Arguments)* |
3419 | 3428 |
3420 // Parse the initial primary or function expression. | 3429 // Parse the initial primary or function expression. |
3421 Expression* result = NULL; | 3430 Expression* result = NULL; |
3422 if (peek() == Token::FUNCTION) { | 3431 if (peek() == Token::FUNCTION) { |
3423 Expect(Token::FUNCTION, CHECK_OK); | 3432 Expect(Token::FUNCTION, CHECK_OK); |
3424 int function_token_position = scanner().location().beg_pos; | 3433 int function_token_position = position(); |
3425 bool is_generator = allow_generators() && Check(Token::MUL); | 3434 bool is_generator = allow_generators() && Check(Token::MUL); |
3426 Handle<String> name; | 3435 Handle<String> name; |
3427 bool is_strict_reserved_name = false; | 3436 bool is_strict_reserved_name = false; |
3428 if (peek_any_identifier()) { | 3437 if (peek_any_identifier()) { |
3429 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, | 3438 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, |
3430 CHECK_OK); | 3439 CHECK_OK); |
3431 } | 3440 } |
3432 FunctionLiteral::FunctionType function_type = name.is_null() | 3441 FunctionLiteral::FunctionType function_type = name.is_null() |
3433 ? FunctionLiteral::ANONYMOUS_EXPRESSION | 3442 ? FunctionLiteral::ANONYMOUS_EXPRESSION |
3434 : FunctionLiteral::NAMED_EXPRESSION; | 3443 : FunctionLiteral::NAMED_EXPRESSION; |
3435 result = ParseFunctionLiteral(name, | 3444 result = ParseFunctionLiteral(name, |
3436 is_strict_reserved_name, | 3445 is_strict_reserved_name, |
3437 is_generator, | 3446 is_generator, |
3438 function_token_position, | 3447 function_token_position, |
3439 function_type, | 3448 function_type, |
3440 CHECK_OK); | 3449 CHECK_OK); |
3441 } else { | 3450 } else { |
3442 result = ParsePrimaryExpression(CHECK_OK); | 3451 result = ParsePrimaryExpression(CHECK_OK); |
3443 } | 3452 } |
3444 | 3453 |
3445 while (true) { | 3454 while (true) { |
3446 switch (peek()) { | 3455 switch (peek()) { |
3447 case Token::LBRACK: { | 3456 case Token::LBRACK: { |
3448 Consume(Token::LBRACK); | 3457 Consume(Token::LBRACK); |
3449 int pos = scanner().location().beg_pos; | 3458 int pos = position(); |
3450 Expression* index = ParseExpression(true, CHECK_OK); | 3459 Expression* index = ParseExpression(true, CHECK_OK); |
3451 result = factory()->NewProperty(result, index, pos); | 3460 result = factory()->NewProperty(result, index, pos); |
3452 if (fni_ != NULL) { | 3461 if (fni_ != NULL) { |
3453 if (index->IsPropertyName()) { | 3462 if (index->IsPropertyName()) { |
3454 fni_->PushLiteralName(index->AsLiteral()->AsPropertyName()); | 3463 fni_->PushLiteralName(index->AsLiteral()->AsPropertyName()); |
3455 } else { | 3464 } else { |
3456 fni_->PushLiteralName( | 3465 fni_->PushLiteralName( |
3457 isolate()->factory()->anonymous_function_string()); | 3466 isolate()->factory()->anonymous_function_string()); |
3458 } | 3467 } |
3459 } | 3468 } |
3460 Expect(Token::RBRACK, CHECK_OK); | 3469 Expect(Token::RBRACK, CHECK_OK); |
3461 break; | 3470 break; |
3462 } | 3471 } |
3463 case Token::PERIOD: { | 3472 case Token::PERIOD: { |
3464 Consume(Token::PERIOD); | 3473 Consume(Token::PERIOD); |
3465 int pos = scanner().location().beg_pos; | 3474 int pos = position(); |
3466 Handle<String> name = ParseIdentifierName(CHECK_OK); | 3475 Handle<String> name = ParseIdentifierName(CHECK_OK); |
3467 result = | 3476 result = factory()->NewProperty( |
3468 factory()->NewProperty(result, factory()->NewLiteral(name), pos); | 3477 result, factory()->NewLiteral(name, pos), pos); |
3469 if (fni_ != NULL) fni_->PushLiteralName(name); | 3478 if (fni_ != NULL) fni_->PushLiteralName(name); |
3470 break; | 3479 break; |
3471 } | 3480 } |
3472 case Token::LPAREN: { | 3481 case Token::LPAREN: { |
3473 if ((stack == NULL) || stack->is_empty()) return result; | 3482 if ((stack == NULL) || stack->is_empty()) return result; |
3474 // Consume one of the new prefixes (already parsed). | 3483 // Consume one of the new prefixes (already parsed). |
3475 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); | 3484 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); |
3476 int last = stack->pop(); | 3485 int pos = stack->pop(); |
3477 result = factory()->NewCallNew(result, args, last); | 3486 result = factory()->NewCallNew(result, args, pos); |
3478 break; | 3487 break; |
3479 } | 3488 } |
3480 default: | 3489 default: |
3481 return result; | 3490 return result; |
3482 } | 3491 } |
3483 } | 3492 } |
3484 } | 3493 } |
3485 | 3494 |
3486 | 3495 |
3487 DebuggerStatement* Parser::ParseDebuggerStatement(bool* ok) { | 3496 DebuggerStatement* Parser::ParseDebuggerStatement(bool* ok) { |
3488 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser | 3497 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser |
3489 // contexts this is used as a statement which invokes the debugger as i a | 3498 // contexts this is used as a statement which invokes the debugger as i a |
3490 // break point is present. | 3499 // break point is present. |
3491 // DebuggerStatement :: | 3500 // DebuggerStatement :: |
3492 // 'debugger' ';' | 3501 // 'debugger' ';' |
3493 | 3502 |
3503 int pos = peek_position(); | |
3494 Expect(Token::DEBUGGER, CHECK_OK); | 3504 Expect(Token::DEBUGGER, CHECK_OK); |
3495 ExpectSemicolon(CHECK_OK); | 3505 ExpectSemicolon(CHECK_OK); |
3496 return factory()->NewDebuggerStatement(); | 3506 return factory()->NewDebuggerStatement(pos); |
3497 } | 3507 } |
3498 | 3508 |
3499 | 3509 |
3500 void Parser::ReportUnexpectedToken(Token::Value token) { | 3510 void Parser::ReportUnexpectedToken(Token::Value token) { |
3501 // We don't report stack overflows here, to avoid increasing the | 3511 // We don't report stack overflows here, to avoid increasing the |
3502 // stack depth even further. Instead we report it after parsing is | 3512 // stack depth even further. Instead we report it after parsing is |
3503 // over, in ParseProgram/ParseJson. | 3513 // over, in ParseProgram/ParseJson. |
3504 if (token == Token::ILLEGAL && stack_overflow_) return; | 3514 if (token == Token::ILLEGAL && stack_overflow_) return; |
3505 // Four of the tokens are treated specially | 3515 // Four of the tokens are treated specially |
3506 switch (token) { | 3516 switch (token) { |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3548 // 'true' | 3558 // 'true' |
3549 // 'false' | 3559 // 'false' |
3550 // Identifier | 3560 // Identifier |
3551 // Number | 3561 // Number |
3552 // String | 3562 // String |
3553 // ArrayLiteral | 3563 // ArrayLiteral |
3554 // ObjectLiteral | 3564 // ObjectLiteral |
3555 // RegExpLiteral | 3565 // RegExpLiteral |
3556 // '(' Expression ')' | 3566 // '(' Expression ')' |
3557 | 3567 |
3568 int pos = peek_position(); | |
3558 Expression* result = NULL; | 3569 Expression* result = NULL; |
3559 switch (peek()) { | 3570 switch (peek()) { |
3560 case Token::THIS: { | 3571 case Token::THIS: { |
3561 Consume(Token::THIS); | 3572 Consume(Token::THIS); |
3562 result = factory()->NewVariableProxy(top_scope_->receiver()); | 3573 result = factory()->NewVariableProxy(top_scope_->receiver()); |
3563 break; | 3574 break; |
3564 } | 3575 } |
3565 | 3576 |
3566 case Token::NULL_LITERAL: | 3577 case Token::NULL_LITERAL: |
3567 Consume(Token::NULL_LITERAL); | 3578 Consume(Token::NULL_LITERAL); |
3568 result = factory()->NewLiteral(isolate()->factory()->null_value()); | 3579 result = factory()->NewLiteral(isolate()->factory()->null_value(), pos); |
3569 break; | 3580 break; |
3570 | 3581 |
3571 case Token::TRUE_LITERAL: | 3582 case Token::TRUE_LITERAL: |
3572 Consume(Token::TRUE_LITERAL); | 3583 Consume(Token::TRUE_LITERAL); |
3573 result = factory()->NewLiteral(isolate()->factory()->true_value()); | 3584 result = factory()->NewLiteral(isolate()->factory()->true_value(), pos); |
3574 break; | 3585 break; |
3575 | 3586 |
3576 case Token::FALSE_LITERAL: | 3587 case Token::FALSE_LITERAL: |
3577 Consume(Token::FALSE_LITERAL); | 3588 Consume(Token::FALSE_LITERAL); |
3578 result = factory()->NewLiteral(isolate()->factory()->false_value()); | 3589 result = factory()->NewLiteral(isolate()->factory()->false_value(), pos); |
3579 break; | 3590 break; |
3580 | 3591 |
3581 case Token::IDENTIFIER: | 3592 case Token::IDENTIFIER: |
3582 case Token::YIELD: | 3593 case Token::YIELD: |
3583 case Token::FUTURE_STRICT_RESERVED_WORD: { | 3594 case Token::FUTURE_STRICT_RESERVED_WORD: { |
3584 Handle<String> name = ParseIdentifier(CHECK_OK); | 3595 Handle<String> name = ParseIdentifier(CHECK_OK); |
3585 if (fni_ != NULL) fni_->PushVariableName(name); | 3596 if (fni_ != NULL) fni_->PushVariableName(name); |
3586 // The name may refer to a module instance object, so its type is unknown. | 3597 // The name may refer to a module instance object, so its type is unknown. |
3587 #ifdef DEBUG | 3598 #ifdef DEBUG |
3588 if (FLAG_print_interface_details) | 3599 if (FLAG_print_interface_details) |
3589 PrintF("# Variable %s ", name->ToAsciiArray()); | 3600 PrintF("# Variable %s ", name->ToAsciiArray()); |
3590 #endif | 3601 #endif |
3591 Interface* interface = Interface::NewUnknown(zone()); | 3602 Interface* interface = Interface::NewUnknown(zone()); |
3592 result = top_scope_->NewUnresolved( | 3603 result = top_scope_->NewUnresolved(factory(), name, interface, pos); |
3593 factory(), name, interface, scanner().location().beg_pos); | |
3594 break; | 3604 break; |
3595 } | 3605 } |
3596 | 3606 |
3597 case Token::NUMBER: { | 3607 case Token::NUMBER: { |
3598 Consume(Token::NUMBER); | 3608 Consume(Token::NUMBER); |
3599 ASSERT(scanner().is_literal_ascii()); | 3609 ASSERT(scanner().is_literal_ascii()); |
3600 double value = StringToDouble(isolate()->unicode_cache(), | 3610 double value = StringToDouble(isolate()->unicode_cache(), |
3601 scanner().literal_ascii_string(), | 3611 scanner().literal_ascii_string(), |
3602 ALLOW_HEX | ALLOW_OCTAL | | 3612 ALLOW_HEX | ALLOW_OCTAL | |
3603 ALLOW_IMPLICIT_OCTAL | ALLOW_BINARY); | 3613 ALLOW_IMPLICIT_OCTAL | ALLOW_BINARY); |
3604 result = factory()->NewNumberLiteral(value); | 3614 result = factory()->NewNumberLiteral(value, pos); |
3605 break; | 3615 break; |
3606 } | 3616 } |
3607 | 3617 |
3608 case Token::STRING: { | 3618 case Token::STRING: { |
3609 Consume(Token::STRING); | 3619 Consume(Token::STRING); |
3610 Handle<String> symbol = GetSymbol(); | 3620 Handle<String> symbol = GetSymbol(); |
3611 result = factory()->NewLiteral(symbol); | 3621 result = factory()->NewLiteral(symbol, pos); |
3612 if (fni_ != NULL) fni_->PushLiteralName(symbol); | 3622 if (fni_ != NULL) fni_->PushLiteralName(symbol); |
3613 break; | 3623 break; |
3614 } | 3624 } |
3615 | 3625 |
3616 case Token::ASSIGN_DIV: | 3626 case Token::ASSIGN_DIV: |
3617 result = ParseRegExpLiteral(true, CHECK_OK); | 3627 result = ParseRegExpLiteral(true, CHECK_OK); |
3618 break; | 3628 break; |
3619 | 3629 |
3620 case Token::DIV: | 3630 case Token::DIV: |
3621 result = ParseRegExpLiteral(false, CHECK_OK); | 3631 result = ParseRegExpLiteral(false, CHECK_OK); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3655 } | 3665 } |
3656 | 3666 |
3657 return result; | 3667 return result; |
3658 } | 3668 } |
3659 | 3669 |
3660 | 3670 |
3661 Expression* Parser::ParseArrayLiteral(bool* ok) { | 3671 Expression* Parser::ParseArrayLiteral(bool* ok) { |
3662 // ArrayLiteral :: | 3672 // ArrayLiteral :: |
3663 // '[' Expression? (',' Expression?)* ']' | 3673 // '[' Expression? (',' Expression?)* ']' |
3664 | 3674 |
3675 int pos = peek_position(); | |
3665 ZoneList<Expression*>* values = new(zone()) ZoneList<Expression*>(4, zone()); | 3676 ZoneList<Expression*>* values = new(zone()) ZoneList<Expression*>(4, zone()); |
3666 Expect(Token::LBRACK, CHECK_OK); | 3677 Expect(Token::LBRACK, CHECK_OK); |
3667 while (peek() != Token::RBRACK) { | 3678 while (peek() != Token::RBRACK) { |
3668 Expression* elem; | 3679 Expression* elem; |
3669 if (peek() == Token::COMMA) { | 3680 if (peek() == Token::COMMA) { |
3670 elem = GetLiteralTheHole(); | 3681 elem = GetLiteralTheHole(peek_position()); |
3671 } else { | 3682 } else { |
3672 elem = ParseAssignmentExpression(true, CHECK_OK); | 3683 elem = ParseAssignmentExpression(true, CHECK_OK); |
3673 } | 3684 } |
3674 values->Add(elem, zone()); | 3685 values->Add(elem, zone()); |
3675 if (peek() != Token::RBRACK) { | 3686 if (peek() != Token::RBRACK) { |
3676 Expect(Token::COMMA, CHECK_OK); | 3687 Expect(Token::COMMA, CHECK_OK); |
3677 } | 3688 } |
3678 } | 3689 } |
3679 Expect(Token::RBRACK, CHECK_OK); | 3690 Expect(Token::RBRACK, CHECK_OK); |
3680 | 3691 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3722 // in a 2-element FixedArray. | 3733 // in a 2-element FixedArray. |
3723 Handle<FixedArray> literals = isolate()->factory()->NewFixedArray(2, TENURED); | 3734 Handle<FixedArray> literals = isolate()->factory()->NewFixedArray(2, TENURED); |
3724 | 3735 |
3725 ElementsKind kind = array->GetElementsKind(); | 3736 ElementsKind kind = array->GetElementsKind(); |
3726 kind = is_holey ? GetHoleyElementsKind(kind) : GetPackedElementsKind(kind); | 3737 kind = is_holey ? GetHoleyElementsKind(kind) : GetPackedElementsKind(kind); |
3727 | 3738 |
3728 literals->set(0, Smi::FromInt(kind)); | 3739 literals->set(0, Smi::FromInt(kind)); |
3729 literals->set(1, *element_values); | 3740 literals->set(1, *element_values); |
3730 | 3741 |
3731 return factory()->NewArrayLiteral( | 3742 return factory()->NewArrayLiteral( |
3732 literals, values, literal_index, is_simple, depth); | 3743 literals, values, literal_index, is_simple, depth, pos); |
3733 } | 3744 } |
3734 | 3745 |
3735 | 3746 |
3736 bool Parser::IsBoilerplateProperty(ObjectLiteral::Property* property) { | 3747 bool Parser::IsBoilerplateProperty(ObjectLiteral::Property* property) { |
3737 return property != NULL && | 3748 return property != NULL && |
3738 property->kind() != ObjectLiteral::Property::PROTOTYPE; | 3749 property->kind() != ObjectLiteral::Property::PROTOTYPE; |
3739 } | 3750 } |
3740 | 3751 |
3741 | 3752 |
3742 bool CompileTimeValue::IsCompileTimeValue(Expression* expression) { | 3753 bool CompileTimeValue::IsCompileTimeValue(Expression* expression) { |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3942 *depth = depth_acc; | 3953 *depth = depth_acc; |
3943 } | 3954 } |
3944 | 3955 |
3945 | 3956 |
3946 ObjectLiteral::Property* Parser::ParseObjectLiteralGetSet(bool is_getter, | 3957 ObjectLiteral::Property* Parser::ParseObjectLiteralGetSet(bool is_getter, |
3947 bool* ok) { | 3958 bool* ok) { |
3948 // Special handling of getter and setter syntax: | 3959 // Special handling of getter and setter syntax: |
3949 // { ... , get foo() { ... }, ... , set foo(v) { ... v ... } , ... } | 3960 // { ... , get foo() { ... }, ... , set foo(v) { ... v ... } , ... } |
3950 // We have already read the "get" or "set" keyword. | 3961 // We have already read the "get" or "set" keyword. |
3951 Token::Value next = Next(); | 3962 Token::Value next = Next(); |
3963 int pos = position(); | |
3952 bool is_keyword = Token::IsKeyword(next); | 3964 bool is_keyword = Token::IsKeyword(next); |
3953 if (next == Token::IDENTIFIER || next == Token::NUMBER || | 3965 if (next == Token::IDENTIFIER || next == Token::NUMBER || |
3954 next == Token::FUTURE_RESERVED_WORD || | 3966 next == Token::FUTURE_RESERVED_WORD || |
3955 next == Token::FUTURE_STRICT_RESERVED_WORD || | 3967 next == Token::FUTURE_STRICT_RESERVED_WORD || |
3956 next == Token::STRING || is_keyword) { | 3968 next == Token::STRING || is_keyword) { |
3957 Handle<String> name; | 3969 Handle<String> name; |
3958 if (is_keyword) { | 3970 if (is_keyword) { |
3959 name = isolate_->factory()->InternalizeUtf8String(Token::String(next)); | 3971 name = isolate_->factory()->InternalizeUtf8String(Token::String(next)); |
3960 } else { | 3972 } else { |
3961 name = GetSymbol(); | 3973 name = GetSymbol(); |
3962 } | 3974 } |
3963 FunctionLiteral* value = | 3975 FunctionLiteral* value = |
3964 ParseFunctionLiteral(name, | 3976 ParseFunctionLiteral(name, |
3965 false, // reserved words are allowed here | 3977 false, // reserved words are allowed here |
3966 false, // not a generator | 3978 false, // not a generator |
3967 RelocInfo::kNoPosition, | 3979 RelocInfo::kNoPosition, |
3968 FunctionLiteral::ANONYMOUS_EXPRESSION, | 3980 FunctionLiteral::ANONYMOUS_EXPRESSION, |
3969 CHECK_OK); | 3981 CHECK_OK); |
3970 // Allow any number of parameters for compatibilty with JSC. | 3982 // Allow any number of parameters for compatibilty with JSC. |
3971 // Specification only allows zero parameters for get and one for set. | 3983 // Specification only allows zero parameters for get and one for set. |
3972 return factory()->NewObjectLiteralProperty(is_getter, value); | 3984 return factory()->NewObjectLiteralProperty(is_getter, value, pos); |
3973 } else { | 3985 } else { |
3974 ReportUnexpectedToken(next); | 3986 ReportUnexpectedToken(next); |
3975 *ok = false; | 3987 *ok = false; |
3976 return NULL; | 3988 return NULL; |
3977 } | 3989 } |
3978 } | 3990 } |
3979 | 3991 |
3980 | 3992 |
3981 Expression* Parser::ParseObjectLiteral(bool* ok) { | 3993 Expression* Parser::ParseObjectLiteral(bool* ok) { |
3982 // ObjectLiteral :: | 3994 // ObjectLiteral :: |
3983 // '{' ( | 3995 // '{' ( |
3984 // ((IdentifierName | String | Number) ':' AssignmentExpression) | 3996 // ((IdentifierName | String | Number) ':' AssignmentExpression) |
3985 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) | 3997 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) |
3986 // )*[','] '}' | 3998 // )*[','] '}' |
3987 | 3999 |
4000 int pos = peek_position(); | |
3988 ZoneList<ObjectLiteral::Property*>* properties = | 4001 ZoneList<ObjectLiteral::Property*>* properties = |
3989 new(zone()) ZoneList<ObjectLiteral::Property*>(4, zone()); | 4002 new(zone()) ZoneList<ObjectLiteral::Property*>(4, zone()); |
3990 int number_of_boilerplate_properties = 0; | 4003 int number_of_boilerplate_properties = 0; |
3991 bool has_function = false; | 4004 bool has_function = false; |
3992 | 4005 |
3993 ObjectLiteralPropertyChecker checker(this, top_scope_->language_mode()); | 4006 ObjectLiteralPropertyChecker checker(this, top_scope_->language_mode()); |
3994 | 4007 |
3995 Expect(Token::LBRACE, CHECK_OK); | 4008 Expect(Token::LBRACE, CHECK_OK); |
3996 | 4009 |
3997 while (peek() != Token::RBRACE) { | 4010 while (peek() != Token::RBRACE) { |
(...skipping 29 matching lines...) Expand all Loading... | |
4027 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK); | 4040 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK); |
4028 | 4041 |
4029 if (fni_ != NULL) { | 4042 if (fni_ != NULL) { |
4030 fni_->Infer(); | 4043 fni_->Infer(); |
4031 fni_->Leave(); | 4044 fni_->Leave(); |
4032 } | 4045 } |
4033 continue; // restart the while | 4046 continue; // restart the while |
4034 } | 4047 } |
4035 // Failed to parse as get/set property, so it's just a property | 4048 // Failed to parse as get/set property, so it's just a property |
4036 // called "get" or "set". | 4049 // called "get" or "set". |
4037 key = factory()->NewLiteral(id); | 4050 key = factory()->NewLiteral(id, loc.beg_pos); |
4038 break; | 4051 break; |
4039 } | 4052 } |
4040 case Token::STRING: { | 4053 case Token::STRING: { |
4041 Consume(Token::STRING); | 4054 Consume(Token::STRING); |
4042 Handle<String> string = GetSymbol(); | 4055 Handle<String> string = GetSymbol(); |
4043 if (fni_ != NULL) fni_->PushLiteralName(string); | 4056 if (fni_ != NULL) fni_->PushLiteralName(string); |
4044 uint32_t index; | 4057 uint32_t index; |
4045 if (!string.is_null() && string->AsArrayIndex(&index)) { | 4058 if (!string.is_null() && string->AsArrayIndex(&index)) { |
4046 key = factory()->NewNumberLiteral(index); | 4059 key = factory()->NewNumberLiteral(index, loc.beg_pos); |
4047 break; | 4060 break; |
4048 } | 4061 } |
4049 key = factory()->NewLiteral(string); | 4062 key = factory()->NewLiteral(string, loc.beg_pos); |
4050 break; | 4063 break; |
4051 } | 4064 } |
4052 case Token::NUMBER: { | 4065 case Token::NUMBER: { |
4053 Consume(Token::NUMBER); | 4066 Consume(Token::NUMBER); |
4054 ASSERT(scanner().is_literal_ascii()); | 4067 ASSERT(scanner().is_literal_ascii()); |
4055 double value = StringToDouble(isolate()->unicode_cache(), | 4068 double value = StringToDouble(isolate()->unicode_cache(), |
4056 scanner().literal_ascii_string(), | 4069 scanner().literal_ascii_string(), |
4057 ALLOW_HEX | ALLOW_OCTAL | | 4070 ALLOW_HEX | ALLOW_OCTAL | |
4058 ALLOW_IMPLICIT_OCTAL | ALLOW_BINARY); | 4071 ALLOW_IMPLICIT_OCTAL | ALLOW_BINARY); |
4059 key = factory()->NewNumberLiteral(value); | 4072 key = factory()->NewNumberLiteral(value, loc.beg_pos); |
4060 break; | 4073 break; |
4061 } | 4074 } |
4062 default: | 4075 default: |
4063 if (Token::IsKeyword(next)) { | 4076 if (Token::IsKeyword(next)) { |
4064 Consume(next); | 4077 Consume(next); |
4065 Handle<String> string = GetSymbol(); | 4078 Handle<String> string = GetSymbol(); |
4066 key = factory()->NewLiteral(string); | 4079 key = factory()->NewLiteral(string, loc.beg_pos); |
4067 } else { | 4080 } else { |
4068 // Unexpected token. | 4081 // Unexpected token. |
4069 Token::Value next = Next(); | 4082 Token::Value next = Next(); |
4070 ReportUnexpectedToken(next); | 4083 ReportUnexpectedToken(next); |
4071 *ok = false; | 4084 *ok = false; |
4072 return NULL; | 4085 return NULL; |
4073 } | 4086 } |
4074 } | 4087 } |
4075 | 4088 |
4076 Expect(Token::COLON, CHECK_OK); | 4089 Expect(Token::COLON, CHECK_OK); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4120 &fast_elements, | 4133 &fast_elements, |
4121 &depth, | 4134 &depth, |
4122 &may_store_doubles); | 4135 &may_store_doubles); |
4123 return factory()->NewObjectLiteral(constant_properties, | 4136 return factory()->NewObjectLiteral(constant_properties, |
4124 properties, | 4137 properties, |
4125 literal_index, | 4138 literal_index, |
4126 is_simple, | 4139 is_simple, |
4127 fast_elements, | 4140 fast_elements, |
4128 depth, | 4141 depth, |
4129 may_store_doubles, | 4142 may_store_doubles, |
4130 has_function); | 4143 has_function, |
4144 pos); | |
4131 } | 4145 } |
4132 | 4146 |
4133 | 4147 |
4134 Expression* Parser::ParseRegExpLiteral(bool seen_equal, bool* ok) { | 4148 Expression* Parser::ParseRegExpLiteral(bool seen_equal, bool* ok) { |
4149 int pos = peek_position(); | |
4135 if (!scanner().ScanRegExpPattern(seen_equal)) { | 4150 if (!scanner().ScanRegExpPattern(seen_equal)) { |
4136 Next(); | 4151 Next(); |
4137 ReportMessage("unterminated_regexp", Vector<const char*>::empty()); | 4152 ReportMessage("unterminated_regexp", Vector<const char*>::empty()); |
4138 *ok = false; | 4153 *ok = false; |
4139 return NULL; | 4154 return NULL; |
4140 } | 4155 } |
4141 | 4156 |
4142 int literal_index = current_function_state_->NextMaterializedLiteralIndex(); | 4157 int literal_index = current_function_state_->NextMaterializedLiteralIndex(); |
4143 | 4158 |
4144 Handle<String> js_pattern = NextLiteralString(TENURED); | 4159 Handle<String> js_pattern = NextLiteralString(TENURED); |
4145 scanner().ScanRegExpFlags(); | 4160 scanner().ScanRegExpFlags(); |
4146 Handle<String> js_flags = NextLiteralString(TENURED); | 4161 Handle<String> js_flags = NextLiteralString(TENURED); |
4147 Next(); | 4162 Next(); |
4148 | 4163 |
4149 return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index); | 4164 return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos); |
4150 } | 4165 } |
4151 | 4166 |
4152 | 4167 |
4153 ZoneList<Expression*>* Parser::ParseArguments(bool* ok) { | 4168 ZoneList<Expression*>* Parser::ParseArguments(bool* ok) { |
4154 // Arguments :: | 4169 // Arguments :: |
4155 // '(' (AssignmentExpression)*[','] ')' | 4170 // '(' (AssignmentExpression)*[','] ')' |
4156 | 4171 |
4157 ZoneList<Expression*>* result = new(zone()) ZoneList<Expression*>(4, zone()); | 4172 ZoneList<Expression*>* result = new(zone()) ZoneList<Expression*>(4, zone()); |
4158 Expect(Token::LPAREN, CHECK_OK); | 4173 Expect(Token::LPAREN, CHECK_OK); |
4159 bool done = (peek() == Token::RPAREN); | 4174 bool done = (peek() == Token::RPAREN); |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4264 // For error messages. | 4279 // For error messages. |
4265 const char* message_; | 4280 const char* message_; |
4266 const char* argument_opt_; | 4281 const char* argument_opt_; |
4267 }; | 4282 }; |
4268 | 4283 |
4269 | 4284 |
4270 FunctionLiteral* Parser::ParseFunctionLiteral( | 4285 FunctionLiteral* Parser::ParseFunctionLiteral( |
4271 Handle<String> function_name, | 4286 Handle<String> function_name, |
4272 bool name_is_strict_reserved, | 4287 bool name_is_strict_reserved, |
4273 bool is_generator, | 4288 bool is_generator, |
4274 int function_token_position, | 4289 int function_token_pos, |
4275 FunctionLiteral::FunctionType function_type, | 4290 FunctionLiteral::FunctionType function_type, |
4276 bool* ok) { | 4291 bool* ok) { |
4277 // Function :: | 4292 // Function :: |
4278 // '(' FormalParameterList? ')' '{' FunctionBody '}' | 4293 // '(' FormalParameterList? ')' '{' FunctionBody '}' |
4279 | 4294 |
4295 int pos = function_token_pos == RelocInfo::kNoPosition | |
4296 ? peek_position() : function_token_pos; | |
4297 | |
4280 // Anonymous functions were passed either the empty symbol or a null | 4298 // Anonymous functions were passed either the empty symbol or a null |
4281 // handle as the function name. Remember if we were passed a non-empty | 4299 // handle as the function name. Remember if we were passed a non-empty |
4282 // handle to decide whether to invoke function name inference. | 4300 // handle to decide whether to invoke function name inference. |
4283 bool should_infer_name = function_name.is_null(); | 4301 bool should_infer_name = function_name.is_null(); |
4284 | 4302 |
4285 // We want a non-null handle as the function name. | 4303 // We want a non-null handle as the function name. |
4286 if (should_infer_name) { | 4304 if (should_infer_name) { |
4287 function_name = isolate()->factory()->empty_string(); | 4305 function_name = isolate()->factory()->empty_string(); |
4288 } | 4306 } |
4289 | 4307 |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4407 // instead of Variables and Proxis as is the case now. | 4425 // instead of Variables and Proxis as is the case now. |
4408 Variable* fvar = NULL; | 4426 Variable* fvar = NULL; |
4409 Token::Value fvar_init_op = Token::INIT_CONST; | 4427 Token::Value fvar_init_op = Token::INIT_CONST; |
4410 if (function_type == FunctionLiteral::NAMED_EXPRESSION) { | 4428 if (function_type == FunctionLiteral::NAMED_EXPRESSION) { |
4411 if (is_extended_mode()) fvar_init_op = Token::INIT_CONST_HARMONY; | 4429 if (is_extended_mode()) fvar_init_op = Token::INIT_CONST_HARMONY; |
4412 VariableMode fvar_mode = is_extended_mode() ? CONST_HARMONY : CONST; | 4430 VariableMode fvar_mode = is_extended_mode() ? CONST_HARMONY : CONST; |
4413 fvar = new(zone()) Variable(top_scope_, | 4431 fvar = new(zone()) Variable(top_scope_, |
4414 function_name, fvar_mode, true /* is valid LHS */, | 4432 function_name, fvar_mode, true /* is valid LHS */, |
4415 Variable::NORMAL, kCreatedInitialized, Interface::NewConst()); | 4433 Variable::NORMAL, kCreatedInitialized, Interface::NewConst()); |
4416 VariableProxy* proxy = factory()->NewVariableProxy(fvar); | 4434 VariableProxy* proxy = factory()->NewVariableProxy(fvar); |
4417 VariableDeclaration* fvar_declaration = | 4435 VariableDeclaration* fvar_declaration = factory()->NewVariableDeclaration( |
4418 factory()->NewVariableDeclaration(proxy, fvar_mode, top_scope_); | 4436 proxy, fvar_mode, top_scope_, RelocInfo::kNoPosition); |
4419 top_scope_->DeclareFunctionVar(fvar_declaration); | 4437 top_scope_->DeclareFunctionVar(fvar_declaration); |
4420 } | 4438 } |
4421 | 4439 |
4422 // Determine whether the function will be lazily compiled. | 4440 // Determine whether the function will be lazily compiled. |
4423 // The heuristics are: | 4441 // The heuristics are: |
4424 // - It must not have been prohibited by the caller to Parse (some callers | 4442 // - It must not have been prohibited by the caller to Parse (some callers |
4425 // need a full AST). | 4443 // need a full AST). |
4426 // - The outer scope must allow lazy compilation of inner functions. | 4444 // - The outer scope must allow lazy compilation of inner functions. |
4427 // - The function mustn't be a function expression with an open parenthesis | 4445 // - The function mustn't be a function expression with an open parenthesis |
4428 // before; we consider that a hint that the function will be called | 4446 // before; we consider that a hint that the function will be called |
4429 // immediately, and it would be a waste of time to make it lazily | 4447 // immediately, and it would be a waste of time to make it lazily |
4430 // compiled. | 4448 // compiled. |
4431 // These are all things we can know at this point, without looking at the | 4449 // These are all things we can know at this point, without looking at the |
4432 // function itself. | 4450 // function itself. |
4433 bool is_lazily_compiled = (mode() == PARSE_LAZILY && | 4451 bool is_lazily_compiled = (mode() == PARSE_LAZILY && |
4434 top_scope_->AllowsLazyCompilation() && | 4452 top_scope_->AllowsLazyCompilation() && |
4435 !parenthesized_function_); | 4453 !parenthesized_function_); |
4436 parenthesized_function_ = false; // The bit was set for this function only. | 4454 parenthesized_function_ = false; // The bit was set for this function only. |
4437 | 4455 |
4438 if (is_lazily_compiled) { | 4456 if (is_lazily_compiled) { |
4439 int function_block_pos = scanner().location().beg_pos; | 4457 int function_block_pos = position(); |
4440 FunctionEntry entry; | 4458 FunctionEntry entry; |
4441 if (pre_parse_data_ != NULL) { | 4459 if (pre_parse_data_ != NULL) { |
4442 // If we have pre_parse_data_, we use it to skip parsing the function | 4460 // If we have pre_parse_data_, we use it to skip parsing the function |
4443 // body. The preparser data contains the information we need to | 4461 // body. The preparser data contains the information we need to |
4444 // construct the lazy function. | 4462 // construct the lazy function. |
4445 entry = pre_parse_data()->GetFunctionEntry(function_block_pos); | 4463 entry = pre_parse_data()->GetFunctionEntry(function_block_pos); |
4446 if (entry.is_valid()) { | 4464 if (entry.is_valid()) { |
4447 if (entry.end_pos() <= function_block_pos) { | 4465 if (entry.end_pos() <= function_block_pos) { |
4448 // End position greater than end of stream is safe, and hard | 4466 // End position greater than end of stream is safe, and hard |
4449 // to check. | 4467 // to check. |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4498 if (!is_lazily_compiled) { | 4516 if (!is_lazily_compiled) { |
4499 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); | 4517 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); |
4500 body = new(zone()) ZoneList<Statement*>(8, zone()); | 4518 body = new(zone()) ZoneList<Statement*>(8, zone()); |
4501 if (fvar != NULL) { | 4519 if (fvar != NULL) { |
4502 VariableProxy* fproxy = top_scope_->NewUnresolved( | 4520 VariableProxy* fproxy = top_scope_->NewUnresolved( |
4503 factory(), function_name, Interface::NewConst()); | 4521 factory(), function_name, Interface::NewConst()); |
4504 fproxy->BindTo(fvar); | 4522 fproxy->BindTo(fvar); |
4505 body->Add(factory()->NewExpressionStatement( | 4523 body->Add(factory()->NewExpressionStatement( |
4506 factory()->NewAssignment(fvar_init_op, | 4524 factory()->NewAssignment(fvar_init_op, |
4507 fproxy, | 4525 fproxy, |
4508 factory()->NewThisFunction(), | 4526 factory()->NewThisFunction(pos), |
4509 RelocInfo::kNoPosition)), | 4527 RelocInfo::kNoPosition), |
4510 zone()); | 4528 RelocInfo::kNoPosition), zone()); |
4511 } | 4529 } |
4512 | 4530 |
4513 // For generators, allocate and yield an iterator on function entry. | 4531 // For generators, allocate and yield an iterator on function entry. |
4514 if (is_generator) { | 4532 if (is_generator) { |
4515 ZoneList<Expression*>* arguments = | 4533 ZoneList<Expression*>* arguments = |
4516 new(zone()) ZoneList<Expression*>(0, zone()); | 4534 new(zone()) ZoneList<Expression*>(0, zone()); |
4517 CallRuntime* allocation = factory()->NewCallRuntime( | 4535 CallRuntime* allocation = factory()->NewCallRuntime( |
4518 isolate()->factory()->empty_string(), | 4536 isolate()->factory()->empty_string(), |
4519 Runtime::FunctionForId(Runtime::kCreateJSGeneratorObject), | 4537 Runtime::FunctionForId(Runtime::kCreateJSGeneratorObject), |
4520 arguments); | 4538 arguments, pos); |
4521 VariableProxy* init_proxy = factory()->NewVariableProxy( | 4539 VariableProxy* init_proxy = factory()->NewVariableProxy( |
4522 current_function_state_->generator_object_variable()); | 4540 current_function_state_->generator_object_variable()); |
4523 Assignment* assignment = factory()->NewAssignment( | 4541 Assignment* assignment = factory()->NewAssignment( |
4524 Token::INIT_VAR, init_proxy, allocation, RelocInfo::kNoPosition); | 4542 Token::INIT_VAR, init_proxy, allocation, RelocInfo::kNoPosition); |
4525 VariableProxy* get_proxy = factory()->NewVariableProxy( | 4543 VariableProxy* get_proxy = factory()->NewVariableProxy( |
4526 current_function_state_->generator_object_variable()); | 4544 current_function_state_->generator_object_variable()); |
4527 Yield* yield = factory()->NewYield( | 4545 Yield* yield = factory()->NewYield( |
4528 get_proxy, assignment, Yield::INITIAL, RelocInfo::kNoPosition); | 4546 get_proxy, assignment, Yield::INITIAL, RelocInfo::kNoPosition); |
4529 body->Add(factory()->NewExpressionStatement(yield), zone()); | 4547 body->Add(factory()->NewExpressionStatement( |
4548 yield, RelocInfo::kNoPosition), zone()); | |
4530 } | 4549 } |
4531 | 4550 |
4532 ParseSourceElements(body, Token::RBRACE, false, false, CHECK_OK); | 4551 ParseSourceElements(body, Token::RBRACE, false, false, CHECK_OK); |
4533 | 4552 |
4534 if (is_generator) { | 4553 if (is_generator) { |
4535 VariableProxy* get_proxy = factory()->NewVariableProxy( | 4554 VariableProxy* get_proxy = factory()->NewVariableProxy( |
4536 current_function_state_->generator_object_variable()); | 4555 current_function_state_->generator_object_variable()); |
4537 Expression *undefined = factory()->NewLiteral( | 4556 Expression *undefined = factory()->NewLiteral( |
4538 isolate()->factory()->undefined_value()); | 4557 isolate()->factory()->undefined_value(), RelocInfo::kNoPosition); |
4539 Yield* yield = factory()->NewYield( | 4558 Yield* yield = factory()->NewYield( |
4540 get_proxy, undefined, Yield::FINAL, RelocInfo::kNoPosition); | 4559 get_proxy, undefined, Yield::FINAL, RelocInfo::kNoPosition); |
4541 body->Add(factory()->NewExpressionStatement(yield), zone()); | 4560 body->Add(factory()->NewExpressionStatement( |
4561 yield, RelocInfo::kNoPosition), zone()); | |
4542 } | 4562 } |
4543 | 4563 |
4544 materialized_literal_count = function_state.materialized_literal_count(); | 4564 materialized_literal_count = function_state.materialized_literal_count(); |
4545 expected_property_count = function_state.expected_property_count(); | 4565 expected_property_count = function_state.expected_property_count(); |
4546 handler_count = function_state.handler_count(); | 4566 handler_count = function_state.handler_count(); |
4547 | 4567 |
4548 Expect(Token::RBRACE, CHECK_OK); | 4568 Expect(Token::RBRACE, CHECK_OK); |
4549 scope->set_end_position(scanner().location().end_pos); | 4569 scope->set_end_position(scanner().location().end_pos); |
4550 } | 4570 } |
4551 | 4571 |
4552 // Validate strict mode. | 4572 // Validate strict mode. |
4553 if (!top_scope_->is_classic_mode()) { | 4573 if (!top_scope_->is_classic_mode()) { |
4554 if (IsEvalOrArguments(function_name)) { | 4574 if (IsEvalOrArguments(function_name)) { |
4555 int start_pos = scope->start_position(); | 4575 int start_pos = scope->start_position(); |
4556 int position = function_token_position != RelocInfo::kNoPosition | 4576 int position = function_token_pos != RelocInfo::kNoPosition |
4557 ? function_token_position | 4577 ? function_token_pos : (start_pos > 0 ? start_pos - 1 : start_pos); |
4558 : (start_pos > 0 ? start_pos - 1 : start_pos); | |
4559 Scanner::Location location = Scanner::Location(position, start_pos); | 4578 Scanner::Location location = Scanner::Location(position, start_pos); |
4560 ReportMessageAt(location, | 4579 ReportMessageAt(location, |
4561 "strict_function_name", Vector<const char*>::empty()); | 4580 "strict_function_name", Vector<const char*>::empty()); |
4562 *ok = false; | 4581 *ok = false; |
4563 return NULL; | 4582 return NULL; |
4564 } | 4583 } |
4565 if (name_loc.IsValid()) { | 4584 if (name_loc.IsValid()) { |
4566 ReportMessageAt(name_loc, "strict_param_name", | 4585 ReportMessageAt(name_loc, "strict_param_name", |
4567 Vector<const char*>::empty()); | 4586 Vector<const char*>::empty()); |
4568 *ok = false; | 4587 *ok = false; |
4569 return NULL; | 4588 return NULL; |
4570 } | 4589 } |
4571 if (dupe_loc.IsValid()) { | 4590 if (dupe_loc.IsValid()) { |
4572 ReportMessageAt(dupe_loc, "strict_param_dupe", | 4591 ReportMessageAt(dupe_loc, "strict_param_dupe", |
4573 Vector<const char*>::empty()); | 4592 Vector<const char*>::empty()); |
4574 *ok = false; | 4593 *ok = false; |
4575 return NULL; | 4594 return NULL; |
4576 } | 4595 } |
4577 if (name_is_strict_reserved) { | 4596 if (name_is_strict_reserved) { |
4578 int start_pos = scope->start_position(); | 4597 int start_pos = scope->start_position(); |
4579 int position = function_token_position != RelocInfo::kNoPosition | 4598 int position = function_token_pos != RelocInfo::kNoPosition |
4580 ? function_token_position | 4599 ? function_token_pos : (start_pos > 0 ? start_pos - 1 : start_pos); |
4581 : (start_pos > 0 ? start_pos - 1 : start_pos); | |
4582 Scanner::Location location = Scanner::Location(position, start_pos); | 4600 Scanner::Location location = Scanner::Location(position, start_pos); |
4583 ReportMessageAt(location, "strict_reserved_word", | 4601 ReportMessageAt(location, "strict_reserved_word", |
4584 Vector<const char*>::empty()); | 4602 Vector<const char*>::empty()); |
4585 *ok = false; | 4603 *ok = false; |
4586 return NULL; | 4604 return NULL; |
4587 } | 4605 } |
4588 if (reserved_loc.IsValid()) { | 4606 if (reserved_loc.IsValid()) { |
4589 ReportMessageAt(reserved_loc, "strict_reserved_word", | 4607 ReportMessageAt(reserved_loc, "strict_reserved_word", |
4590 Vector<const char*>::empty()); | 4608 Vector<const char*>::empty()); |
4591 *ok = false; | 4609 *ok = false; |
(...skipping 16 matching lines...) Expand all Loading... | |
4608 scope, | 4626 scope, |
4609 body, | 4627 body, |
4610 materialized_literal_count, | 4628 materialized_literal_count, |
4611 expected_property_count, | 4629 expected_property_count, |
4612 handler_count, | 4630 handler_count, |
4613 num_parameters, | 4631 num_parameters, |
4614 duplicate_parameters, | 4632 duplicate_parameters, |
4615 function_type, | 4633 function_type, |
4616 FunctionLiteral::kIsFunction, | 4634 FunctionLiteral::kIsFunction, |
4617 parenthesized, | 4635 parenthesized, |
4618 generator); | 4636 generator, |
4619 function_literal->set_function_token_position(function_token_position); | 4637 pos); |
4638 function_literal->set_function_token_position(function_token_pos); | |
4620 function_literal->set_ast_properties(&ast_properties); | 4639 function_literal->set_ast_properties(&ast_properties); |
4621 function_literal->set_dont_optimize_reason(dont_optimize_reason); | 4640 function_literal->set_dont_optimize_reason(dont_optimize_reason); |
4622 | 4641 |
4623 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal); | 4642 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal); |
4624 return function_literal; | 4643 return function_literal; |
4625 } | 4644 } |
4626 | 4645 |
4627 | 4646 |
4628 preparser::PreParser::PreParseResult Parser::LazyParseFunctionLiteral( | 4647 preparser::PreParser::PreParseResult Parser::LazyParseFunctionLiteral( |
4629 SingletonLogger* logger) { | 4648 SingletonLogger* logger) { |
(...skipping 19 matching lines...) Expand all Loading... | |
4649 is_generator(), | 4668 is_generator(), |
4650 logger); | 4669 logger); |
4651 return result; | 4670 return result; |
4652 } | 4671 } |
4653 | 4672 |
4654 | 4673 |
4655 Expression* Parser::ParseV8Intrinsic(bool* ok) { | 4674 Expression* Parser::ParseV8Intrinsic(bool* ok) { |
4656 // CallRuntime :: | 4675 // CallRuntime :: |
4657 // '%' Identifier Arguments | 4676 // '%' Identifier Arguments |
4658 | 4677 |
4678 int pos = peek_position(); | |
4659 Expect(Token::MOD, CHECK_OK); | 4679 Expect(Token::MOD, CHECK_OK); |
4660 Handle<String> name = ParseIdentifier(CHECK_OK); | 4680 Handle<String> name = ParseIdentifier(CHECK_OK); |
4661 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); | 4681 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); |
4662 | 4682 |
4663 if (extension_ != NULL) { | 4683 if (extension_ != NULL) { |
4664 // The extension structures are only accessible while parsing the | 4684 // The extension structures are only accessible while parsing the |
4665 // very first time not when reparsing because of lazy compilation. | 4685 // very first time not when reparsing because of lazy compilation. |
4666 top_scope_->DeclarationScope()->ForceEagerCompilation(); | 4686 top_scope_->DeclarationScope()->ForceEagerCompilation(); |
4667 } | 4687 } |
4668 | 4688 |
(...skipping 25 matching lines...) Expand all Loading... | |
4694 } | 4714 } |
4695 | 4715 |
4696 // Check that the function is defined if it's an inline runtime call. | 4716 // Check that the function is defined if it's an inline runtime call. |
4697 if (function == NULL && name->Get(0) == '_') { | 4717 if (function == NULL && name->Get(0) == '_') { |
4698 ReportMessage("not_defined", Vector<Handle<String> >(&name, 1)); | 4718 ReportMessage("not_defined", Vector<Handle<String> >(&name, 1)); |
4699 *ok = false; | 4719 *ok = false; |
4700 return NULL; | 4720 return NULL; |
4701 } | 4721 } |
4702 | 4722 |
4703 // We have a valid intrinsics call or a call to a builtin. | 4723 // We have a valid intrinsics call or a call to a builtin. |
4704 return factory()->NewCallRuntime(name, function, args); | 4724 return factory()->NewCallRuntime(name, function, args, pos); |
4705 } | 4725 } |
4706 | 4726 |
4707 | 4727 |
4708 bool Parser::peek_any_identifier() { | 4728 bool Parser::peek_any_identifier() { |
4709 Token::Value next = peek(); | 4729 Token::Value next = peek(); |
4710 return next == Token::IDENTIFIER || | 4730 return next == Token::IDENTIFIER || |
4711 next == Token::FUTURE_RESERVED_WORD || | 4731 next == Token::FUTURE_RESERVED_WORD || |
4712 next == Token::FUTURE_STRICT_RESERVED_WORD || | 4732 next == Token::FUTURE_STRICT_RESERVED_WORD || |
4713 next == Token::YIELD; | 4733 next == Token::YIELD; |
4714 } | 4734 } |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4770 void Parser::ExpectContextualKeyword(Vector<const char> keyword, bool* ok) { | 4790 void Parser::ExpectContextualKeyword(Vector<const char> keyword, bool* ok) { |
4771 Expect(Token::IDENTIFIER, ok); | 4791 Expect(Token::IDENTIFIER, ok); |
4772 if (!*ok) return; | 4792 if (!*ok) return; |
4773 if (!scanner().is_literal_contextual_keyword(keyword)) { | 4793 if (!scanner().is_literal_contextual_keyword(keyword)) { |
4774 *ok = false; | 4794 *ok = false; |
4775 ReportUnexpectedToken(scanner().current_token()); | 4795 ReportUnexpectedToken(scanner().current_token()); |
4776 } | 4796 } |
4777 } | 4797 } |
4778 | 4798 |
4779 | 4799 |
4780 Literal* Parser::GetLiteralUndefined() { | 4800 Literal* Parser::GetLiteralUndefined(int position) { |
4781 return factory()->NewLiteral(isolate()->factory()->undefined_value()); | 4801 return factory()->NewLiteral( |
4802 isolate()->factory()->undefined_value(), position); | |
4782 } | 4803 } |
4783 | 4804 |
4784 | 4805 |
4785 Literal* Parser::GetLiteralTheHole() { | 4806 Literal* Parser::GetLiteralTheHole(int position) { |
4786 return factory()->NewLiteral(isolate()->factory()->the_hole_value()); | 4807 return factory()->NewLiteral( |
4808 isolate()->factory()->the_hole_value(), RelocInfo::kNoPosition); | |
4787 } | 4809 } |
4788 | 4810 |
4789 | 4811 |
4790 // Parses an identifier that is valid for the current scope, in particular it | 4812 // Parses an identifier that is valid for the current scope, in particular it |
4791 // fails on strict mode future reserved keywords in a strict scope. | 4813 // fails on strict mode future reserved keywords in a strict scope. |
4792 Handle<String> Parser::ParseIdentifier(bool* ok) { | 4814 Handle<String> Parser::ParseIdentifier(bool* ok) { |
4793 Token::Value next = Next(); | 4815 Token::Value next = Next(); |
4794 if (next == Token::IDENTIFIER || | 4816 if (next == Token::IDENTIFIER || |
4795 (top_scope_->is_classic_mode() && | 4817 (top_scope_->is_classic_mode() && |
4796 (next == Token::FUTURE_STRICT_RESERVED_WORD || | 4818 (next == Token::FUTURE_STRICT_RESERVED_WORD || |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5005 TENURED); | 5027 TENURED); |
5006 for (int i = 0; i < argc; i++) { | 5028 for (int i = 0; i < argc; i++) { |
5007 Handle<Object> element = arguments[i]; | 5029 Handle<Object> element = arguments[i]; |
5008 if (!element.is_null()) { | 5030 if (!element.is_null()) { |
5009 elements->set(i, *element); | 5031 elements->set(i, *element); |
5010 } | 5032 } |
5011 } | 5033 } |
5012 Handle<JSArray> array = isolate()->factory()->NewJSArrayWithElements( | 5034 Handle<JSArray> array = isolate()->factory()->NewJSArrayWithElements( |
5013 elements, FAST_ELEMENTS, TENURED); | 5035 elements, FAST_ELEMENTS, TENURED); |
5014 | 5036 |
5037 int pos = position(); | |
5015 ZoneList<Expression*>* args = new(zone()) ZoneList<Expression*>(2, zone()); | 5038 ZoneList<Expression*>* args = new(zone()) ZoneList<Expression*>(2, zone()); |
5016 args->Add(factory()->NewLiteral(message), zone()); | 5039 args->Add(factory()->NewLiteral(message, pos), zone()); |
5017 args->Add(factory()->NewLiteral(array), zone()); | 5040 args->Add(factory()->NewLiteral(array, pos), zone()); |
5018 CallRuntime* call_constructor = | 5041 CallRuntime* call_constructor = |
5019 factory()->NewCallRuntime(constructor, NULL, args); | 5042 factory()->NewCallRuntime(constructor, NULL, args, pos); |
5020 return factory()->NewThrow(call_constructor, scanner().location().beg_pos); | 5043 return factory()->NewThrow(call_constructor, pos); |
5021 } | 5044 } |
5022 | 5045 |
5023 | 5046 |
5024 // ---------------------------------------------------------------------------- | 5047 // ---------------------------------------------------------------------------- |
5025 // Regular expressions | 5048 // Regular expressions |
5026 | 5049 |
5027 | 5050 |
5028 RegExpParser::RegExpParser(FlatStringReader* in, | 5051 RegExpParser::RegExpParser(FlatStringReader* in, |
5029 Handle<String>* error, | 5052 Handle<String>* error, |
5030 bool multiline, | 5053 bool multiline, |
(...skipping 945 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5976 ASSERT(info()->isolate()->has_pending_exception()); | 5999 ASSERT(info()->isolate()->has_pending_exception()); |
5977 } else { | 6000 } else { |
5978 result = ParseProgram(); | 6001 result = ParseProgram(); |
5979 } | 6002 } |
5980 } | 6003 } |
5981 info()->SetFunction(result); | 6004 info()->SetFunction(result); |
5982 return (result != NULL); | 6005 return (result != NULL); |
5983 } | 6006 } |
5984 | 6007 |
5985 } } // namespace v8::internal | 6008 } } // namespace v8::internal |
OLD | NEW |