1 use crate::{ 2 wasm_byte_vec_t, wasm_config_t, wasm_engine_t, wasmtime_component_type_t, wasmtime_error_t, 3 }; 4 use std::ffi::{CStr, c_char}; 5 use wasmtime::component::{Component, ComponentExportIndex}; 6 use wasmtime::error::Context; 7 8 #[unsafe(no_mangle)] 9 pub extern "C" fn wasmtime_config_wasm_component_model_set(c: &mut wasm_config_t, enable: bool) { 10 c.config.wasm_component_model(enable); 11 } 12 13 #[derive(Clone)] 14 #[repr(transparent)] 15 pub struct wasmtime_component_t { 16 pub(crate) component: Component, 17 } 18 19 #[unsafe(no_mangle)] 20 #[cfg(any(feature = "cranelift", feature = "winch"))] 21 pub unsafe extern "C" fn wasmtime_component_new( 22 engine: &wasm_engine_t, 23 buf: *const u8, 24 len: usize, 25 component_out: &mut *mut wasmtime_component_t, 26 ) -> Option<Box<wasmtime_error_t>> { 27 let bytes = unsafe { crate::slice_from_raw_parts(buf, len) }; 28 crate::handle_result(Component::new(&engine.engine, bytes), |component| { 29 *component_out = Box::into_raw(Box::new(wasmtime_component_t { component })); 30 }) 31 } 32 33 #[unsafe(no_mangle)] 34 #[cfg(any(feature = "cranelift", feature = "winch"))] 35 pub extern "C" fn wasmtime_component_serialize( 36 component: &wasmtime_component_t, 37 ret: &mut wasm_byte_vec_t, 38 ) -> Option<Box<wasmtime_error_t>> { 39 crate::handle_result(component.component.serialize(), |buffer| { 40 ret.set_buffer(buffer); 41 }) 42 } 43 44 #[unsafe(no_mangle)] 45 pub unsafe extern "C" fn wasmtime_component_deserialize( 46 engine: &wasm_engine_t, 47 buf: *const u8, 48 len: usize, 49 component_out: &mut *mut wasmtime_component_t, 50 ) -> Option<Box<wasmtime_error_t>> { 51 let binary = unsafe { crate::slice_from_raw_parts(buf, len) }; 52 crate::handle_result( 53 unsafe { Component::deserialize(&engine.engine, binary) }, 54 |component| { 55 *component_out = Box::into_raw(Box::new(wasmtime_component_t { component })); 56 }, 57 ) 58 } 59 60 #[unsafe(no_mangle)] 61 pub unsafe extern "C" fn wasmtime_component_deserialize_file( 62 engine: &wasm_engine_t, 63 path: *const c_char, 64 component_out: &mut *mut wasmtime_component_t, 65 ) -> Option<Box<wasmtime_error_t>> { 66 let path = unsafe { CStr::from_ptr(path) }; 67 let result = path 68 .to_str() 69 .context("input path is not valid utf-8") 70 .and_then(|path| unsafe { Component::deserialize_file(&engine.engine, path) }); 71 crate::handle_result(result, |component| { 72 *component_out = Box::into_raw(Box::new(wasmtime_component_t { component })); 73 }) 74 } 75 76 #[unsafe(no_mangle)] 77 pub extern "C" fn wasmtime_component_type( 78 component: &wasmtime_component_t, 79 ) -> Box<wasmtime_component_type_t> { 80 Box::new(component.component.component_type().into()) 81 } 82 83 #[unsafe(no_mangle)] 84 pub extern "C" fn wasmtime_component_clone( 85 component: &wasmtime_component_t, 86 ) -> Box<wasmtime_component_t> { 87 Box::new(component.clone()) 88 } 89 90 #[unsafe(no_mangle)] 91 pub extern "C" fn wasmtime_component_delete(_component: Box<wasmtime_component_t>) {} 92 93 #[repr(transparent)] 94 pub struct wasmtime_component_export_index_t { 95 pub(crate) export_index: ComponentExportIndex, 96 } 97 98 #[unsafe(no_mangle)] 99 pub unsafe extern "C" fn wasmtime_component_get_export_index( 100 component: &wasmtime_component_t, 101 instance_export_index: *const wasmtime_component_export_index_t, 102 name: *const u8, 103 name_len: usize, 104 ) -> Option<Box<wasmtime_component_export_index_t>> { 105 let name = unsafe { std::slice::from_raw_parts(name, name_len) }; 106 let Ok(name) = std::str::from_utf8(name) else { 107 return None; 108 }; 109 110 let instance_export_index = if instance_export_index.is_null() { 111 None 112 } else { 113 Some((*instance_export_index).export_index) 114 }; 115 116 component 117 .component 118 .get_export_index(instance_export_index.as_ref(), &name) 119 .map(|export_index| Box::new(wasmtime_component_export_index_t { export_index })) 120 } 121 122 #[unsafe(no_mangle)] 123 pub extern "C" fn wasmtime_component_export_index_clone( 124 export_index: &wasmtime_component_export_index_t, 125 ) -> Box<wasmtime_component_export_index_t> { 126 Box::new(wasmtime_component_export_index_t { 127 export_index: export_index.export_index, 128 }) 129 } 130 131 #[unsafe(no_mangle)] 132 pub extern "C" fn wasmtime_component_export_index_delete( 133 _export_index: Box<wasmtime_component_export_index_t>, 134 ) { 135 } 136