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 // 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 1252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1263 } | 1263 } |
| 1264 | 1264 |
| 1265 interface->MakeModule(ok); | 1265 interface->MakeModule(ok); |
| 1266 DCHECK(*ok); | 1266 DCHECK(*ok); |
| 1267 interface->Freeze(ok); | 1267 interface->Freeze(ok); |
| 1268 DCHECK(*ok); | 1268 DCHECK(*ok); |
| 1269 return factory()->NewModuleLiteral(body, interface, pos); | 1269 return factory()->NewModuleLiteral(body, interface, pos); |
| 1270 } | 1270 } |
| 1271 | 1271 |
| 1272 | 1272 |
| 1273 Module* Parser::ParseModuleUrl(bool* ok) { | 1273 Module* Parser::ParseModuleSpecifier(bool* ok) { |
| 1274 // Module: | 1274 // Module: |
| 1275 // String | 1275 // String |
| 1276 | 1276 |
| 1277 int pos = peek_position(); | 1277 int pos = peek_position(); |
| 1278 Expect(Token::STRING, CHECK_OK); | 1278 Expect(Token::STRING, CHECK_OK); |
| 1279 const AstRawString* symbol = GetSymbol(scanner()); | 1279 const AstRawString* symbol = GetSymbol(scanner()); |
| 1280 | 1280 |
| 1281 // TODO(ES6): Request JS resource from environment... | 1281 // TODO(ES6): Request JS resource from environment... |
| 1282 | 1282 |
| 1283 #ifdef DEBUG | 1283 #ifdef DEBUG |
| 1284 if (FLAG_print_interface_details) PrintF("# Url "); | 1284 if (FLAG_print_interface_details) PrintF("# Url "); |
| 1285 #endif | 1285 #endif |
| 1286 | 1286 |
| 1287 // 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. |
| 1288 USE(symbol); | 1288 USE(symbol); |
| 1289 Scope* scope = NewScope(scope_, MODULE_SCOPE); | 1289 Scope* scope = NewScope(scope_, MODULE_SCOPE); |
| 1290 Block* body = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition); | 1290 Block* body = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition); |
| 1291 body->set_scope(scope); | 1291 body->set_scope(scope); |
| 1292 Interface* interface = scope->interface(); | 1292 Interface* interface = scope->interface(); |
| 1293 Module* result = factory()->NewModuleLiteral(body, interface, pos); | 1293 Module* result = factory()->NewModuleLiteral(body, interface, pos); |
| 1294 interface->Freeze(ok); | 1294 interface->Freeze(ok); |
| 1295 DCHECK(*ok); | 1295 DCHECK(*ok); |
| 1296 interface->Unify(scope->interface(), zone(), ok); | 1296 interface->Unify(scope->interface(), zone(), ok); |
| 1297 DCHECK(*ok); | 1297 DCHECK(*ok); |
| 1298 return result; | 1298 return result; |
| 1299 } | 1299 } |
| 1300 | 1300 |
| 1301 | 1301 |
| 1302 void* Parser::ParseModuleDeclarationClause( | |
| 1303 ZoneList<const AstRawString*>* names, bool* ok) { | |
| 1304 // Handles both imports and exports: | |
| 1305 // | |
| 1306 // ImportOrExportClause : | |
| 1307 // '{' '}' | |
| 1308 // '{' ImportOrExportsList '}' | |
| 1309 // '{' ImportOrExportsList ',' '}' | |
| 1310 // | |
| 1311 // ImportOrExportsList : | |
| 1312 // ImportOrExportSpecifier | |
| 1313 // ImportOrExportsList ',' ImportOrExportSpecifier | |
| 1314 // | |
| 1315 // ImportOrExportSpecifier : | |
| 1316 // IdentifierName | |
| 1317 // IdentifierName 'as' IdentifierName | |
| 1318 | |
| 1319 Expect(Token::LBRACE, CHECK_OK); | |
| 1320 | |
| 1321 while (peek() != Token::RBRACE) { | |
| 1322 const AstRawString* name = ParseIdentifierName(CHECK_OK); | |
| 1323 names->Add(name, zone()); | |
| 1324 const AstRawString* export_name = NULL; | |
| 1325 if (CheckContextualKeyword(CStrVector("as"))) { | |
| 1326 export_name = ParseIdentifierName(CHECK_OK); | |
| 1327 } | |
| 1328 // TODO(ES6): Return the export_name as well as the name. | |
| 1329 USE(export_name); | |
| 1330 if (peek() == Token::RBRACE) break; | |
| 1331 Expect(Token::COMMA, CHECK_OK); | |
| 1332 } | |
| 1333 | |
| 1334 Expect(Token::RBRACE, CHECK_OK); | |
| 1335 | |
| 1336 return 0; | |
| 1337 } | |
| 1338 | |
| 1339 | |
| 1302 Statement* Parser::ParseImportDeclaration(bool* ok) { | 1340 Statement* Parser::ParseImportDeclaration(bool* ok) { |
| 1303 // ImportDeclaration: | 1341 // ImportDeclaration: |
| 1304 // 'import' IdentifierName (',' IdentifierName)* 'from' ModuleUrl ';' | 1342 // 'import' IdentifierName (',' IdentifierName)* 'from' ModuleUrl ';' |
| 1305 // | 1343 // |
| 1306 // TODO(ES6): implement current syntax | 1344 // TODO(ES6): implement current syntax |
| 1307 | 1345 |
| 1308 int pos = peek_position(); | 1346 int pos = peek_position(); |
| 1309 Expect(Token::IMPORT, CHECK_OK); | 1347 Expect(Token::IMPORT, CHECK_OK); |
| 1310 ZoneList<const AstRawString*> names(1, zone()); | 1348 ZoneList<const AstRawString*> names(1, zone()); |
| 1311 | 1349 |
| 1312 const AstRawString* name = ParseIdentifierName(CHECK_OK); | 1350 const AstRawString* name = ParseIdentifierName(CHECK_OK); |
| 1313 names.Add(name, zone()); | 1351 names.Add(name, zone()); |
| 1314 while (peek() == Token::COMMA) { | 1352 while (peek() == Token::COMMA) { |
| 1315 Consume(Token::COMMA); | 1353 Consume(Token::COMMA); |
| 1316 name = ParseIdentifierName(CHECK_OK); | 1354 name = ParseIdentifierName(CHECK_OK); |
| 1317 names.Add(name, zone()); | 1355 names.Add(name, zone()); |
| 1318 } | 1356 } |
| 1319 | 1357 |
| 1320 ExpectContextualKeyword(CStrVector("from"), CHECK_OK); | 1358 ExpectContextualKeyword(CStrVector("from"), CHECK_OK); |
| 1321 Module* module = ParseModuleUrl(CHECK_OK); | 1359 Module* module = ParseModuleSpecifier(CHECK_OK); |
| 1322 ExpectSemicolon(CHECK_OK); | 1360 ExpectSemicolon(CHECK_OK); |
| 1323 | 1361 |
| 1324 // TODO(ES6): Do something with ParseModuleUrl's return value. | 1362 // TODO(ES6): Do something with ParseModuleSpecifier's return value. |
| 1325 USE(module); | 1363 USE(module); |
| 1326 | 1364 |
| 1327 for (int i = 0; i < names.length(); ++i) { | 1365 for (int i = 0; i < names.length(); ++i) { |
| 1328 // TODO(ES6): Add an appropriate declaration for each name | 1366 // TODO(ES6): Add an appropriate declaration for each name |
| 1329 } | 1367 } |
| 1330 | 1368 |
| 1331 return factory()->NewEmptyStatement(pos); | 1369 return factory()->NewEmptyStatement(pos); |
| 1332 } | 1370 } |
| 1333 | 1371 |
| 1334 | 1372 |
| 1373 Statement* Parser::ParseExportDefault(bool* ok) { | |
| 1374 // Supports the following productions, starting after the 'default' token: | |
| 1375 // 'export' 'default' FunctionDeclaration | |
| 1376 // 'export' 'default' ClassDeclaration | |
| 1377 // 'export' 'default' AssignmentExpression[In] ';' | |
| 1378 // | |
| 1379 // TODO(ES6): Allow FunctionDeclaration[Default] and | |
| 1380 // ClassDeclaration[Default]. | |
| 1381 | |
| 1382 Statement* result = NULL; | |
| 1383 switch (peek()) { | |
| 1384 case Token::FUNCTION: | |
|
arv (Not doing code reviews)
2015/01/28 02:57:19
This is going to be problematic. export default su
adamk
2015/01/28 18:05:04
That's the TODO above about FunctionDeclaration[De
| |
| 1385 result = ParseFunctionDeclaration(NULL, CHECK_OK); | |
| 1386 break; | |
| 1387 | |
| 1388 case Token::CLASS: | |
| 1389 result = ParseClassDeclaration(NULL, CHECK_OK); | |
|
arv (Not doing code reviews)
2015/01/28 02:57:19
Same here
| |
| 1390 break; | |
| 1391 | |
| 1392 default: { | |
| 1393 int pos = peek_position(); | |
| 1394 Expression* expr = ParseAssignmentExpression(true, CHECK_OK); | |
| 1395 ExpectSemicolon(CHECK_OK); | |
| 1396 result = factory()->NewExpressionStatement(expr, pos); | |
| 1397 break; | |
| 1398 } | |
| 1399 } | |
| 1400 | |
| 1401 // TODO(ES6): Add default export to scope_->interface() | |
| 1402 | |
| 1403 return result; | |
| 1404 } | |
| 1405 | |
| 1406 | |
| 1335 Statement* Parser::ParseExportDeclaration(bool* ok) { | 1407 Statement* Parser::ParseExportDeclaration(bool* ok) { |
| 1336 // ExportDeclaration: | 1408 // ExportDeclaration: |
| 1337 // 'export' Identifier (',' Identifier)* ';' | 1409 // 'export' '*' 'from' ModuleSpecifier ';' |
| 1338 // 'export' VariableDeclaration | 1410 // 'export' ExportClause ('from' ModuleSpecifier)? ';' |
| 1339 // 'export' FunctionDeclaration | 1411 // 'export' VariableStatement |
| 1340 // 'export' GeneratorDeclaration | 1412 // 'export' Declaration |
| 1341 // 'export' ModuleDeclaration | 1413 // 'export' 'default' ... (handled in ParseExportDefault) |
| 1342 // | |
| 1343 // TODO(ES6): implement current syntax | |
| 1344 | 1414 |
| 1415 int pos = peek_position(); | |
| 1345 Expect(Token::EXPORT, CHECK_OK); | 1416 Expect(Token::EXPORT, CHECK_OK); |
| 1346 | 1417 |
| 1347 Statement* result = NULL; | 1418 Statement* result = NULL; |
| 1348 ZoneList<const AstRawString*> names(1, zone()); | 1419 ZoneList<const AstRawString*> names(1, zone()); |
| 1420 bool is_export_from = false; | |
| 1349 switch (peek()) { | 1421 switch (peek()) { |
| 1350 case Token::IDENTIFIER: { | 1422 case Token::DEFAULT: |
| 1351 int pos = position(); | 1423 Consume(Token::DEFAULT); |
| 1352 const AstRawString* name = | 1424 return ParseExportDefault(ok); |
| 1353 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | 1425 |
| 1354 names.Add(name, zone()); | 1426 case Token::MUL: { |
| 1355 while (peek() == Token::COMMA) { | 1427 Consume(Token::MUL); |
| 1356 Consume(Token::COMMA); | 1428 ExpectContextualKeyword(CStrVector("from"), CHECK_OK); |
| 1357 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | 1429 Module* module = ParseModuleSpecifier(CHECK_OK); |
| 1358 names.Add(name, zone()); | 1430 ExpectSemicolon(CHECK_OK); |
| 1431 // TODO(ES6): Do something with the return value | |
| 1432 // of ParseModuleSpecifier. | |
| 1433 USE(module); | |
| 1434 is_export_from = true; | |
| 1435 result = factory()->NewEmptyStatement(pos); | |
| 1436 break; | |
| 1437 } | |
| 1438 | |
| 1439 case Token::LBRACE: | |
| 1440 ParseModuleDeclarationClause(&names, CHECK_OK); | |
| 1441 if (CheckContextualKeyword(CStrVector("from"))) { | |
| 1442 Module* module = ParseModuleSpecifier(CHECK_OK); | |
| 1443 // TODO(ES6): Do something with the return value | |
| 1444 // of ParseModuleSpecifier. | |
| 1445 USE(module); | |
| 1446 is_export_from = true; | |
| 1359 } | 1447 } |
| 1360 ExpectSemicolon(CHECK_OK); | 1448 ExpectSemicolon(CHECK_OK); |
| 1361 result = factory()->NewEmptyStatement(pos); | 1449 result = factory()->NewEmptyStatement(pos); |
| 1362 break; | 1450 break; |
| 1363 } | |
| 1364 | 1451 |
| 1365 case Token::FUNCTION: | 1452 case Token::FUNCTION: |
| 1366 result = ParseFunctionDeclaration(&names, CHECK_OK); | 1453 result = ParseFunctionDeclaration(&names, CHECK_OK); |
| 1367 break; | 1454 break; |
| 1368 | 1455 |
| 1369 case Token::CLASS: | 1456 case Token::CLASS: |
| 1370 result = ParseClassDeclaration(&names, CHECK_OK); | 1457 result = ParseClassDeclaration(&names, CHECK_OK); |
| 1371 break; | 1458 break; |
| 1372 | 1459 |
| 1373 case Token::VAR: | 1460 case Token::VAR: |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 1388 if (var == NULL) { | 1475 if (var == NULL) { |
| 1389 // TODO(sigurds) This is an export that has no definition yet, | 1476 // TODO(sigurds) This is an export that has no definition yet, |
| 1390 // not clear what to do in this case. | 1477 // not clear what to do in this case. |
| 1391 continue; | 1478 continue; |
| 1392 } | 1479 } |
| 1393 if (!IsImmutableVariableMode(var->mode())) { | 1480 if (!IsImmutableVariableMode(var->mode())) { |
| 1394 var->set_maybe_assigned(); | 1481 var->set_maybe_assigned(); |
| 1395 } | 1482 } |
| 1396 } | 1483 } |
| 1397 | 1484 |
| 1398 // Extract declared names into export declarations and interface. | 1485 // TODO(ES6): Handle 'export from' once imports are properly implemented. |
| 1399 Interface* interface = scope_->interface(); | 1486 // For now we just drop such exports on the floor. |
| 1400 for (int i = 0; i < names.length(); ++i) { | 1487 if (!is_export_from) { |
| 1488 // Extract declared names into export declarations and interface. | |
| 1489 Interface* interface = scope_->interface(); | |
| 1490 for (int i = 0; i < names.length(); ++i) { | |
| 1401 #ifdef DEBUG | 1491 #ifdef DEBUG |
| 1402 if (FLAG_print_interface_details) | 1492 if (FLAG_print_interface_details) |
| 1403 PrintF("# Export %.*s ", names[i]->length(), names[i]->raw_data()); | 1493 PrintF("# Export %.*s ", names[i]->length(), names[i]->raw_data()); |
| 1404 #endif | 1494 #endif |
| 1405 Interface* inner = Interface::NewUnknown(zone()); | 1495 Interface* inner = Interface::NewUnknown(zone()); |
| 1406 interface->Add(names[i], inner, zone(), CHECK_OK); | 1496 interface->Add(names[i], inner, zone(), CHECK_OK); |
| 1407 if (!*ok) | 1497 if (!*ok) |
| 1408 return NULL; | 1498 return NULL; |
| 1409 VariableProxy* proxy = NewUnresolved(names[i], LET, inner); | 1499 VariableProxy* proxy = NewUnresolved(names[i], LET, inner); |
| 1410 USE(proxy); | 1500 USE(proxy); |
| 1411 // TODO(rossberg): Rethink whether we actually need to store export | 1501 // TODO(rossberg): Rethink whether we actually need to store export |
| 1412 // declarations (for compilation?). | 1502 // declarations (for compilation?). |
| 1413 // ExportDeclaration* declaration = | 1503 // ExportDeclaration* declaration = |
| 1414 // factory()->NewExportDeclaration(proxy, scope_, position); | 1504 // factory()->NewExportDeclaration(proxy, scope_, position); |
| 1415 // scope_->AddDeclaration(declaration); | 1505 // scope_->AddDeclaration(declaration); |
| 1506 } | |
| 1416 } | 1507 } |
| 1417 | 1508 |
| 1418 DCHECK(result != NULL); | 1509 DCHECK(result != NULL); |
| 1419 return result; | 1510 return result; |
| 1420 } | 1511 } |
| 1421 | 1512 |
| 1422 | 1513 |
| 1423 Statement* Parser::ParseStatement(ZoneList<const AstRawString*>* labels, | 1514 Statement* Parser::ParseStatement(ZoneList<const AstRawString*>* labels, |
| 1424 bool* ok) { | 1515 bool* ok) { |
| 1425 // Statement :: | 1516 // Statement :: |
| (...skipping 3717 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5143 } else { | 5234 } else { |
| 5144 const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data()); | 5235 const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data()); |
| 5145 running_hash = StringHasher::ComputeRunningHash(running_hash, data, | 5236 running_hash = StringHasher::ComputeRunningHash(running_hash, data, |
| 5146 raw_string->length()); | 5237 raw_string->length()); |
| 5147 } | 5238 } |
| 5148 } | 5239 } |
| 5149 | 5240 |
| 5150 return running_hash; | 5241 return running_hash; |
| 5151 } | 5242 } |
| 5152 } } // namespace v8::internal | 5243 } } // namespace v8::internal |
| OLD | NEW |