| 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 519 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 530 | 530 |
| 531 #define CHECK_FAILED /**/); \ | 531 #define CHECK_FAILED /**/); \ |
| 532 if (failed_) return NULL; \ | 532 if (failed_) return NULL; \ |
| 533 ((void)0 | 533 ((void)0 |
| 534 #define DUMMY ) // to make indentation work | 534 #define DUMMY ) // to make indentation work |
| 535 #undef DUMMY | 535 #undef DUMMY |
| 536 | 536 |
| 537 // ---------------------------------------------------------------------------- | 537 // ---------------------------------------------------------------------------- |
| 538 // Implementation of Parser | 538 // Implementation of Parser |
| 539 | 539 |
| 540 Parser::Parser(CompilationInfo* info, | 540 Parser::Parser(CompilationInfo* info) |
| 541 int parser_flags, | |
| 542 v8::Extension* extension, | |
| 543 ScriptDataImpl* pre_data) | |
| 544 : isolate_(info->isolate()), | 541 : isolate_(info->isolate()), |
| 545 symbol_cache_(pre_data ? pre_data->symbol_count() : 0, info->zone()), | 542 symbol_cache_(0, info->zone()), |
| 546 script_(info->script()), | 543 script_(info->script()), |
| 547 scanner_(isolate_->unicode_cache()), | 544 scanner_(isolate_->unicode_cache()), |
| 548 reusable_preparser_(NULL), | 545 reusable_preparser_(NULL), |
| 549 top_scope_(NULL), | 546 top_scope_(NULL), |
| 550 current_function_state_(NULL), | 547 current_function_state_(NULL), |
| 551 target_stack_(NULL), | 548 target_stack_(NULL), |
| 552 extension_(extension), | 549 extension_(info->extension()), |
| 553 pre_data_(pre_data), | 550 pre_parse_data_(NULL), |
| 554 fni_(NULL), | 551 fni_(NULL), |
| 555 allow_natives_syntax_((parser_flags & kAllowNativesSyntax) != 0), | 552 allow_natives_syntax_(false), |
| 556 allow_lazy_((parser_flags & kAllowLazy) != 0), | 553 allow_lazy_(false), |
| 557 allow_modules_((parser_flags & kAllowModules) != 0), | 554 allow_generators_(false), |
| 558 stack_overflow_(false), | 555 stack_overflow_(false), |
| 559 parenthesized_function_(false), | 556 parenthesized_function_(false), |
| 560 zone_(info->zone()), | 557 zone_(info->zone()), |
| 561 info_(info) { | 558 info_(info) { |
| 562 ASSERT(!script_.is_null()); | 559 ASSERT(!script_.is_null()); |
| 563 isolate_->set_ast_node_id(0); | 560 isolate_->set_ast_node_id(0); |
| 564 if ((parser_flags & kLanguageModeMask) == EXTENDED_MODE) { | 561 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); |
| 565 scanner().SetHarmonyScoping(true); | 562 set_allow_modules(!info->is_native() && FLAG_harmony_modules); |
| 566 } | 563 set_allow_natives_syntax(FLAG_allow_natives_syntax || info->is_native()); |
| 567 if ((parser_flags & kAllowModules) != 0) { | 564 set_allow_lazy(false); // Must be explicitly enabled. |
| 568 scanner().SetHarmonyModules(true); | 565 set_allow_generators(FLAG_harmony_generators); |
| 569 } | |
| 570 } | 566 } |
| 571 | 567 |
| 572 | 568 |
| 573 FunctionLiteral* Parser::ParseProgram() { | 569 FunctionLiteral* Parser::ParseProgram() { |
| 574 ZoneScope zone_scope(zone(), DONT_DELETE_ON_EXIT); | 570 ZoneScope zone_scope(zone(), DONT_DELETE_ON_EXIT); |
| 575 HistogramTimerScope timer(isolate()->counters()->parse()); | 571 HistogramTimerScope timer(isolate()->counters()->parse()); |
| 576 Handle<String> source(String::cast(script_->source())); | 572 Handle<String> source(String::cast(script_->source())); |
| 577 isolate()->counters()->total_parse_size()->Increment(source->length()); | 573 isolate()->counters()->total_parse_size()->Increment(source->length()); |
| 578 int64_t start = FLAG_trace_parse ? OS::Ticks() : 0; | 574 int64_t start = FLAG_trace_parse ? OS::Ticks() : 0; |
| 579 fni_ = new(zone()) FuncNameInferrer(isolate(), zone()); | 575 fni_ = new(zone()) FuncNameInferrer(isolate(), zone()); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 610 } | 606 } |
| 611 return result; | 607 return result; |
| 612 } | 608 } |
| 613 | 609 |
| 614 | 610 |
| 615 FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, | 611 FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, |
| 616 Handle<String> source, | 612 Handle<String> source, |
| 617 ZoneScope* zone_scope) { | 613 ZoneScope* zone_scope) { |
| 618 ASSERT(top_scope_ == NULL); | 614 ASSERT(top_scope_ == NULL); |
| 619 ASSERT(target_stack_ == NULL); | 615 ASSERT(target_stack_ == NULL); |
| 620 if (pre_data_ != NULL) pre_data_->Initialize(); | 616 if (pre_parse_data_ != NULL) pre_parse_data_->Initialize(); |
| 621 | 617 |
| 622 Handle<String> no_name = isolate()->factory()->empty_string(); | 618 Handle<String> no_name = isolate()->factory()->empty_string(); |
| 623 | 619 |
| 624 FunctionLiteral* result = NULL; | 620 FunctionLiteral* result = NULL; |
| 625 { Scope* scope = NewScope(top_scope_, GLOBAL_SCOPE); | 621 { Scope* scope = NewScope(top_scope_, GLOBAL_SCOPE); |
| 626 info->SetGlobalScope(scope); | 622 info->SetGlobalScope(scope); |
| 627 if (!info->context().is_null()) { | 623 if (!info->context().is_null()) { |
| 628 scope = Scope::DeserializeScopeChain(*info->context(), scope, zone()); | 624 scope = Scope::DeserializeScopeChain(*info->context(), scope, zone()); |
| 629 } | 625 } |
| 630 if (info->is_eval()) { | 626 if (info->is_eval()) { |
| 631 if (!scope->is_global_scope() || info->language_mode() != CLASSIC_MODE) { | 627 if (!scope->is_global_scope() || info->language_mode() != CLASSIC_MODE) { |
| 632 scope = NewScope(scope, EVAL_SCOPE); | 628 scope = NewScope(scope, EVAL_SCOPE); |
| 633 } | 629 } |
| 634 } else if (info->is_global()) { | 630 } else if (info->is_global()) { |
| 635 scope = NewScope(scope, GLOBAL_SCOPE); | 631 scope = NewScope(scope, GLOBAL_SCOPE); |
| 636 } | 632 } |
| 637 scope->set_start_position(0); | 633 scope->set_start_position(0); |
| 638 scope->set_end_position(source->length()); | 634 scope->set_end_position(source->length()); |
| 639 | 635 |
| 640 // Compute the parsing mode. | 636 // Compute the parsing mode. |
| 641 Mode mode = (FLAG_lazy && allow_lazy_) ? PARSE_LAZILY : PARSE_EAGERLY; | 637 Mode mode = (FLAG_lazy && allow_lazy()) ? PARSE_LAZILY : PARSE_EAGERLY; |
| 642 if (allow_natives_syntax_ || extension_ != NULL || scope->is_eval_scope()) { | 638 if (allow_natives_syntax() || |
| 639 extension_ != NULL || |
| 640 scope->is_eval_scope()) { |
| 643 mode = PARSE_EAGERLY; | 641 mode = PARSE_EAGERLY; |
| 644 } | 642 } |
| 645 ParsingModeScope parsing_mode(this, mode); | 643 ParsingModeScope parsing_mode(this, mode); |
| 646 | 644 |
| 647 bool is_generator = false; | 645 bool is_generator = false; |
| 648 // Enters 'scope'. | 646 // Enters 'scope'. |
| 649 FunctionState function_state(this, scope, is_generator, isolate()); | 647 FunctionState function_state(this, scope, is_generator, isolate()); |
| 650 | 648 |
| 651 top_scope_->SetLanguageMode(info->language_mode()); | 649 top_scope_->SetLanguageMode(info->language_mode()); |
| 652 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); | 650 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 794 } else { | 792 } else { |
| 795 Handle<String> inferred_name(shared_info->inferred_name()); | 793 Handle<String> inferred_name(shared_info->inferred_name()); |
| 796 result->set_inferred_name(inferred_name); | 794 result->set_inferred_name(inferred_name); |
| 797 } | 795 } |
| 798 return result; | 796 return result; |
| 799 } | 797 } |
| 800 | 798 |
| 801 | 799 |
| 802 Handle<String> Parser::GetSymbol(bool* ok) { | 800 Handle<String> Parser::GetSymbol(bool* ok) { |
| 803 int symbol_id = -1; | 801 int symbol_id = -1; |
| 804 if (pre_data() != NULL) { | 802 if (pre_parse_data() != NULL) { |
| 805 symbol_id = pre_data()->GetSymbolIdentifier(); | 803 symbol_id = pre_parse_data()->GetSymbolIdentifier(); |
| 806 } | 804 } |
| 807 return LookupSymbol(symbol_id); | 805 return LookupSymbol(symbol_id); |
| 808 } | 806 } |
| 809 | 807 |
| 810 | 808 |
| 811 void Parser::ReportMessage(const char* type, Vector<const char*> args) { | 809 void Parser::ReportMessage(const char* type, Vector<const char*> args) { |
| 812 Scanner::Location source_location = scanner().location(); | 810 Scanner::Location source_location = scanner().location(); |
| 813 ReportMessageAt(source_location, type, args); | 811 ReportMessageAt(source_location, type, args); |
| 814 } | 812 } |
| 815 | 813 |
| (...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1085 // In the same manner, we have to patch the parsing mode. | 1083 // In the same manner, we have to patch the parsing mode. |
| 1086 if (is_eval && !top_scope_->is_eval_scope()) { | 1084 if (is_eval && !top_scope_->is_eval_scope()) { |
| 1087 ASSERT(top_scope_->is_global_scope()); | 1085 ASSERT(top_scope_->is_global_scope()); |
| 1088 Scope* scope = NewScope(top_scope_, EVAL_SCOPE); | 1086 Scope* scope = NewScope(top_scope_, EVAL_SCOPE); |
| 1089 scope->set_start_position(top_scope_->start_position()); | 1087 scope->set_start_position(top_scope_->start_position()); |
| 1090 scope->set_end_position(top_scope_->end_position()); | 1088 scope->set_end_position(top_scope_->end_position()); |
| 1091 top_scope_ = scope; | 1089 top_scope_ = scope; |
| 1092 mode_ = PARSE_EAGERLY; | 1090 mode_ = PARSE_EAGERLY; |
| 1093 } | 1091 } |
| 1094 // TODO(ES6): Fix entering extended mode, once it is specified. | 1092 // TODO(ES6): Fix entering extended mode, once it is specified. |
| 1095 top_scope_->SetLanguageMode(FLAG_harmony_scoping | 1093 top_scope_->SetLanguageMode(allow_harmony_scoping() |
| 1096 ? EXTENDED_MODE : STRICT_MODE); | 1094 ? EXTENDED_MODE : STRICT_MODE); |
| 1097 // "use strict" is the only directive for now. | 1095 // "use strict" is the only directive for now. |
| 1098 directive_prologue = false; | 1096 directive_prologue = false; |
| 1099 } | 1097 } |
| 1100 } else { | 1098 } else { |
| 1101 // End of the directive prologue. | 1099 // End of the directive prologue. |
| 1102 directive_prologue = false; | 1100 directive_prologue = false; |
| 1103 } | 1101 } |
| 1104 } | 1102 } |
| 1105 | 1103 |
| (...skipping 797 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1903 | 1901 |
| 1904 | 1902 |
| 1905 Statement* Parser::ParseFunctionDeclaration(ZoneStringList* names, bool* ok) { | 1903 Statement* Parser::ParseFunctionDeclaration(ZoneStringList* names, bool* ok) { |
| 1906 // FunctionDeclaration :: | 1904 // FunctionDeclaration :: |
| 1907 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' | 1905 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' |
| 1908 // GeneratorDeclaration :: | 1906 // GeneratorDeclaration :: |
| 1909 // 'function' '*' Identifier '(' FormalParameterListopt ')' | 1907 // 'function' '*' Identifier '(' FormalParameterListopt ')' |
| 1910 // '{' FunctionBody '}' | 1908 // '{' FunctionBody '}' |
| 1911 Expect(Token::FUNCTION, CHECK_OK); | 1909 Expect(Token::FUNCTION, CHECK_OK); |
| 1912 int function_token_position = scanner().location().beg_pos; | 1910 int function_token_position = scanner().location().beg_pos; |
| 1913 bool is_generator = FLAG_harmony_generators && Check(Token::MUL); | 1911 bool is_generator = allow_generators() && Check(Token::MUL); |
| 1914 bool is_strict_reserved = false; | 1912 bool is_strict_reserved = false; |
| 1915 Handle<String> name = ParseIdentifierOrStrictReservedWord( | 1913 Handle<String> name = ParseIdentifierOrStrictReservedWord( |
| 1916 &is_strict_reserved, CHECK_OK); | 1914 &is_strict_reserved, CHECK_OK); |
| 1917 FunctionLiteral* fun = ParseFunctionLiteral(name, | 1915 FunctionLiteral* fun = ParseFunctionLiteral(name, |
| 1918 is_strict_reserved, | 1916 is_strict_reserved, |
| 1919 is_generator, | 1917 is_generator, |
| 1920 function_token_position, | 1918 function_token_position, |
| 1921 FunctionLiteral::DECLARATION, | 1919 FunctionLiteral::DECLARATION, |
| 1922 CHECK_OK); | 1920 CHECK_OK); |
| 1923 // Even if we're not at the top-level of the global or a function | 1921 // Even if we're not at the top-level of the global or a function |
| (...skipping 1555 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3479 bool* ok) { | 3477 bool* ok) { |
| 3480 // MemberExpression :: | 3478 // MemberExpression :: |
| 3481 // (PrimaryExpression | FunctionLiteral) | 3479 // (PrimaryExpression | FunctionLiteral) |
| 3482 // ('[' Expression ']' | '.' Identifier | Arguments)* | 3480 // ('[' Expression ']' | '.' Identifier | Arguments)* |
| 3483 | 3481 |
| 3484 // Parse the initial primary or function expression. | 3482 // Parse the initial primary or function expression. |
| 3485 Expression* result = NULL; | 3483 Expression* result = NULL; |
| 3486 if (peek() == Token::FUNCTION) { | 3484 if (peek() == Token::FUNCTION) { |
| 3487 Expect(Token::FUNCTION, CHECK_OK); | 3485 Expect(Token::FUNCTION, CHECK_OK); |
| 3488 int function_token_position = scanner().location().beg_pos; | 3486 int function_token_position = scanner().location().beg_pos; |
| 3489 bool is_generator = FLAG_harmony_generators && Check(Token::MUL); | 3487 bool is_generator = allow_generators() && Check(Token::MUL); |
| 3490 Handle<String> name; | 3488 Handle<String> name; |
| 3491 bool is_strict_reserved_name = false; | 3489 bool is_strict_reserved_name = false; |
| 3492 if (peek_any_identifier()) { | 3490 if (peek_any_identifier()) { |
| 3493 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, | 3491 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, |
| 3494 CHECK_OK); | 3492 CHECK_OK); |
| 3495 } | 3493 } |
| 3496 FunctionLiteral::Type type = name.is_null() | 3494 FunctionLiteral::Type type = name.is_null() |
| 3497 ? FunctionLiteral::ANONYMOUS_EXPRESSION | 3495 ? FunctionLiteral::ANONYMOUS_EXPRESSION |
| 3498 : FunctionLiteral::NAMED_EXPRESSION; | 3496 : FunctionLiteral::NAMED_EXPRESSION; |
| 3499 result = ParseFunctionLiteral(name, | 3497 result = ParseFunctionLiteral(name, |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3695 case Token::LPAREN: | 3693 case Token::LPAREN: |
| 3696 Consume(Token::LPAREN); | 3694 Consume(Token::LPAREN); |
| 3697 // Heuristically try to detect immediately called functions before | 3695 // Heuristically try to detect immediately called functions before |
| 3698 // seeing the call parentheses. | 3696 // seeing the call parentheses. |
| 3699 parenthesized_function_ = (peek() == Token::FUNCTION); | 3697 parenthesized_function_ = (peek() == Token::FUNCTION); |
| 3700 result = ParseExpression(true, CHECK_OK); | 3698 result = ParseExpression(true, CHECK_OK); |
| 3701 Expect(Token::RPAREN, CHECK_OK); | 3699 Expect(Token::RPAREN, CHECK_OK); |
| 3702 break; | 3700 break; |
| 3703 | 3701 |
| 3704 case Token::MOD: | 3702 case Token::MOD: |
| 3705 if (allow_natives_syntax_ || extension_ != NULL) { | 3703 if (allow_natives_syntax() || extension_ != NULL) { |
| 3706 result = ParseV8Intrinsic(CHECK_OK); | 3704 result = ParseV8Intrinsic(CHECK_OK); |
| 3707 break; | 3705 break; |
| 3708 } | 3706 } |
| 3709 // If we're not allowing special syntax we fall-through to the | 3707 // If we're not allowing special syntax we fall-through to the |
| 3710 // default case. | 3708 // default case. |
| 3711 | 3709 |
| 3712 default: { | 3710 default: { |
| 3713 Token::Value tok = Next(); | 3711 Token::Value tok = Next(); |
| 3714 ReportUnexpectedToken(tok); | 3712 ReportUnexpectedToken(tok); |
| 3715 *ok = false; | 3713 *ok = false; |
| (...skipping 752 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4468 // These are all things we can know at this point, without looking at the | 4466 // These are all things we can know at this point, without looking at the |
| 4469 // function itself. | 4467 // function itself. |
| 4470 bool is_lazily_compiled = (mode() == PARSE_LAZILY && | 4468 bool is_lazily_compiled = (mode() == PARSE_LAZILY && |
| 4471 top_scope_->AllowsLazyCompilation() && | 4469 top_scope_->AllowsLazyCompilation() && |
| 4472 !parenthesized_function_); | 4470 !parenthesized_function_); |
| 4473 parenthesized_function_ = false; // The bit was set for this function only. | 4471 parenthesized_function_ = false; // The bit was set for this function only. |
| 4474 | 4472 |
| 4475 if (is_lazily_compiled) { | 4473 if (is_lazily_compiled) { |
| 4476 int function_block_pos = scanner().location().beg_pos; | 4474 int function_block_pos = scanner().location().beg_pos; |
| 4477 FunctionEntry entry; | 4475 FunctionEntry entry; |
| 4478 if (pre_data_ != NULL) { | 4476 if (pre_parse_data_ != NULL) { |
| 4479 // If we have pre_data_, we use it to skip parsing the function body. | 4477 // If we have pre_parse_data_, we use it to skip parsing the function |
| 4480 // the preparser data contains the information we need to construct the | 4478 // body. The preparser data contains the information we need to |
| 4481 // lazy function. | 4479 // construct the lazy function. |
| 4482 entry = pre_data()->GetFunctionEntry(function_block_pos); | 4480 entry = pre_parse_data()->GetFunctionEntry(function_block_pos); |
| 4483 if (entry.is_valid()) { | 4481 if (entry.is_valid()) { |
| 4484 if (entry.end_pos() <= function_block_pos) { | 4482 if (entry.end_pos() <= function_block_pos) { |
| 4485 // End position greater than end of stream is safe, and hard | 4483 // End position greater than end of stream is safe, and hard |
| 4486 // to check. | 4484 // to check. |
| 4487 ReportInvalidPreparseData(function_name, CHECK_OK); | 4485 ReportInvalidPreparseData(function_name, CHECK_OK); |
| 4488 } | 4486 } |
| 4489 scanner().SeekForward(entry.end_pos() - 1); | 4487 scanner().SeekForward(entry.end_pos() - 1); |
| 4490 | 4488 |
| 4491 scope->set_end_position(entry.end_pos()); | 4489 scope->set_end_position(entry.end_pos()); |
| 4492 Expect(Token::RBRACE, CHECK_OK); | 4490 Expect(Token::RBRACE, CHECK_OK); |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4639 } | 4637 } |
| 4640 | 4638 |
| 4641 | 4639 |
| 4642 preparser::PreParser::PreParseResult Parser::LazyParseFunctionLiteral( | 4640 preparser::PreParser::PreParseResult Parser::LazyParseFunctionLiteral( |
| 4643 SingletonLogger* logger) { | 4641 SingletonLogger* logger) { |
| 4644 HistogramTimerScope preparse_scope(isolate()->counters()->pre_parse()); | 4642 HistogramTimerScope preparse_scope(isolate()->counters()->pre_parse()); |
| 4645 ASSERT_EQ(Token::LBRACE, scanner().current_token()); | 4643 ASSERT_EQ(Token::LBRACE, scanner().current_token()); |
| 4646 | 4644 |
| 4647 if (reusable_preparser_ == NULL) { | 4645 if (reusable_preparser_ == NULL) { |
| 4648 intptr_t stack_limit = isolate()->stack_guard()->real_climit(); | 4646 intptr_t stack_limit = isolate()->stack_guard()->real_climit(); |
| 4649 bool do_allow_lazy = true; | |
| 4650 reusable_preparser_ = new preparser::PreParser(&scanner_, | 4647 reusable_preparser_ = new preparser::PreParser(&scanner_, |
| 4651 NULL, | 4648 NULL, |
| 4652 stack_limit, | 4649 stack_limit); |
| 4653 do_allow_lazy, | 4650 reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping()); |
| 4654 allow_natives_syntax_, | 4651 reusable_preparser_->set_allow_modules(allow_modules()); |
| 4655 allow_modules_, | 4652 reusable_preparser_->set_allow_natives_syntax(allow_natives_syntax()); |
| 4656 FLAG_harmony_generators); | 4653 reusable_preparser_->set_allow_lazy(true); |
| 4654 reusable_preparser_->set_allow_generators(allow_generators()); |
| 4657 } | 4655 } |
| 4658 preparser::PreParser::PreParseResult result = | 4656 preparser::PreParser::PreParseResult result = |
| 4659 reusable_preparser_->PreParseLazyFunction(top_scope_->language_mode(), | 4657 reusable_preparser_->PreParseLazyFunction(top_scope_->language_mode(), |
| 4660 is_generator(), | 4658 is_generator(), |
| 4661 logger); | 4659 logger); |
| 4662 return result; | 4660 return result; |
| 4663 } | 4661 } |
| 4664 | 4662 |
| 4665 | 4663 |
| 4666 Expression* Parser::ParseV8Intrinsic(bool* ok) { | 4664 Expression* Parser::ParseV8Intrinsic(bool* ok) { |
| (...skipping 1226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5893 input = *data; | 5891 input = *data; |
| 5894 result = (result << 7) | (input & 0x7f); | 5892 result = (result << 7) | (input & 0x7f); |
| 5895 data++; | 5893 data++; |
| 5896 } | 5894 } |
| 5897 *source = data; | 5895 *source = data; |
| 5898 return result; | 5896 return result; |
| 5899 } | 5897 } |
| 5900 | 5898 |
| 5901 | 5899 |
| 5902 // Create a Scanner for the preparser to use as input, and preparse the source. | 5900 // Create a Scanner for the preparser to use as input, and preparse the source. |
| 5903 static ScriptDataImpl* DoPreParse(Utf16CharacterStream* source, | 5901 ScriptDataImpl* PreParserApi::PreParse(Utf16CharacterStream* source) { |
| 5904 int flags, | 5902 CompleteParserRecorder recorder; |
| 5905 ParserRecorder* recorder) { | |
| 5906 Isolate* isolate = Isolate::Current(); | 5903 Isolate* isolate = Isolate::Current(); |
| 5907 HistogramTimerScope timer(isolate->counters()->pre_parse()); | 5904 HistogramTimerScope timer(isolate->counters()->pre_parse()); |
| 5908 Scanner scanner(isolate->unicode_cache()); | 5905 Scanner scanner(isolate->unicode_cache()); |
| 5909 scanner.SetHarmonyScoping(FLAG_harmony_scoping); | 5906 intptr_t stack_limit = isolate->stack_guard()->real_climit(); |
| 5907 preparser::PreParser preparser(&scanner, &recorder, stack_limit); |
| 5908 preparser.set_allow_lazy(true); |
| 5909 preparser.set_allow_generators(FLAG_harmony_generators); |
| 5910 preparser.set_allow_harmony_scoping(FLAG_harmony_scoping); |
| 5910 scanner.Initialize(source); | 5911 scanner.Initialize(source); |
| 5911 intptr_t stack_limit = isolate->stack_guard()->real_climit(); | 5912 preparser::PreParser::PreParseResult result = preparser.PreParseProgram(); |
| 5912 preparser::PreParser::PreParseResult result = | |
| 5913 preparser::PreParser::PreParseProgram(&scanner, | |
| 5914 recorder, | |
| 5915 flags, | |
| 5916 stack_limit); | |
| 5917 if (result == preparser::PreParser::kPreParseStackOverflow) { | 5913 if (result == preparser::PreParser::kPreParseStackOverflow) { |
| 5918 isolate->StackOverflow(); | 5914 isolate->StackOverflow(); |
| 5919 return NULL; | 5915 return NULL; |
| 5920 } | 5916 } |
| 5921 | 5917 |
| 5922 // Extract the accumulated data from the recorder as a single | 5918 // Extract the accumulated data from the recorder as a single |
| 5923 // contiguous vector that we are responsible for disposing. | 5919 // contiguous vector that we are responsible for disposing. |
| 5924 Vector<unsigned> store = recorder->ExtractData(); | 5920 Vector<unsigned> store = recorder.ExtractData(); |
| 5925 return new ScriptDataImpl(store); | 5921 return new ScriptDataImpl(store); |
| 5926 } | 5922 } |
| 5927 | 5923 |
| 5928 | 5924 |
| 5929 ScriptDataImpl* ParserApi::PreParse(Utf16CharacterStream* source) { | |
| 5930 int flags = kNoParsingFlags; | |
| 5931 if (FLAG_lazy) { | |
| 5932 flags |= kAllowLazy; | |
| 5933 } | |
| 5934 if (FLAG_harmony_generators) { | |
| 5935 flags |= kAllowGenerators; | |
| 5936 } | |
| 5937 CompleteParserRecorder recorder; | |
| 5938 return DoPreParse(source, flags, &recorder); | |
| 5939 } | |
| 5940 | |
| 5941 | |
| 5942 bool RegExpParser::ParseRegExp(FlatStringReader* input, | 5925 bool RegExpParser::ParseRegExp(FlatStringReader* input, |
| 5943 bool multiline, | 5926 bool multiline, |
| 5944 RegExpCompileData* result, | 5927 RegExpCompileData* result, |
| 5945 Zone* zone) { | 5928 Zone* zone) { |
| 5946 ASSERT(result != NULL); | 5929 ASSERT(result != NULL); |
| 5947 RegExpParser parser(input, &result->error, multiline, zone); | 5930 RegExpParser parser(input, &result->error, multiline, zone); |
| 5948 RegExpTree* tree = parser.ParsePattern(); | 5931 RegExpTree* tree = parser.ParsePattern(); |
| 5949 if (parser.failed()) { | 5932 if (parser.failed()) { |
| 5950 ASSERT(tree == NULL); | 5933 ASSERT(tree == NULL); |
| 5951 ASSERT(!result->error.is_null()); | 5934 ASSERT(!result->error.is_null()); |
| 5952 } else { | 5935 } else { |
| 5953 ASSERT(tree != NULL); | 5936 ASSERT(tree != NULL); |
| 5954 ASSERT(result->error.is_null()); | 5937 ASSERT(result->error.is_null()); |
| 5955 result->tree = tree; | 5938 result->tree = tree; |
| 5956 int capture_count = parser.captures_started(); | 5939 int capture_count = parser.captures_started(); |
| 5957 result->simple = tree->IsAtom() && parser.simple() && capture_count == 0; | 5940 result->simple = tree->IsAtom() && parser.simple() && capture_count == 0; |
| 5958 result->contains_anchor = parser.contains_anchor(); | 5941 result->contains_anchor = parser.contains_anchor(); |
| 5959 result->capture_count = capture_count; | 5942 result->capture_count = capture_count; |
| 5960 } | 5943 } |
| 5961 return !parser.failed(); | 5944 return !parser.failed(); |
| 5962 } | 5945 } |
| 5963 | 5946 |
| 5964 | 5947 |
| 5965 bool ParserApi::Parse(CompilationInfo* info, int parsing_flags) { | 5948 bool Parser::Parse() { |
| 5966 ASSERT(info->function() == NULL); | 5949 ASSERT(info()->function() == NULL); |
| 5967 FunctionLiteral* result = NULL; | 5950 FunctionLiteral* result = NULL; |
| 5968 ASSERT((parsing_flags & kLanguageModeMask) == CLASSIC_MODE); | 5951 if (info()->is_lazy()) { |
| 5969 if (!info->is_native() && FLAG_harmony_scoping) { | 5952 ASSERT(!info()->is_eval()); |
| 5970 // Harmony scoping is requested. | 5953 if (info()->shared_info()->is_function()) { |
| 5971 parsing_flags |= EXTENDED_MODE; | 5954 result = ParseLazy(); |
| 5972 } | |
| 5973 if (!info->is_native() && FLAG_harmony_modules) { | |
| 5974 parsing_flags |= kAllowModules; | |
| 5975 } | |
| 5976 if (FLAG_allow_natives_syntax || info->is_native()) { | |
| 5977 // We require %identifier(..) syntax. | |
| 5978 parsing_flags |= kAllowNativesSyntax; | |
| 5979 } | |
| 5980 if (info->is_lazy()) { | |
| 5981 ASSERT(!info->is_eval()); | |
| 5982 Parser parser(info, parsing_flags, NULL, NULL); | |
| 5983 if (info->shared_info()->is_function()) { | |
| 5984 result = parser.ParseLazy(); | |
| 5985 } else { | 5955 } else { |
| 5986 result = parser.ParseProgram(); | 5956 result = ParseProgram(); |
| 5987 } | 5957 } |
| 5988 } else { | 5958 } else { |
| 5989 ScriptDataImpl* pre_data = info->pre_parse_data(); | 5959 ScriptDataImpl* pre_parse_data = info()->pre_parse_data(); |
| 5990 Parser parser(info, parsing_flags, info->extension(), pre_data); | 5960 set_pre_parse_data(pre_parse_data); |
| 5991 if (pre_data != NULL && pre_data->has_error()) { | 5961 if (pre_parse_data != NULL && pre_parse_data->has_error()) { |
| 5992 Scanner::Location loc = pre_data->MessageLocation(); | 5962 Scanner::Location loc = pre_parse_data->MessageLocation(); |
| 5993 const char* message = pre_data->BuildMessage(); | 5963 const char* message = pre_parse_data->BuildMessage(); |
| 5994 Vector<const char*> args = pre_data->BuildArgs(); | 5964 Vector<const char*> args = pre_parse_data->BuildArgs(); |
| 5995 parser.ReportMessageAt(loc, message, args); | 5965 ReportMessageAt(loc, message, args); |
| 5996 DeleteArray(message); | 5966 DeleteArray(message); |
| 5997 for (int i = 0; i < args.length(); i++) { | 5967 for (int i = 0; i < args.length(); i++) { |
| 5998 DeleteArray(args[i]); | 5968 DeleteArray(args[i]); |
| 5999 } | 5969 } |
| 6000 DeleteArray(args.start()); | 5970 DeleteArray(args.start()); |
| 6001 ASSERT(info->isolate()->has_pending_exception()); | 5971 ASSERT(info()->isolate()->has_pending_exception()); |
| 6002 } else { | 5972 } else { |
| 6003 result = parser.ParseProgram(); | 5973 result = ParseProgram(); |
| 6004 } | 5974 } |
| 6005 } | 5975 } |
| 6006 info->SetFunction(result); | 5976 info()->SetFunction(result); |
| 6007 return (result != NULL); | 5977 return (result != NULL); |
| 6008 } | 5978 } |
| 6009 | 5979 |
| 6010 } } // namespace v8::internal | 5980 } } // namespace v8::internal |
| OLD | NEW |