[master] e45595ec9 vcc: Parse the built-in VCL independently

Nils Goroll nils.goroll at uplex.de
Wed Mar 3 10:15:04 UTC 2021


commit e45595ec9067475d4d5baac2a6593ac97c0370b5
Author: Dridi Boukelmoune <dridi.boukelmoune at gmail.com>
Date:   Mon Dec 14 06:33:35 2020 +0100

    vcc: Parse the built-in VCL independently
    
    This is a lookahead parsing to learn about built-in subroutines that are
    not tied to a VCL state. Instead of maintaining a mapping of the other
    subroutines the builtin.vcl file itself becomes authoritative.

diff --git a/lib/libvcc/vcc_compile.c b/lib/libvcc/vcc_compile.c
index cec471f16..e52c1da4b 100644
--- a/lib/libvcc/vcc_compile.c
+++ b/lib/libvcc/vcc_compile.c
@@ -72,6 +72,8 @@ static const struct method method_tab[] = {
 	{ NULL, 0U, 0}
 };
 
+struct vcc *vcc_builtin;
+
 /*--------------------------------------------------------------------*/
 
 static void
@@ -782,11 +784,14 @@ vcc_CompileSource(struct vcc *tl, struct source *sp, const char *jfile)
 	Fh(tl, 0, "\nextern const struct VCL_conf VCL_conf;\n");
 
 	/* Register and lex the main source */
-	VTAILQ_INSERT_TAIL(&tl->sources, sp, list);
-	sp->idx = tl->nsources++;
-	vcc_Lexer(tl, sp, 0);
-	if (tl->err)
-		return (NULL);
+	if (sp != NULL) {
+		AN(vcc_builtin);
+		VTAILQ_INSERT_TAIL(&tl->sources, sp, list);
+		sp->idx = tl->nsources++;
+		vcc_Lexer(tl, sp, 0);
+		if (tl->err)
+			return (NULL);
+	}
 
 	/* Register and lex the builtin VCL */
 	sp = vcc_new_source(tl->builtin_vcl, "Builtin");
@@ -808,15 +813,6 @@ vcc_CompileSource(struct vcc *tl, struct source *sp, const char *jfile)
 	if (tl->err)
 		return (NULL);
 
-	/* Check if we have any backends at all */
-	if (tl->default_director == NULL) {
-		VSB_cat(tl->sb,
-		    "No backends or directors found in VCL program, "
-		    "at least one is necessary.\n");
-		tl->err = 1;
-		return (NULL);
-	}
-
 	/* Check for orphans */
 	if (vcc_CheckReferences(tl))
 		return (NULL);
@@ -829,6 +825,18 @@ vcc_CompileSource(struct vcc *tl, struct source *sp, const char *jfile)
 	if (vcc_CheckUses(tl) || tl->err)
 		return (NULL);
 
+	if (vcc_builtin == NULL)
+		return (NULL);
+
+	/* Check if we have any backends at all */
+	if (tl->default_director == NULL) {
+		VSB_cat(tl->sb,
+		    "No backends or directors found in VCL program, "
+		    "at least one is necessary.\n");
+		tl->err = 1;
+		return (NULL);
+	}
+
 	/* Tie vcl_init/fini in */
 	ifp = New_IniFin(tl);
 	VSB_cat(ifp->ini, "\tVGC_function_vcl_init(ctx, VSUB_STATIC, NULL);\n");
@@ -881,6 +889,19 @@ vcc_CompileSource(struct vcc *tl, struct source *sp, const char *jfile)
 	return (vsb);
 }
 
+static struct vcc *
+vcc_ParseBuiltin(struct vcc *tl)
+{
+	struct vcc *tl_builtin;
+
+	CHECK_OBJ_NOTNULL(tl, VCC_MAGIC);
+	tl_builtin = VCC_New();
+	AN(tl_builtin);
+	VCC_Builtin_VCL(tl_builtin, tl->builtin_vcl);
+	AZ(vcc_CompileSource(tl_builtin, NULL, NULL));
+	return (tl_builtin);
+}
+
 /*--------------------------------------------------------------------
  * Report the range of VCL language we support
  */
@@ -913,6 +934,16 @@ VCC_Compile(struct vcc *tl, struct vsb **sb,
 	AN(vclsrcfile);
 	AN(ofile);
 	AN(jfile);
+
+	AZ(vcc_builtin);
+	vcc_builtin = vcc_ParseBuiltin(tl);
+	AN(vcc_builtin);
+	if (vcc_builtin->err) {
+		AZ(VSB_finish(vcc_builtin->sb));
+		*sb = vcc_builtin->sb;
+		return (-1);
+	}
+
 	if (vclsrc != NULL)
 		sp = vcc_new_source(vclsrc, vclsrcfile);
 	else
diff --git a/lib/libvcc/vcc_compile.h b/lib/libvcc/vcc_compile.h
index 2bdc7e480..d261302b1 100644
--- a/lib/libvcc/vcc_compile.h
+++ b/lib/libvcc/vcc_compile.h
@@ -288,6 +288,8 @@ struct vcc {
 	unsigned		vmod_count;
 };
 
+extern struct vcc *vcc_builtin;
+
 struct method {
 	const char		*name;
 	unsigned		ret_bitmap;


More information about the varnish-commit mailing list