** 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'
| 917 | ** 'L->top.p' before calling anything that can run the GC. |
| 918 | */ |
| 919 | int luaG_traceexec (lua_State *L, const Instruction *pc) { |
| 920 | CallInfo *ci = L->ci; |
| 921 | lu_byte mask = L->hookmask; |
| 922 | const Proto *p = ci_func(ci)->p; |
| 923 | int counthook; |
| 924 | if (!(mask & (LUA_MASKLINE | LUA_MASKCOUNT))) { /* no hooks? */ |
| 925 | ci->u.l.trap = 0; /* don't need to stop again */ |
| 926 | return 0; /* turn off 'trap' */ |
| 927 | } |
| 928 | pc++; /* reference is always next instruction */ |
| 929 | ci->u.l.savedpc = pc; /* save 'pc' */ |
| 930 | counthook = (mask & LUA_MASKCOUNT) && (--L->hookcount == 0); |
| 931 | if (counthook) |
| 932 | resethookcount(L); /* reset count */ |
| 933 | else if (!(mask & LUA_MASKLINE)) |
| 934 | return 1; /* no line hook and count != 0; nothing to be done now */ |
| 935 | if (ci->callstatus & CIST_HOOKYIELD) { /* hook yielded last time? */ |
| 936 | ci->callstatus &= ~CIST_HOOKYIELD; /* erase mark */ |
| 937 | return 1; /* do not call hook again (VM yielded, so it did not move) */ |
| 938 | } |
| 939 | if (!isIT(*(ci->u.l.savedpc - 1))) /* top not being used? */ |
| 940 | L->top.p = ci->top.p; /* correct top */ |
| 941 | if (counthook) |
| 942 | luaD_hook(L, LUA_HOOKCOUNT, -1, 0, 0); /* call count hook */ |
| 943 | if (mask & LUA_MASKLINE) { |
| 944 | /* 'L->oldpc' may be invalid; use zero in this case */ |
| 945 | int oldpc = (L->oldpc < p->sizecode) ? L->oldpc : 0; |
| 946 | int npci = pcRel(pc, p); |
| 947 | if (npci <= oldpc || /* call hook when jump back (loop), */ |
| 948 | changedline(p, oldpc, npci)) { /* or when enter new line */ |
| 949 | int newline = luaG_getfuncline(p, npci); |
| 950 | luaD_hook(L, LUA_HOOKLINE, newline, 0, 0); /* call line hook */ |
| 951 | } |
| 952 | L->oldpc = npci; /* 'pc' of last call to line hook */ |
| 953 | } |
| 954 | if (L->status == LUA_YIELD) { /* did hook yield? */ |
| 955 | if (counthook) |
| 956 | L->hookcount = 1; /* undo decrement to zero */ |
| 957 | ci->callstatus |= CIST_HOOKYIELD; /* mark that it yielded */ |
| 958 | luaD_throw(L, LUA_YIELD); |
| 959 | } |
| 960 | return 1; /* keep 'trap' on */ |
| 961 | } |
| 962 |
no test coverage detected