1280405Srpaulo/* 2344220Skevans** $Id: ldo.c,v 2.157.1.1 2017/04/19 17:20:42 roberto Exp $ 3280405Srpaulo** Stack and Call structure of Lua 4280405Srpaulo** See Copyright Notice in lua.h 5280405Srpaulo*/ 6280405Srpaulo 7280405Srpaulo#define ldo_c 8280405Srpaulo#define LUA_CORE 9280405Srpaulo 10280405Srpaulo#include "lprefix.h" 11280405Srpaulo 12280405Srpaulo 13280405Srpaulo#include <setjmp.h> 14280405Srpaulo#include <stdlib.h> 15280405Srpaulo#include <string.h> 16280405Srpaulo 17280405Srpaulo#include "lua.h" 18280405Srpaulo 19280405Srpaulo#include "lapi.h" 20280405Srpaulo#include "ldebug.h" 21280405Srpaulo#include "ldo.h" 22280405Srpaulo#include "lfunc.h" 23280405Srpaulo#include "lgc.h" 24280405Srpaulo#include "lmem.h" 25280405Srpaulo#include "lobject.h" 26280405Srpaulo#include "lopcodes.h" 27280405Srpaulo#include "lparser.h" 28280405Srpaulo#include "lstate.h" 29280405Srpaulo#include "lstring.h" 30280405Srpaulo#include "ltable.h" 31280405Srpaulo#include "ltm.h" 32280405Srpaulo#include "lundump.h" 33280405Srpaulo#include "lvm.h" 34280405Srpaulo#include "lzio.h" 35280405Srpaulo 36280405Srpaulo 37280405Srpaulo 38280405Srpaulo#define errorstatus(s) ((s) > LUA_YIELD) 39280405Srpaulo 40280405Srpaulo 41280405Srpaulo/* 42280405Srpaulo** {====================================================== 43280405Srpaulo** Error-recovery functions 44280405Srpaulo** ======================================================= 45280405Srpaulo*/ 46280405Srpaulo 47280405Srpaulo/* 48280405Srpaulo** LUAI_THROW/LUAI_TRY define how Lua does exception handling. By 49280405Srpaulo** default, Lua handles errors with exceptions when compiling as 50280405Srpaulo** C++ code, with _longjmp/_setjmp when asked to use them, and with 51280405Srpaulo** longjmp/setjmp otherwise. 52280405Srpaulo*/ 53280405Srpaulo#if !defined(LUAI_THROW) /* { */ 54280405Srpaulo 55280405Srpaulo#if defined(__cplusplus) && !defined(LUA_USE_LONGJMP) /* { */ 56280405Srpaulo 57280405Srpaulo/* C++ exceptions */ 58280405Srpaulo#define LUAI_THROW(L,c) throw(c) 59280405Srpaulo#define LUAI_TRY(L,c,a) \ 60280405Srpaulo try { a } catch(...) { if ((c)->status == 0) (c)->status = -1; } 61280405Srpaulo#define luai_jmpbuf int /* dummy variable */ 62280405Srpaulo 63280405Srpaulo#elif defined(LUA_USE_POSIX) /* }{ */ 64280405Srpaulo 65280405Srpaulo/* in POSIX, try _longjmp/_setjmp (more efficient) */ 66280405Srpaulo#define LUAI_THROW(L,c) _longjmp((c)->b, 1) 67280405Srpaulo#define LUAI_TRY(L,c,a) if (_setjmp((c)->b) == 0) { a } 68280405Srpaulo#define luai_jmpbuf jmp_buf 69280405Srpaulo 70280405Srpaulo#else /* }{ */ 71280405Srpaulo 72280405Srpaulo/* ISO C handling with long jumps */ 73280405Srpaulo#define LUAI_THROW(L,c) longjmp((c)->b, 1) 74280405Srpaulo#define LUAI_TRY(L,c,a) if (setjmp((c)->b) == 0) { a } 75280405Srpaulo#define luai_jmpbuf jmp_buf 76280405Srpaulo 77280405Srpaulo#endif /* } */ 78280405Srpaulo 79280405Srpaulo#endif /* } */ 80280405Srpaulo 81280405Srpaulo 82280405Srpaulo 83280405Srpaulo/* chain list of long jump buffers */ 84280405Srpaulostruct lua_longjmp { 85280405Srpaulo struct lua_longjmp *previous; 86280405Srpaulo luai_jmpbuf b; 87280405Srpaulo volatile int status; /* error code */ 88280405Srpaulo}; 89280405Srpaulo 90280405Srpaulo 91280405Srpaulostatic void seterrorobj (lua_State *L, int errcode, StkId oldtop) { 92280405Srpaulo switch (errcode) { 93280405Srpaulo case LUA_ERRMEM: { /* memory error? */ 94280405Srpaulo setsvalue2s(L, oldtop, G(L)->memerrmsg); /* reuse preregistered msg. */ 95280405Srpaulo break; 96280405Srpaulo } 97280405Srpaulo case LUA_ERRERR: { 98280405Srpaulo setsvalue2s(L, oldtop, luaS_newliteral(L, "error in error handling")); 99280405Srpaulo break; 100280405Srpaulo } 101280405Srpaulo default: { 102280405Srpaulo setobjs2s(L, oldtop, L->top - 1); /* error message on current top */ 103280405Srpaulo break; 104280405Srpaulo } 105280405Srpaulo } 106280405Srpaulo L->top = oldtop + 1; 107280405Srpaulo} 108280405Srpaulo 109280405Srpaulo 110280405Srpaulol_noret luaD_throw (lua_State *L, int errcode) { 111280405Srpaulo if (L->errorJmp) { /* thread has an error handler? */ 112280405Srpaulo L->errorJmp->status = errcode; /* set status */ 113280405Srpaulo LUAI_THROW(L, L->errorJmp); /* jump to it */ 114280405Srpaulo } 115280405Srpaulo else { /* thread has no error handler */ 116280405Srpaulo global_State *g = G(L); 117280405Srpaulo L->status = cast_byte(errcode); /* mark it as dead */ 118280405Srpaulo if (g->mainthread->errorJmp) { /* main thread has a handler? */ 119280405Srpaulo setobjs2s(L, g->mainthread->top++, L->top - 1); /* copy error obj. */ 120280405Srpaulo luaD_throw(g->mainthread, errcode); /* re-throw in main thread */ 121280405Srpaulo } 122280405Srpaulo else { /* no handler at all; abort */ 123280405Srpaulo if (g->panic) { /* panic function? */ 124280405Srpaulo seterrorobj(L, errcode, L->top); /* assume EXTRA_STACK */ 125280405Srpaulo if (L->ci->top < L->top) 126280405Srpaulo L->ci->top = L->top; /* pushing msg. can break this invariant */ 127280405Srpaulo lua_unlock(L); 128280405Srpaulo g->panic(L); /* call panic function (last chance to jump out) */ 129280405Srpaulo } 130280405Srpaulo abort(); 131280405Srpaulo } 132280405Srpaulo } 133280405Srpaulo} 134280405Srpaulo 135280405Srpaulo 136280405Srpauloint luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) { 137280405Srpaulo unsigned short oldnCcalls = L->nCcalls; 138280405Srpaulo struct lua_longjmp lj; 139280405Srpaulo lj.status = LUA_OK; 140280405Srpaulo lj.previous = L->errorJmp; /* chain new error handler */ 141280405Srpaulo L->errorJmp = &lj; 142280405Srpaulo LUAI_TRY(L, &lj, 143280405Srpaulo (*f)(L, ud); 144280405Srpaulo ); 145280405Srpaulo L->errorJmp = lj.previous; /* restore old error handler */ 146280405Srpaulo L->nCcalls = oldnCcalls; 147280405Srpaulo return lj.status; 148280405Srpaulo} 149280405Srpaulo 150280405Srpaulo/* }====================================================== */ 151280405Srpaulo 152280405Srpaulo 153326344Simp/* 154326344Simp** {================================================================== 155326344Simp** Stack reallocation 156326344Simp** =================================================================== 157326344Simp*/ 158280405Srpaulostatic void correctstack (lua_State *L, TValue *oldstack) { 159280405Srpaulo CallInfo *ci; 160280405Srpaulo UpVal *up; 161280405Srpaulo L->top = (L->top - oldstack) + L->stack; 162280405Srpaulo for (up = L->openupval; up != NULL; up = up->u.open.next) 163280405Srpaulo up->v = (up->v - oldstack) + L->stack; 164280405Srpaulo for (ci = L->ci; ci != NULL; ci = ci->previous) { 165280405Srpaulo ci->top = (ci->top - oldstack) + L->stack; 166280405Srpaulo ci->func = (ci->func - oldstack) + L->stack; 167280405Srpaulo if (isLua(ci)) 168280405Srpaulo ci->u.l.base = (ci->u.l.base - oldstack) + L->stack; 169280405Srpaulo } 170280405Srpaulo} 171280405Srpaulo 172280405Srpaulo 173280405Srpaulo/* some space for error handling */ 174280405Srpaulo#define ERRORSTACKSIZE (LUAI_MAXSTACK + 200) 175280405Srpaulo 176280405Srpaulo 177280405Srpaulovoid luaD_reallocstack (lua_State *L, int newsize) { 178280405Srpaulo TValue *oldstack = L->stack; 179280405Srpaulo int lim = L->stacksize; 180280405Srpaulo lua_assert(newsize <= LUAI_MAXSTACK || newsize == ERRORSTACKSIZE); 181280405Srpaulo lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK); 182280405Srpaulo luaM_reallocvector(L, L->stack, L->stacksize, newsize, TValue); 183280405Srpaulo for (; lim < newsize; lim++) 184280405Srpaulo setnilvalue(L->stack + lim); /* erase new segment */ 185280405Srpaulo L->stacksize = newsize; 186280405Srpaulo L->stack_last = L->stack + newsize - EXTRA_STACK; 187280405Srpaulo correctstack(L, oldstack); 188280405Srpaulo} 189280405Srpaulo 190280405Srpaulo 191280405Srpaulovoid luaD_growstack (lua_State *L, int n) { 192280405Srpaulo int size = L->stacksize; 193280405Srpaulo if (size > LUAI_MAXSTACK) /* error after extra size? */ 194280405Srpaulo luaD_throw(L, LUA_ERRERR); 195280405Srpaulo else { 196280405Srpaulo int needed = cast_int(L->top - L->stack) + n + EXTRA_STACK; 197280405Srpaulo int newsize = 2 * size; 198280405Srpaulo if (newsize > LUAI_MAXSTACK) newsize = LUAI_MAXSTACK; 199280405Srpaulo if (newsize < needed) newsize = needed; 200280405Srpaulo if (newsize > LUAI_MAXSTACK) { /* stack overflow? */ 201280405Srpaulo luaD_reallocstack(L, ERRORSTACKSIZE); 202280405Srpaulo luaG_runerror(L, "stack overflow"); 203280405Srpaulo } 204280405Srpaulo else 205280405Srpaulo luaD_reallocstack(L, newsize); 206280405Srpaulo } 207280405Srpaulo} 208280405Srpaulo 209280405Srpaulo 210280405Srpaulostatic int stackinuse (lua_State *L) { 211280405Srpaulo CallInfo *ci; 212280405Srpaulo StkId lim = L->top; 213280405Srpaulo for (ci = L->ci; ci != NULL; ci = ci->previous) { 214280405Srpaulo if (lim < ci->top) lim = ci->top; 215280405Srpaulo } 216326344Simp lua_assert(lim <= L->stack_last); 217280405Srpaulo return cast_int(lim - L->stack) + 1; /* part of stack in use */ 218280405Srpaulo} 219280405Srpaulo 220280405Srpaulo 221280405Srpaulovoid luaD_shrinkstack (lua_State *L) { 222280405Srpaulo int inuse = stackinuse(L); 223280405Srpaulo int goodsize = inuse + (inuse / 8) + 2*EXTRA_STACK; 224326344Simp if (goodsize > LUAI_MAXSTACK) 225326344Simp goodsize = LUAI_MAXSTACK; /* respect stack limit */ 226326344Simp if (L->stacksize > LUAI_MAXSTACK) /* had been handling stack overflow? */ 227280405Srpaulo luaE_freeCI(L); /* free all CIs (list grew because of an error) */ 228280405Srpaulo else 229280405Srpaulo luaE_shrinkCI(L); /* shrink list */ 230326344Simp /* if thread is currently not handling a stack overflow and its 231326344Simp good size is smaller than current size, shrink its stack */ 232326344Simp if (inuse <= (LUAI_MAXSTACK - EXTRA_STACK) && 233326344Simp goodsize < L->stacksize) 234326344Simp luaD_reallocstack(L, goodsize); 235326344Simp else /* don't change stack */ 236326344Simp condmovestack(L,{},{}); /* (change only for debugging) */ 237280405Srpaulo} 238280405Srpaulo 239280405Srpaulo 240326344Simpvoid luaD_inctop (lua_State *L) { 241326344Simp luaD_checkstack(L, 1); 242326344Simp L->top++; 243326344Simp} 244326344Simp 245326344Simp/* }================================================================== */ 246326344Simp 247326344Simp 248326344Simp/* 249326344Simp** Call a hook for the given event. Make sure there is a hook to be 250326344Simp** called. (Both 'L->hook' and 'L->hookmask', which triggers this 251326344Simp** function, can be changed asynchronously by signals.) 252326344Simp*/ 253280405Srpaulovoid luaD_hook (lua_State *L, int event, int line) { 254280405Srpaulo lua_Hook hook = L->hook; 255326344Simp if (hook && L->allowhook) { /* make sure there is a hook */ 256280405Srpaulo CallInfo *ci = L->ci; 257280405Srpaulo ptrdiff_t top = savestack(L, L->top); 258280405Srpaulo ptrdiff_t ci_top = savestack(L, ci->top); 259280405Srpaulo lua_Debug ar; 260280405Srpaulo ar.event = event; 261280405Srpaulo ar.currentline = line; 262280405Srpaulo ar.i_ci = ci; 263280405Srpaulo luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ 264280405Srpaulo ci->top = L->top + LUA_MINSTACK; 265280405Srpaulo lua_assert(ci->top <= L->stack_last); 266280405Srpaulo L->allowhook = 0; /* cannot call hooks inside a hook */ 267280405Srpaulo ci->callstatus |= CIST_HOOKED; 268280405Srpaulo lua_unlock(L); 269280405Srpaulo (*hook)(L, &ar); 270280405Srpaulo lua_lock(L); 271280405Srpaulo lua_assert(!L->allowhook); 272280405Srpaulo L->allowhook = 1; 273280405Srpaulo ci->top = restorestack(L, ci_top); 274280405Srpaulo L->top = restorestack(L, top); 275280405Srpaulo ci->callstatus &= ~CIST_HOOKED; 276280405Srpaulo } 277280405Srpaulo} 278280405Srpaulo 279280405Srpaulo 280280405Srpaulostatic void callhook (lua_State *L, CallInfo *ci) { 281280405Srpaulo int hook = LUA_HOOKCALL; 282280405Srpaulo ci->u.l.savedpc++; /* hooks assume 'pc' is already incremented */ 283280405Srpaulo if (isLua(ci->previous) && 284280405Srpaulo GET_OPCODE(*(ci->previous->u.l.savedpc - 1)) == OP_TAILCALL) { 285280405Srpaulo ci->callstatus |= CIST_TAIL; 286280405Srpaulo hook = LUA_HOOKTAILCALL; 287280405Srpaulo } 288280405Srpaulo luaD_hook(L, hook, -1); 289280405Srpaulo ci->u.l.savedpc--; /* correct 'pc' */ 290280405Srpaulo} 291280405Srpaulo 292280405Srpaulo 293280405Srpaulostatic StkId adjust_varargs (lua_State *L, Proto *p, int actual) { 294280405Srpaulo int i; 295280405Srpaulo int nfixargs = p->numparams; 296280405Srpaulo StkId base, fixed; 297280405Srpaulo /* move fixed parameters to final position */ 298280405Srpaulo fixed = L->top - actual; /* first fixed argument */ 299280405Srpaulo base = L->top; /* final position of first argument */ 300326344Simp for (i = 0; i < nfixargs && i < actual; i++) { 301280405Srpaulo setobjs2s(L, L->top++, fixed + i); 302326344Simp setnilvalue(fixed + i); /* erase original copy (for GC) */ 303280405Srpaulo } 304326344Simp for (; i < nfixargs; i++) 305326344Simp setnilvalue(L->top++); /* complete missing arguments */ 306280405Srpaulo return base; 307280405Srpaulo} 308280405Srpaulo 309280405Srpaulo 310280405Srpaulo/* 311280405Srpaulo** Check whether __call metafield of 'func' is a function. If so, put 312280405Srpaulo** it in stack below original 'func' so that 'luaD_precall' can call 313280405Srpaulo** it. Raise an error if __call metafield is not a function. 314280405Srpaulo*/ 315280405Srpaulostatic void tryfuncTM (lua_State *L, StkId func) { 316280405Srpaulo const TValue *tm = luaT_gettmbyobj(L, func, TM_CALL); 317280405Srpaulo StkId p; 318280405Srpaulo if (!ttisfunction(tm)) 319280405Srpaulo luaG_typeerror(L, func, "call"); 320280405Srpaulo /* Open a hole inside the stack at 'func' */ 321280405Srpaulo for (p = L->top; p > func; p--) 322280405Srpaulo setobjs2s(L, p, p-1); 323280405Srpaulo L->top++; /* slot ensured by caller */ 324280405Srpaulo setobj2s(L, func, tm); /* tag method is the new function to be called */ 325280405Srpaulo} 326280405Srpaulo 327280405Srpaulo 328326344Simp/* 329326344Simp** Given 'nres' results at 'firstResult', move 'wanted' of them to 'res'. 330326344Simp** Handle most typical cases (zero results for commands, one result for 331326344Simp** expressions, multiple results for tail calls/single parameters) 332326344Simp** separated. 333326344Simp*/ 334326344Simpstatic int moveresults (lua_State *L, const TValue *firstResult, StkId res, 335326344Simp int nres, int wanted) { 336326344Simp switch (wanted) { /* handle typical cases separately */ 337326344Simp case 0: break; /* nothing to move */ 338326344Simp case 1: { /* one result needed */ 339326344Simp if (nres == 0) /* no results? */ 340326344Simp firstResult = luaO_nilobject; /* adjust with nil */ 341326344Simp setobjs2s(L, res, firstResult); /* move it to proper place */ 342326344Simp break; 343326344Simp } 344326344Simp case LUA_MULTRET: { 345326344Simp int i; 346326344Simp for (i = 0; i < nres; i++) /* move all results to correct place */ 347326344Simp setobjs2s(L, res + i, firstResult + i); 348326344Simp L->top = res + nres; 349326344Simp return 0; /* wanted == LUA_MULTRET */ 350326344Simp } 351326344Simp default: { 352326344Simp int i; 353326344Simp if (wanted <= nres) { /* enough results? */ 354326344Simp for (i = 0; i < wanted; i++) /* move wanted results to correct place */ 355326344Simp setobjs2s(L, res + i, firstResult + i); 356326344Simp } 357326344Simp else { /* not enough results; use all of them plus nils */ 358326344Simp for (i = 0; i < nres; i++) /* move all results to correct place */ 359326344Simp setobjs2s(L, res + i, firstResult + i); 360326344Simp for (; i < wanted; i++) /* complete wanted number of results */ 361326344Simp setnilvalue(res + i); 362326344Simp } 363326344Simp break; 364326344Simp } 365326344Simp } 366326344Simp L->top = res + wanted; /* top points after the last result */ 367326344Simp return 1; 368326344Simp} 369280405Srpaulo 370326344Simp 371326344Simp/* 372326344Simp** Finishes a function call: calls hook if necessary, removes CallInfo, 373326344Simp** moves current number of results to proper place; returns 0 iff call 374326344Simp** wanted multiple (variable number of) results. 375326344Simp*/ 376326344Simpint luaD_poscall (lua_State *L, CallInfo *ci, StkId firstResult, int nres) { 377326344Simp StkId res; 378326344Simp int wanted = ci->nresults; 379326344Simp if (L->hookmask & (LUA_MASKRET | LUA_MASKLINE)) { 380326344Simp if (L->hookmask & LUA_MASKRET) { 381326344Simp ptrdiff_t fr = savestack(L, firstResult); /* hook may change stack */ 382326344Simp luaD_hook(L, LUA_HOOKRET, -1); 383326344Simp firstResult = restorestack(L, fr); 384326344Simp } 385326344Simp L->oldpc = ci->previous->u.l.savedpc; /* 'oldpc' for caller function */ 386326344Simp } 387326344Simp res = ci->func; /* res == final position of 1st result */ 388326344Simp L->ci = ci->previous; /* back to caller */ 389326344Simp /* move results to proper place */ 390326344Simp return moveresults(L, firstResult, res, nres, wanted); 391326344Simp} 392326344Simp 393326344Simp 394326344Simp 395280405Srpaulo#define next_ci(L) (L->ci = (L->ci->next ? L->ci->next : luaE_extendCI(L))) 396280405Srpaulo 397280405Srpaulo 398326344Simp/* macro to check stack size, preserving 'p' */ 399326344Simp#define checkstackp(L,n,p) \ 400326344Simp luaD_checkstackaux(L, n, \ 401326344Simp ptrdiff_t t__ = savestack(L, p); /* save 'p' */ \ 402326344Simp luaC_checkGC(L), /* stack grow uses memory */ \ 403326344Simp p = restorestack(L, t__)) /* 'pos' part: restore 'p' */ 404326344Simp 405326344Simp 406280405Srpaulo/* 407326344Simp** Prepares a function call: checks the stack, creates a new CallInfo 408326344Simp** entry, fills in the relevant information, calls hook if needed. 409326344Simp** If function is a C function, does the call, too. (Otherwise, leave 410326344Simp** the execution ('luaV_execute') to the caller, to allow stackless 411326344Simp** calls.) Returns true iff function has been executed (C function). 412280405Srpaulo*/ 413280405Srpauloint luaD_precall (lua_State *L, StkId func, int nresults) { 414280405Srpaulo lua_CFunction f; 415280405Srpaulo CallInfo *ci; 416280405Srpaulo switch (ttype(func)) { 417326344Simp case LUA_TCCL: /* C closure */ 418326344Simp f = clCvalue(func)->f; 419326344Simp goto Cfunc; 420280405Srpaulo case LUA_TLCF: /* light C function */ 421280405Srpaulo f = fvalue(func); 422326344Simp Cfunc: { 423326344Simp int n; /* number of returns */ 424326344Simp checkstackp(L, LUA_MINSTACK, func); /* ensure minimum stack size */ 425280405Srpaulo ci = next_ci(L); /* now 'enter' new function */ 426280405Srpaulo ci->nresults = nresults; 427326344Simp ci->func = func; 428280405Srpaulo ci->top = L->top + LUA_MINSTACK; 429280405Srpaulo lua_assert(ci->top <= L->stack_last); 430280405Srpaulo ci->callstatus = 0; 431280405Srpaulo if (L->hookmask & LUA_MASKCALL) 432280405Srpaulo luaD_hook(L, LUA_HOOKCALL, -1); 433280405Srpaulo lua_unlock(L); 434280405Srpaulo n = (*f)(L); /* do the actual call */ 435280405Srpaulo lua_lock(L); 436280405Srpaulo api_checknelems(L, n); 437326344Simp luaD_poscall(L, ci, L->top - n, n); 438280405Srpaulo return 1; 439280405Srpaulo } 440280405Srpaulo case LUA_TLCL: { /* Lua function: prepare its call */ 441280405Srpaulo StkId base; 442280405Srpaulo Proto *p = clLvalue(func)->p; 443326344Simp int n = cast_int(L->top - func) - 1; /* number of real arguments */ 444326344Simp int fsize = p->maxstacksize; /* frame size */ 445326344Simp checkstackp(L, fsize, func); 446326344Simp if (p->is_vararg) 447326344Simp base = adjust_varargs(L, p, n); 448326344Simp else { /* non vararg function */ 449326344Simp for (; n < p->numparams; n++) 450326344Simp setnilvalue(L->top++); /* complete missing arguments */ 451280405Srpaulo base = func + 1; 452280405Srpaulo } 453280405Srpaulo ci = next_ci(L); /* now 'enter' new function */ 454280405Srpaulo ci->nresults = nresults; 455280405Srpaulo ci->func = func; 456280405Srpaulo ci->u.l.base = base; 457326344Simp L->top = ci->top = base + fsize; 458280405Srpaulo lua_assert(ci->top <= L->stack_last); 459280405Srpaulo ci->u.l.savedpc = p->code; /* starting point */ 460280405Srpaulo ci->callstatus = CIST_LUA; 461280405Srpaulo if (L->hookmask & LUA_MASKCALL) 462280405Srpaulo callhook(L, ci); 463280405Srpaulo return 0; 464280405Srpaulo } 465280405Srpaulo default: { /* not a function */ 466326344Simp checkstackp(L, 1, func); /* ensure space for metamethod */ 467280405Srpaulo tryfuncTM(L, func); /* try to get '__call' metamethod */ 468280405Srpaulo return luaD_precall(L, func, nresults); /* now it must be a function */ 469280405Srpaulo } 470280405Srpaulo } 471280405Srpaulo} 472280405Srpaulo 473280405Srpaulo 474326344Simp/* 475326344Simp** Check appropriate error for stack overflow ("regular" overflow or 476326344Simp** overflow while handling stack overflow). If 'nCalls' is larger than 477326344Simp** LUAI_MAXCCALLS (which means it is handling a "regular" overflow) but 478326344Simp** smaller than 9/8 of LUAI_MAXCCALLS, does not report an error (to 479326344Simp** allow overflow handling to work) 480326344Simp*/ 481326344Simpstatic void stackerror (lua_State *L) { 482326344Simp if (L->nCcalls == LUAI_MAXCCALLS) 483326344Simp luaG_runerror(L, "C stack overflow"); 484326344Simp else if (L->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS>>3))) 485326344Simp luaD_throw(L, LUA_ERRERR); /* error while handing stack error */ 486280405Srpaulo} 487280405Srpaulo 488280405Srpaulo 489280405Srpaulo/* 490280405Srpaulo** Call a function (C or Lua). The function to be called is at *func. 491280405Srpaulo** The arguments are on the stack, right after the function. 492280405Srpaulo** When returns, all the results are on the stack, starting at the original 493280405Srpaulo** function position. 494280405Srpaulo*/ 495326344Simpvoid luaD_call (lua_State *L, StkId func, int nResults) { 496326344Simp if (++L->nCcalls >= LUAI_MAXCCALLS) 497326344Simp stackerror(L); 498280405Srpaulo if (!luaD_precall(L, func, nResults)) /* is a Lua function? */ 499280405Srpaulo luaV_execute(L); /* call it */ 500280405Srpaulo L->nCcalls--; 501280405Srpaulo} 502280405Srpaulo 503280405Srpaulo 504280405Srpaulo/* 505326344Simp** Similar to 'luaD_call', but does not allow yields during the call 506326344Simp*/ 507326344Simpvoid luaD_callnoyield (lua_State *L, StkId func, int nResults) { 508326344Simp L->nny++; 509326344Simp luaD_call(L, func, nResults); 510326344Simp L->nny--; 511326344Simp} 512326344Simp 513326344Simp 514326344Simp/* 515280405Srpaulo** Completes the execution of an interrupted C function, calling its 516280405Srpaulo** continuation function. 517280405Srpaulo*/ 518280405Srpaulostatic void finishCcall (lua_State *L, int status) { 519280405Srpaulo CallInfo *ci = L->ci; 520280405Srpaulo int n; 521280405Srpaulo /* must have a continuation and must be able to call it */ 522280405Srpaulo lua_assert(ci->u.c.k != NULL && L->nny == 0); 523280405Srpaulo /* error status can only happen in a protected call */ 524280405Srpaulo lua_assert((ci->callstatus & CIST_YPCALL) || status == LUA_YIELD); 525280405Srpaulo if (ci->callstatus & CIST_YPCALL) { /* was inside a pcall? */ 526326344Simp ci->callstatus &= ~CIST_YPCALL; /* continuation is also inside it */ 527326344Simp L->errfunc = ci->u.c.old_errfunc; /* with the same error function */ 528280405Srpaulo } 529280405Srpaulo /* finish 'lua_callk'/'lua_pcall'; CIST_YPCALL and 'errfunc' already 530280405Srpaulo handled */ 531280405Srpaulo adjustresults(L, ci->nresults); 532280405Srpaulo lua_unlock(L); 533326344Simp n = (*ci->u.c.k)(L, status, ci->u.c.ctx); /* call continuation function */ 534280405Srpaulo lua_lock(L); 535280405Srpaulo api_checknelems(L, n); 536326344Simp luaD_poscall(L, ci, L->top - n, n); /* finish 'luaD_precall' */ 537280405Srpaulo} 538280405Srpaulo 539280405Srpaulo 540280405Srpaulo/* 541280405Srpaulo** Executes "full continuation" (everything in the stack) of a 542280405Srpaulo** previously interrupted coroutine until the stack is empty (or another 543280405Srpaulo** interruption long-jumps out of the loop). If the coroutine is 544280405Srpaulo** recovering from an error, 'ud' points to the error status, which must 545280405Srpaulo** be passed to the first continuation function (otherwise the default 546280405Srpaulo** status is LUA_YIELD). 547280405Srpaulo*/ 548280405Srpaulostatic void unroll (lua_State *L, void *ud) { 549280405Srpaulo if (ud != NULL) /* error status? */ 550280405Srpaulo finishCcall(L, *(int *)ud); /* finish 'lua_pcallk' callee */ 551280405Srpaulo while (L->ci != &L->base_ci) { /* something in the stack */ 552280405Srpaulo if (!isLua(L->ci)) /* C function? */ 553280405Srpaulo finishCcall(L, LUA_YIELD); /* complete its execution */ 554280405Srpaulo else { /* Lua function */ 555280405Srpaulo luaV_finishOp(L); /* finish interrupted instruction */ 556280405Srpaulo luaV_execute(L); /* execute down to higher C 'boundary' */ 557280405Srpaulo } 558280405Srpaulo } 559280405Srpaulo} 560280405Srpaulo 561280405Srpaulo 562280405Srpaulo/* 563280405Srpaulo** Try to find a suspended protected call (a "recover point") for the 564280405Srpaulo** given thread. 565280405Srpaulo*/ 566280405Srpaulostatic CallInfo *findpcall (lua_State *L) { 567280405Srpaulo CallInfo *ci; 568280405Srpaulo for (ci = L->ci; ci != NULL; ci = ci->previous) { /* search for a pcall */ 569280405Srpaulo if (ci->callstatus & CIST_YPCALL) 570280405Srpaulo return ci; 571280405Srpaulo } 572280405Srpaulo return NULL; /* no pending pcall */ 573280405Srpaulo} 574280405Srpaulo 575280405Srpaulo 576280405Srpaulo/* 577280405Srpaulo** Recovers from an error in a coroutine. Finds a recover point (if 578280405Srpaulo** there is one) and completes the execution of the interrupted 579280405Srpaulo** 'luaD_pcall'. If there is no recover point, returns zero. 580280405Srpaulo*/ 581280405Srpaulostatic int recover (lua_State *L, int status) { 582280405Srpaulo StkId oldtop; 583280405Srpaulo CallInfo *ci = findpcall(L); 584280405Srpaulo if (ci == NULL) return 0; /* no recovery point */ 585280405Srpaulo /* "finish" luaD_pcall */ 586280405Srpaulo oldtop = restorestack(L, ci->extra); 587280405Srpaulo luaF_close(L, oldtop); 588280405Srpaulo seterrorobj(L, status, oldtop); 589280405Srpaulo L->ci = ci; 590280405Srpaulo L->allowhook = getoah(ci->callstatus); /* restore original 'allowhook' */ 591280405Srpaulo L->nny = 0; /* should be zero to be yieldable */ 592280405Srpaulo luaD_shrinkstack(L); 593280405Srpaulo L->errfunc = ci->u.c.old_errfunc; 594280405Srpaulo return 1; /* continue running the coroutine */ 595280405Srpaulo} 596280405Srpaulo 597280405Srpaulo 598280405Srpaulo/* 599326344Simp** Signal an error in the call to 'lua_resume', not in the execution 600326344Simp** of the coroutine itself. (Such errors should not be handled by any 601326344Simp** coroutine error handler and should not kill the coroutine.) 602280405Srpaulo*/ 603326344Simpstatic int resume_error (lua_State *L, const char *msg, int narg) { 604326344Simp L->top -= narg; /* remove args from the stack */ 605280405Srpaulo setsvalue2s(L, L->top, luaS_new(L, msg)); /* push error message */ 606280405Srpaulo api_incr_top(L); 607326344Simp lua_unlock(L); 608326344Simp return LUA_ERRRUN; 609280405Srpaulo} 610280405Srpaulo 611280405Srpaulo 612280405Srpaulo/* 613280405Srpaulo** Do the work for 'lua_resume' in protected mode. Most of the work 614280405Srpaulo** depends on the status of the coroutine: initial state, suspended 615280405Srpaulo** inside a hook, or regularly suspended (optionally with a continuation 616280405Srpaulo** function), plus erroneous cases: non-suspended coroutine or dead 617280405Srpaulo** coroutine. 618280405Srpaulo*/ 619280405Srpaulostatic void resume (lua_State *L, void *ud) { 620326344Simp int n = *(cast(int*, ud)); /* number of arguments */ 621326344Simp StkId firstArg = L->top - n; /* first argument */ 622280405Srpaulo CallInfo *ci = L->ci; 623326344Simp if (L->status == LUA_OK) { /* starting a coroutine? */ 624280405Srpaulo if (!luaD_precall(L, firstArg - 1, LUA_MULTRET)) /* Lua function? */ 625280405Srpaulo luaV_execute(L); /* call it */ 626280405Srpaulo } 627280405Srpaulo else { /* resuming from previous yield */ 628326344Simp lua_assert(L->status == LUA_YIELD); 629280405Srpaulo L->status = LUA_OK; /* mark that it is running (again) */ 630280405Srpaulo ci->func = restorestack(L, ci->extra); 631280405Srpaulo if (isLua(ci)) /* yielded inside a hook? */ 632280405Srpaulo luaV_execute(L); /* just continue running Lua code */ 633280405Srpaulo else { /* 'common' yield */ 634280405Srpaulo if (ci->u.c.k != NULL) { /* does it have a continuation function? */ 635280405Srpaulo lua_unlock(L); 636280405Srpaulo n = (*ci->u.c.k)(L, LUA_YIELD, ci->u.c.ctx); /* call continuation */ 637280405Srpaulo lua_lock(L); 638280405Srpaulo api_checknelems(L, n); 639280405Srpaulo firstArg = L->top - n; /* yield results come from continuation */ 640280405Srpaulo } 641326344Simp luaD_poscall(L, ci, firstArg, n); /* finish 'luaD_precall' */ 642280405Srpaulo } 643280405Srpaulo unroll(L, NULL); /* run continuation */ 644280405Srpaulo } 645280405Srpaulo} 646280405Srpaulo 647280405Srpaulo 648280405SrpauloLUA_API int lua_resume (lua_State *L, lua_State *from, int nargs) { 649280405Srpaulo int status; 650326344Simp unsigned short oldnny = L->nny; /* save "number of non-yieldable" calls */ 651280405Srpaulo lua_lock(L); 652326344Simp if (L->status == LUA_OK) { /* may be starting a coroutine */ 653326344Simp if (L->ci != &L->base_ci) /* not in base level? */ 654326344Simp return resume_error(L, "cannot resume non-suspended coroutine", nargs); 655326344Simp } 656326344Simp else if (L->status != LUA_YIELD) 657326344Simp return resume_error(L, "cannot resume dead coroutine", nargs); 658326344Simp L->nCcalls = (from) ? from->nCcalls + 1 : 1; 659326344Simp if (L->nCcalls >= LUAI_MAXCCALLS) 660326344Simp return resume_error(L, "C stack overflow", nargs); 661280405Srpaulo luai_userstateresume(L, nargs); 662280405Srpaulo L->nny = 0; /* allow yields */ 663280405Srpaulo api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs); 664326344Simp status = luaD_rawrunprotected(L, resume, &nargs); 665280405Srpaulo if (status == -1) /* error calling 'lua_resume'? */ 666280405Srpaulo status = LUA_ERRRUN; 667280405Srpaulo else { /* continue running after recoverable errors */ 668280405Srpaulo while (errorstatus(status) && recover(L, status)) { 669280405Srpaulo /* unroll continuation */ 670280405Srpaulo status = luaD_rawrunprotected(L, unroll, &status); 671280405Srpaulo } 672280405Srpaulo if (errorstatus(status)) { /* unrecoverable error? */ 673280405Srpaulo L->status = cast_byte(status); /* mark thread as 'dead' */ 674280405Srpaulo seterrorobj(L, status, L->top); /* push error message */ 675280405Srpaulo L->ci->top = L->top; 676280405Srpaulo } 677280405Srpaulo else lua_assert(status == L->status); /* normal end or yield */ 678280405Srpaulo } 679280405Srpaulo L->nny = oldnny; /* restore 'nny' */ 680280405Srpaulo L->nCcalls--; 681280405Srpaulo lua_assert(L->nCcalls == ((from) ? from->nCcalls : 0)); 682280405Srpaulo lua_unlock(L); 683280405Srpaulo return status; 684280405Srpaulo} 685280405Srpaulo 686280405Srpaulo 687280405SrpauloLUA_API int lua_isyieldable (lua_State *L) { 688280405Srpaulo return (L->nny == 0); 689280405Srpaulo} 690280405Srpaulo 691280405Srpaulo 692280405SrpauloLUA_API int lua_yieldk (lua_State *L, int nresults, lua_KContext ctx, 693280405Srpaulo lua_KFunction k) { 694280405Srpaulo CallInfo *ci = L->ci; 695280405Srpaulo luai_userstateyield(L, nresults); 696280405Srpaulo lua_lock(L); 697280405Srpaulo api_checknelems(L, nresults); 698280405Srpaulo if (L->nny > 0) { 699280405Srpaulo if (L != G(L)->mainthread) 700280405Srpaulo luaG_runerror(L, "attempt to yield across a C-call boundary"); 701280405Srpaulo else 702280405Srpaulo luaG_runerror(L, "attempt to yield from outside a coroutine"); 703280405Srpaulo } 704280405Srpaulo L->status = LUA_YIELD; 705280405Srpaulo ci->extra = savestack(L, ci->func); /* save current 'func' */ 706280405Srpaulo if (isLua(ci)) { /* inside a hook? */ 707326344Simp api_check(L, k == NULL, "hooks cannot continue after yielding"); 708280405Srpaulo } 709280405Srpaulo else { 710280405Srpaulo if ((ci->u.c.k = k) != NULL) /* is there a continuation? */ 711280405Srpaulo ci->u.c.ctx = ctx; /* save context */ 712280405Srpaulo ci->func = L->top - nresults - 1; /* protect stack below results */ 713280405Srpaulo luaD_throw(L, LUA_YIELD); 714280405Srpaulo } 715280405Srpaulo lua_assert(ci->callstatus & CIST_HOOKED); /* must be inside a hook */ 716280405Srpaulo lua_unlock(L); 717280405Srpaulo return 0; /* return to 'luaD_hook' */ 718280405Srpaulo} 719280405Srpaulo 720280405Srpaulo 721280405Srpauloint luaD_pcall (lua_State *L, Pfunc func, void *u, 722280405Srpaulo ptrdiff_t old_top, ptrdiff_t ef) { 723280405Srpaulo int status; 724280405Srpaulo CallInfo *old_ci = L->ci; 725280405Srpaulo lu_byte old_allowhooks = L->allowhook; 726280405Srpaulo unsigned short old_nny = L->nny; 727280405Srpaulo ptrdiff_t old_errfunc = L->errfunc; 728280405Srpaulo L->errfunc = ef; 729280405Srpaulo status = luaD_rawrunprotected(L, func, u); 730280405Srpaulo if (status != LUA_OK) { /* an error occurred? */ 731280405Srpaulo StkId oldtop = restorestack(L, old_top); 732280405Srpaulo luaF_close(L, oldtop); /* close possible pending closures */ 733280405Srpaulo seterrorobj(L, status, oldtop); 734280405Srpaulo L->ci = old_ci; 735280405Srpaulo L->allowhook = old_allowhooks; 736280405Srpaulo L->nny = old_nny; 737280405Srpaulo luaD_shrinkstack(L); 738280405Srpaulo } 739280405Srpaulo L->errfunc = old_errfunc; 740280405Srpaulo return status; 741280405Srpaulo} 742280405Srpaulo 743280405Srpaulo 744280405Srpaulo 745280405Srpaulo/* 746280405Srpaulo** Execute a protected parser. 747280405Srpaulo*/ 748280405Srpaulostruct SParser { /* data to 'f_parser' */ 749280405Srpaulo ZIO *z; 750280405Srpaulo Mbuffer buff; /* dynamic structure used by the scanner */ 751280405Srpaulo Dyndata dyd; /* dynamic structures used by the parser */ 752280405Srpaulo const char *mode; 753280405Srpaulo const char *name; 754280405Srpaulo}; 755280405Srpaulo 756280405Srpaulo 757280405Srpaulostatic void checkmode (lua_State *L, const char *mode, const char *x) { 758280405Srpaulo if (mode && strchr(mode, x[0]) == NULL) { 759280405Srpaulo luaO_pushfstring(L, 760280405Srpaulo "attempt to load a %s chunk (mode is '%s')", x, mode); 761280405Srpaulo luaD_throw(L, LUA_ERRSYNTAX); 762280405Srpaulo } 763280405Srpaulo} 764280405Srpaulo 765280405Srpaulo 766280405Srpaulostatic void f_parser (lua_State *L, void *ud) { 767280405Srpaulo LClosure *cl; 768280405Srpaulo struct SParser *p = cast(struct SParser *, ud); 769280405Srpaulo int c = zgetc(p->z); /* read first character */ 770280405Srpaulo if (c == LUA_SIGNATURE[0]) { 771280405Srpaulo checkmode(L, p->mode, "binary"); 772326344Simp cl = luaU_undump(L, p->z, p->name); 773280405Srpaulo } 774280405Srpaulo else { 775280405Srpaulo checkmode(L, p->mode, "text"); 776280405Srpaulo cl = luaY_parser(L, p->z, &p->buff, &p->dyd, p->name, c); 777280405Srpaulo } 778280405Srpaulo lua_assert(cl->nupvalues == cl->p->sizeupvalues); 779280405Srpaulo luaF_initupvals(L, cl); 780280405Srpaulo} 781280405Srpaulo 782280405Srpaulo 783280405Srpauloint luaD_protectedparser (lua_State *L, ZIO *z, const char *name, 784280405Srpaulo const char *mode) { 785280405Srpaulo struct SParser p; 786280405Srpaulo int status; 787280405Srpaulo L->nny++; /* cannot yield during parsing */ 788280405Srpaulo p.z = z; p.name = name; p.mode = mode; 789280405Srpaulo p.dyd.actvar.arr = NULL; p.dyd.actvar.size = 0; 790280405Srpaulo p.dyd.gt.arr = NULL; p.dyd.gt.size = 0; 791280405Srpaulo p.dyd.label.arr = NULL; p.dyd.label.size = 0; 792280405Srpaulo luaZ_initbuffer(L, &p.buff); 793280405Srpaulo status = luaD_pcall(L, f_parser, &p, savestack(L, L->top), L->errfunc); 794280405Srpaulo luaZ_freebuffer(L, &p.buff); 795280405Srpaulo luaM_freearray(L, p.dyd.actvar.arr, p.dyd.actvar.size); 796280405Srpaulo luaM_freearray(L, p.dyd.gt.arr, p.dyd.gt.size); 797280405Srpaulo luaM_freearray(L, p.dyd.label.arr, p.dyd.label.size); 798280405Srpaulo L->nny--; 799280405Srpaulo return status; 800280405Srpaulo} 801280405Srpaulo 802280405Srpaulo 803