Skip to content

Instantly share code, notes, and snippets.

@FROGGS
Created July 26, 2013 21:05
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/d8960e3a60e94eacf90b to your computer and use it in GitHub Desktop.
Save FROGGS/d8960e3a60e94eacf90b to your computer and use it in GitHub Desktop.
diff --git a/lib/MAST/Ops.nqp b/lib/MAST/Ops.nqp
index 2636df9..77eb7a4 100644
--- a/lib/MAST/Ops.nqp
+++ b/lib/MAST/Ops.nqp
@@ -1346,6 +1346,13 @@ class MAST::Ops {
$MVM_operand_read_reg +| $MVM_operand_obj
]
),
+ 'backtrace_strings', nqp::hash(
+ 'code', 177,
+ 'operands', [
+ $MVM_operand_write_reg +| $MVM_operand_obj,
+ $MVM_operand_read_reg +| $MVM_operand_obj
+ ]
+ ),
],
[
'sleep', nqp::hash(
diff --git a/nqp-cc/src/QASTOperationsMAST.nqp b/nqp-cc/src/QASTOperationsMAST.nqp
index d284144..2d52d0b 100644
--- a/nqp-cc/src/QASTOperationsMAST.nqp
+++ b/nqp-cc/src/QASTOperationsMAST.nqp
@@ -1164,6 +1164,7 @@ QAST::MASTOperations.add_core_moarop_mapping('setpayload', 'bindexpayload', 1);
QAST::MASTOperations.add_core_moarop_mapping('getmessage', 'getexmessage');
QAST::MASTOperations.add_core_moarop_mapping('setmessage', 'bindexmessage', 1);
QAST::MASTOperations.add_core_moarop_mapping('newexception', 'newexception');
+QAST::MASTOperations.add_core_moarop_mapping('backtracestrings', 'backtrace_strings');
# XXX backtrace, backtracestrings
QAST::MASTOperations.add_core_moarop_mapping('throw', 'throwdyn');
# XXX rethrow, resume
diff --git a/src/6model/reprs/MVMException.c b/src/6model/reprs/MVMException.c
index d0493ae..0983c80 100644
--- a/src/6model/reprs/MVMException.c
+++ b/src/6model/reprs/MVMException.c
@@ -26,6 +26,7 @@ static MVMObject * allocate(MVMThreadContext *tc, MVMSTable *st) {
/* Initializes a new instance. */
static void initialize(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data) {
+ ((MVMExceptionBody *)data)->origin = tc->cur_frame;
}
/* Copies the body of one object to another. */
@@ -53,6 +54,15 @@ static void gc_free(MVMThreadContext *tc, MVMObject *obj) {
}
}
+static void * get_boxed_ref(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data, MVMuint32 repr_id) {
+ if (repr_id == MVM_REPR_ID_MVMException) {
+ return ((MVMExceptionBody *)data)->origin;
+ }
+
+ MVM_exception_throw_adhoc(tc,
+ "Exception representation cannot unbox to other types");
+}
+
/* Gets the storage specification for this representation. */
static MVMStorageSpec get_storage_spec(MVMThreadContext *tc, MVMSTable *st) {
MVMStorageSpec spec;
@@ -80,6 +90,8 @@ MVMREPROps * MVMException_initialize(MVMThreadContext *tc) {
this_repr->gc_mark = gc_mark;
this_repr->gc_free = gc_free;
this_repr->get_storage_spec = get_storage_spec;
+ this_repr->box_funcs = malloc(sizeof(MVMREPROps_Boxing));
+ this_repr->box_funcs->get_boxed_ref = get_boxed_ref;
this_repr->compose = compose;
return this_repr;
}
diff --git a/src/core/exceptions.c b/src/core/exceptions.c
index c3007a3..5df0548 100644
--- a/src/core/exceptions.c
+++ b/src/core/exceptions.c
@@ -181,6 +181,28 @@ void unwind_after_handler(MVMThreadContext *tc, void *sr_data) {
free(ah);
}
+struct _MVMString * MVM_exception_backtrace_strings(MVMThreadContext *tc, MVMObject *exObj) {
+ MVMException *ex;
+
+ if (IS_CONCRETE(exObj) && REPR(exObj)->ID == MVM_REPR_ID_MVMException)
+ ex = (MVMException *)exObj;
+ else
+ MVM_exception_throw_adhoc(tc, "Can only throw an exception object");
+
+ MVMFrame *cur_frame = (MVMFrame *)REPR(exObj)->box_funcs->get_boxed_ref(tc, STABLE(exObj), exObj,
+ OBJECT_BODY(exObj), MVM_REPR_ID_MVMException);
+ MVMString *s = (MVMString *)REPR(tc->instance->VMString)->allocate(tc, STABLE(tc->instance->VMString));
+ while (cur_frame != NULL) {
+ s = MVM_string_concatenate(tc, s, cur_frame->static_info->name);
+ /* temporary for debugging */
+ fprintf(stderr, ">> in %s\n",
+ MVM_string_utf8_encode(tc, cur_frame->static_info->name, NULL));
+ cur_frame = cur_frame->caller;
+ }
+
+ return s;
+}
+
/* Dumps a backtrace relative to the current frame to stderr. */
static void dump_backtrace(MVMThreadContext *tc) {
MVMFrame *cur_frame = tc->cur_frame;
diff --git a/src/core/exceptions.h b/src/core/exceptions.h
index 7b4155b..e83ffe9 100644
--- a/src/core/exceptions.h
+++ b/src/core/exceptions.h
@@ -58,6 +58,7 @@ typedef struct _MVMActiveHandler {
} MVMActiveHandler;
/* Exception related functions. */
+struct _MVMString * MVM_exception_backtrace_strings(MVMThreadContext *tc, MVMObject *exObj);
void MVM_exception_throwcat(MVMThreadContext *tc, MVMuint8 mode, MVMuint32 cat, union _MVMRegister *resume_result);
void MVM_exception_throwobj(MVMThreadContext *tc, MVMuint8 mode, MVMObject *exObj, MVMRegister *resume_result);
struct _MVMObject * MVM_exception_newlexotic(MVMThreadContext *tc, MVMuint32 offset);
diff --git a/src/core/interp.c b/src/core/interp.c
index 21136e8..e1f7e88 100644
--- a/src/core/interp.c
+++ b/src/core/interp.c
@@ -1091,6 +1091,23 @@ void MVM_interp_run(MVMThreadContext *tc, void (*initial_invoke)(MVMThreadContex
cur_op += 4;
break;
}
+ case MVM_OP_backtrace_strings: {
+ MVMObject *ex = GET_REG(cur_op, 2).o;
+ MVMROOT(tc, ex, {
+ MVMObject *arr = MVM_repr_alloc_init(tc, tc->instance->boot_types->BOOTArray);
+ MVMROOT(tc, arr, {
+ MVMObject *pobj = MVM_repr_alloc_init(tc, tc->instance->boot_types->BOOTStr);
+ MVMROOT(tc, pobj, {
+ MVMString *s = MVM_exception_backtrace_strings(tc, ex);
+ MVM_repr_set_str(tc, pobj, s);
+ MVM_repr_push_o(tc, arr, pobj);
+ GET_REG(cur_op, 0).o = arr;
+ });
+ });
+ });
+ cur_op += 4;
+ break;
+ }
default: {
MVM_panic(MVM_exitcode_invalidopcode, "Invalid opcode executed (corrupt bytecode stream?) bank %u opcode %u",
MVM_OP_BANK_primitives, *(cur_op-1));
diff --git a/src/core/oplist b/src/core/oplist
index a3c5006..e34036f 100644
--- a/src/core/oplist
+++ b/src/core/oplist
@@ -176,6 +176,7 @@ BANK 0 primitives
0xAE assign r(obj) r(obj)
0xAF assignunchecked r(obj) r(obj)
0xB0 objprimspec w(int64) r(obj)
+0xB1 backtrace_strings w(obj) r(obj)
BANK 1 dev
0x00 sleep r(int64)
diff --git a/src/core/ops.c b/src/core/ops.c
index 41689d5..c34b019 100644
--- a/src/core/ops.c
+++ b/src/core/ops.c
@@ -1070,6 +1070,12 @@ static MVMOpInfo MVM_op_info_primitives[] = {
2,
{ MVM_operand_write_reg | MVM_operand_int64, MVM_operand_read_reg | MVM_operand_obj }
},
+ {
+ MVM_OP_backtrace_strings,
+ "backtrace_strings",
+ 2,
+ { MVM_operand_write_reg | MVM_operand_obj, MVM_operand_read_reg | MVM_operand_obj }
+ },
};
static MVMOpInfo MVM_op_info_dev[] = {
{
@@ -3173,7 +3179,7 @@ static MVMOpInfo *MVM_op_info[] = {
static unsigned char MVM_op_banks = 8;
static unsigned char MVM_opcounts_by_bank[] = {
- 177,
+ 178,
2,
53,
57,
diff --git a/src/core/ops.h b/src/core/ops.h
index 31fb90a..94510db 100644
--- a/src/core/ops.h
+++ b/src/core/ops.h
@@ -188,6 +188,7 @@
#define MVM_OP_assign 174
#define MVM_OP_assignunchecked 175
#define MVM_OP_objprimspec 176
+#define MVM_OP_backtrace_strings 177
/* Op name defines for bank dev. */
#define MVM_OP_sleep 0
@FROGGS
Copy link
Author

FROGGS commented Jul 26, 2013

    oops();
    CATCH {
        say(nqp::backtracestrings($!));
    }
nqp nqp-moar-cc.nqp t/nqp/44-try-catch.t
make: »moarvm« ist bereits aktualisiert.
1..9
ok 1 - exceptions exit a try block
>>  in oops
>>  in frame_name_0
>>  in frame_name_30
cannot stringify this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment