Skip to content

Commit

Permalink
add initial swap support
Browse files Browse the repository at this point in the history
  • Loading branch information
WilfredTA committed Aug 3, 2023
1 parent 55c3861 commit fd3a6e2
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 18 deletions.
53 changes: 37 additions & 16 deletions src/instruction/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,19 @@ fn exec_dup_nth(mach: &EvmState, n: usize) -> MachineRecord<32> {
}
}

fn exec_swap_nth(mach: &EvmState, n: usize) -> MachineRecord<32> {


MachineRecord {
stack: Some(StackChange { pop_qty: 0, push_qty: 0, swap_depth: n as u8, ops: vec![] }),
pc: (mach.pc(), mach.pc() + 1),
mem: Default::default(),
halt: false,
storage: None,
constraints: None,
}
}

impl Instruction {
pub fn byte_size(&self) -> usize {
let inst_additional_size: usize = match self {
Expand Down Expand Up @@ -240,6 +253,7 @@ impl<'ctx> MachineInstruction<'ctx, 32> for Instruction {
let stack_change = StackChange {
pop_qty: 2,
push_qty: 1,
swap_depth: 0,
ops: vec![stack_op_1, stack_op_2, stack_op_3],
};
MachineRecord {
Expand Down Expand Up @@ -808,6 +822,7 @@ impl<'ctx> MachineInstruction<'ctx, 32> for Instruction {
let pc = mach.pc();
let stack_rec = StackChange {
pop_qty: 1,
swap_depth: 0,
push_qty: 0,
ops: vec![StackOp::Pop],
};
Expand Down Expand Up @@ -924,6 +939,7 @@ impl<'ctx> MachineInstruction<'ctx, 32> for Instruction {
let stack_rec = StackChange {
pop_qty: 2,
push_qty: 0,
swap_depth: 0,
ops: vec![StackOp::Pop, StackOp::Pop],
};
let storage_change = StorageChange {
Expand All @@ -945,10 +961,12 @@ impl<'ctx> MachineInstruction<'ctx, 32> for Instruction {
}
Instruction::Jump => {
let jump_dest = mach.stack().peek().unwrap();
eprintln!("JUMP DEST IN UNCONDITIONAL JUMP: {:#?}", jump_dest);
let jump_dest_concrete = jump_dest.as_ref().simplify().as_u64().unwrap() as usize;
let stack_rec = StackChange {
pop_qty: 1,
push_qty: 0,
swap_depth: 0,
ops: vec![StackOp::Pop]
};
MachineRecord {
Expand All @@ -971,6 +989,7 @@ impl<'ctx> MachineInstruction<'ctx, 32> for Instruction {

let stack_rec = StackChange {
pop_qty: 2,
swap_depth: 0,
push_qty: 0,
ops: vec![StackOp::Pop, StackOp::Pop],
};
Expand All @@ -988,6 +1007,7 @@ impl<'ctx> MachineInstruction<'ctx, 32> for Instruction {
let pc = BitVec::new_literal(mach.pc() as u64);
let stack_rec = StackChange {
pop_qty: 0,
swap_depth: 0,
push_qty: 1,
ops: vec![StackOp::Push(pc)],
};
Expand Down Expand Up @@ -1489,22 +1509,22 @@ impl<'ctx> MachineInstruction<'ctx, 32> for Instruction {
Instruction::Dup14 => exec_dup_nth(mach, 14),
Instruction::Dup15 => exec_dup_nth(mach, 15),
Instruction::Dup16 => exec_dup_nth(mach, 16),
Instruction::Swap1 => todo!(),
Instruction::Swap2 => todo!(),
Instruction::Swap3 => todo!(),
Instruction::Swap4 => todo!(),
Instruction::Swap5 => todo!(),
Instruction::Swap6 => todo!(),
Instruction::Swap7 => todo!(),
Instruction::Swap8 => todo!(),
Instruction::Swap9 => todo!(),
Instruction::Swap10 => todo!(),
Instruction::Swap11 => todo!(),
Instruction::Swap12 => todo!(),
Instruction::Swap13 => todo!(),
Instruction::Swap14 => todo!(),
Instruction::Swap15 => todo!(),
Instruction::Swap16 => todo!(),
Instruction::Swap1 => exec_dup_nth(mach, 1),
Instruction::Swap2 => exec_dup_nth(mach, 2),
Instruction::Swap3 => exec_dup_nth(mach, 3),
Instruction::Swap4 => exec_dup_nth(mach, 4),
Instruction::Swap5 => exec_dup_nth(mach, 5),
Instruction::Swap6 => exec_dup_nth(mach, 6),
Instruction::Swap7 => exec_dup_nth(mach, 7),
Instruction::Swap8 => exec_dup_nth(mach, 8),
Instruction::Swap9 => exec_dup_nth(mach, 9),
Instruction::Swap10 => exec_dup_nth(mach, 10),
Instruction::Swap11 => exec_dup_nth(mach, 11),
Instruction::Swap12 => exec_dup_nth(mach, 12),
Instruction::Swap13 => exec_dup_nth(mach, 13),
Instruction::Swap14 => exec_dup_nth(mach, 14),
Instruction::Swap15 => exec_dup_nth(mach, 15),
Instruction::Swap16 => exec_dup_nth(mach, 16),
Instruction::Log0 => todo!(),
Instruction::Log1 => todo!(),
Instruction::Log2 => todo!(),
Expand Down Expand Up @@ -1539,6 +1559,7 @@ impl<'ctx> MachineInstruction<'ctx, 32> for Instruction {
let stack_change = StackChange {
pop_qty: 0,
push_qty: 1,
swap_depth: 0,
ops: vec![StackOp::Push(bv.clone())],
};
let pc = mach.pc();
Expand Down
5 changes: 5 additions & 0 deletions src/record.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,14 @@ pub enum MemOp {
pub enum StackOp<const SZ: usize> {
Push(BitVec<SZ>),
Pop,
Swap(usize)
}

#[derive(Default, Clone, Debug)]
pub struct StackChange<const SZ: usize> {
pub pop_qty: u64,
pub push_qty: u64,
pub swap_depth: u8,
pub ops: Vec<StackOp<SZ>>,
}

Expand All @@ -52,6 +54,7 @@ impl<const SZ: usize> StackChange<SZ> {
Self {
pop_qty: 0,
push_qty: 1,
swap_depth: 0,
ops: vec![StackOp::Push(val)],
}
}
Expand All @@ -63,11 +66,13 @@ impl<const SZ: usize> StackChange<SZ> {
ops.iter().for_each(|op| match op {
StackOp::Push(_) => push_qty += 1,
StackOp::Pop => pop_qty += 1,
_ => ()
});

Self {
push_qty,
pop_qty,
swap_depth: 0,
ops,
}
}
Expand Down
50 changes: 48 additions & 2 deletions src/stack.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::record::StackChange;
use crate::{record::StackChange, bvi};
use std::fmt::{Debug, Formatter};

use super::smt::*;
Expand Down Expand Up @@ -27,21 +27,43 @@ impl<const SZ: usize> Stack<SZ> {
}

pub fn peek(&self) -> Option<&BitVec<SZ>> {
self.stack.last()
self.stack.get(self.size - 1)
}

pub fn size(&self) -> usize {
assert!(self.stack.len() == self.size);
self.stack.len()
}

// where n = 0 is top of the stack
pub fn peek_nth(&self, n: usize) -> Option<&BitVec<SZ>> {
if n >= self.size() {
return None;
}
self.stack.get(self.size - n - 1)
}

// where n is stack modulo top element;
pub (crate) fn swap_nth(&mut self, swap_depth: usize) {
if swap_depth < self.size() {
let mut new_stack = self.stack.clone();
let top_idx = self.size - 1;
let swap_idx = self.size - swap_depth - 1;
let top = self.peek().cloned().unwrap();
let swapped = self.peek_nth(swap_depth).cloned().expect(
&format!("stack too deep to swap with depth {}. Stack size: {}", swap_depth, self.size())
);
new_stack.remove(swap_idx);
new_stack.insert(swap_idx, top);
new_stack.pop();
new_stack.push(swapped);
self.stack = new_stack;

} else {
eprintln!("WILL NOT SWAP");
}
}

pub fn peek_top<const N: usize>(&self) -> Option<[&BitVec<SZ>; N]> {
if self.size() < N {
return None;
Expand All @@ -59,6 +81,7 @@ impl<const SZ: usize> MachineComponent for Stack<SZ> {
pop_qty,
push_qty,
ops,
swap_depth
} = rec;

let mut new_stack = self.clone();
Expand All @@ -67,10 +90,33 @@ impl<const SZ: usize> MachineComponent for Stack<SZ> {
crate::record::StackOp::Push(v) => new_stack.push(v.clone()),
crate::record::StackOp::Pop => {
new_stack.pop();
},
crate::record::StackOp::Swap(depth) => {

}
});

if swap_depth > 0 {
eprintln!("SWAP OCCURRING of DEPTH {}. STACK BEFORE: {:#?}", swap_depth, new_stack);
new_stack.swap_nth(swap_depth as usize);
eprintln!("STACK AFTER {:#?}", new_stack);
}

self.stack = new_stack.stack;
self.size = new_stack.size;
}
}


#[test]
fn test_swap() {
let mut stack: Stack<1> = Stack::default();
stack.push(bvi(1));
stack.push(bvi(2));
stack.push(bvi(3));
stack.push(bvi(4));
stack.swap_nth(2);
assert_eq!(stack.peek().cloned().unwrap(), bvi(2));
assert_eq!(stack.peek_nth(2).cloned().unwrap(), bvi(2));

}

0 comments on commit fd3a6e2

Please sign in to comment.