Commit c796ea52 authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Add abi, major and minor to VMOD JSON spec

parent 419fbade
...@@ -54,10 +54,14 @@ struct vmod_import { ...@@ -54,10 +54,14 @@ struct vmod_import {
const char *err; const char *err;
char *path; char *path;
// From $VMOD
double vmod_syntax; double vmod_syntax;
char *name; char *name;
char *func_name; char *func_name;
char *file_id; char *file_id;
char *abi;
unsigned major;
unsigned minor;
struct symbol *sym; struct symbol *sym;
const struct token *t_mod; const struct token *t_mod;
...@@ -102,31 +106,52 @@ vcc_ParseJSON(const struct vcc *tl, const char *jsn, struct vmod_import *vim) ...@@ -102,31 +106,52 @@ vcc_ParseJSON(const struct vcc *tl, const char *jsn, struct vmod_import *vim)
return ("Not array[0]"); return ("Not array[0]");
vv2 = VTAILQ_FIRST(&vv->children); vv2 = VTAILQ_FIRST(&vv->children);
AN(vv2);
if (!vjsn_is_array(vv2)) if (!vjsn_is_array(vv2))
return ("Not array[1]"); return ("Not array[1]");
vv3 = VTAILQ_FIRST(&vv2->children); vv3 = VTAILQ_FIRST(&vv2->children);
AN(vv3);
if (!vjsn_is_string(vv3)) if (!vjsn_is_string(vv3))
return ("Not string[2]"); return ("Not string[2]");
if (strcmp(vv3->value, "$VMOD")) if (strcmp(vv3->value, "$VMOD"))
return ("Not $VMOD[3]"); return ("Not $VMOD[3]");
vv3 = VTAILQ_NEXT(vv3, list); vv3 = VTAILQ_NEXT(vv3, list);
AN(vv3);
assert(vjsn_is_string(vv3)); assert(vjsn_is_string(vv3));
vim->vmod_syntax = strtod(vv3->value, NULL); vim->vmod_syntax = strtod(vv3->value, NULL);
assert (vim->vmod_syntax == 1.0); assert (vim->vmod_syntax == 1.0);
vv3 = VTAILQ_NEXT(vv3, list); vv3 = VTAILQ_NEXT(vv3, list);
AN(vv3);
assert(vjsn_is_string(vv3)); assert(vjsn_is_string(vv3));
vim->name = vv3->value; vim->name = vv3->value;
vv3 = VTAILQ_NEXT(vv3, list); vv3 = VTAILQ_NEXT(vv3, list);
AN(vv3);
assert(vjsn_is_string(vv3)); assert(vjsn_is_string(vv3));
vim->func_name = vv3->value; vim->func_name = vv3->value;
vv3 = VTAILQ_NEXT(vv3, list); vv3 = VTAILQ_NEXT(vv3, list);
AN(vv3);
assert(vjsn_is_string(vv3)); assert(vjsn_is_string(vv3));
vim->file_id = vv3->value; 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)) { if (!vcc_IdIs(vim->t_mod, vim->name)) {
VSB_printf(tl->sb, "Wrong file for VMOD %.*s\n", VSB_printf(tl->sb, "Wrong file for VMOD %.*s\n",
PF(vim->t_mod)); PF(vim->t_mod));
...@@ -135,6 +160,27 @@ vcc_ParseJSON(const struct vcc *tl, const char *jsn, struct vmod_import *vim) ...@@ -135,6 +160,27 @@ vcc_ParseJSON(const struct vcc *tl, const char *jsn, struct vmod_import *vim)
return (""); 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) { VTAILQ_FOREACH(vv2, &vv->children, list) {
assert (vjsn_is_array(vv2)); assert (vjsn_is_array(vv2));
vv3 = VTAILQ_FIRST(&vv2->children); vv3 = VTAILQ_FIRST(&vv2->children);
...@@ -204,7 +250,9 @@ vcc_VmodLoad(const struct vcc *tl, struct vmod_import *vim, char *fnp) ...@@ -204,7 +250,9 @@ vcc_VmodLoad(const struct vcc *tl, struct vmod_import *vim, char *fnp)
return (-1); 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)); AZ(dlclose(vim->hdl));
vim->hdl = NULL; vim->hdl = NULL;
if (err != NULL && *err != '\0') { if (err != NULL && *err != '\0') {
......
...@@ -639,6 +639,12 @@ class ABIStanza(Stanza): ...@@ -639,6 +639,12 @@ class ABIStanza(Stanza):
if self.vcc.strict_abi is None: if self.vcc.strict_abi is None:
err("Valid ABI types are 'strict' or 'vrt', got '%s'\n" % err("Valid ABI types are 'strict' or 'vrt', got '%s'\n" %
self.toks[1]) 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) self.vcc.contents.append(self)
...@@ -1097,16 +1103,27 @@ class vcc(object): ...@@ -1097,16 +1103,27 @@ class vcc(object):
yield i + " " yield i + " "
def json(self, fo, fnx): def json(self, fo, fnx):
fo.write('#define STRINGIFY(arg) #arg\n')
fo.write("\nstatic const char Vmod_Json[] = {\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"') fo.write('\t"')
for j in i: for j in i:
if j in '"\\': if j in '"\\':
fo.write('\\') fo.write('\\')
fo.write(j) 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('\t\"\\n\"\n};\n')
fo.write('#undef STRINGIFY\n')
def vmod_data(self, fo): def vmod_data(self, fo):
vmd = "Vmod_%s_Data" % self.modname vmd = "Vmod_%s_Data" % self.modname
...@@ -1115,12 +1132,8 @@ class vcc(object): ...@@ -1115,12 +1132,8 @@ class vcc(object):
fo.write("/*lint -esym(%d, %s) */\n" % (i, vmd)) fo.write("/*lint -esym(%d, %s) */\n" % (i, vmd))
fo.write("\nextern const struct vmod_data %s;\n" % vmd) fo.write("\nextern const struct vmod_data %s;\n" % vmd)
fo.write("\nconst struct vmod_data %s = {\n" % vmd) fo.write("\nconst struct vmod_data %s = {\n" % vmd)
if self.strict_abi: fo.write("\t.vrt_major =\t%s,\n" % self.vrt_major)
fo.write("\t.vrt_major =\t0,\n") fo.write("\t.vrt_minor =\t%s,\n" % self.vrt_minor)
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.name =\t\t"%s",\n' % self.modname) fo.write('\t.name =\t\t"%s",\n' % self.modname)
fo.write('\t.func =\t\t&%s,\n' % self.csn) fo.write('\t.func =\t\t&%s,\n' % self.csn)
fo.write('\t.func_len =\tsizeof(%s),\n' % self.csn) fo.write('\t.func_len =\tsizeof(%s),\n' % self.csn)
......
...@@ -1087,13 +1087,15 @@ const struct vmod_data Vmod_wrong2_Data = { ...@@ -1087,13 +1087,15 @@ const struct vmod_data Vmod_wrong2_Data = {
.func = foo_struct, .func = foo_struct,
.func_len = sizeof foo_struct, .func_len = sizeof foo_struct,
.func_name = "foo_struct", .func_name = "foo_struct",
.json = "[" .json = "VMOD_JSON_SPEC\x03["
"[" "["
"\"$VMOD\"" "\"$VMOD\""
", \"1.0\"" ", \"1.0\""
", \"wrongN\"" ", \"wrongN\""
", \"foo_struct\"" ", \"foo_struct\""
", \"file_id\"" ", \"file_id\""
", \"abi\""
", 0, 0" // major, minor
"]" "]"
"]", "]",
}; };
...@@ -1106,13 +1108,15 @@ const struct vmod_data Vmod_wrong3_Data = { ...@@ -1106,13 +1108,15 @@ const struct vmod_data Vmod_wrong3_Data = {
.func = foo_struct, .func = foo_struct,
.func_len = sizeof foo_struct, .func_len = sizeof foo_struct,
.func_name = "foo_struct", .func_name = "foo_struct",
.json = "[" .json = "VMOD_JSON_SPEC\x03["
"[" "["
"\"$VMOD\"" "\"$VMOD\""
", \"1.0\"" ", \"1.0\""
", \"wrongN\"" ", \"wrongN\""
", \"foo_struct\"" ", \"foo_struct\""
", \"file_id\"" ", \"file_id\""
", \"abi\""
", 0, 0" // major, minor
"]" "]"
", [\"$CPROTO\", \"\"]" ", [\"$CPROTO\", \"\"]"
"]", "]",
......
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