<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[212035] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/212035">212035</a></dd>
<dt>Author</dt> <dd>fpizlo@apple.com</dd>
<dt>Date</dt> <dd>2017-02-09 18:42:20 -0800 (Thu, 09 Feb 2017)</dd>
</dl>

<h3>Log Message</h3>
<pre>SharedArrayBuffer does not need to be in the transfer list
https://bugs.webkit.org/show_bug.cgi?id=168079

Reviewed by Geoffrey Garen and Keith Miller.
Source/JavaScriptCore:

        
Exposes a simple shareWith() API for when you know you want to share the contents of
a shared buffer. Also a useful explicit operator bool.

* runtime/ArrayBuffer.cpp:
(JSC::ArrayBuffer::shareWith):
* runtime/ArrayBuffer.h:
(JSC::ArrayBufferContents::operator bool):

Source/WebCore:


Tests: workers/sab/multi-memory-multi-buffer.html
       workers/sab/multi-memory.html
       workers/sab/no-transfer.html
       workers/sab/postMessage-clones.html
       workers/sab/sent-from-worker-no-transfer.html
       workers/sab/sent-from-worker-transfer.html

The SAB API that we originally implemented required that SABs get put in transfer lists
when they are sent to workers.
        
The new SAB API that everyone is converging towards requires that you do not put the
SAB in the transfer list. That's supposed to be an error. Instead, anytime that a SAB
is part of any message to or from a dedicated worker then it is automatically shared.
        
The new API provides a lot more clarity about what is supposed to happen in contexts
that support transfering but don't support sharing.
        
Right now this patch allows both styles to work, but I hope we can disable the transfer
list capability soon.

* bindings/js/IDBBindingUtilities.cpp:
(WebCore::deserializeIDBValueToJSValue):
* bindings/js/JSMessageEventCustom.cpp:
(WebCore::JSMessageEvent::data):
* bindings/js/SerializedScriptValue.cpp:
(WebCore::CloneSerializer::serialize):
(WebCore::CloneSerializer::CloneSerializer):
(WebCore::CloneSerializer::dumpIfTerminal):
(WebCore::CloneDeserializer::deserialize):
(WebCore::CloneDeserializer::CloneDeserializer):
(WebCore::CloneDeserializer::readTerminal):
(WebCore::SerializedScriptValue::SerializedScriptValue):
(WebCore::SerializedScriptValue::create):
(WebCore::SerializedScriptValue::deserialize):
* bindings/js/SerializedScriptValue.h:
(): Deleted.
* dom/CustomEvent.cpp:
(WebCore::CustomEvent::trySerializeDetail):
* dom/ErrorEvent.cpp:
(WebCore::ErrorEvent::trySerializeError):
* dom/MessageEvent.cpp:
(WebCore::MessageEvent::trySerializeData):
* dom/PopStateEvent.cpp:
(WebCore::PopStateEvent::trySerializeState):
* workers/DedicatedWorkerGlobalScope.cpp:
(WebCore::DedicatedWorkerGlobalScope::postMessage):
* workers/Worker.cpp:
(WebCore::Worker::postMessage):

LayoutTests:

        
This adds tests that ensure that SABs behave correctly (are either cloned or shared)
depending on context, and that we currently share SABs whether they are in the transfer
list or not. This also adds tests for SABs being passed around via more complicated
data structures.

