[master] 0148166 Convert the VCC symbol table from flat to hierarchy.

Poul-Henning Kamp phk at FreeBSD.org
Mon Jun 6 15:09:07 CEST 2016


commit 0148166a64d8900d535ea40c68af670be9d2412c
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Mon Jun 6 12:36:42 2016 +0000

    Convert the VCC symbol table from flat to hierarchy.
    
    This includes various ugly workarounds for some of the things I
    hope to clean up with this change.

diff --git a/include/tbl/symbol_kind.h b/include/tbl/symbol_kind.h
index e9add4a..bd90016 100644
--- a/include/tbl/symbol_kind.h
+++ b/include/tbl/symbol_kind.h
@@ -32,6 +32,7 @@ VCC_SYMB(NONE,		none)
 VCC_SYMB(ACL,		acl)
 VCC_SYMB(BACKEND,	backend)
 VCC_SYMB(FUNC,		func)		/* VMOD function/procedure */
+VCC_SYMB(INSTANCE,	instance)
 VCC_SYMB(METHOD,	method)
 VCC_SYMB(OBJECT,	object)
 VCC_SYMB(PROBE,		probe)
diff --git a/lib/libvcc/vcc_action.c b/lib/libvcc/vcc_action.c
index aa78adb..e089afd 100644
--- a/lib/libvcc/vcc_action.c
+++ b/lib/libvcc/vcc_action.c
@@ -174,7 +174,7 @@ parse_new(struct vcc *tl)
 		return;
 	}
 
-	sy1 = VCC_AddSymbolTok(tl, tl->t, SYM_NONE);	// XXX: NONE ?
+	sy1 = VCC_AddSymbolTok(tl, tl->t, SYM_INSTANCE);
 	XXXAN(sy1);
 	sy1->def_b = tl->t;
 	vcc_NextToken(tl);
@@ -218,7 +218,8 @@ parse_new(struct vcc *tl)
 	vcc_NextToken(tl);
 
 	bprintf(buf1, ", &vo_%s, \"%s\"", sy1->name, sy1->name);
-	vcc_Eval_Func(tl, s_init, buf1, sy2->name, s_init + strlen(s_init) + 1);
+	vcc_Eval_Func(tl, s_init, buf1, sy2->name, s_init + strlen(s_init) + 1,
+	    sy2->vmod);
 	ifp = New_IniFin(tl);
 	VSB_printf(ifp->fin, "\t\t%s(&vo_%s);", s_fini, sy1->name);
 	ExpectErr(tl, ';');
diff --git a/lib/libvcc/vcc_compile.h b/lib/libvcc/vcc_compile.h
index 8ba41c0..de1cc7e 100644
--- a/lib/libvcc/vcc_compile.h
+++ b/lib/libvcc/vcc_compile.h
@@ -106,8 +106,8 @@ enum symkind {
 
 typedef void sym_expr_t(struct vcc *tl, struct expr **,
     const struct symbol *sym, enum var_type);
-typedef struct symbol *sym_wildcard_t(struct vcc *tl, const struct token *t,
-    const struct symbol *sym);
+typedef void sym_wildcard_t(struct vcc *, struct symbol *,
+    const char *, const char *);
 
 struct symbol {
 	unsigned			magic;
@@ -115,6 +115,8 @@ struct symbol {
 	VTAILQ_ENTRY(symbol)		list;
 	VTAILQ_HEAD(,symbol)		children;
 
+	const char			*vmod;
+
 	char				*name;
 	unsigned			nlen;
 	sym_wildcard_t			*wildcard;
@@ -289,7 +291,7 @@ sym_expr_t vcc_Eval_Var;
 sym_expr_t vcc_Eval_Handle;
 sym_expr_t vcc_Eval_SymFunc;
 void vcc_Eval_Func(struct vcc *tl, const char *cfunc, const char *extra,
-    const char *name, const char *args);
+    const char *name, const char *args, const char *vmod);
 enum var_type VCC_arg_type(const char **p);
 enum symkind VCC_HandleKind(enum var_type fmt);
 struct symbol *VCC_HandleSymbol(struct vcc *, const struct token *,
@@ -312,6 +314,8 @@ void Resolve_Sockaddr(struct vcc *tl, const char *host, const char *defport,
     const struct token *t_err, const char *errid);
 
 /* vcc_symb.c */
+struct symbol *VCC_Symbol(struct vcc *, struct symbol *,
+    const char *, const char *, enum symkind, int);
 struct symbol *VCC_AddSymbolStr(struct vcc *tl, const char *name, enum symkind);
 struct symbol *VCC_AddSymbolTok(struct vcc *tl, const struct token *t,
     enum symkind kind);
diff --git a/lib/libvcc/vcc_expr.c b/lib/libvcc/vcc_expr.c
index 8284618..90cd47e 100644
--- a/lib/libvcc/vcc_expr.c
+++ b/lib/libvcc/vcc_expr.c
@@ -537,18 +537,15 @@ vcc_Eval_Var(struct vcc *tl, struct expr **e, const struct symbol *sym,
  */
 
 static struct expr *
-vcc_priv_arg(struct vcc *tl, const char *p, const char *name)
+vcc_priv_arg(struct vcc *tl, const char *p, const char *name, const char *vmod)
 {
-	const char *r;
 	struct expr *e2;
 	char buf[32];
 	struct inifin *ifp;
 
+	(void)name;
 	if (!strcmp(p, "PRIV_VCL")) {
-		r = strchr(name, '.');
-		AN(r);
-		e2 = vcc_mk_expr(VOID, "&vmod_priv_%.*s",
-		    (int) (r - name), name);
+		e2 = vcc_mk_expr(VOID, "&vmod_priv_%s", vmod);
 	} else if (!strcmp(p, "PRIV_CALL")) {
 		bprintf(buf, "vmod_priv_%u", tl->unique++);
 		ifp = New_IniFin(tl);
@@ -556,17 +553,11 @@ vcc_priv_arg(struct vcc *tl, const char *p, const char *name)
 		VSB_printf(ifp->fin, "\tVRT_priv_fini(&%s);", buf);
 		e2 = vcc_mk_expr(VOID, "&%s", buf);
 	} else if (!strcmp(p, "PRIV_TASK")) {
-		r = strchr(name, '.');
-		AN(r);
 		e2 = vcc_mk_expr(VOID,
-		    "VRT_priv_task(ctx, &VGC_vmod_%.*s)",
-		    (int) (r - name), name);
+		    "VRT_priv_task(ctx, &VGC_vmod_%s)", vmod);
 	} else if (!strcmp(p, "PRIV_TOP")) {
-		r = strchr(name, '.');
-		AN(r);
 		e2 = vcc_mk_expr(VOID,
-		    "VRT_priv_top(ctx, &VGC_vmod_%.*s)",
-		    (int) (r - name), name);
+		    "VRT_priv_top(ctx, &VGC_vmod_%s)", vmod);
 	} else {
 		WRONG("Wrong PRIV_ type");
 	}
@@ -633,7 +624,7 @@ vcc_do_arg(struct vcc *tl, struct func_arg *fa)
 
 static void
 vcc_func(struct vcc *tl, struct expr **e, const char *cfunc,
-    const char *extra, const char *name, const char *args)
+    const char *extra, const char *name, const char *args, const char *vmod)
 {
 	const char *p;
 	struct expr *e1;
@@ -657,7 +648,7 @@ vcc_func(struct vcc *tl, struct expr **e, const char *cfunc,
 		VTAILQ_INSERT_TAIL(&head, fa, list);
 		fa->type = VCC_arg_type(&p);
 		if (fa->type == VOID && !memcmp(p, "PRIV_", 5)) {
-			fa->result = vcc_priv_arg(tl, p, name);
+			fa->result = vcc_priv_arg(tl, p, name, vmod);
 			fa->name = "";
 			p += strlen(p) + 1;
 			continue;
@@ -751,13 +742,13 @@ vcc_func(struct vcc *tl, struct expr **e, const char *cfunc,
 
 void
 vcc_Eval_Func(struct vcc *tl, const char *cfunc,
-    const char *extra, const char *name, const char *args)
+    const char *extra, const char *name, const char *args, const char *vmod)
 {
 	struct expr *e = NULL;
 	struct token *t1;
 
 	t1 = tl->t;
-	vcc_func(tl, &e, cfunc, extra, name, args);
+	vcc_func(tl, &e, cfunc, extra, name, args, vmod);
 	if (!tl->err) {
 		vcc_expr_fmt(tl->fb, tl->indent, e);
 		VSB_cat(tl->fb, ";\n");
@@ -782,7 +773,8 @@ vcc_Eval_SymFunc(struct vcc *tl, struct expr **e, const struct symbol *sym,
 	AN(sym->name);
 	AN(sym->args);
 	SkipToken(tl, ID);
-	vcc_func(tl, e, sym->cfunc, sym->extra, sym->name, sym->args);
+	vcc_func(tl, e, sym->cfunc, sym->extra, sym->name, sym->args,
+	    sym->vmod);
 }
 
 /*--------------------------------------------------------------------
diff --git a/lib/libvcc/vcc_storage.c b/lib/libvcc/vcc_storage.c
index efc4f11..878c727 100644
--- a/lib/libvcc/vcc_storage.c
+++ b/lib/libvcc/vcc_storage.c
@@ -61,21 +61,18 @@
 
 #include "vcc_compile.h"
 
-#define PFX "storage."
-
 /*--------------------------------------------------------------------
  *
  */
 
 static struct var *
-vcc_Stv_mkvar(struct vcc *tl, const struct token *t, enum var_type fmt)
+vcc_Stv_mkvar(struct vcc *tl, enum var_type fmt)
 {
 	struct var *v;
 
 	v = TlAlloc(tl, sizeof *v);
 	AN(v);
 
-	v->name = TlDupTok(tl, t);
 	v->r_methods = 0;
 #define VCL_MET_MAC(l,u,t,b)	v->r_methods |= VCL_MET_##u;
 #include "tbl/vcl_returns.h"
@@ -95,39 +92,34 @@ static struct stvars {
 	{ NULL,			BOOL }
 };
 
-struct symbol *
-vcc_Stv_Wildcard(struct vcc *tl, const struct token *t,
-    const struct symbol *wcsym)
+void __match_proto__(sym_wildcard_t)
+vcc_Stv_Wildcard(struct vcc *tl, struct symbol *parent,
+    const char *b, const char *e)
 {
-	const char *p, *q;
+	const char *q;
 	struct var *v = NULL;
 	struct symbol *sym;
 	struct stvars *sv;
 	char stv[1024];
 	char buf[1024];
 
-	(void)wcsym;
-	assert((t->e - t->b) > strlen(PFX));
-	AZ(memcmp(t->b, PFX, strlen(PFX)));
-
-	p = t->b + strlen(PFX);
-	for (q = p; q < t->e && *q != '.'; q++)
+	for (q = b; q < e && *q != '.'; q++)
 		continue;
-	bprintf(stv, "%.*s", (int)(q - p), p);
+	bprintf(stv, "%.*s", (int)(q - b), b);
 
-	if (q == t->e) {
-		v = vcc_Stv_mkvar(tl, t, BOOL);
+	if (q == e) {
+		v = vcc_Stv_mkvar(tl, BOOL);
 		bprintf(buf, "VRT_Stv(\"%s\")", stv);
 		v->rname = TlDup(tl, buf);
 	} else {
 		assert(*q  == '.');
 		q++;
 		for(sv = stvars; sv->name != NULL; sv++) {
-			if (strncmp(q, sv->name, t->e - q))
+			if (strncmp(q, sv->name, e - q))
 				continue;
-			if (sv->name[t->e - q] != '\0')
+			if (sv->name[e - q] != '\0')
 				continue;
-			v = vcc_Stv_mkvar(tl, t, sv->fmt);
+			v = vcc_Stv_mkvar(tl, sv->fmt);
 			bprintf(buf, "VRT_Stv_%s(\"%s\")", sv->name, stv);
 			v->rname = TlDup(tl, buf);
 			break;
@@ -135,9 +127,9 @@ vcc_Stv_Wildcard(struct vcc *tl, const struct token *t,
 	}
 
 	if (v == NULL)
-		return (NULL);
+		return;
 
-	sym = VCC_AddSymbolTok(tl, t, SYM_VAR);
+	sym = VCC_Symbol(tl, parent, b, e, SYM_VAR, 1);
 	AN(sym);
 	sym->fmt = v->fmt;
 	sym->eval = vcc_Eval_Var;
@@ -145,6 +137,4 @@ vcc_Stv_Wildcard(struct vcc *tl, const struct token *t,
 	sym->rname = v->rname;
 	sym->w_methods = v->w_methods;
 	sym->lname = v->lname;
-
-	return (sym);
 }
diff --git a/lib/libvcc/vcc_symb.c b/lib/libvcc/vcc_symb.c
index 38127a3..be40cc1 100644
--- a/lib/libvcc/vcc_symb.c
+++ b/lib/libvcc/vcc_symb.c
@@ -86,30 +86,83 @@ vcc_new_symbol(struct vcc *tl, const char *b, const char *e)
 	return (sym);
 }
 
-static struct symbol *
-vcc_AddSymbol(struct vcc *tl, const char *nb, int l, enum symkind kind)
+struct symbol *
+VCC_Symbol(struct vcc *tl, struct symbol *parent,
+    const char *b, const char *e, enum symkind kind, int create)
 {
-	struct symbol *sym;
+	const char *q;
+	struct symbol *sym, *sym2 = NULL;
+	size_t l;
+	int i;
 
 	if (tl->symbols == NULL)
 		tl->symbols = vcc_new_symbol(tl, "<root>", NULL);
+	if (parent == NULL)
+		parent = tl->symbols;
+
+	AN(b);
+	assert(e == NULL || b < e);
+	if (e == NULL)
+		e = strchr(b, '\0');
+	assert(e > b);
+	if (e[-1] == '.')
+		e--;
+	assert(e > b);
 
-	VTAILQ_FOREACH(sym, &tl->symbols->children, list) {
-		if (sym->nlen != l)
+	q = strchr(b, '.');
+	if (q == NULL || q > e)
+		q = e;
+	l = q - b;
+	assert(l > 0);
+
+	VTAILQ_FOREACH(sym, &parent->children, list) {
+		i = strncmp(sym->name, b, l);
+		if (i < 0)
 			continue;
-		if (memcmp(nb, sym->name, l))
+		if (i > 0 || l < sym->nlen) {
+			sym2 = sym;
+			sym = NULL;
+			break;
+		}
+		if (l > sym->nlen)
 			continue;
-		if (kind != sym->kind)
+		if (q < e)
+			break;
+		if (kind != SYM_NONE && sym->kind != kind)
 			continue;
-		VSB_printf(tl->sb, "Name Collision: <%.*s> <%s>\n",
-		    l, nb, VCC_SymKind(tl, sym));
-		ErrInternal(tl);
-		return (NULL);
+		if (kind == SYM_NONE && sym->kind == kind)
+			continue;
+		break;
 	}
-	sym = vcc_new_symbol(tl, nb, nb + l);
-	VTAILQ_INSERT_HEAD(&tl->symbols->children, sym, list);
-	sym->kind = kind;
-	return (sym);
+	if (sym == NULL && create == 0 && parent->kind == SYM_WILDCARD) {
+		AN(parent->wildcard);
+		parent->wildcard(tl, parent, b, e);
+		if (tl->err)
+			return (NULL);
+		return (VCC_Symbol(tl, parent, b, e, kind, -1));
+	}
+	if (sym == NULL && create < 1)
+		return (sym);
+	if (sym == NULL) {
+		sym = vcc_new_symbol(tl, b, q);
+		if (sym2 != NULL)
+			VTAILQ_INSERT_BEFORE(sym2, sym, list);
+		else
+			VTAILQ_INSERT_TAIL(&parent->children, sym, list);
+		if (q == e)
+			sym->kind = kind;
+	}
+	if (q == e)
+		return (sym);
+	assert(*q == '.');
+	return (VCC_Symbol(tl, sym, ++q, e, kind, create));
+}
+
+static struct symbol *
+vcc_AddSymbol(struct vcc *tl, const char *nb, int l, enum symkind kind)
+{
+
+	return(VCC_Symbol(tl, NULL, nb, nb + l, kind, 1));
 }
 
 struct symbol *
@@ -143,36 +196,32 @@ VCC_GetSymbolTok(struct vcc *tl, const struct token *tok, enum symkind kind)
 struct symbol *
 VCC_FindSymbol(struct vcc *tl, const struct token *t, enum symkind kind)
 {
-	struct symbol *sym;
 
 	assert(t->tok == ID);
-	VTAILQ_FOREACH(sym, &tl->symbols->children, list) {
-		if (sym->kind == SYM_WILDCARD &&
-		   (t->e - t->b > sym->nlen) &&
-		   !memcmp(sym->name, t->b, sym->nlen)) {
-			AN(sym->wildcard);
-			return (sym->wildcard(tl, t, sym));
-		}
-		if (kind != SYM_NONE && kind != sym->kind)
-			continue;
-		if (vcc_IdIs(t, sym->name))
-			return (sym);
-	}
-	return (NULL);
+	return (VCC_Symbol(tl, NULL, t->b, t->e, kind, 0));
 }
 
-void
-VCC_WalkSymbols(struct vcc *tl, symwalk_f *func, enum symkind kind)
+static void
+vcc_walksymbols(struct vcc *tl, const struct symbol *root,
+    symwalk_f *func, enum symkind kind)
 {
 	struct symbol *sym;
 
-	VTAILQ_FOREACH(sym, &tl->symbols->children, list) {
+	VTAILQ_FOREACH(sym, &root->children, list) {
 		if (kind == SYM_NONE || kind == sym->kind)
 			func(tl, sym);
 		ERRCHK(tl);
+		vcc_walksymbols(tl, sym, func, kind);
 	}
 }
 
+void
+VCC_WalkSymbols(struct vcc *tl, symwalk_f *func, enum symkind kind)
+{
+
+	vcc_walksymbols(tl, tl->symbols, func, kind);
+}
+
 static void
 vcc_global(struct vcc *tl, struct symbol *sym,
     enum var_type fmt, const char *str, va_list ap)
diff --git a/lib/libvcc/vcc_var.c b/lib/libvcc/vcc_var.c
index 6bd5dec..3f4ef81 100644
--- a/lib/libvcc/vcc_var.c
+++ b/lib/libvcc/vcc_var.c
@@ -37,32 +37,31 @@
 
 /*--------------------------------------------------------------------*/
 
-struct symbol *
-vcc_Var_Wildcard(struct vcc *tl, const struct token *t, const struct symbol *wc)
+void __match_proto__(sym_wildcard_t)
+vcc_Var_Wildcard(struct vcc *tl, struct symbol *parent,
+    const char *b, const char *e)
 {
 	struct symbol *sym;
 	struct var *v;
 	const struct var *vh;
 	unsigned u;
-	const char *p, *leaf;
+	const char *p;
 	struct vsb *vsb;
 
-	vh = wc->wildcard_priv;
+	vh = parent->wildcard_priv;
 	assert(vh->fmt == HEADER);
 
 	v = TlAlloc(tl, sizeof *v);
 	AN(v);
-	v->name = TlDupTok(tl, t);
 	v->r_methods = vh->r_methods;
 	v->w_methods = vh->w_methods;
 	v->fmt = vh->fmt;
-	leaf = v->name + vh->len;
 
 	/* Create a C-name version of the header name */
 	vsb = VSB_new_auto();
 	AN(vsb);
 	VSB_printf(vsb, "&VGC_%s_", vh->rname);
-	for (p = leaf, u = 1; *p != '\0'; p++, u++)
+	for (p = b, u = 1; p < e; p++, u++)
 		if (vct_isalpha(*p) || vct_isdigit(*p))
 			VSB_putc(vsb, *p);
 		else
@@ -71,7 +70,8 @@ vcc_Var_Wildcard(struct vcc *tl, const struct token *t, const struct symbol *wc)
 
 	/* Create the static identifier */
 	Fh(tl, 0, "static const struct gethdr_s %s =\n", VSB_data(vsb) + 1);
-	Fh(tl, 0, "    { %s, \"\\%03o%s:\"};\n", vh->rname, u, leaf);
+	Fh(tl, 0, "    { %s, \"\\%03o%.*s:\"};\n",
+	    vh->rname, u, (int)(e - b), b);
 
 	/* Create the symbol r/l values */
 	v->rname = TlDup(tl, VSB_data(vsb));
@@ -81,7 +81,7 @@ vcc_Var_Wildcard(struct vcc *tl, const struct token *t, const struct symbol *wc)
 	v->lname = TlDup(tl, VSB_data(vsb));
 	VSB_destroy(&vsb);
 
-	sym = VCC_AddSymbolTok(tl, t, SYM_VAR);
+	sym = VCC_Symbol(tl, parent, b, e, SYM_VAR, 1);
 	AN(sym);
 	sym->fmt = v->fmt;
 	sym->eval = vcc_Eval_Var;
@@ -89,7 +89,6 @@ vcc_Var_Wildcard(struct vcc *tl, const struct token *t, const struct symbol *wc)
 	sym->rname = v->rname;
 	sym->w_methods = v->w_methods;
 	sym->lname = v->lname;
-	return (sym);
 }
 
 /*--------------------------------------------------------------------*/
diff --git a/lib/libvcc/vcc_vmod.c b/lib/libvcc/vcc_vmod.c
index 06c2b92..07995c3 100644
--- a/lib/libvcc/vcc_vmod.c
+++ b/lib/libvcc/vcc_vmod.c
@@ -67,6 +67,7 @@ vcc_ParseImport(struct vcc *tl)
 	struct inifin *ifp;
 	const char * const *spec;
 	struct symbol *sym;
+	struct symbol *msym;
 	const struct symbol *osym;
 	const char *p;
 	// int *modlen;
@@ -96,11 +97,11 @@ vcc_ParseImport(struct vcc *tl)
 	}
 
 	bprintf(fn, "%.*s", PF(mod));
-	sym = VCC_AddSymbolStr(tl, fn, SYM_VMOD);
+	msym = VCC_AddSymbolStr(tl, fn, SYM_VMOD);
 	ERRCHK(tl);
-	AN(sym);
-	sym->def_b = t1;
-	sym->def_e = tl->t;
+	AN(msym);
+	msym->def_b = t1;
+	msym->def_e = tl->t;
 
 	if (tl->t->tok == ID) {
 		if (!vcc_IdIs(tl->t, "from")) {
@@ -222,6 +223,7 @@ vcc_ParseImport(struct vcc *tl)
 			sym = VCC_AddSymbolStr(tl, p, SYM_OBJECT);
 			XXXAN(sym);
 			sym->args = p;
+			sym->vmod = msym->name;
 		} else if (!strcmp(p, "$EVENT")) {
 			p += strlen(p) + 1;
 			if (ifp == NULL)
@@ -240,6 +242,7 @@ vcc_ParseImport(struct vcc *tl)
 			sym = VCC_AddSymbolStr(tl, p, SYM_FUNC);
 			ERRCHK(tl);
 			AN(sym);
+			sym->vmod = msym->name;
 			sym->eval = vcc_Eval_SymFunc;
 			p += strlen(p) + 1;
 			sym->cfunc = p;



More information about the varnish-commit mailing list