aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorobscuren <geffobscura@gmail.com>2015-03-29 03:30:16 +0800
committerobscuren <geffobscura@gmail.com>2015-03-29 03:30:38 +0800
commit368ebe63a95c870a90dba8635d3a5c3863c43330 (patch)
treea70dc5f0554c91f9f4ec027ae913d1390881ec18
parent3b7e4173ce00fb82ee2f186350dd2aca528ea60d (diff)
downloaddexon-368ebe63a95c870a90dba8635d3a5c3863c43330.tar
dexon-368ebe63a95c870a90dba8635d3a5c3863c43330.tar.gz
dexon-368ebe63a95c870a90dba8635d3a5c3863c43330.tar.bz2
dexon-368ebe63a95c870a90dba8635d3a5c3863c43330.tar.lz
dexon-368ebe63a95c870a90dba8635d3a5c3863c43330.tar.xz
dexon-368ebe63a95c870a90dba8635d3a5c3863c43330.tar.zst
dexon-368ebe63a95c870a90dba8635d3a5c3863c43330.zip
Cleanup VM.
* CALLDATA use getData * removed old context get range value * removed casting big => int for some cases * pc now big int #457
-rw-r--r--core/vm/analysis.go24
-rw-r--r--core/vm/common.go1
-rw-r--r--core/vm/context.go20
-rw-r--r--core/vm/vm.go56
4 files changed, 45 insertions, 56 deletions
diff --git a/core/vm/analysis.go b/core/vm/analysis.go
index 411df5686..264d55cb9 100644
--- a/core/vm/analysis.go
+++ b/core/vm/analysis.go
@@ -1,9 +1,25 @@
package vm
-import "gopkg.in/fatih/set.v0"
+import (
+ "math/big"
-func analyseJumpDests(code []byte) (dests *set.Set) {
- dests = set.New()
+ "gopkg.in/fatih/set.v0"
+)
+
+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++ {
var op OpCode = OpCode(code[pc])
@@ -13,7 +29,7 @@ func analyseJumpDests(code []byte) (dests *set.Set) {
pc += a
case JUMPDEST:
- dests.Add(pc)
+ dests.Add(big.NewInt(int64(pc)))
}
}
return
diff --git a/core/vm/common.go b/core/vm/common.go
index 5226f4828..5ff4e05f2 100644
--- a/core/vm/common.go
+++ b/core/vm/common.go
@@ -33,6 +33,7 @@ var (
S256 = common.S256
Zero = common.Big0
+ One = common.Big1
max = big.NewInt(math.MaxInt64)
)
diff --git a/core/vm/context.go b/core/vm/context.go
index e4b94b600..29bb9f74e 100644
--- a/core/vm/context.go
+++ b/core/vm/context.go
@@ -1,7 +1,6 @@
package vm
import (
- "math"
"math/big"
"github.com/ethereum/go-ethereum/common"
@@ -41,29 +40,18 @@ func NewContext(caller ContextRef, object ContextRef, value, gas, price *big.Int
return c
}
-func (c *Context) GetOp(n uint64) OpCode {
+func (c *Context) GetOp(n *big.Int) OpCode {
return OpCode(c.GetByte(n))
}
-func (c *Context) GetByte(n uint64) byte {
- if n < uint64(len(c.Code)) {
- return c.Code[n]
+func (c *Context) GetByte(n *big.Int) byte {
+ if n.Cmp(big.NewInt(int64(len(c.Code)))) < 0 {
+ return c.Code[n.Int64()]
}
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 {
// Return the remaining gas to the caller
c.caller.ReturnGas(c.Gas, c.Price)
diff --git a/core/vm/vm.go b/core/vm/vm.go
index eceb6e3a9..6c3dd240a 100644
--- a/core/vm/vm.go
+++ b/core/vm/vm.go
@@ -72,23 +72,20 @@ func (self *Vm) Run(context *Context, callData []byte) (ret []byte, err error) {
var (
op OpCode
- destinations = analyseJumpDests(context.Code)
- mem = NewMemory()
- stack = newStack()
- pc uint64 = 0
- step = 0
- statedb = self.env.State()
-
- jump = func(from uint64, to *big.Int) error {
- p := to.Uint64()
-
- nop := context.GetOp(p)
- if !destinations.Has(p) {
- return fmt.Errorf("invalid jump destination (%v) %v", nop, p)
+ destinations = analyseJumpDests(context.Code)
+ mem = NewMemory()
+ stack = newStack()
+ pc = new(big.Int)
+ statedb = self.env.State()
+
+ jump = func(from *big.Int, to *big.Int) error {
+ nop := context.GetOp(to)
+ if !destinations.Has(to) {
+ return fmt.Errorf("invalid jump destination (%v) %v", nop, to)
}
self.Printf(" ~> %v", to)
- pc = to.Uint64()
+ pc = to
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
base := new(big.Int)
- step++
// Get the memory location of 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)
case CALLDATALOAD:
- var (
- 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()])
- }
+ data := getData(callData, stack.pop(), common.Big32)
self.Printf(" => 0x%x", data)
- stack.push(common.BigD(data))
+ stack.push(common.Bytes2Big(data))
case CALLDATASIZE:
l := int64(len(callData))
stack.push(big.NewInt(l))
@@ -542,13 +527,11 @@ func (self *Vm) Run(context *Context, callData []byte) (ret []byte, err error) {
// 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:
- a := uint64(op - PUSH1 + 1)
- byts := context.GetRangeValue(pc+1, a)
+ a := big.NewInt(int64(op - PUSH1 + 1))
+ byts := getData(code, new(big.Int).Add(pc, big.NewInt(1)), a)
// push value to stack
- stack.push(common.BigD(byts))
- pc += a
-
- step += int(op) - int(PUSH1) + 1
+ stack.push(common.Bytes2Big(byts))
+ pc.Add(pc, a)
self.Printf(" => 0x%x", byts)
case POP:
@@ -628,7 +611,8 @@ func (self *Vm) Run(context *Context, callData []byte) (ret []byte, err error) {
case JUMPDEST:
case PC:
- stack.push(big.NewInt(int64(pc)))
+ //stack.push(big.NewInt(int64(pc)))
+ stack.push(pc)
case MSIZE:
stack.push(big.NewInt(int64(mem.Len())))
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)
}
- pc++
+ pc.Add(pc, One)
self.Endl()
}