Skip to main content

wasmtime_c_api/
arrayref.rs

1use crate::{WasmtimeStoreContextMut, wasmtime_anyref_t, wasmtime_array_type_t, wasmtime_eqref_t};
2use std::mem::MaybeUninit;
3use wasmtime::{ArrayRef, ArrayRefPre, OwnedRooted, RootScope};
4
5crate::anyref::ref_wrapper!({
6    wasmtime: ArrayRef,
7    capi: wasmtime_arrayref_t,
8    clone: wasmtime_arrayref_clone,
9    unroot: wasmtime_arrayref_unroot,
10});
11
12pub struct wasmtime_array_ref_pre_t {
13    pre: ArrayRefPre,
14}
15wasmtime_c_api_macros::declare_own!(wasmtime_array_ref_pre_t);
16
17#[unsafe(no_mangle)]
18pub extern "C" fn wasmtime_array_ref_pre_new(
19    cx: WasmtimeStoreContextMut<'_>,
20    ty: &wasmtime_array_type_t,
21) -> Box<wasmtime_array_ref_pre_t> {
22    let pre = ArrayRefPre::new(cx, ty.ty.clone());
23    Box::new(wasmtime_array_ref_pre_t { pre })
24}
25
26#[unsafe(no_mangle)]
27pub unsafe extern "C" fn wasmtime_arrayref_new(
28    mut cx: WasmtimeStoreContextMut<'_>,
29    pre: &wasmtime_array_ref_pre_t,
30    elem: &crate::wasmtime_val_t,
31    len: u32,
32    out: &mut MaybeUninit<wasmtime_arrayref_t>,
33) -> Option<Box<crate::wasmtime_error_t>> {
34    let mut scope = RootScope::new(&mut cx);
35    let val = elem.to_val(&mut scope);
36    match ArrayRef::new(&mut scope, &pre.pre, &val, len) {
37        Ok(arrayref) => {
38            let owned = arrayref
39                .to_owned_rooted(&mut scope)
40                .expect("just allocated");
41            out.write(Some(owned).into());
42            None
43        }
44        Err(e) => {
45            out.write(None::<OwnedRooted<ArrayRef>>.into());
46            Some(Box::new(e.into()))
47        }
48    }
49}
50
51#[unsafe(no_mangle)]
52pub unsafe extern "C" fn wasmtime_arrayref_to_anyref(
53    arrayref: Option<&wasmtime_arrayref_t>,
54    out: &mut MaybeUninit<wasmtime_anyref_t>,
55) {
56    let anyref = arrayref
57        .and_then(|a| a.as_wasmtime())
58        .map(|a| a.to_anyref());
59    out.write(anyref.into());
60}
61
62#[unsafe(no_mangle)]
63pub unsafe extern "C" fn wasmtime_arrayref_to_eqref(
64    arrayref: Option<&wasmtime_arrayref_t>,
65    out: &mut MaybeUninit<wasmtime_eqref_t>,
66) {
67    let eqref = arrayref.and_then(|a| a.as_wasmtime()).map(|a| a.to_eqref());
68    out.write(eqref.into());
69}
70
71#[unsafe(no_mangle)]
72pub unsafe extern "C" fn wasmtime_arrayref_len(
73    cx: WasmtimeStoreContextMut<'_>,
74    arrayref: Option<&wasmtime_arrayref_t>,
75    out: &mut MaybeUninit<u32>,
76) -> Option<Box<crate::wasmtime_error_t>> {
77    let result = (|| {
78        let arrayref = arrayref
79            .and_then(|a| a.as_wasmtime())
80            .ok_or_else(|| wasmtime::format_err!("non-null arrayref required"))?;
81        arrayref.len(&cx)
82    })();
83    crate::handle_result(result, |len| {
84        out.write(len);
85    })
86}
87
88#[unsafe(no_mangle)]
89pub unsafe extern "C" fn wasmtime_arrayref_get(
90    mut cx: WasmtimeStoreContextMut<'_>,
91    arrayref: Option<&wasmtime_arrayref_t>,
92    index: u32,
93    out: &mut MaybeUninit<crate::wasmtime_val_t>,
94) -> Option<Box<crate::wasmtime_error_t>> {
95    let result = (|| {
96        let arrayref = arrayref
97            .and_then(|a| a.as_wasmtime())
98            .ok_or_else(|| wasmtime::format_err!("non-null arrayref required"))?;
99        let mut scope = RootScope::new(&mut cx);
100        let rooted = arrayref.to_rooted(&mut scope);
101        let val = rooted.get(&mut scope, index)?;
102        Ok(crate::wasmtime_val_t::from_val(&mut scope, val))
103    })();
104    crate::handle_result(result, |val| {
105        out.write(val);
106    })
107}
108
109#[unsafe(no_mangle)]
110pub unsafe extern "C" fn wasmtime_arrayref_set(
111    mut cx: WasmtimeStoreContextMut<'_>,
112    arrayref: Option<&wasmtime_arrayref_t>,
113    index: u32,
114    val: &crate::wasmtime_val_t,
115) -> Option<Box<crate::wasmtime_error_t>> {
116    let result = (|| {
117        let arrayref = arrayref
118            .and_then(|a| a.as_wasmtime())
119            .ok_or_else(|| wasmtime::format_err!("non-null arrayref required"))?;
120        let mut scope = RootScope::new(&mut cx);
121        let rooted = arrayref.to_rooted(&mut scope);
122        let rust_val = val.to_val(&mut scope);
123        rooted.set(&mut scope, index, rust_val)
124    })();
125    crate::handle_result(result, |_| {})
126}
127
128#[unsafe(no_mangle)]
129pub unsafe extern "C" fn wasmtime_arrayref_type(
130    mut cx: WasmtimeStoreContextMut<'_>,
131    arrayref: Option<&wasmtime_arrayref_t>,
132) -> Option<Box<crate::wasmtime_array_type_t>> {
133    let arrayref = arrayref.and_then(|a| a.as_wasmtime())?;
134    let ty = arrayref.ty(&mut cx).expect("should be rooted");
135    Some(Box::new(ty.into()))
136}