Ticket #1341: diff

File diff, 4.3 KB (added by plobsing, 5 years ago)
  • src/pmc_freeze.c

     
    264264/* preallocate freeze image for aggregates with this estimation */ 
    265265#define FREEZE_BYTES_PER_ITEM 9 
    266266 
     267/* macros/constants to handle packing/unpacking of PMC IDs and flags 
     268 * the 2 LSBs are used for flags, all other bits are used for PMC ID 
     269 */ 
     270#define PackID_new(id, flags)       (((UINTVAL)(id) * 4) | ((UINTVAL)(flags) & 3)) 
     271#define PackID_get_PMCID(id)        ((UINTVAL)(id) / 4) 
     272#define PackID_set_PMCID(lv, id)    (lv) = PackID_new((id), PackID_get_FLAGS(lv)) 
     273#define PackID_get_FLAGS(id)        ((UINTVAL)(id) & 3) 
     274#define PackID_set_FLAGS(lv, flags) (lv) = PackID_new(PackID_get_PMCID(lv), (flags)) 
     275 
     276enum { 
     277    enum_PackID_normal     = 0, 
     278    enum_PackID_seen       = 1, 
     279    enum_PackID_prev_type  = 2, 
     280    enum_PackID_extra_info = 3 
     281}; 
     282 
    267283/* 
    268284 
    269285=head2 C<opcode_t> IO Functions 
     
    666682 
    667683    if (PMC_IS_NULL(pmc)) { 
    668684        /* NULL + seen bit */ 
    669         VTABLE_push_pmc(interp, io, (PMC*) 1); 
     685        VTABLE_push_pmc(interp, io, (PMC*)PackID_new(NULL, enum_PackID_seen)); 
    670686        return; 
    671687    } 
    672688 
     
    675691    if (PObj_is_object_TEST(pmc)) 
    676692        type = enum_class_Object; 
    677693 
    678     /* TODO: get rid of these magic numbers; they look like pointer tags */ 
    679694    if (seen) { 
    680695        if (info->extra_flags) { 
    681             id |= 3; 
     696            PackID_set_FLAGS(id, enum_PackID_extra_info); 
    682697            VTABLE_push_pmc(interp, io, (PMC *)id); 
    683698            VTABLE_push_integer(interp, io, info->extra_flags); 
    684699            return; 
    685700        } 
    686701 
    687         id |= 1;         /* mark bit 0 if this PMC is known */ 
     702        PackID_set_FLAGS(id, enum_PackID_seen); 
    688703    } 
    689704    else if (type == info->last_type) 
    690         id |= 2;         /* mark bit 1 and don't write type */ 
     705        PackID_set_FLAGS(id, enum_PackID_prev_type); 
    691706 
    692707    VTABLE_push_pmc(interp, io, (PMC*)id); 
    693708 
    694     if (! (id & 3)) {    /* else write type */ 
     709    if (PackID_get_FLAGS(id) == enum_PackID_normal) { 
     710        /* write type */ 
    695711        VTABLE_push_integer(interp, io, type); 
    696712        info->last_type = type; 
    697713    } 
     
    733749 
    734750    info->extra_flags     = EXTRA_IS_NULL; 
    735751 
    736     /* pmc has extra data */ 
    737     if (((UINTVAL) n & 3) == 3) { 
     752    switch (PackID_get_FLAGS(n)) { 
     753      case enum_PackID_extra_info: 
     754        /* pmc has extra data */ 
    738755        info->extra_flags = VTABLE_shift_integer(interp, io); 
    739     } 
    740  
    741     /* seen PMCs have bit 0 set */ 
    742     else if ((UINTVAL) n & 1) { 
     756        break; 
     757      case enum_PackID_seen: 
    743758        seen = 1; 
    744     } 
    745  
    746     /* prev PMC was same type */ 
    747     else if ((UINTVAL) n & 2) { 
     759        break; 
     760      case enum_PackID_prev_type: 
     761        /* prev PMC was same type */ 
    748762        *type = info->last_type; 
    749     } 
     763        break; 
     764      default: 
     765        /* type follows */ 
     766        { 
     767            *type           = VTABLE_shift_integer(interp, io); 
     768            info->last_type = *type; 
    750769 
    751     /* type follows */ 
    752     else { 
    753         *type           = VTABLE_shift_integer(interp, io); 
    754         info->last_type = *type; 
     770            if (*type <= 0) 
     771                Parrot_ex_throw_from_c_args(interp, NULL, 1, 
     772                    "Unknown PMC type to thaw %d", (int) *type); 
    755773 
    756         if (*type <= 0) 
    757             Parrot_ex_throw_from_c_args(interp, NULL, 1, 
    758                 "Unknown PMC type to thaw %d", (int) *type); 
    759  
    760         /* that ought to be a class */ 
    761         if (*type >= interp->n_vtable_max || !interp->vtables[*type]) 
    762             *type = enum_class_Class; 
     774            /* that ought to be a class */ 
     775            if (*type >= interp->n_vtable_max || !interp->vtables[*type]) 
     776                *type = enum_class_Class; 
     777        } 
     778        break; 
    763779    } 
    764780 
    765781    *id = (UINTVAL)n; 
     
    861877    INTVAL  type           = 0; 
    862878    int     must_have_seen = thaw_pmc(interp, info, &id, &type); 
    863879 
    864     id >>= 2; 
     880    id = PackID_get_PMCID(id); 
    865881 
    866882    if (!id) { 
    867883        /* got a NULL PMC */ 
     
    950966    } 
    951967 
    952968    /* next id to freeze */ 
    953     info->id += 4; 
     969    info->id++; 
     970    *id = PackID_new(info->id, enum_PackID_normal); 
    954971 
    955     *id = info->id; 
    956  
    957972    parrot_hash_put(interp, 
    958973            (Hash *)VTABLE_get_pointer(interp, info->seen), pmc, (void *)*id); 
    959974