Skip to content

Commit

Permalink
implement op backtrace
Browse files Browse the repository at this point in the history
  • Loading branch information
FROGGS committed Nov 27, 2013
1 parent ed9b09d commit 58e6fae
Show file tree
Hide file tree
Showing 8 changed files with 94 additions and 8 deletions.
16 changes: 11 additions & 5 deletions lib/MAST/Ops.nqp
Expand Up @@ -547,7 +547,8 @@ BEGIN {
1291,
1293,
1298,
1299);
1299,
1304);
MAST::Ops.WHO<@counts> := nqp::list_i(0,
2,
2,
Expand Down Expand Up @@ -1092,7 +1093,8 @@ BEGIN {
2,
5,
1,
5);
5,
2);
MAST::Ops.WHO<@values> := nqp::list_i(10,
8,
18,
Expand Down Expand Up @@ -2396,7 +2398,9 @@ BEGIN {
57,
57,
65,
57);
57,
66,
65);
MAST::Ops.WHO<%codes> := nqp::hash('no_op', 0,
'const_i8', 1,
'const_i16', 2,
Expand Down Expand Up @@ -2941,7 +2945,8 @@ BEGIN {
'write_fhb', 541,
'replace', 542,
'newexception', 543,
'openpipe', 544);
'openpipe', 544,
'backtrace', 545);
MAST::Ops.WHO<@names> := nqp::list('no_op',
'const_i8',
'const_i16',
Expand Down Expand Up @@ -3486,5 +3491,6 @@ BEGIN {
'write_fhb',
'replace',
'newexception',
'openpipe');
'openpipe',
'backtrace');
}
68 changes: 67 additions & 1 deletion src/core/exceptions.c
Expand Up @@ -236,6 +236,72 @@ char * MVM_exception_backtrace_line(MVMThreadContext *tc, MVMFrame *cur_frame, M
return o;
}

/* Returns a list of hashes containing file, line, sub and annotations. */
MVMObject * MVM_exception_backtrace(MVMThreadContext *tc, MVMObject *ex_obj) {
MVMException *ex;
MVMFrame *cur_frame;
MVMObject *arr, *annotations, *row, *value;
MVMuint32 count = 0;
MVMString *k_file, *k_line, *k_sub, *k_anno;

if (IS_CONCRETE(ex_obj) && REPR(ex_obj)->ID == MVM_REPR_ID_MVMException)
ex = (MVMException *)ex_obj;
else
MVM_exception_throw_adhoc(tc, "Op 'backtrace' needs an exception object");

MVM_gc_root_temp_push(tc, (MVMCollectable **)&arr);
MVM_gc_root_temp_push(tc, (MVMCollectable **)&annotations);
MVM_gc_root_temp_push(tc, (MVMCollectable **)&row);
MVM_gc_root_temp_push(tc, (MVMCollectable **)&value);
MVM_gc_root_temp_push(tc, (MVMCollectable **)&k_file);
MVM_gc_root_temp_push(tc, (MVMCollectable **)&k_line);
MVM_gc_root_temp_push(tc, (MVMCollectable **)&k_sub);
MVM_gc_root_temp_push(tc, (MVMCollectable **)&k_anno);

k_file = MVM_string_ascii_decode_nt(tc, tc->instance->VMString, "file");
k_line = MVM_string_ascii_decode_nt(tc, tc->instance->VMString, "line");
k_sub = MVM_string_ascii_decode_nt(tc, tc->instance->VMString, "sub");
k_anno = MVM_string_ascii_decode_nt(tc, tc->instance->VMString, "annotations");

cur_frame = ex->body.origin;
arr = MVM_repr_alloc_init(tc, tc->instance->boot_types.BOOTArray);

while (cur_frame != NULL) {
MVMuint8 *cur_op = count ? cur_frame->return_address : cur_frame->throw_address;
MVMuint32 offset = cur_op - cur_frame->static_info->body.bytecode;
MVMBytecodeAnnotation *annot = MVM_bytecode_resolve_annotation(tc, &cur_frame->static_info->body, offset);
char *line_number = malloc(16);
snprintf(line_number, 16, "%d", annot ? annot->line_number + 1 : 1);

/* annotations hash will contain "file" and "line" */
annotations = MVM_repr_alloc_init(tc, tc->instance->boot_types.BOOTHash);

/* file */
value = MVM_repr_box_str(tc, MVM_hll_current(tc)->str_box_type,
cur_frame->static_info->body.cu->body.filename);
MVM_repr_bind_key_o(tc, annotations, k_file, value);

/* line */
value = (MVMObject *)MVM_string_ascii_decode_nt(tc, tc->instance->VMString, line_number);
value = MVM_repr_box_str(tc, MVM_hll_current(tc)->str_box_type, (MVMString *)value);
MVM_repr_bind_key_o(tc, annotations, k_line, value);
free(line_number);

/* row will contain "sub" and "annotations" */
row = MVM_repr_alloc_init(tc, tc->instance->boot_types.BOOTHash);
MVM_repr_bind_key_o(tc, row, k_sub, cur_frame->code_ref);
MVM_repr_bind_key_o(tc, row, k_anno, annotations);

MVM_repr_push_o(tc, arr, row);
cur_frame = cur_frame->caller;
count++;
}

MVM_gc_root_temp_pop_n(tc, 8);

return arr;
}

