From efec14bc5af7f1f43b6e736a4fa2138ea5a328a2 Mon Sep 17 00:00:00 2001 From: Ken Thompson Date: Fri, 13 Jun 2008 18:16:23 -0700 Subject: [PATCH] plan9 line numbers and line table SVN=122793 --- src/clean.bash | 2 +- src/cmd/6g/align.c | 7 +++ src/cmd/6g/gg.h | 3 ++ src/cmd/6g/list.c | 8 +-- src/cmd/6g/obj.c | 68 ++++++++++++++++++++++++ src/cmd/clean.bash | 2 +- src/cmd/gc/Makefile | 1 + src/cmd/gc/dcl.c | 5 +- src/cmd/gc/export.c | 2 +- src/cmd/gc/go.h | 21 +++++++- src/cmd/gc/lex.c | 52 ++++++++++++------- src/cmd/gc/subr.c | 124 ++++++++++++++++++++++++++++++++++---------- 12 files changed, 238 insertions(+), 57 deletions(-) diff --git a/src/clean.bash b/src/clean.bash index 6f5da78d5b..2378ecb054 100755 --- a/src/clean.bash +++ b/src/clean.bash @@ -3,7 +3,7 @@ # Use of this source code is governed by a BSD-style # license that can be found in the LICENSE file. -for i in lib9 libbio +for i in lib9 libbio libmach_amd64 do cd $i make clean diff --git a/src/cmd/6g/align.c b/src/cmd/6g/align.c index 092c8b78df..82e0ec981e 100644 --- a/src/cmd/6g/align.c +++ b/src/cmd/6g/align.c @@ -200,6 +200,13 @@ belexinit(int lextype) int i; Sym *s0, *s1; + zprog.link = P; + zprog.as = AGOK; + zprog.from.type = D_NONE; + zprog.from.index = D_NONE; + zprog.from.scale = 0; + zprog.to = zprog.from; + for(i=0; ilexical != lextype) diff --git a/src/cmd/6g/gg.h b/src/cmd/6g/gg.h index c2cfc44cbf..195788b49e 100644 --- a/src/cmd/6g/gg.h +++ b/src/cmd/6g/gg.h @@ -97,6 +97,8 @@ EXTERN long stringo; // size of string objects EXTERN long pcloc; // instruction counter EXTERN String emptystring; extern char* anames[]; +EXTERN Hist* hist; +EXTERN Prog zprog; /* * gen.c @@ -195,6 +197,7 @@ void zaddr(Biobuf*, Addr*, int); void ieeedtod(Ieee*, double); void dumpstrings(void); void dumpsignatures(void); +void outhist(Biobuf*); /* * align diff --git a/src/cmd/6g/list.c b/src/cmd/6g/list.c index 361eb3cb9f..93dd756020 100644 --- a/src/cmd/6g/list.c +++ b/src/cmd/6g/list.c @@ -52,12 +52,12 @@ Pconv(Fmt *fp) sconsize = 8; if(p->as == ADATA) { sconsize = p->from.scale; - snprint(str, sizeof(str), "%.4ld %-7A %D/%d,%D", - p->loc, p->as, &p->from, sconsize, &p->to); + snprint(str, sizeof(str), "%.4ld (%4ld) %-7A %D/%d,%D", + p->loc, p->lineno, p->as, &p->from, sconsize, &p->to); return fmtstrcpy(fp, str); } - snprint(str, sizeof(str), "%.4ld %-7A %D,%D", - p->loc, p->as, &p->from, &p->to); + snprint(str, sizeof(str), "%.4ld (%4ld) %-7A %D,%D", + p->loc, p->lineno, p->as, &p->from, &p->to); return fmtstrcpy(fp, str); } diff --git a/src/cmd/6g/obj.c b/src/cmd/6g/obj.c index 01014655ca..eae3d81216 100644 --- a/src/cmd/6g/obj.c +++ b/src/cmd/6g/obj.c @@ -55,6 +55,8 @@ dumpobj(void) dumpexport(); Bprint(bout, "\n!\n"); + outhist(bout); + // add globals nodconst(&n1, types[TINT32], 0); for(d=externdcl; d!=D; d=d->forw) { @@ -158,6 +160,9 @@ dumpobj(void) zaddr(bout, &p->to, st); } } + Bterm(bout); +return; + Bterm(bout); } void @@ -258,6 +263,69 @@ zaddr(Biobuf *b, Addr *a, int s) Bputc(b, a->type); } +void +outhist(Biobuf *b) +{ + Hist *h; + char *p, *q, *op; + Prog pg; + int n; + + pg = zprog; + pg.as = AHISTORY; + for(h = hist; h != H; h = h->link) { + p = h->name; + op = 0; + + if(p && p[0] != '/' && h->offset == 0 && pathname && pathname[0] == '/') { + op = p; + p = pathname; + } + + while(p) { + q = utfrune(p, '/'); + if(q) { + n = q-p; + if(n == 0) + n = 1; // leading "/" + q++; + } else { + n = strlen(p); + q = 0; + } + if(n) { + Bputc(b, ANAME); + Bputc(b, ANAME>>8); + Bputc(b, D_FILE); + Bputc(b, 1); + Bputc(b, '<'); + Bwrite(b, p, n); + Bputc(b, 0); + } + p = q; + if(p == 0 && op) { + p = op; + op = 0; + } + } + + pg.lineno = h->line; + pg.to.type = zprog.to.type; + pg.to.offset = h->offset; + if(h->offset) + pg.to.type = D_CONST; + + Bputc(b, pg.as); + Bputc(b, pg.as>>8); + Bputc(b, pg.lineno); + Bputc(b, pg.lineno>>8); + Bputc(b, pg.lineno>>16); + Bputc(b, pg.lineno>>24); + zaddr(b, &pg.from, 0); + zaddr(b, &pg.to, 0); + } +} + void ieeedtod(Ieee *ieee, double native) { diff --git a/src/cmd/clean.bash b/src/cmd/clean.bash index a333bcd0e1..184cffc2b0 100644 --- a/src/cmd/clean.bash +++ b/src/cmd/clean.bash @@ -3,7 +3,7 @@ # Use of this source code is governed by a BSD-style # license that can be found in the LICENSE file. -for i in 6l 6a 6c 6g gc cc +for i in 6l 6a 6c 6g gc cc db do cd $i make clean diff --git a/src/cmd/gc/Makefile b/src/cmd/gc/Makefile index 25794c3f23..8535c64b43 100644 --- a/src/cmd/gc/Makefile +++ b/src/cmd/gc/Makefile @@ -27,6 +27,7 @@ OFILES=\ const.$O\ mpatof.$O\ sysimport.$O\ + compat.$O\ $(LIB): $(OFILES) ar rsc $(LIB) $(OFILES) diff --git a/src/cmd/gc/dcl.c b/src/cmd/gc/dcl.c index 63c6485879..95a2ff8c88 100644 --- a/src/cmd/gc/dcl.c +++ b/src/cmd/gc/dcl.c @@ -511,13 +511,14 @@ popdcl(char *why) // if(dflag()) // print("revert\n"); + for(d=dclstack; d!=S; d=d->link) { if(d->name == nil) break; s = pkglookup(d->name, d->package); dcopy(s, d); if(dflag()) - print("\t%ld pop %S\n", curio.lineno, s); + print("\t%L pop %S\n", lineno, s); } if(d == S) fatal("popdcl: no mark"); @@ -537,7 +538,7 @@ poptodcl(void) s = pkglookup(d->name, d->package); dcopy(s, d); if(dflag()) - print("\t%ld pop %S\n", curio.lineno, s); + print("\t%L pop %S\n", lineno, s); } if(d == S) fatal("poptodcl: no mark"); diff --git a/src/cmd/gc/export.c b/src/cmd/gc/export.c index 4904855770..f36b66d12e 100644 --- a/src/cmd/gc/export.c +++ b/src/cmd/gc/export.c @@ -35,7 +35,7 @@ loop: d = mal(sizeof(*d)); d->dsym = s; d->dnode = N; - d->lineno = curio.lineno; + d->lineno = lineno; r = exportlist; d->back = r->back; diff --git a/src/cmd/gc/go.h b/src/cmd/gc/go.h index 5c65a0139b..0ce1e6a9ce 100644 --- a/src/cmd/gc/go.h +++ b/src/cmd/gc/go.h @@ -14,6 +14,7 @@ tothinkabout: #include #include #include +#include "compat.h" #ifndef EXTERN #define EXTERN extern @@ -28,6 +29,7 @@ enum YYMAXDEPTH = 500, MAXALIGN = 7, UINF = 100, + HISTSZ = 10, PRIME1 = 3, PRIME2 = 10007, @@ -189,6 +191,16 @@ struct Iter Node* n; }; +typedef struct Hist Hist; +struct Hist +{ + Hist* link; + char* name; + long line; + long offset; +}; +#define H ((Hist*)0) + enum { OXXX, @@ -313,13 +325,18 @@ struct Io { char* infile; Biobuf* bin; - long lineno; + long ilineno; int peekc; char* cp; // used for content when bin==nil }; EXTERN Io curio; EXTERN Io pushedio; +EXTERN long lineno; +EXTERN char* pathname; +EXTERN Hist* hist; +EXTERN Hist* ehist; + EXTERN char* infile; EXTERN char* outfile; @@ -416,6 +433,7 @@ Sym* pkglookup(char*, char*); void yyerror(char*, ...); void warn(char*, ...); void fatal(char*, ...); +void linehist(char*, long); Node* nod(int, Node*, Node*); Type* typ(int); Dcl* dcl(void); @@ -457,6 +475,7 @@ Type* funcnext(Iter*); int Econv(Fmt*); int Jconv(Fmt*); +int Lconv(Fmt*); int Oconv(Fmt*); int Sconv(Fmt*); int Tconv(Fmt*); diff --git a/src/cmd/gc/lex.c b/src/cmd/gc/lex.c index 03b7b85927..91c35a126b 100644 --- a/src/cmd/gc/lex.c +++ b/src/cmd/gc/lex.c @@ -39,6 +39,10 @@ mainlex(int argc, char *argv[]) if(argc != 1) goto usage; + pathname = mal(100); + if(mygetwd(pathname, 99) == 0) + strcpy(pathname, "/???"); + fmtinstall('O', Oconv); // node opcodes fmtinstall('E', Econv); // etype opcodes fmtinstall('J', Jconv); // all the node flags @@ -46,15 +50,19 @@ mainlex(int argc, char *argv[]) fmtinstall('T', Tconv); // type pointer fmtinstall('N', Nconv); // node pointer fmtinstall('Z', Zconv); // escaped string + fmtinstall('L', Lconv); // line number lexinit(); + lineno = 1; infile = argv[0]; - curio.infile = infile; + linehist(infile, 0); - curio.bin = Bopen(curio.infile, OREAD); + curio.infile = infile; + curio.bin = Bopen(infile, OREAD); if(curio.bin == nil) - fatal("cant open: %s", curio.infile); + fatal("cant open: %s", infile); + curio.peekc = 0; externdcl = mal(sizeof(*externdcl)); externdcl->back = externdcl; @@ -69,14 +77,11 @@ mainlex(int argc, char *argv[]) fskel->right->left = nod(ODCLFIELD, N, N); fskel->right->right = nod(ODCLFIELD, N, N); - curio.peekc = 0; - curio.lineno = 1; nerrors = 0; yyparse(); + linehist(nil, 0); Bterm(curio.bin); - if(bout != nil) - Bterm(bout); if(nerrors) errorexit(); @@ -104,6 +109,7 @@ void importfile(Val *f) { Biobuf *imp; + char *file; long c; if(f->ctype != CTSTR) { @@ -112,12 +118,12 @@ importfile(Val *f) } // BOTCH need to get .8 from backend snprint(namebuf, sizeof(namebuf), "%Z.6", f->sval); + file = strdup(namebuf); + linehist(file, 0); - imp = Bopen(namebuf, OREAD); - if(imp == nil) { - yyerror("cant open import: %s", namebuf); - return; - } + imp = Bopen(file, OREAD); + if(imp == nil) + fatal("cant open import: %s", namebuf); /* * position the input right @@ -125,9 +131,8 @@ importfile(Val *f) */ pushedio = curio; curio.bin = imp; - curio.lineno = 1; curio.peekc = 0; - curio.infile = strdup(namebuf); + curio.infile = file; for(;;) { c = getc(); if(c == EOF) @@ -148,6 +153,8 @@ importfile(Val *f) void unimportfile(void) { + linehist(nil, 0); + if(curio.bin != nil) { Bterm(curio.bin); curio.bin = nil; @@ -160,12 +167,17 @@ unimportfile(void) void cannedimports(void) { + char *file; + + file = "sys.6"; + linehist(file, 0); + pushedio = curio; curio.bin = nil; - curio.lineno = 1; curio.peekc = 0; - curio.infile = "internal sys.go"; + curio.infile = file; curio.cp = sysimport; + pkgmyname = S; inimportsys = 1; } @@ -619,7 +631,7 @@ getc(void) if(c != 0) { curio.peekc = 0; if(c == '\n') - curio.lineno++; + lineno++; return c; } @@ -636,7 +648,7 @@ getc(void) return EOF; case '\n': - curio.lineno++; + lineno++; break; } return c; @@ -647,7 +659,7 @@ ungetc(int c) { curio.peekc = c; if(c == '\n') - curio.lineno--; + lineno--; } long @@ -688,7 +700,7 @@ getnsc(void) if(!isspace(c)) return c; if(c == '\n') { - curio.lineno++; + lineno++; return c; } c = getc(); diff --git a/src/cmd/gc/subr.c b/src/cmd/gc/subr.c index 919589ac48..37375342c0 100644 --- a/src/cmd/gc/subr.c +++ b/src/cmd/gc/subr.c @@ -13,25 +13,12 @@ errorexit(void) myexit(1); } -void -myexit(int x) -{ - if(x) - exits("error"); - exits(nil); -} - void yyerror(char *fmt, ...) { va_list arg; - long lno; - lno = dynlineno; - if(lno == 0) - lno = curio.lineno; - - print("%s:%ld: ", curio.infile, lno); + print("%L: "); va_start(arg, fmt); vfprint(1, fmt, arg); va_end(arg); @@ -48,13 +35,8 @@ void warn(char *fmt, ...) { va_list arg; - long lno; - lno = dynlineno; - if(lno == 0) - lno = curio.lineno; - - print("%s:%ld: ", curio.infile, lno); + print("%L warning: "); va_start(arg, fmt); vfprint(1, fmt, arg); va_end(arg); @@ -67,13 +49,8 @@ void fatal(char *fmt, ...) { va_list arg; - long lno; - lno = dynlineno; - if(lno == 0) - lno = curio.lineno; - - print("%s:%ld: fatal error: ", curio.infile, lno); + print("%L fatal error: "); va_start(arg, fmt); vfprint(1, fmt, arg); va_end(arg); @@ -83,6 +60,31 @@ fatal(char *fmt, ...) myexit(1); } +void +linehist(char *file, long off) +{ + Hist *h; + + if(debug['i']) + if(file != nil) + print("%L: import %s\n", file); + else + print("%L: \n"); + + h = alloc(sizeof(Hist)); + h->name = file; + h->line = lineno; + h->offset = off; + h->link = H; + if(ehist == H) { + hist = h; + ehist = h; + return; + } + ehist->link = h; + ehist = h; +} + ulong stringhash(char *p) { @@ -248,7 +250,7 @@ nod(int op, Node *nleft, Node *nright) n->right = nright; n->lineno = dynlineno; if(dynlineno == 0) - n->lineno = curio.lineno; + n->lineno = lineno; return n; } @@ -646,6 +648,74 @@ Oconv(Fmt *fp) return fmtstrcpy(fp, opnames[o]); } +int +Lconv(Fmt *fp) +{ + char str[STRINGSZ], s[STRINGSZ]; + struct + { + Hist* incl; /* start of this include file */ + long idel; /* delta line number to apply to include */ + Hist* line; /* start of this #line directive */ + long ldel; /* delta line number to apply to #line */ + } a[HISTSZ]; + long lno, d; + int i, n; + Hist *h; + + lno = dynlineno; + if(lno == 0) + lno = lineno; + + n = 0; + for(h=hist; h!=H; h=h->link) { + if(lno < h->line) + break; + if(h->name) { + if(n < HISTSZ) { /* beginning of file */ + a[n].incl = h; + a[n].idel = h->line; + a[n].line = 0; + } + n++; + continue; + } + n--; + if(n > 0 && n < HISTSZ) { + d = h->line - a[n].incl->line; + a[n-1].ldel += d; + a[n-1].idel += d; + } + } + + if(n > HISTSZ) + n = HISTSZ; + + str[0] = 0; + for(i=n-1; i>=0; i--) { + if(i != n-1) { + if(fp->flags & ~(FmtWidth|FmtPrec)) + break; + strcat(str, " "); + } + if(a[i].line) + snprint(s, STRINGSZ, "%s:%ld[%s:%ld]", + a[i].line->name, lno-a[i].ldel+1, + a[i].incl->name, lno-a[i].idel+1); + else + snprint(s, STRINGSZ, "%s:%ld", + a[i].incl->name, lno-a[i].idel+1); + if(strlen(s)+strlen(str) >= STRINGSZ-10) + break; + strcat(str, s); + lno = a[i].incl->line - 1; /* now print out start of this file */ + } + if(n == 0) + strcat(str, ""); + + return fmtstrcpy(fp, str); +} + /* s%,%,\n%g s%\n+%\n%g