Commit graph

5 commits

Author SHA1 Message Date
Stephen Dennis
e2b1f974ab docs(#2136): mark parse_arglist as the producer side of the fargs contract
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>
2026-08-06 15:00:57 -06:00
Stephen Dennis
b5ee3b6f81 refactor: use UTF-8 text in user-facing string literals (#1513)
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.
2026-07-26 21:52:48 -06:00
Stephen Dennis
a14d37a781 fix(eval): restore softcode TRACE output (#1023)
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>
2026-07-22 18:27:14 -06:00
Stephen Dennis
7ec8d738ea Unify pool + refcount layers: shared_ptr replaces manual lbuf_ref/reg_ref
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>
2026-03-19 09:27:48 -06:00
Stephen Dennis
4ff1398de1 Restructure mux/ directory: component-based layout with proper build root
Move from flat mux/src/ layout to clean component hierarchy:
- mux/ is now the autoconf/automake build root (configure.ac lives here)
- mux/include/ — shared headers used by multiple components
- mux/lib/ — libmux.so (core utilities, no game state)
- mux/src/ — netmux driver only (thin networking shell)
- mux/modules/engine/ — engine.so (game logic)
- mux/modules/{comsys,mail,exp3,sqlproxy,sqlslave}/ — external modules
- mux/ganl/ — GANL networking library
- mux/sqlite/ — SQLite amalgamation (builds libsqlite3.a)
- mux/announce/ — announce tool (was mux/src/tools/)

Build changes:
- SUBDIRS ordering: ganl sqlite lib src modules announce
- libmux.so gets -Wl,-soname,libmux.so; netmux links via -L -lmux
- engine.so links libsqlite3.a and libmux.so with -Wl,--no-undefined
- RPATH uses $ORIGIN for portable .so resolution
- Install hooks use absolute paths for game/bin symlinks

Bug fixes:
- engine.so mux_Register() now passes nullptr to mux_RegisterClassObjects
  (matches all other modules; libmux already has the factory via dlsym)
- DbConvert() now calls pcache_init() before db_write, fixing a latent
  crash (free(): invalid pointer) when exporting from SQLite databases

411/411 smoke tests pass.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 20:38:37 -06:00
Renamed from mux/src/eval.cpp (Browse further)