1*0a6a1f1dSLionel Sambuc /* $NetBSD: ldo.c,v 1.4 2015/10/08 13:21:00 mbalmer Exp $ */
211be35a1SLionel Sambuc
311be35a1SLionel Sambuc /*
4*0a6a1f1dSLionel Sambuc ** Id: ldo.c,v 2.138 2015/05/22 17:48:19 roberto Exp
511be35a1SLionel Sambuc ** Stack and Call structure of Lua
611be35a1SLionel Sambuc ** See Copyright Notice in lua.h
711be35a1SLionel Sambuc */
811be35a1SLionel Sambuc
911be35a1SLionel Sambuc #define ldo_c
1011be35a1SLionel Sambuc #define LUA_CORE
1111be35a1SLionel Sambuc
12*0a6a1f1dSLionel Sambuc #include "lprefix.h"
13*0a6a1f1dSLionel Sambuc
14*0a6a1f1dSLionel Sambuc
15*0a6a1f1dSLionel Sambuc #ifndef _KERNEL
16*0a6a1f1dSLionel Sambuc #include <setjmp.h>
17*0a6a1f1dSLionel Sambuc #include <stdlib.h>
18*0a6a1f1dSLionel Sambuc #include <string.h>
19*0a6a1f1dSLionel Sambuc #endif
20*0a6a1f1dSLionel Sambuc
2111be35a1SLionel Sambuc #include "lua.h"
2211be35a1SLionel Sambuc
23*0a6a1f1dSLionel Sambuc #include "lapi.h"
2411be35a1SLionel Sambuc #include "ldebug.h"
2511be35a1SLionel Sambuc #include "ldo.h"
2611be35a1SLionel Sambuc #include "lfunc.h"
2711be35a1SLionel Sambuc #include "lgc.h"
2811be35a1SLionel Sambuc #include "lmem.h"
2911be35a1SLionel Sambuc #include "lobject.h"
3011be35a1SLionel Sambuc #include "lopcodes.h"
3111be35a1SLionel Sambuc #include "lparser.h"
3211be35a1SLionel Sambuc #include "lstate.h"
3311be35a1SLionel Sambuc #include "lstring.h"
3411be35a1SLionel Sambuc #include "ltable.h"
3511be35a1SLionel Sambuc #include "ltm.h"
3611be35a1SLionel Sambuc #include "lundump.h"
3711be35a1SLionel Sambuc #include "lvm.h"
3811be35a1SLionel Sambuc #include "lzio.h"
3911be35a1SLionel Sambuc
4011be35a1SLionel Sambuc
4111be35a1SLionel Sambuc
42*0a6a1f1dSLionel Sambuc #define errorstatus(s) ((s) > LUA_YIELD)
43*0a6a1f1dSLionel Sambuc
4411be35a1SLionel Sambuc
4511be35a1SLionel Sambuc /*
4611be35a1SLionel Sambuc ** {======================================================
4711be35a1SLionel Sambuc ** Error-recovery functions
4811be35a1SLionel Sambuc ** =======================================================
4911be35a1SLionel Sambuc */
5011be35a1SLionel Sambuc
51*0a6a1f1dSLionel Sambuc /*
52*0a6a1f1dSLionel Sambuc ** LUAI_THROW/LUAI_TRY define how Lua does exception handling. By
53*0a6a1f1dSLionel Sambuc ** default, Lua handles errors with exceptions when compiling as
54*0a6a1f1dSLionel Sambuc ** C++ code, with _longjmp/_setjmp when asked to use them, and with
55*0a6a1f1dSLionel Sambuc ** longjmp/setjmp otherwise.
56*0a6a1f1dSLionel Sambuc */
57*0a6a1f1dSLionel Sambuc #if !defined(LUAI_THROW) /* { */
58*0a6a1f1dSLionel Sambuc
59*0a6a1f1dSLionel Sambuc #if defined(__cplusplus) && !defined(LUA_USE_LONGJMP) /* { */
60*0a6a1f1dSLionel Sambuc
61*0a6a1f1dSLionel Sambuc /* C++ exceptions */
62*0a6a1f1dSLionel Sambuc #define LUAI_THROW(L,c) throw(c)
63*0a6a1f1dSLionel Sambuc #define LUAI_TRY(L,c,a) \
64*0a6a1f1dSLionel Sambuc try { a } catch(...) { if ((c)->status == 0) (c)->status = -1; }
65*0a6a1f1dSLionel Sambuc #define luai_jmpbuf int /* dummy variable */
66*0a6a1f1dSLionel Sambuc
67*0a6a1f1dSLionel Sambuc #elif defined(LUA_USE_POSIX) /* }{ */
68*0a6a1f1dSLionel Sambuc
69*0a6a1f1dSLionel Sambuc /* in POSIX, try _longjmp/_setjmp (more efficient) */
70*0a6a1f1dSLionel Sambuc #define LUAI_THROW(L,c) _longjmp((c)->b, 1)
71*0a6a1f1dSLionel Sambuc #define LUAI_TRY(L,c,a) if (_setjmp((c)->b) == 0) { a }
72*0a6a1f1dSLionel Sambuc #define luai_jmpbuf jmp_buf
73*0a6a1f1dSLionel Sambuc
74*0a6a1f1dSLionel Sambuc #else /* }{ */
75*0a6a1f1dSLionel Sambuc
76*0a6a1f1dSLionel Sambuc /* ISO C handling with long jumps */
77*0a6a1f1dSLionel Sambuc #define LUAI_THROW(L,c) longjmp((c)->b, 1)
78*0a6a1f1dSLionel Sambuc #define LUAI_TRY(L,c,a) if (setjmp((c)->b) == 0) { a }
79*0a6a1f1dSLionel Sambuc #define luai_jmpbuf jmp_buf
80*0a6a1f1dSLionel Sambuc
81*0a6a1f1dSLionel Sambuc #endif /* } */
82*0a6a1f1dSLionel Sambuc
83*0a6a1f1dSLionel Sambuc #endif /* } */
84*0a6a1f1dSLionel Sambuc
85*0a6a1f1dSLionel Sambuc
8611be35a1SLionel Sambuc
8711be35a1SLionel Sambuc /* chain list of long jump buffers */
8811be35a1SLionel Sambuc struct lua_longjmp {
8911be35a1SLionel Sambuc struct lua_longjmp *previous;
9011be35a1SLionel Sambuc luai_jmpbuf b;
9111be35a1SLionel Sambuc volatile int status; /* error code */
9211be35a1SLionel Sambuc };
9311be35a1SLionel Sambuc
9411be35a1SLionel Sambuc
seterrorobj(lua_State * L,int errcode,StkId oldtop)95*0a6a1f1dSLionel Sambuc static void seterrorobj (lua_State *L, int errcode, StkId oldtop) {
9611be35a1SLionel Sambuc switch (errcode) {
97*0a6a1f1dSLionel Sambuc case LUA_ERRMEM: { /* memory error? */
98*0a6a1f1dSLionel Sambuc setsvalue2s(L, oldtop, G(L)->memerrmsg); /* reuse preregistered msg. */
9911be35a1SLionel Sambuc break;
10011be35a1SLionel Sambuc }
10111be35a1SLionel Sambuc case LUA_ERRERR: {
10211be35a1SLionel Sambuc setsvalue2s(L, oldtop, luaS_newliteral(L, "error in error handling"));
10311be35a1SLionel Sambuc break;
10411be35a1SLionel Sambuc }
105*0a6a1f1dSLionel Sambuc default: {
10611be35a1SLionel Sambuc setobjs2s(L, oldtop, L->top - 1); /* error message on current top */
10711be35a1SLionel Sambuc break;
10811be35a1SLionel Sambuc }
10911be35a1SLionel Sambuc }
11011be35a1SLionel Sambuc L->top = oldtop + 1;
11111be35a1SLionel Sambuc }
11211be35a1SLionel Sambuc
11311be35a1SLionel Sambuc
luaD_throw(lua_State * L,int errcode)114*0a6a1f1dSLionel Sambuc l_noret luaD_throw (lua_State *L, int errcode) {
115*0a6a1f1dSLionel Sambuc if (L->errorJmp) { /* thread has an error handler? */
116*0a6a1f1dSLionel Sambuc L->errorJmp->status = errcode; /* set status */
117*0a6a1f1dSLionel Sambuc LUAI_THROW(L, L->errorJmp); /* jump to it */
11811be35a1SLionel Sambuc }
119*0a6a1f1dSLionel Sambuc else { /* thread has no error handler */
120*0a6a1f1dSLionel Sambuc global_State *g = G(L);
121*0a6a1f1dSLionel Sambuc L->status = cast_byte(errcode); /* mark it as dead */
122*0a6a1f1dSLionel Sambuc if (g->mainthread->errorJmp) { /* main thread has a handler? */
123*0a6a1f1dSLionel Sambuc setobjs2s(L, g->mainthread->top++, L->top - 1); /* copy error obj. */
124*0a6a1f1dSLionel Sambuc luaD_throw(g->mainthread, errcode); /* re-throw in main thread */
12511be35a1SLionel Sambuc }
126*0a6a1f1dSLionel Sambuc else { /* no handler at all; abort */
127*0a6a1f1dSLionel Sambuc if (g->panic) { /* panic function? */
128*0a6a1f1dSLionel Sambuc seterrorobj(L, errcode, L->top); /* assume EXTRA_STACK */
129*0a6a1f1dSLionel Sambuc if (L->ci->top < L->top)
130*0a6a1f1dSLionel Sambuc L->ci->top = L->top; /* pushing msg. can break this invariant */
13111be35a1SLionel Sambuc lua_unlock(L);
132*0a6a1f1dSLionel Sambuc g->panic(L); /* call panic function (last chance to jump out) */
13311be35a1SLionel Sambuc }
134*0a6a1f1dSLionel Sambuc abort();
135*0a6a1f1dSLionel Sambuc }
13611be35a1SLionel Sambuc }
13711be35a1SLionel Sambuc }
13811be35a1SLionel Sambuc
13911be35a1SLionel Sambuc
luaD_rawrunprotected(lua_State * L,Pfunc f,void * ud)14011be35a1SLionel Sambuc int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) {
141*0a6a1f1dSLionel Sambuc unsigned short oldnCcalls = L->nCcalls;
14211be35a1SLionel Sambuc struct lua_longjmp lj;
143*0a6a1f1dSLionel Sambuc lj.status = LUA_OK;
14411be35a1SLionel Sambuc lj.previous = L->errorJmp; /* chain new error handler */
14511be35a1SLionel Sambuc L->errorJmp = &lj;
14611be35a1SLionel Sambuc LUAI_TRY(L, &lj,
14711be35a1SLionel Sambuc (*f)(L, ud);
14811be35a1SLionel Sambuc );
14911be35a1SLionel Sambuc L->errorJmp = lj.previous; /* restore old error handler */
150*0a6a1f1dSLionel Sambuc L->nCcalls = oldnCcalls;
15111be35a1SLionel Sambuc return lj.status;
15211be35a1SLionel Sambuc }
15311be35a1SLionel Sambuc
15411be35a1SLionel Sambuc /* }====================================================== */
15511be35a1SLionel Sambuc
15611be35a1SLionel Sambuc
correctstack(lua_State * L,TValue * oldstack)15711be35a1SLionel Sambuc static void correctstack (lua_State *L, TValue *oldstack) {
15811be35a1SLionel Sambuc CallInfo *ci;
159*0a6a1f1dSLionel Sambuc UpVal *up;
16011be35a1SLionel Sambuc L->top = (L->top - oldstack) + L->stack;
161*0a6a1f1dSLionel Sambuc for (up = L->openupval; up != NULL; up = up->u.open.next)
162*0a6a1f1dSLionel Sambuc up->v = (up->v - oldstack) + L->stack;
163*0a6a1f1dSLionel Sambuc for (ci = L->ci; ci != NULL; ci = ci->previous) {
16411be35a1SLionel Sambuc ci->top = (ci->top - oldstack) + L->stack;
16511be35a1SLionel Sambuc ci->func = (ci->func - oldstack) + L->stack;
166*0a6a1f1dSLionel Sambuc if (isLua(ci))
167*0a6a1f1dSLionel Sambuc ci->u.l.base = (ci->u.l.base - oldstack) + L->stack;
16811be35a1SLionel Sambuc }
16911be35a1SLionel Sambuc }
17011be35a1SLionel Sambuc
17111be35a1SLionel Sambuc
172*0a6a1f1dSLionel Sambuc /* some space for error handling */
173*0a6a1f1dSLionel Sambuc #define ERRORSTACKSIZE (LUAI_MAXSTACK + 200)
174*0a6a1f1dSLionel Sambuc
175*0a6a1f1dSLionel Sambuc
luaD_reallocstack(lua_State * L,int newsize)17611be35a1SLionel Sambuc void luaD_reallocstack (lua_State *L, int newsize) {
17711be35a1SLionel Sambuc TValue *oldstack = L->stack;
178*0a6a1f1dSLionel Sambuc int lim = L->stacksize;
179*0a6a1f1dSLionel Sambuc lua_assert(newsize <= LUAI_MAXSTACK || newsize == ERRORSTACKSIZE);
180*0a6a1f1dSLionel Sambuc lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK);
181*0a6a1f1dSLionel Sambuc luaM_reallocvector(L, L->stack, L->stacksize, newsize, TValue);
182*0a6a1f1dSLionel Sambuc for (; lim < newsize; lim++)
183*0a6a1f1dSLionel Sambuc setnilvalue(L->stack + lim); /* erase new segment */
184*0a6a1f1dSLionel Sambuc L->stacksize = newsize;
185*0a6a1f1dSLionel Sambuc L->stack_last = L->stack + newsize - EXTRA_STACK;
18611be35a1SLionel Sambuc correctstack(L, oldstack);
18711be35a1SLionel Sambuc }
18811be35a1SLionel Sambuc
18911be35a1SLionel Sambuc
luaD_growstack(lua_State * L,int n)19011be35a1SLionel Sambuc void luaD_growstack (lua_State *L, int n) {
191*0a6a1f1dSLionel Sambuc int size = L->stacksize;
192*0a6a1f1dSLionel Sambuc if (size > LUAI_MAXSTACK) /* error after extra size? */
19311be35a1SLionel Sambuc luaD_throw(L, LUA_ERRERR);
19411be35a1SLionel Sambuc else {
195*0a6a1f1dSLionel Sambuc int needed = cast_int(L->top - L->stack) + n + EXTRA_STACK;
196*0a6a1f1dSLionel Sambuc int newsize = 2 * size;
197*0a6a1f1dSLionel Sambuc if (newsize > LUAI_MAXSTACK) newsize = LUAI_MAXSTACK;
198*0a6a1f1dSLionel Sambuc if (newsize < needed) newsize = needed;
199*0a6a1f1dSLionel Sambuc if (newsize > LUAI_MAXSTACK) { /* stack overflow? */
200*0a6a1f1dSLionel Sambuc luaD_reallocstack(L, ERRORSTACKSIZE);
20111be35a1SLionel Sambuc luaG_runerror(L, "stack overflow");
20211be35a1SLionel Sambuc }
203*0a6a1f1dSLionel Sambuc else
204*0a6a1f1dSLionel Sambuc luaD_reallocstack(L, newsize);
205*0a6a1f1dSLionel Sambuc }
20611be35a1SLionel Sambuc }
20711be35a1SLionel Sambuc
20811be35a1SLionel Sambuc
stackinuse(lua_State * L)209*0a6a1f1dSLionel Sambuc static int stackinuse (lua_State *L) {
210*0a6a1f1dSLionel Sambuc CallInfo *ci;
211*0a6a1f1dSLionel Sambuc StkId lim = L->top;
212*0a6a1f1dSLionel Sambuc for (ci = L->ci; ci != NULL; ci = ci->previous) {
213*0a6a1f1dSLionel Sambuc lua_assert(ci->top <= L->stack_last);
214*0a6a1f1dSLionel Sambuc if (lim < ci->top) lim = ci->top;
215*0a6a1f1dSLionel Sambuc }
216*0a6a1f1dSLionel Sambuc return cast_int(lim - L->stack) + 1; /* part of stack in use */
217*0a6a1f1dSLionel Sambuc }
218*0a6a1f1dSLionel Sambuc
219*0a6a1f1dSLionel Sambuc
luaD_shrinkstack(lua_State * L)220*0a6a1f1dSLionel Sambuc void luaD_shrinkstack (lua_State *L) {
221*0a6a1f1dSLionel Sambuc int inuse = stackinuse(L);
222*0a6a1f1dSLionel Sambuc int goodsize = inuse + (inuse / 8) + 2*EXTRA_STACK;
223*0a6a1f1dSLionel Sambuc if (goodsize > LUAI_MAXSTACK) goodsize = LUAI_MAXSTACK;
224*0a6a1f1dSLionel Sambuc if (L->stacksize > LUAI_MAXSTACK) /* was handling stack overflow? */
225*0a6a1f1dSLionel Sambuc luaE_freeCI(L); /* free all CIs (list grew because of an error) */
226*0a6a1f1dSLionel Sambuc else
227*0a6a1f1dSLionel Sambuc luaE_shrinkCI(L); /* shrink list */
228*0a6a1f1dSLionel Sambuc if (inuse > LUAI_MAXSTACK || /* still handling stack overflow? */
229*0a6a1f1dSLionel Sambuc goodsize >= L->stacksize) /* would grow instead of shrink? */
230*0a6a1f1dSLionel Sambuc condmovestack(L); /* don't change stack (change only for debugging) */
231*0a6a1f1dSLionel Sambuc else
232*0a6a1f1dSLionel Sambuc luaD_reallocstack(L, goodsize); /* shrink it */
233*0a6a1f1dSLionel Sambuc }
234*0a6a1f1dSLionel Sambuc
235*0a6a1f1dSLionel Sambuc
luaD_hook(lua_State * L,int event,int line)236*0a6a1f1dSLionel Sambuc void luaD_hook (lua_State *L, int event, int line) {
23711be35a1SLionel Sambuc lua_Hook hook = L->hook;
23811be35a1SLionel Sambuc if (hook && L->allowhook) {
239*0a6a1f1dSLionel Sambuc CallInfo *ci = L->ci;
24011be35a1SLionel Sambuc ptrdiff_t top = savestack(L, L->top);
241*0a6a1f1dSLionel Sambuc ptrdiff_t ci_top = savestack(L, ci->top);
24211be35a1SLionel Sambuc lua_Debug ar;
24311be35a1SLionel Sambuc ar.event = event;
24411be35a1SLionel Sambuc ar.currentline = line;
245*0a6a1f1dSLionel Sambuc ar.i_ci = ci;
24611be35a1SLionel Sambuc luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
247*0a6a1f1dSLionel Sambuc ci->top = L->top + LUA_MINSTACK;
248*0a6a1f1dSLionel Sambuc lua_assert(ci->top <= L->stack_last);
24911be35a1SLionel Sambuc L->allowhook = 0; /* cannot call hooks inside a hook */
250*0a6a1f1dSLionel Sambuc ci->callstatus |= CIST_HOOKED;
25111be35a1SLionel Sambuc lua_unlock(L);
25211be35a1SLionel Sambuc (*hook)(L, &ar);
25311be35a1SLionel Sambuc lua_lock(L);
25411be35a1SLionel Sambuc lua_assert(!L->allowhook);
25511be35a1SLionel Sambuc L->allowhook = 1;
256*0a6a1f1dSLionel Sambuc ci->top = restorestack(L, ci_top);
25711be35a1SLionel Sambuc L->top = restorestack(L, top);
258*0a6a1f1dSLionel Sambuc ci->callstatus &= ~CIST_HOOKED;
25911be35a1SLionel Sambuc }
26011be35a1SLionel Sambuc }
26111be35a1SLionel Sambuc
26211be35a1SLionel Sambuc
callhook(lua_State * L,CallInfo * ci)263*0a6a1f1dSLionel Sambuc static void callhook (lua_State *L, CallInfo *ci) {
264*0a6a1f1dSLionel Sambuc int hook = LUA_HOOKCALL;
265*0a6a1f1dSLionel Sambuc ci->u.l.savedpc++; /* hooks assume 'pc' is already incremented */
266*0a6a1f1dSLionel Sambuc if (isLua(ci->previous) &&
267*0a6a1f1dSLionel Sambuc GET_OPCODE(*(ci->previous->u.l.savedpc - 1)) == OP_TAILCALL) {
268*0a6a1f1dSLionel Sambuc ci->callstatus |= CIST_TAIL;
269*0a6a1f1dSLionel Sambuc hook = LUA_HOOKTAILCALL;
270*0a6a1f1dSLionel Sambuc }
271*0a6a1f1dSLionel Sambuc luaD_hook(L, hook, -1);
272*0a6a1f1dSLionel Sambuc ci->u.l.savedpc--; /* correct 'pc' */
273*0a6a1f1dSLionel Sambuc }
274*0a6a1f1dSLionel Sambuc
275*0a6a1f1dSLionel Sambuc
adjust_varargs(lua_State * L,Proto * p,int actual)27611be35a1SLionel Sambuc static StkId adjust_varargs (lua_State *L, Proto *p, int actual) {
27711be35a1SLionel Sambuc int i;
27811be35a1SLionel Sambuc int nfixargs = p->numparams;
27911be35a1SLionel Sambuc StkId base, fixed;
280*0a6a1f1dSLionel Sambuc lua_assert(actual >= nfixargs);
28111be35a1SLionel Sambuc /* move fixed parameters to final position */
282*0a6a1f1dSLionel Sambuc luaD_checkstack(L, p->maxstacksize); /* check again for new 'base' */
28311be35a1SLionel Sambuc fixed = L->top - actual; /* first fixed argument */
28411be35a1SLionel Sambuc base = L->top; /* final position of first argument */
28511be35a1SLionel Sambuc for (i=0; i<nfixargs; i++) {
28611be35a1SLionel Sambuc setobjs2s(L, L->top++, fixed + i);
28711be35a1SLionel Sambuc setnilvalue(fixed + i);
28811be35a1SLionel Sambuc }
28911be35a1SLionel Sambuc return base;
29011be35a1SLionel Sambuc }
29111be35a1SLionel Sambuc
29211be35a1SLionel Sambuc
293*0a6a1f1dSLionel Sambuc /*
294*0a6a1f1dSLionel Sambuc ** Check whether __call metafield of 'func' is a function. If so, put
295*0a6a1f1dSLionel Sambuc ** it in stack below original 'func' so that 'luaD_precall' can call
296*0a6a1f1dSLionel Sambuc ** it. Raise an error if __call metafield is not a function.
297*0a6a1f1dSLionel Sambuc */
tryfuncTM(lua_State * L,StkId func)298*0a6a1f1dSLionel Sambuc static void tryfuncTM (lua_State *L, StkId func) {
29911be35a1SLionel Sambuc const TValue *tm = luaT_gettmbyobj(L, func, TM_CALL);
30011be35a1SLionel Sambuc StkId p;
30111be35a1SLionel Sambuc if (!ttisfunction(tm))
30211be35a1SLionel Sambuc luaG_typeerror(L, func, "call");
303*0a6a1f1dSLionel Sambuc /* Open a hole inside the stack at 'func' */
304*0a6a1f1dSLionel Sambuc for (p = L->top; p > func; p--)
305*0a6a1f1dSLionel Sambuc setobjs2s(L, p, p-1);
306*0a6a1f1dSLionel Sambuc L->top++; /* slot ensured by caller */
30711be35a1SLionel Sambuc setobj2s(L, func, tm); /* tag method is the new function to be called */
30811be35a1SLionel Sambuc }
30911be35a1SLionel Sambuc
31011be35a1SLionel Sambuc
31111be35a1SLionel Sambuc
312*0a6a1f1dSLionel Sambuc #define next_ci(L) (L->ci = (L->ci->next ? L->ci->next : luaE_extendCI(L)))
31311be35a1SLionel Sambuc
31411be35a1SLionel Sambuc
315*0a6a1f1dSLionel Sambuc /*
316*0a6a1f1dSLionel Sambuc ** returns true if function has been executed (C function)
317*0a6a1f1dSLionel Sambuc */
luaD_precall(lua_State * L,StkId func,int nresults)31811be35a1SLionel Sambuc int luaD_precall (lua_State *L, StkId func, int nresults) {
319*0a6a1f1dSLionel Sambuc lua_CFunction f;
32011be35a1SLionel Sambuc CallInfo *ci;
321*0a6a1f1dSLionel Sambuc int n; /* number of arguments (Lua) or returns (C) */
322*0a6a1f1dSLionel Sambuc ptrdiff_t funcr = savestack(L, func);
323*0a6a1f1dSLionel Sambuc switch (ttype(func)) {
324*0a6a1f1dSLionel Sambuc case LUA_TLCF: /* light C function */
325*0a6a1f1dSLionel Sambuc f = fvalue(func);
326*0a6a1f1dSLionel Sambuc goto Cfunc;
327*0a6a1f1dSLionel Sambuc case LUA_TCCL: { /* C closure */
328*0a6a1f1dSLionel Sambuc f = clCvalue(func)->f;
329*0a6a1f1dSLionel Sambuc Cfunc:
330*0a6a1f1dSLionel Sambuc luaC_checkGC(L); /* stack grow uses memory */
33111be35a1SLionel Sambuc luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
332*0a6a1f1dSLionel Sambuc ci = next_ci(L); /* now 'enter' new function */
333*0a6a1f1dSLionel Sambuc ci->nresults = nresults;
33411be35a1SLionel Sambuc ci->func = restorestack(L, funcr);
33511be35a1SLionel Sambuc ci->top = L->top + LUA_MINSTACK;
33611be35a1SLionel Sambuc lua_assert(ci->top <= L->stack_last);
337*0a6a1f1dSLionel Sambuc ci->callstatus = 0;
33811be35a1SLionel Sambuc if (L->hookmask & LUA_MASKCALL)
339*0a6a1f1dSLionel Sambuc luaD_hook(L, LUA_HOOKCALL, -1);
34011be35a1SLionel Sambuc lua_unlock(L);
341*0a6a1f1dSLionel Sambuc n = (*f)(L); /* do the actual call */
34211be35a1SLionel Sambuc lua_lock(L);
343*0a6a1f1dSLionel Sambuc api_checknelems(L, n);
344*0a6a1f1dSLionel Sambuc luaD_poscall(L, L->top - n, n);
345*0a6a1f1dSLionel Sambuc return 1;
346*0a6a1f1dSLionel Sambuc }
347*0a6a1f1dSLionel Sambuc case LUA_TLCL: { /* Lua function: prepare its call */
348*0a6a1f1dSLionel Sambuc StkId base;
349*0a6a1f1dSLionel Sambuc Proto *p = clLvalue(func)->p;
350*0a6a1f1dSLionel Sambuc n = cast_int(L->top - func) - 1; /* number of real arguments */
351*0a6a1f1dSLionel Sambuc luaC_checkGC(L); /* stack grow uses memory */
352*0a6a1f1dSLionel Sambuc luaD_checkstack(L, p->maxstacksize);
353*0a6a1f1dSLionel Sambuc for (; n < p->numparams; n++)
354*0a6a1f1dSLionel Sambuc setnilvalue(L->top++); /* complete missing arguments */
355*0a6a1f1dSLionel Sambuc if (!p->is_vararg) {
356*0a6a1f1dSLionel Sambuc func = restorestack(L, funcr);
357*0a6a1f1dSLionel Sambuc base = func + 1;
358*0a6a1f1dSLionel Sambuc }
35911be35a1SLionel Sambuc else {
360*0a6a1f1dSLionel Sambuc base = adjust_varargs(L, p, n);
361*0a6a1f1dSLionel Sambuc func = restorestack(L, funcr); /* previous call can change stack */
362*0a6a1f1dSLionel Sambuc }
363*0a6a1f1dSLionel Sambuc ci = next_ci(L); /* now 'enter' new function */
364*0a6a1f1dSLionel Sambuc ci->nresults = nresults;
365*0a6a1f1dSLionel Sambuc ci->func = func;
366*0a6a1f1dSLionel Sambuc ci->u.l.base = base;
367*0a6a1f1dSLionel Sambuc ci->top = base + p->maxstacksize;
368*0a6a1f1dSLionel Sambuc lua_assert(ci->top <= L->stack_last);
369*0a6a1f1dSLionel Sambuc ci->u.l.savedpc = p->code; /* starting point */
370*0a6a1f1dSLionel Sambuc ci->callstatus = CIST_LUA;
371*0a6a1f1dSLionel Sambuc L->top = ci->top;
372*0a6a1f1dSLionel Sambuc if (L->hookmask & LUA_MASKCALL)
373*0a6a1f1dSLionel Sambuc callhook(L, ci);
374*0a6a1f1dSLionel Sambuc return 0;
375*0a6a1f1dSLionel Sambuc }
376*0a6a1f1dSLionel Sambuc default: { /* not a function */
377*0a6a1f1dSLionel Sambuc luaD_checkstack(L, 1); /* ensure space for metamethod */
378*0a6a1f1dSLionel Sambuc func = restorestack(L, funcr); /* previous call may change stack */
379*0a6a1f1dSLionel Sambuc tryfuncTM(L, func); /* try to get '__call' metamethod */
380*0a6a1f1dSLionel Sambuc return luaD_precall(L, func, nresults); /* now it must be a function */
38111be35a1SLionel Sambuc }
38211be35a1SLionel Sambuc }
38311be35a1SLionel Sambuc }
38411be35a1SLionel Sambuc
38511be35a1SLionel Sambuc
luaD_poscall(lua_State * L,StkId firstResult,int nres)386*0a6a1f1dSLionel Sambuc int luaD_poscall (lua_State *L, StkId firstResult, int nres) {
38711be35a1SLionel Sambuc StkId res;
38811be35a1SLionel Sambuc int wanted, i;
389*0a6a1f1dSLionel Sambuc CallInfo *ci = L->ci;
390*0a6a1f1dSLionel Sambuc if (L->hookmask & (LUA_MASKRET | LUA_MASKLINE)) {
391*0a6a1f1dSLionel Sambuc if (L->hookmask & LUA_MASKRET) {
392*0a6a1f1dSLionel Sambuc ptrdiff_t fr = savestack(L, firstResult); /* hook may change stack */
393*0a6a1f1dSLionel Sambuc luaD_hook(L, LUA_HOOKRET, -1);
394*0a6a1f1dSLionel Sambuc firstResult = restorestack(L, fr);
395*0a6a1f1dSLionel Sambuc }
396*0a6a1f1dSLionel Sambuc L->oldpc = ci->previous->u.l.savedpc; /* 'oldpc' for caller function */
397*0a6a1f1dSLionel Sambuc }
39811be35a1SLionel Sambuc res = ci->func; /* res == final position of 1st result */
39911be35a1SLionel Sambuc wanted = ci->nresults;
400*0a6a1f1dSLionel Sambuc L->ci = ci->previous; /* back to caller */
40111be35a1SLionel Sambuc /* move results to correct place */
402*0a6a1f1dSLionel Sambuc for (i = wanted; i != 0 && nres-- > 0; i--)
40311be35a1SLionel Sambuc setobjs2s(L, res++, firstResult++);
40411be35a1SLionel Sambuc while (i-- > 0)
40511be35a1SLionel Sambuc setnilvalue(res++);
40611be35a1SLionel Sambuc L->top = res;
40711be35a1SLionel Sambuc return (wanted - LUA_MULTRET); /* 0 iff wanted == LUA_MULTRET */
40811be35a1SLionel Sambuc }
40911be35a1SLionel Sambuc
41011be35a1SLionel Sambuc
41111be35a1SLionel Sambuc /*
41211be35a1SLionel Sambuc ** Call a function (C or Lua). The function to be called is at *func.
41311be35a1SLionel Sambuc ** The arguments are on the stack, right after the function.
41411be35a1SLionel Sambuc ** When returns, all the results are on the stack, starting at the original
41511be35a1SLionel Sambuc ** function position.
41611be35a1SLionel Sambuc */
luaD_call(lua_State * L,StkId func,int nResults,int allowyield)417*0a6a1f1dSLionel Sambuc void luaD_call (lua_State *L, StkId func, int nResults, int allowyield) {
41811be35a1SLionel Sambuc if (++L->nCcalls >= LUAI_MAXCCALLS) {
41911be35a1SLionel Sambuc if (L->nCcalls == LUAI_MAXCCALLS)
42011be35a1SLionel Sambuc luaG_runerror(L, "C stack overflow");
42111be35a1SLionel Sambuc else if (L->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS>>3)))
42211be35a1SLionel Sambuc luaD_throw(L, LUA_ERRERR); /* error while handing stack error */
42311be35a1SLionel Sambuc }
424*0a6a1f1dSLionel Sambuc if (!allowyield) L->nny++;
425*0a6a1f1dSLionel Sambuc if (!luaD_precall(L, func, nResults)) /* is a Lua function? */
426*0a6a1f1dSLionel Sambuc luaV_execute(L); /* call it */
427*0a6a1f1dSLionel Sambuc if (!allowyield) L->nny--;
42811be35a1SLionel Sambuc L->nCcalls--;
42911be35a1SLionel Sambuc }
43011be35a1SLionel Sambuc
43111be35a1SLionel Sambuc
432*0a6a1f1dSLionel Sambuc /*
433*0a6a1f1dSLionel Sambuc ** Completes the execution of an interrupted C function, calling its
434*0a6a1f1dSLionel Sambuc ** continuation function.
435*0a6a1f1dSLionel Sambuc */
finishCcall(lua_State * L,int status)436*0a6a1f1dSLionel Sambuc static void finishCcall (lua_State *L, int status) {
43711be35a1SLionel Sambuc CallInfo *ci = L->ci;
438*0a6a1f1dSLionel Sambuc int n;
439*0a6a1f1dSLionel Sambuc /* must have a continuation and must be able to call it */
440*0a6a1f1dSLionel Sambuc lua_assert(ci->u.c.k != NULL && L->nny == 0);
441*0a6a1f1dSLionel Sambuc /* error status can only happen in a protected call */
442*0a6a1f1dSLionel Sambuc lua_assert((ci->callstatus & CIST_YPCALL) || status == LUA_YIELD);
443*0a6a1f1dSLionel Sambuc if (ci->callstatus & CIST_YPCALL) { /* was inside a pcall? */
444*0a6a1f1dSLionel Sambuc ci->callstatus &= ~CIST_YPCALL; /* finish 'lua_pcall' */
445*0a6a1f1dSLionel Sambuc L->errfunc = ci->u.c.old_errfunc;
44611be35a1SLionel Sambuc }
447*0a6a1f1dSLionel Sambuc /* finish 'lua_callk'/'lua_pcall'; CIST_YPCALL and 'errfunc' already
448*0a6a1f1dSLionel Sambuc handled */
449*0a6a1f1dSLionel Sambuc adjustresults(L, ci->nresults);
450*0a6a1f1dSLionel Sambuc /* call continuation function */
45111be35a1SLionel Sambuc lua_unlock(L);
452*0a6a1f1dSLionel Sambuc n = (*ci->u.c.k)(L, status, ci->u.c.ctx);
453*0a6a1f1dSLionel Sambuc lua_lock(L);
454*0a6a1f1dSLionel Sambuc api_checknelems(L, n);
455*0a6a1f1dSLionel Sambuc /* finish 'luaD_precall' */
456*0a6a1f1dSLionel Sambuc luaD_poscall(L, L->top - n, n);
45711be35a1SLionel Sambuc }
45811be35a1SLionel Sambuc
45911be35a1SLionel Sambuc
460*0a6a1f1dSLionel Sambuc /*
461*0a6a1f1dSLionel Sambuc ** Executes "full continuation" (everything in the stack) of a
462*0a6a1f1dSLionel Sambuc ** previously interrupted coroutine until the stack is empty (or another
463*0a6a1f1dSLionel Sambuc ** interruption long-jumps out of the loop). If the coroutine is
464*0a6a1f1dSLionel Sambuc ** recovering from an error, 'ud' points to the error status, which must
465*0a6a1f1dSLionel Sambuc ** be passed to the first continuation function (otherwise the default
466*0a6a1f1dSLionel Sambuc ** status is LUA_YIELD).
467*0a6a1f1dSLionel Sambuc */
unroll(lua_State * L,void * ud)468*0a6a1f1dSLionel Sambuc static void unroll (lua_State *L, void *ud) {
469*0a6a1f1dSLionel Sambuc if (ud != NULL) /* error status? */
470*0a6a1f1dSLionel Sambuc finishCcall(L, *(int *)ud); /* finish 'lua_pcallk' callee */
471*0a6a1f1dSLionel Sambuc while (L->ci != &L->base_ci) { /* something in the stack */
472*0a6a1f1dSLionel Sambuc if (!isLua(L->ci)) /* C function? */
473*0a6a1f1dSLionel Sambuc finishCcall(L, LUA_YIELD); /* complete its execution */
474*0a6a1f1dSLionel Sambuc else { /* Lua function */
475*0a6a1f1dSLionel Sambuc luaV_finishOp(L); /* finish interrupted instruction */
476*0a6a1f1dSLionel Sambuc luaV_execute(L); /* execute down to higher C 'boundary' */
477*0a6a1f1dSLionel Sambuc }
478*0a6a1f1dSLionel Sambuc }
479*0a6a1f1dSLionel Sambuc }
480*0a6a1f1dSLionel Sambuc
481*0a6a1f1dSLionel Sambuc
482*0a6a1f1dSLionel Sambuc /*
483*0a6a1f1dSLionel Sambuc ** Try to find a suspended protected call (a "recover point") for the
484*0a6a1f1dSLionel Sambuc ** given thread.
485*0a6a1f1dSLionel Sambuc */
findpcall(lua_State * L)486*0a6a1f1dSLionel Sambuc static CallInfo *findpcall (lua_State *L) {
487*0a6a1f1dSLionel Sambuc CallInfo *ci;
488*0a6a1f1dSLionel Sambuc for (ci = L->ci; ci != NULL; ci = ci->previous) { /* search for a pcall */
489*0a6a1f1dSLionel Sambuc if (ci->callstatus & CIST_YPCALL)
490*0a6a1f1dSLionel Sambuc return ci;
491*0a6a1f1dSLionel Sambuc }
492*0a6a1f1dSLionel Sambuc return NULL; /* no pending pcall */
493*0a6a1f1dSLionel Sambuc }
494*0a6a1f1dSLionel Sambuc
495*0a6a1f1dSLionel Sambuc
496*0a6a1f1dSLionel Sambuc /*
497*0a6a1f1dSLionel Sambuc ** Recovers from an error in a coroutine. Finds a recover point (if
498*0a6a1f1dSLionel Sambuc ** there is one) and completes the execution of the interrupted
499*0a6a1f1dSLionel Sambuc ** 'luaD_pcall'. If there is no recover point, returns zero.
500*0a6a1f1dSLionel Sambuc */
recover(lua_State * L,int status)501*0a6a1f1dSLionel Sambuc static int recover (lua_State *L, int status) {
502*0a6a1f1dSLionel Sambuc StkId oldtop;
503*0a6a1f1dSLionel Sambuc CallInfo *ci = findpcall(L);
504*0a6a1f1dSLionel Sambuc if (ci == NULL) return 0; /* no recovery point */
505*0a6a1f1dSLionel Sambuc /* "finish" luaD_pcall */
506*0a6a1f1dSLionel Sambuc oldtop = restorestack(L, ci->extra);
507*0a6a1f1dSLionel Sambuc luaF_close(L, oldtop);
508*0a6a1f1dSLionel Sambuc seterrorobj(L, status, oldtop);
509*0a6a1f1dSLionel Sambuc L->ci = ci;
510*0a6a1f1dSLionel Sambuc L->allowhook = getoah(ci->callstatus); /* restore original 'allowhook' */
511*0a6a1f1dSLionel Sambuc L->nny = 0; /* should be zero to be yieldable */
512*0a6a1f1dSLionel Sambuc luaD_shrinkstack(L);
513*0a6a1f1dSLionel Sambuc L->errfunc = ci->u.c.old_errfunc;
514*0a6a1f1dSLionel Sambuc return 1; /* continue running the coroutine */
515*0a6a1f1dSLionel Sambuc }
516*0a6a1f1dSLionel Sambuc
517*0a6a1f1dSLionel Sambuc
518*0a6a1f1dSLionel Sambuc /*
519*0a6a1f1dSLionel Sambuc ** signal an error in the call to 'resume', not in the execution of the
520*0a6a1f1dSLionel Sambuc ** coroutine itself. (Such errors should not be handled by any coroutine
521*0a6a1f1dSLionel Sambuc ** error handler and should not kill the coroutine.)
522*0a6a1f1dSLionel Sambuc */
resume_error(lua_State * L,const char * msg,StkId firstArg)523*0a6a1f1dSLionel Sambuc static l_noret resume_error (lua_State *L, const char *msg, StkId firstArg) {
524*0a6a1f1dSLionel Sambuc L->top = firstArg; /* remove args from the stack */
525*0a6a1f1dSLionel Sambuc setsvalue2s(L, L->top, luaS_new(L, msg)); /* push error message */
526*0a6a1f1dSLionel Sambuc api_incr_top(L);
527*0a6a1f1dSLionel Sambuc luaD_throw(L, -1); /* jump back to 'lua_resume' */
528*0a6a1f1dSLionel Sambuc }
529*0a6a1f1dSLionel Sambuc
530*0a6a1f1dSLionel Sambuc
531*0a6a1f1dSLionel Sambuc /*
532*0a6a1f1dSLionel Sambuc ** Do the work for 'lua_resume' in protected mode. Most of the work
533*0a6a1f1dSLionel Sambuc ** depends on the status of the coroutine: initial state, suspended
534*0a6a1f1dSLionel Sambuc ** inside a hook, or regularly suspended (optionally with a continuation
535*0a6a1f1dSLionel Sambuc ** function), plus erroneous cases: non-suspended coroutine or dead
536*0a6a1f1dSLionel Sambuc ** coroutine.
537*0a6a1f1dSLionel Sambuc */
resume(lua_State * L,void * ud)538*0a6a1f1dSLionel Sambuc static void resume (lua_State *L, void *ud) {
539*0a6a1f1dSLionel Sambuc int nCcalls = L->nCcalls;
540*0a6a1f1dSLionel Sambuc int n = *(cast(int*, ud)); /* number of arguments */
541*0a6a1f1dSLionel Sambuc StkId firstArg = L->top - n; /* first argument */
542*0a6a1f1dSLionel Sambuc CallInfo *ci = L->ci;
543*0a6a1f1dSLionel Sambuc if (nCcalls >= LUAI_MAXCCALLS)
544*0a6a1f1dSLionel Sambuc resume_error(L, "C stack overflow", firstArg);
545*0a6a1f1dSLionel Sambuc if (L->status == LUA_OK) { /* may be starting a coroutine */
546*0a6a1f1dSLionel Sambuc if (ci != &L->base_ci) /* not in base level? */
547*0a6a1f1dSLionel Sambuc resume_error(L, "cannot resume non-suspended coroutine", firstArg);
548*0a6a1f1dSLionel Sambuc /* coroutine is in base level; start running it */
549*0a6a1f1dSLionel Sambuc if (!luaD_precall(L, firstArg - 1, LUA_MULTRET)) /* Lua function? */
550*0a6a1f1dSLionel Sambuc luaV_execute(L); /* call it */
551*0a6a1f1dSLionel Sambuc }
552*0a6a1f1dSLionel Sambuc else if (L->status != LUA_YIELD)
553*0a6a1f1dSLionel Sambuc resume_error(L, "cannot resume dead coroutine", firstArg);
554*0a6a1f1dSLionel Sambuc else { /* resuming from previous yield */
555*0a6a1f1dSLionel Sambuc L->status = LUA_OK; /* mark that it is running (again) */
556*0a6a1f1dSLionel Sambuc ci->func = restorestack(L, ci->extra);
557*0a6a1f1dSLionel Sambuc if (isLua(ci)) /* yielded inside a hook? */
558*0a6a1f1dSLionel Sambuc luaV_execute(L); /* just continue running Lua code */
559*0a6a1f1dSLionel Sambuc else { /* 'common' yield */
560*0a6a1f1dSLionel Sambuc if (ci->u.c.k != NULL) { /* does it have a continuation function? */
561*0a6a1f1dSLionel Sambuc lua_unlock(L);
562*0a6a1f1dSLionel Sambuc n = (*ci->u.c.k)(L, LUA_YIELD, ci->u.c.ctx); /* call continuation */
56311be35a1SLionel Sambuc lua_lock(L);
564*0a6a1f1dSLionel Sambuc api_checknelems(L, n);
565*0a6a1f1dSLionel Sambuc firstArg = L->top - n; /* yield results come from continuation */
566*0a6a1f1dSLionel Sambuc }
567*0a6a1f1dSLionel Sambuc luaD_poscall(L, firstArg, n); /* finish 'luaD_precall' */
568*0a6a1f1dSLionel Sambuc }
569*0a6a1f1dSLionel Sambuc unroll(L, NULL); /* run continuation */
570*0a6a1f1dSLionel Sambuc }
571*0a6a1f1dSLionel Sambuc lua_assert(nCcalls == L->nCcalls);
572*0a6a1f1dSLionel Sambuc }
573*0a6a1f1dSLionel Sambuc
574*0a6a1f1dSLionel Sambuc
lua_resume(lua_State * L,lua_State * from,int nargs)575*0a6a1f1dSLionel Sambuc LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs) {
576*0a6a1f1dSLionel Sambuc int status;
577*0a6a1f1dSLionel Sambuc int oldnny = L->nny; /* save "number of non-yieldable" calls */
578*0a6a1f1dSLionel Sambuc lua_lock(L);
57911be35a1SLionel Sambuc luai_userstateresume(L, nargs);
580*0a6a1f1dSLionel Sambuc L->nCcalls = (from) ? from->nCcalls + 1 : 1;
581*0a6a1f1dSLionel Sambuc L->nny = 0; /* allow yields */
582*0a6a1f1dSLionel Sambuc api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs);
583*0a6a1f1dSLionel Sambuc status = luaD_rawrunprotected(L, resume, &nargs);
584*0a6a1f1dSLionel Sambuc if (status == -1) /* error calling 'lua_resume'? */
585*0a6a1f1dSLionel Sambuc status = LUA_ERRRUN;
586*0a6a1f1dSLionel Sambuc else { /* continue running after recoverable errors */
587*0a6a1f1dSLionel Sambuc while (errorstatus(status) && recover(L, status)) {
588*0a6a1f1dSLionel Sambuc /* unroll continuation */
589*0a6a1f1dSLionel Sambuc status = luaD_rawrunprotected(L, unroll, &status);
590*0a6a1f1dSLionel Sambuc }
591*0a6a1f1dSLionel Sambuc if (errorstatus(status)) { /* unrecoverable error? */
592*0a6a1f1dSLionel Sambuc L->status = cast_byte(status); /* mark thread as 'dead' */
593*0a6a1f1dSLionel Sambuc seterrorobj(L, status, L->top); /* push error message */
59411be35a1SLionel Sambuc L->ci->top = L->top;
59511be35a1SLionel Sambuc }
596*0a6a1f1dSLionel Sambuc else lua_assert(status == L->status); /* normal end or yield */
59711be35a1SLionel Sambuc }
598*0a6a1f1dSLionel Sambuc L->nny = oldnny; /* restore 'nny' */
599*0a6a1f1dSLionel Sambuc L->nCcalls--;
600*0a6a1f1dSLionel Sambuc lua_assert(L->nCcalls == ((from) ? from->nCcalls : 0));
60111be35a1SLionel Sambuc lua_unlock(L);
60211be35a1SLionel Sambuc return status;
60311be35a1SLionel Sambuc }
60411be35a1SLionel Sambuc
60511be35a1SLionel Sambuc
lua_isyieldable(lua_State * L)606*0a6a1f1dSLionel Sambuc LUA_API int lua_isyieldable (lua_State *L) {
607*0a6a1f1dSLionel Sambuc return (L->nny == 0);
608*0a6a1f1dSLionel Sambuc }
609*0a6a1f1dSLionel Sambuc
610*0a6a1f1dSLionel Sambuc
lua_yieldk(lua_State * L,int nresults,lua_KContext ctx,lua_KFunction k)611*0a6a1f1dSLionel Sambuc LUA_API int lua_yieldk (lua_State *L, int nresults, lua_KContext ctx,
612*0a6a1f1dSLionel Sambuc lua_KFunction k) {
613*0a6a1f1dSLionel Sambuc CallInfo *ci = L->ci;
61411be35a1SLionel Sambuc luai_userstateyield(L, nresults);
61511be35a1SLionel Sambuc lua_lock(L);
616*0a6a1f1dSLionel Sambuc api_checknelems(L, nresults);
617*0a6a1f1dSLionel Sambuc if (L->nny > 0) {
618*0a6a1f1dSLionel Sambuc if (L != G(L)->mainthread)
619*0a6a1f1dSLionel Sambuc luaG_runerror(L, "attempt to yield across a C-call boundary");
620*0a6a1f1dSLionel Sambuc else
621*0a6a1f1dSLionel Sambuc luaG_runerror(L, "attempt to yield from outside a coroutine");
622*0a6a1f1dSLionel Sambuc }
62311be35a1SLionel Sambuc L->status = LUA_YIELD;
624*0a6a1f1dSLionel Sambuc ci->extra = savestack(L, ci->func); /* save current 'func' */
625*0a6a1f1dSLionel Sambuc if (isLua(ci)) { /* inside a hook? */
626*0a6a1f1dSLionel Sambuc api_check(L, k == NULL, "hooks cannot continue after yielding");
627*0a6a1f1dSLionel Sambuc }
628*0a6a1f1dSLionel Sambuc else {
629*0a6a1f1dSLionel Sambuc if ((ci->u.c.k = k) != NULL) /* is there a continuation? */
630*0a6a1f1dSLionel Sambuc ci->u.c.ctx = ctx; /* save context */
631*0a6a1f1dSLionel Sambuc ci->func = L->top - nresults - 1; /* protect stack below results */
632*0a6a1f1dSLionel Sambuc luaD_throw(L, LUA_YIELD);
633*0a6a1f1dSLionel Sambuc }
634*0a6a1f1dSLionel Sambuc lua_assert(ci->callstatus & CIST_HOOKED); /* must be inside a hook */
63511be35a1SLionel Sambuc lua_unlock(L);
636*0a6a1f1dSLionel Sambuc return 0; /* return to 'luaD_hook' */
63711be35a1SLionel Sambuc }
63811be35a1SLionel Sambuc
63911be35a1SLionel Sambuc
luaD_pcall(lua_State * L,Pfunc func,void * u,ptrdiff_t old_top,ptrdiff_t ef)64011be35a1SLionel Sambuc int luaD_pcall (lua_State *L, Pfunc func, void *u,
64111be35a1SLionel Sambuc ptrdiff_t old_top, ptrdiff_t ef) {
64211be35a1SLionel Sambuc int status;
643*0a6a1f1dSLionel Sambuc CallInfo *old_ci = L->ci;
64411be35a1SLionel Sambuc lu_byte old_allowhooks = L->allowhook;
645*0a6a1f1dSLionel Sambuc unsigned short old_nny = L->nny;
64611be35a1SLionel Sambuc ptrdiff_t old_errfunc = L->errfunc;
64711be35a1SLionel Sambuc L->errfunc = ef;
64811be35a1SLionel Sambuc status = luaD_rawrunprotected(L, func, u);
649*0a6a1f1dSLionel Sambuc if (status != LUA_OK) { /* an error occurred? */
65011be35a1SLionel Sambuc StkId oldtop = restorestack(L, old_top);
651*0a6a1f1dSLionel Sambuc luaF_close(L, oldtop); /* close possible pending closures */
652*0a6a1f1dSLionel Sambuc seterrorobj(L, status, oldtop);
653*0a6a1f1dSLionel Sambuc L->ci = old_ci;
65411be35a1SLionel Sambuc L->allowhook = old_allowhooks;
655*0a6a1f1dSLionel Sambuc L->nny = old_nny;
656*0a6a1f1dSLionel Sambuc luaD_shrinkstack(L);
65711be35a1SLionel Sambuc }
65811be35a1SLionel Sambuc L->errfunc = old_errfunc;
65911be35a1SLionel Sambuc return status;
66011be35a1SLionel Sambuc }
66111be35a1SLionel Sambuc
66211be35a1SLionel Sambuc
66311be35a1SLionel Sambuc
66411be35a1SLionel Sambuc /*
66511be35a1SLionel Sambuc ** Execute a protected parser.
66611be35a1SLionel Sambuc */
667*0a6a1f1dSLionel Sambuc struct SParser { /* data to 'f_parser' */
66811be35a1SLionel Sambuc ZIO *z;
669*0a6a1f1dSLionel Sambuc Mbuffer buff; /* dynamic structure used by the scanner */
670*0a6a1f1dSLionel Sambuc Dyndata dyd; /* dynamic structures used by the parser */
671*0a6a1f1dSLionel Sambuc const char *mode;
67211be35a1SLionel Sambuc const char *name;
67311be35a1SLionel Sambuc };
67411be35a1SLionel Sambuc
675*0a6a1f1dSLionel Sambuc
checkmode(lua_State * L,const char * mode,const char * x)676*0a6a1f1dSLionel Sambuc static void checkmode (lua_State *L, const char *mode, const char *x) {
677*0a6a1f1dSLionel Sambuc if (mode && strchr(mode, x[0]) == NULL) {
678*0a6a1f1dSLionel Sambuc luaO_pushfstring(L,
679*0a6a1f1dSLionel Sambuc "attempt to load a %s chunk (mode is '%s')", x, mode);
680*0a6a1f1dSLionel Sambuc luaD_throw(L, LUA_ERRSYNTAX);
681*0a6a1f1dSLionel Sambuc }
68211be35a1SLionel Sambuc }
68311be35a1SLionel Sambuc
68411be35a1SLionel Sambuc
f_parser(lua_State * L,void * ud)685*0a6a1f1dSLionel Sambuc static void f_parser (lua_State *L, void *ud) {
686*0a6a1f1dSLionel Sambuc LClosure *cl;
687*0a6a1f1dSLionel Sambuc struct SParser *p = cast(struct SParser *, ud);
688*0a6a1f1dSLionel Sambuc int c = zgetc(p->z); /* read first character */
689*0a6a1f1dSLionel Sambuc if (c == LUA_SIGNATURE[0]) {
690*0a6a1f1dSLionel Sambuc checkmode(L, p->mode, "binary");
691*0a6a1f1dSLionel Sambuc cl = luaU_undump(L, p->z, &p->buff, p->name);
692*0a6a1f1dSLionel Sambuc }
693*0a6a1f1dSLionel Sambuc else {
694*0a6a1f1dSLionel Sambuc checkmode(L, p->mode, "text");
695*0a6a1f1dSLionel Sambuc cl = luaY_parser(L, p->z, &p->buff, &p->dyd, p->name, c);
696*0a6a1f1dSLionel Sambuc }
697*0a6a1f1dSLionel Sambuc lua_assert(cl->nupvalues == cl->p->sizeupvalues);
698*0a6a1f1dSLionel Sambuc luaF_initupvals(L, cl);
699*0a6a1f1dSLionel Sambuc }
700*0a6a1f1dSLionel Sambuc
701*0a6a1f1dSLionel Sambuc
luaD_protectedparser(lua_State * L,ZIO * z,const char * name,const char * mode)702*0a6a1f1dSLionel Sambuc int luaD_protectedparser (lua_State *L, ZIO *z, const char *name,
703*0a6a1f1dSLionel Sambuc const char *mode) {
70411be35a1SLionel Sambuc struct SParser p;
70511be35a1SLionel Sambuc int status;
706*0a6a1f1dSLionel Sambuc L->nny++; /* cannot yield during parsing */
707*0a6a1f1dSLionel Sambuc p.z = z; p.name = name; p.mode = mode;
708*0a6a1f1dSLionel Sambuc p.dyd.actvar.arr = NULL; p.dyd.actvar.size = 0;
709*0a6a1f1dSLionel Sambuc p.dyd.gt.arr = NULL; p.dyd.gt.size = 0;
710*0a6a1f1dSLionel Sambuc p.dyd.label.arr = NULL; p.dyd.label.size = 0;
71111be35a1SLionel Sambuc luaZ_initbuffer(L, &p.buff);
71211be35a1SLionel Sambuc status = luaD_pcall(L, f_parser, &p, savestack(L, L->top), L->errfunc);
71311be35a1SLionel Sambuc luaZ_freebuffer(L, &p.buff);
714*0a6a1f1dSLionel Sambuc luaM_freearray(L, p.dyd.actvar.arr, p.dyd.actvar.size);
715*0a6a1f1dSLionel Sambuc luaM_freearray(L, p.dyd.gt.arr, p.dyd.gt.size);
716*0a6a1f1dSLionel Sambuc luaM_freearray(L, p.dyd.label.arr, p.dyd.label.size);
717*0a6a1f1dSLionel Sambuc L->nny--;
71811be35a1SLionel Sambuc return status;
71911be35a1SLionel Sambuc }
72011be35a1SLionel Sambuc
72111be35a1SLionel Sambuc
722