Skip to content

Commit

Permalink
Add WritableStreamDefaultController signal getter
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=248600
rdar://problem/102858374

Reviewed by Alex Christensen.

Add signal as attribute and signal it as aborted when stream gets aborted.
Add necessary built-in globals to interact with AbortSignal.
Covered by rebased tests.

* LayoutTests/imported/w3c/web-platform-tests/streams/idlharness.any-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/streams/idlharness.any.serviceworker-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/streams/idlharness.any.worker-expected.txt:
* Source/WebCore/Modules/streams/WritableStreamDefaultController.idl:
* Source/WebCore/Modules/streams/WritableStreamDefaultController.js:
(getter.signal):
* Source/WebCore/Modules/streams/WritableStreamInternals.js:
(writableStreamAbort):
(setUpWritableStreamDefaultController):
* Source/WebCore/bindings/js/JSDOMGlobalObject.cpp:
(WebCore::JSC_DEFINE_HOST_FUNCTION):
(WebCore::JSDOMGlobalObject::addBuiltinGlobals):
* Source/WebCore/bindings/js/WebCoreBuiltinNames.h:

Canonical link: https://commits.webkit.org/257397@main
  • Loading branch information
youennf committed Dec 6, 2022
1 parent d401652 commit 5815663
Show file tree
Hide file tree
Showing 8 changed files with 48 additions and 8 deletions.
Expand Up @@ -168,11 +168,11 @@ PASS WritableStreamDefaultController interface object name
PASS WritableStreamDefaultController interface: existence and properties of interface prototype object
PASS WritableStreamDefaultController interface: existence and properties of interface prototype object's "constructor" property
PASS WritableStreamDefaultController interface: existence and properties of interface prototype object's @@unscopables property
FAIL WritableStreamDefaultController interface: attribute signal assert_true: The prototype object must have a property "signal" expected true got false
PASS WritableStreamDefaultController interface: attribute signal
FAIL WritableStreamDefaultController interface: operation error(optional any) assert_equals: property has wrong .length expected 0 but got 1
PASS WritableStreamDefaultController must be primary interface of self.writableStreamDefaultController
PASS Stringification of self.writableStreamDefaultController
FAIL WritableStreamDefaultController interface: self.writableStreamDefaultController must inherit property "signal" with the proper type assert_inherits: property "signal" not found in prototype chain
PASS WritableStreamDefaultController interface: self.writableStreamDefaultController must inherit property "signal" with the proper type
PASS WritableStreamDefaultController interface: self.writableStreamDefaultController must inherit property "error(optional any)" with the proper type
PASS WritableStreamDefaultController interface: calling error(optional any) on self.writableStreamDefaultController with too few arguments must throw TypeError
PASS TransformStream interface: existence and properties of interface object
Expand Down
Expand Up @@ -168,11 +168,11 @@ PASS WritableStreamDefaultController interface object name
PASS WritableStreamDefaultController interface: existence and properties of interface prototype object
PASS WritableStreamDefaultController interface: existence and properties of interface prototype object's "constructor" property
PASS WritableStreamDefaultController interface: existence and properties of interface prototype object's @@unscopables property
FAIL WritableStreamDefaultController interface: attribute signal assert_true: The prototype object must have a property "signal" expected true got false
PASS WritableStreamDefaultController interface: attribute signal
FAIL WritableStreamDefaultController interface: operation error(optional any) assert_equals: property has wrong .length expected 0 but got 1
PASS WritableStreamDefaultController must be primary interface of self.writableStreamDefaultController
PASS Stringification of self.writableStreamDefaultController
FAIL WritableStreamDefaultController interface: self.writableStreamDefaultController must inherit property "signal" with the proper type assert_inherits: property "signal" not found in prototype chain
PASS WritableStreamDefaultController interface: self.writableStreamDefaultController must inherit property "signal" with the proper type
PASS WritableStreamDefaultController interface: self.writableStreamDefaultController must inherit property "error(optional any)" with the proper type
PASS WritableStreamDefaultController interface: calling error(optional any) on self.writableStreamDefaultController with too few arguments must throw TypeError
PASS TransformStream interface: existence and properties of interface object
Expand Down
Expand Up @@ -168,11 +168,11 @@ PASS WritableStreamDefaultController interface object name
PASS WritableStreamDefaultController interface: existence and properties of interface prototype object
PASS WritableStreamDefaultController interface: existence and properties of interface prototype object's "constructor" property
PASS WritableStreamDefaultController interface: existence and properties of interface prototype object's @@unscopables property
FAIL WritableStreamDefaultController interface: attribute signal assert_true: The prototype object must have a property "signal" expected true got false
PASS WritableStreamDefaultController interface: attribute signal
FAIL WritableStreamDefaultController interface: operation error(optional any) assert_equals: property has wrong .length expected 0 but got 1
PASS WritableStreamDefaultController must be primary interface of self.writableStreamDefaultController
PASS Stringification of self.writableStreamDefaultController
FAIL WritableStreamDefaultController interface: self.writableStreamDefaultController must inherit property "signal" with the proper type assert_inherits: property "signal" not found in prototype chain
PASS WritableStreamDefaultController interface: self.writableStreamDefaultController must inherit property "signal" with the proper type
PASS WritableStreamDefaultController interface: self.writableStreamDefaultController must inherit property "error(optional any)" with the proper type
PASS WritableStreamDefaultController interface: calling error(optional any) on self.writableStreamDefaultController with too few arguments must throw TypeError
PASS TransformStream interface: existence and properties of interface object
Expand Down
Expand Up @@ -29,7 +29,6 @@
PrivateIdentifier,
PublicIdentifier
] interface WritableStreamDefaultController {
constructor();

readonly attribute AbortSignal signal;
undefined error(optional any e);
};
11 changes: 11 additions & 0 deletions Source/WebCore/Modules/streams/WritableStreamDefaultController.js
Expand Up @@ -45,6 +45,17 @@ function initializeWritableStreamDefaultController()
return this;
}

