optional sequence values not handled correctly by binding generator
authorweinig@apple.com <weinig@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 3 Dec 2016 20:22:43 +0000 (20:22 +0000)
committerweinig@apple.com <weinig@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 3 Dec 2016 20:22:43 +0000 (20:22 +0000)
https://bugs.webkit.org/show_bug.cgi?id=142562

Source/WebCore:

Also fixes:
    Remove non-standard postMessage overload
    https://bugs.webkit.org/show_bug.cgi?id=161911
and
    Wrong argument order in window.postMessage
    https://bugs.webkit.org/show_bug.cgi?id=63141

Reviewed by Darin Adler.

* WebCore.xcodeproj/project.pbxproj:
Remove no longer needed files.

* bindings/generic/IDLTypes.h:
* bindings/js/JSDOMConvert.h:
(WebCore::Converter<IDLObject>::convert):
Add support for the WebIDL object type.

* bindings/js/JSDOMBinding.cpp:
(WebCore::createDOMException):
Add support for throwing stack overflow errors.

* bindings/js/JSDOMWindowCustom.cpp:
(WebCore::handlePostMessage): Deleted.
(WebCore::JSDOMWindow::postMessage): Deleted.
* bindings/js/JSDedicatedWorkerGlobalScopeCustom.cpp: Removed.
* bindings/js/JSMessagePortCustom.cpp:
(WebCore::JSMessagePort::postMessage): Deleted.
(WebCore::extractTransferables): Deleted.
* bindings/js/JSMessagePortCustom.h: Removed.
* bindings/js/JSWorkerCustom.cpp:
(WebCore::JSWorker::postMessage): Deleted.
Remove custom bindings for postMessage.

* bindings/js/SerializedScriptValue.h:
Switch to using enum class.

* bindings/js/SerializedScriptValue.cpp:
(WebCore::SerializedScriptValue::transferArrayBuffers):
(WebCore::SerializedScriptValue::create):
Add new create function that takes the transfer list, processes it, and returns
MessagePorts and SerializedScriptValue / exception.

(WebCore::CloneBase::throwStackOverflow): Deleted.
(WebCore::CloneDeserializer::throwValidationError): Deleted.
Remove uncalled functions.

* bindings/scripts/CodeGenerator.pm:
(IsRefPtrType):
(IsBuiltinType):
* bindings/scripts/CodeGeneratorJS.pm:
(AddToIncludesForIDLType):
(GetBaseIDLType):
Add support for the WebIDL 'object' type.

* bindings/scripts/test/JS/JSTestObj.cpp:
* bindings/scripts/test/TestObj.idl:
Add tests for 'object'.

* dom/ExceptionCode.h:
Add two new ExceptionCodes:
  - ExistingExceptionError, to indicate that implementation code threw a JS exception.
  - StackOverflowError, to indicate that a stack overflow exception should be thrown.

* dom/MessagePort.cpp:
(WebCore::MessagePort::postMessage):
* dom/MessagePort.h:
* dom/MessagePort.idl:
* page/DOMWindow.cpp:
(WebCore::DOMWindow::postMessage):
* page/DOMWindow.h:
* page/DOMWindow.idl:
* workers/DedicatedWorkerGlobalScope.cpp:
(WebCore::DedicatedWorkerGlobalScope::postMessage):
* workers/DedicatedWorkerGlobalScope.h:
* workers/DedicatedWorkerGlobalScope.idl:
* workers/Worker.cpp:
(WebCore::Worker::postMessage):
* workers/Worker.h:
* workers/Worker.idl:
Update to call new SerializedScriptValue create function.

LayoutTests:

Reviewed by Darin Adler.

* fast/canvas/webgl/resources/typed-array-worker.js:
* fast/dom/Window/window-postmessage-args-expected.txt:
* fast/dom/Window/window-postmessage-args.html:
* fast/events/message-port-deleted-document.html:
* fast/events/message-port-deleted-frame.html:
* fast/events/message-port-inactive-document.html:
* fast/events/message-port-multi-expected.txt:
* fast/events/message-port.html:
* fast/workers/worker-context-multi-port-expected.txt:
* fast/workers/worker-multi-port-expected.txt:
* webgl/1.0.2/resources/webgl_test_files/conformance/typedarrays/resources/typed-array-worker.js:
* webgl/1.0.3/resources/webgl_test_files/conformance/typedarrays/resources/typed-array-worker.js:
Update for new exceptions and stricter enforcement of the postMessage signature.

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

44 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/canvas/webgl/resources/typed-array-worker.js
LayoutTests/fast/dom/Window/window-postmessage-args-expected.txt
LayoutTests/fast/dom/Window/window-postmessage-args.html
LayoutTests/fast/events/message-port-deleted-document.html
LayoutTests/fast/events/message-port-deleted-frame.html
LayoutTests/fast/events/message-port-inactive-document.html
LayoutTests/fast/events/message-port-multi-expected.txt
LayoutTests/fast/events/message-port.html
LayoutTests/fast/workers/worker-context-multi-port-expected.txt
LayoutTests/fast/workers/worker-multi-port-expected.txt
LayoutTests/webgl/1.0.2/resources/webgl_test_files/conformance/typedarrays/resources/typed-array-worker.js
LayoutTests/webgl/1.0.3/resources/webgl_test_files/conformance/typedarrays/resources/typed-array-worker.js
Source/WebCore/CMakeLists.txt
Source/WebCore/ChangeLog
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/bindings/generic/IDLTypes.h
Source/WebCore/bindings/js/JSBindingsAllInOne.cpp
Source/WebCore/bindings/js/JSDOMBinding.cpp
Source/WebCore/bindings/js/JSDOMConvert.h
Source/WebCore/bindings/js/JSDOMWindowCustom.cpp
Source/WebCore/bindings/js/JSDedicatedWorkerGlobalScopeCustom.cpp [deleted file]
Source/WebCore/bindings/js/JSMessagePortCustom.cpp
Source/WebCore/bindings/js/JSMessagePortCustom.h [deleted file]
Source/WebCore/bindings/js/JSWorkerCustom.cpp
Source/WebCore/bindings/js/SerializedScriptValue.cpp
Source/WebCore/bindings/js/SerializedScriptValue.h
Source/WebCore/bindings/scripts/CodeGenerator.pm
Source/WebCore/bindings/scripts/CodeGeneratorJS.pm
Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp
Source/WebCore/bindings/scripts/test/TestObj.idl
Source/WebCore/dom/ExceptionCode.h
Source/WebCore/dom/MessagePort.cpp
Source/WebCore/dom/MessagePort.h
Source/WebCore/dom/MessagePort.idl
Source/WebCore/page/DOMWindow.cpp
Source/WebCore/page/DOMWindow.h
Source/WebCore/page/DOMWindow.idl
Source/WebCore/workers/DedicatedWorkerGlobalScope.cpp
Source/WebCore/workers/DedicatedWorkerGlobalScope.h
Source/WebCore/workers/DedicatedWorkerGlobalScope.idl
Source/WebCore/workers/Worker.cpp
Source/WebCore/workers/Worker.h
Source/WebCore/workers/Worker.idl

index 989a202..9381fbc 100644 (file)
@@ -1,3 +1,24 @@
+2016-12-02  Sam Weinig  <sam@webkit.org>
+
+        optional sequence values not handled correctly by binding generator
+        https://bugs.webkit.org/show_bug.cgi?id=142562
+
+        Reviewed by Darin Adler.
+
+        * fast/canvas/webgl/resources/typed-array-worker.js:
+        * fast/dom/Window/window-postmessage-args-expected.txt:
+        * fast/dom/Window/window-postmessage-args.html:
+        * fast/events/message-port-deleted-document.html:
+        * fast/events/message-port-deleted-frame.html:
+        * fast/events/message-port-inactive-document.html:
+        * fast/events/message-port-multi-expected.txt:
+        * fast/events/message-port.html:
+        * fast/workers/worker-context-multi-port-expected.txt:
+        * fast/workers/worker-multi-port-expected.txt:
+        * webgl/1.0.2/resources/webgl_test_files/conformance/typedarrays/resources/typed-array-worker.js:
+        * webgl/1.0.3/resources/webgl_test_files/conformance/typedarrays/resources/typed-array-worker.js:
+        Update for new exceptions and stricter enforcement of the postMessage signature. 
+
 2016-12-02  Simon Fraser  <simon.fraser@apple.com>
 
         Improve the behavior of scroll-into-view when the target is inside position:fixed
index 6050865..5ff6221 100644 (file)
@@ -74,7 +74,7 @@ onmessage = function(event) {
     } else {
       valueToSend = view.buffer;
     }
