[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