wasmtime/trampoline/
global.rs1use crate::store::{InstanceId, StoreOpaque};
2use crate::trampoline::create_handle;
3use crate::{GlobalType, Mutability, Val};
4use anyhow::Result;
5use wasmtime_environ::{
6 AnyfuncIndex, EntityIndex, Global, GlobalInit, Module, ModuleType, SignatureIndex,
7};
8use wasmtime_runtime::VMFunctionImport;
9
10pub fn create_global(store: &mut StoreOpaque, gt: &GlobalType, val: Val) -> Result<InstanceId> {
11 let mut module = Module::new();
12 let mut func_imports = Vec::new();
13 let mut externref_init = None;
14 let mut one_signature = None;
15
16 let global = Global {
17 wasm_ty: gt.content().to_wasm_type(),
18 mutability: match gt.mutability() {
19 Mutability::Const => false,
20 Mutability::Var => true,
21 },
22 initializer: match val {
23 Val::I32(i) => GlobalInit::I32Const(i),
24 Val::I64(i) => GlobalInit::I64Const(i),
25 Val::F32(f) => GlobalInit::F32Const(f),
26 Val::F64(f) => GlobalInit::F64Const(f),
27 Val::V128(i) => GlobalInit::V128Const(i.into()),
28 Val::ExternRef(None) | Val::FuncRef(None) => GlobalInit::RefNullConst,
29 Val::ExternRef(Some(x)) => {
30 externref_init = Some(x);
35 GlobalInit::RefNullConst
36 }
37 Val::FuncRef(Some(f)) => {
38 let f = f.caller_checked_anyfunc(store);
41 let f = unsafe { f.as_ref() };
42 let sig_id = SignatureIndex::from_u32(0);
43 one_signature = Some(f.type_index);
44 module.types.push(ModuleType::Function(sig_id));
45 let func_index = module.push_escaped_function(sig_id, AnyfuncIndex::from_u32(0));
46 module.num_imported_funcs = 1;
47 module.num_escaped_funcs = 1;
48 module
49 .initializers
50 .push(wasmtime_environ::Initializer::Import {
51 name: "".into(),
52 field: "".into(),
53 index: EntityIndex::Function(func_index),
54 });
55
56 func_imports.push(VMFunctionImport {
57 body: f.func_ptr,
58 vmctx: f.vmctx,
59 });
60
61 GlobalInit::RefFunc(func_index)
62 }
63 },
64 };
65
66 let global_id = module.globals.push(global);
67 module
68 .exports
69 .insert(String::new(), EntityIndex::Global(global_id));
70 let id = create_handle(module, store, Box::new(()), &func_imports, one_signature)?;
71
72 if let Some(x) = externref_init {
73 let instance = store.instance_mut(id);
74 let g = instance.get_exported_global(global_id);
75 unsafe {
76 *(*g.definition).as_externref_mut() = Some(x.inner);
77 }
78 }
79
80 Ok(id)
81}