Author: tene
Date: Thu Aug 7 23:50:53 2008
New Revision: 30123
Modified:
trunk/src/ops/core.ops
trunk/src/pmc/exception.pmc
trunk/src/sub.c
trunk/t/op/exceptions.t
Log:
Add a return continuation attribute to the Exception pmc and fill it in the
throw opcode.
Modified: trunk/src/ops/core.ops
==============================================================================
--- trunk/src/ops/core.ops (original)
+++ trunk/src/ops/core.ops Thu Aug 7 23:50:53 2008
@@ -816,7 +816,9 @@
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);
}
Modified: trunk/src/pmc/exception.pmc
==============================================================================
--- trunk/src/pmc/exception.pmc (original)
+++ trunk/src/pmc/exception.pmc Thu Aug 7 23:50:53 2008
@@ -57,6 +57,7 @@
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 INTVAL severity; /* The severity of the exception. */
ATTR INTVAL type; /* The type of the exception. */
ATTR INTVAL exit_code; /* The exit code of the exception. */
@@ -93,6 +94,7 @@
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 @@
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 @@
else if (string_equal(INTERP, name, CONST_STRING(INTERP, "payload"))
== 0) {
GET_ATTR_payload(interp, SELF, value);
}
+ else if (string_equal(INTERP, name, CONST_STRING(INTERP, "retcont"))
== 0) {
+ GET_ATTR_retcont(interp, SELF, value);
+ }
else if (string_equal(INTERP, name, CONST_STRING(INTERP,
"stacktrace")) == 0) {
GET_ATTR_stacktrace(interp, SELF, value);
}
@@ -579,6 +586,9 @@
else if (string_equal(INTERP, name, CONST_STRING(INTERP, "payload"))
== 0) {
SET_ATTR_payload(interp, SELF, value);
}
+ else if (string_equal(INTERP, name, CONST_STRING(INTERP, "retcont"))
== 0) {
+ SET_ATTR_retcont(interp, SELF, value);
+ }
else if (string_equal(INTERP, name, CONST_STRING(INTERP,
"stacktrace")) == 0) {
SET_ATTR_stacktrace(interp, SELF, value);
}
Modified: trunk/src/sub.c
==============================================================================
--- trunk/src/sub.c (original)
+++ trunk/src/sub.c Thu Aug 7 23:50:53 2008
@@ -191,7 +191,7 @@
Parrot_cont * const cc = mem_allocate_typed(Parrot_cont);
cc->to_ctx = CONTEXT(interp);
- cc->from_ctx = NULL; /* filled in during a call */
+ cc->from_ctx = CONTEXT(interp); /* filled in during a call */
cc->dynamic_state = NULL;
cc->runloop_id = 0;
cc->seg = interp->code;
Modified: trunk/t/op/exceptions.t
==============================================================================
--- trunk/t/op/exceptions.t (original)
+++ trunk/t/op/exceptions.t Thu Aug 7 23:50:53 2008
@@ -6,7 +6,7 @@
use warnings;
use lib qw( . lib ../lib ../../lib );
use Test::More;
-use Parrot::Test tests => 29;
+use Parrot::Test tests => 30;
=head1 NAME
@@ -608,6 +608,29 @@
after compile
OUTPUT
+pir_output_is( <<'CODE', <<'OUTPUT', "Resumable exceptions" );
+.sub main :main
+ push_eh _handler
+ new $P1, 'Exception'
+ say 'Before throwing'
+ throw $P1
+ say 'After throwing'
+ end
+_handler:
+ .local pmc e
+ .local string s
+ .local pmc c
+ .get_results (e, s)
+ say 'In the exception handler'
+ c = e['retcont']
+ c()
+.end
+CODE
+Before throwing
+In the exception handler
+After throwing
+OUTPUT
+
# Local Variables:
# mode: cperl
# cperl-indent-level: 4