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

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

Issue 2472063002: Preparse lazy function parameters (Closed)
Patch Set: IsArrowFunction Created 4 years, 1 month 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
« no previous file with comments | « src/parsing/parser.h ('k') | src/parsing/parser-base.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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"
(...skipping 2505 matching lines...) Expand 10 before | Expand all | Expand 10 after
2516 // 2516 //
2517 // Getter :: 2517 // Getter ::
2518 // '(' ')' '{' FunctionBody '}' 2518 // '(' ')' '{' FunctionBody '}'
2519 // 2519 //
2520 // Setter :: 2520 // Setter ::
2521 // '(' PropertySetParameterList ')' '{' FunctionBody '}' 2521 // '(' PropertySetParameterList ')' '{' FunctionBody '}'
2522 2522
2523 int pos = function_token_pos == kNoSourcePosition ? peek_position() 2523 int pos = function_token_pos == kNoSourcePosition ? peek_position()
2524 : function_token_pos; 2524 : function_token_pos;
2525 2525
2526 bool is_generator = IsGeneratorFunction(kind);
2527
2528 // Anonymous functions were passed either the empty symbol or a null 2526 // Anonymous functions were passed either the empty symbol or a null
2529 // handle as the function name. Remember if we were passed a non-empty 2527 // handle as the function name. Remember if we were passed a non-empty
2530 // handle to decide whether to invoke function name inference. 2528 // handle to decide whether to invoke function name inference.
2531 bool should_infer_name = function_name == NULL; 2529 bool should_infer_name = function_name == NULL;
2532 2530
2533 // We want a non-null handle as the function name. 2531 // We want a non-null handle as the function name.
2534 if (should_infer_name) { 2532 if (should_infer_name) {
2535 function_name = ast_value_factory()->empty_string(); 2533 function_name = ast_value_factory()->empty_string();
2536 } 2534 }
2537 2535
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
2607 : (is_lazy_top_level_function || 2605 : (is_lazy_top_level_function ||
2608 (allow_lazy() && function_type == FunctionLiteral::kDeclaration && 2606 (allow_lazy() && function_type == FunctionLiteral::kDeclaration &&
2609 eager_compile_hint == FunctionLiteral::kShouldLazyCompile))) && 2607 eager_compile_hint == FunctionLiteral::kShouldLazyCompile))) &&
2610 !(FLAG_validate_asm && scope()->IsAsmModule()); 2608 !(FLAG_validate_asm && scope()->IsAsmModule());
2611 bool is_lazy_inner_function = 2609 bool is_lazy_inner_function =
2612 use_temp_zone && FLAG_lazy_inner_functions && !is_lazy_top_level_function; 2610 use_temp_zone && FLAG_lazy_inner_functions && !is_lazy_top_level_function;
2613 2611
2614 // This Scope lives in the main zone. We'll migrate data into that zone later. 2612 // This Scope lives in the main zone. We'll migrate data into that zone later.
2615 DeclarationScope* scope = NewFunctionScope(kind); 2613 DeclarationScope* scope = NewFunctionScope(kind);
2616 SetLanguageMode(scope, language_mode); 2614 SetLanguageMode(scope, language_mode);
2615 #ifdef DEBUG
2616 scope->SetScopeName(function_name);
2617 #endif
2617 2618
2618 ZoneList<Statement*>* body = nullptr; 2619 ZoneList<Statement*>* body = nullptr;
2619 int materialized_literal_count = -1; 2620 int materialized_literal_count = -1;
2620 int expected_property_count = -1; 2621 int expected_property_count = -1;
2621 DuplicateFinder duplicate_finder(scanner()->unicode_cache());
2622 bool should_be_used_once_hint = false; 2622 bool should_be_used_once_hint = false;
2623 bool has_duplicate_parameters; 2623 int num_parameters = -1;
2624 2624 int function_length = -1;
2625 FunctionState function_state(&function_state_, &scope_state_, scope); 2625 bool has_duplicate_parameters = false;
2626 #ifdef DEBUG
2627 scope->SetScopeName(function_name);
2628 #endif
2629
2630 ExpressionClassifier formals_classifier(this, &duplicate_finder);
2631
2632 if (is_generator) PrepareGeneratorVariables(&function_state);
2633 2626
2634 Expect(Token::LPAREN, CHECK_OK); 2627 Expect(Token::LPAREN, CHECK_OK);
2635 int start_position = scanner()->location().beg_pos; 2628 scope->set_start_position(scanner()->location().beg_pos);
2636 this->scope()->set_start_position(start_position);
2637 ParserFormalParameters formals(scope);
2638 ParseFormalParameterList(&formals, CHECK_OK);
2639 Expect(Token::RPAREN, CHECK_OK);
2640 int formals_end_position = scanner()->location().end_pos;
2641
2642 CheckArityRestrictions(formals.arity, kind, formals.has_rest, start_position,
2643 formals_end_position, CHECK_OK);
2644 Expect(Token::LBRACE, CHECK_OK);
2645 2629
2646 { 2630 {
2647 // Temporary zones can nest. When we migrate free variables (see below), we 2631 // Temporary zones can nest. When we migrate free variables (see below), we
2648 // need to recreate them in the previous Zone. 2632 // need to recreate them in the previous Zone.
2649 AstNodeFactory previous_zone_ast_node_factory(ast_value_factory()); 2633 AstNodeFactory previous_zone_ast_node_factory(ast_value_factory());
2650 previous_zone_ast_node_factory.set_zone(zone()); 2634 previous_zone_ast_node_factory.set_zone(zone());
2651 2635
2652 // Open a new zone scope, which sets our AstNodeFactory to allocate in the 2636 // Open a new zone scope, which sets our AstNodeFactory to allocate in the
2653 // new temporary zone if the preconditions are satisfied, and ensures that 2637 // new temporary zone if the preconditions are satisfied, and ensures that
2654 // the previous zone is always restored after parsing the body. To be able 2638 // the previous zone is always restored after parsing the body. To be able
2655 // to do scope analysis correctly after full parsing, we migrate needed 2639 // to do scope analysis correctly after full parsing, we migrate needed
2656 // information when the function is parsed. 2640 // information when the function is parsed.
2657 Zone temp_zone(zone()->allocator(), ZONE_NAME); 2641 Zone temp_zone(zone()->allocator(), ZONE_NAME);
2658 DiscardableZoneScope zone_scope(this, &temp_zone, use_temp_zone); 2642 DiscardableZoneScope zone_scope(this, &temp_zone, use_temp_zone);
2659 #ifdef DEBUG 2643 #ifdef DEBUG
2660 if (use_temp_zone) scope->set_needs_migration(); 2644 if (use_temp_zone) scope->set_needs_migration();
2661 #endif 2645 #endif
2662 2646
2663 // Eager or lazy parse? If is_lazy_top_level_function, we'll parse 2647 // Eager or lazy parse? If is_lazy_top_level_function, we'll parse
2664 // lazily. We'll call SkipLazyFunctionBody, which may decide to abort lazy 2648 // lazily. We'll call SkipFunction, which may decide to
2665 // parsing if it suspects that wasn't a good idea. If so (in which case the 2649 // abort lazy parsing if it suspects that wasn't a good idea. If so (in
2666 // parser is expected to have backtracked), or if we didn't try to lazy 2650 // which case the parser is expected to have backtracked), or if we didn't
2667 // parse in the first place, we'll have to parse eagerly. 2651 // try to lazy parse in the first place, we'll have to parse eagerly.
2668 if (is_lazy_top_level_function || is_lazy_inner_function) { 2652 if (is_lazy_top_level_function || is_lazy_inner_function) {
2669 Scanner::BookmarkScope bookmark(scanner()); 2653 Scanner::BookmarkScope bookmark(scanner());
2670 bookmark.Set(); 2654 bookmark.Set();
2671 LazyParsingResult result = SkipLazyFunctionBody( 2655 LazyParsingResult result =
2672 &materialized_literal_count, &expected_property_count, 2656 SkipFunction(kind, scope, &num_parameters, &function_length,
2673 is_lazy_inner_function, is_lazy_top_level_function, CHECK_OK); 2657 &has_duplicate_parameters, &materialized_literal_count,
2674 2658 &expected_property_count, is_lazy_inner_function,
2675 materialized_literal_count += formals.materialized_literals_count + 2659 is_lazy_top_level_function, CHECK_OK);
2676 function_state.materialized_literal_count();
2677 2660
2678 if (result == kLazyParsingAborted) { 2661 if (result == kLazyParsingAborted) {
2679 DCHECK(is_lazy_top_level_function); 2662 DCHECK(is_lazy_top_level_function);
2680 bookmark.Apply(); 2663 bookmark.Apply();
2681 // Trigger eager (re-)parsing, just below this block. 2664 // Trigger eager (re-)parsing, just below this block.
2682 is_lazy_top_level_function = false; 2665 is_lazy_top_level_function = false;
2683 2666
2684 // This is probably an initialization function. Inform the compiler it 2667 // This is probably an initialization function. Inform the compiler it
2685 // should also eager-compile this function, and that we expect it to be 2668 // should also eager-compile this function, and that we expect it to be
2686 // used once. 2669 // used once.
2687 eager_compile_hint = FunctionLiteral::kShouldEagerCompile; 2670 eager_compile_hint = FunctionLiteral::kShouldEagerCompile;
2688 should_be_used_once_hint = true; 2671 should_be_used_once_hint = true;
2689 scope->ResetAfterPreparsing(ast_value_factory(), true); 2672 scope->ResetAfterPreparsing(ast_value_factory(), true);
2690 zone_scope.Reset(); 2673 zone_scope.Reset();
2691 use_temp_zone = false; 2674 use_temp_zone = false;
2692 } 2675 }
2693 } 2676 }
2694 2677
2695 if (!is_lazy_top_level_function && !is_lazy_inner_function) { 2678 if (!is_lazy_top_level_function && !is_lazy_inner_function) {
2696 body = ParseEagerFunctionBody(function_name, pos, formals, kind, 2679 body = ParseFunction(
2697 function_type, CHECK_OK); 2680 function_name, pos, kind, function_type, scope, &num_parameters,
2698 2681 &function_length, &has_duplicate_parameters,
2699 materialized_literal_count = function_state.materialized_literal_count(); 2682 &materialized_literal_count, &expected_property_count, CHECK_OK);
2700 expected_property_count = function_state.expected_property_count();
2701 } 2683 }
2702 2684
2703 DCHECK(use_temp_zone || !is_lazy_top_level_function); 2685 DCHECK(use_temp_zone || !is_lazy_top_level_function);
2704 if (use_temp_zone) { 2686 if (use_temp_zone) {
2705 // If the preconditions are correct the function body should never be 2687 // If the preconditions are correct the function body should never be
2706 // accessed, but do this anyway for better behaviour if they're wrong. 2688 // accessed, but do this anyway for better behaviour if they're wrong.
2707 body = nullptr; 2689 body = nullptr;
2708 scope->AnalyzePartially(&previous_zone_ast_node_factory); 2690 scope->AnalyzePartially(&previous_zone_ast_node_factory);
2709 } 2691 }
2710 2692
2711 if (FLAG_trace_preparse) { 2693 if (FLAG_trace_preparse) {
2712 PrintF(" [%s]: %i-%i %.*s\n", 2694 PrintF(" [%s]: %i-%i %.*s\n",
2713 is_lazy_top_level_function 2695 is_lazy_top_level_function
2714 ? "Preparse no-resolution" 2696 ? "Preparse no-resolution"
2715 : (use_temp_zone ? "Preparse resolution" : "Full parse"), 2697 : (use_temp_zone ? "Preparse resolution" : "Full parse"),
2716 scope->start_position(), scope->end_position(), 2698 scope->start_position(), scope->end_position(),
2717 function_name->byte_length(), function_name->raw_data()); 2699 function_name->byte_length(), function_name->raw_data());
2718 } 2700 }
2719 2701
2720 // Parsing the body may change the language mode in our scope. 2702 // Validate function name. We can do this only after parsing the function,
2703 // since the function can declare itself strict.
2721 language_mode = scope->language_mode(); 2704 language_mode = scope->language_mode();
2722
2723 // Validate name and parameter names. We can do this only after parsing the
2724 // function, since the function can declare itself strict.
2725 CheckFunctionName(language_mode, function_name, function_name_validity, 2705 CheckFunctionName(language_mode, function_name, function_name_validity,
2726 function_name_location, CHECK_OK); 2706 function_name_location, CHECK_OK);
2727 const bool allow_duplicate_parameters =
2728 is_sloppy(language_mode) && formals.is_simple && !IsConciseMethod(kind);
2729 ValidateFormalParameters(language_mode, allow_duplicate_parameters,
2730 CHECK_OK);
2731 2707
2732 if (is_strict(language_mode)) { 2708 if (is_strict(language_mode)) {
2733 CheckStrictOctalLiteral(scope->start_position(), scope->end_position(), 2709 CheckStrictOctalLiteral(scope->start_position(), scope->end_position(),
2734 CHECK_OK); 2710 CHECK_OK);
2735 CheckDecimalLiteralWithLeadingZero(scope->start_position(), 2711 CheckDecimalLiteralWithLeadingZero(scope->start_position(),
2736 scope->end_position()); 2712 scope->end_position());
2737 } 2713 }
2738 CheckConflictingVarDeclarations(scope, CHECK_OK); 2714 CheckConflictingVarDeclarations(scope, CHECK_OK);
2739
2740 if (body) {
2741 // If body can be inspected, rewrite queued destructuring assignments
2742 RewriteDestructuringAssignments();
2743 }
2744 has_duplicate_parameters =
2745 !classifier()->is_valid_formal_parameter_list_without_duplicates();
2746 } // DiscardableZoneScope goes out of scope. 2715 } // DiscardableZoneScope goes out of scope.
2747 2716
2748 FunctionLiteral::ParameterFlag duplicate_parameters = 2717 FunctionLiteral::ParameterFlag duplicate_parameters =
2749 has_duplicate_parameters ? FunctionLiteral::kHasDuplicateParameters 2718 has_duplicate_parameters ? FunctionLiteral::kHasDuplicateParameters
2750 : FunctionLiteral::kNoDuplicateParameters; 2719 : FunctionLiteral::kNoDuplicateParameters;
2751 2720
2752 // Note that the FunctionLiteral needs to be created in the main Zone again. 2721 // Note that the FunctionLiteral needs to be created in the main Zone again.
2753 FunctionLiteral* function_literal = factory()->NewFunctionLiteral( 2722 FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
2754 function_name, scope, body, materialized_literal_count, 2723 function_name, scope, body, materialized_literal_count,
2755 expected_property_count, formals.num_parameters(), 2724 expected_property_count, num_parameters, function_length,
2756 formals.function_length, duplicate_parameters, function_type, 2725 duplicate_parameters, function_type, eager_compile_hint, pos);
2757 eager_compile_hint, pos);
2758 function_literal->set_function_token_position(function_token_pos); 2726 function_literal->set_function_token_position(function_token_pos);
2759 if (should_be_used_once_hint) 2727 if (should_be_used_once_hint)
2760 function_literal->set_should_be_used_once_hint(); 2728 function_literal->set_should_be_used_once_hint();
2761 2729
2762 if (should_infer_name) { 2730 if (should_infer_name) {
2763 DCHECK_NOT_NULL(fni_); 2731 DCHECK_NOT_NULL(fni_);
2764 fni_->AddFunction(function_literal); 2732 fni_->AddFunction(function_literal);
2765 } 2733 }
2766 return function_literal; 2734 return function_literal;
2767 } 2735 }
2768 2736
2769 Parser::LazyParsingResult Parser::SkipLazyFunctionBody( 2737 Parser::LazyParsingResult Parser::SkipFunction(
2738 FunctionKind kind, DeclarationScope* function_scope, int* num_parameters,
2739 int* function_length, bool* has_duplicate_parameters,
2770 int* materialized_literal_count, int* expected_property_count, 2740 int* materialized_literal_count, int* expected_property_count,
2771 bool is_inner_function, bool may_abort, bool* ok) { 2741 bool is_inner_function, bool may_abort, bool* ok) {
2742 DCHECK_NE(kNoSourcePosition, function_scope->start_position());
2772 if (produce_cached_parse_data()) CHECK(log_); 2743 if (produce_cached_parse_data()) CHECK(log_);
2773 2744
2774 int function_block_pos = position(); 2745 DCHECK_IMPLIES(IsArrowFunction(kind),
2775 DeclarationScope* scope = function_state_->scope(); 2746 scanner()->current_token() == Token::ARROW);
2776 DCHECK(scope->is_function_scope()); 2747
2777 // Inner functions are not part of the cached data. 2748 // Inner functions are not part of the cached data.
2778 if (!is_inner_function && consume_cached_parse_data() && 2749 if (!is_inner_function && consume_cached_parse_data() &&
2779 !cached_parse_data_->rejected()) { 2750 !cached_parse_data_->rejected()) {
2780 // If we have cached data, we use it to skip parsing the function body. The 2751 // If we have cached data, we use it to skip parsing the function. The data
2781 // data contains the information we need to construct the lazy function. 2752 // contains the information we need to construct the lazy function.
2782 FunctionEntry entry = 2753 FunctionEntry entry =
2783 cached_parse_data_->GetFunctionEntry(function_block_pos); 2754 cached_parse_data_->GetFunctionEntry(function_scope->start_position());
2784 // Check that cached data is valid. If not, mark it as invalid (the embedder 2755 // Check that cached data is valid. If not, mark it as invalid (the embedder
2785 // handles it). Note that end position greater than end of stream is safe, 2756 // handles it). Note that end position greater than end of stream is safe,
2786 // and hard to check. 2757 // and hard to check.
2787 if (entry.is_valid() && entry.end_pos() > function_block_pos) { 2758 if (entry.is_valid() &&
2759 entry.end_pos() > function_scope->start_position()) {
2760 total_preparse_skipped_ += entry.end_pos() - position();
2761 function_scope->set_end_position(entry.end_pos());
2788 scanner()->SeekForward(entry.end_pos() - 1); 2762 scanner()->SeekForward(entry.end_pos() - 1);
2789
2790 scope->set_end_position(entry.end_pos());
2791 Expect(Token::RBRACE, CHECK_OK_VALUE(kLazyParsingComplete)); 2763 Expect(Token::RBRACE, CHECK_OK_VALUE(kLazyParsingComplete));
2792 total_preparse_skipped_ += scope->end_position() - function_block_pos; 2764 *num_parameters = entry.num_parameters();
2765 *function_length = entry.function_length();
2766 *has_duplicate_parameters = entry.has_duplicate_parameters();
2793 *materialized_literal_count = entry.literal_count(); 2767 *materialized_literal_count = entry.literal_count();
2794 *expected_property_count = entry.property_count(); 2768 *expected_property_count = entry.property_count();
2795 SetLanguageMode(scope, entry.language_mode()); 2769 SetLanguageMode(function_scope, entry.language_mode());
2796 if (entry.uses_super_property()) scope->RecordSuperPropertyUsage(); 2770 if (entry.uses_super_property())
2797 if (entry.calls_eval()) scope->RecordEvalCall(); 2771 function_scope->RecordSuperPropertyUsage();
2772 if (entry.calls_eval()) function_scope->RecordEvalCall();
2798 return kLazyParsingComplete; 2773 return kLazyParsingComplete;
2799 } 2774 }
2800 cached_parse_data_->Reject(); 2775 cached_parse_data_->Reject();
2801 } 2776 }
2802 // With no cached data, we partially parse the function, without building an 2777 // With no cached data, we partially parse the function, without building an
2803 // AST. This gathers the data needed to build a lazy function. 2778 // AST. This gathers the data needed to build a lazy function.
2804 SingletonLogger logger; 2779 SingletonLogger logger;
2805 PreParser::PreParseResult result = 2780 PreParser::PreParseResult result = ParseFunctionWithPreParser(
2806 ParseFunctionBodyWithPreParser(&logger, is_inner_function, may_abort); 2781 kind, function_scope, &logger, is_inner_function, may_abort);
2807 2782
2808 // Return immediately if pre-parser decided to abort parsing. 2783 // Return immediately if pre-parser decided to abort parsing.
2809 if (result == PreParser::kPreParseAbort) return kLazyParsingAborted; 2784 if (result == PreParser::kPreParseAbort) return kLazyParsingAborted;
2810 if (result == PreParser::kPreParseStackOverflow) { 2785 if (result == PreParser::kPreParseStackOverflow) {
2811 // Propagate stack overflow. 2786 // Propagate stack overflow.
2812 set_stack_overflow(); 2787 set_stack_overflow();
2813 *ok = false; 2788 *ok = false;
2814 return kLazyParsingComplete; 2789 return kLazyParsingComplete;
2815 } 2790 }
2816 if (logger.has_error()) { 2791 if (logger.has_error()) {
2817 ReportMessageAt(Scanner::Location(logger.start(), logger.end()), 2792 ReportMessageAt(Scanner::Location(logger.start(), logger.end()),
2818 logger.message(), logger.argument_opt(), 2793 logger.message(), logger.argument_opt(),
2819 logger.error_type()); 2794 logger.error_type());
2820 *ok = false; 2795 *ok = false;
2821 return kLazyParsingComplete; 2796 return kLazyParsingComplete;
2822 } 2797 }
2823 scope->set_end_position(logger.end()); 2798 function_scope->set_end_position(logger.end());
2824 Expect(Token::RBRACE, CHECK_OK_VALUE(kLazyParsingComplete)); 2799 Expect(Token::RBRACE, CHECK_OK_VALUE(kLazyParsingComplete));
2825 total_preparse_skipped_ += scope->end_position() - function_block_pos; 2800 total_preparse_skipped_ +=
2801 function_scope->end_position() - function_scope->start_position();
2802 *num_parameters = logger.num_parameters();
2803 *function_length = logger.function_length();
2804 *has_duplicate_parameters = logger.has_duplicate_parameters();
2826 *materialized_literal_count = logger.literals(); 2805 *materialized_literal_count = logger.literals();
2827 *expected_property_count = logger.properties(); 2806 *expected_property_count = logger.properties();
2828 SetLanguageMode(scope, logger.language_mode()); 2807 SetLanguageMode(function_scope, logger.language_mode());
2829 if (logger.uses_super_property()) scope->RecordSuperPropertyUsage(); 2808 if (logger.uses_super_property()) function_scope->RecordSuperPropertyUsage();
2830 if (logger.calls_eval()) scope->RecordEvalCall(); 2809 if (logger.calls_eval()) function_scope->RecordEvalCall();
2831 if (!is_inner_function && produce_cached_parse_data()) { 2810 if (!is_inner_function && produce_cached_parse_data()) {
2832 DCHECK(log_); 2811 DCHECK(log_);
2833 // Position right after terminal '}'. 2812 log_->LogFunction(
2834 int body_end = scanner()->location().end_pos; 2813 function_scope->start_position(), function_scope->end_position(),
2835 log_->LogFunction(function_block_pos, body_end, *materialized_literal_count, 2814 *num_parameters, *function_length, *has_duplicate_parameters,
2836 *expected_property_count, language_mode(), 2815 *materialized_literal_count, *expected_property_count, language_mode(),
2837 scope->uses_super_property(), scope->calls_eval()); 2816 function_scope->uses_super_property(), function_scope->calls_eval());
2838 } 2817 }
2839 return kLazyParsingComplete; 2818 return kLazyParsingComplete;
2840 } 2819 }
2841 2820
2842 2821
2843 Statement* Parser::BuildAssertIsCoercible(Variable* var) { 2822 Statement* Parser::BuildAssertIsCoercible(Variable* var) {
2844 // if (var === null || var === undefined) 2823 // if (var === null || var === undefined)
2845 // throw /* type error kNonCoercible) */; 2824 // throw /* type error kNonCoercible) */;
2846 2825
2847 Expression* condition = factory()->NewBinaryOperation( 2826 Expression* condition = factory()->NewBinaryOperation(
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after
3100 Token::INIT, init_proxy, allocation, kNoSourcePosition); 3079 Token::INIT, init_proxy, allocation, kNoSourcePosition);
3101 VariableProxy* get_proxy = 3080 VariableProxy* get_proxy =
3102 factory()->NewVariableProxy(function_state_->generator_object_variable()); 3081 factory()->NewVariableProxy(function_state_->generator_object_variable());
3103 // The position of the yield is important for reporting the exception 3082 // The position of the yield is important for reporting the exception
3104 // caused by calling the .throw method on a generator suspended at the 3083 // caused by calling the .throw method on a generator suspended at the
3105 // initial yield (i.e. right after generator instantiation). 3084 // initial yield (i.e. right after generator instantiation).
3106 return factory()->NewYield(get_proxy, assignment, scope()->start_position(), 3085 return factory()->NewYield(get_proxy, assignment, scope()->start_position(),
3107 Yield::kOnExceptionThrow); 3086 Yield::kOnExceptionThrow);
3108 } 3087 }
3109 3088
3089 ZoneList<Statement*>* Parser::ParseFunction(
3090 const AstRawString* function_name, int pos, FunctionKind kind,
3091 FunctionLiteral::FunctionType function_type,
3092 DeclarationScope* function_scope, int* num_parameters, int* function_length,
3093 bool* has_duplicate_parameters, int* materialized_literal_count,
3094 int* expected_property_count, bool* ok) {
3095 FunctionState function_state(&function_state_, &scope_state_, function_scope);
3096
3097 DuplicateFinder duplicate_finder(scanner()->unicode_cache());
3098 ExpressionClassifier formals_classifier(this, &duplicate_finder);
3099
3100 if (IsGeneratorFunction(kind)) PrepareGeneratorVariables(&function_state);
3101
3102 ParserFormalParameters formals(function_scope);
3103 ParseFormalParameterList(&formals, CHECK_OK);
3104 Expect(Token::RPAREN, CHECK_OK);
3105 int formals_end_position = scanner()->location().end_pos;
3106 *num_parameters = formals.num_parameters();
3107 *function_length = formals.function_length;
3108
3109 CheckArityRestrictions(formals.arity, kind, formals.has_rest,
3110 function_scope->start_position(), formals_end_position,
3111 CHECK_OK);
3112 Expect(Token::LBRACE, CHECK_OK);
3113
3114 ZoneList<Statement*>* body = ParseEagerFunctionBody(
3115 function_name, pos, formals, kind, function_type, ok);
3116
3117 // Validate parameter names. We can do this only after parsing the function,
3118 // since the function can declare itself strict.
3119 const bool allow_duplicate_parameters =
3120 is_sloppy(function_scope->language_mode()) && formals.is_simple &&
3121 !IsConciseMethod(kind);
3122 ValidateFormalParameters(function_scope->language_mode(),
3123 allow_duplicate_parameters, CHECK_OK);
3124
3125 RewriteDestructuringAssignments();
3126
3127 *has_duplicate_parameters =
3128 !classifier()->is_valid_formal_parameter_list_without_duplicates();
3129
3130 *materialized_literal_count = function_state.materialized_literal_count();
3131 *expected_property_count = function_state.expected_property_count();
3132 return body;
3133 }
3134
3110 ZoneList<Statement*>* Parser::ParseEagerFunctionBody( 3135 ZoneList<Statement*>* Parser::ParseEagerFunctionBody(
3111 const AstRawString* function_name, int pos, 3136 const AstRawString* function_name, int pos,
3112 const ParserFormalParameters& parameters, FunctionKind kind, 3137 const ParserFormalParameters& parameters, FunctionKind kind,
3113 FunctionLiteral::FunctionType function_type, bool* ok) { 3138 FunctionLiteral::FunctionType function_type, bool* ok) {
3114 ParsingModeScope mode(this, allow_lazy() ? PARSE_LAZILY : PARSE_EAGERLY); 3139 ParsingModeScope mode(this, allow_lazy() ? PARSE_LAZILY : PARSE_EAGERLY);
3115 ZoneList<Statement*>* result = new(zone()) ZoneList<Statement*>(8, zone()); 3140 ZoneList<Statement*>* result = new(zone()) ZoneList<Statement*>(8, zone());
3116 3141
3117 static const int kFunctionNameAssignmentIndex = 0; 3142 static const int kFunctionNameAssignmentIndex = 0;
3118 if (function_type == FunctionLiteral::kNamedExpression) { 3143 if (function_type == FunctionLiteral::kNamedExpression) {
3119 DCHECK(function_name != NULL); 3144 DCHECK(function_name != NULL);
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
3256 } else { 3281 } else {
3257 statement = factory()->NewEmptyStatement(kNoSourcePosition); 3282 statement = factory()->NewEmptyStatement(kNoSourcePosition);
3258 } 3283 }
3259 result->Set(kFunctionNameAssignmentIndex, statement); 3284 result->Set(kFunctionNameAssignmentIndex, statement);
3260 } 3285 }
3261 3286
3262 MarkCollectedTailCallExpressions(); 3287 MarkCollectedTailCallExpressions();
3263 return result; 3288 return result;
3264 } 3289 }
3265 3290
3266 PreParser::PreParseResult Parser::ParseFunctionBodyWithPreParser( 3291 PreParser::PreParseResult Parser::ParseFunctionWithPreParser(
3292 FunctionKind kind, DeclarationScope* function_scope,
3267 SingletonLogger* logger, bool is_inner_function, bool may_abort) { 3293 SingletonLogger* logger, bool is_inner_function, bool may_abort) {
3268 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.PreParse"); 3294 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.PreParse");
3269 3295
3270 DCHECK_EQ(Token::LBRACE, scanner()->current_token());
3271
3272 if (reusable_preparser_ == NULL) { 3296 if (reusable_preparser_ == NULL) {
3273 reusable_preparser_ = new PreParser(zone(), &scanner_, ast_value_factory(), 3297 reusable_preparser_ = new PreParser(zone(), &scanner_, ast_value_factory(),
3274 NULL, stack_limit_); 3298 NULL, stack_limit_);
3275 reusable_preparser_->set_allow_lazy(true); 3299 reusable_preparser_->set_allow_lazy(true);
3276 #define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name()); 3300 #define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name());
3277 SET_ALLOW(natives); 3301 SET_ALLOW(natives);
3278 SET_ALLOW(harmony_do_expressions); 3302 SET_ALLOW(harmony_do_expressions);
3279 SET_ALLOW(harmony_function_sent); 3303 SET_ALLOW(harmony_function_sent);
3280 SET_ALLOW(harmony_restrictive_declarations); 3304 SET_ALLOW(harmony_restrictive_declarations);
3281 SET_ALLOW(harmony_async_await); 3305 SET_ALLOW(harmony_async_await);
3282 SET_ALLOW(harmony_trailing_commas); 3306 SET_ALLOW(harmony_trailing_commas);
3283 SET_ALLOW(harmony_class_fields); 3307 SET_ALLOW(harmony_class_fields);
3284 #undef SET_ALLOW 3308 #undef SET_ALLOW
3285 } 3309 }
3286 // Aborting inner function preparsing would leave scopes in an inconsistent 3310 // Aborting inner function preparsing would leave scopes in an inconsistent
3287 // state; we don't parse inner functions in the abortable mode anyway. 3311 // state; we don't parse inner functions in the abortable mode anyway.
3288 DCHECK(!is_inner_function || !may_abort); 3312 DCHECK(!is_inner_function || !may_abort);
3289 3313
3290 DeclarationScope* function_scope = function_state_->scope();
3291 PreParser::PreParseResult result = reusable_preparser_->PreParseFunction( 3314 PreParser::PreParseResult result = reusable_preparser_->PreParseFunction(
3292 function_scope, parsing_module_, logger, is_inner_function, may_abort, 3315 kind, function_scope, parsing_module_, logger, is_inner_function,
3293 use_counts_); 3316 may_abort, use_counts_);
3294 return result; 3317 return result;
3295 } 3318 }
3296 3319
3297 Expression* Parser::InstallHomeObject(Expression* function_literal, 3320 Expression* Parser::InstallHomeObject(Expression* function_literal,
3298 Expression* home_object) { 3321 Expression* home_object) {
3299 Block* do_block = factory()->NewBlock(nullptr, 1, false, kNoSourcePosition); 3322 Block* do_block = factory()->NewBlock(nullptr, 1, false, kNoSourcePosition);
3300 Variable* result_var = 3323 Variable* result_var =
3301 scope()->NewTemporary(ast_value_factory()->empty_string()); 3324 scope()->NewTemporary(ast_value_factory()->empty_string());
3302 DoExpression* do_expr = 3325 DoExpression* do_expr =
3303 factory()->NewDoExpression(do_block, result_var, kNoSourcePosition); 3326 factory()->NewDoExpression(do_block, result_var, kNoSourcePosition);
(...skipping 2096 matching lines...) Expand 10 before | Expand all | Expand 10 after
5400 5423
5401 return final_loop; 5424 return final_loop;
5402 } 5425 }
5403 5426
5404 #undef CHECK_OK 5427 #undef CHECK_OK
5405 #undef CHECK_OK_VOID 5428 #undef CHECK_OK_VOID
5406 #undef CHECK_FAILED 5429 #undef CHECK_FAILED
5407 5430
5408 } // namespace internal 5431 } // namespace internal
5409 } // namespace v8 5432 } // namespace v8
OLDNEW
« no previous file with comments | « src/parsing/parser.h ('k') | src/parsing/parser-base.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698