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 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 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 * 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 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* 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 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 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 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 226 sblvar(Decl *vars) 227 { 228 sbldecl(vars, Dglobal); 229 } 230 231 static int 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 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 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