Comment-only. Kagura's post-gate sweep for the old spelling correctly
identified this as the one deliberate survivor — it allocates the lbufs
and writes the pointers, so it must not take them const — and suggested
the note so a future grep sweep doesn't "fix" it.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Replace ~900 typographic \xE2\x80\x.. escapes (curly quotes, en dashes)
and a few \xE2\x80\230 octal workarounds with real UTF-8 in message
strings under mux/modules and mux/src. Leave stringutil and convert
charset mapping tables as explicit byte sequences.
The TRACE flag (and per-attribute trace) produced no output: the emitter
tcache_add/tcache_finish was carried into the AST/JIT evaluator but its caller
was never reconnected, so setting TRACE silently did nothing. Confirmed
regression -- it works in origin/release/2.13.
2.13 drove the trace inline from the tree-walking exec() recursion: compute
is_trace, capture the input substring on entry, tcache_add(input, result) on
exit, tcache_finish() at the top. That exact shape does not exist here because
evaluation moved to an AST interpreter plus a JIT/DBT compile path. This
reconnects the emitter against the surviving interpreter rather than porting
2.13's code:
* mux_exec computes is_trace = (Trace(executor) || (eval & EV_TRACE)) &&
!(eval & EV_NOTRACE). When set, it forces the AST interpreter (the JIT has
no per-node frames for the hook to observe) and brackets the outermost
evaluation so accumulated lines flush to the owner.
* ast_eval_node records (source -> result) for the call boundaries --
AST_FUNCCALL and AST_EVALBRACKET -- using ast_raw_text() for the source and
the span it just wrote for the result. The change-filter in tcache_add
drops no-op nodes. Off-path cost is a single bit test, since EV_TRACE is
only set while tracing.
Both the object TRACE flag and the per-attribute trace flag (AttrTrace ->
EV_TRACE) drive it, and EV_TRACE propagates through argument evaluation so
nested calls trace. The tcache emitter (owns orig, applies the change-filter,
respects trace_limit) is reused unchanged; it is exposed from eval.cpp via
externs.h.
Both config knobs restored to 2.13 parity:
* trace_topdown (default true): accumulate and flush outermost-first at the
top; false flushes each line as its subexpression completes (innermost
first).
* trace_output_limit (trace_limit, default 200): caps stored lines top-down;
a "N lines of trace output discarded." notice reports the overflow.
Verified (fresh DB per case): no flag -> result only, zero trace lines, JIT
still used; object TRACE and per-attribute trace each -> nested
'expr -> result' lines; top-down outermost-first, bottom-up innermost-first;
trace_output_limit 2 -> two lines plus "3 lines of trace output discarded."
Regression: smoke 1319/1319, JIT q-register oracle AST=JIT agree (the
trace-forced interpreter path matches the JIT), stress 8/8, netaddr 57/57,
ganl 14/14.
Not included: bare %-substitution granularity (2.13 also traced e.g. '%0'->'7'
as its own line). Call-boundary tracing -- the function nesting a builder
actually debugs -- is restored; per-substitution lines can be added later if
wanted.
Closes#1023.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Replace the two-level manual reference counting system (lbuf_ref + reg_ref
with BufAddRef/BufRelease/RegAddRef/RegRelease) with std::shared_ptr:
- RegBuffer: new shared buffer struct, managed by shared_ptr — replaces
lbuf_ref which was a manual refcount wrapper around a pool-allocated lbuf
- reg_ref: now contains shared_ptr<RegBuffer> instead of lbuf_ref pointer;
allocated with new/delete instead of POOL_REGREF
- RegAssign: uses make_shared<RegBuffer> instead of alloc_lbuf + alloc_lbufref;
packing optimization preserved (multiple values in one RegBuffer)
- RegRelease: simplified to decrement + delete (shared_ptr destructor
handles buffer lifecycle automatically)
- BufAddRef/BufRelease: eliminated entirely — shared_ptr copy/destroy
handles all buffer reference counting
- POOL_LBUFREF, POOL_REGREF: eliminated (NUM_POOLS 9 → 7)
- JIT arena: uses shared_ptr<RegBuffer> instead of lbuf_ref
The pool allocator (POOL_LBUF) remains for the 323 temporary-buffer call
sites — that's the "blindingly fast" layer. The refcount layer above it
is now automatic via shared_ptr.
Net: −103 deleted, +51 added across 6 files. All 551 smoke tests pass.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>