Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(55)

Side by Side Diff: src/preparser.h

Issue 135213007: (Pre)Parser: Move FunctionState, BlockState and Scope handling to ParserBase. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/parser.cc ('k') | src/preparser.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 11 matching lines...) Expand all
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #ifndef V8_PREPARSER_H 28 #ifndef V8_PREPARSER_H
29 #define V8_PREPARSER_H 29 #define V8_PREPARSER_H
30 30
31 #include "hashmap.h" 31 #include "hashmap.h"
32 #include "scopes.h"
32 #include "token.h" 33 #include "token.h"
33 #include "scanner.h" 34 #include "scanner.h"
34 35
35 namespace v8 { 36 namespace v8 {
36 namespace internal { 37 namespace internal {
37 38
38 // Common base class shared between parser and pre-parser. 39 // Common base class shared between parser and pre-parser.
39 template <typename Traits> 40 template <typename Traits>
40 class ParserBase : public Traits { 41 class ParserBase : public Traits {
41 public: 42 public:
42 ParserBase(Scanner* scanner, uintptr_t stack_limit, 43 ParserBase(Scanner* scanner, uintptr_t stack_limit,
43 typename Traits::ParserType this_object) 44 typename Traits::ParserType this_object)
44 : Traits(this_object), 45 : Traits(this_object),
45 parenthesized_function_(false), 46 parenthesized_function_(false),
47 scope_(NULL),
48 function_state_(NULL),
46 scanner_(scanner), 49 scanner_(scanner),
47 stack_limit_(stack_limit), 50 stack_limit_(stack_limit),
48 stack_overflow_(false), 51 stack_overflow_(false),
49 allow_lazy_(false), 52 allow_lazy_(false),
50 allow_natives_syntax_(false), 53 allow_natives_syntax_(false),
51 allow_generators_(false), 54 allow_generators_(false),
52 allow_for_of_(false) { } 55 allow_for_of_(false) { }
53 56
54 // Getters that indicate whether certain syntactical constructs are 57 // Getters that indicate whether certain syntactical constructs are
55 // allowed to be parsed by this instance of the parser. 58 // allowed to be parsed by this instance of the parser.
(...skipping 20 matching lines...) Expand all
76 void set_allow_harmony_numeric_literals(bool allow) { 79 void set_allow_harmony_numeric_literals(bool allow) {
77 scanner()->SetHarmonyNumericLiterals(allow); 80 scanner()->SetHarmonyNumericLiterals(allow);
78 } 81 }
79 82
80 protected: 83 protected:
81 enum AllowEvalOrArgumentsAsIdentifier { 84 enum AllowEvalOrArgumentsAsIdentifier {
82 kAllowEvalOrArguments, 85 kAllowEvalOrArguments,
83 kDontAllowEvalOrArguments 86 kDontAllowEvalOrArguments
84 }; 87 };
85 88
89 // ---------------------------------------------------------------------------
90 // FunctionState and BlockState together implement the parser's scope stack.
91 // The parser's current scope is in scope_. BlockState and FunctionState
92 // constructors push on the scope stack and the destructors pop. They are also
93 // used to hold the parser's per-function and per-block state.
94 class BlockState BASE_EMBEDDED {
95 public:
96 BlockState(typename Traits::ScopeClass** scope_stack,
97 typename Traits::ScopeClass* scope)
98 : scope_stack_(scope_stack),
99 outer_scope_(*scope_stack),
100 scope_(scope) {
101 *scope_stack_ = scope_;
102 }
103 ~BlockState() { *scope_stack_ = outer_scope_; }
104
105 private:
106 typename Traits::ScopeClass** scope_stack_;
107 typename Traits::ScopeClass* outer_scope_;
108 typename Traits::ScopeClass* scope_;
109 };
110
111 class FunctionState BASE_EMBEDDED {
112 public:
113 FunctionState(FunctionState** function_state_stack,
114 typename Traits::ScopeClass** scope_stack,
115 typename Traits::ScopeClass* scope,
116 typename Traits::FunctionStateParamType* extra_param = NULL);
ulan 2014/02/13 10:43:27 Maybe rename Traits::FunctionStateParamType to jus
marja 2014/02/13 15:57:51 Done.
117 ~FunctionState();
118
119 int NextMaterializedLiteralIndex() {
120 return next_materialized_literal_index_++;
121 }
122 int materialized_literal_count() {
123 return next_materialized_literal_index_ - JSFunction::kLiteralsPrefixSize;
124 }
125
126 int NextHandlerIndex() { return next_handler_index_++; }
127 int handler_count() { return next_handler_index_; }
128
129 void AddProperty() { expected_property_count_++; }
130 int expected_property_count() { return expected_property_count_; }
131
132 void set_is_generator(bool is_generator) { is_generator_ = is_generator; }
133 bool is_generator() const { return is_generator_; }
134
135 void set_generator_object_variable(
136 typename Traits::GeneratorVariableType* variable) {
137 ASSERT(variable != NULL);
138 ASSERT(!is_generator());
139 generator_object_variable_ = variable;
140 is_generator_ = true;
141 }
142 typename Traits::GeneratorVariableType* generator_object_variable() const {
143 return generator_object_variable_;
144 }
145
146 typename Traits::FactoryType* factory() { return &factory_; }
147
148 private:
149 // Used to assign an index to each literal that needs materialization in
150 // the function. Includes regexp literals, and boilerplate for object and
151 // array literals.
152 int next_materialized_literal_index_;
153
154 // Used to assign a per-function index to try and catch handlers.
155 int next_handler_index_;
156
157 // Properties count estimation.
158 int expected_property_count_;
159
160 // Whether the function is a generator.
161 bool is_generator_;
162 // For generators, this variable may hold the generator object. It variable
163 // is used by yield expressions and return statements. It is not necessary
164 // for generator functions to have this variable set.
165 Variable* generator_object_variable_;
166
167 FunctionState** function_state_stack_;
168 FunctionState* outer_function_state_;
169 typename Traits::ScopeClass** scope_stack_;
170 typename Traits::ScopeClass* outer_scope_;
171 Isolate* isolate_; // Only used by ParserTraits.
172 int saved_ast_node_id_; // Only used by ParserTraits.
173 typename Traits::FactoryType factory_;
174
175 friend class ParserTraits;
176 };
177
86 Scanner* scanner() const { return scanner_; } 178 Scanner* scanner() const { return scanner_; }
87 int position() { return scanner_->location().beg_pos; } 179 int position() { return scanner_->location().beg_pos; }
88 int peek_position() { return scanner_->peek_location().beg_pos; } 180 int peek_position() { return scanner_->peek_location().beg_pos; }
89 bool stack_overflow() const { return stack_overflow_; } 181 bool stack_overflow() const { return stack_overflow_; }
90 void set_stack_overflow() { stack_overflow_ = true; } 182 void set_stack_overflow() { stack_overflow_ = true; }
91 183
92 INLINE(Token::Value peek()) { 184 INLINE(Token::Value peek()) {
93 if (stack_overflow_) return Token::ILLEGAL; 185 if (stack_overflow_) return Token::ILLEGAL;
94 return scanner()->peek(); 186 return scanner()->peek();
95 } 187 }
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
186 } 278 }
187 } 279 }
188 280
189 // Determine precedence of given token. 281 // Determine precedence of given token.
190 static int Precedence(Token::Value token, bool accept_IN) { 282 static int Precedence(Token::Value token, bool accept_IN) {
191 if (token == Token::IN && !accept_IN) 283 if (token == Token::IN && !accept_IN)
192 return 0; // 0 precedence will terminate binary expression parsing 284 return 0; // 0 precedence will terminate binary expression parsing
193 return Token::Precedence(token); 285 return Token::Precedence(token);
194 } 286 }
195 287
288 typename Traits::FactoryType* factory() { return function_state_->factory(); }
289
290 bool is_classic_mode() const { return scope_->is_classic_mode(); }
291
292 bool is_generator() const { return function_state_->is_generator(); }
293
196 // Report syntax errors. 294 // Report syntax errors.
197 void ReportMessage(const char* message, Vector<const char*> args) { 295 void ReportMessage(const char* message, Vector<const char*> args) {
198 Scanner::Location source_location = scanner()->location(); 296 Scanner::Location source_location = scanner()->location();
199 Traits::ReportMessageAt(source_location, message, args); 297 Traits::ReportMessageAt(source_location, message, args);
200 } 298 }
201 299
202 void ReportMessageAt(Scanner::Location location, const char* message) { 300 void ReportMessageAt(Scanner::Location location, const char* message) {
203 Traits::ReportMessageAt(location, message, Vector<const char*>::empty()); 301 Traits::ReportMessageAt(location, message, Vector<const char*>::empty());
204 } 302 }
205 303
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
281 DuplicateFinder finder_; 379 DuplicateFinder finder_;
282 LanguageMode language_mode_; 380 LanguageMode language_mode_;
283 }; 381 };
284 382
285 // If true, the next (and immediately following) function literal is 383 // If true, the next (and immediately following) function literal is
286 // preceded by a parenthesis. 384 // preceded by a parenthesis.
287 // Heuristically that means that the function will be called immediately, 385 // Heuristically that means that the function will be called immediately,
288 // so never lazily compile it. 386 // so never lazily compile it.
289 bool parenthesized_function_; 387 bool parenthesized_function_;
290 388
389 typename Traits::ScopeClass* scope_; // Scope stack.
390 FunctionState* function_state_; // Function state stack.
391
291 private: 392 private:
292 Scanner* scanner_; 393 Scanner* scanner_;
293 uintptr_t stack_limit_; 394 uintptr_t stack_limit_;
294 bool stack_overflow_; 395 bool stack_overflow_;
295 396
296 bool allow_lazy_; 397 bool allow_lazy_;
297 bool allow_natives_syntax_; 398 bool allow_natives_syntax_;
298 bool allow_generators_; 399 bool allow_generators_;
299 bool allow_for_of_; 400 bool allow_for_of_;
300 }; 401 };
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
427 528
428 int code_; 529 int code_;
429 }; 530 };
430 531
431 class PreParser; 532 class PreParser;
432 533
433 534
434 class PreParserTraits { 535 class PreParserTraits {
435 public: 536 public:
436 typedef PreParser* ParserType; 537 typedef PreParser* ParserType;
538
539 // Types used by FunctionState and BlockState.
540 class Scope;
541 typedef PreParserTraits::Scope ScopeClass;
542 class Factory;
543 typedef PreParserTraits::Factory FactoryType;
544 // PreParser doesn't need to store generator variables.
545 typedef void GeneratorVariableType;
546 typedef void FunctionStateParamType;
547
437 // Return types for traversing functions. 548 // Return types for traversing functions.
438 typedef PreParserIdentifier IdentifierType; 549 typedef PreParserIdentifier IdentifierType;
439 typedef PreParserExpression ExpressionType; 550 typedef PreParserExpression ExpressionType;
440 551
552 class Scope {
553 public:
554 explicit Scope(Scope* outer_scope, ScopeType scope_type)
555 : scope_type_(scope_type) {
556 if (outer_scope) {
557 scope_inside_with_ =
558 outer_scope->scope_inside_with_ || is_with_scope();
559 language_mode_ = outer_scope->language_mode();
560 } else {
561 scope_inside_with_ = is_with_scope();
562 language_mode_ = CLASSIC_MODE;
563 }
564 }
565
566 bool is_with_scope() const { return scope_type_ == WITH_SCOPE; }
567 bool is_classic_mode() const {
568 return language_mode() == CLASSIC_MODE;
569 }
570 bool is_extended_mode() {
571 return language_mode() == EXTENDED_MODE;
572 }
573 bool inside_with() const {
574 return scope_inside_with_;
575 }
576
577 ScopeType type() { return scope_type_; }
578 LanguageMode language_mode() const { return language_mode_; }
579 void SetLanguageMode(LanguageMode language_mode) {
580 language_mode_ = language_mode;
581 }
582
583 private:
584 ScopeType scope_type_;
585 bool scope_inside_with_;
586 LanguageMode language_mode_;
587 };
588
589 class Factory {
590 public:
591 explicit Factory(void* extra_param) {}
592
593 ExpressionType NewRegExpLiteral(IdentifierType js_pattern,
594 IdentifierType js_flags,
595 int literal_index,
596 int pos) {
597 return PreParserExpression::Default();
598 }
599 };
600
441 explicit PreParserTraits(PreParser* pre_parser) : pre_parser_(pre_parser) {} 601 explicit PreParserTraits(PreParser* pre_parser) : pre_parser_(pre_parser) {}
442 602
603 // Custom operations executed when FunctionStates are created and
604 // destructed. (The PreParser doesn't need to do anything.)
605 template<typename FS>
606 static void SetUpFunctionState(FS* function_state, void*) {}
607 template<typename FS>
608 static void TearDownFunctionState(FS* function_state) {}
609
443 // Helper functions for recursive descent. 610 // Helper functions for recursive descent.
444 bool is_classic_mode() const;
445 bool is_generator() const;
446 static bool IsEvalOrArguments(IdentifierType identifier) { 611 static bool IsEvalOrArguments(IdentifierType identifier) {
447 return identifier.IsEvalOrArguments(); 612 return identifier.IsEvalOrArguments();
448 } 613 }
449 int NextMaterializedLiteralIndex();
450 614
451 // Reporting errors. 615 // Reporting errors.
452 void ReportMessageAt(Scanner::Location location, 616 void ReportMessageAt(Scanner::Location location,
453 const char* message, 617 const char* message,
454 Vector<const char*> args); 618 Vector<const char*> args);
455 void ReportMessageAt(Scanner::Location location, 619 void ReportMessageAt(Scanner::Location location,
456 const char* type, 620 const char* type,
457 const char* name_opt); 621 const char* name_opt);
458 void ReportMessageAt(int start_pos, 622 void ReportMessageAt(int start_pos,
459 int end_pos, 623 int end_pos,
460 const char* type, 624 const char* type,
461 const char* name_opt); 625 const char* name_opt);
462 626
463 // "null" return type creators. 627 // "null" return type creators.
464 static IdentifierType EmptyIdentifier() { 628 static IdentifierType EmptyIdentifier() {
465 return PreParserIdentifier::Default(); 629 return PreParserIdentifier::Default();
466 } 630 }
467 static ExpressionType EmptyExpression() { 631 static ExpressionType EmptyExpression() {
468 return PreParserExpression::Default(); 632 return PreParserExpression::Default();
469 } 633 }
470 634
471 // Producing data during the recursive descent. 635 // Producing data during the recursive descent.
472 IdentifierType GetSymbol(); 636 IdentifierType GetSymbol();
473 static IdentifierType NextLiteralString(PretenureFlag tenured) { 637 static IdentifierType NextLiteralString(PretenureFlag tenured) {
474 return PreParserIdentifier::Default(); 638 return PreParserIdentifier::Default();
475 } 639 }
476 ExpressionType NewRegExpLiteral(IdentifierType js_pattern,
477 IdentifierType js_flags,
478 int literal_index,
479 int pos) {
480 return PreParserExpression::Default();
481 }
482 640
483 private: 641 private:
484 PreParser* pre_parser_; 642 PreParser* pre_parser_;
485 }; 643 };
486 644
487 645
488 // Preparsing checks a JavaScript program and emits preparse-data that helps 646 // Preparsing checks a JavaScript program and emits preparse-data that helps
489 // a later parsing to be faster. 647 // a later parsing to be faster.
490 // See preparse-data-format.h for the data format. 648 // See preparse-data-format.h for the data format.
491 649
(...skipping 12 matching lines...) Expand all
504 662
505 enum PreParseResult { 663 enum PreParseResult {
506 kPreParseStackOverflow, 664 kPreParseStackOverflow,
507 kPreParseSuccess 665 kPreParseSuccess
508 }; 666 };
509 667
510 PreParser(Scanner* scanner, 668 PreParser(Scanner* scanner,
511 ParserRecorder* log, 669 ParserRecorder* log,
512 uintptr_t stack_limit) 670 uintptr_t stack_limit)
513 : ParserBase<PreParserTraits>(scanner, stack_limit, this), 671 : ParserBase<PreParserTraits>(scanner, stack_limit, this),
514 log_(log), 672 log_(log) {}
515 function_state_(NULL),
516 scope_(NULL) { }
517
518 ~PreParser() {}
519 673
520 // Pre-parse the program from the character stream; returns true on 674 // Pre-parse the program from the character stream; returns true on
521 // success (even if parsing failed, the pre-parse data successfully 675 // success (even if parsing failed, the pre-parse data successfully
522 // captured the syntax error), and false if a stack-overflow happened 676 // captured the syntax error), and false if a stack-overflow happened
523 // during parsing. 677 // during parsing.
524 PreParseResult PreParseProgram() { 678 PreParseResult PreParseProgram() {
525 FunctionState top_scope(&function_state_, &scope_, GLOBAL_SCOPE); 679 PreParserTraits::Scope scope(scope_, GLOBAL_SCOPE);
680 FunctionState top_scope(&function_state_, &scope_, &scope, NULL);
526 bool ok = true; 681 bool ok = true;
527 int start_position = scanner()->peek_location().beg_pos; 682 int start_position = scanner()->peek_location().beg_pos;
528 ParseSourceElements(Token::EOS, &ok); 683 ParseSourceElements(Token::EOS, &ok);
529 if (stack_overflow()) return kPreParseStackOverflow; 684 if (stack_overflow()) return kPreParseStackOverflow;
530 if (!ok) { 685 if (!ok) {
531 ReportUnexpectedToken(scanner()->current_token()); 686 ReportUnexpectedToken(scanner()->current_token());
532 } else if (!scope_->is_classic_mode()) { 687 } else if (!scope_->is_classic_mode()) {
533 CheckOctalLiteral(start_position, scanner()->location().end_pos, &ok); 688 CheckOctalLiteral(start_position, scanner()->location().end_pos, &ok);
534 } 689 }
535 return kPreParseSuccess; 690 return kPreParseSuccess;
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
613 explicit Statement(Type code) : code_(code) {} 768 explicit Statement(Type code) : code_(code) {}
614 Type code_; 769 Type code_;
615 }; 770 };
616 771
617 enum SourceElements { 772 enum SourceElements {
618 kUnknownSourceElements 773 kUnknownSourceElements
619 }; 774 };
620 775
621 typedef int Arguments; 776 typedef int Arguments;
622 777
623 class Scope {
624 public:
625 explicit Scope(Scope* outer_scope, ScopeType scope_type)
626 : scope_type_(scope_type) {
627 if (outer_scope) {
628 scope_inside_with_ =
629 outer_scope->scope_inside_with_ || is_with_scope();
630 language_mode_ = outer_scope->language_mode();
631 } else {
632 scope_inside_with_ = is_with_scope();
633 language_mode_ = CLASSIC_MODE;
634 }
635 }
636
637 bool is_with_scope() const { return scope_type_ == WITH_SCOPE; }
638 bool is_classic_mode() const {
639 return language_mode() == CLASSIC_MODE;
640 }
641 bool is_extended_mode() {
642 return language_mode() == EXTENDED_MODE;
643 }
644 bool inside_with() const {
645 return scope_inside_with_;
646 }
647
648 ScopeType type() { return scope_type_; }
649 LanguageMode language_mode() const { return language_mode_; }
650 void SetLanguageMode(LanguageMode language_mode) {
651 language_mode_ = language_mode;
652 }
653
654 private:
655 ScopeType scope_type_;
656 bool scope_inside_with_;
657 LanguageMode language_mode_;
658 };
659
660 class FunctionState {
661 public:
662 FunctionState(FunctionState** function_state_stack, Scope** scope_stack,
663 ScopeType scope_type)
664 : function_state_stack_(function_state_stack),
665 outer_function_state_(*function_state_stack),
666 scope_stack_(scope_stack),
667 outer_scope_(*scope_stack),
668 scope_(*scope_stack, scope_type),
669 materialized_literal_count_(0),
670 expected_properties_(0),
671 is_generator_(false) {
672 *scope_stack = &scope_;
673 *function_state_stack = this;
674 }
675 ~FunctionState() {
676 *scope_stack_ = outer_scope_;
677 *function_state_stack_ = outer_function_state_;
678 }
679 int NextMaterializedLiteralIndex() { return materialized_literal_count_++; }
680 void AddProperty() { expected_properties_++; }
681 int expected_properties() { return expected_properties_; }
682 int materialized_literal_count() { return materialized_literal_count_; }
683 bool is_generator() { return is_generator_; }
684 void set_is_generator(bool is_generator) { is_generator_ = is_generator; }
685
686 private:
687 FunctionState** const function_state_stack_;
688 FunctionState* const outer_function_state_;
689 Scope** const scope_stack_;
690 Scope* const outer_scope_;
691 Scope scope_;
692
693 int materialized_literal_count_;
694 int expected_properties_;
695 LanguageMode language_mode_;
696 bool is_generator_;
697 };
698
699 class BlockState {
700 public:
701 BlockState(Scope** scope_stack, ScopeType scope_type)
702 : scope_stack_(scope_stack),
703 outer_scope_(*scope_stack),
704 scope_(*scope_stack, scope_type) {
705 *scope_stack_ = &scope_;
706 }
707
708 ~BlockState() { *scope_stack_ = outer_scope_; }
709
710 private:
711 Scope** scope_stack_;
712 Scope* outer_scope_;
713 Scope scope_;
714 };
715
716 // All ParseXXX functions take as the last argument an *ok parameter 778 // All ParseXXX functions take as the last argument an *ok parameter
717 // which is set to false if parsing failed; it is unchanged otherwise. 779 // which is set to false if parsing failed; it is unchanged otherwise.
718 // By making the 'exception handling' explicit, we are forced to check 780 // By making the 'exception handling' explicit, we are forced to check
719 // for failure at the call sites. 781 // for failure at the call sites.
720 Statement ParseSourceElement(bool* ok); 782 Statement ParseSourceElement(bool* ok);
721 SourceElements ParseSourceElements(int end_token, bool* ok); 783 SourceElements ParseSourceElements(int end_token, bool* ok);
722 Statement ParseStatement(bool* ok); 784 Statement ParseStatement(bool* ok);
723 Statement ParseFunctionDeclaration(bool* ok); 785 Statement ParseFunctionDeclaration(bool* ok);
724 Statement ParseBlock(bool* ok); 786 Statement ParseBlock(bool* ok);
725 Statement ParseVariableStatement(VariableDeclarationContext var_context, 787 Statement ParseVariableStatement(VariableDeclarationContext var_context,
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
768 void ParseLazyFunctionLiteralBody(bool* ok); 830 void ParseLazyFunctionLiteralBody(bool* ok);
769 831
770 // Logs the currently parsed literal as a symbol in the preparser data. 832 // Logs the currently parsed literal as a symbol in the preparser data.
771 void LogSymbol(); 833 void LogSymbol();
772 // Log the currently parsed string literal. 834 // Log the currently parsed string literal.
773 Expression GetStringSymbol(); 835 Expression GetStringSymbol();
774 836
775 bool CheckInOrOf(bool accept_OF); 837 bool CheckInOrOf(bool accept_OF);
776 838
777 ParserRecorder* log_; 839 ParserRecorder* log_;
778 FunctionState* function_state_;
779 Scope* scope_;
780 }; 840 };
781 841
782 842
783 template<class Traits> 843 template<class Traits>
844 ParserBase<Traits>::FunctionState::FunctionState(
845 FunctionState** function_state_stack,
846 typename Traits::ScopeClass** scope_stack,
847 typename Traits::ScopeClass* scope,
848 typename Traits::FunctionStateParamType* extra_param)
849 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize),
850 next_handler_index_(0),
851 expected_property_count_(0),
852 is_generator_(false),
853 generator_object_variable_(NULL),
854 function_state_stack_(function_state_stack),
855 outer_function_state_(*function_state_stack),
856 scope_stack_(scope_stack),
857 outer_scope_(*scope_stack),
858 isolate_(NULL),
859 saved_ast_node_id_(0),
860 factory_(extra_param) {
861 *scope_stack_ = scope;
862 *function_state_stack = this;
863 Traits::SetUpFunctionState(this, extra_param);
864 }
865
866
867 template<class Traits>
868 ParserBase<Traits>::FunctionState::~FunctionState() {
869 *scope_stack_ = outer_scope_;
870 *function_state_stack_ = outer_function_state_;
871 Traits::TearDownFunctionState(this);
872 }
873
874
875 template<class Traits>
784 void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) { 876 void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) {
785 // We don't report stack overflows here, to avoid increasing the 877 // We don't report stack overflows here, to avoid increasing the
786 // stack depth even further. Instead we report it after parsing is 878 // stack depth even further. Instead we report it after parsing is
787 // over, in ParseProgram. 879 // over, in ParseProgram.
788 if (token == Token::ILLEGAL && stack_overflow()) { 880 if (token == Token::ILLEGAL && stack_overflow()) {
789 return; 881 return;
790 } 882 }
791 Scanner::Location source_location = scanner()->location(); 883 Scanner::Location source_location = scanner()->location();
792 884
793 // Four of the tokens are treated specially 885 // Four of the tokens are treated specially
794 switch (token) { 886 switch (token) {
795 case Token::EOS: 887 case Token::EOS:
796 return ReportMessageAt(source_location, "unexpected_eos"); 888 return ReportMessageAt(source_location, "unexpected_eos");
797 case Token::NUMBER: 889 case Token::NUMBER:
798 return ReportMessageAt(source_location, "unexpected_token_number"); 890 return ReportMessageAt(source_location, "unexpected_token_number");
799 case Token::STRING: 891 case Token::STRING:
800 return ReportMessageAt(source_location, "unexpected_token_string"); 892 return ReportMessageAt(source_location, "unexpected_token_string");
801 case Token::IDENTIFIER: 893 case Token::IDENTIFIER:
802 return ReportMessageAt(source_location, "unexpected_token_identifier"); 894 return ReportMessageAt(source_location, "unexpected_token_identifier");
803 case Token::FUTURE_RESERVED_WORD: 895 case Token::FUTURE_RESERVED_WORD:
804 return ReportMessageAt(source_location, "unexpected_reserved"); 896 return ReportMessageAt(source_location, "unexpected_reserved");
805 case Token::YIELD: 897 case Token::YIELD:
806 case Token::FUTURE_STRICT_RESERVED_WORD: 898 case Token::FUTURE_STRICT_RESERVED_WORD:
807 return ReportMessageAt( 899 return ReportMessageAt(source_location,
808 source_location, 900 is_classic_mode() ? "unexpected_token_identifier"
809 this->is_classic_mode() ? "unexpected_token_identifier" 901 : "unexpected_strict_reserved");
810 : "unexpected_strict_reserved");
811 default: 902 default:
812 const char* name = Token::String(token); 903 const char* name = Token::String(token);
813 ASSERT(name != NULL); 904 ASSERT(name != NULL);
814 Traits::ReportMessageAt( 905 Traits::ReportMessageAt(
815 source_location, "unexpected_token", Vector<const char*>(&name, 1)); 906 source_location, "unexpected_token", Vector<const char*>(&name, 1));
816 } 907 }
817 } 908 }
818 909
819 910
820 template<class Traits> 911 template<class Traits>
821 typename Traits::IdentifierType ParserBase<Traits>::ParseIdentifier( 912 typename Traits::IdentifierType ParserBase<Traits>::ParseIdentifier(
822 AllowEvalOrArgumentsAsIdentifier allow_eval_or_arguments, 913 AllowEvalOrArgumentsAsIdentifier allow_eval_or_arguments,
823 bool* ok) { 914 bool* ok) {
824 Token::Value next = Next(); 915 Token::Value next = Next();
825 if (next == Token::IDENTIFIER) { 916 if (next == Token::IDENTIFIER) {
826 typename Traits::IdentifierType name = this->GetSymbol(); 917 typename Traits::IdentifierType name = this->GetSymbol();
827 if (allow_eval_or_arguments == kDontAllowEvalOrArguments && 918 if (allow_eval_or_arguments == kDontAllowEvalOrArguments &&
828 !this->is_classic_mode() && this->IsEvalOrArguments(name)) { 919 !is_classic_mode() && this->IsEvalOrArguments(name)) {
829 ReportMessageAt(scanner()->location(), "strict_eval_arguments"); 920 ReportMessageAt(scanner()->location(), "strict_eval_arguments");
830 *ok = false; 921 *ok = false;
831 } 922 }
832 return name; 923 return name;
833 } else if (this->is_classic_mode() && 924 } else if (is_classic_mode() && (next == Token::FUTURE_STRICT_RESERVED_WORD ||
834 (next == Token::FUTURE_STRICT_RESERVED_WORD || 925 (next == Token::YIELD && !is_generator()))) {
835 (next == Token::YIELD && !this->is_generator()))) {
836 return this->GetSymbol(); 926 return this->GetSymbol();
837 } else { 927 } else {
838 this->ReportUnexpectedToken(next); 928 this->ReportUnexpectedToken(next);
839 *ok = false; 929 *ok = false;
840 return Traits::EmptyIdentifier(); 930 return Traits::EmptyIdentifier();
841 } 931 }
842 } 932 }
843 933
844 934
845 template <class Traits> 935 template <class Traits>
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
896 typename Traits::ExpressionType 986 typename Traits::ExpressionType
897 ParserBase<Traits>::ParseRegExpLiteral(bool seen_equal, bool* ok) { 987 ParserBase<Traits>::ParseRegExpLiteral(bool seen_equal, bool* ok) {
898 int pos = peek_position(); 988 int pos = peek_position();
899 if (!scanner()->ScanRegExpPattern(seen_equal)) { 989 if (!scanner()->ScanRegExpPattern(seen_equal)) {
900 Next(); 990 Next();
901 ReportMessage("unterminated_regexp", Vector<const char*>::empty()); 991 ReportMessage("unterminated_regexp", Vector<const char*>::empty());
902 *ok = false; 992 *ok = false;
903 return Traits::EmptyExpression(); 993 return Traits::EmptyExpression();
904 } 994 }
905 995
906 int literal_index = this->NextMaterializedLiteralIndex(); 996 int literal_index = function_state_->NextMaterializedLiteralIndex();
907 997
908 typename Traits::IdentifierType js_pattern = this->NextLiteralString(TENURED); 998 typename Traits::IdentifierType js_pattern = this->NextLiteralString(TENURED);
909 if (!scanner()->ScanRegExpFlags()) { 999 if (!scanner()->ScanRegExpFlags()) {
910 Next(); 1000 Next();
911 ReportMessageAt(scanner()->location(), "invalid_regexp_flags"); 1001 ReportMessageAt(scanner()->location(), "invalid_regexp_flags");
912 *ok = false; 1002 *ok = false;
913 return Traits::EmptyExpression(); 1003 return Traits::EmptyExpression();
914 } 1004 }
915 typename Traits::IdentifierType js_flags = this->NextLiteralString(TENURED); 1005 typename Traits::IdentifierType js_flags = this->NextLiteralString(TENURED);
916 Next(); 1006 Next();
917 return this->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos); 1007 return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos);
918 } 1008 }
919 1009
920 1010
921 template <typename Traits> 1011 template <typename Traits>
922 void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty( 1012 void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty(
923 Token::Value property, 1013 Token::Value property,
924 PropertyKind type, 1014 PropertyKind type,
925 bool* ok) { 1015 bool* ok) {
926 int old; 1016 int old;
927 if (property == Token::NUMBER) { 1017 if (property == Token::NUMBER) {
(...skipping 21 matching lines...) Expand all
949 "accessor_get_set"); 1039 "accessor_get_set");
950 } 1040 }
951 *ok = false; 1041 *ok = false;
952 } 1042 }
953 } 1043 }
954 1044
955 1045
956 } } // v8::internal 1046 } } // v8::internal
957 1047
958 #endif // V8_PREPARSER_H 1048 #endif // V8_PREPARSER_H
OLDNEW
« no previous file with comments | « src/parser.cc ('k') | src/preparser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698