Path: blob/main/crates/c-api/src/component/linker.rs
3067 views
use crate::{1WasmtimeStoreContextMut, WasmtimeStoreData, wasm_engine_t, wasmtime_component_func_type_t,2wasmtime_component_resource_type_t, wasmtime_error_t, wasmtime_module_t,3};4use std::ffi::c_void;5use wasmtime::component::{Instance, Linker, LinkerInstance, Val};67use super::{wasmtime_component_t, wasmtime_component_val_t};89#[repr(transparent)]10pub struct wasmtime_component_linker_t {11pub(crate) linker: Linker<WasmtimeStoreData>,12}1314#[repr(transparent)]15pub struct wasmtime_component_linker_instance_t<'a> {16pub(crate) linker_instance: LinkerInstance<'a, WasmtimeStoreData>,17}1819#[unsafe(no_mangle)]20pub extern "C" fn wasmtime_component_linker_new(21engine: &wasm_engine_t,22) -> Box<wasmtime_component_linker_t> {23Box::new(wasmtime_component_linker_t {24linker: Linker::new(&engine.engine),25})26}2728#[unsafe(no_mangle)]29pub extern "C" fn wasmtime_component_linker_allow_shadowing(30linker: &mut wasmtime_component_linker_t,31allow: bool,32) {33linker.linker.allow_shadowing(allow);34}3536#[unsafe(no_mangle)]37pub extern "C" fn wasmtime_component_linker_root(38linker: &mut wasmtime_component_linker_t,39) -> Box<wasmtime_component_linker_instance_t<'_>> {40Box::new(wasmtime_component_linker_instance_t {41linker_instance: linker.linker.root(),42})43}4445#[unsafe(no_mangle)]46pub extern "C" fn wasmtime_component_linker_instantiate(47linker: &wasmtime_component_linker_t,48context: WasmtimeStoreContextMut<'_>,49component: &wasmtime_component_t,50instance_out: &mut Instance,51) -> Option<Box<wasmtime_error_t>> {52let result = linker.linker.instantiate(context, &component.component);53crate::handle_result(result, |instance| *instance_out = instance)54}5556#[unsafe(no_mangle)]57pub extern "C" fn wasmtime_component_linker_delete(_linker: Box<wasmtime_component_linker_t>) {}5859#[unsafe(no_mangle)]60pub unsafe extern "C" fn wasmtime_component_linker_instance_add_instance<'a>(61linker_instance: &'a mut wasmtime_component_linker_instance_t<'a>,62name: *const u8,63name_len: usize,64linker_instance_out: &mut *mut wasmtime_component_linker_instance_t<'a>,65) -> Option<Box<wasmtime_error_t>> {66let name = unsafe { std::slice::from_raw_parts(name, name_len) };67let Ok(name) = std::str::from_utf8(name) else {68return crate::bad_utf8();69};7071let result = linker_instance.linker_instance.instance(&name);72crate::handle_result(result, |linker_instance| {73*linker_instance_out = Box::into_raw(Box::new(wasmtime_component_linker_instance_t {74linker_instance,75}));76})77}7879#[unsafe(no_mangle)]80pub unsafe extern "C" fn wasmtime_component_linker_instance_add_module(81linker_instance: &mut wasmtime_component_linker_instance_t,82name: *const u8,83name_len: usize,84module: &wasmtime_module_t,85) -> Option<Box<wasmtime_error_t>> {86let name = unsafe { std::slice::from_raw_parts(name, name_len) };87let Ok(name) = std::str::from_utf8(name) else {88return crate::bad_utf8();89};9091let result = linker_instance92.linker_instance93.module(&name, &module.module);9495crate::handle_result(result, |_| ())96}9798pub type wasmtime_component_func_callback_t = extern "C" fn(99*mut c_void,100WasmtimeStoreContextMut<'_>,101&wasmtime_component_func_type_t,102*mut wasmtime_component_val_t,103usize,104*mut wasmtime_component_val_t,105usize,106) -> Option<Box<wasmtime_error_t>>;107108#[unsafe(no_mangle)]109pub unsafe extern "C" fn wasmtime_component_linker_instance_add_func(110linker_instance: &mut wasmtime_component_linker_instance_t,111name: *const u8,112name_len: usize,113callback: wasmtime_component_func_callback_t,114data: *mut c_void,115finalizer: Option<extern "C" fn(*mut c_void)>,116) -> Option<Box<wasmtime_error_t>> {117let name = unsafe { std::slice::from_raw_parts(name, name_len) };118let Ok(name) = std::str::from_utf8(name) else {119return crate::bad_utf8();120};121122let foreign = crate::ForeignData { data, finalizer };123124let result = linker_instance125.linker_instance126.func_new(&name, move |ctx, ty, args, rets| {127let _ = &foreign;128129let mut args = args130.iter()131.map(|x| wasmtime_component_val_t::from(x))132.collect::<Vec<_>>();133134let mut c_rets = vec![wasmtime_component_val_t::Bool(false); rets.len()];135136let res = callback(137foreign.data,138ctx,139&ty.into(),140args.as_mut_ptr(),141args.len(),142c_rets.as_mut_ptr(),143c_rets.len(),144);145146if let Some(res) = res {147return Err((*res).into());148}149150for (rust_val, c_val) in std::iter::zip(rets, c_rets) {151*rust_val = Val::from(&c_val);152}153154Ok(())155});156157crate::handle_result(result, |_| ())158}159160#[unsafe(no_mangle)]161#[cfg(feature = "wasi")]162pub unsafe extern "C" fn wasmtime_component_linker_add_wasip2(163linker: &mut wasmtime_component_linker_t,164) -> Option<Box<wasmtime_error_t>> {165let result = wasmtime_wasi::p2::add_to_linker_sync(&mut linker.linker);166crate::handle_result(result, |_| ())167}168169#[unsafe(no_mangle)]170pub unsafe extern "C" fn wasmtime_component_linker_define_unknown_imports_as_traps(171linker: &mut wasmtime_component_linker_t,172component: &wasmtime_component_t,173) -> Option<Box<wasmtime_error_t>> {174let result = linker175.linker176.define_unknown_imports_as_traps(&component.component);177crate::handle_result(result, |_| ())178}179180pub type wasmtime_component_resource_destructor_t =181extern "C" fn(*mut c_void, WasmtimeStoreContextMut<'_>, u32) -> Option<Box<wasmtime_error_t>>;182183#[unsafe(no_mangle)]184pub unsafe extern "C" fn wasmtime_component_linker_instance_add_resource(185linker_instance: &mut wasmtime_component_linker_instance_t,186name: *const u8,187name_len: usize,188ty: &wasmtime_component_resource_type_t,189callback: wasmtime_component_resource_destructor_t,190data: *mut c_void,191finalizer: Option<extern "C" fn(*mut c_void)>,192) -> Option<Box<wasmtime_error_t>> {193let name = unsafe { std::slice::from_raw_parts(name, name_len) };194let Ok(name) = std::str::from_utf8(name) else {195return crate::bad_utf8();196};197198let foreign = crate::ForeignData { data, finalizer };199200let result = linker_instance201.linker_instance202.resource(name, ty.ty, move |ctx, rep| {203let _ = &foreign;204if let Some(res) = callback(foreign.data, ctx, rep) {205return Err((*res).into());206}207Ok(())208});209210crate::handle_result(result, |_| ())211}212213#[unsafe(no_mangle)]214pub unsafe extern "C" fn wasmtime_component_linker_instance_delete(215_linker_instance: Box<wasmtime_component_linker_instance_t>,216) {217}218219220