diff options
Diffstat (limited to 'src/lj_trace.c')
-rw-r--r-- | src/lj_trace.c | 34 |
1 files changed, 28 insertions, 6 deletions
diff --git a/src/lj_trace.c b/src/lj_trace.c index 3b137164..43104be6 100644 --- a/src/lj_trace.c +++ b/src/lj_trace.c | |||
@@ -574,13 +574,34 @@ static void trace_hotside(jit_State *J, const BCIns *pc) | |||
574 | } | 574 | } |
575 | } | 575 | } |
576 | 576 | ||
577 | /* Tiny struct to pass data to protected call. */ | ||
578 | typedef struct ExitDataCP { | ||
579 | jit_State *J; | ||
580 | void *exptr; /* Pointer to exit state. */ | ||
581 | const BCIns *pc; /* Restart interpreter at this PC. */ | ||
582 | } ExitDataCP; | ||
583 | |||
584 | /* Need to protect lj_snap_restore because it may throw. */ | ||
585 | static TValue *trace_exit_cp(lua_State *L, lua_CFunction dummy, void *ud) | ||
586 | { | ||
587 | ExitDataCP *exd = (ExitDataCP *)ud; | ||
588 | cframe_errfunc(L->cframe) = -1; /* Inherit error function. */ | ||
589 | exd->pc = lj_snap_restore(exd->J, exd->exptr); | ||
590 | UNUSED(dummy); | ||
591 | return NULL; | ||
592 | } | ||
593 | |||
577 | /* A trace exited. Restore interpreter state. */ | 594 | /* A trace exited. Restore interpreter state. */ |
578 | void * LJ_FASTCALL lj_trace_exit(jit_State *J, void *exptr) | 595 | int LJ_FASTCALL lj_trace_exit(jit_State *J, void *exptr) |
579 | { | 596 | { |
580 | const BCIns *pc = lj_snap_restore(J, exptr); | ||
581 | lua_State *L = J->L; | 597 | lua_State *L = J->L; |
582 | void *cf = cframe_raw(L->cframe); | 598 | ExitDataCP exd; |
583 | setcframe_pc(cf, pc); /* Restart interpreter at this PC. */ | 599 | int errcode; |
600 | exd.J = J; | ||
601 | exd.exptr = exptr; | ||
602 | errcode = lj_vm_cpcall(L, NULL, &exd, trace_exit_cp); | ||
603 | if (errcode) | ||
604 | return errcode; | ||
584 | 605 | ||
585 | lj_vmevent_send(L, TEXIT, | 606 | lj_vmevent_send(L, TEXIT, |
586 | ExitState *ex = (ExitState *)exptr; | 607 | ExitState *ex = (ExitState *)exptr; |
@@ -600,8 +621,9 @@ void * LJ_FASTCALL lj_trace_exit(jit_State *J, void *exptr) | |||
600 | } | 621 | } |
601 | ); | 622 | ); |
602 | 623 | ||
603 | trace_hotside(J, pc); | 624 | trace_hotside(J, exd.pc); |
604 | return cf; /* Return the interpreter C frame. */ | 625 | setcframe_pc(cframe_raw(L->cframe), exd.pc); |
626 | return 0; | ||
605 | } | 627 | } |
606 | 628 | ||
607 | #endif | 629 | #endif |