00001
00002
00003
00004
00005
00006 static char *rcsid="@(#)$Id$";
00007
00008 #include "eus.h"
00009
00010 #define p_marked(p) (bpointerof(p)->h.pmark)
00011 #define p_mark_on(p) (bpointerof(p)->h.pmark=1)
00012 #define p_mark_off(p) (bpointerof(p)->h.pmark=0)
00013
00014 extern long freeheap,totalheap;
00015 extern struct chunk *chunklist;
00016 extern long gccount,marktime,sweeptime;
00017 extern pointer stacknlist(),stacklist();
00018 extern jmp_buf topjbuf;
00019 extern long alloccount[MAXBUDDY];
00020
00021 pointer GEESEE(ctx,n,argv)
00022 register context *ctx;
00023 int n;
00024 pointer argv[];
00025 { gc();
00026 return(cons(ctx,makeint(freeheap),
00027 cons(ctx,makeint(totalheap),NIL)));}
00028
00029 pointer SBCOUNT(ctx,n,argv)
00030 context *ctx;
00031 int n;
00032 pointer *argv;
00033 { return(makeint(ctx->special_bind_count));}
00034
00035 pointer GCTIME(ctx,n,argv)
00036 register context *ctx;
00037 int n;
00038 pointer argv[];
00039 { return(cons(ctx,makeint(gccount),
00040 cons(ctx,makeint(marktime),
00041 cons(ctx,makeint(sweeptime),NIL))));}
00042
00043 pointer ALLOC(ctx,n,argv)
00044 register context *ctx;
00045 int n;
00046 pointer argv[];
00047 { int ss,i=2;
00048 ckarg(1);
00049 ss=ckintval(argv[0]);
00050 while (buddysize[i]<ss) i++;
00051 if (i>=MAXBUDDY) error(E_ALLOCATION);
00052 #if defined(RGC) && !defined(__HEAP_EXPANDABLE)
00053
00054 #else
00055 #if defined(RGC)
00056 lock_collector;
00057 DPRINT1("ALLOC: newchunk");
00058 #endif
00059 i=newchunk(i);
00060 #if defined(RGC)
00061 unlock_collector;
00062 #endif
00063 #endif
00064 if (i==ERR) error(E_ALLOCATION);
00065 else return(makeint(buddysize[i]));}
00066
00067 pointer NEWSTACK(ctx,n,argv)
00068 context *ctx;
00069 int n;
00070 pointer argv[];
00071 { eusinteger_t newsize;
00072 if (n==0) return(makeint((ctx->stacklimit+100-ctx->stack)));
00073 else {
00074 newsize=ckintval(argv[0]);
00075 if (newsize>1024*1024*256) error(E_USER,(pointer)"too big stack");
00076 allocate_stack(ctx,newsize);
00077 euslongjmp(topjbuf,newsize);}
00078 }
00079
00080 pointer DISPOSE_HOOK(ctx,n,argv)
00081 context *ctx;
00082 int n;
00083 pointer argv[];
00084 {
00085 #ifndef RGC
00086 pointer p;
00087 ckarg2(1,2);
00088 p=argv[0];
00089 if (!ispointer(p)) error(E_NOOBJECT);
00090 else {
00091 if (n==1) return((p->nodispose==0)?NIL:T);
00092 else {
00093 p->nodispose=((argv[1]==NIL)?0:1);
00094 return(argv[1]); }
00095 }
00096 #endif
00097 }
00098
00099 #if Solaris2
00100 extern _end();
00101 #else
00102 extern eusinteger_t edata();
00103 #endif
00104
00105 int xmark(ctx,p)
00106 register context *ctx;
00107 register pointer p;
00108 { register int s;
00109 register bpointer bp;
00110 #if !alpha && system5
00111 if (p<(pointer)0x100000) return(NULL);
00112 #endif
00113 #if Solaris2
00114 if ((eusinteger_t)p<(eusinteger_t)_end) return(NULL);
00115 #elif sun3 || sun4 || news || (i386 && (!Cygwin && !Darwin)) || alpha || mips
00116 if ((eusinteger_t)p<(eusinteger_t)edata) return(NULL);
00117 #endif
00118 #if sun4 || vax || i386
00119 if ((&ctx->stack[0]<=p) && (p<= &ctx->stack[MAXSTACK])) return(NULL);
00120 #endif
00121 if (issymbol(p)) return((long int)NULL);
00122 #if (WORD_SIZE == 64)
00123 bp=(bpointer)((eusinteger_t)p & ~3L);
00124 #else
00125 bp=(bpointer)((eusinteger_t)p & ~3);
00126 #endif
00127 if (marked(bp)) return(0);
00128 markon(bp);
00129 if (bp->h.elmtype==ELM_FIXED) {
00130 #ifdef RGC
00131 s=buddysize[bp->h.bix&TAGMASK]-1;
00132 #else
00133 s=buddysize[bp->h.bix]-1;
00134 #endif
00135 while (s>0) {
00136 p=bp->b.c[--s];
00137 if (ispointer(p)) xmark(ctx,p);}}
00138 else if (bp->h.elmtype==ELM_POINTER) {
00139 s=intval(bp->b.c[0]);
00140 while (s>0) {
00141 p=bp->b.c[s--];
00142 if (ispointer(p)) xmark(ctx,p);}
00143 }
00144 }
00145
00146 int xcollect(ctx,p)
00147 register context *ctx;
00148 register pointer p;
00149 { register int s,r=0;
00150 register bpointer bp;
00151 #if !alpha && system5
00152 if (p<(pointer)0x100000) return(NULL);
00153 #endif
00154 #if sun
00155 if (p<(pointer)0x10000) return(NULL);
00156 #endif
00157 #if (WORD_SIZE == 64)
00158 bp=(bpointer)((eusinteger_t)p & ~3L);
00159 #else
00160 bp=(bpointer)((eusinteger_t)p & ~3);
00161 #endif
00162 if (marked(bp)) {
00163 markoff(bp);
00164 reclaim(bp);
00165 if (bp->h.elmtype==ELM_FIXED) {
00166 #ifdef RGC
00167 s=buddysize[bp->h.bix&TAGMASK]-1;
00168 #else
00169 s=buddysize[bp->h.bix]-1;
00170 #endif
00171 r=s;
00172 while (s>0) {
00173 p=bp->b.c[--s];
00174 if (ispointer(p)) r+=xcollect(ctx,p);}}
00175 else if (bp->h.elmtype==ELM_POINTER) {
00176 s=intval(bp->b.c[0]);
00177 r=s+1;
00178 while (s>0) {
00179 p=bp->b.c[s--];
00180 if (ispointer(p)) r+=xcollect(ctx,p);}
00181 }
00182 return(r);}
00183 else return(0); }
00184
00185 #ifndef RGC
00186 pointer RECLAIM(ctx,n,argv)
00187 register context *ctx;
00188 int n;
00189 pointer argv[];
00190 { pointer p;
00191 bpointer bp;
00192 ckarg(1);
00193 p=argv[0];
00194 if (!ispointer(p)) return(0);
00195 bp=bpointerof(p);
00196 #if THREADED
00197 mutex_lock(&alloc_lock);
00198 #endif
00199 reclaim(bp);
00200 #if THREADED
00201 mutex_unlock(&alloc_lock);
00202 #endif
00203 #ifdef RGC
00204 return(makeint(buddysize[bp->h.bix&TAGMASK]-1));
00205 #else
00206 return(makeint(buddysize[bp->h.bix]-1));
00207 #endif
00208 }
00209
00210 pointer RECLTREE(ctx,n,argv)
00211 register context *ctx;
00212 int n;
00213 pointer argv[];
00214 { pointer p;
00215 ckarg(1);
00216 p=argv[0];
00217 if (!ispointer(p)) return(0);
00218 #if THREADED
00219 mutex_lock(&mark_lock);
00220 mark_locking="RECLTREE";
00221 #endif
00222 xmark(ctx,p);
00223 n=xcollect(ctx,p);
00224 #if THREADED
00225 mutex_unlock(&mark_lock);
00226 #endif
00227 return(makeint(n));}
00228
00229 #else
00230 pointer RECLAIM(ctx,n,argv)
00231 register context *ctx;
00232 int n;
00233 pointer argv[];
00234 {
00235
00236 }
00237
00238 pointer RECLTREE(ctx,n,argv)
00239 register context *ctx;
00240 int n;
00241 pointer argv[];
00242 {
00243
00244 }
00245 #endif
00246
00247 static int cell_count, object_size, cell_size, count_symbol;
00248
00249 pointer objsize1(x)
00250 pointer x;
00251 { int etype,s,i;
00252 if (isnum(x) || x==UNBOUND || (!count_symbol && pissymbol(x))
00253 || p_marked(x)) return(0);
00254 p_mark_on(x);
00255 etype=elmtypeof(x);
00256 cell_count++;
00257 if (isvector(x)) s=vecsize(x); else s=objsize(x);
00258 cell_size+=buddysize[bixof(x)];
00259 switch(etype) {
00260 case ELM_FIXED: object_size+= s;
00261 for (i=0; i<s; i++) objsize1(x->c.obj.iv[i]);
00262 break;
00263 case ELM_BIT: object_size+=1+(s+WORD_SIZE-1)/WORD_SIZE; break;
00264 case ELM_BYTE: case ELM_CHAR:
00265 object_size += 1+(s+sizeof(eusinteger_t))/sizeof(eusinteger_t); break;
00266 case ELM_POINTER: object_size+=1+s;
00267 for (i=0; i<s; i++) objsize1(x->c.vec.v[i]);
00268 break;
00269 case ELM_INT: case ELM_FLOAT: object_size+=1+s; break;}
00270 }
00271
00272 void objsize2(x)
00273 pointer x;
00274 { int etype,s,i;
00275 pointer y;
00276 if (isnum(x) || x==UNBOUND || (!count_symbol && pissymbol(x)) ||
00277 !p_marked(x)) return;
00278 p_mark_off(x);
00279 etype=elmtypeof(x);
00280 if (isvector(x)) s=vecsize(x); else s=objsize(x);
00281 switch(etype) {
00282 case ELM_FIXED:
00283 for (i=0; i<s; i++) objsize2(x->c.obj.iv[i]);
00284 break;
00285 case ELM_POINTER:
00286 for (i=0; i<s; i++) objsize2(x->c.vec.v[i]);
00287 break;}
00288 }
00289
00290 pointer OBJSIZE(ctx,n,argv)
00291 register context *ctx;
00292 int n;
00293 pointer argv[];
00294 { register pointer a=argv[0];
00295 ckarg2(1,2);
00296 if (n==2) count_symbol=(argv[1]!=NIL); else count_symbol=0;
00297 cell_count=object_size=cell_size=0;
00298 #if THREADED
00299 mutex_lock(&mark_lock);
00300 mark_locking="OBJSIZE";
00301 #endif
00302 objsize1(a);
00303 objsize2(a);
00304 #if THREADED
00305 mutex_unlock(&mark_lock);
00306 #endif
00307 return(cons(ctx,makeint(cell_count),
00308 cons(ctx,makeint(object_size),
00309 cons(ctx,makeint(cell_size),NIL))));}
00310
00311 pointer BKTRACE(ctx,n,argv)
00312 register context *ctx;
00313 int n;
00314 pointer argv[];
00315 { int i,j;
00316 pointer r=NIL;
00317 struct callframe *cfp=ctx->callfp;
00318 ckarg(1);
00319 i=j=ckintval(argv[0]);
00320 while (i-->0) {
00321 if (cfp==NULL) break;
00322 vpush(cfp->form); cfp=cfp->vlink;}
00323 while (--j>i) r=cons(ctx,vpop(),r);
00324 return(r);}
00325
00326 pointer MEMORY_REPORT(ctx,n,argv)
00327 register context *ctx;
00328 int n;
00329 pointer *argv;
00330 {
00331 int fcount[MAXBUDDY],tcount[MAXBUDDY];
00332 eusfloat_t loss[MAXBUDDY];
00333 register int i,j;
00334 int s;
00335 bpointer bp,p,tail;
00336 struct chunk *cp;
00337 char cbuf[100];
00338 pointer outs;
00339
00340 outs=(pointer)getoutstream(ctx,n+1,argv[0]);
00341 for (i=1; i<MAXBUDDY; i++) {
00342 s=0;
00343 bp=buddy[i].bp;
00344 while (0 < (eusinteger_t)bp) { s++; bp=bp->b.nextbcell;}
00345 fcount[i]=s; tcount[i]=0;}
00346 cp=chunklist;
00347 while (cp) {
00348 s=buddysize[cp->chunkbix];
00349 p= &cp->rootcell;
00350 tail=(bpointer)((eusinteger_t)p+(s<<WORDSHIFT));
00351 while (p<tail) {
00352 #ifdef RGC
00353 i=p->h.bix&TAGMASK;
00354 #else
00355 i=p->h.bix;
00356 #endif
00357 tcount[i]++;
00358 p=(bpointer)((eusinteger_t)p+(buddysize[i]<<WORDSHIFT));}
00359 cp=cp->nextchunk;}
00360
00361 sprintf(cbuf,"buddy size free total total-size wanted wanted-size\n");
00362 writestr(outs,(byte *)cbuf,strlen(cbuf));
00363
00364 for(i=1; i<MAXBUDDY; i++) {
00365 sprintf(cbuf,"%4d %7ld %5d %6d %8ld %8ld %10ld\n",
00366 i,buddysize[i],fcount[i],tcount[i], tcount[i]*buddysize[i],
00367 alloccount[i],alloccount[i]*buddysize[i]);
00368 writestr(outs,(byte *)cbuf,strlen(cbuf)); }
00369
00370 sprintf(cbuf, "\ncontext big_alloc small_alloc\n");
00371 writestr(outs,(byte *)cbuf,strlen(cbuf));
00372 for (i=1; i<MAXTHREAD; i++) {
00373 if (euscontexts[i]) {
00374 sprintf(cbuf,"%4d %12d %12d\n",
00375 i, euscontexts[i]->alloc_big_count, euscontexts[i]->alloc_small_count);
00376 writestr(outs,(byte *)cbuf,strlen(cbuf)); }
00377 }
00378 return(T);
00379 }
00380
00381 pointer CLEAR_ALLOCCOUNT(ctx,n,argv)
00382 register context *ctx;
00383 int n;
00384 pointer *argv;
00385 { register int i;
00386 for (i=1; i<MAXBUDDY; i++) alloccount[i]=0;
00387 for (i=1; i<MAXTHREAD; i++) {
00388 if (euscontexts[i]) {
00389 euscontexts[i]->alloc_big_count=euscontexts[i]->alloc_small_count;}}
00390 return(NIL);}
00391
00392 pointer ROOM(ctx,n,argv)
00393 register context *ctx;
00394 int n;
00395 pointer argv[];
00396 { int counts[MAXCLASS],sizes[MAXCLASS];
00397 int holecount=0,holesize=0;
00398 register int i,s;
00399 char buf[256];
00400 struct chunk *chp;
00401 pointer klass,strm;
00402 bpointer b,tail;
00403
00404 strm=(pointer)getoutstream(ctx,n+1,argv[0]);
00405 for(i=0; i<MAXCLASS; i++) counts[i]=sizes[i]=0;
00406 #if THREADED
00407 mutex_lock(&mark_lock);
00408 rw_wrlock(&gc_lock);
00409 mark_locking="ROOM";
00410 #endif
00411 markall();
00412 for (chp=chunklist; chp!=0; chp=chp->nextchunk) {
00413 s=buddysize[chp->chunkbix];
00414 b= &chp->rootcell;
00415 tail=(bpointer)((eusinteger_t)b+(s<<WORDSHIFT));
00416 while (b<tail) {
00417 if (marked(b)) {
00418 i=b->h.cix;
00419 if (i<0 || i>=MAXCLASS)
00420 fprintf(stderr,"bad cid %d at %p, bix=%d\n",i,b,b->h.bix);
00421 else {
00422 counts[i]++;
00423 #ifdef RGC
00424 sizes[i]+=buddysize[b->h.bix&TAGMASK];
00425 #else
00426 sizes[i]+=buddysize[b->h.bix];
00427 #endif
00428 }}
00429 else {
00430 holecount++;
00431 #ifdef RGC
00432 holesize+=buddysize[b->h.bix&TAGMASK];
00433 #else
00434 holesize+=buddysize[b->h.bix];
00435 #endif
00436 }
00437 b=nextbuddy(b);} }
00438 sweepall();
00439 #if THREADED
00440 rw_unlock(&gc_lock);
00441 mutex_unlock(&mark_lock);
00442 #endif
00443 for (i=0; i<MAXCLASS; i++) {
00444 klass=classtab[i].def;
00445 if (klass && isclass(klass)) {
00446 sprintf(buf,"%32s%7d cells %7d words %6ldKB\n",
00447 klass->c.cls.name->c.sym.pname->c.str.chars,
00448 counts[i],sizes[i],sizes[i]*sizeof(pointer)/1024);
00449 writestr(strm,(byte *)buf,strlen(buf)); } }
00450 sprintf(buf,"%32s%7d cells %7d words %6ldKB\n","holes",holecount,
00451 holesize,holesize*sizeof(pointer)/1024);
00452 writestr(strm,(byte *)buf,strlen(buf));
00453 return(NIL);}
00454
00455 pointer FREE_COUNTS(ctx,n,argv)
00456 register context *ctx;
00457 int n;
00458 pointer *argv;
00459 { int i;
00460 char buf[256];
00461 pointer strm;
00462 extern pointer QTERMIO;
00463 strm=Spevalof(QTERMIO);
00464 strm=strm->c.iostream.out;
00465 for (i=0; i<MAXBUDDY; i++) {
00466 sprintf(buf, "%3d %10ld * %6d = %10ld\n",
00467 i, buddysize[i], buddy[i].count, buddysize[i]*buddy[i].count);
00468 writestr(strm,(byte *)buf,strlen(buf));
00469 }
00470 return(T);}
00471
00472 pointer LIST_ALL_CHUNKS(ctx,n,argv)
00473 register context *ctx;
00474 int n;
00475 pointer *argv;
00476 { pointer r=NIL,p;
00477 struct chunk *cnk;
00478 ckarg(0);
00479 for (cnk=chunklist; cnk!=NULL; cnk=cnk->nextchunk) {
00480 vpush(r);
00481 p=cons(ctx,makeint((eusinteger_t)cnk),cons(ctx,makeint(buddysize[cnk->chunkbix]),NIL));
00482 r=cons(ctx,p,vpop());}
00483 return(r);}
00484
00485 pointer INSTANCELIST(ctx,n,argv)
00486 register context *ctx;
00487 int n;
00488 pointer argv[];
00489 { pointer klass;
00490 register pointer r=NIL;
00491 register short cid;
00492 struct chunk *chp;
00493 pointer *spsave=ctx->vsp;
00494 int s,sub=0,objcid;
00495 bpointer b,tail;
00496
00497 ckarg2(1,2);
00498 if (n==2) sub=(argv[1]!=NIL);
00499 klass=argv[0];
00500 if (!isclass(klass)) error(E_NOCLASS);
00501 cid=intval(klass->c.cls.cix);
00502 #if THREADED
00503 mutex_lock(&mark_lock);
00504 mark_locking="INSTANCELIST";
00505 #endif
00506 markall();
00507 for (chp=chunklist; chp!=0; chp=chp->nextchunk) {
00508 s=buddysize[chp->chunkbix];
00509 b= &chp->rootcell;
00510 tail=(bpointer)((eusinteger_t)b+(s<<WORDSHIFT));
00511 while (b<tail) {
00512 if (marked(b)) {
00513 objcid=b->h.cix;
00514 if (objcid==cid ||
00515 (sub && (objcid>=cid && objcid<=classtab[cid].subcix))) {
00516 vpush(makepointer(b));
00517 if (ctx->vsp >= ctx->stacklimit) {
00518 sweepall();
00519 error(E_USER,(pointer)"not enough stack space");}} }
00520 b=nextbuddy(b);} }
00521 sweepall();
00522 #if THREADED
00523 mutex_unlock(&mark_lock);
00524 #endif
00525 while (ctx->vsp > spsave) r=cons(ctx,vpop(),r);
00526 return(r);}
00527
00528 pointer LISTALLREFERENCES(ctx,n,argv)
00529 register context *ctx;
00530 int n;
00531 pointer argv[];
00532 { register pointer target=argv[0],p,r=NIL;
00533 struct chunk *chp;
00534 pointer *spsave=ctx->vsp;
00535 register int s,bsize,size;
00536 bpointer b,tail;
00537
00538 ckarg(1);
00539 #if THREADED
00540 mutex_lock(&mark_lock);
00541 mark_locking="LISTALLREF";
00542 #endif
00543 markall();
00544 for (chp=chunklist; chp!=0; chp=chp->nextchunk) {
00545 bsize=buddysize[chp->chunkbix];
00546 b= &chp->rootcell;
00547 tail=(bpointer)((eusinteger_t)b+(bsize<<WORDSHIFT));
00548 while (b<tail) {
00549 if (marked(b)) {
00550 p=makepointer(b);
00551 switch(elmtypeof(p)) {
00552 case ELM_POINTER:
00553 size=vecsize(p);
00554 for (s=0; s<size; s++)
00555 if (p->c.vec.v[s]==target) goto found;
00556 break;
00557 case ELM_FIXED:
00558 size=objsize(p);
00559 for (s=0; s<size; s++)
00560 if (p->c.obj.iv[s]==target) goto found;
00561 break;
00562 default: break;}
00563 goto next_buddy;
00564 found:
00565 vpush(p);
00566 if (ctx->vsp>=ctx->stacklimit) {
00567 sweepall();
00568 error(E_USER,(pointer)"not enough stack space");} }
00569 next_buddy:
00570 b=nextbuddy(b);} }
00571 sweepall();
00572 #if THREADED
00573 mutex_unlock(&mark_lock);
00574 #endif
00575 while (ctx->vsp>spsave) r=cons(ctx,vpop(),r);
00576 return(r);}
00577
00578
00579
00580
00581
00582
00583 pointer ADDRESS(ctx,n,argv)
00584 register context *ctx;
00585 int n;
00586 pointer argv[];
00587 { eusinteger_t p;
00588 ckarg(1);
00589 p=(eusinteger_t)bpointerof(argv[0]);
00590 return(mkbigint(p));}
00591
00592 pointer PEEK(ctx,n,argv)
00593 register context *ctx;
00594 int n;
00595 pointer argv[];
00596 { union un {
00597 byte b;
00598 short s;
00599 int i;
00600 long l;
00601 float f;
00602 double d;
00603 void *p;} *u;
00604 long x,etype;
00605 unsigned long y;
00606 pointer p,size;
00607 numunion nu;
00608
00609 ckarg2(1,3);
00610 p=argv[0];
00611 if (isvector(p)) {
00612 etype=elmtypeof(p);
00613 if (etype==ELM_CHAR || etype==ELM_BYTE) {
00614 u= (union un *)&p->c.str.chars[ckintval(argv[1])];
00615 if (n==3) size=argv[2]; else size=K_LONG;}
00616 else if (etype==ELM_FOREIGN) {
00617 u= (union un *)&((byte *)(p->c.ivec.iv[0]))[ckintval(argv[1])];
00618 if (n==3) size=argv[2]; else size=K_LONG;}
00619 else error(E_NOSTRING);}
00620 else{
00621 x=bigintval(argv[0]);
00622 u=(union un *)x;
00623 if (n==2) size=argv[1]; else size=K_LONG;}
00624 #if (WORD_SIZE == 64)
00625 if (size==K_LONG) return mkbigint(u->l);
00626 if (size==K_INTEGER) return makeint(u->i);
00627 #else
00628 if (size==K_LONG || size==K_INTEGER) {
00629 y=u->l;
00630 return(mkbigint(y));}
00631 #endif
00632 if (size==K_BYTE || size==K_CHAR) return(makeint(u->b));
00633 if (size==K_SHORT) return(makeint(u->s));
00634 if (size==K_FLOAT) return(makeflt(u->f));
00635 if (size==K_DOUBLE) return(makeflt(u->d));
00636 if (size==K_POINTER) return(mkbigint((eusinteger_t)(u->p)));
00637 else error(E_USER,(pointer)"unknown access mode");}
00638
00639 pointer POKE(ctx,n,argv)
00640 register context *ctx;
00641 int n;
00642 pointer argv[];
00643 { union un {
00644 byte b;
00645 short s;
00646 int i;
00647 long l;
00648 float f;
00649 double d;
00650 void *p;} *u;
00651 eusinteger_t x;
00652 int etype;
00653 pointer p,size,val;
00654 numunion nu;
00655
00656 ckarg2(2,4);
00657 val=argv[0];
00658 p=argv[1];
00659 if (isvector(p)) {
00660 etype=elmtypeof(p);
00661 if (etype==ELM_CHAR || etype==ELM_BYTE) {
00662 u= (union un *)&p->c.str.chars[ckintval(argv[2])];
00663 if (n==4) size=argv[3]; else size=K_LONG;}
00664 else if (etype==ELM_FOREIGN) {
00665 u= (union un *)&((byte *)(p->c.ivec.iv[0]))[ckintval(argv[2])];
00666 if (n==4) size=argv[3]; else size=K_LONG;}
00667 else error(E_NOSTRING);}
00668 else{
00669 x=bigintval(argv[1]);
00670 u=(union un *)x;
00671 if (n==3) size=argv[2]; else size=K_LONG;}
00672 #if (WORD_SIZE == 64)
00673 if (size==K_LONG) u->l=bigintval(val);
00674 else if (size==K_INTEGER) u->i=ckintval(val);
00675 #else
00676 if (size==K_LONG || size==K_INTEGER) u->l=bigintval(val);
00677 #endif
00678 else if (size==K_BYTE || size==K_CHAR) u->b=ckintval(val);
00679 else if (size==K_SHORT) u->s=ckintval(val);
00680 else if (size==K_FLOAT) u->f=ckfltval(val);
00681 else if (size==K_DOUBLE) u->d=ckfltval(val);
00682 else if (size==K_POINTER) u->p=(void*)ckintval(val);
00683 else error(E_USER,(pointer)"unknown access mode");
00684 return(val);}
00685
00686
00687
00688
00689
00690 pointer LISTALLCATCHERS(ctx,n,argv)
00691 register context *ctx;
00692 int n;
00693 pointer *argv;
00694 { pointer catchers=NIL;
00695 struct catchframe *cfp=ctx->catchfp;
00696 int i=0;
00697 while (cfp) {
00698 vpush(cfp->label);
00699 i++;
00700 cfp=cfp->nextcatch;}
00701 return(stacknlist(ctx,i));}
00702
00703 pointer LISTBINDINGS(ctx,n,argv)
00704 register context *ctx;
00705 int n;
00706 pointer *argv;
00707 { struct bindframe *bfp=ctx->bindfp, *nextbfp;
00708 int i=0;
00709 while (bfp) {
00710 vpush(cons(ctx,bfp->sym,bfp->val));
00711 i++;
00712 nextbfp=bfp->dynblink;
00713 if (nextbfp==NULL) nextbfp=bfp->lexblink;
00714 bfp=nextbfp;}
00715 return(stacknlist(ctx,i));}
00716
00717 pointer LISTSPECIALBINDINGS(ctx,n,argv)
00718 register context *ctx;
00719 int n;
00720 pointer *argv;
00721 { struct specialbindframe *sbfp=ctx->sbindfp;
00722 int i=0;
00723 while (sbfp) {
00724 vpush(cons(ctx,sbfp->sym,sbfp->oldval));
00725 i++;
00726 sbfp=sbfp->sblink;}
00727 return(stacknlist(ctx,i));}
00728
00729 pointer LISTALLCLASSES(ctx,n,argv)
00730 register context *ctx;
00731 int n;
00732 pointer argv[];
00733 { for (n=nextcix; n>0; ) ckpush(classtab[--n].def);
00734 return(stacknlist(ctx,nextcix));}
00735
00736 pointer EXPORTALL(ctx,n,argv)
00737 register context *ctx;
00738 int n;
00739 pointer argv[];
00740 { ckarg(1);
00741 export_all = (argv[0]!=NIL);
00742 return(export_all?T:NIL);}
00743
00744 pointer NEXT_SPECIAL_INDEX(ctx,n,argv)
00745 context *ctx;
00746 int n;
00747 pointer argv[];
00748 { int x;
00749 x=special_index();
00750 return(makeint(x));}
00751
00752 pointer THREAD_SPECIALS(ctx,n,argv)
00753 context *ctx;
00754 int n;
00755 pointer argv[];
00756 { int x;
00757 context *con;
00758 pointer p;
00759
00760 if (n==0) con=ctx;
00761 else {
00762 x=ckintval(argv[0]);
00763 if (x<0 || x>MAXTHREAD) error(E_USER,(pointer)"no such thread");
00764 if (x==0) con=ctx;
00765 else con=euscontexts[x];}
00766 p=con->specials;
00767 if (p==NULL) return(NIL);
00768 if (n>1) {
00769 x=ckintval(argv[1]);
00770 return(p->c.vec.v[x]); }
00771 else return(p);}
00772
00773
00774 void sysfunc(ctx,mod)
00775 register context *ctx;
00776 pointer mod;
00777 { pointer pkgname,pkgnick,p=Spevalof(PACKAGE);
00778
00779 pointer_update(Spevalof(PACKAGE),syspkg);
00780
00781 defun(ctx,"SBCOUNT",mod,SBCOUNT,NULL);
00782 defun(ctx,"GC",mod,GEESEE,NULL);
00783 defun(ctx,"GCTIME",mod,GCTIME,NULL);
00784 defun(ctx,"ALLOC",mod,ALLOC,NULL);
00785 defun(ctx,"NEWSTACK",mod,NEWSTACK,NULL);
00786 defun(ctx,"RECLAIM",mod,RECLAIM,NULL);
00787 defun(ctx,"RECLAIM-TREE",mod,RECLTREE,NULL);
00788 defun(ctx,"OBJECT-SIZE",mod,OBJSIZE,NULL);
00789 defun(ctx,"BKTRACE",mod,BKTRACE,NULL);
00790 defun(ctx,"MEMORY-REPORT",mod,MEMORY_REPORT,NULL);
00791 defun(ctx,"CLEAR-MEMORY-REPORT",mod,CLEAR_ALLOCCOUNT,NULL);
00792 defun(ctx,"ROOM",mod,ROOM,NULL);
00793 defun(ctx,"FREE-COUNT",mod,FREE_COUNTS,NULL);
00794 defun(ctx,"LIST-ALL-CHUNKS",mod,LIST_ALL_CHUNKS,NULL);
00795 defun(ctx,"LIST-ALL-INSTANCES",mod,INSTANCELIST,NULL);
00796 defun(ctx,"ADDRESS",mod,ADDRESS,NULL);
00797 defun(ctx,"PEEK",mod,PEEK,NULL);
00798 defun(ctx,"POKE",mod,POKE,NULL);
00799
00800
00801 defun(ctx,"LIST-ALL-REFERENCES",mod,LISTALLREFERENCES,NULL);
00802 defun(ctx,"LIST-ALL-CATCHERS",mod,LISTALLCATCHERS,NULL);
00803 defun(ctx,"LIST-ALL-BINDINGS",mod,LISTBINDINGS,NULL);
00804 defun(ctx,"LIST-ALL-SPECIAL-BINDINGS",mod,LISTSPECIALBINDINGS,NULL);
00805 defun(ctx,"LIST-ALL-CLASSES",mod,LISTALLCLASSES,NULL);
00806 defun(ctx,"EXPORT-ALL-SYMBOLS", mod, EXPORTALL,NULL);
00807 defun(ctx,"NEXT-SPECIAL-INDEX", mod, NEXT_SPECIAL_INDEX,NULL);
00808 defun(ctx,"THREAD-SPECIALS", mod, THREAD_SPECIALS,NULL);
00809 defun(ctx,"DISPOSE-HOOK", mod, DISPOSE_HOOK,NULL);
00810
00811 pointer_update(Spevalof(PACKAGE),p);
00812 }