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

Side by Side Diff: src/parser.cc

Issue 1091743002: Simplify DoParseProgram (Closed) Base URL: https://chromium.googlesource.com/v8/v8@master
Patch Set: Use peek location for scope end position Created 5 years, 8 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
« no previous file with comments | « src/parser.h ('k') | no next file » | 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/bailout-reason.h" 9 #include "src/bailout-reason.h"
10 #include "src/base/platform/platform.h" 10 #include "src/base/platform/platform.h"
(...skipping 896 matching lines...) Expand 10 before | Expand all | Expand 10 after
907 907
908 if (produce_cached_parse_data()) { 908 if (produce_cached_parse_data()) {
909 log_ = &recorder; 909 log_ = &recorder;
910 } else if (consume_cached_parse_data()) { 910 } else if (consume_cached_parse_data()) {
911 cached_parse_data_->Initialize(); 911 cached_parse_data_->Initialize();
912 } 912 }
913 913
914 source = String::Flatten(source); 914 source = String::Flatten(source);
915 FunctionLiteral* result; 915 FunctionLiteral* result;
916 916
917 Scope* top_scope = NULL;
918 Scope* eval_scope = NULL;
919 if (source->IsExternalTwoByteString()) { 917 if (source->IsExternalTwoByteString()) {
920 // Notice that the stream is destroyed at the end of the branch block. 918 // Notice that the stream is destroyed at the end of the branch block.
921 // The last line of the blocks can't be moved outside, even though they're 919 // The last line of the blocks can't be moved outside, even though they're
922 // identical calls. 920 // identical calls.
923 ExternalTwoByteStringUtf16CharacterStream stream( 921 ExternalTwoByteStringUtf16CharacterStream stream(
924 Handle<ExternalTwoByteString>::cast(source), 0, source->length()); 922 Handle<ExternalTwoByteString>::cast(source), 0, source->length());
925 scanner_.Initialize(&stream); 923 scanner_.Initialize(&stream);
926 result = DoParseProgram(info, &top_scope, &eval_scope); 924 result = DoParseProgram(info);
927 } else { 925 } else {
928 GenericStringUtf16CharacterStream stream(source, 0, source->length()); 926 GenericStringUtf16CharacterStream stream(source, 0, source->length());
929 scanner_.Initialize(&stream); 927 scanner_.Initialize(&stream);
930 result = DoParseProgram(info, &top_scope, &eval_scope); 928 result = DoParseProgram(info);
931 } 929 }
932 top_scope->set_end_position(source->length()); 930 if (result != NULL) {
933 if (eval_scope != NULL) { 931 DCHECK_EQ(scanner_.peek_location().beg_pos, source->length());
934 eval_scope->set_end_position(source->length());
935 } 932 }
936 HandleSourceURLComments(isolate, info->script()); 933 HandleSourceURLComments(isolate, info->script());
937 934
938 if (FLAG_trace_parse && result != NULL) { 935 if (FLAG_trace_parse && result != NULL) {
939 double ms = timer.Elapsed().InMillisecondsF(); 936 double ms = timer.Elapsed().InMillisecondsF();
940 if (info->is_eval()) { 937 if (info->is_eval()) {
941 PrintF("[parsing eval"); 938 PrintF("[parsing eval");
942 } else if (info->script()->name()->IsString()) { 939 } else if (info->script()->name()->IsString()) {
943 String* name = String::cast(info->script()->name()); 940 String* name = String::cast(info->script()->name());
944 SmartArrayPointer<char> name_chars = name->ToCString(); 941 SmartArrayPointer<char> name_chars = name->ToCString();
945 PrintF("[parsing script: %s", name_chars.get()); 942 PrintF("[parsing script: %s", name_chars.get());
946 } else { 943 } else {
947 PrintF("[parsing script"); 944 PrintF("[parsing script");
948 } 945 }
949 PrintF(" - took %0.3f ms]\n", ms); 946 PrintF(" - took %0.3f ms]\n", ms);
950 } 947 }
951 if (produce_cached_parse_data()) { 948 if (produce_cached_parse_data()) {
952 if (result != NULL) *info->cached_data() = recorder.GetScriptData(); 949 if (result != NULL) *info->cached_data() = recorder.GetScriptData();
953 log_ = NULL; 950 log_ = NULL;
954 } 951 }
955 return result; 952 return result;
956 } 953 }
957 954
958 955
959 FunctionLiteral* Parser::DoParseProgram(ParseInfo* info, Scope** scope, 956 FunctionLiteral* Parser::DoParseProgram(ParseInfo* info) {
960 Scope** eval_scope) {
961 // Note that this function can be called from the main thread or from a 957 // Note that this function can be called from the main thread or from a
962 // background thread. We should not access anything Isolate / heap dependent 958 // background thread. We should not access anything Isolate / heap dependent
963 // via ParseInfo, and also not pass it forward. 959 // via ParseInfo, and also not pass it forward.
964 DCHECK(scope_ == NULL); 960 DCHECK(scope_ == NULL);
965 DCHECK(target_stack_ == NULL); 961 DCHECK(target_stack_ == NULL);
966 962
967 FunctionLiteral* result = NULL; 963 FunctionLiteral* result = NULL;
968 { 964 {
969 *scope = NewScope(scope_, SCRIPT_SCOPE); 965 Scope* scope = NewScope(scope_, SCRIPT_SCOPE);
970 info->set_script_scope(*scope); 966 info->set_script_scope(scope);
971 if (!info->context().is_null() && !info->context()->IsNativeContext()) { 967 if (!info->context().is_null() && !info->context()->IsNativeContext()) {
972 *scope = Scope::DeserializeScopeChain(info->isolate(), zone(), 968 scope = Scope::DeserializeScopeChain(info->isolate(), zone(),
973 *info->context(), *scope); 969 *info->context(), scope);
974 // The Scope is backed up by ScopeInfo (which is in the V8 heap); this 970 // The Scope is backed up by ScopeInfo (which is in the V8 heap); this
975 // means the Parser cannot operate independent of the V8 heap. Tell the 971 // means the Parser cannot operate independent of the V8 heap. Tell the
976 // string table to internalize strings and values right after they're 972 // string table to internalize strings and values right after they're
977 // created. This kind of parsing can only be done in the main thread. 973 // created. This kind of parsing can only be done in the main thread.
978 DCHECK(parsing_on_main_thread_); 974 DCHECK(parsing_on_main_thread_);
979 ast_value_factory()->Internalize(info->isolate()); 975 ast_value_factory()->Internalize(info->isolate());
980 } 976 }
981 original_scope_ = *scope; 977 original_scope_ = scope;
982 if (info->is_eval()) { 978 if (info->is_eval()) {
983 if (!(*scope)->is_script_scope() || is_strict(info->language_mode())) { 979 if (!scope->is_script_scope() || is_strict(info->language_mode())) {
984 *scope = NewScope(*scope, EVAL_SCOPE); 980 scope = NewScope(scope, EVAL_SCOPE);
985 } 981 }
986 } else if (info->is_module()) { 982 } else if (info->is_module()) {
987 *scope = NewScope(*scope, MODULE_SCOPE); 983 scope = NewScope(scope, MODULE_SCOPE);
988 } 984 }
989 (*scope)->set_start_position(0); 985
990 // End position will be set by the caller. 986 scope->set_start_position(0);
991 987
992 // Compute the parsing mode. 988 // Compute the parsing mode.
993 Mode mode = (FLAG_lazy && allow_lazy()) ? PARSE_LAZILY : PARSE_EAGERLY; 989 Mode mode = (FLAG_lazy && allow_lazy()) ? PARSE_LAZILY : PARSE_EAGERLY;
994 if (allow_natives() || extension_ != NULL || 990 if (allow_natives() || extension_ != NULL || scope->is_eval_scope()) {
995 (*scope)->is_eval_scope()) {
996 mode = PARSE_EAGERLY; 991 mode = PARSE_EAGERLY;
997 } 992 }
998 ParsingModeScope parsing_mode(this, mode); 993 ParsingModeScope parsing_mode(this, mode);
999 994
1000 // Enters 'scope'. 995 // Enters 'scope'.
1001 AstNodeFactory function_factory(ast_value_factory()); 996 AstNodeFactory function_factory(ast_value_factory());
1002 FunctionState function_state(&function_state_, &scope_, *scope, 997 FunctionState function_state(&function_state_, &scope_, scope,
1003 kNormalFunction, &function_factory); 998 kNormalFunction, &function_factory);
1004 999
1005 scope_->SetLanguageMode(info->language_mode()); 1000 scope_->SetLanguageMode(info->language_mode());
1006 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); 1001 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone());
1007 bool ok = true; 1002 bool ok = true;
1008 int beg_pos = scanner()->location().beg_pos; 1003 int beg_pos = scanner()->location().beg_pos;
1009 if (info->is_module()) { 1004 if (info->is_module()) {
1010 DCHECK(allow_harmony_modules()); 1005 DCHECK(allow_harmony_modules());
1011 ParseModuleItemList(body, &ok); 1006 ParseModuleItemList(body, &ok);
1012 } else { 1007 } else {
1013 ParseStatementList(body, Token::EOS, info->is_eval(), eval_scope, &ok); 1008 Scope* eval_scope = nullptr;
1009 ParseStatementList(body, Token::EOS, info->is_eval(), &eval_scope, &ok);
1010 if (eval_scope != nullptr)
1011 eval_scope->set_end_position(scanner()->peek_location().beg_pos);
1014 } 1012 }
1015 1013
1014 // The parser will peek but not consume EOS. Our scope logically goes all
1015 // the way to the EOS, though.
1016 scope->set_end_position(scanner()->peek_location().beg_pos);
1017
1016 if (ok && is_strict(language_mode())) { 1018 if (ok && is_strict(language_mode())) {
1017 CheckStrictOctalLiteral(beg_pos, scanner()->location().end_pos, &ok); 1019 CheckStrictOctalLiteral(beg_pos, scanner()->location().end_pos, &ok);
1018 CheckConflictingVarDeclarations(scope_, &ok); 1020 CheckConflictingVarDeclarations(scope_, &ok);
1019 } 1021 }
1020 1022
1021 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) { 1023 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) {
1022 if (body->length() != 1 || 1024 if (body->length() != 1 ||
1023 !body->at(0)->IsExpressionStatement() || 1025 !body->at(0)->IsExpressionStatement() ||
1024 !body->at(0)->AsExpressionStatement()-> 1026 !body->at(0)->AsExpressionStatement()->
1025 expression()->IsFunctionLiteral()) { 1027 expression()->IsFunctionLiteral()) {
(...skipping 4491 matching lines...) Expand 10 before | Expand all | Expand 10 after
5517 info->source_stream_encoding()); 5519 info->source_stream_encoding());
5518 scanner_.Initialize(&stream); 5520 scanner_.Initialize(&stream);
5519 DCHECK(info->context().is_null() || info->context()->IsNativeContext()); 5521 DCHECK(info->context().is_null() || info->context()->IsNativeContext());
5520 5522
5521 // When streaming, we don't know the length of the source until we have parsed 5523 // When streaming, we don't know the length of the source until we have parsed
5522 // it. The raw data can be UTF-8, so we wouldn't know the source length until 5524 // it. The raw data can be UTF-8, so we wouldn't know the source length until
5523 // we have decoded it anyway even if we knew the raw data length (which we 5525 // we have decoded it anyway even if we knew the raw data length (which we
5524 // don't). We work around this by storing all the scopes which need their end 5526 // don't). We work around this by storing all the scopes which need their end
5525 // position set at the end of the script (the top scope and possible eval 5527 // position set at the end of the script (the top scope and possible eval
5526 // scopes) and set their end position after we know the script length. 5528 // scopes) and set their end position after we know the script length.
5527 Scope* top_scope = NULL; 5529 result = DoParseProgram(info);
5528 Scope* eval_scope = NULL;
5529 result = DoParseProgram(info, &top_scope, &eval_scope);
5530
5531 top_scope->set_end_position(scanner()->location().end_pos);
5532 if (eval_scope != NULL) {
5533 eval_scope->set_end_position(scanner()->location().end_pos);
5534 }
5535 5530
5536 info->set_literal(result); 5531 info->set_literal(result);
5537 5532
5538 // We cannot internalize on a background thread; a foreground task will take 5533 // We cannot internalize on a background thread; a foreground task will take
5539 // care of calling Parser::Internalize just before compilation. 5534 // care of calling Parser::Internalize just before compilation.
5540 5535
5541 if (produce_cached_parse_data()) { 5536 if (produce_cached_parse_data()) {
5542 if (result != NULL) *info->cached_data() = recorder.GetScriptData(); 5537 if (result != NULL) *info->cached_data() = recorder.GetScriptData();
5543 log_ = NULL; 5538 log_ = NULL;
5544 } 5539 }
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
5773 5768
5774 Expression* Parser::SpreadCallNew(Expression* function, 5769 Expression* Parser::SpreadCallNew(Expression* function,
5775 ZoneList<v8::internal::Expression*>* args, 5770 ZoneList<v8::internal::Expression*>* args,
5776 int pos) { 5771 int pos) {
5777 args->InsertAt(0, function, zone()); 5772 args->InsertAt(0, function, zone());
5778 5773
5779 return factory()->NewCallRuntime( 5774 return factory()->NewCallRuntime(
5780 ast_value_factory()->reflect_construct_string(), NULL, args, pos); 5775 ast_value_factory()->reflect_construct_string(), NULL, args, pos);
5781 } 5776 }
5782 } } // namespace v8::internal 5777 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/parser.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698