-    var transferablesToSend = null;
+    var transferablesToSend = [];
     if (message.command == 'transfer' ||
         message.command == 'transferBuffer') {
       transferablesToSend = [ view.buffer ];
index 040d628..e65bbbf 100644 (file)
@@ -2,13 +2,13 @@ Test that the second argument of window.postMessage is ignored or triggers an er
 
 PASS: Posting message ('1', 1): threw exception TypeError: Value is not a sequence
 PASS: Posting message ('2', c): threw exception TypeError: Value is not a sequence
-PASS: Posting message ('3', [object Object]): threw exception TypeError: Value is not a sequence
-PASS: Posting message ('4', [object Window]) did not throw an exception
-PASS: Posting message ('4a', *) did not throw an exception
+PASS: Posting message ('3', [object Object]): threw exception TypeError: Type error
+PASS: Posting message ('4', [object Window]): threw exception TypeError: Type error
+PASS: Posting message ('4a', *): threw exception TypeError: Value is not a sequence
 PASS: Posting message ('5', null) did not throw an exception
 PASS: Posting message ('6', undefined) did not throw an exception
 PASS: Posting message ('7', [object MessagePort],[object MessagePort]) did not throw an exception
-PASS: Posting message ('7a', *) did not throw an exception
+PASS: Posting message ('7a', *): threw exception TypeError: Value is not a sequence
 PASS: Posting message ('7', [object MessagePort],[object MessagePort]) did not throw an exception
 PASS: Posting message ('2147483648', null) did not throw an exception
 PASS: Posting message ('[object MessagePort]', [object MessagePort],[object MessagePort]) did not throw an exception
@@ -18,12 +18,9 @@ PASS: Posting message ('[object ArrayBuffer]', [object ArrayBuffer]) did not thr
 PASS: arrayBuffer neutered
 PASS: view neutered
 PASS: Posting message ('done', undefined) did not throw an exception
-Received message '4' with 0 ports.
-Received message '4a' with 0 ports.
 Received message '5' with 0 ports.
 Received message '6' with 0 ports.
 Received message '7' with 2 ports.
-Received message '7a' with 2 ports.
 Received message '7' with 2 ports.
 Received message '2147483648' with 0 ports.
 Received message '[object MessagePort]' with 2 ports.
index f46acfe..007726d 100644 (file)
@@ -44,14 +44,14 @@ document.getElementById("description").innerHTML = "Test that the second argumen
 tryPostMessage('1', '*', 1, true);
 tryPostMessage('2', '*', 'c', true);
 tryPostMessage('3', '*', { x: 1 }, true);
-tryPostMessage('4', '*', window);  // Passes because window has a "length" attribute of value '0', so it looks like an array
-tryPostMessage('4a', window, '*'); // Legacy argument order.
+tryPostMessage('4', '*', window, true);
+tryPostMessage('4a', window, '*', true); // Legacy argument order.
 tryPostMessage('5', '*', null);
 tryPostMessage('6', '*', void 0);
 var channel1 = new MessageChannel;
 tryPostMessageFunction(window.postMessage, '7', '*', [channel1.port1, channel1.port2]);
 var channel1a = new MessageChannel;
-tryPostMessageFunction(window.postMessage, '7a', [channel1a.port1, channel1a.port2], '*');
+tryPostMessageFunction(window.postMessage, '7a', [channel1a.port1, channel1a.port2], '*', true);
 var channel2 = new MessageChannel;
 tryPostMessageFunction(window.postMessage, '7', '*', [channel2.port1, channel2.port2]);
 var channel3 = new MessageChannel;
index e2c06d1..6e420d3 100644 (file)
@@ -27,7 +27,7 @@ var mainPort;
 function test()
 {
     var channel = new MessageChannel;
-    window.frames[0].postMessage("msg", [channel.port2], "*");
+    window.frames[0].postMessage("msg", "*", [channel.port2]);
     mainPort = channel.port1;
     mainPort.start();
 
index 30599a3..22accfc 100644 (file)
@@ -29,7 +29,7 @@ function test()
 {
     frameDoc = window.frames[0].document;
     var channel = new MessageChannel;
-    window.frames[0].postMessage("msg", [channel.port2], "*");
+    window.frames[0].postMessage("msg", "*", [channel.port2]);
     mainPort = channel.port1;
     mainPort.start();
 
index 23f7fb6..d7c81a7 100644 (file)
@@ -29,7 +29,7 @@ function test()
 {
     otherDocument = window.frames[0].document;
     var channel = new MessageChannel;
-    window.frames[0].postMessage("msg", [channel.port2], "*");
+    window.frames[0].postMessage("msg", "*", [channel.port2]);
     mainPort = channel.port1;
     mainPort.start();
 
index e9fb106..4645996 100644 (file)
@@ -5,12 +5,12 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE
 
 PASS channel.port1.postMessage("same port", [channel.port1]) threw exception DataCloneError (DOM Exception 25): The object can not be cloned..
 PASS channel.port1.postMessage("entangled port", [channel.port2]) threw exception DataCloneError (DOM Exception 25): The object can not be cloned..
-PASS channel.port1.postMessage("null port", [channel3.port1, null, channel3.port2]) threw exception InvalidStateError (DOM Exception 11): The object is in an invalid state..
-PASS channel.port1.postMessage("notAPort", [channel3.port1, {}, channel3.port2]) threw exception TypeError: Type error.
-PASS channel.port1.postMessage("duplicate port", [channel3.port1, channel3.port1]) threw exception InvalidStateError (DOM Exception 11): The object is in an invalid state..
-PASS channel.port1.postMessage("notAnArray", channel3.port1) threw exception TypeError: Value is not a sequence.
-PASS channel.port1.postMessage("notASequence", [{length: 3}]) threw exception TypeError: Type error.
-PASS channel.port1.postMessage("largeSequence", largePortArray) threw exception InvalidStateError (DOM Exception 11): The object is in an invalid state..
+PASS channel.port1.postMessage("null port", [channel3.port1, null, channel3.port2]) threw exception TypeError: Type error.
+PASS channel.port1.postMessage("notAPort", [channel3.port1, {}, channel3.port2]) threw exception DataCloneError (DOM Exception 25): The object can not be cloned..
+PASS channel.port1.postMessage("duplicate port", [channel3.port1, channel3.port1]) threw exception DataCloneError (DOM Exception 25): The object can not be cloned..
+PASS channel.port1.postMessage("notAnArray", channel3.port1) threw exception TypeError: Type error.
+PASS channel.port1.postMessage("notASequence", [{length: 3}]) threw exception DataCloneError (DOM Exception 25): The object can not be cloned..
+PASS channel.port1.postMessage("largeSequence", largePortArray) threw exception TypeError: Type error.
 PASS event.ports is non-null and zero length when no port sent
 PASS event.ports is non-null and zero length when empty array sent
 PASS event.ports contains two ports when two ports sent
index 36dc0a1..c0b7632 100644 (file)
@@ -38,7 +38,7 @@ function test(postMessageFun)
 {
     var channel = new MessageChannel;
 
-    window.frames[0][postMessageFun]("msg", [channel.port2], "*");
+    window.frames[0][postMessageFun]("msg", "*", [channel.port2]);
     mainPort = channel.port1;
     mainPort[postMessageFun]("ping");
     mainPort.onmessage = function(evt) {
index d162cc9..5e64444 100644 (file)
@@ -6,11 +6,11 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE
 PASS event.ports is non-null and zero length when no port sent
 PASS event.ports is non-null and zero length when empty array sent
 PASS event.ports contains two ports when two ports sent
-PASS posting a null port did throw: InvalidStateError (DOM Exception 11): The object is in an invalid state.
-PASS posting a non-port did throw: TypeError: Type error
+PASS posting a null port did throw: TypeError: Type error
+PASS posting a non-port did throw: DataCloneError (DOM Exception 25): The object can not be cloned.
 PASS event.ports contains two ports when two ports re-sent after error
-PASS posting a non-array did throw: TypeError: Value is not a sequence
-PASS posting a non-sequence did throw: TypeError: Type error
+PASS posting a non-array did throw: TypeError: Type error
+PASS posting a non-sequence did throw: DataCloneError (DOM Exception 25): The object can not be cloned.
 
 TEST COMPLETE
 
index e9c1828..d79250c 100644 (file)
@@ -3,10 +3,10 @@ This test checks the various use cases around sending multiple ports through Wor
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
-PASS worker.postMessage("null port", [channel3.port1, null, channel3.port2]) threw exception InvalidStateError (DOM Exception 11): The object is in an invalid state..
-PASS worker.postMessage("notAPort", [channel3.port1, {}, channel3.port2]) threw exception TypeError: Type error.
-PASS worker.postMessage("notAnArray", channel3.port1) threw exception TypeError: Value is not a sequence.
-PASS worker.postMessage("notASequence", [{length: 3}]) threw exception TypeError: Type error.
+PASS worker.postMessage("null port", [channel3.port1, null, channel3.port2]) threw exception TypeError: Type error.
+PASS worker.postMessage("notAPort", [channel3.port1, {}, channel3.port2]) threw exception DataCloneError (DOM Exception 25): The object can not be cloned..
+PASS worker.postMessage("notAnArray", channel3.port1) threw exception TypeError: Type error.
+PASS worker.postMessage("notASequence", [{length: 3}]) threw exception DataCloneError (DOM Exception 25): The object can not be cloned..
 PASS event.ports is non-null and zero length when no port sent
 PASS event.ports is non-null and zero length when empty array sent
 PASS event.ports contains two ports when two ports sent
index 6050865..5ff6221 100644 (file)
@@ -74,7 +74,7 @@ onmessage = function(event) {
     } else {
       valueToSend = view.buffer;
     }
-    var transferablesToSend = null;
+    var transferablesToSend = [];
     if (message.command == 'transfer' ||
         message.command == 'transferBuffer') {
       transferablesToSend = [ view.buffer ];
index 6050865..5ff6221 100644 (file)
@@ -74,7 +74,7 @@ onmessage = function(event) {
     } else {
       valueToSend = view.buffer;
     }
-    var transferablesToSend = null;
+    var transferablesToSend = [];
     if (message.command == 'transfer' ||
         message.command == 'transferBuffer') {
       transferablesToSend = [ view.buffer ];
index 6bb8a7b..b991f59 100644 (file)
@@ -1129,7 +1129,6 @@ set(WebCore_SOURCES
     bindings/js/JSDOMWrapper.cpp
     bindings/js/JSDataCueCustom.cpp
     bindings/js/JSDataTransferCustom.cpp
-    bindings/js/JSDedicatedWorkerGlobalScopeCustom.cpp
     bindings/js/JSDeviceMotionEventCustom.cpp
     bindings/js/JSDeviceOrientationEventCustom.cpp
     bindings/js/JSDictionary.cpp
index 80c0efe..7f57b7b 100644 (file)
@@ -1,3 +1,89 @@
+2016-12-02  Sam Weinig  <sam@webkit.org>
+
+        optional sequence values not handled correctly by binding generator
+        https://bugs.webkit.org/show_bug.cgi?id=142562
+
+        Also fixes:
+            Remove non-standard postMessage overload
+            https://bugs.webkit.org/show_bug.cgi?id=161911
+        and
+            Wrong argument order in window.postMessage
+            https://bugs.webkit.org/show_bug.cgi?id=63141
+
+        Reviewed by Darin Adler.
+
+        * WebCore.xcodeproj/project.pbxproj:
+        Remove no longer needed files.
+
+        * bindings/generic/IDLTypes.h:
+        * bindings/js/JSDOMConvert.h:
+        (WebCore::Converter<IDLObject>::convert):
+        Add support for the WebIDL object type.
+
+        * bindings/js/JSDOMBinding.cpp:
+        (WebCore::createDOMException):
+        Add support for throwing stack overflow errors.
+
+        * bindings/js/JSDOMWindowCustom.cpp:
+        (WebCore::handlePostMessage): Deleted.
+        (WebCore::JSDOMWindow::postMessage): Deleted.
+        * bindings/js/JSDedicatedWorkerGlobalScopeCustom.cpp: Removed.
+        * bindings/js/JSMessagePortCustom.cpp:
+        (WebCore::JSMessagePort::postMessage): Deleted.
+        (WebCore::extractTransferables): Deleted.
+        * bindings/js/JSMessagePortCustom.h: Removed.
+        * bindings/js/JSWorkerCustom.cpp:
+        (WebCore::JSWorker::postMessage): Deleted.
+        Remove custom bindings for postMessage.
+
+        * bindings/js/SerializedScriptValue.h:
+        Switch to using enum class.
+
+        * bindings/js/SerializedScriptValue.cpp:
+        (WebCore::SerializedScriptValue::transferArrayBuffers):
+        (WebCore::SerializedScriptValue::create):
+        Add new create function that takes the transfer list, processes it, and returns
+        MessagePorts and SerializedScriptValue / exception.
+
+        (WebCore::CloneBase::throwStackOverflow): Deleted.
+        (WebCore::CloneDeserializer::throwValidationError): Deleted.
+        Remove uncalled functions.
+
+        * bindings/scripts/CodeGenerator.pm:
+        (IsRefPtrType):
+        (IsBuiltinType):
+        * bindings/scripts/CodeGeneratorJS.pm:
+        (AddToIncludesForIDLType):
+        (GetBaseIDLType):
+        Add support for the WebIDL 'object' type.
+
+        * bindings/scripts/test/JS/JSTestObj.cpp:
+        * bindings/scripts/test/TestObj.idl:
+        Add tests for 'object'.
+
+        * dom/ExceptionCode.h:
+        Add two new ExceptionCodes:
+          - ExistingExceptionError, to indicate that implementation code threw a JS exception.
+          - StackOverflowError, to indicate that a stack overflow exception should be thrown.
+
+        * dom/MessagePort.cpp:
+        (WebCore::MessagePort::postMessage):
+        * dom/MessagePort.h:
+        * dom/MessagePort.idl:
+        * page/DOMWindow.cpp:
+        (WebCore::DOMWindow::postMessage):
+        * page/DOMWindow.h:
+        * page/DOMWindow.idl:
+        * workers/DedicatedWorkerGlobalScope.cpp:
+        (WebCore::DedicatedWorkerGlobalScope::postMessage):
+        * workers/DedicatedWorkerGlobalScope.h:
+        * workers/DedicatedWorkerGlobalScope.idl:
+        * workers/Worker.cpp:
+        (WebCore::Worker::postMessage):
+        * workers/Worker.h:
+        * workers/Worker.idl:
+        Update to call new SerializedScriptValue create function.
+
 2016-12-03  Dave Hyatt  <hyatt@apple.com>
 
         [CSS Parser] Support Dashboard Regions
index ff39770..53541e8 100644 (file)
                41614A791DA64241004AD06F /* HTTPHeaderValues.h in Headers */ = {isa = PBXBuildFile; fileRef = 41614A771DA64236004AD06F /* HTTPHeaderValues.h */; };
                4162A450101145AE00DFF3ED /* DedicatedWorkerGlobalScope.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4162A44D101145AE00DFF3ED /* DedicatedWorkerGlobalScope.cpp */; };
                4162A451101145AE00DFF3ED /* DedicatedWorkerGlobalScope.h in Headers */ = {isa = PBXBuildFile; fileRef = 4162A44E101145AE00DFF3ED /* DedicatedWorkerGlobalScope.h */; };
-               4162A454101145E300DFF3ED /* JSDedicatedWorkerGlobalScopeCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4162A453101145E300DFF3ED /* JSDedicatedWorkerGlobalScopeCustom.cpp */; };
                4162A4571011464700DFF3ED /* JSDedicatedWorkerGlobalScope.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4162A4551011464700DFF3ED /* JSDedicatedWorkerGlobalScope.cpp */; };
                4162A4581011464700DFF3ED /* JSDedicatedWorkerGlobalScope.h in Headers */ = {isa = PBXBuildFile; fileRef = 4162A4561011464700DFF3ED /* JSDedicatedWorkerGlobalScope.h */; };
                416E29A6102FA962007FC14E /* WorkerReportingProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 416E29A5102FA962007FC14E /* WorkerReportingProxy.h */; };
                41F54F8B1C50C50300338488 /* FetchBody.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41F54F7D1C50C4F600338488 /* FetchBody.cpp */; };
                41F54F8D1C50C50800338488 /* FetchHeaders.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41F54F821C50C4F600338488 /* FetchHeaders.cpp */; };
                41F54F8E1C50C50C00338488 /* FetchRequest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41F54F871C50C4F600338488 /* FetchRequest.cpp */; };
-               41F584C7104652CB009CAA64 /* JSMessagePortCustom.h in Headers */ = {isa = PBXBuildFile; fileRef = 41F584C6104652CB009CAA64 /* JSMessagePortCustom.h */; };
                41FA303E1316C29C00C0BFC5 /* RenderMediaControls.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41FA303C1316C29C00C0BFC5 /* RenderMediaControls.cpp */; };
                41FA303F1316C29C00C0BFC5 /* RenderMediaControls.h in Headers */ = {isa = PBXBuildFile; fileRef = 41FA303D1316C29C00C0BFC5 /* RenderMediaControls.h */; };
                4306E4E614955543007F17AC /* KillRingNone.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4306E4E514955543007F17AC /* KillRingNone.cpp */; };
                4162A44D101145AE00DFF3ED /* DedicatedWorkerGlobalScope.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DedicatedWorkerGlobalScope.cpp; sourceTree = "<group>"; };
                4162A44E101145AE00DFF3ED /* DedicatedWorkerGlobalScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DedicatedWorkerGlobalScope.h; sourceTree = "<group>"; };
                4162A44F101145AE00DFF3ED /* DedicatedWorkerGlobalScope.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = DedicatedWorkerGlobalScope.idl; sourceTree = "<group>"; };
-               4162A453101145E300DFF3ED /* JSDedicatedWorkerGlobalScopeCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDedicatedWorkerGlobalScopeCustom.cpp; sourceTree = "<group>"; };
                4162A4551011464700DFF3ED /* JSDedicatedWorkerGlobalScope.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDedicatedWorkerGlobalScope.cpp; sourceTree = "<group>"; };
                4162A4561011464700DFF3ED /* JSDedicatedWorkerGlobalScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDedicatedWorkerGlobalScope.h; sourceTree = "<group>"; };
                416E29A5102FA962007FC14E /* WorkerReportingProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WorkerReportingProxy.h; sourceTree = "<group>"; };
                41F54F871C50C4F600338488 /* FetchRequest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FetchRequest.cpp; sourceTree = "<group>"; };
                41F54F881C50C4F600338488 /* FetchRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FetchRequest.h; sourceTree = "<group>"; };
                41F54F891C50C4F600338488 /* FetchRequest.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = FetchRequest.idl; sourceTree = "<group>"; };
-               41F584C6104652CB009CAA64 /* JSMessagePortCustom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSMessagePortCustom.h; sourceTree = "<group>"; };
                41FA303C1316C29C00C0BFC5 /* RenderMediaControls.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderMediaControls.cpp; sourceTree = "<group>"; };
                41FA303D1316C29C00C0BFC5 /* RenderMediaControls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderMediaControls.h; sourceTree = "<group>"; };
                4306E4E514955543007F17AC /* KillRingNone.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KillRingNone.cpp; sourceTree = "<group>"; };
                                DEC2975D1B4DEB2A005F5945 /* JSCustomEventCustom.cpp */,
                                07FBDE2B18FED178001A7CFF /* JSDataCueCustom.cpp */,
                                BCA83E510D7CE205003421A8 /* JSDataTransferCustom.cpp */,
