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

Reply via email to