core/vm: use uint64 in memory for indices everywhere (#30252)

Consistently use `uint64` for indices in `Memory` and drop lots of type
conversions from `uint64` to `int64`.

---------

Co-authored-by: lmittmann <lmittmann@users.noreply.github.com>
This commit is contained in:
lmittmann 2024-08-08 10:27:38 +02:00 committed by GitHub
parent 978041feea
commit 4a3aed380e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 18 additions and 25 deletions

@ -232,7 +232,7 @@ func opSAR(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte
func opKeccak256(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { func opKeccak256(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
offset, size := scope.Stack.pop(), scope.Stack.peek() offset, size := scope.Stack.pop(), scope.Stack.peek()
data := scope.Memory.GetPtr(int64(offset.Uint64()), int64(size.Uint64())) data := scope.Memory.GetPtr(offset.Uint64(), size.Uint64())
if interpreter.hasher == nil { if interpreter.hasher == nil {
interpreter.hasher = crypto.NewKeccakState() interpreter.hasher = crypto.NewKeccakState()
@ -502,7 +502,7 @@ func opPop(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte
func opMload(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { func opMload(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
v := scope.Stack.peek() v := scope.Stack.peek()
offset := int64(v.Uint64()) offset := v.Uint64()
v.SetBytes(scope.Memory.GetPtr(offset, 32)) v.SetBytes(scope.Memory.GetPtr(offset, 32))
return nil, nil return nil, nil
} }
@ -670,7 +670,7 @@ func opCreate(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]b
var ( var (
value = scope.Stack.pop() value = scope.Stack.pop()
offset, size = scope.Stack.pop(), scope.Stack.pop() offset, size = scope.Stack.pop(), scope.Stack.pop()
input = scope.Memory.GetCopy(int64(offset.Uint64()), int64(size.Uint64())) input = scope.Memory.GetCopy(offset.Uint64(), size.Uint64())
gas = scope.Contract.Gas gas = scope.Contract.Gas
) )
if interpreter.evm.chainRules.IsEIP150 { if interpreter.evm.chainRules.IsEIP150 {
@ -714,7 +714,7 @@ func opCreate2(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]
endowment = scope.Stack.pop() endowment = scope.Stack.pop()
offset, size = scope.Stack.pop(), scope.Stack.pop() offset, size = scope.Stack.pop(), scope.Stack.pop()
salt = scope.Stack.pop() salt = scope.Stack.pop()
input = scope.Memory.GetCopy(int64(offset.Uint64()), int64(size.Uint64())) input = scope.Memory.GetCopy(offset.Uint64(), size.Uint64())
gas = scope.Contract.Gas gas = scope.Contract.Gas
) )
@ -752,7 +752,7 @@ func opCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byt
addr, value, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() addr, value, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop()
toAddr := common.Address(addr.Bytes20()) toAddr := common.Address(addr.Bytes20())
// Get the arguments from the memory. // Get the arguments from the memory.
args := scope.Memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64())) args := scope.Memory.GetPtr(inOffset.Uint64(), inSize.Uint64())
if interpreter.readOnly && !value.IsZero() { if interpreter.readOnly && !value.IsZero() {
return nil, ErrWriteProtection return nil, ErrWriteProtection
@ -788,7 +788,7 @@ func opCallCode(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([
addr, value, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() addr, value, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop()
toAddr := common.Address(addr.Bytes20()) toAddr := common.Address(addr.Bytes20())
// Get arguments from the memory. // Get arguments from the memory.
args := scope.Memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64())) args := scope.Memory.GetPtr(inOffset.Uint64(), inSize.Uint64())
if !value.IsZero() { if !value.IsZero() {
gas += params.CallStipend gas += params.CallStipend
@ -821,7 +821,7 @@ func opDelegateCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext
addr, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() addr, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop()
toAddr := common.Address(addr.Bytes20()) toAddr := common.Address(addr.Bytes20())
// Get arguments from the memory. // Get arguments from the memory.
args := scope.Memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64())) args := scope.Memory.GetPtr(inOffset.Uint64(), inSize.Uint64())
ret, returnGas, err := interpreter.evm.DelegateCall(scope.Contract, toAddr, args, gas) ret, returnGas, err := interpreter.evm.DelegateCall(scope.Contract, toAddr, args, gas)
if err != nil { if err != nil {
@ -850,7 +850,7 @@ func opStaticCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext)
addr, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() addr, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop()
toAddr := common.Address(addr.Bytes20()) toAddr := common.Address(addr.Bytes20())
// Get arguments from the memory. // Get arguments from the memory.
args := scope.Memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64())) args := scope.Memory.GetPtr(inOffset.Uint64(), inSize.Uint64())
ret, returnGas, err := interpreter.evm.StaticCall(scope.Contract, toAddr, args, gas) ret, returnGas, err := interpreter.evm.StaticCall(scope.Contract, toAddr, args, gas)
if err != nil { if err != nil {
@ -871,14 +871,14 @@ func opStaticCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext)
func opReturn(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { func opReturn(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
offset, size := scope.Stack.pop(), scope.Stack.pop() offset, size := scope.Stack.pop(), scope.Stack.pop()
ret := scope.Memory.GetPtr(int64(offset.Uint64()), int64(size.Uint64())) ret := scope.Memory.GetPtr(offset.Uint64(), size.Uint64())
return ret, errStopToken return ret, errStopToken
} }
func opRevert(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { func opRevert(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
offset, size := scope.Stack.pop(), scope.Stack.pop() offset, size := scope.Stack.pop(), scope.Stack.pop()
ret := scope.Memory.GetPtr(int64(offset.Uint64()), int64(size.Uint64())) ret := scope.Memory.GetPtr(offset.Uint64(), size.Uint64())
interpreter.returnData = ret interpreter.returnData = ret
return ret, ErrExecutionReverted return ret, ErrExecutionReverted
@ -947,7 +947,7 @@ func makeLog(size int) executionFunc {
topics[i] = addr.Bytes32() topics[i] = addr.Bytes32()
} }
d := scope.Memory.GetCopy(int64(mStart.Uint64()), int64(mSize.Uint64())) d := scope.Memory.GetCopy(mStart.Uint64(), mSize.Uint64())
interpreter.evm.StateDB.AddLog(&types.Log{ interpreter.evm.StateDB.AddLog(&types.Log{
Address: scope.Contract.Address(), Address: scope.Contract.Address(),
Topics: topics, Topics: topics,

@ -66,34 +66,27 @@ func (m *Memory) Resize(size uint64) {
} }
// GetCopy returns offset + size as a new slice // GetCopy returns offset + size as a new slice
func (m *Memory) GetCopy(offset, size int64) (cpy []byte) { func (m *Memory) GetCopy(offset, size uint64) (cpy []byte) {
if size == 0 { if size == 0 {
return nil return nil
} }
if len(m.store) > int(offset) { // memory is always resized before being accessed, no need to check bounds
cpy = make([]byte, size) cpy = make([]byte, size)
copy(cpy, m.store[offset:offset+size]) copy(cpy, m.store[offset:offset+size])
return
}
return return
} }
// GetPtr returns the offset + size // GetPtr returns the offset + size
func (m *Memory) GetPtr(offset, size int64) []byte { func (m *Memory) GetPtr(offset, size uint64) []byte {
if size == 0 { if size == 0 {
return nil return nil
} }
if len(m.store) > int(offset) { // memory is always resized before being accessed, no need to check bounds
return m.store[offset : offset+size] return m.store[offset : offset+size]
} }
return nil
}
// Len returns the length of the backing slice // Len returns the length of the backing slice
func (m *Memory) Len() int { func (m *Memory) Len() int {
return len(m.store) return len(m.store)