| 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/parsing/parser.h" | 5 #include "src/parsing/parser.h" |
| 6 | 6 |
| 7 #include "src/api.h" | 7 #include "src/api.h" |
| 8 #include "src/ast/ast.h" | 8 #include "src/ast/ast.h" |
| 9 #include "src/ast/ast-expression-rewriter.h" | 9 #include "src/ast/ast-expression-rewriter.h" |
| 10 #include "src/ast/ast-expression-visitor.h" | 10 #include "src/ast/ast-expression-visitor.h" |
| (...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 323 | 323 |
| 324 | 324 |
| 325 bool ParserTraits::IsEvalOrArguments(const AstRawString* identifier) const { | 325 bool ParserTraits::IsEvalOrArguments(const AstRawString* identifier) const { |
| 326 return IsEval(identifier) || IsArguments(identifier); | 326 return IsEval(identifier) || IsArguments(identifier); |
| 327 } | 327 } |
| 328 | 328 |
| 329 bool ParserTraits::IsUndefined(const AstRawString* identifier) const { | 329 bool ParserTraits::IsUndefined(const AstRawString* identifier) const { |
| 330 return identifier == parser_->ast_value_factory()->undefined_string(); | 330 return identifier == parser_->ast_value_factory()->undefined_string(); |
| 331 } | 331 } |
| 332 | 332 |
| 333 bool ParserTraits::IsAwait(const AstRawString* identifier) const { |
| 334 return identifier == parser_->ast_value_factory()->await_string(); |
| 335 } |
| 336 |
| 333 bool ParserTraits::IsPrototype(const AstRawString* identifier) const { | 337 bool ParserTraits::IsPrototype(const AstRawString* identifier) const { |
| 334 return identifier == parser_->ast_value_factory()->prototype_string(); | 338 return identifier == parser_->ast_value_factory()->prototype_string(); |
| 335 } | 339 } |
| 336 | 340 |
| 337 | 341 |
| 338 bool ParserTraits::IsConstructor(const AstRawString* identifier) const { | 342 bool ParserTraits::IsConstructor(const AstRawString* identifier) const { |
| 339 return identifier == parser_->ast_value_factory()->constructor_string(); | 343 return identifier == parser_->ast_value_factory()->constructor_string(); |
| 340 } | 344 } |
| 341 | 345 |
| 342 | 346 |
| (...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 791 set_allow_tailcalls(FLAG_harmony_tailcalls && !info->is_native() && | 795 set_allow_tailcalls(FLAG_harmony_tailcalls && !info->is_native() && |
| 792 info->isolate()->is_tail_call_elimination_enabled()); | 796 info->isolate()->is_tail_call_elimination_enabled()); |
| 793 set_allow_harmony_do_expressions(FLAG_harmony_do_expressions); | 797 set_allow_harmony_do_expressions(FLAG_harmony_do_expressions); |
| 794 set_allow_harmony_for_in(FLAG_harmony_for_in); | 798 set_allow_harmony_for_in(FLAG_harmony_for_in); |
| 795 set_allow_harmony_function_name(FLAG_harmony_function_name); | 799 set_allow_harmony_function_name(FLAG_harmony_function_name); |
| 796 set_allow_harmony_function_sent(FLAG_harmony_function_sent); | 800 set_allow_harmony_function_sent(FLAG_harmony_function_sent); |
| 797 set_allow_harmony_restrictive_declarations( | 801 set_allow_harmony_restrictive_declarations( |
| 798 FLAG_harmony_restrictive_declarations); | 802 FLAG_harmony_restrictive_declarations); |
| 799 set_allow_harmony_exponentiation_operator( | 803 set_allow_harmony_exponentiation_operator( |
| 800 FLAG_harmony_exponentiation_operator); | 804 FLAG_harmony_exponentiation_operator); |
| 805 set_allow_harmony_async_await(FLAG_harmony_async_await); |
| 801 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; | 806 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; |
| 802 ++feature) { | 807 ++feature) { |
| 803 use_counts_[feature] = 0; | 808 use_counts_[feature] = 0; |
| 804 } | 809 } |
| 805 if (info->ast_value_factory() == NULL) { | 810 if (info->ast_value_factory() == NULL) { |
| 806 // info takes ownership of AstValueFactory. | 811 // info takes ownership of AstValueFactory. |
| 807 info->set_ast_value_factory(new AstValueFactory(zone(), info->hash_seed())); | 812 info->set_ast_value_factory(new AstValueFactory(zone(), info->hash_seed())); |
| 808 info->set_ast_value_factory_owned(); | 813 info->set_ast_value_factory_owned(); |
| 809 ast_value_factory_ = info->ast_value_factory(); | 814 ast_value_factory_ = info->ast_value_factory(); |
| 810 } | 815 } |
| (...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1068 FunctionState function_state(&function_state_, &scope_, scope, | 1073 FunctionState function_state(&function_state_, &scope_, scope, |
| 1069 shared_info->kind(), &function_factory); | 1074 shared_info->kind(), &function_factory); |
| 1070 DCHECK(is_sloppy(scope->language_mode()) || | 1075 DCHECK(is_sloppy(scope->language_mode()) || |
| 1071 is_strict(info->language_mode())); | 1076 is_strict(info->language_mode())); |
| 1072 DCHECK(info->language_mode() == shared_info->language_mode()); | 1077 DCHECK(info->language_mode() == shared_info->language_mode()); |
| 1073 FunctionLiteral::FunctionType function_type = | 1078 FunctionLiteral::FunctionType function_type = |
| 1074 ComputeFunctionType(shared_info); | 1079 ComputeFunctionType(shared_info); |
| 1075 bool ok = true; | 1080 bool ok = true; |
| 1076 | 1081 |
| 1077 if (shared_info->is_arrow()) { | 1082 if (shared_info->is_arrow()) { |
| 1083 bool is_async = allow_harmony_async_await() && shared_info->is_async(); |
| 1084 if (is_async) { |
| 1085 DCHECK(!scanner()->HasAnyLineTerminatorAfterNext()); |
| 1086 Consume(Token::ASYNC); |
| 1087 DCHECK(peek_any_identifier() || peek() == Token::LPAREN); |
| 1088 } |
| 1089 |
| 1078 // TODO(adamk): We should construct this scope from the ScopeInfo. | 1090 // TODO(adamk): We should construct this scope from the ScopeInfo. |
| 1079 Scope* scope = | 1091 Scope* scope = |
| 1080 NewScope(scope_, FUNCTION_SCOPE, FunctionKind::kArrowFunction); | 1092 NewScope(scope_, FUNCTION_SCOPE, FunctionKind::kArrowFunction); |
| 1081 | 1093 |
| 1082 // These two bits only need to be explicitly set because we're | 1094 // These two bits only need to be explicitly set because we're |
| 1083 // not passing the ScopeInfo to the Scope constructor. | 1095 // not passing the ScopeInfo to the Scope constructor. |
| 1084 // TODO(adamk): Remove these calls once the above NewScope call | 1096 // TODO(adamk): Remove these calls once the above NewScope call |
| 1085 // passes the ScopeInfo. | 1097 // passes the ScopeInfo. |
| 1086 if (shared_info->scope_info()->CallsEval()) { | 1098 if (shared_info->scope_info()->CallsEval()) { |
| 1087 scope->RecordEvalCall(); | 1099 scope->RecordEvalCall(); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1108 DeclareFormalParameter(formals.scope, formals.at(0), | 1120 DeclareFormalParameter(formals.scope, formals.at(0), |
| 1109 &formals_classifier); | 1121 &formals_classifier); |
| 1110 } | 1122 } |
| 1111 } | 1123 } |
| 1112 } | 1124 } |
| 1113 | 1125 |
| 1114 if (ok) { | 1126 if (ok) { |
| 1115 checkpoint.Restore(&formals.materialized_literals_count); | 1127 checkpoint.Restore(&formals.materialized_literals_count); |
| 1116 // Pass `accept_IN=true` to ParseArrowFunctionLiteral --- This should | 1128 // Pass `accept_IN=true` to ParseArrowFunctionLiteral --- This should |
| 1117 // not be observable, or else the preparser would have failed. | 1129 // not be observable, or else the preparser would have failed. |
| 1118 Expression* expression = | 1130 Expression* expression = ParseArrowFunctionLiteral( |
| 1119 ParseArrowFunctionLiteral(true, formals, formals_classifier, &ok); | 1131 true, formals, is_async, formals_classifier, &ok); |
| 1120 if (ok) { | 1132 if (ok) { |
| 1121 // Scanning must end at the same position that was recorded | 1133 // Scanning must end at the same position that was recorded |
| 1122 // previously. If not, parsing has been interrupted due to a stack | 1134 // previously. If not, parsing has been interrupted due to a stack |
| 1123 // overflow, at which point the partially parsed arrow function | 1135 // overflow, at which point the partially parsed arrow function |
| 1124 // concise body happens to be a valid expression. This is a problem | 1136 // concise body happens to be a valid expression. This is a problem |
| 1125 // only for arrow functions with single expression bodies, since there | 1137 // only for arrow functions with single expression bodies, since there |
| 1126 // is no end token such as "}" for normal functions. | 1138 // is no end token such as "}" for normal functions. |
| 1127 if (scanner()->location().end_pos == shared_info->end_position()) { | 1139 if (scanner()->location().end_pos == shared_info->end_position()) { |
| 1128 // The pre-parser saw an arrow function here, so the full parser | 1140 // The pre-parser saw an arrow function here, so the full parser |
| 1129 // must produce a FunctionLiteral. | 1141 // must produce a FunctionLiteral. |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1248 | 1260 |
| 1249 return 0; | 1261 return 0; |
| 1250 } | 1262 } |
| 1251 | 1263 |
| 1252 | 1264 |
| 1253 Statement* Parser::ParseStatementListItem(bool* ok) { | 1265 Statement* Parser::ParseStatementListItem(bool* ok) { |
| 1254 // (Ecma 262 6th Edition, 13.1): | 1266 // (Ecma 262 6th Edition, 13.1): |
| 1255 // StatementListItem: | 1267 // StatementListItem: |
| 1256 // Statement | 1268 // Statement |
| 1257 // Declaration | 1269 // Declaration |
| 1258 | 1270 const Token::Value peeked = peek(); |
| 1259 switch (peek()) { | 1271 switch (peeked) { |
| 1260 case Token::FUNCTION: | 1272 case Token::FUNCTION: |
| 1261 return ParseHoistableDeclaration(NULL, ok); | 1273 return ParseHoistableDeclaration(NULL, ok); |
| 1262 case Token::CLASS: | 1274 case Token::CLASS: |
| 1263 Consume(Token::CLASS); | 1275 Consume(Token::CLASS); |
| 1264 return ParseClassDeclaration(NULL, ok); | 1276 return ParseClassDeclaration(NULL, ok); |
| 1265 case Token::CONST: | 1277 case Token::CONST: |
| 1266 return ParseVariableStatement(kStatementListItem, NULL, ok); | 1278 return ParseVariableStatement(kStatementListItem, NULL, ok); |
| 1267 case Token::VAR: | 1279 case Token::VAR: |
| 1268 return ParseVariableStatement(kStatementListItem, NULL, ok); | 1280 return ParseVariableStatement(kStatementListItem, NULL, ok); |
| 1269 case Token::LET: | 1281 case Token::LET: |
| 1270 if (IsNextLetKeyword()) { | 1282 if (IsNextLetKeyword()) { |
| 1271 return ParseVariableStatement(kStatementListItem, NULL, ok); | 1283 return ParseVariableStatement(kStatementListItem, NULL, ok); |
| 1272 } | 1284 } |
| 1273 break; | 1285 break; |
| 1286 case Token::ASYNC: |
| 1287 if (allow_harmony_async_await() && PeekAhead() == Token::FUNCTION && |
| 1288 !scanner()->HasAnyLineTerminatorAfterNext()) { |
| 1289 Consume(Token::ASYNC); |
| 1290 return ParseAsyncFunctionDeclaration(NULL, ok); |
| 1291 } |
| 1292 /* falls through */ |
| 1274 default: | 1293 default: |
| 1275 break; | 1294 break; |
| 1276 } | 1295 } |
| 1277 return ParseStatement(NULL, kAllowLabelledFunctionStatement, ok); | 1296 return ParseStatement(NULL, kAllowLabelledFunctionStatement, ok); |
| 1278 } | 1297 } |
| 1279 | 1298 |
| 1280 | 1299 |
| 1281 Statement* Parser::ParseModuleItem(bool* ok) { | 1300 Statement* Parser::ParseModuleItem(bool* ok) { |
| 1282 // (Ecma 262 6th Edition, 15.2): | 1301 // (Ecma 262 6th Edition, 15.2): |
| 1283 // ModuleItem : | 1302 // ModuleItem : |
| (...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1553 // GeneratorDeclaration[+Default] :: | 1572 // GeneratorDeclaration[+Default] :: |
| 1554 // 'function' '*' '(' FormalParameters ')' '{' FunctionBody '}' | 1573 // 'function' '*' '(' FormalParameters ')' '{' FunctionBody '}' |
| 1555 default_export = ParseFunctionLiteral( | 1574 default_export = ParseFunctionLiteral( |
| 1556 default_string, Scanner::Location::invalid(), | 1575 default_string, Scanner::Location::invalid(), |
| 1557 kSkipFunctionNameCheck, | 1576 kSkipFunctionNameCheck, |
| 1558 is_generator ? FunctionKind::kGeneratorFunction | 1577 is_generator ? FunctionKind::kGeneratorFunction |
| 1559 : FunctionKind::kNormalFunction, | 1578 : FunctionKind::kNormalFunction, |
| 1560 pos, FunctionLiteral::kDeclaration, language_mode(), CHECK_OK); | 1579 pos, FunctionLiteral::kDeclaration, language_mode(), CHECK_OK); |
| 1561 result = factory()->NewEmptyStatement(RelocInfo::kNoPosition); | 1580 result = factory()->NewEmptyStatement(RelocInfo::kNoPosition); |
| 1562 } else { | 1581 } else { |
| 1563 result = ParseHoistableDeclaration(pos, is_generator, &names, CHECK_OK); | 1582 result = ParseHoistableDeclaration( |
| 1583 pos, is_generator ? ParseFunctionFlags::kIsGenerator |
| 1584 : ParseFunctionFlags::kIsNormal, |
| 1585 &names, CHECK_OK); |
| 1564 } | 1586 } |
| 1565 break; | 1587 break; |
| 1566 } | 1588 } |
| 1567 | 1589 |
| 1568 case Token::CLASS: | 1590 case Token::CLASS: |
| 1569 Consume(Token::CLASS); | 1591 Consume(Token::CLASS); |
| 1570 if (peek() == Token::EXTENDS || peek() == Token::LBRACE) { | 1592 if (peek() == Token::EXTENDS || peek() == Token::LBRACE) { |
| 1571 // ClassDeclaration[+Default] :: | 1593 // ClassDeclaration[+Default] :: |
| 1572 // 'class' ('extends' LeftHandExpression)? '{' ClassBody '}' | 1594 // 'class' ('extends' LeftHandExpression)? '{' ClassBody '}' |
| 1573 default_export = ParseClassLiteral(nullptr, default_string, | 1595 default_export = ParseClassLiteral(nullptr, default_string, |
| 1574 Scanner::Location::invalid(), false, | 1596 Scanner::Location::invalid(), false, |
| 1575 position(), CHECK_OK); | 1597 position(), CHECK_OK); |
| 1576 result = factory()->NewEmptyStatement(RelocInfo::kNoPosition); | 1598 result = factory()->NewEmptyStatement(RelocInfo::kNoPosition); |
| 1577 } else { | 1599 } else { |
| 1578 result = ParseClassDeclaration(&names, CHECK_OK); | 1600 result = ParseClassDeclaration(&names, CHECK_OK); |
| 1579 } | 1601 } |
| 1580 break; | 1602 break; |
| 1581 | 1603 |
| 1604 case Token::ASYNC: |
| 1605 if (allow_harmony_async_await() && PeekAhead() == Token::FUNCTION && |
| 1606 !scanner()->HasAnyLineTerminatorAfterNext()) { |
| 1607 Consume(Token::ASYNC); |
| 1608 Consume(Token::FUNCTION); |
| 1609 int pos = position(); |
| 1610 if (peek() == Token::LPAREN) { |
| 1611 // AsyncFunctionDeclaration[+Default] :: |
| 1612 // async [no LineTerminator here] function ( FormalParameters ) { |
| 1613 // AsyncFunctionBody |
| 1614 // } |
| 1615 default_export = ParseFunctionLiteral( |
| 1616 default_string, Scanner::Location::invalid(), |
| 1617 kSkipFunctionNameCheck, FunctionKind::kAsyncFunction, pos, |
| 1618 FunctionLiteral::kDeclaration, language_mode(), CHECK_OK); |
| 1619 result = factory()->NewEmptyStatement(RelocInfo::kNoPosition); |
| 1620 } else { |
| 1621 result = ParseHoistableDeclaration(pos, ParseFunctionFlags::kIsAsync, |
| 1622 &names, CHECK_OK); |
| 1623 } |
| 1624 break; |
| 1625 } |
| 1626 /* falls through */ |
| 1627 |
| 1582 default: { | 1628 default: { |
| 1583 int pos = peek_position(); | 1629 int pos = peek_position(); |
| 1584 ExpressionClassifier classifier(this); | 1630 ExpressionClassifier classifier(this); |
| 1585 Expression* expr = ParseAssignmentExpression(true, &classifier, CHECK_OK); | 1631 Expression* expr = ParseAssignmentExpression(true, &classifier, CHECK_OK); |
| 1586 RewriteNonPattern(&classifier, CHECK_OK); | 1632 RewriteNonPattern(&classifier, CHECK_OK); |
| 1587 | 1633 |
| 1588 ExpectSemicolon(CHECK_OK); | 1634 ExpectSemicolon(CHECK_OK); |
| 1589 result = factory()->NewExpressionStatement(expr, pos); | 1635 result = factory()->NewExpressionStatement(expr, pos); |
| 1590 break; | 1636 break; |
| 1591 } | 1637 } |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1696 Consume(Token::CLASS); | 1742 Consume(Token::CLASS); |
| 1697 result = ParseClassDeclaration(&names, CHECK_OK); | 1743 result = ParseClassDeclaration(&names, CHECK_OK); |
| 1698 break; | 1744 break; |
| 1699 | 1745 |
| 1700 case Token::VAR: | 1746 case Token::VAR: |
| 1701 case Token::LET: | 1747 case Token::LET: |
| 1702 case Token::CONST: | 1748 case Token::CONST: |
| 1703 result = ParseVariableStatement(kStatementListItem, &names, CHECK_OK); | 1749 result = ParseVariableStatement(kStatementListItem, &names, CHECK_OK); |
| 1704 break; | 1750 break; |
| 1705 | 1751 |
| 1752 case Token::ASYNC: |
| 1753 if (allow_harmony_async_await()) { |
| 1754 Consume(Token::ASYNC); |
| 1755 result = ParseAsyncFunctionDeclaration(&names, CHECK_OK); |
| 1756 break; |
| 1757 } |
| 1758 /* falls through */ |
| 1759 |
| 1706 default: | 1760 default: |
| 1707 *ok = false; | 1761 *ok = false; |
| 1708 ReportUnexpectedToken(scanner()->current_token()); | 1762 ReportUnexpectedToken(scanner()->current_token()); |
| 1709 return NULL; | 1763 return NULL; |
| 1710 } | 1764 } |
| 1711 | 1765 |
| 1712 // Extract declared names into export declarations. | 1766 // Extract declared names into export declarations. |
| 1713 ModuleDescriptor* descriptor = scope_->module(); | 1767 ModuleDescriptor* descriptor = scope_->module(); |
| 1714 for (int i = 0; i < names.length(); ++i) { | 1768 for (int i = 0; i < names.length(); ++i) { |
| 1715 descriptor->AddLocalExport(names[i], names[i], zone(), ok); | 1769 descriptor->AddLocalExport(names[i], names[i], zone(), ok); |
| (...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2055 return factory()->NewExpressionStatement( | 2109 return factory()->NewExpressionStatement( |
| 2056 factory()->NewAssignment(Token::INIT, proxy, lit, RelocInfo::kNoPosition), | 2110 factory()->NewAssignment(Token::INIT, proxy, lit, RelocInfo::kNoPosition), |
| 2057 pos); | 2111 pos); |
| 2058 } | 2112 } |
| 2059 | 2113 |
| 2060 | 2114 |
| 2061 Statement* Parser::ParseHoistableDeclaration( | 2115 Statement* Parser::ParseHoistableDeclaration( |
| 2062 ZoneList<const AstRawString*>* names, bool* ok) { | 2116 ZoneList<const AstRawString*>* names, bool* ok) { |
| 2063 Expect(Token::FUNCTION, CHECK_OK); | 2117 Expect(Token::FUNCTION, CHECK_OK); |
| 2064 int pos = position(); | 2118 int pos = position(); |
| 2065 bool is_generator = Check(Token::MUL); | 2119 ParseFunctionFlags flags = ParseFunctionFlags::kIsNormal; |
| 2066 return ParseHoistableDeclaration(pos, is_generator, names, ok); | 2120 if (Check(Token::MUL)) { |
| 2121 flags |= ParseFunctionFlags::kIsGenerator; |
| 2122 } |
| 2123 return ParseHoistableDeclaration(pos, flags, names, ok); |
| 2067 } | 2124 } |
| 2068 | 2125 |
| 2126 Statement* Parser::ParseAsyncFunctionDeclaration( |
| 2127 ZoneList<const AstRawString*>* names, bool* ok) { |
| 2128 DCHECK_EQ(scanner()->current_token(), Token::ASYNC); |
| 2129 int pos = position(); |
| 2130 if (scanner()->HasAnyLineTerminatorBeforeNext()) { |
| 2131 *ok = false; |
| 2132 ReportUnexpectedToken(scanner()->current_token()); |
| 2133 return nullptr; |
| 2134 } |
| 2135 Expect(Token::FUNCTION, CHECK_OK); |
| 2136 ParseFunctionFlags flags = ParseFunctionFlags::kIsAsync; |
| 2137 return ParseHoistableDeclaration(pos, flags, names, ok); |
| 2138 } |
| 2069 | 2139 |
| 2070 Statement* Parser::ParseHoistableDeclaration( | 2140 Statement* Parser::ParseHoistableDeclaration( |
| 2071 int pos, bool is_generator, ZoneList<const AstRawString*>* names, | 2141 int pos, ParseFunctionFlags flags, ZoneList<const AstRawString*>* names, |
| 2072 bool* ok) { | 2142 bool* ok) { |
| 2073 // FunctionDeclaration :: | 2143 // FunctionDeclaration :: |
| 2074 // 'function' Identifier '(' FormalParameters ')' '{' FunctionBody '}' | 2144 // 'function' Identifier '(' FormalParameters ')' '{' FunctionBody '}' |
| 2075 // GeneratorDeclaration :: | 2145 // GeneratorDeclaration :: |
| 2076 // 'function' '*' Identifier '(' FormalParameters ')' '{' FunctionBody '}' | 2146 // 'function' '*' Identifier '(' FormalParameters ')' '{' FunctionBody '}' |
| 2077 // | 2147 // |
| 2078 // 'function' and '*' (if present) have been consumed by the caller. | 2148 // 'function' and '*' (if present) have been consumed by the caller. |
| 2149 const bool is_generator = flags & ParseFunctionFlags::kIsGenerator; |
| 2150 const bool is_async = flags & ParseFunctionFlags::kIsAsync; |
| 2151 DCHECK(!is_generator || !is_async); |
| 2152 |
| 2079 bool is_strict_reserved = false; | 2153 bool is_strict_reserved = false; |
| 2080 const AstRawString* name = ParseIdentifierOrStrictReservedWord( | 2154 const AstRawString* name = ParseIdentifierOrStrictReservedWord( |
| 2081 &is_strict_reserved, CHECK_OK); | 2155 &is_strict_reserved, CHECK_OK); |
| 2082 | 2156 |
| 2157 if (V8_UNLIKELY(is_async_function() && this->IsAwait(name))) { |
| 2158 ReportMessageAt(scanner()->location(), |
| 2159 MessageTemplate::kAwaitBindingIdentifier); |
| 2160 *ok = false; |
| 2161 return nullptr; |
| 2162 } |
| 2163 |
| 2083 FuncNameInferrer::State fni_state(fni_); | 2164 FuncNameInferrer::State fni_state(fni_); |
| 2084 if (fni_ != NULL) fni_->PushEnclosingName(name); | 2165 if (fni_ != NULL) fni_->PushEnclosingName(name); |
| 2085 FunctionLiteral* fun = ParseFunctionLiteral( | 2166 FunctionLiteral* fun = ParseFunctionLiteral( |
| 2086 name, scanner()->location(), | 2167 name, scanner()->location(), |
| 2087 is_strict_reserved ? kFunctionNameIsStrictReserved | 2168 is_strict_reserved ? kFunctionNameIsStrictReserved |
| 2088 : kFunctionNameValidityUnknown, | 2169 : kFunctionNameValidityUnknown, |
| 2089 is_generator ? FunctionKind::kGeneratorFunction | 2170 is_generator ? FunctionKind::kGeneratorFunction |
| 2090 : FunctionKind::kNormalFunction, | 2171 : is_async ? FunctionKind::kAsyncFunction |
| 2172 : FunctionKind::kNormalFunction, |
| 2091 pos, FunctionLiteral::kDeclaration, language_mode(), CHECK_OK); | 2173 pos, FunctionLiteral::kDeclaration, language_mode(), CHECK_OK); |
| 2092 | 2174 |
| 2093 // Even if we're not at the top-level of the global or a function | 2175 // Even if we're not at the top-level of the global or a function |
| 2094 // scope, we treat it as such and introduce the function with its | 2176 // scope, we treat it as such and introduce the function with its |
| 2095 // initial value upon entering the corresponding scope. | 2177 // initial value upon entering the corresponding scope. |
| 2096 // In ES6, a function behaves as a lexical binding, except in | 2178 // In ES6, a function behaves as a lexical binding, except in |
| 2097 // a script scope, or the initial scope of eval or another function. | 2179 // a script scope, or the initial scope of eval or another function. |
| 2098 VariableMode mode = | 2180 VariableMode mode = |
| 2099 (!scope_->is_declaration_scope() || scope_->is_module_scope()) ? LET | 2181 (!scope_->is_declaration_scope() || scope_->is_module_scope()) ? LET |
| 2100 : VAR; | 2182 : VAR; |
| (...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2393 return true; | 2475 return true; |
| 2394 } | 2476 } |
| 2395 } | 2477 } |
| 2396 } | 2478 } |
| 2397 return false; | 2479 return false; |
| 2398 } | 2480 } |
| 2399 | 2481 |
| 2400 Statement* Parser::ParseFunctionDeclaration(bool* ok) { | 2482 Statement* Parser::ParseFunctionDeclaration(bool* ok) { |
| 2401 Consume(Token::FUNCTION); | 2483 Consume(Token::FUNCTION); |
| 2402 int pos = position(); | 2484 int pos = position(); |
| 2403 bool is_generator = Check(Token::MUL); | 2485 ParseFunctionFlags flags = ParseFunctionFlags::kIsNormal; |
| 2404 if (allow_harmony_restrictive_declarations() && is_generator) { | 2486 if (Check(Token::MUL)) { |
| 2405 ParserTraits::ReportMessageAt( | 2487 flags |= ParseFunctionFlags::kIsGenerator; |
| 2406 scanner()->location(), | 2488 if (allow_harmony_restrictive_declarations()) { |
| 2407 MessageTemplate::kGeneratorInLegacyContext); | 2489 ParserTraits::ReportMessageAt(scanner()->location(), |
| 2408 *ok = false; | 2490 MessageTemplate::kGeneratorInLegacyContext); |
| 2409 return nullptr; | 2491 *ok = false; |
| 2492 return nullptr; |
| 2493 } |
| 2410 } | 2494 } |
| 2411 return ParseHoistableDeclaration(pos, is_generator, nullptr, CHECK_OK); | 2495 |
| 2496 return ParseHoistableDeclaration(pos, flags, nullptr, CHECK_OK); |
| 2412 } | 2497 } |
| 2413 | 2498 |
| 2414 Statement* Parser::ParseExpressionOrLabelledStatement( | 2499 Statement* Parser::ParseExpressionOrLabelledStatement( |
| 2415 ZoneList<const AstRawString*>* labels, | 2500 ZoneList<const AstRawString*>* labels, |
| 2416 AllowLabelledFunctionStatement allow_function, bool* ok) { | 2501 AllowLabelledFunctionStatement allow_function, bool* ok) { |
| 2417 // ExpressionStatement | LabelledStatement :: | 2502 // ExpressionStatement | LabelledStatement :: |
| 2418 // Expression ';' | 2503 // Expression ';' |
| 2419 // Identifier ':' Statement | 2504 // Identifier ':' Statement |
| 2420 // | 2505 // |
| 2421 // ExpressionStatement[Yield] : | 2506 // ExpressionStatement[Yield] : |
| (...skipping 1622 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4044 scope_->set_start_position(start_position); | 4129 scope_->set_start_position(start_position); |
| 4045 ParserFormalParameters formals(scope); | 4130 ParserFormalParameters formals(scope); |
| 4046 ParseFormalParameterList(&formals, &formals_classifier, CHECK_OK); | 4131 ParseFormalParameterList(&formals, &formals_classifier, CHECK_OK); |
| 4047 arity = formals.Arity(); | 4132 arity = formals.Arity(); |
| 4048 Expect(Token::RPAREN, CHECK_OK); | 4133 Expect(Token::RPAREN, CHECK_OK); |
| 4049 int formals_end_position = scanner()->location().end_pos; | 4134 int formals_end_position = scanner()->location().end_pos; |
| 4050 | 4135 |
| 4051 CheckArityRestrictions(arity, kind, formals.has_rest, start_position, | 4136 CheckArityRestrictions(arity, kind, formals.has_rest, start_position, |
| 4052 formals_end_position, CHECK_OK); | 4137 formals_end_position, CHECK_OK); |
| 4053 Expect(Token::LBRACE, CHECK_OK); | 4138 Expect(Token::LBRACE, CHECK_OK); |
| 4054 | |
| 4055 // Don't include the rest parameter into the function's formal parameter | 4139 // Don't include the rest parameter into the function's formal parameter |
| 4056 // count (esp. the SharedFunctionInfo::internal_formal_parameter_count, | 4140 // count (esp. the SharedFunctionInfo::internal_formal_parameter_count, |
| 4057 // which says whether we need to create an arguments adaptor frame). | 4141 // which says whether we need to create an arguments adaptor frame). |
| 4058 if (formals.has_rest) arity--; | 4142 if (formals.has_rest) arity--; |
| 4059 | 4143 |
| 4060 // Determine if the function can be parsed lazily. Lazy parsing is different | 4144 // Determine if the function can be parsed lazily. Lazy parsing is different |
| 4061 // from lazy compilation; we need to parse more eagerly than we compile. | 4145 // from lazy compilation; we need to parse more eagerly than we compile. |
| 4062 | 4146 |
| 4063 // We can only parse lazily if we also compile lazily. The heuristics for | 4147 // We can only parse lazily if we also compile lazily. The heuristics for |
| 4064 // lazy compilation are: | 4148 // lazy compilation are: |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4200 expected_property_count, arity, duplicate_parameters, function_type, | 4284 expected_property_count, arity, duplicate_parameters, function_type, |
| 4201 eager_compile_hint, kind, pos); | 4285 eager_compile_hint, kind, pos); |
| 4202 function_literal->set_function_token_position(function_token_pos); | 4286 function_literal->set_function_token_position(function_token_pos); |
| 4203 if (should_be_used_once_hint) | 4287 if (should_be_used_once_hint) |
| 4204 function_literal->set_should_be_used_once_hint(); | 4288 function_literal->set_should_be_used_once_hint(); |
| 4205 | 4289 |
| 4206 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal); | 4290 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal); |
| 4207 return function_literal; | 4291 return function_literal; |
| 4208 } | 4292 } |
| 4209 | 4293 |
| 4294 Expression* Parser::ParseAsyncFunctionExpression(bool* ok) { |
| 4295 // AsyncFunctionDeclaration :: |
| 4296 // async [no LineTerminator here] function ( FormalParameters[Await] ) |
| 4297 // { AsyncFunctionBody } |
| 4298 // |
| 4299 // async [no LineTerminator here] function BindingIdentifier[Await] |
| 4300 // ( FormalParameters[Await] ) { AsyncFunctionBody } |
| 4301 DCHECK_EQ(scanner()->current_token(), Token::ASYNC); |
| 4302 int pos = position(); |
| 4303 Expect(Token::FUNCTION, CHECK_OK); |
| 4304 bool is_strict_reserved = false; |
| 4305 const AstRawString* name = nullptr; |
| 4306 FunctionLiteral::FunctionType type = FunctionLiteral::kAnonymousExpression; |
| 4307 |
| 4308 if (peek_any_identifier()) { |
| 4309 type = FunctionLiteral::kNamedExpression; |
| 4310 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); |
| 4311 if (this->IsAwait(name)) { |
| 4312 ReportMessageAt(scanner()->location(), |
| 4313 MessageTemplate::kAwaitBindingIdentifier); |
| 4314 *ok = false; |
| 4315 return nullptr; |
| 4316 } |
| 4317 } |
| 4318 return ParseFunctionLiteral(name, scanner()->location(), |
| 4319 is_strict_reserved ? kFunctionNameIsStrictReserved |
| 4320 : kFunctionNameValidityUnknown, |
| 4321 FunctionKind::kAsyncFunction, pos, type, |
| 4322 language_mode(), CHECK_OK); |
| 4323 } |
| 4210 | 4324 |
| 4211 void Parser::SkipLazyFunctionBody(int* materialized_literal_count, | 4325 void Parser::SkipLazyFunctionBody(int* materialized_literal_count, |
| 4212 int* expected_property_count, bool* ok, | 4326 int* expected_property_count, bool* ok, |
| 4213 Scanner::BookmarkScope* bookmark) { | 4327 Scanner::BookmarkScope* bookmark) { |
| 4214 DCHECK_IMPLIES(bookmark, bookmark->HasBeenSet()); | 4328 DCHECK_IMPLIES(bookmark, bookmark->HasBeenSet()); |
| 4215 if (produce_cached_parse_data()) CHECK(log_); | 4329 if (produce_cached_parse_data()) CHECK(log_); |
| 4216 | 4330 |
| 4217 int function_block_pos = position(); | 4331 int function_block_pos = position(); |
| 4218 if (consume_cached_parse_data() && !cached_parse_data_->rejected()) { | 4332 if (consume_cached_parse_data() && !cached_parse_data_->rejected()) { |
| 4219 // If we have cached data, we use it to skip parsing the function body. The | 4333 // If we have cached data, we use it to skip parsing the function body. The |
| (...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4599 NULL, stack_limit_); | 4713 NULL, stack_limit_); |
| 4600 reusable_preparser_->set_allow_lazy(true); | 4714 reusable_preparser_->set_allow_lazy(true); |
| 4601 #define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name()); | 4715 #define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name()); |
| 4602 SET_ALLOW(natives); | 4716 SET_ALLOW(natives); |
| 4603 SET_ALLOW(harmony_do_expressions); | 4717 SET_ALLOW(harmony_do_expressions); |
| 4604 SET_ALLOW(harmony_for_in); | 4718 SET_ALLOW(harmony_for_in); |
| 4605 SET_ALLOW(harmony_function_name); | 4719 SET_ALLOW(harmony_function_name); |
| 4606 SET_ALLOW(harmony_function_sent); | 4720 SET_ALLOW(harmony_function_sent); |
| 4607 SET_ALLOW(harmony_exponentiation_operator); | 4721 SET_ALLOW(harmony_exponentiation_operator); |
| 4608 SET_ALLOW(harmony_restrictive_declarations); | 4722 SET_ALLOW(harmony_restrictive_declarations); |
| 4723 SET_ALLOW(harmony_async_await); |
| 4609 #undef SET_ALLOW | 4724 #undef SET_ALLOW |
| 4610 } | 4725 } |
| 4611 PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction( | 4726 PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction( |
| 4612 language_mode(), function_state_->kind(), scope_->has_simple_parameters(), | 4727 language_mode(), function_state_->kind(), scope_->has_simple_parameters(), |
| 4613 parsing_module_, logger, bookmark, use_counts_); | 4728 parsing_module_, logger, bookmark, use_counts_); |
| 4614 if (pre_parse_timer_ != NULL) { | 4729 if (pre_parse_timer_ != NULL) { |
| 4615 pre_parse_timer_->Stop(); | 4730 pre_parse_timer_->Stop(); |
| 4616 } | 4731 } |
| 4617 return result; | 4732 return result; |
| 4618 } | 4733 } |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4669 FunctionLiteral* constructor = NULL; | 4784 FunctionLiteral* constructor = NULL; |
| 4670 bool has_seen_constructor = false; | 4785 bool has_seen_constructor = false; |
| 4671 | 4786 |
| 4672 Expect(Token::LBRACE, CHECK_OK); | 4787 Expect(Token::LBRACE, CHECK_OK); |
| 4673 | 4788 |
| 4674 const bool has_extends = extends != nullptr; | 4789 const bool has_extends = extends != nullptr; |
| 4675 while (peek() != Token::RBRACE) { | 4790 while (peek() != Token::RBRACE) { |
| 4676 if (Check(Token::SEMICOLON)) continue; | 4791 if (Check(Token::SEMICOLON)) continue; |
| 4677 FuncNameInferrer::State fni_state(fni_); | 4792 FuncNameInferrer::State fni_state(fni_); |
| 4678 const bool in_class = true; | 4793 const bool in_class = true; |
| 4679 const bool is_static = false; | |
| 4680 bool is_computed_name = false; // Classes do not care about computed | 4794 bool is_computed_name = false; // Classes do not care about computed |
| 4681 // property names here. | 4795 // property names here. |
| 4682 ExpressionClassifier property_classifier(this); | 4796 ExpressionClassifier property_classifier(this); |
| 4683 const AstRawString* property_name = nullptr; | 4797 const AstRawString* property_name = nullptr; |
| 4684 ObjectLiteral::Property* property = ParsePropertyDefinition( | 4798 ObjectLiteral::Property* property = ParsePropertyDefinition( |
| 4685 &checker, in_class, has_extends, is_static, &is_computed_name, | 4799 &checker, in_class, has_extends, MethodKind::Normal, &is_computed_name, |
| 4686 &has_seen_constructor, &property_classifier, &property_name, CHECK_OK); | 4800 &has_seen_constructor, &property_classifier, &property_name, CHECK_OK); |
| 4687 RewriteNonPattern(&property_classifier, CHECK_OK); | 4801 RewriteNonPattern(&property_classifier, CHECK_OK); |
| 4688 if (classifier != nullptr) { | 4802 if (classifier != nullptr) { |
| 4689 classifier->Accumulate(&property_classifier, | 4803 classifier->Accumulate(&property_classifier, |
| 4690 ExpressionClassifier::ExpressionProductions); | 4804 ExpressionClassifier::ExpressionProductions); |
| 4691 } | 4805 } |
| 4692 | 4806 |
| 4693 if (has_seen_constructor && constructor == NULL) { | 4807 if (has_seen_constructor && constructor == NULL) { |
| 4694 constructor = GetPropertyValue(property)->AsFunctionLiteral(); | 4808 constructor = GetPropertyValue(property)->AsFunctionLiteral(); |
| 4695 DCHECK_NOT_NULL(constructor); | 4809 DCHECK_NOT_NULL(constructor); |
| (...skipping 610 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5306 for (int i = 0; i < tail_call_expressions.length(); ++i) { | 5420 for (int i = 0; i < tail_call_expressions.length(); ++i) { |
| 5307 Expression* expression = tail_call_expressions[i]; | 5421 Expression* expression = tail_call_expressions[i]; |
| 5308 // If only FLAG_harmony_explicit_tailcalls is enabled then expression | 5422 // If only FLAG_harmony_explicit_tailcalls is enabled then expression |
| 5309 // must be a Call expression. | 5423 // must be a Call expression. |
| 5310 DCHECK(FLAG_harmony_tailcalls || !FLAG_harmony_explicit_tailcalls || | 5424 DCHECK(FLAG_harmony_tailcalls || !FLAG_harmony_explicit_tailcalls || |
| 5311 expression->IsCall()); | 5425 expression->IsCall()); |
| 5312 MarkTailPosition(expression); | 5426 MarkTailPosition(expression); |
| 5313 } | 5427 } |
| 5314 } | 5428 } |
| 5315 | 5429 |
| 5430 Expression* ParserTraits::ExpressionListToExpression( |
| 5431 ZoneList<Expression*>* args) { |
| 5432 AstNodeFactory* factory = parser_->factory(); |
| 5433 Expression* expr = args->at(0); |
| 5434 for (int i = 1; i < args->length(); ++i) { |
| 5435 expr = factory->NewBinaryOperation(Token::COMMA, expr, args->at(i), |
| 5436 expr->position()); |
| 5437 } |
| 5438 return expr; |
| 5439 } |
| 5440 |
| 5316 void ParserTraits::RewriteDestructuringAssignments() { | 5441 void ParserTraits::RewriteDestructuringAssignments() { |
| 5317 parser_->RewriteDestructuringAssignments(); | 5442 parser_->RewriteDestructuringAssignments(); |
| 5318 } | 5443 } |
| 5319 | 5444 |
| 5320 Expression* ParserTraits::RewriteExponentiation(Expression* left, | 5445 Expression* ParserTraits::RewriteExponentiation(Expression* left, |
| 5321 Expression* right, int pos) { | 5446 Expression* right, int pos) { |
| 5322 return parser_->RewriteExponentiation(left, right, pos); | 5447 return parser_->RewriteExponentiation(left, right, pos); |
| 5323 } | 5448 } |
| 5324 | 5449 |
| 5325 Expression* ParserTraits::RewriteAssignExponentiation(Expression* left, | 5450 Expression* ParserTraits::RewriteAssignExponentiation(Expression* left, |
| 5326 Expression* right, | 5451 Expression* right, |
| 5327 int pos) { | 5452 int pos) { |
| 5328 return parser_->RewriteAssignExponentiation(left, right, pos); | 5453 return parser_->RewriteAssignExponentiation(left, right, pos); |
| 5329 } | 5454 } |
| 5330 | 5455 |
| 5331 void ParserTraits::RewriteNonPattern(Type::ExpressionClassifier* classifier, | 5456 void ParserTraits::RewriteNonPattern(Type::ExpressionClassifier* classifier, |
| 5332 bool* ok) { | 5457 bool* ok) { |
| 5333 parser_->RewriteNonPattern(classifier, ok); | 5458 parser_->RewriteNonPattern(classifier, ok); |
| 5334 } | 5459 } |
| 5335 | 5460 |
| 5461 Expression* ParserTraits::RewriteAwaitExpression(Expression* value, int pos) { |
| 5462 // TODO(caitp): Implement AsyncFunctionAwait() |
| 5463 // per tc39.github.io/ecmascript-asyncawait/#abstract-ops-async-function-await |
| 5464 return value; |
| 5465 } |
| 5336 | 5466 |
| 5337 Zone* ParserTraits::zone() const { | 5467 Zone* ParserTraits::zone() const { |
| 5338 return parser_->function_state_->scope()->zone(); | 5468 return parser_->function_state_->scope()->zone(); |
| 5339 } | 5469 } |
| 5340 | 5470 |
| 5341 | 5471 |
| 5342 ZoneList<Expression*>* ParserTraits::GetNonPatternList() const { | 5472 ZoneList<Expression*>* ParserTraits::GetNonPatternList() const { |
| 5343 return parser_->function_state_->non_patterns_to_rewrite(); | 5473 return parser_->function_state_->non_patterns_to_rewrite(); |
| 5344 } | 5474 } |
| 5345 | 5475 |
| (...skipping 1472 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6818 try_block, target); | 6948 try_block, target); |
| 6819 final_loop = target; | 6949 final_loop = target; |
| 6820 } | 6950 } |
| 6821 | 6951 |
| 6822 return final_loop; | 6952 return final_loop; |
| 6823 } | 6953 } |
| 6824 | 6954 |
| 6825 | 6955 |
| 6826 } // namespace internal | 6956 } // namespace internal |
| 6827 } // namespace v8 | 6957 } // namespace v8 |
| OLD | NEW |