Cleanup VM.

* CALLDATA use getData
* removed old context get range value
* removed casting big => int for some cases
* pc now big int #457
release/1.0.1
obscuren 10 years ago
parent 3b7e4173ce
commit 368ebe63a9
  1. 24
      core/vm/analysis.go
  2. 1
      core/vm/common.go
  3. 20
      core/vm/context.go
  4. 46
      core/vm/vm.go

@ -1,9 +1,25 @@
package vm package vm
import "gopkg.in/fatih/set.v0" import (
"math/big"
func analyseJumpDests(code []byte) (dests *set.Set) { "gopkg.in/fatih/set.v0"
dests = set.New() )
type destinations struct {
set *set.Set
}
func (d *destinations) Has(dest *big.Int) bool {
return d.set.Has(string(dest.Bytes()))
}
func (d *destinations) Add(dest *big.Int) {
d.set.Add(string(dest.Bytes()))
}
func analyseJumpDests(code []byte) (dests *destinations) {
dests = &destinations{set.New()}
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])
@ -13,7 +29,7 @@ func analyseJumpDests(code []byte) (dests *set.Set) {
pc += a pc += a
case JUMPDEST: case JUMPDEST:
dests.Add(pc) dests.Add(big.NewInt(int64(pc)))
} }
} }
return return

@ -33,6 +33,7 @@ var (
S256 = common.S256 S256 = common.S256
Zero = common.Big0 Zero = common.Big0
One = common.Big1
max = big.NewInt(math.MaxInt64) max = big.NewInt(math.MaxInt64)
) )

@ -1,7 +1,6 @@
package vm package vm
import ( import (
"math"
"math/big" "math/big"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
@ -41,29 +40,18 @@ func NewContext(caller ContextRef, object ContextRef, value, gas, price *big.Int
return c return c
} }
func (c *Context) GetOp(n uint64) OpCode { func (c *Context) GetOp(n *big.Int) OpCode {
return OpCode(c.GetByte(n)) return OpCode(c.GetByte(n))
} }
func (c *Context) GetByte(n uint64) byte { func (c *Context) GetByte(n *big.Int) byte {
if n < uint64(len(c.Code)) { if n.Cmp(big.NewInt(int64(len(c.Code)))) < 0 {
return c.Code[n] return c.Code[n.Int64()]
} }
return 0 return 0
} }
func (c *Context) GetBytes(x, y int) []byte {
return c.GetRangeValue(uint64(x), uint64(y))
}
func (c *Context) GetRangeValue(x, size uint64) []byte {
x = uint64(math.Min(float64(x), float64(len(c.Code))))
y := uint64(math.Min(float64(x+size), float64(len(c.Code))))
return common.RightPadBytes(c.Code[x:y], int(size))
}
func (c *Context) Return(ret []byte) []byte { func (c *Context) Return(ret []byte) []byte {
// Return the remaining gas to the caller // Return the remaining gas to the caller
c.caller.ReturnGas(c.Gas, c.Price) c.caller.ReturnGas(c.Gas, c.Price)

@ -75,20 +75,17 @@ func (self *Vm) Run(context *Context, callData []byte) (ret []byte, err error) {
destinations = analyseJumpDests(context.Code) destinations = analyseJumpDests(context.Code)
mem = NewMemory() mem = NewMemory()
stack = newStack() stack = newStack()
pc uint64 = 0 pc = new(big.Int)
step = 0
statedb = self.env.State() statedb = self.env.State()
jump = func(from uint64, to *big.Int) error { jump = func(from *big.Int, to *big.Int) error {
p := to.Uint64() nop := context.GetOp(to)
if !destinations.Has(to) {
nop := context.GetOp(p) return fmt.Errorf("invalid jump destination (%v) %v", nop, to)
if !destinations.Has(p) {
return fmt.Errorf("invalid jump destination (%v) %v", nop, p)
} }
self.Printf(" ~> %v", to) self.Printf(" ~> %v", to)
pc = to.Uint64() pc = to
self.Endl() self.Endl()
@ -105,7 +102,6 @@ func (self *Vm) Run(context *Context, callData []byte) (ret []byte, err error) {
// The base for all big integer arithmetic // The base for all big integer arithmetic
base := new(big.Int) base := new(big.Int)
step++
// Get the memory location of pc // Get the memory location of pc
op = context.GetOp(pc) op = context.GetOp(pc)
@ -428,22 +424,11 @@ func (self *Vm) Run(context *Context, callData []byte) (ret []byte, err error) {
self.Printf(" => %v", value) self.Printf(" => %v", value)
case CALLDATALOAD: case CALLDATALOAD:
var ( data := getData(callData, stack.pop(), common.Big32)
offset = stack.pop()
data = make([]byte, 32)
lenData = big.NewInt(int64(len(callData)))
)
if lenData.Cmp(offset) >= 0 {
length := new(big.Int).Add(offset, common.Big32)
length = common.BigMin(length, lenData)
copy(data, callData[offset.Int64():length.Int64()])
}
self.Printf(" => 0x%x", data) self.Printf(" => 0x%x", data)
stack.push(common.BigD(data)) stack.push(common.Bytes2Big(data))
case CALLDATASIZE: case CALLDATASIZE:
l := int64(len(callData)) l := int64(len(callData))
stack.push(big.NewInt(l)) stack.push(big.NewInt(l))
@ -542,13 +527,11 @@ func (self *Vm) Run(context *Context, callData []byte) (ret []byte, err error) {
// 0x50 range // 0x50 range
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 - PUSH1 + 1) a := big.NewInt(int64(op - PUSH1 + 1))
byts := context.GetRangeValue(pc+1, a) byts := getData(code, new(big.Int).Add(pc, big.NewInt(1)), a)
// push value to stack // push value to stack
stack.push(common.BigD(byts)) stack.push(common.Bytes2Big(byts))
pc += a pc.Add(pc, a)
step += int(op) - int(PUSH1) + 1
self.Printf(" => 0x%x", byts) self.Printf(" => 0x%x", byts)
case POP: case POP:
@ -628,7 +611,8 @@ func (self *Vm) Run(context *Context, callData []byte) (ret []byte, err error) {
case JUMPDEST: case JUMPDEST:
case PC: case PC:
stack.push(big.NewInt(int64(pc))) //stack.push(big.NewInt(int64(pc)))
stack.push(pc)
case MSIZE: case MSIZE:
stack.push(big.NewInt(int64(mem.Len()))) stack.push(big.NewInt(int64(mem.Len())))
case GAS: case GAS:
@ -734,7 +718,7 @@ func (self *Vm) Run(context *Context, callData []byte) (ret []byte, err error) {
return nil, fmt.Errorf("Invalid opcode %x", op) return nil, fmt.Errorf("Invalid opcode %x", op)
} }
pc++ pc.Add(pc, One)
self.Endl() self.Endl()
} }

Loading…
Cancel
Save