[master] a82916eac Register types and type methods as symbols

Dridi Boukelmoune dridi.boukelmoune at gmail.com
Thu Jul 2 12:49:07 UTC 2020


commit a82916eac970cf1c1a53b4f4df57ff61120b5270
Author: Dridi Boukelmoune <dridi.boukelmoune at gmail.com>
Date:   Fri Jun 5 07:55:54 2020 +0200

    Register types and type methods as symbols
    
    The SYM_METHOD kind of symbol was already present but never used so it
    just found its purpose.
    
    They appear in their dedicated symbol table:
    
        /*
         * Symbol Table MAIN
         *
         * reserved  VOID       41 41 acl
         * reserved  VOID       41 41 backend
         * [...]
         */
    
        /*
         * Symbol Table TYPE
         *
         * none      VOID     40 41 BACKEND
         * method    BACKEND  40 41 BACKEND.resolve
         * none      VOID     40 41 STEVEDORE
         * method    BYTES    40 41 STEVEDORE.free_space
         * method    BOOL     40 41 STEVEDORE.happy
         * method    BYTES    40 41 STEVEDORE.used_space
         * none      VOID     40 41 STRINGS
         * method    STRING   40 41 STRINGS.lower
         * method    STRING   40 41 STRINGS.upper
         */
    
    Unlike VMOD functions or object methods, native type methods are never
    invoked as a standalone statement:
    
        strings.upper();
    
    They are only evaluated atop an expression:
    
        (string expression).upper();
    
    So any VMOD named after a type, like vmod_blob, should not conflict with
    native type methods in the symbol table. Unless a symbol already exists
    in the MAIN namespace, like reserved keywords acl and backend.

diff --git a/lib/libvcc/vcc_compile.c b/lib/libvcc/vcc_compile.c
index d726a80eb..caf735f53 100644
--- a/lib/libvcc/vcc_compile.c
+++ b/lib/libvcc/vcc_compile.c
@@ -647,6 +647,8 @@ vcc_CompileSource(struct vcc *tl, struct source *sp, const char *jfile)
 
 	vcc_Var_Init(tl);
 
+	vcc_Type_Init(tl);
+
 	Fh(tl, 0, "\nextern const struct VCL_conf VCL_conf;\n");
 
 	/* Register and lex the main source */
