varnish-cache/lib/libvcc/vcc_compile.c
0
/*-
1
 * Copyright (c) 2006 Verdens Gang AS
2
 * Copyright (c) 2006-2015 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
31
/*
32
 * XXX:
33
 *      Better error messages, throughout.
34
 *      >It also occurred to me that we could link the errors to the error
35
 *      >documentation.
36
 *      >
37
 *      >Unreferenced  function 'request_policy', first mention is
38
 *      >         Line 8 Pos 4
39
 *      >         sub request_policy {
40
 *      >         ----##############--
41
 *      >Read more about this type of error:
42
 *      >http://varnish/doc/error.html#Unreferenced%20function
43
 *      >
44
 *      >
45
 *      >         Unknown variable 'obj.bandwidth'
46
 *      >         At: Line 88 Pos 12
47
 *      >                 if (obj.bandwidth < 1 kb/h) {
48
 *      >         ------------#############------------
49
 *      >Read more about this type of error:
50
 *      >http://varnish/doc/error.html#Unknown%20variable
51
 *
52
 */
53
54
#include "config.h"
55
56
#include <fcntl.h>
57
#include <stdarg.h>
58
#include <stdlib.h>
59
#include <string.h>
60
#include <unistd.h>
61
62
#include "vcc_compile.h"
63
64
#include "libvcc.h"
65
#include "vfil.h"
66
#include "vct.h"
67
68
static const struct method method_tab[] = {
69
        { "none", 0U, 0},
70
#define VCL_MET_MAC(l,U,t,b)    { "vcl_"#l, b, VCL_MET_##U },
71
#include "tbl/vcl_returns.h"
72
        { NULL, 0U, 0}
73
};
74
75
struct vcc *vcc_builtin;
76
77
/*--------------------------------------------------------------------*/
78
79
static void
80 1776400
vcc_vcl_met2c(struct vsb *vsb, unsigned method)
81
{
82 1776400
        int d = 0;
83
84
        //lint -e{774} Boolean within 'if' always evaluates to False
85
#define VCL_MET_MAC(l,U,t,b)                            \
86
        do {                                            \
87
                if (method & VCL_MET_##U) {             \
88
                        if (d)                          \
89
                                VSB_putc(vsb, '|');     \
90
                        VSB_cat(vsb, "VCL_MET_" #U);    \
91
                        d = 1;                          \
92
                }                                       \
93
        } while (0);
94
#include "tbl/vcl_returns.h"
95 1776400
        AN(d);
96
}
97
98
99
/*--------------------------------------------------------------------*/
100
101
void * v_matchproto_(TlAlloc)
102 147451360
TlAlloc(struct vcc *tl, unsigned len)
103
{
104
        void *p;
105
106 147451360
        (void)tl;
107 147451360
        p = calloc(1, len);
108 147451360
        assert(p != NULL);
109 147451360
        return (p);
110
}
111
112 1776400
char *
113 7478600
TlDup(struct vcc *tl, const char *s)
114
{
115
        char *p;
116
117 7478600
        p = TlAlloc(tl, strlen(s) + 1);
118 7478600
        AN(p);
119 9255000
        strcpy(p, s);
120 7478600
        return (p);
121
}
122
123
static int
124 98560
TLWriteVSB(struct vcc *tl, const char *fn, const struct vsb *vsb,
125
    const char *what)
126 1776400
{
127
        int fo;
128
        int i;
129
130 98560
        fo = open(fn, O_WRONLY|O_TRUNC|O_CREAT, 0600);
131 98560
        if (fo < 0) {
132 0
                VSB_printf(tl->sb,
133
                    "Could not open %s file %s: %s\n",
134 0
                    what, fn, strerror(errno));
135 1776400
                return (-1);
136
        }
137 98560
        i = VSB_tofile(vsb, fo);
138 98560
        if (i) {
139 0
                VSB_printf(tl->sb,
140
                    "Could not write %s to %s: %s\n",
141 0
                    what, fn, strerror(errno));
142 1776400
        }
143 98560
        closefd(&fo);
144 98560
        return (i);
145 98560
}
146 1776400
147
/*--------------------------------------------------------------------*/
148
149
struct proc *
150 4186480
vcc_NewProc(struct vcc *tl, struct symbol *sym)
151 1776400
{
152
        struct proc *p;
153
154 4186480
        ALLOC_OBJ(p, PROC_MAGIC);
155 4186480
        AN(p);
156 4186480
        VTAILQ_INIT(&p->calls);
157 4186480
        VTAILQ_INIT(&p->uses);
158 4186480
        VTAILQ_INSERT_TAIL(&tl->procs, p, list);
159 5962880
        p->prologue = VSB_new_auto();
160 4186480
        AN(p->prologue);
161 4186480
        p->body = VSB_new_auto();
162 4186480
        AN(p->body);
163 4186480
        p->cname = VSB_new_auto();
164 5962880
        AN(p->cname);
165 4186480
        p->okmask = VCL_MET_TASK_ALL;
166 4186480
        sym->proc = p;
167 4186480
        p->sym = sym;
168 4186480
        return (p);
169
}
170
171
static void
172 3552800
vcc_EmitProc(struct vcc *tl, struct proc *p)
173
{
174
        struct vsb *vsbm;
175
        unsigned mask, nsub;
176
        const char *maskcmp;
177
        const char *cc_adv;
178 1776400
        int dyn = (p->sym->nref > p->called);
179 1776400
180 1776400
        AN(p->okmask);
181 1776400
        AZ(VSB_finish(p->cname));
182 1776400
        AZ(VSB_finish(p->prologue));
183 1776400
        AZ(VSB_finish(p->body));
184 1776400
        AN(p->sym);
185 1776400
186 1776400
        if (p->method) {
187 689920
                mask = p->method->bitval;
188 689920
                maskcmp = "==";
189 689920
        } else {
190 1086480
                mask = p->okmask;
191 2862880
                maskcmp = "&";
192
        }
193
194 1776400
        if (dyn == 0 && (p->calledfrom & VCL_MET_TASK_H) == p->calledfrom)
195 99040
                cc_adv = "v_dont_optimize ";
196
        else
197 1677360
                cc_adv = "";
198
199 1776400
        nsub = tl->nsub++;
200
201 1776400
        Fh(tl, 1, "vcl_func_f %s;\n", VSB_data(p->cname));
202 5329200
        Fh(tl, 1, "extern const struct vcl_sub sub_%s[1];\n",
203 1776400
            VSB_data(p->cname));
204 1776400
        Fh(tl, 1, "const struct vcl_sub sub_%s[1] = {{\n", VSB_data(p->cname));
205 1776400
        Fh(tl, 1, "\t.magic\t\t= VCL_SUB_MAGIC,\n");
206 1776400
        Fh(tl, 1, "\t.methods\t= 0x%x,\n", p->okmask);
207 1776400
        Fh(tl, 1, "\t.name\t\t= \"%.*s\",\n", PF(p->name));
208 1776400
        Fh(tl, 1, "\t.vcl_conf\t= &VCL_conf,\n");
209 1776400
        Fh(tl, 1, "\t.func\t\t= %s,\n", VSB_data(p->cname));
210 1776400
        Fh(tl, 1, "\t.n\t\t= %d,\n", nsub);
211 1776400
        Fh(tl, 1, "\t.nref\t\t= %d,\n", p->sym->nref);
212 1776400
        Fh(tl, 1, "\t.called\t\t= %d\n", p->called);
213 1776400
        Fh(tl, 1, "\t// calledfrom\t  0x%x\n", p->calledfrom);
214 1776400
        Fh(tl, 1, "}};\n");
215
216 1776400
        if (dyn) {
217 1200
                Fc(tl, 1, "\nstatic inline void %s\n", cc_adv);
218 1200
                Fc(tl, 1, "%s_checked(VRT_CTX)\n{\n", VSB_data(p->cname));
219 1200
        } else {
220 1775200
                Fc(tl, 1, "\nvoid %sv_matchproto_(vcl_func_f)\n", cc_adv);
221 3550400
                Fc(tl, 1, "%s(VRT_CTX, enum vcl_func_call_e call,\n",
222 1775200
                    VSB_data(p->cname));
223 1775200
                Fc(tl, 1, "    enum vcl_func_fail_e *failp)\n{\n");
224 1775200
                Fc(tl, 1, "  assert(call == VSUB_STATIC);\n");
225 1775200
                Fc(tl, 1, "  assert(failp == NULL);\n");
226
        }
227
228 1776400
        vsbm = VSB_new_auto();
229 1776400
        AN(vsbm);
230 1776400
        vcc_vcl_met2c(vsbm, mask);
231 1776400
        AZ(VSB_finish(vsbm));
232 1776400
        Fc(tl, 1, "  assert(ctx->method %s (%s));\n", maskcmp, VSB_data(vsbm));
233 1776400
        VSB_destroy(&vsbm);
234 1776400
        Fc(tl, 1, "%s\n%s}\n", VSB_data(p->prologue), VSB_data(p->body));
235 1776400
        VSB_destroy(&p->body);
236 1776400
        VSB_destroy(&p->prologue);
237
238 1776400
        if (! dyn) {
239 1775200
                VSB_destroy(&p->cname);
240 1775200
                return;
241
        }
242
243
        /* wrapper to call the actual (_checked) function */
244 1200
        Fc(tl, 1, "\nvoid v_matchproto_(vcl_func_f)\n");
245 2400
        Fc(tl, 1, "%s(VRT_CTX, enum vcl_func_call_e call,\n",
246 1200
            VSB_data(p->cname));
247 1200
        Fc(tl, 1, "    enum vcl_func_fail_e *failp)\n{\n");
248 1200
        Fc(tl, 1, "  enum vcl_func_fail_e fail;\n\n");
249 2400
        Fc(tl, 1, "  fail = VPI_Call_Check(ctx, &VCL_conf, 0x%x, %d);\n",
250 1200
            mask, nsub);
251 1200
        Fc(tl, 1, "  if (failp)\n");
252 1200
        Fc(tl, 1, "    *failp = fail;\n");
253 1200
        Fc(tl, 1, "  else if (fail == VSUB_E_METHOD)\n");
254 2400
        Fc(tl, 1, "    VRT_fail(ctx, \"call to \\\"sub %.*s{}\\\""
255 1200
            " not allowed from here\");\n", PF(p->name));
256 1200
        Fc(tl, 1, "  else if (fail == VSUB_E_RECURSE)\n");
257 2400
        Fc(tl, 1, "    VRT_fail(ctx, \"Recursive call to "
258 1200
            "\\\"sub %.*s{}\\\"\");\n", PF(p->name));
259 1200
        Fc(tl, 1, "  else\n");
260 1200
        Fc(tl, 1, "    assert (fail == VSUB_E_OK);\n");
261 1200
        Fc(tl, 1, "  if (fail != VSUB_E_OK || call == VSUB_CHECK)\n");
262 1200
        Fc(tl, 1, "    return;\n");
263 1200
        Fc(tl, 1, "  VPI_Call_Begin(ctx, %d);\n", nsub);
264 1200
        Fc(tl, 1, "  %s_checked(ctx);\n", VSB_data(p->cname));
265 1200
        Fc(tl, 1, "  VPI_Call_End(ctx, %d);\n", nsub);
266 1200
        Fc(tl, 1, "}\n");
267 1200
        VSB_destroy(&p->cname);
268 1776400
}
269
270
/*--------------------------------------------------------------------*/
271
272
struct inifin *
273 616840
New_IniFin(struct vcc *tl)
274
{
275
        struct inifin *p;
276
277 616840
        ALLOC_OBJ(p, INIFIN_MAGIC);
278 616840
        AN(p);
279 616840
        p->ini = VSB_new_auto();
280 616840
        AN(p->ini);
281 616840
        p->fin = VSB_new_auto();
282 616840
        AN(p->fin);
283 616840
        p->final = VSB_new_auto();
284 616840
        AN(p->final);
285 616840
        p->event = VSB_new_auto();
286 616840
        AN(p->event);
287 616840
        p->n = ++tl->ninifin;
288 616840
        VTAILQ_INSERT_TAIL(&tl->inifin, p, list);
289 616840
        return (p);
290
}
291
292
/*--------------------------------------------------------------------
293
 * Printf output to the vsbs, possibly indented
294
 */
295
296
void
297 32223680
Fh(const struct vcc *tl, int indent, const char *fmt, ...)
298
{
299
        va_list ap;
300
301 32223680
        if (indent)
302 23142640
                VSB_printf(tl->fh, "%*.*s", tl->hindent, tl->hindent, "");
303 32223680
        va_start(ap, fmt);
304 32223680
        VSB_vprintf(tl->fh, fmt, ap);
305 32223680
        va_end(ap);
306 32223680
}
307
308
void
309 80610920
Fb(const struct vcc *tl, int indent, const char *fmt, ...)
310
{
311
        va_list ap;
312
313 80610920
        assert(tl->fb != NULL);
314 80610920
        if (indent)
315 70768520
                VSB_printf(tl->fb, "%*.*s", tl->indent, tl->indent, "");
316 80610920
        va_start(ap, fmt);
317 80610920
        VSB_vprintf(tl->fb, fmt, ap);
318 80610920
        va_end(ap);
319 80610920
}
320
321
void
322 67151720
Fc(const struct vcc *tl, int indent, const char *fmt, ...)
323
{
324
        va_list ap;
325
326 67151720
        if (indent)
327 12454000
                VSB_printf(tl->fc, "%*.*s", tl->indent, tl->indent, "");
328 67151720
        va_start(ap, fmt);
329 67151720
        VSB_vprintf(tl->fc, fmt, ap);
330 67151720
        va_end(ap);
331 67151720
}
332
333
/*--------------------------------------------------------------------*/
334
335
void
336 3854520
EncToken(struct vsb *sb, const struct token *t)
337
{
338
339 3854520
        assert(t->tok == CSTR);
340 3854520
        VSB_quote(sb, t->dec, -1, VSB_QUOTE_CSTR);
341 3854520
}
342
343
/*--------------------------------------------------------------------
344
 * Output the location/profiling table.  For each counted token, we
345
 * record source+line+charpos for the first character in the token.
346
 */
347
348
static void
349 49280
EmitCoordinates(const struct vcc *tl, struct vsb *vsb)
350
{
351
        struct token *t;
352
        unsigned lin, pos;
353
        const struct source *sp;
354
        const char *p;
355
356 49280
        VSB_cat(vsb, "/* ---===### Source Code ###===---*/\n");
357
358 49280
        VSB_printf(vsb, "\n#define VGC_NSRCS %u\n", tl->nsources);
359
360 49280
        VSB_cat(vsb, "\nstatic const char *srcname[VGC_NSRCS] = {\n");
361 149080
        VTAILQ_FOREACH(sp, &tl->sources, list) {
362 99800
                VSB_cat(vsb, "\t");
363 99800
                VSB_quote(vsb, sp->name, -1, VSB_QUOTE_CSTR);
364 99800
                VSB_cat(vsb, ",\n");
365 99800
        }
366 49280
        VSB_cat(vsb, "};\n");
367
368 49280
        VSB_printf(vsb, "\nstatic const char *srcbody[%u] = {\n", tl->nsources);
369 149080
        VTAILQ_FOREACH(sp, &tl->sources, list) {
370 99800
                VSB_cat(vsb, "    /* ");
371 99800
                VSB_quote(vsb, sp->name, -1, VSB_QUOTE_CSTR);
372 99800
                VSB_cat(vsb, " */\n");
373 99800
                VSB_quote_pfx(vsb, "\t", sp->b, sp->e - sp->b, VSB_QUOTE_CSTR);
374 99800
                VSB_cat(vsb, ",\n");
375 99800
        }
376 49280
        VSB_cat(vsb, "};\n\n");
377
378 49280
        VSB_cat(vsb, "/* ---===### Location Counters ###===---*/\n");
379
380 49280
        VSB_printf(vsb, "\n#define VGC_NREFS %u\n\n", tl->cnt + 1);
381
382 49280
        VSB_cat(vsb, "static const struct vpi_ref VGC_ref[VGC_NREFS] = {\n");
383 49280
        lin = 1;
384 49280
        pos = 0;
385 49280
        sp = 0;
386 49280
        p = NULL;
387 42058080
        VTAILQ_FOREACH(t, &tl->tokens, list) {
388 42008800
                if (t->cnt == 0)
389 38635840
                        continue;
390 3372960
                assert(t->src != NULL);
391 3372960
                if (t->src != sp) {
392 83440
                        lin = 1;
393 83440
                        pos = 0;
394 83440
                        sp = t->src;
395 83440
                        p = sp->b;
396 83440
                }
397 3372960
                assert(sp != NULL);
398 3372960
                assert(p != NULL);
399 331868446
                for (;p < t->b; p++) {
400 328495486
                        if (*p == '\n') {
401 14998760
                                lin++;
402 14998760
                                pos = 0;
403 328495486
                        } else if (*p == '\t') {
404 7473160
                                pos &= ~7;
405 7473160
                                pos += 8;
406 7473160
                        } else
407 306023566
                                pos++;
408
409 328495486
                }
410 6745920
                VSB_printf(vsb, "  [%3u] = { VPI_REF_MAGIC, %u, %8tu, %4u, %3u, ",
411 3372960
                    t->cnt, sp->idx, t->b - sp->b, lin, pos + 1);
412 3372960
                if (t->tok == CSRC)
413 280
                        VSB_cat(vsb, " \"C{\"},\n");
414
                else
415 3372680
                        VSB_printf(vsb, " \"%.*s\" },\n", PF(t));
416 3372960
        }
417 49280
        VSB_cat(vsb, "};\n\n");
418 49280
}
419
420
/*--------------------------------------------------------------------
421
 * Init/Fini/Event
422
 *
423
 * We call DISCARD and COLD events in the opposite order of LOAD and
424
 * WARM.
425
 */
426
427
static void
428 49280
EmitInitFini(const struct vcc *tl)
429
{
430 49280
        struct inifin *p, *q = NULL;
431 49280
        unsigned has_event = 0;
432
        struct symbol *sy;
433
434 49280
        Fh(tl, 0, "\n");
435 49280
        Fh(tl, 0, "static unsigned vgc_inistep;\n");
436 49280
        Fh(tl, 0, "static unsigned vgc_warmupstep;\n");
437
438
        /*
439
         * LOAD
440
         */
441 49280
        Fc(tl, 0, "\nstatic int\nVGC_Load(VRT_CTX)\n{\n\n");
442 49280
        Fc(tl, 0, "\tvgc_inistep = 0;\n");
443 49280
        Fc(tl, 0, "\tsize_t ndirector = %dUL;\n", tl->ndirector);
444 49280
        Fc(tl, 0, "\n");
445 394600
        VTAILQ_FOREACH(p, &tl->inifin, list) {
446 345320
                AZ(VSB_finish(p->ini));
447 345320
                assert(p->n > 0);
448 345320
                if (VSB_len(p->ini))
449 336680
                        Fc(tl, 0, "\t/* %u */\n%s\n", p->n, VSB_data(p->ini));
450 345320
                if (p->ignore_errors == 0) {
451 296040
                        Fc(tl, 0, "\tif (ctx->vpi->handling == VCL_RET_FAIL)\n");
452 296040
                        Fc(tl, 0, "\t\treturn(1);\n");
453 296040
                }
454 345320
                Fc(tl, 0, "\tvgc_inistep = %u;\n\n", p->n);
455 345320
                VSB_destroy(&p->ini);
456
457 345320
                AZ(VSB_finish(p->event));
458 345320
                if (VSB_len(p->event))
459 4240
                        has_event = 1;
460 345320
        }
461
462
        /* Handle failures from vcl_init */
463 49280
        Fc(tl, 0, "\n");
464 49280
        Fc(tl, 0, "\tif (ctx->vpi->handling != VCL_RET_OK)\n");
465 49280
        Fc(tl, 0, "\t\treturn(1);\n");
466 49280
        Fc(tl, 0, "\tctx->vpi->handling = 0;\n");
467
468 56880
        VTAILQ_FOREACH(sy, &tl->sym_objects, sideways) {
469 7600
                Fc(tl, 0, "\tif (!%s) {\n", sy->rname);
470 15200
                Fc(tl, 0, "\t\tVRT_fail(ctx, "
471 7600
                    "\"Object %s not initialized\");\n" , sy->name);
472 7600
                Fc(tl, 0, "\t\treturn(1);\n");
473 7600
                Fc(tl, 0, "\t}\n");
474 7600
        }
475
476 49280
        Fc(tl, 0, "\treturn(0);\n");
477 49280
        Fc(tl, 0, "}\n");
478
479
        /*
480
         * DISCARD
481
         */
482 49280
        Fc(tl, 0, "\nstatic int\nVGC_Discard(VRT_CTX)\n{\n\n");
483
484 49280
        Fc(tl, 0, "\tswitch (vgc_inistep) {\n");
485 394600
        VTAILQ_FOREACH_REVERSE(p, &tl->inifin, inifinhead, list) {
486 345320
                AZ(VSB_finish(p->fin));
487 345320
                if (q)
488 296040
                        assert(q->n > p->n);
489 345320
                q = p;
490 345320
                Fc(tl, 0, "\t\tcase %u:\n", p->n);
491 345320
                if (VSB_len(p->fin))
492 345240
                        Fc(tl, 0, "\t%s\n", VSB_data(p->fin));
493 345320
                Fc(tl, 0, "\t\t\t/* FALLTHROUGH */\n");
494 345320
                VSB_destroy(&p->fin);
495 345320
        }
496 49280
        Fc(tl, 0, "\t\tdefault:\n\t\t\tbreak;\n");
497 49280
        Fc(tl, 0, "\t}\n\n");
498 49280
        Fc(tl, 0, "\tswitch (vgc_inistep) {\n");
499 394600
        VTAILQ_FOREACH_REVERSE(p, &tl->inifin, inifinhead, list) {
500 345320
                AZ(VSB_finish(p->final));
501 345320
                Fc(tl, 0, "\t\tcase %u:\n", p->n);
502 345320
                if (VSB_len(p->final))
503 20080
                        Fc(tl, 0, "\t%s\n", VSB_data(p->final));
504 345320
                Fc(tl, 0, "\t\t\t/* FALLTHROUGH */\n");
505 345320
                VSB_destroy(&p->final);
506 345320
        }
507 49280
        Fc(tl, 0, "\t\tdefault:\n\t\t\tbreak;\n");
508 49280
        Fc(tl, 0, "\t}\n\n");
509
510 49280
        Fc(tl, 0, "\treturn (0);\n");
511 49280
        Fc(tl, 0, "}\n");
512
513 49280
        if (has_event) {
514
                /*
515
                 * WARM
516
                 */
517 4240
                Fc(tl, 0, "\nstatic int\n");
518 4240
                Fc(tl, 0, "VGC_Warmup(VRT_CTX, enum vcl_event_e ev)\n{\n\n");
519
520 4240
                Fc(tl, 0, "\tvgc_warmupstep = 0;\n\n");
521 43000
                VTAILQ_FOREACH(p, &tl->inifin, list) {
522 38760
                        assert(p->n > 0);
523 38760
                        if (VSB_len(p->event)) {
524 4240
                                Fc(tl, 0, "\t/* %u */\n", p->n);
525 4240
                                Fc(tl, 0, "\tif (%s)\n", VSB_data(p->event));
526 4240
                                Fc(tl, 0, "\t\treturn (1);\n");
527 4240
                                Fc(tl, 0, "\tvgc_warmupstep = %u;\n\n", p->n);
528 4240
                        }
529 38760
                }
530
531 4240
                Fc(tl, 0, "\treturn (0);\n");
532 4240
                Fc(tl, 0, "}\n");
533
534
                /*
535
                 * COLD
536
                 */
537 4240
                Fc(tl, 0, "\nstatic int\n");
538 4240
                Fc(tl, 0, "VGC_Cooldown(VRT_CTX, enum vcl_event_e ev)\n{\n");
539 4240
                Fc(tl, 0, "\tint retval = 0;\n\n");
540
541 43000
                VTAILQ_FOREACH_REVERSE(p, &tl->inifin, inifinhead, list) {
542 38760
                        if (VSB_len(p->event)) {
543 4240
                                Fc(tl, 0, "\t/* %u */\n", p->n);
544 8480
                                Fc(tl, 0,
545 4240
                                    "\tif (vgc_warmupstep >= %u &&\n", p->n);
546 8480
                                Fc(tl, 0,
547 4240
                                    "\t    %s != 0)\n", VSB_data(p->event));
548 4240
                                Fc(tl, 0, "\t\tretval = 1;\n\n");
549 4240
                        }
550 38760
                        VSB_destroy(&p->event);
551 38760
                }
552
553 4240
                Fc(tl, 0, "\treturn (retval);\n");
554 4240
                Fc(tl, 0, "}\n");
555 4240
        }
556
557
        /*
558
         * EVENTS
559
         */
560 49280
        Fc(tl, 0, "\nstatic int\n");
561 49280
        Fc(tl, 0, "VGC_Event(VRT_CTX, enum vcl_event_e ev)\n");
562 49280
        Fc(tl, 0, "{\n");
563 49280
        Fc(tl, 0, "\tif (ev == VCL_EVENT_LOAD)\n");
564 49280
        Fc(tl, 0, "\t\treturn (VGC_Load(ctx));\n");
565 49280
        if (has_event) {
566 4240
                Fc(tl, 0, "\tif (ev == VCL_EVENT_WARM)\n");
567 4240
                Fc(tl, 0, "\t\treturn (VGC_Warmup(ctx, ev));\n");
568 4240
                Fc(tl, 0, "\tif (ev == VCL_EVENT_COLD)\n");
569 4240
                Fc(tl, 0, "\t\treturn (VGC_Cooldown(ctx, ev));\n");
570 4240
        }
571 49280
        Fc(tl, 0, "\tif (ev == VCL_EVENT_DISCARD)\n");
572 49280
        Fc(tl, 0, "\t\treturn (VGC_Discard(ctx));\n");
573 49280
        Fc(tl, 0, "\n");
574 49280
        if (!has_event)
575 45040
                Fc(tl, 0, "\t(void)vgc_warmupstep;\n");
576 49280
        Fc(tl, 0, "\treturn (%d);\n", has_event ? 1 : 0);
577 49280
        Fc(tl, 0, "}\n");
578 49280
}
579
580
/*--------------------------------------------------------------------*/
581
582
static void
583 49280
EmitStruct(const struct vcc *tl)
584
{
585 49280
        Fc(tl, 0, "\nconst struct VCL_conf VCL_conf = {\n");
586 49280
        Fc(tl, 0, "\t.magic = VCL_CONF_MAGIC,\n");
587 49280
        Fc(tl, 0, "\t.syntax = %u,\n", tl->syntax);
588 49280
        Fc(tl, 0, "\t.event_vcl = VGC_Event,\n");
589 49280
        Fc(tl, 0, "\t.default_director = &%s,\n", tl->default_director);
590 49280
        if (tl->default_probe != NULL)
591 400
                Fc(tl, 0, "\t.default_probe = %s,\n", tl->default_probe);
592 49280
        Fc(tl, 0, "\t.ref = VGC_ref,\n");
593 49280
        Fc(tl, 0, "\t.nref = VGC_NREFS,\n");
594 49280
        Fc(tl, 0, "\t.nsrc = VGC_NSRCS,\n");
595 49280
        Fc(tl, 0, "\t.nsub = %d,\n", tl->subref > 0 ? tl->nsub : 0);
596 49280
        Fc(tl, 0, "\t.srcname = srcname,\n");
597 49280
        Fc(tl, 0, "\t.srcbody = srcbody,\n");
598 49280
        Fc(tl, 0, "\t.nvmod = %u,\n", tl->vmod_count);
599
#define VCL_MET_MAC(l,u,t,b) \
600
        Fc(tl, 0, "\t." #l "_func = VGC_function_vcl_" #l ",\n");
601
#include "tbl/vcl_returns.h"
602
        Fc(tl, 0, "\t.instance_info = VGC_instance_info\n");
603
        Fc(tl, 0, "};\n");
604
}
605
606
/*--------------------------------------------------------------------
607
 * Compile the VCL code from the given source and return the C-source
608
 */
609
610
static struct vsb *
611 121960
vcc_CompileSource(struct vcc *tl, struct source *sp, const char *jfile)
612
{
613
        struct proc *p;
614
        struct vsb *vsb;
615
        struct inifin *ifp;
616
617 121960
        Fh(tl, 0, "/* ---===### VCC generated .h code ###===---*/\n");
618 121960
        Fc(tl, 0, "\n/* ---===### VCC generated .c code ###===---*/\n");
619
620 121960
        Fc(tl, 0, "\n#define END_ if (ctx->vpi->handling) return\n");
621
622 121960
        vcc_Parse_Init(tl);
623
624 121960
        vcc_Expr_Init(tl);
625
626 121960
        vcc_Action_Init(tl);
627
628 121960
        vcc_Backend_Init(tl);
629
630 121960
        vcc_Var_Init(tl);
631
632 121960
        vcc_Type_Init(tl);
633
634 121960
        Fh(tl, 0, "\nextern const struct VCL_conf VCL_conf;\n");
635
636
        /* Register and lex the main source */
637 121960
        if (sp != NULL) {
638 60960
                AN(vcc_builtin);
639 60960
                vcc_lex_source(tl, sp, 0);
640 60960
                if (tl->err)
641 1320
                        return (NULL);
642 59640
        }
643
644
        /* Register and lex the builtin VCL */
645 120640
        sp = vcc_new_source(tl->builtin_vcl, "builtin", "<builtin>");
646 120640
        assert(sp != NULL);
647 120640
        vcc_lex_source(tl, sp, 1);
648 120640
        if (tl->err)
649 0
                return (NULL);
650
651
        /* Expand and lex any includes in the token string */
652 120640
        if (tl->err)
653 0
                return (NULL);
654
655
        /* Parse the token string */
656 120640
        tl->t = VTAILQ_FIRST(&tl->tokens);
657 120640
        vcc_Parse(tl);
658 120640
        if (tl->err)
659 8120
                return (NULL);
660
661
        /* Check for orphans */
662 112520
        if (vcc_CheckReferences(tl))
663 360
                return (NULL);
664
665
        /* Check that all action returns are legal */
666 112160
        if (vcc_CheckAction(tl) || tl->err)
667 120
                return (NULL);
668
669
        /* Check that all variable uses are legal */
670 112040
        if (vcc_CheckUses(tl) || tl->err)
671 1680
                return (NULL);
672
673 110360
        if (vcc_builtin == NULL)
674 61000
                return (NULL);
675
676
        /* Check if we have any backends at all */
677 49360
        if (tl->default_director == NULL) {
678 80
                VSB_cat(tl->sb,
679
                    "No backends or directors found in VCL program, "
680
                    "at least one is necessary.\n");
681 80
                tl->err = 1;
682 80
                return (NULL);
683
        }
684
685
        /* Tie vcl_init/fini in */
686 49280
        ifp = New_IniFin(tl);
687 49280
        VSB_cat(ifp->ini, "\tVGC_function_vcl_init(ctx, VSUB_STATIC, NULL);\n");
688
        /*
689
         * Because the failure could be half way into vcl_init{} so vcl_fini{}
690
         * must always be called, also on failure.
691
         */
692 49280
        ifp->ignore_errors = 1;
693 49280
        VSB_cat(ifp->fin, "\t\tVGC_function_vcl_fini(ctx, VSUB_STATIC, NULL);\n");
694 49280
        VSB_cat(ifp->fin, "\t\t\tVPI_vcl_fini(ctx);");
695
696
        /* Emit method functions */
697 49280
        Fh(tl, 1, "\n");
698 1825680
        VTAILQ_FOREACH(p, &tl->procs, list)
699 2862880
                if (p->method == NULL)
700 1086480
                        vcc_EmitProc(tl, p);
701 1825680
        VTAILQ_FOREACH(p, &tl->procs, list)
702 2466320
                if (p->method != NULL)
703 689920
                        vcc_EmitProc(tl, p);
704
705 49280
        EmitInitFini(tl);
706
707 49280
        VCC_InstanceInfo(tl);
708
709 49280
        EmitStruct(tl);
710
711 49280
        VCC_XrefTable(tl);
712
713 49280
        VSB_cat(tl->symtab, "\n]\n");
714 49280
        AZ(VSB_finish(tl->symtab));
715 49280
        if (TLWriteVSB(tl, jfile, tl->symtab, "Symbol table"))
716 0
                return (NULL);
717
718
        /* Combine it all */
719
720 49280
        vsb = VSB_new_auto();
721 49280
        AN(vsb);
722
723 49280
        vcl_output_lang_h(vsb);
724
725 49280
        EmitCoordinates(tl, vsb);
726
727 49280
        AZ(VSB_finish(tl->fh));
728 49280
        VSB_cat(vsb, VSB_data(tl->fh));
729
730 49280
        AZ(VSB_finish(tl->fc));
731 49280
        VSB_cat(vsb, VSB_data(tl->fc));
732
733 49280
        AZ(VSB_finish(vsb));
734 49280
        return (vsb);
735 121960
}
736
737
static struct vcc *
738 61000
vcc_ParseBuiltin(struct vcc *tl)
739
{
740
        struct vcc *tl_builtin;
741
742 61000
        CHECK_OBJ_NOTNULL(tl, VCC_MAGIC);
743 61000
        tl_builtin = VCC_New();
744 61000
        AN(tl_builtin);
745 61000
        VCC_Builtin_VCL(tl_builtin, tl->builtin_vcl);
746 61000
        AZ(vcc_CompileSource(tl_builtin, NULL, NULL));
747 61000
        return (tl_builtin);
748
}
749
750
/*--------------------------------------------------------------------
751
 * Report the range of VCL language we support
752
 */
753
void
754 41520
VCC_VCL_Range(unsigned *lo, unsigned *hi)
755
{
756
757 41520
        AN(lo);
758 41520
        *lo = VCL_LOW;
759 41520
        AN(hi);
760 41520
        *hi = VCL_HIGH;
761 41520
}
762
763
/*--------------------------------------------------------------------
764
 * Compile the VCL code in the argument.  Error messages, if any are
765
 * formatted into the vsb.
766
 */
767
768
int
769 61000
VCC_Compile(struct vcc *tl, struct vsb **sb,
770
    const char *vclsrc, const char *vclsrcfile,
771
    const char *ofile, const char *jfile)
772
{
773
        struct source *sp;
774 61000
        struct vsb *r = NULL;
775 61000
        int retval = 0;
776
777 61000
        CHECK_OBJ_NOTNULL(tl, VCC_MAGIC);
778 61000
        AN(sb);
779 61000
        AN(vclsrcfile);
780 61000
        AN(ofile);
781 61000
        AN(jfile);
782
783 61000
        AZ(vcc_builtin);
784 61000
        vcc_builtin = vcc_ParseBuiltin(tl);
785 61000
        AN(vcc_builtin);
786 61000
        if (vcc_builtin->err) {
787 0
                AZ(VSB_finish(vcc_builtin->sb));
788 0
                *sb = vcc_builtin->sb;
789 0
                return (-1);
790
        }
791
792 61000
        if (vclsrc != NULL)
793 60480
                sp = vcc_new_source(vclsrc, "vcl.inline", vclsrcfile);
794
        else
795 520
                sp = vcc_file_source(tl, vclsrcfile);
796
797 61000
        if (sp != NULL)
798 60960
                r = vcc_CompileSource(tl, sp, jfile);
799
800 61000
        if (r != NULL) {
801 49280
                retval = TLWriteVSB(tl, ofile, r, "C-source");
802 49280
                VSB_destroy(&r);
803 49280
        } else {
804 11720
                retval = -1;
805
        }
806 61000
        AZ(VSB_finish(tl->sb));
807 61000
        *sb = tl->sb;
808 61000
        return (retval);
809 61000
}
810
811
/*--------------------------------------------------------------------
812
 * Allocate a compiler instance
813
 */
814
815
struct vcc *
816 122000
VCC_New(void)
817
{
818
        struct vcc *tl;
819
        struct symbol *sym;
820
        struct proc *p;
821
        struct vsb *vsb;
822
        int i;
823
824 122000
        ALLOC_OBJ(tl, VCC_MAGIC);
825 122000
        AN(tl);
826 122000
        VTAILQ_INIT(&tl->inifin);
827 122000
        VTAILQ_INIT(&tl->tokens);
828 122000
        VTAILQ_INIT(&tl->sources);
829 122000
        VTAILQ_INIT(&tl->procs);
830 122000
        VTAILQ_INIT(&tl->sym_objects);
831 122000
        VTAILQ_INIT(&tl->sym_vmods);
832 122000
        VTAILQ_INIT(&tl->vmod_objects);
833
834 122000
        tl->nsources = 0;
835
836 122000
        tl->symtab = VSB_new_auto();
837 122000
        assert(tl->symtab != NULL);
838 122000
        VSB_cat(tl->symtab, "[\n    {\"version\": 0}");
839
840 122000
        tl->fc = VSB_new_auto();
841 122000
        assert(tl->fc != NULL);
842
843 122000
        tl->fh = VSB_new_auto();
844 122000
        assert(tl->fh != NULL);
845
846 1830000
        for (i = 1; i < VCL_MET_MAX; i++) {
847 3416000
                sym = VCC_MkSym(tl, method_tab[i].name,
848 1708000
                    SYM_MAIN, SYM_SUB, VCL_LOW, VCL_HIGH);
849 1708000
                p = vcc_NewProc(tl, sym);
850 1708000
                p->method = &method_tab[i];
851
852
                // see also VCC_GlobalSymbol()
853 1708000
                vsb = VSB_new_auto();
854 1708000
                AN(vsb);
855 1708000
                VSB_printf(vsb, "%s_%s", SUB->global_pfx, p->method->name);
856 1708000
                AZ(VSB_finish(vsb));
857
858 1708000
                AZ(VSB_bcat(p->cname, VSB_data(vsb), VSB_len(vsb)));
859
860 1708000
                sym->lname = strdup(VSB_data(vsb));
861 1708000
                AN(sym->lname);
862
863 1708000
                VSB_clear(vsb);
864 1708000
                VSB_printf(vsb, "sub_%s", sym->lname);
865 1708000
                AZ(VSB_finish(vsb));
866
867 1708000
                sym->rname = strdup(VSB_data(vsb));
868 1708000
                AN(sym->rname);
869 1708000
                VSB_destroy(&vsb);
870
871 1708000
                sym->type = SUB;
872 1708000
                sym->kind = VCC_HandleKind(SUB);
873 1708000
                AZ(VCT_invalid_name(sym->rname, NULL));
874 1708000
                sym->eval = vcc_Eval_Sub;
875 1708000
        }
876 122000
        tl->sb = VSB_new_auto();
877 122000
        AN(tl->sb);
878 122000
        return (tl);
879
}
880
881
/*--------------------------------------------------------------------
882
 * Configure builtin VCL source code
883
 */
884
885
void
886 122000
VCC_Builtin_VCL(struct vcc *vcc, const char *str)
887
{
888
889 122000
        CHECK_OBJ_NOTNULL(vcc, VCC_MAGIC);
890 122000
        REPLACE(vcc->builtin_vcl, str);
891 122000
}
892
893
/*--------------------------------------------------------------------
894
 * Configure default VCL source path
895
 */
896
897
void
898 61000
VCC_VCL_path(struct vcc *vcc, const char *str)
899
{
900
901 61000
        CHECK_OBJ_NOTNULL(vcc, VCC_MAGIC);
902 61000
        VFIL_setpath(&vcc->vcl_path, str);
903 61000
}
904
905
/*--------------------------------------------------------------------
906
 * Configure default VMOD path
907
 */
908
909
void
910 61000
VCC_VMOD_path(struct vcc *vcc, const char *str)
911
{
912
913 61000
        CHECK_OBJ_NOTNULL(vcc, VCC_MAGIC);
914 61000
        VFIL_setpath(&vcc->vmod_path, str);
915 61000
}
916
917
/*--------------------------------------------------------------------
918
 * Configure settings
919
 */
920
921
#define VCC_FEATURE_BIT(U, l, d)                                \
922
        void VCC_Opt_ ## l(struct vcc *vcc, unsigned val)       \
923
        {                                                       \
924
                CHECK_OBJ_NOTNULL(vcc, VCC_MAGIC);              \
925
                vcc->l = val;                                   \
926
        }
927
#include "tbl/vcc_feature_bits.h"
928
929
/*--------------------------------------------------------------------
930
 * Configure settings
931
 */
932
933
static void
934 1680
vcc_predef_vcl(struct vcc *vcc, const char *name)
935
{
936
        struct symbol *sym;
937
938 1680
        sym = VCC_MkSym(vcc, name, SYM_MAIN, SYM_VCL, VCL_LOW, VCL_HIGH);
939 1680
        AN(sym);
940 1680
        sym->type = VCL;
941 1680
        sym->r_methods = VCL_MET_RECV;
942 1680
}
943
944
void
945 123840
VCC_Predef(struct vcc *vcc, const char *type, const char *name)
946
{
947
948 123840
        CHECK_OBJ_NOTNULL(vcc, VCC_MAGIC);
949 123840
        if (!strcmp(type, "VCL_STEVEDORE"))
950 122160
                vcc_stevedore(vcc, name);
951 1680
        else if (!strcmp(type, "VCL_VCL"))
952 1680
                vcc_predef_vcl(vcc, name);
953
        else
954 0
                WRONG("Unknown VCC predef type");
955 123840
}
956
957
void
958 40
VCC_VEXT(struct vcc *vcc, const char *filename)
959
{
960 40
        CHECK_OBJ_NOTNULL(vcc, VCC_MAGIC);
961 40
        vcc_ImportVext(vcc, filename);
962 40
}