mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-08 00:38:39 +09:00
Fix stream cross-realm globals
This commit is contained in:
parent
29056ef112
commit
8c6e09601c
1 changed files with 283 additions and 178 deletions
|
|
@ -101,14 +101,72 @@ Is(const HandleValue v)
|
|||
return v.isObject() && v.toObject().is<T>();
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
template<class T>
|
||||
MOZ_ALWAYS_INLINE bool
|
||||
IsMaybeWrapped(const HandleValue v)
|
||||
{
|
||||
if (!v.isObject())
|
||||
return false;
|
||||
|
||||
JSObject* obj = &v.toObject();
|
||||
if (obj->is<T>())
|
||||
return true;
|
||||
|
||||
JSObject* unwrapped = CheckedUnwrap(obj);
|
||||
return unwrapped && unwrapped->is<T>();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
MOZ_ALWAYS_INLINE T*
|
||||
UnwrapInternalSlotObject(JSObject* obj)
|
||||
{
|
||||
JSObject* unwrapped = UncheckedUnwrap(obj);
|
||||
MOZ_ASSERT(unwrapped);
|
||||
MOZ_ASSERT(unwrapped->is<T>());
|
||||
return &unwrapped->as<T>();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
MOZ_ALWAYS_INLINE T*
|
||||
UnwrapMaybeWrappedArg(const HandleValue v)
|
||||
{
|
||||
if (!v.isObject())
|
||||
return nullptr;
|
||||
|
||||
JSObject* obj = &v.toObject();
|
||||
if (obj->is<T>())
|
||||
return &obj->as<T>();
|
||||
|
||||
JSObject* unwrapped = CheckedUnwrap(obj);
|
||||
if (!unwrapped || !unwrapped->is<T>())
|
||||
return nullptr;
|
||||
|
||||
return &unwrapped->as<T>();
|
||||
}
|
||||
|
||||
static bool
|
||||
IsReadableStreamController(const JSObject* controller)
|
||||
{
|
||||
return controller->is<ReadableStreamDefaultController>() ||
|
||||
controller->is<ReadableByteStreamController>();
|
||||
}
|
||||
#endif // DEBUG
|
||||
|
||||
[[nodiscard]] static NativeObject*
|
||||
UnwrapMaybeWrappedReadableStreamController(const HandleValue v)
|
||||
{
|
||||
if (!v.isObject())
|
||||
return nullptr;
|
||||
|
||||
JSObject* obj = &v.toObject();
|
||||
if (IsReadableStreamController(obj))
|
||||
return &obj->as<NativeObject>();
|
||||
|
||||
JSObject* unwrapped = CheckedUnwrap(obj);
|
||||
if (!unwrapped || !IsReadableStreamController(unwrapped))
|
||||
return nullptr;
|
||||
|
||||
return &unwrapped->as<NativeObject>();
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
ControllerFlags(const NativeObject* controller)
|
||||
|
|
@ -188,7 +246,8 @@ inline static MOZ_MUST_USE ReadableStream*
|
|||
StreamFromController(const NativeObject* controller)
|
||||
{
|
||||
MOZ_ASSERT(IsReadableStreamController(controller));
|
||||
return &controller->getFixedSlot(ControllerSlot_Stream).toObject().as<ReadableStream>();
|
||||
return UnwrapInternalSlotObject<ReadableStream>(
|
||||
&controller->getFixedSlot(ControllerSlot_Stream).toObject());
|
||||
}
|
||||
|
||||
inline static MOZ_MUST_USE NativeObject*
|
||||
|
|
@ -220,15 +279,17 @@ inline static MOZ_MUST_USE ReadableStream*
|
|||
StreamFromReader(const NativeObject* reader)
|
||||
{
|
||||
MOZ_ASSERT(ReaderHasStream(reader));
|
||||
return &reader->getFixedSlot(ReaderSlot_Stream).toObject().as<ReadableStream>();
|
||||
return UnwrapInternalSlotObject<ReadableStream>(
|
||||
&reader->getFixedSlot(ReaderSlot_Stream).toObject());
|
||||
}
|
||||
|
||||
inline static MOZ_MUST_USE NativeObject*
|
||||
ReaderFromStream(const NativeObject* stream)
|
||||
{
|
||||
Value readerVal = stream->getFixedSlot(StreamSlot_Reader);
|
||||
MOZ_ASSERT(JS::IsReadableStreamReader(&readerVal.toObject()));
|
||||
return &readerVal.toObject().as<NativeObject>();
|
||||
NativeObject* reader = UnwrapInternalSlotObject<NativeObject>(&readerVal.toObject());
|
||||
MOZ_ASSERT(JS::IsReadableStreamReader(reader));
|
||||
return reader;
|
||||
}
|
||||
|
||||
inline static bool
|
||||
|
|
@ -310,26 +371,55 @@ RejectNonGenericMethod(JSContext* cx, const CallArgs& args,
|
|||
return ReturnPromiseRejectedWithPendingError(cx, args);
|
||||
}
|
||||
|
||||
inline static MOZ_MUST_USE NativeObject*
|
||||
[[nodiscard]] static bool
|
||||
ResolveMaybeWrappedPromise(JSContext* cx, HandleObject promise, HandleValue value)
|
||||
{
|
||||
RootedObject wrappedPromise(cx, promise);
|
||||
RootedValue wrappedValue(cx, value);
|
||||
if (!JS_WrapObject(cx, &wrappedPromise) || !JS_WrapValue(cx, &wrappedValue))
|
||||
return false;
|
||||
return ResolvePromise(cx, wrappedPromise, wrappedValue);
|
||||
}
|
||||
|
||||
[[nodiscard]] static bool
|
||||
RejectMaybeWrappedPromise(JSContext* cx, HandleObject promise, HandleValue reason)
|
||||
{
|
||||
RootedObject wrappedPromise(cx, promise);
|
||||
RootedValue wrappedReason(cx, reason);
|
||||
if (!JS_WrapObject(cx, &wrappedPromise) || !JS_WrapValue(cx, &wrappedReason))
|
||||
return false;
|
||||
return RejectPromise(cx, wrappedPromise, wrappedReason);
|
||||
}
|
||||
|
||||
[[nodiscard]] inline static NativeObject*
|
||||
SetNewList(JSContext* cx, HandleNativeObject container, uint32_t slot)
|
||||
{
|
||||
NativeObject* list = NewObjectWithNullTaggedProto<PlainObject>(cx);
|
||||
if (!list)
|
||||
return nullptr;
|
||||
container->setFixedSlot(slot, ObjectValue(*list));
|
||||
RootedNativeObject list(cx);
|
||||
{
|
||||
JSAutoCompartment ac(cx, container);
|
||||
list = NewObjectWithNullTaggedProto<PlainObject>(cx);
|
||||
if (!list)
|
||||
return nullptr;
|
||||
container->setFixedSlot(slot, ObjectValue(*list));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
inline static MOZ_MUST_USE bool
|
||||
AppendToList(JSContext* cx, HandleNativeObject list, HandleValue value)
|
||||
{
|
||||
JSAutoCompartment ac(cx, list);
|
||||
RootedValue wrappedValue(cx, value);
|
||||
if (!JS_WrapValue(cx, &wrappedValue))
|
||||
return false;
|
||||
|
||||
uint32_t length = list->getDenseInitializedLength();
|
||||
|
||||
if (!list->ensureElements(cx, length + 1))
|
||||
return false;
|
||||
|
||||
list->ensureDenseInitializedLength(cx, length, 1);
|
||||
list->setDenseElement(length, value);
|
||||
list->setDenseElement(length, wrappedValue);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -346,6 +436,7 @@ template<class T>
|
|||
inline static MOZ_MUST_USE T*
|
||||
ShiftFromList(JSContext* cx, HandleNativeObject list)
|
||||
{
|
||||
JSAutoCompartment ac(cx, list);
|
||||
uint32_t length = list->getDenseInitializedLength();
|
||||
MOZ_ASSERT(length > 0);
|
||||
|
||||
|
|
@ -1367,7 +1458,8 @@ ReadableStreamAddReadIntoRequest(JSContext* cx, Handle<ReadableStream*> stream)
|
|||
{
|
||||
// Step 1: MOZ_ASSERT: ! IsReadableStreamBYOBReader(stream.[[reader]]) is true.
|
||||
RootedValue val(cx, stream->getFixedSlot(StreamSlot_Reader));
|
||||
RootedNativeObject reader(cx, &val.toObject().as<ReadableStreamBYOBReader>());
|
||||
RootedNativeObject reader(cx, ReaderFromStream(stream));
|
||||
MOZ_ASSERT(reader->is<ReadableStreamBYOBReader>());
|
||||
|
||||
// Step 2: MOZ_ASSERT: stream.[[state]] is "readable" or "closed".
|
||||
MOZ_ASSERT(stream->readable() || stream->closed());
|
||||
|
|
@ -1380,7 +1472,8 @@ ReadableStreamAddReadIntoRequest(JSContext* cx, Handle<ReadableStream*> stream)
|
|||
// Step 4: Let readIntoRequest be Record {[[promise]]: promise}.
|
||||
// Step 5: Append readIntoRequest as the last element of stream.[[reader]].[[readIntoRequests]].
|
||||
val = reader->getFixedSlot(ReaderSlot_Requests);
|
||||
RootedNativeObject readIntoRequests(cx, &val.toObject().as<NativeObject>());
|
||||
RootedNativeObject readIntoRequests(cx);
|
||||
readIntoRequests = UnwrapInternalSlotObject<NativeObject>(&val.toObject());
|
||||
// Since [[promise]] is the Record's only field, we store it directly.
|
||||
val = ObjectValue(*promise);
|
||||
if (!AppendToList(cx, readIntoRequests, val))
|
||||
|
|
@ -1410,7 +1503,8 @@ ReadableStreamAddReadRequest(JSContext* cx, Handle<ReadableStream*> stream)
|
|||
// Step 4: Let readRequest be Record {[[promise]]: promise}.
|
||||
// Step 5: Append readRequest as the last element of stream.[[reader]].[[readRequests]].
|
||||
RootedValue val(cx, reader->getFixedSlot(ReaderSlot_Requests));
|
||||
RootedNativeObject readRequests(cx, &val.toObject().as<NativeObject>());
|
||||
RootedNativeObject readRequests(cx);
|
||||
readRequests = UnwrapInternalSlotObject<NativeObject>(&val.toObject());
|
||||
|
||||
// Since [[promise]] is the Record's only field, we store it directly.
|
||||
val = ObjectValue(*promise);
|
||||
|
|
@ -1454,6 +1548,8 @@ ReadableStream::cancel(JSContext* cx, Handle<ReadableStream*> stream, HandleValu
|
|||
// with stream.[[storedError]].
|
||||
if (stream->errored()) {
|
||||
RootedValue storedError(cx, stream->getFixedSlot(StreamSlot_StoredError));
|
||||
if (!JS_WrapValue(cx, &storedError))
|
||||
return nullptr;
|
||||
return PromiseObject::unforgeableReject(cx, storedError);
|
||||
}
|
||||
|
||||
|
|
@ -1497,13 +1593,14 @@ ReadableStreamCloseInternal(JSContext* cx, Handle<ReadableStream*> stream)
|
|||
return true;
|
||||
|
||||
// Step 5: If ! IsReadableStreamDefaultReader(reader) is true,
|
||||
RootedNativeObject reader(cx, &val.toObject().as<NativeObject>());
|
||||
RootedNativeObject reader(cx, ReaderFromStream(stream));
|
||||
if (reader->is<ReadableStreamDefaultReader>()) {
|
||||
// Step a: Repeat for each readRequest that is an element of
|
||||
// reader.[[readRequests]],
|
||||
val = reader->getFixedSlot(ReaderSlot_Requests);
|
||||
if (!val.isUndefined()) {
|
||||
RootedNativeObject readRequests(cx, &val.toObject().as<NativeObject>());
|
||||
RootedNativeObject readRequests(cx);
|
||||
readRequests = UnwrapInternalSlotObject<NativeObject>(&val.toObject());
|
||||
uint32_t len = readRequests->getDenseInitializedLength();
|
||||
RootedObject readRequest(cx);
|
||||
RootedObject resultObj(cx);
|
||||
|
|
@ -1516,7 +1613,7 @@ ReadableStreamCloseInternal(JSContext* cx, Handle<ReadableStream*> stream)
|
|||
if (!resultObj)
|
||||
return false;
|
||||
resultVal = ObjectValue(*resultObj);
|
||||
if (!ResolvePromise(cx, readRequest, resultVal))
|
||||
if (!ResolveMaybeWrappedPromise(cx, readRequest, resultVal))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -1528,7 +1625,7 @@ ReadableStreamCloseInternal(JSContext* cx, Handle<ReadableStream*> stream)
|
|||
// Step 6: Resolve reader.[[closedPromise]] with undefined.
|
||||
// Step 7: Return (implicit).
|
||||
RootedObject closedPromise(cx, &reader->getFixedSlot(ReaderSlot_ClosedPromise).toObject());
|
||||
if (!ResolvePromise(cx, closedPromise, UndefinedHandleValue))
|
||||
if (!ResolveMaybeWrappedPromise(cx, closedPromise, UndefinedHandleValue))
|
||||
return false;
|
||||
|
||||
if (stream->mode() == JS::ReadableStreamMode::ExternalSource &&
|
||||
|
|
@ -1556,7 +1653,13 @@ ReadableStreamErrorInternal(JSContext* cx, Handle<ReadableStream*> stream, Handl
|
|||
SetStreamState(stream, (state & ReadableStream::Disturbed) | ReadableStream::Errored);
|
||||
|
||||
// Step 4: Set stream.[[storedError]] to e.
|
||||
stream->setFixedSlot(StreamSlot_StoredError, e);
|
||||
RootedValue storedError(cx, e);
|
||||
{
|
||||
JSAutoCompartment ac(cx, stream);
|
||||
if (!JS_WrapValue(cx, &storedError))
|
||||
return false;
|
||||
stream->setFixedSlot(StreamSlot_StoredError, storedError);
|
||||
}
|
||||
|
||||
// Step 5: Let reader be stream.[[reader]].
|
||||
RootedValue val(cx, stream->getFixedSlot(StreamSlot_Reader));
|
||||
|
|
@ -1564,20 +1667,21 @@ ReadableStreamErrorInternal(JSContext* cx, Handle<ReadableStream*> stream, Handl
|
|||
// Step 6: If reader is undefined, return.
|
||||
if (val.isUndefined())
|
||||
return true;
|
||||
RootedNativeObject reader(cx, &val.toObject().as<NativeObject>());
|
||||
RootedNativeObject reader(cx, ReaderFromStream(stream));
|
||||
|
||||
// Steps 7,8: (Identical in our implementation.)
|
||||
// Step a: Repeat for each readRequest that is an element of
|
||||
// reader.[[readRequests]],
|
||||
val = reader->getFixedSlot(ReaderSlot_Requests);
|
||||
RootedNativeObject readRequests(cx, &val.toObject().as<NativeObject>());
|
||||
Rooted<PromiseObject*> readRequest(cx);
|
||||
RootedNativeObject readRequests(cx);
|
||||
readRequests = UnwrapInternalSlotObject<NativeObject>(&val.toObject());
|
||||
RootedObject readRequest(cx);
|
||||
uint32_t len = readRequests->getDenseInitializedLength();
|
||||
for (uint32_t i = 0; i < len; i++) {
|
||||
// Step i: Reject readRequest.[[promise]] with e.
|
||||
val = readRequests->getDenseElement(i);
|
||||
readRequest = &val.toObject().as<PromiseObject>();
|
||||
if (!PromiseObject::reject(cx, readRequest, e))
|
||||
readRequest = &val.toObject();
|
||||
if (!RejectMaybeWrappedPromise(cx, readRequest, e))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -1587,8 +1691,8 @@ ReadableStreamErrorInternal(JSContext* cx, Handle<ReadableStream*> stream, Handl
|
|||
|
||||
// Step 9: Reject reader.[[closedPromise]] with e.
|
||||
val = reader->getFixedSlot(ReaderSlot_ClosedPromise);
|
||||
Rooted<PromiseObject*> closedPromise(cx, &val.toObject().as<PromiseObject>());
|
||||
if (!PromiseObject::reject(cx, closedPromise, e))
|
||||
RootedObject closedPromise(cx, &val.toObject());
|
||||
if (!RejectMaybeWrappedPromise(cx, closedPromise, e))
|
||||
return false;
|
||||
|
||||
if (stream->mode() == JS::ReadableStreamMode::ExternalSource &&
|
||||
|
|
@ -1612,7 +1716,7 @@ ReadableStreamFulfillReadOrReadIntoRequest(JSContext* cx, Handle<ReadableStream*
|
|||
{
|
||||
// Step 1: Let reader be stream.[[reader]].
|
||||
RootedValue val(cx, stream->getFixedSlot(StreamSlot_Reader));
|
||||
RootedNativeObject reader(cx, &val.toObject().as<NativeObject>());
|
||||
RootedNativeObject reader(cx, ReaderFromStream(stream));
|
||||
|
||||
// Step 2: Let readIntoRequest be the first element of
|
||||
// reader.[[readIntoRequests]].
|
||||
|
|
@ -1620,7 +1724,8 @@ ReadableStreamFulfillReadOrReadIntoRequest(JSContext* cx, Handle<ReadableStream*
|
|||
// all other elements downward (so that the second becomes the first,
|
||||
// and so on).
|
||||
val = reader->getFixedSlot(ReaderSlot_Requests);
|
||||
RootedNativeObject readIntoRequests(cx, &val.toObject().as<NativeObject>());
|
||||
RootedNativeObject readIntoRequests(cx);
|
||||
readIntoRequests = UnwrapInternalSlotObject<NativeObject>(&val.toObject());
|
||||
Rooted<PromiseObject*> readIntoRequest(cx);
|
||||
readIntoRequest = ShiftFromList<PromiseObject>(cx, readIntoRequests);
|
||||
MOZ_ASSERT(readIntoRequest);
|
||||
|
|
@ -1631,7 +1736,8 @@ ReadableStreamFulfillReadOrReadIntoRequest(JSContext* cx, Handle<ReadableStream*
|
|||
if (!iterResult)
|
||||
return false;
|
||||
val = ObjectValue(*iterResult);
|
||||
return PromiseObject::resolve(cx, readIntoRequest, val);
|
||||
RootedObject readIntoRequestObj(cx, readIntoRequest);
|
||||
return ResolveMaybeWrappedPromise(cx, readIntoRequestObj, val);
|
||||
}
|
||||
|
||||
// Streams spec, 3.4.8. ReadableStreamGetNumReadIntoRequests ( stream )
|
||||
|
|
@ -1646,7 +1752,8 @@ ReadableStreamGetNumReadRequests(ReadableStream* stream)
|
|||
return 0;
|
||||
NativeObject* reader = ReaderFromStream(stream);
|
||||
Value readRequests = reader->getFixedSlot(ReaderSlot_Requests);
|
||||
return readRequests.toObject().as<NativeObject>().getDenseInitializedLength();
|
||||
NativeObject* requests = UnwrapInternalSlotObject<NativeObject>(&readRequests.toObject());
|
||||
return requests->getDenseInitializedLength();
|
||||
}
|
||||
|
||||
// Stream spec 3.4.10. ReadableStreamHasBYOBReader ( stream )
|
||||
|
|
@ -1658,7 +1765,10 @@ ReadableStreamHasBYOBReader(ReadableStream* stream)
|
|||
// Step 3: If ! IsReadableStreamBYOBReader(reader) is false, return false.
|
||||
// Step 4: Return true.
|
||||
Value reader = stream->getFixedSlot(StreamSlot_Reader);
|
||||
return reader.isObject() && reader.toObject().is<ReadableStreamBYOBReader>();
|
||||
if (!reader.isObject())
|
||||
return false;
|
||||
JSObject* unwrapped = UncheckedUnwrap(&reader.toObject());
|
||||
return unwrapped && unwrapped->is<ReadableStreamBYOBReader>();
|
||||
}
|
||||
|
||||
// Streap spec 3.4.11. ReadableStreamHasDefaultReader ( stream )
|
||||
|
|
@ -1670,7 +1780,10 @@ ReadableStreamHasDefaultReader(ReadableStream* stream)
|
|||
// Step 3: If ! ReadableStreamDefaultReader(reader) is false, return false.
|
||||
// Step 4: Return true.
|
||||
Value reader = stream->getFixedSlot(StreamSlot_Reader);
|
||||
return reader.isObject() && reader.toObject().is<ReadableStreamDefaultReader>();
|
||||
if (!reader.isObject())
|
||||
return false;
|
||||
JSObject* unwrapped = UncheckedUnwrap(&reader.toObject());
|
||||
return unwrapped && unwrapped->is<ReadableStreamDefaultReader>();
|
||||
}
|
||||
|
||||
static MOZ_MUST_USE bool
|
||||
|
|
@ -1717,14 +1830,13 @@ ReadableStreamDefaultReader::constructor(JSContext* cx, unsigned argc, Value* vp
|
|||
return false;
|
||||
|
||||
// Step 1: If ! IsReadableStream(stream) is false, throw a TypeError exception.
|
||||
if (!Is<ReadableStream>(args.get(0))) {
|
||||
Rooted<ReadableStream*> stream(cx, UnwrapMaybeWrappedArg<ReadableStream>(args.get(0)));
|
||||
if (!stream) {
|
||||
ReportArgTypeError(cx, "ReadableStreamDefaultReader", "ReadableStream",
|
||||
args.get(0));
|
||||
return false;
|
||||
}
|
||||
|
||||
Rooted<ReadableStream*> stream(cx, &args.get(0).toObject().as<ReadableStream>());
|
||||
|
||||
RootedObject reader(cx, CreateReadableStreamDefaultReader(cx, stream));
|
||||
if (!reader)
|
||||
return false;
|
||||
|
|
@ -1734,36 +1846,40 @@ ReadableStreamDefaultReader::constructor(JSContext* cx, unsigned argc, Value* vp
|
|||
}
|
||||
|
||||
// Streams spec, 3.5.4.1 get closed
|
||||
static MOZ_MUST_USE bool
|
||||
ReadableStreamDefaultReader_closed(JSContext* cx, unsigned argc, Value* vp)
|
||||
[[nodiscard]] static bool
|
||||
ReadableStreamDefaultReader_closed_impl(JSContext* cx, const CallArgs& args)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
||||
// Step 1: If ! IsReadableStreamDefaultReader(this) is false, return a promise
|
||||
// rejected with a TypeError exception.
|
||||
if (!Is<ReadableStreamDefaultReader>(args.thisv()))
|
||||
return RejectNonGenericMethod(cx, args, "ReadableStreamDefaultReader", "get closed");
|
||||
|
||||
// Step 2: Return this.[[closedPromise]].
|
||||
NativeObject* reader = &args.thisv().toObject().as<NativeObject>();
|
||||
args.rval().set(reader->getFixedSlot(ReaderSlot_ClosedPromise));
|
||||
return true;
|
||||
}
|
||||
|
||||
static MOZ_MUST_USE JSObject*
|
||||
ReadableStreamReaderGenericCancel(JSContext* cx, HandleNativeObject reader, HandleValue reason);
|
||||
|
||||
// Streams spec, 3.5.4.2. cancel ( reason )
|
||||
static MOZ_MUST_USE bool
|
||||
ReadableStreamDefaultReader_cancel(JSContext* cx, unsigned argc, Value* vp)
|
||||
static bool
|
||||
ReadableStreamDefaultReader_closed(JSContext* cx, unsigned argc, Value* vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
||||
// Step 1: If ! IsReadableStreamDefaultReader(this) is false, return a promise
|
||||
// rejected with a TypeError exception.
|
||||
if (!Is<ReadableStreamDefaultReader>(args.thisv()))
|
||||
return RejectNonGenericMethod(cx, args, "ReadableStreamDefaultReader", "cancel");
|
||||
if (!Is<ReadableStreamDefaultReader>(args.thisv())) {
|
||||
if (IsMaybeWrapped<ReadableStreamDefaultReader>(args.thisv())) {
|
||||
return CallNonGenericMethod<Is<ReadableStreamDefaultReader>,
|
||||
ReadableStreamDefaultReader_closed_impl>(cx, args);
|
||||
}
|
||||
return RejectNonGenericMethod(cx, args, "ReadableStreamDefaultReader", "get closed");
|
||||
}
|
||||
|
||||
return ReadableStreamDefaultReader_closed_impl(cx, args);
|
||||
}
|
||||
|
||||
static MOZ_MUST_USE JSObject*
|
||||
ReadableStreamReaderGenericCancel(JSContext* cx, HandleNativeObject reader, HandleValue reason);
|
||||
|
||||
// Streams spec, 3.5.4.2. cancel ( reason )
|
||||
[[nodiscard]] static bool
|
||||
ReadableStreamDefaultReader_cancel_impl(JSContext* cx, const CallArgs& args)
|
||||
{
|
||||
// Step 2: If this.[[ownerReadableStream]] is undefined, return a promise
|
||||
// rejected with a TypeError exception.
|
||||
RootedNativeObject reader(cx, &args.thisv().toObject().as<NativeObject>());
|
||||
|
|
@ -1781,17 +1897,28 @@ ReadableStreamDefaultReader_cancel(JSContext* cx, unsigned argc, Value* vp)
|
|||
return true;
|
||||
}
|
||||
|
||||
// Streams spec, 3.5.4.3 read ( )
|
||||
static MOZ_MUST_USE bool
|
||||
ReadableStreamDefaultReader_read(JSContext* cx, unsigned argc, Value* vp)
|
||||
static bool
|
||||
ReadableStreamDefaultReader_cancel(JSContext* cx, unsigned argc, Value* vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
||||
// Step 1: If ! IsReadableStreamDefaultReader(this) is false, return a promise
|
||||
// rejected with a TypeError exception.
|
||||
if (!Is<ReadableStreamDefaultReader>(args.thisv()))
|
||||
return RejectNonGenericMethod(cx, args, "ReadableStreamDefaultReader", "read");
|
||||
if (!Is<ReadableStreamDefaultReader>(args.thisv())) {
|
||||
if (IsMaybeWrapped<ReadableStreamDefaultReader>(args.thisv())) {
|
||||
return CallNonGenericMethod<Is<ReadableStreamDefaultReader>,
|
||||
ReadableStreamDefaultReader_cancel_impl>(cx, args);
|
||||
}
|
||||
return RejectNonGenericMethod(cx, args, "ReadableStreamDefaultReader", "cancel");
|
||||
}
|
||||
|
||||
return ReadableStreamDefaultReader_cancel_impl(cx, args);
|
||||
}
|
||||
|
||||
// Streams spec, 3.5.4.3 read ( )
|
||||
[[nodiscard]] static bool
|
||||
ReadableStreamDefaultReader_read_impl(JSContext* cx, const CallArgs& args)
|
||||
{
|
||||
// Step 2: If this.[[ownerReadableStream]] is undefined, return a promise
|
||||
// rejected with a TypeError exception.
|
||||
Rooted<ReadableStreamDefaultReader*> reader(cx);
|
||||
|
|
@ -1810,7 +1937,25 @@ ReadableStreamDefaultReader_read(JSContext* cx, unsigned argc, Value* vp)
|
|||
return true;
|
||||
}
|
||||
|
||||
static MOZ_MUST_USE bool
|
||||
static bool
|
||||
ReadableStreamDefaultReader_read(JSContext* cx, unsigned argc, Value* vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
||||
// Step 1: If ! IsReadableStreamDefaultReader(this) is false, return a promise
|
||||
// rejected with a TypeError exception.
|
||||
if (!Is<ReadableStreamDefaultReader>(args.thisv())) {
|
||||
if (IsMaybeWrapped<ReadableStreamDefaultReader>(args.thisv())) {
|
||||
return CallNonGenericMethod<Is<ReadableStreamDefaultReader>,
|
||||
ReadableStreamDefaultReader_read_impl>(cx, args);
|
||||
}
|
||||
return RejectNonGenericMethod(cx, args, "ReadableStreamDefaultReader", "read");
|
||||
}
|
||||
|
||||
return ReadableStreamDefaultReader_read_impl(cx, args);
|
||||
}
|
||||
|
||||
[[nodiscard]] static bool
|
||||
ReadableStreamReaderGenericRelease(JSContext* cx, HandleNativeObject reader);
|
||||
|
||||
// Streams spec, 3.5.4.4. releaseLock ( )
|
||||
|
|
@ -1865,8 +2010,7 @@ static const JSPropertySpec ReadableStreamDefaultReader_properties[] = {
|
|||
JS_PS_END
|
||||
};
|
||||
|
||||
CLASS_SPEC(ReadableStreamDefaultReader, 1, ReaderSlotCount, ClassSpec::DontDefineConstructor, 0,
|
||||
JS_NULL_CLASS_OPS);
|
||||
CLASS_SPEC(ReadableStreamDefaultReader, 1, ReaderSlotCount, 0, 0, JS_NULL_CLASS_OPS);
|
||||
|
||||
|
||||
// Streams spec, 3.6.3 new ReadableStreamBYOBReader ( stream )
|
||||
|
|
@ -1916,12 +2060,12 @@ ReadableStreamBYOBReader::constructor(JSContext* cx, unsigned argc, Value* vp)
|
|||
return false;
|
||||
|
||||
// Step 1: If ! IsReadableStream(stream) is false, throw a TypeError exception.
|
||||
if (!Is<ReadableStream>(args.get(0))) {
|
||||
Rooted<ReadableStream*> stream(cx, UnwrapMaybeWrappedArg<ReadableStream>(args.get(0)));
|
||||
if (!stream) {
|
||||
ReportArgTypeError(cx, "ReadableStreamBYOBReader", "ReadableStream", args.get(0));
|
||||
return false;
|
||||
}
|
||||
|
||||
Rooted<ReadableStream*> stream(cx, &args.get(0).toObject().as<ReadableStream>());
|
||||
RootedObject reader(cx, CreateReadableStreamBYOBReader(cx, stream));
|
||||
if (!reader)
|
||||
return false;
|
||||
|
|
@ -2080,7 +2224,7 @@ static const JSFunctionSpec ReadableStreamBYOBReader_methods[] = {
|
|||
JS_FS_END
|
||||
};
|
||||
|
||||
CLASS_SPEC(ReadableStreamBYOBReader, 1, 3, ClassSpec::DontDefineConstructor, 0, JS_NULL_CLASS_OPS);
|
||||
CLASS_SPEC(ReadableStreamBYOBReader, 1, 3, 0, 0, JS_NULL_CLASS_OPS);
|
||||
|
||||
inline static MOZ_MUST_USE bool
|
||||
ReadableStreamControllerCallPullIfNeeded(JSContext* cx, HandleNativeObject controller);
|
||||
|
|
@ -2101,7 +2245,21 @@ ReadableStreamReaderGenericCancel(JSContext* cx, HandleNativeObject reader, Hand
|
|||
// Step 2: Assert: stream is not undefined (implicit).
|
||||
|
||||
// Step 3: Return ! ReadableStreamCancel(stream, reason).
|
||||
return &ReadableStreamCancel(cx, stream, reason)->as<PromiseObject>();
|
||||
RootedObject cancelPromise(cx);
|
||||
{
|
||||
JSAutoCompartment ac(cx, stream);
|
||||
RootedValue wrappedReason(cx, reason);
|
||||
if (!JS_WrapValue(cx, &wrappedReason))
|
||||
return nullptr;
|
||||
|
||||
cancelPromise = ReadableStreamCancel(cx, stream, wrappedReason);
|
||||
if (!cancelPromise)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!JS_WrapObject(cx, &cancelPromise))
|
||||
return nullptr;
|
||||
return cancelPromise;
|
||||
}
|
||||
|
||||
// Streams spec, 3.7.4. ReadableStreamReaderGenericInitialize ( reader, stream )
|
||||
|
|
@ -2110,10 +2268,19 @@ ReadableStreamReaderGenericInitialize(JSContext* cx, HandleNativeObject reader,
|
|||
Handle<ReadableStream*> stream)
|
||||
{
|
||||
// Step 1: Set reader.[[ownerReadableStream]] to stream.
|
||||
reader->setFixedSlot(ReaderSlot_Stream, ObjectValue(*stream));
|
||||
RootedValue streamVal(cx, ObjectValue(*stream));
|
||||
if (!JS_WrapValue(cx, &streamVal))
|
||||
return false;
|
||||
reader->setFixedSlot(ReaderSlot_Stream, streamVal);
|
||||
|
||||
// Step 2: Set stream.[[reader]] to reader.
|
||||
stream->setFixedSlot(StreamSlot_Reader, ObjectValue(*reader));
|
||||
RootedValue readerVal(cx, ObjectValue(*reader));
|
||||
{
|
||||
JSAutoCompartment ac(cx, stream);
|
||||
if (!JS_WrapValue(cx, &readerVal))
|
||||
return false;
|
||||
stream->setFixedSlot(StreamSlot_Reader, readerVal);
|
||||
}
|
||||
|
||||
// Step 3: If stream.[[state]] is "readable",
|
||||
RootedObject promise(cx);
|
||||
|
|
@ -2134,6 +2301,8 @@ ReadableStreamReaderGenericInitialize(JSContext* cx, HandleNativeObject reader,
|
|||
// Step ii: Set reader.[[closedPromise]] to a new promise rejected with
|
||||
// stream.[[storedError]].
|
||||
RootedValue storedError(cx, stream->getFixedSlot(StreamSlot_StoredError));
|
||||
if (!JS_WrapValue(cx, &storedError))
|
||||
return false;
|
||||
promise = PromiseObject::unforgeableReject(cx, storedError);
|
||||
}
|
||||
|
||||
|
|
@ -2152,7 +2321,7 @@ ReadableStreamReaderGenericRelease(JSContext* cx, HandleNativeObject reader)
|
|||
Rooted<ReadableStream*> stream(cx, StreamFromReader(reader));
|
||||
|
||||
// Step 2: Assert: reader.[[ownerReadableStream]].[[reader]] is reader.
|
||||
MOZ_ASSERT(&stream->getFixedSlot(StreamSlot_Reader).toObject() == reader);
|
||||
MOZ_ASSERT(ReaderFromStream(stream) == reader);
|
||||
|
||||
// Create an exception to reject promises with below. We don't have a
|
||||
// clean way to do this, unfortunately.
|
||||
|
|
@ -2210,6 +2379,8 @@ ReadableStreamBYOBReader::read(JSContext* cx, Handle<ReadableStreamBYOBReader*>
|
|||
// stream.[[storedError]].
|
||||
if (stream->errored()) {
|
||||
RootedValue storedError(cx, stream->getFixedSlot(StreamSlot_StoredError));
|
||||
if (!JS_WrapValue(cx, &storedError))
|
||||
return nullptr;
|
||||
return PromiseObject::unforgeableReject(cx, storedError);
|
||||
}
|
||||
|
||||
|
|
@ -2401,40 +2572,12 @@ CreateReadableStreamDefaultController(JSContext* cx, Handle<ReadableStream*> str
|
|||
bool
|
||||
ReadableStreamDefaultController::constructor(JSContext* cx, unsigned argc, Value* vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
||||
if (!ThrowIfNotConstructing(cx, args, "ReadableStreamDefaultController"))
|
||||
return false;
|
||||
|
||||
// Step 1: If ! IsReadableStream(stream) is false, throw a TypeError exception.
|
||||
HandleValue streamVal = args.get(0);
|
||||
if (!Is<ReadableStream>(streamVal)) {
|
||||
ReportArgTypeError(cx, "ReadableStreamDefaultController", "ReadableStream",
|
||||
args.get(0));
|
||||
return false;
|
||||
}
|
||||
|
||||
Rooted<ReadableStream*> stream(cx, &streamVal.toObject().as<ReadableStream>());
|
||||
|
||||
// Step 2: If stream.[[readableStreamController]] is not undefined, throw a
|
||||
// TypeError exception.
|
||||
if (HasController(stream)) {
|
||||
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
|
||||
JSMSG_READABLESTREAM_CONTROLLER_SET);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Steps 3-11.
|
||||
RootedObject controller(cx, CreateReadableStreamDefaultController(cx, stream, args.get(1),
|
||||
args.get(2), args.get(3)));
|
||||
if (!controller)
|
||||
return false;
|
||||
|
||||
args.rval().setObject(*controller);
|
||||
return true;
|
||||
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_NO_CONSTRUCTOR,
|
||||
"ReadableStreamDefaultController");
|
||||
return false;
|
||||
}
|
||||
|
||||
static MOZ_MUST_USE double
|
||||
[[nodiscard]] static double
|
||||
ReadableStreamControllerGetDesiredSizeUnchecked(NativeObject* controller);
|
||||
|
||||
// Streams spec, 3.8.4.1. get desiredSize
|
||||
|
|
@ -2444,7 +2587,8 @@ static MOZ_MUST_USE bool
|
|||
ReadableStreamController_desiredSize_impl(JSContext* cx, const CallArgs& args)
|
||||
{
|
||||
RootedNativeObject controller(cx);
|
||||
controller = &args.thisv().toObject().as<NativeObject>();
|
||||
controller = UnwrapMaybeWrappedReadableStreamController(args.thisv());
|
||||
MOZ_ASSERT(controller);
|
||||
|
||||
// Streams spec, 3.9.8. steps 1-4.
|
||||
// 3.9.8. Step 1: Let stream be controller.[[controlledReadableStream]].
|
||||
|
|
@ -2474,8 +2618,12 @@ ReadableStreamDefaultController_desiredSize(JSContext* cx, unsigned argc, Value*
|
|||
// Step 1: If ! IsReadableStreamDefaultController(this) is false, throw a
|
||||
// TypeError exception.
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
return CallNonGenericMethod<Is<ReadableStreamDefaultController>,
|
||||
ReadableStreamController_desiredSize_impl>(cx, args);
|
||||
if (!IsMaybeWrapped<ReadableStreamDefaultController>(args.thisv())) {
|
||||
ReportValueError3(cx, JSMSG_INCOMPATIBLE_PROTO, JSDVG_SEARCH_STACK, args.thisv(),
|
||||
nullptr, "ReadableStreamDefaultController", "get desiredSize");
|
||||
return false;
|
||||
}
|
||||
return ReadableStreamController_desiredSize_impl(cx, args);
|
||||
}
|
||||
|
||||
static MOZ_MUST_USE bool
|
||||
|
|
@ -2510,7 +2658,8 @@ static MOZ_MUST_USE bool
|
|||
ReadableStreamDefaultController_close_impl(JSContext* cx, const CallArgs& args)
|
||||
{
|
||||
Rooted<ReadableStreamDefaultController*> controller(cx);
|
||||
controller = &args.thisv().toObject().as<ReadableStreamDefaultController>();
|
||||
controller = UnwrapMaybeWrappedArg<ReadableStreamDefaultController>(args.thisv());
|
||||
MOZ_ASSERT(controller);
|
||||
|
||||
// Steps 2-3.
|
||||
if (!VerifyControllerStateForClosing(cx, controller))
|
||||
|
|
@ -2530,8 +2679,12 @@ ReadableStreamDefaultController_close(JSContext* cx, unsigned argc, Value* vp)
|
|||
// TypeError exception.
|
||||
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
return CallNonGenericMethod<Is<ReadableStreamDefaultController>,
|
||||
ReadableStreamDefaultController_close_impl>(cx, args);
|
||||
if (!IsMaybeWrapped<ReadableStreamDefaultController>(args.thisv())) {
|
||||
ReportValueError3(cx, JSMSG_INCOMPATIBLE_PROTO, JSDVG_SEARCH_STACK, args.thisv(),
|
||||
nullptr, "ReadableStreamDefaultController", "close");
|
||||
return false;
|
||||
}
|
||||
return ReadableStreamDefaultController_close_impl(cx, args);
|
||||
}
|
||||
|
||||
static MOZ_MUST_USE bool
|
||||
|
|
@ -2544,7 +2697,8 @@ static MOZ_MUST_USE bool
|
|||
ReadableStreamDefaultController_enqueue_impl(JSContext* cx, const CallArgs& args)
|
||||
{
|
||||
Rooted<ReadableStreamDefaultController*> controller(cx);
|
||||
controller = &args.thisv().toObject().as<ReadableStreamDefaultController>();
|
||||
controller = UnwrapMaybeWrappedArg<ReadableStreamDefaultController>(args.thisv());
|
||||
MOZ_ASSERT(controller);
|
||||
|
||||
// Step 2: If this.[[closeRequested]] is true, throw a TypeError exception.
|
||||
if (ControllerFlags(controller) & ControllerFlag_CloseRequested) {
|
||||
|
|
@ -2576,8 +2730,12 @@ ReadableStreamDefaultController_enqueue(JSContext* cx, unsigned argc, Value* vp)
|
|||
// TypeError exception.
|
||||
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
return CallNonGenericMethod<Is<ReadableStreamDefaultController>,
|
||||
ReadableStreamDefaultController_enqueue_impl>(cx, args);
|
||||
if (!IsMaybeWrapped<ReadableStreamDefaultController>(args.thisv())) {
|
||||
ReportValueError3(cx, JSMSG_INCOMPATIBLE_PROTO, JSDVG_SEARCH_STACK, args.thisv(),
|
||||
nullptr, "ReadableStreamDefaultController", "enqueue");
|
||||
return false;
|
||||
}
|
||||
return ReadableStreamDefaultController_enqueue_impl(cx, args);
|
||||
}
|
||||
|
||||
// Streams spec, 3.8.4.4. error ( e )
|
||||
|
|
@ -2585,7 +2743,8 @@ static MOZ_MUST_USE bool
|
|||
ReadableStreamDefaultController_error_impl(JSContext* cx, const CallArgs& args)
|
||||
{
|
||||
Rooted<ReadableStreamDefaultController*> controller(cx);
|
||||
controller = &args.thisv().toObject().as<ReadableStreamDefaultController>();
|
||||
controller = UnwrapMaybeWrappedArg<ReadableStreamDefaultController>(args.thisv());
|
||||
MOZ_ASSERT(controller);
|
||||
|
||||
// Step 2: Let stream be this.[[controlledReadableStream]].
|
||||
// Step 3: If stream.[[state]] is not "readable", throw a TypeError exception.
|
||||
|
|
@ -2609,8 +2768,12 @@ ReadableStreamDefaultController_error(JSContext* cx, unsigned argc, Value* vp)
|
|||
// TypeError exception.
|
||||
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
return CallNonGenericMethod<Is<ReadableStreamDefaultController>,
|
||||
ReadableStreamDefaultController_error_impl>(cx, args);
|
||||
if (!IsMaybeWrapped<ReadableStreamDefaultController>(args.thisv())) {
|
||||
ReportValueError3(cx, JSMSG_INCOMPATIBLE_PROTO, JSDVG_SEARCH_STACK, args.thisv(),
|
||||
nullptr, "ReadableStreamDefaultController", "error");
|
||||
return false;
|
||||
}
|
||||
return ReadableStreamDefaultController_error_impl(cx, args);
|
||||
}
|
||||
|
||||
static const JSPropertySpec ReadableStreamDefaultController_properties[] = {
|
||||
|
|
@ -2625,8 +2788,7 @@ static const JSFunctionSpec ReadableStreamDefaultController_methods[] = {
|
|||
JS_FS_END
|
||||
};
|
||||
|
||||
CLASS_SPEC(ReadableStreamDefaultController, 4, 7, ClassSpec::DontDefineConstructor, 0,
|
||||
JS_NULL_CLASS_OPS);
|
||||
CLASS_SPEC(ReadableStreamDefaultController, 4, 7, 0, 0, JS_NULL_CLASS_OPS);
|
||||
|
||||
/**
|
||||
* Unified implementation of ReadableStream controllers' [[CancelSteps]] internal
|
||||
|
|
@ -3170,36 +3332,9 @@ ReadableByteStreamController::hasExternalSource() {
|
|||
bool
|
||||
ReadableByteStreamController::constructor(JSContext* cx, unsigned argc, Value* vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
||||
if (!ThrowIfNotConstructing(cx, args, "ReadableByteStreamController"))
|
||||
return false;
|
||||
|
||||
// Step 1: If ! IsReadableStream(stream) is false, throw a TypeError exception.
|
||||
HandleValue streamVal = args.get(0);
|
||||
if (!Is<ReadableStream>(streamVal)) {
|
||||
ReportArgTypeError(cx, "ReadableStreamDefaultController", "ReadableStream",
|
||||
args.get(0));
|
||||
return false;
|
||||
}
|
||||
|
||||
Rooted<ReadableStream*> stream(cx, &streamVal.toObject().as<ReadableStream>());
|
||||
|
||||
// Step 2: If stream.[[readableStreamController]] is not undefined, throw a
|
||||
// TypeError exception.
|
||||
if (HasController(stream)) {
|
||||
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
|
||||
JSMSG_READABLESTREAM_CONTROLLER_SET);
|
||||
return false;
|
||||
}
|
||||
|
||||
RootedObject controller(cx, CreateReadableByteStreamController(cx, stream, args.get(1),
|
||||
args.get(2)));
|
||||
if (!controller)
|
||||
return false;
|
||||
|
||||
args.rval().setObject(*controller);
|
||||
return true;
|
||||
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_NO_CONSTRUCTOR,
|
||||
"ReadableByteStreamController");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Version of the ReadableByteStreamConstructor that's specialized for
|
||||
|
|
@ -3505,8 +3640,8 @@ static const ClassOps ReadableByteStreamControllerClassOps = {
|
|||
nullptr, /* trace */
|
||||
};
|
||||
|
||||
CLASS_SPEC(ReadableByteStreamController, 3, 9, ClassSpec::DontDefineConstructor,
|
||||
JSCLASS_BACKGROUND_FINALIZE, &ReadableByteStreamControllerClassOps);
|
||||
CLASS_SPEC(ReadableByteStreamController, 3, 9, 0, JSCLASS_BACKGROUND_FINALIZE,
|
||||
&ReadableByteStreamControllerClassOps);
|
||||
|
||||
// Streams spec, 3.10.5.1. [[PullSteps]] ()
|
||||
// Unified with 3.8.5.1 above.
|
||||
|
|
@ -3692,38 +3827,9 @@ CreateReadableStreamBYOBRequest(JSContext* cx, Handle<ReadableByteStreamControll
|
|||
bool
|
||||
ReadableStreamBYOBRequest::constructor(JSContext* cx, unsigned argc, Value* vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
HandleValue controllerVal = args.get(0);
|
||||
HandleValue viewVal = args.get(1);
|
||||
|
||||
if (!ThrowIfNotConstructing(cx, args, "ReadableStreamBYOBRequest"))
|
||||
return false;
|
||||
|
||||
// TODO: open PR against spec to add these checks.
|
||||
// They're expected to have happened in code using requests.
|
||||
if (!Is<ReadableByteStreamController>(controllerVal)) {
|
||||
ReportArgTypeError(cx, "ReadableStreamBYOBRequest",
|
||||
"ReadableByteStreamController", args.get(0));
|
||||
return false;
|
||||
}
|
||||
|
||||
Rooted<ReadableByteStreamController*> controller(cx);
|
||||
controller = &controllerVal.toObject().as<ReadableByteStreamController>();
|
||||
|
||||
if (!viewVal.isObject() || !JS_IsArrayBufferViewObject(&viewVal.toObject())) {
|
||||
ReportArgTypeError(cx, "ReadableStreamBYOBRequest", "ArrayBuffer view",
|
||||
args.get(1));
|
||||
return false;
|
||||
}
|
||||
|
||||
RootedArrayBufferObject view(cx, &viewVal.toObject().as<ArrayBufferObject>());
|
||||
|
||||
RootedObject request(cx, CreateReadableStreamBYOBRequest(cx, controller, view));
|
||||
if (!request)
|
||||
return false;
|
||||
|
||||
args.rval().setObject(*request);
|
||||
return true;
|
||||
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_NO_CONSTRUCTOR,
|
||||
"ReadableStreamBYOBRequest");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Streams spec, 3.11.4.1 get view
|
||||
|
|
@ -3858,8 +3964,7 @@ static const JSFunctionSpec ReadableStreamBYOBRequest_methods[] = {
|
|||
JS_FS_END
|
||||
};
|
||||
|
||||
CLASS_SPEC(ReadableStreamBYOBRequest, 3, 2, ClassSpec::DontDefineConstructor, 0,
|
||||
JS_NULL_CLASS_OPS);
|
||||
CLASS_SPEC(ReadableStreamBYOBRequest, 3, 2, 0, 0, JS_NULL_CLASS_OPS);
|
||||
|
||||
// Streams spec, 3.12.1. IsReadableStreamBYOBRequest ( x )
|
||||
// Implemented via is<ReadableStreamBYOBRequest>()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue