From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mimir.eigenstate.org ([206.124.132.107]) by ewsd; Sun Oct 25 21:33:51 -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 4226ef98 (TLSv1.2:ECDHE-RSA-AES256-SHA:256:NO); Sun, 25 Oct 2020 18:33:42 -0700 (PDT) Message-ID: To: cinap_lenrek@felloff.net, 9front@9front.org Subject: Re: [9front] rc: null list in concatenation line numbers Date: Sun, 25 Oct 2020 18:33:40 -0700 From: ori@eigenstate.org In-Reply-To: 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: optimized property-oriented realtime solution > hm... thinking about it. basically, change of file can > only happen when we do execdot() *AND* when calling a > function. > > but this should be easy. we could have a Xsrcfile pseudo > operation that just updates the filename and has the > filename as a immediate string in the opstream. > > in fact, you could even just have a Xdbgname() that sets > a generic stirng prefix, so you could also capture the > function name. After spending some time experimenting with this approach, it feels fragile with the code as is. Xreturn also changes the filename, and it's a bit messy to keep the file in sync with the current code. Here's the current iteration: 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 18:23:40 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,26 @@ 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->line != line || lexfile != file){ + line = t->line; + file = lexfile; + /* + * 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 = (lexfile > LFMAX) ? 0 : lexfile << LSHIFT; + l = (t->line > LMASK) ? 0 : t->line; + 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 18:23:40 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 = emalloc(sizeof(char*)); + nlexpath = 1; + lexpath[0] = strdup("unknown"); + 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,9 @@ { globlist(runq->argv->words); } + +void +Xloc(void) +{ + runq->loc = runq->code[runq->pc++].i; +} 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 18:23:40 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 18:23:40 2020 -0700 @@ -25,6 +25,15 @@ int doprompt = 1; int inquote; int incomm; +int lastc; +int ndot; +int nerror; +int lexline; +int lexfile; +char **lexpath; +int nlexpath; +int lexpathsz; + /* * Look ahead in the input stream */ @@ -39,13 +48,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 18:23:40 2020 -0700 @@ -51,6 +51,7 @@ Xrdfn, "Xrdfn", Xsimple, "Xsimple", Xqw, "Xqw", + Xloc, "Xloc", 0}; void @@ -59,7 +60,8 @@ 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, "%s:%d: pid %d cycle %p %d ", lexpath[t->loc>>LSHIFT], t->loc&LMASK, getpid(), t->code, t->pc); 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 18:23:40 2020 -0700 @@ -43,6 +43,7 @@ char *str; int quoted; int iskw; + int line; tree *child[3]; tree *next; }; @@ -54,6 +55,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; } @@ -257,9 +257,16 @@ union code rdcmds[4]; void -execcmds(io *f) +execcmds(io *in) { static int first = 1; + int f, l; + + /* set up Xreturn to restore the right address */ + f = (lexfile > LFMAX) ? 0 : lexfile << LSHIFT; + l = (lexline > LMASK) ? 0 : lexline; + runq->loc = f|l; + if(first){ rdcmds[0].i = 1; rdcmds[1].f = Xrdcmds; @@ -267,7 +274,7 @@ first = 0; } start(rdcmds, 1, runq->local); - runq->cmdfd = f; + runq->cmdfd = in; runq->iflast = 0; } @@ -294,7 +301,7 @@ execdot(void) { int iflag = 0; - int fd; + int fd, i, f, l; list *av; thread *p = runq; char *zero, *file; @@ -319,6 +326,12 @@ } else eflagok = 1; + + /* set up Xreturn to restore the right address */ + f = (lexfile > LFMAX) ? 0 : lexfile << LSHIFT; + l = (lexline > LMASK) ? 0 : lexline; + runq->loc = f|l; + popword(); if(p->argv->words && strcmp(p->argv->words->word, "-i")==0){ iflag = 1; @@ -354,6 +367,23 @@ Xerror(".: can't open"); return; } + + lexline = 1; + lexfile = 0; + for(i = 0; i < nlexpath; i++){ + if(strcmp(lexpath[i], zero) == 0){ + lexfile = i; + break; + } + } + if(i == nlexpath && i < LFMAX){ + if(nlexpath == lexpathsz){ + lexpathsz *= 2; + lexpath = erealloc(lexpath, lexpathsz*sizeof(char*)); + } + lexpath[nlexpath] = estrdup(zero); + lexfile = nlexpath++; + } /* 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 18:23:40 2020 -0700 @@ -16,6 +16,7 @@ t->str = 0; t->child[0] = t->child[1] = t->child[2] = 0; t->next = treenodes; + t->line = lexline; treenodes = t; return t; }