mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-04 02:53:45 +00:00
core/vm: reimplemented RETURNDATA{SIZE, COPY}
Reimplemented RETURNDATA such that the returndata buffer is isolated inside the interpreter rather than the memory object.
This commit is contained in:
parent
f7212a43df
commit
ad0a31f9a4
3 changed files with 9 additions and 4 deletions
|
|
@ -718,7 +718,7 @@ func opSuicide(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *
|
|||
}
|
||||
|
||||
func opReturnDataSize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
|
||||
stack.push(evm.interpreter.intPool.get().SetUint64(uint64(len(memory.lastReturn))))
|
||||
stack.push(evm.interpreter.intPool.get().SetUint64(uint64(len(evm.interpreter.returnData))))
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
|
|
@ -728,7 +728,7 @@ func opReturnDataCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory,
|
|||
cOff = stack.pop()
|
||||
l = stack.pop()
|
||||
)
|
||||
memory.Set(mOff.Uint64(), l.Uint64(), getData(memory.lastReturn, cOff, l))
|
||||
memory.Set(mOff.Uint64(), l.Uint64(), getData(evm.interpreter.returnData, cOff, l))
|
||||
|
||||
evm.interpreter.intPool.put(mOff, cOff, l)
|
||||
return nil, nil
|
||||
|
|
|
|||
|
|
@ -61,6 +61,8 @@ type Interpreter struct {
|
|||
intPool *intPool
|
||||
|
||||
readonly bool
|
||||
// returnData contains the last call's return data
|
||||
returnData []byte
|
||||
}
|
||||
|
||||
// NewInterpreter returns a new instance of the Interpreter.
|
||||
|
|
@ -108,8 +110,12 @@ func (in *Interpreter) enforceRestrictions(op OpCode, operation operation, stack
|
|||
// considered a revert-and-consume-all-gas operation. No error specific checks
|
||||
// should be handled to reduce complexity and errors further down the in.
|
||||
func (in *Interpreter) Run(snapshot int, contract *Contract, input []byte) (ret []byte, err error) {
|
||||
// Increment the call depth which is restricted to 1024.
|
||||
in.evm.depth++
|
||||
defer func() { in.evm.depth-- }()
|
||||
// Reset the previous call's return data. It's unimportant to preserve the old buffer
|
||||
// as every returning call will return new data anyway.
|
||||
in.returnData = nil
|
||||
|
||||
// Don't bother with the execution if there's no code.
|
||||
if len(contract.Code) == 0 {
|
||||
|
|
@ -228,7 +234,7 @@ func (in *Interpreter) Run(snapshot int, contract *Contract, input []byte) (ret
|
|||
// if the operation returned a value make sure that is also set
|
||||
// the last return data.
|
||||
if res != nil {
|
||||
mem.lastReturn = ret
|
||||
in.returnData = res
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ import "fmt"
|
|||
type Memory struct {
|
||||
store []byte
|
||||
lastGasCost uint64
|
||||
lastReturn []byte
|
||||
}
|
||||
|
||||
func NewMemory() *Memory {
|
||||
|
|
|
|||
Loading…
Reference in a new issue