stack.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. package vm
  2. import (
  3. "fmt"
  4. "math"
  5. "math/big"
  6. )
  7. type OpType int
  8. const (
  9. tNorm = iota
  10. tData
  11. tExtro
  12. tCrypto
  13. )
  14. type TxCallback func(opType OpType) bool
  15. // Simple push/pop stack mechanism
  16. type Stack struct {
  17. data []*big.Int
  18. }
  19. func NewStack() *Stack {
  20. return &Stack{}
  21. }
  22. func (st *Stack) Data() []*big.Int {
  23. return st.data
  24. }
  25. func (st *Stack) Len() int {
  26. return len(st.data)
  27. }
  28. func (st *Stack) Pop() *big.Int {
  29. str := st.data[len(st.data)-1]
  30. copy(st.data[:len(st.data)-1], st.data[:len(st.data)-1])
  31. st.data = st.data[:len(st.data)-1]
  32. return str
  33. }
  34. func (st *Stack) Popn() (*big.Int, *big.Int) {
  35. ints := st.data[len(st.data)-2:]
  36. copy(st.data[:len(st.data)-2], st.data[:len(st.data)-2])
  37. st.data = st.data[:len(st.data)-2]
  38. return ints[0], ints[1]
  39. }
  40. func (st *Stack) Peek() *big.Int {
  41. str := st.data[len(st.data)-1]
  42. return str
  43. }
  44. func (st *Stack) Peekn() (*big.Int, *big.Int) {
  45. ints := st.data[len(st.data)-2:]
  46. return ints[0], ints[1]
  47. }
  48. func (st *Stack) Swapn(n int) (*big.Int, *big.Int) {
  49. st.data[len(st.data)-n], st.data[len(st.data)-1] = st.data[len(st.data)-1], st.data[len(st.data)-n]
  50. return st.data[len(st.data)-n], st.data[len(st.data)-1]
  51. }
  52. func (st *Stack) Dupn(n int) *big.Int {
  53. st.Push(st.data[len(st.data)-n])
  54. return st.Peek()
  55. }
  56. func (st *Stack) Push(d *big.Int) {
  57. st.data = append(st.data, new(big.Int).Set(d))
  58. }
  59. func (st *Stack) Get(amount *big.Int) []*big.Int {
  60. // offset + size <= len(data)
  61. length := big.NewInt(int64(len(st.data)))
  62. if amount.Cmp(length) <= 0 {
  63. start := new(big.Int).Sub(length, amount)
  64. return st.data[start.Int64():length.Int64()]
  65. }
  66. return nil
  67. }
  68. func (st *Stack) Print() {
  69. fmt.Println("### stack ###")
  70. if len(st.data) > 0 {
  71. for i, val := range st.data {
  72. fmt.Printf("%-3d %v\n", i, val)
  73. }
  74. } else {
  75. fmt.Println("-- empty --")
  76. }
  77. fmt.Println("#############")
  78. }
  79. type Memory struct {
  80. store []byte
  81. }
  82. func NewMemory() *Memory {
  83. return &Memory{nil}
  84. }
  85. func (m *Memory) Set(offset, size int64, value []byte) {
  86. if len(value) > 0 {
  87. totSize := offset + size
  88. lenSize := int64(len(m.store) - 1)
  89. if totSize > lenSize {
  90. // Calculate the diff between the sizes
  91. diff := totSize - lenSize
  92. if diff > 0 {
  93. // Create a new empty slice and append it
  94. newSlice := make([]byte, diff-1)
  95. // Resize slice
  96. m.store = append(m.store, newSlice...)
  97. }
  98. }
  99. copy(m.store[offset:offset+size], value)
  100. }
  101. }
  102. func (m *Memory) Resize(size uint64) {
  103. if uint64(m.Len()) < size {
  104. m.store = append(m.store, make([]byte, size-uint64(m.Len()))...)
  105. }
  106. }
  107. func (m *Memory) Get(offset, size int64) []byte {
  108. if len(m.store) > int(offset) {
  109. end := int(math.Min(float64(len(m.store)), float64(offset+size)))
  110. return m.store[offset:end]
  111. }
  112. return nil
  113. }
  114. func (self *Memory) Geti(offset, size int64) (cpy []byte) {
  115. if len(self.store) > int(offset) {
  116. cpy = make([]byte, size)
  117. copy(cpy, self.store[offset:offset+size])
  118. return
  119. }
  120. return
  121. }
  122. func (m *Memory) Len() int {
  123. return len(m.store)
  124. }
  125. func (m *Memory) Data() []byte {
  126. return m.store
  127. }
  128. func (m *Memory) Print() {
  129. fmt.Printf("### mem %d bytes ###\n", len(m.store))
  130. if len(m.store) > 0 {
  131. addr := 0
  132. for i := 0; i+32 <= len(m.store); i += 32 {
  133. fmt.Printf("%03d: % x\n", addr, m.store[i:i+32])
  134. addr++
  135. }
  136. } else {
  137. fmt.Println("-- empty --")
  138. }
  139. fmt.Println("####################")
  140. }