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

Side by Side Diff: src/preparser.h

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

Powered by Google App Engine
This is Rietveld 408576698