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 1228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1239 !scanner().literal_contains_escapes()) { | 1239 !scanner().literal_contains_escapes()) { |
1240 return ParseModuleDeclaration(NULL, ok); | 1240 return ParseModuleDeclaration(NULL, ok); |
1241 } | 1241 } |
1242 } | 1242 } |
1243 return stmt; | 1243 return stmt; |
1244 } | 1244 } |
1245 } | 1245 } |
1246 } | 1246 } |
1247 | 1247 |
1248 | 1248 |
1249 Block* Parser::ParseModuleDeclaration(ZoneStringList* names, bool* ok) { | 1249 Statement* Parser::ParseModuleDeclaration(ZoneStringList* names, bool* ok) { |
1250 // ModuleDeclaration: | 1250 // ModuleDeclaration: |
1251 // 'module' Identifier Module | 1251 // 'module' Identifier Module |
1252 | 1252 |
1253 // Create new block with one expected declaration. | |
1254 Block* block = factory()->NewBlock(NULL, 1, true); | |
1255 Handle<String> name = ParseIdentifier(CHECK_OK); | 1253 Handle<String> name = ParseIdentifier(CHECK_OK); |
1256 | 1254 |
1257 #ifdef DEBUG | 1255 #ifdef DEBUG |
1258 if (FLAG_print_interface_details) | 1256 if (FLAG_print_interface_details) |
1259 PrintF("# Module %s...\n", name->ToAsciiArray()); | 1257 PrintF("# Module %s...\n", name->ToAsciiArray()); |
1260 #endif | 1258 #endif |
1261 | 1259 |
1262 Module* module = ParseModule(CHECK_OK); | 1260 Module* module = ParseModule(CHECK_OK); |
1263 VariableProxy* proxy = NewUnresolved(name, LET, module->interface()); | 1261 VariableProxy* proxy = NewUnresolved(name, LET, module->interface()); |
1264 Declaration* declaration = | 1262 Declaration* declaration = |
1265 factory()->NewModuleDeclaration(proxy, module, top_scope_); | 1263 factory()->NewModuleDeclaration(proxy, module, top_scope_); |
1266 Declare(declaration, true, CHECK_OK); | 1264 Declare(declaration, true, CHECK_OK); |
1267 | 1265 |
1268 #ifdef DEBUG | 1266 #ifdef DEBUG |
1269 if (FLAG_print_interface_details) | 1267 if (FLAG_print_interface_details) |
1270 PrintF("# Module %s.\n", name->ToAsciiArray()); | 1268 PrintF("# Module %s.\n", name->ToAsciiArray()); |
1271 | 1269 |
1272 if (FLAG_print_interfaces) { | 1270 if (FLAG_print_interfaces) { |
1273 PrintF("module %s : ", name->ToAsciiArray()); | 1271 PrintF("module %s : ", name->ToAsciiArray()); |
1274 module->interface()->Print(); | 1272 module->interface()->Print(); |
1275 } | 1273 } |
1276 #endif | 1274 #endif |
1277 | 1275 |
1278 // TODO(rossberg): Add initialization statement to block. | |
1279 | |
1280 if (names) names->Add(name, zone()); | 1276 if (names) names->Add(name, zone()); |
1281 return block; | 1277 if (module->body() == NULL) |
| 1278 return factory()->NewEmptyStatement(); |
| 1279 else |
| 1280 return module->body(); |
1282 } | 1281 } |
1283 | 1282 |
1284 | 1283 |
1285 Module* Parser::ParseModule(bool* ok) { | 1284 Module* Parser::ParseModule(bool* ok) { |
1286 // Module: | 1285 // Module: |
1287 // '{' ModuleElement '}' | 1286 // '{' ModuleElement '}' |
1288 // '=' ModulePath ';' | 1287 // '=' ModulePath ';' |
1289 // 'at' String ';' | 1288 // 'at' String ';' |
1290 | 1289 |
1291 switch (peek()) { | 1290 switch (peek()) { |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1337 body->AddStatement(stat, zone()); | 1336 body->AddStatement(stat, zone()); |
1338 block_finder.Update(stat); | 1337 block_finder.Update(stat); |
1339 } | 1338 } |
1340 } | 1339 } |
1341 } | 1340 } |
1342 | 1341 |
1343 Expect(Token::RBRACE, CHECK_OK); | 1342 Expect(Token::RBRACE, CHECK_OK); |
1344 scope->set_end_position(scanner().location().end_pos); | 1343 scope->set_end_position(scanner().location().end_pos); |
1345 body->set_scope(scope); | 1344 body->set_scope(scope); |
1346 | 1345 |
1347 // Instance objects have to be created ahead of time (before code generation | 1346 // Check that all exports are bound. |
1348 // linking them) because of potentially cyclic references between them. | |
1349 // We create them here, to avoid another pass over the AST. | |
1350 Interface* interface = scope->interface(); | 1347 Interface* interface = scope->interface(); |
| 1348 for (Interface::Iterator it = interface->iterator(); |
| 1349 !it.done(); it.Advance()) { |
| 1350 if (scope->LocalLookup(it.name()) == NULL) { |
| 1351 Handle<String> name(it.name()); |
| 1352 ReportMessage("module_export_undefined", |
| 1353 Vector<Handle<String> >(&name, 1)); |
| 1354 *ok = false; |
| 1355 return NULL; |
| 1356 } |
| 1357 } |
| 1358 |
1351 interface->MakeModule(ok); | 1359 interface->MakeModule(ok); |
1352 ASSERT(ok); | 1360 ASSERT(*ok); |
1353 interface->MakeSingleton(Isolate::Current()->factory()->NewJSModule(), ok); | |
1354 ASSERT(ok); | |
1355 interface->Freeze(ok); | 1361 interface->Freeze(ok); |
1356 ASSERT(ok); | 1362 ASSERT(*ok); |
1357 return factory()->NewModuleLiteral(body, interface); | 1363 return factory()->NewModuleLiteral(body, interface); |
1358 } | 1364 } |
1359 | 1365 |
1360 | 1366 |
1361 Module* Parser::ParseModulePath(bool* ok) { | 1367 Module* Parser::ParseModulePath(bool* ok) { |
1362 // ModulePath: | 1368 // ModulePath: |
1363 // Identifier | 1369 // Identifier |
1364 // ModulePath '.' Identifier | 1370 // ModulePath '.' Identifier |
1365 | 1371 |
1366 Module* result = ParseModuleVariable(CHECK_OK); | 1372 Module* result = ParseModuleVariable(CHECK_OK); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1417 Handle<String> symbol = GetSymbol(CHECK_OK); | 1423 Handle<String> symbol = GetSymbol(CHECK_OK); |
1418 | 1424 |
1419 // TODO(ES6): Request JS resource from environment... | 1425 // TODO(ES6): Request JS resource from environment... |
1420 | 1426 |
1421 #ifdef DEBUG | 1427 #ifdef DEBUG |
1422 if (FLAG_print_interface_details) PrintF("# Url "); | 1428 if (FLAG_print_interface_details) PrintF("# Url "); |
1423 #endif | 1429 #endif |
1424 | 1430 |
1425 Module* result = factory()->NewModuleUrl(symbol); | 1431 Module* result = factory()->NewModuleUrl(symbol); |
1426 Interface* interface = result->interface(); | 1432 Interface* interface = result->interface(); |
1427 interface->MakeSingleton(Isolate::Current()->factory()->NewJSModule(), ok); | |
1428 ASSERT(ok); | |
1429 interface->Freeze(ok); | 1433 interface->Freeze(ok); |
1430 ASSERT(ok); | 1434 ASSERT(*ok); |
| 1435 // Create dummy scope to avoid errors as long as the feature isn't finished. |
| 1436 Scope* scope = NewScope(top_scope_, MODULE_SCOPE); |
| 1437 interface->Unify(scope->interface(), zone(), ok); |
| 1438 ASSERT(*ok); |
1431 return result; | 1439 return result; |
1432 } | 1440 } |
1433 | 1441 |
1434 | 1442 |
1435 Module* Parser::ParseModuleSpecifier(bool* ok) { | 1443 Module* Parser::ParseModuleSpecifier(bool* ok) { |
1436 // ModuleSpecifier: | 1444 // ModuleSpecifier: |
1437 // String | 1445 // String |
1438 // ModulePath | 1446 // ModulePath |
1439 | 1447 |
1440 if (peek() == Token::STRING) { | 1448 if (peek() == Token::STRING) { |
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1736 } | 1744 } |
1737 | 1745 |
1738 | 1746 |
1739 void Parser::Declare(Declaration* declaration, bool resolve, bool* ok) { | 1747 void Parser::Declare(Declaration* declaration, bool resolve, bool* ok) { |
1740 VariableProxy* proxy = declaration->proxy(); | 1748 VariableProxy* proxy = declaration->proxy(); |
1741 Handle<String> name = proxy->name(); | 1749 Handle<String> name = proxy->name(); |
1742 VariableMode mode = declaration->mode(); | 1750 VariableMode mode = declaration->mode(); |
1743 Scope* declaration_scope = DeclarationScope(mode); | 1751 Scope* declaration_scope = DeclarationScope(mode); |
1744 Variable* var = NULL; | 1752 Variable* var = NULL; |
1745 | 1753 |
1746 // If a function scope exists, then we can statically declare this | 1754 // If a suitable scope exists, then we can statically declare this |
1747 // variable and also set its mode. In any case, a Declaration node | 1755 // variable and also set its mode. In any case, a Declaration node |
1748 // will be added to the scope so that the declaration can be added | 1756 // will be added to the scope so that the declaration can be added |
1749 // to the corresponding activation frame at runtime if necessary. | 1757 // to the corresponding activation frame at runtime if necessary. |
1750 // For instance declarations inside an eval scope need to be added | 1758 // For instance declarations inside an eval scope need to be added |
1751 // to the calling function context. | 1759 // to the calling function context. |
1752 // Similarly, strict mode eval scope does not leak variable declarations to | 1760 // Similarly, strict mode eval scope does not leak variable declarations to |
1753 // the caller's scope so we declare all locals, too. | 1761 // the caller's scope so we declare all locals, too. |
1754 // Also for block scoped let/const bindings the variable can be | |
1755 // statically declared. | |
1756 if (declaration_scope->is_function_scope() || | 1762 if (declaration_scope->is_function_scope() || |
1757 declaration_scope->is_strict_or_extended_eval_scope() || | 1763 declaration_scope->is_strict_or_extended_eval_scope() || |
1758 declaration_scope->is_block_scope() || | 1764 declaration_scope->is_block_scope() || |
1759 declaration_scope->is_module_scope() || | 1765 declaration_scope->is_module_scope() || |
1760 declaration->AsModuleDeclaration() != NULL) { | 1766 declaration->AsModuleDeclaration() != NULL) { |
1761 // Declare the variable in the function scope. | 1767 // Declare the variable in the declaration scope. |
1762 var = declaration_scope->LocalLookup(name); | 1768 var = declaration_scope->LocalLookup(name); |
1763 if (var == NULL) { | 1769 if (var == NULL) { |
1764 // Declare the name. | 1770 // Declare the name. |
1765 var = declaration_scope->DeclareLocal( | 1771 var = declaration_scope->DeclareLocal( |
1766 name, mode, declaration->initialization(), proxy->interface()); | 1772 name, mode, declaration->initialization(), proxy->interface()); |
1767 } else { | 1773 } else { |
1768 // The name was declared in this scope before; check for conflicting | 1774 // The name was declared in this scope before; check for conflicting |
1769 // re-declarations. We have a conflict if either of the declarations is | 1775 // re-declarations. We have a conflict if either of the declarations is |
1770 // not a var. There is similar code in runtime.cc in the Declare | 1776 // not a var. There is similar code in runtime.cc in the Declare |
1771 // functions. The function CheckNonConflictingScope checks for conflicting | 1777 // functions. The function CheckNonConflictingScope checks for conflicting |
(...skipping 4292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6064 ASSERT(info->isolate()->has_pending_exception()); | 6070 ASSERT(info->isolate()->has_pending_exception()); |
6065 } else { | 6071 } else { |
6066 result = parser.ParseProgram(); | 6072 result = parser.ParseProgram(); |
6067 } | 6073 } |
6068 } | 6074 } |
6069 info->SetFunction(result); | 6075 info->SetFunction(result); |
6070 return (result != NULL); | 6076 return (result != NULL); |
6071 } | 6077 } |
6072 | 6078 |
6073 } } // namespace v8::internal | 6079 } } // namespace v8::internal |
OLD | NEW |