| 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 #ifndef V8_PARSING_PARSER_BASE_H | 5 #ifndef V8_PARSING_PARSER_BASE_H |
| 6 #define V8_PARSING_PARSER_BASE_H | 6 #define V8_PARSING_PARSER_BASE_H |
| 7 | 7 |
| 8 #include "src/ast/ast.h" | 8 #include "src/ast/ast.h" |
| 9 #include "src/ast/scopes.h" | 9 #include "src/ast/scopes.h" |
| 10 #include "src/bailout-reason.h" | 10 #include "src/bailout-reason.h" |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 211 stack_overflow_(false), | 211 stack_overflow_(false), |
| 212 default_eager_compile_hint_(FunctionLiteral::kShouldLazyCompile), | 212 default_eager_compile_hint_(FunctionLiteral::kShouldLazyCompile), |
| 213 function_literal_id_(0), | 213 function_literal_id_(0), |
| 214 allow_natives_(false), | 214 allow_natives_(false), |
| 215 allow_tailcalls_(false), | 215 allow_tailcalls_(false), |
| 216 allow_harmony_do_expressions_(false), | 216 allow_harmony_do_expressions_(false), |
| 217 allow_harmony_function_sent_(false), | 217 allow_harmony_function_sent_(false), |
| 218 allow_harmony_restrictive_generators_(false), | 218 allow_harmony_restrictive_generators_(false), |
| 219 allow_harmony_trailing_commas_(false), | 219 allow_harmony_trailing_commas_(false), |
| 220 allow_harmony_class_fields_(false), | 220 allow_harmony_class_fields_(false), |
| 221 allow_harmony_object_spread_(false) {} | 221 allow_harmony_object_spread_(false), |
| 222 allow_harmony_async_iteration_(false) {} |
| 222 | 223 |
| 223 #define ALLOW_ACCESSORS(name) \ | 224 #define ALLOW_ACCESSORS(name) \ |
| 224 bool allow_##name() const { return allow_##name##_; } \ | 225 bool allow_##name() const { return allow_##name##_; } \ |
| 225 void set_allow_##name(bool allow) { allow_##name##_ = allow; } | 226 void set_allow_##name(bool allow) { allow_##name##_ = allow; } |
| 226 | 227 |
| 227 ALLOW_ACCESSORS(natives); | 228 ALLOW_ACCESSORS(natives); |
| 228 ALLOW_ACCESSORS(tailcalls); | 229 ALLOW_ACCESSORS(tailcalls); |
| 229 ALLOW_ACCESSORS(harmony_do_expressions); | 230 ALLOW_ACCESSORS(harmony_do_expressions); |
| 230 ALLOW_ACCESSORS(harmony_function_sent); | 231 ALLOW_ACCESSORS(harmony_function_sent); |
| 231 ALLOW_ACCESSORS(harmony_restrictive_generators); | 232 ALLOW_ACCESSORS(harmony_restrictive_generators); |
| 232 ALLOW_ACCESSORS(harmony_trailing_commas); | 233 ALLOW_ACCESSORS(harmony_trailing_commas); |
| 233 ALLOW_ACCESSORS(harmony_class_fields); | 234 ALLOW_ACCESSORS(harmony_class_fields); |
| 234 ALLOW_ACCESSORS(harmony_object_spread); | 235 ALLOW_ACCESSORS(harmony_object_spread); |
| 236 ALLOW_ACCESSORS(harmony_async_iteration); |
| 235 | 237 |
| 236 #undef ALLOW_ACCESSORS | 238 #undef ALLOW_ACCESSORS |
| 237 | 239 |
| 238 uintptr_t stack_limit() const { return stack_limit_; } | 240 uintptr_t stack_limit() const { return stack_limit_; } |
| 239 | 241 |
| 240 void set_stack_limit(uintptr_t stack_limit) { stack_limit_ = stack_limit; } | 242 void set_stack_limit(uintptr_t stack_limit) { stack_limit_ = stack_limit; } |
| 241 | 243 |
| 242 void set_default_eager_compile_hint( | 244 void set_default_eager_compile_hint( |
| 243 FunctionLiteral::EagerCompileHint eager_compile_hint) { | 245 FunctionLiteral::EagerCompileHint eager_compile_hint) { |
| 244 default_eager_compile_hint_ = eager_compile_hint; | 246 default_eager_compile_hint_ = eager_compile_hint; |
| (...skipping 690 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 935 void RaiseLanguageMode(LanguageMode mode) { | 937 void RaiseLanguageMode(LanguageMode mode) { |
| 936 LanguageMode old = scope()->language_mode(); | 938 LanguageMode old = scope()->language_mode(); |
| 937 impl()->SetLanguageMode(scope(), old > mode ? old : mode); | 939 impl()->SetLanguageMode(scope(), old > mode ? old : mode); |
| 938 } | 940 } |
| 939 bool is_generator() const { | 941 bool is_generator() const { |
| 940 return IsGeneratorFunction(function_state_->kind()); | 942 return IsGeneratorFunction(function_state_->kind()); |
| 941 } | 943 } |
| 942 bool is_async_function() const { | 944 bool is_async_function() const { |
| 943 return IsAsyncFunction(function_state_->kind()); | 945 return IsAsyncFunction(function_state_->kind()); |
| 944 } | 946 } |
| 947 bool is_async_generator() const { |
| 948 return IsAsyncGeneratorFunction(function_state_->kind()); |
| 949 } |
| 945 bool is_resumable() const { | 950 bool is_resumable() const { |
| 946 return IsResumableFunction(function_state_->kind()); | 951 return IsResumableFunction(function_state_->kind()); |
| 947 } | 952 } |
| 948 | 953 |
| 949 // Report syntax errors. | 954 // Report syntax errors. |
| 950 void ReportMessage(MessageTemplate::Template message) { | 955 void ReportMessage(MessageTemplate::Template message) { |
| 951 Scanner::Location source_location = scanner()->location(); | 956 Scanner::Location source_location = scanner()->location(); |
| 952 impl()->ReportMessageAt(source_location, message, | 957 impl()->ReportMessageAt(source_location, message, |
| 953 static_cast<const char*>(nullptr), kSyntaxError); | 958 static_cast<const char*>(nullptr), kSyntaxError); |
| 954 } | 959 } |
| (...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1282 bool* ok); | 1287 bool* ok); |
| 1283 StatementT ParseDoWhileStatement(ZoneList<const AstRawString*>* labels, | 1288 StatementT ParseDoWhileStatement(ZoneList<const AstRawString*>* labels, |
| 1284 bool* ok); | 1289 bool* ok); |
| 1285 StatementT ParseWhileStatement(ZoneList<const AstRawString*>* labels, | 1290 StatementT ParseWhileStatement(ZoneList<const AstRawString*>* labels, |
| 1286 bool* ok); | 1291 bool* ok); |
| 1287 StatementT ParseThrowStatement(bool* ok); | 1292 StatementT ParseThrowStatement(bool* ok); |
| 1288 StatementT ParseSwitchStatement(ZoneList<const AstRawString*>* labels, | 1293 StatementT ParseSwitchStatement(ZoneList<const AstRawString*>* labels, |
| 1289 bool* ok); | 1294 bool* ok); |
| 1290 StatementT ParseTryStatement(bool* ok); | 1295 StatementT ParseTryStatement(bool* ok); |
| 1291 StatementT ParseForStatement(ZoneList<const AstRawString*>* labels, bool* ok); | 1296 StatementT ParseForStatement(ZoneList<const AstRawString*>* labels, bool* ok); |
| 1297 StatementT ParseForAwaitStatement(ZoneList<const AstRawString*>* labels, |
| 1298 bool* ok); |
| 1299 V8_INLINE StatementT ParseForStatementOrForAwaitStatement( |
| 1300 ZoneList<const AstRawString*>* labels, bool* ok) { |
| 1301 if (V8_UNLIKELY(allow_harmony_async_iteration() && is_async_function() && |
| 1302 PeekAhead() == Token::AWAIT)) { |
| 1303 return ParseForAwaitStatement(labels, ok); |
| 1304 } |
| 1305 return ParseForStatement(labels, ok); |
| 1306 } |
| 1292 | 1307 |
| 1293 bool IsNextLetKeyword(); | 1308 bool IsNextLetKeyword(); |
| 1294 bool IsTrivialExpression(); | 1309 bool IsTrivialExpression(); |
| 1295 | 1310 |
| 1296 // Checks if the expression is a valid reference expression (e.g., on the | 1311 // Checks if the expression is a valid reference expression (e.g., on the |
| 1297 // left-hand side of assignments). Although ruled out by ECMA as early errors, | 1312 // left-hand side of assignments). Although ruled out by ECMA as early errors, |
| 1298 // we allow calls for web compatibility and rewrite them to a runtime throw. | 1313 // we allow calls for web compatibility and rewrite them to a runtime throw. |
| 1299 ExpressionT CheckAndRewriteReferenceExpression( | 1314 ExpressionT CheckAndRewriteReferenceExpression( |
| 1300 ExpressionT expression, int beg_pos, int end_pos, | 1315 ExpressionT expression, int beg_pos, int end_pos, |
| 1301 MessageTemplate::Template message, bool* ok); | 1316 MessageTemplate::Template message, bool* ok); |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1450 int function_literal_id_; | 1465 int function_literal_id_; |
| 1451 | 1466 |
| 1452 bool allow_natives_; | 1467 bool allow_natives_; |
| 1453 bool allow_tailcalls_; | 1468 bool allow_tailcalls_; |
| 1454 bool allow_harmony_do_expressions_; | 1469 bool allow_harmony_do_expressions_; |
| 1455 bool allow_harmony_function_sent_; | 1470 bool allow_harmony_function_sent_; |
| 1456 bool allow_harmony_restrictive_generators_; | 1471 bool allow_harmony_restrictive_generators_; |
| 1457 bool allow_harmony_trailing_commas_; | 1472 bool allow_harmony_trailing_commas_; |
| 1458 bool allow_harmony_class_fields_; | 1473 bool allow_harmony_class_fields_; |
| 1459 bool allow_harmony_object_spread_; | 1474 bool allow_harmony_object_spread_; |
| 1475 bool allow_harmony_async_iteration_; |
| 1460 | 1476 |
| 1461 friend class DiscardableZoneScope; | 1477 friend class DiscardableZoneScope; |
| 1462 }; | 1478 }; |
| 1463 | 1479 |
| 1464 template <typename Impl> | 1480 template <typename Impl> |
| 1465 ParserBase<Impl>::FunctionState::FunctionState( | 1481 ParserBase<Impl>::FunctionState::FunctionState( |
| 1466 FunctionState** function_state_stack, ScopeState** scope_stack, | 1482 FunctionState** function_state_stack, ScopeState** scope_stack, |
| 1467 DeclarationScope* scope) | 1483 DeclarationScope* scope) |
| 1468 : ScopeState(scope_stack, scope), | 1484 : ScopeState(scope_stack, scope), |
| 1469 next_materialized_literal_index_(0), | 1485 next_materialized_literal_index_(0), |
| (...skipping 570 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2040 *kind = PropertyKind::kMethodProperty; | 2056 *kind = PropertyKind::kMethodProperty; |
| 2041 } | 2057 } |
| 2042 | 2058 |
| 2043 Token::Value token = peek(); | 2059 Token::Value token = peek(); |
| 2044 int pos = peek_position(); | 2060 int pos = peek_position(); |
| 2045 | 2061 |
| 2046 if (!*is_generator && token == Token::ASYNC && | 2062 if (!*is_generator && token == Token::ASYNC && |
| 2047 !scanner()->HasAnyLineTerminatorAfterNext()) { | 2063 !scanner()->HasAnyLineTerminatorAfterNext()) { |
| 2048 Consume(Token::ASYNC); | 2064 Consume(Token::ASYNC); |
| 2049 token = peek(); | 2065 token = peek(); |
| 2050 if (SetPropertyKindFromToken(token, kind)) { | 2066 if (token == Token::MUL && allow_harmony_async_iteration() && |
| 2067 !scanner()->HasAnyLineTerminatorBeforeNext()) { |
| 2068 Consume(Token::MUL); |
| 2069 token = peek(); |
| 2070 *is_generator = true; |
| 2071 } else if (SetPropertyKindFromToken(token, kind)) { |
| 2051 *name = impl()->GetSymbol(); // TODO(bakkot) specialize on 'async' | 2072 *name = impl()->GetSymbol(); // TODO(bakkot) specialize on 'async' |
| 2052 impl()->PushLiteralName(*name); | 2073 impl()->PushLiteralName(*name); |
| 2053 return factory()->NewStringLiteral(*name, pos); | 2074 return factory()->NewStringLiteral(*name, pos); |
| 2054 } | 2075 } |
| 2055 *kind = PropertyKind::kMethodProperty; | 2076 *kind = PropertyKind::kMethodProperty; |
| 2056 *is_async = true; | 2077 *is_async = true; |
| 2057 pos = peek_position(); | 2078 pos = peek_position(); |
| 2058 } | 2079 } |
| 2059 | 2080 |
| 2060 if (token == Token::IDENTIFIER && !*is_generator && !*is_async) { | 2081 if (token == Token::IDENTIFIER && !*is_generator && !*is_async) { |
| (...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2447 return factory()->NewObjectLiteralProperty( | 2468 return factory()->NewObjectLiteralProperty( |
| 2448 name_expression, value, ObjectLiteralProperty::COMPUTED, false); | 2469 name_expression, value, ObjectLiteralProperty::COMPUTED, false); |
| 2449 } | 2470 } |
| 2450 | 2471 |
| 2451 case PropertyKind::kMethodProperty: { | 2472 case PropertyKind::kMethodProperty: { |
| 2452 DCHECK(!is_get && !is_set); | 2473 DCHECK(!is_get && !is_set); |
| 2453 | 2474 |
| 2454 // MethodDefinition | 2475 // MethodDefinition |
| 2455 // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' | 2476 // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' |
| 2456 // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' | 2477 // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' |
| 2478 // async PropertyName '(' StrictFormalParameters ')' |
| 2479 // '{' FunctionBody '}' |
| 2480 // async '*' PropertyName '(' StrictFormalParameters ')' |
| 2481 // '{' FunctionBody '}' |
| 2457 | 2482 |
| 2458 classifier()->RecordPatternError( | 2483 classifier()->RecordPatternError( |
| 2459 Scanner::Location(next_beg_pos, scanner()->location().end_pos), | 2484 Scanner::Location(next_beg_pos, scanner()->location().end_pos), |
| 2460 MessageTemplate::kInvalidDestructuringTarget); | 2485 MessageTemplate::kInvalidDestructuringTarget); |
| 2461 | 2486 |
| 2462 FunctionKind kind = is_generator | 2487 static const FunctionKind kMethodKinds[] = { |
| 2463 ? FunctionKind::kConciseGeneratorMethod | 2488 FunctionKind::kConciseMethod, FunctionKind::kConciseGeneratorMethod, |
| 2464 : is_async ? FunctionKind::kAsyncConciseMethod | 2489 FunctionKind::kAsyncConciseMethod, |
| 2465 : FunctionKind::kConciseMethod; | 2490 FunctionKind::kAsyncConciseGeneratorMethod}; |
| 2491 int index = static_cast<int>(!!is_generator) + |
| 2492 (static_cast<int>(!!is_async) << 1); |
| 2493 FunctionKind kind = kMethodKinds[index]; |
| 2466 | 2494 |
| 2467 ExpressionT value = impl()->ParseFunctionLiteral( | 2495 ExpressionT value = impl()->ParseFunctionLiteral( |
| 2468 name, scanner()->location(), kSkipFunctionNameCheck, kind, | 2496 name, scanner()->location(), kSkipFunctionNameCheck, kind, |
| 2469 kNoSourcePosition, FunctionLiteral::kAccessorOrMethod, | 2497 kNoSourcePosition, FunctionLiteral::kAccessorOrMethod, |
| 2470 language_mode(), CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2498 language_mode(), CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 2471 | 2499 |
| 2472 return factory()->NewObjectLiteralProperty( | 2500 return factory()->NewObjectLiteralProperty( |
| 2473 name_expression, value, ObjectLiteralProperty::COMPUTED, | 2501 name_expression, value, ObjectLiteralProperty::COMPUTED, |
| 2474 *is_computed_name); | 2502 *is_computed_name); |
| 2475 } | 2503 } |
| (...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2881 expression = ParseAssignmentExpression(accept_IN, CHECK_OK); | 2909 expression = ParseAssignmentExpression(accept_IN, CHECK_OK); |
| 2882 impl()->RewriteNonPattern(CHECK_OK); | 2910 impl()->RewriteNonPattern(CHECK_OK); |
| 2883 break; | 2911 break; |
| 2884 } | 2912 } |
| 2885 } | 2913 } |
| 2886 | 2914 |
| 2887 if (delegating) { | 2915 if (delegating) { |
| 2888 return impl()->RewriteYieldStar(generator_object, expression, pos); | 2916 return impl()->RewriteYieldStar(generator_object, expression, pos); |
| 2889 } | 2917 } |
| 2890 | 2918 |
| 2891 expression = impl()->BuildIteratorResult(expression, false); | 2919 if (!is_async_generator()) { |
| 2920 // Async generator yield is rewritten in Ignition, and doesn't require |
| 2921 // producing an Iterator Result. |
| 2922 expression = impl()->BuildIteratorResult(expression, false); |
| 2923 } |
| 2924 |
| 2892 // Hackily disambiguate o from o.next and o [Symbol.iterator](). | 2925 // Hackily disambiguate o from o.next and o [Symbol.iterator](). |
| 2893 // TODO(verwaest): Come up with a better solution. | 2926 // TODO(verwaest): Come up with a better solution. |
| 2894 ExpressionT yield = factory()->NewYield(generator_object, expression, pos, | 2927 ExpressionT yield = factory()->NewYield(generator_object, expression, pos, |
| 2895 Yield::kOnExceptionThrow); | 2928 Yield::kOnExceptionThrow); |
| 2896 return yield; | 2929 return yield; |
| 2897 } | 2930 } |
| 2898 | 2931 |
| 2899 // Precedence = 3 | 2932 // Precedence = 3 |
| 2900 template <typename Impl> | 2933 template <typename Impl> |
| 2901 typename ParserBase<Impl>::ExpressionT | 2934 typename ParserBase<Impl>::ExpressionT |
| (...skipping 842 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3744 // 'function' Identifier '(' FormalParameters ')' '{' FunctionBody '}' | 3777 // 'function' Identifier '(' FormalParameters ')' '{' FunctionBody '}' |
| 3745 // 'function' '(' FormalParameters ')' '{' FunctionBody '}' | 3778 // 'function' '(' FormalParameters ')' '{' FunctionBody '}' |
| 3746 // GeneratorDeclaration :: | 3779 // GeneratorDeclaration :: |
| 3747 // 'function' '*' Identifier '(' FormalParameters ')' '{' FunctionBody '}' | 3780 // 'function' '*' Identifier '(' FormalParameters ')' '{' FunctionBody '}' |
| 3748 // 'function' '*' '(' FormalParameters ')' '{' FunctionBody '}' | 3781 // 'function' '*' '(' FormalParameters ')' '{' FunctionBody '}' |
| 3749 // | 3782 // |
| 3750 // The anonymous forms are allowed iff [default_export] is true. | 3783 // The anonymous forms are allowed iff [default_export] is true. |
| 3751 // | 3784 // |
| 3752 // 'function' and '*' (if present) have been consumed by the caller. | 3785 // 'function' and '*' (if present) have been consumed by the caller. |
| 3753 | 3786 |
| 3754 const bool is_generator = flags & ParseFunctionFlags::kIsGenerator; | 3787 bool is_generator = flags & ParseFunctionFlags::kIsGenerator; |
| 3755 const bool is_async = flags & ParseFunctionFlags::kIsAsync; | 3788 const bool is_async = flags & ParseFunctionFlags::kIsAsync; |
| 3756 DCHECK(!is_generator || !is_async); | 3789 DCHECK(!is_generator || !is_async); |
| 3757 | 3790 |
| 3791 if (allow_harmony_async_iteration() && is_async && Check(Token::MUL)) { |
| 3792 // Async generator |
| 3793 is_generator = true; |
| 3794 } |
| 3795 |
| 3758 IdentifierT name; | 3796 IdentifierT name; |
| 3759 FunctionNameValidity name_validity; | 3797 FunctionNameValidity name_validity; |
| 3760 IdentifierT variable_name; | 3798 IdentifierT variable_name; |
| 3761 if (default_export && peek() == Token::LPAREN) { | 3799 if (default_export && peek() == Token::LPAREN) { |
| 3762 impl()->GetDefaultStrings(&name, &variable_name); | 3800 impl()->GetDefaultStrings(&name, &variable_name); |
| 3763 name_validity = kSkipFunctionNameCheck; | 3801 name_validity = kSkipFunctionNameCheck; |
| 3764 } else { | 3802 } else { |
| 3765 bool is_strict_reserved; | 3803 bool is_strict_reserved; |
| 3766 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved, | 3804 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved, |
| 3767 CHECK_OK_CUSTOM(NullStatement)); | 3805 CHECK_OK_CUSTOM(NullStatement)); |
| 3768 name_validity = is_strict_reserved ? kFunctionNameIsStrictReserved | 3806 name_validity = is_strict_reserved ? kFunctionNameIsStrictReserved |
| 3769 : kFunctionNameValidityUnknown; | 3807 : kFunctionNameValidityUnknown; |
| 3770 variable_name = name; | 3808 variable_name = name; |
| 3771 } | 3809 } |
| 3772 | 3810 |
| 3773 FuncNameInferrer::State fni_state(fni_); | 3811 FuncNameInferrer::State fni_state(fni_); |
| 3774 impl()->PushEnclosingName(name); | 3812 impl()->PushEnclosingName(name); |
| 3813 |
| 3814 static const FunctionKind kFunctionKinds[] = { |
| 3815 FunctionKind::kNormalFunction, FunctionKind::kGeneratorFunction, |
| 3816 FunctionKind::kAsyncFunction, FunctionKind::kAsyncGeneratorFunction}; |
| 3817 int index = |
| 3818 static_cast<int>(!!is_generator) + (static_cast<int>(!!is_async) << 1); |
| 3819 FunctionKind kind = kFunctionKinds[index]; |
| 3820 |
| 3775 FunctionLiteralT function = impl()->ParseFunctionLiteral( | 3821 FunctionLiteralT function = impl()->ParseFunctionLiteral( |
| 3776 name, scanner()->location(), name_validity, | 3822 name, scanner()->location(), name_validity, kind, pos, |
| 3777 is_generator ? FunctionKind::kGeneratorFunction | 3823 FunctionLiteral::kDeclaration, language_mode(), |
| 3778 : is_async ? FunctionKind::kAsyncFunction | |
| 3779 : FunctionKind::kNormalFunction, | |
| 3780 pos, FunctionLiteral::kDeclaration, language_mode(), | |
| 3781 CHECK_OK_CUSTOM(NullStatement)); | 3824 CHECK_OK_CUSTOM(NullStatement)); |
| 3782 | 3825 |
| 3783 return impl()->DeclareFunction(variable_name, function, pos, is_generator, | 3826 return impl()->DeclareFunction(variable_name, function, pos, is_generator, |
| 3784 is_async, names, ok); | 3827 is_async, names, ok); |
| 3785 } | 3828 } |
| 3786 | 3829 |
| 3787 template <typename Impl> | 3830 template <typename Impl> |
| 3788 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseClassDeclaration( | 3831 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseClassDeclaration( |
| 3789 ZoneList<const AstRawString*>* names, bool default_export, bool* ok) { | 3832 ZoneList<const AstRawString*>* names, bool default_export, bool* ok) { |
| 3790 // ClassDeclaration :: | 3833 // ClassDeclaration :: |
| (...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4224 // | 4267 // |
| 4225 // async [no LineTerminator here] function BindingIdentifier[Await] | 4268 // async [no LineTerminator here] function BindingIdentifier[Await] |
| 4226 // ( FormalParameters[Await] ) { AsyncFunctionBody } | 4269 // ( FormalParameters[Await] ) { AsyncFunctionBody } |
| 4227 DCHECK_EQ(scanner()->current_token(), Token::ASYNC); | 4270 DCHECK_EQ(scanner()->current_token(), Token::ASYNC); |
| 4228 int pos = position(); | 4271 int pos = position(); |
| 4229 Expect(Token::FUNCTION, CHECK_OK); | 4272 Expect(Token::FUNCTION, CHECK_OK); |
| 4230 bool is_strict_reserved = false; | 4273 bool is_strict_reserved = false; |
| 4231 IdentifierT name = impl()->EmptyIdentifier(); | 4274 IdentifierT name = impl()->EmptyIdentifier(); |
| 4232 FunctionLiteral::FunctionType type = FunctionLiteral::kAnonymousExpression; | 4275 FunctionLiteral::FunctionType type = FunctionLiteral::kAnonymousExpression; |
| 4233 | 4276 |
| 4277 bool is_generator = allow_harmony_async_iteration() && Check(Token::MUL); |
| 4278 |
| 4279 static const FunctionKind kFunctionKinds[] = { |
| 4280 FunctionKind::kAsyncFunction, FunctionKind::kAsyncGeneratorFunction, |
| 4281 }; |
| 4282 FunctionKind kind = kFunctionKinds[!!is_generator]; |
| 4283 |
| 4234 if (peek_any_identifier()) { | 4284 if (peek_any_identifier()) { |
| 4235 type = FunctionLiteral::kNamedExpression; | 4285 type = FunctionLiteral::kNamedExpression; |
| 4236 name = ParseIdentifierOrStrictReservedWord(FunctionKind::kAsyncFunction, | 4286 name = ParseIdentifierOrStrictReservedWord(kind, &is_strict_reserved, |
| 4237 &is_strict_reserved, CHECK_OK); | 4287 CHECK_OK); |
| 4238 } | 4288 } |
| 4239 return impl()->ParseFunctionLiteral( | 4289 return impl()->ParseFunctionLiteral( |
| 4240 name, scanner()->location(), | 4290 name, scanner()->location(), |
| 4241 is_strict_reserved ? kFunctionNameIsStrictReserved | 4291 is_strict_reserved ? kFunctionNameIsStrictReserved |
| 4242 : kFunctionNameValidityUnknown, | 4292 : kFunctionNameValidityUnknown, |
| 4243 FunctionKind::kAsyncFunction, pos, type, language_mode(), CHECK_OK); | 4293 kind, pos, type, language_mode(), CHECK_OK); |
| 4244 } | 4294 } |
| 4245 | 4295 |
| 4246 template <typename Impl> | 4296 template <typename Impl> |
| 4247 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseTemplateLiteral( | 4297 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseTemplateLiteral( |
| 4248 ExpressionT tag, int start, bool* ok) { | 4298 ExpressionT tag, int start, bool* ok) { |
| 4249 // A TemplateLiteral is made up of 0 or more TEMPLATE_SPAN tokens (literal | 4299 // A TemplateLiteral is made up of 0 or more TEMPLATE_SPAN tokens (literal |
| 4250 // text followed by a substitution expression), finalized by a single | 4300 // text followed by a substitution expression), finalized by a single |
| 4251 // TEMPLATE_TAIL. | 4301 // TEMPLATE_TAIL. |
| 4252 // | 4302 // |
| 4253 // In terms of draft language, TEMPLATE_SPAN may be either the TemplateHead or | 4303 // In terms of draft language, TEMPLATE_SPAN may be either the TemplateHead or |
| (...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4594 case Token::SEMICOLON: | 4644 case Token::SEMICOLON: |
| 4595 Next(); | 4645 Next(); |
| 4596 return factory()->NewEmptyStatement(kNoSourcePosition); | 4646 return factory()->NewEmptyStatement(kNoSourcePosition); |
| 4597 case Token::IF: | 4647 case Token::IF: |
| 4598 return ParseIfStatement(labels, ok); | 4648 return ParseIfStatement(labels, ok); |
| 4599 case Token::DO: | 4649 case Token::DO: |
| 4600 return ParseDoWhileStatement(labels, ok); | 4650 return ParseDoWhileStatement(labels, ok); |
| 4601 case Token::WHILE: | 4651 case Token::WHILE: |
| 4602 return ParseWhileStatement(labels, ok); | 4652 return ParseWhileStatement(labels, ok); |
| 4603 case Token::FOR: | 4653 case Token::FOR: |
| 4604 return ParseForStatement(labels, ok); | 4654 return ParseForStatementOrForAwaitStatement(labels, ok); |
| 4605 case Token::CONTINUE: | 4655 case Token::CONTINUE: |
| 4606 case Token::BREAK: | 4656 case Token::BREAK: |
| 4607 case Token::RETURN: | 4657 case Token::RETURN: |
| 4608 case Token::THROW: | 4658 case Token::THROW: |
| 4609 case Token::TRY: { | 4659 case Token::TRY: { |
| 4610 // These statements must have their labels preserved in an enclosing | 4660 // These statements must have their labels preserved in an enclosing |
| 4611 // block, as the corresponding AST nodes do not currently store their | 4661 // block, as the corresponding AST nodes do not currently store their |
| 4612 // labels. | 4662 // labels. |
| 4613 // TODO(nikolaos, marja): Consider adding the labels to the AST nodes. | 4663 // TODO(nikolaos, marja): Consider adding the labels to the AST nodes. |
| 4614 if (labels == nullptr) { | 4664 if (labels == nullptr) { |
| (...skipping 856 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5471 block->set_scope(for_scope); | 5521 block->set_scope(for_scope); |
| 5472 loop->Initialize(init, cond, next, body); | 5522 loop->Initialize(init, cond, next, body); |
| 5473 return block; | 5523 return block; |
| 5474 } else { | 5524 } else { |
| 5475 loop->Initialize(init, cond, next, body); | 5525 loop->Initialize(init, cond, next, body); |
| 5476 return loop; | 5526 return loop; |
| 5477 } | 5527 } |
| 5478 } | 5528 } |
| 5479 } | 5529 } |
| 5480 | 5530 |
| 5531 template <typename Impl> |
| 5532 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseForAwaitStatement( |
| 5533 ZoneList<const AstRawString*>* labels, bool* ok) { |
| 5534 // for await '(' ForDeclaration of AssignmentExpression ')' Statement |
| 5535 DCHECK(is_async_function()); |
| 5536 |
| 5537 int stmt_pos = peek_position(); |
| 5538 bool bound_names_are_lexical = false; |
| 5539 |
| 5540 ForInfo for_info(this); |
| 5541 BlockState for_state(zone(), &scope_state_); |
| 5542 |
| 5543 Expect(Token::FOR, CHECK_OK); |
| 5544 Expect(Token::AWAIT, CHECK_OK); |
| 5545 Expect(Token::LPAREN, CHECK_OK); |
| 5546 |
| 5547 /* |
| 5548 ZoneList<const AstRawString*> bound_names; |
| 5549 ForEachStatement::VisitMode mode; |
| 5550 int position; |
| 5551 DeclarationParsingResult parsing_result; |
| 5552 */ |
| 5553 for_info.mode = ForEachStatement::ASYNC_ITERATE; |
| 5554 for_state.set_start_position(scanner()->location().beg_pos); |
| 5555 for_state.set_is_hidden(); |
| 5556 |
| 5557 StatementT init = impl()->NullStatement(); |
| 5558 |
| 5559 bool has_declarations = false; |
| 5560 bool is_destructuring = false; |
| 5561 |
| 5562 if (peek() == Token::VAR || peek() == Token::CONST || |
| 5563 (peek() == Token::LET && IsNextLetKeyword())) { |
| 5564 // The initializer contains declarations. |
| 5565 has_declarations = true; |
| 5566 ParseVariableDeclarations(kForStatement, &for_info.parsing_result, nullptr, |
| 5567 CHECK_OK); |
| 5568 bound_names_are_lexical = |
| 5569 IsLexicalVariableMode(for_info.parsing_result.descriptor.mode); |
| 5570 for_info.position = scanner()->location().beg_pos; |
| 5571 |
| 5572 // Just one declaration followed by in/of. |
| 5573 if (for_info.parsing_result.declarations.length() != 1) { |
| 5574 impl()->ReportMessageAt(for_info.parsing_result.bindings_loc, |
| 5575 MessageTemplate::kForInOfLoopMultiBindings, |
| 5576 ForEachStatement::VisitModeString(for_info.mode)); |
| 5577 *ok = false; |
| 5578 return impl()->NullStatement(); |
| 5579 } |
| 5580 } else { |
| 5581 // The initializer does not contain declarations. |
| 5582 int lhs_beg_pos = peek_position(); |
| 5583 ExpressionClassifier classifier(this); |
| 5584 ExpressionT expression = ParseExpressionCoverGrammar(false, CHECK_OK); |
| 5585 int lhs_end_pos = scanner()->location().end_pos; |
| 5586 |
| 5587 if (expression->IsArrayLiteral() || expression->IsObjectLiteral()) { |
| 5588 ValidateAssignmentPattern(CHECK_OK); |
| 5589 } else { |
| 5590 impl()->RewriteNonPattern(CHECK_OK); |
| 5591 expression = impl()->CheckAndRewriteReferenceExpression( |
| 5592 expression, lhs_beg_pos, lhs_end_pos, |
| 5593 MessageTemplate::kInvalidLhsInFor, kSyntaxError, CHECK_OK); |
| 5594 } |
| 5595 } |
| 5596 |
| 5597 ExpectContextualKeyword(CStrVector("of"), CHECK_OK); |
| 5598 int each_keyword_pos = scanner()->location().beg_pos; |
| 5599 |
| 5600 ExpressionClassifier classifier(this); |
| 5601 ExpressionT iterable = ParseAssignmentExpression(true, CHECK_OK); |
| 5602 impl()->RewriteNonPattern(CHECK_OK); |
| 5603 |
| 5604 BlockT init_block = impl()->RewriteForVarInLegacy(for_info); |
| 5605 |
| 5606 auto loop = factory()->NewForEachStatement(for_info.mode, labels, stmt_pos); |
| 5607 typename Types::Target target(this, loop); |
| 5608 |
| 5609 Expect(Token::RPAREN, CHECK_OK); |
| 5610 |
| 5611 StatementT final_loop = impl()->NullStatement(); |
| 5612 { |
| 5613 ReturnExprScope no_tail_calls(function_state_, |
| 5614 ReturnExprContext::kInsideForInOfBody); |
| 5615 BlockState block_state(zone(), &scope_state_); |
| 5616 block_state.set_start_position(scanner()->location().beg_pos); |
| 5617 |
| 5618 StatementT body = ParseScopedStatement(nullptr, true, CHECK_OK); |
| 5619 |
| 5620 BlockT body_block = impl()->NullBlock(); |
| 5621 ExpressionT each_variable = impl()->EmptyExpression(); |
| 5622 impl()->DesugarBindingInForEachStatement(&for_info, &body_block, |
| 5623 &each_variable, CHECK_OK); |
| 5624 body_block->statements()->Add(body, zone()); |
| 5625 final_loop = impl()->InitializeForAwaitOfStatement( |
| 5626 loop, each_variable, iterable, body_block, each_keyword_pos); |
| 5627 |
| 5628 block_state.set_end_position(scanner()->location().end_pos); |
| 5629 body_block->set_scope(block_state.FinalizedBlockScope()); |
| 5630 } |
| 5631 |
| 5632 init_block = impl()->CreateForEachStatementTDZ(init_block, for_info, ok); |
| 5633 |
| 5634 for_state.set_end_position(scanner()->location().end_pos); |
| 5635 Scope* for_scope = for_state.FinalizedBlockScope(); |
| 5636 // Parsed for-in loop w/ variable declarations. |
| 5637 if (!impl()->IsNullStatement(init_block)) { |
| 5638 init_block->statements()->Add(final_loop, zone()); |
| 5639 init_block->set_scope(for_scope); |
| 5640 return init_block; |
| 5641 } |
| 5642 |
| 5643 DCHECK_NULL(for_scope); |
| 5644 return final_loop; |
| 5645 } |
| 5646 |
| 5481 #undef CHECK_OK | 5647 #undef CHECK_OK |
| 5482 #undef CHECK_OK_CUSTOM | 5648 #undef CHECK_OK_CUSTOM |
| 5483 | 5649 |
| 5484 template <typename Impl> | 5650 template <typename Impl> |
| 5485 void ParserBase<Impl>::ObjectLiteralChecker::CheckDuplicateProto( | 5651 void ParserBase<Impl>::ObjectLiteralChecker::CheckDuplicateProto( |
| 5486 Token::Value property) { | 5652 Token::Value property) { |
| 5487 if (property == Token::SMI || property == Token::NUMBER) return; | 5653 if (property == Token::SMI || property == Token::NUMBER) return; |
| 5488 | 5654 |
| 5489 if (IsProto()) { | 5655 if (IsProto()) { |
| 5490 if (has_seen_proto_) { | 5656 if (has_seen_proto_) { |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5529 has_seen_constructor_ = true; | 5695 has_seen_constructor_ = true; |
| 5530 return; | 5696 return; |
| 5531 } | 5697 } |
| 5532 } | 5698 } |
| 5533 | 5699 |
| 5534 | 5700 |
| 5535 } // namespace internal | 5701 } // namespace internal |
| 5536 } // namespace v8 | 5702 } // namespace v8 |
| 5537 | 5703 |
| 5538 #endif // V8_PARSING_PARSER_BASE_H | 5704 #endif // V8_PARSING_PARSER_BASE_H |
| OLD | NEW |