[svn:parrot] r38519 - in trunk/src: . ops

whiteknight at svn.parrot.org whiteknight at svn.parrot.org
Thu May 7 00:25:35 UTC 2009


Author: whiteknight
Date: Thu May  7 00:25:34 2009
New Revision: 38519
URL: https://trac.parrot.org/parrot/changeset/38519

Log:
A basic fix for TT #595. Throw or rethrow on a null PMC or a non-exception PMC should cause a fatal error, instead of random and ungraceful results like we used to have. Probably not an ideal fix, but a basis for later improvements. NotFound++ for ideas

Modified:
   trunk/src/exceptions.c
   trunk/src/ops/core.ops

Modified: trunk/src/exceptions.c
==============================================================================
--- trunk/src/exceptions.c	Wed May  6 23:48:36 2009	(r38518)
+++ trunk/src/exceptions.c	Thu May  7 00:25:34 2009	(r38519)
@@ -464,8 +464,6 @@
 Parrot_ex_rethrow_from_op(PARROT_INTERP, ARGIN(PMC *exception))
 {
     ASSERT_ARGS(Parrot_ex_rethrow_from_op)
-    if (exception->vtable->base_type != enum_class_Exception)
-        PANIC(interp, "Illegal rethrow");
 
     Parrot_ex_mark_unhandled(interp, exception);
 

Modified: trunk/src/ops/core.ops
==============================================================================
--- trunk/src/ops/core.ops	Wed May  6 23:48:36 2009	(r38518)
+++ trunk/src/ops/core.ops	Thu May  7 00:25:34 2009	(r38519)
@@ -866,27 +866,41 @@
 }
 
 inline op throw(invar PMC) :flow {
+    PMC * except = $1;
     opcode_t *dest;
     opcode_t *const ret    = expr NEXT();
     PMC            *resume = new_ret_continuation_pmc(interp, ret);
+    if(PMC_IS_NULL(except) || except->vtable->base_type != enum_class_Exception)
+        except = Parrot_ex_build_exception(interp, EXCEPT_fatal, 1, NULL);
     /*
      * We might return here after handling the exception, so mark the
      * current context appropriately.
      */
     Parrot_context_ref(interp, CONTEXT(interp));
-    VTABLE_set_attr_str(interp, $1, Parrot_str_new_constant(interp, "resume"), resume);
-    dest = Parrot_ex_throw_from_op(interp, $1, ret);
+    VTABLE_set_attr_str(interp, except, Parrot_str_new_constant(interp, "resume"), resume);
+    dest = Parrot_ex_throw_from_op(interp, except, ret);
     goto ADDRESS(dest);
 }
 
 inline op throw(invar PMC, invar PMC) :flow {
-    opcode_t * const dest = Parrot_ex_throw_from_op(interp, $1,
+    opcode_t * dest;
+    PMC * except = $1;
+    if(PMC_IS_NULL(except) || except->vtable->base_type != enum_class_Exception)
+        except = Parrot_ex_build_exception(interp, EXCEPT_fatal, 1, NULL);
+    dest = Parrot_ex_throw_from_op(interp, $1,
                                 VTABLE_get_pointer(interp, $2));
     goto ADDRESS(dest);
 }
 
 inline op rethrow(invar PMC) :flow {
-    opcode_t * const dest = Parrot_ex_rethrow_from_op(interp, $1);
+    opcode_t * dest;
+    if(PMC_IS_NULL($1) || $1->vtable->base_type != enum_class_Exception) {
+        opcode_t * const ret = expr NEXT();
+        PMC * except = Parrot_ex_build_exception(interp, EXCEPT_fatal, 1, NULL);
+        dest = Parrot_ex_throw_from_op(interp, except, ret);
+        goto ADDRESS(dest);
+    }
+    dest = Parrot_ex_rethrow_from_op(interp, $1);
     goto ADDRESS(dest);
 }
 


More information about the parrot-commits mailing list