Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
varnish-cache
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Commits
Open sidebar
varnishcache
varnish-cache
Commits
419fbade
Commit
419fbade
authored
Jun 23, 2022
by
Poul-Henning Kamp
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
More rework of VCC-VMOD code.
parent
eaa1c903
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
566 additions
and
398 deletions
+566
-398
vrt.h
include/vrt.h
+1
-1
Makefile.am
lib/libvcc/Makefile.am
+2
-0
vcc_compile.h
lib/libvcc/vcc_compile.h
+3
-0
vcc_vmod.c
lib/libvcc/vcc_vmod.c
+227
-394
vcc_vmod.h
lib/libvcc/vcc_vmod.h
+40
-0
vcc_vmod_sym.c
lib/libvcc/vcc_vmod_sym.c
+273
-0
vmodtool.py
lib/libvcc/vmodtool.py
+1
-1
vmod_debug.c
vmod/vmod_debug.c
+19
-2
No files found.
include/vrt.h
View file @
419fbade
...
...
@@ -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
...
...
lib/libvcc/Makefile.am
View file @
419fbade
...
...
@@ -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
=
\
...
...
lib/libvcc/vcc_compile.h
View file @
419fbade
...
...
@@ -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
;
...
...
lib/libvcc/vcc_vmod.c
View file @
419fbade
...
...
@@ -26,6 +26,9 @@
* 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.
*
* Parse `import`, check metadata and versioning.
*
*/
#include "config.h"
...
...
@@ -42,22 +45,31 @@
#include "vmod_abi.h"
#include "vsb.h"
#include "vcc_vmod.h"
struct
vmod_import
{
unsigned
magic
;
#define VMOD_IMPORT_MAGIC 0x31803a5d
void
*
hdl
;
const
char
*
err
;
const
struct
vmod_data
*
vmd
;
};
char
*
path
;
struct
vmod_obj
{
unsigned
magic
;
#define VMOD_OBJ_MAGIC 0x349885f8
double
vmod_syntax
;
char
*
name
;
struct
type
type
[
1
];
VTAILQ_ENTRY
(
vmod_obj
)
list
;
char
*
func_name
;
char
*
file_id
;
struct
symbol
*
sym
;
const
struct
token
*
t_mod
;
struct
vjsn
*
vj
;
#define STANZA(UU, ll, ss) int n_##ll;
STANZA_TBL
#undef STANZA
};
typedef
void
vcc_do_stanza_f
(
struct
vcc
*
tl
,
const
struct
vmod_import
*
vim
,
const
struct
vjsn_val
*
vv
);
static
int
vcc_path_dlopen
(
void
*
priv
,
const
char
*
fn
)
{
...
...
@@ -74,178 +86,111 @@ vcc_path_dlopen(void *priv, const char *fn)
return
(
0
);
}
static
void
vcc_VmodObject
(
struct
vcc
*
tl
,
struct
symbol
*
sym
);
static
void
vcc_VmodSymbols
(
struct
vcc
*
tl
,
const
struct
symbol
*
sym
);
static
void
alias_sym
(
struct
vcc
*
tl
,
const
struct
symbol
*
psym
,
const
struct
vjsn_val
*
v
)
static
const
char
*
vcc_ParseJSON
(
const
struct
vcc
*
tl
,
const
char
*
jsn
,
struct
vmod_import
*
vim
)
{
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
;
const
struct
vjsn_val
*
vv
,
*
vv2
,
*
vv3
;
const
char
*
err
;
vim
->
vj
=
vjsn_parse
(
jsn
,
&
err
);
if
(
err
!=
NULL
)
return
(
err
);
AN
(
vim
->
vj
);
vv
=
vim
->
vj
->
value
;
if
(
!
vjsn_is_array
(
vv
))
return
(
"Not array[0]"
);
vv2
=
VTAILQ_FIRST
(
&
vv
->
children
);
if
(
!
vjsn_is_array
(
vv2
))
return
(
"Not array[1]"
);
vv3
=
VTAILQ_FIRST
(
&
vv2
->
children
);
if
(
!
vjsn_is_string
(
vv3
))
return
(
"Not string[2]"
);
if
(
strcmp
(
vv3
->
value
,
"$VMOD"
))
return
(
"Not $VMOD[3]"
);
vv3
=
VTAILQ_NEXT
(
vv3
,
list
);
assert
(
vjsn_is_string
(
vv3
));
vim
->
vmod_syntax
=
strtod
(
vv3
->
value
,
NULL
);
assert
(
vim
->
vmod_syntax
==
1
.
0
);
vv3
=
VTAILQ_NEXT
(
vv3
,
list
);
assert
(
vjsn_is_string
(
vv3
));
vim
->
name
=
vv3
->
value
;
vv3
=
VTAILQ_NEXT
(
vv3
,
list
);
assert
(
vjsn_is_string
(
vv3
));
vim
->
func_name
=
vv3
->
value
;
vv3
=
VTAILQ_NEXT
(
vv3
,
list
);
assert
(
vjsn_is_string
(
vv3
));
vim
->
file_id
=
vv3
->
value
;
if
(
!
vcc_IdIs
(
vim
->
t_mod
,
vim
->
name
))
{
VSB_printf
(
tl
->
sb
,
"Wrong file for VMOD %.*s
\n
"
,
PF
(
vim
->
t_mod
));
VSB_printf
(
tl
->
sb
,
"
\t
File name: %s
\n
"
,
vim
->
path
);
VSB_printf
(
tl
->
sb
,
"
\t
Contains vmod
\"
%s
\"\n
"
,
vim
->
name
);
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
;
VTAILQ_FOREACH
(
vv2
,
&
vv
->
children
,
list
)
{
assert
(
vjsn_is_array
(
vv2
));
vv3
=
VTAILQ_FIRST
(
&
vv2
->
children
);
assert
(
vjsn_is_string
(
vv3
));
assert
(
vv3
->
value
[
0
]
==
'$'
);
#define STANZA(UU, ll, ss) \
if (!strcmp(vv3->value, "$" #UU)) {vim->n_##ll++; continue;}
STANZA_TBL
#undef STANZA
return
(
"Unknown entry"
);
}
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
;
if
(
vim
->
n_cproto
!=
1
)
return
(
"Bad cproto stanza(s)"
);
if
(
vim
->
n_vmod
!=
1
)
return
(
"Bad vmod stanza(s)"
);
return
(
NULL
);
}
static
void
vcc_json_always
(
struct
vcc
*
tl
,
const
struct
vjsn
*
vj
,
const
char
*
vmod_name
)
{
struct
inifin
*
ifp
;
const
struct
vjsn_val
*
vv
,
*
vv2
;
double
vmod_syntax
=
0
.
0
;
int
cproto_seen
=
0
;
AN
(
vj
);
AN
(
vmod_name
);
ifp
=
NULL
;
VTAILQ_FOREACH
(
vv
,
&
vj
->
value
->
children
,
list
)
{
assert
(
vjsn_is_array
(
vv
));
vv2
=
VTAILQ_FIRST
(
&
vv
->
children
);
assert
(
vjsn_is_string
(
vv2
));
if
(
!
strcmp
(
vv2
->
value
,
"$VMOD"
))
{
vmod_syntax
=
strtod
(
VTAILQ_NEXT
(
vv2
,
list
)
->
value
,
NULL
);
continue
;
}
assert
(
vmod_syntax
==
1
.
0
);
if
(
!
strcmp
(
vv2
->
value
,
"$EVENT"
))
{
/* XXX: What about the rest of the events ? */
if
(
ifp
==
NULL
)
ifp
=
New_IniFin
(
tl
);
vv2
=
VTAILQ_NEXT
(
vv2
,
list
);
VSB_printf
(
ifp
->
ini
,
"
\t
if (%s(ctx, &vmod_priv_%s, VCL_EVENT_LOAD))
\n
"
"
\t\t
return(1);"
,
vv2
->
value
,
vmod_name
);
VSB_printf
(
ifp
->
fin
,
"
\t\t
(void)%s(ctx, &vmod_priv_%s,
\n
"
"
\t\t\t
VCL_EVENT_DISCARD);"
,
vv2
->
value
,
vmod_name
);
VSB_printf
(
ifp
->
event
,
"%s(ctx, &vmod_priv_%s, ev)"
,
vv2
->
value
,
vmod_name
);
}
else
if
(
!
strcmp
(
vv2
->
value
,
"$ALIAS"
))
{
}
else
if
(
!
strcmp
(
vv2
->
value
,
"$FUNC"
))
{
}
else
if
(
!
strcmp
(
vv2
->
value
,
"$OBJ"
))
{
}
else
if
(
!
strcmp
(
vv2
->
value
,
"$CPROTO"
))
{
cproto_seen
=
1
;
}
else
{
VTAILQ_FOREACH
(
vv2
,
&
vv
->
children
,
list
)
fprintf
(
stderr
,
"
\t
t %s n %s v %s
\n
"
,
vv2
->
type
,
vv2
->
name
,
vv2
->
value
);
WRONG
(
"Vmod JSON syntax error"
);
}
}
if
(
!
cproto_seen
)
WRONG
(
"Vmod JSON has no CPROTO"
);
}
/*
* Load and check the metadata from the objectfile containing the vmod
*/
static
const
struct
vmod_data
*
vcc_Vmod
Sanity
(
struct
vcc
*
tl
,
void
*
hdl
,
const
struct
token
*
mod
,
char
*
fnp
)
static
int
vcc_Vmod
Load
(
const
struct
vcc
*
tl
,
struct
vmod_import
*
vim
,
char
*
fnp
)
{
char
buf
[
256
];
static
const
char
*
err
;
const
struct
vmod_data
*
vmd
;
bprintf
(
buf
,
"Vmod_%.*s_Data"
,
PF
(
mod
));
vmd
=
dlsym
(
hdl
,
buf
);
CHECK_OBJ_NOTNULL
(
vim
,
VMOD_IMPORT_MAGIC
);
bprintf
(
buf
,
"Vmod_%.*s_Data"
,
PF
(
vim
->
t_mod
));
vmd
=
dlsym
(
vim
->
hdl
,
buf
);
if
(
vmd
==
NULL
)
{
VSB_printf
(
tl
->
sb
,
"Malformed VMOD %.*s
\n
"
,
PF
(
mod
));
VSB_printf
(
tl
->
sb
,
"Malformed VMOD %.*s
\n
"
,
PF
(
vim
->
t_
mod
));
VSB_printf
(
tl
->
sb
,
"
\t
File name: %s
\n
"
,
fnp
);
VSB_cat
(
tl
->
sb
,
"
\t
(no Vmod_Data symbol)
\n
"
);
vcc_ErrWhere
(
tl
,
mod
);
return
(
NULL
);
return
(
-
1
);
}
if
(
vmd
->
vrt_major
==
0
&&
vmd
->
vrt_minor
==
0
&&
(
vmd
->
abi
==
NULL
||
strcmp
(
vmd
->
abi
,
VMOD_ABI_Version
)
!=
0
))
{
VSB_printf
(
tl
->
sb
,
"Incompatible VMOD %.*s
\n
"
,
PF
(
mod
));
(
vmd
->
abi
==
NULL
||
strcmp
(
vmd
->
abi
,
VMOD_ABI_Version
)))
{
VSB_printf
(
tl
->
sb
,
"Incompatible VMOD %.*s
\n
"
,
PF
(
vim
->
t_
mod
));
VSB_printf
(
tl
->
sb
,
"
\t
File name: %s
\n
"
,
fnp
);
VSB_printf
(
tl
->
sb
,
"
\t
ABI mismatch, expected <%s>, got <%s>
\n
"
,
VMOD_ABI_Version
,
vmd
->
abi
);
vcc_ErrWhere
(
tl
,
mod
);
return
(
NULL
);
return
(
-
1
);
}
if
(
vmd
->
vrt_major
!=
0
&&
(
vmd
->
vrt_major
!=
VRT_MAJOR_VERSION
||
if
(
vmd
->
vrt_major
!=
0
&&
(
vmd
->
vrt_major
!=
VRT_MAJOR_VERSION
||
vmd
->
vrt_minor
>
VRT_MINOR_VERSION
))
{
VSB_printf
(
tl
->
sb
,
"Incompatible VMOD %.*s
\n
"
,
PF
(
mod
));
VSB_printf
(
tl
->
sb
,
"Incompatible VMOD %.*s
\n
"
,
PF
(
vim
->
t_
mod
));
VSB_printf
(
tl
->
sb
,
"
\t
File name: %s
\n
"
,
fnp
);
VSB_printf
(
tl
->
sb
,
"
\t
VMOD wants ABI version %u.%u
\n
"
,
vmd
->
vrt_major
,
vmd
->
vrt_minor
);
VSB_printf
(
tl
->
sb
,
"
\t
varnishd provides ABI version %u.%u
\n
"
,
VRT_MAJOR_VERSION
,
VRT_MINOR_VERSION
);
vcc_ErrWhere
(
tl
,
mod
);
return
(
NULL
);
return
(
-
1
);
}
if
(
vmd
->
name
==
NULL
||
vmd
->
func
==
NULL
||
...
...
@@ -253,131 +198,146 @@ vcc_VmodSanity(struct vcc *tl, void *hdl, const struct token *mod, char *fnp)
vmd
->
json
==
NULL
||
vmd
->
proto
!=
NULL
||
vmd
->
abi
==
NULL
)
{
VSB_printf
(
tl
->
sb
,
"Mangled VMOD %.*s
\n
"
,
PF
(
mod
));
VSB_printf
(
tl
->
sb
,
"Mangled VMOD %.*s
\n
"
,
PF
(
vim
->
t_
mod
));
VSB_printf
(
tl
->
sb
,
"
\t
File name: %s
\n
"
,
fnp
);
VSB_cat
(
tl
->
sb
,
"
\t
Inconsistent metadata
\n
"
);
vcc_ErrWhere
(
tl
,
mod
);
return
(
NULL
);
return
(
-
1
);
}
if
(
!
vcc_IdIs
(
mod
,
vmd
->
name
))
{
VSB_printf
(
tl
->
sb
,
"Wrong file for VMOD %.*s
\n
"
,
PF
(
mod
));
VSB_printf
(
tl
->
sb
,
"
\t
File name: %s
\n
"
,
fnp
);
VSB_printf
(
tl
->
sb
,
"
\t
Contains vmod
\"
%s
\"\n
"
,
vmd
->
name
);
vcc_ErrWhere
(
tl
,
mod
);
return
(
NULL
);
err
=
vcc_ParseJSON
(
tl
,
vmd
->
json
,
vim
);
AZ
(
dlclose
(
vim
->
hdl
));
vim
->
hdl
=
NULL
;
if
(
err
!=
NULL
&&
*
err
!=
'\0'
)
{
VSB_printf
(
tl
->
sb
,
"VMOD %.*s: bad metadata
\n
"
,
PF
(
vim
->
t_mod
));
VSB_printf
(
tl
->
sb
,
"
\t
(%s)
\n
"
,
err
);
VSB_printf
(
tl
->
sb
,
"
\t
File name: %s
\n
"
,
vim
->
path
);
}
return
(
vmd
);
}
static
vcc_kind_t
vcc_vmod_kind
(
const
char
*
type
)
{
if
(
err
!=
NULL
)
return
(
-
1
);
#define VMOD_KIND(str, kind) \
do { \
if (!strcmp(str, type)) \
return (kind); \
} while (0)
VMOD_KIND
(
"$OBJ"
,
SYM_OBJECT
);
VMOD_KIND
(
"$METHOD"
,
SYM_METHOD
);
VMOD_KIND
(
"$FUNC"
,
SYM_FUNC
);
VMOD_KIND
(
"$ALIAS"
,
SYM_ALIAS
);
#undef VMOD_KIND
return
(
SYM_NONE
);
return
(
0
);
}
static
void
vcc_VmodObject
(
struct
vcc
*
tl
,
struct
symbol
*
sym
)
static
void
v_matchproto_
(
vcc_do_stanza_f
)
vcc_do_event
(
struct
vcc
*
tl
,
const
struct
vmod_import
*
vim
,
const
struct
vjsn_val
*
vv
)
{
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
));
struct
inifin
*
ifp
;
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
);
ifp
=
New_IniFin
(
tl
);
VSB_printf
(
ifp
->
ini
,
"
\t
if (%s(ctx, &vmod_priv_%s, VCL_EVENT_LOAD))
\n
"
"
\t\t
return(1);"
,
vv
->
value
,
vim
->
sym
->
vmod_name
);
VSB_printf
(
ifp
->
fin
,
"
\t\t
(void)%s(ctx, &vmod_priv_%s,
\n
"
"
\t\t\t
VCL_EVENT_DISCARD);"
,
vv
->
value
,
vim
->
sym
->
vmod_name
);
VSB_printf
(
ifp
->
event
,
"%s(ctx, &vmod_priv_%s, ev)"
,
vv
->
value
,
vim
->
sym
->
vmod_name
);
}
static
void
vcc_VmodSymbols
(
struct
vcc
*
tl
,
const
struct
symbol
*
sym
)
static
void
v_matchproto_
(
vcc_do_stanza_f
)
vcc_do_cproto
(
struct
vcc
*
tl
,
const
struct
vmod_import
*
vim
,
const
struct
vjsn_val
*
vv
)
{
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
=
vcc_vmod_kind
(
vv1
->
value
);
if
(
kind
==
SYM_NONE
)
continue
;
func_sym
(
tl
,
kind
,
sym
,
vv2
);
}
(
void
)
vim
;
do
{
assert
(
vjsn_is_string
(
vv
));
Fh
(
tl
,
0
,
"%s
\n
"
,
vv
->
value
);
vv
=
VTAILQ_NEXT
(
vv
,
list
);
}
while
(
vv
!=
NULL
);
}
static
void
vcc_emit_c_prototypes
(
const
struct
vcc
*
tl
,
const
struct
vjsn
*
vj
)
vcc_vj_foreach
(
struct
vcc
*
tl
,
const
struct
vmod_import
*
vim
,
const
char
*
stanza
,
vcc_do_stanza_f
*
func
)
{
const
struct
vjsn_val
*
vv
,
*
vv2
,
*
vv3
;
Fh
(
tl
,
0
,
"
\n
"
);
vv
=
vj
->
value
;
vv
=
vim
->
vj
->
value
;
assert
(
vjsn_is_array
(
vv
));
vv3
=
NULL
;
VTAILQ_FOREACH
(
vv2
,
&
vv
->
children
,
list
)
{
assert
(
vjsn_is_array
(
vv2
));
vv3
=
VTAILQ_FIRST
(
&
vv2
->
children
);
assert
(
vjsn_is_string
(
vv3
));
if
(
!
strcmp
(
vv3
->
value
,
"$CPROTO"
))
break
;
}
assert
(
vv3
!=
NULL
);
while
(
1
)
{
vv3
=
VTAILQ_NEXT
(
vv3
,
list
);
if
(
vv3
==
NULL
)
break
;
assert
(
vjsn_is_string
(
vv3
));
Fh
(
tl
,
0
,
"%s
\n
"
,
vv3
->
value
);
if
(
!
strcmp
(
vv3
->
value
,
stanza
))
func
(
tl
,
vim
,
VTAILQ_NEXT
(
vv3
,
list
));
}
}
static
void
vcc_emit_setup
(
struct
vcc
*
tl
,
const
struct
vmod_import
*
vim
)
{
struct
inifin
*
ifp
;
const
struct
token
*
mod
=
vim
->
t_mod
;
ifp
=
New_IniFin
(
tl
);
VSB_cat
(
ifp
->
ini
,
"
\t
if (VPI_Vmod_Init(ctx,
\n
"
);
VSB_printf
(
ifp
->
ini
,
"
\t
&VGC_vmod_%.*s,
\n
"
,
PF
(
mod
));
VSB_printf
(
ifp
->
ini
,
"
\t
%u,
\n
"
,
tl
->
vmod_count
++
);
VSB_printf
(
ifp
->
ini
,
"
\t
&%s,
\n
"
,
vim
->
func_name
);
VSB_printf
(
ifp
->
ini
,
"
\t
sizeof(%s),
\n
"
,
vim
->
func_name
);
VSB_printf
(
ifp
->
ini
,
"
\t
\"
%.*s
\"
,
\n
"
,
PF
(
mod
));
VSB_cat
(
ifp
->
ini
,
"
\t
"
);
VSB_quote
(
ifp
->
ini
,
vim
->
path
,
-
1
,
VSB_QUOTE_CSTR
);
VSB_cat
(
ifp
->
ini
,
",
\n
"
);
AN
(
vim
->
file_id
);
VSB_printf
(
ifp
->
ini
,
"
\t
\"
%s
\"
,
\n
"
,
vim
->
file_id
);
VSB_printf
(
ifp
->
ini
,
"
\t
\"
./vmod_cache/_vmod_%.*s.%s
\"\n
"
,
PF
(
mod
),
vim
->
file_id
);
VSB_cat
(
ifp
->
ini
,
"
\t
))
\n
"
);
VSB_cat
(
ifp
->
ini
,
"
\t\t
return(1);"
);
VSB_cat
(
tl
->
symtab
,
",
\n
{
\n
"
);
VSB_cat
(
tl
->
symtab
,
"
\t\"
dir
\"
:
\"
import
\"
,
\n
"
);
VSB_cat
(
tl
->
symtab
,
"
\t\"
type
\"
:
\"
$VMOD
\"
,
\n
"
);
VSB_printf
(
tl
->
symtab
,
"
\t\"
name
\"
:
\"
%.*s
\"
,
\n
"
,
PF
(
mod
));
VSB_printf
(
tl
->
symtab
,
"
\t\"
file
\"
:
\"
%s
\"
,
\n
"
,
vim
->
path
);
VSB_printf
(
tl
->
symtab
,
"
\t\"
dst
\"
:
\"
./vmod_cache/_vmod_%.*s.%s
\"\n
"
,
PF
(
mod
),
vim
->
file_id
);
VSB_cat
(
tl
->
symtab
,
" }"
);
/* XXX: zero the function pointer structure ?*/
VSB_printf
(
ifp
->
fin
,
"
\t\t
VRT_priv_fini(ctx, &vmod_priv_%.*s);"
,
PF
(
mod
));
VSB_printf
(
ifp
->
final
,
"
\t\t
VPI_Vmod_Unload(ctx, &VGC_vmod_%.*s);"
,
PF
(
mod
));
vcc_vj_foreach
(
tl
,
vim
,
"$EVENT"
,
vcc_do_event
);
Fh
(
tl
,
0
,
"
\n
/* --- BEGIN VMOD %.*s --- */
\n\n
"
,
PF
(
mod
));
Fh
(
tl
,
0
,
"static struct vmod *VGC_vmod_%.*s;
\n
"
,
PF
(
mod
));
Fh
(
tl
,
0
,
"static struct vmod_priv vmod_priv_%.*s;
\n
"
,
PF
(
mod
));
vcc_vj_foreach
(
tl
,
vim
,
"$CPROTO"
,
vcc_do_cproto
);
Fh
(
tl
,
0
,
"
\n
/* --- END VMOD %.*s --- */
\n\n
"
,
PF
(
mod
));
}
static
void
vcc_vim_destroy
(
struct
vmod_import
**
vimp
)
{
struct
vmod_import
*
vim
;
TAKE_OBJ_NOTNULL
(
vim
,
vimp
,
VMOD_IMPORT_MAGIC
);
if
(
vim
->
path
)
free
(
vim
->
path
);
if
(
vim
->
vj
)
vjsn_delete
(
&
vim
->
vj
);
FREE_OBJ
(
vim
);
}
void
vcc_ParseImport
(
struct
vcc
*
tl
)
{
char
fn
[
1024
]
,
*
fnpx
;
char
fn
[
1024
];
const
char
*
p
;
struct
token
*
mod
,
*
tmod
,
*
t1
;
struct
inifin
*
ifp
;
struct
symbol
*
msym
,
*
vsym
;
const
struct
vmod_data
*
vmd
;
struct
vjsn
*
vj
;
struct
vmod_import
*
vim
;
const
struct
vmod_import
*
vimold
;
...
...
@@ -428,8 +388,10 @@ vcc_ParseImport(struct vcc *tl)
ALLOC_OBJ
(
vim
,
VMOD_IMPORT_MAGIC
);
AN
(
vim
);
vim
->
t_mod
=
mod
;
vim
->
sym
=
msym
;
if
(
VFIL_searchpath
(
tl
->
vmod_path
,
vcc_path_dlopen
,
vim
,
fn
,
&
fnpx
))
{
if
(
VFIL_searchpath
(
tl
->
vmod_path
,
vcc_path_dlopen
,
vim
,
fn
,
&
vim
->
path
))
{
if
(
vim
->
err
==
NULL
)
{
VSB_printf
(
tl
->
sb
,
"Could not find VMOD %.*s
\n
"
,
PF
(
mod
));
...
...
@@ -437,26 +399,24 @@ vcc_ParseImport(struct vcc *tl)
VSB_printf
(
tl
->
sb
,
"Could not open VMOD %.*s
\n
"
,
PF
(
mod
));
VSB_printf
(
tl
->
sb
,
"
\t
File name: %s
\n
"
,
fnpx
!=
NULL
?
fnpx
:
fn
);
vim
->
path
!=
NULL
?
vim
->
path
:
fn
);
VSB_printf
(
tl
->
sb
,
"
\t
dlerror: %s
\n
"
,
vim
->
err
);
}
vcc_ErrWhere
(
tl
,
mod
);
free
(
fnpx
);
FREE_OBJ
(
vim
);
vcc_vim_destroy
(
&
vim
);
return
;
}
vmd
=
vcc_VmodSanity
(
tl
,
vim
->
hdl
,
mod
,
fnpx
);
if
(
vmd
==
NULL
||
tl
->
err
)
{
AZ
(
dlclose
(
vim
->
hdl
));
free
(
fnpx
);
FREE_OBJ
(
vim
);
if
(
vcc_VmodLoad
(
tl
,
vim
,
vim
->
path
)
<
0
||
tl
->
err
)
{
vcc_ErrWhere
(
tl
,
vim
->
t_mod
);
vcc_vim_destroy
(
&
vim
);
return
;
}
CAST_OBJ
(
vimold
,
(
const
void
*
)(
msym
->
extra
),
VMOD_IMPORT_MAGIC
)
;
vimold
=
msym
->
import
;
if
(
vimold
!=
NULL
)
{
if
(
!
strcmp
(
vimold
->
vmd
->
file_id
,
vmd
->
file_id
))
{
CHECK_OBJ_NOTNULL
(
vimold
,
VMOD_IMPORT_MAGIC
);
if
(
!
strcmp
(
vimold
->
file_id
,
vim
->
file_id
))
{
/* Identical import is OK */
}
else
{
VSB_printf
(
tl
->
sb
,
...
...
@@ -464,9 +424,7 @@ vcc_ParseImport(struct vcc *tl)
PF
(
tmod
));
vcc_ErrWhere2
(
tl
,
t1
,
tl
->
t
);
}
AZ
(
dlclose
(
vim
->
hdl
));
free
(
fnpx
);
FREE_OBJ
(
vim
);
vcc_vim_destroy
(
&
vim
);
return
;
}
msym
->
def_b
=
t1
;
...
...
@@ -474,151 +432,26 @@ vcc_ParseImport(struct vcc *tl)
VTAILQ_FOREACH
(
vsym
,
&
tl
->
sym_vmods
,
sideways
)
{
assert
(
vsym
->
kind
==
SYM_VMOD
);
CAST_OBJ_NOTNULL
(
vimold
,
(
const
void
*
)(
vsym
->
extra
),
VMOD_IMPORT_MAGIC
);
if
(
!
strcmp
(
vimold
->
vmd
->
file_id
,
vmd
->
file_id
))
{
vimold
=
vsym
->
import
;
CHECK_OBJ_NOTNULL
(
vimold
,
VMOD_IMPORT_MAGIC
);
if
(
!
strcmp
(
vimold
->
file_id
,
vim
->
file_id
))
{
/* Already loaded under different name */
msym
->
eval_priv
=
vsym
->
eval_priv
;
msym
->
extra
=
vsym
->
extra
;
msym
->
import
=
vsym
->
import
;
msym
->
vmod_name
=
vsym
->
vmod_name
;
vcc_VmodSymbols
(
tl
,
msym
);
AZ
(
dlclose
(
vim
->
hdl
));
free
(
fnpx
);
FREE_OBJ
(
vim
);
// XXX: insert msym in sideways ?
vcc_vim_destroy
(
&
vim
);
return
;
}
}
VTAILQ_INSERT_TAIL
(
&
tl
->
sym_vmods
,
msym
,
sideways
);
ifp
=
New_IniFin
(
tl
);
VSB_cat
(
ifp
->
ini
,
"
\t
if (VPI_Vmod_Init(ctx,
\n
"
);
VSB_printf
(
ifp
->
ini
,
"
\t
&VGC_vmod_%.*s,
\n
"
,
PF
(
mod
));
VSB_printf
(
ifp
->
ini
,
"
\t
%u,
\n
"
,
tl
->
vmod_count
++
);
VSB_printf
(
ifp
->
ini
,
"
\t
&%s,
\n
"
,
vmd
->
func_name
);
VSB_printf
(
ifp
->
ini
,
"
\t
sizeof(%s),
\n
"
,
vmd
->
func_name
);
VSB_printf
(
ifp
->
ini
,
"
\t
\"
%.*s
\"
,
\n
"
,
PF
(
mod
));
VSB_cat
(
ifp
->
ini
,
"
\t
"
);
VSB_quote
(
ifp
->
ini
,
fnpx
,
-
1
,
VSB_QUOTE_CSTR
);
VSB_cat
(
ifp
->
ini
,
",
\n
"
);
AN
(
vmd
);
AN
(
vmd
->
file_id
);
VSB_printf
(
ifp
->
ini
,
"
\t
\"
%s
\"
,
\n
"
,
vmd
->
file_id
);
VSB_printf
(
ifp
->
ini
,
"
\t
\"
./vmod_cache/_vmod_%.*s.%s
\"\n
"
,
PF
(
mod
),
vmd
->
file_id
);
VSB_cat
(
ifp
->
ini
,
"
\t
))
\n
"
);
VSB_cat
(
ifp
->
ini
,
"
\t\t
return(1);"
);
VSB_cat
(
tl
->
symtab
,
",
\n
{
\n
"
);
VSB_cat
(
tl
->
symtab
,
"
\t\"
dir
\"
:
\"
import
\"
,
\n
"
);
VSB_cat
(
tl
->
symtab
,
"
\t\"
type
\"
:
\"
$VMOD
\"
,
\n
"
);
VSB_printf
(
tl
->
symtab
,
"
\t\"
name
\"
:
\"
%.*s
\"
,
\n
"
,
PF
(
mod
));
VSB_printf
(
tl
->
symtab
,
"
\t\"
file
\"
:
\"
%s
\"
,
\n
"
,
fnpx
);
VSB_printf
(
tl
->
symtab
,
"
\t\"
dst
\"
:
\"
./vmod_cache/_vmod_%.*s.%s
\"\n
"
,
PF
(
mod
),
vmd
->
file_id
);
VSB_cat
(
tl
->
symtab
,
" }"
);
/* XXX: zero the function pointer structure ?*/
VSB_printf
(
ifp
->
fin
,
"
\t\t
VRT_priv_fini(ctx, &vmod_priv_%.*s);"
,
PF
(
mod
));
VSB_printf
(
ifp
->
final
,
"
\t\t
VPI_Vmod_Unload(ctx, &VGC_vmod_%.*s);"
,
PF
(
mod
));
vj
=
vjsn_parse
(
vmd
->
json
,
&
p
);
XXXAZ
(
p
);
AN
(
vj
);
msym
->
eval_priv
=
vj
;
vim
->
vmd
=
vmd
;
msym
->
extra
=
(
const
char
*
)
vim
;
msym
->
vmod_name
=
TlDup
(
tl
,
vmd
->
name
);
msym
->
eval_priv
=
vim
->
vj
;
msym
->
import
=
vim
;
msym
->
vmod_name
=
TlDup
(
tl
,
vim
->
name
);
vcc_VmodSymbols
(
tl
,
msym
);
vcc_json_always
(
tl
,
vj
,
msym
->
vmod_name
);
Fh
(
tl
,
0
,
"
\n
/* --- BEGIN VMOD %.*s --- */
\n\n
"
,
PF
(
mod
));
Fh
(
tl
,
0
,
"static struct vmod *VGC_vmod_%.*s;
\n
"
,
PF
(
mod
));
Fh
(
tl
,
0
,
"static struct vmod_priv vmod_priv_%.*s;
\n
"
,
PF
(
mod
));
vcc_emit_c_prototypes
(
tl
,
vj
);
Fh
(
tl
,
0
,
"
\n
/* --- END VMOD %.*s --- */
\n\n
"
,
PF
(
mod
));
free
(
fnpx
);
}
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\t
if (%s)
\n
"
,
isym
->
rname
);
VSB_printf
(
ifp
->
fin
,
"
\t\t\t\t
%s(&%s);"
,
vf
->
value
,
isym
->
rname
);
vcc_emit_setup
(
tl
,
vim
);
}
lib/libvcc/vcc_vmod.h
0 → 100644
View file @
419fbade
/*-
* 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
);
lib/libvcc/vcc_vmod_sym.c
0 → 100644
View file @
419fbade
/*-
* 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\t
if (%s)
\n
"
,
isym
->
rname
);
VSB_printf
(
ifp
->
fin
,
"
\t\t\t\t
%s(&%s);"
,
vf
->
value
,
isym
->
rname
);
}
lib/libvcc/vmodtool.py
View file @
419fbade
...
...
@@ -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
())
...
...
vmod/vmod_debug.c
View file @
419fbade
...
...
@@ -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"
,
};
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment