|
|
Power 6/32 Unix version 1.2b
static char sccsid[] = "@(#)proc.c 2.8";
#include <setjmp.h>
#ifndef REGULUS
#ifdef BSD42
#include <machine/reg.h>
#else
#include <sys/reg.h>
#endif
#endif
#include "macdefs.h"
#include "cdb.h"
export ADRT vadrBreak; /* the place we break at when doing proc calls */
export ADRT vadrCall; /* location of call instruction in _end_ */
export int vcNestProc; /* nesting depth of proc's from cmd line */
/* D O P R O C */
export long DoProc(ipd, rgTy, adr)
int ipd;
pTYR rgTy;
ADRT adr;
{
short sigSave, iarg, iargMac, ibp;
long isym, result, reg, rgArgs[20];
char *sbProc, sbSave[50];
pTYR ty;
TKE tk;
TYR rgTyLoc[cTyMax];
REGT regs[uregMax];
int *envSave;
jmp_buf envProc;
STUFFU stuff;
if (vpid == pidNil) {
/* we have no child! we will start one - may not be correct */
ibp = IbpFNewChild(vsbArgsChild);
if (ibp != ibpNil) {
/* this is obscure. We have a break point on the
* first line of the program. In this case we MUST
* ignore it and throw away any commands associated
* with it. Otherwise, we would screw up the state
* of the expression evaluator.
*/
vsbCmd = PopCmd();
}
} /* if */
if (setjmp(envProc)==0) {
/* save register values and prepare for errors */
envSave = venv;
sigSave = vsig;
venv = envProc;
SaveRegs(regs);
}
else {
/* error city, wonder what went wrong??? */
RestoreRegs(regs);
vsig = sigSave;
venv = envSave;
if (--vcNestProc == 0)
FClearBp(vadrBreak);
return(0L);
} /* if */
if (ipd != ipdNil) {
/* a 'known procedure' */
isym = vrgPd[ipd].isym;
adr = vrgPd[ipd].adrStart;
sbProc = vrgPd[ipd].sbProc;
}
else {
/* a label-type procedure call */
isym = -1;
LabelFAdr(adr);
#ifdef BSD41
strcpy(sbSave, SbInCore(vsymCur->sbSym));
#else
strncpy(sbSave, SbInCore(vsymCur->sbSym), 8);
#endif
sbProc = (sbSave[0] == '_') ? sbSave+1 : sbSave;
} /* if */
iargMac = 0;
/* so far, we have eaten `procname(' */
/* eat the arguments */
if ((tk = TkPeek()) == tkRP)
tk = TkNext(); /* acutally eat the ')' */
while (tk != tkRP) {
rgArgs[iargMac] = GetExpr(&ty, vtk);
if (ty == tyNil)
UError("Bad expression in proc call: %s", vsbCmd);
if (isym != -1) {
SetSym(isym);
if (FNextLocal(false, true, sbNil)) {
isym = visym; /* remember where we are */
TyFLocal(rgTyLoc, SbInCore(vsymCur->sbSym+1), isym);
}
else {
CopyTy(rgTyLoc, ty);
} /* if */
}
else {
CopyTy(rgTyLoc, ty);
} /* if */
CopyTy(rgTy+iargMac, rgTyLoc);
iargMac++;
tk = vtk;
if (tk != tkComma)
break;
} /* while */
if (isym != -1) {
SetSym(isym);/* point at symbol after what we just ate */
if (FNextLocal(false, true, sbNil)) {
printf("WARNING: too few parameters: ");
DispFrame(adrNil, ipd, adrNil, adrNil, -1, false, false);
} /* if */
} /* if */
for (iarg = iargMac-1; iarg >= 0; iarg--) { /* push in reverse order */
/* there is a problem here when there is no .d file and
* the last arg is other than the size of an INT.
* see CbFLoc for the gory details.
*/
/* MACHINE DEPENDENT - BYTE SEX, SIZE */
vsp -= CBINT;
#ifdef TAHOE
PutWord(vsp, spaceData, rgArgs[iarg]);
#endif
#ifdef VAX
PutWord(vsp, spaceData, rgArgs[iarg]);
#endif
#ifdef SUN
PutWord(vsp, spaceData, rgArgs[iarg]);
#endif
#ifdef ONYX
stuff.lng = rgArgs[iarg];
PutWord(vsp, spaceData, stuff.shorts.shortLo); /* put low order word */
if (CbFTy(rgTy+iarg) == 4) {
vsp -= CBINT; /* a double word arg, put the high order one */
PutWord(vsp, spaceData, stuff.shorts.shortHi);
} /* if */
#endif
} /* for */
vfp = 0;
#ifdef M68000
vsp -= CBPOINT;
/* we will pretend we are calling from location `_end_' */
PutBlock(vsp, spaceData, &vadrBreak, CBPOINT); /* return address */
vpc = adr;
#endif
#ifdef ONYX
vsp -= CBINT;
/* we will pretend we are calling from location `_end_' */
PutWord(vsp, spaceData, vadrBreak); /* return address */
vpc = adr;
#endif
#ifdef TAHOE
PutReg(u1, 4 + 4*iargMac);
/* argument counter (have to see Tahoe architecture to understand this) */
PutReg(u0, adr); /* callee's address in r0 */
vpc = vadrCall;
#endif
#ifdef VAX
PutReg(u1, iargMac); /* argument counter */
PutReg(u0, adr); /* callee's address in r0 */
vpc = vadrCall;
#endif
if (vcNestProc == 0)
ibp = IbpFAdr(vadrBreak, 1, "Q;q"); /* and set a break there */
vcNestProc++; /* count of proc call nesting */
/* and away we go........ */
IbpFRun(ptResume);
while (ibp != vibp)
DebugIt(false);
if (isym != -1) {
TyFLocal(rgTy, vrgPd[ipd].sbProc, vrgPd[ipd].isym);
}
else {
CopyTy(rgTy, vtyInt);
} /* if */
if (4 == CbFTy(rgTy)) {
FAdrFSpecial("$long", rgTy, &adr);
result = ValFAdr(lengthen(adr), rgTy);
CopyTy(rgTy, vtyCnLong);
}
else {
FAdrFSpecial("$short", rgTy, &adr);
result = ValFAdr(lengthen(adr), rgTy);
CopyTy(rgTy, vtyCnShort);
}
#ifdef BSD41
rgTy[0].sbVar = bitHigh | (int)(sbProc);
/* what a CROCK!!!!! */
#else
strncpy(rgTy[0].sbVar, sbProc, 8);
#endif
if (--vcNestProc == 0)
FClearBp(vadrBreak);
RestoreRegs(regs);
vsig = sigSave;
venv = envSave; /* return to normal error handling */
return(result);
} /* DoProc */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.