diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2009-04-17 11:28:06 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2009-04-17 11:28:06 -0300 |
| commit | 4f88418170d298b065a7f71d86b1127153919ae9 (patch) | |
| tree | 7e9c403890b4fe7ac13d501242cfdd967bf0285e | |
| parent | 311e9f3ceb19eefe30a1b5f90dfad9898d8bac74 (diff) | |
| download | lua-4f88418170d298b065a7f71d86b1127153919ae9.tar.gz lua-4f88418170d298b065a7f71d86b1127153919ae9.tar.bz2 lua-4f88418170d298b065a7f71d86b1127153919ae9.zip | |
'CallInfo' stack implemented as double-linked list instead of an array
| -rw-r--r-- | lapi.c | 6 | ||||
| -rw-r--r-- | ldebug.c | 24 | ||||
| -rw-r--r-- | ldo.c | 69 | ||||
| -rw-r--r-- | ldo.h | 5 | ||||
| -rw-r--r-- | lgc.c | 39 | ||||
| -rw-r--r-- | lstate.c | 61 | ||||
| -rw-r--r-- | lstate.h | 13 | ||||
| -rw-r--r-- | ltests.c | 18 | ||||
| -rw-r--r-- | lua.h | 4 | ||||
| -rw-r--r-- | lvm.c | 14 |
10 files changed, 127 insertions, 126 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lapi.c,v 2.73 2009/03/30 18:39:20 roberto Exp roberto $ | 2 | ** $Id: lapi.c,v 2.74 2009/04/08 18:04:33 roberto Exp roberto $ |
| 3 | ** Lua API | 3 | ** Lua API |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -72,7 +72,7 @@ static TValue *index2adr (lua_State *L, int idx) { | |||
| 72 | 72 | ||
| 73 | 73 | ||
| 74 | static Table *getcurrenv (lua_State *L) { | 74 | static Table *getcurrenv (lua_State *L) { |
| 75 | if (L->ci == L->base_ci) /* no enclosing function? */ | 75 | if (L->ci->previous == NULL) /* no enclosing function? */ |
| 76 | return hvalue(gt(L)); /* use global table as environment */ | 76 | return hvalue(gt(L)); /* use global table as environment */ |
| 77 | else { | 77 | else { |
| 78 | Closure *func = curr_func(L); | 78 | Closure *func = curr_func(L); |
| @@ -185,7 +185,7 @@ LUA_API void lua_replace (lua_State *L, int idx) { | |||
| 185 | StkId o; | 185 | StkId o; |
| 186 | lua_lock(L); | 186 | lua_lock(L); |
| 187 | /* explicit test for incompatible code */ | 187 | /* explicit test for incompatible code */ |
| 188 | if (idx == LUA_ENVIRONINDEX && L->ci == L->base_ci) | 188 | if (idx == LUA_ENVIRONINDEX && L->ci->previous == NULL) |
| 189 | luaG_runerror(L, "no calling environment"); | 189 | luaG_runerror(L, "no calling environment"); |
| 190 | api_checknelems(L, 1); | 190 | api_checknelems(L, 1); |
| 191 | o = index2adr(L, idx); | 191 | o = index2adr(L, idx); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ldebug.c,v 2.44 2009/03/10 17:14:37 roberto Exp roberto $ | 2 | ** $Id: ldebug.c,v 2.45 2009/03/26 12:56:38 roberto Exp roberto $ |
| 3 | ** Debug Interface | 3 | ** Debug Interface |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -86,18 +86,18 @@ LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) { | |||
| 86 | int status; | 86 | int status; |
| 87 | CallInfo *ci; | 87 | CallInfo *ci; |
| 88 | lua_lock(L); | 88 | lua_lock(L); |
| 89 | for (ci = L->ci; level > 0 && ci > L->base_ci; ci--) { | 89 | for (ci = L->ci; level > 0 && ci != &L->base_ci; ci = ci->previous) { |
| 90 | level--; | 90 | level--; |
| 91 | if (isLua(ci)) /* Lua function? */ | 91 | if (isLua(ci)) /* Lua function? */ |
| 92 | level -= ci->u.l.tailcalls; /* skip lost tail calls */ | 92 | level -= ci->u.l.tailcalls; /* skip lost tail calls */ |
| 93 | } | 93 | } |
| 94 | if (level == 0 && ci > L->base_ci) { /* level found? */ | 94 | if (level == 0 && ci != &L->base_ci) { /* level found? */ |
| 95 | status = 1; | 95 | status = 1; |
| 96 | ar->i_ci = cast_int(ci - L->base_ci); | 96 | ar->i_ci = ci; |
| 97 | } | 97 | } |
| 98 | else if (level < 0) { /* level is of a lost tail call? */ | 98 | else if (level < 0) { /* level is of a lost tail call? */ |
| 99 | status = 1; | 99 | status = 1; |
| 100 | ar->i_ci = 0; | 100 | ar->i_ci = NULL; |
| 101 | } | 101 | } |
| 102 | else status = 0; /* no such level */ | 102 | else status = 0; /* no such level */ |
| 103 | lua_unlock(L); | 103 | lua_unlock(L); |
| @@ -116,7 +116,7 @@ static const char *findlocal (lua_State *L, CallInfo *ci, int n) { | |||
| 116 | if (fp && (name = luaF_getlocalname(fp, n, currentpc(L, ci))) != NULL) | 116 | if (fp && (name = luaF_getlocalname(fp, n, currentpc(L, ci))) != NULL) |
| 117 | return name; /* is a local variable in a Lua function */ | 117 | return name; /* is a local variable in a Lua function */ |
| 118 | else { | 118 | else { |
| 119 | StkId limit = (ci == L->ci) ? L->top : (ci+1)->func; | 119 | StkId limit = (ci == L->ci) ? L->top : ci->next->func; |
| 120 | if (limit - ci->base >= n && n > 0) /* is 'n' inside 'ci' stack? */ | 120 | if (limit - ci->base >= n && n > 0) /* is 'n' inside 'ci' stack? */ |
| 121 | return "(*temporary)"; | 121 | return "(*temporary)"; |
| 122 | else | 122 | else |
| @@ -126,7 +126,7 @@ static const char *findlocal (lua_State *L, CallInfo *ci, int n) { | |||
| 126 | 126 | ||
| 127 | 127 | ||
| 128 | LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) { | 128 | LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) { |
| 129 | CallInfo *ci = L->base_ci + ar->i_ci; | 129 | CallInfo *ci = ar->i_ci; |
| 130 | const char *name = findlocal(L, ci, n); | 130 | const char *name = findlocal(L, ci, n); |
| 131 | lua_lock(L); | 131 | lua_lock(L); |
| 132 | if (name) { | 132 | if (name) { |
| @@ -139,7 +139,7 @@ LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) { | |||
| 139 | 139 | ||
| 140 | 140 | ||
| 141 | LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) { | 141 | LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) { |
| 142 | CallInfo *ci = L->base_ci + ar->i_ci; | 142 | CallInfo *ci = ar->i_ci; |
| 143 | const char *name = findlocal(L, ci, n); | 143 | const char *name = findlocal(L, ci, n); |
| 144 | lua_lock(L); | 144 | lua_lock(L); |
| 145 | if (name) | 145 | if (name) |
| @@ -246,8 +246,8 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { | |||
| 246 | f = clvalue(func); | 246 | f = clvalue(func); |
| 247 | L->top--; /* pop function */ | 247 | L->top--; /* pop function */ |
| 248 | } | 248 | } |
| 249 | else if (ar->i_ci != 0) { /* no tail call? */ | 249 | else if (ar->i_ci != NULL) { /* no tail call? */ |
| 250 | ci = L->base_ci + ar->i_ci; | 250 | ci = ar->i_ci; |
| 251 | lua_assert(ttisfunction(ci->func)); | 251 | lua_assert(ttisfunction(ci->func)); |
| 252 | f = clvalue(ci->func); | 252 | f = clvalue(ci->func); |
| 253 | } | 253 | } |
| @@ -525,9 +525,9 @@ static const char *getobjname (lua_State *L, CallInfo *ci, int stackpos, | |||
| 525 | static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) { | 525 | static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) { |
| 526 | TMS tm = 0; | 526 | TMS tm = 0; |
| 527 | Instruction i; | 527 | Instruction i; |
| 528 | if ((isLua(ci) && ci->u.l.tailcalls > 0) || !isLua(ci - 1)) | 528 | if ((isLua(ci) && ci->u.l.tailcalls > 0) || !isLua(ci->previous)) |
| 529 | return NULL; /* calling function is not Lua (or is unknown) */ | 529 | return NULL; /* calling function is not Lua (or is unknown) */ |
| 530 | ci--; /* calling function */ | 530 | ci = ci->previous; /* calling function */ |
| 531 | i = ci_func(ci)->l.p->code[currentpc(L, ci)]; | 531 | i = ci_func(ci)->l.p->code[currentpc(L, ci)]; |
| 532 | switch (GET_OPCODE(i)) { | 532 | switch (GET_OPCODE(i)) { |
| 533 | case OP_CALL: | 533 | case OP_CALL: |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ldo.c,v 2.58 2009/04/08 18:04:33 roberto Exp roberto $ | 2 | ** $Id: ldo.c,v 2.59 2009/04/15 16:53:39 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 | */ |
| @@ -70,12 +70,8 @@ void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop) { | |||
| 70 | 70 | ||
| 71 | 71 | ||
| 72 | static void restore_stack_limit (lua_State *L) { | 72 | static void restore_stack_limit (lua_State *L) { |
| 73 | lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1); | 73 | if (L->nci >= LUAI_MAXCALLS) /* stack overflow? */ |
| 74 | if (L->size_ci > LUAI_MAXCALLS) { /* there was an overflow? */ | 74 | luaE_freeCI(L); /* erase all extras CIs */ |
| 75 | int inuse = cast_int(L->ci - L->base_ci); | ||
| 76 | if (inuse + 1 < LUAI_MAXCALLS) /* can `undo' overflow? */ | ||
| 77 | luaD_reallocCI(L, LUAI_MAXCALLS); | ||
| 78 | } | ||
| 79 | } | 75 | } |
| 80 | 76 | ||
| 81 | 77 | ||
| @@ -124,7 +120,7 @@ static void correctstack (lua_State *L, TValue *oldstack) { | |||
| 124 | L->top = (L->top - oldstack) + L->stack; | 120 | L->top = (L->top - oldstack) + L->stack; |
| 125 | for (up = L->openupval; up != NULL; up = up->gch.next) | 121 | for (up = L->openupval; up != NULL; up = up->gch.next) |
| 126 | gco2uv(up)->v = (gco2uv(up)->v - oldstack) + L->stack; | 122 | gco2uv(up)->v = (gco2uv(up)->v - oldstack) + L->stack; |
| 127 | for (ci = L->base_ci; ci <= L->ci; ci++) { | 123 | for (ci = L->ci; ci != NULL; ci = ci->previous) { |
| 128 | ci->top = (ci->top - oldstack) + L->stack; | 124 | ci->top = (ci->top - oldstack) + L->stack; |
| 129 | ci->base = (ci->base - oldstack) + L->stack; | 125 | ci->base = (ci->base - oldstack) + L->stack; |
| 130 | ci->func = (ci->func - oldstack) + L->stack; | 126 | ci->func = (ci->func - oldstack) + L->stack; |
| @@ -144,15 +140,6 @@ void luaD_reallocstack (lua_State *L, int newsize) { | |||
| 144 | } | 140 | } |
| 145 | 141 | ||
| 146 | 142 | ||
| 147 | void luaD_reallocCI (lua_State *L, int newsize) { | ||
| 148 | CallInfo *oldci = L->base_ci; | ||
| 149 | luaM_reallocvector(L, L->base_ci, L->size_ci, newsize, CallInfo); | ||
| 150 | L->size_ci = newsize; | ||
| 151 | L->ci = (L->ci - oldci) + L->base_ci; | ||
| 152 | L->end_ci = L->base_ci + L->size_ci - 1; | ||
| 153 | } | ||
| 154 | |||
| 155 | |||
| 156 | void luaD_growstack (lua_State *L, int n) { | 143 | void luaD_growstack (lua_State *L, int n) { |
| 157 | if (n <= L->stacksize) /* double size is enough? */ | 144 | if (n <= L->stacksize) /* double size is enough? */ |
| 158 | luaD_reallocstack(L, 2*L->stacksize); | 145 | luaD_reallocstack(L, 2*L->stacksize); |
| @@ -161,18 +148,6 @@ void luaD_growstack (lua_State *L, int n) { | |||
| 161 | } | 148 | } |
| 162 | 149 | ||
| 163 | 150 | ||
| 164 | static CallInfo *growCI (lua_State *L) { | ||
| 165 | if (L->size_ci > LUAI_MAXCALLS) /* overflow while handling overflow? */ | ||
| 166 | luaD_throw(L, LUA_ERRERR); | ||
| 167 | else { | ||
| 168 | luaD_reallocCI(L, 2*L->size_ci); | ||
| 169 | if (L->size_ci > LUAI_MAXCALLS) | ||
| 170 | luaG_runerror(L, "stack overflow"); | ||
| 171 | } | ||
| 172 | return ++L->ci; | ||
| 173 | } | ||
| 174 | |||
| 175 | |||
| 176 | void luaD_callhook (lua_State *L, int event, int line) { | 151 | void luaD_callhook (lua_State *L, int event, int line) { |
| 177 | lua_Hook hook = L->hook; | 152 | lua_Hook hook = L->hook; |
| 178 | if (hook && L->allowhook) { | 153 | if (hook && L->allowhook) { |
| @@ -182,9 +157,9 @@ void luaD_callhook (lua_State *L, int event, int line) { | |||
| 182 | ar.event = event; | 157 | ar.event = event; |
| 183 | ar.currentline = line; | 158 | ar.currentline = line; |
| 184 | if (event == LUA_HOOKTAILRET) | 159 | if (event == LUA_HOOKTAILRET) |
| 185 | ar.i_ci = 0; /* tail call; no debug information about it */ | 160 | ar.i_ci = NULL; /* tail call; no debug information about it */ |
| 186 | else | 161 | else |
| 187 | ar.i_ci = cast_int(L->ci - L->base_ci); | 162 | ar.i_ci = L->ci; |
| 188 | luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ | 163 | luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ |
| 189 | L->ci->top = L->top + LUA_MINSTACK; | 164 | L->ci->top = L->top + LUA_MINSTACK; |
| 190 | lua_assert(L->ci->top <= L->stack_last); | 165 | lua_assert(L->ci->top <= L->stack_last); |
| @@ -235,9 +210,7 @@ static StkId tryfuncTM (lua_State *L, StkId func) { | |||
| 235 | 210 | ||
| 236 | 211 | ||
| 237 | 212 | ||
| 238 | #define inc_ci(L) \ | 213 | #define next_ci(L) (L->ci = (L->ci->next ? L->ci->next : luaE_extendCI(L))) |
| 239 | ((L->ci == L->end_ci) ? growCI(L) : \ | ||
| 240 | (condhardstacktests(luaD_reallocCI(L, L->size_ci)), ++L->ci)) | ||
| 241 | 214 | ||
| 242 | 215 | ||
| 243 | /* | 216 | /* |
| @@ -265,7 +238,7 @@ int luaD_precall (lua_State *L, StkId func, int nresults) { | |||
| 265 | base = adjust_varargs(L, p, nargs); | 238 | base = adjust_varargs(L, p, nargs); |
| 266 | func = restorestack(L, funcr); /* previous call may change the stack */ | 239 | func = restorestack(L, funcr); /* previous call may change the stack */ |
| 267 | } | 240 | } |
| 268 | ci = inc_ci(L); /* now `enter' new function */ | 241 | ci = next_ci(L); /* now 'enter' new function */ |
| 269 | ci->func = func; | 242 | ci->func = func; |
| 270 | L->base = ci->base = base; | 243 | L->base = ci->base = base; |
| 271 | ci->top = L->base + p->maxstacksize; | 244 | ci->top = L->base + p->maxstacksize; |
| @@ -287,7 +260,7 @@ int luaD_precall (lua_State *L, StkId func, int nresults) { | |||
| 287 | CallInfo *ci; | 260 | CallInfo *ci; |
| 288 | int n; | 261 | int n; |
| 289 | luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ | 262 | luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ |
| 290 | ci = inc_ci(L); /* now `enter' new function */ | 263 | ci = next_ci(L); /* now 'enter' new function */ |
| 291 | ci->func = restorestack(L, funcr); | 264 | ci->func = restorestack(L, funcr); |
| 292 | L->base = ci->base = ci->func + 1; | 265 | L->base = ci->base = ci->func + 1; |
| 293 | ci->top = L->top + LUA_MINSTACK; | 266 | ci->top = L->top + LUA_MINSTACK; |
| @@ -318,17 +291,17 @@ static StkId callrethooks (lua_State *L, StkId firstResult) { | |||
| 318 | int luaD_poscall (lua_State *L, StkId firstResult) { | 291 | int luaD_poscall (lua_State *L, StkId firstResult) { |
| 319 | StkId res; | 292 | StkId res; |
| 320 | int wanted, i; | 293 | int wanted, i; |
| 321 | CallInfo *ci; | 294 | CallInfo *ci = L->ci; |
| 322 | if (L->hookmask & (LUA_MASKRET | LUA_MASKLINE)) { | 295 | if (L->hookmask & (LUA_MASKRET | LUA_MASKLINE)) { |
| 323 | if (L->hookmask & LUA_MASKRET) | 296 | if (L->hookmask & LUA_MASKRET) |
| 324 | firstResult = callrethooks(L, firstResult); | 297 | firstResult = callrethooks(L, firstResult); |
| 325 | L->oldpc = (L->ci - 1)->savedpc; /* set 'oldpc' for returning function */ | 298 | L->oldpc = L->ci->previous->savedpc; /* 'oldpc' for returning function */ |
| 326 | } | 299 | } |
| 327 | ci = L->ci--; | ||
| 328 | res = ci->func; /* res == final position of 1st result */ | 300 | res = ci->func; /* res == final position of 1st result */ |
| 329 | wanted = (ci - 1)->nresults; | 301 | L->ci = ci = L->ci->previous; /* back to caller */ |
| 330 | L->base = (ci - 1)->base; /* restore base */ | 302 | wanted = ci->nresults; |
| 331 | L->savedpc = (ci - 1)->savedpc; /* restore savedpc */ | 303 | L->base = ci->base; /* restore base */ |
| 304 | L->savedpc = ci->savedpc; /* restore savedpc */ | ||
| 332 | /* move results to correct place */ | 305 | /* move results to correct place */ |
| 333 | for (i = wanted; i != 0 && firstResult < L->top; i--) | 306 | for (i = wanted; i != 0 && firstResult < L->top; i--) |
| 334 | setobjs2s(L, res++, firstResult++); | 307 | setobjs2s(L, res++, firstResult++); |
| @@ -387,7 +360,7 @@ static void finishCcall (lua_State *L) { | |||
| 387 | static void unroll (lua_State *L, void *ud) { | 360 | static void unroll (lua_State *L, void *ud) { |
| 388 | UNUSED(ud); | 361 | UNUSED(ud); |
| 389 | for (;;) { | 362 | for (;;) { |
| 390 | if (L->ci == L->base_ci) /* stack is empty? */ | 363 | if (L->ci == &L->base_ci) /* stack is empty? */ |
| 391 | return; /* coroutine finished normally */ | 364 | return; /* coroutine finished normally */ |
| 392 | if (!isLua(L->ci)) /* C function? */ | 365 | if (!isLua(L->ci)) /* C function? */ |
| 393 | finishCcall(L); | 366 | finishCcall(L); |
| @@ -403,7 +376,7 @@ static void resume (lua_State *L, void *ud) { | |||
| 403 | StkId firstArg = cast(StkId, ud); | 376 | StkId firstArg = cast(StkId, ud); |
| 404 | CallInfo *ci = L->ci; | 377 | CallInfo *ci = L->ci; |
| 405 | if (L->status == LUA_OK) { /* start coroutine? */ | 378 | if (L->status == LUA_OK) { /* start coroutine? */ |
| 406 | lua_assert(ci == L->base_ci && firstArg > L->base); | 379 | lua_assert(ci == &L->base_ci && firstArg > L->base); |
| 407 | if (!luaD_precall(L, firstArg - 1, LUA_MULTRET)) /* Lua function? */ | 380 | if (!luaD_precall(L, firstArg - 1, LUA_MULTRET)) /* Lua function? */ |
| 408 | luaV_execute(L); /* call it */ | 381 | luaV_execute(L); /* call it */ |
| 409 | } | 382 | } |
| @@ -437,7 +410,7 @@ static int resume_error (lua_State *L, const char *msg) { | |||
| 437 | */ | 410 | */ |
| 438 | static CallInfo *findpcall (lua_State *L) { | 411 | static CallInfo *findpcall (lua_State *L) { |
| 439 | CallInfo *ci; | 412 | CallInfo *ci; |
| 440 | for (ci = L->ci; ci > L->base_ci; ci--) { /* search for first pcall */ | 413 | for (ci = L->ci; ci != NULL; ci = ci->previous) { /* search for a pcall */ |
| 441 | if (ci->callstatus & CIST_YPCALL) | 414 | if (ci->callstatus & CIST_YPCALL) |
| 442 | return ci; | 415 | return ci; |
| 443 | } | 416 | } |
| @@ -471,7 +444,7 @@ LUA_API int lua_resume (lua_State *L, int nargs) { | |||
| 471 | if (L->status != LUA_YIELD) { | 444 | if (L->status != LUA_YIELD) { |
| 472 | if (L->status != LUA_OK) | 445 | if (L->status != LUA_OK) |
| 473 | return resume_error(L, "cannot resume dead coroutine"); | 446 | return resume_error(L, "cannot resume dead coroutine"); |
| 474 | else if (L->ci != L->base_ci) | 447 | else if (L->ci != &L->base_ci) |
| 475 | return resume_error(L, "cannot resume non-suspended coroutine"); | 448 | return resume_error(L, "cannot resume non-suspended coroutine"); |
| 476 | } | 449 | } |
| 477 | luai_userstateresume(L, nargs); | 450 | luai_userstateresume(L, nargs); |
| @@ -515,7 +488,7 @@ LUA_API int lua_yield (lua_State *L, int nresults) { | |||
| 515 | int luaD_pcall (lua_State *L, Pfunc func, void *u, | 488 | int luaD_pcall (lua_State *L, Pfunc func, void *u, |
| 516 | ptrdiff_t old_top, ptrdiff_t ef) { | 489 | ptrdiff_t old_top, ptrdiff_t ef) { |
| 517 | int status; | 490 | int status; |
| 518 | ptrdiff_t old_ci = saveci(L, L->ci); | 491 | CallInfo *old_ci = L->ci; |
| 519 | lu_byte old_allowhooks = L->allowhook; | 492 | lu_byte old_allowhooks = L->allowhook; |
| 520 | unsigned short old_nny = L->nny; | 493 | unsigned short old_nny = L->nny; |
| 521 | ptrdiff_t old_errfunc = L->errfunc; | 494 | ptrdiff_t old_errfunc = L->errfunc; |
| @@ -525,7 +498,7 @@ int luaD_pcall (lua_State *L, Pfunc func, void *u, | |||
| 525 | StkId oldtop = restorestack(L, old_top); | 498 | StkId oldtop = restorestack(L, old_top); |
| 526 | luaF_close(L, oldtop); /* close possible pending closures */ | 499 | luaF_close(L, oldtop); /* close possible pending closures */ |
| 527 | luaD_seterrorobj(L, status, oldtop); | 500 | luaD_seterrorobj(L, status, oldtop); |
| 528 | L->ci = restoreci(L, old_ci); | 501 | L->ci = old_ci; |
| 529 | L->base = L->ci->base; | 502 | L->base = L->ci->base; |
| 530 | L->savedpc = L->ci->savedpc; | 503 | L->savedpc = L->ci->savedpc; |
| 531 | L->allowhook = old_allowhooks; | 504 | L->allowhook = old_allowhooks; |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ldo.h,v 2.10 2008/08/13 17:02:42 roberto Exp roberto $ | 2 | ** $Id: ldo.h,v 2.11 2009/03/10 17:14:37 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 | */ |
| @@ -24,9 +24,6 @@ | |||
| 24 | #define savestack(L,p) ((char *)(p) - (char *)L->stack) | 24 | #define savestack(L,p) ((char *)(p) - (char *)L->stack) |
| 25 | #define restorestack(L,n) ((TValue *)((char *)L->stack + (n))) | 25 | #define restorestack(L,n) ((TValue *)((char *)L->stack + (n))) |
| 26 | 26 | ||
| 27 | #define saveci(L,p) ((char *)(p) - (char *)L->base_ci) | ||
| 28 | #define restoreci(L,n) ((CallInfo *)((char *)L->base_ci + (n))) | ||
| 29 | |||
| 30 | 27 | ||
| 31 | /* type of protected functions, to be ran by `runprotected' */ | 28 | /* type of protected functions, to be ran by `runprotected' */ |
| 32 | typedef void (*Pfunc) (lua_State *L, void *ud); | 29 | typedef void (*Pfunc) (lua_State *L, void *ud); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lgc.c,v 2.48 2009/02/17 19:47:58 roberto Exp roberto $ | 2 | ** $Id: lgc.c,v 2.49 2009/03/10 17:14:37 roberto Exp roberto $ |
| 3 | ** Garbage Collector | 3 | ** Garbage Collector |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -379,38 +379,34 @@ static void traverseclosure (global_State *g, Closure *cl) { | |||
| 379 | } | 379 | } |
| 380 | 380 | ||
| 381 | 381 | ||
| 382 | static void checkstacksizes (lua_State *L, StkId max) { | 382 | static void checkstacksize (lua_State *L, StkId max) { |
| 383 | /* should not change the stack when handling overflow or | 383 | /* should not change the stack during an emergency gc cycle */ |
| 384 | during an emergency gc cycle */ | 384 | if (G(L)->gckind == KGC_EMERGENCY) |
| 385 | if (L->size_ci > LUAI_MAXCALLS || G(L)->gckind == KGC_EMERGENCY) | 385 | return; /* do not touch the stack */ |
| 386 | return; /* do not touch the stacks */ | ||
| 387 | else { | 386 | else { |
| 388 | int ci_used = cast_int(L->ci - L->base_ci) + 1; /* number of `ci' in use */ | ||
| 389 | int s_used = cast_int(max - L->stack) + 1; /* part of stack in use */ | 387 | int s_used = cast_int(max - L->stack) + 1; /* part of stack in use */ |
| 390 | if (2*ci_used < L->size_ci) | ||
| 391 | luaD_reallocCI(L, 2*ci_used); | ||
| 392 | if (2*s_used < (L->stacksize - EXTRA_STACK)) | 388 | if (2*s_used < (L->stacksize - EXTRA_STACK)) |
| 393 | luaD_reallocstack(L, 2*s_used); | 389 | luaD_reallocstack(L, 2*s_used); |
| 394 | } | 390 | } |
| 395 | } | 391 | } |
| 396 | 392 | ||
| 397 | 393 | ||
| 398 | static void traversestack (global_State *g, lua_State *l) { | 394 | static void traversestack (global_State *g, lua_State *L) { |
| 399 | StkId o, lim; | 395 | StkId o, lim; |
| 400 | CallInfo *ci; | 396 | CallInfo *ci; |
| 401 | if (l->stack == NULL || l->base_ci == NULL) | 397 | if (L->stack == NULL) |
| 402 | return; /* stack not completely built yet */ | 398 | return; /* stack not completely built yet */ |
| 403 | markvalue(g, gt(l)); | 399 | markvalue(g, gt(L)); |
| 404 | lim = l->top; | 400 | lim = L->top; |
| 405 | for (ci = l->base_ci; ci <= l->ci; ci++) { | 401 | for (ci = L->ci; ci != NULL; ci = ci->previous) { |
| 406 | lua_assert(ci->top <= l->stack_last); | 402 | lua_assert(ci->top <= L->stack_last); |
| 407 | if (lim < ci->top) lim = ci->top; | 403 | if (lim < ci->top) lim = ci->top; |
| 408 | } | 404 | } |
| 409 | for (o = l->stack; o < l->top; o++) | 405 | for (o = L->stack; o < L->top; o++) |
| 410 | markvalue(g, o); | 406 | markvalue(g, o); |
| 411 | for (; o <= lim; o++) | 407 | for (; o <= lim; o++) |
| 412 | setnilvalue(o); | 408 | setnilvalue(o); |
| 413 | checkstacksizes(l, lim); | 409 | checkstacksize(L, lim); |
| 414 | } | 410 | } |
| 415 | 411 | ||
| 416 | 412 | ||
| @@ -445,7 +441,7 @@ static l_mem propagatemark (global_State *g) { | |||
| 445 | black2gray(o); | 441 | black2gray(o); |
| 446 | traversestack(g, th); | 442 | traversestack(g, th); |
| 447 | return sizeof(lua_State) + sizeof(TValue) * th->stacksize + | 443 | return sizeof(lua_State) + sizeof(TValue) * th->stacksize + |
| 448 | sizeof(CallInfo) * th->size_ci; | 444 | sizeof(CallInfo) * th->nci; |
| 449 | } | 445 | } |
| 450 | case LUA_TPROTO: { | 446 | case LUA_TPROTO: { |
| 451 | Proto *p = gco2p(o); | 447 | Proto *p = gco2p(o); |
| @@ -554,8 +550,11 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) { | |||
| 554 | global_State *g = G(L); | 550 | global_State *g = G(L); |
| 555 | int deadmask = otherwhite(g); | 551 | int deadmask = otherwhite(g); |
| 556 | while ((curr = *p) != NULL && count-- > 0) { | 552 | while ((curr = *p) != NULL && count-- > 0) { |
| 557 | if (ttisthread(gch(curr))) /* sweep open upvalues of each thread */ | 553 | if (ttisthread(gch(curr))) { |
| 558 | sweepwholelist(L, &gco2th(curr)->openupval); | 554 | lua_State *L1 = gco2th(curr); |
| 555 | sweepwholelist(L, &L1->openupval); /* sweep open upvalues */ | ||
| 556 | luaE_freeCI(L1); /* free extra CallInfo slots */ | ||
| 557 | } | ||
| 559 | if ((gch(curr)->marked ^ WHITEBITS) & deadmask) { /* not dead? */ | 558 | if ((gch(curr)->marked ^ WHITEBITS) & deadmask) { /* not dead? */ |
| 560 | lua_assert(!isdead(g, curr) || testbit(gch(curr)->marked, FIXEDBIT)); | 559 | lua_assert(!isdead(g, curr) || testbit(gch(curr)->marked, FIXEDBIT)); |
| 561 | makewhite(g, curr); /* make it white (for next cycle) */ | 560 | makewhite(g, curr); /* make it white (for next cycle) */ |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lstate.c,v 2.49 2009/02/18 17:20:56 roberto Exp roberto $ | 2 | ** $Id: lstate.c,v 2.50 2009/03/10 17:14:37 roberto Exp roberto $ |
| 3 | ** Global State | 3 | ** Global State |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -40,12 +40,41 @@ typedef struct LG { | |||
| 40 | 40 | ||
| 41 | 41 | ||
| 42 | 42 | ||
| 43 | /* | ||
| 44 | ** maximum number of nested calls made by error-handling function | ||
| 45 | */ | ||
| 46 | #define LUAI_EXTRACALLS 10 | ||
| 47 | |||
| 48 | |||
| 49 | CallInfo *luaE_extendCI (lua_State *L) { | ||
| 50 | CallInfo *ci = luaM_new(L, CallInfo); | ||
| 51 | lua_assert(L->ci->next == NULL); | ||
| 52 | L->ci->next = ci; | ||
| 53 | ci->previous = L->ci; | ||
| 54 | ci->next = NULL; | ||
| 55 | if (++L->nci >= LUAI_MAXCALLS) { | ||
| 56 | if (L->nci == LUAI_MAXCALLS) /* overflow? */ | ||
| 57 | luaG_runerror(L, "stack overflow"); | ||
| 58 | if (L->nci >= LUAI_MAXCALLS + LUAI_EXTRACALLS) /* again? */ | ||
| 59 | luaD_throw(L, LUA_ERRERR); /* error while handling overflow */ | ||
| 60 | } | ||
| 61 | return ci; | ||
| 62 | } | ||
| 63 | |||
| 64 | |||
| 65 | void luaE_freeCI (lua_State *L) { | ||
| 66 | CallInfo *ci = L->ci; | ||
| 67 | CallInfo *next = ci->next; | ||
| 68 | ci->next = NULL; | ||
| 69 | while ((ci = next) != NULL) { | ||
| 70 | next = ci->next; | ||
| 71 | luaM_free(L, ci); | ||
| 72 | L->nci--; | ||
| 73 | } | ||
| 74 | } | ||
| 75 | |||
| 76 | |||
| 43 | static void stack_init (lua_State *L1, lua_State *L) { | 77 | static void stack_init (lua_State *L1, lua_State *L) { |
| 44 | /* initialize CallInfo array */ | ||
| 45 | L1->base_ci = luaM_newvector(L, BASIC_CI_SIZE, CallInfo); | ||
| 46 | L1->ci = L1->base_ci; | ||
| 47 | L1->size_ci = BASIC_CI_SIZE; | ||
| 48 | L1->end_ci = L1->base_ci + L1->size_ci - 1; | ||
| 49 | /* initialize stack array */ | 78 | /* initialize stack array */ |
| 50 | L1->stack = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, TValue); | 79 | L1->stack = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, TValue); |
| 51 | L1->stacksize = BASIC_STACK_SIZE + EXTRA_STACK; | 80 | L1->stacksize = BASIC_STACK_SIZE + EXTRA_STACK; |
| @@ -53,16 +82,18 @@ static void stack_init (lua_State *L1, lua_State *L) { | |||
| 53 | L1->stack_last = L1->stack+(L1->stacksize - EXTRA_STACK)-1; | 82 | L1->stack_last = L1->stack+(L1->stacksize - EXTRA_STACK)-1; |
| 54 | /* initialize first ci */ | 83 | /* initialize first ci */ |
| 55 | L1->ci->func = L1->top; | 84 | L1->ci->func = L1->top; |
| 56 | setnilvalue(L1->top++); /* `function' entry for this `ci' */ | 85 | setnilvalue(L1->top++); /* 'function' entry for this 'ci' */ |
| 57 | L1->base = L1->ci->base = L1->top; | 86 | L1->base = L1->ci->base = L1->top; |
| 58 | L1->ci->top = L1->top + LUA_MINSTACK; | 87 | L1->ci->top = L1->top + LUA_MINSTACK; |
| 59 | L1->ci->callstatus = 0; | 88 | L1->ci->callstatus = 0; |
| 60 | } | 89 | } |
| 61 | 90 | ||
| 62 | 91 | ||
| 63 | static void freestack (lua_State *L, lua_State *L1) { | 92 | static void freestack (lua_State *L) { |
| 64 | luaM_freearray(L, L1->base_ci, L1->size_ci, CallInfo); | 93 | L->ci = &L->base_ci; /* reset 'ci' list */ |
| 65 | luaM_freearray(L, L1->stack, L1->stacksize, TValue); | 94 | luaE_freeCI(L); |
| 95 | lua_assert(L->nci == 0); | ||
| 96 | luaM_freearray(L, L->stack, L->stacksize, TValue); | ||
| 66 | } | 97 | } |
| 67 | 98 | ||
| 68 | 99 | ||
| @@ -94,10 +125,11 @@ static void preinit_state (lua_State *L, global_State *g) { | |||
| 94 | L->allowhook = 1; | 125 | L->allowhook = 1; |
| 95 | resethookcount(L); | 126 | resethookcount(L); |
| 96 | L->openupval = NULL; | 127 | L->openupval = NULL; |
| 97 | L->size_ci = 0; | ||
| 98 | L->nny = 1; | 128 | L->nny = 1; |
| 99 | L->status = LUA_OK; | 129 | L->status = LUA_OK; |
| 100 | L->base_ci = L->ci = NULL; | 130 | L->base_ci.next = L->base_ci.previous = NULL; |
| 131 | L->ci = &L->base_ci; | ||
| 132 | L->nci = 0; | ||
| 101 | L->savedpc = NULL; | 133 | L->savedpc = NULL; |
| 102 | L->errfunc = 0; | 134 | L->errfunc = 0; |
| 103 | setnilvalue(gt(L)); | 135 | setnilvalue(gt(L)); |
| @@ -110,7 +142,7 @@ static void close_state (lua_State *L) { | |||
| 110 | luaC_freeall(L); /* collect all objects */ | 142 | luaC_freeall(L); /* collect all objects */ |
| 111 | luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size, TString *); | 143 | luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size, TString *); |
| 112 | luaZ_freebuffer(L, &g->buff); | 144 | luaZ_freebuffer(L, &g->buff); |
| 113 | freestack(L, L); | 145 | freestack(L); |
| 114 | lua_assert(g->totalbytes == sizeof(LG)); | 146 | lua_assert(g->totalbytes == sizeof(LG)); |
| 115 | (*g->frealloc)(g->ud, fromstate(L), state_size(LG), 0); | 147 | (*g->frealloc)(g->ud, fromstate(L), state_size(LG), 0); |
| 116 | } | 148 | } |
| @@ -142,7 +174,7 @@ void luaE_freethread (lua_State *L, lua_State *L1) { | |||
| 142 | luaF_close(L1, L1->stack); /* close all upvalues for this thread */ | 174 | luaF_close(L1, L1->stack); /* close all upvalues for this thread */ |
| 143 | lua_assert(L1->openupval == NULL); | 175 | lua_assert(L1->openupval == NULL); |
| 144 | luai_userstatefree(L1); | 176 | luai_userstatefree(L1); |
| 145 | freestack(L, L1); | 177 | freestack(L1); |
| 146 | luaM_freemem(L, fromstate(L1), state_size(lua_State)); | 178 | luaM_freemem(L, fromstate(L1), state_size(lua_State)); |
| 147 | } | 179 | } |
| 148 | 180 | ||
| @@ -211,3 +243,4 @@ LUA_API void lua_close (lua_State *L) { | |||
| 211 | close_state(L); | 243 | close_state(L); |
| 212 | } | 244 | } |
| 213 | 245 | ||
| 246 | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lstate.h,v 2.40 2009/03/23 14:26:12 roberto Exp roberto $ | 2 | ** $Id: lstate.h,v 2.41 2009/04/08 18:04:33 roberto Exp roberto $ |
| 3 | ** Global State | 3 | ** Global State |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -80,8 +80,9 @@ typedef struct CallInfo { | |||
| 80 | StkId base; /* base for this function */ | 80 | StkId base; /* base for this function */ |
| 81 | StkId func; /* function index in the stack */ | 81 | StkId func; /* function index in the stack */ |
| 82 | StkId top; /* top for this function */ | 82 | StkId top; /* top for this function */ |
| 83 | struct CallInfo *previous, *next; /* dynamic call link */ | ||
| 83 | const Instruction *savedpc; | 84 | const Instruction *savedpc; |
| 84 | short nresults; /* expected number of results from this function */ | 85 | short nresults; /* expected number of results from a call */ |
| 85 | lu_byte callstatus; | 86 | lu_byte callstatus; |
| 86 | union { | 87 | union { |
| 87 | struct { /* only for Lua functions */ | 88 | struct { /* only for Lua functions */ |
| @@ -163,14 +164,12 @@ struct lua_State { | |||
| 163 | StkId base; /* base of current function */ | 164 | StkId base; /* base of current function */ |
| 164 | global_State *l_G; | 165 | global_State *l_G; |
| 165 | CallInfo *ci; /* call info for current function */ | 166 | CallInfo *ci; /* call info for current function */ |
| 167 | int nci; /* number of total CallInfo structures linked */ | ||
| 166 | const Instruction *savedpc; /* `savedpc' of current function */ | 168 | const Instruction *savedpc; /* `savedpc' of current function */ |
| 167 | const Instruction *oldpc; /* last pc traced */ | 169 | const Instruction *oldpc; /* last pc traced */ |
| 168 | StkId stack_last; /* last free slot in the stack */ | 170 | StkId stack_last; /* last free slot in the stack */ |
| 169 | StkId stack; /* stack base */ | 171 | StkId stack; /* stack base */ |
| 170 | CallInfo *end_ci; /* points after end of ci array*/ | ||
| 171 | CallInfo *base_ci; /* array of CallInfo's */ | ||
| 172 | int stacksize; | 172 | int stacksize; |
| 173 | int size_ci; /* size of array `base_ci' */ | ||
| 174 | unsigned short nny; /* number of non-yieldable calls in stack */ | 173 | unsigned short nny; /* number of non-yieldable calls in stack */ |
| 175 | lu_byte hookmask; | 174 | lu_byte hookmask; |
| 176 | lu_byte allowhook; | 175 | lu_byte allowhook; |
| @@ -183,6 +182,7 @@ struct lua_State { | |||
| 183 | GCObject *gclist; | 182 | GCObject *gclist; |
| 184 | struct lua_longjmp *errorJmp; /* current error recover point */ | 183 | struct lua_longjmp *errorJmp; /* current error recover point */ |
| 185 | ptrdiff_t errfunc; /* current error handling function (stack index) */ | 184 | ptrdiff_t errfunc; /* current error handling function (stack index) */ |
| 185 | CallInfo base_ci; /* CallInfo for first level (C calling Lua) */ | ||
| 186 | }; | 186 | }; |
| 187 | 187 | ||
| 188 | 188 | ||
| @@ -223,6 +223,9 @@ union GCObject { | |||
| 223 | 223 | ||
| 224 | 224 | ||
| 225 | LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1); | 225 | LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1); |
| 226 | LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L); | ||
| 227 | LUAI_FUNC void luaE_freeCI (lua_State *L); | ||
| 228 | |||
| 226 | 229 | ||
| 227 | #endif | 230 | #endif |
| 228 | 231 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ltests.c,v 2.59 2009/03/03 18:52:36 roberto Exp roberto $ | 2 | ** $Id: ltests.c,v 2.60 2009/04/14 19:10:17 roberto Exp roberto $ |
| 3 | ** Internal Module for Debugging of the Lua Implementation | 3 | ** Internal Module for Debugging of the Lua Implementation |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -296,13 +296,10 @@ static void checkstack (global_State *g, lua_State *L1) { | |||
| 296 | lua_assert(!isblack(uvo)); /* open upvalues cannot be black */ | 296 | lua_assert(!isblack(uvo)); /* open upvalues cannot be black */ |
| 297 | } | 297 | } |
| 298 | checkliveness(g, gt(L1)); | 298 | checkliveness(g, gt(L1)); |
| 299 | if (L1->base_ci) { | 299 | for (ci = L1->ci; ci != NULL; ci = ci->previous) { |
| 300 | for (ci = L1->base_ci; ci <= L1->ci; ci++) { | 300 | lua_assert(ci->top <= L1->stack_last); |
| 301 | lua_assert(ci->top <= L1->stack_last); | 301 | lua_assert(lua_checkpc(L1, ci)); |
| 302 | lua_assert(lua_checkpc(L1, ci)); | ||
| 303 | } | ||
| 304 | } | 302 | } |
| 305 | else lua_assert(L1->size_ci == 0); | ||
| 306 | if (L1->stack) { | 303 | if (L1->stack) { |
| 307 | for (o = L1->stack; o < L1->top; o++) | 304 | for (o = L1->stack; o < L1->top; o++) |
| 308 | checkliveness(g, o); | 305 | checkliveness(g, o); |
| @@ -356,10 +353,10 @@ printf(">>> %d %s %02x\n", g->gcstate, luaT_typenames[gch(o)->tt], gch(o)->mar | |||
| 356 | 353 | ||
| 357 | 354 | ||
| 358 | int lua_checkpc (lua_State *L, pCallInfo ci) { | 355 | int lua_checkpc (lua_State *L, pCallInfo ci) { |
| 359 | if (ci == L->base_ci || !isLua(ci)) return 1; | 356 | if (!isLua(ci)) return 1; |
| 360 | else { | 357 | else { |
| 361 | Proto *p = ci_func(ci)->l.p; | 358 | Proto *p = ci_func(ci)->l.p; |
| 362 | if (ci < L->ci) | 359 | if (ci != L->ci) |
| 363 | return p->code <= ci->savedpc && ci->savedpc <= p->code + p->sizecode; | 360 | return p->code <= ci->savedpc && ci->savedpc <= p->code + p->sizecode; |
| 364 | else | 361 | else |
| 365 | return p->code <= L->savedpc && L->savedpc <= p->code + p->sizecode; | 362 | return p->code <= L->savedpc && L->savedpc <= p->code + p->sizecode; |
| @@ -575,8 +572,7 @@ static int stacklevel (lua_State *L) { | |||
| 575 | unsigned long a = 0; | 572 | unsigned long a = 0; |
| 576 | lua_pushinteger(L, (L->top - L->stack)); | 573 | lua_pushinteger(L, (L->top - L->stack)); |
| 577 | lua_pushinteger(L, (L->stack_last - L->stack)); | 574 | lua_pushinteger(L, (L->stack_last - L->stack)); |
| 578 | lua_pushinteger(L, (L->ci - L->base_ci)); | 575 | lua_pushinteger(L, L->nci); |
| 579 | lua_pushinteger(L, (L->end_ci - L->base_ci)); | ||
| 580 | lua_pushinteger(L, (unsigned long)&a); | 576 | lua_pushinteger(L, (unsigned long)&a); |
| 581 | return 5; | 577 | return 5; |
| 582 | } | 578 | } |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lua.h,v 1.234 2009/03/23 14:26:12 roberto Exp roberto $ | 2 | ** $Id: lua.h,v 1.235 2009/04/08 18:04:33 roberto Exp roberto $ |
| 3 | ** Lua - An Extensible Extension Language | 3 | ** Lua - An Extensible Extension Language |
| 4 | ** Lua.org, PUC-Rio, Brazil (http://www.lua.org) | 4 | ** Lua.org, PUC-Rio, Brazil (http://www.lua.org) |
| 5 | ** See Copyright Notice at the end of this file | 5 | ** See Copyright Notice at the end of this file |
| @@ -367,7 +367,7 @@ struct lua_Debug { | |||
| 367 | int lastlinedefined; /* (S) */ | 367 | int lastlinedefined; /* (S) */ |
| 368 | char short_src[LUA_IDSIZE]; /* (S) */ | 368 | char short_src[LUA_IDSIZE]; /* (S) */ |
| 369 | /* private part */ | 369 | /* private part */ |
| 370 | int i_ci; /* active function */ | 370 | struct CallInfo *i_ci; /* active function */ |
| 371 | }; | 371 | }; |
| 372 | 372 | ||
| 373 | /* }====================================================================== */ | 373 | /* }====================================================================== */ |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lvm.c,v 2.83 2009/03/04 13:32:29 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 2.84 2009/03/10 17:14:37 roberto Exp roberto $ |
| 3 | ** Lua virtual machine | 3 | ** Lua virtual machine |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -663,19 +663,19 @@ void luaV_execute (lua_State *L) { | |||
| 663 | } | 663 | } |
| 664 | else { | 664 | else { |
| 665 | /* tail call: put new frame in place of previous one */ | 665 | /* tail call: put new frame in place of previous one */ |
| 666 | CallInfo *ci = L->ci - 1; /* previous frame */ | 666 | StkId pfunc = L->ci->func; /* called function index */ |
| 667 | int aux; | 667 | CallInfo *ci = L->ci->previous; /* caller frame */ |
| 668 | StkId func = ci->func; | 668 | StkId func = ci->func; |
| 669 | StkId pfunc = (ci+1)->func; /* previous function index */ | 669 | int aux; |
| 670 | if (cl->p->sizep > 0) luaF_close(L, ci->base); | 670 | if (cl->p->sizep > 0) luaF_close(L, ci->base); |
| 671 | L->base = ci->base = ci->func + ((ci+1)->base - pfunc); | 671 | L->base = ci->base = ci->func + (L->ci->base - pfunc); |
| 672 | for (aux = 0; pfunc+aux < L->top; aux++) /* move frame down */ | 672 | for (aux = 0; pfunc+aux < L->top; aux++) /* move frame down */ |
| 673 | setobjs2s(L, func+aux, pfunc+aux); | 673 | setobjs2s(L, func+aux, pfunc+aux); |
| 674 | ci->top = L->top = func+aux; /* correct top */ | 674 | ci->top = L->top = func+aux; /* correct top */ |
| 675 | lua_assert(L->top == L->base + clvalue(func)->l.p->maxstacksize); | 675 | lua_assert(L->top == L->base + clvalue(func)->l.p->maxstacksize); |
| 676 | ci->savedpc = L->savedpc; | 676 | ci->savedpc = L->savedpc; |
| 677 | ci->u.l.tailcalls++; /* one more call lost */ | 677 | ci->u.l.tailcalls++; /* one more call lost */ |
| 678 | L->ci--; /* remove new frame */ | 678 | L->ci = ci; /* remove new frame */ |
| 679 | goto reentry; | 679 | goto reentry; |
| 680 | } | 680 | } |
| 681 | } | 681 | } |
| @@ -684,7 +684,7 @@ void luaV_execute (lua_State *L) { | |||
| 684 | if (b != 0) L->top = ra+b-1; | 684 | if (b != 0) L->top = ra+b-1; |
| 685 | if (cl->p->sizep > 0) luaF_close(L, base); | 685 | if (cl->p->sizep > 0) luaF_close(L, base); |
| 686 | b = luaD_poscall(L, ra); | 686 | b = luaD_poscall(L, ra); |
| 687 | if (!((L->ci + 1)->callstatus & CIST_REENTRY)) | 687 | if (!(L->ci->next->callstatus & CIST_REENTRY)) |
| 688 | return; /* external invocation: return */ | 688 | return; /* external invocation: return */ |
| 689 | else { /* invocation via reentry: continue execution */ | 689 | else { /* invocation via reentry: continue execution */ |
| 690 | if (b) L->top = L->ci->top; | 690 | if (b) L->top = L->ci->top; |
