1 use crate::{CExternType, wasm_externtype_t, wasm_valtype_t};
2 use std::cell::OnceCell;
3 use wasmtime::GlobalType;
4 
5 pub type wasm_mutability_t = u8;
6 
7 pub const WASM_CONST: wasm_mutability_t = 0;
8 pub const WASM_VAR: wasm_mutability_t = 1;
9 
10 #[repr(transparent)]
11 #[derive(Clone)]
12 pub struct wasm_globaltype_t {
13     ext: wasm_externtype_t,
14 }
15 
16 wasmtime_c_api_macros::declare_ty!(wasm_globaltype_t);
17 
18 #[derive(Clone)]
19 pub(crate) struct CGlobalType {
20     pub(crate) ty: GlobalType,
21     content_cache: OnceCell<wasm_valtype_t>,
22 }
23 
24 impl wasm_globaltype_t {
new(ty: GlobalType) -> wasm_globaltype_t25     pub(crate) fn new(ty: GlobalType) -> wasm_globaltype_t {
26         wasm_globaltype_t {
27             ext: wasm_externtype_t::from_extern_type(ty.into()),
28         }
29     }
30 
try_from(e: &wasm_externtype_t) -> Option<&wasm_globaltype_t>31     pub(crate) fn try_from(e: &wasm_externtype_t) -> Option<&wasm_globaltype_t> {
32         match &e.which {
33             CExternType::Global(_) => Some(unsafe { &*(e as *const _ as *const _) }),
34             _ => None,
35         }
36     }
37 
ty(&self) -> &CGlobalType38     pub(crate) fn ty(&self) -> &CGlobalType {
39         match &self.ext.which {
40             CExternType::Global(f) => &f,
41             _ => unsafe { std::hint::unreachable_unchecked() },
42         }
43     }
44 }
45 
46 impl CGlobalType {
new(ty: GlobalType) -> CGlobalType47     pub(crate) fn new(ty: GlobalType) -> CGlobalType {
48         CGlobalType {
49             ty,
50             content_cache: OnceCell::new(),
51         }
52     }
53 }
54 
55 #[unsafe(no_mangle)]
wasm_globaltype_new( ty: Box<wasm_valtype_t>, mutability: wasm_mutability_t, ) -> Option<Box<wasm_globaltype_t>>56 pub extern "C" fn wasm_globaltype_new(
57     ty: Box<wasm_valtype_t>,
58     mutability: wasm_mutability_t,
59 ) -> Option<Box<wasm_globaltype_t>> {
60     use wasmtime::Mutability::*;
61     let mutability = match mutability {
62         WASM_CONST => Const,
63         WASM_VAR => Var,
64         _ => return None,
65     };
66     let ty = GlobalType::new(ty.ty.clone(), mutability);
67     Some(Box::new(wasm_globaltype_t::new(ty)))
68 }
69 
70 #[unsafe(no_mangle)]
wasm_globaltype_content(gt: &wasm_globaltype_t) -> &wasm_valtype_t71 pub extern "C" fn wasm_globaltype_content(gt: &wasm_globaltype_t) -> &wasm_valtype_t {
72     let gt = gt.ty();
73     gt.content_cache.get_or_init(|| wasm_valtype_t {
74         ty: gt.ty.content().clone(),
75     })
76 }
77 
78 #[unsafe(no_mangle)]
wasm_globaltype_mutability(gt: &wasm_globaltype_t) -> wasm_mutability_t79 pub extern "C" fn wasm_globaltype_mutability(gt: &wasm_globaltype_t) -> wasm_mutability_t {
80     use wasmtime::Mutability::*;
81     let gt = gt.ty();
82     match gt.ty.mutability() {
83         Const => WASM_CONST,
84         Var => WASM_VAR,
85     }
86 }
87 
88 #[unsafe(no_mangle)]
wasm_globaltype_as_externtype(ty: &wasm_globaltype_t) -> &wasm_externtype_t89 pub extern "C" fn wasm_globaltype_as_externtype(ty: &wasm_globaltype_t) -> &wasm_externtype_t {
90     &ty.ext
91 }
92 
93 #[unsafe(no_mangle)]
wasm_globaltype_as_externtype_const( ty: &wasm_globaltype_t, ) -> &wasm_externtype_t94 pub extern "C" fn wasm_globaltype_as_externtype_const(
95     ty: &wasm_globaltype_t,
96 ) -> &wasm_externtype_t {
97     &ty.ext
98 }
99