revm_interpreter/instructions/
utility.rspub use crate::InstructionResult;
pub use primitives::U256;
use primitives::{Address, B256};
#[inline]
pub fn cast_slice_to_u256(slice: &[u8], dest: &mut U256) {
if slice.is_empty() {
return;
}
assert!(slice.len() <= 32, "slice too long");
let n_words = (slice.len() + 31) / 32;
unsafe {
let dst = dest.as_limbs_mut().as_mut_ptr();
let mut i = 0;
let words = slice.chunks_exact(32);
let partial_last_word = words.remainder();
for word in words {
for l in word.rchunks_exact(8) {
dst.add(i).write(u64::from_be_bytes(l.try_into().unwrap()));
i += 1;
}
}
if partial_last_word.is_empty() {
return;
}
let limbs = partial_last_word.rchunks_exact(8);
let partial_last_limb = limbs.remainder();
for l in limbs {
dst.add(i).write(u64::from_be_bytes(l.try_into().unwrap()));
i += 1;
}
if !partial_last_limb.is_empty() {
let mut tmp = [0u8; 8];
tmp[8 - partial_last_limb.len()..].copy_from_slice(partial_last_limb);
dst.add(i).write(u64::from_be_bytes(tmp));
i += 1;
}
debug_assert_eq!((i + 3) / 4, n_words, "wrote too much");
let m = i % 4; if m != 0 {
dst.add(i).write_bytes(0, 4 - m);
}
}
}
pub trait IntoU256 {
fn into_u256(self) -> U256;
}
impl IntoU256 for Address {
fn into_u256(self) -> U256 {
self.into_word().into_u256()
}
}
impl IntoU256 for B256 {
fn into_u256(self) -> U256 {
U256::from_be_bytes(self.0)
}
}
pub trait IntoAddress {
fn into_address(self) -> Address;
}
impl IntoAddress for U256 {
fn into_address(self) -> Address {
Address::from_word(B256::from(self.to_be_bytes()))
}
}
#[cfg(test)]
mod tests {
use primitives::address;
use super::*;
#[test]
fn test_into_u256() {
let addr = address!("0000000000000000000000000000000000000001");
let u256 = addr.into_u256();
assert_eq!(u256, U256::from(0x01));
assert_eq!(u256.into_address(), addr);
}
}