Coverage Report

Created: 2026-05-12 06:44

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/zeek/src/script_opt/ZAM/Driver.cc
Line
Count
Source
1
// See the file "COPYING" in the main distribution directory for copyright.
2
3
// Driver (and other high-level) methods for ZAM compilation.
4
5
#include "zeek/Frame.h"
6
#include "zeek/Reporter.h"
7
#include "zeek/Scope.h"
8
#include "zeek/script_opt/ScriptOpt.h"
9
#include "zeek/script_opt/ZAM/Compile.h"
10
11
namespace zeek::detail {
12
13
ZAMCompiler::ZAMCompiler(ScriptFuncPtr f, std::shared_ptr<ProfileFuncs> _pfs, std::shared_ptr<ProfileFunc> _pf,
14
0
                         ScopePtr _scope, StmtPtr _body, std::shared_ptr<UseDefs> _ud, std::shared_ptr<Reducer> _rd) {
15
0
    func = std::move(f);
16
0
    pfs = std::move(_pfs);
17
0
    pf = std::move(_pf);
18
0
    scope = std::move(_scope);
19
0
    body = std::move(_body);
20
0
    ud = std::move(_ud);
21
0
    reducer = std::move(_rd);
22
0
    frame_sizeI = 0;
23
24
0
    auto loc = body->GetLocationInfo();
25
0
    ASSERT(loc->FirstLine() != 0 || body->Tag() == STMT_NULL);
26
0
    auto loc_copy = std::make_shared<Location>(loc->FileName(), loc->FirstLine(), loc->LastLine());
27
0
    ZAM::curr_func = func->GetName();
28
0
    ZAM::curr_loc = std::make_shared<ZAMLocInfo>(ZAM::curr_func, std::move(loc_copy), nullptr);
29
30
0
    Init();
31
0
}
32
33
0
ZAMCompiler::~ZAMCompiler() {
34
0
    for ( auto i : insts1 )
35
0
        delete i;
36
0
}
37
38
0
void ZAMCompiler::Init() {
39
0
    InitGlobals();
40
0
    InitArgs();
41
0
    InitCaptures();
42
0
    InitLocals();
43
44
0
    TrackMemoryManagement();
45
46
0
    non_recursive = non_recursive_funcs.contains(func.get());
47
0
}
48
49
0
void ZAMCompiler::InitGlobals() {
50
0
    for ( auto& g : pf->Globals() ) {
51
0
        GlobalInfo info{.id = g, .slot = AddToFrame(g)};
52
0
        global_id_to_info[g] = globalsI.size();
53
0
        globalsI.push_back(info);
54
0
    }
55
0
}
56
57
0
void ZAMCompiler::InitArgs() {
58
0
    auto uds = ud->HasUsage(body.get()) ? ud->GetUsage(body.get()) : nullptr;
59
60
0
    auto args = scope->OrderedVars();
61
0
    int nparam = func->GetType()->Params()->NumFields();
62
63
0
    push_existing_scope(scope);
64
65
0
    for ( auto& a : args ) {
66
0
        if ( --nparam < 0 )
67
0
            break;
68
69
0
        if ( uds && uds->HasID(a) )
70
0
            LoadParam(a);
71
0
        else {
72
            // printf("param %s unused\n", obj_desc(arg_id.get()));
73
0
        }
74
0
    }
75
76
0
    pop_scope();
77
0
}
78
79
0
void ZAMCompiler::InitCaptures() {
80
0
    for ( const auto& c : pf->Captures() )
81
0
        (void)AddToFrame(c);
82
0
}
83
84
0
void ZAMCompiler::InitLocals() {
85
    // Assign slots for locals (which includes temporaries).
86
0
    for ( auto& l : pf->Locals() ) {
87
0
        if ( IsCapture(l) )
88
0
            continue;
89
90
0
        if ( pf->WhenLocals().contains(l) )
91
0
            continue;
92
93
        // Don't add locals that were already added because they're
94
        // parameters.
95
        //
96
        // Don't worry about unused variables, those will get
97
        // removed during low-level ZAM optimization.
98
0
        if ( ! HasFrameSlot(l) )
99
0
            (void)AddToFrame(l);
100
0
    }
101
0
}
102
103
0
void ZAMCompiler::TrackMemoryManagement() {
104
0
    for ( auto& slot : frame_layout1 ) {
105
        // Look for locals with values of types for which
106
        // we do explicit memory management on (re)assignment.
107
0
        auto t = slot.first->GetType();
108
0
        if ( ZVal::IsManagedType(t) )
109
0
            managed_slotsI.push_back(slot.second);
110
0
    }
111
0
}
112
113
0
StmtPtr ZAMCompiler::CompileBody() {
114
0
    if ( func->Flavor() == FUNC_FLAVOR_HOOK )
115
0
        PushBreaks();
116
117
0
    (void)CompileStmt(body);
118
119
0
    if ( reporter->Errors() > 0 )
120
0
        return nullptr;
121
122
0
    ResolveHookBreaks();
123
124
0
    if ( ! nexts.empty() )
125
0
        reporter->Error("\"next\" used without an enclosing \"for\"");
126
127
0
    if ( ! fallthroughs.empty() )
128
0
        reporter->Error("\"fallthrough\" used without an enclosing \"switch\"");
129
130
0
    if ( ! catches.empty() )
131
0
        reporter->InternalError("untargeted inline return");
132
133
    // Make sure we have a (pseudo-)instruction at the end so we
134
    // can use it as a branch label.
135
0
    if ( ! pending_inst )
136
0
        pending_inst = new ZInstI();
137
138
    // Concretize instruction numbers in inst1 so we can
139
    // easily move through the code.
140
0
    for ( auto i = 0U; i < insts1.size(); ++i )
141
0
        insts1[i]->inst_num = i;
142
143
0
    ComputeLoopLevels();
144
145
0
    if ( ! analysis_options.no_ZAM_opt )
146
0
        OptimizeInsts();
147
148
0
    AdjustBranches();
149
150
    // Construct the final program with the dead code eliminated
151
    // and branches resolved.
152
153
    // Make sure we don't include the empty pending-instruction, if any.
154
0
    if ( pending_inst )
155
0
        pending_inst->live = false;
156
157
    // Maps inst1 instructions to where they are in inst2.
158
    // Dead instructions map to -1.
159
0
    std::vector<int> inst1_to_inst2;
160
161
0
    for ( auto& i1 : insts1 ) {
162
0
        if ( i1->live ) {
163
0
            inst1_to_inst2.push_back(insts2.size());
164
0
            insts2.push_back(i1);
165
0
        }
166
0
        else
167
0
            inst1_to_inst2.push_back(-1);
168
0
    }
169
170
    // Re-concretize instruction numbers, and concretize GoTo's.
171
0
    for ( auto i = 0U; i < insts2.size(); ++i )
172
0
        insts2[i]->inst_num = i;
173
174
0
    RetargetBranches();
175
176
    // If we have remapped frame denizens, update them.  If not,
177
    // create them.
178
0
    if ( ! shared_frame_denizens.empty() )
179
0
        RemapFrameDenizens(inst1_to_inst2);
180
181
0
    else
182
0
        CreateSharedFrameDenizens();
183
184
0
    delete pending_inst;
185
186
0
    ConcretizeSwitches();
187
188
0
    auto fname = func->GetName();
189
190
0
    if ( func->Flavor() == FUNC_FLAVOR_FUNCTION )
191
0
        fname = func_name_at_loc(fname, body->GetLocationInfo());
192
193
0
    auto zb = make_intrusive<ZBody>(fname, this);
194
0
    zb->SetInsts(insts2);
195
0
    zb->SetLocationInfo(body->GetLocationInfo());
196
197
    // Could erase insts1 here to recover memory, but it's handy
198
    // for debugging.
199
200
0
    return zb;
201
0
}
202
203
0
void ZAMCompiler::ResolveHookBreaks() {
204
0
    if ( ! breaks.empty() ) {
205
0
        ASSERT(breaks.size() == 1);
206
207
0
        if ( func->Flavor() == FUNC_FLAVOR_HOOK ) {
208
            // Rewrite the breaks.
209
0
            for ( auto& b : breaks[0] ) {
210
0
                auto& i = insts1[b.stmt_num];
211
0
                auto aux = i->aux;
212
0
                *i = ZInstI(OP_HOOK_BREAK_X);
213
0
                i->aux = aux;
214
0
            }
215
0
        }
216
217
0
        else
218
0
            reporter->Error("\"break\" used without an enclosing \"for\" or \"switch\"");
219
0
    }
220
0
}
221
222
0
void ZAMCompiler::ComputeLoopLevels() {
223
    // Compute which instructions are inside loops.
224
0
    for ( auto i = 0; i < static_cast<int>(insts1.size()); ++i ) {
225
0
        auto inst = insts1[i];
226
227
0
        auto t = inst->target;
228
0
        if ( ! t || t == pending_inst )
229
0
            continue;
230
231
0
        if ( t->inst_num < i ) {
232
0
            auto j = t->inst_num;
233
234
0
            if ( ! t->loop_start ) {
235
                // Loop is newly discovered.
236
0
                t->loop_start = true;
237
0
            }
238
0
            else {
239
                // We're extending an existing loop.  Find
240
                // its current end.
241
0
                auto depth = t->loop_depth;
242
0
                while ( j < i && insts1[j]->loop_depth >= depth )
243
0
                    ++j;
244
245
0
                ASSERT(insts1[j]->loop_depth == depth - 1);
246
0
            }
247
248
            // Run from j's current position to i, bumping
249
            // the loop depth.
250
0
            while ( j <= i ) {
251
0
                ++insts1[j]->loop_depth;
252
0
                ++j;
253
0
            }
254
0
        }
255
0
    }
256
0
}
257
258
0
void ZAMCompiler::AdjustBranches() {
259
    // Move branches to dead code forward to their successor live code.
260
0
    for ( auto& inst : insts1 ) {
261
0
        if ( ! inst->live )
262
0
            continue;
263
264
0
        if ( auto t = inst->target )
265
0
            inst->target = FindLiveTarget(t);
266
0
    }
267
268
    // Fix up the implicit branches in switches, too.
269
0
    AdjustSwitchTables(int_casesI);
270
0
    AdjustSwitchTables(uint_casesI);
271
0
    AdjustSwitchTables(double_casesI);
272
0
    AdjustSwitchTables(str_casesI);
273
0
}
274
275
template<typename T>
276
0
void ZAMCompiler::AdjustSwitchTables(CaseMapsI<T>& abstract_cases) {
277
0
    for ( auto& targs : abstract_cases ) {
278
0
        for ( auto& targ : targs )
279
0
            targ.second = FindLiveTarget(targ.second);
280
0
    }
281
0
}
Unexecuted instantiation: void zeek::detail::ZAMCompiler::AdjustSwitchTables<long>(std::__1::vector<std::__1::map<long, zeek::detail::ZInstI*, std::__1::less<long>, std::__1::allocator<std::__1::pair<long const, zeek::detail::ZInstI*> > >, std::__1::allocator<std::__1::map<long, zeek::detail::ZInstI*, std::__1::less<long>, std::__1::allocator<std::__1::pair<long const, zeek::detail::ZInstI*> > > > >&)
Unexecuted instantiation: void zeek::detail::ZAMCompiler::AdjustSwitchTables<unsigned long>(std::__1::vector<std::__1::map<unsigned long, zeek::detail::ZInstI*, std::__1::less<unsigned long>, std::__1::allocator<std::__1::pair<unsigned long const, zeek::detail::ZInstI*> > >, std::__1::allocator<std::__1::map<unsigned long, zeek::detail::ZInstI*, std::__1::less<unsigned long>, std::__1::allocator<std::__1::pair<unsigned long const, zeek::detail::ZInstI*> > > > >&)
Unexecuted instantiation: void zeek::detail::ZAMCompiler::AdjustSwitchTables<double>(std::__1::vector<std::__1::map<double, zeek::detail::ZInstI*, std::__1::less<double>, std::__1::allocator<std::__1::pair<double const, zeek::detail::ZInstI*> > >, std::__1::allocator<std::__1::map<double, zeek::detail::ZInstI*, std::__1::less<double>, std::__1::allocator<std::__1::pair<double const, zeek::detail::ZInstI*> > > > >&)
Unexecuted instantiation: void zeek::detail::ZAMCompiler::AdjustSwitchTables<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(std::__1::vector<std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, zeek::detail::ZInstI*, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, zeek::detail::ZInstI*> > >, std::__1::allocator<std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, zeek::detail::ZInstI*, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, zeek::detail::ZInstI*> > > > >&)
282
283
0
void ZAMCompiler::RetargetBranches() {
284
0
    for ( auto& inst : insts2 )
285
0
        if ( inst->target )
286
0
            ConcretizeBranch(inst, inst->target, inst->target_slot);
287
0
}
288
289
0
void ZAMCompiler::RemapFrameDenizens(const std::vector<int>& inst1_to_inst2) {
290
0
    for ( auto& info : shared_frame_denizens ) {
291
0
        for ( auto& start : info.id_start ) {
292
            // It can happen that the identifier's
293
            // origination instruction was optimized
294
            // away, if due to slot sharing it's of
295
            // the form "slotX = slotX".  In that
296
            // case, look forward for the next viable
297
            // instruction.
298
0
            while ( start < insts1.size() && inst1_to_inst2[start] == -1 )
299
0
                ++start;
300
301
0
            ASSERT(start < insts1.size());
302
0
            start = inst1_to_inst2[start];
303
0
        }
304
305
0
        shared_frame_denizens_final.push_back(info);
306
0
    }
307
0
}
308
309
0
void ZAMCompiler::CreateSharedFrameDenizens() {
310
0
    for ( auto& fd : frame_denizens ) {
311
0
        FrameSharingInfo info;
312
0
        info.ids.push_back(fd);
313
0
        info.id_start.push_back(0);
314
0
        info.scope_end = insts2.size();
315
316
        // The following doesn't matter since the value
317
        // is only used during compiling, not during
318
        // execution.
319
0
        info.is_managed = false;
320
321
0
        shared_frame_denizens_final.push_back(std::move(info));
322
0
    }
323
0
}
324
325
0
void ZAMCompiler::ConcretizeSwitches() {
326
    // Create concretized versions of any case tables.
327
0
    ConcretizeSwitchTables(int_casesI, int_cases);
328
0
    ConcretizeSwitchTables(uint_casesI, uint_cases);
329
0
    ConcretizeSwitchTables(double_casesI, double_cases);
330
0
    ConcretizeSwitchTables(str_casesI, str_cases);
331
0
}
332
333
template<typename T>
334
0
void ZAMCompiler::ConcretizeSwitchTables(const CaseMapsI<T>& abstract_cases, CaseMaps<T>& concrete_cases) {
335
0
    for ( auto& targs : abstract_cases ) {
336
0
        CaseMap<T> cm;
337
0
        for ( auto& targ : targs )
338
0
            cm[targ.first] = targ.second->inst_num;
339
0
        concrete_cases.emplace_back(cm);
340
0
    }
341
0
}
Unexecuted instantiation: void zeek::detail::ZAMCompiler::ConcretizeSwitchTables<long>(std::__1::vector<std::__1::map<long, zeek::detail::ZInstI*, std::__1::less<long>, std::__1::allocator<std::__1::pair<long const, zeek::detail::ZInstI*> > >, std::__1::allocator<std::__1::map<long, zeek::detail::ZInstI*, std::__1::less<long>, std::__1::allocator<std::__1::pair<long const, zeek::detail::ZInstI*> > > > > const&, std::__1::vector<std::__1::map<long, int, std::__1::less<long>, std::__1::allocator<std::__1::pair<long const, int> > >, std::__1::allocator<std::__1::map<long, int, std::__1::less<long>, std::__1::allocator<std::__1::pair<long const, int> > > > >&)
Unexecuted instantiation: void zeek::detail::ZAMCompiler::ConcretizeSwitchTables<unsigned long>(std::__1::vector<std::__1::map<unsigned long, zeek::detail::ZInstI*, std::__1::less<unsigned long>, std::__1::allocator<std::__1::pair<unsigned long const, zeek::detail::ZInstI*> > >, std::__1::allocator<std::__1::map<unsigned long, zeek::detail::ZInstI*, std::__1::less<unsigned long>, std::__1::allocator<std::__1::pair<unsigned long const, zeek::detail::ZInstI*> > > > > const&, std::__1::vector<std::__1::map<unsigned long, int, std::__1::less<unsigned long>, std::__1::allocator<std::__1::pair<unsigned long const, int> > >, std::__1::allocator<std::__1::map<unsigned long, int, std::__1::less<unsigned long>, std::__1::allocator<std::__1::pair<unsigned long const, int> > > > >&)
Unexecuted instantiation: void zeek::detail::ZAMCompiler::ConcretizeSwitchTables<double>(std::__1::vector<std::__1::map<double, zeek::detail::ZInstI*, std::__1::less<double>, std::__1::allocator<std::__1::pair<double const, zeek::detail::ZInstI*> > >, std::__1::allocator<std::__1::map<double, zeek::detail::ZInstI*, std::__1::less<double>, std::__1::allocator<std::__1::pair<double const, zeek::detail::ZInstI*> > > > > const&, std::__1::vector<std::__1::map<double, int, std::__1::less<double>, std::__1::allocator<std::__1::pair<double const, int> > >, std::__1::allocator<std::__1::map<double, int, std::__1::less<double>, std::__1::allocator<std::__1::pair<double const, int> > > > >&)
Unexecuted instantiation: void zeek::detail::ZAMCompiler::ConcretizeSwitchTables<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(std::__1::vector<std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, zeek::detail::ZInstI*, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, zeek::detail::ZInstI*> > >, std::__1::allocator<std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, zeek::detail::ZInstI*, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, zeek::detail::ZInstI*> > > > > const&, std::__1::vector<std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, int, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, int> > >, std::__1::allocator<std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, int, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, int> > > > >&)
342
343
#include "ZAM-MethodDefs.h"
344
345
0
void ZAMCompiler::Dump() {
346
0
    bool remapped_frame = ! analysis_options.no_ZAM_opt;
347
348
0
    if ( analysis_options.dump_ZAM ) {
349
0
        if ( remapped_frame )
350
0
            printf("\nOriginal frame for %s:\n", func->GetName().c_str());
351
352
0
        for ( const auto& elem : frame_layout1 )
353
0
            printf("frame[%d] = %s\n", elem.second, elem.first->Name());
354
355
0
        if ( remapped_frame ) {
356
0
            printf("Final frame for %s:\n", func->GetName().c_str());
357
358
0
            for ( auto i = 0U; i < shared_frame_denizens.size(); ++i ) {
359
0
                printf("frame2[%d] =", i);
360
0
                for ( auto& id : shared_frame_denizens[i].ids )
361
0
                    printf(" %s", id->Name());
362
0
                printf("\n");
363
0
            }
364
0
        }
365
366
0
        if ( ! insts2.empty() )
367
0
            printf("Pre-removal of dead code for %s:\n", func->GetName().c_str());
368
369
0
        auto remappings = remapped_frame ? &shared_frame_denizens : nullptr;
370
371
0
        DumpInsts1(remappings);
372
373
0
        if ( ! insts2.empty() )
374
0
            printf("Final intermediary code for %s:\n", func->GetName().c_str());
375
376
0
        remappings = remapped_frame ? &shared_frame_denizens_final : nullptr;
377
378
0
        for ( auto i = 0U; i < insts2.size(); ++i ) {
379
0
            auto& inst = insts2[i];
380
0
            std::string liveness;
381
0
            std::string depth;
382
383
0
            if ( inst->live )
384
0
                liveness = util::fmt("(labels %d)", inst->num_labels);
385
0
            else
386
0
                liveness = "(dead)";
387
388
0
            if ( inst->loop_depth )
389
0
                depth = util::fmt(" (loop %d)", inst->loop_depth);
390
391
0
            printf("%d %s%s: ", i, liveness.c_str(), depth.c_str());
392
393
0
            inst->Dump(stdout, &frame_denizens, remappings);
394
0
        }
395
0
    }
396
0
    else if ( analysis_options.dump_final_ZAM ) {
397
0
        printf("\nFrame for %s:\n", func->GetName().c_str());
398
399
0
        if ( remapped_frame ) {
400
0
            for ( auto i = 0U; i < shared_frame_denizens.size(); ++i ) {
401
0
                printf("frame[%d] =", i);
402
0
                for ( auto& id : shared_frame_denizens[i].ids )
403
0
                    printf(" %s", id->Name());
404
0
                printf("\n");
405
0
            }
406
0
        }
407
0
        else
408
0
            for ( const auto& elem : frame_layout1 )
409
0
                printf("frame[%d] = %s\n", elem.second, elem.first->Name());
410
0
    }
411
412
0
    if ( ! insts2.empty() )
413
0
        printf("Final code for %s:\n", func->GetName().c_str());
414
415
0
    auto remappings = remapped_frame ? &shared_frame_denizens_final : nullptr;
416
0
    for ( auto i = 0U; i < insts2.size(); ++i ) {
417
0
        auto& inst = insts2[i];
418
        // printf("%s:%d\n", inst->loc->filename, inst->loc->first_line);
419
0
        printf("%d: ", i);
420
0
        inst->Dump(stdout, &frame_denizens, remappings);
421
0
    }
422
423
0
    DumpCases(int_cases, "int");
424
0
    DumpCases(uint_cases, "uint");
425
0
    DumpCases(double_cases, "double");
426
0
    DumpCases(str_cases, "str");
427
0
}
428
429
template<typename T>
430
0
void ZAMCompiler::DumpCases(const CaseMaps<T>& cases, const char* type_name) const {
431
0
    for ( auto i = 0U; i < cases.size(); ++i ) {
432
0
        printf("%s switch table #%d:", type_name, i);
433
0
        for ( auto& m : cases[i] ) {
434
0
            std::string case_val;
435
            if constexpr ( std::is_same_v<T, std::string> )
436
0
                case_val = m.first;
437
            else if constexpr ( std::is_same_v<T, zeek_int_t> || std::is_same_v<T, zeek_uint_t> ||
438
                                std::is_same_v<T, double> )
439
0
                case_val = std::to_string(m.first);
440
441
0
            printf(" %s->%d", case_val.c_str(), m.second);
442
0
        }
443
0
        printf("\n");
444
0
    }
445
0
}
Unexecuted instantiation: void zeek::detail::ZAMCompiler::DumpCases<long>(std::__1::vector<std::__1::map<long, int, std::__1::less<long>, std::__1::allocator<std::__1::pair<long const, int> > >, std::__1::allocator<std::__1::map<long, int, std::__1::less<long>, std::__1::allocator<std::__1::pair<long const, int> > > > > const&, char const*) const
Unexecuted instantiation: void zeek::detail::ZAMCompiler::DumpCases<unsigned long>(std::__1::vector<std::__1::map<unsigned long, int, std::__1::less<unsigned long>, std::__1::allocator<std::__1::pair<unsigned long const, int> > >, std::__1::allocator<std::__1::map<unsigned long, int, std::__1::less<unsigned long>, std::__1::allocator<std::__1::pair<unsigned long const, int> > > > > const&, char const*) const
Unexecuted instantiation: void zeek::detail::ZAMCompiler::DumpCases<double>(std::__1::vector<std::__1::map<double, int, std::__1::less<double>, std::__1::allocator<std::__1::pair<double const, int> > >, std::__1::allocator<std::__1::map<double, int, std::__1::less<double>, std::__1::allocator<std::__1::pair<double const, int> > > > > const&, char const*) const
Unexecuted instantiation: void zeek::detail::ZAMCompiler::DumpCases<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(std::__1::vector<std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, int, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, int> > >, std::__1::allocator<std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, int, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, int> > > > > const&, char const*) const
446
447
0
void ZAMCompiler::DumpInsts1(const FrameReMap* remappings) {
448
0
    for ( auto i = 0U; i < insts1.size(); ++i ) {
449
0
        auto& inst = insts1[i];
450
451
0
        if ( inst->target )
452
            // To get meaningful branch information in the dump,
453
            // we need to concretize the branch slots
454
0
            ConcretizeBranch(inst, inst->target, inst->target_slot);
455
456
0
        std::string liveness;
457
0
        std::string depth;
458
459
0
        if ( inst->live )
460
0
            liveness = util::fmt("(labels %d)", inst->num_labels);
461
0
        else
462
0
            liveness = "(dead)";
463
464
0
        if ( inst->loop_depth )
465
0
            depth = util::fmt(" (loop %d)", inst->loop_depth);
466
467
0
        printf("%d %s%s: ", i, liveness.c_str(), depth.c_str());
468
469
        inst->Dump(stdout, &frame_denizens, remappings);
470
0
    }
471
0
}
472
473
} // namespace zeek::detail