diff --git a/crates/library/std/src/buf.fe b/crates/library/std/src/buf.fe index 291471f4a4..c53b7eb0e7 100644 --- a/crates/library/std/src/buf.fe +++ b/crates/library/std/src/buf.fe @@ -47,7 +47,7 @@ pub struct MemoryBuffer { pub fn new(len: u256) -> Self { unsafe { - return MemoryBuffer(offset: alloc(len), len) + return MemoryBuffer(offset: alloc(len: len + 31), len) } } @@ -103,7 +103,8 @@ pub struct MemoryBufferWriter { pub fn write_n(mut self, value: u256, len: u256) { let offset: u256 = self.write_offset(len) - unsafe { rewrite_slot(offset, value, len) } + let shifted_value: u256 = evm::shl(bits: 256 - len * 8, value) + unsafe { evm::mstore(offset, value: shifted_value) } } pub fn write_buf(mut self, buf: MemoryBuffer) { @@ -174,27 +175,6 @@ impl MemoryBufferWrite for () { fn write_buf(self, mut writer: MemoryBufferWriter) {} } -/// Rewrites the left-most `len` bytes in slot with the right-most `len` bytes of `value`. -unsafe fn rewrite_slot(offset: u256, value: u256, len: u256) { - // bit mask for right side of 256 bit slot - let mask: u256 = evm::shr( - bits: len * 8, - value: 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff - ) - // new value shifted to left - let shifted_value: u256 = evm::shl( - bits: 256 - len * 8, - value - ) - - let old_value: u256 = evm::mload(offset) - let new_value: u256 = evm::bitwise_or( - evm::bitwise_and(mask, old_value), - shifted_value - ) - evm::mstore(offset, value: new_value) -} - /// Memory buffer reader abstraction. pub struct MemoryBufferReader { buf: MemoryBuffer diff --git a/newsfragments/898.performance.md b/newsfragments/898.performance.md new file mode 100644 index 0000000000..5edaef9511 --- /dev/null +++ b/newsfragments/898.performance.md @@ -0,0 +1 @@ +`MemoryBuffer` now allocates an extra 31 bytes. This removes the need for runtime checks and bitshifting needed to ensure safe writing to a `MemoryBuffer`'s region.