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

Update zig @panic calls to roc_panic for numeric errors #6062

Merged
merged 17 commits into from
Dec 5, 2023
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 14 additions & 13 deletions crates/compiler/builtins/bitcode/src/dec.zig
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,6 @@ pub const RocDec = extern struct {

if (answer.has_overflowed) {
roc_panic("Decimal addition overflowed!", 0);
unreachable;
} else {
return answer.value;
}
Expand Down Expand Up @@ -283,7 +282,6 @@ pub const RocDec = extern struct {

if (answer.has_overflowed) {
roc_panic("Decimal subtraction overflowed!", 0);
unreachable;
} else {
return answer.value;
}
Expand Down Expand Up @@ -347,7 +345,6 @@ pub const RocDec = extern struct {

if (answer.has_overflowed) {
roc_panic("Decimal multiplication overflowed!", 0);
unreachable;
} else {
return answer.value;
}
Expand All @@ -369,7 +366,7 @@ pub const RocDec = extern struct {

// (n / 0) is an error
if (denominator_i128 == 0) {
@panic("TODO runtime exception for dividing by 0!");
roc_panic("Decimal division by 0!", 0);
}

// If they're both negative, or if neither is negative, the final answer
Expand Down Expand Up @@ -397,7 +394,7 @@ pub const RocDec = extern struct {
if (denominator_i128 == one_point_zero_i128) {
return self;
} else {
@panic("TODO runtime exception for overflow when dividing!");
roc_panic("Decimal division overflow in numerator!", 0);
}
};
const numerator_u128 = @as(u128, @intCast(numerator_abs_i128));
Expand All @@ -410,7 +407,7 @@ pub const RocDec = extern struct {
if (numerator_i128 == one_point_zero_i128) {
return other;
} else {
@panic("TODO runtime exception for overflow when dividing!");
roc_panic("Decimal division overflow in denominator!", 0);
}
};
const denominator_u128 = @as(u128, @intCast(denominator_abs_i128));
Expand All @@ -422,7 +419,7 @@ pub const RocDec = extern struct {
if (answer.hi == 0 and answer.lo <= math.maxInt(i128)) {
unsigned_answer = @as(i128, @intCast(answer.lo));
} else {
@panic("TODO runtime exception for overflow when dividing!");
roc_panic("Decimal division overflow!", 0);
}

return RocDec{ .num = if (is_answer_negative) -unsigned_answer else unsigned_answer };
Expand Down Expand Up @@ -632,7 +629,7 @@ fn mul_and_decimalize(a: u128, b: u128) i128 {
const d = answer[0];

if (overflowed == 1) {
@panic("TODO runtime exception for overflow!");
roc_panic("Decimal multiplication overflow22!", 0);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
roc_panic("Decimal multiplication overflow22!", 0);
roc_panic("Decimal multiplication overflow!", 0);

}

// Final 512bit value is d, c, b, a
Expand Down Expand Up @@ -1208,7 +1205,7 @@ pub fn fromF64C(arg: f64) callconv(.C) i128 {
if (@call(.always_inline, RocDec.fromF64, .{arg})) |dec| {
return dec.num;
} else {
@panic("TODO runtime exception failing convert f64 to RocDec");
roc_panic("Decimal conversion from f64!", 0);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
roc_panic("Decimal conversion from f64!", 0);
roc_panic("Decimal conversion from f64 failed!", 0);

}
}

Expand All @@ -1217,7 +1214,7 @@ pub fn fromF32C(arg_f32: f32) callconv(.C) i128 {
if (@call(.always_inline, RocDec.fromF64, .{arg_f64})) |dec| {
return dec.num;
} else {
@panic("TODO runtime exception failing convert f64 to RocDec");
roc_panic("Decimal conversion from f32!", 0);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
roc_panic("Decimal conversion from f32!", 0);
roc_panic("Decimal conversion from f32 failed!", 0);

}
}

Expand All @@ -1232,7 +1229,7 @@ pub fn exportFromInt(comptime T: type, comptime name: []const u8) void {

const answer = @mulWithOverflow(this, RocDec.one_point_zero_i128);
if (answer[1] == 1) {
@panic("TODO runtime exception failing convert integer to RocDec");
roc_panic("Decimal conversion from integer!", 0);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
roc_panic("Decimal conversion from integer!", 0);
roc_panic("Decimal conversion from integer failed!", 0);

} else {
return answer[0];
}
Expand All @@ -1258,11 +1255,15 @@ pub fn neqC(arg1: RocDec, arg2: RocDec) callconv(.C) bool {
}

pub fn negateC(arg: RocDec) callconv(.C) i128 {
return if (@call(.always_inline, RocDec.negate, .{arg})) |dec| dec.num else @panic("TODO overflow for negating RocDec");
return if (@call(.always_inline, RocDec.negate, .{arg})) |dec| dec.num else {
roc_panic("Decimal negation overflow!", 0);
};
}

pub fn absC(arg: RocDec) callconv(.C) i128 {
const result = @call(.always_inline, RocDec.abs, .{arg}) catch @panic("TODO overflow for calling absolute value on RocDec");
const result = @call(.always_inline, RocDec.abs, .{arg}) catch {
roc_panic("Decimal absolute value overflow!", 0);
};
return result.num;
}

Expand Down
7 changes: 3 additions & 4 deletions crates/compiler/builtins/bitcode/src/num.zig
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,9 @@ pub fn exportCeiling(comptime F: type, comptime T: type, comptime name: []const
pub fn exportDivCeil(comptime T: type, comptime name: []const u8) void {
comptime var f = struct {
fn func(a: T, b: T) callconv(.C) T {
return math.divCeil(T, a, b) catch @panic("TODO runtime exception for dividing by 0!");
return math.divCeil(T, a, b) catch {
roc_panic("integer division by 0!", 0);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be worth trying to convert these all back to Integer. Probably will require update some tests. I assume most in cargo test-gen-llvm

Copy link
Sponsor Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ill give that a shot

Copy link
Sponsor Contributor Author

@JRMurr JRMurr Nov 29, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did a bunch of find replace and made all the panics i found capitalize Integer

};
}
}.func;
@export(f, .{ .name = name ++ @typeName(T), .linkage = .Strong });
Expand Down Expand Up @@ -380,7 +382,6 @@ pub fn exportAddOrPanic(comptime T: type, comptime name: []const u8) void {
const result = addWithOverflow(T, self, other);
if (result.has_overflowed) {
roc_panic("integer addition overflowed!", 0);
unreachable;
} else {
return result.value;
}
Expand Down Expand Up @@ -438,7 +439,6 @@ pub fn exportSubOrPanic(comptime T: type, comptime name: []const u8) void {
const result = subWithOverflow(T, self, other);
if (result.has_overflowed) {
roc_panic("integer subtraction overflowed!", 0);
unreachable;
} else {
return result.value;
}
Expand Down Expand Up @@ -623,7 +623,6 @@ pub fn exportMulOrPanic(comptime T: type, comptime W: type, comptime name: []con
const result = @call(.always_inline, mulWithOverflow, .{ T, W, self, other });
if (result.has_overflowed) {
roc_panic("integer multiplication overflowed!", 0);
unreachable;
} else {
return result.value;
}
Expand Down
6 changes: 3 additions & 3 deletions crates/compiler/builtins/bitcode/src/panic.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ const std = @import("std");
const RocStr = @import("str.zig").RocStr;

// Signals to the host that the program has panicked
extern fn roc_panic(msg: *const RocStr, tag_id: u32) callconv(.C) void;
extern fn roc_panic(msg: *const RocStr, tag_id: u32) callconv(.C) noreturn;

pub fn panic_help(msg: []const u8, tag_id: u32) void {
pub fn panic_help(msg: []const u8, tag_id: u32) noreturn {
var str = RocStr.init(msg.ptr, msg.len);
roc_panic(&str, tag_id);
}

// must export this explicitly because right now it is not used from zig code
pub fn panic(msg: *const RocStr, alignment: u32) callconv(.C) void {
pub fn panic(msg: *const RocStr, alignment: u32) callconv(.C) noreturn {
return roc_panic(msg, alignment);
}
Comment on lines +5 to 15
Copy link
Sponsor Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was having a weird error in CI were valgrind was crashing but was not happening locally

My gut feeling is that us adding unreachable after a roc_panic call is whats causing the issue.

Looks like unreachable is undefined behavior when compiled with RelaseFast https://ziglang.org/documentation/master/#try which i think we do

This return type lets you do

if (some_cond) {
    roc_panic(...)
} else {
    return foo
}

without zig type errors

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So glad this worked. Thanks for the find

20 changes: 20 additions & 0 deletions crates/compiler/test_gen/src/gen_num.rs
Original file line number Diff line number Diff line change
Expand Up @@ -799,6 +799,26 @@ fn gen_div_checked_by_zero_dec() {
);
}

#[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
#[should_panic(expected = r#"Roc failed with message: "Decimal division by 0!"#)]
fn gen_div_dec_by_zero() {
assert_evals_to!("1dec / 0", RocDec::from_str_to_i128_unsafe("-1"), i128);
}

#[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
#[should_panic(expected = r#"Roc failed with message: "integer division by 0!"#)]
fn gen_div_ceil_by_zero() {
assert_evals_to!(
r#"
Num.divCeil 5 0 == 0
"#,
false,
bool
);
}

#[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-dev", feature = "gen-wasm"))]
fn gen_int_eq() {
Expand Down
2 changes: 1 addition & 1 deletion crates/lang_srv/debug_server.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/bin/bash
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like you have a number of unrelated changes in this file and below. Probably don't want those here?

Copy link
Sponsor Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ahh yea this file is not related to this branch. I can remove

the readme/gitignore updates were useful when i was testing the wasm repl so i figured those were fine to leave in but can move out

#!/usr/bin/env bash

SCRIPT_DIR=$(cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd)
${SCRIPT_DIR}/../../target/debug/roc_ls "$@" 2> /tmp/roc_ls.err
5 changes: 3 additions & 2 deletions crates/repl_wasm/README.md
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still a bit confused about the random repl and flake changes, but otherwise, this pr looks great.

Copy link
Sponsor Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The docs here were out of date, linking to the public dir did not seem to hot reload for me

Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,14 @@ crates/repl_wasm/build-www.sh
### 2. Make symlinks to the generated Wasm and JS

```bash
cd www/public
mkdir -p www/public/repl
cd www/public/repl
ln -s ../../../crates/repl_wasm/build/roc_repl_wasm_bg.wasm
ln -s ../../../crates/repl_wasm/build/roc_repl_wasm.js
```
These symlinks are ignored by Git.

> This is a bit different from the production build, where we copy all the files to `www/build/`. But for development, it's convenient to have just one copy of files like `www/public/repl.js`. You can make changes, reload your browser to see them, and commit them to Git, without getting mixed up between different copies of the same file.
> This is a bit different from the production build, where we copy all the files to `www/build/`. But for development, it's convenient to have just one copy of files like `www/public/repl/repl.js`. You can make changes, reload your browser to see them, and commit them to Git, without getting mixed up between different copies of the same file.

### 3. Run a local HTTP server

Expand Down
3 changes: 2 additions & 1 deletion flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@
wasm-pack # for repl_wasm
jq # used in several bash scripts
cargo-nextest # used to give more info for segfaults for gen tests
zls # zig language server
]);

aliases = ''
Expand Down Expand Up @@ -160,7 +161,7 @@
# You can build this package (the roc CLI) with the `nix build` command.
packages = {
default = rocBuild.roc-cli;

# all rust crates in workspace.members of Cargo.toml
full = rocBuild.roc-full;
# only the CLI crate = executable provided in nightly releases
Expand Down
2 changes: 2 additions & 0 deletions www/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# ignore a symlink to the wasm repl code
public/repl