Skip to content

Commit

Permalink
Complete the use of the Lua state allocator.
Browse files Browse the repository at this point in the history
The original work, in commit 4417618, failed to call the
lua_Alloc function to free allocated memory. Thanks to George Zhao for
the report (issue #3).

Lrealloc and Lfree functions were added to mirror Lmalloc and simplify
the code.

In the process two other bugs turned up. First, one caller of Lmalloc
tried to take action if the allocation failed, but this was
ineffective, as Lmalloc called luaL_error. Hence, Lmalloc was changed
not to abort on error. Secondly, in lgnu.c, Lmalloc was called
erroneously, to allocate a buffer later freed by regfree (and hence by
free); this was corrected to call malloc.

The resulting code has been tested with both Lua 5.2 and luajit
2.0.0-beta9.
  • Loading branch information
rrthomas committed Jan 8, 2013
1 parent cdd65f3 commit fadff34
Show file tree
Hide file tree
Showing 7 changed files with 39 additions and 20 deletions.
29 changes: 16 additions & 13 deletions src/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,19 @@ void set_int_field (lua_State *L, const char* field, int val)
void *Lmalloc(lua_State *L, size_t size) {
void *ud;
lua_Alloc lalloc = lua_getallocf(L, &ud);
void *p = lalloc(ud, NULL, 0, size);
if(p == NULL)
luaL_error(L, "malloc failed");
return p;
return lalloc(ud, NULL, 0, size);
}

void *Lrealloc(lua_State *L, void *p, size_t osize, size_t nsize) {
void *ud;
lua_Alloc lalloc = lua_getallocf(L, &ud);
return lalloc(ud, p, osize, nsize);
}

void Lfree(lua_State *L, void *p, size_t osize) {
void *ud;
lua_Alloc lalloc = lua_getallocf(L, &ud);
lalloc(ud, p, osize, 0);
}

/* This function fills a table with string-number pairs.
Expand Down Expand Up @@ -117,9 +126,7 @@ void freelist_free (TFreeList *fl) {
enum { ID_NUMBER, ID_STRING };

void buffer_init (TBuffer *buf, size_t sz, lua_State *L, TFreeList *fl) {
void *ud;
lua_Alloc lalloc = lua_getallocf(L, &ud);
buf->arr = (char*) lalloc (ud, NULL, 0, sz);
buf->arr = Lmalloc(L, sz);
if (!buf->arr) {
freelist_free (fl);
luaL_error (L, "malloc failed");
Expand All @@ -132,9 +139,7 @@ void buffer_init (TBuffer *buf, size_t sz, lua_State *L, TFreeList *fl) {
}

void buffer_free (TBuffer *buf) {
void *ud;
lua_Alloc lalloc = lua_getallocf(buf->L, &ud);
lalloc (ud, buf->arr, buf->size, 0);
Lfree(buf->L, buf->arr, buf->size);
}

void buffer_clear (TBuffer *buf) {
Expand All @@ -152,9 +157,7 @@ void buffer_addbuffer (TBuffer *trg, TBuffer *src) {
void buffer_addlstring (TBuffer *buf, const void *src, size_t sz) {
size_t newtop = buf->top + sz;
if (newtop > buf->size) {
void *ud;
lua_Alloc lalloc = lua_getallocf(buf->L, &ud);
char *p = (char*) lalloc (ud, buf->arr, buf->size, 2 * newtop); /* 2x expansion */
char *p = (char*) Lrealloc (buf->L, buf->arr, buf->size, 2 * newtop); /* 2x expansion */
if (!p) {
freelist_free (buf->freelist);
luaL_error (buf->L, "realloc failed");
Expand Down
2 changes: 2 additions & 0 deletions src/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,5 +92,7 @@ void set_int_field (lua_State *L, const char* field, int val);
int get_flags (lua_State *L, const flag_pair **arr);
const char *get_flag_key (const flag_pair *fp, int val);
void *Lmalloc (lua_State *L, size_t size);
void *Lrealloc (lua_State *L, void *p, size_t osize, size_t nsize);
void Lfree (lua_State *L, void *p, size_t size);

#endif
4 changes: 3 additions & 1 deletion src/gnu/lgnu.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,9 @@ static const unsigned char *gettranslate (lua_State *L, int pos) {
if (lua_isnoneornil (L, pos))
return NULL;

translate = (const unsigned char *) Lmalloc (L, ALG_TRANSLATE_SIZE);
translate = (const unsigned char *) malloc (ALG_TRANSLATE_SIZE);
if (!translate)
luaL_error (L, "malloc failed");
memset ((unsigned char *) translate, 0, ALG_TRANSLATE_SIZE); /* initialize all members to 0 */
for (i = 0; i <= UCHAR_MAX; i++) {
lua_pushinteger (L, i);
Expand Down
14 changes: 10 additions & 4 deletions src/pcre/lpcre.c
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,8 @@ static int compile_regex (lua_State *L, const TArgComp *argC, TPcre **pud) {
pcre_fullinfo (ud->pr, ud->extra, PCRE_INFO_CAPTURECOUNT, &ud->ncapt);
/* need (2 ints per capture, plus one for substring match) * 3/2 */
ud->match = (int *) Lmalloc (L, (ALG_NSUB(ud) + 1) * 3 * sizeof (int));
if (!ud->match)
luaL_error (L, "malloc failed");

if (pud) *pud = ud;
return 1;
Expand Down Expand Up @@ -258,9 +260,13 @@ static int Lpcre_dfa_exec (lua_State *L)
TPcre *ud;
int res;
int *buf, *ovector, *wspace;
size_t bufsize;

checkarg_dfa_exec (L, &argE, &ud);
buf = (int*) Lmalloc (L, (argE.ovecsize + argE.wscount) * sizeof(int));
bufsize = (argE.ovecsize + argE.wscount) * sizeof(int);
buf = (int*) Lmalloc (L, bufsize);
if (!buf)
luaL_error (L, "malloc failed");
ovector = buf;
wspace = buf + argE.ovecsize;

Expand All @@ -277,11 +283,11 @@ static int Lpcre_dfa_exec (lua_State *L)
lua_rawseti (L, -2, i+1);
}
lua_pushinteger (L, res); /* 3-rd return value */
free (buf);
Lfree (L, buf, bufsize);
return 3;
}
else {
free (buf);
Lfree (L, buf, bufsize);
if (ALG_NOMATCH (res))
return lua_pushnil (L), 1;
else
Expand Down Expand Up @@ -337,7 +343,7 @@ static int Lpcre_gc (lua_State *L) {
if (ud->pr) pcre_free (ud->pr);
if (ud->extra) pcre_free (ud->extra);
if (ud->tables) pcre_free ((void *)ud->tables);
free (ud->match);
Lfree (L, ud->match, (ALG_NSUB(ud) + 1) * 3 * sizeof (int));
}
return 0;
}
Expand Down
4 changes: 3 additions & 1 deletion src/posix/lposix.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ static int compile_regex (lua_State *L, const TArgComp *argC, TPosix **pud) {
if (argC->cflags & REG_NOSUB)
ud->r.re_nsub = 0;
ud->match = (regmatch_t *) Lmalloc (L, (ALG_NSUB(ud) + 1) * sizeof (regmatch_t));
if (!ud->match)
luaL_error (L, "malloc failed");
lua_pushvalue (L, ALG_ENVIRONINDEX);
lua_setmetatable (L, -2);

Expand Down Expand Up @@ -184,7 +186,7 @@ static int Posix_gc (lua_State *L) {
if (ud->freed == 0) { /* precaution against "manual" __gc calling */
ud->freed = 1;
regfree (&ud->r);
free (ud->match);
Lfree (L, ud->match, (ALG_NSUB(ud) + 1) * sizeof (regmatch_t));
}
return 0;
}
Expand Down
4 changes: 3 additions & 1 deletion src/tre/ltre.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ static int compile_regex (lua_State *L, const TArgComp *argC, TPosix **pud) {
if (argC->cflags & REG_NOSUB)
ud->r.re_nsub = 0;
ud->match = (regmatch_t *) Lmalloc (L, (ALG_NSUB(ud) + 1) * sizeof (regmatch_t));
if (!ud->match)
luaL_error (L, "malloc failed");
lua_pushvalue (L, ALG_ENVIRONINDEX);
lua_setmetatable (L, -2);

Expand Down Expand Up @@ -209,7 +211,7 @@ static int Ltre_gc (lua_State *L) {
if (ud->freed == 0) { /* precaution against "manual" __gc calling */
ud->freed = 1;
tre_regfree (&ud->r);
free (ud->match);
Lfree (L, ud->match, (ALG_NSUB(ud) + 1) * sizeof (regmatch_t));
}
return 0;
}
Expand Down
2 changes: 2 additions & 0 deletions src/tre/ltre_w.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ static int compile_regex (lua_State *L, const TArgComp *argC, TPosix **pud) {
if (argC->cflags & REG_NOSUB)
ud->r.re_nsub = 0;
ud->match = (regmatch_t *) Lmalloc (L, (ALG_NSUB(ud) + 1) * sizeof (regmatch_t));
if (!ud->match)
luaL_error (L, "malloc failed");
lua_pushvalue (L, ALG_ENVIRONINDEX);
lua_setmetatable (L, -2);

Expand Down

0 comments on commit fadff34

Please sign in to comment.