diff --git a/js/src/builtin/Stream.cpp b/js/src/builtin/Stream.cpp index 188ba694392f..55a539f63b66 100644 --- a/js/src/builtin/Stream.cpp +++ b/js/src/builtin/Stream.cpp @@ -4361,3 +4361,370 @@ js::UnwrapReadableStream(JSObject* obj) } return nullptr; } + +extern JS_PUBLIC_API(void) +JS::SetReadableStreamCallbacks(JSContext* cx, + JS::RequestReadableStreamDataCallback dataRequestCallback, + JS::WriteIntoReadRequestBufferCallback writeIntoReadRequestCallback, + JS::CancelReadableStreamCallback cancelCallback, + JS::ReadableStreamClosedCallback closedCallback, + JS::ReadableStreamErroredCallback erroredCallback, + JS::ReadableStreamFinalizeCallback finalizeCallback) +{ + MOZ_ASSERT(dataRequestCallback); + MOZ_ASSERT(writeIntoReadRequestCallback); + MOZ_ASSERT(cancelCallback); + MOZ_ASSERT(closedCallback); + MOZ_ASSERT(erroredCallback); + MOZ_ASSERT(finalizeCallback); + + JSRuntime* rt = cx->runtime(); + + MOZ_ASSERT(!rt->readableStreamDataRequestCallback); + MOZ_ASSERT(!rt->readableStreamWriteIntoReadRequestCallback); + MOZ_ASSERT(!rt->readableStreamCancelCallback); + MOZ_ASSERT(!rt->readableStreamClosedCallback); + MOZ_ASSERT(!rt->readableStreamErroredCallback); + MOZ_ASSERT(!rt->readableStreamFinalizeCallback); + + rt->readableStreamDataRequestCallback = dataRequestCallback; + rt->readableStreamWriteIntoReadRequestCallback = writeIntoReadRequestCallback; + rt->readableStreamCancelCallback = cancelCallback; + rt->readableStreamClosedCallback = closedCallback; + rt->readableStreamErroredCallback = erroredCallback; + rt->readableStreamFinalizeCallback = finalizeCallback; +} + +JS_PUBLIC_API(bool) +JS::HasReadableStreamCallbacks(JSContext* cx) +{ + return cx->runtime()->readableStreamDataRequestCallback; +} + +JS_PUBLIC_API(JSObject*) +JS::NewReadableDefaultStreamObject(JSContext* cx, + JS::HandleObject underlyingSource /* = nullptr */, + JS::HandleFunction size /* = nullptr */, + double highWaterMark /* = 1 */, + JS::HandleObject proto /* = nullptr */) +{ + MOZ_ASSERT(!cx->zone()->isAtomsZone()); + AssertHeapIsIdle(); + CHECK_THREAD(cx); + + RootedObject source(cx, underlyingSource); + if (!source) { + source = NewBuiltinClassInstance(cx); + if (!source) + return nullptr; + } + RootedValue sourceVal(cx, ObjectValue(*source)); + RootedValue sizeVal(cx, size ? ObjectValue(*size) : UndefinedValue()); + RootedValue highWaterMarkVal(cx, NumberValue(highWaterMark)); + return ReadableStream::createDefaultStream(cx, sourceVal, sizeVal, highWaterMarkVal, proto); +} + +JS_PUBLIC_API(JSObject*) +JS::NewReadableExternalSourceStreamObject(JSContext* cx, void* underlyingSource, + uint8_t flags /* = 0 */, + HandleObject proto /* = nullptr */) +{ + MOZ_ASSERT(!cx->zone()->isAtomsZone()); + AssertHeapIsIdle(); + CHECK_THREAD(cx); + MOZ_ASSERT((uintptr_t(underlyingSource) & 1) == 0, + "external underlying source pointers must be aligned"); +#ifdef DEBUG + JSRuntime* rt = cx->runtime(); + MOZ_ASSERT(rt->readableStreamDataRequestCallback); + MOZ_ASSERT(rt->readableStreamWriteIntoReadRequestCallback); + MOZ_ASSERT(rt->readableStreamCancelCallback); + MOZ_ASSERT(rt->readableStreamClosedCallback); + MOZ_ASSERT(rt->readableStreamErroredCallback); + MOZ_ASSERT(rt->readableStreamFinalizeCallback); +#endif // DEBUG + + return ReadableStream::createExternalSourceStream(cx, underlyingSource, flags, proto); +} + +JS_PUBLIC_API(bool) +JS::IsReadableStream(JSObject* obj) +{ + return obj->canUnwrapAs(); +} + +JS_PUBLIC_API(bool) +JS::IsReadableStreamReader(JSObject* obj) +{ + return obj->canUnwrapAs(); +} + +JS_PUBLIC_API(bool) +JS::IsReadableStreamDefaultReader(JSObject* obj) +{ + return obj->canUnwrapAs(); +} + +template +static MOZ_MUST_USE T* +APIToUnwrapped(JSContext* cx, JSObject* obj) +{ + cx->check(obj); + return ToUnwrapped(cx, obj); +} + +JS_PUBLIC_API(bool) +JS::ReadableStreamIsReadable(JSContext* cx, HandleObject streamObj, bool* result) +{ + ReadableStream* stream = APIToUnwrapped(cx, streamObj); + if (!stream) + return false; + + *result = stream->readable(); + return true; +} + +JS_PUBLIC_API(bool) +JS::ReadableStreamIsLocked(JSContext* cx, HandleObject streamObj, bool* result) +{ + ReadableStream* stream = APIToUnwrapped(cx, streamObj); + if (!stream) + return false; + + *result = stream->locked(); + return true; +} + +JS_PUBLIC_API(bool) +JS::ReadableStreamIsDisturbed(JSContext* cx, HandleObject streamObj, bool* result) +{ + ReadableStream* stream = APIToUnwrapped(cx, streamObj); + if (!stream) + return false; + + *result = stream->disturbed(); + return true; +} + +JS_PUBLIC_API(bool) +JS::ReadableStreamGetEmbeddingFlags(JSContext* cx, HandleObject streamObj, uint8_t* flags) +{ + ReadableStream* stream = APIToUnwrapped(cx, streamObj); + if (!stream) + return false; + + *flags = stream->embeddingFlags(); + return true; +} + +JS_PUBLIC_API(JSObject*) +JS::ReadableStreamCancel(JSContext* cx, HandleObject streamObj, HandleValue reason) +{ + AssertHeapIsIdle(); + CHECK_THREAD(cx); + cx->check(reason); + + Rooted stream(cx, APIToUnwrapped(cx, streamObj)); + if (!stream) + return nullptr; + + return ReadableStream::cancel(cx, stream, reason); +} + +JS_PUBLIC_API(bool) +JS::ReadableStreamGetMode(JSContext* cx, HandleObject streamObj, JS::ReadableStreamMode* mode) +{ + ReadableStream* stream = APIToUnwrapped(cx, streamObj); + if (!stream) + return false; + + *mode = stream->mode(); + return true; +} + +JS_PUBLIC_API(JSObject*) +JS::ReadableStreamGetReader(JSContext* cx, HandleObject streamObj, ReadableStreamReaderMode mode) +{ + AssertHeapIsIdle(); + CHECK_THREAD(cx); + + Rooted stream(cx, APIToUnwrapped(cx, streamObj)); + if (!stream) + return nullptr; + + JSObject* result = ReadableStream::getReader(cx, stream, mode); + MOZ_ASSERT_IF(result, IsObjectInContextCompartment(result, cx)); + return result; +} + +JS_PUBLIC_API(bool) +JS::ReadableStreamGetExternalUnderlyingSource(JSContext* cx, HandleObject streamObj, void** source) +{ + AssertHeapIsIdle(); + CHECK_THREAD(cx); + + Rooted stream(cx, APIToUnwrapped(cx, streamObj)); + if (!stream) + return false; + + return ReadableStream::getExternalSource(cx, stream, source); +} + +JS_PUBLIC_API(bool) +JS::ReadableStreamReleaseExternalUnderlyingSource(JSContext* cx, HandleObject streamObj) +{ + ReadableStream* stream = APIToUnwrapped(cx, streamObj); + if (!stream) + return false; + + stream->releaseExternalSource(); + return true; +} + +JS_PUBLIC_API(bool) +JS::ReadableStreamUpdateDataAvailableFromSource(JSContext* cx, JS::HandleObject streamObj, + uint32_t availableData) +{ + AssertHeapIsIdle(); + CHECK_THREAD(cx); + + Rooted stream(cx, APIToUnwrapped(cx, streamObj)); + if (!stream) + return false; + + return ReadableStream::updateDataAvailableFromSource(cx, stream, availableData); +} + +JS_PUBLIC_API(bool) +JS::ReadableStreamTee(JSContext* cx, HandleObject streamObj, + MutableHandleObject branch1Obj, MutableHandleObject branch2Obj) +{ + AssertHeapIsIdle(); + CHECK_THREAD(cx); + + Rooted stream(cx, APIToUnwrapped(cx, streamObj)); + if (!stream) + return false; + + Rooted branch1Stream(cx); + Rooted branch2Stream(cx); + + if (!ReadableStream::tee(cx, stream, false, &branch1Stream, &branch2Stream)) { + return false; + } + + branch1Obj.set(branch1Stream); + branch2Obj.set(branch2Stream); + + return true; +} + +JS_PUBLIC_API(bool) +JS::ReadableStreamGetDesiredSize(JSContext* cx, JSObject* streamObj, bool* hasValue, double* value) +{ + ReadableStream* stream = APIToUnwrapped(cx, streamObj); + if (!stream) + return false; + + stream->desiredSize(hasValue, value); + return true; +} + +JS_PUBLIC_API(bool) +JS::ReadableStreamClose(JSContext* cx, HandleObject streamObj) +{ + AssertHeapIsIdle(); + CHECK_THREAD(cx); + + Rooted stream(cx, APIToUnwrapped(cx, streamObj)); + if (!stream) + return false; + + return ReadableStream::close(cx, stream); +} + +JS_PUBLIC_API(bool) +JS::ReadableStreamEnqueue(JSContext* cx, HandleObject streamObj, HandleValue chunk) +{ + AssertHeapIsIdle(); + CHECK_THREAD(cx); + cx->check(chunk); + + Rooted stream(cx, APIToUnwrapped(cx, streamObj)); + if (!stream) + return false; + + if (stream->mode() != JS::ReadableStreamMode::Default) { + JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, + JSMSG_READABLESTREAM_NOT_DEFAULT_CONTROLLER, + "JS::ReadableStreamEnqueue"); + return false; + } + return ReadableStream::enqueue(cx, stream, chunk); +} + +JS_PUBLIC_API(bool) +JS::ReadableStreamError(JSContext* cx, HandleObject streamObj, HandleValue error) +{ + AssertHeapIsIdle(); + CHECK_THREAD(cx); + cx->check(error); + + Rooted stream(cx, APIToUnwrapped(cx, streamObj)); + if (!stream) + return false; + + return js::ReadableStream::error(cx, stream, error); +} + +JS_PUBLIC_API(bool) +JS::ReadableStreamReaderIsClosed(JSContext* cx, HandleObject readerObj, bool* result) +{ + Rooted reader(cx, APIToUnwrapped(cx, readerObj)); + if (!reader) + return false; + + *result = reader->isClosed(); + return true; +} + +JS_PUBLIC_API(bool) +JS::ReadableStreamReaderCancel(JSContext* cx, HandleObject readerObj, HandleValue reason) +{ + AssertHeapIsIdle(); + CHECK_THREAD(cx); + cx->check(reason); + + RootedNativeObject reader(cx, APIToUnwrapped(cx, readerObj)); + if (!reader) + return false; + + return js::ReadableStreamReaderCancel(cx, reader, reason); +} + +JS_PUBLIC_API(bool) +JS::ReadableStreamReaderReleaseLock(JSContext* cx, HandleObject readerObj) +{ + AssertHeapIsIdle(); + CHECK_THREAD(cx); + + RootedNativeObject reader(cx, APIToUnwrapped(cx, readerObj)); + if (!reader) + return false; + + return js::ReadableStreamReaderReleaseLock(cx, reader); +} + +JS_PUBLIC_API(JSObject*) +JS::ReadableStreamDefaultReaderRead(JSContext* cx, HandleObject readerObj) +{ + AssertHeapIsIdle(); + CHECK_THREAD(cx); + + Rooted reader(cx); + reader = APIToUnwrapped(cx, readerObj); + if (!reader) + return nullptr; + + return js::ReadableStreamDefaultReader::read(cx, reader); +} diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index fb2c45483b45..48f24d9002a3 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -4628,380 +4628,6 @@ JS::GetWaitForAllPromise(JSContext* cx, const JS::AutoObjectVector& promises) return js::GetWaitForAllPromise(cx, promises); } -extern JS_PUBLIC_API(void) -JS::SetReadableStreamCallbacks(JSContext* cx, - JS::RequestReadableStreamDataCallback dataRequestCallback, - JS::WriteIntoReadRequestBufferCallback writeIntoReadRequestCallback, - JS::CancelReadableStreamCallback cancelCallback, - JS::ReadableStreamClosedCallback closedCallback, - JS::ReadableStreamErroredCallback erroredCallback, - JS::ReadableStreamFinalizeCallback finalizeCallback) -{ - MOZ_ASSERT(dataRequestCallback); - MOZ_ASSERT(writeIntoReadRequestCallback); - MOZ_ASSERT(cancelCallback); - MOZ_ASSERT(closedCallback); - MOZ_ASSERT(erroredCallback); - MOZ_ASSERT(finalizeCallback); - - JSRuntime* rt = cx->runtime(); - - MOZ_ASSERT(!rt->readableStreamDataRequestCallback); - MOZ_ASSERT(!rt->readableStreamWriteIntoReadRequestCallback); - MOZ_ASSERT(!rt->readableStreamCancelCallback); - MOZ_ASSERT(!rt->readableStreamClosedCallback); - MOZ_ASSERT(!rt->readableStreamErroredCallback); - MOZ_ASSERT(!rt->readableStreamFinalizeCallback); - - rt->readableStreamDataRequestCallback = dataRequestCallback; - rt->readableStreamWriteIntoReadRequestCallback = writeIntoReadRequestCallback; - rt->readableStreamCancelCallback = cancelCallback; - rt->readableStreamClosedCallback = closedCallback; - rt->readableStreamErroredCallback = erroredCallback; - rt->readableStreamFinalizeCallback = finalizeCallback; -} - -JS_PUBLIC_API(bool) -JS::HasReadableStreamCallbacks(JSContext* cx) -{ - return cx->runtime()->readableStreamDataRequestCallback; -} - -JS_PUBLIC_API(JSObject*) -JS::NewReadableDefaultStreamObject(JSContext* cx, - JS::HandleObject underlyingSource /* = nullptr */, - JS::HandleFunction size /* = nullptr */, - double highWaterMark /* = 1 */, - JS::HandleObject proto /* = nullptr */) -{ - MOZ_ASSERT(!cx->zone()->isAtomsZone()); - AssertHeapIsIdle(); - CHECK_THREAD(cx); - - RootedObject source(cx, underlyingSource); - if (!source) { - source = NewBuiltinClassInstance(cx); - if (!source) - return nullptr; - } - RootedValue sourceVal(cx, ObjectValue(*source)); - RootedValue sizeVal(cx, size ? ObjectValue(*size) : UndefinedValue()); - RootedValue highWaterMarkVal(cx, NumberValue(highWaterMark)); - return ReadableStream::createDefaultStream(cx, sourceVal, sizeVal, highWaterMarkVal, proto); -} - -JS_PUBLIC_API(JSObject*) -JS::NewReadableExternalSourceStreamObject(JSContext* cx, void* underlyingSource, - uint8_t flags /* = 0 */, - HandleObject proto /* = nullptr */) -{ - MOZ_ASSERT(!cx->zone()->isAtomsZone()); - AssertHeapIsIdle(); - CHECK_THREAD(cx); - MOZ_ASSERT((uintptr_t(underlyingSource) & 1) == 0, - "external underlying source pointers must be aligned"); -#ifdef DEBUG - JSRuntime* rt = cx->runtime(); - MOZ_ASSERT(rt->readableStreamDataRequestCallback); - MOZ_ASSERT(rt->readableStreamWriteIntoReadRequestCallback); - MOZ_ASSERT(rt->readableStreamCancelCallback); - MOZ_ASSERT(rt->readableStreamClosedCallback); - MOZ_ASSERT(rt->readableStreamErroredCallback); - MOZ_ASSERT(rt->readableStreamFinalizeCallback); -#endif // DEBUG - - return ReadableStream::createExternalSourceStream(cx, underlyingSource, flags, proto); -} - -JS_PUBLIC_API(bool) -JS::IsReadableStream(JSObject* obj) -{ - return obj->canUnwrapAs(); -} - -JS_PUBLIC_API(bool) -JS::IsReadableStreamReader(JSObject* obj) -{ - return obj->canUnwrapAs(); -} - -JS_PUBLIC_API(bool) -JS::IsReadableStreamDefaultReader(JSObject* obj) -{ - return obj->canUnwrapAs(); -} - -template -static MOZ_MUST_USE T* -ToUnwrapped(JSContext* cx, JSObject* obj) -{ - cx->check(obj); - if (IsWrapper(obj)) { - obj = CheckedUnwrap(obj); - if (!obj) { - ReportAccessDenied(cx); - return nullptr; - } - } - return &obj->as(); -} - -JS_PUBLIC_API(bool) -JS::ReadableStreamIsReadable(JSContext* cx, HandleObject streamObj, bool* result) -{ - ReadableStream* stream = ToUnwrapped(cx, streamObj); - if (!stream) - return false; - - *result = stream->readable(); - return true; -} - -JS_PUBLIC_API(bool) -JS::ReadableStreamIsLocked(JSContext* cx, HandleObject streamObj, bool* result) -{ - ReadableStream* stream = ToUnwrapped(cx, streamObj); - if (!stream) - return false; - - *result = stream->locked(); - return true; -} - -JS_PUBLIC_API(bool) -JS::ReadableStreamIsDisturbed(JSContext* cx, HandleObject streamObj, bool* result) -{ - ReadableStream* stream = ToUnwrapped(cx, streamObj); - if (!stream) - return false; - - *result = stream->disturbed(); - return true; -} - -JS_PUBLIC_API(bool) -JS::ReadableStreamGetEmbeddingFlags(JSContext* cx, HandleObject streamObj, uint8_t* flags) -{ - ReadableStream* stream = ToUnwrapped(cx, streamObj); - if (!stream) - return false; - - *flags = stream->embeddingFlags(); - return true; -} - -JS_PUBLIC_API(JSObject*) -JS::ReadableStreamCancel(JSContext* cx, HandleObject streamObj, HandleValue reason) -{ - AssertHeapIsIdle(); - CHECK_THREAD(cx); - cx->check(reason); - - Rooted stream(cx, ToUnwrapped(cx, streamObj)); - if (!stream) - return nullptr; - - return ReadableStream::cancel(cx, stream, reason); -} - -JS_PUBLIC_API(bool) -JS::ReadableStreamGetMode(JSContext* cx, HandleObject streamObj, JS::ReadableStreamMode* mode) -{ - ReadableStream* stream = ToUnwrapped(cx, streamObj); - if (!stream) - return false; - - *mode = stream->mode(); - return true; -} - -JS_PUBLIC_API(JSObject*) -JS::ReadableStreamGetReader(JSContext* cx, HandleObject streamObj, ReadableStreamReaderMode mode) -{ - AssertHeapIsIdle(); - CHECK_THREAD(cx); - - Rooted stream(cx, ToUnwrapped(cx, streamObj)); - if (!stream) - return nullptr; - - JSObject* result = ReadableStream::getReader(cx, stream, mode); - MOZ_ASSERT_IF(result, IsObjectInContextCompartment(result, cx)); - return result; -} - -JS_PUBLIC_API(bool) -JS::ReadableStreamGetExternalUnderlyingSource(JSContext* cx, HandleObject streamObj, void** source) -{ - AssertHeapIsIdle(); - CHECK_THREAD(cx); - - Rooted stream(cx, ToUnwrapped(cx, streamObj)); - if (!stream) - return false; - - return ReadableStream::getExternalSource(cx, stream, source); -} - -JS_PUBLIC_API(bool) -JS::ReadableStreamReleaseExternalUnderlyingSource(JSContext* cx, HandleObject streamObj) -{ - ReadableStream* stream = ToUnwrapped(cx, streamObj); - if (!stream) - return false; - - stream->releaseExternalSource(); - return true; -} - -JS_PUBLIC_API(bool) -JS::ReadableStreamUpdateDataAvailableFromSource(JSContext* cx, JS::HandleObject streamObj, - uint32_t availableData) -{ - AssertHeapIsIdle(); - CHECK_THREAD(cx); - - Rooted stream(cx, ToUnwrapped(cx, streamObj)); - if (!stream) - return false; - - return ReadableStream::updateDataAvailableFromSource(cx, stream, availableData); -} - -JS_PUBLIC_API(bool) -JS::ReadableStreamTee(JSContext* cx, HandleObject streamObj, - MutableHandleObject branch1Obj, MutableHandleObject branch2Obj) -{ - AssertHeapIsIdle(); - CHECK_THREAD(cx); - - Rooted stream(cx, ToUnwrapped(cx, streamObj)); - if (!stream) - return false; - - Rooted branch1Stream(cx); - Rooted branch2Stream(cx); - - if (!ReadableStream::tee(cx, stream, false, &branch1Stream, &branch2Stream)) { - return false; - } - - branch1Obj.set(branch1Stream); - branch2Obj.set(branch2Stream); - - return true; -} - -JS_PUBLIC_API(bool) -JS::ReadableStreamGetDesiredSize(JSContext* cx, JSObject* streamObj, bool* hasValue, double* value) -{ - ReadableStream* stream = ToUnwrapped(cx, streamObj); - if (!stream) - return false; - - stream->desiredSize(hasValue, value); - return true; -} - -JS_PUBLIC_API(bool) -JS::ReadableStreamClose(JSContext* cx, HandleObject streamObj) -{ - AssertHeapIsIdle(); - CHECK_THREAD(cx); - - Rooted stream(cx, ToUnwrapped(cx, streamObj)); - if (!stream) - return false; - - return ReadableStream::close(cx, stream); -} - -JS_PUBLIC_API(bool) -JS::ReadableStreamEnqueue(JSContext* cx, HandleObject streamObj, HandleValue chunk) -{ - AssertHeapIsIdle(); - CHECK_THREAD(cx); - cx->check(chunk); - - Rooted stream(cx, ToUnwrapped(cx, streamObj)); - if (!stream) - return false; - - if (stream->mode() != JS::ReadableStreamMode::Default) { - JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, - JSMSG_READABLESTREAM_NOT_DEFAULT_CONTROLLER, - "JS::ReadableStreamEnqueue"); - return false; - } - return ReadableStream::enqueue(cx, stream, chunk); -} - -JS_PUBLIC_API(bool) -JS::ReadableStreamError(JSContext* cx, HandleObject streamObj, HandleValue error) -{ - AssertHeapIsIdle(); - CHECK_THREAD(cx); - cx->check(error); - - Rooted stream(cx, ToUnwrapped(cx, streamObj)); - if (!stream) - return false; - - return js::ReadableStream::error(cx, stream, error); -} - -JS_PUBLIC_API(bool) -JS::ReadableStreamReaderIsClosed(JSContext* cx, HandleObject readerObj, bool* result) -{ - Rooted reader(cx, ToUnwrapped(cx, readerObj)); - if (!reader) - return false; - - *result = reader->isClosed(); - return true; -} - -JS_PUBLIC_API(bool) -JS::ReadableStreamReaderCancel(JSContext* cx, HandleObject readerObj, HandleValue reason) -{ - AssertHeapIsIdle(); - CHECK_THREAD(cx); - cx->check(reason); - - RootedNativeObject reader(cx, ToUnwrapped(cx, readerObj)); - if (!reader) - return false; - - return js::ReadableStreamReaderCancel(cx, reader, reason); -} - -JS_PUBLIC_API(bool) -JS::ReadableStreamReaderReleaseLock(JSContext* cx, HandleObject readerObj) -{ - AssertHeapIsIdle(); - CHECK_THREAD(cx); - - RootedNativeObject reader(cx, ToUnwrapped(cx, readerObj)); - if (!reader) - return false; - - return js::ReadableStreamReaderReleaseLock(cx, reader); -} - -JS_PUBLIC_API(JSObject*) -JS::ReadableStreamDefaultReaderRead(JSContext* cx, HandleObject readerObj) -{ - AssertHeapIsIdle(); - CHECK_THREAD(cx); - - Rooted reader(cx); - reader = ToUnwrapped(cx, readerObj); - if (!reader) - return nullptr; - - return js::ReadableStreamDefaultReader::read(cx, reader); -} - JS_PUBLIC_API(void) JS::InitDispatchToEventLoop(JSContext* cx, JS::DispatchToEventLoopCallback callback, void* closure) {