| OLD | NEW |
| 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 17 matching lines...) Expand all Loading... |
| 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 namespace internal { |
| 37 | 37 |
| 38 // Used to detect duplicates in object literals. Each of the values | |
| 39 // kGetterProperty, kSetterProperty and kValueProperty represents | |
| 40 // a type of object literal property. When parsing a property, its | |
| 41 // type value is stored in the DuplicateFinder for the property name. | |
| 42 // Values are chosen so that having intersection bits means the there is | |
| 43 // an incompatibility. | |
| 44 // I.e., you can add a getter to a property that already has a setter, since | |
| 45 // kGetterProperty and kSetterProperty doesn't intersect, but not if it | |
| 46 // already has a getter or a value. Adding the getter to an existing | |
| 47 // setter will store the value (kGetterProperty | kSetterProperty), which | |
| 48 // is incompatible with adding any further properties. | |
| 49 enum PropertyKind { | |
| 50 kNone = 0, | |
| 51 // Bit patterns representing different object literal property types. | |
| 52 kGetterProperty = 1, | |
| 53 kSetterProperty = 2, | |
| 54 kValueProperty = 7, | |
| 55 // Helper constants. | |
| 56 kValueFlag = 4 | |
| 57 }; | |
| 58 | |
| 59 | |
| 60 // Validation per 11.1.5 Object Initialiser | |
| 61 template<typename P> | |
| 62 class ObjectLiteralChecker { | |
| 63 public: | |
| 64 ObjectLiteralChecker(P* parser, Scanner* scanner, LanguageMode mode) | |
| 65 : parser_(parser), | |
| 66 scanner_(scanner), | |
| 67 finder_(scanner->unicode_cache()), | |
| 68 language_mode_(mode) { } | |
| 69 | |
| 70 void CheckProperty(Token::Value property, PropertyKind type, bool* ok); | |
| 71 | |
| 72 private: | |
| 73 // Checks the type of conflict based on values coming from PropertyType. | |
| 74 bool HasConflict(PropertyKind type1, PropertyKind type2) { | |
| 75 return (type1 & type2) != 0; | |
| 76 } | |
| 77 bool IsDataDataConflict(PropertyKind type1, PropertyKind type2) { | |
| 78 return ((type1 & type2) & kValueFlag) != 0; | |
| 79 } | |
| 80 bool IsDataAccessorConflict(PropertyKind type1, PropertyKind type2) { | |
| 81 return ((type1 ^ type2) & kValueFlag) != 0; | |
| 82 } | |
| 83 bool IsAccessorAccessorConflict(PropertyKind type1, PropertyKind type2) { | |
| 84 return ((type1 | type2) & kValueFlag) == 0; | |
| 85 } | |
| 86 | |
| 87 P* parser_; | |
| 88 Scanner* scanner_; | |
| 89 DuplicateFinder finder_; | |
| 90 LanguageMode language_mode_; | |
| 91 }; | |
| 92 | |
| 93 | |
| 94 template<typename P> | |
| 95 void ObjectLiteralChecker<P>::CheckProperty(Token::Value property, | |
| 96 PropertyKind type, | |
| 97 bool* ok) { | |
| 98 int old; | |
| 99 if (property == Token::NUMBER) { | |
| 100 old = finder_.AddNumber(scanner_->literal_ascii_string(), type); | |
| 101 } else if (scanner_->is_literal_ascii()) { | |
| 102 old = finder_.AddAsciiSymbol(scanner_->literal_ascii_string(), type); | |
| 103 } else { | |
| 104 old = finder_.AddUtf16Symbol(scanner_->literal_utf16_string(), type); | |
| 105 } | |
| 106 PropertyKind old_type = static_cast<PropertyKind>(old); | |
| 107 if (HasConflict(old_type, type)) { | |
| 108 if (IsDataDataConflict(old_type, type)) { | |
| 109 // Both are data properties. | |
| 110 if (language_mode_ == CLASSIC_MODE) return; | |
| 111 parser_->ReportMessageAt(scanner_->location(), | |
| 112 "strict_duplicate_property"); | |
| 113 } else if (IsDataAccessorConflict(old_type, type)) { | |
| 114 // Both a data and an accessor property with the same name. | |
| 115 parser_->ReportMessageAt(scanner_->location(), | |
| 116 "accessor_data_property"); | |
| 117 } else { | |
| 118 ASSERT(IsAccessorAccessorConflict(old_type, type)); | |
| 119 // Both accessors of the same type. | |
| 120 parser_->ReportMessageAt(scanner_->location(), | |
| 121 "accessor_get_set"); | |
| 122 } | |
| 123 *ok = false; | |
| 124 } | |
| 125 } | |
| 126 | |
| 127 | |
| 128 // Common base class shared between parser and pre-parser. | 38 // Common base class shared between parser and pre-parser. |
| 129 class ParserBase { | 39 class ParserBase { |
| 130 public: | 40 public: |
| 131 ParserBase(Scanner* scanner, uintptr_t stack_limit) | 41 ParserBase(Scanner* scanner, uintptr_t stack_limit) |
| 132 : scanner_(scanner), | 42 : scanner_(scanner), |
| 133 stack_limit_(stack_limit), | 43 stack_limit_(stack_limit), |
| 134 stack_overflow_(false), | 44 stack_overflow_(false), |
| 135 allow_lazy_(false), | 45 allow_lazy_(false), |
| 136 allow_natives_syntax_(false), | 46 allow_natives_syntax_(false), |
| 137 allow_generators_(false), | 47 allow_generators_(false), |
| (...skipping 22 matching lines...) Expand all Loading... |
| 160 void set_allow_modules(bool allow) { scanner()->SetHarmonyModules(allow); } | 70 void set_allow_modules(bool allow) { scanner()->SetHarmonyModules(allow); } |
| 161 void set_allow_harmony_scoping(bool allow) { | 71 void set_allow_harmony_scoping(bool allow) { |
| 162 scanner()->SetHarmonyScoping(allow); | 72 scanner()->SetHarmonyScoping(allow); |
| 163 } | 73 } |
| 164 void set_allow_harmony_numeric_literals(bool allow) { | 74 void set_allow_harmony_numeric_literals(bool allow) { |
| 165 scanner()->SetHarmonyNumericLiterals(allow); | 75 scanner()->SetHarmonyNumericLiterals(allow); |
| 166 } | 76 } |
| 167 | 77 |
| 168 protected: | 78 protected: |
| 169 Scanner* scanner() const { return scanner_; } | 79 Scanner* scanner() const { return scanner_; } |
| 80 int position() { return scanner_->location().beg_pos; } |
| 81 int peek_position() { return scanner_->peek_location().beg_pos; } |
| 170 bool stack_overflow() const { return stack_overflow_; } | 82 bool stack_overflow() const { return stack_overflow_; } |
| 171 void set_stack_overflow() { stack_overflow_ = true; } | 83 void set_stack_overflow() { stack_overflow_ = true; } |
| 172 | 84 |
| 173 INLINE(Token::Value peek()) { | 85 INLINE(Token::Value peek()) { |
| 174 if (stack_overflow_) return Token::ILLEGAL; | 86 if (stack_overflow_) return Token::ILLEGAL; |
| 175 return scanner()->peek(); | 87 return scanner()->peek(); |
| 176 } | 88 } |
| 177 | 89 |
| 178 INLINE(Token::Value Next()) { | 90 INLINE(Token::Value Next()) { |
| 179 if (stack_overflow_) return Token::ILLEGAL; | 91 if (stack_overflow_) return Token::ILLEGAL; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 208 void Expect(Token::Value token, bool* ok) { | 120 void Expect(Token::Value token, bool* ok) { |
| 209 Token::Value next = Next(); | 121 Token::Value next = Next(); |
| 210 if (next != token) { | 122 if (next != token) { |
| 211 ReportUnexpectedToken(next); | 123 ReportUnexpectedToken(next); |
| 212 *ok = false; | 124 *ok = false; |
| 213 } | 125 } |
| 214 } | 126 } |
| 215 | 127 |
| 216 bool peek_any_identifier(); | 128 bool peek_any_identifier(); |
| 217 void ExpectSemicolon(bool* ok); | 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); |
| 218 | 138 |
| 219 // Report syntax errors. | 139 // Report syntax errors. |
| 220 virtual void ReportUnexpectedToken(Token::Value token) = 0; | 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 }; |
| 221 | 196 |
| 222 private: | 197 private: |
| 223 Scanner* scanner_; | 198 Scanner* scanner_; |
| 224 uintptr_t stack_limit_; | 199 uintptr_t stack_limit_; |
| 225 bool stack_overflow_; | 200 bool stack_overflow_; |
| 226 | 201 |
| 227 bool allow_lazy_; | 202 bool allow_lazy_; |
| 228 bool allow_natives_syntax_; | 203 bool allow_natives_syntax_; |
| 229 bool allow_generators_; | 204 bool allow_generators_; |
| 230 bool allow_for_of_; | 205 bool allow_for_of_; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 247 typedef uint8_t byte; | 222 typedef uint8_t byte; |
| 248 namespace i = v8::internal; | 223 namespace i = v8::internal; |
| 249 | 224 |
| 250 class PreParser : public ParserBase { | 225 class PreParser : public ParserBase { |
| 251 public: | 226 public: |
| 252 enum PreParseResult { | 227 enum PreParseResult { |
| 253 kPreParseStackOverflow, | 228 kPreParseStackOverflow, |
| 254 kPreParseSuccess | 229 kPreParseSuccess |
| 255 }; | 230 }; |
| 256 | 231 |
| 257 | 232 PreParser(Scanner* scanner, |
| 258 PreParser(i::Scanner* scanner, | 233 ParserRecorder* log, |
| 259 i::ParserRecorder* log, | |
| 260 uintptr_t stack_limit) | 234 uintptr_t stack_limit) |
| 261 : ParserBase(scanner, stack_limit), | 235 : ParserBase(scanner, stack_limit), |
| 262 log_(log), | 236 log_(log), |
| 263 scope_(NULL), | 237 scope_(NULL), |
| 264 strict_mode_violation_location_(i::Scanner::Location::invalid()), | 238 strict_mode_violation_location_(Scanner::Location::invalid()), |
| 265 strict_mode_violation_type_(NULL), | 239 strict_mode_violation_type_(NULL), |
| 266 parenthesized_function_(false) { } | 240 parenthesized_function_(false) { } |
| 267 | 241 |
| 268 ~PreParser() {} | 242 ~PreParser() {} |
| 269 | 243 |
| 270 // Pre-parse the program from the character stream; returns true on | 244 // Pre-parse the program from the character stream; returns true on |
| 271 // success (even if parsing failed, the pre-parse data successfully | 245 // success (even if parsing failed, the pre-parse data successfully |
| 272 // captured the syntax error), and false if a stack-overflow happened | 246 // captured the syntax error), and false if a stack-overflow happened |
| 273 // during parsing. | 247 // during parsing. |
| 274 PreParseResult PreParseProgram() { | 248 PreParseResult PreParseProgram() { |
| 275 Scope top_scope(&scope_, kTopLevelScope); | 249 Scope top_scope(&scope_, kTopLevelScope); |
| 276 bool ok = true; | 250 bool ok = true; |
| 277 int start_position = scanner()->peek_location().beg_pos; | 251 int start_position = scanner()->peek_location().beg_pos; |
| 278 ParseSourceElements(i::Token::EOS, &ok); | 252 ParseSourceElements(Token::EOS, &ok); |
| 279 if (stack_overflow()) return kPreParseStackOverflow; | 253 if (stack_overflow()) return kPreParseStackOverflow; |
| 280 if (!ok) { | 254 if (!ok) { |
| 281 ReportUnexpectedToken(scanner()->current_token()); | 255 ReportUnexpectedToken(scanner()->current_token()); |
| 282 } else if (!scope_->is_classic_mode()) { | 256 } else if (!scope_->is_classic_mode()) { |
| 283 CheckOctalLiteral(start_position, scanner()->location().end_pos, &ok); | 257 CheckOctalLiteral(start_position, scanner()->location().end_pos, &ok); |
| 284 } | 258 } |
| 285 return kPreParseSuccess; | 259 return kPreParseSuccess; |
| 286 } | 260 } |
| 287 | 261 |
| 288 // Parses a single function literal, from the opening parentheses before | 262 // Parses a single function literal, from the opening parentheses before |
| 289 // parameters to the closing brace after the body. | 263 // parameters to the closing brace after the body. |
| 290 // Returns a FunctionEntry describing the body of the function in enough | 264 // Returns a FunctionEntry describing the body of the function in enough |
| 291 // detail that it can be lazily compiled. | 265 // detail that it can be lazily compiled. |
| 292 // The scanner is expected to have matched the "function" or "function*" | 266 // The scanner is expected to have matched the "function" or "function*" |
| 293 // keyword and parameters, and have consumed the initial '{'. | 267 // keyword and parameters, and have consumed the initial '{'. |
| 294 // At return, unless an error occurred, the scanner is positioned before the | 268 // At return, unless an error occurred, the scanner is positioned before the |
| 295 // the final '}'. | 269 // the final '}'. |
| 296 PreParseResult PreParseLazyFunction(i::LanguageMode mode, | 270 PreParseResult PreParseLazyFunction(LanguageMode mode, |
| 297 bool is_generator, | 271 bool is_generator, |
| 298 i::ParserRecorder* log); | 272 ParserRecorder* log); |
| 299 | 273 |
| 300 private: | 274 private: |
| 301 // These types form an algebra over syntactic categories that is just | 275 // These types form an algebra over syntactic categories that is just |
| 302 // rich enough to let us recognize and propagate the constructs that | 276 // rich enough to let us recognize and propagate the constructs that |
| 303 // are either being counted in the preparser data, or is important | 277 // are either being counted in the preparser data, or is important |
| 304 // to throw the correct syntax error exceptions. | 278 // to throw the correct syntax error exceptions. |
| 305 | 279 |
| 306 enum ScopeType { | 280 enum ScopeType { |
| 307 kTopLevelScope, | 281 kTopLevelScope, |
| 308 kFunctionScope | 282 kFunctionScope |
| (...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 549 class Scope { | 523 class Scope { |
| 550 public: | 524 public: |
| 551 Scope(Scope** variable, ScopeType type) | 525 Scope(Scope** variable, ScopeType type) |
| 552 : variable_(variable), | 526 : variable_(variable), |
| 553 prev_(*variable), | 527 prev_(*variable), |
| 554 type_(type), | 528 type_(type), |
| 555 materialized_literal_count_(0), | 529 materialized_literal_count_(0), |
| 556 expected_properties_(0), | 530 expected_properties_(0), |
| 557 with_nesting_count_(0), | 531 with_nesting_count_(0), |
| 558 language_mode_( | 532 language_mode_( |
| 559 (prev_ != NULL) ? prev_->language_mode() : i::CLASSIC_MODE), | 533 (prev_ != NULL) ? prev_->language_mode() : CLASSIC_MODE), |
| 560 is_generator_(false) { | 534 is_generator_(false) { |
| 561 *variable = this; | 535 *variable = this; |
| 562 } | 536 } |
| 563 ~Scope() { *variable_ = prev_; } | 537 ~Scope() { *variable_ = prev_; } |
| 564 void NextMaterializedLiteralIndex() { materialized_literal_count_++; } | 538 void NextMaterializedLiteralIndex() { materialized_literal_count_++; } |
| 565 void AddProperty() { expected_properties_++; } | 539 void AddProperty() { expected_properties_++; } |
| 566 ScopeType type() { return type_; } | 540 ScopeType type() { return type_; } |
| 567 int expected_properties() { return expected_properties_; } | 541 int expected_properties() { return expected_properties_; } |
| 568 int materialized_literal_count() { return materialized_literal_count_; } | 542 int materialized_literal_count() { return materialized_literal_count_; } |
| 569 bool IsInsideWith() { return with_nesting_count_ != 0; } | 543 bool IsInsideWith() { return with_nesting_count_ != 0; } |
| 570 bool is_generator() { return is_generator_; } | 544 bool is_generator() { return is_generator_; } |
| 571 void set_is_generator(bool is_generator) { is_generator_ = is_generator; } | 545 void set_is_generator(bool is_generator) { is_generator_ = is_generator; } |
| 572 bool is_classic_mode() { | 546 bool is_classic_mode() { |
| 573 return language_mode_ == i::CLASSIC_MODE; | 547 return language_mode_ == CLASSIC_MODE; |
| 574 } | 548 } |
| 575 i::LanguageMode language_mode() { | 549 LanguageMode language_mode() { |
| 576 return language_mode_; | 550 return language_mode_; |
| 577 } | 551 } |
| 578 void set_language_mode(i::LanguageMode language_mode) { | 552 void set_language_mode(LanguageMode language_mode) { |
| 579 language_mode_ = language_mode; | 553 language_mode_ = language_mode; |
| 580 } | 554 } |
| 581 | 555 |
| 582 class InsideWith { | 556 class InsideWith { |
| 583 public: | 557 public: |
| 584 explicit InsideWith(Scope* scope) : scope_(scope) { | 558 explicit InsideWith(Scope* scope) : scope_(scope) { |
| 585 scope->with_nesting_count_++; | 559 scope->with_nesting_count_++; |
| 586 } | 560 } |
| 587 | 561 |
| 588 ~InsideWith() { scope_->with_nesting_count_--; } | 562 ~InsideWith() { scope_->with_nesting_count_--; } |
| 589 | 563 |
| 590 private: | 564 private: |
| 591 Scope* scope_; | 565 Scope* scope_; |
| 592 DISALLOW_COPY_AND_ASSIGN(InsideWith); | 566 DISALLOW_COPY_AND_ASSIGN(InsideWith); |
| 593 }; | 567 }; |
| 594 | 568 |
| 595 private: | 569 private: |
| 596 Scope** const variable_; | 570 Scope** const variable_; |
| 597 Scope* const prev_; | 571 Scope* const prev_; |
| 598 const ScopeType type_; | 572 const ScopeType type_; |
| 599 int materialized_literal_count_; | 573 int materialized_literal_count_; |
| 600 int expected_properties_; | 574 int expected_properties_; |
| 601 int with_nesting_count_; | 575 int with_nesting_count_; |
| 602 i::LanguageMode language_mode_; | 576 LanguageMode language_mode_; |
| 603 bool is_generator_; | 577 bool is_generator_; |
| 604 }; | 578 }; |
| 605 | 579 |
| 606 // Report syntax error | 580 // Report syntax error |
| 607 void ReportUnexpectedToken(i::Token::Value token); | 581 void ReportUnexpectedToken(Token::Value token); |
| 608 void ReportMessageAt(i::Scanner::Location location, | 582 void ReportMessageAt(Scanner::Location location, const char* type) { |
| 583 ReportMessageAt(location, type, NULL); |
| 584 } |
| 585 void ReportMessageAt(Scanner::Location location, |
| 609 const char* type, | 586 const char* type, |
| 610 const char* name_opt = NULL) { | 587 const char* name_opt) { |
| 611 log_->LogMessage(location.beg_pos, location.end_pos, type, name_opt); | 588 log_->LogMessage(location.beg_pos, location.end_pos, type, name_opt); |
| 612 } | 589 } |
| 613 void ReportMessageAt(int start_pos, | 590 void ReportMessageAt(int start_pos, |
| 614 int end_pos, | 591 int end_pos, |
| 615 const char* type, | 592 const char* type, |
| 616 const char* name_opt) { | 593 const char* name_opt) { |
| 617 log_->LogMessage(start_pos, end_pos, type, name_opt); | 594 log_->LogMessage(start_pos, end_pos, type, name_opt); |
| 618 } | 595 } |
| 619 | 596 |
| 620 void CheckOctalLiteral(int beg_pos, int end_pos, bool* ok); | |
| 621 | |
| 622 // All ParseXXX functions take as the last argument an *ok parameter | 597 // All ParseXXX functions take as the last argument an *ok parameter |
| 623 // which is set to false if parsing failed; it is unchanged otherwise. | 598 // which is set to false if parsing failed; it is unchanged otherwise. |
| 624 // By making the 'exception handling' explicit, we are forced to check | 599 // By making the 'exception handling' explicit, we are forced to check |
| 625 // for failure at the call sites. | 600 // for failure at the call sites. |
| 626 Statement ParseSourceElement(bool* ok); | 601 Statement ParseSourceElement(bool* ok); |
| 627 SourceElements ParseSourceElements(int end_token, bool* ok); | 602 SourceElements ParseSourceElements(int end_token, bool* ok); |
| 628 Statement ParseStatement(bool* ok); | 603 Statement ParseStatement(bool* ok); |
| 629 Statement ParseFunctionDeclaration(bool* ok); | 604 Statement ParseFunctionDeclaration(bool* ok); |
| 630 Statement ParseBlock(bool* ok); | 605 Statement ParseBlock(bool* ok); |
| 631 Statement ParseVariableStatement(VariableDeclarationContext var_context, | 606 Statement ParseVariableStatement(VariableDeclarationContext var_context, |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 675 bool* is_set, | 650 bool* is_set, |
| 676 bool* ok); | 651 bool* ok); |
| 677 | 652 |
| 678 // Logs the currently parsed literal as a symbol in the preparser data. | 653 // Logs the currently parsed literal as a symbol in the preparser data. |
| 679 void LogSymbol(); | 654 void LogSymbol(); |
| 680 // Log the currently parsed identifier. | 655 // Log the currently parsed identifier. |
| 681 Identifier GetIdentifierSymbol(); | 656 Identifier GetIdentifierSymbol(); |
| 682 // Log the currently parsed string literal. | 657 // Log the currently parsed string literal. |
| 683 Expression GetStringSymbol(); | 658 Expression GetStringSymbol(); |
| 684 | 659 |
| 685 void set_language_mode(i::LanguageMode language_mode) { | 660 void set_language_mode(LanguageMode language_mode) { |
| 686 scope_->set_language_mode(language_mode); | 661 scope_->set_language_mode(language_mode); |
| 687 } | 662 } |
| 688 | 663 |
| 689 bool is_classic_mode() { | 664 bool is_classic_mode() { |
| 690 return scope_->language_mode() == i::CLASSIC_MODE; | 665 return scope_->language_mode() == CLASSIC_MODE; |
| 691 } | 666 } |
| 692 | 667 |
| 693 bool is_extended_mode() { | 668 bool is_extended_mode() { |
| 694 return scope_->language_mode() == i::EXTENDED_MODE; | 669 return scope_->language_mode() == EXTENDED_MODE; |
| 695 } | 670 } |
| 696 | 671 |
| 697 i::LanguageMode language_mode() { return scope_->language_mode(); } | 672 LanguageMode language_mode() { return scope_->language_mode(); } |
| 698 | 673 |
| 699 bool CheckInOrOf(bool accept_OF); | 674 bool CheckInOrOf(bool accept_OF); |
| 700 | 675 |
| 701 static int Precedence(i::Token::Value tok, bool accept_IN); | 676 void SetStrictModeViolation(Scanner::Location, |
| 702 | |
| 703 void SetStrictModeViolation(i::Scanner::Location, | |
| 704 const char* type, | 677 const char* type, |
| 705 bool* ok); | 678 bool* ok); |
| 706 | 679 |
| 707 void CheckDelayedStrictModeViolation(int beg_pos, int end_pos, bool* ok); | 680 void CheckDelayedStrictModeViolation(int beg_pos, int end_pos, bool* ok); |
| 708 | 681 |
| 709 void StrictModeIdentifierViolation(i::Scanner::Location, | 682 void StrictModeIdentifierViolation(Scanner::Location, |
| 710 const char* eval_args_type, | 683 const char* eval_args_type, |
| 711 Identifier identifier, | 684 Identifier identifier, |
| 712 bool* ok); | 685 bool* ok); |
| 713 | 686 |
| 714 i::ParserRecorder* log_; | 687 ParserRecorder* log_; |
| 715 Scope* scope_; | 688 Scope* scope_; |
| 716 i::Scanner::Location strict_mode_violation_location_; | 689 Scanner::Location strict_mode_violation_location_; |
| 717 const char* strict_mode_violation_type_; | 690 const char* strict_mode_violation_type_; |
| 718 bool parenthesized_function_; | 691 bool parenthesized_function_; |
| 719 | |
| 720 friend class i::ObjectLiteralChecker<PreParser>; | |
| 721 }; | 692 }; |
| 722 | 693 |
| 723 } } // v8::internal | 694 } } // v8::internal |
| 724 | 695 |
| 725 #endif // V8_PREPARSER_H | 696 #endif // V8_PREPARSER_H |
| OLD | NEW |