1/* $NetBSD$ */ 2 3/* 4** Id: ldo.c,v 2.38.1.3 2008/01/18 22:31:22 roberto Exp 5** Stack and Call structure of Lua 6** See Copyright Notice in lua.h 7*/ 8 9 10#include <setjmp.h> 11#include <stdlib.h> 12#include <string.h> 13 14#define ldo_c 15#define LUA_CORE 16 17#include "lua.h" 18 19#include "ldebug.h" 20#include "ldo.h" 21#include "lfunc.h" 22#include "lgc.h" 23#include "lmem.h" 24#include "lobject.h" 25#include "lopcodes.h" 26#include "lparser.h" 27#include "lstate.h" 28#include "lstring.h" 29#include "ltable.h" 30#include "ltm.h" 31#include "lundump.h" 32#include "lvm.h" 33#include "lzio.h" 34 35 36 37 38/* 39** {====================================================== 40** Error-recovery functions 41** ======================================================= 42*/ 43 44 45/* chain list of long jump buffers */ 46struct lua_longjmp { 47 struct lua_longjmp *previous; 48 luai_jmpbuf b; 49 volatile int status; /* error code */ 50}; 51 52 53void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop) { 54 switch (errcode) { 55 case LUA_ERRMEM: { 56 setsvalue2s(L, oldtop, luaS_newliteral(L, MEMERRMSG)); 57 break; 58 } 59 case LUA_ERRERR: { 60 setsvalue2s(L, oldtop, luaS_newliteral(L, "error in error handling")); 61 break; 62 } 63 case LUA_ERRSYNTAX: 64 case LUA_ERRRUN: { 65 setobjs2s(L, oldtop, L->top - 1); /* error message on current top */ 66 break; 67 } 68 } 69 L->top = oldtop + 1; 70} 71 72 73static void restore_stack_limit (lua_State *L) { 74 lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1); 75 if (L->size_ci > LUAI_MAXCALLS) { /* there was an overflow? */ 76 int inuse = cast_int(L->ci - L->base_ci); 77 if (inuse + 1 < LUAI_MAXCALLS) /* can `undo' overflow? */ 78 luaD_reallocCI(L, LUAI_MAXCALLS); 79 } 80} 81 82 83static void resetstack (lua_State *L, int status) { 84 L->ci = L->base_ci; 85 L->base = L->ci->base; 86 luaF_close(L, L->base); /* close eventual pending closures */ 87 luaD_seterrorobj(L, status, L->base); 88 L->nCcalls = L->baseCcalls; 89 L->allowhook = 1; 90 restore_stack_limit(L); 91 L->errfunc = 0; 92 L->errorJmp = NULL; 93} 94 95 96void luaD_throw (lua_State *L, int errcode) { 97 if (L->errorJmp) { 98 L->errorJmp->status = errcode; 99 LUAI_THROW(L, L->errorJmp); 100 } 101 else { 102 L->status = cast_byte(errcode); 103 if (G(L)->panic) { 104 resetstack(L, errcode); 105 lua_unlock(L); 106 G(L)->panic(L); 107 } 108 exit(EXIT_FAILURE); 109 } 110} 111 112 113int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) { 114 struct lua_longjmp lj; 115 lj.status = 0; 116 lj.previous = L->errorJmp; /* chain new error handler */ 117 L->errorJmp = &lj; 118 LUAI_TRY(L, &lj, 119 (*f)(L, ud); 120 ); 121 L->errorJmp = lj.previous; /* restore old error handler */ 122 return lj.status; 123} 124 125/* }====================================================== */ 126 127 128static void correctstack (lua_State *L, TValue *oldstack) { 129 CallInfo *ci; 130 GCObject *up; 131 L->top = (L->top - oldstack) + L->stack; 132 for (up = L->openupval; up != NULL; up = up->gch.next) 133 gco2uv(up)->v = (gco2uv(up)->v - oldstack) + L->stack; 134 for (ci = L->base_ci; ci <= L->ci; ci++) { 135 ci->top = (ci->top - oldstack) + L->stack; 136 ci->base = (ci->base - oldstack) + L->stack; 137 ci->func = (ci->func - oldstack) + L->stack; 138 } 139 L->base = (L->base - oldstack) + L->stack; 140} 141 142 143void luaD_reallocstack (lua_State *L, int newsize) { 144 TValue *oldstack = L->stack; 145 int realsize = newsize + 1 + EXTRA_STACK; 146 lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1); 147 luaM_reallocvector(L, L->stack, L->stacksize, realsize, TValue); 148 L->stacksize = realsize; 149 L->stack_last = L->stack+newsize; 150 correctstack(L, oldstack); 151} 152 153 154void luaD_reallocCI (lua_State *L, int newsize) { 155 CallInfo *oldci = L->base_ci; 156 luaM_reallocvector(L, L->base_ci, L->size_ci, newsize, CallInfo); 157 L->size_ci = newsize; 158 L->ci = (L->ci - oldci) + L->base_ci; 159 L->end_ci = L->base_ci + L->size_ci - 1; 160} 161 162 163void luaD_growstack (lua_State *L, int n) { 164 if (n <= L->stacksize) /* double size is enough? */ 165 luaD_reallocstack(L, 2*L->stacksize); 166 else 167 luaD_reallocstack(L, L->stacksize + n); 168} 169 170 171static CallInfo *growCI (lua_State *L) { 172 if (L->size_ci > LUAI_MAXCALLS) /* overflow while handling overflow? */ 173 luaD_throw(L, LUA_ERRERR); 174 else { 175 luaD_reallocCI(L, 2*L->size_ci); 176 if (L->size_ci > LUAI_MAXCALLS) 177 luaG_runerror(L, "stack overflow"); 178 } 179 return ++L->ci; 180} 181 182 183void luaD_callhook (lua_State *L, int event, int line) { 184 lua_Hook hook = L->hook; 185 if (hook && L->allowhook) { 186 ptrdiff_t top = savestack(L, L->top); 187 ptrdiff_t ci_top = savestack(L, L->ci->top); 188 lua_Debug ar; 189 ar.event = event; 190 ar.currentline = line; 191 if (event == LUA_HOOKTAILRET) 192 ar.i_ci = 0; /* tail call; no debug information about it */ 193 else 194 ar.i_ci = cast_int(L->ci - L->base_ci); 195 luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ 196 L->ci->top = L->top + LUA_MINSTACK; 197 lua_assert(L->ci->top <= L->stack_last); 198 L->allowhook = 0; /* cannot call hooks inside a hook */ 199 lua_unlock(L); 200 (*hook)(L, &ar); 201 lua_lock(L); 202 lua_assert(!L->allowhook); 203 L->allowhook = 1; 204 L->ci->top = restorestack(L, ci_top); 205 L->top = restorestack(L, top); 206 } 207} 208 209 210static StkId adjust_varargs (lua_State *L, Proto *p, int actual) { 211 int i; 212 int nfixargs = p->numparams; 213 Table *htab = NULL; 214 StkId base, fixed; 215 for (; actual < nfixargs; ++actual) 216 setnilvalue(L->top++); 217#if defined(LUA_COMPAT_VARARG) 218 if (p->is_vararg & VARARG_NEEDSARG) { /* compat. with old-style vararg? */ 219 int nvar = actual - nfixargs; /* number of extra arguments */ 220 lua_assert(p->is_vararg & VARARG_HASARG); 221 luaC_checkGC(L); 222 htab = luaH_new(L, nvar, 1); /* create `arg' table */ 223 for (i=0; i<nvar; i++) /* put extra arguments into `arg' table */ 224 setobj2n(L, luaH_setnum(L, htab, i+1), L->top - nvar + i); 225 /* store counter in field `n' */ 226 setnvalue(luaH_setstr(L, htab, luaS_newliteral(L, "n")), cast_num(nvar)); 227 } 228#endif 229 /* move fixed parameters to final position */ 230 fixed = L->top - actual; /* first fixed argument */ 231 base = L->top; /* final position of first argument */ 232 for (i=0; i<nfixargs; i++) { 233 setobjs2s(L, L->top++, fixed+i); 234 setnilvalue(fixed+i); 235 } 236 /* add `arg' parameter */ 237 if (htab) { 238 sethvalue(L, L->top++, htab); 239 lua_assert(iswhite(obj2gco(htab))); 240 } 241 return base; 242} 243 244 245static StkId tryfuncTM (lua_State *L, StkId func) { 246 const TValue *tm = luaT_gettmbyobj(L, func, TM_CALL); 247 StkId p; 248 ptrdiff_t funcr = savestack(L, func); 249 if (!ttisfunction(tm)) 250 luaG_typeerror(L, func, "call"); 251 /* Open a hole inside the stack at `func' */ 252 for (p = L->top; p > func; p--) setobjs2s(L, p, p-1); 253 incr_top(L); 254 func = restorestack(L, funcr); /* previous call may change stack */ 255 setobj2s(L, func, tm); /* tag method is the new function to be called */ 256 return func; 257} 258 259 260 261#define inc_ci(L) \ 262 ((L->ci == L->end_ci) ? growCI(L) : \ 263 (condhardstacktests(luaD_reallocCI(L, L->size_ci)), ++L->ci)) 264 265 266int luaD_precall (lua_State *L, StkId func, int nresults) { 267 LClosure *cl; 268 ptrdiff_t funcr; 269 if (!ttisfunction(func)) /* `func' is not a function? */ 270 func = tryfuncTM(L, func); /* check the `function' tag method */ 271 funcr = savestack(L, func); 272 cl = &clvalue(func)->l; 273 L->ci->savedpc = L->savedpc; 274 if (!cl->isC) { /* Lua function? prepare its call */ 275 CallInfo *ci; 276 StkId st, base; 277 Proto *p = cl->p; 278 luaD_checkstack(L, p->maxstacksize); 279 func = restorestack(L, funcr); 280 if (!p->is_vararg) { /* no varargs? */ 281 base = func + 1; 282 if (L->top > base + p->numparams) 283 L->top = base + p->numparams; 284 } 285 else { /* vararg function */ 286 int nargs = cast_int(L->top - func) - 1; 287 base = adjust_varargs(L, p, nargs); 288 func = restorestack(L, funcr); /* previous call may change the stack */ 289 } 290 ci = inc_ci(L); /* now `enter' new function */ 291 ci->func = func; 292 L->base = ci->base = base; 293 ci->top = L->base + p->maxstacksize; 294 lua_assert(ci->top <= L->stack_last); 295 L->savedpc = p->code; /* starting point */ 296 ci->tailcalls = 0; 297 ci->nresults = nresults; 298 for (st = L->top; st < ci->top; st++) 299 setnilvalue(st); 300 L->top = ci->top; 301 if (L->hookmask & LUA_MASKCALL) { 302 L->savedpc++; /* hooks assume 'pc' is already incremented */ 303 luaD_callhook(L, LUA_HOOKCALL, -1); 304 L->savedpc--; /* correct 'pc' */ 305 } 306 return PCRLUA; 307 } 308 else { /* if is a C function, call it */ 309 CallInfo *ci; 310 int n; 311 luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ 312 ci = inc_ci(L); /* now `enter' new function */ 313 ci->func = restorestack(L, funcr); 314 L->base = ci->base = ci->func + 1; 315 ci->top = L->top + LUA_MINSTACK; 316 lua_assert(ci->top <= L->stack_last); 317 ci->nresults = nresults; 318 if (L->hookmask & LUA_MASKCALL) 319 luaD_callhook(L, LUA_HOOKCALL, -1); 320 lua_unlock(L); 321 n = (*curr_func(L)->c.f)(L); /* do the actual call */ 322 lua_lock(L); 323 if (n < 0) /* yielding? */ 324 return PCRYIELD; 325 else { 326 luaD_poscall(L, L->top - n); 327 return PCRC; 328 } 329 } 330} 331 332 333static StkId callrethooks (lua_State *L, StkId firstResult) { 334 ptrdiff_t fr = savestack(L, firstResult); /* next call may change stack */ 335 luaD_callhook(L, LUA_HOOKRET, -1); 336 if (f_isLua(L->ci)) { /* Lua function? */ 337 while ((L->hookmask & LUA_MASKRET) && L->ci->tailcalls--) /* tail calls */ 338 luaD_callhook(L, LUA_HOOKTAILRET, -1); 339 } 340 return restorestack(L, fr); 341} 342 343 344int luaD_poscall (lua_State *L, StkId firstResult) { 345 StkId res; 346 int wanted, i; 347 CallInfo *ci; 348 if (L->hookmask & LUA_MASKRET) 349 firstResult = callrethooks(L, firstResult); 350 ci = L->ci--; 351 res = ci->func; /* res == final position of 1st result */ 352 wanted = ci->nresults; 353 L->base = (ci - 1)->base; /* restore base */ 354 L->savedpc = (ci - 1)->savedpc; /* restore savedpc */ 355 /* move results to correct place */ 356 for (i = wanted; i != 0 && firstResult < L->top; i--) 357 setobjs2s(L, res++, firstResult++); 358 while (i-- > 0) 359 setnilvalue(res++); 360 L->top = res; 361 return (wanted - LUA_MULTRET); /* 0 iff wanted == LUA_MULTRET */ 362} 363 364 365/* 366** Call a function (C or Lua). The function to be called is at *func. 367** The arguments are on the stack, right after the function. 368** When returns, all the results are on the stack, starting at the original 369** function position. 370*/ 371void luaD_call (lua_State *L, StkId func, int nResults) { 372 if (++L->nCcalls >= LUAI_MAXCCALLS) { 373 if (L->nCcalls == LUAI_MAXCCALLS) 374 luaG_runerror(L, "C stack overflow"); 375 else if (L->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS>>3))) 376 luaD_throw(L, LUA_ERRERR); /* error while handing stack error */ 377 } 378 if (luaD_precall(L, func, nResults) == PCRLUA) /* is a Lua function? */ 379 luaV_execute(L, 1); /* call it */ 380 L->nCcalls--; 381 luaC_checkGC(L); 382} 383 384 385static void resume (lua_State *L, void *ud) { 386 StkId firstArg = cast(StkId, ud); 387 CallInfo *ci = L->ci; 388 if (L->status == 0) { /* start coroutine? */ 389 lua_assert(ci == L->base_ci && firstArg > L->base); 390 if (luaD_precall(L, firstArg - 1, LUA_MULTRET) != PCRLUA) 391 return; 392 } 393 else { /* resuming from previous yield */ 394 lua_assert(L->status == LUA_YIELD); 395 L->status = 0; 396 if (!f_isLua(ci)) { /* `common' yield? */ 397 /* finish interrupted execution of `OP_CALL' */ 398 lua_assert(GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_CALL || 399 GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_TAILCALL); 400 if (luaD_poscall(L, firstArg)) /* complete it... */ 401 L->top = L->ci->top; /* and correct top if not multiple results */ 402 } 403 else /* yielded inside a hook: just continue its execution */ 404 L->base = L->ci->base; 405 } 406 luaV_execute(L, cast_int(L->ci - L->base_ci)); 407} 408 409 410static int resume_error (lua_State *L, const char *msg) { 411 L->top = L->ci->base; 412 setsvalue2s(L, L->top, luaS_new(L, msg)); 413 incr_top(L); 414 lua_unlock(L); 415 return LUA_ERRRUN; 416} 417 418 419LUA_API int lua_resume (lua_State *L, int nargs) { 420 int status; 421 lua_lock(L); 422 if (L->status != LUA_YIELD && (L->status != 0 || L->ci != L->base_ci)) 423 return resume_error(L, "cannot resume non-suspended coroutine"); 424 if (L->nCcalls >= LUAI_MAXCCALLS) 425 return resume_error(L, "C stack overflow"); 426 luai_userstateresume(L, nargs); 427 lua_assert(L->errfunc == 0); 428 L->baseCcalls = ++L->nCcalls; 429 status = luaD_rawrunprotected(L, resume, L->top - nargs); 430 if (status != 0) { /* error? */ 431 L->status = cast_byte(status); /* mark thread as `dead' */ 432 luaD_seterrorobj(L, status, L->top); 433 L->ci->top = L->top; 434 } 435 else { 436 lua_assert(L->nCcalls == L->baseCcalls); 437 status = L->status; 438 } 439 --L->nCcalls; 440 lua_unlock(L); 441 return status; 442} 443 444 445LUA_API int lua_yield (lua_State *L, int nresults) { 446 luai_userstateyield(L, nresults); 447 lua_lock(L); 448 if (L->nCcalls > L->baseCcalls) 449 luaG_runerror(L, "attempt to yield across metamethod/C-call boundary"); 450 L->base = L->top - nresults; /* protect stack slots below */ 451 L->status = LUA_YIELD; 452 lua_unlock(L); 453 return -1; 454} 455 456 457int luaD_pcall (lua_State *L, Pfunc func, void *u, 458 ptrdiff_t old_top, ptrdiff_t ef) { 459 int status; 460 unsigned short oldnCcalls = L->nCcalls; 461 ptrdiff_t old_ci = saveci(L, L->ci); 462 lu_byte old_allowhooks = L->allowhook; 463 ptrdiff_t old_errfunc = L->errfunc; 464 L->errfunc = ef; 465 status = luaD_rawrunprotected(L, func, u); 466 if (status != 0) { /* an error occurred? */ 467 StkId oldtop = restorestack(L, old_top); 468 luaF_close(L, oldtop); /* close eventual pending closures */ 469 luaD_seterrorobj(L, status, oldtop); 470 L->nCcalls = oldnCcalls; 471 L->ci = restoreci(L, old_ci); 472 L->base = L->ci->base; 473 L->savedpc = L->ci->savedpc; 474 L->allowhook = old_allowhooks; 475 restore_stack_limit(L); 476 } 477 L->errfunc = old_errfunc; 478 return status; 479} 480 481 482 483/* 484** Execute a protected parser. 485*/ 486struct SParser { /* data to `f_parser' */ 487 ZIO *z; 488 Mbuffer buff; /* buffer to be used by the scanner */ 489 const char *name; 490}; 491 492static void f_parser (lua_State *L, void *ud) { 493 int i; 494 Proto *tf; 495 Closure *cl; 496 struct SParser *p = cast(struct SParser *, ud); 497 int c = luaZ_lookahead(p->z); 498 luaC_checkGC(L); 499 tf = ((c == LUA_SIGNATURE[0]) ? luaU_undump : luaY_parser)(L, p->z, 500 &p->buff, p->name); 501 cl = luaF_newLclosure(L, tf->nups, hvalue(gt(L))); 502 cl->l.p = tf; 503 for (i = 0; i < tf->nups; i++) /* initialize eventual upvalues */ 504 cl->l.upvals[i] = luaF_newupval(L); 505 setclvalue(L, L->top, cl); 506 incr_top(L); 507} 508 509 510int luaD_protectedparser (lua_State *L, ZIO *z, const char *name) { 511 struct SParser p; 512 int status; 513 p.z = z; p.name = name; 514 luaZ_initbuffer(L, &p.buff); 515 status = luaD_pcall(L, f_parser, &p, savestack(L, L->top), L->errfunc); 516 luaZ_freebuffer(L, &p.buff); 517 return status; 518} 519 520 521