/** * \file wasmtime/module.hh */ #ifndef WASMTIME_MODULE_HH #define WASMTIME_MODULE_HH #include #include #include #include #include #include #include #include #include namespace wasmtime { /** * \brief Representation of a compiled WebAssembly module. * * This type contains JIT code of a compiled WebAssembly module. A `Module` is * connected to an `Engine` and can only be instantiated within that `Engine`. * You can inspect a `Module` for its type information. This is passed as an * argument to other APIs to instantiate it. */ class Module { WASMTIME_CLONE_WRAPPER(Module, wasmtime_module); #ifdef WASMTIME_FEATURE_COMPILER #ifdef WASMTIME_FEATURE_WAT /** * \brief Compiles a module from the WebAssembly text format. * * This function will automatically use `wat2wasm` on the input and then * delegate to the #compile function. */ static Result compile(Engine &engine, std::string_view wat) { auto wasm = wat2wasm(wat); if (!wasm) { return wasm.err(); } auto bytes = wasm.ok(); return compile(engine, bytes); } #endif // WASMTIME_FEATURE_WAT /** * \brief Compiles a module from the WebAssembly binary format. * * This function compiles the provided WebAssembly binary specified by `wasm` * within the compilation settings configured by `engine`. This method is * synchronous and will not return until the module has finished compiling. * * This function can fail if the WebAssembly binary is invalid or doesn't * validate (or similar). */ static Result compile(Engine &engine, Span wasm) { wasmtime_module_t *ret = nullptr; auto *error = wasmtime_module_new(engine.capi(), wasm.data(), wasm.size(), &ret); if (error != nullptr) { return Error(error); } return Module(ret); } /** * \brief Validates the provided WebAssembly binary without compiling it. * * This function will validate whether the provided binary is indeed valid * within the compilation settings of the `engine` provided. */ static Result validate(Engine &engine, Span wasm) { auto *error = wasmtime_module_validate(engine.capi(), wasm.data(), wasm.size()); if (error != nullptr) { return Error(error); } return std::monostate(); } #endif // WASMTIME_FEATURE_COMPILER /** * \brief Deserializes a previous list of bytes created with `serialize`. * * This function is intended to be much faster than `compile` where it uses * the artifacts of a previous compilation to quickly create an in-memory * module ready for instantiation. * * It is not safe to pass arbitrary input to this function, it is only safe to * pass in output from previous calls to `serialize`. For more information see * the Rust documentation - * https://docs.wasmtime.dev/api/wasmtime/struct.Module.html#method.deserialize */ static Result deserialize(Engine &engine, Span wasm) { wasmtime_module_t *ret = nullptr; auto *error = wasmtime_module_deserialize(engine.capi(), wasm.data(), wasm.size(), &ret); if (error != nullptr) { return Error(error); } return Module(ret); } /** * \brief Deserializes a module from an on-disk file. * * This function is the same as `deserialize` except that it reads the data * for the serialized module from the path on disk. This can be faster than * the alternative which may require copying the data around. * * It is not safe to pass arbitrary input to this function, it is only safe to * pass in output from previous calls to `serialize`. For more information see * the Rust documentation - * https://docs.wasmtime.dev/api/wasmtime/struct.Module.html#method.deserialize */ static Result deserialize_file(Engine &engine, const std::string &path) { wasmtime_module_t *ret = nullptr; auto *error = wasmtime_module_deserialize_file(engine.capi(), path.c_str(), &ret); if (error != nullptr) { return Error(error); } return Module(ret); } /// Returns the list of types imported by this module. ImportType::List imports() const { ImportType::List list; wasmtime_module_imports(ptr.get(), &list.list); return list; } /// Returns the list of types exported by this module. ExportType::List exports() const { ExportType::List list; wasmtime_module_exports(ptr.get(), &list.list); return list; } #ifdef WASMTIME_FEATURE_COMPILER /** * \brief Serializes this module to a list of bytes. * * The returned bytes can then be used to later pass to `deserialize` to * quickly recreate this module in a different process perhaps. */ Result> serialize() const { wasm_byte_vec_t bytes; auto *error = wasmtime_module_serialize(ptr.get(), &bytes); if (error != nullptr) { return Error(error); } std::vector ret; // NOLINTNEXTLINE TODO can this be done without triggering lints? Span raw(reinterpret_cast(bytes.data), bytes.size); ret.assign(raw.begin(), raw.end()); wasm_byte_vec_delete(&bytes); return ret; } #endif // WASMTIME_FEATURE_COMPILER }; } // namespace wasmtime #endif // WASMTIME_MODULE_HH