Ticket #212: count_eh.patch

File count_eh.patch, 6.0 KB (added by rg, 13 years ago)
  • src/scheduler.c

     
    559559 
    560560/* 
    561561 
     562=item C<void Parrot_cx_count_handlers_local> 
     563 
     564Count the number of active handlers of a particular type from the 
     565context's list of handlers. 
     566 
     567=cut 
     568 
     569*/ 
     570 
     571PARROT_EXPORT 
     572INTVAL 
     573Parrot_cx_count_handlers_local(PARROT_INTERP, ARGIN(STRING *handler_type)) 
     574{ 
     575    ASSERT_ARGS(Parrot_cx_count_handlers_local) 
     576    PMC *handlers = CONTEXT(interp)->handlers; 
     577    INTVAL elements; 
     578 
     579    if (PMC_IS_NULL(handlers)) 
     580        return 0; 
     581 
     582    elements = VTABLE_elements(interp, handlers); 
     583 
     584    if (STRING_IS_NULL(handler_type) || STRING_IS_EMPTY(handler_type)) 
     585        return elements; 
     586 
     587    /* Loop from newest handler to oldest handler. */ 
     588    { 
     589        STRING      *exception_str = CONST_STRING(interp, "exception"); 
     590        STRING      *event_str     = CONST_STRING(interp, "event"); 
     591        STRING      *handler_str   = CONST_STRING(interp, "ExceptionHandler"); 
     592        INTVAL       count = 0; 
     593        INTVAL       index; 
     594        typedef enum { Hunknown,  Hexception, Hevent } Htype; 
     595 
     596        const Htype htype = 
     597            (string_equal(interp, handler_type, exception_str) == 0) ? 
     598            Hexception : 
     599            (string_equal(interp, handler_type, event_str) == 0) ? 
     600                Hevent : 
     601                Hunknown; 
     602        STRING * const handler_name = (htype == Hexception) ? 
     603            handler_str : (STRING *) NULL; 
     604 
     605        for (index = 0; index < elements; ++index) { 
     606            PMC *handler = VTABLE_get_pmc_keyed_int(interp, handlers, index); 
     607            if (!PMC_IS_NULL(handler)) { 
     608                switch (htype) { 
     609                case Hexception: 
     610                        if (VTABLE_isa(interp, handler, handler_name)) 
     611                            count++; 
     612                        break; 
     613                    case Hevent: 
     614                        if (handler->vtable->base_type == enum_class_EventHandler) 
     615                            count++; 
     616                        break; 
     617                    default: 
     618                        break; 
     619                } 
     620            } 
     621        } 
     622        return count; 
     623    } 
     624} 
     625 
     626 
     627/* 
     628 
    562629=item C<void Parrot_cx_add_handler> 
    563630 
    564631Add a task handler to scheduler's list of handlers. 
     
    625692        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION, 
    626693            "Scheduler was not initialized for this interpreter.\n"); 
    627694 
    628     Parrot_PCCINVOKE(interp, interp->scheduler, CONST_STRING(interp, "count_handlers"), "S->I", handler_type, count); 
     695    Parrot_PCCINVOKE(interp, interp->scheduler, CONST_STRING(interp, "count_handlers"), "S->I", handler_type, &count); 
    629696 
    630697    return count; 
    631698} 
  • src/ops/core.ops

     
    866866} 
    867867 
    868868inline op count_eh(out INT) { 
    869     $1 = Parrot_cx_count_handlers_typed(interp, 
     869    $1 = Parrot_cx_count_handlers_local(interp, 
    870870            string_from_cstring(interp, "exception", 9)); 
    871871} 
    872872 
  • src/pmc/scheduler.pmc

     
    513513    METHOD count_handlers(STRING *type :optional, INTVAL have_type :opt_flag) { 
    514514        /* avoid uninitialized value warning */ 
    515515        PMC   *handlers = NULL; 
    516         INTVAL elements = VTABLE_elements(INTERP, handlers); 
     516        INTVAL elements; 
    517517        INTVAL count    = 0; 
    518518        INTVAL index; 
    519519 
    520520        GET_ATTR_handlers(INTERP, SELF, handlers); 
     521        elements = VTABLE_elements(INTERP, handlers); 
    521522 
    522523        if (!have_type) 
    523524            RETURN(INTVAL elements); 
  • include/parrot/scheduler.h

     
    3636        __attribute__nonnull__(2); 
    3737 
    3838PARROT_EXPORT 
     39INTVAL Parrot_cx_count_handlers_local(PARROT_INTERP, 
     40    ARGIN(STRING *handler_type)) 
     41        __attribute__nonnull__(1) 
     42        __attribute__nonnull__(2); 
     43 
     44PARROT_EXPORT 
    3945INTVAL Parrot_cx_count_handlers_typed(PARROT_INTERP, 
    4046    ARGIN(STRING *handler_type)) 
    4147        __attribute__nonnull__(1) 
     
    171177#define ASSERT_ARGS_Parrot_cx_broadcast_message __attribute__unused__ int _ASSERT_ARGS_CHECK = \ 
    172178       PARROT_ASSERT_ARG(interp) \ 
    173179    || PARROT_ASSERT_ARG(messagetype) 
     180#define ASSERT_ARGS_Parrot_cx_count_handlers_local \ 
     181     __attribute__unused__ int _ASSERT_ARGS_CHECK = \ 
     182       PARROT_ASSERT_ARG(interp) \ 
     183    || PARROT_ASSERT_ARG(handler_type) 
    174184#define ASSERT_ARGS_Parrot_cx_count_handlers_typed \ 
    175185     __attribute__unused__ int _ASSERT_ARGS_CHECK = \ 
    176186       PARROT_ASSERT_ARG(interp) \ 
  • t/pmc/exception.t

     
    66use warnings; 
    77use lib qw( . lib ../lib ../../lib ); 
    88use Test::More; 
    9 use Parrot::Test tests => 30; 
     9use Parrot::Test tests => 31; 
    1010 
    1111=head1 NAME 
    1212 
     
    715715no segfault 
    716716OUTPUT 
    717717 
     718pir_output_is( <<'CODE', <<'OUTPUT', "count_eh" ); 
     719.sub main :main 
     720    $I0 = count_eh 
     721    if $I0 == 0 goto right_number1 
     722        print "not " 
     723    right_number1: 
     724    print "ok 1\n" 
     725    push_eh _handler1 
     726    push_eh _handler2 
     727    print "ok 2\n" 
     728    $I1 = count_eh 
     729    if $I1 == 2 goto right_number2 
     730        print "not " 
     731    right_number2: 
     732    print "ok 3\n" 
     733    pop_eh 
     734    pop_eh 
     735    print "ok 4\n" 
     736    $I2 = count_eh 
     737    if $I2 == 0 goto right_number3 
     738        print "not " 
     739    right_number3: 
     740    print "ok 5\n" 
     741    end 
     742_handler1: 
     743    print "first handler\n" 
     744    end 
     745_handler2: 
     746    print "second handler\n" 
     747    end 
     748.end 
     749CODE 
     750ok 1 
     751ok 2 
     752ok 3 
     753ok 4 
     754ok 5 
     755OUTPUT 
     756 
    718757# Local Variables: 
    719758#   mode: cperl 
    720759#   cperl-indent-level: 4