11819edbaSAlex Crichton /** 21819edbaSAlex Crichton * \file wasmtime/module.hh 31819edbaSAlex Crichton */ 41819edbaSAlex Crichton 51819edbaSAlex Crichton #ifndef WASMTIME_MODULE_HH 61819edbaSAlex Crichton #define WASMTIME_MODULE_HH 71819edbaSAlex Crichton 81819edbaSAlex Crichton #include <memory> 91819edbaSAlex Crichton #include <string_view> 101819edbaSAlex Crichton #include <wasmtime/engine.hh> 11311d023aSAlex Crichton #include <wasmtime/helpers.hh> 121819edbaSAlex Crichton #include <wasmtime/module.h> 131819edbaSAlex Crichton #include <wasmtime/span.hh> 141819edbaSAlex Crichton #include <wasmtime/types/export.hh> 151819edbaSAlex Crichton #include <wasmtime/types/import.hh> 161819edbaSAlex Crichton #include <wasmtime/wat.hh> 171819edbaSAlex Crichton 181819edbaSAlex Crichton namespace wasmtime { 191819edbaSAlex Crichton 201819edbaSAlex Crichton /** 211819edbaSAlex Crichton * \brief Representation of a compiled WebAssembly module. 221819edbaSAlex Crichton * 231819edbaSAlex Crichton * This type contains JIT code of a compiled WebAssembly module. A `Module` is 241819edbaSAlex Crichton * connected to an `Engine` and can only be instantiated within that `Engine`. 251819edbaSAlex Crichton * You can inspect a `Module` for its type information. This is passed as an 261819edbaSAlex Crichton * argument to other APIs to instantiate it. 271819edbaSAlex Crichton */ 281819edbaSAlex Crichton class Module { 29311d023aSAlex Crichton WASMTIME_CLONE_WRAPPER(Module, wasmtime_module); 301819edbaSAlex Crichton 311819edbaSAlex Crichton #ifdef WASMTIME_FEATURE_COMPILER 32*7a4f53a3SPiotr Sikora 33*7a4f53a3SPiotr Sikora #ifdef WASMTIME_FEATURE_WAT 341819edbaSAlex Crichton /** 351819edbaSAlex Crichton * \brief Compiles a module from the WebAssembly text format. 361819edbaSAlex Crichton * 371819edbaSAlex Crichton * This function will automatically use `wat2wasm` on the input and then 381819edbaSAlex Crichton * delegate to the #compile function. 391819edbaSAlex Crichton */ compile(Engine & engine,std::string_view wat)401819edbaSAlex Crichton static Result<Module> compile(Engine &engine, std::string_view wat) { 411819edbaSAlex Crichton auto wasm = wat2wasm(wat); 421819edbaSAlex Crichton if (!wasm) { 431819edbaSAlex Crichton return wasm.err(); 441819edbaSAlex Crichton } 451819edbaSAlex Crichton auto bytes = wasm.ok(); 461819edbaSAlex Crichton return compile(engine, bytes); 471819edbaSAlex Crichton } 48*7a4f53a3SPiotr Sikora #endif // WASMTIME_FEATURE_WAT 491819edbaSAlex Crichton 501819edbaSAlex Crichton /** 511819edbaSAlex Crichton * \brief Compiles a module from the WebAssembly binary format. 521819edbaSAlex Crichton * 531819edbaSAlex Crichton * This function compiles the provided WebAssembly binary specified by `wasm` 541819edbaSAlex Crichton * within the compilation settings configured by `engine`. This method is 551819edbaSAlex Crichton * synchronous and will not return until the module has finished compiling. 561819edbaSAlex Crichton * 571819edbaSAlex Crichton * This function can fail if the WebAssembly binary is invalid or doesn't 581819edbaSAlex Crichton * validate (or similar). 591819edbaSAlex Crichton */ compile(Engine & engine,Span<uint8_t> wasm)601819edbaSAlex Crichton static Result<Module> compile(Engine &engine, Span<uint8_t> wasm) { 611819edbaSAlex Crichton wasmtime_module_t *ret = nullptr; 621819edbaSAlex Crichton auto *error = 63311d023aSAlex Crichton wasmtime_module_new(engine.capi(), wasm.data(), wasm.size(), &ret); 641819edbaSAlex Crichton if (error != nullptr) { 651819edbaSAlex Crichton return Error(error); 661819edbaSAlex Crichton } 671819edbaSAlex Crichton return Module(ret); 681819edbaSAlex Crichton } 691819edbaSAlex Crichton 701819edbaSAlex Crichton /** 711819edbaSAlex Crichton * \brief Validates the provided WebAssembly binary without compiling it. 721819edbaSAlex Crichton * 731819edbaSAlex Crichton * This function will validate whether the provided binary is indeed valid 741819edbaSAlex Crichton * within the compilation settings of the `engine` provided. 751819edbaSAlex Crichton */ validate(Engine & engine,Span<uint8_t> wasm)761819edbaSAlex Crichton static Result<std::monostate> validate(Engine &engine, Span<uint8_t> wasm) { 771819edbaSAlex Crichton auto *error = 78311d023aSAlex Crichton wasmtime_module_validate(engine.capi(), wasm.data(), wasm.size()); 791819edbaSAlex Crichton if (error != nullptr) { 801819edbaSAlex Crichton return Error(error); 811819edbaSAlex Crichton } 821819edbaSAlex Crichton return std::monostate(); 831819edbaSAlex Crichton } 841819edbaSAlex Crichton #endif // WASMTIME_FEATURE_COMPILER 851819edbaSAlex Crichton 861819edbaSAlex Crichton /** 871819edbaSAlex Crichton * \brief Deserializes a previous list of bytes created with `serialize`. 881819edbaSAlex Crichton * 891819edbaSAlex Crichton * This function is intended to be much faster than `compile` where it uses 901819edbaSAlex Crichton * the artifacts of a previous compilation to quickly create an in-memory 911819edbaSAlex Crichton * module ready for instantiation. 921819edbaSAlex Crichton * 931819edbaSAlex Crichton * It is not safe to pass arbitrary input to this function, it is only safe to 941819edbaSAlex Crichton * pass in output from previous calls to `serialize`. For more information see 951819edbaSAlex Crichton * the Rust documentation - 961819edbaSAlex Crichton * https://docs.wasmtime.dev/api/wasmtime/struct.Module.html#method.deserialize 971819edbaSAlex Crichton */ deserialize(Engine & engine,Span<uint8_t> wasm)981819edbaSAlex Crichton static Result<Module> deserialize(Engine &engine, Span<uint8_t> wasm) { 991819edbaSAlex Crichton wasmtime_module_t *ret = nullptr; 100311d023aSAlex Crichton auto *error = wasmtime_module_deserialize(engine.capi(), wasm.data(), 1011819edbaSAlex Crichton wasm.size(), &ret); 1021819edbaSAlex Crichton if (error != nullptr) { 1031819edbaSAlex Crichton return Error(error); 1041819edbaSAlex Crichton } 1051819edbaSAlex Crichton return Module(ret); 1061819edbaSAlex Crichton } 1071819edbaSAlex Crichton 1081819edbaSAlex Crichton /** 1091819edbaSAlex Crichton * \brief Deserializes a module from an on-disk file. 1101819edbaSAlex Crichton * 1111819edbaSAlex Crichton * This function is the same as `deserialize` except that it reads the data 1121819edbaSAlex Crichton * for the serialized module from the path on disk. This can be faster than 1131819edbaSAlex Crichton * the alternative which may require copying the data around. 1141819edbaSAlex Crichton * 1151819edbaSAlex Crichton * It is not safe to pass arbitrary input to this function, it is only safe to 1161819edbaSAlex Crichton * pass in output from previous calls to `serialize`. For more information see 1171819edbaSAlex Crichton * the Rust documentation - 1181819edbaSAlex Crichton * https://docs.wasmtime.dev/api/wasmtime/struct.Module.html#method.deserialize 1191819edbaSAlex Crichton */ deserialize_file(Engine & engine,const std::string & path)1201819edbaSAlex Crichton static Result<Module> deserialize_file(Engine &engine, 1211819edbaSAlex Crichton const std::string &path) { 1221819edbaSAlex Crichton wasmtime_module_t *ret = nullptr; 1231819edbaSAlex Crichton auto *error = 124311d023aSAlex Crichton wasmtime_module_deserialize_file(engine.capi(), path.c_str(), &ret); 1251819edbaSAlex Crichton if (error != nullptr) { 1261819edbaSAlex Crichton return Error(error); 1271819edbaSAlex Crichton } 1281819edbaSAlex Crichton return Module(ret); 1291819edbaSAlex Crichton } 1301819edbaSAlex Crichton 1311819edbaSAlex Crichton /// Returns the list of types imported by this module. imports() const1321819edbaSAlex Crichton ImportType::List imports() const { 1331819edbaSAlex Crichton ImportType::List list; 1341819edbaSAlex Crichton wasmtime_module_imports(ptr.get(), &list.list); 1351819edbaSAlex Crichton return list; 1361819edbaSAlex Crichton } 1371819edbaSAlex Crichton 1381819edbaSAlex Crichton /// Returns the list of types exported by this module. exports() const1391819edbaSAlex Crichton ExportType::List exports() const { 1401819edbaSAlex Crichton ExportType::List list; 1411819edbaSAlex Crichton wasmtime_module_exports(ptr.get(), &list.list); 1421819edbaSAlex Crichton return list; 1431819edbaSAlex Crichton } 1441819edbaSAlex Crichton 1451819edbaSAlex Crichton #ifdef WASMTIME_FEATURE_COMPILER 1461819edbaSAlex Crichton /** 1471819edbaSAlex Crichton * \brief Serializes this module to a list of bytes. 1481819edbaSAlex Crichton * 1491819edbaSAlex Crichton * The returned bytes can then be used to later pass to `deserialize` to 1501819edbaSAlex Crichton * quickly recreate this module in a different process perhaps. 1511819edbaSAlex Crichton */ serialize() const1521819edbaSAlex Crichton Result<std::vector<uint8_t>> serialize() const { 1531819edbaSAlex Crichton wasm_byte_vec_t bytes; 1541819edbaSAlex Crichton auto *error = wasmtime_module_serialize(ptr.get(), &bytes); 1551819edbaSAlex Crichton if (error != nullptr) { 1561819edbaSAlex Crichton return Error(error); 1571819edbaSAlex Crichton } 1581819edbaSAlex Crichton std::vector<uint8_t> ret; 1591819edbaSAlex Crichton // NOLINTNEXTLINE TODO can this be done without triggering lints? 1601819edbaSAlex Crichton Span<uint8_t> raw(reinterpret_cast<uint8_t *>(bytes.data), bytes.size); 1611819edbaSAlex Crichton ret.assign(raw.begin(), raw.end()); 1621819edbaSAlex Crichton wasm_byte_vec_delete(&bytes); 1631819edbaSAlex Crichton return ret; 1641819edbaSAlex Crichton } 1651819edbaSAlex Crichton #endif // WASMTIME_FEATURE_COMPILER 1661819edbaSAlex Crichton }; 1671819edbaSAlex Crichton 1681819edbaSAlex Crichton } // namespace wasmtime 1691819edbaSAlex Crichton 1701819edbaSAlex Crichton #endif // WASMTIME_MODULE_HH 171