From 9bd6068fefe5687735bed342f3545f515fa717c8 Mon Sep 17 00:00:00 2001 From: Jeffrey Wilcke Date: Wed, 16 Aug 2017 13:07:33 +0300 Subject: core/vm: implement RETURNDATA metropolis opcodes --- core/vm/instructions.go | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'core/vm/instructions.go') diff --git a/core/vm/instructions.go b/core/vm/instructions.go index aaa8d7945..0dd9af096 100644 --- a/core/vm/instructions.go +++ b/core/vm/instructions.go @@ -31,6 +31,7 @@ import ( var ( bigZero = new(big.Int) errWriteProtection = errors.New("evm: write protection") + errReadOutOfBound = errors.New("evm: read out of bound") ) func opAdd(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { @@ -360,6 +361,28 @@ func opCalldataCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, st return nil, nil } +func opReturnDataSize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { + stack.push(evm.interpreter.intPool.get().SetUint64(uint64(len(evm.interpreter.returnData)))) + return nil, nil +} + +func opReturnDataCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { + var ( + mOff = stack.pop() + cOff = stack.pop() + l = stack.pop() + ) + defer evm.interpreter.intPool.put(mOff, cOff, l) + + cEnd := new(big.Int).Add(cOff, l) + if cEnd.BitLen() > 64 || uint64(len(evm.interpreter.returnData)) < cEnd.Uint64() { + return nil, errReadOutOfBound + } + memory.Set(mOff.Uint64(), l.Uint64(), evm.interpreter.returnData[cOff.Uint64():cEnd.Uint64()]) + + return nil, nil +} + func opExtCodeSize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { a := stack.pop() -- cgit