| 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 |