Avoid alloca for contract storage value when type is already 32 bytes
@@ -352,6 +352,36 @@ impl TargetRuntime for EwasmTarget {
slot: PointerValue<'a>,
dest: PointerValue<'a>,
) {
+ if dest
+ .get_type()
+ .get_element_type()
+ .into_int_type()
+ .get_bit_width()
+ == 256
+ {
+ contract.builder.build_call(
+ contract.module.get_function("storageStore").unwrap(),
+ &[
+ contract
+ .builder
+ .build_pointer_cast(
+ slot,
+ contract.context.i8_type().ptr_type(AddressSpace::Generic),
+ "",
+ )
+ .into(),
+ contract
+ .builder
+ .build_pointer_cast(
+ dest,
+ contract.context.i8_type().ptr_type(AddressSpace::Generic),
+ "",
+ )
+ .into(),
+ ],
+ "",
+ );
+ } else {
let value = contract
.builder
.build_alloca(contract.context.custom_width_int_type(256), "value");
@@ -396,6 +426,7 @@ impl TargetRuntime for EwasmTarget {
"",
);
}
+ }
fn get_storage<'a>(
&self,
@@ -404,7 +435,36 @@ impl TargetRuntime for EwasmTarget {
slot: PointerValue<'a>,
dest: PointerValue<'a>,
) {
- // FIXME: no need to alloca for 256 bit value
+ if dest
+ .get_type()
+ .get_element_type()
+ .into_int_type()
+ .get_bit_width()
+ == 256
+ {
+ contract.builder.build_call(
+ contract.module.get_function("storageLoad").unwrap(),
+ &[
+ contract
+ .builder
+ .build_pointer_cast(
+ slot,
+ contract.context.i8_type().ptr_type(AddressSpace::Generic),
+ "",
+ )
+ .into(),
+ contract
+ .builder
+ .build_pointer_cast(
+ dest,
+ contract.context.i8_type().ptr_type(AddressSpace::Generic),
+ "",
+ )
+ .into(),
+ ],
+ "",
+ );
+ } else {
let value = contract
.builder
.build_alloca(contract.context.custom_width_int_type(256), "value");
@@ -441,6 +501,7 @@ impl TargetRuntime for EwasmTarget {
contract.builder.build_store(dest, val);
}
+ }
fn return_empty_abi(&self, contract: &Contract) {
contract.builder.build_call(
