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