@getter
function signal()
{
"use strict";

if (@getByIdDirectPrivate(this, "abortSteps") === @undefined)
throw @makeThisTypeError("WritableStreamDefaultController", "signal");

return @getByIdDirectPrivate(this, "signal");
}

function error(e)
{
"use strict";
Expand Down
4 changes: 4 additions & 0 deletions Source/WebCore/Modules/streams/WritableStreamInternals.js
Expand Up @@ -186,6 +186,9 @@ function writableStreamAbort(stream, reason)
if (state === "closed" || state === "errored")
return @Promise.@resolve();

const controller = @getByIdDirectPrivate(stream, "controller");
@signalAbort(@getByIdDirectPrivate(controller, "signal"), reason);

const pendingAbortRequest = @getByIdDirectPrivate(stream, "pendingAbortRequest");
if (pendingAbortRequest !== @undefined)
return pendingAbortRequest.promise.@promise;
Expand Down Expand Up @@ -579,6 +582,7 @@ function setUpWritableStreamDefaultController(stream, controller, startAlgorithm

@resetQueue(@getByIdDirectPrivate(controller, "queue"));

@putByIdDirectPrivate(controller, "signal", @createAbortSignal());
@putByIdDirectPrivate(controller, "started", false);
@putByIdDirectPrivate(controller, "strategySizeAlgorithm", sizeAlgorithm);
@putByIdDirectPrivate(controller, "strategyHWM", highWaterMark);
Expand Down
23 changes: 23 additions & 0 deletions Source/WebCore/bindings/js/JSDOMGlobalObject.cpp
Expand Up @@ -86,7 +86,9 @@ JSC_DECLARE_HOST_FUNCTION(createWritableStreamFromInternal);
JSC_DECLARE_HOST_FUNCTION(getInternalWritableStream);
JSC_DECLARE_HOST_FUNCTION(addAbortAlgorithmToSignal);
JSC_DECLARE_HOST_FUNCTION(removeAbortAlgorithmFromSignal);
JSC_DECLARE_HOST_FUNCTION(signalAbort);
JSC_DECLARE_HOST_FUNCTION(isAbortSignal);
JSC_DECLARE_HOST_FUNCTION(createAbortSignal);

const ClassInfo JSDOMGlobalObject::s_info = { "DOMGlobalObject"_s, &JSGlobalObject::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSDOMGlobalObject) };

Expand Down Expand Up @@ -228,6 +230,23 @@ JSC_DEFINE_HOST_FUNCTION(isAbortSignal, (JSGlobalObject*, CallFrame* callFrame))
return JSValue::encode(jsBoolean(callFrame->uncheckedArgument(0).inherits<JSAbortSignal>()));
}

