Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(989)

Side by Side Diff: src/parsing/parser.cc

Issue 2481163002: Assign unique IDs to FunctionLiterals (Closed)
Patch Set: updates Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 #include "src/parsing/parser.h" 5 #include "src/parsing/parser.h"
6 6
7 #include <memory> 7 #include <memory>
8 8
9 #include "src/api.h" 9 #include "src/api.h"
10 #include "src/ast/ast-expression-rewriter.h" 10 #include "src/ast/ast-expression-rewriter.h"
11 #include "src/ast/ast-function-literal-id-reindexer.h"
11 #include "src/ast/ast-literal-reindexer.h" 12 #include "src/ast/ast-literal-reindexer.h"
12 #include "src/ast/ast-traversal-visitor.h" 13 #include "src/ast/ast-traversal-visitor.h"
13 #include "src/ast/ast.h" 14 #include "src/ast/ast.h"
14 #include "src/bailout-reason.h" 15 #include "src/bailout-reason.h"
15 #include "src/base/platform/platform.h" 16 #include "src/base/platform/platform.h"
16 #include "src/char-predicates-inl.h" 17 #include "src/char-predicates-inl.h"
17 #include "src/messages.h" 18 #include "src/messages.h"
18 #include "src/parsing/duplicate-finder.h" 19 #include "src/parsing/duplicate-finder.h"
19 #include "src/parsing/parameter-initializer-rewriter.h" 20 #include "src/parsing/parameter-initializer-rewriter.h"
20 #include "src/parsing/parse-info.h" 21 #include "src/parsing/parse-info.h"
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after
273 274
274 materialized_literal_count = function_state.materialized_literal_count(); 275 materialized_literal_count = function_state.materialized_literal_count();
275 expected_property_count = function_state.expected_property_count(); 276 expected_property_count = function_state.expected_property_count();
276 } 277 }
277 278
278 FunctionLiteral* function_literal = factory()->NewFunctionLiteral( 279 FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
279 name, function_scope, body, materialized_literal_count, 280 name, function_scope, body, materialized_literal_count,
280 expected_property_count, parameter_count, parameter_count, 281 expected_property_count, parameter_count, parameter_count,
281 FunctionLiteral::kNoDuplicateParameters, 282 FunctionLiteral::kNoDuplicateParameters,
282 FunctionLiteral::kAnonymousExpression, default_eager_compile_hint(), pos, 283 FunctionLiteral::kAnonymousExpression, default_eager_compile_hint(), pos,
283 true); 284 true, GetNextFunctionLiteralId());
284 285
285 function_literal->set_requires_class_field_init(requires_class_field_init); 286 function_literal->set_requires_class_field_init(requires_class_field_init);
286 287
287 return function_literal; 288 return function_literal;
288 } 289 }
289 290
290 // ---------------------------------------------------------------------------- 291 // ----------------------------------------------------------------------------
291 // The CHECK_OK macro is a convenient macro to enforce error 292 // The CHECK_OK macro is a convenient macro to enforce error
292 // handling for functions that may fail (by returning !*ok). 293 // handling for functions that may fail (by returning !*ok).
293 // 294 //
(...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after
722 723
723 724
724 FunctionLiteral* Parser::DoParseProgram(ParseInfo* info) { 725 FunctionLiteral* Parser::DoParseProgram(ParseInfo* info) {
725 // Note that this function can be called from the main thread or from a 726 // Note that this function can be called from the main thread or from a
726 // background thread. We should not access anything Isolate / heap dependent 727 // background thread. We should not access anything Isolate / heap dependent
727 // via ParseInfo, and also not pass it forward. 728 // via ParseInfo, and also not pass it forward.
728 DCHECK_NULL(scope_state_); 729 DCHECK_NULL(scope_state_);
729 DCHECK_NULL(target_stack_); 730 DCHECK_NULL(target_stack_);
730 731
731 ParsingModeScope mode(this, allow_lazy_ ? PARSE_LAZILY : PARSE_EAGERLY); 732 ParsingModeScope mode(this, allow_lazy_ ? PARSE_LAZILY : PARSE_EAGERLY);
733 ResetFunctionLiteralId();
734 DCHECK(info->function_literal_id() == FunctionLiteral::kIdTypeTopLevel ||
735 info->function_literal_id() == FunctionLiteral::kIdTypeInvalid);
732 736
733 FunctionLiteral* result = NULL; 737 FunctionLiteral* result = NULL;
734 { 738 {
735 Scope* outer = original_scope_; 739 Scope* outer = original_scope_;
736 DCHECK_NOT_NULL(outer); 740 DCHECK_NOT_NULL(outer);
737 parsing_module_ = info->is_module(); 741 parsing_module_ = info->is_module();
738 if (info->is_eval()) { 742 if (info->is_eval()) {
739 outer = NewEvalScope(outer); 743 outer = NewEvalScope(outer);
740 } else if (parsing_module_) { 744 } else if (parsing_module_) {
741 DCHECK_EQ(outer, info->script_scope()); 745 DCHECK_EQ(outer, info->script_scope());
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
882 const AstRawString* raw_name, 886 const AstRawString* raw_name,
883 Utf16CharacterStream* source) { 887 Utf16CharacterStream* source) {
884 scanner_.Initialize(source); 888 scanner_.Initialize(source);
885 DCHECK_NULL(scope_state_); 889 DCHECK_NULL(scope_state_);
886 DCHECK_NULL(target_stack_); 890 DCHECK_NULL(target_stack_);
887 891
888 DCHECK(ast_value_factory()); 892 DCHECK(ast_value_factory());
889 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone()); 893 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
890 fni_->PushEnclosingName(raw_name); 894 fni_->PushEnclosingName(raw_name);
891 895
896 ResetFunctionLiteralId();
897 DCHECK_LT(0, info->function_literal_id());
898 SkipFunctionLiterals(info->function_literal_id() - 1);
899
892 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); 900 ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
893 901
894 // Place holder for the result. 902 // Place holder for the result.
895 FunctionLiteral* result = nullptr; 903 FunctionLiteral* result = nullptr;
896 904
897 { 905 {
898 // Parse the function literal. 906 // Parse the function literal.
899 Scope* outer = original_scope_; 907 Scope* outer = original_scope_;
900 DeclarationScope* outer_function = outer->GetClosureScope(); 908 DeclarationScope* outer_function = outer->GetClosureScope();
901 DCHECK(outer); 909 DCHECK(outer);
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
948 if (ok) ok = Check(Token::RPAREN); 956 if (ok) ok = Check(Token::RPAREN);
949 } else { 957 } else {
950 // BindingIdentifier 958 // BindingIdentifier
951 ParseFormalParameter(&formals, &ok); 959 ParseFormalParameter(&formals, &ok);
952 if (ok) DeclareFormalParameter(formals.scope, formals.at(0)); 960 if (ok) DeclareFormalParameter(formals.scope, formals.at(0));
953 } 961 }
954 } 962 }
955 963
956 if (ok) { 964 if (ok) {
957 checkpoint.Restore(&formals.materialized_literals_count); 965 checkpoint.Restore(&formals.materialized_literals_count);
966 if (GetLastFunctionLiteralId() != info->function_literal_id() - 1) {
967 // If there were FunctionLiterals in the parameters, we need to
968 // renumber them to shift down so the next function literal id for
969 // the arrow function is the one requested.
970 AstFunctionLiteralIdReindexer reindexer(
971 stack_limit_,
972 (info->function_literal_id() - 1) - GetLastFunctionLiteralId());
973 for (const auto p : formals.params) {
974 if (p.pattern != nullptr) reindexer.Reindex(p.pattern);
975 if (p.initializer != nullptr) reindexer.Reindex(p.initializer);
976 }
977 ResetFunctionLiteralId();
978 SkipFunctionLiterals(info->function_literal_id() - 1);
979 }
980
958 // Pass `accept_IN=true` to ParseArrowFunctionLiteral --- This should 981 // Pass `accept_IN=true` to ParseArrowFunctionLiteral --- This should
959 // not be observable, or else the preparser would have failed. 982 // not be observable, or else the preparser would have failed.
960 Expression* expression = ParseArrowFunctionLiteral(true, formals, &ok); 983 Expression* expression = ParseArrowFunctionLiteral(true, formals, &ok);
961 if (ok) { 984 if (ok) {
962 // Scanning must end at the same position that was recorded 985 // Scanning must end at the same position that was recorded
963 // previously. If not, parsing has been interrupted due to a stack 986 // previously. If not, parsing has been interrupted due to a stack
964 // overflow, at which point the partially parsed arrow function 987 // overflow, at which point the partially parsed arrow function
965 // concise body happens to be a valid expression. This is a problem 988 // concise body happens to be a valid expression. This is a problem
966 // only for arrow functions with single expression bodies, since there 989 // only for arrow functions with single expression bodies, since there
967 // is no end token such as "}" for normal functions. 990 // is no end token such as "}" for normal functions.
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1000 if (info->requires_class_field_init()) { 1023 if (info->requires_class_field_init()) {
1001 result = InsertClassFieldInitializer(result); 1024 result = InsertClassFieldInitializer(result);
1002 } 1025 }
1003 } 1026 }
1004 // Make sure the results agree. 1027 // Make sure the results agree.
1005 DCHECK(ok == (result != nullptr)); 1028 DCHECK(ok == (result != nullptr));
1006 } 1029 }
1007 1030
1008 // Make sure the target stack is empty. 1031 // Make sure the target stack is empty.
1009 DCHECK_NULL(target_stack_); 1032 DCHECK_NULL(target_stack_);
1033 DCHECK_IMPLIES(result,
1034 info->function_literal_id() == result->function_literal_id());
1010 return result; 1035 return result;
1011 } 1036 }
1012 1037
1013 Statement* Parser::ParseModuleItem(bool* ok) { 1038 Statement* Parser::ParseModuleItem(bool* ok) {
1014 // ecma262/#prod-ModuleItem 1039 // ecma262/#prod-ModuleItem
1015 // ModuleItem : 1040 // ModuleItem :
1016 // ImportDeclaration 1041 // ImportDeclaration
1017 // ExportDeclaration 1042 // ExportDeclaration
1018 // StatementListItem 1043 // StatementListItem
1019 1044
(...skipping 1598 matching lines...) Expand 10 before | Expand all | Expand 10 after
2618 scope->SetScopeName(function_name); 2643 scope->SetScopeName(function_name);
2619 #endif 2644 #endif
2620 2645
2621 ZoneList<Statement*>* body = nullptr; 2646 ZoneList<Statement*>* body = nullptr;
2622 int materialized_literal_count = -1; 2647 int materialized_literal_count = -1;
2623 int expected_property_count = -1; 2648 int expected_property_count = -1;
2624 bool should_be_used_once_hint = false; 2649 bool should_be_used_once_hint = false;
2625 int num_parameters = -1; 2650 int num_parameters = -1;
2626 int function_length = -1; 2651 int function_length = -1;
2627 bool has_duplicate_parameters = false; 2652 bool has_duplicate_parameters = false;
2653 int function_literal_id = GetNextFunctionLiteralId();
2628 2654
2629 Expect(Token::LPAREN, CHECK_OK); 2655 Expect(Token::LPAREN, CHECK_OK);
2630 scope->set_start_position(scanner()->location().beg_pos); 2656 scope->set_start_position(scanner()->location().beg_pos);
2631 2657
2632 { 2658 {
2633 // Temporary zones can nest. When we migrate free variables (see below), we 2659 // Temporary zones can nest. When we migrate free variables (see below), we
2634 // need to recreate them in the previous Zone. 2660 // need to recreate them in the previous Zone.
2635 AstNodeFactory previous_zone_ast_node_factory(ast_value_factory()); 2661 AstNodeFactory previous_zone_ast_node_factory(ast_value_factory());
2636 previous_zone_ast_node_factory.set_zone(zone()); 2662 previous_zone_ast_node_factory.set_zone(zone());
2637 2663
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
2724 } // DiscardableZoneScope goes out of scope. 2750 } // DiscardableZoneScope goes out of scope.
2725 2751
2726 FunctionLiteral::ParameterFlag duplicate_parameters = 2752 FunctionLiteral::ParameterFlag duplicate_parameters =
2727 has_duplicate_parameters ? FunctionLiteral::kHasDuplicateParameters 2753 has_duplicate_parameters ? FunctionLiteral::kHasDuplicateParameters
2728 : FunctionLiteral::kNoDuplicateParameters; 2754 : FunctionLiteral::kNoDuplicateParameters;
2729 2755
2730 // Note that the FunctionLiteral needs to be created in the main Zone again. 2756 // Note that the FunctionLiteral needs to be created in the main Zone again.
2731 FunctionLiteral* function_literal = factory()->NewFunctionLiteral( 2757 FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
2732 function_name, scope, body, materialized_literal_count, 2758 function_name, scope, body, materialized_literal_count,
2733 expected_property_count, num_parameters, function_length, 2759 expected_property_count, num_parameters, function_length,
2734 duplicate_parameters, function_type, eager_compile_hint, pos, true); 2760 duplicate_parameters, function_type, eager_compile_hint, pos, true,
2761 function_literal_id);
2735 function_literal->set_function_token_position(function_token_pos); 2762 function_literal->set_function_token_position(function_token_pos);
2736 if (should_be_used_once_hint) 2763 if (should_be_used_once_hint)
2737 function_literal->set_should_be_used_once_hint(); 2764 function_literal->set_should_be_used_once_hint();
2738 2765
2739 if (should_infer_name) { 2766 if (should_infer_name) {
2740 DCHECK_NOT_NULL(fni_); 2767 DCHECK_NOT_NULL(fni_);
2741 fni_->AddFunction(function_literal); 2768 fni_->AddFunction(function_literal);
2742 } 2769 }
2743 return function_literal; 2770 return function_literal;
2744 } 2771 }
(...skipping 27 matching lines...) Expand all
2772 Expect(Token::RBRACE, CHECK_OK_VALUE(kLazyParsingComplete)); 2799 Expect(Token::RBRACE, CHECK_OK_VALUE(kLazyParsingComplete));
2773 *num_parameters = entry.num_parameters(); 2800 *num_parameters = entry.num_parameters();
2774 *function_length = entry.function_length(); 2801 *function_length = entry.function_length();
2775 *has_duplicate_parameters = entry.has_duplicate_parameters(); 2802 *has_duplicate_parameters = entry.has_duplicate_parameters();
2776 *materialized_literal_count = entry.literal_count(); 2803 *materialized_literal_count = entry.literal_count();
2777 *expected_property_count = entry.property_count(); 2804 *expected_property_count = entry.property_count();
2778 SetLanguageMode(function_scope, entry.language_mode()); 2805 SetLanguageMode(function_scope, entry.language_mode());
2779 if (entry.uses_super_property()) 2806 if (entry.uses_super_property())
2780 function_scope->RecordSuperPropertyUsage(); 2807 function_scope->RecordSuperPropertyUsage();
2781 if (entry.calls_eval()) function_scope->RecordEvalCall(); 2808 if (entry.calls_eval()) function_scope->RecordEvalCall();
2809 SkipFunctionLiterals(entry.num_inner_functions());
2782 return kLazyParsingComplete; 2810 return kLazyParsingComplete;
2783 } 2811 }
2784 cached_parse_data_->Reject(); 2812 cached_parse_data_->Reject();
2785 } 2813 }
2786 2814
2787 // With no cached data, we partially parse the function, without building an 2815 // With no cached data, we partially parse the function, without building an
2788 // AST. This gathers the data needed to build a lazy function. 2816 // AST. This gathers the data needed to build a lazy function.
2789 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.PreParse"); 2817 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.PreParse");
2790 2818
2791 if (reusable_preparser_ == NULL) { 2819 if (reusable_preparser_ == NULL) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
2824 PreParserLogger* logger = reusable_preparser_->logger(); 2852 PreParserLogger* logger = reusable_preparser_->logger();
2825 function_scope->set_end_position(logger->end()); 2853 function_scope->set_end_position(logger->end());
2826 Expect(Token::RBRACE, CHECK_OK_VALUE(kLazyParsingComplete)); 2854 Expect(Token::RBRACE, CHECK_OK_VALUE(kLazyParsingComplete));
2827 total_preparse_skipped_ += 2855 total_preparse_skipped_ +=
2828 function_scope->end_position() - function_scope->start_position(); 2856 function_scope->end_position() - function_scope->start_position();
2829 *num_parameters = logger->num_parameters(); 2857 *num_parameters = logger->num_parameters();
2830 *function_length = logger->function_length(); 2858 *function_length = logger->function_length();
2831 *has_duplicate_parameters = logger->has_duplicate_parameters(); 2859 *has_duplicate_parameters = logger->has_duplicate_parameters();
2832 *materialized_literal_count = logger->literals(); 2860 *materialized_literal_count = logger->literals();
2833 *expected_property_count = logger->properties(); 2861 *expected_property_count = logger->properties();
2862 SkipFunctionLiterals(logger->num_inner_functions());
2834 if (!is_inner_function && produce_cached_parse_data()) { 2863 if (!is_inner_function && produce_cached_parse_data()) {
2835 DCHECK(log_); 2864 DCHECK(log_);
2836 log_->LogFunction( 2865 log_->LogFunction(
2837 function_scope->start_position(), function_scope->end_position(), 2866 function_scope->start_position(), function_scope->end_position(),
2838 *num_parameters, *function_length, *has_duplicate_parameters, 2867 *num_parameters, *function_length, *has_duplicate_parameters,
2839 *materialized_literal_count, *expected_property_count, language_mode(), 2868 *materialized_literal_count, *expected_property_count, language_mode(),
2840 function_scope->uses_super_property(), function_scope->calls_eval()); 2869 function_scope->uses_super_property(), function_scope->calls_eval(),
2870 logger->num_inner_functions());
2841 } 2871 }
2842 return kLazyParsingComplete; 2872 return kLazyParsingComplete;
2843 } 2873 }
2844 2874
2845 2875
2846 Statement* Parser::BuildAssertIsCoercible(Variable* var) { 2876 Statement* Parser::BuildAssertIsCoercible(Variable* var) {
2847 // if (var === null || var === undefined) 2877 // if (var === null || var === undefined)
2848 // throw /* type error kNonCoercible) */; 2878 // throw /* type error kNonCoercible) */;
2849 2879
2850 Expression* condition = factory()->NewBinaryOperation( 2880 Expression* condition = factory()->NewBinaryOperation(
(...skipping 558 matching lines...) Expand 10 before | Expand all | Expand 10 after
3409 body->Add(factory()->NewReturnStatement(ThisExpression(kNoSourcePosition), 3439 body->Add(factory()->NewReturnStatement(ThisExpression(kNoSourcePosition),
3410 kNoSourcePosition), 3440 kNoSourcePosition),
3411 zone()); 3441 zone());
3412 FunctionLiteral* function_literal = factory()->NewFunctionLiteral( 3442 FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
3413 ast_value_factory()->empty_string(), initializer_scope, body, 3443 ast_value_factory()->empty_string(), initializer_scope, body,
3414 initializer_state.materialized_literal_count(), 3444 initializer_state.materialized_literal_count(),
3415 initializer_state.expected_property_count(), 0, count, 3445 initializer_state.expected_property_count(), 0, count,
3416 FunctionLiteral::kNoDuplicateParameters, 3446 FunctionLiteral::kNoDuplicateParameters,
3417 FunctionLiteral::kAnonymousExpression, 3447 FunctionLiteral::kAnonymousExpression,
3418 FunctionLiteral::kShouldLazyCompile, initializer_scope->start_position(), 3448 FunctionLiteral::kShouldLazyCompile, initializer_scope->start_position(),
3419 true); 3449 true, GetNextFunctionLiteralId());
3420 function_literal->set_is_class_field_initializer(true); 3450 function_literal->set_is_class_field_initializer(true);
3421 return function_literal; 3451 return function_literal;
3422 } 3452 }
3423 3453
3424 FunctionLiteral* Parser::InsertClassFieldInitializer( 3454 FunctionLiteral* Parser::InsertClassFieldInitializer(
3425 FunctionLiteral* constructor) { 3455 FunctionLiteral* constructor) {
3426 Statement* call_initializer = factory()->NewExpressionStatement( 3456 Statement* call_initializer = factory()->NewExpressionStatement(
3427 CallClassFieldInitializer( 3457 CallClassFieldInitializer(
3428 constructor->scope(), 3458 constructor->scope(),
3429 constructor->scope()->NewUnresolved( 3459 constructor->scope()->NewUnresolved(
(...skipping 23 matching lines...) Expand all
3453 } 3483 }
3454 3484
3455 // This method declares a property of the given class. It updates the 3485 // This method declares a property of the given class. It updates the
3456 // following fields of class_info, as appropriate: 3486 // following fields of class_info, as appropriate:
3457 // - constructor 3487 // - constructor
3458 // - static_initializer_var 3488 // - static_initializer_var
3459 // - instance_field_initializers 3489 // - instance_field_initializers
3460 // - properties 3490 // - properties
3461 void Parser::DeclareClassProperty(const AstRawString* class_name, 3491 void Parser::DeclareClassProperty(const AstRawString* class_name,
3462 ClassLiteralProperty* property, 3492 ClassLiteralProperty* property,
3463 ClassInfo* class_info, bool* ok) { 3493 ClassLiteralProperty::Kind kind,
3494 bool is_static, ClassInfo* class_info,
3495 bool* ok) {
3464 if (class_info->has_seen_constructor && class_info->constructor == nullptr) { 3496 if (class_info->has_seen_constructor && class_info->constructor == nullptr) {
3465 class_info->constructor = GetPropertyValue(property)->AsFunctionLiteral(); 3497 class_info->constructor = GetPropertyValue(property)->AsFunctionLiteral();
3466 DCHECK_NOT_NULL(class_info->constructor); 3498 DCHECK_NOT_NULL(class_info->constructor);
3467 class_info->constructor->set_raw_name( 3499 class_info->constructor->set_raw_name(
3468 class_name != nullptr ? class_name 3500 class_name != nullptr ? class_name
3469 : ast_value_factory()->empty_string()); 3501 : ast_value_factory()->empty_string());
3470 return; 3502 return;
3471 } 3503 }
3472 3504
3473 if (property->kind() == ClassLiteralProperty::FIELD) { 3505 if (property->kind() == ClassLiteralProperty::FIELD) {
(...skipping 1963 matching lines...) Expand 10 before | Expand all | Expand 10 after
5437 5469
5438 return final_loop; 5470 return final_loop;
5439 } 5471 }
5440 5472
5441 #undef CHECK_OK 5473 #undef CHECK_OK
5442 #undef CHECK_OK_VOID 5474 #undef CHECK_OK_VOID
5443 #undef CHECK_FAILED 5475 #undef CHECK_FAILED
5444 5476
5445 } // namespace internal 5477 } // namespace internal
5446 } // namespace v8 5478 } // namespace v8
OLDNEW
« no previous file with comments | « src/parsing/parser.h ('k') | src/parsing/parser-base.h » ('j') | src/parsing/preparser.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698