Skip to content

Instantly share code, notes, and snippets.

@jnthn
Created May 18, 2009 21:17
Show Gist options
  • Save jnthn/113752 to your computer and use it in GitHub Desktop.
Save jnthn/113752 to your computer and use it in GitHub Desktop.
Index: src/exceptions.c
===================================================================
--- src/exceptions.c (revision 38911)
+++ src/exceptions.c (working copy)
@@ -372,6 +372,10 @@
PDB_backtrace(interp);
}
+ /* Note the thrower.
+ * XXX TT#596 - pass in current context instead when we have context PMCs. */
+ VTABLE_set_attr_str(interp, exception, CONST_STRING(interp, "thrower"), CONTEXT(interp)->current_cont);
+
/* it's a C exception handler */
if (PObj_get_FLAGS(handler) & SUB_FLAG_C_HANDLER) {
Parrot_runloop * const jump_point =
Index: src/pmc/exception.pmc
===================================================================
--- src/pmc/exception.pmc (revision 38911)
+++ src/pmc/exception.pmc (working copy)
@@ -66,6 +66,7 @@
ATTR INTVAL handled; /* Whether the exception has been handled. */
ATTR PMC *handler_iter; /* An iterator of handlers (for rethrow). */
ATTR Parrot_Context *handler_ctx; /* A stored context for handler iterator. */
+ ATTR Parrot_Context *thrower; /* The position we were at when thrown. */
/*
@@ -655,6 +656,14 @@
else if (Parrot_str_equal(INTERP, name, CONST_STRING(INTERP, "handler_iter"))) {
SET_ATTR_handler_iter(interp, SELF, value);
}
+ else if (Parrot_str_equal(INTERP, name, CONST_STRING(INTERP, "thrower"))) {
+ /* Ensure it's a ret cont, and extract the from_ctx.
+ * XXX TT#596 - when we have Context PMCs, just take and set that. */
+ if (VTABLE_isa(interp, value, CONST_STRING(interp, "Continuation"))) {
+ Parrot_Context *ctx = PMC_cont(value)->from_ctx;
+ SET_ATTR_thrower(interp, SELF, ctx);
+ }
+ }
else {
/* If unknown attribute name, throw an exception. */
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_ATTRIB_NOT_FOUND,
@@ -748,13 +757,24 @@
METHOD backtrace() {
PMC *result = pmc_new(interp, enum_class_ResizablePMCArray);
PMC *resume;
+ Parrot_Context *cur_ctx;
+ Parrot_cont *cont;
/* Get starting context, then loop over them. */
GET_ATTR_resume(interp, SELF, resume);
if (!PMC_IS_NULL(resume)) {
- Parrot_cont *cont = PMC_cont(resume);
- Parrot_Context *cur_ctx = cont->to_ctx;
+ /* We have a resume continuation, so we can get the address from
+ * that. */
+ cont = PMC_cont(resume);
+ cur_ctx = cont->to_ctx;
+ }
+ else {
+ /* No return continuation. Assuming we're being called */
+ cont = NULL;
+ GET_ATTR_thrower(interp, SELF, cur_ctx);
+ }
+ {
while (cur_ctx) {
PMC *frame = pmc_new(interp, enum_class_Hash);
PMC *annotations = NULL;
@@ -774,7 +794,7 @@
if (sub->seg->annotations) {
PackFile_ByteCode *seg = sub->seg;
- opcode_t *pc = cur_ctx == cont->to_ctx
+ opcode_t *pc = cont && cur_ctx == cont->to_ctx
? cont->address
: cur_ctx->current_pc;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment