• 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(Vector<const uint8_t> bytes)28   void OnBytesReceived(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()35   void Finish() 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 (deserializing()) {
47       HandleScope scope(isolate_);
48       SaveAndSwitchContext saved_context(isolate_, *context_);
49 
50       MaybeHandle<WasmModuleObject> module_object = DeserializeNativeModule(
51           isolate_, compiled_module_bytes_,
52           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         isolate_->wasm_engine()->SyncCompile(isolate_, enabled_, &thrower,
66                                              wire_bytes);
67     if (thrower.error()) {
68       resolver_->OnCompilationFailed(thrower.Reify());
69       return;
70     }
71     Handle<WasmModuleObject> module = module_object.ToHandleChecked();
72     if (module_compiled_callback_) {
73       module_compiled_callback_(module->shared_native_module());
74     }
75     resolver_->OnCompilationSucceeded(module);
76   }
77 
Abort()78   void Abort() override {
79     // Abort is fully handled by the API, we only clear the buffer.
80     buffer_.clear();
81   }
82 
NotifyCompilationEnded()83   void NotifyCompilationEnded() override { buffer_.clear(); }
84 
NotifyNativeModuleCreated(const std::shared_ptr<NativeModule> &)85   void NotifyNativeModuleCreated(
86       const std::shared_ptr<NativeModule>&) override {
87     // This function is only called from the {AsyncCompileJob}.
88     UNREACHABLE();
89   }
90 
91  private:
92   Isolate* isolate_;
93   const WasmFeatures enabled_;
94   Handle<Context> context_;
95   const char* api_method_name_for_errors_;
96   std::shared_ptr<CompilationResultResolver> resolver_;
97 
98   std::vector<std::vector<uint8_t>> buffer_;
99   size_t buffer_size_ = 0;
100 };
101 
CreateSyncStreamingDecoder(Isolate * isolate,const WasmFeatures & enabled,Handle<Context> context,const char * api_method_name_for_errors,std::shared_ptr<CompilationResultResolver> resolver)102 std::unique_ptr<StreamingDecoder> StreamingDecoder::CreateSyncStreamingDecoder(
103     Isolate* isolate, const WasmFeatures& enabled, Handle<Context> context,
104     const char* api_method_name_for_errors,
105     std::shared_ptr<CompilationResultResolver> resolver) {
106   return std::make_unique<SyncStreamingDecoder>(isolate, enabled, context,
107                                                 api_method_name_for_errors,
108                                                 std::move(resolver));
109 }
110 }  // namespace wasm
111 }  // namespace internal
112 }  // namespace v8
113