summaryrefslogtreecommitdiffstats
path: root/preparser
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2011-06-08 16:22:53 +0100
committerBen Murdoch <benm@google.com>2011-06-08 16:56:58 +0100
commit8b112d2025046f85ef7f6be087c6129c872ebad2 (patch)
treea52884866a47449a8037fc3a960fb5a1ba665ceb /preparser
parent7eeff62978ae0a77c5a22455e231e22c10a89958 (diff)
downloadandroid_external_v8-8b112d2025046f85ef7f6be087c6129c872ebad2.tar.gz
android_external_v8-8b112d2025046f85ef7f6be087c6129c872ebad2.tar.bz2
android_external_v8-8b112d2025046f85ef7f6be087c6129c872ebad2.zip
Merge V8 at r7668: Initial merge by Git.
Change-Id: I1703c8b4f5c63052451a22cf3fb878abc9a0ec75
Diffstat (limited to 'preparser')
-rw-r--r--preparser/preparser-process.cc191
1 files changed, 77 insertions, 114 deletions
diff --git a/preparser/preparser-process.cc b/preparser/preparser-process.cc
index 26dfc42b..fb6e3866 100644
--- a/preparser/preparser-process.cc
+++ b/preparser/preparser-process.cc
@@ -27,105 +27,64 @@
#include <stdlib.h>
#include <stdarg.h>
+#include <stdio.h>
+
#include "../include/v8stdint.h"
#include "../include/v8-preparser.h"
-#include "unicode-inl.h"
-
-enum ResultCode { kSuccess = 0, kErrorReading = 1, kErrorWriting = 2 };
-
-namespace v8 {
-namespace internal {
-// THIS FILE IS PROOF-OF-CONCEPT ONLY.
-// The final goal is a stand-alone preparser library.
+// 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 file is read into memory, so it should have a reasonable size.
-class UTF8InputStream : public v8::UnicodeInputStream {
+// Adapts an ASCII string to the UnicodeInputStream interface.
+class AsciiInputStream : public v8::UnicodeInputStream {
public:
- UTF8InputStream(uint8_t* buffer, size_t length)
+ AsciiInputStream(uint8_t* buffer, size_t length)
: buffer_(buffer),
- offset_(0),
- pos_(0),
- end_offset_(static_cast<int>(length)) { }
+ end_offset_(static_cast<int>(length)),
+ offset_(0) { }
- virtual ~UTF8InputStream() { }
+ virtual ~AsciiInputStream() { }
virtual void PushBack(int32_t ch) {
- // Pushback assumes that the character pushed back is the
- // one that was most recently read, and jumps back in the
- // UTF-8 stream by the length of that character's encoding.
- offset_ -= unibrow::Utf8::Length(ch);
- pos_--;
+ offset_--;
#ifdef DEBUG
- if (static_cast<unsigned>(ch) <= unibrow::Utf8::kMaxOneByteChar) {
- if (ch != buffer_[offset_]) {
- fprintf(stderr, "Invalid pushback: '%c'.", ch);
- exit(1);
- }
- } else {
- unsigned tmp = 0;
- if (static_cast<unibrow::uchar>(ch) !=
- unibrow::Utf8::CalculateValue(buffer_ + offset_,
- end_offset_ - offset_,
- &tmp)) {
- fprintf(stderr, "Invalid pushback: 0x%x.", ch);
- exit(1);
- }
+ if (offset_ < 0 ||
+ (ch != ((offset_ >= end_offset_) ? -1 : buffer_[offset_]))) {
+ fprintf(stderr, "Invalid pushback: '%c' at offset %d.", ch, offset_);
+ exit(1);
}
#endif
}
virtual int32_t Next() {
- if (offset_ == end_offset_) return -1;
- uint8_t first_char = buffer_[offset_];
- if (first_char <= unibrow::Utf8::kMaxOneByteChar) {
- pos_++;
- offset_++;
- return static_cast<int32_t>(first_char);
+ if (offset_ >= end_offset_) {
+ offset_++; // Increment anyway to allow symmetric pushbacks.
+ return -1;
+ }
+ uint8_t next_char = buffer_[offset_];
+#ifdef DEBUG
+ if (next_char > 0x7fu) {
+ fprintf(stderr, "Non-ASCII character in input: '%c'.", next_char);
+ exit(1);
}
- unibrow::uchar codepoint =
- unibrow::Utf8::CalculateValue(buffer_ + offset_,
- end_offset_ - offset_,
- &offset_);
- pos_++;
- return static_cast<int32_t>(codepoint);
+#endif
+ offset_++;
+ return static_cast<int32_t>(next_char);
}
private:
const uint8_t* buffer_;
- unsigned offset_;
- unsigned pos_;
- unsigned end_offset_;
+ const int end_offset_;
+ int offset_;
};
-// Write a number to dest in network byte order.
-void WriteUInt32(FILE* dest, uint32_t value, bool* ok) {
- for (int i = 3; i >= 0; i--) {
- uint8_t byte = static_cast<uint8_t>(value >> (i << 3));
- int result = fputc(byte, dest);
- if (result == EOF) {
- *ok = false;
- return;
- }
- }
-}
-
-// Read number from FILE* in network byte order.
-uint32_t ReadUInt32(FILE* source, bool* ok) {
- uint32_t n = 0;
- for (int i = 0; i < 4; i++) {
- int c = fgetc(source);
- if (c == EOF) {
- *ok = false;
- return 0;
- }
- n = (n << 8) + static_cast<uint32_t>(c);
- }
- return n;
-}
-
-
bool ReadBuffer(FILE* source, void* buffer, size_t length) {
size_t actually_read = fread(buffer, 1, length, source);
return (actually_read == length);
@@ -150,57 +109,61 @@ class ScopedPointer {
};
-// Preparse input and output result on stdout.
-int PreParseIO(FILE* input) {
- fprintf(stderr, "LOG: Enter parsing loop\n");
- bool ok = true;
- uint32_t length = ReadUInt32(input, &ok);
- fprintf(stderr, "LOG: Input length: %d\n", length);
- if (!ok) return kErrorReading;
- ScopedPointer<uint8_t> buffer(new uint8_t[length]);
+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;
+ }
+ const char* filename = argv[1];
+
+ // Open JS file.
+ FILE* input = fopen(filename, "rb");
+ if (input == NULL) {
+ perror("ERROR: Error opening file");
+ fflush(stderr);
+ return EXIT_FAILURE;
+ }
+ // Find length of JS file.
+ if (fseek(input, 0, SEEK_END) != 0) {
+ perror("ERROR: Error during seek");
+ fflush(stderr);
+ return EXIT_FAILURE;
+ }
+ size_t length = static_cast<size_t>(ftell(input));
+ rewind(input);
+
+ // Read JS file into memory buffer.
+ ScopedPointer<uint8_t> buffer(new uint8_t[length]);
if (!ReadBuffer(input, *buffer, length)) {
- return kErrorReading;
+ perror("ERROR: Reading file");
+ fflush(stderr);
+ return EXIT_FAILURE;
}
- UTF8InputStream input_buffer(*buffer, static_cast<size_t>(length));
+ fclose(input);
+
+ // Preparse input file.
+ AsciiInputStream input_buffer(*buffer, length);
+ size_t kMaxStackSize = 64 * 1024 * sizeof(void*); // NOLINT
+ v8::PreParserData data = v8::Preparse(&input_buffer, kMaxStackSize);
- v8::PreParserData data =
- v8::Preparse(&input_buffer, 64 * 1024 * sizeof(void*)); // NOLINT
+ // Fail if stack overflow.
if (data.stack_overflow()) {
- fprintf(stderr, "LOG: Stack overflow\n");
+ fprintf(stderr, "ERROR: Stack overflow\n");
fflush(stderr);
- // Report stack overflow error/no-preparser-data.
- WriteUInt32(stdout, 0, &ok);
- if (!ok) return kErrorWriting;
- return 0;
+ return EXIT_FAILURE;
}
+ // Print preparser data to stdout.
uint32_t size = data.size();
fprintf(stderr, "LOG: Success, data size: %u\n", size);
fflush(stderr);
- WriteUInt32(stdout, size, &ok);
- if (!ok) return kErrorWriting;
if (!WriteBuffer(stdout, data.data(), size)) {
- return kErrorWriting;
+ perror("ERROR: Writing data");
+ return EXIT_FAILURE;
}
- return 0;
-}
-
-} } // namespace v8::internal
-
-int main(int argc, char* argv[]) {
- FILE* input = stdin;
- if (argc > 1) {
- char* arg = argv[1];
- input = fopen(arg, "rb");
- if (input == NULL) return EXIT_FAILURE;
- }
- int status = 0;
- do {
- status = v8::internal::PreParseIO(input);
- } while (status == 0);
- fprintf(stderr, "EXIT: Failure %d\n", status);
- fflush(stderr);
- return EXIT_FAILURE;
+ return EXIT_SUCCESS;
}