mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-24 12:32:29 +00:00
Implement crash in gen-wasm
This commit is contained in:
parent
a8122662c2
commit
32400e37e1
4 changed files with 32 additions and 14 deletions
|
@ -718,7 +718,7 @@ impl<'a> WasmBackend<'a> {
|
|||
Stmt::ExpectFx { .. } => todo!("expect-fx is not implemented in the wasm backend"),
|
||||
|
||||
Stmt::RuntimeError(msg) => self.stmt_runtime_error(msg),
|
||||
Stmt::Crash(_, _) => todo!(),
|
||||
Stmt::Crash(sym, _) => self.stmt_crash(*sym),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1016,6 +1016,16 @@ impl<'a> WasmBackend<'a> {
|
|||
self.code_builder.unreachable_();
|
||||
}
|
||||
|
||||
pub fn stmt_crash(&mut self, msg: Symbol) {
|
||||
let tag_id = 1;
|
||||
// load the pointer
|
||||
self.storage.load_symbols(&mut self.code_builder, &[msg]);
|
||||
self.code_builder.i32_const(tag_id);
|
||||
self.call_host_fn_after_loading_args("roc_panic", 2, false);
|
||||
|
||||
self.code_builder.unreachable_();
|
||||
}
|
||||
|
||||
/**********************************************************
|
||||
|
||||
EXPRESSIONS
|
||||
|
|
|
@ -7,7 +7,7 @@ use crate::helpers::llvm::expect_runtime_error_panic;
|
|||
use crate::helpers::wasm::expect_runtime_error_panic;
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm"))]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
||||
#[should_panic = r#"User crash with message: "hello crash""#]
|
||||
fn crash_literal() {
|
||||
expect_runtime_error_panic!(indoc!(
|
||||
|
@ -20,7 +20,7 @@ fn crash_literal() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm"))]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
||||
#[should_panic = r#"User crash with message: "hello crash""#]
|
||||
fn crash_variable() {
|
||||
expect_runtime_error_panic!(indoc!(
|
||||
|
@ -35,7 +35,7 @@ fn crash_variable() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm"))]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
||||
#[should_panic = r#"User crash with message: "turns out this was fallible""#]
|
||||
fn crash_in_call() {
|
||||
expect_runtime_error_panic!(indoc!(
|
||||
|
@ -55,7 +55,7 @@ fn crash_in_call() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm"))]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
||||
#[should_panic = r#"User crash with message: "no new even primes""#]
|
||||
fn crash_in_passed_closure() {
|
||||
expect_runtime_error_panic!(indoc!(
|
||||
|
|
|
@ -194,7 +194,7 @@ where
|
|||
|
||||
let parsed = Module::parse(&env, &wasm_bytes[..]).expect("Unable to parse module");
|
||||
let mut module = rt.load_module(parsed).expect("Unable to load module");
|
||||
let panic_msg: Rc<Mutex<Option<i32>>> = Default::default();
|
||||
let panic_msg: Rc<Mutex<Option<(i32, u32)>>> = Default::default();
|
||||
link_module(&mut module, panic_msg.clone());
|
||||
|
||||
let test_wrapper = module
|
||||
|
@ -203,11 +203,18 @@ where
|
|||
|
||||
match test_wrapper.call() {
|
||||
Err(e) => {
|
||||
if let Some(msg_ptr) = *panic_msg.lock().unwrap() {
|
||||
if let Some((msg_ptr, tag)) = *panic_msg.lock().unwrap() {
|
||||
let memory: &[u8] = get_memory(&rt);
|
||||
let msg = RocStr::decode(memory, msg_ptr as _);
|
||||
|
||||
Err(format!("Roc failed with message: \"{}\"", msg))
|
||||
dbg!(tag);
|
||||
let msg = match tag {
|
||||
0 => format!(r#"Roc failed with message: "{}""#, msg),
|
||||
1 => format!(r#"User crash with message: "{}""#, msg),
|
||||
tag => format!(r#"Got an invald panic tag: "{}""#, tag),
|
||||
};
|
||||
|
||||
Err(msg)
|
||||
} else {
|
||||
Err(format!("{}", e))
|
||||
}
|
||||
|
@ -253,7 +260,7 @@ where
|
|||
let parsed = Module::parse(&env, wasm_bytes).expect("Unable to parse module");
|
||||
let mut module = rt.load_module(parsed).expect("Unable to load module");
|
||||
|
||||
let panic_msg: Rc<Mutex<Option<i32>>> = Default::default();
|
||||
let panic_msg: Rc<Mutex<Option<(i32, u32)>>> = Default::default();
|
||||
link_module(&mut module, panic_msg.clone());
|
||||
|
||||
let expected_len = num_refcounts as i32;
|
||||
|
@ -316,13 +323,13 @@ fn read_i32(memory: &[u8], ptr: usize) -> i32 {
|
|||
i32::from_le_bytes(bytes)
|
||||
}
|
||||
|
||||
fn link_module(module: &mut Module, panic_msg: Rc<Mutex<Option<i32>>>) {
|
||||
fn link_module(module: &mut Module, panic_msg: Rc<Mutex<Option<(i32, u32)>>>) {
|
||||
let try_link_panic = module.link_closure(
|
||||
"env",
|
||||
"send_panic_msg_to_rust",
|
||||
move |_call_context, msg_ptr: i32| {
|
||||
move |_call_context, (msg_ptr, tag): (i32, u32)| {
|
||||
let mut w = panic_msg.lock().unwrap();
|
||||
*w = Some(msg_ptr);
|
||||
*w = Some((msg_ptr, tag));
|
||||
Ok(())
|
||||
},
|
||||
);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
@ -123,11 +124,11 @@ void roc_dealloc(void *ptr, unsigned int alignment)
|
|||
|
||||
//--------------------------
|
||||
|
||||
extern void send_panic_msg_to_rust(void* msg);
|
||||
extern void send_panic_msg_to_rust(void* msg, uint32_t tag_id);
|
||||
|
||||
void roc_panic(void* msg, unsigned int tag_id)
|
||||
{
|
||||
send_panic_msg_to_rust(msg);
|
||||
send_panic_msg_to_rust(msg, tag_id);
|
||||
exit(101);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue