OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 14 matching lines...) Expand all Loading... |
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_PARSER_H_ | 28 #ifndef V8_PARSER_H_ |
29 #define V8_PARSER_H_ | 29 #define V8_PARSER_H_ |
30 | 30 |
31 #include "allocation.h" | 31 #include "allocation.h" |
32 #include "ast.h" | 32 #include "ast.h" |
33 #include "scanner.h" | 33 #include "scanner.h" |
34 #include "scopes.h" | 34 #include "scopes.h" |
| 35 #include "preparse-data.h" |
35 | 36 |
36 namespace v8 { | 37 namespace v8 { |
37 namespace internal { | 38 namespace internal { |
38 | 39 |
39 class CompilationInfo; | 40 class CompilationInfo; |
40 class FuncNameInferrer; | 41 class FuncNameInferrer; |
41 class ParserLog; | 42 class ParserLog; |
42 class PositionStack; | 43 class PositionStack; |
43 class Target; | 44 class Target; |
44 class TemporaryScope; | 45 class TemporaryScope; |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
116 | 117 |
117 FunctionEntry GetFunctionEntry(int start); | 118 FunctionEntry GetFunctionEntry(int start); |
118 int GetSymbolIdentifier(); | 119 int GetSymbolIdentifier(); |
119 bool SanityCheck(); | 120 bool SanityCheck(); |
120 | 121 |
121 Scanner::Location MessageLocation(); | 122 Scanner::Location MessageLocation(); |
122 const char* BuildMessage(); | 123 const char* BuildMessage(); |
123 Vector<const char*> BuildArgs(); | 124 Vector<const char*> BuildArgs(); |
124 | 125 |
125 int symbol_count() { | 126 int symbol_count() { |
126 return (store_.length() > kHeaderSize) ? store_[kSymbolCountOffset] : 0; | 127 return (store_.length() > PreparseDataConstants::kHeaderSize) |
| 128 ? store_[PreparseDataConstants::kSymbolCountOffset] |
| 129 : 0; |
127 } | 130 } |
128 // The following functions should only be called if SanityCheck has | 131 // The following functions should only be called if SanityCheck has |
129 // returned true. | 132 // returned true. |
130 bool has_error() { return store_[kHasErrorOffset]; } | 133 bool has_error() { return store_[PreparseDataConstants::kHasErrorOffset]; } |
131 unsigned magic() { return store_[kMagicOffset]; } | 134 unsigned magic() { return store_[PreparseDataConstants::kMagicOffset]; } |
132 unsigned version() { return store_[kVersionOffset]; } | 135 unsigned version() { return store_[PreparseDataConstants::kVersionOffset]; } |
133 | |
134 static const unsigned kMagicNumber = 0xBadDead; | |
135 static const unsigned kCurrentVersion = 5; | |
136 | |
137 static const int kMagicOffset = 0; | |
138 static const int kVersionOffset = 1; | |
139 static const int kHasErrorOffset = 2; | |
140 static const int kFunctionsSizeOffset = 3; | |
141 static const int kSymbolCountOffset = 4; | |
142 static const int kSizeOffset = 5; | |
143 static const int kHeaderSize = 6; | |
144 | |
145 // If encoding a message, the following positions are fixed. | |
146 static const int kMessageStartPos = 0; | |
147 static const int kMessageEndPos = 1; | |
148 static const int kMessageArgCountPos = 2; | |
149 static const int kMessageTextPos = 3; | |
150 | |
151 static const byte kNumberTerminator = 0x80u; | |
152 | 136 |
153 private: | 137 private: |
154 Vector<unsigned> store_; | 138 Vector<unsigned> store_; |
155 unsigned char* symbol_data_; | 139 unsigned char* symbol_data_; |
156 unsigned char* symbol_data_end_; | 140 unsigned char* symbol_data_end_; |
157 int function_index_; | 141 int function_index_; |
158 bool owns_store_; | 142 bool owns_store_; |
159 | 143 |
160 unsigned Read(int position); | 144 unsigned Read(int position); |
161 unsigned* ReadAddress(int position); | 145 unsigned* ReadAddress(int position); |
162 // Reads a number from the current symbols | 146 // Reads a number from the current symbols |
163 int ReadNumber(byte** source); | 147 int ReadNumber(byte** source); |
164 | 148 |
165 ScriptDataImpl(const char* backing_store, int length) | 149 ScriptDataImpl(const char* backing_store, int length) |
166 : store_(reinterpret_cast<unsigned*>(const_cast<char*>(backing_store)), | 150 : store_(reinterpret_cast<unsigned*>(const_cast<char*>(backing_store)), |
167 length / static_cast<int>(sizeof(unsigned))), | 151 length / static_cast<int>(sizeof(unsigned))), |
168 owns_store_(false) { | 152 owns_store_(false) { |
169 ASSERT_EQ(0, static_cast<int>( | 153 ASSERT_EQ(0, static_cast<int>( |
170 reinterpret_cast<intptr_t>(backing_store) % sizeof(unsigned))); | 154 reinterpret_cast<intptr_t>(backing_store) % sizeof(unsigned))); |
171 } | 155 } |
172 | 156 |
173 // Read strings written by ParserRecorder::WriteString. | 157 // Read strings written by ParserRecorder::WriteString. |
174 static const char* ReadString(unsigned* start, int* chars); | 158 static const char* ReadString(unsigned* start, int* chars); |
175 | 159 |
176 friend class ScriptData; | 160 friend class ScriptData; |
177 }; | 161 }; |
178 | 162 |
179 | 163 |
180 // Record only functions. | |
181 class PartialParserRecorder { | |
182 public: | |
183 PartialParserRecorder(); | |
184 virtual ~PartialParserRecorder() {} | |
185 | |
186 void LogFunction(int start, int end, int literals, int properties) { | |
187 function_store_.Add(start); | |
188 function_store_.Add(end); | |
189 function_store_.Add(literals); | |
190 function_store_.Add(properties); | |
191 } | |
192 | |
193 virtual void LogSymbol(int start, const char* symbol, int length) { } | |
194 | |
195 // Logs an error message and marks the log as containing an error. | |
196 // Further logging will be ignored, and ExtractData will return a vector | |
197 // representing the error only. | |
198 void LogMessage(int start, | |
199 int end, | |
200 const char* message, | |
201 const char* argument_opt) { | |
202 Scanner::Location location(start, end); | |
203 Vector<const char*> arguments; | |
204 if (argument_opt != NULL) { | |
205 arguments = Vector<const char*>(&argument_opt, 1); | |
206 } | |
207 this->LogMessage(location, message, arguments); | |
208 } | |
209 | |
210 int function_position() { return function_store_.size(); } | |
211 | |
212 void LogMessage(Scanner::Location loc, | |
213 const char* message, | |
214 Vector<const char*> args); | |
215 | |
216 virtual Vector<unsigned> ExtractData(); | |
217 | |
218 void PauseRecording() { | |
219 pause_count_++; | |
220 is_recording_ = false; | |
221 } | |
222 | |
223 void ResumeRecording() { | |
224 ASSERT(pause_count_ > 0); | |
225 if (--pause_count_ == 0) is_recording_ = !has_error(); | |
226 } | |
227 | |
228 int symbol_position() { return 0; } | |
229 int symbol_ids() { return 0; } | |
230 | |
231 protected: | |
232 bool has_error() { | |
233 return static_cast<bool>(preamble_[ScriptDataImpl::kHasErrorOffset]); | |
234 } | |
235 | |
236 bool is_recording() { | |
237 return is_recording_; | |
238 } | |
239 | |
240 void WriteString(Vector<const char> str); | |
241 | |
242 Collector<unsigned> function_store_; | |
243 unsigned preamble_[ScriptDataImpl::kHeaderSize]; | |
244 bool is_recording_; | |
245 int pause_count_; | |
246 | |
247 #ifdef DEBUG | |
248 int prev_start_; | |
249 #endif | |
250 }; | |
251 | |
252 | |
253 // Record both functions and symbols. | |
254 class CompleteParserRecorder: public PartialParserRecorder { | |
255 public: | |
256 CompleteParserRecorder(); | |
257 virtual ~CompleteParserRecorder() { } | |
258 | |
259 void LogSymbol(int start, Vector<const char> literal); | |
260 | |
261 virtual void LogSymbol(int start, const char* symbol, int length) { | |
262 LogSymbol(start, Vector<const char>(symbol, length)); | |
263 } | |
264 | |
265 virtual Vector<unsigned> ExtractData(); | |
266 | |
267 int symbol_position() { return symbol_store_.size(); } | |
268 int symbol_ids() { return symbol_id_; } | |
269 | |
270 private: | |
271 static int vector_hash(Vector<const char> string) { | |
272 int hash = 0; | |
273 for (int i = 0; i < string.length(); i++) { | |
274 int c = string[i]; | |
275 hash += c; | |
276 hash += (hash << 10); | |
277 hash ^= (hash >> 6); | |
278 } | |
279 return hash; | |
280 } | |
281 | |
282 static bool vector_compare(void* a, void* b) { | |
283 Vector<const char>* string1 = reinterpret_cast<Vector<const char>* >(a); | |
284 Vector<const char>* string2 = reinterpret_cast<Vector<const char>* >(b); | |
285 int length = string1->length(); | |
286 if (string2->length() != length) return false; | |
287 return memcmp(string1->start(), string2->start(), length) == 0; | |
288 } | |
289 | |
290 // Write a non-negative number to the symbol store. | |
291 void WriteNumber(int number); | |
292 | |
293 Collector<byte> symbol_store_; | |
294 Collector<Vector<const char> > symbol_entries_; | |
295 HashMap symbol_table_; | |
296 int symbol_id_; | |
297 }; | |
298 | |
299 | |
300 | |
301 class ParserApi { | 164 class ParserApi { |
302 public: | 165 public: |
303 // Parses the source code represented by the compilation info and sets its | 166 // Parses the source code represented by the compilation info and sets its |
304 // function literal. Returns false (and deallocates any allocated AST | 167 // function literal. Returns false (and deallocates any allocated AST |
305 // nodes) if parsing failed. | 168 // nodes) if parsing failed. |
306 static bool Parse(CompilationInfo* info); | 169 static bool Parse(CompilationInfo* info); |
307 | 170 |
308 // Generic preparser generating full preparse data. | 171 // Generic preparser generating full preparse data. |
309 static ScriptDataImpl* PreParse(Handle<String> source, | 172 static ScriptDataImpl* PreParse(Handle<String> source, |
310 unibrow::CharacterStream* stream, | 173 unibrow::CharacterStream* stream, |
(...skipping 541 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
852 // return a null handle. Primarily for readability. | 715 // return a null handle. Primarily for readability. |
853 Handle<Object> ReportUnexpectedToken() { return Handle<Object>::null(); } | 716 Handle<Object> ReportUnexpectedToken() { return Handle<Object>::null(); } |
854 // Converts the currently parsed literal to a JavaScript String. | 717 // Converts the currently parsed literal to a JavaScript String. |
855 Handle<String> GetString(); | 718 Handle<String> GetString(); |
856 | 719 |
857 JsonScanner scanner_; | 720 JsonScanner scanner_; |
858 }; | 721 }; |
859 } } // namespace v8::internal | 722 } } // namespace v8::internal |
860 | 723 |
861 #endif // V8_PARSER_H_ | 724 #endif // V8_PARSER_H_ |
OLD | NEW |