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/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 Loading... | |
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 } | |
932 top_scope->set_end_position(source->length()); | |
933 if (eval_scope != NULL) { | |
934 eval_scope->set_end_position(source->length()); | |
935 } | 929 } |
936 HandleSourceURLComments(isolate, info->script()); | 930 HandleSourceURLComments(isolate, info->script()); |
937 | 931 |
938 if (FLAG_trace_parse && result != NULL) { | 932 if (FLAG_trace_parse && result != NULL) { |
939 double ms = timer.Elapsed().InMillisecondsF(); | 933 double ms = timer.Elapsed().InMillisecondsF(); |
940 if (info->is_eval()) { | 934 if (info->is_eval()) { |
941 PrintF("[parsing eval"); | 935 PrintF("[parsing eval"); |
942 } else if (info->script()->name()->IsString()) { | 936 } else if (info->script()->name()->IsString()) { |
943 String* name = String::cast(info->script()->name()); | 937 String* name = String::cast(info->script()->name()); |
944 SmartArrayPointer<char> name_chars = name->ToCString(); | 938 SmartArrayPointer<char> name_chars = name->ToCString(); |
945 PrintF("[parsing script: %s", name_chars.get()); | 939 PrintF("[parsing script: %s", name_chars.get()); |
946 } else { | 940 } else { |
947 PrintF("[parsing script"); | 941 PrintF("[parsing script"); |
948 } | 942 } |
949 PrintF(" - took %0.3f ms]\n", ms); | 943 PrintF(" - took %0.3f ms]\n", ms); |
950 } | 944 } |
951 if (produce_cached_parse_data()) { | 945 if (produce_cached_parse_data()) { |
952 if (result != NULL) *info->cached_data() = recorder.GetScriptData(); | 946 if (result != NULL) *info->cached_data() = recorder.GetScriptData(); |
953 log_ = NULL; | 947 log_ = NULL; |
954 } | 948 } |
955 return result; | 949 return result; |
956 } | 950 } |
957 | 951 |
958 | 952 |
959 FunctionLiteral* Parser::DoParseProgram(ParseInfo* info, Scope** scope, | 953 FunctionLiteral* Parser::DoParseProgram(ParseInfo* info) { |
960 Scope** eval_scope) { | |
961 // Note that this function can be called from the main thread or from a | 954 // 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 | 955 // background thread. We should not access anything Isolate / heap dependent |
963 // via ParseInfo, and also not pass it forward. | 956 // via ParseInfo, and also not pass it forward. |
964 DCHECK(scope_ == NULL); | 957 DCHECK(scope_ == NULL); |
965 DCHECK(target_stack_ == NULL); | 958 DCHECK(target_stack_ == NULL); |
966 | 959 |
967 FunctionLiteral* result = NULL; | 960 FunctionLiteral* result = NULL; |
968 { | 961 { |
969 *scope = NewScope(scope_, SCRIPT_SCOPE); | 962 Scope* scope = NewScope(scope_, SCRIPT_SCOPE); |
970 info->set_script_scope(*scope); | 963 info->set_script_scope(scope); |
971 if (!info->context().is_null() && !info->context()->IsNativeContext()) { | 964 if (!info->context().is_null() && !info->context()->IsNativeContext()) { |
972 *scope = Scope::DeserializeScopeChain(info->isolate(), zone(), | 965 scope = Scope::DeserializeScopeChain(info->isolate(), zone(), |
973 *info->context(), *scope); | 966 *info->context(), scope); |
974 // The Scope is backed up by ScopeInfo (which is in the V8 heap); this | 967 // 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 | 968 // means the Parser cannot operate independent of the V8 heap. Tell the |
976 // string table to internalize strings and values right after they're | 969 // 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. | 970 // created. This kind of parsing can only be done in the main thread. |
978 DCHECK(parsing_on_main_thread_); | 971 DCHECK(parsing_on_main_thread_); |
979 ast_value_factory()->Internalize(info->isolate()); | 972 ast_value_factory()->Internalize(info->isolate()); |
980 } | 973 } |
981 original_scope_ = *scope; | 974 original_scope_ = scope; |
982 if (info->is_eval()) { | 975 if (info->is_eval()) { |
983 if (!(*scope)->is_script_scope() || is_strict(info->language_mode())) { | 976 if (!scope->is_script_scope() || is_strict(info->language_mode())) { |
984 *scope = NewScope(*scope, EVAL_SCOPE); | 977 scope = NewScope(scope, EVAL_SCOPE); |
985 } | 978 } |
986 } else if (info->is_module()) { | 979 } else if (info->is_module()) { |
987 *scope = NewScope(*scope, MODULE_SCOPE); | 980 scope = NewScope(scope, MODULE_SCOPE); |
988 } | 981 } |
989 (*scope)->set_start_position(0); | 982 |
990 // End position will be set by the caller. | 983 scope->set_start_position(0); |
991 | 984 |
992 // Compute the parsing mode. | 985 // Compute the parsing mode. |
993 Mode mode = (FLAG_lazy && allow_lazy()) ? PARSE_LAZILY : PARSE_EAGERLY; | 986 Mode mode = (FLAG_lazy && allow_lazy()) ? PARSE_LAZILY : PARSE_EAGERLY; |
994 if (allow_natives() || extension_ != NULL || | 987 if (allow_natives() || extension_ != NULL || scope->is_eval_scope()) { |
995 (*scope)->is_eval_scope()) { | |
996 mode = PARSE_EAGERLY; | 988 mode = PARSE_EAGERLY; |
997 } | 989 } |
998 ParsingModeScope parsing_mode(this, mode); | 990 ParsingModeScope parsing_mode(this, mode); |
999 | 991 |
1000 // Enters 'scope'. | 992 // Enters 'scope'. |
1001 AstNodeFactory function_factory(ast_value_factory()); | 993 AstNodeFactory function_factory(ast_value_factory()); |
1002 FunctionState function_state(&function_state_, &scope_, *scope, | 994 FunctionState function_state(&function_state_, &scope_, scope, |
1003 kNormalFunction, &function_factory); | 995 kNormalFunction, &function_factory); |
1004 | 996 |
1005 scope_->SetLanguageMode(info->language_mode()); | 997 scope_->SetLanguageMode(info->language_mode()); |
1006 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); | 998 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); |
1007 bool ok = true; | 999 bool ok = true; |
1008 int beg_pos = scanner()->location().beg_pos; | 1000 int beg_pos = scanner()->location().beg_pos; |
1009 if (info->is_module()) { | 1001 if (info->is_module()) { |
1010 DCHECK(allow_harmony_modules()); | 1002 DCHECK(allow_harmony_modules()); |
1011 ParseModuleItemList(body, &ok); | 1003 ParseModuleItemList(body, &ok); |
1012 } else { | 1004 } else { |
1013 ParseStatementList(body, Token::EOS, info->is_eval(), eval_scope, &ok); | 1005 Scope* eval_scope = NULL; |
marja
2015/04/15 13:11:23
nullptr
wingo
2015/04/15 13:14:52
Done.
| |
1006 ParseStatementList(body, Token::EOS, info->is_eval(), &eval_scope, &ok); | |
1007 if (eval_scope != nullptr) | |
1008 eval_scope->set_end_position(scanner()->location().end_pos); | |
1014 } | 1009 } |
1015 | 1010 |
1011 scope->set_end_position(scanner()->location().end_pos); | |
1012 | |
1016 if (ok && is_strict(language_mode())) { | 1013 if (ok && is_strict(language_mode())) { |
1017 CheckStrictOctalLiteral(beg_pos, scanner()->location().end_pos, &ok); | 1014 CheckStrictOctalLiteral(beg_pos, scanner()->location().end_pos, &ok); |
1018 CheckConflictingVarDeclarations(scope_, &ok); | 1015 CheckConflictingVarDeclarations(scope_, &ok); |
1019 } | 1016 } |
1020 | 1017 |
1021 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) { | 1018 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) { |
1022 if (body->length() != 1 || | 1019 if (body->length() != 1 || |
1023 !body->at(0)->IsExpressionStatement() || | 1020 !body->at(0)->IsExpressionStatement() || |
1024 !body->at(0)->AsExpressionStatement()-> | 1021 !body->at(0)->AsExpressionStatement()-> |
1025 expression()->IsFunctionLiteral()) { | 1022 expression()->IsFunctionLiteral()) { |
(...skipping 4491 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5517 info->source_stream_encoding()); | 5514 info->source_stream_encoding()); |
5518 scanner_.Initialize(&stream); | 5515 scanner_.Initialize(&stream); |
5519 DCHECK(info->context().is_null() || info->context()->IsNativeContext()); | 5516 DCHECK(info->context().is_null() || info->context()->IsNativeContext()); |
5520 | 5517 |
5521 // When streaming, we don't know the length of the source until we have parsed | 5518 // 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 | 5519 // 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 | 5520 // 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 | 5521 // 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 | 5522 // 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. | 5523 // scopes) and set their end position after we know the script length. |
5527 Scope* top_scope = NULL; | 5524 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 | 5525 |
5536 info->set_literal(result); | 5526 info->set_literal(result); |
5537 | 5527 |
5538 // We cannot internalize on a background thread; a foreground task will take | 5528 // We cannot internalize on a background thread; a foreground task will take |
5539 // care of calling Parser::Internalize just before compilation. | 5529 // care of calling Parser::Internalize just before compilation. |
5540 | 5530 |
5541 if (produce_cached_parse_data()) { | 5531 if (produce_cached_parse_data()) { |
5542 if (result != NULL) *info->cached_data() = recorder.GetScriptData(); | 5532 if (result != NULL) *info->cached_data() = recorder.GetScriptData(); |
5543 log_ = NULL; | 5533 log_ = NULL; |
5544 } | 5534 } |
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5773 | 5763 |
5774 Expression* Parser::SpreadCallNew(Expression* function, | 5764 Expression* Parser::SpreadCallNew(Expression* function, |
5775 ZoneList<v8::internal::Expression*>* args, | 5765 ZoneList<v8::internal::Expression*>* args, |
5776 int pos) { | 5766 int pos) { |
5777 args->InsertAt(0, function, zone()); | 5767 args->InsertAt(0, function, zone()); |
5778 | 5768 |
5779 return factory()->NewCallRuntime( | 5769 return factory()->NewCallRuntime( |
5780 ast_value_factory()->reflect_construct_string(), NULL, args, pos); | 5770 ast_value_factory()->reflect_construct_string(), NULL, args, pos); |
5781 } | 5771 } |
5782 } } // namespace v8::internal | 5772 } } // namespace v8::internal |
OLD | NEW |