52 lines
1.5 KiB
C
52 lines
1.5 KiB
C
#include "arena_allocator.h"
|
|
|
|
#include <string.h>
|
|
#include <lauxlib.h>
|
|
|
|
struct lxl_arena {
|
|
lua_State *L;
|
|
int ref;
|
|
};
|
|
|
|
lxl_arena *lxl_arena_init(lua_State *L) {
|
|
lua_newtable(L);
|
|
lxl_arena *arena = lua_newuserdata(L, sizeof(lxl_arena));
|
|
arena->L = L; arena->ref = lua_gettop(L)-1;
|
|
lua_rawseti(L, -2, 1);
|
|
return arena;
|
|
}
|
|
|
|
void *lxl_arena_malloc(lxl_arena *arena, size_t size) {
|
|
if (!arena || !arena->L) return NULL;
|
|
if (!lua_istable(arena->L, arena->ref)) luaL_error(arena->L, "invalid arena reference");
|
|
void *data = lua_newuserdata(arena->L, size);
|
|
lua_pushlightuserdata(arena->L, data);
|
|
lua_pushvalue(arena->L, -2);
|
|
lua_settable(arena->L, arena->ref);
|
|
lua_pop(arena->L, 1);
|
|
return data;
|
|
}
|
|
|
|
void *lxl_arena_zero(lxl_arena *arena, size_t size) {
|
|
void *v = lxl_arena_malloc(arena, size);
|
|
return v ? memset(v, 0, size) : NULL;
|
|
}
|
|
|
|
char *lxl_arena_strdup(lxl_arena *arena, const char *str) {
|
|
if (!str) return NULL;
|
|
return lxl_arena_copy(arena, (void *) str, (strlen(str) + 1) * sizeof(char));
|
|
}
|
|
|
|
char *lxl_arena_copy(lxl_arena *arena, void *ptr, size_t len) {
|
|
if (!ptr) return NULL;
|
|
char *output = lxl_arena_malloc(arena, sizeof(char) * len);
|
|
return output ? memcpy(output, ptr, len) : NULL;
|
|
}
|
|
|
|
void lxl_arena_free(lxl_arena *arena, void *ptr) {
|
|
if (!arena || !arena->L || !ptr) return;
|
|
if (!lua_istable(arena->L, arena->ref)) luaL_error(arena->L, "invalid arena reference");
|
|
lua_pushlightuserdata(arena->L, ptr);
|
|
lua_pushnil(arena->L);
|
|
lua_settable(arena->L, arena->ref);
|
|
} |