From a289a77d5de2a2cfa6b38f294b4ab953ebc1bfb8 Mon Sep 17 00:00:00 2001
From: obscuren <geffobscura@gmail.com>
Date: Thu, 21 Aug 2014 18:15:09 +0200
Subject: [PATCH] DUP n SWAP n

---
 ethvm/stack.go | 12 ++++++++++++
 ethvm/types.go | 34 ++++++++++++++++++++++++++++++++++
 ethvm/vm.go    | 20 ++++++++++++--------
 peer.go        |  2 +-
 4 files changed, 59 insertions(+), 9 deletions(-)

diff --git a/ethvm/stack.go b/ethvm/stack.go
index f4b0be393..82dd612c2 100644
--- a/ethvm/stack.go
+++ b/ethvm/stack.go
@@ -64,6 +64,18 @@ func (st *Stack) Peekn() (*big.Int, *big.Int) {
 	return ints[0], ints[1]
 }
 
+func (st *Stack) Swapn(n int) (*big.Int, *big.Int) {
+	st.data[n], st.data[0] = st.data[0], st.data[n]
+
+	return st.data[n], st.data[0]
+}
+
+func (st *Stack) Dupn(n int) *big.Int {
+	st.Push(st.data[n])
+
+	return st.Peek()
+}
+
 func (st *Stack) Push(d *big.Int) {
 	st.data = append(st.data, new(big.Int).Set(d))
 }
diff --git a/ethvm/types.go b/ethvm/types.go
index 1c3f66139..99dc0672d 100644
--- a/ethvm/types.go
+++ b/ethvm/types.go
@@ -105,6 +105,40 @@ const (
 	PUSH31 = 0x7e
 	PUSH32 = 0x7f
 
+	DUP1  = 0x80
+	DUP2  = 0x81
+	DUP3  = 0x82
+	DUP4  = 0x83
+	DUP5  = 0x84
+	DUP6  = 0x85
+	DUP7  = 0x86
+	DUP8  = 0x87
+	DUP9  = 0x88
+	DUP10 = 0x89
+	DUP11 = 0x8a
+	DUP12 = 0x8b
+	DUP13 = 0x8c
+	DUP14 = 0x8d
+	DUP15 = 0x8e
+	DUP16 = 0x8f
+
+	SWAP1  = 0x90
+	SWAP2  = 0x91
+	SWAP3  = 0x92
+	SWAP4  = 0x93
+	SWAP5  = 0x94
+	SWAP6  = 0x95
+	SWAP7  = 0x96
+	SWAP8  = 0x97
+	SWAP9  = 0x98
+	SWAP10 = 0x99
+	SWAP11 = 0x9a
+	SWAP12 = 0x9b
+	SWAP13 = 0x9c
+	SWAP14 = 0x9d
+	SWAP15 = 0x9e
+	SWAP16 = 0x9f
+
 	// 0xf0 range - closures
 	CREATE = 0xf0
 	CALL   = 0xf1
diff --git a/ethvm/vm.go b/ethvm/vm.go
index ddad0d366..b27417586 100644
--- a/ethvm/vm.go
+++ b/ethvm/vm.go
@@ -600,16 +600,20 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
 		case POP:
 			require(1)
 			stack.Pop()
-		case DUP:
-			require(1)
-			stack.Push(stack.Peek())
+		case DUP1, DUP2, DUP3, DUP4, DUP5, DUP6, DUP7, DUP8, DUP9, DUP10, DUP11, DUP12, DUP13, DUP14, DUP15, DUP16:
+			n := int(op - DUP1 + 1)
+			stack.Dupn(n)
+
+			self.Printf(" => [%d] 0x%x", n, stack.Peek().Bytes())
+		case SWAP1, SWAP2, SWAP3, SWAP4, SWAP5, SWAP6, SWAP7, SWAP8, SWAP9, SWAP10, SWAP11, SWAP12, SWAP13, SWAP14, SWAP15, SWAP16:
+			n := int(op - SWAP1 + 1)
+			x, y := stack.Swapn(n)
 
-			self.Printf(" => 0x%x", stack.Peek().Bytes())
+			self.Printf(" => [%d] %x [0] %x", n, x.Bytes(), y.Bytes())
+		case DUP:
+			// NOP
 		case SWAP:
-			require(2)
-			x, y := stack.Popn()
-			stack.Push(y)
-			stack.Push(x)
+			// NOP
 		case MLOAD:
 			require(1)
 			offset := stack.Pop()
diff --git a/peer.go b/peer.go
index d841b2ad3..ab17466e1 100644
--- a/peer.go
+++ b/peer.go
@@ -24,7 +24,7 @@ const (
 	// The size of the output buffer for writing messages
 	outputBufferSize = 50
 	// Current protocol version
-	ProtocolVersion = 27
+	ProtocolVersion = 28
 	// Interval for ping/pong message
 	pingPongTimer = 2 * time.Second
 )
-- 
GitLab