aboutsummaryrefslogtreecommitdiffstats
path: root/ethchain/stack.go
blob: 2883600627ed7fb28253183d8f417175b5b95c21 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
package ethchain

import (
    "fmt"
    _ "github.com/ethereum/eth-go/ethutil"
    "math/big"
)

type OpType int

const (
    tNorm = iota
    tData
    tExtro
    tCrypto
)

type TxCallback func(opType OpType) bool

// Simple push/pop stack mechanism
type Stack struct {
    data []*big.Int
}

func NewStack() *Stack {
    return &Stack{}
}

func (st *Stack) Data() []*big.Int {
    return st.data
}

func (st *Stack) Len() int {
    return len(st.data)
}

func (st *Stack) Pop() *big.Int {
    str := st.data[len(st.data)-1]

    copy(st.data[:len(st.data)-1], st.data[:len(st.data)-1])
    st.data = st.data[:len(st.data)-1]

    return str
}

func (st *Stack) Popn() (*big.Int, *big.Int) {
    ints := st.data[len(st.data)-2:]

    copy(st.data[:len(st.data)-2], st.data[:len(st.data)-2])
    st.data = st.data[:len(st.data)-2]

    return ints[0], ints[1]
}

func (st *Stack) Peek() *big.Int {
    str := st.data[len(st.data)-1]

    return str
}

func (st *Stack) Peekn() (*big.Int, *big.Int) {
    ints := st.data[:2]

    return ints[0], ints[1]
}

func (st *Stack) Push(d *big.Int) {
    st.data = append(st.data, d)
}
func (st *Stack) Print() {
    fmt.Println("### stack ###")
    if len(st.data) > 0 {
        for i, val := range st.data {
            fmt.Printf("%-3d  %v\n", i, val)
        }
    } else {
        fmt.Println("-- empty --")
    }
    fmt.Println("#############")
}

type Memory struct {
    store []byte
}

func (m *Memory) Set(offset, size int64, value []byte) {
    totSize := offset + size
    lenSize := int64(len(m.store) - 1)
    if totSize > lenSize {
        // Calculate the diff between the sizes
        diff := totSize - lenSize
        if diff > 0 {
            // Create a new empty slice and append it
            newSlice := make([]byte, diff-1)
            // Resize slice
            m.store = append(m.store, newSlice...)
        }
    }
    copy(m.store[offset:offset+size], value)
}

func (m *Memory) Get(offset, size int64) []byte {
    return m.store[offset : offset+size]
}

func (m *Memory) Len() int {
    return len(m.store)
}

func (m *Memory) Data() []byte {
    return m.store
}

func (m *Memory) Print() {
    fmt.Printf("### mem %d bytes ###\n", len(m.store))
    if len(m.store) > 0 {
        addr := 0
        for i := 0; i+32 <= len(m.store); i += 32 {
            fmt.Printf("%03d: % x\n", addr, m.store[i:i+32])
            addr++
        }
    } else {
        fmt.Println("-- empty --")
    }
    fmt.Println("####################")
}