mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-16 00:43:46 +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) {
|
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
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -728,7 +728,7 @@ func opReturnDataCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory,
|
||||||
cOff = stack.pop()
|
cOff = stack.pop()
|
||||||
l = 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)
|
evm.interpreter.intPool.put(mOff, cOff, l)
|
||||||
return nil, nil
|
return nil, nil
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,8 @@ type Interpreter struct {
|
||||||
intPool *intPool
|
intPool *intPool
|
||||||
|
|
||||||
readonly bool
|
readonly bool
|
||||||
|
// returnData contains the last call's return data
|
||||||
|
returnData []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewInterpreter returns a new instance of the Interpreter.
|
// 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
|
// considered a revert-and-consume-all-gas operation. No error specific checks
|
||||||
// should be handled to reduce complexity and errors further down the in.
|
// 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) {
|
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++
|
in.evm.depth++
|
||||||
defer func() { 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.
|
// Don't bother with the execution if there's no code.
|
||||||
if len(contract.Code) == 0 {
|
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
|
// if the operation returned a value make sure that is also set
|
||||||
// the last return data.
|
// the last return data.
|
||||||
if res != nil {
|
if res != nil {
|
||||||
mem.lastReturn = ret
|
in.returnData = res
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil, nil
|
return nil, nil
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,6 @@ import "fmt"
|
||||||
type Memory struct {
|
type Memory struct {
|
||||||
store []byte
|
store []byte
|
||||||
lastGasCost uint64
|
lastGasCost uint64
|
||||||
lastReturn []byte
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMemory() *Memory {
|
func NewMemory() *Memory {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue