Skip to content

Commit b6a596c

Browse files
MatteoMerclaude
andcommitted
fix: replace silent failures with loud errors in lookup tables and CLI
Lookup tables: - Replace 16 placeholder F.zero() returns with @Panic for unimplemented MLE cases (UpperWord, Pow2W, VirtualROTR, VirtualXORROT*, etc.) - Replace else => F.zero() / else => 0 fallbacks with panics that report the unsupported table index CLI/commands: - parseHexInput: report invalid hex bytes instead of silently treating them as 0 - run.zig: report emulator step errors instead of silent catch break - run.zig: report register read errors instead of silent catch 0 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 4366679 commit b6a596c

3 files changed

Lines changed: 32 additions & 21 deletions

File tree

src/cli/args.zig

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ pub fn parseCommand(arg: []const u8) Command {
7878
}
7979

8080
/// Parse hex string (with optional 0x prefix) into bytes.
81+
/// Returns null if allocation fails or the hex string contains invalid characters.
8182
pub fn parseHexInput(allocator: std.mem.Allocator, hex: []const u8) ?[]u8 {
8283
var clean_hex = hex;
8384
if (std.mem.startsWith(u8, hex, "0x") or std.mem.startsWith(u8, hex, "0X")) {
@@ -89,7 +90,11 @@ pub fn parseHexInput(allocator: std.mem.Allocator, hex: []const u8) ?[]u8 {
8990
while (i < buf_len) : (i += 1) {
9091
const start = i * 2;
9192
const end = @min(start + 2, clean_hex.len);
92-
buf[i] = std.fmt.parseInt(u8, clean_hex[start..end], 16) catch 0;
93+
buf[i] = std.fmt.parseInt(u8, clean_hex[start..end], 16) catch {
94+
std.debug.print("Error: invalid hex byte '{s}' in --input-hex\n", .{clean_hex[start..end]});
95+
allocator.free(buf);
96+
return null;
97+
};
9398
}
9499
return buf;
95100
}

src/commands/run.zig

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,10 @@ pub fn runEmulator(allocator: std.mem.Allocator, elf_path: []const u8, show_regs
4646
std.debug.print("\n", .{});
4747
var running = true;
4848
while (running) {
49-
running = emulator.step() catch break;
49+
running = emulator.step() catch |err| {
50+
std.debug.print("Emulator error during trace: {}\n", .{err});
51+
break;
52+
};
5053
}
5154

5255
const max_steps = max_trace_steps orelse 100;
@@ -149,7 +152,10 @@ pub fn runEmulator(allocator: std.mem.Allocator, elf_path: []const u8, show_regs
149152
std.debug.print("\nFinal Register State:\n", .{});
150153
var reg_i: u8 = 0;
151154
while (reg_i < 32) : (reg_i += 1) {
152-
const val = emulator.registers.read(reg_i) catch 0;
155+
const val = emulator.registers.read(reg_i) catch |err| {
156+
std.debug.print(" x{d:0>2}: error reading register: {}\n", .{ reg_i, err });
157+
continue;
158+
};
153159
if (val != 0) {
154160
const reg_name = switch (reg_i) {
155161
0 => "zero",

src/zkvm/lookup_table/mod.zig

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1361,7 +1361,7 @@ pub fn LookupTable(comptime F: type, comptime XLEN: comptime_int) type {
13611361
10 => SignedLessThan.evaluateMLE(r),
13621362
11 => UnsignedLessThan.evaluateMLE(r),
13631363
12 => Movsign.evaluateMLE(r),
1364-
13 => F.zero(), // UpperWord - TODO
1364+
13 => @panic("UpperWord MLE not implemented"),
13651365
14 => UnsignedLessThanEqual.evaluateMLE(r),
13661366
// 15 was ValidSignedRemainder (removed in PR #1355)
13671367
15 => ValidUnsignedRemainder.evaluateMLE(r),
@@ -1371,25 +1371,25 @@ pub fn LookupTable(comptime F: type, comptime XLEN: comptime_int) type {
13711371
19 => LowerHalfWord.evaluateMLE(r),
13721372
20 => SignExtendHalfWord.evaluateMLE(r),
13731373
21 => Pow2.evaluateMLE(r),
1374-
22 => F.zero(), // Pow2W - TODO
1374+
22 => @panic("Pow2W MLE not implemented"),
13751375
23 => ShiftRightBitmask.evaluateMLE(r),
1376-
24 => F.zero(), // VirtualRev8W - TODO
1376+
24 => @panic("VirtualRev8W MLE not implemented"),
13771377
25 => VirtualSRL.evaluateMLE(r),
13781378
26 => VirtualSRA.evaluateMLE(r),
1379-
27 => F.zero(), // VirtualROTR - TODO
1380-
28 => F.zero(), // VirtualROTRW - TODO
1381-
29 => F.zero(), // VirtualChangeDivisor - TODO
1382-
30 => F.zero(), // VirtualChangeDivisorW - TODO
1383-
31 => F.zero(), // MulUNoOverflow - TODO
1384-
32 => F.zero(), // VirtualXORROT32 - TODO
1385-
33 => F.zero(), // VirtualXORROT24 - TODO
1386-
34 => F.zero(), // VirtualXORROT16 - TODO
1387-
35 => F.zero(), // VirtualXORROT63 - TODO
1388-
36 => F.zero(), // VirtualXORROTW16 - TODO
1389-
37 => F.zero(), // VirtualXORROTW12 - TODO
1390-
38 => F.zero(), // VirtualXORROTW8 - TODO
1391-
39 => F.zero(), // VirtualXORROTW7 - TODO
1392-
else => F.zero(),
1379+
27 => @panic("VirtualROTR MLE not implemented"),
1380+
28 => @panic("VirtualROTRW MLE not implemented"),
1381+
29 => @panic("VirtualChangeDivisor MLE not implemented"),
1382+
30 => @panic("VirtualChangeDivisorW MLE not implemented"),
1383+
31 => @panic("MulUNoOverflow MLE not implemented"),
1384+
32 => @panic("VirtualXORROT32 MLE not implemented"),
1385+
33 => @panic("VirtualXORROT24 MLE not implemented"),
1386+
34 => @panic("VirtualXORROT16 MLE not implemented"),
1387+
35 => @panic("VirtualXORROT63 MLE not implemented"),
1388+
36 => @panic("VirtualXORROTW16 MLE not implemented"),
1389+
37 => @panic("VirtualXORROTW12 MLE not implemented"),
1390+
38 => @panic("VirtualXORROTW8 MLE not implemented"),
1391+
39 => @panic("VirtualXORROTW7 MLE not implemented"),
1392+
else => std.debug.panic("unsupported lookup table index: {}", .{table_index}),
13931393
};
13941394
}
13951395

@@ -1495,7 +1495,7 @@ pub fn LookupTable(comptime F: type, comptime XLEN: comptime_int) type {
14951495
else
14961496
@bitCast(@as(i64, divisor_i32));
14971497
},
1498-
else => 0, // Unimplemented tables return 0
1498+
else => std.debug.panic("unsupported lookup table index for materializeTableEntry: {}", .{table_index}),
14991499
};
15001500
}
15011501

0 commit comments

Comments
 (0)