-
-
Save FROGGS/d8960e3a60e94eacf90b 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 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 |
Author
FROGGS
commented
Jul 26, 2013
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment