xref: /wasmtime-44.0.1/crates/c-api/src/global.rs (revision d07fdca7)
1 use crate::{handle_result, wasmtime_error_t};
2 use crate::{wasm_extern_t, wasm_globaltype_t, wasm_store_t, wasm_val_t};
3 use std::mem::MaybeUninit;
4 use std::ptr;
5 use wasmtime::{Extern, Global};
6 
7 #[derive(Clone)]
8 #[repr(transparent)]
9 pub struct wasm_global_t {
10     ext: wasm_extern_t,
11 }
12 
13 wasmtime_c_api_macros::declare_ref!(wasm_global_t);
14 
15 impl wasm_global_t {
16     pub(crate) fn try_from(e: &wasm_extern_t) -> Option<&wasm_global_t> {
17         match &e.which {
18             Extern::Global(_) => Some(unsafe { &*(e as *const _ as *const _) }),
19             _ => None,
20         }
21     }
22 
23     fn global(&self) -> &Global {
24         match &self.ext.which {
25             Extern::Global(g) => g,
26             _ => unsafe { std::hint::unreachable_unchecked() },
27         }
28     }
29 }
30 
31 #[no_mangle]
32 pub extern "C" fn wasm_global_new(
33     store: &wasm_store_t,
34     gt: &wasm_globaltype_t,
35     val: &wasm_val_t,
36 ) -> Option<Box<wasm_global_t>> {
37     let mut global = ptr::null_mut();
38     match wasmtime_global_new(store, gt, val, &mut global) {
39         Some(_err) => None,
40         None => {
41             assert!(!global.is_null());
42             Some(unsafe { Box::from_raw(global) })
43         }
44     }
45 }
46 
47 #[no_mangle]
48 pub extern "C" fn wasmtime_global_new(
49     store: &wasm_store_t,
50     gt: &wasm_globaltype_t,
51     val: &wasm_val_t,
52     ret: &mut *mut wasm_global_t,
53 ) -> Option<Box<wasmtime_error_t>> {
54     let global = Global::new(&store.store, gt.ty().ty.clone(), val.val());
55     handle_result(global, |global| {
56         *ret = Box::into_raw(Box::new(wasm_global_t {
57             ext: wasm_extern_t {
58                 which: global.into(),
59             },
60         }));
61     })
62 }
63 
64 #[no_mangle]
65 pub extern "C" fn wasm_global_as_extern(g: &wasm_global_t) -> &wasm_extern_t {
66     &g.ext
67 }
68 
69 #[no_mangle]
70 pub extern "C" fn wasm_global_type(g: &wasm_global_t) -> Box<wasm_globaltype_t> {
71     let globaltype = g.global().ty();
72     Box::new(wasm_globaltype_t::new(globaltype))
73 }
74 
75 #[no_mangle]
76 pub extern "C" fn wasm_global_get(g: &wasm_global_t, out: &mut MaybeUninit<wasm_val_t>) {
77     crate::initialize(out, wasm_val_t::from_val(g.global().get()));
78 }
79 
80 #[no_mangle]
81 pub extern "C" fn wasm_global_set(g: &wasm_global_t, val: &wasm_val_t) {
82     let result = g.global().set(val.val());
83     // FIXME(WebAssembly/wasm-c-api#131) should communicate the error here
84     drop(result);
85 }
86 
87 #[no_mangle]
88 pub extern "C" fn wasmtime_global_set(
89     g: &wasm_global_t,
90     val: &wasm_val_t,
91 ) -> Option<Box<wasmtime_error_t>> {
92     handle_result(g.global().set(val.val()), |()| {})
93 }
94