Chromium Code Reviews| 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 |