| Index: third_party/WebKit/Source/core/streams/ReadableStreamReader.cpp
|
| diff --git a/third_party/WebKit/Source/core/streams/ReadableStreamReader.cpp b/third_party/WebKit/Source/core/streams/ReadableStreamReader.cpp
|
| index 5f7912d26821451de70959d847d2d1fb0e9c6676..e727aa896aa7669cb6ce7d506d4fbb468ea18828 100644
|
| --- a/third_party/WebKit/Source/core/streams/ReadableStreamReader.cpp
|
| +++ b/third_party/WebKit/Source/core/streams/ReadableStreamReader.cpp
|
| @@ -7,6 +7,7 @@
|
|
|
| #include "bindings/core/v8/ExceptionState.h"
|
| #include "bindings/core/v8/ScriptPromiseResolver.h"
|
| +#include "bindings/core/v8/ToV8.h"
|
| #include "bindings/core/v8/V8IteratorResultValue.h"
|
| #include "core/dom/DOMException.h"
|
| #include "core/dom/ExceptionCode.h"
|
| @@ -17,18 +18,16 @@ namespace blink {
|
| ReadableStreamReader::ReadableStreamReader(ExecutionContext* executionContext, ReadableStream* stream)
|
| : ActiveDOMObject(executionContext)
|
| , m_stream(stream)
|
| - , m_stateAfterRelease(ReadableStream::Closed)
|
| , m_closed(new ClosedPromise(executionContext, this, ClosedPromise::Closed))
|
| {
|
| suspendIfNeeded();
|
| ASSERT(m_stream->isLockedTo(nullptr));
|
| m_stream->setReader(this);
|
|
|
| - if (m_stream->stateInternal() == ReadableStream::Closed || m_stream->stateInternal() == ReadableStream::Errored) {
|
| - // If the stream is already closed or errored the created reader
|
| - // should be closed or errored respectively.
|
| - releaseLock();
|
| - }
|
| + if (m_stream->stateInternal() == ReadableStream::Closed)
|
| + m_closed->resolve(ToV8UndefinedGenerator());
|
| + if (m_stream->stateInternal() == ReadableStream::Errored)
|
| + m_closed->reject(m_stream->storedException());
|
| }
|
|
|
| ScriptPromise ReadableStreamReader::closed(ScriptState* scriptState)
|
| @@ -51,27 +50,13 @@ ScriptPromise ReadableStreamReader::cancel(ScriptState* scriptState, ScriptValue
|
| if (isActive())
|
| return m_stream->cancelInternal(scriptState, reason);
|
|
|
| - // A method should return a different promise on each call.
|
| - ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
|
| - ScriptPromise promise = resolver->promise();
|
| - resolver->resolve(closed(scriptState).v8Value());
|
| - return promise;
|
| + return ScriptPromise::reject(scriptState, V8ThrowException::createTypeError(scriptState->isolate(), "the reader is already released"));
|
| }
|
|
|
| ScriptPromise ReadableStreamReader::read(ScriptState* scriptState)
|
| {
|
| - if (!isActive()) {
|
| - ASSERT(m_stateAfterRelease == ReadableStream::Closed || m_stateAfterRelease == ReadableStream::Errored);
|
| - if (m_stateAfterRelease == ReadableStream::Closed) {
|
| - // {value: undefined, done: true}
|
| - return ScriptPromise::cast(scriptState, v8IteratorResultDone(scriptState));
|
| - }
|
| - // A method should return a different promise on each call.
|
| - ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
|
| - ScriptPromise promise = resolver->promise();
|
| - resolver->resolve(closed(scriptState).v8Value());
|
| - return promise;
|
| - }
|
| + if (!isActive())
|
| + return ScriptPromise::reject(scriptState, V8ThrowException::createTypeError(scriptState->isolate(), "the reader is already released"));
|
|
|
| return m_stream->read(scriptState);
|
| }
|
| @@ -94,16 +79,12 @@ void ReadableStreamReader::releaseLock()
|
| return;
|
|
|
| ASSERT(!m_stream->hasPendingReads());
|
| - if (m_stream->stateInternal() == ReadableStream::Closed) {
|
| - m_stateAfterRelease = ReadableStream::Closed;
|
| - m_closed->resolve(ToV8UndefinedGenerator());
|
| - } else if (m_stream->stateInternal() == ReadableStream::Errored) {
|
| - m_stateAfterRelease = ReadableStream::Errored;
|
| - m_closed->reject(m_stream->storedException());
|
| - } else {
|
| - m_stateAfterRelease = ReadableStream::Closed;
|
| - m_closed->resolve(ToV8UndefinedGenerator());
|
| - }
|
| + if (m_stream->stateInternal() != ReadableStream::Readable)
|
| + m_closed->reset();
|
| + // Note: It is generally a bad idea to store world-dependent values
|
| + // (e.g. v8::Object) in a ScriptPromiseProperty, so we use DOMException
|
| + // though the spec says the promise should be rejected with a TypeError.
|
| + m_closed->reject(DOMException::create(AbortError, "the reader is already released"));
|
|
|
| // We call setReader(nullptr) after resolving / rejecting |m_closed|
|
| // because it affects hasPendingActivity.
|
| @@ -111,11 +92,23 @@ void ReadableStreamReader::releaseLock()
|
| ASSERT(!isActive());
|
| }
|
|
|
| +void ReadableStreamReader::close()
|
| +{
|
| + ASSERT(isActive());
|
| + m_closed->resolve(ToV8UndefinedGenerator());
|
| +}
|
| +
|
| +void ReadableStreamReader::error()
|
| +{
|
| + ASSERT(isActive());
|
| + m_closed->reject(m_stream->storedException());
|
| +}
|
| +
|
| bool ReadableStreamReader::hasPendingActivity() const
|
| {
|
| // We need to extend ReadableStreamReader's wrapper's life while it is
|
| // active in order to call resolve / reject on ScriptPromiseProperties.
|
| - return isActive();
|
| + return isActive() && m_stream->stateInternal() == ReadableStream::Readable;
|
| }
|
|
|
| void ReadableStreamReader::stop()
|
|
|