| 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 |