00001 /* 00002 ** $Id: ldo.c,v 2.38.1.3 2008/01/18 22:31:22 roberto Exp $ 00003 ** Stack and Call structure of Lua 00004 ** See Copyright Notice in lua.h 00005 */ 00006 00007 00008 #include <setjmp.h> 00009 #include <stdlib.h> 00010 #include <string.h> 00011 00012 #define ldo_c 00013 #define LUA_CORE 00014 00015 #include "lua.h" 00016 00017 #include "ldebug.h" 00018 #include "ldo.h" 00019 #include "lfunc.h" 00020 #include "lgc.h" 00021 #include "lmem.h" 00022 #include "lobject.h" 00023 #include "lopcodes.h" 00024 #include "lparser.h" 00025 #include "lstate.h" 00026 #include "lstring.h" 00027 #include "ltable.h" 00028 #include "ltm.h" 00029 #include "lundump.h" 00030 #include "lvm.h" 00031 #include "lzio.h" 00032 00033 00034 #ifdef LUA_SYMBIAN 00035 #include <e32std.h> 00036 #endif 00037 00038 00039 /* 00040 ** {====================================================== 00041 ** Error-recovery functions 00042 ** ======================================================= 00043 */ 00044 00045 00046 /* chain list of long jump buffers */ 00047 struct lua_longjmp { 00048 struct lua_longjmp *previous; 00049 luai_jmpbuf b; 00050 volatile int status; /* error code */ 00051 }; 00052 00053 00054 void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop) { 00055 switch (errcode) { 00056 case LUA_ERRMEM: { 00057 setsvalue2s(L, oldtop, luaS_newliteral(L, MEMERRMSG)); 00058 break; 00059 } 00060 case LUA_ERRERR: { 00061 setsvalue2s(L, oldtop, luaS_newliteral(L, "error in error handling")); 00062 break; 00063 } 00064 case LUA_ERRSYNTAX: 00065 case LUA_ERRRUN: { 00066 setobjs2s(L, oldtop, L->top - 1); /* error message on current top */ 00067 break; 00068 } 00069 } 00070 L->top = oldtop + 1; 00071 } 00072 00073 00074 static void restore_stack_limit (lua_State *L) { 00075 lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1); 00076 if (L->size_ci > LUAI_MAXCALLS) { /* there was an overflow? */ 00077 int inuse = cast_int(L->ci - L->base_ci); 00078 if (inuse + 1 < LUAI_MAXCALLS) /* can `undo' overflow? */ 00079 luaD_reallocCI(L, LUAI_MAXCALLS); 00080 } 00081 } 00082 00083 00084 static void resetstack (lua_State *L, int status) { 00085 L->ci = L->base_ci; 00086 L->base = L->ci->base; 00087 luaF_close(L, L->base); /* close eventual pending closures */ 00088 luaD_seterrorobj(L, status, L->base); 00089 L->nCcalls = L->baseCcalls; 00090 L->allowhook = 1; 00091 restore_stack_limit(L); 00092 L->errfunc = 0; 00093 L->errorJmp = NULL; 00094 } 00095 00096 00097 void luaD_throw (lua_State *L, int errcode) { 00098 //logg("luaD_throw errCode %d", errcode); 00099 if (L->errorJmp) { 00100 //logt("have errorJmp"); 00101 L->errorJmp->status = errcode; 00102 LUAI_THROW(L, L->errorJmp); 00103 } 00104 else { 00105 L->status = cast_byte(errcode); 00106 if (G(L)->panic) { 00107 resetstack(L, errcode); 00108 lua_unlock(L); 00109 G(L)->panic(L); 00110 } 00111 exit(EXIT_FAILURE); 00112 } 00113 } 00114 00115 00116 int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) { 00117 struct lua_longjmp lj; 00118 lj.status = 0; 00119 lj.previous = L->errorJmp; /* chain new error handler */ 00120 L->errorJmp = &lj; 00121 LUAI_TRY(L, &lj, 00122 (*f)(L, ud); 00123 ); 00124 //logt("exited LUAI_TRY"); 00125 L->errorJmp = lj.previous; /* restore old error handler */ 00126 return lj.status; 00127 } 00128 00129 /* }====================================================== */ 00130 00131 00132 static void correctstack (lua_State *L, TValue *oldstack) { 00133 CallInfo *ci; 00134 GCObject *up; 00135 L->top = (L->top - oldstack) + L->stack; 00136 for (up = L->openupval; up != NULL; up = up->gch.next) 00137 gco2uv(up)->v = (gco2uv(up)->v - oldstack) + L->stack; 00138 for (ci = L->base_ci; ci <= L->ci; ci++) { 00139 ci->top = (ci->top - oldstack) + L->stack; 00140 ci->base = (ci->base - oldstack) + L->stack; 00141 ci->func = (ci->func - oldstack) + L->stack; 00142 } 00143 L->base = (L->base - oldstack) + L->stack; 00144 } 00145 00146 00147 void luaD_reallocstack (lua_State *L, int newsize) { 00148 TValue *oldstack = L->stack; 00149 int realsize = newsize + 1 + EXTRA_STACK; 00150 lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1); 00151 luaM_reallocvector(L, L->stack, L->stacksize, realsize, TValue); 00152 L->stacksize = realsize; 00153 L->stack_last = L->stack+newsize; 00154 correctstack(L, oldstack); 00155 } 00156 00157 00158 void luaD_reallocCI (lua_State *L, int newsize) { 00159 CallInfo *oldci = L->base_ci; 00160 luaM_reallocvector(L, L->base_ci, L->size_ci, newsize, CallInfo); 00161 L->size_ci = newsize; 00162 L->ci = (L->ci - oldci) + L->base_ci; 00163 L->end_ci = L->base_ci + L->size_ci - 1; 00164 } 00165 00166 00167 void luaD_growstack (lua_State *L, int n) { 00168 if (n <= L->stacksize) /* double size is enough? */ 00169 luaD_reallocstack(L, 2*L->stacksize); 00170 else 00171 luaD_reallocstack(L, L->stacksize + n); 00172 } 00173 00174 00175 static CallInfo *growCI (lua_State *L) { 00176 if (L->size_ci > LUAI_MAXCALLS) /* overflow while handling overflow? */ 00177 luaD_throw(L, LUA_ERRERR); 00178 else { 00179 luaD_reallocCI(L, 2*L->size_ci); 00180 if (L->size_ci > LUAI_MAXCALLS) 00181 luaG_runerror_1(L, "stack overflow"); 00182 } 00183 return ++L->ci; 00184 } 00185 00186 00187 void luaD_callhook (lua_State *L, int event, int line) { 00188 lua_Hook hook = L->hook; 00189 if (hook && L->allowhook) { 00190 ptrdiff_t top = savestack(L, L->top); 00191 ptrdiff_t ci_top = savestack(L, L->ci->top); 00192 lua_Debug ar; 00193 ar.event = event; 00194 ar.currentline = line; 00195 if (event == LUA_HOOKTAILRET) 00196 ar.i_ci = 0; /* tail call; no debug information about it */ 00197 else 00198 ar.i_ci = cast_int(L->ci - L->base_ci); 00199 luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ 00200 L->ci->top = L->top + LUA_MINSTACK; 00201 lua_assert(L->ci->top <= L->stack_last); 00202 L->allowhook = 0; /* cannot call hooks inside a hook */ 00203 lua_unlock(L); 00204 (*hook)(L, &ar); 00205 lua_lock(L); 00206 lua_assert(!L->allowhook); 00207 L->allowhook = 1; 00208 L->ci->top = restorestack(L, ci_top); 00209 L->top = restorestack(L, top); 00210 } 00211 } 00212 00213 00214 static StkId adjust_varargs (lua_State *L, Proto *p, int actual) { 00215 int i; 00216 int nfixargs = p->numparams; 00217 Table *htab = NULL; 00218 StkId base, fixed; 00219 for (; actual < nfixargs; ++actual) 00220 setnilvalue(L->top++); 00221 #if defined(LUA_COMPAT_VARARG) 00222 if (p->is_vararg & VARARG_NEEDSARG) { /* compat. with old-style vararg? */ 00223 int nvar = actual - nfixargs; /* number of extra arguments */ 00224 lua_assert(p->is_vararg & VARARG_HASARG); 00225 luaC_checkGC(L); 00226 htab = luaH_new(L, nvar, 1); /* create `arg' table */ 00227 for (i=0; i<nvar; i++) /* put extra arguments into `arg' table */ 00228 setobj2n(L, luaH_setnum(L, htab, i+1), L->top - nvar + i); 00229 /* store counter in field `n' */ 00230 setnvalue(luaH_setstr(L, htab, luaS_newliteral(L, "n")), cast_num(nvar)); 00231 } 00232 #endif 00233 /* move fixed parameters to final position */ 00234 fixed = L->top - actual; /* first fixed argument */ 00235 base = L->top; /* final position of first argument */ 00236 for (i=0; i<nfixargs; i++) { 00237 setobjs2s(L, L->top++, fixed+i); 00238 setnilvalue(fixed+i); 00239 } 00240 /* add `arg' parameter */ 00241 if (htab) { 00242 sethvalue(L, L->top++, htab); 00243 lua_assert(iswhite(obj2gco(htab))); 00244 } 00245 return base; 00246 } 00247 00248 00249 static StkId tryfuncTM (lua_State *L, StkId func) { 00250 const TValue *tm = luaT_gettmbyobj(L, func, TM_CALL); 00251 StkId p; 00252 ptrdiff_t funcr = savestack(L, func); 00253 if (!ttisfunction(tm)) 00254 luaG_typeerror(L, func, "call"); 00255 /* Open a hole inside the stack at `func' */ 00256 for (p = L->top; p > func; p--) setobjs2s(L, p, p-1); 00257 incr_top(L); 00258 func = restorestack(L, funcr); /* previous call may change stack */ 00259 setobj2s(L, func, tm); /* tag method is the new function to be called */ 00260 return func; 00261 } 00262 00263 00264 00265 #define inc_ci(L) \ 00266 ((L->ci == L->end_ci) ? growCI(L) : \ 00267 (condhardstacktests(luaD_reallocCI(L, L->size_ci)), ++L->ci)) 00268 00269 00270 int luaD_precall (lua_State *L, StkId func, int nresults) { 00271 LClosure *cl; 00272 ptrdiff_t funcr; 00273 if (!ttisfunction(func)) /* `func' is not a function? */ 00274 func = tryfuncTM(L, func); /* check the `function' tag method */ 00275 funcr = savestack(L, func); 00276 cl = &clvalue(func)->l; 00277 L->ci->savedpc = L->savedpc; 00278 if (!cl->isC) { /* Lua function? prepare its call */ 00279 CallInfo *ci; 00280 StkId st, base; 00281 Proto *p = cl->p; 00282 luaD_checkstack(L, p->maxstacksize); 00283 func = restorestack(L, funcr); 00284 if (!p->is_vararg) { /* no varargs? */ 00285 base = func + 1; 00286 if (L->top > base + p->numparams) 00287 L->top = base + p->numparams; 00288 } 00289 else { /* vararg function */ 00290 int nargs = cast_int(L->top - func) - 1; 00291 base = adjust_varargs(L, p, nargs); 00292 func = restorestack(L, funcr); /* previous call may change the stack */ 00293 } 00294 ci = inc_ci(L); /* now `enter' new function */ 00295 ci->func = func; 00296 L->base = ci->base = base; 00297 ci->top = L->base + p->maxstacksize; 00298 lua_assert(ci->top <= L->stack_last); 00299 L->savedpc = p->code; /* starting point */ 00300 ci->tailcalls = 0; 00301 ci->nresults = nresults; 00302 for (st = L->top; st < ci->top; st++) 00303 setnilvalue(st); 00304 L->top = ci->top; 00305 if (L->hookmask & LUA_MASKCALL) { 00306 L->savedpc++; /* hooks assume 'pc' is already incremented */ 00307 luaD_callhook(L, LUA_HOOKCALL, -1); 00308 L->savedpc--; /* correct 'pc' */ 00309 } 00310 return PCRLUA; 00311 } 00312 else { /* if is a C function, call it */ 00313 CallInfo *ci; 00314 int n; 00315 luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ 00316 ci = inc_ci(L); /* now `enter' new function */ 00317 ci->func = restorestack(L, funcr); 00318 L->base = ci->base = ci->func + 1; 00319 ci->top = L->top + LUA_MINSTACK; 00320 lua_assert(ci->top <= L->stack_last); 00321 ci->nresults = nresults; 00322 if (L->hookmask & LUA_MASKCALL) 00323 luaD_callhook(L, LUA_HOOKCALL, -1); 00324 lua_unlock(L); 00325 n = (*curr_func(L)->c.f)(L); /* do the actual call */ 00326 lua_lock(L); 00327 if (n < 0) /* yielding? */ 00328 return PCRYIELD; 00329 else { 00330 luaD_poscall(L, L->top - n); 00331 return PCRC; 00332 } 00333 } 00334 } 00335 00336 00337 static StkId callrethooks (lua_State *L, StkId firstResult) { 00338 ptrdiff_t fr = savestack(L, firstResult); /* next call may change stack */ 00339 luaD_callhook(L, LUA_HOOKRET, -1); 00340 if (f_isLua(L->ci)) { /* Lua function? */ 00341 while ((L->hookmask & LUA_MASKRET) && L->ci->tailcalls--) /* tail calls */ 00342 luaD_callhook(L, LUA_HOOKTAILRET, -1); 00343 } 00344 return restorestack(L, fr); 00345 } 00346 00347 00348 int luaD_poscall (lua_State *L, StkId firstResult) { 00349 StkId res; 00350 int wanted, i; 00351 CallInfo *ci; 00352 if (L->hookmask & LUA_MASKRET) 00353 firstResult = callrethooks(L, firstResult); 00354 ci = L->ci--; 00355 res = ci->func; /* res == final position of 1st result */ 00356 wanted = ci->nresults; 00357 L->base = (ci - 1)->base; /* restore base */ 00358 L->savedpc = (ci - 1)->savedpc; /* restore savedpc */ 00359 /* move results to correct place */ 00360 for (i = wanted; i != 0 && firstResult < L->top; i--) 00361 setobjs2s(L, res++, firstResult++); 00362 while (i-- > 0) 00363 setnilvalue(res++); 00364 L->top = res; 00365 return (wanted - LUA_MULTRET); /* 0 iff wanted == LUA_MULTRET */ 00366 } 00367 00368 00369 /* 00370 ** Call a function (C or Lua). The function to be called is at *func. 00371 ** The arguments are on the stack, right after the function. 00372 ** When returns, all the results are on the stack, starting at the original 00373 ** function position. 00374 */ 00375 void luaD_call (lua_State *L, StkId func, int nResults) { 00376 if (++L->nCcalls >= LUAI_MAXCCALLS) { 00377 if (L->nCcalls == LUAI_MAXCCALLS) 00378 luaG_runerror_1(L, "C stack overflow"); 00379 else if (L->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS>>3))) 00380 luaD_throw(L, LUA_ERRERR); /* error while handing stack error */ 00381 } 00382 if (luaD_precall(L, func, nResults) == PCRLUA) /* is a Lua function? */ 00383 luaV_execute(L, 1); /* call it */ 00384 L->nCcalls--; 00385 luaC_checkGC(L); 00386 } 00387 00388 00389 static void resume (lua_State *L, void *ud) { 00390 StkId firstArg = cast(StkId, ud); 00391 CallInfo *ci = L->ci; 00392 if (L->status == 0) { /* start coroutine? */ 00393 lua_assert(ci == L->base_ci && firstArg > L->base); 00394 if (luaD_precall(L, firstArg - 1, LUA_MULTRET) != PCRLUA) 00395 return; 00396 } 00397 else { /* resuming from previous yield */ 00398 lua_assert(L->status == LUA_YIELD); 00399 L->status = 0; 00400 if (!f_isLua(ci)) { /* `common' yield? */ 00401 /* finish interrupted execution of `OP_CALL' */ 00402 lua_assert(GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_CALL || 00403 GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_TAILCALL); 00404 if (luaD_poscall(L, firstArg)) /* complete it... */ 00405 L->top = L->ci->top; /* and correct top if not multiple results */ 00406 } 00407 else /* yielded inside a hook: just continue its execution */ 00408 L->base = L->ci->base; 00409 } 00410 luaV_execute(L, cast_int(L->ci - L->base_ci)); 00411 } 00412 00413 00414 static int resume_error (lua_State *L, const char *msg) { 00415 L->top = L->ci->base; 00416 setsvalue2s(L, L->top, luaS_new(L, msg)); 00417 incr_top(L); 00418 lua_unlock(L); 00419 return LUA_ERRRUN; 00420 } 00421 00422 00423 LUA_API int lua_resume (lua_State *L, int nargs) { 00424 int status; 00425 lua_lock(L); 00426 if (L->status != LUA_YIELD && (L->status != 0 || L->ci != L->base_ci)) 00427 return resume_error(L, "cannot resume non-suspended coroutine"); 00428 if (L->nCcalls >= LUAI_MAXCCALLS) 00429 return resume_error(L, "C stack overflow"); 00430 luai_userstateresume(L, nargs); 00431 lua_assert(L->errfunc == 0); 00432 L->baseCcalls = ++L->nCcalls; 00433 status = luaD_rawrunprotected(L, resume, L->top - nargs); 00434 if (status != 0) { /* error? */ 00435 L->status = cast_byte(status); /* mark thread as `dead' */ 00436 luaD_seterrorobj(L, status, L->top); 00437 L->ci->top = L->top; 00438 } 00439 else { 00440 lua_assert(L->nCcalls == L->baseCcalls); 00441 status = L->status; 00442 } 00443 --L->nCcalls; 00444 lua_unlock(L); 00445 return status; 00446 } 00447 00448 00449 LUA_API int lua_yield (lua_State *L, int nresults) { 00450 luai_userstateyield(L, nresults); 00451 lua_lock(L); 00452 if (L->nCcalls > L->baseCcalls) 00453 luaG_runerror_1(L, "attempt to yield across metamethod/C-call boundary"); 00454 L->base = L->top - nresults; /* protect stack slots below */ 00455 L->status = LUA_YIELD; 00456 lua_unlock(L); 00457 return -1; 00458 } 00459 00460 00461 int luaD_pcall (lua_State *L, Pfunc func, void *u, 00462 ptrdiff_t old_top, ptrdiff_t ef) { 00463 int status; 00464 unsigned short oldnCcalls = L->nCcalls; 00465 ptrdiff_t old_ci = saveci(L, L->ci); 00466 lu_byte old_allowhooks = L->allowhook; 00467 ptrdiff_t old_errfunc = L->errfunc; 00468 L->errfunc = ef; 00469 status = luaD_rawrunprotected(L, func, u); 00470 if (status != 0) { /* an error occurred? */ 00471 StkId oldtop = restorestack(L, old_top); 00472 luaF_close(L, oldtop); /* close eventual pending closures */ 00473 luaD_seterrorobj(L, status, oldtop); 00474 L->nCcalls = oldnCcalls; 00475 L->ci = restoreci(L, old_ci); 00476 L->base = L->ci->base; 00477 L->savedpc = L->ci->savedpc; 00478 L->allowhook = old_allowhooks; 00479 restore_stack_limit(L); 00480 } 00481 L->errfunc = old_errfunc; 00482 return status; 00483 } 00484 00485 00486 00487 /* 00488 ** Execute a protected parser. 00489 */ 00490 struct SParser { /* data to `f_parser' */ 00491 ZIO *z; 00492 Mbuffer buff; /* buffer to be used by the scanner */ 00493 const char *name; 00494 }; 00495 00496 static void f_parser (lua_State *L, void *ud) { 00497 int i; 00498 Proto *tf; 00499 Closure *cl; 00500 struct SParser *p = cast(struct SParser *, ud); 00501 int c = luaZ_lookahead(p->z); 00502 luaC_checkGC(L); 00503 tf = ((c == LUA_SIGNATURE[0]) ? luaU_undump : luaY_parser)(L, p->z, 00504 &p->buff, p->name); 00505 cl = luaF_newLclosure(L, tf->nups, hvalue(gt(L))); 00506 cl->l.p = tf; 00507 for (i = 0; i < tf->nups; i++) /* initialize eventual upvalues */ 00508 cl->l.upvals[i] = luaF_newupval(L); 00509 setclvalue(L, L->top, cl); 00510 incr_top(L); 00511 } 00512 00513 00514 int luaD_protectedparser (lua_State *L, ZIO *z, const char *name) { 00515 struct SParser p; 00516 int status; 00517 p.z = z; p.name = name; 00518 luaZ_initbuffer(L, &p.buff); 00519 status = luaD_pcall(L, f_parser, &p, savestack(L, L->top), L->errfunc); 00520 luaZ_freebuffer(L, &p.buff); 00521 return status; 00522 } 00523 00524
ContextLogger2—ContextLogger2 Logger Daemon Internals—Generated on Mon May 2 13:49:54 2011 by Doxygen 1.6.1