Simplify SerializedScriptValue, MessagePortArray and ArrayBufferArray to ease generation
authorweinig@apple.com <weinig@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 19 Oct 2016 00:05:09 +0000 (00:05 +0000)
committerweinig@apple.com <weinig@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 19 Oct 2016 00:05:09 +0000 (00:05 +0000)
https://bugs.webkit.org/show_bug.cgi?id=163625

Reviewed by Chris Dumez.

- Replace uses of MessagePortArray (a.k.a. Vector<RefPtr<MessagePort>, 1>) with Vector<RefPtr<MessagePort>>.
- Replace uses of ArrayBufferArray (a.k.a. Vector<RefPtr<ArrayBuffer>, 1>) with Vector<RefPtr<ArrayBuffer>>.
- Add convenience functions to SerializedScriptValue to allow calling with fewer parameters.
- Move MessagePorts and ArrayBuffers more where possible.

* Modules/indexeddb/IDBObjectStore.cpp:
(WebCore::IDBObjectStore::putOrAdd):
* Modules/indexeddb/server/UniqueIDBDatabase.cpp:
(WebCore::IDBServer::UniqueIDBDatabase::performPutOrAdd):
* bindings/js/IDBBindingUtilities.cpp:
(WebCore::deserializeIDBValueToJSValue):
* bindings/js/JSCustomEventCustom.cpp:
(WebCore::JSCustomEvent::detail):
* bindings/js/JSHistoryCustom.cpp:
(WebCore::JSHistory::state):
(WebCore::JSHistory::pushState):
(WebCore::JSHistory::replaceState):
* bindings/js/JSPopStateEventCustom.cpp:
(WebCore::JSPopStateEvent::state):
* dom/CustomEvent.cpp:
(WebCore::CustomEvent::trySerializeDetail):
* dom/ErrorEvent.cpp:
(WebCore::ErrorEvent::sanitizedErrorValue):
(WebCore::ErrorEvent::trySerializeError):
* dom/PopStateEvent.cpp:
(WebCore::PopStateEvent::trySerializeState):
* page/DOMWindow.cpp:
(WebCore::DOMWindow::postMessage):
* page/DOMWindow.h:
* workers/DedicatedWorkerGlobalScope.cpp:
(WebCore::DedicatedWorkerGlobalScope::postMessage):
* workers/DedicatedWorkerGlobalScope.h:
* workers/Worker.cpp:
(WebCore::Worker::postMessage):
* workers/Worker.h:
* bindings/js/JSDOMWindowCustom.cpp:
(WebCore::handlePostMessage):
* bindings/js/JSDictionary.cpp:
(WebCore::JSDictionary::convertValue):
* bindings/js/JSDictionary.h:
Updated for new SerializedScriptValue interface/vector naming.

* bindings/js/JSMessageEventCustom.cpp:
(WebCore::handleInitMessageEvent):
Update handleInitMessageEvent to check for exceptions and use convert for the MessagePort sequence.

* bindings/js/JSMessagePortCustom.cpp:
(WebCore::extractTransferables):
(WebCore::fillMessagePortArray): Deleted.
* bindings/js/JSMessagePortCustom.h:
(WebCore::handlePostMessage):
Rename fillMessagePortArray to extractTransferables to better express what it does.

* bindings/js/SerializedScriptValue.cpp:
(WebCore::CloneSerializer::serialize):
(WebCore::CloneSerializer::CloneSerializer):
(WebCore::CloneSerializer::fillTransferMap):
(WebCore::CloneSerializer::dumpIfTerminal):
(WebCore::CloneDeserializer::deserialize):
(WebCore::CloneDeserializer::CloneDeserializer):
(WebCore::CloneDeserializer::readTerminal):
(WebCore::SerializedScriptValue::transferArrayBuffers):
(WebCore::SerializedScriptValue::create):
(WebCore::SerializedScriptValue::deserialize):
* bindings/js/SerializedScriptValue.h:
Simplify interface to allow more callers to avoid passing default arguments. Use ExecState& more.
* bindings/scripts/CodeGeneratorJS.pm:
(GetNativeVectorType):
Remove special case for MessagePort.
(JSValueToNative):
(NativeToJSValue):
Updated for new SerializedScriptValue interface.

* dom/MessageEvent.cpp:
(WebCore::MessageEvent::MessageEvent):
(WebCore::MessageEvent::create):
(WebCore::MessageEvent::initMessageEvent):
(WebCore::MessageEvent::trySerializeData):
* dom/MessageEvent.h:
Store the MessagePort sequence as a Vector<RefPtr<MessagePort>> rather than in a unique_ptr.

* dom/MessageEvent.idl:
Update last type in init functions to be sequence<MessagePort> rather than Array. They are still
custom, as we don't quite generate these correctly yet.

* dom/MessagePort.cpp:
(WebCore::MessagePort::postMessage):
(WebCore::MessagePort::dispatchMessages):
(WebCore::MessagePort::disentanglePorts):
(WebCore::MessagePort::entanglePorts):
* dom/MessagePort.h:
Update interface to take MessagePort vectors by rvalue reference.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@207505 268f45cc-cd09-0410-ab3c-d52691b4dbfc

30 files changed:
Source/WebCore/ChangeLog
Source/WebCore/Modules/indexeddb/IDBObjectStore.cpp
Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp
Source/WebCore/bindings/js/IDBBindingUtilities.cpp
Source/WebCore/bindings/js/JSCustomEventCustom.cpp
Source/WebCore/bindings/js/JSDOMWindowCustom.cpp
Source/WebCore/bindings/js/JSDictionary.cpp
Source/WebCore/bindings/js/JSDictionary.h
Source/WebCore/bindings/js/JSHistoryCustom.cpp
Source/WebCore/bindings/js/JSMessageEventCustom.cpp
Source/WebCore/bindings/js/JSMessagePortCustom.cpp
Source/WebCore/bindings/js/JSMessagePortCustom.h
Source/WebCore/bindings/js/JSPopStateEventCustom.cpp
Source/WebCore/bindings/js/SerializedScriptValue.cpp
Source/WebCore/bindings/js/SerializedScriptValue.h
Source/WebCore/bindings/scripts/CodeGeneratorJS.pm
Source/WebCore/dom/CustomEvent.cpp
Source/WebCore/dom/ErrorEvent.cpp
Source/WebCore/dom/MessageEvent.cpp
Source/WebCore/dom/MessageEvent.h
Source/WebCore/dom/MessageEvent.idl
Source/WebCore/dom/MessagePort.cpp
Source/WebCore/dom/MessagePort.h
Source/WebCore/dom/PopStateEvent.cpp
Source/WebCore/page/DOMWindow.cpp
Source/WebCore/page/DOMWindow.h
Source/WebCore/workers/DedicatedWorkerGlobalScope.cpp
Source/WebCore/workers/DedicatedWorkerGlobalScope.h
Source/WebCore/workers/Worker.cpp
Source/WebCore/workers/Worker.h

