| 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 "v8.h" | 5 #include "v8.h" |
| 6 | 6 |
| 7 #include "api.h" | 7 #include "api.h" |
| 8 #include "ast.h" | 8 #include "ast.h" |
| 9 #include "bootstrapper.h" | 9 #include "bootstrapper.h" |
| 10 #include "char-predicates-inl.h" | 10 #include "char-predicates-inl.h" |
| 11 #include "codegen.h" | 11 #include "codegen.h" |
| 12 #include "compiler.h" | 12 #include "compiler.h" |
| 13 #include "messages.h" | 13 #include "messages.h" |
| 14 #include "parser.h" | 14 #include "parser.h" |
| 15 #include "parser-thread.h" |
| 15 #include "platform.h" | 16 #include "platform.h" |
| 16 #include "preparser.h" | 17 #include "preparser.h" |
| 17 #include "runtime.h" | 18 #include "runtime.h" |
| 18 #include "scanner-character-streams.h" | 19 #include "scanner-character-streams.h" |
| 19 #include "scopeinfo.h" | 20 #include "scopeinfo.h" |
| 20 #include "string-stream.h" | 21 #include "string-stream.h" |
| 21 | 22 |
| 22 namespace v8 { | 23 namespace v8 { |
| 23 namespace internal { | 24 namespace internal { |
| 24 | 25 |
| 26 namespace { |
| 27 |
| 28 // Returns NULL if the string is not external. Caller takes ownership of the |
| 29 // returned stream. |
| 30 Utf16CharacterStream* ExternalCharacterStreamFromString(Handle<String> string) { |
| 31 if (string->IsExternalAsciiString()) { |
| 32 return new ExternalOneByteStringUtf16CharacterStream( |
| 33 Handle<ExternalAsciiString>::cast(string)->GetChars(), 0, |
| 34 string->length()); |
| 35 } |
| 36 if (string->IsExternalTwoByteString()) { |
| 37 return new ExternalTwoByteStringUtf16CharacterStream( |
| 38 Handle<ExternalTwoByteString>::cast(string)->GetTwoByteData(0), 0, |
| 39 string->length()); |
| 40 } |
| 41 return NULL; |
| 42 } |
| 43 |
| 44 } // namespace |
| 45 |
| 46 |
| 25 RegExpBuilder::RegExpBuilder(Zone* zone) | 47 RegExpBuilder::RegExpBuilder(Zone* zone) |
| 26 : zone_(zone), | 48 : zone_(zone), |
| 27 pending_empty_(false), | 49 pending_empty_(false), |
| 28 characters_(NULL), | 50 characters_(NULL), |
| 29 terms_(), | 51 terms_(), |
| 30 alternatives_() | 52 alternatives_() |
| 31 #ifdef DEBUG | 53 #ifdef DEBUG |
| 32 , last_added_(ADD_NONE) | 54 , last_added_(ADD_NONE) |
| 33 #endif | 55 #endif |
| 34 {} | 56 {} |
| (...skipping 738 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 773 name_is_strict_reserved, is_generator, | 795 name_is_strict_reserved, is_generator, |
| 774 function_token_position, type, ok); | 796 function_token_position, type, ok); |
| 775 } | 797 } |
| 776 | 798 |
| 777 | 799 |
| 778 Parser::Parser(CompilationInfo* info) | 800 Parser::Parser(CompilationInfo* info) |
| 779 : ParserBase<ParserTraits>(&scanner_, | 801 : ParserBase<ParserTraits>(&scanner_, |
| 780 info->isolate()->stack_guard()->real_climit(), | 802 info->isolate()->stack_guard()->real_climit(), |
| 781 info->extension(), | 803 info->extension(), |
| 782 NULL, | 804 NULL, |
| 805 NULL, |
| 783 info->zone(), | 806 info->zone(), |
| 784 this), | 807 this), |
| 785 isolate_(info->isolate()), | 808 isolate_(info->isolate()), |
| 786 script_(info->script()), | 809 script_(info->script()), |
| 787 scanner_(isolate_->unicode_cache()), | 810 scanner_(isolate_->unicode_cache()), |
| 788 reusable_preparser_(NULL), | 811 reusable_preparser_(NULL), |
| 789 original_scope_(NULL), | 812 original_scope_(NULL), |
| 790 target_stack_(NULL), | 813 target_stack_(NULL), |
| 791 cached_data_(NULL), | 814 cached_data_(NULL), |
| 792 cached_data_mode_(NO_CACHED_DATA), | 815 cached_data_mode_(NO_CACHED_DATA), |
| (...skipping 15 matching lines...) Expand all Loading... |
| 808 // see comment for HistogramTimerScope class. | 831 // see comment for HistogramTimerScope class. |
| 809 HistogramTimerScope timer_scope(isolate()->counters()->parse(), true); | 832 HistogramTimerScope timer_scope(isolate()->counters()->parse(), true); |
| 810 Handle<String> source(String::cast(script_->source())); | 833 Handle<String> source(String::cast(script_->source())); |
| 811 isolate()->counters()->total_parse_size()->Increment(source->length()); | 834 isolate()->counters()->total_parse_size()->Increment(source->length()); |
| 812 ElapsedTimer timer; | 835 ElapsedTimer timer; |
| 813 if (FLAG_trace_parse) { | 836 if (FLAG_trace_parse) { |
| 814 timer.Start(); | 837 timer.Start(); |
| 815 } | 838 } |
| 816 fni_ = new(zone()) FuncNameInferrer(isolate(), zone()); | 839 fni_ = new(zone()) FuncNameInferrer(isolate(), zone()); |
| 817 | 840 |
| 818 // Initialize parser state. | |
| 819 CompleteParserRecorder recorder; | 841 CompleteParserRecorder recorder; |
| 842 |
| 820 if (cached_data_mode_ == PRODUCE_CACHED_DATA) { | 843 if (cached_data_mode_ == PRODUCE_CACHED_DATA) { |
| 844 ASSERT(allow_lazy()); |
| 821 log_ = &recorder; | 845 log_ = &recorder; |
| 822 } else if (cached_data_mode_ == CONSUME_CACHED_DATA) { | 846 } else if (cached_data_mode_ == CONSUME_CACHED_DATA) { |
| 823 (*cached_data_)->Initialize(); | 847 (*cached_data_)->Initialize(); |
| 824 } | 848 } |
| 849 source = String::Flatten(source); |
| 850 StartFastParserTaskIfPossible(source); |
| 825 | 851 |
| 826 source = String::Flatten(source); | |
| 827 FunctionLiteral* result; | 852 FunctionLiteral* result; |
| 828 if (source->IsExternalTwoByteString()) { | 853 if (source->IsExternalTwoByteString()) { |
| 829 // Notice that the stream is destroyed at the end of the branch block. | 854 // Notice that the stream is destroyed at the end of the branch block. |
| 830 // The last line of the blocks can't be moved outside, even though they're | 855 // The last line of the blocks can't be moved outside, even though they're |
| 831 // identical calls. | 856 // identical calls. |
| 832 ExternalTwoByteStringUtf16CharacterStream stream( | 857 ExternalTwoByteStringUtf16CharacterStream stream( |
| 833 Handle<ExternalTwoByteString>::cast(source), 0, source->length()); | 858 Handle<ExternalTwoByteString>::cast(source)->GetTwoByteData(0), 0, |
| 859 source->length()); |
| 834 scanner_.Initialize(&stream); | 860 scanner_.Initialize(&stream); |
| 835 result = DoParseProgram(info(), source); | 861 result = DoParseProgram(info(), source); |
| 836 } else { | 862 } else { |
| 837 GenericStringUtf16CharacterStream stream(source, 0, source->length()); | 863 GenericStringUtf16CharacterStream stream(source, 0, source->length()); |
| 838 scanner_.Initialize(&stream); | 864 scanner_.Initialize(&stream); |
| 839 result = DoParseProgram(info(), source); | 865 result = DoParseProgram(info(), source); |
| 840 } | 866 } |
| 841 | 867 |
| 842 if (FLAG_trace_parse && result != NULL) { | 868 if (FLAG_trace_parse && result != NULL) { |
| 843 double ms = timer.Elapsed().InMillisecondsF(); | 869 double ms = timer.Elapsed().InMillisecondsF(); |
| 844 if (info()->is_eval()) { | 870 if (info()->is_eval()) { |
| 845 PrintF("[parsing eval"); | 871 PrintF("[parsing eval"); |
| 846 } else if (info()->script()->name()->IsString()) { | 872 } else if (info()->script()->name()->IsString()) { |
| 847 String* name = String::cast(info()->script()->name()); | 873 String* name = String::cast(info()->script()->name()); |
| 848 SmartArrayPointer<char> name_chars = name->ToCString(); | 874 SmartArrayPointer<char> name_chars = name->ToCString(); |
| 849 PrintF("[parsing script: %s", name_chars.get()); | 875 PrintF("[parsing script: %s", name_chars.get()); |
| 850 } else { | 876 } else { |
| 851 PrintF("[parsing script"); | 877 PrintF("[parsing script"); |
| 852 } | 878 } |
| 853 PrintF(" - took %0.3f ms]\n", ms); | 879 PrintF(" - took %0.3f ms]\n", ms); |
| 854 } | 880 } |
| 855 if (cached_data_mode_ == PRODUCE_CACHED_DATA) { | 881 if (cached_data_mode_ == PRODUCE_CACHED_DATA) { |
| 856 if (result != NULL) { | 882 if (result != NULL) { |
| 857 Vector<unsigned> store = recorder.ExtractData(); | 883 Vector<unsigned> store = recorder.ExtractData(); |
| 858 *cached_data_ = new ScriptData(store); | 884 *cached_data_ = new ScriptData(store); |
| 859 } | 885 } |
| 860 log_ = NULL; | 886 log_ = NULL; |
| 861 } | 887 } |
| 888 FinishFastParserTask(); |
| 862 return result; | 889 return result; |
| 863 } | 890 } |
| 864 | 891 |
| 865 | 892 |
| 866 FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, | 893 FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, |
| 867 Handle<String> source) { | 894 Handle<String> source) { |
| 868 ASSERT(scope_ == NULL); | 895 ASSERT(scope_ == NULL); |
| 869 ASSERT(target_stack_ == NULL); | 896 ASSERT(target_stack_ == NULL); |
| 870 | 897 |
| 871 Handle<String> no_name = isolate()->factory()->empty_string(); | 898 Handle<String> no_name = isolate()->factory()->empty_string(); |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 960 if (FLAG_trace_parse) { | 987 if (FLAG_trace_parse) { |
| 961 timer.Start(); | 988 timer.Start(); |
| 962 } | 989 } |
| 963 Handle<SharedFunctionInfo> shared_info = info()->shared_info(); | 990 Handle<SharedFunctionInfo> shared_info = info()->shared_info(); |
| 964 | 991 |
| 965 // Initialize parser state. | 992 // Initialize parser state. |
| 966 source = String::Flatten(source); | 993 source = String::Flatten(source); |
| 967 FunctionLiteral* result; | 994 FunctionLiteral* result; |
| 968 if (source->IsExternalTwoByteString()) { | 995 if (source->IsExternalTwoByteString()) { |
| 969 ExternalTwoByteStringUtf16CharacterStream stream( | 996 ExternalTwoByteStringUtf16CharacterStream stream( |
| 970 Handle<ExternalTwoByteString>::cast(source), | 997 Handle<ExternalTwoByteString>::cast(source)->GetTwoByteData(0), |
| 971 shared_info->start_position(), | 998 shared_info->start_position(), |
| 972 shared_info->end_position()); | 999 shared_info->end_position()); |
| 973 result = ParseLazy(&stream); | 1000 result = ParseLazy(&stream); |
| 974 } else { | 1001 } else { |
| 975 GenericStringUtf16CharacterStream stream(source, | 1002 GenericStringUtf16CharacterStream stream(source, |
| 976 shared_info->start_position(), | 1003 shared_info->start_position(), |
| 977 shared_info->end_position()); | 1004 shared_info->end_position()); |
| 978 result = ParseLazy(&stream); | 1005 result = ParseLazy(&stream); |
| 979 } | 1006 } |
| 980 | 1007 |
| (...skipping 2319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3300 // that it will be compiled lazily. | 3327 // that it will be compiled lazily. |
| 3301 | 3328 |
| 3302 // To make this additional case work, both Parser and PreParser implement a | 3329 // To make this additional case work, both Parser and PreParser implement a |
| 3303 // logic where only top-level functions will be parsed lazily. | 3330 // logic where only top-level functions will be parsed lazily. |
| 3304 bool is_lazily_parsed = (mode() == PARSE_LAZILY && | 3331 bool is_lazily_parsed = (mode() == PARSE_LAZILY && |
| 3305 scope_->AllowsLazyCompilation() && | 3332 scope_->AllowsLazyCompilation() && |
| 3306 !parenthesized_function_); | 3333 !parenthesized_function_); |
| 3307 parenthesized_function_ = false; // The bit was set for this function only. | 3334 parenthesized_function_ = false; // The bit was set for this function only. |
| 3308 | 3335 |
| 3309 if (is_lazily_parsed) { | 3336 if (is_lazily_parsed) { |
| 3310 SkipLazyFunctionBody(function_name, &materialized_literal_count, | 3337 int function_block_pos = position(); |
| 3311 &expected_property_count, CHECK_OK); | 3338 StrictMode strict_mode; |
| 3339 SkipLazyFunctionBody( |
| 3340 function_name, function_block_pos, &materialized_literal_count, |
| 3341 &expected_property_count, &strict_mode, CHECK_OK); |
| 3342 scope_->SetStrictMode(strict_mode); |
| 3343 Expect(Token::RBRACE, CHECK_OK); |
| 3344 // Position right after terminal '}'. |
| 3345 int body_end = scanner()->location().end_pos; |
| 3346 scope_->set_end_position(body_end); |
| 3347 isolate()->counters()->total_preparse_skipped()->Increment( |
| 3348 body_end - function_block_pos); |
| 3349 if (cached_data_mode_ == PRODUCE_CACHED_DATA) { |
| 3350 ASSERT(log_); |
| 3351 log_->LogFunction(function_block_pos, body_end, |
| 3352 materialized_literal_count, expected_property_count, |
| 3353 strict_mode); |
| 3354 } |
| 3312 } else { | 3355 } else { |
| 3313 body = ParseEagerFunctionBody(function_name, pos, fvar, fvar_init_op, | 3356 body = ParseEagerFunctionBody(function_name, pos, fvar, fvar_init_op, |
| 3314 is_generator, CHECK_OK); | 3357 is_generator, CHECK_OK); |
| 3315 materialized_literal_count = function_state.materialized_literal_count(); | 3358 materialized_literal_count = function_state.materialized_literal_count(); |
| 3316 expected_property_count = function_state.expected_property_count(); | 3359 expected_property_count = function_state.expected_property_count(); |
| 3317 handler_count = function_state.handler_count(); | 3360 handler_count = function_state.handler_count(); |
| 3318 } | 3361 } |
| 3319 | 3362 |
| 3320 // Validate strict mode. We can do this only after parsing the function, | 3363 // Validate strict mode. We can do this only after parsing the function, |
| 3321 // since the function can declare itself strict. | 3364 // since the function can declare itself strict. |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3377 function_literal->set_function_token_position(function_token_pos); | 3420 function_literal->set_function_token_position(function_token_pos); |
| 3378 function_literal->set_ast_properties(&ast_properties); | 3421 function_literal->set_ast_properties(&ast_properties); |
| 3379 function_literal->set_dont_optimize_reason(dont_optimize_reason); | 3422 function_literal->set_dont_optimize_reason(dont_optimize_reason); |
| 3380 | 3423 |
| 3381 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal); | 3424 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal); |
| 3382 return function_literal; | 3425 return function_literal; |
| 3383 } | 3426 } |
| 3384 | 3427 |
| 3385 | 3428 |
| 3386 void Parser::SkipLazyFunctionBody(Handle<String> function_name, | 3429 void Parser::SkipLazyFunctionBody(Handle<String> function_name, |
| 3430 int function_block_pos, |
| 3387 int* materialized_literal_count, | 3431 int* materialized_literal_count, |
| 3388 int* expected_property_count, | 3432 int* expected_property_count, |
| 3433 StrictMode* strict_mode, |
| 3389 bool* ok) { | 3434 bool* ok) { |
| 3390 int function_block_pos = position(); | |
| 3391 if (cached_data_mode_ == CONSUME_CACHED_DATA) { | 3435 if (cached_data_mode_ == CONSUME_CACHED_DATA) { |
| 3392 // If we have cached data, we use it to skip parsing the function body. The | 3436 // If we have cached data, we use it to skip parsing the function body. The |
| 3393 // data contains the information we need to construct the lazy function. | 3437 // data contains the information we need to construct the lazy function. |
| 3394 FunctionEntry entry = | 3438 FunctionEntry entry = |
| 3395 (*cached_data())->GetFunctionEntry(function_block_pos); | 3439 (*cached_data())->GetFunctionEntry(function_block_pos); |
| 3396 if (entry.is_valid()) { | 3440 if (entry.is_valid()) { |
| 3397 if (entry.end_pos() <= function_block_pos) { | 3441 if (entry.end_pos() <= function_block_pos) { |
| 3398 // End position greater than end of stream is safe, and hard to check. | 3442 // End position greater than end of stream is safe, and hard to check. |
| 3399 ReportInvalidCachedData(function_name, ok); | 3443 ReportInvalidCachedData(function_name, ok); |
| 3400 if (!*ok) { | 3444 return; |
| 3401 return; | |
| 3402 } | |
| 3403 } | 3445 } |
| 3404 scanner()->SeekForward(entry.end_pos() - 1); | 3446 scanner()->SeekForward(entry.end_pos() - 1); |
| 3405 | |
| 3406 scope_->set_end_position(entry.end_pos()); | |
| 3407 Expect(Token::RBRACE, ok); | |
| 3408 if (!*ok) { | |
| 3409 return; | |
| 3410 } | |
| 3411 isolate()->counters()->total_preparse_skipped()->Increment( | |
| 3412 scope_->end_position() - function_block_pos); | |
| 3413 *materialized_literal_count = entry.literal_count(); | 3447 *materialized_literal_count = entry.literal_count(); |
| 3414 *expected_property_count = entry.property_count(); | 3448 *expected_property_count = entry.property_count(); |
| 3415 scope_->SetStrictMode(entry.strict_mode()); | 3449 *strict_mode = entry.strict_mode(); |
| 3416 } else { | 3450 } else { |
| 3417 // This case happens when we have preparse data but it doesn't contain an | 3451 // This case happens when we have preparse data but it doesn't contain an |
| 3418 // entry for the function. Fail the compilation. | 3452 // entry for the function. Fail the compilation. |
| 3419 ReportInvalidCachedData(function_name, ok); | 3453 ReportInvalidCachedData(function_name, ok); |
| 3420 return; | 3454 return; |
| 3421 } | 3455 } |
| 3456 } else if (thread_) { |
| 3457 int start, end; |
| 3458 // This will wait until the background thread has found the lazy function. |
| 3459 thread_->Consume(&start, &end, materialized_literal_count, |
| 3460 expected_property_count, strict_mode); |
| 3461 if (start == function_block_pos) { |
| 3462 scanner()->SeekForward(end - 1); |
| 3463 } else { |
| 3464 ProcessErrorFromRecorder(thread_->result(), thread_->recorder(), ok); |
| 3465 // If there is no error, the thread produced data for a lazy function |
| 3466 // which was not the function we expected. That should never happen. |
| 3467 ASSERT(!*ok); |
| 3468 *ok = false; |
| 3469 FinishFastParserTask(); |
| 3470 } |
| 3422 } else { | 3471 } else { |
| 3423 // With no cached data, we partially parse the function, without building an | 3472 // With no cached data, we partially parse the function, without building an |
| 3424 // AST. This gathers the data needed to build a lazy function. | 3473 // AST. This gathers the data needed to build a lazy function. The PreParser |
| 3474 // uses the same scanner, so it will be automatically positioned in the |
| 3475 // right position without additional seeking. |
| 3425 SingletonLogger logger; | 3476 SingletonLogger logger; |
| 3426 PreParser::PreParseResult result = | 3477 PreParser::PreParseResult result = |
| 3427 ParseLazyFunctionBodyWithPreParser(&logger); | 3478 ParseLazyFunctionBodyWithPreParser(&logger); |
| 3428 if (result == PreParser::kPreParseStackOverflow) { | 3479 ProcessErrorFromRecorder(result, &logger, ok); |
| 3429 // Propagate stack overflow. | |
| 3430 set_stack_overflow(); | |
| 3431 *ok = false; | |
| 3432 return; | |
| 3433 } | |
| 3434 if (logger.has_error()) { | |
| 3435 ParserTraits::ReportMessageAt( | |
| 3436 Scanner::Location(logger.start(), logger.end()), | |
| 3437 logger.message(), logger.argument_opt(), logger.is_reference_error()); | |
| 3438 *ok = false; | |
| 3439 return; | |
| 3440 } | |
| 3441 scope_->set_end_position(logger.end()); | |
| 3442 Expect(Token::RBRACE, ok); | |
| 3443 if (!*ok) { | 3480 if (!*ok) { |
| 3444 return; | 3481 return; |
| 3445 } | 3482 } |
| 3446 isolate()->counters()->total_preparse_skipped()->Increment( | |
| 3447 scope_->end_position() - function_block_pos); | |
| 3448 *materialized_literal_count = logger.literals(); | 3483 *materialized_literal_count = logger.literals(); |
| 3449 *expected_property_count = logger.properties(); | 3484 *expected_property_count = logger.properties(); |
| 3450 scope_->SetStrictMode(logger.strict_mode()); | 3485 *strict_mode = logger.strict_mode(); |
| 3451 if (cached_data_mode_ == PRODUCE_CACHED_DATA) { | |
| 3452 ASSERT(log_); | |
| 3453 // Position right after terminal '}'. | |
| 3454 int body_end = scanner()->location().end_pos; | |
| 3455 log_->LogFunction(function_block_pos, body_end, | |
| 3456 *materialized_literal_count, | |
| 3457 *expected_property_count, | |
| 3458 scope_->strict_mode()); | |
| 3459 } | |
| 3460 } | 3486 } |
| 3461 } | 3487 } |
| 3462 | 3488 |
| 3463 | 3489 |
| 3490 void Parser::ProcessErrorFromRecorder(PreParser::PreParseResult result, |
| 3491 const SingletonLogger* logger, bool* ok) { |
| 3492 if (result == PreParser::kPreParseStackOverflow) { |
| 3493 set_stack_overflow(); |
| 3494 *ok = false; |
| 3495 } else if (logger->has_error()) { |
| 3496 ParserTraits::ReportMessageAt( |
| 3497 Scanner::Location(logger->start(), logger->end()), logger->message(), |
| 3498 logger->argument_opt(), logger->is_reference_error()); |
| 3499 *ok = false; |
| 3500 } |
| 3501 } |
| 3502 |
| 3464 ZoneList<Statement*>* Parser::ParseEagerFunctionBody( | 3503 ZoneList<Statement*>* Parser::ParseEagerFunctionBody( |
| 3465 Handle<String> function_name, int pos, Variable* fvar, | 3504 Handle<String> function_name, int pos, Variable* fvar, |
| 3466 Token::Value fvar_init_op, bool is_generator, bool* ok) { | 3505 Token::Value fvar_init_op, bool is_generator, bool* ok) { |
| 3467 // Everything inside an eagerly parsed function will be parsed eagerly | 3506 // Everything inside an eagerly parsed function will be parsed eagerly |
| 3468 // (see comment above). | 3507 // (see comment above). |
| 3469 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); | 3508 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); |
| 3470 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(8, zone()); | 3509 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(8, zone()); |
| 3471 if (fvar != NULL) { | 3510 if (fvar != NULL) { |
| 3472 VariableProxy* fproxy = scope_->NewUnresolved( | 3511 VariableProxy* fproxy = scope_->NewUnresolved( |
| 3473 factory(), function_name, Interface::NewConst()); | 3512 factory(), function_name, Interface::NewConst()); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3520 } | 3559 } |
| 3521 | 3560 |
| 3522 | 3561 |
| 3523 PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser( | 3562 PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser( |
| 3524 SingletonLogger* logger) { | 3563 SingletonLogger* logger) { |
| 3525 HistogramTimerScope preparse_scope(isolate()->counters()->pre_parse()); | 3564 HistogramTimerScope preparse_scope(isolate()->counters()->pre_parse()); |
| 3526 ASSERT_EQ(Token::LBRACE, scanner()->current_token()); | 3565 ASSERT_EQ(Token::LBRACE, scanner()->current_token()); |
| 3527 | 3566 |
| 3528 if (reusable_preparser_ == NULL) { | 3567 if (reusable_preparser_ == NULL) { |
| 3529 intptr_t stack_limit = isolate()->stack_guard()->real_climit(); | 3568 intptr_t stack_limit = isolate()->stack_guard()->real_climit(); |
| 3530 reusable_preparser_ = new PreParser(&scanner_, NULL, stack_limit); | 3569 reusable_preparser_ = new PreParser(&scanner_, NULL, stack_limit, NULL); |
| 3531 reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping()); | 3570 reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping()); |
| 3532 reusable_preparser_->set_allow_modules(allow_modules()); | 3571 reusable_preparser_->set_allow_modules(allow_modules()); |
| 3533 reusable_preparser_->set_allow_natives_syntax(allow_natives_syntax()); | 3572 reusable_preparser_->set_allow_natives_syntax(allow_natives_syntax()); |
| 3534 reusable_preparser_->set_allow_lazy(true); | 3573 reusable_preparser_->set_allow_lazy(true); |
| 3535 reusable_preparser_->set_allow_generators(allow_generators()); | 3574 reusable_preparser_->set_allow_generators(allow_generators()); |
| 3536 reusable_preparser_->set_allow_for_of(allow_for_of()); | 3575 reusable_preparser_->set_allow_for_of(allow_for_of()); |
| 3537 reusable_preparser_->set_allow_harmony_numeric_literals( | 3576 reusable_preparser_->set_allow_harmony_numeric_literals( |
| 3538 allow_harmony_numeric_literals()); | 3577 allow_harmony_numeric_literals()); |
| 3539 } | 3578 } |
| 3540 PreParser::PreParseResult result = | 3579 PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction( |
| 3541 reusable_preparser_->PreParseLazyFunction(strict_mode(), | 3580 strict_mode(), is_generator(), logger); |
| 3542 is_generator(), | |
| 3543 logger); | |
| 3544 return result; | 3581 return result; |
| 3545 } | 3582 } |
| 3546 | 3583 |
| 3547 | 3584 |
| 3585 void Parser::StartFastParserTaskIfPossible(Handle<String> source) { |
| 3586 if (cached_data_mode_ == PRODUCE_CACHED_DATA && FLAG_parallel_parse && |
| 3587 source->length() >= FLAG_min_parallel_parse_length) { |
| 3588 Utf16CharacterStream* stream = ExternalCharacterStreamFromString(source); |
| 3589 if (stream) { |
| 3590 ASSERT(isolate()->fast_parser_thread()); |
| 3591 thread_ = isolate()->fast_parser_thread(); |
| 3592 thread_->StartBackgroundParsing(stream, allow_harmony_scoping(), |
| 3593 allow_modules(), allow_natives_syntax(), |
| 3594 allow_generators(), allow_for_of(), |
| 3595 allow_harmony_numeric_literals()); |
| 3596 } |
| 3597 } |
| 3598 } |
| 3599 |
| 3600 |
| 3601 void Parser::FinishFastParserTask() { |
| 3602 if (thread_) { |
| 3603 thread_->FinishBackgroundParsing(); |
| 3604 thread_ = NULL; |
| 3605 } |
| 3606 } |
| 3607 |
| 3608 |
| 3548 Expression* Parser::ParseV8Intrinsic(bool* ok) { | 3609 Expression* Parser::ParseV8Intrinsic(bool* ok) { |
| 3549 // CallRuntime :: | 3610 // CallRuntime :: |
| 3550 // '%' Identifier Arguments | 3611 // '%' Identifier Arguments |
| 3551 | 3612 |
| 3552 int pos = peek_position(); | 3613 int pos = peek_position(); |
| 3553 Expect(Token::MOD, CHECK_OK); | 3614 Expect(Token::MOD, CHECK_OK); |
| 3554 // Allow "eval" or "arguments" for backward compatibility. | 3615 // Allow "eval" or "arguments" for backward compatibility. |
| 3555 Handle<String> name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); | 3616 Handle<String> name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
| 3556 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); | 3617 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); |
| 3557 | 3618 |
| (...skipping 1041 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4599 ASSERT(info()->isolate()->has_pending_exception()); | 4660 ASSERT(info()->isolate()->has_pending_exception()); |
| 4600 } else { | 4661 } else { |
| 4601 result = ParseProgram(); | 4662 result = ParseProgram(); |
| 4602 } | 4663 } |
| 4603 } | 4664 } |
| 4604 info()->SetFunction(result); | 4665 info()->SetFunction(result); |
| 4605 return (result != NULL); | 4666 return (result != NULL); |
| 4606 } | 4667 } |
| 4607 | 4668 |
| 4608 } } // namespace v8::internal | 4669 } } // namespace v8::internal |
| OLD | NEW |