Skip to content

Commit c402569

Browse files
authored
bytecode: reorg (#18)
1 parent e9fcdce commit c402569

File tree

6 files changed

+467
-286
lines changed

6 files changed

+467
-286
lines changed

crates/vm/src/bytecode.rs

Lines changed: 0 additions & 286 deletions
This file was deleted.

crates/vm/src/bytecode/hint.rs

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
use std::{
2+
fmt,
3+
fmt::{Display, Formatter},
4+
};
5+
6+
use super::MemOrConstant;
7+
8+
/// Hints are special instructions for the prover to resolve non-determinism.
9+
///
10+
/// They are not part of the verified computation trace.
11+
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
12+
pub enum Hint {
13+
/// A hint for the prover to allocate a new memory segment for a function's stack frame.
14+
///
15+
/// This is the core mechanism for memory management in a VM without an `ap` (allocation pointer)
16+
/// register. The compiler pre-calculates the required memory size for each function.
17+
RequestMemory {
18+
/// The offset from `fp` where the pointer to the newly allocated segment will be stored.
19+
offset: usize,
20+
/// The requested size of the memory segment in scalar field elements.
21+
size: MemOrConstant,
22+
/// If true, the start of the allocated memory is aligned to an 8-element boundary
23+
/// to facilitate vectorized memory access for extension field operations.
24+
/// The value stored at `m[fp + offset]` will be the aligned address divided by 8.
25+
vectorized: bool,
26+
},
27+
/// A hint for the prover to compute the bit decomposition of a base field element.
28+
///
29+
/// This is a non-deterministic operation used for operations like range checks
30+
/// or other logic required by the XMSS signature scheme.
31+
DecomposeBits {
32+
/// The starting offset from `fp` where the resulting bits will be stored.
33+
res_offset: usize,
34+
/// The field element that needs to be decomposed into its bits.
35+
to_decompose: MemOrConstant,
36+
},
37+
/// A hint used for debugging to print values from memory during execution.
38+
Print {
39+
/// A string containing line information (e.g., file and line number) for context.
40+
line_info: String,
41+
/// A list of memory locations or constants whose values should be printed.
42+
content: Vec<MemOrConstant>,
43+
},
44+
/// A hint for the prover to compute the modular inverse of a field element.
45+
Inverse {
46+
/// The value to be inverted.
47+
arg: MemOrConstant,
48+
/// The offset from `fp` where the result (`arg^-1`) will be stored. If `arg` is zero, zero is stored.
49+
res_offset: usize,
50+
},
51+
}
52+
53+
impl Display for Hint {
54+
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
55+
match self {
56+
Self::RequestMemory {
57+
offset,
58+
size,
59+
vectorized,
60+
} => {
61+
write!(
62+
f,
63+
"m[fp + {offset}] = {}({size})",
64+
if *vectorized { "malloc_vec" } else { "malloc" }
65+
)
66+
}
67+
Self::DecomposeBits {
68+
res_offset,
69+
to_decompose,
70+
} => {
71+
write!(f, "m[fp + {res_offset}] = decompose_bits({to_decompose})")
72+
}
73+
Self::Print { line_info, content } => {
74+
write!(f, "print(")?;
75+
for (i, c) in content.iter().enumerate() {
76+
if i > 0 {
77+
write!(f, ", ")?;
78+
}
79+
write!(f, "{c}")?;
80+
}
81+
write!(f, ") for \"{line_info}\"")
82+
}
83+
Self::Inverse { arg, res_offset } => {
84+
write!(f, "m[fp + {res_offset}] = inverse({arg})")
85+
}
86+
}
87+
}
88+
}

0 commit comments

Comments
 (0)