OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/api.h" | 7 #include "src/api.h" |
8 #include "src/ast.h" | 8 #include "src/ast.h" |
9 #include "src/bailout-reason.h" | 9 #include "src/bailout-reason.h" |
10 #include "src/base/platform/platform.h" | 10 #include "src/base/platform/platform.h" |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
258 DCHECK(info_->cached_data() != NULL); | 258 DCHECK(info_->cached_data() != NULL); |
259 if (compile_options() == ScriptCompiler::kConsumeParserCache) { | 259 if (compile_options() == ScriptCompiler::kConsumeParserCache) { |
260 cached_parse_data_ = ParseData::FromCachedData(*info_->cached_data()); | 260 cached_parse_data_ = ParseData::FromCachedData(*info_->cached_data()); |
261 } | 261 } |
262 } | 262 } |
263 } | 263 } |
264 | 264 |
265 | 265 |
266 Scope* Parser::NewScope(Scope* parent, ScopeType scope_type) { | 266 Scope* Parser::NewScope(Scope* parent, ScopeType scope_type) { |
267 DCHECK(ast_value_factory()); | 267 DCHECK(ast_value_factory()); |
| 268 DCHECK(scope_type != MODULE_SCOPE || allow_harmony_modules()); |
268 Scope* result = new (zone()) | 269 Scope* result = new (zone()) |
269 Scope(isolate(), zone(), parent, scope_type, ast_value_factory()); | 270 Scope(isolate(), zone(), parent, scope_type, ast_value_factory()); |
270 result->Initialize(); | 271 result->Initialize(); |
271 return result; | 272 return result; |
272 } | 273 } |
273 | 274 |
274 | 275 |
275 FunctionLiteral* Parser::DefaultConstructor(bool call_super, Scope* scope, | 276 FunctionLiteral* Parser::DefaultConstructor(bool call_super, Scope* scope, |
276 int pos, int end_pos) { | 277 int pos, int end_pos) { |
277 int materialized_literal_count = -1; | 278 int materialized_literal_count = -1; |
(...skipping 649 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
927 | 928 |
928 // Enters 'scope'. | 929 // Enters 'scope'. |
929 AstNodeFactory function_factory(ast_value_factory()); | 930 AstNodeFactory function_factory(ast_value_factory()); |
930 FunctionState function_state(&function_state_, &scope_, *scope, | 931 FunctionState function_state(&function_state_, &scope_, *scope, |
931 &function_factory); | 932 &function_factory); |
932 | 933 |
933 scope_->SetStrictMode(info->strict_mode()); | 934 scope_->SetStrictMode(info->strict_mode()); |
934 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); | 935 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); |
935 bool ok = true; | 936 bool ok = true; |
936 int beg_pos = scanner()->location().beg_pos; | 937 int beg_pos = scanner()->location().beg_pos; |
937 ParseSourceElements(body, Token::EOS, info->is_eval(), true, eval_scope, | 938 if (info->is_module()) { |
938 &ok); | 939 DCHECK(allow_harmony_modules()); |
| 940 Module* module = ParseModule(&ok); |
| 941 if (ok) { |
| 942 // TODO(adamk): Do something with returned Module |
| 943 CHECK(module); |
| 944 body->Add(factory()->NewEmptyStatement(RelocInfo::kNoPosition), zone()); |
| 945 } |
| 946 } else { |
| 947 ParseStatementList(body, Token::EOS, info->is_eval(), eval_scope, &ok); |
| 948 } |
939 | 949 |
940 if (ok && strict_mode() == STRICT) { | 950 if (ok && strict_mode() == STRICT) { |
941 CheckStrictOctalLiteral(beg_pos, scanner()->location().end_pos, &ok); | 951 CheckStrictOctalLiteral(beg_pos, scanner()->location().end_pos, &ok); |
942 } | 952 } |
943 | 953 |
944 if (ok && allow_harmony_scoping() && strict_mode() == STRICT) { | 954 if (ok && allow_harmony_scoping() && strict_mode() == STRICT) { |
945 CheckConflictingVarDeclarations(scope_, &ok); | 955 CheckConflictingVarDeclarations(scope_, &ok); |
946 } | 956 } |
947 | 957 |
948 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) { | 958 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) { |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1073 DCHECK(target_stack_ == NULL); | 1083 DCHECK(target_stack_ == NULL); |
1074 | 1084 |
1075 if (result != NULL) { | 1085 if (result != NULL) { |
1076 Handle<String> inferred_name(shared_info->inferred_name()); | 1086 Handle<String> inferred_name(shared_info->inferred_name()); |
1077 result->set_inferred_name(inferred_name); | 1087 result->set_inferred_name(inferred_name); |
1078 } | 1088 } |
1079 return result; | 1089 return result; |
1080 } | 1090 } |
1081 | 1091 |
1082 | 1092 |
1083 void* Parser::ParseSourceElements(ZoneList<Statement*>* processor, | 1093 void* Parser::ParseStatementList(ZoneList<Statement*>* body, int end_token, |
1084 int end_token, bool is_eval, bool is_global, | 1094 bool is_eval, Scope** eval_scope, bool* ok) { |
1085 Scope** eval_scope, bool* ok) { | 1095 // StatementList :: |
1086 // SourceElements :: | 1096 // (StatementListItem)* <end_token> |
1087 // (ModuleElement)* <end_token> | |
1088 | 1097 |
1089 // Allocate a target stack to use for this set of source | 1098 // Allocate a target stack to use for this set of source |
1090 // elements. This way, all scripts and functions get their own | 1099 // elements. This way, all scripts and functions get their own |
1091 // target stack thus avoiding illegal breaks and continues across | 1100 // target stack thus avoiding illegal breaks and continues across |
1092 // functions. | 1101 // functions. |
1093 TargetScope scope(&this->target_stack_); | 1102 TargetScope scope(&this->target_stack_); |
1094 | 1103 |
1095 DCHECK(processor != NULL); | 1104 DCHECK(body != NULL); |
1096 bool directive_prologue = true; // Parsing directive prologue. | 1105 bool directive_prologue = true; // Parsing directive prologue. |
1097 | 1106 |
1098 while (peek() != end_token) { | 1107 while (peek() != end_token) { |
1099 if (directive_prologue && peek() != Token::STRING) { | 1108 if (directive_prologue && peek() != Token::STRING) { |
1100 directive_prologue = false; | 1109 directive_prologue = false; |
1101 } | 1110 } |
1102 | 1111 |
1103 Scanner::Location token_loc = scanner()->peek_location(); | 1112 Scanner::Location token_loc = scanner()->peek_location(); |
1104 Statement* stat; | 1113 Statement* stat = ParseStatementListItem(CHECK_OK); |
1105 if (is_global && !is_eval) { | |
1106 stat = ParseModuleElement(NULL, CHECK_OK); | |
1107 } else { | |
1108 stat = ParseBlockElement(NULL, CHECK_OK); | |
1109 } | |
1110 if (stat == NULL || stat->IsEmpty()) { | 1114 if (stat == NULL || stat->IsEmpty()) { |
1111 directive_prologue = false; // End of directive prologue. | 1115 directive_prologue = false; // End of directive prologue. |
1112 continue; | 1116 continue; |
1113 } | 1117 } |
1114 | 1118 |
1115 if (directive_prologue) { | 1119 if (directive_prologue) { |
1116 // A shot at a directive. | 1120 // A shot at a directive. |
1117 ExpressionStatement* e_stat; | 1121 ExpressionStatement* e_stat; |
1118 Literal* literal; | 1122 Literal* literal; |
1119 // Still processing directive prologue? | 1123 // Still processing directive prologue? |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1155 // incremented after parsing is done. | 1159 // incremented after parsing is done. |
1156 ++use_counts_[v8::Isolate::kUseAsm]; | 1160 ++use_counts_[v8::Isolate::kUseAsm]; |
1157 scope_->SetAsmModule(); | 1161 scope_->SetAsmModule(); |
1158 } | 1162 } |
1159 } else { | 1163 } else { |
1160 // End of the directive prologue. | 1164 // End of the directive prologue. |
1161 directive_prologue = false; | 1165 directive_prologue = false; |
1162 } | 1166 } |
1163 } | 1167 } |
1164 | 1168 |
1165 processor->Add(stat, zone()); | 1169 body->Add(stat, zone()); |
1166 } | 1170 } |
1167 | 1171 |
1168 return 0; | 1172 return 0; |
1169 } | 1173 } |
1170 | 1174 |
1171 | 1175 |
1172 Statement* Parser::ParseModuleElement(ZoneList<const AstRawString*>* labels, | 1176 Statement* Parser::ParseStatementListItem(bool* ok) { |
1173 bool* ok) { | 1177 // (Ecma 262 6th Edition, 13.1): |
1174 // (Ecma 262 5th Edition, clause 14): | 1178 // StatementListItem: |
1175 // SourceElement: | |
1176 // Statement | 1179 // Statement |
1177 // FunctionDeclaration | 1180 // Declaration |
1178 // | |
1179 // In harmony mode we allow additionally the following productions | |
1180 // ModuleElement: | |
1181 // LetDeclaration | |
1182 // ConstDeclaration | |
1183 // ModuleDeclaration | |
1184 // ImportDeclaration | |
1185 // ExportDeclaration | |
1186 // GeneratorDeclaration | |
1187 | 1181 |
1188 switch (peek()) { | 1182 switch (peek()) { |
1189 case Token::FUNCTION: | 1183 case Token::FUNCTION: |
1190 return ParseFunctionDeclaration(NULL, ok); | 1184 return ParseFunctionDeclaration(NULL, ok); |
1191 case Token::CLASS: | 1185 case Token::CLASS: |
1192 return ParseClassDeclaration(NULL, ok); | 1186 return ParseClassDeclaration(NULL, ok); |
| 1187 case Token::CONST: |
| 1188 case Token::VAR: |
| 1189 return ParseVariableStatement(kStatementListItem, NULL, ok); |
| 1190 case Token::LET: |
| 1191 DCHECK(allow_harmony_scoping()); |
| 1192 if (strict_mode() == STRICT) { |
| 1193 return ParseVariableStatement(kStatementListItem, NULL, ok); |
| 1194 } |
| 1195 // Fall through. |
| 1196 default: |
| 1197 return ParseStatement(NULL, ok); |
| 1198 } |
| 1199 } |
| 1200 |
| 1201 |
| 1202 Statement* Parser::ParseModuleItem(bool* ok) { |
| 1203 // (Ecma 262 6th Edition, 15.2): |
| 1204 // ModuleItem : |
| 1205 // ImportDeclaration |
| 1206 // ExportDeclaration |
| 1207 // StatementListItem |
| 1208 |
| 1209 switch (peek()) { |
1193 case Token::IMPORT: | 1210 case Token::IMPORT: |
1194 return ParseImportDeclaration(ok); | 1211 return ParseImportDeclaration(ok); |
1195 case Token::EXPORT: | 1212 case Token::EXPORT: |
1196 return ParseExportDeclaration(ok); | 1213 return ParseExportDeclaration(ok); |
1197 case Token::CONST: | 1214 default: |
1198 return ParseVariableStatement(kModuleElement, NULL, ok); | 1215 return ParseStatementListItem(ok); |
1199 case Token::LET: | |
1200 DCHECK(allow_harmony_scoping()); | |
1201 if (strict_mode() == STRICT) { | |
1202 return ParseVariableStatement(kModuleElement, NULL, ok); | |
1203 } | |
1204 // Fall through. | |
1205 default: { | |
1206 Statement* stmt = ParseStatement(labels, CHECK_OK); | |
1207 // Handle 'module' as a context-sensitive keyword. | |
1208 if (FLAG_harmony_modules && | |
1209 peek() == Token::IDENTIFIER && | |
1210 !scanner()->HasAnyLineTerminatorBeforeNext() && | |
1211 stmt != NULL) { | |
1212 ExpressionStatement* estmt = stmt->AsExpressionStatement(); | |
1213 if (estmt != NULL && estmt->expression()->AsVariableProxy() != NULL && | |
1214 estmt->expression()->AsVariableProxy()->raw_name() == | |
1215 ast_value_factory()->module_string() && | |
1216 !scanner()->literal_contains_escapes()) { | |
1217 return ParseModuleDeclaration(NULL, ok); | |
1218 } | |
1219 } | |
1220 return stmt; | |
1221 } | |
1222 } | 1216 } |
1223 } | 1217 } |
1224 | 1218 |
1225 | 1219 |
1226 Statement* Parser::ParseModuleDeclaration(ZoneList<const AstRawString*>* names, | |
1227 bool* ok) { | |
1228 // ModuleDeclaration: | |
1229 // 'module' Identifier Module | |
1230 | |
1231 int pos = peek_position(); | |
1232 const AstRawString* name = | |
1233 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | |
1234 | |
1235 #ifdef DEBUG | |
1236 if (FLAG_print_interface_details) | |
1237 PrintF("# Module %.*s ", name->length(), name->raw_data()); | |
1238 #endif | |
1239 | |
1240 Module* module = ParseModule(CHECK_OK); | |
1241 VariableProxy* proxy = NewUnresolved(name, MODULE, module->interface()); | |
1242 Declaration* declaration = | |
1243 factory()->NewModuleDeclaration(proxy, module, scope_, pos); | |
1244 Declare(declaration, true, CHECK_OK); | |
1245 | |
1246 #ifdef DEBUG | |
1247 if (FLAG_print_interface_details) | |
1248 PrintF("# Module %.*s ", name->length(), name->raw_data()); | |
1249 if (FLAG_print_interfaces) { | |
1250 PrintF("module %.*s: ", name->length(), name->raw_data()); | |
1251 module->interface()->Print(); | |
1252 } | |
1253 #endif | |
1254 | |
1255 if (names) names->Add(name, zone()); | |
1256 if (module->body() == NULL) | |
1257 return factory()->NewEmptyStatement(pos); | |
1258 else | |
1259 return factory()->NewModuleStatement(proxy, module->body(), pos); | |
1260 } | |
1261 | |
1262 | |
1263 Module* Parser::ParseModule(bool* ok) { | 1220 Module* Parser::ParseModule(bool* ok) { |
1264 // Module: | 1221 // (Ecma 262 6th Edition, 15.2): |
1265 // '{' ModuleElement '}' | 1222 // Module : |
1266 // '=' ModulePath ';' | 1223 // ModuleBody? |
1267 // 'at' String ';' | 1224 // |
1268 | 1225 // ModuleBody : |
1269 switch (peek()) { | 1226 // ModuleItem* |
1270 case Token::LBRACE: | |
1271 return ParseModuleLiteral(ok); | |
1272 | |
1273 case Token::ASSIGN: { | |
1274 Expect(Token::ASSIGN, CHECK_OK); | |
1275 Module* result = ParseModulePath(CHECK_OK); | |
1276 ExpectSemicolon(CHECK_OK); | |
1277 return result; | |
1278 } | |
1279 | |
1280 default: { | |
1281 ExpectContextualKeyword(CStrVector("at"), CHECK_OK); | |
1282 Module* result = ParseModuleUrl(CHECK_OK); | |
1283 ExpectSemicolon(CHECK_OK); | |
1284 return result; | |
1285 } | |
1286 } | |
1287 } | |
1288 | |
1289 | |
1290 Module* Parser::ParseModuleLiteral(bool* ok) { | |
1291 // Module: | |
1292 // '{' ModuleElement '}' | |
1293 | 1227 |
1294 int pos = peek_position(); | 1228 int pos = peek_position(); |
1295 // Construct block expecting 16 statements. | 1229 // Construct block expecting 16 statements. |
1296 Block* body = factory()->NewBlock(NULL, 16, false, RelocInfo::kNoPosition); | 1230 Block* body = factory()->NewBlock(NULL, 16, false, RelocInfo::kNoPosition); |
1297 #ifdef DEBUG | 1231 #ifdef DEBUG |
1298 if (FLAG_print_interface_details) PrintF("# Literal "); | 1232 if (FLAG_print_interface_details) PrintF("# Literal "); |
1299 #endif | 1233 #endif |
1300 Scope* scope = NewScope(scope_, MODULE_SCOPE); | 1234 Scope* scope = NewScope(scope_, MODULE_SCOPE); |
1301 | 1235 |
1302 Expect(Token::LBRACE, CHECK_OK); | |
1303 scope->set_start_position(scanner()->location().beg_pos); | 1236 scope->set_start_position(scanner()->location().beg_pos); |
1304 scope->SetStrictMode(STRICT); | 1237 scope->SetStrictMode(STRICT); |
1305 | 1238 |
1306 { | 1239 { |
1307 BlockState block_state(&scope_, scope); | 1240 BlockState block_state(&scope_, scope); |
1308 Target target(&this->target_stack_, body); | 1241 Target target(&this->target_stack_, body); |
1309 | 1242 |
1310 while (peek() != Token::RBRACE) { | 1243 while (peek() != Token::EOS) { |
1311 Statement* stat = ParseModuleElement(NULL, CHECK_OK); | 1244 Statement* stat = ParseModuleItem(CHECK_OK); |
1312 if (stat && !stat->IsEmpty()) { | 1245 if (stat && !stat->IsEmpty()) { |
1313 body->AddStatement(stat, zone()); | 1246 body->AddStatement(stat, zone()); |
1314 } | 1247 } |
1315 } | 1248 } |
1316 } | 1249 } |
1317 | 1250 |
1318 Expect(Token::RBRACE, CHECK_OK); | |
1319 scope->set_end_position(scanner()->location().end_pos); | 1251 scope->set_end_position(scanner()->location().end_pos); |
1320 body->set_scope(scope); | 1252 body->set_scope(scope); |
1321 | 1253 |
1322 // Check that all exports are bound. | 1254 // Check that all exports are bound. |
1323 Interface* interface = scope->interface(); | 1255 Interface* interface = scope->interface(); |
1324 for (Interface::Iterator it = interface->iterator(); | 1256 for (Interface::Iterator it = interface->iterator(); |
1325 !it.done(); it.Advance()) { | 1257 !it.done(); it.Advance()) { |
1326 if (scope->LookupLocal(it.name()) == NULL) { | 1258 if (scope->LookupLocal(it.name()) == NULL) { |
1327 ParserTraits::ReportMessage("module_export_undefined", it.name()); | 1259 ParserTraits::ReportMessage("module_export_undefined", it.name()); |
1328 *ok = false; | 1260 *ok = false; |
1329 return NULL; | 1261 return NULL; |
1330 } | 1262 } |
1331 } | 1263 } |
1332 | 1264 |
1333 interface->MakeModule(ok); | 1265 interface->MakeModule(ok); |
1334 DCHECK(*ok); | 1266 DCHECK(*ok); |
1335 interface->Freeze(ok); | 1267 interface->Freeze(ok); |
1336 DCHECK(*ok); | 1268 DCHECK(*ok); |
1337 return factory()->NewModuleLiteral(body, interface, pos); | 1269 return factory()->NewModuleLiteral(body, interface, pos); |
1338 } | 1270 } |
1339 | 1271 |
1340 | 1272 |
1341 Module* Parser::ParseModulePath(bool* ok) { | |
1342 // ModulePath: | |
1343 // Identifier | |
1344 // ModulePath '.' Identifier | |
1345 | |
1346 int pos = peek_position(); | |
1347 Module* result = ParseModuleVariable(CHECK_OK); | |
1348 while (Check(Token::PERIOD)) { | |
1349 const AstRawString* name = ParseIdentifierName(CHECK_OK); | |
1350 #ifdef DEBUG | |
1351 if (FLAG_print_interface_details) | |
1352 PrintF("# Path .%.*s ", name->length(), name->raw_data()); | |
1353 #endif | |
1354 Module* member = factory()->NewModulePath(result, name, pos); | |
1355 result->interface()->Add(name, member->interface(), zone(), ok); | |
1356 if (!*ok) { | |
1357 #ifdef DEBUG | |
1358 if (FLAG_print_interfaces) { | |
1359 PrintF("PATH TYPE ERROR at '%.*s'\n", name->length(), name->raw_data()); | |
1360 PrintF("result: "); | |
1361 result->interface()->Print(); | |
1362 PrintF("member: "); | |
1363 member->interface()->Print(); | |
1364 } | |
1365 #endif | |
1366 ParserTraits::ReportMessage("invalid_module_path", name); | |
1367 return NULL; | |
1368 } | |
1369 result = member; | |
1370 } | |
1371 | |
1372 return result; | |
1373 } | |
1374 | |
1375 | |
1376 Module* Parser::ParseModuleVariable(bool* ok) { | |
1377 // ModulePath: | |
1378 // Identifier | |
1379 | |
1380 int pos = peek_position(); | |
1381 const AstRawString* name = | |
1382 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | |
1383 #ifdef DEBUG | |
1384 if (FLAG_print_interface_details) | |
1385 PrintF("# Module variable %.*s ", name->length(), name->raw_data()); | |
1386 #endif | |
1387 VariableProxy* proxy = scope_->NewUnresolved( | |
1388 factory(), name, Interface::NewModule(zone()), | |
1389 scanner()->location().beg_pos); | |
1390 | |
1391 return factory()->NewModuleVariable(proxy, pos); | |
1392 } | |
1393 | |
1394 | |
1395 Module* Parser::ParseModuleUrl(bool* ok) { | 1273 Module* Parser::ParseModuleUrl(bool* ok) { |
1396 // Module: | 1274 // Module: |
1397 // String | 1275 // String |
1398 | 1276 |
1399 int pos = peek_position(); | 1277 int pos = peek_position(); |
1400 Expect(Token::STRING, CHECK_OK); | 1278 Expect(Token::STRING, CHECK_OK); |
1401 const AstRawString* symbol = GetSymbol(scanner()); | 1279 const AstRawString* symbol = GetSymbol(scanner()); |
1402 | 1280 |
1403 // TODO(ES6): Request JS resource from environment... | 1281 // TODO(ES6): Request JS resource from environment... |
1404 | 1282 |
1405 #ifdef DEBUG | 1283 #ifdef DEBUG |
1406 if (FLAG_print_interface_details) PrintF("# Url "); | 1284 if (FLAG_print_interface_details) PrintF("# Url "); |
1407 #endif | 1285 #endif |
1408 | 1286 |
1409 // Create an empty literal as long as the feature isn't finished. | 1287 // Create an empty literal as long as the feature isn't finished. |
1410 USE(symbol); | 1288 USE(symbol); |
1411 Scope* scope = NewScope(scope_, MODULE_SCOPE); | 1289 Scope* scope = NewScope(scope_, MODULE_SCOPE); |
1412 Block* body = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition); | 1290 Block* body = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition); |
1413 body->set_scope(scope); | 1291 body->set_scope(scope); |
1414 Interface* interface = scope->interface(); | 1292 Interface* interface = scope->interface(); |
1415 Module* result = factory()->NewModuleLiteral(body, interface, pos); | 1293 Module* result = factory()->NewModuleLiteral(body, interface, pos); |
1416 interface->Freeze(ok); | 1294 interface->Freeze(ok); |
1417 DCHECK(*ok); | 1295 DCHECK(*ok); |
1418 interface->Unify(scope->interface(), zone(), ok); | 1296 interface->Unify(scope->interface(), zone(), ok); |
1419 DCHECK(*ok); | 1297 DCHECK(*ok); |
1420 return result; | 1298 return result; |
1421 } | 1299 } |
1422 | 1300 |
1423 | 1301 |
1424 Module* Parser::ParseModuleSpecifier(bool* ok) { | 1302 Statement* Parser::ParseImportDeclaration(bool* ok) { |
1425 // ModuleSpecifier: | |
1426 // String | |
1427 // ModulePath | |
1428 | |
1429 if (peek() == Token::STRING) { | |
1430 return ParseModuleUrl(ok); | |
1431 } else { | |
1432 return ParseModulePath(ok); | |
1433 } | |
1434 } | |
1435 | |
1436 | |
1437 Block* Parser::ParseImportDeclaration(bool* ok) { | |
1438 // ImportDeclaration: | 1303 // ImportDeclaration: |
1439 // 'import' IdentifierName (',' IdentifierName)* 'from' ModuleSpecifier ';' | 1304 // 'import' IdentifierName (',' IdentifierName)* 'from' ModuleUrl ';' |
1440 // | 1305 // |
1441 // TODO(ES6): implement destructuring ImportSpecifiers | 1306 // TODO(ES6): implement current syntax |
1442 | 1307 |
1443 int pos = peek_position(); | 1308 int pos = peek_position(); |
1444 Expect(Token::IMPORT, CHECK_OK); | 1309 Expect(Token::IMPORT, CHECK_OK); |
1445 ZoneList<const AstRawString*> names(1, zone()); | 1310 ZoneList<const AstRawString*> names(1, zone()); |
1446 | 1311 |
1447 const AstRawString* name = ParseIdentifierName(CHECK_OK); | 1312 const AstRawString* name = ParseIdentifierName(CHECK_OK); |
1448 names.Add(name, zone()); | 1313 names.Add(name, zone()); |
1449 while (peek() == Token::COMMA) { | 1314 while (peek() == Token::COMMA) { |
1450 Consume(Token::COMMA); | 1315 Consume(Token::COMMA); |
1451 name = ParseIdentifierName(CHECK_OK); | 1316 name = ParseIdentifierName(CHECK_OK); |
1452 names.Add(name, zone()); | 1317 names.Add(name, zone()); |
1453 } | 1318 } |
1454 | 1319 |
1455 ExpectContextualKeyword(CStrVector("from"), CHECK_OK); | 1320 ExpectContextualKeyword(CStrVector("from"), CHECK_OK); |
1456 Module* module = ParseModuleSpecifier(CHECK_OK); | 1321 Module* module = ParseModuleUrl(CHECK_OK); |
1457 ExpectSemicolon(CHECK_OK); | 1322 ExpectSemicolon(CHECK_OK); |
1458 | 1323 |
1459 // Generate a separate declaration for each identifier. | 1324 // TODO(ES6): Do something with ParseModuleUrl's return value. |
1460 // TODO(ES6): once we implement destructuring, make that one declaration. | 1325 USE(module); |
1461 Block* block = factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition); | 1326 |
1462 for (int i = 0; i < names.length(); ++i) { | 1327 for (int i = 0; i < names.length(); ++i) { |
1463 #ifdef DEBUG | 1328 // TODO(ES6): Add an appropriate declaration for each name |
1464 if (FLAG_print_interface_details) | |
1465 PrintF("# Import %.*s ", name->length(), name->raw_data()); | |
1466 #endif | |
1467 Interface* interface = Interface::NewUnknown(zone()); | |
1468 module->interface()->Add(names[i], interface, zone(), ok); | |
1469 if (!*ok) { | |
1470 #ifdef DEBUG | |
1471 if (FLAG_print_interfaces) { | |
1472 PrintF("IMPORT TYPE ERROR at '%.*s'\n", name->length(), | |
1473 name->raw_data()); | |
1474 PrintF("module: "); | |
1475 module->interface()->Print(); | |
1476 } | |
1477 #endif | |
1478 ParserTraits::ReportMessage("invalid_module_path", name); | |
1479 return NULL; | |
1480 } | |
1481 VariableProxy* proxy = NewUnresolved(names[i], LET, interface); | |
1482 Declaration* declaration = | |
1483 factory()->NewImportDeclaration(proxy, module, scope_, pos); | |
1484 Declare(declaration, true, CHECK_OK); | |
1485 } | 1329 } |
1486 | 1330 |
1487 return block; | 1331 return factory()->NewEmptyStatement(pos); |
1488 } | 1332 } |
1489 | 1333 |
1490 | 1334 |
1491 Statement* Parser::ParseExportDeclaration(bool* ok) { | 1335 Statement* Parser::ParseExportDeclaration(bool* ok) { |
1492 // ExportDeclaration: | 1336 // ExportDeclaration: |
1493 // 'export' Identifier (',' Identifier)* ';' | 1337 // 'export' Identifier (',' Identifier)* ';' |
1494 // 'export' VariableDeclaration | 1338 // 'export' VariableDeclaration |
1495 // 'export' FunctionDeclaration | 1339 // 'export' FunctionDeclaration |
1496 // 'export' GeneratorDeclaration | 1340 // 'export' GeneratorDeclaration |
1497 // 'export' ModuleDeclaration | 1341 // 'export' ModuleDeclaration |
1498 // | 1342 // |
1499 // TODO(ES6): implement structuring ExportSpecifiers | 1343 // TODO(ES6): implement current syntax |
1500 | 1344 |
1501 Expect(Token::EXPORT, CHECK_OK); | 1345 Expect(Token::EXPORT, CHECK_OK); |
1502 | 1346 |
1503 Statement* result = NULL; | 1347 Statement* result = NULL; |
1504 ZoneList<const AstRawString*> names(1, zone()); | 1348 ZoneList<const AstRawString*> names(1, zone()); |
1505 switch (peek()) { | 1349 switch (peek()) { |
1506 case Token::IDENTIFIER: { | 1350 case Token::IDENTIFIER: { |
1507 int pos = position(); | 1351 int pos = position(); |
1508 const AstRawString* name = | 1352 const AstRawString* name = |
1509 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | 1353 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
1510 // Handle 'module' as a context-sensitive keyword. | 1354 names.Add(name, zone()); |
1511 if (name != ast_value_factory()->module_string()) { | 1355 while (peek() == Token::COMMA) { |
| 1356 Consume(Token::COMMA); |
| 1357 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
1512 names.Add(name, zone()); | 1358 names.Add(name, zone()); |
1513 while (peek() == Token::COMMA) { | |
1514 Consume(Token::COMMA); | |
1515 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | |
1516 names.Add(name, zone()); | |
1517 } | |
1518 ExpectSemicolon(CHECK_OK); | |
1519 result = factory()->NewEmptyStatement(pos); | |
1520 } else { | |
1521 result = ParseModuleDeclaration(&names, CHECK_OK); | |
1522 } | 1359 } |
| 1360 ExpectSemicolon(CHECK_OK); |
| 1361 result = factory()->NewEmptyStatement(pos); |
1523 break; | 1362 break; |
1524 } | 1363 } |
1525 | 1364 |
1526 case Token::FUNCTION: | 1365 case Token::FUNCTION: |
1527 result = ParseFunctionDeclaration(&names, CHECK_OK); | 1366 result = ParseFunctionDeclaration(&names, CHECK_OK); |
1528 break; | 1367 break; |
1529 | 1368 |
1530 case Token::CLASS: | 1369 case Token::CLASS: |
1531 result = ParseClassDeclaration(&names, CHECK_OK); | 1370 result = ParseClassDeclaration(&names, CHECK_OK); |
1532 break; | 1371 break; |
1533 | 1372 |
1534 case Token::VAR: | 1373 case Token::VAR: |
1535 case Token::LET: | 1374 case Token::LET: |
1536 case Token::CONST: | 1375 case Token::CONST: |
1537 result = ParseVariableStatement(kModuleElement, &names, CHECK_OK); | 1376 result = ParseVariableStatement(kStatementListItem, &names, CHECK_OK); |
1538 break; | 1377 break; |
1539 | 1378 |
1540 default: | 1379 default: |
1541 *ok = false; | 1380 *ok = false; |
1542 ReportUnexpectedToken(scanner()->current_token()); | 1381 ReportUnexpectedToken(scanner()->current_token()); |
1543 return NULL; | 1382 return NULL; |
1544 } | 1383 } |
1545 | 1384 |
1546 // Every export of a module may be assigned. | 1385 // Every export of a module may be assigned. |
1547 for (int i = 0; i < names.length(); ++i) { | 1386 for (int i = 0; i < names.length(); ++i) { |
(...skipping 26 matching lines...) Expand all Loading... |
1574 // ExportDeclaration* declaration = | 1413 // ExportDeclaration* declaration = |
1575 // factory()->NewExportDeclaration(proxy, scope_, position); | 1414 // factory()->NewExportDeclaration(proxy, scope_, position); |
1576 // scope_->AddDeclaration(declaration); | 1415 // scope_->AddDeclaration(declaration); |
1577 } | 1416 } |
1578 | 1417 |
1579 DCHECK(result != NULL); | 1418 DCHECK(result != NULL); |
1580 return result; | 1419 return result; |
1581 } | 1420 } |
1582 | 1421 |
1583 | 1422 |
1584 Statement* Parser::ParseBlockElement(ZoneList<const AstRawString*>* labels, | |
1585 bool* ok) { | |
1586 // (Ecma 262 5th Edition, clause 14): | |
1587 // SourceElement: | |
1588 // Statement | |
1589 // FunctionDeclaration | |
1590 // | |
1591 // In harmony mode we allow additionally the following productions | |
1592 // BlockElement (aka SourceElement): | |
1593 // LetDeclaration | |
1594 // ConstDeclaration | |
1595 // GeneratorDeclaration | |
1596 // ClassDeclaration | |
1597 | |
1598 switch (peek()) { | |
1599 case Token::FUNCTION: | |
1600 return ParseFunctionDeclaration(NULL, ok); | |
1601 case Token::CLASS: | |
1602 return ParseClassDeclaration(NULL, ok); | |
1603 case Token::CONST: | |
1604 return ParseVariableStatement(kModuleElement, NULL, ok); | |
1605 case Token::LET: | |
1606 DCHECK(allow_harmony_scoping()); | |
1607 if (strict_mode() == STRICT) { | |
1608 return ParseVariableStatement(kModuleElement, NULL, ok); | |
1609 } | |
1610 // Fall through. | |
1611 default: | |
1612 return ParseStatement(labels, ok); | |
1613 } | |
1614 } | |
1615 | |
1616 | |
1617 Statement* Parser::ParseStatement(ZoneList<const AstRawString*>* labels, | 1423 Statement* Parser::ParseStatement(ZoneList<const AstRawString*>* labels, |
1618 bool* ok) { | 1424 bool* ok) { |
1619 // Statement :: | 1425 // Statement :: |
1620 // Block | 1426 // Block |
1621 // VariableStatement | 1427 // VariableStatement |
1622 // EmptyStatement | 1428 // EmptyStatement |
1623 // ExpressionStatement | 1429 // ExpressionStatement |
1624 // IfStatement | 1430 // IfStatement |
1625 // IterationStatement | 1431 // IterationStatement |
1626 // ContinueStatement | 1432 // ContinueStatement |
(...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2060 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition); | 1866 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition); |
2061 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE); | 1867 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE); |
2062 | 1868 |
2063 // Parse the statements and collect escaping labels. | 1869 // Parse the statements and collect escaping labels. |
2064 Expect(Token::LBRACE, CHECK_OK); | 1870 Expect(Token::LBRACE, CHECK_OK); |
2065 block_scope->set_start_position(scanner()->location().beg_pos); | 1871 block_scope->set_start_position(scanner()->location().beg_pos); |
2066 { BlockState block_state(&scope_, block_scope); | 1872 { BlockState block_state(&scope_, block_scope); |
2067 Target target(&this->target_stack_, body); | 1873 Target target(&this->target_stack_, body); |
2068 | 1874 |
2069 while (peek() != Token::RBRACE) { | 1875 while (peek() != Token::RBRACE) { |
2070 Statement* stat = ParseBlockElement(NULL, CHECK_OK); | 1876 Statement* stat = ParseStatementListItem(CHECK_OK); |
2071 if (stat && !stat->IsEmpty()) { | 1877 if (stat && !stat->IsEmpty()) { |
2072 body->AddStatement(stat, zone()); | 1878 body->AddStatement(stat, zone()); |
2073 } | 1879 } |
2074 } | 1880 } |
2075 } | 1881 } |
2076 Expect(Token::RBRACE, CHECK_OK); | 1882 Expect(Token::RBRACE, CHECK_OK); |
2077 block_scope->set_end_position(scanner()->location().end_pos); | 1883 block_scope->set_end_position(scanner()->location().end_pos); |
2078 block_scope = block_scope->FinalizeBlockScope(); | 1884 block_scope = block_scope->FinalizeBlockScope(); |
2079 body->set_scope(block_scope); | 1885 body->set_scope(block_scope); |
2080 return body; | 1886 return body; |
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2475 // no line-terminator between the two words. | 2281 // no line-terminator between the two words. |
2476 if (extension_ != NULL && peek() == Token::FUNCTION && | 2282 if (extension_ != NULL && peek() == Token::FUNCTION && |
2477 !scanner()->HasAnyLineTerminatorBeforeNext() && expr != NULL && | 2283 !scanner()->HasAnyLineTerminatorBeforeNext() && expr != NULL && |
2478 expr->AsVariableProxy() != NULL && | 2284 expr->AsVariableProxy() != NULL && |
2479 expr->AsVariableProxy()->raw_name() == | 2285 expr->AsVariableProxy()->raw_name() == |
2480 ast_value_factory()->native_string() && | 2286 ast_value_factory()->native_string() && |
2481 !scanner()->literal_contains_escapes()) { | 2287 !scanner()->literal_contains_escapes()) { |
2482 return ParseNativeDeclaration(ok); | 2288 return ParseNativeDeclaration(ok); |
2483 } | 2289 } |
2484 | 2290 |
2485 // Parsed expression statement, or the context-sensitive 'module' keyword. | 2291 // Parsed expression statement, followed by semicolon. |
2486 // Only expect semicolon in the former case. | 2292 // Detect attempts at 'let' declarations in sloppy mode. |
2487 // Also detect attempts at 'let' declarations in sloppy mode. | 2293 if (peek() == Token::IDENTIFIER && expr->AsVariableProxy() != NULL && |
2488 if (!FLAG_harmony_modules || peek() != Token::IDENTIFIER || | 2294 expr->AsVariableProxy()->raw_name() == |
2489 scanner()->HasAnyLineTerminatorBeforeNext() || | 2295 ast_value_factory()->let_string()) { |
2490 expr->AsVariableProxy() == NULL || | 2296 ReportMessage("sloppy_lexical", NULL); |
2491 expr->AsVariableProxy()->raw_name() != | 2297 *ok = false; |
2492 ast_value_factory()->module_string() || | 2298 return NULL; |
2493 scanner()->literal_contains_escapes()) { | |
2494 if (peek() == Token::IDENTIFIER && expr->AsVariableProxy() != NULL && | |
2495 expr->AsVariableProxy()->raw_name() == | |
2496 ast_value_factory()->let_string()) { | |
2497 ReportMessage("sloppy_lexical", NULL); | |
2498 *ok = false; | |
2499 return NULL; | |
2500 } | |
2501 ExpectSemicolon(CHECK_OK); | |
2502 } | 2299 } |
| 2300 ExpectSemicolon(CHECK_OK); |
2503 return factory()->NewExpressionStatement(expr, pos); | 2301 return factory()->NewExpressionStatement(expr, pos); |
2504 } | 2302 } |
2505 | 2303 |
2506 | 2304 |
2507 IfStatement* Parser::ParseIfStatement(ZoneList<const AstRawString*>* labels, | 2305 IfStatement* Parser::ParseIfStatement(ZoneList<const AstRawString*>* labels, |
2508 bool* ok) { | 2306 bool* ok) { |
2509 // IfStatement :: | 2307 // IfStatement :: |
2510 // 'if' '(' Expression ')' Statement ('else' Statement)? | 2308 // 'if' '(' Expression ')' Statement ('else' Statement)? |
2511 | 2309 |
2512 int pos = peek_position(); | 2310 int pos = peek_position(); |
(...skipping 1393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3906 Assignment* assignment = factory()->NewAssignment( | 3704 Assignment* assignment = factory()->NewAssignment( |
3907 Token::INIT_VAR, init_proxy, allocation, RelocInfo::kNoPosition); | 3705 Token::INIT_VAR, init_proxy, allocation, RelocInfo::kNoPosition); |
3908 VariableProxy* get_proxy = factory()->NewVariableProxy( | 3706 VariableProxy* get_proxy = factory()->NewVariableProxy( |
3909 function_state_->generator_object_variable()); | 3707 function_state_->generator_object_variable()); |
3910 Yield* yield = factory()->NewYield( | 3708 Yield* yield = factory()->NewYield( |
3911 get_proxy, assignment, Yield::kInitial, RelocInfo::kNoPosition); | 3709 get_proxy, assignment, Yield::kInitial, RelocInfo::kNoPosition); |
3912 body->Add(factory()->NewExpressionStatement( | 3710 body->Add(factory()->NewExpressionStatement( |
3913 yield, RelocInfo::kNoPosition), zone()); | 3711 yield, RelocInfo::kNoPosition), zone()); |
3914 } | 3712 } |
3915 | 3713 |
3916 ParseSourceElements(body, Token::RBRACE, false, false, NULL, CHECK_OK); | 3714 ParseStatementList(body, Token::RBRACE, false, NULL, CHECK_OK); |
3917 | 3715 |
3918 if (is_generator) { | 3716 if (is_generator) { |
3919 VariableProxy* get_proxy = factory()->NewVariableProxy( | 3717 VariableProxy* get_proxy = factory()->NewVariableProxy( |
3920 function_state_->generator_object_variable()); | 3718 function_state_->generator_object_variable()); |
3921 Expression* undefined = | 3719 Expression* undefined = |
3922 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition); | 3720 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition); |
3923 Yield* yield = factory()->NewYield(get_proxy, undefined, Yield::kFinal, | 3721 Yield* yield = factory()->NewYield(get_proxy, undefined, Yield::kFinal, |
3924 RelocInfo::kNoPosition); | 3722 RelocInfo::kNoPosition); |
3925 body->Add(factory()->NewExpressionStatement( | 3723 body->Add(factory()->NewExpressionStatement( |
3926 yield, RelocInfo::kNoPosition), zone()); | 3724 yield, RelocInfo::kNoPosition), zone()); |
(...skipping 1418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5345 } else { | 5143 } else { |
5346 const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data()); | 5144 const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data()); |
5347 running_hash = StringHasher::ComputeRunningHash(running_hash, data, | 5145 running_hash = StringHasher::ComputeRunningHash(running_hash, data, |
5348 raw_string->length()); | 5146 raw_string->length()); |
5349 } | 5147 } |
5350 } | 5148 } |
5351 | 5149 |
5352 return running_hash; | 5150 return running_hash; |
5353 } | 5151 } |
5354 } } // namespace v8::internal | 5152 } } // namespace v8::internal |
OLD | NEW |