1 use crate::host_ref::HostRef;
2 use crate::{handle_result, wasmtime_error_t};
3 use crate::{wasm_extern_t, wasm_globaltype_t, wasm_store_t, wasm_val_t, ExternHost};
4 use std::ptr;
5 use wasmtime::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 {
try_from(e: &wasm_extern_t) -> Option<&wasm_global_t>16 pub(crate) fn try_from(e: &wasm_extern_t) -> Option<&wasm_global_t> {
17 match &e.which {
18 ExternHost::Global(_) => Some(unsafe { &*(e as *const _ as *const _) }),
19 _ => None,
20 }
21 }
22
global(&self) -> &HostRef<Global>23 fn global(&self) -> &HostRef<Global> {
24 match &self.ext.which {
25 ExternHost::Global(g) => g,
26 _ => unsafe { std::hint::unreachable_unchecked() },
27 }
28 }
29
externref(&self) -> wasmtime::ExternRef30 fn externref(&self) -> wasmtime::ExternRef {
31 self.global().clone().into()
32 }
33 }
34
35 #[no_mangle]
wasm_global_new( store: &wasm_store_t, gt: &wasm_globaltype_t, val: &wasm_val_t, ) -> Option<Box<wasm_global_t>>36 pub extern "C" fn wasm_global_new(
37 store: &wasm_store_t,
38 gt: &wasm_globaltype_t,
39 val: &wasm_val_t,
40 ) -> Option<Box<wasm_global_t>> {
41 let mut global = ptr::null_mut();
42 match wasmtime_global_new(store, gt, val, &mut global) {
43 Some(_err) => None,
44 None => {
45 assert!(!global.is_null());
46 Some(unsafe { Box::from_raw(global) })
47 }
48 }
49 }
50
51 #[no_mangle]
wasmtime_global_new( store: &wasm_store_t, gt: &wasm_globaltype_t, val: &wasm_val_t, ret: &mut *mut wasm_global_t, ) -> Option<Box<wasmtime_error_t>>52 pub extern "C" fn wasmtime_global_new(
53 store: &wasm_store_t,
54 gt: &wasm_globaltype_t,
55 val: &wasm_val_t,
56 ret: &mut *mut wasm_global_t,
57 ) -> Option<Box<wasmtime_error_t>> {
58 let global = Global::new(&store.store, gt.ty().ty.clone(), val.val());
59 handle_result(global, |global| {
60 *ret = Box::into_raw(Box::new(wasm_global_t {
61 ext: wasm_extern_t {
62 which: ExternHost::Global(HostRef::new(&store.store, global)),
63 },
64 }));
65 })
66 }
67
68 #[no_mangle]
wasm_global_as_extern(g: &wasm_global_t) -> &wasm_extern_t69 pub extern "C" fn wasm_global_as_extern(g: &wasm_global_t) -> &wasm_extern_t {
70 &g.ext
71 }
72
73 #[no_mangle]
wasm_global_type(g: &wasm_global_t) -> Box<wasm_globaltype_t>74 pub extern "C" fn wasm_global_type(g: &wasm_global_t) -> Box<wasm_globaltype_t> {
75 let globaltype = g.global().borrow().ty();
76 Box::new(wasm_globaltype_t::new(globaltype))
77 }
78
79 #[no_mangle]
wasm_global_get(g: &wasm_global_t, out: &mut wasm_val_t)80 pub extern "C" fn wasm_global_get(g: &wasm_global_t, out: &mut wasm_val_t) {
81 out.set(g.global().borrow().get());
82 }
83
84 #[no_mangle]
wasm_global_set(g: &wasm_global_t, val: &wasm_val_t)85 pub extern "C" fn wasm_global_set(g: &wasm_global_t, val: &wasm_val_t) {
86 let result = g.global().borrow().set(val.val());
87 // FIXME(WebAssembly/wasm-c-api#131) should communicate the error here
88 drop(result);
89 }
90
91 #[no_mangle]
wasmtime_global_set( g: &wasm_global_t, val: &wasm_val_t, ) -> Option<Box<wasmtime_error_t>>92 pub extern "C" fn wasmtime_global_set(
93 g: &wasm_global_t,
94 val: &wasm_val_t,
95 ) -> Option<Box<wasmtime_error_t>> {
96 handle_result(g.global().borrow().set(val.val()), |()| {})
97 }
98