00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 static char *rcsid="@(#)$Id$";
00012
00013 #include "eus.h"
00014
00015 extern pointer K_METHOD_DOCUMENTATION;
00016
00017 #if THREADED
00018
00019 #endif
00020
00021 int mchit=0, mcmiss=0, trycache=1;
00022
00023 pointer GETCLASS(ctx,n,argv)
00024 register context *ctx;
00025 int n;
00026 pointer argv[];
00027 { pointer v;
00028 ckarg(1);
00029 if (isnum(argv[0])) return(NIL);
00030 return(classof(argv[0]));}
00031
00032 pointer CLASSP(ctx,n,argv)
00033 register context *ctx;
00034 int n;
00035 pointer argv[];
00036 {
00037 if (n!=1) error(E_MISMATCHARG);
00038 return(isclass(argv[0])?T:NIL);}
00039
00040 pointer SUBCLASSP(ctx,n,argv)
00041 register context *ctx;
00042 int n;
00043 register pointer argv[];
00044 { register int k,s;
00045 ckarg(2);
00046 if (!isclass(argv[0])) error(E_NOCLASS,argv[0]);
00047 if (!isclass(argv[1])) error(E_NOCLASS,argv[1]);
00048 k=intval(argv[0]->c.cls.cix);
00049 s=intval(argv[1]->c.cls.cix);
00050 if (k>=s && k<=classtab[s].subcix) return(T); else return(NIL); }
00051
00052 pointer DERIVEDP(ctx,n,argv)
00053 register context *ctx;
00054 int n;
00055 pointer argv[];
00056 { register pointer obj,klass;
00057 register int objcix,klasscix;
00058 ckarg(2);
00059 obj=argv[0]; klass=argv[1];
00060 if (isnum(obj)) {
00061 if ((klass==QFLOAT || klass==K_FLOAT)&& isflt(obj)) return(T);
00062 else if ((klass==QINTEGER || klass==K_INTEGER) && isint(obj)) return(T);
00063 else return(NIL);}
00064 if (!isclass(klass)) error(E_NOCLASS,klass);
00065 objcix=obj->cix;
00066 klasscix=intval(klass->c.cls.cix);
00067 if (objcix>=klasscix && objcix<=classtab[klasscix].subcix) return(T);
00068 else return(NIL);}
00069
00070
00071
00072
00073
00074
00075 pointer ENTERCLASS(ctx,n,argv)
00076 register context *ctx;
00077 int n;
00078 register pointer argv[];
00079 { ckarg(1);
00080 if (!isclass(argv[0])) error(E_NOCLASS,argv[0]);
00081 enterclass(argv[0]);
00082 return(argv[0]);}
00083
00084
00085
00086
00087
00088 extern pointer K_CLASS;
00089
00090 void addmethod(ctx,meth,class,doc)
00091 register context *ctx;
00092 register pointer meth,class,doc;
00093 { extern pointer putprop(), assq();
00094 register pointer selector,methods,classes,medoc,medoc2;
00095 register int i,j;
00096 vpush(meth);
00097 selector=ccar(meth); methods=class->c.cls.methods;
00098 if (!issymbol(selector)) error(E_NOSYMBOL);
00099 classes=assq(K_CLASS,selector->c.sym.plist);
00100 if (classes!=NIL) classes=ccdr(classes);
00101 putprop(ctx,selector,cons(ctx,class,classes),K_CLASS);
00102
00103 if (doc!=NIL) {
00104 medoc=assq(K_METHOD_DOCUMENTATION, selector->c.sym.plist);
00105
00106 if (medoc==NIL) putprop(ctx,selector,cons(ctx,cons(ctx,class,doc),NIL),
00107 K_METHOD_DOCUMENTATION);
00108 else {
00109 medoc2=assq(class,ccdr(medoc));
00110 if (medoc2==NIL)
00111 {pointer_update(medoc->c.cons.cdr,cons(ctx,cons(ctx,class,doc),ccdr(medoc)));}
00112 else pointer_update(medoc2->c.cons.cdr,doc); } }
00113
00114 if (methods==NIL) {pointer_update(class->c.cls.methods,cons(ctx,meth,NIL));}
00115 else if (ccar(ccar(methods))==selector) {pointer_update(ccar(methods),meth);}
00116 else {
00117 while(ccdr(methods)!=NIL) {
00118 methods=ccdr(methods);
00119 if (ccar(ccar(methods))==selector) {
00120 ccar(methods)=meth;
00121 goto purgecache; } }
00122 pointer_update(ccdr(methods),cons(ctx,meth,NIL)); }
00123
00124 purgecache:
00125 vpop();
00126 for (j=0; j<MAXTHREAD; j++) {
00127 if ((ctx=euscontexts[j]))
00128 for (i=0; i<MAXMETHCACHE; i++)
00129 if (ctx->methcache[i].selector==selector)
00130 pointer_update(ctx->methcache[i].selector,NIL); }
00131 }
00132
00133 void addcmethod(ctx,mod,cfunc,sel,class,doc)
00134 register context *ctx;
00135 pointer sel,mod,class,doc;
00136 pointer (*cfunc)();
00137 { if (!issymbol(class)) error(E_NOCLASS,class);
00138 class=speval(class);
00139 if (class==UNBOUND || !isclass(class)) error(E_NOCLASS,class);
00140 addmethod(ctx,cons(ctx,sel,
00141 cons(ctx,makecode(mod,cfunc,SUBR_FUNCTION),NIL)),
00142 class,doc);}
00143
00144 pointer DEFMETHOD(ctx,arg)
00145 register context *ctx;
00146 pointer arg;
00147 { register pointer class,selector,classsym,body,doc;
00148 classsym=carof(arg,E_MISMATCHARG); arg=ccdr(arg);
00149 if (!issymbol(classsym)) error(E_NOSYMBOL);
00150 class=speval(classsym);
00151 if (class==UNBOUND) error(E_UNBOUND,classsym);
00152 if (!isclass(class)) error(E_NOCLASS,class);
00153 while (islist(arg)) {
00154 body=ccar(arg);
00155 if (!iscons(body)) error(E_NOLIST);
00156 doc=ccdr(ccdr(body));
00157 if (isstring(ccar(doc))) doc=ccar(doc); else doc=NIL;
00158 addmethod(ctx,body,class,doc); arg=ccdr(arg);}
00159 return(classsym);}
00160
00161 pointer INSTANTIATE(ctx,n,argv)
00162 register context *ctx;
00163 int n;
00164 pointer argv[];
00165 { pointer a;
00166 int s;
00167 extern pointer makeobject();
00168 a=argv[0];
00169 if (isvecclass(a)) {
00170 s=intval(a->c.vcls.size);
00171 if (s<0) { ckarg(2); s=ckintval(argv[1]);}
00172 else ckarg(1);
00173 #ifdef SAFETY
00174 {
00175 pointer tmp = makevector(a,s);
00176 take_care(tmp);
00177 return(tmp);
00178 }
00179 #else
00180 return(makevector(a,s));
00181 #endif
00182 }
00183 else if (isclass(a)) {
00184 ckarg(1);
00185 #ifdef SAFETY
00186 {
00187 pointer tmp = makeobject(a);
00188 take_care(tmp);
00189 return(tmp);
00190 }
00191 #else
00192 return(makeobject(a));
00193 #endif
00194 }
00195 else error(E_NOCLASS,a);}
00196
00197
00198
00199
00200
00201
00202
00203 pointer findmethod(ctx,sel,search, curclass)
00204 register context *ctx;
00205 register pointer sel,search, *curclass;
00206 { register pointer meths,klass=search;
00207 register struct methdef *mt;
00208 register int h;
00209
00210 if (trycache) {
00211 h=(((eusinteger_t)sel+(eusinteger_t)klass)>>3) & (MAXMETHCACHE-1);
00212 mt= &ctx->methcache[h];
00213 if (mt->selector==sel && mt->class==search) {
00214
00215 mchit++;
00216 *curclass = mt->ownerclass;
00217 return(mt->method);}}
00218 while (isclass(klass) || isvecclass(klass)) {
00219 mcmiss++;
00220 meths=klass->c.cls.methods;
00221 while (islist(meths))
00222 if (ccar(ccar(meths))==sel) {
00223 if (trycache) {
00224 pointer_update(mt->selector,sel);
00225 pointer_update(mt->class,search);
00226 pointer_update(mt->ownerclass,klass);
00227 pointer_update(mt->method,ccar(meths));
00228 }
00229 *curclass = klass; return(ccar(meths));}
00230 else meths=ccdr(meths);
00231 klass= (klass->c.cls.super);}
00232 return(NIL);}
00233
00234 pointer findforward(ctx,selector,klass,obj,component,classfound)
00235 context *ctx;
00236 register pointer selector,klass,obj, *component, *classfound;
00237 { register pointer forwards=klass->c.cls.forwards,flist,meth;
00238 register int i=0,vcount=vecsize(forwards);
00239 while (i<vcount) {
00240 flist=forwards->c.vec.v[i];
00241 if (flist==T || memq(selector,flist)!=NIL) {
00242 *component = obj->c.obj.iv[i];
00243 if (!isnum(*component)) {
00244 meth=findmethod(ctx,selector,classof(*component),classfound);
00245 if (meth!=NIL) return(meth);}
00246 else error(E_NOOBJECT);}
00247 i++;}
00248 return(NIL);}
00249
00250 pointer SEND(ctx,n,argv)
00251 register context *ctx;
00252 int n;
00253 register pointer argv[];
00254 { register pointer receiver,klass,selector,meth,result;
00255 register pointer *spsave=ctx->vsp, *altargv;
00256 pointer curclass, component;
00257 struct bindframe *bf,*bfsave=ctx->bindfp;
00258 struct specialbindframe *sbfpsave=ctx->sbindfp;
00259 int sbcount=ctx->special_bind_count;
00260 int i,argoffset;
00261 #if defined(DEBUG_COUNT) || defined(SEND_DEBUG)
00262 static int count = 0;
00263
00264 count++;
00265 #endif
00266
00267 #ifdef SEND_DEBUG
00268 printf( "SEND:%d\n", count );
00269 #endif
00270
00271 if (n<2) error(E_MISMATCHARG);
00272 receiver=argv[0];
00273 selector=argv[1];
00274 if (isnum(receiver)) error(E_NOOBJECT);
00275 klass=classof(receiver);
00276 meth=findmethod(ctx,selector,klass, &curclass);
00277 if (meth==NIL) {
00278
00279 meth=findforward(ctx,selector,klass,receiver, &component, &curclass);
00280 if (meth!=NIL) { argv[0]=component; receiver=component; argoffset=2;}
00281 else {
00282 meth=findmethod(ctx,K_NOMETHOD,klass, &curclass);
00283 if (meth==NIL) error(E_NOMETHOD,selector);
00284 if (iscode(ccar(ccdr(meth)))) {
00285 altargv=ctx->vsp;
00286 vpush(receiver); vpush(selector);
00287 i=1;
00288 while (i<n) ckpush(argv[i++]);
00289 argv=altargv;
00290 n++;}
00291 else argoffset=1;} }
00292 else argoffset=2;
00293
00294 if (iscode(ccar(ccdr(meth)))) {
00295 argv[1]=curclass;
00296 result=funcode(ctx,ccar(ccdr(meth)),(pointer)argv,n);
00297 }
00298 else {
00299 bf=fastbind(ctx,classof(receiver)->c.cls.vars,receiver,NULL);
00300 #if SunOS4_1
00301 bf=fastbind(ctx,QSELF,receiver,bf);
00302 #else
00303 bf=fastbind(ctx,SELF,receiver,bf);
00304 #endif
00305 bf=fastbind(ctx,CLASS,curclass,bf);
00306 result=funlambda(ctx,ccar(meth),ccar(ccdr(meth)),ccdr(ccdr(meth)),
00307 &argv[argoffset],bf,n-argoffset);
00308 ctx->bindfp=bfsave;
00309
00310 unbindspecial(ctx,sbfpsave+1);
00311 }
00312 ctx->vsp=spsave;
00313 return(result);}
00314
00315 pointer SEND_IF_FOUND(ctx,n,argv)
00316 register context *ctx;
00317 int n;
00318 register pointer argv[];
00319 { register pointer receiver,klass,selector,meth,result;
00320 register pointer *spsave=ctx->vsp,*altargv;
00321 pointer curclass, component;
00322 struct bindframe *bf,*bfsave=ctx->bindfp;
00323 struct specialbindframe *sbfpsave=ctx->sbindfp;
00324 int argoffset;
00325
00326 if (n<3) error(E_MISMATCHARG);
00327 receiver=argv[1];
00328 selector=argv[2];
00329 if (isnum(receiver)) return(argv[0]);
00330 klass=classof(receiver);
00331 meth=findmethod(ctx,selector,klass, &curclass);
00332 if (meth==NIL) {
00333
00334 meth=findforward(ctx,selector,klass,receiver, &component, NULL);
00335 if (meth!=NIL) { argv[1]=component; receiver=component; argoffset=3;}
00336 else return(argv[0]); }
00337 else argoffset=3;
00338
00339 if (iscode(ccar(ccdr(meth)))) {
00340 argv[2]=curclass;
00341 result=funcode(ctx,ccar(ccdr(meth)), (pointer)&argv[1],n-1);
00342 }
00343 else {
00344 bf=fastbind(ctx,classof(receiver)->c.cls.vars,receiver,NULL);
00345 #if SunOS4_1
00346 bf=fastbind(ctx,QSELF,receiver,bf);
00347 #else
00348 bf=fastbind(ctx,SELF,receiver,bf);
00349 #endif
00350 bf=fastbind(ctx,CLASS,curclass,bf);
00351 result=funlambda(ctx,ccar(meth),ccar(ccdr(meth)),ccdr(ccdr(meth)),
00352 &argv[argoffset],bf,n-argoffset);
00353 ctx->bindfp=bfsave;
00354
00355 unbindspecial(ctx,sbfpsave+1);
00356 }
00357 ctx->vsp=spsave;
00358 #ifdef SAFETY
00359 take_care(result);
00360 #endif
00361 return(result);}
00362
00363 pointer SENDMESSAGE(ctx,n,argv)
00364 register context *ctx;
00365 int n;
00366 pointer argv[];
00367
00368 { pointer receiver,search,selector,meth,form,result,*spsave, curclass;
00369 struct bindframe *bf,*bfsave=ctx->bindfp;
00370 struct specialbindframe *sbfpsave=ctx->sbindfp;
00371
00372 if (n<3) error(E_MISMATCHARG);
00373 receiver=argv[0]; search=argv[1]; selector=argv[2];
00374 if (issymbol(search)) search=speval(search);
00375 if (search==UNBOUND || (!isclass(search) && !isvecclass(search)))
00376 error(E_NOCLASS,search);
00377
00378 meth=findmethod(ctx,selector,search, &curclass);
00379 if (meth==NIL) error(E_NOMETHOD);
00380 form=ctx->callfp->form;
00381 if (iscode(ccar(ccdr(meth)))) {
00382 argv[1]=receiver; argv[2]=curclass;
00383 result=ufuncall(ctx,form,ccar(ccdr(meth)),(pointer)&argv[1],NULL,n-1);}
00384 else {
00385 spsave=ctx->vsp;
00386 bf=fastbind(ctx,classof(receiver)->c.cls.vars,receiver,NULL);
00387 #if SunOS4_1
00388 bf=fastbind(ctx,QSELF,receiver,bf);
00389 #else
00390 bf=fastbind(ctx,SELF,receiver,bf);
00391 #endif
00392 bf=fastbind(ctx,CLASS,curclass,bf);
00393 result=ufuncall(ctx,form,meth,(pointer)&argv[3],bf,n-3);
00394 ctx->bindfp=bfsave;
00395
00396 unbindspecial(ctx,sbfpsave+1);
00397 ctx->vsp=spsave;}
00398 #ifdef SAFETY
00399 take_care(result);
00400 #endif
00401 return(result);}
00402
00403 pointer CLONE(ctx,n,argv)
00404 register context *ctx;
00405 int n;
00406 pointer argv[];
00407 { pointer a=argv[0],klass,x;
00408 register int i,s;
00409 int etype;
00410 ckarg(1);
00411 if (ispointer(a)) {
00412 klass=classof(a);
00413 if (isvecclass(klass)) {
00414 etype=intval(klass->c.vcls.elmtype);
00415 s=vecsize(a);
00416 switch(etype) {
00417 case ELM_BIT: n=(s+WORD_SIZE-1)/WORD_SIZE; break;
00418 case ELM_CHAR: case ELM_BYTE: n=(s+sizeof(eusinteger_t))/sizeof(eusinteger_t); break;
00419 default: n=s; break;}
00420 n++;
00421 x=makevector(klass,s);
00422 }
00423 else {
00424 n=vecsize(klass->c.cls.vars);
00425 x=makeobject(klass);}
00426 for (i=0; i<n; i++) x->c.obj.iv[i]=a->c.obj.iv[i];
00427 #ifdef SAFETY
00428 take_care(x);
00429 #endif
00430 return(x);}
00431 else error(E_INSTANTIATE);}
00432
00433 pointer METHCACHE(ctx,n,argv)
00434 register context *ctx;
00435 int n;
00436 pointer argv[];
00437 {
00438 register int i;
00439 if (n==1) {
00440 trycache=(argv[0]!=NIL);
00441 for (i=0; i<MAXMETHCACHE; i++) {
00442 pointer_update(ctx->methcache[i].class,NIL);
00443 pointer_update(ctx->methcache[i].selector,NIL);
00444 }
00445 }
00446 #ifdef SAFETY
00447 {
00448 pointer tmp = cons(ctx,makeint(mchit),cons(ctx,makeint(mcmiss),NIL));
00449 take_care(tmp);
00450 return(tmp);
00451 }
00452 #else
00453 return(cons(ctx,makeint(mchit),cons(ctx,makeint(mcmiss),NIL)));
00454 #endif
00455 }
00456
00457 pointer FINDMETHOD(ctx,n,argv)
00458 register context *ctx;
00459 int n;
00460 pointer argv[];
00461 { pointer a;
00462 pointer curclass;
00463 ckarg(2);
00464 a=argv[0];
00465 if (isnum(a)) error(E_NOOBJECT);
00466 a=findmethod(ctx,argv[1],classof(a), &curclass);
00467 if (a!=NIL) a=cons(ctx,curclass,cons(ctx,a,NIL));
00468 #ifdef SAFETY
00469 take_care(a);
00470 #endif
00471 return(a);}
00472
00473 int getslotindex(obj,klass,varid)
00474 register pointer obj,klass,varid;
00475 {
00476 register int objcix,klasscix,index;
00477 register pointer vvec;
00478 extern pointer equal();
00479
00480 if (!isclass(klass)) error(E_NOCLASS,klass);
00481 objcix=obj->cix;
00482 klasscix=intval(klass->c.cls.cix);
00483 if (objcix>=klasscix && objcix<=classtab[klasscix].subcix) {
00484 vvec=klass->c.cls.vars;
00485 if (isint(varid)) index=intval(varid);
00486 else if (issymbol(varid)) {
00487 index=0;
00488 while (index<vecsize(vvec))
00489 if (vvec->c.vec.v[index]==varid) break; else index++;}
00490 else if (isstring(varid)) {
00491 index=0;
00492 while (index<vecsize(vvec))
00493 if (equal(vvec->c.vec.v[index]->c.sym.pname, varid)==T) break;
00494 else index++;}
00495 else error(E_NOINT);
00496 if (index>=vecsize(vvec)) error(E_NOOBJVAR,varid);
00497 return(index);}
00498 else error(E_NOOBJVAR,varid);}
00499
00500 pointer SLOT(ctx,n,argv)
00501 register context *ctx;
00502 register int n;
00503 register pointer argv[];
00504 { register pointer a;
00505 ckarg(3);
00506 n=getslotindex(argv[0],argv[1],argv[2]);
00507 a=argv[0]->c.obj.iv[n];
00508 if (a==UNBOUND) return(QUNBOUND);
00509 else return(a);}
00510
00511 pointer SETSLOT(ctx,n,argv)
00512 register context *ctx;
00513 register int n;
00514 register pointer argv[];
00515 { ckarg(4);
00516 n=getslotindex(argv[0],argv[1],argv[2]);
00517 pointer_update(argv[0]->c.obj.iv[n],argv[3]);
00518 return(argv[3]);}
00519
00520
00521 pointer CONSCAR(ctx,n,argv)
00522 register context *ctx;
00523 int n;
00524 pointer argv[];
00525 { pointer self=argv[0];
00526 if (n>=3) pointer_update(self->c.cons.car,argv[2]);
00527 return(self->c.cons.car);}
00528
00529 pointer CONSCDR(ctx,n,argv)
00530 register context *ctx;
00531 int n;
00532 pointer argv[];
00533 { pointer self=argv[0];
00534 if (n>=3) pointer_update(self->c.cons.cdr,argv[2]);
00535 return(self->c.cons.cdr);}
00536
00537
00538
00539
00540
00541 #define p_marked(p) (bpointerof(p)->h.pmark)
00542 #define p_mark_on(p) (bpointerof(p)->h.pmark=1)
00543 #define p_mark_off(p) (bpointerof(p)->h.pmark=0)
00544
00545 static pointer *cpvec;
00546 static int cpx;
00547 static jmp_buf cpyjmp;
00548
00549 pointer copyobj(ctx,org)
00550 register context *ctx;
00551 register pointer org;
00552 { register pointer clone;
00553 pointer klass,x;
00554 register int i,s;
00555 int etype;
00556
00557 if (isnum(org) || issymbol(org) || isclass(org)) return(org);
00558
00559 x=org->c.obj.iv[1];
00560 if (p_marked(org)) return(cpvec[intval(x)]);
00561 p_mark_on(org);
00562 klass=classof(org);
00563 if (isvecclass(klass)) {
00564 etype=elmtypeof(org);
00565 s=vecsize(org);
00566 clone=makevector(klass,s);
00567 elmtypeof(clone)=etype;
00568 switch(etype) {
00569 case ELM_BIT: s=(s+WORD_SIZE-1)/WORD_SIZE; break;
00570 case ELM_BYTE: case ELM_CHAR: s=(s+sizeof(eusinteger_t))/sizeof(eusinteger_t); break;
00571 case ELM_FOREIGN: s=1; break; }}
00572 else {
00573 etype=ELM_FIXED;
00574 s=objsize(org);
00575 clone=(pointer)makeobject(klass);}
00576
00577 if (ctx->vsp>ctx->stacklimit)
00578 { p_mark_off(org);
00579 fprintf(stderr,"cannot copy\n"); euslongjmp(cpyjmp,ERR);}
00580 #ifdef RGC
00581 if (etype == ELM_FIXED || etype == ELM_POINTER) {
00582 pointer_update(org->c.obj.iv[1],makeint(cpx));
00583 } else {
00584 org->c.obj.iv[1] = makeint(cpx);
00585 }
00586 #else
00587 pointer_update(org->c.obj.iv[1],makeint(cpx));
00588 #endif
00589 vpush(clone);
00590 vpush(x);
00591 cpx += 2;
00592 switch (etype) {
00593 case ELM_FIXED:
00594 clone->c.obj.iv[1]=copyobj(ctx,x);
00595 if (s>0) clone->c.obj.iv[0]=copyobj(ctx,org->c.obj.iv[0]);
00596 for (i=2; i<s; i++) clone->c.obj.iv[i]=copyobj(ctx,org->c.obj.iv[i]);
00597 break;
00598 case ELM_POINTER:
00599 clone->c.vec.v[0]=copyobj(ctx,x);
00600 for (i=1; i<s; i++) clone->c.vec.v[i]=copyobj(ctx,org->c.vec.v[i]);
00601 break;
00602 default:
00603 clone->c.vec.v[0]=x;
00604 for (i=1; i<s; i++) clone->c.ivec.iv[i]=org->c.ivec.iv[i];
00605 break;}
00606 #ifdef SAFETY
00607 take_care(clone);
00608 #endif
00609 return(clone);}
00610
00611 void copyunmark(obj)
00612 register pointer obj;
00613 { pointer x,klass;
00614 register int i,s;
00615
00616 if (isnum(obj) || pissymbol(obj) || pisclass(obj)) return;
00617 x=obj->c.obj.iv[1];
00618 if (p_marked(obj)) {
00619 pointer_update(obj->c.obj.iv[1],cpvec[intval(x)+1]);
00620 p_mark_off(obj);
00621 if (pisvector(obj)) {
00622 if (elmtypeof(obj)<ELM_POINTER) return;
00623 s=vecsize(obj);
00624 for (i=0; i<s; i++) copyunmark(obj->c.vec.v[i]); }
00625 else {
00626 s=objsize(obj);
00627 for (i=0; i<s; i++) copyunmark(obj->c.obj.iv[i]); }
00628 }
00629 }
00630
00631 pointer COPYOBJ(ctx,n,argv)
00632 register context *ctx;
00633 int n;
00634 pointer argv[];
00635 { pointer a=argv[0],b;
00636 pointer *spsave=ctx->vsp;
00637 ckarg(1);
00638 #if THREADED
00639 mutex_lock(&mark_lock);
00640 #endif
00641 cpx=0;
00642 cpvec= ctx->vsp;
00643 if ((b=(pointer)eussetjmp(cpyjmp))==0) b=copyobj(ctx,a);
00644 copyunmark(a);
00645 ctx->vsp=spsave;
00646 #if THREADED
00647 mutex_unlock(&mark_lock);
00648 #endif
00649 ctx->vsp=spsave;
00650 if (b==(pointer)ERR) error(E_USER,(pointer)"too big to copy");
00651 else return(b);
00652 }
00653
00654 pointer BECOME(ctx,n,argv)
00655 register context *ctx;
00656 int n;
00657 register pointer argv[];
00658 { int e1,e2, newsize;
00659 ckarg(2);
00660 if (isnum(argv[0])) error(E_NOOBJECT);
00661 if (isvecclass(argv[1])) {
00662 e1=elmtypeof(argv[0]); e2=intval(argv[1]->c.vcls.elmtype);
00663 if (e1==ELM_FIXED) error(E_USER,(pointer)"a record type object cannot become a vector");
00664 if (e1==ELM_POINTER && e1!=e2) error(E_USER,(pointer)"element type mismatch");
00665
00666 n=vecsize(argv[0]);
00667 switch(e1) {
00668 case ELM_BIT: switch(e2) {
00669 case ELM_CHAR: case ELM_BYTE: n=(n+7)/8; break;
00670 case ELM_BIT: break;
00671 default: n=(n+WORD_SIZE-1)/WORD_SIZE; break;} break;
00672 case ELM_CHAR: case ELM_BYTE:
00673 switch(e2) {
00674 case ELM_CHAR: case ELM_BYTE: break;
00675 case ELM_BIT: n*=8; break;
00676 default: n=(n+sizeof(eusinteger_t)-1)/sizeof(eusinteger_t); break;} break;
00677 default: switch(e2) {
00678 case ELM_CHAR: case ELM_BYTE: n*=sizeof(pointer); break;
00679 case ELM_BIT: n*=WORD_SIZE; break;
00680 default: break;} break; }
00681 argv[0]->c.vec.size=makeint(n);
00682
00683 argv[0]->cix=intval(argv[1]->c.vcls.cix);
00684 elmtypeof(argv[0])=e2;
00685 return(argv[0]);}
00686 else if (isint(argv[1])) {
00687 newsize=ckintval(argv[1]);
00688
00689 switch(elmtypeof(argv[0])) {
00690 case ELM_BIT: n=(newsize+WORD_SIZE-1)/WORD_SIZE; break;
00691 case ELM_BYTE: case ELM_CHAR:
00692 n=(newsize+(WORD_SIZE/8)-1)/(WORD_SIZE/8); break;
00693 default: n=newsize; }
00694 if (buddysize[bixof(argv[0])]>=n+2) argv[0]->c.vec.size=makeint(newsize);
00695 else error(E_ARRAYINDEX);
00696 return(argv[0]);
00697 }
00698 else error(E_USER,(pointer)"vector class or number expected");
00699 }
00700
00701 pointer REPLACEOBJECT(ctx,n,argv)
00702 register context *ctx;
00703 register int n;
00704 pointer argv[];
00705 { register pointer dest=argv[0],src=argv[1];
00706 int nsrc,ndest;
00707 ckarg(2);
00708 if (isnum(src) || isnum(dest)) return(src);
00709 nsrc=objsize(src); ndest=objsize(dest);
00710 n=min(nsrc,ndest);
00711 while (n-->0) pointer_update(dest->c.obj.iv[n],src->c.obj.iv[n]);
00712 return(dest);}
00713
00714 void leo(ctx,mod)
00715 register context *ctx;
00716 pointer mod;
00717 {
00718 defun(ctx,"CLASS",mod,GETCLASS);
00719 defun(ctx,"ENTER-CLASS",mod,ENTERCLASS);
00720
00721 defspecial(ctx,"DEFMETHOD",mod,DEFMETHOD);
00722 defun(ctx,"SEND",mod,SEND);
00723 defun(ctx,"SEND-MSG",mod,SEND);
00724 defun(ctx,"SEND-IF-FOUND",mod,SEND_IF_FOUND);
00725 defun(ctx,"SEND-MESSAGE",mod,SENDMESSAGE);
00726 defun(ctx,"INSTANTIATE",mod,INSTANTIATE);
00727 defun(ctx,"CLASSP",mod,CLASSP);
00728 defun(ctx,"SUBCLASSP",mod,SUBCLASSP);
00729 defun(ctx,"DERIVEDP",mod,DERIVEDP);
00730 defun(ctx,"CLONE",mod,CLONE);
00731 defun(ctx,"SLOT",mod,SLOT);
00732 defun(ctx,"SETSLOT",mod,SETSLOT);
00733 defun(ctx,"FIND-METHOD",mod,FINDMETHOD);
00734 defunpkg(ctx,"METHOD-CACHE",mod,METHCACHE,syspkg);
00735 addcmethod(ctx,mod,CONSCAR,defkeyword(ctx,"CAR"),QCONS,NIL);
00736 addcmethod(ctx,mod,CONSCDR,defkeyword(ctx,"CDR"),QCONS,NIL);
00737 defun(ctx,"COPY-OBJECT",mod,COPYOBJ);
00738 defun(ctx,"BECOME",mod,BECOME);
00739 defun(ctx,"REPLACE-OBJECT",mod,REPLACEOBJECT);
00740 }
00741