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 514 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
525 | 525 |
526 #define CHECK_FAILED /**/); \ | 526 #define CHECK_FAILED /**/); \ |
527 if (failed_) return NULL; \ | 527 if (failed_) return NULL; \ |
528 ((void)0 | 528 ((void)0 |
529 #define DUMMY ) // to make indentation work | 529 #define DUMMY ) // to make indentation work |
530 #undef DUMMY | 530 #undef DUMMY |
531 | 531 |
532 // ---------------------------------------------------------------------------- | 532 // ---------------------------------------------------------------------------- |
533 // Implementation of Parser | 533 // Implementation of Parser |
534 | 534 |
535 Parser::Parser(Handle<Script> script, | 535 Parser::Parser(CompilationInfo* info, |
536 int parser_flags, | 536 int parser_flags, |
537 v8::Extension* extension, | 537 v8::Extension* extension, |
538 ScriptDataImpl* pre_data, | 538 ScriptDataImpl* pre_data) |
539 Zone* zone) | 539 : isolate_(info->isolate()), |
540 : isolate_(script->GetIsolate()), | 540 symbol_cache_(pre_data ? pre_data->symbol_count() : 0, info->zone()), |
541 symbol_cache_(pre_data ? pre_data->symbol_count() : 0, zone), | 541 script_(info->script()), |
542 script_(script), | |
543 scanner_(isolate_->unicode_cache()), | 542 scanner_(isolate_->unicode_cache()), |
544 reusable_preparser_(NULL), | 543 reusable_preparser_(NULL), |
545 top_scope_(NULL), | 544 top_scope_(NULL), |
546 current_function_state_(NULL), | 545 current_function_state_(NULL), |
547 target_stack_(NULL), | 546 target_stack_(NULL), |
548 extension_(extension), | 547 extension_(extension), |
549 pre_data_(pre_data), | 548 pre_data_(pre_data), |
550 fni_(NULL), | 549 fni_(NULL), |
551 allow_natives_syntax_((parser_flags & kAllowNativesSyntax) != 0), | 550 allow_natives_syntax_((parser_flags & kAllowNativesSyntax) != 0), |
552 allow_lazy_((parser_flags & kAllowLazy) != 0), | 551 allow_lazy_((parser_flags & kAllowLazy) != 0), |
553 allow_modules_((parser_flags & kAllowModules) != 0), | 552 allow_modules_((parser_flags & kAllowModules) != 0), |
554 stack_overflow_(false), | 553 stack_overflow_(false), |
555 parenthesized_function_(false), | 554 parenthesized_function_(false), |
556 zone_(zone) { | 555 zone_(info->zone()), |
| 556 info_(info) { |
| 557 ASSERT(!script_.is_null()); |
557 isolate_->set_ast_node_id(0); | 558 isolate_->set_ast_node_id(0); |
558 if ((parser_flags & kLanguageModeMask) == EXTENDED_MODE) { | 559 if ((parser_flags & kLanguageModeMask) == EXTENDED_MODE) { |
559 scanner().SetHarmonyScoping(true); | 560 scanner().SetHarmonyScoping(true); |
560 } | 561 } |
561 if ((parser_flags & kAllowModules) != 0) { | 562 if ((parser_flags & kAllowModules) != 0) { |
562 scanner().SetHarmonyModules(true); | 563 scanner().SetHarmonyModules(true); |
563 } | 564 } |
564 } | 565 } |
565 | 566 |
566 | 567 |
567 FunctionLiteral* Parser::ParseProgram(CompilationInfo* info) { | 568 FunctionLiteral* Parser::ParseProgram() { |
568 ZoneScope zone_scope(info->zone(), DONT_DELETE_ON_EXIT); | 569 ZoneScope zone_scope(zone(), DONT_DELETE_ON_EXIT); |
569 | 570 |
570 HistogramTimerScope timer(isolate()->counters()->parse()); | 571 HistogramTimerScope timer(isolate()->counters()->parse()); |
571 Handle<String> source(String::cast(script_->source())); | 572 Handle<String> source(String::cast(script_->source())); |
572 isolate()->counters()->total_parse_size()->Increment(source->length()); | 573 isolate()->counters()->total_parse_size()->Increment(source->length()); |
573 fni_ = new(zone()) FuncNameInferrer(isolate(), zone()); | 574 fni_ = new(zone()) FuncNameInferrer(isolate(), zone()); |
574 | 575 |
575 // Initialize parser state. | 576 // Initialize parser state. |
576 source->TryFlatten(); | 577 source->TryFlatten(); |
577 if (source->IsExternalTwoByteString()) { | 578 if (source->IsExternalTwoByteString()) { |
578 // Notice that the stream is destroyed at the end of the branch block. | 579 // Notice that the stream is destroyed at the end of the branch block. |
579 // The last line of the blocks can't be moved outside, even though they're | 580 // The last line of the blocks can't be moved outside, even though they're |
580 // identical calls. | 581 // identical calls. |
581 ExternalTwoByteStringUtf16CharacterStream stream( | 582 ExternalTwoByteStringUtf16CharacterStream stream( |
582 Handle<ExternalTwoByteString>::cast(source), 0, source->length()); | 583 Handle<ExternalTwoByteString>::cast(source), 0, source->length()); |
583 scanner_.Initialize(&stream); | 584 scanner_.Initialize(&stream); |
584 return DoParseProgram(info, source, &zone_scope); | 585 return DoParseProgram(info(), source, &zone_scope); |
585 } else { | 586 } else { |
586 GenericStringUtf16CharacterStream stream(source, 0, source->length()); | 587 GenericStringUtf16CharacterStream stream(source, 0, source->length()); |
587 scanner_.Initialize(&stream); | 588 scanner_.Initialize(&stream); |
588 return DoParseProgram(info, source, &zone_scope); | 589 return DoParseProgram(info(), source, &zone_scope); |
589 } | 590 } |
590 } | 591 } |
591 | 592 |
592 | 593 |
593 FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, | 594 FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, |
594 Handle<String> source, | 595 Handle<String> source, |
595 ZoneScope* zone_scope) { | 596 ZoneScope* zone_scope) { |
596 ASSERT(top_scope_ == NULL); | 597 ASSERT(top_scope_ == NULL); |
597 ASSERT(target_stack_ == NULL); | 598 ASSERT(target_stack_ == NULL); |
598 if (pre_data_ != NULL) pre_data_->Initialize(); | 599 if (pre_data_ != NULL) pre_data_->Initialize(); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
655 // Make sure the target stack is empty. | 656 // Make sure the target stack is empty. |
656 ASSERT(target_stack_ == NULL); | 657 ASSERT(target_stack_ == NULL); |
657 | 658 |
658 // If there was a syntax error we have to get rid of the AST | 659 // If there was a syntax error we have to get rid of the AST |
659 // and it is not safe to do so before the scope has been deleted. | 660 // and it is not safe to do so before the scope has been deleted. |
660 if (result == NULL) zone_scope->DeleteOnExit(); | 661 if (result == NULL) zone_scope->DeleteOnExit(); |
661 return result; | 662 return result; |
662 } | 663 } |
663 | 664 |
664 | 665 |
665 FunctionLiteral* Parser::ParseLazy(CompilationInfo* info) { | 666 FunctionLiteral* Parser::ParseLazy() { |
666 ZoneScope zone_scope(info->zone(), DONT_DELETE_ON_EXIT); | 667 ZoneScope zone_scope(zone(), DONT_DELETE_ON_EXIT); |
667 HistogramTimerScope timer(isolate()->counters()->parse_lazy()); | 668 HistogramTimerScope timer(isolate()->counters()->parse_lazy()); |
668 Handle<String> source(String::cast(script_->source())); | 669 Handle<String> source(String::cast(script_->source())); |
669 isolate()->counters()->total_parse_size()->Increment(source->length()); | 670 isolate()->counters()->total_parse_size()->Increment(source->length()); |
670 | 671 |
671 Handle<SharedFunctionInfo> shared_info = info->shared_info(); | 672 Handle<SharedFunctionInfo> shared_info = info()->shared_info(); |
672 // Initialize parser state. | 673 // Initialize parser state. |
673 source->TryFlatten(); | 674 source->TryFlatten(); |
674 if (source->IsExternalTwoByteString()) { | 675 if (source->IsExternalTwoByteString()) { |
675 ExternalTwoByteStringUtf16CharacterStream stream( | 676 ExternalTwoByteStringUtf16CharacterStream stream( |
676 Handle<ExternalTwoByteString>::cast(source), | 677 Handle<ExternalTwoByteString>::cast(source), |
677 shared_info->start_position(), | 678 shared_info->start_position(), |
678 shared_info->end_position()); | 679 shared_info->end_position()); |
679 FunctionLiteral* result = ParseLazy(info, &stream, &zone_scope); | 680 FunctionLiteral* result = ParseLazy(&stream, &zone_scope); |
680 return result; | 681 return result; |
681 } else { | 682 } else { |
682 GenericStringUtf16CharacterStream stream(source, | 683 GenericStringUtf16CharacterStream stream(source, |
683 shared_info->start_position(), | 684 shared_info->start_position(), |
684 shared_info->end_position()); | 685 shared_info->end_position()); |
685 FunctionLiteral* result = ParseLazy(info, &stream, &zone_scope); | 686 FunctionLiteral* result = ParseLazy(&stream, &zone_scope); |
686 return result; | 687 return result; |
687 } | 688 } |
688 } | 689 } |
689 | 690 |
690 | 691 |
691 FunctionLiteral* Parser::ParseLazy(CompilationInfo* info, | 692 FunctionLiteral* Parser::ParseLazy(Utf16CharacterStream* source, |
692 Utf16CharacterStream* source, | |
693 ZoneScope* zone_scope) { | 693 ZoneScope* zone_scope) { |
694 Handle<SharedFunctionInfo> shared_info = info->shared_info(); | 694 Handle<SharedFunctionInfo> shared_info = info()->shared_info(); |
695 scanner_.Initialize(source); | 695 scanner_.Initialize(source); |
696 ASSERT(top_scope_ == NULL); | 696 ASSERT(top_scope_ == NULL); |
697 ASSERT(target_stack_ == NULL); | 697 ASSERT(target_stack_ == NULL); |
698 | 698 |
699 Handle<String> name(String::cast(shared_info->name())); | 699 Handle<String> name(String::cast(shared_info->name())); |
700 fni_ = new(zone()) FuncNameInferrer(isolate(), zone()); | 700 fni_ = new(zone()) FuncNameInferrer(isolate(), zone()); |
701 fni_->PushEnclosingName(name); | 701 fni_->PushEnclosingName(name); |
702 | 702 |
703 mode_ = PARSE_EAGERLY; | 703 mode_ = PARSE_EAGERLY; |
704 | 704 |
705 // Place holder for the result. | 705 // Place holder for the result. |
706 FunctionLiteral* result = NULL; | 706 FunctionLiteral* result = NULL; |
707 | 707 |
708 { | 708 { |
709 // Parse the function literal. | 709 // Parse the function literal. |
710 Scope* scope = NewScope(top_scope_, GLOBAL_SCOPE); | 710 Scope* scope = NewScope(top_scope_, GLOBAL_SCOPE); |
711 info->SetGlobalScope(scope); | 711 info()->SetGlobalScope(scope); |
712 if (!info->closure().is_null()) { | 712 if (!info()->closure().is_null()) { |
713 scope = Scope::DeserializeScopeChain(info->closure()->context(), scope, | 713 scope = Scope::DeserializeScopeChain(info()->closure()->context(), scope, |
714 zone()); | 714 zone()); |
715 } | 715 } |
716 FunctionState function_state(this, scope, isolate()); | 716 FunctionState function_state(this, scope, isolate()); |
717 ASSERT(scope->language_mode() != STRICT_MODE || !info->is_classic_mode()); | 717 ASSERT(scope->language_mode() != STRICT_MODE || !info()->is_classic_mode()); |
718 ASSERT(scope->language_mode() != EXTENDED_MODE || | 718 ASSERT(scope->language_mode() != EXTENDED_MODE || |
719 info->is_extended_mode()); | 719 info()->is_extended_mode()); |
720 ASSERT(info->language_mode() == shared_info->language_mode()); | 720 ASSERT(info()->language_mode() == shared_info->language_mode()); |
721 scope->SetLanguageMode(shared_info->language_mode()); | 721 scope->SetLanguageMode(shared_info->language_mode()); |
722 FunctionLiteral::Type type = shared_info->is_expression() | 722 FunctionLiteral::Type type = shared_info->is_expression() |
723 ? (shared_info->is_anonymous() | 723 ? (shared_info->is_anonymous() |
724 ? FunctionLiteral::ANONYMOUS_EXPRESSION | 724 ? FunctionLiteral::ANONYMOUS_EXPRESSION |
725 : FunctionLiteral::NAMED_EXPRESSION) | 725 : FunctionLiteral::NAMED_EXPRESSION) |
726 : FunctionLiteral::DECLARATION; | 726 : FunctionLiteral::DECLARATION; |
727 bool ok = true; | 727 bool ok = true; |
728 result = ParseFunctionLiteral(name, | 728 result = ParseFunctionLiteral(name, |
729 false, // Strict mode name already checked. | 729 false, // Strict mode name already checked. |
730 RelocInfo::kNoPosition, | 730 RelocInfo::kNoPosition, |
(...skipping 5303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6034 } | 6034 } |
6035 if (!info->is_native() && FLAG_harmony_modules) { | 6035 if (!info->is_native() && FLAG_harmony_modules) { |
6036 parsing_flags |= kAllowModules; | 6036 parsing_flags |= kAllowModules; |
6037 } | 6037 } |
6038 if (FLAG_allow_natives_syntax || info->is_native()) { | 6038 if (FLAG_allow_natives_syntax || info->is_native()) { |
6039 // We require %identifier(..) syntax. | 6039 // We require %identifier(..) syntax. |
6040 parsing_flags |= kAllowNativesSyntax; | 6040 parsing_flags |= kAllowNativesSyntax; |
6041 } | 6041 } |
6042 if (info->is_lazy()) { | 6042 if (info->is_lazy()) { |
6043 ASSERT(!info->is_eval()); | 6043 ASSERT(!info->is_eval()); |
6044 Parser parser(script, parsing_flags, NULL, NULL, info->zone()); | 6044 Parser parser(info, parsing_flags, NULL, NULL); |
6045 if (info->shared_info()->is_function()) { | 6045 if (info->shared_info()->is_function()) { |
6046 result = parser.ParseLazy(info); | 6046 result = parser.ParseLazy(); |
6047 } else { | 6047 } else { |
6048 result = parser.ParseProgram(info); | 6048 result = parser.ParseProgram(); |
6049 } | 6049 } |
6050 } else { | 6050 } else { |
6051 ScriptDataImpl* pre_data = info->pre_parse_data(); | 6051 ScriptDataImpl* pre_data = info->pre_parse_data(); |
6052 Parser parser(script, parsing_flags, info->extension(), pre_data, | 6052 Parser parser(info, parsing_flags, info->extension(), pre_data); |
6053 info->zone()); | |
6054 if (pre_data != NULL && pre_data->has_error()) { | 6053 if (pre_data != NULL && pre_data->has_error()) { |
6055 Scanner::Location loc = pre_data->MessageLocation(); | 6054 Scanner::Location loc = pre_data->MessageLocation(); |
6056 const char* message = pre_data->BuildMessage(); | 6055 const char* message = pre_data->BuildMessage(); |
6057 Vector<const char*> args = pre_data->BuildArgs(); | 6056 Vector<const char*> args = pre_data->BuildArgs(); |
6058 parser.ReportMessageAt(loc, message, args); | 6057 parser.ReportMessageAt(loc, message, args); |
6059 DeleteArray(message); | 6058 DeleteArray(message); |
6060 for (int i = 0; i < args.length(); i++) { | 6059 for (int i = 0; i < args.length(); i++) { |
6061 DeleteArray(args[i]); | 6060 DeleteArray(args[i]); |
6062 } | 6061 } |
6063 DeleteArray(args.start()); | 6062 DeleteArray(args.start()); |
6064 ASSERT(info->isolate()->has_pending_exception()); | 6063 ASSERT(info->isolate()->has_pending_exception()); |
6065 } else { | 6064 } else { |
6066 result = parser.ParseProgram(info); | 6065 result = parser.ParseProgram(); |
6067 } | 6066 } |
6068 } | 6067 } |
6069 info->SetFunction(result); | 6068 info->SetFunction(result); |
6070 return (result != NULL); | 6069 return (result != NULL); |
6071 } | 6070 } |
6072 | 6071 |
6073 } } // namespace v8::internal | 6072 } } // namespace v8::internal |
OLD | NEW |