char * MVM_exception_backtrace_line(MVMThreadContext *tc, MVMFrame *cur_frame, MVMuint16 not_top) { MVMString *filename = cur_frame->static_info->body.cu->body.filename; MVMString *name = cur_frame->static_info->body.name; /* XXX TODO: make the caller pass in a char ** and a length pointer so * we can update it if necessary, and the caller can cache it. */ char *o = malloc(1024); MVMuint8 *cur_op = !not_top ? (*tc->interp_cur_op) : cur_frame->return_address; MVMuint32 offset = cur_op - cur_frame->static_info->body.bytecode; MVMuint32 instr = MVM_bytecode_offset_to_instr_idx(tc, cur_frame->static_info, offset); MVMBytecodeAnnotation *annot = MVM_bytecode_resolve_annotation(tc, &cur_frame->static_info->body, offset); MVMuint32 line_number = annot ? annot->line_number + 1 : 1; MVMuint16 string_heap_index = annot ? annot->filename_string_heap_index : 0; char *tmp1 = annot && string_heap_index < cur_frame->static_info->body.cu->body.num_strings ? MVM_string_utf8_encode(tc, cur_frame->static_info->body.cu->body.strings[string_heap_index], NULL) : NULL; sprintf(o, " %s %s:%u (%s:%s:%u)", not_top ? "from" : " at", tmp1 ? tmp1 : "<unknown>", line_number, filename ? (char *) MVM_string_utf8_encode(tc, filename, NULL) : "<ephemeral file>", name ? (char *) MVM_string_utf8_encode(tc, name, NULL) : "<anonymous frame>", instr ); if (tmp1) free(tmp1); if (annot) free(annot); return o; }
/* Dumps a backtrace relative to the current frame to stderr. */ static void dump_backtrace(MVMThreadContext *tc) { MVMFrame *cur_frame = tc->cur_frame; while (cur_frame != NULL) { fprintf(stderr, " in %s\n", MVM_string_utf8_encode(tc, cur_frame->static_info->name, NULL)); cur_frame = cur_frame->caller; } }
char * MVM_exception_backtrace_line(MVMThreadContext *tc, MVMFrame *cur_frame, MVMuint16 not_top) { MVMString *filename = cur_frame->static_info->body.cu->body.filename; MVMString *name = cur_frame->static_info->body.name; /* XXX TODO: make the caller pass in a char ** and a length pointer so * we can update it if necessary, and the caller can cache it. */ char *o = malloc(1024); MVMuint8 *cur_op = not_top ? cur_frame->return_address : cur_frame->throw_address; MVMuint32 offset = cur_op - cur_frame->effective_bytecode; MVMuint32 instr = MVM_bytecode_offset_to_instr_idx(tc, cur_frame->static_info, offset); MVMBytecodeAnnotation *annot = MVM_bytecode_resolve_annotation(tc, &cur_frame->static_info->body, offset > 0 ? offset - 1 : 0); MVMuint32 line_number = annot ? annot->line_number : 1; MVMuint16 string_heap_index = annot ? annot->filename_string_heap_index : 0; char *tmp1 = annot && string_heap_index < cur_frame->static_info->body.cu->body.num_strings ? MVM_string_utf8_encode(tc, cur_frame->static_info->body.cu->body.strings[string_heap_index], NULL) : NULL; /* We may be mid-instruction if exception was thrown at an unfortunate * point; try to cope with that. */ if (instr == MVM_BC_ILLEGAL_OFFSET && offset >= 2) instr = MVM_bytecode_offset_to_instr_idx(tc, cur_frame->static_info, offset - 2); snprintf(o, 1024, " %s %s:%u (%s:%s:%u)", not_top ? "from" : " at", tmp1 ? tmp1 : "<unknown>", line_number, filename ? (char *) MVM_string_utf8_encode(tc, filename, NULL) : "<ephemeral file>", name ? (char *) MVM_string_utf8_encode(tc, name, NULL) : "<anonymous frame>", instr ); if (tmp1) free(tmp1); if (annot) free(annot); return o; }
void MVM_string_print(MVMThreadContext *tc, MVMString *a) { MVMuint8 *utf8_encoded; MVMuint64 utf8_encoded_length; if (!IS_CONCRETE((MVMObject *)a)) { MVM_exception_throw_adhoc(tc, "print needs a concrete string"); } /* XXX send a buffer of substrings of size 100 or something? */ utf8_encoded = MVM_string_utf8_encode(tc, a, &utf8_encoded_length); fwrite(utf8_encoded, 1, utf8_encoded_length, stdout); free(utf8_encoded); }