9front - general discussion about 9front
 help / color / mirror / Atom feed
From: ori@eigenstate.org
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	[thread overview]
Message-ID: <D4F895BF715AECA5A05DF790A038DABF@eigenstate.org> (raw)
In-Reply-To: <A818CA5FC6F0E642CBE18BF5A3249ACF@felloff.net>

> 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<<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 +140,16 @@
  */
 #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;
+extern int lexpathsz;
+
 /*
  * 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 18:23:40 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;
 }
@@ -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;
 }



  reply	other threads:[~2020-10-26  1:33 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
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 [this message]
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=D4F895BF715AECA5A05DF790A038DABF@eigenstate.org \
    --to=ori@eigenstate.org \
    --cc=9front@9front.org \
    --cc=cinap_lenrek@felloff.net \
    /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).