From: ager@chromium.org Date: Tue, 25 May 2010 06:38:19 +0000 (+0000) Subject: Landing patch by tonyg@chromium.org: X-Git-Tag: upstream/4.7.83~21753 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ab6055d85d0fa496b10bf4151afee980ced6769d;p=platform%2Fupstream%2Fv8.git 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 --- diff --git a/include/v8.h b/include/v8.h index eb12de8..62bf85c 100644 --- a/include/v8.h +++ b/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; }; diff --git a/src/api.cc b/src/api.cc index 5560cf4..a063e90 100644 --- a/src/api.cc +++ b/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(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()); + } + + // Copy the data to ensure it is properly aligned. + int deserialized_data_length = length / sizeof(unsigned); + unsigned* deserialized_data = i::NewArray(deserialized_data_length); + memcpy(deserialized_data, data, length); + + return new i::ScriptDataImpl( + i::Vector(deserialized_data, deserialized_data_length)); } diff --git a/src/objects.cc b/src/objects.cc index 360eb28..735786f 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -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) { diff --git a/src/parser.cc b/src/parser.cc index c482fdf..d97db2e 100644 --- a/src/parser.cc +++ b/src/parser.cc @@ -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(store_.start()); } diff --git a/src/parser.h b/src/parser.h index 2e5daf9..89966a6 100644 --- a/src/parser.h +++ b/src/parser.h @@ -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(); diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc index ea9e6e1..bb34375 100644 --- a/test/cctest/test-api.cc +++ b/test/cctest/test-api.cc @@ -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(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