Allow for use of custom allocators for lua

This commit is contained in:
abux 2026-07-28 11:17:37 +01:00
parent c082ff719b
commit 795d1c47a7
2 changed files with 75 additions and 10 deletions

View file

@ -1,7 +1,7 @@
**Simple** **Simple**
```zig ```zig
// --- ZLA --- // --- ZLA ---
var zla: Zla = try .init(); var zla: Zla = try .init(allocator);
defer zla.deinit(); defer zla.deinit();
// --- EXEC FILE --- // --- EXEC FILE ---

View file

@ -7,11 +7,57 @@ const std = @import("std");
const lua = @import("luajit"); const lua = @import("luajit");
const Self = @This(); 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 // FIELDS
// //
state: *lua.lua_State, state: *lua.lua_State,
alloc: std.mem.Allocator,
alloc_ud: *AllocatorUD,
err: ?[*:0]const u8 = null, err: ?[*:0]const u8 = null,
// //
@ -20,16 +66,34 @@ err: ?[*:0]const u8 = null,
/// ---------------------------------------------------- /// ----------------------------------------------------
/// ---------------------------------------------------- /// ----------------------------------------------------
pub fn init() !Self { pub fn init(alloc: std.mem.Allocator) !Self {
const state = lua.luaL_newstate() orelse return error.LuaStateFailed; // --- CREATE NEW ALLOCATOR ---
lua.luaL_openlibs(state); const ud = try alloc.create(AllocatorUD);
return .{ .state = state }; 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 { pub fn deinit(self: *Self) void {
lua.lua_close(self.state); lua.lua_close(self.state);
self.alloc.destroy(self.alloc_ud);
} }
// //
@ -313,7 +377,7 @@ pub fn register(
const Wrapper = struct { const Wrapper = struct {
fn luaFunc(state: ?*lua.lua_State) callconv(.c) c_int { 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: { const args: std.meta.ArgsTuple(@TypeOf(func)) = args: {
var a: std.meta.ArgsTuple(@TypeOf(func)) = undefined; var a: std.meta.ArgsTuple(@TypeOf(func)) = undefined;
@ -350,7 +414,7 @@ pub fn registerWithCtx(
// --- # --- // --- # ---
const Wrapper = struct { const Wrapper = struct {
fn luaFunc(state: ?*lua.lua_State) callconv(.c) c_int { 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( const ctx_ptr: CtxType = @ptrCast(@alignCast(
@ -444,7 +508,7 @@ pub fn registerMethods(
const Wrapper = struct { const Wrapper = struct {
fn luaFunc(state: ?*lua.lua_State) callconv(.c) c_int { 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: { const args: std.meta.ArgsTuple(@TypeOf(func)) = args: {
// --- # --- // --- # ---
var a: std.meta.ArgsTuple(@TypeOf(func)) = undefined; var a: std.meta.ArgsTuple(@TypeOf(func)) = undefined;
@ -461,6 +525,7 @@ pub fn registerMethods(
// --- # --- // --- # ---
break :args a; break :args a;
}; };
// --- # --- // --- # ---
const ret = @call(.auto, func, args); const ret = @call(.auto, func, args);
if (Return == void) return 0; if (Return == void) return 0;
@ -555,7 +620,7 @@ test "exec" {
std.debug.print("\x1b[34m<--- EXEC --->\x1b[0m\n", .{}); std.debug.print("\x1b[34m<--- EXEC --->\x1b[0m\n", .{});
// --- ZLA --- // --- ZLA ---
var zla: Self = try .init(); var zla: Self = try .init(std.testing.allocator);
defer zla.deinit(); defer zla.deinit();
// --- EXEC FILE --- // --- EXEC FILE ---
@ -576,7 +641,7 @@ test "userdata" {
std.debug.print("\x1b[34m<--- USERDATA --->\x1b[0m\n", .{}); std.debug.print("\x1b[34m<--- USERDATA --->\x1b[0m\n", .{});
// --- ZLA --- // --- ZLA ---
var zla: Self = try .init(); var zla: Self = try .init(std.testing.allocator);
defer zla.deinit(); defer zla.deinit();
// --- APP --- // --- APP ---