Commit 419fbade authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

More rework of VCC-VMOD code.

parent eaa1c903
......@@ -58,7 +58,7 @@
* binary/load-time compatible, increment MAJOR version
*
* NEXT (2022-09-15)
* C-prototypes moved into JSON
* VMOD C-prototypes moved into JSON
* VRT_AddVDP() deprecated
* VRT_AddVFP() deprecated
* VRT_RemoveVDP() deprecated
......
......@@ -30,6 +30,8 @@ libvcc_la_SOURCES = \
vcc_utils.c \
vcc_var.c \
vcc_vmod.c \
vcc_vmod.h \
vcc_vmod_sym.c \
vcc_xref.c
dist_noinst_SCRIPTS = \
......
......@@ -194,6 +194,9 @@ struct symbol {
const char *extra;
/* vcc_vmod.c */
const struct vmod_import *import;
/* SYM_VAR */
const char *rname;
unsigned r_methods;
......
This diff is collapsed.
/*-
* Copyright (c) 2010-2015 Varnish Software AS
* All rights reserved.
*
* Author: Poul-Henning Kamp <phk@phk.freebsd.dk>
*
* SPDX-License-Identifier: BSD-2-Clause
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#define STANZA_TBL \
STANZA(ALIAS, alias, SYM_ALIAS) \
STANZA(CPROTO, cproto, SYM_NONE) \
STANZA(EVENT, evant, SYM_NONE) \
STANZA(FUNC, func, SYM_FUNC) \
STANZA(METHOD, method, SYM_METHOD) \
STANZA(OBJ, obj, SYM_OBJECT) \
STANZA(VMOD, vmod, SYM_NONE)
void vcc_VmodSymbols(struct vcc *tl, const struct symbol *sym);
/*-
* Copyright (c) 2010-2015 Varnish Software AS
* All rights reserved.
*
* Author: Poul-Henning Kamp <phk@phk.freebsd.dk>
*
* SPDX-License-Identifier: BSD-2-Clause
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Turn vmod JSON spec into symbols
*
*/
#include "config.h"
#include <stdlib.h>
#include <string.h>
#include "vcc_compile.h"
#include "libvcc.h"
#include "vjsn.h"
#include "vsb.h"
#include "vcc_vmod.h"
struct vmod_obj {
unsigned magic;
#define VMOD_OBJ_MAGIC 0x349885f8
char *name;
struct type type[1];
VTAILQ_ENTRY(vmod_obj) list;
};
static void
vcc_VmodObject(struct vcc *tl, struct symbol *sym)
{
struct vmod_obj *obj;
struct vsb *buf;
buf = VSB_new_auto();
AN(buf);
VSB_printf(buf, "%s.%s", sym->vmod_name, sym->name);
AZ(VSB_finish(buf));
ALLOC_OBJ(obj, VMOD_OBJ_MAGIC);
AN(obj);
REPLACE(obj->name, VSB_data(buf));
INIT_OBJ(obj->type, TYPE_MAGIC);
obj->type->name = obj->name;
sym->type = obj->type;
VTAILQ_INSERT_TAIL(&tl->vmod_objects, obj, list);
VSB_destroy(&buf);
}
static void
alias_sym(struct vcc *tl, const struct symbol *psym, const struct vjsn_val *v)
{
char *alias = NULL, *func = NULL;
struct symbol *sym;
struct vsb *buf;
buf = VSB_new_auto();
AN(buf);
VCC_SymName(buf, psym);
VSB_printf(buf, ".%s", v->value);
AZ(VSB_finish(buf));
REPLACE(alias, VSB_data(buf));
v = VTAILQ_NEXT(v, list);
assert(vjsn_is_string(v));
VSB_clear(buf);
VCC_SymName(buf, psym);
VSB_printf(buf, ".%s", v->value);
AZ(VSB_finish(buf));
REPLACE(func, VSB_data(buf));
sym = VCC_MkSymAlias(tl, alias, func);
AN(sym);
assert(sym->kind == SYM_FUNC || sym->kind == SYM_METHOD);
VSB_destroy(&buf);
free(alias);
free(func);
}
static void
func_sym(struct vcc *tl, vcc_kind_t kind, const struct symbol *psym,
const struct vjsn_val *v)
{
struct symbol *sym;
struct vsb *buf;
if (kind == SYM_ALIAS) {
alias_sym(tl, psym, v);
return;
}
buf = VSB_new_auto();
AN(buf);
VCC_SymName(buf, psym);
VSB_printf(buf, ".%s", v->value);
AZ(VSB_finish(buf));
sym = VCC_MkSym(tl, VSB_data(buf), SYM_MAIN, kind, VCL_LOW, VCL_HIGH);
AN(sym);
VSB_destroy(&buf);
if (kind == SYM_OBJECT) {
sym->eval_priv = v;
sym->vmod_name = psym->vmod_name;
sym->r_methods = VCL_MET_INIT;
vcc_VmodObject(tl, sym);
vcc_VmodSymbols(tl, sym);
return;
}
if (kind == SYM_METHOD)
sym->extra = psym->rname;
v = VTAILQ_NEXT(v, list);
assert(vjsn_is_array(v));
sym->action = vcc_Act_Call;
sym->vmod_name = psym->vmod_name;
sym->eval = vcc_Eval_SymFunc;
sym->eval_priv = v;
v = VTAILQ_FIRST(&v->children);
assert(vjsn_is_array(v));
v = VTAILQ_FIRST(&v->children);
assert(vjsn_is_string(v));
sym->type = VCC_Type(v->value);
AN(sym->type);
sym->r_methods = VCL_MET_TASK_ALL;
}
void
vcc_VmodSymbols(struct vcc *tl, const struct symbol *sym)
{
const struct vjsn *vj;
const struct vjsn_val *vv, *vv1, *vv2;
vcc_kind_t kind;
if (sym->kind == SYM_VMOD) {
CAST_OBJ_NOTNULL(vj, sym->eval_priv, VJSN_MAGIC);
vv = VTAILQ_FIRST(&vj->value->children);
} else if (sym->kind == SYM_OBJECT) {
CAST_OBJ_NOTNULL(vv, sym->eval_priv, VJSN_VAL_MAGIC);
} else {
WRONG("symbol kind");
}
for (; vv != NULL; vv = VTAILQ_NEXT(vv, list)) {
if (!vjsn_is_array(vv))
continue;
vv1 = VTAILQ_FIRST(&vv->children);
assert(vjsn_is_string(vv1));
vv2 = VTAILQ_NEXT(vv1, list);
if (!vjsn_is_string(vv2))
continue;
kind = SYM_NONE;
#define STANZA(UU, ll, ss) if (!strcmp(vv1->value, "$" #UU)) kind = ss;
STANZA_TBL
#undef STANZA
if (kind != SYM_NONE)
func_sym(tl, kind, sym, vv2);
}
}
void v_matchproto_(sym_act_f)
vcc_Act_New(struct vcc *tl, struct token *t, struct symbol *sym)
{
struct symbol *isym, *osym;
struct inifin *ifp;
struct vsb *buf;
const struct vjsn_val *vv, *vf;
int null_ok = 0;
(void)sym;
(void)t;
ExpectErr(tl, ID);
vcc_ExpectVid(tl, "VCL object");
ERRCHK(tl);
isym = VCC_HandleSymbol(tl, INSTANCE);
ERRCHK(tl);
AN(isym);
isym->noref = 1;
isym->action = vcc_Act_Obj;
SkipToken(tl, '=');
ExpectErr(tl, ID);
osym = VCC_SymbolGet(tl, SYM_MAIN, SYM_OBJECT, SYMTAB_EXISTING,
XREF_NONE);
ERRCHK(tl);
AN(osym);
/* Scratch the generic INSTANCE type */
isym->type = osym->type;
CAST_OBJ_NOTNULL(vv, osym->eval_priv, VJSN_VAL_MAGIC);
// vv = object name
isym->vmod_name = osym->vmod_name;
isym->eval_priv = vv;
vv = VTAILQ_NEXT(vv, list);
// vv = flags
assert(vjsn_is_object(vv));
VTAILQ_FOREACH(vf, &vv->children, list)
if (!strcmp(vf->name, "NULL_OK") && vjsn_is_true(vf))
null_ok = 1;
if (!null_ok)
VTAILQ_INSERT_TAIL(&tl->sym_objects, isym, sideways);
vv = VTAILQ_NEXT(vv, list);
// vv = struct name
Fh(tl, 0, "static %s *%s;\n\n", vv->value, isym->rname);
vv = VTAILQ_NEXT(vv, list);
vf = VTAILQ_FIRST(&vv->children);
vv = VTAILQ_NEXT(vv, list);
assert(vjsn_is_string(vf));
assert(!strcmp(vf->value, "$INIT"));
vf = VTAILQ_NEXT(vf, list);
buf = VSB_new_auto();
AN(buf);
VSB_printf(buf, "&%s, \"%s\"", isym->rname, isym->name);
AZ(VSB_finish(buf));
vcc_Eval_Func(tl, vf, VSB_data(buf), osym);
VSB_destroy(&buf);
ERRCHK(tl);
SkipToken(tl, ';');
isym->def_e = tl->t;
vf = VTAILQ_FIRST(&vv->children);
assert(vjsn_is_string(vf));
assert(!strcmp(vf->value, "$FINI"));
vf = VTAILQ_NEXT(vf, list);
vf = VTAILQ_FIRST(&vf->children);
vf = VTAILQ_NEXT(vf, list);
ifp = New_IniFin(tl);
VSB_printf(ifp->fin, "\t\tif (%s)\n", isym->rname);
VSB_printf(ifp->fin, "\t\t\t\t%s(&%s);", vf->value, isym->rname);
}
......@@ -1086,7 +1086,7 @@ class vcc(object):
def iter_json(self, fnx):
jl = [["$VMOD", "1.0"]]
jl = [["$VMOD", "1.0", self.modname, self.csn, self.file_id]]
jl.append(["$CPROTO"])
for i in open(fnx):
jl[-1].append(i.rstrip())
......
......@@ -1087,7 +1087,15 @@ const struct vmod_data Vmod_wrong2_Data = {
.func = foo_struct,
.func_len = sizeof foo_struct,
.func_name = "foo_struct",
.json = "blablabla",
.json = "["
"["
"\"$VMOD\""
", \"1.0\""
", \"wrongN\""
", \"foo_struct\""
", \"file_id\""
"]"
"]",
};
extern const struct vmod_data Vmod_wrong3_Data;
......@@ -1098,7 +1106,16 @@ const struct vmod_data Vmod_wrong3_Data = {
.func = foo_struct,
.func_len = sizeof foo_struct,
.func_name = "foo_struct",
.json = "blablabla",
.json = "["
"["
"\"$VMOD\""
", \"1.0\""
", \"wrongN\""
", \"foo_struct\""
", \"file_id\""
"]"
", [\"$CPROTO\", \"\"]"
"]",
.abi = "abiblabla",
};
......
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