1 /** 2 * \file wasmtime/component/component.hh 3 */ 4 5 #ifndef WASMTIME_COMPONENT_COMPONENT_HH 6 #define WASMTIME_COMPONENT_COMPONENT_HH 7 8 #include <wasmtime/conf.h> 9 10 #ifdef WASMTIME_FEATURE_COMPONENT_MODEL 11 12 #include <memory> 13 #include <optional> 14 #include <string_view> 15 #include <vector> 16 #include <wasmtime/component/component.h> 17 #include <wasmtime/component/types/component.hh> 18 #include <wasmtime/engine.hh> 19 #include <wasmtime/error.hh> 20 #include <wasmtime/span.hh> 21 #include <wasmtime/wat.hh> 22 23 namespace wasmtime { 24 namespace component { 25 26 /** 27 * \brief An index to an exported item within a particular component. 28 * 29 * This structure is acquired from a `Component` and used to lookup exports on 30 * instances. 31 */ 32 class ExportIndex { 33 WASMTIME_CLONE_WRAPPER(ExportIndex, wasmtime_component_export_index); 34 }; 35 36 /** 37 * \brief Representation of a compiled WebAssembly component. 38 */ 39 class Component { 40 WASMTIME_CLONE_WRAPPER(Component, wasmtime_component); 41 42 #ifdef WASMTIME_FEATURE_COMPILER 43 /** 44 * \brief Compiles a component from the WebAssembly text format. 45 * 46 * This function will automatically use `wat2wasm` on the input and then 47 * delegate to the #compile function. 48 */ 49 static Result<Component> compile(Engine &engine, std::string_view wat) { 50 auto wasm = wat2wasm(wat); 51 if (!wasm) { 52 return wasm.err(); 53 } 54 auto bytes = wasm.ok(); 55 return compile(engine, bytes); 56 } 57 58 /** 59 * \brief Compiles a component from the WebAssembly binary format. 60 * 61 * This function compiles the provided WebAssembly binary specified by `wasm` 62 * within the compilation settings configured by `engine`. This method is 63 * synchronous and will not return until the component has finished compiling. 64 * 65 * This function can fail if the WebAssembly binary is invalid or doesn't 66 * validate (or similar). Note that this API does not compile WebAssembly 67 * modules, which is done with `Module` instead of `Component`. 68 */ 69 static Result<Component> compile(Engine &engine, Span<uint8_t> wasm) { 70 wasmtime_component_t *ret = nullptr; 71 auto *error = 72 wasmtime_component_new(engine.capi(), wasm.data(), wasm.size(), &ret); 73 if (error != nullptr) { 74 return Error(error); 75 } 76 return Component(ret); 77 } 78 #endif // WASMTIME_FEATURE_COMPILER 79 80 /** 81 * \brief Deserializes a previous list of bytes created with `serialize`. 82 * 83 * This function is intended to be much faster than `compile` where it uses 84 * the artifacts of a previous compilation to quickly create an in-memory 85 * component ready for instantiation. 86 * 87 * It is not safe to pass arbitrary input to this function, it is only safe to 88 * pass in output from previous calls to `serialize`. For more information see 89 * the Rust documentation - 90 * https://docs.wasmtime.dev/api/wasmtime/struct.Module.html#method.deserialize 91 */ 92 static Result<Component> deserialize(Engine &engine, Span<uint8_t> wasm) { 93 wasmtime_component_t *ret = nullptr; 94 auto *error = wasmtime_component_deserialize(engine.capi(), wasm.data(), 95 wasm.size(), &ret); 96 if (error != nullptr) { 97 return Error(error); 98 } 99 return Component(ret); 100 } 101 102 /** 103 * \brief Deserializes a component from an on-disk file. 104 * 105 * This function is the same as `deserialize` except that it reads the data 106 * for the serialized component from the path on disk. This can be faster than 107 * the alternative which may require copying the data around. 108 * 109 * It is not safe to pass arbitrary input to this function, it is only safe to 110 * pass in output from previous calls to `serialize`. For more information see 111 * the Rust documentation - 112 * https://docs.wasmtime.dev/api/wasmtime/struct.Module.html#method.deserialize 113 */ 114 static Result<Component> deserialize_file(Engine &engine, 115 const std::string &path) { 116 wasmtime_component_t *ret = nullptr; 117 auto *error = 118 wasmtime_component_deserialize_file(engine.capi(), path.c_str(), &ret); 119 if (error != nullptr) { 120 return Error(error); 121 } 122 return Component(ret); 123 } 124 125 #ifdef WASMTIME_FEATURE_COMPILER 126 /** 127 * \brief Serializes this component to a list of bytes. 128 * 129 * The returned bytes can then be used to later pass to `deserialize` to 130 * quickly recreate this component in a different process perhaps. 131 */ 132 Result<std::vector<uint8_t>> serialize() const { 133 wasm_byte_vec_t bytes; 134 auto *error = wasmtime_component_serialize(ptr.get(), &bytes); 135 if (error != nullptr) { 136 return Error(error); 137 } 138 std::vector<uint8_t> ret; 139 Span<uint8_t> raw(reinterpret_cast<uint8_t *>(bytes.data), bytes.size); 140 ret.assign(raw.begin(), raw.end()); 141 wasm_byte_vec_delete(&bytes); 142 return ret; 143 } 144 #endif // WASMTIME_FEATURE_COMPILER 145 146 /** 147 * \brief Returns the export index for the export named `name` in this 148 * component. 149 * 150 * The `instance` argument is an optionally provided index which is the 151 * instance under which the `name` should be looked up. 152 */ 153 std::optional<ExportIndex> export_index(ExportIndex *instance, 154 std::string_view name) { 155 auto ret = wasmtime_component_get_export_index( 156 capi(), instance ? instance->capi() : nullptr, name.data(), 157 name.size()); 158 if (ret) { 159 return ExportIndex(ret); 160 } 161 return std::nullopt; 162 }; 163 164 /// \brief Returns the type of this component. 165 ComponentType type() const { 166 return ComponentType(wasmtime_component_type(ptr.get())); 167 } 168 }; 169 170 } // namespace component 171 } // namespace wasmtime 172 173 #endif // WASMTIME_FEATURE_COMPONENT_MODEL 174 175 #endif // WASMTIME_COMPONENT_COMPONENT_HH 176