Packing memory operations

This commit is contained in:
Daniel Lubarov 2022-08-03 22:54:17 -07:00
parent 9d3d3afeba
commit ccc4202de3
5 changed files with 92 additions and 1 deletions

View File

@ -25,6 +25,8 @@ pub(crate) fn combined_kernel() -> Kernel {
include_str!("asm/halt.asm"),
include_str!("asm/memory/core.asm"),
include_str!("asm/memory/memcpy.asm"),
include_str!("asm/memory/metadata.asm"),
include_str!("asm/memory/packing.asm"),
include_str!("asm/memory/txn_fields.asm"),
include_str!("asm/rlp/encode.asm"),
include_str!("asm/rlp/decode.asm"),

View File

@ -0,0 +1,45 @@
// Methods for encoding integers as bytes in memory, as well as the reverse,
// decoding bytes as integers. All big-endian.
global mload_packing:
// stack: context, segment, offset, len, retdest
// TODO
// stack: value
global mstore_unpacking:
// stack: context, segment, offset, value, len, retdest
// We will enumerate i in (32 - len)..32.
// That way BYTE(i, value) will give us the bytes we want.
DUP5 // len
PUSH 32
SUB
mstore_unpacking_loop:
// stack: i, context, segment, offset, value, len, retdest
// If i == 32, finish.
DUP1
%eq_const(32)
%jumpi(mstore_unpacking_finish)
// stack: i, context, segment, offset, value, len, retdest
DUP5 // value
DUP2 // i
BYTE
// stack: value[i], i, context, segment, offset, value, len, retdest
DUP5 DUP5 DUP5 // context, segment, offset
// stack: context, segment, offset, value[i], i, context, segment, offset, value, len, retdest
MSTORE_GENERAL
// stack: i, context, segment, offset, value, len, retdest
// Increment offset.
SWAP3 %add_const(1) SWAP3
// Increment i.
%add_const(1)
%jump(mstore_unpacking_loop)
mstore_unpacking_finish:
// stack: i, context, segment, offset, value, len, retdest
%pop6
// stack: retdest
JUMP

View File

@ -196,7 +196,7 @@ impl<'a> Interpreter<'a> {
0x17 => self.run_or(), // "OR",
0x18 => self.run_xor(), // "XOR",
0x19 => self.run_not(), // "NOT",
0x1a => todo!(), // "BYTE",
0x1a => self.run_byte(), // "BYTE",
0x1b => self.run_shl(), // "SHL",
0x1c => todo!(), // "SHR",
0x1d => todo!(), // "SAR",
@ -380,6 +380,20 @@ impl<'a> Interpreter<'a> {
self.push(!x);
}
fn run_byte(&mut self) {
dbg!("byte");
let i = self.pop();
let x = self.pop();
let result = if i > 32.into() {
0
} else {
let mut bytes = [0; 32];
x.to_big_endian(&mut bytes);
bytes[i.as_usize()]
};
self.push(result.into());
}
fn run_shl(&mut self) {
let shift = self.pop();
let x = self.pop();

View File

@ -1,6 +1,7 @@
mod curve_ops;
mod ecrecover;
mod exp;
mod packing;
mod rlp;
mod transaction_parsing;

View File

@ -0,0 +1,29 @@
use anyhow::Result;
use crate::cpu::kernel::aggregator::KERNEL;
use crate::cpu::kernel::interpreter::Interpreter;
use crate::memory::segments::Segment;
#[test]
fn test_mstore_unpacking() -> Result<()> {
let mstore_unpacking = KERNEL.global_labels["mstore_unpacking"];
let retdest = 0xDEADBEEFu32.into();
let len = 4.into();
let value = 0xABCD1234u32.into();
let offset = 0.into();
let segment = (Segment::TxnData as u32).into();
let context = 0.into();
let initial_stack = vec![retdest, len, value, offset, segment, context];
let mut interpreter = Interpreter::new_with_kernel(mstore_unpacking, initial_stack);
interpreter.run()?;
assert_eq!(interpreter.stack(), vec![]);
assert_eq!(
&interpreter.get_txn_data(),
&[0xAB.into(), 0xCD.into(), 0x12.into(), 0x34.into()]
);
Ok(())
}