diff --git a/lapi.c b/lapi.c index b1b7d0ff..661d5ba5 100644 --- a/lapi.c +++ b/lapi.c @@ -1,5 +1,5 @@ /* -** $Id: lapi.c,v 1.112 2000/12/04 18:33:40 roberto Exp roberto $ +** $Id: lapi.c,v 1.113 2000/12/26 18:46:09 roberto Exp roberto $ ** Lua API ** See Copyright Notice in lua.h */ @@ -362,7 +362,6 @@ LUA_API int lua_ref (lua_State *L, int lock) { else { /* no more free places */ luaM_growvector(L, L->refArray, L->nref, L->sizeref, struct Ref, MAX_INT, "reference table overflow"); - L->nblocks += sizeof(struct Ref); ref = L->nref++; } L->refArray[ref].o = *(L->top-1); diff --git a/lcode.c b/lcode.c index 685ce748..bd73dc57 100644 --- a/lcode.c +++ b/lcode.c @@ -1,5 +1,5 @@ /* -** $Id: lcode.c,v 1.53 2000/12/04 18:33:40 roberto Exp roberto $ +** $Id: lcode.c,v 1.54 2000/12/26 18:46:09 roberto Exp roberto $ ** Code generator for Lua ** See Copyright Notice in lua.h */ @@ -102,14 +102,14 @@ void luaK_kstr (LexState *ls, int c) { static int number_constant (FuncState *fs, lua_Number r) { /* check whether `r' has appeared within the last LOOKBACKNUMS entries */ Proto *f = fs->f; - int c = f->nknum; + int c = fs->nknum; int lim = c < LOOKBACKNUMS ? 0 : c-LOOKBACKNUMS; while (--c >= lim) if (f->knum[c] == r) return c; /* not found; create a new entry */ - luaM_growvector(fs->L, f->knum, f->nknum, fs->sizeknum, lua_Number, + luaM_growvector(fs->L, f->knum, fs->nknum, f->sizeknum, lua_Number, MAXARG_U, "constant table overflow"); - c = f->nknum++; + c = fs->nknum++; f->knum[c] = r; return c; } @@ -424,13 +424,13 @@ static void codelineinfo (FuncState *fs) { LexState *ls = fs->ls; if (ls->lastline > fs->lastline) { if (ls->lastline > fs->lastline+1) { - luaM_growvector(fs->L, f->lineinfo, f->nlineinfo, fs->sizelineinfo, int, + luaM_growvector(fs->L, f->lineinfo, fs->nlineinfo, f->sizelineinfo, int, MAX_INT, "line info overflow"); - f->lineinfo[f->nlineinfo++] = -(ls->lastline - (fs->lastline+1)); + f->lineinfo[fs->nlineinfo++] = -(ls->lastline - (fs->lastline+1)); } - luaM_growvector(fs->L, f->lineinfo, f->nlineinfo, fs->sizelineinfo, int, + luaM_growvector(fs->L, f->lineinfo, fs->nlineinfo, f->sizelineinfo, int, MAX_INT, "line info overflow"); - f->lineinfo[f->nlineinfo++] = fs->pc; + f->lineinfo[fs->nlineinfo++] = fs->pc; fs->lastline = ls->lastline; } } @@ -447,6 +447,7 @@ int luaK_code1 (FuncState *fs, OpCode o, int arg1) { int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) { + Proto *f; Instruction i = previous_instruction(fs); int delta = (int)luaK_opproperties[o].push - (int)luaK_opproperties[o].pop; int optm = 0; /* 1 when there is an optimization */ @@ -629,9 +630,10 @@ int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) { break; } } + f = fs->f; luaK_deltastack(fs, delta); if (optm) { /* optimize: put instruction in place of last one */ - fs->f->code[fs->pc-1] = i; /* change previous instruction */ + f->code[fs->pc-1] = i; /* change previous instruction */ return fs->pc-1; /* do not generate new instruction */ } /* else build new instruction */ @@ -643,9 +645,9 @@ int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) { } codelineinfo(fs); /* put new instruction in code array */ - luaM_growvector(fs->L, fs->f->code, fs->pc, fs->sizecode, Instruction, + luaM_growvector(fs->L, f->code, fs->pc, f->sizecode, Instruction, MAX_INT, "code size overflow"); - fs->f->code[fs->pc] = i; + f->code[fs->pc] = i; return fs->pc++; } diff --git a/ldo.c b/ldo.c index 140cff45..01485165 100644 --- a/ldo.c +++ b/ldo.c @@ -1,5 +1,5 @@ /* -** $Id: ldo.c,v 1.109 2000/10/30 12:38:50 roberto Exp roberto $ +** $Id: ldo.c,v 1.110 2000/11/24 17:39:56 roberto Exp roberto $ ** Stack and Call structure of Lua ** See Copyright Notice in lua.h */ @@ -28,38 +28,40 @@ /* space to handle stack overflow errors */ -#define EXTRA_STACK (2*LUA_MINSTACK) +#define EXTRA_STACK (2*LUA_MINSTACK) + + +static void restore_stack_limit (lua_State *L) { + StkId limit = L->stack+(L->stacksize-EXTRA_STACK)-1; + if (L->top < limit) + L->stack_last = limit; +} void luaD_init (lua_State *L, int stacksize) { - L->stack = luaM_newvector(L, stacksize+EXTRA_STACK, TObject); - L->nblocks += stacksize*sizeof(TObject); - L->stack_last = L->stack+(stacksize-1); + stacksize += EXTRA_STACK; + L->stack = luaM_newvector(L, stacksize, TObject); L->stacksize = stacksize; L->Cbase = L->top = L->stack; + restore_stack_limit(L); } void luaD_checkstack (lua_State *L, int n) { if (L->stack_last - L->top <= n) { /* stack overflow? */ - if (L->stack_last-L->stack > (L->stacksize-1)) { + if (L->stack_last == L->stack+L->stacksize-1) { /* overflow while handling overflow */ luaD_breakrun(L, LUA_ERRERR); /* break run without error message */ } else { L->stack_last += EXTRA_STACK; /* to be used by error message */ + LUA_ASSERT(L->stack_last == L->stack+L->stacksize-1, "wrong stack limit"); lua_error(L, "stack overflow"); } } } -static void restore_stack_limit (lua_State *L) { - if (L->top - L->stack < L->stacksize - 1) - L->stack_last = L->stack + (L->stacksize-1); -} - - /* ** Adjust stack. Set top to base+extra, pushing NILs if needed. ** (we cannot add base+extra unless we are sure it fits in the stack; diff --git a/lfunc.c b/lfunc.c index ad1abfc4..14ef5e15 100644 --- a/lfunc.c +++ b/lfunc.c @@ -1,5 +1,5 @@ /* -** $Id: lfunc.c,v 1.34 2000/10/30 12:20:29 roberto Exp roberto $ +** $Id: lfunc.c,v 1.35 2000/12/04 18:33:40 roberto Exp roberto $ ** Auxiliary functions to manipulate prototypes and closures ** See Copyright Notice in lua.h */ @@ -18,13 +18,11 @@ Closure *luaF_newclosure (lua_State *L, int nelems) { - int size = sizeclosure(nelems); - Closure *c = (Closure *)luaM_malloc(L, size); + Closure *c = (Closure *)luaM_malloc(L, sizeclosure(nelems)); c->next = L->rootcl; L->rootcl = c; c->mark = c; c->nupvalues = nelems; - L->nblocks += size; return c; } @@ -32,20 +30,20 @@ Closure *luaF_newclosure (lua_State *L, int nelems) { Proto *luaF_newproto (lua_State *L) { Proto *f = luaM_new(L, Proto); f->knum = NULL; - f->nknum = 0; + f->sizeknum = 0; f->kstr = NULL; - f->nkstr = 0; + f->sizekstr = 0; f->kproto = NULL; - f->nkproto = 0; + f->sizekproto = 0; f->code = NULL; - f->ncode = 0; + f->sizecode = 0; f->numparams = 0; f->is_vararg = 0; f->maxstacksize = 0; f->marked = 0; f->lineinfo = NULL; - f->nlineinfo = 0; - f->nlocvars = 0; + f->sizelocvars = 0; + f->sizelineinfo = 0; f->locvars = NULL; f->lineDefined = 0; f->source = NULL; @@ -55,39 +53,19 @@ Proto *luaF_newproto (lua_State *L) { } -static size_t protosize (Proto *f) { - return sizeof(Proto) - + f->nknum*sizeof(lua_Number) - + f->nkstr*sizeof(TString *) - + f->nkproto*sizeof(Proto *) - + f->ncode*sizeof(Instruction) - + f->nlocvars*sizeof(struct LocVar) - + f->nlineinfo*sizeof(int); -} - - -void luaF_protook (lua_State *L, Proto *f, int pc) { - f->ncode = pc; /* signal that proto was properly created */ - L->nblocks += protosize(f); -} - - void luaF_freeproto (lua_State *L, Proto *f) { - if (f->ncode > 0) /* function was properly created? */ - L->nblocks -= protosize(f); - luaM_free(L, f->code); - luaM_free(L, f->locvars); - luaM_free(L, f->kstr); - luaM_free(L, f->knum); - luaM_free(L, f->kproto); - luaM_free(L, f->lineinfo); - luaM_free(L, f); + luaM_freearray(L, f->code, f->sizecode, Instruction); + luaM_freearray(L, f->locvars, f->sizelocvars, struct LocVar); + luaM_freearray(L, f->kstr, f->sizekstr, TString *); + luaM_freearray(L, f->knum, f->sizeknum, lua_Number); + luaM_freearray(L, f->kproto, f->sizekproto, Proto *); + luaM_freearray(L, f->lineinfo, f->sizelineinfo, int); + luaM_freelem(L, f, Proto); } void luaF_freeclosure (lua_State *L, Closure *c) { - L->nblocks -= sizeclosure(c->nupvalues); - luaM_free(L, c); + luaM_free(L, c, sizeclosure(c->nupvalues)); } @@ -97,7 +75,7 @@ void luaF_freeclosure (lua_State *L, Closure *c) { */ const char *luaF_getlocalname (const Proto *f, int local_number, int pc) { int i; - for (i = 0; inlocvars && f->locvars[i].startpc <= pc; i++) { + for (i = 0; isizelocvars && f->locvars[i].startpc <= pc; i++) { if (pc < f->locvars[i].endpc) { /* is variable active? */ local_number--; if (local_number == 0) diff --git a/lfunc.h b/lfunc.h index 3a9bc990..b78578a6 100644 --- a/lfunc.h +++ b/lfunc.h @@ -1,5 +1,5 @@ /* -** $Id: lfunc.h,v 1.12 2000/06/26 19:28:31 roberto Exp roberto $ +** $Id: lfunc.h,v 1.13 2000/09/29 12:42:13 roberto Exp roberto $ ** Auxiliary functions to manipulate prototypes and closures ** See Copyright Notice in lua.h */ @@ -13,7 +13,6 @@ Proto *luaF_newproto (lua_State *L); -void luaF_protook (lua_State *L, Proto *f, int pc); Closure *luaF_newclosure (lua_State *L, int nelems); void luaF_freeproto (lua_State *L, Proto *f); void luaF_freeclosure (lua_State *L, Closure *c); diff --git a/lgc.c b/lgc.c index 7b35ee03..8c63570a 100644 --- a/lgc.c +++ b/lgc.c @@ -1,5 +1,5 @@ /* -** $Id: lgc.c,v 1.73 2000/11/24 17:39:56 roberto Exp roberto $ +** $Id: lgc.c,v 1.74 2000/12/26 18:46:09 roberto Exp roberto $ ** Garbage Collector ** See Copyright Notice in lua.h */ @@ -37,11 +37,11 @@ static void protomark (Proto *f) { int i; f->marked = 1; strmark(f->source); - for (i=0; inkstr; i++) + for (i=0; isizekstr; i++) strmark(f->kstr[i]); - for (i=0; inkproto; i++) + for (i=0; isizekproto; i++) protomark(f->kproto[i]); - for (i=0; inlocvars; i++) /* mark local-variable names */ + for (i=0; isizelocvars; i++) /* mark local-variable names */ strmark(f->locvars[i].varname); } } @@ -248,8 +248,7 @@ static void collectstrings (lua_State *L, int all) { else { /* collect */ *p = next->nexthash; L->strt.nuse--; - L->nblocks -= sizestring(next->len); - luaM_free(L, next); + luaM_free(L, next, sizestring(next->len)); } } } @@ -273,7 +272,6 @@ static void collectudata (lua_State *L, int all) { *p = next->nexthash; next->nexthash = L->TMtable[tag].collected; /* chain udata */ L->TMtable[tag].collected = next; - L->nblocks -= sizestring(next->len); L->udt.nuse--; } } @@ -286,9 +284,8 @@ static void collectudata (lua_State *L, int all) { static void checkMbuffer (lua_State *L) { if (L->Mbuffsize > MINBUFFER*2) { /* is buffer too big? */ size_t newsize = L->Mbuffsize/2; /* still larger than MINBUFFER */ - L->nblocks -= (L->Mbuffsize - newsize)*sizeof(char); + luaM_reallocvector(L, L->Mbuffer, L->Mbuffsize, newsize, char); L->Mbuffsize = newsize; - luaM_reallocvector(L, L->Mbuffer, newsize, char); } } @@ -320,7 +317,7 @@ static void callgcTMudata (lua_State *L) { L->TMtable[tag].collected = udata->nexthash; /* remove it from list */ tsvalue(&o) = udata; callgcTM(L, &o); - luaM_free(L, udata); + luaM_free(L, udata, sizeudata(udata->len)); } } } diff --git a/lmem.c b/lmem.c index 830f6f1d..3d34e313 100644 --- a/lmem.c +++ b/lmem.c @@ -1,5 +1,5 @@ /* -** $Id: lmem.c,v 1.40 2000/11/24 17:39:56 roberto Exp roberto $ +** $Id: lmem.c,v 1.41 2000/12/26 18:46:09 roberto Exp roberto $ ** Interface to Memory Manager ** See Copyright Notice in lua.h */ @@ -29,15 +29,14 @@ #include #include -#define realloc(b, s) debug_realloc(b, s) -#define malloc(b) debug_realloc(NULL, b) -#define free(b) debug_realloc(b, 0) +#define basicrealloc(b, os, s) debug_realloc(b, os, s) +#define basicfree(b, s) debug_realloc(b, s, 0) /* ensures maximum alignment for HEADER */ #define HEADER (sizeof(union L_Umaxalign)) -#define MARKSIZE 16 +#define MARKSIZE 32 #define MARK 0x55 /* 01010101 (a nice pattern) */ @@ -55,8 +54,6 @@ static void *checkblock (void *block) { int i; for (i=0;i memdebug_memlimit) return NULL; /* to test memory allocation errors */ else { - size_t realsize = HEADER+size+MARKSIZE; - char *newblock = (char *)(malloc)(realsize); /* alloc a new block */ + char *newblock; int i; + size_t realsize = HEADER+size+MARKSIZE; if (realsize < size) return NULL; /* overflow! */ + newblock = (char *)malloc(realsize); /* alloc a new block */ if (newblock == NULL) return NULL; + if (oldsize > size) oldsize = size; if (block) { - size_t oldsize = *blocksize(block); - if (oldsize > size) oldsize = size; memcpy(newblock+HEADER, block, oldsize); freeblock(block); /* erase (and check) old copy */ } + /* initialize new part of the block with something `weird' */ + memset(newblock+HEADER+oldsize, -MARK, size-oldsize); memdebug_total += size; - if (memdebug_total > memdebug_maxmem) memdebug_maxmem = memdebug_total; + if (memdebug_total > memdebug_maxmem) + memdebug_maxmem = memdebug_total; memdebug_numblocks++; *(size_t *)newblock = size; for (i=0;i= MAX_SIZET) lua_error(L, "memory allocation error: block too big"); - block = realloc(block, size); - if (block == NULL) { - if (L) - luaD_breakrun(L, LUA_ERRMEM); /* break run without error message */ - else return NULL; /* error before creating state! */ + else { + block = basicrealloc(block, oldsize, size); + if (block == NULL) { + if (L) + luaD_breakrun(L, LUA_ERRMEM); /* break run without error message */ + else return NULL; /* error before creating state! */ + } + } + if (L) { + L->nblocks -= oldsize; + L->nblocks += size; } return block; } - diff --git a/lmem.h b/lmem.h index c2ee8213..d33473c7 100644 --- a/lmem.h +++ b/lmem.h @@ -1,5 +1,5 @@ /* -** $Id: lmem.h,v 1.17 2000/11/24 17:39:56 roberto Exp roberto $ +** $Id: lmem.h,v 1.18 2000/12/26 18:46:09 roberto Exp roberto $ ** Interface to Memory Manager ** See Copyright Notice in lua.h */ @@ -13,21 +13,29 @@ #include "llimits.h" #include "lua.h" -void *luaM_realloc (lua_State *L, void *oldblock, luint32 size); +void *luaM_realloc (lua_State *L, void *oldblock, luint32 oldsize, + luint32 size); + void *luaM_growaux (lua_State *L, void *block, int *size, int size_elem, int limit, const char *errormsg); -#define luaM_free(L, b) luaM_realloc(L, (b), 0) -#define luaM_malloc(L, t) luaM_realloc(L, NULL, (t)) +#define luaM_free(L, b, s) luaM_realloc(L, (b), (s), 0) +#define luaM_freelem(L, b, t) luaM_realloc(L, (b), sizeof(t), 0) +#define luaM_freearray(L, b, n, t) luaM_realloc(L, (b), \ + ((luint32)(n)*(luint32)sizeof(t)), 0) + +#define luaM_malloc(L, t) luaM_realloc(L, NULL, 0, (t)) #define luaM_new(L, t) ((t *)luaM_malloc(L, sizeof(t))) -#define luaM_newvector(L, n,t) ((t *)luaM_malloc(L, (n)*(luint32)sizeof(t))) +#define luaM_newvector(L, n,t) ((t *)luaM_malloc(L, \ + (luint32)(n)*(luint32)sizeof(t))) #define luaM_growvector(L,v,nelems,size,t,limit,e) \ if (((nelems)+1) > (size)) \ ((v)=(t *)luaM_growaux(L,v,&(size),sizeof(t),limit,e)) -#define luaM_reallocvector(L, v,n,t) \ - ((v)=(t *)luaM_realloc(L, v,(n)*(luint32)sizeof(t))) +#define luaM_reallocvector(L, v,oldn,n,t) \ + ((v)=(t *)luaM_realloc(L, v,(luint32)(oldn)*(luint32)sizeof(t), \ + (luint32)(n)*(luint32)sizeof(t))) #ifdef LUA_DEBUG diff --git a/lobject.c b/lobject.c index 5f9876c0..a2fd786b 100644 --- a/lobject.c +++ b/lobject.c @@ -1,5 +1,5 @@ /* -** $Id: lobject.c,v 1.56 2000/11/24 17:39:56 roberto Exp roberto $ +** $Id: lobject.c,v 1.57 2000/12/04 18:33:40 roberto Exp roberto $ ** Some generic functions over Lua objects ** See Copyright Notice in lua.h */ @@ -57,8 +57,7 @@ int luaO_equalObj (const TObject *t1, const TObject *t2) { char *luaO_openspace (lua_State *L, size_t n) { if (n > L->Mbuffsize) { - luaM_reallocvector(L, L->Mbuffer, n, char); - L->nblocks += (n - L->Mbuffsize)*sizeof(char); + luaM_reallocvector(L, L->Mbuffer, L->Mbuffsize, n, char); L->Mbuffsize = n; } return L->Mbuffer; diff --git a/lobject.h b/lobject.h index 916cc4d1..903833f0 100644 --- a/lobject.h +++ b/lobject.h @@ -1,5 +1,5 @@ /* -** $Id: lobject.h,v 1.83 2000/11/24 17:39:56 roberto Exp roberto $ +** $Id: lobject.h,v 1.84 2000/12/04 18:33:40 roberto Exp roberto $ ** Type definitions for Lua objects ** See Copyright Notice in lua.h */ @@ -102,13 +102,13 @@ typedef struct TString { */ typedef struct Proto { lua_Number *knum; /* numbers used by the function */ - int nknum; /* size of `knum' */ + int sizeknum; /* size of `knum' */ struct TString **kstr; /* strings used by the function */ - int nkstr; /* size of `kstr' */ + int sizekstr; /* size of `kstr' */ struct Proto **kproto; /* functions defined inside the function */ - int nkproto; /* size of `kproto' */ + int sizekproto; /* size of `kproto' */ Instruction *code; - int ncode; /* size of `code'; when 0 means an incomplete `Proto' */ + int sizecode; short numparams; short is_vararg; short maxstacksize; @@ -116,9 +116,9 @@ typedef struct Proto { struct Proto *next; /* debug information */ int *lineinfo; /* map from opcodes to source lines */ - int nlineinfo; /* size of `lineinfo' */ - int nlocvars; + int sizelineinfo; /* size of `lineinfo' */ struct LocVar *locvars; /* information about local variables */ + int sizelocvars; int lineDefined; TString *source; } Proto; diff --git a/lparser.c b/lparser.c index f4e4c551..fe4a1586 100644 --- a/lparser.c +++ b/lparser.c @@ -1,5 +1,5 @@ /* -** $Id: lparser.c,v 1.119 2000/12/04 18:33:40 roberto Exp roberto $ +** $Id: lparser.c,v 1.120 2000/12/26 18:46:09 roberto Exp roberto $ ** LL(1) Parser and code generator for Lua ** See Copyright Notice in lua.h */ @@ -120,10 +120,10 @@ static void check_match (LexState *ls, int what, int who, int where) { static int string_constant (FuncState *fs, TString *s) { Proto *f = fs->f; int c = s->u.s.constindex; - if (c >= f->nkstr || f->kstr[c] != s) { - luaM_growvector(fs->L, f->kstr, f->nkstr, fs->sizekstr, TString *, + if (c >= fs->nkstr || f->kstr[c] != s) { + luaM_growvector(fs->L, f->kstr, fs->nkstr, f->sizekstr, TString *, MAXARG_U, "constant table overflow"); - c = f->nkstr++; + c = fs->nkstr++; f->kstr[c] = s; s->u.s.constindex = c; /* hint for next time */ } @@ -151,11 +151,12 @@ static int checkname (LexState *ls) { static int luaI_registerlocalvar (LexState *ls, TString *varname) { - Proto *f = ls->fs->f; - luaM_growvector(ls->L, f->locvars, f->nlocvars, ls->fs->sizelocvars, + FuncState *fs = ls->fs; + Proto *f = fs->f; + luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars, LocVar, MAX_INT, ""); - f->locvars[f->nlocvars].varname = varname; - return f->nlocvars++; + f->locvars[fs->nlocvars].varname = varname; + return fs->nlocvars++; } @@ -295,10 +296,10 @@ static void pushclosure (LexState *ls, FuncState *func) { int i; for (i=0; inupvalues; i++) luaK_tostack(ls, &func->upvalues[i], 1); - luaM_growvector(ls->L, f->kproto, f->nkproto, fs->sizekproto, Proto *, + luaM_growvector(ls->L, f->kproto, fs->nkproto, f->sizekproto, Proto *, MAXARG_A, "constant table overflow"); - f->kproto[f->nkproto++] = func->f; - luaK_code2(fs, OP_CLOSURE, f->nkproto-1, func->nupvalues); + f->kproto[fs->nkproto++] = func->f; + luaK_code2(fs, OP_CLOSURE, fs->nkproto-1, func->nupvalues); } @@ -313,12 +314,11 @@ static void open_func (LexState *ls, FuncState *fs) { fs->lasttarget = 0; fs->jlt = NO_JUMP; fs->stacklevel = 0; - fs->sizekstr = 0; - fs->sizekproto = 0; - fs->sizeknum = 0; - fs->sizelineinfo = 0; - fs->sizecode = 0; - fs->sizelocvars = 0; + fs->nkstr = 0; + fs->nkproto = 0; + fs->nknum = 0; + fs->nlineinfo = 0; + fs->nlocvars = 0; fs->nactloc = 0; fs->nupvalues = 0; fs->lastline = 0; @@ -337,15 +337,20 @@ static void close_func (LexState *ls) { Proto *f = fs->f; luaK_code0(fs, OP_END); luaK_getlabel(fs); /* close eventual list of pending jumps */ - luaM_reallocvector(L, f->code, fs->pc, Instruction); - luaM_reallocvector(L, f->kstr, f->nkstr, TString *); - luaM_reallocvector(L, f->knum, f->nknum, lua_Number); - luaM_reallocvector(L, f->kproto, f->nkproto, Proto *); removelocalvars(ls, fs->nactloc); - luaM_reallocvector(L, f->locvars, f->nlocvars, LocVar); - luaM_reallocvector(L, f->lineinfo, f->nlineinfo+1, int); - f->lineinfo[f->nlineinfo++] = MAX_INT; /* end flag */ - luaF_protook(L, f, fs->pc); /* proto is ok now */ + luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction); + f->sizecode = fs->pc; + luaM_reallocvector(L, f->kstr, f->sizekstr, fs->nkstr, TString *); + f->sizekstr = fs->nkstr; + luaM_reallocvector(L, f->knum, f->sizeknum, fs->nknum, lua_Number); + f->sizeknum = fs->nknum; + luaM_reallocvector(L, f->kproto, f->sizekproto, fs->nkproto, Proto *); + f->sizekproto = fs->nkproto; + luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar); + f->sizelocvars = fs->nlocvars; + luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->nlineinfo+1, int); + f->lineinfo[fs->nlineinfo++] = MAX_INT; /* end flag */ + f->sizelineinfo = fs->nlineinfo; ls->fs = fs->prev; LUA_ASSERT(fs->bl == NULL, "wrong list end"); } diff --git a/lparser.h b/lparser.h index 9c34a861..933934c9 100644 --- a/lparser.h +++ b/lparser.h @@ -1,5 +1,5 @@ /* -** $Id: lparser.h,v 1.27 2000/11/30 18:50:47 roberto Exp roberto $ +** $Id: lparser.h,v 1.28 2000/12/26 18:46:09 roberto Exp roberto $ ** LL(1) Parser and code generator for Lua ** See Copyright Notice in lua.h */ @@ -41,16 +41,15 @@ typedef struct FuncState { struct FuncState *prev; /* enclosing function */ struct LexState *ls; /* lexical state */ struct lua_State *L; /* copy of the Lua state */ - int pc; /* next position to code */ + int pc; /* next position to code (equivalent to `ncode') */ int lasttarget; /* `pc' of last `jump target' */ int jlt; /* list of jumps to `lasttarget' */ int stacklevel; /* number of values on activation register */ - int sizekstr; /* size of array `kstr' */ - int sizekproto; /* size of array `kproto' */ - int sizeknum; /* size of array `knum' */ - int sizelineinfo; /* size of array `lineinfo' */ - int sizecode; /* size of array `code' */ - int sizelocvars; /* size of array `locvars' */ + int nkstr; /* number of elements in `kstr' */ + int nkproto; /* number of elements in `kproto' */ + int nknum; /* number of elements in `knum' */ + int nlineinfo; /* number of elements in `lineinfo' */ + int nlocvars; /* number of elements in `locvars' */ int nactloc; /* number of active local variables */ int nupvalues; /* number of upvalues */ int lastline; /* line where last `lineinfo' was generated */ diff --git a/lstate.c b/lstate.c index 90ee5cb3..7ed79b50 100644 --- a/lstate.c +++ b/lstate.c @@ -1,5 +1,5 @@ /* -** $Id: lstate.c,v 1.48 2000/10/30 16:29:59 roberto Exp roberto $ +** $Id: lstate.c,v 1.49 2000/12/26 18:46:09 roberto Exp roberto $ ** Global State ** See Copyright Notice in lua.h */ @@ -58,8 +58,8 @@ static void f_luaopen (lua_State *L, void *ud) { #ifdef LUA_DEBUG luaB_opentests(L); if (lua_state == NULL) lua_state = L; /* keep first state to be opened */ -#endif LUA_ASSERT(lua_gettop(L) == 0, "wrong API stack"); +#endif } @@ -67,10 +67,10 @@ LUA_API lua_State *lua_open (int stacksize) { lua_State *L = luaM_new(NULL, lua_State); if (L == NULL) return NULL; /* memory allocation error */ L->stack = NULL; + L->stacksize = 0; L->strt.size = L->udt.size = 0; L->strt.nuse = L->udt.nuse = 0; - L->strt.hash = NULL; - L->udt.hash = NULL; + L->strt.hash = L->udt.hash = NULL; L->Mbuffer = NULL; L->Mbuffsize = 0; L->rootproto = NULL; @@ -106,17 +106,12 @@ LUA_API void lua_close (lua_State *L) { LUA_ASSERT(L->rootcl == NULL, "list should be empty"); LUA_ASSERT(L->roottable == NULL, "list should be empty"); luaS_freeall(L); - if (L->stack) - L->nblocks -= (L->stack_last - L->stack + 1)*sizeof(TObject); - luaM_free(L, L->stack); - L->nblocks -= L->ntag*sizeof(struct TM); - luaM_free(L, L->TMtable); - L->nblocks -= (L->nref)*sizeof(struct Ref); - luaM_free(L, L->refArray); - L->nblocks -= (L->Mbuffsize)*sizeof(char); - luaM_free(L, L->Mbuffer); + luaM_freearray(L, L->stack, L->stacksize, TObject); + luaM_freearray(L, L->TMtable, L->sizeTM, struct TM); + luaM_freearray(L, L->refArray, L->sizeref, struct Ref); + luaM_freearray(L, L->Mbuffer, L->Mbuffsize, char); LUA_ASSERT(L->nblocks == sizeof(lua_State), "wrong count for nblocks"); - luaM_free(L, L); + luaM_freelem(L, L, lua_State); LUA_ASSERT(L != lua_state || memdebug_numblocks == 0, "memory leak!"); LUA_ASSERT(L != lua_state || memdebug_total == 0,"memory leak!"); } diff --git a/lstring.c b/lstring.c index 05e5bbaa..c8cd17b1 100644 --- a/lstring.c +++ b/lstring.c @@ -1,5 +1,5 @@ /* -** $Id: lstring.c,v 1.46 2000/11/24 17:39:56 roberto Exp roberto $ +** $Id: lstring.c,v 1.47 2000/12/22 16:57:46 roberto Exp roberto $ ** String table (keeps all strings handled by Lua) ** See Copyright Notice in lua.h */ @@ -15,32 +15,18 @@ #include "lstring.h" -/* -** type equivalent to TString, but with maximum alignment requirements -*/ -union L_UTString { - TString ts; - union L_Umaxalign dummy; /* ensures maximum alignment for `local' udata */ -}; - - void luaS_init (lua_State *L) { - L->strt.hash = luaM_newvector(L, 1, TString *); - L->udt.hash = luaM_newvector(L, 1, TString *); - L->nblocks += 2*sizeof(TString *); - L->strt.size = L->udt.size = 1; - L->strt.nuse = L->udt.nuse = 0; - L->strt.hash[0] = L->udt.hash[0] = NULL; + luaS_resize(L, &L->strt, MINPOWER2); + luaS_resize(L, &L->udt, MINPOWER2); } void luaS_freeall (lua_State *L) { LUA_ASSERT(L->strt.nuse==0, "non-empty string table"); - L->nblocks -= (L->strt.size + L->udt.size)*sizeof(TString *); - luaM_free(L, L->strt.hash); + luaM_freearray(L, L->strt.hash, L->strt.size, TString *); LUA_ASSERT(L->udt.nuse==0, "non-empty udata table"); - luaM_free(L, L->udt.hash); + luaM_freearray(L, L->udt.hash, L->udt.size, TString *); } @@ -71,9 +57,7 @@ void luaS_resize (lua_State *L, stringtable *tb, int newsize) { p = next; } } - luaM_free(L, tb->hash); - L->nblocks -= tb->size*sizeof(TString *); - L->nblocks += newsize*sizeof(TString *); + luaM_freearray(L, tb->hash, tb->size, TString *); tb->size = newsize; tb->hash = newhash; } @@ -106,23 +90,20 @@ TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { ts->u.s.constindex = 0; memcpy(ts->str, str, l); ts->str[l] = 0; /* ending 0 */ - L->nblocks += sizestring(l); newentry(L, &L->strt, ts, h1); /* insert it on table */ return ts; } TString *luaS_newudata (lua_State *L, size_t s, void *udata) { - union L_UTString *uts = (union L_UTString *)luaM_malloc(L, - (luint32)sizeof(union L_UTString)+s); + union L_UTString *uts = (union L_UTString *)luaM_malloc(L, sizeudata(s)); TString *ts = &uts->ts; ts->marked = 0; ts->nexthash = NULL; ts->len = s; ts->u.d.tag = 0; ts->u.d.value = (udata == NULL) ? uts+1 : udata; - L->nblocks += sizestring(s); - /* insert it on table */ + /* insert it on table */ newentry(L, &L->udt, ts, IntPoint(ts->u.d.value) & (L->udt.size-1)); return ts; } diff --git a/lstring.h b/lstring.h index af733b74..330d80e1 100644 --- a/lstring.h +++ b/lstring.h @@ -1,5 +1,5 @@ /* -** $Id: lstring.h,v 1.24 2000/10/30 17:49:19 roberto Exp roberto $ +** $Id: lstring.h,v 1.25 2000/11/24 17:39:56 roberto Exp roberto $ ** String table (keep all strings handled by Lua) ** See Copyright Notice in lua.h */ @@ -12,6 +12,17 @@ #include "lstate.h" + +/* +** type equivalent to TString, but with maximum alignment requirements +*/ +union L_UTString { + TString ts; + union L_Umaxalign dummy; /* ensures maximum alignment for `local' udata */ +}; + + + /* ** any TString with mark>=FIXMARK is never collected. ** Marks>=RESERVEDMARK are used to identify reserved words. @@ -23,6 +34,8 @@ #define sizestring(l) ((lint32)sizeof(TString) + \ ((lint32)(l+1)-TSPACK)*(lint32)sizeof(char)) +#define sizeudata(l) ((luint32)sizeof(union L_UTString)+(l)) + void luaS_init (lua_State *L); void luaS_resize (lua_State *L, stringtable *tb, int newsize); diff --git a/ltable.c b/ltable.c index 82f47808..1895029c 100644 --- a/ltable.c +++ b/ltable.c @@ -1,5 +1,5 @@ /* -** $Id: ltable.c,v 1.60 2000/12/04 18:33:40 roberto Exp roberto $ +** $Id: ltable.c,v 1.61 2000/12/22 16:57:46 roberto Exp roberto $ ** Lua tables (hash) ** See Copyright Notice in lua.h */ @@ -27,9 +27,6 @@ #include "ltable.h" -#define gcsize(L, n) (sizeof(Hash)+(n)*sizeof(Node)) - - #define TagDefault LUA_TTABLE @@ -167,8 +164,6 @@ static void setnodevector (lua_State *L, Hash *t, luint32 size) { ttype(&t->node[i].key) = ttype(&t->node[i].val) = LUA_TNIL; t->node[i].next = NULL; } - L->nblocks -= gcsize(L, t->size); /* old size */ - L->nblocks += gcsize(L, size); /* new size */ t->size = size; t->firstfree = &t->node[size-1]; /* first free position to be used */ } @@ -181,7 +176,6 @@ Hash *luaH_new (lua_State *L, int size) { L->roottable = t; t->mark = t; t->size = 0; - L->nblocks += gcsize(L, 0); t->node = NULL; setnodevector(L, t, luaO_power2(size)); return t; @@ -189,9 +183,8 @@ Hash *luaH_new (lua_State *L, int size) { void luaH_free (lua_State *L, Hash *t) { - L->nblocks -= gcsize(L, t->size); - luaM_free(L, t->node); - luaM_free(L, t); + luaM_freearray(L, t->node, t->size, Node); + luaM_freelem(L, t, Hash); } @@ -226,7 +219,7 @@ static void rehash (lua_State *L, Hash *t) { if (ttype(&old->val) != LUA_TNIL) *luaH_set(L, t, &old->key) = old->val; } - luaM_free(L, nold); /* free old array */ + luaM_freearray(L, nold, oldsize, Node); /* free old array */ } diff --git a/ltests.c b/ltests.c index a80a7977..ae0c71fc 100644 --- a/ltests.c +++ b/ltests.c @@ -1,5 +1,5 @@ /* -** $Id: ltests.c,v 1.53 2000/10/30 16:29:59 roberto Exp roberto $ +** $Id: ltests.c,v 1.54 2000/10/31 13:10:24 roberto Exp roberto $ ** Internal Module for Debugging of the Lua Implementation ** See Copyright Notice in lua.h */ @@ -116,7 +116,7 @@ static int liststrings (lua_State *L) { 1, "Lua function expected"); p = clvalue(luaA_index(L, 1))->f.l; lua_newtable(L); - for (i=0; inkstr; i++) { + for (i=0; isizekstr; i++) { lua_pushnumber(L, i+1); lua_pushstring(L, p->kstr[i]->str); lua_settable(L, -3); diff --git a/ltm.c b/ltm.c index 852dfd13..78cebeb2 100644 --- a/ltm.c +++ b/ltm.c @@ -1,5 +1,5 @@ /* -** $Id: ltm.c,v 1.57 2000/11/30 18:50:47 roberto Exp roberto $ +** $Id: ltm.c,v 1.58 2000/12/26 18:46:09 roberto Exp roberto $ ** Tag methods ** See Copyright Notice in lua.h */ @@ -75,9 +75,8 @@ static void init_entry (lua_State *L, int tag) { void luaT_init (lua_State *L) { int t; + L->TMtable = luaM_newvector(L, NUM_TAGS+2, struct TM); L->sizeTM = NUM_TAGS+2; - L->TMtable = luaM_newvector(L, L->sizeTM, struct TM); - L->nblocks += NUM_TAGS*sizeof(struct TM); L->ntag = NUM_TAGS; for (t=0; tntag; t++) init_entry(L, t); @@ -87,7 +86,6 @@ void luaT_init (lua_State *L) { LUA_API int lua_newtag (lua_State *L) { luaM_growvector(L, L->TMtable, L->ntag, L->sizeTM, struct TM, MAX_INT, "tag table overflow"); - L->nblocks += sizeof(struct TM); init_entry(L, L->ntag); return L->ntag++; } diff --git a/lundump.c b/lundump.c index b367fe36..04d062a0 100644 --- a/lundump.c +++ b/lundump.c @@ -1,5 +1,5 @@ /* -** $Id: lundump.c,v 1.34 2000/11/07 12:44:44 roberto Exp roberto $ +** $Id: lundump.c,v 1.35 2000/12/04 18:33:40 roberto Exp roberto $ ** load bytecodes from files ** See Copyright Notice in lua.h */ @@ -104,17 +104,17 @@ static TString* LoadString (lua_State* L, ZIO* Z, int swap) static void LoadCode (lua_State* L, Proto* tf, ZIO* Z, int swap) { - int size=LoadInt(L,Z,swap); + int size; + tf->sizecode=size=LoadInt(L,Z,swap); tf->code=luaM_newvector(L,size,Instruction); LoadVector(L,tf->code,size,sizeof(*tf->code),Z,swap); if (tf->code[size-1]!=OP_END) luaO_verror(L,"bad code in `%.99s'",ZNAME(Z)); - luaF_protook(L,tf,size); } static void LoadLocals (lua_State* L, Proto* tf, ZIO* Z, int swap) { int i,n; - tf->nlocvars=n=LoadInt(L,Z,swap); + tf->sizelocvars=n=LoadInt(L,Z,swap); tf->locvars=luaM_newvector(L,n,LocVar); for (i=0; inlineinfo=n=LoadInt(L,Z,swap); + tf->sizelineinfo=n=LoadInt(L,Z,swap); tf->lineinfo=luaM_newvector(L,n,int); LoadVector(L,tf->lineinfo,n,sizeof(*tf->lineinfo),Z,swap); } @@ -137,14 +137,14 @@ static Proto* LoadFunction (lua_State* L, ZIO* Z, int swap); static void LoadConstants (lua_State* L, Proto* tf, ZIO* Z, int swap) { int i,n; - tf->nkstr=n=LoadInt(L,Z,swap); + tf->sizekstr=n=LoadInt(L,Z,swap); tf->kstr=luaM_newvector(L,n,TString*); for (i=0; ikstr[i]=LoadString(L,Z,swap); - tf->nknum=n=LoadInt(L,Z,swap); + tf->sizeknum=n=LoadInt(L,Z,swap); tf->knum=luaM_newvector(L,n,lua_Number); LoadVector(L,tf->knum,n,sizeof(*tf->knum),Z,swap); - tf->nkproto=n=LoadInt(L,Z,swap); + tf->sizekproto=n=LoadInt(L,Z,swap); tf->kproto=luaM_newvector(L,n,Proto*); for (i=0; ikproto[i]=LoadFunction(L,Z,swap); diff --git a/lvm.c b/lvm.c index d49ed9e4..141d88f6 100644 --- a/lvm.c +++ b/lvm.c @@ -1,5 +1,5 @@ /* -** $Id: lvm.c,v 1.147 2000/11/24 17:39:56 roberto Exp roberto $ +** $Id: lvm.c,v 1.148 2000/12/04 18:33:40 roberto Exp roberto $ ** Lua virtual machine ** See Copyright Notice in lua.h */ @@ -35,7 +35,7 @@ ** Extra stack size to run a function: ** TAG_LINE(1), NAME(1), TM calls(3) (plus some extra...) */ -#define EXTRA_STACK 8 +#define EXTRA_FSTACK 8 @@ -355,7 +355,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { TString **const kstr = tf->kstr; const lua_Hook linehook = L->linehook; infovalue(base-1)->pc = &pc; - luaD_checkstack(L, tf->maxstacksize+EXTRA_STACK); + luaD_checkstack(L, tf->maxstacksize+EXTRA_FSTACK); if (tf->is_vararg) /* varargs? */ adjust_varargs(L, base, tf->numparams); else