From 3f90f7c89856f5d024eec1df535a4fc2871214c2 Mon Sep 17 00:00:00 2001
From: obscuren <geffobscura@gmail.com>
Date: Sat, 1 Nov 2014 02:14:55 +0100
Subject: [PATCH] Signextend

---
 ethutil/big.go |  4 ++++
 vm/vm_debug.go | 14 ++++++++++++++
 2 files changed, 18 insertions(+)

diff --git a/ethutil/big.go b/ethutil/big.go
index bdcf86421..8d7b3fe70 100644
--- a/ethutil/big.go
+++ b/ethutil/big.go
@@ -34,6 +34,10 @@ func BigD(data []byte) *big.Int {
 	return n
 }
 
+func BitTest(num *big.Int, i int) bool {
+	return num.Bit(i) > 0
+}
+
 // To256
 //
 // "cast" the big int to a 256 big int (i.e., limit to)
diff --git a/vm/vm_debug.go b/vm/vm_debug.go
index 0abfa098d..129ea1a59 100644
--- a/vm/vm_debug.go
+++ b/vm/vm_debug.go
@@ -392,6 +392,20 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
 			self.Printf(" = %v", base)
 
 			stack.Push(base)
+		case SIGNEXTEND:
+			back := stack.Pop().Uint64()
+			if back.Cmp(big.NewInt(31)) < 0 {
+				bit := uint(back*8 + 7)
+				num := stack.Pop()
+				mask := new(big.Int).Lsh(ethutil.Big1, bit)
+				mask.Sub(mask, ethutil.Big1)
+				if ethutil.BitTest(num, int(bit)) {
+					num.Or(num, mask.Not(mask))
+				} else {
+					num.And(num, mask)
+				}
+				stack.Push(num)
+			}
 		case NOT:
 			base.Sub(Pow256, stack.Pop()).Sub(base, ethutil.Big1)
 
-- 
GitLab