| Index: Source/modules/fetch/Body.cpp | 
| diff --git a/Source/modules/fetch/Body.cpp b/Source/modules/fetch/Body.cpp | 
| index 902ed48e0465637cdb9ae9a48e8bff993139f3a0..18b88f1041d43cf147f43194e3c372ebf20d94ce 100644 | 
| --- a/Source/modules/fetch/Body.cpp | 
| +++ b/Source/modules/fetch/Body.cpp | 
| @@ -15,194 +15,94 @@ | 
| #include "core/dom/ExceptionCode.h" | 
| #include "core/fileapi/Blob.h" | 
| #include "core/frame/UseCounter.h" | 
| -#include "core/streams/ReadableByteStream.h" | 
| -#include "core/streams/ReadableByteStreamReader.h" | 
| -#include "core/streams/UnderlyingSource.h" | 
| #include "modules/fetch/BodyStreamBuffer.h" | 
| -#include "modules/fetch/DataConsumerHandleUtil.h" | 
| -#include "modules/fetch/FetchBlobDataConsumerHandle.h" | 
| +#include "modules/fetch/FetchDataLoader.h" | 
| +#include "wtf/PassRefPtr.h" | 
| +#include "wtf/RefPtr.h" | 
|  | 
| namespace blink { | 
|  | 
| -class Body::ReadableStreamSource : public GarbageCollectedFinalized<Body::ReadableStreamSource>, public UnderlyingSource, public WebDataConsumerHandle::Client, public BodyStreamBuffer::DrainingStreamNotificationClient { | 
| -    USING_GARBAGE_COLLECTED_MIXIN(ReadableStreamSource); | 
| +namespace { | 
| + | 
| +class BodyConsumerBase : public GarbageCollectedFinalized<BodyConsumerBase>, public FetchDataLoader::Client { | 
| +    WTF_MAKE_NONCOPYABLE(BodyConsumerBase); | 
| +    USING_GARBAGE_COLLECTED_MIXIN(BodyConsumerBase); | 
| public: | 
| -    ReadableStreamSource(ExecutionContext* executionContext, BodyStreamBuffer* buffer) | 
| -        : m_bodyStreamBuffer(buffer) | 
| -        , m_streamNeedsMore(false) | 
| -#if ENABLE(ASSERT) | 
| -        , m_drained(false) | 
| -        , m_isCloseCalled(false) | 
| -        , m_isErrorCalled(false) | 
| -#endif | 
| +    explicit BodyConsumerBase(PassRefPtrWillBeRawPtr<ScriptPromiseResolver> resolver) : m_resolver(resolver) {} | 
| +    PassRefPtrWillBeRawPtr<ScriptPromiseResolver> resolver() { return m_resolver; } | 
| +    void didFetchDataLoadFailed() override | 
| { | 
| -        if (m_bodyStreamBuffer) | 
| -            obtainReader(); | 
| +        ScriptState::Scope scope(resolver()->scriptState()); | 
| +        m_resolver->reject(V8ThrowException::createTypeError(resolver()->scriptState()->isolate(), "Failed to fetch")); | 
| } | 
|  | 
| -    ~ReadableStreamSource() override { } | 
| - | 
| -    void startStream(ReadableByteStream* stream) | 
| -    { | 
| -        m_stream = stream; | 
| -        stream->didSourceStart(); | 
| -        if (!m_bodyStreamBuffer) | 
| -            close(); | 
| -    } | 
| -    // Creates a new BodyStreamBuffer to drain the data. | 
| -    PassOwnPtr<DrainingBodyStreamBuffer> createDrainingStream() | 
| +    DEFINE_INLINE_TRACE() | 
| { | 
| -        if (!m_bodyStreamBuffer) | 
| -            return nullptr; | 
| - | 
| -#if ENABLE(ASSERT) | 
| -        ASSERT(!m_drained); | 
| -        m_drained = true; | 
| -        ASSERT(!(m_stream->stateInternal() == ReadableByteStream::Closed && !m_isCloseCalled)); | 
| -        ASSERT(!(m_stream->stateInternal() == ReadableByteStream::Errored && !m_isErrorCalled)); | 
| -#endif | 
| - | 
| -        m_reader.clear(); | 
| -        return DrainingBodyStreamBuffer::create(m_bodyStreamBuffer, this); | 
| +        visitor->trace(m_resolver); | 
| +        FetchDataLoader::Client::trace(visitor); | 
| } | 
|  | 
| -    DEFINE_INLINE_VIRTUAL_TRACE() | 
| -    { | 
| -        visitor->trace(m_bodyStreamBuffer); | 
| -        visitor->trace(m_stream); | 
| -        UnderlyingSource::trace(visitor); | 
| -        DrainingStreamNotificationClient::trace(visitor); | 
| -    } | 
| +private: | 
| +    RefPtrWillBeMember<ScriptPromiseResolver> m_resolver; | 
| +}; | 
|  | 
| -    void close() | 
| -    { | 
| -        m_reader.clear(); | 
| -        m_stream->close(); | 
| -        if (m_bodyStreamBuffer) | 
| -            m_bodyStreamBuffer = BodyStreamBuffer::createEmpty(); | 
| -#if ENABLE(ASSERT) | 
| -        m_isCloseCalled = true; | 
| -#endif | 
| -    } | 
| +class BodyBlobConsumer final : public BodyConsumerBase { | 
| +    WTF_MAKE_NONCOPYABLE(BodyBlobConsumer); | 
| +public: | 
| +    explicit BodyBlobConsumer(PassRefPtrWillBeRawPtr<ScriptPromiseResolver> resolver) : BodyConsumerBase(resolver) {} | 
|  | 
| -    void error() | 
| +    void didFetchDataLoadedBlobHandle(PassRefPtr<BlobDataHandle> blobDataHandle) override | 
| { | 
| -        m_reader.clear(); | 
| -        m_stream->error(DOMException::create(NetworkError, "network error")); | 
| -        if (m_bodyStreamBuffer) | 
| -            m_bodyStreamBuffer = BodyStreamBuffer::create(createFetchDataConsumerHandleFromWebHandle(createUnexpectedErrorDataConsumerHandle())); | 
| -#if ENABLE(ASSERT) | 
| -        m_isErrorCalled = true; | 
| -#endif | 
| +        resolver()->resolve(Blob::create(blobDataHandle)); | 
| } | 
| +}; | 
|  | 
| -private: | 
| -    void obtainReader() | 
| -    { | 
| -        m_reader = m_bodyStreamBuffer->handle()->obtainReader(this); | 
| -    } | 
| +class BodyArrayBufferConsumer final : public BodyConsumerBase { | 
| +    WTF_MAKE_NONCOPYABLE(BodyArrayBufferConsumer); | 
| +public: | 
| +    explicit BodyArrayBufferConsumer(PassRefPtrWillBeRawPtr<ScriptPromiseResolver> resolver) : BodyConsumerBase(resolver) {} | 
|  | 
| -    void didFetchDataLoadFinishedFromDrainingStream() | 
| +    void didFetchDataLoadedArrayBuffer(PassRefPtr<DOMArrayBuffer> arrayBuffer) override | 
| { | 
| -        ASSERT(m_bodyStreamBuffer); | 
| -        ASSERT(m_drained); | 
| - | 
| -#if ENABLE(ASSERT) | 
| -        m_drained = false; | 
| -#endif | 
| -        obtainReader(); | 
| -        // We have to call didGetReadable() now to call close()/error() if | 
| -        // necessary. | 
| -        // didGetReadable() would be called asynchronously, but it is too late. | 
| -        didGetReadable(); | 
| +        resolver()->resolve(arrayBuffer); | 
| } | 
| +}; | 
|  | 
| -    void didGetReadable() override | 
| -    { | 
| -        if (!m_streamNeedsMore) { | 
| -            // Perform zero-length read to call close()/error() early. | 
| -            size_t readSize; | 
| -            WebDataConsumerHandle::Result result = m_reader->read(nullptr, 0, WebDataConsumerHandle::FlagNone, &readSize); | 
| -            switch (result) { | 
| -            case WebDataConsumerHandle::Ok: | 
| -            case WebDataConsumerHandle::ShouldWait: | 
| -                return; | 
| -            case WebDataConsumerHandle::Done: | 
| -                close(); | 
| -                return; | 
| -            case WebDataConsumerHandle::Busy: | 
| -            case WebDataConsumerHandle::ResourceExhausted: | 
| -            case WebDataConsumerHandle::UnexpectedError: | 
| -                error(); | 
| -                return; | 
| -            } | 
| -        } | 
| - | 
| -        processData(); | 
| -    } | 
| +class BodyTextConsumer final : public BodyConsumerBase { | 
| +    WTF_MAKE_NONCOPYABLE(BodyTextConsumer); | 
| +public: | 
| +    explicit BodyTextConsumer(PassRefPtrWillBeRawPtr<ScriptPromiseResolver> resolver) : BodyConsumerBase(resolver) {} | 
|  | 
| -    // UnderlyingSource functions. | 
| -    void pullSource() override | 
| +    void didFetchDataLoadedString(const String& string) override | 
| { | 
| -        ASSERT(!m_streamNeedsMore); | 
| -        m_streamNeedsMore = true; | 
| - | 
| -        ASSERT(!m_drained); | 
| - | 
| -        processData(); | 
| +        resolver()->resolve(string); | 
| } | 
| +}; | 
|  | 
| -    ScriptPromise cancelSource(ScriptState* scriptState, ScriptValue reason) override | 
| -    { | 
| -        close(); | 
| -        return ScriptPromise::cast(scriptState, v8::Undefined(scriptState->isolate())); | 
| -    } | 
| +class BodyJsonConsumer final : public BodyConsumerBase { | 
| +    WTF_MAKE_NONCOPYABLE(BodyJsonConsumer); | 
| +public: | 
| +    explicit BodyJsonConsumer(PassRefPtrWillBeRawPtr<ScriptPromiseResolver> resolver) : BodyConsumerBase(resolver) {} | 
|  | 
| -    // Reads data and writes the data to |m_stream|, as long as data are | 
| -    // available and the stream has pending reads. | 
| -    void processData() | 
| +    void didFetchDataLoadedString(const String& string) override | 
| { | 
| -        ASSERT(m_reader); | 
| -        while (m_streamNeedsMore) { | 
| -            const void* buffer; | 
| -            size_t available; | 
| -            WebDataConsumerHandle::Result result = m_reader->beginRead(&buffer, WebDataConsumerHandle::FlagNone, &available); | 
| -            switch (result) { | 
| -            case WebDataConsumerHandle::Ok: | 
| -                m_streamNeedsMore = m_stream->enqueue(DOMUint8Array::create(static_cast<const unsigned char*>(buffer), available)); | 
| -                m_reader->endRead(available); | 
| -                break; | 
| - | 
| -            case WebDataConsumerHandle::Done: | 
| -                close(); | 
| -                return; | 
| - | 
| -            case WebDataConsumerHandle::ShouldWait: | 
| -                return; | 
| - | 
| -            case WebDataConsumerHandle::Busy: | 
| -            case WebDataConsumerHandle::ResourceExhausted: | 
| -            case WebDataConsumerHandle::UnexpectedError: | 
| -                error(); | 
| -                return; | 
| -            } | 
| -        } | 
| +        if (!resolver()->executionContext() || resolver()->executionContext()->activeDOMObjectsAreStopped()) | 
| +            return; | 
| +        ScriptState::Scope scope(resolver()->scriptState()); | 
| +        v8::Isolate* isolate = resolver()->scriptState()->isolate(); | 
| +        v8::Local<v8::String> inputString = v8String(isolate, string); | 
| +        v8::TryCatch trycatch; | 
| +        v8::Local<v8::Value> parsed; | 
| +        if (v8Call(v8::JSON::Parse(isolate, inputString), parsed, trycatch)) | 
| +            resolver()->resolve(parsed); | 
| +        else | 
| +            resolver()->reject(trycatch.Exception()); | 
| } | 
| - | 
| -    // Source of data. | 
| -    Member<BodyStreamBuffer> m_bodyStreamBuffer; | 
| -    OwnPtr<FetchDataConsumerHandle::Reader> m_reader; | 
| - | 
| -    Member<ReadableByteStream> m_stream; | 
| -    bool m_streamNeedsMore; | 
| -#if ENABLE(ASSERT) | 
| -    bool m_drained; | 
| -    bool m_isCloseCalled; | 
| -    bool m_isErrorCalled; | 
| -#endif | 
| }; | 
|  | 
| -ScriptPromise Body::readAsync(ScriptState* scriptState, ResponseType type) | 
| +} // namespace | 
| + | 
| +ScriptPromise Body::arrayBuffer(ScriptState* scriptState) | 
| { | 
| if (bodyUsed()) | 
| return ScriptPromise::reject(scriptState, V8ThrowException::createTypeError(scriptState->isolate(), "Already read")); | 
| @@ -213,256 +113,82 @@ ScriptPromise Body::readAsync(ScriptState* scriptState, ResponseType type) | 
| // first check the ExecutionContext and return immediately if it's already | 
| // gone (which means that the V8::TerminateExecution() signal has been sent | 
| // to this worker thread). | 
| -    ExecutionContext* executionContext = scriptState->executionContext(); | 
| -    if (!executionContext) | 
| +    if (!scriptState->executionContext()) | 
| return ScriptPromise(); | 
|  | 
| -    lockBody(); | 
| -    m_responseType = type; | 
| - | 
| -    ASSERT(!m_resolver); | 
| -    m_resolver = ScriptPromiseResolver::create(scriptState); | 
| -    ScriptPromise promise = m_resolver->promise(); | 
| - | 
| -    if (m_stream->stateInternal() == ReadableStream::Closed) { | 
| -        resolveWithEmptyDataSynchronously(); | 
| -    } else if (m_stream->stateInternal() == ReadableStream::Errored) { | 
| -        m_resolver->reject(m_stream->storedException()); | 
| -        m_resolver.clear(); | 
| -    } else { | 
| -        readAsyncFromDrainingBodyStreamBuffer(createDrainingStream(), mimeType()); | 
| -    } | 
| +    RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState); | 
| +    ScriptPromise promise = resolver->promise(); | 
| +    bodyBuffer()->startLoading(scriptState->executionContext(), FetchDataLoader::createLoaderAsArrayBuffer(), new BodyArrayBufferConsumer(resolver)); | 
| return promise; | 
| } | 
|  | 
| -void Body::resolveWithEmptyDataSynchronously() | 
| -{ | 
| -    // We resolve the resolver manually in order not to use member | 
| -    // variables. | 
| -    switch (m_responseType) { | 
| -    case ResponseAsArrayBuffer: | 
| -        m_resolver->resolve(DOMArrayBuffer::create(nullptr, 0)); | 
| -        break; | 
| -    case ResponseAsBlob: { | 
| -        OwnPtr<BlobData> blobData = BlobData::create(); | 
| -        blobData->setContentType(mimeType()); | 
| -        m_resolver->resolve(Blob::create(BlobDataHandle::create(blobData.release(), 0))); | 
| -        break; | 
| -    } | 
| -    case ResponseAsText: | 
| -        m_resolver->resolve(String()); | 
| -        break; | 
| -    case ResponseAsFormData: | 
| -        // TODO(yhirano): Implement this. | 
| -        ASSERT_NOT_REACHED(); | 
| -        break; | 
| -    case ResponseAsJSON: { | 
| -        ScriptState::Scope scope(m_resolver->scriptState()); | 
| -        m_resolver->reject(V8ThrowException::createSyntaxError(m_resolver->scriptState()->isolate(), "Unexpected end of input")); | 
| -        break; | 
| -    } | 
| -    case ResponseUnknown: | 
| -        ASSERT_NOT_REACHED(); | 
| -        break; | 
| -    } | 
| -    m_resolver.clear(); | 
| -} | 
| - | 
| -void Body::readAsyncFromDrainingBodyStreamBuffer(PassOwnPtr<DrainingBodyStreamBuffer> buffer, const String& mimeType) | 
| +ScriptPromise Body::blob(ScriptState* scriptState) | 
| { | 
| -    if (!buffer) { | 
| -        resolveWithEmptyDataSynchronously(); | 
| -        m_streamSource->close(); | 
| -        return; | 
| -    } | 
| - | 
| -    FetchDataLoader* fetchDataLoader = nullptr; | 
| - | 
| -    switch (m_responseType) { | 
| -    case ResponseAsArrayBuffer: | 
| -        fetchDataLoader = FetchDataLoader::createLoaderAsArrayBuffer(); | 
| -        break; | 
| - | 
| -    case ResponseAsJSON: | 
| -    case ResponseAsText: | 
| -        fetchDataLoader = FetchDataLoader::createLoaderAsString(); | 
| -        break; | 
| - | 
| -    case ResponseAsBlob: | 
| -        fetchDataLoader = FetchDataLoader::createLoaderAsBlobHandle(mimeType); | 
| -        break; | 
| +    if (bodyUsed()) | 
| +        return ScriptPromise::reject(scriptState, V8ThrowException::createTypeError(scriptState->isolate(), "Already read")); | 
|  | 
| -    case ResponseAsFormData: | 
| -        // FIXME: Implement this. | 
| -        ASSERT_NOT_REACHED(); | 
| -        return; | 
| +    // See above comment. | 
| +    if (!scriptState->executionContext()) | 
| +        return ScriptPromise(); | 
|  | 
| -    default: | 
| -        ASSERT_NOT_REACHED(); | 
| -        return; | 
| -    } | 
| +    RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState); | 
| +    ScriptPromise promise = resolver->promise(); | 
| +    bodyBuffer()->startLoading(scriptState->executionContext(), FetchDataLoader::createLoaderAsBlobHandle(mimeType()), new BodyBlobConsumer(resolver)); | 
| +    return promise; | 
|  | 
| -    buffer->startLoading(fetchDataLoader, this); | 
| } | 
|  | 
| -ScriptPromise Body::arrayBuffer(ScriptState* scriptState) | 
| -{ | 
| -    return readAsync(scriptState, ResponseAsArrayBuffer); | 
| -} | 
| - | 
| -ScriptPromise Body::blob(ScriptState* scriptState) | 
| +ScriptPromise Body::json(ScriptState* scriptState) | 
| { | 
| -    return readAsync(scriptState, ResponseAsBlob); | 
| -} | 
| +    if (bodyUsed()) | 
| +        return ScriptPromise::reject(scriptState, V8ThrowException::createTypeError(scriptState->isolate(), "Already read")); | 
|  | 
| -ScriptPromise Body::formData(ScriptState* scriptState) | 
| -{ | 
| -    return readAsync(scriptState, ResponseAsFormData); | 
| -} | 
| +    // See above comment. | 
| +    if (!scriptState->executionContext()) | 
| +        return ScriptPromise(); | 
|  | 
| -ScriptPromise Body::json(ScriptState* scriptState) | 
| -{ | 
| -    return readAsync(scriptState, ResponseAsJSON); | 
| +    RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState); | 
| +    ScriptPromise promise = resolver->promise(); | 
| +    bodyBuffer()->startLoading(scriptState->executionContext(), FetchDataLoader::createLoaderAsString(), new BodyJsonConsumer(resolver)); | 
| +    return promise; | 
| } | 
|  | 
| ScriptPromise Body::text(ScriptState* scriptState) | 
| { | 
| -    return readAsync(scriptState, ResponseAsText); | 
| -} | 
| - | 
| -ReadableByteStream* Body::body() | 
| -{ | 
| -    UseCounter::count(executionContext(), UseCounter::FetchBodyStream); | 
| -    return m_stream; | 
| -} | 
| +    if (bodyUsed()) | 
| +        return ScriptPromise::reject(scriptState, V8ThrowException::createTypeError(scriptState->isolate(), "Already read")); | 
|  | 
| -bool Body::bodyUsed() const | 
| -{ | 
| -    return m_bodyUsed || m_stream->isLocked(); | 
| -} | 
| +    // See above comment. | 
| +    if (!scriptState->executionContext()) | 
| +        return ScriptPromise(); | 
|  | 
| -void Body::lockBody(LockBodyOption option) | 
| -{ | 
| -    ASSERT(!bodyUsed()); | 
| -    if (option == PassBody) | 
| -        m_bodyUsed = true; | 
| -    ASSERT(!m_stream->isLocked()); | 
| -    TrackExceptionState exceptionState; | 
| -    m_stream->getBytesReader(executionContext(), exceptionState); | 
| -    ASSERT(!exceptionState.hadException()); | 
| +    RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState); | 
| +    ScriptPromise promise = resolver->promise(); | 
| +    bodyBuffer()->startLoading(scriptState->executionContext(), FetchDataLoader::createLoaderAsString(), new BodyTextConsumer(resolver)); | 
| +    return promise; | 
| } | 
|  | 
| -void Body::setBody(BodyStreamBuffer* buffer) | 
| +ReadableByteStream* Body::body() | 
| { | 
| -    m_streamSource = new ReadableStreamSource(executionContext(), buffer); | 
| -    m_stream = new ReadableByteStream(m_streamSource, new ReadableByteStream::StrictStrategy); | 
| -    m_streamSource->startStream(m_stream); | 
| +    UseCounter::count(executionContext(), UseCounter::FetchBodyStream); | 
| +    return bodyBuffer()->stream(); | 
| } | 
|  | 
| -PassOwnPtr<DrainingBodyStreamBuffer> Body::createDrainingStream() | 
| +bool Body::bodyUsed() | 
| { | 
| -    return m_streamSource->createDrainingStream(); | 
| +    return m_bodyPassed || body()->isLocked(); | 
| } | 
|  | 
| bool Body::hasPendingActivity() const | 
| { | 
| if (executionContext()->activeDOMObjectsAreStopped()) | 
| return false; | 
| -    if (m_resolver) | 
| -        return true; | 
| -    if (m_stream->isLocked()) | 
| -        return true; | 
| -    return false; | 
| -} | 
| - | 
| -DEFINE_TRACE(Body) | 
| -{ | 
| -    visitor->trace(m_resolver); | 
| -    visitor->trace(m_stream); | 
| -    visitor->trace(m_streamSource); | 
| -    ActiveDOMObject::trace(visitor); | 
| -    FetchDataLoader::Client::trace(visitor); | 
| -} | 
| - | 
| -Body::Body(ExecutionContext* context) | 
| -    : ActiveDOMObject(context) | 
| -    , m_bodyUsed(false) | 
| -    , m_responseType(ResponseType::ResponseUnknown) | 
| -    , m_streamSource(new ReadableStreamSource(context, nullptr)) | 
| -    , m_stream(new ReadableByteStream(m_streamSource, new ReadableByteStream::StrictStrategy)) | 
| -{ | 
| -    m_streamSource->startStream(m_stream); | 
| -} | 
| - | 
| -void Body::resolveJSON(const String& string) | 
| -{ | 
| -    ASSERT(m_responseType == ResponseAsJSON); | 
| -    ScriptState::Scope scope(m_resolver->scriptState()); | 
| -    v8::Isolate* isolate = m_resolver->scriptState()->isolate(); | 
| -    v8::Local<v8::String> inputString = v8String(isolate, string); | 
| -    v8::TryCatch trycatch; | 
| -    v8::Local<v8::Value> parsed; | 
| -    if (v8Call(v8::JSON::Parse(isolate, inputString), parsed, trycatch)) | 
| -        m_resolver->resolve(parsed); | 
| -    else | 
| -        m_resolver->reject(trycatch.Exception()); | 
| -} | 
| - | 
| -// FetchDataLoader::Client functions. | 
| -void Body::didFetchDataLoadFailed() | 
| -{ | 
| -    if (!executionContext() || executionContext()->activeDOMObjectsAreStopped()) | 
| -        return; | 
| - | 
| -    if (m_resolver) { | 
| -        if (!m_resolver->executionContext() || m_resolver->executionContext()->activeDOMObjectsAreStopped()) { | 
| -            m_resolver.clear(); | 
| -            return; | 
| -        } | 
| -        ScriptState* state = m_resolver->scriptState(); | 
| -        ScriptState::Scope scope(state); | 
| -        m_resolver->reject(V8ThrowException::createTypeError(state->isolate(), "Failed to fetch")); | 
| -        m_resolver.clear(); | 
| -    } | 
| -} | 
| - | 
| -void Body::didFetchDataLoadedBlobHandle(PassRefPtr<BlobDataHandle> blobDataHandle) | 
| -{ | 
| -    if (!executionContext() || executionContext()->activeDOMObjectsAreStopped()) | 
| -        return; | 
| - | 
| -    ASSERT(m_responseType == ResponseAsBlob); | 
| -    m_resolver->resolve(Blob::create(blobDataHandle)); | 
| -    m_resolver.clear(); | 
| +    return bodyBuffer()->hasPendingActivity(); | 
| } | 
|  | 
| -void Body::didFetchDataLoadedArrayBuffer(PassRefPtr<DOMArrayBuffer> arrayBuffer) | 
| +Body::Body(ExecutionContext* context) : ActiveDOMObject(context), m_bodyPassed(false) | 
| { | 
| -    if (!executionContext() || executionContext()->activeDOMObjectsAreStopped()) | 
| -        return; | 
| - | 
| -    ASSERT(m_responseType == ResponseAsArrayBuffer); | 
| -    m_resolver->resolve(arrayBuffer); | 
| -    m_resolver.clear(); | 
| -} | 
| - | 
| -void Body::didFetchDataLoadedString(const String& str) | 
| -{ | 
| -    if (!executionContext() || executionContext()->activeDOMObjectsAreStopped()) | 
| -        return; | 
| - | 
| -    switch (m_responseType) { | 
| -    case ResponseAsJSON: | 
| -        resolveJSON(str); | 
| -        break; | 
| -    case ResponseAsText: | 
| -        m_resolver->resolve(str); | 
| -        break; | 
| -    default: | 
| -        ASSERT_NOT_REACHED(); | 
| -    } | 
| - | 
| -    m_resolver.clear(); | 
| +    suspendIfNeeded(); | 
| } | 
|  | 
| } // namespace blink | 
|  |