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

Side by Side Diff: src/parser.cc

Issue 545203003: Revert "Add script streaming API." (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 3 months 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 | Annotate | Revision Log
« no previous file with comments | « src/parser.h ('k') | src/scanner-character-streams.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/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 732 matching lines...) Expand 10 before | Expand all | Expand 10 after
743 original_scope_(NULL), 743 original_scope_(NULL),
744 target_stack_(NULL), 744 target_stack_(NULL),
745 cached_parse_data_(NULL), 745 cached_parse_data_(NULL),
746 info_(info), 746 info_(info),
747 has_pending_error_(false), 747 has_pending_error_(false),
748 pending_error_message_(NULL), 748 pending_error_message_(NULL),
749 pending_error_arg_(NULL), 749 pending_error_arg_(NULL),
750 pending_error_char_arg_(NULL), 750 pending_error_char_arg_(NULL),
751 total_preparse_skipped_(0), 751 total_preparse_skipped_(0),
752 pre_parse_timer_(NULL) { 752 pre_parse_timer_(NULL) {
753 DCHECK(!script().is_null() || info->source_stream() != NULL); 753 DCHECK(!script().is_null());
754 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); 754 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping);
755 set_allow_modules(!info->is_native() && FLAG_harmony_modules); 755 set_allow_modules(!info->is_native() && FLAG_harmony_modules);
756 set_allow_natives_syntax(FLAG_allow_natives_syntax || info->is_native()); 756 set_allow_natives_syntax(FLAG_allow_natives_syntax || info->is_native());
757 set_allow_lazy(false); // Must be explicitly enabled. 757 set_allow_lazy(false); // Must be explicitly enabled.
758 set_allow_generators(FLAG_harmony_generators); 758 set_allow_generators(FLAG_harmony_generators);
759 set_allow_arrow_functions(FLAG_harmony_arrow_functions); 759 set_allow_arrow_functions(FLAG_harmony_arrow_functions);
760 set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals); 760 set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals);
761 set_allow_classes(FLAG_harmony_classes); 761 set_allow_classes(FLAG_harmony_classes);
762 set_allow_harmony_object_literals(FLAG_harmony_object_literals); 762 set_allow_harmony_object_literals(FLAG_harmony_object_literals);
763 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; 763 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
(...skipping 27 matching lines...) Expand all
791 CompleteParserRecorder recorder; 791 CompleteParserRecorder recorder;
792 792
793 if (compile_options() == ScriptCompiler::kProduceParserCache) { 793 if (compile_options() == ScriptCompiler::kProduceParserCache) {
794 log_ = &recorder; 794 log_ = &recorder;
795 } else if (compile_options() == ScriptCompiler::kConsumeParserCache) { 795 } else if (compile_options() == ScriptCompiler::kConsumeParserCache) {
796 cached_parse_data_->Initialize(); 796 cached_parse_data_->Initialize();
797 } 797 }
798 798
799 source = String::Flatten(source); 799 source = String::Flatten(source);
800 FunctionLiteral* result; 800 FunctionLiteral* result;
801
802 Scope* top_scope = NULL;
803 Scope* eval_scope = NULL;
804 if (source->IsExternalTwoByteString()) { 801 if (source->IsExternalTwoByteString()) {
805 // Notice that the stream is destroyed at the end of the branch block. 802 // Notice that the stream is destroyed at the end of the branch block.
806 // The last line of the blocks can't be moved outside, even though they're 803 // The last line of the blocks can't be moved outside, even though they're
807 // identical calls. 804 // identical calls.
808 ExternalTwoByteStringUtf16CharacterStream stream( 805 ExternalTwoByteStringUtf16CharacterStream stream(
809 Handle<ExternalTwoByteString>::cast(source), 0, source->length()); 806 Handle<ExternalTwoByteString>::cast(source), 0, source->length());
810 scanner_.Initialize(&stream); 807 scanner_.Initialize(&stream);
811 result = DoParseProgram(info(), &top_scope, &eval_scope); 808 result = DoParseProgram(info(), source);
812 } else { 809 } else {
813 GenericStringUtf16CharacterStream stream(source, 0, source->length()); 810 GenericStringUtf16CharacterStream stream(source, 0, source->length());
814 scanner_.Initialize(&stream); 811 scanner_.Initialize(&stream);
815 result = DoParseProgram(info(), &top_scope, &eval_scope); 812 result = DoParseProgram(info(), source);
816 }
817 top_scope->set_end_position(source->length());
818 if (eval_scope != NULL) {
819 eval_scope->set_end_position(source->length());
820 } 813 }
821 HandleSourceURLComments(); 814 HandleSourceURLComments();
822 815
823 if (FLAG_trace_parse && result != NULL) { 816 if (FLAG_trace_parse && result != NULL) {
824 double ms = timer.Elapsed().InMillisecondsF(); 817 double ms = timer.Elapsed().InMillisecondsF();
825 if (info()->is_eval()) { 818 if (info()->is_eval()) {
826 PrintF("[parsing eval"); 819 PrintF("[parsing eval");
827 } else if (info()->script()->name()->IsString()) { 820 } else if (info()->script()->name()->IsString()) {
828 String* name = String::cast(info()->script()->name()); 821 String* name = String::cast(info()->script()->name());
829 SmartArrayPointer<char> name_chars = name->ToCString(); 822 SmartArrayPointer<char> name_chars = name->ToCString();
830 PrintF("[parsing script: %s", name_chars.get()); 823 PrintF("[parsing script: %s", name_chars.get());
831 } else { 824 } else {
832 PrintF("[parsing script"); 825 PrintF("[parsing script");
833 } 826 }
834 PrintF(" - took %0.3f ms]\n", ms); 827 PrintF(" - took %0.3f ms]\n", ms);
835 } 828 }
836 if (compile_options() == ScriptCompiler::kProduceParserCache) { 829 if (compile_options() == ScriptCompiler::kProduceParserCache) {
837 if (result != NULL) *info_->cached_data() = recorder.GetScriptData(); 830 if (result != NULL) *info_->cached_data() = recorder.GetScriptData();
838 log_ = NULL; 831 log_ = NULL;
839 } 832 }
840 return result; 833 return result;
841 } 834 }
842 835
843 836
844 FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, Scope** scope, 837 FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info,
845 Scope** eval_scope) { 838 Handle<String> source) {
846 DCHECK(scope_ == NULL); 839 DCHECK(scope_ == NULL);
847 DCHECK(target_stack_ == NULL); 840 DCHECK(target_stack_ == NULL);
848 841
849 FunctionLiteral* result = NULL; 842 FunctionLiteral* result = NULL;
850 { 843 { Scope* scope = NewScope(scope_, GLOBAL_SCOPE);
851 *scope = NewScope(scope_, GLOBAL_SCOPE); 844 info->SetGlobalScope(scope);
852 info->SetGlobalScope(*scope);
853 if (!info->context().is_null() && !info->context()->IsNativeContext()) { 845 if (!info->context().is_null() && !info->context()->IsNativeContext()) {
854 *scope = Scope::DeserializeScopeChain(*info->context(), *scope, zone()); 846 scope = Scope::DeserializeScopeChain(*info->context(), scope, zone());
855 // The Scope is backed up by ScopeInfo (which is in the V8 heap); this 847 // The Scope is backed up by ScopeInfo (which is in the V8 heap); this
856 // means the Parser cannot operate independent of the V8 heap. Tell the 848 // means the Parser cannot operate independent of the V8 heap. Tell the
857 // string table to internalize strings and values right after they're 849 // string table to internalize strings and values right after they're
858 // created. 850 // created.
859 ast_value_factory()->Internalize(isolate()); 851 ast_value_factory()->Internalize(isolate());
860 } 852 }
861 original_scope_ = *scope; 853 original_scope_ = scope;
862 if (info->is_eval()) { 854 if (info->is_eval()) {
863 if (!(*scope)->is_global_scope() || info->strict_mode() == STRICT) { 855 if (!scope->is_global_scope() || info->strict_mode() == STRICT) {
864 *scope = NewScope(*scope, EVAL_SCOPE); 856 scope = NewScope(scope, EVAL_SCOPE);
865 } 857 }
866 } else if (info->is_global()) { 858 } else if (info->is_global()) {
867 *scope = NewScope(*scope, GLOBAL_SCOPE); 859 scope = NewScope(scope, GLOBAL_SCOPE);
868 } 860 }
869 (*scope)->set_start_position(0); 861 scope->set_start_position(0);
870 // End position will be set by the caller. 862 scope->set_end_position(source->length());
871 863
872 // Compute the parsing mode. 864 // Compute the parsing mode.
873 Mode mode = (FLAG_lazy && allow_lazy()) ? PARSE_LAZILY : PARSE_EAGERLY; 865 Mode mode = (FLAG_lazy && allow_lazy()) ? PARSE_LAZILY : PARSE_EAGERLY;
874 if (allow_natives_syntax() || extension_ != NULL || 866 if (allow_natives_syntax() ||
875 (*scope)->is_eval_scope()) { 867 extension_ != NULL ||
868 scope->is_eval_scope()) {
876 mode = PARSE_EAGERLY; 869 mode = PARSE_EAGERLY;
877 } 870 }
878 ParsingModeScope parsing_mode(this, mode); 871 ParsingModeScope parsing_mode(this, mode);
879 872
880 // Enters 'scope'. 873 // Enters 'scope'.
881 FunctionState function_state(&function_state_, &scope_, *scope, zone(), 874 FunctionState function_state(&function_state_, &scope_, scope, zone(),
882 ast_value_factory(), info->ast_node_id_gen()); 875 ast_value_factory(), info->ast_node_id_gen());
883 876
884 scope_->SetStrictMode(info->strict_mode()); 877 scope_->SetStrictMode(info->strict_mode());
885 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); 878 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone());
886 bool ok = true; 879 bool ok = true;
887 int beg_pos = scanner()->location().beg_pos; 880 int beg_pos = scanner()->location().beg_pos;
888 ParseSourceElements(body, Token::EOS, info->is_eval(), true, eval_scope, 881 ParseSourceElements(body, Token::EOS, info->is_eval(), true, &ok);
889 &ok);
890 882
891 if (ok && strict_mode() == STRICT) { 883 if (ok && strict_mode() == STRICT) {
892 CheckOctalLiteral(beg_pos, scanner()->location().end_pos, &ok); 884 CheckOctalLiteral(beg_pos, scanner()->location().end_pos, &ok);
893 } 885 }
894 886
895 if (ok && allow_harmony_scoping() && strict_mode() == STRICT) { 887 if (ok && allow_harmony_scoping() && strict_mode() == STRICT) {
896 CheckConflictingVarDeclarations(scope_, &ok); 888 CheckConflictingVarDeclarations(scope_, &ok);
897 } 889 }
898 890
899 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) { 891 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) {
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
1024 1016
1025 if (result != NULL) { 1017 if (result != NULL) {
1026 Handle<String> inferred_name(shared_info->inferred_name()); 1018 Handle<String> inferred_name(shared_info->inferred_name());
1027 result->set_inferred_name(inferred_name); 1019 result->set_inferred_name(inferred_name);
1028 } 1020 }
1029 return result; 1021 return result;
1030 } 1022 }
1031 1023
1032 1024
1033 void* Parser::ParseSourceElements(ZoneList<Statement*>* processor, 1025 void* Parser::ParseSourceElements(ZoneList<Statement*>* processor,
1034 int end_token, bool is_eval, bool is_global, 1026 int end_token,
1035 Scope** eval_scope, bool* ok) { 1027 bool is_eval,
1028 bool is_global,
1029 bool* ok) {
1036 // SourceElements :: 1030 // SourceElements ::
1037 // (ModuleElement)* <end_token> 1031 // (ModuleElement)* <end_token>
1038 1032
1039 // Allocate a target stack to use for this set of source 1033 // Allocate a target stack to use for this set of source
1040 // elements. This way, all scripts and functions get their own 1034 // elements. This way, all scripts and functions get their own
1041 // target stack thus avoiding illegal breaks and continues across 1035 // target stack thus avoiding illegal breaks and continues across
1042 // functions. 1036 // functions.
1043 TargetScope scope(&this->target_stack_); 1037 TargetScope scope(&this->target_stack_);
1044 1038
1045 DCHECK(processor != NULL); 1039 DCHECK(processor != NULL);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1081 // as specified in ES5 10.4.2(3). The correct fix would be to always 1075 // as specified in ES5 10.4.2(3). The correct fix would be to always
1082 // add this scope in DoParseProgram(), but that requires adaptations 1076 // add this scope in DoParseProgram(), but that requires adaptations
1083 // all over the code base, so we go with a quick-fix for now. 1077 // all over the code base, so we go with a quick-fix for now.
1084 // In the same manner, we have to patch the parsing mode. 1078 // In the same manner, we have to patch the parsing mode.
1085 if (is_eval && !scope_->is_eval_scope()) { 1079 if (is_eval && !scope_->is_eval_scope()) {
1086 DCHECK(scope_->is_global_scope()); 1080 DCHECK(scope_->is_global_scope());
1087 Scope* scope = NewScope(scope_, EVAL_SCOPE); 1081 Scope* scope = NewScope(scope_, EVAL_SCOPE);
1088 scope->set_start_position(scope_->start_position()); 1082 scope->set_start_position(scope_->start_position());
1089 scope->set_end_position(scope_->end_position()); 1083 scope->set_end_position(scope_->end_position());
1090 scope_ = scope; 1084 scope_ = scope;
1091 if (eval_scope != NULL) {
1092 // Caller will correct the positions of the ad hoc eval scope.
1093 *eval_scope = scope;
1094 }
1095 mode_ = PARSE_EAGERLY; 1085 mode_ = PARSE_EAGERLY;
1096 } 1086 }
1097 scope_->SetStrictMode(STRICT); 1087 scope_->SetStrictMode(STRICT);
1098 // "use strict" is the only directive for now. 1088 // "use strict" is the only directive for now.
1099 directive_prologue = false; 1089 directive_prologue = false;
1100 } else if (literal->raw_value()->AsString() == 1090 } else if (literal->raw_value()->AsString() ==
1101 ast_value_factory()->use_asm_string() && 1091 ast_value_factory()->use_asm_string() &&
1102 token_loc.end_pos - token_loc.beg_pos == 1092 token_loc.end_pos - token_loc.beg_pos ==
1103 ast_value_factory()->use_asm_string()->length() + 2) { 1093 ast_value_factory()->use_asm_string()->length() + 2) {
1104 // Store the usage count; The actual use counter on the isolate is 1094 // Store the usage count; The actual use counter on the isolate is
(...skipping 2620 matching lines...) Expand 10 before | Expand all | Expand 10 after
3725 Assignment* assignment = factory()->NewAssignment( 3715 Assignment* assignment = factory()->NewAssignment(
3726 Token::INIT_VAR, init_proxy, allocation, RelocInfo::kNoPosition); 3716 Token::INIT_VAR, init_proxy, allocation, RelocInfo::kNoPosition);
3727 VariableProxy* get_proxy = factory()->NewVariableProxy( 3717 VariableProxy* get_proxy = factory()->NewVariableProxy(
3728 function_state_->generator_object_variable()); 3718 function_state_->generator_object_variable());
3729 Yield* yield = factory()->NewYield( 3719 Yield* yield = factory()->NewYield(
3730 get_proxy, assignment, Yield::kInitial, RelocInfo::kNoPosition); 3720 get_proxy, assignment, Yield::kInitial, RelocInfo::kNoPosition);
3731 body->Add(factory()->NewExpressionStatement( 3721 body->Add(factory()->NewExpressionStatement(
3732 yield, RelocInfo::kNoPosition), zone()); 3722 yield, RelocInfo::kNoPosition), zone());
3733 } 3723 }
3734 3724
3735 ParseSourceElements(body, Token::RBRACE, false, false, NULL, CHECK_OK); 3725 ParseSourceElements(body, Token::RBRACE, false, false, CHECK_OK);
3736 3726
3737 if (is_generator) { 3727 if (is_generator) {
3738 VariableProxy* get_proxy = factory()->NewVariableProxy( 3728 VariableProxy* get_proxy = factory()->NewVariableProxy(
3739 function_state_->generator_object_variable()); 3729 function_state_->generator_object_variable());
3740 Expression* undefined = 3730 Expression* undefined =
3741 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition); 3731 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition);
3742 Yield* yield = factory()->NewYield(get_proxy, undefined, Yield::kFinal, 3732 Yield* yield = factory()->NewYield(get_proxy, undefined, Yield::kFinal,
3743 RelocInfo::kNoPosition); 3733 RelocInfo::kNoPosition);
3744 body->Add(factory()->NewExpressionStatement( 3734 body->Add(factory()->NewExpressionStatement(
3745 yield, RelocInfo::kNoPosition), zone()); 3735 yield, RelocInfo::kNoPosition), zone());
(...skipping 1096 matching lines...) Expand 10 before | Expand all | Expand 10 after
4842 SetCachedData(); 4832 SetCachedData();
4843 result = ParseProgram(); 4833 result = ParseProgram();
4844 } 4834 }
4845 info()->SetFunction(result); 4835 info()->SetFunction(result);
4846 4836
4847 Internalize(); 4837 Internalize();
4848 DCHECK(ast_value_factory()->IsInternalized()); 4838 DCHECK(ast_value_factory()->IsInternalized());
4849 return (result != NULL); 4839 return (result != NULL);
4850 } 4840 }
4851 4841
4852
4853 void Parser::ParseOnBackground() {
4854 DCHECK(info()->function() == NULL);
4855 FunctionLiteral* result = NULL;
4856 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
4857
4858 CompleteParserRecorder recorder;
4859 if (compile_options() == ScriptCompiler::kProduceParserCache) {
4860 log_ = &recorder;
4861 }
4862
4863 DCHECK(info()->source_stream() != NULL);
4864 ExternalStreamingStream stream(info()->source_stream(),
4865 info()->source_stream_encoding());
4866 scanner_.Initialize(&stream);
4867 DCHECK(info()->context().is_null() || info()->context()->IsNativeContext());
4868
4869 // When streaming, we don't know the length of the source until we have parsed
4870 // it. The raw data can be UTF-8, so we wouldn't know the source length until
4871 // we have decoded it anyway even if we knew the raw data length (which we
4872 // don't). We work around this by storing all the scopes which need their end
4873 // position set at the end of the script (the top scope and possible eval
4874 // scopes) and set their end position after we know the script length.
4875 Scope* top_scope = NULL;
4876 Scope* eval_scope = NULL;
4877 result = DoParseProgram(info(), &top_scope, &eval_scope);
4878
4879 top_scope->set_end_position(scanner()->location().end_pos);
4880 if (eval_scope != NULL) {
4881 eval_scope->set_end_position(scanner()->location().end_pos);
4882 }
4883
4884 info()->SetFunction(result);
4885
4886 // We cannot internalize on a background thread; a foreground task will take
4887 // care of calling Parser::Internalize just before compilation.
4888
4889 if (compile_options() == ScriptCompiler::kProduceParserCache) {
4890 if (result != NULL) *info_->cached_data() = recorder.GetScriptData();
4891 log_ = NULL;
4892 }
4893 }
4894 } } // namespace v8::internal 4842 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/parser.h ('k') | src/scanner-character-streams.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698