@@ -3,7 +3,8 @@ package org.ton.kotlin.tvm
3
3
import org.ton.bigint.BigInt
4
4
import org.ton.bigint.sign
5
5
import org.ton.bigint.toBigInt
6
- import org.ton.kotlin.tvm.exception.StackOverflowException
6
+ import org.ton.cell.Cell
7
+ import org.ton.cell.CellSlice
7
8
import org.ton.kotlin.tvm.exception.StackUnderflowException
8
9
9
10
private const val INCREMENT = 256
@@ -18,33 +19,19 @@ public fun stackOf(vararg elements: Any): Stack {
18
19
19
20
public class Stack {
20
21
private var elements = arrayOfNulls<Any ?>(INCREMENT )
21
- public var top: Int = - 1
22
-
23
- public val depth: Int get() = top + 1
24
-
25
- public operator fun get (offset : Int ): Any? {
26
- if (offset < 0 || offset > depth) {
27
- throw StackUnderflowException ()
28
- }
29
- return elements[top - offset]
30
- }
31
22
32
- public operator fun set (offset : Int , operand : Any ) {
33
- if (offset < 0 ) {
34
- throw StackUnderflowException ()
35
- } else if (offset > top) {
36
- throw StackOverflowException ()
37
- }
38
- elements[top - offset] = operand
39
- }
23
+ public var depth: Int = 0
40
24
41
25
public fun pop (): Any {
42
- if (top < 0 ) {
26
+ val currentDepth = depth
27
+ if (currentDepth == 0 ) {
43
28
throw StackUnderflowException ()
44
29
}
45
30
val elements = elements
46
- val removed = elements[top]
47
- elements[top-- ] = null
31
+ val newDepth = currentDepth - 1
32
+ val removed = elements[newDepth]
33
+ elements[newDepth] = null
34
+ depth = newDepth
48
35
return removed as Any
49
36
}
50
37
@@ -56,33 +43,48 @@ public class Stack {
56
43
pushElement(value)
57
44
}
58
45
46
+ public fun pushCell (value : Cell ) {
47
+ pushElement(value)
48
+ }
49
+
50
+ public fun pushSlice (value : CellSlice ) {
51
+ pushElement(value)
52
+ }
53
+
54
+ public fun pushContinuation (value : TvmContinuation ) {
55
+ pushElement(value)
56
+ }
57
+
59
58
public fun pushElement (operand : Any ) {
60
- val nextTop = top + 1
59
+ val currentDepth = depth
61
60
var elements = elements
62
61
val currentCapacity = elements.size
63
- if (nextTop >= currentCapacity) {
62
+ val nextDepth = currentDepth + 1
63
+ if (nextDepth > currentCapacity) {
64
64
elements = elements.copyOf(currentCapacity + INCREMENT )
65
65
this .elements = elements
66
66
}
67
- elements[nextTop ] = operand
68
- top = nextTop
67
+ elements[currentDepth ] = operand
68
+ depth = nextDepth
69
69
}
70
70
71
71
public fun pushCopy (offset : Int ) {
72
72
var elements = elements
73
- val value = elements[top - offset]
74
- val nextTop = top + 1
73
+ val currentDepth = depth
74
+ val value = elements[currentDepth - 1 - offset]
75
+ val nextDepth = currentDepth + 1
75
76
val currentCapacity = elements.size
76
- if (nextTop >= currentCapacity) {
77
+ if (nextDepth > currentCapacity) {
77
78
elements = elements.copyOf(currentCapacity + INCREMENT )
78
79
this .elements = elements
79
80
}
80
- elements[nextTop ] = value
81
- top = nextTop
81
+ elements[currentDepth ] = value
82
+ depth = nextDepth
82
83
}
83
84
84
85
public fun reverse (fromOffset : Int , toOffset : Int ) {
85
86
val length = toOffset - fromOffset
87
+ val top = depth - 1
86
88
val fromIndex = top - fromOffset - 1
87
89
val toIndex = top - toOffset
88
90
val elements = elements
@@ -97,45 +99,57 @@ public class Stack {
97
99
}
98
100
99
101
public fun dropTop (count : Int ) {
100
- elements.fill(null , top - count + 1 , top + 1 )
101
- top - = count
102
+ val currentDepth = depth
103
+ val newDepth = currentDepth - count
104
+ elements.fill(null , newDepth, currentDepth)
105
+ depth = newDepth
102
106
}
103
107
104
108
public fun onlyTop (count : Int ) {
105
109
val elements = elements
106
- val top = top
107
- val toIndex = top + 1
108
- elements.copyInto(elements, 0 , top - count + 1 , toIndex)
109
- elements.fill(null , count, toIndex)
110
- this .top = count - 1
110
+ val currentDepth = depth
111
+ elements.copyInto(elements, 0 , currentDepth - count, currentDepth)
112
+ elements.fill(null , count, currentDepth)
113
+ depth = count
111
114
}
112
115
113
116
public fun rot () {
114
117
val elements = elements
115
- val a = elements[top - 2 ]
116
- val b = elements[top - 1 ]
117
- val c = elements[top]
118
- elements[top - 2 ] = b
119
- elements[top - 1 ] = c
120
- elements[top] = a
118
+ val depth = depth
119
+ val aIndex = depth - 3
120
+ val bIndex = depth - 2
121
+ val cIndex = depth - 1
122
+ val a = elements[aIndex]
123
+ val b = elements[bIndex]
124
+ val c = elements[cIndex]
125
+ elements[aIndex] = b
126
+ elements[bIndex] = c
127
+ elements[cIndex] = a
121
128
}
122
129
123
130
public fun rotRev () {
124
131
val elements = elements
125
- val a = elements[top - 2 ]
126
- val b = elements[top - 1 ]
127
- val c = elements[top]
128
- elements[top - 2 ] = c
129
- elements[top - 1 ] = a
130
- elements[top] = b
132
+ val depth = depth
133
+ val aIndex = depth - 3
134
+ val bIndex = depth - 2
135
+ val cIndex = depth - 1
136
+ val a = elements[aIndex]
137
+ val b = elements[bIndex]
138
+ val c = elements[cIndex]
139
+ elements[aIndex] = c
140
+ elements[bIndex] = a
141
+ elements[cIndex] = b
131
142
}
132
143
133
144
public fun swap (first : Int , second : Int ) {
134
145
val elements = elements
135
- val firstValue = elements[top - first]
136
- val secondValue = elements[top - second]
137
- elements[top - first] = secondValue
138
- elements[top - second] = firstValue
146
+ val depth = depth
147
+ val firstIndex = depth - 1 - first
148
+ val secondIndex = depth - 1 - second
149
+ val firstValue = elements[firstIndex]
150
+ val secondValue = elements[secondIndex]
151
+ elements[firstIndex] = secondValue
152
+ elements[secondIndex] = firstValue
139
153
}
140
154
141
155
/* *
@@ -144,16 +158,19 @@ public class Stack {
144
158
*/
145
159
public fun blockSwap (i : Int , j : Int ) {
146
160
val elements = elements
147
- val lastElements = elements.copyOfRange(top - j + 1 , top + 1 )
148
- elements.copyInto(elements, top - i + 1 , top - j - i + 1 , top - j + 1 )
149
- lastElements.copyInto(elements, top - i - j + 1 )
161
+ val currentDepth = depth
162
+ val lastElements = elements.copyOfRange(currentDepth - j, currentDepth)
163
+ elements.copyInto(elements, currentDepth - i, currentDepth - j - i, currentDepth - j)
164
+ lastElements.copyInto(elements, currentDepth - i - j)
150
165
}
151
166
152
167
public fun blockDrop (i : Int , j : Int ) {
153
168
val elements = elements
154
- elements.copyInto(elements, top - j - i + 1 , top - j + 1 , top + 1 )
155
- elements.fill(null , top - i + 1 , top + 1 )
156
- top = top - i
169
+ val currentDepth = depth
170
+ val newDepth = currentDepth - i
171
+ elements.copyInto(elements, newDepth - j, currentDepth - j, currentDepth)
172
+ elements.fill(null , newDepth, currentDepth)
173
+ depth = newDepth
157
174
}
158
175
159
176
public fun copy (srcSlot : Int , dstSlot : Int ) {
@@ -166,27 +183,29 @@ public class Stack {
166
183
167
184
public fun popBoolean (): Boolean = popInt().sign != 0
168
185
186
+ public fun popSlice (): CellSlice = pop() as CellSlice
187
+
169
188
override fun toString (): String = buildString {
170
189
val elements = elements
171
190
append(" [ " )
172
- for (i in 0 .. top ) {
191
+ for (i in 0 until depth ) {
173
192
append(elements[i])
174
193
append(" " )
175
194
}
176
- append(" ]" )
195
+ append(" ] | ${elements.copyOf( 16 ).contentToString()} " )
177
196
}
178
197
179
198
override fun equals (other : Any? ): Boolean {
180
199
if (this == = other) return true
181
200
if (other == null || this ::class != other::class ) return false
182
201
other as Stack
183
- if (top != other.top ) return false
202
+ if (depth != other.depth ) return false
184
203
if (! elements.contentEquals(other.elements)) return false
185
204
return true
186
205
}
187
206
188
207
override fun hashCode (): Int {
189
- var result = top
208
+ var result = depth
190
209
result = 31 * result + elements.contentHashCode()
191
210
return result
192
211
}
0 commit comments