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**
```zig
// --- ZLA ---
var zla: Zla = try .init();
var zla: Zla = try .init(allocator);
defer zla.deinit();
// --- EXEC FILE ---

View file

@ -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 ---