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