17a1b7cdfSAlex Crichton use crate::{
290ac295eSAlex Crichton     WasmStoreRef, WasmtimeStoreContextMut, WasmtimeStoreData, wasm_extern_t, wasm_extern_vec_t,
390ac295eSAlex Crichton     wasm_module_t, wasm_store_t, wasm_trap_t, wasmtime_error_t, wasmtime_extern_t,
490ac295eSAlex Crichton     wasmtime_module_t,
57a1b7cdfSAlex Crichton };
67a1b7cdfSAlex Crichton use std::mem::MaybeUninit;
7ec07c89bSTyler Rockwood use wasmtime::{Instance, InstancePre, Trap};
86ef09359SAlex Crichton 
96ef09359SAlex Crichton #[derive(Clone)]
106ef09359SAlex Crichton pub struct wasm_instance_t {
11420fc3d1SNick Fitzgerald     store: WasmStoreRef,
1276b82910SAlex Crichton     instance: Instance,
136ef09359SAlex Crichton }
146ef09359SAlex Crichton 
156ef09359SAlex Crichton wasmtime_c_api_macros::declare_ref!(wasm_instance_t);
166ef09359SAlex Crichton 
176ef09359SAlex Crichton impl wasm_instance_t {
new(store: WasmStoreRef, instance: Instance) -> wasm_instance_t18420fc3d1SNick Fitzgerald     pub(crate) fn new(store: WasmStoreRef, instance: Instance) -> wasm_instance_t {
1976b82910SAlex Crichton         wasm_instance_t { store, instance }
206ef09359SAlex Crichton     }
216ef09359SAlex Crichton }
226ef09359SAlex Crichton 
23ae84e6edSAlex Crichton #[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>>246ef09359SAlex Crichton pub unsafe extern "C" fn wasm_instance_new(
257a1b7cdfSAlex Crichton     store: &mut wasm_store_t,
26bd374fd6SAlex Crichton     wasm_module: &wasm_module_t,
27f94db655SPeter Huene     imports: *const wasm_extern_vec_t,
286ef09359SAlex Crichton     result: Option<&mut *mut wasm_trap_t>,
296ef09359SAlex Crichton ) -> Option<Box<wasm_instance_t>> {
307a1b7cdfSAlex Crichton     let imports = (*imports)
317a1b7cdfSAlex Crichton         .as_slice()
32bd374fd6SAlex Crichton         .iter()
33f94db655SPeter Huene         .filter_map(|import| match import {
34f94db655SPeter Huene             Some(i) => Some(i.which.clone()),
35f94db655SPeter Huene             None => None,
36f94db655SPeter Huene         })
37bd374fd6SAlex Crichton         .collect::<Vec<_>>();
3876b82910SAlex Crichton     match Instance::new(store.store.context_mut(), &wasm_module.module, &imports) {
397a1b7cdfSAlex Crichton         Ok(instance) => Some(Box::new(wasm_instance_t::new(
407a1b7cdfSAlex Crichton             store.store.clone(),
417a1b7cdfSAlex Crichton             instance,
427a1b7cdfSAlex Crichton         ))),
437a1b7cdfSAlex Crichton         Err(e) => {
447a1b7cdfSAlex Crichton             if let Some(ptr) = result {
452afaac51SAlex Crichton                 *ptr = Box::into_raw(Box::new(wasm_trap_t::new(e)));
466ef09359SAlex Crichton             }
476ef09359SAlex Crichton             None
486ef09359SAlex Crichton         }
496ef09359SAlex Crichton     }
506ef09359SAlex Crichton }
516ef09359SAlex Crichton 
52ae84e6edSAlex Crichton #[unsafe(no_mangle)]
wasm_instance_exports( instance: &mut wasm_instance_t, out: &mut wasm_extern_vec_t, )537a1b7cdfSAlex Crichton pub unsafe extern "C" fn wasm_instance_exports(
547a1b7cdfSAlex Crichton     instance: &mut wasm_instance_t,
557a1b7cdfSAlex Crichton     out: &mut wasm_extern_vec_t,
567a1b7cdfSAlex Crichton ) {
5776b82910SAlex Crichton     let store = instance.store.clone();
58cca558cdSAlex Crichton     out.set_buffer(
596ef09359SAlex Crichton         instance
6076b82910SAlex Crichton             .instance
6176b82910SAlex Crichton             .exports(instance.store.context_mut())
62cca558cdSAlex Crichton             .map(|e| {
63cca558cdSAlex Crichton                 Some(Box::new(wasm_extern_t {
64cca558cdSAlex Crichton                     which: e.into_extern(),
657a1b7cdfSAlex Crichton                     store: store.clone(),
66cca558cdSAlex Crichton                 }))
676ef09359SAlex Crichton             })
68cca558cdSAlex Crichton             .collect(),
69cca558cdSAlex Crichton     );
706ef09359SAlex Crichton }
7141caf67aSAlex Crichton 
72ae84e6edSAlex Crichton #[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>>737a1b7cdfSAlex Crichton pub unsafe extern "C" fn wasmtime_instance_new(
74420fc3d1SNick Fitzgerald     store: WasmtimeStoreContextMut<'_>,
757a1b7cdfSAlex Crichton     module: &wasmtime_module_t,
767a1b7cdfSAlex Crichton     imports: *const wasmtime_extern_t,
777a1b7cdfSAlex Crichton     nimports: usize,
787a1b7cdfSAlex Crichton     instance: &mut Instance,
797a1b7cdfSAlex Crichton     trap_ptr: &mut *mut wasm_trap_t,
807a1b7cdfSAlex Crichton ) -> Option<Box<wasmtime_error_t>> {
817a1b7cdfSAlex Crichton     let imports = crate::slice_from_raw_parts(imports, nimports)
827a1b7cdfSAlex Crichton         .iter()
837a1b7cdfSAlex Crichton         .map(|i| i.to_extern())
847a1b7cdfSAlex Crichton         .collect::<Vec<_>>();
857a1b7cdfSAlex Crichton     handle_instantiate(
867a1b7cdfSAlex Crichton         Instance::new(store, &module.module, &imports),
877a1b7cdfSAlex Crichton         instance,
887a1b7cdfSAlex Crichton         trap_ptr,
897a1b7cdfSAlex Crichton     )
907a1b7cdfSAlex Crichton }
917a1b7cdfSAlex Crichton 
handle_instantiate( instance: wasmtime::Result<Instance>, instance_ptr: &mut Instance, trap_ptr: &mut *mut wasm_trap_t, ) -> Option<Box<wasmtime_error_t>>927a1b7cdfSAlex Crichton pub(crate) fn handle_instantiate(
93*dc029724SNick Fitzgerald     instance: wasmtime::Result<Instance>,
947a1b7cdfSAlex Crichton     instance_ptr: &mut Instance,
957a1b7cdfSAlex Crichton     trap_ptr: &mut *mut wasm_trap_t,
967a1b7cdfSAlex Crichton ) -> Option<Box<wasmtime_error_t>> {
977a1b7cdfSAlex Crichton     match instance {
987a1b7cdfSAlex Crichton         Ok(i) => {
997a1b7cdfSAlex Crichton             *instance_ptr = i;
1007a1b7cdfSAlex Crichton             None
1017a1b7cdfSAlex Crichton         }
1027b5fd840SAlex Crichton         Err(e) => {
1037b5fd840SAlex Crichton             if e.is::<Trap>() {
1047b5fd840SAlex Crichton                 *trap_ptr = Box::into_raw(Box::new(wasm_trap_t::new(e)));
1057a1b7cdfSAlex Crichton                 None
1067b5fd840SAlex Crichton             } else {
1077b5fd840SAlex Crichton                 Some(Box::new(e.into()))
1087a1b7cdfSAlex Crichton             }
1097b5fd840SAlex Crichton         }
1107a1b7cdfSAlex Crichton     }
1117a1b7cdfSAlex Crichton }
1127a1b7cdfSAlex Crichton 
113ae84e6edSAlex Crichton #[unsafe(no_mangle)]
wasmtime_instance_export_get( store: WasmtimeStoreContextMut<'_>, instance: &Instance, name: *const u8, name_len: usize, item: &mut MaybeUninit<wasmtime_extern_t>, ) -> bool1147a1b7cdfSAlex Crichton pub unsafe extern "C" fn wasmtime_instance_export_get(
115420fc3d1SNick Fitzgerald     store: WasmtimeStoreContextMut<'_>,
1167a1b7cdfSAlex Crichton     instance: &Instance,
1177a1b7cdfSAlex Crichton     name: *const u8,
1187a1b7cdfSAlex Crichton     name_len: usize,
1197a1b7cdfSAlex Crichton     item: &mut MaybeUninit<wasmtime_extern_t>,
1207a1b7cdfSAlex Crichton ) -> bool {
1217a1b7cdfSAlex Crichton     let name = crate::slice_from_raw_parts(name, name_len);
1227a1b7cdfSAlex Crichton     let name = match std::str::from_utf8(name) {
1237a1b7cdfSAlex Crichton         Ok(name) => name,
1247a1b7cdfSAlex Crichton         Err(_) => return false,
1257a1b7cdfSAlex Crichton     };
1267a1b7cdfSAlex Crichton     match instance.get_export(store, name) {
1277a1b7cdfSAlex Crichton         Some(e) => {
1287a1b7cdfSAlex Crichton             crate::initialize(item, e.into());
1297a1b7cdfSAlex Crichton             true
1307a1b7cdfSAlex Crichton         }
1317a1b7cdfSAlex Crichton         None => false,
1327a1b7cdfSAlex Crichton     }
1337a1b7cdfSAlex Crichton }
1347a1b7cdfSAlex Crichton 
135ae84e6edSAlex Crichton #[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>, ) -> bool1367a1b7cdfSAlex Crichton pub unsafe extern "C" fn wasmtime_instance_export_nth(
137420fc3d1SNick Fitzgerald     store: WasmtimeStoreContextMut<'_>,
1387a1b7cdfSAlex Crichton     instance: &Instance,
1397a1b7cdfSAlex Crichton     index: usize,
1407a1b7cdfSAlex Crichton     name_ptr: &mut *const u8,
1417a1b7cdfSAlex Crichton     name_len: &mut usize,
1427a1b7cdfSAlex Crichton     item: &mut MaybeUninit<wasmtime_extern_t>,
1437a1b7cdfSAlex Crichton ) -> bool {
1447a1b7cdfSAlex Crichton     match instance.exports(store).nth(index) {
1457a1b7cdfSAlex Crichton         Some(e) => {
1467a1b7cdfSAlex Crichton             *name_ptr = e.name().as_ptr();
1477a1b7cdfSAlex Crichton             *name_len = e.name().len();
1487a1b7cdfSAlex Crichton             crate::initialize(item, e.into_extern().into());
1497a1b7cdfSAlex Crichton             true
1507a1b7cdfSAlex Crichton         }
1517a1b7cdfSAlex Crichton         None => false,
1527a1b7cdfSAlex Crichton     }
15341caf67aSAlex Crichton }
154ec07c89bSTyler Rockwood 
155ec07c89bSTyler Rockwood #[repr(transparent)]
156ec07c89bSTyler Rockwood pub struct wasmtime_instance_pre_t {
157420fc3d1SNick Fitzgerald     pub(crate) underlying: InstancePre<WasmtimeStoreData>,
158ec07c89bSTyler Rockwood }
159ec07c89bSTyler Rockwood 
160ae84e6edSAlex Crichton #[unsafe(no_mangle)]
wasmtime_instance_pre_delete(_instance_pre: Box<wasmtime_instance_pre_t>)161ec07c89bSTyler Rockwood pub unsafe extern "C" fn wasmtime_instance_pre_delete(_instance_pre: Box<wasmtime_instance_pre_t>) {
162ec07c89bSTyler Rockwood }
163ec07c89bSTyler Rockwood 
164ae84e6edSAlex Crichton #[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>>165ec07c89bSTyler Rockwood pub unsafe extern "C" fn wasmtime_instance_pre_instantiate(
166ec07c89bSTyler Rockwood     instance_pre: &wasmtime_instance_pre_t,
167420fc3d1SNick Fitzgerald     store: WasmtimeStoreContextMut<'_>,
168ec07c89bSTyler Rockwood     instance_ptr: &mut Instance,
169ec07c89bSTyler Rockwood     trap_ptr: &mut *mut wasm_trap_t,
170ec07c89bSTyler Rockwood ) -> Option<Box<wasmtime_error_t>> {
171ec07c89bSTyler Rockwood     let result = instance_pre.underlying.instantiate(store);
172ec07c89bSTyler Rockwood     handle_instantiate(result, instance_ptr, trap_ptr)
173ec07c89bSTyler Rockwood }
174b4b7bc93STyler Rockwood 
175ae84e6edSAlex Crichton #[unsafe(no_mangle)]
wasmtime_instance_pre_module( instance_pre: &wasmtime_instance_pre_t, ) -> Box<wasmtime_module_t>176b4b7bc93STyler Rockwood pub unsafe extern "C" fn wasmtime_instance_pre_module(
177b4b7bc93STyler Rockwood     instance_pre: &wasmtime_instance_pre_t,
178b4b7bc93STyler Rockwood ) -> Box<wasmtime_module_t> {
179b4b7bc93STyler Rockwood     let module = instance_pre.underlying.module().clone();
180b4b7bc93STyler Rockwood     Box::new(wasmtime_module_t { module })
181b4b7bc93STyler Rockwood }
182