index 583b95f..ccfc0de 100644 (file)
@@ -1,3 +1,103 @@
+2016-10-18  Sam Weinig  <sam@webkit.org>
+
+        Simplify SerializedScriptValue, MessagePortArray and ArrayBufferArray to ease generation
+        https://bugs.webkit.org/show_bug.cgi?id=163625
+
+        Reviewed by Chris Dumez.
+
+        - Replace uses of MessagePortArray (a.k.a. Vector<RefPtr<MessagePort>, 1>) with Vector<RefPtr<MessagePort>>.
+        - Replace uses of ArrayBufferArray (a.k.a. Vector<RefPtr<ArrayBuffer>, 1>) with Vector<RefPtr<ArrayBuffer>>.
+        - Add convenience functions to SerializedScriptValue to allow calling with fewer parameters.
+        - Move MessagePorts and ArrayBuffers more where possible.
+
+        * Modules/indexeddb/IDBObjectStore.cpp:
+        (WebCore::IDBObjectStore::putOrAdd):
+        * Modules/indexeddb/server/UniqueIDBDatabase.cpp:
+        (WebCore::IDBServer::UniqueIDBDatabase::performPutOrAdd):
+        * bindings/js/IDBBindingUtilities.cpp:
+        (WebCore::deserializeIDBValueToJSValue):
+        * bindings/js/JSCustomEventCustom.cpp:
+        (WebCore::JSCustomEvent::detail):
+        * bindings/js/JSHistoryCustom.cpp:
+        (WebCore::JSHistory::state):
+        (WebCore::JSHistory::pushState):
+        (WebCore::JSHistory::replaceState):
+        * bindings/js/JSPopStateEventCustom.cpp:
+        (WebCore::JSPopStateEvent::state):
+        * dom/CustomEvent.cpp:
+        (WebCore::CustomEvent::trySerializeDetail):
+        * dom/ErrorEvent.cpp:
+        (WebCore::ErrorEvent::sanitizedErrorValue):
+        (WebCore::ErrorEvent::trySerializeError):
+        * dom/PopStateEvent.cpp:
+        (WebCore::PopStateEvent::trySerializeState):
+        * page/DOMWindow.cpp:
+        (WebCore::DOMWindow::postMessage):
+        * page/DOMWindow.h:
+        * workers/DedicatedWorkerGlobalScope.cpp:
+        (WebCore::DedicatedWorkerGlobalScope::postMessage):
+        * workers/DedicatedWorkerGlobalScope.h:
+        * workers/Worker.cpp:
+        (WebCore::Worker::postMessage):
+        * workers/Worker.h:
+        * bindings/js/JSDOMWindowCustom.cpp:
+        (WebCore::handlePostMessage):
+        * bindings/js/JSDictionary.cpp:
+        (WebCore::JSDictionary::convertValue):
+        * bindings/js/JSDictionary.h:
+        Updated for new SerializedScriptValue interface/vector naming.
+
+        * bindings/js/JSMessageEventCustom.cpp:
+        (WebCore::handleInitMessageEvent):
+        Update handleInitMessageEvent to check for exceptions and use convert for the MessagePort sequence.
+
+        * bindings/js/JSMessagePortCustom.cpp:
+        (WebCore::extractTransferables):
+        (WebCore::fillMessagePortArray): Deleted.
+        * bindings/js/JSMessagePortCustom.h:
+        (WebCore::handlePostMessage):
+        Rename fillMessagePortArray to extractTransferables to better express what it does.
+
+        * bindings/js/SerializedScriptValue.cpp:
+        (WebCore::CloneSerializer::serialize):
+        (WebCore::CloneSerializer::CloneSerializer):
+        (WebCore::CloneSerializer::fillTransferMap):
+        (WebCore::CloneSerializer::dumpIfTerminal):
+        (WebCore::CloneDeserializer::deserialize):
+        (WebCore::CloneDeserializer::CloneDeserializer):
+        (WebCore::CloneDeserializer::readTerminal):
+        (WebCore::SerializedScriptValue::transferArrayBuffers):
+        (WebCore::SerializedScriptValue::create):
+        (WebCore::SerializedScriptValue::deserialize):
+        * bindings/js/SerializedScriptValue.h:
+        Simplify interface to allow more callers to avoid passing default arguments. Use ExecState& more.
+        * bindings/scripts/CodeGeneratorJS.pm:
+        (GetNativeVectorType):
+        Remove special case for MessagePort.
+        (JSValueToNative):
+        (NativeToJSValue):
+        Updated for new SerializedScriptValue interface.
+
+        * dom/MessageEvent.cpp:
+        (WebCore::MessageEvent::MessageEvent):
+        (WebCore::MessageEvent::create):
+        (WebCore::MessageEvent::initMessageEvent):
+        (WebCore::MessageEvent::trySerializeData):
+        * dom/MessageEvent.h:
+        Store the MessagePort sequence as a Vector<RefPtr<MessagePort>> rather than in a unique_ptr.
+
+        * dom/MessageEvent.idl:
+        Update last type in init functions to be sequence<MessagePort> rather than Array. They are still
+        custom, as we don't quite generate these correctly yet. 
+
+        * dom/MessagePort.cpp:
+        (WebCore::MessagePort::postMessage):
+        (WebCore::MessagePort::dispatchMessages):
+        (WebCore::MessagePort::disentanglePorts):
+        (WebCore::MessagePort::entanglePorts):
+        * dom/MessagePort.h:
+        Update interface to take MessagePort vectors by rvalue reference.
+
 2016-10-18  Chris Dumez  <cdumez@apple.com>
 
         [iOS] Drop JSDictionary::convertValue() overload taking a TouchList
index 94cd707..acc7976 100644 (file)
@@ -236,7 +236,7 @@ ExceptionOr<Ref<IDBRequest>> IDBObjectStore::putOrAdd(ExecState& state, JSValue
     if (m_transaction->isReadOnly())
         return Exception { IDBDatabaseException::ReadOnlyError, ASCIILiteral("Failed to store record in an IDBObjectStore: The transaction is read-only.") };
 
-    RefPtr<SerializedScriptValue> serializedValue = SerializedScriptValue::create(&state, value, nullptr, nullptr);
+    auto serializedValue = SerializedScriptValue::create(state, value);
     if (UNLIKELY(scope.exception())) {
         // Clear the DOM exception from the serializer so we can give a more targeted exception.
         scope.clearException();
index d703f44..4082f48 100644 (file)
@@ -874,7 +874,7 @@ void UniqueIDBDatabase::performPutOrAdd(uint64_t callbackIdentifier, const IDBRe
             return;
         }
 
-        auto serializedValue = SerializedScriptValue::create(&databaseThreadExecState(), value, nullptr, nullptr);
+        auto serializedValue = SerializedScriptValue::create(databaseThreadExecState(), value);
         if (UNLIKELY(scope.exception())) {
             postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformPutOrAdd, callbackIdentifier, IDBError(IDBDatabaseException::ConstraintError, ASCIILiteral("Unable to serialize record value after injecting record key")), usedKey));
             return;
index b40213e..7d49187 100644 (file)
@@ -40,6 +40,7 @@
 #include "JSDOMConvert.h"
 #include "JSDOMStringList.h"
 #include "Logging.h"
+#include "MessagePort.h"
 #include "ScriptExecutionContext.h"
 #include "SerializedScriptValue.h"
 #include "SharedBuffer.h"
@@ -328,7 +329,8 @@ JSValue deserializeIDBValueToJSValue(ExecState& exec, const IDBValue& value)
     auto serializedValue = SerializedScriptValue::createFromWireBytes(Vector<uint8_t>(data));
 
     exec.vm().apiLock().lock();
-    JSValue result = serializedValue->deserialize(&exec, exec.lexicalGlobalObject(), 0, NonThrowing, value.blobURLs(), value.blobFilePaths());
+    Vector<RefPtr<MessagePort>> messagePorts;
+    JSValue result = serializedValue->deserialize(exec, exec.lexicalGlobalObject(), messagePorts, value.blobURLs(), value.blobFilePaths(), NonThrowing);
     exec.vm().apiLock().unlock();
 
     return result;
index f55a85b..8cfb769 100644 (file)
@@ -50,7 +50,7 @@ JSValue JSCustomEvent::detail(ExecState& state) const
         auto serializedDetail = event.trySerializeDetail(state);
         if (!serializedDetail)
             return jsNull();
-        return serializedDetail->deserialize(&state, globalObject(), nullptr);
+        return serializedDetail->deserialize(state, globalObject());
     }
 
     return detail;
index 62ca9c9..12a6ace 100644 (file)
@@ -505,8 +505,8 @@ static JSValue handlePostMessage(DOMWindow& impl, ExecState& state)
     if (UNLIKELY(state.argumentCount() < 2))
         return throwException(&state, scope, createNotEnoughArgumentsError(&state));
 
-    MessagePortArray messagePorts;
-    ArrayBufferArray arrayBuffers;
+    Vector<RefPtr<MessagePort>> messagePorts;
+    Vector<RefPtr<JSC::ArrayBuffer>> arrayBuffers;
 
     // This function has variable arguments and can be:
     // Per current spec:
@@ -521,11 +521,11 @@ static JSValue handlePostMessage(DOMWindow& impl, ExecState& state)
             targetOriginArgIndex = 2;
             transferablesArgIndex = 1;
         }
-        fillMessagePortArray(state, state.argument(transferablesArgIndex), messagePorts, arrayBuffers);
+        extractTransferables(state, state.argument(transferablesArgIndex), messagePorts, arrayBuffers);
     }
     RETURN_IF_EXCEPTION(scope, JSValue());
 
-    auto message = SerializedScriptValue::create(&state, state.uncheckedArgument(0), &messagePorts, &arrayBuffers);
+    auto message = SerializedScriptValue::create(state, state.uncheckedArgument(0), messagePorts, WTFMove(arrayBuffers));
 
     RETURN_IF_EXCEPTION(scope, JSValue());
 
@@ -533,7 +533,7 @@ static JSValue handlePostMessage(DOMWindow& impl, ExecState& state)
     RETURN_IF_EXCEPTION(scope, JSValue());
 
     ExceptionCode ec = 0;
-    impl.postMessage(WTFMove(message), &messagePorts, targetOrigin, callerDOMWindow(&state), ec);
+    impl.postMessage(WTFMove(message), WTFMove(messagePorts), targetOrigin, callerDOMWindow(&state), ec);
     setDOMException(&state, ec);
 
     return jsUndefined();
index e328bc2..9c10b46 100644 (file)
 #include "DOMWindow.h"
 #include "Dictionary.h"
 #include "JSCSSFontFaceRule.h"
+#include "JSDOMConvert.h"
 #include "JSDOMError.h"
 #include "JSDOMWindow.h"
 #include "JSEventTarget.h"
-#include "JSMessagePortCustom.h"
+#include "JSMessagePort.h"
 #include "JSNode.h"
 #include "JSStorage.h"
 #include "JSTrackCustom.h"
