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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « include/v8-profiler.h ('k') | samples/shell.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: preparser/preparser-process.cc
===================================================================
--- preparser/preparser-process.cc (revision 7948)
+++ preparser/preparser-process.cc (working copy)
@@ -1,4 +1,4 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -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 @@
}
+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,133 @@
};
-int main(int argc, char* argv[]) {
- // Check for filename argument.
- if (argc < 2) {
- fprintf(stderr, "ERROR: No filename on command line.\n");
+
+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);
- return EXIT_FAILURE;
}
- const char* filename = argv[1];
+ exit(EXIT_FAILURE);
+};
+
+bool IsFlag(const char* arg) {
+ // Anything starting with '-' is considered a flag.
+ // It's summarily ignored for now.
+ return arg[0] == '-';
+}
+
+
+struct ExceptionExpectation {
+ ExceptionExpectation()
+ : throws(false), type(NULL), beg_pos(-1), end_pos(-1) { }
+ bool throws;
+ const char* type;
+ int beg_pos;
+ int end_pos;
+};
+
+
+void CheckException(v8::PreParserData* data,
+ ExceptionExpectation* expects) {
+ PreparseDataInterpreter reader(data->data(), data->size());
+ if (expects->throws) {
+ if (!reader.throws()) {
+ if (expects->type == NULL) {
+ fail(data, "Didn't throw as expected\n");
+ } else {
+ fail(data, "Didn't throw \"%s\" as expected\n", expects->type);
+ }
+ }
+ if (expects->type != NULL) {
+ const char* actual_message = reader.message();
+ if (strcmp(expects->type, actual_message)) {
+ fail(data, "Wrong error message. Expected <%s>, found <%s>\n",
+ expects->type, actual_message);
+ }
+ }
+ if (expects->beg_pos >= 0) {
+ if (expects->beg_pos != reader.beg_pos()) {
+ fail(data, "Wrong error start position: Expected %i, found %i\n",
+ expects->beg_pos, reader.beg_pos());
+ }
+ }
+ if (expects->end_pos >= 0) {
+ if (expects->end_pos != reader.end_pos()) {
+ fail(data, "Wrong error end position: Expected %i, found %i\n",
+ expects->end_pos, reader.end_pos());
+ }
+ }
+ } else if (reader.throws()) {
+ const char* message = reader.message();
+ fail(data, "Throws unexpectedly with message: %s\n", message);
+ }
+}
+
+
+ExceptionExpectation ParseExpectation(int argc, const char* argv[]) {
+ ExceptionExpectation expects;
+
+ // Parse exception expectations from (the remainder of) the command line.
+ int arg_index = 0;
+ // Skip any flags.
+ while (argc > arg_index && IsFlag(argv[arg_index])) arg_index++;
+ if (argc > arg_index) {
+ if (strncmp("throws", argv[arg_index], 7)) {
+ // First argument after filename, if present, must be the verbatim
+ // "throws", marking that the preparsing should fail with an exception.
+ fail(NULL, "ERROR: Extra arguments not prefixed by \"throws\".\n");
+ }
+ expects.throws = true;
+ do {
+ arg_index++;
+ } while (argc > arg_index && IsFlag(argv[arg_index]));
+ if (argc > arg_index) {
+ // Next argument is the exception type identifier.
+ expects.type = argv[arg_index];
+ do {
+ arg_index++;
+ } while (argc > arg_index && IsFlag(argv[arg_index]));
+ if (argc > arg_index) {
+ expects.beg_pos = atoi(argv[arg_index]);
+ do {
+ arg_index++;
+ } while (argc > arg_index && IsFlag(argv[arg_index]));
+ if (argc > arg_index) {
+ expects.end_pos = atoi(argv[arg_index]);
+ }
+ }
+ }
+ }
+ return expects;
+}
+
+
+int main(int argc, const char* argv[]) {
+ // Parse command line.
+ // Format: preparser <scriptfile> ["throws" [<exn-type> [<start> [<end>]]]]
+ // Any flags on the line are ignored.
+
+ // Check for mandatory filename argument.
+ int arg_index = 1;
+ while (argc > arg_index && IsFlag(argv[arg_index])) arg_index++;
+ if (argc <= arg_index) {
+ fail(NULL, "ERROR: No filename on command line.\n");
+ }
+ const char* filename = argv[arg_index];
+ // Check remainder of command line for exception expectations.
+ arg_index++;
+ ExceptionExpectation expects =
+ ParseExpectation(argc - arg_index, argv + arg_index);
+
// Open JS file.
FILE* input = fopen(filename, "rb");
if (input == NULL) {
@@ -151,19 +345,12 @@
// 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, &expects);
return EXIT_SUCCESS;
}
« 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