diff options
| author | Mike Pall <mike> | 2025-11-10 18:11:26 +0100 |
|---|---|---|
| committer | Mike Pall <mike> | 2025-11-10 18:11:26 +0100 |
| commit | 5c647754a687a910ef40a097fbf8f7415561c8aa (patch) | |
| tree | 239007a579b77f8f370234a42b2f25054abf2807 | |
| parent | fdf2379ccba1eb68ff07f8bc48541568f5bbdfbf (diff) | |
| download | luajit-5c647754a687a910ef40a097fbf8f7415561c8aa.tar.gz luajit-5c647754a687a910ef40a097fbf8f7415561c8aa.tar.bz2 luajit-5c647754a687a910ef40a097fbf8f7415561c8aa.zip | |
Run VM events and finalizers in separate state.
Reported by Sergey Kaplun. #1403
| -rw-r--r-- | src/lj_gc.c | 18 | ||||
| -rw-r--r-- | src/lj_obj.h | 2 | ||||
| -rw-r--r-- | src/lj_parse.c | 4 | ||||
| -rw-r--r-- | src/lj_state.c | 1 | ||||
| -rw-r--r-- | src/lj_trace.c | 91 | ||||
| -rw-r--r-- | src/lj_vmevent.c | 5 | ||||
| -rw-r--r-- | src/lj_vmevent.h | 22 |
7 files changed, 76 insertions, 67 deletions
diff --git a/src/lj_gc.c b/src/lj_gc.c index d9581d20..c779d583 100644 --- a/src/lj_gc.c +++ b/src/lj_gc.c | |||
| @@ -106,6 +106,7 @@ static void gc_mark_start(global_State *g) | |||
| 106 | setgcrefnull(g->gc.weak); | 106 | setgcrefnull(g->gc.weak); |
| 107 | gc_markobj(g, mainthread(g)); | 107 | gc_markobj(g, mainthread(g)); |
| 108 | gc_markobj(g, tabref(mainthread(g)->env)); | 108 | gc_markobj(g, tabref(mainthread(g)->env)); |
| 109 | gc_markobj(g, vmthread(g)); | ||
| 109 | gc_marktv(g, &g->registrytv); | 110 | gc_marktv(g, &g->registrytv); |
| 110 | gc_mark_gcroot(g); | 111 | gc_mark_gcroot(g); |
| 111 | g->gc.state = GCSpropagate; | 112 | g->gc.state = GCSpropagate; |
| @@ -507,24 +508,25 @@ static void gc_call_finalizer(global_State *g, lua_State *L, | |||
| 507 | uint8_t oldh = hook_save(g); | 508 | uint8_t oldh = hook_save(g); |
| 508 | GCSize oldt = g->gc.threshold; | 509 | GCSize oldt = g->gc.threshold; |
| 509 | int errcode; | 510 | int errcode; |
| 511 | lua_State *VL = vmthread(g); | ||
| 510 | TValue *top; | 512 | TValue *top; |
| 511 | lj_trace_abort(g); | 513 | lj_trace_abort(g); |
| 512 | hook_entergc(g); /* Disable hooks and new traces during __gc. */ | 514 | hook_entergc(g); /* Disable hooks and new traces during __gc. */ |
| 513 | if (LJ_HASPROFILE && (oldh & HOOK_PROFILE)) lj_dispatch_update(g); | 515 | if (LJ_HASPROFILE && (oldh & HOOK_PROFILE)) lj_dispatch_update(g); |
| 514 | g->gc.threshold = LJ_MAX_MEM; /* Prevent GC steps. */ | 516 | g->gc.threshold = LJ_MAX_MEM; /* Prevent GC steps. */ |
| 515 | top = L->top; | 517 | top = VL->top; |
| 516 | copyTV(L, top++, mo); | 518 | copyTV(VL, top++, mo); |
| 517 | if (LJ_FR2) setnilV(top++); | 519 | if (LJ_FR2) setnilV(top++); |
| 518 | setgcV(L, top, o, ~o->gch.gct); | 520 | setgcV(VL, top, o, ~o->gch.gct); |
| 519 | L->top = top+1; | 521 | VL->top = top+1; |
| 520 | errcode = lj_vm_pcall(L, top, 1+0, -1); /* Stack: |mo|o| -> | */ | 522 | errcode = lj_vm_pcall(VL, top, 1+0, -1); /* Stack: |mo|o| -> | */ |
| 523 | setgcref(g->cur_L, obj2gco(L)); | ||
| 521 | hook_restore(g, oldh); | 524 | hook_restore(g, oldh); |
| 522 | if (LJ_HASPROFILE && (oldh & HOOK_PROFILE)) lj_dispatch_update(g); | 525 | if (LJ_HASPROFILE && (oldh & HOOK_PROFILE)) lj_dispatch_update(g); |
| 523 | g->gc.threshold = oldt; /* Restore GC threshold. */ | 526 | g->gc.threshold = oldt; /* Restore GC threshold. */ |
| 524 | if (errcode) { | 527 | if (errcode) { |
| 525 | ptrdiff_t errobj = savestack(L, L->top-1); /* Stack may be resized. */ | 528 | lj_vmevent_send(g, ERRFIN, |
| 526 | lj_vmevent_send(L, ERRFIN, | 529 | copyTV(V, V->top++, L->top-1); |
| 527 | copyTV(L, L->top++, restorestack(L, errobj)); | ||
| 528 | ); | 530 | ); |
| 529 | L->top--; | 531 | L->top--; |
| 530 | } | 532 | } |
diff --git a/src/lj_obj.h b/src/lj_obj.h index 855727bf..73b186e2 100644 --- a/src/lj_obj.h +++ b/src/lj_obj.h | |||
| @@ -647,6 +647,7 @@ typedef struct global_State { | |||
| 647 | TValue tmptv, tmptv2; /* Temporary TValues. */ | 647 | TValue tmptv, tmptv2; /* Temporary TValues. */ |
| 648 | Node nilnode; /* Fallback 1-element hash part (nil key and value). */ | 648 | Node nilnode; /* Fallback 1-element hash part (nil key and value). */ |
| 649 | TValue registrytv; /* Anchor for registry. */ | 649 | TValue registrytv; /* Anchor for registry. */ |
| 650 | GCRef vmthref; /* Link to VM thread. */ | ||
| 650 | GCupval uvhead; /* Head of double-linked list of all open upvalues. */ | 651 | GCupval uvhead; /* Head of double-linked list of all open upvalues. */ |
| 651 | int32_t hookcount; /* Instruction hook countdown. */ | 652 | int32_t hookcount; /* Instruction hook countdown. */ |
| 652 | int32_t hookcstart; /* Start count for instruction hook counter. */ | 653 | int32_t hookcstart; /* Start count for instruction hook counter. */ |
| @@ -663,6 +664,7 @@ typedef struct global_State { | |||
| 663 | } global_State; | 664 | } global_State; |
| 664 | 665 | ||
| 665 | #define mainthread(g) (&gcref(g->mainthref)->th) | 666 | #define mainthread(g) (&gcref(g->mainthref)->th) |
| 667 | #define vmthread(g) (&gcref(g->vmthref)->th) | ||
| 666 | #define niltv(L) \ | 668 | #define niltv(L) \ |
| 667 | check_exp(tvisnil(&G(L)->nilnode.val), &G(L)->nilnode.val) | 669 | check_exp(tvisnil(&G(L)->nilnode.val), &G(L)->nilnode.val) |
| 668 | #define niltvg(g) \ | 670 | #define niltvg(g) \ |
diff --git a/src/lj_parse.c b/src/lj_parse.c index e326432a..181ce4d7 100644 --- a/src/lj_parse.c +++ b/src/lj_parse.c | |||
| @@ -1593,8 +1593,8 @@ static GCproto *fs_finish(LexState *ls, BCLine line) | |||
| 1593 | fs_fixup_line(fs, pt, (void *)((char *)pt + ofsli), numline); | 1593 | fs_fixup_line(fs, pt, (void *)((char *)pt + ofsli), numline); |
| 1594 | fs_fixup_var(ls, pt, (uint8_t *)((char *)pt + ofsdbg), ofsvar); | 1594 | fs_fixup_var(ls, pt, (uint8_t *)((char *)pt + ofsdbg), ofsvar); |
| 1595 | 1595 | ||
| 1596 | lj_vmevent_send(L, BC, | 1596 | lj_vmevent_send(G(L), BC, |
| 1597 | setprotoV(L, L->top++, pt); | 1597 | setprotoV(V, V->top++, pt); |
| 1598 | ); | 1598 | ); |
| 1599 | 1599 | ||
| 1600 | L->top--; /* Pop table of constants. */ | 1600 | L->top--; /* Pop table of constants. */ |
diff --git a/src/lj_state.c b/src/lj_state.c index fb6d41a5..9d4fdcee 100644 --- a/src/lj_state.c +++ b/src/lj_state.c | |||
| @@ -202,6 +202,7 @@ static TValue *cpluaopen(lua_State *L, lua_CFunction dummy, void *ud) | |||
| 202 | #endif | 202 | #endif |
| 203 | lj_trace_initstate(g); | 203 | lj_trace_initstate(g); |
| 204 | lj_err_verify(); | 204 | lj_err_verify(); |
| 205 | setgcref(g->vmthref, obj2gco(lj_state_new(L))); | ||
| 205 | return NULL; | 206 | return NULL; |
| 206 | } | 207 | } |
| 207 | 208 | ||
diff --git a/src/lj_trace.c b/src/lj_trace.c index 3e2cd0b3..47d7faa5 100644 --- a/src/lj_trace.c +++ b/src/lj_trace.c | |||
| @@ -296,8 +296,8 @@ int lj_trace_flushall(lua_State *L) | |||
| 296 | /* Free the whole machine code and invalidate all exit stub groups. */ | 296 | /* Free the whole machine code and invalidate all exit stub groups. */ |
| 297 | lj_mcode_free(J); | 297 | lj_mcode_free(J); |
| 298 | memset(J->exitstubgroup, 0, sizeof(J->exitstubgroup)); | 298 | memset(J->exitstubgroup, 0, sizeof(J->exitstubgroup)); |
| 299 | lj_vmevent_send(L, TRACE, | 299 | lj_vmevent_send(J2G(J), TRACE, |
| 300 | setstrV(L, L->top++, lj_str_newlit(L, "flush")); | 300 | setstrV(V, V->top++, lj_str_newlit(V, "flush")); |
| 301 | ); | 301 | ); |
| 302 | return 0; | 302 | return 0; |
| 303 | } | 303 | } |
| @@ -416,7 +416,6 @@ setpenalty: | |||
| 416 | /* Start tracing. */ | 416 | /* Start tracing. */ |
| 417 | static void trace_start(jit_State *J) | 417 | static void trace_start(jit_State *J) |
| 418 | { | 418 | { |
| 419 | lua_State *L; | ||
| 420 | TraceNo traceno; | 419 | TraceNo traceno; |
| 421 | 420 | ||
| 422 | if ((J->pt->flags & PROTO_NOJIT)) { /* JIT disabled for this proto? */ | 421 | if ((J->pt->flags & PROTO_NOJIT)) { /* JIT disabled for this proto? */ |
| @@ -466,20 +465,19 @@ static void trace_start(jit_State *J) | |||
| 466 | J->ktrace = 0; | 465 | J->ktrace = 0; |
| 467 | setgcref(J->cur.startpt, obj2gco(J->pt)); | 466 | setgcref(J->cur.startpt, obj2gco(J->pt)); |
| 468 | 467 | ||
| 469 | L = J->L; | 468 | lj_vmevent_send(J2G(J), TRACE, |
| 470 | lj_vmevent_send(L, TRACE, | 469 | setstrV(V, V->top++, lj_str_newlit(V, "start")); |
| 471 | setstrV(L, L->top++, lj_str_newlit(L, "start")); | 470 | setintV(V->top++, traceno); |
| 472 | setintV(L->top++, traceno); | 471 | setfuncV(V, V->top++, J->fn); |
| 473 | setfuncV(L, L->top++, J->fn); | 472 | setintV(V->top++, proto_bcpos(J->pt, J->pc)); |
| 474 | setintV(L->top++, proto_bcpos(J->pt, J->pc)); | ||
| 475 | if (J->parent) { | 473 | if (J->parent) { |
| 476 | setintV(L->top++, J->parent); | 474 | setintV(V->top++, J->parent); |
| 477 | setintV(L->top++, J->exitno); | 475 | setintV(V->top++, J->exitno); |
| 478 | } else { | 476 | } else { |
| 479 | BCOp op = bc_op(*J->pc); | 477 | BCOp op = bc_op(*J->pc); |
| 480 | if (op == BC_CALLM || op == BC_CALL || op == BC_ITERC) { | 478 | if (op == BC_CALLM || op == BC_CALL || op == BC_ITERC) { |
| 481 | setintV(L->top++, J->exitno); /* Parent of stitched trace. */ | 479 | setintV(V->top++, J->exitno); /* Parent of stitched trace. */ |
| 482 | setintV(L->top++, -1); | 480 | setintV(V->top++, -1); |
| 483 | } | 481 | } |
| 484 | } | 482 | } |
| 485 | ); | 483 | ); |
| @@ -494,7 +492,6 @@ static void trace_stop(jit_State *J) | |||
| 494 | GCproto *pt = &gcref(J->cur.startpt)->pt; | 492 | GCproto *pt = &gcref(J->cur.startpt)->pt; |
| 495 | TraceNo traceno = J->cur.traceno; | 493 | TraceNo traceno = J->cur.traceno; |
| 496 | GCtrace *T = J->curfinal; | 494 | GCtrace *T = J->curfinal; |
| 497 | lua_State *L; | ||
| 498 | 495 | ||
| 499 | switch (op) { | 496 | switch (op) { |
| 500 | case BC_FORL: | 497 | case BC_FORL: |
| @@ -551,11 +548,10 @@ static void trace_stop(jit_State *J) | |||
| 551 | J->postproc = LJ_POST_NONE; | 548 | J->postproc = LJ_POST_NONE; |
| 552 | trace_save(J, T); | 549 | trace_save(J, T); |
| 553 | 550 | ||
| 554 | L = J->L; | 551 | lj_vmevent_send(J2G(J), TRACE, |
| 555 | lj_vmevent_send(L, TRACE, | 552 | setstrV(V, V->top++, lj_str_newlit(V, "stop")); |
| 556 | setstrV(L, L->top++, lj_str_newlit(L, "stop")); | 553 | setintV(V->top++, traceno); |
| 557 | setintV(L->top++, traceno); | 554 | setfuncV(V, V->top++, J->fn); |
| 558 | setfuncV(L, L->top++, J->fn); | ||
| 559 | ); | 555 | ); |
| 560 | } | 556 | } |
| 561 | 557 | ||
| @@ -610,18 +606,17 @@ static int trace_abort(jit_State *J) | |||
| 610 | /* Is there anything to abort? */ | 606 | /* Is there anything to abort? */ |
| 611 | traceno = J->cur.traceno; | 607 | traceno = J->cur.traceno; |
| 612 | if (traceno) { | 608 | if (traceno) { |
| 613 | ptrdiff_t errobj = savestack(L, L->top-1); /* Stack may be resized. */ | ||
| 614 | J->cur.link = 0; | 609 | J->cur.link = 0; |
| 615 | J->cur.linktype = LJ_TRLINK_NONE; | 610 | J->cur.linktype = LJ_TRLINK_NONE; |
| 616 | lj_vmevent_send(L, TRACE, | 611 | lj_vmevent_send(J2G(J), TRACE, |
| 617 | cTValue *bot = tvref(L->stack)+LJ_FR2; | 612 | cTValue *bot = tvref(L->stack)+LJ_FR2; |
| 618 | cTValue *frame; | 613 | cTValue *frame; |
| 619 | const BCIns *pc; | 614 | const BCIns *pc; |
| 620 | BCPos pos = 0; | 615 | BCPos pos = 0; |
| 621 | setstrV(L, L->top++, lj_str_newlit(L, "abort")); | 616 | setstrV(V, V->top++, lj_str_newlit(V, "abort")); |
| 622 | setintV(L->top++, traceno); | 617 | setintV(V->top++, traceno); |
| 623 | /* Find original Lua function call to generate a better error message. */ | 618 | /* Find original Lua function call to generate a better error message. */ |
| 624 | for (frame = J->L->base-1, pc = J->pc; ; frame = frame_prev(frame)) { | 619 | for (frame = L->base-1, pc = J->pc; ; frame = frame_prev(frame)) { |
| 625 | if (isluafunc(frame_func(frame))) { | 620 | if (isluafunc(frame_func(frame))) { |
| 626 | pos = proto_bcpos(funcproto(frame_func(frame)), pc); | 621 | pos = proto_bcpos(funcproto(frame_func(frame)), pc); |
| 627 | break; | 622 | break; |
| @@ -633,10 +628,10 @@ static int trace_abort(jit_State *J) | |||
| 633 | pc = frame_pc(frame) - 1; | 628 | pc = frame_pc(frame) - 1; |
| 634 | } | 629 | } |
| 635 | } | 630 | } |
| 636 | setfuncV(L, L->top++, frame_func(frame)); | 631 | setfuncV(V, V->top++, frame_func(frame)); |
| 637 | setintV(L->top++, pos); | 632 | setintV(V->top++, pos); |
| 638 | copyTV(L, L->top++, restorestack(L, errobj)); | 633 | copyTV(V, V->top++, L->top-1); |
| 639 | copyTV(L, L->top++, &J->errinfo); | 634 | copyTV(V, V->top++, &J->errinfo); |
| 640 | ); | 635 | ); |
| 641 | /* Drop aborted trace after the vmevent (which may still access it). */ | 636 | /* Drop aborted trace after the vmevent (which may still access it). */ |
| 642 | setgcrefnull(J->trace[traceno]); | 637 | setgcrefnull(J->trace[traceno]); |
| @@ -692,16 +687,16 @@ static TValue *trace_state(lua_State *L, lua_CFunction dummy, void *ud) | |||
| 692 | case LJ_TRACE_RECORD: | 687 | case LJ_TRACE_RECORD: |
| 693 | trace_pendpatch(J, 0); | 688 | trace_pendpatch(J, 0); |
| 694 | setvmstate(J2G(J), RECORD); | 689 | setvmstate(J2G(J), RECORD); |
| 695 | lj_vmevent_send_(L, RECORD, | 690 | lj_vmevent_send_(J2G(J), RECORD, |
| 696 | /* Save/restore state for trace recorder. */ | 691 | /* Save/restore state for trace recorder. */ |
| 697 | TValue savetv = J2G(J)->tmptv; | 692 | TValue savetv = J2G(J)->tmptv; |
| 698 | TValue savetv2 = J2G(J)->tmptv2; | 693 | TValue savetv2 = J2G(J)->tmptv2; |
| 699 | TraceNo parent = J->parent; | 694 | TraceNo parent = J->parent; |
| 700 | ExitNo exitno = J->exitno; | 695 | ExitNo exitno = J->exitno; |
| 701 | setintV(L->top++, J->cur.traceno); | 696 | setintV(V->top++, J->cur.traceno); |
| 702 | setfuncV(L, L->top++, J->fn); | 697 | setfuncV(V, V->top++, J->fn); |
| 703 | setintV(L->top++, J->pt ? (int32_t)proto_bcpos(J->pt, J->pc) : -1); | 698 | setintV(V->top++, J->pt ? (int32_t)proto_bcpos(J->pt, J->pc) : -1); |
| 704 | setintV(L->top++, J->framedepth); | 699 | setintV(V->top++, J->framedepth); |
| 705 | , | 700 | , |
| 706 | J2G(J)->tmptv = savetv; | 701 | J2G(J)->tmptv = savetv; |
| 707 | J2G(J)->tmptv2 = savetv2; | 702 | J2G(J)->tmptv2 = savetv2; |
| @@ -839,23 +834,23 @@ static TValue *trace_exit_cp(lua_State *L, lua_CFunction dummy, void *ud) | |||
| 839 | 834 | ||
| 840 | #ifndef LUAJIT_DISABLE_VMEVENT | 835 | #ifndef LUAJIT_DISABLE_VMEVENT |
| 841 | /* Push all registers from exit state. */ | 836 | /* Push all registers from exit state. */ |
| 842 | static void trace_exit_regs(lua_State *L, ExitState *ex) | 837 | static void trace_exit_regs(lua_State *V, ExitState *ex) |
| 843 | { | 838 | { |
| 844 | int32_t i; | 839 | int32_t i; |
| 845 | setintV(L->top++, RID_NUM_GPR); | 840 | setintV(V->top++, RID_NUM_GPR); |
| 846 | setintV(L->top++, RID_NUM_FPR); | 841 | setintV(V->top++, RID_NUM_FPR); |
| 847 | for (i = 0; i < RID_NUM_GPR; i++) { | 842 | for (i = 0; i < RID_NUM_GPR; i++) { |
| 848 | if (sizeof(ex->gpr[i]) == sizeof(int32_t)) | 843 | if (sizeof(ex->gpr[i]) == sizeof(int32_t)) |
| 849 | setintV(L->top++, (int32_t)ex->gpr[i]); | 844 | setintV(V->top++, (int32_t)ex->gpr[i]); |
| 850 | else | 845 | else |
| 851 | setnumV(L->top++, (lua_Number)ex->gpr[i]); | 846 | setnumV(V->top++, (lua_Number)ex->gpr[i]); |
| 852 | } | 847 | } |
| 853 | #if !LJ_SOFTFP | 848 | #if !LJ_SOFTFP |
| 854 | for (i = 0; i < RID_NUM_FPR; i++) { | 849 | for (i = 0; i < RID_NUM_FPR; i++) { |
| 855 | setnumV(L->top, ex->fpr[i]); | 850 | setnumV(V->top, ex->fpr[i]); |
| 856 | if (LJ_UNLIKELY(tvisnan(L->top))) | 851 | if (LJ_UNLIKELY(tvisnan(V->top))) |
| 857 | setnanV(L->top); | 852 | setnanV(V->top); |
| 858 | L->top++; | 853 | V->top++; |
| 859 | } | 854 | } |
| 860 | #endif | 855 | #endif |
| 861 | } | 856 | } |
| @@ -897,6 +892,8 @@ int LJ_FASTCALL lj_trace_exit(jit_State *J, void *exptr) | |||
| 897 | 892 | ||
| 898 | #ifdef EXITSTATE_PCREG | 893 | #ifdef EXITSTATE_PCREG |
| 899 | J->parent = trace_exit_find(J, (MCode *)(intptr_t)ex->gpr[EXITSTATE_PCREG]); | 894 | J->parent = trace_exit_find(J, (MCode *)(intptr_t)ex->gpr[EXITSTATE_PCREG]); |
| 895 | #else | ||
| 896 | UNUSED(ex); | ||
| 900 | #endif | 897 | #endif |
| 901 | T = traceref(J, J->parent); UNUSED(T); | 898 | T = traceref(J, J->parent); UNUSED(T); |
| 902 | #ifdef EXITSTATE_CHECKEXIT | 899 | #ifdef EXITSTATE_CHECKEXIT |
| @@ -917,11 +914,11 @@ int LJ_FASTCALL lj_trace_exit(jit_State *J, void *exptr) | |||
| 917 | if (exitcode) copyTV(L, L->top++, &exiterr); /* Anchor the error object. */ | 914 | if (exitcode) copyTV(L, L->top++, &exiterr); /* Anchor the error object. */ |
| 918 | 915 | ||
| 919 | if (!(LJ_HASPROFILE && (G(L)->hookmask & HOOK_PROFILE))) | 916 | if (!(LJ_HASPROFILE && (G(L)->hookmask & HOOK_PROFILE))) |
| 920 | lj_vmevent_send(L, TEXIT, | 917 | lj_vmevent_send(G(L), TEXIT, |
| 921 | lj_state_checkstack(L, 4+RID_NUM_GPR+RID_NUM_FPR+LUA_MINSTACK); | 918 | lj_state_checkstack(V, 4+RID_NUM_GPR+RID_NUM_FPR+LUA_MINSTACK); |
| 922 | setintV(L->top++, J->parent); | 919 | setintV(V->top++, J->parent); |
| 923 | setintV(L->top++, J->exitno); | 920 | setintV(V->top++, J->exitno); |
| 924 | trace_exit_regs(L, ex); | 921 | trace_exit_regs(V, ex); |
| 925 | ); | 922 | ); |
| 926 | 923 | ||
| 927 | pc = exd.pc; | 924 | pc = exd.pc; |
diff --git a/src/lj_vmevent.c b/src/lj_vmevent.c index 070c6144..8913ead9 100644 --- a/src/lj_vmevent.c +++ b/src/lj_vmevent.c | |||
| @@ -38,6 +38,7 @@ ptrdiff_t lj_vmevent_prepare(lua_State *L, VMEvent ev) | |||
| 38 | void lj_vmevent_call(lua_State *L, ptrdiff_t argbase) | 38 | void lj_vmevent_call(lua_State *L, ptrdiff_t argbase) |
| 39 | { | 39 | { |
| 40 | global_State *g = G(L); | 40 | global_State *g = G(L); |
| 41 | lua_State *oldL = gco2th(gcref(g->cur_L)); | ||
| 41 | uint8_t oldmask = g->vmevmask; | 42 | uint8_t oldmask = g->vmevmask; |
| 42 | uint8_t oldh = hook_save(g); | 43 | uint8_t oldh = hook_save(g); |
| 43 | int status; | 44 | int status; |
| @@ -51,6 +52,10 @@ void lj_vmevent_call(lua_State *L, ptrdiff_t argbase) | |||
| 51 | fputs(tvisstr(L->top) ? strVdata(L->top) : "?", stderr); | 52 | fputs(tvisstr(L->top) ? strVdata(L->top) : "?", stderr); |
| 52 | fputc('\n', stderr); | 53 | fputc('\n', stderr); |
| 53 | } | 54 | } |
| 55 | setgcref(g->cur_L, obj2gco(oldL)); | ||
| 56 | #if LJ_HASJIT | ||
| 57 | G2J(g)->L = oldL; | ||
| 58 | #endif | ||
| 54 | hook_restore(g, oldh); | 59 | hook_restore(g, oldh); |
| 55 | if (g->vmevmask != VMEVENT_NOCACHE) | 60 | if (g->vmevmask != VMEVENT_NOCACHE) |
| 56 | g->vmevmask = oldmask; /* Restore event mask, but not if not modified. */ | 61 | g->vmevmask = oldmask; /* Restore event mask, but not if not modified. */ |
diff --git a/src/lj_vmevent.h b/src/lj_vmevent.h index 8a995360..cdd4f758 100644 --- a/src/lj_vmevent.h +++ b/src/lj_vmevent.h | |||
| @@ -32,23 +32,25 @@ typedef enum { | |||
| 32 | } VMEvent; | 32 | } VMEvent; |
| 33 | 33 | ||
| 34 | #ifdef LUAJIT_DISABLE_VMEVENT | 34 | #ifdef LUAJIT_DISABLE_VMEVENT |
| 35 | #define lj_vmevent_send(L, ev, args) UNUSED(L) | 35 | #define lj_vmevent_send(g, ev, args) UNUSED(g) |
| 36 | #define lj_vmevent_send_(L, ev, args, post) UNUSED(L) | 36 | #define lj_vmevent_send_(g, ev, args, post) UNUSED(g) |
| 37 | #else | 37 | #else |
| 38 | #define lj_vmevent_send(L, ev, args) \ | 38 | #define lj_vmevent_send(g, ev, args) \ |
| 39 | if (G(L)->vmevmask & VMEVENT_MASK(LJ_VMEVENT_##ev)) { \ | 39 | if ((g)->vmevmask & VMEVENT_MASK(LJ_VMEVENT_##ev)) { \ |
| 40 | ptrdiff_t argbase = lj_vmevent_prepare(L, LJ_VMEVENT_##ev); \ | 40 | lua_State *V = vmthread(g); \ |
| 41 | ptrdiff_t argbase = lj_vmevent_prepare(V, LJ_VMEVENT_##ev); \ | ||
| 41 | if (argbase) { \ | 42 | if (argbase) { \ |
| 42 | args \ | 43 | args \ |
| 43 | lj_vmevent_call(L, argbase); \ | 44 | lj_vmevent_call(V, argbase); \ |
| 44 | } \ | 45 | } \ |
| 45 | } | 46 | } |
| 46 | #define lj_vmevent_send_(L, ev, args, post) \ | 47 | #define lj_vmevent_send_(g, ev, args, post) \ |
| 47 | if (G(L)->vmevmask & VMEVENT_MASK(LJ_VMEVENT_##ev)) { \ | 48 | if ((g)->vmevmask & VMEVENT_MASK(LJ_VMEVENT_##ev)) { \ |
| 48 | ptrdiff_t argbase = lj_vmevent_prepare(L, LJ_VMEVENT_##ev); \ | 49 | lua_State *V = vmthread(g); \ |
| 50 | ptrdiff_t argbase = lj_vmevent_prepare(V, LJ_VMEVENT_##ev); \ | ||
| 49 | if (argbase) { \ | 51 | if (argbase) { \ |
| 50 | args \ | 52 | args \ |
| 51 | lj_vmevent_call(L, argbase); \ | 53 | lj_vmevent_call(V, argbase); \ |
| 52 | post \ | 54 | post \ |
| 53 | } \ | 55 | } \ |
| 54 | } | 56 | } |
