mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-28 06:14:46 +00:00
test_gen: create a getter for wasm panic messages
This commit is contained in:
parent
63c33d82e3
commit
a9df6f4ff9
2 changed files with 51 additions and 1 deletions
|
@ -18,6 +18,7 @@ const OUT_DIR_VAR: &str = "TEST_GEN_OUT";
|
|||
|
||||
const TEST_WRAPPER_NAME: &str = "test_wrapper";
|
||||
const INIT_REFCOUNT_NAME: &str = "init_refcount_test";
|
||||
const GET_PANIC_MSG_NAME: &str = "get_panic_msg";
|
||||
|
||||
fn promote_expr_to_module(src: &str) -> String {
|
||||
let mut buffer = String::from("app \"test\" provides [ main ] to \"./platform\"\n\nmain =\n");
|
||||
|
@ -136,6 +137,15 @@ fn compile_roc_to_wasm_bytes<'a, T: Wasm32Result>(
|
|||
index: init_refcount_idx,
|
||||
});
|
||||
|
||||
// Export the getter function for panic messages
|
||||
let get_panic_msg_bytes = GET_PANIC_MSG_NAME.as_bytes();
|
||||
let get_panic_msg_idx = module.names.functions[get_panic_msg_bytes];
|
||||
module.export.append(Export {
|
||||
name: arena.alloc_slice_copy(get_panic_msg_bytes),
|
||||
ty: ExportType::Func,
|
||||
index: get_panic_msg_idx,
|
||||
});
|
||||
|
||||
module.remove_dead_preloads(env.arena, called_preload_fns);
|
||||
|
||||
let mut app_module_bytes = std::vec::Vec::with_capacity(module.size());
|
||||
|
@ -194,7 +204,10 @@ where
|
|||
let test_wrapper = instance.exports.get_function(TEST_WRAPPER_NAME).unwrap();
|
||||
|
||||
match test_wrapper.call(&[]) {
|
||||
Err(e) => Err(format!("{:?}", e)),
|
||||
Err(e) => match get_panic_msg(&instance, memory) {
|
||||
Ok(msg) => Err(msg),
|
||||
Err(_) => Err(format!("{}", e)),
|
||||
},
|
||||
Ok(result) => {
|
||||
let address = match result[0] {
|
||||
wasmer::Value::I32(a) => a,
|
||||
|
@ -218,6 +231,35 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
/// Call our test platform's getter function for panic messages
|
||||
fn get_panic_msg(instance: &wasmer::Instance, memory: &wasmer::Memory) -> Result<String, String> {
|
||||
let msg_getter = instance
|
||||
.exports
|
||||
.get_function(GET_PANIC_MSG_NAME)
|
||||
.map_err(|e| format!("{:?}", e))?;
|
||||
|
||||
let msg_result = msg_getter.call(&[]).map_err(|e| format!("{:?}", e))?;
|
||||
|
||||
let msg_addr: i32 = match msg_result[0] {
|
||||
wasmer::Value::I32(a) => a,
|
||||
_ => panic!(),
|
||||
};
|
||||
if msg_addr == 0 {
|
||||
return Err("no panic msg".to_string());
|
||||
}
|
||||
|
||||
let msg_index = msg_addr as usize;
|
||||
let memory_bytes = unsafe { memory.data_unchecked() };
|
||||
let msg_len = memory_bytes[msg_index..]
|
||||
.iter()
|
||||
.position(|c| *c == 0)
|
||||
.unwrap();
|
||||
|
||||
let msg_bytes = &memory_bytes[msg_index..msg_len];
|
||||
let msg = unsafe { String::from_utf8_unchecked(msg_bytes.to_vec()) };
|
||||
Ok(msg)
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn assert_wasm_refcounts_help<T>(
|
||||
src: &str,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue