Backed out changeset 2693a863dabd (bug 1272697)

This commit is contained in:
Sebastian Hengst 2017-07-28 20:18:21 +02:00
parent 5dd8373329
commit 08625237bc
14 changed files with 204 additions and 2423 deletions

View File

@ -1,522 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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/. */
/*
* JSAPI functions and callbacks related to WHATWG Stream objects.
*
* Much of the API here mirrors the JS API of ReadableStream and associated
* classes, e.g. ReadableStreamDefaultReader, ReadableStreamBYOBReader,
* ReadableStreamDefaultController, ReadableByteStreamController, and
* ReadableStreamBYOBRequest.
*
* There are some crucial differences, though: Functionality that's exposed
* as methods/accessors on controllers in JS is exposed as functions taking
* ReadableStream instances instead. This is because an analysis of how
* the API would be used showed that all functions that'd take controllers
* would do so by first getting the controller from the stream instance it's
* associated with and then call the function taking it. I.e., it would purely
* add boilerplate without any gains in ease of use of the API.
*
* It would probably still make sense to factor the API the same as the JS API
* if we had to keep any API stability guarantees: the JS API won't change, so
* we could be sure that the C++ API could stay the same, too. Given that we
* don't guarantee API stability, this concern isn't too pressing.
*
* Some functions exposed here deal with ReadableStream instances that have an
* embedding-provided underlying source. These instances are largely similar
* to byte streams as created using |new ReadableStream({type: "bytes"})|:
* They enable users to acquire ReadableStreamBYOBReaders and only vend chunks
* that're typed array instances.
*
* When creating an "external readable stream" using
* JS::NewReadableExternalSourceStreamObject, an underlying source and a set
* of flags can be passed to be stored on the stream. The underlying source is
* treated as an opaque void* pointer by the JS engine: it's purely meant as
* a reference to be used by the embedding to identify whatever actual source
* it uses to supply data for the stream. Similarly, the flags aren't
* interpreted by the JS engine, but are passed to some of the callbacks below
* and can be retrieved using JS::ReadableStreamGetEmbeddingFlags.
*
* External readable streams are optimized to allow the embedding to interact
* with them with a minimum of overhead: chunks aren't enqueued as individual
* typed array instances; instead, the embedding only updates the amount of
* data available using ReadableStreamUpdateDataAvailableFromSource.
* When content requests data by reading from a reader,
* WriteIntoReadRequestBufferCallback is invoked, asking the embedding to
* write data directly into the buffer we're about to hand to content.
*
* Additionally, ReadableStreamGetExternalUnderlyingSource can be used to
* get the void* pointer to the underlying source. This is equivalent to
* acquiring a reader for the stream in that it locks the stream until it
* is released again using JS::ReadableStreamReleaseExternalUnderlyingSource.
*
* Embeddings are expected to detect situations where an API exposed to JS
* takes a ReadableStream to read from that has an external underlying source.
* In those situations, it might be preferable to directly perform data
* transfers from the stream's underlying source to whatever sink the
* embedding uses, assuming that such direct transfers can be performed
* more efficiently.
*
* An example of such an optimized operation might be a ServiceWorker piping a
* fetch Response body to a TextDecoder: instead of writing chunks of data
* into JS typed array buffers only to immediately read from them again, the
* embedding can presumably directly feed the incoming data to the
* TextDecoder's underlying implementation.
*/
#ifndef js_Stream_h
#define js_Stream_h
#include "jstypes.h"
#include "js/TypeDecls.h"
namespace JS {
/**
* Invoked whenever a reader desires more data from a ReadableStream's
* embedding-provided underlying source.
*
* The given |desiredSize| is the absolute size, not a delta from the previous
* desired size.
*/
typedef void
(* RequestReadableStreamDataCallback)(JSContext* cx, HandleObject stream,
void* underlyingSource, uint8_t flags, size_t desiredSize);
/**
* Invoked to cause the embedding to fill the given |buffer| with data from
* the given embedding-provided underlying source.
*
* This can only happen after the embedding has updated the amount of data
* available using JS::ReadableStreamUpdateDataAvailableFromSource. If at
* least one read request is pending when
* JS::ReadableStreamUpdateDataAvailableFromSource is called,
* the WriteIntoReadRequestBufferCallback is invoked immediately from under
* the call to JS::WriteIntoReadRequestBufferCallback. If not, it is invoked
* if and when a new read request is made.
*
* Note: This callback *must not cause GC*, because that could potentially
* invalidate the |buffer| pointer.
*/
typedef void
(* WriteIntoReadRequestBufferCallback)(JSContext* cx, HandleObject stream,
void* underlyingSource, uint8_t flags, void* buffer,
size_t length, size_t* bytesWritten);
/**
* Invoked in reaction to the ReadableStream being canceled to allow the
* embedding to free the underlying source.
*
* This is equivalent to calling |cancel| on non-external underlying sources
* provided to the ReadableStream constructor in JavaScript.
*
* The given |reason| is the JS::Value that was passed as an argument to
* ReadableStream#cancel().
*
* The returned JS::Value will be used to resolve the Promise returned by
* ReadableStream#cancel().
*/
typedef Value
(* CancelReadableStreamCallback)(JSContext* cx, HandleObject stream,
void* underlyingSource, uint8_t flags, HandleValue reason);
/**
* Invoked in reaction to a ReadableStream with an embedding-provided
* underlying source being closed.
*/
typedef void
(* ReadableStreamClosedCallback)(JSContext* cx, HandleObject stream, void* underlyingSource,
uint8_t flags);
/**
* Invoked in reaction to a ReadableStream with an embedding-provided
* underlying source being errored with the
* given reason.
*/
typedef void
(* ReadableStreamErroredCallback)(JSContext* cx, HandleObject stream, void* underlyingSource,
uint8_t flags, HandleValue reason);
/**
* Invoked in reaction to a ReadableStream with an embedding-provided
* underlying source being finalized. Only the underlying source is passed
* as an argument, while the ReadableStream itself is not to prevent the
* embedding from operating on a JSObject that might not be in a valid state
* anymore.
*
* Note: the ReadableStream might be finalized on a background thread. That
* means this callback might be invoked from an arbitrary thread, which the
* embedding must be able to handle.
*/
typedef void
(* ReadableStreamFinalizeCallback)(void* underlyingSource, uint8_t flags);
/**
* Sets runtime-wide callbacks to use for interacting with embedding-provided
* hooks for operating on ReadableStream instances.
*
* See the documentation for the individual callback types for details.
*/
extern JS_PUBLIC_API(void)
SetReadableStreamCallbacks(JSContext* cx,
RequestReadableStreamDataCallback dataRequestCallback,
WriteIntoReadRequestBufferCallback writeIntoReadRequestCallback,
CancelReadableStreamCallback cancelCallback,
ReadableStreamClosedCallback closedCallback,
ReadableStreamErroredCallback erroredCallback,
ReadableStreamFinalizeCallback finalizeCallback);
extern JS_PUBLIC_API(bool)
HasReadableStreamCallbacks(JSContext* cx);
/**
* Returns a new instance of the ReadableStream builtin class in the current
* compartment, configured as a default stream.
* If a |proto| is passed, that gets set as the instance's [[Prototype]]
* instead of the original value of |ReadableStream.prototype|.
*/
extern JS_PUBLIC_API(JSObject*)
NewReadableDefaultStreamObject(JSContext* cx, HandleObject underlyingSource = nullptr,
HandleFunction size = nullptr, double highWaterMark = 1,
HandleObject proto = nullptr);
/**
* Returns a new instance of the ReadableStream builtin class in the current
* compartment, configured as a byte stream.
* If a |proto| is passed, that gets set as the instance's [[Prototype]]
* instead of the original value of |ReadableStream.prototype|.
*/
extern JS_PUBLIC_API(JSObject*)
NewReadableByteStreamObject(JSContext* cx, HandleObject underlyingSource = nullptr,
double highWaterMark = 0, HandleObject proto = nullptr);
/**
* Returns a new instance of the ReadableStream builtin class in the current
* compartment, with the right slot layout. If a |proto| is passed, that gets
* set as the instance's [[Prototype]] instead of the original value of
* |ReadableStream.prototype|.
*
* The instance is optimized for operating as a byte stream backed by an
* embedding-provided underlying source, using the callbacks set via
* |JS::SetReadableStreamCallbacks|.
*
* The given |flags| will be passed to all applicable callbacks and can be
* used to disambiguate between different types of stream sources the
* embedding might support.
*
* Note: the embedding is responsible for ensuring that the pointer to the
* underlying source stays valid as long as the stream can be read from.
* The underlying source can be freed if the tree is canceled or errored.
* It can also be freed if the stream is destroyed. The embedding is notified
* of that using ReadableStreamFinalizeCallback.
*/
extern JS_PUBLIC_API(JSObject*)
NewReadableExternalSourceStreamObject(JSContext* cx, void* underlyingSource,
uint8_t flags = 0, HandleObject proto = nullptr);
/**
* Returns the flags that were passed to NewReadableExternalSourceStreamObject
* when creating the given stream.
*
* Asserts that the given stream has an embedding-provided underlying source.
*/
extern JS_PUBLIC_API(uint8_t)
ReadableStreamGetEmbeddingFlags(const JSObject* stream);
/**
* Returns the embedding-provided underlying source of the given |stream|.
*
* Can be used to optimize operations if both the underlying source and the
* intended sink are embedding-provided. In that case it might be
* preferrable to pipe data directly from source to sink without interacting
* with the stream at all.
*
* Locks the stream until ReadableStreamReleaseExternalUnderlyingSource is
* called.
*
* Throws an exception if the stream is locked, i.e. if a reader has been
* acquired for the stream, or if ReadableStreamGetExternalUnderlyingSource
* has been used previously without releasing the external source again.
*
* Throws an exception if the stream isn't readable, i.e if it is errored or
* closed. This is different from ReadableStreamGetReader because we don't
* have a Promise to resolve/reject, which a reader provides.
*
* Asserts that the stream has an embedding-provided underlying source.
*/
extern JS_PUBLIC_API(bool)
ReadableStreamGetExternalUnderlyingSource(JSContext* cx, HandleObject stream, void** source);
/**
* Releases the embedding-provided underlying source of the given |stream|,
* returning the stream into an unlocked state.
*
* Asserts that the stream was locked through
* ReadableStreamGetExternalUnderlyingSource.
*
* Asserts that the stream has an embedding-provided underlying source.
*/
extern JS_PUBLIC_API(void)
ReadableStreamReleaseExternalUnderlyingSource(JSObject* stream);
/**
* Update the amount of data available at the underlying source of the given
* |stream|.
*
* Can only be used for streams with an embedding-provided underlying source.
* The JS engine will use the given value to satisfy read requests for the
* stream by invoking the JS::WriteIntoReadRequestBuffer callback.
*/
extern JS_PUBLIC_API(bool)
ReadableStreamUpdateDataAvailableFromSource(JSContext* cx, HandleObject stream,
uint32_t availableData);
/**
* Returns true if the given object is an unwrapped ReadableStream object,
* false otherwise.
*/
extern JS_PUBLIC_API(bool)
IsReadableStream(const JSObject* obj);
/**
* Returns true if the given object is an unwrapped
* ReadableStreamDefaultReader or ReadableStreamBYOBReader object,
* false otherwise.
*/
extern JS_PUBLIC_API(bool)
IsReadableStreamReader(const JSObject* obj);
/**
* Returns true if the given object is an unwrapped
* ReadableStreamDefaultReader object, false otherwise.
*/
extern JS_PUBLIC_API(bool)
IsReadableStreamDefaultReader(const JSObject* obj);
/**
* Returns true if the given object is an unwrapped
* ReadableStreamBYOBReader object, false otherwise.
*/
extern JS_PUBLIC_API(bool)
IsReadableStreamBYOBReader(const JSObject* obj);
enum class ReadableStreamMode {
Default,
Byte,
ExternalSource
};
/**
* Returns the stream's ReadableStreamMode. If the mode is |Byte| or
* |ExternalSource|, it's possible to acquire a BYOB reader for more optimized
* operations.
*
* Asserts that |stream| is an unwrapped ReadableStream instance.
*/
extern JS_PUBLIC_API(ReadableStreamMode)
ReadableStreamGetMode(const JSObject* stream);
enum class ReadableStreamReaderMode {
Default,
BYOB
};
/**
* Returns true if the given ReadableStream is readable, false if not.
*
* Asserts that |stream| is an unwrapped ReadableStream instance.
*/
extern JS_PUBLIC_API(bool)
ReadableStreamIsReadable(const JSObject* stream);
/**
* Returns true if the given ReadableStream is locked, false if not.
*
* Asserts that |stream| is an unwrapped ReadableStream instance.
*/
extern JS_PUBLIC_API(bool)
ReadableStreamIsLocked(const JSObject* stream);
/**
* Returns true if the given ReadableStream is disturbed, false if not.
*
* Asserts that |stream| is an ReadableStream instance.
*/
extern JS_PUBLIC_API(bool)
ReadableStreamIsDisturbed(const JSObject* stream);
/**
* Cancels the given ReadableStream with the given reason and returns a
* Promise resolved according to the result.
*
* Asserts that |stream| is an unwrapped ReadableStream instance.
*/
extern JS_PUBLIC_API(JSObject*)
ReadableStreamCancel(JSContext* cx, HandleObject stream, HandleValue reason);
/**
* Creates a reader of the type specified by the mode option and locks the
* stream to the new reader.
*
* Asserts that |stream| is an unwrapped ReadableStream instance.
*/
extern JS_PUBLIC_API(JSObject*)
ReadableStreamGetReader(JSContext* cx, HandleObject stream, ReadableStreamReaderMode mode);
/**
* Tees the given ReadableStream and stores the two resulting streams in
* outparams. Returns false if the operation fails, e.g. because the stream is
* locked.
*
* Asserts that |stream| is an unwrapped ReadableStream instance.
*/
extern JS_PUBLIC_API(bool)
ReadableStreamTee(JSContext* cx, HandleObject stream,
MutableHandleObject branch1Stream, MutableHandleObject branch2Stream);
/**
* Retrieves the desired combined size of additional chunks to fill the given
* ReadableStream's queue. Stores the result in |value| and sets |hasValue| to
* true on success, returns false on failure.
*
* If the stream is errored, the call will succeed but no value will be stored
* in |value| and |hasValue| will be set to false.
*
* Note: This is semantically equivalent to the |desiredSize| getter on
* the stream controller's prototype in JS. We expose it with the stream
* itself as a target for simplicity.
*
* Asserts that |stream| is an unwrapped ReadableStream instance.
*/
extern JS_PUBLIC_API(void)
ReadableStreamGetDesiredSize(JSObject* stream, bool* hasValue, double* value);
/**
* Closes the given ReadableStream.
*
* Throws a TypeError and returns false if the closing operation fails.
*
* Note: This is semantically equivalent to the |close| method on
* the stream controller's prototype in JS. We expose it with the stream
* itself as a target for simplicity.
*
* Asserts that |stream| is an unwrapped ReadableStream instance.
*/
extern JS_PUBLIC_API(bool)
ReadableStreamClose(JSContext* cx, HandleObject stream);
/**
* Returns true if the given ReadableStream reader is locked, false otherwise.
*
* Asserts that |reader| is an unwrapped ReadableStreamDefaultReader or
* ReadableStreamBYOBReader instance.
*/
extern JS_PUBLIC_API(bool)
ReadableStreamReaderIsClosed(const JSObject* reader);
/**
* Enqueues the given chunk in the given ReadableStream.
*
* Throws a TypeError and returns false if the enqueing operation fails.
*
* Note: This is semantically equivalent to the |enqueue| method on
* the stream controller's prototype in JS. We expose it with the stream
* itself as a target for simplicity.
*
* If the ReadableStream has an underlying byte source, the given chunk must
* be a typed array or a DataView. Consider using
* ReadableByteStreamEnqueueBuffer.
*
* Asserts that |stream| is an unwrapped ReadableStream instance.
*/
extern JS_PUBLIC_API(bool)
ReadableStreamEnqueue(JSContext* cx, HandleObject stream, HandleValue chunk);
/**
* Enqueues the given buffer as a chunk in the given ReadableStream.
*
* Throws a TypeError and returns false if the enqueing operation fails.
*
* Note: This is semantically equivalent to the |enqueue| method on
* the stream controller's prototype in JS. We expose it with the stream
* itself as a target for simplicity. Additionally, the JS version only
* takes typed arrays and ArrayBufferView instances as arguments, whereas
* this takes an ArrayBuffer, obviating the need to wrap it into a typed
* array.
*
* Asserts that |stream| is an unwrapped ReadableStream instance and |buffer|
* an unwrapped ArrayBuffer instance.
*/
extern JS_PUBLIC_API(bool)
ReadableByteStreamEnqueueBuffer(JSContext* cx, HandleObject stream, HandleObject buffer);
/**
* Errors the given ReadableStream, causing all future interactions to fail
* with the given error value.
*
* Throws a TypeError and returns false if the erroring operation fails.
*
* Note: This is semantically equivalent to the |error| method on
* the stream controller's prototype in JS. We expose it with the stream
* itself as a target for simplicity.
*
* Asserts that |stream| is an unwrapped ReadableStream instance.
*/
extern JS_PUBLIC_API(bool)
ReadableStreamError(JSContext* cx, HandleObject stream, HandleValue error);
/**
* Cancels the given ReadableStream reader's associated stream.
*
* Throws a TypeError and returns false if the given reader isn't active.
*
* Asserts that |reader| is an unwrapped ReadableStreamDefaultReader or
* ReadableStreamBYOBReader instance.
*/
extern JS_PUBLIC_API(bool)
ReadableStreamReaderCancel(JSContext* cx, HandleObject reader, HandleValue reason);
/**
* Cancels the given ReadableStream reader's associated stream.
*
* Throws a TypeError and returns false if the given reader has pending
* read or readInto (for default or byob readers, respectively) requests.
*
* Asserts that |reader| is an unwrapped ReadableStreamDefaultReader or
* ReadableStreamBYOBReader instance.
*/
extern JS_PUBLIC_API(bool)
ReadableStreamReaderReleaseLock(JSContext* cx, HandleObject reader);
/**
* Requests a read from the reader's associated ReadableStream and returns the
* resulting PromiseObject.
*
* Returns a Promise that's resolved with the read result once available or
* rejected immediately if the stream is errored or the operation failed.
*
* Asserts that |reader| is an unwrapped ReadableStreamDefaultReader instance.
*/
extern JS_PUBLIC_API(JSObject*)
ReadableStreamDefaultReaderRead(JSContext* cx, HandleObject reader);
/**
* Requests a read from the reader's associated ReadableStream into the given
* ArrayBufferView and returns the resulting PromiseObject.
*
* Returns a Promise that's resolved with the read result once available or
* rejected immediately if the stream is errored or the operation failed.
*
* Asserts that |reader| is an unwrapped ReadableStreamDefaultReader and
* |view| an unwrapped typed array or DataView instance.
*/
extern JS_PUBLIC_API(JSObject*)
ReadableStreamBYOBReaderRead(JSContext* cx, HandleObject reader, HandleObject view);
} // namespace JS
#endif // js_Realm_h

