Changed JUMP(I) behaviour.

* All jumps must land on a JUMPDEST instruction byte.
* The byte may not be part of a PUSH*
pull/229/merge
obscuren 10 years ago
parent 530953050a
commit 55e55826ee
  1. 8
      tests/vm/gh_test.go
  2. 26
      vm/analysis.go
  3. 20
      vm/vm_debug.go

@ -78,6 +78,12 @@ func RunVmTest(p string, t *testing.T) {
helper.CreateFileTests(t, p, &tests)
for name, test := range tests {
/*
helper.Logger.SetLogLevel(5)
if name != "jump0_jumpdest2" {
continue
}
*/
statedb := state.New(helper.NewTrie())
for addr, account := range test.Pre {
obj := StateObjectFromAccount(addr, account)
@ -127,7 +133,7 @@ func RunVmTest(p string, t *testing.T) {
if isVmTest {
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 {
gexp := ethutil.Big(test.Gas)
if gexp.Cmp(gas) != 0 {

@ -1,34 +1,20 @@
package vm
import (
"math/big"
import "gopkg.in/fatih/set.v0"
"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++ {
var op OpCode = OpCode(code[pc])
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:
a := uint64(op) - uint64(PUSH1) + 1
if uint64(len(code)) > pc+1+a {
lpv = ethutil.BigD(code[pc+1 : pc+1+a])
}
pc += a
lp = true
case JUMP, JUMPI:
if lp {
dests[pc] = lpv
}
default:
lp = false
//lp = true
case JUMPDEST:
dests.Add(pc)
}
}
return

@ -83,29 +83,13 @@ func (self *DebugVm) Run(me, caller ContextRef, code []byte, value, gas, price *
jump = func(from uint64, to *big.Int) {
p := to.Uint64()
self.Printf(" ~> %v", to)
/* NOTE: new model. Will change soon
nop := OpCode(context.GetOp(p))
if nop != JUMPDEST {
if !destinations.Has(p) {
panic(fmt.Sprintf("invalid jump destination (%v) %v", nop, p))
}
self.Printf(" ~> %v", to)
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()
}

Loading…
Cancel
Save