From: ori@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 [thread overview]
Message-ID: <37CF109B904B5F178848E0FADF7E5CAF@eigenstate.org> (raw)
In-Reply-To: <9661591FC410B16CA272B221336B866C@eigenstate.org>
>> 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<<LSHIFT)-1)
+#define LFMAX (1<<(8*sizeof(int)-LSHIFT-1))
+
/*
* The first word of any code vector is a reference count.
* Always create a new reference to a code vector by calling codecopy(.).
@@ -126,10 +141,15 @@
*/
#define onebyte(c) ((c&0x80)==0x00)
-char **argp;
-char **args;
-int nerror; /* number of errors encountered during compilation */
-int doprompt; /* is it time for a prompt? */
+extern char **argp;
+extern char **args;
+extern int nerror; /* number of errors encountered during compilation */
+extern int doprompt; /* is it time for a prompt? */
+extern int lexfile;
+extern int lexline;
+extern char **lexpath;
+extern int nlexpath;
+
/*
* Which fds are the reading/writing end of a pipe?
* Unfortunately, this can vary from system to system.
@@ -143,7 +163,7 @@
* How many dot commands have we executed?
* Used to ensure that -v flag doesn't print rcmain.
*/
-int ndot;
+extern int ndot;
+extern int lastc;
+extern int lastword;
char *getstatus(void);
-int lastc;
-int lastword;
diff -r 0281cd6caa8c sys/src/cmd/rc/simple.c
--- a/sys/src/cmd/rc/simple.c Sat Oct 24 17:24:59 2020 -0700
+++ b/sys/src/cmd/rc/simple.c Sun Oct 25 13:28:14 2020 -0700
@@ -11,7 +11,7 @@
*/
int
exitnext(void){
- union code *c=&runq->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;
}
next prev parent reply other threads:[~2020-10-25 20:29 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-10-16 1:40 ori
2020-10-16 3:43 ` [9front] " Xiao-Yong Jin
2020-10-17 1:47 ` ori
2020-10-16 5:40 ` Iruatã Souza
2020-10-22 1:18 ` ori
2020-10-22 12:11 ` tlaronde
2020-10-25 20:29 ` ori [this message]
2020-10-25 23:18 ` cinap_lenrek
2020-10-26 1:00 ` ori
2020-10-25 23:41 ` cinap_lenrek
2020-10-26 1:33 ` ori
2020-10-26 7:36 ` cinap_lenrek
2020-10-28 3:16 ` ori
2020-10-28 9:50 ` cinap_lenrek
2020-10-28 17:59 ` ori
2020-10-31 1:55 ` ori
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=37CF109B904B5F178848E0FADF7E5CAF@eigenstate.org \
--to=ori@eigenstate.org \
--cc=9front@9front.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).