** Traces the execution of a Lua function. Called before the execution ** of each opcode, when debug is on. 'L->oldpc' stores the last ** instruction traced, to detect line changes. When entering a new ** function, 'npci' will be zero and will test as a new line whatever ** the value of 'oldpc'. Some exceptional conditions may return to ** a function without setting 'oldpc'. In that case, 'oldpc'
| 878 | ** 'L->top.p' before calling anything that can run the GC. |
| 879 | */ |
| 880 | int luaG_traceexec (lua_State *L, const Instruction *pc) { |
| 881 | CallInfo *ci = L->ci; |
| 882 | lu_byte mask = L->hookmask; |
| 883 | const Proto *p = ci_func(ci)->p; |
| 884 | int counthook; |
| 885 | if (!(mask & (LUA_MASKLINE | LUA_MASKCOUNT))) { /* no hooks? */ |
| 886 | ci->u.l.trap = 0; /* don't need to stop again */ |
| 887 | return 0; /* turn off 'trap' */ |
| 888 | } |
| 889 | pc++; /* reference is always next instruction */ |
| 890 | ci->u.l.savedpc = pc; /* save 'pc' */ |
| 891 | counthook = (--L->hookcount == 0 && (mask & LUA_MASKCOUNT)); |
| 892 | if (counthook) |
| 893 | resethookcount(L); /* reset count */ |
| 894 | else if (!(mask & LUA_MASKLINE)) |
| 895 | return 1; /* no line hook and count != 0; nothing to be done now */ |
| 896 | if (ci->callstatus & CIST_HOOKYIELD) { /* called hook last time? */ |
| 897 | ci->callstatus &= ~CIST_HOOKYIELD; /* erase mark */ |
| 898 | return 1; /* do not call hook again (VM yielded, so it did not move) */ |
| 899 | } |
| 900 | if (!isIT(*(ci->u.l.savedpc - 1))) /* top not being used? */ |
| 901 | L->top.p = ci->top.p; /* correct top */ |
| 902 | if (counthook) |
| 903 | luaD_hook(L, LUA_HOOKCOUNT, -1, 0, 0); /* call count hook */ |
| 904 | if (mask & LUA_MASKLINE) { |
| 905 | /* 'L->oldpc' may be invalid; use zero in this case */ |
| 906 | int oldpc = (L->oldpc < p->sizecode) ? L->oldpc : 0; |
| 907 | int npci = pcRel(pc, p); |
| 908 | if (npci <= oldpc || /* call hook when jump back (loop), */ |
| 909 | changedline(p, oldpc, npci)) { /* or when enter new line */ |
| 910 | int newline = luaG_getfuncline(p, npci); |
| 911 | luaD_hook(L, LUA_HOOKLINE, newline, 0, 0); /* call line hook */ |
| 912 | } |
| 913 | L->oldpc = npci; /* 'pc' of last call to line hook */ |
| 914 | } |
| 915 | if (L->status == LUA_YIELD) { /* did hook yield? */ |
| 916 | if (counthook) |
| 917 | L->hookcount = 1; /* undo decrement to zero */ |
| 918 | ci->u.l.savedpc--; /* undo increment (resume will increment it again) */ |
| 919 | ci->callstatus |= CIST_HOOKYIELD; /* mark that it yielded */ |
| 920 | luaD_throw(L, LUA_YIELD); |
| 921 | } |
| 922 | return 1; /* keep 'trap' on */ |
| 923 | } |
| 924 |
no test coverage detected