Skip to main content

wasmtime_c_api/
eqref.rs

1use crate::{
2    WasmtimeStoreContextMut, wasmtime_anyref_t, wasmtime_arrayref_t, wasmtime_heaptype_t,
3    wasmtime_structref_t,
4};
5use std::mem::MaybeUninit;
6use wasmtime::{ArrayRef, EqRef, I31, OwnedRooted, RootScope, StructRef};
7
8crate::anyref::ref_wrapper!({
9    wasmtime: EqRef,
10    capi: wasmtime_eqref_t,
11    clone: wasmtime_eqref_clone,
12    unroot: wasmtime_eqref_unroot,
13});
14
15#[unsafe(no_mangle)]
16pub unsafe extern "C" fn wasmtime_eqref_to_anyref(
17    eqref: Option<&wasmtime_eqref_t>,
18    out: &mut MaybeUninit<wasmtime_anyref_t>,
19) {
20    let anyref = eqref.and_then(|e| e.as_wasmtime()).map(|e| e.to_anyref());
21    crate::initialize(out, anyref.into());
22}
23
24#[unsafe(no_mangle)]
25pub extern "C" fn wasmtime_eqref_from_i31(
26    cx: WasmtimeStoreContextMut<'_>,
27    val: u32,
28    out: &mut MaybeUninit<wasmtime_eqref_t>,
29) {
30    let mut scope = RootScope::new(cx);
31    let eqref = EqRef::from_i31(&mut scope, I31::wrapping_u32(val));
32    let eqref = eqref.to_owned_rooted(&mut scope).expect("in scope");
33    crate::initialize(out, Some(eqref).into())
34}
35
36#[unsafe(no_mangle)]
37pub unsafe extern "C" fn wasmtime_eqref_is_i31(
38    cx: WasmtimeStoreContextMut<'_>,
39    eqref: Option<&wasmtime_eqref_t>,
40) -> bool {
41    match eqref.and_then(|e| e.as_wasmtime()) {
42        Some(eqref) => eqref.is_i31(&cx).expect("OwnedRooted always in scope"),
43        None => false,
44    }
45}
46
47#[unsafe(no_mangle)]
48pub unsafe extern "C" fn wasmtime_eqref_i31_get_u(
49    cx: WasmtimeStoreContextMut<'_>,
50    eqref: Option<&wasmtime_eqref_t>,
51    dst: &mut MaybeUninit<u32>,
52) -> bool {
53    let mut scope = RootScope::new(cx);
54    if let Some(eqref) = eqref.and_then(|e| e.as_wasmtime()) {
55        if let Some(val) = eqref.as_i31(&mut scope).expect("in scope") {
56            crate::initialize(dst, val.get_u32());
57            return true;
58        }
59    }
60    false
61}
62
63#[unsafe(no_mangle)]
64pub unsafe extern "C" fn wasmtime_eqref_i31_get_s(
65    cx: WasmtimeStoreContextMut<'_>,
66    eqref: Option<&wasmtime_eqref_t>,
67    dst: &mut MaybeUninit<i32>,
68) -> bool {
69    let mut scope = RootScope::new(cx);
70    if let Some(eqref) = eqref.and_then(|e| e.as_wasmtime()) {
71        if let Some(val) = eqref.as_i31(&mut scope).expect("in scope") {
72            crate::initialize(dst, val.get_i32());
73            return true;
74        }
75    }
76    false
77}
78
79#[unsafe(no_mangle)]
80pub unsafe extern "C" fn wasmtime_eqref_is_struct(
81    cx: WasmtimeStoreContextMut<'_>,
82    eqref: Option<&wasmtime_eqref_t>,
83) -> bool {
84    match eqref.and_then(|e| e.as_wasmtime()) {
85        Some(eqref) => eqref.is_struct(&cx).expect("OwnedRooted always in scope"),
86        None => false,
87    }
88}
89
90#[unsafe(no_mangle)]
91pub unsafe extern "C" fn wasmtime_eqref_as_struct(
92    mut cx: WasmtimeStoreContextMut<'_>,
93    eqref: Option<&wasmtime_eqref_t>,
94    out: &mut MaybeUninit<wasmtime_structref_t>,
95) -> bool {
96    if let Some(eqref) = eqref.and_then(|e| e.as_wasmtime()) {
97        let mut scope = RootScope::new(&mut cx);
98        let rooted = eqref.to_rooted(&mut scope);
99        if let Ok(Some(structref)) = rooted.as_struct(&scope) {
100            let owned = structref.to_owned_rooted(&mut scope).expect("in scope");
101            crate::initialize(out, Some(owned).into());
102            return true;
103        }
104    }
105    crate::initialize(out, None::<OwnedRooted<StructRef>>.into());
106    false
107}
108
109#[unsafe(no_mangle)]
110pub unsafe extern "C" fn wasmtime_eqref_is_array(
111    cx: WasmtimeStoreContextMut<'_>,
112    eqref: Option<&wasmtime_eqref_t>,
113) -> bool {
114    match eqref.and_then(|e| e.as_wasmtime()) {
115        Some(eqref) => eqref.is_array(&cx).expect("OwnedRooted always in scope"),
116        None => false,
117    }
118}
119
120#[unsafe(no_mangle)]
121pub unsafe extern "C" fn wasmtime_eqref_as_array(
122    mut cx: WasmtimeStoreContextMut<'_>,
123    eqref: Option<&wasmtime_eqref_t>,
124    out: &mut MaybeUninit<wasmtime_arrayref_t>,
125) -> bool {
126    if let Some(eqref) = eqref.and_then(|e| e.as_wasmtime()) {
127        let mut scope = RootScope::new(&mut cx);
128        let rooted = eqref.to_rooted(&mut scope);
129        if let Ok(Some(arrayref)) = rooted.as_array(&scope) {
130            let owned = arrayref.to_owned_rooted(&mut scope).expect("just created");
131            crate::initialize(out, Some(owned).into());
132            return true;
133        }
134    }
135    crate::initialize(out, None::<OwnedRooted<ArrayRef>>.into());
136    false
137}
138
139#[unsafe(no_mangle)]
140pub unsafe extern "C" fn wasmtime_eqref_type(
141    mut cx: WasmtimeStoreContextMut<'_>,
142    eqref: Option<&wasmtime_eqref_t>,
143    out: &mut MaybeUninit<wasmtime_heaptype_t>,
144) -> bool {
145    match eqref.and_then(|a| a.as_wasmtime()) {
146        Some(eqref) => {
147            let ty = eqref.ty(&mut cx).expect("should be rooted");
148            out.write(ty.into());
149            true
150        }
151        None => false,
152    }
153}