github.com/sberex/go-sberex@v1.8.2-0.20181113200658-ed96ac38f7d7/core/vm/stack.go (about) 1 // This file is part of the go-sberex library. The go-sberex library is 2 // free software: you can redistribute it and/or modify it under the terms 3 // of the GNU Lesser General Public License as published by the Free 4 // Software Foundation, either version 3 of the License, or (at your option) 5 // any later version. 6 // 7 // The go-sberex library is distributed in the hope that it will be useful, 8 // but WITHOUT ANY WARRANTY; without even the implied warranty of 9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 10 // General Public License <http://www.gnu.org/licenses/> for more details. 11 12 package vm 13 14 import ( 15 "fmt" 16 "math/big" 17 ) 18 19 // stack is an object for basic stack operations. Items popped to the stack are 20 // expected to be changed and modified. stack does not take care of adding newly 21 // initialised objects. 22 type Stack struct { 23 data []*big.Int 24 } 25 26 func newstack() *Stack { 27 return &Stack{data: make([]*big.Int, 0, 1024)} 28 } 29 30 func (st *Stack) Data() []*big.Int { 31 return st.data 32 } 33 34 func (st *Stack) push(d *big.Int) { 35 // NOTE push limit (1024) is checked in baseCheck 36 //stackItem := new(big.Int).Set(d) 37 //st.data = append(st.data, stackItem) 38 st.data = append(st.data, d) 39 } 40 func (st *Stack) pushN(ds ...*big.Int) { 41 st.data = append(st.data, ds...) 42 } 43 44 func (st *Stack) pop() (ret *big.Int) { 45 ret = st.data[len(st.data)-1] 46 st.data = st.data[:len(st.data)-1] 47 return 48 } 49 50 func (st *Stack) len() int { 51 return len(st.data) 52 } 53 54 func (st *Stack) swap(n int) { 55 st.data[st.len()-n], st.data[st.len()-1] = st.data[st.len()-1], st.data[st.len()-n] 56 } 57 58 func (st *Stack) dup(pool *intPool, n int) { 59 st.push(pool.get().Set(st.data[st.len()-n])) 60 } 61 62 func (st *Stack) peek() *big.Int { 63 return st.data[st.len()-1] 64 } 65 66 // Back returns the n'th item in stack 67 func (st *Stack) Back(n int) *big.Int { 68 return st.data[st.len()-n-1] 69 } 70 71 func (st *Stack) require(n int) error { 72 if st.len() < n { 73 return fmt.Errorf("stack underflow (%d <=> %d)", len(st.data), n) 74 } 75 return nil 76 } 77 78 func (st *Stack) Print() { 79 fmt.Println("### stack ###") 80 if len(st.data) > 0 { 81 for i, val := range st.data { 82 fmt.Printf("%-3d %v\n", i, val) 83 } 84 } else { 85 fmt.Println("-- empty --") 86 } 87 fmt.Println("#############") 88 }