From 9896787cdfb5667d0b5220b5af080828f6997784 Mon Sep 17 00:00:00 2001 From: Grant Wuerker Date: Fri, 18 Aug 2023 15:16:33 +0200 Subject: [PATCH] Finish buf refactor --- .../errors__emittable_not_implementable.snap | 4 +- crates/library/std/src/buf.fe | 30 ++-- crates/library/std/src/context.fe | 1 + crates/library/std/src/evm.fe | 133 ++++++++++-------- crates/library/std/src/precompiles.fe | 50 +++---- newsfragments/917.feature.md | 1 + 6 files changed, 121 insertions(+), 98 deletions(-) create mode 100644 newsfragments/917.feature.md diff --git a/crates/analyzer/tests/snapshots/errors__emittable_not_implementable.snap b/crates/analyzer/tests/snapshots/errors__emittable_not_implementable.snap index da4fcbbbde..63c3488324 100644 --- a/crates/analyzer/tests/snapshots/errors__emittable_not_implementable.snap +++ b/crates/analyzer/tests/snapshots/errors__emittable_not_implementable.snap @@ -14,9 +14,9 @@ error: the struct `OutOfReachMarker` is private 6 │ fn emit(self, _ val: OutOfReachMarker) { │ ^^^^^^^^^^^^^^^^ this struct is not `pub` │ - ┌─ src/context.fe:13:8 + ┌─ src/context.fe:14:8 │ -13 │ struct OutOfReachMarker {} +14 │ struct OutOfReachMarker {} │ ---------------- `OutOfReachMarker` is defined here │ = `OutOfReachMarker` can only be used within `context` diff --git a/crates/library/std/src/buf.fe b/crates/library/std/src/buf.fe index 4fcd9e2672..5fa4fd6b89 100644 --- a/crates/library/std/src/buf.fe +++ b/crates/library/std/src/buf.fe @@ -112,7 +112,7 @@ pub struct MemoryBuffer { } /// The start of the buffer in EVM memory. - pub fn offset(self) -> u256 { + pub unsafe fn offset(self) -> u256 { return self.offset } @@ -146,14 +146,16 @@ pub struct MemoryBufferWriter { return self.cur.remainder() } - pub fn write_offset(mut self, len: u256) -> u256 { + pub unsafe fn write_offset(mut self, len: u256) -> u256 { return self.buf.offset() + self.cur.advance(len) } pub fn write_n(mut self, value: u256, len: u256) { - let offset: u256 = self.write_offset(len) let shifted_value: u256 = evm::shl(bits: 256 - len * 8, value) - unsafe { evm::mstore(offset, value: shifted_value) } + unsafe { + let offset: u256 = self.write_offset(len) + evm::mstore(offset, value: shifted_value) + } } pub fn write_buf(mut self, buf: MemoryBuffer) { @@ -183,8 +185,10 @@ pub trait MemoryBufferWrite { impl MemoryBufferWrite for u256 { fn write_buf(self, mut writer: MemoryBufferWriter) { - let offset: u256 = writer.write_offset(len: 32) - unsafe { evm::mstore(offset, value: self) } + unsafe { + let offset: u256 = writer.write_offset(len: 32) + evm::mstore(offset, value: self) + } } } @@ -214,8 +218,10 @@ impl MemoryBufferWrite for u16 { impl MemoryBufferWrite for u8 { fn write_buf(self, mut writer: MemoryBufferWriter) { - let offset: u256 = writer.write_offset(len: 1) - unsafe { evm::mstore8(offset, value: self) } + unsafe { + let offset: u256 = writer.write_offset(len: 1) + evm::mstore8(offset, value: self) + } } } @@ -239,13 +245,13 @@ pub struct MemoryBufferReader { return self.cur.remainder() } - fn read_offset(mut self, len: u256) -> u256 { + unsafe fn read_offset(mut self, len: u256) -> u256 { return self.buf.offset() + self.cur.advance(len) } fn read_n(mut self, len: u256) -> u256 { - let offset: u256 = self.read_offset(len) unsafe { + let offset: u256 = self.read_offset(len) let value: u256 = evm::mload(offset) return evm::shr(bits: 256 - len * 8, value) } @@ -272,8 +278,8 @@ pub struct MemoryBufferReader { } pub fn read_u256(mut self) -> u256 { - let offset: u256 = self.read_offset(len: 32) unsafe { + let offset: u256 = self.read_offset(len: 32) let value: u256 = evm::mload(offset) return value } @@ -334,7 +340,7 @@ pub struct RawCallBuffer { return self.output_len } - pub fn offset(self) -> u256 { + pub unsafe fn offset(self) -> u256 { return self.buf.offset() } diff --git a/crates/library/std/src/context.fe b/crates/library/std/src/context.fe index 9b51f9ca9e..48ee1a0cad 100644 --- a/crates/library/std/src/context.fe +++ b/crates/library/std/src/context.fe @@ -6,6 +6,7 @@ use ingot::error::{ } use ingot::buf::{ RawCallBuffer, + MemoryBuffer, MemoryBufferReader, MemoryBufferWriter } diff --git a/crates/library/std/src/evm.fe b/crates/library/std/src/evm.fe index 09c9382556..9f6f5c9e27 100644 --- a/crates/library/std/src/evm.fe +++ b/crates/library/std/src/evm.fe @@ -2,181 +2,181 @@ use ingot::buf::{MemoryBuffer, RawCallBuffer} // Basic context accessor functions. pub unsafe fn chain_id() -> u256 { - return __chainid() + return __chainid() } pub unsafe fn base_fee() -> u256 { - return __basefee() + return __basefee() } pub unsafe fn origin() -> address { - return address(__origin()) + return address(__origin()) } pub unsafe fn gas_price() -> u256 { - return __gasprice() + return __gasprice() } pub unsafe fn gas_limit() -> u256 { - return __gaslimit() + return __gaslimit() } pub unsafe fn gas_remaining() -> u256 { - return __gas() + return __gas() } pub unsafe fn block_hash(_ b: u256) -> u256 { - return __blockhash(b) + return __blockhash(b) } pub unsafe fn coinbase() -> address { - return address(__coinbase()) + return address(__coinbase()) } pub unsafe fn timestamp() -> u256 { - return __timestamp() + return __timestamp() } pub unsafe fn block_number() -> u256 { - return __number() + return __number() } pub unsafe fn prevrandao() -> u256 { - return __prevrandao() + return __prevrandao() } pub unsafe fn self_address() -> address { - return address(__address()) + return address(__address()) } pub unsafe fn balance_of(_ addr: address) -> u256 { - return __balance(u256(addr)) + return __balance(u256(addr)) } pub unsafe fn balance() -> u256 { - return __selfbalance() + return __selfbalance() } pub unsafe fn caller() -> address { - return address(__caller()) + return address(__caller()) } pub unsafe fn call_value() -> u256 { - return __callvalue() + return __callvalue() } // Overflowing math ops. Should these be unsafe or named // `overflowing_add`, etc? pub fn add(_ x: u256, _ y: u256) -> u256 { - unsafe { return __add(x, y) } + unsafe { return __add(x, y) } } pub fn sub(_ x: u256, _ y: u256) -> u256 { - unsafe { return __sub(x, y) } + unsafe { return __sub(x, y) } } pub fn mul(_ x: u256, _ y: u256) -> u256 { - unsafe { return __mul(x, y) } + unsafe { return __mul(x, y) } } pub fn div(_ x: u256, _ y: u256) -> u256 { - unsafe { return __div(x, y) } + unsafe { return __div(x, y) } } pub fn sdiv(_ x: u256, _ y: u256) -> u256 { - unsafe { return __sdiv(x, y) } + unsafe { return __sdiv(x, y) } } pub fn mod(_ x: u256, _ y: u256) -> u256 { - unsafe { return __mod(x, y) } + unsafe { return __mod(x, y) } } pub fn smod(_ x: u256, _ y: u256) -> u256 { - unsafe { return __smod(x, y) } + unsafe { return __smod(x, y) } } pub fn exp(_ x: u256, _ y: u256) -> u256 { - unsafe { return __exp(x, y) } + unsafe { return __exp(x, y) } } pub fn addmod(_ x: u256, _ y: u256, _ m: u256) -> u256 { - unsafe { return __addmod(x, y, m) } + unsafe { return __addmod(x, y, m) } } pub fn mulmod(_ x: u256, _ y: u256, _ m: u256) -> u256 { - unsafe { return __mulmod(x, y, m) } + unsafe { return __mulmod(x, y, m) } } pub fn sign_extend(_ i: u256, _ x: u256) -> u256 { - unsafe { return __signextend(i, x) } + unsafe { return __signextend(i, x) } } // Comparison ops // TODO: return bool (see issue //653) pub fn lt(_ x: u256, _ y: u256) -> u256 { - unsafe { return __lt(x, y) } + unsafe { return __lt(x, y) } } pub fn gt(_ x: u256, _ y: u256) -> u256 { - unsafe { return __gt(x, y) } + unsafe { return __gt(x, y) } } pub fn slt(_ x: u256, _ y: u256) -> u256 { - unsafe { return __slt(x, y) } + unsafe { return __slt(x, y) } } pub fn sgt(_ x: u256, _ y: u256) -> u256 { - unsafe { return __sgt(x, y) } + unsafe { return __sgt(x, y) } } pub fn eq(_ x: u256, _ y: u256) -> u256 { - unsafe { return __eq(x, y) } +unsafe { return __eq(x, y) } } pub fn is_zero(_ x: u256) -> u256 { - unsafe { return __iszero(x) } + unsafe { return __iszero(x) } } // Bitwise ops pub fn bitwise_and(_ x: u256, _ y: u256) -> u256 { - unsafe { return __and(x, y) } + unsafe { return __and(x, y) } } pub fn bitwise_or(_ x: u256, _ y: u256) -> u256 { - unsafe { return __or(x, y) } + unsafe { return __or(x, y) } } pub fn bitwise_not(_ x: u256) -> u256 { - unsafe { return __not(x) } + unsafe { return __not(x) } } pub fn xor(_ x: u256, _ y: u256) -> u256 { - unsafe { return __xor(x, y) } + unsafe { return __xor(x, y) } } pub fn byte(offset: u256, value: u256) -> u256 { - unsafe { return __byte(offset, value) } + unsafe { return __byte(offset, value) } } pub fn shl(bits: u256, value: u256) -> u256 { - unsafe { return __shl(bits, value) } + unsafe { return __shl(bits, value) } } pub fn shr(bits: u256, value: u256) -> u256 { - unsafe { return __shr(bits, value) } + unsafe { return __shr(bits, value) } } pub fn sar(bits: u256, value: u256) -> u256 { - unsafe { return __sar(bits, value) } + unsafe { return __sar(bits, value) } } // Evm state access and control pub fn return_mem(buf: MemoryBuffer) { - unsafe{ __return(buf.offset(), buf.len()) } + unsafe{ __return(buf.offset(), buf.len()) } } pub fn revert_mem(buf: MemoryBuffer) { @@ -238,32 +238,32 @@ pub unsafe fn call_data_size() -> u256 { return __calldatasize() } -pub fn call_data_copy(buf: MemoryBuffer, from_offset f: u256) { - unsafe { __calldatacopy(buf.offset(), f, buf.len()) } +pub fn call_data_copy(mut buf: MemoryBuffer, from_offset f: u256) { + unsafe { __calldatacopy(buf.offset(), f, buf.len()) } } pub unsafe fn code_size() -> u256 { return __codesize() } -pub unsafe fn code_copy(to_offset t: u256, from_offset f: u256, len: u256) { - __codecopy(t, f, len) +pub fn code_copy(mut buf: MemoryBuffer, from_offset f: u256) { + unsafe { __codecopy(buf.offset(), f, buf.len()) } } pub unsafe fn return_data_size() -> u256 { return __returndatasize() } -pub unsafe fn return_data_copy(to_offset t: u256, from_offset f: u256, len: u256) { - __returndatacopy(t, f, len) +pub fn return_data_copy(mut buf: MemoryBuffer, from_offset f: u256) { + unsafe { __returndatacopy(buf.offset(), f, buf.len()) } } pub unsafe fn extcodesize(_ addr: address) -> u256 { return __extcodesize(u256(addr)) } -pub unsafe fn ext_code_copy(_ addr: address, to_offset t: u256, from_offset f: u256, len: u256) { - __extcodecopy(u256(addr), t, f, len) +pub unsafe fn ext_code_copy(addr: address, mut buf: MemoryBuffer, from_offset f: u256) { + __extcodecopy(u256(addr), buf.offset(), f, buf.len()) } pub unsafe fn ext_code_hash(_ addr: address) -> u256 { @@ -271,7 +271,7 @@ pub unsafe fn ext_code_hash(_ addr: address) -> u256 { } pub fn keccak256_mem(buf: MemoryBuffer) -> u256 { - unsafe { return __keccak256(buf.offset(), buf.len()) } + unsafe { return __keccak256(buf.offset(), buf.len()) } } @@ -285,21 +285,36 @@ pub fn create2(value v: u256, buf: MemoryBuffer, salt s: u256) -> address { unsafe { return address(__create2(v, buf.offset(), buf.len(), s)) } } -// TODO: return bool (success) pub fn call(gas: u256, addr: address, value: u256, mut buf: RawCallBuffer) -> bool { - unsafe{ return __call(gas, u256(addr), value, buf.offset(), buf.input_len(), buf.offset(), buf.output_len()) == 1 } + unsafe { return __call(gas, u256(addr), value, buf.offset(), buf.input_len(), buf.offset(), buf.output_len()) == 1 } } -pub unsafe fn call_code(gas: u256, addr: address, value: u256, input_offset: u256, input_len: u256, output_offset: u256, output_len: u256) -> u256 { - return __callcode(gas, u256(addr), value, input_offset, input_len, output_offset, output_len) +pub fn call_code(gas: u256, addr: address, value: u256, mut buf: RawCallBuffer) -> bool { + unsafe { return __callcode(gas, u256(addr), value, buf.offset(), buf.input_len(), buf.offset(), buf.output_len()) == 1 } } -pub unsafe fn delegate_call(gas: u256, addr: address, value: u256, input_offset: u256, input_len: u256, output_offset: u256, output_len: u256) -> u256 { - return __delegatecall(gas, u256(addr), input_offset, input_len, output_offset, output_len) +pub fn delegate_call(gas: u256, addr: address, mut buf: RawCallBuffer) -> bool { + unsafe { return __delegatecall(gas, u256(addr), buf.offset(), buf.input_len(), buf.offset(), buf.output_len()) == 1 } } -pub unsafe fn static_call(gas: u256, addr: address, input_offset: u256, input_len: u256, output_offset: u256, output_len: u256) -> u256 { - return __staticcall(gas, u256(addr), input_offset, input_len, output_offset, output_len) +pub fn static_call(gas: u256, addr: address, mut buf: RawCallBuffer) -> bool { + unsafe { return __staticcall(gas, u256(addr), buf.offset(), buf.input_len(), buf.offset(), buf.output_len()) == 1 } +} + +pub unsafe fn call_2(gas: u256, addr: address, value: u256, input_offset: u256, input_len: u256, output_offset: u256, output_len: u256) -> bool { + return __call(gas, u256(addr), value, input_offset, input_len, output_offset, output_len) == 1 +} + +pub unsafe fn call_code_2(gas: u256, addr: address, value: u256, input_offset: u256, input_len: u256, output_offset: u256, output_len: u256) -> bool { + return __callcode(gas, u256(addr), value, input_offset, input_len, output_offset, output_len) == 1 +} + +pub unsafe fn delegate_call_2(gas: u256, addr: address, input_offset: u256, input_len: u256, output_offset: u256, output_len: u256) -> bool { + return __delegatecall(gas, u256(addr), input_offset, input_len, output_offset, output_len) == 1 +} + +pub unsafe fn static_call_2(gas: u256, addr: address, input_offset: u256, input_len: u256, output_offset: u256, output_len: u256) -> bool { + return __staticcall(gas, u256(addr), input_offset, input_len, output_offset, output_len) == 1 } // Logging functions diff --git a/crates/library/std/src/precompiles.fe b/crates/library/std/src/precompiles.fe index ba9d59f138..6bb8430de4 100644 --- a/crates/library/std/src/precompiles.fe +++ b/crates/library/std/src/precompiles.fe @@ -28,27 +28,27 @@ enum Precompile { pub fn single_buf_call(self, mut buf: MemoryBuffer) { unsafe { - assert evm::static_call( + assert evm::static_call_2( gas: evm::gas_remaining(), addr: self.addr(), input_offset: buf.offset(), input_len: buf.len(), output_offset: buf.offset(), output_len: buf.len() - ) == 1 + ) } } - pub fn call(self, input: MemoryBuffer, mut output: MemoryBuffer) { + pub fn call(self, input_buf: MemoryBuffer, mut output_buf: MemoryBuffer) { unsafe { - assert evm::static_call( + assert evm::static_call_2( gas: evm::gas_remaining(), addr: self.addr(), - input_offset: input.offset(), - input_len: input.len(), - output_offset: output.offset(), - output_len: output.len() - ) == 1 + input_offset: input_buf.offset(), + input_len: input_buf.len(), + output_offset: output_buf.offset(), + output_len: output_buf.len() + ) } } } @@ -70,26 +70,26 @@ pub fn ec_recover(hash: u256, v: u256, r: u256, s: u256) -> address { } /// SHA2 256 precompile call. -pub fn sha2_256(buf: MemoryBuffer) -> u256 { - let mut output: MemoryBuffer = MemoryBuffer::new(len: 32) - let mut reader: MemoryBufferReader = output.reader() - Precompile::Sha2256.call(input: buf, output) +pub fn sha2_256(buf input_buf: MemoryBuffer) -> u256 { + let mut output_buf: MemoryBuffer = MemoryBuffer::new(len: 32) + let mut reader: MemoryBufferReader = output_buf.reader() + Precompile::Sha2256.call(input_buf, output_buf) return reader.read_u256() } /// Ripemd 160 precompile call. -pub fn ripemd_160(buf: MemoryBuffer) -> u256 { - let mut output: MemoryBuffer = MemoryBuffer::new(len: 32) - let mut reader: MemoryBufferReader = output.reader() - Precompile::Ripemd160.call(input: buf, output) +pub fn ripemd_160(buf input_buf: MemoryBuffer) -> u256 { + let mut output_buf: MemoryBuffer = MemoryBuffer::new(len: 32) + let mut reader: MemoryBufferReader = output_buf.reader() + Precompile::Ripemd160.call(input_buf, output_buf) return reader.read_u256() } /// Identity precompile call. -pub fn identity(buf: MemoryBuffer) -> MemoryBuffer { - let mut output: MemoryBuffer = MemoryBuffer::new(len: buf.len()) - Precompile::Identity.call(input: buf, output) - return output +pub fn identity(buf input_buf: MemoryBuffer) -> MemoryBuffer { + let mut output_buf: MemoryBuffer = MemoryBuffer::new(len: input_buf.len()) + Precompile::Identity.call(input_buf, output_buf) + return output_buf } /// Mod exp preocmpile call. @@ -151,10 +151,10 @@ pub fn ec_mul(x: u256, y: u256, s: u256) -> (u256, u256) { } /// EC pairing precompile call. -pub fn ec_pairing(buf: MemoryBuffer) -> bool { - let mut output: MemoryBuffer = MemoryBuffer::new(len: 32) - let mut reader: MemoryBufferReader = output.reader() - Precompile::EcPairing.call(input: buf, output) +pub fn ec_pairing(buf input_buf: MemoryBuffer) -> bool { + let mut output_buf: MemoryBuffer = MemoryBuffer::new(len: 32) + let mut reader: MemoryBufferReader = output_buf.reader() + Precompile::EcPairing.call(input_buf, output_buf) return reader.read_u256() == 1 } diff --git a/newsfragments/917.feature.md b/newsfragments/917.feature.md new file mode 100644 index 0000000000..5f5f1e1c52 --- /dev/null +++ b/newsfragments/917.feature.md @@ -0,0 +1 @@ +Completed `std::buf::MemoryBuffer` refactor.