|
|
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.