diff options
Diffstat (limited to 'ethchain/vm.go')
-rw-r--r-- | ethchain/vm.go | 63 |
1 files changed, 51 insertions, 12 deletions
diff --git a/ethchain/vm.go b/ethchain/vm.go index 98aaa603a..dd99ee790 100644 --- a/ethchain/vm.go +++ b/ethchain/vm.go @@ -2,7 +2,7 @@ package ethchain import ( _ "bytes" - "fmt" + _ "fmt" "github.com/ethereum/eth-go/ethutil" _ "github.com/obscuren/secp256k1-go" _ "math" @@ -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.Get(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())) @@ -277,9 +301,23 @@ func (vm *Vm) RunClosure(closure *Closure) []byte { // 0x50 range case oPUSH: // Push PC+1 on to the stack pc.Add(pc, ethutil.Big1) + data := closure.Gets(pc, big.NewInt(32)) + val := ethutil.BigD(data.Bytes()) + + // Push value to stack + stack.Push(val) + + pc.Add(pc, big.NewInt(31)) + case oPUSH20: + pc.Add(pc, ethutil.Big1) + data := closure.Gets(pc, big.NewInt(20)) + val := ethutil.BigD(data.Bytes()) - val := closure.GetMem(pc).BigInt() + // Push value to stack stack.Push(val) + + pc.Add(pc, big.NewInt(19)) + case oPOP: stack.Pop() case oDUP: @@ -319,21 +357,20 @@ func (vm *Vm) RunClosure(closure *Closure) []byte { stack.Push(big.NewInt(int64(mem.Len()))) // 0x60 range case oCALL: - // Pop return size and offset - retSize, retOffset := stack.Popn() + // Closure addr + addr := stack.Pop() + // Pop gas and value of the stack. + gas, value := stack.Popn() // Pop input size and offset inSize, inOffset := stack.Popn() - fmt.Println(inSize, inOffset) + // Pop return size and offset + retSize, retOffset := stack.Popn() // Get the arguments from the memory args := mem.Get(inOffset.Int64(), inSize.Int64()) - // Pop gas and value of the stack. - gas, value := stack.Popn() - // Closure addr - addr := stack.Pop() // Fetch the contract which will serve as the closure body contract := vm.state.GetContract(addr.Bytes()) // Create a new callable closure - closure := NewClosure(closure, contract, vm.state, gas, value) + closure := NewClosure(closure, contract, contract.script, vm.state, gas, value) // Executer the closure and get the return value (if any) ret := closure.Call(vm, args) @@ -361,7 +398,9 @@ func (vm *Vm) RunClosure(closure *Closure) []byte { break out */ default: - ethutil.Config.Log.Debugln("Invalid opcode", op) + ethutil.Config.Log.Debugf("Invalid opcode %x\n", op) + + return closure.Return(nil) } pc.Add(pc, ethutil.Big1) |