diff --git a/lib/libvcc/vcc_compile.h b/lib/libvcc/vcc_compile.h
index d91bd00b4..1a4cb44db 100644
--- a/lib/libvcc/vcc_compile.h
+++ b/lib/libvcc/vcc_compile.h
@@ -110,6 +110,8 @@ typedef const struct type	*vcc_type_t;
  * XXX: type methods might move in a more comprehensive direction.
  */
 struct vcc_method {
+	unsigned		magic;
+#define VCC_METHOD_MAGIC	0x594108cd
 	vcc_type_t		type;
 	const char		*name;
 	const char		*impl;
@@ -423,6 +425,7 @@ void vcc_AddToken(struct vcc *tl, unsigned tok, const char *b,
 
 /* vcc_types.c */
 vcc_type_t VCC_Type(const char *p);
+void vcc_Type_Init(struct vcc *tl);
 
 /* vcc_var.c */
 sym_wildcard_t vcc_Var_Wildcard;
diff --git a/lib/libvcc/vcc_types.c b/lib/libvcc/vcc_types.c
index 4f9db3b80..1292ec27a 100644
--- a/lib/libvcc/vcc_types.c
+++ b/lib/libvcc/vcc_types.c
@@ -43,8 +43,9 @@ const struct type ACL[1] = {{
 }};
 
 static const struct vcc_method backend_methods[] = {
-	{ BACKEND, "resolve", "VRT_DirectorResolve(ctx, \v1)", 1 },
-	{ NULL },
+	{ VCC_METHOD_MAGIC, BACKEND, "resolve",
+	    "VRT_DirectorResolve(ctx, \v1)", 1 },
+	{ VCC_METHOD_MAGIC, NULL },
 };
 
 const struct type BACKEND[1] = {{
@@ -133,9 +134,9 @@ const struct type REAL[1] = {{
 
 static const struct vcc_method stevedore_methods[] = {
 #define VRTSTVVAR(nm, vtype, ctype, dval) \
-	{ vtype, #nm, "VRT_stevedore_" #nm "(\v1)", 0},
+	{ VCC_METHOD_MAGIC, vtype, #nm, "VRT_stevedore_" #nm "(\v1)", 0},
 #include "tbl/vrt_stv_var.h"
-	{ NULL },
+	{ VCC_METHOD_MAGIC, NULL },
 };
 
 const struct type STEVEDORE[1] = {{
@@ -159,9 +160,11 @@ const struct type STRANDS[1] = {{
 }};
 
 static const struct vcc_method strings_methods[] = {
-	{ STRING, "upper", "VRT_UpperLowerStrands(ctx, \vT, 1)", 1 },
-	{ STRING, "lower", "VRT_UpperLowerStrands(ctx, \vT, 0)", 1 },
-	{ NULL },
+	{ VCC_METHOD_MAGIC, STRING, "upper",
+	    "VRT_UpperLowerStrands(ctx, \vT, 1)", 1 },
+	{ VCC_METHOD_MAGIC, STRING, "lower",
+	    "VRT_UpperLowerStrands(ctx, \vT, 0)", 1 },
+	{ VCC_METHOD_MAGIC, NULL },
 };
 
 const struct type STRINGS[1] = {{
@@ -207,3 +210,43 @@ VCC_Type(const char *p)
 	return (NULL);
 }
 
+static void
+vcc_type_init(struct vcc *tl, vcc_type_t type)
+{
+	const struct vcc_method *vm;
+	struct symbol *sym;
+	struct vsb *buf;
+
+	/* NB: Don't bother even creating a type symbol if there are no
+	 * methods attached to it.
+	 */
+	if (type->methods == NULL)
+		return;
+
+	buf = VSB_new_auto();
+	AN(buf);
+	AN(VCC_MkSym(tl, type->name, SYM_TYPE, SYM_NONE, VCL_LOW, VCL_HIGH));
+
+	for (vm = type->methods; vm->type != NULL; vm++) {
+		VSB_printf(buf, "%s.%s", type->name, vm->name);
+		AZ(VSB_finish(buf));
+		sym = VCC_MkSym(tl, VSB_data(buf), SYM_TYPE, SYM_METHOD,
+		    VCL_LOW, VCL_HIGH);
+		VSB_clear(buf);
+		if (tl->err)
+			break;
+		AN(sym);
+		sym->type = vm->type;
+		sym->eval_priv = vm;
+	}
+
+	VSB_destroy(&buf);
+}
+
+void
+vcc_Type_Init(struct vcc *tl)
+{
+
+#define VCC_TYPE(UC, lc)	vcc_type_init(tl, UC);
+#include "tbl/vcc_types.h"
+}
diff --git a/lib/libvcc/vcc_xref.c b/lib/libvcc/vcc_xref.c
index b0228ec26..0bd9f2aed 100644
--- a/lib/libvcc/vcc_xref.c
+++ b/lib/libvcc/vcc_xref.c
@@ -358,21 +358,6 @@ vcc_CheckUses(struct vcc *tl)
 
 /*---------------------------------------------------------------------*/
 
-static int sym_type_len = 0;
-
-static void v_matchproto_(symwalk_f)
-vcc_xreftable_len(struct vcc *tl, const struct symbol *sym)
-{
-	int len;
-
-	(void)tl;
-	CHECK_OBJ_NOTNULL(sym, SYMBOL_MAGIC);
-	CHECK_OBJ_NOTNULL(sym->type, TYPE_MAGIC);
-	len = strlen(sym->type->name);
-	if (sym_type_len < len)
-		sym_type_len = len;
-}
-
 static void v_matchproto_(symwalk_f)
 vcc_instance_info(struct vcc *tl, const struct symbol *sym)
 {
@@ -393,6 +378,23 @@ VCC_InstanceInfo(struct vcc *tl)
 	Fc(tl, 0, "};\n");
 }
 
+/*---------------------------------------------------------------------*/
+
+static int sym_type_len;
+
+static void v_matchproto_(symwalk_f)
+vcc_xreftable_len(struct vcc *tl, const struct symbol *sym)
+{
+	int len;
+
+	(void)tl;
+	CHECK_OBJ_NOTNULL(sym, SYMBOL_MAGIC);
+	CHECK_OBJ_NOTNULL(sym->type, TYPE_MAGIC);
+	len = strlen(sym->type->name);
+	if (sym_type_len < len)
+		sym_type_len = len;
+}
+
 static void v_matchproto_(symwalk_f)
 vcc_xreftable(struct vcc *tl, const struct symbol *sym)
 {
@@ -413,10 +415,13 @@ void
 VCC_XrefTable(struct vcc *tl)
 {
 
-	Fc(tl, 0, "\n/*\n * Symbol Table\n *\n");
-	VCC_WalkSymbols(tl, vcc_xreftable_len, SYM_MAIN, SYM_NONE);
-	VCC_WalkSymbols(tl, vcc_xreftable, SYM_MAIN, SYM_NONE);
+#define VCC_NAMESPACE(U, l)						\
+	Fc(tl, 0, "\n/*\n * Symbol Table " #U "\n *\n");		\
+	sym_type_len = 0;						\
+	VCC_WalkSymbols(tl, vcc_xreftable_len, SYM_##U, SYM_NONE);	\
+	VCC_WalkSymbols(tl, vcc_xreftable, SYM_##U, SYM_NONE);		\
 	Fc(tl, 0, "*/\n\n");
+#include "vcc_namespace.h"
 }
 
 /*---------------------------------------------------------------------


More information about the varnish-commit mailing list