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