-                               4162A453101145E300DFF3ED /* JSDedicatedWorkerGlobalScopeCustom.cpp */,
                                31FB1A6B120A5D6900DC02A0 /* JSDeviceMotionEventCustom.cpp */,
                                590E1B4A11E4EF700069F784 /* JSDeviceOrientationEventCustom.cpp */,
                                49C7BA8C1042F5B10009D447 /* JSDocumentCustom.cpp */,
                                E1A5F99A0E7EAA2500AF85EA /* JSMessageChannelCustom.cpp */,
                                410B7E711045FAB000D8224F /* JSMessageEventCustom.cpp */,
                                E1ADED460E76B8DD004A1A5E /* JSMessagePortCustom.cpp */,
-                               41F584C6104652CB009CAA64 /* JSMessagePortCustom.h */,
                                A1E5B31D1AAD1DA4006EBEFB /* JSMockContentFilterSettingsCustom.cpp */,
                                C6F0917E143A2BB900685849 /* JSMutationObserverCustom.cpp */,
                                BCD9C25F0C17AA67005C90A2 /* JSNamedNodeMapCustom.cpp */,
                                E107400E0E77BDC00033AF24 /* JSMessageChannel.h in Headers */,
                                75793EC90D0CE72D007FC0AC /* JSMessageEvent.h in Headers */,
                                E1ADEDDA0E76BD93004A1A5E /* JSMessagePort.h in Headers */,
-                               41F584C7104652CB009CAA64 /* JSMessagePortCustom.h in Headers */,
                                2D6F3E951C1F85550061DBD4 /* JSMockPageOverlay.h in Headers */,
                                A86629D109DA2B48009633A5 /* JSMouseEvent.h in Headers */,
                                830A36BD1DAC5FAD006D7D09 /* JSMouseEventInit.h in Headers */,
                                BCA83E4F0D7CE1E9003421A8 /* JSDataTransfer.cpp in Sources */,
                                BCA83E520D7CE205003421A8 /* JSDataTransferCustom.cpp in Sources */,
                                4162A4571011464700DFF3ED /* JSDedicatedWorkerGlobalScope.cpp in Sources */,
-                               4162A454101145E300DFF3ED /* JSDedicatedWorkerGlobalScopeCustom.cpp in Sources */,
                                FDA15ED112B03F94003A583A /* JSDelayNode.cpp in Sources */,
                                31FB1A65120A5D3F00DC02A0 /* JSDeviceMotionEvent.cpp in Sources */,
                                31FB1A6C120A5D6900DC02A0 /* JSDeviceMotionEventCustom.cpp in Sources */,
