1 use crate::{
2 WasmStoreRef, WasmtimeStoreContextMut, WasmtimeStoreData, wasm_extern_t, wasm_extern_vec_t,
3 wasm_module_t, wasm_store_t, wasm_trap_t, wasmtime_error_t, wasmtime_extern_t,
4 wasmtime_module_t,
5 };
6 use std::mem::MaybeUninit;
7 use wasmtime::{Instance, InstancePre, Trap};
8
9 #[derive(Clone)]
10 pub struct wasm_instance_t {
11 store: WasmStoreRef,
12 instance: Instance,
13 }
14
15 wasmtime_c_api_macros::declare_ref!(wasm_instance_t);
16
17 impl wasm_instance_t {
new(store: WasmStoreRef, instance: Instance) -> wasm_instance_t18 pub(crate) fn new(store: WasmStoreRef, instance: Instance) -> wasm_instance_t {
19 wasm_instance_t { store, instance }
20 }
21 }
22
23 #[unsafe(no_mangle)]
wasm_instance_new( store: &mut wasm_store_t, wasm_module: &wasm_module_t, imports: *const wasm_extern_vec_t, result: Option<&mut *mut wasm_trap_t>, ) -> Option<Box<wasm_instance_t>>24 pub unsafe extern "C" fn wasm_instance_new(
25 store: &mut wasm_store_t,
26 wasm_module: &wasm_module_t,
27 imports: *const wasm_extern_vec_t,
28 result: Option<&mut *mut wasm_trap_t>,
29 ) -> Option<Box<wasm_instance_t>> {
30 let imports = (*imports)
31 .as_slice()
32 .iter()
33 .filter_map(|import| match import {
34 Some(i) => Some(i.which.clone()),
35 None => None,
36 })
37 .collect::<Vec<_>>();
38 match Instance::new(store.store.context_mut(), &wasm_module.module, &imports) {
39 Ok(instance) => Some(Box::new(wasm_instance_t::new(
40 store.store.clone(),
41 instance,
42 ))),
43 Err(e) => {
44 if let Some(ptr) = result {
45 *ptr = Box::into_raw(Box::new(wasm_trap_t::new(e)));
46 }
47 None
48 }
49 }
50 }
51
52 #[unsafe(no_mangle)]
wasm_instance_exports( instance: &mut wasm_instance_t, out: &mut wasm_extern_vec_t, )53 pub unsafe extern "C" fn wasm_instance_exports(
54 instance: &mut wasm_instance_t,
55 out: &mut wasm_extern_vec_t,
56 ) {
57 let store = instance.store.clone();
58 out.set_buffer(
59 instance
60 .instance
61 .exports(instance.store.context_mut())
62 .map(|e| {
63 Some(Box::new(wasm_extern_t {
64 which: e.into_extern(),
65 store: store.clone(),
66 }))
67 })
68 .collect(),
69 );
70 }
71
72 #[unsafe(no_mangle)]
wasmtime_instance_new( store: WasmtimeStoreContextMut<'_>, module: &wasmtime_module_t, imports: *const wasmtime_extern_t, nimports: usize, instance: &mut Instance, trap_ptr: &mut *mut wasm_trap_t, ) -> Option<Box<wasmtime_error_t>>73 pub unsafe extern "C" fn wasmtime_instance_new(
74 store: WasmtimeStoreContextMut<'_>,
75 module: &wasmtime_module_t,
76 imports: *const wasmtime_extern_t,
77 nimports: usize,
78 instance: &mut Instance,
79 trap_ptr: &mut *mut wasm_trap_t,
80 ) -> Option<Box<wasmtime_error_t>> {
81 let imports = crate::slice_from_raw_parts(imports, nimports)
82 .iter()
83 .map(|i| i.to_extern())
84 .collect::<Vec<_>>();
85 handle_instantiate(
86 Instance::new(store, &module.module, &imports),
87 instance,
88 trap_ptr,
89 )
90 }
91
handle_instantiate( instance: wasmtime::Result<Instance>, instance_ptr: &mut Instance, trap_ptr: &mut *mut wasm_trap_t, ) -> Option<Box<wasmtime_error_t>>92 pub(crate) fn handle_instantiate(
93 instance: wasmtime::Result<Instance>,
94 instance_ptr: &mut Instance,
95 trap_ptr: &mut *mut wasm_trap_t,
96 ) -> Option<Box<wasmtime_error_t>> {
97 match instance {
98 Ok(i) => {
99 *instance_ptr = i;
100 None
101 }
102 Err(e) => {
103 if e.is::<Trap>() {
104 *trap_ptr = Box::into_raw(Box::new(wasm_trap_t::new(e)));
105 None
106 } else {
107 Some(Box::new(e.into()))
108 }
109 }
110 }
111 }
112
113 #[unsafe(no_mangle)]
wasmtime_instance_export_get( store: WasmtimeStoreContextMut<'_>, instance: &Instance, name: *const u8, name_len: usize, item: &mut MaybeUninit<wasmtime_extern_t>, ) -> bool114 pub unsafe extern "C" fn wasmtime_instance_export_get(
115 store: WasmtimeStoreContextMut<'_>,
116 instance: &Instance,
117 name: *const u8,
118 name_len: usize,
119 item: &mut MaybeUninit<wasmtime_extern_t>,
120 ) -> bool {
121 let name = crate::slice_from_raw_parts(name, name_len);
122 let name = match std::str::from_utf8(name) {
123 Ok(name) => name,
124 Err(_) => return false,
125 };
126 match instance.get_export(store, name) {
127 Some(e) => {
128 crate::initialize(item, e.into());
129 true
130 }
131 None => false,
132 }
133 }
134
135 #[unsafe(no_mangle)]
wasmtime_instance_export_nth( store: WasmtimeStoreContextMut<'_>, instance: &Instance, index: usize, name_ptr: &mut *const u8, name_len: &mut usize, item: &mut MaybeUninit<wasmtime_extern_t>, ) -> bool136 pub unsafe extern "C" fn wasmtime_instance_export_nth(
137 store: WasmtimeStoreContextMut<'_>,
138 instance: &Instance,
139 index: usize,
140 name_ptr: &mut *const u8,
141 name_len: &mut usize,
142 item: &mut MaybeUninit<wasmtime_extern_t>,
143 ) -> bool {
144 match instance.exports(store).nth(index) {
145 Some(e) => {
146 *name_ptr = e.name().as_ptr();
147 *name_len = e.name().len();
148 crate::initialize(item, e.into_extern().into());
149 true
150 }
151 None => false,
152 }
153 }
154
155 #[repr(transparent)]
156 pub struct wasmtime_instance_pre_t {
157 pub(crate) underlying: InstancePre<WasmtimeStoreData>,
158 }
159
160 #[unsafe(no_mangle)]
wasmtime_instance_pre_delete(_instance_pre: Box<wasmtime_instance_pre_t>)161 pub unsafe extern "C" fn wasmtime_instance_pre_delete(_instance_pre: Box<wasmtime_instance_pre_t>) {
162 }
163
164 #[unsafe(no_mangle)]
wasmtime_instance_pre_instantiate( instance_pre: &wasmtime_instance_pre_t, store: WasmtimeStoreContextMut<'_>, instance_ptr: &mut Instance, trap_ptr: &mut *mut wasm_trap_t, ) -> Option<Box<wasmtime_error_t>>165 pub unsafe extern "C" fn wasmtime_instance_pre_instantiate(
166 instance_pre: &wasmtime_instance_pre_t,
167 store: WasmtimeStoreContextMut<'_>,
168 instance_ptr: &mut Instance,
169 trap_ptr: &mut *mut wasm_trap_t,
170 ) -> Option<Box<wasmtime_error_t>> {
171 let result = instance_pre.underlying.instantiate(store);
172 handle_instantiate(result, instance_ptr, trap_ptr)
173 }
174
175 #[unsafe(no_mangle)]
wasmtime_instance_pre_module( instance_pre: &wasmtime_instance_pre_t, ) -> Box<wasmtime_module_t>176 pub unsafe extern "C" fn wasmtime_instance_pre_module(
177 instance_pre: &wasmtime_instance_pre_t,
178 ) -> Box<wasmtime_module_t> {
179 let module = instance_pre.underlying.module().clone();
180 Box::new(wasmtime_module_t { module })
181 }
182