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/scopes.h" | 8 #include "src/ast/scopes.h" |
9 #include "src/bailout-reason.h" | 9 #include "src/bailout-reason.h" |
10 #include "src/hashmap.h" | 10 #include "src/hashmap.h" |
(...skipping 18 matching lines...) Expand all Loading... |
29 kDisallowLabelledFunctionStatement, | 29 kDisallowLabelledFunctionStatement, |
30 }; | 30 }; |
31 | 31 |
32 enum class ParseFunctionFlags { | 32 enum class ParseFunctionFlags { |
33 kIsNormal = 0, | 33 kIsNormal = 0, |
34 kIsGenerator = 1, | 34 kIsGenerator = 1, |
35 kIsAsync = 2, | 35 kIsAsync = 2, |
36 kIsDefault = 4 | 36 kIsDefault = 4 |
37 }; | 37 }; |
38 | 38 |
| 39 enum class FunctionBody { |
| 40 Normal, |
| 41 ArrowBlock = Normal, |
| 42 ArrowConcise, |
| 43 }; |
| 44 |
39 static inline ParseFunctionFlags operator|(ParseFunctionFlags lhs, | 45 static inline ParseFunctionFlags operator|(ParseFunctionFlags lhs, |
40 ParseFunctionFlags rhs) { | 46 ParseFunctionFlags rhs) { |
41 typedef unsigned char T; | 47 typedef unsigned char T; |
42 return static_cast<ParseFunctionFlags>(static_cast<T>(lhs) | | 48 return static_cast<ParseFunctionFlags>(static_cast<T>(lhs) | |
43 static_cast<T>(rhs)); | 49 static_cast<T>(rhs)); |
44 } | 50 } |
45 | 51 |
46 static inline ParseFunctionFlags& operator|=(ParseFunctionFlags& lhs, | 52 static inline ParseFunctionFlags& operator|=(ParseFunctionFlags& lhs, |
47 const ParseFunctionFlags& rhs) { | 53 const ParseFunctionFlags& rhs) { |
48 lhs = lhs | rhs; | 54 lhs = lhs | rhs; |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
253 | 259 |
254 bool is_generator() const { return IsGeneratorFunction(kind_); } | 260 bool is_generator() const { return IsGeneratorFunction(kind_); } |
255 bool is_async_function() const { return IsAsyncFunction(kind_); } | 261 bool is_async_function() const { return IsAsyncFunction(kind_); } |
256 | 262 |
257 FunctionKind kind() const { return kind_; } | 263 FunctionKind kind() const { return kind_; } |
258 FunctionState* outer() const { return outer_function_state_; } | 264 FunctionState* outer() const { return outer_function_state_; } |
259 | 265 |
260 void set_generator_object_variable( | 266 void set_generator_object_variable( |
261 typename Traits::Type::GeneratorVariable* variable) { | 267 typename Traits::Type::GeneratorVariable* variable) { |
262 DCHECK(variable != NULL); | 268 DCHECK(variable != NULL); |
263 DCHECK(is_generator()); | 269 DCHECK(is_generator() || is_async_function()); |
264 generator_object_variable_ = variable; | 270 generator_object_variable_ = variable; |
265 } | 271 } |
266 typename Traits::Type::GeneratorVariable* generator_object_variable() | 272 typename Traits::Type::GeneratorVariable* generator_object_variable() |
267 const { | 273 const { |
268 return generator_object_variable_; | 274 return generator_object_variable_; |
269 } | 275 } |
270 | 276 |
271 typename Traits::Type::Factory* factory() { return factory_; } | 277 typename Traits::Type::Factory* factory() { return factory_; } |
272 | 278 |
273 const List<DestructuringAssignment>& destructuring_assignments_to_rewrite() | 279 const List<DestructuringAssignment>& destructuring_assignments_to_rewrite() |
(...skipping 1732 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2006 name, position(), scanner()->location().end_pos, scope_, factory()); | 2012 name, position(), scanner()->location().end_pos, scope_, factory()); |
2007 } | 2013 } |
2008 | 2014 |
2009 if (peek() == Token::ARROW) { | 2015 if (peek() == Token::ARROW) { |
2010 classifier->RecordPatternError(scanner()->peek_location(), | 2016 classifier->RecordPatternError(scanner()->peek_location(), |
2011 MessageTemplate::kUnexpectedToken, | 2017 MessageTemplate::kUnexpectedToken, |
2012 Token::String(Token::ARROW)); | 2018 Token::String(Token::ARROW)); |
2013 ValidateArrowFormalParameters(&arrow_formals_classifier, expression, | 2019 ValidateArrowFormalParameters(&arrow_formals_classifier, expression, |
2014 parenthesized_formals, is_async, CHECK_OK); | 2020 parenthesized_formals, is_async, CHECK_OK); |
2015 Scanner::Location loc(lhs_beg_pos, scanner()->location().end_pos); | 2021 Scanner::Location loc(lhs_beg_pos, scanner()->location().end_pos); |
2016 Scope* scope = | 2022 Scope* scope = this->NewScope(scope_, FUNCTION_SCOPE, |
2017 this->NewScope(scope_, FUNCTION_SCOPE, FunctionKind::kArrowFunction); | 2023 is_async ? FunctionKind::kAsyncArrowFunction |
| 2024 : FunctionKind::kArrowFunction); |
2018 // Because the arrow's parameters were parsed in the outer scope, any | 2025 // Because the arrow's parameters were parsed in the outer scope, any |
2019 // usage flags that might have been triggered there need to be copied | 2026 // usage flags that might have been triggered there need to be copied |
2020 // to the arrow scope. | 2027 // to the arrow scope. |
2021 scope_->PropagateUsageFlagsToScope(scope); | 2028 scope_->PropagateUsageFlagsToScope(scope); |
2022 FormalParametersT parameters(scope); | 2029 FormalParametersT parameters(scope); |
2023 if (!arrow_formals_classifier.is_simple_parameter_list()) { | 2030 if (!arrow_formals_classifier.is_simple_parameter_list()) { |
2024 scope->SetHasNonSimpleParameters(); | 2031 scope->SetHasNonSimpleParameters(); |
2025 parameters.is_simple = false; | 2032 parameters.is_simple = false; |
2026 } | 2033 } |
2027 | 2034 |
(...skipping 906 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2934 *ok = false; | 2941 *ok = false; |
2935 return this->EmptyExpression(); | 2942 return this->EmptyExpression(); |
2936 } | 2943 } |
2937 | 2944 |
2938 typename Traits::Type::StatementList body; | 2945 typename Traits::Type::StatementList body; |
2939 int num_parameters = formal_parameters.scope->num_parameters(); | 2946 int num_parameters = formal_parameters.scope->num_parameters(); |
2940 int materialized_literal_count = -1; | 2947 int materialized_literal_count = -1; |
2941 int expected_property_count = -1; | 2948 int expected_property_count = -1; |
2942 Scanner::Location super_loc; | 2949 Scanner::Location super_loc; |
2943 | 2950 |
| 2951 FunctionKind arrow_kind = is_async ? kAsyncArrowFunction : kArrowFunction; |
2944 { | 2952 { |
2945 typename Traits::Type::Factory function_factory(ast_value_factory()); | 2953 typename Traits::Type::Factory function_factory(ast_value_factory()); |
2946 FunctionState function_state( | 2954 FunctionState function_state(&function_state_, &scope_, |
2947 &function_state_, &scope_, formal_parameters.scope, | 2955 formal_parameters.scope, arrow_kind, |
2948 is_async ? kAsyncArrowFunction : kArrowFunction, &function_factory); | 2956 &function_factory); |
2949 | 2957 |
2950 function_state.SkipMaterializedLiterals( | 2958 function_state.SkipMaterializedLiterals( |
2951 formal_parameters.materialized_literals_count); | 2959 formal_parameters.materialized_literals_count); |
2952 | 2960 |
2953 this->ReindexLiterals(formal_parameters); | 2961 this->ReindexLiterals(formal_parameters); |
2954 | 2962 |
2955 Expect(Token::ARROW, CHECK_OK); | 2963 Expect(Token::ARROW, CHECK_OK); |
2956 | 2964 |
2957 if (peek() == Token::LBRACE) { | 2965 if (peek() == Token::LBRACE) { |
2958 // Multiple statement body | 2966 // Multiple statement body |
2959 Consume(Token::LBRACE); | 2967 Consume(Token::LBRACE); |
2960 bool is_lazily_parsed = | 2968 bool is_lazily_parsed = |
2961 (mode() == PARSE_LAZILY && scope_->AllowsLazyParsing()); | 2969 (mode() == PARSE_LAZILY && scope_->AllowsLazyParsing()); |
2962 if (is_lazily_parsed) { | 2970 if (is_lazily_parsed) { |
2963 body = this->NewStatementList(0, zone()); | 2971 body = this->NewStatementList(0, zone()); |
2964 this->SkipLazyFunctionBody(&materialized_literal_count, | 2972 this->SkipLazyFunctionBody(&materialized_literal_count, |
2965 &expected_property_count, CHECK_OK); | 2973 &expected_property_count, CHECK_OK); |
2966 if (formal_parameters.materialized_literals_count > 0) { | 2974 if (formal_parameters.materialized_literals_count > 0) { |
2967 materialized_literal_count += | 2975 materialized_literal_count += |
2968 formal_parameters.materialized_literals_count; | 2976 formal_parameters.materialized_literals_count; |
2969 } | 2977 } |
2970 } else { | 2978 } else { |
2971 body = this->ParseEagerFunctionBody( | 2979 body = this->ParseEagerFunctionBody( |
2972 this->EmptyIdentifier(), RelocInfo::kNoPosition, formal_parameters, | 2980 this->EmptyIdentifier(), RelocInfo::kNoPosition, formal_parameters, |
2973 kArrowFunction, FunctionLiteral::kAnonymousExpression, CHECK_OK); | 2981 arrow_kind, FunctionLiteral::kAnonymousExpression, CHECK_OK); |
2974 materialized_literal_count = | 2982 materialized_literal_count = |
2975 function_state.materialized_literal_count(); | 2983 function_state.materialized_literal_count(); |
2976 expected_property_count = function_state.expected_property_count(); | 2984 expected_property_count = function_state.expected_property_count(); |
2977 } | 2985 } |
2978 } else { | 2986 } else { |
2979 // Single-expression body | 2987 // Single-expression body |
2980 int pos = position(); | 2988 int pos = position(); |
2981 parenthesized_function_ = false; | 2989 parenthesized_function_ = false; |
2982 ExpressionClassifier classifier(this); | 2990 ExpressionClassifier classifier(this); |
2983 ExpressionT expression = | |
2984 ParseAssignmentExpression(accept_IN, &classifier, CHECK_OK); | |
2985 Traits::RewriteNonPattern(&classifier, CHECK_OK); | |
2986 body = this->NewStatementList(1, zone()); | 2991 body = this->NewStatementList(1, zone()); |
2987 this->AddParameterInitializationBlock(formal_parameters, body, CHECK_OK); | 2992 this->AddParameterInitializationBlock(formal_parameters, body, is_async, |
2988 body->Add(factory()->NewReturnStatement(expression, pos), zone()); | 2993 CHECK_OK); |
| 2994 if (is_async) { |
| 2995 this->ParseAsyncArrowSingleExpressionBody(body, accept_IN, &classifier, |
| 2996 pos, CHECK_OK); |
| 2997 } else { |
| 2998 ExpressionT expression = |
| 2999 ParseAssignmentExpression(accept_IN, &classifier, CHECK_OK); |
| 3000 Traits::RewriteNonPattern(&classifier, CHECK_OK); |
| 3001 body->Add(factory()->NewReturnStatement(expression, pos), zone()); |
| 3002 } |
2989 materialized_literal_count = function_state.materialized_literal_count(); | 3003 materialized_literal_count = function_state.materialized_literal_count(); |
2990 expected_property_count = function_state.expected_property_count(); | 3004 expected_property_count = function_state.expected_property_count(); |
2991 } | 3005 } |
2992 super_loc = function_state.super_location(); | 3006 super_loc = function_state.super_location(); |
2993 | 3007 |
2994 formal_parameters.scope->set_end_position(scanner()->location().end_pos); | 3008 formal_parameters.scope->set_end_position(scanner()->location().end_pos); |
2995 | 3009 |
2996 // Arrow function formal parameters are parsed as StrictFormalParameterList, | 3010 // Arrow function formal parameters are parsed as StrictFormalParameterList, |
2997 // which is not the same as "parameters of a strict function"; it only means | 3011 // which is not the same as "parameters of a strict function"; it only means |
2998 // that duplicates are not allowed. Of course, the arrow function may | 3012 // that duplicates are not allowed. Of course, the arrow function may |
(...skipping 10 matching lines...) Expand all Loading... |
3009 this->CheckConflictingVarDeclarations(formal_parameters.scope, CHECK_OK); | 3023 this->CheckConflictingVarDeclarations(formal_parameters.scope, CHECK_OK); |
3010 | 3024 |
3011 Traits::RewriteDestructuringAssignments(); | 3025 Traits::RewriteDestructuringAssignments(); |
3012 } | 3026 } |
3013 | 3027 |
3014 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( | 3028 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( |
3015 this->EmptyIdentifierString(), formal_parameters.scope, body, | 3029 this->EmptyIdentifierString(), formal_parameters.scope, body, |
3016 materialized_literal_count, expected_property_count, num_parameters, | 3030 materialized_literal_count, expected_property_count, num_parameters, |
3017 FunctionLiteral::kNoDuplicateParameters, | 3031 FunctionLiteral::kNoDuplicateParameters, |
3018 FunctionLiteral::kAnonymousExpression, | 3032 FunctionLiteral::kAnonymousExpression, |
3019 FunctionLiteral::kShouldLazyCompile, FunctionKind::kArrowFunction, | 3033 FunctionLiteral::kShouldLazyCompile, arrow_kind, |
3020 formal_parameters.scope->start_position()); | 3034 formal_parameters.scope->start_position()); |
3021 | 3035 |
3022 function_literal->set_function_token_position( | 3036 function_literal->set_function_token_position( |
3023 formal_parameters.scope->start_position()); | 3037 formal_parameters.scope->start_position()); |
3024 if (super_loc.IsValid()) function_state_->set_super_location(super_loc); | 3038 if (super_loc.IsValid()) function_state_->set_super_location(super_loc); |
3025 | 3039 |
3026 if (fni_ != NULL) this->InferFunctionName(fni_, function_literal); | 3040 if (fni_ != NULL) this->InferFunctionName(fni_, function_literal); |
3027 | 3041 |
3028 return function_literal; | 3042 return function_literal; |
3029 } | 3043 } |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3237 has_seen_constructor_ = true; | 3251 has_seen_constructor_ = true; |
3238 return; | 3252 return; |
3239 } | 3253 } |
3240 } | 3254 } |
3241 | 3255 |
3242 | 3256 |
3243 } // namespace internal | 3257 } // namespace internal |
3244 } // namespace v8 | 3258 } // namespace v8 |
3245 | 3259 |
3246 #endif // V8_PARSING_PARSER_BASE_H | 3260 #endif // V8_PARSING_PARSER_BASE_H |
OLD | NEW |