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

Side by Side Diff: src/preparser.h

Issue 27182002: Introduce ParserBase for common code between parser and pre-parser. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 2 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 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
118 ASSERT(IsAccessorAccessorConflict(old_type, type)); 118 ASSERT(IsAccessorAccessorConflict(old_type, type));
119 // Both accessors of the same type. 119 // Both accessors of the same type.
120 parser_->ReportMessageAt(scanner_->location(), 120 parser_->ReportMessageAt(scanner_->location(),
121 "accessor_get_set"); 121 "accessor_get_set");
122 } 122 }
123 *ok = false; 123 *ok = false;
124 } 124 }
125 } 125 }
126 126
127 127
128 // Common base class shared between parser and pre-parser.
129 class ParserBase {
130 public:
131 ParserBase(Scanner* scanner, uintptr_t stack_limit)
132 : scanner_(scanner),
133 stack_limit_(stack_limit),
134 stack_overflow_(false),
135 allow_lazy_(false),
136 allow_natives_syntax_(false),
137 allow_generators_(false),
138 allow_for_of_(false) { }
139 // TODO(mstarzinger): Only virtual until message reporting has been unified.
140 virtual ~ParserBase() { }
141
142 // Getters that indicate whether certain syntactical constructs are
143 // allowed to be parsed by this instance of the parser.
144 bool allow_lazy() const { return allow_lazy_; }
145 bool allow_natives_syntax() const { return allow_natives_syntax_; }
146 bool allow_generators() const { return allow_generators_; }
147 bool allow_for_of() const { return allow_for_of_; }
148 bool allow_modules() const { return scanner()->HarmonyModules(); }
149 bool allow_harmony_scoping() const { return scanner()->HarmonyScoping(); }
150 bool allow_harmony_numeric_literals() const {
151 return scanner()->HarmonyNumericLiterals();
152 }
153
154 // Setters that determine whether certain syntactical constructs are
155 // allowed to be parsed by this instance of the parser.
156 void set_allow_lazy(bool allow) { allow_lazy_ = allow; }
157 void set_allow_natives_syntax(bool allow) { allow_natives_syntax_ = allow; }
158 void set_allow_generators(bool allow) { allow_generators_ = allow; }
159 void set_allow_for_of(bool allow) { allow_for_of_ = allow; }
160 void set_allow_modules(bool allow) { scanner()->SetHarmonyModules(allow); }
161 void set_allow_harmony_scoping(bool allow) {
162 scanner()->SetHarmonyScoping(allow);
163 }
164 void set_allow_harmony_numeric_literals(bool allow) {
165 scanner()->SetHarmonyNumericLiterals(allow);
166 }
167
168 protected:
169 Scanner* scanner() const { return scanner_; }
170 bool stack_overflow() const { return stack_overflow_; }
171 void set_stack_overflow() { stack_overflow_ = true; }
172
173 INLINE(Token::Value peek()) {
174 if (stack_overflow_) return Token::ILLEGAL;
175 return scanner()->peek();
176 }
177
178 INLINE(Token::Value Next()) {
179 if (stack_overflow_) return Token::ILLEGAL;
180 {
181 int marker;
182 if (reinterpret_cast<uintptr_t>(&marker) < stack_limit_) {
183 // Any further calls to Next or peek will return the illegal token.
184 // The current call must return the next token, which might already
185 // have been peek'ed.
186 stack_overflow_ = true;
187 }
188 }
189 return scanner()->Next();
190 }
191
192 void Consume(Token::Value token) {
193 Token::Value next = Next();
194 USE(next);
195 USE(token);
196 ASSERT(next == token);
197 }
198
199 bool Check(Token::Value token) {
200 Token::Value next = peek();
201 if (next == token) {
202 Consume(next);
203 return true;
204 }
205 return false;
206 }
207
208 void Expect(Token::Value token, bool* ok) {
209 Token::Value next = Next();
210 if (next != token) {
211 ReportUnexpectedToken(next);
212 *ok = false;
213 }
214 }
215
216 bool peek_any_identifier();
217 void ExpectSemicolon(bool* ok);
218
219 // Report syntax errors.
220 virtual void ReportUnexpectedToken(Token::Value token) = 0;
221
222 private:
223 Scanner* scanner_;
224 uintptr_t stack_limit_;
225 bool stack_overflow_;
226
227 bool allow_lazy_;
228 bool allow_natives_syntax_;
229 bool allow_generators_;
230 bool allow_for_of_;
231 };
232
233
128 // Preparsing checks a JavaScript program and emits preparse-data that helps 234 // Preparsing checks a JavaScript program and emits preparse-data that helps
129 // a later parsing to be faster. 235 // a later parsing to be faster.
130 // See preparse-data-format.h for the data format. 236 // See preparse-data-format.h for the data format.
131 237
132 // The PreParser checks that the syntax follows the grammar for JavaScript, 238 // The PreParser checks that the syntax follows the grammar for JavaScript,
133 // and collects some information about the program along the way. 239 // and collects some information about the program along the way.
134 // The grammar check is only performed in order to understand the program 240 // The grammar check is only performed in order to understand the program
135 // sufficiently to deduce some information about it, that can be used 241 // sufficiently to deduce some information about it, that can be used
136 // to speed up later parsing. Finding errors is not the goal of pre-parsing, 242 // to speed up later parsing. Finding errors is not the goal of pre-parsing,
137 // rather it is to speed up properly written and correct programs. 243 // rather it is to speed up properly written and correct programs.
138 // That means that contextual checks (like a label being declared where 244 // That means that contextual checks (like a label being declared where
139 // it is used) are generally omitted. 245 // it is used) are generally omitted.
140 246
141 typedef uint8_t byte; 247 typedef uint8_t byte;
142 namespace i = v8::internal; 248 namespace i = v8::internal;
143 249
144 class PreParser { 250 class PreParser : public ParserBase {
145 public: 251 public:
146 enum PreParseResult { 252 enum PreParseResult {
147 kPreParseStackOverflow, 253 kPreParseStackOverflow,
148 kPreParseSuccess 254 kPreParseSuccess
149 }; 255 };
150 256
151 257
152 PreParser(i::Scanner* scanner, 258 PreParser(i::Scanner* scanner,
153 i::ParserRecorder* log, 259 i::ParserRecorder* log,
154 uintptr_t stack_limit) 260 uintptr_t stack_limit)
155 : scanner_(scanner), 261 : ParserBase(scanner, stack_limit),
156 log_(log), 262 log_(log),
157 scope_(NULL), 263 scope_(NULL),
158 stack_limit_(stack_limit),
159 strict_mode_violation_location_(i::Scanner::Location::invalid()), 264 strict_mode_violation_location_(i::Scanner::Location::invalid()),
160 strict_mode_violation_type_(NULL), 265 strict_mode_violation_type_(NULL),
161 stack_overflow_(false),
162 allow_lazy_(false),
163 allow_natives_syntax_(false),
164 allow_generators_(false),
165 allow_for_of_(false),
166 parenthesized_function_(false) { } 266 parenthesized_function_(false) { }
167 267
168 ~PreParser() {} 268 ~PreParser() {}
169 269
170 bool allow_natives_syntax() const { return allow_natives_syntax_; }
171 bool allow_lazy() const { return allow_lazy_; }
172 bool allow_modules() const { return scanner_->HarmonyModules(); }
173 bool allow_harmony_scoping() const { return scanner_->HarmonyScoping(); }
174 bool allow_generators() const { return allow_generators_; }
175 bool allow_for_of() const { return allow_for_of_; }
176 bool allow_harmony_numeric_literals() const {
177 return scanner_->HarmonyNumericLiterals();
178 }
179
180 void set_allow_natives_syntax(bool allow) { allow_natives_syntax_ = allow; }
181 void set_allow_lazy(bool allow) { allow_lazy_ = allow; }
182 void set_allow_modules(bool allow) { scanner_->SetHarmonyModules(allow); }
183 void set_allow_harmony_scoping(bool allow) {
184 scanner_->SetHarmonyScoping(allow);
185 }
186 void set_allow_generators(bool allow) { allow_generators_ = allow; }
187 void set_allow_for_of(bool allow) { allow_for_of_ = allow; }
188 void set_allow_harmony_numeric_literals(bool allow) {
189 scanner_->SetHarmonyNumericLiterals(allow);
190 }
191
192 // Pre-parse the program from the character stream; returns true on 270 // Pre-parse the program from the character stream; returns true on
193 // success (even if parsing failed, the pre-parse data successfully 271 // success (even if parsing failed, the pre-parse data successfully
194 // captured the syntax error), and false if a stack-overflow happened 272 // captured the syntax error), and false if a stack-overflow happened
195 // during parsing. 273 // during parsing.
196 PreParseResult PreParseProgram() { 274 PreParseResult PreParseProgram() {
197 Scope top_scope(&scope_, kTopLevelScope); 275 Scope top_scope(&scope_, kTopLevelScope);
198 bool ok = true; 276 bool ok = true;
199 int start_position = scanner_->peek_location().beg_pos; 277 int start_position = scanner()->peek_location().beg_pos;
200 ParseSourceElements(i::Token::EOS, &ok); 278 ParseSourceElements(i::Token::EOS, &ok);
201 if (stack_overflow_) return kPreParseStackOverflow; 279 if (stack_overflow()) return kPreParseStackOverflow;
202 if (!ok) { 280 if (!ok) {
203 ReportUnexpectedToken(scanner_->current_token()); 281 ReportUnexpectedToken(scanner()->current_token());
204 } else if (!scope_->is_classic_mode()) { 282 } else if (!scope_->is_classic_mode()) {
205 CheckOctalLiteral(start_position, scanner_->location().end_pos, &ok); 283 CheckOctalLiteral(start_position, scanner()->location().end_pos, &ok);
206 } 284 }
207 return kPreParseSuccess; 285 return kPreParseSuccess;
208 } 286 }
209 287
210 // Parses a single function literal, from the opening parentheses before 288 // Parses a single function literal, from the opening parentheses before
211 // parameters to the closing brace after the body. 289 // parameters to the closing brace after the body.
212 // Returns a FunctionEntry describing the body of the function in enough 290 // Returns a FunctionEntry describing the body of the function in enough
213 // detail that it can be lazily compiled. 291 // detail that it can be lazily compiled.
214 // The scanner is expected to have matched the "function" or "function*" 292 // The scanner is expected to have matched the "function" or "function*"
215 // keyword and parameters, and have consumed the initial '{'. 293 // keyword and parameters, and have consumed the initial '{'.
(...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after
597 bool* is_set, 675 bool* is_set,
598 bool* ok); 676 bool* ok);
599 677
600 // Logs the currently parsed literal as a symbol in the preparser data. 678 // Logs the currently parsed literal as a symbol in the preparser data.
601 void LogSymbol(); 679 void LogSymbol();
602 // Log the currently parsed identifier. 680 // Log the currently parsed identifier.
603 Identifier GetIdentifierSymbol(); 681 Identifier GetIdentifierSymbol();
604 // Log the currently parsed string literal. 682 // Log the currently parsed string literal.
605 Expression GetStringSymbol(); 683 Expression GetStringSymbol();
606 684
607 i::Token::Value peek() {
608 if (stack_overflow_) return i::Token::ILLEGAL;
609 return scanner_->peek();
610 }
611
612 i::Token::Value Next() {
613 if (stack_overflow_) return i::Token::ILLEGAL;
614 {
615 int marker;
616 if (reinterpret_cast<uintptr_t>(&marker) < stack_limit_) {
617 // Further calls to peek/Next will return illegal token.
618 // The current one will still be returned. It might already
619 // have been seen using peek.
620 stack_overflow_ = true;
621 }
622 }
623 return scanner_->Next();
624 }
625
626 bool peek_any_identifier();
627
628 void set_language_mode(i::LanguageMode language_mode) { 685 void set_language_mode(i::LanguageMode language_mode) {
629 scope_->set_language_mode(language_mode); 686 scope_->set_language_mode(language_mode);
630 } 687 }
631 688
632 bool is_classic_mode() { 689 bool is_classic_mode() {
633 return scope_->language_mode() == i::CLASSIC_MODE; 690 return scope_->language_mode() == i::CLASSIC_MODE;
634 } 691 }
635 692
636 bool is_extended_mode() { 693 bool is_extended_mode() {
637 return scope_->language_mode() == i::EXTENDED_MODE; 694 return scope_->language_mode() == i::EXTENDED_MODE;
638 } 695 }
639 696
640 i::LanguageMode language_mode() { return scope_->language_mode(); } 697 i::LanguageMode language_mode() { return scope_->language_mode(); }
641 698
642 void Consume(i::Token::Value token) { Next(); }
643
644 void Expect(i::Token::Value token, bool* ok) {
645 if (Next() != token) {
646 *ok = false;
647 }
648 }
649
650 bool Check(i::Token::Value token) {
651 i::Token::Value next = peek();
652 if (next == token) {
653 Consume(next);
654 return true;
655 }
656 return false;
657 }
658 void ExpectSemicolon(bool* ok);
659
660 bool CheckInOrOf(bool accept_OF); 699 bool CheckInOrOf(bool accept_OF);
661 700
662 static int Precedence(i::Token::Value tok, bool accept_IN); 701 static int Precedence(i::Token::Value tok, bool accept_IN);
663 702
664 void SetStrictModeViolation(i::Scanner::Location, 703 void SetStrictModeViolation(i::Scanner::Location,
665 const char* type, 704 const char* type,
666 bool* ok); 705 bool* ok);
667 706
668 void CheckDelayedStrictModeViolation(int beg_pos, int end_pos, bool* ok); 707 void CheckDelayedStrictModeViolation(int beg_pos, int end_pos, bool* ok);
669 708
670 void StrictModeIdentifierViolation(i::Scanner::Location, 709 void StrictModeIdentifierViolation(i::Scanner::Location,
671 const char* eval_args_type, 710 const char* eval_args_type,
672 Identifier identifier, 711 Identifier identifier,
673 bool* ok); 712 bool* ok);
674 713
675 i::Scanner* scanner_;
676 i::ParserRecorder* log_; 714 i::ParserRecorder* log_;
677 Scope* scope_; 715 Scope* scope_;
678 uintptr_t stack_limit_;
679 i::Scanner::Location strict_mode_violation_location_; 716 i::Scanner::Location strict_mode_violation_location_;
680 const char* strict_mode_violation_type_; 717 const char* strict_mode_violation_type_;
681 bool stack_overflow_;
682 bool allow_lazy_;
683 bool allow_natives_syntax_;
684 bool allow_generators_;
685 bool allow_for_of_;
686 bool parenthesized_function_; 718 bool parenthesized_function_;
687 719
688 friend class i::ObjectLiteralChecker<PreParser>; 720 friend class i::ObjectLiteralChecker<PreParser>;
689 }; 721 };
690 722
691 } } // v8::internal 723 } } // v8::internal
692 724
693 #endif // V8_PREPARSER_H 725 #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