lj_vmevent.c (1552B)
1 /* 2 ** VM event handling. 3 ** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h 4 */ 5 6 #include <stdio.h> 7 8 #define lj_vmevent_c 9 #define LUA_CORE 10 11 #include "lj_obj.h" 12 #include "lj_str.h" 13 #include "lj_tab.h" 14 #include "lj_state.h" 15 #include "lj_dispatch.h" 16 #include "lj_vm.h" 17 #include "lj_vmevent.h" 18 19 ptrdiff_t lj_vmevent_prepare(lua_State *L, VMEvent ev) 20 { 21 global_State *g = G(L); 22 GCstr *s = lj_str_newlit(L, LJ_VMEVENTS_REGKEY); 23 cTValue *tv = lj_tab_getstr(tabV(registry(L)), s); 24 if (tvistab(tv)) { 25 int hash = VMEVENT_HASH(ev); 26 tv = lj_tab_getint(tabV(tv), hash); 27 if (tv && tvisfunc(tv)) { 28 lj_state_checkstack(L, LUA_MINSTACK); 29 setfuncV(L, L->top++, funcV(tv)); 30 if (LJ_FR2) setnilV(L->top++); 31 return savestack(L, L->top); 32 } 33 } 34 g->vmevmask &= ~VMEVENT_MASK(ev); /* No handler: cache this fact. */ 35 return 0; 36 } 37 38 void lj_vmevent_call(lua_State *L, ptrdiff_t argbase) 39 { 40 global_State *g = G(L); 41 uint8_t oldmask = g->vmevmask; 42 uint8_t oldh = hook_save(g); 43 int status; 44 g->vmevmask = 0; /* Disable all events. */ 45 hook_vmevent(g); 46 status = lj_vm_pcall(L, restorestack(L, argbase), 0+1, 0); 47 if (LJ_UNLIKELY(status)) { 48 /* Really shouldn't use stderr here, but where else to complain? */ 49 L->top--; 50 fputs("VM handler failed: ", stderr); 51 fputs(tvisstr(L->top) ? strVdata(L->top) : "?", stderr); 52 fputc('\n', stderr); 53 } 54 hook_restore(g, oldh); 55 if (g->vmevmask != VMEVENT_NOCACHE) 56 g->vmevmask = oldmask; /* Restore event mask, but not if not modified. */ 57 } 58