///\return string of the sig tuple. "arg1=o,arg2=o" PN potion_sig_string(Potion *P, PN cl, PN sig) { PN out = potion_byte_str(P, ""); if (PN_IS_TUPLE(sig)) { int nextdef = 0; struct PNTuple * volatile t = ((struct PNTuple *)potion_fwd(sig)); if (t->len != 0) { PN_SIZE i, comma=0; for (i = 0; i < t->len; i++) { PN v = (PN)t->set[i]; if (PN_IS_NUM(v)) { // currently types are still encoded as NUM, TODO: support VTABLE also int c = PN_INT(v); comma=0; if (c == '.') // is end pn_printf(P, out, "."); else if (c == '|') // is optional pn_printf(P, out, "|"); else if (c == ':') { nextdef = 1; pn_printf(P, out, ":"); // is default } else { if (comma++) pn_printf(P, out, ","); if (nextdef) { nextdef = 0; pn_printf(P, out, "="); potion_bytes_obj_string(P, out, v); } else pn_printf(P, out, "=%c", c); } } else { if (comma++) pn_printf(P, out, ","); if (nextdef) { nextdef = 0; pn_printf(P, out, "="); } potion_bytes_obj_string(P, out, v); }}}} return PN_STR_B(out); }
static PN_SIZE pngc_mark_array(Potion *P, register _PN *x, register long n, int forward) { _PN v; PN_SIZE i = 0; struct PNMemory *M = P->mem; while (n--) { v = *x; if (IS_GC_PROTECTED(v) || IN_BIRTH_REGION(v) || IN_OLDER_REGION(v)) { v = potion_fwd(v); switch (forward) { case 0: // count only if (!IS_GC_PROTECTED(v) && IN_BIRTH_REGION(v) && HAS_REAL_TYPE(v)) i++; break; case 1: // minor if (!IS_GC_PROTECTED(v) && IN_BIRTH_REGION(v) && HAS_REAL_TYPE(v)) { GC_FORWARD(x, v); i++; } break; case 2: // major if (!IS_GC_PROTECTED(v) && (IN_BIRTH_REGION(v) || IN_OLDER_REGION(v)) && HAS_REAL_TYPE(v)) { GC_FORWARD(x, v); i++; } break; } } x++; } return i; }
static inline char *potion_type_name(Potion *P, PN obj) { obj = potion_fwd(obj); return PN_IS_PTR(obj) ? AS_STR(potion_send(PN_VTABLE(PN_TYPE(obj)), PN_string)) : PN_IS_NIL(obj) ? "nil" : PN_IS_NUM(obj) ? "Number" : "Boolean"; }
ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS static PN_SIZE pngc_mark_array(Potion *P, register _PN *x, register long n, int type) { _PN v; PN_SIZE i = 0; struct PNMemory *M = P->mem; while (n--) { v = *x; if (IS_GC_PROTECTED(v) || IN_BIRTH_REGION(v) || IN_OLDER_REGION(v)) { v = potion_fwd(v); switch (type) { case 0: // count only if (!IS_GC_PROTECTED(v) && IN_BIRTH_REGION(v) && HAS_REAL_TYPE(v)) { i++; DBG_Gv(P,"GC mark count only %p %6x\n", x, PN_TYPE(*x)); } break; case 1: // minor if (!IS_GC_PROTECTED(v) && IN_BIRTH_REGION(v) && HAS_REAL_TYPE(v)) { GC_FORWARD(x, v); i++; DBG_Gv(P,"GC mark minor %p -> 0x%lx %6x\n", x, v, PN_TYPE(*x)); } break; case 2: // major if (!IS_GC_PROTECTED(v) && (IN_BIRTH_REGION(v) || IN_OLDER_REGION(v)) && HAS_REAL_TYPE(v)) { GC_FORWARD(x, v); i++; DBG_Gv(P,"GC mark major %p -> 0x%lx %6x\n", x, v, PN_TYPE(*x)); } break; } } x++; } return i; }
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); }