1 /* $NetBSD: ldo.c,v 1.1.1.2 2012/03/15 00:08:09 alnsn Exp $ */ 2 3 /* 4 ** $Id: ldo.c,v 1.1.1.2 2012/03/15 00:08:09 alnsn 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 */ 46 struct lua_longjmp { 47 struct lua_longjmp *previous; 48 luai_jmpbuf b; 49 volatile int status; /* error code */ 50 }; 51 52 53 void 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 73 static 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 83 static 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 96 void 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 113 int 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 128 static 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 143 void 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 154 void 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 163 void 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 171 static 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 183 void 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 210 static 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 luaD_checkstack(L, p->maxstacksize); 223 htab = luaH_new(L, nvar, 1); /* create `arg' table */ 224 for (i=0; i<nvar; i++) /* put extra arguments into `arg' table */ 225 setobj2n(L, luaH_setnum(L, htab, i+1), L->top - nvar + i); 226 /* store counter in field `n' */ 227 setnvalue(luaH_setstr(L, htab, luaS_newliteral(L, "n")), cast_num(nvar)); 228 } 229 #endif 230 /* move fixed parameters to final position */ 231 fixed = L->top - actual; /* first fixed argument */ 232 base = L->top; /* final position of first argument */ 233 for (i=0; i<nfixargs; i++) { 234 setobjs2s(L, L->top++, fixed+i); 235 setnilvalue(fixed+i); 236 } 237 /* add `arg' parameter */ 238 if (htab) { 239 sethvalue(L, L->top++, htab); 240 lua_assert(iswhite(obj2gco(htab))); 241 } 242 return base; 243 } 244 245 246 static StkId tryfuncTM (lua_State *L, StkId func) { 247 const TValue *tm = luaT_gettmbyobj(L, func, TM_CALL); 248 StkId p; 249 ptrdiff_t funcr = savestack(L, func); 250 if (!ttisfunction(tm)) 251 luaG_typeerror(L, func, "call"); 252 /* Open a hole inside the stack at `func' */ 253 for (p = L->top; p > func; p--) setobjs2s(L, p, p-1); 254 incr_top(L); 255 func = restorestack(L, funcr); /* previous call may change stack */ 256 setobj2s(L, func, tm); /* tag method is the new function to be called */ 257 return func; 258 } 259 260 261 262 #define inc_ci(L) \ 263 ((L->ci == L->end_ci) ? growCI(L) : \ 264 (condhardstacktests(luaD_reallocCI(L, L->size_ci)), ++L->ci)) 265 266 267 int luaD_precall (lua_State *L, StkId func, int nresults) { 268 LClosure *cl; 269 ptrdiff_t funcr; 270 if (!ttisfunction(func)) /* `func' is not a function? */ 271 func = tryfuncTM(L, func); /* check the `function' tag method */ 272 funcr = savestack(L, func); 273 cl = &clvalue(func)->l; 274 L->ci->savedpc = L->savedpc; 275 if (!cl->isC) { /* Lua function? prepare its call */ 276 CallInfo *ci; 277 StkId st, base; 278 Proto *p = cl->p; 279 luaD_checkstack(L, p->maxstacksize); 280 func = restorestack(L, funcr); 281 if (!p->is_vararg) { /* no varargs? */ 282 base = func + 1; 283 if (L->top > base + p->numparams) 284 L->top = base + p->numparams; 285 } 286 else { /* vararg function */ 287 int nargs = cast_int(L->top - func) - 1; 288 base = adjust_varargs(L, p, nargs); 289 func = restorestack(L, funcr); /* previous call may change the stack */ 290 } 291 ci = inc_ci(L); /* now `enter' new function */ 292 ci->func = func; 293 L->base = ci->base = base; 294 ci->top = L->base + p->maxstacksize; 295 lua_assert(ci->top <= L->stack_last); 296 L->savedpc = p->code; /* starting point */ 297 ci->tailcalls = 0; 298 ci->nresults = nresults; 299 for (st = L->top; st < ci->top; st++) 300 setnilvalue(st); 301 L->top = ci->top; 302 if (L->hookmask & LUA_MASKCALL) { 303 L->savedpc++; /* hooks assume 'pc' is already incremented */ 304 luaD_callhook(L, LUA_HOOKCALL, -1); 305 L->savedpc--; /* correct 'pc' */ 306 } 307 return PCRLUA; 308 } 309 else { /* if is a C function, call it */ 310 CallInfo *ci; 311 int n; 312 luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ 313 ci = inc_ci(L); /* now `enter' new function */ 314 ci->func = restorestack(L, funcr); 315 L->base = ci->base = ci->func + 1; 316 ci->top = L->top + LUA_MINSTACK; 317 lua_assert(ci->top <= L->stack_last); 318 ci->nresults = nresults; 319 if (L->hookmask & LUA_MASKCALL) 320 luaD_callhook(L, LUA_HOOKCALL, -1); 321 lua_unlock(L); 322 n = (*curr_func(L)->c.f)(L); /* do the actual call */ 323 lua_lock(L); 324 if (n < 0) /* yielding? */ 325 return PCRYIELD; 326 else { 327 luaD_poscall(L, L->top - n); 328 return PCRC; 329 } 330 } 331 } 332 333 334 static StkId callrethooks (lua_State *L, StkId firstResult) { 335 ptrdiff_t fr = savestack(L, firstResult); /* next call may change stack */ 336 luaD_callhook(L, LUA_HOOKRET, -1); 337 if (f_isLua(L->ci)) { /* Lua function? */ 338 while ((L->hookmask & LUA_MASKRET) && L->ci->tailcalls--) /* tail calls */ 339 luaD_callhook(L, LUA_HOOKTAILRET, -1); 340 } 341 return restorestack(L, fr); 342 } 343 344 345 int luaD_poscall (lua_State *L, StkId firstResult) { 346 StkId res; 347 int wanted, i; 348 CallInfo *ci; 349 if (L->hookmask & LUA_MASKRET) 350 firstResult = callrethooks(L, firstResult); 351 ci = L->ci--; 352 res = ci->func; /* res == final position of 1st result */ 353 wanted = ci->nresults; 354 L->base = (ci - 1)->base; /* restore base */ 355 L->savedpc = (ci - 1)->savedpc; /* restore savedpc */ 356 /* move results to correct place */ 357 for (i = wanted; i != 0 && firstResult < L->top; i--) 358 setobjs2s(L, res++, firstResult++); 359 while (i-- > 0) 360 setnilvalue(res++); 361 L->top = res; 362 return (wanted - LUA_MULTRET); /* 0 iff wanted == LUA_MULTRET */ 363 } 364 365 366 /* 367 ** Call a function (C or Lua). The function to be called is at *func. 368 ** The arguments are on the stack, right after the function. 369 ** When returns, all the results are on the stack, starting at the original 370 ** function position. 371 */ 372 void luaD_call (lua_State *L, StkId func, int nResults) { 373 if (++L->nCcalls >= LUAI_MAXCCALLS) { 374 if (L->nCcalls == LUAI_MAXCCALLS) 375 luaG_runerror(L, "C stack overflow"); 376 else if (L->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS>>3))) 377 luaD_throw(L, LUA_ERRERR); /* error while handing stack error */ 378 } 379 if (luaD_precall(L, func, nResults) == PCRLUA) /* is a Lua function? */ 380 luaV_execute(L, 1); /* call it */ 381 L->nCcalls--; 382 luaC_checkGC(L); 383 } 384 385 386 static void resume (lua_State *L, void *ud) { 387 StkId firstArg = cast(StkId, ud); 388 CallInfo *ci = L->ci; 389 if (L->status == 0) { /* start coroutine? */ 390 lua_assert(ci == L->base_ci && firstArg > L->base); 391 if (luaD_precall(L, firstArg - 1, LUA_MULTRET) != PCRLUA) 392 return; 393 } 394 else { /* resuming from previous yield */ 395 lua_assert(L->status == LUA_YIELD); 396 L->status = 0; 397 if (!f_isLua(ci)) { /* `common' yield? */ 398 /* finish interrupted execution of `OP_CALL' */ 399 lua_assert(GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_CALL || 400 GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_TAILCALL); 401 if (luaD_poscall(L, firstArg)) /* complete it... */ 402 L->top = L->ci->top; /* and correct top if not multiple results */ 403 } 404 else /* yielded inside a hook: just continue its execution */ 405 L->base = L->ci->base; 406 } 407 luaV_execute(L, cast_int(L->ci - L->base_ci)); 408 } 409 410 411 static int resume_error (lua_State *L, const char *msg) { 412 L->top = L->ci->base; 413 setsvalue2s(L, L->top, luaS_new(L, msg)); 414 incr_top(L); 415 lua_unlock(L); 416 return LUA_ERRRUN; 417 } 418 419 420 LUA_API int lua_resume (lua_State *L, int nargs) { 421 int status; 422 lua_lock(L); 423 if (L->status != LUA_YIELD && (L->status != 0 || L->ci != L->base_ci)) 424 return resume_error(L, "cannot resume non-suspended coroutine"); 425 if (L->nCcalls >= LUAI_MAXCCALLS) 426 return resume_error(L, "C stack overflow"); 427 luai_userstateresume(L, nargs); 428 lua_assert(L->errfunc == 0); 429 L->baseCcalls = ++L->nCcalls; 430 status = luaD_rawrunprotected(L, resume, L->top - nargs); 431 if (status != 0) { /* error? */ 432 L->status = cast_byte(status); /* mark thread as `dead' */ 433 luaD_seterrorobj(L, status, L->top); 434 L->ci->top = L->top; 435 } 436 else { 437 lua_assert(L->nCcalls == L->baseCcalls); 438 status = L->status; 439 } 440 --L->nCcalls; 441 lua_unlock(L); 442 return status; 443 } 444 445 446 LUA_API int lua_yield (lua_State *L, int nresults) { 447 luai_userstateyield(L, nresults); 448 lua_lock(L); 449 if (L->nCcalls > L->baseCcalls) 450 luaG_runerror(L, "attempt to yield across metamethod/C-call boundary"); 451 L->base = L->top - nresults; /* protect stack slots below */ 452 L->status = LUA_YIELD; 453 lua_unlock(L); 454 return -1; 455 } 456 457 458 int luaD_pcall (lua_State *L, Pfunc func, void *u, 459 ptrdiff_t old_top, ptrdiff_t ef) { 460 int status; 461 unsigned short oldnCcalls = L->nCcalls; 462 ptrdiff_t old_ci = saveci(L, L->ci); 463 lu_byte old_allowhooks = L->allowhook; 464 ptrdiff_t old_errfunc = L->errfunc; 465 L->errfunc = ef; 466 status = luaD_rawrunprotected(L, func, u); 467 if (status != 0) { /* an error occurred? */ 468 StkId oldtop = restorestack(L, old_top); 469 luaF_close(L, oldtop); /* close eventual pending closures */ 470 luaD_seterrorobj(L, status, oldtop); 471 L->nCcalls = oldnCcalls; 472 L->ci = restoreci(L, old_ci); 473 L->base = L->ci->base; 474 L->savedpc = L->ci->savedpc; 475 L->allowhook = old_allowhooks; 476 restore_stack_limit(L); 477 } 478 L->errfunc = old_errfunc; 479 return status; 480 } 481 482 483 484 /* 485 ** Execute a protected parser. 486 */ 487 struct SParser { /* data to `f_parser' */ 488 ZIO *z; 489 Mbuffer buff; /* buffer to be used by the scanner */ 490 const char *name; 491 }; 492 493 static void f_parser (lua_State *L, void *ud) { 494 int i; 495 Proto *tf; 496 Closure *cl; 497 struct SParser *p = cast(struct SParser *, ud); 498 int c = luaZ_lookahead(p->z); 499 luaC_checkGC(L); 500 tf = ((c == LUA_SIGNATURE[0]) ? luaU_undump : luaY_parser)(L, p->z, 501 &p->buff, p->name); 502 cl = luaF_newLclosure(L, tf->nups, hvalue(gt(L))); 503 cl->l.p = tf; 504 for (i = 0; i < tf->nups; i++) /* initialize eventual upvalues */ 505 cl->l.upvals[i] = luaF_newupval(L); 506 setclvalue(L, L->top, cl); 507 incr_top(L); 508 } 509 510 511 int luaD_protectedparser (lua_State *L, ZIO *z, const char *name) { 512 struct SParser p; 513 int status; 514 p.z = z; p.name = name; 515 luaZ_initbuffer(L, &p.buff); 516 status = luaD_pcall(L, f_parser, &p, savestack(L, L->top), L->errfunc); 517 luaZ_freebuffer(L, &p.buff); 518 return status; 519 } 520 521 522