• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "src/execution/isolate.h"
6 #include "src/wasm/streaming-decoder.h"
7 #include "src/wasm/wasm-engine.h"
8 #include "src/wasm/wasm-objects-inl.h"
9 #include "src/wasm/wasm-serialization.h"
10 
11 namespace v8 {
12 namespace internal {
13 namespace wasm {
14 
15 class V8_EXPORT_PRIVATE SyncStreamingDecoder : public StreamingDecoder {
16  public:
SyncStreamingDecoder(Isolate * isolate,const WasmFeatures & enabled,Handle<Context> context,const char * api_method_name_for_errors,std::shared_ptr<CompilationResultResolver> resolver)17   SyncStreamingDecoder(Isolate* isolate, const WasmFeatures& enabled,
18                        Handle<Context> context,
19                        const char* api_method_name_for_errors,
20                        std::shared_ptr<CompilationResultResolver> resolver)
21       : isolate_(isolate),
22         enabled_(enabled),
23         context_(context),
24         api_method_name_for_errors_(api_method_name_for_errors),
25         resolver_(resolver) {}
26 
27   // The buffer passed into OnBytesReceived is owned by the caller.
OnBytesReceived(base::Vector<const uint8_t> bytes)28   void OnBytesReceived(base::Vector<const uint8_t> bytes) override {
29     buffer_.emplace_back(bytes.size());
30     CHECK_EQ(buffer_.back().size(), bytes.size());
31     std::memcpy(buffer_.back().data(), bytes.data(), bytes.size());
32     buffer_size_ += bytes.size();
33   }
34 
Finish(bool can_use_compiled_module)35   void Finish(bool can_use_compiled_module) override {
36     // We copy all received chunks into one byte buffer.
37     auto bytes = std::make_unique<uint8_t[]>(buffer_size_);
38     uint8_t* destination = bytes.get();
39     for (auto& chunk : buffer_) {
40       std::memcpy(destination, chunk.data(), chunk.size());
41       destination += chunk.size();
42     }
43     CHECK_EQ(destination - bytes.get(), buffer_size_);
44 
45     // Check if we can deserialize the module from cache.
46     if (can_use_compiled_module && deserializing()) {
47       HandleScope scope(isolate_);
48       SaveAndSwitchContext saved_context(isolate_, *context_);
49 
50       MaybeHandle<WasmModuleObject> module_object = DeserializeNativeModule(
51           isolate_, compiled_module_bytes_,
52           base::Vector<const uint8_t>(bytes.get(), buffer_size_), url());
53 
54       if (!module_object.is_null()) {
55         Handle<WasmModuleObject> module = module_object.ToHandleChecked();
56         resolver_->OnCompilationSucceeded(module);
57         return;
58       }
59     }
60 
61     // Compile the received bytes synchronously.
62     ModuleWireBytes wire_bytes(bytes.get(), bytes.get() + buffer_size_);
63     ErrorThrower thrower(isolate_, api_method_name_for_errors_);
64     MaybeHandle<WasmModuleObject> module_object =
65         GetWasmEngine()->SyncCompile(isolate_, enabled_, &thrower, wire_bytes);
66     if (thrower.error()) {
67       resolver_->OnCompilationFailed(thrower.Reify());
68       return;
69     }
70     Handle<WasmModuleObject> module = module_object.ToHandleChecked();
71     if (module_compiled_callback_) {
72       module_compiled_callback_(module->shared_native_module());
73     }
74     resolver_->OnCompilationSucceeded(module);
75   }
76 
Abort()77   void Abort() override {
78     // Abort is fully handled by the API, we only clear the buffer.
79     buffer_.clear();
80   }
81 
NotifyCompilationEnded()82   void NotifyCompilationEnded() override { buffer_.clear(); }
83 
NotifyNativeModuleCreated(const std::shared_ptr<NativeModule> &)84   void NotifyNativeModuleCreated(
85       const std::shared_ptr<NativeModule>&) override {
86     // This function is only called from the {AsyncCompileJob}.
87     UNREACHABLE();
88   }
89 
90  private:
91   Isolate* isolate_;
92   const WasmFeatures enabled_;
93   Handle<Context> context_;
94   const char* api_method_name_for_errors_;
95   std::shared_ptr<CompilationResultResolver> resolver_;
96 
97   std::vector<std::vector<uint8_t>> buffer_;
98   size_t buffer_size_ = 0;
99 };
100 
CreateSyncStreamingDecoder(Isolate * isolate,const WasmFeatures & enabled,Handle<Context> context,const char * api_method_name_for_errors,std::shared_ptr<CompilationResultResolver> resolver)101 std::unique_ptr<StreamingDecoder> StreamingDecoder::CreateSyncStreamingDecoder(
102     Isolate* isolate, const WasmFeatures& enabled, Handle<Context> context,
103     const char* api_method_name_for_errors,
104     std::shared_ptr<CompilationResultResolver> resolver) {
105   return std::make_unique<SyncStreamingDecoder>(isolate, enabled, context,
106                                                 api_method_name_for_errors,
107                                                 std::move(resolver));
108 }
109 }  // namespace wasm
110 }  // namespace internal
111 }  // namespace v8
112