index 0ae04d5..63c3736 100644 (file)
@@ -34,6 +34,8 @@ namespace JSC {
 class ArrayBuffer;
 class ArrayBufferView;
 class JSValue;
+class JSObject;
+template<typename T> class Strong;
 }
 
 namespace WebCore {
@@ -94,7 +96,7 @@ struct IDLDOMString : IDLString { };
 struct IDLByteString : IDLString { };
 struct IDLUSVString : IDLString { };
 
-struct IDLObject : IDLUnsupportedType { };
+struct IDLObject : IDLType<JSC::Strong<JSC::JSObject>> { };
 
 template<typename T> struct IDLWrapper : IDLType<RefPtr<T>> {
     using RawType = T;
index c1ee21a..d954e17 100644 (file)
@@ -64,7 +64,6 @@
 #include "JSDOMWrapper.cpp"
 #include "JSDataCueCustom.cpp"
 #include "JSDataTransferCustom.cpp"
-#include "JSDedicatedWorkerGlobalScopeCustom.cpp"
 #include "JSDeviceOrientationEventCustom.cpp"
 #include "JSDictionary.cpp"
 #include "JSDocumentCustom.cpp"
index 76b9375..8deb815 100644 (file)
@@ -270,7 +270,7 @@ void reportCurrentException(ExecState* exec)
 
 static JSValue createDOMException(ExecState* exec, ExceptionCode ec, const String* message = nullptr)
 {
-    if (!ec)
+    if (!ec || ec == ExistingExceptionError)
         return jsUndefined();
 
     // FIXME: Handle other WebIDL exception types.
@@ -286,6 +286,9 @@ static JSValue createDOMException(ExecState* exec, ExceptionCode ec, const Strin
         return createRangeError(exec, *message);
     }
 
+    if (ec == StackOverflowError)
+        return createStackOverflowError(exec);
+
     // FIXME: All callers to setDOMException need to pass in the right global object
     // for now, we're going to assume the lexicalGlobalObject. Which is wrong in cases like this:
     // frames[0].document.createElement(null, null); // throws an exception which should have the subframes prototypes.
index 884296d..965383e 100644 (file)
@@ -813,6 +813,25 @@ template<> struct JSConverter<IDLUSVString> {
 };
 
 // MARK: -
+// MARK: Object type
+
+template<> struct Converter<IDLObject> : DefaultConverter<IDLObject> {
+    template<typename ExceptionThrower = DefaultExceptionThrower>
+    static JSC::Strong<JSC::JSObject> convert(JSC::ExecState& state, JSC::JSValue value, ExceptionThrower&& exceptionThrower = ExceptionThrower())
+    {
+        JSC::VM& vm = state.vm();
+        auto scope = DECLARE_THROW_SCOPE(vm);
+
+        if (!value.isObject()) {
+            exceptionThrower(state, scope);
+            return { };
+        }
+        
+        return { vm, JSC::asObject(value) };
+    }
+};
+
+// MARK: -
 // MARK: Array-like types
 
 namespace Detail {
index 76b89b8..6c6f3b7 100644 (file)
 #include "JSHTMLOptionElement.h"
 #include "JSIDBFactory.h"
 #include "JSImageConstructor.h"
-#include "JSMessagePortCustom.h"
 #include "JSWorker.h"
 #include "Location.h"
 #include "RuntimeEnabledFeatures.h"
 #include "ScheduledAction.h"
 #include "Settings.h"
+#include <runtime/JSCInlines.h>
 
 #if ENABLE(USER_MESSAGE_HANDLERS)
 #include "JSWebKitNamespace.h"
@@ -489,50 +489,6 @@ JSValue JSDOMWindow::showModalDialog(ExecState& state)
     return handler.returnValue();
 }
 
-static JSValue handlePostMessage(DOMWindow& impl, ExecState& state)
-{
-    VM& vm = state.vm();
-    auto scope = DECLARE_THROW_SCOPE(vm);
-
-    if (UNLIKELY(state.argumentCount() < 2))
-        return throwException(&state, scope, createNotEnoughArgumentsError(&state));
-
-    Vector<RefPtr<MessagePort>> messagePorts;
-    Vector<RefPtr<JSC::ArrayBuffer>> arrayBuffers;
-
-    // This function has variable arguments and can be:
-    // Per current spec:
-    //   postMessage(message, targetOrigin)
-    //   postMessage(message, targetOrigin, {sequence of transferrables})
-    // Legacy non-standard implementations in webkit allowed:
-    //   postMessage(message, {sequence of transferrables}, targetOrigin);
-    int targetOriginArgIndex = 1;
-    if (state.argumentCount() > 2) {
-        int transferablesArgIndex = 2;
-        if (state.uncheckedArgument(2).isString()) {
-            targetOriginArgIndex = 2;
-            transferablesArgIndex = 1;
-        }
-        extractTransferables(state, state.argument(transferablesArgIndex), messagePorts, arrayBuffers);
-    }
-    RETURN_IF_EXCEPTION(scope, JSValue());
-
-    auto message = SerializedScriptValue::create(state, state.uncheckedArgument(0), messagePorts, WTFMove(arrayBuffers));
-    RETURN_IF_EXCEPTION(scope, JSValue());
-
-    String targetOrigin = convert<IDLNullable<IDLUSVString>>(state, state.uncheckedArgument(targetOriginArgIndex));
-    RETURN_IF_EXCEPTION(scope, JSValue());
-
-    propagateException(state, scope, impl.postMessage(message.releaseNonNull(), WTFMove(messagePorts), targetOrigin, callerDOMWindow(&state)));
-
-    return jsUndefined();
-}
-
-JSValue JSDOMWindow::postMessage(ExecState& state)
-{
-    return handlePostMessage(wrapped(), state);
-}
-
 JSValue JSDOMWindow::setTimeout(ExecState& state)
 {
     VM& vm = state.vm();
diff --git a/Source/WebCore/bindings/js/JSDedicatedWorkerGlobalScopeCustom.cpp b/Source/WebCore/bindings/js/JSDedicatedWorkerGlobalScopeCustom.cpp
deleted file mode 100644 (file)
index ecd4a1e..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2009 Apple, Inc. All rights reserved.
- * Copyright (C) 2009, 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "JSDedicatedWorkerGlobalScope.h"
-
-#include "JSDOMBinding.h"
-#include "JSMessagePortCustom.h"
-
-using namespace JSC;
-
-namespace WebCore {
-
-JSC::JSValue JSDedicatedWorkerGlobalScope::postMessage(JSC::ExecState& state)
-{
-    return handlePostMessage(state, wrapped());
-}
-
-} // namespace WebCore
index 17387e3..b168cf2 100644 (file)
 #include "config.h"
 #include "JSMessagePort.h"
 
-#include "Event.h"
-#include "ExceptionCode.h"
-#include "Frame.h"
-#include "JSDOMBinding.h"
-#include "JSDOMGlobalObject.h"
-#include "JSEvent.h"
-#include "JSEventListener.h"
-#include "JSMessagePortCustom.h"
-#include "MessagePort.h"
-#include <heap/SlotVisitorInlines.h>
-#include <runtime/Error.h>
-#include <runtime/JSArrayBuffer.h>
-#include <wtf/text/AtomicString.h>
-
 using namespace JSC;
 
 namespace WebCore {
@@ -52,53 +38,4 @@ void JSMessagePort::visitAdditionalChildren(SlotVisitor& visitor)
         visitor.addOpaqueRoot(port);
 }
 
-JSC::JSValue JSMessagePort::postMessage(JSC::ExecState& state)
-{
-    return handlePostMessage(state, wrapped());
-}
-
-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);
-
-    if (value.isUndefinedOrNull()) {
-        portArray.resize(0);
-        arrayBuffers.resize(0);
-        return;
-    }
-
-    // Validation of sequence types, per WebIDL spec 4.1.13.
-    unsigned length = 0;
-    JSObject* object = toJSSequence(state, value, length);
-    RETURN_IF_EXCEPTION(scope, void());
-
-    for (unsigned i = 0 ; i < length; ++i) {
-        JSValue value = object->get(&state, i);
-        RETURN_IF_EXCEPTION(scope, void());
-
-        if (value.isUndefinedOrNull()) {
-            setDOMException(&state, INVALID_STATE_ERR);
-            return;
-        }
-
-        // Validation of Objects implementing an interface, per WebIDL spec 4.1.15.
-        if (RefPtr<MessagePort> port = JSMessagePort::toWrapped(value)) {
-            // Check for duplicate ports.
-            if (portArray.contains(port)) {
-                setDOMException(&state, INVALID_STATE_ERR);
-                return;
-            }
-            portArray.append(WTFMove(port));
-        } else {
-            if (RefPtr<ArrayBuffer> arrayBuffer = toPossiblySharedArrayBuffer(value))
-                arrayBuffers.append(WTFMove(arrayBuffer));
-            else {
-                throwTypeError(&state, scope);
-                return;
-            }
-        }
-    }
-}
-
 } // namespace WebCore
diff --git a/Source/WebCore/bindings/js/JSMessagePortCustom.h b/Source/WebCore/bindings/js/JSMessagePortCustom.h
deleted file mode 100644 (file)
index a8339cf..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2009 Google Inc. All rights reserved.
- * Copyright (C) 2016 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#pragma once
-
-#include "MessagePort.h"
-#include <runtime/Error.h>
-#include <runtime/JSCInlines.h>
-#include <runtime/JSCJSValue.h>
-#include <wtf/Forward.h>
-
-namespace WebCore {
-
-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> inline JSC::JSValue handlePostMessage(JSC::ExecState& state, T& object)
-{
-    JSC::VM& vm = state.vm();
-    auto scope = DECLARE_THROW_SCOPE(vm);
-
-    if (UNLIKELY(state.argumentCount() < 1))
-        return throwException(&state, scope, createNotEnoughArgumentsError(&state));
-
-    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());
-
-    propagateException(state, scope, object.postMessage(WTFMove(message), WTFMove(messagePortArray)));
-    return JSC::jsUndefined();
-}
-
-}
index 583c505..867313b 100644 (file)
@@ -31,7 +31,6 @@
 #include "JSDOMBinding.h"
 #include "JSDOMGlobalObject.h"
 #include "JSDOMWindowCustom.h"
-#include "JSMessagePortCustom.h"
 #include "Worker.h"
 #include <runtime/Error.h>
 
