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 */ |
