Annotation of researchv9/jtools/src/pi/symtab.c, revision 1.1.1.1

1.1       root        1: #include "symtab.pri"
                      2: #include "dtype.pri"
                      3: #include "symbol.h"
                      4: #include "srctext.pub"
                      5: #include "phrase.pub"
                      6: #include "format.pub"
                      7: #include "core.pub"
                      8: SRCFILE("symtab.c")
                      9: 
                     10: int FunctionGathered, UTypeGathered, FunctionStubs, UTypeStubs;
                     11: int IdToSymCalls, StrCmpCalls;
                     12: 
                     13: UType *SymTab::utypelist() { return utype; }
                     14: 
                     15: int HASHF(register char *s)
                     16: {
                     17:        register unsigned h = 0;
                     18:        while( *s ) h = (h<<1)^*(s++);
                     19:        return h % HASH;
                     20: }
                     21: 
                     22: int nccdemangle(char **text, char *classname)
                     23: {
                     24:        register char *cp = *text;
                     25:        if (!classname && !strncmp(cp, "__", 2) ) {     // Locals
                     26:                cp += 2;
                     27:                if (*cp >= '0' && *cp <= '9') {
                     28:                        do
                     29:                                cp++;
                     30:                        while (*cp >= '0' && *cp <= '9');
                     31:                        *text = cp;
                     32:                        return 1;
                     33:                }
                     34:        }
                     35:        cp++;
                     36:        while (*cp) {
                     37:          if (*cp == '_' && cp[1] == '_') {
                     38:                if (cp[2] == 'F') {     // Functions
                     39:                        *cp = 0;
                     40:                        return 1;
                     41:                } else if (cp[2] >= '0' && cp[2] <= '9') { // Class members
                     42:                        *cp = 0;
                     43:                        cp += 2;
                     44:                        int nchar = 0;
                     45:                        int ndigits = 0;
                     46:                        do {
                     47:                                nchar = nchar * 10 + *cp - '0';
                     48:                                ndigits++;
                     49:                                cp++;
                     50:                        } while (*cp >= '0' && *cp <= '9');
                     51:                        if (!classname || strlen(classname) != nchar ||
                     52:                            strncmp(cp, classname, nchar)) {
                     53:                                static char proto[256];
                     54:                                strncpy(proto,cp,nchar);
                     55:                                strcpy(proto+nchar, "::");
                     56:                                strcat(proto, *text);
                     57:                                strcpy(*text, proto);
                     58:                                if (--ndigits) {
                     59:                                        cp += nchar;
                     60:                                        while (ndigits--)
                     61:                                                *--cp = 0;
                     62:                                }
                     63:                        }
                     64:                        return 1;
                     65:                }
                     66:          }
                     67:          cp++;
                     68:        }
                     69:        return 0;
                     70: }
                     71: 
                     72: int ccdemangle(char **text, char *classname)
                     73: {
                     74:        register char *cp = *text;
                     75:        if (*cp++ != '_')
                     76:                return 0;
                     77:        if (classname) {
                     78:                int l = strlen(classname);
                     79:                if (!strncmp(cp, classname, l) && cp[l] == '_') {
                     80:                        *text = &cp[l+1];
                     81:                        return 1;
                     82:                }
                     83:        } else if (!strncmp(cp, "au", 2)) {
                     84:                cp += 2;
                     85:                while (*cp >= '0' && *cp <= '9')
                     86:                        cp++;
                     87:                if (*cp++ == '_') {
                     88:                        *text = cp;
                     89:                        return 1;
                     90:                }
                     91:        }
                     92:        return 0;
                     93: }
                     94: 
                     95: void SymTab::uncfront(Var *v, char *classname )
                     96: {
                     97:        for( ; v; v = (Var*)v->rsib ) {
                     98:                if (!ccdemangle(&v->_text, classname))
                     99:                        nccdemangle(&v->_text, classname);
                    100:        }
                    101: }
                    102: 
                    103: SSet::SSet(char a)
                    104: {
                    105:        v[0] = a;
                    106:        v[1] = 0;
                    107: }
                    108: 
                    109: SSet::SSet(char a, char b, char c, char d, char e, char f, char g )
                    110: {
                    111:        v[0] = a; v[1] = b; v[2] = c; v[3] = d;
                    112:        v[4] = e; v[5] = f; v[6] = g; v[7] = 0;
                    113: }
                    114: 
                    115: char *DiscName(UDisc d)
                    116: {
                    117:        switch( d ){
                    118:        case U_ARG:     return "arg";
                    119:        case U_AUT:     return "aut";
                    120:        case U_REG:     return "reg";
                    121:        case U_STA:     return "sta";
                    122:        case U_FST:     return "Sta";
                    123:        case U_GLB:     return "Glb";
                    124:        default:        return Name("U_%d",d);
                    125:        }
                    126: }
                    127: 
                    128: char *SymTab::stabpath()       { OK("SymTab::stabpath"); return _core->stabpath(); }
                    129: char *SymTab::warn()   { OK("SymTab::warn"); return _warn; }
                    130: Pad *SymTab::pad()     { OK(0); return _pad; }
                    131: 
                    132: void SymTab::showutype(UType *u)               // cf Var.showutype(UTpe*)
                    133: {
                    134:        trace("%d.showutype(%d))", this, u); VOK;
                    135:        u->show(LEAVE, SELECTLINE);
                    136: }
                    137: 
                    138: void SymTab::banner()
                    139: {
                    140:        trace("%d.banner()", this);     VOK;
                    141:        if( !_pad ) return;
                    142:        _pad->banner("User Defined Types: %s", _core->procpath());
                    143:        _pad->name("Types %s", basename(_core->procpath()));
                    144:        _pad->options(TRUNCATE);
                    145:        Menu m;
                    146:        Action a = (Action)&SymTab::showutype;
                    147:        char *index(char*,char);
                    148:        for( UType *u = utype; u; u = (UType *)u->rsib ){
                    149:                if( u->type.isstrun() )
                    150:                        m.sort(sf("%s\240",u->text()), a, (long) u);
                    151:        }
                    152:        _pad->menu(m);
                    153: }
                    154: 
                    155: SymTab::SymTab(Core* c,int stabfd, SymTab *i, long r)
                    156: {
                    157:        trace("%d.SymTab(%d,%d)", this, c, stabfd); VOK;
                    158:        _core = c;
                    159:        fd = stabfd;
                    160:        inherit = i;
                    161:        relocation = r;
                    162:        _blk = new Block(this, 0, 0, sf("%s.glb_blk",
                    163:                                         stabpath()?stabpath():""));
                    164: }
                    165: 
                    166: void SymTab::opentypes()
                    167: {
                    168:        if( !_pad ){
                    169:                _pad = new Pad((PadRcv*) this);
                    170:                banner();
                    171:        }
                    172:        _pad->makecurrent();
                    173: }
                    174: 
                    175: SymTab::~SymTab()
                    176: {
                    177:        void abort();
                    178:        trace( "%d.~SymTab()", this ); VOK;
                    179:        if( _pad ) delete _pad;
                    180:        if( strings ) delete strings;
                    181:        Source *_rootrsib;
                    182:        for( ; _root; _root = _rootrsib){
                    183:                _rootrsib = (Source*) _root->rsib;      // new malloc
                    184:                _root->srctext->userclose();
                    185:                delete _root;
                    186:        }
                    187:        for( int i = 0; i <= TOSYM; ++i )
                    188:          for( int j = 0; j < HASH; ++j )
                    189:            for( Symbol *s = hashtable[i][j]; s; s = s->hashlink )
                    190:                switch( s->disc() ){
                    191:                case U_UTYPE:   delete (UType*)s; break;
                    192:                case U_GLB:
                    193:                case U_STA:     ((Var*)s)->type.free();
                    194:                                delete (Var*)  s;
                    195:                                break;
                    196:                case U_FUNC:    delete (Func*) s; break;
                    197:                case U_STMT:    delete (Stmt*) s; break;
                    198:                default:        abort();
                    199:                }                               
                    200: }
                    201: 
                    202: Core *SymTab::core()           { OK(0); return _core; }
                    203: Source *SymTab::root()         { OK(0); return _root; }
                    204: long SymTab::modtime()         { OK(0); return modified(fd); }
                    205: Block *SymTab::blk()           { OK(0); return _blk; }
                    206: long SymTab::magic()           { OK(0); return _magic; }
                    207: 
                    208: Var *SymTab::globregs(Block *b, int r)
                    209: {
                    210:        Var *g = 0;
                    211:        int i;
                    212: 
                    213:        trace("%d.globregs(%d,%d)", this, b, r);        OK(0);
                    214:        for( i = 0; i<r; ++i ){
                    215:                g = new Var(this, b, g, U_REG, sf("$%s",_core->regname(i)) );
                    216:                g->range.lo = i;
                    217:                g->type.pcc = LONG;
                    218:                if( !b->var ) b->var = g;
                    219:        }
                    220:        return g;
                    221: }
                    222: 
                    223: char *SymTab::dump()
                    224: {
                    225:        int i, j;
                    226:        Symbol *s;
                    227: 
                    228:        OK("SymTab::dump");
                    229:        trace( "stabpath()=%s entries=%d", stabpath(), strings );
                    230:        trace( "strings=%d strsize=%d", strings, strsize );
                    231:        for( i = 0; i <= TOSYM; ++i )
                    232:                for( j = 0; j < HASH; ++j )
                    233:                        for( s = hashtable[i][j]; s; s = s->hashlink )
                    234:                                trace( "%s", s->dump() );
                    235:        return "SymTab::dump";
                    236: }
                    237: 
                    238: void SymTab::read()
                    239: {
                    240:        char *error;
                    241: 
                    242:        trace( "%d.read()", this );     VOK;
                    243:        trace( "symtab modified %d", modtime() );
                    244:        _root = 0;
                    245:        if( error = gethdr() )
                    246:                _warn = sf( "symbol table header: %s; go on", error );
                    247:        else if( !entries )
                    248:                _warn = "symbol table missing; go on";
                    249:        else if( !(_root = tree()) )
                    250:                _warn = sf( "%s; go on", _warn ? _warn : "symbol table error" );
                    251:        trace( "%s", dump() );
                    252: }
                    253: 
                    254: void SymTab::enter( Symbol *s )
                    255: {
                    256:        int i, h;
                    257: 
                    258:        trace( "%d.enter(%d) %s %d", this, s, s->dump(), HASHF(s->_text) ); VOK;
                    259:        s->hashlink = hashtable[i=s->disc()&TOSYM][h=HASHF(s->_text)];
                    260:        hashtable[i][h] = s;
                    261: }
                    262: 
                    263: 
                    264: Block *SymTab::fakeblk()               /* VAX  ap offsets */
                    265: {
                    266:        Block *b;
                    267:        int i;
                    268:        Var *a = 0;
                    269: 
                    270:        b = new Block( this, 0, 0, "?().arg_blk" );
                    271:        new Block( this, b, 0, "?().lcl_blk" );
                    272:        for( i = 1; i <= 3; ++i ){
                    273:                a = new Var( this, b, a, U_ARG, sf( "$arg%d", i ) );
                    274:                if( i==1 ) b->var = a;
                    275:                a->range.lo = (i+1)*4;
                    276:                a->type.pcc = INT;
                    277:        }
                    278:        return b;
                    279: }
                    280: 
                    281: Symbol *SymTab::idtosym(SSet set, register char *id, int lev)
                    282: {
                    283:        register int i, h;
                    284:        register Symbol *s;
                    285: 
                    286:        trace("%d.idtosym(%d,%s) %d", this, set.v[0], id?id:"0", HASHF(id)); OK(0);
                    287:        ++IdToSymCalls;
                    288:        if( !id ) return 0;
                    289:        h = HASHF(id);
                    290:        for( i = 0; set.v[i]; ++i ){
                    291:                trace( "%s", DiscName(set.v[i]) );
                    292:                for( s = hashtable[set.v[i]&TOSYM][h]; s; s = s->hashlink ){
                    293:                        trace( "%s", s->dump() );
                    294:                        ++StrCmpCalls;
                    295:                        if( eqstr(id,s->_text) ) return s;
                    296:                }
                    297:        }
                    298:        return (lev>0 && inherit) ? inherit->idtosym(set,id,lev-1) : 0;
                    299: }
                    300: 
                    301: inline Symbol *LookupCache::match(SSet _set, long _loc)
                    302: {
                    303:        return !strcmp(_set.v, set.v) && loc == _loc ? sym : 0;
                    304: }
                    305: 
                    306: void LookupCache::save(SSet _set, long _loc, Symbol *_sym)
                    307: {
                    308:        set = _set;
                    309:        loc = _loc;
                    310:        sym = _sym;
                    311: }
                    312: 
                    313: int LoctosymHit, Loctosym;
                    314: Symbol *SymTab::loctosym(SSet set, register long loc, int lev)
                    315: {
                    316:        register h, best_lo = 0, s_lo;
                    317:        register Symbol *s, *best = 0;
                    318:        register i, setvi;
                    319:        Symbol   *ibest;
                    320: 
                    321:        trace( "%d.loctosym(%d,%d)", this, set.v[0], loc ); OK(0);
                    322:        ++Loctosym;
                    323:        if( s = loctosymcache.match(set, loc) ){
                    324:                ++LoctosymHit;
                    325:                return s;
                    326:        }
                    327:        for( i = 0; setvi = set.v[i]; ++i ){
                    328:                setvi &= TOSYM;
                    329:                for( h = 0; h < HASH; ++h ){
                    330:                        for( s = hashtable[setvi][h]; s; s = s->hashlink ){
                    331:                                s_lo = s->range.lo;
                    332:                                if( loc < s_lo
                    333:                                ||( best && best_lo >= s_lo )
                    334:                                ||( s->range.hi && loc > s->range.hi ) )
                    335:                                        continue;
                    336:                                best = s;
                    337:                                best_lo = best->range.lo;
                    338:                                if( loc == best_lo ) goto returnbest;
                    339:                        }
                    340:                }
                    341:        }
                    342:        if( lev>0 && inherit && (ibest = inherit->loctosym(set,loc,lev-1)) ){
                    343:                if( !best || ibest->range.lo > best->range.lo ){
                    344:                        best = ibest;
                    345:                        goto returnbest;
                    346:                }
                    347:        }
                    348: returnbest:
                    349:        loctosymcache.save(set, loc, best);
                    350:        return best;
                    351: }
                    352: 
                    353: char *SymTab::symaddr(long a)
                    354: {
                    355:        trace( "%d.symaddr(%d)", this, a ); OK("SymTab::symaddr");
                    356:        return Format(F_SYMBOLIC, this).f(a);
                    357: }
                    358: 
                    359: Index SymTab::utypecarte(short sorety)
                    360: {
                    361:        Menu m;
                    362:        UType *u;
                    363:        Action a = (Action)&Phrase::applycast;
                    364:        char *index(char*,char);
                    365: 
                    366:        trace( "%d.utypecarte(%d)", this, sorety );     OK(ZIndex);
                    367:        if( !castix[sorety].null() ) return castix[sorety];
                    368:        for( u = utype; u; u = (UType *)u->rsib ){
                    369:                if( ::index(u->text(),'$') ) continue;          /* $ ? */
                    370:                if( u->type.pcc == sorety )
                    371:                        m.sort( sf("%s\240",u->text()), a, (long) &u->type );
                    372:        }
                    373:        if( inherit && !inherit->utypecarte(sorety).null() ){
                    374:                Menu s;
                    375:                s.first(inherit->utypecarte(sorety));
                    376:                m.last(s.index("inherit"));
                    377:        }
                    378:        return castix[sorety] = m.index();
                    379: }
                    380: 
                    381: Block *SymTab::gatherfunc(Func*)               { IF_LIVE(1) return 0; }
                    382: Var *SymTab::gatherutype(UType*)               { IF_LIVE(1) return 0; }
                    383: 
                    384: void SymbolStats()
                    385: {
                    386:        void WireTap(...);
                    387: 
                    388:        int fpc = FunctionStubs ? FunctionGathered*100/FunctionStubs : 0;
                    389:        int upc = UTypeStubs ? UTypeGathered*100/UTypeStubs : 0;
                    390:        static int prevfpc = -1, prevupc = -1;
                    391:        if( fpc>prevfpc || upc>prevupc )
                    392:                WireTap("FG=%d FS=%d UG=%d US=%d\n", FunctionGathered,
                    393:                        FunctionStubs, UTypeGathered, UTypeStubs);
                    394:        prevfpc = fpc;
                    395:        prevupc = upc;
                    396: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.