Skip to main content

wasmtime_c_api/
structref.rs

1use crate::{WasmtimeStoreContextMut, wasmtime_anyref_t, wasmtime_eqref_t, wasmtime_struct_type_t};
2use std::mem::MaybeUninit;
3use wasmtime::{OwnedRooted, RootScope, StructRef, StructRefPre, Val};
4
5crate::anyref::ref_wrapper!({
6    wasmtime: StructRef,
7    capi: wasmtime_structref_t,
8    clone: wasmtime_structref_clone,
9    unroot: wasmtime_structref_unroot,
10});
11
12pub struct wasmtime_struct_ref_pre_t {
13    pre: StructRefPre,
14}
15wasmtime_c_api_macros::declare_own!(wasmtime_struct_ref_pre_t);
16
17#[unsafe(no_mangle)]
18pub extern "C" fn wasmtime_struct_ref_pre_new(
19    cx: WasmtimeStoreContextMut<'_>,
20    ty: &wasmtime_struct_type_t,
21) -> Box<wasmtime_struct_ref_pre_t> {
22    let pre = StructRefPre::new(cx, ty.ty.clone());
23    Box::new(wasmtime_struct_ref_pre_t { pre })
24}
25
26#[unsafe(no_mangle)]
27pub unsafe extern "C" fn wasmtime_structref_new(
28    mut cx: WasmtimeStoreContextMut<'_>,
29    pre: &wasmtime_struct_ref_pre_t,
30    fields: *const crate::wasmtime_val_t,
31    nfields: usize,
32    out: &mut MaybeUninit<wasmtime_structref_t>,
33) -> Option<Box<crate::wasmtime_error_t>> {
34    let c_fields = crate::slice_from_raw_parts(fields, nfields);
35    let mut scope = RootScope::new(&mut cx);
36    let vals: Vec<Val> = c_fields.iter().map(|v| v.to_val(&mut scope)).collect();
37    match StructRef::new(&mut scope, &pre.pre, &vals) {
38        Ok(structref) => {
39            let owned = structref
40                .to_owned_rooted(&mut scope)
41                .expect("just allocated");
42            out.write(Some(owned).into());
43            None
44        }
45        Err(e) => {
46            out.write(None::<OwnedRooted<StructRef>>.into());
47            Some(Box::new(e.into()))
48        }
49    }
50}
51
52#[unsafe(no_mangle)]
53pub unsafe extern "C" fn wasmtime_structref_to_anyref(
54    structref: Option<&wasmtime_structref_t>,
55    out: &mut MaybeUninit<wasmtime_anyref_t>,
56) {
57    let anyref = structref
58        .and_then(|s| s.as_wasmtime())
59        .map(|s| s.to_anyref());
60    out.write(anyref.into());
61}
62
63#[unsafe(no_mangle)]
64pub unsafe extern "C" fn wasmtime_structref_to_eqref(
65    structref: Option<&wasmtime_structref_t>,
66    out: &mut MaybeUninit<wasmtime_eqref_t>,
67) {
68    let eqref = structref
69        .and_then(|s| s.as_wasmtime())
70        .map(|s| s.to_eqref());
71    out.write(eqref.into());
72}
73
74#[unsafe(no_mangle)]
75pub unsafe extern "C" fn wasmtime_structref_field(
76    mut cx: WasmtimeStoreContextMut<'_>,
77    structref: Option<&wasmtime_structref_t>,
78    index: usize,
79    out: &mut MaybeUninit<crate::wasmtime_val_t>,
80) -> Option<Box<crate::wasmtime_error_t>> {
81    let result = (|| {
82        let structref = structref
83            .and_then(|s| s.as_wasmtime())
84            .ok_or_else(|| wasmtime::format_err!("non-null structref required"))?;
85        let mut scope = RootScope::new(&mut cx);
86        let rooted = structref.to_rooted(&mut scope);
87        let val = rooted.field(&mut scope, index)?;
88        Ok(crate::wasmtime_val_t::from_val(&mut scope, val))
89    })();
90    crate::handle_result(result, |val| {
91        out.write(val);
92    })
93}
94
95#[unsafe(no_mangle)]
96pub unsafe extern "C" fn wasmtime_structref_set_field(
97    mut cx: WasmtimeStoreContextMut<'_>,
98    structref: Option<&wasmtime_structref_t>,
99    index: usize,
100    val: &crate::wasmtime_val_t,
101) -> Option<Box<crate::wasmtime_error_t>> {
102    let result = (|| {
103        let structref = structref
104            .and_then(|s| s.as_wasmtime())
105            .ok_or_else(|| wasmtime::format_err!("non-null structref required"))?;
106        let mut scope = RootScope::new(&mut cx);
107        let rust_val = val.to_val(&mut scope);
108        structref.set_field(&mut scope, index, rust_val)
109    })();
110    crate::handle_result(result, |()| {})
111}
112
113#[unsafe(no_mangle)]
114pub unsafe extern "C" fn wasmtime_structref_type(
115    mut cx: WasmtimeStoreContextMut<'_>,
116    structref: Option<&wasmtime_structref_t>,
117) -> Option<Box<crate::wasmtime_struct_type_t>> {
118    let structref = structref.and_then(|a| a.as_wasmtime())?;
119    let ty = structref.ty(&mut cx).expect("should be rooted");
120    Some(Box::new(ty.into()))
121}