summaryrefslogtreecommitdiffstats
path: root/js/src/builtin/streams/ReadableStream.h
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
commit2aa4a82499d4becd2284cdb482213d541b8804dd (patch)
treeb80bf8bf13c3766139fbacc530efd0dd9d54394c /js/src/builtin/streams/ReadableStream.h
parentInitial commit. (diff)
downloadfirefox-2aa4a82499d4becd2284cdb482213d541b8804dd.tar.xz
firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.zip
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'js/src/builtin/streams/ReadableStream.h')
-rw-r--r--js/src/builtin/streams/ReadableStream.h139
1 files changed, 139 insertions, 0 deletions
diff --git a/js/src/builtin/streams/ReadableStream.h b/js/src/builtin/streams/ReadableStream.h
new file mode 100644
index 0000000000..c11596d356
--- /dev/null
+++ b/js/src/builtin/streams/ReadableStream.h
@@ -0,0 +1,139 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * vim: set ts=8 sts=2 et sw=2 tw=80:
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* Class ReadableStream. */
+
+#ifndef builtin_streams_ReadableStream_h
+#define builtin_streams_ReadableStream_h
+
+#include "mozilla/Assertions.h" // MOZ_ASSERT{,_IF}
+#include "mozilla/Attributes.h" // MOZ_MUST_USE
+
+#include <stdint.h> // uint32_t
+
+#include "jstypes.h" // JS_PUBLIC_API
+#include "js/Class.h" // JSClass, js::ClassSpec
+#include "js/RootingAPI.h" // JS::Handle
+#include "js/Stream.h" // JS::ReadableStream{Mode,UnderlyingSource}
+#include "js/Value.h" // JS::Int32Value, JS::ObjectValue, JS::UndefinedValue
+#include "vm/NativeObject.h" // js::NativeObject
+
+class JS_PUBLIC_API JSObject;
+
+namespace js {
+
+class ReadableStreamController;
+
+class ReadableStream : public NativeObject {
+ public:
+ /**
+ * Memory layout of Stream instances.
+ *
+ * See https://streams.spec.whatwg.org/#rs-internal-slots for details on
+ * the stored state. [[state]] and [[disturbed]] are stored in
+ * StreamSlot_State as ReadableStream::State enum values.
+ *
+ * Of the stored values, Reader and StoredError might be cross-compartment
+ * wrappers. This can happen if the Reader was created by applying a
+ * different compartment's ReadableStream.prototype.getReader method.
+ *
+ * A stream's associated controller is always created from under the
+ * stream's constructor and thus cannot be in a different compartment.
+ */
+ enum Slots {
+ Slot_Controller,
+ Slot_Reader,
+ Slot_State,
+ Slot_StoredError,
+ SlotCount
+ };
+
+ private:
+ enum StateBits {
+ Readable = 0,
+ Closed = 1,
+ Errored = 2,
+ StateMask = 0x000000ff,
+ Disturbed = 0x00000100
+ };
+
+ uint32_t stateBits() const { return getFixedSlot(Slot_State).toInt32(); }
+ void initStateBits(uint32_t stateBits) {
+ MOZ_ASSERT((stateBits & ~Disturbed) <= Errored);
+ setFixedSlot(Slot_State, JS::Int32Value(stateBits));
+ }
+ void setStateBits(uint32_t stateBits) {
+#ifdef DEBUG
+ bool wasDisturbed = disturbed();
+ bool wasClosedOrErrored = closed() || errored();
+#endif
+ initStateBits(stateBits);
+ MOZ_ASSERT_IF(wasDisturbed, disturbed());
+ MOZ_ASSERT_IF(wasClosedOrErrored, !readable());
+ }
+
+ StateBits state() const { return StateBits(stateBits() & StateMask); }
+ void setState(StateBits state) {
+ MOZ_ASSERT(state <= Errored);
+ uint32_t current = stateBits() & ~StateMask;
+ setStateBits(current | state);
+ }
+
+ public:
+ bool readable() const { return state() == Readable; }
+ bool closed() const { return state() == Closed; }
+ void setClosed() { setState(Closed); }
+ bool errored() const { return state() == Errored; }
+ void setErrored() { setState(Errored); }
+ bool disturbed() const { return stateBits() & Disturbed; }
+ void setDisturbed() { setStateBits(stateBits() | Disturbed); }
+
+ bool hasController() const {
+ return !getFixedSlot(Slot_Controller).isUndefined();
+ }
+ inline ReadableStreamController* controller() const;
+ inline void setController(ReadableStreamController* controller);
+ void clearController() {
+ setFixedSlot(Slot_Controller, JS::UndefinedValue());
+ }
+
+ bool hasReader() const { return !getFixedSlot(Slot_Reader).isUndefined(); }
+ void setReader(JSObject* reader) {
+ setFixedSlot(Slot_Reader, JS::ObjectValue(*reader));
+ }
+ void clearReader() { setFixedSlot(Slot_Reader, JS::UndefinedValue()); }
+
+ JS::Value storedError() const { return getFixedSlot(Slot_StoredError); }
+ void setStoredError(JS::Handle<JS::Value> value) {
+ setFixedSlot(Slot_StoredError, value);
+ }
+
+ JS::ReadableStreamMode mode() const;
+
+ bool locked() const;
+
+ static MOZ_MUST_USE ReadableStream* create(
+ JSContext* cx, void* nsISupportsObject_alreadyAddreffed = nullptr,
+ JS::Handle<JSObject*> proto = nullptr);
+ static ReadableStream* createExternalSourceStream(
+ JSContext* cx, JS::ReadableStreamUnderlyingSource* source,
+ void* nsISupportsObject_alreadyAddreffed = nullptr,
+ JS::Handle<JSObject*> proto = nullptr);
+
+ static bool constructor(JSContext* cx, unsigned argc, Value* vp);
+ static const ClassSpec classSpec_;
+ static const JSClass class_;
+ static const ClassSpec protoClassSpec_;
+ static const JSClass protoClass_;
+};
+
+extern MOZ_MUST_USE bool SetUpExternalReadableByteStreamController(
+ JSContext* cx, JS::Handle<ReadableStream*> stream,
+ JS::ReadableStreamUnderlyingSource* source);
+
+} // namespace js
+
+#endif // builtin_streams_ReadableStream_h