diff --git a/crates/compiler/builtins/bitcode/src/utils.zig b/crates/compiler/builtins/bitcode/src/utils.zig index 841b143863..8e5271d711 100644 --- a/crates/compiler/builtins/bitcode/src/utils.zig +++ b/crates/compiler/builtins/bitcode/src/utils.zig @@ -107,15 +107,16 @@ pub fn memcpy(dst: [*]u8, src: [*]u8, size: usize) void { // indirection because otherwise zig creates an alias to the panic function which our LLVM code // does not know how to deal with -pub fn test_panic(c_ptr: *anyopaque, alignment: u32) callconv(.C) void { +pub fn test_panic(c_ptr: *anyopaque, crash_tag: u32) callconv(.C) void { _ = c_ptr; - _ = alignment; - // const cstr = @ptrCast([*:0]u8, c_ptr); + _ = crash_tag; - // const stderr = std.io.getStdErr().writer(); - // stderr.print("Roc panicked: {s}!\n", .{cstr}) catch unreachable; - - // std.c.exit(1); + // const cstr = @ptrCast([*:0]u8, c_ptr); + // + // const stderr = std.io.getStdErr().writer(); + // stderr.print("Roc panicked: {s}!\n", .{cstr}) catch unreachable; + // + // std.c.exit(1); } pub const Inc = fn (?[*]u8) callconv(.C) void; diff --git a/crates/compiler/gen_dev/src/lib.rs b/crates/compiler/gen_dev/src/lib.rs index cd10214880..ad597aac63 100644 --- a/crates/compiler/gen_dev/src/lib.rs +++ b/crates/compiler/gen_dev/src/lib.rs @@ -14,8 +14,8 @@ use roc_module::low_level::{LowLevel, LowLevelWrapperType}; use roc_module::symbol::{Interns, ModuleId, Symbol}; use roc_mono::code_gen_help::{CallerProc, CodeGenHelp}; use roc_mono::ir::{ - BranchInfo, CallType, Expr, HigherOrderLowLevel, JoinPointId, ListLiteralElement, Literal, - Param, Proc, ProcLayout, SelfRecursive, Stmt, + BranchInfo, CallType, CrashTag, Expr, HigherOrderLowLevel, JoinPointId, ListLiteralElement, + Literal, Param, Proc, ProcLayout, SelfRecursive, Stmt, }; use roc_mono::layout::{ Builtin, InLayout, Layout, LayoutIds, LayoutInterner, STLayoutInterner, TagIdIntType, @@ -279,9 +279,33 @@ trait Backend<'a> { self.build_jump(id, args, arg_layouts.into_bump_slice(), ret_layout); self.free_symbols(stmt); } + Stmt::Crash(msg, crash_tag) => self.roc_panic(*msg, *crash_tag), x => todo!("the statement, {:?}", x), } } + + fn roc_panic(&mut self, msg: Symbol, crash_tag: CrashTag) { + self.load_literal( + &Symbol::DEV_TMP, + &Layout::U32, + &Literal::Int((crash_tag as u128).to_ne_bytes()), + ); + + // Now that the arguments are needed, load them if they are literals. + let arguments = &[msg, Symbol::DEV_TMP]; + self.load_literal_symbols(arguments); + self.build_fn_call( + &Symbol::DEV_TMP2, + String::from("roc_panic"), + arguments, + &[Layout::STR, Layout::U32], + &Layout::UNIT, + ); + + self.free_symbol(&Symbol::DEV_TMP); + self.free_symbol(&Symbol::DEV_TMP2); + } + // build_switch generates a instructions for a switch statement. fn build_switch( &mut self, @@ -1758,7 +1782,9 @@ trait Backend<'a> { Stmt::Expect { .. } => todo!("expect is not implemented in the dev backend"), Stmt::ExpectFx { .. } => todo!("expect-fx is not implemented in the dev backend"), - Stmt::Crash(..) => todo!("crash is not implemented in the dev backend"), + Stmt::Crash(msg, _crash_tag) => { + self.set_last_seen(*msg, stmt); + } } }