예제 #1
0
파일: gc.c 프로젝트: adamsanderson/potion
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
}
예제 #2
0
파일: gc.c 프로젝트: adamsanderson/potion
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);
}
예제 #3
0
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
}