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 1273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1284 *ok = false; | 1284 *ok = false; |
1285 return NULL; | 1285 return NULL; |
1286 } | 1286 } |
1287 } | 1287 } |
1288 | 1288 |
1289 scope_->module()->Freeze(); | 1289 scope_->module()->Freeze(); |
1290 return NULL; | 1290 return NULL; |
1291 } | 1291 } |
1292 | 1292 |
1293 | 1293 |
1294 Literal* Parser::ParseModuleSpecifier(bool* ok) { | 1294 const AstRawString* Parser::ParseModuleSpecifier(bool* ok) { |
1295 // ModuleSpecifier : | 1295 // ModuleSpecifier : |
1296 // StringLiteral | 1296 // StringLiteral |
1297 | 1297 |
1298 int pos = peek_position(); | |
1299 Expect(Token::STRING, CHECK_OK); | 1298 Expect(Token::STRING, CHECK_OK); |
1300 return factory()->NewStringLiteral(GetSymbol(scanner()), pos); | 1299 return GetSymbol(scanner()); |
1301 } | 1300 } |
1302 | 1301 |
1303 | 1302 |
1304 void* Parser::ParseExportClause(ZoneList<const AstRawString*>* export_names, | 1303 void* Parser::ParseExportClause(ZoneList<const AstRawString*>* export_names, |
1305 ZoneList<Scanner::Location>* export_locations, | 1304 ZoneList<Scanner::Location>* export_locations, |
1306 ZoneList<const AstRawString*>* local_names, | 1305 ZoneList<const AstRawString*>* local_names, |
1307 Scanner::Location* reserved_loc, bool* ok) { | 1306 Scanner::Location* reserved_loc, bool* ok) { |
1308 // ExportClause : | 1307 // ExportClause : |
1309 // '{' '}' | 1308 // '{' '}' |
1310 // '{' ExportsList '}' | 1309 // '{' ExportsList '}' |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1342 if (peek() == Token::RBRACE) break; | 1341 if (peek() == Token::RBRACE) break; |
1343 Expect(Token::COMMA, CHECK_OK); | 1342 Expect(Token::COMMA, CHECK_OK); |
1344 } | 1343 } |
1345 | 1344 |
1346 Expect(Token::RBRACE, CHECK_OK); | 1345 Expect(Token::RBRACE, CHECK_OK); |
1347 | 1346 |
1348 return 0; | 1347 return 0; |
1349 } | 1348 } |
1350 | 1349 |
1351 | 1350 |
1352 void* Parser::ParseNamedImports(ZoneList<const AstRawString*>* import_names, | 1351 ZoneList<ImportDeclaration*>* Parser::ParseNamedImports(int pos, bool* ok) { |
1353 ZoneList<const AstRawString*>* local_names, | |
1354 bool* ok) { | |
1355 // NamedImports : | 1352 // NamedImports : |
1356 // '{' '}' | 1353 // '{' '}' |
1357 // '{' ImportsList '}' | 1354 // '{' ImportsList '}' |
1358 // '{' ImportsList ',' '}' | 1355 // '{' ImportsList ',' '}' |
1359 // | 1356 // |
1360 // ImportsList : | 1357 // ImportsList : |
1361 // ImportSpecifier | 1358 // ImportSpecifier |
1362 // ImportsList ',' ImportSpecifier | 1359 // ImportsList ',' ImportSpecifier |
1363 // | 1360 // |
1364 // ImportSpecifier : | 1361 // ImportSpecifier : |
1365 // BindingIdentifier | 1362 // BindingIdentifier |
1366 // IdentifierName 'as' BindingIdentifier | 1363 // IdentifierName 'as' BindingIdentifier |
1367 | 1364 |
1368 Expect(Token::LBRACE, CHECK_OK); | 1365 Expect(Token::LBRACE, CHECK_OK); |
1369 | 1366 |
| 1367 ZoneList<ImportDeclaration*>* result = |
| 1368 new (zone()) ZoneList<ImportDeclaration*>(1, zone()); |
1370 while (peek() != Token::RBRACE) { | 1369 while (peek() != Token::RBRACE) { |
1371 const AstRawString* import_name = ParseIdentifierName(CHECK_OK); | 1370 const AstRawString* import_name = ParseIdentifierName(CHECK_OK); |
1372 const AstRawString* local_name = import_name; | 1371 const AstRawString* local_name = import_name; |
1373 // In the presence of 'as', the left-side of the 'as' can | 1372 // In the presence of 'as', the left-side of the 'as' can |
1374 // be any IdentifierName. But without 'as', it must be a valid | 1373 // be any IdentifierName. But without 'as', it must be a valid |
1375 // BindingIdentifier. | 1374 // BindingIdentifier. |
1376 if (CheckContextualKeyword(CStrVector("as"))) { | 1375 if (CheckContextualKeyword(CStrVector("as"))) { |
1377 local_name = ParseIdentifierName(CHECK_OK); | 1376 local_name = ParseIdentifierName(CHECK_OK); |
1378 } | 1377 } |
1379 if (!Token::IsIdentifier(scanner()->current_token(), STRICT, false)) { | 1378 if (!Token::IsIdentifier(scanner()->current_token(), STRICT, false)) { |
1380 *ok = false; | 1379 *ok = false; |
1381 ReportMessage("unexpected_reserved"); | 1380 ReportMessage("unexpected_reserved"); |
1382 return NULL; | 1381 return NULL; |
1383 } else if (IsEvalOrArguments(local_name)) { | 1382 } else if (IsEvalOrArguments(local_name)) { |
1384 *ok = false; | 1383 *ok = false; |
1385 ReportMessage("strict_eval_arguments"); | 1384 ReportMessage("strict_eval_arguments"); |
1386 return NULL; | 1385 return NULL; |
1387 } | 1386 } |
1388 import_names->Add(import_name, zone()); | 1387 VariableProxy* proxy = NewUnresolved(local_name, IMPORT); |
1389 local_names->Add(local_name, zone()); | 1388 ImportDeclaration* declaration = |
| 1389 factory()->NewImportDeclaration(proxy, import_name, NULL, scope_, pos); |
| 1390 Declare(declaration, true, CHECK_OK); |
| 1391 result->Add(declaration, zone()); |
1390 if (peek() == Token::RBRACE) break; | 1392 if (peek() == Token::RBRACE) break; |
1391 Expect(Token::COMMA, CHECK_OK); | 1393 Expect(Token::COMMA, CHECK_OK); |
1392 } | 1394 } |
1393 | 1395 |
1394 Expect(Token::RBRACE, CHECK_OK); | 1396 Expect(Token::RBRACE, CHECK_OK); |
1395 | 1397 |
1396 return NULL; | 1398 return result; |
1397 } | 1399 } |
1398 | 1400 |
1399 | 1401 |
1400 Statement* Parser::ParseImportDeclaration(bool* ok) { | 1402 Statement* Parser::ParseImportDeclaration(bool* ok) { |
1401 // ImportDeclaration : | 1403 // ImportDeclaration : |
1402 // 'import' ImportClause 'from' ModuleSpecifier ';' | 1404 // 'import' ImportClause 'from' ModuleSpecifier ';' |
1403 // 'import' ModuleSpecifier ';' | 1405 // 'import' ModuleSpecifier ';' |
1404 // | 1406 // |
1405 // ImportClause : | 1407 // ImportClause : |
1406 // NameSpaceImport | 1408 // NameSpaceImport |
1407 // NamedImports | 1409 // NamedImports |
1408 // ImportedDefaultBinding | 1410 // ImportedDefaultBinding |
1409 // ImportedDefaultBinding ',' NameSpaceImport | 1411 // ImportedDefaultBinding ',' NameSpaceImport |
1410 // ImportedDefaultBinding ',' NamedImports | 1412 // ImportedDefaultBinding ',' NamedImports |
1411 // | 1413 // |
1412 // NameSpaceImport : | 1414 // NameSpaceImport : |
1413 // '*' 'as' ImportedBinding | 1415 // '*' 'as' ImportedBinding |
1414 | 1416 |
1415 int pos = peek_position(); | 1417 int pos = peek_position(); |
1416 Expect(Token::IMPORT, CHECK_OK); | 1418 Expect(Token::IMPORT, CHECK_OK); |
1417 | 1419 |
1418 Token::Value tok = peek(); | 1420 Token::Value tok = peek(); |
1419 | 1421 |
1420 // 'import' ModuleSpecifier ';' | 1422 // 'import' ModuleSpecifier ';' |
1421 if (tok == Token::STRING) { | 1423 if (tok == Token::STRING) { |
1422 Literal* module = ParseModuleSpecifier(CHECK_OK); | 1424 const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK); |
1423 ExpectSemicolon(CHECK_OK); | 1425 ExpectSemicolon(CHECK_OK); |
1424 // TODO(ES6): Add module to the requested modules of scope_->module(). | 1426 // TODO(ES6): Add module to the requested modules of scope_->module(). |
1425 USE(module); | 1427 USE(module_specifier); |
1426 return factory()->NewEmptyStatement(pos); | 1428 return factory()->NewEmptyStatement(pos); |
1427 } | 1429 } |
1428 | 1430 |
1429 // Parse ImportedDefaultBinding if present. | 1431 // Parse ImportedDefaultBinding if present. |
1430 const AstRawString* imported_default_binding = NULL; | 1432 const AstRawString* imported_default_binding = NULL; |
1431 if (tok != Token::MUL && tok != Token::LBRACE) { | 1433 if (tok != Token::MUL && tok != Token::LBRACE) { |
1432 imported_default_binding = | 1434 imported_default_binding = |
1433 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | 1435 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
| 1436 // TODO(ES6): Add an appropriate declaration. |
1434 } | 1437 } |
1435 | 1438 |
1436 const AstRawString* module_instance_binding = NULL; | 1439 const AstRawString* module_instance_binding = NULL; |
1437 ZoneList<const AstRawString*> local_names(1, zone()); | 1440 ZoneList<ImportDeclaration*>* named_declarations = NULL; |
1438 ZoneList<const AstRawString*> import_names(1, zone()); | |
1439 if (imported_default_binding == NULL || Check(Token::COMMA)) { | 1441 if (imported_default_binding == NULL || Check(Token::COMMA)) { |
1440 switch (peek()) { | 1442 switch (peek()) { |
1441 case Token::MUL: { | 1443 case Token::MUL: { |
1442 Consume(Token::MUL); | 1444 Consume(Token::MUL); |
1443 ExpectContextualKeyword(CStrVector("as"), CHECK_OK); | 1445 ExpectContextualKeyword(CStrVector("as"), CHECK_OK); |
1444 module_instance_binding = | 1446 module_instance_binding = |
1445 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | 1447 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
| 1448 // TODO(ES6): Add an appropriate declaration. |
1446 break; | 1449 break; |
1447 } | 1450 } |
1448 | 1451 |
1449 case Token::LBRACE: | 1452 case Token::LBRACE: |
1450 ParseNamedImports(&import_names, &local_names, CHECK_OK); | 1453 named_declarations = ParseNamedImports(pos, CHECK_OK); |
1451 break; | 1454 break; |
1452 | 1455 |
1453 default: | 1456 default: |
1454 *ok = false; | 1457 *ok = false; |
1455 ReportUnexpectedToken(scanner()->current_token()); | 1458 ReportUnexpectedToken(scanner()->current_token()); |
1456 return NULL; | 1459 return NULL; |
1457 } | 1460 } |
1458 } | 1461 } |
1459 | 1462 |
1460 ExpectContextualKeyword(CStrVector("from"), CHECK_OK); | 1463 ExpectContextualKeyword(CStrVector("from"), CHECK_OK); |
1461 Literal* module = ParseModuleSpecifier(CHECK_OK); | 1464 const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK); |
1462 USE(module); | |
1463 | |
1464 ExpectSemicolon(CHECK_OK); | 1465 ExpectSemicolon(CHECK_OK); |
1465 | 1466 |
1466 if (module_instance_binding != NULL) { | 1467 if (module_instance_binding != NULL) { |
1467 // TODO(ES6): Bind name to the Module Instance Object of module. | 1468 // TODO(ES6): Set the module specifier for the module namespace binding. |
1468 } | 1469 } |
1469 | 1470 |
1470 if (imported_default_binding != NULL) { | 1471 if (imported_default_binding != NULL) { |
1471 // TODO(ES6): Add an appropriate declaration. | 1472 // TODO(ES6): Set the module specifier for the default binding. |
1472 } | 1473 } |
1473 | 1474 |
1474 const int length = import_names.length(); | 1475 if (named_declarations != NULL) { |
1475 DCHECK_EQ(length, local_names.length()); | 1476 for (int i = 0; i < named_declarations->length(); ++i) { |
1476 for (int i = 0; i < length; ++i) { | 1477 named_declarations->at(i)->set_module_specifier(module_specifier); |
1477 // TODO(ES6): Add an appropriate declaration for each name | 1478 } |
1478 } | 1479 } |
1479 | 1480 |
1480 return factory()->NewEmptyStatement(pos); | 1481 return factory()->NewEmptyStatement(pos); |
1481 } | 1482 } |
1482 | 1483 |
1483 | 1484 |
1484 Statement* Parser::ParseExportDefault(bool* ok) { | 1485 Statement* Parser::ParseExportDefault(bool* ok) { |
1485 // Supports the following productions, starting after the 'default' token: | 1486 // Supports the following productions, starting after the 'default' token: |
1486 // 'export' 'default' FunctionDeclaration | 1487 // 'export' 'default' FunctionDeclaration |
1487 // 'export' 'default' ClassDeclaration | 1488 // 'export' 'default' ClassDeclaration |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1544 | 1545 |
1545 Statement* result = NULL; | 1546 Statement* result = NULL; |
1546 ZoneList<const AstRawString*> names(1, zone()); | 1547 ZoneList<const AstRawString*> names(1, zone()); |
1547 switch (peek()) { | 1548 switch (peek()) { |
1548 case Token::DEFAULT: | 1549 case Token::DEFAULT: |
1549 return ParseExportDefault(ok); | 1550 return ParseExportDefault(ok); |
1550 | 1551 |
1551 case Token::MUL: { | 1552 case Token::MUL: { |
1552 Consume(Token::MUL); | 1553 Consume(Token::MUL); |
1553 ExpectContextualKeyword(CStrVector("from"), CHECK_OK); | 1554 ExpectContextualKeyword(CStrVector("from"), CHECK_OK); |
1554 Literal* module = ParseModuleSpecifier(CHECK_OK); | 1555 const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK); |
1555 ExpectSemicolon(CHECK_OK); | 1556 ExpectSemicolon(CHECK_OK); |
1556 // TODO(ES6): scope_->module()->AddStarExport(...) | 1557 // TODO(ES6): scope_->module()->AddStarExport(...) |
1557 USE(module); | 1558 USE(module_specifier); |
1558 return factory()->NewEmptyStatement(pos); | 1559 return factory()->NewEmptyStatement(pos); |
1559 } | 1560 } |
1560 | 1561 |
1561 case Token::LBRACE: { | 1562 case Token::LBRACE: { |
1562 // There are two cases here: | 1563 // There are two cases here: |
1563 // | 1564 // |
1564 // 'export' ExportClause ';' | 1565 // 'export' ExportClause ';' |
1565 // and | 1566 // and |
1566 // 'export' ExportClause FromClause ';' | 1567 // 'export' ExportClause FromClause ';' |
1567 // | 1568 // |
1568 // In the first case, the exported identifiers in ExportClause must | 1569 // In the first case, the exported identifiers in ExportClause must |
1569 // not be reserved words, while in the latter they may be. We | 1570 // not be reserved words, while in the latter they may be. We |
1570 // pass in a location that gets filled with the first reserved word | 1571 // pass in a location that gets filled with the first reserved word |
1571 // encountered, and then throw a SyntaxError if we are in the | 1572 // encountered, and then throw a SyntaxError if we are in the |
1572 // non-FromClause case. | 1573 // non-FromClause case. |
1573 Scanner::Location reserved_loc = Scanner::Location::invalid(); | 1574 Scanner::Location reserved_loc = Scanner::Location::invalid(); |
1574 ZoneList<const AstRawString*> export_names(1, zone()); | 1575 ZoneList<const AstRawString*> export_names(1, zone()); |
1575 ZoneList<Scanner::Location> export_locations(1, zone()); | 1576 ZoneList<Scanner::Location> export_locations(1, zone()); |
1576 ZoneList<const AstRawString*> local_names(1, zone()); | 1577 ZoneList<const AstRawString*> local_names(1, zone()); |
1577 ParseExportClause(&export_names, &export_locations, &local_names, | 1578 ParseExportClause(&export_names, &export_locations, &local_names, |
1578 &reserved_loc, CHECK_OK); | 1579 &reserved_loc, CHECK_OK); |
1579 Literal* indirect_export_module_specifier = NULL; | 1580 const AstRawString* indirect_export_module_specifier = NULL; |
1580 if (CheckContextualKeyword(CStrVector("from"))) { | 1581 if (CheckContextualKeyword(CStrVector("from"))) { |
1581 indirect_export_module_specifier = ParseModuleSpecifier(CHECK_OK); | 1582 indirect_export_module_specifier = ParseModuleSpecifier(CHECK_OK); |
1582 } else if (reserved_loc.IsValid()) { | 1583 } else if (reserved_loc.IsValid()) { |
1583 // No FromClause, so reserved words are invalid in ExportClause. | 1584 // No FromClause, so reserved words are invalid in ExportClause. |
1584 *ok = false; | 1585 *ok = false; |
1585 ReportMessageAt(reserved_loc, "unexpected_reserved"); | 1586 ReportMessageAt(reserved_loc, "unexpected_reserved"); |
1586 return NULL; | 1587 return NULL; |
1587 } | 1588 } |
1588 ExpectSemicolon(CHECK_OK); | 1589 ExpectSemicolon(CHECK_OK); |
1589 const int length = export_names.length(); | 1590 const int length = export_names.length(); |
(...skipping 3890 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5480 } else { | 5481 } else { |
5481 const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data()); | 5482 const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data()); |
5482 running_hash = StringHasher::ComputeRunningHash(running_hash, data, | 5483 running_hash = StringHasher::ComputeRunningHash(running_hash, data, |
5483 raw_string->length()); | 5484 raw_string->length()); |
5484 } | 5485 } |
5485 } | 5486 } |
5486 | 5487 |
5487 return running_hash; | 5488 return running_hash; |
5488 } | 5489 } |
5489 } } // namespace v8::internal | 5490 } } // namespace v8::internal |
OLD | NEW |