implement byte stores and assert heap values to be either i256 or i8

Signed-off-by: xermicus <cyrill@parity.io>
This commit is contained in:
xermicus
2024-04-17 12:44:54 +02:00
parent 40013b4f5c
commit bfcdb8afa9
3 changed files with 108 additions and 15 deletions
+93
View File
@@ -215,4 +215,97 @@ mod tests {
let received = U256::from_be_bytes::<32>(state.output.data.try_into().unwrap()); let received = U256::from_be_bytes::<32>(state.output.data.try_into().unwrap());
assert_eq!(received, expected); assert_eq!(received, expected);
} }
#[test]
fn mstore8() {
sol!(
#[derive(Debug, PartialEq, Eq)]
contract MStore8 {
function mStore8(uint value) public pure returns (uint256 word);
}
);
let code = crate::compile_blob_with_options(
"MStore8",
include_str!("../contracts/mStore8.sol"),
false,
);
let (mut instance, export) = mock_runtime::prepare(&code, None);
let mut assert = |parameter, expected| {
let input = MStore8::mStore8Call::new((parameter,)).abi_encode();
let state = crate::mock_runtime::call(State::new(input), &mut instance, export);
assert_eq!(state.output.flags, 0);
let received = U256::from_be_bytes::<32>(state.output.data.try_into().unwrap());
assert_eq!(received, expected);
};
for (parameter, expected) in [
(U256::MIN, U256::MIN),
(
U256::from(1),
U256::from_str_radix(
"452312848583266388373324160190187140051835877600158453279131187530910662656",
10,
)
.unwrap(),
),
(
U256::from(2),
U256::from_str_radix(
"904625697166532776746648320380374280103671755200316906558262375061821325312",
10,
)
.unwrap(),
),
(
U256::from(255),
U256::from_str_radix(
"115339776388732929035197660848497720713218148788040405586178452820382218977280",
10,
)
.unwrap(),
),
(
U256::from(256),
U256::from(0),
),
(
U256::from(257),
U256::from_str_radix(
"452312848583266388373324160190187140051835877600158453279131187530910662656",
10,
)
.unwrap(),
),
(
U256::from(258),
U256::from_str_radix(
"904625697166532776746648320380374280103671755200316906558262375061821325312",
10,
)
.unwrap(),
),
(
U256::from(123456789),
U256::from_str_radix(
"9498569820248594155839807363993929941088553429603327518861754938149123915776",
10,
)
.unwrap(),
),
(
U256::MAX,
U256::from_str_radix(
"115339776388732929035197660848497720713218148788040405586178452820382218977280",
10,
)
.unwrap(),
),
] {
assert(parameter, expected);
}
}
} }
+7 -1
View File
@@ -789,7 +789,13 @@ where
.expect("should be IntValue") .expect("should be IntValue")
.const_truncate(self.xlen_type()), .const_truncate(self.xlen_type()),
)?; )?;
let value = self.build_byte_swap(value.as_basic_value_enum());
let value = value.as_basic_value_enum();
let value = match value.get_type().into_int_type().get_bit_width() as usize {
revive_common::BIT_LENGTH_FIELD => self.build_byte_swap(value),
revive_common::BIT_LENGTH_BYTE => value,
_ => unreachable!("Only word and byte sized values can be stored on EVM heap"),
};
self.builder self.builder
.build_store(heap_pointer.value, value)? .build_store(heap_pointer.value, value)?
+8 -14
View File
@@ -2,8 +2,6 @@
//! Translates the heap memory operations. //! Translates the heap memory operations.
//! //!
use inkwell::values::BasicValue;
use crate::eravm::context::address_space::AddressSpace; use crate::eravm::context::address_space::AddressSpace;
use crate::eravm::context::pointer::Pointer; use crate::eravm::context::pointer::Pointer;
use crate::eravm::context::Context; use crate::eravm::context::Context;
@@ -68,20 +66,16 @@ pub fn store_byte<'ctx, D>(
where where
D: Dependency + Clone, D: Dependency + Clone,
{ {
let offset_pointer = Pointer::new_with_offset( let byte_type = context.byte_type();
let value = context
.builder()
.build_int_truncate(value, byte_type, "mstore8_value")?;
let pointer = Pointer::new_with_offset(
context, context,
AddressSpace::Heap, AddressSpace::Heap,
context.byte_type(), byte_type,
offset, offset,
"mstore8_offset_pointer", "mstore8_destination",
); );
context.build_call( context.build_store(pointer, value)
context.llvm_runtime().mstore8,
&[
offset_pointer.value.as_basic_value_enum(),
value.as_basic_value_enum(),
],
"mstore8_call",
);
Ok(())
} }