Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/crates/c-api/src/component/linker.rs
3067 views
1
use crate::{
2
WasmtimeStoreContextMut, WasmtimeStoreData, wasm_engine_t, wasmtime_component_func_type_t,
3
wasmtime_component_resource_type_t, wasmtime_error_t, wasmtime_module_t,
4
};
5
use std::ffi::c_void;
6
use wasmtime::component::{Instance, Linker, LinkerInstance, Val};
7
8
use super::{wasmtime_component_t, wasmtime_component_val_t};
9
10
#[repr(transparent)]
11
pub struct wasmtime_component_linker_t {
12
pub(crate) linker: Linker<WasmtimeStoreData>,
13
}
14
15
#[repr(transparent)]
16
pub struct wasmtime_component_linker_instance_t<'a> {
17
pub(crate) linker_instance: LinkerInstance<'a, WasmtimeStoreData>,
18
}
19
20
#[unsafe(no_mangle)]
21
pub extern "C" fn wasmtime_component_linker_new(
22
engine: &wasm_engine_t,
23
) -> Box<wasmtime_component_linker_t> {
24
Box::new(wasmtime_component_linker_t {
25
linker: Linker::new(&engine.engine),
26
})
27
}
28
29
#[unsafe(no_mangle)]
30
pub extern "C" fn wasmtime_component_linker_allow_shadowing(
31
linker: &mut wasmtime_component_linker_t,
32
allow: bool,
33
) {
34
linker.linker.allow_shadowing(allow);
35
}
36
37
#[unsafe(no_mangle)]
38
pub extern "C" fn wasmtime_component_linker_root(
39
linker: &mut wasmtime_component_linker_t,
40
) -> Box<wasmtime_component_linker_instance_t<'_>> {
41
Box::new(wasmtime_component_linker_instance_t {
42
linker_instance: linker.linker.root(),
43
})
44
}
45
46
#[unsafe(no_mangle)]
47
pub extern "C" fn wasmtime_component_linker_instantiate(
48
linker: &wasmtime_component_linker_t,
49
context: WasmtimeStoreContextMut<'_>,
50
component: &wasmtime_component_t,
51
instance_out: &mut Instance,
52
) -> Option<Box<wasmtime_error_t>> {
53
let result = linker.linker.instantiate(context, &component.component);
54
crate::handle_result(result, |instance| *instance_out = instance)
55
}
56
57
#[unsafe(no_mangle)]
58
pub extern "C" fn wasmtime_component_linker_delete(_linker: Box<wasmtime_component_linker_t>) {}
59
60
#[unsafe(no_mangle)]
61
pub unsafe extern "C" fn wasmtime_component_linker_instance_add_instance<'a>(
62
linker_instance: &'a mut wasmtime_component_linker_instance_t<'a>,
63
name: *const u8,
64
name_len: usize,
65
linker_instance_out: &mut *mut wasmtime_component_linker_instance_t<'a>,
66
) -> Option<Box<wasmtime_error_t>> {
67
let name = unsafe { std::slice::from_raw_parts(name, name_len) };
68
let Ok(name) = std::str::from_utf8(name) else {
69
return crate::bad_utf8();
70
};
71
72
let result = linker_instance.linker_instance.instance(&name);
73
crate::handle_result(result, |linker_instance| {
74
*linker_instance_out = Box::into_raw(Box::new(wasmtime_component_linker_instance_t {
75
linker_instance,
76
}));
77
})
78
}
79
80
#[unsafe(no_mangle)]
81
pub unsafe extern "C" fn wasmtime_component_linker_instance_add_module(
82
linker_instance: &mut wasmtime_component_linker_instance_t,
83
name: *const u8,
84
name_len: usize,
85
module: &wasmtime_module_t,
86
) -> Option<Box<wasmtime_error_t>> {
87
let name = unsafe { std::slice::from_raw_parts(name, name_len) };
88
let Ok(name) = std::str::from_utf8(name) else {
89
return crate::bad_utf8();
90
};
91
92
let result = linker_instance
93
.linker_instance
94
.module(&name, &module.module);
95
96
crate::handle_result(result, |_| ())
97
}
98
99
pub type wasmtime_component_func_callback_t = extern "C" fn(
100
*mut c_void,
101
WasmtimeStoreContextMut<'_>,
102
&wasmtime_component_func_type_t,
103
*mut wasmtime_component_val_t,
104
usize,
105
*mut wasmtime_component_val_t,
106
usize,
107
) -> Option<Box<wasmtime_error_t>>;
108
109
#[unsafe(no_mangle)]
110
pub unsafe extern "C" fn wasmtime_component_linker_instance_add_func(
111
linker_instance: &mut wasmtime_component_linker_instance_t,
112
name: *const u8,
113
name_len: usize,
114
callback: wasmtime_component_func_callback_t,
115
data: *mut c_void,
116
finalizer: Option<extern "C" fn(*mut c_void)>,
117
) -> Option<Box<wasmtime_error_t>> {
118
let name = unsafe { std::slice::from_raw_parts(name, name_len) };
119
let Ok(name) = std::str::from_utf8(name) else {
120
return crate::bad_utf8();
121
};
122
123
let foreign = crate::ForeignData { data, finalizer };
124
125
let result = linker_instance
126
.linker_instance
127
.func_new(&name, move |ctx, ty, args, rets| {
128
let _ = &foreign;
129
130
let mut args = args
131
.iter()
132
.map(|x| wasmtime_component_val_t::from(x))
133
.collect::<Vec<_>>();
134
135
let mut c_rets = vec![wasmtime_component_val_t::Bool(false); rets.len()];
136
137
let res = callback(
138
foreign.data,
139
ctx,
140
&ty.into(),
141
args.as_mut_ptr(),
142
args.len(),
143
c_rets.as_mut_ptr(),
144
c_rets.len(),
145
);
146
147
if let Some(res) = res {
148
return Err((*res).into());
149
}
150
151
for (rust_val, c_val) in std::iter::zip(rets, c_rets) {
152
*rust_val = Val::from(&c_val);
153
}
154
155
Ok(())
156
});
157
158
crate::handle_result(result, |_| ())
159
}
160
161
#[unsafe(no_mangle)]
162
#[cfg(feature = "wasi")]
163
pub unsafe extern "C" fn wasmtime_component_linker_add_wasip2(
164
linker: &mut wasmtime_component_linker_t,
165
) -> Option<Box<wasmtime_error_t>> {
166
let result = wasmtime_wasi::p2::add_to_linker_sync(&mut linker.linker);
167
crate::handle_result(result, |_| ())
168
}
169
170
#[unsafe(no_mangle)]
171
pub unsafe extern "C" fn wasmtime_component_linker_define_unknown_imports_as_traps(
172
linker: &mut wasmtime_component_linker_t,
173
component: &wasmtime_component_t,
174
) -> Option<Box<wasmtime_error_t>> {
175
let result = linker
176
.linker
177
.define_unknown_imports_as_traps(&component.component);
178
crate::handle_result(result, |_| ())
179
}
180
181
pub type wasmtime_component_resource_destructor_t =
182
extern "C" fn(*mut c_void, WasmtimeStoreContextMut<'_>, u32) -> Option<Box<wasmtime_error_t>>;
183
184
#[unsafe(no_mangle)]
185
pub unsafe extern "C" fn wasmtime_component_linker_instance_add_resource(
186
linker_instance: &mut wasmtime_component_linker_instance_t,
187
name: *const u8,
188
name_len: usize,
189
ty: &wasmtime_component_resource_type_t,
190
callback: wasmtime_component_resource_destructor_t,
191
data: *mut c_void,
192
finalizer: Option<extern "C" fn(*mut c_void)>,
193
) -> Option<Box<wasmtime_error_t>> {
194
let name = unsafe { std::slice::from_raw_parts(name, name_len) };
195
let Ok(name) = std::str::from_utf8(name) else {
196
return crate::bad_utf8();
197
};
198
199
let foreign = crate::ForeignData { data, finalizer };
200
201
let result = linker_instance
202
.linker_instance
203
.resource(name, ty.ty, move |ctx, rep| {
204
let _ = &foreign;
205
if let Some(res) = callback(foreign.data, ctx, rep) {
206
return Err((*res).into());
207
}
208
Ok(())
209
});
210
211
crate::handle_result(result, |_| ())
212
}
213
214
#[unsafe(no_mangle)]
215
pub unsafe extern "C" fn wasmtime_component_linker_instance_delete(
216
_linker_instance: Box<wasmtime_component_linker_instance_t>,
217
) {
218
}
219
220