Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/parser.cc

Issue 10690043: Implement proper module linking. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed Michael's comments. Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698