lj_vmevent.c 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. /*
  2. ** VM event handling.
  3. ** Copyright (C) 2005-2014 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. return savestack(L, L->top);
  27. }
  28. }
  29. g->vmevmask &= ~VMEVENT_MASK(ev); /* No handler: cache this fact. */
  30. return 0;
  31. }
  32. void lj_vmevent_call(lua_State *L, ptrdiff_t argbase)
  33. {
  34. global_State *g = G(L);
  35. uint8_t oldmask = g->vmevmask;
  36. uint8_t oldh = hook_save(g);
  37. int status;
  38. g->vmevmask = 0; /* Disable all events. */
  39. hook_vmevent(g);
  40. status = lj_vm_pcall(L, restorestack(L, argbase), 0+1, 0);
  41. if (LJ_UNLIKELY(status)) {
  42. /* Really shouldn't use stderr here, but where else to complain? */
  43. L->top--;
  44. fputs("VM handler failed: ", stderr);
  45. fputs(tvisstr(L->top) ? strVdata(L->top) : "?", stderr);
  46. fputc('\n', stderr);
  47. }
  48. hook_restore(g, oldh);
  49. if (g->vmevmask != VMEVENT_NOCACHE)
  50. g->vmevmask = oldmask; /* Restore event mask, but not if not modified. */
  51. }