OLD | NEW |
---|---|
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 13 matching lines...) Expand all Loading... | |
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
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 namespace v8 { | 31 namespace v8 { |
32 namespace preparser { | 32 namespace preparser { |
33 | 33 |
34 typedef uint8_t byte; | |
35 | |
34 // Preparsing checks a JavaScript program and emits preparse-data that helps | 36 // Preparsing checks a JavaScript program and emits preparse-data that helps |
35 // a later parsing to be faster. | 37 // a later parsing to be faster. |
36 // See preparse-data-format.h for the data format. | 38 // See preparse-data-format.h for the data format. |
37 | 39 |
38 // The PreParser checks that the syntax follows the grammar for JavaScript, | 40 // The PreParser checks that the syntax follows the grammar for JavaScript, |
39 // and collects some information about the program along the way. | 41 // and collects some information about the program along the way. |
40 // The grammar check is only performed in order to understand the program | 42 // The grammar check is only performed in order to understand the program |
41 // sufficiently to deduce some information about it, that can be used | 43 // sufficiently to deduce some information about it, that can be used |
42 // to speed up later parsing. Finding errors is not the goal of pre-parsing, | 44 // to speed up later parsing. Finding errors is not the goal of pre-parsing, |
43 // rather it is to speed up properly written and correct programs. | 45 // rather it is to speed up properly written and correct programs. |
44 // That means that contextual checks (like a label being declared where | 46 // That means that contextual checks (like a label being declared where |
45 // it is used) are generally omitted. | 47 // it is used) are generally omitted. |
46 | 48 |
47 namespace i = v8::internal; | 49 namespace i = v8::internal; |
48 | 50 |
51 class DuplicateFinder { | |
52 public: | |
53 DuplicateFinder() | |
54 : backing_store_(16), | |
55 map_(new i::HashMap(&Match)) { } | |
56 ~DuplicateFinder() { | |
Mads Ager (chromium)
2011/06/16 06:48:56
Could you add a line between constructor and destr
| |
57 delete map_; | |
58 } | |
59 | |
60 int AddAsciiSymbol(i::Vector<const char> key, int value); | |
61 int AddUC16Symbol(i::Vector<const uint16_t> key, int value); | |
62 // Add a a number literal by converting it (if necessary) | |
63 // to the string that ToString(ToNumber(literal)) would generate. | |
64 // and then adding that string with AddAsciiSymbol. | |
65 // This string is the actual value used as key in an object literal, | |
66 // and the one that must be different from the other keys. | |
67 int AddNumber(i::Vector<const char> key, int value); | |
68 | |
69 private: | |
70 int AddSymbol(i::Vector<const byte> key, bool is_ascii, int value); | |
71 // Backs up the key and its length in the backing store. | |
72 // The backup is stored with a base 127 encoding of the | |
73 // length (plus a bit saying whether the string is ASCII), | |
74 // followed by the bytes of the key. | |
75 byte* BackupKey(i::Vector<const byte> key, bool is_ascii); | |
76 | |
77 // Compare two encoded keys (both pointing into the backing store) | |
78 // for having the same base-127 encoded lengths and ASCII-ness, | |
79 // and then having the same 'length' bytes following. | |
80 static bool Match(void* first, void* second); | |
81 // Creates a hash from a sequence of bytes. | |
82 static uint32_t Hash(i::Vector<const byte> key, bool is_ascii); | |
83 // Checks whether a string containing a JS number is its canonical | |
84 // form. | |
85 static bool IsNumberCanonical(i::Vector<const char> key); | |
86 | |
87 static const int kBufferSize = 100; | |
88 // Buffer used for string->number->canonical string conversions. | |
89 char number_buffer_[kBufferSize]; | |
90 // Backing store used to store strings used as hashmap keys. | |
91 i::SequenceCollector<unsigned char> backing_store_; | |
92 i::HashMap* map_; | |
93 }; | |
94 | |
95 | |
49 class PreParser { | 96 class PreParser { |
50 public: | 97 public: |
51 enum PreParseResult { | 98 enum PreParseResult { |
52 kPreParseStackOverflow, | 99 kPreParseStackOverflow, |
53 kPreParseSuccess | 100 kPreParseSuccess |
54 }; | 101 }; |
55 | 102 |
56 ~PreParser() { } | 103 ~PreParser() { } |
57 | 104 |
58 // Pre-parse the program from the character stream; returns true on | 105 // Pre-parse the program from the character stream; returns true on |
59 // success (even if parsing failed, the pre-parse data successfully | 106 // success (even if parsing failed, the pre-parse data successfully |
60 // captured the syntax error), and false if a stack-overflow happened | 107 // captured the syntax error), and false if a stack-overflow happened |
61 // during parsing. | 108 // during parsing. |
62 static PreParseResult PreParseProgram(i::JavaScriptScanner* scanner, | 109 static PreParseResult PreParseProgram(i::JavaScriptScanner* scanner, |
63 i::ParserRecorder* log, | 110 i::ParserRecorder* log, |
64 bool allow_lazy, | 111 bool allow_lazy, |
65 uintptr_t stack_limit) { | 112 uintptr_t stack_limit) { |
66 return PreParser(scanner, log, stack_limit, allow_lazy).PreParse(); | 113 return PreParser(scanner, log, stack_limit, allow_lazy).PreParse(); |
67 } | 114 } |
68 | 115 |
69 private: | 116 private: |
117 // Used to detect duplicates in object literals. | |
118 enum PropertyType { | |
Mads Ager (chromium)
2011/06/16 06:48:56
Please add a comment about the format here. I don'
| |
119 kNone = 0, | |
120 // Bit patterns representing different object literal property types. | |
121 kGetterProperty = 1, | |
122 kSetterProperty = 2, | |
123 kValueProperty = 7, | |
124 // Helper constants. | |
125 kValueFlag = 4 | |
126 }; | |
127 | |
128 void CheckDuplicate(DuplicateFinder* finder, | |
129 i::Token::Value property, | |
130 int type, | |
131 bool* ok); | |
132 | |
70 // These types form an algebra over syntactic categories that is just | 133 // These types form an algebra over syntactic categories that is just |
71 // rich enough to let us recognize and propagate the constructs that | 134 // rich enough to let us recognize and propagate the constructs that |
72 // are either being counted in the preparser data, or is important | 135 // are either being counted in the preparser data, or is important |
73 // to throw the correct syntax error exceptions. | 136 // to throw the correct syntax error exceptions. |
74 | 137 |
75 enum ScopeType { | 138 enum ScopeType { |
76 kTopLevelScope, | 139 kTopLevelScope, |
77 kFunctionScope | 140 kFunctionScope |
78 }; | 141 }; |
79 | 142 |
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
350 if (!ok) { | 413 if (!ok) { |
351 ReportUnexpectedToken(scanner_->current_token()); | 414 ReportUnexpectedToken(scanner_->current_token()); |
352 } else if (scope_->is_strict()) { | 415 } else if (scope_->is_strict()) { |
353 CheckOctalLiteral(start_position, scanner_->location().end_pos, &ok); | 416 CheckOctalLiteral(start_position, scanner_->location().end_pos, &ok); |
354 } | 417 } |
355 return kPreParseSuccess; | 418 return kPreParseSuccess; |
356 } | 419 } |
357 | 420 |
358 // Report syntax error | 421 // Report syntax error |
359 void ReportUnexpectedToken(i::Token::Value token); | 422 void ReportUnexpectedToken(i::Token::Value token); |
423 void ReportMessageAt(i::Scanner::Location location, | |
424 const char* type, | |
425 const char* name_opt) { | |
426 log_->LogMessage(location.beg_pos, location.end_pos, type, name_opt); | |
427 } | |
360 void ReportMessageAt(int start_pos, | 428 void ReportMessageAt(int start_pos, |
361 int end_pos, | 429 int end_pos, |
362 const char* type, | 430 const char* type, |
363 const char* name_opt) { | 431 const char* name_opt) { |
364 log_->LogMessage(start_pos, end_pos, type, name_opt); | 432 log_->LogMessage(start_pos, end_pos, type, name_opt); |
365 } | 433 } |
366 | 434 |
367 void CheckOctalLiteral(int beg_pos, int end_pos, bool* ok); | 435 void CheckOctalLiteral(int beg_pos, int end_pos, bool* ok); |
368 | 436 |
369 // All ParseXXX functions take as the last argument an *ok parameter | 437 // All ParseXXX functions take as the last argument an *ok parameter |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
485 uintptr_t stack_limit_; | 553 uintptr_t stack_limit_; |
486 i::Scanner::Location strict_mode_violation_location_; | 554 i::Scanner::Location strict_mode_violation_location_; |
487 const char* strict_mode_violation_type_; | 555 const char* strict_mode_violation_type_; |
488 bool stack_overflow_; | 556 bool stack_overflow_; |
489 bool allow_lazy_; | 557 bool allow_lazy_; |
490 bool parenthesized_function_; | 558 bool parenthesized_function_; |
491 }; | 559 }; |
492 } } // v8::preparser | 560 } } // v8::preparser |
493 | 561 |
494 #endif // V8_PREPARSER_H | 562 #endif // V8_PREPARSER_H |
OLD | NEW |