00001
00002
00003
00004
00005
00006
00007
00008 #include <setjmp.h>
00009 #include <stdlib.h>
00010 #include <string.h>
00011
00012 #define ldo_c
00013
00014 #include "lua.h"
00015
00016 #include "ldebug.h"
00017 #include "ldo.h"
00018 #include "lfunc.h"
00019 #include "lgc.h"
00020 #include "lmem.h"
00021 #include "lobject.h"
00022 #include "lopcodes.h"
00023 #include "lparser.h"
00024 #include "lstate.h"
00025 #include "lstring.h"
00026 #include "ltable.h"
00027 #include "ltm.h"
00028 #include "lundump.h"
00029 #include "lvm.h"
00030 #include "lzio.h"
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 struct lua_longjmp {
00044 struct lua_longjmp *previous;
00045 jmp_buf b;
00046 volatile int status;
00047 };
00048
00049
00050 static void seterrorobj (lua_State *L, int errcode, StkId oldtop)
00051
00052 {
00053 switch (errcode) {
00054 case LUA_ERRMEM: {
00055 setsvalue2s(oldtop, luaS_new(L, MEMERRMSG));
00056 break;
00057 }
00058 case LUA_ERRERR: {
00059 setsvalue2s(oldtop, luaS_new(L, "error in error handling"));
00060 break;
00061 }
00062 case LUA_ERRSYNTAX:
00063 case LUA_ERRRUN: {
00064 setobjs2s(oldtop, L->top - 1);
00065 break;
00066 }
00067 }
00068 L->top = oldtop + 1;
00069 }
00070
00071
00072 void luaD_throw (lua_State *L, int errcode) {
00073 if (L->errorJmp) {
00074 L->errorJmp->status = errcode;
00075 longjmp(L->errorJmp->b, 1);
00076 }
00077 else {
00078 G(L)->panic(L);
00079 exit(EXIT_FAILURE);
00080 }
00081 }
00082
00083
00084 int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) {
00085 struct lua_longjmp lj;
00086 lj.status = 0;
00087 lj.previous = L->errorJmp;
00088 L->errorJmp = &lj;
00089 if (setjmp(lj.b) == 0)
00090 (*f)(L, ud);
00091 L->errorJmp = lj.previous;
00092 return lj.status;
00093 }
00094
00095
00096 static void restore_stack_limit (lua_State *L)
00097
00098 {
00099 L->stack_last = L->stack+L->stacksize-1;
00100 if (L->size_ci > LUA_MAXCALLS) {
00101 int inuse = (L->ci - L->base_ci);
00102 if (inuse + 1 < LUA_MAXCALLS)
00103 luaD_reallocCI(L, LUA_MAXCALLS);
00104 }
00105 }
00106
00107
00108
00109
00110 static void correctstack (lua_State *L, TObject *oldstack)
00111
00112 {
00113 CallInfo *ci;
00114 GCObject *up;
00115 L->top = (L->top - oldstack) + L->stack;
00116 for (up = L->openupval; up != NULL; up = up->gch.next)
00117 gcotouv(up)->v = (gcotouv(up)->v - oldstack) + L->stack;
00118 for (ci = L->base_ci; ci <= L->ci; ci++) {
00119 ci->top = (ci->top - oldstack) + L->stack;
00120 ci->base = (ci->base - oldstack) + L->stack;
00121 }
00122 L->base = L->ci->base;
00123 }
00124
00125
00126 void luaD_reallocstack (lua_State *L, int newsize) {
00127 TObject *oldstack = L->stack;
00128 luaM_reallocvector(L, L->stack, L->stacksize, newsize, TObject);
00129 L->stacksize = newsize;
00130 L->stack_last = L->stack+newsize-1-EXTRA_STACK;
00131 correctstack(L, oldstack);
00132 }
00133
00134
00135 void luaD_reallocCI (lua_State *L, int newsize) {
00136 CallInfo *oldci = L->base_ci;
00137 luaM_reallocvector(L, L->base_ci, L->size_ci, newsize, CallInfo);
00138 L->size_ci = cast(unsigned short, newsize);
00139 L->ci = (L->ci - oldci) + L->base_ci;
00140 L->end_ci = L->base_ci + L->size_ci;
00141 }
00142
00143
00144 void luaD_growstack (lua_State *L, int n) {
00145 if (n <= L->stacksize)
00146 luaD_reallocstack(L, 2*L->stacksize);
00147 else
00148 luaD_reallocstack(L, L->stacksize + n + EXTRA_STACK);
00149 }
00150
00151
00152 static void luaD_growCI (lua_State *L)
00153
00154 {
00155 if (L->size_ci > LUA_MAXCALLS)
00156 luaD_throw(L, LUA_ERRERR);
00157 else {
00158 luaD_reallocCI(L, 2*L->size_ci);
00159 if (L->size_ci > LUA_MAXCALLS)
00160 luaG_runerror(L, "stack overflow");
00161 }
00162 }
00163
00164
00165 void luaD_callhook (lua_State *L, int event, int line) {
00166 lua_Hook hook = L->hook;
00167 if (hook && L->allowhook) {
00168 ptrdiff_t top = savestack(L, L->top);
00169 ptrdiff_t ci_top = savestack(L, L->ci->top);
00170 lua_Debug ar;
00171 ar.event = event;
00172 ar.currentline = line;
00173 if (event == LUA_HOOKTAILRET)
00174 ar.i_ci = 0;
00175 else
00176 ar.i_ci = L->ci - L->base_ci;
00177 luaD_checkstack(L, LUA_MINSTACK);
00178 L->ci->top = L->top + LUA_MINSTACK;
00179 L->allowhook = 0;
00180 lua_unlock(L);
00181 (*hook)(L, &ar);
00182 lua_lock(L);
00183 lua_assert(!L->allowhook);
00184 L->allowhook = 1;
00185 L->ci->top = restorestack(L, ci_top);
00186 L->top = restorestack(L, top);
00187 }
00188 }
00189
00190
00191 static void adjust_varargs (lua_State *L, int nfixargs, StkId base)
00192
00193 {
00194 int i;
00195 Table *htab;
00196 TObject nname;
00197 int actual = L->top - base;
00198 if (actual < nfixargs) {
00199 luaD_checkstack(L, nfixargs - actual);
00200 for (; actual < nfixargs; ++actual)
00201 setnilvalue(L->top++);
00202 }
00203 actual -= nfixargs;
00204 htab = luaH_new(L, actual, 1);
00205 for (i=0; i<actual; i++)
00206 setobj2n(luaH_setnum(L, htab, i+1), L->top - actual + i);
00207
00208 setsvalue(&nname, luaS_newliteral(L, "n"));
00209 setnvalue(luaH_set(L, htab, &nname), cast(lua_Number, actual));
00210 L->top -= actual;
00211 sethvalue(L->top, htab);
00212 incr_top(L);
00213 }
00214
00215
00216
00217 static StkId tryfuncTM (lua_State *L, StkId func)
00218
00219 {
00220 const TObject *tm = luaT_gettmbyobj(L, func, TM_CALL);
00221 StkId p;
00222 ptrdiff_t funcr = savestack(L, func);
00223 if (!ttisfunction(tm))
00224 luaG_typeerror(L, func, "call");
00225
00226 for (p = L->top; p > func; p--) setobjs2s(p, p-1);
00227 incr_top(L);
00228 func = restorestack(L, funcr);
00229 setobj2s(func, tm);
00230 return func;
00231 }
00232
00233
00234 StkId luaD_precall (lua_State *L, StkId func) {
00235 LClosure *cl;
00236 ptrdiff_t funcr = savestack(L, func);
00237 if (!ttisfunction(func))
00238 func = tryfuncTM(L, func);
00239 if (L->ci + 1 == L->end_ci) luaD_growCI(L);
00240 else condhardstacktests(luaD_reallocCI(L, L->size_ci));
00241 cl = &clvalue(func)->l;
00242 if (!cl->isC) {
00243 CallInfo *ci;
00244 Proto *p = cl->p;
00245 if (p->is_vararg)
00246 adjust_varargs(L, p->numparams, func+1);
00247 luaD_checkstack(L, p->maxstacksize);
00248 ci = ++L->ci;
00249 L->base = L->ci->base = restorestack(L, funcr) + 1;
00250 ci->top = L->base + p->maxstacksize;
00251 ci->u.l.savedpc = p->code;
00252 ci->u.l.tailcalls = 0;
00253 ci->state = CI_SAVEDPC;
00254 while (L->top < ci->top)
00255 setnilvalue(L->top++);
00256 L->top = ci->top;
00257 return NULL;
00258 }
00259 else {
00260 CallInfo *ci;
00261 int n;
00262 luaD_checkstack(L, LUA_MINSTACK);
00263 ci = ++L->ci;
00264 L->base = L->ci->base = restorestack(L, funcr) + 1;
00265 ci->top = L->top + LUA_MINSTACK;
00266 ci->state = CI_C;
00267 if (L->hookmask & LUA_MASKCALL)
00268 luaD_callhook(L, LUA_HOOKCALL, -1);
00269 lua_unlock(L);
00270 #ifdef LUA_COMPATUPVALUES
00271 lua_pushupvalues(L);
00272 #endif
00273 n = (*clvalue(L->base - 1)->c.f)(L);
00274 lua_lock(L);
00275 return L->top - n;
00276 }
00277 }
00278
00279
00280
00281 static StkId callrethooks (lua_State *L, StkId firstResult)
00282
00283 {
00284 ptrdiff_t fr = savestack(L, firstResult);
00285 luaD_callhook(L, LUA_HOOKRET, -1);
00286 if (!(L->ci->state & CI_C)) {
00287 while (L->ci->u.l.tailcalls--)
00288 luaD_callhook(L, LUA_HOOKTAILRET, -1);
00289 }
00290 return restorestack(L, fr);
00291 }
00292
00293
00294 void luaD_poscall (lua_State *L, int wanted, StkId firstResult) {
00295 StkId res;
00296 if (L->hookmask & LUA_MASKRET)
00297 firstResult = callrethooks(L, firstResult);
00298 res = L->base - 1;
00299 L->ci--;
00300 L->base = L->ci->base;
00301
00302 while (wanted != 0 && firstResult < L->top) {
00303 setobjs2s(res++, firstResult++);
00304 wanted--;
00305 }
00306 while (wanted-- > 0)
00307 setnilvalue(res++);
00308 L->top = res;
00309 }
00310
00311
00312
00313
00314
00315
00316
00317
00318 void luaD_call (lua_State *L, StkId func, int nResults) {
00319 StkId firstResult;
00320 lua_assert(!(L->ci->state & CI_CALLING));
00321 if (++L->nCcalls >= LUA_MAXCCALLS) {
00322 if (L->nCcalls == LUA_MAXCCALLS)
00323 luaG_runerror(L, "C stack overflow");
00324 else if (L->nCcalls >= (LUA_MAXCCALLS + (LUA_MAXCCALLS>>3)))
00325 luaD_throw(L, LUA_ERRERR);
00326 }
00327 firstResult = luaD_precall(L, func);
00328 if (firstResult == NULL)
00329 firstResult = luaV_execute(L);
00330 luaD_poscall(L, nResults, firstResult);
00331 L->nCcalls--;
00332 luaC_checkGC(L);
00333 }
00334
00335
00336 static void resume (lua_State *L, void *ud)
00337
00338 {
00339 StkId firstResult;
00340 int nargs = *cast(int *, ud);
00341 CallInfo *ci = L->ci;
00342 if (ci == L->base_ci) {
00343 lua_assert(nargs < L->top - L->base);
00344 luaD_precall(L, L->top - (nargs + 1));
00345 }
00346 else {
00347 lua_assert(ci->state & CI_YIELD);
00348 if (ci->state & CI_C) {
00349
00350 int nresults;
00351 lua_assert((ci-1)->state & CI_SAVEDPC);
00352 lua_assert(GET_OPCODE(*((ci-1)->u.l.savedpc - 1)) == OP_CALL ||
00353 GET_OPCODE(*((ci-1)->u.l.savedpc - 1)) == OP_TAILCALL);
00354 nresults = GETARG_C(*((ci-1)->u.l.savedpc - 1)) - 1;
00355 luaD_poscall(L, nresults, L->top - nargs);
00356 if (nresults >= 0) L->top = L->ci->top;
00357 }
00358 else {
00359 ci->state &= ~CI_YIELD;
00360 }
00361 }
00362 firstResult = luaV_execute(L);
00363 if (firstResult != NULL)
00364 luaD_poscall(L, LUA_MULTRET, firstResult);
00365 }
00366
00367
00368 static int resume_error (lua_State *L, const char *msg)
00369
00370 {
00371 L->top = L->ci->base;
00372 setsvalue2s(L->top, luaS_new(L, msg));
00373 incr_top(L);
00374 lua_unlock(L);
00375 return LUA_ERRRUN;
00376 }
00377
00378
00379 LUA_API int lua_resume (lua_State *L, int nargs)
00380
00381 {
00382 int status;
00383 lu_byte old_allowhooks;
00384 lua_lock(L);
00385 if (L->ci == L->base_ci) {
00386 if (nargs >= L->top - L->base)
00387 return resume_error(L, "cannot resume dead coroutine");
00388 }
00389 else if (!(L->ci->state & CI_YIELD))
00390 return resume_error(L, "cannot resume non-suspended coroutine");
00391 old_allowhooks = L->allowhook;
00392 lua_assert(L->errfunc == 0 && L->nCcalls == 0);
00393 status = luaD_rawrunprotected(L, resume, &nargs);
00394 if (status != 0) {
00395 L->ci = L->base_ci;
00396 L->base = L->ci->base;
00397 L->nCcalls = 0;
00398 luaF_close(L, L->base);
00399 seterrorobj(L, status, L->base);
00400 L->allowhook = old_allowhooks;
00401 restore_stack_limit(L);
00402 }
00403 lua_unlock(L);
00404 return status;
00405 }
00406
00407
00408 LUA_API int lua_yield (lua_State *L, int nresults)
00409
00410 {
00411 CallInfo *ci;
00412 lua_lock(L);
00413 ci = L->ci;
00414 if (L->nCcalls > 0)
00415 luaG_runerror(L, "attempt to yield across metamethod/C-call boundary");
00416 if (ci->state & CI_C) {
00417 if ((ci-1)->state & CI_C)
00418 luaG_runerror(L, "cannot yield a C function");
00419 if (L->top - nresults > L->base) {
00420 int i;
00421 for (i=0; i<nresults; i++)
00422 setobjs2s(L->base + i, L->top - nresults + i);
00423 L->top = L->base + nresults;
00424 }
00425 }
00426 ci->state |= CI_YIELD;
00427 lua_unlock(L);
00428 return -1;
00429 }
00430
00431
00432 int luaD_pcall (lua_State *L, Pfunc func, void *u,
00433 ptrdiff_t old_top, ptrdiff_t ef) {
00434 int status;
00435 unsigned short oldnCcalls = L->nCcalls;
00436 ptrdiff_t old_ci = saveci(L, L->ci);
00437 lu_byte old_allowhooks = L->allowhook;
00438 ptrdiff_t old_errfunc = L->errfunc;
00439 L->errfunc = ef;
00440 status = luaD_rawrunprotected(L, func, u);
00441 if (status != 0) {
00442 StkId oldtop = restorestack(L, old_top);
00443 luaF_close(L, oldtop);
00444 seterrorobj(L, status, oldtop);
00445 L->nCcalls = oldnCcalls;
00446 L->ci = restoreci(L, old_ci);
00447 L->base = L->ci->base;
00448 L->allowhook = old_allowhooks;
00449 restore_stack_limit(L);
00450 }
00451 L->errfunc = old_errfunc;
00452 return status;
00453 }
00454
00455
00456
00457
00458
00459
00460 struct SParser {
00461 ZIO *z;
00462 Mbuffer buff;
00463 int bin;
00464 };
00465
00466 static void f_parser (lua_State *L, void *ud)
00467
00468 {
00469 struct SParser *p;
00470 Proto *tf;
00471 Closure *cl;
00472 luaC_checkGC(L);
00473 p = cast(struct SParser *, ud);
00474 tf = p->bin ? luaU_undump(L, p->z, &p->buff) : luaY_parser(L, p->z, &p->buff);
00475 cl = luaF_newLclosure(L, 0, gt(L));
00476 cl->l.p = tf;
00477 setclvalue(L->top, cl);
00478 incr_top(L);
00479 }
00480
00481
00482 int luaD_protectedparser (lua_State *L, ZIO *z, int bin) {
00483 struct SParser p;
00484 int status;
00485 ptrdiff_t oldtopr = savestack(L, L->top);
00486 p.z = z; p.bin = bin;
00487 luaZ_initbuffer(L, &p.buff);
00488 status = luaD_rawrunprotected(L, f_parser, &p);
00489 luaZ_freebuffer(L, &p.buff);
00490 if (status != 0) {
00491 StkId oldtop = restorestack(L, oldtopr);
00492 seterrorobj(L, status, oldtop);
00493 }
00494 return status;
00495 }
00496
00497