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 21 matching lines...) Expand all Loading... |
32 | 32 |
33 #include "../include/v8stdint.h" | 33 #include "../include/v8stdint.h" |
34 #include "../include/v8-preparser.h" | 34 #include "../include/v8-preparser.h" |
35 | 35 |
36 #include "../src/preparse-data-format.h" | 36 #include "../src/preparse-data-format.h" |
37 | 37 |
38 namespace i = v8::internal; | 38 namespace i = v8::internal; |
39 | 39 |
40 // This file is only used for testing the stand-alone preparser | 40 // This file is only used for testing the stand-alone preparser |
41 // library. | 41 // library. |
42 // The first argument must be the path of a JavaScript source file. | 42 // The first argument must be the path of a JavaScript source file, or |
| 43 // the flags "-e" and the next argument is then the source of a JavaScript |
| 44 // program. |
43 // Optionally this can be followed by the word "throws" (case sensitive), | 45 // Optionally this can be followed by the word "throws" (case sensitive), |
44 // which signals that the parsing is expected to throw - the default is | 46 // which signals that the parsing is expected to throw - the default is |
45 // to expect the parsing to not throw. | 47 // to expect the parsing to not throw. |
46 // The command line can further be followed by a message text (the | 48 // The command line can further be followed by a message text (the |
47 // *type* of the exception to throw), and even more optionally, the | 49 // *type* of the exception to throw), and even more optionally, the |
48 // start and end position reported with the exception. | 50 // start and end position reported with the exception. |
49 // | 51 // |
50 // This source file is preparsed and tested against the expectations, and if | 52 // This source file is preparsed and tested against the expectations, and if |
51 // successful, the resulting preparser data is written to stdout. | 53 // successful, the resulting preparser data is written to stdout. |
52 // Diagnostic output is output on stderr. | 54 // Diagnostic output is output on stderr. |
53 // The source file must contain only ASCII characters (UTF-8 isn't supported). | 55 // The source file must contain only ASCII characters (UTF-8 isn't supported). |
54 // The file is read into memory, so it should have a reasonable size. | 56 // The file is read into memory, so it should have a reasonable size. |
55 | 57 |
56 | 58 |
57 // Adapts an ASCII string to the UnicodeInputStream interface. | 59 // Adapts an ASCII string to the UnicodeInputStream interface. |
58 class AsciiInputStream : public v8::UnicodeInputStream { | 60 class AsciiInputStream : public v8::UnicodeInputStream { |
59 public: | 61 public: |
60 AsciiInputStream(uint8_t* buffer, size_t length) | 62 AsciiInputStream(const uint8_t* buffer, size_t length) |
61 : buffer_(buffer), | 63 : buffer_(buffer), |
62 end_offset_(static_cast<int>(length)), | 64 end_offset_(static_cast<int>(length)), |
63 offset_(0) { } | 65 offset_(0) { } |
64 | 66 |
65 virtual ~AsciiInputStream() { } | 67 virtual ~AsciiInputStream() { } |
66 | 68 |
67 virtual void PushBack(int32_t ch) { | 69 virtual void PushBack(int32_t ch) { |
68 offset_--; | 70 offset_--; |
69 #ifdef DEBUG | 71 #ifdef DEBUG |
70 if (offset_ < 0 || | 72 if (offset_ < 0 || |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
169 | 171 |
170 const uint8_t* const data_; | 172 const uint8_t* const data_; |
171 const int length_; | 173 const int length_; |
172 const char* message_; | 174 const char* message_; |
173 }; | 175 }; |
174 | 176 |
175 | 177 |
176 template <typename T> | 178 template <typename T> |
177 class ScopedPointer { | 179 class ScopedPointer { |
178 public: | 180 public: |
| 181 explicit ScopedPointer() : pointer_(NULL) {} |
179 explicit ScopedPointer(T* pointer) : pointer_(pointer) {} | 182 explicit ScopedPointer(T* pointer) : pointer_(pointer) {} |
180 ~ScopedPointer() { delete[] pointer_; } | 183 ~ScopedPointer() { if (pointer_ != NULL) delete[] pointer_; } |
181 T& operator[](int index) { return pointer_[index]; } | 184 T& operator[](int index) { return pointer_[index]; } |
182 T* operator*() { return pointer_ ;} | 185 T* operator*() { return pointer_ ;} |
| 186 T*& operator=(T* new_value) { |
| 187 if (pointer_ != NULL) delete[] pointer_; |
| 188 pointer_ = new_value; |
| 189 } |
183 private: | 190 private: |
184 T* pointer_; | 191 T* pointer_; |
185 }; | 192 }; |
186 | 193 |
187 | 194 |
188 | 195 |
189 void fail(v8::PreParserData* data, const char* message, ...) { | 196 void fail(v8::PreParserData* data, const char* message, ...) { |
190 va_list args; | 197 va_list args; |
191 va_start(args, message); | 198 va_start(args, message); |
192 vfprintf(stderr, message, args); | 199 vfprintf(stderr, message, args); |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
291 } | 298 } |
292 } | 299 } |
293 } | 300 } |
294 } | 301 } |
295 return expects; | 302 return expects; |
296 } | 303 } |
297 | 304 |
298 | 305 |
299 int main(int argc, const char* argv[]) { | 306 int main(int argc, const char* argv[]) { |
300 // Parse command line. | 307 // Parse command line. |
301 // Format: preparser <scriptfile> ["throws" [<exn-type> [<start> [<end>]]]] | 308 // Format: preparser (<scriptfile> | -e "<source>") |
302 // Any flags on the line are ignored. | 309 // ["throws" [<exn-type> [<start> [<end>]]]] |
| 310 // Any flags (except an initial -s) are ignored. |
303 | 311 |
304 // Check for mandatory filename argument. | 312 // Check for mandatory filename argument. |
305 int arg_index = 1; | 313 int arg_index = 1; |
306 while (argc > arg_index && IsFlag(argv[arg_index])) arg_index++; | |
307 if (argc <= arg_index) { | 314 if (argc <= arg_index) { |
308 fail(NULL, "ERROR: No filename on command line.\n"); | 315 fail(NULL, "ERROR: No filename on command line.\n"); |
309 } | 316 } |
| 317 const uint8_t* source = NULL; |
310 const char* filename = argv[arg_index]; | 318 const char* filename = argv[arg_index]; |
| 319 if (!strcmp(filename, "-e")) { |
| 320 arg_index++; |
| 321 if (argc <= arg_index) { |
| 322 fail(NULL, "ERROR: No source after -e on command line.\n"); |
| 323 } |
| 324 source = reinterpret_cast<const uint8_t*>(argv[arg_index]); |
| 325 } |
311 // Check remainder of command line for exception expectations. | 326 // Check remainder of command line for exception expectations. |
312 arg_index++; | 327 arg_index++; |
313 ExceptionExpectation expects = | 328 ExceptionExpectation expects = |
314 ParseExpectation(argc - arg_index, argv + arg_index); | 329 ParseExpectation(argc - arg_index, argv + arg_index); |
315 | 330 |
316 // Open JS file. | 331 ScopedPointer<uint8_t> buffer; |
317 FILE* input = fopen(filename, "rb"); | 332 size_t length; |
318 if (input == NULL) { | 333 |
319 perror("ERROR: Error opening file"); | 334 if (source == NULL) { |
320 fflush(stderr); | 335 // Open JS file. |
321 return EXIT_FAILURE; | 336 FILE* input = fopen(filename, "rb"); |
| 337 if (input == NULL) { |
| 338 perror("ERROR: Error opening file"); |
| 339 fflush(stderr); |
| 340 return EXIT_FAILURE; |
| 341 } |
| 342 // Find length of JS file. |
| 343 if (fseek(input, 0, SEEK_END) != 0) { |
| 344 perror("ERROR: Error during seek"); |
| 345 fflush(stderr); |
| 346 return EXIT_FAILURE; |
| 347 } |
| 348 length = static_cast<size_t>(ftell(input)); |
| 349 rewind(input); |
| 350 // Read JS file into memory buffer. |
| 351 buffer = new uint8_t[length]; |
| 352 if (!ReadBuffer(input, *buffer, length)) { |
| 353 perror("ERROR: Reading file"); |
| 354 fflush(stderr); |
| 355 return EXIT_FAILURE; |
| 356 } |
| 357 fclose(input); |
| 358 source = *buffer; |
| 359 } else { |
| 360 length = strlen(reinterpret_cast<const char*>(source)); |
322 } | 361 } |
323 | 362 |
324 // Find length of JS file. | |
325 if (fseek(input, 0, SEEK_END) != 0) { | |
326 perror("ERROR: Error during seek"); | |
327 fflush(stderr); | |
328 return EXIT_FAILURE; | |
329 } | |
330 size_t length = static_cast<size_t>(ftell(input)); | |
331 rewind(input); | |
332 | |
333 // Read JS file into memory buffer. | |
334 ScopedPointer<uint8_t> buffer(new uint8_t[length]); | |
335 if (!ReadBuffer(input, *buffer, length)) { | |
336 perror("ERROR: Reading file"); | |
337 fflush(stderr); | |
338 return EXIT_FAILURE; | |
339 } | |
340 fclose(input); | |
341 | |
342 // Preparse input file. | 363 // Preparse input file. |
343 AsciiInputStream input_buffer(*buffer, length); | 364 AsciiInputStream input_buffer(source, length); |
344 size_t kMaxStackSize = 64 * 1024 * sizeof(void*); // NOLINT | 365 size_t kMaxStackSize = 64 * 1024 * sizeof(void*); // NOLINT |
345 v8::PreParserData data = v8::Preparse(&input_buffer, kMaxStackSize); | 366 v8::PreParserData data = v8::Preparse(&input_buffer, kMaxStackSize); |
346 | 367 |
347 // Fail if stack overflow. | 368 // Fail if stack overflow. |
348 if (data.stack_overflow()) { | 369 if (data.stack_overflow()) { |
349 fail(&data, "ERROR: Stack overflow\n"); | 370 fail(&data, "ERROR: Stack overflow\n"); |
350 } | 371 } |
351 | 372 |
352 // Check that the expected exception is thrown, if an exception is | 373 // Check that the expected exception is thrown, if an exception is |
353 // expected. | 374 // expected. |
354 CheckException(&data, &expects); | 375 CheckException(&data, &expects); |
355 | 376 |
356 return EXIT_SUCCESS; | 377 return EXIT_SUCCESS; |
357 } | 378 } |
OLD | NEW |