| 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 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/api.h" | 7 #include "src/api.h" |
| 8 #include "src/ast.h" | 8 #include "src/ast.h" |
| 9 #include "src/base/platform/platform.h" | 9 #include "src/base/platform/platform.h" |
| 10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
| (...skipping 721 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 732 FunctionLiteral::FunctionType type, | 732 FunctionLiteral::FunctionType type, |
| 733 FunctionLiteral::ArityRestriction arity_restriction, | 733 FunctionLiteral::ArityRestriction arity_restriction, |
| 734 bool* ok) { | 734 bool* ok) { |
| 735 return parser_->ParseFunctionLiteral(name, function_name_location, | 735 return parser_->ParseFunctionLiteral(name, function_name_location, |
| 736 name_is_strict_reserved, is_generator, | 736 name_is_strict_reserved, is_generator, |
| 737 function_token_position, type, | 737 function_token_position, type, |
| 738 arity_restriction, ok); | 738 arity_restriction, ok); |
| 739 } | 739 } |
| 740 | 740 |
| 741 | 741 |
| 742 Parser::Parser(CompilationInfo* info) | 742 Parser::Parser(CompilationInfo* info, uintptr_t stack_limit, uint32_t hash_seed, |
| 743 : ParserBase<ParserTraits>( | 743 UnicodeCache* unicode_cache) |
| 744 &scanner_, info->isolate()->stack_guard()->real_climit(), | 744 : ParserBase<ParserTraits>(&scanner_, stack_limit, info->extension(), NULL, |
| 745 info->extension(), NULL, info->zone(), info->ast_node_id_gen(), this), | 745 info->zone(), info->ast_node_id_gen(), this), |
| 746 isolate_(info->isolate()), | 746 isolate_(info->isolate()), |
| 747 script_(info->script()), | 747 script_(info->script()), |
| 748 scanner_(isolate_->unicode_cache()), | 748 scanner_(unicode_cache), |
| 749 reusable_preparser_(NULL), | 749 reusable_preparser_(NULL), |
| 750 original_scope_(NULL), | 750 original_scope_(NULL), |
| 751 target_stack_(NULL), | 751 target_stack_(NULL), |
| 752 cached_parse_data_(NULL), | 752 cached_parse_data_(NULL), |
| 753 ast_value_factory_(NULL), | 753 ast_value_factory_(NULL), |
| 754 info_(info), | 754 info_(info), |
| 755 has_pending_error_(false), | 755 has_pending_error_(false), |
| 756 pending_error_message_(NULL), | 756 pending_error_message_(NULL), |
| 757 pending_error_arg_(NULL), | 757 pending_error_arg_(NULL), |
| 758 pending_error_char_arg_(NULL) { | 758 pending_error_char_arg_(NULL), |
| 759 total_preparse_skipped_(0), |
| 760 pre_parse_timer_(NULL), |
| 761 hash_seed_(hash_seed) { |
| 759 DCHECK(!script_.is_null()); | 762 DCHECK(!script_.is_null()); |
| 760 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); | 763 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); |
| 761 set_allow_modules(!info->is_native() && FLAG_harmony_modules); | 764 set_allow_modules(!info->is_native() && FLAG_harmony_modules); |
| 762 set_allow_natives_syntax(FLAG_allow_natives_syntax || info->is_native()); | 765 set_allow_natives_syntax(FLAG_allow_natives_syntax || info->is_native()); |
| 763 set_allow_lazy(false); // Must be explicitly enabled. | 766 set_allow_lazy(false); // Must be explicitly enabled. |
| 764 set_allow_generators(FLAG_harmony_generators); | 767 set_allow_generators(FLAG_harmony_generators); |
| 765 set_allow_arrow_functions(FLAG_harmony_arrow_functions); | 768 set_allow_arrow_functions(FLAG_harmony_arrow_functions); |
| 766 set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals); | 769 set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals); |
| 767 set_allow_classes(FLAG_harmony_classes); | 770 set_allow_classes(FLAG_harmony_classes); |
| 768 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; | 771 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; |
| 769 ++feature) { | 772 ++feature) { |
| 770 use_counts_[feature] = 0; | 773 use_counts_[feature] = 0; |
| 771 } | 774 } |
| 772 } | 775 } |
| 773 | 776 |
| 774 | 777 |
| 775 FunctionLiteral* Parser::ParseProgram() { | 778 FunctionLiteral* Parser::ParseProgram() { |
| 776 // TODO(bmeurer): We temporarily need to pass allow_nesting = true here, | 779 // TODO(bmeurer): We temporarily need to pass allow_nesting = true here, |
| 777 // see comment for HistogramTimerScope class. | 780 // see comment for HistogramTimerScope class. |
| 781 |
| 782 // It's OK to use the counters here, since this function is only called in |
| 783 // the main thread. |
| 778 HistogramTimerScope timer_scope(isolate()->counters()->parse(), true); | 784 HistogramTimerScope timer_scope(isolate()->counters()->parse(), true); |
| 779 Handle<String> source(String::cast(script_->source())); | 785 Handle<String> source(String::cast(script_->source())); |
| 780 isolate()->counters()->total_parse_size()->Increment(source->length()); | 786 isolate()->counters()->total_parse_size()->Increment(source->length()); |
| 781 base::ElapsedTimer timer; | 787 base::ElapsedTimer timer; |
| 782 if (FLAG_trace_parse) { | 788 if (FLAG_trace_parse) { |
| 783 timer.Start(); | 789 timer.Start(); |
| 784 } | 790 } |
| 785 fni_ = new(zone()) FuncNameInferrer(ast_value_factory_, zone()); | 791 fni_ = new(zone()) FuncNameInferrer(ast_value_factory_, zone()); |
| 786 | 792 |
| 787 // Initialize parser state. | 793 // Initialize parser state. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 801 // identical calls. | 807 // identical calls. |
| 802 ExternalTwoByteStringUtf16CharacterStream stream( | 808 ExternalTwoByteStringUtf16CharacterStream stream( |
| 803 Handle<ExternalTwoByteString>::cast(source), 0, source->length()); | 809 Handle<ExternalTwoByteString>::cast(source), 0, source->length()); |
| 804 scanner_.Initialize(&stream); | 810 scanner_.Initialize(&stream); |
| 805 result = DoParseProgram(info(), source); | 811 result = DoParseProgram(info(), source); |
| 806 } else { | 812 } else { |
| 807 GenericStringUtf16CharacterStream stream(source, 0, source->length()); | 813 GenericStringUtf16CharacterStream stream(source, 0, source->length()); |
| 808 scanner_.Initialize(&stream); | 814 scanner_.Initialize(&stream); |
| 809 result = DoParseProgram(info(), source); | 815 result = DoParseProgram(info(), source); |
| 810 } | 816 } |
| 817 HandleSourceURLComments(); |
| 811 | 818 |
| 812 if (FLAG_trace_parse && result != NULL) { | 819 if (FLAG_trace_parse && result != NULL) { |
| 813 double ms = timer.Elapsed().InMillisecondsF(); | 820 double ms = timer.Elapsed().InMillisecondsF(); |
| 814 if (info()->is_eval()) { | 821 if (info()->is_eval()) { |
| 815 PrintF("[parsing eval"); | 822 PrintF("[parsing eval"); |
| 816 } else if (info()->script()->name()->IsString()) { | 823 } else if (info()->script()->name()->IsString()) { |
| 817 String* name = String::cast(info()->script()->name()); | 824 String* name = String::cast(info()->script()->name()); |
| 818 SmartArrayPointer<char> name_chars = name->ToCString(); | 825 SmartArrayPointer<char> name_chars = name->ToCString(); |
| 819 PrintF("[parsing script: %s", name_chars.get()); | 826 PrintF("[parsing script: %s", name_chars.get()); |
| 820 } else { | 827 } else { |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 869 // Enters 'scope'. | 876 // Enters 'scope'. |
| 870 FunctionState function_state(&function_state_, &scope_, scope, zone(), | 877 FunctionState function_state(&function_state_, &scope_, scope, zone(), |
| 871 ast_value_factory_, info->ast_node_id_gen()); | 878 ast_value_factory_, info->ast_node_id_gen()); |
| 872 | 879 |
| 873 scope_->SetStrictMode(info->strict_mode()); | 880 scope_->SetStrictMode(info->strict_mode()); |
| 874 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); | 881 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); |
| 875 bool ok = true; | 882 bool ok = true; |
| 876 int beg_pos = scanner()->location().beg_pos; | 883 int beg_pos = scanner()->location().beg_pos; |
| 877 ParseSourceElements(body, Token::EOS, info->is_eval(), true, &ok); | 884 ParseSourceElements(body, Token::EOS, info->is_eval(), true, &ok); |
| 878 | 885 |
| 879 HandleSourceURLComments(); | |
| 880 | |
| 881 if (ok && strict_mode() == STRICT) { | 886 if (ok && strict_mode() == STRICT) { |
| 882 CheckOctalLiteral(beg_pos, scanner()->location().end_pos, &ok); | 887 CheckOctalLiteral(beg_pos, scanner()->location().end_pos, &ok); |
| 883 } | 888 } |
| 884 | 889 |
| 885 if (ok && allow_harmony_scoping() && strict_mode() == STRICT) { | 890 if (ok && allow_harmony_scoping() && strict_mode() == STRICT) { |
| 886 CheckConflictingVarDeclarations(scope_, &ok); | 891 CheckConflictingVarDeclarations(scope_, &ok); |
| 887 } | 892 } |
| 888 | 893 |
| 889 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) { | 894 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) { |
| 890 if (body->length() != 1 || | 895 if (body->length() != 1 || |
| 891 !body->at(0)->IsExpressionStatement() || | 896 !body->at(0)->IsExpressionStatement() || |
| 892 !body->at(0)->AsExpressionStatement()-> | 897 !body->at(0)->AsExpressionStatement()-> |
| 893 expression()->IsFunctionLiteral()) { | 898 expression()->IsFunctionLiteral()) { |
| 894 ReportMessage("single_function_literal"); | 899 ReportMessage("single_function_literal"); |
| 895 ok = false; | 900 ok = false; |
| 896 } | 901 } |
| 897 } | 902 } |
| 898 | 903 |
| 899 ast_value_factory_->Internalize(isolate()); | |
| 900 if (ok) { | 904 if (ok) { |
| 901 result = factory()->NewFunctionLiteral( | 905 result = factory()->NewFunctionLiteral( |
| 902 ast_value_factory_->empty_string(), ast_value_factory_, scope_, body, | 906 ast_value_factory_->empty_string(), ast_value_factory_, scope_, body, |
| 903 function_state.materialized_literal_count(), | 907 function_state.materialized_literal_count(), |
| 904 function_state.expected_property_count(), | 908 function_state.expected_property_count(), |
| 905 function_state.handler_count(), 0, | 909 function_state.handler_count(), 0, |
| 906 FunctionLiteral::kNoDuplicateParameters, | 910 FunctionLiteral::kNoDuplicateParameters, |
| 907 FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kGlobalOrEval, | 911 FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kGlobalOrEval, |
| 908 FunctionLiteral::kNotParenthesized, FunctionLiteral::kNormalFunction, | 912 FunctionLiteral::kNotParenthesized, FunctionLiteral::kNormalFunction, |
| 909 0); | 913 0); |
| 910 result->set_ast_properties(factory()->visitor()->ast_properties()); | 914 result->set_ast_properties(factory()->visitor()->ast_properties()); |
| 911 result->set_dont_optimize_reason( | 915 result->set_dont_optimize_reason( |
| 912 factory()->visitor()->dont_optimize_reason()); | 916 factory()->visitor()->dont_optimize_reason()); |
| 913 } else if (stack_overflow()) { | |
| 914 isolate()->StackOverflow(); | |
| 915 } else { | |
| 916 ThrowPendingError(); | |
| 917 } | 917 } |
| 918 } | 918 } |
| 919 | 919 |
| 920 // Make sure the target stack is empty. | 920 // Make sure the target stack is empty. |
| 921 DCHECK(target_stack_ == NULL); | 921 DCHECK(target_stack_ == NULL); |
| 922 | 922 |
| 923 return result; | 923 return result; |
| 924 } | 924 } |
| 925 | 925 |
| 926 | 926 |
| 927 FunctionLiteral* Parser::ParseLazy() { | 927 FunctionLiteral* Parser::ParseLazy() { |
| 928 // It's OK to use the counters here, since this function is only called in |
| 929 // the main thread. |
| 928 HistogramTimerScope timer_scope(isolate()->counters()->parse_lazy()); | 930 HistogramTimerScope timer_scope(isolate()->counters()->parse_lazy()); |
| 929 Handle<String> source(String::cast(script_->source())); | 931 Handle<String> source(String::cast(script_->source())); |
| 930 isolate()->counters()->total_parse_size()->Increment(source->length()); | 932 isolate()->counters()->total_parse_size()->Increment(source->length()); |
| 931 base::ElapsedTimer timer; | 933 base::ElapsedTimer timer; |
| 932 if (FLAG_trace_parse) { | 934 if (FLAG_trace_parse) { |
| 933 timer.Start(); | 935 timer.Start(); |
| 934 } | 936 } |
| 935 Handle<SharedFunctionInfo> shared_info = info()->shared_info(); | 937 Handle<SharedFunctionInfo> shared_info = info()->shared_info(); |
| 936 | 938 |
| 937 // Initialize parser state. | 939 // Initialize parser state. |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1010 function_type, | 1012 function_type, |
| 1011 FunctionLiteral::NORMAL_ARITY, &ok); | 1013 FunctionLiteral::NORMAL_ARITY, &ok); |
| 1012 } | 1014 } |
| 1013 // Make sure the results agree. | 1015 // Make sure the results agree. |
| 1014 DCHECK(ok == (result != NULL)); | 1016 DCHECK(ok == (result != NULL)); |
| 1015 } | 1017 } |
| 1016 | 1018 |
| 1017 // Make sure the target stack is empty. | 1019 // Make sure the target stack is empty. |
| 1018 DCHECK(target_stack_ == NULL); | 1020 DCHECK(target_stack_ == NULL); |
| 1019 | 1021 |
| 1020 ast_value_factory_->Internalize(isolate()); | 1022 if (result != NULL) { |
| 1021 if (result == NULL) { | |
| 1022 if (stack_overflow()) { | |
| 1023 isolate()->StackOverflow(); | |
| 1024 } else { | |
| 1025 ThrowPendingError(); | |
| 1026 } | |
| 1027 } else { | |
| 1028 Handle<String> inferred_name(shared_info->inferred_name()); | 1023 Handle<String> inferred_name(shared_info->inferred_name()); |
| 1029 result->set_inferred_name(inferred_name); | 1024 result->set_inferred_name(inferred_name); |
| 1030 } | 1025 } |
| 1031 return result; | 1026 return result; |
| 1032 } | 1027 } |
| 1033 | 1028 |
| 1034 | 1029 |
| 1035 void* Parser::ParseSourceElements(ZoneList<Statement*>* processor, | 1030 void* Parser::ParseSourceElements(ZoneList<Statement*>* processor, |
| 1036 int end_token, | 1031 int end_token, |
| 1037 bool is_eval, | 1032 bool is_eval, |
| (...skipping 2609 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3647 CHECK(entry.is_valid()); | 3642 CHECK(entry.is_valid()); |
| 3648 // End position greater than end of stream is safe, and hard to check. | 3643 // End position greater than end of stream is safe, and hard to check. |
| 3649 CHECK(entry.end_pos() > function_block_pos); | 3644 CHECK(entry.end_pos() > function_block_pos); |
| 3650 scanner()->SeekForward(entry.end_pos() - 1); | 3645 scanner()->SeekForward(entry.end_pos() - 1); |
| 3651 | 3646 |
| 3652 scope_->set_end_position(entry.end_pos()); | 3647 scope_->set_end_position(entry.end_pos()); |
| 3653 Expect(Token::RBRACE, ok); | 3648 Expect(Token::RBRACE, ok); |
| 3654 if (!*ok) { | 3649 if (!*ok) { |
| 3655 return; | 3650 return; |
| 3656 } | 3651 } |
| 3657 isolate()->counters()->total_preparse_skipped()->Increment( | 3652 total_preparse_skipped_ += scope_->end_position() - function_block_pos; |
| 3658 scope_->end_position() - function_block_pos); | |
| 3659 *materialized_literal_count = entry.literal_count(); | 3653 *materialized_literal_count = entry.literal_count(); |
| 3660 *expected_property_count = entry.property_count(); | 3654 *expected_property_count = entry.property_count(); |
| 3661 scope_->SetStrictMode(entry.strict_mode()); | 3655 scope_->SetStrictMode(entry.strict_mode()); |
| 3662 } else { | 3656 } else { |
| 3663 // With no cached data, we partially parse the function, without building an | 3657 // With no cached data, we partially parse the function, without building an |
| 3664 // AST. This gathers the data needed to build a lazy function. | 3658 // AST. This gathers the data needed to build a lazy function. |
| 3665 SingletonLogger logger; | 3659 SingletonLogger logger; |
| 3666 PreParser::PreParseResult result = | 3660 PreParser::PreParseResult result = |
| 3667 ParseLazyFunctionBodyWithPreParser(&logger); | 3661 ParseLazyFunctionBodyWithPreParser(&logger); |
| 3668 if (result == PreParser::kPreParseStackOverflow) { | 3662 if (result == PreParser::kPreParseStackOverflow) { |
| 3669 // Propagate stack overflow. | 3663 // Propagate stack overflow. |
| 3670 set_stack_overflow(); | 3664 set_stack_overflow(); |
| 3671 *ok = false; | 3665 *ok = false; |
| 3672 return; | 3666 return; |
| 3673 } | 3667 } |
| 3674 if (logger.has_error()) { | 3668 if (logger.has_error()) { |
| 3675 ParserTraits::ReportMessageAt( | 3669 ParserTraits::ReportMessageAt( |
| 3676 Scanner::Location(logger.start(), logger.end()), | 3670 Scanner::Location(logger.start(), logger.end()), |
| 3677 logger.message(), logger.argument_opt(), logger.is_reference_error()); | 3671 logger.message(), logger.argument_opt(), logger.is_reference_error()); |
| 3678 *ok = false; | 3672 *ok = false; |
| 3679 return; | 3673 return; |
| 3680 } | 3674 } |
| 3681 scope_->set_end_position(logger.end()); | 3675 scope_->set_end_position(logger.end()); |
| 3682 Expect(Token::RBRACE, ok); | 3676 Expect(Token::RBRACE, ok); |
| 3683 if (!*ok) { | 3677 if (!*ok) { |
| 3684 return; | 3678 return; |
| 3685 } | 3679 } |
| 3686 isolate()->counters()->total_preparse_skipped()->Increment( | 3680 total_preparse_skipped_ += scope_->end_position() - function_block_pos; |
| 3687 scope_->end_position() - function_block_pos); | |
| 3688 *materialized_literal_count = logger.literals(); | 3681 *materialized_literal_count = logger.literals(); |
| 3689 *expected_property_count = logger.properties(); | 3682 *expected_property_count = logger.properties(); |
| 3690 scope_->SetStrictMode(logger.strict_mode()); | 3683 scope_->SetStrictMode(logger.strict_mode()); |
| 3691 if (compile_options() == ScriptCompiler::kProduceParserCache) { | 3684 if (compile_options() == ScriptCompiler::kProduceParserCache) { |
| 3692 DCHECK(log_); | 3685 DCHECK(log_); |
| 3693 // Position right after terminal '}'. | 3686 // Position right after terminal '}'. |
| 3694 int body_end = scanner()->location().end_pos; | 3687 int body_end = scanner()->location().end_pos; |
| 3695 log_->LogFunction(function_block_pos, body_end, | 3688 log_->LogFunction(function_block_pos, body_end, |
| 3696 *materialized_literal_count, | 3689 *materialized_literal_count, |
| 3697 *expected_property_count, | 3690 *expected_property_count, |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3755 | 3748 |
| 3756 Expect(Token::RBRACE, CHECK_OK); | 3749 Expect(Token::RBRACE, CHECK_OK); |
| 3757 scope_->set_end_position(scanner()->location().end_pos); | 3750 scope_->set_end_position(scanner()->location().end_pos); |
| 3758 | 3751 |
| 3759 return body; | 3752 return body; |
| 3760 } | 3753 } |
| 3761 | 3754 |
| 3762 | 3755 |
| 3763 PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser( | 3756 PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser( |
| 3764 SingletonLogger* logger) { | 3757 SingletonLogger* logger) { |
| 3765 HistogramTimerScope preparse_scope(isolate()->counters()->pre_parse()); | 3758 // This function may be called on a background thread too; record only the |
| 3759 // main thread preparse times. |
| 3760 if (pre_parse_timer_ != NULL) { |
| 3761 pre_parse_timer_->Start(); |
| 3762 } |
| 3766 DCHECK_EQ(Token::LBRACE, scanner()->current_token()); | 3763 DCHECK_EQ(Token::LBRACE, scanner()->current_token()); |
| 3767 | 3764 |
| 3768 if (reusable_preparser_ == NULL) { | 3765 if (reusable_preparser_ == NULL) { |
| 3769 intptr_t stack_limit = isolate()->stack_guard()->real_climit(); | 3766 reusable_preparser_ = new PreParser(&scanner_, NULL, stack_limit_); |
| 3770 reusable_preparser_ = new PreParser(&scanner_, NULL, stack_limit); | |
| 3771 reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping()); | 3767 reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping()); |
| 3772 reusable_preparser_->set_allow_modules(allow_modules()); | 3768 reusable_preparser_->set_allow_modules(allow_modules()); |
| 3773 reusable_preparser_->set_allow_natives_syntax(allow_natives_syntax()); | 3769 reusable_preparser_->set_allow_natives_syntax(allow_natives_syntax()); |
| 3774 reusable_preparser_->set_allow_lazy(true); | 3770 reusable_preparser_->set_allow_lazy(true); |
| 3775 reusable_preparser_->set_allow_generators(allow_generators()); | 3771 reusable_preparser_->set_allow_generators(allow_generators()); |
| 3776 reusable_preparser_->set_allow_arrow_functions(allow_arrow_functions()); | 3772 reusable_preparser_->set_allow_arrow_functions(allow_arrow_functions()); |
| 3777 reusable_preparser_->set_allow_harmony_numeric_literals( | 3773 reusable_preparser_->set_allow_harmony_numeric_literals( |
| 3778 allow_harmony_numeric_literals()); | 3774 allow_harmony_numeric_literals()); |
| 3779 reusable_preparser_->set_allow_classes(allow_classes()); | 3775 reusable_preparser_->set_allow_classes(allow_classes()); |
| 3780 } | 3776 } |
| 3781 PreParser::PreParseResult result = | 3777 PreParser::PreParseResult result = |
| 3782 reusable_preparser_->PreParseLazyFunction(strict_mode(), | 3778 reusable_preparser_->PreParseLazyFunction(strict_mode(), |
| 3783 is_generator(), | 3779 is_generator(), |
| 3784 logger); | 3780 logger); |
| 3781 if (pre_parse_timer_ != NULL) { |
| 3782 pre_parse_timer_->Stop(); |
| 3783 } |
| 3785 return result; | 3784 return result; |
| 3786 } | 3785 } |
| 3787 | 3786 |
| 3788 | 3787 |
| 3789 Expression* Parser::ParseV8Intrinsic(bool* ok) { | 3788 Expression* Parser::ParseV8Intrinsic(bool* ok) { |
| 3790 // CallRuntime :: | 3789 // CallRuntime :: |
| 3791 // '%' Identifier Arguments | 3790 // '%' Identifier Arguments |
| 3792 | 3791 |
| 3793 int pos = peek_position(); | 3792 int pos = peek_position(); |
| 3794 Expect(Token::MOD, CHECK_OK); | 3793 Expect(Token::MOD, CHECK_OK); |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3958 Handle<Object> error; | 3957 Handle<Object> error; |
| 3959 MaybeHandle<Object> maybe_error = | 3958 MaybeHandle<Object> maybe_error = |
| 3960 pending_error_is_reference_error_ | 3959 pending_error_is_reference_error_ |
| 3961 ? factory->NewReferenceError(pending_error_message_, array) | 3960 ? factory->NewReferenceError(pending_error_message_, array) |
| 3962 : factory->NewSyntaxError(pending_error_message_, array); | 3961 : factory->NewSyntaxError(pending_error_message_, array); |
| 3963 if (maybe_error.ToHandle(&error)) isolate()->Throw(*error, &location); | 3962 if (maybe_error.ToHandle(&error)) isolate()->Throw(*error, &location); |
| 3964 } | 3963 } |
| 3965 } | 3964 } |
| 3966 | 3965 |
| 3967 | 3966 |
| 3968 void Parser::InternalizeUseCounts() { | 3967 void Parser::Internalize() { |
| 3968 // Internalize strings. |
| 3969 ast_value_factory_->Internalize(isolate()); |
| 3970 |
| 3971 // Error processing. |
| 3972 if (info()->function() == NULL) { |
| 3973 if (stack_overflow()) { |
| 3974 isolate()->StackOverflow(); |
| 3975 } else { |
| 3976 ThrowPendingError(); |
| 3977 } |
| 3978 } |
| 3979 |
| 3980 // Move statistics to Isolate. |
| 3969 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; | 3981 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; |
| 3970 ++feature) { | 3982 ++feature) { |
| 3971 for (int i = 0; i < use_counts_[feature]; ++i) { | 3983 for (int i = 0; i < use_counts_[feature]; ++i) { |
| 3972 isolate()->CountUsage(v8::Isolate::UseCounterFeature(feature)); | 3984 isolate()->CountUsage(v8::Isolate::UseCounterFeature(feature)); |
| 3973 } | 3985 } |
| 3974 } | 3986 } |
| 3987 isolate()->counters()->total_preparse_skipped()->Increment( |
| 3988 total_preparse_skipped_); |
| 3975 } | 3989 } |
| 3976 | 3990 |
| 3977 | 3991 |
| 3978 // ---------------------------------------------------------------------------- | 3992 // ---------------------------------------------------------------------------- |
| 3979 // Regular expressions | 3993 // Regular expressions |
| 3980 | 3994 |
| 3981 | 3995 |
| 3982 RegExpParser::RegExpParser(FlatStringReader* in, | 3996 RegExpParser::RegExpParser(FlatStringReader* in, |
| 3983 Handle<String>* error, | 3997 Handle<String>* error, |
| 3984 bool multiline, | 3998 bool multiline, |
| (...skipping 819 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4804 } | 4818 } |
| 4805 return !parser.failed(); | 4819 return !parser.failed(); |
| 4806 } | 4820 } |
| 4807 | 4821 |
| 4808 | 4822 |
| 4809 bool Parser::Parse() { | 4823 bool Parser::Parse() { |
| 4810 DCHECK(info()->function() == NULL); | 4824 DCHECK(info()->function() == NULL); |
| 4811 FunctionLiteral* result = NULL; | 4825 FunctionLiteral* result = NULL; |
| 4812 ast_value_factory_ = info()->ast_value_factory(); | 4826 ast_value_factory_ = info()->ast_value_factory(); |
| 4813 if (ast_value_factory_ == NULL) { | 4827 if (ast_value_factory_ == NULL) { |
| 4814 ast_value_factory_ = | 4828 ast_value_factory_ = new AstValueFactory(zone(), hash_seed_); |
| 4815 new AstValueFactory(zone(), isolate()->heap()->HashSeed()); | |
| 4816 } | 4829 } |
| 4817 if (allow_natives_syntax() || extension_ != NULL) { | 4830 if (allow_natives_syntax() || extension_ != NULL) { |
| 4818 // If intrinsics are allowed, the Parser cannot operate independent of the | 4831 // If intrinsics are allowed, the Parser cannot operate independent of the |
| 4819 // V8 heap because of Rumtime. Tell the string table to internalize strings | 4832 // V8 heap because of Rumtime. Tell the string table to internalize strings |
| 4820 // and values right after they're created. | 4833 // and values right after they're created. |
| 4821 ast_value_factory_->Internalize(isolate()); | 4834 ast_value_factory_->Internalize(isolate()); |
| 4822 } | 4835 } |
| 4823 | 4836 pre_parse_timer_ = isolate()->counters()->pre_parse(); |
| 4824 if (info()->is_lazy()) { | 4837 if (info()->is_lazy()) { |
| 4825 DCHECK(!info()->is_eval()); | 4838 DCHECK(!info()->is_eval()); |
| 4826 if (info()->shared_info()->is_function()) { | 4839 if (info()->shared_info()->is_function()) { |
| 4827 result = ParseLazy(); | 4840 result = ParseLazy(); |
| 4828 } else { | 4841 } else { |
| 4829 result = ParseProgram(); | 4842 result = ParseProgram(); |
| 4830 } | 4843 } |
| 4831 } else { | 4844 } else { |
| 4832 SetCachedData(); | 4845 SetCachedData(); |
| 4833 result = ParseProgram(); | 4846 result = ParseProgram(); |
| 4834 } | 4847 } |
| 4835 info()->SetFunction(result); | 4848 info()->SetFunction(result); |
| 4849 |
| 4850 Internalize(); |
| 4836 DCHECK(ast_value_factory_->IsInternalized()); | 4851 DCHECK(ast_value_factory_->IsInternalized()); |
| 4837 // info takes ownership of ast_value_factory_. | 4852 // info takes ownership of ast_value_factory_. |
| 4838 if (info()->ast_value_factory() == NULL) { | 4853 if (info()->ast_value_factory() == NULL) { |
| 4839 info()->SetAstValueFactory(ast_value_factory_); | 4854 info()->SetAstValueFactory(ast_value_factory_); |
| 4840 } | 4855 } |
| 4841 ast_value_factory_ = NULL; | 4856 ast_value_factory_ = NULL; |
| 4842 | |
| 4843 InternalizeUseCounts(); | |
| 4844 | |
| 4845 return (result != NULL); | 4857 return (result != NULL); |
| 4846 } | 4858 } |
| 4847 | 4859 |
| 4848 } } // namespace v8::internal | 4860 } } // namespace v8::internal |
| OLD | NEW |