File diff suppressed because it is too large Load Diff

View File

@ -7,10 +7,8 @@
#ifndef builtin_Stream_h
#define builtin_Stream_h
#include "builtin/Promise.h"
#include "vm/NativeObject.h"
namespace js {
class AutoSetNewObjectMetadata;
@ -19,50 +17,14 @@ class ReadableStream : public NativeObject
{
public:
static ReadableStream* createDefaultStream(JSContext* cx, HandleValue underlyingSource,
HandleValue size, HandleValue highWaterMark,
HandleObject proto = nullptr);
HandleValue size, HandleValue highWaterMark);
static ReadableStream* createByteStream(JSContext* cx, HandleValue underlyingSource,
HandleValue highWaterMark,
HandleObject proto = nullptr);
static ReadableStream* createExternalSourceStream(JSContext* cx, void* underlyingSource,
uint8_t flags, HandleObject proto = nullptr);
HandleValue highWaterMark);
bool readable() const;
bool closed() const;
bool errored() const;
bool disturbed() const;
bool locked() const;
void desiredSize(bool* hasSize, double* size) const;
JS::ReadableStreamMode mode() const;
static MOZ_MUST_USE bool close(JSContext* cx, Handle<ReadableStream*> stream);
static MOZ_MUST_USE JSObject* cancel(JSContext* cx, Handle<ReadableStream*> stream,
HandleValue reason);
static MOZ_MUST_USE bool error(JSContext* cx, Handle<ReadableStream*> stream,
HandleValue error);
static MOZ_MUST_USE NativeObject* getReader(JSContext* cx, Handle<ReadableStream*> stream,
JS::ReadableStreamReaderMode mode);
static MOZ_MUST_USE bool tee(JSContext* cx,
Handle<ReadableStream*> stream, bool cloneForBranch2,
MutableHandle<ReadableStream*> branch1Stream,
MutableHandle<ReadableStream*> branch2Stream);
static MOZ_MUST_USE bool enqueue(JSContext* cx, Handle<ReadableStream*> stream,
HandleValue chunk);
static MOZ_MUST_USE bool enqueueBuffer(JSContext* cx, Handle<ReadableStream*> stream,
Handle<ArrayBufferObject*> chunk);
static MOZ_MUST_USE bool getExternalSource(JSContext* cx, Handle<ReadableStream*> stream,
void** source);
void releaseExternalSource();
uint8_t embeddingFlags() const;
static MOZ_MUST_USE bool updateDataAvailableFromSource(JSContext* cx,
Handle<ReadableStream*> stream,
uint32_t availableData);
inline bool readable() const;
inline bool closed() const;
inline bool errored() const;
inline bool disturbed() const;
enum State {
Readable = 1 << 0,
@ -72,7 +34,7 @@ class ReadableStream : public NativeObject
};
private:
static MOZ_MUST_USE ReadableStream* createStream(JSContext* cx, HandleObject proto = nullptr);
static ReadableStream* createStream(JSContext* cx);
public:
static bool constructor(JSContext* cx, unsigned argc, Value* vp);
@ -85,8 +47,6 @@ class ReadableStream : public NativeObject
class ReadableStreamDefaultReader : public NativeObject
{
public:
static MOZ_MUST_USE JSObject* read(JSContext* cx, Handle<ReadableStreamDefaultReader*> reader);
static bool constructor(JSContext* cx, unsigned argc, Value* vp);
static const ClassSpec classSpec_;
static const Class class_;
@ -97,9 +57,6 @@ class ReadableStreamDefaultReader : public NativeObject
class ReadableStreamBYOBReader : public NativeObject
{
public:
static MOZ_MUST_USE JSObject* read(JSContext* cx, Handle<ReadableStreamBYOBReader*> reader,
Handle<ArrayBufferViewObject*> view);
static bool constructor(JSContext* cx, unsigned argc, Value* vp);
static const ClassSpec classSpec_;
static const Class class_;
@ -107,13 +64,6 @@ class ReadableStreamBYOBReader : public NativeObject
static const Class protoClass_;
};
bool ReadableStreamReaderIsClosed(const JSObject* reader);
MOZ_MUST_USE bool ReadableStreamReaderCancel(JSContext* cx, HandleObject reader,
HandleValue reason);
MOZ_MUST_USE bool ReadableStreamReaderReleaseLock(JSContext* cx, HandleObject reader);
class ReadableStreamDefaultController : public NativeObject
{
public:
@ -127,8 +77,6 @@ class ReadableStreamDefaultController : public NativeObject
class ReadableByteStreamController : public NativeObject
{
public:
bool hasExternalSource();
static bool constructor(JSContext* cx, unsigned argc, Value* vp);
static const ClassSpec classSpec_;
static const Class class_;

View File

@ -611,19 +611,18 @@ MSG_DEF(JSMSG_NUMBER_MUST_BE_FINITE_NON_NEGATIVE, 1, JSEXN_RANGEERR, "'{0}' must
MSG_DEF(JSMSG_READABLEBYTESTREAMCONTROLLER_INVALID_BYTESWRITTEN, 0, JSEXN_RANGEERR, "'bytesWritten' exceeds remaining length.")
MSG_DEF(JSMSG_READABLEBYTESTREAMCONTROLLER_INVALID_VIEW_SIZE, 0, JSEXN_RANGEERR, "view size does not match requested data.")
MSG_DEF(JSMSG_READABLEBYTESTREAMCONTROLLER_INVALID_VIEW_OFFSET, 0, JSEXN_RANGEERR, "view offset does not match requested position.")
MSG_DEF(JSMSG_READABLESTREAM_NOT_LOCKED, 1, JSEXN_TYPEERR, "'{0}' may only be called on a locked stream.")
MSG_DEF(JSMSG_READABLESTREAM_NOT_LOCKED, 1, JSEXN_TYPEERR, "The ReadableStream method '{0}' may only be called on a locked stream.")
MSG_DEF(JSMSG_READABLESTREAM_LOCKED, 0, JSEXN_TYPEERR, "A Reader may only be created for an unlocked ReadableStream.")
MSG_DEF(JSMSG_READABLESTREAM_NOT_BYTE_STREAM_CONTROLLER, 1, JSEXN_TYPEERR, "{0} requires a ReadableByteStreamController.")
MSG_DEF(JSMSG_READABLESTREAM_NOT_DEFAULT_CONTROLLER, 1, JSEXN_TYPEERR, "{0} requires a ReadableStreamDefaultController.")
MSG_DEF(JSMSG_READABLESTREAM_NOT_BYTE_STREAM_CONTROLLER, 0, JSEXN_TYPEERR, "ReadableStream.getReader('byob') requires a ReadableByteStreamController.")
MSG_DEF(JSMSG_READABLESTREAM_CONTROLLER_SET, 0, JSEXN_TYPEERR, "The ReadableStream already has a controller defined.")
MSG_DEF(JSMSG_READABLESTREAMREADER_NOT_OWNED, 1, JSEXN_TYPEERR, "The ReadableStream reader method '{0}' may only be called on a reader owned by a stream.")
MSG_DEF(JSMSG_READABLESTREAMREADER_NOT_EMPTY, 1, JSEXN_TYPEERR, "The ReadableStream reader method '{0}' may not be called on a reader with read requests.")
MSG_DEF(JSMSG_READABLESTREAMBYOBREADER_READ_EMPTY_VIEW, 0, JSEXN_TYPEERR, "ReadableStreamBYOBReader.read() was passed an empty TypedArrayBuffer view.")
MSG_DEF(JSMSG_READABLESTREAMREADER_RELEASED, 0, JSEXN_TYPEERR, "The ReadableStream reader was released.")
MSG_DEF(JSMSG_READABLESTREAMCONTROLLER_CLOSED, 1, JSEXN_TYPEERR, "'{0}' called on a stream already closing.")
MSG_DEF(JSMSG_READABLESTREAMCONTROLLER_NOT_READABLE, 1, JSEXN_TYPEERR, "'{0}' may only be called on a stream in the 'readable' state.")
MSG_DEF(JSMSG_READABLESTREAMCONTROLLER_CLOSED, 1, JSEXN_TYPEERR, "The ReadableStream controller method '{0}' called on a stream already closing.")
MSG_DEF(JSMSG_READABLESTREAMCONTROLLER_NOT_READABLE, 1, JSEXN_TYPEERR, "The ReadableStream controller method '{0}' may only be called on a stream in the 'readable' state.")
MSG_DEF(JSMSG_READABLEBYTESTREAMCONTROLLER_BAD_CHUNKSIZE,0, JSEXN_RANGEERR, "ReadableByteStreamController requires a positive integer or undefined for 'autoAllocateChunkSize'.")
MSG_DEF(JSMSG_READABLEBYTESTREAMCONTROLLER_BAD_CHUNK, 1, JSEXN_TYPEERR, "{0} passed a bad chunk.")
MSG_DEF(JSMSG_READABLEBYTESTREAMCONTROLLER_BAD_CHUNK, 0, JSEXN_TYPEERR, "ReadableByteStreamController passed a bad chunk.")
MSG_DEF(JSMSG_READABLEBYTESTREAMCONTROLLER_CLOSE_PENDING_PULL, 0, JSEXN_TYPEERR, "The ReadableByteStreamController cannot be closed while the buffer is being filled.")
MSG_DEF(JSMSG_READABLESTREAMBYOBREQUEST_NO_CONTROLLER, 1, JSEXN_TYPEERR, "ReadableStreamBYOBRequest method '{0}' called on a request with no controller.")
MSG_DEF(JSMSG_READABLESTREAMBYOBREQUEST_RESPOND_CLOSED, 0, JSEXN_TYPEERR, "ReadableStreamBYOBRequest method 'respond' called with non-zero number of bytes with a closed controller.")

View File

@ -125,11 +125,6 @@ if CONFIG['ENABLE_ION']:
'testJitRValueAlloc.cpp',
]
if CONFIG['ENABLE_STREAMS']:
UNIFIED_SOURCES += [
'testReadableStream.cpp',
]
DEFINES['EXPORT_JS_API'] = True
LOCAL_INCLUDES += [

View File

@ -30,7 +30,6 @@
#include "js/RequiredDefines.h"
#include "js/RootingAPI.h"
#include "js/SliceBudget.h"
#include "js/Stream.h"
#include "js/StructuredClone.h"
#include "js/TracingAPI.h"
#include "js/TrackedOptimizationInfo.h"

View File

@ -1,678 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
*/
/* 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/. */
#include "jsapi.h"
#include "jsapi-tests/tests.h"
using namespace JS;
char test_buffer_data[] = "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
static JSObject*
NewDefaultStream(JSContext* cx, HandleObject source = nullptr, HandleFunction size = nullptr,
double highWaterMark = 1, HandleObject proto = nullptr)
{
RootedObject stream(cx, NewReadableDefaultStreamObject(cx, source, size, highWaterMark,
proto));
MOZ_ASSERT_IF(stream, IsReadableStream(stream));
return stream;
}
static JSObject*
NewByteStream(JSContext* cx, double highWaterMark = 0, HandleObject proto = nullptr)
{
RootedObject source(cx, JS_NewPlainObject(cx));
MOZ_ASSERT(source);
RootedObject stream(cx, NewReadableByteStreamObject(cx, source, highWaterMark, proto));
MOZ_ASSERT_IF(stream, IsReadableStream(stream));
return stream;
}
static bool dataRequestCBCalled = false;
static void
DataRequestCB(JSContext* cx, HandleObject stream, void* underlyingSource, uint8_t flags,
size_t desiredSize)
{
MOZ_ASSERT(!dataRequestCBCalled, "Invalid test setup");
dataRequestCBCalled = true;
}
static bool writeIntoRequestBufferCBCalled = false;
static void
WriteIntoRequestBufferCB(JSContext* cx, HandleObject stream, void* underlyingSource, uint8_t flags,
void* buffer, size_t length, size_t* bytesWritten)
{
MOZ_ASSERT(!writeIntoRequestBufferCBCalled, "Invalid test setup");
MOZ_ASSERT(length <= sizeof(test_buffer_data));
memcpy(buffer, test_buffer_data, length);
writeIntoRequestBufferCBCalled = true;
*bytesWritten = length;
}
static bool cancelStreamCBCalled = false;
static Value cancelStreamReason;
static Value
CancelStreamCB(JSContext* cx, HandleObject stream, void* underlyingSource, uint8_t flags,
HandleValue reason)
{
MOZ_ASSERT(!cancelStreamCBCalled, "Invalid test setup");
cancelStreamCBCalled = true;
cancelStreamReason = reason;
return reason;
}
static bool streamClosedCBCalled = false;
static Value streamClosedReason;
static void
StreamClosedCB(JSContext* cx, HandleObject stream, void* underlyingSource, uint8_t flags)
{
MOZ_ASSERT(!streamClosedCBCalled, "Invalid test setup");
streamClosedCBCalled = true;
}
static bool streamErroredCBCalled = false;
static Value streamErroredReason;
static void
StreamErroredCB(JSContext* cx, HandleObject stream, void* underlyingSource, uint8_t flags,
HandleValue reason)
{
MOZ_ASSERT(!streamErroredCBCalled, "Invalid test setup");
streamErroredCBCalled = true;
streamErroredReason = reason;
}
static bool finalizeStreamCBCalled = false;
static void* finalizedStreamUnderlyingSource;
static void
FinalizeStreamCB(void* underlyingSource, uint8_t flags)
{
MOZ_ASSERT(!finalizeStreamCBCalled, "Invalid test setup");
finalizeStreamCBCalled = true;
finalizedStreamUnderlyingSource = underlyingSource;
}
static void
ResetCallbacks()
{
dataRequestCBCalled = false;
writeIntoRequestBufferCBCalled = false;
cancelStreamReason = UndefinedValue();
cancelStreamCBCalled = false;
streamClosedCBCalled = false;
streamErroredCBCalled = false;
finalizeStreamCBCalled = false;
}
static bool
GetIterResult(JSContext* cx, HandleObject promise, MutableHandleValue value, bool* done)
{
RootedObject iterResult(cx, &GetPromiseResult(promise).toObject());
bool found;
if (!JS_HasProperty(cx, iterResult, "value", &found))
return false;
MOZ_ASSERT(found);
if (!JS_HasProperty(cx, iterResult, "done", &found))
return false;
MOZ_ASSERT(found);
RootedValue doneVal(cx);
if (!JS_GetProperty(cx, iterResult, "value", value))
return false;
if (!JS_GetProperty(cx, iterResult, "done", &doneVal))
return false;
*done = doneVal.toBoolean();
MOZ_ASSERT_IF(*done, value.isUndefined());
return true;
}
static JSObject*
GetReadChunk(JSContext* cx, HandleObject readRequest)
{
MOZ_ASSERT(GetPromiseState(readRequest) == PromiseState::Fulfilled);
RootedValue resultVal(cx, GetPromiseResult(readRequest));
MOZ_ASSERT(resultVal.isObject());
RootedObject result(cx, &resultVal.toObject());
RootedValue chunkVal(cx);
JS_GetProperty(cx, result, "value", &chunkVal);
return &chunkVal.toObject();
}
BEGIN_TEST(testReadableStream_NewReadableStream)
{
RootedObject stream(cx, NewDefaultStream(cx));
CHECK(stream);
CHECK(ReadableStreamGetMode(stream) == ReadableStreamMode::Default);
return true;
}
END_TEST(testReadableStream_NewReadableStream)
BEGIN_TEST(testReadableStream_NewReadableByteStream)
{
RootedObject stream(cx, NewByteStream(cx));
CHECK(stream);
CHECK(ReadableStreamGetMode(stream) == ReadableStreamMode::Byte);
return true;
}
END_TEST(testReadableStream_NewReadableByteStream)
BEGIN_TEST(testReadableStream_ReadableStreamGetReaderDefault)
{
RootedObject stream(cx, NewDefaultStream(cx));
CHECK(stream);
RootedObject reader(cx, ReadableStreamGetReader(cx, stream, ReadableStreamReaderMode::Default));
CHECK(reader);
CHECK(IsReadableStreamDefaultReader(reader));
CHECK(ReadableStreamIsLocked(stream));
CHECK(!ReadableStreamReaderIsClosed(reader));
return true;
}
END_TEST(testReadableStream_ReadableStreamGetReaderDefault)
BEGIN_TEST(testReadableStream_ReadableStreamGetReaderBYOB)
{
RootedObject stream(cx, NewByteStream(cx));
CHECK(stream);
RootedObject reader(cx, ReadableStreamGetReader(cx, stream, ReadableStreamReaderMode::BYOB));
CHECK(reader);
CHECK(IsReadableStreamBYOBReader(reader));
CHECK(ReadableStreamIsLocked(stream));
CHECK(!ReadableStreamReaderIsClosed(reader));
return true;
}
END_TEST(testReadableStream_ReadableStreamGetReaderBYOB)
BEGIN_TEST(testReadableStream_ReadableStreamTee)
{
RootedObject stream(cx, NewDefaultStream(cx));
CHECK(stream);
RootedObject leftStream(cx);
RootedObject rightStream(cx);
CHECK(ReadableStreamTee(cx, stream, &leftStream, &rightStream));
CHECK(ReadableStreamIsLocked(stream));
CHECK(leftStream);
CHECK(IsReadableStream(leftStream));
CHECK(rightStream);
CHECK(IsReadableStream(rightStream));
return true;
}
END_TEST(testReadableStream_ReadableStreamTee)
BEGIN_TEST(testReadableStream_ReadableStreamEnqueue)
{
RootedObject stream(cx, NewDefaultStream(cx));
CHECK(stream);
RootedObject chunk(cx, JS_NewPlainObject(cx));
CHECK(chunk);
RootedValue chunkVal(cx, ObjectValue(*chunk));
CHECK(ReadableStreamEnqueue(cx, stream, chunkVal));
return true;
}
END_TEST(testReadableStream_ReadableStreamEnqueue)
BEGIN_TEST(testReadableStream_ReadableByteStreamEnqueue)
{
RootedObject stream(cx, NewDefaultStream(cx));
CHECK(stream);
RootedObject chunk(cx, JS_NewUint8Array(cx, 42));
CHECK(chunk);
CHECK(!ReadableByteStreamEnqueueBuffer(cx, stream, chunk));
CHECK(JS_IsExceptionPending(cx));
return true;
}
END_TEST(testReadableStream_ReadableByteStreamEnqueue)
BEGIN_TEST(testReadableStream_ReadableStreamDefaultReaderRead)
{
RootedObject stream(cx, NewDefaultStream(cx));
CHECK(stream);
RootedObject reader(cx, ReadableStreamGetReader(cx, stream, ReadableStreamReaderMode::Default));
CHECK(reader);
RootedObject request(cx, ReadableStreamDefaultReaderRead(cx, reader));
CHECK(request);
CHECK(IsPromiseObject(request));
CHECK(GetPromiseState(request) == PromiseState::Pending);
RootedObject chunk(cx, JS_NewPlainObject(cx));
CHECK(chunk);
RootedValue chunkVal(cx, ObjectValue(*chunk));
CHECK(ReadableStreamEnqueue(cx, stream, chunkVal));
CHECK(GetReadChunk(cx, request) == chunk);
return true;
}
END_TEST(testReadableStream_ReadableStreamDefaultReaderRead)
BEGIN_TEST(testReadableStream_ReadableByteStreamDefaultReaderRead)
{
RootedObject stream(cx, NewByteStream(cx));
CHECK(stream);
RootedObject reader(cx, ReadableStreamGetReader(cx, stream, ReadableStreamReaderMode::Default));
CHECK(reader);
RootedObject request(cx, ReadableStreamDefaultReaderRead(cx, reader));
CHECK(request);
CHECK(IsPromiseObject(request));
CHECK(GetPromiseState(request) == PromiseState::Pending);
size_t length = sizeof(test_buffer_data);
RootedObject buffer(cx, JS_NewArrayBufferWithExternalContents(cx, length, test_buffer_data));
CHECK(buffer);
RootedObject chunk(cx, JS_NewUint8ArrayWithBuffer(cx, buffer, 0, length));
CHECK(chunk);
bool isShared;
CHECK(!JS_IsDetachedArrayBufferObject(buffer));
CHECK(ReadableByteStreamEnqueueBuffer(cx, stream, chunk));
CHECK(JS_IsDetachedArrayBufferObject(buffer));
RootedObject readChunk(cx, GetReadChunk(cx, request));
CHECK(JS_IsUint8Array(readChunk));
void* readBufferData;
{
JS::AutoCheckCannotGC autoNoGC(cx);
readBufferData = JS_GetArrayBufferViewData(readChunk, &isShared, autoNoGC);
}
CHECK(readBufferData);
CHECK(!memcmp(test_buffer_data, readBufferData, length));
return true;
}
END_TEST(testReadableStream_ReadableByteStreamDefaultReaderRead)
BEGIN_TEST(testReadableStream_ReadableByteStreamBYOBReaderRead)
{
RootedObject stream(cx, NewByteStream(cx));
CHECK(stream);
RootedObject reader(cx, ReadableStreamGetReader(cx, stream, ReadableStreamReaderMode::BYOB));
CHECK(reader);
size_t length = sizeof(test_buffer_data);
RootedObject targetArray(cx, JS_NewUint8Array(cx, length));
bool isShared;
RootedObject request(cx, ReadableStreamBYOBReaderRead(cx, reader, targetArray));
CHECK(request);
CHECK(IsPromiseObject(request));
CHECK(GetPromiseState(request) == PromiseState::Pending);
CHECK(JS_IsDetachedArrayBufferObject(JS_GetArrayBufferViewBuffer(cx, targetArray, &isShared)));
RootedObject buffer(cx, JS_NewArrayBufferWithExternalContents(cx, length, test_buffer_data));
CHECK(buffer);
CHECK(!JS_IsDetachedArrayBufferObject(buffer));
CHECK(ReadableByteStreamEnqueueBuffer(cx, stream, buffer));
CHECK(JS_IsDetachedArrayBufferObject(buffer));
RootedObject readChunk(cx, GetReadChunk(cx, request));
CHECK(JS_IsUint8Array(readChunk));
void* readBufferData;
{
JS::AutoCheckCannotGC autoNoGC(cx);
readBufferData = JS_GetArrayBufferViewData(readChunk, &isShared, autoNoGC);
}
CHECK(readBufferData);
CHECK(!memcmp(test_buffer_data, readBufferData, length));
// TODO: eliminate the memcpy that happens here.
// CHECK(readBufferData == test_buffer_data);
return true;
}
END_TEST(testReadableStream_ReadableByteStreamBYOBReaderRead)
BEGIN_TEST(testReadableStream_ReadableStreamDefaultReaderClose)
{
SetReadableStreamCallbacks(cx, &DataRequestCB, &WriteIntoRequestBufferCB,
&CancelStreamCB, &StreamClosedCB, &StreamErroredCB,
&FinalizeStreamCB);
RootedObject stream(cx, NewDefaultStream(cx));
CHECK(stream);
RootedObject reader(cx, ReadableStreamGetReader(cx, stream, ReadableStreamReaderMode::Default));
CHECK(reader);
RootedObject request(cx, ReadableStreamDefaultReaderRead(cx, reader));
CHECK(request);
CHECK(IsPromiseObject(request));
CHECK(GetPromiseState(request) == PromiseState::Pending);
CHECK(ReadableStreamClose(cx, stream));
bool done;
RootedValue value(cx);
CHECK(GetPromiseState(request) == PromiseState::Fulfilled);
CHECK(GetIterResult(cx, request, &value, &done));
CHECK(value.isUndefined());
CHECK(done);
// The callbacks are only invoked for external streams.
CHECK(!streamClosedCBCalled);
return true;
}
END_TEST(testReadableStream_ReadableStreamDefaultReaderClose)
BEGIN_TEST(testReadableStream_ReadableStreamDefaultReaderError)
{
ResetCallbacks();
SetReadableStreamCallbacks(cx, &DataRequestCB, &WriteIntoRequestBufferCB,
&CancelStreamCB, &StreamClosedCB, &StreamErroredCB,
&FinalizeStreamCB);
RootedObject stream(cx, NewDefaultStream(cx));
CHECK(stream);
RootedObject reader(cx, ReadableStreamGetReader(cx, stream, ReadableStreamReaderMode::Default));
CHECK(reader);
RootedObject request(cx, ReadableStreamDefaultReaderRead(cx, reader));
CHECK(request);
CHECK(IsPromiseObject(request));
CHECK(GetPromiseState(request) == PromiseState::Pending);
CHECK(ReadableStreamIsLocked(stream));
CHECK(ReadableStreamIsReadable(stream));
RootedValue error(cx, Int32Value(42));
CHECK(ReadableStreamError(cx, stream, error));
CHECK(GetPromiseState(request) == PromiseState::Rejected);
RootedValue reason(cx, GetPromiseResult(request));
CHECK(reason.isInt32());
CHECK(reason.toInt32() == 42);
// The callbacks are only invoked for external streams.
CHECK(!streamErroredCBCalled);
return true;
}
END_TEST(testReadableStream_ReadableStreamDefaultReaderError)
static JSObject*
NewExternalSourceStream(JSContext* cx, void* underlyingSource,
RequestReadableStreamDataCallback dataRequestCallback,
WriteIntoReadRequestBufferCallback writeIntoReadRequestCallback,
CancelReadableStreamCallback cancelCallback,
ReadableStreamClosedCallback closedCallback,
ReadableStreamErroredCallback erroredCallback,
ReadableStreamFinalizeCallback finalizeCallback)
{
SetReadableStreamCallbacks(cx, dataRequestCallback, writeIntoReadRequestCallback,
cancelCallback, closedCallback, erroredCallback,
finalizeCallback);
RootedObject stream(cx, NewReadableExternalSourceStreamObject(cx, underlyingSource));
MOZ_ASSERT_IF(stream, IsReadableStream(stream));
return stream;
}
BEGIN_TEST(testReadableStream_CreateReadableByteStreamWithExternalSource)
{
ResetCallbacks();
RootedObject stream(cx, NewExternalSourceStream(cx, &test_buffer_data, &DataRequestCB,
&WriteIntoRequestBufferCB, &CancelStreamCB,
&StreamClosedCB, &StreamErroredCB,
&FinalizeStreamCB));
CHECK(stream);
CHECK(ReadableStreamGetMode(stream) == JS::ReadableStreamMode::ExternalSource);
void* underlyingSource;
CHECK(ReadableStreamGetExternalUnderlyingSource(cx, stream, &underlyingSource));
CHECK(underlyingSource == &test_buffer_data);
CHECK(ReadableStreamIsLocked(stream));
ReadableStreamReleaseExternalUnderlyingSource(stream);
return true;
}
END_TEST(testReadableStream_CreateReadableByteStreamWithExternalSource)
BEGIN_TEST(testReadableStream_ExternalSourceCancel)
{
ResetCallbacks();
RootedObject stream(cx, NewExternalSourceStream(cx, &test_buffer_data, &DataRequestCB,
&WriteIntoRequestBufferCB, &CancelStreamCB,
&StreamClosedCB, &StreamErroredCB,
&FinalizeStreamCB));
CHECK(stream);
RootedValue reason(cx, Int32Value(42));
CHECK(ReadableStreamCancel(cx, stream, reason));
CHECK(cancelStreamCBCalled);
CHECK(cancelStreamReason == reason);
return true;
}
END_TEST(testReadableStream_ExternalSourceCancel)
BEGIN_TEST(testReadableStream_ExternalSourceGetReader)
{
ResetCallbacks();
RootedObject stream(cx, NewExternalSourceStream(cx, &test_buffer_data, &DataRequestCB,
&WriteIntoRequestBufferCB, &CancelStreamCB,
&StreamClosedCB, &StreamErroredCB,
&FinalizeStreamCB));
CHECK(stream);
RootedValue streamVal(cx, ObjectValue(*stream));
CHECK(JS_SetProperty(cx, global, "stream", streamVal));
RootedValue rval(cx);
EVAL("stream.getReader()", &rval);
CHECK(rval.isObject());
RootedObject reader(cx, &rval.toObject());
CHECK(IsReadableStreamDefaultReader(reader));
return true;
}
END_TEST(testReadableStream_ExternalSourceGetReader)
BEGIN_TEST(testReadableStream_ExternalSourceUpdateAvailableData)
{
ResetCallbacks();
RootedObject stream(cx, NewExternalSourceStream(cx, &test_buffer_data, &DataRequestCB,
&WriteIntoRequestBufferCB, &CancelStreamCB,
&StreamClosedCB, &StreamErroredCB,
&FinalizeStreamCB));
CHECK(stream);
ReadableStreamUpdateDataAvailableFromSource(cx, stream, 1024);
return true;
}
END_TEST(testReadableStream_ExternalSourceUpdateAvailableData)
struct ReadFromExternalSourceFixture : public JSAPITest
{
virtual ~ReadFromExternalSourceFixture() {}
bool readWithoutDataAvailable(const char* evalSrc, const char* evalSrc2,
uint32_t writtenLength)
{
ResetCallbacks();
definePrint();
RootedObject stream(cx, NewExternalSourceStream(cx, &test_buffer_data, &DataRequestCB,
&WriteIntoRequestBufferCB,
&CancelStreamCB,
&StreamClosedCB, &StreamErroredCB,
&FinalizeStreamCB));
CHECK(stream);
js::RunJobs(cx);
void* underlyingSource;
CHECK(ReadableStreamGetExternalUnderlyingSource(cx, stream, &underlyingSource));
CHECK(underlyingSource == &test_buffer_data);
CHECK(ReadableStreamIsLocked(stream));
ReadableStreamReleaseExternalUnderlyingSource(stream);
RootedValue streamVal(cx, ObjectValue(*stream));
CHECK(JS_SetProperty(cx, global, "stream", streamVal));
RootedValue rval(cx);
EVAL(evalSrc, &rval);
CHECK(dataRequestCBCalled);
CHECK(!writeIntoRequestBufferCBCalled);
CHECK(rval.isObject());
RootedObject promise(cx, &rval.toObject());
CHECK(IsPromiseObject(promise));
CHECK(GetPromiseState(promise) == PromiseState::Pending);
size_t length = sizeof(test_buffer_data);
ReadableStreamUpdateDataAvailableFromSource(cx, stream, length);
CHECK(writeIntoRequestBufferCBCalled);
CHECK(GetPromiseState(promise) == PromiseState::Fulfilled);
RootedValue iterVal(cx);
bool done;
if (!GetIterResult(cx, promise, &iterVal, &done))
return false;
CHECK(!done);
RootedObject chunk(cx, &iterVal.toObject());
CHECK(JS_IsUint8Array(chunk));
{
JS::AutoCheckCannotGC noGC(cx);
bool dummy;
void* buffer = JS_GetArrayBufferViewData(chunk, &dummy, noGC);
CHECK(!memcmp(buffer, test_buffer_data, writtenLength));
}
dataRequestCBCalled = false;
writeIntoRequestBufferCBCalled = false;
EVAL(evalSrc2, &rval);
CHECK(dataRequestCBCalled);
CHECK(!writeIntoRequestBufferCBCalled);
return true;
}
bool readWithDataAvailable(const char* evalSrc, uint32_t writtenLength) {
ResetCallbacks();
definePrint();
RootedObject stream(cx, NewExternalSourceStream(cx, &test_buffer_data, &DataRequestCB,
&WriteIntoRequestBufferCB, &CancelStreamCB,
&StreamClosedCB, &StreamErroredCB,
&FinalizeStreamCB));
CHECK(stream);
void* underlyingSource;
CHECK(ReadableStreamGetExternalUnderlyingSource(cx, stream, &underlyingSource));
CHECK(underlyingSource == &test_buffer_data);
CHECK(ReadableStreamIsLocked(stream));
ReadableStreamReleaseExternalUnderlyingSource(stream);
size_t length = sizeof(test_buffer_data);
ReadableStreamUpdateDataAvailableFromSource(cx, stream, length);
RootedValue streamVal(cx, ObjectValue(*stream));
CHECK(JS_SetProperty(cx, global, "stream", streamVal));
RootedValue rval(cx);
EVAL(evalSrc, &rval);
CHECK(writeIntoRequestBufferCBCalled);
CHECK(rval.isObject());
RootedObject promise(cx, &rval.toObject());
CHECK(IsPromiseObject(promise));
CHECK(GetPromiseState(promise) == PromiseState::Fulfilled);
RootedValue iterVal(cx);
bool done;
if (!GetIterResult(cx, promise, &iterVal, &done))
return false;
CHECK(!done);
RootedObject chunk(cx, &iterVal.toObject());
CHECK(JS_IsUint8Array(chunk));
{
JS::AutoCheckCannotGC noGC(cx);
bool dummy;
void* buffer = JS_GetArrayBufferViewData(chunk, &dummy, noGC);
CHECK(!memcmp(buffer, test_buffer_data, writtenLength));
}
return true;
}
};
BEGIN_FIXTURE_TEST(ReadFromExternalSourceFixture,
testReadableStream_ExternalSourceReadDefaultWithoutDataAvailable)
{
return readWithoutDataAvailable("r = stream.getReader(); r.read()", "r.read()", sizeof(test_buffer_data));
}
END_FIXTURE_TEST(ReadFromExternalSourceFixture,
testReadableStream_ExternalSourceReadDefaultWithoutDataAvailable)
BEGIN_FIXTURE_TEST(ReadFromExternalSourceFixture,
testReadableStream_ExternalSourceCloseWithPendingRead)
{
CHECK(readWithoutDataAvailable("r = stream.getReader(); request0 = r.read(); "
"request1 = r.read(); request0", "r.read()",
sizeof(test_buffer_data)));
RootedValue val(cx);
CHECK(JS_GetProperty(cx, global, "request1", &val));
CHECK(val.isObject());
RootedObject request(cx, &val.toObject());
CHECK(IsPromiseObject(request));
CHECK(GetPromiseState(request) == PromiseState::Pending);
CHECK(JS_GetProperty(cx, global, "stream", &val));
RootedObject stream(cx, &val.toObject());
ReadableStreamClose(cx, stream);
val = GetPromiseResult(request);
MOZ_ASSERT(val.isObject());
RootedObject result(cx, &val.toObject());
JS_GetProperty(cx, result, "done", &val);
CHECK(val.isBoolean());
CHECK(val.toBoolean() == true);
JS_GetProperty(cx, result, "value", &val);
CHECK(val.isUndefined());
return true;
}
END_FIXTURE_TEST(ReadFromExternalSourceFixture,
testReadableStream_ExternalSourceCloseWithPendingRead)
BEGIN_FIXTURE_TEST(ReadFromExternalSourceFixture,
testReadableStream_ExternalSourceReadDefaultWithDataAvailable)
{
return readWithDataAvailable("r = stream.getReader(); r.read()", sizeof(test_buffer_data));
}
END_FIXTURE_TEST(ReadFromExternalSourceFixture,
testReadableStream_ExternalSourceReadDefaultWithDataAvailable)
BEGIN_FIXTURE_TEST(ReadFromExternalSourceFixture,
testReadableStream_ExternalSourceReadBYOBWithoutDataAvailable)
{
return readWithoutDataAvailable("r = stream.getReader({mode: 'byob'}); r.read(new Uint8Array(63))", "r.read(new Uint8Array(10))", 10);
}
END_FIXTURE_TEST(ReadFromExternalSourceFixture,
testReadableStream_ExternalSourceReadBYOBWithoutDataAvailable)
BEGIN_FIXTURE_TEST(ReadFromExternalSourceFixture,
testReadableStream_ExternalSourceReadBYOBWithDataAvailable)
{
return readWithDataAvailable("r = stream.getReader({mode: 'byob'}); r.read(new Uint8Array(10))", 10);
}
END_FIXTURE_TEST(ReadFromExternalSourceFixture,
testReadableStream_ExternalSourceReadBYOBWithDataAvailable)

View File

@ -83,10 +83,6 @@ JSObject* JSAPITest::createGlobal(JSPrincipals* principals)
/* Create the global object. */
JS::RootedObject newGlobal(cx);
JS::CompartmentOptions options;
#ifdef ENABLE_STREAMS
options.creationOptions().setStreamsEnabled(true);
#endif
printf("enabled\n");
options.behaviors().setVersion(JSVERSION_LATEST);
newGlobal = JS_NewGlobalObject(cx, getGlobalClass(), principals, JS::FireOnNewGlobalHook,
options);

View File

@ -49,7 +49,6 @@
#include "builtin/MapObject.h"
#include "builtin/Promise.h"
#include "builtin/RegExp.h"
#include "builtin/Stream.h"
#include "builtin/SymbolObject.h"
#ifdef ENABLE_SIMD
# include "builtin/SIMD.h"
@ -5212,6 +5211,7 @@ CallOriginalPromiseThenImpl(JSContext* cx, JS::HandleObject promiseObj,
return false;
}
return true;
}
JS_PUBLIC_API(JSObject*)
@ -5253,368 +5253,6 @@ JS::GetWaitForAllPromise(JSContext* cx, const JS::AutoObjectVector& promises)
return js::GetWaitForAllPromise(cx, promises);
}
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->runtime()->isAtomsCompartment(cx->compartment()));
AssertHeapIsIdle();
CHECK_REQUEST(cx);
RootedObject source(cx, underlyingSource);
if (!source) {
source = NewBuiltinClassInstance<PlainObject>(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::NewReadableByteStreamObject(JSContext* cx,
JS::HandleObject underlyingSource /* = nullptr */,
double highWaterMark /* = 1 */,
JS::HandleObject proto /* = nullptr */)
{
MOZ_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
AssertHeapIsIdle();
CHECK_REQUEST(cx);
RootedObject source(cx, underlyingSource);
if (!source) {
source = NewBuiltinClassInstance<PlainObject>(cx);
if (!source)
return nullptr;
}
RootedValue sourceVal(cx, ObjectValue(*source));
RootedValue highWaterMarkVal(cx, NumberValue(highWaterMark));
return ReadableStream::createByteStream(cx, sourceVal, highWaterMarkVal, proto);
}
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::NewReadableExternalSourceStreamObject(JSContext* cx, void* underlyingSource,
uint8_t flags /* = 0 */,
HandleObject proto /* = nullptr */)
{
MOZ_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
AssertHeapIsIdle();
CHECK_REQUEST(cx);
#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(uint8_t)
JS::ReadableStreamGetEmbeddingFlags(const JSObject* stream)
{
return stream->as<ReadableStream>().embeddingFlags();
}
JS_PUBLIC_API(bool)
JS::IsReadableStream(const JSObject* obj)
{
return obj->is<ReadableStream>();
}
JS_PUBLIC_API(bool)
JS::IsReadableStreamReader(const JSObject* obj)
{
return obj->is<ReadableStreamDefaultReader>() || obj->is<ReadableStreamBYOBReader>();
}
JS_PUBLIC_API(bool)
JS::IsReadableStreamDefaultReader(const JSObject* obj)
{
return obj->is<ReadableStreamDefaultReader>();
}
JS_PUBLIC_API(bool)
JS::IsReadableStreamBYOBReader(const JSObject* obj)
{
return obj->is<ReadableStreamBYOBReader>();
}
JS_PUBLIC_API(bool)
JS::ReadableStreamIsReadable(const JSObject* stream)
{
return stream->as<ReadableStream>().readable();
}
JS_PUBLIC_API(bool)
JS::ReadableStreamIsLocked(const JSObject* stream)
{
return stream->as<ReadableStream>().locked();
}
JS_PUBLIC_API(bool)
JS::ReadableStreamIsDisturbed(const JSObject* stream)
{
return stream->as<ReadableStream>().disturbed();
}
JS_PUBLIC_API(JSObject*)
JS::ReadableStreamCancel(JSContext* cx, HandleObject streamObj, HandleValue reason)
{
AssertHeapIsIdle();
CHECK_REQUEST(cx);
assertSameCompartment(cx, streamObj);
assertSameCompartment(cx, reason);
Rooted<ReadableStream*> stream(cx, &streamObj->as<ReadableStream>());
return ReadableStream::cancel(cx, stream, reason);
}
JS_PUBLIC_API(JS::ReadableStreamMode)
JS::ReadableStreamGetMode(const JSObject* stream)
{
return stream->as<ReadableStream>().mode();
}
JS_PUBLIC_API(JSObject*)
JS::ReadableStreamGetReader(JSContext* cx, HandleObject streamObj, ReadableStreamReaderMode mode)
{
AssertHeapIsIdle();
CHECK_REQUEST(cx);
assertSameCompartment(cx, streamObj);
Rooted<ReadableStream*> stream(cx, &streamObj->as<ReadableStream>());
return ReadableStream::getReader(cx, stream, mode);
}
JS_PUBLIC_API(bool)
JS::ReadableStreamGetExternalUnderlyingSource(JSContext* cx, HandleObject streamObj, void** source)
{
AssertHeapIsIdle();
CHECK_REQUEST(cx);
assertSameCompartment(cx, streamObj);
Rooted<ReadableStream*> stream(cx, &streamObj->as<ReadableStream>());
return ReadableStream::getExternalSource(cx, stream, source);
}
JS_PUBLIC_API(void)
JS::ReadableStreamReleaseExternalUnderlyingSource(JSObject* stream)
{
stream->as<ReadableStream>().releaseExternalSource();
}
JS_PUBLIC_API(bool)
JS::ReadableStreamUpdateDataAvailableFromSource(JSContext* cx, JS::HandleObject streamObj,
uint32_t availableData)
{
AssertHeapIsIdle();
CHECK_REQUEST(cx);
assertSameCompartment(cx, streamObj);
Rooted<ReadableStream*> stream(cx, &streamObj->as<ReadableStream>());
return ReadableStream::updateDataAvailableFromSource(cx, stream, availableData);
}
JS_PUBLIC_API(bool)
JS::ReadableStreamTee(JSContext* cx, HandleObject streamObj,
MutableHandleObject branch1Obj, MutableHandleObject branch2Obj)
{
AssertHeapIsIdle();
CHECK_REQUEST(cx);
assertSameCompartment(cx, streamObj);
Rooted<ReadableStream*> stream(cx, &streamObj->as<ReadableStream>());
Rooted<ReadableStream*> branch1Stream(cx);
Rooted<ReadableStream*> branch2Stream(cx);
if (!ReadableStream::tee(cx, stream, false, &branch1Stream, &branch2Stream))
return false;
branch1Obj.set(branch1Stream);
branch2Obj.set(branch2Stream);
return true;
}
JS_PUBLIC_API(void)
JS::ReadableStreamGetDesiredSize(JSObject* streamObj, bool* hasValue, double* value)
{
streamObj->as<ReadableStream>().desiredSize(hasValue, value);
}
JS_PUBLIC_API(bool)
JS::ReadableStreamClose(JSContext* cx, HandleObject streamObj)
{
AssertHeapIsIdle();
CHECK_REQUEST(cx);
assertSameCompartment(cx, streamObj);
Rooted<ReadableStream*> stream(cx, &streamObj->as<ReadableStream>());
return ReadableStream::close(cx, stream);
}
JS_PUBLIC_API(bool)
JS::ReadableStreamEnqueue(JSContext* cx, HandleObject streamObj, HandleValue chunk)
{
AssertHeapIsIdle();
CHECK_REQUEST(cx);
assertSameCompartment(cx, streamObj);
assertSameCompartment(cx, chunk);
Rooted<ReadableStream*> stream(cx, &streamObj->as<ReadableStream>());
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::ReadableByteStreamEnqueueBuffer(JSContext* cx, HandleObject streamObj, HandleObject chunkObj)
{
AssertHeapIsIdle();
CHECK_REQUEST(cx);
assertSameCompartment(cx, streamObj);
assertSameCompartment(cx, chunkObj);
Rooted<ReadableStream*> stream(cx, &streamObj->as<ReadableStream>());
if (stream->mode() != JS::ReadableStreamMode::Byte) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
JSMSG_READABLESTREAM_NOT_BYTE_STREAM_CONTROLLER,
"JS::ReadableByteStreamEnqueueBuffer");
return false;
}
Rooted<ArrayBufferObject*> buffer(cx);
if (chunkObj->is<ArrayBufferViewObject>()) {
bool dummy;
buffer = &JS_GetArrayBufferViewBuffer(cx, chunkObj, &dummy)->as<ArrayBufferObject>();
} else if (chunkObj->is<ArrayBufferObject>()) {
buffer = &chunkObj->as<ArrayBufferObject>();
} else {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
JSMSG_READABLEBYTESTREAMCONTROLLER_BAD_CHUNK,
"JS::ReadableByteStreamEnqueueBuffer");
return false;
}
return ReadableStream::enqueueBuffer(cx, stream, buffer);
}
JS_PUBLIC_API(bool)
JS::ReadableStreamError(JSContext* cx, HandleObject streamObj, HandleValue error)
{
AssertHeapIsIdle();
CHECK_REQUEST(cx);
assertSameCompartment(cx, streamObj);
assertSameCompartment(cx, error);
Rooted<ReadableStream*> stream(cx, &streamObj->as<ReadableStream>());
return js::ReadableStream::error(cx, stream, error);
}
JS_PUBLIC_API(bool)
JS::ReadableStreamReaderIsClosed(const JSObject* reader)
{
return js::ReadableStreamReaderIsClosed(reader);
}
JS_PUBLIC_API(bool)
JS::ReadableStreamReaderCancel(JSContext* cx, HandleObject reader, HandleValue reason)
{
AssertHeapIsIdle();
CHECK_REQUEST(cx);
assertSameCompartment(cx, reader);
assertSameCompartment(cx, reason);
return js::ReadableStreamReaderCancel(cx, reader, reason);
}
JS_PUBLIC_API(bool)
JS::ReadableStreamReaderReleaseLock(JSContext* cx, HandleObject reader)
{
AssertHeapIsIdle();
CHECK_REQUEST(cx);
assertSameCompartment(cx, reader);
return js::ReadableStreamReaderReleaseLock(cx, reader);
}
JS_PUBLIC_API(JSObject*)
JS::ReadableStreamDefaultReaderRead(JSContext* cx, HandleObject readerObj)
{
AssertHeapIsIdle();
CHECK_REQUEST(cx);
assertSameCompartment(cx, readerObj);
Rooted<ReadableStreamDefaultReader*> reader(cx, &readerObj->as<ReadableStreamDefaultReader>());
return js::ReadableStreamDefaultReader::read(cx, reader);
}
JS_PUBLIC_API(JSObject*)
JS::ReadableStreamBYOBReaderRead(JSContext* cx, HandleObject readerObj, HandleObject viewObj)
{
AssertHeapIsIdle();
CHECK_REQUEST(cx);
assertSameCompartment(cx, readerObj);
assertSameCompartment(cx, viewObj);
Rooted<ReadableStreamBYOBReader*> reader(cx, &readerObj->as<ReadableStreamBYOBReader>());
Rooted<ArrayBufferViewObject*> view(cx, &viewObj->as<ArrayBufferViewObject>());
return js::ReadableStreamBYOBReader::read(cx, reader, view);
}
JS_PUBLIC_API(void)
JS::SetAsyncTaskCallbacks(JSContext* cx, JS::StartAsyncTaskCallback start,
JS::FinishAsyncTaskCallback finish)

View File

@ -36,7 +36,6 @@
#include "js/Realm.h"
#include "js/RefCounted.h"
#include "js/RootingAPI.h"
#include "js/Stream.h"
#include "js/TracingAPI.h"
#include "js/UniquePtr.h"
#include "js/Utility.h"

View File

@ -125,7 +125,6 @@ EXPORTS.js += [
'../public/Result.h',
'../public/RootingAPI.h',
'../public/SliceBudget.h',
'../public/Stream.h',
'../public/StructuredClone.h',
'../public/SweepingAPI.h',
'../public/TraceKind.h',

View File

@ -17,8 +17,6 @@
macro(anonymous, anonymous, "anonymous") \
macro(Any, Any, "Any") \
macro(apply, apply, "apply") \
macro(AcquireReadableStreamBYOBReader, AcquireReadableStreamBYOBReader, "AcquireReadableStreamBYOBReader") \
macro(AcquireReadableStreamDefaultReader, AcquireReadableStreamDefaultReader, "AcquireReadableStreamDefaultReader") \
macro(arguments, arguments, "arguments") \
macro(ArrayBufferSpecies, ArrayBufferSpecies, "ArrayBufferSpecies") \
macro(ArrayIterator, ArrayIterator, "Array Iterator") \
@ -299,50 +297,6 @@
macro(prototype, prototype, "prototype") \
macro(proxy, proxy, "proxy") \
macro(raw, raw, "raw") \
macro(ReadableByteStreamControllerGetDesiredSize, \
ReadableByteStreamControllerGetDesiredSize, \
"ReadableByteStreamControllerGetDesiredSize") \
macro(ReadableByteStreamController_close, \
ReadableByteStreamController_close, \
"ReadableByteStreamController_close") \
macro(ReadableByteStreamController_enqueue, \
ReadableByteStreamController_enqueue, \
"ReadableByteStreamController_enqueue") \
macro(ReadableByteStreamController_error, \
ReadableByteStreamController_error, \
"ReadableByteStreamController_error") \
macro(ReadableStreamBYOBReader_cancel, \
ReadableStreamBYOBReader_cancel, \
"ReadableStreamBYOBReader_cancel") \
macro(ReadableStreamBYOBReader_read, \
ReadableStreamBYOBReader_read, \
"ReadableStreamBYOBReader_read") \
macro(ReadableStreamBYOBReader_releaseLock, \
ReadableStreamBYOBReader_releaseLock, \
"ReadableStreamBYOBReader_releaseLock") \
macro(ReadableStream_cancel, ReadableStream_cancel, "ReadableStream_cancel") \
macro(ReadableStreamDefaultControllerGetDesiredSize, \
ReadableStreamDefaultControllerGetDesiredSize, \
"ReadableStreamDefaultControllerGetDesiredSize") \
macro(ReadableStreamDefaultController_close, \
ReadableStreamDefaultController_close, \
"ReadableStreamDefaultController_close") \
macro(ReadableStreamDefaultController_enqueue, \
ReadableStreamDefaultController_enqueue, \
"ReadableStreamDefaultController_enqueue") \
macro(ReadableStreamDefaultController_error, \
ReadableStreamDefaultController_error, \
"ReadableStreamDefaultController_error") \
macro(ReadableStreamDefaultReader_cancel, \
ReadableStreamDefaultReader_cancel, \
"ReadableStreamDefaultReader_cancel") \
macro(ReadableStreamDefaultReader_read, \
ReadableStreamDefaultReader_read, \
"ReadableStreamDefaultReader_read") \
macro(ReadableStreamDefaultReader_releaseLock, \
ReadableStreamDefaultReader_releaseLock, \
"ReadableStreamDefaultReader_releaseLock") \
macro(ReadableStreamTee, ReadableStreamTee, "ReadableStreamTee") \
macro(reason, reason, "reason") \
macro(RegExpBuiltinExec, RegExpBuiltinExec, "RegExpBuiltinExec") \
macro(RegExpFlagsGetter, RegExpFlagsGetter, "RegExpFlagsGetter") \

View File

@ -108,12 +108,6 @@ JSRuntime::JSRuntime(JSRuntime* parentRuntime)
startAsyncTaskCallback(nullptr),
finishAsyncTaskCallback(nullptr),
promiseTasksToDestroy(mutexid::PromiseTaskPtrVector),
readableStreamDataRequestCallback(nullptr),
readableStreamWriteIntoReadRequestCallback(nullptr),
readableStreamCancelCallback(nullptr),
readableStreamClosedCallback(nullptr),
readableStreamErroredCallback(nullptr),
readableStreamFinalizeCallback(nullptr),
hadOutOfMemory(false),
allowRelazificationForTesting(false),
destroyCompartmentCallback(nullptr),

View File

@ -476,13 +476,6 @@ struct JSRuntime : public js::MallocProvider<JSRuntime>
void addUnhandledRejectedPromise(JSContext* cx, js::HandleObject promise);
void removeUnhandledRejectedPromise(JSContext* cx, js::HandleObject promise);
js::UnprotectedData<JS::RequestReadableStreamDataCallback> readableStreamDataRequestCallback;
js::UnprotectedData<JS::WriteIntoReadRequestBufferCallback> readableStreamWriteIntoReadRequestCallback;
js::UnprotectedData<JS::CancelReadableStreamCallback> readableStreamCancelCallback;
js::UnprotectedData<JS::ReadableStreamClosedCallback> readableStreamClosedCallback;
js::UnprotectedData<JS::ReadableStreamErroredCallback> readableStreamErroredCallback;
js::UnprotectedData<JS::ReadableStreamFinalizeCallback> readableStreamFinalizeCallback;
/* Had an out-of-memory error which did not populate an exception. */
mozilla::Atomic<bool> hadOutOfMemory;