Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
- Add a compaction function for achieving maximal sharing out of a `MastForest` with stripped decorators ([#2408](https://github.com/0xMiden/miden-vm/pull/2408)).
- Refactor and remove tech debt from parallel trace generation ([#2382](https://github.com/0xMiden/miden-vm/pull/2382))
- [BREAKING] Added `kind` field to `Package` struct to indicate package type (Executable, AccountComponent, NoteScript, TxScript, AuthComponent) ([#2403](https://github.com/0xMiden/miden-vm/pull/2403)).
- [BREAKING] Make the Assembler work in debug mode, remove optionality ([#2396](https://github.com/0xMiden/miden-vm/pull/2396)).

## 0.19.1 (2025-11-6)

Expand Down
13 changes: 7 additions & 6 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 2 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ WARNINGS := RUSTDOCFLAGS="-D warnings"
BUILDDOCS := MIDEN_BUILD_LIBCORE_DOCS=1

# -- feature configuration ------------------------------------------------------------------------
ALL_FEATURES_BUT_ASYNC := --features concurrent,executable,metal,testing,with-debug-info,internal
ALL_FEATURES_BUT_ASYNC := --features concurrent,executable,metal,testing,internal

# Workspace-wide test features
WORKSPACE_TEST_FEATURES := concurrent,testing,metal,executable
Expand All @@ -51,8 +51,7 @@ FEATURES_core :=
FEATURES_miden-vm := concurrent,executable,metal,internal
FEATURES_processor := concurrent,testing,bus-debugger
FEATURES_prover := concurrent,metal
FEATURES_libcore := with-debug-info
FEATURES_verifier :=
FEATURES_libcore :=FEATURES_verifier :=

# -- linting --------------------------------------------------------------------------------------

Expand Down
1 change: 1 addition & 0 deletions crates/assembly/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,6 @@ thiserror.workspace = true
miden-assembly = { path = ".", default-features = false, features = ["testing"] }
miden-mast-package = { workspace = true, features = ["arbitrary"] }
miden-libcore = { path = "../../libcore", default-features = false }
miden-processor = { workspace = true, features = ["testing"] }
insta.workspace = true
proptest = { workspace = true, features = ["std"] }
6 changes: 3 additions & 3 deletions crates/assembly/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ shown below:
# use std::sync::Arc;
#
// Instantiate the assembler in debug mode
let assembler = Assembler::new(Arc::new(DefaultSourceManager::default())).with_debug_mode(true);
let assembler = Assembler::new(Arc::new(DefaultSourceManager::default()));
```

## Putting it all together
Expand All @@ -206,8 +206,8 @@ let kernel_lib = Assembler::new(source_manager.clone())

// Instantiate the assembler with multiple options at once
let assembler = Assembler::with_kernel(source_manager, kernel_lib)
.with_debug_mode(true)
.with_dynamic_library(&CoreLibrary::default())
.with_dynamic_library(&CoreLibrary::default()) .with_dynamic_library(&StdLibrary::default())
>>>>>>> 1d3ff0866 (Improve tests for always-enabled debug mode after issue #1821)
.unwrap();

// Assemble our program
Expand Down
74 changes: 26 additions & 48 deletions crates/assembly/src/assembler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,6 @@ pub struct Assembler {
linker: Linker,
/// Whether to treat warning diagnostics as errors
warnings_as_errors: bool,
/// Whether the assembler enables extra debugging information.
in_debug_mode: bool,
}

impl Default for Assembler {
Expand All @@ -98,7 +96,6 @@ impl Default for Assembler {
source_manager,
linker,
warnings_as_errors: false,
in_debug_mode: false,
}
}
}
Expand All @@ -113,7 +110,6 @@ impl Assembler {
source_manager,
linker,
warnings_as_errors: false,
in_debug_mode: false,
}
}

Expand All @@ -135,17 +131,6 @@ impl Assembler {
self.warnings_as_errors = yes;
self
}

/// Puts the assembler into the debug mode.
pub fn with_debug_mode(mut self, yes: bool) -> Self {
self.in_debug_mode = yes;
self
}

/// Sets the debug mode flag of the assembler
pub fn set_debug_mode(&mut self, yes: bool) {
self.in_debug_mode = yes;
}
}

// ------------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -326,11 +311,6 @@ impl Assembler {
self.warnings_as_errors
}

/// Returns true if this assembler was instantiated in debug mode.
pub fn in_debug_mode(&self) -> bool {
self.in_debug_mode
}

/// Returns a reference to the kernel for this assembler.
///
/// If the assembler was instantiated without a kernel, the internal kernel will be empty.
Expand Down Expand Up @@ -912,6 +892,20 @@ impl Assembler {
Ok(proc_ctx.into_procedure(proc_body_node.digest(), proc_body_id))
}

/// Creates an assembly operation decorator for control flow nodes.
fn create_asmop_decorator(
&self,
span: &SourceSpan,
op_name: &str,
proc_ctx: &ProcedureContext,
) -> AssemblyOp {
let location = proc_ctx.source_manager().location(*span).ok();
let context_name = proc_ctx.path().to_string();
let num_cycles = 0;
let should_break = false;
AssemblyOp::new(location, context_name, num_cycles, op_name.to_string(), should_break)
}

fn compile_body<'a, I>(
&self,
body: I,
Expand Down Expand Up @@ -969,20 +963,12 @@ impl Assembler {
split_builder.append_before_enter(decorator_ids);
}

// Add an assembly operation decorator to the if node in debug mode.
if self.in_debug_mode() {
let location = proc_ctx.source_manager().location(*span).ok();
let context_name = proc_ctx.path().to_string();
let num_cycles = 0;
let op = "if.true".to_string();
let should_break = false;
let op =
AssemblyOp::new(location, context_name, num_cycles, op, should_break);
let decorator_id = block_builder
.mast_forest_builder_mut()
.ensure_decorator(Decorator::AsmOp(op))?;
split_builder.append_before_enter([decorator_id]);
}
// Add an assembly operation decorator to the if node.
let op = self.create_asmop_decorator(span, "if.true", proc_ctx);
let decorator_id = block_builder
.mast_forest_builder_mut()
.ensure_decorator(Decorator::AsmOp(op))?;
split_builder.append_before_enter([decorator_id]);

let split_node_id =
block_builder.mast_forest_builder_mut().ensure_node(split_builder)?;
Expand Down Expand Up @@ -1040,20 +1026,12 @@ impl Assembler {
loop_builder.append_before_enter(decorator_ids);
}

// Add an assembly operation decorator to the loop node in debug mode.
if self.in_debug_mode() {
let location = proc_ctx.source_manager().location(*span).ok();
let context_name = proc_ctx.path().to_string();
let num_cycles = 0;
let op = "while.true".to_string();
let should_break = false;
let op =
AssemblyOp::new(location, context_name, num_cycles, op, should_break);
let decorator_id = block_builder
.mast_forest_builder_mut()
.ensure_decorator(Decorator::AsmOp(op))?;
loop_builder.append_before_enter([decorator_id]);
}
// Add an assembly operation decorator to the loop node.
let op = self.create_asmop_decorator(span, "while.true", proc_ctx);
let decorator_id = block_builder
.mast_forest_builder_mut()
.ensure_decorator(Decorator::AsmOp(op))?;
loop_builder.append_before_enter([decorator_id]);

let loop_node_id =
block_builder.mast_forest_builder_mut().ensure_node(loop_builder)?;
Expand Down
61 changes: 27 additions & 34 deletions crates/assembly/src/instruction/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,38 +45,36 @@ impl Assembler {
// Always collect decorators into a single Vec; it will remain empty if not needed.
let mut decorators = Vec::new();

if self.in_debug_mode() {
// if the assembler is in debug mode, start tracking the instruction about to be
// executed; this will allow us to map the instruction to the sequence of
// operations which were executed as a part of this instruction.
block_builder.track_instruction(instruction, proc_ctx)?;

// New node is being created, so we are done building the current block. We then want to
// add the assembly operation to the new node - for example call, dyncall, if/else
// statements, loops, etc. However, `exec` instructions are compiled away and not
// added to the trace, so we should ignore them. Theoretically, we
// could probably add them anyways, but it currently breaks the
// `VmStateIterator`.
if can_create_node
&& !matches!(instruction.inner(), Instruction::Exec(_))
&& let Some(asm_op_id) = block_builder.set_instruction_cycle_count()
{
// Set the cycle count for this assembly op to 1
let assembly_op = &mut block_builder.mast_forest_builder_mut()[asm_op_id];
match assembly_op {
Decorator::AsmOp(op) => op.set_num_cycles(1),
_ => panic!("expected AsmOp decorator"),
}
decorators.push(asm_op_id);
// Start tracking the instruction about to be executed; this will allow us to map the
// instruction to the sequence of operations which were executed as a part of this
// instruction.
block_builder.track_instruction(instruction, proc_ctx)?;

// New node is being created, so we are done building the current block. We then want to
// add the assembly operation to the new node - for example call, dyncall, if/else
// statements, loops, etc. However, `exec` instructions are compiled away and not
// added to the trace, so we should ignore them. Theoretically, we
// could probably add them anyways, but it currently breaks the
// `VmStateIterator`.
if can_create_node
&& !matches!(instruction.inner(), Instruction::Exec(_))
&& let Some(asm_op_id) = block_builder.set_instruction_cycle_count()
{
// Set the cycle count for this assembly op to 1
let assembly_op = &mut block_builder.mast_forest_builder_mut()[asm_op_id];
match assembly_op {
Decorator::AsmOp(op) => op.set_num_cycles(1),
_ => panic!("expected AsmOp decorator"),
}
decorators.push(asm_op_id);
}

// Compile the instruction, passing the decorators (which may be empty).
let opt_new_node_id =
self.compile_instruction_impl(instruction, block_builder, proc_ctx, decorators)?;

// If we're in debug mode but didn't create a node, set the cycle count after compilation.
if self.in_debug_mode() && !can_create_node {
// If we didn't create a node, set the cycle count after compilation.
if !can_create_node {
let _ = block_builder.set_instruction_cycle_count();
}

Expand Down Expand Up @@ -580,18 +578,13 @@ impl Assembler {

// ----- debug decorators -------------------------------------------------------------
Instruction::Breakpoint => {
if self.in_debug_mode() {
block_builder.push_op(Noop);
block_builder.track_instruction(instruction, proc_ctx)?;
}
block_builder.push_op(Noop);
block_builder.track_instruction(instruction, proc_ctx)?;
},

Instruction::Debug(options) => {
if self.in_debug_mode() {
block_builder.push_decorator(Decorator::Debug(debug::compile_options(
options, proc_ctx,
)?))?;
}
block_builder
.push_decorator(Decorator::Debug(debug::compile_options(options, proc_ctx)?))?;
},

// ----- emit instruction -------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
source: crates/assembly/src/tests.rs
assertion_line: 2803
expression: program
---
begin
Expand All @@ -8,9 +9,11 @@ begin
push(4294967294)
mstore
drop
asmOp(adv.has_mapkey, 3)
push(5642583036089175977)
emit
drop
asmOp(assert, 1)
assert(0)
end
end
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
source: crates/assembly/src/tests.rs
assertion_line: 2773
expression: program
---
begin
Expand All @@ -8,15 +9,18 @@ begin
push(4294967294)
mstore
drop
asmOp(push.[2,2,2,2], 4)
push(2)
push(2)
push(2)
push(2)
noop
noop
asmOp(adv.push_mapval, 3)
push(17843484659000820118)
emit
drop
asmOp(assert, 1)
assert(0)
end
end
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
source: crates/assembly/src/tests.rs
assertion_line: 2788
expression: program
---
begin
Expand All @@ -8,15 +9,18 @@ begin
push(4294967294)
mstore
drop
asmOp(push.[3846236276142386450,5034591595140902852,4565868838168209231,6740431856120851931], 4)
push(3846236276142386450)
push(5034591595140902852)
push(4565868838168209231)
push(6740431856120851931)
noop
noop
asmOp(adv.push_mapval, 3)
push(17843484659000820118)
emit
drop
asmOp(assert, 1)
assert(0)
end
end
Loading