DzLox

:)
git clone https://git.sr.ht/~ashymad/DzLox
Log | Files | Refs | Submodules | LICENSE

commit 6883315460175834a896139a80400514706f150b
parent 669df913edb3924e356e2d4e6ec67a6cb1e38bdb
Author: Szymon Mikulicz <szymon.mikulicz@posteo.net>
Date:   Mon, 17 Aug 2026 23:16:05 +0200

Marking names

Diffstat:
Mzlox/src/compiler.zig | 2+-
Mzlox/src/gc.zig | 14++++++++++----
Mzlox/src/obj/function.zig | 8++++----
Mzlox/src/vm.zig | 18++++++++++++++----
4 files changed, 29 insertions(+), 13 deletions(-)

diff --git a/zlox/src/compiler.zig b/zlox/src/compiler.zig @@ -716,7 +716,7 @@ pub fn Compiler(size: comptime_int) type { self.consume(Token.LEFT_PAREN, "Expect '(' after 'switch'."); - self.emitObj(.Native, Obj.Native.Arg{ .name = "switch", .fun = vm_native.table }) catch return; + self.emitObj(.Native, Obj.Native.Arg{ .name = "internal::switch", .fun = vm_native.table }) catch return; var jumpOver = self.emitJump(OP.JUMP); const switchExpression = self.currentChunk().code.len; diff --git a/zlox/src/gc.zig b/zlox/src/gc.zig @@ -96,10 +96,8 @@ pub const GC = struct { pub fn mark(arg: anytype) void { const T = @TypeOf(arg); + switch (T) { - VM.Global => { - mark(arg.val); - }, Value => switch (arg) { .obj => |o| { mark(o); @@ -109,12 +107,20 @@ pub const GC = struct { *Obj => { dbg_print("Marking {any} at 0x{x}: {f}\n", .{ arg.type, @intFromPtr(arg), arg }); arg.fields.mark = true; + switch (arg.type) { + .Function => if ((arg.cast(.Function) catch unreachable).name.ptr()) |name| { + mark(name); + }, + else => {}, + } }, *const Obj => { dbg_print("Skipping const {any} at 0x{x}: {f}\n", .{ arg.type, @intFromPtr(arg), arg }); }, - else => if (Obj.isChild(T)) { + else => if (comptime Obj.isChild(T)) { mark(arg.cast()); + } else { + @compileError("Unable to mark " ++ @typeName(T)); }, } } diff --git a/zlox/src/obj/function.zig b/zlox/src/obj/function.zig @@ -17,7 +17,7 @@ pub fn Function(fields: anytype) type { obj: Super, arity: u8, chunk: Packed(*chunk.Chunk), - name: Packed(?*const String), + name: Packed(?*String), type: Type, upvalue_count: u8, @@ -27,7 +27,7 @@ pub fn Function(fields: anytype) type { .obj = Super.make(Self), .chunk = try Packed(*chunk.Chunk).create(allocator), .arity = 0, - .name = Packed(?*const String).init(null), + .name = Packed(?*String).init(null), .type = tp, .upvalue_count = 0, }; @@ -35,8 +35,8 @@ pub fn Function(fields: anytype) type { return self; } - pub fn set_name(self: *Self, name: *const String) void { - self.name = Packed(?*const String).init(name); + pub fn set_name(self: *Self, name: *String) void { + self.name = Packed(?*String).init(name); } pub fn cast(self: anytype) utils.copy_const(@TypeOf(self), *Super) { diff --git a/zlox/src/vm.zig b/zlox/src/vm.zig @@ -45,7 +45,7 @@ pub const VM = struct { } }; - const Globals = table.Table(*const Obj.String, Global, hash.hash_t(*const Obj.String), Obj.String.eql); + const Globals = table.Table(*Obj.String, Global, hash.hash_t(*Obj.String), Obj.String.eql); const CallFrame = struct { callee: *const Obj, @@ -64,14 +64,24 @@ pub const VM = struct { fn defineNative(self: *@This(), name: []const u8, arity_min: u8, arity_max: u8, fun: Obj.Native.Fn) !void { const nameObj = try self.objects.emplace(.String, &.{name}); - const funObj = try self.objects.emplace_cast(.Native, Obj.Native.Arg{ .fun = fun, .name = name, .arity_min = arity_min, .arity_max = arity_max }); + const funObj = try self.objects.emplace_cast(.Native, Obj.Native.Arg{ + .fun = fun, + .name = nameObj.slice(), + .arity_min = arity_min, + .arity_max = arity_max, + }); _ = try self.globals.set(nameObj, Global.make_con(Value.init(funObj))); } fn gc_callback(self_ptr: *anyopaque) void { const self: *@This() = @ptrCast(@alignCast(self_ptr)); - GC.markTable(self.globals); + self.globals.for_each({}, struct { + pub fn fun(name: *Obj.String, val: Global) void { + GC.mark(name); + GC.mark(val.val); + } + }.fun); } pub fn init(allocator: std.mem.Allocator, io: std.Io) !@This() { @@ -176,7 +186,7 @@ pub const VM = struct { return self.frame().chunk.constants.get(self.read_byte()) catch unreachable; } - fn read_string(self: *@This()) *const Obj.String { + fn read_string(self: *@This()) *Obj.String { return self.read_constant().obj.cast(.String) catch unreachable; }