[master] 2fb26ab7e Parse .method() expressions via the symbol table

Dridi Boukelmoune dridi.boukelmoune at gmail.com
Thu Jul 2 12:49:07 UTC 2020


commit 2fb26ab7ee2a842ecca584975ccebdf411abca95
Author: Dridi Boukelmoune <dridi.boukelmoune at gmail.com>
Date:   Fri Nov 29 07:43:08 2019 +0100

    Parse .method() expressions via the symbol table
    
    Technically the lookup is TYPE.METHOD so it's not as simple as calling
    VCC_SymbolGet() with the correct namespace.

diff --git a/lib/libvcc/vcc_compile.h b/lib/libvcc/vcc_compile.h
index 1a4cb44db..874c63c15 100644
--- a/lib/libvcc/vcc_compile.h
+++ b/lib/libvcc/vcc_compile.h
@@ -402,6 +402,8 @@ extern const struct symmode SYMTAB_PARTIAL[1];
 struct symbol *VCC_SymbolGet(struct vcc *, vcc_ns_t, vcc_kind_t,
     const struct symmode *, const struct symxref *);
 
+struct symbol *VCC_TypeSymbol(struct vcc *, vcc_kind_t, vcc_type_t);
+
 typedef void symwalk_f(struct vcc *tl, const struct symbol *s);
 void VCC_WalkSymbols(struct vcc *tl, symwalk_f *func, vcc_ns_t, vcc_kind_t);
 
diff --git a/lib/libvcc/vcc_expr.c b/lib/libvcc/vcc_expr.c
index 862dd6686..be0ee4aa3 100644
--- a/lib/libvcc/vcc_expr.c
+++ b/lib/libvcc/vcc_expr.c
@@ -823,6 +823,7 @@ static void
 vcc_expr4(struct vcc *tl, struct expr **e, vcc_type_t fmt)
 {
 	const struct vcc_method *vm;
+	const struct symbol *sym;
 
 	*e = NULL;
 	vcc_expr5(tl, e, fmt);
@@ -832,14 +833,8 @@ vcc_expr4(struct vcc *tl, struct expr **e, vcc_type_t fmt)
 		vcc_NextToken(tl);
 		ExpectErr(tl, ID);
 
-		vm = (*e)->fmt->methods;
-		while (vm != NULL && vm->type != NULL) {
-			if (vcc_IdIs(tl->t, vm->name))
-				break;
-			vm++;
-		}
-
-		if (vm == NULL || vm->type == NULL) {
+		sym = VCC_TypeSymbol(tl, SYM_METHOD, (*e)->fmt);
+		if (sym == NULL) {
 			VSB_cat(tl->sb, "Unknown property ");
 			vcc_ErrToken(tl, tl->t);
 			VSB_printf(tl->sb,
@@ -847,6 +842,8 @@ vcc_expr4(struct vcc *tl, struct expr **e, vcc_type_t fmt)
 			vcc_ErrWhere(tl, tl->t);
 			return;
 		}
+		CAST_OBJ_NOTNULL(vm, sym->eval_priv, VCC_METHOD_MAGIC);
+
 		vcc_NextToken(tl);
 		*e = vcc_expr_edit(tl, vm->type, vm->impl, *e, NULL);
 		ERRCHK(tl);
diff --git a/lib/libvcc/vcc_symb.c b/lib/libvcc/vcc_symb.c
index 93983c098..7630f4e14 100644
--- a/lib/libvcc/vcc_symb.c
+++ b/lib/libvcc/vcc_symb.c
@@ -364,6 +364,31 @@ VCC_SymbolGet(struct vcc *tl, vcc_ns_t ns, vcc_kind_t kind,
 	return (sym);
 }
 
+struct symbol *
+VCC_TypeSymbol(struct vcc *tl, vcc_kind_t kind, vcc_type_t type)
+{
+	struct token t[1], *t0;
+	struct symbol *sym;
+	struct vsb *buf;
+
+	buf = VSB_new_auto();
+	AN(buf);
+	VSB_printf(buf, "%s.%.*s", type->name, PF(tl->t));
+	AZ(VSB_finish(buf));
+
+	/* NB: we create a fake token but errors are handled by the caller. */
+	memcpy(t, tl->t, sizeof *t);
+	t->b = VSB_data(buf);
+	t->e = t->b + VSB_len(buf);
+
+	t0 = tl->t;
+	tl->t = t;
+	sym = VCC_SymbolGet(tl, SYM_TYPE, kind, SYMTAB_NOERR, XREF_NONE);
+	tl->t = t0;
+	VSB_destroy(&buf);
+	return (sym);
+}
+
 struct symbol *
 VCC_MkSym(struct vcc *tl, const char *b, vcc_ns_t ns, vcc_kind_t kind,
     int vlo, int vhi)


More information about the varnish-commit mailing list