Title: [264967] trunk
Revision
264967
Author
you...@apple.com
Date
2020-07-28 01:01:34 -0700 (Tue, 28 Jul 2020)

Log Message

ReadableStreamDefaultController should use private JS built-in methods
https://bugs.webkit.org/show_bug.cgi?id=214819

Reviewed by Darin Adler.

Source/WebCore:

Call directly private buitl-in methods instead of getting close/error/enqueue methods from the controller.
Test: http/wpt/fetch/readableStreamDefaultController-overwriting.html

* bindings/js/ReadableStreamDefaultController.cpp:
(WebCore::invokeReadableStreamDefaultControllerFunction):
(WebCore::ReadableStreamDefaultController::close):
(WebCore::ReadableStreamDefaultController::error):
(WebCore::ReadableStreamDefaultController::enqueue):
* bindings/js/ReadableStreamDefaultController.h:
(WebCore::ReadableStreamDefaultController::enqueue):
(WebCore::ReadableStreamDefaultController::error):

LayoutTests:

* http/wpt/fetch/readableStreamDefaultController-overwriting-expected.txt: Added.
* http/wpt/fetch/readableStreamDefaultController-overwriting.html: Added.
* http/wpt/fetch/resources/lengthy-pass.py: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (264966 => 264967)


--- trunk/LayoutTests/ChangeLog	2020-07-28 08:01:20 UTC (rev 264966)
+++ trunk/LayoutTests/ChangeLog	2020-07-28 08:01:34 UTC (rev 264967)
@@ -1,3 +1,14 @@
+2020-07-28  Youenn Fablet  <you...@apple.com>
+
+        ReadableStreamDefaultController should use private JS built-in methods
+        https://bugs.webkit.org/show_bug.cgi?id=214819
+
+        Reviewed by Darin Adler.
+
+        * http/wpt/fetch/readableStreamDefaultController-overwriting-expected.txt: Added.
+        * http/wpt/fetch/readableStreamDefaultController-overwriting.html: Added.
+        * http/wpt/fetch/resources/lengthy-pass.py: Added.
+
 2020-07-27  Carlos Garcia Campos  <cgar...@igalia.com>
 
         REGRESSION(r230479): [TextureMapper] replica layer is not rendered

Added: trunk/LayoutTests/http/wpt/fetch/readableStreamDefaultController-overwriting-expected.txt (0 => 264967)


--- trunk/LayoutTests/http/wpt/fetch/readableStreamDefaultController-overwriting-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/wpt/fetch/readableStreamDefaultController-overwriting-expected.txt	2020-07-28 08:01:34 UTC (rev 264967)
@@ -0,0 +1,5 @@
+
+PASS Overwrite ReadableStreamDefaultController enqueue 
+PASS Overwrite ReadableStreamDefaultController error 
+PASS Overwrite ReadableStreamDefaultController close 
+

Added: trunk/LayoutTests/http/wpt/fetch/readableStreamDefaultController-overwriting.html (0 => 264967)


--- trunk/LayoutTests/http/wpt/fetch/readableStreamDefaultController-overwriting.html	                        (rev 0)
+++ trunk/LayoutTests/http/wpt/fetch/readableStreamDefaultController-overwriting.html	2020-07-28 08:01:34 UTC (rev 264967)
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<script src=''></script>
+<script src=''></script>
+<script>
+
+var controllerPrototype;
+const rs = new ReadableStream({
+    start: function(c) {
+        controllerPrototype = Object.getPrototypeOf(c);
+    }
+});
+
+async function pumpStream(streamReader)
+{
+    const chunk = await streamReader.read();
+    if (!chunk.done)
+        return pumpStream(streamReader);
+}
+
+promise_test(async t => {
+    const enqueue = controllerPrototype.enqueue;
+    controllerPrototype.enqueue = null;
+    t.add_cleanup(async () => controllerPrototype.enqueue = enqueue);
+
+    const response = await fetch(".");
+    await response.body.getReader().read();
+}, "Overwrite ReadableStreamDefaultController enqueue");
+
+promise_test(async t => {
+    const error = controllerPrototype.error;
+    controllerPrototype.error = null;
+    t.add_cleanup(async () => controllerPrototype.error = error);
+
+    const controller = new AbortController();
+    const signal = controller.signal;
+
+    const response = await fetch('./resources/lengthy-pass.py?delay=1', { signal });
+    const reader = response.body.getReader();
+
+    controller.abort();
+
+    await promise_rejects_dom(t, "AbortError", reader.closed);
+}, "Overwrite ReadableStreamDefaultController error");
+
+promise_test(async t => {
+    const close = controllerPrototype.close;
+    controllerPrototype.close = null;
+    t.add_cleanup(async () => controllerPrototype.close = close);
+
+    const response = await fetch(".");
+    const reader = response.body.getReader();
+    await pumpStream(reader);
+    await reader.closed;
+}, "Overwrite ReadableStreamDefaultController close");
+</script>