JSC_DEFINE_HOST_FUNCTION(createAbortSignal, (JSGlobalObject* globalObject, CallFrame*))
{
auto* jsDOMGlobalObject = JSC::jsCast<JSDOMGlobalObject*>(globalObject);
return JSValue::encode(toJS(globalObject, jsDOMGlobalObject, AbortSignal::create(jsDOMGlobalObject->scriptExecutionContext())));
}

JSC_DEFINE_HOST_FUNCTION(signalAbort, (JSGlobalObject*, CallFrame* callFrame))
{
ASSERT(callFrame);
ASSERT(callFrame->argumentCount() == 2);

auto* abortSignal = jsDynamicCast<JSAbortSignal*>(callFrame->uncheckedArgument(0));
if (UNLIKELY(abortSignal))
abortSignal->wrapped().signalAbort(callFrame->uncheckedArgument(1));
return JSValue::encode(JSC::jsUndefined());
}

SUPPRESS_ASAN void JSDOMGlobalObject::addBuiltinGlobals(VM& vm)
{
m_builtinInternalFunctions.initialize(*this);
Expand All @@ -244,6 +263,10 @@ SUPPRESS_ASAN void JSDOMGlobalObject::addBuiltinGlobals(VM& vm)
JSFunction::create(vm, this, 2, String(), addAbortAlgorithmToSignal, ImplementationVisibility::Public), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
JSDOMGlobalObject::GlobalPropertyInfo(builtinNames.removeAbortAlgorithmFromSignalPrivateName(),
JSFunction::create(vm, this, 2, String(), removeAbortAlgorithmFromSignal, ImplementationVisibility::Public), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
JSDOMGlobalObject::GlobalPropertyInfo(builtinNames.signalAbortPrivateName(),
JSFunction::create(vm, this, 2, String(), signalAbort, ImplementationVisibility::Public), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
JSDOMGlobalObject::GlobalPropertyInfo(builtinNames.createAbortSignalPrivateName(),
JSFunction::create(vm, this, 0, String(), createAbortSignal, ImplementationVisibility::Public), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
JSDOMGlobalObject::GlobalPropertyInfo(builtinNames.cloneArrayBufferPrivateName(),
JSFunction::create(vm, this, 3, String(), cloneArrayBuffer, ImplementationVisibility::Public), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
JSDOMGlobalObject::GlobalPropertyInfo(builtinNames.structuredCloneForStreamPrivateName(),
Expand Down
3 changes: 3 additions & 0 deletions Source/WebCore/bindings/js/WebCoreBuiltinNames.h
Expand Up @@ -493,6 +493,7 @@ namespace WebCore {
macro(consumeChunk) \
macro(controlledReadableStream) \
macro(controller) \
macro(createAbortSignal) \
macro(createImageBitmap) \
macro(createReadableStream) \
macro(createWritableStreamFromInternal) \
Expand Down Expand Up @@ -600,6 +601,8 @@ namespace WebCore {
macro(setBodyFromInputRequest) \
macro(setStatus) \
macro(showModalDialog) \
macro(signal) \
macro(signalAbort) \
macro(SpeechSynthesis) \
macro(SpeechSynthesisErrorEvent) \
macro(SpeechSynthesisEvent) \
Expand Down

0 comments on commit 5815663

Please sign in to comment.