Index: third_party/WebKit/Source/modules/fetch/FetchDataLoader.cpp |
diff --git a/third_party/WebKit/Source/modules/fetch/FetchDataLoader.cpp b/third_party/WebKit/Source/modules/fetch/FetchDataLoader.cpp |
index e5b6ce557785ad9816bf866ffd45be9bc671477d..93ad0149aaf33b3ae48b2a926f4a321844d36cff 100644 |
--- a/third_party/WebKit/Source/modules/fetch/FetchDataLoader.cpp |
+++ b/third_party/WebKit/Source/modules/fetch/FetchDataLoader.cpp |
@@ -305,6 +305,103 @@ class FetchDataLoaderAsStream final : public FetchDataLoader, |
Member<Stream> m_outStream; |
}; |
+class FetchDataLoaderAsWasmModule final : public FetchDataLoader, |
+ public BytesConsumer::Client { |
+ USING_GARBAGE_COLLECTED_MIXIN(FetchDataLoaderAsWasmModule); |
+ |
+ public: |
+ FetchDataLoaderAsWasmModule(v8::Isolate* isolate, |
+ ScriptPromiseResolver* resolver, |
+ ScriptState* scriptState) |
+ : m_resolver(resolver), m_builder(isolate), m_scriptState(scriptState) {} |
+ |
+ void start(BytesConsumer* consumer, |
+ FetchDataLoader::Client* client) override { |
+ DCHECK(!m_consumer); |
+ DCHECK(!m_client); |
+ m_client = client; |
+ m_consumer = consumer; |
+ m_consumer->setClient(this); |
+ onStateChange(); |
+ } |
+ |
+ void onStateChange() override { |
+ while (true) { |
+ // buffer is allocated by beginRead and de-allocated by endRead. |
+ const char* buffer = nullptr; |
+ size_t available = 0; |
+ BytesConsumer::Result result = m_consumer->beginRead(&buffer, &available); |
+ |
+ if (result == BytesConsumer::Result::ShouldWait) |
+ return; |
+ if (result == BytesConsumer::Result::Ok) { |
+ if (available > 0) { |
+ DCHECK_NE(buffer, nullptr); |
+ m_builder.OnBytesReceived(reinterpret_cast<const uint8_t*>(buffer), |
+ available); |
+ } |
+ result = m_consumer->endRead(available); |
+ } |
+ switch (result) { |
+ case BytesConsumer::Result::ShouldWait: |
+ NOTREACHED(); |
+ return; |
+ case BytesConsumer::Result::Ok: { |
+ break; |
+ } |
+ case BytesConsumer::Result::Done: { |
+ v8::Isolate* isolate = m_resolver->getScriptState()->isolate(); |
+ ScriptState::Scope scope(m_scriptState.get()); |
+ v8::TryCatch trycatch(isolate); |
+ v8::Local<v8::WasmCompiledModule> module; |
+ if (m_builder.Finish().ToLocal(&module)) { |
+ DCHECK(!trycatch.HasCaught()); |
+ ScriptValue scriptValue(m_scriptState.get(), module); |
+ m_resolver->resolve(scriptValue); |
+ } else { |
+ DCHECK(trycatch.HasCaught()); |
+ m_resolver->reject(trycatch.Exception()); |
+ trycatch.Reset(); |
+ } |
+ m_client->didFetchDataLoadedWasmModule(); |
+ return; |
+ } |
+ case BytesConsumer::Result::Error: { |
+ // TODO(mtrofin): do we need an abort on the wasm side? |
+ // m_outStream->abort(); |
yhirano
2017/04/05 12:02:50
What does this line mean?
Mircea Trofin
2017/04/05 17:17:49
It's part of the TODO, I added more text around to
|
+ return ThrowTypeError(); |
+ } |
+ } |
+ } |
+ } |
+ |
+ void cancel() override { |
+ m_consumer->cancel(); |
+ return ThrowTypeError(); |
+ } |
+ |
+ DEFINE_INLINE_TRACE() { |
+ visitor->trace(m_consumer); |
+ visitor->trace(m_resolver); |
+ visitor->trace(m_client); |
+ FetchDataLoader::trace(visitor); |
+ BytesConsumer::Client::trace(visitor); |
+ } |
+ |
+ private: |
+ // TODO(mtrofin): replace with spec-ed error types, once spec clarifies |
+ // what they are. |
+ void ThrowTypeError() { |
+ m_resolver->reject(V8ThrowException::createTypeError( |
+ m_scriptState->isolate(), "Could not download wasm module")); |
+ } |
+ Member<BytesConsumer> m_consumer; |
+ Member<ScriptPromiseResolver> m_resolver; |
+ Member<FetchDataLoader::Client> m_client; |
+ v8::WasmModuleObjectBuilder m_builder; |
+ const RefPtr<ScriptState> m_scriptState; |
+}; |
+ |
} // namespace |
FetchDataLoader* FetchDataLoader::createLoaderAsBlobHandle( |
@@ -324,4 +421,11 @@ FetchDataLoader* FetchDataLoader::createLoaderAsStream(Stream* outStream) { |
return new FetchDataLoaderAsStream(outStream); |
} |
+FetchDataLoader* FetchDataLoader::createLoaderAsWasmModule( |
+ v8::Isolate* isolate, |
+ ScriptPromiseResolver* resolver, |
+ ScriptState* scriptState) { |
+ return new FetchDataLoaderAsWasmModule(isolate, resolver, scriptState); |
+} |
+ |
} // namespace blink |