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/base/hashmap.h" | 10 #include "src/base/hashmap.h" |
(...skipping 3344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3355 bool* ok) { | 3355 bool* ok) { |
3356 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) { | 3356 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) { |
3357 // ASI inserts `;` after arrow parameters if a line terminator is found. | 3357 // ASI inserts `;` after arrow parameters if a line terminator is found. |
3358 // `=> ...` is never a valid expression, so report as syntax error. | 3358 // `=> ...` is never a valid expression, so report as syntax error. |
3359 // If next token is not `=>`, it's a syntax error anyways. | 3359 // If next token is not `=>`, it's a syntax error anyways. |
3360 ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW); | 3360 ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW); |
3361 *ok = false; | 3361 *ok = false; |
3362 return impl()->EmptyExpression(); | 3362 return impl()->EmptyExpression(); |
3363 } | 3363 } |
3364 | 3364 |
3365 typename Types::StatementList body; | 3365 typename Types::StatementList body = impl()->NullStatementList(); |
adamk
2016/08/30 22:13:14
FunctionLiteral-consuming code is OK with null bod
nickie
2016/08/31 13:23:36
Yes, this is how it works already, in the case of
| |
3366 int num_parameters = formal_parameters.scope->num_parameters(); | 3366 int num_parameters = formal_parameters.scope->num_parameters(); |
3367 int materialized_literal_count = -1; | 3367 int materialized_literal_count = -1; |
3368 int expected_property_count = -1; | 3368 int expected_property_count = -1; |
3369 | 3369 |
3370 FunctionKind arrow_kind = is_async ? kAsyncArrowFunction : kArrowFunction; | 3370 FunctionKind arrow_kind = is_async ? kAsyncArrowFunction : kArrowFunction; |
3371 FunctionLiteral::EagerCompileHint eager_compile_hint = | |
3372 FunctionLiteral::kShouldLazyCompile; | |
3373 bool should_be_used_once_hint = false; | |
3371 { | 3374 { |
3372 FunctionState function_state(&function_state_, &scope_state_, | 3375 FunctionState function_state(&function_state_, &scope_state_, |
3373 formal_parameters.scope, arrow_kind); | 3376 formal_parameters.scope, arrow_kind); |
3374 | 3377 |
3375 function_state.SkipMaterializedLiterals( | 3378 function_state.SkipMaterializedLiterals( |
3376 formal_parameters.materialized_literals_count); | 3379 formal_parameters.materialized_literals_count); |
3377 | 3380 |
3378 impl()->ReindexLiterals(formal_parameters); | 3381 impl()->ReindexLiterals(formal_parameters); |
3379 | 3382 |
3380 Expect(Token::ARROW, CHECK_OK); | 3383 Expect(Token::ARROW, CHECK_OK); |
3381 | 3384 |
3382 if (peek() == Token::LBRACE) { | 3385 if (peek() == Token::LBRACE) { |
3383 // Multiple statement body | 3386 // Multiple statement body |
3384 Consume(Token::LBRACE); | 3387 Consume(Token::LBRACE); |
3385 DCHECK_EQ(scope(), formal_parameters.scope); | 3388 DCHECK_EQ(scope(), formal_parameters.scope); |
3386 bool is_lazily_parsed = (mode() == PARSE_LAZILY && | 3389 bool is_lazily_parsed = (mode() == PARSE_LAZILY && |
3387 formal_parameters.scope->AllowsLazyParsing()); | 3390 formal_parameters.scope->AllowsLazyParsing()); |
3388 if (is_lazily_parsed) { | 3391 if (is_lazily_parsed) { |
3389 body = impl()->NewStatementList(0); | 3392 Scanner::BookmarkScope bookmark(scanner()); |
3390 impl()->SkipLazyFunctionBody(&materialized_literal_count, | 3393 bool may_abort = bookmark.Set(); |
3391 &expected_property_count, CHECK_OK); | 3394 bool aborted = impl()->SkipLazyFunctionBody(&materialized_literal_count, |
3392 if (formal_parameters.materialized_literals_count > 0) { | 3395 &expected_property_count, |
3393 materialized_literal_count += | 3396 may_abort, CHECK_OK); |
3394 formal_parameters.materialized_literals_count; | 3397 |
3398 materialized_literal_count += | |
3399 formal_parameters.materialized_literals_count + | |
3400 function_state.materialized_literal_count(); | |
adamk
2016/08/30 22:13:14
Was this wrong before? Why did it change?
nickie
2016/08/31 13:23:36
I changed because it was different from the case o
| |
3401 | |
3402 if (aborted) { | |
3403 bookmark.Reset(); | |
3404 // Trigger eager (re-)parsing, just below this block. | |
3405 is_lazily_parsed = false; | |
3406 | |
3407 // This is probably an initialization function. Inform the compiler it | |
3408 // should also eager-compile this function, and that we expect it to | |
3409 // be used once. | |
3410 eager_compile_hint = FunctionLiteral::kShouldEagerCompile; | |
3411 should_be_used_once_hint = true; | |
3395 } | 3412 } |
3396 } else { | 3413 } |
3414 if (!is_lazily_parsed) { | |
3397 body = impl()->ParseEagerFunctionBody( | 3415 body = impl()->ParseEagerFunctionBody( |
3398 impl()->EmptyIdentifier(), kNoSourcePosition, formal_parameters, | 3416 impl()->EmptyIdentifier(), kNoSourcePosition, formal_parameters, |
3399 arrow_kind, FunctionLiteral::kAnonymousExpression, CHECK_OK); | 3417 arrow_kind, FunctionLiteral::kAnonymousExpression, CHECK_OK); |
3400 materialized_literal_count = | 3418 materialized_literal_count = |
3401 function_state.materialized_literal_count(); | 3419 function_state.materialized_literal_count(); |
3402 expected_property_count = function_state.expected_property_count(); | 3420 expected_property_count = function_state.expected_property_count(); |
3403 } | 3421 } |
3404 } else { | 3422 } else { |
3405 // Single-expression body | 3423 // Single-expression body |
3406 int pos = position(); | 3424 int pos = position(); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3447 } | 3465 } |
3448 impl()->CheckConflictingVarDeclarations(formal_parameters.scope, CHECK_OK); | 3466 impl()->CheckConflictingVarDeclarations(formal_parameters.scope, CHECK_OK); |
3449 | 3467 |
3450 impl()->RewriteDestructuringAssignments(); | 3468 impl()->RewriteDestructuringAssignments(); |
3451 } | 3469 } |
3452 | 3470 |
3453 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( | 3471 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( |
3454 impl()->EmptyIdentifierString(), formal_parameters.scope, body, | 3472 impl()->EmptyIdentifierString(), formal_parameters.scope, body, |
3455 materialized_literal_count, expected_property_count, num_parameters, | 3473 materialized_literal_count, expected_property_count, num_parameters, |
3456 FunctionLiteral::kNoDuplicateParameters, | 3474 FunctionLiteral::kNoDuplicateParameters, |
3457 FunctionLiteral::kAnonymousExpression, | 3475 FunctionLiteral::kAnonymousExpression, eager_compile_hint, arrow_kind, |
3458 FunctionLiteral::kShouldLazyCompile, arrow_kind, | |
3459 formal_parameters.scope->start_position()); | 3476 formal_parameters.scope->start_position()); |
3460 | 3477 |
3461 function_literal->set_function_token_position( | 3478 function_literal->set_function_token_position( |
3462 formal_parameters.scope->start_position()); | 3479 formal_parameters.scope->start_position()); |
3480 if (should_be_used_once_hint) | |
3481 function_literal->set_should_be_used_once_hint(); | |
adamk
2016/08/30 22:13:14
Same style nit, please add { }
nickie
2016/08/31 13:23:36
Done. But look at the very next line... :-)
adamk
2016/08/31 18:08:53
The difference is whether the entire if-statement
| |
3463 | 3482 |
3464 if (fni_ != NULL) impl()->InferFunctionName(fni_, function_literal); | 3483 if (fni_ != NULL) impl()->InferFunctionName(fni_, function_literal); |
3465 | 3484 |
3466 return function_literal; | 3485 return function_literal; |
3467 } | 3486 } |
3468 | 3487 |
3469 template <typename Impl> | 3488 template <typename Impl> |
3470 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseTemplateLiteral( | 3489 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseTemplateLiteral( |
3471 ExpressionT tag, int start, bool* ok) { | 3490 ExpressionT tag, int start, bool* ok) { |
3472 // A TemplateLiteral is made up of 0 or more TEMPLATE_SPAN tokens (literal | 3491 // A TemplateLiteral is made up of 0 or more TEMPLATE_SPAN tokens (literal |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3668 has_seen_constructor_ = true; | 3687 has_seen_constructor_ = true; |
3669 return; | 3688 return; |
3670 } | 3689 } |
3671 } | 3690 } |
3672 | 3691 |
3673 | 3692 |
3674 } // namespace internal | 3693 } // namespace internal |
3675 } // namespace v8 | 3694 } // namespace v8 |
3676 | 3695 |
3677 #endif // V8_PARSING_PARSER_BASE_H | 3696 #endif // V8_PARSING_PARSER_BASE_H |
OLD | NEW |