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, | |
neis
2016/05/11 09:45:16
I find that confusing.
| |
42 ArrowConcise, | |
43 }; | |
44 | |
45 enum class FunctionParsePhase { Unknown, FormalParameters, FunctionBody }; | |
46 | |
39 static inline ParseFunctionFlags operator|(ParseFunctionFlags lhs, | 47 static inline ParseFunctionFlags operator|(ParseFunctionFlags lhs, |
40 ParseFunctionFlags rhs) { | 48 ParseFunctionFlags rhs) { |
41 typedef unsigned char T; | 49 typedef unsigned char T; |
42 return static_cast<ParseFunctionFlags>(static_cast<T>(lhs) | | 50 return static_cast<ParseFunctionFlags>(static_cast<T>(lhs) | |
43 static_cast<T>(rhs)); | 51 static_cast<T>(rhs)); |
44 } | 52 } |
45 | 53 |
46 static inline ParseFunctionFlags& operator|=(ParseFunctionFlags& lhs, | 54 static inline ParseFunctionFlags& operator|=(ParseFunctionFlags& lhs, |
47 const ParseFunctionFlags& rhs) { | 55 const ParseFunctionFlags& rhs) { |
48 lhs = lhs | rhs; | 56 lhs = lhs | rhs; |
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
298 void set_return_location(Scanner::Location location) { | 306 void set_return_location(Scanner::Location location) { |
299 return_location_ = location; | 307 return_location_ = location; |
300 } | 308 } |
301 | 309 |
302 bool is_generator() const { return IsGeneratorFunction(kind_); } | 310 bool is_generator() const { return IsGeneratorFunction(kind_); } |
303 bool is_async_function() const { return IsAsyncFunction(kind_); } | 311 bool is_async_function() const { return IsAsyncFunction(kind_); } |
304 | 312 |
305 FunctionKind kind() const { return kind_; } | 313 FunctionKind kind() const { return kind_; } |
306 FunctionState* outer() const { return outer_function_state_; } | 314 FunctionState* outer() const { return outer_function_state_; } |
307 | 315 |
316 bool is_async_function_body() const { | |
317 return is_async_function() && | |
318 parse_phase() == FunctionParsePhase::FunctionBody; | |
319 } | |
320 | |
321 FunctionParsePhase parse_phase() const { return parse_phase_; } | |
322 | |
323 void set_parse_phase(FunctionParsePhase parse_phase) { | |
324 parse_phase_ = parse_phase; | |
325 } | |
326 | |
308 void set_generator_object_variable( | 327 void set_generator_object_variable( |
309 typename Traits::Type::GeneratorVariable* variable) { | 328 typename Traits::Type::GeneratorVariable* variable) { |
310 DCHECK(variable != NULL); | 329 DCHECK(variable != NULL); |
311 DCHECK(is_generator()); | 330 DCHECK(is_generator() || is_async_function()); |
neis
2016/05/11 09:45:16
Didn't you introduce a function for this?
| |
312 generator_object_variable_ = variable; | 331 generator_object_variable_ = variable; |
313 } | 332 } |
314 typename Traits::Type::GeneratorVariable* generator_object_variable() | 333 typename Traits::Type::GeneratorVariable* generator_object_variable() |
315 const { | 334 const { |
316 return generator_object_variable_; | 335 return generator_object_variable_; |
317 } | 336 } |
318 | 337 |
319 typename Traits::Type::Factory* factory() { return factory_; } | 338 typename Traits::Type::Factory* factory() { return factory_; } |
320 | 339 |
321 const List<DestructuringAssignment>& destructuring_assignments_to_rewrite() | 340 const List<DestructuringAssignment>& destructuring_assignments_to_rewrite() |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
404 typename Traits::Type::Factory* factory_; | 423 typename Traits::Type::Factory* factory_; |
405 | 424 |
406 // If true, the next (and immediately following) function literal is | 425 // If true, the next (and immediately following) function literal is |
407 // preceded by a parenthesis. | 426 // preceded by a parenthesis. |
408 bool next_function_is_parenthesized_; | 427 bool next_function_is_parenthesized_; |
409 | 428 |
410 // The value of the parents' next_function_is_parenthesized_, as it applies | 429 // The value of the parents' next_function_is_parenthesized_, as it applies |
411 // to this function. Filled in by constructor. | 430 // to this function. Filled in by constructor. |
412 bool this_function_is_parenthesized_; | 431 bool this_function_is_parenthesized_; |
413 | 432 |
433 FunctionParsePhase parse_phase_ = FunctionParsePhase::Unknown; | |
434 | |
414 friend class ParserTraits; | 435 friend class ParserTraits; |
415 friend class PreParserTraits; | 436 friend class PreParserTraits; |
416 friend class Checkpoint; | 437 friend class Checkpoint; |
417 }; | 438 }; |
418 | 439 |
419 // This scope sets current ReturnExprContext to given value. | 440 // This scope sets current ReturnExprContext to given value. |
420 class ReturnExprScope { | 441 class ReturnExprScope { |
421 public: | 442 public: |
422 explicit ReturnExprScope(FunctionState* function_state, | 443 explicit ReturnExprScope(FunctionState* function_state, |
423 ReturnExprContext return_expr_context) | 444 ReturnExprContext return_expr_context) |
(...skipping 1725 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2149 parenthesized_formals, is_async, CHECK_OK); | 2170 parenthesized_formals, is_async, CHECK_OK); |
2150 // This reads strangely, but is correct: it checks whether any | 2171 // This reads strangely, but is correct: it checks whether any |
2151 // sub-expression of the parameter list failed to be a valid formal | 2172 // sub-expression of the parameter list failed to be a valid formal |
2152 // parameter initializer. Since YieldExpressions are banned anywhere | 2173 // parameter initializer. Since YieldExpressions are banned anywhere |
2153 // in an arrow parameter list, this is correct. | 2174 // in an arrow parameter list, this is correct. |
2154 // TODO(adamk): Rename "FormalParameterInitializerError" to refer to | 2175 // TODO(adamk): Rename "FormalParameterInitializerError" to refer to |
2155 // "YieldExpression", which is its only use. | 2176 // "YieldExpression", which is its only use. |
2156 ValidateFormalParameterInitializer(&arrow_formals_classifier, ok); | 2177 ValidateFormalParameterInitializer(&arrow_formals_classifier, ok); |
2157 | 2178 |
2158 Scanner::Location loc(lhs_beg_pos, scanner()->location().end_pos); | 2179 Scanner::Location loc(lhs_beg_pos, scanner()->location().end_pos); |
2159 Scope* scope = | 2180 Scope* scope = this->NewScope(scope_, FUNCTION_SCOPE, |
2160 this->NewScope(scope_, FUNCTION_SCOPE, FunctionKind::kArrowFunction); | 2181 is_async ? FunctionKind::kAsyncArrowFunction |
2182 : FunctionKind::kArrowFunction); | |
2161 // Because the arrow's parameters were parsed in the outer scope, any | 2183 // 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 | 2184 // usage flags that might have been triggered there need to be copied |
2163 // to the arrow scope. | 2185 // to the arrow scope. |
2164 scope_->PropagateUsageFlagsToScope(scope); | 2186 scope_->PropagateUsageFlagsToScope(scope); |
2165 FormalParametersT parameters(scope); | 2187 FormalParametersT parameters(scope); |
2166 if (!arrow_formals_classifier.is_simple_parameter_list()) { | 2188 if (!arrow_formals_classifier.is_simple_parameter_list()) { |
2167 scope->SetHasNonSimpleParameters(); | 2189 scope->SetHasNonSimpleParameters(); |
2168 parameters.is_simple = false; | 2190 parameters.is_simple = false; |
2169 } | 2191 } |
2170 | 2192 |
(...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2574 | 2596 |
2575 return this->ExpressionFromIdentifier( | 2597 return this->ExpressionFromIdentifier( |
2576 name, beg_pos, scanner()->location().end_pos, scope_, factory()); | 2598 name, beg_pos, scanner()->location().end_pos, scope_, factory()); |
2577 } | 2599 } |
2578 default: | 2600 default: |
2579 break; | 2601 break; |
2580 } | 2602 } |
2581 Consume(Token::AWAIT); | 2603 Consume(Token::AWAIT); |
2582 | 2604 |
2583 ExpressionT value = ParseUnaryExpression(classifier, CHECK_OK); | 2605 ExpressionT value = ParseUnaryExpression(classifier, CHECK_OK); |
2584 classifier->RecordFormalParameterInitializerError( | 2606 if (!function_state_->is_async_function_body()) { |
2585 Scanner::Location(beg_pos, scanner()->location().end_pos), | 2607 // Not currently parsing function body --- must have occurred within |
2586 MessageTemplate::kAwaitExpressionFormalParameter); | 2608 // formal parameter parsing. |
2587 | 2609 ReportMessageAt(Scanner::Location(beg_pos, scanner()->location().end_pos), |
2610 MessageTemplate::kAwaitExpressionFormalParameter); | |
2611 *ok = false; | |
2612 return this->EmptyExpression(); | |
2613 } | |
2588 return Traits::RewriteAwaitExpression(value, beg_pos); | 2614 return Traits::RewriteAwaitExpression(value, beg_pos); |
2589 } else { | 2615 } else { |
2590 return this->ParsePostfixExpression(classifier, ok); | 2616 return this->ParsePostfixExpression(classifier, ok); |
2591 } | 2617 } |
2592 } | 2618 } |
2593 | 2619 |
2594 | 2620 |
2595 template <class Traits> | 2621 template <class Traits> |
2596 typename ParserBase<Traits>::ExpressionT | 2622 typename ParserBase<Traits>::ExpressionT |
2597 ParserBase<Traits>::ParsePostfixExpression(ExpressionClassifier* classifier, | 2623 ParserBase<Traits>::ParsePostfixExpression(ExpressionClassifier* classifier, |
(...skipping 577 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3175 *ok = false; | 3201 *ok = false; |
3176 return this->EmptyExpression(); | 3202 return this->EmptyExpression(); |
3177 } | 3203 } |
3178 | 3204 |
3179 typename Traits::Type::StatementList body; | 3205 typename Traits::Type::StatementList body; |
3180 int num_parameters = formal_parameters.scope->num_parameters(); | 3206 int num_parameters = formal_parameters.scope->num_parameters(); |
3181 int materialized_literal_count = -1; | 3207 int materialized_literal_count = -1; |
3182 int expected_property_count = -1; | 3208 int expected_property_count = -1; |
3183 Scanner::Location super_loc; | 3209 Scanner::Location super_loc; |
3184 | 3210 |
3211 FunctionKind arrow_kind = is_async ? kAsyncArrowFunction : kArrowFunction; | |
3185 { | 3212 { |
3186 typename Traits::Type::Factory function_factory(ast_value_factory()); | 3213 typename Traits::Type::Factory function_factory(ast_value_factory()); |
3187 FunctionState function_state( | 3214 FunctionState function_state(&function_state_, &scope_, |
3188 &function_state_, &scope_, formal_parameters.scope, | 3215 formal_parameters.scope, arrow_kind, |
3189 is_async ? kAsyncArrowFunction : kArrowFunction, &function_factory); | 3216 &function_factory); |
3190 | 3217 |
3191 function_state.SkipMaterializedLiterals( | 3218 function_state.SkipMaterializedLiterals( |
3192 formal_parameters.materialized_literals_count); | 3219 formal_parameters.materialized_literals_count); |
3193 | 3220 |
3194 this->ReindexLiterals(formal_parameters); | 3221 this->ReindexLiterals(formal_parameters); |
3195 | 3222 |
3196 Expect(Token::ARROW, CHECK_OK); | 3223 Expect(Token::ARROW, CHECK_OK); |
3224 function_state.set_parse_phase(FunctionParsePhase::FunctionBody); | |
3197 | 3225 |
3198 if (peek() == Token::LBRACE) { | 3226 if (peek() == Token::LBRACE) { |
3199 // Multiple statement body | 3227 // Multiple statement body |
3200 Consume(Token::LBRACE); | 3228 Consume(Token::LBRACE); |
3201 bool is_lazily_parsed = | 3229 bool is_lazily_parsed = |
3202 (mode() == PARSE_LAZILY && scope_->AllowsLazyParsing()); | 3230 (mode() == PARSE_LAZILY && scope_->AllowsLazyParsing()); |
3203 if (is_lazily_parsed) { | 3231 if (is_lazily_parsed) { |
3204 body = this->NewStatementList(0, zone()); | 3232 body = this->NewStatementList(0, zone()); |
3205 this->SkipLazyFunctionBody(&materialized_literal_count, | 3233 this->SkipLazyFunctionBody(&materialized_literal_count, |
3206 &expected_property_count, CHECK_OK); | 3234 &expected_property_count, CHECK_OK); |
3207 if (formal_parameters.materialized_literals_count > 0) { | 3235 if (formal_parameters.materialized_literals_count > 0) { |
3208 materialized_literal_count += | 3236 materialized_literal_count += |
3209 formal_parameters.materialized_literals_count; | 3237 formal_parameters.materialized_literals_count; |
3210 } | 3238 } |
3211 } else { | 3239 } else { |
3212 body = this->ParseEagerFunctionBody( | 3240 body = this->ParseEagerFunctionBody( |
3213 this->EmptyIdentifier(), RelocInfo::kNoPosition, formal_parameters, | 3241 this->EmptyIdentifier(), RelocInfo::kNoPosition, formal_parameters, |
3214 kArrowFunction, FunctionLiteral::kAnonymousExpression, CHECK_OK); | 3242 arrow_kind, FunctionLiteral::kAnonymousExpression, CHECK_OK); |
3215 materialized_literal_count = | 3243 materialized_literal_count = |
3216 function_state.materialized_literal_count(); | 3244 function_state.materialized_literal_count(); |
3217 expected_property_count = function_state.expected_property_count(); | 3245 expected_property_count = function_state.expected_property_count(); |
3218 } | 3246 } |
3219 } else { | 3247 } else { |
3220 // Single-expression body | 3248 // Single-expression body |
3221 int pos = position(); | 3249 int pos = position(); |
3222 ExpressionClassifier classifier(this); | 3250 ExpressionClassifier classifier(this); |
3223 DCHECK(ReturnExprContext::kInsideValidBlock == | 3251 DCHECK(ReturnExprContext::kInsideValidBlock == |
3224 function_state_->return_expr_context()); | 3252 function_state_->return_expr_context()); |
3225 ReturnExprScope allow_tail_calls( | 3253 ReturnExprScope allow_tail_calls( |
3226 function_state_, ReturnExprContext::kInsideValidReturnStatement); | 3254 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()); | 3255 body = this->NewStatementList(1, zone()); |
3231 this->AddParameterInitializationBlock(formal_parameters, body, CHECK_OK); | 3256 this->AddParameterInitializationBlock(formal_parameters, body, is_async, |
3232 body->Add(factory()->NewReturnStatement(expression, pos), zone()); | 3257 CHECK_OK); |
3258 if (is_async) { | |
3259 this->ParseAsyncArrowSingleExpressionBody(body, accept_IN, &classifier, | |
3260 pos, CHECK_OK); | |
3261 Traits::RewriteNonPattern(&classifier, CHECK_OK); | |
3262 } else { | |
3263 ExpressionT expression = | |
3264 ParseAssignmentExpression(accept_IN, &classifier, CHECK_OK); | |
3265 Traits::RewriteNonPattern(&classifier, CHECK_OK); | |
3266 body->Add(factory()->NewReturnStatement(expression, pos), zone()); | |
3267 if (allow_tailcalls() && !is_sloppy(language_mode())) { | |
3268 // ES6 14.6.1 Static Semantics: IsInTailPosition | |
3269 this->MarkTailPosition(expression); | |
3270 } | |
3271 } | |
3233 materialized_literal_count = function_state.materialized_literal_count(); | 3272 materialized_literal_count = function_state.materialized_literal_count(); |
3234 expected_property_count = function_state.expected_property_count(); | 3273 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(); | 3274 this->MarkCollectedTailCallExpressions(); |
3240 } | 3275 } |
3241 super_loc = function_state.super_location(); | 3276 super_loc = function_state.super_location(); |
3242 | 3277 |
3243 formal_parameters.scope->set_end_position(scanner()->location().end_pos); | 3278 formal_parameters.scope->set_end_position(scanner()->location().end_pos); |
3244 | 3279 |
3245 // Arrow function formal parameters are parsed as StrictFormalParameterList, | 3280 // Arrow function formal parameters are parsed as StrictFormalParameterList, |
3246 // which is not the same as "parameters of a strict function"; it only means | 3281 // 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 | 3282 // that duplicates are not allowed. Of course, the arrow function may |
3248 // itself be strict as well. | 3283 // itself be strict as well. |
3249 const bool allow_duplicate_parameters = false; | 3284 const bool allow_duplicate_parameters = false; |
3250 this->ValidateFormalParameters(&formals_classifier, language_mode(), | 3285 this->ValidateFormalParameters(&formals_classifier, language_mode(), |
3251 allow_duplicate_parameters, CHECK_OK); | 3286 allow_duplicate_parameters, CHECK_OK); |
3252 | 3287 |
3253 // Validate strict mode. | 3288 // Validate strict mode. |
3254 if (is_strict(language_mode())) { | 3289 if (is_strict(language_mode())) { |
3255 CheckStrictOctalLiteral(formal_parameters.scope->start_position(), | 3290 CheckStrictOctalLiteral(formal_parameters.scope->start_position(), |
3256 scanner()->location().end_pos, CHECK_OK); | 3291 scanner()->location().end_pos, CHECK_OK); |
3257 } | 3292 } |
3258 this->CheckConflictingVarDeclarations(formal_parameters.scope, CHECK_OK); | 3293 this->CheckConflictingVarDeclarations(formal_parameters.scope, CHECK_OK); |
3259 | 3294 |
3260 Traits::RewriteDestructuringAssignments(); | 3295 Traits::RewriteDestructuringAssignments(); |
3261 } | 3296 } |
3262 | 3297 |
3263 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( | 3298 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( |
3264 this->EmptyIdentifierString(), formal_parameters.scope, body, | 3299 this->EmptyIdentifierString(), formal_parameters.scope, body, |
3265 materialized_literal_count, expected_property_count, num_parameters, | 3300 materialized_literal_count, expected_property_count, num_parameters, |
3266 FunctionLiteral::kNoDuplicateParameters, | 3301 FunctionLiteral::kNoDuplicateParameters, |
3267 FunctionLiteral::kAnonymousExpression, | 3302 FunctionLiteral::kAnonymousExpression, |
3268 FunctionLiteral::kShouldLazyCompile, FunctionKind::kArrowFunction, | 3303 FunctionLiteral::kShouldLazyCompile, arrow_kind, |
3269 formal_parameters.scope->start_position()); | 3304 formal_parameters.scope->start_position()); |
3270 | 3305 |
3271 function_literal->set_function_token_position( | 3306 function_literal->set_function_token_position( |
3272 formal_parameters.scope->start_position()); | 3307 formal_parameters.scope->start_position()); |
3273 if (super_loc.IsValid()) function_state_->set_super_location(super_loc); | 3308 if (super_loc.IsValid()) function_state_->set_super_location(super_loc); |
3274 | 3309 |
3275 if (fni_ != NULL) this->InferFunctionName(fni_, function_literal); | 3310 if (fni_ != NULL) this->InferFunctionName(fni_, function_literal); |
3276 | 3311 |
3277 return function_literal; | 3312 return function_literal; |
3278 } | 3313 } |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3487 has_seen_constructor_ = true; | 3522 has_seen_constructor_ = true; |
3488 return; | 3523 return; |
3489 } | 3524 } |
3490 } | 3525 } |
3491 | 3526 |
3492 | 3527 |
3493 } // namespace internal | 3528 } // namespace internal |
3494 } // namespace v8 | 3529 } // namespace v8 |
3495 | 3530 |
3496 #endif // V8_PARSING_PARSER_BASE_H | 3531 #endif // V8_PARSING_PARSER_BASE_H |
OLD | NEW |