Commit 8a73d957 authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

This is a very shaky first prototype of VMOD objects.

parent 25c5715a
...@@ -28,14 +28,16 @@ ...@@ -28,14 +28,16 @@
*/ */
/*lint -save -e525 -e539 */ /*lint -save -e525 -e539 */
VCC_SYMB(NONE, none, "undefined") VCC_SYMB(NONE, none)
VCC_SYMB(VAR, var, "variable") VCC_SYMB(VAR, var)
VCC_SYMB(FUNC, func, "function") /* VMOD function */ VCC_SYMB(FUNC, func) /* VMOD function */
VCC_SYMB(PROC, proc, "procedure") /* VMOD procedure */ VCC_SYMB(PROC, proc) /* VMOD procedure */
VCC_SYMB(VMOD, vmod, "vmod") VCC_SYMB(VMOD, vmod)
VCC_SYMB(ACL, acl, "acl") VCC_SYMB(ACL, acl)
VCC_SYMB(SUB, sub, "sub") /* VCL subroutine */ VCC_SYMB(SUB, sub) /* VCL subroutine */
VCC_SYMB(BACKEND, backend, "backend") VCC_SYMB(BACKEND, backend)
VCC_SYMB(PROBE, probe, "probe") VCC_SYMB(PROBE, probe)
VCC_SYMB(WILDCARD, wildcard, "wildcard") VCC_SYMB(WILDCARD, wildcard)
VCC_SYMB(OBJECT, object)
VCC_SYMB(METHOD, method)
/*lint -restore */ /*lint -restore */
...@@ -32,6 +32,8 @@ ...@@ -32,6 +32,8 @@
#include "config.h" #include "config.h"
#include <string.h>
#include "vcc_compile.h" #include "vcc_compile.h"
/*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
...@@ -174,6 +176,76 @@ parse_unset(struct vcc *tl) ...@@ -174,6 +176,76 @@ parse_unset(struct vcc *tl)
/*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
static void
parse_new(struct vcc *tl)
{
struct symbol *sy1, *sy2, *sy3;
const char *p, *s_obj, *s_init, *s_struct, *s_fini;
char buf1[128];
char buf2[128];
vcc_NextToken(tl);
ExpectErr(tl, ID);
sy1 = VCC_FindSymbol(tl, tl->t, SYM_NONE);
XXXAZ(sy1);
sy1 = VCC_AddSymbolTok(tl, tl->t, SYM_NONE); // XXX: NONE ?
XXXAN(sy1);
vcc_NextToken(tl);
ExpectErr(tl, '=');
vcc_NextToken(tl);
ExpectErr(tl, ID);
sy2 = VCC_FindSymbol(tl, tl->t, SYM_OBJECT);
XXXAN(sy2);
/*lint -save -e448 */
/* Split the first three args */
p = sy2->args;
s_obj = p;
p += strlen(p) + 1;
s_init = p;
while (p[0] != '\0' || p[1] != '\0')
p++;
p += 2;
s_struct = p;
p += strlen(p) + 1;
s_fini = p + strlen(p) + 1;
while (p[0] != '\0' || p[1] != '\0')
p++;
p += 2;
Fh(tl, 0, "static %s *%s;\n\n", s_struct, sy1->name);
vcc_NextToken(tl);
bprintf(buf1, ", &%s", sy1->name);
vcc_Eval_Func(tl, s_init, buf1, "ASDF", s_init + strlen(s_init) + 1);
Ff(tl, 0, "\t%s((struct req*)0, &%s);\n", s_fini, sy1->name);
ExpectErr(tl, ';');
bprintf(buf1, ", %s", sy1->name);
/* Split the methods from the args */
while (*p != '\0') {
p += strlen(s_obj);
bprintf(buf2, "%s%s", sy1->name, p);
sy3 = VCC_AddSymbolStr(tl, buf2, SYM_FUNC);
sy3->eval = vcc_Eval_SymFunc;
p += strlen(p) + 1;
sy3->cfunc = p;
p += strlen(p) + 1;
sy3->args = p;
sy3->extra = TlDup(tl, buf1);
while (p[0] != '\0' || p[1] != '\0')
p++;
p += 2;
}
/*lint -restore */
}
/*--------------------------------------------------------------------*/
static void static void
parse_ban(struct vcc *tl) parse_ban(struct vcc *tl)
{ {
...@@ -313,6 +385,7 @@ static struct action_table { ...@@ -313,6 +385,7 @@ static struct action_table {
{ "synthetic", parse_synthetic, VCL_MET_ERROR }, { "synthetic", parse_synthetic, VCL_MET_ERROR },
{ "unset", parse_unset }, { "unset", parse_unset },
{ "purge", parse_purge, VCL_MET_MISS | VCL_MET_HIT }, { "purge", parse_purge, VCL_MET_MISS | VCL_MET_HIT },
{ "new", parse_new, VCL_MET_INIT},
{ NULL, NULL } { NULL, NULL }
}; };
......
...@@ -98,7 +98,7 @@ struct token { ...@@ -98,7 +98,7 @@ struct token {
}; };
enum symkind { enum symkind {
#define VCC_SYMB(uu, ll, dd) SYM_##uu, #define VCC_SYMB(uu, ll) SYM_##uu,
#include "tbl/symbol_kind.h" #include "tbl/symbol_kind.h"
#undef VCC_SYMB #undef VCC_SYMB
}; };
...@@ -131,6 +131,7 @@ struct symbol { ...@@ -131,6 +131,7 @@ struct symbol {
/* SYM_PROC, SYM_FUNC */ /* SYM_PROC, SYM_FUNC */
const char *cfunc; const char *cfunc;
const char *extra;
const char *args; const char *args;
/* SYM_VAR */ /* SYM_VAR */
...@@ -278,7 +279,9 @@ void vcc_Expr(struct vcc *tl, enum var_type typ); ...@@ -278,7 +279,9 @@ void vcc_Expr(struct vcc *tl, enum var_type typ);
void vcc_Expr_Call(struct vcc *tl, const struct symbol *sym); void vcc_Expr_Call(struct vcc *tl, const struct symbol *sym);
void vcc_Expr_Init(struct vcc *tl); void vcc_Expr_Init(struct vcc *tl);
sym_expr_t vcc_Eval_Var; sym_expr_t vcc_Eval_Var;
sym_expr_t vcc_Eval_Func; 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);
sym_expr_t vcc_Eval_Backend; sym_expr_t vcc_Eval_Backend;
/* vcc_dir_dns.c */ /* vcc_dir_dns.c */
......
...@@ -519,30 +519,31 @@ vcc_Eval_Var(struct vcc *tl, struct expr **e, const struct symbol *sym) ...@@ -519,30 +519,31 @@ vcc_Eval_Var(struct vcc *tl, struct expr **e, const struct symbol *sym)
/*-------------------------------------------------------------------- /*--------------------------------------------------------------------
*/ */
void static void
vcc_Eval_Func(struct vcc *tl, struct expr **e, const struct symbol *sym) vcc_func(struct vcc *tl, struct expr **e, const char *cfunc,
const char *extra, const char *name, const char *args)
{ {
const char *p, *r; const char *p, *r;
// const struct var *v;
struct expr *e1, *e2; struct expr *e1, *e2;
enum var_type fmt; enum var_type fmt;
char buf[32]; char buf[32];
assert(sym->kind == SYM_FUNC || sym->kind == SYM_PROC); AN(cfunc);
AN(sym->cfunc); AN(args);
AN(sym->args); AN(name);
SkipToken(tl, ID);
SkipToken(tl, '('); SkipToken(tl, '(');
p = sym->args; p = args;
e2 = vcc_mk_expr(vcc_arg_type(&p), "%s(req\v+", sym->cfunc); if (extra == NULL)
extra = "";
e2 = vcc_mk_expr(vcc_arg_type(&p), "%s(req%s\v+", cfunc, extra);
while (*p != '\0') { while (*p != '\0') {
e1 = NULL; e1 = NULL;
fmt = vcc_arg_type(&p); fmt = vcc_arg_type(&p);
if (fmt == VOID && !strcmp(p, "PRIV_VCL")) { if (fmt == VOID && !strcmp(p, "PRIV_VCL")) {
r = strchr(sym->name, '.'); r = strchr(name, '.');
AN(r); AN(r);
e1 = vcc_mk_expr(VOID, "&vmod_priv_%.*s", e1 = vcc_mk_expr(VOID, "&vmod_priv_%.*s",
(int) (r - sym->name), sym->name); (int) (r - name), name);
p += strlen(p) + 1; p += strlen(p) + 1;
} else if (fmt == VOID && !strcmp(p, "PRIV_CALL")) { } else if (fmt == VOID && !strcmp(p, "PRIV_CALL")) {
bprintf(buf, "vmod_priv_%u", tl->nvmodpriv++); bprintf(buf, "vmod_priv_%u", tl->nvmodpriv++);
...@@ -573,7 +574,7 @@ vcc_Eval_Func(struct vcc *tl, struct expr **e, const struct symbol *sym) ...@@ -573,7 +574,7 @@ vcc_Eval_Func(struct vcc *tl, struct expr **e, const struct symbol *sym)
p += strlen(p) + 1; p += strlen(p) + 1;
p++; p++;
SkipToken(tl, ID); SkipToken(tl, ID);
if (*p != '\0') if (*p != '\0') /*lint !e448 */
SkipToken(tl, ','); SkipToken(tl, ',');
} else { } else {
vcc_expr0(tl, &e1, fmt); vcc_expr0(tl, &e1, fmt);
...@@ -603,6 +604,42 @@ vcc_Eval_Func(struct vcc *tl, struct expr **e, const struct symbol *sym) ...@@ -603,6 +604,42 @@ vcc_Eval_Func(struct vcc *tl, struct expr **e, const struct symbol *sym)
*e = e2; *e = e2;
} }
/*--------------------------------------------------------------------
*/
void
vcc_Eval_Func(struct vcc *tl, const char *cfunc,
const char *extra, const char *name, const char *args)
{
struct expr *e = NULL;
struct token *t1;
t1 = tl->t;
vcc_func(tl, &e, cfunc, extra, name, args);
if (!tl->err) {
vcc_expr_fmt(tl->fb, tl->indent, e);
VSB_cat(tl->fb, ";\n");
} else if (t1 != tl->t) {
vcc_ErrWhere2(tl, t1, tl->t);
}
vcc_delete_expr(e);
}
/*--------------------------------------------------------------------
*/
void
vcc_Eval_SymFunc(struct vcc *tl, struct expr **e, const struct symbol *sym)
{
assert(sym->kind == SYM_FUNC || sym->kind == SYM_PROC);
AN(sym->cfunc);
AN(sym->name);
AN(sym->args);
SkipToken(tl, ID);
vcc_func(tl, e, sym->cfunc, sym->extra, sym->name, sym->args);
}
/*-------------------------------------------------------------------- /*--------------------------------------------------------------------
* SYNTAX: * SYNTAX:
* Expr4: * Expr4:
...@@ -1170,7 +1207,7 @@ vcc_Expr_Call(struct vcc *tl, const struct symbol *sym) ...@@ -1170,7 +1207,7 @@ vcc_Expr_Call(struct vcc *tl, const struct symbol *sym)
t1 = tl->t; t1 = tl->t;
e = NULL; e = NULL;
vcc_Eval_Func(tl, &e, sym); vcc_Eval_SymFunc(tl, &e, sym);
if (!tl->err) { if (!tl->err) {
vcc_expr_fmt(tl->fb, tl->indent, e); vcc_expr_fmt(tl->fb, tl->indent, e);
VSB_cat(tl->fb, ";\n"); VSB_cat(tl->fb, ";\n");
......
...@@ -40,7 +40,7 @@ const char * ...@@ -40,7 +40,7 @@ const char *
VCC_SymKind(struct vcc *tl, const struct symbol *s) VCC_SymKind(struct vcc *tl, const struct symbol *s)
{ {
switch(s->kind) { switch(s->kind) {
#define VCC_SYMB(uu, ll, dd) case SYM_##uu: return(dd); #define VCC_SYMB(uu, ll) case SYM_##uu: return(#ll);
#include "tbl/symbol_kind.h" #include "tbl/symbol_kind.h"
#undef VCC_SYMB #undef VCC_SYMB
default: default:
......
...@@ -168,10 +168,12 @@ vcc_ParseImport(struct vcc *tl) ...@@ -168,10 +168,12 @@ vcc_ParseImport(struct vcc *tl)
for (; *spec != NULL; spec++) { for (; *spec != NULL; spec++) {
p = *spec; p = *spec;
if (!strcmp(p, "OBJ")) { if (!strcmp(p, "OBJ")) {
// Nothing yet p += strlen(p) + 1;
} else if (!strcmp(p, "METHOD")) { sym = VCC_AddSymbolStr(tl, p, SYM_OBJECT);
// Nothing yet XXXAN(sym);
sym->args = p;
} else if (!strcmp(p, "FINI")) { } else if (!strcmp(p, "FINI")) {
p += strlen(p) + 1;
// Nothing yet // Nothing yet
} else if (!strcmp(p, "INIT")) { } else if (!strcmp(p, "INIT")) {
p += strlen(p) + 1; p += strlen(p) + 1;
...@@ -181,7 +183,7 @@ vcc_ParseImport(struct vcc *tl) ...@@ -181,7 +183,7 @@ vcc_ParseImport(struct vcc *tl)
sym = VCC_AddSymbolStr(tl, p, SYM_FUNC); sym = VCC_AddSymbolStr(tl, p, SYM_FUNC);
ERRCHK(tl); ERRCHK(tl);
AN(sym); AN(sym);
sym->eval = vcc_Eval_Func; sym->eval = vcc_Eval_SymFunc;
p += strlen(p) + 1; p += strlen(p) + 1;
sym->cfunc = p; sym->cfunc = p;
p += strlen(p) + 1; p += strlen(p) + 1;
......
...@@ -248,7 +248,7 @@ class func(object): ...@@ -248,7 +248,7 @@ class func(object):
raise Exception( raise Exception(
"Return type '%s' not a valid type" % retval) "Return type '%s' not a valid type" % retval)
self.nam = nam self.nam = nam
self.cnam = nam.replace(".", "__") self.cnam = nam.replace(".", "_")
self.al = al self.al = al
self.retval = retval self.retval = retval
self.pfx = None self.pfx = None
...@@ -299,23 +299,28 @@ class func(object): ...@@ -299,23 +299,28 @@ class func(object):
for a in self.al: for a in self.al:
s += a.c_strspec() s += a.c_strspec()
return s return s
####################################################################### #######################################################################
class obj(object): class obj(object):
def __init__(self, nam): def __init__(self, nam):
self.nam = nam self.nam = nam
self.init_fini = None self.init = None
self.fini = None
self.methods = list() self.methods = list()
def set_modnam(self, modnam): def set_modnam(self, modnam):
self.st = "struct vmod_" + modnam + "_" + self.nam self.st = "struct vmod_" + modnam + "_" + self.nam
self.init_fini.set_pfx(", " + self.st + " **") self.init.set_pfx(", " + self.st + " **")
self.fini.set_pfx(", " + self.st + " **")
for m in self.methods: for m in self.methods:
m.set_pfx(", " + self.st + " *") m.set_pfx(", " + self.st + " *")
def set_init_fini(self, f): def set_init(self, f):
self.init_fini = f self.init = f
self.fini = func(f.nam, "VOID", [])
self.init.cnam += "__init"
self.fini.cnam += "__fini"
def add_method(self, m): def add_method(self, m):
self.methods.append(m) self.methods.append(m)
...@@ -324,38 +329,44 @@ class obj(object): ...@@ -324,38 +329,44 @@ class obj(object):
l = list() l = list()
l.append("/* Object " + self.nam + " */") l.append("/* Object " + self.nam + " */")
l.append(self.st + ";") l.append(self.st + ";")
l.append(self.init_fini.c_typedef(modnam) + "") l.append(self.init.c_typedef(modnam) + "")
l.append(self.fini.c_typedef(modnam) + "")
for m in self.methods: for m in self.methods:
l.append(m.c_typedef(modnam) + "") l.append(m.c_typedef(modnam) + "")
return l return l
def c_proto(self, fo): def c_proto(self, fo):
fo.write(self.st + ";\n") fo.write(self.st + ";\n")
self.init_fini.c_proto(fo) self.init.c_proto(fo)
self.fini.c_proto(fo)
for m in o.methods: for m in o.methods:
m.c_proto(fo) m.c_proto(fo)
def c_struct(self, modnam): def c_struct(self, modnam):
s = "\t/* Object " + self.nam + " */\n" s = "\t/* Object " + self.nam + " */\n"
s += self.init_fini.c_struct(modnam) s += self.init.c_struct(modnam)
s += self.fini.c_struct(modnam)
for m in self.methods: for m in self.methods:
s += m.c_struct(modnam) s += m.c_struct(modnam)
return s return s
def c_initializer(self): def c_initializer(self):
s = "\t/* Object " + self.nam + " */\n" s = "\t/* Object " + self.nam + " */\n"
s += self.init_fini.c_initializer() s += self.init.c_initializer()
s += self.fini.c_initializer()
for m in self.methods: for m in self.methods:
s += m.c_initializer() s += m.c_initializer()
return s return s
def c_strspec(self, modnam): def c_strspec(self, modnam):
s = "\t/* Object " + self.nam + " */\n" s = "\t/* Object " + self.nam + " */\n"
s += '\t"OBJ\\0' s += '\t"OBJ\\0"\n'
s += self.st + '\\0' s += '\t\t"' + self.init.c_strspec(modnam) + '\\0"\n'
s += self.init_fini.c_strspec(modnam) + '",\n' s += '\t\t"' + self.st + '\\0"\n'
s += '\t\t"' + self.fini.c_strspec(modnam) + '\\0"\n'
for m in self.methods: for m in self.methods:
s += '\t"METHOD\\0' + m.c_strspec(modnam) + '",\n' s += '\t\t"' + m.c_strspec(modnam) + '\\0"\n'
s += '\t\t"\\0",\n'
return s return s
####################################################################### #######################################################################
...@@ -466,7 +477,7 @@ def parse_func(tl, rt_type = None, obj=None): ...@@ -466,7 +477,7 @@ def parse_func(tl, rt_type = None, obj=None):
def parse_obj(tl): def parse_obj(tl):
o = obj(tl[0].str) o = obj(tl[0].str)
f = parse_func(tl, "VOID") f = parse_func(tl, "VOID")
o.set_init_fini(f) o.set_init(f)
t = tl.pop(0) t = tl.pop(0)
assert t.str == "{" assert t.str == "{"
while True: while True:
......
...@@ -42,28 +42,34 @@ struct vmod_debug_obj { ...@@ -42,28 +42,34 @@ struct vmod_debug_obj {
}; };
VCL_VOID VCL_VOID
vmod_obj(struct req *req, struct vmod_debug_obj **op, VCL_STRING s) vmod_obj__init(struct req *req, struct vmod_debug_obj **op, VCL_STRING s)
{ {
struct vmod_debug_obj *o; struct vmod_debug_obj *o;
(void)req; (void)req;
(void)s; (void)s;
AN(op); AN(op);
if (*op == NULL) { AZ(*op);
/* INIT */ ALLOC_OBJ(o, VMOD_DEBUG_OBJ_MAGIC);
ALLOC_OBJ(o, VMOD_DEBUG_OBJ_MAGIC); AN(o);
*op = o; *op = o;
o->foobar = 42; o->foobar = 42;
AN(*op); AN(*op);
} else {
/* FINI */
FREE_OBJ(*op);
*op = NULL;
}
} }
VCL_STRING VCL_VOID
vmod_obj__foo(struct req *req, struct vmod_debug_obj *o, VCL_STRING s) vmod_obj__fini(struct req *req, struct vmod_debug_obj **op)
{
(void)req;
AN(op);
AN(*op);
FREE_OBJ(*op);
*op = NULL;
}
VCL_STRING __match_proto__()
vmod_obj_foo(struct req *req, struct vmod_debug_obj *o, VCL_STRING s)
{ {
(void)req; (void)req;
(void)s; (void)s;
...@@ -72,8 +78,8 @@ vmod_obj__foo(struct req *req, struct vmod_debug_obj *o, VCL_STRING s) ...@@ -72,8 +78,8 @@ vmod_obj__foo(struct req *req, struct vmod_debug_obj *o, VCL_STRING s)
return ("BOO"); return ("BOO");
} }
VCL_TIME VCL_TIME __match_proto__()
vmod_obj__date(struct req *req, struct vmod_debug_obj *o) vmod_obj_date(struct req *req, struct vmod_debug_obj *o)
{ {
(void)req; (void)req;
CHECK_OBJ_NOTNULL(o, VMOD_DEBUG_OBJ_MAGIC); CHECK_OBJ_NOTNULL(o, VMOD_DEBUG_OBJ_MAGIC);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment