Ticket #1741: macros.diff

File macros.diff, 14.2 KB (added by luben, 4 years ago)

patch

  • src/hash.c

     
    512512parrot_mark_hash_keys(PARROT_INTERP, ARGIN(Hash *hash)) 
    513513{ 
    514514    ASSERT_ARGS(parrot_mark_hash_keys) 
    515     const UINTVAL entries = hash->entries; 
    516     UINTVAL found = 0; 
    517     UINTVAL i; 
    518  
    519     HashBucket *bucket = hash->buckets; 
    520  
    521     for (i= 0; i <= hash->mask; ++i, ++bucket) { 
    522         if (bucket->key){ 
    523  
    524             PARROT_ASSERT(bucket->key); 
    525             Parrot_gc_mark_PObj_alive(interp, (PObj *)bucket->key); 
    526  
    527             if (++found >= entries) 
    528                 break; 
    529         } 
    530     } 
     515    parrot_hash_iterate(hash, 
     516        PARROT_ASSERT(_bucket->key); 
     517        Parrot_gc_mark_PObj_alive(interp, (PObj *)_bucket->key); 
     518    ); 
    531519} 
    532520 
    533521 
     
    545533parrot_mark_hash_values(PARROT_INTERP, ARGIN(Hash *hash)) 
    546534{ 
    547535    ASSERT_ARGS(parrot_mark_hash_values) 
    548     const UINTVAL entries = hash->entries; 
    549     UINTVAL found = 0; 
    550     UINTVAL i; 
    551  
    552     HashBucket *bucket = hash->buckets; 
    553  
    554     for (i= 0; i <= hash->mask; ++i, ++bucket) { 
    555         if (bucket->key){ 
    556  
    557             PARROT_ASSERT(bucket->value); 
    558             Parrot_gc_mark_PObj_alive(interp, (PObj *)bucket->value); 
    559  
    560             if (++found >= entries) 
    561                 break; 
    562         } 
    563     } 
     536    parrot_hash_iterate(hash, 
     537        PARROT_ASSERT(_bucket->value); 
     538        Parrot_gc_mark_PObj_alive(interp, (PObj *)_bucket->value); 
     539    ); 
    564540} 
    565541 
     542 
    566543/* 
    567544 
    568545=item C<static void parrot_mark_hash_both(PARROT_INTERP, Hash *hash)> 
     
    577554parrot_mark_hash_both(PARROT_INTERP, ARGIN(Hash *hash)) 
    578555{ 
    579556    ASSERT_ARGS(parrot_mark_hash_both) 
    580     const UINTVAL entries = hash->entries; 
    581     UINTVAL found = 0; 
    582     UINTVAL i; 
    583  
    584     HashBucket *bucket = hash->buckets; 
    585  
    586     for (i= 0; i <= hash->mask; ++i, ++bucket) { 
    587         if (bucket->key){ 
    588             PARROT_ASSERT(bucket->key); 
    589             Parrot_gc_mark_PObj_alive(interp, (PObj *)bucket->key); 
    590  
    591             PARROT_ASSERT(bucket->value); 
    592             Parrot_gc_mark_PObj_alive(interp, (PObj *)bucket->value); 
    593  
    594             if (++found >= entries) 
    595                 break; 
    596         } 
    597     } 
     557    parrot_hash_iterate(hash, 
     558        PARROT_ASSERT(_bucket->key); 
     559        Parrot_gc_mark_PObj_alive(interp, (PObj *)_bucket->key); 
     560        PARROT_ASSERT(_bucket->value); 
     561        Parrot_gc_mark_PObj_alive(interp, (PObj *)_bucket->value); 
     562    ); 
    598563} 
    599564 
    600565/* 
     
    714679    const size_t           entries    = hash->entries; 
    715680    size_t                 i; 
    716681 
    717     for (i = 0; i < entries; ++i) { 
    718         HashBucket * const b = hash->buckets + i; 
    719  
     682    parrot_hash_iterate(hash, 
    720683        switch (key_type) { 
    721684          case Hash_key_type_int: 
    722             VTABLE_push_integer(interp, info, (INTVAL)b->key); 
     685            VTABLE_push_integer(interp, info, (INTVAL)_bucket->key); 
    723686            break; 
    724687          case Hash_key_type_STRING: 
    725             VTABLE_push_string(interp, info, (STRING *)b->key); 
     688            VTABLE_push_string(interp, info, (STRING *)_bucket->key); 
    726689            break; 
    727690          case Hash_key_type_PMC: 
    728             VTABLE_push_pmc(interp, info, (PMC *)b->key); 
     691            VTABLE_push_pmc(interp, info, (PMC *)_bucket->key); 
    729692            break; 
    730693          default: 
    731694            Parrot_ex_throw_from_c_args(interp, NULL, 1, 
    732695                    "unimplemented key type"); 
    733696            break; 
    734697        } 
    735  
    736698        switch (entry_type) { 
    737699          case enum_hash_int: 
    738             VTABLE_push_integer(interp, info, (INTVAL)b->value); 
     700            VTABLE_push_integer(interp, info, (INTVAL)_bucket->value); 
    739701            break; 
    740702          case enum_hash_string: 
    741             VTABLE_push_string(interp, info, (STRING *)b->value); 
     703            VTABLE_push_string(interp, info, (STRING *)_bucket->value); 
    742704            break; 
    743705          case enum_hash_pmc: 
    744             VTABLE_push_pmc(interp, info, (PMC *)b->value); 
     706            VTABLE_push_pmc(interp, info, (PMC *)_bucket->value); 
    745707            break; 
    746708          default: 
    747709            Parrot_ex_throw_from_c_args(interp, NULL, 1, 
    748710                    "unimplemented value type"); 
    749711            break; 
    750712        } 
    751     } 
     713    ); 
    752714} 
    753715 
    754716 
     
    11211083parrot_chash_destroy(PARROT_INTERP, ARGMOD(Hash *hash)) 
    11221084{ 
    11231085    ASSERT_ARGS(parrot_chash_destroy) 
    1124     UINTVAL i; 
    1125  
    1126     for (i = 0; i <= hash->mask; ++i) { 
    1127         HashBucket *bucket = hash->bucket_indices[i]; 
    1128         while (bucket) { 
    1129             mem_gc_free(interp, bucket->key); 
    1130             mem_gc_free(interp, bucket->value); 
    1131             bucket = bucket->next; 
    1132         } 
    1133     } 
    1134  
     1086    parrot_hash_iterate(hash, 
     1087        mem_gc_free(interp, _bucket->key); 
     1088        mem_gc_free(interp, _bucket->value); 
     1089    ); 
    11351090    parrot_hash_destroy(interp, hash); 
    11361091} 
    11371092 
     
    14721427    ARGOUT(Hash *dest), int deep) 
    14731428{ 
    14741429    ASSERT_ARGS(parrot_hash_clone_prunable) 
    1475     UINTVAL entries = hash->entries; 
    1476     UINTVAL i; 
    14771430 
    1478     for (i = 0; i < entries; ++i) { 
     1431    parrot_hash_iterate(hash, 
    14791432        void         *valtmp; 
    1480         HashBucket   *b   = hash->buckets + i; 
    1481         void * const  key = b->key; 
     1433        void * const  key = _bucket->key; 
    14821434 
    14831435        switch (hash->entry_type) { 
    14841436          case enum_type_undef: 
    14851437          case enum_type_ptr: 
    14861438          case enum_type_INTVAL: 
    1487             valtmp = (void *)b->value; 
     1439            valtmp = (void *)_bucket->value; 
    14881440            break; 
    14891441 
    14901442          case enum_type_STRING: 
    1491             valtmp = b->value; 
     1443            valtmp = _bucket->value; 
    14921444            break; 
    14931445 
    14941446          case enum_type_PMC: 
    1495             if (PMC_IS_NULL((PMC *)b->value)) 
     1447            if (PMC_IS_NULL((PMC *)_bucket->value)) 
    14961448                valtmp = (void *)PMCNULL; 
    14971449            else 
    14981450                if (deep) 
    1499                     valtmp = (void *)VTABLE_clone(interp, (PMC*)b->value); 
     1451                    valtmp = (void *)VTABLE_clone(interp, (PMC*)_bucket->value); 
    15001452                else 
    1501                     valtmp = b->value; 
     1453                    valtmp = _bucket->value; 
    15021454            break; 
    15031455 
    15041456          default: 
     
    15061458            Parrot_ex_throw_from_c_args(interp, NULL, -1, 
    15071459                    "hash corruption: type = %d\n", hash->entry_type); 
    15081460        }; 
    1509  
    15101461        if (key) 
    15111462            parrot_hash_put(interp, dest, key, valtmp); 
    1512     } 
     1463    ); 
    15131464} 
    15141465 
    15151466/* 
  • src/pmc/lexinfo.pmc

     
    9999        if (Parrot_str_equal(INTERP, what, CONST_STRING(INTERP, "symbols"))) { 
    100100            PMC * const result    = Parrot_pmc_new(INTERP, enum_class_ResizableStringArray); 
    101101            const Hash *hash      = (Hash *)SELF.get_pointer(); 
    102             const UINTVAL entries = hash->entries; 
    103102 
    104             UINTVAL found   = 0; 
    105             INTVAL  i; 
     103            parrot_hash_iterate(hash, 
     104                PARROT_ASSERT(_bucket->key); 
     105                VTABLE_push_string(INTERP, result, (STRING *)_bucket->key); 
     106            ); 
    106107 
    107             for (i = hash->mask; i >= 0; --i) { 
    108                 HashBucket *bucket = hash->bucket_indices[i]; 
    109                 while (bucket) { 
    110                     if (++found > entries) 
    111                         Parrot_ex_throw_from_c_args(INTERP, NULL, 1, 
    112                             "Detected corruption at LexInfo hash %p entries %d", 
    113                             hash, (int)entries); 
    114  
    115                     PARROT_ASSERT(bucket->key); 
    116                     VTABLE_push_string(INTERP, result, (STRING *)bucket->key); 
    117  
    118                     bucket = bucket->next; 
    119                 } 
    120             } 
    121  
    122108            return result; 
    123109        } 
    124110        else 
  • src/pmc/callcontext.pmc

     
    378378mark_hash(PARROT_INTERP, ARGIN(Hash *h)) 
    379379{ 
    380380    ASSERT_ARGS(mark_hash) 
    381     INTVAL  i; 
    382  
    383     for (i = h->mask; i >= 0; --i) { 
    384         HashBucket *b = h->bucket_indices[i]; 
    385  
    386         while (b) { 
    387             Parrot_gc_mark_STRING_alive(interp, (STRING *)b->key); 
    388             mark_cell(interp, (Pcc_cell *)b->value); 
    389             b = b->next; 
    390         } 
    391     } 
     381    parrot_hash_iterate(h, 
     382        Parrot_gc_mark_STRING_alive(interp, (STRING *)_bucket->key); 
     383        mark_cell(interp, (Pcc_cell *)_bucket->value); 
     384    ); 
    392385} 
    393386 
    394387PARROT_CAN_RETURN_NULL 
     
    402395 
    403396    /* yes, this *looks* risky, but it's a Parrot STRING hash internally */ 
    404397    if (hash && hash->entries) { 
    405         UINTVAL i, j = 0; 
     398        UINTVAL j = 0; 
    406399        PMC *result = Parrot_pmc_new_init_int(interp, enum_class_FixedStringArray, hash->entries); 
    407  
    408         for (i = 0; i <= hash->mask; ++i) { 
    409             HashBucket *b = hash->bucket_indices[i]; 
    410  
    411             while (b) { 
    412                 VTABLE_set_string_keyed_int(interp, result, 
    413                     j++, (STRING *)b->key); 
    414                 b = b->next; 
    415             } 
    416         } 
    417  
     400        parrot_hash_iterate(hash, 
     401            VTABLE_set_string_keyed_int(interp, result, j++, (STRING *)_bucket->key); 
     402        ); 
    418403        return result; 
    419404    } 
    420405 
     
    604589        GET_ATTR_hash(INTERP, SELF, hash); 
    605590 
    606591        if (hash) { 
    607             UINTVAL i; 
    608  
    609             for (i = 0; i <= hash->mask; ++i) { 
    610                 HashBucket *b = hash->bucket_indices[i]; 
    611  
    612                 while (b) { 
    613                     FREE_CELL(INTERP, (Pcc_cell *)b->value); 
    614                     b = b->next; 
    615                 } 
    616             } 
    617  
     592            parrot_hash_iterate(hash, 
     593               FREE_CELL(INTERP, (Pcc_cell *)_bucket->value); 
     594            ); 
    618595            parrot_hash_destroy(INTERP, hash); 
    619596            SET_ATTR_hash(INTERP, SELF, NULL); 
    620597        } 
     
    642619        } 
    643620 
    644621        if (hash) { 
    645             UINTVAL i; 
    646  
    647             for (i = 0; i <= hash->mask; ++i) { 
    648                 HashBucket *b = hash->bucket_indices[i]; 
    649  
    650                 while (b) { 
    651                     FREE_CELL(INTERP, (Pcc_cell *)b->value); 
    652                     b = b->next; 
    653                 } 
    654             } 
    655  
     622            parrot_hash_iterate(hash, 
     623                FREE_CELL(INTERP, (Pcc_cell *)_bucket->value); 
     624            ); 
    656625            parrot_hash_destroy(INTERP, hash); 
    657626        } 
    658627 
  • src/pmc/hashiterator.pmc

     
    7878advance_to_next(PARROT_INTERP, ARGMOD(PMC *self)) 
    7979{ 
    8080    ASSERT_ARGS(advance_to_next) 
    81  
    8281    Parrot_HashIterator_attributes * const attrs  = PARROT_HASHITERATOR(self); 
    83     HashBucket                            *bucket = attrs->bucket; 
    84  
    85     /* Try to advance current bucket */ 
    86     if (bucket) 
    87         bucket = bucket->next; 
    88  
    89     while (!bucket) { 
    90         /* If there is no more buckets */ 
    91         if (attrs->pos == attrs->total_buckets) 
    92             break; 
    93  
    94         bucket = attrs->parrot_hash->bucket_indices[attrs->pos++]; 
    95     } 
    96     attrs->bucket = bucket; 
     82    parrot_hash_iterator(attrs->parrot_hash, attrs->bucket, attrs->pos) 
    9783    --attrs->elements; 
    98  
    9984    return; 
    10085} 
    10186 
  • src/packfile.c

     
    34713471    if (!hash) 
    34723472        return; 
    34733473 
    3474     for (i = 0; i <= hash->mask; ++i) { 
    3475         HashBucket *bucket = hash->bucket_indices[i]; 
    3476  
    3477         while (bucket) { 
    3478             PackFile_ConstTable * const table      = 
    3479                 (PackFile_ConstTable *)bucket->key; 
    3480             PackFile_Constant * const orig_consts = table->constants; 
    3481             PackFile_Constant * const consts      = 
    3482                 (PackFile_Constant *) bucket->value; 
    3483             INTVAL j; 
    3484  
    3485             mem_gc_free(interp, consts); 
    3486             bucket = bucket->next; 
    3487         } 
    3488     } 
    3489  
     3474    parrot_hash_iterate(hash, 
     3475        PackFile_ConstTable * const table     = (PackFile_ConstTable *)_bucket->key; 
     3476        PackFile_Constant * const orig_consts = table->constants; 
     3477        PackFile_Constant * const consts      = (PackFile_Constant *) _bucket->value; 
     3478        mem_gc_free(interp, consts); 
     3479    ); 
    34903480    parrot_hash_destroy(interp, hash); 
    34913481} 
    34923482 
  • include/parrot/hash.h

     
    7878    hash_hash_key_fn hash_val; 
    7979}; 
    8080 
     81/* Utility macros - use them, do not reinvent the weel */ 
     82#define parrot_hash_iterate(_hash, _code)                                   \ 
     83{                                                                           \ 
     84    INTVAL _loc;                                                            \ 
     85    for (_loc = (_hash)->mask; _loc >= 0; --_loc) {                         \ 
     86        HashBucket *_bucket = (_hash)->bucket_indices[_loc];                \ 
     87        while (_bucket) {                                                   \ 
     88            _code                                                           \ 
     89            _bucket = _bucket->next;                                        \ 
     90        }                                                                   \ 
     91    }                                                                       \ 
     92} 
     93 
     94#define parrot_hash_iterator(_hash,_bucket,_loc)                            \ 
     95{                                                                           \ 
     96    /* Try to advance current bucket */                                     \ 
     97    if ((_bucket))                                                          \ 
     98        (_bucket) = (_bucket)->next;                                        \ 
     99    while (!(_bucket)) {                                                    \ 
     100        /* If there is no more buckets */                                   \ 
     101        if ((_loc) == (INTVAL)(_hash)->mask+1)                              \ 
     102            break;                                                          \ 
     103        (_bucket) = (_hash)->bucket_indices[_loc++];                        \ 
     104    }                                                                       \ 
     105} 
     106 
     107 
    81108typedef void (*value_free)(ARGFREE(void *)); 
    82109 
    83110/* To avoid creating OrderedHashItem PMC we reuse FixedPMCArray PMC */