wasmtime/runtime/trampoline/
global.rs

1use crate::runtime::vm::{StoreBox, VMGlobalDefinition};
2use crate::store::{AutoAssertNoGc, StoreOpaque};
3use crate::{GlobalType, Mutability, Result, RootedGcRefImpl, Val};
4use core::ptr::{self, NonNull};
5
6#[repr(C)]
7pub struct VMHostGlobalContext {
8    pub(crate) ty: GlobalType,
9    pub(crate) global: VMGlobalDefinition,
10}
11
12pub fn generate_global_export(
13    store: &mut StoreOpaque,
14    ty: GlobalType,
15    val: Val,
16) -> Result<crate::runtime::vm::ExportGlobal> {
17    let global = wasmtime_environ::Global {
18        wasm_ty: ty.content().to_wasm_type(),
19        mutability: match ty.mutability() {
20            Mutability::Const => false,
21            Mutability::Var => true,
22        },
23    };
24    let ctx = StoreBox::new(VMHostGlobalContext {
25        ty,
26        global: VMGlobalDefinition::new(),
27    });
28
29    let mut store = AutoAssertNoGc::new(store);
30    let definition = unsafe {
31        let global = &mut ctx.get().as_mut().global;
32        match val {
33            Val::I32(x) => *global.as_i32_mut() = x,
34            Val::I64(x) => *global.as_i64_mut() = x,
35            Val::F32(x) => *global.as_f32_bits_mut() = x,
36            Val::F64(x) => *global.as_f64_bits_mut() = x,
37            Val::V128(x) => global.set_u128(x.into()),
38            Val::FuncRef(f) => {
39                *global.as_func_ref_mut() =
40                    f.map_or(ptr::null_mut(), |f| f.vm_func_ref(&mut store).as_ptr());
41            }
42            Val::ExternRef(x) => {
43                let new = match x {
44                    None => None,
45                    #[cfg_attr(not(feature = "gc"), allow(unreachable_patterns))]
46                    Some(x) => Some(x.try_gc_ref(&store)?.unchecked_copy()),
47                };
48                let new = new.as_ref();
49                global.write_gc_ref(store.gc_store_mut()?, new);
50            }
51            Val::AnyRef(a) => {
52                let new = match a {
53                    None => None,
54                    #[cfg_attr(not(feature = "gc"), allow(unreachable_patterns))]
55                    Some(a) => Some(a.try_gc_ref(&store)?.unchecked_copy()),
56                };
57                let new = new.as_ref();
58                global.write_gc_ref(store.gc_store_mut()?, new);
59            }
60        }
61        global
62    };
63
64    store.host_globals().push(ctx);
65    Ok(crate::runtime::vm::ExportGlobal {
66        definition: NonNull::from(definition),
67        vmctx: None,
68        global,
69    })
70}