diff --git a/core/vm/eof_instructions.go b/core/vm/eof_instructions.go index 800d14d7b8..f37402489d 100644 --- a/core/vm/eof_instructions.go +++ b/core/vm/eof_instructions.go @@ -78,17 +78,37 @@ func opDataCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([ // opDupN implements the DUPN opcode func opDupN(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - panic("not implemented") + var ( + code = scope.Contract.CodeAt(scope.CodeSection) + index = int(code[*pc+1]) + 1 + ) + scope.Stack.dup(index) + *pc += 1 // move past immediate + return nil, nil } // opSwapN implements the SWAPN opcode func opSwapN(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - panic("not implemented") + var ( + code = scope.Contract.CodeAt(scope.CodeSection) + index = int(code[*pc+1]) + 1 + ) + scope.Stack.swap(index + 1) + *pc += 1 // move past immediate + return nil, nil } // opExchange implements the EXCHANGE opcode func opExchange(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - panic("not implemented") + var ( + code = scope.Contract.CodeAt(scope.CodeSection) + index = int(code[*pc+1]) + n = (index >> 4) + 1 + m = (index & 0x0F) + 1 + ) + scope.Stack.swapN(n+1, n+m+1) + *pc += 1 // move past immediate + return nil, nil } // opReturnDataLoad implements the RETURNDATALOAD opcode diff --git a/core/vm/stack.go b/core/vm/stack.go index 879dc9aa6d..22358b3a54 100644 --- a/core/vm/stack.go +++ b/core/vm/stack.go @@ -113,6 +113,14 @@ func (st *Stack) swap16() { st.data[st.len()-17], st.data[st.len()-1] = st.data[st.len()-1], st.data[st.len()-17] } +func (st *Stack) swap(n int) { + st.swapN(n, 1) +} + +func (st *Stack) swapN(n, m int) { + st.data[st.len()-n], st.data[st.len()-m] = st.data[st.len()-m], st.data[st.len()-n] +} + func (st *Stack) dup(n int) { st.push(&st.data[st.len()-n]) }