v8-wasm.h 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. // Copyright 2021 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. #ifndef INCLUDE_V8_WASM_H_
  5. #define INCLUDE_V8_WASM_H_
  6. #include <memory>
  7. #include <string>
  8. #include "v8-local-handle.h" // NOLINT(build/include_directory)
  9. #include "v8-memory-span.h" // NOLINT(build/include_directory)
  10. #include "v8-object.h" // NOLINT(build/include_directory)
  11. #include "v8config.h" // NOLINT(build/include_directory)
  12. namespace v8 {
  13. class ArrayBuffer;
  14. class Promise;
  15. namespace internal {
  16. namespace wasm {
  17. class NativeModule;
  18. class StreamingDecoder;
  19. } // namespace wasm
  20. } // namespace internal
  21. /**
  22. * An owned byte buffer with associated size.
  23. */
  24. struct OwnedBuffer {
  25. std::unique_ptr<const uint8_t[]> buffer;
  26. size_t size = 0;
  27. OwnedBuffer(std::unique_ptr<const uint8_t[]> buffer, size_t size)
  28. : buffer(std::move(buffer)), size(size) {}
  29. OwnedBuffer() = default;
  30. };
  31. // Wrapper around a compiled WebAssembly module, which is potentially shared by
  32. // different WasmModuleObjects.
  33. class V8_EXPORT CompiledWasmModule {
  34. public:
  35. /**
  36. * Serialize the compiled module. The serialized data does not include the
  37. * wire bytes.
  38. */
  39. OwnedBuffer Serialize();
  40. /**
  41. * Get the (wasm-encoded) wire bytes that were used to compile this module.
  42. */
  43. MemorySpan<const uint8_t> GetWireBytesRef();
  44. const std::string& source_url() const { return source_url_; }
  45. private:
  46. friend class WasmModuleObject;
  47. friend class WasmStreaming;
  48. explicit CompiledWasmModule(std::shared_ptr<internal::wasm::NativeModule>,
  49. const char* source_url, size_t url_length);
  50. const std::shared_ptr<internal::wasm::NativeModule> native_module_;
  51. const std::string source_url_;
  52. };
  53. // An instance of WebAssembly.Memory.
  54. class V8_EXPORT WasmMemoryObject : public Object {
  55. public:
  56. WasmMemoryObject() = delete;
  57. /**
  58. * Returns underlying ArrayBuffer.
  59. */
  60. Local<ArrayBuffer> Buffer();
  61. V8_INLINE static WasmMemoryObject* Cast(Value* value) {
  62. #ifdef V8_ENABLE_CHECKS
  63. CheckCast(value);
  64. #endif
  65. return static_cast<WasmMemoryObject*>(value);
  66. }
  67. private:
  68. static void CheckCast(Value* object);
  69. };
  70. // An instance of WebAssembly.Module.
  71. class V8_EXPORT WasmModuleObject : public Object {
  72. public:
  73. WasmModuleObject() = delete;
  74. /**
  75. * Efficiently re-create a WasmModuleObject, without recompiling, from
  76. * a CompiledWasmModule.
  77. */
  78. static MaybeLocal<WasmModuleObject> FromCompiledModule(
  79. Isolate* isolate, const CompiledWasmModule&);
  80. /**
  81. * Get the compiled module for this module object. The compiled module can be
  82. * shared by several module objects.
  83. */
  84. CompiledWasmModule GetCompiledModule();
  85. /**
  86. * Compile a Wasm module from the provided uncompiled bytes.
  87. */
  88. static MaybeLocal<WasmModuleObject> Compile(
  89. Isolate* isolate, MemorySpan<const uint8_t> wire_bytes);
  90. V8_INLINE static WasmModuleObject* Cast(Value* value) {
  91. #ifdef V8_ENABLE_CHECKS
  92. CheckCast(value);
  93. #endif
  94. return static_cast<WasmModuleObject*>(value);
  95. }
  96. private:
  97. static void CheckCast(Value* obj);
  98. };
  99. /**
  100. * The V8 interface for WebAssembly streaming compilation. When streaming
  101. * compilation is initiated, V8 passes a {WasmStreaming} object to the embedder
  102. * such that the embedder can pass the input bytes for streaming compilation to
  103. * V8.
  104. */
  105. class V8_EXPORT WasmStreaming final {
  106. public:
  107. class WasmStreamingImpl;
  108. /**
  109. * Client to receive streaming event notifications.
  110. */
  111. class Client {
  112. public:
  113. virtual ~Client() = default;
  114. /**
  115. * Passes the fully compiled module to the client. This can be used to
  116. * implement code caching.
  117. */
  118. virtual void OnModuleCompiled(CompiledWasmModule compiled_module) = 0;
  119. };
  120. explicit WasmStreaming(std::unique_ptr<WasmStreamingImpl> impl);
  121. ~WasmStreaming();
  122. /**
  123. * Pass a new chunk of bytes to WebAssembly streaming compilation.
  124. * The buffer passed into {OnBytesReceived} is owned by the caller.
  125. */
  126. void OnBytesReceived(const uint8_t* bytes, size_t size);
  127. /**
  128. * {Finish} should be called after all received bytes where passed to
  129. * {OnBytesReceived} to tell V8 that there will be no more bytes. {Finish}
  130. * does not have to be called after {Abort} has been called already.
  131. * If {can_use_compiled_module} is true and {SetCompiledModuleBytes} was
  132. * previously called, the compiled module bytes can be used.
  133. * If {can_use_compiled_module} is false, the compiled module bytes previously
  134. * set by {SetCompiledModuleBytes} should not be used.
  135. */
  136. void Finish(bool can_use_compiled_module = true);
  137. /**
  138. * Abort streaming compilation. If {exception} has a value, then the promise
  139. * associated with streaming compilation is rejected with that value. If
  140. * {exception} does not have value, the promise does not get rejected.
  141. */
  142. void Abort(MaybeLocal<Value> exception);
  143. /**
  144. * Passes previously compiled module bytes. This must be called before
  145. * {OnBytesReceived}, {Finish}, or {Abort}. Returns true if the module bytes
  146. * can be used, false otherwise. The buffer passed via {bytes} and {size}
  147. * is owned by the caller. If {SetCompiledModuleBytes} returns true, the
  148. * buffer must remain valid until either {Finish} or {Abort} completes.
  149. * The compiled module bytes should not be used until {Finish(true)} is
  150. * called, because they can be invalidated later by {Finish(false)}.
  151. */
  152. bool SetCompiledModuleBytes(const uint8_t* bytes, size_t size);
  153. /**
  154. * Sets the client object that will receive streaming event notifications.
  155. * This must be called before {OnBytesReceived}, {Finish}, or {Abort}.
  156. */
  157. void SetClient(std::shared_ptr<Client> client);
  158. /*
  159. * Sets the UTF-8 encoded source URL for the {Script} object. This must be
  160. * called before {Finish}.
  161. */
  162. void SetUrl(const char* url, size_t length);
  163. /**
  164. * Unpacks a {WasmStreaming} object wrapped in a {Managed} for the embedder.
  165. * Since the embedder is on the other side of the API, it cannot unpack the
  166. * {Managed} itself.
  167. */
  168. static std::shared_ptr<WasmStreaming> Unpack(Isolate* isolate,
  169. Local<Value> value);
  170. private:
  171. std::unique_ptr<WasmStreamingImpl> impl_;
  172. };
  173. // TODO(mtrofin): when streaming compilation is done, we can rename this
  174. // to simply WasmModuleObjectBuilder
  175. class V8_EXPORT WasmModuleObjectBuilderStreaming final {
  176. public:
  177. explicit WasmModuleObjectBuilderStreaming(Isolate* isolate);
  178. /**
  179. * The buffer passed into OnBytesReceived is owned by the caller.
  180. */
  181. void OnBytesReceived(const uint8_t*, size_t size);
  182. void Finish();
  183. /**
  184. * Abort streaming compilation. If {exception} has a value, then the promise
  185. * associated with streaming compilation is rejected with that value. If
  186. * {exception} does not have value, the promise does not get rejected.
  187. */
  188. void Abort(MaybeLocal<Value> exception);
  189. Local<Promise> GetPromise();
  190. ~WasmModuleObjectBuilderStreaming() = default;
  191. private:
  192. WasmModuleObjectBuilderStreaming(const WasmModuleObjectBuilderStreaming&) =
  193. delete;
  194. WasmModuleObjectBuilderStreaming(WasmModuleObjectBuilderStreaming&&) =
  195. default;
  196. WasmModuleObjectBuilderStreaming& operator=(
  197. const WasmModuleObjectBuilderStreaming&) = delete;
  198. WasmModuleObjectBuilderStreaming& operator=(
  199. WasmModuleObjectBuilderStreaming&&) = default;
  200. Isolate* isolate_ = nullptr;
  201. #if V8_CC_MSVC
  202. /**
  203. * We don't need the static Copy API, so the default
  204. * NonCopyablePersistentTraits would be sufficient, however,
  205. * MSVC eagerly instantiates the Copy.
  206. * We ensure we don't use Copy, however, by compiling with the
  207. * defaults everywhere else.
  208. */
  209. Persistent<Promise, CopyablePersistentTraits<Promise>> promise_;
  210. #else
  211. Persistent<Promise> promise_;
  212. #endif
  213. std::shared_ptr<internal::wasm::StreamingDecoder> streaming_decoder_;
  214. };
  215. } // namespace v8
  216. #endif // INCLUDE_V8_WASM_H_