@@ -39,11 +38,6 @@ using namespace JSC;
 
 namespace WebCore {
 
-JSC::JSValue JSWorker::postMessage(JSC::ExecState& state)
-{
-    return handlePostMessage(state, wrapped());
-}
-
 EncodedJSValue JSC_HOST_CALL constructJSWorker(ExecState& state)
 {
     VM& vm = state.vm();
index df06d26..1220b34 100644 (file)
@@ -92,6 +92,16 @@ namespace WebCore {
 
 static const unsigned maximumFilterRecursion = 40000;
 
+enum class SerializationReturnCode {
+    SuccessfullyCompleted,
+    StackOverflowError,
+    InterruptedExecutionError,
+    ValidationError,
+    ExistingExceptionError,
+    DataCloneError,
+    UnspecifiedError
+};
+
 enum WalkerState { StateUnknown, ArrayStartState, ArrayStartVisitMember, ArrayEndVisitMember,
     ObjectStartState, ObjectStartVisitMember, ObjectEndVisitMember,
     MapDataStartVisitEntry, MapDataEndVisitKey, MapDataEndVisitValue,
@@ -374,7 +384,7 @@ static const unsigned StringDataIs8BitFlag = 0x80000000;
  *    <factorSize:uint32_t> <factor:byte{factorSize}> <crtExponentSize:uint32_t> <crtExponent:byte{crtExponentSize}> <crtCoefficientSize:uint32_t> <crtCoefficient:byte{crtCoefficientSize}>
  */
 
-typedef std::pair<JSC::JSValue, SerializationReturnCode> DeserializationResult;
+using DeserializationResult = std::pair<JSC::JSValue, SerializationReturnCode>;
 
 class CloneBase {
 protected:
@@ -391,13 +401,6 @@ protected:
         return scope.exception();
     }
 
-    void throwStackOverflow()
-    {
-        VM& vm = m_exec->vm();
-        auto scope = DECLARE_THROW_SCOPE(vm);
-        throwException(m_exec, scope, createStackOverflowError(m_exec));
-    }
-
     void fail()
     {
         m_failed = true;
@@ -731,7 +734,7 @@ private:
         write(static_cast<uint32_t>(arrayBufferView->byteLength()));
         RefPtr<ArrayBuffer> arrayBuffer = arrayBufferView->possiblySharedBuffer();
         if (!arrayBuffer) {
-            code = ValidationError;
+            code = SerializationReturnCode::ValidationError;
             return true;
         }
         JSValue bufferObj = toJS(m_exec, jsCast<JSDOMGlobalObject*>(m_exec->lexicalGlobalObject()), arrayBuffer.get());
@@ -841,12 +844,12 @@ private:
                     return true;
                 }
                 // MessagePort object could not be found in transferred message ports
-                code = ValidationError;
+                code = SerializationReturnCode::ValidationError;
                 return true;
             }
             if (ArrayBuffer* arrayBuffer = toPossiblySharedArrayBuffer(obj)) {
                 if (arrayBuffer->isNeutered()) {
-                    code = ValidationError;
+                    code = SerializationReturnCode::ValidationError;
                     return true;
                 }
                 ObjectPool::iterator index = m_transferredArrayBuffers.find(obj);
@@ -1234,7 +1237,7 @@ SerializationReturnCode CloneSerializer::serialize(JSValue in)
             case ArrayStartState: {
                 ASSERT(isArray(inValue));
                 if (inputObjectStack.size() > maximumFilterRecursion)
-                    return StackOverflowError;
+                    return SerializationReturnCode::StackOverflowError;
 
                 JSArray* inArray = asArray(inValue);
                 unsigned length = inArray->length();
@@ -1273,9 +1276,9 @@ SerializationReturnCode CloneSerializer::serialize(JSValue in)
                 }
 
                 write(index);
-                SerializationReturnCode terminalCode = SuccessfullyCompleted;
+                auto terminalCode = SerializationReturnCode::SuccessfullyCompleted;
                 if (dumpIfTerminal(inValue, terminalCode)) {
-                    if (terminalCode != SuccessfullyCompleted)
+                    if (terminalCode != SerializationReturnCode::SuccessfullyCompleted)
                         return terminalCode;
                     indexStack.last()++;
                     goto arrayStartVisitMember;
@@ -1291,7 +1294,7 @@ SerializationReturnCode CloneSerializer::serialize(JSValue in)
             case ObjectStartState: {
                 ASSERT(inValue.isObject());
                 if (inputObjectStack.size() > maximumFilterRecursion)
-                    return StackOverflowError;
+                    return SerializationReturnCode::StackOverflowError;
                 JSObject* inObject = asObject(inValue);
                 if (!startObject(inObject))
                     break;
@@ -1300,7 +1303,7 @@ SerializationReturnCode CloneSerializer::serialize(JSValue in)
                 // the input is not an Object object then we should throw
                 // a DataCloneError.
                 if (inObject->classInfo() != JSFinalObject::info())
-                    return DataCloneError;
+                    return SerializationReturnCode::DataCloneError;
                 inputObjectStack.append(inObject);
                 indexStack.append(0);
                 propertyStack.append(PropertyNameArray(m_exec, PropertyNameMode::Strings));
@@ -1321,7 +1324,7 @@ SerializationReturnCode CloneSerializer::serialize(JSValue in)
                 }
                 inValue = getProperty(object, properties[index]);
                 if (shouldTerminate())
-                    return ExistingExceptionError;
+                    return SerializationReturnCode::ExistingExceptionError;
 
                 if (!inValue) {
                     // Property was removed during serialisation
@@ -1331,20 +1334,20 @@ SerializationReturnCode CloneSerializer::serialize(JSValue in)
                 write(properties[index]);
 
                 if (shouldTerminate())
-                    return ExistingExceptionError;
+                    return SerializationReturnCode::ExistingExceptionError;
 
-                SerializationReturnCode terminalCode = SuccessfullyCompleted;
+                auto terminalCode = SerializationReturnCode::SuccessfullyCompleted;
                 if (!dumpIfTerminal(inValue, terminalCode)) {
                     stateStack.append(ObjectEndVisitMember);
                     goto stateUnknown;
                 }
-                if (terminalCode != SuccessfullyCompleted)
+                if (terminalCode != SerializationReturnCode::SuccessfullyCompleted)
                     return terminalCode;
                 FALLTHROUGH;
             }
             case ObjectEndVisitMember: {
                 if (shouldTerminate())
-                    return ExistingExceptionError;
+                    return SerializationReturnCode::ExistingExceptionError;
 
                 indexStack.last()++;
                 goto objectStartVisitMember;
@@ -1352,7 +1355,7 @@ SerializationReturnCode CloneSerializer::serialize(JSValue in)
             mapStartState: {
                 ASSERT(inValue.isObject());
                 if (inputObjectStack.size() > maximumFilterRecursion)
-                    return StackOverflowError;
+                    return SerializationReturnCode::StackOverflowError;
                 JSMap* inMap = jsCast<JSMap*>(inValue);
                 if (!startMap(inMap))
                     break;
@@ -1396,7 +1399,7 @@ SerializationReturnCode CloneSerializer::serialize(JSValue in)
             setStartState: {
                 ASSERT(inValue.isObject());
                 if (inputObjectStack.size() > maximumFilterRecursion)
-                    return StackOverflowError;
+                    return SerializationReturnCode::StackOverflowError;
                 JSSet* inSet = jsCast<JSSet*>(inValue);
                 if (!startSet(inSet))
                     break;
@@ -1431,9 +1434,9 @@ SerializationReturnCode CloneSerializer::serialize(JSValue in)
 
             stateUnknown:
             case StateUnknown: {
-                SerializationReturnCode terminalCode = SuccessfullyCompleted;
+                auto terminalCode = SerializationReturnCode::SuccessfullyCompleted;
                 if (dumpIfTerminal(inValue, terminalCode)) {
-                    if (terminalCode != SuccessfullyCompleted)
+                    if (terminalCode != SerializationReturnCode::SuccessfullyCompleted)
                         return terminalCode;
                     break;
                 }
@@ -1454,13 +1457,11 @@ SerializationReturnCode CloneSerializer::serialize(JSValue in)
         stateStack.removeLast();
     }
     if (m_failed)
-        return UnspecifiedError;
+        return SerializationReturnCode::UnspecifiedError;
 
-    return SuccessfullyCompleted;
+    return SerializationReturnCode::SuccessfullyCompleted;
 }
 
-typedef Vector<JSC::ArrayBufferContents> ArrayBufferContentsArray;
-
 class CloneDeserializer : CloneBase {
 public:
     static String deserializeString(const Vector<uint8_t>& buffer)
@@ -1489,10 +1490,10 @@ public:
     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);
+            return std::make_pair(jsNull(), SerializationReturnCode::UnspecifiedError);
         CloneDeserializer deserializer(exec, globalObject, messagePorts, arrayBufferContentsArray, buffer, blobURLs, blobFilePaths);
         if (!deserializer.isValid())
-            return std::make_pair(JSValue(), ValidationError);
+            return std::make_pair(JSValue(), SerializationReturnCode::ValidationError);
         return deserializer.deserialize();
     }
 
@@ -1569,13 +1570,6 @@ private:
 
     DeserializationResult deserialize();
 
-    void throwValidationError()
-    {
-        VM& vm = m_exec->vm();
-        auto scope = DECLARE_THROW_SCOPE(vm);
-        throwTypeError(m_exec, scope, ASCIILiteral("Unable to deserialize data."));
-    }
-
     bool isValid() const { return m_version <= CurrentVersion; }
 
     template <typename T> bool readLittleEndian(T& value)
@@ -2528,7 +2522,7 @@ DeserializationResult CloneDeserializer::deserialize()
         objectStartState:
         case ObjectStartState: {
             if (outputObjectStack.size() > maximumFilterRecursion)
-                return std::make_pair(JSValue(), StackOverflowError);
+                return std::make_pair(JSValue(), SerializationReturnCode::StackOverflowError);
             JSObject* outObject = constructEmptyObject(m_exec, m_globalObject->objectPrototype());
             m_gcBuffer.append(outObject);
             outputObjectStack.append(outObject);
@@ -2563,7 +2557,7 @@ DeserializationResult CloneDeserializer::deserialize()
         }
         mapObjectStartState: {
             if (outputObjectStack.size() > maximumFilterRecursion)
-                return std::make_pair(JSValue(), StackOverflowError);
+                return std::make_pair(JSValue(), SerializationReturnCode::StackOverflowError);
             JSMap* map = JSMap::create(m_exec, m_exec->vm(), m_globalObject->mapStructure());
             if (UNLIKELY(scope.exception()))
                 goto error;
@@ -2594,7 +2588,7 @@ DeserializationResult CloneDeserializer::deserialize()
 
         setObjectStartState: {
             if (outputObjectStack.size() > maximumFilterRecursion)
-                return std::make_pair(JSValue(), StackOverflowError);
+                return std::make_pair(JSValue(), SerializationReturnCode::StackOverflowError);
             JSSet* set = JSSet::create(m_exec, m_exec->vm(), m_globalObject->setStructure());
             if (UNLIKELY(scope.exception()))
                 goto error;
@@ -2643,10 +2637,10 @@ DeserializationResult CloneDeserializer::deserialize()
     }
     ASSERT(outValue);
     ASSERT(!m_failed);
-    return std::make_pair(outValue, SuccessfullyCompleted);
+    return std::make_pair(outValue, SerializationReturnCode::SuccessfullyCompleted);
 error:
     fail();
-    return std::make_pair(JSValue(), ValidationError);
+    return std::make_pair(JSValue(), SerializationReturnCode::ValidationError);
 }
 
 SerializedScriptValue::~SerializedScriptValue()
@@ -2669,19 +2663,12 @@ SerializedScriptValue::SerializedScriptValue(Vector<uint8_t>&& buffer, const Vec
         m_blobURLs.append(url.isolatedCopy());
 }
 
-std::unique_ptr<SerializedScriptValue::ArrayBufferContentsArray> SerializedScriptValue::transferArrayBuffers(
-    ExecState* exec, Vector<RefPtr<JSC::ArrayBuffer>>& arrayBuffers, SerializationReturnCode& code)
+static ExceptionOr<std::unique_ptr<ArrayBufferContentsArray>> transferArrayBuffers(const Vector<RefPtr<JSC::ArrayBuffer>>& arrayBuffers)
 {
-    for (size_t i = 0; i < arrayBuffers.size(); i++) {
-        if (arrayBuffers[i]->isNeutered()) {
-            code = ValidationError;
-            return nullptr;
-        }
-    }
+    if (arrayBuffers.isEmpty())
+        return nullptr;
 
     auto contents = std::make_unique<ArrayBufferContentsArray>(arrayBuffers.size());
-    Vector<Ref<DOMWrapperWorld>> worlds;
-    static_cast<JSVMClientData*>(exec->vm().clientData)->getAllWorlds(worlds);
 
     HashSet<JSC::ArrayBuffer*> visited;
     for (size_t arrayBufferIndex = 0; arrayBufferIndex < arrayBuffers.size(); arrayBufferIndex++) {
@@ -2690,37 +2677,111 @@ std::unique_ptr<SerializedScriptValue::ArrayBufferContentsArray> SerializedScrip
         visited.add(arrayBuffers[arrayBufferIndex].get());
 
         bool result = arrayBuffers[arrayBufferIndex]->transferTo(contents->at(arrayBufferIndex));
-        if (!result) {
-            code = ValidationError;
-            return nullptr;
-        }
+        if (!result)
+            return Exception { TypeError };
     }
-    return contents;
+
+    return WTFMove(contents);
 }
 
-RefPtr<SerializedScriptValue> SerializedScriptValue::create(ExecState& exec, JSValue value, SerializationErrorMode throwExceptions)
+static void maybeThrowExceptionIfSerializationFailed(ExecState* exec, SerializationReturnCode code)
 {
-    Vector<RefPtr<MessagePort>> messagePorts;
-    return SerializedScriptValue::create(exec, value, messagePorts, { }, throwExceptions);
+    auto& vm = exec->vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    if (code == SerializationReturnCode::SuccessfullyCompleted)
+        return;
+    
+    switch (code) {
+    case SerializationReturnCode::StackOverflowError:
+        throwException(exec, scope, createStackOverflowError(exec));
+        break;
+    case SerializationReturnCode::ValidationError:
+        throwTypeError(exec, scope, ASCIILiteral("Unable to deserialize data."));
+        break;
+    case SerializationReturnCode::DataCloneError:
+        setDOMException(exec, DATA_CLONE_ERR);
+        break;
+    case SerializationReturnCode::ExistingExceptionError:
+    case SerializationReturnCode::UnspecifiedError:
+        break;
+        break;
+    case SerializationReturnCode::SuccessfullyCompleted:
+    case SerializationReturnCode::InterruptedExecutionError:
+        ASSERT_NOT_REACHED();
+    }
+}
+
+static Exception exceptionForSerializationFailure(SerializationReturnCode code)
+{
+    ASSERT(code != SerializationReturnCode::SuccessfullyCompleted);
+    
+    switch (code) {
+    case SerializationReturnCode::StackOverflowError:
+        return Exception { StackOverflowError };
+    case SerializationReturnCode::ValidationError:
+        return Exception { TypeError };
+    case SerializationReturnCode::DataCloneError:
+        return Exception { DATA_CLONE_ERR };
+    case SerializationReturnCode::ExistingExceptionError:
+        return Exception { ExistingExceptionError };
+    case SerializationReturnCode::UnspecifiedError:
+        return Exception { TypeError };
+    case SerializationReturnCode::SuccessfullyCompleted:
+    case SerializationReturnCode::InterruptedExecutionError:
+        ASSERT_NOT_REACHED();
+        return Exception { TypeError };
+    }
 }
 
-RefPtr<SerializedScriptValue> SerializedScriptValue::create(ExecState& exec, JSValue value, Vector<RefPtr<MessagePort>>& messagePorts, Vector<RefPtr<JSC::ArrayBuffer>>&& arrayBuffers, SerializationErrorMode throwExceptions)
+RefPtr<SerializedScriptValue> SerializedScriptValue::create(ExecState& exec, JSValue value, SerializationErrorMode throwExceptions)
 {
     Vector<uint8_t> buffer;
     Vector<String> blobURLs;
-    SerializationReturnCode code = CloneSerializer::serialize(&exec, value, messagePorts, arrayBuffers, blobURLs, buffer);
-
-    std::unique_ptr<ArrayBufferContentsArray> arrayBufferContentsArray;
-    if (!arrayBuffers.isEmpty() && serializationDidCompleteSuccessfully(code))
-        arrayBufferContentsArray = transferArrayBuffers(&exec, arrayBuffers, code);
+    Vector<RefPtr<MessagePort>> dummyMessagePorts;
+    Vector<RefPtr<JSC::ArrayBuffer>> dummyArrayBuffers;
+    auto code = CloneSerializer::serialize(&exec, value, dummyMessagePorts, dummyArrayBuffers, blobURLs, buffer);
 
     if (throwExceptions == Throwing)
         maybeThrowExceptionIfSerializationFailed(&exec, code);
 
-    if (!serializationDidCompleteSuccessfully(code))
+    if (code != SerializationReturnCode::SuccessfullyCompleted)
         return nullptr;
 
-    return adoptRef(*new SerializedScriptValue(WTFMove(buffer), blobURLs, WTFMove(arrayBufferContentsArray)));
+    return adoptRef(*new SerializedScriptValue(WTFMove(buffer), blobURLs, nullptr));
+}
+
+ExceptionOr<Ref<SerializedScriptValue>> SerializedScriptValue::create(ExecState& state, JSValue value, Vector<JSC::Strong<JSC::JSObject>>&& transferList, Vector<RefPtr<MessagePort>>& messagePorts)
+{
+    Vector<RefPtr<JSC::ArrayBuffer>> arrayBuffers;
+    for (auto& transferable : transferList) {
+        if (auto arrayBuffer = toPossiblySharedArrayBuffer(transferable.get())) {
+            if (arrayBuffer->isNeutered())
+                return Exception { DATA_CLONE_ERR };
+            arrayBuffers.append(WTFMove(arrayBuffer));
+            continue;
+        }
+        if (auto port = JSMessagePort::toWrapped(transferable.get())) {
+            // FIXME: This should check if the port is detached as per https://html.spec.whatwg.org/multipage/infrastructure.html#istransferable.
+            messagePorts.append(WTFMove(port));
+            continue;
+        }
+
+        return Exception { DATA_CLONE_ERR };
+    }
+
+    Vector<uint8_t> buffer;
+    Vector<String> blobURLs;
+    auto code = CloneSerializer::serialize(&state, value, messagePorts, arrayBuffers, blobURLs, buffer);
+
+    if (code != SerializationReturnCode::SuccessfullyCompleted)
+        return exceptionForSerializationFailure(code);
+
+    auto arrayBufferContentsArray = transferArrayBuffers(arrayBuffers);
+    if (arrayBufferContentsArray.hasException())
+        return arrayBufferContentsArray.releaseException();
+
+    return adoptRef(*new SerializedScriptValue(WTFMove(buffer), blobURLs, arrayBufferContentsArray.releaseReturnValue()));
 }
 
 RefPtr<SerializedScriptValue> SerializedScriptValue::create(StringView string)
@@ -2799,38 +2860,6 @@ Ref<SerializedScriptValue> SerializedScriptValue::nullValue()
     return adoptRef(*new SerializedScriptValue(Vector<uint8_t>()));
 }
 
-void SerializedScriptValue::maybeThrowExceptionIfSerializationFailed(ExecState* exec, SerializationReturnCode code)
-{
-    VM& vm = exec->vm();
-    auto scope = DECLARE_THROW_SCOPE(vm);
-
-    if (code == SuccessfullyCompleted)
-        return;
-    
-    switch (code) {
-    case StackOverflowError:
-        throwException(exec, scope, createStackOverflowError(exec));
-        break;
-    case ValidationError:
-        throwTypeError(exec, scope, ASCIILiteral("Unable to deserialize data."));
-        break;
-    case DataCloneError:
-        setDOMException(exec, DATA_CLONE_ERR);
-        break;
-    case ExistingExceptionError:
-        break;
-    case UnspecifiedError:
-        break;
-    default:
-        ASSERT_NOT_REACHED();
-    }
-}
-
-bool SerializedScriptValue::serializationDidCompleteSuccessfully(SerializationReturnCode code)
-{
-    return (code == SuccessfullyCompleted);
-}
-
 uint32_t SerializedScriptValue::wireFormatVersion()
 {
     return CurrentVersion;
index cefa729..24e506c 100644 (file)
@@ -26,6 +26,7 @@
 
 #pragma once
 
+#include "ExceptionOr.h"
 #include <bindings/ScriptValue.h>
 #include <heap/Strong.h>
 #include <runtime/ArrayBuffer.h>
@@ -42,25 +43,18 @@ namespace WebCore {
 
 class IDBValue;
 class MessagePort;
-enum SerializationReturnCode {
-    SuccessfullyCompleted,
-    StackOverflowError,
-    InterruptedExecutionError,
-    ValidationError,
-    ExistingExceptionError,
-    DataCloneError,
-    UnspecifiedError
-};
-    
+class SharedBuffer;
+enum class SerializationReturnCode;
+
 enum SerializationErrorMode { NonThrowing, Throwing };
 
-class SharedBuffer;
+using ArrayBufferContentsArray = Vector<JSC::ArrayBufferContents>;
 
 class SerializedScriptValue : public ThreadSafeRefCounted<SerializedScriptValue> {
 public:
     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 ExceptionOr<Ref<SerializedScriptValue>> create(JSC::ExecState&, JSC::JSValue, Vector<JSC::Strong<JSC::JSObject>>&&, Vector<RefPtr<MessagePort>>&);
 
     WEBCORE_EXPORT static RefPtr<SerializedScriptValue> create(StringView);
     static Ref<SerializedScriptValue> adopt(Vector<uint8_t>&& buffer)
@@ -100,17 +94,11 @@ public:
     WEBCORE_EXPORT ~SerializedScriptValue();
 
 private:
-    typedef Vector<JSC::ArrayBufferContents> ArrayBufferContentsArray;
-    static void maybeThrowExceptionIfSerializationFailed(JSC::ExecState*, SerializationReturnCode);
-    static bool serializationDidCompleteSuccessfully(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>&&);
 
     Vector<unsigned char> m_data;
     std::unique_ptr<ArrayBufferContentsArray> m_arrayBufferContentsArray;
-
     Vector<String> m_blobURLs;
 };
 
index 607febc..b2908a6 100644 (file)
@@ -597,6 +597,7 @@ sub IsRefPtrType
     return 0 if $object->IsStringType($type);
     return 0 if $type->isUnion;
     return 0 if $type->name eq "any";
+    return 0 if $type->name eq "object";
 
     return 1;
 }
@@ -862,6 +863,7 @@ sub IsBuiltinType
     return 1 if $object->IsTypedArrayType($type);
     return 1 if $type->isUnion;
     return 1 if $type->name eq "any";
+    return 1 if $type->name eq "object";
     return 1 if $type->name eq "BufferSource";
     return 1 if $type->name eq "Promise";
     return 1 if $type->name eq "XPathNSResolver";    
index 1b22446..6b6c973 100644 (file)
@@ -279,6 +279,7 @@ sub AddToIncludesForIDLType
     return if $codeGenerator->IsStringType($type);
     return if $codeGenerator->IsTypedArrayType($type);
     return if $type->name eq "any";
+    return if $type->name eq "object";
 
     if ($type->isUnion) {
         AddToIncludes("<wtf/Variant.h>", $includesRef, $conditional);
@@ -4970,6 +4971,7 @@ my %nativeType = (
     "SerializedScriptValue" => "RefPtr<SerializedScriptValue>",
     "XPathNSResolver" => "RefPtr<XPathNSResolver>",
     "any" => "JSC::JSValue",
+    "object" => "JSC::Strong<JSC::JSObject>",
     "boolean" => "bool",
     "byte" => "int8_t",
     "double" => "double",
@@ -5058,6 +5060,7 @@ sub GetBaseIDLType
         "DOMString" => "IDLDOMString",
         "ByteString" => "IDLByteString",
         "USVString" => "IDLUSVString",
+        "object" => "IDLObject",
         
         # Non-WebIDL extensions
         "Date" => "IDLDate",
index 10fdf5f..cc6354b 100644 (file)
@@ -1015,6 +1015,7 @@ JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionMethodWithOptionalSe
 JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionMethodWithOptionalBoolean(JSC::ExecState*);
 JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionMethodWithOptionalBooleanIsFalse(JSC::ExecState*);
 JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionMethodWithOptionalAny(JSC::ExecState*);
+JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionMethodWithOptionalObject(JSC::ExecState*);
 JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionMethodWithOptionalNullableWrapper(JSC::ExecState*);
 JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionMethodWithOptionalNullableWrapperIsNull(JSC::ExecState*);
 JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionMethodWithOptionalXPathNSResolver(JSC::ExecState*);
@@ -1240,6 +1241,8 @@ JSC::EncodedJSValue jsTestObjCachedAttribute1(JSC::ExecState*, JSC::EncodedJSVal
 JSC::EncodedJSValue jsTestObjCachedAttribute2(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
 JSC::EncodedJSValue jsTestObjAnyAttribute(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
 bool setJSTestObjAnyAttribute(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
+JSC::EncodedJSValue jsTestObjObjectAttribute(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
+bool setJSTestObjObjectAttribute(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
 JSC::EncodedJSValue jsTestObjContentDocument(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
 JSC::EncodedJSValue jsTestObjMutablePoint(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
 bool setJSTestObjMutablePoint(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
@@ -1540,6 +1543,7 @@ static const HashTableValue JSTestObjPrototypeTableValues[] =
     { "cachedAttribute1", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestObjCachedAttribute1), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
     { "cachedAttribute2", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestObjCachedAttribute2), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
     { "anyAttribute", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestObjAnyAttribute), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSTestObjAnyAttribute) } },
+    { "objectAttribute", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestObjObjectAttribute), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSTestObjObjectAttribute) } },
     { "contentDocument", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestObjContentDocument), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
     { "mutablePoint", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestObjMutablePoint), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSTestObjMutablePoint) } },
     { "immutablePoint", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestObjImmutablePoint), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSTestObjImmutablePoint) } },
@@ -1652,6 +1656,7 @@ static const HashTableValue JSTestObjPrototypeTableValues[] =
     { "methodWithOptionalBoolean", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsTestObjPrototypeFunctionMethodWithOptionalBoolean), (intptr_t) (0) } },
     { "methodWithOptionalBooleanIsFalse", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsTestObjPrototypeFunctionMethodWithOptionalBooleanIsFalse), (intptr_t) (0) } },
     { "methodWithOptionalAny", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsTestObjPrototypeFunctionMethodWithOptionalAny), (intptr_t) (0) } },
