slot based allocator for lua, usage of lua_createtable
This commit is contained in:
parent
46e077ba63
commit
e8b02570a2
@ -8,6 +8,9 @@ with open(sys.argv[1], 'r') if sys.argv[1] != "-" else sys.stdin as f:
|
||||
api = json.loads(api_source)
|
||||
|
||||
|
||||
# TODO: use lua_to--x functions for defaults, so that fewer function calls are made
|
||||
# TODO: use lua_createtable for preallocation
|
||||
|
||||
def default(parameter):
|
||||
basetype = parameter["type"].rsplit(' *', 1)[0]
|
||||
if parameter["type"] == "float":
|
||||
@ -32,7 +35,7 @@ def default(parameter):
|
||||
|
||||
|
||||
def to_table(typedesc, variable, indent = 0):
|
||||
binding = ' ' * indent + "lua_newtable(L);\n"
|
||||
binding = ' ' * indent + "lua_createtable(L, 0, %i);\n" % len(typedesc["fields"])
|
||||
for field in typedesc["fields"]:
|
||||
if field["type"] == "float":
|
||||
binding += ' ' * indent + "lua_pushnumber(L, (double)(%s));\n" % (variable + ".%s" % field["name"])
|
||||
@ -48,7 +51,8 @@ def to_table(typedesc, variable, indent = 0):
|
||||
|
||||
|
||||
print('#include "twn_game_api.h"\n')
|
||||
print('#define STB_DS_IMPLEMENTATION') # TODO: reuse implementation from the engine
|
||||
# TODO: reuse implementation from the engine, this also breaks with statically compiled build
|
||||
print('#define STB_DS_IMPLEMENTATION')
|
||||
print('#include <stb_ds.h>')
|
||||
print('#include <lua.h>')
|
||||
print('#include <lualib.h>')
|
||||
@ -88,11 +92,13 @@ for procedure, procedure_desc in api["procedures"].items():
|
||||
else:
|
||||
raise BaseException("Unhandled parameter type '%s'" % (parameter["type"]))
|
||||
|
||||
# binding += " lua_pop(L, %i);\n" % (1 + len(procedure_desc["params"]) if "params" in procedure_desc else 0)
|
||||
|
||||
if "return" in procedure_desc:
|
||||
if procedure_desc["return"] == "bool":
|
||||
binding += " lua_pushboolean(L, (int)%s(%s));\n" % (procedure, ", ".join(param["name"] for param in procedure_desc["params"]))
|
||||
binding += " lua_pushboolean(L, (int)(%s(%s)));\n" % (procedure, ", ".join(param["name"] for param in procedure_desc["params"]))
|
||||
elif procedure_desc["return"] == "float":
|
||||
binding += " lua_pushnumber(L, (double)%s(%s));\n" % (procedure, ", ".join(param["name"] for param in procedure_desc["params"]))
|
||||
binding += " lua_pushnumber(L, (double)(%s(%s)));\n" % (procedure, ", ".join(param["name"] for param in procedure_desc["params"]))
|
||||
elif procedure_desc["return"] == "char *":
|
||||
binding += " lua_pushstring(L, %s(%s));\n" % (procedure, ", ".join(param["name"] for param in procedure_desc["params"]))
|
||||
elif type(procedure_desc["return"]) is dict or procedure_desc["return"] in api["types"]:
|
||||
@ -159,7 +165,7 @@ loader = "void bindgen_load_%s(lua_State *L) {\n" % api["name"]
|
||||
modules = set(api["procedures"][procedure]["module"] for procedure in api["procedures"])
|
||||
for module in modules:
|
||||
loader += " bindgen_init();\n"
|
||||
loader += " lua_newtable(L);\n"
|
||||
loader += " lua_createtable(L, 0, %i);\n" % len(api["procedures"])
|
||||
for procedure, procedure_desc in api["procedures"].items():
|
||||
if procedure_desc["module"] == module:
|
||||
loader += " lua_pushcfunction(L, binding_%s);\n" % procedure
|
||||
|
@ -43,6 +43,50 @@ static int physfs_loader(lua_State *L) {
|
||||
}
|
||||
|
||||
|
||||
/* WARN! experimental and will probably be removed */
|
||||
/* it was an attempt to ease memory usage problems posed by using lua */
|
||||
/* it saved ~100MiB, but it still hogs ~500MiB for no reason on my PC */
|
||||
static void *custom_alloc(void *ud, void *ptr, size_t osize, size_t nsize) {
|
||||
(void)ud;
|
||||
|
||||
/* small allocations are placed in slots, as there's a big chance they will not need to be resized */
|
||||
static char slots[1024][64];
|
||||
static int16_t free_slots[1024] = { [0] = -1 };
|
||||
static size_t free_slot_count = 1024;
|
||||
|
||||
if (free_slots[0] == -1)
|
||||
for (int i = 0; i < 1024; i++)
|
||||
free_slots[i] = (int16_t)i;
|
||||
|
||||
if (nsize == 0) {
|
||||
if (ptr && (char *)ptr >= &slots[0][0] && (char *)ptr <= &slots[1024-1][64-1])
|
||||
free_slots[free_slot_count++] = (int16_t)(((uintptr_t)ptr - (uintptr_t)slots) / 64);
|
||||
else
|
||||
SDL_free(ptr);
|
||||
return NULL;
|
||||
} else {
|
||||
if (!ptr && nsize <= 64 && free_slot_count > 0) {
|
||||
/* use a slot */
|
||||
return slots[free_slots[--free_slot_count]];
|
||||
}
|
||||
|
||||
if ((char *)ptr >= &slots[0][0] && (char *)ptr <= &slots[1024-1][64-1]) {
|
||||
/* still fits */
|
||||
if (nsize <= 64)
|
||||
return ptr;
|
||||
|
||||
/* move from slot to dynamic memory */
|
||||
void *mem = SDL_malloc(nsize);
|
||||
SDL_memcpy(mem, ptr, osize);
|
||||
free_slots[free_slot_count++] = (int16_t)(((uintptr_t)ptr - (uintptr_t)slots) / 64);
|
||||
return mem;
|
||||
}
|
||||
|
||||
return SDL_realloc(ptr, nsize);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void game_tick(void) {
|
||||
if (ctx.initialization_needed) {
|
||||
if (!ctx.udata)
|
||||
@ -57,6 +101,8 @@ void game_tick(void) {
|
||||
}
|
||||
state->L = luaL_newstate();
|
||||
|
||||
lua_setallocf(state->L, custom_alloc, NULL);
|
||||
|
||||
/* fakey version of luaL_openlibs() that excludes file i/o and os stuff */
|
||||
{
|
||||
static const luaL_Reg loaded_libs[] = {
|
||||
@ -79,7 +125,7 @@ void game_tick(void) {
|
||||
|
||||
/* package.searchers = { physfs_loader } */
|
||||
lua_getglobal(state->L, "package");
|
||||
lua_newtable(state->L);
|
||||
lua_createtable(state->L, 0, 1);
|
||||
lua_setfield(state->L, -2, "searchers");
|
||||
|
||||
lua_getfield(state->L, -1, "searchers");
|
||||
|
@ -439,6 +439,8 @@ TextureKey textures_get_key(TextureCache *cache, const char *path) {
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: this will be bad when dynamic strings are involved */
|
||||
/* to mitigate that we could free ptr_to_texture each frame */
|
||||
/* try loading */
|
||||
last_texture = textures_load(cache, path);
|
||||
hmput(ptr_to_texture, path, last_texture);
|
||||
|
Loading…
Reference in New Issue
Block a user