Added: trunk/LayoutTests/http/wpt/fetch/resources/lengthy-pass.py (0 => 264967)


--- trunk/LayoutTests/http/wpt/fetch/resources/lengthy-pass.py	                        (rev 0)
+++ trunk/LayoutTests/http/wpt/fetch/resources/lengthy-pass.py	2020-07-28 08:01:34 UTC (rev 264967)
@@ -0,0 +1,19 @@
+import time
+
+def main(request, response):
+    delay = 0.05
+    headers = []
+    if "delay" in request.GET:
+        delay = float(request.GET.first("delay"))
+    response.headers.set("Content-type", "text/_javascript_")
+    response.headers.append("Access-Control-Allow-Origin", "*")
+    response.write_status_headers()
+    time.sleep(delay);
+    response.writer.write_content("document")
+    time.sleep(delay)
+    response.writer.write_content(".body")
+    time.sleep(delay)
+    response.writer.write_content(".innerHTML = ")
+    time.sleep(delay)
+    response.writer.write_content("'PASS'")
+    time.sleep(delay)

Modified: trunk/Source/WebCore/ChangeLog (264966 => 264967)


--- trunk/Source/WebCore/ChangeLog	2020-07-28 08:01:20 UTC (rev 264966)
+++ trunk/Source/WebCore/ChangeLog	2020-07-28 08:01:34 UTC (rev 264967)
@@ -1,3 +1,22 @@
+2020-07-28  Youenn Fablet  <you...@apple.com>
+
+        ReadableStreamDefaultController should use private JS built-in methods
+        https://bugs.webkit.org/show_bug.cgi?id=214819
+
+        Reviewed by Darin Adler.
+
+        Call directly private buitl-in methods instead of getting close/error/enqueue methods from the controller.
+        Test: http/wpt/fetch/readableStreamDefaultController-overwriting.html
+
+        * bindings/js/ReadableStreamDefaultController.cpp:
+        (WebCore::invokeReadableStreamDefaultControllerFunction):
+        (WebCore::ReadableStreamDefaultController::close):
+        (WebCore::ReadableStreamDefaultController::error):
+        (WebCore::ReadableStreamDefaultController::enqueue):
+        * bindings/js/ReadableStreamDefaultController.h:
+        (WebCore::ReadableStreamDefaultController::enqueue):
+        (WebCore::ReadableStreamDefaultController::error):
+
 2020-07-27  Carlos Garcia Campos  <cgar...@igalia.com>
 
         REGRESSION(r230479): [TextureMapper] replica layer is not rendered

Modified: trunk/Source/WebCore/bindings/js/ReadableStreamDefaultController.cpp (264966 => 264967)


