| 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 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 365 char* result = NewArray<char>(length + 1); | 365 char* result = NewArray<char>(length + 1); |
| 366 for (int i = 0; i < length; i++) { | 366 for (int i = 0; i < length; i++) { |
| 367 result[i] = start[i + 1]; | 367 result[i] = start[i + 1]; |
| 368 } | 368 } |
| 369 result[length] = '\0'; | 369 result[length] = '\0'; |
| 370 if (chars != NULL) *chars = length; | 370 if (chars != NULL) *chars = length; |
| 371 return result; | 371 return result; |
| 372 } | 372 } |
| 373 | 373 |
| 374 | 374 |
| 375 Scanner::Location ScriptDataImpl::MessageLocation() { | 375 ScannerBase::Location ScriptDataImpl::MessageLocation() { |
| 376 int beg_pos = Read(PreparseDataConstants::kMessageStartPos); | 376 int beg_pos = Read(PreparseDataConstants::kMessageStartPos); |
| 377 int end_pos = Read(PreparseDataConstants::kMessageEndPos); | 377 int end_pos = Read(PreparseDataConstants::kMessageEndPos); |
| 378 return Scanner::Location(beg_pos, end_pos); | 378 return ScannerBase::Location(beg_pos, end_pos); |
| 379 } | 379 } |
| 380 | 380 |
| 381 | 381 |
| 382 const char* ScriptDataImpl::BuildMessage() { | 382 const char* ScriptDataImpl::BuildMessage() { |
| 383 unsigned* start = ReadAddress(PreparseDataConstants::kMessageTextPos); | 383 unsigned* start = ReadAddress(PreparseDataConstants::kMessageTextPos); |
| 384 return ReadString(start, NULL); | 384 return ReadString(start, NULL); |
| 385 } | 385 } |
| 386 | 386 |
| 387 | 387 |
| 388 Vector<const char*> ScriptDataImpl::BuildArgs() { | 388 Vector<const char*> ScriptDataImpl::BuildArgs() { |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 529 #define CHECK_FAILED /**/); \ | 529 #define CHECK_FAILED /**/); \ |
| 530 if (failed_) return NULL; \ | 530 if (failed_) return NULL; \ |
| 531 ((void)0 | 531 ((void)0 |
| 532 #define DUMMY ) // to make indentation work | 532 #define DUMMY ) // to make indentation work |
| 533 #undef DUMMY | 533 #undef DUMMY |
| 534 | 534 |
| 535 // ---------------------------------------------------------------------------- | 535 // ---------------------------------------------------------------------------- |
| 536 // Implementation of Parser | 536 // Implementation of Parser |
| 537 | 537 |
| 538 Parser::Parser(CompilationInfo* info) | 538 Parser::Parser(CompilationInfo* info) |
| 539 : ParserBase(&scanner_, info->isolate()->stack_guard()->real_climit()), | 539 : ParserBase(NULL, info->isolate()->stack_guard()->real_climit()), |
| 540 isolate_(info->isolate()), | 540 isolate_(info->isolate()), |
| 541 symbol_cache_(0, info->zone()), | 541 symbol_cache_(0, info->zone()), |
| 542 script_(info->script()), | 542 script_(info->script()), |
| 543 scanner_(isolate_->unicode_cache()), | |
| 544 reusable_preparser_(NULL), | 543 reusable_preparser_(NULL), |
| 545 top_scope_(NULL), | 544 top_scope_(NULL), |
| 546 original_scope_(NULL), | 545 original_scope_(NULL), |
| 547 current_function_state_(NULL), | 546 current_function_state_(NULL), |
| 548 target_stack_(NULL), | 547 target_stack_(NULL), |
| 549 extension_(info->extension()), | 548 extension_(info->extension()), |
| 550 pre_parse_data_(NULL), | 549 pre_parse_data_(NULL), |
| 551 fni_(NULL), | 550 fni_(NULL), |
| 552 parenthesized_function_(false), | 551 parenthesized_function_(false), |
| 553 zone_(info->zone()), | 552 zone_(info->zone()), |
| 554 info_(info) { | 553 info_(info) { |
| 555 ASSERT(!script_.is_null()); | 554 ASSERT(!script_.is_null()); |
| 556 isolate_->set_ast_node_id(0); | 555 isolate_->set_ast_node_id(0); |
| 557 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); | 556 // FIXME: these can be done only when the ExperimentalScanner has been |
| 558 set_allow_modules(!info->is_native() && FLAG_harmony_modules); | 557 // created, and they need to be redone when it's recreated. |
| 558 // set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); |
| 559 // set_allow_modules(!info->is_native() && FLAG_harmony_modules); |
| 559 set_allow_natives_syntax(FLAG_allow_natives_syntax || info->is_native()); | 560 set_allow_natives_syntax(FLAG_allow_natives_syntax || info->is_native()); |
| 561 // set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals); |
| 560 set_allow_lazy(false); // Must be explicitly enabled. | 562 set_allow_lazy(false); // Must be explicitly enabled. |
| 561 set_allow_generators(FLAG_harmony_generators); | 563 set_allow_generators(FLAG_harmony_generators); |
| 562 set_allow_for_of(FLAG_harmony_iteration); | 564 set_allow_for_of(FLAG_harmony_iteration); |
| 563 set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals); | |
| 564 } | 565 } |
| 565 | 566 |
| 566 | 567 |
| 567 FunctionLiteral* Parser::ParseProgram() { | 568 FunctionLiteral* Parser::ParseProgram() { |
| 568 // TODO(bmeurer): We temporarily need to pass allow_nesting = true here, | 569 // TODO(bmeurer): We temporarily need to pass allow_nesting = true here, |
| 569 // see comment for HistogramTimerScope class. | 570 // see comment for HistogramTimerScope class. |
| 570 HistogramTimerScope timer_scope(isolate()->counters()->parse(), true); | 571 HistogramTimerScope timer_scope(isolate()->counters()->parse(), true); |
| 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 ElapsedTimer timer; | 574 ElapsedTimer timer; |
| 574 if (FLAG_trace_parse) { | 575 if (FLAG_trace_parse) { |
| 575 timer.Start(); | 576 timer.Start(); |
| 576 } | 577 } |
| 577 fni_ = new(zone()) FuncNameInferrer(isolate(), zone()); | 578 fni_ = new(zone()) FuncNameInferrer(isolate(), zone()); |
| 578 | 579 |
| 579 // Initialize parser state. | 580 // Initialize parser state. |
| 580 source->TryFlatten(); | 581 source->TryFlatten(); |
| 581 FunctionLiteral* result; | 582 FunctionLiteral* result; |
| 582 if (source->IsExternalTwoByteString()) { | 583 if (source->IsExternalTwoByteString()) { |
| 583 // Notice that the stream is destroyed at the end of the branch block. | 584 // Notice that the stream is destroyed at the end of the branch block. |
| 584 // The last line of the blocks can't be moved outside, even though they're | 585 // The last line of the blocks can't be moved outside, even though they're |
| 585 // identical calls. | 586 // identical calls. // FIXME |
| 586 ExternalTwoByteStringUtf16CharacterStream stream( | 587 delete scanner_; |
| 587 Handle<ExternalTwoByteString>::cast(source), 0, source->length()); | 588 scanner_ = new ExperimentalScanner<uint16_t>(source, isolate()); |
| 588 scanner_.Initialize(&stream); | 589 // FIXME: set flags |
| 589 result = DoParseProgram(info(), source); | 590 result = DoParseProgram(info(), source); |
| 590 } else { | 591 } else { |
| 591 GenericStringUtf16CharacterStream stream(source, 0, source->length()); | 592 delete scanner_; |
| 592 scanner_.Initialize(&stream); | 593 scanner_ = new ExperimentalScanner<uint8_t>(source, isolate()); |
| 594 // FIXME: set flags |
| 593 result = DoParseProgram(info(), source); | 595 result = DoParseProgram(info(), source); |
| 594 } | 596 } |
| 595 | 597 |
| 596 if (FLAG_trace_parse && result != NULL) { | 598 if (FLAG_trace_parse && result != NULL) { |
| 597 double ms = timer.Elapsed().InMillisecondsF(); | 599 double ms = timer.Elapsed().InMillisecondsF(); |
| 598 if (info()->is_eval()) { | 600 if (info()->is_eval()) { |
| 599 PrintF("[parsing eval"); | 601 PrintF("[parsing eval"); |
| 600 } else if (info()->script()->name()->IsString()) { | 602 } else if (info()->script()->name()->IsString()) { |
| 601 String* name = String::cast(info()->script()->name()); | 603 String* name = String::cast(info()->script()->name()); |
| 602 SmartArrayPointer<char> name_chars = name->ToCString(); | 604 SmartArrayPointer<char> name_chars = name->ToCString(); |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 701 | 703 |
| 702 | 704 |
| 703 FunctionLiteral* Parser::ParseLazy() { | 705 FunctionLiteral* Parser::ParseLazy() { |
| 704 HistogramTimerScope timer_scope(isolate()->counters()->parse_lazy()); | 706 HistogramTimerScope timer_scope(isolate()->counters()->parse_lazy()); |
| 705 Handle<String> source(String::cast(script_->source())); | 707 Handle<String> source(String::cast(script_->source())); |
| 706 isolate()->counters()->total_parse_size()->Increment(source->length()); | 708 isolate()->counters()->total_parse_size()->Increment(source->length()); |
| 707 ElapsedTimer timer; | 709 ElapsedTimer timer; |
| 708 if (FLAG_trace_parse) { | 710 if (FLAG_trace_parse) { |
| 709 timer.Start(); | 711 timer.Start(); |
| 710 } | 712 } |
| 711 Handle<SharedFunctionInfo> shared_info = info()->shared_info(); | |
| 712 | |
| 713 // Initialize parser state. | 713 // Initialize parser state. |
| 714 source->TryFlatten(); | 714 source->TryFlatten(); |
| 715 FunctionLiteral* result; | 715 Handle<SharedFunctionInfo> shared_info = info()->shared_info(); |
| 716 if (source->IsExternalTwoByteString()) { | 716 FunctionLiteral* result = ParseLazy( |
| 717 ExternalTwoByteStringUtf16CharacterStream stream( | 717 source, shared_info->start_position(), shared_info->end_position()); |
| 718 Handle<ExternalTwoByteString>::cast(source), | |
| 719 shared_info->start_position(), | |
| 720 shared_info->end_position()); | |
| 721 result = ParseLazy(&stream); | |
| 722 } else { | |
| 723 GenericStringUtf16CharacterStream stream(source, | |
| 724 shared_info->start_position(), | |
| 725 shared_info->end_position()); | |
| 726 result = ParseLazy(&stream); | |
| 727 } | |
| 728 | |
| 729 if (FLAG_trace_parse && result != NULL) { | 718 if (FLAG_trace_parse && result != NULL) { |
| 730 double ms = timer.Elapsed().InMillisecondsF(); | 719 double ms = timer.Elapsed().InMillisecondsF(); |
| 731 SmartArrayPointer<char> name_chars = result->debug_name()->ToCString(); | 720 SmartArrayPointer<char> name_chars = result->debug_name()->ToCString(); |
| 732 PrintF("[parsing function: %s - took %0.3f ms]\n", *name_chars, ms); | 721 PrintF("[parsing function: %s - took %0.3f ms]\n", *name_chars, ms); |
| 733 } | 722 } |
| 734 return result; | 723 return result; |
| 735 } | 724 } |
| 736 | 725 |
| 737 | 726 |
| 738 FunctionLiteral* Parser::ParseLazy(Utf16CharacterStream* source) { | 727 FunctionLiteral* Parser::ParseLazy(Handle<String> source, int start, int end) { |
| 728 delete scanner_; |
| 729 if (source->IsExternalTwoByteString()) { |
| 730 scanner_ = new ExperimentalScanner<uint16_t>(source, isolate()); |
| 731 } else { |
| 732 scanner_ = new ExperimentalScanner<uint8_t>(source, isolate()); |
| 733 } |
| 734 scanner_->SeekForward(start); |
| 735 scanner_->SetEnd(end); |
| 736 // FIXME: set flags |
| 737 |
| 739 Handle<SharedFunctionInfo> shared_info = info()->shared_info(); | 738 Handle<SharedFunctionInfo> shared_info = info()->shared_info(); |
| 740 scanner_.Initialize(source); | |
| 741 ASSERT(top_scope_ == NULL); | 739 ASSERT(top_scope_ == NULL); |
| 742 ASSERT(target_stack_ == NULL); | 740 ASSERT(target_stack_ == NULL); |
| 743 | 741 |
| 744 Handle<String> name(String::cast(shared_info->name())); | 742 Handle<String> name(String::cast(shared_info->name())); |
| 745 fni_ = new(zone()) FuncNameInferrer(isolate(), zone()); | 743 fni_ = new(zone()) FuncNameInferrer(isolate(), zone()); |
| 746 fni_->PushEnclosingName(name); | 744 fni_->PushEnclosingName(name); |
| 747 | 745 |
| 748 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); | 746 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); |
| 749 | 747 |
| 750 // Place holder for the result. | 748 // Place holder for the result. |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 797 Handle<String> Parser::GetSymbol() { | 795 Handle<String> Parser::GetSymbol() { |
| 798 int symbol_id = -1; | 796 int symbol_id = -1; |
| 799 if (pre_parse_data() != NULL) { | 797 if (pre_parse_data() != NULL) { |
| 800 symbol_id = pre_parse_data()->GetSymbolIdentifier(); | 798 symbol_id = pre_parse_data()->GetSymbolIdentifier(); |
| 801 } | 799 } |
| 802 return LookupSymbol(symbol_id); | 800 return LookupSymbol(symbol_id); |
| 803 } | 801 } |
| 804 | 802 |
| 805 | 803 |
| 806 void Parser::ReportMessage(const char* message, Vector<const char*> args) { | 804 void Parser::ReportMessage(const char* message, Vector<const char*> args) { |
| 807 Scanner::Location source_location = scanner().location(); | 805 ScannerBase::Location source_location = scanner().location(); |
| 808 ReportMessageAt(source_location, message, args); | 806 ReportMessageAt(source_location, message, args); |
| 809 } | 807 } |
| 810 | 808 |
| 811 | 809 |
| 812 void Parser::ReportMessage(const char* message, Vector<Handle<String> > args) { | 810 void Parser::ReportMessage(const char* message, Vector<Handle<String> > args) { |
| 813 Scanner::Location source_location = scanner().location(); | 811 ScannerBase::Location source_location = scanner().location(); |
| 814 ReportMessageAt(source_location, message, args); | 812 ReportMessageAt(source_location, message, args); |
| 815 } | 813 } |
| 816 | 814 |
| 817 | 815 |
| 818 void Parser::ReportMessageAt(Scanner::Location source_location, | 816 void Parser::ReportMessageAt(ScannerBase::Location source_location, |
| 819 const char* message, | 817 const char* message, |
| 820 Vector<const char*> args) { | 818 Vector<const char*> args) { |
| 821 MessageLocation location(script_, | 819 MessageLocation location(script_, |
| 822 source_location.beg_pos, | 820 source_location.beg_pos, |
| 823 source_location.end_pos); | 821 source_location.end_pos); |
| 824 Factory* factory = isolate()->factory(); | 822 Factory* factory = isolate()->factory(); |
| 825 Handle<FixedArray> elements = factory->NewFixedArray(args.length()); | 823 Handle<FixedArray> elements = factory->NewFixedArray(args.length()); |
| 826 for (int i = 0; i < args.length(); i++) { | 824 for (int i = 0; i < args.length(); i++) { |
| 827 Handle<String> arg_string = factory->NewStringFromUtf8(CStrVector(args[i])); | 825 Handle<String> arg_string = factory->NewStringFromUtf8(CStrVector(args[i])); |
| 828 elements->set(i, *arg_string); | 826 elements->set(i, *arg_string); |
| 829 } | 827 } |
| 830 Handle<JSArray> array = factory->NewJSArrayWithElements(elements); | 828 Handle<JSArray> array = factory->NewJSArrayWithElements(elements); |
| 831 Handle<Object> result = factory->NewSyntaxError(message, array); | 829 Handle<Object> result = factory->NewSyntaxError(message, array); |
| 832 isolate()->Throw(*result, &location); | 830 isolate()->Throw(*result, &location); |
| 833 } | 831 } |
| 834 | 832 |
| 835 | 833 |
| 836 void Parser::ReportMessageAt(Scanner::Location source_location, | 834 void Parser::ReportMessageAt(ScannerBase::Location source_location, |
| 837 const char* message, | 835 const char* message, |
| 838 Vector<Handle<String> > args) { | 836 Vector<Handle<String> > args) { |
| 839 MessageLocation location(script_, | 837 MessageLocation location(script_, |
| 840 source_location.beg_pos, | 838 source_location.beg_pos, |
| 841 source_location.end_pos); | 839 source_location.end_pos); |
| 842 Factory* factory = isolate()->factory(); | 840 Factory* factory = isolate()->factory(); |
| 843 Handle<FixedArray> elements = factory->NewFixedArray(args.length()); | 841 Handle<FixedArray> elements = factory->NewFixedArray(args.length()); |
| 844 for (int i = 0; i < args.length(); i++) { | 842 for (int i = 0; i < args.length(); i++) { |
| 845 elements->set(i, *args[i]); | 843 elements->set(i, *args[i]); |
| 846 } | 844 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 865 TargetScope scope(&this->target_stack_); | 863 TargetScope scope(&this->target_stack_); |
| 866 | 864 |
| 867 ASSERT(processor != NULL); | 865 ASSERT(processor != NULL); |
| 868 bool directive_prologue = true; // Parsing directive prologue. | 866 bool directive_prologue = true; // Parsing directive prologue. |
| 869 | 867 |
| 870 while (peek() != end_token) { | 868 while (peek() != end_token) { |
| 871 if (directive_prologue && peek() != Token::STRING) { | 869 if (directive_prologue && peek() != Token::STRING) { |
| 872 directive_prologue = false; | 870 directive_prologue = false; |
| 873 } | 871 } |
| 874 | 872 |
| 875 Scanner::Location token_loc = scanner().peek_location(); | 873 ScannerBase::Location token_loc = scanner().peek_location(); |
| 876 Statement* stat; | 874 Statement* stat; |
| 877 if (is_global && !is_eval) { | 875 if (is_global && !is_eval) { |
| 878 stat = ParseModuleElement(NULL, CHECK_OK); | 876 stat = ParseModuleElement(NULL, CHECK_OK); |
| 879 } else { | 877 } else { |
| 880 stat = ParseBlockElement(NULL, CHECK_OK); | 878 stat = ParseBlockElement(NULL, CHECK_OK); |
| 881 } | 879 } |
| 882 if (stat == NULL || stat->IsEmpty()) { | 880 if (stat == NULL || stat->IsEmpty()) { |
| 883 directive_prologue = false; // End of directive prologue. | 881 directive_prologue = false; // End of directive prologue. |
| 884 continue; | 882 continue; |
| 885 } | 883 } |
| (...skipping 3213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4099 // FunctionState indicates that this function is a generator. | 4097 // FunctionState indicates that this function is a generator. |
| 4100 Variable* temp = top_scope_->DeclarationScope()->NewTemporary( | 4098 Variable* temp = top_scope_->DeclarationScope()->NewTemporary( |
| 4101 isolate()->factory()->dot_generator_object_string()); | 4099 isolate()->factory()->dot_generator_object_string()); |
| 4102 function_state.set_generator_object_variable(temp); | 4100 function_state.set_generator_object_variable(temp); |
| 4103 } | 4101 } |
| 4104 | 4102 |
| 4105 // FormalParameterList :: | 4103 // FormalParameterList :: |
| 4106 // '(' (Identifier)*[','] ')' | 4104 // '(' (Identifier)*[','] ')' |
| 4107 Expect(Token::LPAREN, CHECK_OK); | 4105 Expect(Token::LPAREN, CHECK_OK); |
| 4108 scope->set_start_position(scanner().location().beg_pos); | 4106 scope->set_start_position(scanner().location().beg_pos); |
| 4109 Scanner::Location name_loc = Scanner::Location::invalid(); | 4107 ScannerBase::Location name_loc = ScannerBase::Location::invalid(); |
| 4110 Scanner::Location dupe_loc = Scanner::Location::invalid(); | 4108 ScannerBase::Location dupe_loc = ScannerBase::Location::invalid(); |
| 4111 Scanner::Location reserved_loc = Scanner::Location::invalid(); | 4109 ScannerBase::Location reserved_loc = ScannerBase::Location::invalid(); |
| 4112 | 4110 |
| 4113 bool done = (peek() == Token::RPAREN); | 4111 bool done = (peek() == Token::RPAREN); |
| 4114 while (!done) { | 4112 while (!done) { |
| 4115 bool is_strict_reserved = false; | 4113 bool is_strict_reserved = false; |
| 4116 Handle<String> param_name = | 4114 Handle<String> param_name = |
| 4117 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); | 4115 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); |
| 4118 | 4116 |
| 4119 // Store locations for possible future error reports. | 4117 // Store locations for possible future error reports. |
| 4120 if (!name_loc.IsValid() && IsEvalOrArguments(param_name)) { | 4118 if (!name_loc.IsValid() && IsEvalOrArguments(param_name)) { |
| 4121 name_loc = scanner().location(); | 4119 name_loc = scanner().location(); |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4216 set_stack_overflow(); | 4214 set_stack_overflow(); |
| 4217 *ok = false; | 4215 *ok = false; |
| 4218 return NULL; | 4216 return NULL; |
| 4219 } | 4217 } |
| 4220 if (logger.has_error()) { | 4218 if (logger.has_error()) { |
| 4221 const char* arg = logger.argument_opt(); | 4219 const char* arg = logger.argument_opt(); |
| 4222 Vector<const char*> args; | 4220 Vector<const char*> args; |
| 4223 if (arg != NULL) { | 4221 if (arg != NULL) { |
| 4224 args = Vector<const char*>(&arg, 1); | 4222 args = Vector<const char*>(&arg, 1); |
| 4225 } | 4223 } |
| 4226 ReportMessageAt(Scanner::Location(logger.start(), logger.end()), | 4224 ReportMessageAt(ScannerBase::Location(logger.start(), logger.end()), |
| 4227 logger.message(), args); | 4225 logger.message(), args); |
| 4228 *ok = false; | 4226 *ok = false; |
| 4229 return NULL; | 4227 return NULL; |
| 4230 } | 4228 } |
| 4231 scope->set_end_position(logger.end()); | 4229 scope->set_end_position(logger.end()); |
| 4232 Expect(Token::RBRACE, CHECK_OK); | 4230 Expect(Token::RBRACE, CHECK_OK); |
| 4233 isolate()->counters()->total_preparse_skipped()->Increment( | 4231 isolate()->counters()->total_preparse_skipped()->Increment( |
| 4234 scope->end_position() - function_block_pos); | 4232 scope->end_position() - function_block_pos); |
| 4235 materialized_literal_count = logger.literals(); | 4233 materialized_literal_count = logger.literals(); |
| 4236 expected_property_count = logger.properties(); | 4234 expected_property_count = logger.properties(); |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4293 Expect(Token::RBRACE, CHECK_OK); | 4291 Expect(Token::RBRACE, CHECK_OK); |
| 4294 scope->set_end_position(scanner().location().end_pos); | 4292 scope->set_end_position(scanner().location().end_pos); |
| 4295 } | 4293 } |
| 4296 | 4294 |
| 4297 // Validate strict mode. | 4295 // Validate strict mode. |
| 4298 if (!top_scope_->is_classic_mode()) { | 4296 if (!top_scope_->is_classic_mode()) { |
| 4299 if (IsEvalOrArguments(function_name)) { | 4297 if (IsEvalOrArguments(function_name)) { |
| 4300 int start_pos = scope->start_position(); | 4298 int start_pos = scope->start_position(); |
| 4301 int position = function_token_pos != RelocInfo::kNoPosition | 4299 int position = function_token_pos != RelocInfo::kNoPosition |
| 4302 ? function_token_pos : (start_pos > 0 ? start_pos - 1 : start_pos); | 4300 ? function_token_pos : (start_pos > 0 ? start_pos - 1 : start_pos); |
| 4303 Scanner::Location location = Scanner::Location(position, start_pos); | 4301 ScannerBase::Location location = |
| 4302 ScannerBase::Location(position, start_pos); |
| 4304 ReportMessageAt(location, | 4303 ReportMessageAt(location, |
| 4305 "strict_function_name", Vector<const char*>::empty()); | 4304 "strict_function_name", Vector<const char*>::empty()); |
| 4306 *ok = false; | 4305 *ok = false; |
| 4307 return NULL; | 4306 return NULL; |
| 4308 } | 4307 } |
| 4309 if (name_loc.IsValid()) { | 4308 if (name_loc.IsValid()) { |
| 4310 ReportMessageAt(name_loc, "strict_param_name", | 4309 ReportMessageAt(name_loc, "strict_param_name", |
| 4311 Vector<const char*>::empty()); | 4310 Vector<const char*>::empty()); |
| 4312 *ok = false; | 4311 *ok = false; |
| 4313 return NULL; | 4312 return NULL; |
| 4314 } | 4313 } |
| 4315 if (dupe_loc.IsValid()) { | 4314 if (dupe_loc.IsValid()) { |
| 4316 ReportMessageAt(dupe_loc, "strict_param_dupe", | 4315 ReportMessageAt(dupe_loc, "strict_param_dupe", |
| 4317 Vector<const char*>::empty()); | 4316 Vector<const char*>::empty()); |
| 4318 *ok = false; | 4317 *ok = false; |
| 4319 return NULL; | 4318 return NULL; |
| 4320 } | 4319 } |
| 4321 if (name_is_strict_reserved) { | 4320 if (name_is_strict_reserved) { |
| 4322 int start_pos = scope->start_position(); | 4321 int start_pos = scope->start_position(); |
| 4323 int position = function_token_pos != RelocInfo::kNoPosition | 4322 int position = function_token_pos != RelocInfo::kNoPosition |
| 4324 ? function_token_pos : (start_pos > 0 ? start_pos - 1 : start_pos); | 4323 ? function_token_pos : (start_pos > 0 ? start_pos - 1 : start_pos); |
| 4325 Scanner::Location location = Scanner::Location(position, start_pos); | 4324 ScannerBase::Location location = |
| 4325 ScannerBase::Location(position, start_pos); |
| 4326 ReportMessageAt(location, "strict_reserved_word", | 4326 ReportMessageAt(location, "strict_reserved_word", |
| 4327 Vector<const char*>::empty()); | 4327 Vector<const char*>::empty()); |
| 4328 *ok = false; | 4328 *ok = false; |
| 4329 return NULL; | 4329 return NULL; |
| 4330 } | 4330 } |
| 4331 if (reserved_loc.IsValid()) { | 4331 if (reserved_loc.IsValid()) { |
| 4332 ReportMessageAt(reserved_loc, "strict_reserved_word", | 4332 ReportMessageAt(reserved_loc, "strict_reserved_word", |
| 4333 Vector<const char*>::empty()); | 4333 Vector<const char*>::empty()); |
| 4334 *ok = false; | 4334 *ok = false; |
| 4335 return NULL; | 4335 return NULL; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4369 } | 4369 } |
| 4370 | 4370 |
| 4371 | 4371 |
| 4372 PreParser::PreParseResult Parser::LazyParseFunctionLiteral( | 4372 PreParser::PreParseResult Parser::LazyParseFunctionLiteral( |
| 4373 SingletonLogger* logger) { | 4373 SingletonLogger* logger) { |
| 4374 HistogramTimerScope preparse_scope(isolate()->counters()->pre_parse()); | 4374 HistogramTimerScope preparse_scope(isolate()->counters()->pre_parse()); |
| 4375 ASSERT_EQ(Token::LBRACE, scanner().current_token()); | 4375 ASSERT_EQ(Token::LBRACE, scanner().current_token()); |
| 4376 | 4376 |
| 4377 if (reusable_preparser_ == NULL) { | 4377 if (reusable_preparser_ == NULL) { |
| 4378 intptr_t stack_limit = isolate()->stack_guard()->real_climit(); | 4378 intptr_t stack_limit = isolate()->stack_guard()->real_climit(); |
| 4379 reusable_preparser_ = new PreParser(&scanner_, NULL, stack_limit); | 4379 reusable_preparser_ = new PreParser(scanner_, NULL, stack_limit); |
| 4380 reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping()); | 4380 reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping()); |
| 4381 reusable_preparser_->set_allow_modules(allow_modules()); | 4381 reusable_preparser_->set_allow_modules(allow_modules()); |
| 4382 reusable_preparser_->set_allow_natives_syntax(allow_natives_syntax()); | 4382 reusable_preparser_->set_allow_natives_syntax(allow_natives_syntax()); |
| 4383 reusable_preparser_->set_allow_lazy(true); | 4383 reusable_preparser_->set_allow_lazy(true); |
| 4384 reusable_preparser_->set_allow_generators(allow_generators()); | 4384 reusable_preparser_->set_allow_generators(allow_generators()); |
| 4385 reusable_preparser_->set_allow_for_of(allow_for_of()); | 4385 reusable_preparser_->set_allow_for_of(allow_for_of()); |
| 4386 reusable_preparser_->set_allow_harmony_numeric_literals( | 4386 reusable_preparser_->set_allow_harmony_numeric_literals( |
| 4387 allow_harmony_numeric_literals()); | 4387 allow_harmony_numeric_literals()); |
| 4388 } | 4388 } |
| 4389 PreParser::PreParseResult result = | 4389 PreParser::PreParseResult result = |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4578 if (lhs != NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) { | 4578 if (lhs != NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) { |
| 4579 ReportMessage(error, Vector<const char*>::empty()); | 4579 ReportMessage(error, Vector<const char*>::empty()); |
| 4580 *ok = false; | 4580 *ok = false; |
| 4581 } | 4581 } |
| 4582 } | 4582 } |
| 4583 | 4583 |
| 4584 | 4584 |
| 4585 // Checks whether an octal literal was last seen between beg_pos and end_pos. | 4585 // Checks whether an octal literal was last seen between beg_pos and end_pos. |
| 4586 // If so, reports an error. Only called for strict mode. | 4586 // If so, reports an error. Only called for strict mode. |
| 4587 void ParserBase::CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) { | 4587 void ParserBase::CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) { |
| 4588 Scanner::Location octal = scanner()->octal_position(); | 4588 ScannerBase::Location octal = scanner()->octal_position(); |
| 4589 if (octal.IsValid() && beg_pos <= octal.beg_pos && octal.end_pos <= end_pos) { | 4589 if (octal.IsValid() && beg_pos <= octal.beg_pos && octal.end_pos <= end_pos) { |
| 4590 ReportMessageAt(octal, "strict_octal_literal"); | 4590 ReportMessageAt(octal, "strict_octal_literal"); |
| 4591 scanner()->clear_octal_position(); | 4591 scanner()->clear_octal_position(); |
| 4592 *ok = false; | 4592 *ok = false; |
| 4593 } | 4593 } |
| 4594 } | 4594 } |
| 4595 | 4595 |
| 4596 | 4596 |
| 4597 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) { | 4597 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) { |
| 4598 Declaration* decl = scope->CheckConflictingVarDeclarations(); | 4598 Declaration* decl = scope->CheckConflictingVarDeclarations(); |
| 4599 if (decl != NULL) { | 4599 if (decl != NULL) { |
| 4600 // In harmony mode we treat conflicting variable bindinds as early | 4600 // In harmony mode we treat conflicting variable bindinds as early |
| 4601 // errors. See ES5 16 for a definition of early errors. | 4601 // errors. See ES5 16 for a definition of early errors. |
| 4602 Handle<String> name = decl->proxy()->name(); | 4602 Handle<String> name = decl->proxy()->name(); |
| 4603 SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS); | 4603 SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS); |
| 4604 const char* elms[2] = { "Variable", *c_string }; | 4604 const char* elms[2] = { "Variable", *c_string }; |
| 4605 Vector<const char*> args(elms, 2); | 4605 Vector<const char*> args(elms, 2); |
| 4606 int position = decl->proxy()->position(); | 4606 int position = decl->proxy()->position(); |
| 4607 Scanner::Location location = position == RelocInfo::kNoPosition | 4607 ScannerBase::Location location = position == RelocInfo::kNoPosition |
| 4608 ? Scanner::Location::invalid() | 4608 ? ScannerBase::Location::invalid() |
| 4609 : Scanner::Location(position, position + 1); | 4609 : ScannerBase::Location(position, position + 1); |
| 4610 ReportMessageAt(location, "redeclaration", args); | 4610 ReportMessageAt(location, "redeclaration", args); |
| 4611 *ok = false; | 4611 *ok = false; |
| 4612 } | 4612 } |
| 4613 } | 4613 } |
| 4614 | 4614 |
| 4615 | 4615 |
| 4616 // This function reads an identifier name and determines whether or not it | 4616 // This function reads an identifier name and determines whether or not it |
| 4617 // is 'get' or 'set'. | 4617 // is 'get' or 'set'. |
| 4618 Handle<String> Parser::ParseIdentifierNameOrGetOrSet(bool* is_get, | 4618 Handle<String> Parser::ParseIdentifierNameOrGetOrSet(bool* is_get, |
| 4619 bool* is_set, | 4619 bool* is_set, |
| (...skipping 983 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5603 if (data >= symbol_data_end_) return -1; | 5603 if (data >= symbol_data_end_) return -1; |
| 5604 input = *data; | 5604 input = *data; |
| 5605 result = (result << 7) | (input & 0x7f); | 5605 result = (result << 7) | (input & 0x7f); |
| 5606 data++; | 5606 data++; |
| 5607 } | 5607 } |
| 5608 *source = data; | 5608 *source = data; |
| 5609 return result; | 5609 return result; |
| 5610 } | 5610 } |
| 5611 | 5611 |
| 5612 | 5612 |
| 5613 // Create a Scanner for the preparser to use as input, and preparse the source. | 5613 // Create a ScannerBase for the preparser to use as input, and preparse the |
| 5614 // source. |
| 5614 ScriptDataImpl* PreParserApi::PreParse(Isolate* isolate, | 5615 ScriptDataImpl* PreParserApi::PreParse(Isolate* isolate, |
| 5615 Utf16CharacterStream* source) { | 5616 Utf16CharacterStream* source) { |
| 5616 CompleteParserRecorder recorder; | 5617 // FIXME(experimental-scanner): implement |
| 5617 HistogramTimerScope timer(isolate->counters()->pre_parse()); | 5618 return NULL; |
| 5618 Scanner scanner(isolate->unicode_cache()); | |
| 5619 intptr_t stack_limit = isolate->stack_guard()->real_climit(); | |
| 5620 PreParser preparser(&scanner, &recorder, stack_limit); | |
| 5621 preparser.set_allow_lazy(true); | |
| 5622 preparser.set_allow_generators(FLAG_harmony_generators); | |
| 5623 preparser.set_allow_for_of(FLAG_harmony_iteration); | |
| 5624 preparser.set_allow_harmony_scoping(FLAG_harmony_scoping); | |
| 5625 preparser.set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals); | |
| 5626 scanner.Initialize(source); | |
| 5627 PreParser::PreParseResult result = preparser.PreParseProgram(); | |
| 5628 if (result == PreParser::kPreParseStackOverflow) { | |
| 5629 isolate->StackOverflow(); | |
| 5630 return NULL; | |
| 5631 } | |
| 5632 | |
| 5633 // Extract the accumulated data from the recorder as a single | |
| 5634 // contiguous vector that we are responsible for disposing. | |
| 5635 Vector<unsigned> store = recorder.ExtractData(); | |
| 5636 return new ScriptDataImpl(store); | |
| 5637 } | 5619 } |
| 5638 | 5620 |
| 5639 | 5621 |
| 5640 bool RegExpParser::ParseRegExp(FlatStringReader* input, | 5622 bool RegExpParser::ParseRegExp(FlatStringReader* input, |
| 5641 bool multiline, | 5623 bool multiline, |
| 5642 RegExpCompileData* result, | 5624 RegExpCompileData* result, |
| 5643 Zone* zone) { | 5625 Zone* zone) { |
| 5644 ASSERT(result != NULL); | 5626 ASSERT(result != NULL); |
| 5645 RegExpParser parser(input, &result->error, multiline, zone); | 5627 RegExpParser parser(input, &result->error, multiline, zone); |
| 5646 RegExpTree* tree = parser.ParsePattern(); | 5628 RegExpTree* tree = parser.ParsePattern(); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 5667 ASSERT(!info()->is_eval()); | 5649 ASSERT(!info()->is_eval()); |
| 5668 if (info()->shared_info()->is_function()) { | 5650 if (info()->shared_info()->is_function()) { |
| 5669 result = ParseLazy(); | 5651 result = ParseLazy(); |
| 5670 } else { | 5652 } else { |
| 5671 result = ParseProgram(); | 5653 result = ParseProgram(); |
| 5672 } | 5654 } |
| 5673 } else { | 5655 } else { |
| 5674 ScriptDataImpl* pre_parse_data = info()->pre_parse_data(); | 5656 ScriptDataImpl* pre_parse_data = info()->pre_parse_data(); |
| 5675 set_pre_parse_data(pre_parse_data); | 5657 set_pre_parse_data(pre_parse_data); |
| 5676 if (pre_parse_data != NULL && pre_parse_data->has_error()) { | 5658 if (pre_parse_data != NULL && pre_parse_data->has_error()) { |
| 5677 Scanner::Location loc = pre_parse_data->MessageLocation(); | 5659 ScannerBase::Location loc = pre_parse_data->MessageLocation(); |
| 5678 const char* message = pre_parse_data->BuildMessage(); | 5660 const char* message = pre_parse_data->BuildMessage(); |
| 5679 Vector<const char*> args = pre_parse_data->BuildArgs(); | 5661 Vector<const char*> args = pre_parse_data->BuildArgs(); |
| 5680 ReportMessageAt(loc, message, args); | 5662 ReportMessageAt(loc, message, args); |
| 5681 DeleteArray(message); | 5663 DeleteArray(message); |
| 5682 for (int i = 0; i < args.length(); i++) { | 5664 for (int i = 0; i < args.length(); i++) { |
| 5683 DeleteArray(args[i]); | 5665 DeleteArray(args[i]); |
| 5684 } | 5666 } |
| 5685 DeleteArray(args.start()); | 5667 DeleteArray(args.start()); |
| 5686 ASSERT(info()->isolate()->has_pending_exception()); | 5668 ASSERT(info()->isolate()->has_pending_exception()); |
| 5687 } else { | 5669 } else { |
| 5688 result = ParseProgram(); | 5670 result = ParseProgram(); |
| 5689 } | 5671 } |
| 5690 } | 5672 } |
| 5691 info()->SetFunction(result); | 5673 info()->SetFunction(result); |
| 5692 return (result != NULL); | 5674 return (result != NULL); |
| 5693 } | 5675 } |
| 5694 | 5676 |
| 5695 } } // namespace v8::internal | 5677 } } // namespace v8::internal |
| OLD | NEW |