From 795d1c47a772ec46b34a52e2adf79c323088e55d Mon Sep 17 00:00:00 2001 From: abux Date: Tue, 28 Jul 2026 11:17:37 +0100 Subject: [PATCH] Allow for use of custom allocators for lua --- README.md | 2 +- src/zla.zig | 83 +++++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 75 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 5af2669..4e70e8a 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ **Simple** ```zig // --- ZLA --- -var zla: Zla = try .init(); +var zla: Zla = try .init(allocator); defer zla.deinit(); // --- EXEC FILE --- diff --git a/src/zla.zig b/src/zla.zig index 153063c..eee76c4 100644 --- a/src/zla.zig +++ b/src/zla.zig @@ -7,11 +7,57 @@ const std = @import("std"); const lua = @import("luajit"); const Self = @This(); +/// ---------------------------------------------------- +/// ---------------------------------------------------- +const AllocatorUD = struct { + alloc: std.mem.Allocator, +}; + +/// ---------------------------------------------------- +/// ---------------------------------------------------- +fn luaAlloc( + ud: ?*anyopaque, + ptr: ?*anyopaque, + osize: usize, + nsize: usize, +) callconv(.c) ?*anyopaque { + // --- # --- + const alloc = @as( + *AllocatorUD, + @ptrCast(@alignCast(ud)), + ).alloc; + + // --- # --- + if (nsize == 0) { + if (ptr) |p| alloc.free(@as([*]u8, @ptrCast(p))[0..osize]); + return null; + } + + // --- # --- + if (ptr) |p| { + return (alloc.realloc(@as([*]u8, @ptrCast(p))[0..osize], nsize) catch { + std.debug.print("[LUA_ERROR] Failed to reallocate\n", .{}); + return null; + }).ptr; + } + + // --- # --- + return (alloc.alloc( + u8, + nsize, + ) catch { + std.debug.print("[LUA_ERROR] Failed to allocate\n", .{}); + return null; + }).ptr; +} + // // FIELDS // state: *lua.lua_State, +alloc: std.mem.Allocator, +alloc_ud: *AllocatorUD, err: ?[*:0]const u8 = null, // @@ -20,16 +66,34 @@ err: ?[*:0]const u8 = null, /// ---------------------------------------------------- /// ---------------------------------------------------- -pub fn init() !Self { - const state = lua.luaL_newstate() orelse return error.LuaStateFailed; - lua.luaL_openlibs(state); - return .{ .state = state }; +pub fn init(alloc: std.mem.Allocator) !Self { + // --- CREATE NEW ALLOCATOR --- + const ud = try alloc.create(AllocatorUD); + ud.* = .{ .alloc = alloc }; + + // --- NEW LUA STATE --- + const state = lua.lua_newstate(luaAlloc, ud) orelse { + alloc.destroy(ud); + return error.LuaStateFailed; + }; + + // --- OPEN LIBS --- + lua.luaL_openlibs( + state, + ); + + return .{ + .state = state, + .alloc = alloc, + .alloc_ud = ud, + }; } /// ---------------------------------------------------- /// ---------------------------------------------------- pub fn deinit(self: *Self) void { lua.lua_close(self.state); + self.alloc.destroy(self.alloc_ud); } // @@ -313,7 +377,7 @@ pub fn register( const Wrapper = struct { fn luaFunc(state: ?*lua.lua_State) callconv(.c) c_int { - var zl = Self{ .state = state.? }; + var zl = Self{ .state = state.?, .alloc = undefined, .alloc_ud = undefined }; const args: std.meta.ArgsTuple(@TypeOf(func)) = args: { var a: std.meta.ArgsTuple(@TypeOf(func)) = undefined; @@ -350,7 +414,7 @@ pub fn registerWithCtx( // --- # --- const Wrapper = struct { fn luaFunc(state: ?*lua.lua_State) callconv(.c) c_int { - var zl = Self{ .state = state.? }; + var zl = Self{ .state = state.?, .alloc = undefined, .alloc_ud = undefined }; // --- # --- const ctx_ptr: CtxType = @ptrCast(@alignCast( @@ -444,7 +508,7 @@ pub fn registerMethods( const Wrapper = struct { fn luaFunc(state: ?*lua.lua_State) callconv(.c) c_int { // --- # --- - var zl = Self{ .state = state.? }; + var zl = Self{ .state = state.?, .alloc = undefined, .alloc_ud = undefined }; const args: std.meta.ArgsTuple(@TypeOf(func)) = args: { // --- # --- var a: std.meta.ArgsTuple(@TypeOf(func)) = undefined; @@ -461,6 +525,7 @@ pub fn registerMethods( // --- # --- break :args a; }; + // --- # --- const ret = @call(.auto, func, args); if (Return == void) return 0; @@ -555,7 +620,7 @@ test "exec" { std.debug.print("\x1b[34m<--- EXEC --->\x1b[0m\n", .{}); // --- ZLA --- - var zla: Self = try .init(); + var zla: Self = try .init(std.testing.allocator); defer zla.deinit(); // --- EXEC FILE --- @@ -576,7 +641,7 @@ test "userdata" { std.debug.print("\x1b[34m<--- USERDATA --->\x1b[0m\n", .{}); // --- ZLA --- - var zla: Self = try .init(); + var zla: Self = try .init(std.testing.allocator); defer zla.deinit(); // --- APP ---