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 }
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 }