/* Returns the lines (backtrace) of an exception-object as an array. */
MVMObject * MVM_exception_backtrace_strings(MVMThreadContext *tc, MVMObject *ex_obj) {
MVMException *ex;
Expand All @@ -245,7 +311,7 @@ MVMObject * MVM_exception_backtrace_strings(MVMThreadContext *tc, MVMObject *ex_
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 throw an exception object");
MVM_exception_throw_adhoc(tc, "Op 'backtracestrings' needs an exception object");

cur_frame = ex->body.origin;
arr = MVM_repr_alloc_init(tc, tc->instance->boot_types.BOOTArray);
Expand Down
1 change: 1 addition & 0 deletions src/core/exceptions.h
Expand Up @@ -58,6 +58,7 @@ struct MVMActiveHandler {
};

/* Exception related functions. */
MVMObject * MVM_exception_backtrace(MVMThreadContext *tc, MVMObject *ex_obj);
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);
Expand Down
4 changes: 4 additions & 0 deletions src/core/interp.c
Expand Up @@ -3780,6 +3780,10 @@ void MVM_interp_run(MVMThreadContext *tc, void (*initial_invoke)(MVMThreadContex
goto NEXT;
OP(openpipe):
MVM_exception_throw_adhoc(tc, "openpipe NYI");
OP(backtrace):
GET_REG(cur_op, 0).o = MVM_exception_backtrace(tc, GET_REG(cur_op, 2).o);
cur_op += 4;
goto NEXT;
#if MVM_CGOTO
OP_CALL_EXTOP: {
/* Bounds checking? Never heard of that. */
Expand Down
2 changes: 1 addition & 1 deletion src/core/oplabels.h
Expand Up @@ -546,7 +546,7 @@ static const void * const LABELS[] = {
&&OP_replace,
&&OP_newexception,
&&OP_openpipe,
NULL,
&&OP_backtrace,
NULL,
NULL,
NULL,
Expand Down
1 change: 1 addition & 0 deletions src/core/oplist
Expand Up @@ -574,3 +574,4 @@ write_fhb r(obj) r(obj)
replace w(str) r(str) r(int64) r(int64) r(str)
newexception w(obj)
openpipe w(obj) r(str) r(str) r(obj) r(str)
backtrace w(obj) r(obj)
9 changes: 8 additions & 1 deletion src/core/ops.c
Expand Up @@ -3821,9 +3821,16 @@ static MVMOpInfo MVM_op_infos[] = {
5,
{ MVM_operand_write_reg | MVM_operand_obj, MVM_operand_read_reg | MVM_operand_str, MVM_operand_read_reg | MVM_operand_str, MVM_operand_read_reg | MVM_operand_obj, MVM_operand_read_reg | MVM_operand_str }
},
{
MVM_OP_backtrace,
"backtrace",
" ",
2,
{ MVM_operand_write_reg | MVM_operand_obj, MVM_operand_read_reg | MVM_operand_obj }
},
};

static unsigned short MVM_op_counts = 545;
static unsigned short MVM_op_counts = 546;

MVMOpInfo * MVM_op_get_op(unsigned short op) {
if (op >= MVM_op_counts)
Expand Down
1 change: 1 addition & 0 deletions src/core/ops.h
Expand Up @@ -546,6 +546,7 @@
#define MVM_OP_replace 542
#define MVM_OP_newexception 543
#define MVM_OP_openpipe 544
#define MVM_OP_backtrace 545

#define MVM_OP_EXT_BASE 1024
#define MVM_OP_EXT_CU_LIMIT 1024
Expand Down

0 comments on commit 58e6fae

Please sign in to comment.