[master] c796ea52d Add abi, major and minor to VMOD JSON spec
Poul-Henning Kamp
phk at FreeBSD.org
Thu Jun 23 10:37:05 UTC 2022
commit c796ea52d0f3369ec8e53aa8bebbef00fa65c391
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date: Thu Jun 23 10:00:32 2022 +0000
Add abi, major and minor to VMOD JSON spec
diff --git a/lib/libvcc/vcc_vmod.c b/lib/libvcc/vcc_vmod.c
index a9f169d10..a90712f19 100644
--- a/lib/libvcc/vcc_vmod.c
+++ b/lib/libvcc/vcc_vmod.c
@@ -54,10 +54,14 @@ struct vmod_import {
const char *err;
char *path;
+ // From $VMOD
double vmod_syntax;
char *name;
char *func_name;
char *file_id;
+ char *abi;
+ unsigned major;
+ unsigned minor;
struct symbol *sym;
const struct token *t_mod;
@@ -102,31 +106,52 @@ vcc_ParseJSON(const struct vcc *tl, const char *jsn, struct vmod_import *vim)
return ("Not array[0]");
vv2 = VTAILQ_FIRST(&vv->children);
+ AN(vv2);
if (!vjsn_is_array(vv2))
return ("Not array[1]");
vv3 = VTAILQ_FIRST(&vv2->children);
+ AN(vv3);
if (!vjsn_is_string(vv3))
return ("Not string[2]");
if (strcmp(vv3->value, "$VMOD"))
return ("Not $VMOD[3]");
vv3 = VTAILQ_NEXT(vv3, list);
+ AN(vv3);
assert(vjsn_is_string(vv3));
vim->vmod_syntax = strtod(vv3->value, NULL);
assert (vim->vmod_syntax == 1.0);
vv3 = VTAILQ_NEXT(vv3, list);
+ AN(vv3);
assert(vjsn_is_string(vv3));
vim->name = vv3->value;
vv3 = VTAILQ_NEXT(vv3, list);
+ AN(vv3);
assert(vjsn_is_string(vv3));
vim->func_name = vv3->value;
vv3 = VTAILQ_NEXT(vv3, list);
+ AN(vv3);
assert(vjsn_is_string(vv3));
vim->file_id = vv3->value;
+ vv3 = VTAILQ_NEXT(vv3, list);
+ AN(vv3);
+ assert(vjsn_is_string(vv3));
+ vim->abi = vv3->value;
+
+ vv3 = VTAILQ_NEXT(vv3, list);
+ AN(vv3);
+ assert(vjsn_is_number(vv3));
+ vim->major = atoi(vv3->value);
+
+ vv3 = VTAILQ_NEXT(vv3, list);
+ AN(vv3);
+ assert(vjsn_is_number(vv3));
+ vim->minor = atoi(vv3->value);
+
if (!vcc_IdIs(vim->t_mod, vim->name)) {
VSB_printf(tl->sb, "Wrong file for VMOD %.*s\n",
PF(vim->t_mod));
@@ -135,6 +160,27 @@ vcc_ParseJSON(const struct vcc *tl, const char *jsn, struct vmod_import *vim)
return ("");
}
+ if (vim->major == 0 && vim->minor == 0 &&
+ strcmp(vim->abi, VMOD_ABI_Version)) {
+ VSB_printf(tl->sb, "Incompatible VMOD %.*s\n", PF(vim->t_mod));
+ VSB_printf(tl->sb, "\tFile name: %s\n", vim->path);
+ VSB_printf(tl->sb, "\tABI mismatch, expected <%s>, got <%s>\n",
+ VMOD_ABI_Version, vim->abi);
+ return ("");
+ }
+ if (vim->major != 0 &&
+ (vim->major != VRT_MAJOR_VERSION ||
+ vim->minor > VRT_MINOR_VERSION)) {
+ VSB_printf(tl->sb, "Incompatible VMOD %.*s\n", PF(vim->t_mod));
+ VSB_printf(tl->sb, "\tFile name: %s\n", vim->path);
+ VSB_printf(tl->sb, "\tVMOD wants ABI version %u.%u\n",
+ vim->major, vim->minor);
+ VSB_printf(tl->sb, "\tvarnishd provides ABI version %u.%u\n",
+ VRT_MAJOR_VERSION, VRT_MINOR_VERSION);
+ return ("");
+ }
+
+
VTAILQ_FOREACH(vv2, &vv->children, list) {
assert (vjsn_is_array(vv2));
vv3 = VTAILQ_FIRST(&vv2->children);
@@ -204,7 +250,9 @@ vcc_VmodLoad(const struct vcc *tl, struct vmod_import *vim, char *fnp)
return (-1);
}
- err = vcc_ParseJSON(tl, vmd->json, vim);
+ assert(!memcmp(vmd->json, "VMOD_JSON_SPEC\x03", 15));
+
+ err = vcc_ParseJSON(tl, vmd->json + 15, vim);
AZ(dlclose(vim->hdl));
vim->hdl = NULL;
if (err != NULL && *err != '\0') {
diff --git a/lib/libvcc/vmodtool.py b/lib/libvcc/vmodtool.py
index 1ea7f66be..50e5ab99b 100755
--- a/lib/libvcc/vmodtool.py
+++ b/lib/libvcc/vmodtool.py
@@ -639,6 +639,12 @@ class ABIStanza(Stanza):
if self.vcc.strict_abi is None:
err("Valid ABI types are 'strict' or 'vrt', got '%s'\n" %
self.toks[1])
+ if self.vcc.strict_abi:
+ self.vcc.vrt_major = "0"
+ self.vcc.vrt_minor = "0"
+ else:
+ self.vcc.vrt_major = "VRT_MAJOR_VERSION"
+ self.vcc.vrt_minor = "VRT_MINOR_VERSION"
self.vcc.contents.append(self)
@@ -1097,16 +1103,27 @@ class vcc(object):
yield i + " "
def json(self, fo, fnx):
+ fo.write('#define STRINGIFY(arg) #arg\n')
fo.write("\nstatic const char Vmod_Json[] = {\n")
+ fo.write('\t"VMOD_JSON_SPEC\\x03"\n')
- for i in self.iter_json(fnx):
+ for n, i in enumerate(self.iter_json(fnx)):
fo.write('\t"')
for j in i:
if j in '"\\':
fo.write('\\')
fo.write(j)
- fo.write('"\n')
+ if n == 6:
+ # Hand-munge the JSON to insert stuff only known by
+ # the C-compiler at compile-time.
+ fo.write(',"\n\t" \\"" VMOD_ABI_Version "\\", "\n')
+ fo.write('\t STRINGIFY(%s) ", "\n' % self.vrt_major)
+ fo.write('\t STRINGIFY(%s)\n' % self.vrt_minor)
+ else:
+ fo.write('"\n')
fo.write('\t\"\\n\"\n};\n')
+ fo.write('#undef STRINGIFY\n')
+
def vmod_data(self, fo):
vmd = "Vmod_%s_Data" % self.modname
@@ -1115,12 +1132,8 @@ class vcc(object):
fo.write("/*lint -esym(%d, %s) */\n" % (i, vmd))
fo.write("\nextern const struct vmod_data %s;\n" % vmd)
fo.write("\nconst struct vmod_data %s = {\n" % vmd)
- if self.strict_abi:
- fo.write("\t.vrt_major =\t0,\n")
- fo.write("\t.vrt_minor =\t0,\n")
- else:
- fo.write("\t.vrt_major =\tVRT_MAJOR_VERSION,\n")
- fo.write("\t.vrt_minor =\tVRT_MINOR_VERSION,\n")
+ fo.write("\t.vrt_major =\t%s,\n" % self.vrt_major)
+ fo.write("\t.vrt_minor =\t%s,\n" % self.vrt_minor)
fo.write('\t.name =\t\t"%s",\n' % self.modname)
fo.write('\t.func =\t\t&%s,\n' % self.csn)
fo.write('\t.func_len =\tsizeof(%s),\n' % self.csn)
diff --git a/vmod/vmod_debug.c b/vmod/vmod_debug.c
index a0a11f5b6..846b00d92 100644
--- a/vmod/vmod_debug.c
+++ b/vmod/vmod_debug.c
@@ -1087,13 +1087,15 @@ const struct vmod_data Vmod_wrong2_Data = {
.func = foo_struct,
.func_len = sizeof foo_struct,
.func_name = "foo_struct",
- .json = "["
+ .json = "VMOD_JSON_SPEC\x03["
"["
"\"$VMOD\""
", \"1.0\""
", \"wrongN\""
", \"foo_struct\""
", \"file_id\""
+ ", \"abi\""
+ ", 0, 0" // major, minor
"]"
"]",
};
@@ -1106,13 +1108,15 @@ const struct vmod_data Vmod_wrong3_Data = {
.func = foo_struct,
.func_len = sizeof foo_struct,
.func_name = "foo_struct",
- .json = "["
+ .json = "VMOD_JSON_SPEC\x03["
"["
"\"$VMOD\""
", \"1.0\""
", \"wrongN\""
", \"foo_struct\""
", \"file_id\""
+ ", \"abi\""
+ ", 0, 0" // major, minor
"]"
", [\"$CPROTO\", \"\"]"
"]",
More information about the varnish-commit
mailing list