|
|
1.1 root 1: static char sccsid[] = "@(#)proc.c 2.8";
2:
3: #include <setjmp.h>
4: #ifndef REGULUS
5:
6: #ifdef BSD42
7: #include <machine/reg.h>
8: #else
9: #include <sys/reg.h>
10: #endif
11:
12: #endif
13: #include "macdefs.h"
14: #include "cdb.h"
15:
16: export ADRT vadrBreak; /* the place we break at when doing proc calls */
17: export ADRT vadrCall; /* location of call instruction in _end_ */
18: export int vcNestProc; /* nesting depth of proc's from cmd line */
19:
20:
21: /* D O P R O C */
22:
23: export long DoProc(ipd, rgTy, adr)
24: int ipd;
25: pTYR rgTy;
26: ADRT adr;
27: {
28: short sigSave, iarg, iargMac, ibp;
29: long isym, result, reg, rgArgs[20];
30: char *sbProc, sbSave[50];
31: pTYR ty;
32: TKE tk;
33: TYR rgTyLoc[cTyMax];
34: REGT regs[uregMax];
35: int *envSave;
36: jmp_buf envProc;
37: STUFFU stuff;
38:
39: if (vpid == pidNil) {
40: /* we have no child! we will start one - may not be correct */
41: ibp = IbpFNewChild(vsbArgsChild);
42: if (ibp != ibpNil) {
43: /* this is obscure. We have a break point on the
44: * first line of the program. In this case we MUST
45: * ignore it and throw away any commands associated
46: * with it. Otherwise, we would screw up the state
47: * of the expression evaluator.
48: */
49: vsbCmd = PopCmd();
50: }
51: } /* if */
52:
53: if (setjmp(envProc)==0) {
54: /* save register values and prepare for errors */
55: envSave = venv;
56: sigSave = vsig;
57: venv = envProc;
58: SaveRegs(regs);
59: }
60: else {
61: /* error city, wonder what went wrong??? */
62: RestoreRegs(regs);
63: vsig = sigSave;
64: venv = envSave;
65: if (--vcNestProc == 0)
66: FClearBp(vadrBreak);
67: return(0L);
68: } /* if */
69:
70: if (ipd != ipdNil) {
71: /* a 'known procedure' */
72: isym = vrgPd[ipd].isym;
73: adr = vrgPd[ipd].adrStart;
74: sbProc = vrgPd[ipd].sbProc;
75: }
76: else {
77: /* a label-type procedure call */
78: isym = -1;
79: LabelFAdr(adr);
80: #ifdef BSD41
81: strcpy(sbSave, SbInCore(vsymCur->sbSym));
82: #else
83: strncpy(sbSave, SbInCore(vsymCur->sbSym), 8);
84: #endif
85: sbProc = (sbSave[0] == '_') ? sbSave+1 : sbSave;
86: } /* if */
87: iargMac = 0;
88:
89: /* so far, we have eaten `procname(' */
90: /* eat the arguments */
91: if ((tk = TkPeek()) == tkRP)
92: tk = TkNext(); /* acutally eat the ')' */
93: while (tk != tkRP) {
94: rgArgs[iargMac] = GetExpr(&ty, vtk);
95: if (ty == tyNil)
96: UError("Bad expression in proc call: %s", vsbCmd);
97: if (isym != -1) {
98: SetSym(isym);
99: if (FNextLocal(false, true, sbNil)) {
100: isym = visym; /* remember where we are */
101: TyFLocal(rgTyLoc, SbInCore(vsymCur->sbSym+1), isym);
102: }
103: else {
104: CopyTy(rgTyLoc, ty);
105: } /* if */
106: }
107: else {
108: CopyTy(rgTyLoc, ty);
109: } /* if */
110: CopyTy(rgTy+iargMac, rgTyLoc);
111: iargMac++;
112: tk = vtk;
113: if (tk != tkComma)
114: break;
115: } /* while */
116:
117: if (isym != -1) {
118: SetSym(isym);/* point at symbol after what we just ate */
119: if (FNextLocal(false, true, sbNil)) {
120: printf("WARNING: too few parameters: ");
121: DispFrame(adrNil, ipd, adrNil, adrNil, -1, false, false);
122: } /* if */
123: } /* if */
124:
125: for (iarg = iargMac-1; iarg >= 0; iarg--) { /* push in reverse order */
126: /* there is a problem here when there is no .d file and
127: * the last arg is other than the size of an INT.
128: * see CbFLoc for the gory details.
129: */
130: /* MACHINE DEPENDENT - BYTE SEX, SIZE */
131: vsp -= CBINT;
132: #ifdef TAHOE
133: PutWord(vsp, spaceData, rgArgs[iarg]);
134: #endif
135: #ifdef VAX
136: PutWord(vsp, spaceData, rgArgs[iarg]);
137: #endif
138: #ifdef SUN
139: PutWord(vsp, spaceData, rgArgs[iarg]);
140: #endif
141: #ifdef ONYX
142: stuff.lng = rgArgs[iarg];
143: PutWord(vsp, spaceData, stuff.shorts.shortLo); /* put low order word */
144: if (CbFTy(rgTy+iarg) == 4) {
145: vsp -= CBINT; /* a double word arg, put the high order one */
146: PutWord(vsp, spaceData, stuff.shorts.shortHi);
147: } /* if */
148: #endif
149: } /* for */
150:
151: vfp = 0;
152: #ifdef M68000
153: vsp -= CBPOINT;
154: /* we will pretend we are calling from location `_end_' */
155: PutBlock(vsp, spaceData, &vadrBreak, CBPOINT); /* return address */
156: vpc = adr;
157: #endif
158: #ifdef ONYX
159: vsp -= CBINT;
160: /* we will pretend we are calling from location `_end_' */
161: PutWord(vsp, spaceData, vadrBreak); /* return address */
162: vpc = adr;
163: #endif
164: #ifdef TAHOE
165: PutReg(u1, 4 + 4*iargMac);
166: /* argument counter (have to see Tahoe architecture to understand this) */
167: PutReg(u0, adr); /* callee's address in r0 */
168: vpc = vadrCall;
169: #endif
170: #ifdef VAX
171: PutReg(u1, iargMac); /* argument counter */
172: PutReg(u0, adr); /* callee's address in r0 */
173: vpc = vadrCall;
174: #endif
175: if (vcNestProc == 0)
176: ibp = IbpFAdr(vadrBreak, 1, "Q;q"); /* and set a break there */
177: vcNestProc++; /* count of proc call nesting */
178:
179: /* and away we go........ */
180: IbpFRun(ptResume);
181: while (ibp != vibp)
182: DebugIt(false);
183:
184: if (isym != -1) {
185: TyFLocal(rgTy, vrgPd[ipd].sbProc, vrgPd[ipd].isym);
186: }
187: else {
188: CopyTy(rgTy, vtyInt);
189: } /* if */
190:
191: if (4 == CbFTy(rgTy)) {
192: FAdrFSpecial("$long", rgTy, &adr);
193: result = ValFAdr(lengthen(adr), rgTy);
194: CopyTy(rgTy, vtyCnLong);
195: }
196: else {
197: FAdrFSpecial("$short", rgTy, &adr);
198: result = ValFAdr(lengthen(adr), rgTy);
199: CopyTy(rgTy, vtyCnShort);
200: }
201: #ifdef BSD41
202: rgTy[0].sbVar = bitHigh | (int)(sbProc);
203: /* what a CROCK!!!!! */
204: #else
205: strncpy(rgTy[0].sbVar, sbProc, 8);
206: #endif
207: if (--vcNestProc == 0)
208: FClearBp(vadrBreak);
209: RestoreRegs(regs);
210: vsig = sigSave;
211: venv = envSave; /* return to normal error handling */
212: return(result);
213: } /* DoProc */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.