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/base/platform/platform.h" | 9 #include "src/base/platform/platform.h" |
10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
(...skipping 1140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1151 // LetDeclaration | 1151 // LetDeclaration |
1152 // ConstDeclaration | 1152 // ConstDeclaration |
1153 // ModuleDeclaration | 1153 // ModuleDeclaration |
1154 // ImportDeclaration | 1154 // ImportDeclaration |
1155 // ExportDeclaration | 1155 // ExportDeclaration |
1156 // GeneratorDeclaration | 1156 // GeneratorDeclaration |
1157 | 1157 |
1158 switch (peek()) { | 1158 switch (peek()) { |
1159 case Token::FUNCTION: | 1159 case Token::FUNCTION: |
1160 return ParseFunctionDeclaration(NULL, ok); | 1160 return ParseFunctionDeclaration(NULL, ok); |
1161 case Token::LET: | |
1162 case Token::CONST: | |
1163 return ParseVariableStatement(kModuleElement, NULL, ok); | |
1164 case Token::IMPORT: | 1161 case Token::IMPORT: |
1165 return ParseImportDeclaration(ok); | 1162 return ParseImportDeclaration(ok); |
1166 case Token::EXPORT: | 1163 case Token::EXPORT: |
1167 return ParseExportDeclaration(ok); | 1164 return ParseExportDeclaration(ok); |
1165 case Token::CONST: | |
1166 return ParseVariableStatement(kModuleElement, NULL, ok); | |
1167 case Token::LET: | |
1168 ASSERT(allow_harmony_scoping()); | |
1169 if (strict_mode() == STRICT) { | |
1170 return ParseVariableStatement(kModuleElement, NULL, ok); | |
1171 } | |
1172 // Fall through. | |
1168 default: { | 1173 default: { |
1169 Statement* stmt = ParseStatement(labels, CHECK_OK); | 1174 Statement* stmt = ParseStatement(labels, CHECK_OK); |
1170 // Handle 'module' as a context-sensitive keyword. | 1175 // Handle 'module' as a context-sensitive keyword. |
1171 if (FLAG_harmony_modules && | 1176 if (FLAG_harmony_modules && |
1172 peek() == Token::IDENTIFIER && | 1177 peek() == Token::IDENTIFIER && |
1173 !scanner()->HasAnyLineTerminatorBeforeNext() && | 1178 !scanner()->HasAnyLineTerminatorBeforeNext() && |
1174 stmt != NULL) { | 1179 stmt != NULL) { |
1175 ExpressionStatement* estmt = stmt->AsExpressionStatement(); | 1180 ExpressionStatement* estmt = stmt->AsExpressionStatement(); |
1176 if (estmt != NULL && estmt->expression()->AsVariableProxy() != NULL && | 1181 if (estmt != NULL && estmt->expression()->AsVariableProxy() != NULL && |
1177 estmt->expression()->AsVariableProxy()->raw_name() == | 1182 estmt->expression()->AsVariableProxy()->raw_name() == |
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1456 Statement* Parser::ParseExportDeclaration(bool* ok) { | 1461 Statement* Parser::ParseExportDeclaration(bool* ok) { |
1457 // ExportDeclaration: | 1462 // ExportDeclaration: |
1458 // 'export' Identifier (',' Identifier)* ';' | 1463 // 'export' Identifier (',' Identifier)* ';' |
1459 // 'export' VariableDeclaration | 1464 // 'export' VariableDeclaration |
1460 // 'export' FunctionDeclaration | 1465 // 'export' FunctionDeclaration |
1461 // 'export' GeneratorDeclaration | 1466 // 'export' GeneratorDeclaration |
1462 // 'export' ModuleDeclaration | 1467 // 'export' ModuleDeclaration |
1463 // | 1468 // |
1464 // TODO(ES6): implement structuring ExportSpecifiers | 1469 // TODO(ES6): implement structuring ExportSpecifiers |
1465 | 1470 |
1471 ASSERT(strict_mode() == STRICT); | |
1472 | |
1466 Expect(Token::EXPORT, CHECK_OK); | 1473 Expect(Token::EXPORT, CHECK_OK); |
1467 | 1474 |
1468 Statement* result = NULL; | 1475 Statement* result = NULL; |
1469 ZoneList<const AstRawString*> names(1, zone()); | 1476 ZoneList<const AstRawString*> names(1, zone()); |
1470 switch (peek()) { | 1477 switch (peek()) { |
1471 case Token::IDENTIFIER: { | 1478 case Token::IDENTIFIER: { |
1472 int pos = position(); | 1479 int pos = position(); |
1473 const AstRawString* name = | 1480 const AstRawString* name = |
1474 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | 1481 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
1475 // Handle 'module' as a context-sensitive keyword. | 1482 // Handle 'module' as a context-sensitive keyword. |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1538 // | 1545 // |
1539 // In harmony mode we allow additionally the following productions | 1546 // In harmony mode we allow additionally the following productions |
1540 // BlockElement (aka SourceElement): | 1547 // BlockElement (aka SourceElement): |
1541 // LetDeclaration | 1548 // LetDeclaration |
1542 // ConstDeclaration | 1549 // ConstDeclaration |
1543 // GeneratorDeclaration | 1550 // GeneratorDeclaration |
1544 | 1551 |
1545 switch (peek()) { | 1552 switch (peek()) { |
1546 case Token::FUNCTION: | 1553 case Token::FUNCTION: |
1547 return ParseFunctionDeclaration(NULL, ok); | 1554 return ParseFunctionDeclaration(NULL, ok); |
1548 case Token::LET: | |
1549 case Token::CONST: | 1555 case Token::CONST: |
1550 return ParseVariableStatement(kModuleElement, NULL, ok); | 1556 return ParseVariableStatement(kModuleElement, NULL, ok); |
1557 case Token::LET: | |
1558 ASSERT(allow_harmony_scoping()); | |
1559 if (strict_mode() == STRICT) { | |
1560 return ParseVariableStatement(kModuleElement, NULL, ok); | |
1561 } | |
1562 // Fall through. | |
1551 default: | 1563 default: |
1552 return ParseStatement(labels, ok); | 1564 return ParseStatement(labels, ok); |
1553 } | 1565 } |
1554 } | 1566 } |
1555 | 1567 |
1556 | 1568 |
1557 Statement* Parser::ParseStatement(ZoneList<const AstRawString*>* labels, | 1569 Statement* Parser::ParseStatement(ZoneList<const AstRawString*>* labels, |
1558 bool* ok) { | 1570 bool* ok) { |
1559 // Statement :: | 1571 // Statement :: |
1560 // Block | 1572 // Block |
(...skipping 15 matching lines...) Expand all Loading... | |
1576 // Note: Since labels can only be used by 'break' and 'continue' | 1588 // Note: Since labels can only be used by 'break' and 'continue' |
1577 // statements, which themselves are only valid within blocks, | 1589 // statements, which themselves are only valid within blocks, |
1578 // iterations or 'switch' statements (i.e., BreakableStatements), | 1590 // iterations or 'switch' statements (i.e., BreakableStatements), |
1579 // labels can be simply ignored in all other cases; except for | 1591 // labels can be simply ignored in all other cases; except for |
1580 // trivial labeled break statements 'label: break label' which is | 1592 // trivial labeled break statements 'label: break label' which is |
1581 // parsed into an empty statement. | 1593 // parsed into an empty statement. |
1582 switch (peek()) { | 1594 switch (peek()) { |
1583 case Token::LBRACE: | 1595 case Token::LBRACE: |
1584 return ParseBlock(labels, ok); | 1596 return ParseBlock(labels, ok); |
1585 | 1597 |
1586 case Token::CONST: // fall through | |
1587 case Token::LET: | |
1588 case Token::VAR: | |
1589 return ParseVariableStatement(kStatement, NULL, ok); | |
1590 | |
1591 case Token::SEMICOLON: | 1598 case Token::SEMICOLON: |
1592 Next(); | 1599 Next(); |
1593 return factory()->NewEmptyStatement(RelocInfo::kNoPosition); | 1600 return factory()->NewEmptyStatement(RelocInfo::kNoPosition); |
1594 | 1601 |
1595 case Token::IF: | 1602 case Token::IF: |
1596 return ParseIfStatement(labels, ok); | 1603 return ParseIfStatement(labels, ok); |
1597 | 1604 |
1598 case Token::DO: | 1605 case Token::DO: |
1599 return ParseDoWhileStatement(labels, ok); | 1606 return ParseDoWhileStatement(labels, ok); |
1600 | 1607 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1652 ReportMessageAt(scanner()->peek_location(), "strict_function"); | 1659 ReportMessageAt(scanner()->peek_location(), "strict_function"); |
1653 *ok = false; | 1660 *ok = false; |
1654 return NULL; | 1661 return NULL; |
1655 } | 1662 } |
1656 return ParseFunctionDeclaration(NULL, ok); | 1663 return ParseFunctionDeclaration(NULL, ok); |
1657 } | 1664 } |
1658 | 1665 |
1659 case Token::DEBUGGER: | 1666 case Token::DEBUGGER: |
1660 return ParseDebuggerStatement(ok); | 1667 return ParseDebuggerStatement(ok); |
1661 | 1668 |
1669 case Token::VAR: | |
1670 case Token::CONST: | |
1671 return ParseVariableStatement(kStatement, NULL, ok); | |
1672 | |
1673 case Token::LET: | |
1674 ASSERT(allow_harmony_scoping()); | |
1675 if (strict_mode() == STRICT) { | |
1676 return ParseVariableStatement(kStatement, NULL, ok); | |
1677 } | |
1678 // Fall through. | |
1662 default: | 1679 default: |
1663 return ParseExpressionOrLabelledStatement(labels, ok); | 1680 return ParseExpressionOrLabelledStatement(labels, ok); |
1664 } | 1681 } |
1665 } | 1682 } |
1666 | 1683 |
1667 | 1684 |
1668 VariableProxy* Parser::NewUnresolved(const AstRawString* name, | 1685 VariableProxy* Parser::NewUnresolved(const AstRawString* name, |
1669 VariableMode mode, Interface* interface) { | 1686 VariableMode mode, Interface* interface) { |
1670 // If we are inside a function, a declaration of a var/const variable is a | 1687 // If we are inside a function, a declaration of a var/const variable is a |
1671 // truly local variable, and the scope of the variable is always the function | 1688 // truly local variable, and the scope of the variable is always the function |
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2055 mode = CONST; | 2072 mode = CONST; |
2056 init_op = Token::INIT_CONST; | 2073 init_op = Token::INIT_CONST; |
2057 } else { | 2074 } else { |
2058 ReportMessage("strict_const"); | 2075 ReportMessage("strict_const"); |
2059 *ok = false; | 2076 *ok = false; |
2060 return NULL; | 2077 return NULL; |
2061 } | 2078 } |
2062 } | 2079 } |
2063 is_const = true; | 2080 is_const = true; |
2064 needs_init = true; | 2081 needs_init = true; |
2065 } else if (peek() == Token::LET) { | 2082 } else if (peek() == Token::LET && strict_mode() == STRICT) { |
marja
2014/07/10 14:05:28
Here you probably also want to ASSERT(allow_harmon
| |
2066 // ES6 Draft Rev4 section 12.2.1: | |
2067 // | |
2068 // LetDeclaration : let LetBindingList ; | |
2069 // | |
2070 // * It is a Syntax Error if the code that matches this production is not | |
2071 // contained in extended code. | |
2072 // | |
2073 // TODO(rossberg): make 'let' a legal identifier in sloppy mode. | |
2074 if (!allow_harmony_scoping() || strict_mode() == SLOPPY) { | |
2075 ReportMessage("illegal_let"); | |
2076 *ok = false; | |
2077 return NULL; | |
2078 } | |
2079 Consume(Token::LET); | 2083 Consume(Token::LET); |
2080 if (var_context == kStatement) { | 2084 if (var_context == kStatement) { |
2081 // Let declarations are only allowed in source element positions. | 2085 // Let declarations are only allowed in source element positions. |
2082 ReportMessage("unprotected_let"); | 2086 ReportMessage("unprotected_let"); |
2083 *ok = false; | 2087 *ok = false; |
2084 return NULL; | 2088 return NULL; |
2085 } | 2089 } |
2086 mode = LET; | 2090 mode = LET; |
2087 needs_init = true; | 2091 needs_init = true; |
2088 init_op = Token::INIT_LET; | 2092 init_op = Token::INIT_LET; |
(...skipping 1018 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3107 result->AddStatement(loop, zone()); | 3111 result->AddStatement(loop, zone()); |
3108 scope_ = saved_scope; | 3112 scope_ = saved_scope; |
3109 for_scope->set_end_position(scanner()->location().end_pos); | 3113 for_scope->set_end_position(scanner()->location().end_pos); |
3110 for_scope = for_scope->FinalizeBlockScope(); | 3114 for_scope = for_scope->FinalizeBlockScope(); |
3111 ASSERT(for_scope == NULL); | 3115 ASSERT(for_scope == NULL); |
3112 // Parsed for-in loop w/ variable/const declaration. | 3116 // Parsed for-in loop w/ variable/const declaration. |
3113 return result; | 3117 return result; |
3114 } else { | 3118 } else { |
3115 init = variable_statement; | 3119 init = variable_statement; |
3116 } | 3120 } |
3117 } else if (peek() == Token::LET) { | 3121 } else if (peek() == Token::LET && strict_mode() == STRICT) { |
marja
2014/07/10 14:05:28
Ditto
| |
3118 const AstRawString* name = NULL; | 3122 const AstRawString* name = NULL; |
3119 VariableDeclarationProperties decl_props = kHasNoInitializers; | 3123 VariableDeclarationProperties decl_props = kHasNoInitializers; |
3120 Block* variable_statement = | 3124 Block* variable_statement = |
3121 ParseVariableDeclarations(kForStatement, &decl_props, &let_bindings, | 3125 ParseVariableDeclarations(kForStatement, &decl_props, &let_bindings, |
3122 &name, CHECK_OK); | 3126 &name, CHECK_OK); |
3123 bool accept_IN = name != NULL && decl_props != kHasInitializers; | 3127 bool accept_IN = name != NULL && decl_props != kHasInitializers; |
3124 bool accept_OF = decl_props == kHasNoInitializers; | 3128 bool accept_OF = decl_props == kHasNoInitializers; |
3125 ForEachStatement::VisitMode mode; | 3129 ForEachStatement::VisitMode mode; |
3126 | 3130 |
3127 if (accept_IN && CheckInOrOf(accept_OF, &mode)) { | 3131 if (accept_IN && CheckInOrOf(accept_OF, &mode)) { |
(...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3493 // NOTE: We create a proxy and resolve it here so that in the | 3497 // NOTE: We create a proxy and resolve it here so that in the |
3494 // future we can change the AST to only refer to VariableProxies | 3498 // future we can change the AST to only refer to VariableProxies |
3495 // instead of Variables and Proxis as is the case now. | 3499 // instead of Variables and Proxis as is the case now. |
3496 Variable* fvar = NULL; | 3500 Variable* fvar = NULL; |
3497 Token::Value fvar_init_op = Token::INIT_CONST_LEGACY; | 3501 Token::Value fvar_init_op = Token::INIT_CONST_LEGACY; |
3498 if (function_type == FunctionLiteral::NAMED_EXPRESSION) { | 3502 if (function_type == FunctionLiteral::NAMED_EXPRESSION) { |
3499 if (allow_harmony_scoping() && strict_mode() == STRICT) { | 3503 if (allow_harmony_scoping() && strict_mode() == STRICT) { |
3500 fvar_init_op = Token::INIT_CONST; | 3504 fvar_init_op = Token::INIT_CONST; |
3501 } | 3505 } |
3502 VariableMode fvar_mode = | 3506 VariableMode fvar_mode = |
3503 allow_harmony_scoping() && strict_mode() == STRICT ? CONST | 3507 allow_harmony_scoping() && strict_mode() == STRICT |
3504 : CONST_LEGACY; | 3508 ? CONST : CONST_LEGACY; |
3505 ASSERT(function_name != NULL); | 3509 ASSERT(function_name != NULL); |
3506 fvar = new(zone()) Variable(scope_, | 3510 fvar = new(zone()) Variable(scope_, |
3507 function_name, fvar_mode, true /* is valid LHS */, | 3511 function_name, fvar_mode, true /* is valid LHS */, |
3508 Variable::NORMAL, kCreatedInitialized, Interface::NewConst()); | 3512 Variable::NORMAL, kCreatedInitialized, Interface::NewConst()); |
3509 VariableProxy* proxy = factory()->NewVariableProxy(fvar); | 3513 VariableProxy* proxy = factory()->NewVariableProxy(fvar); |
3510 VariableDeclaration* fvar_declaration = factory()->NewVariableDeclaration( | 3514 VariableDeclaration* fvar_declaration = factory()->NewVariableDeclaration( |
3511 proxy, fvar_mode, scope_, RelocInfo::kNoPosition); | 3515 proxy, fvar_mode, scope_, RelocInfo::kNoPosition); |
3512 scope_->DeclareFunctionVar(fvar_declaration); | 3516 scope_->DeclareFunctionVar(fvar_declaration); |
3513 } | 3517 } |
3514 | 3518 |
(...skipping 1371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4886 info()->SetAstValueFactory(ast_value_factory_); | 4890 info()->SetAstValueFactory(ast_value_factory_); |
4887 } | 4891 } |
4888 ast_value_factory_ = NULL; | 4892 ast_value_factory_ = NULL; |
4889 | 4893 |
4890 InternalizeUseCounts(); | 4894 InternalizeUseCounts(); |
4891 | 4895 |
4892 return (result != NULL); | 4896 return (result != NULL); |
4893 } | 4897 } |
4894 | 4898 |
4895 } } // namespace v8::internal | 4899 } } // namespace v8::internal |
OLD | NEW |