Skip to content

Commit

Permalink
Migrate exception unwind usage of special return
Browse files Browse the repository at this point in the history
  • Loading branch information
jnthn committed Nov 3, 2021
1 parent ae6b4b7 commit 94778d2
Show file tree
Hide file tree
Showing 4 changed files with 12 additions and 32 deletions.
6 changes: 4 additions & 2 deletions src/core/callstack.c
Expand Up @@ -587,6 +587,8 @@ static void exit_frame(MVMThreadContext *tc, MVMFrame *returner) {
* remove_one_frame, in that case for the sake of lazy deopt. */
*(tc->interp_cur_op) = caller->return_address;
*(tc->interp_bytecode_start) = MVM_frame_effective_bytecode(caller);
*(tc->interp_reg_base) = caller->work;
*(tc->interp_cu) = caller->static_info->body.cu;
}
else {
tc->cur_frame = NULL;
Expand Down Expand Up @@ -714,15 +716,15 @@ MVMFrame * MVM_callstack_unwind_frame(MVMThreadContext *tc, MVMuint8 exceptional

/* Run the callback if present. */
MVMCallStackRecord *top_was = tc->stack_top;
MVMuint8 *bytecode_was = *(tc->interp_cur_op);
if (!exceptional && special_return)
special_return(tc, data);
else if (exceptional && special_unwind)
special_unwind(tc, data);

/* If we invoked something, then set the thunk flag and return. */
if (tc->stack_top != top_was) {
if (tc->stack_top != top_was || bytecode_was != *(tc->interp_cur_op)) {
*thunked = 1;
return NULL;
}
break;
}
Expand Down
27 changes: 8 additions & 19 deletions src/core/exceptions.c
Expand Up @@ -397,8 +397,10 @@ static void run_handler(MVMThreadContext *tc, LocatedHandler lh, MVMObject *ex_o
cur_frame->return_value = (MVMRegister *)&tc->last_handler_result;
cur_frame->return_type = MVM_RETURN_OBJ;
cur_frame->return_address = *(tc->interp_cur_op);
MVM_frame_special_return(tc, cur_frame, unwind_after_handler, cleanup_active_handler,
ah, NULL);
MVMActiveHandler **sr = MVM_callstack_allocate_special_return(tc,
unwind_after_handler, cleanup_active_handler,
NULL, sizeof(MVMActiveHandler *));
*sr = ah;

/* Invoke the handler frame and return to runloop. */
MVM_frame_dispatch_zero_args(tc, (MVMCode *)handler_code);
Expand All @@ -419,7 +421,7 @@ static void unwind_after_handler(MVMThreadContext *tc, void *sr_data) {

/* Get active handler; sanity check (though it's possible other cases
* should be supported). */
MVMActiveHandler *ah = (MVMActiveHandler *)sr_data;
MVMActiveHandler *ah = *((MVMActiveHandler **)sr_data);
if (tc->active_handlers != ah)
MVM_panic(1, "Trying to unwind from wrong handler");

Expand Down Expand Up @@ -455,7 +457,7 @@ static void unwind_after_handler(MVMThreadContext *tc, void *sr_data) {
static void cleanup_active_handler(MVMThreadContext *tc, void *sr_data) {
/* Get active handler; sanity check (though it's possible other cases
* should be supported). */
MVMActiveHandler *ah = (MVMActiveHandler *)sr_data;
MVMActiveHandler *ah = *((MVMActiveHandler **)sr_data);
if (tc->active_handlers != ah)
MVM_panic(1, "Trying to unwind over wrong handler");

Expand Down Expand Up @@ -804,10 +806,7 @@ void MVM_exception_throwpayload(MVMThreadContext *tc, MVMuint8 mode, MVMuint32 c
}

void MVM_exception_resume(MVMThreadContext *tc, MVMObject *ex_obj) {
MVMException *ex;
MVMFrame *target;
MVMActiveHandler *ah;

MVMException *ex;
if (IS_CONCRETE(ex_obj) && REPR(ex_obj)->ID == MVM_REPR_ID_MVMException)
ex = (MVMException *)ex_obj;
else
Expand All @@ -816,11 +815,9 @@ void MVM_exception_resume(MVMThreadContext *tc, MVMObject *ex_obj) {
/* Check that everything is in place to do the resumption. */
if (!ex->body.resume_addr)
MVM_exception_throw_adhoc(tc, "This exception is not resumable");
target = ex->body.origin;
MVMFrame *target = ex->body.origin;
if (!target)
MVM_exception_throw_adhoc(tc, "This exception is not resumable");
if (!target->extra || target->extra->special_return != unwind_after_handler)
MVM_exception_throw_adhoc(tc, "This exception is not resumable");
if (!in_caller_chain(tc, target))
MVM_exception_throw_adhoc(tc, "Too late to resume this exception");

Expand All @@ -830,14 +827,6 @@ void MVM_exception_resume(MVMThreadContext *tc, MVMObject *ex_obj) {
if (tc->active_handlers->ex_obj != ex_obj)
MVM_exception_throw_adhoc(tc, "Can only resume the current exception");

/* Clear special return handler; we'll do its work here. */
MVM_frame_clear_special_return(tc, target);

/* Clear the current active handler. */
ah = tc->active_handlers;
tc->active_handlers = ah->next_handler;
MVM_fixed_size_free(tc, tc->instance->fsa, sizeof(MVMActiveHandler), ah);

/* Unwind to the thrower of the exception; set PC and jit entry label. */
MVM_frame_unwind_to(tc, target, ex->body.resume_addr, 0, NULL, ex->body.jit_resume_label);
}
Expand Down
10 changes: 0 additions & 10 deletions src/core/frame.c
Expand Up @@ -1775,16 +1775,6 @@ void MVM_frame_special_return(MVMThreadContext *tc, MVMFrame *f,
e->mark_special_return_data = mark_special_return_data;
}

/* Clears any special return data on a frame. */
void MVM_frame_clear_special_return(MVMThreadContext *tc, MVMFrame *f) {
if (f->extra) {
f->extra->special_return = NULL;
f->extra->special_unwind = NULL;
f->extra->special_return_data = NULL;
f->extra->mark_special_return_data = NULL;
}
}

/* Gets the code object of the caller, provided there is one. Works even in
* the face that the caller was an inline (however, the current frame that is
* using the op must not be itself inlined). */
Expand Down
1 change: 0 additions & 1 deletion src/core/frame.h
Expand Up @@ -202,5 +202,4 @@ MVMFrameExtra * MVM_frame_extra(MVMThreadContext *tc, MVMFrame *f);
MVM_PUBLIC void MVM_frame_special_return(MVMThreadContext *tc, MVMFrame *f,
MVMSpecialReturn special_return, MVMSpecialReturn special_unwind,
void *special_return_data, MVMSpecialReturnDataMark mark_special_return_data);
MVM_PUBLIC void MVM_frame_clear_special_return(MVMThreadContext *tc, MVMFrame *f);
MVMObject * MVM_frame_caller_code(MVMThreadContext *tc);

0 comments on commit 94778d2

Please sign in to comment.