@btc-vision/btc-runtime 1.2.3 → 1.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/runtime/buffer/BytesReader.ts +47 -4
- package/runtime/buffer/BytesWriter.ts +31 -3
- package/runtime/index.ts +1 -0
- package/runtime/math/i256.ts +606 -0
- package/runtime/types/Address.ts +1 -1
package/package.json
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { Address, ADDRESS_BYTE_LENGTH } from '../types/Address';
|
|
2
2
|
import { Selector } from '../math/abi';
|
|
3
|
-
import { u256 } from 'as-bignum/assembly';
|
|
3
|
+
import { i128, u128, u256 } from 'as-bignum/assembly';
|
|
4
4
|
import { Revert } from '../types/Revert';
|
|
5
5
|
import { Map } from '../generic/Map';
|
|
6
6
|
import { TransactionInput, TransactionOutput } from '../env/classes/UTXO';
|
|
7
7
|
import { StaticArray } from 'staticarray';
|
|
8
|
+
import { i256 } from '../math/i256';
|
|
8
9
|
|
|
9
10
|
@final
|
|
10
11
|
export class BytesReader {
|
|
@@ -49,12 +50,46 @@ export class BytesReader {
|
|
|
49
50
|
}
|
|
50
51
|
|
|
51
52
|
public readU256(): u256 {
|
|
53
|
+
this.verifyEnd(this.currentOffset + 32);
|
|
54
|
+
|
|
55
|
+
const next32Bytes: u8[] = this.readBytesBE(32);
|
|
56
|
+
|
|
57
|
+
return u256.fromBytesBE(next32Bytes);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
@inline
|
|
61
|
+
public readBytesBE(count: i32): u8[] {
|
|
52
62
|
const next32Bytes: u8[] = [];
|
|
53
|
-
for (let i = 0; i <
|
|
63
|
+
for (let i = 0; i < count; i++) {
|
|
54
64
|
next32Bytes[i] = this.readU8();
|
|
55
65
|
}
|
|
56
66
|
|
|
57
|
-
return
|
|
67
|
+
return next32Bytes;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
public readI64(): i64 {
|
|
71
|
+
this.verifyEnd(this.currentOffset + 8);
|
|
72
|
+
|
|
73
|
+
const value = this.buffer.getInt64(this.currentOffset, true);
|
|
74
|
+
this.currentOffset += 8;
|
|
75
|
+
|
|
76
|
+
return value;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
public readU128(): u128 {
|
|
80
|
+
this.verifyEnd(this.currentOffset + 16);
|
|
81
|
+
|
|
82
|
+
const next16Bytes: u8[] = this.readBytesBE(16);
|
|
83
|
+
|
|
84
|
+
return u128.fromBytesBE(next16Bytes);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
public readI128(): i128 {
|
|
88
|
+
this.verifyEnd(this.currentOffset + 16);
|
|
89
|
+
|
|
90
|
+
const next16Bytes: u8[] = this.readBytesBE(16);
|
|
91
|
+
|
|
92
|
+
return i128.fromBytesBE(next16Bytes);
|
|
58
93
|
}
|
|
59
94
|
|
|
60
95
|
public readBytes(length: u32, zeroStop: boolean = false): Uint8Array {
|
|
@@ -138,6 +173,14 @@ export class BytesReader {
|
|
|
138
173
|
return result;
|
|
139
174
|
}
|
|
140
175
|
|
|
176
|
+
public readI256(): i256 {
|
|
177
|
+
this.verifyEnd(this.currentOffset + 32);
|
|
178
|
+
|
|
179
|
+
const next32Bytes: u8[] = this.readBytesBE(32);
|
|
180
|
+
|
|
181
|
+
return i256.fromBytesBE(next32Bytes);
|
|
182
|
+
}
|
|
183
|
+
|
|
141
184
|
public readTuple(): u256[] {
|
|
142
185
|
const length = this.readU32();
|
|
143
186
|
const result: u256[] = new Array<u256>(length);
|
|
@@ -187,7 +230,7 @@ export class BytesReader {
|
|
|
187
230
|
}
|
|
188
231
|
|
|
189
232
|
public readAddress(): Address {
|
|
190
|
-
return this.readString(ADDRESS_BYTE_LENGTH);
|
|
233
|
+
return this.readString(<u16>ADDRESS_BYTE_LENGTH);
|
|
191
234
|
}
|
|
192
235
|
|
|
193
236
|
public getOffset(): i32 {
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { u256 } from 'as-bignum/assembly';
|
|
1
|
+
import { i128, u128, u256 } from 'as-bignum/assembly';
|
|
2
2
|
import { Address, ADDRESS_BYTE_LENGTH } from '../types/Address';
|
|
3
3
|
import { Selector } from '../math/abi';
|
|
4
4
|
import { BytesReader } from './BytesReader';
|
|
5
5
|
import { Revert } from '../types/Revert';
|
|
6
6
|
import { Map } from '../generic/Map';
|
|
7
7
|
import { ArrayBuffer } from 'arraybuffer';
|
|
8
|
+
import { i256 } from '../math/i256';
|
|
8
9
|
|
|
9
10
|
@final
|
|
10
11
|
export class BytesWriter {
|
|
@@ -63,6 +64,15 @@ export class BytesWriter {
|
|
|
63
64
|
this.writeU8(value ? 1 : 0);
|
|
64
65
|
}
|
|
65
66
|
|
|
67
|
+
public writeI256(value: i256): void {
|
|
68
|
+
this.allocSafe(32);
|
|
69
|
+
|
|
70
|
+
const bytes = value.toUint8Array(true);
|
|
71
|
+
for (let i: i32 = 0; i < 32; i++) {
|
|
72
|
+
this.writeU8(bytes[i] || 0);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
66
76
|
public writeU256(value: u256): void {
|
|
67
77
|
this.allocSafe(32);
|
|
68
78
|
|
|
@@ -72,6 +82,24 @@ export class BytesWriter {
|
|
|
72
82
|
}
|
|
73
83
|
}
|
|
74
84
|
|
|
85
|
+
public writeI128(value: i128): void {
|
|
86
|
+
this.allocSafe(32);
|
|
87
|
+
|
|
88
|
+
const bytes = value.toUint8Array(true);
|
|
89
|
+
for (let i: i32 = 0; i < 32; i++) {
|
|
90
|
+
this.writeU8(bytes[i] || 0);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
public writeU128(value: u128): void {
|
|
95
|
+
this.allocSafe(32);
|
|
96
|
+
|
|
97
|
+
const bytes = value.toUint8Array(true);
|
|
98
|
+
for (let i: i32 = 0; i < 32; i++) {
|
|
99
|
+
this.writeU8(bytes[i] || 0);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
75
103
|
public writeTuple(value: u256[]): void {
|
|
76
104
|
this.allocSafe(4 + value.length * 32);
|
|
77
105
|
this.writeU32(u32(value.length));
|
|
@@ -242,7 +270,7 @@ export class BytesWriter {
|
|
|
242
270
|
}
|
|
243
271
|
|
|
244
272
|
private fromAddress(value: Address): Uint8Array {
|
|
245
|
-
if (value.length >
|
|
273
|
+
if (value.length > ADDRESS_BYTE_LENGTH) {
|
|
246
274
|
throw new Revert(`Address is too long ${value.length} > ${ADDRESS_BYTE_LENGTH} bytes`);
|
|
247
275
|
}
|
|
248
276
|
|
|
@@ -252,7 +280,7 @@ export class BytesWriter {
|
|
|
252
280
|
bytes[i] = value.charCodeAt(i);
|
|
253
281
|
}
|
|
254
282
|
|
|
255
|
-
if (value.length <
|
|
283
|
+
if (value.length < ADDRESS_BYTE_LENGTH) {
|
|
256
284
|
bytes[value.length] = 0;
|
|
257
285
|
}
|
|
258
286
|
|
package/runtime/index.ts
CHANGED
|
@@ -0,0 +1,606 @@
|
|
|
1
|
+
import { i128, u128, u256 } from 'as-bignum/assembly';
|
|
2
|
+
|
|
3
|
+
export class i256 {
|
|
4
|
+
|
|
5
|
+
@inline static get Zero(): i256 { return new i256(); }
|
|
6
|
+
@inline static get One(): i256 { return new i256(1); }
|
|
7
|
+
@inline static get Min(): i256 { return new i256(0, 0, 0, 0x8000000000000000); }
|
|
8
|
+
@inline static get Max(): i256 { return new i256(-1, -1, -1, 0x7FFFFFFFFFFFFFFF); }
|
|
9
|
+
|
|
10
|
+
@inline
|
|
11
|
+
static fromI256(value: i256): i256 {
|
|
12
|
+
return new i256(value.lo1, value.lo2, value.hi1, value.hi2);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
@inline
|
|
16
|
+
static fromU256(value: u256): i256 {
|
|
17
|
+
return new i256(<i64>value.lo1, <i64>value.lo2, <i64>value.hi1, <i64>value.hi2);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
@inline
|
|
21
|
+
static fromI128(value: i128): i256 {
|
|
22
|
+
var signExt = value.hi >> 63;
|
|
23
|
+
return new i256(<i64>value.lo, value.hi, signExt, signExt);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
@inline
|
|
27
|
+
static fromU128(value: u128): i256 {
|
|
28
|
+
return new i256(<i64>value.lo, <i64>value.hi, 0, 0);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
@inline
|
|
32
|
+
static fromI64(value: i64): i256 {
|
|
33
|
+
var signExt = value >> 63;
|
|
34
|
+
return new i256(value, signExt, signExt, signExt);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
@inline
|
|
38
|
+
static fromU64(value: u64): i256 {
|
|
39
|
+
return new i256(<i64>value, 0, 0, 0);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
@inline
|
|
43
|
+
static fromI32(value: i32): i256 {
|
|
44
|
+
var signExt = value >> 31;
|
|
45
|
+
var signExt64 = <i64>signExt;
|
|
46
|
+
return new i256(<i64>value, signExt64, signExt64, signExt64);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
@inline
|
|
50
|
+
static fromU32(value: u32): i256 {
|
|
51
|
+
return new i256(<i64>value, 0, 0, 0);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
@inline
|
|
55
|
+
static fromF64(value: f64): i256 {
|
|
56
|
+
var signExt = reinterpret<i64>(value) >> 63;
|
|
57
|
+
return new i256(<i64>value, signExt, signExt, signExt);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
@inline
|
|
61
|
+
static fromF32(value: f32): i256 {
|
|
62
|
+
var signExt = reinterpret<i32>(value) >> 31;
|
|
63
|
+
var signExt64 = <i64>signExt;
|
|
64
|
+
return new i256(<i64>value, signExt64, signExt64, signExt64);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
@inline
|
|
68
|
+
static fromBits(
|
|
69
|
+
l0: i32, l1: i32, l2: i32, l3: i32,
|
|
70
|
+
h0: i32, h1: i32, h2: i32, h3: i32,
|
|
71
|
+
): i256 {
|
|
72
|
+
return new i256(
|
|
73
|
+
<i64>l0 | ((<i64>l1) << 32),
|
|
74
|
+
<i64>l2 | ((<i64>l3) << 32),
|
|
75
|
+
<i64>h0 | ((<i64>h1) << 32),
|
|
76
|
+
<i64>h2 | ((<i64>h3) << 32),
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
@inline
|
|
81
|
+
static fromBytes<T>(array: T, bigEndian: bool = false): i256 {
|
|
82
|
+
if (array instanceof u8[]) {
|
|
83
|
+
return bigEndian
|
|
84
|
+
? i256.fromBytesBE(<u8[]>array)
|
|
85
|
+
: i256.fromBytesLE(<u8[]>array);
|
|
86
|
+
} else if (array instanceof Uint8Array) {
|
|
87
|
+
return bigEndian
|
|
88
|
+
? i256.fromUint8ArrayBE(<Uint8Array>array)
|
|
89
|
+
: i256.fromUint8ArrayLE(<Uint8Array>array);
|
|
90
|
+
} else {
|
|
91
|
+
throw new TypeError("Unsupported generic type");
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
@inline
|
|
96
|
+
static fromBytesLE(array: u8[]): i256 {
|
|
97
|
+
assert(array.length && (array.length & 31) == 0);
|
|
98
|
+
var buffer = array.dataStart;
|
|
99
|
+
return new i256(
|
|
100
|
+
load<i64>(buffer, 0 * sizeof<i64>()),
|
|
101
|
+
load<i64>(buffer, 1 * sizeof<i64>()),
|
|
102
|
+
load<i64>(buffer, 2 * sizeof<i64>()),
|
|
103
|
+
load<i64>(buffer, 3 * sizeof<i64>()),
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
@inline
|
|
108
|
+
static fromBytesBE(array: u8[]): i256 {
|
|
109
|
+
assert(array.length && (array.length & 31) == 0);
|
|
110
|
+
var buffer = array.dataStart;
|
|
111
|
+
return new i256(
|
|
112
|
+
bswap<i64>(load<i64>(buffer, 3 * sizeof<i64>())),
|
|
113
|
+
bswap<i64>(load<i64>(buffer, 2 * sizeof<i64>())),
|
|
114
|
+
bswap<i64>(load<i64>(buffer, 1 * sizeof<i64>())),
|
|
115
|
+
bswap<i64>(load<i64>(buffer, 0 * sizeof<i64>())),
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
@inline
|
|
120
|
+
static fromUint8ArrayLE(array: Uint8Array): i256 {
|
|
121
|
+
assert(array.length && (array.length & 31) == 0);
|
|
122
|
+
var buffer = array.dataStart;
|
|
123
|
+
return new i256(
|
|
124
|
+
load<i64>(buffer, 0 * sizeof<i64>()),
|
|
125
|
+
load<i64>(buffer, 1 * sizeof<i64>()),
|
|
126
|
+
load<i64>(buffer, 2 * sizeof<i64>()),
|
|
127
|
+
load<i64>(buffer, 3 * sizeof<i64>()),
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
@inline
|
|
132
|
+
static fromUint8ArrayBE(array: Uint8Array): i256 {
|
|
133
|
+
assert(array.length && (array.length & 31) == 0);
|
|
134
|
+
var buffer = array.dataStart;
|
|
135
|
+
return new i256(
|
|
136
|
+
bswap<i64>(load<i64>(buffer, 3 * sizeof<i64>())),
|
|
137
|
+
bswap<i64>(load<i64>(buffer, 2 * sizeof<i64>())),
|
|
138
|
+
bswap<i64>(load<i64>(buffer, 1 * sizeof<i64>())),
|
|
139
|
+
bswap<i64>(load<i64>(buffer, 0 * sizeof<i64>())),
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
@inline
|
|
144
|
+
static from<T>(value: T): i256 {
|
|
145
|
+
if (value instanceof bool) return i256.fromU64(<u64>value);
|
|
146
|
+
else if (value instanceof i8) return i256.fromI64(<i64>value);
|
|
147
|
+
else if (value instanceof u8) return i256.fromU64(<u64>value);
|
|
148
|
+
else if (value instanceof i16) return i256.fromI64(<i64>value);
|
|
149
|
+
else if (value instanceof u16) return i256.fromU64(<u64>value);
|
|
150
|
+
else if (value instanceof i32) return i256.fromI32(<i32>value);
|
|
151
|
+
else if (value instanceof u32) return i256.fromU32(<u32>value);
|
|
152
|
+
else if (value instanceof i64) return i256.fromI64(<i64>value);
|
|
153
|
+
else if (value instanceof u64) return i256.fromU64(<u64>value);
|
|
154
|
+
else if (value instanceof f32) return i256.fromF64(<f64>value);
|
|
155
|
+
else if (value instanceof f64) return i256.fromF64(<f64>value);
|
|
156
|
+
else if (value instanceof i128) return i256.fromI128(<i128>value);
|
|
157
|
+
else if (value instanceof u128) return i256.fromU128(<u128>value);
|
|
158
|
+
else if (value instanceof i256) return i256.fromI256(<i256>value);
|
|
159
|
+
else if (value instanceof u256) return i256.fromU256(<u256>value);
|
|
160
|
+
else if (value instanceof u8[]) return i256.fromBytes(<u8[]>value);
|
|
161
|
+
else if (value instanceof Uint8Array) return i256.fromBytes(<Uint8Array>value);
|
|
162
|
+
else throw new TypeError("Unsupported generic type");
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
constructor(
|
|
166
|
+
public lo1: i64 = 0,
|
|
167
|
+
public lo2: i64 = 0,
|
|
168
|
+
public hi1: i64 = 0,
|
|
169
|
+
public hi2: i64 = 0,
|
|
170
|
+
) {}
|
|
171
|
+
|
|
172
|
+
@inline
|
|
173
|
+
set(value: i256): this {
|
|
174
|
+
this.lo1 = value.lo1;
|
|
175
|
+
this.lo2 = value.lo2;
|
|
176
|
+
this.hi1 = value.hi1;
|
|
177
|
+
this.hi2 = value.hi2;
|
|
178
|
+
return this;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
@inline
|
|
182
|
+
isNeg(): bool {
|
|
183
|
+
return <bool>(this.hi2 >>> 63);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
@inline
|
|
187
|
+
isZero(): bool {
|
|
188
|
+
return !(this.lo1 | this.lo2 | this.hi1 | this.hi2);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
@inline @operator.prefix('!')
|
|
192
|
+
static isEmpty(value: i256): bool {
|
|
193
|
+
return value.isZero();
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
@operator.prefix('~')
|
|
197
|
+
not(): i256 {
|
|
198
|
+
return new i256(~this.lo1, ~this.lo2, ~this.hi1, ~this.hi2);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
@operator.prefix('+')
|
|
202
|
+
pos(): i256 {
|
|
203
|
+
return this;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
@operator.prefix('-')
|
|
207
|
+
neg(): i256 {
|
|
208
|
+
var lo1 = ~this.lo1;
|
|
209
|
+
var lo2 = ~this.lo2;
|
|
210
|
+
var hi1 = ~this.hi1;
|
|
211
|
+
var hi2 = ~this.hi2;
|
|
212
|
+
|
|
213
|
+
var lo1p = lo1 + 1;
|
|
214
|
+
var carry = lo1p == 0 ? 1 : 0;
|
|
215
|
+
|
|
216
|
+
var lo2p = lo2 + carry;
|
|
217
|
+
carry = (lo2p == 0 && carry == 1) ? 1 : 0;
|
|
218
|
+
|
|
219
|
+
var hi1p = hi1 + carry;
|
|
220
|
+
carry = (hi1p == 0 && carry == 1) ? 1 : 0;
|
|
221
|
+
|
|
222
|
+
var hi2p = hi2 + carry;
|
|
223
|
+
|
|
224
|
+
return new i256(lo1p, lo2p, hi1p, hi2p);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
@operator('+')
|
|
228
|
+
static add(a: i256, b: i256): i256 {
|
|
229
|
+
var lo1 = a.lo1 + b.lo1;
|
|
230
|
+
var carry = lo1 < a.lo1 ? 1 : 0;
|
|
231
|
+
|
|
232
|
+
var lo2 = a.lo2 + b.lo2 + carry;
|
|
233
|
+
carry = (lo2 < a.lo2 || (carry == 1 && lo2 == a.lo2)) ? 1 : 0;
|
|
234
|
+
|
|
235
|
+
var hi1 = a.hi1 + b.hi1 + carry;
|
|
236
|
+
carry = (hi1 < a.hi1 || (carry == 1 && hi1 == a.hi1)) ? 1 : 0;
|
|
237
|
+
|
|
238
|
+
var hi2 = a.hi2 + b.hi2 + carry;
|
|
239
|
+
|
|
240
|
+
return new i256(lo1, lo2, hi1, hi2);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
@operator('-')
|
|
244
|
+
static sub(a: i256, b: i256): i256 {
|
|
245
|
+
var lo1 = a.lo1 - b.lo1;
|
|
246
|
+
var borrow = a.lo1 < b.lo1 ? 1 : 0;
|
|
247
|
+
|
|
248
|
+
var lo2 = a.lo2 - b.lo2 - borrow;
|
|
249
|
+
borrow = a.lo2 < b.lo2 + borrow ? 1 : 0;
|
|
250
|
+
|
|
251
|
+
var hi1 = a.hi1 - b.hi1 - borrow;
|
|
252
|
+
borrow = hi1 < b.hi1 + borrow ? 1 : 0;
|
|
253
|
+
|
|
254
|
+
var hi2 = a.hi2 - b.hi2 - borrow;
|
|
255
|
+
|
|
256
|
+
return new i256(lo1, lo2, hi1, hi2);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
@inline @operator('|')
|
|
260
|
+
static or(a: i256, b: i256): i256 {
|
|
261
|
+
return new i256(a.lo1 | b.lo1, a.lo2 | b.lo2, a.hi1 | b.hi1, a.hi2 | b.hi2);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
@inline @operator('^')
|
|
265
|
+
static xor(a: i256, b: i256): i256 {
|
|
266
|
+
return new i256(a.lo1 ^ b.lo1, a.lo2 ^ b.lo2, a.hi1 ^ b.hi1, a.hi2 ^ b.hi2);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
@inline @operator('&')
|
|
270
|
+
static and(a: i256, b: i256): i256 {
|
|
271
|
+
return new i256(a.lo1 & b.lo1, a.lo2 & b.lo2, a.hi1 & b.hi1, a.hi2 & b.hi2);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
@operator('<')
|
|
275
|
+
static lt(a: i256, b: i256): bool {
|
|
276
|
+
if (a.hi2 == b.hi2) {
|
|
277
|
+
if (a.hi1 == b.hi1) {
|
|
278
|
+
if (a.lo2 == b.lo2) {
|
|
279
|
+
return a.lo1 < b.lo1;
|
|
280
|
+
} else {
|
|
281
|
+
return a.lo2 < b.lo2;
|
|
282
|
+
}
|
|
283
|
+
} else {
|
|
284
|
+
return a.hi1 < b.hi1;
|
|
285
|
+
}
|
|
286
|
+
} else {
|
|
287
|
+
return a.hi2 < b.hi2;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
@inline @operator('>')
|
|
292
|
+
static gt(a: i256, b: i256): bool {
|
|
293
|
+
return b < a;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
@inline @operator('==')
|
|
297
|
+
static eq(a: i256, b: i256): bool {
|
|
298
|
+
return a.lo1 == b.lo1 && a.lo2 == b.lo2 && a.hi1 == b.hi1 && a.hi2 == b.hi2;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
@inline @operator('!=')
|
|
302
|
+
static ne(a: i256, b: i256): bool {
|
|
303
|
+
return !i256.eq(a, b);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
@inline @operator('<=')
|
|
307
|
+
static le(a: i256, b: i256): bool {
|
|
308
|
+
return !i256.gt(a, b);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
@inline @operator('>=')
|
|
312
|
+
static ge(a: i256, b: i256): bool {
|
|
313
|
+
return !i256.lt(a, b);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
@operator('<<')
|
|
317
|
+
static shl(value: i256, shift: i32): i256 {
|
|
318
|
+
shift &= 255;
|
|
319
|
+
if (shift == 0) return value;
|
|
320
|
+
if (shift >= 256) return new i256();
|
|
321
|
+
var lo1 = value.lo1;
|
|
322
|
+
var lo2 = value.lo2;
|
|
323
|
+
var hi1 = value.hi1;
|
|
324
|
+
var hi2 = value.hi2;
|
|
325
|
+
if (shift >= 192) {
|
|
326
|
+
let s = shift - 192;
|
|
327
|
+
return new i256(0, 0, 0, lo1 << s);
|
|
328
|
+
} else if (shift >= 128) {
|
|
329
|
+
let s = shift - 128;
|
|
330
|
+
return new i256(0, 0, lo1 << s, (lo2 << s) | (lo1 >>> (64 - s)));
|
|
331
|
+
} else if (shift >= 64) {
|
|
332
|
+
let s = shift - 64;
|
|
333
|
+
return new i256(0, (lo1 << s), (lo2 << s) | (lo1 >>> (64 - s)), (hi1 << s) | (lo2 >>> (64 - s)));
|
|
334
|
+
} else {
|
|
335
|
+
let s = shift;
|
|
336
|
+
return new i256(
|
|
337
|
+
lo1 << s,
|
|
338
|
+
(lo2 << s) | (lo1 >>> (64 - s)),
|
|
339
|
+
(hi1 << s) | (lo2 >>> (64 - s)),
|
|
340
|
+
(hi2 << s) | (hi1 >>> (64 - s)),
|
|
341
|
+
);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
@operator('>>')
|
|
346
|
+
static shr(value: i256, shift: i32): i256 {
|
|
347
|
+
shift &= 255;
|
|
348
|
+
if (shift == 0) return value;
|
|
349
|
+
if (shift >= 256) {
|
|
350
|
+
let sign = value.isNeg() ? -1 : 0;
|
|
351
|
+
return new i256(sign, sign, sign, sign);
|
|
352
|
+
}
|
|
353
|
+
var lo1 = value.lo1;
|
|
354
|
+
var lo2 = value.lo2;
|
|
355
|
+
var hi1 = value.hi1;
|
|
356
|
+
var hi2 = value.hi2;
|
|
357
|
+
if (shift >= 192) {
|
|
358
|
+
let s = shift - 192;
|
|
359
|
+
let sign = value.isNeg() ? -1 : 0;
|
|
360
|
+
return new i256((hi2 >> s) | (sign << (64 - s)), sign, sign, sign);
|
|
361
|
+
} else if (shift >= 128) {
|
|
362
|
+
let s = shift - 128;
|
|
363
|
+
return new i256((hi1 >> s) | (hi2 << (64 - s)), (hi2 >> s) | (hi2 >> 63) << (64 - s), hi2 >> 63, hi2 >> 63);
|
|
364
|
+
} else if (shift >= 64) {
|
|
365
|
+
let s = shift - 64;
|
|
366
|
+
return new i256(
|
|
367
|
+
(lo2 >> s) | (hi1 << (64 - s)),
|
|
368
|
+
(hi1 >> s) | (hi2 << (64 - s)),
|
|
369
|
+
(hi2 >> s) | (hi2 >> 63) << (64 - s),
|
|
370
|
+
hi2 >> 63,
|
|
371
|
+
);
|
|
372
|
+
} else {
|
|
373
|
+
let s = shift;
|
|
374
|
+
return new i256(
|
|
375
|
+
(lo1 >> s) | (lo2 << (64 - s)),
|
|
376
|
+
(lo2 >> s) | (hi1 << (64 - s)),
|
|
377
|
+
(hi1 >> s) | (hi2 << (64 - s)),
|
|
378
|
+
(hi2 >> s) | (hi2 >> 63) << (64 - s),
|
|
379
|
+
);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
@operator('>>>')
|
|
384
|
+
static shr_u(value: i256, shift: i32): i256 {
|
|
385
|
+
shift &= 255;
|
|
386
|
+
if (shift == 0) return value;
|
|
387
|
+
if (shift >= 256) return new i256();
|
|
388
|
+
var lo1 = value.lo1;
|
|
389
|
+
var lo2 = value.lo2;
|
|
390
|
+
var hi1 = value.hi1;
|
|
391
|
+
var hi2 = value.hi2;
|
|
392
|
+
if (shift >= 192) {
|
|
393
|
+
let s = shift - 192;
|
|
394
|
+
return new i256((hi2 >>> s), 0, 0, 0);
|
|
395
|
+
} else if (shift >= 128) {
|
|
396
|
+
let s = shift - 128;
|
|
397
|
+
return new i256((hi1 >>> s) | (hi2 << (64 - s)), (hi2 >>> s), 0, 0);
|
|
398
|
+
} else if (shift >= 64) {
|
|
399
|
+
let s = shift - 64;
|
|
400
|
+
return new i256(
|
|
401
|
+
(lo2 >>> s) | (hi1 << (64 - s)),
|
|
402
|
+
(hi1 >>> s) | (hi2 << (64 - s)),
|
|
403
|
+
(hi2 >>> s),
|
|
404
|
+
0,
|
|
405
|
+
);
|
|
406
|
+
} else {
|
|
407
|
+
let s = shift;
|
|
408
|
+
return new i256(
|
|
409
|
+
(lo1 >>> s) | (lo2 << (64 - s)),
|
|
410
|
+
(lo2 >>> s) | (hi1 << (64 - s)),
|
|
411
|
+
(hi1 >>> s) | (hi2 << (64 - s)),
|
|
412
|
+
hi2 >>> s,
|
|
413
|
+
);
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
clone(): i256 {
|
|
418
|
+
return new i256(this.lo1, this.lo2, this.hi1, this.hi2);
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
// Helper methods to write the internal representation to a buffer
|
|
422
|
+
@inline
|
|
423
|
+
private toArrayBufferLE(buffer: usize): void {
|
|
424
|
+
store<i64>(buffer, this.lo1, 0 * sizeof<i64>());
|
|
425
|
+
store<i64>(buffer, this.lo2, 1 * sizeof<i64>());
|
|
426
|
+
store<i64>(buffer, this.hi1, 2 * sizeof<i64>());
|
|
427
|
+
store<i64>(buffer, this.hi2, 3 * sizeof<i64>());
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
@inline
|
|
431
|
+
private toArrayBufferBE(buffer: usize): void {
|
|
432
|
+
store<i64>(buffer, bswap<i64>(this.hi2), 0 * sizeof<i64>());
|
|
433
|
+
store<i64>(buffer, bswap<i64>(this.hi1), 1 * sizeof<i64>());
|
|
434
|
+
store<i64>(buffer, bswap<i64>(this.lo2), 2 * sizeof<i64>());
|
|
435
|
+
store<i64>(buffer, bswap<i64>(this.lo1), 3 * sizeof<i64>());
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
@inline
|
|
439
|
+
private toArrayBuffer(buffer: usize, bigEndian: bool = false): void {
|
|
440
|
+
if (bigEndian) {
|
|
441
|
+
this.toArrayBufferBE(buffer);
|
|
442
|
+
} else {
|
|
443
|
+
this.toArrayBufferLE(buffer);
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
/**
|
|
448
|
+
* Convert to Uint8Array
|
|
449
|
+
* @param bigEndian Little or Big Endian? Default: false
|
|
450
|
+
* @returns Uint8Array
|
|
451
|
+
*/
|
|
452
|
+
@inline
|
|
453
|
+
toUint8Array(bigEndian: bool = false): Uint8Array {
|
|
454
|
+
var result = new Uint8Array(32);
|
|
455
|
+
this.toArrayBuffer(result.dataStart, bigEndian);
|
|
456
|
+
return result;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
/**
|
|
460
|
+
* Convert to byte array
|
|
461
|
+
* @param bigEndian Little or Big Endian? Default: false
|
|
462
|
+
* @returns Array of bytes
|
|
463
|
+
*/
|
|
464
|
+
@inline
|
|
465
|
+
toBytes(bigEndian: bool = false): u8[] {
|
|
466
|
+
var result = new Array<u8>(32);
|
|
467
|
+
this.toArrayBuffer(result.dataStart, bigEndian);
|
|
468
|
+
return result;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
/**
|
|
472
|
+
* Convert to StaticArray of bytes
|
|
473
|
+
* @param bigEndian Little or Big Endian? Default: false
|
|
474
|
+
* @returns StaticArray<u8>
|
|
475
|
+
*/
|
|
476
|
+
@inline
|
|
477
|
+
toStaticBytes(bigEndian: bool = false): StaticArray<u8> {
|
|
478
|
+
var result = new StaticArray<u8>(32);
|
|
479
|
+
this.toArrayBuffer(changetype<usize>(result), bigEndian);
|
|
480
|
+
return result;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
// Other conversion methods can be added as needed, following similar patterns.
|
|
484
|
+
|
|
485
|
+
/**
|
|
486
|
+
* Generic type conversion
|
|
487
|
+
*/
|
|
488
|
+
@inline
|
|
489
|
+
as<T>(): T {
|
|
490
|
+
var dummy!: T;
|
|
491
|
+
if (dummy instanceof bool) return <T>this.toBool();
|
|
492
|
+
else if (dummy instanceof i8) return <T>this.toI64();
|
|
493
|
+
else if (dummy instanceof u8) return <T>this.toU64();
|
|
494
|
+
else if (dummy instanceof i16) return <T>this.toI64();
|
|
495
|
+
else if (dummy instanceof u16) return <T>this.toU64();
|
|
496
|
+
else if (dummy instanceof i32) return <T>this.toI64();
|
|
497
|
+
else if (dummy instanceof u32) return <T>this.toU64();
|
|
498
|
+
else if (dummy instanceof i64) return <T>this.toI64();
|
|
499
|
+
else if (dummy instanceof u64) return <T>this.toU64();
|
|
500
|
+
else if (dummy instanceof i128) return <T>this.toI128();
|
|
501
|
+
else if (dummy instanceof u128) return <T>this.toU128();
|
|
502
|
+
else if (dummy instanceof i256) return <T>this;
|
|
503
|
+
else if (dummy instanceof u256) return <T>this.toU256();
|
|
504
|
+
else if (dummy instanceof u8[]) return <T>this.toBytes();
|
|
505
|
+
else if (dummy instanceof Uint8Array) return <T>this.toUint8Array();
|
|
506
|
+
else if (dummy instanceof StaticArray<u8>) return <T>this.toStaticBytes();
|
|
507
|
+
else if (dummy instanceof String) return <T>this.toString();
|
|
508
|
+
else throw new TypeError('Unsupported generic type');
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
@inline
|
|
512
|
+
toBool(): bool {
|
|
513
|
+
return this.lo1 != 0 || this.lo2 != 0 || this.hi1 != 0 || this.hi2 != 0;
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
@inline
|
|
517
|
+
toI64(): i64 {
|
|
518
|
+
return this.lo1;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
@inline
|
|
522
|
+
toU64(): u64 {
|
|
523
|
+
return <u64>this.lo1;
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
@inline
|
|
527
|
+
toI32(): i32 {
|
|
528
|
+
return <i32>this.lo1;
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
@inline
|
|
532
|
+
toU32(): u32 {
|
|
533
|
+
return <u32>this.lo1;
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
@inline
|
|
537
|
+
toI128(): i128 {
|
|
538
|
+
return new i128(<u64>this.lo1, this.lo2);
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
@inline
|
|
542
|
+
toU128(): u128 {
|
|
543
|
+
return new u128(<u64>this.lo1, <u64>this.lo2);
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
@inline
|
|
547
|
+
toU256(): u256 {
|
|
548
|
+
return new u256(<u64>this.lo1, <u64>this.lo2, <u64>this.hi1, <u64>this.hi2);
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
@inline
|
|
552
|
+
public toString(radix: i32 = 10): string {
|
|
553
|
+
assert(radix == 10 || radix == 16, 'radix argument must be 10 or 16');
|
|
554
|
+
if (this.isZero()) return '0';
|
|
555
|
+
|
|
556
|
+
const isNegative = this.isNeg();
|
|
557
|
+
const value = isNegative ? this.neg() : this.clone();
|
|
558
|
+
let result = '';
|
|
559
|
+
|
|
560
|
+
if (radix == 16) {
|
|
561
|
+
const HEX_CHARS = '0123456789abcdef';
|
|
562
|
+
let shift: i32 = 252 - (i256.clz(value) & ~3);
|
|
563
|
+
let started = false;
|
|
564
|
+
while (shift >= 0) {
|
|
565
|
+
let digit = (<u8>((value.shr_u(shift)).lo1 & 0xF));
|
|
566
|
+
if (digit != 0 || started) {
|
|
567
|
+
// @ts-ignore
|
|
568
|
+
result += HEX_CHARS.charAt(digit);
|
|
569
|
+
started = true;
|
|
570
|
+
}
|
|
571
|
+
shift -= 4;
|
|
572
|
+
}
|
|
573
|
+
if (isNegative) {
|
|
574
|
+
result = '-' + result;
|
|
575
|
+
}
|
|
576
|
+
return result;
|
|
577
|
+
} else {
|
|
578
|
+
// Radix 10 conversion requires division, which needs to be implemented.
|
|
579
|
+
// Placeholder implementation (throws an error).
|
|
580
|
+
throw new Error('Radix 10 conversion is not implemented yet.');
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
shr_u(value: i32): i256 {
|
|
585
|
+
return i256.shr_u(this, value);
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
@inline
|
|
589
|
+
static clz(value: i256): i32 {
|
|
590
|
+
// For signed integers, leading zeros are counted from the sign bit.
|
|
591
|
+
// If the value is negative, we take its two's complement to get the magnitude.
|
|
592
|
+
if (value.isNeg()) {
|
|
593
|
+
value = value.neg();
|
|
594
|
+
}
|
|
595
|
+
if (value.hi2 != 0) {
|
|
596
|
+
return clz<u64>(value.hi2);
|
|
597
|
+
} else if (value.hi1 != 0) {
|
|
598
|
+
return clz<u64>(value.hi1) + 64;
|
|
599
|
+
} else if (value.lo2 != 0) {
|
|
600
|
+
return clz<u64>(value.lo2) + 128;
|
|
601
|
+
} else {
|
|
602
|
+
return clz<u64>(value.lo1) + 192;
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
}
|
package/runtime/types/Address.ts
CHANGED