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