diff --git a/lib/c-api/src/wasm_c_api/types/frame.rs b/lib/c-api/src/wasm_c_api/types/frame.rs index d88767d6882..9cccd95805f 100644 --- a/lib/c-api/src/wasm_c_api/types/frame.rs +++ b/lib/c-api/src/wasm_c_api/types/frame.rs @@ -1,4 +1,6 @@ use super::super::instance::wasm_instance_t; +use libc::c_char; +use std::ffi::CString; use wasmer_api::FrameInfo; #[allow(non_camel_case_types)] @@ -47,4 +49,79 @@ pub unsafe extern "C" fn wasm_frame_module_offset(frame: &wasm_frame_t) -> usize frame.info.module_offset() } +#[repr(C)] +#[allow(non_camel_case_types)] +#[derive(Debug, Clone)] +pub struct wasm_name_t { + pub name: *mut c_char, +} + +#[no_mangle] +pub unsafe extern "C" fn wasm_frame_module_name(frame: &wasm_frame_t) -> wasm_name_t { + let module_name = + Some(frame.info.module_name()).and_then(|f| Some(CString::new(f).ok()?.into_raw())); + + match module_name { + Some(s) => wasm_name_t { name: s }, + None => wasm_name_t { + name: core::ptr::null_mut(), + }, + } +} + +#[no_mangle] +pub unsafe extern "C" fn wasm_frame_func_name(frame: &wasm_frame_t) -> wasm_name_t { + let func_name = frame + .info + .function_name() + .and_then(|f| Some(CString::new(f).ok()?.into_raw())); + + match func_name { + Some(s) => wasm_name_t { name: s }, + None => wasm_name_t { + name: core::ptr::null_mut(), + }, + } +} + +#[no_mangle] +pub unsafe extern "C" fn wasm_name_delete(name: Option<&mut wasm_name_t>) { + if let Some(s) = name { + if !s.name.is_null() { + let _ = CString::from_raw(s.name); + } + } +} + wasm_declare_boxed_vec!(frame); + +#[cfg(test)] +#[test] +fn test_frame_name() { + use std::ffi::CStr; + use wasmer_types::SourceLoc; + + let info = wasm_frame_t { + info: FrameInfo::new( + "module_name".to_string(), + 5, + Some("function_name".to_string()), + SourceLoc::new(10), + SourceLoc::new(20), + ), + }; + + unsafe { + let mut wasm_frame_func_name = wasm_frame_func_name(&info); + let s = CStr::from_ptr(wasm_frame_func_name.name); + assert_eq!(s.to_str().unwrap(), "function_name"); + wasm_name_delete(Some(&mut wasm_frame_func_name)); + + let mut wasm_frame_module_name = wasm_frame_module_name(&info); + let s = CStr::from_ptr(wasm_frame_module_name.name); + assert_eq!(s.to_str().unwrap(), "module_name"); + wasm_name_delete(Some(&mut wasm_frame_module_name)); + } + + println!("{:#?}", info); +} diff --git a/lib/compiler/src/engine/trap/frame_info.rs b/lib/compiler/src/engine/trap/frame_info.rs index 65324014cfd..c7bf7034d73 100644 --- a/lib/compiler/src/engine/trap/frame_info.rs +++ b/lib/compiler/src/engine/trap/frame_info.rs @@ -259,6 +259,23 @@ pub struct FrameInfo { } impl FrameInfo { + /// Creates a new [FrameInfo], useful for testing. + pub fn new( + module_name: String, + func_index: u32, + function_name: Option, + func_start: SourceLoc, + instr: SourceLoc, + ) -> Self { + Self { + module_name, + func_index, + function_name, + func_start, + instr, + } + } + /// Returns the WebAssembly function index for this frame. /// /// This function index is the index in the function index space of the