Exemplo n.º 1
0
static int hasmark (const TObject *o) {
  /* valid only for locked objects */
  switch (o->ttype) {
    case LUA_TSTRING: case LUA_TUSERDATA:
      return tsvalue(o)->marked;
    case LUA_TTABLE:
      return ismarked(hvalue(o));
    case LUA_TFUNCTION:
      return ismarked(clvalue(o));
    default:  /* number */
      return 1;
  }
}
Exemplo n.º 2
0
void print_traverse(value_t v)
{
    value_t *bp;
    while (iscons(v)) {
        if (ismarked(v)) {
            bp = (value_t*)ptrhash_bp(&printconses, (void*)v);
            if (*bp == (value_t)HT_NOTFOUND)
                *bp = fixnum(printlabel++);
            return;
        }
        mark_cons(v);
        print_traverse(car_(v));
        v = cdr_(v);
    }
    if (!ismanaged(v) || issymbol(v))
        return;
    if (ismarked(v)) {
        bp = (value_t*)ptrhash_bp(&printconses, (void*)v);
        if (*bp == (value_t)HT_NOTFOUND)
            *bp = fixnum(printlabel++);
        return;
    }
    if (isvector(v)) {
        if (vector_size(v) > 0)
            mark_cons(v);
        unsigned int i;
        for(i=0; i < vector_size(v); i++)
            print_traverse(vector_elt(v,i));
    }
    else if (iscprim(v)) {
        mark_cons(v);
    }
    else if (isclosure(v)) {
        mark_cons(v);
        function_t *f = (function_t*)ptr(v);
        print_traverse(f->bcode);
        print_traverse(f->vals);
        print_traverse(f->env);
    }
    else {
        assert(iscvalue(v));
        cvalue_t *cv = (cvalue_t*)ptr(v);
        // don't consider shared references to ""
        if (!cv_isstr(cv) || cv_len(cv)!=0)
            mark_cons(v);
        fltype_t *t = cv_class(cv);
        if (t->vtable != NULL && t->vtable->print_traverse != NULL)
            t->vtable->print_traverse(v);
    }
}
Exemplo n.º 3
0
Arquivo: lgc.c Projeto: gitrider/wxsj2
void reallymarkobject (GCState *st, GCObject *o) {
  lua_assert(!ismarked(o));
  setbit(o->gch.marked, 0);  /* mark object */
  switch (o->gch.tt) {
    case LUA_TUSERDATA: {
      markvalue(st, gcotou(o)->uv.metatable);
      break;
    }
    case LUA_TFUNCTION: {
      gcotocl(o)->c.gclist = st->tmark;
      st->tmark = o;
      break;
    }
    case LUA_TTABLE: {
      gcotoh(o)->gclist = st->tmark;
      st->tmark = o;
      break;
    }
    case LUA_TTHREAD: {
#if LUA_REFCOUNT
      gcototh(o)->gclist_head.next = st->tmark;
#else !LUA_REFCOUNT
      gcototh(o)->gclist = st->tmark;
#endif LUA_REFCOUNT
      st->tmark = o;
      break;
    }
    case LUA_TPROTO: {
      gcotop(o)->gclist = st->tmark;
      st->tmark = o;
      break;
    }
    default: lua_assert(o->gch.tt == LUA_TSTRING || o->gch.tt == LUA_TWSTRING);
  }
}
Exemplo n.º 4
0
/* move `dead' udata that need finalization to list `tmudata' */
size_t luaC_separateudata (lua_State *L) {
    size_t deadmem = 0;
    GCObject **p = &G(L)->rootudata;
    GCObject *curr;
    GCObject *collected = NULL;  /* to collect udata with gc event */
    GCObject **lastcollected = &collected;
    while ((curr = *p) != NULL) {
        lua_assert(curr->gch.tt == LUA_TUSERDATA);
        if (ismarked(curr) || isfinalized(gcotou(curr)))
            p = &curr->gch.next;  /* don't bother with them */

        else if (fasttm(L, gcotou(curr)->uv.metatable, TM_GC) == NULL) {
            markfinalized(gcotou(curr));  /* don't need finalization */
            p = &curr->gch.next;
        }
        else {  /* must call its gc method */
            deadmem += sizeudata(gcotou(curr)->uv.len);
            *p = curr->gch.next;
            curr->gch.next = NULL;  /* link `curr' at the end of `collected' list */
            *lastcollected = curr;
            lastcollected = &curr->gch.next;
        }
    }
    /* insert collected udata with gc event into `tmudata' list */
    *lastcollected = G(L)->tmudata;
    G(L)->tmudata = collected;
    return deadmem;
}
Exemplo n.º 5
0
static int print_circle_prefix(ios_t *f, value_t v)
{
    value_t label;
    char buf[64];
    char *str;
    if ((label=(value_t)ptrhash_get(&printconses, (void*)v)) !=
        (value_t)HT_NOTFOUND) {
        if (!ismarked(v)) {
            //HPOS+=ios_printf(f, "#%ld#", numval(label));
            outc('#', f);
            str = uint2str(buf, sizeof(buf)-1, numval(label), 10);
            outs(str, f);
            outc('#', f);
            return 1;
        }
        //HPOS+=ios_printf(f, "#%ld=", numval(label));
        outc('#', f);
        str = uint2str(buf, sizeof(buf)-1, numval(label), 10);
        outs(str, f);
        outc('=', f);
    }
    if (ismanaged(v))
        unmark_cons(v);
    return 0;
}
Exemplo n.º 6
0
static void invalidaterefs (void)
{
  int32 i;
  for (i=0; i<L->refSize; i++)
    if (L->refArray[i].status == HOLD && !ismarked(&L->refArray[i].o))
      L->refArray[i].status = COLLECTED;
}
Exemplo n.º 7
0
static void markclosure (GCState *st, Closure *cl) {
  if (!ismarked(cl)) {
    if (!cl->isC)
      protomark(cl->f.l);
    cl->mark = st->cmark;  /* chain it for later traversal */
    st->cmark = cl;
  }
}
Exemplo n.º 8
0
static void collecttable (lua_State *L) {
  Hash **p = &L->roottable;
  Hash *next;
  while ((next = *p) != NULL) {
    if (ismarked(next)) {
      next->mark = next;  /* unmark */
      p = &next->next;
    }
    else {
      *p = next->next;
      luaH_free(L, next);
    }
  }
}
Exemplo n.º 9
0
static void collectclosure (lua_State *L) {
  Closure **p = &L->rootcl;
  Closure *next;
  while ((next = *p) != NULL) {
    if (ismarked(next)) {
      next->mark = next;  /* unmark */
      p = &next->next;
    }
    else {
      *p = next->next;
      luaF_freeclosure(L, next);
    }
  }
}
Exemplo n.º 10
0
vector<hvec> trace(hvec stpoint)
/* Traces a contour. The start point, because of the way the iteration works,
 * is the leftmost point of the bottom line, so it starts going right.
 */
{hvec dir(1), left(1,1), right(0,-1);
 vector<hvec> contour;
 while (isedge(stpoint) && !ismarked(stpoint))
   {contour.push_back(stpoint);
    mark(stpoint);
    if (isedge(stpoint+dir))
       ;
    else if (isedge(stpoint+dir*left))
       dir*=left;
    else
       dir*=right;
    stpoint+=dir;
    }
 return contour;
 }
