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 1281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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(ZoneList<const AstRawString*>* names, | 1302 void* Parser::ParseExportClause(ZoneList<const AstRawString*>* names, |
1303 bool* ok) { | 1303 Scanner::Location* reserved_loc, bool* ok) { |
1304 // Handles both imports and exports: | 1304 // ExportClause : |
| 1305 // '{' '}' |
| 1306 // '{' ExportsList '}' |
| 1307 // '{' ExportsList ',' '}' |
1305 // | 1308 // |
1306 // ImportOrExportClause : | 1309 // ExportsList : |
1307 // '{' '}' | 1310 // ExportSpecifier |
1308 // '{' ImportOrExportsList '}' | 1311 // ExportsList ',' ExportSpecifier |
1309 // '{' ImportOrExportsList ',' '}' | |
1310 // | 1312 // |
1311 // ImportOrExportsList : | 1313 // ExportSpecifier : |
1312 // ImportOrExportSpecifier | |
1313 // ImportOrExportsList ',' ImportOrExportSpecifier | |
1314 // | |
1315 // ImportOrExportSpecifier : | |
1316 // IdentifierName | 1314 // IdentifierName |
1317 // IdentifierName 'as' IdentifierName | 1315 // IdentifierName 'as' IdentifierName |
1318 | 1316 |
1319 Expect(Token::LBRACE, CHECK_OK); | 1317 Expect(Token::LBRACE, CHECK_OK); |
1320 | 1318 |
1321 while (peek() != Token::RBRACE) { | 1319 Token::Value name_tok; |
| 1320 while ((name_tok = peek()) != Token::RBRACE) { |
| 1321 // Keep track of the first reserved word encountered in case our |
| 1322 // caller needs to report an error. |
| 1323 if (!reserved_loc->IsValid() && |
| 1324 !Token::IsIdentifier(name_tok, STRICT, false)) { |
| 1325 *reserved_loc = scanner()->location(); |
| 1326 } |
1322 const AstRawString* name = ParseIdentifierName(CHECK_OK); | 1327 const AstRawString* name = ParseIdentifierName(CHECK_OK); |
1323 names->Add(name, zone()); | 1328 names->Add(name, zone()); |
1324 const AstRawString* export_name = NULL; | 1329 const AstRawString* export_name = NULL; |
1325 if (CheckContextualKeyword(CStrVector("as"))) { | 1330 if (CheckContextualKeyword(CStrVector("as"))) { |
1326 export_name = ParseIdentifierName(CHECK_OK); | 1331 export_name = ParseIdentifierName(CHECK_OK); |
1327 } | 1332 } |
1328 // TODO(ES6): Return the export_name as well as the name. | 1333 // TODO(ES6): Return the export_name as well as the name. |
1329 USE(export_name); | 1334 USE(export_name); |
1330 if (peek() == Token::RBRACE) break; | 1335 if (peek() == Token::RBRACE) break; |
1331 Expect(Token::COMMA, CHECK_OK); | 1336 Expect(Token::COMMA, CHECK_OK); |
1332 } | 1337 } |
1333 | 1338 |
1334 Expect(Token::RBRACE, CHECK_OK); | 1339 Expect(Token::RBRACE, CHECK_OK); |
1335 | 1340 |
1336 return 0; | 1341 return 0; |
1337 } | 1342 } |
1338 | 1343 |
1339 | 1344 |
| 1345 void* Parser::ParseNamedImports(ZoneList<const AstRawString*>* names, |
| 1346 bool* ok) { |
| 1347 // NamedImports : |
| 1348 // '{' '}' |
| 1349 // '{' ImportsList '}' |
| 1350 // '{' ImportsList ',' '}' |
| 1351 // |
| 1352 // ImportsList : |
| 1353 // ImportSpecifier |
| 1354 // ImportsList ',' ImportSpecifier |
| 1355 // |
| 1356 // ImportSpecifier : |
| 1357 // BindingIdentifier |
| 1358 // IdentifierName 'as' BindingIdentifier |
| 1359 |
| 1360 Expect(Token::LBRACE, CHECK_OK); |
| 1361 |
| 1362 Token::Value name_tok; |
| 1363 while ((name_tok = peek()) != Token::RBRACE) { |
| 1364 const AstRawString* name = ParseIdentifierName(CHECK_OK); |
| 1365 const AstRawString* import_name = NULL; |
| 1366 // In the presence of 'as', the left-side of the 'as' can |
| 1367 // be any IdentifierName. But without 'as', it must be a valid |
| 1368 // BindingIdentiifer. |
| 1369 if (CheckContextualKeyword(CStrVector("as"))) { |
| 1370 import_name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
| 1371 } else if (!Token::IsIdentifier(name_tok, STRICT, false)) { |
| 1372 *ok = false; |
| 1373 ReportMessageAt(scanner()->location(), "unexpected_reserved"); |
| 1374 return NULL; |
| 1375 } else if (IsEvalOrArguments(name)) { |
| 1376 *ok = false; |
| 1377 ReportMessageAt(scanner()->location(), "strict_eval_arguments"); |
| 1378 return NULL; |
| 1379 } |
| 1380 // TODO(ES6): Return the import_name as well as the name. |
| 1381 names->Add(name, zone()); |
| 1382 USE(import_name); |
| 1383 if (peek() == Token::RBRACE) break; |
| 1384 Expect(Token::COMMA, CHECK_OK); |
| 1385 } |
| 1386 |
| 1387 Expect(Token::RBRACE, CHECK_OK); |
| 1388 |
| 1389 return NULL; |
| 1390 } |
| 1391 |
| 1392 |
1340 Statement* Parser::ParseImportDeclaration(bool* ok) { | 1393 Statement* Parser::ParseImportDeclaration(bool* ok) { |
1341 // ImportDeclaration: | 1394 // ImportDeclaration : |
1342 // 'import' IdentifierName (',' IdentifierName)* 'from' ModuleUrl ';' | 1395 // 'import' ImportClause 'from' ModuleSpecifier ';' |
| 1396 // 'import' ModuleSpecifier ';' |
1343 // | 1397 // |
1344 // TODO(ES6): implement current syntax | 1398 // ImportClause : |
| 1399 // NameSpaceImport |
| 1400 // NamedImports |
| 1401 // ImportedDefaultBinding |
| 1402 // ImportedDefaultBinding ',' NameSpaceImport |
| 1403 // ImportedDefaultBinding ',' NamedImports |
| 1404 // |
| 1405 // NameSpaceImport : |
| 1406 // '*' 'as' ImportedBinding |
1345 | 1407 |
1346 int pos = peek_position(); | 1408 int pos = peek_position(); |
1347 Expect(Token::IMPORT, CHECK_OK); | 1409 Expect(Token::IMPORT, CHECK_OK); |
| 1410 |
| 1411 Token::Value tok = peek(); |
| 1412 |
| 1413 // 'import' ModuleSpecifier ';' |
| 1414 if (tok == Token::STRING) { |
| 1415 ParseModuleSpecifier(CHECK_OK); |
| 1416 ExpectSemicolon(CHECK_OK); |
| 1417 return factory()->NewEmptyStatement(pos); |
| 1418 } |
| 1419 |
| 1420 const AstRawString* imported_default_binding = NULL; |
| 1421 if (tok != Token::MUL && tok != Token::LBRACE) { |
| 1422 imported_default_binding = |
| 1423 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
| 1424 } |
| 1425 |
| 1426 const AstRawString* module_instance_binding = NULL; |
1348 ZoneList<const AstRawString*> names(1, zone()); | 1427 ZoneList<const AstRawString*> names(1, zone()); |
| 1428 if (imported_default_binding == NULL || Check(Token::COMMA)) { |
| 1429 switch (peek()) { |
| 1430 case Token::MUL: { |
| 1431 Consume(Token::MUL); |
| 1432 ExpectContextualKeyword(CStrVector("as"), CHECK_OK); |
| 1433 module_instance_binding = |
| 1434 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
| 1435 break; |
| 1436 } |
1349 | 1437 |
1350 const AstRawString* name = ParseIdentifierName(CHECK_OK); | 1438 case Token::LBRACE: |
1351 names.Add(name, zone()); | 1439 ParseNamedImports(&names, CHECK_OK); |
1352 while (peek() == Token::COMMA) { | 1440 break; |
1353 Consume(Token::COMMA); | 1441 |
1354 name = ParseIdentifierName(CHECK_OK); | 1442 default: |
1355 names.Add(name, zone()); | 1443 *ok = false; |
| 1444 ReportUnexpectedToken(scanner()->current_token()); |
| 1445 return NULL; |
| 1446 } |
1356 } | 1447 } |
1357 | 1448 |
1358 ExpectContextualKeyword(CStrVector("from"), CHECK_OK); | 1449 ExpectContextualKeyword(CStrVector("from"), CHECK_OK); |
1359 Module* module = ParseModuleSpecifier(CHECK_OK); | 1450 Module* module = ParseModuleSpecifier(CHECK_OK); |
| 1451 USE(module); |
| 1452 |
1360 ExpectSemicolon(CHECK_OK); | 1453 ExpectSemicolon(CHECK_OK); |
1361 | 1454 |
1362 // TODO(ES6): Do something with ParseModuleSpecifier's return value. | 1455 if (module_instance_binding != NULL) { |
1363 USE(module); | 1456 // TODO(ES6): Bind name to the Module Instance Object of module. |
| 1457 } |
| 1458 |
| 1459 if (imported_default_binding != NULL) { |
| 1460 // TODO(ES6): Add an appropriate declaration. |
| 1461 } |
1364 | 1462 |
1365 for (int i = 0; i < names.length(); ++i) { | 1463 for (int i = 0; i < names.length(); ++i) { |
1366 // TODO(ES6): Add an appropriate declaration for each name | 1464 // TODO(ES6): Add an appropriate declaration for each name |
1367 } | 1465 } |
1368 | 1466 |
1369 return factory()->NewEmptyStatement(pos); | 1467 return factory()->NewEmptyStatement(pos); |
1370 } | 1468 } |
1371 | 1469 |
1372 | 1470 |
1373 Statement* Parser::ParseExportDefault(bool* ok) { | 1471 Statement* Parser::ParseExportDefault(bool* ok) { |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1428 Module* module = ParseModuleSpecifier(CHECK_OK); | 1526 Module* module = ParseModuleSpecifier(CHECK_OK); |
1429 ExpectSemicolon(CHECK_OK); | 1527 ExpectSemicolon(CHECK_OK); |
1430 // TODO(ES6): Do something with the return value | 1528 // TODO(ES6): Do something with the return value |
1431 // of ParseModuleSpecifier. | 1529 // of ParseModuleSpecifier. |
1432 USE(module); | 1530 USE(module); |
1433 is_export_from = true; | 1531 is_export_from = true; |
1434 result = factory()->NewEmptyStatement(pos); | 1532 result = factory()->NewEmptyStatement(pos); |
1435 break; | 1533 break; |
1436 } | 1534 } |
1437 | 1535 |
1438 case Token::LBRACE: | 1536 case Token::LBRACE: { |
1439 ParseModuleDeclarationClause(&names, CHECK_OK); | 1537 // There are two cases here: |
| 1538 // |
| 1539 // 'export' ExportClause ';' |
| 1540 // and |
| 1541 // 'export' ExportClause FromClause ';' |
| 1542 // |
| 1543 // In the first case, the exported identifiers in ExportClause must |
| 1544 // not be reserved words, while in the latter they may be. We |
| 1545 // pass in a location that gets filled with the first reserved word |
| 1546 // encountered, and then throw a SyntaxError if we are in the |
| 1547 // non-FromClause case. |
| 1548 Scanner::Location reserved_loc = Scanner::Location::invalid(); |
| 1549 ParseExportClause(&names, &reserved_loc, CHECK_OK); |
1440 if (CheckContextualKeyword(CStrVector("from"))) { | 1550 if (CheckContextualKeyword(CStrVector("from"))) { |
1441 Module* module = ParseModuleSpecifier(CHECK_OK); | 1551 Module* module = ParseModuleSpecifier(CHECK_OK); |
1442 // TODO(ES6): Do something with the return value | 1552 // TODO(ES6): Do something with the return value |
1443 // of ParseModuleSpecifier. | 1553 // of ParseModuleSpecifier. |
1444 USE(module); | 1554 USE(module); |
1445 is_export_from = true; | 1555 is_export_from = true; |
| 1556 } else if (reserved_loc.IsValid()) { |
| 1557 // No FromClause, so reserved words are invalid in ExportClause. |
| 1558 *ok = false; |
| 1559 ReportMessageAt(reserved_loc, "unexpected_reserved"); |
| 1560 return NULL; |
1446 } | 1561 } |
1447 ExpectSemicolon(CHECK_OK); | 1562 ExpectSemicolon(CHECK_OK); |
1448 result = factory()->NewEmptyStatement(pos); | 1563 result = factory()->NewEmptyStatement(pos); |
1449 break; | 1564 break; |
| 1565 } |
1450 | 1566 |
1451 case Token::FUNCTION: | 1567 case Token::FUNCTION: |
1452 result = ParseFunctionDeclaration(&names, CHECK_OK); | 1568 result = ParseFunctionDeclaration(&names, CHECK_OK); |
1453 break; | 1569 break; |
1454 | 1570 |
1455 case Token::CLASS: | 1571 case Token::CLASS: |
1456 result = ParseClassDeclaration(&names, CHECK_OK); | 1572 result = ParseClassDeclaration(&names, CHECK_OK); |
1457 break; | 1573 break; |
1458 | 1574 |
1459 case Token::VAR: | 1575 case Token::VAR: |
(...skipping 3772 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5232 } else { | 5348 } else { |
5233 const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data()); | 5349 const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data()); |
5234 running_hash = StringHasher::ComputeRunningHash(running_hash, data, | 5350 running_hash = StringHasher::ComputeRunningHash(running_hash, data, |
5235 raw_string->length()); | 5351 raw_string->length()); |
5236 } | 5352 } |
5237 } | 5353 } |
5238 | 5354 |
5239 return running_hash; | 5355 return running_hash; |
5240 } | 5356 } |
5241 } } // namespace v8::internal | 5357 } } // namespace v8::internal |
OLD | NEW |