+    { "methodWithOptionalObject", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsTestObjPrototypeFunctionMethodWithOptionalObject), (intptr_t) (0) } },
     { "methodWithOptionalNullableWrapper", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsTestObjPrototypeFunctionMethodWithOptionalNullableWrapper), (intptr_t) (0) } },
     { "methodWithOptionalNullableWrapperIsNull", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsTestObjPrototypeFunctionMethodWithOptionalNullableWrapperIsNull), (intptr_t) (0) } },
     { "methodWithOptionalXPathNSResolver", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsTestObjPrototypeFunctionMethodWithOptionalXPathNSResolver), (intptr_t) (0) } },
@@ -3025,6 +3030,22 @@ static inline JSValue jsTestObjAnyAttributeGetter(ExecState& state, JSTestObj& t
     return result;
 }
 
+static inline JSValue jsTestObjObjectAttributeGetter(ExecState&, JSTestObj&, ThrowScope& throwScope);
+
+EncodedJSValue jsTestObjObjectAttribute(ExecState* state, EncodedJSValue thisValue, PropertyName)
+{
+    return BindingCaller<JSTestObj>::attribute<jsTestObjObjectAttributeGetter>(state, thisValue, "objectAttribute");
+}
+
+static inline JSValue jsTestObjObjectAttributeGetter(ExecState& state, JSTestObj& thisObject, ThrowScope& throwScope)
+{
+    UNUSED_PARAM(throwScope);
+    UNUSED_PARAM(state);
+    auto& impl = thisObject.wrapped();
+    JSValue result = toJS<IDLObject>(impl.objectAttribute());
+    return result;
+}
+
 static inline JSValue jsTestObjContentDocumentGetter(ExecState&, JSTestObj&, ThrowScope& throwScope);
 
 EncodedJSValue jsTestObjContentDocument(ExecState* state, EncodedJSValue thisValue, PropertyName)
