Bug 1503006 - Part 9: Code motion only. Move some static Stream methods immediately after their sole callers. r=tcampbell

Depends on D10433

Differential Revision: https://phabricator.services.mozilla.com/D10434

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Jason Orendorff 2018-11-02 21:08:02 +00:00
parent 387184986d
commit bc8918eb92
2 changed files with 243 additions and 243 deletions

View File

@ -49,6 +49,14 @@ ReadableStream::mode() const
: JS::ReadableStreamMode::Byte;
}
uint8_t
ReadableStream::embeddingFlags() const
{
uint8_t flags = controller()->flags() >> ReadableStreamController::EmbeddingFlagsOffset;
MOZ_ASSERT_IF(flags, mode() == JS::ReadableStreamMode::ExternalSource);
return flags;
}
/**
* Checks that |obj| is an unwrapped instance of T or throws an error.
*
@ -4111,248 +4119,6 @@ ValidateAndNormalizeQueuingStrategy(JSContext* cx, HandleValue size,
/*** API entry points ****************************************************************************/
MOZ_MUST_USE bool
js::ReadableStreamReaderCancel(JSContext* cx, HandleObject readerObj, HandleValue reason)
{
Rooted<ReadableStreamReader*> reader(cx, &readerObj->as<ReadableStreamReader>());
Rooted<ReadableStream*> stream(cx);
if (!UnwrapStreamFromReader(cx, reader, &stream)) {
return false;
}
return ReadableStreamReaderGenericCancel(cx, reader, reason);
}
MOZ_MUST_USE bool
js::ReadableStreamReaderReleaseLock(JSContext* cx, HandleObject readerObj)
{
Rooted<ReadableStreamReader*> reader(cx, &readerObj->as<ReadableStreamReader>());
Rooted<ReadableStream*> stream(cx);
if (!UnwrapStreamFromReader(cx, reader, &stream)) {
return false;
}
MOZ_ASSERT(ReadableStreamGetNumReadRequests(stream) == 0);
return ReadableStreamReaderGenericRelease(cx, reader);
}
MOZ_MUST_USE bool
ReadableStream::enqueue(JSContext* cx, Handle<ReadableStream*> stream, HandleValue chunk)
{
Rooted<ReadableStreamDefaultController*> controller(cx);
controller = &stream->controller()->as<ReadableStreamDefaultController>();
MOZ_ASSERT(!controller->closeRequested());
MOZ_ASSERT(stream->readable());
return ReadableStreamDefaultControllerEnqueue(cx, controller, chunk);
}
void
ReadableStream::desiredSize(bool* hasSize, double* size) const
{
if (errored()) {
*hasSize = false;
return;
}
*hasSize = true;
if (closed()) {
*size = 0;
return;
}
*size = ReadableStreamControllerGetDesiredSizeUnchecked(controller());
}
/*static */ bool
ReadableStream::getExternalSource(JSContext* cx, Handle<ReadableStream*> stream, void** source)
{
MOZ_ASSERT(stream->mode() == JS::ReadableStreamMode::ExternalSource);
if (stream->locked()) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_READABLESTREAM_LOCKED);
return false;
}
if (!stream->readable()) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
JSMSG_READABLESTREAMCONTROLLER_NOT_READABLE,
"ReadableStreamGetExternalUnderlyingSource");
return false;
}
auto controller = &stream->controller()->as<ReadableByteStreamController>();
controller->setSourceLocked();
*source = controller->underlyingSource().toPrivate();
return true;
}
void
ReadableStream::releaseExternalSource()
{
MOZ_ASSERT(mode() == JS::ReadableStreamMode::ExternalSource);
MOZ_ASSERT(locked());
MOZ_ASSERT(controller()->sourceLocked());
controller()->clearSourceLocked();
}
uint8_t
ReadableStream::embeddingFlags() const
{
uint8_t flags = controller()->flags() >> ReadableStreamController::EmbeddingFlagsOffset;
MOZ_ASSERT_IF(flags, mode() == JS::ReadableStreamMode::ExternalSource);
return flags;
}
// Streams spec, obsolete (previously 3.10.4.4. steps 1-3 and 3.12.8. steps 8-9)
//
// Adapted to handling updates signaled by the embedding for streams with
// external underlying sources.
//
// The remaining steps of those two functions perform checks and asserts that
// don't apply to streams with external underlying sources.
MOZ_MUST_USE bool
ReadableStream::updateDataAvailableFromSource(JSContext* cx, Handle<ReadableStream*> stream,
uint32_t availableData)
{
Rooted<ReadableByteStreamController*> controller(cx,
&stream->controller()->as<ReadableByteStreamController>());
// Step 2: If this.[[closeRequested]] is true, throw a TypeError exception.
if (controller->closeRequested()) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
JSMSG_READABLESTREAMCONTROLLER_CLOSED, "enqueue");
return false;
}
// Step 3: If this.[[controlledReadableStream]].[[state]] is not "readable",
// throw a TypeError exception.
if (!controller->stream()->readable()) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
JSMSG_READABLESTREAMCONTROLLER_NOT_READABLE, "enqueue");
return false;
}
controller->clearPullFlags();
#if DEBUG
uint32_t oldAvailableData =
controller->getFixedSlot(StreamController::Slot_TotalSize).toInt32();
#endif // DEBUG
controller->setQueueTotalSize(availableData);
// Step 8.a: If ! ReadableStreamGetNumReadRequests(stream) is 0,
// Reordered because for externally-sourced streams it applies regardless
// of reader type.
if (ReadableStreamGetNumReadRequests(stream) == 0) {
return true;
}
// Step 8: If ! ReadableStreamHasDefaultReader(stream) is true
ReaderMode readerMode;
if (!ReadableStreamGetReaderMode(cx, stream, &readerMode)) {
return false;
}
if (readerMode == ReaderMode::Default) {
// Step b: Otherwise,
// Step i: Assert: controller.[[queue]] is empty.
MOZ_ASSERT(oldAvailableData == 0);
// Step ii: Let transferredView be
// ! Construct(%Uint8Array%, transferredBuffer, byteOffset, byteLength).
JSObject* viewObj = JS_NewUint8Array(cx, availableData);
Rooted<ArrayBufferViewObject*> transferredView(cx, &viewObj->as<ArrayBufferViewObject>());
if (!transferredView) {
return false;
}
void* underlyingSource = controller->underlyingSource().toPrivate();
size_t bytesWritten;
{
JS::AutoSuppressGCAnalysis suppressGC(cx);
JS::AutoCheckCannotGC noGC;
bool dummy;
void* buffer = JS_GetArrayBufferViewData(transferredView, &dummy, noGC);
auto cb = cx->runtime()->readableStreamWriteIntoReadRequestCallback;
MOZ_ASSERT(cb);
// TODO: use bytesWritten to correctly update the request's state.
// TODO: make cross-compartment safe.
cb(cx, stream, underlyingSource, stream->embeddingFlags(), buffer,
availableData, &bytesWritten);
}
// Step iii: Perform ! ReadableStreamFulfillReadRequest(stream, transferredView, false).
RootedValue chunk(cx, ObjectValue(*transferredView));
if (!ReadableStreamFulfillReadOrReadIntoRequest(cx, stream, chunk, false)) {
return false;
}
controller->setQueueTotalSize(availableData - bytesWritten);
} else {
// Step b: Otherwise,
// Step i: Assert: ! IsReadableStreamLocked(stream) is false.
MOZ_ASSERT(!stream->locked());
// Step ii: Perform
// ! ReadableByteStreamControllerEnqueueChunkToQueue(controller,
// transferredBuffer,
// byteOffset,
// byteLength).
// (Not needed for external underlying sources.)
}
return true;
}
MOZ_MUST_USE bool
ReadableStream::close(JSContext* cx, Handle<ReadableStream*> stream)
{
Rooted<ReadableStreamController*> controllerObj(cx, stream->controller());
if (!VerifyControllerStateForClosing(cx, controllerObj)) {
return false;
}
if (controllerObj->is<ReadableStreamDefaultController>()) {
Rooted<ReadableStreamDefaultController*> controller(cx);
controller = &controllerObj->as<ReadableStreamDefaultController>();
return ReadableStreamDefaultControllerClose(cx, controller);
}
Rooted<ReadableByteStreamController*> controller(cx);
controller = &controllerObj->as<ReadableByteStreamController>();
return ReadableByteStreamControllerClose(cx, controller);
}
MOZ_MUST_USE bool
ReadableStream::error(JSContext* cx, Handle<ReadableStream*> stream, HandleValue reason)
{
// Step 3: If stream.[[state]] is not "readable", throw a TypeError exception.
if (!stream->readable()) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
JSMSG_READABLESTREAMCONTROLLER_NOT_READABLE, "error");
return false;
}
// Step 4: Perform ! ReadableStreamDefaultControllerError(this, e).
Rooted<ReadableStreamController*> controller(cx, stream->controller());
return ReadableStreamControllerError(cx, controller, reason);
}
MOZ_MUST_USE bool
ReadableStream::tee(JSContext* cx, Handle<ReadableStream*> stream, bool cloneForBranch2,
MutableHandle<ReadableStream*> branch1Stream,
MutableHandle<ReadableStream*> branch2Stream)
{
return ReadableStreamTee(cx, stream, false, branch1Stream, branch2Stream);
}
MOZ_MUST_USE ReadableStreamReader*
ReadableStream::getReader(JSContext* cx, Handle<ReadableStream*> stream,
JS::ReadableStreamReaderMode mode)
{
return CreateReadableStreamDefaultReader(cx, stream);
}
JS_FRIEND_API(JSObject*)
js::UnwrapReadableStream(JSObject* obj)
{
@ -4557,6 +4323,13 @@ JS::ReadableStreamGetReader(JSContext* cx, HandleObject streamObj, ReadableStrea
return result;
}
MOZ_MUST_USE ReadableStreamReader*
ReadableStream::getReader(JSContext* cx, Handle<ReadableStream*> stream,
JS::ReadableStreamReaderMode mode)
{
return CreateReadableStreamDefaultReader(cx, stream);
}
JS_PUBLIC_API(bool)
JS::ReadableStreamGetExternalUnderlyingSource(JSContext* cx, HandleObject streamObj, void** source)
{
@ -4570,6 +4343,27 @@ JS::ReadableStreamGetExternalUnderlyingSource(JSContext* cx, HandleObject stream
return ReadableStream::getExternalSource(cx, stream, source);
}
/*static */ bool
ReadableStream::getExternalSource(JSContext* cx, Handle<ReadableStream*> stream, void** source)
{
MOZ_ASSERT(stream->mode() == JS::ReadableStreamMode::ExternalSource);
if (stream->locked()) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_READABLESTREAM_LOCKED);
return false;
}
if (!stream->readable()) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
JSMSG_READABLESTREAMCONTROLLER_NOT_READABLE,
"ReadableStreamGetExternalUnderlyingSource");
return false;
}
auto controller = &stream->controller()->as<ReadableByteStreamController>();
controller->setSourceLocked();
*source = controller->underlyingSource().toPrivate();
return true;
}
JS_PUBLIC_API(bool)
JS::ReadableStreamReleaseExternalUnderlyingSource(JSContext* cx, HandleObject streamObj)
{
@ -4581,6 +4375,15 @@ JS::ReadableStreamReleaseExternalUnderlyingSource(JSContext* cx, HandleObject st
return true;
}
void
ReadableStream::releaseExternalSource()
{
MOZ_ASSERT(mode() == JS::ReadableStreamMode::ExternalSource);
MOZ_ASSERT(locked());
MOZ_ASSERT(controller()->sourceLocked());
controller()->clearSourceLocked();
}
JS_PUBLIC_API(bool)
JS::ReadableStreamUpdateDataAvailableFromSource(JSContext* cx, JS::HandleObject streamObj,
uint32_t availableData)
@ -4595,6 +4398,108 @@ JS::ReadableStreamUpdateDataAvailableFromSource(JSContext* cx, JS::HandleObject
return ReadableStream::updateDataAvailableFromSource(cx, stream, availableData);
}
// Streams spec, obsolete (previously 3.10.4.4. steps 1-3 and 3.12.8. steps 8-9)
//
// Adapted to handling updates signaled by the embedding for streams with
// external underlying sources.
//
// The remaining steps of those two functions perform checks and asserts that
// don't apply to streams with external underlying sources.
MOZ_MUST_USE bool
ReadableStream::updateDataAvailableFromSource(JSContext* cx, Handle<ReadableStream*> stream,
uint32_t availableData)
{
Rooted<ReadableByteStreamController*> controller(cx,
&stream->controller()->as<ReadableByteStreamController>());
// Step 2: If this.[[closeRequested]] is true, throw a TypeError exception.
if (controller->closeRequested()) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
JSMSG_READABLESTREAMCONTROLLER_CLOSED, "enqueue");
return false;
}
// Step 3: If this.[[controlledReadableStream]].[[state]] is not "readable",
// throw a TypeError exception.
if (!controller->stream()->readable()) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
JSMSG_READABLESTREAMCONTROLLER_NOT_READABLE, "enqueue");
return false;
}
controller->clearPullFlags();
#if DEBUG
uint32_t oldAvailableData =
controller->getFixedSlot(StreamController::Slot_TotalSize).toInt32();
#endif // DEBUG
controller->setQueueTotalSize(availableData);
// Step 8.a: If ! ReadableStreamGetNumReadRequests(stream) is 0,
// Reordered because for externally-sourced streams it applies regardless
// of reader type.
if (ReadableStreamGetNumReadRequests(stream) == 0) {
return true;
}
// Step 8: If ! ReadableStreamHasDefaultReader(stream) is true
ReaderMode readerMode;
if (!ReadableStreamGetReaderMode(cx, stream, &readerMode)) {
return false;
}
if (readerMode == ReaderMode::Default) {
// Step b: Otherwise,
// Step i: Assert: controller.[[queue]] is empty.
MOZ_ASSERT(oldAvailableData == 0);
// Step ii: Let transferredView be
// ! Construct(%Uint8Array%, transferredBuffer, byteOffset, byteLength).
JSObject* viewObj = JS_NewUint8Array(cx, availableData);
Rooted<ArrayBufferViewObject*> transferredView(cx, &viewObj->as<ArrayBufferViewObject>());
if (!transferredView) {
return false;
}
void* underlyingSource = controller->underlyingSource().toPrivate();
size_t bytesWritten;
{
JS::AutoSuppressGCAnalysis suppressGC(cx);
JS::AutoCheckCannotGC noGC;
bool dummy;
void* buffer = JS_GetArrayBufferViewData(transferredView, &dummy, noGC);
auto cb = cx->runtime()->readableStreamWriteIntoReadRequestCallback;
MOZ_ASSERT(cb);
// TODO: use bytesWritten to correctly update the request's state.
// TODO: make cross-compartment safe.
cb(cx, stream, underlyingSource, stream->embeddingFlags(), buffer,
availableData, &bytesWritten);
}
// Step iii: Perform ! ReadableStreamFulfillReadRequest(stream, transferredView, false).
RootedValue chunk(cx, ObjectValue(*transferredView));
if (!ReadableStreamFulfillReadOrReadIntoRequest(cx, stream, chunk, false)) {
return false;
}
controller->setQueueTotalSize(availableData - bytesWritten);
} else {
// Step b: Otherwise,
// Step i: Assert: ! IsReadableStreamLocked(stream) is false.
MOZ_ASSERT(!stream->locked());
// Step ii: Perform
// ! ReadableByteStreamControllerEnqueueChunkToQueue(controller,
// transferredBuffer,
// byteOffset,
// byteLength).
// (Not needed for external underlying sources.)
}
return true;
}
JS_PUBLIC_API(bool)
JS::ReadableStreamTee(JSContext* cx, HandleObject streamObj,
MutableHandleObject branch1Obj, MutableHandleObject branch2Obj)
@ -4619,6 +4524,14 @@ JS::ReadableStreamTee(JSContext* cx, HandleObject streamObj,
return true;
}
MOZ_MUST_USE bool
ReadableStream::tee(JSContext* cx, Handle<ReadableStream*> stream, bool cloneForBranch2,
MutableHandle<ReadableStream*> branch1Stream,
MutableHandle<ReadableStream*> branch2Stream)
{
return ReadableStreamTee(cx, stream, false, branch1Stream, branch2Stream);
}
JS_PUBLIC_API(bool)
JS::ReadableStreamGetDesiredSize(JSContext* cx, JSObject* streamObj, bool* hasValue, double* value)
{
@ -4630,6 +4543,24 @@ JS::ReadableStreamGetDesiredSize(JSContext* cx, JSObject* streamObj, bool* hasVa
return true;
}
void
ReadableStream::desiredSize(bool* hasSize, double* size) const
{
if (errored()) {
*hasSize = false;
return;
}
*hasSize = true;
if (closed()) {
*size = 0;
return;
}
*size = ReadableStreamControllerGetDesiredSizeUnchecked(controller());
}
JS_PUBLIC_API(bool)
JS::ReadableStreamClose(JSContext* cx, HandleObject streamObj)
{
@ -4643,6 +4574,25 @@ JS::ReadableStreamClose(JSContext* cx, HandleObject streamObj)
return ReadableStream::close(cx, stream);
}
MOZ_MUST_USE bool
ReadableStream::close(JSContext* cx, Handle<ReadableStream*> stream)
{
Rooted<ReadableStreamController*> controllerObj(cx, stream->controller());
if (!VerifyControllerStateForClosing(cx, controllerObj)) {
return false;
}
if (controllerObj->is<ReadableStreamDefaultController>()) {
Rooted<ReadableStreamDefaultController*> controller(cx);
controller = &controllerObj->as<ReadableStreamDefaultController>();
return ReadableStreamDefaultControllerClose(cx, controller);
}
Rooted<ReadableByteStreamController*> controller(cx);
controller = &controllerObj->as<ReadableByteStreamController>();
return ReadableByteStreamControllerClose(cx, controller);
}
JS_PUBLIC_API(bool)
JS::ReadableStreamEnqueue(JSContext* cx, HandleObject streamObj, HandleValue chunk)
{
@ -4663,6 +4613,18 @@ JS::ReadableStreamEnqueue(JSContext* cx, HandleObject streamObj, HandleValue chu
return ReadableStream::enqueue(cx, stream, chunk);
}
MOZ_MUST_USE bool
ReadableStream::enqueue(JSContext* cx, Handle<ReadableStream*> stream, HandleValue chunk)
{
Rooted<ReadableStreamDefaultController*> controller(cx);
controller = &stream->controller()->as<ReadableStreamDefaultController>();
MOZ_ASSERT(!controller->closeRequested());
MOZ_ASSERT(stream->readable());
return ReadableStreamDefaultControllerEnqueue(cx, controller, chunk);
}
JS_PUBLIC_API(bool)
JS::ReadableStreamError(JSContext* cx, HandleObject streamObj, HandleValue error)
{
@ -4677,6 +4639,21 @@ JS::ReadableStreamError(JSContext* cx, HandleObject streamObj, HandleValue error
return js::ReadableStream::error(cx, stream, error);
}
MOZ_MUST_USE bool
ReadableStream::error(JSContext* cx, Handle<ReadableStream*> stream, HandleValue reason)
{
// Step 3: If stream.[[state]] is not "readable", throw a TypeError exception.
if (!stream->readable()) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
JSMSG_READABLESTREAMCONTROLLER_NOT_READABLE, "error");
return false;
}
// Step 4: Perform ! ReadableStreamDefaultControllerError(this, e).
Rooted<ReadableStreamController*> controller(cx, stream->controller());
return ReadableStreamControllerError(cx, controller, reason);
}
JS_PUBLIC_API(bool)
JS::ReadableStreamReaderIsClosed(JSContext* cx, HandleObject readerObj, bool* result)
{
@ -4702,6 +4679,17 @@ JS::ReadableStreamReaderCancel(JSContext* cx, HandleObject readerObj, HandleValu
return js::ReadableStreamReaderCancel(cx, reader, reason);
}
MOZ_MUST_USE bool
js::ReadableStreamReaderCancel(JSContext* cx, HandleObject readerObj, HandleValue reason)
{
Rooted<ReadableStreamReader*> reader(cx, &readerObj->as<ReadableStreamReader>());
Rooted<ReadableStream*> stream(cx);
if (!UnwrapStreamFromReader(cx, reader, &stream)) {
return false;
}
return ReadableStreamReaderGenericCancel(cx, reader, reason);
}
JS_PUBLIC_API(bool)
JS::ReadableStreamReaderReleaseLock(JSContext* cx, HandleObject readerObj)
{
@ -4715,6 +4703,18 @@ JS::ReadableStreamReaderReleaseLock(JSContext* cx, HandleObject readerObj)
return js::ReadableStreamReaderReleaseLock(cx, reader);
}
MOZ_MUST_USE bool
js::ReadableStreamReaderReleaseLock(JSContext* cx, HandleObject readerObj)
{
Rooted<ReadableStreamReader*> reader(cx, &readerObj->as<ReadableStreamReader>());
Rooted<ReadableStream*> stream(cx);
if (!UnwrapStreamFromReader(cx, reader, &stream)) {
return false;
}
MOZ_ASSERT(ReadableStreamGetNumReadRequests(stream) == 0);
return ReadableStreamReaderGenericRelease(cx, reader);
}
JS_PUBLIC_API(JSObject*)
JS::ReadableStreamDefaultReaderRead(JSContext* cx, HandleObject readerObj)
{

View File

@ -83,6 +83,7 @@ class ReadableStream : public NativeObject
void desiredSize(bool* hasSize, double* size) const;
JS::ReadableStreamMode mode() const;
uint8_t embeddingFlags() const;
static MOZ_MUST_USE bool close(JSContext* cx, Handle<ReadableStream*> stream);
static MOZ_MUST_USE JSObject* cancel(JSContext* cx, Handle<ReadableStream*> stream,
@ -104,7 +105,6 @@ class ReadableStream : public NativeObject
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);