9front - general discussion about 9front
 help / color / mirror / Atom feed
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;
 }



  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).