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