--- trunk/Source/WebCore/bindings/js/ReadableStreamDefaultController.cpp	2020-07-28 08:01:20 UTC (rev 264966)
+++ trunk/Source/WebCore/bindings/js/ReadableStreamDefaultController.cpp	2020-07-28 08:01:34 UTC (rev 264967)
@@ -39,32 +39,84 @@
 
 namespace WebCore {
 
-static inline JSC::JSValue readableStreamCallFunction(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue jsFunction, JSC::JSValue thisValue, const JSC::ArgList& arguments)
+static bool invokeReadableStreamDefaultControllerFunction(JSC::JSGlobalObject& lexicalGlobalObject, const Identifier& identifier, const MarkedArgumentBuffer& arguments)
 {
-    auto callData = JSC::getCallData(lexicalGlobalObject.vm(), jsFunction);
-    return call(&lexicalGlobalObject, jsFunction, callData, thisValue, arguments);
+    JSC::VM& vm = lexicalGlobalObject.vm();
+    JSC::JSLockHolder lock(vm);
+
+    auto function = lexicalGlobalObject.get(&lexicalGlobalObject, identifier);
+    ASSERT(function.isCallable(lexicalGlobalObject.vm()));
+
+    auto scope = DECLARE_CATCH_SCOPE(vm);
+    auto callData = JSC::getCallData(vm, function);
+    call(&lexicalGlobalObject, function, callData, JSC::jsUndefined(), arguments);
+    EXCEPTION_ASSERT(!scope.exception() || isTerminatedExecutionException(lexicalGlobalObject.vm(), scope.exception()));
+    return !scope.exception();
 }
 
-JSC::JSValue ReadableStreamDefaultController::invoke(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSObject& object, const char* propertyName, JSC::JSValue parameter)
+void ReadableStreamDefaultController::close()
 {
-    JSC::VM& vm = lexicalGlobalObject.vm();
+    MarkedArgumentBuffer arguments;
+    arguments.append(&jsController());
+
+    auto* clientData = static_cast<JSVMClientData*>(globalObject().vm().clientData);
+    auto& privateName = clientData->builtinFunctions().readableStreamInternalsBuiltins().readableStreamDefaultControllerClosePrivateName();
+
+    invokeReadableStreamDefaultControllerFunction(globalObject(), privateName, arguments);
+}
+
+
+void ReadableStreamDefaultController::error(const Exception& exception)
+{
+    JSC::JSGlobalObject& lexicalGlobalObject = this->globalObject();
+    auto& vm = lexicalGlobalObject.vm();
     JSC::JSLockHolder lock(vm);
-    auto scope = DECLARE_THROW_SCOPE(vm);
+    auto scope = DECLARE_CATCH_SCOPE(vm);
+    auto value = createDOMException(&lexicalGlobalObject, exception.code(), exception.message());
 
-    auto function = object.get(&lexicalGlobalObject, JSC::Identifier::fromString(vm, propertyName));
-    RETURN_IF_EXCEPTION(scope, JSC::JSValue());
+    if (UNLIKELY(scope.exception())) {
+        ASSERT(isTerminatedExecutionException(lexicalGlobalObject.vm(), scope.exception()));
+        return;
+    }
 
-    if (!function.isCallable(vm)) {
-        if (!function.isUndefined())
-            throwTypeError(&lexicalGlobalObject, scope, "ReadableStream trying to call a property that is not callable"_s);
-        return JSC::jsUndefined();
+    MarkedArgumentBuffer arguments;
+    arguments.append(&jsController());
+    arguments.append(value);
+
+    auto* clientData = static_cast<JSVMClientData*>(lexicalGlobalObject.vm().clientData);
+    auto& privateName = clientData->builtinFunctions().readableStreamInternalsBuiltins().readableStreamDefaultControllerErrorPrivateName();
+
+    invokeReadableStreamDefaultControllerFunction(globalObject(), privateName, arguments);
+}
+
+bool ReadableStreamDefaultController::enqueue(RefPtr<JSC::ArrayBuffer>&& buffer)
+{
+    if (!buffer) {
+        error(Exception { OutOfMemoryError });
+        return false;
     }
 
-    JSC::MarkedArgumentBuffer arguments;
-    arguments.append(parameter);
-    ASSERT(!arguments.hasOverflowed());
+    JSC::JSGlobalObject& lexicalGlobalObject = this->globalObject();
+    auto& vm = lexicalGlobalObject.vm();
+    JSC::JSLockHolder lock(vm);
+    auto scope = DECLARE_CATCH_SCOPE(vm);
+    auto length = buffer->byteLength();
+    auto chunk = JSC::Uint8Array::create(WTFMove(buffer), 0, length);
+    auto value = toJS(&lexicalGlobalObject, &lexicalGlobalObject, chunk.get());
 
-    return readableStreamCallFunction(lexicalGlobalObject, function, &object, arguments);
+    if (UNLIKELY(scope.exception())) {
+        ASSERT(isTerminatedExecutionException(lexicalGlobalObject.vm(), scope.exception()));
+        return false;
+    }
+
+    MarkedArgumentBuffer arguments;
+    arguments.append(&jsController());
+    arguments.append(value);
+
+    auto* clientData = static_cast<JSVMClientData*>(lexicalGlobalObject.vm().clientData);
+    auto& privateName = clientData->builtinFunctions().readableStreamInternalsBuiltins().readableStreamDefaultControllerEnqueuePrivateName();
+
+    return invokeReadableStreamDefaultControllerFunction(globalObject(), privateName, arguments);
 }
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/bindings/js/ReadableStreamDefaultController.h (264966 => 264967)


--- trunk/Source/WebCore/bindings/js/ReadableStreamDefaultController.h	2020-07-28 08:01:20 UTC (rev 264966)
+++ trunk/Source/WebCore/bindings/js/ReadableStreamDefaultController.h	2020-07-28 08:01:34 UTC (rev 264967)
@@ -43,17 +43,11 @@
 public:
     explicit ReadableStreamDefaultController(JSReadableStreamDefaultController* controller) : m_jsController(controller) { }
 
-    static JSC::JSValue invoke(JSC::JSGlobalObject&, JSC::JSObject&, const char*, JSC::JSValue);
-
     bool enqueue(RefPtr<JSC::ArrayBuffer>&&);
-
     void error(const Exception&);
+    void close();
 
-    void close() { invoke(globalObject(), jsController(), "close", JSC::jsUndefined()); }
-
 private:
-    void error(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) { invoke(lexicalGlobalObject, jsController(), "error", value); }
-    void enqueue(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value) { invoke(lexicalGlobalObject, jsController(), "enqueue", value); }
     JSReadableStreamDefaultController& jsController() const;
 
     JSDOMGlobalObject& globalObject() const;
@@ -75,35 +69,4 @@
     return *static_cast<JSDOMGlobalObject*>(m_jsController->globalObject());
 }
 
-inline bool ReadableStreamDefaultController::enqueue(RefPtr<JSC::ArrayBuffer>&& buffer)
-{
-    auto& globalObject = this->globalObject();
-    JSC::VM& vm = globalObject.vm();
-    JSC::JSLockHolder locker(vm);
-    auto scope = DECLARE_THROW_SCOPE(vm);
-    JSC::JSGlobalObject& lexicalGlobalObject = globalObject;
-
-    if (!buffer) {
-        error(lexicalGlobalObject, createOutOfMemoryError(&lexicalGlobalObject));
-        return false;
-    }
-    auto length = buffer->byteLength();
-    auto chunk = JSC::Uint8Array::create(WTFMove(buffer), 0, length);
-    enqueue(lexicalGlobalObject, toJS(&lexicalGlobalObject, &globalObject, chunk.ptr()));
-
-    if (UNLIKELY(scope.exception())) {
-        ASSERT(isTerminatedExecutionException(lexicalGlobalObject.vm(), scope.exception()));
-        return false;
-    }
-
-    return true;
-}
-
-inline void ReadableStreamDefaultController::error(const Exception& exception)
-{
-    JSC::JSGlobalObject& lexicalGlobalObject = globalObject();
-    JSC::JSLockHolder locker(&lexicalGlobalObject);
-    error(lexicalGlobalObject, createDOMException(&lexicalGlobalObject, exception.code(), exception.message()));
-}
-
 } // namespace WebCore
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to