| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 #include "v8.h" | 28 #include "v8.h" |
| 29 | 29 |
| 30 #include "api.h" | 30 #include "api.h" |
| 31 #include "ast.h" | 31 #include "ast.h" |
| 32 #include "bootstrapper.h" | 32 #include "bootstrapper.h" |
| 33 #include "char-predicates-inl.h" | 33 #include "char-predicates-inl.h" |
| 34 #include "codegen.h" | 34 #include "codegen.h" |
| 35 #include "compiler.h" | 35 #include "compiler.h" |
| 36 #include "messages.h" | 36 #include "messages.h" |
| 37 #include "parser.h" | 37 #include "parser.h" |
| 38 #include "parser-thread.h" |
| 38 #include "platform.h" | 39 #include "platform.h" |
| 39 #include "preparser.h" | 40 #include "preparser.h" |
| 40 #include "runtime.h" | 41 #include "runtime.h" |
| 41 #include "scanner-character-streams.h" | 42 #include "scanner-character-streams.h" |
| 42 #include "scopeinfo.h" | 43 #include "scopeinfo.h" |
| 43 #include "string-stream.h" | 44 #include "string-stream.h" |
| 44 | 45 |
| 45 namespace v8 { | 46 namespace v8 { |
| 46 namespace internal { | 47 namespace internal { |
| 47 | 48 |
| 49 namespace { |
| 50 |
| 51 // Returns NULL if the string is not external. Caller takes ownership of the |
| 52 // returned stream. |
| 53 Utf16CharacterStream* ExternalCharacterStreamFromString(Handle<String> string) { |
| 54 if (string->IsExternalAsciiString()) { |
| 55 return new ExternalOneByteStringUtf16CharacterStream( |
| 56 Handle<ExternalAsciiString>::cast(string)->GetChars(), 0, |
| 57 string->length()); |
| 58 } |
| 59 if (string->IsExternalTwoByteString()) { |
| 60 return new ExternalTwoByteStringUtf16CharacterStream( |
| 61 Handle<ExternalTwoByteString>::cast(string)->GetTwoByteData(0), 0, |
| 62 string->length()); |
| 63 } |
| 64 return NULL; |
| 65 } |
| 66 |
| 67 } // namespace |
| 68 |
| 69 |
| 48 RegExpBuilder::RegExpBuilder(Zone* zone) | 70 RegExpBuilder::RegExpBuilder(Zone* zone) |
| 49 : zone_(zone), | 71 : zone_(zone), |
| 50 pending_empty_(false), | 72 pending_empty_(false), |
| 51 characters_(NULL), | 73 characters_(NULL), |
| 52 terms_(), | 74 terms_(), |
| 53 alternatives_() | 75 alternatives_() |
| 54 #ifdef DEBUG | 76 #ifdef DEBUG |
| 55 , last_added_(ADD_NONE) | 77 , last_added_(ADD_NONE) |
| 56 #endif | 78 #endif |
| 57 {} | 79 {} |
| (...skipping 774 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 832 name_is_strict_reserved, is_generator, | 854 name_is_strict_reserved, is_generator, |
| 833 function_token_position, type, ok); | 855 function_token_position, type, ok); |
| 834 } | 856 } |
| 835 | 857 |
| 836 | 858 |
| 837 Parser::Parser(CompilationInfo* info) | 859 Parser::Parser(CompilationInfo* info) |
| 838 : ParserBase<ParserTraits>(&scanner_, | 860 : ParserBase<ParserTraits>(&scanner_, |
| 839 info->isolate()->stack_guard()->real_climit(), | 861 info->isolate()->stack_guard()->real_climit(), |
| 840 info->extension(), | 862 info->extension(), |
| 841 NULL, | 863 NULL, |
| 864 NULL, |
| 842 info->zone(), | 865 info->zone(), |
| 843 this), | 866 this), |
| 844 isolate_(info->isolate()), | 867 isolate_(info->isolate()), |
| 845 symbol_cache_(0, info->zone()), | 868 symbol_cache_(0, info->zone()), |
| 846 script_(info->script()), | 869 script_(info->script()), |
| 847 scanner_(isolate_->unicode_cache()), | 870 scanner_(isolate_->unicode_cache()), |
| 848 reusable_preparser_(NULL), | 871 reusable_preparser_(NULL), |
| 849 original_scope_(NULL), | 872 original_scope_(NULL), |
| 850 target_stack_(NULL), | 873 target_stack_(NULL), |
| 851 cached_data_(NULL), | 874 cached_data_(NULL), |
| (...skipping 16 matching lines...) Expand all Loading... |
| 868 // see comment for HistogramTimerScope class. | 891 // see comment for HistogramTimerScope class. |
| 869 HistogramTimerScope timer_scope(isolate()->counters()->parse(), true); | 892 HistogramTimerScope timer_scope(isolate()->counters()->parse(), true); |
| 870 Handle<String> source(String::cast(script_->source())); | 893 Handle<String> source(String::cast(script_->source())); |
| 871 isolate()->counters()->total_parse_size()->Increment(source->length()); | 894 isolate()->counters()->total_parse_size()->Increment(source->length()); |
| 872 ElapsedTimer timer; | 895 ElapsedTimer timer; |
| 873 if (FLAG_trace_parse) { | 896 if (FLAG_trace_parse) { |
| 874 timer.Start(); | 897 timer.Start(); |
| 875 } | 898 } |
| 876 fni_ = new(zone()) FuncNameInferrer(isolate(), zone()); | 899 fni_ = new(zone()) FuncNameInferrer(isolate(), zone()); |
| 877 | 900 |
| 878 // Initialize parser state. | |
| 879 CompleteParserRecorder recorder; | 901 CompleteParserRecorder recorder; |
| 902 |
| 880 if (cached_data_mode_ == PRODUCE_CACHED_DATA) { | 903 if (cached_data_mode_ == PRODUCE_CACHED_DATA) { |
| 904 ASSERT(allow_lazy()); |
| 881 log_ = &recorder; | 905 log_ = &recorder; |
| 882 } else if (cached_data_mode_ == CONSUME_CACHED_DATA) { | 906 } else if (cached_data_mode_ == CONSUME_CACHED_DATA) { |
| 883 (*cached_data_)->Initialize(); | 907 (*cached_data_)->Initialize(); |
| 884 } | 908 } |
| 909 source = String::Flatten(source); |
| 910 StartFastParserTaskIfPossible(source); |
| 885 | 911 |
| 886 source = String::Flatten(source); | |
| 887 FunctionLiteral* result; | 912 FunctionLiteral* result; |
| 888 if (source->IsExternalTwoByteString()) { | 913 if (source->IsExternalTwoByteString()) { |
| 889 // Notice that the stream is destroyed at the end of the branch block. | 914 // Notice that the stream is destroyed at the end of the branch block. |
| 890 // The last line of the blocks can't be moved outside, even though they're | 915 // The last line of the blocks can't be moved outside, even though they're |
| 891 // identical calls. | 916 // identical calls. |
| 892 ExternalTwoByteStringUtf16CharacterStream stream( | 917 ExternalTwoByteStringUtf16CharacterStream stream( |
| 893 Handle<ExternalTwoByteString>::cast(source), 0, source->length()); | 918 Handle<ExternalTwoByteString>::cast(source)->GetTwoByteData(0), 0, |
| 919 source->length()); |
| 894 scanner_.Initialize(&stream); | 920 scanner_.Initialize(&stream); |
| 895 result = DoParseProgram(info(), source); | 921 result = DoParseProgram(info(), source); |
| 896 } else { | 922 } else { |
| 897 GenericStringUtf16CharacterStream stream(source, 0, source->length()); | 923 GenericStringUtf16CharacterStream stream(source, 0, source->length()); |
| 898 scanner_.Initialize(&stream); | 924 scanner_.Initialize(&stream); |
| 899 result = DoParseProgram(info(), source); | 925 result = DoParseProgram(info(), source); |
| 900 } | 926 } |
| 901 | 927 |
| 902 if (FLAG_trace_parse && result != NULL) { | 928 if (FLAG_trace_parse && result != NULL) { |
| 903 double ms = timer.Elapsed().InMillisecondsF(); | 929 double ms = timer.Elapsed().InMillisecondsF(); |
| 904 if (info()->is_eval()) { | 930 if (info()->is_eval()) { |
| 905 PrintF("[parsing eval"); | 931 PrintF("[parsing eval"); |
| 906 } else if (info()->script()->name()->IsString()) { | 932 } else if (info()->script()->name()->IsString()) { |
| 907 String* name = String::cast(info()->script()->name()); | 933 String* name = String::cast(info()->script()->name()); |
| 908 SmartArrayPointer<char> name_chars = name->ToCString(); | 934 SmartArrayPointer<char> name_chars = name->ToCString(); |
| 909 PrintF("[parsing script: %s", name_chars.get()); | 935 PrintF("[parsing script: %s", name_chars.get()); |
| 910 } else { | 936 } else { |
| 911 PrintF("[parsing script"); | 937 PrintF("[parsing script"); |
| 912 } | 938 } |
| 913 PrintF(" - took %0.3f ms]\n", ms); | 939 PrintF(" - took %0.3f ms]\n", ms); |
| 914 } | 940 } |
| 915 if (cached_data_mode_ == PRODUCE_CACHED_DATA) { | 941 if (cached_data_mode_ == PRODUCE_CACHED_DATA) { |
| 916 Vector<unsigned> store = recorder.ExtractData(); | 942 Vector<unsigned> store = recorder.ExtractData(); |
| 917 *cached_data_ = new ScriptData(store); | 943 *cached_data_ = new ScriptData(store); |
| 918 log_ = NULL; | 944 log_ = NULL; |
| 919 } | 945 } |
| 946 FinishFastParserTask(); |
| 920 return result; | 947 return result; |
| 921 } | 948 } |
| 922 | 949 |
| 923 | 950 |
| 924 FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, | 951 FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, |
| 925 Handle<String> source) { | 952 Handle<String> source) { |
| 926 ASSERT(scope_ == NULL); | 953 ASSERT(scope_ == NULL); |
| 927 ASSERT(target_stack_ == NULL); | 954 ASSERT(target_stack_ == NULL); |
| 928 | 955 |
| 929 Handle<String> no_name = isolate()->factory()->empty_string(); | 956 Handle<String> no_name = isolate()->factory()->empty_string(); |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1019 if (FLAG_trace_parse) { | 1046 if (FLAG_trace_parse) { |
| 1020 timer.Start(); | 1047 timer.Start(); |
| 1021 } | 1048 } |
| 1022 Handle<SharedFunctionInfo> shared_info = info()->shared_info(); | 1049 Handle<SharedFunctionInfo> shared_info = info()->shared_info(); |
| 1023 | 1050 |
| 1024 // Initialize parser state. | 1051 // Initialize parser state. |
| 1025 source = String::Flatten(source); | 1052 source = String::Flatten(source); |
| 1026 FunctionLiteral* result; | 1053 FunctionLiteral* result; |
| 1027 if (source->IsExternalTwoByteString()) { | 1054 if (source->IsExternalTwoByteString()) { |
| 1028 ExternalTwoByteStringUtf16CharacterStream stream( | 1055 ExternalTwoByteStringUtf16CharacterStream stream( |
| 1029 Handle<ExternalTwoByteString>::cast(source), | 1056 Handle<ExternalTwoByteString>::cast(source)->GetTwoByteData(0), |
| 1030 shared_info->start_position(), | 1057 shared_info->start_position(), |
| 1031 shared_info->end_position()); | 1058 shared_info->end_position()); |
| 1032 result = ParseLazy(&stream); | 1059 result = ParseLazy(&stream); |
| 1033 } else { | 1060 } else { |
| 1034 GenericStringUtf16CharacterStream stream(source, | 1061 GenericStringUtf16CharacterStream stream(source, |
| 1035 shared_info->start_position(), | 1062 shared_info->start_position(), |
| 1036 shared_info->end_position()); | 1063 shared_info->end_position()); |
| 1037 result = ParseLazy(&stream); | 1064 result = ParseLazy(&stream); |
| 1038 } | 1065 } |
| 1039 | 1066 |
| (...skipping 2339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3379 // that it will be compiled lazily. | 3406 // that it will be compiled lazily. |
| 3380 | 3407 |
| 3381 // To make this additional case work, both Parser and PreParser implement a | 3408 // To make this additional case work, both Parser and PreParser implement a |
| 3382 // logic where only top-level functions will be parsed lazily. | 3409 // logic where only top-level functions will be parsed lazily. |
| 3383 bool is_lazily_parsed = (mode() == PARSE_LAZILY && | 3410 bool is_lazily_parsed = (mode() == PARSE_LAZILY && |
| 3384 scope_->AllowsLazyCompilation() && | 3411 scope_->AllowsLazyCompilation() && |
| 3385 !parenthesized_function_); | 3412 !parenthesized_function_); |
| 3386 parenthesized_function_ = false; // The bit was set for this function only. | 3413 parenthesized_function_ = false; // The bit was set for this function only. |
| 3387 | 3414 |
| 3388 if (is_lazily_parsed) { | 3415 if (is_lazily_parsed) { |
| 3389 SkipLazyFunctionBody(function_name, &materialized_literal_count, | 3416 int function_block_pos = position(); |
| 3390 &expected_property_count, CHECK_OK); | 3417 StrictMode strict_mode; |
| 3418 SkipLazyFunctionBody( |
| 3419 function_name, function_block_pos, &materialized_literal_count, |
| 3420 &expected_property_count, &strict_mode, CHECK_OK); |
| 3421 scope_->SetStrictMode(strict_mode); |
| 3422 Expect(Token::RBRACE, CHECK_OK); |
| 3423 // Position right after terminal '}'. |
| 3424 int body_end = scanner()->location().end_pos; |
| 3425 scope_->set_end_position(body_end); |
| 3426 isolate()->counters()->total_preparse_skipped()->Increment( |
| 3427 body_end - function_block_pos); |
| 3428 if (cached_data_mode_ == PRODUCE_CACHED_DATA) { |
| 3429 ASSERT(log_); |
| 3430 log_->LogFunction(function_block_pos, body_end, |
| 3431 materialized_literal_count, expected_property_count, |
| 3432 strict_mode); |
| 3433 } |
| 3391 } else { | 3434 } else { |
| 3392 body = ParseEagerFunctionBody(function_name, pos, fvar, fvar_init_op, | 3435 body = ParseEagerFunctionBody(function_name, pos, fvar, fvar_init_op, |
| 3393 is_generator, CHECK_OK); | 3436 is_generator, CHECK_OK); |
| 3394 materialized_literal_count = function_state.materialized_literal_count(); | 3437 materialized_literal_count = function_state.materialized_literal_count(); |
| 3395 expected_property_count = function_state.expected_property_count(); | 3438 expected_property_count = function_state.expected_property_count(); |
| 3396 handler_count = function_state.handler_count(); | 3439 handler_count = function_state.handler_count(); |
| 3397 } | 3440 } |
| 3398 | 3441 |
| 3399 // Validate strict mode. We can do this only after parsing the function, | 3442 // Validate strict mode. We can do this only after parsing the function, |
| 3400 // since the function can declare itself strict. | 3443 // since the function can declare itself strict. |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3458 function_literal->set_ast_properties(&ast_properties); | 3501 function_literal->set_ast_properties(&ast_properties); |
| 3459 function_literal->set_slot_processor(slot_processor); | 3502 function_literal->set_slot_processor(slot_processor); |
| 3460 function_literal->set_dont_optimize_reason(dont_optimize_reason); | 3503 function_literal->set_dont_optimize_reason(dont_optimize_reason); |
| 3461 | 3504 |
| 3462 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal); | 3505 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal); |
| 3463 return function_literal; | 3506 return function_literal; |
| 3464 } | 3507 } |
| 3465 | 3508 |
| 3466 | 3509 |
| 3467 void Parser::SkipLazyFunctionBody(Handle<String> function_name, | 3510 void Parser::SkipLazyFunctionBody(Handle<String> function_name, |
| 3511 int function_block_pos, |
| 3468 int* materialized_literal_count, | 3512 int* materialized_literal_count, |
| 3469 int* expected_property_count, | 3513 int* expected_property_count, |
| 3514 StrictMode* strict_mode, |
| 3470 bool* ok) { | 3515 bool* ok) { |
| 3471 int function_block_pos = position(); | |
| 3472 if (cached_data_mode_ == CONSUME_CACHED_DATA) { | 3516 if (cached_data_mode_ == CONSUME_CACHED_DATA) { |
| 3473 // If we have cached data, we use it to skip parsing the function body. The | 3517 // If we have cached data, we use it to skip parsing the function body. The |
| 3474 // data contains the information we need to construct the lazy function. | 3518 // data contains the information we need to construct the lazy function. |
| 3475 FunctionEntry entry = | 3519 FunctionEntry entry = |
| 3476 (*cached_data())->GetFunctionEntry(function_block_pos); | 3520 (*cached_data())->GetFunctionEntry(function_block_pos); |
| 3477 if (entry.is_valid()) { | 3521 if (entry.is_valid()) { |
| 3478 if (entry.end_pos() <= function_block_pos) { | 3522 if (entry.end_pos() <= function_block_pos) { |
| 3479 // End position greater than end of stream is safe, and hard to check. | 3523 // End position greater than end of stream is safe, and hard to check. |
| 3480 ReportInvalidCachedData(function_name, ok); | 3524 ReportInvalidCachedData(function_name, ok); |
| 3481 if (!*ok) { | 3525 return; |
| 3482 return; | |
| 3483 } | |
| 3484 } | 3526 } |
| 3485 scanner()->SeekForward(entry.end_pos() - 1); | 3527 scanner()->SeekForward(entry.end_pos() - 1); |
| 3486 | |
| 3487 scope_->set_end_position(entry.end_pos()); | |
| 3488 Expect(Token::RBRACE, ok); | |
| 3489 if (!*ok) { | |
| 3490 return; | |
| 3491 } | |
| 3492 isolate()->counters()->total_preparse_skipped()->Increment( | |
| 3493 scope_->end_position() - function_block_pos); | |
| 3494 *materialized_literal_count = entry.literal_count(); | 3528 *materialized_literal_count = entry.literal_count(); |
| 3495 *expected_property_count = entry.property_count(); | 3529 *expected_property_count = entry.property_count(); |
| 3496 scope_->SetStrictMode(entry.strict_mode()); | 3530 *strict_mode = entry.strict_mode(); |
| 3497 } else { | 3531 } else { |
| 3498 // This case happens when we have preparse data but it doesn't contain an | 3532 // This case happens when we have preparse data but it doesn't contain an |
| 3499 // entry for the function. Fail the compilation. | 3533 // entry for the function. Fail the compilation. |
| 3500 ReportInvalidCachedData(function_name, ok); | 3534 ReportInvalidCachedData(function_name, ok); |
| 3501 return; | 3535 return; |
| 3502 } | 3536 } |
| 3537 } else if (thread_) { |
| 3538 int start, end; |
| 3539 // This will wait until the background thread has found the lazy function. |
| 3540 thread_->Consume(&start, &end, materialized_literal_count, |
| 3541 expected_property_count, strict_mode); |
| 3542 if (start == function_block_pos) { |
| 3543 scanner()->SeekForward(end - 1); |
| 3544 } else { |
| 3545 ProcessErrorFromRecorder(thread_->result(), thread_->recorder(), ok); |
| 3546 // If there is no error, the thread produced data for a lazy function |
| 3547 // which was not the function we expected. That should never happen. |
| 3548 ASSERT(!*ok); |
| 3549 *ok = false; |
| 3550 FinishFastParserTask(); |
| 3551 } |
| 3503 } else { | 3552 } else { |
| 3504 // With no cached data, we partially parse the function, without building an | 3553 // With no cached data, we partially parse the function, without building an |
| 3505 // AST. This gathers the data needed to build a lazy function. | 3554 // AST. This gathers the data needed to build a lazy function. The PreParser |
| 3555 // uses the same scanner, so it will be automatically positioned in the |
| 3556 // right position without additional seeking. |
| 3506 SingletonLogger logger; | 3557 SingletonLogger logger; |
| 3507 PreParser::PreParseResult result = | 3558 PreParser::PreParseResult result = |
| 3508 ParseLazyFunctionBodyWithPreParser(&logger); | 3559 ParseLazyFunctionBodyWithPreParser(&logger); |
| 3509 if (result == PreParser::kPreParseStackOverflow) { | 3560 ProcessErrorFromRecorder(result, &logger, ok); |
| 3510 // Propagate stack overflow. | |
| 3511 set_stack_overflow(); | |
| 3512 *ok = false; | |
| 3513 return; | |
| 3514 } | |
| 3515 if (logger.has_error()) { | |
| 3516 const char* arg = logger.argument_opt(); | |
| 3517 Vector<const char*> args; | |
| 3518 if (arg != NULL) { | |
| 3519 args = Vector<const char*>(&arg, 1); | |
| 3520 } | |
| 3521 ParserTraits::ReportMessageAt( | |
| 3522 Scanner::Location(logger.start(), logger.end()), | |
| 3523 logger.message(), args, logger.is_reference_error()); | |
| 3524 *ok = false; | |
| 3525 return; | |
| 3526 } | |
| 3527 scope_->set_end_position(logger.end()); | |
| 3528 Expect(Token::RBRACE, ok); | |
| 3529 if (!*ok) { | 3561 if (!*ok) { |
| 3530 return; | 3562 return; |
| 3531 } | 3563 } |
| 3532 isolate()->counters()->total_preparse_skipped()->Increment( | |
| 3533 scope_->end_position() - function_block_pos); | |
| 3534 *materialized_literal_count = logger.literals(); | 3564 *materialized_literal_count = logger.literals(); |
| 3535 *expected_property_count = logger.properties(); | 3565 *expected_property_count = logger.properties(); |
| 3536 scope_->SetStrictMode(logger.strict_mode()); | 3566 *strict_mode = logger.strict_mode(); |
| 3537 if (cached_data_mode_ == PRODUCE_CACHED_DATA) { | |
| 3538 ASSERT(log_); | |
| 3539 // Position right after terminal '}'. | |
| 3540 int body_end = scanner()->location().end_pos; | |
| 3541 log_->LogFunction(function_block_pos, body_end, | |
| 3542 *materialized_literal_count, | |
| 3543 *expected_property_count, | |
| 3544 scope_->strict_mode()); | |
| 3545 } | |
| 3546 } | 3567 } |
| 3547 } | 3568 } |
| 3548 | 3569 |
| 3570 |
| 3571 void Parser::ProcessErrorFromRecorder(PreParser::PreParseResult result, |
| 3572 const SingletonLogger* logger, bool* ok) { |
| 3573 if (result == PreParser::kPreParseStackOverflow) { |
| 3574 set_stack_overflow(); |
| 3575 *ok = false; |
| 3576 } else if (logger->has_error()) { |
| 3577 const char* arg = logger->argument_opt(); |
| 3578 Vector<const char*> args; |
| 3579 if (arg != NULL) { |
| 3580 args = Vector<const char*>(&arg, 1); |
| 3581 } |
| 3582 ParserTraits::ReportMessageAt( |
| 3583 Scanner::Location(logger->start(), logger->end()), |
| 3584 logger->message(), args, logger->is_reference_error()); |
| 3585 *ok = false; |
| 3586 } |
| 3587 } |
| 3588 |
| 3549 | 3589 |
| 3550 ZoneList<Statement*>* Parser::ParseEagerFunctionBody( | 3590 ZoneList<Statement*>* Parser::ParseEagerFunctionBody( |
| 3551 Handle<String> function_name, int pos, Variable* fvar, | 3591 Handle<String> function_name, int pos, Variable* fvar, |
| 3552 Token::Value fvar_init_op, bool is_generator, bool* ok) { | 3592 Token::Value fvar_init_op, bool is_generator, bool* ok) { |
| 3553 // Everything inside an eagerly parsed function will be parsed eagerly | 3593 // Everything inside an eagerly parsed function will be parsed eagerly |
| 3554 // (see comment above). | 3594 // (see comment above). |
| 3555 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); | 3595 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); |
| 3556 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(8, zone()); | 3596 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(8, zone()); |
| 3557 if (fvar != NULL) { | 3597 if (fvar != NULL) { |
| 3558 VariableProxy* fproxy = scope_->NewUnresolved( | 3598 VariableProxy* fproxy = scope_->NewUnresolved( |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3606 } | 3646 } |
| 3607 | 3647 |
| 3608 | 3648 |
| 3609 PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser( | 3649 PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser( |
| 3610 SingletonLogger* logger) { | 3650 SingletonLogger* logger) { |
| 3611 HistogramTimerScope preparse_scope(isolate()->counters()->pre_parse()); | 3651 HistogramTimerScope preparse_scope(isolate()->counters()->pre_parse()); |
| 3612 ASSERT_EQ(Token::LBRACE, scanner()->current_token()); | 3652 ASSERT_EQ(Token::LBRACE, scanner()->current_token()); |
| 3613 | 3653 |
| 3614 if (reusable_preparser_ == NULL) { | 3654 if (reusable_preparser_ == NULL) { |
| 3615 intptr_t stack_limit = isolate()->stack_guard()->real_climit(); | 3655 intptr_t stack_limit = isolate()->stack_guard()->real_climit(); |
| 3616 reusable_preparser_ = new PreParser(&scanner_, NULL, stack_limit); | 3656 reusable_preparser_ = new PreParser(&scanner_, NULL, stack_limit, NULL); |
| 3617 reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping()); | 3657 reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping()); |
| 3618 reusable_preparser_->set_allow_modules(allow_modules()); | 3658 reusable_preparser_->set_allow_modules(allow_modules()); |
| 3619 reusable_preparser_->set_allow_natives_syntax(allow_natives_syntax()); | 3659 reusable_preparser_->set_allow_natives_syntax(allow_natives_syntax()); |
| 3620 reusable_preparser_->set_allow_lazy(true); | 3660 reusable_preparser_->set_allow_lazy(true); |
| 3621 reusable_preparser_->set_allow_generators(allow_generators()); | 3661 reusable_preparser_->set_allow_generators(allow_generators()); |
| 3622 reusable_preparser_->set_allow_for_of(allow_for_of()); | 3662 reusable_preparser_->set_allow_for_of(allow_for_of()); |
| 3623 reusable_preparser_->set_allow_harmony_numeric_literals( | 3663 reusable_preparser_->set_allow_harmony_numeric_literals( |
| 3624 allow_harmony_numeric_literals()); | 3664 allow_harmony_numeric_literals()); |
| 3625 } | 3665 } |
| 3626 PreParser::PreParseResult result = | 3666 PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction( |
| 3627 reusable_preparser_->PreParseLazyFunction(strict_mode(), | 3667 strict_mode(), is_generator(), logger); |
| 3628 is_generator(), | |
| 3629 logger); | |
| 3630 return result; | 3668 return result; |
| 3631 } | 3669 } |
| 3632 | 3670 |
| 3633 | 3671 |
| 3672 void Parser::StartFastParserTaskIfPossible(Handle<String> source) { |
| 3673 if (cached_data_mode_ == PRODUCE_CACHED_DATA && FLAG_parallel_parse && |
| 3674 source->length() >= FLAG_min_parallel_parse_length) { |
| 3675 Utf16CharacterStream* stream = ExternalCharacterStreamFromString(source); |
| 3676 if (stream) { |
| 3677 ASSERT(isolate()->fast_parser_thread()); |
| 3678 thread_ = isolate()->fast_parser_thread(); |
| 3679 thread_->StartBackgroundParsing(stream, allow_harmony_scoping(), |
| 3680 allow_modules(), allow_natives_syntax(), |
| 3681 allow_generators(), allow_for_of(), |
| 3682 allow_harmony_numeric_literals()); |
| 3683 } |
| 3684 } |
| 3685 } |
| 3686 |
| 3687 |
| 3688 void Parser::FinishFastParserTask() { |
| 3689 if (thread_) { |
| 3690 thread_->FinishBackgroundParsing(); |
| 3691 thread_ = NULL; |
| 3692 } |
| 3693 } |
| 3694 |
| 3695 |
| 3634 Expression* Parser::ParseV8Intrinsic(bool* ok) { | 3696 Expression* Parser::ParseV8Intrinsic(bool* ok) { |
| 3635 // CallRuntime :: | 3697 // CallRuntime :: |
| 3636 // '%' Identifier Arguments | 3698 // '%' Identifier Arguments |
| 3637 | 3699 |
| 3638 int pos = peek_position(); | 3700 int pos = peek_position(); |
| 3639 Expect(Token::MOD, CHECK_OK); | 3701 Expect(Token::MOD, CHECK_OK); |
| 3640 // Allow "eval" or "arguments" for backward compatibility. | 3702 // Allow "eval" or "arguments" for backward compatibility. |
| 3641 Handle<String> name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); | 3703 Handle<String> name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
| 3642 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); | 3704 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); |
| 3643 | 3705 |
| (...skipping 1049 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4693 ASSERT(info()->isolate()->has_pending_exception()); | 4755 ASSERT(info()->isolate()->has_pending_exception()); |
| 4694 } else { | 4756 } else { |
| 4695 result = ParseProgram(); | 4757 result = ParseProgram(); |
| 4696 } | 4758 } |
| 4697 } | 4759 } |
| 4698 info()->SetFunction(result); | 4760 info()->SetFunction(result); |
| 4699 return (result != NULL); | 4761 return (result != NULL); |
| 4700 } | 4762 } |
| 4701 | 4763 |
| 4702 } } // namespace v8::internal | 4764 } } // namespace v8::internal |
| OLD | NEW |