38#define errorstatus(s) ((s) > LUA_YIELD)
53#if !defined(LUAI_THROW)
55#if defined(__cplusplus) && !defined(LUA_USE_LONGJMP)
58#define LUAI_THROW(L,c) throw(c)
59#define LUAI_TRY(L,c,a) \
60 try { a } catch(...) { if ((c)->status == 0) (c)->status = -1; }
61#define luai_jmpbuf int
63#elif defined(LUA_USE_POSIX)
66#define LUAI_THROW(L,c) _longjmp((c)->b, 1)
67#define LUAI_TRY(L,c,a) if (_setjmp((c)->b) == 0) { a }
68#define luai_jmpbuf jmp_buf
73#define LUAI_THROW(L,c) longjmp((c)->b, 1)
74#define LUAI_TRY(L,c,a) if (setjmp((c)->b) == 0) { a }
75#define luai_jmpbuf jmp_buf
91void luaD_seterrorobj (
lua_State *L,
int errcode, StkId oldtop) {
94 setsvalue2s(L, oldtop, G(L)->memerrmsg);
98 setsvalue2s(L, oldtop, luaS_newliteral(L,
"error in error handling"));
102 setnilvalue(s2v(oldtop));
106 lua_assert(errorstatus(errcode));
107 setobjs2s(L, oldtop, L->top.p - 1);
111 L->top.p = oldtop + 1;
115l_noret luaD_throw (
lua_State *L,
int errcode) {
117 L->errorJmp->status = errcode;
118 LUAI_THROW(L, L->errorJmp);
122 errcode = luaE_resetthread(L, errcode);
123 if (g->mainthread->errorJmp) {
124 setobjs2s(L, g->mainthread->top.p++, L->top.p - 1);
125 luaD_throw(g->mainthread, errcode);
138int luaD_rawrunprotected (
lua_State *L, Pfunc f,
void *ud) {
139 l_uint32 oldnCcalls = L->nCcalls;
142 lj.previous = L->errorJmp;
147 L->errorJmp = lj.previous;
148 L->nCcalls = oldnCcalls;
168 L->top.offset = savestack(L, L->top.p);
169 L->tbclist.offset = savestack(L, L->tbclist.p);
170 for (up = L->openupval; up != NULL; up = up->u.open.next)
171 up->v.offset = savestack(L, uplevel(up));
172 for (ci = L->ci; ci != NULL; ci = ci->previous) {
173 ci->top.offset = savestack(L, ci->top.p);
174 ci->func.offset = savestack(L, ci->func.p);
185 L->top.p = restorestack(L, L->top.offset);
186 L->tbclist.p = restorestack(L, L->tbclist.offset);
187 for (up = L->openupval; up != NULL; up = up->u.open.next)
188 up->v.p = s2v(restorestack(L, up->v.offset));
189 for (ci = L->ci; ci != NULL; ci = ci->previous) {
190 ci->top.p = restorestack(L, ci->top.offset);
191 ci->func.p = restorestack(L, ci->func.offset);
199#define ERRORSTACKSIZE (LUAI_MAXSTACK + 200)
212int luaD_reallocstack (
lua_State *L,
int newsize,
int raiseerror) {
213 int oldsize = stacksize(L);
216 int oldgcstop = G(L)->gcstopem;
217 lua_assert(newsize <= LUAI_MAXSTACK || newsize == ERRORSTACKSIZE);
220 newstack = luaM_reallocvector(L, L->stack.p, oldsize + EXTRA_STACK,
222 G(L)->gcstopem = oldgcstop;
223 if (l_unlikely(newstack == NULL)) {
229 L->stack.p = newstack;
231 L->stack_last.p = L->stack.p + newsize;
232 for (i = oldsize + EXTRA_STACK; i < newsize + EXTRA_STACK; i++)
233 setnilvalue(s2v(newstack + i));
242int luaD_growstack (
lua_State *L,
int n,
int raiseerror) {
243 int size = stacksize(L);
244 if (l_unlikely(size > LUAI_MAXSTACK)) {
248 lua_assert(stacksize(L) == ERRORSTACKSIZE);
250 luaD_throw(L, LUA_ERRERR);
253 else if (n < LUAI_MAXSTACK) {
254 int newsize = 2 * size;
255 int needed = cast_int(L->top.p - L->stack.p) + n;
256 if (newsize > LUAI_MAXSTACK)
257 newsize = LUAI_MAXSTACK;
258 if (newsize < needed)
260 if (l_likely(newsize <= LUAI_MAXSTACK))
261 return luaD_reallocstack(L, newsize, raiseerror);
265 luaD_reallocstack(L, ERRORSTACKSIZE, raiseerror);
267 luaG_runerror(L,
"stack overflow");
279 StkId lim = L->top.p;
280 for (ci = L->ci; ci != NULL; ci = ci->previous) {
281 if (lim < ci->top.p) lim = ci->top.p;
283 lua_assert(lim <= L->stack_last.p + EXTRA_STACK);
284 res = cast_int(lim - L->stack.p) + 1;
285 if (res < LUA_MINSTACK)
301 int inuse = stackinuse(L);
302 int max = (inuse > LUAI_MAXSTACK / 3) ? LUAI_MAXSTACK : inuse * 3;
305 if (inuse <= LUAI_MAXSTACK && stacksize(L) > max) {
306 int nsize = (inuse > LUAI_MAXSTACK / 2) ? LUAI_MAXSTACK : inuse * 2;
307 luaD_reallocstack(L, nsize, 0);
310 condmovestack(L,{},{});
316 luaD_checkstack(L, 1);
328void luaD_hook (
lua_State *L,
int event,
int line,
329 int ftransfer,
int ntransfer) {
330 lua_Hook hook = L->hook;
331 if (hook && L->allowhook) {
332 int mask = CIST_HOOKED;
334 ptrdiff_t top = savestack(L, L->top.p);
335 ptrdiff_t ci_top = savestack(L, ci->top.p);
338 ar.currentline = line;
340 if (ntransfer != 0) {
342 ci->u2.transferinfo.ftransfer = ftransfer;
343 ci->u2.transferinfo.ntransfer = ntransfer;
345 if (isLua(ci) && L->top.p < ci->top.p)
346 L->top.p = ci->top.p;
347 luaD_checkstack(L, LUA_MINSTACK);
348 if (ci->top.p < L->top.p + LUA_MINSTACK)
349 ci->top.p = L->top.p + LUA_MINSTACK;
351 ci->callstatus |= mask;
355 lua_assert(!L->allowhook);
357 ci->top.p = restorestack(L, ci_top);
358 L->top.p = restorestack(L, top);
359 ci->callstatus &= ~mask;
371 if (L->hookmask & LUA_MASKCALL) {
372 int event = (ci->callstatus & CIST_TAIL) ? LUA_HOOKTAILCALL
374 Proto *p = ci_func(ci)->p;
376 luaD_hook(L, event, -1, 1, p->numparams);
388 if (L->hookmask & LUA_MASKRET) {
389 StkId firstres = L->top.p - nres;
393 Proto *p = ci_func(ci)->p;
395 delta = ci->u.l.nextraargs + p->numparams + 1;
398 ftransfer = cast(
unsigned short, firstres - ci->func.p);
399 luaD_hook(L, LUA_HOOKRET, -1, ftransfer, nres);
402 if (isLua(ci = ci->previous))
403 L->oldpc = pcRel(ci->u.l.savedpc, ci_func(ci)->p);
412StkId luaD_tryfuncTM (
lua_State *L, StkId func) {
415 checkstackGCp(L, 1, func);
416 tm = luaT_gettmbyobj(L, s2v(func), TM_CALL);
417 if (l_unlikely(ttisnil(tm)))
418 luaG_callerror(L, s2v(func));
419 for (p = L->top.p; p > func; p--)
420 setobjs2s(L, p, p-1);
422 setobj2s(L, func, tm);
433l_sinline
void moveresults (
lua_State *L, StkId res,
int nres,
int wanted) {
442 setnilvalue(s2v(res));
444 setobjs2s(L, res, L->top.p - nres);
451 if (hastocloseCfunc(wanted)) {
452 L->ci->callstatus |= CIST_CLSRET;
453 L->ci->u2.nres = nres;
454 res = luaF_close(L, res, CLOSEKTOP, 1);
455 L->ci->callstatus &= ~CIST_CLSRET;
457 ptrdiff_t savedres = savestack(L, res);
458 rethook(L, L->ci, nres);
459 res = restorestack(L, savedres);
461 wanted = decodeNresults(wanted);
462 if (wanted == LUA_MULTRET)
468 firstresult = L->top.p - nres;
471 for (i = 0; i < nres; i++)
472 setobjs2s(L, res + i, firstresult + i);
473 for (; i < wanted; i++)
474 setnilvalue(s2v(res + i));
475 L->top.p = res + wanted;
486 int wanted = ci->nresults;
487 if (l_unlikely(L->hookmask && !hastocloseCfunc(wanted)))
488 rethook(L, ci, nres);
490 moveresults(L, ci->func.p, nres, wanted);
492 lua_assert(!(ci->callstatus &
493 (CIST_HOOKED | CIST_YPCALL | CIST_FIN | CIST_TRAN | CIST_CLSRET)));
494 L->ci = ci->previous;
499#define next_ci(L) (L->ci->next ? L->ci->next : luaE_extendCI(L))
503 int mask, StkId top) {
507 ci->callstatus = mask;
516l_sinline
int precallC (
lua_State *L, StkId func,
int nresults,
520 checkstackGCp(L, LUA_MINSTACK, func);
521 L->ci = ci = prepCallInfo(L, func, nresults, CIST_C,
522 L->top.p + LUA_MINSTACK);
523 lua_assert(ci->top.p <= L->stack_last.p);
524 if (l_unlikely(L->hookmask & LUA_MASKCALL)) {
525 int narg = cast_int(L->top.p - func) - 1;
526 luaD_hook(L, LUA_HOOKCALL, -1, 1, narg);
531 api_checknelems(L, n);
532 luaD_poscall(L, ci, n);
544 int narg1,
int delta) {
546 switch (ttypetag(s2v(func))) {
548 return precallC(L, func, LUA_MULTRET, clCvalue(s2v(func))->f);
550 return precallC(L, func, LUA_MULTRET, fvalue(s2v(func)));
552 Proto *p = clLvalue(s2v(func))->p;
553 int fsize = p->maxstacksize;
554 int nfixparams = p->numparams;
556 checkstackGCp(L, fsize - delta, func);
558 for (i = 0; i < narg1; i++)
559 setobjs2s(L, ci->func.p + i, func + i);
561 for (; narg1 <= nfixparams; narg1++)
562 setnilvalue(s2v(func + narg1));
563 ci->top.p = func + 1 + fsize;
564 lua_assert(ci->top.p <= L->stack_last.p);
565 ci->u.l.savedpc = p->code;
566 ci->callstatus |= CIST_TAIL;
567 L->top.p = func + narg1;
571 func = luaD_tryfuncTM(L, func);
590 switch (ttypetag(s2v(func))) {
592 precallC(L, func, nresults, clCvalue(s2v(func))->f);
595 precallC(L, func, nresults, fvalue(s2v(func)));
599 Proto *p = clLvalue(s2v(func))->p;
600 int narg = cast_int(L->top.p - func) - 1;
601 int nfixparams = p->numparams;
602 int fsize = p->maxstacksize;
603 checkstackGCp(L, fsize, func);
604 L->ci = ci = prepCallInfo(L, func, nresults, 0, func + 1 + fsize);
605 ci->u.l.savedpc = p->code;
606 for (; narg < nfixparams; narg++)
607 setnilvalue(s2v(L->top.p++));
608 lua_assert(ci->top.p <= L->stack_last.p);
612 func = luaD_tryfuncTM(L, func);
628l_sinline
void ccall (
lua_State *L, StkId func,
int nResults, l_uint32 inc) {
631 if (l_unlikely(getCcalls(L) >= LUAI_MAXCCALLS)) {
632 checkstackp(L, 0, func);
635 if ((ci = luaD_precall(L, func, nResults)) != NULL) {
636 ci->callstatus = CIST_FRESH;
646void luaD_call (
lua_State *L, StkId func,
int nResults) {
647 ccall(L, func, nResults, 1);
654void luaD_callnoyield (
lua_State *L, StkId func,
int nResults) {
655 ccall(L, func, nResults, nyci);
676 int status = getcistrecst(ci);
677 if (l_likely(status == LUA_OK))
680 StkId func = restorestack(L, ci->u2.funcidx);
681 L->allowhook = getoah(ci->callstatus);
682 func = luaF_close(L, func, status, 1);
683 luaD_seterrorobj(L, status, func);
685 setcistrecst(ci, LUA_OK);
687 ci->callstatus &= ~CIST_YPCALL;
688 L->errfunc = ci->u.c.old_errfunc;
710 if (ci->callstatus & CIST_CLSRET) {
711 lua_assert(hastocloseCfunc(ci->nresults));
716 int status = LUA_YIELD;
718 lua_assert(ci->u.c.k != NULL && yieldable(L));
719 if (ci->callstatus & CIST_YPCALL)
720 status = finishpcallk(L, ci);
721 adjustresults(L, LUA_MULTRET);
723 n = (*ci->u.c.k)(L, status, ci->u.c.ctx);
725 api_checknelems(L, n);
727 luaD_poscall(L, ci, n);
736static void unroll (
lua_State *L,
void *ud) {
739 while ((ci = L->ci) != &L->base_ci) {
756 for (ci = L->ci; ci != NULL; ci = ci->previous) {
757 if (ci->callstatus & CIST_YPCALL)
769static int resume_error (
lua_State *L,
const char *msg,
int narg) {
771 setsvalue2s(L, L->top.p, luaS_new(L, msg));
785static void resume (
lua_State *L,
void *ud) {
786 int n = *(cast(
int*, ud));
787 StkId firstArg = L->top.p - n;
789 if (L->status == LUA_OK)
790 ccall(L, firstArg - 1, LUA_MULTRET, 0);
792 lua_assert(L->status == LUA_YIELD);
799 if (ci->u.c.k != NULL) {
801 n = (*ci->u.c.k)(L, LUA_YIELD, ci->u.c.ctx);
803 api_checknelems(L, n);
805 luaD_poscall(L, ci, n);
820static int precover (
lua_State *L,
int status) {
822 while (errorstatus(status) && (ci = findpcall(L)) != NULL) {
824 setcistrecst(ci, status);
825 status = luaD_rawrunprotected(L, unroll, NULL);
835 if (L->status == LUA_OK) {
836 if (L->ci != &L->base_ci)
837 return resume_error(L,
"cannot resume non-suspended coroutine", nargs);
838 else if (L->top.p - (L->ci->func.p + 1) == nargs)
839 return resume_error(L,
"cannot resume dead coroutine", nargs);
841 else if (L->status != LUA_YIELD)
842 return resume_error(L,
"cannot resume dead coroutine", nargs);
843 L->nCcalls = (from) ? getCcalls(from) : 0;
844 if (getCcalls(L) >= LUAI_MAXCCALLS)
845 return resume_error(L,
"C stack overflow", nargs);
847 luai_userstateresume(L, nargs);
848 api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs);
849 status = luaD_rawrunprotected(L, resume, &nargs);
851 status = precover(L, status);
852 if (l_likely(!errorstatus(status)))
853 lua_assert(status == L->status);
855 L->status = cast_byte(status);
856 luaD_seterrorobj(L, status, L->top.p);
857 L->ci->top.p = L->top.p;
859 *nresults = (status == LUA_YIELD) ? L->ci->u2.nyield
860 : cast_int(L->top.p - (L->ci->func.p + 1));
866LUA_API
int lua_isyieldable (
lua_State *L) {
871LUA_API
int lua_yieldk (
lua_State *L,
int nresults, lua_KContext ctx,
874 luai_userstateyield(L, nresults);
877 api_checknelems(L, nresults);
878 if (l_unlikely(!yieldable(L))) {
879 if (L != G(L)->mainthread)
880 luaG_runerror(L,
"attempt to yield across a C-call boundary");
882 luaG_runerror(L,
"attempt to yield from outside a coroutine");
884 L->status = LUA_YIELD;
885 ci->u2.nyield = nresults;
887 lua_assert(!isLuacode(ci));
888 api_check(L, nresults == 0,
"hooks cannot yield values");
889 api_check(L, k == NULL,
"hooks cannot continue after yielding");
892 if ((ci->u.c.k = k) != NULL)
894 luaD_throw(L, LUA_YIELD);
896 lua_assert(ci->callstatus & CIST_HOOKED);
914static void closepaux (
lua_State *L,
void *ud) {
916 luaF_close(L, pcl->level, pcl->status, 0);
924int luaD_closeprotected (
lua_State *L, ptrdiff_t level,
int status) {
926 lu_byte old_allowhooks = L->allowhook;
929 pcl.level = restorestack(L, level); pcl.status = status;
930 status = luaD_rawrunprotected(L, &closepaux, &pcl);
931 if (l_likely(status == LUA_OK))
935 L->allowhook = old_allowhooks;
946int luaD_pcall (
lua_State *L, Pfunc func,
void *u,
947 ptrdiff_t old_top, ptrdiff_t ef) {
950 lu_byte old_allowhooks = L->allowhook;
951 ptrdiff_t old_errfunc = L->errfunc;
953 status = luaD_rawrunprotected(L, func, u);
954 if (l_unlikely(status != LUA_OK)) {
956 L->allowhook = old_allowhooks;
957 status = luaD_closeprotected(L, old_top, status);
958 luaD_seterrorobj(L, status, restorestack(L, old_top));
961 L->errfunc = old_errfunc;
979static void checkmode (
lua_State *L,
const char *mode,
const char *x) {
980 if (mode && strchr(mode, x[0]) == NULL) {
982 "attempt to load a %s chunk (mode is '%s')", x, mode);
983 luaD_throw(L, LUA_ERRSYNTAX);
988static void f_parser (
lua_State *L,
void *ud) {
992 if (c == LUA_SIGNATURE[0]) {
993 checkmode(L, p->mode,
"binary");
994 cl = luaU_undump(L, p->z, p->name);
997 checkmode(L, p->mode,
"text");
998 cl = luaY_parser(L, p->z, &p->buff, &p->dyd, p->name, c);
1000 lua_assert(cl->nupvalues == cl->p->sizeupvalues);
1001 luaF_initupvals(L, cl);
1005int luaD_protectedparser (
lua_State *L, ZIO *z,
const char *name,
1010 p.z = z; p.name = name; p.mode = mode;
1011 p.dyd.actvar.arr = NULL; p.dyd.actvar.size = 0;
1012 p.dyd.gt.arr = NULL; p.dyd.gt.size = 0;
1013 p.dyd.label.arr = NULL; p.dyd.label.size = 0;
1014 luaZ_initbuffer(L, &p.buff);
1015 status = luaD_pcall(L, f_parser, &p, savestack(L, L->top.p), L->errfunc);
1016 luaZ_freebuffer(L, &p.buff);
1017 luaM_freearray(L, p.dyd.actvar.arr, p.dyd.actvar.size);
1018 luaM_freearray(L, p.dyd.gt.arr, p.dyd.gt.size);
1019 luaM_freearray(L, p.dyd.label.arr, p.dyd.label.size);