Revision f230a1cf deps/v8/src/preparser.h
deps/v8/src/preparser.h | ||
---|---|---|
33 | 33 |
#include "scanner.h" |
34 | 34 |
|
35 | 35 |
namespace v8 { |
36 |
|
|
37 | 36 |
namespace internal { |
38 |
class UnicodeCache; |
|
39 |
} |
|
40 | 37 |
|
41 |
namespace preparser { |
|
38 |
// Common base class shared between parser and pre-parser. |
|
39 |
class ParserBase { |
|
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() { } |
|
51 |
|
|
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 |
} |
|
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_; |
|
206 |
}; |
|
42 | 207 |
|
43 |
typedef uint8_t byte; |
|
44 | 208 |
|
45 | 209 |
// Preparsing checks a JavaScript program and emits preparse-data that helps |
46 | 210 |
// a later parsing to be faster. |
... | ... | |
54 | 218 |
// rather it is to speed up properly written and correct programs. |
55 | 219 |
// That means that contextual checks (like a label being declared where |
56 | 220 |
// it is used) are generally omitted. |
57 |
|
|
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 { |
|
221 |
class PreParser : public ParserBase { |
|
108 | 222 |
public: |
109 | 223 |
enum PreParseResult { |
110 | 224 |
kPreParseStackOverflow, |
111 | 225 |
kPreParseSuccess |
112 | 226 |
}; |
113 | 227 |
|
114 |
|
|
115 |
PreParser(i::Scanner* scanner, |
|
116 |
i::ParserRecorder* log, |
|
228 |
PreParser(Scanner* scanner, |
|
229 |
ParserRecorder* log, |
|
117 | 230 |
uintptr_t stack_limit) |
118 |
: scanner_(scanner),
|
|
231 |
: ParserBase(scanner, stack_limit),
|
|
119 | 232 |
log_(log), |
120 | 233 |
scope_(NULL), |
121 |
stack_limit_(stack_limit), |
|
122 |
strict_mode_violation_location_(i::Scanner::Location::invalid()), |
|
234 |
strict_mode_violation_location_(Scanner::Location::invalid()), |
|
123 | 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 | 236 |
parenthesized_function_(false) { } |
130 | 237 |
|
131 | 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 | 240 |
// Pre-parse the program from the character stream; returns true on |
156 | 241 |
// success (even if parsing failed, the pre-parse data successfully |
157 | 242 |
// captured the syntax error), and false if a stack-overflow happened |
... | ... | |
159 | 244 |
PreParseResult PreParseProgram() { |
160 | 245 |
Scope top_scope(&scope_, kTopLevelScope); |
161 | 246 |
bool ok = true; |
162 |
int start_position = scanner_->peek_location().beg_pos;
|
|
163 |
ParseSourceElements(i::Token::EOS, &ok);
|
|
164 |
if (stack_overflow_) return kPreParseStackOverflow;
|
|
247 |
int start_position = scanner()->peek_location().beg_pos;
|
|
248 |
ParseSourceElements(Token::EOS, &ok); |
|
249 |
if (stack_overflow()) return kPreParseStackOverflow;
|
|
165 | 250 |
if (!ok) { |
166 |
ReportUnexpectedToken(scanner_->current_token());
|
|
251 |
ReportUnexpectedToken(scanner()->current_token());
|
|
167 | 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 | 255 |
return kPreParseSuccess; |
171 | 256 |
} |
... | ... | |
178 | 263 |
// keyword and parameters, and have consumed the initial '{'. |
179 | 264 |
// At return, unless an error occurred, the scanner is positioned before the |
180 | 265 |
// the final '}'. |
181 |
PreParseResult PreParseLazyFunction(i::LanguageMode mode,
|
|
266 |
PreParseResult PreParseLazyFunction(LanguageMode mode, |
|
182 | 267 |
bool is_generator, |
183 |
i::ParserRecorder* log);
|
|
268 |
ParserRecorder* log); |
|
184 | 269 |
|
185 | 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 | 271 |
// These types form an algebra over syntactic categories that is just |
226 | 272 |
// rich enough to let us recognize and propagate the constructs that |
227 | 273 |
// are either being counted in the preparser data, or is important |
... | ... | |
441 | 487 |
} |
442 | 488 |
|
443 | 489 |
bool IsStringLiteral() { |
444 |
return code_ != kUnknownStatement;
|
|
490 |
return code_ == kStringLiteralExpressionStatement;
|
|
445 | 491 |
} |
446 | 492 |
|
447 | 493 |
bool IsUseStrictLiteral() { |
... | ... | |
480 | 526 |
expected_properties_(0), |
481 | 527 |
with_nesting_count_(0), |
482 | 528 |
language_mode_( |
483 |
(prev_ != NULL) ? prev_->language_mode() : i::CLASSIC_MODE),
|
|
529 |
(prev_ != NULL) ? prev_->language_mode() : CLASSIC_MODE), |
|
484 | 530 |
is_generator_(false) { |
485 | 531 |
*variable = this; |
486 | 532 |
} |
... | ... | |
494 | 540 |
bool is_generator() { return is_generator_; } |
495 | 541 |
void set_is_generator(bool is_generator) { is_generator_ = is_generator; } |
496 | 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 | 546 |
return language_mode_; |
501 | 547 |
} |
502 |
void set_language_mode(i::LanguageMode language_mode) {
|
|
548 |
void set_language_mode(LanguageMode language_mode) { |
|
503 | 549 |
language_mode_ = language_mode; |
504 | 550 |
} |
505 | 551 |
|
... | ... | |
523 | 569 |
int materialized_literal_count_; |
524 | 570 |
int expected_properties_; |
525 | 571 |
int with_nesting_count_; |
526 |
i::LanguageMode language_mode_;
|
|
572 |
LanguageMode language_mode_; |
|
527 | 573 |
bool is_generator_; |
528 | 574 |
}; |
529 | 575 |
|
530 | 576 |
// Report syntax error |
531 |
void ReportUnexpectedToken(i::Token::Value token); |
|
532 |
void ReportMessageAt(i::Scanner::Location location, |
|
577 |
void ReportUnexpectedToken(Token::Value token); |
|
578 |
void ReportMessageAt(Scanner::Location location, const char* type) { |
|
579 |
ReportMessageAt(location, type, NULL); |
|
580 |
} |
|
581 |
void ReportMessageAt(Scanner::Location location, |
|
533 | 582 |
const char* type, |
534 | 583 |
const char* name_opt) { |
535 | 584 |
log_->LogMessage(location.beg_pos, location.end_pos, type, name_opt); |
... | ... | |
541 | 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 | 593 |
// All ParseXXX functions take as the last argument an *ok parameter |
547 | 594 |
// which is set to false if parsing failed; it is unchanged otherwise. |
548 | 595 |
// By making the 'exception handling' explicit, we are forced to check |
... | ... | |
606 | 653 |
// Log the currently parsed string literal. |
607 | 654 |
Expression GetStringSymbol(); |
608 | 655 |
|
609 |
i::Token::Value peek() { |
|
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) { |
|
656 |
void set_language_mode(LanguageMode language_mode) { |
|
631 | 657 |
scope_->set_language_mode(language_mode); |
632 | 658 |
} |
633 | 659 |
|
634 | 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 | 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(); } |
|
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); |
|
668 |
LanguageMode language_mode() { return scope_->language_mode(); } |
|
661 | 669 |
|
662 | 670 |
bool CheckInOrOf(bool accept_OF); |
663 | 671 |
|
664 |
static int Precedence(i::Token::Value tok, bool accept_IN); |
|
665 |
|
|
666 |
void SetStrictModeViolation(i::Scanner::Location, |
|
672 |
void SetStrictModeViolation(Scanner::Location, |
|
667 | 673 |
const char* type, |
668 | 674 |
bool* ok); |
669 | 675 |
|
670 | 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 | 679 |
const char* eval_args_type, |
674 | 680 |
Identifier identifier, |
675 | 681 |
bool* ok); |
676 | 682 |
|
677 |
i::Scanner* scanner_; |
|
678 |
i::ParserRecorder* log_; |
|
683 |
ParserRecorder* log_; |
|
679 | 684 |
Scope* scope_; |
680 |
uintptr_t stack_limit_; |
|
681 |
i::Scanner::Location strict_mode_violation_location_; |
|
685 |
Scanner::Location strict_mode_violation_location_; |
|
682 | 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 | 687 |
bool parenthesized_function_; |
689 | 688 |
}; |
690 |
} } // v8::preparser |
|
689 |
|
|
690 |
} } // v8::internal |
|
691 | 691 |
|
692 | 692 |
#endif // V8_PREPARSER_H |
Also available in: Unified diff