Diff
Modified: trunk/Source/WebCore/ChangeLog (282394 => 282395)
--- trunk/Source/WebCore/ChangeLog 2021-09-14 16:48:34 UTC (rev 282394)
+++ trunk/Source/WebCore/ChangeLog 2021-09-14 17:02:08 UTC (rev 282395)
@@ -1,3 +1,36 @@
+2021-09-14 Youenn Fablet <[email protected]>
+
+ Refactor WritableStream to better integrate https://streams.spec.whatwg.org/#create-writable-stream
+ https://bugs.webkit.org/show_bug.cgi?id=230219
+
+ Reviewed by Sihui Liu.
+
+ Previously to create a WritableStream as https://streams.spec.whatwg.org/#create-writable-stream,
+ we were still going through the WritableStream constructor taking an underlying sink.
+ We refactor code to stop doing that, which will make it easy to introduce https://streams.spec.whatwg.org/#writablestream-set-up
+ which is now used in other web specifications.
+
+ To do so, we introduce a createFromUnderlyingSink built-in function that creates a WritableStream from an InternalWritableStream.
+ Covered by existing tests.
+
+ * Modules/streams/StreamInternals.js:
+ (extractHighWaterMark): Make sure extractHighWaterMark returns a number as WebIDL defines HWM as a double.
+ * Modules/streams/WritableStream.cpp:
+ (WebCore::WritableStream::create):
+ * Modules/streams/WritableStream.h:
+ * Modules/streams/WritableStreamInternals.js:
+ (createWritableStream):
+ (createInternalWritableStreamFromUnderlyingSink):
+ * bindings/js/InternalWritableStream.cpp:
+ (WebCore::InternalWritableStream::createFromUnderlyingSink):
+ (WebCore::InternalWritableStream::fromObject):
+ (WebCore::InternalWritableStream::create): Deleted.
+ * bindings/js/InternalWritableStream.h:
+ * bindings/js/JSDOMGlobalObject.cpp:
+ (WebCore::JSC_DEFINE_HOST_FUNCTION):
+ (WebCore::JSDOMGlobalObject::addBuiltinGlobals):
+ * bindings/js/WebCoreBuiltinNames.h:
+
2021-09-14 Chris Dumez <[email protected]>
[Hardening] Validate IDBValue's blob paths in WebIDBServer::putOrAdd()
Modified: trunk/Source/WebCore/Modules/streams/StreamInternals.js (282394 => 282395)
--- trunk/Source/WebCore/Modules/streams/StreamInternals.js 2021-09-14 16:48:34 UTC (rev 282394)
+++ trunk/Source/WebCore/Modules/streams/StreamInternals.js 2021-09-14 17:02:08 UTC (rev 282395)
@@ -185,7 +185,7 @@
if (@isNaN(highWaterMark) || highWaterMark < 0)
@throwRangeError("highWaterMark value is negative or not a number");
- return highWaterMark;
+ return @toNumber(highWaterMark);
}
function createFulfilledPromise(value)
Modified: trunk/Source/WebCore/Modules/streams/WritableStream.cpp (282394 => 282395)
--- trunk/Source/WebCore/Modules/streams/WritableStream.cpp 2021-09-14 16:48:34 UTC (rev 282394)
+++ trunk/Source/WebCore/Modules/streams/WritableStream.cpp 2021-09-14 17:02:08 UTC (rev 282395)
@@ -46,7 +46,7 @@
ExceptionOr<Ref<WritableStream>> WritableStream::create(JSC::JSGlobalObject& globalObject, JSC::JSValue underlyingSink, JSC::JSValue strategy)
{
- auto result = InternalWritableStream::create(*JSC::jsCast<JSDOMGlobalObject*>(&globalObject), underlyingSink, strategy);
+ auto result = InternalWritableStream::createFromUnderlyingSink(*JSC::jsCast<JSDOMGlobalObject*>(&globalObject), underlyingSink, strategy);
if (result.hasException())
return result.releaseException();
@@ -58,6 +58,11 @@
return create(globalObject, toJSNewlyCreated(&globalObject, &globalObject, WTFMove(sink)), JSC::jsUndefined());
}
+Ref<WritableStream> WritableStream::create(Ref<InternalWritableStream>&& internalWritableStream)
+{
+ return adoptRef(*new WritableStream(WTFMove(internalWritableStream)));
+}
+
WritableStream::WritableStream(Ref<InternalWritableStream>&& internalWritableStream)
: m_internalWritableStream(WTFMove(internalWritableStream))
{
Modified: trunk/Source/WebCore/Modules/streams/WritableStream.h (282394 => 282395)
--- trunk/Source/WebCore/Modules/streams/WritableStream.h 2021-09-14 16:48:34 UTC (rev 282394)
+++ trunk/Source/WebCore/Modules/streams/WritableStream.h 2021-09-14 17:02:08 UTC (rev 282395)
@@ -39,6 +39,7 @@
public:
static ExceptionOr<Ref<WritableStream>> create(JSC::JSGlobalObject&, std::optional<JSC::Strong<JSC::JSObject>>&&, std::optional<JSC::Strong<JSC::JSObject>>&&);
static ExceptionOr<Ref<WritableStream>> create(JSDOMGlobalObject&, Ref<WritableStreamSink>&&);
+ static Ref<WritableStream> create(Ref<InternalWritableStream>&&);
~WritableStream() = default;
Modified: trunk/Source/WebCore/Modules/streams/WritableStreamInternals.js (282394 => 282395)
--- trunk/Source/WebCore/Modules/streams/WritableStreamInternals.js 2021-09-14 16:48:34 UTC (rev 282394)
+++ trunk/Source/WebCore/Modules/streams/WritableStreamInternals.js 2021-09-14 17:02:08 UTC (rev 282395)
@@ -45,19 +45,21 @@
return new @WritableStreamDefaultWriter(stream);
}
-function createWritableStream(startAlgorithm, writeAlgorithm, closeAlgorithm, abortAlgorithm, writableHighWaterMark, writableSizeAlgorithm)
+// https://streams.spec.whatwg.org/#create-writable-stream
+function createWritableStream(startAlgorithm, writeAlgorithm, closeAlgorithm, abortAlgorithm, highWaterMark, sizeAlgorithm)
{
- if (arguments.length < 5)
- writableHighWaterMark = 1;
- if (arguments.length < 6)
- writableSizeAlgorithm = () => { return 1; };
+ @assert(typeof highWaterMark === "number" && !@isNaN(highWaterMark) && highWaterMark >= 0);
- let underlyingSink = { startAlgorithm: startAlgorithm, writeAlgorithm: writeAlgorithm, closeAlgorithm: closeAlgorithm, abortAlgorithm: abortAlgorithm};
- @putByIdDirectPrivate(underlyingSink, "WritableStream", true);
- return new @WritableStream(underlyingSink, { sizeAlgorithm: writableSizeAlgorithm, highWaterMark: writableHighWaterMark });
+ const internalStream = { };
+ @initializeWritableStreamSlots(internalStream, { });
+ const controller = new @WritableStreamDefaultController();
+
+ @setUpWritableStreamDefaultController(internalStream, controller, startAlgorithm, writeAlgorithm, closeAlgorithm, abortAlgorithm, highWaterMark, sizeAlgorithm);
+
+ return @createWritableStreamFromInternal(internalStream);
}
-function createInternalWritableStream(underlyingSink, strategy)
+function createInternalWritableStreamFromUnderlyingSink(underlyingSink, strategy)
{
"use strict";
@@ -72,16 +74,6 @@
if (!@isObject(underlyingSink))
@throwTypeError("WritableStream constructor takes an object as first argument");
- // createWriteStream code path.
- if (@getByIdDirectPrivate(underlyingSink, "WritableStream")) {
- @initializeWritableStreamSlots(stream, underlyingSink);
-
- const controller = new @WritableStreamDefaultController();
-
- @setUpWritableStreamDefaultController(stream, controller, underlyingSink.startAlgorithm, underlyingSink.writeAlgorithm, underlyingSink.closeAlgorithm, underlyingSink.abortAlgorithm, strategy.highWaterMark, strategy.sizeAlgorithm);
- return stream;
- }
-
if ("type" in underlyingSink)
@throwRangeError("Invalid type is specified");
Modified: trunk/Source/WebCore/bindings/js/InternalWritableStream.cpp (282394 => 282395)
--- trunk/Source/WebCore/bindings/js/InternalWritableStream.cpp 2021-09-14 16:48:34 UTC (rev 282394)
+++ trunk/Source/WebCore/bindings/js/InternalWritableStream.cpp 2021-09-14 17:02:08 UTC (rev 282395)
@@ -50,10 +50,10 @@
return result;
}
-ExceptionOr<Ref<InternalWritableStream>> InternalWritableStream::create(JSDOMGlobalObject& globalObject, JSC::JSValue underlyingSink, JSC::JSValue strategy)
+ExceptionOr<Ref<InternalWritableStream>> InternalWritableStream::createFromUnderlyingSink(JSDOMGlobalObject& globalObject, JSC::JSValue underlyingSink, JSC::JSValue strategy)
{
auto* clientData = static_cast<JSVMClientData*>(globalObject.vm().clientData);
- auto& privateName = clientData->builtinFunctions().writableStreamInternalsBuiltins().createInternalWritableStreamPrivateName();
+ auto& privateName = clientData->builtinFunctions().writableStreamInternalsBuiltins().createInternalWritableStreamFromUnderlyingSinkPrivateName();
JSC::MarkedArgumentBuffer arguments;
arguments.append(underlyingSink);
@@ -68,6 +68,11 @@
return adoptRef(*new InternalWritableStream(globalObject, *result.returnValue().toObject(&globalObject)));
}
+Ref<InternalWritableStream> InternalWritableStream::fromObject(JSDOMGlobalObject& globalObject, JSC::JSObject& object)
+{
+ return adoptRef(*new InternalWritableStream(globalObject, object));
+}
+
bool InternalWritableStream::locked() const
{
auto* globalObject = this->globalObject();
Modified: trunk/Source/WebCore/bindings/js/InternalWritableStream.h (282394 => 282395)
--- trunk/Source/WebCore/bindings/js/InternalWritableStream.h 2021-09-14 16:48:34 UTC (rev 282394)
+++ trunk/Source/WebCore/bindings/js/InternalWritableStream.h 2021-09-14 17:02:08 UTC (rev 282395)
@@ -32,7 +32,8 @@
namespace WebCore {
class InternalWritableStream final : public DOMGuarded<JSC::JSObject> {
public:
- static ExceptionOr<Ref<InternalWritableStream>> create(JSDOMGlobalObject&, JSC::JSValue underlyingSink, JSC::JSValue strategy);
+ static ExceptionOr<Ref<InternalWritableStream>> createFromUnderlyingSink(JSDOMGlobalObject&, JSC::JSValue underlyingSink, JSC::JSValue strategy);
+ static Ref<InternalWritableStream> fromObject(JSDOMGlobalObject&, JSC::JSObject&);
operator JSC::JSValue() const { return guarded(); }
Modified: trunk/Source/WebCore/bindings/js/JSDOMGlobalObject.cpp (282394 => 282395)
--- trunk/Source/WebCore/bindings/js/JSDOMGlobalObject.cpp 2021-09-14 16:48:34 UTC (rev 282394)
+++ trunk/Source/WebCore/bindings/js/JSDOMGlobalObject.cpp 2021-09-14 17:02:08 UTC (rev 282395)
@@ -72,6 +72,7 @@
JSC_DECLARE_HOST_FUNCTION(makeGetterTypeErrorForBuiltins);
JSC_DECLARE_HOST_FUNCTION(makeDOMExceptionForBuiltins);
JSC_DECLARE_HOST_FUNCTION(isReadableByteStreamAPIEnabled);
+JSC_DECLARE_HOST_FUNCTION(createWritableStreamFromInternal);
JSC_DECLARE_HOST_FUNCTION(getInternalWritableStream);
JSC_DECLARE_HOST_FUNCTION(whenSignalAborted);
JSC_DECLARE_HOST_FUNCTION(isAbortSignal);
@@ -171,6 +172,17 @@
return JSValue::encode(writableStream->wrapped().internalWritableStream());
}
+JSC_DEFINE_HOST_FUNCTION(createWritableStreamFromInternal, (JSGlobalObject* globalObject, CallFrame* callFrame))
+{
+ ASSERT(callFrame);
+ ASSERT(callFrame->argumentCount() == 1);
+ ASSERT(callFrame->uncheckedArgument(0).isObject());
+
+ auto* jsDOMGlobalObject = JSC::jsCast<JSDOMGlobalObject*>(globalObject);
+ auto internalWritableStream = InternalWritableStream::fromObject(*jsDOMGlobalObject, *callFrame->uncheckedArgument(0).toObject(globalObject));
+ return JSValue::encode(toJSNewlyCreated(globalObject, jsDOMGlobalObject, WritableStream::create(WTFMove(internalWritableStream))));
+}
+
JSC_DEFINE_HOST_FUNCTION(whenSignalAborted, (JSGlobalObject* globalObject, CallFrame* callFrame))
{
ASSERT(callFrame);
@@ -222,6 +234,7 @@
JSDOMGlobalObject::GlobalPropertyInfo(clientData.builtinNames().readableByteStreamAPIEnabledPrivateName(), JSFunction::create(vm, this, 0, String(), isReadableByteStreamAPIEnabled), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
JSDOMGlobalObject::GlobalPropertyInfo(clientData.builtinNames().isAbortSignalPrivateName(), JSFunction::create(vm, this, 1, String(), isAbortSignal), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
JSDOMGlobalObject::GlobalPropertyInfo(clientData.builtinNames().getInternalWritableStreamPrivateName(), JSFunction::create(vm, this, 1, String(), getInternalWritableStream), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
+ JSDOMGlobalObject::GlobalPropertyInfo(clientData.builtinNames().createWritableStreamFromInternalPrivateName(), JSFunction::create(vm, this, 1, String(), createWritableStreamFromInternal), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
};
addStaticGlobals(staticGlobals, WTF_ARRAY_LENGTH(staticGlobals));
}
Modified: trunk/Source/WebCore/bindings/js/WebCoreBuiltinNames.h (282394 => 282395)
--- trunk/Source/WebCore/bindings/js/WebCoreBuiltinNames.h 2021-09-14 16:48:34 UTC (rev 282394)
+++ trunk/Source/WebCore/bindings/js/WebCoreBuiltinNames.h 2021-09-14 17:02:08 UTC (rev 282395)
@@ -342,6 +342,7 @@
macro(controller) \
macro(createImageBitmap) \
macro(createReadableStream) \
+ macro(createWritableStreamFromInternal) \
macro(crossOriginIsolated) \
macro(customElements) \
macro(decode) \