1 /*-
2 * Copyright (c) 2010 Varnish Software AS
3 * All rights reserved.
4 *
5 * Author: Poul-Henning Kamp <phk@phk.freebsd.dk>
6 *
7 * SPDX-License-Identifier: BSD-2-Clause
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30 /*lint -save -esym(759, SYMTAB_NOERR) -esym(765, SYMTAB_NOERR)*/
31
32 #include "config.h"
33
34 #include <ctype.h>
35 #include <stdarg.h>
36 #include <stdlib.h>
37 #include <string.h>
38
39 #include "vcc_compile.h"
40
41 #include "vct.h"
42
43 /*--------------------------------------------------------------------*/
44
45 #define VCC_KIND(U,l) const struct kind SYM_##U[1] = {{ KIND_MAGIC, #l}};
46 #include "tbl/symbol_kind.h"
47
48 /*--------------------------------------------------------------------*/
49
50 struct vcc_namespace {
51 unsigned magic;
52 #define VCC_NAMESPACE_MAGIC 0x27b842f4
53 const char *name;
54 enum vcc_namespace_e id;
55 };
56
57 #define VCC_NAMESPACE(U, l) \
58 static const struct vcc_namespace sym_##l = { \
59 VCC_NAMESPACE_MAGIC, \
60 #l, \
61 VCC_NAMESPACE_##U \
62 }; \
63 vcc_ns_t SYM_##U = &sym_##l;
64 #include "vcc_namespace.h"
65
66 /*--------------------------------------------------------------------*/
67
68 struct symtab {
69 unsigned magic;
70 #define SYMTAB_MAGIC 0x084d9c8a
71 unsigned nlen;
72 const char *name;
73 const struct symtab *parent;
74 VTAILQ_ENTRY(symtab) list;
75 VTAILQ_HEAD(,symtab) children;
76 VTAILQ_HEAD(,symbol) symbols;
77 };
78
79 static vcc_kind_t
VCC_HandleKind(vcc_type_t fmt)80 VCC_HandleKind(vcc_type_t fmt)
81 {
82 if (fmt == ACL) return (SYM_ACL);
83 if (fmt == BACKEND) return (SYM_BACKEND);
84 if (fmt == PROBE) return (SYM_PROBE);
85 if (fmt == STEVEDORE) return (SYM_STEVEDORE);
86 if (fmt == SUB) return (SYM_SUB);
87 if (fmt == INSTANCE) return (SYM_INSTANCE);
88 return (SYM_NONE);
89 }
90
91 void
VCC_PrintCName(struct vsb * vsb,const char * b,const char * e)92 VCC_PrintCName(struct vsb *vsb, const char *b, const char *e)
93 {
94
95 AN(vsb);
96 AN(b);
97
98 if (e == NULL)
99 e = strchr(b, '\0');
100 assert(b < e);
101
102 for (; b < e; b++)
103 if (vct_isalnum(*b))
104 VSB_putc(vsb, *b);
105 else
106 VSB_printf(vsb, "_%02x_", *b);
107 }
108
109 static void
vcc_symtabname(struct vsb * vsb,const struct symtab * st)110 vcc_symtabname(struct vsb *vsb, const struct symtab *st)
111 {
112 if (st->parent != NULL && st->parent->parent != NULL) {
113 vcc_symtabname(vsb, st->parent);
114 VSB_putc(vsb, '.');
115 }
116 VSB_cat(vsb, st->name);
117 }
118
119 void
VCC_SymName(struct vsb * vsb,const struct symbol * sym)120 VCC_SymName(struct vsb *vsb, const struct symbol *sym)
121 {
122 AN(vsb);
123 CHECK_OBJ_NOTNULL(sym, SYMBOL_MAGIC);
124 CHECK_OBJ_NOTNULL(sym->symtab, SYMTAB_MAGIC);
125 vcc_symtabname(vsb, sym->symtab);
126 }
127
128 static char *
vcc_dup_be(const char * b,const char * e)129 vcc_dup_be(const char *b, const char *e)
130 {
131 char *p;
132
133 AN(b);
134 if (e == NULL)
135 e = strchr(b, '\0');
136 AN(e);
137 assert(e >= b);
138
139 p = strndup(b, e - b);
140 AN(p);
141 return (p);
142 }
143
144 static struct symtab *
vcc_symtab_new(const char * name)145 vcc_symtab_new(const char *name)
146 {
147 struct symtab *st;
148
149 ALLOC_OBJ(st, SYMTAB_MAGIC);
150 AN(st);
151 st->name = name;
152 st->nlen = strlen(st->name);
153 VTAILQ_INIT(&st->children);
154 VTAILQ_INIT(&st->symbols);
155 return (st);
156 }
157
158 static struct symtab *
vcc_symtab_str(struct symtab * st,const char * b,const char * e)159 vcc_symtab_str(struct symtab *st, const char *b, const char *e)
160 {
161 struct symtab *st2, *st3;
162 size_t l;
163 int i;
164 const char *q;
165
166 if (e == NULL)
167 e = strchr(b, '\0');
168
169 while (b < e) {
170 for (q = b; q < e && *q != '.'; q++)
171 continue;
172 AN(q);
173 l = q - b;
174 VTAILQ_FOREACH(st2, &st->children, list) {
175 i = strncasecmp(st2->name, b, l);
176 if (i < 0)
177 continue;
178 if (i == 0 && l == st2->nlen)
179 break;
180 st3 = vcc_symtab_new(vcc_dup_be(b, q));
181 st3->parent = st;
182 VTAILQ_INSERT_BEFORE(st2, st3, list);
183 st2 = st3;
184 break;
185 }
186 if (st2 == NULL) {
187 st2 = vcc_symtab_new(vcc_dup_be(b, q));
188 st2->parent = st;
189 VTAILQ_INSERT_TAIL(&st->children, st2, list);
190 }
191 st = st2;
192 b = q + 1;
193 }
194 return (st);
195 }
196
197 static struct symbol *
vcc_new_symbol(struct vcc * tl,struct symtab * st,vcc_kind_t kind,int vlo,int vhi)198 vcc_new_symbol(struct vcc *tl, struct symtab *st,
199 vcc_kind_t kind, int vlo, int vhi)
200 {
201 struct symbol *sym;
202
203 sym = TlAlloc(tl, sizeof *sym);
204 INIT_OBJ(sym, SYMBOL_MAGIC);
205 AN(sym);
206 sym->name = st->name;
207 sym->symtab = st;
208 sym->kind = kind;
209 sym->type = VOID;
210 sym->lorev = vlo;
211 sym->hirev = vhi;
212 VTAILQ_INSERT_TAIL(&st->symbols, sym, list);
213 return (sym);
214 }
215
216 static struct symbol *
vcc_sym_in_tab(struct vcc * tl,struct symtab * st,vcc_kind_t kind,int vlo,int vhi)217 vcc_sym_in_tab(struct vcc *tl, struct symtab *st,
218 vcc_kind_t kind, int vlo, int vhi)
219 {
220 const struct symtab *pst;
221 struct symbol *sym, *psym;
222
223 VTAILQ_FOREACH(sym, &st->symbols, list) {
224 if (sym->lorev > vhi || sym->hirev < vlo)
225 continue;
226 if ((kind == SYM_NONE && kind == sym->kind))
227 continue;
228 if (tl->syntax < VCL_41 && strcmp(sym->name, "default") &&
229 (kind != SYM_NONE && kind != sym->kind))
230 continue;
231 return (sym);
232 }
233 pst = st->parent;
234 if (pst == NULL)
235 return (sym);
236 psym = VTAILQ_FIRST(&pst->symbols);
237 if (psym == NULL)
238 return (sym);
239 if (psym->wildcard == NULL)
240 return (sym);
241
242 sym = vcc_new_symbol(tl, st, kind, vlo, vhi);
243 psym->wildcard(tl, psym, sym);
244 if (tl->err)
245 return (NULL);
246 return (sym);
247 }
248
249
250 const struct symxref XREF_NONE[1] = {{"xref_none"}};
251 const struct symxref XREF_DEF[1] = {{"xref_def"}};
252 const struct symxref XREF_REF[1] = {{"xref_ref"}};
253
254 const struct symmode SYMTAB_NOERR[1] = {{
255 .name = "sym_noerror",
256 .noerr = 1
257 }};
258 const struct symmode SYMTAB_CREATE[1] = {{
259 .name = "sym_create"
260 }};
261 const struct symmode SYMTAB_EXISTING[1] = {{
262 .name = "Symbol not found"
263 }};
264 const struct symmode SYMTAB_PARTIAL[1] = {{
265 .name = "Symbol not found",
266 .partial = 1
267 }};
268 const struct symmode SYMTAB_PARTIAL_NOERR[1] = {{
269 .name = "Symbol not found",
270 .partial = 1,
271 .noerr = 1
272 }};
273
274 struct symbol *
VCC_SymbolGet(struct vcc * tl,vcc_ns_t ns,vcc_kind_t kind,const struct symmode * e,const struct symxref * x)275 VCC_SymbolGet(struct vcc *tl, vcc_ns_t ns, vcc_kind_t kind,
276 const struct symmode *e, const struct symxref *x)
277 {
278 struct symtab *st, *st2 = NULL;
279 struct symbol *sym = NULL, *sym2 = NULL;
280 struct token *t0, *tn, *tn1, *tn2 = NULL;
281
282 AN(tl);
283 CHECK_OBJ_NOTNULL(ns, VCC_NAMESPACE_MAGIC);
284 AN(ns->name);
285 CHECK_OBJ_NOTNULL(kind, KIND_MAGIC);
286 AN(e);
287 AN(x);
288 AN(x->name);
289 if (tl->syntax >= VCL_41 && e == SYMTAB_CREATE && kind != SYM_SUB &&
290 (tl->t->b[0] == 'v'|| tl->t->b[0] == 'V') &&
291 (tl->t->b[1] == 'c'|| tl->t->b[1] == 'C') &&
292 (tl->t->b[2] == 'l'|| tl->t->b[2] == 'L') &&
293 (tl->t->b[3] == '_')) {
294 VSB_cat(tl->sb, "Symbols named 'vcl_*' are reserved.\nAt:");
295 vcc_ErrWhere(tl, tl->t);
296 return (NULL);
297 }
298
299 st = tl->syms[ns->id];
300 t0 = tl->t;
301 tn = tl->t;
302 while (1) {
303 st = vcc_symtab_str(st, tn->b, tn->e);
304 sym2 = vcc_sym_in_tab(tl, st, kind, tl->syntax, tl->syntax);
305 if (sym2 != NULL) {
306 sym = sym2;
307 st2 = st;
308 tn2 = tn;
309 }
310 tn1 = VTAILQ_NEXT(tn, list);
311 if (tn1->tok != '.')
312 break;
313 tn1 = VTAILQ_NEXT(tn1, list);
314 if (tn1->tok != ID)
315 break;
316 tn = tn1;
317 }
318 if (sym != NULL && sym->kind == SYM_VMOD && e->partial)
319 e = SYMTAB_EXISTING;
320 if (sym != NULL && e->partial) {
321 st = st2;
322 tn = tn2;
323 } else if (st != st2) {
324 sym = NULL;
325 }
326 if (sym == NULL && e->noerr)
327 return (sym);
328 AN(st);
329 AN(tn);
330 if (sym == NULL && e == SYMTAB_CREATE)
331 sym = vcc_new_symbol(tl, st, kind, tl->syntax, tl->syntax);
332 tl->t = VTAILQ_NEXT(tn, list);
333 if (sym == NULL) {
334 VSB_printf(tl->sb, "%s: '", e->name);
335 for (tn1 = t0; tn1 != tl->t; tn1 = VTAILQ_NEXT(tn1, list))
336 VSB_printf(tl->sb, "%.*s", PF(tn1));
337 VSB_cat(tl->sb, "'");
338 sym = vcc_sym_in_tab(tl, st, kind, VCL_LOW, VCL_HIGH);
339 if (sym != NULL && sym->kind != SYM_OBJECT &&
340 sym->kind != SYM_INSTANCE) { /* XXX: too specific */
341 VSB_cat(tl->sb, " (Only available when");
342 if (sym->lorev >= VCL_LOW)
343 VSB_printf(tl->sb, " %.1f <=", .1 * sym->lorev);
344 VSB_cat(tl->sb, " VCL syntax");
345 if (sym->hirev <= VCL_HIGH)
346 VSB_printf(tl->sb, " <= %.1f", .1 * sym->hirev);
347 VSB_cat(tl->sb, ")");
348 }
349 VSB_cat(tl->sb, "\nAt: ");
350 vcc_ErrWhere2(tl, t0, tl->t);
351 return (NULL);
352 }
353 if (kind != SYM_NONE && kind != sym->kind) {
354 VSB_cat(tl->sb, "Symbol '");
355 for (tn1 = t0; tn1 != tl->t; tn1 = VTAILQ_NEXT(tn1, list))
356 VSB_printf(tl->sb, "%.*s", PF(tn1));
357 VSB_printf(tl->sb, "' has wrong type (%s), expected %s:",
358 sym->kind->name, kind->name);
359 VSB_cat(tl->sb, "\nAt: ");
360 vcc_ErrWhere2(tl, t0, tl->t);
361 if (sym->def_b != NULL) {
362 VSB_cat(tl->sb, "Symbol was defined here: ");
363 vcc_ErrWhere(tl, sym->def_b);
364 } else if (sym->ref_b != NULL) {
365 VSB_cat(tl->sb, "Symbol was declared here: ");
366 vcc_ErrWhere(tl, sym->ref_b);
367 } else {
368 VSB_cat(tl->sb, "Symbol was builtin\n");
369 }
370 return (NULL);
371 }
372 if (x == XREF_DEF) {
373 if (sym->def_b == NULL)
374 sym->def_b = t0;
375 sym->ndef++;
376 } else if (x == XREF_REF) {
377 if (sym->ref_b == NULL)
378 sym->ref_b = t0;
379 sym->nref++;
380 } else {
381 assert (x == XREF_NONE);
382 }
383 return (sym);
384 }
385
386 static struct symbol *
vcc_TypeSymbol(struct vcc * tl,vcc_ns_t ns,vcc_kind_t kind,vcc_type_t type)387 vcc_TypeSymbol(struct vcc *tl, vcc_ns_t ns, vcc_kind_t kind, vcc_type_t type)
388 {
389 struct token t[1], *t0;
390 struct symbol *sym;
391 struct vsb *buf;
392
393 buf = VSB_new_auto();
394 AN(buf);
395 VSB_printf(buf, "%s.%.*s", type->name, PF(tl->t));
396 AZ(VSB_finish(buf));
397
398 /* NB: we create a fake token but errors are handled by the caller. */
399 memcpy(t, tl->t, sizeof *t);
400 t->b = VSB_data(buf);
401 t->e = t->b + VSB_len(buf);
402
403 t0 = tl->t;
404 tl->t = t;
405 sym = VCC_SymbolGet(tl, ns, kind, SYMTAB_NOERR, XREF_NONE);
406 tl->t = t0;
407 VSB_destroy(&buf);
408
409 return (sym);
410 }
411
412 struct symbol *
VCC_TypeSymbol(struct vcc * tl,vcc_kind_t kind,vcc_type_t type)413 VCC_TypeSymbol(struct vcc *tl, vcc_kind_t kind, vcc_type_t type)
414 {
415
416 if (strchr(type->name, '.') == NULL)
417 return (vcc_TypeSymbol(tl, SYM_TYPE, kind, type));
418
419 /* NB: type imported from a VMOD */
420 return (vcc_TypeSymbol(tl, SYM_MAIN, kind, type));
421 }
422
423 struct symbol *
VCC_MkSym(struct vcc * tl,const char * b,vcc_ns_t ns,vcc_kind_t kind,int vlo,int vhi)424 VCC_MkSym(struct vcc *tl, const char *b, vcc_ns_t ns, vcc_kind_t kind,
425 int vlo, int vhi)
426 {
427 struct symtab *st;
428 struct symbol *sym;
429
430 AN(tl);
431 AN(b);
432 CHECK_OBJ_NOTNULL(ns, VCC_NAMESPACE_MAGIC);
433 CHECK_OBJ_NOTNULL(kind, KIND_MAGIC);
434 assert(vlo <= vhi);
435
436 if (tl->syms[ns->id] == NULL)
437 tl->syms[ns->id] = vcc_symtab_new("");
438 st = vcc_symtab_str(tl->syms[ns->id], b, NULL);
439 AN(st);
440 sym = vcc_sym_in_tab(tl, st, kind, vlo, vhi);
441 AZ(sym);
442 sym = vcc_new_symbol(tl, st, kind, vlo, vhi);
443 AN(sym);
444 sym->noref = 1;
445 return (sym);
446 }
447
448 static void
vcc_walksymbols(struct vcc * tl,const struct symtab * root,symwalk_f * func,vcc_kind_t kind)449 vcc_walksymbols(struct vcc *tl, const struct symtab *root,
450 symwalk_f *func, vcc_kind_t kind)
451 {
452 struct symbol *sym;
453 struct symtab *st1, *st2 = NULL;
454
455 VTAILQ_FOREACH(sym, &root->symbols, list) {
456 if (kind == SYM_NONE || kind == sym->kind)
457 func(tl, sym);
458 ERRCHK(tl);
459 }
460 VTAILQ_FOREACH(st1, &root->children, list) {
461 if (st2 != NULL)
462 assert(strcasecmp(st1->name, st2->name) >= 0);
463 st2 = st1;
464 vcc_walksymbols(tl, st1, func, kind);
465 ERRCHK(tl);
466 }
467 }
468
469 void
VCC_WalkSymbols(struct vcc * tl,symwalk_f * func,vcc_ns_t ns,vcc_kind_t kind)470 VCC_WalkSymbols(struct vcc *tl, symwalk_f *func, vcc_ns_t ns, vcc_kind_t kind)
471 {
472
473 CHECK_OBJ_NOTNULL(ns, VCC_NAMESPACE_MAGIC);
474 vcc_walksymbols(tl, tl->syms[ns->id], func, kind);
475 }
476
477 void
VCC_GlobalSymbol(struct symbol * sym,vcc_type_t type,const char * pfx)478 VCC_GlobalSymbol(struct symbol *sym, vcc_type_t type, const char *pfx)
479 {
480 struct vsb *vsb;
481
482 CHECK_OBJ_NOTNULL(sym, SYMBOL_MAGIC);
483 AN(pfx);
484
485 vsb = VSB_new_auto();
486 AN(vsb);
487 VSB_printf(vsb, "%s_", pfx);
488 VCC_PrintCName(vsb, sym->name, NULL);
489 AZ(VSB_finish(vsb));
490 sym->lname = strdup(VSB_data(vsb));
491 AN(sym->lname);
492 if (type == SUB) {
493 VSB_destroy(&vsb);
494 vsb = VSB_new_auto();
495 AN(vsb);
496 VSB_printf(vsb, "sub_%s", sym->lname);
497 AZ(VSB_finish(vsb));
498 }
499 sym->rname = strdup(VSB_data(vsb));
500 AN(sym->rname);
501 VSB_destroy(&vsb);
502
503 sym->type = type;
504 sym->kind = VCC_HandleKind(sym->type);
505 if (sym->kind != SYM_NONE) {
506 AZ(VCT_invalid_name(sym->rname, NULL));
507 sym->eval = vcc_Eval_Handle;
508 } else {
509 WRONG("Wrong kind of global symbol");
510 }
511
512 #define VCL_MET_MAC(l,u,t,b) sym->r_methods |= VCL_MET_##u;
513 #include "tbl/vcl_returns.h"
514 }
515
516 struct symbol *
VCC_HandleSymbol(struct vcc * tl,vcc_type_t fmt,const char * pfx)517 VCC_HandleSymbol(struct vcc *tl, vcc_type_t fmt, const char *pfx)
518 {
519 struct symbol *sym;
520 vcc_kind_t kind;
521 struct token *t;
522 const char *p;
523
524 kind = VCC_HandleKind(fmt);
525 assert(kind != SYM_NONE);
526
527 t = tl->t;
528 sym = VCC_SymbolGet(tl, SYM_MAIN, SYM_NONE, SYMTAB_NOERR, XREF_NONE);
529 if (sym != NULL && sym->def_b != NULL && kind == sym->kind) {
530 p = sym->kind->name;
531 VSB_printf(tl->sb, "%c%s '%.*s' redefined.\n",
532 toupper(*p), p + 1, PF(t));
533 vcc_ErrWhere(tl, t);
534 VSB_cat(tl->sb, "First definition:\n");
535 AN(sym->def_b);
536 vcc_ErrWhere(tl, sym->def_b);
537 return (sym);
538 } else if (sym != NULL && sym->def_b != NULL) {
539 VSB_printf(tl->sb, "Name '%.*s' already defined.\n", PF(t));
540 vcc_ErrWhere(tl, t);
541 VSB_cat(tl->sb, "First definition:\n");
542 AN(sym->def_b);
543 vcc_ErrWhere(tl, sym->def_b);
544 return (sym);
545 } else if (sym != NULL && sym->kind != kind) {
546 VSB_printf(tl->sb,
547 "Name %.*s must have type '%s'.\n",
548 PF(t), sym->kind->name);
549 vcc_ErrWhere(tl, t);
550 return (sym);
551 }
552 if (sym == NULL)
553 sym = VCC_SymbolGet(tl, SYM_MAIN, kind, SYMTAB_CREATE,
554 XREF_NONE);
555 if (sym == NULL)
556 return (NULL);
557 AN(sym);
558 AZ(sym->ndef);
559 VCC_GlobalSymbol(sym, fmt, pfx);
560 sym->ndef = 1;
561 if (sym->def_b == NULL)
562 sym->def_b = t;
563 return (sym);
564 }
565 /*lint -restore */
566