Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(213)

Side by Side Diff: preparser/preparser-process.cc

Issue 7060010: Merge bleeding edge into the GC branch up to 7948. The asserts (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: Created 9 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « include/v8-profiler.h ('k') | samples/shell.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 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
11 // with the distribution. 11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its 12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived 13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission. 14 // from this software without specific prior written permission.
15 // 15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
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 #include <stdlib.h> 28 #include <stdlib.h>
29 #include <stdarg.h> 29 #include <stdarg.h>
30 #include <stdio.h> 30 #include <stdio.h>
31 #include <string.h>
31 32
32 #include "../include/v8stdint.h" 33 #include "../include/v8stdint.h"
33 #include "../include/v8-preparser.h" 34 #include "../include/v8-preparser.h"
34 35
36 #include "../src/preparse-data-format.h"
37
38 namespace i = v8::internal;
39
35 // This file is only used for testing the stand-alone preparser 40 // This file is only used for testing the stand-alone preparser
36 // library. 41 // library.
37 // The first (and only) argument must be the path of a JavaScript file. 42 // The first argument must be the path of a JavaScript source file.
38 // This file is preparsed and the resulting preparser data is written 43 // Optionally this can be followed by the word "throws" (case sensitive),
39 // to stdout. Diagnostic output is output on stderr. 44 // which signals that the parsing is expected to throw - the default is
40 // The file must contain only ASCII characters (UTF-8 isn't supported). 45 // to expect the parsing to not throw.
46 // The command line can further be followed by a message text (the
47 // *type* of the exception to throw), and even more optionally, the
48 // start and end position reported with the exception.
49 //
50 // This source file is preparsed and tested against the expectations, and if
51 // successful, the resulting preparser data is written to stdout.
52 // Diagnostic output is output on stderr.
53 // The source file must contain only ASCII characters (UTF-8 isn't supported).
41 // The file is read into memory, so it should have a reasonable size. 54 // The file is read into memory, so it should have a reasonable size.
42 55
43 56
44 // Adapts an ASCII string to the UnicodeInputStream interface. 57 // Adapts an ASCII string to the UnicodeInputStream interface.
45 class AsciiInputStream : public v8::UnicodeInputStream { 58 class AsciiInputStream : public v8::UnicodeInputStream {
46 public: 59 public:
47 AsciiInputStream(uint8_t* buffer, size_t length) 60 AsciiInputStream(uint8_t* buffer, size_t length)
48 : buffer_(buffer), 61 : buffer_(buffer),
49 end_offset_(static_cast<int>(length)), 62 end_offset_(static_cast<int>(length)),
50 offset_(0) { } 63 offset_(0) { }
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 return (actually_read == length); 103 return (actually_read == length);
91 } 104 }
92 105
93 106
94 bool WriteBuffer(FILE* dest, const void* buffer, size_t length) { 107 bool WriteBuffer(FILE* dest, const void* buffer, size_t length) {
95 size_t actually_written = fwrite(buffer, 1, length, dest); 108 size_t actually_written = fwrite(buffer, 1, length, dest);
96 return (actually_written == length); 109 return (actually_written == length);
97 } 110 }
98 111
99 112
113 class PreparseDataInterpreter {
114 public:
115 PreparseDataInterpreter(const uint8_t* data, int length)
116 : data_(data), length_(length), message_(NULL) { }
117
118 ~PreparseDataInterpreter() {
119 if (message_ != NULL) delete[] message_;
120 }
121
122 bool valid() {
123 int header_length =
124 i::PreparseDataConstants::kHeaderSize * sizeof(int); // NOLINT
125 return length_ >= header_length;
126 }
127
128 bool throws() {
129 return valid() &&
130 word(i::PreparseDataConstants::kHasErrorOffset) != 0;
131 }
132
133 const char* message() {
134 if (message_ != NULL) return message_;
135 if (!throws()) return NULL;
136 int text_pos = i::PreparseDataConstants::kHeaderSize +
137 i::PreparseDataConstants::kMessageTextPos;
138 int length = word(text_pos);
139 char* buffer = new char[length + 1];
140 for (int i = 1; i <= length; i++) {
141 int character = word(text_pos + i);
142 buffer[i - 1] = character;
143 }
144 buffer[length] = '\0';
145 message_ = buffer;
146 return buffer;
147 }
148
149 int beg_pos() {
150 if (!throws()) return -1;
151 return word(i::PreparseDataConstants::kHeaderSize +
152 i::PreparseDataConstants::kMessageStartPos);
153 }
154
155 int end_pos() {
156 if (!throws()) return -1;
157 return word(i::PreparseDataConstants::kHeaderSize +
158 i::PreparseDataConstants::kMessageEndPos);
159 }
160
161 private:
162 int word(int offset) {
163 const int* word_data = reinterpret_cast<const int*>(data_);
164 if (word_data + offset < reinterpret_cast<const int*>(data_ + length_)) {
165 return word_data[offset];
166 }
167 return -1;
168 }
169
170 const uint8_t* const data_;
171 const int length_;
172 const char* message_;
173 };
174
175
100 template <typename T> 176 template <typename T>
101 class ScopedPointer { 177 class ScopedPointer {
102 public: 178 public:
103 explicit ScopedPointer(T* pointer) : pointer_(pointer) {} 179 explicit ScopedPointer(T* pointer) : pointer_(pointer) {}
104 ~ScopedPointer() { delete[] pointer_; } 180 ~ScopedPointer() { delete[] pointer_; }
105 T& operator[](int index) { return pointer_[index]; } 181 T& operator[](int index) { return pointer_[index]; }
106 T* operator*() { return pointer_ ;} 182 T* operator*() { return pointer_ ;}
107 private: 183 private:
108 T* pointer_; 184 T* pointer_;
109 }; 185 };
110 186
111 187
112 int main(int argc, char* argv[]) { 188
113 // Check for filename argument. 189 void fail(v8::PreParserData* data, const char* message, ...) {
114 if (argc < 2) { 190 va_list args;
115 fprintf(stderr, "ERROR: No filename on command line.\n"); 191 va_start(args, message);
192 vfprintf(stderr, message, args);
193 va_end(args);
194 fflush(stderr);
195 // Print preparser data to stdout.
196 uint32_t size = data->size();
197 fprintf(stderr, "LOG: data size: %u\n", size);
198 if (!WriteBuffer(stdout, data->data(), size)) {
199 perror("ERROR: Writing data");
116 fflush(stderr); 200 fflush(stderr);
117 return EXIT_FAILURE;
118 } 201 }
119 const char* filename = argv[1]; 202 exit(EXIT_FAILURE);
203 };
204
205
206 bool IsFlag(const char* arg) {
207 // Anything starting with '-' is considered a flag.
208 // It's summarily ignored for now.
209 return arg[0] == '-';
210 }
211
212
213 struct ExceptionExpectation {
214 ExceptionExpectation()
215 : throws(false), type(NULL), beg_pos(-1), end_pos(-1) { }
216 bool throws;
217 const char* type;
218 int beg_pos;
219 int end_pos;
220 };
221
222
223 void CheckException(v8::PreParserData* data,
224 ExceptionExpectation* expects) {
225 PreparseDataInterpreter reader(data->data(), data->size());
226 if (expects->throws) {
227 if (!reader.throws()) {
228 if (expects->type == NULL) {
229 fail(data, "Didn't throw as expected\n");
230 } else {
231 fail(data, "Didn't throw \"%s\" as expected\n", expects->type);
232 }
233 }
234 if (expects->type != NULL) {
235 const char* actual_message = reader.message();
236 if (strcmp(expects->type, actual_message)) {
237 fail(data, "Wrong error message. Expected <%s>, found <%s>\n",
238 expects->type, actual_message);
239 }
240 }
241 if (expects->beg_pos >= 0) {
242 if (expects->beg_pos != reader.beg_pos()) {
243 fail(data, "Wrong error start position: Expected %i, found %i\n",
244 expects->beg_pos, reader.beg_pos());
245 }
246 }
247 if (expects->end_pos >= 0) {
248 if (expects->end_pos != reader.end_pos()) {
249 fail(data, "Wrong error end position: Expected %i, found %i\n",
250 expects->end_pos, reader.end_pos());
251 }
252 }
253 } else if (reader.throws()) {
254 const char* message = reader.message();
255 fail(data, "Throws unexpectedly with message: %s\n", message);
256 }
257 }
258
259
260 ExceptionExpectation ParseExpectation(int argc, const char* argv[]) {
261 ExceptionExpectation expects;
262
263 // Parse exception expectations from (the remainder of) the command line.
264 int arg_index = 0;
265 // Skip any flags.
266 while (argc > arg_index && IsFlag(argv[arg_index])) arg_index++;
267 if (argc > arg_index) {
268 if (strncmp("throws", argv[arg_index], 7)) {
269 // First argument after filename, if present, must be the verbatim
270 // "throws", marking that the preparsing should fail with an exception.
271 fail(NULL, "ERROR: Extra arguments not prefixed by \"throws\".\n");
272 }
273 expects.throws = true;
274 do {
275 arg_index++;
276 } while (argc > arg_index && IsFlag(argv[arg_index]));
277 if (argc > arg_index) {
278 // Next argument is the exception type identifier.
279 expects.type = argv[arg_index];
280 do {
281 arg_index++;
282 } while (argc > arg_index && IsFlag(argv[arg_index]));
283 if (argc > arg_index) {
284 expects.beg_pos = atoi(argv[arg_index]);
285 do {
286 arg_index++;
287 } while (argc > arg_index && IsFlag(argv[arg_index]));
288 if (argc > arg_index) {
289 expects.end_pos = atoi(argv[arg_index]);
290 }
291 }
292 }
293 }
294 return expects;
295 }
296
297
298 int main(int argc, const char* argv[]) {
299 // Parse command line.
300 // Format: preparser <scriptfile> ["throws" [<exn-type> [<start> [<end>]]]]
301 // Any flags on the line are ignored.
302
303 // Check for mandatory filename argument.
304 int arg_index = 1;
305 while (argc > arg_index && IsFlag(argv[arg_index])) arg_index++;
306 if (argc <= arg_index) {
307 fail(NULL, "ERROR: No filename on command line.\n");
308 }
309 const char* filename = argv[arg_index];
310 // Check remainder of command line for exception expectations.
311 arg_index++;
312 ExceptionExpectation expects =
313 ParseExpectation(argc - arg_index, argv + arg_index);
120 314
121 // Open JS file. 315 // Open JS file.
122 FILE* input = fopen(filename, "rb"); 316 FILE* input = fopen(filename, "rb");
123 if (input == NULL) { 317 if (input == NULL) {
124 perror("ERROR: Error opening file"); 318 perror("ERROR: Error opening file");
125 fflush(stderr); 319 fflush(stderr);
126 return EXIT_FAILURE; 320 return EXIT_FAILURE;
127 } 321 }
128 322
129 // Find length of JS file. 323 // Find length of JS file.
(...skipping 14 matching lines...) Expand all
144 } 338 }
145 fclose(input); 339 fclose(input);
146 340
147 // Preparse input file. 341 // Preparse input file.
148 AsciiInputStream input_buffer(*buffer, length); 342 AsciiInputStream input_buffer(*buffer, length);
149 size_t kMaxStackSize = 64 * 1024 * sizeof(void*); // NOLINT 343 size_t kMaxStackSize = 64 * 1024 * sizeof(void*); // NOLINT
150 v8::PreParserData data = v8::Preparse(&input_buffer, kMaxStackSize); 344 v8::PreParserData data = v8::Preparse(&input_buffer, kMaxStackSize);
151 345
152 // Fail if stack overflow. 346 // Fail if stack overflow.
153 if (data.stack_overflow()) { 347 if (data.stack_overflow()) {
154 fprintf(stderr, "ERROR: Stack overflow\n"); 348 fail(&data, "ERROR: Stack overflow\n");
155 fflush(stderr);
156 return EXIT_FAILURE;
157 } 349 }
158 350
159 // Print preparser data to stdout. 351 // Check that the expected exception is thrown, if an exception is
160 uint32_t size = data.size(); 352 // expected.
161 fprintf(stderr, "LOG: Success, data size: %u\n", size); 353 CheckException(&data, &expects);
162 fflush(stderr);
163 if (!WriteBuffer(stdout, data.data(), size)) {
164 perror("ERROR: Writing data");
165 return EXIT_FAILURE;
166 }
167 354
168 return EXIT_SUCCESS; 355 return EXIT_SUCCESS;
169 } 356 }
OLDNEW
« no previous file with comments | « include/v8-profiler.h ('k') | samples/shell.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698