<!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>[191622] 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/191622">191622</a></dd>
<dt>Author</dt> <dd>calvaris@igalia.com</dd>
<dt>Date</dt> <dd>2015-10-27 04:36:56 -0700 (Tue, 27 Oct 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>[Streams API] Add close method to writable stream
https://bugs.webkit.org/show_bug.cgi?id=150560

Reviewed by Darin Adler.

Source/WebCore:

Added the close method which requires three additional writable stream internal functions plus a queuing
function to retrieve a value from the queue according to the spec.

Current test set suffices. Expectations were updated accordingly.

* Modules/streams/StreamInternals.js:
(peekQueueValue):
* Modules/streams/WritableStream.js:
(close):
* Modules/streams/WritableStreamInternals.js:
(callOrScheduleWritableStreamAdvanceQueue):
(writableStreamAdvanceQueue):
(closeWritableStream): Added as per spec.

LayoutTests:

New expectations after adding close method to writable stream.

Two tests were also flagged because of bug 147933 that prevents them from running properly in certain
conditions. So far this only happened in Mac, hence they were flagged only for it.

* platform/mac/TestExpectations:
* streams/reference-implementation/bad-underlying-sinks-expected.txt:
* streams/reference-implementation/brand-checks-expected.txt:
* streams/reference-implementation/pipe-to-expected.txt:
* streams/reference-implementation/writable-stream-abort-expected.txt:
* streams/reference-implementation/writable-stream-expected.txt:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsplatformmacTestExpectations">trunk/LayoutTests/platform/mac/TestExpectations</a></li>
<li><a href="#trunkLayoutTestsstreamsreferenceimplementationbadunderlyingsinksexpectedtxt">trunk/LayoutTests/streams/reference-implementation/bad-underlying-sinks-expected.txt</a></li>
<li><a href="#trunkLayoutTestsstreamsreferenceimplementationbrandchecksexpectedtxt">trunk/LayoutTests/streams/reference-implementation/brand-checks-expected.txt</a></li>
<li><a href="#trunkLayoutTestsstreamsreferenceimplementationpipetoexpectedtxt">trunk/LayoutTests/streams/reference-implementation/pipe-to-expected.txt</a></li>
<li><a href="#trunkLayoutTestsstreamsreferenceimplementationwritablestreamabortexpectedtxt">trunk/LayoutTests/streams/reference-implementation/writable-stream-abort-expected.txt</a></li>
<li><a href="#trunkLayoutTestsstreamsreferenceimplementationwritablestreamexpectedtxt">trunk/LayoutTests/streams/reference-implementation/writable-stream-expected.txt</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreModulesstreamsStreamInternalsjs">trunk/Source/WebCore/Modules/streams/StreamInternals.js</a></li>
<li><a href="#trunkSourceWebCoreModulesstreamsWritableStreamjs">trunk/Source/WebCore/Modules/streams/WritableStream.js</a></li>
<li><a href="#trunkSourceWebCoreModulesstreamsWritableStreamInternalsjs">trunk/Source/WebCore/Modules/streams/WritableStreamInternals.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (191621 => 191622)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2015-10-27 07:00:57 UTC (rev 191621)
+++ trunk/LayoutTests/ChangeLog        2015-10-27 11:36:56 UTC (rev 191622)
</span><span class="lines">@@ -1,3 +1,22 @@
</span><ins>+2015-10-27  Xabier Rodriguez Calvar  &lt;calvaris@igalia.com&gt;
+
+        [Streams API] Add close method to writable stream
+        https://bugs.webkit.org/show_bug.cgi?id=150560
+
+        Reviewed by Darin Adler.
+
+        New expectations after adding close method to writable stream.
+
+        Two tests were also flagged because of bug 147933 that prevents them from running properly in certain
+        conditions. So far this only happened in Mac, hence they were flagged only for it.
+
+        * platform/mac/TestExpectations:
+        * streams/reference-implementation/bad-underlying-sinks-expected.txt:
+        * streams/reference-implementation/brand-checks-expected.txt:
+        * streams/reference-implementation/pipe-to-expected.txt:
+        * streams/reference-implementation/writable-stream-abort-expected.txt:
+        * streams/reference-implementation/writable-stream-expected.txt:
+
</ins><span class="cx"> 2015-10-26  Ryan Haddad  &lt;ryanhaddad@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Removing duplicated test expectations and removing debug flag from flaky fast/canvas/webgl tests
</span></span></pre></div>
<a id="trunkLayoutTestsplatformmacTestExpectations"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/mac/TestExpectations (191621 => 191622)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/mac/TestExpectations        2015-10-27 07:00:57 UTC (rev 191621)
+++ trunk/LayoutTests/platform/mac/TestExpectations        2015-10-27 11:36:56 UTC (rev 191622)
</span><span class="lines">@@ -1348,3 +1348,7 @@
</span><span class="cx"> 
</span><span class="cx"> # Imported Blink tests which have not been investigated.
</span><span class="cx"> imported/blink/compositing/video/video-controls-layer-creation-squashing.html [ Pass ImageOnlyFailure ]
</span><ins>+
+# Promises callbacks issues create problems in the writable stream tests
+webkit.org/b/147933 streams/reference-implementation/count-queuing-strategy.html [ Pass Failure ]
+webkit.org/b/147933 streams/reference-implementation/writable-stream-abort.html [ Pass Failure ]
</ins></span></pre></div>
<a id="trunkLayoutTestsstreamsreferenceimplementationbadunderlyingsinksexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/streams/reference-implementation/bad-underlying-sinks-expected.txt (191621 => 191622)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/streams/reference-implementation/bad-underlying-sinks-expected.txt        2015-10-27 07:00:57 UTC (rev 191621)
+++ trunk/LayoutTests/streams/reference-implementation/bad-underlying-sinks-expected.txt        2015-10-27 11:36:56 UTC (rev 191622)
</span><span class="lines">@@ -5,6 +5,6 @@
</span><span class="cx"> FAIL Underlying sink: throwing write method write not implemented
</span><span class="cx"> PASS Underlying sink: throwing abort getter 
</span><span class="cx"> PASS Underlying sink: throwing abort method 
</span><del>-FAIL Underlying sink: throwing close getter close not implemented
-FAIL Underlying sink: throwing close method close not implemented
</del><ins>+PASS Underlying sink: throwing close getter 
+PASS Underlying sink: throwing close method 
</ins><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestsstreamsreferenceimplementationbrandchecksexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/streams/reference-implementation/brand-checks-expected.txt (191621 => 191622)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/streams/reference-implementation/brand-checks-expected.txt        2015-10-27 07:00:57 UTC (rev 191621)
+++ trunk/LayoutTests/streams/reference-implementation/brand-checks-expected.txt        2015-10-27 11:36:56 UTC (rev 191622)
</span><span class="lines">@@ -22,7 +22,7 @@
</span><span class="cx"> PASS WritableStream.prototype.state enforces a brand check 
</span><span class="cx"> PASS WritableStream.prototype.abort enforces a brand check 
</span><span class="cx"> FAIL WritableStream.prototype.write enforces a brand check write not implemented
</span><del>-FAIL WritableStream.prototype.close enforces a brand check close not implemented
</del><ins>+PASS WritableStream.prototype.close enforces a brand check 
</ins><span class="cx"> PASS ByteLengthQueuingStrategy.prototype.size should work generically on its this and its arguments 
</span><span class="cx"> PASS CountQueuingStrategy.prototype.size should work generically on its this and its arguments 
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestsstreamsreferenceimplementationpipetoexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/streams/reference-implementation/pipe-to-expected.txt (191621 => 191622)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/streams/reference-implementation/pipe-to-expected.txt        2015-10-27 07:00:57 UTC (rev 191621)
+++ trunk/LayoutTests/streams/reference-implementation/pipe-to-expected.txt        2015-10-27 11:36:56 UTC (rev 191622)
</span><span class="lines">@@ -1,6 +1,6 @@
</span><span class="cx"> 
</span><span class="cx"> FAIL Piping from a ReadableStream from which lots of data are readable synchronously pipeTo is not implemented
</span><del>-FAIL Piping from a ReadableStream in readable state to a WritableStream in closing state close not implemented
</del><ins>+FAIL Piping from a ReadableStream in readable state to a WritableStream in closing state pipeTo is not implemented
</ins><span class="cx"> FAIL Piping from a ReadableStream in readable state to a WritableStream in errored state write not implemented
</span><span class="cx"> FAIL Piping from a ReadableStream in the readable state which becomes closed after pipeTo call to a WritableStream in the writable state pipeTo is not implemented
</span><span class="cx"> FAIL Piping from a ReadableStream in the readable state which becomes errored after pipeTo call to a WritableStream in the writable state pipeTo is not implemented
</span><span class="lines">@@ -17,7 +17,7 @@
</span><span class="cx"> FAIL Piping to a duck-typed asynchronous &quot;writable stream&quot; works pipeTo is not implemented
</span><span class="cx"> FAIL Piping to a stream that has been aborted passes through the error as the cancellation reason pipeTo is not implemented
</span><span class="cx"> FAIL Piping to a stream and then aborting it passes through the error as the cancellation reason pipeTo is not implemented
</span><del>-FAIL Piping to a stream that has been closed propagates a TypeError cancellation reason backward close not implemented
</del><ins>+FAIL Piping to a stream that has been closed propagates a TypeError cancellation reason backward pipeTo is not implemented
</ins><span class="cx"> FAIL Piping to a stream and then closing it propagates a TypeError cancellation reason backward pipeTo is not implemented
</span><span class="cx"> FAIL Piping to a stream that errors on write should pass through the error as the cancellation reason pipeTo is not implemented
</span><span class="cx"> FAIL Piping to a stream that errors on write should not pass through the error if the stream is already closed pipeTo is not implemented
</span></span></pre></div>
<a id="trunkLayoutTestsstreamsreferenceimplementationwritablestreamabortexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/streams/reference-implementation/writable-stream-abort-expected.txt (191621 => 191622)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/streams/reference-implementation/writable-stream-abort-expected.txt        2015-10-27 07:00:57 UTC (rev 191621)
+++ trunk/LayoutTests/streams/reference-implementation/writable-stream-abort-expected.txt        2015-10-27 11:36:56 UTC (rev 191622)
</span><span class="lines">@@ -7,8 +7,8 @@
</span><span class="cx"> FAIL Aborting a WritableStream puts it in an errored state, with stored error equal to the abort reason write not implemented
</span><span class="cx"> FAIL Aborting a WritableStream causes any outstanding ready promises to be fulfilled immediately write not implemented
</span><span class="cx"> FAIL Aborting a WritableStream causes any outstanding write() promises to be rejected with the abort reason write not implemented
</span><del>-FAIL Closing but then immediately aborting a WritableStream causes the stream to error close not implemented
-FAIL Closing a WritableStream and aborting it while it closes causes the stream to error close not implemented
-FAIL Aborting a WritableStream after it is closed is a no-op close not implemented
</del><ins>+PASS Closing but then immediately aborting a WritableStream causes the stream to error 
+PASS Closing a WritableStream and aborting it while it closes causes the stream to error 
+PASS Aborting a WritableStream after it is closed is a no-op 
</ins><span class="cx"> PASS WritableStream should call underlying sink's close if no abort is supplied 
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestsstreamsreferenceimplementationwritablestreamexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/streams/reference-implementation/writable-stream-expected.txt (191621 => 191622)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/streams/reference-implementation/writable-stream-expected.txt        2015-10-27 07:00:57 UTC (rev 191621)
+++ trunk/LayoutTests/streams/reference-implementation/writable-stream-expected.txt        2015-10-27 11:36:56 UTC (rev 191622)
</span><span class="lines">@@ -1,8 +1,8 @@
</span><span class="cx"> 
</span><span class="cx"> PASS error argument is given to start method 
</span><span class="cx"> FAIL Underlying sink's write won't be called until start finishes write not implemented
</span><del>-FAIL Underlying sink's close won't be called until start finishes close not implemented
-FAIL Fulfillment value of ws.close() call must be undefined even if the underlying sink returns a non-undefined value close not implemented
</del><ins>+PASS Underlying sink's close won't be called until start finishes 
+PASS Fulfillment value of ws.close() call must be undefined even if the underlying sink returns a non-undefined value 
</ins><span class="cx"> PASS Underlying sink's write or close are never invoked if start throws 
</span><span class="cx"> PASS Underlying sink's write or close are never invoked if the promise returned by start is rejected 
</span><span class="cx"> PASS WritableStream can be constructed with no arguments 
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (191621 => 191622)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2015-10-27 07:00:57 UTC (rev 191621)
+++ trunk/Source/WebCore/ChangeLog        2015-10-27 11:36:56 UTC (rev 191622)
</span><span class="lines">@@ -1,3 +1,24 @@
</span><ins>+2015-10-27  Xabier Rodriguez Calvar  &lt;calvaris@igalia.com&gt;
+
+        [Streams API] Add close method to writable stream
+        https://bugs.webkit.org/show_bug.cgi?id=150560
+
+        Reviewed by Darin Adler.
+
+        Added the close method which requires three additional writable stream internal functions plus a queuing
+        function to retrieve a value from the queue according to the spec.
+
+        Current test set suffices. Expectations were updated accordingly.
+
+        * Modules/streams/StreamInternals.js:
+        (peekQueueValue):
+        * Modules/streams/WritableStream.js:
+        (close):
+        * Modules/streams/WritableStreamInternals.js:
+        (callOrScheduleWritableStreamAdvanceQueue):
+        (writableStreamAdvanceQueue):
+        (closeWritableStream): Added as per spec.
+
</ins><span class="cx"> 2015-10-26  Brady Eidson  &lt;beidson@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Make IDBKeyData from a struct to a class.
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesstreamsStreamInternalsjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/streams/StreamInternals.js (191621 => 191622)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/streams/StreamInternals.js        2015-10-27 07:00:57 UTC (rev 191621)
+++ trunk/Source/WebCore/Modules/streams/StreamInternals.js        2015-10-27 11:36:56 UTC (rev 191622)
</span><span class="lines">@@ -151,3 +151,11 @@
</span><span class="cx"> 
</span><span class="cx">     return undefined;
</span><span class="cx"> }
</span><ins>+
+function peekQueueValue(queue)
+{
+    // FIXME
+    // assert(queue.content.length &gt; 0);
+
+    return queue.content[0].value;
+}
</ins></span></pre></div>
<a id="trunkSourceWebCoreModulesstreamsWritableStreamjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/streams/WritableStream.js (191621 => 191622)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/streams/WritableStream.js        2015-10-27 07:00:57 UTC (rev 191621)
+++ trunk/Source/WebCore/Modules/streams/WritableStream.js        2015-10-27 11:36:56 UTC (rev 191622)
</span><span class="lines">@@ -88,7 +88,23 @@
</span><span class="cx"> {
</span><span class="cx">     &quot;use strict&quot;;
</span><span class="cx"> 
</span><del>-    throw new EvalError(&quot;close not implemented&quot;);
</del><ins>+    if (!@isWritableStream(this))
+        return Promise.reject(new @TypeError(&quot;The WritableStream.close method can only be used on instances of WritableStream&quot;));
+
+    if (this.@state === &quot;closed&quot; || this.@state === &quot;closing&quot;)
+        return Promise.reject(new @TypeError(&quot;Cannot close a WritableString that is closed or closing&quot;));
+
+    if (this.@state === &quot;errored&quot;)
+        return Promise.reject(this.@storedError);
+
+    if (this.@state === &quot;waiting&quot;)
+        @resolveStreamsPromise(this.@readyPromise, undefined);
+
+    this.@state = &quot;closing&quot;;
+    @enqueueValueWithSize(this.@queue, &quot;close&quot;, 0);
+    @callOrScheduleWritableStreamAdvanceQueue(this);
+
+    return this.@closedPromise;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> function write(chunk)
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesstreamsWritableStreamInternalsjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/streams/WritableStreamInternals.js (191621 => 191622)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/streams/WritableStreamInternals.js        2015-10-27 07:00:57 UTC (rev 191621)
+++ trunk/Source/WebCore/Modules/streams/WritableStreamInternals.js        2015-10-27 11:36:56 UTC (rev 191622)
</span><span class="lines">@@ -73,3 +73,69 @@
</span><span class="cx">     this.@state = &quot;errored&quot;;
</span><span class="cx">     return undefined;
</span><span class="cx"> }
</span><ins>+
+function callOrScheduleWritableStreamAdvanceQueue(stream)
+{
+    if (!stream.@started)
+        stream.@startedPromise.then(function() { @writableStreamAdvanceQueue(stream); });
+    else
+        @writableStreamAdvanceQueue(stream);
+
+    return undefined;
+}
+
+function writableStreamAdvanceQueue(stream)
+{
+    if (stream.@queue.content.length === 0 || stream.@writing)
+        return undefined;
+
+    const writeRecord = @peekQueueValue(stream.@queue);
+    if (writeRecord === &quot;close&quot;) {
+        // FIXME
+        // assert(stream.@state === &quot;closing&quot;);
+        @dequeueValue(stream.@queue);
+        // FIXME
+        // assert(stream.@queue.content.length === 0);
+        @closeWritableStream(stream);
+        return undefined;
+    }
+
+    stream.@writing = true;
+    @promiseInvokeOrNoop(stream.@underlyingSink, &quot;write&quot;, [writeRecord.chunk]).then(
+        function() {
+            if (stream.@state === &quot;errored&quot;)
+                return;
+            stream.@writing = false;
+            @resolveStreamsPromise(writeRecord.promise, undefined);
+            @dequeueValue(stream.@queue);
+            @syncWritableStreamStateWithQueue(stream);
+            @writableStreamAdvanceQueue(stream);
+        },
+        function(r) {
+            @errorWritableStream.@apply(stream, [r]);
+        }
+    );
+
+    return undefined;
+}
+
+function closeWritableStream(stream)
+{
+    // FIXME
+    // assert(stream.@state === &quot;closing&quot;);
+    @promiseInvokeOrNoop(stream.@underlyingSink, &quot;close&quot;).then(
+        function() {
+            if (stream.@state === &quot;errored&quot;)
+                return;
+            // FIXME
+            // assert(stream.@state === &quot;closing&quot;);
+            @resolveStreamsPromise(stream.@closedPromise, undefined);
+            stream.@state = &quot;closed&quot;;
+        },
+        function(r) {
+            @errorWritableStream.@apply(stream, [r]);
+        }
+    );
+
+    return undefined;
+}
</ins></span></pre>
</div>
</div>

</body>
</html>