@@ -126,6 +126,222 @@ WASM_API_EXTERN bool wasmtime_eqref_i31_get_s(wasmtime_context_t *context,
126126 const wasmtime_eqref_t * eqref ,
127127 int32_t * dst );
128128
129+ // ============================================================================
130+ // StructRef
131+ // ============================================================================
132+
133+ /**
134+ * \brief Discriminant for storage types in struct/array field types.
135+ *
136+ * Extends #wasmtime_valkind_t with packed storage types
137+ * #WASMTIME_STORAGE_KIND_I8 and #WASMTIME_STORAGE_KIND_I16.
138+ */
139+ typedef uint8_t wasmtime_storage_kind_t ;
140+
141+ /// \brief An 8-bit packed integer (only valid inside struct/array fields).
142+ #define WASMTIME_STORAGE_KIND_I8 9
143+ /// \brief A 16-bit packed integer (only valid inside struct/array fields).
144+ #define WASMTIME_STORAGE_KIND_I16 10
145+
146+ /**
147+ * \typedef wasmtime_field_type_t
148+ * \brief Convenience alias for #wasmtime_field_type
149+ *
150+ * \struct wasmtime_field_type
151+ * \brief Describes the type and mutability of a struct field or array element.
152+ */
153+ typedef struct wasmtime_field_type {
154+ /// The storage type of this field. Use #WASMTIME_I32, #WASMTIME_I64,
155+ /// #WASMTIME_F32, etc. for value types, or #WASMTIME_STORAGE_KIND_I8 /
156+ /// #WASMTIME_STORAGE_KIND_I16 for packed types.
157+ wasmtime_storage_kind_t kind ;
158+ /// Whether this field is mutable. `true` for mutable, `false` for
159+ /// immutable.
160+ bool mutable_ ;
161+ } wasmtime_field_type_t ;
162+
163+ /**
164+ * \brief An opaque handle to a WebAssembly struct type definition.
165+ *
166+ * A struct type describes the fields of a struct. It is used to create a
167+ * #wasmtime_struct_ref_pre_t, which can then allocate struct instances.
168+ *
169+ * Owned. Must be deleted with #wasmtime_struct_type_delete.
170+ */
171+ typedef struct wasmtime_struct_type wasmtime_struct_type_t ;
172+
173+ /**
174+ * \brief Create a new struct type.
175+ *
176+ * \param engine The engine to register the type with.
177+ * \param fields Pointer to an array of field type descriptors.
178+ * \param nfields Number of fields.
179+ *
180+ * \return Returns a new struct type, or NULL on error (e.g. invalid field
181+ * types).
182+ */
183+ WASM_API_EXTERN wasmtime_struct_type_t *
184+ wasmtime_struct_type_new (const wasm_engine_t * engine ,
185+ const wasmtime_field_type_t * fields , size_t nfields );
186+
187+ /**
188+ * \brief Delete a struct type.
189+ */
190+ WASM_API_EXTERN void wasmtime_struct_type_delete (wasmtime_struct_type_t * ty );
191+
192+ /**
193+ * \brief An opaque, pre-allocated, and registered struct layout for faster
194+ * allocation.
195+ *
196+ * Created from a #wasmtime_struct_type_t and a store context. Reusable for
197+ * allocating many struct instances of the same type.
198+ *
199+ * Owned. Must be deleted with #wasmtime_struct_ref_pre_delete.
200+ */
201+ typedef struct wasmtime_struct_ref_pre wasmtime_struct_ref_pre_t ;
202+
203+ /**
204+ * \brief Create a new struct pre-allocator.
205+ *
206+ * \param context The store context.
207+ * \param ty The struct type.
208+ *
209+ * \return Returns a new struct ref pre-allocator.
210+ */
211+ WASM_API_EXTERN wasmtime_struct_ref_pre_t *
212+ wasmtime_struct_ref_pre_new (wasmtime_context_t * context ,
213+ const wasmtime_struct_type_t * ty );
214+
215+ /**
216+ * \brief Delete a struct pre-allocator.
217+ */
218+ WASM_API_EXTERN void
219+ wasmtime_struct_ref_pre_delete (wasmtime_struct_ref_pre_t * pre );
220+
221+ /**
222+ * \typedef wasmtime_structref_t
223+ * \brief Convenience alias for #wasmtime_structref
224+ *
225+ * \struct wasmtime_structref
226+ * \brief A WebAssembly `structref` value.
227+ *
228+ * This structure represents a reference to a GC struct. It is a subtype of
229+ * `eqref` and `anyref`.
230+ *
231+ * Values must be explicitly unrooted via #wasmtime_structref_unroot.
232+ */
233+ typedef struct wasmtime_structref {
234+ /// Internal metadata.
235+ uint64_t store_id ;
236+ /// Internal to Wasmtime.
237+ uint32_t __private1 ;
238+ /// Internal to Wasmtime.
239+ uint32_t __private2 ;
240+ /// Internal to Wasmtime.
241+ void * __private3 ;
242+ } wasmtime_structref_t ;
243+
244+ /// \brief Initialize the `ref` to a null `structref` value.
245+ static inline void wasmtime_structref_set_null (wasmtime_structref_t * ref ) {
246+ ref -> store_id = 0 ;
247+ }
248+
249+ /// \brief Returns whether the provided `ref` is a null `structref` value.
250+ static inline bool wasmtime_structref_is_null (const wasmtime_structref_t * ref ) {
251+ return ref -> store_id == 0 ;
252+ }
253+
254+ /**
255+ * \brief Allocate a new struct instance.
256+ *
257+ * \param context The store context.
258+ * \param pre The struct pre-allocator.
259+ * \param fields Pointer to array of field values (#wasmtime_val_t).
260+ * \param nfields Number of fields (must match the struct type).
261+ * \param out Receives the new structref on success.
262+ *
263+ * \return NULL on success, or a #wasmtime_error_t on failure.
264+ */
265+ WASM_API_EXTERN wasmtime_error_t * wasmtime_structref_new (
266+ wasmtime_context_t * context , const wasmtime_struct_ref_pre_t * pre ,
267+ const wasmtime_val_t * fields , size_t nfields , wasmtime_structref_t * out );
268+
269+ /**
270+ * \brief Clone a `structref`, creating a new root.
271+ */
272+ WASM_API_EXTERN void
273+ wasmtime_structref_clone (const wasmtime_structref_t * structref ,
274+ wasmtime_structref_t * out );
275+
276+ /**
277+ * \brief Unroot a `structref` to allow garbage collection.
278+ */
279+ WASM_API_EXTERN void wasmtime_structref_unroot (wasmtime_structref_t * ref );
280+
281+ /**
282+ * \brief Upcast a `structref` to an `anyref`.
283+ */
284+ WASM_API_EXTERN void
285+ wasmtime_structref_to_anyref (const wasmtime_structref_t * structref ,
286+ wasmtime_anyref_t * out );
287+
288+ /**
289+ * \brief Upcast a `structref` to an `eqref`.
290+ */
291+ WASM_API_EXTERN void
292+ wasmtime_structref_to_eqref (const wasmtime_structref_t * structref ,
293+ wasmtime_eqref_t * out );
294+
295+ /**
296+ * \brief Read a field from a struct.
297+ *
298+ * \param context The store context.
299+ * \param structref The struct to read from (not consumed).
300+ * \param index The field index.
301+ * \param out Receives the field value on success.
302+ *
303+ * \return NULL on success, or a #wasmtime_error_t on failure.
304+ */
305+ WASM_API_EXTERN wasmtime_error_t *
306+ wasmtime_structref_field (wasmtime_context_t * context ,
307+ const wasmtime_structref_t * structref , size_t index ,
308+ wasmtime_val_t * out );
309+
310+ /**
311+ * \brief Set a field of a struct.
312+ *
313+ * \param context The store context.
314+ * \param structref The struct to write to (not consumed).
315+ * \param index The field index.
316+ * \param val The value to write (not consumed; caller must still unroot if
317+ * applicable).
318+ *
319+ * \return NULL on success, or a #wasmtime_error_t on failure.
320+ */
321+ WASM_API_EXTERN wasmtime_error_t *
322+ wasmtime_structref_set_field (wasmtime_context_t * context ,
323+ const wasmtime_structref_t * structref ,
324+ size_t index , const wasmtime_val_t * val );
325+
326+ /**
327+ * \brief Test whether an `eqref` is a `structref`.
328+ *
329+ * Returns `false` for null references.
330+ */
331+ WASM_API_EXTERN bool wasmtime_eqref_is_struct (wasmtime_context_t * context ,
332+ const wasmtime_eqref_t * eqref );
333+
334+ /**
335+ * \brief Downcast an `eqref` to a `structref`.
336+ *
337+ * If the given `eqref` is a `structref`, a new root for it is stored in `out`
338+ * and `true` is returned. Otherwise `false` is returned and `out` is set to
339+ * null.
340+ */
341+ WASM_API_EXTERN bool wasmtime_eqref_as_struct (wasmtime_context_t * context ,
342+ const wasmtime_eqref_t * eqref ,
343+ wasmtime_structref_t * out );
344+
129345#ifdef __cplusplus
130346} // extern "C"
131347#endif
0 commit comments