Reallocating/resizing Lua 5.1 userdata in C -
how resize lua 5.1 userdata object in c during runtime?
i change size of numarray structure described in roberto ierusalimschy's book programming in lua, 2nd edition, pp. 260, lua 5.1 console.
my numarray userdata can either store unsigned chars or lua_numbers. played around calling unmodified luam_realloc_ function defined in lmem.c, call c's realloc (via l_alloc) function returns null, not enough memory
error message.
would please me ?
--- lapi.c ------------------------------------------------------------------------------------------------- lua_api void *agn_resizeud (lua_state *l, void *block, size_t osize, size_t nsize) { udata *u = (udata *)luam_realloc_(l, block, osize + sizeof(udata), nsize + sizeof(udata)); u->uv.len = nsize; if (u == null) lual_error(l, "error in " lua_qs ": failed allocate memory.", "api/agn_resizeud"); return u; } --- numarray.c --------------------------------------------------------------------------------------------- #define checkarray(l, n) (numarray *)lual_checkudata(l, n, "numarray") [...] /* auxiliary c function call luam_realloc_ via lua c api */ void *reallocud (lua_state *l, void *block, size_t o, size_t n, size_t sizeofelem, size_t sizeofnumarray) { if (n + 1 > max_sizet/sizeofelem) lual_error(l, "error in " lua_qs ": memory allocation error: block big.", "(reallocud)", n); else return agn_resizeud(l, block, sizeofnumarray + o*sizeofelem, sizeofnumarray + n*sizeofelem); } /* function resize numarray */ static int numarray_resize (lua_state *l) { size_t i; global_state *g = g(l); numarray *a = checkarray(l, 1); int n = lual_checkinteger(l, 2); if (n < 1) lual_error(l, "error in " lua_qs ": new size %d non-positive.", "numarray.resize", n); if (n == a->size) { /* nothing , not complain */ lua_pushinteger(l, a->size); return 1; } if (n > a->size) { /* extend */ = reallocud(l, a, a->size, n, a->isnumber ? sizeof(lua_number) : sizeof(char), sizeof(numarray)); if (a->isnumber) { (i=a->size; < n; i++) a->data.n[i] = 0; } else { (i=a->size; < n; i++) a->data.c[i] = 0; } } else { /* reduce */ if (a->isnumber) { (i=a->size - 1; > n - 1; i--) a->data.n[i] = 0; } else { (i=a->size - 1; > n - 1; i--) a->data.c[i] = 0; } = reallocud(l, a, a->size, n, a->isnumber ? sizeof(lua_number) : sizeof(char), sizeof(numarray)); } a->size = n; lua_pushnumber(l, a->size); return 1; } [...] typedef struct numarray { size_t size; /* number of slots */ char isnumber; union data { lua_number n[1]; /* pointer various lua_number values */ unsigned char c[1]; } data; } numarray;
there no need mess internals of lua.
but need change how userdata created: instead of allocating struct , data in same memory block, allocate them separately, using lua_newuserdata
allocate struct , malloc
allocate data.
then, resize data part, update size in struct , realloc
data part.
Comments
Post a Comment