Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(133)

Unified Diff: Source/WebCore/bindings/v8/SerializedScriptValue.cpp

Issue 8806015: Changes to support a second VM. (Closed) Base URL: svn://svn.chromium.org/dash/experimental/chrome/src/webkit-full
Patch Set: . Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: Source/WebCore/bindings/v8/SerializedScriptValue.cpp
diff --git a/Source/WebCore/bindings/v8/SerializedScriptValue.cpp b/Source/WebCore/bindings/v8/SerializedScriptValue.cpp
index 42a37082ea0d8fe2966bc3afbde05c7321b99558..8f37300111c77843e32ec15d8677d6d0f9b12e12 100644
--- a/Source/WebCore/bindings/v8/SerializedScriptValue.cpp
+++ b/Source/WebCore/bindings/v8/SerializedScriptValue.cpp
@@ -47,6 +47,8 @@
#include "Int32Array.h"
#include "Int8Array.h"
#include "MessagePort.h"
+#include "ScriptValueDeserializer.h"
+#include "ScriptValueSerializer.h"
#include "SharedBuffer.h"
#include "Uint16Array.h"
#include "Uint32Array.h"
@@ -267,7 +269,7 @@ private:
// Writer is responsible for serializing primitive types and storing
// information used to reconstruct composite types.
-class Writer {
+class Writer : public ScriptValueWriter {
WTF_MAKE_NONCOPYABLE(Writer);
public:
Writer()
@@ -1107,23 +1109,6 @@ Serializer::StateBase* Serializer::doSerialize(v8::Handle<v8::Value> value, Stat
return 0;
}
-// Interface used by Reader to create objects of composite types.
-class CompositeCreator {
-public:
- virtual ~CompositeCreator() { }
-
- virtual bool consumeTopOfStack(v8::Handle<v8::Value>*) = 0;
- virtual uint32_t objectReferenceCount() = 0;
- virtual void pushObjectReference(const v8::Handle<v8::Value>&) = 0;
- virtual bool tryGetObjectFromObjectReference(uint32_t reference, v8::Handle<v8::Value>*) = 0;
- virtual bool tryGetTransferredMessagePort(uint32_t index, v8::Handle<v8::Value>*) = 0;
- virtual bool newArray(uint32_t length) = 0;
- virtual bool newObject() = 0;
- virtual bool completeArray(uint32_t length, v8::Handle<v8::Value>*) = 0;
- virtual bool completeObject(uint32_t numProperties, v8::Handle<v8::Value>*) = 0;
- virtual bool completeSparseArray(uint32_t numProperties, uint32_t length, v8::Handle<v8::Value>*) = 0;
-};
-
// Reader is responsible for deserializing primitive types and
// restoring information about saved objects of composite types.
class Reader {
@@ -1137,194 +1122,200 @@ public:
ASSERT(length >= 0);
}
- bool isEof() const { return m_position >= m_length; }
+ uint32_t version() const { return m_version; }
- bool read(v8::Handle<v8::Value>* value, CompositeCreator& creator)
+ bool read(ScriptValueDeserializer& deserializer)
{
- SerializationTag tag;
- if (!readTag(&tag))
+ if (!readVersion(m_version) || m_version > wireFormatVersion)
return false;
- switch (tag) {
- case ReferenceCountTag: {
- if (m_version <= 0)
- return false;
- uint32_t referenceTableSize;
- if (!doReadUint32(&referenceTableSize))
- return false;
- // If this test fails, then the serializer and deserializer disagree about the assignment
- // of object reference IDs. On the deserialization side, this means there are too many or too few
- // calls to pushObjectReference.
- if (referenceTableSize != creator.objectReferenceCount())
- return false;
- return true;
- }
- case InvalidTag:
- return false;
- case PaddingTag:
- return true;
- case UndefinedTag:
- *value = v8::Undefined();
- break;
- case NullTag:
- *value = v8::Null();
- break;
- case TrueTag:
- *value = v8::True();
- break;
- case FalseTag:
- *value = v8::False();
- break;
- case TrueObjectTag:
- *value = v8::BooleanObject::New(true);
- creator.pushObjectReference(*value);
- break;
- case FalseObjectTag:
- *value = v8::BooleanObject::New(false);
- creator.pushObjectReference(*value);
- break;
- case StringTag:
- if (!readString(value))
- return false;
- break;
- case StringObjectTag:
- if (!readStringObject(value))
- return false;
- creator.pushObjectReference(*value);
- break;
- case Int32Tag:
- if (!readInt32(value))
- return false;
- break;
- case Uint32Tag:
- if (!readUint32(value))
- return false;
- break;
- case DateTag:
- if (!readDate(value))
- return false;
- creator.pushObjectReference(*value);
- break;
- case NumberTag:
- if (!readNumber(value))
- return false;
- break;
- case NumberObjectTag:
- if (!readNumberObject(value))
- return false;
- creator.pushObjectReference(*value);
- break;
- case BlobTag:
- if (!readBlob(value))
- return false;
- creator.pushObjectReference(*value);
- break;
- case FileTag:
- if (!readFile(value))
- return false;
- creator.pushObjectReference(*value);
- break;
- case FileListTag:
- if (!readFileList(value))
- return false;
- creator.pushObjectReference(*value);
- break;
- case ImageDataTag:
- if (!readImageData(value))
- return false;
- creator.pushObjectReference(*value);
- break;
- case ArrayTag: {
- uint32_t length;
- if (!doReadUint32(&length))
- return false;
- if (!creator.completeArray(length, value))
- return false;
- break;
- }
- case RegExpTag:
- if (!readRegExp(value))
+ while (!isEof()) {
+ SerializationTag tag;
+ if (!readTag(&tag))
return false;
- creator.pushObjectReference(*value);
- break;
- case ObjectTag: {
- uint32_t numProperties;
- if (!doReadUint32(&numProperties))
- return false;
- if (!creator.completeObject(numProperties, value))
- return false;
- break;
- }
- case SparseArrayTag: {
- uint32_t numProperties;
- uint32_t length;
- if (!doReadUint32(&numProperties))
- return false;
- if (!doReadUint32(&length))
- return false;
- if (!creator.completeSparseArray(numProperties, length, value))
- return false;
- break;
- }
- case ArrayBufferViewTag: {
- if (m_version <= 0)
- return false;
- if (!readArrayBufferView(value, creator))
- return false;
- creator.pushObjectReference(*value);
- break;
- }
- case ArrayBufferTag: {
- if (m_version <= 0)
- return false;
- if (!readArrayBuffer(value))
- return false;
- creator.pushObjectReference(*value);
- break;
- }
- case GenerateFreshObjectTag: {
- if (m_version <= 0)
- return false;
- if (!creator.newObject())
- return false;
- return true;
- }
- case GenerateFreshArrayTag: {
- if (m_version <= 0)
- return false;
- uint32_t length;
- if (!doReadUint32(&length))
- return false;
- if (!creator.newArray(length))
- return false;
- return true;
- }
- case MessagePortTag: {
- if (m_version <= 0)
- return false;
- uint32_t index;
- if (!doReadUint32(&index))
- return false;
- if (!creator.tryGetTransferredMessagePort(index, value))
- return false;
- break;
- }
- case ObjectReferenceTag: {
- if (m_version <= 0)
- return false;
- uint32_t reference;
- if (!doReadUint32(&reference))
+ switch (tag) {
+ case ReferenceCountTag: {
+ if (m_version <= 0)
+ return false;
+ uint32_t referenceTableSize;
+ if (!doReadUint32(&referenceTableSize))
+ return false;
+ // If this test fails, then the serializer and deserializer disagree about the assignment
+ // of object reference IDs.
+ if (referenceTableSize != deserializer.objectReferenceCount())
+ return false;
+ break;
+ }
+ case InvalidTag:
return false;
- if (!creator.tryGetObjectFromObjectReference(reference, value))
+ case PaddingTag:
+ break;
+ case UndefinedTag:
+ if (!deserializer.pushUndefined())
+ return false;
+ break;
+ case NullTag:
+ if (!deserializer.pushNull())
+ return false;
+ break;
+ case TrueTag:
+ if (!deserializer.pushTrue())
+ return false;
+ break;
+ case FalseTag:
+ if (!deserializer.pushFalse())
+ return false;
+ break;
+ case TrueObjectTag:
+ if (!deserializer.pushTrueObject())
+ return false;
+ deserializer.addReferenceForTop();
+ break;
+ case FalseObjectTag:
+ if (!deserializer.pushFalseObject())
+ return false;
+ deserializer.addReferenceForTop();
+ break;
+ case StringTag:
+ if (!readString(deserializer))
+ return false;
+ break;
+ case StringObjectTag:
+ if (!readStringObject(deserializer))
+ return false;
+ break;
+ case Int32Tag:
+ if (!readInt32(deserializer))
+ return false;
+ break;
+ case Uint32Tag:
+ if (!readUint32(deserializer))
+ return false;
+ break;
+ case DateTag:
+ if (!readDate(deserializer))
+ return false;
+ break;
+ case NumberTag:
+ if (!readNumber(deserializer))
+ return false;
+ break;
+ case NumberObjectTag:
+ if (!readNumberObject(deserializer))
+ return false;
+ break;
+ case BlobTag:
+ if (!readBlob(deserializer))
+ return false;
+ break;
+ case FileTag:
+ if (!readFile(deserializer))
+ return false;
+ break;
+ case FileListTag:
+ if (!readFileList(deserializer))
+ return false;
+ break;
+ case ImageDataTag:
+ if (!readImageData(deserializer))
+ return false;
+ break;
+ case ArrayTag: {
+ uint32_t length;
+ if (!doReadUint32(&length))
+ return false;
+ if (!deserializer.pushArray(length))
+ return false;
+ break;
+ }
+ case RegExpTag:
+ if (!readRegExp(deserializer))
+ return false;
+ break;
+ case ObjectTag: {
+ uint32_t numProperties;
+ if (!doReadUint32(&numProperties))
+ return false;
+ if (!deserializer.pushObject(numProperties))
+ return false;
+ break;
+ }
+ case SparseArrayTag: {
+ uint32_t numProperties;
+ uint32_t length;
+ if (!doReadUint32(&numProperties))
+ return false;
+ if (!doReadUint32(&length))
+ return false;
+ if (!deserializer.pushSparseArray(numProperties, length))
+ return false;
+ break;
+ }
+ case ArrayBufferViewTag: {
+ if (m_version <= 0)
+ return false;
+ if (!readArrayBufferView(deserializer))
+ return false;
+ break;
+ }
+ case ArrayBufferTag: {
+ if (m_version <= 0)
+ return false;
+ if (!readArrayBuffer(deserializer))
+ return false;
+ break;
+ }
+ case GenerateFreshObjectTag: {
+ if (m_version <= 0)
+ return false;
+ if (!deserializer.newObject())
+ return false;
+ break;
+ }
+ case GenerateFreshArrayTag: {
+ if (m_version <= 0)
+ return false;
+ uint32_t length;
+ if (!doReadUint32(&length))
+ return false;
+ if (!deserializer.newArray(length))
+ return false;
+ break;
+ }
+ // FIXMEDART: uncomment this.
+ /*
+ case MessagePortTag: {
+ if (m_version <= 0)
+ return false;
+ uint32_t index;
+ if (!doReadUint32(&index))
+ return false;
+ if (!deserializer.tryGetTransferredMessagePort(index, value))
+ return false;
+ break;
+ }
+ */
+ case ObjectReferenceTag: {
+ if (m_version <= 0)
+ return false;
+ uint32_t reference;
+ if (!doReadUint32(&reference))
+ return false;
+ if (!deserializer.tryGetObjectFromObjectReference(reference))
+ return false;
+ break;
+ }
+ default:
return false;
- break;
- }
- default:
- return false;
+ }
}
- return !value->IsEmpty();
+
+ return true;
}
+private:
+ bool isEof() const { return m_position >= m_length; }
+
bool readVersion(uint32_t& version)
{
SerializationTag tag;
@@ -1344,12 +1335,6 @@ public:
return doReadUint32(&version);
}
- void setVersion(uint32_t version)
- {
- m_version = version;
- }
-
-private:
bool readTag(SerializationTag* tag)
{
if (m_position >= m_length)
@@ -1372,24 +1357,25 @@ private:
return true;
}
- bool readString(v8::Handle<v8::Value>* value)
+ bool readString(ScriptValueDeserializer& deserializer)
{
uint32_t length;
if (!doReadUint32(&length))
return false;
if (m_position + length > m_length)
return false;
- *value = v8::String::New(reinterpret_cast<const char*>(m_buffer + m_position), length);
+ const char* data = reinterpret_cast<const char*>(m_buffer + m_position);
m_position += length;
- return true;
+ return deserializer.pushScriptString(data, length);
}
- bool readStringObject(v8::Handle<v8::Value>* value)
+ bool readStringObject(ScriptValueDeserializer& deserializer)
{
- v8::Handle<v8::Value> stringValue;
- if (!readString(&stringValue) || !stringValue->IsString())
+ if (!readString(deserializer))
+ return false;
+ if (!deserializer.pushScriptStringObject())
return false;
- *value = v8::StringObject::New(stringValue.As<v8::String>());
+ deserializer.addReferenceForTop();
return true;
}
@@ -1405,52 +1391,53 @@ private:
return true;
}
- bool readInt32(v8::Handle<v8::Value>* value)
+ bool readInt32(ScriptValueDeserializer& deserializer)
{
uint32_t rawValue;
if (!doReadUint32(&rawValue))
return false;
- *value = v8::Integer::New(static_cast<int32_t>(ZigZag::decode(rawValue)));
- return true;
+ return deserializer.pushInt32(static_cast<int32_t>(ZigZag::decode(rawValue)));
}
- bool readUint32(v8::Handle<v8::Value>* value)
+ bool readUint32(ScriptValueDeserializer& deserializer)
{
uint32_t rawValue;
if (!doReadUint32(&rawValue))
return false;
- *value = v8::Integer::NewFromUnsigned(rawValue);
- return true;
+ return deserializer.pushUInt32(rawValue);
}
- bool readDate(v8::Handle<v8::Value>* value)
+ bool readDate(ScriptValueDeserializer& deserializer)
{
double numberValue;
if (!doReadNumber(&numberValue))
return false;
- *value = v8::Date::New(numberValue);
+ if (!deserializer.pushDate(numberValue))
+ return false;
+ deserializer.addReferenceForTop();
return true;
}
- bool readNumber(v8::Handle<v8::Value>* value)
+ bool readNumber(ScriptValueDeserializer& deserializer)
{
double number;
if (!doReadNumber(&number))
return false;
- *value = v8::Number::New(number);
- return true;
+ return deserializer.pushNumber(number);
}
-
- bool readNumberObject(v8::Handle<v8::Value>* value)
+
+ bool readNumberObject(ScriptValueDeserializer& deserializer)
{
double number;
if (!doReadNumber(&number))
return false;
- *value = v8::NumberObject::New(number);
+ if (!deserializer.pushNumberObject(number))
+ return false;
+ deserializer.addReferenceForTop();
return true;
}
- bool readImageData(v8::Handle<v8::Value>* value)
+ bool readImageData(ScriptValueDeserializer& deserializer)
{
uint32_t width;
uint32_t height;
@@ -1469,7 +1456,9 @@ private:
ASSERT(pixelArray->length() >= pixelDataLength);
memcpy(pixelArray->data(), m_buffer + m_position, pixelDataLength);
m_position += pixelDataLength;
- *value = toV8(imageData.release());
+ if (!deserializer.pushImageData(imageData))
+ return false;
+ deserializer.addReferenceForTop();
return true;
}
@@ -1486,107 +1475,115 @@ private:
return arrayBuffer.release();
}
- bool readArrayBuffer(v8::Handle<v8::Value>* value)
+ bool readArrayBuffer(ScriptValueDeserializer& deserializer)
{
RefPtr<ArrayBuffer> arrayBuffer = doReadArrayBuffer();
if (!arrayBuffer)
return false;
- *value = toV8(arrayBuffer.release());
+ if (!deserializer.pushArrayBuffer(arrayBuffer))
+ return false;
+ deserializer.addReferenceForTop();
return true;
}
- bool readArrayBufferView(v8::Handle<v8::Value>* value, CompositeCreator& creator)
+ bool readArrayBufferView(ScriptValueDeserializer& deserializer)
{
ArrayBufferViewSubTag subTag;
uint32_t byteOffset;
uint32_t byteLength;
RefPtr<ArrayBuffer> arrayBuffer;
- v8::Handle<v8::Value> arrayBufferV8Value;
if (!readArrayBufferViewSubTag(&subTag))
return false;
if (!doReadUint32(&byteOffset))
return false;
if (!doReadUint32(&byteLength))
return false;
- if (!creator.consumeTopOfStack(&arrayBufferV8Value))
- return false;
- arrayBuffer = V8ArrayBuffer::toNative(arrayBufferV8Value.As<v8::Object>());
- if (!arrayBuffer)
- return false;
switch (subTag) {
case ByteArrayTag:
- *value = toV8(Int8Array::create(arrayBuffer.release(), byteOffset, byteLength));
- break;
+ if (!deserializer.pushInt8Array(byteOffset, byteLength))
+ return false;
+ deserializer.addReferenceForTop();
+ return true;
case UnsignedByteArrayTag:
- *value = toV8(Uint8Array::create(arrayBuffer.release(), byteOffset, byteLength));
- break;
+ return deserializer.pushUint8Array(byteOffset, byteLength);
case ShortArrayTag: {
uint32_t shortLength = byteLength / sizeof(int16_t);
if (shortLength * sizeof(int16_t) != byteLength)
return false;
- *value = toV8(Int16Array::create(arrayBuffer.release(), byteOffset, shortLength));
- break;
+ if (!deserializer.pushInt16Array(byteOffset, byteLength))
+ return false;
+ deserializer.addReferenceForTop();
+ return true;
}
case UnsignedShortArrayTag: {
uint32_t shortLength = byteLength / sizeof(uint16_t);
if (shortLength * sizeof(uint16_t) != byteLength)
return false;
- *value = toV8(Uint16Array::create(arrayBuffer.release(), byteOffset, shortLength));
- break;
+ if (!deserializer.pushUint16Array(byteOffset, byteLength))
+ return false;
+ deserializer.addReferenceForTop();
+ return true;
}
case IntArrayTag: {
uint32_t intLength = byteLength / sizeof(int32_t);
if (intLength * sizeof(int32_t) != byteLength)
return false;
- *value = toV8(Int32Array::create(arrayBuffer.release(), byteOffset, intLength));
- break;
+ if (!deserializer.pushInt32Array(byteOffset, byteLength))
+ return false;
+ deserializer.addReferenceForTop();
+ return true;
}
case UnsignedIntArrayTag: {
uint32_t intLength = byteLength / sizeof(uint32_t);
if (intLength * sizeof(uint32_t) != byteLength)
return false;
- *value = toV8(Uint32Array::create(arrayBuffer.release(), byteOffset, intLength));
- break;
+ if (!deserializer.pushUint32Array(byteOffset, byteLength))
+ return false;
+ deserializer.addReferenceForTop();
+ return true;
}
case FloatArrayTag: {
uint32_t floatLength = byteLength / sizeof(float);
if (floatLength * sizeof(float) != byteLength)
return false;
- *value = toV8(Float32Array::create(arrayBuffer.release(), byteOffset, floatLength));
- break;
+ if (!deserializer.pushFloat32Array(byteOffset, byteLength))
+ return false;
+ deserializer.addReferenceForTop();
+ return true;
}
case DoubleArrayTag: {
uint32_t floatLength = byteLength / sizeof(double);
if (floatLength * sizeof(double) != byteLength)
return false;
- *value = toV8(Float64Array::create(arrayBuffer.release(), byteOffset, floatLength));
- break;
+ if (!deserializer.pushFloat64Array(byteOffset, byteLength))
+ return false;
+ deserializer.addReferenceForTop();
+ return true;
}
case DataViewTag:
- *value = toV8(DataView::create(arrayBuffer.release(), byteOffset, byteLength));
- break;
+ if (!deserializer.pushDataView(byteOffset, byteLength))
+ return false;
+ deserializer.addReferenceForTop();
+ return true;
default:
return false;
}
- // The various *Array::create() methods will return null if the range the view expects is
- // mismatched with the range the buffer can provide or if the byte offset is not aligned
- // to the size of the element type.
- return !value->IsEmpty();
}
- bool readRegExp(v8::Handle<v8::Value>* value)
+ bool readRegExp(ScriptValueDeserializer& deserializer)
{
- v8::Handle<v8::Value> pattern;
- if (!readString(&pattern))
+ if (!readString(deserializer))
return false;
uint32_t flags;
if (!doReadUint32(&flags))
return false;
- *value = v8::RegExp::New(pattern.As<v8::String>(), static_cast<v8::RegExp::Flags>(flags));
+ if (!deserializer.pushRegExp(flags))
+ return false;
+ deserializer.addReferenceForTop();
return true;
}
- bool readBlob(v8::Handle<v8::Value>* value)
+ bool readBlob(ScriptValueDeserializer& deserializer)
{
String url;
String type;
@@ -1597,12 +1594,13 @@ private:
return false;
if (!doReadUint64(&size))
return false;
- PassRefPtr<Blob> blob = Blob::create(KURL(ParsedURLString, url), type, size);
- *value = toV8(blob);
+ if (!deserializer.pushBlob(Blob::create(KURL(ParsedURLString, url), type, size)))
+ return false;
+ deserializer.addReferenceForTop();
return true;
}
- bool readFile(v8::Handle<v8::Value>* value)
+ bool readFile(ScriptValueDeserializer& deserializer)
{
String path;
String url;
@@ -1613,17 +1611,18 @@ private:
return false;
if (!readWebCoreString(&type))
return false;
- PassRefPtr<File> file = File::create(path, KURL(ParsedURLString, url), type);
- *value = toV8(file);
+ if (!deserializer.pushFile(File::create(path, KURL(ParsedURLString, url), type)))
+ return false;
+ deserializer.addReferenceForTop();
return true;
}
- bool readFileList(v8::Handle<v8::Value>* value)
+ bool readFileList(ScriptValueDeserializer& deserializer)
{
uint32_t length;
if (!doReadUint32(&length))
return false;
- PassRefPtr<FileList> fileList = FileList::create();
+ RefPtr<FileList> fileList = FileList::create();
for (unsigned i = 0; i < length; ++i) {
String path;
String urlString;
@@ -1636,7 +1635,9 @@ private:
return false;
fileList->append(File::create(path, KURL(ParsedURLString, urlString), type));
}
- *value = toV8(fileList);
+ if (!deserializer.pushFileList(fileList))
+ return false;
+ deserializer.addReferenceForTop();
return true;
}
@@ -1682,9 +1683,9 @@ private:
uint32_t m_version;
};
-class Deserializer : public CompositeCreator {
+class V8Deserializer : public ScriptValueDeserializer {
public:
- explicit Deserializer(Reader& reader, MessagePortArray* messagePorts)
+ explicit V8Deserializer(Reader& reader, MessagePortArray* messagePorts)
: m_reader(reader)
, m_transferredMessagePorts(messagePorts)
, m_version(0)
@@ -1693,18 +1694,12 @@ public:
v8::Handle<v8::Value> deserialize()
{
- if (!m_reader.readVersion(m_version) || m_version > wireFormatVersion)
- return v8::Null();
- m_reader.setVersion(m_version);
v8::HandleScope scope;
- while (!m_reader.isEof()) {
- if (!doDeserialize())
- return v8::Null();
- }
+ if (!m_reader.read(*this))
+ return v8::Null();
if (stackDepth() != 1 || m_openCompositeReferenceStack.size())
return v8::Null();
- v8::Handle<v8::Value> result = scope.Close(element(0));
- return result;
+ return scope.Close(element(0));
}
virtual bool newArray(uint32_t length)
@@ -1716,21 +1711,78 @@ public:
return true;
}
- virtual bool consumeTopOfStack(v8::Handle<v8::Value>* object)
+ virtual bool newObject()
{
- if (stackDepth() < 1)
+ v8::Local<v8::Object> object = v8::Object::New();
+ if (object.IsEmpty())
return false;
- *object = element(stackDepth() - 1);
- pop(1);
+ openComposite(object);
+ return true;
+ }
+
+ virtual bool tryGetObjectFromObjectReference(uint32_t reference)
+ {
+ if (reference >= m_objectPool.size())
+ return false;
+ v8::Handle<v8::Value> value = m_objectPool[reference];
+ ASSERT(!value.IsEmpty());
+ return push(value);
+ }
+
+ virtual bool tryGetTransferredMessagePort(uint32_t index, v8::Handle<v8::Value>* object)
+ {
+ if (!m_transferredMessagePorts)
+ return false;
+ if (index >= m_transferredMessagePorts->size())
+ return false;
+ *object = V8MessagePort::wrap(m_transferredMessagePorts->at(index).get());
return true;
}
- virtual bool completeArray(uint32_t length, v8::Handle<v8::Value>* value)
+ virtual uint32_t objectReferenceCount()
+ {
+ return m_objectPool.size();
+ }
+
+ virtual void addReferenceForTop()
+ {
+ ASSERT(stackDepth() > 0);
+ v8::Handle<v8::Value> value = element(stackDepth() - 1);
+ ASSERT(!value.IsEmpty());
+ m_objectPool.append(value);
+ }
+
+
+ virtual bool pushUndefined() { return push(v8::Undefined()); }
+ virtual bool pushNull() { return push(v8::Null()); }
+ virtual bool pushTrue() { return push(v8::True()); }
+ virtual bool pushTrueObject() { return push(v8::BooleanObject::New(true)); }
+ virtual bool pushFalse() { return push(v8::False()); }
+ virtual bool pushFalseObject() { return push(v8::BooleanObject::New(false)); }
+ virtual bool pushScriptString(const char* data, uint32_t length) { return push(v8::String::New(data, length)); }
+ virtual bool pushScriptStringObject()
+ {
+ if (stackDepth() < 1)
+ return false;
+ v8::Handle<v8::Value> string = popValue();
+ return push(v8::StringObject::New(string.As<v8::String>()));
+ }
+ virtual bool pushInt32(int32_t value) { return push(v8::Integer::New(value)); }
+ virtual bool pushUInt32(uint32_t value) { return push(v8::Integer::NewFromUnsigned(value)); }
+ virtual bool pushDate(double numberValue) { return push(v8::Date::New(numberValue)); }
+ virtual bool pushNumber(double value) { return push(v8::Number::New(value)); }
+ virtual bool pushNumberObject(double value) { return push(v8::NumberObject::New(value)); }
+ virtual bool pushBlob(PassRefPtr<Blob> blob) { return push(toV8(blob)); }
+ virtual bool pushFile(PassRefPtr<File> file) { return push(toV8(file)); }
+ virtual bool pushFileList(PassRefPtr<FileList> fileList) { return push(toV8(fileList)); }
+ virtual bool pushImageData(PassRefPtr<ImageData> imageData) { return push(toV8(imageData)); }
+
+ virtual bool pushArray(uint32_t length)
{
if (length > stackDepth())
return false;
v8::Local<v8::Array> array;
- if (m_version > 0) {
+ if (m_reader.version() > 0) {
v8::Local<v8::Value> composite;
if (!closeComposite(&composite))
return false;
@@ -1744,23 +1796,21 @@ public:
for (unsigned i = 0; i < length; ++i)
array->Set(i, element(depth + i));
pop(length);
- *value = array;
- return true;
+ return push(array);
}
- virtual bool newObject()
+ virtual bool pushRegExp(uint32_t flags)
{
- v8::Local<v8::Object> object = v8::Object::New();
- if (object.IsEmpty())
+ if (stackDepth() < 1)
return false;
- openComposite(object);
- return true;
+ v8::Handle<v8::Value> pattern = popValue();
+ return push(v8::RegExp::New(pattern.As<v8::String>(), static_cast<v8::RegExp::Flags>(flags)));
}
- virtual bool completeObject(uint32_t numProperties, v8::Handle<v8::Value>* value)
+ virtual bool pushObject(uint32_t numProperties)
{
v8::Local<v8::Object> object;
- if (m_version > 0) {
+ if (m_reader.version() > 0) {
v8::Local<v8::Value> composite;
if (!closeComposite(&composite))
return false;
@@ -1769,13 +1819,13 @@ public:
object = v8::Object::New();
if (object.IsEmpty())
return false;
- return initializeObject(object, numProperties, value);
+ return initializeObject(object, numProperties);
}
- virtual bool completeSparseArray(uint32_t numProperties, uint32_t length, v8::Handle<v8::Value>* value)
+ virtual bool pushSparseArray(uint32_t numProperties, uint32_t length)
{
v8::Local<v8::Array> array;
- if (m_version > 0) {
+ if (m_reader.version() > 0) {
v8::Local<v8::Value> composite;
if (!closeComposite(&composite))
return false;
@@ -1784,74 +1834,76 @@ public:
array = v8::Array::New(length);
if (array.IsEmpty())
return false;
- return initializeObject(array, numProperties, value);
+ return initializeObject(array, numProperties);
}
- virtual void pushObjectReference(const v8::Handle<v8::Value>& object)
- {
- m_objectPool.append(object);
- }
+ virtual bool pushInt8Array(uint32_t byteOffset, uint32_t byteLength) { return pushTypedArray<Int8Array>(byteOffset, byteLength); }
+ virtual bool pushUint8Array(uint32_t byteOffset, uint32_t byteLength) { return pushTypedArray<Uint8Array>(byteOffset, byteLength); }
+ virtual bool pushInt16Array(uint32_t byteOffset, uint32_t byteLength) { return pushTypedArray<Int16Array>(byteOffset, byteLength); }
+ virtual bool pushUint16Array(uint32_t byteOffset, uint32_t byteLength) { return pushTypedArray<Uint16Array>(byteOffset, byteLength); }
+ virtual bool pushInt32Array(uint32_t byteOffset, uint32_t byteLength) { return pushTypedArray<Int32Array>(byteOffset, byteLength); }
+ virtual bool pushUint32Array(uint32_t byteOffset, uint32_t byteLength) { return pushTypedArray<Uint32Array>(byteOffset, byteLength); }
+ virtual bool pushFloat32Array(uint32_t byteOffset, uint32_t byteLength) { return pushTypedArray<Float32Array>(byteOffset, byteLength); }
+ virtual bool pushFloat64Array(uint32_t byteOffset, uint32_t byteLength) { return pushTypedArray<Float64Array>(byteOffset, byteLength); }
+ virtual bool pushDataView(uint32_t byteOffset, uint32_t byteLength) { return pushTypedArray<DataView>(byteOffset, byteLength); }
+ virtual bool pushArrayBuffer(PassRefPtr<ArrayBuffer> arrayBuffer) { return push(toV8(arrayBuffer)); }
- virtual bool tryGetTransferredMessagePort(uint32_t index, v8::Handle<v8::Value>* object)
+private:
+ template <class C>
+ bool pushTypedArray(uint32_t byteOffset, uint32_t byteLength)
{
- if (!m_transferredMessagePorts)
- return false;
- if (index >= m_transferredMessagePorts->size())
+ if (stackDepth() < 1)
return false;
- *object = V8MessagePort::wrap(m_transferredMessagePorts->at(index).get());
- return true;
- }
-
- virtual bool tryGetObjectFromObjectReference(uint32_t reference, v8::Handle<v8::Value>* object)
- {
- if (reference >= m_objectPool.size())
+ RefPtr<ArrayBuffer> arrayBuffer = V8ArrayBuffer::toNative(popValue().As<v8::Object>());
+ if (!arrayBuffer)
return false;
- *object = m_objectPool[reference];
- return object;
- }
- virtual uint32_t objectReferenceCount()
- {
- return m_objectPool.size();
+ // The various *Array::create() methods will return null if the range the view expects is
+ // mismatched with the range the buffer can provide or if the byte offset is not aligned
+ // to the size of the element type.
+ return push(toV8(C::create(arrayBuffer.release(), byteOffset, byteLength)));
}
-private:
- bool initializeObject(v8::Handle<v8::Object> object, uint32_t numProperties, v8::Handle<v8::Value>* value)
+ bool initializeObject(v8::Handle<v8::Object> object, uint32_t numProperties)
{
+ ASSERT(!object.IsEmpty());
unsigned length = 2 * numProperties;
if (length > stackDepth())
return false;
for (unsigned i = stackDepth() - length; i < stackDepth(); i += 2) {
- v8::Local<v8::Value> propertyName = element(i);
- v8::Local<v8::Value> propertyValue = element(i + 1);
+ v8::Handle<v8::Value> propertyName = element(i);
+ v8::Handle<v8::Value> propertyValue = element(i + 1);
object->Set(propertyName, propertyValue);
}
pop(length);
- *value = object;
- return true;
+ return push(object);
}
- bool doDeserialize()
+ bool push(v8::Handle<v8::Value> value)
{
- v8::Local<v8::Value> value;
- if (!m_reader.read(&value, *this))
+ if (value.IsEmpty())
return false;
- if (!value.IsEmpty())
- push(value);
+ m_stack.append(value);
return true;
}
- void push(v8::Local<v8::Value> value) { m_stack.append(value); }
-
void pop(unsigned length)
{
ASSERT(length <= m_stack.size());
m_stack.shrink(m_stack.size() - length);
}
+ v8::Handle<v8::Value> popValue()
+ {
+ ASSERT(stackDepth() >= 1);
+ v8::Handle<v8::Value> top = element(stackDepth() - 1);
+ pop(1);
+ return top;
+ }
+
unsigned stackDepth() const { return m_stack.size(); }
- v8::Local<v8::Value> element(unsigned index)
+ v8::Handle<v8::Value> element(unsigned index)
{
ASSERT(index < m_stack.size());
return m_stack[index];
@@ -1877,7 +1929,7 @@ private:
}
Reader& m_reader;
- Vector<v8::Local<v8::Value> > m_stack;
+ Vector<v8::Handle<v8::Value> > m_stack;
Vector<v8::Handle<v8::Value> > m_objectPool;
Vector<uint32_t> m_openCompositeReferenceStack;
MessagePortArray* m_transferredMessagePorts;
@@ -2015,8 +2067,24 @@ v8::Handle<v8::Value> SerializedScriptValue::deserialize(MessagePortArray* messa
return v8::Null();
COMPILE_ASSERT(sizeof(BufferValueType) == 2, BufferValueTypeIsTwoBytes);
Reader reader(reinterpret_cast<const uint8_t*>(m_data.impl()->characters()), 2 * m_data.length());
- Deserializer deserializer(reader, messagePorts);
+ V8Deserializer deserializer(reader, messagePorts);
return deserializer.deserialize();
}
+PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(ScriptValueSerializer* serializer)
+{
+ Writer writer;
+ serializer->serialize(&writer);
+ return adoptRef(new SerializedScriptValue(StringImpl::adopt(writer.data())));
+}
+
+bool SerializedScriptValue::deserialize(ScriptValueDeserializer* deserializer)
+{
+ if (!m_data.impl())
+ return false;
+ COMPILE_ASSERT(sizeof(BufferValueType) == 2, BufferValueTypeIsTwoBytes);
+ Reader reader(reinterpret_cast<const uint8_t*>(m_data.impl()->characters()), 2 * m_data.length());
+ return reader.read(*deserializer);
+}
+
} // namespace WebCore

Powered by Google App Engine
This is Rietveld 408576698