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 wasmtime::{Instance, InstancePre, Trap};
8
9#[derive(Clone)]
10pub struct wasm_instance_t {
11 store: WasmStoreRef,
12 instance: Instance,
13}
14
15wasmtime_c_api_macros::declare_ref!(wasm_instance_t);
16
17impl wasm_instance_t {
18 pub(crate) fn new(store: WasmStoreRef, instance: Instance) -> wasm_instance_t {
19 wasm_instance_t { store, instance }
20 }
21}
22
23#[unsafe(no_mangle)]
24pub 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)]
53pub 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)]
73pub 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
92pub(crate) fn handle_instantiate(
93 instance: anyhow::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)]
114pub 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)]
136pub 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)]
156pub struct wasmtime_instance_pre_t {
157 pub(crate) underlying: InstancePre<WasmtimeStoreData>,
158}
159
160#[unsafe(no_mangle)]
161pub unsafe extern "C" fn wasmtime_instance_pre_delete(_instance_pre: Box<wasmtime_instance_pre_t>) {
162}
163
164#[unsafe(no_mangle)]
165pub 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)]
176pub 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}