Skip to content

Commit

Permalink
Simplify VCC's handling of procedures.
Browse files Browse the repository at this point in the history
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 f7860ad
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 152 deletions.
77 changes: 37 additions & 40 deletions lib/libvcc/vcc_compile.c
Expand Up @@ -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"
Expand Down Expand Up @@ -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)
{
Expand All @@ -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
*/
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;

Expand All @@ -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);
Expand Down
25 changes: 19 additions & 6 deletions lib/libvcc/vcc_compile.h
Expand Up @@ -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];
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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
Expand All @@ -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);

Expand Down Expand Up @@ -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,
Expand Down
66 changes: 38 additions & 28 deletions lib/libvcc/vcc_parse.c
Expand Up @@ -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");
Expand Down

0 comments on commit f7860ad

Please sign in to comment.