From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mimir.eigenstate.org ([206.124.132.107]) by ewsd; Sun Oct 25 16:29:12 -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 bf87f23e (TLSv1.2:ECDHE-RSA-AES256-SHA:256:NO); Sun, 25 Oct 2020 13:29:03 -0700 (PDT) Message-ID: <37CF109B904B5F178848E0FADF7E5CAF@eigenstate.org> To: ori@eigenstate.org, 9front@9front.org Subject: Re: [9front] rc: null list in concatenation line numbers Date: Sun, 25 Oct 2020 13:29:01 -0700 From: ori@eigenstate.org In-Reply-To: <9661591FC410B16CA272B221336B866C@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: responsive core layer >> 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. And one more, which restores the location correctly after sourcing a file; thanks to kvik for testing it out and reporting back. diff -r 0281cd6caa8c sys/src/cmd/rc/code.c --- a/sys/src/cmd/rc/code.c Sat Oct 24 17:24:59 2020 -0700 +++ b/sys/src/cmd/rc/code.c Sun Oct 25 13:28:14 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,30 @@ 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; + + if(f|l != 0){ + emitf(Xloc); + emiti(f|l); + } + } switch(t->type){ default: pfmt(err, "bad type %d in outcode\n", t->type); diff -r 0281cd6caa8c sys/src/cmd/rc/exec.c --- a/sys/src/cmd/rc/exec.c Sat Oct 24 17:24:59 2020 -0700 +++ b/sys/src/cmd/rc/exec.c Sun Oct 25 13:28:14 2020 -0700 @@ -14,6 +14,7 @@ struct thread *p = new(struct thread); p->code = codecopy(c); + p->loc = runq?runq->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); @@ -932,7 +938,9 @@ if(p->cmdfile) free(p->cmdfile); closeio(p->cmdfd); - Xreturn(); /* should this be omitted? */ + Xreturn(); + lexfile = runq->loc >> LSHIFT; + lexline = runq->loc & LMASK; } else{ if(Eintr()){ @@ -953,10 +961,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 +978,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 +1043,10 @@ { globlist(runq->argv->words); } + +void +Xloc(void) +{ + runq->loc = runq->code[runq->pc].i; + runq->pc++; +} diff -r 0281cd6caa8c sys/src/cmd/rc/exec.h --- a/sys/src/cmd/rc/exec.h Sat Oct 24 17:24:59 2020 -0700 +++ b/sys/src/cmd/rc/exec.h Sun Oct 25 13:28:14 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 0281cd6caa8c sys/src/cmd/rc/lex.c --- a/sys/src/cmd/rc/lex.c Sat Oct 24 17:24:59 2020 -0700 +++ b/sys/src/cmd/rc/lex.c Sun Oct 25 13:28:14 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 0281cd6caa8c sys/src/cmd/rc/pfnc.c --- a/sys/src/cmd/rc/pfnc.c Sat Oct 24 17:24:59 2020 -0700 +++ b/sys/src/cmd/rc/pfnc.c Sun Oct 25 13:28:14 2020 -0700 @@ -51,6 +51,7 @@ Xrdfn, "Xrdfn", Xsimple, "Xsimple", Xqw, "Xqw", + Xloc, "Xloc", 0}; void @@ -59,7 +60,7 @@ int i; void (*fn)(void) = t->code[t->pc].f; list *a; - pfmt(fd, "pid %d cycle %p %d ", getpid(), t->code, t->pc); + pfmt(fd, "pid %d cycle %p %d %s:%d ", getpid(), t->code, t->pc, lexpath[t->loc>>LSHIFT], t->loc&LMASK); for(i = 0;fname[i].f;i++) if(fname[i].f==fn){ pstr(fd, fname[i].name); break; diff -r 0281cd6caa8c sys/src/cmd/rc/rc.h --- a/sys/src/cmd/rc/rc.h Sat Oct 24 17:24:59 2020 -0700 +++ b/sys/src/cmd/rc/rc.h Sun Oct 25 13:28:14 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, f, l; list *av; thread *p = runq; char *zero, *file; @@ -319,6 +319,12 @@ } else eflagok = 1; + + /* set up Xreturn to restore the right address */ + f = (lexfile > LFMAX) ? 0 : lexfile << LSHIFT; + l = (lexline > LMASK) ? -1 : lexline; + runq->loc = f|l; + popword(); if(p->argv->words && strcmp(p->argv->words->word, "-i")==0){ iflag = 1; @@ -354,6 +360,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 0281cd6caa8c sys/src/cmd/rc/tree.c --- a/sys/src/cmd/rc/tree.c Sat Oct 24 17:24:59 2020 -0700 +++ b/sys/src/cmd/rc/tree.c Sun Oct 25 13:28:14 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; }