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  }