1 /* 2 ** $Id: ldebug.c,v 2.121 2016/10/19 12:32:10 roberto Exp $ 3 ** Debug Interface 4 ** See Copyright Notice in lua.h 5 */ 6 7 #define ldebug_c 8 #define LUA_CORE 9 10 #include "lprefix.h" 11 12 13 #include <stdarg.h> 14 #include <stddef.h> 15 #include <string.h> 16 17 #include "lua.h" 18 19 #include "lapi.h" 20 #include "lcode.h" 21 #include "ldebug.h" 22 #include "ldo.h" 23 #include "lfunc.h" 24 #include "lobject.h" 25 #include "lopcodes.h" 26 #include "lstate.h" 27 #include "lstring.h" 28 #include "ltable.h" 29 #include "ltm.h" 30 #include "lvm.h" 31 32 33 34 #define noLuaClosure(f) ((f) == NULL || (f)->c.tt == LUA_TCCL) 35 36 37 /* Active Lua function (given call info) */ 38 #define ci_func(ci) (clLvalue((ci)->func)) 39 40 41 static const char *funcnamefromcode (lua_State *L, CallInfo *ci, 42 const char **name); 43 44 45 static int currentpc (CallInfo *ci) { 46 lua_assert(isLua(ci)); 47 return pcRel(ci->u.l.savedpc, ci_func(ci)->p); 48 } 49 50 51 static int currentline (CallInfo *ci) { 52 return getfuncline(ci_func(ci)->p, currentpc(ci)); 53 } 54 55 56 /* 57 ** If function yielded, its 'func' can be in the 'extra' field. The 58 ** next function restores 'func' to its correct value for debugging 59 ** purposes. (It exchanges 'func' and 'extra'; so, when called again, 60 ** after debugging, it also "re-restores" ** 'func' to its altered value. 61 */ 62 static void swapextra (lua_State *L) { 63 if (L->status == LUA_YIELD) { 64 CallInfo *ci = L->ci; /* get function that yielded */ 65 StkId temp = ci->func; /* exchange its 'func' and 'extra' values */ 66 ci->func = restorestack(L, ci->extra); 67 ci->extra = savestack(L, temp); 68 } 69 } 70 71 72 /* 73 ** This function can be called asynchronously (e.g. during a signal). 74 ** Fields 'oldpc', 'basehookcount', and 'hookcount' (set by 75 ** 'resethookcount') are for debug only, and it is no problem if they 76 ** get arbitrary values (causes at most one wrong hook call). 'hookmask' 77 ** is an atomic value. We assume that pointers are atomic too (e.g., gcc 78 ** ensures that for all platforms where it runs). Moreover, 'hook' is 79 ** always checked before being called (see 'luaD_hook'). 80 */ 81 LUA_API void lua_sethook (lua_State *L, lua_Hook func, int mask, int count) { 82 if (func == NULL || mask == 0) { /* turn off hooks? */ 83 mask = 0; 84 func = NULL; 85 } 86 if (isLua(L->ci)) 87 L->oldpc = L->ci->u.l.savedpc; 88 L->hook = func; 89 L->basehookcount = count; 90 resethookcount(L); 91 L->hookmask = cast_byte(mask); 92 } 93 94 95 LUA_API lua_Hook lua_gethook (lua_State *L) { 96 return L->hook; 97 } 98 99 100 LUA_API int lua_gethookmask (lua_State *L) { 101 return L->hookmask; 102 } 103 104 105 LUA_API int lua_gethookcount (lua_State *L) { 106 return L->basehookcount; 107 } 108 109 110 LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) { 111 int status; 112 CallInfo *ci; 113 if (level < 0) return 0; /* invalid (negative) level */ 114 lua_lock(L); 115 for (ci = L->ci; level > 0 && ci != &L->base_ci; ci = ci->previous) 116 level--; 117 if (level == 0 && ci != &L->base_ci) { /* level found? */ 118 status = 1; 119 ar->i_ci = ci; 120 } 121 else status = 0; /* no such level */ 122 lua_unlock(L); 123 return status; 124 } 125 126 127 static const char *upvalname (Proto *p, int uv) { 128 TString *s = check_exp(uv < p->sizeupvalues, p->upvalues[uv].name); 129 if (s == NULL) return "?"; 130 else return getstr(s); 131 } 132 133 134 static const char *findvararg (CallInfo *ci, int n, StkId *pos) { 135 int nparams = clLvalue(ci->func)->p->numparams; 136 if (n >= cast_int(ci->u.l.base - ci->func) - nparams) 137 return NULL; /* no such vararg */ 138 else { 139 *pos = ci->func + nparams + n; 140 return "(*vararg)"; /* generic name for any vararg */ 141 } 142 } 143 144 145 static const char *findlocal (lua_State *L, CallInfo *ci, int n, 146 StkId *pos) { 147 const char *name = NULL; 148 StkId base; 149 if (isLua(ci)) { 150 if (n < 0) /* access to vararg values? */ 151 return findvararg(ci, -n, pos); 152 else { 153 base = ci->u.l.base; 154 name = luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci)); 155 } 156 } 157 else 158 base = ci->func + 1; 159 if (name == NULL) { /* no 'standard' name? */ 160 StkId limit = (ci == L->ci) ? L->top : ci->next->func; 161 if (limit - base >= n && n > 0) /* is 'n' inside 'ci' stack? */ 162 name = "(*temporary)"; /* generic name for any valid slot */ 163 else 164 return NULL; /* no name */ 165 } 166 *pos = base + (n - 1); 167 return name; 168 } 169 170 171 LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) { 172 const char *name; 173 lua_lock(L); 174 swapextra(L); 175 if (ar == NULL) { /* information about non-active function? */ 176 if (!isLfunction(L->top - 1)) /* not a Lua function? */ 177 name = NULL; 178 else /* consider live variables at function start (parameters) */ 179 name = luaF_getlocalname(clLvalue(L->top - 1)->p, n, 0); 180 } 181 else { /* active function; get information through 'ar' */ 182 StkId pos = NULL; /* to avoid warnings */ 183 name = findlocal(L, ar->i_ci, n, &pos); 184 if (name) { 185 setobj2s(L, L->top, pos); 186 api_incr_top(L); 187 } 188 } 189 swapextra(L); 190 lua_unlock(L); 191 return name; 192 } 193 194 195 LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) { 196 StkId pos = NULL; /* to avoid warnings */ 197 const char *name; 198 lua_lock(L); 199 swapextra(L); 200 name = findlocal(L, ar->i_ci, n, &pos); 201 if (name) { 202 setobjs2s(L, pos, L->top - 1); 203 L->top--; /* pop value */ 204 } 205 swapextra(L); 206 lua_unlock(L); 207 return name; 208 } 209 210 211 static void funcinfo (lua_Debug *ar, Closure *cl) { 212 if (noLuaClosure(cl)) { 213 ar->source = "=[C]"; 214 ar->linedefined = -1; 215 ar->lastlinedefined = -1; 216 ar->what = "C"; 217 } 218 else { 219 Proto *p = cl->l.p; 220 ar->source = p->source ? getstr(p->source) : "=?"; 221 ar->linedefined = p->linedefined; 222 ar->lastlinedefined = p->lastlinedefined; 223 ar->what = (ar->linedefined == 0) ? "main" : "Lua"; 224 } 225 luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE); 226 } 227 228 229 static void collectvalidlines (lua_State *L, Closure *f) { 230 if (noLuaClosure(f)) { 231 setnilvalue(L->top); 232 api_incr_top(L); 233 } 234 else { 235 int i; 236 TValue v; 237 int *lineinfo = f->l.p->lineinfo; 238 Table *t = luaH_new(L); /* new table to store active lines */ 239 sethvalue(L, L->top, t); /* push it on stack */ 240 api_incr_top(L); 241 setbvalue(&v, 1); /* boolean 'true' to be the value of all indices */ 242 for (i = 0; i < f->l.p->sizelineinfo; i++) /* for all lines with code */ 243 luaH_setint(L, t, lineinfo[i], &v); /* table[line] = true */ 244 } 245 } 246 247 248 static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) { 249 if (ci == NULL) /* no 'ci'? */ 250 return NULL; /* no info */ 251 else if (ci->callstatus & CIST_FIN) { /* is this a finalizer? */ 252 *name = "__gc"; 253 return "metamethod"; /* report it as such */ 254 } 255 /* calling function is a known Lua function? */ 256 else if (!(ci->callstatus & CIST_TAIL) && isLua(ci->previous)) 257 return funcnamefromcode(L, ci->previous, name); 258 else return NULL; /* no way to find a name */ 259 } 260 261 262 static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, 263 Closure *f, CallInfo *ci) { 264 int status = 1; 265 for (; *what; what++) { 266 switch (*what) { 267 case 'S': { 268 funcinfo(ar, f); 269 break; 270 } 271 case 'l': { 272 ar->currentline = (ci && isLua(ci)) ? currentline(ci) : -1; 273 break; 274 } 275 case 'u': { 276 ar->nups = (f == NULL) ? 0 : f->c.nupvalues; 277 if (noLuaClosure(f)) { 278 ar->isvararg = 1; 279 ar->nparams = 0; 280 } 281 else { 282 ar->isvararg = f->l.p->is_vararg; 283 ar->nparams = f->l.p->numparams; 284 } 285 break; 286 } 287 case 't': { 288 ar->istailcall = (ci) ? ci->callstatus & CIST_TAIL : 0; 289 break; 290 } 291 case 'n': { 292 ar->namewhat = getfuncname(L, ci, &ar->name); 293 if (ar->namewhat == NULL) { 294 ar->namewhat = ""; /* not found */ 295 ar->name = NULL; 296 } 297 break; 298 } 299 case 'L': 300 case 'f': /* handled by lua_getinfo */ 301 break; 302 default: status = 0; /* invalid option */ 303 } 304 } 305 return status; 306 } 307 308 309 LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { 310 int status; 311 Closure *cl; 312 CallInfo *ci; 313 StkId func; 314 lua_lock(L); 315 swapextra(L); 316 if (*what == '>') { 317 ci = NULL; 318 func = L->top - 1; 319 api_check(L, ttisfunction(func), "function expected"); 320 what++; /* skip the '>' */ 321 L->top--; /* pop function */ 322 } 323 else { 324 ci = ar->i_ci; 325 func = ci->func; 326 lua_assert(ttisfunction(ci->func)); 327 } 328 cl = ttisclosure(func) ? clvalue(func) : NULL; 329 status = auxgetinfo(L, what, ar, cl, ci); 330 if (strchr(what, 'f')) { 331 setobjs2s(L, L->top, func); 332 api_incr_top(L); 333 } 334 swapextra(L); /* correct before option 'L', which can raise a mem. error */ 335 if (strchr(what, 'L')) 336 collectvalidlines(L, cl); 337 lua_unlock(L); 338 return status; 339 } 340 341 342 /* 343 ** {====================================================== 344 ** Symbolic Execution 345 ** ======================================================= 346 */ 347 348 static const char *getobjname (Proto *p, int lastpc, int reg, 349 const char **name); 350 351 352 /* 353 ** find a "name" for the RK value 'c' 354 */ 355 static void kname (Proto *p, int pc, int c, const char **name) { 356 if (ISK(c)) { /* is 'c' a constant? */ 357 TValue *kvalue = &p->k[INDEXK(c)]; 358 if (ttisstring(kvalue)) { /* literal constant? */ 359 *name = svalue(kvalue); /* it is its own name */ 360 return; 361 } 362 /* else no reasonable name found */ 363 } 364 else { /* 'c' is a register */ 365 const char *what = getobjname(p, pc, c, name); /* search for 'c' */ 366 if (what && *what == 'c') { /* found a constant name? */ 367 return; /* 'name' already filled */ 368 } 369 /* else no reasonable name found */ 370 } 371 *name = "?"; /* no reasonable name found */ 372 } 373 374 375 static int filterpc (int pc, int jmptarget) { 376 if (pc < jmptarget) /* is code conditional (inside a jump)? */ 377 return -1; /* cannot know who sets that register */ 378 else return pc; /* current position sets that register */ 379 } 380 381 382 /* 383 ** try to find last instruction before 'lastpc' that modified register 'reg' 384 */ 385 static int findsetreg (Proto *p, int lastpc, int reg) { 386 int pc; 387 int setreg = -1; /* keep last instruction that changed 'reg' */ 388 int jmptarget = 0; /* any code before this address is conditional */ 389 for (pc = 0; pc < lastpc; pc++) { 390 Instruction i = p->code[pc]; 391 OpCode op = GET_OPCODE(i); 392 int a = GETARG_A(i); 393 switch (op) { 394 case OP_LOADNIL: { 395 int b = GETARG_B(i); 396 if (a <= reg && reg <= a + b) /* set registers from 'a' to 'a+b' */ 397 setreg = filterpc(pc, jmptarget); 398 break; 399 } 400 case OP_TFORCALL: { 401 if (reg >= a + 2) /* affect all regs above its base */ 402 setreg = filterpc(pc, jmptarget); 403 break; 404 } 405 case OP_CALL: 406 case OP_TAILCALL: { 407 if (reg >= a) /* affect all registers above base */ 408 setreg = filterpc(pc, jmptarget); 409 break; 410 } 411 case OP_JMP: { 412 int b = GETARG_sBx(i); 413 int dest = pc + 1 + b; 414 /* jump is forward and do not skip 'lastpc'? */ 415 if (pc < dest && dest <= lastpc) { 416 if (dest > jmptarget) 417 jmptarget = dest; /* update 'jmptarget' */ 418 } 419 break; 420 } 421 default: 422 if (testAMode(op) && reg == a) /* any instruction that set A */ 423 setreg = filterpc(pc, jmptarget); 424 break; 425 } 426 } 427 return setreg; 428 } 429 430 431 static const char *getobjname (Proto *p, int lastpc, int reg, 432 const char **name) { 433 int pc; 434 *name = luaF_getlocalname(p, reg + 1, lastpc); 435 if (*name) /* is a local? */ 436 return "local"; 437 /* else try symbolic execution */ 438 pc = findsetreg(p, lastpc, reg); 439 if (pc != -1) { /* could find instruction? */ 440 Instruction i = p->code[pc]; 441 OpCode op = GET_OPCODE(i); 442 switch (op) { 443 case OP_MOVE: { 444 int b = GETARG_B(i); /* move from 'b' to 'a' */ 445 if (b < GETARG_A(i)) 446 return getobjname(p, pc, b, name); /* get name for 'b' */ 447 break; 448 } 449 case OP_GETTABUP: 450 case OP_GETTABLE: { 451 int k = GETARG_C(i); /* key index */ 452 int t = GETARG_B(i); /* table index */ 453 const char *vn = (op == OP_GETTABLE) /* name of indexed variable */ 454 ? luaF_getlocalname(p, t + 1, pc) 455 : upvalname(p, t); 456 kname(p, pc, k, name); 457 return (vn && strcmp(vn, LUA_ENV) == 0) ? "global" : "field"; 458 } 459 case OP_GETUPVAL: { 460 *name = upvalname(p, GETARG_B(i)); 461 return "upvalue"; 462 } 463 case OP_LOADK: 464 case OP_LOADKX: { 465 int b = (op == OP_LOADK) ? GETARG_Bx(i) 466 : GETARG_Ax(p->code[pc + 1]); 467 if (ttisstring(&p->k[b])) { 468 *name = svalue(&p->k[b]); 469 return "constant"; 470 } 471 break; 472 } 473 case OP_SELF: { 474 int k = GETARG_C(i); /* key index */ 475 kname(p, pc, k, name); 476 return "method"; 477 } 478 default: break; /* go through to return NULL */ 479 } 480 } 481 return NULL; /* could not find reasonable name */ 482 } 483 484 485 /* 486 ** Try to find a name for a function based on the code that called it. 487 ** (Only works when function was called by a Lua function.) 488 ** Returns what the name is (e.g., "for iterator", "method", 489 ** "metamethod") and sets '*name' to point to the name. 490 */ 491 static const char *funcnamefromcode (lua_State *L, CallInfo *ci, 492 const char **name) { 493 TMS tm = (TMS)0; /* (initial value avoids warnings) */ 494 Proto *p = ci_func(ci)->p; /* calling function */ 495 int pc = currentpc(ci); /* calling instruction index */ 496 Instruction i = p->code[pc]; /* calling instruction */ 497 if (ci->callstatus & CIST_HOOKED) { /* was it called inside a hook? */ 498 *name = "?"; 499 return "hook"; 500 } 501 switch (GET_OPCODE(i)) { 502 case OP_CALL: 503 case OP_TAILCALL: 504 return getobjname(p, pc, GETARG_A(i), name); /* get function name */ 505 case OP_TFORCALL: { /* for iterator */ 506 *name = "for iterator"; 507 return "for iterator"; 508 } 509 /* other instructions can do calls through metamethods */ 510 case OP_SELF: case OP_GETTABUP: case OP_GETTABLE: 511 tm = TM_INDEX; 512 break; 513 case OP_SETTABUP: case OP_SETTABLE: 514 tm = TM_NEWINDEX; 515 break; 516 case OP_ADD: case OP_SUB: case OP_MUL: case OP_MOD: 517 case OP_POW: case OP_DIV: case OP_IDIV: case OP_BAND: 518 case OP_BOR: case OP_BXOR: case OP_SHL: case OP_SHR: { 519 int offset = cast_int(GET_OPCODE(i)) - cast_int(OP_ADD); /* ORDER OP */ 520 tm = cast(TMS, offset + cast_int(TM_ADD)); /* ORDER TM */ 521 break; 522 } 523 case OP_UNM: tm = TM_UNM; break; 524 case OP_BNOT: tm = TM_BNOT; break; 525 case OP_LEN: tm = TM_LEN; break; 526 case OP_CONCAT: tm = TM_CONCAT; break; 527 case OP_EQ: tm = TM_EQ; break; 528 case OP_LT: tm = TM_LT; break; 529 case OP_LE: tm = TM_LE; break; 530 default: 531 return NULL; /* cannot find a reasonable name */ 532 } 533 *name = getstr(G(L)->tmname[tm]); 534 return "metamethod"; 535 } 536 537 /* }====================================================== */ 538 539 540 541 /* 542 ** The subtraction of two potentially unrelated pointers is 543 ** not ISO C, but it should not crash a program; the subsequent 544 ** checks are ISO C and ensure a correct result. 545 */ 546 static int isinstack (CallInfo *ci, const TValue *o) { 547 ptrdiff_t i = o - ci->u.l.base; 548 return (0 <= i && i < (ci->top - ci->u.l.base) && ci->u.l.base + i == o); 549 } 550 551 552 /* 553 ** Checks whether value 'o' came from an upvalue. (That can only happen 554 ** with instructions OP_GETTABUP/OP_SETTABUP, which operate directly on 555 ** upvalues.) 556 */ 557 static const char *getupvalname (CallInfo *ci, const TValue *o, 558 const char **name) { 559 LClosure *c = ci_func(ci); 560 int i; 561 for (i = 0; i < c->nupvalues; i++) { 562 if (c->upvals[i]->v == o) { 563 *name = upvalname(c->p, i); 564 return "upvalue"; 565 } 566 } 567 return NULL; 568 } 569 570 571 static const char *varinfo (lua_State *L, const TValue *o) { 572 const char *name = NULL; /* to avoid warnings */ 573 CallInfo *ci = L->ci; 574 const char *kind = NULL; 575 if (isLua(ci)) { 576 kind = getupvalname(ci, o, &name); /* check whether 'o' is an upvalue */ 577 if (!kind && isinstack(ci, o)) /* no? try a register */ 578 kind = getobjname(ci_func(ci)->p, currentpc(ci), 579 cast_int(o - ci->u.l.base), &name); 580 } 581 return (kind) ? luaO_pushfstring(L, " (%s '%s')", kind, name) : ""; 582 } 583 584 585 l_noret luaG_typeerror (lua_State *L, const TValue *o, const char *op) { 586 const char *t = luaT_objtypename(L, o); 587 luaG_runerror(L, "attempt to %s a %s value%s", op, t, varinfo(L, o)); 588 } 589 590 591 l_noret luaG_concaterror (lua_State *L, const TValue *p1, const TValue *p2) { 592 if (ttisstring(p1) || cvt2str(p1)) p1 = p2; 593 luaG_typeerror(L, p1, "concatenate"); 594 } 595 596 597 l_noret luaG_opinterror (lua_State *L, const TValue *p1, 598 const TValue *p2, const char *msg) { 599 lua_Number temp; 600 if (!tonumber(p1, &temp)) /* first operand is wrong? */ 601 p2 = p1; /* now second is wrong */ 602 luaG_typeerror(L, p2, msg); 603 } 604 605 606 /* 607 ** Error when both values are convertible to numbers, but not to integers 608 */ 609 l_noret luaG_tointerror (lua_State *L, const TValue *p1, const TValue *p2) { 610 lua_Integer temp; 611 if (!tointeger(p1, &temp)) 612 p2 = p1; 613 luaG_runerror(L, "number%s has no integer representation", varinfo(L, p2)); 614 } 615 616 617 l_noret luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) { 618 const char *t1 = luaT_objtypename(L, p1); 619 const char *t2 = luaT_objtypename(L, p2); 620 if (strcmp(t1, t2) == 0) 621 luaG_runerror(L, "attempt to compare two %s values", t1); 622 else 623 luaG_runerror(L, "attempt to compare %s with %s", t1, t2); 624 } 625 626 627 /* add src:line information to 'msg' */ 628 const char *luaG_addinfo (lua_State *L, const char *msg, TString *src, 629 int line) { 630 char buff[LUA_IDSIZE]; 631 if (src) 632 luaO_chunkid(buff, getstr(src), LUA_IDSIZE); 633 else { /* no source available; use "?" instead */ 634 buff[0] = '?'; buff[1] = '\0'; 635 } 636 return luaO_pushfstring(L, "%s:%d: %s", buff, line, msg); 637 } 638 639 640 l_noret luaG_errormsg (lua_State *L) { 641 if (L->errfunc != 0) { /* is there an error handling function? */ 642 StkId errfunc = restorestack(L, L->errfunc); 643 setobjs2s(L, L->top, L->top - 1); /* move argument */ 644 setobjs2s(L, L->top - 1, errfunc); /* push function */ 645 L->top++; /* assume EXTRA_STACK */ 646 luaD_callnoyield(L, L->top - 2, 1); /* call it */ 647 } 648 luaD_throw(L, LUA_ERRRUN); 649 } 650 651 652 l_noret luaG_runerror (lua_State *L, const char *fmt, ...) { 653 CallInfo *ci = L->ci; 654 const char *msg; 655 va_list argp; 656 va_start(argp, fmt); 657 msg = luaO_pushvfstring(L, fmt, argp); /* format message */ 658 va_end(argp); 659 if (isLua(ci)) /* if Lua function, add source:line information */ 660 luaG_addinfo(L, msg, ci_func(ci)->p->source, currentline(ci)); 661 luaG_errormsg(L); 662 } 663 664 665 void luaG_traceexec (lua_State *L) { 666 CallInfo *ci = L->ci; 667 lu_byte mask = L->hookmask; 668 int counthook = (--L->hookcount == 0 && (mask & LUA_MASKCOUNT)); 669 if (counthook) 670 resethookcount(L); /* reset count */ 671 else if (!(mask & LUA_MASKLINE)) 672 return; /* no line hook and count != 0; nothing to be done */ 673 if (ci->callstatus & CIST_HOOKYIELD) { /* called hook last time? */ 674 ci->callstatus &= ~CIST_HOOKYIELD; /* erase mark */ 675 return; /* do not call hook again (VM yielded, so it did not move) */ 676 } 677 if (counthook) 678 luaD_hook(L, LUA_HOOKCOUNT, -1); /* call count hook */ 679 if (mask & LUA_MASKLINE) { 680 Proto *p = ci_func(ci)->p; 681 int npc = pcRel(ci->u.l.savedpc, p); 682 int newline = getfuncline(p, npc); 683 if (npc == 0 || /* call linehook when enter a new function, */ 684 ci->u.l.savedpc <= L->oldpc || /* when jump back (loop), or when */ 685 newline != getfuncline(p, pcRel(L->oldpc, p))) /* enter a new line */ 686 luaD_hook(L, LUA_HOOKLINE, newline); /* call line hook */ 687 } 688 L->oldpc = ci->u.l.savedpc; 689 if (L->status == LUA_YIELD) { /* did hook yield? */ 690 if (counthook) 691 L->hookcount = 1; /* undo decrement to zero */ 692 ci->u.l.savedpc--; /* undo increment (resume will increment it again) */ 693 ci->callstatus |= CIST_HOOKYIELD; /* mark that it yielded */ 694 ci->func = L->top - 1; /* protect stack below results */ 695 luaD_throw(L, LUA_YIELD); 696 } 697 } 698 699