Author: julianalbo
Date: Sun Jan 25 11:20:43 2009
New Revision: 36004

Modified:
   trunk/include/parrot/scheduler.h
   trunk/src/ops/core.ops
   trunk/src/pmc/scheduler.pmc
   trunk/src/scheduler.c
   trunk/t/pmc/exception.t

Log:
fix count_eh opcode and add test for it, TT #212 rg++

Modified: trunk/include/parrot/scheduler.h
==============================================================================
--- trunk/include/parrot/scheduler.h    (original)
+++ trunk/include/parrot/scheduler.h    Sun Jan 25 11:20:43 2009
@@ -36,6 +36,12 @@
         __attribute__nonnull__(2);
 
 PARROT_EXPORT
+INTVAL Parrot_cx_count_handlers_local(PARROT_INTERP,
+    ARGIN(STRING *handler_type))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
 INTVAL Parrot_cx_count_handlers_typed(PARROT_INTERP,
     ARGIN(STRING *handler_type))
         __attribute__nonnull__(1)
@@ -171,6 +177,10 @@
 #define ASSERT_ARGS_Parrot_cx_broadcast_message __attribute__unused__ int 
_ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(messagetype)
+#define ASSERT_ARGS_Parrot_cx_count_handlers_local \
+     __attribute__unused__ int _ASSERT_ARGS_CHECK = \
+       PARROT_ASSERT_ARG(interp) \
+    || PARROT_ASSERT_ARG(handler_type)
 #define ASSERT_ARGS_Parrot_cx_count_handlers_typed \
      __attribute__unused__ int _ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \

Modified: trunk/src/ops/core.ops
==============================================================================
--- trunk/src/ops/core.ops      (original)
+++ trunk/src/ops/core.ops      Sun Jan 25 11:20:43 2009
@@ -866,7 +866,7 @@
 }
 
 inline op count_eh(out INT) {
-    $1 = Parrot_cx_count_handlers_typed(interp,
+    $1 = Parrot_cx_count_handlers_local(interp,
             string_from_cstring(interp, "exception", 9));
 }
 

Modified: trunk/src/pmc/scheduler.pmc
==============================================================================
--- trunk/src/pmc/scheduler.pmc (original)
+++ trunk/src/pmc/scheduler.pmc Sun Jan 25 11:20:43 2009
@@ -513,11 +513,12 @@
     METHOD count_handlers(STRING *type :optional, INTVAL have_type :opt_flag) {
         /* avoid uninitialized value warning */
         PMC   *handlers = NULL;
-        INTVAL elements = VTABLE_elements(INTERP, handlers);
+        INTVAL elements;
         INTVAL count    = 0;
         INTVAL index;
 
         GET_ATTR_handlers(INTERP, SELF, handlers);
+        elements = VTABLE_elements(INTERP, handlers);
 
         if (!have_type)
             RETURN(INTVAL elements);

Modified: trunk/src/scheduler.c
==============================================================================
--- trunk/src/scheduler.c       (original)
+++ trunk/src/scheduler.c       Sun Jan 25 11:20:43 2009
@@ -559,6 +559,73 @@
 
 /*
 
+=item C<INTVAL Parrot_cx_count_handlers_local>
+
+Count the number of active handlers of a particular type from the
+context's list of handlers.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+INTVAL
+Parrot_cx_count_handlers_local(PARROT_INTERP, ARGIN(STRING *handler_type))
+{
+    ASSERT_ARGS(Parrot_cx_count_handlers_local)
+    PMC *handlers = CONTEXT(interp)->handlers;
+    INTVAL elements;
+
+    if (PMC_IS_NULL(handlers))
+        return 0;
+
+    elements = VTABLE_elements(interp, handlers);
+
+    if (STRING_IS_NULL(handler_type) || STRING_IS_EMPTY(handler_type))
+        return elements;
+
+    /* Loop from newest handler to oldest handler. */
+    {
+        STRING      *exception_str = CONST_STRING(interp, "exception");
+        STRING      *event_str     = CONST_STRING(interp, "event");
+        STRING      *handler_str   = CONST_STRING(interp, "ExceptionHandler");
+        INTVAL       count = 0;
+        INTVAL       index;
+        typedef enum { Hunknown,  Hexception, Hevent } Htype;
+
+        const Htype htype =
+            (string_equal(interp, handler_type, exception_str) == 0) ?
+            Hexception :
+            (string_equal(interp, handler_type, event_str) == 0) ?
+                Hevent :
+                Hunknown;
+        STRING * const handler_name = (htype == Hexception) ?
+            handler_str : (STRING *) NULL;
+
+        for (index = 0; index < elements; ++index) {
+            PMC *handler = VTABLE_get_pmc_keyed_int(interp, handlers, index);
+            if (!PMC_IS_NULL(handler)) {
+                switch (htype) {
+                case Hexception:
+                        if (VTABLE_isa(interp, handler, handler_name))
+                            count++;
+                        break;
+                    case Hevent:
+                        if (handler->vtable->base_type == 
enum_class_EventHandler)
+                            count++;
+                        break;
+                    default:
+                        break;
+                }
+            }
+        }
+        return count;
+    }
+}
+
+
+/*
+
 =item C<void Parrot_cx_add_handler>
 
 Add a task handler to scheduler's list of handlers.
@@ -625,7 +692,7 @@
         Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
             "Scheduler was not initialized for this interpreter.\n");
 
-    Parrot_PCCINVOKE(interp, interp->scheduler, CONST_STRING(interp, 
"count_handlers"), "S->I", handler_type, count);
+    Parrot_PCCINVOKE(interp, interp->scheduler, CONST_STRING(interp, 
"count_handlers"), "S->I", handler_type, &count);
 
     return count;
 }

Modified: trunk/t/pmc/exception.t
==============================================================================
--- trunk/t/pmc/exception.t     (original)
+++ trunk/t/pmc/exception.t     Sun Jan 25 11:20:43 2009
@@ -6,7 +6,7 @@
 use warnings;
 use lib qw( . lib ../lib ../../lib );
 use Test::More;
-use Parrot::Test tests => 30;
+use Parrot::Test tests => 31;
 
 =head1 NAME
 
@@ -715,6 +715,45 @@
 no segfault
 OUTPUT
 
+pir_output_is( <<'CODE', <<'OUTPUT', "count_eh" );
+.sub main :main
+    $I0 = count_eh
+    if $I0 == 0 goto right_number1
+        print "not "
+    right_number1:
+    print "ok 1\n"
+    push_eh _handler1
+    push_eh _handler2
+    print "ok 2\n"
+    $I1 = count_eh
+    if $I1 == 2 goto right_number2
+        print "not "
+    right_number2:
+    print "ok 3\n"
+    pop_eh
+    pop_eh
+    print "ok 4\n"
+    $I2 = count_eh
+    if $I2 == 0 goto right_number3
+        print "not "
+    right_number3:
+    print "ok 5\n"
+    end
+_handler1:
+    print "first handler\n"
+    end
+_handler2:
+    print "second handler\n"
+    end
+.end
+CODE
+ok 1
+ok 2
+ok 3
+ok 4
+ok 5
+OUTPUT
+
 # Local Variables:
 #   mode: cperl
 #   cperl-indent-level: 4

Reply via email to