# New Ticket Created by Stephen Weeks
# Please include the string: [perl #57610]
# in the subject line of all future correspondence about this issue.
# URL: http://rt.perl.org/rt3/Ticket/Display.html?id=57610
pdd23:
Exception handlers can resume execution immediately after the
throw opcode by invoking the resume continuation which is stored
in the exception object. That continuation must be invoked with no
parameters; in other words, throw never returns a value.
Exception.pmc has the following attributes:
ATTR INTVALid; /* The task ID in the scheduler. */
ATTR FLOATVAL birthtime;/* The creation time stamp of the exception. */
ATTR STRING *message; /* The exception message. */
ATTR PMC *payload; /* The payload for the exception. */
ATTR INTVALseverity; /* The severity of the exception. */
ATTR INTVALtype; /* The type of the exception. */
ATTR INTVALexit_code;/* The exit code of the exception. */
ATTR PMC *stacktrace; /* The stacktrace of an exception. */
ATTR INTVALhandled; /* 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.
*/
None of these is a continuation.
The throw opcode passes the address of the next opcode to
Parrot_ex_throw_from_op, but Petfo only uses it in:
address= VTABLE_invoke(interp, handler, dest);
and the ExceptionHandler PMC's invoke() does not use that parameter
at all.
This first draft of a patch adds an attribute to the exception pmc to
hold a return continuation, creates a retcontinuation pmc in the throw
opcode and assigns it to that attribute, and patches
new_ret_continuation to initialize the new continuation's from_ctx
attribute in the same way new_continuation does.
This last item is there to fix a segfault. I don't understand parrot's
continuations well enough yet to have any idea why they were different,
so I just guessed. I don't know if it's wrong, but it doesn't seem to
fail any extra tests.
Added a simple test case.
From 21bc85c3ae1d749187b250bd898028d63a92891f Mon Sep 17 00:00:00 2001
From: Stephen Weeks [EMAIL PROTECTED]
Date: Tue, 5 Aug 2008 04:55:30 -0600
Subject: [PATCH] Add a return continuation attribute to the Exception pmc and
fill it in the throw opcode.
---
src/ops/core.ops |4 +++-
src/pmc/exception.pmc | 10 ++
src/sub.c |2 +-
t/op/exceptions.t | 25 -
4 files changed, 38 insertions(+), 3 deletions(-)
diff --git a/src/ops/core.ops b/src/ops/core.ops
index 25f8775..da821f3 100644
--- a/src/ops/core.ops
+++ b/src/ops/core.ops
@@ -816,7 +816,9 @@ inline op pop_eh() {
inline op throw(invar PMC) :flow {
opcode_t * const ret = expr NEXT();
-opcode_t * const dest = Parrot_ex_throw_from_op(interp, $1, ret);
+Parrot_cont * resume = new_ret_continuation_pmc(interp,ret);
+
VTABLE_set_attr_str(interp,$1,string_from_literal(interp,retcont),resume);
+opcode_t * const dest = Parrot_ex_throw_from_op(interp, $1, resume);
goto ADDRESS(dest);
}
diff --git a/src/pmc/exception.pmc b/src/pmc/exception.pmc
index 15c7056..2a09882 100644
--- a/src/pmc/exception.pmc
+++ b/src/pmc/exception.pmc
@@ -57,6 +57,7 @@ pmclass Exception {
ATTR FLOATVAL birthtime;/* The creation time stamp of the exception.
*/
ATTR STRING *message; /* The exception message. */
ATTR PMC *payload; /* The payload for the exception. */
+ATTR PMC *retcont; /* The return continuation for the exception.
*/
ATTR INTVALseverity; /* The severity of the exception. */
ATTR INTVALtype; /* The type of the exception. */
ATTR INTVALexit_code;/* The exit code of the exception. */
@@ -93,6 +94,7 @@ Initializes the exception with default values.
core_struct-handled= 0;
core_struct-message= CONST_STRING(interp, );
core_struct-payload= PMCNULL;
+core_struct-retcont= PMCNULL;
core_struct-stacktrace = PMCNULL;
core_struct-handler_iter = PMCNULL;
}
@@ -113,6 +115,8 @@ Mark any active exception data as live.
pobject_lives(interp, (PObj *)core_struct-message);
if (core_struct-payload)
pobject_lives(interp, (PObj *)core_struct-payload);
+if (core_struct-retcont)
+pobject_lives(interp, (PObj *)core_struct-retcont);
if (core_struct-stacktrace)
pobject_lives(interp, (PObj *)core_struct-stacktrace);
if (core_struct-handler_iter)
@@ -530,6 +534,9 @@ Retrieve an attribute value for the exception object.
else if (string_equal(INTERP, name, CONST_STRING(INTERP, payload))
== 0) {
GET_ATTR_payload(interp, SELF, value);
}
+else if (string_equal(INTERP, name,