Skip to content

Instantly share code, notes, and snippets.

@FROGGS
Last active December 22, 2015 14:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save FROGGS/d006980f3c95b53364ca to your computer and use it in GitHub Desktop.
Save FROGGS/d006980f3c95b53364ca to your computer and use it in GitHub Desktop.
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