Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tracking PR for v0.11.0 release #1472

Merged
merged 115 commits into from
Nov 5, 2024
Merged
Changes from 5 commits
Commits
Show all changes
115 commits
Select commit Hold shift + click to select a range
07134e3
chore: remove callset from `Procedure` (#1470)
plafer Aug 27, 2024
d7c8933
chore: Add warning about `no_std` environment (#1471)
plafer Aug 27, 2024
b192c61
refactor: wrap MastForest in Program and Library in Arc (#1465)
bobbinth Aug 27, 2024
6523811
`Assembler::invoke`: no longer returns an `Option`
plafer Aug 27, 2024
4c77063
`MastForestBuilder`: `ensure_node` -> `add_node`
plafer Aug 27, 2024
bc5cb74
`Library`: use `MastNodeId` as unique identifier for procedures
plafer Aug 27, 2024
7272a55
fix tests
plafer Aug 28, 2024
725eff5
add failing test
plafer Aug 28, 2024
62b4c52
use `MastNodeId` to identify procedures in ModuleGraph
plafer Aug 28, 2024
72a7093
ProcedureInfo: store `body_node_id`
plafer Aug 28, 2024
30d2933
`ResolvedProcedure`: store body_id when present
plafer Aug 28, 2024
c678944
create a new root node on exec
plafer Aug 28, 2024
a352fa2
Revert "ProcedureInfo: store `body_node_id`"
plafer Aug 28, 2024
5ae4fd5
fix build after `ProcedureInfo` revert
plafer Aug 28, 2024
de51e2c
Remove `ResolvedProcedure::BodyNodeId`
plafer Aug 28, 2024
03471eb
`Assembler::resolve_target` returns `Either<MastNodeId, RpoDigest>`
plafer Aug 28, 2024
bc045b6
fix failing test
plafer Aug 28, 2024
67a061a
fmt
plafer Aug 28, 2024
a3c5d8c
add back map digest -> GID to mast forest builder
plafer Aug 28, 2024
b45d459
`MastForestBuilder`: change all `ensure_*` to `add_*`
plafer Aug 28, 2024
961d6f6
fix regression
plafer Aug 28, 2024
a4cb422
fix failing test
plafer Aug 29, 2024
0665cf5
changelog
plafer Aug 29, 2024
ef307c2
docs
plafer Aug 29, 2024
cccf018
docs
plafer Aug 29, 2024
883356a
add test `ensure_unique_node_ids_for_identical_procedures`
plafer Aug 29, 2024
ecec03b
cleanup `MastForestBuilder`
plafer Aug 29, 2024
aa04649
remove `ensure_unique_node_ids_for_identical_procedures` test
plafer Aug 29, 2024
72a482b
`MastForestBuilder::eq_hash()`
plafer Aug 29, 2024
e18c4e7
`MastForestBuilder`: digest -> mast_root
plafer Aug 29, 2024
4a46d32
`MastForestBuilder`: don't duplicate equal nodes
plafer Aug 29, 2024
d959dd6
revert changes to tests
plafer Aug 29, 2024
187db6b
invoke: don't create new node needlessly
plafer Aug 29, 2024
53003b5
fix test
plafer Aug 29, 2024
126931e
fix docs
plafer Aug 29, 2024
45539ed
fmt
plafer Aug 29, 2024
ded33b4
cleanup `Assembler::invoke`
plafer Aug 29, 2024
c5e6b8b
remove stale TODOs
plafer Aug 29, 2024
485cbc8
fix doc tests
plafer Aug 29, 2024
191404a
fix no_std
plafer Aug 29, 2024
5b3285e
`TestContext`: don't use debug mode by default
plafer Aug 30, 2024
f141c76
fix asmop hash
plafer Aug 30, 2024
8dd1662
Remove redundant comments
plafer Sep 3, 2024
ca2d6d1
revert comment change
plafer Sep 3, 2024
1b619e6
fix docstring
plafer Sep 3, 2024
a30a9c7
`Library::new()`: check that every procedures are indeed exports
plafer Sep 3, 2024
3b280f1
rename `procedure_root_digest`
plafer Sep 3, 2024
41f45d4
fix docs
plafer Sep 3, 2024
ed09c6c
refactor `Assembler::resolve_target()`
plafer Sep 3, 2024
2125923
split `Assembler::get_proc_root_id_from_mast_root`
plafer Sep 3, 2024
d294d20
`Assembler::resolve_target` docstring
plafer Sep 3, 2024
43185ec
fmt
plafer Sep 3, 2024
4c139bb
`invoke`: document
plafer Sep 3, 2024
dd72f68
fmt
plafer Sep 3, 2024
72b9fe5
add `unwrap()` comment
plafer Sep 3, 2024
8243fa2
fmt
plafer Sep 3, 2024
4eeeb03
adjust `Assembler::invoke()` comment
plafer Sep 3, 2024
2ffd050
fix `Assembler::ensure_valid_procedure_mast_root`
plafer Sep 3, 2024
9b74a8b
cleanup proc alias
plafer Sep 3, 2024
245022e
fmt
plafer Sep 3, 2024
f7d179e
Merge pull request #1473 from 0xPolygonMiden/plafer-mast-forest-build…
bitwalker Sep 4, 2024
b4e84a5
fix(assembly): properly indent first op in nested blocks
bitwalker Sep 5, 2024
1b4609e
Merge pull request #1481 from 0xPolygonMiden/bitwalker/masm-pretty-pr…
bitwalker Sep 5, 2024
0ce2fe5
feat: add no_std once primitive for stdlib deserialization (#1463)
sergerad Sep 6, 2024
2c46076
feat: improve handling of u32 operations (#1480)
bitwalker Sep 7, 2024
4ba0c53
Plafer 1122 fix decorators (#1466)
plafer Sep 11, 2024
492ce81
Simplify `batch_ops()` (#1492)
plafer Sep 12, 2024
19b5643
Merge branch 'main' into next
bobbinth Sep 13, 2024
dcde6d1
chore: fix lint
bobbinth Sep 13, 2024
f06923b
Fix operation batch flags constraints (#1495)
plafer Sep 17, 2024
9a1c34f
feat: introduce `Emit` instruction
plafer Sep 13, 2024
0b1c2f6
feat: remove `Decorator::Event`
plafer Sep 13, 2024
354052b
docs: fix docs after adding emit instruction
plafer Sep 17, 2024
0e2d4c4
fix: move push instruction to degree 5 flags
plafer Sep 18, 2024
080597b
Merge pull request #1496 from 0xPolygonMiden/plafer-1457-emit-instr
plafer Sep 18, 2024
097f76d
Documentation fixes (#1506)
PhilippGackstatter Sep 23, 2024
8e9fe06
fix: fix block hash table construction and docs (#1509)
plafer Sep 24, 2024
c6e2bc8
feat: enable specifying debug mode via cli option (#1502)
yasonk Sep 24, 2024
8762dae
feat: implement procedure annotation syntax
bitwalker Sep 23, 2024
7ee5170
fix: block stack table (#1511)
plafer Sep 25, 2024
be14f5b
fix: make chiplets vtable only use current row
plafer Sep 26, 2024
6f60f74
Merge pull request #1514 from 0xPolygonMiden/plafer-1389-fix-chiplets…
plafer Sep 26, 2024
f2b9161
Merge pull request #1510 from 0xPolygonMiden/bitwalker/annotations
bitwalker Sep 27, 2024
5085999
fix: bug in chiplet bus (#1516)
Al-Kindi-0 Oct 1, 2024
b2c5215
refactor: restrict the number of stack inputs and outputs to 16 (#1456)
Fumuran Oct 3, 2024
a898596
fix: fix block stack table dealing of RESPAN
plafer Oct 2, 2024
8d06221
Merge pull request #1512 from 0xPolygonMiden/plafer-fix-block-stack-t…
plafer Oct 3, 2024
b648a8a
chore: simplify requests hasher (#1524)
Al-Kindi-0 Oct 4, 2024
5dc5c2e
chore: fix lifetime lints
bobbinth Oct 4, 2024
f92a463
fix: simplify chiplets bus hasher chiplet (#1525)
plafer Oct 7, 2024
b2294a1
Update the stack documentation (#1530)
Fumuran Oct 17, 2024
2a97d8d
fix: `Program` deserialization (#1543)
Fumuran Oct 22, 2024
25f9382
docs: document how call and syscall work
plafer Oct 16, 2024
8029102
Merge pull request #1536 from 0xPolygonMiden/plafer-483-docs
plafer Oct 23, 2024
62a113e
chore: disable chiplets aux columns check (#1546)
plafer Oct 23, 2024
ae34c56
refactor: migrate to new padding rule (#1343)
Al-Kindi-0 Oct 24, 2024
dc41735
chore: remove dependabot, add issue templates
bobbinth Oct 28, 2024
9f9cc63
feat: implement `MastForest` merging (#1534)
PhilippGackstatter Oct 28, 2024
db71e28
Rename `EqHash` to `MastNodeFingerprint` (#1539)
PhilippGackstatter Oct 29, 2024
12dd5e5
fix: blake example (#1553)
Al-Kindi-0 Oct 29, 2024
fc46c04
fix: fix kernel ROM multiset check
plafer Oct 30, 2024
34ea043
Merge pull request #1556 from 0xPolygonMiden/plafer-1545-fix-kernel-rom
plafer Oct 30, 2024
6bbee60
feat: `DYN` takes a memory address instead of digest on stack
plafer Oct 15, 2024
550668c
feat: add dyncall operation
plafer Oct 18, 2024
7f469c4
docs: update docs for dyn and dyncall
plafer Oct 23, 2024
a30bc62
fix: block stack table construction
plafer Oct 30, 2024
766292d
Merge pull request #1557 from 0xPolygonMiden/plafer-fix-block-stack-t…
plafer Oct 31, 2024
2b96b85
Merge pull request #1535 from 0xPolygonMiden/plafer-1091-dyn-op-rework
plafer Nov 1, 2024
f1c0553
Permit child `MastNodeId`s to exceed the `MastNodeId`s of their paren…
PhilippGackstatter Nov 1, 2024
1ea1e1e
chore: migrate to winterfell v0.10 (#1533)
Al-Kindi-0 Nov 3, 2024
a82a174
feat: make prover conditionally asynchronous (#1563)
bobbinth Nov 3, 2024
ce26595
docs: fix typos (#1500)
cratiu222 Nov 4, 2024
60a5f37
chore: add the string that failed validation to `IdentError::InvalidC…
greenhat Nov 4, 2024
e3fa9ec
fix: on Library deserialization, use unchecked constructor for proced…
greenhat Nov 4, 2024
0a9344c
chore: update crate versions to v0.11.0
bobbinth Nov 5, 2024
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
@@ -9,6 +9,7 @@
- Added `miden_core::utils::sync::racy_lock` module (#1463).
- Updated `miden_core::utils` to re-export `std::sync::LazyLock` and `racy_lock::RacyLock as LazyLock` for std and no_std environments, respectively (#1463).
- Made the undocumented behavior of the VM with regard to undefined behavior of u32 operations, stricter (#1480)
- Introduced the `Emit` instruction (#1496)

#### Fixes

9 changes: 5 additions & 4 deletions air/src/constraints/stack/op_flags/mod.rs
Original file line number Diff line number Diff line change
@@ -267,7 +267,7 @@ impl<E: FieldElement> OpFlags<E> {

// degree 6 flags do not use the first two bits (op_bits[0], op_bits[1])
degree4_op_flags[0] = not_2_not_3; // MRUPDATE
degree4_op_flags[1] = yes_2_not_3; // PUSH
degree4_op_flags[1] = yes_2_not_3; // (unused)
degree4_op_flags[2] = not_2_yes_3; // SYSCALL
degree4_op_flags[3] = yes_2_yes_3; // CALL

@@ -292,6 +292,7 @@ impl<E: FieldElement> OpFlags<E> {
+ degree5_op_flags[1] // MPVERIFY
+ degree5_op_flags[6] // SPAN
+ degree5_op_flags[7] // JOIN
+ degree5_op_flags[10] // EMIT
+ degree4_op_flags[6] // RESPAN
+ degree4_op_flags[7] // HALT
+ degree4_op_flags[3] // CALL
@@ -375,7 +376,7 @@ impl<E: FieldElement> OpFlags<E> {
+ degree7_op_flags[22]
+ degree7_op_flags[26];

right_shift_flags[0] = f011 + degree4_op_flags[1] + movupn_flag;
right_shift_flags[0] = f011 + degree5_op_flags[11] + movupn_flag; // degree 5: PUSH

right_shift_flags[1] = right_shift_flags[0] + degree6_op_flags[4]; // degree 6: U32SPLIT

@@ -395,7 +396,7 @@ impl<E: FieldElement> OpFlags<E> {
right_shift_flags[15] = right_shift_flags[8];

// Flag if the stack has been shifted to the right.
let right_shift = f011 + degree4_op_flags[1] + degree6_op_flags[4]; // PUSH; U32SPLIT
let right_shift = f011 + degree5_op_flags[11] + degree6_op_flags[4]; // PUSH; U32SPLIT

// Flag if the stack has been shifted to the left.
let left_shift =
@@ -907,7 +908,7 @@ impl<E: FieldElement> OpFlags<E> {
/// Operation Flag of PUSH operation.
#[inline(always)]
pub fn push(&self) -> E {
self.degree4_op_flags[get_op_index(Operation::Push(ONE).op_code())]
self.degree5_op_flags[get_op_index(Operation::Push(ONE).op_code())]
}

/// Operation Flag of CALL operation.
5 changes: 3 additions & 2 deletions air/src/constraints/stack/op_flags/tests.rs
Original file line number Diff line number Diff line change
@@ -144,7 +144,8 @@ fn degree_4_op_flags() {
fn composite_flags() {
// ------ no change 0 ---------------------------------------------------------------------

let op_no_change_0 = [Operation::MpVerify(0), Operation::Span, Operation::Halt];
let op_no_change_0 =
[Operation::MpVerify(0), Operation::Span, Operation::Halt, Operation::Emit(42)];
for op in op_no_change_0 {
// frame initialised with an op operation.
let frame = generate_evaluation_frame(op.op_code().into());
@@ -168,7 +169,7 @@ fn composite_flags() {
assert_eq!(op_flags.left_shift(), ZERO);
assert_eq!(op_flags.top_binary(), ZERO);

if op == Operation::MpVerify(0) {
if op == Operation::MpVerify(0) || op == Operation::Emit(42) {
assert_eq!(op_flags.control_flow(), ZERO);
} else if op == Operation::Span || op == Operation::Halt {
assert_eq!(op_flags.control_flow(), ONE);
4 changes: 2 additions & 2 deletions air/src/trace/main_trace.rs
Original file line number Diff line number Diff line change
@@ -259,8 +259,8 @@ impl MainTrace {
[b6, b5, b4] == [ZERO, ONE, ONE]||
// u32SPLIT 100_1000
([b6, b5, b4, b3, b2, b1, b0] == [ONE, ZERO, ZERO, ONE, ZERO, ZERO, ZERO]) ||
// PUSH i.e., 110_0100
([b6, b5, b4, b3, b2, b1, b0] == [ONE, ONE, ZERO, ZERO, ONE, ZERO, ZERO])
// PUSH i.e., 101_1011
([b6, b5, b4, b3, b2, b1, b0] == [ONE, ZERO, ONE, ONE, ZERO, ONE, ONE])
}

// STACK COLUMNS
2 changes: 1 addition & 1 deletion assembly/src/assembler/instruction/mod.rs
Original file line number Diff line number Diff line change
@@ -432,7 +432,7 @@ impl Assembler {

// ----- emit instruction -------------------------------------------------------------
Instruction::Emit(event_id) => {
block_builder.push_decorator(Decorator::Event(event_id.expect_value()))?;
block_builder.push_op(Operation::Emit(event_id.expect_value()));
},

// ----- trace instruction ------------------------------------------------------------
37 changes: 37 additions & 0 deletions assembly/src/assembler/tests.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use alloc::vec::Vec;

use pretty_assertions::assert_eq;
use vm_core::{
assert_matches,
crypto::hash::RpoDigest,
mast::{MastForest, MastNode},
Program,
};
@@ -158,6 +161,40 @@ fn nested_blocks() -> Result<(), Report> {
Ok(())
}

/// Ensures that the arguments of `emit` do indeed modify the digest of a basic block
#[test]
fn emit_instruction_digest() {
let context = TestContext::new();

let program_source = r#"
proc.foo
emit.1
end

proc.bar
emit.2
end

begin
# specific impl irrelevant
exec.foo
exec.bar
end
"#;

let program = context.assemble(program_source).unwrap();

let procedure_digests: Vec<RpoDigest> = program.mast_forest().procedure_digests().collect();

// foo, bar and entrypoint
assert_eq!(3, procedure_digests.len());

// Ensure that foo, bar and entrypoint all have different digests
assert_ne!(procedure_digests[0], procedure_digests[1]);
assert_ne!(procedure_digests[0], procedure_digests[2]);
assert_ne!(procedure_digests[1], procedure_digests[2]);
}

/// Since `foo` and `bar` have the same body, we only expect them to be added once to the program.
#[test]
fn duplicate_procedure() {
2 changes: 1 addition & 1 deletion assembly/src/tests.rs
Original file line number Diff line number Diff line change
@@ -1180,7 +1180,7 @@ fn decorators_external() -> TestResult {
let expected = "\
begin
trace(0)
external.0x178d0a56b911f3eb23bbf18fb9f130130ba0c5d321e420610f64bb41790ca070
external.0xe776df8dc02329acc43a09fe8e510b44a87dfd876e375ad383891470ece4f6de
trace(1)
end";
let program = Assembler::new(context.source_manager())
10 changes: 5 additions & 5 deletions core/src/mast/node/basic_block_node/tests.rs
Original file line number Diff line number Diff line change
@@ -300,11 +300,11 @@ fn operation_or_decorator_iterator() {

// Note: there are 2 decorators after the last instruction
let decorators = vec![
(0, Decorator::Event(0)), // ID: 0
(0, Decorator::Event(1)), // ID: 1
(3, Decorator::Event(2)), // ID: 2
(4, Decorator::Event(3)), // ID: 3
(4, Decorator::Event(4)), // ID: 4
(0, Decorator::Trace(0)), // ID: 0
(0, Decorator::Trace(1)), // ID: 1
(3, Decorator::Trace(2)), // ID: 2
(4, Decorator::Trace(3)), // ID: 3
(4, Decorator::Trace(4)), // ID: 4
];

let node =
9 changes: 1 addition & 8 deletions core/src/mast/serialization/decorator.rs
Original file line number Diff line number Diff line change
@@ -178,11 +178,6 @@ impl DecoratorInfo {

Ok(Decorator::Debug(DebugOptions::LocalInterval(start, second, end)))
},
EncodedDecoratorVariant::Event => {
let value = data_reader.read_u32()?;

Ok(Decorator::Event(value))
},
EncodedDecoratorVariant::Trace => {
let value = data_reader.read_u32()?;

@@ -245,7 +240,6 @@ pub enum EncodedDecoratorVariant {
DebugOptionsMemAll,
DebugOptionsMemInterval,
DebugOptionsLocalInterval,
Event,
Trace,
}

@@ -298,7 +292,6 @@ impl From<&Decorator> for EncodedDecoratorVariant {
DebugOptions::MemInterval(..) => Self::DebugOptionsMemInterval,
DebugOptions::LocalInterval(..) => Self::DebugOptionsLocalInterval,
},
Decorator::Event(_) => Self::Event,
Decorator::Trace(_) => Self::Trace,
}
}
@@ -432,7 +425,7 @@ impl DecoratorDataBuilder {
},
DebugOptions::StackAll | DebugOptions::MemAll => None,
},
Decorator::Event(value) | Decorator::Trace(value) => {
Decorator::Trace(value) => {
self.decorator_data.extend(value.to_le_bytes());

Some(data_offset)
6 changes: 3 additions & 3 deletions core/src/mast/serialization/tests.rs
Original file line number Diff line number Diff line change
@@ -104,9 +104,10 @@ fn confirm_operation_and_decorator_structure() {
Operation::MrUpdate => (),
Operation::FriE2F4 => (),
Operation::RCombBase => (),
Operation::Emit(_) => (),
};

match Decorator::Event(0) {
match Decorator::Trace(0) {
Decorator::Advice(advice) => match advice {
AdviceInjector::MerkleNodeMerge => (),
AdviceInjector::MerkleNodeToStack => (),
@@ -136,7 +137,6 @@ fn confirm_operation_and_decorator_structure() {
DebugOptions::MemInterval(..) => (),
DebugOptions::LocalInterval(..) => (),
},
Decorator::Event(_) => (),
Decorator::Trace(_) => (),
};
}
@@ -236,6 +236,7 @@ fn serialize_deserialize_all_nodes() {
Operation::MrUpdate,
Operation::FriE2F4,
Operation::RCombBase,
Operation::Emit(42),
];

let num_operations = operations.len();
@@ -288,7 +289,6 @@ fn serialize_deserialize_all_nodes() {
(15, Decorator::Debug(DebugOptions::MemAll)),
(15, Decorator::Debug(DebugOptions::MemInterval(0, 16))),
(17, Decorator::Debug(DebugOptions::LocalInterval(1, 2, 3))),
(num_operations, Decorator::Event(45)),
(num_operations, Decorator::Trace(55)),
];

4 changes: 0 additions & 4 deletions core/src/operations/decorators/mod.rs
Original file line number Diff line number Diff line change
@@ -35,8 +35,6 @@ pub enum Decorator {
/// Prints out information about the state of the VM based on the specified options. This
/// decorator is executed only in debug mode.
Debug(DebugOptions),
/// Emits an event to the host.
Event(u32),
/// Emits a trace to the host.
Trace(u32),
}
@@ -60,7 +58,6 @@ impl Decorator {
Blake3_256::hash(&bytes_to_hash)
},
Self::Debug(debug) => Blake3_256::hash(debug.to_string().as_bytes()),
Self::Event(event) => Blake3_256::hash(&event.to_le_bytes()),
Self::Trace(trace) => Blake3_256::hash(&trace.to_le_bytes()),
}
}
@@ -80,7 +77,6 @@ impl fmt::Display for Decorator {
write!(f, "asmOp({}, {})", assembly_op.op(), assembly_op.num_cycles())
},
Self::Debug(options) => write!(f, "debug({options})"),
Self::Event(event_id) => write!(f, "event({})", event_id),
Self::Trace(trace_id) => write!(f, "trace({})", trace_id),
}
}
29 changes: 25 additions & 4 deletions core/src/operations/mod.rs
Original file line number Diff line number Diff line change
@@ -109,9 +109,11 @@ pub(super) mod opcode_constants {
pub const OPCODE_JOIN: u8 = 0b0101_0111;
pub const OPCODE_DYN: u8 = 0b0101_1000;
pub const OPCODE_RCOMBBASE: u8 = 0b0101_1001;
pub const OPCODE_EMIT: u8 = 0b0101_1010;
pub const OPCODE_PUSH: u8 = 0b0101_1011;

pub const OPCODE_MRUPDATE: u8 = 0b0110_0000;
pub const OPCODE_PUSH: u8 = 0b0110_0100;
/* unused: 0b0110_0100 */
pub const OPCODE_SYSCALL: u8 = 0b0110_1000;
pub const OPCODE_CALL: u8 = 0b0110_1100;
pub const OPCODE_END: u8 = 0b0111_0000;
@@ -156,6 +158,16 @@ pub enum Operation {
/// instruction.
Clk = OPCODE_CLK,

/// Emits an event id (`u32` value) to the host.
///
/// We interpret the event id as follows:
/// - 16 most significant bits identify the event source,
/// - 16 least significant bits identify the actual event.
///
/// Similar to Noop, this operation does not change the state of user stack. The immediate
/// value affects the program MAST root computation.
Emit(u32) = OPCODE_EMIT,

// ----- flow control operations -------------------------------------------------------------
/// Marks the beginning of a join block.
Join = OPCODE_JOIN,
@@ -570,8 +582,9 @@ impl Operation {

/// Returns an immediate value carried by this operation.
pub fn imm_value(&self) -> Option<Felt> {
match self {
Self::Push(imm) => Some(*imm),
match *self {
Self::Push(imm) => Some(imm),
Self::Emit(imm) => Some(imm.into()),
_ => None,
}
}
@@ -718,6 +731,8 @@ impl fmt::Display for Operation {
Self::MStream => write!(f, "mstream"),
Self::Pipe => write!(f, "pipe"),

Self::Emit(value) => write!(f, "emit({value})"),

// ----- cryptographic operations -----------------------------------------------------
Self::HPerm => write!(f, "hperm"),
Self::MpVerify(err_code) => write!(f, "mpverify({err_code})"),
@@ -737,9 +752,10 @@ impl Serializable for Operation {
Operation::Assert(err_code)
| Operation::MpVerify(err_code)
| Operation::U32assert2(err_code) => {
err_code.to_le_bytes().write_into(target);
err_code.write_into(target);
},
Operation::Push(value) => value.as_int().write_into(target),
Operation::Emit(value) => value.write_into(target),

// Note: we explicitly write out all the operations so that whenever we make a
// modification to the `Operation` enum, we get a compile error here. This
@@ -947,6 +963,11 @@ impl Deserializable for Operation {

Self::Push(value_felt)
},
OPCODE_EMIT => {
let value = source.read_u32()?;

Self::Emit(value)
},
OPCODE_SYSCALL => Self::SysCall,
OPCODE_CALL => Self::Call,
OPCODE_END => Self::End,
Loading