Exemplo n.º 11
0
static const void *
readobject(lua_State *L, lua_State *dL, const void *parent, const char *desc) {
    int t = lua_type(L, -1);
    int tidx = 0;
    const void * p = NULL;

    switch (t) {
    case LUA_TTABLE:
        tidx = TABLE;
        break;
    case LUA_TFUNCTION:
        tidx = FUNCTION;
        break;
    case LUA_TTHREAD:
        tidx = THREAD;
        break;
    case LUA_TUSERDATA:
        tidx = USERDATA;
        break;
    default:
        return NULL;
    }

    p = lua_topointer(L, -1);
    if (ismarked(dL, p)) {
        lua_rawgetp(dL, tidx, p);
        if (!lua_isnil(dL,-1)) {
            lua_pushstring(dL,desc);
            lua_rawsetp(dL, -2, parent);
        }
        lua_pop(dL,1);
        lua_pop(L,1);
        return NULL;
    }

    lua_newtable(dL);
    lua_pushstring(dL,desc);
    lua_rawsetp(dL, -2, parent);
    lua_rawsetp(dL, tidx, p);

    return p;
}
Exemplo n.º 12
0
static void markobject (GCState *st, TObject *o) {
  switch (ttype(o)) {
    case LUA_TUSERDATA:  case LUA_TSTRING:
      strmark(tsvalue(o));
      break;
    case LUA_TMARK:
      markclosure(st, infovalue(o)->func);
      break;
    case LUA_TFUNCTION:
      markclosure(st, clvalue(o));
      break;
    case LUA_TTABLE: {
      if (!ismarked(hvalue(o))) {
        hvalue(o)->mark = st->tmark;  /* chain it in list of marked */
        st->tmark = hvalue(o);
      }
      break;
    }
    default: break;  /* numbers, etc */
  }
}
Exemplo n.º 13
0
Arquivo: lgc.c Projeto: gitrider/wxsj2
static void marktmu (GCState *st) {
  GCObject *u;
#if LUA_REFCOUNT
  for (u = st->g->tmudata_head.next; u != (GCObject*)&st->g->tmudata_tail; u = u->gch.next) {
#else !LUA_REFCOUNT
  for (u = st->g->tmudata; u; u = u->gch.next) {
#endif LUA_REFCOUNT
    unmark(u);  /* may be marked, if left from previous GC */
    reallymarkobject(st, u);
  }
}


/* move `dead' udata that need finalization to list `tmudata' */
size_t luaC_separateudata (lua_State *L) {
  size_t deadmem = 0;
#if LUA_REFCOUNT
  GCObject **p = &G(L)->rootudata_head.next;
#else !LUA_REFCOUNT
  GCObject **p = &G(L)->rootudata;
#endif LUA_REFCOUNT
  GCObject *curr;
  GCObject *collected = NULL;  /* to collect udata with gc event */
#if !LUA_REFCOUNT
  GCObject **lastcollected = &collected;
  while ((curr = *p) != NULL) {
    lua_assert(curr->gch.tt == LUA_TUSERDATA);
#else LUA_REFCOUNT
  while ((curr = *p) != (GCObject*)&G(L)->rootudata_tail) {
#endif LUA_REFCOUNT
    if (ismarked(curr) || isfinalized(gcotou(curr)))
      p = &curr->gch.next;  /* don't bother with them */

    else if (fasttm(L, gcotou(curr)->uv.metatable, TM_GC) == NULL) {
      markfinalized(gcotou(curr));  /* don't need finalization */
      p = &curr->gch.next;
    }
    else {  /* must call its gc method */
      deadmem += sizeudata(gcotou(curr)->uv.len);
      *p = curr->gch.next;
#if LUA_REFCOUNT
	  Unlink(curr);
	  curr->gch.next = (GCObject*)&G(L)->tmudata_tail;  /* link `curr' at the end of `collected' list */
	  curr->gch.prev = G(L)->tmudata_tail.prev;
	  G(L)->tmudata_tail.prev->gch.next = curr;
      G(L)->tmudata_tail.prev = curr;
#else !LUA_REFCOUNT
	  curr->gch.next = NULL;  /* link `curr' at the end of `collected' list */
      *lastcollected = curr;
      lastcollected = &curr->gch.next;
#endif LUA_REFCOUNT
    }
  }
  /* insert collected udata with gc event into `tmudata' list */
#if LUA_REFCOUNT
//  *lastcollected = G(L)->tmudata_head.next;
//  G(L)->tmudata_head.next = collected;
#else !LUA_REFCOUNT
  *lastcollected = G(L)->tmudata;
  G(L)->tmudata = collected;
#endif LUA_REFCOUNT
  return deadmem;
}


static void removekey (lua_State *L, Node *n) {
  (void)L;
  setnilvalue(gval(n));  /* remove corresponding value ... */
  if (iscollectable(gkey(n)))
    setttype(gkey(n), LUA_TNONE);  /* dead key; remove it */
}
Exemplo n.º 14
0
static void invalidaterefs() {
	int32 i;
	for (i = 0; i < refSize; i++)
		if (refArray[i].status == HOLD && !ismarked(&refArray[i].o))
			refArray[i].status = COLLECTED;
}
Exemplo n.º 15
0
/* mark all the nodes in the hat file that are reachable
 * from the given root -- setting the highest bit in the
 * tag byte
 */
void
markfrom (FileOffset root, FileOffset *buf)
{
  char tag;
  if (root > 8 && root < filesize) {
    /* First read the tag byte.  If it is marked, return.
     * If it is not marked, then mark it now.
     */
    fseek(f,(long int)root,SEEK_SET);
    fread(&tag,sizeof(char),1,f);
    if (ismarked(tag)) return;
    marktag(&tag);
    fseek(f,(long int)root,SEEK_SET);
    fwrite(&tag,sizeof(char),1,f);
    cleartag(&tag);
    /* Examine the tag to determine the kind of node.
     * Read pointers from the node into buf, then
     * markfrom() these pointers recursively.  The buffer is
     * overwritten where possible to minimise the risk of overflow:
     * for this reason, pointers are recursively traced in
     * reverse order.
     */
    {
      int k = lo5(tag);
      if ((ExpDoStmt < k && k < AtomVariable) || k > ListCons) {
	fprintf(stderr, "strange tag %d at 0x%x\n",
                	k, root);
	exit(1);
      }
      switch (k) {
        case ListCons:
          fread(buf,sizeof(FileOffset),2,f);	/* two pointers */
          markfrom(getpointer(buf+1),buf+1);
          markfrom(getpointer(buf),buf);
	  break;
        case Module: break;
        case AtomAbstract: break;

        case SrcPos:
        case AtomVariable:
        case AtomConstructor: 	/* ignore fieldnames for now */
          fread(buf,sizeof(FileOffset),1,f);	/* points to module mode */
          markfrom(getpointer(buf),buf);
          break;

        default: {
          int pos = 0;
          if (hasSrcPos(tag)) {
            fread(buf+pos,sizeof(FileOffset),1,f);
            pos++;
          }
          fread(buf+pos,sizeof(FileOffset),1,f);	/* parent pointer */
          pos++;
          switch (k) {
            case ExpApp:
              fread(buf+pos,sizeof(FileOffset),2,f); /* result+fun */
              pos += 2;
              { unsigned char arity;
                fread(&arity,sizeof(unsigned char),1,f);
                fread(buf+pos,sizeof(FileOffset),(unsigned int)arity,f);
                pos += (int)arity;
              }
	      break;
            case ExpValueApp:
              fread(buf+pos,sizeof(FileOffset),1,f); /* fun */
              pos += 1;
              { unsigned char arity;
                fread(&arity,sizeof(unsigned char),1,f);
                fread(buf+pos,sizeof(FileOffset),(unsigned int)arity,f);
                pos += (int)arity;
              }
	      break;
            case ExpValueUse:
            case ExpConstUse:
            case ExpProjection:
              fread(buf+pos,sizeof(FileOffset),1,f);	/* one extra pointer */
              pos++;
	      break;
            case ExpHidden:
            case ExpConstDef:
            case ExpFieldUpdate:	/* ignore fieldnames for now */
            case ExpGuard:
            case ExpCase:
            case ExpIf:
              fread(buf+pos,sizeof(FileOffset),2,f);	/* two pointers */
              pos+=2;
	      break;
            default: break;				/* no pointers */
          }
	  for (;pos-->0;) markfrom(getpointer(buf+pos), buf+pos);
        } break;
      }
    }
  }
}
Exemplo n.º 16
0
void
nextnode (void)
{
  FileOffset offset = nextoffset;
  char b;
  int marked, err;
  err = fread(&b,sizeof(char),1,f); nextoffset+=1;
  if (err!=1) return;
  if (rmode || xmode) {
    marked = ismarked(b);
    if (marked) {
      cleartag(&b);
      newtagat(&b, offset);
    }
    if (amode) printf("%s", (marked ? "=> " : "   "));
  }
  {
    int k = lo5(b);
    if ((ExpDoStmt<k && k<AtomVariable) || k>ListCons) {
      fprintf(stderr, "strange tag %d at byte offset 0x%x\n",
                      k, offset);
      exit(1);
    } else if (smode) {
      count[k]++;
      if (rmode && marked) reachcount[k]++;
    }
    switch (k) {
    case ListCons:
	if (gmode) printf("%d [label=\"0x%x ListCons\"]\n", offset, offset);
        if (amode) printf("0x%x:  %-20s\t", offset, tag2str(k));
	if (amode) printf("elem=");
        dopointer(NONZERO, ANYEXP, readpointer(), k, offset, "e");
	if (amode) printf(" tail=");
        dopointer(MAYBEZERO, ListCons, readpointer(), k, offset, "t");
      break;
    case Module:
      if (amode) {
        if (tracedModule(b))
             printf("0x%x:  Module (suspect) \t", offset);
        else printf("0x%x:  Module (trusted) \t", offset);
      }
      { char *s = readstring(); if (amode) printf("%s\t", s); }
      { char *s = readstring(); if (amode) printf("\"%s\"", s); }
      break;
    case SrcPos:
      if (amode) printf("0x%x:  SrcPos\t\t\t", offset);
      dopointer(NONZERO, Module, readpointer(), k, offset, "");
      { char *p = readposn(); if (amode) printf(" %s", p); }
      break;
    case AtomVariable:
      if (amode) {
        if (localDef(b))
             printf("0x%x:  AtomVariable (local)\t", offset);
        else printf("0x%x:  AtomVariable (toplevel)\t", offset);
      }
      if (gmode) printf("%d [label=\"0x%x AtomVariable", offset, offset);
      dopointer(NONZERO, Module, readpointer(), k, offset, "");
      { char *p = readposn(); if (amode) printf(" %s", p); }
      { char *fp = readfixpri(); if (*fp!='\0' && amode) printf("%s ", fp); }
      { unsigned int a = readarity();
        if (amode || gmode) printf(amode ? " arity=%u," : " %u", a); }
      { char *n = readstring(); if (amode || gmode) printf(" %s", n); }
      if (gmode) printf("\"]\n");
      break;
    case AtomConstructor:
      if (amode) printf("0x%x:  %-20s\t", offset, tag2str(k));
      if (gmode) printf("%d [label=\"0x%x AtomConstructor", offset, offset);
      dopointer(NONZERO, Module, readpointer(), k, offset, "");
      { char *p = readposn(); if (amode) printf(" %s", p); }
      { char *fp = readfixpri(); if (*fp!='\0' && amode) printf("%s", fp); }
      { unsigned int a = readarity();
        if (amode || gmode) printf(amode ? " arity=%u," : " %u", a);
        { char *n = readstring(); if (amode || gmode) printf(" %s", n); }
        if (gmode) printf("\"]\n");
        if hasFields(b) {
	  int i;
          if (amode) printf(" fields:");
          for (i=1; i<=a; i++) {
            dopointer(NONZERO, AtomVariable, readpointer(), k, offset,
	      (gmode ? (sprintf(stringbuf,"%d",i), stringbuf) : "")
	    );
          }
        }
      }
      break;
    case AtomAbstract:
      if (amode) printf("0x%x:  %-20s\t", offset, tag2str(k));
      if (gmode) printf("%d [label=\"0x%x AtomAbstract ", offset, offset);
      { char *s = readstring(); if (amode || gmode) printf("%s", s); }
      if (gmode) printf("\"]\n");
      break;
    default: {
      if (amode) printf("0x%x:  %-20s\t", offset, tag2str(k));
      if (hasSrcPos(b)) {
	  if (amode) printf("use=");
          dopointer(NONZERO, SrcPos, readpointer(), k, offset, "");
	  if (amode) printf(" ");
      }
   // if (amode && (ExpChar <= k) && (k <= ExpConstUse)) {
   //     printf("(");
   //     if (!isEntered(b)) printf("not ");
   //     printf("entered) ");
   // }
      switch (k) {
      case ExpApp:
	if (amode) printf("parent=");
        dopointer(MAYBEZERO, ANYEXP, readpointer(), k, offset, "p");
	if (amode) printf(" result=");
        dopointer(MAYBEZERO, ANYEXP, readpointer(), k, offset, "r");
	if (amode) printf(" fun=");
        dopointer(NONZERO, ANYEXP, readpointer(), k, offset, "f");
        if (gmode) printf("%d [label=\"0x%x ExpApp", offset, offset);
        { unsigned int a = readarity();
	  int i;
	  if (amode || gmode)
	    printf(amode ? " arity=%u, args " : " %u\"]\n",a);
	  for (i=1; i<=a; i++)
	    dopointer(NONZERO, ANYEXP, readpointer(), k, offset,
	      (gmode ? (sprintf(stringbuf,"%d",i), stringbuf) : "")
	    );
	}
	break;
      case ExpValueApp:
	if (amode) printf("parent=");
        dopointer(MAYBEZERO, ANYEXP, readpointer(), k, offset, "p");
	if (amode) printf(" fun=");
        dopointer(NONZERO, ANYATOM, readpointer(), k, offset, "f");
        if (gmode) printf("%d [label=\"0x%x ExpValueApp", offset, offset);
        { unsigned int a = readarity();
	  int i;
	  if (amode || gmode)
	    printf(amode ? " arity=%u, args " : " %u\"]\n",a);
	  for (i=1; i<=a; i++)
	    dopointer(NONZERO, ANYEXP, readpointer(), k, offset,
	      (gmode ? (sprintf(stringbuf,"%d",i), stringbuf) : "")
	    );
	}
	break;
      case ExpChar:
	if (amode) printf("parent=");
        dopointer(MAYBEZERO, ANYEXP, readpointer(), k, offset, "p");
        { char c = nextbyte();
	  if (gmode) printf("%d [label=\"ExpChar", offset);
	  if (amode || gmode) printf(" '%c'", c);
	  if (gmode) printf("\"]\n");
	}
	break;
      case ExpInt:
	if (amode) printf("parent=");
        dopointer(MAYBEZERO, ANYEXP, readpointer(), k, offset, "p");
        { int i; i = readfourbytes();
	  if (gmode) printf("%d [label=\"ExpInt", offset);
	  if (amode || gmode) printf(" %d", i);
	  if (gmode) printf("\"]\n");
	}
	break;
      case ExpInteger:
	if (amode) printf("parent=");
        dopointer(MAYBEZERO, ANYEXP, readpointer(), k, offset, "p");
        { char* i; i = readinteger();
	  if (gmode) printf("%d [label=\"ExpInteger", offset);
	  if (amode || gmode) printf(" %s", i);
	  if (gmode) printf("\"]\n");
	}
	break;
      case ExpRat:
	if (amode) printf("parent=");
        dopointer(MAYBEZERO, ANYEXP, readpointer(), k, offset, "p");
        { int n,d; n=readfourbytes(); d=readfourbytes();
	  if (gmode) printf("%d [label=\"ExpRat", offset);
          if (amode || gmode) printf(" %d%%%d", n,d);
	  if (gmode) printf("\"]\n");
        }
	break;
      case ExpRational:
	if (amode) printf("parent=");
        dopointer(MAYBEZERO, ANYEXP, readpointer(), k, offset, "p");
        { char* r = readrational();
	  if (gmode) printf("%d [label=\"ExpRational", offset);
	  if (amode || gmode) printf(" %s", r);
	  if (gmode) printf("\"]\n");
        }
	break;
      case ExpFloat:
	if (amode) printf("parent=");
        dopointer(MAYBEZERO, ANYEXP, readpointer(), k, offset, "p");
        { float f = readfloat();
	  if (gmode) printf("%d [label=\"ExpFloat", offset);
	  if (amode || gmode) printf(" %f", f);
	  if (gmode) printf("\"]\n");
        }
	break;
      case ExpDouble:
	if (amode) printf("parent=");
        dopointer(MAYBEZERO, ANYEXP, readpointer(), k, offset, "p");
        { double d = readdouble();
	  if (gmode) printf("%d [label=\"ExpDouble", offset);
	  if (amode || gmode) printf(" %f", d);
	  if (gmode) printf("\"]\n");
        }
	break;
      case ExpValueUse:
	if (gmode) printf("%d [label=\"0x%x ExpValueUse\"]\n", offset, offset);
	if (amode) printf("parent=");
        dopointer(MAYBEZERO, ANYEXP, readpointer(), k, offset, "p");
	if (amode) printf(" value=");
        dopointer(MAYBELAMBDA, ANYATOM, readpointer(), ExpValueUse, offset,"v");
	break;
      case ExpConstUse:
	if (gmode) printf("%d [label=\"0x%x ExpConstUse\"]\n", offset, offset);
	if (amode) printf("parent=");
        dopointer(MAYBEZERO, ANYEXP, readpointer(), k, offset, "p");
	if (amode) printf(" const=");
        dopointer(NONZERO, ExpConstDef, readpointer(), k, offset, "c");
	break;
      case ExpConstDef:
	if (gmode) printf("%d [label=\"0x%x ExpConstDef\"]\n", offset, offset);
	if (amode) printf("parent=");
        dopointer(MAYBEZERO, ANYEXP, readpointer(), k, offset, "p");
	if (amode) printf(" result=");
        dopointer(MAYBEZERO, ANYEXP, readpointer(), k, offset, "r");
	if (amode) printf(" var=");
        dopointer(NONZERO, AtomVariable, readpointer(), k, offset, "v");
	break;
      case ExpGuard:
      case ExpCase:
      case ExpIf:
	if (gmode) printf("%d [label=\"0x%x %s\"]\n", offset, offset,
                  k==ExpGuard ? "ExpGuard" : k==ExpCase ? "ExpCase" : "ExpIf");
	if (amode) printf("parent=");
        dopointer(MAYBEZERO, ANYEXP, readpointer(), k, offset, "p");
	if (amode) printf(" result=");
        dopointer(MAYBEZERO, ANYEXP, readpointer(), k, offset, "r");
	if (amode) printf(" cond=");
        dopointer(NONZERO, ANYEXP, readpointer(), k, offset, "c");
	break;
      case ExpFieldUpdate:
	if (amode) printf("parent=");
        dopointer(MAYBEZERO, ANYEXP, readpointer(), k, offset, "p");
	if (amode) printf(" result=");
        dopointer(MAYBEZERO, ANYEXP, readpointer(), k, offset, "r");
	if (amode) printf(" arg=");
        dopointer(NONZERO, ANYEXP, readpointer(), k, offset, "a");
        { unsigned int i, arity = readarity();
	  if (gmode) printf("%d [label=\"0x%x ExpFieldUpdate %u\"]\n", offset, offset, arity);
	  if (amode) printf(" arity=%u, binders ",arity);
          for (i=0; i<arity; i++) {
            dopointer(NONZERO, AtomVariable, readpointer(), k, offset, "");
          }
	  if (amode) printf(", bindees ",arity);
          for (i=0; i<arity; i++) {
            dopointer(NONZERO, ANYEXP, readpointer(), k, offset, "");
          }
        }
	break;
      case ExpProjection:
	if (gmode) printf("%d [label=\"0x%x ExpProjection\"]\n", offset, offset);
	if (amode) printf("parent=");
        dopointer(MAYBEZERO, ANYEXP, readpointer(), k, offset, "p");
	if (amode) printf(" exp=");
        dopointer(NONZERO, ANYEXP, readpointer(), k, offset, "e");
	break;
      case ExpHidden:
	if (gmode) printf("%d [label=\"0x%x ExpHidden\"]\n", offset, offset);
	if (amode) printf("parent=");
        dopointer(MAYBEZERO, ANYEXP, readpointer(), k, offset, "p");
	if (amode) printf(" result=");
        dopointer(MAYBEZERO, ANYEXP, readpointer(), k, offset, "r");
	if (amode) printf(" children=");
	dopointer(MAYBEZERO, ListCons, readpointer(), k, offset, "c");
	break;
      case ExpForward:
	if (gmode) printf("%d [label=\"0x%x ExpForward\"]\n", offset, offset);
	if (amode) printf("result=");
        dopointer(NONZERO, ANYEXP, readpointer(), k, offset, "r");
	break;
      case ExpDoStmt:
	if (gmode) printf("%d [label=\"0x%x ExpDoStmt\"]\n", offset, offset);
	if (amode) printf("stmt=");
        dopointer(NONZERO, ANYEXP, readpointer(), k, offset, "s");
	break;
      }
    }}
    if (amode) printf("\n");
    if (smode) space[k] += nextoffset - offset;
  }
}