PN_SIZE potion_type_size(Potion *P, const struct PNObject *ptr) { int sz = 0; switch (((struct PNFwd *)ptr)->fwd) { case POTION_COPIED: case POTION_FWD: sz = ((struct PNFwd *)ptr)->siz; goto done; } if (ptr->vt > PN_TUSER) { sz = sizeof(struct PNObject) + (((struct PNVtable *)PN_VTABLE(ptr->vt))->ivlen * sizeof(PN)); goto done; } switch (ptr->vt) { case PN_TNUMBER: sz = sizeof(struct PNDecimal); break; case PN_TSTRING: sz = sizeof(struct PNString) + PN_STR_LEN(ptr) + 1; break; case PN_TCLOSURE: sz = sizeof(struct PNClosure) + (PN_CLOSURE(ptr)->extra * sizeof(PN)); break; case PN_TTUPLE: sz = sizeof(struct PNTuple) + (sizeof(PN) * ((struct PNTuple *)ptr)->len); break; case PN_TSTATE: sz = sizeof(Potion); break; case PN_TFILE: sz = sizeof(struct PNFile); break; case PN_TVTABLE: sz = sizeof(struct PNVtable); break; case PN_TSOURCE: // TODO: look up ast size (see core/ast.c) sz = sizeof(struct PNSource) + (3 * sizeof(PN)); break; case PN_TBYTES: sz = sizeof(struct PNBytes) + ((struct PNBytes *)ptr)->siz; break; case PN_TPROTO: sz = sizeof(struct PNProto); break; case PN_TTABLE: sz = sizeof(struct PNTable) + kh_mem(PN, ptr); break; case PN_TSTRINGS: sz = sizeof(struct PNTable) + kh_mem(str, ptr); break; case PN_TFLEX: sz = sizeof(PNFlex) + ((PNFlex *)ptr)->siz; break; case PN_TCONT: sz = sizeof(struct PNCont) + (((struct PNCont *)ptr)->len * sizeof(PN)); break; case PN_TUSER: sz = sizeof(struct PNData) + ((struct PNData *)ptr)->siz; break; } done: if (sz < sizeof(struct PNFwd)) sz = sizeof(struct PNFwd); return PN_ALIGN(sz, 8); // force 64-bit alignment }
void *potion_mark_major(Potion *P, const struct PNObject *ptr) { struct PNMemory *M = P->mem; PN_SIZE i; PN_SIZE sz = 16; switch (((struct PNFwd *)ptr)->fwd) { case POTION_COPIED: case POTION_FWD: GC_MAJOR_UPDATE(((struct PNFwd *)ptr)->ptr); goto done; } if (ptr->vt > PN_TUSER) { GC_MAJOR_UPDATE(PN_VTABLE(ptr->vt)); int ivars = ((struct PNVtable *)PN_VTABLE(ptr->vt))->ivlen; for (i = 0; i < ivars; i++) GC_MAJOR_UPDATE(((struct PNObject *)ptr)->ivars[i]); goto done; } switch (ptr->vt) { case PN_TWEAK: GC_MAJOR_UPDATE(((struct PNWeakRef *)ptr)->data); break; case PN_TCLOSURE: GC_MAJOR_UPDATE(((struct PNClosure *)ptr)->sig); for (i = 0; i < ((struct PNClosure *)ptr)->extra; i++) GC_MAJOR_UPDATE(((struct PNClosure *)ptr)->data[i]); break; case PN_TTUPLE: { struct PNTuple * volatile t = (struct PNTuple *)potion_fwd((PN)ptr); for (i = 0; i < t->len; i++) GC_MAJOR_UPDATE(t->set[i]); } break; case PN_TSTATE: GC_MAJOR_UPDATE(((Potion *)ptr)->strings); GC_MAJOR_UPDATE(((Potion *)ptr)->lobby); GC_MAJOR_UPDATE(((Potion *)ptr)->vts); GC_MAJOR_UPDATE(((Potion *)ptr)->source); GC_MAJOR_UPDATE(((Potion *)ptr)->input); GC_MAJOR_UPDATE(((Potion *)ptr)->pbuf); GC_MAJOR_UPDATE(((Potion *)ptr)->unclosed); GC_MAJOR_UPDATE(((Potion *)ptr)->call); GC_MAJOR_UPDATE(((Potion *)ptr)->callset); break; case PN_TFILE: GC_MAJOR_UPDATE(((struct PNFile *)ptr)->path); break; case PN_TVTABLE: GC_MAJOR_UPDATE(((struct PNVtable *)ptr)->parent); GC_MAJOR_UPDATE(((struct PNVtable *)ptr)->ivars); GC_MAJOR_UPDATE(((struct PNVtable *)ptr)->methods); GC_MAJOR_UPDATE(((struct PNVtable *)ptr)->ctor); GC_MAJOR_UPDATE(((struct PNVtable *)ptr)->call); GC_MAJOR_UPDATE(((struct PNVtable *)ptr)->callset); break; case PN_TSOURCE: GC_MAJOR_UPDATE(((struct PNSource *)ptr)->a[0]); GC_MAJOR_UPDATE(((struct PNSource *)ptr)->a[1]); GC_MAJOR_UPDATE(((struct PNSource *)ptr)->a[2]); break; case PN_TPROTO: GC_MAJOR_UPDATE(((struct PNProto *)ptr)->source); GC_MAJOR_UPDATE(((struct PNProto *)ptr)->sig); GC_MAJOR_UPDATE(((struct PNProto *)ptr)->stack); GC_MAJOR_UPDATE(((struct PNProto *)ptr)->paths); GC_MAJOR_UPDATE(((struct PNProto *)ptr)->locals); GC_MAJOR_UPDATE(((struct PNProto *)ptr)->upvals); GC_MAJOR_UPDATE(((struct PNProto *)ptr)->values); GC_MAJOR_UPDATE(((struct PNProto *)ptr)->protos); GC_MAJOR_UPDATE(((struct PNProto *)ptr)->tree); GC_MAJOR_UPDATE(((struct PNProto *)ptr)->asmb); break; case PN_TTABLE: GC_MAJOR_UPDATE_TABLE(PN, (struct PNTable *)potion_fwd((PN)ptr), 1); break; case PN_TFLEX: for (i = 0; i < PN_FLEX_SIZE(ptr); i++) GC_MAJOR_UPDATE(PN_FLEX_AT(ptr, i)); break; case PN_TCONT: GC_KEEP(ptr); pngc_mark_array(P, (_PN *)((struct PNCont *)ptr)->stack + 3, ((struct PNCont *)ptr)->len - 3, 2); break; } done: sz = potion_type_size(P, ptr); return (void *)((char *)ptr + sz); }
PN_SIZE potion_type_size(Potion *P, const struct PNObject *ptr) { int sz = 0; switch (((struct PNFwd *)ptr)->fwd) { case POTION_COPIED: case POTION_FWD: sz = ((struct PNFwd *)ptr)->siz; goto done; } if (ptr->vt < PN_TNIL) goto err; if (ptr->vt > PN_TUSER) { if (P->vts && ptr->vt < P->vts->len && PN_VTABLE(ptr->vt) && PN_TYPECHECK(ptr->vt)) { sz = sizeof(struct PNObject) + (((struct PNVtable *)PN_VTABLE(ptr->vt))->ivlen * sizeof(PN)); //sz = potion_send((PN)ptr, PN_size); //cannot use bind with POTION_COPIED objs during GC! } else { err: if (P->flags & (DEBUG_VERBOSE #ifdef DEBUG |DEBUG_GC #endif )) fprintf(stderr, "** Invalid User Object 0x%lx vt: 0x%lx\n", (unsigned long)ptr, (unsigned long)ptr->vt); return 0; } goto done; } switch (ptr->vt) { case PN_TNUMBER: sz = sizeof(struct PNDecimal); break; case PN_TSTRING: sz = sizeof(struct PNString) + PN_STR_LEN(ptr) + 1; break; case PN_TCLOSURE: sz = sizeof(struct PNClosure) + (PN_CLOSURE(ptr)->extra * sizeof(PN)); break; case PN_TTUPLE: sz = sizeof(struct PNTuple) + (sizeof(PN) * ((struct PNTuple *)ptr)->alloc); break; case PN_TSTATE: sz = sizeof(Potion); break; case PN_TFILE: sz = sizeof(struct PNFile); break; case PN_TVTABLE: sz = sizeof(struct PNVtable); break; case PN_TSOURCE: sz = sizeof(struct PNSource); break; case PN_TBYTES: sz = sizeof(struct PNBytes) + ((struct PNBytes *)ptr)->siz; break; case PN_TPROTO: sz = sizeof(struct PNProto); break; case PN_TTABLE: sz = sizeof(struct PNTable) + kh_mem(PN, ptr); break; case PN_TLICK: sz = sizeof(struct PNLick); break; case PN_TSTRINGS: sz = sizeof(struct PNTable) + kh_mem(str, ptr); break; case PN_TFLEX: sz = sizeof(PNFlex) + ((PNFlex *)ptr)->siz; break; case PN_TCONT: sz = sizeof(struct PNCont) + (((struct PNCont *)ptr)->len * sizeof(PN)); break; case PN_TUSER: sz = sizeof(struct PNData) + ((struct PNData *)ptr)->siz; break; } done: if (sz < sizeof(struct PNFwd)) sz = sizeof(struct PNFwd); return PN_ALIGN(sz, 8); // force 64-bit alignment }