Ticket #1473: tt1473.patch

File tt1473.patch, 5.6 KB (added by whiteknight, 4 years ago)

proposed fix

  • src/pmc/pmcproxy.pmc

     
    318318*/ 
    319319 
    320320    VTABLE INTVAL does(STRING *role_name) { 
    321         Parrot_Class_attributes *_class  = PARROT_CLASS(SELF); 
    322         INTVAL                   id      = _class->id; 
    323         PMC                     *proxied = Parrot_pmc_new(interp, id); 
    324  
    325         if (VTABLE_does(interp, proxied, role_name)) 
     321        Parrot_Class_attributes * const attrs = PARROT_CLASS(SELF); 
     322        const INTVAL id = attrs->id; 
     323        const INTVAL type_does = Parrot_pmc_type_does(INTERP, role_name, id); 
     324        if (type_does) 
    326325            return 1; 
    327  
    328         return VTABLE_isa(interp, proxied, role_name); 
    329  
     326        return VTABLE_isa(INTERP, SELF, role_name); 
    330327    } 
    331328 
    332329/* 
  • src/pmc/default.pmc

     
    280280    return prop; 
    281281} 
    282282 
    283 /* 
    284  
    285 =item C<static INTVAL does_isa(PARROT_INTERP, const STRING *method, const STRING 
    286 *what)> 
    287  
    288 Compares C<*method> and C<*what>. 
    289 Returns true (1) if B<method> is found in B<what>, false (0) otherwise. 
    290  
    291 =cut 
    292  
    293 */ 
    294  
    295 static INTVAL 
    296 does_isa(PARROT_INTERP, ARGIN(const STRING *method), ARGIN(const STRING *what)) 
    297 { 
    298     const INTVAL length = Parrot_str_byte_length(interp, what); 
    299     INTVAL  pos    = 0; 
    300  
    301     do { 
    302         INTVAL len; 
    303         INTVAL idx = Parrot_str_find_index(interp, what, method, (INTVAL)pos); 
    304  
    305         if (idx < 0) 
    306             return 0; 
    307  
    308         pos = idx; 
    309  
    310         if (pos >= length) 
    311             return 0; 
    312  
    313         len = Parrot_str_byte_length(interp, method); 
    314  
    315         if (pos && Parrot_str_indexed(interp, what, pos - 1) != 32) { 
    316             pos += len; 
    317             continue; 
    318         } 
    319  
    320         if (pos + len < length && Parrot_str_indexed(interp, what, pos + len) != 32) { 
    321             pos += len; 
    322             continue; 
    323         } 
    324  
    325         return 1; 
    326     } while (1); 
    327 } 
    328  
    329283pmclass default abstract { 
    330284 
    331285/* 
     
    919873*/ 
    920874 
    921875    VTABLE INTVAL does(STRING *_interface) { 
    922         return does_isa(INTERP, _interface, SELF->vtable->provides_str); 
     876        return Parrot_pmc_type_does(INTERP, _interface, SELF->vtable->base_type); 
    923877    } 
    924878 
    925879/* 
  • src/pmc.c

     
    963963 
    964964/* 
    965965 
     966=item C<INTVAL Parrot_pmc_type_does(PARROT_INTERP, STRING *role, INTVAL type)> 
     967 
     968Checks to see if PMCs of the given type does the given role. Checks 
     969C<<vtable->provides_str>> to find a match. 
     970Returns true (1) if B<role> is found, false (0) otherwise. 
     971 
     972=cut 
     973 
     974*/ 
     975 
     976INTVAL 
     977Parrot_pmc_type_does(PARROT_INTERP, ARGIN(STRING *role), INTVAL type) 
     978{ 
     979    INTVAL pos = 0; 
     980    STRING * const what = interp->vtables[type]->provides_str; 
     981    INTVAL length = Parrot_str_byte_length(interp, what); 
     982 
     983    do { 
     984        INTVAL len; 
     985        INTVAL idx = Parrot_str_find_index(interp, what, role, (INTVAL)pos); 
     986 
     987        if (idx < 0) 
     988            return 0; 
     989 
     990        pos = idx; 
     991 
     992        if (pos >= length) 
     993            return 0; 
     994 
     995        len = Parrot_str_byte_length(interp, role); 
     996 
     997        if (pos && Parrot_str_indexed(interp, what, pos - 1) != 32) { 
     998            pos += len; 
     999            continue; 
     1000        } 
     1001 
     1002        if (pos + len < length && Parrot_str_indexed(interp, what, pos + len) != 32) { 
     1003            pos += len; 
     1004            continue; 
     1005        } 
     1006 
     1007        return 1; 
     1008    } while (1); 
     1009} 
     1010 
     1011/* 
     1012 
    9661013=back 
    9671014 
    9681015=head1 SEE ALSO 
  • include/parrot/pmc.h

     
    148148PMC * Parrot_pmc_new_temporary(PARROT_INTERP, INTVAL base_type) 
    149149        __attribute__nonnull__(1); 
    150150 
     151INTVAL Parrot_pmc_type_does(PARROT_INTERP, 
     152    ARGIN(STRING *method), 
     153    INTVAL type) 
     154        __attribute__nonnull__(1) 
     155        __attribute__nonnull__(2); 
     156 
    151157#define ASSERT_ARGS_Parrot_pmc_create_mro __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 
    152158       PARROT_ASSERT_ARG(interp)) 
    153159#define ASSERT_ARGS_Parrot_pmc_destroy __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 
     
    203209       PARROT_ASSERT_ARG(interp)) 
    204210#define ASSERT_ARGS_Parrot_pmc_new_temporary __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 
    205211       PARROT_ASSERT_ARG(interp)) 
     212#define ASSERT_ARGS_Parrot_pmc_type_does __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 
     213       PARROT_ASSERT_ARG(interp) \ 
     214    , PARROT_ASSERT_ARG(method)) 
    206215/* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */ 
    207216/* HEADERIZER END: src/pmc.c */ 
    208217 
  • t/pmc/handle.t

     
    2020.sub main :main 
    2121    .include 'test_more.pir' 
    2222 
    23     plan(1) 
     23    plan(2) 
     24    'test_create'() 
     25    'test_does_tt_1473'() 
     26.end 
     27 
     28.sub 'test_create' 
    2429    push_eh cant_instantiate 
    2530    $P0 = new 'Handle' 
    26     print "not " 
     31    ok(0, "Can instantiate an abstract type") 
     32    pop_eh 
     33    goto create_end 
    2734  cant_instantiate: 
    28     say "ok 1" 
     35    ok(1, "Cannot instantiate an abstract type") 
     36    pop_eh 
     37  create_end: 
    2938.end 
    3039 
     40.sub 'test_does_tt_1473' 
     41    push_eh cant_do_does 
     42    $P0 = get_class 'Handle' 
     43    $I0 = does $P0, 'Handle' 
     44    ok($I0, "Handle does Handle") 
     45    goto does_end 
     46  cant_do_does: 
     47    ok(0, "Does throws an exception") 
     48  does_end: 
     49    pop_eh 
     50.end 
     51 
     52 
    3153# Local Variables: 
    3254#   mode: pir 
    3355#   fill-column: 100