1*74a4d8c2SCharles.Forsyth #include "u.h"
2*74a4d8c2SCharles.Forsyth #include "../port/lib.h"
3*74a4d8c2SCharles.Forsyth #include "mem.h"
4*74a4d8c2SCharles.Forsyth #include "dat.h"
5*74a4d8c2SCharles.Forsyth #include "fns.h"
6*74a4d8c2SCharles.Forsyth #include "../port/error.h"
7*74a4d8c2SCharles.Forsyth #include "interp.h"
8*74a4d8c2SCharles.Forsyth #include "isa.h"
9*74a4d8c2SCharles.Forsyth #include "runt.h"
10*74a4d8c2SCharles.Forsyth #include "kernel.h"
11*74a4d8c2SCharles.Forsyth #include "raise.h"
12*74a4d8c2SCharles.Forsyth
13*74a4d8c2SCharles.Forsyth static int
ematch(char * pat,char * exp)14*74a4d8c2SCharles.Forsyth ematch(char *pat, char *exp)
15*74a4d8c2SCharles.Forsyth {
16*74a4d8c2SCharles.Forsyth int l;
17*74a4d8c2SCharles.Forsyth
18*74a4d8c2SCharles.Forsyth if(strcmp(pat, exp) == 0)
19*74a4d8c2SCharles.Forsyth return 1;
20*74a4d8c2SCharles.Forsyth
21*74a4d8c2SCharles.Forsyth l = strlen(pat);
22*74a4d8c2SCharles.Forsyth if(l == 0)
23*74a4d8c2SCharles.Forsyth return 0;
24*74a4d8c2SCharles.Forsyth if(pat[l-1] == '*') {
25*74a4d8c2SCharles.Forsyth if(l == 1)
26*74a4d8c2SCharles.Forsyth return 1;
27*74a4d8c2SCharles.Forsyth if(strncmp(pat, exp, l-1) == 0)
28*74a4d8c2SCharles.Forsyth return 1;
29*74a4d8c2SCharles.Forsyth }
30*74a4d8c2SCharles.Forsyth return 0;
31*74a4d8c2SCharles.Forsyth }
32*74a4d8c2SCharles.Forsyth
33*74a4d8c2SCharles.Forsyth static void
setstr(String * s,char * p)34*74a4d8c2SCharles.Forsyth setstr(String *s, char *p)
35*74a4d8c2SCharles.Forsyth {
36*74a4d8c2SCharles.Forsyth if(s == H)
37*74a4d8c2SCharles.Forsyth return;
38*74a4d8c2SCharles.Forsyth if(s->len < 0 || s->max < 4)
39*74a4d8c2SCharles.Forsyth return;
40*74a4d8c2SCharles.Forsyth kstrcpy(s->Sascii, p, s->max); /* TO DO: we are assuming they aren't runes */
41*74a4d8c2SCharles.Forsyth s->len = strlen(s->Sascii);
42*74a4d8c2SCharles.Forsyth }
43*74a4d8c2SCharles.Forsyth
44*74a4d8c2SCharles.Forsyth static String *exstr;
45*74a4d8c2SCharles.Forsyth
46*74a4d8c2SCharles.Forsyth void
excinit(void)47*74a4d8c2SCharles.Forsyth excinit(void)
48*74a4d8c2SCharles.Forsyth {
49*74a4d8c2SCharles.Forsyth exstr = newstring(ERRMAX);
50*74a4d8c2SCharles.Forsyth poolimmutable(D2H(exstr));
51*74a4d8c2SCharles.Forsyth }
52*74a4d8c2SCharles.Forsyth
53*74a4d8c2SCharles.Forsyth static String*
newestring(char * estr)54*74a4d8c2SCharles.Forsyth newestring(char *estr)
55*74a4d8c2SCharles.Forsyth {
56*74a4d8c2SCharles.Forsyth String *s;
57*74a4d8c2SCharles.Forsyth
58*74a4d8c2SCharles.Forsyth if(waserror()){
59*74a4d8c2SCharles.Forsyth setstr(exstr, estr);
60*74a4d8c2SCharles.Forsyth D2H(exstr)->ref++;
61*74a4d8c2SCharles.Forsyth return exstr;
62*74a4d8c2SCharles.Forsyth }
63*74a4d8c2SCharles.Forsyth s = c2string(estr, strlen(estr));
64*74a4d8c2SCharles.Forsyth poperror();
65*74a4d8c2SCharles.Forsyth return s;
66*74a4d8c2SCharles.Forsyth }
67*74a4d8c2SCharles.Forsyth
68*74a4d8c2SCharles.Forsyth #define NOPC 0xffffffff
69*74a4d8c2SCharles.Forsyth
70*74a4d8c2SCharles.Forsyth #define FRTYPE(f) ((f)->t == nil ? SEXTYPE(f)->reg.TR : (f)->t)
71*74a4d8c2SCharles.Forsyth
72*74a4d8c2SCharles.Forsyth /*
73*74a4d8c2SCharles.Forsyth * clear up an uncalled frame
74*74a4d8c2SCharles.Forsyth */
75*74a4d8c2SCharles.Forsyth static void
freeframe(uchar * fp,int setsp)76*74a4d8c2SCharles.Forsyth freeframe(uchar *fp, int setsp)
77*74a4d8c2SCharles.Forsyth {
78*74a4d8c2SCharles.Forsyth Frame *f;
79*74a4d8c2SCharles.Forsyth
80*74a4d8c2SCharles.Forsyth f = (Frame*)fp;
81*74a4d8c2SCharles.Forsyth if(f->t == nil)
82*74a4d8c2SCharles.Forsyth unextend(f);
83*74a4d8c2SCharles.Forsyth else if(f->t->np)
84*74a4d8c2SCharles.Forsyth freeptrs(f, f->t);
85*74a4d8c2SCharles.Forsyth if(setsp)
86*74a4d8c2SCharles.Forsyth R.SP = fp;
87*74a4d8c2SCharles.Forsyth }
88*74a4d8c2SCharles.Forsyth
89*74a4d8c2SCharles.Forsyth int
handler(char * estr)90*74a4d8c2SCharles.Forsyth handler(char *estr)
91*74a4d8c2SCharles.Forsyth {
92*74a4d8c2SCharles.Forsyth Prog *p;
93*74a4d8c2SCharles.Forsyth Modlink *m, *mr;
94*74a4d8c2SCharles.Forsyth int str, ne;
95*74a4d8c2SCharles.Forsyth ulong pc, newpc;
96*74a4d8c2SCharles.Forsyth long eoff;
97*74a4d8c2SCharles.Forsyth uchar *fp, **eadr;
98*74a4d8c2SCharles.Forsyth Frame *f;
99*74a4d8c2SCharles.Forsyth Type *t, *zt;
100*74a4d8c2SCharles.Forsyth Handler *h;
101*74a4d8c2SCharles.Forsyth Except *e;
102*74a4d8c2SCharles.Forsyth void *v;
103*74a4d8c2SCharles.Forsyth
104*74a4d8c2SCharles.Forsyth p = currun();
105*74a4d8c2SCharles.Forsyth if(*estr == 0 || p == nil)
106*74a4d8c2SCharles.Forsyth return 0;
107*74a4d8c2SCharles.Forsyth str = p->exval == H || D2H(p->exval)->t == &Tstring;
108*74a4d8c2SCharles.Forsyth m = R.M;
109*74a4d8c2SCharles.Forsyth if(m->compiled)
110*74a4d8c2SCharles.Forsyth pc = (ulong)R.PC-(ulong)m->prog;
111*74a4d8c2SCharles.Forsyth else
112*74a4d8c2SCharles.Forsyth pc = R.PC-m->prog;
113*74a4d8c2SCharles.Forsyth pc--;
114*74a4d8c2SCharles.Forsyth fp = R.FP;
115*74a4d8c2SCharles.Forsyth while(fp != nil){ /* look for a handler */
116*74a4d8c2SCharles.Forsyth if((h = m->m->htab) != nil){
117*74a4d8c2SCharles.Forsyth for( ; h->etab != nil; h++){
118*74a4d8c2SCharles.Forsyth if(pc < h->pc1 || pc >= h->pc2)
119*74a4d8c2SCharles.Forsyth continue;
120*74a4d8c2SCharles.Forsyth eoff = h->eoff;
121*74a4d8c2SCharles.Forsyth zt = h->t;
122*74a4d8c2SCharles.Forsyth for(e = h->etab, ne = h->ne; e->s != nil; e++, ne--){
123*74a4d8c2SCharles.Forsyth if(ematch(e->s, estr) && (str && ne <= 0 || !str && ne > 0)){
124*74a4d8c2SCharles.Forsyth newpc = e->pc;
125*74a4d8c2SCharles.Forsyth goto found;
126*74a4d8c2SCharles.Forsyth }
127*74a4d8c2SCharles.Forsyth }
128*74a4d8c2SCharles.Forsyth newpc = e->pc;
129*74a4d8c2SCharles.Forsyth if(newpc != NOPC)
130*74a4d8c2SCharles.Forsyth goto found;
131*74a4d8c2SCharles.Forsyth }
132*74a4d8c2SCharles.Forsyth }
133*74a4d8c2SCharles.Forsyth if(!str && fp != R.FP){ /* becomes a string exception in immediate caller */
134*74a4d8c2SCharles.Forsyth v = p->exval;
135*74a4d8c2SCharles.Forsyth p->exval = *(String**)v;
136*74a4d8c2SCharles.Forsyth D2H(p->exval)->ref++;
137*74a4d8c2SCharles.Forsyth destroy(v);
138*74a4d8c2SCharles.Forsyth str = 1;
139*74a4d8c2SCharles.Forsyth continue;
140*74a4d8c2SCharles.Forsyth }
141*74a4d8c2SCharles.Forsyth f = (Frame*)fp;
142*74a4d8c2SCharles.Forsyth if(f->mr != nil)
143*74a4d8c2SCharles.Forsyth m = f->mr;
144*74a4d8c2SCharles.Forsyth if(m->compiled)
145*74a4d8c2SCharles.Forsyth pc = (ulong)f->lr-(ulong)m->prog;
146*74a4d8c2SCharles.Forsyth else
147*74a4d8c2SCharles.Forsyth pc = f->lr-m->prog;
148*74a4d8c2SCharles.Forsyth pc--;
149*74a4d8c2SCharles.Forsyth fp = f->fp;
150*74a4d8c2SCharles.Forsyth }
151*74a4d8c2SCharles.Forsyth destroy(p->exval);
152*74a4d8c2SCharles.Forsyth p->exval = H;
153*74a4d8c2SCharles.Forsyth return 0;
154*74a4d8c2SCharles.Forsyth found:
155*74a4d8c2SCharles.Forsyth {
156*74a4d8c2SCharles.Forsyth int n;
157*74a4d8c2SCharles.Forsyth char name[3*KNAMELEN];
158*74a4d8c2SCharles.Forsyth
159*74a4d8c2SCharles.Forsyth pc = modstatus(&R, name, sizeof(name));
160*74a4d8c2SCharles.Forsyth n = 10+1+strlen(name)+1+strlen(estr)+1;
161*74a4d8c2SCharles.Forsyth p->exstr = realloc(p->exstr, n);
162*74a4d8c2SCharles.Forsyth if(p->exstr != nil)
163*74a4d8c2SCharles.Forsyth snprint(p->exstr, n, "%lud %s %s", pc, name, estr);
164*74a4d8c2SCharles.Forsyth }
165*74a4d8c2SCharles.Forsyth
166*74a4d8c2SCharles.Forsyth /*
167*74a4d8c2SCharles.Forsyth * there may be an uncalled frame at the top of the stack
168*74a4d8c2SCharles.Forsyth */
169*74a4d8c2SCharles.Forsyth f = (Frame*)R.FP;
170*74a4d8c2SCharles.Forsyth t = FRTYPE(f);
171*74a4d8c2SCharles.Forsyth if(R.FP < R.EX || R.FP >= R.TS)
172*74a4d8c2SCharles.Forsyth freeframe(R.EX+OA(Stkext, reg.tos.fr), 0);
173*74a4d8c2SCharles.Forsyth else if(R.FP+t->size < R.SP)
174*74a4d8c2SCharles.Forsyth freeframe(R.FP+t->size, 1);
175*74a4d8c2SCharles.Forsyth
176*74a4d8c2SCharles.Forsyth m = R.M;
177*74a4d8c2SCharles.Forsyth while(R.FP != fp){
178*74a4d8c2SCharles.Forsyth f = (Frame*)R.FP;
179*74a4d8c2SCharles.Forsyth R.PC = f->lr;
180*74a4d8c2SCharles.Forsyth R.FP = f->fp;
181*74a4d8c2SCharles.Forsyth R.SP = (uchar*)f;
182*74a4d8c2SCharles.Forsyth mr = f->mr;
183*74a4d8c2SCharles.Forsyth if(f->t == nil)
184*74a4d8c2SCharles.Forsyth unextend(f);
185*74a4d8c2SCharles.Forsyth else if(f->t->np)
186*74a4d8c2SCharles.Forsyth freeptrs(f, f->t);
187*74a4d8c2SCharles.Forsyth if(mr != nil){
188*74a4d8c2SCharles.Forsyth m = mr;
189*74a4d8c2SCharles.Forsyth destroy(R.M);
190*74a4d8c2SCharles.Forsyth R.M = m;
191*74a4d8c2SCharles.Forsyth R.MP = m->MP;
192*74a4d8c2SCharles.Forsyth }
193*74a4d8c2SCharles.Forsyth }
194*74a4d8c2SCharles.Forsyth if(zt != nil){
195*74a4d8c2SCharles.Forsyth freeptrs(fp, zt);
196*74a4d8c2SCharles.Forsyth initmem(zt, fp);
197*74a4d8c2SCharles.Forsyth }
198*74a4d8c2SCharles.Forsyth eadr = (uchar**)(fp+eoff);
199*74a4d8c2SCharles.Forsyth destroy(*eadr);
200*74a4d8c2SCharles.Forsyth *eadr = H;
201*74a4d8c2SCharles.Forsyth if(p->exval == H)
202*74a4d8c2SCharles.Forsyth *eadr = (uchar*)newestring(estr); /* might fail */
203*74a4d8c2SCharles.Forsyth else{
204*74a4d8c2SCharles.Forsyth D2H(p->exval)->ref++;
205*74a4d8c2SCharles.Forsyth *eadr = p->exval;
206*74a4d8c2SCharles.Forsyth }
207*74a4d8c2SCharles.Forsyth if(m->compiled)
208*74a4d8c2SCharles.Forsyth R.PC = (Inst*)((ulong)m->prog+newpc);
209*74a4d8c2SCharles.Forsyth else
210*74a4d8c2SCharles.Forsyth R.PC = m->prog+newpc;
211*74a4d8c2SCharles.Forsyth memmove(&p->R, &R, sizeof(R));
212*74a4d8c2SCharles.Forsyth p->kill = nil;
213*74a4d8c2SCharles.Forsyth destroy(p->exval);
214*74a4d8c2SCharles.Forsyth p->exval = H;
215*74a4d8c2SCharles.Forsyth return 1;
216*74a4d8c2SCharles.Forsyth }
217