[master] 8a73d95 This is a very shaky first prototype of VMOD objects.

Poul-Henning Kamp phk at varnish-cache.org
Mon Feb 11 11:27:29 CET 2013


commit 8a73d9572edf80f092bd1c239f0dd1d7651a4876
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Mon Feb 11 10:26:49 2013 +0000

    This is a very shaky first prototype of VMOD objects.

diff --git a/include/tbl/symbol_kind.h b/include/tbl/symbol_kind.h
index 155d36e..3d426f9 100644
--- a/include/tbl/symbol_kind.h
+++ b/include/tbl/symbol_kind.h
@@ -28,14 +28,16 @@
  */
 
 /*lint -save -e525 -e539 */
-VCC_SYMB(NONE,		none,		"undefined")
-VCC_SYMB(VAR,		var,		"variable")
-VCC_SYMB(FUNC,		func,		"function")	/* VMOD function */
-VCC_SYMB(PROC,		proc,		"procedure")	/* VMOD procedure */
-VCC_SYMB(VMOD,		vmod,		"vmod")
-VCC_SYMB(ACL,		acl,		"acl")
-VCC_SYMB(SUB,		sub,		"sub")		/* VCL subroutine */
-VCC_SYMB(BACKEND,	backend,	"backend")
-VCC_SYMB(PROBE,		probe,		"probe")
-VCC_SYMB(WILDCARD,	wildcard,	"wildcard")
+VCC_SYMB(NONE,		none)
+VCC_SYMB(VAR,		var)
+VCC_SYMB(FUNC,		func)		/* VMOD function */
+VCC_SYMB(PROC,		proc)		/* VMOD procedure */
+VCC_SYMB(VMOD,		vmod)
+VCC_SYMB(ACL,		acl)
+VCC_SYMB(SUB,		sub)		/* VCL subroutine */
+VCC_SYMB(BACKEND,	backend)
+VCC_SYMB(PROBE,		probe)
+VCC_SYMB(WILDCARD,	wildcard)
+VCC_SYMB(OBJECT,	object)
+VCC_SYMB(METHOD,	method)
 /*lint -restore */
diff --git a/lib/libvcl/vcc_action.c b/lib/libvcl/vcc_action.c
index 1eec1c4..40b56f8 100644
--- a/lib/libvcl/vcc_action.c
+++ b/lib/libvcl/vcc_action.c
@@ -32,6 +32,8 @@
 
 #include "config.h"
 
+#include <string.h>
+
 #include "vcc_compile.h"
 
 /*--------------------------------------------------------------------*/
