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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « include/v8-preparser.h ('k') | src/parser.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: preparser/preparser-process.cc
diff --git a/preparser/preparser-process.cc b/preparser/preparser-process.cc
index fb6e38660aba998c2f89e1eb6cbeb8a7aba214ac..486094617987be22b496fdce351038d53db9ea77 100644
--- a/preparser/preparser-process.cc
+++ b/preparser/preparser-process.cc
@@ -28,16 +28,29 @@
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
+#include <string.h>
#include "../include/v8stdint.h"
#include "../include/v8-preparser.h"
+#include "../src/preparse-data-format.h"
+
+namespace i = v8::internal;
+
// This file is only used for testing the stand-alone preparser
// library.
-// The first (and only) argument must be the path of a JavaScript file.
-// This file is preparsed and the resulting preparser data is written
-// to stdout. Diagnostic output is output on stderr.
-// The file must contain only ASCII characters (UTF-8 isn't supported).
+// The first argument must be the path of a JavaScript source file.
+// Optionally this can be followed by the word "throws" (case sensitive),
+// which signals that the parsing is expected to throw - the default is
+// to expect the parsing to not throw.
+// The command line can further be followed by a message text (the
+// *type* of the exception to throw), and even more optionally, the
+// start and end position reported with the exception.
+//
+// This source file is preparsed and tested against the expectations, and if
+// successful, the resulting preparser data is written to stdout.
+// Diagnostic output is output on stderr.
+// The source file must contain only ASCII characters (UTF-8 isn't supported).
// The file is read into memory, so it should have a reasonable size.
@@ -97,6 +110,69 @@ bool WriteBuffer(FILE* dest, const void* buffer, size_t length) {
}
+class PreparseDataInterpreter {
+ public:
+ PreparseDataInterpreter(const uint8_t* data, int length)
+ : data_(data), length_(length), message_(NULL) { }
+
+ ~PreparseDataInterpreter() {
+ if (message_ != NULL) delete[] message_;
+ }
+
+ bool valid() {
+ int header_length =
+ i::PreparseDataConstants::kHeaderSize * sizeof(int); // NOLINT
+ return length_ >= header_length;
+ }
+
+ bool throws() {
+ return valid() &&
+ word(i::PreparseDataConstants::kHasErrorOffset) != 0;
+ }
+
+ const char* message() {
+ if (message_ != NULL) return message_;
+ if (!throws()) return NULL;
+ int text_pos = i::PreparseDataConstants::kHeaderSize +
+ i::PreparseDataConstants::kMessageTextPos;
+ int length = word(text_pos);
+ char* buffer = new char[length + 1];
+ for (int i = 1; i <= length; i++) {
+ int character = word(text_pos + i);
+ buffer[i - 1] = character;
+ }
+ buffer[length] = '\0';
+ message_ = buffer;
+ return buffer;
+ }
+
+ int beg_pos() {
+ if (!throws()) return -1;
+ return word(i::PreparseDataConstants::kHeaderSize +
+ i::PreparseDataConstants::kMessageStartPos);
+ }
+
+ int end_pos() {
+ if (!throws()) return -1;
+ return word(i::PreparseDataConstants::kHeaderSize +
+ i::PreparseDataConstants::kMessageEndPos);
+ }
+
+ private:
+ int word(int offset) {
+ const int* word_data = reinterpret_cast<const int*>(data_);
+ if (word_data + offset < reinterpret_cast<const int*>(data_ + length_)) {
+ return word_data[offset];
+ }
+ return -1;
+ }
+
+ const uint8_t* const data_;
+ const int length_;
+ const char* message_;
+};
+
+
template <typename T>
class ScopedPointer {
public:
@@ -109,15 +185,93 @@ class ScopedPointer {
};
+
+void fail(v8::PreParserData* data, const char* message, ...) {
+ va_list args;
+ va_start(args, message);
+ vfprintf(stderr, message, args);
+ va_end(args);
+ fflush(stderr);
+ // Print preparser data to stdout.
+ uint32_t size = data->size();
+ fprintf(stderr, "LOG: data size: %u\n", size);
+ if (!WriteBuffer(stdout, data->data(), size)) {
+ perror("ERROR: Writing data");
+ fflush(stderr);
+ }
+ exit(EXIT_FAILURE);
+};
+
+
+void CheckException(v8::PreParserData* data,
+ bool throws,
+ const char* message,
+ int beg_pos,
+ int end_pos) {
+ PreparseDataInterpreter reader(data->data(), data->size());
+ if (throws) {
+ if (!reader.throws()) {
+ if (message == NULL) {
+ fail(data, "Didn't throw as expected\n");
+ } else {
+ fail(data, "Didn't throw \"%s\" as expected\n", message);
+ }
+ }
+ if (message != NULL) {
+ const char* actual_message = reader.message();
+ if (strcmp(message, actual_message)) {
+ fail(data, "Wrong error message. Expected <%s>, found <%s>\n",
+ message, actual_message);
+ }
+ }
+ if (beg_pos >= 0) {
+ if (beg_pos != reader.beg_pos()) {
+ fail(data, "Wrong error start position: Expected %i, found %i\n",
+ beg_pos, reader.beg_pos());
+ }
+ }
+ if (end_pos >= 0) {
+ if (end_pos != reader.end_pos()) {
+ fail(data, "Wrong error end position: Expected %i, found %i\n",
+ end_pos, reader.end_pos());
+ }
+ }
+ } else if (reader.throws()) {
+ const char* message = reader.message();
+ fail(data, "Throws unexpectedly with message: %s\n",
+ message);
+ }
+}
+
int main(int argc, char* argv[]) {
// Check for filename argument.
if (argc < 2) {
- fprintf(stderr, "ERROR: No filename on command line.\n");
- fflush(stderr);
- return EXIT_FAILURE;
+ fail(NULL, "ERROR: No filename on command line.\n");
}
const char* filename = argv[1];
+ // Parse expectations.
+ bool throws = false;
+ const char* throws_message = NULL;
+ int throws_beg_pos = -1;
+ int throws_end_pos = -1;
+ // Check for throws argument.
+ if (argc > 2) {
+ if (strncmp("throws", argv[2], 6)) {
+ fail(NULL, "ERROR: Extra arguments not prefixed by \"throws\".\n");
+ }
+ throws = true;
+ if (argc > 3) {
+ throws_message = argv[3];
+ }
+ if (argc > 4) {
+ throws_beg_pos = atoi(argv[4]);
+ }
+ if (argc > 5) {
+ throws_end_pos = atoi(argv[5]);
+ }
+ }
+
// Open JS file.
FILE* input = fopen(filename, "rb");
if (input == NULL) {
@@ -151,19 +305,13 @@ int main(int argc, char* argv[]) {
// Fail if stack overflow.
if (data.stack_overflow()) {
- fprintf(stderr, "ERROR: Stack overflow\n");
- fflush(stderr);
- return EXIT_FAILURE;
+ fail(&data, "ERROR: Stack overflow\n");
}
- // Print preparser data to stdout.
- uint32_t size = data.size();
- fprintf(stderr, "LOG: Success, data size: %u\n", size);
- fflush(stderr);
- if (!WriteBuffer(stdout, data.data(), size)) {
- perror("ERROR: Writing data");
- return EXIT_FAILURE;
- }
+ // Check that the expected exception is thrown, if an exception is
+ // expected.
+ CheckException(&data, throws, throws_message,
+ throws_beg_pos, throws_end_pos);
return EXIT_SUCCESS;
}
« 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