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 |