* workers/sab/multi-memory-expected.txt: Added.
* workers/sab/multi-memory-multi-buffer-expected.txt: Added.
* workers/sab/multi-memory-multi-buffer.html: Added.
* workers/sab/multi-memory-worker-1.js: Added.
(onmessage):
* workers/sab/multi-memory-worker-2.js: Added.
(onmessage):
* workers/sab/multi-memory.html: Added.
* workers/sab/no-transfer-expected.txt: Added.
* workers/sab/no-transfer.html: Added.
* workers/sab/postMessage-clones-expected.txt: Added.
* workers/sab/postMessage-clones.html: Added.
* workers/sab/sab-creator-no-transfer.js: Added.
* workers/sab/sab-creator-transfer.js: Added.
* workers/sab/sent-from-worker-no-transfer-expected.txt: Added.
* workers/sab/sent-from-worker-no-transfer.html: Added.
* workers/sab/sent-from-worker-transfer-expected.txt: Added.
* workers/sab/sent-from-worker-transfer.html: Added.
* workers/sab/worker-resources.js:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsworkerssabworkerresourcesjs">trunk/LayoutTests/workers/sab/worker-resources.js</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeArrayBuffercpp">trunk/Source/JavaScriptCore/runtime/ArrayBuffer.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeArrayBufferh">trunk/Source/JavaScriptCore/runtime/ArrayBuffer.h</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorebindingsjsIDBBindingUtilitiescpp">trunk/Source/WebCore/bindings/js/IDBBindingUtilities.cpp</a></li>
<li><a href="#trunkSourceWebCorebindingsjsJSMessageEventCustomcpp">trunk/Source/WebCore/bindings/js/JSMessageEventCustom.cpp</a></li>
<li><a href="#trunkSourceWebCorebindingsjsSerializedScriptValuecpp">trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp</a></li>
<li><a href="#trunkSourceWebCorebindingsjsSerializedScriptValueh">trunk/Source/WebCore/bindings/js/SerializedScriptValue.h</a></li>
<li><a href="#trunkSourceWebCoredomCustomEventcpp">trunk/Source/WebCore/dom/CustomEvent.cpp</a></li>
<li><a href="#trunkSourceWebCoredomErrorEventcpp">trunk/Source/WebCore/dom/ErrorEvent.cpp</a></li>
<li><a href="#trunkSourceWebCoredomMessageEventcpp">trunk/Source/WebCore/dom/MessageEvent.cpp</a></li>
<li><a href="#trunkSourceWebCoredomPopStateEventcpp">trunk/Source/WebCore/dom/PopStateEvent.cpp</a></li>
<li><a href="#trunkSourceWebCoreworkersDedicatedWorkerGlobalScopecpp">trunk/Source/WebCore/workers/DedicatedWorkerGlobalScope.cpp</a></li>
<li><a href="#trunkSourceWebCoreworkersWorkercpp">trunk/Source/WebCore/workers/Worker.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsworkerssabmultimemoryexpectedtxt">trunk/LayoutTests/workers/sab/multi-memory-expected.txt</a></li>
<li><a href="#trunkLayoutTestsworkerssabmultimemorymultibufferexpectedtxt">trunk/LayoutTests/workers/sab/multi-memory-multi-buffer-expected.txt</a></li>
<li><a href="#trunkLayoutTestsworkerssabmultimemorymultibufferhtml">trunk/LayoutTests/workers/sab/multi-memory-multi-buffer.html</a></li>
<li><a href="#trunkLayoutTestsworkerssabmultimemoryworker1js">trunk/LayoutTests/workers/sab/multi-memory-worker-1.js</a></li>
<li><a href="#trunkLayoutTestsworkerssabmultimemoryworker2js">trunk/LayoutTests/workers/sab/multi-memory-worker-2.js</a></li>
<li><a href="#trunkLayoutTestsworkerssabmultimemoryhtml">trunk/LayoutTests/workers/sab/multi-memory.html</a></li>
<li><a href="#trunkLayoutTestsworkerssabnotransferexpectedtxt">trunk/LayoutTests/workers/sab/no-transfer-expected.txt</a></li>
<li><a href="#trunkLayoutTestsworkerssabnotransferhtml">trunk/LayoutTests/workers/sab/no-transfer.html</a></li>
<li><a href="#trunkLayoutTestsworkerssabpostMessageclonesexpectedtxt">trunk/LayoutTests/workers/sab/postMessage-clones-expected.txt</a></li>
<li><a href="#trunkLayoutTestsworkerssabpostMessagecloneshtml">trunk/LayoutTests/workers/sab/postMessage-clones.html</a></li>
<li><a href="#trunkLayoutTestsworkerssabsabcreatornotransferjs">trunk/LayoutTests/workers/sab/sab-creator-no-transfer.js</a></li>
<li><a href="#trunkLayoutTestsworkerssabsabcreatortransferjs">trunk/LayoutTests/workers/sab/sab-creator-transfer.js</a></li>
<li><a href="#trunkLayoutTestsworkerssabsentfromworkernotransferexpectedtxt">trunk/LayoutTests/workers/sab/sent-from-worker-no-transfer-expected.txt</a></li>
<li><a href="#trunkLayoutTestsworkerssabsentfromworkernotransferhtml">trunk/LayoutTests/workers/sab/sent-from-worker-no-transfer.html</a></li>
<li><a href="#trunkLayoutTestsworkerssabsentfromworkertransferexpectedtxt">trunk/LayoutTests/workers/sab/sent-from-worker-transfer-expected.txt</a></li>
<li><a href="#trunkLayoutTestsworkerssabsentfromworkertransferhtml">trunk/LayoutTests/workers/sab/sent-from-worker-transfer.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (212034 => 212035)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2017-02-10 02:35:51 UTC (rev 212034)
+++ trunk/LayoutTests/ChangeLog        2017-02-10 02:42:20 UTC (rev 212035)
</span><span class="lines">@@ -1,3 +1,35 @@
</span><ins>+2017-02-09  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        SharedArrayBuffer does not need to be in the transfer list
+        https://bugs.webkit.org/show_bug.cgi?id=168079
+
+        Reviewed by Geoffrey Garen and Keith Miller.
+        
+        This adds tests that ensure that SABs behave correctly (are either cloned or shared)
+        depending on context, and that we currently share SABs whether they are in the transfer
+        list or not. This also adds tests for SABs being passed around via more complicated
+        data structures.
+
+        * workers/sab/multi-memory-expected.txt: Added.
+        * workers/sab/multi-memory-multi-buffer-expected.txt: Added.
+        * workers/sab/multi-memory-multi-buffer.html: Added.
+        * workers/sab/multi-memory-worker-1.js: Added.
+        (onmessage):
+        * workers/sab/multi-memory-worker-2.js: Added.
+        (onmessage):
+        * workers/sab/multi-memory.html: Added.
+        * workers/sab/no-transfer-expected.txt: Added.
+        * workers/sab/no-transfer.html: Added.
+        * workers/sab/postMessage-clones-expected.txt: Added.
+        * workers/sab/postMessage-clones.html: Added.
+        * workers/sab/sab-creator-no-transfer.js: Added.
+        * workers/sab/sab-creator-transfer.js: Added.
+        * workers/sab/sent-from-worker-no-transfer-expected.txt: Added.
+        * workers/sab/sent-from-worker-no-transfer.html: Added.
+        * workers/sab/sent-from-worker-transfer-expected.txt: Added.
+        * workers/sab/sent-from-worker-transfer.html: Added.
+        * workers/sab/worker-resources.js:
+
</ins><span class="cx"> 2017-02-09  Chris Dumez  &lt;cdumez@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Make sure Event keeps its current target element alive
</span></span></pre></div>
<a id="trunkLayoutTestsworkerssabmultimemoryexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/workers/sab/multi-memory-expected.txt (0 => 212035)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/workers/sab/multi-memory-expected.txt                                (rev 0)
+++ trunk/LayoutTests/workers/sab/multi-memory-expected.txt        2017-02-10 02:42:20 UTC (rev 212035)
</span><span class="lines">@@ -0,0 +1,3 @@
</span><ins>+All workers done!
+Test passed!
+
</ins></span></pre></div>
<a id="trunkLayoutTestsworkerssabmultimemorymultibufferexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/workers/sab/multi-memory-multi-buffer-expected.txt (0 => 212035)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/workers/sab/multi-memory-multi-buffer-expected.txt                                (rev 0)
+++ trunk/LayoutTests/workers/sab/multi-memory-multi-buffer-expected.txt        2017-02-10 02:42:20 UTC (rev 212035)
</span><span class="lines">@@ -0,0 +1,3 @@
</span><ins>+All workers done!
+Test passed!
+
</ins></span></pre></div>
<a id="trunkLayoutTestsworkerssabmultimemorymultibufferhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/workers/sab/multi-memory-multi-buffer.html (0 => 212035)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/workers/sab/multi-memory-multi-buffer.html                                (rev 0)
+++ trunk/LayoutTests/workers/sab/multi-memory-multi-buffer.html        2017-02-10 02:42:20 UTC (rev 212035)
</span><span class="lines">@@ -0,0 +1,88 @@
</span><ins>+&lt;!DOCTYPE HTML PUBLIC &quot;-//IETF//DTD HTML//EN&quot;&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;script&gt;
+function getOrCreate(id, tagName)
+{
+    var element = document.getElementById(id);
+    if (element)
+        return element;
+    
+    element = document.createElement(tagName);
+    element.id = id;
+    var parent = document.body || document.documentElement;
+    var refNode = parent.firstChild;
+    
+    parent.insertBefore(element, refNode);
+    return element;
+}
+
+function debug(msg)
+{
+    var span = document.createElement(&quot;span&quot;);
+    getOrCreate(&quot;console&quot;, &quot;div&quot;).appendChild(span); // insert it first so XHTML knows the namespace
+    span.innerHTML = msg + '&lt;br /&gt;';
+}
+
+if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.waitUntilDone();
+}
+
+var verbose = false;
+
+var didStart = new Int32Array(new SharedArrayBuffer(4), 0, 1);
+var shouldGo = new Int32Array(new SharedArrayBuffer(4), 0, 1);
+var didEnd = new Int32Array(new SharedArrayBuffer(4), 0, 1);
+
+var numWorkers = 0;
+function startWorker(file)
+{
+    if (verbose)
+        debug(&quot;Starting worker: &quot; + file);
+    numWorkers++;
+    var worker = new Worker(file);
+    worker.onmessage = function(event) {
+        if (event.data == &quot;done&quot;) {
+            if (verbose)
+                debug(&quot;Finished worker: &quot; + file);
+            if (--numWorkers)
+                return;
+            debug(&quot;All workers done!&quot;);
+            done();
+            return;
+        }
+        if (event.data.indexOf(&quot;Error&quot;) == 0) {
+            debug(&quot;Test failed: &quot;+ event.data);
+            if (window.testRunner)
+                testRunner.notifyDone();
+        }
+        
+        if (verbose)
+            debug(&quot;Event from &quot; + file + &quot;: &quot; + event.data);
+    };
+    worker.postMessage({didStart: didStart, shouldGo: shouldGo, didEnd: didEnd, shouldShareBuffer: false});
+}
+
+function done()
+{
+    if (didStart[0] != 1)
+        throw &quot;Error: Bad value at didStart[0]: &quot; + didStart[0];
+    if (shouldGo[0] != 1)
+        throw &quot;Error: Bad value at shouldGo[0]: &quot; + shouldGo[0];
+    if (didEnd[0] != 1)
+        throw &quot;Error: Bad value at didEnd[0]: &quot; + didEnd[0];
+    debug(&quot;Test passed!&quot;);
+
+    if (window.testRunner)
+        testRunner.notifyDone();
+}
+
+startWorker(&quot;multi-memory-worker-1.js&quot;);
+startWorker(&quot;multi-memory-worker-2.js&quot;);
+
+&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsworkerssabmultimemoryworker1js"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/workers/sab/multi-memory-worker-1.js (0 => 212035)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/workers/sab/multi-memory-worker-1.js                                (rev 0)
+++ trunk/LayoutTests/workers/sab/multi-memory-worker-1.js        2017-02-10 02:42:20 UTC (rev 212035)
</span><span class="lines">@@ -0,0 +1,29 @@
</span><ins>+importScripts(&quot;worker-resources.js&quot;);
+
+onmessage = function (event) {
+    var didStart = event.data.didStart;
+    var shouldGo = event.data.shouldGo;
+    var didEnd = event.data.didEnd;
+
+    checkBufferSharing(event.data.shouldShareBuffer, didStart, shouldGo, didEnd);
+    
+    postMessage(&quot;Started!&quot;);
+    postMessage(&quot;didStart: &quot; + didStart);
+    postMessage(&quot;shouldGo: &quot; + shouldGo);
+    postMessage(&quot;didEnd: &quot; + didEnd);
+    
+    wait(didStart, 0, 0, 1);
+    
+    postMessage(&quot;It started!&quot;);
+    
+    shouldGo[0] = 1;
+    wake(shouldGo, 0);
+    
+    wait(didEnd, 0, 0, 1);
+    
+    postMessage(&quot;All done!&quot;);
+    postMessage(&quot;didStart: &quot; + didStart);
+    postMessage(&quot;shouldGo: &quot; + shouldGo);
+    postMessage(&quot;didEnd: &quot; + didEnd);
+    postMessage(&quot;done&quot;);
+}
</ins></span></pre></div>
<a id="trunkLayoutTestsworkerssabmultimemoryworker2js"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/workers/sab/multi-memory-worker-2.js (0 => 212035)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/workers/sab/multi-memory-worker-2.js                                (rev 0)
+++ trunk/LayoutTests/workers/sab/multi-memory-worker-2.js        2017-02-10 02:42:20 UTC (rev 212035)
</span><span class="lines">@@ -0,0 +1,27 @@
</span><ins>+importScripts(&quot;worker-resources.js&quot;);
+
+onmessage = function(event) {
+    var didStart = event.data.didStart;
+    var shouldGo = event.data.shouldGo;
+    var didEnd = event.data.didEnd;
+
+    checkBufferSharing(event.data.shouldShareBuffer, didStart, shouldGo, didEnd);
+    
+    postMessage(&quot;Started!&quot;);
+    postMessage(&quot;didStart: &quot; + didStart);
+    postMessage(&quot;shouldGo: &quot; + shouldGo);
+    postMessage(&quot;didEnd: &quot; + didEnd);
+    
+    Atomics.store(didStart, 0, 1);
+    wake(didStart, 0);
+
+    wait(shouldGo, 0, 0, 1);
+    
+    Atomics.store(didEnd, 0, 1);
+    wake(didEnd, 0, 1);
+
+    postMessage(&quot;didStart: &quot; + didStart);
+    postMessage(&quot;shouldGo: &quot; + shouldGo);
+    postMessage(&quot;didEnd: &quot; + didEnd);
+    postMessage(&quot;done&quot;);
+}
</ins></span></pre></div>
<a id="trunkLayoutTestsworkerssabmultimemoryhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/workers/sab/multi-memory.html (0 => 212035)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/workers/sab/multi-memory.html                                (rev 0)
+++ trunk/LayoutTests/workers/sab/multi-memory.html        2017-02-10 02:42:20 UTC (rev 212035)
</span><span class="lines">@@ -0,0 +1,90 @@
</span><ins>+&lt;!DOCTYPE HTML PUBLIC &quot;-//IETF//DTD HTML//EN&quot;&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;script&gt;
+function getOrCreate(id, tagName)
+{
+    var element = document.getElementById(id);
+    if (element)
+        return element;
+    
+    element = document.createElement(tagName);
+    element.id = id;
+    var parent = document.body || document.documentElement;
+    var refNode = parent.firstChild;
+    
+    parent.insertBefore(element, refNode);
+    return element;
+}
+
+function debug(msg)
+{
+    var span = document.createElement(&quot;span&quot;);
+    getOrCreate(&quot;console&quot;, &quot;div&quot;).appendChild(span); // insert it first so XHTML knows the namespace
+    span.innerHTML = msg + '&lt;br /&gt;';
+}
+
+if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.waitUntilDone();
+}
+
+var verbose = false;
+
+var sab = new SharedArrayBuffer(3 * 4);
+
+var didStart = new Int32Array(sab, 0, 1);
+var shouldGo = new Int32Array(sab, 4, 1);
+var didEnd = new Int32Array(sab, 8, 1);
+
+var numWorkers = 0;
+function startWorker(file)
+{
+    if (verbose)
+        debug(&quot;Starting worker: &quot; + file);
+    numWorkers++;
+    var worker = new Worker(file);
+    worker.onmessage = function(event) {
+        if (event.data == &quot;done&quot;) {
+            if (verbose)
+                debug(&quot;Finished worker: &quot; + file);
+            if (--numWorkers)
+                return;
+            debug(&quot;All workers done!&quot;);
+            done();
+            return;
+        }
+        if (event.data.indexOf(&quot;Error&quot;) == 0) {
+            debug(&quot;Test failed: &quot;+ event.data);
+            if (window.testRunner)
+                testRunner.notifyDone();
+        }
+        
+        if (verbose)
+            debug(&quot;Event from &quot; + file + &quot;: &quot; + event.data);
+    };
+    worker.postMessage({didStart: didStart, shouldGo: shouldGo, didEnd: didEnd, shouldShareBuffer: true});
+}
+
+function done()
+{
+    if (didStart[0] != 1)
+        throw &quot;Error: Bad value at didStart[0]: &quot; + didStart[0];
+    if (shouldGo[0] != 1)
+        throw &quot;Error: Bad value at shouldGo[0]: &quot; + shouldGo[0];
+    if (didEnd[0] != 1)
+        throw &quot;Error: Bad value at didEnd[0]: &quot; + didEnd[0];
+    debug(&quot;Test passed!&quot;);
+
+    if (window.testRunner)
+        testRunner.notifyDone();
+}
+
+startWorker(&quot;multi-memory-worker-1.js&quot;);
+startWorker(&quot;multi-memory-worker-2.js&quot;);
+
+&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsworkerssabnotransferexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/workers/sab/no-transfer-expected.txt (0 => 212035)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/workers/sab/no-transfer-expected.txt                                (rev 0)
+++ trunk/LayoutTests/workers/sab/no-transfer-expected.txt        2017-02-10 02:42:20 UTC (rev 212035)
</span><span class="lines">@@ -0,0 +1,3 @@
</span><ins>+All workers done!
+Test passed!
+
</ins></span></pre></div>
<a id="trunkLayoutTestsworkerssabnotransferhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/workers/sab/no-transfer.html (0 => 212035)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/workers/sab/no-transfer.html                                (rev 0)
+++ trunk/LayoutTests/workers/sab/no-transfer.html        2017-02-10 02:42:20 UTC (rev 212035)
</span><span class="lines">@@ -0,0 +1,90 @@
</span><ins>+&lt;!DOCTYPE HTML PUBLIC &quot;-//IETF//DTD HTML//EN&quot;&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;script&gt;
+function getOrCreate(id, tagName)
+{
+    var element = document.getElementById(id);
+    if (element)
+        return element;
+    
+    element = document.createElement(tagName);
+    element.id = id;
+    var parent = document.body || document.documentElement;
+    var refNode = parent.firstChild;
+    
+    parent.insertBefore(element, refNode);
+    return element;
+}
+
+function debug(msg)
+{
+    var span = document.createElement(&quot;span&quot;);
+    getOrCreate(&quot;console&quot;, &quot;div&quot;).appendChild(span); // insert it first so XHTML knows the namespace
+    span.innerHTML = msg + '&lt;br /&gt;';
+}
+
+if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.waitUntilDone();
+}
+
+var verbose = false;
+
+var sab = new SharedArrayBuffer(100 * 4);
+
+var memory = new Int32Array(sab);
+
+var numWorkers = 0;
+function startWorker(file)
+{
+    if (verbose)
+        debug(&quot;Starting worker: &quot; + file);
+    numWorkers++;
+    var worker = new Worker(file);
+    worker.onmessage = function(event) {
+        if (event.data == &quot;done&quot;) {
+            if (verbose)
+                debug(&quot;Finished worker: &quot; + file);
+            if (--numWorkers)
+                return;
+            debug(&quot;All workers done!&quot;);
+            done();
+            return;
+        }
+        if (event.data.indexOf(&quot;Error&quot;) == 0) {
+            debug(&quot;Test failed: &quot;+ event.data);
+            if (window.testRunner)
+                testRunner.notifyDone();
+        }
+        
+        if (verbose)
+            debug(&quot;Event from &quot; + file + &quot;: &quot; + event.data);
+    };
+    worker.postMessage(memory);
+}
+
+function done()
+{
+    for (var i = 0; i &lt; 3; ++i) {
+        if (memory[i] != 1)
+            throw &quot;Error: Bad value at memory[&quot; + i + &quot;]: &quot; + memory[i];
+    }
+    for (var i = 3; i &lt; memory.length; ++i) {
+        if (memory[i] != 0)
+            throw &quot;Error: Bad value at memory[&quot; + i + &quot;]: &quot; + memory[i];
+    }
+    debug(&quot;Test passed!&quot;);
+
+    if (window.testRunner)
+        testRunner.notifyDone();
+}
+
+startWorker(&quot;simple-worker-1.js&quot;);
+startWorker(&quot;simple-worker-2.js&quot;);
+
+&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsworkerssabpostMessageclonesexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/workers/sab/postMessage-clones-expected.txt (0 => 212035)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/workers/sab/postMessage-clones-expected.txt                                (rev 0)
+++ trunk/LayoutTests/workers/sab/postMessage-clones-expected.txt        2017-02-10 02:42:20 UTC (rev 212035)
</span><span class="lines">@@ -0,0 +1,13 @@
</span><ins>+Checks that window.postMessage clones SharedArrayBuffers
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+PASS memory[0] is 42
+PASS otherMemory[0] is 0
+PASS memory[0] is 42
+PASS otherMemory[0] is 43
+
</ins></span></pre></div>
<a id="trunkLayoutTestsworkerssabpostMessagecloneshtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/workers/sab/postMessage-clones.html (0 => 212035)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/workers/sab/postMessage-clones.html                                (rev 0)
+++ trunk/LayoutTests/workers/sab/postMessage-clones.html        2017-02-10 02:42:20 UTC (rev 212035)
</span><span class="lines">@@ -0,0 +1,33 @@
</span><ins>+&lt;!DOCTYPE HTML PUBLIC &quot;-//IETF//DTD HTML//EN&quot;&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;script&gt;
+description(&quot;Checks that window.postMessage clones SharedArrayBuffers&quot;);
+
+if (window.testRunner)
+    testRunner.waitUntilDone();
+
+var sab = new SharedArrayBuffer(4);
+var memory = new Int32Array(sab);
+var otherMemory;
+
+window.addEventListener(&quot;message&quot;, function (event) {
+    otherMemory = event.data;
+    memory[0] = 42;
+    shouldBe(&quot;memory[0]&quot;, &quot;42&quot;);
+    shouldBe(&quot;otherMemory[0]&quot;, &quot;0&quot;);
+    otherMemory[0] = 43;
+    shouldBe(&quot;memory[0]&quot;, &quot;42&quot;);
+    shouldBe(&quot;otherMemory[0]&quot;, &quot;43&quot;);
+    if (window.testRunner)
+        testRunner.notifyDone();
+});
+
+postMessage(memory, &quot;*&quot;);
+&lt;/script&gt;
+&lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsworkerssabsabcreatornotransferjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/workers/sab/sab-creator-no-transfer.js (0 => 212035)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/workers/sab/sab-creator-no-transfer.js                                (rev 0)
+++ trunk/LayoutTests/workers/sab/sab-creator-no-transfer.js        2017-02-10 02:42:20 UTC (rev 212035)
</span><span class="lines">@@ -0,0 +1,4 @@
</span><ins>+var sab = new SharedArrayBuffer(100 * 4);
+var memory = new Int32Array(sab);
+postMessage(memory);
+
</ins></span></pre></div>
<a id="trunkLayoutTestsworkerssabsabcreatortransferjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/workers/sab/sab-creator-transfer.js (0 => 212035)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/workers/sab/sab-creator-transfer.js                                (rev 0)
+++ trunk/LayoutTests/workers/sab/sab-creator-transfer.js        2017-02-10 02:42:20 UTC (rev 212035)
</span><span class="lines">@@ -0,0 +1,4 @@
</span><ins>+var sab = new SharedArrayBuffer(100 * 4);
+var memory = new Int32Array(sab);
+postMessage(memory, [sab]);
+
</ins></span></pre></div>
<a id="trunkLayoutTestsworkerssabsentfromworkernotransferexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/workers/sab/sent-from-worker-no-transfer-expected.txt (0 => 212035)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/workers/sab/sent-from-worker-no-transfer-expected.txt                                (rev 0)
+++ trunk/LayoutTests/workers/sab/sent-from-worker-no-transfer-expected.txt        2017-02-10 02:42:20 UTC (rev 212035)
</span><span class="lines">@@ -0,0 +1,3 @@
</span><ins>+All workers done!
+Test passed!
+
</ins></span></pre></div>
<a id="trunkLayoutTestsworkerssabsentfromworkernotransferhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/workers/sab/sent-from-worker-no-transfer.html (0 => 212035)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/workers/sab/sent-from-worker-no-transfer.html                                (rev 0)
+++ trunk/LayoutTests/workers/sab/sent-from-worker-no-transfer.html        2017-02-10 02:42:20 UTC (rev 212035)
</span><span class="lines">@@ -0,0 +1,93 @@
</span><ins>+&lt;!DOCTYPE HTML PUBLIC &quot;-//IETF//DTD HTML//EN&quot;&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;script&gt;
+function getOrCreate(id, tagName)
+{
+    var element = document.getElementById(id);
+    if (element)
+        return element;
+    
+    element = document.createElement(tagName);
+    element.id = id;
+    var parent = document.body || document.documentElement;
+    var refNode = parent.firstChild;
+    
+    parent.insertBefore(element, refNode);
+    return element;
+}
+
+function debug(msg)
+{
+    var span = document.createElement(&quot;span&quot;);
+    getOrCreate(&quot;console&quot;, &quot;div&quot;).appendChild(span); // insert it first so XHTML knows the namespace
+    span.innerHTML = msg + '&lt;br /&gt;';
+}
+
+if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.waitUntilDone();
+}
+
+var verbose = false;
+
+var memory;
+
+var numWorkers = 0;
+function startWorker(file)
+{
+    if (verbose)
+        debug(&quot;Starting worker: &quot; + file);
+    numWorkers++;
+    var worker = new Worker(file);
+    worker.onmessage = function(event) {
+        if (event.data == &quot;done&quot;) {
+            if (verbose)
+                debug(&quot;Finished worker: &quot; + file);
+            if (--numWorkers)
+                return;
+            debug(&quot;All workers done!&quot;);
+            done();
+            return;
+        }
+        if (event.data.indexOf(&quot;Error&quot;) == 0) {
+            debug(&quot;Test failed: &quot;+ event.data);
+            if (window.testRunner)
+                testRunner.notifyDone();
+        }
+        
+        if (verbose)
+            debug(&quot;Event from &quot; + file + &quot;: &quot; + event.data);
+    };
+    worker.postMessage(memory);
+}
+
+function done()
+{
+    for (var i = 0; i &lt; 3; ++i) {
+        if (memory[i] != 1)
+            throw &quot;Error: Bad value at memory[&quot; + i + &quot;]: &quot; + memory[i];
+    }
+    for (var i = 3; i &lt; memory.length; ++i) {
+        if (memory[i] != 0)
+            throw &quot;Error: Bad value at memory[&quot; + i + &quot;]: &quot; + memory[i];
+    }
+    debug(&quot;Test passed!&quot;);
+
+    if (window.testRunner)
+        testRunner.notifyDone();
+}
+
+var sabCreator = new Worker(&quot;sab-creator-no-transfer.js&quot;);
+sabCreator.onmessage = function(event) {
+    memory = event.data;
+    
+    startWorker(&quot;simple-worker-1.js&quot;);
+    startWorker(&quot;simple-worker-2.js&quot;);
+};
+
+&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsworkerssabsentfromworkertransferexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/workers/sab/sent-from-worker-transfer-expected.txt (0 => 212035)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/workers/sab/sent-from-worker-transfer-expected.txt                                (rev 0)
+++ trunk/LayoutTests/workers/sab/sent-from-worker-transfer-expected.txt        2017-02-10 02:42:20 UTC (rev 212035)
</span><span class="lines">@@ -0,0 +1,3 @@
</span><ins>+All workers done!
+Test passed!
+
</ins></span></pre></div>
<a id="trunkLayoutTestsworkerssabsentfromworkertransferhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/workers/sab/sent-from-worker-transfer.html (0 => 212035)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/workers/sab/sent-from-worker-transfer.html                                (rev 0)
+++ trunk/LayoutTests/workers/sab/sent-from-worker-transfer.html        2017-02-10 02:42:20 UTC (rev 212035)
</span><span class="lines">@@ -0,0 +1,95 @@
</span><ins>+&lt;!DOCTYPE HTML PUBLIC &quot;-//IETF//DTD HTML//EN&quot;&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;script&gt;
+function getOrCreate(id, tagName)
+{
+    var element = document.getElementById(id);
+    if (element)
+        return element;
+    
+    element = document.createElement(tagName);
+    element.id = id;
+    var parent = document.body || document.documentElement;
+    var refNode = parent.firstChild;
+    
+    parent.insertBefore(element, refNode);
+    return element;
+}
+
+function debug(msg)
+{
+    var span = document.createElement(&quot;span&quot;);
+    getOrCreate(&quot;console&quot;, &quot;div&quot;).appendChild(span); // insert it first so XHTML knows the namespace
+    span.innerHTML = msg + '&lt;br /&gt;';
+}
+
+if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.waitUntilDone();
+}
+
+var verbose = false;
+
+var sab;
+var memory;
+
+var numWorkers = 0;
+function startWorker(file)
+{
+    if (verbose)
+        debug(&quot;Starting worker: &quot; + file);
+    numWorkers++;
+    var worker = new Worker(file);
+    worker.onmessage = function(event) {
+        if (event.data == &quot;done&quot;) {
+            if (verbose)
+                debug(&quot;Finished worker: &quot; + file);
+            if (--numWorkers)
+                return;
+            debug(&quot;All workers done!&quot;);
+            done();
+            return;
+        }
+        if (event.data.indexOf(&quot;Error&quot;) == 0) {
+            debug(&quot;Test failed: &quot;+ event.data);
+            if (window.testRunner)
+                testRunner.notifyDone();
+        }
+        
+        if (verbose)
+            debug(&quot;Event from &quot; + file + &quot;: &quot; + event.data);
+    };
+    worker.postMessage(memory, [sab]);
+}
+
+function done()
+{
+    for (var i = 0; i &lt; 3; ++i) {
+        if (memory[i] != 1)
+            throw &quot;Error: Bad value at memory[&quot; + i + &quot;]: &quot; + memory[i];
+    }
+    for (var i = 3; i &lt; memory.length; ++i) {
+        if (memory[i] != 0)
+            throw &quot;Error: Bad value at memory[&quot; + i + &quot;]: &quot; + memory[i];
+    }
+    debug(&quot;Test passed!&quot;);
+
+    if (window.testRunner)
+        testRunner.notifyDone();
+}
+
+var sabCreator = new Worker(&quot;sab-creator-transfer.js&quot;);
+sabCreator.onmessage = function(event) {
+    memory = event.data;
+    sab = memory.buffer;
+    
+    startWorker(&quot;simple-worker-1.js&quot;);
+    startWorker(&quot;simple-worker-2.js&quot;);
+};
+
+&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsworkerssabworkerresourcesjs"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/workers/sab/worker-resources.js (212034 => 212035)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/workers/sab/worker-resources.js        2017-02-10 02:35:51 UTC (rev 212034)
+++ trunk/LayoutTests/workers/sab/worker-resources.js        2017-02-10 02:42:20 UTC (rev 212035)
</span><span class="lines">@@ -33,3 +33,21 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+function checkBufferSharing(shouldShareBuffer)
+{
+    var set = new Set();
+    for (var i = 1; i &lt; arguments.length; ++i)
+        set.add(arguments[i].buffer);
+    if (shouldShareBuffer) {
+        if (set.size != 1) {
+            postMessage(&quot;Error: buffers should be shared but are not shared (set.size == &quot; + set.size + &quot;)&quot;);
+            postMessage(&quot;error&quot;);
+        }
+    } else {
+        if (set.size != arguments.length - 1) {
+            postMessage(&quot;Error: buffers should not be shared but are shared&quot;);
+            postMessage(&quot;error&quot;);
+        }
+    }
+}
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (212034 => 212035)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2017-02-10 02:35:51 UTC (rev 212034)
+++ trunk/Source/JavaScriptCore/ChangeLog        2017-02-10 02:42:20 UTC (rev 212035)
</span><span class="lines">@@ -1,3 +1,18 @@
</span><ins>+2017-02-09  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        SharedArrayBuffer does not need to be in the transfer list
+        https://bugs.webkit.org/show_bug.cgi?id=168079
+
+        Reviewed by Geoffrey Garen and Keith Miller.
+        
+        Exposes a simple shareWith() API for when you know you want to share the contents of
+        a shared buffer. Also a useful explicit operator bool.
+
+        * runtime/ArrayBuffer.cpp:
+        (JSC::ArrayBuffer::shareWith):
+        * runtime/ArrayBuffer.h:
+        (JSC::ArrayBufferContents::operator bool):
+
</ins><span class="cx"> 2017-02-09  Mark Lam  &lt;mark.lam@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         B3::Procedure::deleteOrphans() should neutralize upsilons with dead phis.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeArrayBuffercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/ArrayBuffer.cpp (212034 => 212035)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/ArrayBuffer.cpp        2017-02-10 02:35:51 UTC (rev 212034)
+++ trunk/Source/JavaScriptCore/runtime/ArrayBuffer.cpp        2017-02-10 02:42:20 UTC (rev 212035)
</span><span class="lines">@@ -284,6 +284,17 @@
</span><span class="cx">     makeShared();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool ArrayBuffer::shareWith(ArrayBufferContents&amp; result)
+{
+    if (!m_contents.m_data || !isShared()) {
+        result.m_data = nullptr;
+        return false;
+    }
+    
+    m_contents.shareWith(result);
+    return true;
+}
+
</ins><span class="cx"> bool ArrayBuffer::transferTo(VM&amp; vm, ArrayBufferContents&amp; result)
</span><span class="cx"> {
</span><span class="cx">     Ref&lt;ArrayBuffer&gt; protect(*this);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeArrayBufferh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/ArrayBuffer.h (212034 => 212035)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/ArrayBuffer.h        2017-02-10 02:35:51 UTC (rev 212034)
+++ trunk/Source/JavaScriptCore/runtime/ArrayBuffer.h        2017-02-10 02:42:20 UTC (rev 212035)
</span><span class="lines">@@ -65,6 +65,8 @@
</span><span class="cx">     
</span><span class="cx">     JS_EXPORT_PRIVATE void clear();
</span><span class="cx">     
</span><ins>+    explicit operator bool() { return !!m_data; }
+    
</ins><span class="cx">     void* data() const { return m_data; }
</span><span class="cx">     unsigned sizeInBytes() const { return m_sizeInBytes; }
</span><span class="cx">     
</span><span class="lines">@@ -131,6 +133,7 @@
</span><span class="cx">     inline void pinAndLock();
</span><span class="cx"> 
</span><span class="cx">     JS_EXPORT_PRIVATE bool transferTo(VM&amp;, ArrayBufferContents&amp;);
</span><ins>+    JS_EXPORT_PRIVATE bool shareWith(ArrayBufferContents&amp;);
</ins><span class="cx">     bool isNeutered() { return !m_contents.m_data; }
</span><span class="cx">     
</span><span class="cx">     static ptrdiff_t offsetOfData() { return OBJECT_OFFSETOF(ArrayBuffer, m_contents) + OBJECT_OFFSETOF(ArrayBufferContents, m_data); }
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (212034 => 212035)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2017-02-10 02:35:51 UTC (rev 212034)
+++ trunk/Source/WebCore/ChangeLog        2017-02-10 02:42:20 UTC (rev 212035)
</span><span class="lines">@@ -1,3 +1,59 @@
</span><ins>+2017-02-09  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        SharedArrayBuffer does not need to be in the transfer list
+        https://bugs.webkit.org/show_bug.cgi?id=168079
+
+        Reviewed by Geoffrey Garen and Keith Miller.
+
+        Tests: workers/sab/multi-memory-multi-buffer.html
+               workers/sab/multi-memory.html
+               workers/sab/no-transfer.html
+               workers/sab/postMessage-clones.html
+               workers/sab/sent-from-worker-no-transfer.html
+               workers/sab/sent-from-worker-transfer.html
+
+        The SAB API that we originally implemented required that SABs get put in transfer lists
+        when they are sent to workers.
+        
+        The new SAB API that everyone is converging towards requires that you do not put the
+        SAB in the transfer list. That's supposed to be an error. Instead, anytime that a SAB
+        is part of any message to or from a dedicated worker then it is automatically shared.
+        
+        The new API provides a lot more clarity about what is supposed to happen in contexts
+        that support transfering but don't support sharing.
+        
+        Right now this patch allows both styles to work, but I hope we can disable the transfer
+        list capability soon.
+
+        * bindings/js/IDBBindingUtilities.cpp:
+        (WebCore::deserializeIDBValueToJSValue):
+        * bindings/js/JSMessageEventCustom.cpp:
+        (WebCore::JSMessageEvent::data):
+        * bindings/js/SerializedScriptValue.cpp:
+        (WebCore::CloneSerializer::serialize):
+        (WebCore::CloneSerializer::CloneSerializer):
+        (WebCore::CloneSerializer::dumpIfTerminal):
+        (WebCore::CloneDeserializer::deserialize):
+        (WebCore::CloneDeserializer::CloneDeserializer):
+        (WebCore::CloneDeserializer::readTerminal):
+        (WebCore::SerializedScriptValue::SerializedScriptValue):
+        (WebCore::SerializedScriptValue::create):
+        (WebCore::SerializedScriptValue::deserialize):
+        * bindings/js/SerializedScriptValue.h:
+        (): Deleted.
+        * dom/CustomEvent.cpp:
+        (WebCore::CustomEvent::trySerializeDetail):
+        * dom/ErrorEvent.cpp:
+        (WebCore::ErrorEvent::trySerializeError):
+        * dom/MessageEvent.cpp:
+        (WebCore::MessageEvent::trySerializeData):
+        * dom/PopStateEvent.cpp:
+        (WebCore::PopStateEvent::trySerializeState):
+        * workers/DedicatedWorkerGlobalScope.cpp:
+        (WebCore::DedicatedWorkerGlobalScope::postMessage):
+        * workers/Worker.cpp:
+        (WebCore::Worker::postMessage):
+
</ins><span class="cx"> 2017-02-09  Brent Fulgham  &lt;bfulgham@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Unreviewed build fix after r212025.
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsIDBBindingUtilitiescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/IDBBindingUtilities.cpp (212034 => 212035)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/IDBBindingUtilities.cpp        2017-02-10 02:35:51 UTC (rev 212034)
+++ trunk/Source/WebCore/bindings/js/IDBBindingUtilities.cpp        2017-02-10 02:42:20 UTC (rev 212035)
</span><span class="lines">@@ -345,7 +345,7 @@
</span><span class="cx"> 
</span><span class="cx">     state.vm().apiLock().lock();
</span><span class="cx">     Vector&lt;RefPtr&lt;MessagePort&gt;&gt; messagePorts;
</span><del>-    JSValue result = serializedValue-&gt;deserialize(state, &amp;globalObject, messagePorts, value.blobURLs(), value.blobFilePaths(), NonThrowing);
</del><ins>+    JSValue result = serializedValue-&gt;deserialize(state, &amp;globalObject, messagePorts, value.blobURLs(), value.blobFilePaths(), SerializationErrorMode::NonThrowing);
</ins><span class="cx">     state.vm().apiLock().unlock();
</span><span class="cx"> 
</span><span class="cx">     return result;
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsJSMessageEventCustomcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/JSMessageEventCustom.cpp (212034 => 212035)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/JSMessageEventCustom.cpp        2017-02-10 02:35:51 UTC (rev 212034)
+++ trunk/Source/WebCore/bindings/js/JSMessageEventCustom.cpp        2017-02-10 02:42:20 UTC (rev 212035)
</span><span class="lines">@@ -80,7 +80,7 @@
</span><span class="cx">         if (RefPtr&lt;SerializedScriptValue&gt; serializedValue = event.dataAsSerializedScriptValue()) {
</span><span class="cx">             Vector&lt;RefPtr&lt;MessagePort&gt;&gt; ports = wrapped().ports();
</span><span class="cx">             // FIXME: Why does this suppress exceptions?
</span><del>-            result = serializedValue-&gt;deserialize(state, globalObject(), ports, NonThrowing);
</del><ins>+            result = serializedValue-&gt;deserialize(state, globalObject(), ports, SerializationErrorMode::NonThrowing);
</ins><span class="cx">         } else
</span><span class="cx">             result = jsNull();
</span><span class="cx">         break;
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsSerializedScriptValuecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp (212034 => 212035)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp        2017-02-10 02:35:51 UTC (rev 212034)
+++ trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp        2017-02-10 02:42:20 UTC (rev 212035)
</span><span class="lines">@@ -144,6 +144,7 @@
</span><span class="cx"> #if ENABLE(SUBTLE_CRYPTO)
</span><span class="cx">     CryptoKeyTag = 33,
</span><span class="cx"> #endif
</span><ins>+    SharedArrayBufferTag = 34,
</ins><span class="cx">     ErrorTag = 255
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="lines">@@ -476,9 +477,9 @@
</span><span class="cx"> 
</span><span class="cx"> class CloneSerializer : CloneBase {
</span><span class="cx"> public:
</span><del>-    static SerializationReturnCode serialize(ExecState* exec, JSValue value, Vector&lt;RefPtr&lt;MessagePort&gt;&gt;&amp; messagePorts, Vector&lt;RefPtr&lt;JSC::ArrayBuffer&gt;&gt;&amp; arrayBuffers, Vector&lt;String&gt;&amp; blobURLs, Vector&lt;uint8_t&gt;&amp; out)
</del><ins>+    static SerializationReturnCode serialize(ExecState* exec, JSValue value, Vector&lt;RefPtr&lt;MessagePort&gt;&gt;&amp; messagePorts, Vector&lt;RefPtr&lt;JSC::ArrayBuffer&gt;&gt;&amp; arrayBuffers, Vector&lt;String&gt;&amp; blobURLs, Vector&lt;uint8_t&gt;&amp; out, SerializationContext context, ArrayBufferContentsArray&amp; sharedBuffers)
</ins><span class="cx">     {
</span><del>-        CloneSerializer serializer(exec, messagePorts, arrayBuffers, blobURLs, out);
</del><ins>+        CloneSerializer serializer(exec, messagePorts, arrayBuffers, blobURLs, out, context, sharedBuffers);
</ins><span class="cx">         return serializer.serialize(value);
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -525,11 +526,13 @@
</span><span class="cx"> private:
</span><span class="cx">     typedef HashMap&lt;JSObject*, uint32_t&gt; ObjectPool;
</span><span class="cx"> 
</span><del>-    CloneSerializer(ExecState* exec, Vector&lt;RefPtr&lt;MessagePort&gt;&gt;&amp; messagePorts, Vector&lt;RefPtr&lt;JSC::ArrayBuffer&gt;&gt;&amp; arrayBuffers, Vector&lt;String&gt;&amp; blobURLs, Vector&lt;uint8_t&gt;&amp; out)
</del><ins>+    CloneSerializer(ExecState* exec, Vector&lt;RefPtr&lt;MessagePort&gt;&gt;&amp; messagePorts, Vector&lt;RefPtr&lt;JSC::ArrayBuffer&gt;&gt;&amp; arrayBuffers, Vector&lt;String&gt;&amp; blobURLs, Vector&lt;uint8_t&gt;&amp; out, SerializationContext context, ArrayBufferContentsArray&amp; sharedBuffers)
</ins><span class="cx">         : CloneBase(exec)
</span><span class="cx">         , m_buffer(out)
</span><span class="cx">         , m_blobURLs(blobURLs)
</span><span class="cx">         , m_emptyIdentifier(Identifier::fromString(exec, emptyString()))
</span><ins>+        , m_context(context)
+        , m_sharedBuffers(sharedBuffers)
</ins><span class="cx">     {
</span><span class="cx">         write(CurrentVersion);
</span><span class="cx">         fillTransferMap(messagePorts, m_transferredMessagePorts);
</span><span class="lines">@@ -861,6 +864,19 @@
</span><span class="cx">                 }
</span><span class="cx">                 if (!startObjectInternal(obj)) // handle duplicates
</span><span class="cx">                     return true;
</span><ins>+                
+                if (arrayBuffer-&gt;isShared()
+                    &amp;&amp; m_context == SerializationContext::WorkerPostMessage) {
+                    uint32_t index = m_sharedBuffers.size();
+                    ArrayBufferContents contents;
+                    if (arrayBuffer-&gt;shareWith(contents)) {
+                        write(SharedArrayBufferTag);
+                        m_sharedBuffers.append(WTFMove(contents));
+                        write(index);
+                        return true;
+                    }
+                }
+                
</ins><span class="cx">                 write(ArrayBufferTag);
</span><span class="cx">                 write(arrayBuffer-&gt;byteLength());
</span><span class="cx">                 write(static_cast&lt;const uint8_t*&gt;(arrayBuffer-&gt;data()), arrayBuffer-&gt;byteLength());
</span><span class="lines">@@ -880,7 +896,8 @@
</span><span class="cx">                 Vector&lt;String&gt; dummyBlobURLs;
</span><span class="cx">                 Vector&lt;RefPtr&lt;MessagePort&gt;&gt; dummyMessagePorts;
</span><span class="cx">                 Vector&lt;RefPtr&lt;JSC::ArrayBuffer&gt;&gt; dummyArrayBuffers;
</span><del>-                CloneSerializer rawKeySerializer(m_exec, dummyMessagePorts, dummyArrayBuffers, dummyBlobURLs, serializedKey);
</del><ins>+                ArrayBufferContentsArray dummySharedBuffers;
+                CloneSerializer rawKeySerializer(m_exec, dummyMessagePorts, dummyArrayBuffers, dummyBlobURLs, serializedKey, SerializationContext::Default, dummySharedBuffers);
</ins><span class="cx">                 rawKeySerializer.write(key);
</span><span class="cx">                 Vector&lt;uint8_t&gt; wrappedKey;
</span><span class="cx">                 if (!wrapCryptoKey(m_exec, serializedKey, wrappedKey))
</span><span class="lines">@@ -1218,6 +1235,8 @@
</span><span class="cx">     typedef HashMap&lt;RefPtr&lt;UniquedStringImpl&gt;, uint32_t, IdentifierRepHash&gt; StringConstantPool;
</span><span class="cx">     StringConstantPool m_constantPool;
</span><span class="cx">     Identifier m_emptyIdentifier;
</span><ins>+    SerializationContext m_context;
+    ArrayBufferContentsArray&amp; m_sharedBuffers;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> SerializationReturnCode CloneSerializer::serialize(JSValue in)
</span><span class="lines">@@ -1489,11 +1508,11 @@
</span><span class="cx">         return str;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    static DeserializationResult deserialize(ExecState* exec, JSGlobalObject* globalObject, Vector&lt;RefPtr&lt;MessagePort&gt;&gt;&amp; messagePorts, ArrayBufferContentsArray* arrayBufferContentsArray, const Vector&lt;uint8_t&gt;&amp; buffer, const Vector&lt;String&gt;&amp; blobURLs, const Vector&lt;String&gt; blobFilePaths)
</del><ins>+    static DeserializationResult deserialize(ExecState* exec, JSGlobalObject* globalObject, Vector&lt;RefPtr&lt;MessagePort&gt;&gt;&amp; messagePorts, ArrayBufferContentsArray* arrayBufferContentsArray, const Vector&lt;uint8_t&gt;&amp; buffer, const Vector&lt;String&gt;&amp; blobURLs, const Vector&lt;String&gt; blobFilePaths, ArrayBufferContentsArray* sharedBuffers)
</ins><span class="cx">     {
</span><span class="cx">         if (!buffer.size())
</span><span class="cx">             return std::make_pair(jsNull(), SerializationReturnCode::UnspecifiedError);
</span><del>-        CloneDeserializer deserializer(exec, globalObject, messagePorts, arrayBufferContentsArray, buffer, blobURLs, blobFilePaths);
</del><ins>+        CloneDeserializer deserializer(exec, globalObject, messagePorts, arrayBufferContentsArray, buffer, blobURLs, blobFilePaths, sharedBuffers);
</ins><span class="cx">         if (!deserializer.isValid())
</span><span class="cx">             return std::make_pair(JSValue(), SerializationReturnCode::ValidationError);
</span><span class="cx">         return deserializer.deserialize();
</span><span class="lines">@@ -1553,7 +1572,7 @@
</span><span class="cx">             m_version = 0xFFFFFFFF;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    CloneDeserializer(ExecState* exec, JSGlobalObject* globalObject, Vector&lt;RefPtr&lt;MessagePort&gt;&gt;&amp; messagePorts, ArrayBufferContentsArray* arrayBufferContents, const Vector&lt;uint8_t&gt;&amp; buffer, const Vector&lt;String&gt;&amp; blobURLs, const Vector&lt;String&gt; blobFilePaths)
</del><ins>+    CloneDeserializer(ExecState* exec, JSGlobalObject* globalObject, Vector&lt;RefPtr&lt;MessagePort&gt;&gt;&amp; messagePorts, ArrayBufferContentsArray* arrayBufferContents, const Vector&lt;uint8_t&gt;&amp; buffer, const Vector&lt;String&gt;&amp; blobURLs, const Vector&lt;String&gt; blobFilePaths, ArrayBufferContentsArray* sharedBuffers)
</ins><span class="cx">         : CloneBase(exec)
</span><span class="cx">         , m_globalObject(globalObject)
</span><span class="cx">         , m_isDOMGlobalObject(globalObject-&gt;inherits(globalObject-&gt;vm(), JSDOMGlobalObject::info()))
</span><span class="lines">@@ -1565,6 +1584,7 @@
</span><span class="cx">         , m_arrayBuffers(arrayBufferContents ? arrayBufferContents-&gt;size() : 0)
</span><span class="cx">         , m_blobURLs(blobURLs)
</span><span class="cx">         , m_blobFilePaths(blobFilePaths)
</span><ins>+        , m_sharedBuffers(sharedBuffers)
</ins><span class="cx">     {
</span><span class="cx">         if (!read(m_version))
</span><span class="cx">             m_version = 0xFFFFFFFF;
</span><span class="lines">@@ -2387,6 +2407,20 @@
</span><span class="cx"> 
</span><span class="cx">             return getJSValue(m_arrayBuffers[index].get());
</span><span class="cx">         }
</span><ins>+        case SharedArrayBufferTag: {
+            uint32_t index = UINT_MAX;
+            bool indexSuccessfullyRead = read(index);
+            if (!indexSuccessfullyRead || !m_sharedBuffers || index &gt;= m_sharedBuffers-&gt;size()) {
+                fail();
+                return JSValue();
+            }
+            
+            RELEASE_ASSERT(m_sharedBuffers-&gt;at(index));
+            RefPtr&lt;ArrayBuffer&gt; buffer = ArrayBuffer::create(WTFMove(m_sharedBuffers-&gt;at(index)));
+            JSValue result = getJSValue(buffer.get());
+            m_gcBuffer.append(result);
+            return result;
+        }
</ins><span class="cx">         case ArrayBufferViewTag: {
</span><span class="cx">             JSValue arrayBufferView;
</span><span class="cx">             if (!readArrayBufferView(m_exec-&gt;vm(), arrayBufferView)) {
</span><span class="lines">@@ -2445,6 +2479,7 @@
</span><span class="cx">     Vector&lt;RefPtr&lt;JSC::ArrayBuffer&gt;&gt; m_arrayBuffers;
</span><span class="cx">     Vector&lt;String&gt; m_blobURLs;
</span><span class="cx">     Vector&lt;String&gt; m_blobFilePaths;
</span><ins>+    ArrayBufferContentsArray* m_sharedBuffers;
</ins><span class="cx"> 
</span><span class="cx">     String blobFilePathForBlobURL(const String&amp; blobURL)
</span><span class="cx">     {
</span><span class="lines">@@ -2654,9 +2689,10 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-SerializedScriptValue::SerializedScriptValue(Vector&lt;uint8_t&gt;&amp;&amp; buffer, const Vector&lt;String&gt;&amp; blobURLs, std::unique_ptr&lt;ArrayBufferContentsArray&gt;&amp;&amp; arrayBufferContentsArray)
</del><ins>+SerializedScriptValue::SerializedScriptValue(Vector&lt;uint8_t&gt;&amp;&amp; buffer, const Vector&lt;String&gt;&amp; blobURLs, std::unique_ptr&lt;ArrayBufferContentsArray&gt; arrayBufferContentsArray, std::unique_ptr&lt;ArrayBufferContentsArray&gt; sharedBufferContentsArray)
</ins><span class="cx">     : m_data(WTFMove(buffer))
</span><span class="cx">     , m_arrayBufferContentsArray(WTFMove(arrayBufferContentsArray))
</span><ins>+    , m_sharedBufferContentsArray(WTFMove(sharedBufferContentsArray))
</ins><span class="cx"> {
</span><span class="cx">     // Since this SerializedScriptValue is meant to be passed between threads, its String data members
</span><span class="cx">     // need to be isolatedCopies so we don't run into thread safety issues for the StringImpls.
</span><span class="lines">@@ -2741,18 +2777,19 @@
</span><span class="cx">     Vector&lt;String&gt; blobURLs;
</span><span class="cx">     Vector&lt;RefPtr&lt;MessagePort&gt;&gt; dummyMessagePorts;
</span><span class="cx">     Vector&lt;RefPtr&lt;JSC::ArrayBuffer&gt;&gt; dummyArrayBuffers;
</span><del>-    auto code = CloneSerializer::serialize(&amp;exec, value, dummyMessagePorts, dummyArrayBuffers, blobURLs, buffer);
</del><ins>+    ArrayBufferContentsArray dummySharedBuffers;
+    auto code = CloneSerializer::serialize(&amp;exec, value, dummyMessagePorts, dummyArrayBuffers, blobURLs, buffer, SerializationContext::Default, dummySharedBuffers);
</ins><span class="cx"> 
</span><del>-    if (throwExceptions == Throwing)
</del><ins>+    if (throwExceptions == SerializationErrorMode::Throwing)
</ins><span class="cx">         maybeThrowExceptionIfSerializationFailed(exec, code);
</span><span class="cx"> 
</span><span class="cx">     if (code != SerializationReturnCode::SuccessfullyCompleted)
</span><span class="cx">         return nullptr;
</span><span class="cx"> 
</span><del>-    return adoptRef(*new SerializedScriptValue(WTFMove(buffer), blobURLs, nullptr));
</del><ins>+    return adoptRef(*new SerializedScriptValue(WTFMove(buffer), blobURLs, nullptr, nullptr));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-ExceptionOr&lt;Ref&lt;SerializedScriptValue&gt;&gt; SerializedScriptValue::create(ExecState&amp; state, JSValue value, Vector&lt;JSC::Strong&lt;JSC::JSObject&gt;&gt;&amp;&amp; transferList, Vector&lt;RefPtr&lt;MessagePort&gt;&gt;&amp; messagePorts)
</del><ins>+ExceptionOr&lt;Ref&lt;SerializedScriptValue&gt;&gt; SerializedScriptValue::create(ExecState&amp; state, JSValue value, Vector&lt;JSC::Strong&lt;JSC::JSObject&gt;&gt;&amp;&amp; transferList, Vector&lt;RefPtr&lt;MessagePort&gt;&gt;&amp; messagePorts, SerializationContext context)
</ins><span class="cx"> {
</span><span class="cx">     VM&amp; vm = state.vm();
</span><span class="cx">     Vector&lt;RefPtr&lt;JSC::ArrayBuffer&gt;&gt; arrayBuffers;
</span><span class="lines">@@ -2760,6 +2797,8 @@
</span><span class="cx">         if (auto arrayBuffer = toPossiblySharedArrayBuffer(vm, transferable.get())) {
</span><span class="cx">             if (arrayBuffer-&gt;isNeutered())
</span><span class="cx">                 return Exception { DATA_CLONE_ERR };
</span><ins>+            if (arrayBuffer-&gt;isShared() &amp;&amp; context != SerializationContext::WorkerPostMessage)
+                return Exception { DATA_CLONE_ERR };
</ins><span class="cx">             arrayBuffers.append(WTFMove(arrayBuffer));
</span><span class="cx">             continue;
</span><span class="cx">         }
</span><span class="lines">@@ -2774,7 +2813,8 @@
</span><span class="cx"> 
</span><span class="cx">     Vector&lt;uint8_t&gt; buffer;
</span><span class="cx">     Vector&lt;String&gt; blobURLs;
</span><del>-    auto code = CloneSerializer::serialize(&amp;state, value, messagePorts, arrayBuffers, blobURLs, buffer);
</del><ins>+    std::unique_ptr&lt;ArrayBufferContentsArray&gt; sharedBuffers = std::make_unique&lt;ArrayBufferContentsArray&gt;();
+    auto code = CloneSerializer::serialize(&amp;state, value, messagePorts, arrayBuffers, blobURLs, buffer, context, *sharedBuffers);
</ins><span class="cx"> 
</span><span class="cx">     if (code != SerializationReturnCode::SuccessfullyCompleted)
</span><span class="cx">         return exceptionForSerializationFailure(code);
</span><span class="lines">@@ -2783,7 +2823,7 @@
</span><span class="cx">     if (arrayBufferContentsArray.hasException())
</span><span class="cx">         return arrayBufferContentsArray.releaseException();
</span><span class="cx"> 
</span><del>-    return adoptRef(*new SerializedScriptValue(WTFMove(buffer), blobURLs, arrayBufferContentsArray.releaseReturnValue()));
</del><ins>+    return adoptRef(*new SerializedScriptValue(WTFMove(buffer), blobURLs, arrayBufferContentsArray.releaseReturnValue(), context == SerializationContext::WorkerPostMessage ? WTFMove(sharedBuffers) : nullptr));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> RefPtr&lt;SerializedScriptValue&gt; SerializedScriptValue::create(StringView string)
</span><span class="lines">@@ -2833,8 +2873,8 @@
</span><span class="cx"> 
</span><span class="cx"> JSValue SerializedScriptValue::deserialize(ExecState&amp; exec, JSGlobalObject* globalObject, Vector&lt;RefPtr&lt;MessagePort&gt;&gt;&amp; messagePorts, const Vector&lt;String&gt;&amp; blobURLs, const Vector&lt;String&gt;&amp; blobFilePaths, SerializationErrorMode throwExceptions)
</span><span class="cx"> {
</span><del>-    DeserializationResult result = CloneDeserializer::deserialize(&amp;exec, globalObject, messagePorts, m_arrayBufferContentsArray.get(), m_data, blobURLs, blobFilePaths);
-    if (throwExceptions == Throwing)
</del><ins>+    DeserializationResult result = CloneDeserializer::deserialize(&amp;exec, globalObject, messagePorts, m_arrayBufferContentsArray.get(), m_data, blobURLs, blobFilePaths, m_sharedBufferContentsArray.get());
+    if (throwExceptions == SerializationErrorMode::Throwing)
</ins><span class="cx">         maybeThrowExceptionIfSerializationFailed(exec, result.second);
</span><span class="cx">     return result.first ? result.first : jsNull();
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsSerializedScriptValueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/SerializedScriptValue.h (212034 => 212035)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/SerializedScriptValue.h        2017-02-10 02:35:51 UTC (rev 212034)
+++ trunk/Source/WebCore/bindings/js/SerializedScriptValue.h        2017-02-10 02:42:20 UTC (rev 212035)
</span><span class="lines">@@ -45,15 +45,16 @@
</span><span class="cx"> class SharedBuffer;
</span><span class="cx"> enum class SerializationReturnCode;
</span><span class="cx"> 
</span><del>-enum SerializationErrorMode { NonThrowing, Throwing };
</del><ins>+enum class SerializationErrorMode { NonThrowing, Throwing };
+enum class SerializationContext { Default, WorkerPostMessage };
</ins><span class="cx"> 
</span><span class="cx"> using ArrayBufferContentsArray = Vector&lt;JSC::ArrayBufferContents&gt;;
</span><span class="cx"> 
</span><span class="cx"> class SerializedScriptValue : public ThreadSafeRefCounted&lt;SerializedScriptValue&gt; {
</span><span class="cx"> public:
</span><del>-    WEBCORE_EXPORT static RefPtr&lt;SerializedScriptValue&gt; create(JSC::ExecState&amp;, JSC::JSValue, SerializationErrorMode = Throwing);
</del><ins>+    WEBCORE_EXPORT static RefPtr&lt;SerializedScriptValue&gt; create(JSC::ExecState&amp;, JSC::JSValue, SerializationErrorMode = SerializationErrorMode::Throwing);
</ins><span class="cx"> 
</span><del>-    WEBCORE_EXPORT static ExceptionOr&lt;Ref&lt;SerializedScriptValue&gt;&gt; create(JSC::ExecState&amp;, JSC::JSValue, Vector&lt;JSC::Strong&lt;JSC::JSObject&gt;&gt;&amp;&amp;, Vector&lt;RefPtr&lt;MessagePort&gt;&gt;&amp;);
</del><ins>+    WEBCORE_EXPORT static ExceptionOr&lt;Ref&lt;SerializedScriptValue&gt;&gt; create(JSC::ExecState&amp;, JSC::JSValue, Vector&lt;JSC::Strong&lt;JSC::JSObject&gt;&gt;&amp;&amp; transfer, Vector&lt;RefPtr&lt;MessagePort&gt;&gt;&amp;, SerializationContext = SerializationContext::Default);
</ins><span class="cx"> 
</span><span class="cx">     WEBCORE_EXPORT static RefPtr&lt;SerializedScriptValue&gt; create(StringView);
</span><span class="cx">     static Ref&lt;SerializedScriptValue&gt; adopt(Vector&lt;uint8_t&gt;&amp;&amp; buffer)
</span><span class="lines">@@ -63,9 +64,9 @@
</span><span class="cx"> 
</span><span class="cx">     static Ref&lt;SerializedScriptValue&gt; nullValue();
</span><span class="cx"> 
</span><del>-    WEBCORE_EXPORT JSC::JSValue deserialize(JSC::ExecState&amp;, JSC::JSGlobalObject*, SerializationErrorMode = Throwing);
-    WEBCORE_EXPORT JSC::JSValue deserialize(JSC::ExecState&amp;, JSC::JSGlobalObject*, Vector&lt;RefPtr&lt;MessagePort&gt;&gt;&amp;, SerializationErrorMode = Throwing);
-    JSC::JSValue deserialize(JSC::ExecState&amp;, JSC::JSGlobalObject*, Vector&lt;RefPtr&lt;MessagePort&gt;&gt;&amp;, const Vector&lt;String&gt;&amp; blobURLs, const Vector&lt;String&gt;&amp; blobFilePaths, SerializationErrorMode = Throwing);
</del><ins>+    WEBCORE_EXPORT JSC::JSValue deserialize(JSC::ExecState&amp;, JSC::JSGlobalObject*, SerializationErrorMode = SerializationErrorMode::Throwing);
+    WEBCORE_EXPORT JSC::JSValue deserialize(JSC::ExecState&amp;, JSC::JSGlobalObject*, Vector&lt;RefPtr&lt;MessagePort&gt;&gt;&amp;, SerializationErrorMode = SerializationErrorMode::Throwing);
+    JSC::JSValue deserialize(JSC::ExecState&amp;, JSC::JSGlobalObject*, Vector&lt;RefPtr&lt;MessagePort&gt;&gt;&amp;, const Vector&lt;String&gt;&amp; blobURLs, const Vector&lt;String&gt;&amp; blobFilePaths, SerializationErrorMode = SerializationErrorMode::Throwing);
</ins><span class="cx"> 
</span><span class="cx">     static uint32_t wireFormatVersion();
</span><span class="cx"> 
</span><span class="lines">@@ -94,10 +95,11 @@
</span><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     WEBCORE_EXPORT SerializedScriptValue(Vector&lt;unsigned char&gt;&amp;&amp;);
</span><del>-    SerializedScriptValue(Vector&lt;unsigned char&gt;&amp;&amp;, const Vector&lt;String&gt;&amp; blobURLs, std::unique_ptr&lt;ArrayBufferContentsArray&gt;&amp;&amp;);
</del><ins>+    SerializedScriptValue(Vector&lt;unsigned char&gt;&amp;&amp;, const Vector&lt;String&gt;&amp; blobURLs, std::unique_ptr&lt;ArrayBufferContentsArray&gt;, std::unique_ptr&lt;ArrayBufferContentsArray&gt; sharedBuffers);
</ins><span class="cx"> 
</span><span class="cx">     Vector&lt;unsigned char&gt; m_data;
</span><span class="cx">     std::unique_ptr&lt;ArrayBufferContentsArray&gt; m_arrayBufferContentsArray;
</span><ins>+    std::unique_ptr&lt;ArrayBufferContentsArray&gt; m_sharedBufferContentsArray;
</ins><span class="cx">     Vector&lt;String&gt; m_blobURLs;
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoredomCustomEventcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/CustomEvent.cpp (212034 => 212035)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/CustomEvent.cpp        2017-02-10 02:35:51 UTC (rev 212034)
+++ trunk/Source/WebCore/dom/CustomEvent.cpp        2017-02-10 02:42:20 UTC (rev 212035)
</span><span class="lines">@@ -60,7 +60,7 @@
</span><span class="cx"> RefPtr&lt;SerializedScriptValue&gt; CustomEvent::trySerializeDetail(JSC::ExecState&amp; state)
</span><span class="cx"> {
</span><span class="cx">     if (!m_triedToSerialize) {
</span><del>-        m_serializedDetail = SerializedScriptValue::create(state, m_detail, NonThrowing);
</del><ins>+        m_serializedDetail = SerializedScriptValue::create(state, m_detail, SerializationErrorMode::NonThrowing);
</ins><span class="cx">         m_triedToSerialize = true;
</span><span class="cx">     }
</span><span class="cx">     return m_serializedDetail;
</span></span></pre></div>
<a id="trunkSourceWebCoredomErrorEventcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/ErrorEvent.cpp (212034 => 212035)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/ErrorEvent.cpp        2017-02-10 02:35:51 UTC (rev 212034)
+++ trunk/Source/WebCore/dom/ErrorEvent.cpp        2017-02-10 02:42:20 UTC (rev 212035)
</span><span class="lines">@@ -91,7 +91,7 @@
</span><span class="cx"> RefPtr&lt;SerializedScriptValue&gt; ErrorEvent::trySerializeError(ExecState&amp; exec)
</span><span class="cx"> {
</span><span class="cx">     if (!m_triedToSerialize) {
</span><del>-        m_serializedDetail = SerializedScriptValue::create(exec, m_error.get(), NonThrowing);
</del><ins>+        m_serializedDetail = SerializedScriptValue::create(exec, m_error.get(), SerializationErrorMode::NonThrowing);
</ins><span class="cx">         m_triedToSerialize = true;
</span><span class="cx">     }
</span><span class="cx">     return m_serializedDetail;
</span></span></pre></div>
<a id="trunkSourceWebCoredomMessageEventcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/MessageEvent.cpp (212034 => 212035)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/MessageEvent.cpp        2017-02-10 02:35:51 UTC (rev 212034)
+++ trunk/Source/WebCore/dom/MessageEvent.cpp        2017-02-10 02:42:20 UTC (rev 212035)
</span><span class="lines">@@ -168,7 +168,7 @@
</span><span class="cx">     ASSERT(!m_dataAsScriptValue.hasNoValue());
</span><span class="cx">     
</span><span class="cx">     if (!m_dataAsSerializedScriptValue &amp;&amp; !m_triedToSerialize) {
</span><del>-        m_dataAsSerializedScriptValue = SerializedScriptValue::create(*exec, m_dataAsScriptValue.jsValue(), NonThrowing);
</del><ins>+        m_dataAsSerializedScriptValue = SerializedScriptValue::create(*exec, m_dataAsScriptValue.jsValue(), SerializationErrorMode::NonThrowing);
</ins><span class="cx">         m_triedToSerialize = true;
</span><span class="cx">     }
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceWebCoredomPopStateEventcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/PopStateEvent.cpp (212034 => 212035)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/PopStateEvent.cpp        2017-02-10 02:35:51 UTC (rev 212034)
+++ trunk/Source/WebCore/dom/PopStateEvent.cpp        2017-02-10 02:42:20 UTC (rev 212035)
</span><span class="lines">@@ -70,7 +70,7 @@
</span><span class="cx">     ASSERT(!m_state.hasNoValue());
</span><span class="cx">     
</span><span class="cx">     if (!m_serializedState &amp;&amp; !m_triedToSerialize) {
</span><del>-        m_serializedState = SerializedScriptValue::create(executionState, m_state.jsValue(), NonThrowing);
</del><ins>+        m_serializedState = SerializedScriptValue::create(executionState, m_state.jsValue(), SerializationErrorMode::NonThrowing);
</ins><span class="cx">         m_triedToSerialize = true;
</span><span class="cx">     }
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceWebCoreworkersDedicatedWorkerGlobalScopecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/workers/DedicatedWorkerGlobalScope.cpp (212034 => 212035)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/workers/DedicatedWorkerGlobalScope.cpp        2017-02-10 02:35:51 UTC (rev 212034)
+++ trunk/Source/WebCore/workers/DedicatedWorkerGlobalScope.cpp        2017-02-10 02:42:20 UTC (rev 212035)
</span><span class="lines">@@ -66,7 +66,7 @@
</span><span class="cx"> ExceptionOr&lt;void&gt; DedicatedWorkerGlobalScope::postMessage(JSC::ExecState&amp; state, JSC::JSValue messageValue, Vector&lt;JSC::Strong&lt;JSC::JSObject&gt;&gt;&amp;&amp; transfer)
</span><span class="cx"> {
</span><span class="cx">     Vector&lt;RefPtr&lt;MessagePort&gt;&gt; ports;
</span><del>-    auto message = SerializedScriptValue::create(state, messageValue, WTFMove(transfer), ports);
</del><ins>+    auto message = SerializedScriptValue::create(state, messageValue, WTFMove(transfer), ports, SerializationContext::WorkerPostMessage);
</ins><span class="cx">     if (message.hasException())
</span><span class="cx">         return message.releaseException();
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreworkersWorkercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/workers/Worker.cpp (212034 => 212035)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/workers/Worker.cpp        2017-02-10 02:35:51 UTC (rev 212034)
+++ trunk/Source/WebCore/workers/Worker.cpp        2017-02-10 02:42:20 UTC (rev 212035)
</span><span class="lines">@@ -107,7 +107,7 @@
</span><span class="cx"> ExceptionOr&lt;void&gt; Worker::postMessage(JSC::ExecState&amp; state, JSC::JSValue messageValue, Vector&lt;JSC::Strong&lt;JSC::JSObject&gt;&gt;&amp;&amp; transfer)
</span><span class="cx"> {
</span><span class="cx">     Vector&lt;RefPtr&lt;MessagePort&gt;&gt; ports;
</span><del>-    auto message = SerializedScriptValue::create(state, messageValue, WTFMove(transfer), ports);
</del><ins>+    auto message = SerializedScriptValue::create(state, messageValue, WTFMove(transfer), ports, SerializationContext::WorkerPostMessage);
</ins><span class="cx">     if (message.hasException())
</span><span class="cx">         return message.releaseException();
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>