Skip to content

Commit

Permalink
refactor: improve readability of Program decoding
Browse files Browse the repository at this point in the history
  • Loading branch information
jan-ferdinand committed Oct 16, 2023
1 parent bcf61ee commit e3741d6
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 23 deletions.
9 changes: 9 additions & 0 deletions triton-vm/src/instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,15 @@ impl TryFrom<usize> for Instruction {
}
}

impl TryFrom<BFieldElement> for Instruction {
type Error = anyhow::Error;

fn try_from(opcode: BFieldElement) -> Result<Self> {
let opcode = u32::try_from(opcode)?;
opcode.try_into()
}
}

const fn all_instructions_without_args() -> [AnInstruction<BFieldElement>; Instruction::COUNT] {
[
Pop,
Expand Down
41 changes: 18 additions & 23 deletions triton-vm/src/program.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,33 +66,28 @@ impl BFieldCodec for Program {
let sequence = &sequence[1..];
ensure_eq!(program_length, sequence.len());

let mut idx = 0;
let mut read_idx = 0;
let mut instructions = Vec::with_capacity(program_length);
while idx < program_length {
let opcode: u32 = match sequence[idx].value().try_into() {
Ok(opcode) => opcode,
Err(_) => bail!("Invalid opcode {} at index {idx}.", sequence[idx].value()),
};
let instruction: Instruction = opcode.try_into()?;
if !instruction.has_arg() {
instructions.push(instruction);
} else if instructions.len() + 1 >= program_length {
bail!("Missing argument for instruction {instruction} at index {idx}.");
} else {
let instruction = match instruction.change_arg(sequence[idx + 1]) {
Some(instruction) => instruction,
None => {
bail!("Invalid argument for instruction {instruction} at index {idx}.")
}
};
// Instructions with argument are recorded twice to align the `instruction_pointer`.
instructions.push(instruction);
instructions.push(instruction);
while read_idx < program_length {
let opcode = sequence[read_idx];
let mut instruction: Instruction = opcode
.try_into()
.expect("Invalid opcode {opcode} at index {idx}.");
if instruction.has_arg() && instructions.len() + instruction.size() > program_length {
bail!("Missing argument for instruction {instruction} at index {read_idx}.");
}
if instruction.has_arg() {
let arg = sequence[read_idx + 1];
instruction = instruction
.change_arg(arg)
.expect("Invalid argument {arg} for instruction {instruction} at index {idx}.");
}
idx += instruction.size();

instructions.extend(vec![instruction; instruction.size()]);
read_idx += instruction.size();
}

ensure_eq!(idx, program_length);
ensure_eq!(read_idx, program_length);

Ok(Box::new(Program {
instructions,
Expand Down

0 comments on commit e3741d6

Please sign in to comment.