Skip to content

feat(assembly): add trace for generating read-only events - #3478

Open
mooori wants to merge 5 commits into
0xMiden:nextfrom
mooori:trace-assembly-readonly-event
Open

feat(assembly): add trace for generating read-only events#3478
mooori wants to merge 5 commits into
0xMiden:nextfrom
mooori:trace-assembly-readonly-event

Conversation

@mooori

@mooori mooori commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Closes #3373

For now I kept the variant with immediate consistent with emit. Reasoning:

  • Fully typed out trace.event("miden::mytrace") looks natural as we referred to it as "trace event"
  • Under the hood miden::mytrace is an event, so it fits event(...)

@mooori
mooori force-pushed the trace-assembly-readonly-event branch from dcd2c84 to 220f6e2 Compare August 5, 2026 19:55
@mooori
mooori marked this pull request as ready for review August 5, 2026 20:06
@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown

Automated check (CONTRIBUTING.md)

Findings:

  • Add a short Rationale explaining why the change is needed.

Recommendations:

  • Consider adding a Test plan or clear review steps.

Next steps:

@mooori

mooori commented Aug 5, 2026

Copy link
Copy Markdown
Contributor Author

/cc @bobbinth @bitwalker

@bobbinth
bobbinth requested a review from bitwalker August 5, 2026 22:21
Self::Trace => const_text("trace"),
// Printing `TraceImm` such that it is consistent with `EmitImm`, even though this
// does not round-trip. `trace.<FELT_IMM>` is invalid.
Self::TraceImm(value) => inst_with_felt_imm("trace", value),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Formatting a parsed trace.event(...) now writes trace.<felt>, but this PR also rejects numeric trace immediates.

I reproduced this with trace.event("test::roundtrip"): the formatted module fails to parse with invalid instruction trace or malformed operands.

Could this print a valid equivalent such as push.<felt> trace drop, and cover it with a parse-format-parse test?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea of printing as trace.<felt> was to be in line with emit.<felt>, see the comment displayed in the code snippet above. In 23fb57b I've changed it to print as push.<felt> trace drop and added a test to verify that this can be parsed back.

Should we open an issue to change the printing of EmitImm to push.<felt> emit drop so that it can be parsed back too? Though I assume that would be a breaking change.

},

ExtendedInstructionKind::Emit => lower_emit_instruction(context, span, &tokens),
ExtendedInstructionKind::Trace => lower_trace_instruction(context, span, &tokens),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: trace duplicates the full emit extended parser below, including constant lookup and event-name hashing.

THe instruction spec could carry the immediate constructor and use one lowering helper keyed by spec.keyword instead.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

THe instruction spec could carry the immediate constructor and use one lowering helper keyed by spec.keyword instead.

Not sure if I understand correctly, but Wouldn't that require changing ExtendedInstructionSpec?

For now I removed the duplication by lowering both through a new shared function: lower_event_imm_instruction.

@mooori
mooori requested a review from huitseeker August 7, 2026 16:40

@huitseeker huitseeker left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Comment thread CHANGELOG.md

#### Features

- Added `trace`, `trace.CONST`, and `trace.event("...")` assembly as syntactic sugar for emitting optional read-only trace events ([#3478](https://github.com/0xMiden/miden-vm/pull/3478)).

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This also adds Trace and TraceImm to the public exhaustive miden_assembly_syntax::ast::Instruction enum, so downstream exhaustive matches stop compiling. cargo semver-checks check-release -p miden-assembly-syntax --baseline-version 0.29.0 --release-type minor reports enum_variant_added for both variants.

Could we mark this entry [BREAKING]?

Self::Trace => const_text("trace"),
// `trace.<FELT_IMM>` is invalid syntax, so to support a `print -> parse` round trip
// we print the equivalent `push.<value> trace drop` sequence instead.
Self::TraceImm(value) => {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: this repeats the Felt immediate rendering in inst_with_felt_imm just below. Could this be flatten(inst_with_felt_imm("push", value) + const_text(" trace drop"))?

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bring back trace assembly to generate readonly events

2 participants