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