@@ -177,7 +178,7 @@ void JSDictionary::convertValue(ExecState* exec, JSValue value, Deprecated::Scri
 
 void JSDictionary::convertValue(ExecState* exec, JSValue value, RefPtr<SerializedScriptValue>& result)
 {
-    result = SerializedScriptValue::create(exec, value, 0, 0);
+    result = SerializedScriptValue::create(*exec, value);
 }
 
 void JSDictionary::convertValue(ExecState* state, JSValue value, RefPtr<DOMWindow>& result)
@@ -208,10 +209,9 @@ void JSDictionary::convertValue(ExecState*, JSValue value, RefPtr<Storage>& resu
     result = JSStorage::toWrapped(value);
 }
 
-void JSDictionary::convertValue(ExecState* exec, JSValue value, MessagePortArray& result)
+void JSDictionary::convertValue(ExecState* exec, JSValue value, Vector<RefPtr<MessagePort>>& result)
 {
-    ArrayBufferArray arrayBuffers;
-    fillMessagePortArray(*exec, value, result, arrayBuffers);
+    result = convert<IDLSequence<IDLInterface<MessagePort>>>(*exec, value);
 }
 
 #if ENABLE(VIDEO_TRACK)
index cf100c4..fb1e9ee 100644 (file)
@@ -136,7 +136,7 @@ private:
     static void convertValue(JSC::ExecState*, JSC::JSValue, RefPtr<EventTarget>& result);
     static void convertValue(JSC::ExecState*, JSC::JSValue, RefPtr<Node>& result);
     static void convertValue(JSC::ExecState*, JSC::JSValue, RefPtr<Storage>& result);
-    static void convertValue(JSC::ExecState*, JSC::JSValue, MessagePortArray& result);
+    static void convertValue(JSC::ExecState*, JSC::JSValue, Vector<RefPtr<MessagePort>>& result);
 #if ENABLE(VIDEO_TRACK)
     static void convertValue(JSC::ExecState*, JSC::JSValue, RefPtr<TrackBase>& result);
 #endif
index bdcb5f0..9424356 100644 (file)
@@ -48,7 +48,7 @@ JSValue JSHistory::state(ExecState& state) const
         return cachedValue;
 
     RefPtr<SerializedScriptValue> serialized = history.state();
-    JSValue result = serialized ? serialized->deserialize(&state, globalObject(), 0) : jsNull();
+    JSValue result = serialized ? serialized->deserialize(state, globalObject()) : jsNull();
     m_state.set(state.vm(), this, result);
     return result;
 }
@@ -62,7 +62,7 @@ JSValue JSHistory::pushState(ExecState& state)
     if (UNLIKELY(argCount < 2))
         return throwException(&state, scope, createNotEnoughArgumentsError(&state));
 
-    auto historyState = SerializedScriptValue::create(&state, state.uncheckedArgument(0), 0, 0);
+    auto historyState = SerializedScriptValue::create(state, state.uncheckedArgument(0));
     RETURN_IF_EXCEPTION(scope, JSValue());
 
     // FIXME: title should not be nullable.
@@ -91,7 +91,7 @@ JSValue JSHistory::replaceState(ExecState& state)
     if (UNLIKELY(argCount < 2))
         return throwException(&state, scope, createNotEnoughArgumentsError(&state));
 
-    auto historyState = SerializedScriptValue::create(&state, state.uncheckedArgument(0), 0, 0);
+    auto historyState = SerializedScriptValue::create(state, state.uncheckedArgument(0));
     RETURN_IF_EXCEPTION(scope, JSValue());
 
     // FIXME: title should not be nullable.
index b025081..6f233f7 100644 (file)
 
 #include "JSBlob.h"
 #include "JSDOMBinding.h"
+#include "JSDOMConvert.h"
 #include "JSDOMWindow.h"
 #include "JSEventTarget.h"
 #include "JSMessagePort.h"
-#include "JSMessagePortCustom.h"
 #include "MessageEvent.h"
 #include <runtime/JSArray.h>
 #include <runtime/JSArrayBuffer.h>
@@ -67,7 +67,7 @@ JSValue JSMessageEvent::data(ExecState& state) const
             if (dataValue.isObject() && &worldForDOMObject(dataValue.getObject()) != &currentWorld(&state)) {
                 RefPtr<SerializedScriptValue> serializedValue = event.trySerializeData(&state);
                 if (serializedValue)
-                    result = serializedValue->deserialize(&state, globalObject(), nullptr);
+                    result = serializedValue->deserialize(state, globalObject());
                 else
                     result = jsNull();
             } else
@@ -78,9 +78,9 @@ JSValue JSMessageEvent::data(ExecState& state) const
 
     case MessageEvent::DataTypeSerializedScriptValue:
         if (RefPtr<SerializedScriptValue> serializedValue = event.dataAsSerializedScriptValue()) {
-            MessagePortArray ports = wrapped().ports();
+            Vector<RefPtr<MessagePort>> ports = wrapped().ports();
             // FIXME: Why does this suppress exceptions?
-            result = serializedValue->deserialize(&state, globalObject(), &ports, NonThrowing);
+            result = serializedValue->deserialize(state, globalObject(), ports, NonThrowing);
         } else
             result = jsNull();
         break;
@@ -109,25 +109,34 @@ static JSC::JSValue handleInitMessageEvent(JSMessageEvent* jsEvent, JSC::ExecSta
     auto scope = DECLARE_THROW_SCOPE(vm);
 
     const String& typeArg = state.argument(0).toString(&state)->value(&state);
+    RETURN_IF_EXCEPTION(scope, JSValue());
+
     bool canBubbleArg = state.argument(1).toBoolean(&state);
+    RETURN_IF_EXCEPTION(scope, JSValue());
+
     bool cancelableArg = state.argument(2).toBoolean(&state);
+    RETURN_IF_EXCEPTION(scope, JSValue());
+
+    JSValue dataArg = state.argument(3);
+
     const String originArg = valueToUSVString(&state, state.argument(4));
+    RETURN_IF_EXCEPTION(scope, JSValue());
+
     const String lastEventIdArg = state.argument(5).toString(&state)->value(&state);
+    RETURN_IF_EXCEPTION(scope, JSValue());
+
     auto sourceArg = convert<IDLNullable<IDLUnion<IDLInterface<DOMWindow>, IDLInterface<MessagePort>>>>(state, state.argument(6));
-    std::unique_ptr<MessagePortArray> messagePorts;
-    std::unique_ptr<ArrayBufferArray> arrayBuffers;
+    RETURN_IF_EXCEPTION(scope, JSValue());
+    
+    Vector<RefPtr<MessagePort>> messagePorts;
     if (!state.argument(7).isUndefinedOrNull()) {
-        messagePorts = std::make_unique<MessagePortArray>();
-        arrayBuffers = std::make_unique<ArrayBufferArray>();
-        fillMessagePortArray(state, state.argument(7), *messagePorts, *arrayBuffers);
+        messagePorts = convert<IDLSequence<IDLInterface<MessagePort>>>(state, state.argument(7));
         RETURN_IF_EXCEPTION(scope, JSValue());
     }
-    Deprecated::ScriptValue dataArg(vm, state.argument(3));
-    RETURN_IF_EXCEPTION(scope, JSValue());
 
     MessageEvent& event = jsEvent->wrapped();
-    event.initMessageEvent(typeArg, canBubbleArg, cancelableArg, dataArg, originArg, lastEventIdArg, WTFMove(sourceArg), WTFMove(messagePorts));
-    jsEvent->m_data.set(vm, jsEvent, dataArg.jsValue());
+    event.initMessageEvent(state, typeArg, canBubbleArg, cancelableArg, dataArg, originArg, lastEventIdArg, WTFMove(sourceArg), WTFMove(messagePorts));
+    jsEvent->m_data.set(vm, jsEvent, dataArg);
     return jsUndefined();
 }
 
index b840820..9f3622e 100644 (file)
@@ -57,13 +57,11 @@ JSC::JSValue JSMessagePort::postMessage(JSC::ExecState& state)
     return handlePostMessage(state, &wrapped());
 }
 
