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

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

Issue 6927075: Strict mode detection in preparser. (Closed)
Patch Set: Added TODO with bugnumber for R 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
« no previous file with comments | « include/v8-preparser.h ('k') | src/parser.h » ('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 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 10 matching lines...) Expand all
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
188
189 void fail(v8::PreParserData* data, const char* message, ...) {
190 va_list args;
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");
200 fflush(stderr);
201 }
202 exit(EXIT_FAILURE);
203 };
204
205
206 void CheckException(v8::PreParserData* data,
207 bool throws,
208 const char* message,
209 int beg_pos,
210 int end_pos) {
211 PreparseDataInterpreter reader(data->data(), data->size());
212 if (throws) {
213 if (!reader.throws()) {
214 if (message == NULL) {
215 fail(data, "Didn't throw as expected\n");
216 } else {
217 fail(data, "Didn't throw \"%s\" as expected\n", message);
218 }
219 }
220 if (message != NULL) {
221 const char* actual_message = reader.message();
222 if (strcmp(message, actual_message)) {
223 fail(data, "Wrong error message. Expected <%s>, found <%s>\n",
224 message, actual_message);
225 }
226 }
227 if (beg_pos >= 0) {
228 if (beg_pos != reader.beg_pos()) {
229 fail(data, "Wrong error start position: Expected %i, found %i\n",
230 beg_pos, reader.beg_pos());
231 }
232 }
233 if (end_pos >= 0) {
234 if (end_pos != reader.end_pos()) {
235 fail(data, "Wrong error end position: Expected %i, found %i\n",
236 end_pos, reader.end_pos());
237 }
238 }
239 } else if (reader.throws()) {
240 const char* message = reader.message();
241 fail(data, "Throws unexpectedly with message: %s\n",
242 message);
243 }
244 }
245
112 int main(int argc, char* argv[]) { 246 int main(int argc, char* argv[]) {
113 // Check for filename argument. 247 // Check for filename argument.
114 if (argc < 2) { 248 if (argc < 2) {
115 fprintf(stderr, "ERROR: No filename on command line.\n"); 249 fail(NULL, "ERROR: No filename on command line.\n");
116 fflush(stderr);
117 return EXIT_FAILURE;
118 } 250 }
119 const char* filename = argv[1]; 251 const char* filename = argv[1];
120 252
253 // Parse expectations.
254 bool throws = false;
255 const char* throws_message = NULL;
256 int throws_beg_pos = -1;
257 int throws_end_pos = -1;
258 // Check for throws argument.
259 if (argc > 2) {
260 if (strncmp("throws", argv[2], 6)) {
261 fail(NULL, "ERROR: Extra arguments not prefixed by \"throws\".\n");
262 }
263 throws = true;
264 if (argc > 3) {
265 throws_message = argv[3];
266 }
267 if (argc > 4) {
268 throws_beg_pos = atoi(argv[4]);
269 }
270 if (argc > 5) {
271 throws_end_pos = atoi(argv[5]);
272 }
273 }
274
121 // Open JS file. 275 // Open JS file.
122 FILE* input = fopen(filename, "rb"); 276 FILE* input = fopen(filename, "rb");
123 if (input == NULL) { 277 if (input == NULL) {
124 perror("ERROR: Error opening file"); 278 perror("ERROR: Error opening file");
125 fflush(stderr); 279 fflush(stderr);
126 return EXIT_FAILURE; 280 return EXIT_FAILURE;
127 } 281 }
128 282
129 // Find length of JS file. 283 // Find length of JS file.
130 if (fseek(input, 0, SEEK_END) != 0) { 284 if (fseek(input, 0, SEEK_END) != 0) {
(...skipping 13 matching lines...) Expand all
144 } 298 }
145 fclose(input); 299 fclose(input);
146 300
147 // Preparse input file. 301 // Preparse input file.
148 AsciiInputStream input_buffer(*buffer, length); 302 AsciiInputStream input_buffer(*buffer, length);
149 size_t kMaxStackSize = 64 * 1024 * sizeof(void*); // NOLINT 303 size_t kMaxStackSize = 64 * 1024 * sizeof(void*); // NOLINT
150 v8::PreParserData data = v8::Preparse(&input_buffer, kMaxStackSize); 304 v8::PreParserData data = v8::Preparse(&input_buffer, kMaxStackSize);
151 305
152 // Fail if stack overflow. 306 // Fail if stack overflow.
153 if (data.stack_overflow()) { 307 if (data.stack_overflow()) {
154 fprintf(stderr, "ERROR: Stack overflow\n"); 308 fail(&data, "ERROR: Stack overflow\n");
155 fflush(stderr);
156 return EXIT_FAILURE;
157 } 309 }
158 310
159 // Print preparser data to stdout. 311 // Check that the expected exception is thrown, if an exception is
160 uint32_t size = data.size(); 312 // expected.
161 fprintf(stderr, "LOG: Success, data size: %u\n", size); 313 CheckException(&data, throws, throws_message,
162 fflush(stderr); 314 throws_beg_pos, throws_end_pos);
163 if (!WriteBuffer(stdout, data.data(), size)) {
164 perror("ERROR: Writing data");
165 return EXIT_FAILURE;
166 }
167 315
168 return EXIT_SUCCESS; 316 return EXIT_SUCCESS;
169 } 317 }
OLDNEW
« no previous file with comments | « include/v8-preparser.h ('k') | src/parser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698