|
|
1.1 root 1: #include "frame.pri"
2: #include "core.pub"
3: #include "symbol.h"
4: #include "symtab.pub"
5: #include "format.pub"
6: #include "expr.pub"
7: #include "phrase.pri"
8: #include "parse.h"
9: #include "process.pub"
10: #include "bpts.pub"
11: #include "journal.pub"
12: SRCFILE("frame.c")
13:
14: CallStk::CallStk(long s, Core *c)
15: {
16: fpf = new FpFrame[size = s];
17: core = c;
18: }
19:
20: CallStk::~CallStk()
21: {
22: delete fpf;
23: }
24:
25: Frame CallStk::frame(long l)
26: {
27: Frame f = core->frameabove(l==0 ? 0 : fpf[l-1].fp); // cfront bug
28: return f;
29: }
30:
31: Frame::Frame(Core *c) // cfront bug - c = 0
32: {
33: core = c;
34: level = 0;
35: fp = ap = pc = nargs = regsave = regbase = 0;
36: func = 0;
37: pad = 0;
38: phraset = 0;
39: }
40:
41: Frame::Frame() // cfront bug - c = 0
42: {
43: core = 0;
44: level = 0;
45: fp = ap = pc = nargs = regsave = regbase = 0;
46: func = 0;
47: pad = 0;
48: phraset = 0;
49: }
50:
51: void Frame::pop()
52: {
53: trace("%d.pop()", this); VOK;
54: core->process()->pop();
55: }
56:
57: SymTab *Frame::symtab() { OK(0); return core->symtab(); }
58:
59: int Frame::addsymbols()
60: {
61: trace("%d.addsymbols()", this); OK(0);
62: func = (Func*) symtab()->loctosym(U_FUNC, pc);
63: return func!=0;
64: }
65:
66: void Frame::hostclose()
67: {
68: Phrase *p, *psib;
69:
70: trace("%d.hostclose()", this); VOK;
71: if( pad ) delete pad;
72: pad = 0;
73: invalidate();
74: for( p = phraset; p; p = psib ){
75: psib = p->sib; // new malloc
76: p->expr->setspy(0); // why?
77: delete p;
78: }
79: }
80:
81: void Frame::banner()
82: {
83: Bls t;
84: trace("%d.banner()", this); VOK;
85: if( pad ){
86: pad->banner("%s:", text(t));
87: pad->name(func ? func->text() : "?()");
88: }
89: }
90:
91: void Frame::opencallersframe()
92: {
93: trace("%d.opencallersframe()", this); VOK;
94: Frame *c = caller();
95: if( c ) c->open();
96: }
97:
98: Frame *Frame::caller()
99: {
100: trace("%d.caller()", this); OK(0);
101: return core->process()->frame(level+1);
102: }
103:
104: void Frame::open(long svp)
105: {
106: Menu m;
107:
108: trace("%d.open()", this); VOK;
109: if( !pad ){
110: pad = new Pad( (PadRcv*) this );
111: if( func->stmt(pc) )
112: m.last( sf("src text",func->text()), (Action)&Frame::select );
113: if( core->process()->frame(level+1) )
114: m.last( "caller's frame", (Action) &Frame::opencallersframe );
115: m.last( "changed spies ", (Action)&Frame::changes, 1 );
116: m.last( varcarte() );
117: m.last( regcarte() );
118: pad->menu(m);
119: }
120: banner();
121: if( svp!=SVP ) pad->makecurrent();
122: }
123:
124: int Frame::changes(long verbose)
125: {
126: Phrase *p;
127: long changes = 0, key = 0x40000000, spies = 0;
128:
129: trace("%d.changes()", this); OK(0);
130:
131: for( p = phraset; p; p = p->sib )
132: if( p->expr->spy ){
133: Bls b;
134: ++spies;
135: if( p->changed(b) ){
136: ++changes;
137: core->process()->journal()->insert("%s",b.text);
138: }
139: }
140: if( verbose && pad ){
141: pad->removeline(key);
142: if( spies == 0 )
143: pad->insert( key, SELECTLINE, "no spies in this frame" );
144: else if( changes==0 )
145: pad->insert( key, SELECTLINE, "no spies changed" );
146: }
147: return changes;
148: }
149:
150: char *Frame::text(Bls &buf)
151: {
152: Var *arg;
153: Stmt *stmt = 0;
154:
155: trace("%d.text()", this); OK("Frame::text");
156: if( !func ) return sf( "pc=%d ?()", pc );
157: if( core->online() )
158: stmt = core->process()->bpts()->bptstmt(pc);
159: if( !stmt ) stmt = func->stmt(pc);
160: if( stmt )
161: buf.af("%s", stmt->text(pc));
162: else
163: buf.af( "%s+%d", func->_text, pc - func->range.lo );
164: buf.af(" %s(", func->_text);
165: for( int i = 1; arg = func->argument(i); ++i ){
166: if( i>1 ) buf.af(",");
167: E_Sym(arg)->evaltext(this,buf); // should use a stack expr
168: }
169: return buf.af( ")" );
170: }
171:
172: void Frame::select(long svp)
173: {
174: Stmt *stmt = 0;
175:
176: trace("%d.select(%d)", this, svp); VOK;
177: if( core->online() )
178: stmt = core->process()->bpts()->bptstmt(pc);
179: if( !stmt && func ) stmt = func->stmt(pc);
180: if( stmt ) stmt->select(svp);
181: }
182:
183: long Frame::saved(int r, int size) { return core->saved(this,r,size); }
184:
185: long Frame::regloc(int r, int size) /* what about r>=12 on vax ? */
186: {
187: if( !this ) return 0;
188: long loc = saved(r,size);
189: if( loc ) return loc;
190: if( level == 0 ) return core->regloc(r,size);
191: return core->process()->frame(level-1)->regloc(r,size);
192: }
193:
194: long Frame::locate(Var *v)
195: {
196: trace("%d.locate(%d) %s %d", this, v, v->_text, v->range.lo);
197: IF_LIVE( !v ) return 0;
198: switch( (int) v->disc() ){
199: case U_GLB:
200: case U_STA:
201: case U_FST:
202: case U_FUNC:
203: IF_LIVE(!v->range.lo) return 0; /* this == 0 */
204: return v->range.lo;
205: case U_ARG:
206: IF_LIVE(!this || !ap) return 0;
207: return ap+v->range.lo;
208: case U_AUT:
209: IF_LIVE(!this || !fp) return 0;
210: return fp+v->range.lo;
211: case U_REG:
212: IF_LIVE(!this) return 0;
213: if( level == 0 ) /* SAME AS CODE ABOVE! */
214: return core->regloc(v->range.lo, v->type.size_of());
215: return core->process()->frame(level-1)->regloc(v->range.lo, v->type.size_of());
216: }
217: IF_LIVE( 1 ) return 0;
218: }
219:
220: Cslfd *Frame::peek(long loc, Cslfd* fail)
221: {
222: trace("%d.peek(0x%X,%d)", this, loc, fail); OK(0);
223: return core->peek(loc, fail);
224: }
225:
226: char *Frame::special(char *id, long loc )
227: {
228: trace("%d.special(%s,0x%X)", this, id, loc); OK(0);
229: return core->special(id, loc);
230: }
231:
232: char *Frame::peekstring(long loc, char *fail)
233: {
234: trace("%d.peekstring(0x%X,%s)", this, loc, fail?fail:"0"); OK(0);
235: return core->peekstring(loc, fail);
236: }
237:
238: char *Frame::poke(long loc, long data, int bytes)
239: {
240: trace("%d.poke(0x%X,0x%X,%d)", this, loc, data, bytes); OK(0);
241: return core->poke(loc, data, bytes);
242: }
243:
244: char *Frame::pokedbl(long loc, double data, int bytes) /* broke float poke */
245: {
246: trace("%d.pokedbl(0x%X,%g,%d)", this, loc, data, bytes); OK(0);
247: return core->pokedbl(loc, data, bytes);
248: }
249:
250: char *Frame::blockmove(long s, long d, long ct)
251: {
252: trace("%d.blockmove(0x%X,0x%X,%d)", this, s, d, ct); OK("Frame::blockmove");
253: return core->blockmove(s, d, ct);
254: }
255:
256: char *Frame::help()
257: {
258: trace("%d.help()", this);
259: return "<expr> {evaluate in this scope}";
260: }
261:
262: char *Frame::kbd(char *s)
263: {
264: Parse y(G_EXPR,0);
265: Expr *e;
266: char *error;
267:
268: trace("%d.kbd(%s)", this, s); OK("kbd");
269: if( !(e = (Expr*)y.parse(s)) ){
270: pad->error( "%s: %s", y.error, s );
271: return 0;
272: }
273: if( error = makephrase(e) ) pad->error( "%s", error );
274: return 0;
275: }
276:
277: #define GAP 2
278: void Frame::freekey(long k)
279: {
280: Phrase *p;
281: int found = 0;
282:
283: trace("%d.freekey(%d)", this, k); VOK;
284: for( p = phraset; p; p = p->sib )
285: if( p->key >= k ){
286: p->key += GAP;
287: found = 1;
288: }
289: if( found ) pad->makegap(k,GAP);
290: }
291:
292: char *Frame::makephrase(Expr *e,long k)
293: {
294: Bls b;
295: Phrase *p;
296: char *error = 0;
297:
298: trace("%d.makephrase(%d,%d)", this, e, k); OK("Frame::makephrase");
299: if( !e ) return "not and expr";
300: if( !k ) k = UniqueKey();
301: for( p = phraset; p; p = p->sib )
302: if( p->key == k || p->expr == e) break;
303: if( !p ) phraset = p = new Phrase(this, phraset, e, k);
304: e->evaltext(this,b);
305: if( e->evalerr ){
306: Attrib a = ACCEPT_KBD;
307: switch( e->op ){
308: case O_TYPEOF: break;
309: case O_INDEX: if( e->sub2->op == O_RANGE ) break;
310: default:
311: pad->insert(p->key, a, (PadRcv*)p ,e->carte(0), "%s", e->text());
312: }
313: return sf( "%s", b.text );
314: }
315: Attrib a = ACCEPT_KBD|SELECTLINE;
316: if( e->spy ) a |= DONT_CUT;
317: pad->insert(p->key, a, (PadRcv*)p, e->carte(this), "%s", b.text);
318: return 0;
319:
320: }
321:
322: void Frame::pickvar(Var *v)
323: {
324: char *error;
325:
326: trace("%d.pickvar(%d)", this, v); VOK;
327: if( error = makephrase(E_Sym(v)) ) /* who owns this expr? */
328: pad->error(error);
329: }
330:
331: Index Frame::varcarte()
332: {
333: Var *v, *d;
334: Menu m;
335: int limit = 75, n;
336: char *q = "'''''''''''''''";
337:
338: if( !func ) return ZIndex;
339: BlkVars bv(func->blk(pc));
340: while( (v = bv.gen()) && limit-->0 ){
341: BlkVars dup(0);
342: dup = bv;
343: for( n = 0; d = dup.gen(); )
344: if( !strcmp(d->_text,v->_text) ) ++n;
345: Bls id( "%s%0.*s\240%s", v->_text, n, q, DiscName(v->disc()));
346: m.sort( id.text, (Action)&Frame::pickvar, (long) v);
347: }
348: return m.index();
349: }
350:
351: // void Frame::ambiguous(char *id, BlkVars &bl)
352: // {
353: // Var *v; VOK;
354: //
355: // while( v = bl.gen() )
356: // if( !strcmp(v->text(),id) ){
357: // PadsWarn("more than one %s in %s (use the menu)",
358: // id, func->text() );
359: // return;
360: // }
361: // }
362:
363: Var *Frame::idtosym(char *id) // ever called with id==0 ?
364: {
365: Var *v;
366:
367: trace("%d.idtosym(%s)", this, id?id:"0"); OK(0);
368: if( !id ) return 0;
369: if( func ) {
370: BlkVars bl((Block*)func->blk()->child); // blk(pc) ?
371: while( v = bl.gen() )
372: if( !strcmp(v->text(),id) ){
373: // ambiguous(id, bl);
374: return v;
375: }
376: }
377: BlkVars bg(core->symtab()->blk()); // idtosym doesn't work for regs
378: while( v = bg.gen() )
379: if( !strcmp(v->text(),id) ) return v;
380: return (Var*) symtab()->idtosym(SSet(U_GLB,U_FUNC), id);
381: }
382:
383: Index Frame::carte()
384: {
385: trace("%d.carte()", this); OK(ZIndex);
386: if( !func ) return ZIndex;
387: Bls o("open %s frame", func->text());
388: Menu m(o.text, (Action)&Frame::open);
389: Stmt *stmt = func->stmt(pc);
390: if( stmt ){
391: Bls s("show %s", stmt->text());
392: m.last(s.text, (Action)&Frame::select);
393: }
394: if( core->online() && core->process()->frame(0) == this )
395: m.last("pop off callstack", (Action)&Frame::pop);
396: return m.index();
397: }
398:
399: Globals::Globals(Core *c):(c)
400: {
401: trace("%d.Globals(%d)", this, c); VOK;
402: }
403:
404: void Globals::banner()
405: {
406: trace("%d.banner()", this); VOK;
407: if( pad ){
408: pad->banner("Globals: %s", core->procpath());
409: pad->name("Globals");
410: }
411: }
412:
413: void Globals::open(long)
414: {
415: Var *g;
416: Menu m;
417:
418: trace( "%d.open()", this ); VOK;
419: if( !pad ){
420: BlkVars bv(core->symtab()->blk());
421: pad = new Pad( (PadRcv *) this );
422: banner();
423: while( g = bv.gen() ){
424: if( g->range.lo && g->disc() == U_GLB ){
425: Bls id("%s\240%s", g->_text, DiscName(g->disc()));
426: m.sort(id.text, (Action)&Frame::pickvar, (long) g);
427: }
428: }
429: m.first("changed spies", (Action)&Frame::changes, 1);
430: m.last(regcarte());
431: pad->menu(m);
432: ix = m.index();
433: }
434: pad->makecurrent();
435: }
436:
437: void Globals::addvars(Menu *m)
438: {
439: Menu combine;
440: trace("%d.addvars(%d)", this, m); VOK;
441: if( !pad ) open();
442: combine.first(ix);
443: combine.last(m->index());
444: pad->menu(combine);
445: ix = combine.index();
446: pad->makecurrent();
447: }
448:
449: Index Frame::regcarte()
450: {
451: Var *v;
452: Menu m;
453:
454: trace("%d.regcarte()", this); OK(ZIndex);
455: BlkVars bv( core->symtab()->blk() );
456: while( v = bv.gen() )
457: if( v->disc() == U_REG )
458: m.last(v->text(), (Action)&Frame::pickvar, (long)v);
459: return m.index("registers\240");
460: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.