[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: RE: Hooks for I/O, memory, etc?
- From: "Joshua Jensen" <jjensen@...>
- Date: Mon, 10 Jun 2002 15:14:37 -0600
> The drawback is that everyone using Lua would have to start
> it with something like
>
> lua_open(&realloc);
>
> which is not exactly friendly... Note that you already can
> change memory allocation without editing the source:
>
> #ifndef l_realloc
> #define l_realloc(b,os,s) realloc(b,s)
> #endif
I offer the following changes I made to Lua 4.1 Alpha which avoids this
problem. You have to register your callbacks BEFORE lua_open() is
called, although reasonable defaults (Lua's original scheme) are
provided.
Thanks,
Josh
------------------------------------------------------------------
>From lmem.c:
/*
** generic allocation routine.
*/
void *luaM_realloc (lua_State *L, void *block, lu_mem oldsize, lu_mem
size) {
if (size == 0) {
// l_free(block, oldsize); /* block may be NULL; that is OK for free
*/
(*G(L)->freeFunc)(block, G(L)->memData);
luaM_setname(L, NULL);
block = NULL;
}
else if (size >= MAX_SIZET)
luaD_error(L, "memory allocation error: block too big");
else {
// block = l_realloc(block, oldsize, size);
block = (*G(L)->reallocFunc)(block, size, G(L)->memData,
L->allocName, L->allocFlags);
luaM_setname(L, NULL);
if (block == NULL) {
if (L)
luaD_breakrun(L, LUA_ERRMEM); /* break run without error
message */
else return NULL; /* error before creating state! */
}
}
if (L && G(L)) {
G(L)->nblocks -= oldsize;
G(L)->nblocks += size;
}
return block;
}
------------------------------------------------------------------------
-------
>From lua.h:
typedef void* (*lua_ReallocFunction)(void* ptr, int size, void* data,
const char* allocName, unsigned int flags);
typedef void (*lua_FreeFunction)(void* ptr, void* data);
void lua_getdefaultmemoryfunctions(lua_ReallocFunction* reallocFunc,
lua_FreeFunction* freeFunc, void** data);
void lua_setdefaultmemoryfunctions(lua_ReallocFunction reallocFunc,
lua_FreeFunction freeFunc, void* data);
------------------------------------------------------------------------
-------
>From lstate.h:
typedef struct global_State {
lua_ReallocFunction reallocFunc;
lua_FreeFunction freeFunc;
------------------------------------------------------------------------
-------
>From lstate.c:
static void* luaHelper_ReallocFunction(void* ptr, int size, void* data,
const char* allocName, unsigned int allocFlags)
{
UNUSED(data);
UNUSED(allocName);
UNUSED(allocFlags);
return realloc(ptr, size);
}
static void luaHelper_FreeFunction(void* ptr, void* data)
{
UNUSED(data);
free(ptr);
}
static lua_ReallocFunction luaHelper_Realloc =
luaHelper_ReallocFunction;
static lua_FreeFunction luaHelper_Free = luaHelper_FreeFunction;
static void* luaHelper_memData = NULL;
void lua_getdefaultmemoryfunctions(lua_ReallocFunction* reallocFunc,
lua_FreeFunction* freeFunc, void** data)
{
*reallocFunc = luaHelper_Realloc;
*freeFunc = luaHelper_Free;
*data = luaHelper_memData;
}
void lua_setdefaultmemoryfunctions(lua_ReallocFunction reallocFunc,
lua_FreeFunction freeFunc, void* data)
{
if (reallocFunc)
luaHelper_Realloc = reallocFunc;
else
luaHelper_Realloc = luaHelper_ReallocFunction;
if (freeFunc)
luaHelper_Free = freeFunc;
else
luaHelper_Free = luaHelper_FreeFunction;
luaHelper_memData = data;
}
static void f_luaopen (lua_State *L, void *ud) {
int i;
global_State globalState;
lua_State luaState;
UNUSED(ud);
luaState.allocName = "global_State";
luaState._G = &globalState;
globalState.reallocFunc = luaHelper_Realloc;
globalState.freeFunc = luaHelper_Free;
globalState.memData = luaHelper_memData;
/* create a new global state */
L->_G = luaM_new(&luaState, global_State);
G(L)->reallocFunc = luaHelper_Realloc;
G(L)->freeFunc = luaHelper_Free;
G(L)->memData = luaHelper_memData;
...
}
LUA_API lua_State *lua_open (void) {
global_State globalState;
lua_State luaState;
lua_State *L;
luaState.allocName = "global_State";
luaState._G = &globalState;
globalState.reallocFunc = luaHelper_Realloc;
globalState.freeFunc = luaHelper_Free;
globalState.memData = luaHelper_memData;
L = luaM_new(&luaState, lua_State);
...
}
static void close_state (lua_State *L) {
global_State globalState;
lua_State luaState;
luaF_close(L, L->stack); /* close all upvalues for this thread */
luaState._G = &globalState;
globalState.reallocFunc = G(L)->reallocFunc;
globalState.freeFunc = G(L)->freeFunc;
globalState.memData = G(L)->memData;
if (G(L)) { /* close global state */
luaC_collect(L, 1); /* collect all elements */
lua_assert(G(L)->rootproto == NULL);
lua_assert(G(L)->rootudata == NULL);
lua_assert(G(L)->rootcl == NULL);
lua_assert(G(L)->rootupval == NULL);
lua_assert(G(L)->roottable == NULL);
luaS_freeall(L);
luaM_freearray(L, G(L)->Mbuffer, G(L)->Mbuffsize, char);
luaM_freelem(&luaState, L->_G);
}
luaE_closethread(&luaState, L);
}