mirror of https://github.com/lukechilds/node.git
Ryan Dahl
14 years ago
68 changed files with 2767 additions and 1756 deletions
@ -0,0 +1,227 @@ |
|||||
|
// Copyright 2010 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:
|
||||
|
//
|
||||
|
// * Redistributions of source code must retain the above copyright
|
||||
|
// notice, this list of conditions and the following disclaimer.
|
||||
|
// * Redistributions in binary form must reproduce the above
|
||||
|
// copyright notice, this list of conditions and the following
|
||||
|
// disclaimer in the documentation and/or other materials provided
|
||||
|
// with the distribution.
|
||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||
|
// contributors may be used to endorse or promote products derived
|
||||
|
// from this software without specific prior written permission.
|
||||
|
//
|
||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
|
||||
|
#include <stdarg.h> |
||||
|
#include "../include/v8stdint.h" |
||||
|
#include "globals.h" |
||||
|
#include "checks.h" |
||||
|
#include "allocation.h" |
||||
|
#include "utils.h" |
||||
|
#include "list.h" |
||||
|
#include "smart-pointer.h" |
||||
|
#include "scanner-base.h" |
||||
|
#include "preparse-data.h" |
||||
|
#include "preparser.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.
|
||||
|
|
||||
|
// UTF16Buffer based on an UTF-8 string in memory.
|
||||
|
class UTF8UTF16Buffer : public UTF16Buffer { |
||||
|
public: |
||||
|
UTF8UTF16Buffer(uint8_t* buffer, size_t length) |
||||
|
: UTF16Buffer(), |
||||
|
buffer_(buffer), |
||||
|
offset_(0), |
||||
|
end_offset_(static_cast<int>(length)) { } |
||||
|
|
||||
|
virtual void PushBack(uc32 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_--; |
||||
|
#ifdef DEBUG |
||||
|
int tmp = 0; |
||||
|
ASSERT_EQ(ch, unibrow::Utf8::ValueOf(buffer_ + offset_, |
||||
|
end_offset_ - offset_, |
||||
|
&tmp); |
||||
|
#endif |
||||
|
} |
||||
|
|
||||
|
virtual uc32 Advance() { |
||||
|
if (offset_ == end_offset_) return -1; |
||||
|
uint8_t first_char = buffer_[offset_]; |
||||
|
if (first_char <= unibrow::Utf8::kMaxOneByteChar) { |
||||
|
pos_++; |
||||
|
offset_++; |
||||
|
return static_cast<uc32>(first_char); |
||||
|
} |
||||
|
unibrow::uchar codepoint = |
||||
|
unibrow::Utf8::CalculateValue(buffer_ + offset_, |
||||
|
end_offset_ - offset_, |
||||
|
&offset_); |
||||
|
pos_++; |
||||
|
return static_cast<uc32>(codepoint); |
||||
|
} |
||||
|
|
||||
|
virtual void SeekForward(int pos) { |
||||
|
while (pos_ < pos) { |
||||
|
uint8_t first_byte = buffer_[offset_++]; |
||||
|
while (first_byte & 0x80u && offset_ < end_offset_) { |
||||
|
offset_++; |
||||
|
first_byte <<= 1; |
||||
|
} |
||||
|
pos_++; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private: |
||||
|
const uint8_t* buffer_; |
||||
|
unsigned offset_; |
||||
|
unsigned end_offset_; |
||||
|
}; |
||||
|
|
||||
|
|
||||
|
class StandAloneJavaScriptScanner : public JavaScriptScanner { |
||||
|
public: |
||||
|
void Initialize(UTF16Buffer* source) { |
||||
|
source_ = source; |
||||
|
literal_flags_ = kLiteralString | kLiteralIdentifier; |
||||
|
Init(); |
||||
|
// Skip initial whitespace allowing HTML comment ends just like
|
||||
|
// after a newline and scan first token.
|
||||
|
has_line_terminator_before_next_ = true; |
||||
|
SkipWhiteSpace(); |
||||
|
Scan(); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
|
||||
|
// 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, stdin); |
||||
|
return (actually_read == length); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
bool WriteBuffer(FILE* dest, void* buffer, size_t length) { |
||||
|
size_t actually_written = fwrite(buffer, 1, length, dest); |
||||
|
return (actually_written == length); |
||||
|
} |
||||
|
|
||||
|
// Preparse stdin and output result on stdout.
|
||||
|
int PreParseIO() { |
||||
|
fprintf(stderr, "LOG: Enter parsing loop\n"); |
||||
|
bool ok = true; |
||||
|
uint32_t length = ReadUInt32(stdin, &ok); |
||||
|
if (!ok) return kErrorReading; |
||||
|
SmartPointer<byte> buffer(NewArray<byte>(length)); |
||||
|
if (!ReadBuffer(stdin, *buffer, length)) { |
||||
|
return kErrorReading; |
||||
|
} |
||||
|
UTF8UTF16Buffer input_buffer(*buffer, static_cast<size_t>(length)); |
||||
|
StandAloneJavaScriptScanner scanner; |
||||
|
scanner.Initialize(&input_buffer); |
||||
|
CompleteParserRecorder recorder; |
||||
|
preparser::PreParser preparser; |
||||
|
|
||||
|
if (!preparser.PreParseProgram(&scanner, &recorder, true)) { |
||||
|
if (scanner.stack_overflow()) { |
||||
|
// Report stack overflow error/no-preparser-data.
|
||||
|
WriteUInt32(stdout, 0, &ok); |
||||
|
if (!ok) return kErrorWriting; |
||||
|
return 0; |
||||
|
} |
||||
|
} |
||||
|
Vector<unsigned> pre_data = recorder.ExtractData(); |
||||
|
|
||||
|
uint32_t size = static_cast<uint32_t>(pre_data.length() * sizeof(uint32_t)); |
||||
|
WriteUInt32(stdout, size, &ok); |
||||
|
if (!ok) return kErrorWriting; |
||||
|
if (!WriteBuffer(stdout, |
||||
|
reinterpret_cast<byte*>(pre_data.start()), |
||||
|
size)) { |
||||
|
return kErrorWriting; |
||||
|
} |
||||
|
return 0; |
||||
|
} |
||||
|
|
||||
|
// Functions declared by allocation.h
|
||||
|
|
||||
|
void FatalProcessOutOfMemory(const char* location) { |
||||
|
V8_Fatal("", 0, location); |
||||
|
} |
||||
|
|
||||
|
bool EnableSlowAsserts() { return true; } |
||||
|
|
||||
|
} } // namespace v8::internal
|
||||
|
|
||||
|
|
||||
|
int main(int argc, char* argv[]) { |
||||
|
int status = 0; |
||||
|
do { |
||||
|
status = v8::internal::PreParseIO(); |
||||
|
} while (status == 0); |
||||
|
fprintf(stderr, "EXIT: Failure %d\n", status); |
||||
|
return EXIT_FAILURE; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
// Fatal error handling declared by checks.h.
|
||||
|
|
||||
|
extern "C" void V8_Fatal(const char* file, int line, const char* format, ...) { |
||||
|
fflush(stdout); |
||||
|
fflush(stderr); |
||||
|
va_list arguments; |
||||
|
va_start(arguments, format); |
||||
|
vfprintf(stderr, format, arguments); |
||||
|
va_end(arguments); |
||||
|
fputs("\n#\n\n", stderr); |
||||
|
exit(EXIT_FAILURE); |
||||
|
} |
@ -0,0 +1,180 @@ |
|||||
|
// Copyright 2010 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:
|
||||
|
//
|
||||
|
// * Redistributions of source code must retain the above copyright
|
||||
|
// notice, this list of conditions and the following disclaimer.
|
||||
|
// * Redistributions in binary form must reproduce the above
|
||||
|
// copyright notice, this list of conditions and the following
|
||||
|
// disclaimer in the documentation and/or other materials provided
|
||||
|
// with the distribution.
|
||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||
|
// contributors may be used to endorse or promote products derived
|
||||
|
// from this software without specific prior written permission.
|
||||
|
//
|
||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
|
||||
|
#include "../include/v8stdint.h" |
||||
|
#include "globals.h" |
||||
|
#include "checks.h" |
||||
|
#include "allocation.h" |
||||
|
#include "utils.h" |
||||
|
#include "list-inl.h" |
||||
|
#include "hashmap.h" |
||||
|
#include "preparse-data.h" |
||||
|
|
||||
|
namespace v8 { |
||||
|
namespace internal { |
||||
|
|
||||
|
// ----------------------------------------------------------------------------
|
||||
|
// FunctionLoggingParserRecorder
|
||||
|
|
||||
|
FunctionLoggingParserRecorder::FunctionLoggingParserRecorder() |
||||
|
: function_store_(0), |
||||
|
is_recording_(true), |
||||
|
pause_count_(0) { |
||||
|
preamble_[PreparseDataConstants::kMagicOffset] = |
||||
|
PreparseDataConstants::kMagicNumber; |
||||
|
preamble_[PreparseDataConstants::kVersionOffset] = |
||||
|
PreparseDataConstants::kCurrentVersion; |
||||
|
preamble_[PreparseDataConstants::kHasErrorOffset] = false; |
||||
|
preamble_[PreparseDataConstants::kFunctionsSizeOffset] = 0; |
||||
|
preamble_[PreparseDataConstants::kSymbolCountOffset] = 0; |
||||
|
preamble_[PreparseDataConstants::kSizeOffset] = 0; |
||||
|
ASSERT_EQ(6, PreparseDataConstants::kHeaderSize); |
||||
|
#ifdef DEBUG |
||||
|
prev_start_ = -1; |
||||
|
#endif |
||||
|
} |
||||
|
|
||||
|
|
||||
|
void FunctionLoggingParserRecorder::LogMessage(int start_pos, |
||||
|
int end_pos, |
||||
|
const char* message, |
||||
|
const char* arg_opt) { |
||||
|
if (has_error()) return; |
||||
|
preamble_[PreparseDataConstants::kHasErrorOffset] = true; |
||||
|
function_store_.Reset(); |
||||
|
STATIC_ASSERT(PreparseDataConstants::kMessageStartPos == 0); |
||||
|
function_store_.Add(start_pos); |
||||
|
STATIC_ASSERT(PreparseDataConstants::kMessageEndPos == 1); |
||||
|
function_store_.Add(end_pos); |
||||
|
STATIC_ASSERT(PreparseDataConstants::kMessageArgCountPos == 2); |
||||
|
function_store_.Add((arg_opt == NULL) ? 0 : 1); |
||||
|
STATIC_ASSERT(PreparseDataConstants::kMessageTextPos == 3); |
||||
|
WriteString(CStrVector(message)); |
||||
|
if (arg_opt) WriteString(CStrVector(arg_opt)); |
||||
|
is_recording_ = false; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
void FunctionLoggingParserRecorder::WriteString(Vector<const char> str) { |
||||
|
function_store_.Add(str.length()); |
||||
|
for (int i = 0; i < str.length(); i++) { |
||||
|
function_store_.Add(str[i]); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// ----------------------------------------------------------------------------
|
||||
|
// PartialParserRecorder - Record both function entries and symbols.
|
||||
|
|
||||
|
Vector<unsigned> PartialParserRecorder::ExtractData() { |
||||
|
int function_size = function_store_.size(); |
||||
|
int total_size = PreparseDataConstants::kHeaderSize + function_size; |
||||
|
Vector<unsigned> data = Vector<unsigned>::New(total_size); |
||||
|
preamble_[PreparseDataConstants::kFunctionsSizeOffset] = function_size; |
||||
|
preamble_[PreparseDataConstants::kSymbolCountOffset] = 0; |
||||
|
memcpy(data.start(), preamble_, sizeof(preamble_)); |
||||
|
int symbol_start = PreparseDataConstants::kHeaderSize + function_size; |
||||
|
if (function_size > 0) { |
||||
|
function_store_.WriteTo(data.SubVector(PreparseDataConstants::kHeaderSize, |
||||
|
symbol_start)); |
||||
|
} |
||||
|
return data; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
// ----------------------------------------------------------------------------
|
||||
|
// CompleteParserRecorder - Record both function entries and symbols.
|
||||
|
|
||||
|
CompleteParserRecorder::CompleteParserRecorder() |
||||
|
: FunctionLoggingParserRecorder(), |
||||
|
symbol_store_(0), |
||||
|
symbol_entries_(0), |
||||
|
symbol_table_(vector_compare), |
||||
|
symbol_id_(0) { |
||||
|
} |
||||
|
|
||||
|
|
||||
|
void CompleteParserRecorder::LogSymbol( |
||||
|
int start, const char* literal_chars, int length) { |
||||
|
if (!is_recording_) return; |
||||
|
|
||||
|
Vector<const char> literal(literal_chars, length); |
||||
|
int hash = vector_hash(literal); |
||||
|
HashMap::Entry* entry = symbol_table_.Lookup(&literal, hash, true); |
||||
|
int id = static_cast<int>(reinterpret_cast<intptr_t>(entry->value)); |
||||
|
if (id == 0) { |
||||
|
// Put (symbol_id_ + 1) into entry and increment it.
|
||||
|
id = ++symbol_id_; |
||||
|
entry->value = reinterpret_cast<void*>(id); |
||||
|
Vector<Vector<const char> > symbol = symbol_entries_.AddBlock(1, literal); |
||||
|
entry->key = &symbol[0]; |
||||
|
} |
||||
|
WriteNumber(id - 1); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
Vector<unsigned> CompleteParserRecorder::ExtractData() { |
||||
|
int function_size = function_store_.size(); |
||||
|
// Add terminator to symbols, then pad to unsigned size.
|
||||
|
int symbol_size = symbol_store_.size(); |
||||
|
int padding = sizeof(unsigned) - (symbol_size % sizeof(unsigned)); |
||||
|
symbol_store_.AddBlock(padding, PreparseDataConstants::kNumberTerminator); |
||||
|
symbol_size += padding; |
||||
|
int total_size = PreparseDataConstants::kHeaderSize + function_size |
||||
|
+ (symbol_size / sizeof(unsigned)); |
||||
|
Vector<unsigned> data = Vector<unsigned>::New(total_size); |
||||
|
preamble_[PreparseDataConstants::kFunctionsSizeOffset] = function_size; |
||||
|
preamble_[PreparseDataConstants::kSymbolCountOffset] = symbol_id_; |
||||
|
memcpy(data.start(), preamble_, sizeof(preamble_)); |
||||
|
int symbol_start = PreparseDataConstants::kHeaderSize + function_size; |
||||
|
if (function_size > 0) { |
||||
|
function_store_.WriteTo(data.SubVector(PreparseDataConstants::kHeaderSize, |
||||
|
symbol_start)); |
||||
|
} |
||||
|
if (!has_error()) { |
||||
|
symbol_store_.WriteTo( |
||||
|
Vector<byte>::cast(data.SubVector(symbol_start, total_size))); |
||||
|
} |
||||
|
return data; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
void CompleteParserRecorder::WriteNumber(int number) { |
||||
|
ASSERT(number >= 0); |
||||
|
|
||||
|
int mask = (1 << 28) - 1; |
||||
|
for (int i = 28; i > 0; i -= 7) { |
||||
|
if (number > mask) { |
||||
|
symbol_store_.Add(static_cast<byte>(number >> i) | 0x80u); |
||||
|
number &= mask; |
||||
|
} |
||||
|
mask >>= 7; |
||||
|
} |
||||
|
symbol_store_.Add(static_cast<byte>(number)); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
} } // namespace v8::internal.
|
@ -0,0 +1,223 @@ |
|||||
|
// Copyright 2010 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:
|
||||
|
//
|
||||
|
// * Redistributions of source code must retain the above copyright
|
||||
|
// notice, this list of conditions and the following disclaimer.
|
||||
|
// * Redistributions in binary form must reproduce the above
|
||||
|
// copyright notice, this list of conditions and the following
|
||||
|
// disclaimer in the documentation and/or other materials provided
|
||||
|
// with the distribution.
|
||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||
|
// contributors may be used to endorse or promote products derived
|
||||
|
// from this software without specific prior written permission.
|
||||
|
//
|
||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
|
||||
|
#ifndef V8_PREPARSER_DATA_H_ |
||||
|
#define V8_PREPARSER_DATA_H_ |
||||
|
|
||||
|
#include "hashmap.h" |
||||
|
|
||||
|
namespace v8 { |
||||
|
namespace internal { |
||||
|
|
||||
|
// Generic and general data used by preparse data recorders and readers.
|
||||
|
|
||||
|
class PreparseDataConstants : public AllStatic { |
||||
|
public: |
||||
|
// Layout and constants of the preparse data exchange format.
|
||||
|
static const unsigned kMagicNumber = 0xBadDead; |
||||
|
static const unsigned kCurrentVersion = 5; |
||||
|
|
||||
|
static const int kMagicOffset = 0; |
||||
|
static const int kVersionOffset = 1; |
||||
|
static const int kHasErrorOffset = 2; |
||||
|
static const int kFunctionsSizeOffset = 3; |
||||
|
static const int kSymbolCountOffset = 4; |
||||
|
static const int kSizeOffset = 5; |
||||
|
static const int kHeaderSize = 6; |
||||
|
|
||||
|
// If encoding a message, the following positions are fixed.
|
||||
|
static const int kMessageStartPos = 0; |
||||
|
static const int kMessageEndPos = 1; |
||||
|
static const int kMessageArgCountPos = 2; |
||||
|
static const int kMessageTextPos = 3; |
||||
|
|
||||
|
static const byte kNumberTerminator = 0x80u; |
||||
|
}; |
||||
|
|
||||
|
|
||||
|
// ----------------------------------------------------------------------------
|
||||
|
// ParserRecorder - Logging of preparser data.
|
||||
|
|
||||
|
// Abstract interface for preparse data recorder.
|
||||
|
class ParserRecorder { |
||||
|
public: |
||||
|
ParserRecorder() { } |
||||
|
virtual ~ParserRecorder() { } |
||||
|
|
||||
|
// Logs the scope and some details of a function literal in the source.
|
||||
|
virtual void LogFunction(int start, |
||||
|
int end, |
||||
|
int literals, |
||||
|
int properties) = 0; |
||||
|
|
||||
|
// Logs a symbol creation of a literal or identifier.
|
||||
|
virtual void LogSymbol(int start, const char* symbol, int length) = 0; |
||||
|
|
||||
|
// Logs an error message and marks the log as containing an error.
|
||||
|
// Further logging will be ignored, and ExtractData will return a vector
|
||||
|
// representing the error only.
|
||||
|
virtual void LogMessage(int start, |
||||
|
int end, |
||||
|
const char* message, |
||||
|
const char* argument_opt) = 0; |
||||
|
|
||||
|
virtual int function_position() = 0; |
||||
|
|
||||
|
virtual int symbol_position() = 0; |
||||
|
|
||||
|
virtual int symbol_ids() = 0; |
||||
|
|
||||
|
virtual Vector<unsigned> ExtractData() = 0; |
||||
|
|
||||
|
virtual void PauseRecording() = 0; |
||||
|
|
||||
|
virtual void ResumeRecording() = 0; |
||||
|
}; |
||||
|
|
||||
|
|
||||
|
// ----------------------------------------------------------------------------
|
||||
|
// FunctionLoggingParserRecorder - Record only function entries
|
||||
|
|
||||
|
class FunctionLoggingParserRecorder : public ParserRecorder { |
||||
|
public: |
||||
|
FunctionLoggingParserRecorder(); |
||||
|
virtual ~FunctionLoggingParserRecorder() {} |
||||
|
|
||||
|
virtual void LogFunction(int start, int end, int literals, int properties) { |
||||
|
function_store_.Add(start); |
||||
|
function_store_.Add(end); |
||||
|
function_store_.Add(literals); |
||||
|
function_store_.Add(properties); |
||||
|
} |
||||
|
|
||||
|
// Logs an error message and marks the log as containing an error.
|
||||
|
// Further logging will be ignored, and ExtractData will return a vector
|
||||
|
// representing the error only.
|
||||
|
virtual void LogMessage(int start, |
||||
|
int end, |
||||
|
const char* message, |
||||
|
const char* argument_opt); |
||||
|
|
||||
|
virtual int function_position() { return function_store_.size(); } |
||||
|
|
||||
|
|
||||
|
virtual Vector<unsigned> ExtractData() = 0; |
||||
|
|
||||
|
virtual void PauseRecording() { |
||||
|
pause_count_++; |
||||
|
is_recording_ = false; |
||||
|
} |
||||
|
|
||||
|
virtual void ResumeRecording() { |
||||
|
ASSERT(pause_count_ > 0); |
||||
|
if (--pause_count_ == 0) is_recording_ = !has_error(); |
||||
|
} |
||||
|
|
||||
|
protected: |
||||
|
bool has_error() { |
||||
|
return static_cast<bool>(preamble_[PreparseDataConstants::kHasErrorOffset]); |
||||
|
} |
||||
|
|
||||
|
bool is_recording() { |
||||
|
return is_recording_; |
||||
|
} |
||||
|
|
||||
|
void WriteString(Vector<const char> str); |
||||
|
|
||||
|
Collector<unsigned> function_store_; |
||||
|
unsigned preamble_[PreparseDataConstants::kHeaderSize]; |
||||
|
bool is_recording_; |
||||
|
int pause_count_; |
||||
|
|
||||
|
#ifdef DEBUG |
||||
|
int prev_start_; |
||||
|
#endif |
||||
|
}; |
||||
|
|
||||
|
|
||||
|
// ----------------------------------------------------------------------------
|
||||
|
// PartialParserRecorder - Record only function entries
|
||||
|
|
||||
|
class PartialParserRecorder : public FunctionLoggingParserRecorder { |
||||
|
public: |
||||
|
PartialParserRecorder() : FunctionLoggingParserRecorder() { } |
||||
|
virtual void LogSymbol(int start, const char* symbol, int length) { } |
||||
|
virtual ~PartialParserRecorder() { } |
||||
|
virtual Vector<unsigned> ExtractData(); |
||||
|
virtual int symbol_position() { return 0; } |
||||
|
virtual int symbol_ids() { return 0; } |
||||
|
}; |
||||
|
|
||||
|
|
||||
|
// ----------------------------------------------------------------------------
|
||||
|
// CompleteParserRecorder - Record both function entries and symbols.
|
||||
|
|
||||
|
class CompleteParserRecorder: public FunctionLoggingParserRecorder { |
||||
|
public: |
||||
|
CompleteParserRecorder(); |
||||
|
virtual ~CompleteParserRecorder() { } |
||||
|
|
||||
|
virtual void LogSymbol(int start, const char* symbol, int length); |
||||
|
|
||||
|
virtual Vector<unsigned> ExtractData(); |
||||
|
|
||||
|
virtual int symbol_position() { return symbol_store_.size(); } |
||||
|
virtual int symbol_ids() { return symbol_id_; } |
||||
|
|
||||
|
private: |
||||
|
static int vector_hash(Vector<const char> string) { |
||||
|
int hash = 0; |
||||
|
for (int i = 0; i < string.length(); i++) { |
||||
|
int c = string[i]; |
||||
|
hash += c; |
||||
|
hash += (hash << 10); |
||||
|
hash ^= (hash >> 6); |
||||
|
} |
||||
|
return hash; |
||||
|
} |
||||
|
|
||||
|
static bool vector_compare(void* a, void* b) { |
||||
|
Vector<const char>* string1 = reinterpret_cast<Vector<const char>* >(a); |
||||
|
Vector<const char>* string2 = reinterpret_cast<Vector<const char>* >(b); |
||||
|
int length = string1->length(); |
||||
|
if (string2->length() != length) return false; |
||||
|
return memcmp(string1->start(), string2->start(), length) == 0; |
||||
|
} |
||||
|
|
||||
|
// Write a non-negative number to the symbol store.
|
||||
|
void WriteNumber(int number); |
||||
|
|
||||
|
Collector<byte> symbol_store_; |
||||
|
Collector<Vector<const char> > symbol_entries_; |
||||
|
HashMap symbol_table_; |
||||
|
int symbol_id_; |
||||
|
}; |
||||
|
|
||||
|
|
||||
|
} } // namespace v8::internal.
|
||||
|
|
||||
|
#endif // V8_PREPARSER_DATA_H_
|
File diff suppressed because it is too large
File diff suppressed because it is too large
@ -0,0 +1,64 @@ |
|||||
|
// Copyright 2006-2008 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:
|
||||
|
//
|
||||
|
// * Redistributions of source code must retain the above copyright
|
||||
|
// notice, this list of conditions and the following disclaimer.
|
||||
|
// * Redistributions in binary form must reproduce the above
|
||||
|
// copyright notice, this list of conditions and the following
|
||||
|
// disclaimer in the documentation and/or other materials provided
|
||||
|
// with the distribution.
|
||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||
|
// contributors may be used to endorse or promote products derived
|
||||
|
// from this software without specific prior written permission.
|
||||
|
//
|
||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
|
||||
|
#ifndef V8_V8CHECKS_H_ |
||||
|
#define V8_V8CHECKS_H_ |
||||
|
|
||||
|
#include "checks.h" |
||||
|
|
||||
|
void API_Fatal(const char* location, const char* format, ...); |
||||
|
|
||||
|
namespace v8 { |
||||
|
class Value; |
||||
|
template <class T> class Handle; |
||||
|
|
||||
|
namespace internal { |
||||
|
intptr_t HeapObjectTagMask(); |
||||
|
|
||||
|
} } // namespace v8::internal
|
||||
|
|
||||
|
|
||||
|
void CheckNonEqualsHelper(const char* file, |
||||
|
int line, |
||||
|
const char* unexpected_source, |
||||
|
v8::Handle<v8::Value> unexpected, |
||||
|
const char* value_source, |
||||
|
v8::Handle<v8::Value> value); |
||||
|
|
||||
|
void CheckEqualsHelper(const char* file, |
||||
|
int line, |
||||
|
const char* expected_source, |
||||
|
v8::Handle<v8::Value> expected, |
||||
|
const char* value_source, |
||||
|
v8::Handle<v8::Value> value); |
||||
|
|
||||
|
#define ASSERT_TAG_ALIGNED(address) \ |
||||
|
ASSERT((reinterpret_cast<intptr_t>(address) & HeapObjectTagMask()) == 0) |
||||
|
|
||||
|
#define ASSERT_SIZE_TAG_ALIGNED(size) ASSERT((size & HeapObjectTagMask()) == 0) |
||||
|
|
||||
|
#endif // V8_V8CHECKS_H_
|
@ -0,0 +1,46 @@ |
|||||
|
// Copyright 2010 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:
|
||||
|
//
|
||||
|
// * Redistributions of source code must retain the above copyright
|
||||
|
// notice, this list of conditions and the following disclaimer.
|
||||
|
// * Redistributions in binary form must reproduce the above
|
||||
|
// copyright notice, this list of conditions and the following
|
||||
|
// disclaimer in the documentation and/or other materials provided
|
||||
|
// with the distribution.
|
||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||
|
// contributors may be used to endorse or promote products derived
|
||||
|
// from this software without specific prior written permission.
|
||||
|
//
|
||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
|
||||
|
// Check for parsing of proper ES5 15.9.1.15 (ISO 8601 / RFC 3339) time
|
||||
|
// strings that contain millisecond values with exactly 3 digits (as is
|
||||
|
// required by the spec format if the string has milliseconds at all).
|
||||
|
assertEquals(1290722550521, Date.parse("2010-11-25T22:02:30.521Z")); |
||||
|
|
||||
|
// Check for parsing of extension/generalization of the ES5 15.9.1.15 spec
|
||||
|
// format where millisecond values have only 1 or 2 digits.
|
||||
|
assertEquals(1290722550500, Date.parse("2010-11-25T22:02:30.5Z")); |
||||
|
assertEquals(1290722550520, Date.parse("2010-11-25T22:02:30.52Z")); |
||||
|
assertFalse(Date.parse("2010-11-25T22:02:30.5Z") === Date.parse("2010-11-25T22:02:30.005Z")); |
||||
|
|
||||
|
// Check that we truncate millisecond values having more than 3 digits.
|
||||
|
assertEquals(Date.parse("2010-11-25T22:02:30.1005Z"), Date.parse("2010-11-25T22:02:30.100Z")); |
||||
|
|
||||
|
// Check that we accept lots of digits.
|
||||
|
assertEquals(Date.parse("2010-11-25T22:02:30.999Z"), Date.parse("2010-11-25T22:02:30.99999999999999999999999999999999999999999999999999999999999999999999999999999999999999Z")); |
||||
|
|
||||
|
// Fail if there's a decimal point but zero digits for (expected) milliseconds.
|
||||
|
assertTrue(isNaN(Date.parse("2010-11-25T22:02:30.Z"))); |
Loading…
Reference in new issue