Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/crates/c-api/src/linker.rs
1692 views
1
use crate::{
2
WasmtimeStoreContext, WasmtimeStoreContextMut, bad_utf8, handle_result, wasm_engine_t,
3
wasm_functype_t, wasm_trap_t, wasmtime_error_t, wasmtime_extern_t, wasmtime_instance_pre_t,
4
wasmtime_module_t,
5
};
6
use std::ffi::c_void;
7
use std::mem::MaybeUninit;
8
use std::str;
9
use wasmtime::{Func, Instance, Linker};
10
11
#[repr(C)]
12
pub struct wasmtime_linker_t {
13
pub(crate) linker: Linker<crate::WasmtimeStoreData>,
14
}
15
16
wasmtime_c_api_macros::declare_own!(wasmtime_linker_t);
17
18
#[unsafe(no_mangle)]
19
pub extern "C" fn wasmtime_linker_new(engine: &wasm_engine_t) -> Box<wasmtime_linker_t> {
20
Box::new(wasmtime_linker_t {
21
linker: Linker::new(&engine.engine),
22
})
23
}
24
25
#[unsafe(no_mangle)]
26
pub extern "C" fn wasmtime_linker_clone(linker: &wasmtime_linker_t) -> Box<wasmtime_linker_t> {
27
Box::new(wasmtime_linker_t {
28
linker: linker.linker.clone(),
29
})
30
}
31
32
#[unsafe(no_mangle)]
33
pub extern "C" fn wasmtime_linker_allow_shadowing(
34
linker: &mut wasmtime_linker_t,
35
allow_shadowing: bool,
36
) {
37
linker.linker.allow_shadowing(allow_shadowing);
38
}
39
40
macro_rules! to_str {
41
($ptr:expr, $len:expr) => {
42
match str::from_utf8(crate::slice_from_raw_parts($ptr, $len)) {
43
Ok(s) => s,
44
Err(_) => return bad_utf8(),
45
}
46
};
47
}
48
49
pub(crate) use to_str;
50
51
#[unsafe(no_mangle)]
52
pub unsafe extern "C" fn wasmtime_linker_define(
53
linker: &mut wasmtime_linker_t,
54
store: WasmtimeStoreContext<'_>,
55
module: *const u8,
56
module_len: usize,
57
name: *const u8,
58
name_len: usize,
59
item: &wasmtime_extern_t,
60
) -> Option<Box<wasmtime_error_t>> {
61
let linker = &mut linker.linker;
62
let module = to_str!(module, module_len);
63
let name = to_str!(name, name_len);
64
let item = item.to_extern();
65
handle_result(linker.define(&store, module, name, item), |_linker| ())
66
}
67
68
#[unsafe(no_mangle)]
69
pub unsafe extern "C" fn wasmtime_linker_define_func(
70
linker: &mut wasmtime_linker_t,
71
module: *const u8,
72
module_len: usize,
73
name: *const u8,
74
name_len: usize,
75
ty: &wasm_functype_t,
76
callback: crate::wasmtime_func_callback_t,
77
data: *mut c_void,
78
finalizer: Option<extern "C" fn(*mut std::ffi::c_void)>,
79
) -> Option<Box<wasmtime_error_t>> {
80
let ty = ty.ty().ty(linker.linker.engine());
81
let module = to_str!(module, module_len);
82
let name = to_str!(name, name_len);
83
let cb = crate::func::c_callback_to_rust_fn(callback, data, finalizer);
84
handle_result(linker.linker.func_new(module, name, ty, cb), |_linker| ())
85
}
86
87
#[unsafe(no_mangle)]
88
pub unsafe extern "C" fn wasmtime_linker_define_func_unchecked(
89
linker: &mut wasmtime_linker_t,
90
module: *const u8,
91
module_len: usize,
92
name: *const u8,
93
name_len: usize,
94
ty: &wasm_functype_t,
95
callback: crate::wasmtime_func_unchecked_callback_t,
96
data: *mut c_void,
97
finalizer: Option<extern "C" fn(*mut std::ffi::c_void)>,
98
) -> Option<Box<wasmtime_error_t>> {
99
let ty = ty.ty().ty(linker.linker.engine());
100
let module = to_str!(module, module_len);
101
let name = to_str!(name, name_len);
102
let cb = crate::func::c_unchecked_callback_to_rust_fn(callback, data, finalizer);
103
handle_result(
104
linker.linker.func_new_unchecked(module, name, ty, cb),
105
|_linker| (),
106
)
107
}
108
109
#[cfg(feature = "wasi")]
110
#[unsafe(no_mangle)]
111
pub extern "C" fn wasmtime_linker_define_wasi(
112
linker: &mut wasmtime_linker_t,
113
) -> Option<Box<wasmtime_error_t>> {
114
handle_result(
115
wasmtime_wasi::p1::add_to_linker_sync(&mut linker.linker, |ctx| {
116
ctx.wasi.as_mut().expect("wasi context must be populated")
117
}),
118
|_linker| (),
119
)
120
}
121
122
#[unsafe(no_mangle)]
123
pub unsafe extern "C" fn wasmtime_linker_define_instance(
124
linker: &mut wasmtime_linker_t,
125
store: WasmtimeStoreContextMut<'_>,
126
name: *const u8,
127
name_len: usize,
128
instance: &Instance,
129
) -> Option<Box<wasmtime_error_t>> {
130
let linker = &mut linker.linker;
131
let name = to_str!(name, name_len);
132
handle_result(linker.instance(store, name, *instance), |_linker| ())
133
}
134
135
#[unsafe(no_mangle)]
136
pub extern "C" fn wasmtime_linker_instantiate(
137
linker: &wasmtime_linker_t,
138
store: WasmtimeStoreContextMut<'_>,
139
module: &wasmtime_module_t,
140
instance_ptr: &mut Instance,
141
trap_ptr: &mut *mut wasm_trap_t,
142
) -> Option<Box<wasmtime_error_t>> {
143
let result = linker.linker.instantiate(store, &module.module);
144
super::instance::handle_instantiate(result, instance_ptr, trap_ptr)
145
}
146
147
#[unsafe(no_mangle)]
148
pub unsafe extern "C" fn wasmtime_linker_instantiate_pre(
149
linker: &wasmtime_linker_t,
150
module: &wasmtime_module_t,
151
instance_ptr: &mut *mut wasmtime_instance_pre_t,
152
) -> Option<Box<wasmtime_error_t>> {
153
let linker = &linker.linker;
154
handle_result(linker.instantiate_pre(&module.module), |i| {
155
let instance_pre = Box::new(wasmtime_instance_pre_t { underlying: i });
156
*instance_ptr = Box::into_raw(instance_pre)
157
})
158
}
159
160
#[unsafe(no_mangle)]
161
pub unsafe extern "C" fn wasmtime_linker_module(
162
linker: &mut wasmtime_linker_t,
163
store: WasmtimeStoreContextMut<'_>,
164
name: *const u8,
165
name_len: usize,
166
module: &wasmtime_module_t,
167
) -> Option<Box<wasmtime_error_t>> {
168
let linker = &mut linker.linker;
169
let name = to_str!(name, name_len);
170
handle_result(linker.module(store, name, &module.module), |_linker| ())
171
}
172
173
#[unsafe(no_mangle)]
174
pub unsafe extern "C" fn wasmtime_linker_get_default(
175
linker: &wasmtime_linker_t,
176
store: WasmtimeStoreContextMut<'_>,
177
name: *const u8,
178
name_len: usize,
179
func: &mut Func,
180
) -> Option<Box<wasmtime_error_t>> {
181
let linker = &linker.linker;
182
let name = to_str!(name, name_len);
183
handle_result(linker.get_default(store, name), |f| *func = f)
184
}
185
186
#[unsafe(no_mangle)]
187
pub unsafe extern "C" fn wasmtime_linker_get(
188
linker: &wasmtime_linker_t,
189
store: WasmtimeStoreContextMut<'_>,
190
module: *const u8,
191
module_len: usize,
192
name: *const u8,
193
name_len: usize,
194
item_ptr: &mut MaybeUninit<wasmtime_extern_t>,
195
) -> bool {
196
let linker = &linker.linker;
197
let module = match str::from_utf8(crate::slice_from_raw_parts(module, module_len)) {
198
Ok(s) => s,
199
Err(_) => return false,
200
};
201
let name = match str::from_utf8(crate::slice_from_raw_parts(name, name_len)) {
202
Ok(s) => s,
203
Err(_) => return false,
204
};
205
match linker.get(store, module, name) {
206
Some(which) => {
207
crate::initialize(item_ptr, which.into());
208
true
209
}
210
None => false,
211
}
212
}
213
214