Commit 55e55826 authored by obscuren's avatar obscuren

Changed JUMP(I) behaviour.

* All jumps must land on a JUMPDEST instruction byte.
* The byte may not be part of a PUSH*
parent 53095305
...@@ -78,6 +78,12 @@ func RunVmTest(p string, t *testing.T) { ...@@ -78,6 +78,12 @@ func RunVmTest(p string, t *testing.T) {
helper.CreateFileTests(t, p, &tests) helper.CreateFileTests(t, p, &tests)
for name, test := range tests { for name, test := range tests {
/*
helper.Logger.SetLogLevel(5)
if name != "jump0_jumpdest2" {
continue
}
*/
statedb := state.New(helper.NewTrie()) statedb := state.New(helper.NewTrie())
for addr, account := range test.Pre { for addr, account := range test.Pre {
obj := StateObjectFromAccount(addr, account) obj := StateObjectFromAccount(addr, account)
...@@ -127,7 +133,7 @@ func RunVmTest(p string, t *testing.T) { ...@@ -127,7 +133,7 @@ func RunVmTest(p string, t *testing.T) {
if isVmTest { if isVmTest {
if len(test.Gas) == 0 && err == nil { if len(test.Gas) == 0 && err == nil {
t.Errorf("%s's gas unspecified, indicating an error. VM returned (incorrectly) successfull") t.Errorf("%s's gas unspecified, indicating an error. VM returned (incorrectly) successfull", name)
} else { } else {
gexp := ethutil.Big(test.Gas) gexp := ethutil.Big(test.Gas)
if gexp.Cmp(gas) != 0 { if gexp.Cmp(gas) != 0 {
......
package vm package vm
import ( import "gopkg.in/fatih/set.v0"
"math/big"
"github.com/ethereum/go-ethereum/ethutil" func analyseJumpDests(code []byte) (dests *set.Set) {
) dests = set.New()
func analyseJumpDests(code []byte) (dests map[uint64]*big.Int) {
dests = make(map[uint64]*big.Int)
lp := false
var lpv *big.Int
for pc := uint64(0); pc < uint64(len(code)); pc++ { for pc := uint64(0); pc < uint64(len(code)); pc++ {
var op OpCode = OpCode(code[pc]) var op OpCode = OpCode(code[pc])
switch op { switch op {
case PUSH1, PUSH2, PUSH3, PUSH4, PUSH5, PUSH6, PUSH7, PUSH8, PUSH9, PUSH10, PUSH11, PUSH12, PUSH13, PUSH14, PUSH15, PUSH16, PUSH17, PUSH18, PUSH19, PUSH20, PUSH21, PUSH22, PUSH23, PUSH24, PUSH25, PUSH26, PUSH27, PUSH28, PUSH29, PUSH30, PUSH31, PUSH32: case PUSH1, PUSH2, PUSH3, PUSH4, PUSH5, PUSH6, PUSH7, PUSH8, PUSH9, PUSH10, PUSH11, PUSH12, PUSH13, PUSH14, PUSH15, PUSH16, PUSH17, PUSH18, PUSH19, PUSH20, PUSH21, PUSH22, PUSH23, PUSH24, PUSH25, PUSH26, PUSH27, PUSH28, PUSH29, PUSH30, PUSH31, PUSH32:
a := uint64(op) - uint64(PUSH1) + 1 a := uint64(op) - uint64(PUSH1) + 1
if uint64(len(code)) > pc+1+a {
lpv = ethutil.BigD(code[pc+1 : pc+1+a])
}
pc += a pc += a
lp = true //lp = true
case JUMP, JUMPI: case JUMPDEST:
if lp { dests.Add(pc)
dests[pc] = lpv
}
default:
lp = false
} }
} }
return return
......
...@@ -83,29 +83,13 @@ func (self *DebugVm) Run(me, caller ContextRef, code []byte, value, gas, price * ...@@ -83,29 +83,13 @@ func (self *DebugVm) Run(me, caller ContextRef, code []byte, value, gas, price *
jump = func(from uint64, to *big.Int) { jump = func(from uint64, to *big.Int) {
p := to.Uint64() p := to.Uint64()
self.Printf(" ~> %v", to)
/* NOTE: new model. Will change soon
nop := OpCode(context.GetOp(p)) nop := OpCode(context.GetOp(p))
if nop != JUMPDEST { if !destinations.Has(p) {
panic(fmt.Sprintf("invalid jump destination (%v) %v", nop, p)) panic(fmt.Sprintf("invalid jump destination (%v) %v", nop, p))
} }
self.Printf(" ~> %v", to)
pc = to.Uint64() pc = to.Uint64()
*/
// Return to start
if p == 0 {
pc = 0
} else {
nop := OpCode(context.GetOp(p))
if !(nop == JUMPDEST || destinations[from] != nil) {
panic(fmt.Sprintf("invalid jump destination (%v) %v", nop, p))
} else if nop == JUMP || nop == JUMPI {
panic(fmt.Sprintf("not allowed to JUMP(I) in to JUMP"))
}
pc = to.Uint64()
}
self.Endl() self.Endl()
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment