Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add function to retrieve function name from wasm_frame_t #3222

Merged
merged 15 commits into from
Oct 25, 2022
77 changes: 77 additions & 0 deletions lib/c-api/src/wasm_c_api/types/frame.rs
Original file line number Diff line number Diff line change
@@ -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)]
Expand Down Expand Up @@ -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);
}
17 changes: 17 additions & 0 deletions lib/compiler/src/engine/trap/frame_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<String>,
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
Expand Down