-
-
Save FROGGS/d006980f3c95b53364ca to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/lib/MAST/Ops.nqp b/lib/MAST/Ops.nqp | |
index b94298e..7b318e7 100644 | |
--- a/lib/MAST/Ops.nqp | |
+++ b/lib/MAST/Ops.nqp | |
@@ -494,7 +494,8 @@ BEGIN { | |
1184, | |
1188, | |
1189, | |
- 1190); | |
+ 1190, | |
+ 1191); | |
MAST::Ops.WHO<@counts> := nqp::list_i(0, | |
1, | |
2, | |
@@ -986,6 +987,7 @@ BEGIN { | |
4, | |
1, | |
1, | |
+ 1, | |
1); | |
MAST::Ops.WHO<@values> := nqp::list_i(72, | |
33, | |
@@ -2177,6 +2179,7 @@ BEGIN { | |
65, | |
58, | |
33, | |
+ 65, | |
65); | |
MAST::Ops.WHO<%codes> := nqp::hash('no_op', 0, | |
'goto', 1, | |
@@ -2669,7 +2672,8 @@ BEGIN { | |
'shell', 488, | |
'cwd', 489, | |
'seed', 490, | |
- 'rethrow', 491); | |
+ 'rethrow', 491, | |
+ 'resume', 492); | |
MAST::Ops.WHO<@names> := nqp::list('no_op', | |
'goto', | |
'if_i', | |
@@ -3161,5 +3165,6 @@ BEGIN { | |
'shell', | |
'cwd', | |
'seed', | |
- 'rethrow'); | |
+ 'rethrow', | |
+ 'resume'); | |
} | |
diff --git a/nqp-cc/src/QASTOperationsMAST.nqp b/nqp-cc/src/QASTOperationsMAST.nqp | |
index 5101056..923f349 100644 | |
--- a/nqp-cc/src/QASTOperationsMAST.nqp | |
+++ b/nqp-cc/src/QASTOperationsMAST.nqp | |
@@ -1198,7 +1198,7 @@ QAST::MASTOperations.add_core_moarop_mapping('backtracestrings', 'backtracestrin | |
# XXX backtrace | |
QAST::MASTOperations.add_core_moarop_mapping('throw', 'throwdyn'); | |
QAST::MASTOperations.add_core_moarop_mapping('rethrow', 'rethrow'); | |
-# XXX resume | |
+QAST::MASTOperations.add_core_moarop_mapping('resume', 'resume'); | |
my %handler_names := nqp::hash( | |
'CATCH', $HandlerCategory::catch, | |
diff --git a/src/6model/reprs/MVMException.h b/src/6model/reprs/MVMException.h | |
index ec32d2c..a41db4d 100644 | |
--- a/src/6model/reprs/MVMException.h | |
+++ b/src/6model/reprs/MVMException.h | |
@@ -14,6 +14,9 @@ struct MVMExceptionBody { | |
/* Where was the exception thrown from? */ | |
MVMFrame *origin; | |
+ | |
+ /* Offset into the frame's bytecode, for resumption. */ | |
+ MVMuint32 goto_offset; | |
}; | |
struct MVMException { | |
MVMObject common; | |
diff --git a/src/core/exceptions.c b/src/core/exceptions.c | |
index 0cdfd90..03737c3 100644 | |
--- a/src/core/exceptions.c | |
+++ b/src/core/exceptions.c | |
@@ -326,6 +326,20 @@ void MVM_exception_throwobj(MVMThreadContext *tc, MVMuint8 mode, MVMObject *ex_o | |
run_handler(tc, lh, ex_obj); | |
} | |
+void MVM_exception_resume(MVMThreadContext *tc, MVMObject *ex_obj) { | |
+ MVMException *ex; | |
+ MVMActiveHandler *ah; | |
+ | |
+ if (IS_CONCRETE(ex_obj) && REPR(ex_obj)->ID == MVM_REPR_ID_MVMException) | |
+ ex = (MVMException *)ex_obj; | |
+ else | |
+ MVM_exception_throw_adhoc(tc, "Can only resume an exception object"); | |
+ | |
+ ah = (MVMActiveHandler *)ex->body.origin->special_return_data; | |
+ ah->frame = (void *)ex->body.origin; | |
+ ah->handler->goto_offset = ex->body.goto_offset; | |
+} | |
+ | |
/* Creates a new lexotic. */ | |
MVMObject * MVM_exception_newlexotic(MVMThreadContext *tc, MVMuint32 offset) { | |
MVMLexotic *lexotic; | |
diff --git a/src/core/exceptions.h b/src/core/exceptions.h | |
index 68dd455..eac5eb5 100644 | |
--- a/src/core/exceptions.h | |
+++ b/src/core/exceptions.h | |
@@ -61,6 +61,7 @@ struct MVMActiveHandler { | |
MVMObject * MVM_exception_backtrace_strings(MVMThreadContext *tc, MVMObject *exObj); | |
void MVM_exception_throwcat(MVMThreadContext *tc, MVMuint8 mode, MVMuint32 cat, MVMRegister *resume_result); | |
void MVM_exception_throwobj(MVMThreadContext *tc, MVMuint8 mode, MVMObject *exObj, MVMRegister *resume_result); | |
+void MVM_exception_resume(MVMThreadContext *tc, MVMObject *exObj); | |
MVMObject * MVM_exception_newlexotic(MVMThreadContext *tc, MVMuint32 offset); | |
void MVM_exception_gotolexotic(MVMThreadContext *tc, MVMFrameHandler *h, MVMFrame *f); | |
MVM_NO_RETURN void MVM_panic(MVMint32 exitCode, const char *messageFormat, ...) MVM_NO_RETURN_GCC; | |
diff --git a/src/core/interp.c b/src/core/interp.c | |
index 1d43e9e..5c6a5fd 100644 | |
--- a/src/core/interp.c | |
+++ b/src/core/interp.c | |
@@ -968,9 +968,13 @@ void MVM_interp_run(MVMThreadContext *tc, void (*initial_invoke)(MVMThreadContex | |
OP(die): { | |
MVMObject *ex_obj = MVM_repr_alloc_init(tc, tc->instance->boot_types->BOOTException); | |
MVMException *ex = (MVMException *)ex_obj; | |
+ MVMRegister *resume_result = &GET_REG(cur_op, 0); | |
+ | |
ex->body.category = MVM_EX_CAT_CATCH; | |
MVM_ASSIGN_REF(tc, ex_obj, ex->body.message, GET_REG(cur_op, 2).s); | |
- MVM_exception_throwobj(tc, MVM_EX_THROW_DYN, ex_obj, &GET_REG(cur_op, 0)); | |
+ cur_op += 4; | |
+ ex->body.goto_offset = (MVMuint32)(*tc->interp_cur_op - *tc->interp_bytecode_start); | |
+ MVM_exception_throwobj(tc, MVM_EX_THROW_DYN, ex_obj, resume_result); | |
goto NEXT; | |
} | |
OP(newlexotic): { | |
@@ -3350,6 +3354,24 @@ void MVM_interp_run(MVMThreadContext *tc, void (*initial_invoke)(MVMThreadContex | |
cur_op += 2; | |
goto NEXT; | |
} | |
+ OP(resume): { | |
+ MVMObject *ex_obj = MVM_repr_alloc_init(tc, tc->instance->boot_types->BOOTException); | |
+ MVMException *ex = (MVMException *)ex_obj; | |
+ | |
+ MVMObject *got_ex_obj = GET_REG(cur_op, 0).o; | |
+ if (REPR(got_ex_obj)->ID == MVM_REPR_ID_MVMException) { | |
+ MVMException *got_ex = (MVMException *)got_ex_obj; | |
+ | |
+ ex->body.origin = MVM_frame_inc_ref(tc, got_ex->body.origin); | |
+ ex->body.goto_offset = got_ex->body.goto_offset; | |
+ MVM_exception_resume(tc, ex_obj); | |
+ } | |
+ else { | |
+ MVM_exception_throw_adhoc(tc, "resume requires an MVMException"); | |
+ } | |
+ cur_op += 2; | |
+ goto NEXT; | |
+ } | |
#if !MVM_CGOTO | |
default: | |
MVM_panic(MVM_exitcode_invalidopcode, "Invalid opcode executed (corrupt bytecode stream?) opcode %u", *(cur_op-2)); | |
diff --git a/src/core/oplabels.h b/src/core/oplabels.h | |
index cd7c8c4..d2346d7 100644 | |
--- a/src/core/oplabels.h | |
+++ b/src/core/oplabels.h | |
@@ -492,5 +492,6 @@ static const void * const LABELS[] = { | |
&&OP_shell, | |
&&OP_cwd, | |
&&OP_seed, | |
- &&OP_rethrow | |
+ &&OP_rethrow, | |
+ &&OP_resume | |
}; | |
diff --git a/src/core/oplist b/src/core/oplist | |
index 675f7f7..b1f76cf 100644 | |
--- a/src/core/oplist | |
+++ b/src/core/oplist | |
@@ -526,3 +526,4 @@ shell w(int64) r(str) r(str) r(obj) | |
cwd w(str) | |
seed r(int64) | |
rethrow r(obj) | |
+resume r(obj) | |
diff --git a/src/core/ops.c b/src/core/ops.c | |
index a042be3..3029b33 100644 | |
--- a/src/core/ops.c | |
+++ b/src/core/ops.c | |
@@ -2960,9 +2960,15 @@ static MVMOpInfo MVM_op_infos[] = { | |
1, | |
{ MVM_operand_read_reg | MVM_operand_obj } | |
}, | |
+ { | |
+ MVM_OP_resume, | |
+ "resume", | |
+ 1, | |
+ { MVM_operand_read_reg | MVM_operand_obj } | |
+ }, | |
}; | |
-static unsigned short MVM_op_counts = 492; | |
+static unsigned short MVM_op_counts = 493; | |
MVMOpInfo * MVM_op_get_op(unsigned short op) { | |
if (op >= MVM_op_counts) | |
diff --git a/src/core/ops.h b/src/core/ops.h | |
index 4cd3d82..718e542 100644 | |
--- a/src/core/ops.h | |
+++ b/src/core/ops.h | |
@@ -493,5 +493,6 @@ | |
#define MVM_OP_cwd 489 | |
#define MVM_OP_seed 490 | |
#define MVM_OP_rethrow 491 | |
+#define MVM_OP_resume 492 | |
MVMOpInfo * MVM_op_get_op(unsigned short op); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment