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