diff options
Diffstat (limited to 'WebCore/bindings/js/SerializedScriptValue.cpp')
-rw-r--r-- | WebCore/bindings/js/SerializedScriptValue.cpp | 87 |
1 files changed, 74 insertions, 13 deletions
diff --git a/WebCore/bindings/js/SerializedScriptValue.cpp b/WebCore/bindings/js/SerializedScriptValue.cpp index 7c4ad62..fd9cb59 100644 --- a/WebCore/bindings/js/SerializedScriptValue.cpp +++ b/WebCore/bindings/js/SerializedScriptValue.cpp @@ -28,12 +28,14 @@ #include "SerializedScriptValue.h" #include "File.h" +#include "FileList.h" #include "JSDOMGlobalObject.h" #include "JSFile.h" #include "JSFileList.h" #include <JavaScriptCore/APICast.h> #include <runtime/DateInstance.h> #include <runtime/ExceptionHelpers.h> +#include <runtime/JSLock.h> #include <runtime/PropertyNameArray.h> #include <wtf/HashTraits.h> #include <wtf/Vector.h> @@ -141,6 +143,28 @@ private: unsigned m_length; }; +class SerializedFileList : public SharedSerializedData { +public: + static PassRefPtr<SerializedFileList> create(const FileList* list) + { + return adoptRef(new SerializedFileList(list)); + } + + unsigned length() const { return m_files.size(); } + const String& item(unsigned idx) { return m_files[idx]; } + +private: + SerializedFileList(const FileList* list) + { + unsigned length = list->length(); + m_files.reserveCapacity(length); + for (unsigned i = 0; i < length; i++) + m_files.append(list->item(i)->path().crossThreadString()); + } + + Vector<String> m_files; +}; + SerializedScriptValueData::SerializedScriptValueData(RefPtr<SerializedObject> data) : m_type(ObjectType) , m_sharedData(data) @@ -153,6 +177,12 @@ SerializedScriptValueData::SerializedScriptValueData(RefPtr<SerializedArray> dat { } +SerializedScriptValueData::SerializedScriptValueData(const FileList* fileList) + : m_type(FileListType) + , m_sharedData(SerializedFileList::create(fileList)) +{ +} + SerializedScriptValueData::SerializedScriptValueData(const File* file) : m_type(FileType) , m_string(file->path().crossThreadString()) @@ -169,6 +199,11 @@ SerializedObject* SharedSerializedData::asObject() return static_cast<SerializedObject*>(this); } +SerializedFileList* SharedSerializedData::asFileList() +{ + return static_cast<SerializedFileList*>(this); +} + static const unsigned maximumFilterRecursion = 40000; enum WalkerState { StateUnknown, ArrayStartState, ArrayStartVisitMember, ArrayEndVisitMember, ObjectStartState, ObjectStartVisitMember, ObjectEndVisitMember }; @@ -496,6 +531,8 @@ struct SerializingTreeWalker : public BaseWalker { JSObject* obj = asObject(value); if (obj->inherits(&JSFile::s_info)) return SerializedScriptValueData(toFile(obj)); + if (obj->inherits(&JSFileList::s_info)) + return SerializedScriptValueData(toFileList(obj)); CallData unusedData; if (value.getCallData(unusedData) == CallTypeNone) @@ -575,8 +612,10 @@ struct DeserializingTreeWalker : public BaseWalker { typedef JSObject* OutputObject; typedef SerializedObject::PropertyNameList PropertyList; - DeserializingTreeWalker(ExecState* exec, bool mustCopy) + DeserializingTreeWalker(ExecState* exec, JSGlobalObject* globalObject, bool mustCopy) : BaseWalker(exec) + , m_globalObject(globalObject) + , m_isDOMGlobalObject(globalObject->inherits(&JSDOMGlobalObject::s_info)) , m_mustCopy(mustCopy) { } @@ -605,14 +644,14 @@ struct DeserializingTreeWalker : public BaseWalker { JSArray* createOutputArray(unsigned length) { - JSArray* array = constructEmptyArray(m_exec); + JSArray* array = constructEmptyArray(m_exec, m_globalObject); array->setLength(length); return array; } JSObject* createOutputObject() { - return constructEmptyObject(m_exec); + return constructEmptyObject(m_exec, m_globalObject); } uint32_t length(RefPtr<SerializedArray> array) @@ -655,13 +694,27 @@ struct DeserializingTreeWalker : public BaseWalker { case SerializedScriptValueData::NumberType: return jsNumber(m_exec, value.asDouble()); case SerializedScriptValueData::DateType: - return new (m_exec) DateInstance(m_exec, value.asDouble()); + return new (m_exec) DateInstance(m_exec, m_globalObject->dateStructure(), value.asDouble()); case SerializedScriptValueData::FileType: - return toJS(m_exec, static_cast<JSDOMGlobalObject*>(m_exec->lexicalGlobalObject()), File::create(value.asString().crossThreadString())); - default: + if (!m_isDOMGlobalObject) + return jsNull(); + return toJS(m_exec, static_cast<JSDOMGlobalObject*>(m_globalObject), File::create(value.asString().crossThreadString())); + case SerializedScriptValueData::FileListType: { + if (!m_isDOMGlobalObject) + return jsNull(); + RefPtr<FileList> result = FileList::create(); + SerializedFileList* serializedFileList = value.asFileList(); + unsigned length = serializedFileList->length(); + for (unsigned i = 0; i < length; i++) + result->append(File::create(serializedFileList->item(i))); + return toJS(m_exec, static_cast<JSDOMGlobalObject*>(m_globalObject), result.get()); + } + case SerializedScriptValueData::EmptyType: ASSERT_NOT_REACHED(); - return JSValue(); + return jsNull(); } + ASSERT_NOT_REACHED(); + return jsNull(); } void getPropertyNames(RefPtr<SerializedObject> object, Vector<SerializedObject::PropertyNameList, 16>& properties) @@ -699,12 +752,15 @@ struct DeserializingTreeWalker : public BaseWalker { } private: + void* operator new(size_t); + JSGlobalObject* m_globalObject; + bool m_isDOMGlobalObject; bool m_mustCopy; }; -JSValue SerializedScriptValueData::deserialize(ExecState* exec, bool mustCopy) const +JSValue SerializedScriptValueData::deserialize(ExecState* exec, JSGlobalObject* global, bool mustCopy) const { - DeserializingTreeWalker context(exec, mustCopy); + DeserializingTreeWalker context(exec, global, mustCopy); return walk<DeserializingTreeWalker>(context, *this); } @@ -808,11 +864,14 @@ struct TeardownTreeWalker { case SerializedScriptValueData::StringType: case SerializedScriptValueData::ImmediateType: case SerializedScriptValueData::NumberType: + case SerializedScriptValueData::DateType: + case SerializedScriptValueData::EmptyType: + case SerializedScriptValueData::FileType: + case SerializedScriptValueData::FileListType: return true; - default: - ASSERT_NOT_REACHED(); - return JSValue(); } + ASSERT_NOT_REACHED(); + return true; } void getPropertyNames(RefPtr<SerializedObject> object, Vector<SerializedObject::PropertyNameList, 16>& properties) @@ -860,6 +919,7 @@ SerializedScriptValue::~SerializedScriptValue() PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(JSContextRef originContext, JSValueRef apiValue, JSValueRef* exception) { + JSLock lock(SilenceAssertionsOnly); ExecState* exec = toJS(originContext); JSValue value = toJS(exec, apiValue); PassRefPtr<SerializedScriptValue> serializedValue = SerializedScriptValue::create(exec, value); @@ -875,8 +935,9 @@ PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(JSContextRef ori JSValueRef SerializedScriptValue::deserialize(JSContextRef destinationContext, JSValueRef* exception) { + JSLock lock(SilenceAssertionsOnly); ExecState* exec = toJS(destinationContext); - JSValue value = deserialize(exec); + JSValue value = deserialize(exec, exec->lexicalGlobalObject()); if (exec->hadException()) { if (exception) *exception = toRef(exec, exec->exception()); |