lite-xl/src/arena_allocator.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);
}