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() |