aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ethchain/closure.go5
-rw-r--r--ethchain/contract.go9
-rw-r--r--ethchain/vm.go26
3 files changed, 39 insertions, 1 deletions
diff --git a/ethchain/closure.go b/ethchain/closure.go
index 2e809aa9d..e9cb2c8bc 100644
--- a/ethchain/closure.go
+++ b/ethchain/closure.go
@@ -17,6 +17,7 @@ type ClosureBody interface {
ethutil.RlpEncodable
GetMem(*big.Int) *ethutil.Value
SetMem(*big.Int, *ethutil.Value)
+ GetInstr(*big.Int) *ethutil.Value
}
// Basic inline closure object which implement the 'closure' interface
@@ -46,6 +47,10 @@ func (c *Closure) GetMem(x *big.Int) *ethutil.Value {
return m
}
+func (c *Closure) GetInstr(x *big.Int) *ethutil.Value {
+ return c.object.GetInstr(x)
+}
+
func (c *Closure) SetMem(x *big.Int, val *ethutil.Value) {
c.object.SetMem(x, val)
}
diff --git a/ethchain/contract.go b/ethchain/contract.go
index f7ae01753..f68dcf367 100644
--- a/ethchain/contract.go
+++ b/ethchain/contract.go
@@ -11,6 +11,7 @@ type Contract struct {
//state *ethutil.Trie
state *State
address []byte
+ script []byte
}
func NewContract(address []byte, Amount *big.Int, root []byte) *Contract {
@@ -45,6 +46,14 @@ func (c *Contract) GetMem(num *big.Int) *ethutil.Value {
return c.Addr(nb)
}
+func (c *Contract) GetInstr(pc *big.Int) *ethutil.Value {
+ if int64(len(c.script)-1) < pc.Int64() {
+ return ethutil.NewValue(0)
+ }
+
+ return ethutil.NewValueFromBytes([]byte{c.script[pc.Int64()]})
+}
+
func (c *Contract) SetMem(num *big.Int, val *ethutil.Value) {
addr := ethutil.BigToBytes(num, 256)
c.state.trie.Update(string(addr), string(val.Encode()))
diff --git a/ethchain/vm.go b/ethchain/vm.go
index 98aaa603a..b4b2177bf 100644
--- a/ethchain/vm.go
+++ b/ethchain/vm.go
@@ -72,7 +72,7 @@ func (vm *Vm) RunClosure(closure *Closure) []byte {
for {
step++
// Get the memory location of pc
- val := closure.GetMem(pc)
+ val := closure.GetInstr(pc)
// Get the opcode (it must be an opcode!)
op := OpCode(val.Uint())
if ethutil.Config.Debug {
@@ -233,13 +233,37 @@ func (vm *Vm) RunClosure(closure *Closure) []byte {
// 0x10 range
case oAND:
+ x, y := stack.Popn()
+ if (x.Cmp(ethutil.BigTrue) >= 0) && (y.Cmp(ethutil.BigTrue) >= 0) {
+ stack.Push(ethutil.BigTrue)
+ } else {
+ stack.Push(ethutil.BigFalse)
+ }
+
case oOR:
+ x, y := stack.Popn()
+ if (x.Cmp(ethutil.BigInt0) >= 0) || (y.Cmp(ethutil.BigInt0) >= 0) {
+ stack.Push(ethutil.BigTrue)
+ } else {
+ stack.Push(ethutil.BigFalse)
+ }
case oXOR:
+ x, y := stack.Popn()
+ stack.Push(base.Xor(x, y))
case oBYTE:
+ val, th := stack.Popn()
+ if th.Cmp(big.NewInt(32)) < 0 {
+ stack.Push(big.NewInt(int64(len(val.Bytes())-1) - th.Int64()))
+ } else {
+ stack.Push(ethutil.BigFalse)
+ }
// 0x20 range
case oSHA3:
+ size, offset := stack.Popn()
+ data := mem.Get(offset.Int64(), size.Int64())
+ stack.Push(ethutil.BigD(data))
// 0x30 range
case oADDRESS:
stack.Push(ethutil.BigD(closure.Object().Address()))