@@ -4623,6 +4644,25 @@ static inline bool setJSTestObjAnyAttributeFunction(ExecState& state, JSTestObj&
 }
 
 
+static inline bool setJSTestObjObjectAttributeFunction(ExecState&, JSTestObj&, JSValue, ThrowScope&);
+
+bool setJSTestObjObjectAttribute(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
+{
+    return BindingCaller<JSTestObj>::setAttribute<setJSTestObjObjectAttributeFunction>(state, thisValue, encodedValue, "objectAttribute");
+}
+
+static inline bool setJSTestObjObjectAttributeFunction(ExecState& state, JSTestObj& thisObject, JSValue value, ThrowScope& throwScope)
+{
+    UNUSED_PARAM(state);
+    UNUSED_PARAM(throwScope);
+    auto& impl = thisObject.wrapped();
+    auto nativeValue = convert<IDLObject>(state, value);
+    RETURN_IF_EXCEPTION(throwScope, false);
+    impl.setObjectAttribute(WTFMove(nativeValue));
+    return true;
+}
+
+
 static inline bool setJSTestObjMutablePointFunction(ExecState&, JSTestObj&, JSValue, ThrowScope&);
 
 bool setJSTestObjMutablePoint(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
@@ -6433,6 +6473,24 @@ static inline JSC::EncodedJSValue jsTestObjPrototypeFunctionMethodWithOptionalAn
     return JSValue::encode(jsUndefined());
 }
 
+static inline JSC::EncodedJSValue jsTestObjPrototypeFunctionMethodWithOptionalObjectCaller(JSC::ExecState*, JSTestObj*, JSC::ThrowScope&);
+
+EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionMethodWithOptionalObject(ExecState* state)
+{
+    return BindingCaller<JSTestObj>::callOperation<jsTestObjPrototypeFunctionMethodWithOptionalObjectCaller>(state, "methodWithOptionalObject");
+}
+
+static inline JSC::EncodedJSValue jsTestObjPrototypeFunctionMethodWithOptionalObjectCaller(JSC::ExecState* state, JSTestObj* castedThis, JSC::ThrowScope& throwScope)
+{
+    UNUSED_PARAM(state);
+    UNUSED_PARAM(throwScope);
+    auto& impl = castedThis->wrapped();
+    auto a = state->argument(0).isUndefined() ? std::optional<JSC::Strong<JSC::JSObject>>() : convert<IDLObject>(*state, state->uncheckedArgument(0));
+    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+    impl.methodWithOptionalObject(WTFMove(a));
+    return JSValue::encode(jsUndefined());
+}
+
 static inline JSC::EncodedJSValue jsTestObjPrototypeFunctionMethodWithOptionalNullableWrapperCaller(JSC::ExecState*, JSTestObj*, JSC::ThrowScope&);
 
 EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionMethodWithOptionalNullableWrapper(ExecState* state)
index 940b947..1de4fe6 100644 (file)
@@ -233,6 +233,7 @@ enum TestConfidence { "high", "kinda-low" };
     void    methodWithOptionalBoolean(optional boolean b);
     void    methodWithOptionalBooleanIsFalse(optional boolean b = false);
     void    methodWithOptionalAny(optional any a);
+    void    methodWithOptionalObject(optional object a);
     void    methodWithOptionalNullableWrapper(optional TestObj? obj);
     void    methodWithOptionalNullableWrapperIsNull(optional TestObj? obj = null);
     void    methodWithOptionalXPathNSResolver(optional XPathNSResolver? resolver);
@@ -272,6 +273,7 @@ enum TestConfidence { "high", "kinda-low" };
     [CachedAttribute] readonly attribute any cachedAttribute2;
     
     attribute any anyAttribute;
+    attribute object objectAttribute;
 
     // Overloads
     void    overloadedMethod(TestObj? objArg, DOMString strArg);
index 5354c86..496a736 100644 (file)
@@ -72,6 +72,12 @@ enum {
     OperationError,
     NotAllowedError,
 
+    // Non-standard errors
+    StackOverflowError,
+
+    // Used to indicate to the bindings that a JS exception was thrown below and it should be propogated.
+    ExistingExceptionError,
+
     // WebIDL exception types, handled by the binding layer.
     // FIXME: Add GeneralError, EvalError, etc. when implemented in the bindings.
     TypeError = 105,
index 82810d1..b03711f 100644 (file)
@@ -51,8 +51,13 @@ MessagePort::~MessagePort()
         m_scriptExecutionContext->destroyedMessagePort(*this);
 }
 
-ExceptionOr<void> MessagePort::postMessage(RefPtr<SerializedScriptValue>&& message, Vector<RefPtr<MessagePort>>&& ports)
+ExceptionOr<void> MessagePort::postMessage(JSC::ExecState& state, JSC::JSValue messageValue, Vector<JSC::Strong<JSC::JSObject>>&& transfer)
 {
+    Vector<RefPtr<MessagePort>> ports;
+    auto message = SerializedScriptValue::create(state, messageValue, WTFMove(transfer), ports);
+    if (message.hasException())
+        return message.releaseException();
+
     if (!isEntangled())
         return { };
     ASSERT(m_scriptExecutionContext);
@@ -69,7 +74,7 @@ ExceptionOr<void> MessagePort::postMessage(RefPtr<SerializedScriptValue>&& messa
             return disentangleResult.releaseException();
         channels = disentangleResult.releaseReturnValue();
     }
-    m_entangledChannel->postMessageToRemote(WTFMove(message), WTFMove(channels));
+    m_entangledChannel->postMessageToRemote(message.releaseReturnValue(), WTFMove(channels));
     return { };
 }
 
index 086d95b..1bf676d 100644 (file)
 #include "ExceptionOr.h"
 #include "MessagePortChannel.h"
 
+namespace JSC {
+class ExecState;
+class JSObject;
+class JSValue;
+}
+
 namespace WebCore {
 
 class Frame;
@@ -39,7 +45,7 @@ public:
     static Ref<MessagePort> create(ScriptExecutionContext& scriptExecutionContext) { return adoptRef(*new MessagePort(scriptExecutionContext)); }
     virtual ~MessagePort();
 
-    ExceptionOr<void> postMessage(RefPtr<SerializedScriptValue>&& message, Vector<RefPtr<MessagePort>>&&);
+    ExceptionOr<void> postMessage(JSC::ExecState&, JSC::JSValue message, Vector<JSC::Strong<JSC::JSObject>>&&);
 
     void start();
     void close();
index 9a6589a..468ff5d 100644 (file)
@@ -31,8 +31,7 @@
     GenerateIsReachable=Impl,
     JSCustomMarkFunction,
 ] interface MessagePort : EventTarget {
-    [Custom, MayThrowException] void postMessage(any message, optional Array messagePorts);
-
+    [CallWith=ScriptState, MayThrowException] void postMessage(any message, optional sequence<object> transfer = []);
     void start();
     void close();
 
index e4570e1..a9c03c4 100644 (file)
 #include <wtf/MathExtras.h>
 #include <wtf/NeverDestroyed.h>
 #include <wtf/Ref.h>
+#include <wtf/Variant.h>
 #include <wtf/text/WTFString.h>
 
 #if ENABLE(USER_MESSAGE_HANDLERS)
@@ -919,12 +920,12 @@ ExceptionOr<Storage*> DOMWindow::localStorage() const
     return m_localStorage.get();
 }
 
-ExceptionOr<void> DOMWindow::postMessage(Ref<SerializedScriptValue>&& message, Vector<RefPtr<MessagePort>>&& ports, const String& targetOrigin, DOMWindow& source)
+ExceptionOr<void> DOMWindow::postMessage(JSC::ExecState& state, DOMWindow& callerWindow, JSC::JSValue messageValue, const String& targetOrigin, Vector<JSC::Strong<JSC::JSObject>>&& transfer)
 {
     if (!isCurrentlyDisplayedInFrame())
         return { };
 
-    Document* sourceDocument = source.document();
+    Document* sourceDocument = callerWindow.document();
 
     // Compute the target origin.  We need to do this synchronously in order
     // to generate the SYNTAX_ERR exception correctly.
@@ -941,6 +942,11 @@ ExceptionOr<void> DOMWindow::postMessage(Ref<SerializedScriptValue>&& message, V
             return Exception { SYNTAX_ERR };
     }
 
+    Vector<RefPtr<MessagePort>> ports;
+    auto message = SerializedScriptValue::create(state, messageValue, WTFMove(transfer), ports);
+    if (message.hasException())
+        return message.releaseException();
+
     auto channels = MessagePort::disentanglePorts(WTFMove(ports));
     if (channels.hasException())
         return channels.releaseException();
@@ -957,7 +963,7 @@ ExceptionOr<void> DOMWindow::postMessage(Ref<SerializedScriptValue>&& message, V
         stackTrace = createScriptCallStack(JSMainThreadExecState::currentState(), ScriptCallStack::maxCallStackSizeToCapture);
 
     // Schedule the message.
-    auto* timer = new PostMessageTimer(*this, WTFMove(message), sourceOrigin, source, channels.releaseReturnValue(), WTFMove(target), WTFMove(stackTrace));
+    auto* timer = new PostMessageTimer(*this, message.releaseReturnValue(), sourceOrigin, callerWindow, channels.releaseReturnValue(), WTFMove(target), WTFMove(stackTrace));
     timer->startOneShot(0);
 
     return { };
index 595b3ce..0a66516 100644 (file)
@@ -36,6 +36,7 @@
 #include "URL.h"
 #include <functional>
 #include <memory>
+#include <wtf/Forward.h>
 #include <wtf/HashSet.h>
 #include <wtf/Optional.h>
 #include <wtf/WeakPtr.h>
@@ -44,6 +45,13 @@ namespace Inspector {
 class ScriptCallStack;
 }
 
+namespace JSC {
+class ExecState;
+class JSObject;
+class JSValue;
+template<typename T> class Strong;
+}
+
 namespace WebCore {
 
 class BarProp;
@@ -235,7 +243,7 @@ public:
     void printErrorMessage(const String&);
     String crossDomainAccessErrorMessage(const DOMWindow& activeWindow);
 
-    ExceptionOr<void> postMessage(Ref<SerializedScriptValue>&& message, Vector<RefPtr<MessagePort>>&&, const String& targetOrigin, DOMWindow& source);
+    ExceptionOr<void> postMessage(JSC::ExecState&, DOMWindow& callerWindow, JSC::JSValue message, const String& targetOrigin, Vector<JSC::Strong<JSC::JSObject>>&&);
     void postMessageTimerFired(PostMessageTimer&);
     void dispatchMessageEventWithOriginCheck(SecurityOrigin* intendedTargetOrigin, Event&, PassRefPtr<Inspector::ScriptCallStack>);
 
index d4b59c4..2d21b33 100644 (file)
     // 0 when straight up; -90 when rotated 90 degrees clockwise; 90 counter clockwise.
     [Conditional=ORIENTATION_EVENTS] readonly attribute long orientation;
 
-    [DoNotCheckSecurity, Custom, MayThrowException, ForwardDeclareInHeader] void postMessage(SerializedScriptValue message, USVString targetOrigin, optional Array messagePorts);
+    [CallWith=ScriptState&CallerWindow, DoNotCheckSecurity, ForwardDeclareInHeader, MayThrowException] void postMessage(any message, USVString targetOrigin, optional sequence<object> transfer = []);
 
     [Conditional=WEB_TIMING, Replaceable] readonly attribute Performance performance;
 
index 56c34a9..5e1c7ca 100644 (file)
@@ -63,13 +63,18 @@ EventTargetInterface DedicatedWorkerGlobalScope::eventTargetInterface() const
     return DedicatedWorkerGlobalScopeEventTargetInterfaceType;
 }
 
-ExceptionOr<void> DedicatedWorkerGlobalScope::postMessage(RefPtr<SerializedScriptValue>&& message, Vector<RefPtr<MessagePort>>&& ports)
+ExceptionOr<void> DedicatedWorkerGlobalScope::postMessage(JSC::ExecState& state, JSC::JSValue messageValue, Vector<JSC::Strong<JSC::JSObject>>&& transfer)
 {
+    Vector<RefPtr<MessagePort>> ports;
+    auto message = SerializedScriptValue::create(state, messageValue, WTFMove(transfer), ports);
+    if (message.hasException())
+        return message.releaseException();
+
     // Disentangle the port in preparation for sending it to the remote context.
     auto channels = MessagePort::disentanglePorts(WTFMove(ports));
     if (channels.hasException())
         return channels.releaseException();
-    thread().workerObjectProxy().postMessageToWorkerObject(WTFMove(message), channels.releaseReturnValue());
+    thread().workerObjectProxy().postMessageToWorkerObject(message.releaseReturnValue(), channels.releaseReturnValue());
     return { };
 }
 
index ce54b70..13f75f1 100644 (file)
 
 #include "WorkerGlobalScope.h"
 
+namespace JSC {
+class ExecState;
+class JSObject;
+class JSValue;
+}
+
 namespace WebCore {
 
 class ContentSecurityPolicyResponseHeaders;
@@ -45,7 +51,7 @@ public:
     static Ref<DedicatedWorkerGlobalScope> create(const URL&, const String& identifier, const String& userAgent, DedicatedWorkerThread&, const ContentSecurityPolicyResponseHeaders&, bool shouldBypassMainWorldContentSecurityPolicy, RefPtr<SecurityOrigin>&& topOrigin, IDBClient::IDBConnectionProxy*, SocketProvider*);
     virtual ~DedicatedWorkerGlobalScope();
 
-    ExceptionOr<void> postMessage(RefPtr<SerializedScriptValue>&&, Vector<RefPtr<MessagePort>>&&);
+    ExceptionOr<void> postMessage(JSC::ExecState&, JSC::JSValue message, Vector<JSC::Strong<JSC::JSObject>>&&);
 
     DedicatedWorkerThread& thread();
 
index 13a9a86..a080e68 100644 (file)
@@ -34,7 +34,7 @@
     Global=(Worker,DedicatedWorker),
     JSGenerateToNativeObject,
 ] interface DedicatedWorkerGlobalScope : WorkerGlobalScope {
-    [Custom, MayThrowException] void postMessage(any message, optional Array messagePorts);
+    [CallWith=ScriptState, MayThrowException] void postMessage(any message, optional sequence<object> transfer = []);
 
     attribute EventHandler onmessage;
 };
index 18528ae..514ec4d 100644 (file)
@@ -101,13 +101,18 @@ Worker::~Worker()
     m_contextProxy->workerObjectDestroyed();
 }
 
-ExceptionOr<void> Worker::postMessage(RefPtr<SerializedScriptValue>&& message, Vector<RefPtr<MessagePort>>&& ports)
+ExceptionOr<void> Worker::postMessage(JSC::ExecState& state, JSC::JSValue messageValue, Vector<JSC::Strong<JSC::JSObject>>&& transfer)
 {
+    Vector<RefPtr<MessagePort>> ports;
+    auto message = SerializedScriptValue::create(state, messageValue, WTFMove(transfer), ports);
+    if (message.hasException())
+        return message.releaseException();
+
     // Disentangle the port in preparation for sending it to the remote context.
     auto channels = MessagePort::disentanglePorts(WTFMove(ports));
     if (channels.hasException())
         return channels.releaseException();
-    m_contextProxy->postMessageToWorkerGlobalScope(WTFMove(message), channels.releaseReturnValue());
+    m_contextProxy->postMessageToWorkerGlobalScope(message.releaseReturnValue(), channels.releaseReturnValue());
     return { };
 }
 
index 19d8d56..52637a4 100644 (file)
 #include <wtf/Optional.h>
 #include <wtf/text/AtomicStringHash.h>
 
+namespace JSC {
+class ExecState;
+class JSObject;
+class JSValue;
+}
+
 namespace WebCore {
 
 class ScriptExecutionContext;
@@ -46,7 +52,7 @@ public:
     static ExceptionOr<Ref<Worker>> create(ScriptExecutionContext&, const String& url, JSC::RuntimeFlags);
     virtual ~Worker();
 
-    ExceptionOr<void> postMessage(RefPtr<SerializedScriptValue>&& message, Vector<RefPtr<MessagePort>>&&);
+    ExceptionOr<void> postMessage(JSC::ExecState&, JSC::JSValue message, Vector<JSC::Strong<JSC::JSObject>>&&);
 
     void terminate();
 
index 6fc6893..16481a3 100644 (file)
     ActiveDOMObject,
     CustomConstructor(USVString scriptUrl),
 ] interface Worker : EventTarget {
-    attribute EventHandler onmessage;
-
-    [Custom, MayThrowException] void postMessage(SerializedScriptValue message, optional Array messagePorts);
-
     void terminate();
+
+    [CallWith=ScriptState, MayThrowException] void postMessage(any message, optional sequence<object> transfer = []);
+    attribute EventHandler onmessage;
 };
 
 Worker implements AbstractWorker;