Chromium Code Reviews| 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 |