Skip to content

Emit chialisp structural debug metadata sidecars #199

Open

Description

@Rigidity

Rue should emit the structural CLVM debug metadata sidecar (.debug.clvm.bin) from Chia-Network/chialisp#579, so failing Rue programs get symbolized stack traces through run_program_with_diagnostics and chialisp's renderer.

The spike in #187 (draft, reference only) shows this works with the current format. All 15 test cases in spike/cases produce correct traces against #579 at 1ba4c714, including closures, recursion and destructured parameters. See spike/REPORT.md for the details and spike/out/*.txt for the rendered output.

Implementation

Compiler tracking. These replace the // SPIKE code in #187 with real APIs:

  • Record each HIR node's source span (innermost expression, plus block spans), as rue-compiler/src/compile/{expr,block}.rs do in the spike.
  • In lowering, tag every LIR node with the span of the HIR node that produced it, and record function roots with their parameter layouts (rue-hir/src/lower.rs, database.rs). Keep Fix source locations for main capture wrappers #188's tag on the main capture/setup wrapper: a span but no function, since its environment differs from the body's.
  • Carry tags through the optimizer: each optimized node needs to know which original node it came from (rue-lir/src/optimize.rs).
  • Map final CLVM nodes back to their tags in codegen (rue-lir/src/codegen.rs).
  • Replace the spike's global state (DEBUG_TAGGING, OPT_TRACE) with state passed explicitly and collected only when requested. OPT_TRACE is currently always on and never cleared, which would leak in the LSP.

Sidecar writer. spike/rue-debug-spike/src/main.rs has a working builder. It should:

  • write the magic, version, coordinates, program hash, and the file, string, span and function tables, plus the shadow tree;
  • describe Rue's real environment layout in the parameter tree;
  • use Nil for skipped slots, left_env for the function table, and constraints from Rue's types where they map (Int → Integer, Bytes32 → Bytes(32), lists → ProperList, and so on).

The encoding is simple enough to write in Rue without depending on the chialisp crate. That keeps Rue off chialisp's release schedule.

CLI and API. Emit the sidecar behind a debug flag next to the compiled output. Compiling with the flag must produce the same program bytes in debug and release builds as compiling without it.

Runner (later). A Rue command that runs a program with run_program_with_diagnostics and renders the trace using the chialisp crate. This needs clvmr 0.22 with pre-eval, which is blocked until chia_rs's clvm-traits moves off clvmr 0.21.

Tests.

Known gaps in v1

These all need format additions. The tolerant decoder in chialisp#579 (69599b8c) lets them be added later without breaking v1 readers. In rough priority order:

  1. Type strings on parameters. Values currently render by runtime shape, so an Int can show as "hell", a String as a number, and false/0 as (). This is the most visible gap.
  2. Definition span on functions. Frames currently point at the body root: the { or the first statement.
  3. Inline sites. Inlined calls lose their call site, and the inlined body shows as an anonymous frame.
  4. Declaration order. Parameters display in environment layout order.
  5. Function/scope kind, so let locals can be shown without appearing as fake call frames.
  6. Byte offsets alongside the tab-expanded columns, plus a producer field and a tree-hash identity.

Accepted limitation from #579: byte-identical function bodies render as <ambiguous: a | b>.

Dependencies

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions