diff options
Diffstat (limited to 'core/vm/stack.go')
-rw-r--r-- | core/vm/stack.go | 84 |
1 files changed, 60 insertions, 24 deletions
diff --git a/core/vm/stack.go b/core/vm/stack.go index 4c1b9e8..af27d65 100644 --- a/core/vm/stack.go +++ b/core/vm/stack.go @@ -18,36 +18,48 @@ package vm import ( "fmt" - "math/big" + "sync" + + "github.com/holiman/uint256" ) +var stackPool = sync.Pool{ + New: func() interface{} { + return &Stack{data: make([]uint256.Int, 0, 16)} + }, +} + // Stack is an object for basic stack operations. Items popped to the stack are // expected to be changed and modified. stack does not take care of adding newly // initialised objects. type Stack struct { - data []*big.Int + data []uint256.Int } func newstack() *Stack { - return &Stack{data: make([]*big.Int, 0, 1024)} + return stackPool.Get().(*Stack) } -// Data returns the underlying big.Int array. -func (st *Stack) Data() []*big.Int { +func returnStack(s *Stack) { + s.data = s.data[:0] + stackPool.Put(s) +} + +// Data returns the underlying uint256.Int array. +func (st *Stack) Data() []uint256.Int { return st.data } -func (st *Stack) push(d *big.Int) { +func (st *Stack) push(d *uint256.Int) { // NOTE push limit (1024) is checked in baseCheck - //stackItem := new(big.Int).Set(d) - //st.data = append(st.data, stackItem) - st.data = append(st.data, d) + st.data = append(st.data, *d) } -func (st *Stack) pushN(ds ...*big.Int) { +func (st *Stack) pushN(ds ...uint256.Int) { + // FIXME: Is there a way to pass args by pointers. st.data = append(st.data, ds...) } -func (st *Stack) pop() (ret *big.Int) { +func (st *Stack) pop() (ret uint256.Int) { ret = st.data[len(st.data)-1] st.data = st.data[:len(st.data)-1] return @@ -61,24 +73,17 @@ func (st *Stack) swap(n int) { st.data[st.len()-n], st.data[st.len()-1] = st.data[st.len()-1], st.data[st.len()-n] } -func (st *Stack) dup(pool *intPool, n int) { - st.push(pool.get().Set(st.data[st.len()-n])) +func (st *Stack) dup(n int) { + st.push(&st.data[st.len()-n]) } -func (st *Stack) peek() *big.Int { - return st.data[st.len()-1] +func (st *Stack) peek() *uint256.Int { + return &st.data[st.len()-1] } // Back returns the n'th item in stack -func (st *Stack) Back(n int) *big.Int { - return st.data[st.len()-n-1] -} - -func (st *Stack) require(n int) error { - if st.len() < n { - return fmt.Errorf("stack underflow (%d <=> %d)", len(st.data), n) - } - return nil +func (st *Stack) Back(n int) *uint256.Int { + return &st.data[st.len()-n-1] } // Print dumps the content of the stack @@ -93,3 +98,34 @@ func (st *Stack) Print() { } fmt.Println("#############") } + +var rStackPool = sync.Pool{ + New: func() interface{} { + return &ReturnStack{data: make([]uint32, 0, 10)} + }, +} + +// ReturnStack is an object for basic return stack operations. +type ReturnStack struct { + data []uint32 +} + +func newReturnStack() *ReturnStack { + return rStackPool.Get().(*ReturnStack) +} + +func returnRStack(rs *ReturnStack) { + rs.data = rs.data[:0] + rStackPool.Put(rs) +} + +func (st *ReturnStack) push(d uint32) { + st.data = append(st.data, d) +} + +// A uint32 is sufficient as for code below 4.2G +func (st *ReturnStack) pop() (ret uint32) { + ret = st.data[len(st.data)-1] + st.data = st.data[:len(st.data)-1] + return +} |