1 // Copyright 2017 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 #if !V8_ENABLE_WEBASSEMBLY 6 #error This header should only be included if WebAssembly is enabled. 7 #endif // !V8_ENABLE_WEBASSEMBLY 8 9 #ifndef V8_WASM_STREAMING_DECODER_H_ 10 #define V8_WASM_STREAMING_DECODER_H_ 11 12 #include <memory> 13 14 #include "src/base/macros.h" 15 #include "src/base/vector.h" 16 #include "src/wasm/compilation-environment.h" 17 #include "src/wasm/wasm-constants.h" 18 #include "src/wasm/wasm-engine.h" 19 #include "src/wasm/wasm-result.h" 20 21 namespace v8 { 22 namespace internal { 23 namespace wasm { 24 class NativeModule; 25 26 // This class is an interface for the StreamingDecoder to start the processing 27 // of the incoming module bytes. 28 class V8_EXPORT_PRIVATE StreamingProcessor { 29 public: 30 virtual ~StreamingProcessor() = default; 31 // Process the first 8 bytes of a WebAssembly module. Returns true if the 32 // processing finished successfully and the decoding should continue. 33 virtual bool ProcessModuleHeader(base::Vector<const uint8_t> bytes, 34 uint32_t offset) = 0; 35 36 // Process all sections but the code section. Returns true if the processing 37 // finished successfully and the decoding should continue. 38 virtual bool ProcessSection(SectionCode section_code, 39 base::Vector<const uint8_t> bytes, 40 uint32_t offset) = 0; 41 42 // Process the start of the code section. Returns true if the processing 43 // finished successfully and the decoding should continue. 44 virtual bool ProcessCodeSectionHeader(int num_functions, uint32_t offset, 45 std::shared_ptr<WireBytesStorage>, 46 int code_section_start, 47 int code_section_length) = 0; 48 49 // Process a function body. Returns true if the processing finished 50 // successfully and the decoding should continue. 51 virtual bool ProcessFunctionBody(base::Vector<const uint8_t> bytes, 52 uint32_t offset) = 0; 53 54 // Report the end of a chunk. 55 virtual void OnFinishedChunk() = 0; 56 // Report the end of the stream. If the stream was successful, all 57 // received bytes are passed by parameter. If there has been an error, an 58 // empty array is passed. 59 virtual void OnFinishedStream(base::OwnedVector<uint8_t> bytes) = 0; 60 // Report an error detected in the StreamingDecoder. 61 virtual void OnError(const WasmError&) = 0; 62 // Report the abortion of the stream. 63 virtual void OnAbort() = 0; 64 65 // Attempt to deserialize the module. Supports embedder caching. 66 virtual bool Deserialize(base::Vector<const uint8_t> module_bytes, 67 base::Vector<const uint8_t> wire_bytes) = 0; 68 }; 69 70 // The StreamingDecoder takes a sequence of byte arrays, each received by a call 71 // of {OnBytesReceived}, and extracts the bytes which belong to section payloads 72 // and function bodies. 73 class V8_EXPORT_PRIVATE StreamingDecoder { 74 public: 75 virtual ~StreamingDecoder() = default; 76 77 // The buffer passed into OnBytesReceived is owned by the caller. 78 virtual void OnBytesReceived(base::Vector<const uint8_t> bytes) = 0; 79 80 virtual void Finish(bool can_use_compiled_module = true) = 0; 81 82 virtual void Abort() = 0; 83 84 // Notify the StreamingDecoder that compilation ended and the 85 // StreamingProcessor should not be called anymore. 86 virtual void NotifyCompilationEnded() = 0; 87 88 // Caching support. 89 // Sets the callback that is called after the module is fully compiled. 90 using ModuleCompiledCallback = 91 std::function<void(const std::shared_ptr<NativeModule>&)>; 92 SetModuleCompiledCallback(ModuleCompiledCallback callback)93 void SetModuleCompiledCallback(ModuleCompiledCallback callback) { 94 module_compiled_callback_ = callback; 95 } 96 97 // Passes previously compiled module bytes from the embedder's cache. 98 // The content shouldn't be used until Finish(true) is called. SetCompiledModuleBytes(base::Vector<const uint8_t> compiled_module_bytes)99 bool SetCompiledModuleBytes( 100 base::Vector<const uint8_t> compiled_module_bytes) { 101 compiled_module_bytes_ = compiled_module_bytes; 102 return true; 103 } 104 105 virtual void NotifyNativeModuleCreated( 106 const std::shared_ptr<NativeModule>& native_module) = 0; 107 url()108 base::Vector<const char> url() { return base::VectorOf(url_); } 109 SetUrl(base::Vector<const char> url)110 void SetUrl(base::Vector<const char> url) { 111 url_.assign(url.begin(), url.length()); 112 } 113 114 static std::unique_ptr<StreamingDecoder> CreateAsyncStreamingDecoder( 115 std::unique_ptr<StreamingProcessor> processor); 116 117 static std::unique_ptr<StreamingDecoder> CreateSyncStreamingDecoder( 118 Isolate* isolate, const WasmFeatures& enabled, Handle<Context> context, 119 const char* api_method_name_for_errors, 120 std::shared_ptr<CompilationResultResolver> resolver); 121 122 protected: deserializing()123 bool deserializing() const { return !compiled_module_bytes_.empty(); } 124 125 std::string url_; 126 ModuleCompiledCallback module_compiled_callback_; 127 // The content of `compiled_module_bytes_` shouldn't be used until 128 // Finish(true) is called. 129 base::Vector<const uint8_t> compiled_module_bytes_; 130 }; 131 132 } // namespace wasm 133 } // namespace internal 134 } // namespace v8 135 136 #endif // V8_WASM_STREAMING_DECODER_H_ 137