Commit a82916ea authored by Dridi Boukelmoune's avatar Dridi Boukelmoune

Register types and type methods as symbols

The SYM_METHOD kind of symbol was already present but never used so it
just found its purpose.

They appear in their dedicated symbol table:

    /*
     * Symbol Table MAIN
     *
     * reserved  VOID       41 41 acl
     * reserved  VOID       41 41 backend
     * [...]
     */

    /*
     * Symbol Table TYPE
     *
     * none      VOID     40 41 BACKEND
     * method    BACKEND  40 41 BACKEND.resolve
     * none      VOID     40 41 STEVEDORE
     * method    BYTES    40 41 STEVEDORE.free_space
     * method    BOOL     40 41 STEVEDORE.happy
     * method    BYTES    40 41 STEVEDORE.used_space
     * none      VOID     40 41 STRINGS
     * method    STRING   40 41 STRINGS.lower
     * method    STRING   40 41 STRINGS.upper
     */

Unlike VMOD functions or object methods, native type methods are never
invoked as a standalone statement:

    strings.upper();

They are only evaluated atop an expression:

    (string expression).upper();

So any VMOD named after a type, like vmod_blob, should not conflict with
native type methods in the symbol table. Unless a symbol already exists
in the MAIN namespace, like reserved keywords acl and backend.
parent 6c5d9ae0
...@@ -647,6 +647,8 @@ vcc_CompileSource(struct vcc *tl, struct source *sp, const char *jfile) ...@@ -647,6 +647,8 @@ vcc_CompileSource(struct vcc *tl, struct source *sp, const char *jfile)
vcc_Var_Init(tl); vcc_Var_Init(tl);
vcc_Type_Init(tl);
Fh(tl, 0, "\nextern const struct VCL_conf VCL_conf;\n"); Fh(tl, 0, "\nextern const struct VCL_conf VCL_conf;\n");
/* Register and lex the main source */ /* Register and lex the main source */
......
...@@ -110,6 +110,8 @@ typedef const struct type *vcc_type_t; ...@@ -110,6 +110,8 @@ typedef const struct type *vcc_type_t;
* XXX: type methods might move in a more comprehensive direction. * XXX: type methods might move in a more comprehensive direction.
*/ */
struct vcc_method { struct vcc_method {
unsigned magic;
#define VCC_METHOD_MAGIC 0x594108cd
vcc_type_t type; vcc_type_t type;
const char *name; const char *name;
const char *impl; const char *impl;
...@@ -423,6 +425,7 @@ void vcc_AddToken(struct vcc *tl, unsigned tok, const char *b, ...@@ -423,6 +425,7 @@ void vcc_AddToken(struct vcc *tl, unsigned tok, const char *b,
/* vcc_types.c */ /* vcc_types.c */
vcc_type_t VCC_Type(const char *p); vcc_type_t VCC_Type(const char *p);
void vcc_Type_Init(struct vcc *tl);
/* vcc_var.c */ /* vcc_var.c */
sym_wildcard_t vcc_Var_Wildcard; sym_wildcard_t vcc_Var_Wildcard;
......
...@@ -43,8 +43,9 @@ const struct type ACL[1] = {{ ...@@ -43,8 +43,9 @@ const struct type ACL[1] = {{
}}; }};
static const struct vcc_method backend_methods[] = { static const struct vcc_method backend_methods[] = {
{ BACKEND, "resolve", "VRT_DirectorResolve(ctx, \v1)", 1 }, { VCC_METHOD_MAGIC, BACKEND, "resolve",
{ NULL }, "VRT_DirectorResolve(ctx, \v1)", 1 },
{ VCC_METHOD_MAGIC, NULL },
}; };
const struct type BACKEND[1] = {{ const struct type BACKEND[1] = {{
...@@ -133,9 +134,9 @@ const struct type REAL[1] = {{ ...@@ -133,9 +134,9 @@ const struct type REAL[1] = {{
static const struct vcc_method stevedore_methods[] = { static const struct vcc_method stevedore_methods[] = {
#define VRTSTVVAR(nm, vtype, ctype, dval) \ #define VRTSTVVAR(nm, vtype, ctype, dval) \
{ vtype, #nm, "VRT_stevedore_" #nm "(\v1)", 0}, { VCC_METHOD_MAGIC, vtype, #nm, "VRT_stevedore_" #nm "(\v1)", 0},
#include "tbl/vrt_stv_var.h" #include "tbl/vrt_stv_var.h"
{ NULL }, { VCC_METHOD_MAGIC, NULL },
}; };
const struct type STEVEDORE[1] = {{ const struct type STEVEDORE[1] = {{
...@@ -159,9 +160,11 @@ const struct type STRANDS[1] = {{ ...@@ -159,9 +160,11 @@ const struct type STRANDS[1] = {{
}}; }};
static const struct vcc_method strings_methods[] = { static const struct vcc_method strings_methods[] = {
{ STRING, "upper", "VRT_UpperLowerStrands(ctx, \vT, 1)", 1 }, { VCC_METHOD_MAGIC, STRING, "upper",
{ STRING, "lower", "VRT_UpperLowerStrands(ctx, \vT, 0)", 1 }, "VRT_UpperLowerStrands(ctx, \vT, 1)", 1 },
{ NULL }, { VCC_METHOD_MAGIC, STRING, "lower",
"VRT_UpperLowerStrands(ctx, \vT, 0)", 1 },
{ VCC_METHOD_MAGIC, NULL },
}; };
const struct type STRINGS[1] = {{ const struct type STRINGS[1] = {{
...@@ -207,3 +210,43 @@ VCC_Type(const char *p) ...@@ -207,3 +210,43 @@ VCC_Type(const char *p)
return (NULL); return (NULL);
} }
static void
vcc_type_init(struct vcc *tl, vcc_type_t type)
{
const struct vcc_method *vm;
struct symbol *sym;
struct vsb *buf;
/* NB: Don't bother even creating a type symbol if there are no
* methods attached to it.
*/
if (type->methods == NULL)
return;
buf = VSB_new_auto();
AN(buf);
AN(VCC_MkSym(tl, type->name, SYM_TYPE, SYM_NONE, VCL_LOW, VCL_HIGH));
for (vm = type->methods; vm->type != NULL; vm++) {
VSB_printf(buf, "%s.%s", type->name, vm->name);
AZ(VSB_finish(buf));
sym = VCC_MkSym(tl, VSB_data(buf), SYM_TYPE, SYM_METHOD,
VCL_LOW, VCL_HIGH);
VSB_clear(buf);
if (tl->err)
break;
AN(sym);
sym->type = vm->type;
sym->eval_priv = vm;
}
VSB_destroy(&buf);
}
void
vcc_Type_Init(struct vcc *tl)
{
#define VCC_TYPE(UC, lc) vcc_type_init(tl, UC);
#include "tbl/vcc_types.h"
}
...@@ -358,21 +358,6 @@ vcc_CheckUses(struct vcc *tl) ...@@ -358,21 +358,6 @@ vcc_CheckUses(struct vcc *tl)
/*---------------------------------------------------------------------*/ /*---------------------------------------------------------------------*/
static int sym_type_len = 0;
static void v_matchproto_(symwalk_f)
vcc_xreftable_len(struct vcc *tl, const struct symbol *sym)
{
int len;
(void)tl;
CHECK_OBJ_NOTNULL(sym, SYMBOL_MAGIC);
CHECK_OBJ_NOTNULL(sym->type, TYPE_MAGIC);
len = strlen(sym->type->name);
if (sym_type_len < len)
sym_type_len = len;
}
static void v_matchproto_(symwalk_f) static void v_matchproto_(symwalk_f)
vcc_instance_info(struct vcc *tl, const struct symbol *sym) vcc_instance_info(struct vcc *tl, const struct symbol *sym)
{ {
...@@ -393,6 +378,23 @@ VCC_InstanceInfo(struct vcc *tl) ...@@ -393,6 +378,23 @@ VCC_InstanceInfo(struct vcc *tl)
Fc(tl, 0, "};\n"); Fc(tl, 0, "};\n");
} }
/*---------------------------------------------------------------------*/
static int sym_type_len;
static void v_matchproto_(symwalk_f)
vcc_xreftable_len(struct vcc *tl, const struct symbol *sym)
{
int len;
(void)tl;
CHECK_OBJ_NOTNULL(sym, SYMBOL_MAGIC);
CHECK_OBJ_NOTNULL(sym->type, TYPE_MAGIC);
len = strlen(sym->type->name);
if (sym_type_len < len)
sym_type_len = len;
}
static void v_matchproto_(symwalk_f) static void v_matchproto_(symwalk_f)
vcc_xreftable(struct vcc *tl, const struct symbol *sym) vcc_xreftable(struct vcc *tl, const struct symbol *sym)
{ {
...@@ -413,10 +415,13 @@ void ...@@ -413,10 +415,13 @@ void
VCC_XrefTable(struct vcc *tl) VCC_XrefTable(struct vcc *tl)
{ {
Fc(tl, 0, "\n/*\n * Symbol Table\n *\n"); #define VCC_NAMESPACE(U, l) \
VCC_WalkSymbols(tl, vcc_xreftable_len, SYM_MAIN, SYM_NONE); Fc(tl, 0, "\n/*\n * Symbol Table " #U "\n *\n"); \
VCC_WalkSymbols(tl, vcc_xreftable, SYM_MAIN, SYM_NONE); sym_type_len = 0; \
VCC_WalkSymbols(tl, vcc_xreftable_len, SYM_##U, SYM_NONE); \
VCC_WalkSymbols(tl, vcc_xreftable, SYM_##U, SYM_NONE); \
Fc(tl, 0, "*/\n\n"); Fc(tl, 0, "*/\n\n");
#include "vcc_namespace.h"
} }
/*--------------------------------------------------------------------- /*---------------------------------------------------------------------
......
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