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