Path: blob/main/crates/c-api/src/component/linker.rs
1692 views
use std::ffi::c_void;12use wasmtime::component::{Instance, Linker, LinkerInstance, Val};34use crate::{5WasmtimeStoreContextMut, WasmtimeStoreData, wasm_engine_t, wasmtime_error_t, wasmtime_module_t,6};78use super::{wasmtime_component_t, wasmtime_component_val_t};910#[repr(transparent)]11pub struct wasmtime_component_linker_t {12pub(crate) linker: Linker<WasmtimeStoreData>,13}1415#[repr(transparent)]16pub struct wasmtime_component_linker_instance_t<'a> {17pub(crate) linker_instance: LinkerInstance<'a, WasmtimeStoreData>,18}1920#[unsafe(no_mangle)]21pub unsafe extern "C" fn wasmtime_component_linker_new(22engine: &wasm_engine_t,23) -> Box<wasmtime_component_linker_t> {24Box::new(wasmtime_component_linker_t {25linker: Linker::new(&engine.engine),26})27}2829#[unsafe(no_mangle)]30pub unsafe extern "C" fn wasmtime_component_linker_root(31linker: &mut wasmtime_component_linker_t,32) -> Box<wasmtime_component_linker_instance_t<'_>> {33Box::new(wasmtime_component_linker_instance_t {34linker_instance: linker.linker.root(),35})36}3738#[unsafe(no_mangle)]39pub unsafe extern "C" fn wasmtime_component_linker_instantiate(40linker: &wasmtime_component_linker_t,41context: WasmtimeStoreContextMut<'_>,42component: &wasmtime_component_t,43instance_out: &mut Instance,44) -> Option<Box<wasmtime_error_t>> {45let result = linker.linker.instantiate(context, &component.component);46crate::handle_result(result, |instance| *instance_out = instance)47}4849#[unsafe(no_mangle)]50pub unsafe extern "C" fn wasmtime_component_linker_delete(51_linker: Box<wasmtime_component_linker_t>,52) {53}5455#[unsafe(no_mangle)]56pub unsafe extern "C" fn wasmtime_component_linker_instance_add_instance<'a>(57linker_instance: &'a mut wasmtime_component_linker_instance_t<'a>,58name: *const u8,59name_len: usize,60linker_instance_out: &mut *mut wasmtime_component_linker_instance_t<'a>,61) -> Option<Box<wasmtime_error_t>> {62let name = unsafe { std::slice::from_raw_parts(name, name_len) };63let Ok(name) = std::str::from_utf8(name) else {64return crate::bad_utf8();65};6667let result = linker_instance.linker_instance.instance(&name);68crate::handle_result(result, |linker_instance| {69*linker_instance_out = Box::into_raw(Box::new(wasmtime_component_linker_instance_t {70linker_instance,71}));72})73}7475#[unsafe(no_mangle)]76pub unsafe extern "C" fn wasmtime_component_linker_instance_add_module(77linker_instance: &mut wasmtime_component_linker_instance_t,78name: *const u8,79name_len: usize,80module: &wasmtime_module_t,81) -> Option<Box<wasmtime_error_t>> {82let name = unsafe { std::slice::from_raw_parts(name, name_len) };83let Ok(name) = std::str::from_utf8(name) else {84return crate::bad_utf8();85};8687let result = linker_instance88.linker_instance89.module(&name, &module.module);9091crate::handle_result(result, |_| ())92}9394pub type wasmtime_component_func_callback_t = extern "C" fn(95*mut c_void,96WasmtimeStoreContextMut<'_>,97*const wasmtime_component_val_t,98usize,99*mut wasmtime_component_val_t,100usize,101) -> Option<Box<wasmtime_error_t>>;102103#[unsafe(no_mangle)]104pub unsafe extern "C" fn wasmtime_component_linker_instance_add_func(105linker_instance: &mut wasmtime_component_linker_instance_t,106name: *const u8,107name_len: usize,108callback: wasmtime_component_func_callback_t,109data: *mut c_void,110finalizer: Option<extern "C" fn(*mut c_void)>,111) -> Option<Box<wasmtime_error_t>> {112let name = unsafe { std::slice::from_raw_parts(name, name_len) };113let Ok(name) = std::str::from_utf8(name) else {114return crate::bad_utf8();115};116117let foreign = crate::ForeignData { data, finalizer };118119let result = linker_instance120.linker_instance121.func_new(&name, move |ctx, args, rets| {122let _ = &foreign;123124let args = args125.iter()126.map(|x| wasmtime_component_val_t::from(x))127.collect::<Vec<_>>();128129let mut c_rets = vec![wasmtime_component_val_t::Bool(false); rets.len()];130131let res = callback(132foreign.data,133ctx,134args.as_ptr(),135args.len(),136c_rets.as_mut_ptr(),137c_rets.len(),138);139140if let Some(res) = res {141return Err((*res).into());142}143144for (rust_val, c_val) in std::iter::zip(rets, c_rets) {145*rust_val = Val::from(&c_val);146}147148Ok(())149});150151crate::handle_result(result, |_| ())152}153154#[unsafe(no_mangle)]155#[cfg(feature = "wasi")]156pub unsafe extern "C" fn wasmtime_component_linker_add_wasip2(157linker: &mut wasmtime_component_linker_t,158) -> Option<Box<wasmtime_error_t>> {159let result = wasmtime_wasi::p2::add_to_linker_sync(&mut linker.linker);160crate::handle_result(result, |_| ())161}162163#[unsafe(no_mangle)]164pub unsafe extern "C" fn wasmtime_component_linker_instance_delete(165_linker_instance: Box<wasmtime_component_linker_instance_t>,166) {167}168169170