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

Side by Side Diff: src/preparser.h

Issue 39973003: Merge bleeding_edge. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
Patch Set: again Created 7 years, 1 month 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 15 matching lines...) Expand all
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 "token.h" 32 #include "token.h"
33 #include "scanner.h" 33 #include "scanner.h"
34 34
35 namespace v8 { 35 namespace v8 {
36
37 namespace internal { 36 namespace internal {
38 37
39 // Used to detect duplicates in object literals. Each of the values 38 // Common base class shared between parser and pre-parser.
40 // kGetterProperty, kSetterProperty and kValueProperty represents 39 class ParserBase {
41 // a type of object literal property. When parsing a property, its 40 public:
42 // type value is stored in the DuplicateFinder for the property name. 41 ParserBase(Scanner* scanner, uintptr_t stack_limit)
43 // Values are chosen so that having intersection bits means the there is 42 : scanner_(scanner),
44 // an incompatibility. 43 stack_limit_(stack_limit),
45 // I.e., you can add a getter to a property that already has a setter, since 44 stack_overflow_(false),
46 // kGetterProperty and kSetterProperty doesn't intersect, but not if it 45 allow_lazy_(false),
47 // already has a getter or a value. Adding the getter to an existing 46 allow_natives_syntax_(false),
48 // setter will store the value (kGetterProperty | kSetterProperty), which 47 allow_generators_(false),
49 // is incompatible with adding any further properties. 48 allow_for_of_(false) { }
50 enum PropertyKind { 49 // TODO(mstarzinger): Only virtual until message reporting has been unified.
51 kNone = 0, 50 virtual ~ParserBase() { }
52 // Bit patterns representing different object literal property types. 51
53 kGetterProperty = 1, 52 // Getters that indicate whether certain syntactical constructs are
54 kSetterProperty = 2, 53 // allowed to be parsed by this instance of the parser.
55 kValueProperty = 7, 54 bool allow_lazy() const { return allow_lazy_; }
56 // Helper constants. 55 bool allow_natives_syntax() const { return allow_natives_syntax_; }
57 kValueFlag = 4 56 bool allow_generators() const { return allow_generators_; }
57 bool allow_for_of() const { return allow_for_of_; }
58 bool allow_modules() const { return scanner()->HarmonyModules(); }
59 bool allow_harmony_scoping() const { return scanner()->HarmonyScoping(); }
60 bool allow_harmony_numeric_literals() const {
61 return scanner()->HarmonyNumericLiterals();
62 }
63
64 // Setters that determine whether certain syntactical constructs are
65 // allowed to be parsed by this instance of the parser.
66 void set_allow_lazy(bool allow) { allow_lazy_ = allow; }
67 void set_allow_natives_syntax(bool allow) { allow_natives_syntax_ = allow; }
68 void set_allow_generators(bool allow) { allow_generators_ = allow; }
69 void set_allow_for_of(bool allow) { allow_for_of_ = allow; }
70 void set_allow_modules(bool allow) { scanner()->SetHarmonyModules(allow); }
71 void set_allow_harmony_scoping(bool allow) {
72 scanner()->SetHarmonyScoping(allow);
73 }
74 void set_allow_harmony_numeric_literals(bool allow) {
75 scanner()->SetHarmonyNumericLiterals(allow);
76 }
77
78 protected:
79 Scanner* scanner() const { return scanner_; }
80 int position() { return scanner_->location().beg_pos; }
81 int peek_position() { return scanner_->peek_location().beg_pos; }
82 bool stack_overflow() const { return stack_overflow_; }
83 void set_stack_overflow() { stack_overflow_ = true; }
84
85 INLINE(Token::Value peek()) {
86 if (stack_overflow_) return Token::ILLEGAL;
87 return scanner()->peek();
88 }
89
90 INLINE(Token::Value Next()) {
91 if (stack_overflow_) return Token::ILLEGAL;
92 {
93 int marker;
94 if (reinterpret_cast<uintptr_t>(&marker) < stack_limit_) {
95 // Any further calls to Next or peek will return the illegal token.
96 // The current call must return the next token, which might already
97 // have been peek'ed.
98 stack_overflow_ = true;
99 }
100 }
101 return scanner()->Next();
102 }
103
104 void Consume(Token::Value token) {
105 Token::Value next = Next();
106 USE(next);
107 USE(token);
108 ASSERT(next == token);
109 }
110
111 bool Check(Token::Value token) {
112 Token::Value next = peek();
113 if (next == token) {
114 Consume(next);
115 return true;
116 }
117 return false;
118 }
119
120 void Expect(Token::Value token, bool* ok) {
121 Token::Value next = Next();
122 if (next != token) {
123 ReportUnexpectedToken(next);
124 *ok = false;
125 }
126 }
127
128 bool peek_any_identifier();
129 void ExpectSemicolon(bool* ok);
130 bool CheckContextualKeyword(Vector<const char> keyword);
131 void ExpectContextualKeyword(Vector<const char> keyword, bool* ok);
132
133 // Strict mode octal literal validation.
134 void CheckOctalLiteral(int beg_pos, int end_pos, bool* ok);
135
136 // Determine precedence of given token.
137 static int Precedence(Token::Value token, bool accept_IN);
138
139 // Report syntax errors.
140 virtual void ReportUnexpectedToken(Token::Value token) = 0;
141 virtual void ReportMessageAt(Scanner::Location loc, const char* type) = 0;
142
143 // Used to detect duplicates in object literals. Each of the values
144 // kGetterProperty, kSetterProperty and kValueProperty represents
145 // a type of object literal property. When parsing a property, its
146 // type value is stored in the DuplicateFinder for the property name.
147 // Values are chosen so that having intersection bits means the there is
148 // an incompatibility.
149 // I.e., you can add a getter to a property that already has a setter, since
150 // kGetterProperty and kSetterProperty doesn't intersect, but not if it
151 // already has a getter or a value. Adding the getter to an existing
152 // setter will store the value (kGetterProperty | kSetterProperty), which
153 // is incompatible with adding any further properties.
154 enum PropertyKind {
155 kNone = 0,
156 // Bit patterns representing different object literal property types.
157 kGetterProperty = 1,
158 kSetterProperty = 2,
159 kValueProperty = 7,
160 // Helper constants.
161 kValueFlag = 4
162 };
163
164 // Validation per ECMA 262 - 11.1.5 "Object Initialiser".
165 class ObjectLiteralChecker {
166 public:
167 ObjectLiteralChecker(ParserBase* parser, LanguageMode mode)
168 : parser_(parser),
169 finder_(scanner()->unicode_cache()),
170 language_mode_(mode) { }
171
172 void CheckProperty(Token::Value property, PropertyKind type, bool* ok);
173
174 private:
175 ParserBase* parser() const { return parser_; }
176 Scanner* scanner() const { return parser_->scanner(); }
177
178 // Checks the type of conflict based on values coming from PropertyType.
179 bool HasConflict(PropertyKind type1, PropertyKind type2) {
180 return (type1 & type2) != 0;
181 }
182 bool IsDataDataConflict(PropertyKind type1, PropertyKind type2) {
183 return ((type1 & type2) & kValueFlag) != 0;
184 }
185 bool IsDataAccessorConflict(PropertyKind type1, PropertyKind type2) {
186 return ((type1 ^ type2) & kValueFlag) != 0;
187 }
188 bool IsAccessorAccessorConflict(PropertyKind type1, PropertyKind type2) {
189 return ((type1 | type2) & kValueFlag) == 0;
190 }
191
192 ParserBase* parser_;
193 DuplicateFinder finder_;
194 LanguageMode language_mode_;
195 };
196
197 private:
198 Scanner* scanner_;
199 uintptr_t stack_limit_;
200 bool stack_overflow_;
201
202 bool allow_lazy_;
203 bool allow_natives_syntax_;
204 bool allow_generators_;
205 bool allow_for_of_;
58 }; 206 };
59 207
60 208
61 // Validation per 11.1.5 Object Initialiser
62 template<typename P>
63 class ObjectLiteralChecker {
64 public:
65 ObjectLiteralChecker(P* parser, Scanner* scanner, LanguageMode mode)
66 : parser_(parser),
67 scanner_(scanner),
68 finder_(scanner->unicode_cache()),
69 language_mode_(mode) { }
70
71 void CheckProperty(Token::Value property, PropertyKind type, bool* ok);
72
73 private:
74 // Checks the type of conflict based on values coming from PropertyType.
75 bool HasConflict(PropertyKind type1, PropertyKind type2) {
76 return (type1 & type2) != 0;
77 }
78 bool IsDataDataConflict(PropertyKind type1, PropertyKind type2) {
79 return ((type1 & type2) & kValueFlag) != 0;
80 }
81 bool IsDataAccessorConflict(PropertyKind type1, PropertyKind type2) {
82 return ((type1 ^ type2) & kValueFlag) != 0;
83 }
84 bool IsAccessorAccessorConflict(PropertyKind type1, PropertyKind type2) {
85 return ((type1 | type2) & kValueFlag) == 0;
86 }
87
88 P* parser_;
89 Scanner* scanner_;
90 DuplicateFinder finder_;
91 LanguageMode language_mode_;
92 };
93
94
95 template<typename P>
96 void ObjectLiteralChecker<P>::CheckProperty(Token::Value property,
97 PropertyKind type,
98 bool* ok) {
99 int old;
100 if (property == Token::NUMBER) {
101 old = finder_.AddNumber(scanner_->literal_ascii_string(), type);
102 } else if (scanner_->is_literal_ascii()) {
103 old = finder_.AddAsciiSymbol(scanner_->literal_ascii_string(), type);
104 } else {
105 old = finder_.AddUtf16Symbol(scanner_->literal_utf16_string(), type);
106 }
107 PropertyKind old_type = static_cast<PropertyKind>(old);
108 if (HasConflict(old_type, type)) {
109 if (IsDataDataConflict(old_type, type)) {
110 // Both are data properties.
111 if (language_mode_ == CLASSIC_MODE) return;
112 parser_->ReportMessageAt(scanner_->location(),
113 "strict_duplicate_property");
114 } else if (IsDataAccessorConflict(old_type, type)) {
115 // Both a data and an accessor property with the same name.
116 parser_->ReportMessageAt(scanner_->location(),
117 "accessor_data_property");
118 } else {
119 ASSERT(IsAccessorAccessorConflict(old_type, type));
120 // Both accessors of the same type.
121 parser_->ReportMessageAt(scanner_->location(),
122 "accessor_get_set");
123 }
124 *ok = false;
125 }
126 }
127
128 } // v8::internal
129
130 namespace preparser {
131
132 typedef uint8_t byte;
133
134 // Preparsing checks a JavaScript program and emits preparse-data that helps 209 // Preparsing checks a JavaScript program and emits preparse-data that helps
135 // a later parsing to be faster. 210 // a later parsing to be faster.
136 // See preparse-data-format.h for the data format. 211 // See preparse-data-format.h for the data format.
137 212
138 // The PreParser checks that the syntax follows the grammar for JavaScript, 213 // The PreParser checks that the syntax follows the grammar for JavaScript,
139 // and collects some information about the program along the way. 214 // and collects some information about the program along the way.
140 // The grammar check is only performed in order to understand the program 215 // The grammar check is only performed in order to understand the program
141 // sufficiently to deduce some information about it, that can be used 216 // sufficiently to deduce some information about it, that can be used
142 // to speed up later parsing. Finding errors is not the goal of pre-parsing, 217 // to speed up later parsing. Finding errors is not the goal of pre-parsing,
143 // rather it is to speed up properly written and correct programs. 218 // rather it is to speed up properly written and correct programs.
144 // That means that contextual checks (like a label being declared where 219 // That means that contextual checks (like a label being declared where
145 // it is used) are generally omitted. 220 // it is used) are generally omitted.
146 221 class PreParser : public ParserBase {
147 namespace i = v8::internal;
148
149 class PreParser {
150 public: 222 public:
151 enum PreParseResult { 223 enum PreParseResult {
152 kPreParseStackOverflow, 224 kPreParseStackOverflow,
153 kPreParseSuccess 225 kPreParseSuccess
154 }; 226 };
155 227
156 228 PreParser(Scanner* scanner,
157 PreParser(i::Scanner* scanner, 229 ParserRecorder* log,
158 i::ParserRecorder* log,
159 uintptr_t stack_limit) 230 uintptr_t stack_limit)
160 : scanner_(scanner), 231 : ParserBase(scanner, stack_limit),
161 log_(log), 232 log_(log),
162 scope_(NULL), 233 scope_(NULL),
163 stack_limit_(stack_limit), 234 strict_mode_violation_location_(Scanner::Location::invalid()),
164 strict_mode_violation_location_(i::Scanner::Location::invalid()),
165 strict_mode_violation_type_(NULL), 235 strict_mode_violation_type_(NULL),
166 stack_overflow_(false),
167 allow_lazy_(false),
168 allow_natives_syntax_(false),
169 allow_generators_(false),
170 allow_for_of_(false),
171 parenthesized_function_(false) { } 236 parenthesized_function_(false) { }
172 237
173 ~PreParser() {} 238 ~PreParser() {}
174 239
175 bool allow_natives_syntax() const { return allow_natives_syntax_; }
176 bool allow_lazy() const { return allow_lazy_; }
177 bool allow_modules() const { return scanner_->HarmonyModules(); }
178 bool allow_harmony_scoping() const { return scanner_->HarmonyScoping(); }
179 bool allow_generators() const { return allow_generators_; }
180 bool allow_for_of() const { return allow_for_of_; }
181 bool allow_harmony_numeric_literals() const {
182 return scanner_->HarmonyNumericLiterals();
183 }
184
185 void set_allow_natives_syntax(bool allow) { allow_natives_syntax_ = allow; }
186 void set_allow_lazy(bool allow) { allow_lazy_ = allow; }
187 void set_allow_modules(bool allow) { scanner_->SetHarmonyModules(allow); }
188 void set_allow_harmony_scoping(bool allow) {
189 scanner_->SetHarmonyScoping(allow);
190 }
191 void set_allow_generators(bool allow) { allow_generators_ = allow; }
192 void set_allow_for_of(bool allow) { allow_for_of_ = allow; }
193 void set_allow_harmony_numeric_literals(bool allow) {
194 scanner_->SetHarmonyNumericLiterals(allow);
195 }
196
197 // Pre-parse the program from the character stream; returns true on 240 // Pre-parse the program from the character stream; returns true on
198 // success (even if parsing failed, the pre-parse data successfully 241 // success (even if parsing failed, the pre-parse data successfully
199 // captured the syntax error), and false if a stack-overflow happened 242 // captured the syntax error), and false if a stack-overflow happened
200 // during parsing. 243 // during parsing.
201 PreParseResult PreParseProgram() { 244 PreParseResult PreParseProgram() {
202 Scope top_scope(&scope_, kTopLevelScope); 245 Scope top_scope(&scope_, kTopLevelScope);
203 bool ok = true; 246 bool ok = true;
204 int start_position = scanner_->peek_location().beg_pos; 247 int start_position = scanner()->peek_location().beg_pos;
205 ParseSourceElements(i::Token::EOS, &ok); 248 ParseSourceElements(Token::EOS, &ok);
206 if (stack_overflow_) return kPreParseStackOverflow; 249 if (stack_overflow()) return kPreParseStackOverflow;
207 if (!ok) { 250 if (!ok) {
208 ReportUnexpectedToken(scanner_->current_token()); 251 ReportUnexpectedToken(scanner()->current_token());
209 } else if (!scope_->is_classic_mode()) { 252 } else if (!scope_->is_classic_mode()) {
210 CheckOctalLiteral(start_position, scanner_->location().end_pos, &ok); 253 CheckOctalLiteral(start_position, scanner()->location().end_pos, &ok);
211 } 254 }
212 return kPreParseSuccess; 255 return kPreParseSuccess;
213 } 256 }
214 257
215 // Parses a single function literal, from the opening parentheses before 258 // Parses a single function literal, from the opening parentheses before
216 // parameters to the closing brace after the body. 259 // parameters to the closing brace after the body.
217 // Returns a FunctionEntry describing the body of the function in enough 260 // Returns a FunctionEntry describing the body of the function in enough
218 // detail that it can be lazily compiled. 261 // detail that it can be lazily compiled.
219 // The scanner is expected to have matched the "function" or "function*" 262 // The scanner is expected to have matched the "function" or "function*"
220 // keyword and parameters, and have consumed the initial '{'. 263 // keyword and parameters, and have consumed the initial '{'.
221 // At return, unless an error occurred, the scanner is positioned before the 264 // At return, unless an error occurred, the scanner is positioned before the
222 // the final '}'. 265 // the final '}'.
223 PreParseResult PreParseLazyFunction(i::LanguageMode mode, 266 PreParseResult PreParseLazyFunction(LanguageMode mode,
224 bool is_generator, 267 bool is_generator,
225 i::ParserRecorder* log); 268 ParserRecorder* log);
226 269
227 private: 270 private:
228 // These types form an algebra over syntactic categories that is just 271 // These types form an algebra over syntactic categories that is just
229 // rich enough to let us recognize and propagate the constructs that 272 // rich enough to let us recognize and propagate the constructs that
230 // are either being counted in the preparser data, or is important 273 // are either being counted in the preparser data, or is important
231 // to throw the correct syntax error exceptions. 274 // to throw the correct syntax error exceptions.
232 275
233 enum ScopeType { 276 enum ScopeType {
234 kTopLevelScope, 277 kTopLevelScope,
235 kFunctionScope 278 kFunctionScope
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
437 return Statement(kUseStrictExpressionStatement); 480 return Statement(kUseStrictExpressionStatement);
438 } 481 }
439 if (expression.IsStringLiteral()) { 482 if (expression.IsStringLiteral()) {
440 return Statement(kStringLiteralExpressionStatement); 483 return Statement(kStringLiteralExpressionStatement);
441 } 484 }
442 } 485 }
443 return Default(); 486 return Default();
444 } 487 }
445 488
446 bool IsStringLiteral() { 489 bool IsStringLiteral() {
447 return code_ != kUnknownStatement; 490 return code_ == kStringLiteralExpressionStatement;
448 } 491 }
449 492
450 bool IsUseStrictLiteral() { 493 bool IsUseStrictLiteral() {
451 return code_ == kUseStrictExpressionStatement; 494 return code_ == kUseStrictExpressionStatement;
452 } 495 }
453 496
454 bool IsFunctionDeclaration() { 497 bool IsFunctionDeclaration() {
455 return code_ == kFunctionDeclaration; 498 return code_ == kFunctionDeclaration;
456 } 499 }
457 500
(...skipping 18 matching lines...) Expand all
476 class Scope { 519 class Scope {
477 public: 520 public:
478 Scope(Scope** variable, ScopeType type) 521 Scope(Scope** variable, ScopeType type)
479 : variable_(variable), 522 : variable_(variable),
480 prev_(*variable), 523 prev_(*variable),
481 type_(type), 524 type_(type),
482 materialized_literal_count_(0), 525 materialized_literal_count_(0),
483 expected_properties_(0), 526 expected_properties_(0),
484 with_nesting_count_(0), 527 with_nesting_count_(0),
485 language_mode_( 528 language_mode_(
486 (prev_ != NULL) ? prev_->language_mode() : i::CLASSIC_MODE), 529 (prev_ != NULL) ? prev_->language_mode() : CLASSIC_MODE),
487 is_generator_(false) { 530 is_generator_(false) {
488 *variable = this; 531 *variable = this;
489 } 532 }
490 ~Scope() { *variable_ = prev_; } 533 ~Scope() { *variable_ = prev_; }
491 void NextMaterializedLiteralIndex() { materialized_literal_count_++; } 534 void NextMaterializedLiteralIndex() { materialized_literal_count_++; }
492 void AddProperty() { expected_properties_++; } 535 void AddProperty() { expected_properties_++; }
493 ScopeType type() { return type_; } 536 ScopeType type() { return type_; }
494 int expected_properties() { return expected_properties_; } 537 int expected_properties() { return expected_properties_; }
495 int materialized_literal_count() { return materialized_literal_count_; } 538 int materialized_literal_count() { return materialized_literal_count_; }
496 bool IsInsideWith() { return with_nesting_count_ != 0; } 539 bool IsInsideWith() { return with_nesting_count_ != 0; }
497 bool is_generator() { return is_generator_; } 540 bool is_generator() { return is_generator_; }
498 void set_is_generator(bool is_generator) { is_generator_ = is_generator; } 541 void set_is_generator(bool is_generator) { is_generator_ = is_generator; }
499 bool is_classic_mode() { 542 bool is_classic_mode() {
500 return language_mode_ == i::CLASSIC_MODE; 543 return language_mode_ == CLASSIC_MODE;
501 } 544 }
502 i::LanguageMode language_mode() { 545 LanguageMode language_mode() {
503 return language_mode_; 546 return language_mode_;
504 } 547 }
505 void set_language_mode(i::LanguageMode language_mode) { 548 void set_language_mode(LanguageMode language_mode) {
506 language_mode_ = language_mode; 549 language_mode_ = language_mode;
507 } 550 }
508 551
509 class InsideWith { 552 class InsideWith {
510 public: 553 public:
511 explicit InsideWith(Scope* scope) : scope_(scope) { 554 explicit InsideWith(Scope* scope) : scope_(scope) {
512 scope->with_nesting_count_++; 555 scope->with_nesting_count_++;
513 } 556 }
514 557
515 ~InsideWith() { scope_->with_nesting_count_--; } 558 ~InsideWith() { scope_->with_nesting_count_--; }
516 559
517 private: 560 private:
518 Scope* scope_; 561 Scope* scope_;
519 DISALLOW_COPY_AND_ASSIGN(InsideWith); 562 DISALLOW_COPY_AND_ASSIGN(InsideWith);
520 }; 563 };
521 564
522 private: 565 private:
523 Scope** const variable_; 566 Scope** const variable_;
524 Scope* const prev_; 567 Scope* const prev_;
525 const ScopeType type_; 568 const ScopeType type_;
526 int materialized_literal_count_; 569 int materialized_literal_count_;
527 int expected_properties_; 570 int expected_properties_;
528 int with_nesting_count_; 571 int with_nesting_count_;
529 i::LanguageMode language_mode_; 572 LanguageMode language_mode_;
530 bool is_generator_; 573 bool is_generator_;
531 }; 574 };
532 575
533 // Report syntax error 576 // Report syntax error
534 void ReportUnexpectedToken(i::Token::Value token); 577 void ReportUnexpectedToken(Token::Value token);
535 void ReportMessageAt(i::Scanner::Location location, 578 void ReportMessageAt(Scanner::Location location, const char* type) {
579 ReportMessageAt(location, type, NULL);
580 }
581 void ReportMessageAt(Scanner::Location location,
536 const char* type, 582 const char* type,
537 const char* name_opt = NULL) { 583 const char* name_opt) {
538 log_->LogMessage(location.beg_pos, location.end_pos, type, name_opt); 584 log_->LogMessage(location.beg_pos, location.end_pos, type, name_opt);
539 } 585 }
540 void ReportMessageAt(int start_pos, 586 void ReportMessageAt(int start_pos,
541 int end_pos, 587 int end_pos,
542 const char* type, 588 const char* type,
543 const char* name_opt) { 589 const char* name_opt) {
544 log_->LogMessage(start_pos, end_pos, type, name_opt); 590 log_->LogMessage(start_pos, end_pos, type, name_opt);
545 } 591 }
546 592
547 void CheckOctalLiteral(int beg_pos, int end_pos, bool* ok);
548
549 // All ParseXXX functions take as the last argument an *ok parameter 593 // All ParseXXX functions take as the last argument an *ok parameter
550 // which is set to false if parsing failed; it is unchanged otherwise. 594 // which is set to false if parsing failed; it is unchanged otherwise.
551 // By making the 'exception handling' explicit, we are forced to check 595 // By making the 'exception handling' explicit, we are forced to check
552 // for failure at the call sites. 596 // for failure at the call sites.
553 Statement ParseSourceElement(bool* ok); 597 Statement ParseSourceElement(bool* ok);
554 SourceElements ParseSourceElements(int end_token, bool* ok); 598 SourceElements ParseSourceElements(int end_token, bool* ok);
555 Statement ParseStatement(bool* ok); 599 Statement ParseStatement(bool* ok);
556 Statement ParseFunctionDeclaration(bool* ok); 600 Statement ParseFunctionDeclaration(bool* ok);
557 Statement ParseBlock(bool* ok); 601 Statement ParseBlock(bool* ok);
558 Statement ParseVariableStatement(VariableDeclarationContext var_context, 602 Statement ParseVariableStatement(VariableDeclarationContext var_context,
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
602 bool* is_set, 646 bool* is_set,
603 bool* ok); 647 bool* ok);
604 648
605 // Logs the currently parsed literal as a symbol in the preparser data. 649 // Logs the currently parsed literal as a symbol in the preparser data.
606 void LogSymbol(); 650 void LogSymbol();
607 // Log the currently parsed identifier. 651 // Log the currently parsed identifier.
608 Identifier GetIdentifierSymbol(); 652 Identifier GetIdentifierSymbol();
609 // Log the currently parsed string literal. 653 // Log the currently parsed string literal.
610 Expression GetStringSymbol(); 654 Expression GetStringSymbol();
611 655
612 i::Token::Value peek() { 656 void set_language_mode(LanguageMode language_mode) {
613 if (stack_overflow_) return i::Token::ILLEGAL;
614 return scanner_->peek();
615 }
616
617 i::Token::Value Next() {
618 if (stack_overflow_) return i::Token::ILLEGAL;
619 {
620 int marker;
621 if (reinterpret_cast<uintptr_t>(&marker) < stack_limit_) {
622 // Further calls to peek/Next will return illegal token.
623 // The current one will still be returned. It might already
624 // have been seen using peek.
625 stack_overflow_ = true;
626 }
627 }
628 return scanner_->Next();
629 }
630
631 bool peek_any_identifier();
632
633 void set_language_mode(i::LanguageMode language_mode) {
634 scope_->set_language_mode(language_mode); 657 scope_->set_language_mode(language_mode);
635 } 658 }
636 659
637 bool is_classic_mode() { 660 bool is_classic_mode() {
638 return scope_->language_mode() == i::CLASSIC_MODE; 661 return scope_->language_mode() == CLASSIC_MODE;
639 } 662 }
640 663
641 bool is_extended_mode() { 664 bool is_extended_mode() {
642 return scope_->language_mode() == i::EXTENDED_MODE; 665 return scope_->language_mode() == EXTENDED_MODE;
643 } 666 }
644 667
645 i::LanguageMode language_mode() { return scope_->language_mode(); } 668 LanguageMode language_mode() { return scope_->language_mode(); }
646
647 void Consume(i::Token::Value token) { Next(); }
648
649 void Expect(i::Token::Value token, bool* ok) {
650 if (Next() != token) {
651 *ok = false;
652 }
653 }
654
655 bool Check(i::Token::Value token) {
656 i::Token::Value next = peek();
657 if (next == token) {
658 Consume(next);
659 return true;
660 }
661 return false;
662 }
663 void ExpectSemicolon(bool* ok);
664 669
665 bool CheckInOrOf(bool accept_OF); 670 bool CheckInOrOf(bool accept_OF);
666 671
667 static int Precedence(i::Token::Value tok, bool accept_IN); 672 void SetStrictModeViolation(Scanner::Location,
668
669 void SetStrictModeViolation(i::Scanner::Location,
670 const char* type, 673 const char* type,
671 bool* ok); 674 bool* ok);
672 675
673 void CheckDelayedStrictModeViolation(int beg_pos, int end_pos, bool* ok); 676 void CheckDelayedStrictModeViolation(int beg_pos, int end_pos, bool* ok);
674 677
675 void StrictModeIdentifierViolation(i::Scanner::Location, 678 void StrictModeIdentifierViolation(Scanner::Location,
676 const char* eval_args_type, 679 const char* eval_args_type,
677 Identifier identifier, 680 Identifier identifier,
678 bool* ok); 681 bool* ok);
679 682
680 i::Scanner* scanner_; 683 ParserRecorder* log_;
681 i::ParserRecorder* log_;
682 Scope* scope_; 684 Scope* scope_;
683 uintptr_t stack_limit_; 685 Scanner::Location strict_mode_violation_location_;
684 i::Scanner::Location strict_mode_violation_location_;
685 const char* strict_mode_violation_type_; 686 const char* strict_mode_violation_type_;
686 bool stack_overflow_;
687 bool allow_lazy_;
688 bool allow_natives_syntax_;
689 bool allow_generators_;
690 bool allow_for_of_;
691 bool parenthesized_function_; 687 bool parenthesized_function_;
692
693 friend class i::ObjectLiteralChecker<PreParser>;
694 }; 688 };
695 689
696 } } // v8::preparser 690 } } // v8::internal
697 691
698 #endif // V8_PREPARSER_H 692 #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