| 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 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 301 | 307 |
| 302 bool is_generator() const { return IsGeneratorFunction(kind_); } | 308 bool is_generator() const { return IsGeneratorFunction(kind_); } |
| 303 bool is_async_function() const { return IsAsyncFunction(kind_); } | 309 bool is_async_function() const { return IsAsyncFunction(kind_); } |
| 304 | 310 |
| 305 FunctionKind kind() const { return kind_; } | 311 FunctionKind kind() const { return kind_; } |
| 306 FunctionState* outer() const { return outer_function_state_; } | 312 FunctionState* outer() const { return outer_function_state_; } |
| 307 | 313 |
| 308 void set_generator_object_variable( | 314 void set_generator_object_variable( |
| 309 typename Traits::Type::GeneratorVariable* variable) { | 315 typename Traits::Type::GeneratorVariable* variable) { |
| 310 DCHECK(variable != NULL); | 316 DCHECK(variable != NULL); |
| 311 DCHECK(is_generator()); | 317 DCHECK(is_generator() || is_async_function()); |
| 312 generator_object_variable_ = variable; | 318 generator_object_variable_ = variable; |
| 313 } | 319 } |
| 314 typename Traits::Type::GeneratorVariable* generator_object_variable() | 320 typename Traits::Type::GeneratorVariable* generator_object_variable() |
| 315 const { | 321 const { |
| 316 return generator_object_variable_; | 322 return generator_object_variable_; |
| 317 } | 323 } |
| 318 | 324 |
| 319 typename Traits::Type::Factory* factory() { return factory_; } | 325 typename Traits::Type::Factory* factory() { return factory_; } |
| 320 | 326 |
| 321 const List<DestructuringAssignment>& destructuring_assignments_to_rewrite() | 327 const List<DestructuringAssignment>& destructuring_assignments_to_rewrite() |
| (...skipping 1827 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2149 parenthesized_formals, is_async, CHECK_OK); | 2155 parenthesized_formals, is_async, CHECK_OK); |
| 2150 // This reads strangely, but is correct: it checks whether any | 2156 // This reads strangely, but is correct: it checks whether any |
| 2151 // sub-expression of the parameter list failed to be a valid formal | 2157 // sub-expression of the parameter list failed to be a valid formal |
| 2152 // parameter initializer. Since YieldExpressions are banned anywhere | 2158 // parameter initializer. Since YieldExpressions are banned anywhere |
| 2153 // in an arrow parameter list, this is correct. | 2159 // in an arrow parameter list, this is correct. |
| 2154 // TODO(adamk): Rename "FormalParameterInitializerError" to refer to | 2160 // TODO(adamk): Rename "FormalParameterInitializerError" to refer to |
| 2155 // "YieldExpression", which is its only use. | 2161 // "YieldExpression", which is its only use. |
| 2156 ValidateFormalParameterInitializer(&arrow_formals_classifier, ok); | 2162 ValidateFormalParameterInitializer(&arrow_formals_classifier, ok); |
| 2157 | 2163 |
| 2158 Scanner::Location loc(lhs_beg_pos, scanner()->location().end_pos); | 2164 Scanner::Location loc(lhs_beg_pos, scanner()->location().end_pos); |
| 2159 Scope* scope = | 2165 Scope* scope = this->NewScope(scope_, FUNCTION_SCOPE, |
| 2160 this->NewScope(scope_, FUNCTION_SCOPE, FunctionKind::kArrowFunction); | 2166 is_async ? FunctionKind::kAsyncArrowFunction |
| 2167 : FunctionKind::kArrowFunction); |
| 2161 // Because the arrow's parameters were parsed in the outer scope, any | 2168 // Because the arrow's parameters were parsed in the outer scope, any |
| 2162 // usage flags that might have been triggered there need to be copied | 2169 // usage flags that might have been triggered there need to be copied |
| 2163 // to the arrow scope. | 2170 // to the arrow scope. |
| 2164 scope_->PropagateUsageFlagsToScope(scope); | 2171 scope_->PropagateUsageFlagsToScope(scope); |
| 2165 FormalParametersT parameters(scope); | 2172 FormalParametersT parameters(scope); |
| 2166 if (!arrow_formals_classifier.is_simple_parameter_list()) { | 2173 if (!arrow_formals_classifier.is_simple_parameter_list()) { |
| 2167 scope->SetHasNonSimpleParameters(); | 2174 scope->SetHasNonSimpleParameters(); |
| 2168 parameters.is_simple = false; | 2175 parameters.is_simple = false; |
| 2169 } | 2176 } |
| 2170 | 2177 |
| (...skipping 1004 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3175 *ok = false; | 3182 *ok = false; |
| 3176 return this->EmptyExpression(); | 3183 return this->EmptyExpression(); |
| 3177 } | 3184 } |
| 3178 | 3185 |
| 3179 typename Traits::Type::StatementList body; | 3186 typename Traits::Type::StatementList body; |
| 3180 int num_parameters = formal_parameters.scope->num_parameters(); | 3187 int num_parameters = formal_parameters.scope->num_parameters(); |
| 3181 int materialized_literal_count = -1; | 3188 int materialized_literal_count = -1; |
| 3182 int expected_property_count = -1; | 3189 int expected_property_count = -1; |
| 3183 Scanner::Location super_loc; | 3190 Scanner::Location super_loc; |
| 3184 | 3191 |
| 3192 FunctionKind arrow_kind = is_async ? kAsyncArrowFunction : kArrowFunction; |
| 3185 { | 3193 { |
| 3186 typename Traits::Type::Factory function_factory(ast_value_factory()); | 3194 typename Traits::Type::Factory function_factory(ast_value_factory()); |
| 3187 FunctionState function_state( | 3195 FunctionState function_state(&function_state_, &scope_, |
| 3188 &function_state_, &scope_, formal_parameters.scope, | 3196 formal_parameters.scope, arrow_kind, |
| 3189 is_async ? kAsyncArrowFunction : kArrowFunction, &function_factory); | 3197 &function_factory); |
| 3190 | 3198 |
| 3191 function_state.SkipMaterializedLiterals( | 3199 function_state.SkipMaterializedLiterals( |
| 3192 formal_parameters.materialized_literals_count); | 3200 formal_parameters.materialized_literals_count); |
| 3193 | 3201 |
| 3194 this->ReindexLiterals(formal_parameters); | 3202 this->ReindexLiterals(formal_parameters); |
| 3195 | 3203 |
| 3196 Expect(Token::ARROW, CHECK_OK); | 3204 Expect(Token::ARROW, CHECK_OK); |
| 3197 | 3205 |
| 3198 if (peek() == Token::LBRACE) { | 3206 if (peek() == Token::LBRACE) { |
| 3199 // Multiple statement body | 3207 // Multiple statement body |
| 3200 Consume(Token::LBRACE); | 3208 Consume(Token::LBRACE); |
| 3201 bool is_lazily_parsed = | 3209 bool is_lazily_parsed = |
| 3202 (mode() == PARSE_LAZILY && scope_->AllowsLazyParsing()); | 3210 (mode() == PARSE_LAZILY && scope_->AllowsLazyParsing()); |
| 3203 if (is_lazily_parsed) { | 3211 if (is_lazily_parsed) { |
| 3204 body = this->NewStatementList(0, zone()); | 3212 body = this->NewStatementList(0, zone()); |
| 3205 this->SkipLazyFunctionBody(&materialized_literal_count, | 3213 this->SkipLazyFunctionBody(&materialized_literal_count, |
| 3206 &expected_property_count, CHECK_OK); | 3214 &expected_property_count, CHECK_OK); |
| 3207 if (formal_parameters.materialized_literals_count > 0) { | 3215 if (formal_parameters.materialized_literals_count > 0) { |
| 3208 materialized_literal_count += | 3216 materialized_literal_count += |
| 3209 formal_parameters.materialized_literals_count; | 3217 formal_parameters.materialized_literals_count; |
| 3210 } | 3218 } |
| 3211 } else { | 3219 } else { |
| 3212 body = this->ParseEagerFunctionBody( | 3220 body = this->ParseEagerFunctionBody( |
| 3213 this->EmptyIdentifier(), RelocInfo::kNoPosition, formal_parameters, | 3221 this->EmptyIdentifier(), RelocInfo::kNoPosition, formal_parameters, |
| 3214 kArrowFunction, FunctionLiteral::kAnonymousExpression, CHECK_OK); | 3222 arrow_kind, FunctionLiteral::kAnonymousExpression, CHECK_OK); |
| 3215 materialized_literal_count = | 3223 materialized_literal_count = |
| 3216 function_state.materialized_literal_count(); | 3224 function_state.materialized_literal_count(); |
| 3217 expected_property_count = function_state.expected_property_count(); | 3225 expected_property_count = function_state.expected_property_count(); |
| 3218 } | 3226 } |
| 3219 } else { | 3227 } else { |
| 3220 // Single-expression body | 3228 // Single-expression body |
| 3221 int pos = position(); | 3229 int pos = position(); |
| 3222 ExpressionClassifier classifier(this); | 3230 ExpressionClassifier classifier(this); |
| 3223 DCHECK(ReturnExprContext::kInsideValidBlock == | 3231 DCHECK(ReturnExprContext::kInsideValidBlock == |
| 3224 function_state_->return_expr_context()); | 3232 function_state_->return_expr_context()); |
| 3225 ReturnExprScope allow_tail_calls( | 3233 ReturnExprScope allow_tail_calls( |
| 3226 function_state_, ReturnExprContext::kInsideValidReturnStatement); | 3234 function_state_, ReturnExprContext::kInsideValidReturnStatement); |
| 3227 ExpressionT expression = | |
| 3228 ParseAssignmentExpression(accept_IN, &classifier, CHECK_OK); | |
| 3229 Traits::RewriteNonPattern(&classifier, CHECK_OK); | |
| 3230 body = this->NewStatementList(1, zone()); | 3235 body = this->NewStatementList(1, zone()); |
| 3231 this->AddParameterInitializationBlock(formal_parameters, body, CHECK_OK); | 3236 this->AddParameterInitializationBlock(formal_parameters, body, is_async, |
| 3232 body->Add(factory()->NewReturnStatement(expression, pos), zone()); | 3237 CHECK_OK); |
| 3238 if (is_async) { |
| 3239 this->ParseAsyncArrowSingleExpressionBody(body, accept_IN, &classifier, |
| 3240 pos, CHECK_OK); |
| 3241 Traits::RewriteNonPattern(&classifier, CHECK_OK); |
| 3242 } else { |
| 3243 ExpressionT expression = |
| 3244 ParseAssignmentExpression(accept_IN, &classifier, CHECK_OK); |
| 3245 Traits::RewriteNonPattern(&classifier, CHECK_OK); |
| 3246 body->Add(factory()->NewReturnStatement(expression, pos), zone()); |
| 3247 if (allow_tailcalls() && !is_sloppy(language_mode())) { |
| 3248 // ES6 14.6.1 Static Semantics: IsInTailPosition |
| 3249 this->MarkTailPosition(expression); |
| 3250 } |
| 3251 } |
| 3233 materialized_literal_count = function_state.materialized_literal_count(); | 3252 materialized_literal_count = function_state.materialized_literal_count(); |
| 3234 expected_property_count = function_state.expected_property_count(); | 3253 expected_property_count = function_state.expected_property_count(); |
| 3235 if (allow_tailcalls() && !is_sloppy(language_mode())) { | |
| 3236 // ES6 14.6.1 Static Semantics: IsInTailPosition | |
| 3237 this->MarkTailPosition(expression); | |
| 3238 } | |
| 3239 this->MarkCollectedTailCallExpressions(); | 3254 this->MarkCollectedTailCallExpressions(); |
| 3240 } | 3255 } |
| 3241 super_loc = function_state.super_location(); | 3256 super_loc = function_state.super_location(); |
| 3242 | 3257 |
| 3243 formal_parameters.scope->set_end_position(scanner()->location().end_pos); | 3258 formal_parameters.scope->set_end_position(scanner()->location().end_pos); |
| 3244 | 3259 |
| 3245 // Arrow function formal parameters are parsed as StrictFormalParameterList, | 3260 // Arrow function formal parameters are parsed as StrictFormalParameterList, |
| 3246 // which is not the same as "parameters of a strict function"; it only means | 3261 // which is not the same as "parameters of a strict function"; it only means |
| 3247 // that duplicates are not allowed. Of course, the arrow function may | 3262 // that duplicates are not allowed. Of course, the arrow function may |
| 3248 // itself be strict as well. | 3263 // itself be strict as well. |
| 3249 const bool allow_duplicate_parameters = false; | 3264 const bool allow_duplicate_parameters = false; |
| 3250 this->ValidateFormalParameters(&formals_classifier, language_mode(), | 3265 this->ValidateFormalParameters(&formals_classifier, language_mode(), |
| 3251 allow_duplicate_parameters, CHECK_OK); | 3266 allow_duplicate_parameters, CHECK_OK); |
| 3252 | 3267 |
| 3253 // Validate strict mode. | 3268 // Validate strict mode. |
| 3254 if (is_strict(language_mode())) { | 3269 if (is_strict(language_mode())) { |
| 3255 CheckStrictOctalLiteral(formal_parameters.scope->start_position(), | 3270 CheckStrictOctalLiteral(formal_parameters.scope->start_position(), |
| 3256 scanner()->location().end_pos, CHECK_OK); | 3271 scanner()->location().end_pos, CHECK_OK); |
| 3257 } | 3272 } |
| 3258 this->CheckConflictingVarDeclarations(formal_parameters.scope, CHECK_OK); | 3273 this->CheckConflictingVarDeclarations(formal_parameters.scope, CHECK_OK); |
| 3259 | 3274 |
| 3260 Traits::RewriteDestructuringAssignments(); | 3275 Traits::RewriteDestructuringAssignments(); |
| 3261 } | 3276 } |
| 3262 | 3277 |
| 3263 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( | 3278 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( |
| 3264 this->EmptyIdentifierString(), formal_parameters.scope, body, | 3279 this->EmptyIdentifierString(), formal_parameters.scope, body, |
| 3265 materialized_literal_count, expected_property_count, num_parameters, | 3280 materialized_literal_count, expected_property_count, num_parameters, |
| 3266 FunctionLiteral::kNoDuplicateParameters, | 3281 FunctionLiteral::kNoDuplicateParameters, |
| 3267 FunctionLiteral::kAnonymousExpression, | 3282 FunctionLiteral::kAnonymousExpression, |
| 3268 FunctionLiteral::kShouldLazyCompile, FunctionKind::kArrowFunction, | 3283 FunctionLiteral::kShouldLazyCompile, arrow_kind, |
| 3269 formal_parameters.scope->start_position()); | 3284 formal_parameters.scope->start_position()); |
| 3270 | 3285 |
| 3271 function_literal->set_function_token_position( | 3286 function_literal->set_function_token_position( |
| 3272 formal_parameters.scope->start_position()); | 3287 formal_parameters.scope->start_position()); |
| 3273 if (super_loc.IsValid()) function_state_->set_super_location(super_loc); | 3288 if (super_loc.IsValid()) function_state_->set_super_location(super_loc); |
| 3274 | 3289 |
| 3275 if (fni_ != NULL) this->InferFunctionName(fni_, function_literal); | 3290 if (fni_ != NULL) this->InferFunctionName(fni_, function_literal); |
| 3276 | 3291 |
| 3277 return function_literal; | 3292 return function_literal; |
| 3278 } | 3293 } |
| (...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3487 has_seen_constructor_ = true; | 3502 has_seen_constructor_ = true; |
| 3488 return; | 3503 return; |
| 3489 } | 3504 } |
| 3490 } | 3505 } |
| 3491 | 3506 |
| 3492 | 3507 |
| 3493 } // namespace internal | 3508 } // namespace internal |
| 3494 } // namespace v8 | 3509 } // namespace v8 |
| 3495 | 3510 |
| 3496 #endif // V8_PARSING_PARSER_BASE_H | 3511 #endif // V8_PARSING_PARSER_BASE_H |
| OLD | NEW |