use crate::{ wasm_byte_vec_t, wasm_engine_t, wasm_name_t, wasmtime_error_t, wasmtime_module_t, wasmtime_store_t, }; use std::slice; use std::str::from_utf8; use std::time::Duration; use wasmtime::GuestProfiler; pub struct wasmtime_guestprofiler_t { guest_profiler: GuestProfiler, } wasmtime_c_api_macros::declare_own!(wasmtime_guestprofiler_t); #[repr(C)] pub struct wasmtime_guestprofiler_modules_t<'a> { name: &'a wasm_name_t, module: &'a wasmtime_module_t, } #[unsafe(no_mangle)] pub unsafe extern "C" fn wasmtime_guestprofiler_new( engine: &wasm_engine_t, module_name: &wasm_name_t, interval_nanos: u64, modules: *const wasmtime_guestprofiler_modules_t, modules_len: usize, ) -> Box { let module_name = from_utf8(&module_name.as_slice()).expect("not valid utf-8"); let list = slice::from_raw_parts(modules, modules_len) .iter() .map(|entry| { ( from_utf8(entry.name.as_slice()) .expect("not valid utf-8") .to_owned(), entry.module.module.clone(), ) }) .collect::>(); Box::new(wasmtime_guestprofiler_t { guest_profiler: GuestProfiler::new( &engine.engine, module_name, Duration::from_nanos(interval_nanos), list, ) .unwrap(), }) } #[unsafe(no_mangle)] pub extern "C" fn wasmtime_guestprofiler_sample( guestprofiler: &mut wasmtime_guestprofiler_t, store: &wasmtime_store_t, delta_nanos: u64, ) { guestprofiler .guest_profiler .sample(&store.store, Duration::from_nanos(delta_nanos)); } #[unsafe(no_mangle)] pub extern "C" fn wasmtime_guestprofiler_finish( guestprofiler: Box, out: &mut wasm_byte_vec_t, ) -> Option> { let mut buf = vec![]; match guestprofiler.guest_profiler.finish(&mut buf) { Ok(()) => { out.set_buffer(buf); None } Err(e) => Some(Box::new(e.into())), } }