@@ -175,6 +177,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
 parse_ban(struct vcc *tl)
 {
 
@@ -313,6 +385,7 @@ static struct action_table {
 	{ "synthetic",		parse_synthetic, VCL_MET_ERROR },
 	{ "unset",		parse_unset },
 	{ "purge",		parse_purge, VCL_MET_MISS | VCL_MET_HIT },
+	{ "new",		parse_new, VCL_MET_INIT},
 	{ NULL,			NULL }
 };
 
diff --git a/lib/libvcl/vcc_compile.h b/lib/libvcl/vcc_compile.h
index 99a1169..162fef6 100644
--- a/lib/libvcl/vcc_compile.h
+++ b/lib/libvcl/vcc_compile.h
@@ -98,7 +98,7 @@ struct token {
 };
 
 enum symkind {
-#define VCC_SYMB(uu, ll, dd)	SYM_##uu,
+#define VCC_SYMB(uu, ll)	SYM_##uu,
 #include "tbl/symbol_kind.h"
 #undef VCC_SYMB
 };
@@ -131,6 +131,7 @@ struct symbol {
 
 	/* SYM_PROC, SYM_FUNC */
 	const char			*cfunc;
+	const char			*extra;
 	const char			*args;
 
 	/* SYM_VAR */
@@ -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_Init(struct vcc *tl);
 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;
 
 /* vcc_dir_dns.c */
diff --git a/lib/libvcl/vcc_expr.c b/lib/libvcl/vcc_expr.c
index 9e0f360..b6790aa 100644
--- a/lib/libvcl/vcc_expr.c
+++ b/lib/libvcl/vcc_expr.c
@@ -519,30 +519,31 @@ vcc_Eval_Var(struct vcc *tl, struct expr **e, const struct symbol *sym)
 /*--------------------------------------------------------------------
  */
 
-void
-vcc_Eval_Func(struct vcc *tl, struct expr **e, const struct symbol *sym)
+static void
+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 struct var *v;
 	struct expr *e1, *e2;
 	enum var_type fmt;
 	char buf[32];
 
-	assert(sym->kind == SYM_FUNC || sym->kind == SYM_PROC);
-	AN(sym->cfunc);
-	AN(sym->args);
-	SkipToken(tl, ID);
+	AN(cfunc);
+	AN(args);
+	AN(name);
 	SkipToken(tl, '(');
-	p = sym->args;
-	e2 = vcc_mk_expr(vcc_arg_type(&p), "%s(req\v+", sym->cfunc);
+	p = args;
+	if (extra == NULL)
+		extra = "";
+	e2 = vcc_mk_expr(vcc_arg_type(&p), "%s(req%s\v+", cfunc, extra);
 	while (*p != '\0') {
 		e1 = NULL;
 		fmt = vcc_arg_type(&p);
 		if (fmt == VOID && !strcmp(p, "PRIV_VCL")) {
-			r = strchr(sym->name, '.');
+			r = strchr(name, '.');
 			AN(r);
 			e1 = vcc_mk_expr(VOID, "&vmod_priv_%.*s",
-			    (int) (r - sym->name), sym->name);
+			    (int) (r - name), name);
 			p += strlen(p) + 1;
 		} else if (fmt == VOID && !strcmp(p, "PRIV_CALL")) {
 			bprintf(buf, "vmod_priv_%u", tl->nvmodpriv++);
@@ -573,7 +574,7 @@ vcc_Eval_Func(struct vcc *tl, struct expr **e, const struct symbol *sym)
 				p += strlen(p) + 1;
 			p++;
 			SkipToken(tl, ID);
-			if (*p != '\0')
+			if (*p != '\0')		/*lint !e448 */
 				SkipToken(tl, ',');
 		} else {
 			vcc_expr0(tl, &e1, fmt);
@@ -604,6 +605,42 @@ vcc_Eval_Func(struct vcc *tl, struct expr **e, const struct symbol *sym)
 }
 
 /*--------------------------------------------------------------------
+ */
+
+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:
  *    Expr4:
  *	'(' Expr0 ')'
@@ -1170,7 +1207,7 @@ vcc_Expr_Call(struct vcc *tl, const struct symbol *sym)
 
 	t1 = tl->t;
 	e = NULL;
-	vcc_Eval_Func(tl, &e, sym);
+	vcc_Eval_SymFunc(tl, &e, sym);
 	if (!tl->err) {
 		vcc_expr_fmt(tl->fb, tl->indent, e);
 		VSB_cat(tl->fb, ";\n");
diff --git a/lib/libvcl/vcc_symb.c b/lib/libvcl/vcc_symb.c
index 691f6b8..c3d8a13 100644
--- a/lib/libvcl/vcc_symb.c
+++ b/lib/libvcl/vcc_symb.c
@@ -40,7 +40,7 @@ const char *
 VCC_SymKind(struct vcc *tl, const struct symbol *s)
 {
 	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"
 #undef VCC_SYMB
 	default:
diff --git a/lib/libvcl/vcc_vmod.c b/lib/libvcl/vcc_vmod.c
index 839577d..42fc1b6 100644
--- a/lib/libvcl/vcc_vmod.c
+++ b/lib/libvcl/vcc_vmod.c
@@ -168,10 +168,12 @@ vcc_ParseImport(struct vcc *tl)
 	for (; *spec != NULL; spec++) {
 		p = *spec;
 		if (!strcmp(p, "OBJ")) {
-			// Nothing yet
-		} else if (!strcmp(p, "METHOD")) {
-			// Nothing yet
+			p += strlen(p) + 1;
+			sym = VCC_AddSymbolStr(tl, p, SYM_OBJECT);
+			XXXAN(sym);
+			sym->args = p;
 		} else if (!strcmp(p, "FINI")) {
+			p += strlen(p) + 1;
 			// Nothing yet
 		} else if (!strcmp(p, "INIT")) {
 			p += strlen(p) + 1;
@@ -181,7 +183,7 @@ vcc_ParseImport(struct vcc *tl)
 			sym = VCC_AddSymbolStr(tl, p, SYM_FUNC);
 			ERRCHK(tl);
 			AN(sym);
-			sym->eval = vcc_Eval_Func;
+			sym->eval = vcc_Eval_SymFunc;
 			p += strlen(p) + 1;
 			sym->cfunc = p;
 			p += strlen(p) + 1;
diff --git a/lib/libvcl/vmodtool.py b/lib/libvcl/vmodtool.py
index d5f5c30..4076597 100755
--- a/lib/libvcl/vmodtool.py
+++ b/lib/libvcl/vmodtool.py
@@ -248,7 +248,7 @@ class func(object):
 			raise Exception(
 			    "Return type '%s' not a valid type" % retval)
 		self.nam = nam
-		self.cnam = nam.replace(".", "__")
+		self.cnam = nam.replace(".", "_")
 		self.al = al
 		self.retval = retval
 		self.pfx = None
@@ -299,23 +299,28 @@ class func(object):
 		for a in self.al:
 			s += a.c_strspec()
 		return s
-		
+
 #######################################################################
 
 class obj(object):
 	def __init__(self, nam):
 		self.nam = nam
-		self.init_fini = None
+		self.init = None
+		self.fini = None
 		self.methods = list()
 
 	def set_modnam(self, modnam):
 		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:
 			m.set_pfx(", " + self.st + " *")
 
-	def set_init_fini(self, f):
-		self.init_fini = f
+	def set_init(self, f):
+		self.init = f
+		self.fini = func(f.nam, "VOID", [])
+		self.init.cnam += "__init"
+		self.fini.cnam += "__fini"
 
 	def add_method(self, m):
 		self.methods.append(m)
@@ -324,38 +329,44 @@ class obj(object):
 		l = list()
 		l.append("/* Object " + self.nam + " */")
 		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:
 			l.append(m.c_typedef(modnam) + "")
 		return l
 
 	def c_proto(self, fo):
 		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:
 			m.c_proto(fo)
 
 	def c_struct(self, modnam):
 		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:
 			s += m.c_struct(modnam)
 		return s
 
 	def c_initializer(self):
 		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:
 			s += m.c_initializer()
 		return s
 
 	def c_strspec(self, modnam):
 		s = "\t/* Object " + self.nam + " */\n"
-		s += '\t"OBJ\\0'
-		s += self.st + '\\0'
-		s += self.init_fini.c_strspec(modnam) + '",\n'
+		s += '\t"OBJ\\0"\n'
+		s += '\t\t"' + self.init.c_strspec(modnam) + '\\0"\n'
+		s += '\t\t"' + self.st + '\\0"\n'
+		s += '\t\t"' + self.fini.c_strspec(modnam) + '\\0"\n'
 		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
 
 #######################################################################
@@ -466,7 +477,7 @@ def parse_func(tl, rt_type = None, obj=None):
 def parse_obj(tl):
 	o = obj(tl[0].str)
 	f = parse_func(tl, "VOID")
-	o.set_init_fini(f)
+	o.set_init(f)
 	t = tl.pop(0)
 	assert t.str == "{"
 	while True:
diff --git a/lib/libvmod_debug/vmod_debug_obj.c b/lib/libvmod_debug/vmod_debug_obj.c
index 5ae2f3b..d44e634 100644
--- a/lib/libvmod_debug/vmod_debug_obj.c
+++ b/lib/libvmod_debug/vmod_debug_obj.c
@@ -42,28 +42,34 @@ struct vmod_debug_obj {
 };
 
 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;
 
 	(void)req;
 	(void)s;
 	AN(op);
-	if (*op == NULL) {
-		/* INIT */
-		ALLOC_OBJ(o, VMOD_DEBUG_OBJ_MAGIC);
-		*op = o;
-		o->foobar = 42;
-		AN(*op);
-	} else {
-		/* FINI */
-		FREE_OBJ(*op);
-		*op = NULL;
-	}
+	AZ(*op);
+	ALLOC_OBJ(o, VMOD_DEBUG_OBJ_MAGIC);
+	AN(o);
+	*op = o;
+	o->foobar = 42;
+	AN(*op);
 }
 
-VCL_STRING
-vmod_obj__foo(struct req *req, struct vmod_debug_obj *o, VCL_STRING s)
+VCL_VOID
+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)s;
@@ -72,8 +78,8 @@ vmod_obj__foo(struct req *req, struct vmod_debug_obj *o, VCL_STRING s)
 	return ("BOO");
 }
 
-VCL_TIME
-vmod_obj__date(struct req *req, struct vmod_debug_obj *o)
+VCL_TIME __match_proto__()
+vmod_obj_date(struct req *req, struct vmod_debug_obj *o)
 {
 	(void)req;
 	CHECK_OBJ_NOTNULL(o, VMOD_DEBUG_OBJ_MAGIC);



More information about the varnish-commit mailing list