Esempio n. 1
0
void potion_test_allocated(CuTest *T) {
  struct PNMemory *M = P->mem;
  void *prev = NULL;
  void *scanptr = (void *)((char *)M->birth_lo + PN_ALIGN(sizeof(struct PNMemory), 8));
  while ((PN)scanptr < (PN)M->birth_cur) {
    if (((struct PNFwd *)scanptr)->fwd != POTION_FWD && ((struct PNFwd *)scanptr)->fwd != POTION_COPIED) {
      if (((struct PNObject *)scanptr)->vt > PN_TUSER) {
	vPN(Object) o = (struct PNObject *)scanptr;
	fprintf(stderr, "error: scanning heap from %p to %p\n",
		M->birth_lo, M->birth_cur);
	fprintf(stderr, "%p in %s region\n", scanptr,
		IS_GC_PROTECTED(scanptr) ? "protected"
		: IN_BIRTH_REGION(scanptr) ? "birth"
		: IN_OLDER_REGION(scanptr) ? "older"
		: "gc");
	fprintf(stderr, "%p { uniq:0x%08x vt:0x%08x ivars[0]:0x%08lx type:0x%x}\n",
		scanptr, o->uniq, o->vt, o->ivars[0],
		potion_type((PN)scanptr));
	fprintf(stderr, "prev %p: size=%d, type:0x%x (%s)\n",
		prev, potion_type_size(P, prev),
		potion_type((PN)prev), AS_STR(PN_VTABLE(PN_TYPE((PN)prev))));
#ifdef DEBUG
	//potion_dump_stack(P);
#endif
      }
      CuAssert(T, "wrong type for allocated object", ((struct PNObject *)scanptr)->vt <= PN_TUSER);
    }
    prev = scanptr;
    scanptr = (void *)((char *)scanptr + potion_type_size(P, scanptr));
    CuAssert(T, "allocated object goes beyond GC pointer", (PN)scanptr <= (PN)M->birth_cur);
  }
}
Esempio n. 2
0
void potion_dump(Potion *P, PN data) {
  PN pd = potion_send(data, PN_string);
  PN pt = potion_send(PN_VTABLE(PN_TYPE(data)), PN_string);
  char *d = pd ? PN_STR_PTR(pd) : "nil";
  char *t = pt ? PN_STR_PTR(pt) : "NilKind";
  printf("%s (%s)\n", d, t);
}
Esempio n. 3
0
File: file.c Progetto: perl11/potion
/**\memberof PNFile
 \c "write" a binary representation of obj to the file handle.
 \param obj PNString, PNBytes, PNInteger (long or double), PNBoolean (char 0 or 1)
 \return PNInteger written bytes or PN_NIL */
