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 /// \brief Value of #wasmtime_component_valkind_t meaning that 270 /// #wasmtime_component_val_t is a map 271 #define WASMTIME_COMPONENT_MAP 22 272 273 struct wasmtime_component_val; 274 struct wasmtime_component_valrecord_entry; 275 struct wasmtime_component_valmap_entry; 276 277 #define DECLARE_VEC(name, type) \ 278 /** \brief A vec of a type */ \ 279 typedef struct name { \ 280 /** Length of the vec */ \ 281 size_t size; \ 282 /** Pointer to the elements */ \ 283 type *data; \ 284 } name##_t; \ 285 \ 286 /** \brief Create vec from \p ptr and \p size */ \ 287 WASM_API_EXTERN void name##_new(name##_t *out, size_t size, \ 288 const type *ptr); \ 289 /** \brief Create an empty vec */ \ 290 WASM_API_EXTERN void name##_new_empty(name##_t *out); \ 291 /** \brief Create a vec with length \p size */ \ 292 WASM_API_EXTERN void name##_new_uninit(name##_t *out, size_t size); \ 293 /** \brief Copy \p src to \p dst */ \ 294 WASM_API_EXTERN void name##_copy(name##_t *dst, const name##_t *src); \ 295 /** \brief Delete \p value */ \ 296 WASM_API_EXTERN void name##_delete(name##_t *value); 297 298 DECLARE_VEC(wasmtime_component_vallist, struct wasmtime_component_val) 299 DECLARE_VEC(wasmtime_component_valrecord, 300 struct wasmtime_component_valrecord_entry) 301 DECLARE_VEC(wasmtime_component_valtuple, struct wasmtime_component_val) 302 DECLARE_VEC(wasmtime_component_valflags, wasm_name_t) 303 DECLARE_VEC(wasmtime_component_valmap, struct wasmtime_component_valmap_entry) 304 305 #undef DECLARE_VEC 306 307 /// Represents a variant type 308 typedef struct { 309 /// The discriminant of the variant 310 wasm_name_t discriminant; 311 /// The payload of the variant 312 struct wasmtime_component_val *val; 313 } wasmtime_component_valvariant_t; 314 315 /// Represents a result type 316 typedef struct { 317 /// The discriminant of the result 318 bool is_ok; 319 /// The 'ok' value if #wasmtime_component_valresult_t::is_ok is `true`, else 320 /// the 'err' value 321 struct wasmtime_component_val *val; 322 } wasmtime_component_valresult_t; 323 324 /// \brief Represents possible runtime values which a component function can 325 /// either consume or produce 326 typedef union { 327 /// Field used if #wasmtime_component_val_t::kind is #WASMTIME_COMPONENT_BOOL 328 bool boolean; 329 /// Field used if #wasmtime_component_val_t::kind is #WASMTIME_COMPONENT_S8 330 int8_t s8; 331 /// Field used if #wasmtime_component_val_t::kind is #WASMTIME_COMPONENT_U8 332 uint8_t u8; 333 /// Field used if #wasmtime_component_val_t::kind is #WASMTIME_COMPONENT_S16 334 int16_t s16; 335 /// Field used if #wasmtime_component_val_t::kind is #WASMTIME_COMPONENT_U16 336 uint16_t u16; 337 /// Field used if #wasmtime_component_val_t::kind is #WASMTIME_COMPONENT_S32 338 int32_t s32; 339 /// Field used if #wasmtime_component_val_t::kind is #WASMTIME_COMPONENT_U32 340 uint32_t u32; 341 /// Field used if #wasmtime_component_val_t::kind is #WASMTIME_COMPONENT_S64 342 int64_t s64; 343 /// Field used if #wasmtime_component_val_t::kind is #WASMTIME_COMPONENT_U64 344 uint64_t u64; 345 /// Field used if #wasmtime_component_val_t::kind is #WASMTIME_COMPONENT_F32 346 float32_t f32; 347 /// Field used if #wasmtime_component_val_t::kind is #WASMTIME_COMPONENT_F64 348 float64_t f64; 349 /// Field used if #wasmtime_component_val_t::kind is #WASMTIME_COMPONENT_CHAR 350 uint32_t character; 351 /// Field used if #wasmtime_component_val_t::kind is 352 /// #WASMTIME_COMPONENT_STRING 353 wasm_name_t string; 354 /// Field used if #wasmtime_component_val_t::kind is #WASMTIME_COMPONENT_LIST 355 wasmtime_component_vallist_t list; 356 /// Field used if #wasmtime_component_val_t::kind is 357 /// #WASMTIME_COMPONENT_RECORD 358 wasmtime_component_valrecord_t record; 359 /// Field used if #wasmtime_component_val_t::kind is #WASMTIME_COMPONENT_TUPLE 360 wasmtime_component_valtuple_t tuple; 361 /// Field used if #wasmtime_component_val_t::kind is 362 /// #WASMTIME_COMPONENT_VARIANT 363 wasmtime_component_valvariant_t variant; 364 /// Field used if #wasmtime_component_val_t::kind is #WASMTIME_COMPONENT_ENUM 365 wasm_name_t enumeration; 366 /// Field used if #wasmtime_component_val_t::kind is 367 /// #WASMTIME_COMPONENT_OPTION 368 struct wasmtime_component_val *option; 369 /// Field used if #wasmtime_component_val_t::kind is 370 /// #WASMTIME_COMPONENT_RESULT 371 wasmtime_component_valresult_t result; 372 /// Field used if #wasmtime_component_val_t::kind is #WASMTIME_COMPONENT_FLAGS 373 wasmtime_component_valflags_t flags; 374 /// Field used if #wasmtime_component_val_t::kind is #WASMTIME_COMPONENT_MAP 375 wasmtime_component_valmap_t map; 376 /// Field used if #wasmtime_component_val_t::kind is 377 /// #WASMTIME_COMPONENT_RESOURCE 378 wasmtime_component_resource_any_t *resource; 379 } wasmtime_component_valunion_t; 380 381 /// \brief Represents possible runtime values which a component function can 382 /// either consume or produce 383 typedef struct wasmtime_component_val { 384 /// The type discriminant 385 wasmtime_component_valkind_t kind; 386 /// Value of type \ref kind 387 wasmtime_component_valunion_t of; 388 } wasmtime_component_val_t; 389 390 /// \brief A pair of a name and a value that represents one entry in a value 391 /// with kind #WASMTIME_COMPONENT_RECORD 392 typedef struct wasmtime_component_valrecord_entry { 393 /// The name of this entry 394 wasm_name_t name; 395 /// The value of this entry 396 wasmtime_component_val_t val; 397 } wasmtime_component_valrecord_entry_t; 398 399 /// \brief A pair of a key and a value that represents one entry in a value 400 /// with kind #WASMTIME_COMPONENT_MAP 401 typedef struct wasmtime_component_valmap_entry { 402 /// The key of this entry 403 wasmtime_component_val_t key; 404 /// The value of this entry 405 wasmtime_component_val_t value; 406 } wasmtime_component_valmap_entry_t; 407 408 /// \brief Allocates a new `wasmtime_component_val_t` on the heap, initializing 409 /// it with the contents of `val`. 410 /// 411 /// This function is intended to be used with the `variant`, `result`, and 412 /// `option` fields of `wasmtime_component_valunion_t`. The returned pointer 413 /// must be deallocated with `wasmtime_component_val_free` to deallocate the 414 /// heap-owned pointer. The `val` provided is "taken" meaning that its contents 415 /// are transferred to the returned pointer. This is not a clone operation but 416 /// instead is an operation used to move `val` onto a Wasmtime-defined heap 417 /// allocation. 418 /// 419 /// Note that `wasmtime_component_val_delete` should not be used for 420 /// deallocating the return value because that will deallocate the contents of 421 /// the value but not the value pointer itself. 422 WASM_API_EXTERN wasmtime_component_val_t * 423 wasmtime_component_val_new(wasmtime_component_val_t *val); 424 425 /// \brief Deallocates the heap-allocated value at `ptr`. 426 /// 427 /// This function will perform `wasmtime_component_val_delete` on `ptr` and 428 /// then it will deallocate `ptr` itself. This should not be used on 429 /// embedder-owned `ptr` storage. This function is used to clean up 430 /// allocations made by `wasmtime_component_val_new`. 431 WASM_API_EXTERN void wasmtime_component_val_free(wasmtime_component_val_t *ptr); 432 433 /// \brief Performs a deep copy of the provided `src`, storing the results into 434 /// `dst`. 435 /// 436 /// The `dst` value must have `wasmtime_component_val_delete` run to discard 437 /// its contents. 438 WASM_API_EXTERN void 439 wasmtime_component_val_clone(const wasmtime_component_val_t *src, 440 wasmtime_component_val_t *dst); 441 442 /// \brief Deallocates any memory owned by `value`. 443 /// 444 /// This function will look at `value->kind` and deallocate any memory if 445 /// necessary. For example lists will deallocate 446 /// `value->of.list`. 447 /// 448 /// Note that this function is not to be confused with 449 /// `wasmtime_component_val_free` which not only deallocates the memory that 450 /// `value` owns but also deallocates the memory of `value` itself. This 451 /// function should only be used when the embedder owns the pointer `value` 452 /// itself. 453 WASM_API_EXTERN void 454 wasmtime_component_val_delete(wasmtime_component_val_t *value); 455 456 #ifdef __cplusplus 457 } // extern "C" 458 #endif 459 460 #endif // WASMTIME_FEATURE_COMPONENT_MODEL 461 462 #endif // WASMTIME_COMPONENT_VAL_H 463