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/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 441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 784 set_allow_natives(FLAG_allow_natives_syntax || info->is_native()); | 788 set_allow_natives(FLAG_allow_natives_syntax || info->is_native()); |
| 785 set_allow_tailcalls(FLAG_harmony_tailcalls && !info->is_native() && | 789 set_allow_tailcalls(FLAG_harmony_tailcalls && !info->is_native() && |
| 786 info->isolate()->is_tail_call_elimination_enabled()); | 790 info->isolate()->is_tail_call_elimination_enabled()); |
| 787 set_allow_harmony_do_expressions(FLAG_harmony_do_expressions); | 791 set_allow_harmony_do_expressions(FLAG_harmony_do_expressions); |
| 788 set_allow_harmony_function_name(FLAG_harmony_function_name); | 792 set_allow_harmony_function_name(FLAG_harmony_function_name); |
| 789 set_allow_harmony_function_sent(FLAG_harmony_function_sent); | 793 set_allow_harmony_function_sent(FLAG_harmony_function_sent); |
| 790 set_allow_harmony_restrictive_declarations( | 794 set_allow_harmony_restrictive_declarations( |
| 791 FLAG_harmony_restrictive_declarations); | 795 FLAG_harmony_restrictive_declarations); |
| 792 set_allow_harmony_exponentiation_operator( | 796 set_allow_harmony_exponentiation_operator( |
| 793 FLAG_harmony_exponentiation_operator); | 797 FLAG_harmony_exponentiation_operator); |
| 798 set_allow_harmony_async_await(FLAG_harmony_async_await); | |
| 794 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; | 799 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; |
| 795 ++feature) { | 800 ++feature) { |
| 796 use_counts_[feature] = 0; | 801 use_counts_[feature] = 0; |
| 797 } | 802 } |
| 798 if (info->ast_value_factory() == NULL) { | 803 if (info->ast_value_factory() == NULL) { |
| 799 // info takes ownership of AstValueFactory. | 804 // info takes ownership of AstValueFactory. |
| 800 info->set_ast_value_factory(new AstValueFactory(zone(), info->hash_seed())); | 805 info->set_ast_value_factory(new AstValueFactory(zone(), info->hash_seed())); |
| 801 info->set_ast_value_factory_owned(); | 806 info->set_ast_value_factory_owned(); |
| 802 ast_value_factory_ = info->ast_value_factory(); | 807 ast_value_factory_ = info->ast_value_factory(); |
| 803 } | 808 } |
| (...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1058 FunctionState function_state(&function_state_, &scope_, scope, | 1063 FunctionState function_state(&function_state_, &scope_, scope, |
| 1059 shared_info->kind(), &function_factory); | 1064 shared_info->kind(), &function_factory); |
| 1060 DCHECK(is_sloppy(scope->language_mode()) || | 1065 DCHECK(is_sloppy(scope->language_mode()) || |
| 1061 is_strict(info->language_mode())); | 1066 is_strict(info->language_mode())); |
| 1062 DCHECK(info->language_mode() == shared_info->language_mode()); | 1067 DCHECK(info->language_mode() == shared_info->language_mode()); |
| 1063 FunctionLiteral::FunctionType function_type = | 1068 FunctionLiteral::FunctionType function_type = |
| 1064 ComputeFunctionType(shared_info); | 1069 ComputeFunctionType(shared_info); |
| 1065 bool ok = true; | 1070 bool ok = true; |
| 1066 | 1071 |
| 1067 if (shared_info->is_arrow()) { | 1072 if (shared_info->is_arrow()) { |
| 1073 bool is_async = allow_harmony_async_await() && | |
| 1074 peek() == Token::IDENTIFIER && | |
| 1075 PeekContextualKeyword(CStrVector("async")) && | |
| 1076 !scanner()->HasAnyLineTerminatorAfterNext(); | |
| 1077 | |
| 1078 if (is_async) { | |
| 1079 Consume(Token::IDENTIFIER); | |
| 1080 DCHECK(peek_any_identifier() || peek() == Token::LPAREN); | |
| 1081 } | |
| 1082 | |
| 1068 // TODO(adamk): We should construct this scope from the ScopeInfo. | 1083 // TODO(adamk): We should construct this scope from the ScopeInfo. |
| 1069 Scope* scope = | 1084 Scope* scope = |
| 1070 NewScope(scope_, FUNCTION_SCOPE, FunctionKind::kArrowFunction); | 1085 NewScope(scope_, FUNCTION_SCOPE, FunctionKind::kArrowFunction); |
| 1071 | 1086 |
| 1072 // These two bits only need to be explicitly set because we're | 1087 // These two bits only need to be explicitly set because we're |
| 1073 // not passing the ScopeInfo to the Scope constructor. | 1088 // not passing the ScopeInfo to the Scope constructor. |
| 1074 // TODO(adamk): Remove these calls once the above NewScope call | 1089 // TODO(adamk): Remove these calls once the above NewScope call |
| 1075 // passes the ScopeInfo. | 1090 // passes the ScopeInfo. |
| 1076 if (shared_info->scope_info()->CallsEval()) { | 1091 if (shared_info->scope_info()->CallsEval()) { |
| 1077 scope->RecordEvalCall(); | 1092 scope->RecordEvalCall(); |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 1098 DeclareFormalParameter(formals.scope, formals.at(0), | 1113 DeclareFormalParameter(formals.scope, formals.at(0), |
| 1099 &formals_classifier); | 1114 &formals_classifier); |
| 1100 } | 1115 } |
| 1101 } | 1116 } |
| 1102 } | 1117 } |
| 1103 | 1118 |
| 1104 if (ok) { | 1119 if (ok) { |
| 1105 checkpoint.Restore(&formals.materialized_literals_count); | 1120 checkpoint.Restore(&formals.materialized_literals_count); |
| 1106 // Pass `accept_IN=true` to ParseArrowFunctionLiteral --- This should | 1121 // Pass `accept_IN=true` to ParseArrowFunctionLiteral --- This should |
| 1107 // not be observable, or else the preparser would have failed. | 1122 // not be observable, or else the preparser would have failed. |
| 1108 Expression* expression = | 1123 Expression* expression = ParseArrowFunctionLiteral( |
| 1109 ParseArrowFunctionLiteral(true, formals, formals_classifier, &ok); | 1124 true, formals, is_async, formals_classifier, &ok); |
| 1110 if (ok) { | 1125 if (ok) { |
| 1111 // Scanning must end at the same position that was recorded | 1126 // Scanning must end at the same position that was recorded |
| 1112 // previously. If not, parsing has been interrupted due to a stack | 1127 // previously. If not, parsing has been interrupted due to a stack |
| 1113 // overflow, at which point the partially parsed arrow function | 1128 // overflow, at which point the partially parsed arrow function |
| 1114 // concise body happens to be a valid expression. This is a problem | 1129 // concise body happens to be a valid expression. This is a problem |
| 1115 // only for arrow functions with single expression bodies, since there | 1130 // only for arrow functions with single expression bodies, since there |
| 1116 // is no end token such as "}" for normal functions. | 1131 // is no end token such as "}" for normal functions. |
| 1117 if (scanner()->location().end_pos == shared_info->end_position()) { | 1132 if (scanner()->location().end_pos == shared_info->end_position()) { |
| 1118 // The pre-parser saw an arrow function here, so the full parser | 1133 // The pre-parser saw an arrow function here, so the full parser |
| 1119 // must produce a FunctionLiteral. | 1134 // must produce a FunctionLiteral. |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1238 | 1253 |
| 1239 return 0; | 1254 return 0; |
| 1240 } | 1255 } |
| 1241 | 1256 |
| 1242 | 1257 |
| 1243 Statement* Parser::ParseStatementListItem(bool* ok) { | 1258 Statement* Parser::ParseStatementListItem(bool* ok) { |
| 1244 // (Ecma 262 6th Edition, 13.1): | 1259 // (Ecma 262 6th Edition, 13.1): |
| 1245 // StatementListItem: | 1260 // StatementListItem: |
| 1246 // Statement | 1261 // Statement |
| 1247 // Declaration | 1262 // Declaration |
| 1248 | 1263 const Token::Value peeked = peek(); |
| 1249 switch (peek()) { | 1264 switch (peeked) { |
| 1250 case Token::FUNCTION: | 1265 case Token::FUNCTION: |
| 1251 return ParseFunctionDeclaration(NULL, ok); | 1266 return ParseFunctionDeclaration(NULL, ok); |
| 1252 case Token::CLASS: | 1267 case Token::CLASS: |
| 1253 Consume(Token::CLASS); | 1268 Consume(Token::CLASS); |
| 1254 return ParseClassDeclaration(NULL, ok); | 1269 return ParseClassDeclaration(NULL, ok); |
| 1255 case Token::CONST: | 1270 case Token::CONST: |
| 1256 return ParseVariableStatement(kStatementListItem, NULL, ok); | 1271 return ParseVariableStatement(kStatementListItem, NULL, ok); |
| 1257 case Token::VAR: | 1272 case Token::VAR: |
| 1258 return ParseVariableStatement(kStatementListItem, NULL, ok); | 1273 return ParseVariableStatement(kStatementListItem, NULL, ok); |
| 1259 case Token::LET: | 1274 case Token::LET: |
| 1260 if (IsNextLetKeyword()) { | 1275 if (IsNextLetKeyword()) { |
| 1261 return ParseVariableStatement(kStatementListItem, NULL, ok); | 1276 return ParseVariableStatement(kStatementListItem, NULL, ok); |
| 1262 } | 1277 } |
| 1263 break; | 1278 break; |
| 1279 case Token::IDENTIFIER: | |
| 1280 if (allow_harmony_async_await() && | |
| 1281 PeekContextualKeyword(CStrVector("async")) && | |
|
Dan Ehrenberg
2016/04/25 21:18:16
You mentioned that this patch causes a parser slow
caitp (gmail)
2016/04/26 00:09:38
I said there was a parser slowdown in JSC. I don't
| |
| 1282 PeekAhead() == Token::FUNCTION && | |
| 1283 !scanner()->HasAnyLineTerminatorAfterNext()) { | |
| 1284 Consume(Token::IDENTIFIER); | |
| 1285 return ParseAsyncFunctionDeclaration(NULL, ok); | |
| 1286 } | |
| 1287 /* falls through */ | |
| 1264 default: | 1288 default: |
| 1265 break; | 1289 break; |
| 1266 } | 1290 } |
| 1267 return ParseStatement(NULL, kAllowLabelledFunctionStatement, ok); | 1291 return ParseStatement(NULL, kAllowLabelledFunctionStatement, ok); |
| 1268 } | 1292 } |
| 1269 | 1293 |
| 1270 | 1294 |
| 1271 Statement* Parser::ParseModuleItem(bool* ok) { | 1295 Statement* Parser::ParseModuleItem(bool* ok) { |
| 1272 // (Ecma 262 6th Edition, 15.2): | 1296 // (Ecma 262 6th Edition, 15.2): |
| 1273 // ModuleItem : | 1297 // ModuleItem : |
| (...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1543 // GeneratorDeclaration[+Default] :: | 1567 // GeneratorDeclaration[+Default] :: |
| 1544 // 'function' '*' '(' FormalParameters ')' '{' FunctionBody '}' | 1568 // 'function' '*' '(' FormalParameters ')' '{' FunctionBody '}' |
| 1545 default_export = ParseFunctionLiteral( | 1569 default_export = ParseFunctionLiteral( |
| 1546 default_string, Scanner::Location::invalid(), | 1570 default_string, Scanner::Location::invalid(), |
| 1547 kSkipFunctionNameCheck, | 1571 kSkipFunctionNameCheck, |
| 1548 is_generator ? FunctionKind::kGeneratorFunction | 1572 is_generator ? FunctionKind::kGeneratorFunction |
| 1549 : FunctionKind::kNormalFunction, | 1573 : FunctionKind::kNormalFunction, |
| 1550 pos, FunctionLiteral::kDeclaration, language_mode(), CHECK_OK); | 1574 pos, FunctionLiteral::kDeclaration, language_mode(), CHECK_OK); |
| 1551 result = factory()->NewEmptyStatement(RelocInfo::kNoPosition); | 1575 result = factory()->NewEmptyStatement(RelocInfo::kNoPosition); |
| 1552 } else { | 1576 } else { |
| 1553 result = ParseFunctionDeclaration(pos, is_generator, &names, CHECK_OK); | 1577 result = ParseFunctionDeclarationInternal( |
| 1578 pos, is_generator ? ParseFunctionFlags::kIsGenerator | |
| 1579 : ParseFunctionFlags::kIsNormal, | |
| 1580 &names, CHECK_OK); | |
| 1554 } | 1581 } |
| 1555 break; | 1582 break; |
| 1556 } | 1583 } |
| 1557 | 1584 |
| 1558 case Token::CLASS: | 1585 case Token::CLASS: |
| 1559 Consume(Token::CLASS); | 1586 Consume(Token::CLASS); |
| 1560 if (peek() == Token::EXTENDS || peek() == Token::LBRACE) { | 1587 if (peek() == Token::EXTENDS || peek() == Token::LBRACE) { |
| 1561 // ClassDeclaration[+Default] :: | 1588 // ClassDeclaration[+Default] :: |
| 1562 // 'class' ('extends' LeftHandExpression)? '{' ClassBody '}' | 1589 // 'class' ('extends' LeftHandExpression)? '{' ClassBody '}' |
| 1563 default_export = | 1590 default_export = |
| (...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2044 return factory()->NewExpressionStatement( | 2071 return factory()->NewExpressionStatement( |
| 2045 factory()->NewAssignment(Token::INIT, proxy, lit, RelocInfo::kNoPosition), | 2072 factory()->NewAssignment(Token::INIT, proxy, lit, RelocInfo::kNoPosition), |
| 2046 pos); | 2073 pos); |
| 2047 } | 2074 } |
| 2048 | 2075 |
| 2049 | 2076 |
| 2050 Statement* Parser::ParseFunctionDeclaration( | 2077 Statement* Parser::ParseFunctionDeclaration( |
| 2051 ZoneList<const AstRawString*>* names, bool* ok) { | 2078 ZoneList<const AstRawString*>* names, bool* ok) { |
| 2052 Expect(Token::FUNCTION, CHECK_OK); | 2079 Expect(Token::FUNCTION, CHECK_OK); |
| 2053 int pos = position(); | 2080 int pos = position(); |
| 2054 bool is_generator = Check(Token::MUL); | 2081 ParseFunctionFlags flags = ParseFunctionFlags::kIsNormal; |
| 2055 return ParseFunctionDeclaration(pos, is_generator, names, ok); | 2082 if (Check(Token::MUL)) { |
| 2083 flags |= ParseFunctionFlags::kIsGenerator; | |
| 2084 } | |
| 2085 return ParseFunctionDeclarationInternal(pos, flags, names, ok); | |
| 2056 } | 2086 } |
| 2057 | 2087 |
| 2088 Statement* Parser::ParseAsyncFunctionDeclaration( | |
| 2089 ZoneList<const AstRawString*>* names, bool* ok) { | |
| 2090 DCHECK_EQ(scanner()->current_token(), Token::IDENTIFIER); | |
| 2091 DCHECK(scanner()->is_literal_contextual_keyword(CStrVector("async"))); | |
| 2092 int pos = position(); | |
| 2093 Expect(Token::FUNCTION, CHECK_OK); | |
| 2094 ParseFunctionFlags flags = ParseFunctionFlags::kIsAsync; | |
| 2095 return ParseFunctionDeclarationInternal(pos, flags, names, ok); | |
| 2096 } | |
| 2058 | 2097 |
| 2059 Statement* Parser::ParseFunctionDeclaration( | 2098 Statement* Parser::ParseFunctionDeclarationInternal( |
| 2060 int pos, bool is_generator, ZoneList<const AstRawString*>* names, | 2099 int pos, ParseFunctionFlags flags, ZoneList<const AstRawString*>* names, |
| 2061 bool* ok) { | 2100 bool* ok) { |
| 2062 // FunctionDeclaration :: | 2101 // FunctionDeclaration :: |
| 2063 // 'function' Identifier '(' FormalParameters ')' '{' FunctionBody '}' | 2102 // 'function' Identifier '(' FormalParameters ')' '{' FunctionBody '}' |
| 2064 // GeneratorDeclaration :: | 2103 // GeneratorDeclaration :: |
| 2065 // 'function' '*' Identifier '(' FormalParameters ')' '{' FunctionBody '}' | 2104 // 'function' '*' Identifier '(' FormalParameters ')' '{' FunctionBody '}' |
| 2066 // | 2105 // |
| 2067 // 'function' and '*' (if present) have been consumed by the caller. | 2106 // 'function' and '*' (if present) have been consumed by the caller. |
| 2107 const bool is_generator = flags & ParseFunctionFlags::kIsGenerator; | |
| 2108 const bool is_async = flags & ParseFunctionFlags::kIsAsync; | |
| 2109 DCHECK(!is_generator || !is_async); | |
| 2110 | |
| 2068 bool is_strict_reserved = false; | 2111 bool is_strict_reserved = false; |
| 2069 const AstRawString* name = ParseIdentifierOrStrictReservedWord( | 2112 const AstRawString* name = ParseIdentifierOrStrictReservedWord( |
| 2070 &is_strict_reserved, CHECK_OK); | 2113 &is_strict_reserved, CHECK_OK); |
| 2071 | 2114 |
| 2115 if (V8_UNLIKELY(is_async_function() && is_async && this->IsAwait(name))) { | |
| 2116 ReportMessageAt(scanner()->location(), | |
| 2117 MessageTemplate::kAwaitBindingIdentifier); | |
| 2118 *ok = false; | |
| 2119 return nullptr; | |
| 2120 } | |
| 2121 | |
| 2072 FuncNameInferrer::State fni_state(fni_); | 2122 FuncNameInferrer::State fni_state(fni_); |
| 2073 if (fni_ != NULL) fni_->PushEnclosingName(name); | 2123 if (fni_ != NULL) fni_->PushEnclosingName(name); |
| 2074 FunctionLiteral* fun = ParseFunctionLiteral( | 2124 FunctionLiteral* fun = ParseFunctionLiteral( |
| 2075 name, scanner()->location(), | 2125 name, scanner()->location(), |
| 2076 is_strict_reserved ? kFunctionNameIsStrictReserved | 2126 is_strict_reserved ? kFunctionNameIsStrictReserved |
| 2077 : kFunctionNameValidityUnknown, | 2127 : kFunctionNameValidityUnknown, |
| 2078 is_generator ? FunctionKind::kGeneratorFunction | 2128 is_generator ? FunctionKind::kGeneratorFunction |
| 2079 : FunctionKind::kNormalFunction, | 2129 : is_async ? FunctionKind::kAsyncFunction |
| 2130 : FunctionKind::kNormalFunction, | |
| 2080 pos, FunctionLiteral::kDeclaration, language_mode(), CHECK_OK); | 2131 pos, FunctionLiteral::kDeclaration, language_mode(), CHECK_OK); |
| 2081 | 2132 |
| 2082 // Even if we're not at the top-level of the global or a function | 2133 // Even if we're not at the top-level of the global or a function |
| 2083 // scope, we treat it as such and introduce the function with its | 2134 // scope, we treat it as such and introduce the function with its |
| 2084 // initial value upon entering the corresponding scope. | 2135 // initial value upon entering the corresponding scope. |
| 2085 // In ES6, a function behaves as a lexical binding, except in | 2136 // In ES6, a function behaves as a lexical binding, except in |
| 2086 // a script scope, or the initial scope of eval or another function. | 2137 // a script scope, or the initial scope of eval or another function. |
| 2087 VariableMode mode = !scope_->is_declaration_scope() ? LET : VAR; | 2138 VariableMode mode = !scope_->is_declaration_scope() ? LET : VAR; |
| 2088 VariableProxy* proxy = NewUnresolved(name, mode); | 2139 VariableProxy* proxy = NewUnresolved(name, mode); |
| 2089 Declaration* declaration = | 2140 Declaration* declaration = |
| (...skipping 2093 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4183 expected_property_count, arity, duplicate_parameters, function_type, | 4234 expected_property_count, arity, duplicate_parameters, function_type, |
| 4184 eager_compile_hint, kind, pos); | 4235 eager_compile_hint, kind, pos); |
| 4185 function_literal->set_function_token_position(function_token_pos); | 4236 function_literal->set_function_token_position(function_token_pos); |
| 4186 if (should_be_used_once_hint) | 4237 if (should_be_used_once_hint) |
| 4187 function_literal->set_should_be_used_once_hint(); | 4238 function_literal->set_should_be_used_once_hint(); |
| 4188 | 4239 |
| 4189 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal); | 4240 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal); |
| 4190 return function_literal; | 4241 return function_literal; |
| 4191 } | 4242 } |
| 4192 | 4243 |
| 4244 Expression* Parser::ParseAsyncFunctionExpression(bool* ok) { | |
| 4245 // AsyncFunctionDeclaration :: | |
| 4246 // async [no LineTerminator here] function ( FormalParameters[Await] ) | |
| 4247 // { AsyncFunctionBody } | |
| 4248 // | |
| 4249 // async [no LineTerminator here] function BindingIdentifier[Await] | |
| 4250 // ( FormalParameters[Await] ) { AsyncFunctionBody } | |
| 4251 DCHECK_EQ(scanner()->current_token(), Token::IDENTIFIER); | |
| 4252 DCHECK(scanner()->is_literal_contextual_keyword(CStrVector("async"))); | |
| 4253 int pos = position(); | |
| 4254 Expect(Token::FUNCTION, CHECK_OK); | |
| 4255 bool is_strict_reserved = false; | |
| 4256 const AstRawString* name = nullptr; | |
| 4257 FunctionLiteral::FunctionType type = FunctionLiteral::kAnonymousExpression; | |
| 4258 | |
| 4259 if (peek_any_identifier()) { | |
| 4260 type = FunctionLiteral::kNamedExpression; | |
| 4261 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); | |
| 4262 if (this->IsAwait(name)) { | |
| 4263 ReportMessageAt(scanner()->location(), | |
| 4264 MessageTemplate::kAwaitBindingIdentifier); | |
| 4265 *ok = false; | |
| 4266 return nullptr; | |
| 4267 } | |
| 4268 } | |
| 4269 return ParseFunctionLiteral(name, scanner()->location(), | |
| 4270 is_strict_reserved ? kFunctionNameIsStrictReserved | |
| 4271 : kFunctionNameValidityUnknown, | |
| 4272 FunctionKind::kAsyncFunction, pos, type, | |
| 4273 language_mode(), CHECK_OK); | |
| 4274 } | |
| 4193 | 4275 |
| 4194 void Parser::SkipLazyFunctionBody(int* materialized_literal_count, | 4276 void Parser::SkipLazyFunctionBody(int* materialized_literal_count, |
| 4195 int* expected_property_count, bool* ok, | 4277 int* expected_property_count, bool* ok, |
| 4196 Scanner::BookmarkScope* bookmark) { | 4278 Scanner::BookmarkScope* bookmark) { |
| 4197 DCHECK_IMPLIES(bookmark, bookmark->HasBeenSet()); | 4279 DCHECK_IMPLIES(bookmark, bookmark->HasBeenSet()); |
| 4198 if (produce_cached_parse_data()) CHECK(log_); | 4280 if (produce_cached_parse_data()) CHECK(log_); |
| 4199 | 4281 |
| 4200 int function_block_pos = position(); | 4282 int function_block_pos = position(); |
| 4201 if (consume_cached_parse_data() && !cached_parse_data_->rejected()) { | 4283 if (consume_cached_parse_data() && !cached_parse_data_->rejected()) { |
| 4202 // If we have cached data, we use it to skip parsing the function body. The | 4284 // If we have cached data, we use it to skip parsing the function body. The |
| (...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4587 reusable_preparser_ = new PreParser(zone(), &scanner_, ast_value_factory(), | 4669 reusable_preparser_ = new PreParser(zone(), &scanner_, ast_value_factory(), |
| 4588 NULL, stack_limit_); | 4670 NULL, stack_limit_); |
| 4589 reusable_preparser_->set_allow_lazy(true); | 4671 reusable_preparser_->set_allow_lazy(true); |
| 4590 #define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name()); | 4672 #define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name()); |
| 4591 SET_ALLOW(natives); | 4673 SET_ALLOW(natives); |
| 4592 SET_ALLOW(harmony_do_expressions); | 4674 SET_ALLOW(harmony_do_expressions); |
| 4593 SET_ALLOW(harmony_function_name); | 4675 SET_ALLOW(harmony_function_name); |
| 4594 SET_ALLOW(harmony_function_sent); | 4676 SET_ALLOW(harmony_function_sent); |
| 4595 SET_ALLOW(harmony_exponentiation_operator); | 4677 SET_ALLOW(harmony_exponentiation_operator); |
| 4596 SET_ALLOW(harmony_restrictive_declarations); | 4678 SET_ALLOW(harmony_restrictive_declarations); |
| 4679 SET_ALLOW(harmony_async_await); | |
| 4597 #undef SET_ALLOW | 4680 #undef SET_ALLOW |
| 4598 } | 4681 } |
| 4599 PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction( | 4682 PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction( |
| 4600 language_mode(), function_state_->kind(), scope_->has_simple_parameters(), | 4683 language_mode(), function_state_->kind(), scope_->has_simple_parameters(), |
| 4601 logger, bookmark); | 4684 logger, bookmark); |
| 4602 if (pre_parse_timer_ != NULL) { | 4685 if (pre_parse_timer_ != NULL) { |
| 4603 pre_parse_timer_->Stop(); | 4686 pre_parse_timer_->Stop(); |
| 4604 } | 4687 } |
| 4605 return result; | 4688 return result; |
| 4606 } | 4689 } |
| (...skipping 665 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5272 ++use_counts_[feature]; | 5355 ++use_counts_[feature]; |
| 5273 scope->SetLanguageMode(mode); | 5356 scope->SetLanguageMode(mode); |
| 5274 } | 5357 } |
| 5275 | 5358 |
| 5276 | 5359 |
| 5277 void Parser::RaiseLanguageMode(LanguageMode mode) { | 5360 void Parser::RaiseLanguageMode(LanguageMode mode) { |
| 5278 LanguageMode old = scope_->language_mode(); | 5361 LanguageMode old = scope_->language_mode(); |
| 5279 SetLanguageMode(scope_, old > mode ? old : mode); | 5362 SetLanguageMode(scope_, old > mode ? old : mode); |
| 5280 } | 5363 } |
| 5281 | 5364 |
| 5365 Expression* ParserTraits::ExpressionListToExpression( | |
| 5366 ZoneList<Expression*>* args) { | |
| 5367 AstNodeFactory* factory = parser_->factory(); | |
| 5368 Expression* expr = args->at(0); | |
| 5369 for (int i = 1; i < args->length(); ++i) { | |
| 5370 expr = factory->NewBinaryOperation(Token::COMMA, expr, args->at(i), | |
| 5371 expr->position()); | |
| 5372 } | |
| 5373 return expr; | |
| 5374 } | |
| 5282 | 5375 |
| 5283 void ParserTraits::RewriteDestructuringAssignments() { | 5376 void ParserTraits::RewriteDestructuringAssignments() { |
| 5284 parser_->RewriteDestructuringAssignments(); | 5377 parser_->RewriteDestructuringAssignments(); |
| 5285 } | 5378 } |
| 5286 | 5379 |
| 5287 Expression* ParserTraits::RewriteExponentiation(Expression* left, | 5380 Expression* ParserTraits::RewriteExponentiation(Expression* left, |
| 5288 Expression* right, int pos) { | 5381 Expression* right, int pos) { |
| 5289 return parser_->RewriteExponentiation(left, right, pos); | 5382 return parser_->RewriteExponentiation(left, right, pos); |
| 5290 } | 5383 } |
| 5291 | 5384 |
| 5292 Expression* ParserTraits::RewriteAssignExponentiation(Expression* left, | 5385 Expression* ParserTraits::RewriteAssignExponentiation(Expression* left, |
| 5293 Expression* right, | 5386 Expression* right, |
| 5294 int pos) { | 5387 int pos) { |
| 5295 return parser_->RewriteAssignExponentiation(left, right, pos); | 5388 return parser_->RewriteAssignExponentiation(left, right, pos); |
| 5296 } | 5389 } |
| 5297 | 5390 |
| 5298 void ParserTraits::RewriteNonPattern(Type::ExpressionClassifier* classifier, | 5391 void ParserTraits::RewriteNonPattern(Type::ExpressionClassifier* classifier, |
| 5299 bool* ok) { | 5392 bool* ok) { |
| 5300 parser_->RewriteNonPattern(classifier, ok); | 5393 parser_->RewriteNonPattern(classifier, ok); |
| 5301 } | 5394 } |
| 5302 | 5395 |
| 5396 Expression* ParserTraits::RewriteAwaitExpression(Expression* value, int pos) { | |
| 5397 // TODO(caitp): Implement AsyncFunctionAwait() | |
| 5398 // per tc39.github.io/ecmascript-asyncawait/#abstract-ops-async-function-await | |
| 5399 return value; | |
| 5400 } | |
| 5303 | 5401 |
| 5304 Zone* ParserTraits::zone() const { | 5402 Zone* ParserTraits::zone() const { |
| 5305 return parser_->function_state_->scope()->zone(); | 5403 return parser_->function_state_->scope()->zone(); |
| 5306 } | 5404 } |
| 5307 | 5405 |
| 5308 | 5406 |
| 5309 ZoneList<Expression*>* ParserTraits::GetNonPatternList() const { | 5407 ZoneList<Expression*>* ParserTraits::GetNonPatternList() const { |
| 5310 return parser_->function_state_->non_patterns_to_rewrite(); | 5408 return parser_->function_state_->non_patterns_to_rewrite(); |
| 5311 } | 5409 } |
| 5312 | 5410 |
| (...skipping 1469 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6782 try_block, target); | 6880 try_block, target); |
| 6783 final_loop = target; | 6881 final_loop = target; |
| 6784 } | 6882 } |
| 6785 | 6883 |
| 6786 return final_loop; | 6884 return final_loop; |
| 6787 } | 6885 } |
| 6788 | 6886 |
| 6789 | 6887 |
| 6790 } // namespace internal | 6888 } // namespace internal |
| 6791 } // namespace v8 | 6889 } // namespace v8 |
| OLD | NEW |