diff --git a/crates/haku2/src/render.zig b/crates/haku2/src/render.zig index 7f6c94e..08e2de4 100644 --- a/crates/haku2/src/render.zig +++ b/crates/haku2/src/render.zig @@ -19,6 +19,7 @@ fn renderRec(vm: *Vm, canvas: *Canvas, val: Value, depth: usize, max_depth: usiz .{max_depth}, ); } + if (val == .nil) return; if (val != .ref) return notAScribble(vm, val); switch (val.ref.*) { diff --git a/crates/haku2/src/value.zig b/crates/haku2/src/value.zig index 2de5d2e..d1498ff 100644 --- a/crates/haku2/src/value.zig +++ b/crates/haku2/src/value.zig @@ -146,8 +146,12 @@ pub const Closure = struct { param_count: u8, impl: Impl, - pub fn bytecodePtr(c: *const Closure, pc: usize) [*]const u8 { - return c.impl.bytecode.chunk.bytecode[c.impl.bytecode.start + pc ..].ptr; + pub fn globalBytecodePtr(c: *const Closure, pc: usize) [*]const u8 { + return c.impl.bytecode.chunk.bytecode[pc..].ptr; + } + + pub fn relBytecodePtr(c: *const Closure, pc: usize) [*]const u8 { + return c.globalBytecodePtr(c.impl.bytecode.start + pc); } pub fn programCounter(c: *const Closure, ip: [*]const u8) u16 { diff --git a/crates/haku2/src/vm.zig b/crates/haku2/src/vm.zig index d5b8d86..9f90953 100644 --- a/crates/haku2/src/vm.zig +++ b/crates/haku2/src/vm.zig @@ -266,8 +266,10 @@ pub fn run( // system functions should be able to call themselves (like: map (range 1 10) sin) debug.assert(init_closure.impl == .bytecode); + log.debug("BYTECODE {any}", .{init_closure.impl.bytecode.chunk.bytecode}); + var closure = init_closure; - var ip: [*]const u8 = closure.bytecodePtr(0); + var ip: [*]const u8 = closure.relBytecodePtr(0); var bottom = init_bottom; var fuel = vm.fuel; @@ -391,7 +393,7 @@ pub fn run( const name = ip[0..name_len]; ip += name_len; const body = ip; - ip = closure.bytecodePtr(then); + ip = closure.globalBytecodePtr(then); const local_count = read(u8, &ip); const capture_count = read(u8, &ip); @@ -418,7 +420,7 @@ pub fn run( .param_count = param_count, .impl = .{ .bytecode = .{ .chunk = closure.impl.bytecode.chunk, - .start = @truncate(body - closure.bytecodePtr(0)), + .start = @truncate(body - closure.relBytecodePtr(0)), .local_count = local_count, .captures = captures, } }, @@ -433,7 +435,8 @@ pub fn run( .jump => { const offset = read(u16, &ip); try vm.consumeFuel(&fuel, 1); - ip = closure.bytecodePtr(offset); + log.debug("JUMP {}", .{offset}); + ip = closure.globalBytecodePtr(offset); continue :next vm.readOpcode(&ip); }, @@ -442,7 +445,10 @@ pub fn run( try vm.consumeFuel(&fuel, 1); const condition = try vm.pop(); if (!condition.isTruthy()) { - ip = closure.bytecodePtr(offset); + log.debug("CJUMP {} JUMPED", .{offset}); + ip = closure.globalBytecodePtr(offset); + } else { + log.debug("CJUMP {} SKIPPED", .{offset}); } continue :next vm.readOpcode(&ip); }, @@ -508,7 +514,7 @@ pub fn run( try vm.validateBytecode(overflow == 0, "not enough values on the stack for arguments", .{}); closure = called_closure; - ip = closure.bytecodePtr(0); + ip = closure.relBytecodePtr(0); bottom = new_bottom; // pushCall before setting vm.closure and vm.ip, such that stack overflow errors are diff --git a/static/index.css b/static/index.css index 40fc17d..4e27b08 100644 --- a/static/index.css +++ b/static/index.css @@ -546,6 +546,7 @@ rkgk-brush-editor { & > .errors { margin: 0; + padding: 4px; color: var(--color-error); white-space: pre-wrap;