1579ec46bSAlex Crichton /** 2579ec46bSAlex Crichton * \file wasmtime/component/component.hh 3579ec46bSAlex Crichton */ 4579ec46bSAlex Crichton 5cde2e04fSAlex Crichton #ifndef WASMTIME_COMPONENT_COMPONENT_HH 6cde2e04fSAlex Crichton #define WASMTIME_COMPONENT_COMPONENT_HH 7579ec46bSAlex Crichton 8579ec46bSAlex Crichton #include <wasmtime/conf.h> 9579ec46bSAlex Crichton 10579ec46bSAlex Crichton #ifdef WASMTIME_FEATURE_COMPONENT_MODEL 11579ec46bSAlex Crichton 12579ec46bSAlex Crichton #include <memory> 13579ec46bSAlex Crichton #include <optional> 14579ec46bSAlex Crichton #include <string_view> 15579ec46bSAlex Crichton #include <vector> 16579ec46bSAlex Crichton #include <wasmtime/component/component.h> 1739ec36caSAlex Crichton #include <wasmtime/component/types/component.hh> 18579ec46bSAlex Crichton #include <wasmtime/engine.hh> 19579ec46bSAlex Crichton #include <wasmtime/error.hh> 20579ec46bSAlex Crichton #include <wasmtime/span.hh> 21579ec46bSAlex Crichton #include <wasmtime/wat.hh> 22579ec46bSAlex Crichton 23579ec46bSAlex Crichton namespace wasmtime { 24579ec46bSAlex Crichton namespace component { 25579ec46bSAlex Crichton 26579ec46bSAlex Crichton /** 27579ec46bSAlex Crichton * \brief An index to an exported item within a particular component. 28579ec46bSAlex Crichton * 29579ec46bSAlex Crichton * This structure is acquired from a `Component` and used to lookup exports on 30579ec46bSAlex Crichton * instances. 31579ec46bSAlex Crichton */ 32579ec46bSAlex Crichton class ExportIndex { 33311d023aSAlex Crichton WASMTIME_CLONE_WRAPPER(ExportIndex, wasmtime_component_export_index); 34579ec46bSAlex Crichton }; 35579ec46bSAlex Crichton 36579ec46bSAlex Crichton /** 37579ec46bSAlex Crichton * \brief Representation of a compiled WebAssembly component. 38579ec46bSAlex Crichton */ 39579ec46bSAlex Crichton class Component { 40311d023aSAlex Crichton WASMTIME_CLONE_WRAPPER(Component, wasmtime_component); 41579ec46bSAlex Crichton 42579ec46bSAlex Crichton #ifdef WASMTIME_FEATURE_COMPILER 43*7a4f53a3SPiotr Sikora 44*7a4f53a3SPiotr Sikora #ifdef WASMTIME_FEATURE_WAT 45579ec46bSAlex Crichton /** 46579ec46bSAlex Crichton * \brief Compiles a component from the WebAssembly text format. 47579ec46bSAlex Crichton * 48579ec46bSAlex Crichton * This function will automatically use `wat2wasm` on the input and then 49579ec46bSAlex Crichton * delegate to the #compile function. 50579ec46bSAlex Crichton */ compile(Engine & engine,std::string_view wat)51579ec46bSAlex Crichton static Result<Component> compile(Engine &engine, std::string_view wat) { 52579ec46bSAlex Crichton auto wasm = wat2wasm(wat); 53579ec46bSAlex Crichton if (!wasm) { 54579ec46bSAlex Crichton return wasm.err(); 55579ec46bSAlex Crichton } 56579ec46bSAlex Crichton auto bytes = wasm.ok(); 57579ec46bSAlex Crichton return compile(engine, bytes); 58579ec46bSAlex Crichton } 59*7a4f53a3SPiotr Sikora #endif // WASMTIME_FEATURE_WAT 60579ec46bSAlex Crichton 61579ec46bSAlex Crichton /** 62579ec46bSAlex Crichton * \brief Compiles a component from the WebAssembly binary format. 63579ec46bSAlex Crichton * 64579ec46bSAlex Crichton * This function compiles the provided WebAssembly binary specified by `wasm` 65579ec46bSAlex Crichton * within the compilation settings configured by `engine`. This method is 66579ec46bSAlex Crichton * synchronous and will not return until the component has finished compiling. 67579ec46bSAlex Crichton * 68579ec46bSAlex Crichton * This function can fail if the WebAssembly binary is invalid or doesn't 69579ec46bSAlex Crichton * validate (or similar). Note that this API does not compile WebAssembly 70579ec46bSAlex Crichton * modules, which is done with `Module` instead of `Component`. 71579ec46bSAlex Crichton */ compile(Engine & engine,Span<uint8_t> wasm)72579ec46bSAlex Crichton static Result<Component> compile(Engine &engine, Span<uint8_t> wasm) { 73579ec46bSAlex Crichton wasmtime_component_t *ret = nullptr; 74579ec46bSAlex Crichton auto *error = 75579ec46bSAlex Crichton wasmtime_component_new(engine.capi(), wasm.data(), wasm.size(), &ret); 76579ec46bSAlex Crichton if (error != nullptr) { 77579ec46bSAlex Crichton return Error(error); 78579ec46bSAlex Crichton } 79579ec46bSAlex Crichton return Component(ret); 80579ec46bSAlex Crichton } 81579ec46bSAlex Crichton #endif // WASMTIME_FEATURE_COMPILER 82579ec46bSAlex Crichton 83579ec46bSAlex Crichton /** 84579ec46bSAlex Crichton * \brief Deserializes a previous list of bytes created with `serialize`. 85579ec46bSAlex Crichton * 86579ec46bSAlex Crichton * This function is intended to be much faster than `compile` where it uses 87579ec46bSAlex Crichton * the artifacts of a previous compilation to quickly create an in-memory 88579ec46bSAlex Crichton * component ready for instantiation. 89579ec46bSAlex Crichton * 90579ec46bSAlex Crichton * It is not safe to pass arbitrary input to this function, it is only safe to 91579ec46bSAlex Crichton * pass in output from previous calls to `serialize`. For more information see 92579ec46bSAlex Crichton * the Rust documentation - 93579ec46bSAlex Crichton * https://docs.wasmtime.dev/api/wasmtime/struct.Module.html#method.deserialize 94579ec46bSAlex Crichton */ deserialize(Engine & engine,Span<uint8_t> wasm)95579ec46bSAlex Crichton static Result<Component> deserialize(Engine &engine, Span<uint8_t> wasm) { 96579ec46bSAlex Crichton wasmtime_component_t *ret = nullptr; 97579ec46bSAlex Crichton auto *error = wasmtime_component_deserialize(engine.capi(), wasm.data(), 98579ec46bSAlex Crichton wasm.size(), &ret); 99579ec46bSAlex Crichton if (error != nullptr) { 100579ec46bSAlex Crichton return Error(error); 101579ec46bSAlex Crichton } 102579ec46bSAlex Crichton return Component(ret); 103579ec46bSAlex Crichton } 104579ec46bSAlex Crichton 105579ec46bSAlex Crichton /** 106579ec46bSAlex Crichton * \brief Deserializes a component from an on-disk file. 107579ec46bSAlex Crichton * 108579ec46bSAlex Crichton * This function is the same as `deserialize` except that it reads the data 109579ec46bSAlex Crichton * for the serialized component from the path on disk. This can be faster than 110579ec46bSAlex Crichton * the alternative which may require copying the data around. 111579ec46bSAlex Crichton * 112579ec46bSAlex Crichton * It is not safe to pass arbitrary input to this function, it is only safe to 113579ec46bSAlex Crichton * pass in output from previous calls to `serialize`. For more information see 114579ec46bSAlex Crichton * the Rust documentation - 115579ec46bSAlex Crichton * https://docs.wasmtime.dev/api/wasmtime/struct.Module.html#method.deserialize 116579ec46bSAlex Crichton */ deserialize_file(Engine & engine,const std::string & path)117579ec46bSAlex Crichton static Result<Component> deserialize_file(Engine &engine, 118579ec46bSAlex Crichton const std::string &path) { 119579ec46bSAlex Crichton wasmtime_component_t *ret = nullptr; 120579ec46bSAlex Crichton auto *error = 121579ec46bSAlex Crichton wasmtime_component_deserialize_file(engine.capi(), path.c_str(), &ret); 122579ec46bSAlex Crichton if (error != nullptr) { 123579ec46bSAlex Crichton return Error(error); 124579ec46bSAlex Crichton } 125579ec46bSAlex Crichton return Component(ret); 126579ec46bSAlex Crichton } 127579ec46bSAlex Crichton 128579ec46bSAlex Crichton #ifdef WASMTIME_FEATURE_COMPILER 129579ec46bSAlex Crichton /** 130579ec46bSAlex Crichton * \brief Serializes this component to a list of bytes. 131579ec46bSAlex Crichton * 132579ec46bSAlex Crichton * The returned bytes can then be used to later pass to `deserialize` to 133579ec46bSAlex Crichton * quickly recreate this component in a different process perhaps. 134579ec46bSAlex Crichton */ serialize() const135579ec46bSAlex Crichton Result<std::vector<uint8_t>> serialize() const { 136579ec46bSAlex Crichton wasm_byte_vec_t bytes; 137579ec46bSAlex Crichton auto *error = wasmtime_component_serialize(ptr.get(), &bytes); 138579ec46bSAlex Crichton if (error != nullptr) { 139579ec46bSAlex Crichton return Error(error); 140579ec46bSAlex Crichton } 141579ec46bSAlex Crichton std::vector<uint8_t> ret; 142579ec46bSAlex Crichton Span<uint8_t> raw(reinterpret_cast<uint8_t *>(bytes.data), bytes.size); 143579ec46bSAlex Crichton ret.assign(raw.begin(), raw.end()); 144579ec46bSAlex Crichton wasm_byte_vec_delete(&bytes); 145579ec46bSAlex Crichton return ret; 146579ec46bSAlex Crichton } 147579ec46bSAlex Crichton #endif // WASMTIME_FEATURE_COMPILER 148579ec46bSAlex Crichton 149579ec46bSAlex Crichton /** 150579ec46bSAlex Crichton * \brief Returns the export index for the export named `name` in this 151579ec46bSAlex Crichton * component. 152579ec46bSAlex Crichton * 153579ec46bSAlex Crichton * The `instance` argument is an optionally provided index which is the 154579ec46bSAlex Crichton * instance under which the `name` should be looked up. 155579ec46bSAlex Crichton */ export_index(ExportIndex * instance,std::string_view name)156579ec46bSAlex Crichton std::optional<ExportIndex> export_index(ExportIndex *instance, 157579ec46bSAlex Crichton std::string_view name) { 158579ec46bSAlex Crichton auto ret = wasmtime_component_get_export_index( 159579ec46bSAlex Crichton capi(), instance ? instance->capi() : nullptr, name.data(), 160579ec46bSAlex Crichton name.size()); 161579ec46bSAlex Crichton if (ret) { 162579ec46bSAlex Crichton return ExportIndex(ret); 163579ec46bSAlex Crichton } 164579ec46bSAlex Crichton return std::nullopt; 165579ec46bSAlex Crichton }; 16639ec36caSAlex Crichton 16739ec36caSAlex Crichton /// \brief Returns the type of this component. type() const16839ec36caSAlex Crichton ComponentType type() const { 16939ec36caSAlex Crichton return ComponentType(wasmtime_component_type(ptr.get())); 17039ec36caSAlex Crichton } 171579ec46bSAlex Crichton }; 172579ec46bSAlex Crichton 173579ec46bSAlex Crichton } // namespace component 174579ec46bSAlex Crichton } // namespace wasmtime 175579ec46bSAlex Crichton 176579ec46bSAlex Crichton #endif // WASMTIME_FEATURE_COMPONENT_MODEL 177579ec46bSAlex Crichton 178cde2e04fSAlex Crichton #endif // WASMTIME_COMPONENT_COMPONENT_HH 179