PN potion_file_write(Potion *P, PN cl, pn_file self, PN obj) {
  long len = 0;
  char *ptr = NULL;
  union { double d; long l; char c; } tmp;
  //TODO: maybe extract ptr+len to seperate function
  if (!PN_IS_PTR(obj)) {
    if (!obj) return PN_NIL; //silent
    else if (PN_IS_INT(obj)) {
      tmp.l = PN_NUM(obj); len = sizeof(tmp); ptr = (char *)&tmp.l;
    }
    else if (PN_IS_BOOL(obj)) {
      tmp.c = (obj == PN_TRUE) ? 1 : 0; len = 1; ptr = (char *)&tmp.c;
    }
    else {
      assert(0 && "Invalid primitive type");
    }
  } else {
    switch (PN_TYPE(obj)) {
      case PN_TSTRING: len = PN_STR_LEN(obj); ptr = PN_STR_PTR(obj); break;
      case PN_TBYTES:  len = potion_send(obj, PN_STR("length")); ptr = PN_STR_PTR(obj); break;
      case PN_TNUMBER: {
        tmp.d = PN_DBL(obj); len = sizeof(tmp); ptr = (char *)&tmp.d;
        break;
      }
      default: return potion_type_error(P, obj);
    }
  }
  int r = write(self->fd, ptr, len);
  if (r == -1)
    return potion_io_error(P, "write");
  return PN_NUM(r);
}
Esempio n. 4
0
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";
}
Esempio n. 5
0
void potion_dump_stack(Potion *P) {
  long n;
  PN *end, *ebp, *start = P->mem->cstack;
  struct PNMemory *M = P->mem;
  POTION_ESP(&end);
  POTION_EBP(&ebp);
#if POTION_STACK_DIR > 0
  n = end - start;
#else
  n = start - end + 1;
  start = end;
  end = M->cstack;
#endif

  printf("-- dumping %ld stack from %p to %p --\n", n, start, end);
  printf("   ebp = %p, *ebp = %lx\n", ebp, *ebp);
  while (n--) {
    vPN(Object) o = (struct PNObject*)*start;
    printf("   stack(%ld) = %p: %lx", n, start, *start);
    if (IS_GC_PROTECTED(*start))
      printf(" vt=%x gc", PN_TYPE(o));
    else if (IN_BIRTH_REGION(*start))
      printf(" vt=%x gc(0)", PN_TYPE(o));
    else if (IN_OLDER_REGION(*start))
      printf(" vt=%x gc(1)", PN_TYPE(o));

    if (*start == 0)
      printf(" nil\n");
    else if (*start & 1)
      printf(" %ld INT\n", PN_INT(*start));
    else if (*start & 2)
      printf(" %s BOOL\n", *start == 2 ? "false" : "true");
    else
      printf(" \n");
    start++;
  }
}
Esempio n. 6
0
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;
}
Esempio n. 7
0
void potion_test_double(CuTest *T) {
  PN dec = potion_strtod(P, "14466", 5);
  CuAssert(T, "double not a number", PN_TYPE(dec) == PN_TNUMBER);
}
Esempio n. 8
0
void potion_test_bool(CuTest *T) {
  CuAssert(T, "true isn't a bool type", PN_TYPE(PN_TRUE) == PN_TBOOLEAN);
  CuAssert(T, "true is a ref", !PN_IS_PTR(PN_TRUE));
  CuAssert(T, "false isn't a bool type", PN_TYPE(PN_FALSE) == PN_TBOOLEAN);
  CuAssert(T, "false is a ref", !PN_IS_PTR(PN_FALSE));
}
Esempio n. 9
0
void potion_test_nil(CuTest *T) {
  CuAssert(T, "nil isn't a nil type", PN_TYPE(PN_NIL) == PN_TNIL);
  CuAssert(T, "nil is a ref", !PN_IS_PTR(PN_NIL));
  CuAssert(T, "nil nil? is false",
    PN_TRUE == potion_send(PN_NIL, potion_str(P, "nil?")));
}
Esempio n. 10
0
static void potion_cmd_compile
(
		char *filename,
		int exec,
		int verbose,
		void *sp
)
{
	PN buf, code;
	int fd = -1;
	struct stat stats;
	Potion *P = potion_create(sp);
	if (stat(filename, &stats) == -1)
	{
		potion_warn("** %s does not exist.\n", filename);
		goto done;
	}

	fd = open(filename, O_RDONLY | O_BINARY);
	if (fd == -1)
	{
		potion_warn("** could not open %s. check permissions.\n", filename);
		goto done;
	}

	buf = potion_bytes(P, stats.st_size);
	if (read(fd, PN_STR_PTR(buf), stats.st_size) == stats.st_size)
	{
		PN_STR_PTR(buf)[stats.st_size] = '\0';
		code = potion_source_load(P, PN_NIL, buf);
		if (PN_IS_PROTO(code))
		{
			if (verbose > 1)
				printf("\n\n-- loaded --\n");
		}
		else
		{
			code = potion_parse(P, buf);
			if (PN_TYPE(code) == PN_TERROR)
			{
				potion_send(potion_send(code, PN_string), PN_print);
				goto done;
			}
			if (verbose > 1)
			{
				printf("\n-- parsed --\n");
				potion_send(potion_send(code, PN_string), PN_print);
				printf("\n");
			}
			code =
					potion_send(code, PN_compile, potion_str(P, filename), PN_NIL);
			if (verbose > 1)
				printf("\n-- compiled --\n");
		}
		if (verbose > 1)
		{
			potion_send(potion_send(code, PN_string), PN_print);
			printf("\n");
		}
		if (exec == 1)
		{
			code = potion_vm(P, code, P->lobby, PN_NIL, 0, NULL );
			if (verbose > 1)
				printf(
						"\n-- vm returned %p (fixed=%ld, actual=%ld, reserved=%ld) --\n",
						(void *) code, PN_INT(potion_gc_fixed(P, 0, 0)),
						PN_INT(potion_gc_actual(P, 0, 0)),
						PN_INT(potion_gc_reserved(P, 0, 0)));
			if (verbose)
			{
				potion_send(potion_send(code, PN_string), PN_print);
				printf("\n");
			}
		}
		else if (exec == 2)
		{
#if POTION_JIT == 1
			PN val;
			PN cl = potion_closure_new(P, (PN_F)potion_jit_proto(P, code, POTION_JIT_TARGET), PN_NIL, 1);
			PN_CLOSURE(cl)->data[0] = code;
			val = PN_PROTO(code)->jit(P, cl, P->lobby);
			if (verbose > 1)
			printf("\n-- jit returned %p (fixed=%ld, actual=%ld, reserved=%ld) --\n", PN_PROTO(code)->jit,
					PN_INT(potion_gc_fixed(P, 0, 0)), PN_INT(potion_gc_actual(P, 0, 0)),
					PN_INT(potion_gc_reserved(P, 0, 0)));
			if (verbose)
			{
				potion_send(potion_send(val, PN_string), PN_print);
				printf("\n");
			}
#else
			potion_warn("** potion built without JIT support\n");
#endif
		}
		else
		{
			char pnbpath[255];
			FILE *pnb;
			sprintf(pnbpath, "%sb", filename);
			pnb = fopen(pnbpath, "wb");
			if (!pnb)
			{
				potion_warn("** could not open %s for writing. check permissions.\n",pnbpath);
				goto done;
			}

			code = potion_source_dump(P, PN_NIL, code);
			if (fwrite(PN_STR_PTR(code), 1, PN_STR_LEN(code),
					pnb) == PN_STR_LEN(code))
			{
				potion_notice("** compiled code saved to %s\n", pnbpath);
				potion_notice("** run it with: potion %s\n", pnbpath);
				fclose(pnb);
			}
			else
			{
				potion_warn("** could not write all bytecode.\n");
			}
		}

#if 0
		void *scanptr = (void *)((char *)P->mem->old_lo + (sizeof(PN) * 2));
		while ((PN)scanptr < (PN)P->mem->old_cur)
		{
			printf("%p.vt = %lx (%u)\n",
					scanptr, ((struct PNObject *)scanptr)->vt,
					potion_type_size(P, scanptr));
			if (((struct PNFwd *)scanptr)->fwd != POTION_FWD && ((struct PNFwd *)scanptr)->fwd != POTION_COPIED)
			{
				if (((struct PNObject *)scanptr)->vt < 0 || ((struct PNObject *)scanptr)->vt > PN_TUSER)
				{
					printf("wrong type for allocated object: %p.vt = %lx\n",
							scanptr, ((struct PNObject *)scanptr)->vt);
					break;
				}
			}
			scanptr = (void *)((char *)scanptr + potion_type_size(P, scanptr));
			if ((PN)scanptr > (PN)P->mem->old_cur)
			{
				printf("allocated object goes beyond GC pointer\n");
				break;
			}
		}
#endif

	}
	else
	{
		potion_warn("** could not read entire file.");
	}

	done: if (fd != -1)
		close(fd);
	if (P != NULL )
		potion_destroy(P);
}