Get tests passing

Add roc_dbg to some platforms.
Also start updating some roc_panic impls.
This commit is contained in:
Brendan Hansknecht 2023-11-29 16:18:22 -08:00
parent e6cc43492a
commit f5fb01fd53
No known key found for this signature in database
GPG key ID: 0EA784685083E75B
17 changed files with 191 additions and 47 deletions

View file

@ -562,11 +562,11 @@ mod cli_run {
x : Num * x : Num *
x = 42 x = 42
[<ignored for tests> 19:9] 42 [#UserApp] 42
[<ignored for tests> 20:9] "Fjoer en ferdjer frieten oan dyn geve lea" [#UserApp] "Fjoer en ferdjer frieten oan dyn geve lea"
[<ignored for tests> 13:9] "abc" [#UserApp] "abc"
[<ignored for tests> 13:9] 10 [#UserApp] 10
[<ignored for tests> 13:9] A (B C) [#UserApp] (A (B C))
Program finished! Program finished!
"# "#
), ),

View file

@ -38,15 +38,19 @@ export fn roc_memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void {
return memset(dst, value, size); return memset(dst, value, size);
} }
export fn roc_panic(c_ptr: *anyopaque, tag_id: u32) callconv(.C) void { export fn roc_panic(msg: *RocStr, tag_id: u32) callconv(.C) void {
_ = tag_id; _ = tag_id;
const stderr = std.io.getStdErr().writer(); const stderr = std.io.getStdErr().writer();
const msg = @as([*:0]const u8, @ptrCast(c_ptr)); stderr.print("Application crashed with message\n\n {s}\n\nShutting down\n", .{msg.asSlice()}) catch unreachable;
stderr.print("Application crashed with message\n\n {s}\n\nShutting down\n", .{msg}) catch unreachable;
std.process.exit(0); std.process.exit(0);
} }
export fn roc_dbg(loc: *RocStr, msg: *RocStr) callconv(.C) void {
const stderr = std.io.getStdErr().writer();
stderr.print("[{s}] {s}\n", .{ loc.asSlice(), msg.asSlice() }) catch unreachable;
}
extern fn kill(pid: c_int, sig: c_int) c_int; extern fn kill(pid: c_int, sig: c_int) c_int;
extern fn shm_open(name: *const i8, oflag: c_int, mode: c_uint) c_int; extern fn shm_open(name: *const i8, oflag: c_int, mode: c_uint) c_int;
extern fn mmap(addr: ?*anyopaque, length: c_uint, prot: c_int, flags: c_int, fd: c_int, offset: c_uint) *anyopaque; extern fn mmap(addr: ?*anyopaque, length: c_uint, prot: c_int, flags: c_int, fd: c_int, offset: c_uint) *anyopaque;

View file

@ -1,5 +1,7 @@
const std = @import("std"); const std = @import("std");
const builtin = @import("builtin"); const builtin = @import("builtin");
const str = @import("glue").str;
const RocStr = str.RocStr;
const testing = std.testing; const testing = std.testing;
const expectEqual = testing.expectEqual; const expectEqual = testing.expectEqual;
const expect = testing.expect; const expect = testing.expect;
@ -50,13 +52,17 @@ export fn roc_dealloc(c_ptr: *anyopaque, alignment: u32) callconv(.C) void {
free(@as([*]align(Align) u8, @alignCast(@ptrCast(c_ptr)))); free(@as([*]align(Align) u8, @alignCast(@ptrCast(c_ptr))));
} }
export fn roc_panic(c_ptr: *anyopaque, tag_id: u32) callconv(.C) void { export fn roc_panic(msg: *RocStr, tag_id: u32) callconv(.C) void {
_ = tag_id; _ = tag_id;
const stderr = std.io.getStdErr().writer(); const stderr = std.io.getStdErr().writer();
const msg = @as([*:0]const u8, @ptrCast(c_ptr)); stderr.print("Application crashed with message\n\n {s}\n\nShutting down\n", .{msg.asSlice()}) catch unreachable;
stderr.print("Application crashed with message\n\n {s}\n\nShutting down\n", .{msg}) catch unreachable; std.process.exit(1);
std.process.exit(0); }
export fn roc_dbg(loc: *RocStr, msg: *RocStr) callconv(.C) void {
const stderr = std.io.getStdErr().writer();
stderr.print("[{s}] {s}\n", .{ loc.asSlice(), msg.asSlice() }) catch unreachable;
} }
export fn roc_memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void { export fn roc_memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void {

View file

@ -54,13 +54,17 @@ export fn roc_dealloc(c_ptr: *anyopaque, alignment: u32) callconv(.C) void {
free(@as([*]align(Align) u8, @alignCast(@ptrCast(c_ptr)))); free(@as([*]align(Align) u8, @alignCast(@ptrCast(c_ptr))));
} }
export fn roc_panic(c_ptr: *anyopaque, tag_id: u32) callconv(.C) void { export fn roc_panic(msg: *RocStr, tag_id: u32) callconv(.C) void {
_ = tag_id; _ = tag_id;
const stderr = std.io.getStdErr().writer(); const stderr = std.io.getStdErr().writer();
const msg = @as([*:0]const u8, @ptrCast(c_ptr)); stderr.print("Application crashed with message\n\n {s}\n\nShutting down\n", .{msg.asSlice()}) catch unreachable;
stderr.print("Application crashed with message\n\n {s}\n\nShutting down\n", .{msg}) catch unreachable; std.process.exit(1);
std.process.exit(0); }
export fn roc_dbg(loc: *RocStr, msg: *RocStr) callconv(.C) void {
const stderr = std.io.getStdErr().writer();
stderr.print("[{s}] {s}\n", .{ loc.asSlice(), msg.asSlice() }) catch unreachable;
} }
export fn roc_memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void { export fn roc_memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void {

View file

@ -44,13 +44,18 @@ export fn roc_dealloc(c_ptr: *anyopaque, alignment: u32) callconv(.C) void {
free(@as([*]align(Align) u8, @alignCast(@ptrCast(c_ptr)))); free(@as([*]align(Align) u8, @alignCast(@ptrCast(c_ptr))));
} }
export fn roc_panic(c_ptr: *anyopaque, tag_id: u32) callconv(.C) void { export fn roc_panic(msg: *RocStr, tag_id: u32) callconv(.C) void {
_ = tag_id; _ = tag_id;
const stderr = std.io.getStdErr().writer(); const stderr = std.io.getStdErr().writer();
const msg = @as([*:0]const u8, @ptrCast(c_ptr)); stderr.print("Application crashed with message\n\n {s}\n\nShutting down\n", .{msg.asSlice()}) catch unreachable;
stderr.print("Application crashed with message\n\n {s}\n\nShutting down\n", .{msg}) catch unreachable; std.process.exit(1);
std.process.exit(0); }
export fn roc_dbg(loc: *RocStr, msg: *RocStr) callconv(.C) void {
// This platform uses stdout for testing purposes instead of the normal stderr.
const stdout = std.io.getStdOut().writer();
stdout.print("[{s}] {s}\n", .{ loc.asSlice(), msg.asSlice() }) catch unreachable;
} }
export fn roc_memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void { export fn roc_memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void {

View file

@ -57,6 +57,14 @@ impl AssemblyBackendMode {
AssemblyBackendMode::Repl => true, AssemblyBackendMode::Repl => true,
} }
} }
fn generate_roc_dbg(self) -> bool {
match self {
AssemblyBackendMode::Binary => false,
AssemblyBackendMode::Test => true,
AssemblyBackendMode::Repl => true,
}
}
} }
pub struct Env<'a> { pub struct Env<'a> {

View file

@ -296,6 +296,23 @@ fn generate_roc_panic<'a, B: Backend<'a>>(backend: &mut B, output: &mut Object)
} }
} }
fn generate_roc_dbg<'a, B: Backend<'a>>(_backend: &mut B, output: &mut Object) {
let text_section = output.section_id(StandardSection::Text);
let proc_symbol = Symbol {
name: "roc_dbg".as_bytes().to_vec(),
value: 0,
size: 0,
kind: SymbolKind::Text,
scope: SymbolScope::Dynamic,
weak: false,
section: SymbolSection::Section(text_section),
flags: SymbolFlags::None,
};
let _proc_id = output.add_symbol(proc_symbol);
// TODO: Actually generate an impl instead of just an empty symbol.
// At a minimum, it should just be a ret.
}
fn generate_wrapper<'a, B: Backend<'a>>( fn generate_wrapper<'a, B: Backend<'a>>(
backend: &mut B, backend: &mut B,
output: &mut Object, output: &mut Object,
@ -412,6 +429,10 @@ fn build_object<'a, B: Backend<'a>>(
generate_longjmp(&mut backend, &mut output); generate_longjmp(&mut backend, &mut output);
} }
if backend.env().mode.generate_roc_dbg() {
generate_roc_dbg(&mut backend, &mut output);
}
if backend.env().mode.generate_allocators() { if backend.env().mode.generate_allocators() {
generate_wrapper( generate_wrapper(
&mut backend, &mut backend,

View file

@ -160,6 +160,9 @@ pub fn add_default_roc_externs(env: &Env<'_, '_, '_>) {
} }
} }
// TODO: generate a valid impl of dbg here.
unreachable_function(env, "roc_dbg");
match env.target_info.operating_system { match env.target_info.operating_system {
roc_target::OperatingSystem::Windows => { roc_target::OperatingSystem::Windows => {
// We don't need these functions on Windows // We don't need these functions on Windows

View file

@ -132,6 +132,8 @@ void roc_panic(void* msg, unsigned int panic_tag)
exit(101); exit(101);
} }
void roc_debug(void* loc, void* msg) {}
//-------------------------- //--------------------------
void *roc_memset(void *str, int c, size_t n) void *roc_memset(void *str, int c, size_t n)

View file

@ -2,8 +2,48 @@ procedure Bool.2 ():
let Bool.23 : Int1 = true; let Bool.23 : Int1 = true;
ret Bool.23; ret Bool.23;
procedure Inspect.249 (Inspect.250, Inspect.248):
let Inspect.323 : Str = "\"";
let Inspect.322 : Str = CallByName Inspect.61 Inspect.250 Inspect.323;
let Inspect.318 : Str = CallByName Inspect.61 Inspect.322 Inspect.248;
let Inspect.319 : Str = "\"";
let Inspect.317 : Str = CallByName Inspect.61 Inspect.318 Inspect.319;
ret Inspect.317;
procedure Inspect.30 (Inspect.147):
ret Inspect.147;
procedure Inspect.35 (Inspect.300):
ret Inspect.300;
procedure Inspect.36 (Inspect.304):
let Inspect.311 : Str = "";
ret Inspect.311;
procedure Inspect.44 (Inspect.248):
let Inspect.313 : Str = CallByName Inspect.30 Inspect.248;
ret Inspect.313;
procedure Inspect.5 (Inspect.150):
let Inspect.312 : Str = CallByName Inspect.44 Inspect.150;
let Inspect.309 : {} = Struct {};
let Inspect.308 : Str = CallByName Inspect.36 Inspect.309;
let Inspect.307 : Str = CallByName Inspect.249 Inspect.308 Inspect.312;
ret Inspect.307;
procedure Inspect.61 (Inspect.303, Inspect.298):
let Inspect.321 : Str = CallByName Str.3 Inspect.303 Inspect.298;
dec Inspect.298;
ret Inspect.321;
procedure Str.3 (#Attr.2, #Attr.3):
let Str.292 : Str = lowlevel StrConcat #Attr.2 #Attr.3;
ret Str.292;
procedure Test.1 (): procedure Test.1 ():
let Test.0 : Str = ""; let Test.5 : Str = "";
let Test.4 : Str = CallByName Inspect.5 Test.5;
let Test.0 : Str = CallByName Inspect.35 Test.4;
dbg Test.0; dbg Test.0;
dec Test.0; dec Test.0;
let Test.3 : Int1 = CallByName Bool.2; let Test.3 : Int1 = CallByName Bool.2;

View file

@ -1,5 +1,45 @@
procedure Inspect.249 (Inspect.250, Inspect.248):
let Inspect.323 : Str = "\"";
let Inspect.322 : Str = CallByName Inspect.61 Inspect.250 Inspect.323;
let Inspect.318 : Str = CallByName Inspect.61 Inspect.322 Inspect.248;
let Inspect.319 : Str = "\"";
let Inspect.317 : Str = CallByName Inspect.61 Inspect.318 Inspect.319;
ret Inspect.317;
procedure Inspect.30 (Inspect.147):
ret Inspect.147;
procedure Inspect.35 (Inspect.300):
ret Inspect.300;
procedure Inspect.36 (Inspect.304):
let Inspect.311 : Str = "";
ret Inspect.311;
procedure Inspect.44 (Inspect.248):
let Inspect.313 : Str = CallByName Inspect.30 Inspect.248;
ret Inspect.313;
procedure Inspect.5 (Inspect.150):
let Inspect.312 : Str = CallByName Inspect.44 Inspect.150;
let Inspect.309 : {} = Struct {};
let Inspect.308 : Str = CallByName Inspect.36 Inspect.309;
let Inspect.307 : Str = CallByName Inspect.249 Inspect.308 Inspect.312;
ret Inspect.307;
procedure Inspect.61 (Inspect.303, Inspect.298):
let Inspect.321 : Str = CallByName Str.3 Inspect.303 Inspect.298;
dec Inspect.298;
ret Inspect.321;
procedure Str.3 (#Attr.2, #Attr.3):
let Str.292 : Str = lowlevel StrConcat #Attr.2 #Attr.3;
ret Str.292;
procedure Test.0 (): procedure Test.0 ():
let Test.1 : Str = ""; let Test.4 : Str = "";
let Test.3 : Str = CallByName Inspect.5 Test.4;
let Test.1 : Str = CallByName Inspect.35 Test.3;
dbg Test.1; dbg Test.1;
dec Test.1; dec Test.1;
let Test.2 : I64 = 42i64; let Test.2 : I64 = 42i64;

View file

@ -1,7 +1,7 @@
app "test" provides [main] to "./platform" app "test" provides [main] to "./platform"
polyDbg = \x -> polyDbg = \x ->
#^^^^^^^{-1} a -[[polyDbg(1)]]-> a #^^^^^^^{-1} val -[[polyDbg(1)]]-> val where val implements Inspect
dbg x dbg x
x x

View file

@ -36,6 +36,7 @@ extern "C" {
) -> *mut c_void; ) -> *mut c_void;
pub fn roc_dealloc(ptr: *mut c_void, alignment: u32); pub fn roc_dealloc(ptr: *mut c_void, alignment: u32);
pub fn roc_panic(c_ptr: *mut c_void, tag_id: u32); pub fn roc_panic(c_ptr: *mut c_void, tag_id: u32);
pub fn roc_dbg(loc: *mut c_void, msg: *mut c_void);
pub fn roc_memset(dst: *mut c_void, c: i32, n: usize) -> *mut c_void; pub fn roc_memset(dst: *mut c_void, c: i32, n: usize) -> *mut c_void;
} }

View file

@ -32,18 +32,14 @@ pub unsafe extern "C" fn roc_dealloc(c_ptr: *mut c_void, _alignment: u32) {
#[cfg(test)] #[cfg(test)]
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn roc_panic(c_ptr: *mut c_void, tag_id: u32) { pub unsafe extern "C" fn roc_panic(msg: *mut roc_std::RocStr, _tag_id: u32) {
use std::ffi::CStr; panic!("roc_panic during test: {}", &*msg);
use std::os::raw::c_char; }
match tag_id { #[cfg(test)]
0 => { #[no_mangle]
let c_str = CStr::from_ptr(c_ptr as *const c_char); pub unsafe extern "C" fn roc_dbg(loc: *mut roc_std::RocStr, msg: *mut roc_std::RocStr) {
let string = c_str.to_str().unwrap(); eprintln!("[{}] {}", &*loc, &*msg);
panic!("roc_panic during test: {string}");
}
_ => todo!(),
}
} }
#[cfg(test)] #[cfg(test)]

View file

@ -44,13 +44,17 @@ export fn roc_dealloc(c_ptr: *anyopaque, alignment: u32) callconv(.C) void {
free(@as([*]align(Align) u8, @alignCast(@ptrCast(c_ptr)))); free(@as([*]align(Align) u8, @alignCast(@ptrCast(c_ptr))));
} }
export fn roc_panic(c_ptr: *anyopaque, tag_id: u32) callconv(.C) void { export fn roc_panic(msg: *RocStr, tag_id: u32) callconv(.C) void {
_ = tag_id; _ = tag_id;
const stderr = std.io.getStdErr().writer(); const stderr = std.io.getStdErr().writer();
const msg = @as([*:0]const u8, @ptrCast(c_ptr)); stderr.print("Application crashed with message\n\n {s}\n\nShutting down\n", .{msg.asSlice()}) catch unreachable;
stderr.print("Application crashed with message\n\n {s}\n\nShutting down\n", .{msg}) catch unreachable; std.process.exit(1);
std.process.exit(0); }
export fn roc_dbg(loc: *RocStr, msg: *RocStr) callconv(.C) void {
const stderr = std.io.getStdErr().writer();
stderr.print("[{s}] {s}\n", .{ loc.asSlice(), msg.asSlice() }) catch unreachable;
} }
export fn roc_memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void { export fn roc_memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void {

View file

@ -44,15 +44,19 @@ export fn roc_dealloc(c_ptr: *anyopaque, alignment: u32) callconv(.C) void {
free(@as([*]align(Align) u8, @alignCast(@ptrCast(c_ptr)))); free(@as([*]align(Align) u8, @alignCast(@ptrCast(c_ptr))));
} }
export fn roc_panic(c_ptr: *anyopaque, tag_id: u32) callconv(.C) void { export fn roc_panic(msg: *RocStr, tag_id: u32) callconv(.C) void {
_ = tag_id; _ = tag_id;
const stderr = std.io.getStdErr().writer(); const stderr = std.io.getStdErr().writer();
const msg = @as([*:0]const u8, @ptrCast(c_ptr)); stderr.print("Application crashed with message\n\n {s}\n\nShutting down\n", .{msg.asSlice()}) catch unreachable;
stderr.print("Application crashed with message\n\n {s}\n\nShutting down\n", .{msg}) catch unreachable;
std.process.exit(0); std.process.exit(0);
} }
export fn roc_dbg(loc: *RocStr, msg: *RocStr) callconv(.C) void {
const stderr = std.io.getStdErr().writer();
stderr.print("[{s}] {s}\n", .{ loc.asSlice(), msg.asSlice() }) catch unreachable;
}
export fn roc_memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void { export fn roc_memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void {
return memset(dst, value, size); return memset(dst, value, size);
} }

View file

@ -86,16 +86,22 @@ pub extern "C" fn rust_main() -> i32 {
} }
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn roc_panic(c_ptr: *mut c_void, tag_id: u32) { pub unsafe extern "C" fn roc_panic(msg: *mut RocStr, tag_id: u32) {
match tag_id { match tag_id {
0 => { 0 => {
let slice = CStr::from_ptr(c_ptr as *const c_char); eprintln!("Roc standard library hit a panic: {}", &*msg);
let string = slice.to_str().unwrap();
eprintln!("Roc hit a panic: {}", string);
std::process::exit(1);
} }
_ => todo!(), 1 => {
eprintln!("Application hit a panic: {}", &*msg);
}
_ => unreachable!(),
} }
std::process::exit(1);
}
#[no_mangle]
pub unsafe extern "C" fn roc_dbg(loc: *mut RocStr, msg: *mut RocStr) {
eprintln!("[{}] {}", &*loc, &*msg);
} }
#[no_mangle] #[no_mangle]