lj_vmevent.c 1.5 KB

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