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)
vcc_Var_Init(tl);
vcc_Type_Init(tl);
Fh(tl, 0, "\nextern const struct VCL_conf VCL_conf;\n");
/* Register and lex the main source */
......
......@@ -110,6 +110,8 @@ typedef const struct type *vcc_type_t;
* XXX: type methods might move in a more comprehensive direction.
*/
struct vcc_method {
unsigned magic;
#define VCC_METHOD_MAGIC 0x594108cd
vcc_type_t type;
const char *name;
const char *impl;
......@@ -423,6 +425,7 @@ void vcc_AddToken(struct vcc *tl, unsigned tok, const char *b,
/* vcc_types.c */
vcc_type_t VCC_Type(const char *p);
void vcc_Type_Init(struct vcc *tl);
/* vcc_var.c */
sym_wildcard_t vcc_Var_Wildcard;
......
......@@ -43,8 +43,9 @@ const struct type ACL[1] = {{
}};
static const struct vcc_method backend_methods[] = {
{ BACKEND, "resolve", "VRT_DirectorResolve(ctx, \v1)", 1 },
{ NULL },
{ VCC_METHOD_MAGIC, BACKEND, "resolve",
"VRT_DirectorResolve(ctx, \v1)", 1 },
{ VCC_METHOD_MAGIC, NULL },
};
const struct type BACKEND[1] = {{
......@@ -133,9 +134,9 @@ const struct type REAL[1] = {{
static const struct vcc_method stevedore_methods[] = {
#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"
{ NULL },
{ VCC_METHOD_MAGIC, NULL },
};
const struct type STEVEDORE[1] = {{
......@@ -159,9 +160,11 @@ const struct type STRANDS[1] = {{
}};
static const struct vcc_method strings_methods[] = {
{ STRING, "upper", "VRT_UpperLowerStrands(ctx, \vT, 1)", 1 },
{ STRING, "lower", "VRT_UpperLowerStrands(ctx, \vT, 0)", 1 },
{ NULL },
{ VCC_METHOD_MAGIC, STRING, "upper",
"VRT_UpperLowerStrands(ctx, \vT, 1)", 1 },
{ VCC_METHOD_MAGIC, STRING, "lower",
"VRT_UpperLowerStrands(ctx, \vT, 0)", 1 },
{ VCC_METHOD_MAGIC, NULL },
};
const struct type STRINGS[1] = {{
......@@ -207,3 +210,43 @@ VCC_Type(const char *p)
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)
/*---------------------------------------------------------------------*/
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)
vcc_instance_info(struct vcc *tl, const struct symbol *sym)
{
......@@ -393,6 +378,23 @@ VCC_InstanceInfo(struct vcc *tl)
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)
vcc_xreftable(struct vcc *tl, const struct symbol *sym)
{
......@@ -413,10 +415,13 @@ void
VCC_XrefTable(struct vcc *tl)
{
Fc(tl, 0, "\n/*\n * Symbol Table\n *\n");
VCC_WalkSymbols(tl, vcc_xreftable_len, SYM_MAIN, SYM_NONE);
VCC_WalkSymbols(tl, vcc_xreftable, SYM_MAIN, SYM_NONE);
#define VCC_NAMESPACE(U, l) \
Fc(tl, 0, "\n/*\n * Symbol Table " #U "\n *\n"); \
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");
#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