1use crate::{wasm_extern_t, wasm_globaltype_t, wasm_store_t, wasm_val_t};
2use alloc::boxed::Box;
3use core::{hint, mem::MaybeUninit};
4use wasmi::{Extern, Global};
5
6#[derive(Clone)]
10#[repr(transparent)]
11pub struct wasm_global_t {
12 inner: wasm_extern_t,
13}
14
15wasmi_c_api_macros::declare_ref!(wasm_global_t);
16
17impl wasm_global_t {
18 pub(crate) fn try_from(e: &wasm_extern_t) -> Option<&wasm_global_t> {
19 match &e.which {
20 Extern::Global(_) => Some(unsafe { &*(e as *const _ as *const _) }),
21 _ => None,
22 }
23 }
24
25 pub(crate) fn try_from_mut(e: &mut wasm_extern_t) -> Option<&mut wasm_global_t> {
26 match &mut e.which {
27 Extern::Global(_) => Some(unsafe { &mut *(e as *mut _ as *mut _) }),
28 _ => None,
29 }
30 }
31
32 fn global(&self) -> Global {
34 match self.inner.which {
35 Extern::Global(g) => g,
36 _ => unsafe { hint::unreachable_unchecked() },
37 }
38 }
39}
40
41#[cfg_attr(not(feature = "prefix-symbols"), unsafe(no_mangle))]
52#[cfg_attr(feature = "prefix-symbols", wasmi_c_api_macros::prefix_symbol)]
53pub unsafe extern "C" fn wasm_global_new(
54 store: &mut wasm_store_t,
55 ty: &wasm_globaltype_t,
56 val: &wasm_val_t,
57) -> Option<Box<wasm_global_t>> {
58 unsafe {
59 let val = val.to_val();
60 let ty = ty.ty().ty;
61 if val.ty() != ty.content() {
62 return None;
63 }
64 let global = Global::new(store.inner.context_mut(), val, ty.mutability());
65 Some(Box::new(wasm_global_t {
66 inner: wasm_extern_t {
67 store: store.inner.clone(),
68 which: global.into(),
69 },
70 }))
71 }
72}
73
74#[cfg_attr(not(feature = "prefix-symbols"), unsafe(no_mangle))]
76#[cfg_attr(feature = "prefix-symbols", wasmi_c_api_macros::prefix_symbol)]
77pub extern "C" fn wasm_global_as_extern(g: &mut wasm_global_t) -> &mut wasm_extern_t {
78 &mut g.inner
79}
80
81#[cfg_attr(not(feature = "prefix-symbols"), unsafe(no_mangle))]
83#[cfg_attr(feature = "prefix-symbols", wasmi_c_api_macros::prefix_symbol)]
84pub extern "C" fn wasm_global_as_extern_const(g: &wasm_global_t) -> &wasm_extern_t {
85 &g.inner
86}
87
88#[cfg_attr(not(feature = "prefix-symbols"), unsafe(no_mangle))]
97#[cfg_attr(feature = "prefix-symbols", wasmi_c_api_macros::prefix_symbol)]
98pub unsafe extern "C" fn wasm_global_type(g: &wasm_global_t) -> Box<wasm_globaltype_t> {
99 unsafe {
100 let globaltype = g.global().ty(g.inner.store.context());
101 Box::new(wasm_globaltype_t::new(globaltype))
102 }
103}
104
105#[cfg_attr(not(feature = "prefix-symbols"), unsafe(no_mangle))]
114#[cfg_attr(feature = "prefix-symbols", wasmi_c_api_macros::prefix_symbol)]
115pub unsafe extern "C" fn wasm_global_get(g: &mut wasm_global_t, out: &mut MaybeUninit<wasm_val_t>) {
116 unsafe {
117 let global = g.global();
118 crate::initialize(
119 out,
120 wasm_val_t::from(global.get(g.inner.store.context_mut())),
121 );
122 }
123}
124
125#[cfg_attr(not(feature = "prefix-symbols"), unsafe(no_mangle))]
135#[cfg_attr(feature = "prefix-symbols", wasmi_c_api_macros::prefix_symbol)]
136pub unsafe extern "C" fn wasm_global_set(g: &mut wasm_global_t, val: &wasm_val_t) {
137 unsafe {
138 let global = g.global();
139 drop(global.set(g.inner.store.context_mut(), val.to_val()));
140 }
141}