OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "modules/fetch/FetchDataLoader.h" | 5 #include "modules/fetch/FetchDataLoader.h" |
6 | 6 |
7 #include "core/html/parser/TextResourceDecoder.h" | 7 #include "core/html/parser/TextResourceDecoder.h" |
8 #include "modules/fetch/BytesConsumer.h" | 8 #include "modules/fetch/BytesConsumer.h" |
9 #include "wtf/PtrUtil.h" | 9 #include "wtf/PtrUtil.h" |
10 #include "wtf/text/StringBuilder.h" | 10 #include "wtf/text/StringBuilder.h" |
11 #include "wtf/text/WTFString.h" | 11 #include "wtf/text/WTFString.h" |
12 #include "wtf/typed_arrays/ArrayBufferBuilder.h" | 12 #include "wtf/typed_arrays/ArrayBufferBuilder.h" |
13 #include <memory> | 13 #include <memory> |
14 | 14 |
15 namespace blink { | 15 namespace blink { |
16 | 16 |
17 namespace { | 17 namespace { |
18 | 18 |
19 class FetchDataLoaderAsBlobHandle final : public FetchDataLoader, | 19 class FetchDataLoaderAsBlobHandle final : public FetchDataLoader, |
20 public BytesConsumer::Client { | 20 public BytesConsumer::Client { |
21 USING_GARBAGE_COLLECTED_MIXIN(FetchDataLoaderAsBlobHandle); | 21 USING_GARBAGE_COLLECTED_MIXIN(FetchDataLoaderAsBlobHandle); |
22 | 22 |
23 public: | 23 public: |
24 explicit FetchDataLoaderAsBlobHandle(const String& mimeType) | 24 FetchDataLoaderAsBlobHandle(const String& mimeType) : m_mimeType(mimeType) {} |
25 : m_mimeType(mimeType) {} | |
26 | 25 |
27 void start(BytesConsumer* consumer, | 26 void start(BytesConsumer* consumer, |
28 FetchDataLoader::Client* client) override { | 27 FetchDataLoader::Client* client) override { |
29 DCHECK(!m_client); | 28 DCHECK(!m_client); |
30 DCHECK(!m_consumer); | 29 DCHECK(!m_consumer); |
31 | 30 |
32 m_client = client; | 31 m_client = client; |
33 m_consumer = consumer; | 32 m_consumer = consumer; |
34 | 33 |
35 RefPtr<BlobDataHandle> blobHandle = m_consumer->drainAsBlobDataHandle(); | 34 RefPtr<BlobDataHandle> blobHandle = m_consumer->drainAsBlobDataHandle(); |
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
298 visitor->trace(m_outStream); | 297 visitor->trace(m_outStream); |
299 FetchDataLoader::trace(visitor); | 298 FetchDataLoader::trace(visitor); |
300 BytesConsumer::Client::trace(visitor); | 299 BytesConsumer::Client::trace(visitor); |
301 } | 300 } |
302 | 301 |
303 Member<BytesConsumer> m_consumer; | 302 Member<BytesConsumer> m_consumer; |
304 Member<FetchDataLoader::Client> m_client; | 303 Member<FetchDataLoader::Client> m_client; |
305 Member<Stream> m_outStream; | 304 Member<Stream> m_outStream; |
306 }; | 305 }; |
307 | 306 |
307 class FetchDataLoaderAsWasmModule final : public FetchDataLoader, | |
308 public BytesConsumer::Client { | |
309 USING_GARBAGE_COLLECTED_MIXIN(FetchDataLoaderAsWasmModule); | |
310 | |
311 public: | |
312 explicit FetchDataLoaderAsWasmModule(v8::Isolate* isolate, | |
313 ScriptPromiseResolver* resolver, | |
314 ScriptState* scriptState) | |
haraken
2017/04/04 06:05:31
Drop explicit.
| |
315 : m_resolver(resolver), m_builder(isolate), m_scriptState(scriptState) {} | |
316 | |
317 void start(BytesConsumer* consumer, | |
318 FetchDataLoader::Client* client) override { | |
319 DCHECK(!m_consumer); | |
320 DCHECK(!m_client); | |
321 m_client = client; | |
322 m_consumer = consumer; | |
323 m_consumer->setClient(this); | |
324 onStateChange(); | |
325 } | |
326 | |
327 void onStateChange() override { | |
328 while (true) { | |
329 const char* buffer; | |
330 size_t available; | |
331 BytesConsumer::Result result = m_consumer->beginRead(&buffer, &available); | |
332 | |
333 switch (result) { | |
334 case BytesConsumer::Result::ShouldWait: | |
335 return; | |
336 case BytesConsumer::Result::Ok: { | |
337 sendBytes(buffer, available); | |
338 result = m_consumer->endRead(available); | |
339 if (result == BytesConsumer::Result::Error) { | |
340 m_resolver->reject(); | |
341 } | |
342 break; | |
343 } | |
344 case BytesConsumer::Result::Done: { | |
345 DCHECK_EQ(available, 0U); | |
346 v8::Isolate* isolate = m_resolver->getScriptState()->isolate(); | |
347 ScriptState::Scope scope(m_scriptState.get()); | |
348 v8::TryCatch trycatch(isolate); | |
349 v8::Local<v8::WasmCompiledModule> module; | |
350 if (m_builder.Finish().ToLocal(&module)) { | |
351 DCHECK(!trycatch.HasCaught()); | |
352 ScriptValue scriptValue(m_scriptState.get(), module); | |
353 m_resolver->resolve(scriptValue); | |
354 } else { | |
355 DCHECK(trycatch.HasCaught()); | |
356 m_resolver->reject(trycatch.Exception()); | |
357 trycatch.Reset(); | |
358 } | |
359 m_client->didFetchDataLoadedStream(); | |
360 return; | |
361 } | |
362 case BytesConsumer::Result::Error: { | |
363 // TODO(mtrofin): do we need an abort on the wasm side? | |
364 // m_outStream->abort(); | |
365 m_client->didFetchDataLoadFailed(); | |
366 return; | |
367 } | |
368 } | |
369 } | |
370 } | |
371 | |
372 void cancel() override { m_consumer->cancel(); } | |
373 | |
374 DEFINE_INLINE_TRACE() { | |
375 visitor->trace(m_consumer); | |
376 visitor->trace(m_resolver); | |
377 visitor->trace(m_client); | |
378 FetchDataLoader::trace(visitor); | |
379 BytesConsumer::Client::trace(visitor); | |
380 } | |
381 | |
382 private: | |
383 void sendBytes(const char* bytes, size_t size) { | |
384 std::unique_ptr<uint8_t[]> bufferCopy(new uint8_t[size]); | |
haraken
2017/04/04 06:05:31
We should use fastMalloc / fastFree instead of new
Mircea Trofin
2017/04/04 06:48:07
Oh, good point - thats anyway what we want to do o
| |
385 memcpy(bufferCopy.get(), bytes, size); | |
386 // TODO(mtrofin): we want to extend OnBytesReceived to test | |
387 // for decoding errors or for compilation errors that | |
388 // happened meanwhile. | |
389 m_builder.OnBytesReceived( | |
390 std::unique_ptr<const uint8_t[]>( | |
391 const_cast<const uint8_t*>(bufferCopy.release())), | |
392 size); | |
393 } | |
394 | |
395 Member<BytesConsumer> m_consumer; | |
396 Member<ScriptPromiseResolver> m_resolver; | |
397 Member<FetchDataLoader::Client> m_client; | |
398 v8::WasmModuleObjectBuilder m_builder; | |
399 const RefPtr<ScriptState> m_scriptState; | |
400 }; | |
401 | |
308 } // namespace | 402 } // namespace |
309 | 403 |
310 FetchDataLoader* FetchDataLoader::createLoaderAsBlobHandle( | 404 FetchDataLoader* FetchDataLoader::createLoaderAsBlobHandle( |
311 const String& mimeType) { | 405 const String& mimeType) { |
312 return new FetchDataLoaderAsBlobHandle(mimeType); | 406 return new FetchDataLoaderAsBlobHandle(mimeType); |
313 } | 407 } |
314 | 408 |
315 FetchDataLoader* FetchDataLoader::createLoaderAsArrayBuffer() { | 409 FetchDataLoader* FetchDataLoader::createLoaderAsArrayBuffer() { |
316 return new FetchDataLoaderAsArrayBuffer(); | 410 return new FetchDataLoaderAsArrayBuffer(); |
317 } | 411 } |
318 | 412 |
319 FetchDataLoader* FetchDataLoader::createLoaderAsString() { | 413 FetchDataLoader* FetchDataLoader::createLoaderAsString() { |
320 return new FetchDataLoaderAsString(); | 414 return new FetchDataLoaderAsString(); |
321 } | 415 } |
322 | 416 |
323 FetchDataLoader* FetchDataLoader::createLoaderAsStream(Stream* outStream) { | 417 FetchDataLoader* FetchDataLoader::createLoaderAsStream(Stream* outStream) { |
324 return new FetchDataLoaderAsStream(outStream); | 418 return new FetchDataLoaderAsStream(outStream); |
325 } | 419 } |
326 | 420 |
421 FetchDataLoader* FetchDataLoader::createLoaderAsWasmModule( | |
422 v8::Isolate* isolate, | |
423 ScriptPromiseResolver* resolver, | |
424 ScriptState* scriptState) { | |
425 return new FetchDataLoaderAsWasmModule(isolate, resolver, scriptState); | |
426 } | |
427 | |
327 } // namespace blink | 428 } // namespace blink |
OLD | NEW |