DzLox

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

commit 02a6abb8b245952640a4f8ec30502ff45eca371f
parent fbecd2575e66d296f3e940667efcff78e85c1ca2
Author: Szymon Mikulicz <szymon.mikulicz@posteo.net>
Date:   Wed,  9 Sep 2026 18:04:19 +0200

Optimize method getting

Diffstat:
Mzlox/src/gc.zig | 6++++++
Mzlox/src/obj::instance.zig | 47+++++++++++++++++++++++++++--------------------
2 files changed, 33 insertions(+), 20 deletions(-)

diff --git a/zlox/src/gc.zig b/zlox/src/gc.zig @@ -124,6 +124,12 @@ pub const GC = struct { s.mark("i", val); } }.fun); + obj.bound.ptr().for_each(self, struct { + pub fn fun(s: *Self, key: Obj.Class.Methods.Key, val: Obj.Class.Methods.Value) void { + s.mark("i", key); + s.mark("i", val); + } + }.fun); }, *Obj.Class => { obj.methods.ptr().for_each(self, struct { diff --git a/zlox/src/obj::instance.zig b/zlox/src/obj::instance.zig @@ -23,6 +23,7 @@ pub fn Instance(fields: anytype) type { obj: Super, cls: Packed(*Super.Class), fields: Packed(*Fields), + bound: Packed(*Super.Class.Methods), pub fn init(cls: Arg, allocator: std.mem.Allocator) Error!*Self { const self: *Self = try allocator.create(Self); @@ -30,31 +31,36 @@ pub fn Instance(fields: anytype) type { .obj = Super.make(Self), .cls = Packed(*Super.Class).init(cls), .fields = try Packed(*Self.Fields).create(allocator), + .bound = try Packed(*Super.Class.Methods).create(allocator), }; return self; } pub fn method(self: *Self, gc: *GC, name: *Super.String) !*Super.Function { - const met = try self.cls.ptr().methods.ptr().get(name); - const fun = try gc.emplace(.Function, .{ - .type = .Method, - .chunk = met.chunk.ptr(), - .arity = met.arity, - .upvalues = @intCast(met.upvalues.len() + 1), - }); - - var val = Value.init(self.cast()); - const len = fun.upvalues.len(); - if (len > 1) - @memcpy(fun.upvalues.ptr()[0 .. len - 1], met.upvalues.ptr()); - - fun.upvalues.ptr()[len - 1] = try gc.emplace(.Upvalue, .{ - .val = &val, - .slot = 0, - .closed = true, - }); - - return fun; + return self.bound.ptr().get(name) catch blk: { + const met = try self.cls.ptr().methods.ptr().get(name); + const fun = try gc.emplace(.Function, .{ + .type = .Method, + .chunk = met.chunk.ptr(), + .arity = met.arity, + .upvalues = @intCast(met.upvalues.len() + 1), + }); + + var val = Value.init(self.cast()); + const len = fun.upvalues.len(); + if (len > 1) + @memcpy(fun.upvalues.ptr()[0 .. len - 1], met.upvalues.ptr()); + + fun.upvalues.ptr()[len - 1] = try gc.emplace(.Upvalue, .{ + .val = &val, + .slot = 0, + .closed = true, + }); + + _ = try self.bound.ptr().set(name, fun); + + break :blk fun; + }; } pub fn cast(self: anytype) utils.copy_const(@TypeOf(self), *Super) { @@ -71,6 +77,7 @@ pub fn Instance(fields: anytype) type { pub fn free(self: *const Self, allocator: std.mem.Allocator) void { self.fields.destroy(allocator); + self.bound.destroy(allocator); allocator.destroy(self); } };