commit 02a6abb8b245952640a4f8ec30502ff45eca371f
parent fbecd2575e66d296f3e940667efcff78e85c1ca2
Author: Szymon Mikulicz <szymon.mikulicz@posteo.net>
Date: Wed, 9 Sep 2026 18:04:19 +0200
Optimize method getting
Diffstat:
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);
}
};