-void fillMessagePortArray(JSC::ExecState& state, JSC::JSValue value, MessagePortArray& portArray, ArrayBufferArray& arrayBuffers)
+void extractTransferables(JSC::ExecState& state, JSC::JSValue value, Vector<RefPtr<MessagePort>>& portArray, Vector<RefPtr<JSC::ArrayBuffer>>& arrayBuffers)
 {
     VM& vm = state.vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
 
-    // Convert from the passed-in JS array-like object to a MessagePortArray.
-    // Also validates the elements per sections 4.1.13 and 4.1.15 of the WebIDL spec and section 8.3.3 of the HTML5 spec.
     if (value.isUndefinedOrNull()) {
         portArray.resize(0);
         arrayBuffers.resize(0);
@@ -78,7 +76,7 @@ void fillMessagePortArray(JSC::ExecState& state, JSC::JSValue value, MessagePort
     for (unsigned i = 0 ; i < length; ++i) {
         JSValue value = object->get(&state, i);
         RETURN_IF_EXCEPTION(scope, void());
-        // Validation of non-null objects, per HTML5 spec 10.3.3.
+
         if (value.isUndefinedOrNull()) {
             setDOMException(&state, INVALID_STATE_ERR);
             return;
index 8045744..4972908 100644 (file)
@@ -42,10 +42,7 @@ namespace WebCore {
 
     typedef int ExceptionCode;
 
-    // Helper function which pulls the values out of a JS sequence and into a MessagePortArray.
-    // Also validates the elements per sections 4.1.13 and 4.1.15 of the WebIDL spec and section 8.3.3 of the HTML5 spec.
-    // May generate an exception via the passed ExecState.
-    void fillMessagePortArray(JSC::ExecState&, JSC::JSValue, MessagePortArray&, ArrayBufferArray&);
+    void extractTransferables(JSC::ExecState&, JSC::JSValue, Vector<RefPtr<MessagePort>>&, Vector<RefPtr<JSC::ArrayBuffer>>&);
 
     // Helper function to convert from JS postMessage arguments to WebCore postMessage arguments.
     template <typename T>
@@ -57,14 +54,16 @@ namespace WebCore {
         if (UNLIKELY(state.argumentCount() < 1))
             return throwException(&state, scope, createNotEnoughArgumentsError(&state));
 
-        MessagePortArray portArray;
-        ArrayBufferArray arrayBufferArray;
-        fillMessagePortArray(state, state.argument(1), portArray, arrayBufferArray);
-        auto message = SerializedScriptValue::create(&state, state.uncheckedArgument(0), &portArray, &arrayBufferArray);
+        
+        Vector<RefPtr<MessagePort>> messagePortArray;
+        Vector<RefPtr<JSC::ArrayBuffer>> arrayBufferArray;
+        extractTransferables(state, state.argument(1), messagePortArray, arrayBufferArray);
+        
+        auto message = SerializedScriptValue::create(state, state.uncheckedArgument(0), messagePortArray, WTFMove(arrayBufferArray));
         RETURN_IF_EXCEPTION(scope, JSC::JSValue());
 
         ExceptionCode ec = 0;
-        impl->postMessage(WTFMove(message), &portArray, ec);
+        impl->postMessage(WTFMove(message), WTFMove(messagePortArray), ec);
         setDOMException(&state, ec);
         return JSC::jsUndefined();
     }
index 823c69a..0438c93 100644 (file)
@@ -64,7 +64,7 @@ JSValue JSPopStateEvent::state(ExecState& state) const
         // Ideally, we would check that the worlds have different privileges but that's not possible yet.
         if (eventState.isObject() && &worldForDOMObject(eventState.getObject()) != &currentWorld(&state)) {
             if (auto serializedValue = event.trySerializeState(&state))
-                eventState = serializedValue->deserialize(&state, globalObject(), nullptr);
+                eventState = serializedValue->deserialize(state, globalObject());
             else
                 eventState = jsNull();
         }
@@ -88,7 +88,7 @@ JSValue JSPopStateEvent::state(ExecState& state) const
         JSHistory* jsHistory = jsCast<JSHistory*>(toJS(&state, globalObject(), *history).asCell());
         result = jsHistory->state(state);
     } else
-        result = event.serializedState()->deserialize(&state, globalObject(), 0);
+        result = event.serializedState()->deserialize(state, globalObject());
 
     return cacheState(state, this, result);
 }
index 5cac12e..2230e1f 100644 (file)
@@ -474,9 +474,7 @@ template <> bool writeLittleEndian<uint8_t>(Vector<uint8_t>& buffer, const uint8
 
 class CloneSerializer : CloneBase {
 public:
-    static SerializationReturnCode serialize(ExecState* exec, JSValue value,
-                                             MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers,
-                                             Vector<String>& blobURLs, Vector<uint8_t>& out)
+    static SerializationReturnCode serialize(ExecState* exec, JSValue value, Vector<RefPtr<MessagePort>>& messagePorts, Vector<RefPtr<JSC::ArrayBuffer>>& arrayBuffers, Vector<String>& blobURLs, Vector<uint8_t>& out)
     {
         CloneSerializer serializer(exec, messagePorts, arrayBuffers, blobURLs, out);
         return serializer.serialize(value);
@@ -525,7 +523,7 @@ public:
 private:
     typedef HashMap<JSObject*, uint32_t> ObjectPool;
 
-    CloneSerializer(ExecState* exec, MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers, Vector<String>& blobURLs, Vector<uint8_t>& out)
+    CloneSerializer(ExecState* exec, Vector<RefPtr<MessagePort>>& messagePorts, Vector<RefPtr<JSC::ArrayBuffer>>& arrayBuffers, Vector<String>& blobURLs, Vector<uint8_t>& out)
         : CloneBase(exec)
         , m_buffer(out)
         , m_blobURLs(blobURLs)
@@ -537,13 +535,13 @@ private:
     }
 
     template <class T>
-    void fillTransferMap(Vector<RefPtr<T>, 1>* input, ObjectPool& result)
+    void fillTransferMap(Vector<RefPtr<T>>& input, ObjectPool& result)
     {
-        if (!input)
+        if (input.isEmpty())
             return;
         JSDOMGlobalObject* globalObject = jsCast<JSDOMGlobalObject*>(m_exec->lexicalGlobalObject());
-        for (size_t i = 0; i < input->size(); i++) {
-            JSC::JSValue value = toJS(m_exec, globalObject, input->at(i).get());
+        for (size_t i = 0; i < input.size(); i++) {
+            JSC::JSValue value = toJS(m_exec, globalObject, input[i].get());
             JSC::JSObject* obj = value.getObject();
             if (obj && !result.contains(obj))
                 result.add(obj, i);
@@ -877,7 +875,9 @@ private:
                 write(CryptoKeyTag);
                 Vector<uint8_t> serializedKey;
                 Vector<String> dummyBlobURLs;
-                CloneSerializer rawKeySerializer(m_exec, nullptr, nullptr, dummyBlobURLs, serializedKey);
+                Vector<RefPtr<MessagePort>> dummyMessagePorts;
+                Vector<RefPtr<JSC::ArrayBuffer>> dummyArrayBuffers;
+                CloneSerializer rawKeySerializer(m_exec, dummyMessagePorts, dummyArrayBuffers, dummyBlobURLs, serializedKey);
                 rawKeySerializer.write(key);
                 Vector<uint8_t> wrappedKey;
                 if (!wrapCryptoKey(m_exec, serializedKey, wrappedKey))
@@ -1487,7 +1487,7 @@ public:
         return str;
     }
 
-    static DeserializationResult deserialize(ExecState* exec, JSGlobalObject* globalObject, MessagePortArray* messagePorts, ArrayBufferContentsArray* arrayBufferContentsArray, const Vector<uint8_t>& buffer, const Vector<String>& blobURLs, const Vector<String> blobFilePaths)
+    static DeserializationResult deserialize(ExecState* exec, JSGlobalObject* globalObject, Vector<RefPtr<MessagePort>>& messagePorts, ArrayBufferContentsArray* arrayBufferContentsArray, const Vector<uint8_t>& buffer, const Vector<String>& blobURLs, const Vector<String> blobFilePaths)
     {
         if (!buffer.size())
             return std::make_pair(jsNull(), UnspecifiedError);
@@ -1536,7 +1536,7 @@ private:
         size_t m_index;
     };
 
-    CloneDeserializer(ExecState* exec, JSGlobalObject* globalObject, MessagePortArray* messagePorts, ArrayBufferContentsArray* arrayBufferContents, const Vector<uint8_t>& buffer)
+    CloneDeserializer(ExecState* exec, JSGlobalObject* globalObject, Vector<RefPtr<MessagePort>>& messagePorts, ArrayBufferContentsArray* arrayBufferContents, const Vector<uint8_t>& buffer)
         : CloneBase(exec)
         , m_globalObject(globalObject)
         , m_isDOMGlobalObject(globalObject->inherits(JSDOMGlobalObject::info()))
@@ -1551,7 +1551,7 @@ private:
             m_version = 0xFFFFFFFF;
     }
 
-    CloneDeserializer(ExecState* exec, JSGlobalObject* globalObject, MessagePortArray* messagePorts, ArrayBufferContentsArray* arrayBufferContents, const Vector<uint8_t>& buffer, const Vector<String>& blobURLs, const Vector<String> blobFilePaths)
+    CloneDeserializer(ExecState* exec, JSGlobalObject* globalObject, Vector<RefPtr<MessagePort>>& messagePorts, ArrayBufferContentsArray* arrayBufferContents, const Vector<uint8_t>& buffer, const Vector<String>& blobURLs, const Vector<String> blobFilePaths)
         : CloneBase(exec)
         , m_globalObject(globalObject)
         , m_isDOMGlobalObject(globalObject->inherits(JSDOMGlobalObject::info()))
@@ -2347,11 +2347,11 @@ private:
         case MessagePortReferenceTag: {
             uint32_t index;
             bool indexSuccessfullyRead = read(index);
-            if (!indexSuccessfullyRead || !m_messagePorts || index >= m_messagePorts->size()) {
+            if (!indexSuccessfullyRead || index >= m_messagePorts.size()) {
                 fail();
                 return JSValue();
             }
-            return getJSValue(m_messagePorts->at(index).get());
+            return getJSValue(m_messagePorts[index].get());
         }
         case ArrayBufferTag: {
             RefPtr<ArrayBuffer> arrayBuffer;
@@ -2398,7 +2398,8 @@ private:
                 return JSValue();
             }
             JSValue cryptoKey;
-            CloneDeserializer rawKeyDeserializer(m_exec, m_globalObject, nullptr, nullptr, serializedKey);
+            Vector<RefPtr<MessagePort>> dummyMessagePorts;
+            CloneDeserializer rawKeyDeserializer(m_exec, m_globalObject, dummyMessagePorts, nullptr, serializedKey);
             if (!rawKeyDeserializer.readCryptoKey(cryptoKey)) {
                 fail();
                 return JSValue();
@@ -2428,9 +2429,9 @@ private:
     const uint8_t* m_end;
     unsigned m_version;
     Vector<CachedString> m_constantPool;
-    MessagePortArray* m_messagePorts;
+    Vector<RefPtr<MessagePort>>& m_messagePorts;
     ArrayBufferContentsArray* m_arrayBufferContents;
-    ArrayBufferArray m_arrayBuffers;
+    Vector<RefPtr<JSC::ArrayBuffer>> m_arrayBuffers;
     Vector<String> m_blobURLs;
     Vector<String> m_blobFilePaths;
 
@@ -2654,7 +2655,7 @@ SerializedScriptValue::SerializedScriptValue(Vector<uint8_t>&& buffer, const Vec
 }
 
 std::unique_ptr<SerializedScriptValue::ArrayBufferContentsArray> SerializedScriptValue::transferArrayBuffers(
-    ExecState* exec, ArrayBufferArray& arrayBuffers, SerializationReturnCode& code)
+    ExecState* exec, Vector<RefPtr<JSC::ArrayBuffer>>& arrayBuffers, SerializationReturnCode& code)
 {
     for (size_t i = 0; i < arrayBuffers.size(); i++) {
         if (arrayBuffers[i]->isNeutered()) {
@@ -2682,19 +2683,24 @@ std::unique_ptr<SerializedScriptValue::ArrayBufferContentsArray> SerializedScrip
     return contents;
 }
 
-RefPtr<SerializedScriptValue> SerializedScriptValue::create(ExecState* exec, JSValue value, MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers, SerializationErrorMode throwExceptions)
+RefPtr<SerializedScriptValue> SerializedScriptValue::create(ExecState& exec, JSValue value, SerializationErrorMode throwExceptions)
+{
+    Vector<RefPtr<MessagePort>> messagePorts;
+    return SerializedScriptValue::create(exec, value, messagePorts, { }, throwExceptions);
+}
+
+RefPtr<SerializedScriptValue> SerializedScriptValue::create(ExecState& exec, JSValue value, Vector<RefPtr<MessagePort>>& messagePorts, Vector<RefPtr<JSC::ArrayBuffer>>&& arrayBuffers, SerializationErrorMode throwExceptions)
 {
     Vector<uint8_t> buffer;
     Vector<String> blobURLs;
-    SerializationReturnCode code = CloneSerializer::serialize(exec, value, messagePorts, arrayBuffers, blobURLs, buffer);
+    SerializationReturnCode code = CloneSerializer::serialize(&exec, value, messagePorts, arrayBuffers, blobURLs, buffer);
 
     std::unique_ptr<ArrayBufferContentsArray> arrayBufferContentsArray;
-
-    if (arrayBuffers && serializationDidCompleteSuccessfully(code))
-        arrayBufferContentsArray = transferArrayBuffers(exec, *arrayBuffers, code);
+    if (!arrayBuffers.isEmpty() && serializationDidCompleteSuccessfully(code))
+        arrayBufferContentsArray = transferArrayBuffers(&exec, arrayBuffers, code);
 
     if (throwExceptions == Throwing)
-        maybeThrowExceptionIfSerializationFailed(exec, code);
+        maybeThrowExceptionIfSerializationFailed(&exec, code);
 
     if (!serializationDidCompleteSuccessfully(code))
         return nullptr;
@@ -2718,7 +2724,7 @@ RefPtr<SerializedScriptValue> SerializedScriptValue::create(JSContextRef originC
     auto scope = DECLARE_CATCH_SCOPE(vm);
 
     JSValue value = toJS(exec, apiValue);
-    RefPtr<SerializedScriptValue> serializedValue = SerializedScriptValue::create(exec, value, nullptr, nullptr);
+    RefPtr<SerializedScriptValue> serializedValue = SerializedScriptValue::create(*exec, value);
     if (UNLIKELY(scope.exception())) {
         if (exception)
             *exception = toRef(exec, scope.exception()->value());
@@ -2734,17 +2740,24 @@ String SerializedScriptValue::toString()
     return CloneDeserializer::deserializeString(m_data);
 }
 
-JSValue SerializedScriptValue::deserialize(ExecState* exec, JSGlobalObject* globalObject, MessagePortArray* messagePorts, SerializationErrorMode throwExceptions)
+JSValue SerializedScriptValue::deserialize(ExecState& exec, JSGlobalObject* globalObject, SerializationErrorMode throwExceptions)
+{
+    Vector<RefPtr<MessagePort>> dummyMessagePorts;
+    return deserialize(exec, globalObject, dummyMessagePorts, throwExceptions);
+}
+
+JSValue SerializedScriptValue::deserialize(ExecState& exec, JSGlobalObject* globalObject, Vector<RefPtr<MessagePort>>& messagePorts, SerializationErrorMode throwExceptions)
 {
-    Vector<String> dummyBlobs, dummyPaths;
-    return deserialize(exec, globalObject, messagePorts, throwExceptions, dummyBlobs, dummyPaths);
+    Vector<String> dummyBlobs;
+    Vector<String> dummyPaths;
+    return deserialize(exec, globalObject, messagePorts, dummyBlobs, dummyPaths, throwExceptions);
 }
 
-JSValue SerializedScriptValue::deserialize(ExecState* exec, JSGlobalObject* globalObject, MessagePortArray* messagePorts, SerializationErrorMode throwExceptions, const Vector<String>& blobURLs, const Vector<String>& blobFilePaths)
+JSValue SerializedScriptValue::deserialize(ExecState& exec, JSGlobalObject* globalObject, Vector<RefPtr<MessagePort>>& messagePorts, const Vector<String>& blobURLs, const Vector<String>& blobFilePaths, SerializationErrorMode throwExceptions)
 {
-    DeserializationResult result = CloneDeserializer::deserialize(exec, globalObject, messagePorts, m_arrayBufferContentsArray.get(), m_data, blobURLs, blobFilePaths);
+    DeserializationResult result = CloneDeserializer::deserialize(&exec, globalObject, messagePorts, m_arrayBufferContentsArray.get(), m_data, blobURLs, blobFilePaths);
     if (throwExceptions == Throwing)
-        maybeThrowExceptionIfSerializationFailed(exec, result.second);
+        maybeThrowExceptionIfSerializationFailed(&exec, result.second);
     return result.first ? result.first : jsNull();
 }
 
@@ -2755,7 +2768,7 @@ JSValueRef SerializedScriptValue::deserialize(JSContextRef destinationContext, J
     JSLockHolder locker(vm);
     auto scope = DECLARE_CATCH_SCOPE(vm);
 
-    JSValue value = deserialize(exec, exec->lexicalGlobalObject(), nullptr);
+    JSValue value = deserialize(*exec, exec->lexicalGlobalObject());
     if (UNLIKELY(scope.exception())) {
         if (exception)
             *exception = toRef(exec, scope.exception()->value());
index 9e15cd0..cefa729 100644 (file)
@@ -42,8 +42,6 @@ namespace WebCore {
 
 class IDBValue;
 class MessagePort;
-typedef Vector<RefPtr<MessagePort>, 1> MessagePortArray;
-typedef Vector<RefPtr<JSC::ArrayBuffer>, 1> ArrayBufferArray;
  
 enum SerializationReturnCode {
     SuccessfullyCompleted,
@@ -61,7 +59,8 @@ class SharedBuffer;
 
 class SerializedScriptValue : public ThreadSafeRefCounted<SerializedScriptValue> {
 public:
-    WEBCORE_EXPORT static RefPtr<SerializedScriptValue> create(JSC::ExecState*, JSC::JSValue, MessagePortArray*, ArrayBufferArray*, SerializationErrorMode = Throwing);
+    WEBCORE_EXPORT static RefPtr<SerializedScriptValue> create(JSC::ExecState&, JSC::JSValue, SerializationErrorMode = Throwing);
+    WEBCORE_EXPORT static RefPtr<SerializedScriptValue> create(JSC::ExecState&, JSC::JSValue, Vector<RefPtr<MessagePort>>&, Vector<RefPtr<JSC::ArrayBuffer>>&&, SerializationErrorMode = Throwing);
 
     WEBCORE_EXPORT static RefPtr<SerializedScriptValue> create(StringView);
     static Ref<SerializedScriptValue> adopt(Vector<uint8_t>&& buffer)
@@ -71,8 +70,9 @@ public:
 
     static Ref<SerializedScriptValue> nullValue();
 
-    WEBCORE_EXPORT JSC::JSValue deserialize(JSC::ExecState*, JSC::JSGlobalObject*, MessagePortArray*, SerializationErrorMode = Throwing);
-    JSC::JSValue deserialize(JSC::ExecState*, JSC::JSGlobalObject*, MessagePortArray*, SerializationErrorMode, const Vector<String>& blobURLs, const Vector<String>& blobFilePaths);
+    WEBCORE_EXPORT JSC::JSValue deserialize(JSC::ExecState&, JSC::JSGlobalObject*, SerializationErrorMode = Throwing);
+    WEBCORE_EXPORT JSC::JSValue deserialize(JSC::ExecState&, JSC::JSGlobalObject*, Vector<RefPtr<MessagePort>>&, SerializationErrorMode = Throwing);
+    JSC::JSValue deserialize(JSC::ExecState&, JSC::JSGlobalObject*, Vector<RefPtr<MessagePort>>&, const Vector<String>& blobURLs, const Vector<String>& blobFilePaths, SerializationErrorMode = Throwing);
 
     static uint32_t wireFormatVersion();
 
@@ -103,7 +103,7 @@ private:
     typedef Vector<JSC::ArrayBufferContents> ArrayBufferContentsArray;
     static void maybeThrowExceptionIfSerializationFailed(JSC::ExecState*, SerializationReturnCode);
     static bool serializationDidCompleteSuccessfully(SerializationReturnCode);
-    static std::unique_ptr<ArrayBufferContentsArray> transferArrayBuffers(JSC::ExecState*, ArrayBufferArray&, SerializationReturnCode&);
+    static std::unique_ptr<ArrayBufferContentsArray> transferArrayBuffers(JSC::ExecState*, Vector<RefPtr<JSC::ArrayBuffer>>&, SerializationReturnCode&);
 
     WEBCORE_EXPORT SerializedScriptValue(Vector<unsigned char>&&);
     SerializedScriptValue(Vector<unsigned char>&&, const Vector<String>& blobURLs, std::unique_ptr<ArrayBufferContentsArray>&&);
index b3c04f7..feb5097 100644 (file)
@@ -4905,7 +4905,6 @@ sub GetNativeVectorType
     die "This should only be called for sequence or array types" unless $codeGenerator->IsSequenceOrFrozenArrayType($type);
 
     my $innerType = $codeGenerator->GetSequenceOrFrozenArrayInnerType($type);
-    return "MessagePortArray" if $innerType eq "MessagePort";
     return "Vector<" . GetNativeVectorInnerType($innerType) . ">";
 }
 
@@ -5168,7 +5167,7 @@ sub JSValueToNative
 
     if ($type eq "SerializedScriptValue") {
         AddToImplIncludes("SerializedScriptValue.h", $conditional);
-        return ("SerializedScriptValue::create($statePointer, $value, 0, 0)", 1);
+        return ("SerializedScriptValue::create($stateReference, $value)", 1);
     }
 
     if ($type eq "Dictionary") {
@@ -5274,7 +5273,7 @@ sub NativeToJSValue
 
     if ($type eq "SerializedScriptValue") {
         AddToImplIncludes("SerializedScriptValue.h", $conditional);
-        return "$value ? $value->deserialize($statePointer, $globalObject, 0) : jsNull()";
+        return "$value ? $value->deserialize($stateReference, $globalObject) : jsNull()";
     }
 
     AddToImplIncludes("StyleProperties.h", $conditional) if $type eq "CSSStyleDeclaration";
index 91d83d4..6065bc0 100644 (file)
@@ -61,7 +61,7 @@ void CustomEvent::initCustomEvent(JSC::ExecState& state, const AtomicString& typ
 RefPtr<SerializedScriptValue> CustomEvent::trySerializeDetail(JSC::ExecState& state)
 {
     if (!m_triedToSerialize) {
-        m_serializedDetail = SerializedScriptValue::create(&state, m_detail, nullptr, nullptr, NonThrowing);
+        m_serializedDetail = SerializedScriptValue::create(state, m_detail, NonThrowing);
         m_triedToSerialize = true;
     }
     return m_serializedDetail;
index e997fa2..b587048 100644 (file)
@@ -81,7 +81,7 @@ JSValue ErrorEvent::sanitizedErrorValue(ExecState& exec, JSGlobalObject& globalO
         auto serializedError = trySerializeError(exec);
         if (!serializedError)
             return jsNull();
-        return serializedError->deserialize(&exec, &globalObject, nullptr);
+        return serializedError->deserialize(exec, &globalObject);
     }
 
     return error;
@@ -90,7 +90,7 @@ JSValue ErrorEvent::sanitizedErrorValue(ExecState& exec, JSGlobalObject& globalO
 RefPtr<SerializedScriptValue> ErrorEvent::trySerializeError(ExecState& exec)
 {
     if (!m_triedToSerialize) {
-        m_serializedDetail = SerializedScriptValue::create(&exec, m_error, nullptr, nullptr, NonThrowing);
+        m_serializedDetail = SerializedScriptValue::create(exec, m_error, NonThrowing);
         m_triedToSerialize = true;
     }
     return m_serializedDetail;
index 6d32ca0..c256666 100644 (file)
@@ -48,11 +48,11 @@ inline MessageEvent::MessageEvent(ExecState& state, const AtomicString& type, In
     , m_origin(initializer.origin)
     , m_lastEventId(initializer.lastEventId)
     , m_source(WTFMove(initializer.source))
-    , m_ports(std::make_unique<MessagePortArray>(initializer.ports))
+    , m_ports(WTFMove(initializer.ports))
 {
 }
 
-inline MessageEvent::MessageEvent(RefPtr<SerializedScriptValue>&& data, const String& origin, const String& lastEventId, Optional<MessageEventSource>&& source, std::unique_ptr<MessagePortArray> ports)
+inline MessageEvent::MessageEvent(RefPtr<SerializedScriptValue>&& data, const String& origin, const String& lastEventId, Optional<MessageEventSource>&& source, Vector<RefPtr<MessagePort>>&& ports)
     : Event(eventNames().messageEvent, false, false)
     , m_dataType(DataTypeSerializedScriptValue)
     , m_dataAsSerializedScriptValue(WTFMove(data))
@@ -96,7 +96,7 @@ inline MessageEvent::MessageEvent(Ref<ArrayBuffer>&& data, const String& origin)
 {
 }
 
-Ref<MessageEvent> MessageEvent::create(std::unique_ptr<MessagePortArray> ports, RefPtr<SerializedScriptValue>&& data, const String& origin, const String& lastEventId, Optional<MessageEventSource>&& source)
+Ref<MessageEvent> MessageEvent::create(Vector<RefPtr<MessagePort>>&& ports, RefPtr<SerializedScriptValue>&& data, const String& origin, const String& lastEventId, Optional<MessageEventSource>&& source)
 {
     return adoptRef(*new MessageEvent(WTFMove(data), origin, lastEventId, WTFMove(source), WTFMove(ports)));
 }
@@ -135,7 +135,7 @@ MessageEvent::~MessageEvent()
 {
 }
 
-void MessageEvent::initMessageEvent(const AtomicString& type, bool canBubble, bool cancelable, const Deprecated::ScriptValue& data, const String& origin, const String& lastEventId, Optional<MessageEventSource>&& source, std::unique_ptr<MessagePortArray> ports)
+void MessageEvent::initMessageEvent(ExecState& state, const AtomicString& type, bool canBubble, bool cancelable, JSValue data, const String& origin, const String& lastEventId, Optional<MessageEventSource>&& source, Vector<RefPtr<MessagePort>>&& ports)
 {
     if (dispatched())
         return;
@@ -143,7 +143,7 @@ void MessageEvent::initMessageEvent(const AtomicString& type, bool canBubble, bo
     initEvent(type, canBubble, cancelable);
 
     m_dataType = DataTypeScriptValue;
-    m_dataAsScriptValue = data;
+    m_dataAsScriptValue = Deprecated::ScriptValue(state.vm(), data);
     m_dataAsSerializedScriptValue = nullptr;
     m_triedToSerialize = false;
     m_origin = origin;
@@ -152,7 +152,7 @@ void MessageEvent::initMessageEvent(const AtomicString& type, bool canBubble, bo
     m_ports = WTFMove(ports);
 }
 
-void MessageEvent::initMessageEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<SerializedScriptValue> data, const String& origin, const String& lastEventId, Optional<MessageEventSource>&& source, std::unique_ptr<MessagePortArray> ports)
+void MessageEvent::initMessageEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<SerializedScriptValue> data, const String& origin, const String& lastEventId, Optional<MessageEventSource>&& source, Vector<RefPtr<MessagePort>>&& ports)
 {
     if (dispatched())
         return;
@@ -185,7 +185,7 @@ RefPtr<SerializedScriptValue> MessageEvent::trySerializeData(ExecState* exec)
     ASSERT(!m_dataAsScriptValue.hasNoValue());
     
     if (!m_dataAsSerializedScriptValue && !m_triedToSerialize) {
-        m_dataAsSerializedScriptValue = SerializedScriptValue::create(exec, m_dataAsScriptValue.jsValue(), nullptr, nullptr, NonThrowing);
+        m_dataAsSerializedScriptValue = SerializedScriptValue::create(*exec, m_dataAsScriptValue.jsValue(), NonThrowing);
         m_triedToSerialize = true;
     }
     
index d0350c3..dec3f65 100644 (file)
@@ -42,7 +42,7 @@ using MessageEventSource = std::experimental::variant<RefPtr<DOMWindow>, RefPtr<
 
 class MessageEvent final : public Event {
 public:
-    static Ref<MessageEvent> create(std::unique_ptr<MessagePortArray>, RefPtr<SerializedScriptValue>&&, const String& origin = { }, const String& lastEventId = { }, Optional<MessageEventSource>&& source = Nullopt);
+    static Ref<MessageEvent> create(Vector<RefPtr<MessagePort>>&&, RefPtr<SerializedScriptValue>&&, const String& origin = { }, const String& lastEventId = { }, Optional<MessageEventSource>&& source = Nullopt);
     static Ref<MessageEvent> create(const AtomicString& type, RefPtr<SerializedScriptValue>&&, const String& origin, const String& lastEventId);
     static Ref<MessageEvent> create(const String& data, const String& origin = { });
     static Ref<MessageEvent> create(Ref<Blob>&& data, const String& origin);
@@ -54,19 +54,19 @@ public:
         String origin;
         String lastEventId;
         Optional<MessageEventSource> source;
-        MessagePortArray ports;
+        Vector<RefPtr<MessagePort>> ports;
     };
     static Ref<MessageEvent> create(JSC::ExecState&, const AtomicString& type, Init&, IsTrusted = IsTrusted::No);
 
     virtual ~MessageEvent();
 
-    void initMessageEvent(const AtomicString& type, bool canBubble, bool cancelable, const Deprecated::ScriptValue& data, const String& origin, const String& lastEventId, Optional<MessageEventSource>&& source, std::unique_ptr<MessagePortArray>);
-    void initMessageEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<SerializedScriptValue> data, const String& origin, const String& lastEventId, Optional<MessageEventSource>&& source, std::unique_ptr<MessagePortArray>);
+    void initMessageEvent(JSC::ExecState&, const AtomicString& type, bool canBubble, bool cancelable, JSC::JSValue data, const String& origin, const String& lastEventId, Optional<MessageEventSource>&&, Vector<RefPtr<MessagePort>>&&);
+    void initMessageEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<SerializedScriptValue> data, const String& origin, const String& lastEventId, Optional<MessageEventSource>&&, Vector<RefPtr<MessagePort>>&&);
 
     const String& origin() const { return m_origin; }
     const String& lastEventId() const { return m_lastEventId; }
     EventTarget* source() const;
-    MessagePortArray ports() const { return m_ports ? *m_ports : MessagePortArray(); }
+    const Vector<RefPtr<MessagePort>>& ports() const { return m_ports; }
 
     // FIXME: Remove this when we have custom ObjC binding support.
     SerializedScriptValue* data() const;
@@ -92,7 +92,7 @@ public:
 private:
     MessageEvent();
     MessageEvent(JSC::ExecState&, const AtomicString&, Init&, IsTrusted);
-    MessageEvent(RefPtr<SerializedScriptValue>&& data, const String& origin, const String& lastEventId, Optional<MessageEventSource>&& source, std::unique_ptr<MessagePortArray>);
+    MessageEvent(RefPtr<SerializedScriptValue>&& data, const String& origin, const String& lastEventId, Optional<MessageEventSource>&&, Vector<RefPtr<MessagePort>>&&);
     MessageEvent(const AtomicString& type, RefPtr<SerializedScriptValue>&& data, const String& origin, const String& lastEventId);
     MessageEvent(const String& data, const String& origin);
     MessageEvent(Ref<Blob>&& data, const String& origin);
@@ -108,7 +108,7 @@ private:
     String m_origin;
     String m_lastEventId;
     Optional<MessageEventSource> m_source;
-    std::unique_ptr<MessagePortArray> m_ports;
+    Vector<RefPtr<MessagePort>> m_ports;
 };
 
 } // namespace WebCore
index 145e4e5..4257bd2 100644 (file)
 
     [Custom] void initMessageEvent(optional DOMString typeArg, optional boolean canBubbleArg, optional boolean cancelableArg,
         optional any dataArg, optional USVString originArg, optional DOMString lastEventIdArg, optional (DOMWindow or MessagePort)? sourceArg,
-        optional Array messagePorts);
-
+        optional sequence<MessagePort> messagePorts);
     [Custom] void webkitInitMessageEvent(optional DOMString typeArg, optional boolean canBubbleArg, optional boolean cancelableArg,
         optional any dataArg, optional USVString originArg, optional DOMString lastEventIdArg, optional (DOMWindow or MessagePort)? sourceArg,
-        optional Array transferables);
+        optional sequence<MessagePort> messagePorts);
 };
 
 dictionary MessageEventInit : EventInit {
index 79a80ed..0ff9dd1 100644 (file)
@@ -53,7 +53,7 @@ MessagePort::~MessagePort()
         m_scriptExecutionContext->destroyedMessagePort(*this);
 }
 
-void MessagePort::postMessage(RefPtr<SerializedScriptValue>&& message, const MessagePortArray* ports, ExceptionCode& ec)
+void MessagePort::postMessage(RefPtr<SerializedScriptValue>&& message, Vector<RefPtr<MessagePort>>&& ports, ExceptionCode& ec)
 {
     if (!isEntangled())
         return;
@@ -61,14 +61,14 @@ void MessagePort::postMessage(RefPtr<SerializedScriptValue>&& message, const Mes
 
     std::unique_ptr<MessagePortChannelArray> channels;
     // Make sure we aren't connected to any of the passed-in ports.
-    if (ports) {
-        for (auto& dataPort : *ports) {
+    if (!ports.isEmpty()) {
+        for (auto& dataPort : ports) {
             if (dataPort == this || m_entangledChannel->isConnectedTo(dataPort.get())) {
                 ec = DATA_CLONE_ERR;
                 return;
             }
         }
-        channels = MessagePort::disentanglePorts(ports, ec);
+        channels = MessagePort::disentanglePorts(WTFMove(ports), ec);
         if (ec)
             return;
     }
@@ -152,7 +152,7 @@ void MessagePort::dispatchMessages()
         if (is<WorkerGlobalScope>(*m_scriptExecutionContext) && downcast<WorkerGlobalScope>(*m_scriptExecutionContext).isClosing())
             return;
 
-        std::unique_ptr<MessagePortArray> ports = MessagePort::entanglePorts(*m_scriptExecutionContext, WTFMove(channels));
+        Vector<RefPtr<MessagePort>> ports = MessagePort::entanglePorts(*m_scriptExecutionContext, WTFMove(channels));
         Ref<Event> event = MessageEvent::create(WTFMove(ports), WTFMove(message));
         dispatchEvent(event);
     }
@@ -174,16 +174,16 @@ MessagePort* MessagePort::locallyEntangledPort()
     return m_entangledChannel ? m_entangledChannel->locallyEntangledPort(m_scriptExecutionContext) : nullptr;
 }
 
-std::unique_ptr<MessagePortChannelArray> MessagePort::disentanglePorts(const MessagePortArray* ports, ExceptionCode& ec)
+std::unique_ptr<MessagePortChannelArray> MessagePort::disentanglePorts(Vector<RefPtr<MessagePort>>&& ports, ExceptionCode& ec)
 {
-    if (!ports || !ports->size())
+    if (ports.isEmpty())
         return nullptr;
 
     // HashSet used to efficiently check for duplicates in the passed-in array.
     HashSet<MessagePort*> portSet;
 
     // Walk the incoming array - if there are any duplicate ports, or null ports or cloned ports, throw an error (per section 8.3.3 of the HTML5 spec).
-    for (auto& port : *ports) {
+    for (auto& port : ports) {
         if (!port || port->isNeutered() || portSet.contains(port.get())) {
             ec = DATA_CLONE_ERR;
             return nullptr;
@@ -192,24 +192,25 @@ std::unique_ptr<MessagePortChannelArray> MessagePort::disentanglePorts(const Mes
     }
 
     // Passed-in ports passed validity checks, so we can disentangle them.
-    auto portArray = std::make_unique<MessagePortChannelArray>(ports->size());
-    for (unsigned int i = 0 ; i < ports->size() ; ++i) {
-        std::unique_ptr<MessagePortChannel> channel = (*ports)[i]->disentangle();
+    auto portArray = std::make_unique<MessagePortChannelArray>(ports.size());
+    for (unsigned int i = 0 ; i < ports.size() ; ++i) {
+        std::unique_ptr<MessagePortChannel> channel = ports[i]->disentangle();
         (*portArray)[i] = WTFMove(channel);
     }
     return portArray;
 }
 
-std::unique_ptr<MessagePortArray> MessagePort::entanglePorts(ScriptExecutionContext& context, std::unique_ptr<MessagePortChannelArray> channels)
+Vector<RefPtr<MessagePort>> MessagePort::entanglePorts(ScriptExecutionContext& context, std::unique_ptr<MessagePortChannelArray> channels)
 {
     if (!channels || !channels->size())
-        return nullptr;
+        return { };
 
-    auto portArray = std::make_unique<MessagePortArray>(channels->size());
+    Vector<RefPtr<MessagePort>> portArray;
+    portArray.reserveInitialCapacity(channels->size());
     for (unsigned int i = 0; i < channels->size(); ++i) {
         auto port = MessagePort::create(context);
         port->entangle(WTFMove((*channels)[i]));
-        (*portArray)[i] = WTFMove(port);
+        portArray.uncheckedAppend(WTFMove(port));
     }
     return portArray;
 }
index 7677018..099ee51 100644 (file)
@@ -42,15 +42,12 @@ namespace WebCore {
     class MessagePort;
     class ScriptExecutionContext;
 
-    // The overwhelmingly common case is sending a single port, so handle that efficiently with an inline buffer of size 1.
-    typedef Vector<RefPtr<MessagePort>, 1> MessagePortArray;
-
     class MessagePort final : public RefCounted<MessagePort>, public EventTargetWithInlineData {
     public:
         static Ref<MessagePort> create(ScriptExecutionContext& scriptExecutionContext) { return adoptRef(*new MessagePort(scriptExecutionContext)); }
         virtual ~MessagePort();
 
-        void postMessage(RefPtr<SerializedScriptValue>&& message, const MessagePortArray*, ExceptionCode&);
+        void postMessage(RefPtr<SerializedScriptValue>&& message, Vector<RefPtr<MessagePort>>&&, ExceptionCode&);
 
         void start();
         void close();
@@ -59,10 +56,9 @@ namespace WebCore {
         std::unique_ptr<MessagePortChannel> disentangle();
 
         // Returns 0 if there is an exception, or if the passed-in array is 0/empty.
-        static std::unique_ptr<MessagePortChannelArray> disentanglePorts(const MessagePortArray*, ExceptionCode&);
+        static std::unique_ptr<MessagePortChannelArray> disentanglePorts(Vector<RefPtr<MessagePort>>&&, ExceptionCode&);
 
-        // Returns 0 if the passed array is 0/empty.
-        static std::unique_ptr<MessagePortArray> entanglePorts(ScriptExecutionContext&, std::unique_ptr<MessagePortChannelArray>);
+        static Vector<RefPtr<MessagePort>> entanglePorts(ScriptExecutionContext&, std::unique_ptr<MessagePortChannelArray>);
 
         void messageAvailable();
         bool started() const { return m_started; }
index f065bc1..8939c96 100644 (file)
@@ -70,7 +70,7 @@ RefPtr<SerializedScriptValue> PopStateEvent::trySerializeState(JSC::ExecState* e
     ASSERT(!m_state.hasNoValue());
     
     if (!m_serializedState && !m_triedToSerialize) {
-        m_serializedState = SerializedScriptValue::create(exec, m_state.jsValue(), nullptr, nullptr, NonThrowing);
+        m_serializedState = SerializedScriptValue::create(*exec, m_state.jsValue(), NonThrowing);
         m_triedToSerialize = true;
     }
     
index eb82e72..e1e0880 100644 (file)
@@ -906,7 +906,7 @@ Storage* DOMWindow::localStorage(ExceptionCode& ec) const
     return m_localStorage.get();
 }
 
-void DOMWindow::postMessage(PassRefPtr<SerializedScriptValue> message, const MessagePortArray* ports, const String& targetOrigin, DOMWindow& source, ExceptionCode& ec)
+void DOMWindow::postMessage(PassRefPtr<SerializedScriptValue> message, Vector<RefPtr<MessagePort>>&& ports, const String& targetOrigin, DOMWindow& source, ExceptionCode& ec)
 {
     if (!isCurrentlyDisplayedInFrame())
         return;
@@ -930,7 +930,7 @@ void DOMWindow::postMessage(PassRefPtr<SerializedScriptValue> message, const Mes
         }
     }
 
-    auto channels = MessagePort::disentanglePorts(ports, ec);
+    auto channels = MessagePort::disentanglePorts(WTFMove(ports), ec);
     if (ec)
         return;
 
index 51e80d4..cdb2329 100644 (file)
@@ -88,8 +88,6 @@ namespace WebCore {
 
     struct WindowFeatures;
 
-    typedef Vector<RefPtr<MessagePort>, 1> MessagePortArray;
-
     typedef int ExceptionCode;
 
     enum SetLocationLocking { LockHistoryBasedOnGestureState, LockHistoryAndBackForwardList };
@@ -241,7 +239,7 @@ namespace WebCore {
         void printErrorMessage(const String&);
         String crossDomainAccessErrorMessage(const DOMWindow& activeWindow);
 
-        void postMessage(PassRefPtr<SerializedScriptValue> message, const MessagePortArray*, const String& targetOrigin, DOMWindow& source, ExceptionCode&);
+        void postMessage(PassRefPtr<SerializedScriptValue> message, Vector<RefPtr<MessagePort>>&&, const String& targetOrigin, DOMWindow& source, ExceptionCode&);
         void postMessageTimerFired(PostMessageTimer&);
         void dispatchMessageEventWithOriginCheck(SecurityOrigin* intendedTargetOrigin, Event&, PassRefPtr<Inspector::ScriptCallStack>);
 
index e2253be..8e1bbf5 100644 (file)
@@ -63,10 +63,10 @@ EventTargetInterface DedicatedWorkerGlobalScope::eventTargetInterface() const
     return DedicatedWorkerGlobalScopeEventTargetInterfaceType;
 }
 
-void DedicatedWorkerGlobalScope::postMessage(RefPtr<SerializedScriptValue>&& message, const MessagePortArray* ports, ExceptionCode& ec)
+void DedicatedWorkerGlobalScope::postMessage(RefPtr<SerializedScriptValue>&& message, Vector<RefPtr<MessagePort>>&& ports, ExceptionCode& ec)
 {
     // Disentangle the port in preparation for sending it to the remote context.
-    auto channels = MessagePort::disentanglePorts(ports, ec);
+    auto channels = MessagePort::disentanglePorts(WTFMove(ports), ec);
     if (ec)
         return;
     thread().workerObjectProxy().postMessageToWorkerObject(WTFMove(message), WTFMove(channels));
index 4cc5f7e..b120cb8 100644 (file)
@@ -53,7 +53,7 @@ namespace WebCore {
         // EventTarget
         EventTargetInterface eventTargetInterface() const override;
 
-        void postMessage(RefPtr<SerializedScriptValue>&&, const MessagePortArray*, ExceptionCode&);
+        void postMessage(RefPtr<SerializedScriptValue>&&, Vector<RefPtr<MessagePort>>&&, ExceptionCode&);
 
         DedicatedWorkerThread& thread();
 
index 306d247..c827cad 100644 (file)
@@ -107,10 +107,10 @@ Worker::~Worker()
     m_contextProxy->workerObjectDestroyed();
 }
 
-void Worker::postMessage(RefPtr<SerializedScriptValue>&& message, const MessagePortArray* ports, ExceptionCode& ec)
+void Worker::postMessage(RefPtr<SerializedScriptValue>&& message, Vector<RefPtr<MessagePort>>&& ports, ExceptionCode& ec)
 {
     // Disentangle the port in preparation for sending it to the remote context.
-    auto channels = MessagePort::disentanglePorts(ports, ec);
+    auto channels = MessagePort::disentanglePorts(WTFMove(ports), ec);
     if (ec)
         return;
     m_contextProxy->postMessageToWorkerGlobalScope(WTFMove(message), WTFMove(channels));
index ebcc50e..e17ceba 100644 (file)
@@ -54,7 +54,7 @@ namespace WebCore {
 
         EventTargetInterface eventTargetInterface() const override { return WorkerEventTargetInterfaceType; }
 
-        void postMessage(RefPtr<SerializedScriptValue>&& message, const MessagePortArray*, ExceptionCode&);
+        void postMessage(RefPtr<SerializedScriptValue>&& message, Vector<RefPtr<MessagePort>>&&, ExceptionCode&);
 
         void terminate();