1 #include "limbo.h"
2
3 static char sbltname[Tend] =
4 {
5 /* Tnone */ 'n',
6 /* Tadt */ 'a',
7 /* Tadtpick */ 'a',
8 /* Tarray */ 'A',
9 /* Tbig */ 'B',
10 /* Tbyte */ 'b',
11 /* Tchan */ 'C',
12 /* Treal */ 'f',
13 /* Tfn */ 'F',
14 /* Tint */ 'i',
15 /* Tlist */ 'L',
16 /* Tmodule */ 'm',
17 /* Tref */ 'R',
18 /* Tstring */ 's',
19 /* Ttuple */ 't',
20 /* Texception */ 't',
21 /* Tfix */ 'i',
22 /* Tpoly */ 'P',
23
24 /* Tainit */ '?',
25 /* Talt */ '?',
26 /* Tany */ 'N',
27 /* Tarrow */ '?',
28 /* Tcase */ '?',
29 /* Tcasel */ '?',
30 /* Tcasec */ '?',
31 /* Tdot */ '?',
32 /* Terror */ '?',
33 /* Tgoto */ '?',
34 /* Tid */ '?',
35 /* Tiface */ '?',
36 /* Texcept */ '?',
37 /* Tinst */ '?',
38 };
39 int sbltadtpick = 'p';
40
41 static Sym *sfiles;
42 static Sym *ftail;
43 static int nsfiles;
44 static int blockid;
45 static int lastf;
46 static int lastline;
47
48 static void sbltype(Type*, int);
49 static void sbldecl(Decl*, int);
50 static void sblftype(Type*);
51 static void sblfdecl(Decl*, int);
52
53 void
sblmod(Decl * m)54 sblmod(Decl *m)
55 {
56 Bprint(bsym, "limbo .sbl 2.1\n");
57 Bprint(bsym, "%s\n", m->sym->name);
58
59 blockid = 0;
60 nsfiles = 0;
61 sfiles = ftail = nil;
62 lastf = 0;
63 lastline = 0;
64 }
65
66 static int
sblfile(char * name)67 sblfile(char *name)
68 {
69 Sym *s;
70 int i;
71
72 i = 0;
73 for(s = sfiles; s != nil; s = s->next){
74 if(strcmp(s->name, name) == 0)
75 return i;
76 i++;
77 }
78 s = allocmem(sizeof(Sym));
79 s->name = name;
80 s->next = nil;
81 if(sfiles == nil)
82 sfiles = s;
83 else
84 ftail->next = s;
85 ftail = s;
86 nsfiles = i + 1;
87 return i;
88 }
89
90 static char *
filename(char * s)91 filename(char *s)
92 {
93 char *t;
94
95 t = strrchr(s, '/');
96 if(t != nil)
97 s = t + 1;
98 t = strrchr(s, '\\');
99 if(t != nil)
100 s = t+1;
101 t = strrchr(s, ' ');
102 if(t != nil)
103 s = t + 1;
104 return s;
105 }
106
107 void
sblfiles(void)108 sblfiles(void)
109 {
110 Sym *s;
111 int i;
112
113 for(i = 0; i < nfiles; i++)
114 files[i]->sbl = sblfile(files[i]->name);
115 Bprint(bsym, "%d\n", nsfiles);
116 for(s = sfiles; s != nil; s = s->next)
117 Bprint(bsym, "%s\n", filename(s->name));
118 }
119
120 static char*
sblsrcconv(char * buf,char * end,Src * src)121 sblsrcconv(char *buf, char *end, Src *src)
122 {
123 Fline fl;
124 File *startf, *stopf;
125 char *s;
126 int startl, stopl;
127
128 s = buf;
129
130 fl = fline(src->start.line);
131 startf = fl.file;
132 startl = fl.line;
133 fl = fline(src->stop.line);
134 stopf = fl.file;
135 stopl = fl.line;
136 if(lastf != startf->sbl)
137 s = seprint(s, end, "%d:", startf->sbl);
138 if(lastline != startl)
139 s = seprint(s, end, "%d.", startl);
140 s = seprint(s, end, "%d,", src->start.pos);
141 if(startf->sbl != stopf->sbl)
142 s = seprint(s, end, "%d:", stopf->sbl);
143 if(startl != stopl)
144 s = seprint(s, end, "%d.", stopl);
145 seprint(s, end, "%d ", src->stop.pos);
146 lastf = stopf->sbl;
147 lastline = stopl;
148 return buf;
149 }
150
151 #define isnilsrc(s) ((s)->start.line == 0 && (s)->stop.line == 0 && (s)->start.pos == 0 && (s)->stop.pos == 0)
152 #define isnilstopsrc(s) ((s)->stop.line == 0 && (s)->stop.pos == 0)
153
154 void
sblinst(Inst * inst,long ninst)155 sblinst(Inst *inst, long ninst)
156 {
157 Inst *in;
158 char buf[StrSize];
159 int *sblblocks, i, b;
160 Src src;
161
162 Bprint(bsym, "%ld\n", ninst);
163 sblblocks = allocmem(nblocks * sizeof *sblblocks);
164 for(i = 0; i < nblocks; i++)
165 sblblocks[i] = -1;
166 src = nosrc;
167 for(in = inst; in != nil; in = in->next){
168 if(in->op == INOOP)
169 continue;
170 if(in->src.start.line < 0)
171 fatal("no file specified for %I", in);
172 b = sblblocks[in->block];
173 if(b < 0)
174 sblblocks[in->block] = b = blockid++;
175 if(isnilsrc(&in->src))
176 in->src = src;
177 else if(isnilstopsrc(&in->src)){ /* how does this happen ? */
178 in->src.stop = in->src.start;
179 in->src.stop.pos++;
180 }
181 Bprint(bsym, "%s%d\n", sblsrcconv(buf, buf+sizeof(buf), &in->src), b);
182 src = in->src;
183 }
184 free(sblblocks);
185 }
186
187 void
sblty(Decl ** tys,int ntys)188 sblty(Decl **tys, int ntys)
189 {
190 Decl *d;
191 int i;
192
193 Bprint(bsym, "%d\n", ntys);
194 for(i = 0; i < ntys; i++){
195 d = tys[i];
196 d->ty->sbl = i;
197 }
198 for(i = 0; i < ntys; i++){
199 d = tys[i];
200 sbltype(d->ty, 1);
201 }
202 }
203
204 void
sblfn(Decl ** fns,int nfns)205 sblfn(Decl **fns, int nfns)
206 {
207 Decl *f;
208 int i;
209
210 Bprint(bsym, "%d\n", nfns);
211 for(i = 0; i < nfns; i++){
212 f = fns[i];
213 if(ispoly(f))
214 rmfnptrs(f);
215 if(f->dot != nil && f->dot->ty->kind == Tadt)
216 Bprint(bsym, "%ld:%s.%s\n", f->pc->pc, f->dot->sym->name, f->sym->name);
217 else
218 Bprint(bsym, "%ld:%s\n", f->pc->pc, f->sym->name);
219 sbldecl(f->ty->ids, Darg);
220 sbldecl(f->locals, Dlocal);
221 sbltype(f->ty->tof, 0);
222 }
223 }
224
225 void
sblvar(Decl * vars)226 sblvar(Decl *vars)
227 {
228 sbldecl(vars, Dglobal);
229 }
230
231 static int
isvis(Decl * id)232 isvis(Decl *id)
233 {
234 if(!tattr[id->ty->kind].vis
235 || id->sym == nil
236 || id->sym->name == nil /*????*/
237 || id->sym->name[0] == '.')
238 return 0;
239 if(id->ty == tstring && id->init != nil && id->init->op == Oconst)
240 return 0;
241 if(id->src.start.line < 0 || id->src.stop.line < 0)
242 return 0;
243 return 1;
244 }
245
246 static void
sbldecl(Decl * ids,int store)247 sbldecl(Decl *ids, int store)
248 {
249 Decl *id;
250 char buf[StrSize];
251 int n;
252
253 n = 0;
254 for(id = ids; id != nil; id = id->next){
255 if(id->store != store || !isvis(id))
256 continue;
257 n++;
258 }
259 Bprint(bsym, "%d\n", n);
260 for(id = ids; id != nil; id = id->next){
261 if(id->store != store || !isvis(id))
262 continue;
263 Bprint(bsym, "%ld:%s:%s", id->offset, id->sym->name, sblsrcconv(buf, buf+sizeof(buf), &id->src));
264 sbltype(id->ty, 0);
265 Bprint(bsym, "\n");
266 }
267 }
268
269 static void
sbltype(Type * t,int force)270 sbltype(Type *t, int force)
271 {
272 Type *lastt;
273 Decl *tg, *d;
274 char buf[StrSize];
275
276 if(t->kind == Tadtpick)
277 t = t->decl->dot->ty;
278
279 d = t->decl;
280 if(!force && d != nil && d->ty->sbl >= 0){
281 Bprint(bsym, "@%d\n", d->ty->sbl);
282 return;
283 }
284
285 switch(t->kind){
286 default:
287 fatal("bad type %T in sbltype", t);
288 break;
289 case Tnone:
290 case Tany:
291 case Tint:
292 case Tbig:
293 case Tbyte:
294 case Treal:
295 case Tstring:
296 case Tfix:
297 case Tpoly:
298 Bprint(bsym, "%c", sbltname[t->kind]);
299 break;
300 case Tfn:
301 Bprint(bsym, "%c", sbltname[t->kind]);
302 sbldecl(t->ids, Darg);
303 sbltype(t->tof, 0);
304 break;
305 case Tarray:
306 case Tlist:
307 case Tchan:
308 case Tref:
309 Bprint(bsym, "%c", sbltname[t->kind]);
310 if(t->kind == Tref && t->tof->kind == Tfn){
311 tattr[Tany].vis = 1;
312 sbltype(tfnptr, 0);
313 tattr[Tany].vis = 0;
314 }
315 else
316 sbltype(t->tof, 0);
317 break;
318 case Ttuple:
319 case Texception:
320 Bprint(bsym, "%c%ld.", sbltname[t->kind], t->size);
321 sbldecl(t->ids, Dfield);
322 break;
323 case Tadt:
324 if(t->tags != nil)
325 Bputc(bsym, sbltadtpick);
326 else
327 Bputc(bsym, sbltname[t->kind]);
328 if(d->dot != nil && !isimpmod(d->dot->sym))
329 Bprint(bsym, "%s->", d->dot->sym->name);
330 Bprint(bsym, "%s %s%ld\n", d->sym->name, sblsrcconv(buf, buf+sizeof(buf), &d->src), d->ty->size);
331 sbldecl(t->ids, Dfield);
332 if(t->tags != nil){
333 Bprint(bsym, "%d\n", t->decl->tag);
334 lastt = nil;
335 for(tg = t->tags; tg != nil; tg = tg->next){
336 Bprint(bsym, "%s:%s", tg->sym->name, sblsrcconv(buf, buf+sizeof(buf), &tg->src));
337 if(lastt == tg->ty){
338 Bputc(bsym, '\n');
339 }else{
340 Bprint(bsym, "%ld\n", tg->ty->size);
341 sbldecl(tg->ty->ids, Dfield);
342 }
343 lastt = tg->ty;
344 }
345 }
346 break;
347 case Tmodule:
348 Bprint(bsym, "%c%s\n%s", sbltname[t->kind], d->sym->name, sblsrcconv(buf, buf+sizeof(buf), &d->src));
349 sbldecl(t->ids, Dglobal);
350 break;
351 }
352 }
353