|
|
1.1 root 1: /*
2: * The routines in this file handle
3: * the reading in of functions. The internal data
4: * structures are built and threaded together.
5: */
6: #ifdef vax
7: #include "INC$LIB:cc2.h"
8: #else
9: #include "cc2.h"
10: #endif
11:
12: /*
13: * Read in a function.
14: * Pack it into the internal data structure.
15: * Copy non shared stuff straight through to save
16: * both space and time. Switch tables are in the
17: * shared data, so this works w.r.t. label reference
18: * counts. The PROLOG item has been already read.
19: */
20: getfunc()
21: {
22: register INS *ip;
23:
24: ins.i_fp = &ins;
25: ins.i_bp = &ins;
26: for (;;) {
27: ip = getins();
28: if (dotseg<0 || isshared(dotseg)==0
29: || (ip->i_type==ENTER && isshared(ip->i_seg)==0)) {
30: genins(ip);
31: free((char *) ip);
32: continue;
33: }
34: ip->i_fp = &ins;
35: ip->i_bp = ins.i_bp;
36: ins.i_bp->i_fp = ip;
37: ins.i_bp = ip;
38: if (ip->i_type == EPILOG)
39: break;
40: }
41: }
42:
43: /*
44: * This routine reads an item from
45: * the input file and constructs and INS node
46: * to hold it. A pointer to the INS node is
47: * returned. Any format errors are fatal.
48: */
49: INS *
50: getins()
51: {
52: register INS *ip;
53: register int op;
54:
55: loop:
56: op = bget();
57: switch (op) {
58:
59: case ENTER:
60: ip = newi(sizeof(INS));
61: ip->i_seg = bget();
62: break;
63:
64: case FNAME:
65: sget(file, NFNAME);
66: goto loop;
67:
68: case LINE:
69: line = iget();
70: ip = newi(sizeof(INS));
71: ip->i_line = line;
72: break;
73:
74: case DLABEL:
75: gendbgt(1);
76: goto loop;
77:
78: case AUTOS:
79: getautos();
80: goto loop;
81:
82: case BLOCK:
83: ip = newi(sizeof(INS));
84: ip->i_len = zget();
85: break;
86:
87: case LLABEL:
88: ip = newi(sizeof(INS));
89: ip->i_labno = iget();
90: ip->i_sp = NULL;
91: ip->i_refc = 0;
92: break;
93:
94: #ifdef KLUDGE
95: case SGUESS:
96: {
97: register SYM *sp;
98: int seg;
99: sget(id, NCSYMB);
100: seg = bget();
101: sp = glookup(id, 0);
102: if ((sp->s_flag&S_DEF) == 0)
103: sp->s_seg = seg;
104: goto loop;
105: }
106:
107: #endif
108: case EPILOG:
109: ip = newi(sizeof(INS));
110: break;
111:
112: case ALIGN:
113: ip = newi(sizeof(INS));
114: ip->i_align = bget();
115: break;
116:
117: case CODE:
118: return (getcode());
119:
120: case EOF:
121: cfatal("unexpected EOF");
122:
123: default:
124: cbotch("bad temporary file opcode %d", op);
125: }
126: ip->i_type = op;
127: ip->i_fp = ip->i_bp = NULL;
128: return (ip);
129: }
130:
131: /*
132: * Return true if segment "s" is
133: * shared. All local label references must be
134: * in a shared segment, or label reference counting
135: * will get screwed up. This includes the dispatch
136: * tables of switch statements.
137: */
138: isshared(s)
139: {
140: if (s==SCODE || s==SPURE)
141: return (1);
142: return (0);
143: }
144:
145: /*
146: * Allocate a new INS node.
147: */
148: INS *
149: newi(n)
150: {
151: register INS *ip;
152:
153: if ((ip = (INS *) malloc(n)) == NULL)
154: cnomem("newi");
155: return (ip);
156: }
157:
158: /*
159: * Allocate a new INS node with
160: * an `n' element `i_af' field on the end.
161: */
162: INS *
163: newn(n)
164: {
165: return (newi(sizeof(INS)+n*sizeof(struct afield)));
166: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.