1 /// \file wasmtime/component/val.h 2 3 #ifndef WASMTIME_COMPONENT_VAL_H 4 #define WASMTIME_COMPONENT_VAL_H 5 6 #include <wasmtime/conf.h> 7 8 #ifdef WASMTIME_FEATURE_COMPONENT_MODEL 9 10 #include <stdint.h> 11 #include <wasm.h> 12 #include <wasmtime/component/types/resource.h> 13 #include <wasmtime/store.h> 14 15 #ifdef __cplusplus 16 extern "C" { 17 #endif 18 19 /// \brief Represents a component resource which can be either guest-owned or 20 /// host-owned. 21 /// 22 /// This type is an opaque type used to represent any component model resource. 23 /// Internally this tracks information about ownership, type, etc. Values of 24 /// this type have dynamic ownership guarantees associated with them. Notably 25 /// from a component-model perspective values of this type must either be 26 /// converted to a host resource with `wasmtime_component_resource_any_to_host` 27 /// or dropped via `wasmtime_component_resource_any_drop`. This is required to 28 /// handle various metadata tracking appropriately, and if this is not done 29 /// then the resource will be leaked into the store and a trap may be raised. 30 /// 31 /// Note that this type also has dynamic memory allocations associated with it 32 /// and users must call `wasmtime_component_resource_any_delete` to deallocate 33 /// the host-side resources. This destructor can be called in an RAII fashion 34 /// and will only clean up memory, not metadata related to the resource. 35 /// It is required to call `wasmtime_component_resource_any_delete` to prevent 36 /// leaking memory on the host. It's highly recommended to call 37 /// `wasmtime_component_resource_any_drop` to avoid leaking memory in a 38 /// long-lived store, but if this is forgotten then deallocating the store will 39 /// deallocate all memory still. 40 typedef struct wasmtime_component_resource_any 41 wasmtime_component_resource_any_t; 42 43 /// \brief Gets the type of a component resource. 44 /// 45 /// Returns an owned `wasmtime_component_resource_type_t` which represents the 46 /// type of this resource. 47 /// 48 /// The pointer returned from this function must be deallocated with 49 /// `wasmtime_component_resource_type_delete`. 50 WASM_API_EXTERN 51 wasmtime_component_resource_type_t *wasmtime_component_resource_any_type( 52 const wasmtime_component_resource_any_t *resource); 53 54 /// \brief Clones a component resource. 55 /// 56 /// Creates a new owned copy of a component resource. Note that the returned 57 /// resource still logically refers to the same resource as before, but this 58 /// can be convenient from an API perspective. Calls to 59 /// `wasmtime_component_resource_any_drop` need only happen 60 /// once-per-logical-resource, not once-per-handle-to-the-resource. Note though 61 /// that calls to `wasmtime_component_resource_any_delete` must happen 62 /// once-per-handle-to-the-resource. 63 /// 64 /// The pointer returned from this function must be deallocated with 65 /// `wasmtime_component_resource_any_delete`. 66 WASM_API_EXTERN 67 wasmtime_component_resource_any_t *wasmtime_component_resource_any_clone( 68 const wasmtime_component_resource_any_t *resource); 69 70 /// \brief Returns whether this resource is an `own`, or a `borrow` in the 71 /// component model. 72 WASM_API_EXTERN 73 bool wasmtime_component_resource_any_owned( 74 const wasmtime_component_resource_any_t *resource); 75 76 /// \brief Drops a component resource. 77 /// 78 /// This function is required to be called per "logical resource" to clean up 79 /// any borrow-tracking state in the store, for example. Additionally this may 80 /// invoke WebAssembly if it's a guest-owned resource with a destructor 81 /// associated with it. 82 /// 83 /// This operation is not to be confused with 84 /// `wasmtime_component_resource_any_delete` which deallocates host-related 85 /// memory for this resource. After `wasmtime_component_resource_any_drop` is 86 /// called it's still required to call 87 /// `wasmtime_component_resource_any_delete`. 88 WASM_API_EXTERN 89 wasmtime_error_t *wasmtime_component_resource_any_drop( 90 wasmtime_context_t *ctx, const wasmtime_component_resource_any_t *resource); 91 92 /// \brief Deallocates a component resource. 93 /// 94 /// This function deallocates any host-side memory associated with this 95 /// resource. This function does not perform any component-model related 96 /// cleanup, and `wasmtime_component_resource_any_drop` is required for that. 97 WASM_API_EXTERN 98 void wasmtime_component_resource_any_delete( 99 wasmtime_component_resource_any_t *resource); 100 101 /// \brief Represents a host-defined component resource. 102 /// 103 /// This structure is similar to `wasmtime_component_resource_any_t` except 104 /// that it unconditionally represents an embedder-defined resource via this 105 /// API. Host resources have a "rep" which is a 32-bit integer whose meaning 106 /// is defined by the host. This "rep" is trusted in the sense that the guest 107 /// cannot forge this so the embedder is the only one that can view this. 108 /// 109 /// Host resources also have a 32-bit type whose meaning is also defined by the 110 /// host and has no meaning internally. This is used to distinguish different 111 /// types of resources from one another. 112 /// 113 /// Also note that unlike `wasmtime_component_resource_any_t` host resources 114 /// do not have a "drop" operation. It's up to the host to define what it means 115 /// to drop an owned resource and handle that appropriately. 116 typedef struct wasmtime_component_resource_host 117 wasmtime_component_resource_host_t; 118 119 /// \brief Creates a new host-defined component resource. 120 /// 121 /// This function creates a new host-defined component resource with the 122 /// provided parameters. The `owned` parameter indicates whether this resource 123 /// is an `own` or a `borrow` in the component model. The `rep` and `ty` 124 /// parameters are 32-bit integers which only have meaning to the embedder and 125 /// are plumbed through with this resource. 126 /// 127 /// The pointer returned from this function must be deallocated with 128 /// `wasmtime_component_resource_host_delete`. 129 WASM_API_EXTERN 130 wasmtime_component_resource_host_t * 131 wasmtime_component_resource_host_new(bool owned, uint32_t rep, uint32_t ty); 132 133 /// \brief Clones a host-defined component resource. 134 /// 135 /// Creates a new owned copy of a host-defined component resource. Note that the 136 /// returned resource still logically refers to the same resource as before, 137 /// but this can be convenient from an API perspective. 138 /// 139 /// The pointer returned from this function must be deallocated with 140 /// `wasmtime_component_resource_host_delete`. 141 WASM_API_EXTERN 142 wasmtime_component_resource_host_t *wasmtime_component_resource_host_clone( 143 const wasmtime_component_resource_host_t *resource); 144 145 /// \brief Gets the "rep" of a host-defined component resource. 146 /// 147 /// Returns the 32-bit integer "rep" associated with this resource. This is a 148 /// trusted value that guests cannot forge. 149 WASM_API_EXTERN 150 uint32_t wasmtime_component_resource_host_rep( 151 const wasmtime_component_resource_host_t *resource); 152 153 /// \brief Gets the "type" of a host-defined component resource. 154 /// 155 /// Returns the 32-bit integer "type" associated with this resource. This is a 156 /// trusted value that guests cannot forge. 157 WASM_API_EXTERN 158 uint32_t wasmtime_component_resource_host_type( 159 const wasmtime_component_resource_host_t *resource); 160 161 /// \brief Returns whether this host-defined resource is an `own` or a `borrow` 162 /// in the component model. 163 WASM_API_EXTERN 164 bool wasmtime_component_resource_host_owned( 165 const wasmtime_component_resource_host_t *resource); 166 167 /// \brief Deallocates a host-defined component resource. 168 /// 169 /// This function deallocates any host-side memory associated with this 170 /// resource. 171 WASM_API_EXTERN 172 void wasmtime_component_resource_host_delete( 173 wasmtime_component_resource_host_t *resource); 174 175 /// \brief Attempts to convert a `wasmtime_component_resource_any_t` into a 176 /// `wasmtime_component_resource_host_t`. 177 /// 178 /// This function will attempt to convert the provided `resource` into a 179 /// host-defined resource. If the resource is indeed host-defined then a new 180 /// owned `wasmtime_component_resource_host_t` is returned via `ret`. If the 181 /// resource is guest-defined then an error is returned and `ret` is not 182 /// modified. 183 /// 184 /// If no error is returned then the pointer written to `ret` must be 185 /// deallocated with `wasmtime_component_resource_host_delete`. 186 WASM_API_EXTERN 187 wasmtime_error_t *wasmtime_component_resource_any_to_host( 188 wasmtime_context_t *ctx, const wasmtime_component_resource_any_t *resource, 189 wasmtime_component_resource_host_t **ret); 190 191 /// \brief Same as `wasmtime_component_resource_any_to_host` except for 192 /// converting the other way around. 193 /// 194 /// This can fail in some edge-case scenarios but typically does not fail. 195 WASM_API_EXTERN 196 wasmtime_error_t *wasmtime_component_resource_host_to_any( 197 wasmtime_context_t *ctx, const wasmtime_component_resource_host_t *resource, 198 wasmtime_component_resource_any_t **ret); 199 200 /// \brief Discriminant used in #wasmtime_component_val_t::kind 201 typedef uint8_t wasmtime_component_valkind_t; 202 203 /// \brief Value of #wasmtime_component_valkind_t meaning that 204 /// #wasmtime_component_val_t is a bool 205 #define WASMTIME_COMPONENT_BOOL 0 206 /// \brief Value of #wasmtime_component_valkind_t meaning that 207 /// #wasmtime_component_val_t is a s8 208 #define WASMTIME_COMPONENT_S8 1 209 /// \brief Value of #wasmtime_component_valkind_t meaning that 210 /// #wasmtime_component_val_t is a u8 211 #define WASMTIME_COMPONENT_U8 2 212 /// \brief Value of #wasmtime_component_valkind_t meaning that 213 /// #wasmtime_component_val_t is a s16 214 #define WASMTIME_COMPONENT_S16 3 215 /// \brief Value of #wasmtime_component_valkind_t meaning that 216 /// #wasmtime_component_val_t is a u16 217 #define WASMTIME_COMPONENT_U16 4 218 /// \brief Value of #wasmtime_component_valkind_t meaning that 219 /// #wasmtime_component_val_t is a s32 220 #define WASMTIME_COMPONENT_S32 5 221 /// \brief Value of #wasmtime_component_valkind_t meaning that 222 /// #wasmtime_component_val_t is a u32 223 #define WASMTIME_COMPONENT_U32 6 224 /// \brief Value of #wasmtime_component_valkind_t meaning that 225 /// #wasmtime_component_val_t is a s64 226 #define WASMTIME_COMPONENT_S64 7 227 /// \brief Value of #wasmtime_component_valkind_t meaning that 228 /// #wasmtime_component_val_t is a u64 229 #define WASMTIME_COMPONENT_U64 8 230 /// \brief Value of #wasmtime_component_valkind_t meaning that 231 /// #wasmtime_component_val_t is a f32 232 #define WASMTIME_COMPONENT_F32 9 233 /// \brief Value of #wasmtime_component_valkind_t meaning that 234 /// #wasmtime_component_val_t is a f64 235 #define WASMTIME_COMPONENT_F64 10 236 /// \brief Value of #wasmtime_component_valkind_t meaning that 237 /// #wasmtime_component_val_t is a char 238 #define WASMTIME_COMPONENT_CHAR 11 239 /// \brief Value of #wasmtime_component_valkind_t meaning that 240 /// #wasmtime_component_val_t is a string 241 #define WASMTIME_COMPONENT_STRING 12 242 /// \brief Value of #wasmtime_component_valkind_t meaning that 243 /// #wasmtime_component_val_t is a list 244 #define WASMTIME_COMPONENT_LIST 13 245 /// \brief Value of #wasmtime_component_valkind_t meaning that 246 /// #wasmtime_component_val_t is a record 247 #define WASMTIME_COMPONENT_RECORD 14 248 /// \brief Value of #wasmtime_component_valkind_t meaning that 249 /// #wasmtime_component_val_t is a tuple 250 #define WASMTIME_COMPONENT_TUPLE 15 251 /// \brief Value of #wasmtime_component_valkind_t meaning that 252 /// #wasmtime_component_val_t is a variant 253 #define WASMTIME_COMPONENT_VARIANT 16 254 /// \brief Value of #wasmtime_component_valkind_t meaning that 255 /// #wasmtime_component_val_t is a enum 256 #define WASMTIME_COMPONENT_ENUM 17 257 /// \brief Value of #wasmtime_component_valkind_t meaning that 258 /// #wasmtime_component_val_t is a option 259 #define WASMTIME_COMPONENT_OPTION 18 260 /// \brief Value of #wasmtime_component_valkind_t meaning that 261 /// #wasmtime_component_val_t is a result 262 #define WASMTIME_COMPONENT_RESULT 19 263 /// \brief Value of #wasmtime_component_valkind_t meaning that 264 /// #wasmtime_component_val_t is flags 265 #define WASMTIME_COMPONENT_FLAGS 20 266 /// \brief Value of #wasmtime_component_valkind_t meaning that 267 /// #wasmtime_component_val_t is a resource 268 #define WASMTIME_COMPONENT_RESOURCE 21 269 270 struct wasmtime_component_val; 271 struct wasmtime_component_valrecord_entry; 272 273 #define DECLARE_VEC(name, type) \ 274 /** \brief A vec of a type */ \ 275 typedef struct name { \ 276 /** Length of the vec */ \ 277 size_t size; \ 278 /** Pointer to the elements */ \ 279 type *data; \ 280 } name##_t; \ 281 \ 282 /** \brief Create vec from \p ptr and \p size */ \ 283 WASM_API_EXTERN void name##_new(name##_t *out, size_t size, \ 284 const type *ptr); \ 285 /** \brief Create an empty vec */ \ 286 WASM_API_EXTERN void name##_new_empty(name##_t *out); \ 287 /** \brief Create a vec with length \p size */ \ 288 WASM_API_EXTERN void name##_new_uninit(name##_t *out, size_t size); \ 289 /** \brief Copy \p src to \p dst */ \ 290 WASM_API_EXTERN void name##_copy(name##_t *dst, const name##_t *src); \ 291 /** \brief Delete \p value */ \ 292 WASM_API_EXTERN void name##_delete(name##_t *value); 293 294 DECLARE_VEC(wasmtime_component_vallist, struct wasmtime_component_val) 295 DECLARE_VEC(wasmtime_component_valrecord, 296 struct wasmtime_component_valrecord_entry) 297 DECLARE_VEC(wasmtime_component_valtuple, struct wasmtime_component_val) 298 DECLARE_VEC(wasmtime_component_valflags, wasm_name_t) 299 300 #undef DECLARE_VEC 301 302 /// Represents a variant type 303 typedef struct { 304 /// The discriminant of the variant 305 wasm_name_t discriminant; 306 /// The payload of the variant 307 struct wasmtime_component_val *val; 308 } wasmtime_component_valvariant_t; 309 310 /// Represents a result type 311 typedef struct { 312 /// The discriminant of the result 313 bool is_ok; 314 /// The 'ok' value if #wasmtime_component_valresult_t::is_ok is `true`, else 315 /// the 'err' value 316 struct wasmtime_component_val *val; 317 } wasmtime_component_valresult_t; 318 319 /// \brief Represents possible runtime values which a component function can 320 /// either consume or produce 321 typedef union { 322 /// Field used if #wasmtime_component_val_t::kind is #WASMTIME_COMPONENT_BOOL 323 bool boolean; 324 /// Field used if #wasmtime_component_val_t::kind is #WASMTIME_COMPONENT_S8 325 int8_t s8; 326 /// Field used if #wasmtime_component_val_t::kind is #WASMTIME_COMPONENT_U8 327 uint8_t u8; 328 /// Field used if #wasmtime_component_val_t::kind is #WASMTIME_COMPONENT_S16 329 int16_t s16; 330 /// Field used if #wasmtime_component_val_t::kind is #WASMTIME_COMPONENT_U16 331 uint16_t u16; 332 /// Field used if #wasmtime_component_val_t::kind is #WASMTIME_COMPONENT_S32 333 int32_t s32; 334 /// Field used if #wasmtime_component_val_t::kind is #WASMTIME_COMPONENT_U32 335 uint32_t u32; 336 /// Field used if #wasmtime_component_val_t::kind is #WASMTIME_COMPONENT_S64 337 int64_t s64; 338 /// Field used if #wasmtime_component_val_t::kind is #WASMTIME_COMPONENT_U64 339 uint64_t u64; 340 /// Field used if #wasmtime_component_val_t::kind is #WASMTIME_COMPONENT_F32 341 float32_t f32; 342 /// Field used if #wasmtime_component_val_t::kind is #WASMTIME_COMPONENT_F64 343 float64_t f64; 344 /// Field used if #wasmtime_component_val_t::kind is #WASMTIME_COMPONENT_CHAR 345 uint32_t character; 346 /// Field used if #wasmtime_component_val_t::kind is 347 /// #WASMTIME_COMPONENT_STRING 348 wasm_name_t string; 349 /// Field used if #wasmtime_component_val_t::kind is #WASMTIME_COMPONENT_LIST 350 wasmtime_component_vallist_t list; 351 /// Field used if #wasmtime_component_val_t::kind is 352 /// #WASMTIME_COMPONENT_RECORD 353 wasmtime_component_valrecord_t record; 354 /// Field used if #wasmtime_component_val_t::kind is #WASMTIME_COMPONENT_TUPLE 355 wasmtime_component_valtuple_t tuple; 356 /// Field used if #wasmtime_component_val_t::kind is 357 /// #WASMTIME_COMPONENT_VARIANT 358 wasmtime_component_valvariant_t variant; 359 /// Field used if #wasmtime_component_val_t::kind is #WASMTIME_COMPONENT_ENUM 360 wasm_name_t enumeration; 361 /// Field used if #wasmtime_component_val_t::kind is 362 /// #WASMTIME_COMPONENT_OPTION 363 struct wasmtime_component_val *option; 364 /// Field used if #wasmtime_component_val_t::kind is 365 /// #WASMTIME_COMPONENT_RESULT 366 wasmtime_component_valresult_t result; 367 /// Field used if #wasmtime_component_val_t::kind is #WASMTIME_COMPONENT_FLAGS 368 wasmtime_component_valflags_t flags; 369 /// Field used if #wasmtime_component_val_t::kind is 370 /// #WASMTIME_COMPONENT_RESOURCE 371 wasmtime_component_resource_any_t *resource; 372 } wasmtime_component_valunion_t; 373 374 /// \brief Represents possible runtime values which a component function can 375 /// either consume or produce 376 typedef struct wasmtime_component_val { 377 /// The type discriminant 378 wasmtime_component_valkind_t kind; 379 /// Value of type \ref kind 380 wasmtime_component_valunion_t of; 381 } wasmtime_component_val_t; 382 383 /// \brief A pair of a name and a value that represents one entry in a value 384 /// with kind #WASMTIME_COMPONENT_RECORD 385 typedef struct wasmtime_component_valrecord_entry { 386 /// The name of this entry 387 wasm_name_t name; 388 /// The value of this entry 389 wasmtime_component_val_t val; 390 } wasmtime_component_valrecord_entry_t; 391 392 /// \brief Allocates a new `wasmtime_component_val_t` on the heap, initializing 393 /// it with the contents of `val`. 394 /// 395 /// This function is intended to be used with the `variant`, `result`, and 396 /// `option` fields of `wasmtime_component_valunion_t`. The returned pointer 397 /// must be deallocated with `wasmtime_component_val_free` to deallocate the 398 /// heap-owned pointer. The `val` provided is "taken" meaning that its contents 399 /// are transferred to the returned pointer. This is not a clone operation but 400 /// instead is an operation used to move `val` onto a Wasmtime-defined heap 401 /// allocation. 402 /// 403 /// Note that `wasmtime_component_val_delete` should not be used for 404 /// deallocating the return value because that will deallocate the contents of 405 /// the value but not the value pointer itself. 406 WASM_API_EXTERN wasmtime_component_val_t * 407 wasmtime_component_val_new(wasmtime_component_val_t *val); 408 409 /// \brief Deallocates the heap-allocated value at `ptr`. 410 /// 411 /// This function will perform `wasmtime_component_val_delete` on `ptr` and 412 /// then it will deallocate `ptr` itself. This should not be used on 413 /// embedder-owned `ptr` storage. This function is used to clean up 414 /// allocations made by `wasmtime_component_val_new`. 415 WASM_API_EXTERN void wasmtime_component_val_free(wasmtime_component_val_t *ptr); 416 417 /// \brief Performs a deep copy of the provided `src`, storing the results into 418 /// `dst`. 419 /// 420 /// The `dst` value must have `wasmtime_component_val_delete` run to discard 421 /// its contents. 422 WASM_API_EXTERN void 423 wasmtime_component_val_clone(const wasmtime_component_val_t *src, 424 wasmtime_component_val_t *dst); 425 426 /// \brief Deallocates any memory owned by `value`. 427 /// 428 /// This function will look at `value->kind` and deallocate any memory if 429 /// necessary. For example lists will deallocate 430 /// `value->of.list`. 431 /// 432 /// Note that this function is not to be confused with 433 /// `wasmtime_component_val_free` which not only deallocates the memory that 434 /// `value` owns but also deallocates the memory of `value` itself. This 435 /// function should only be used when the embedder owns the pointer `value` 436 /// itself. 437 WASM_API_EXTERN void 438 wasmtime_component_val_delete(wasmtime_component_val_t *value); 439 440 #ifdef __cplusplus 441 } // extern "C" 442 #endif 443 444 #endif // WASMTIME_FEATURE_COMPONENT_MODEL 445 446 #endif // WASMTIME_COMPONENT_VAL_H 447