Landing patch by tonyg@chromium.org:
Changing ScriptData API to serialize its internal representation to a const char* array. This decouples the API from the internal representation and avoids the need for callers to serialize themselves. As a side-effect, ScriptData::New() no longer assumes ownership of its input. This shouldn't matter as typical usage patterns for the old API would have required a copy prior to calling ScriptData::New(). Review URL: http://codereview.chromium.org/2118010/show git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4710 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
0328e0cf3a
commit
ab6055d85d
30
include/v8.h
30
include/v8.h
@ -512,11 +512,37 @@ class V8EXPORT Data {
|
||||
class V8EXPORT ScriptData { // NOLINT
|
||||
public:
|
||||
virtual ~ScriptData() { }
|
||||
/**
|
||||
* Pre-compiles the specified script (context-independent).
|
||||
*
|
||||
* \param input Pointer to UTF-8 script source code.
|
||||
* \param length Length of UTF-8 script source code.
|
||||
*/
|
||||
static ScriptData* PreCompile(const char* input, int length);
|
||||
static ScriptData* New(unsigned* data, int length);
|
||||
|
||||
/**
|
||||
* Load previous pre-compilation data.
|
||||
*
|
||||
* \param data Pointer to data returned by a call to Data() of a previous
|
||||
* ScriptData. Ownership is not transferred.
|
||||
* \param length Length of data.
|
||||
*/
|
||||
static ScriptData* New(const char* data, int length);
|
||||
|
||||
/**
|
||||
* Returns the length of Data().
|
||||
*/
|
||||
virtual int Length() = 0;
|
||||
virtual unsigned* Data() = 0;
|
||||
|
||||
/**
|
||||
* Returns a serialized representation of this ScriptData that can later be
|
||||
* passed to New(). NOTE: Serialized data is platform-dependent.
|
||||
*/
|
||||
virtual const char* Data() = 0;
|
||||
|
||||
/**
|
||||
* Returns true if the source code could not be parsed.
|
||||
*/
|
||||
virtual bool HasError() = 0;
|
||||
};
|
||||
|
||||
|
15
src/api.cc
15
src/api.cc
@ -1105,8 +1105,19 @@ ScriptData* ScriptData::PreCompile(const char* input, int length) {
|
||||
}
|
||||
|
||||
|
||||
ScriptData* ScriptData::New(unsigned* data, int length) {
|
||||
return new i::ScriptDataImpl(i::Vector<unsigned>(data, length));
|
||||
ScriptData* ScriptData::New(const char* data, int length) {
|
||||
// Return an empty ScriptData if the length is obviously invalid.
|
||||
if (length % sizeof(unsigned) != 0) {
|
||||
return new i::ScriptDataImpl(i::Vector<unsigned>());
|
||||
}
|
||||
|
||||
// Copy the data to ensure it is properly aligned.
|
||||
int deserialized_data_length = length / sizeof(unsigned);
|
||||
unsigned* deserialized_data = i::NewArray<unsigned>(deserialized_data_length);
|
||||
memcpy(deserialized_data, data, length);
|
||||
|
||||
return new i::ScriptDataImpl(
|
||||
i::Vector<unsigned>(deserialized_data, deserialized_data_length));
|
||||
}
|
||||
|
||||
|
||||
|
@ -139,7 +139,8 @@ Object* Object::GetPropertyWithReceiver(Object* receiver,
|
||||
}
|
||||
|
||||
|
||||
Object* Object::GetPropertyWithCallback(Object* receiver,
|
||||
Object* Object::GetPropertyWithCallk
|
||||
jback(Object* receiver,
|
||||
Object* structure,
|
||||
String* name,
|
||||
Object* holder) {
|
||||
|
@ -5073,12 +5073,13 @@ ScriptDataImpl::~ScriptDataImpl() {
|
||||
|
||||
|
||||
int ScriptDataImpl::Length() {
|
||||
return store_.length();
|
||||
static const int kCharToUnsignedFactor = sizeof(unsigned) / sizeof(char);
|
||||
return store_.length() * kCharToUnsignedFactor;
|
||||
}
|
||||
|
||||
|
||||
unsigned* ScriptDataImpl::Data() {
|
||||
return store_.start();
|
||||
const char* ScriptDataImpl::Data() {
|
||||
return reinterpret_cast<const char*>(store_.start());
|
||||
}
|
||||
|
||||
|
||||
|
@ -90,7 +90,7 @@ class ScriptDataImpl : public ScriptData {
|
||||
last_entry_(0) { }
|
||||
virtual ~ScriptDataImpl();
|
||||
virtual int Length();
|
||||
virtual unsigned* Data();
|
||||
virtual const char* Data();
|
||||
virtual bool HasError();
|
||||
FunctionEntry GetFunctionEnd(int start);
|
||||
bool SanityCheck();
|
||||
|
@ -8003,8 +8003,8 @@ TEST(PreCompile) {
|
||||
// TODO(155): This test would break without the initialization of V8. This is
|
||||
// a workaround for now to make this test not fail.
|
||||
v8::V8::Initialize();
|
||||
const char *script = "function foo(a) { return a+1; }";
|
||||
v8::ScriptData *sd =
|
||||
const char* script = "function foo(a) { return a+1; }";
|
||||
v8::ScriptData* sd =
|
||||
v8::ScriptData::PreCompile(script, i::StrLength(script));
|
||||
CHECK_NE(sd->Length(), 0);
|
||||
CHECK_NE(sd->Data(), NULL);
|
||||
@ -8015,8 +8015,8 @@ TEST(PreCompile) {
|
||||
|
||||
TEST(PreCompileWithError) {
|
||||
v8::V8::Initialize();
|
||||
const char *script = "function foo(a) { return 1 * * 2; }";
|
||||
v8::ScriptData *sd =
|
||||
const char* script = "function foo(a) { return 1 * * 2; }";
|
||||
v8::ScriptData* sd =
|
||||
v8::ScriptData::PreCompile(script, i::StrLength(script));
|
||||
CHECK(sd->HasError());
|
||||
delete sd;
|
||||
@ -8025,14 +8025,53 @@ TEST(PreCompileWithError) {
|
||||
|
||||
TEST(Regress31661) {
|
||||
v8::V8::Initialize();
|
||||
const char *script = " The Definintive Guide";
|
||||
v8::ScriptData *sd =
|
||||
const char* script = " The Definintive Guide";
|
||||
v8::ScriptData* sd =
|
||||
v8::ScriptData::PreCompile(script, i::StrLength(script));
|
||||
CHECK(sd->HasError());
|
||||
delete sd;
|
||||
}
|
||||
|
||||
|
||||
// Tests that ScriptData can be serialized and deserialized.
|
||||
TEST(PreCompileSerialization) {
|
||||
v8::V8::Initialize();
|
||||
const char* script = "function foo(a) { return a+1; }";
|
||||
v8::ScriptData* sd =
|
||||
v8::ScriptData::PreCompile(script, i::StrLength(script));
|
||||
|
||||
// Serialize.
|
||||
int serialized_data_length = sd->Length();
|
||||
char* serialized_data = i::NewArray<char>(serialized_data_length);
|
||||
memcpy(serialized_data, sd->Data(), serialized_data_length);
|
||||
|
||||
// Deserialize.
|
||||
v8::ScriptData* deserialized_sd =
|
||||
v8::ScriptData::New(serialized_data, serialized_data_length);
|
||||
|
||||
// Verify that the original is the same as the deserialized.
|
||||
CHECK_EQ(sd->Length(), deserialized_sd->Length());
|
||||
CHECK_EQ(0, memcmp(sd->Data(), deserialized_sd->Data(), sd->Length()));
|
||||
CHECK_EQ(sd->HasError(), deserialized_sd->HasError());
|
||||
|
||||
delete sd;
|
||||
delete deserialized_sd;
|
||||
}
|
||||
|
||||
|
||||
// Attempts to deserialize bad data.
|
||||
TEST(PreCompileDeserializationError) {
|
||||
v8::V8::Initialize();
|
||||
const char* data = "DONT CARE";
|
||||
int invalid_size = 3;
|
||||
v8::ScriptData* sd = v8::ScriptData::New(data, invalid_size);
|
||||
|
||||
CHECK_EQ(0, sd->Length());
|
||||
|
||||
delete sd;
|
||||
}
|
||||
|
||||
|
||||
// This tests that we do not allow dictionary load/call inline caches
|
||||
// to use functions that have not yet been compiled. The potential
|
||||
// problem of loading a function that has not yet been compiled can
|
||||
|
Loading…
Reference in New Issue
Block a user