1 /** 2 * \file wasmtime/module.hh 3 */ 4 5 #ifndef WASMTIME_MODULE_HH 6 #define WASMTIME_MODULE_HH 7 8 #include <memory> 9 #include <string_view> 10 #include <wasmtime/engine.hh> 11 #include <wasmtime/module.h> 12 #include <wasmtime/span.hh> 13 #include <wasmtime/types/export.hh> 14 #include <wasmtime/types/import.hh> 15 #include <wasmtime/wat.hh> 16 17 namespace wasmtime { 18 19 /** 20 * \brief Representation of a compiled WebAssembly module. 21 * 22 * This type contains JIT code of a compiled WebAssembly module. A `Module` is 23 * connected to an `Engine` and can only be instantiated within that `Engine`. 24 * You can inspect a `Module` for its type information. This is passed as an 25 * argument to other APIs to instantiate it. 26 */ 27 class Module { 28 friend class Store; 29 friend class Instance; 30 friend class Linker; 31 32 struct deleter { 33 void operator()(wasmtime_module_t *p) const { wasmtime_module_delete(p); } 34 }; 35 36 std::unique_ptr<wasmtime_module_t, deleter> ptr; 37 38 Module(wasmtime_module_t *raw) : ptr(raw) {} 39 40 public: 41 /// Copies another module into this one. 42 Module(const Module &other) : ptr(wasmtime_module_clone(other.ptr.get())) {} 43 /// Copies another module into this one. 44 Module &operator=(const Module &other) { 45 ptr.reset(wasmtime_module_clone(other.ptr.get())); 46 return *this; 47 } 48 ~Module() = default; 49 /// Moves resources from another module into this one. 50 Module(Module &&other) = default; 51 /// Moves resources from another module into this one. 52 Module &operator=(Module &&other) = default; 53 54 #ifdef WASMTIME_FEATURE_COMPILER 55 /** 56 * \brief Compiles a module from the WebAssembly text format. 57 * 58 * This function will automatically use `wat2wasm` on the input and then 59 * delegate to the #compile function. 60 */ 61 static Result<Module> compile(Engine &engine, std::string_view wat) { 62 auto wasm = wat2wasm(wat); 63 if (!wasm) { 64 return wasm.err(); 65 } 66 auto bytes = wasm.ok(); 67 return compile(engine, bytes); 68 } 69 70 /** 71 * \brief Compiles a module from the WebAssembly binary format. 72 * 73 * This function compiles the provided WebAssembly binary specified by `wasm` 74 * within the compilation settings configured by `engine`. This method is 75 * synchronous and will not return until the module has finished compiling. 76 * 77 * This function can fail if the WebAssembly binary is invalid or doesn't 78 * validate (or similar). 79 */ 80 static Result<Module> compile(Engine &engine, Span<uint8_t> wasm) { 81 wasmtime_module_t *ret = nullptr; 82 auto *error = 83 wasmtime_module_new(engine.ptr.get(), wasm.data(), wasm.size(), &ret); 84 if (error != nullptr) { 85 return Error(error); 86 } 87 return Module(ret); 88 } 89 90 /** 91 * \brief Validates the provided WebAssembly binary without compiling it. 92 * 93 * This function will validate whether the provided binary is indeed valid 94 * within the compilation settings of the `engine` provided. 95 */ 96 static Result<std::monostate> validate(Engine &engine, Span<uint8_t> wasm) { 97 auto *error = 98 wasmtime_module_validate(engine.ptr.get(), wasm.data(), wasm.size()); 99 if (error != nullptr) { 100 return Error(error); 101 } 102 return std::monostate(); 103 } 104 #endif // WASMTIME_FEATURE_COMPILER 105 106 /** 107 * \brief Deserializes a previous list of bytes created with `serialize`. 108 * 109 * This function is intended to be much faster than `compile` where it uses 110 * the artifacts of a previous compilation to quickly create an in-memory 111 * module ready for instantiation. 112 * 113 * It is not safe to pass arbitrary input to this function, it is only safe to 114 * pass in output from previous calls to `serialize`. For more information see 115 * the Rust documentation - 116 * https://docs.wasmtime.dev/api/wasmtime/struct.Module.html#method.deserialize 117 */ 118 static Result<Module> deserialize(Engine &engine, Span<uint8_t> wasm) { 119 wasmtime_module_t *ret = nullptr; 120 auto *error = wasmtime_module_deserialize(engine.ptr.get(), wasm.data(), 121 wasm.size(), &ret); 122 if (error != nullptr) { 123 return Error(error); 124 } 125 return Module(ret); 126 } 127 128 /** 129 * \brief Deserializes a module from an on-disk file. 130 * 131 * This function is the same as `deserialize` except that it reads the data 132 * for the serialized module from the path on disk. This can be faster than 133 * the alternative which may require copying the data around. 134 * 135 * It is not safe to pass arbitrary input to this function, it is only safe to 136 * pass in output from previous calls to `serialize`. For more information see 137 * the Rust documentation - 138 * https://docs.wasmtime.dev/api/wasmtime/struct.Module.html#method.deserialize 139 */ 140 static Result<Module> deserialize_file(Engine &engine, 141 const std::string &path) { 142 wasmtime_module_t *ret = nullptr; 143 auto *error = 144 wasmtime_module_deserialize_file(engine.ptr.get(), path.c_str(), &ret); 145 if (error != nullptr) { 146 return Error(error); 147 } 148 return Module(ret); 149 } 150 151 /// Returns the list of types imported by this module. 152 ImportType::List imports() const { 153 ImportType::List list; 154 wasmtime_module_imports(ptr.get(), &list.list); 155 return list; 156 } 157 158 /// Returns the list of types exported by this module. 159 ExportType::List exports() const { 160 ExportType::List list; 161 wasmtime_module_exports(ptr.get(), &list.list); 162 return list; 163 } 164 165 #ifdef WASMTIME_FEATURE_COMPILER 166 /** 167 * \brief Serializes this module to a list of bytes. 168 * 169 * The returned bytes can then be used to later pass to `deserialize` to 170 * quickly recreate this module in a different process perhaps. 171 */ 172 Result<std::vector<uint8_t>> serialize() const { 173 wasm_byte_vec_t bytes; 174 auto *error = wasmtime_module_serialize(ptr.get(), &bytes); 175 if (error != nullptr) { 176 return Error(error); 177 } 178 std::vector<uint8_t> ret; 179 // NOLINTNEXTLINE TODO can this be done without triggering lints? 180 Span<uint8_t> raw(reinterpret_cast<uint8_t *>(bytes.data), bytes.size); 181 ret.assign(raw.begin(), raw.end()); 182 wasm_byte_vec_delete(&bytes); 183 return ret; 184 } 185 #endif // WASMTIME_FEATURE_COMPILER 186 }; 187 188 } // namespace wasmtime 189 190 #endif // WASMTIME_MODULE_HH 191