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 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
262 | 268 |
263 bool is_generator() const { return IsGeneratorFunction(kind_); } | 269 bool is_generator() const { return IsGeneratorFunction(kind_); } |
264 bool is_async_function() const { return IsAsyncFunction(kind_); } | 270 bool is_async_function() const { return IsAsyncFunction(kind_); } |
265 | 271 |
266 FunctionKind kind() const { return kind_; } | 272 FunctionKind kind() const { return kind_; } |
267 FunctionState* outer() const { return outer_function_state_; } | 273 FunctionState* outer() const { return outer_function_state_; } |
268 | 274 |
269 void set_generator_object_variable( | 275 void set_generator_object_variable( |
270 typename Traits::Type::GeneratorVariable* variable) { | 276 typename Traits::Type::GeneratorVariable* variable) { |
271 DCHECK(variable != NULL); | 277 DCHECK(variable != NULL); |
272 DCHECK(is_generator()); | 278 DCHECK(is_generator() || is_async_function()); |
273 generator_object_variable_ = variable; | 279 generator_object_variable_ = variable; |
274 } | 280 } |
275 typename Traits::Type::GeneratorVariable* generator_object_variable() | 281 typename Traits::Type::GeneratorVariable* generator_object_variable() |
276 const { | 282 const { |
277 return generator_object_variable_; | 283 return generator_object_variable_; |
278 } | 284 } |
279 | 285 |
280 typename Traits::Type::Factory* factory() { return factory_; } | 286 typename Traits::Type::Factory* factory() { return factory_; } |
281 | 287 |
282 const List<DestructuringAssignment>& destructuring_assignments_to_rewrite() | 288 const List<DestructuringAssignment>& destructuring_assignments_to_rewrite() |
(...skipping 1789 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2072 name, position(), scanner()->location().end_pos, scope_, factory()); | 2078 name, position(), scanner()->location().end_pos, scope_, factory()); |
2073 } | 2079 } |
2074 | 2080 |
2075 if (peek() == Token::ARROW) { | 2081 if (peek() == Token::ARROW) { |
2076 classifier->RecordPatternError(scanner()->peek_location(), | 2082 classifier->RecordPatternError(scanner()->peek_location(), |
2077 MessageTemplate::kUnexpectedToken, | 2083 MessageTemplate::kUnexpectedToken, |
2078 Token::String(Token::ARROW)); | 2084 Token::String(Token::ARROW)); |
2079 ValidateArrowFormalParameters(&arrow_formals_classifier, expression, | 2085 ValidateArrowFormalParameters(&arrow_formals_classifier, expression, |
2080 parenthesized_formals, is_async, CHECK_OK); | 2086 parenthesized_formals, is_async, CHECK_OK); |
2081 Scanner::Location loc(lhs_beg_pos, scanner()->location().end_pos); | 2087 Scanner::Location loc(lhs_beg_pos, scanner()->location().end_pos); |
2082 Scope* scope = | 2088 Scope* scope = this->NewScope(scope_, FUNCTION_SCOPE, |
2083 this->NewScope(scope_, FUNCTION_SCOPE, FunctionKind::kArrowFunction); | 2089 is_async ? FunctionKind::kAsyncArrowFunction |
| 2090 : FunctionKind::kArrowFunction); |
2084 // Because the arrow's parameters were parsed in the outer scope, any | 2091 // Because the arrow's parameters were parsed in the outer scope, any |
2085 // usage flags that might have been triggered there need to be copied | 2092 // usage flags that might have been triggered there need to be copied |
2086 // to the arrow scope. | 2093 // to the arrow scope. |
2087 scope_->PropagateUsageFlagsToScope(scope); | 2094 scope_->PropagateUsageFlagsToScope(scope); |
2088 FormalParametersT parameters(scope); | 2095 FormalParametersT parameters(scope); |
2089 if (!arrow_formals_classifier.is_simple_parameter_list()) { | 2096 if (!arrow_formals_classifier.is_simple_parameter_list()) { |
2090 scope->SetHasNonSimpleParameters(); | 2097 scope->SetHasNonSimpleParameters(); |
2091 parameters.is_simple = false; | 2098 parameters.is_simple = false; |
2092 } | 2099 } |
2093 | 2100 |
(...skipping 907 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3001 *ok = false; | 3008 *ok = false; |
3002 return this->EmptyExpression(); | 3009 return this->EmptyExpression(); |
3003 } | 3010 } |
3004 | 3011 |
3005 typename Traits::Type::StatementList body; | 3012 typename Traits::Type::StatementList body; |
3006 int num_parameters = formal_parameters.scope->num_parameters(); | 3013 int num_parameters = formal_parameters.scope->num_parameters(); |
3007 int materialized_literal_count = -1; | 3014 int materialized_literal_count = -1; |
3008 int expected_property_count = -1; | 3015 int expected_property_count = -1; |
3009 Scanner::Location super_loc; | 3016 Scanner::Location super_loc; |
3010 | 3017 |
| 3018 FunctionKind arrow_kind = is_async ? kAsyncArrowFunction : kArrowFunction; |
3011 { | 3019 { |
3012 typename Traits::Type::Factory function_factory(ast_value_factory()); | 3020 typename Traits::Type::Factory function_factory(ast_value_factory()); |
3013 FunctionState function_state( | 3021 FunctionState function_state(&function_state_, &scope_, |
3014 &function_state_, &scope_, formal_parameters.scope, | 3022 formal_parameters.scope, arrow_kind, |
3015 is_async ? kAsyncArrowFunction : kArrowFunction, &function_factory); | 3023 &function_factory); |
3016 | 3024 |
3017 function_state.SkipMaterializedLiterals( | 3025 function_state.SkipMaterializedLiterals( |
3018 formal_parameters.materialized_literals_count); | 3026 formal_parameters.materialized_literals_count); |
3019 | 3027 |
3020 this->ReindexLiterals(formal_parameters); | 3028 this->ReindexLiterals(formal_parameters); |
3021 | 3029 |
3022 Expect(Token::ARROW, CHECK_OK); | 3030 Expect(Token::ARROW, CHECK_OK); |
3023 | 3031 |
3024 if (peek() == Token::LBRACE) { | 3032 if (peek() == Token::LBRACE) { |
3025 // Multiple statement body | 3033 // Multiple statement body |
3026 Consume(Token::LBRACE); | 3034 Consume(Token::LBRACE); |
3027 bool is_lazily_parsed = | 3035 bool is_lazily_parsed = |
3028 (mode() == PARSE_LAZILY && scope_->AllowsLazyParsing()); | 3036 (mode() == PARSE_LAZILY && scope_->AllowsLazyParsing()); |
3029 if (is_lazily_parsed) { | 3037 if (is_lazily_parsed) { |
3030 body = this->NewStatementList(0, zone()); | 3038 body = this->NewStatementList(0, zone()); |
3031 this->SkipLazyFunctionBody(&materialized_literal_count, | 3039 this->SkipLazyFunctionBody(&materialized_literal_count, |
3032 &expected_property_count, CHECK_OK); | 3040 &expected_property_count, CHECK_OK); |
3033 if (formal_parameters.materialized_literals_count > 0) { | 3041 if (formal_parameters.materialized_literals_count > 0) { |
3034 materialized_literal_count += | 3042 materialized_literal_count += |
3035 formal_parameters.materialized_literals_count; | 3043 formal_parameters.materialized_literals_count; |
3036 } | 3044 } |
3037 } else { | 3045 } else { |
3038 body = this->ParseEagerFunctionBody( | 3046 body = this->ParseEagerFunctionBody( |
3039 this->EmptyIdentifier(), RelocInfo::kNoPosition, formal_parameters, | 3047 this->EmptyIdentifier(), RelocInfo::kNoPosition, formal_parameters, |
3040 kArrowFunction, FunctionLiteral::kAnonymousExpression, CHECK_OK); | 3048 arrow_kind, FunctionLiteral::kAnonymousExpression, CHECK_OK); |
3041 materialized_literal_count = | 3049 materialized_literal_count = |
3042 function_state.materialized_literal_count(); | 3050 function_state.materialized_literal_count(); |
3043 expected_property_count = function_state.expected_property_count(); | 3051 expected_property_count = function_state.expected_property_count(); |
3044 } | 3052 } |
3045 } else { | 3053 } else { |
3046 // Single-expression body | 3054 // Single-expression body |
3047 int pos = position(); | 3055 int pos = position(); |
3048 ExpressionClassifier classifier(this); | 3056 ExpressionClassifier classifier(this); |
3049 bool is_tail_call_expression; | 3057 bool is_tail_call_expression; |
3050 if (FLAG_harmony_explicit_tailcalls) { | 3058 if (FLAG_harmony_explicit_tailcalls) { |
3051 // TODO(ishell): update chapter number. | 3059 // TODO(ishell): update chapter number. |
3052 // ES8 XX.YY.ZZ | 3060 // ES8 XX.YY.ZZ |
3053 if (peek() == Token::CONTINUE) { | 3061 if (peek() == Token::CONTINUE) { |
3054 Consume(Token::CONTINUE); | 3062 Consume(Token::CONTINUE); |
3055 pos = position(); | 3063 pos = position(); |
3056 is_tail_call_expression = true; | 3064 is_tail_call_expression = true; |
3057 } else { | 3065 } else { |
3058 is_tail_call_expression = false; | 3066 is_tail_call_expression = false; |
3059 } | 3067 } |
3060 } else { | 3068 } else { |
3061 // ES6 14.6.1 Static Semantics: IsInTailPosition | 3069 // ES6 14.6.1 Static Semantics: IsInTailPosition |
3062 is_tail_call_expression = | 3070 is_tail_call_expression = |
3063 allow_tailcalls() && !is_sloppy(language_mode()); | 3071 allow_tailcalls() && !is_sloppy(language_mode()); |
3064 } | 3072 } |
3065 ExpressionT expression = | |
3066 ParseAssignmentExpression(accept_IN, &classifier, CHECK_OK); | |
3067 Traits::RewriteNonPattern(&classifier, CHECK_OK); | |
3068 body = this->NewStatementList(1, zone()); | 3073 body = this->NewStatementList(1, zone()); |
3069 this->AddParameterInitializationBlock(formal_parameters, body, CHECK_OK); | 3074 this->AddParameterInitializationBlock(formal_parameters, body, is_async, |
3070 body->Add(factory()->NewReturnStatement(expression, pos), zone()); | 3075 CHECK_OK); |
| 3076 if (is_async) { |
| 3077 this->ParseAsyncArrowSingleExpressionBody(body, accept_IN, &classifier, |
| 3078 pos, CHECK_OK); |
| 3079 } else { |
| 3080 ExpressionT expression = |
| 3081 ParseAssignmentExpression(accept_IN, &classifier, CHECK_OK); |
| 3082 Traits::RewriteNonPattern(&classifier, CHECK_OK); |
| 3083 body->Add(factory()->NewReturnStatement(expression, pos), zone()); |
| 3084 if (is_tail_call_expression) { |
| 3085 this->MarkTailPosition(expression); |
| 3086 } |
| 3087 } |
3071 materialized_literal_count = function_state.materialized_literal_count(); | 3088 materialized_literal_count = function_state.materialized_literal_count(); |
3072 expected_property_count = function_state.expected_property_count(); | 3089 expected_property_count = function_state.expected_property_count(); |
3073 if (is_tail_call_expression) { | |
3074 this->MarkTailPosition(expression); | |
3075 } | |
3076 } | 3090 } |
3077 super_loc = function_state.super_location(); | 3091 super_loc = function_state.super_location(); |
3078 | 3092 |
3079 formal_parameters.scope->set_end_position(scanner()->location().end_pos); | 3093 formal_parameters.scope->set_end_position(scanner()->location().end_pos); |
3080 | 3094 |
3081 // Arrow function formal parameters are parsed as StrictFormalParameterList, | 3095 // Arrow function formal parameters are parsed as StrictFormalParameterList, |
3082 // which is not the same as "parameters of a strict function"; it only means | 3096 // which is not the same as "parameters of a strict function"; it only means |
3083 // that duplicates are not allowed. Of course, the arrow function may | 3097 // that duplicates are not allowed. Of course, the arrow function may |
3084 // itself be strict as well. | 3098 // itself be strict as well. |
3085 const bool allow_duplicate_parameters = false; | 3099 const bool allow_duplicate_parameters = false; |
3086 this->ValidateFormalParameters(&formals_classifier, language_mode(), | 3100 this->ValidateFormalParameters(&formals_classifier, language_mode(), |
3087 allow_duplicate_parameters, CHECK_OK); | 3101 allow_duplicate_parameters, CHECK_OK); |
3088 | 3102 |
3089 // Validate strict mode. | 3103 // Validate strict mode. |
3090 if (is_strict(language_mode())) { | 3104 if (is_strict(language_mode())) { |
3091 CheckStrictOctalLiteral(formal_parameters.scope->start_position(), | 3105 CheckStrictOctalLiteral(formal_parameters.scope->start_position(), |
3092 scanner()->location().end_pos, CHECK_OK); | 3106 scanner()->location().end_pos, CHECK_OK); |
3093 } | 3107 } |
3094 this->CheckConflictingVarDeclarations(formal_parameters.scope, CHECK_OK); | 3108 this->CheckConflictingVarDeclarations(formal_parameters.scope, CHECK_OK); |
3095 | 3109 |
3096 Traits::RewriteDestructuringAssignments(); | 3110 Traits::RewriteDestructuringAssignments(); |
3097 } | 3111 } |
3098 | 3112 |
3099 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( | 3113 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( |
3100 this->EmptyIdentifierString(), formal_parameters.scope, body, | 3114 this->EmptyIdentifierString(), formal_parameters.scope, body, |
3101 materialized_literal_count, expected_property_count, num_parameters, | 3115 materialized_literal_count, expected_property_count, num_parameters, |
3102 FunctionLiteral::kNoDuplicateParameters, | 3116 FunctionLiteral::kNoDuplicateParameters, |
3103 FunctionLiteral::kAnonymousExpression, | 3117 FunctionLiteral::kAnonymousExpression, |
3104 FunctionLiteral::kShouldLazyCompile, FunctionKind::kArrowFunction, | 3118 FunctionLiteral::kShouldLazyCompile, arrow_kind, |
3105 formal_parameters.scope->start_position()); | 3119 formal_parameters.scope->start_position()); |
3106 | 3120 |
3107 function_literal->set_function_token_position( | 3121 function_literal->set_function_token_position( |
3108 formal_parameters.scope->start_position()); | 3122 formal_parameters.scope->start_position()); |
3109 if (super_loc.IsValid()) function_state_->set_super_location(super_loc); | 3123 if (super_loc.IsValid()) function_state_->set_super_location(super_loc); |
3110 | 3124 |
3111 if (fni_ != NULL) this->InferFunctionName(fni_, function_literal); | 3125 if (fni_ != NULL) this->InferFunctionName(fni_, function_literal); |
3112 | 3126 |
3113 return function_literal; | 3127 return function_literal; |
3114 } | 3128 } |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3322 has_seen_constructor_ = true; | 3336 has_seen_constructor_ = true; |
3323 return; | 3337 return; |
3324 } | 3338 } |
3325 } | 3339 } |
3326 | 3340 |
3327 | 3341 |
3328 } // namespace internal | 3342 } // namespace internal |
3329 } // namespace v8 | 3343 } // namespace v8 |
3330 | 3344 |
3331 #endif // V8_PARSING_PARSER_BASE_H | 3345 #endif // V8_PARSING_PARSER_BASE_H |
OLD | NEW |