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

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: rebased 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::Type::Parser 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::Type::Scope** scope_stack,
97 typename Traits::Type::Scope* 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::Type::Scope** scope_stack_;
107 typename Traits::Type::Scope* outer_scope_;
108 typename Traits::Type::Scope* scope_;
109 };
110
111 class FunctionState BASE_EMBEDDED {
112 public:
113 FunctionState(
114 FunctionState** function_state_stack,
115 typename Traits::Type::Scope** scope_stack,
116 typename Traits::Type::Scope* scope,
117 typename Traits::Type::Zone* zone = NULL);
118 ~FunctionState();
119
120 int NextMaterializedLiteralIndex() {
121 return next_materialized_literal_index_++;
122 }
123 int materialized_literal_count() {
124 return next_materialized_literal_index_ - JSFunction::kLiteralsPrefixSize;
125 }
126
127 int NextHandlerIndex() { return next_handler_index_++; }
128 int handler_count() { return next_handler_index_; }
129
130 void AddProperty() { expected_property_count_++; }
131 int expected_property_count() { return expected_property_count_; }
132
133 void set_is_generator(bool is_generator) { is_generator_ = is_generator; }
134 bool is_generator() const { return is_generator_; }
135
136 void set_generator_object_variable(
137 typename Traits::Type::GeneratorVariable* variable) {
138 ASSERT(variable != NULL);
139 ASSERT(!is_generator());
140 generator_object_variable_ = variable;
141 is_generator_ = true;
142 }
143 typename Traits::Type::GeneratorVariable* generator_object_variable()
144 const {
145 return generator_object_variable_;
146 }
147
148 typename Traits::Type::Factory* factory() { return &factory_; }
149
150 private:
151 // Used to assign an index to each literal that needs materialization in
152 // the function. Includes regexp literals, and boilerplate for object and
153 // array literals.
154 int next_materialized_literal_index_;
155
156 // Used to assign a per-function index to try and catch handlers.
157 int next_handler_index_;
158
159 // Properties count estimation.
160 int expected_property_count_;
161
162 // Whether the function is a generator.
163 bool is_generator_;
164 // For generators, this variable may hold the generator object. It variable
165 // is used by yield expressions and return statements. It is not necessary
166 // for generator functions to have this variable set.
167 Variable* generator_object_variable_;
168
169 FunctionState** function_state_stack_;
170 FunctionState* outer_function_state_;
171 typename Traits::Type::Scope** scope_stack_;
172 typename Traits::Type::Scope* outer_scope_;
173 Isolate* isolate_; // Only used by ParserTraits.
174 int saved_ast_node_id_; // Only used by ParserTraits.
175 typename Traits::Type::Factory factory_;
176
177 friend class ParserTraits;
178 };
179
86 Scanner* scanner() const { return scanner_; } 180 Scanner* scanner() const { return scanner_; }
87 int position() { return scanner_->location().beg_pos; } 181 int position() { return scanner_->location().beg_pos; }
88 int peek_position() { return scanner_->peek_location().beg_pos; } 182 int peek_position() { return scanner_->peek_location().beg_pos; }
89 bool stack_overflow() const { return stack_overflow_; } 183 bool stack_overflow() const { return stack_overflow_; }
90 void set_stack_overflow() { stack_overflow_ = true; } 184 void set_stack_overflow() { stack_overflow_ = true; }
91 185
92 INLINE(Token::Value peek()) { 186 INLINE(Token::Value peek()) {
93 if (stack_overflow_) return Token::ILLEGAL; 187 if (stack_overflow_) return Token::ILLEGAL;
94 return scanner()->peek(); 188 return scanner()->peek();
95 } 189 }
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
186 } 280 }
187 } 281 }
188 282
189 // Determine precedence of given token. 283 // Determine precedence of given token.
190 static int Precedence(Token::Value token, bool accept_IN) { 284 static int Precedence(Token::Value token, bool accept_IN) {
191 if (token == Token::IN && !accept_IN) 285 if (token == Token::IN && !accept_IN)
192 return 0; // 0 precedence will terminate binary expression parsing 286 return 0; // 0 precedence will terminate binary expression parsing
193 return Token::Precedence(token); 287 return Token::Precedence(token);
194 } 288 }
195 289
290 typename Traits::Type::Factory* factory() {
291 return function_state_->factory();
292 }
293
294 bool is_classic_mode() const { return scope_->is_classic_mode(); }
295
296 bool is_generator() const { return function_state_->is_generator(); }
297
196 // Report syntax errors. 298 // Report syntax errors.
197 void ReportMessage(const char* message, Vector<const char*> args) { 299 void ReportMessage(const char* message, Vector<const char*> args) {
198 Scanner::Location source_location = scanner()->location(); 300 Scanner::Location source_location = scanner()->location();
199 Traits::ReportMessageAt(source_location, message, args); 301 Traits::ReportMessageAt(source_location, message, args);
200 } 302 }
201 303
202 void ReportMessageAt(Scanner::Location location, const char* message) { 304 void ReportMessageAt(Scanner::Location location, const char* message) {
203 Traits::ReportMessageAt(location, message, Vector<const char*>::empty()); 305 Traits::ReportMessageAt(location, message, Vector<const char*>::empty());
204 } 306 }
205 307
206 void ReportUnexpectedToken(Token::Value token); 308 void ReportUnexpectedToken(Token::Value token);
207 309
208 // Recursive descent functions: 310 // Recursive descent functions:
209 311
210 // Parses an identifier that is valid for the current scope, in particular it 312 // Parses an identifier that is valid for the current scope, in particular it
211 // fails on strict mode future reserved keywords in a strict scope. If 313 // fails on strict mode future reserved keywords in a strict scope. If
212 // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or 314 // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or
213 // "arguments" as identifier even in strict mode (this is needed in cases like 315 // "arguments" as identifier even in strict mode (this is needed in cases like
214 // "var foo = eval;"). 316 // "var foo = eval;").
215 typename Traits::IdentifierType ParseIdentifier( 317 typename Traits::Type::Identifier ParseIdentifier(
216 AllowEvalOrArgumentsAsIdentifier, 318 AllowEvalOrArgumentsAsIdentifier,
217 bool* ok); 319 bool* ok);
218 // Parses an identifier or a strict mode future reserved word, and indicate 320 // Parses an identifier or a strict mode future reserved word, and indicate
219 // whether it is strict mode future reserved. 321 // whether it is strict mode future reserved.
220 typename Traits::IdentifierType ParseIdentifierOrStrictReservedWord( 322 typename Traits::Type::Identifier ParseIdentifierOrStrictReservedWord(
221 bool* is_strict_reserved, 323 bool* is_strict_reserved,
222 bool* ok); 324 bool* ok);
223 typename Traits::IdentifierType ParseIdentifierName(bool* ok); 325 typename Traits::Type::Identifier ParseIdentifierName(bool* ok);
224 // Parses an identifier and determines whether or not it is 'get' or 'set'. 326 // Parses an identifier and determines whether or not it is 'get' or 'set'.
225 typename Traits::IdentifierType ParseIdentifierNameOrGetOrSet(bool* is_get, 327 typename Traits::Type::Identifier ParseIdentifierNameOrGetOrSet(bool* is_get,
226 bool* is_set, 328 bool* is_set,
227 bool* ok); 329 bool* ok);
228 330
229 typename Traits::ExpressionType ParseRegExpLiteral(bool seen_equal, bool* ok); 331 typename Traits::Type::Expression ParseRegExpLiteral(bool seen_equal,
332 bool* ok);
230 333
231 // Used to detect duplicates in object literals. Each of the values 334 // Used to detect duplicates in object literals. Each of the values
232 // kGetterProperty, kSetterProperty and kValueProperty represents 335 // kGetterProperty, kSetterProperty and kValueProperty represents
233 // a type of object literal property. When parsing a property, its 336 // a type of object literal property. When parsing a property, its
234 // type value is stored in the DuplicateFinder for the property name. 337 // type value is stored in the DuplicateFinder for the property name.
235 // Values are chosen so that having intersection bits means the there is 338 // Values are chosen so that having intersection bits means the there is
236 // an incompatibility. 339 // an incompatibility.
237 // I.e., you can add a getter to a property that already has a setter, since 340 // I.e., you can add a getter to a property that already has a setter, since
238 // kGetterProperty and kSetterProperty doesn't intersect, but not if it 341 // kGetterProperty and kSetterProperty doesn't intersect, but not if it
239 // already has a getter or a value. Adding the getter to an existing 342 // already has a getter or a value. Adding the getter to an existing
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
281 DuplicateFinder finder_; 384 DuplicateFinder finder_;
282 LanguageMode language_mode_; 385 LanguageMode language_mode_;
283 }; 386 };
284 387
285 // If true, the next (and immediately following) function literal is 388 // If true, the next (and immediately following) function literal is
286 // preceded by a parenthesis. 389 // preceded by a parenthesis.
287 // Heuristically that means that the function will be called immediately, 390 // Heuristically that means that the function will be called immediately,
288 // so never lazily compile it. 391 // so never lazily compile it.
289 bool parenthesized_function_; 392 bool parenthesized_function_;
290 393
394 typename Traits::Type::Scope* scope_; // Scope stack.
395 FunctionState* function_state_; // Function state stack.
396
291 private: 397 private:
292 Scanner* scanner_; 398 Scanner* scanner_;
293 uintptr_t stack_limit_; 399 uintptr_t stack_limit_;
294 bool stack_overflow_; 400 bool stack_overflow_;
295 401
296 bool allow_lazy_; 402 bool allow_lazy_;
297 bool allow_natives_syntax_; 403 bool allow_natives_syntax_;
298 bool allow_generators_; 404 bool allow_generators_;
299 bool allow_for_of_; 405 bool allow_for_of_;
300 }; 406 };
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
421 kThisExpression = 4, 527 kThisExpression = 4,
422 kThisPropertyExpression = 8, 528 kThisPropertyExpression = 8,
423 kStrictFunctionExpression = 12 529 kStrictFunctionExpression = 12
424 }; 530 };
425 531
426 explicit PreParserExpression(int expression_code) : code_(expression_code) {} 532 explicit PreParserExpression(int expression_code) : code_(expression_code) {}
427 533
428 int code_; 534 int code_;
429 }; 535 };
430 536
537
538 class PreParserScope {
539 public:
540 explicit PreParserScope(PreParserScope* outer_scope, ScopeType scope_type)
541 : scope_type_(scope_type) {
542 if (outer_scope) {
543 scope_inside_with_ =
544 outer_scope->scope_inside_with_ || is_with_scope();
545 language_mode_ = outer_scope->language_mode();
546 } else {
547 scope_inside_with_ = is_with_scope();
548 language_mode_ = CLASSIC_MODE;
549 }
550 }
551
552 bool is_with_scope() const { return scope_type_ == WITH_SCOPE; }
553 bool is_classic_mode() const {
554 return language_mode() == CLASSIC_MODE;
555 }
556 bool is_extended_mode() {
557 return language_mode() == EXTENDED_MODE;
558 }
559 bool inside_with() const {
560 return scope_inside_with_;
561 }
562
563 ScopeType type() { return scope_type_; }
564 LanguageMode language_mode() const { return language_mode_; }
565 void SetLanguageMode(LanguageMode language_mode) {
566 language_mode_ = language_mode;
567 }
568
569 private:
570 ScopeType scope_type_;
571 bool scope_inside_with_;
572 LanguageMode language_mode_;
573 };
574
575
576 class PreParserFactory {
577 public:
578 explicit PreParserFactory(void* extra_param) {}
579
580 PreParserExpression NewRegExpLiteral(PreParserIdentifier js_pattern,
581 PreParserIdentifier js_flags,
582 int literal_index,
583 int pos) {
584 return PreParserExpression::Default();
585 }
586 };
587
588
431 class PreParser; 589 class PreParser;
432 590
433
434 class PreParserTraits { 591 class PreParserTraits {
435 public: 592 public:
436 typedef PreParser* ParserType; 593 struct Type {
437 // Return types for traversing functions. 594 typedef PreParser* Parser;
438 typedef PreParserIdentifier IdentifierType; 595
439 typedef PreParserExpression ExpressionType; 596 // Types used by FunctionState and BlockState.
597 typedef PreParserScope Scope;
598 typedef PreParserFactory Factory;
599 // PreParser doesn't need to store generator variables.
600 typedef void GeneratorVariable;
601 // No interaction with Zones.
602 typedef void Zone;
603
604 // Return types for traversing functions.
605 typedef PreParserIdentifier Identifier;
606 typedef PreParserExpression Expression;
607 };
440 608
441 explicit PreParserTraits(PreParser* pre_parser) : pre_parser_(pre_parser) {} 609 explicit PreParserTraits(PreParser* pre_parser) : pre_parser_(pre_parser) {}
442 610
611 // Custom operations executed when FunctionStates are created and
612 // destructed. (The PreParser doesn't need to do anything.)
613 template<typename FS>
614 static void SetUpFunctionState(FS* function_state, void*) {}
615 template<typename FS>
616 static void TearDownFunctionState(FS* function_state) {}
617
443 // Helper functions for recursive descent. 618 // Helper functions for recursive descent.
444 bool is_classic_mode() const; 619 static bool IsEvalOrArguments(PreParserIdentifier identifier) {
445 bool is_generator() const;
446 static bool IsEvalOrArguments(IdentifierType identifier) {
447 return identifier.IsEvalOrArguments(); 620 return identifier.IsEvalOrArguments();
448 } 621 }
449 int NextMaterializedLiteralIndex();
450 622
451 // Reporting errors. 623 // Reporting errors.
452 void ReportMessageAt(Scanner::Location location, 624 void ReportMessageAt(Scanner::Location location,
453 const char* message, 625 const char* message,
454 Vector<const char*> args); 626 Vector<const char*> args);
455 void ReportMessageAt(Scanner::Location location, 627 void ReportMessageAt(Scanner::Location location,
456 const char* type, 628 const char* type,
457 const char* name_opt); 629 const char* name_opt);
458 void ReportMessageAt(int start_pos, 630 void ReportMessageAt(int start_pos,
459 int end_pos, 631 int end_pos,
460 const char* type, 632 const char* type,
461 const char* name_opt); 633 const char* name_opt);
462 634
463 // "null" return type creators. 635 // "null" return type creators.
464 static IdentifierType EmptyIdentifier() { 636 static PreParserIdentifier EmptyIdentifier() {
465 return PreParserIdentifier::Default(); 637 return PreParserIdentifier::Default();
466 } 638 }
467 static ExpressionType EmptyExpression() { 639 static PreParserExpression EmptyExpression() {
468 return PreParserExpression::Default(); 640 return PreParserExpression::Default();
469 } 641 }
470 642
471 // Producing data during the recursive descent. 643 // Producing data during the recursive descent.
472 IdentifierType GetSymbol(); 644 PreParserIdentifier GetSymbol();
473 static IdentifierType NextLiteralString(PretenureFlag tenured) { 645 static PreParserIdentifier NextLiteralString(PretenureFlag tenured) {
474 return PreParserIdentifier::Default(); 646 return PreParserIdentifier::Default();
475 } 647 }
476 ExpressionType NewRegExpLiteral(IdentifierType js_pattern,
477 IdentifierType js_flags,
478 int literal_index,
479 int pos) {
480 return PreParserExpression::Default();
481 }
482 648
483 private: 649 private:
484 PreParser* pre_parser_; 650 PreParser* pre_parser_;
485 }; 651 };
486 652
487 653
488 // Preparsing checks a JavaScript program and emits preparse-data that helps 654 // Preparsing checks a JavaScript program and emits preparse-data that helps
489 // a later parsing to be faster. 655 // a later parsing to be faster.
490 // See preparse-data-format.h for the data format. 656 // See preparse-data-format.h for the data format.
491 657
(...skipping 12 matching lines...) Expand all
504 670
505 enum PreParseResult { 671 enum PreParseResult {
506 kPreParseStackOverflow, 672 kPreParseStackOverflow,
507 kPreParseSuccess 673 kPreParseSuccess
508 }; 674 };
509 675
510 PreParser(Scanner* scanner, 676 PreParser(Scanner* scanner,
511 ParserRecorder* log, 677 ParserRecorder* log,
512 uintptr_t stack_limit) 678 uintptr_t stack_limit)
513 : ParserBase<PreParserTraits>(scanner, stack_limit, this), 679 : ParserBase<PreParserTraits>(scanner, stack_limit, this),
514 log_(log), 680 log_(log) {}
515 function_state_(NULL),
516 scope_(NULL) { }
517
518 ~PreParser() {}
519 681
520 // Pre-parse the program from the character stream; returns true on 682 // Pre-parse the program from the character stream; returns true on
521 // success (even if parsing failed, the pre-parse data successfully 683 // success (even if parsing failed, the pre-parse data successfully
522 // captured the syntax error), and false if a stack-overflow happened 684 // captured the syntax error), and false if a stack-overflow happened
523 // during parsing. 685 // during parsing.
524 PreParseResult PreParseProgram() { 686 PreParseResult PreParseProgram() {
525 FunctionState top_scope(&function_state_, &scope_, GLOBAL_SCOPE); 687 PreParserScope scope(scope_, GLOBAL_SCOPE);
688 FunctionState top_scope(&function_state_, &scope_, &scope, NULL);
526 bool ok = true; 689 bool ok = true;
527 int start_position = scanner()->peek_location().beg_pos; 690 int start_position = scanner()->peek_location().beg_pos;
528 ParseSourceElements(Token::EOS, &ok); 691 ParseSourceElements(Token::EOS, &ok);
529 if (stack_overflow()) return kPreParseStackOverflow; 692 if (stack_overflow()) return kPreParseStackOverflow;
530 if (!ok) { 693 if (!ok) {
531 ReportUnexpectedToken(scanner()->current_token()); 694 ReportUnexpectedToken(scanner()->current_token());
532 } else if (!scope_->is_classic_mode()) { 695 } else if (!scope_->is_classic_mode()) {
533 CheckOctalLiteral(start_position, scanner()->location().end_pos, &ok); 696 CheckOctalLiteral(start_position, scanner()->location().end_pos, &ok);
534 } 697 }
535 return kPreParseSuccess; 698 return kPreParseSuccess;
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
613 explicit Statement(Type code) : code_(code) {} 776 explicit Statement(Type code) : code_(code) {}
614 Type code_; 777 Type code_;
615 }; 778 };
616 779
617 enum SourceElements { 780 enum SourceElements {
618 kUnknownSourceElements 781 kUnknownSourceElements
619 }; 782 };
620 783
621 typedef int Arguments; 784 typedef int Arguments;
622 785
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 bool is_generator_;
696 };
697
698 class BlockState {
699 public:
700 BlockState(Scope** scope_stack, ScopeType scope_type)
701 : scope_stack_(scope_stack),
702 outer_scope_(*scope_stack),
703 scope_(*scope_stack, scope_type) {
704 *scope_stack_ = &scope_;
705 }
706
707 ~BlockState() { *scope_stack_ = outer_scope_; }
708
709 private:
710 Scope** scope_stack_;
711 Scope* outer_scope_;
712 Scope scope_;
713 };
714
715 // All ParseXXX functions take as the last argument an *ok parameter 786 // All ParseXXX functions take as the last argument an *ok parameter
716 // which is set to false if parsing failed; it is unchanged otherwise. 787 // which is set to false if parsing failed; it is unchanged otherwise.
717 // By making the 'exception handling' explicit, we are forced to check 788 // By making the 'exception handling' explicit, we are forced to check
718 // for failure at the call sites. 789 // for failure at the call sites.
719 Statement ParseSourceElement(bool* ok); 790 Statement ParseSourceElement(bool* ok);
720 SourceElements ParseSourceElements(int end_token, bool* ok); 791 SourceElements ParseSourceElements(int end_token, bool* ok);
721 Statement ParseStatement(bool* ok); 792 Statement ParseStatement(bool* ok);
722 Statement ParseFunctionDeclaration(bool* ok); 793 Statement ParseFunctionDeclaration(bool* ok);
723 Statement ParseBlock(bool* ok); 794 Statement ParseBlock(bool* ok);
724 Statement ParseVariableStatement(VariableDeclarationContext var_context, 795 Statement ParseVariableStatement(VariableDeclarationContext var_context,
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
767 void ParseLazyFunctionLiteralBody(bool* ok); 838 void ParseLazyFunctionLiteralBody(bool* ok);
768 839
769 // Logs the currently parsed literal as a symbol in the preparser data. 840 // Logs the currently parsed literal as a symbol in the preparser data.
770 void LogSymbol(); 841 void LogSymbol();
771 // Log the currently parsed string literal. 842 // Log the currently parsed string literal.
772 Expression GetStringSymbol(); 843 Expression GetStringSymbol();
773 844
774 bool CheckInOrOf(bool accept_OF); 845 bool CheckInOrOf(bool accept_OF);
775 846
776 ParserRecorder* log_; 847 ParserRecorder* log_;
777 FunctionState* function_state_;
778 Scope* scope_;
779 }; 848 };
780 849
781 850
782 template<class Traits> 851 template<class Traits>
852 ParserBase<Traits>::FunctionState::FunctionState(
853 FunctionState** function_state_stack,
854 typename Traits::Type::Scope** scope_stack,
855 typename Traits::Type::Scope* scope,
856 typename Traits::Type::Zone* extra_param)
857 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize),
858 next_handler_index_(0),
859 expected_property_count_(0),
860 is_generator_(false),
861 generator_object_variable_(NULL),
862 function_state_stack_(function_state_stack),
863 outer_function_state_(*function_state_stack),
864 scope_stack_(scope_stack),
865 outer_scope_(*scope_stack),
866 isolate_(NULL),
867 saved_ast_node_id_(0),
868 factory_(extra_param) {
869 *scope_stack_ = scope;
870 *function_state_stack = this;
871 Traits::SetUpFunctionState(this, extra_param);
872 }
873
874
875 template<class Traits>
876 ParserBase<Traits>::FunctionState::~FunctionState() {
877 *scope_stack_ = outer_scope_;
878 *function_state_stack_ = outer_function_state_;
879 Traits::TearDownFunctionState(this);
880 }
881
882
883 template<class Traits>
783 void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) { 884 void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) {
784 // We don't report stack overflows here, to avoid increasing the 885 // We don't report stack overflows here, to avoid increasing the
785 // stack depth even further. Instead we report it after parsing is 886 // stack depth even further. Instead we report it after parsing is
786 // over, in ParseProgram. 887 // over, in ParseProgram.
787 if (token == Token::ILLEGAL && stack_overflow()) { 888 if (token == Token::ILLEGAL && stack_overflow()) {
788 return; 889 return;
789 } 890 }
790 Scanner::Location source_location = scanner()->location(); 891 Scanner::Location source_location = scanner()->location();
791 892
792 // Four of the tokens are treated specially 893 // Four of the tokens are treated specially
793 switch (token) { 894 switch (token) {
794 case Token::EOS: 895 case Token::EOS:
795 return ReportMessageAt(source_location, "unexpected_eos"); 896 return ReportMessageAt(source_location, "unexpected_eos");
796 case Token::NUMBER: 897 case Token::NUMBER:
797 return ReportMessageAt(source_location, "unexpected_token_number"); 898 return ReportMessageAt(source_location, "unexpected_token_number");
798 case Token::STRING: 899 case Token::STRING:
799 return ReportMessageAt(source_location, "unexpected_token_string"); 900 return ReportMessageAt(source_location, "unexpected_token_string");
800 case Token::IDENTIFIER: 901 case Token::IDENTIFIER:
801 return ReportMessageAt(source_location, "unexpected_token_identifier"); 902 return ReportMessageAt(source_location, "unexpected_token_identifier");
802 case Token::FUTURE_RESERVED_WORD: 903 case Token::FUTURE_RESERVED_WORD:
803 return ReportMessageAt(source_location, "unexpected_reserved"); 904 return ReportMessageAt(source_location, "unexpected_reserved");
804 case Token::YIELD: 905 case Token::YIELD:
805 case Token::FUTURE_STRICT_RESERVED_WORD: 906 case Token::FUTURE_STRICT_RESERVED_WORD:
806 return ReportMessageAt( 907 return ReportMessageAt(source_location,
807 source_location, 908 is_classic_mode() ? "unexpected_token_identifier"
808 this->is_classic_mode() ? "unexpected_token_identifier" 909 : "unexpected_strict_reserved");
809 : "unexpected_strict_reserved");
810 default: 910 default:
811 const char* name = Token::String(token); 911 const char* name = Token::String(token);
812 ASSERT(name != NULL); 912 ASSERT(name != NULL);
813 Traits::ReportMessageAt( 913 Traits::ReportMessageAt(
814 source_location, "unexpected_token", Vector<const char*>(&name, 1)); 914 source_location, "unexpected_token", Vector<const char*>(&name, 1));
815 } 915 }
816 } 916 }
817 917
818 918
819 template<class Traits> 919 template<class Traits>
820 typename Traits::IdentifierType ParserBase<Traits>::ParseIdentifier( 920 typename Traits::Type::Identifier ParserBase<Traits>::ParseIdentifier(
821 AllowEvalOrArgumentsAsIdentifier allow_eval_or_arguments, 921 AllowEvalOrArgumentsAsIdentifier allow_eval_or_arguments,
822 bool* ok) { 922 bool* ok) {
823 Token::Value next = Next(); 923 Token::Value next = Next();
824 if (next == Token::IDENTIFIER) { 924 if (next == Token::IDENTIFIER) {
825 typename Traits::IdentifierType name = this->GetSymbol(); 925 typename Traits::Type::Identifier name = this->GetSymbol();
826 if (allow_eval_or_arguments == kDontAllowEvalOrArguments && 926 if (allow_eval_or_arguments == kDontAllowEvalOrArguments &&
827 !this->is_classic_mode() && this->IsEvalOrArguments(name)) { 927 !is_classic_mode() && this->IsEvalOrArguments(name)) {
828 ReportMessageAt(scanner()->location(), "strict_eval_arguments"); 928 ReportMessageAt(scanner()->location(), "strict_eval_arguments");
829 *ok = false; 929 *ok = false;
830 } 930 }
831 return name; 931 return name;
832 } else if (this->is_classic_mode() && 932 } else if (is_classic_mode() && (next == Token::FUTURE_STRICT_RESERVED_WORD ||
833 (next == Token::FUTURE_STRICT_RESERVED_WORD || 933 (next == Token::YIELD && !is_generator()))) {
834 (next == Token::YIELD && !this->is_generator()))) {
835 return this->GetSymbol(); 934 return this->GetSymbol();
836 } else { 935 } else {
837 this->ReportUnexpectedToken(next); 936 this->ReportUnexpectedToken(next);
838 *ok = false; 937 *ok = false;
839 return Traits::EmptyIdentifier(); 938 return Traits::EmptyIdentifier();
840 } 939 }
841 } 940 }
842 941
843 942
844 template <class Traits> 943 template <class Traits>
845 typename Traits::IdentifierType ParserBase< 944 typename Traits::Type::Identifier ParserBase<
846 Traits>::ParseIdentifierOrStrictReservedWord(bool* is_strict_reserved, 945 Traits>::ParseIdentifierOrStrictReservedWord(bool* is_strict_reserved,
847 bool* ok) { 946 bool* ok) {
848 Token::Value next = Next(); 947 Token::Value next = Next();
849 if (next == Token::IDENTIFIER) { 948 if (next == Token::IDENTIFIER) {
850 *is_strict_reserved = false; 949 *is_strict_reserved = false;
851 } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || 950 } else if (next == Token::FUTURE_STRICT_RESERVED_WORD ||
852 (next == Token::YIELD && !this->is_generator())) { 951 (next == Token::YIELD && !this->is_generator())) {
853 *is_strict_reserved = true; 952 *is_strict_reserved = true;
854 } else { 953 } else {
855 ReportUnexpectedToken(next); 954 ReportUnexpectedToken(next);
856 *ok = false; 955 *ok = false;
857 return Traits::EmptyIdentifier(); 956 return Traits::EmptyIdentifier();
858 } 957 }
859 return this->GetSymbol(); 958 return this->GetSymbol();
860 } 959 }
861 960
862 961
863 template <class Traits> 962 template <class Traits>
864 typename Traits::IdentifierType ParserBase<Traits>::ParseIdentifierName( 963 typename Traits::Type::Identifier ParserBase<Traits>::ParseIdentifierName(
865 bool* ok) { 964 bool* ok) {
866 Token::Value next = Next(); 965 Token::Value next = Next();
867 if (next != Token::IDENTIFIER && next != Token::FUTURE_RESERVED_WORD && 966 if (next != Token::IDENTIFIER && next != Token::FUTURE_RESERVED_WORD &&
868 next != Token::FUTURE_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) { 967 next != Token::FUTURE_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) {
869 this->ReportUnexpectedToken(next); 968 this->ReportUnexpectedToken(next);
870 *ok = false; 969 *ok = false;
871 return Traits::EmptyIdentifier(); 970 return Traits::EmptyIdentifier();
872 } 971 }
873 return this->GetSymbol(); 972 return this->GetSymbol();
874 } 973 }
875 974
876 975
877 template <class Traits> 976 template <class Traits>
878 typename Traits::IdentifierType 977 typename Traits::Type::Identifier
879 ParserBase<Traits>::ParseIdentifierNameOrGetOrSet(bool* is_get, 978 ParserBase<Traits>::ParseIdentifierNameOrGetOrSet(bool* is_get,
880 bool* is_set, 979 bool* is_set,
881 bool* ok) { 980 bool* ok) {
882 typename Traits::IdentifierType result = ParseIdentifierName(ok); 981 typename Traits::Type::Identifier result = ParseIdentifierName(ok);
883 if (!*ok) return Traits::EmptyIdentifier(); 982 if (!*ok) return Traits::EmptyIdentifier();
884 if (scanner()->is_literal_ascii() && 983 if (scanner()->is_literal_ascii() &&
885 scanner()->literal_length() == 3) { 984 scanner()->literal_length() == 3) {
886 const char* token = scanner()->literal_ascii_string().start(); 985 const char* token = scanner()->literal_ascii_string().start();
887 *is_get = strncmp(token, "get", 3) == 0; 986 *is_get = strncmp(token, "get", 3) == 0;
888 *is_set = !*is_get && strncmp(token, "set", 3) == 0; 987 *is_set = !*is_get && strncmp(token, "set", 3) == 0;
889 } 988 }
890 return result; 989 return result;
891 } 990 }
892 991
893 992
894 template <class Traits> 993 template <class Traits>
895 typename Traits::ExpressionType 994 typename Traits::Type::Expression
896 ParserBase<Traits>::ParseRegExpLiteral(bool seen_equal, bool* ok) { 995 ParserBase<Traits>::ParseRegExpLiteral(bool seen_equal, bool* ok) {
897 int pos = peek_position(); 996 int pos = peek_position();
898 if (!scanner()->ScanRegExpPattern(seen_equal)) { 997 if (!scanner()->ScanRegExpPattern(seen_equal)) {
899 Next(); 998 Next();
900 ReportMessage("unterminated_regexp", Vector<const char*>::empty()); 999 ReportMessage("unterminated_regexp", Vector<const char*>::empty());
901 *ok = false; 1000 *ok = false;
902 return Traits::EmptyExpression(); 1001 return Traits::EmptyExpression();
903 } 1002 }
904 1003
905 int literal_index = this->NextMaterializedLiteralIndex(); 1004 int literal_index = function_state_->NextMaterializedLiteralIndex();
906 1005
907 typename Traits::IdentifierType js_pattern = this->NextLiteralString(TENURED); 1006 typename Traits::Type::Identifier js_pattern =
1007 this->NextLiteralString(TENURED);
908 if (!scanner()->ScanRegExpFlags()) { 1008 if (!scanner()->ScanRegExpFlags()) {
909 Next(); 1009 Next();
910 ReportMessageAt(scanner()->location(), "invalid_regexp_flags"); 1010 ReportMessageAt(scanner()->location(), "invalid_regexp_flags");
911 *ok = false; 1011 *ok = false;
912 return Traits::EmptyExpression(); 1012 return Traits::EmptyExpression();
913 } 1013 }
914 typename Traits::IdentifierType js_flags = this->NextLiteralString(TENURED); 1014 typename Traits::Type::Identifier js_flags =
1015 this->NextLiteralString(TENURED);
915 Next(); 1016 Next();
916 return this->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos); 1017 return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos);
917 } 1018 }
918 1019
919 1020
920 template <typename Traits> 1021 template <typename Traits>
921 void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty( 1022 void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty(
922 Token::Value property, 1023 Token::Value property,
923 PropertyKind type, 1024 PropertyKind type,
924 bool* ok) { 1025 bool* ok) {
925 int old; 1026 int old;
926 if (property == Token::NUMBER) { 1027 if (property == Token::NUMBER) {
(...skipping 21 matching lines...) Expand all
948 "accessor_get_set"); 1049 "accessor_get_set");
949 } 1050 }
950 *ok = false; 1051 *ok = false;
951 } 1052 }
952 } 1053 }
953 1054
954 1055
955 } } // v8::internal 1056 } } // v8::internal
956 1057
957 #endif // V8_PREPARSER_H 1058 #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