diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2009-04-28 16:04:36 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2009-04-28 16:04:36 -0300 |
commit | e091a254dfe4521d837469d3ae7cc329e2df3376 (patch) | |
tree | 7ee2f1c83a9a07500b6826bb55f0f1e977785d02 /ldo.c | |
parent | 58c3aa8b5f51194980a9abf463a2648bb1413925 (diff) | |
download | lua-e091a254dfe4521d837469d3ae7cc329e2df3376.tar.gz lua-e091a254dfe4521d837469d3ae7cc329e2df3376.tar.bz2 lua-e091a254dfe4521d837469d3ae7cc329e2df3376.zip |
new way to GC stacks: the entire stack must be correct all the times;
the 'dead' part of a stack (after the top) must have only nil's, so
that 'top' may go up without cleaning the stack.
Diffstat (limited to 'ldo.c')
-rw-r--r-- | ldo.c | 26 |
1 files changed, 14 insertions, 12 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldo.c,v 2.61 2009/04/17 22:00:01 roberto Exp roberto $ | 2 | ** $Id: ldo.c,v 2.62 2009/04/26 21:55:35 roberto Exp roberto $ |
3 | ** Stack and Call structure of Lua | 3 | ** Stack and Call structure of Lua |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -131,9 +131,12 @@ static void correctstack (lua_State *L, TValue *oldstack) { | |||
131 | 131 | ||
132 | void luaD_reallocstack (lua_State *L, int newsize) { | 132 | void luaD_reallocstack (lua_State *L, int newsize) { |
133 | TValue *oldstack = L->stack; | 133 | TValue *oldstack = L->stack; |
134 | int lim = L->stacksize; | ||
134 | int realsize = newsize + 1 + EXTRA_STACK; | 135 | int realsize = newsize + 1 + EXTRA_STACK; |
135 | lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1); | 136 | lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1); |
136 | luaM_reallocvector(L, L->stack, L->stacksize, realsize, TValue); | 137 | luaM_reallocvector(L, L->stack, L->stacksize, realsize, TValue); |
138 | for (; lim < realsize; lim++) | ||
139 | setnilvalue(L->stack + lim); /* erase new segment */ | ||
137 | L->stacksize = realsize; | 140 | L->stacksize = realsize; |
138 | L->stack_last = L->stack+newsize; | 141 | L->stack_last = L->stack+newsize; |
139 | correctstack(L, oldstack); | 142 | correctstack(L, oldstack); |
@@ -182,14 +185,13 @@ static StkId adjust_varargs (lua_State *L, Proto *p, int actual) { | |||
182 | int i; | 185 | int i; |
183 | int nfixargs = p->numparams; | 186 | int nfixargs = p->numparams; |
184 | StkId base, fixed; | 187 | StkId base, fixed; |
185 | for (; actual < nfixargs; ++actual) | 188 | lua_assert(actual >= nfixargs); |
186 | setnilvalue(L->top++); | ||
187 | /* move fixed parameters to final position */ | 189 | /* move fixed parameters to final position */ |
188 | fixed = L->top - actual; /* first fixed argument */ | 190 | fixed = L->top - actual; /* first fixed argument */ |
189 | base = L->top; /* final position of first argument */ | 191 | base = L->top; /* final position of first argument */ |
190 | for (i=0; i<nfixargs; i++) { | 192 | for (i=0; i<nfixargs; i++) { |
191 | setobjs2s(L, L->top++, fixed+i); | 193 | setobjs2s(L, L->top++, fixed + i); |
192 | setnilvalue(fixed+i); | 194 | setnilvalue(fixed + i); |
193 | } | 195 | } |
194 | return base; | 196 | return base; |
195 | } | 197 | } |
@@ -227,17 +229,19 @@ int luaD_precall (lua_State *L, StkId func, int nresults) { | |||
227 | L->ci->nresults = nresults; | 229 | L->ci->nresults = nresults; |
228 | if (!cl->isC) { /* Lua function? prepare its call */ | 230 | if (!cl->isC) { /* Lua function? prepare its call */ |
229 | CallInfo *ci; | 231 | CallInfo *ci; |
230 | StkId st, base; | 232 | int nparams, nargs; |
233 | StkId base; | ||
231 | Proto *p = cl->p; | 234 | Proto *p = cl->p; |
232 | luaD_checkstack(L, p->maxstacksize); | 235 | luaD_checkstack(L, p->maxstacksize); |
233 | func = restorestack(L, funcr); | 236 | func = restorestack(L, funcr); |
237 | nargs = cast_int(L->top - func) - 1; /* number of real arguments */ | ||
238 | nparams = p->numparams; /* number of expected parameters */ | ||
239 | for (; nargs < nparams; nargs++) | ||
240 | setnilvalue(L->top++); /* complete missing arguments */ | ||
234 | if (!p->is_vararg) /* no varargs? */ | 241 | if (!p->is_vararg) /* no varargs? */ |
235 | base = func + 1; | 242 | base = func + 1; |
236 | else { /* vararg function */ | 243 | else /* vararg function */ |
237 | int nargs = cast_int(L->top - func) - 1; | ||
238 | base = adjust_varargs(L, p, nargs); | 244 | base = adjust_varargs(L, p, nargs); |
239 | func = restorestack(L, funcr); /* previous call may change the stack */ | ||
240 | } | ||
241 | ci = next_ci(L); /* now 'enter' new function */ | 245 | ci = next_ci(L); /* now 'enter' new function */ |
242 | ci->func = func; | 246 | ci->func = func; |
243 | L->base = ci->base = base; | 247 | L->base = ci->base = base; |
@@ -246,8 +250,6 @@ int luaD_precall (lua_State *L, StkId func, int nresults) { | |||
246 | ci->u.l.savedpc = p->code; /* starting point */ | 250 | ci->u.l.savedpc = p->code; /* starting point */ |
247 | ci->u.l.tailcalls = 0; | 251 | ci->u.l.tailcalls = 0; |
248 | ci->callstatus = CIST_LUA; | 252 | ci->callstatus = CIST_LUA; |
249 | for (st = L->top; st < ci->top; st++) | ||
250 | setnilvalue(st); | ||
251 | L->top = ci->top; | 253 | L->top = ci->top; |
252 | if (L->hookmask & LUA_MASKCALL) { | 254 | if (L->hookmask & LUA_MASKCALL) { |
253 | ci->u.l.savedpc++; /* hooks assume 'pc' is already incremented */ | 255 | ci->u.l.savedpc++; /* hooks assume 'pc' is already incremented */ |