You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

122 lines
2.0 KiB

9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
  1. package vm
  2. import (
  3. "fmt"
  4. . "github.com/tendermint/tendermint/common"
  5. )
  6. // Not goroutine safe
  7. type Stack struct {
  8. data []Word256
  9. ptr int
  10. gas *int64
  11. err *error
  12. }
  13. func NewStack(capacity int, gas *int64, err *error) *Stack {
  14. return &Stack{
  15. data: make([]Word256, capacity),
  16. ptr: 0,
  17. gas: gas,
  18. err: err,
  19. }
  20. }
  21. func (st *Stack) useGas(gasToUse int64) {
  22. if *st.gas > gasToUse {
  23. *st.gas -= gasToUse
  24. } else {
  25. st.setErr(ErrInsufficientGas)
  26. }
  27. }
  28. func (st *Stack) setErr(err error) {
  29. if *st.err == nil {
  30. *st.err = err
  31. }
  32. }
  33. func (st *Stack) Push(d Word256) {
  34. st.useGas(GasStackOp)
  35. if st.ptr == cap(st.data) {
  36. st.setErr(ErrDataStackOverflow)
  37. return
  38. }
  39. st.data[st.ptr] = d
  40. st.ptr++
  41. }
  42. // currently only called after Sha3
  43. func (st *Stack) PushBytes(bz []byte) {
  44. if len(bz) != 32 {
  45. panic("Invalid bytes size: expected 32")
  46. }
  47. st.Push(LeftPadWord256(bz))
  48. }
  49. func (st *Stack) Push64(i int64) {
  50. st.Push(Int64ToWord256(i))
  51. }
  52. func (st *Stack) Pop() Word256 {
  53. st.useGas(GasStackOp)
  54. if st.ptr == 0 {
  55. st.setErr(ErrDataStackUnderflow)
  56. return Zero256
  57. }
  58. st.ptr--
  59. return st.data[st.ptr]
  60. }
  61. func (st *Stack) PopBytes() []byte {
  62. return st.Pop().Bytes()
  63. }
  64. func (st *Stack) Pop64() int64 {
  65. d := st.Pop()
  66. return Int64FromWord256(d)
  67. }
  68. func (st *Stack) Len() int {
  69. return st.ptr
  70. }
  71. func (st *Stack) Swap(n int) {
  72. st.useGas(GasStackOp)
  73. if st.ptr < n {
  74. st.setErr(ErrDataStackUnderflow)
  75. return
  76. }
  77. st.data[st.ptr-n], st.data[st.ptr-1] = st.data[st.ptr-1], st.data[st.ptr-n]
  78. return
  79. }
  80. func (st *Stack) Dup(n int) {
  81. st.useGas(GasStackOp)
  82. if st.ptr < n {
  83. st.setErr(ErrDataStackUnderflow)
  84. return
  85. }
  86. st.Push(st.data[st.ptr-n])
  87. return
  88. }
  89. // Not an opcode, costs no gas.
  90. func (st *Stack) Peek() Word256 {
  91. return st.data[st.ptr-1]
  92. }
  93. func (st *Stack) Print(n int) {
  94. fmt.Println("### stack ###")
  95. if st.ptr > 0 {
  96. nn := MinInt(n, st.ptr)
  97. for j, i := 0, st.ptr-1; i > st.ptr-1-nn; i-- {
  98. fmt.Printf("%-3d %X\n", j, st.data[i])
  99. j += 1
  100. }
  101. } else {
  102. fmt.Println("-- empty --")
  103. }
  104. fmt.Println("#############")
  105. }