Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/crates/c-api/src/instance.rs
1692 views
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 {
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)]
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)]
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)]
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
92
pub(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)]
114
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)]
136
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)]
161
pub unsafe extern "C" fn wasmtime_instance_pre_delete(_instance_pre: Box<wasmtime_instance_pre_t>) {
162
}
163
164
#[unsafe(no_mangle)]
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)]
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
183