From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mimir.eigenstate.org ([206.124.132.107]) by ewsd; Wed Oct 21 21:18:39 -0400 2020 Received: from abbatoir.fios-router.home (pool-74-101-2-6.nycmny.fios.verizon.net [74.101.2.6]) by mimir.eigenstate.org (OpenSMTPD) with ESMTPSA id a11d38fa (TLSv1.2:ECDHE-RSA-AES256-SHA:256:NO) for <9front@9front.org>; Wed, 21 Oct 2020 18:18:31 -0700 (PDT) Message-ID: <9661591FC410B16CA272B221336B866C@eigenstate.org> To: 9front@9front.org Subject: Re: [9front] rc: null list in concatenation line numbers Date: Wed, 21 Oct 2020 18:18:28 -0700 From: ori@eigenstate.org In-Reply-To: <71CE86A5EC086742886B6A2E7F09C255@eigenstate.org> MIME-Version: 1.0 Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit List-ID: <9front.9front.org> List-Help: X-Glyph: ➈ X-Bullshit: content-addressed storage content-driven-based strategy > Testing and review welcome. Another iteration: This one caps the number of filenames that we put into the name table. It's pointless to past the name table past the maximum number of files that fit into the location. diff -r bdd5a746e8c5 sys/src/cmd/rc/code.c --- a/sys/src/cmd/rc/code.c Sun Oct 18 19:30:14 2020 -0700 +++ b/sys/src/cmd/rc/code.c Wed Oct 21 18:15:06 2020 -0700 @@ -6,10 +6,12 @@ #define c0 t->child[0] #define c1 t->child[1] #define c2 t->child[2] +code *codebuf; int codep, ncode; #define emitf(x) ((codep!=ncode || morecode()), codebuf[codep].f = (x), codep++) #define emiti(x) ((codep!=ncode || morecode()), codebuf[codep].i = (x), codep++) #define emits(x) ((codep!=ncode || morecode()), codebuf[codep].s = (x), codep++) + void stuffdot(int); char *fnstr(tree*); void outcode(tree*, int); @@ -37,9 +39,9 @@ int compile(tree *t) { + codep = 0; ncode = 100; - codebuf = (code *)emalloc(ncode*sizeof codebuf[0]); - codep = 0; + codebuf = emalloc(ncode*sizeof codebuf[0]); emiti(0); /* reference count */ outcode(t, flag['e']?1:0); if(nerror){ @@ -79,12 +81,28 @@ void outcode(tree *t, int eflag) { - int p, q; + static int file, line; + int p, q, f, l; tree *tt; if(t==0) return; if(t->type!=NOT && t->type!=';') runq->iflast = 0; + if(t->file != file || t->line != line){ + file = t->file; + line = t->line; + + /* + * These are small enough that with a ton of sourcing, + * overflow is a realistic risk. If we run out of files, + * set to file 0, which is always '???' + */ + f = (t->file > LFMAX) ? 0 : t->file << LSHIFT; + l = (t->line > LMASK) ? -1 : t->line; + + emitf(Xloc); + emiti(f|l); + } switch(t->type){ default: pfmt(err, "bad type %d in outcode\n", t->type); diff -r bdd5a746e8c5 sys/src/cmd/rc/exec.c --- a/sys/src/cmd/rc/exec.c Sun Oct 18 19:30:14 2020 -0700 +++ b/sys/src/cmd/rc/exec.c Wed Oct 21 18:15:06 2020 -0700 @@ -14,6 +14,7 @@ struct thread *p = new(struct thread); p->code = codecopy(c); + p->loc = 0; p->pc = pc; p->argv = 0; p->redir = p->startredir = runq?runq->redir:0; @@ -205,6 +206,11 @@ pushlist(); argv0 = estrdup(argv[0]); for(i = argc-1;i!=0;--i) pushword(argv[i]); + + lexpath = erealloc(lexpath, sizeof(char*)); + nlexpath = 1; + lexpath[0] = strdup("???"); + for(;;){ if(flag['r']) pfnc(err, runq); @@ -953,10 +959,15 @@ void Xerror(char *s) { + int f, l; + + f = runq->loc >> LSHIFT; + l = runq->loc & LMASK; + assert(f >= 0 && f < nlexpath); if(strcmp(argv0, "rc")==0 || strcmp(argv0, "/bin/rc")==0) - pfmt(err, "rc: %s: %r\n", s); + pfmt(err, "rc:%d: %s: %r\n", l, s); else - pfmt(err, "rc (%s): %s: %r\n", argv0, s); + pfmt(err, "%s:%d: %s: %r\n", lexpath[f], l, s); flush(err); setstatus("error"); while(!runq->iflag) Xreturn(); @@ -965,10 +976,15 @@ void Xerror1(char *s) { + int f, l; + + f = runq->loc >> LSHIFT; + l = runq->loc & LMASK; + assert(f >= 0 && f < nlexpath); if(strcmp(argv0, "rc")==0 || strcmp(argv0, "/bin/rc")==0) - pfmt(err, "rc: %s\n", s); + pfmt(err, "rc:%d: %s\n", l, s); else - pfmt(err, "rc (%s): %s\n", argv0, s); + pfmt(err, "%s:%d: %s\n", lexpath[f], l, s); flush(err); setstatus("error"); while(!runq->iflag) Xreturn(); @@ -1025,3 +1041,10 @@ { globlist(runq->argv->words); } + +void +Xloc(void) +{ + runq->loc = runq->code[runq->pc].i; + runq->pc++; +} diff -r bdd5a746e8c5 sys/src/cmd/rc/exec.h --- a/sys/src/cmd/rc/exec.h Sun Oct 18 19:30:14 2020 -0700 +++ b/sys/src/cmd/rc/exec.h Wed Oct 21 18:15:06 2020 -0700 @@ -5,7 +5,7 @@ extern void Xconc(void), Xcount(void), Xdelfn(void), Xdol(void), Xqw(void), Xdup(void); extern void Xexit(void), Xfalse(void), Xfn(void), Xfor(void), Xglob(void); extern void Xjump(void), Xmark(void), Xmatch(void), Xpipe(void), Xread(void); -extern void Xrdwr(void); +extern void Xrdwr(void), Xloc(void); extern void Xrdfn(void), Xunredir(void), Xstar(void), Xreturn(void), Xsubshell(void); extern void Xtrue(void), Xword(void), Xglobs(void), Xwrite(void), Xpipefd(void), Xcase(void); extern void Xlocal(void), Xunlocal(void), Xassign(void), Xsimple(void), Xpopm(void); @@ -30,7 +30,7 @@ struct redir{ char type; /* what to do */ short from, to; /* what to do it to */ - struct redir *next; /* what else to do (reverse order) */ + redir *next; /* what else to do (reverse order) */ }; #define NSTATUS ERRMAX /* length of status (from plan 9) */ /* @@ -40,14 +40,15 @@ #define RDUP 2 /* dup2(from, to); */ #define RCLOSE 3 /* close(from); */ struct thread{ - union code *code; /* code for this thread */ + code *code; /* code for this thread */ int pc; /* code[pc] is the next instruction */ - struct list *argv; /* argument stack */ - struct redir *redir; /* redirection stack */ - struct redir *startredir; /* redir inheritance point */ - struct var *local; /* list of local variables */ + int loc; /* source code location */ + list *argv; /* argument stack */ + redir *redir; /* redirection stack */ + redir *startredir; /* redir inheritance point */ + var *local; /* list of local variables */ char *cmdfile; /* file name in Xrdcmd */ - struct io *cmdfd; /* file descriptor for Xrdcmd */ + io *cmdfd; /* file descriptor for Xrdcmd */ int iflast; /* static `if not' checking */ int eof; /* is cmdfd at eof? */ int iflag; /* interactive? */ @@ -55,7 +56,7 @@ int pid; /* process for Xpipewait to wait for */ char status[NSTATUS]; /* status for Xpipewait */ tree *treenodes; /* tree nodes created by this process */ - thread *ret; /* who continues when this finishes */ + thread *ret; /* who continues when this finishes */ }; thread *runq; code *codecopy(code*); diff -r bdd5a746e8c5 sys/src/cmd/rc/lex.c --- a/sys/src/cmd/rc/lex.c Sun Oct 18 19:30:14 2020 -0700 +++ b/sys/src/cmd/rc/lex.c Wed Oct 21 18:15:06 2020 -0700 @@ -25,6 +25,13 @@ int doprompt = 1; int inquote; int incomm; +int lastc; +int ndot; +int nerror; +int lexline; +int lexfile; +char **lexpath; +int nlexpath; /* * Look ahead in the input stream */ @@ -39,13 +46,14 @@ /* * Consume the lookahead character. */ - int advance(void) { int c = nextc(); lastc = future; future = EOF; + if(c == '\n') + lexline++; return c; } /* diff -r bdd5a746e8c5 sys/src/cmd/rc/pfnc.c --- a/sys/src/cmd/rc/pfnc.c Sun Oct 18 19:30:14 2020 -0700 +++ b/sys/src/cmd/rc/pfnc.c Wed Oct 21 18:15:06 2020 -0700 @@ -51,6 +51,7 @@ Xrdfn, "Xrdfn", Xsimple, "Xsimple", Xqw, "Xqw", + Xloc, "Xloc", 0}; void diff -r bdd5a746e8c5 sys/src/cmd/rc/rc.h --- a/sys/src/cmd/rc/rc.h Sun Oct 18 19:30:14 2020 -0700 +++ b/sys/src/cmd/rc/rc.h Wed Oct 21 18:15:06 2020 -0700 @@ -43,6 +43,8 @@ char *str; int quoted; int iskw; + int file; + int line; tree *child[3]; tree *next; }; @@ -54,6 +56,19 @@ tree *simplemung(tree*), *heredoc(tree*); void freetree(tree*); tree *cmdtree; + +/* + * Locations are stored as instructions in the rc bytecode. + * To avoid wasting too much space, both the file and line + * is packed into a single integer, as + * (file << LSHIFT) | line + * With 32 bit integers, this gives us 2048 filenames, with + * just over 1 million lines of code in each. + */ +#define LSHIFT 20 +#define LMASK ((1<code[runq->pc]; + code *c=&runq->code[runq->pc]; while(c->f==Xpopredir || c->f==Xunlocal) c++; return c->f==Xexit; } @@ -294,7 +294,7 @@ execdot(void) { int iflag = 0; - int fd; + int fd, i; list *av; thread *p = runq; char *zero, *file; @@ -354,6 +354,22 @@ Xerror(".: can't open"); return; } + + lexline = 1; + for(i = 0; i < nlexpath; i++){ + if(strcmp(lexpath[i], zero) == 0){ + lexfile = i; + break; + } + } + if(i == nlexpath){ + if(nlexpath < LFMAX){ + lexpath = erealloc(lexpath, (nlexpath + 1)*sizeof(char*)); + lexpath[nlexpath] = estrdup(zero); + lexfile = nlexpath++; + }else + lexfile = 0; + } /* set up for a new command loop */ start(dotcmds, 1, (struct var *)0); pushredir(RCLOSE, fd, 0); diff -r bdd5a746e8c5 sys/src/cmd/rc/tree.c --- a/sys/src/cmd/rc/tree.c Sun Oct 18 19:30:14 2020 -0700 +++ b/sys/src/cmd/rc/tree.c Wed Oct 21 18:15:06 2020 -0700 @@ -16,6 +16,8 @@ t->str = 0; t->child[0] = t->child[1] = t->child[2] = 0; t->next = treenodes; + t->file = lexfile; + t->line = lexline; treenodes = t; return t; }