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