Permalink
Browse files

Simplify VCC's handling of procedures.

Give procedures proper data structures and stick the VCL methods into
the symbol table up front and GC a lot of small hacks and workarounds.
  • Loading branch information...
bsdphk committed Dec 5, 2017
1 parent b9f7170 commit f7860ad011378b60c8168726dec4462da668832f
Showing with 121 additions and 152 deletions.
  1. +37 −40 lib/libvcc/vcc_compile.c
  2. +19 −6 lib/libvcc/vcc_compile.h
  3. +38 −28 lib/libvcc/vcc_parse.c
  4. +27 −78 lib/libvcc/vcc_xref.c
View
@@ -62,7 +62,7 @@
#include "libvcc.h"
#include "vfil.h"
struct method method_tab[] = {
static const struct method method_tab[] = {
{ "none", 0U, 0},
#define VCL_MET_MAC(l,U,t,b) { "vcl_"#l, b, VCL_MET_##U },
#include "tbl/vcl_returns.h"
@@ -95,6 +95,24 @@ TlDup(struct vcc *tl, const char *s)
/*--------------------------------------------------------------------*/
struct proc *
vcc_NewProc(struct vcc *tl, struct symbol *sym)
{
struct proc *p;
ALLOC_OBJ(p, PROC_MAGIC);
AN(p);
VTAILQ_INIT(&p->calls);
VTAILQ_INIT(&p->uses);
VTAILQ_INSERT_TAIL(&tl->procs, p, list);
p->body = VSB_new_auto();
AN(p->body);
sym->proc = p;
return (p);
}
/*--------------------------------------------------------------------*/
struct inifin *
New_IniFin(struct vcc *tl)
{
@@ -111,25 +129,6 @@ New_IniFin(struct vcc *tl)
return (p);
}
/*--------------------------------------------------------------------*/
int
IsMethod(const struct token *t)
{
int i;
assert(t->tok == ID);
for (i = 1; method_tab[i].name != NULL; i++) {
if (vcc_IdIs(t, method_tab[i].name))
return (i);
}
if ((t->b[0] == 'v'|| t->b[0] == 'V') &&
(t->b[1] == 'c'|| t->b[1] == 'C') &&
(t->b[2] == 'l'|| t->b[2] == 'L'))
return (-2);
return (-1);
}
/*--------------------------------------------------------------------
* Printf output to the vsbs, possibly indented
*/
@@ -535,10 +534,10 @@ static struct vsb *
vcc_CompileSource(struct vcc *tl, struct source *sp)
{
struct symbol *sym;
struct proc *p;
const struct var *v;
struct vsb *vsb;
struct inifin *ifp;
int i;
vcc_Expr_Init(tl);
@@ -626,26 +625,19 @@ vcc_CompileSource(struct vcc *tl, struct source *sp)
/* Emit method functions */
Fh(tl, 1, "\n");
for (i = 1; i < VCL_MET_MAX; i++) {
VTAILQ_FOREACH(p, &tl->procs, list) {
if (p->method == NULL)
continue;
Fh(tl, 1,
"void v_matchproto_(vcl_func_f) "
"VGC_function_%s(VRT_CTX);\n",
method_tab[i].name);
p->method->name);
Fc(tl, 1, "\nvoid v_matchproto_(vcl_func_f)\n");
Fc(tl, 1,
"VGC_function_%s(VRT_CTX)\n",
method_tab[i].name);
AZ(VSB_finish(tl->fm[i]));
Fc(tl, 1, "{\n");
/*
* We want vmods to be able set a FAIL return value
* in members called from vcl_init, so set OK up front
* and return with whatever was set last.
*/
Fc(tl, 1, "%s", VSB_data(tl->fm[i]));
if (method_tab[i].bitval == VCL_MET_INIT)
Fc(tl, 1, " return;\n");
Fc(tl, 1, "}\n");
Fc(tl, 1, "VGC_function_%s(VRT_CTX)\n",
p->method->name);
AZ(VSB_finish(p->body));
Fc(tl, 1, "{\n%s}\n", VSB_data(p->body));
VSB_destroy(&p->body);
}
EmitInitFini(tl);
@@ -710,13 +702,16 @@ struct vcc *
VCC_New(void)
{
struct vcc *tl;
struct symbol *sym;
struct proc *p;
int i;
ALLOC_OBJ(tl, VCC_MAGIC);
AN(tl);
VTAILQ_INIT(&tl->inifin);
VTAILQ_INIT(&tl->tokens);
VTAILQ_INIT(&tl->sources);
VTAILQ_INIT(&tl->procs);
tl->nsources = 0;
@@ -729,9 +724,11 @@ VCC_New(void)
tl->fh = VSB_new_auto();
assert(tl->fh != NULL);
for (i = 0; i < VCL_MET_MAX; i++) {
tl->fm[i] = VSB_new_auto();
assert(tl->fm[i] != NULL);
for (i = 1; i < VCL_MET_MAX; i++) {
sym = VCC_Symbol(tl, NULL,
method_tab[i].name, NULL, SYM_SUB, 1);
p = vcc_NewProc(tl, sym);
p->method = &method_tab[i];
}
tl->sb = VSB_new_auto();
AN(tl->sb);
View
@@ -49,6 +49,7 @@
struct vsb;
struct token;
struct sockaddr_storage;
struct method;
unsigned vcl_fixed_token(const char *p, const char **q);
extern const char * const vcl_tnames[256];
@@ -146,6 +147,21 @@ struct symbol {
VTAILQ_HEAD(tokenhead, token);
struct proc {
unsigned magic;
#define PROC_MAGIC 0xd1d98499
const struct method *method;
VTAILQ_HEAD(,proccall) calls;
VTAILQ_HEAD(,procuse) uses;
VTAILQ_ENTRY(proc) list;
struct token *name;
unsigned ret_bitmap;
unsigned called;
unsigned active;
struct token *return_tok[VCL_RET_MAX];
struct vsb *body;
};
struct inifin {
unsigned magic;
#define INIFIN_MAGIC 0x583c274c
@@ -191,11 +207,10 @@ struct vcc {
struct vsb *fb; /* Body of current sub
* NULL otherwise
*/
struct vsb *fm[VCL_MET_MAX]; /* Method bodies */
struct vsb *sb;
int err;
struct proc *curproc;
struct proc *mprocs[VCL_MET_MAX];
VTAILQ_HEAD(, proc) procs;
VTAILQ_HEAD(, acl_e) acl;
@@ -244,8 +259,8 @@ void vcc_IsField(struct vcc *tl, struct token **t, struct fld_spec *fs);
void vcc_FieldsOk(struct vcc *tl, const struct fld_spec *fs);
/* vcc_compile.c */
extern struct method method_tab[];
struct inifin *New_IniFin(struct vcc *tl);
struct inifin *New_IniFin(struct vcc *);
struct proc *vcc_NewProc(struct vcc*, struct symbol*);
/*
* H -> Header, before the C code
@@ -261,7 +276,6 @@ void Fc(const struct vcc *tl, int indent, const char *fmt, ...)
void Fb(const struct vcc *tl, int indent, const char *fmt, ...)
v_printflike_(3, 4);
void EncToken(struct vsb *sb, const struct token *t);
int IsMethod(const struct token *t);
void *TlAlloc(struct vcc *tl, unsigned len);
char *TlDup(struct vcc *tl, const char *s);
@@ -346,7 +360,6 @@ int vcc_CheckReferences(struct vcc *tl);
void VCC_XrefTable(struct vcc *);
void vcc_AddCall(struct vcc *tl, struct token *t);
struct proc *vcc_AddProc(struct vcc *tl, struct token *t);
void vcc_ProcAction(struct proc *p, unsigned action, struct token *t);
int vcc_CheckAction(struct vcc *tl);
void vcc_AddUses(struct vcc *tl, const struct token *t, unsigned mask,
View
@@ -209,48 +209,58 @@ static void
vcc_ParseFunction(struct vcc *tl)
{
struct symbol *sym;
int m, i;
struct proc *p;
vcc_NextToken(tl);
vcc_ExpectVid(tl, "function");
ERRCHK(tl);
m = IsMethod(tl->t);
if (m == -2) {
VSB_printf(tl->sb,
"VCL sub's named 'vcl*' are reserved names.\n");
sym = vcc_AddDef(tl, tl->t, SYM_SUB);
AN(sym);
p = sym->proc;
if (p == NULL) {
if ((tl->t->b[0] == 'v'|| tl->t->b[0] == 'V') &&
(tl->t->b[1] == 'c'|| tl->t->b[1] == 'C') &&
(tl->t->b[2] == 'l'|| tl->t->b[2] == 'L')) {
VSB_printf(tl->sb,
"VCL sub's named 'vcl*' are reserved names.\n");
vcc_ErrWhere(tl, tl->t);
VSB_printf(tl->sb, "Valid vcl_* methods are:\n");
VTAILQ_FOREACH(p, &tl->procs, list) {
if (p->method != NULL)
VSB_printf(tl->sb, "\t%s\n",
p->method->name);
}
return;
}
VCC_GlobalSymbol(sym, SUB, "VGC_function");
p = vcc_NewProc(tl, sym);
p->name = tl->t;
tl->fb = tl->fc;
Fh(tl, 0, "void %s(VRT_CTX);\n", sym->rname);
Fc(tl, 1, "\nvoid v_matchproto_(vcl_func_t)\n");
Fc(tl, 1, "%s(VRT_CTX)\n", sym->rname);
} else if (p->method == NULL) {
VSB_printf(tl->sb, "Function '%s' redefined\n", sym->name);
vcc_ErrWhere(tl, tl->t);
VSB_printf(tl->sb, "Valid vcl_* methods are:\n");
for (i = 1; method_tab[i].name != NULL; i++)
VSB_printf(tl->sb, "\t%s\n", method_tab[i].name);
VSB_printf(tl->sb, "Previously defined here:\n");
vcc_ErrWhere(tl, p->name);
return;
} else if (m != -1) {
assert(m < VCL_MET_MAX);
tl->fb = tl->fm[m];
if (tl->mprocs[m] == NULL) {
} else {
/* Add to VCL sub */
AN(p->method);
if (p->name == NULL) {
(void)vcc_AddDef(tl, tl->t, SYM_SUB);
(void)vcc_AddRef(tl, tl->t, SYM_SUB);
tl->mprocs[m] = vcc_AddProc(tl, tl->t);
p->name = tl->t;
}
tl->curproc = tl->mprocs[m];
tl->fb = p->body;
Fb(tl, 1, " /* ... from ");
vcc_Coord(tl, tl->fb, NULL);
Fb(tl, 0, " */\n");
} else {
tl->fb = tl->fc;
sym = vcc_AddDef(tl, tl->t, SYM_SUB);
VCC_GlobalSymbol(sym, SUB, "VGC_function");
if (sym->ndef > 1) {
VSB_printf(tl->sb,
"Function '%s' redefined\n", sym->name);
vcc_ErrWhere(tl, tl->t);
return;
}
tl->curproc = vcc_AddProc(tl, tl->t);
Fh(tl, 0, "void %s(VRT_CTX);\n", sym->rname);
Fc(tl, 1, "\nvoid v_matchproto_(vcl_func_t)\n");
Fc(tl, 1, "%s(VRT_CTX)\n", sym->rname);
}
CHECK_OBJ_NOTNULL(p, PROC_MAGIC);
tl->curproc = p;
vcc_NextToken(tl);
tl->indent += INDENT;
Fb(tl, 1, "{\n");
Oops, something went wrong.

0 comments on commit f7860ad

Please sign in to comment.