toilscript 0.0.1 → 0.1.1

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.
Files changed (121) hide show
  1. package/LICENSE +201 -201
  2. package/NOTICE +94 -94
  3. package/README.md +101 -114
  4. package/bin/asc.js +0 -0
  5. package/bin/asinit.js +6 -6
  6. package/dist/asc.generated.d.ts +10027 -0
  7. package/dist/asc.js +24474 -0
  8. package/dist/asc.js.map +7 -0
  9. package/dist/importmap.json +9 -0
  10. package/dist/toilscript.generated.d.ts +11242 -0
  11. package/dist/toilscript.js +337 -0
  12. package/dist/toilscript.js.map +7 -0
  13. package/dist/web.js +22 -0
  14. package/lib/binaryen.d.ts +2 -2
  15. package/lib/binaryen.js +2 -2
  16. package/package.json +115 -114
  17. package/std/README.md +6 -6
  18. package/std/assembly/array.ts +550 -550
  19. package/std/assembly/arraybuffer.ts +77 -77
  20. package/std/assembly/atomics.ts +127 -127
  21. package/std/assembly/bindings/asyncify.ts +16 -16
  22. package/std/assembly/bindings/dom.ts +291 -291
  23. package/std/assembly/bindings/node.ts +6 -6
  24. package/std/assembly/bitflags.ts +53 -53
  25. package/std/assembly/builtins.ts +2650 -2650
  26. package/std/assembly/byteslice.ts +177 -177
  27. package/std/assembly/compat.ts +2 -2
  28. package/std/assembly/console.ts +42 -42
  29. package/std/assembly/crypto.ts +9 -9
  30. package/std/assembly/dataview.ts +181 -181
  31. package/std/assembly/date.ts +375 -375
  32. package/std/assembly/diagnostics.ts +11 -11
  33. package/std/assembly/encoding.ts +151 -151
  34. package/std/assembly/endian.ts +45 -45
  35. package/std/assembly/error.ts +44 -44
  36. package/std/assembly/fixedarray.ts +173 -173
  37. package/std/assembly/fixedmap.ts +326 -326
  38. package/std/assembly/fixedset.ts +275 -275
  39. package/std/assembly/function.ts +42 -42
  40. package/std/assembly/index.d.ts +2892 -2891
  41. package/std/assembly/iterator.ts +35 -35
  42. package/std/assembly/map.ts +269 -269
  43. package/std/assembly/math.ts +3289 -3289
  44. package/std/assembly/memory.ts +123 -123
  45. package/std/assembly/number.ts +388 -388
  46. package/std/assembly/object.ts +36 -36
  47. package/std/assembly/performance.ts +9 -9
  48. package/std/assembly/pointer.ts +80 -80
  49. package/std/assembly/polyfills.ts +27 -27
  50. package/std/assembly/process.ts +50 -50
  51. package/std/assembly/reference.ts +48 -48
  52. package/std/assembly/regexp.ts +12 -12
  53. package/std/assembly/rt/README.md +83 -83
  54. package/std/assembly/rt/common.ts +81 -81
  55. package/std/assembly/rt/index-incremental.ts +2 -2
  56. package/std/assembly/rt/index-memory.ts +1 -1
  57. package/std/assembly/rt/index-minimal.ts +2 -2
  58. package/std/assembly/rt/index-stub.ts +1 -1
  59. package/std/assembly/rt/index.d.ts +37 -37
  60. package/std/assembly/rt/itcms.ts +419 -419
  61. package/std/assembly/rt/memory-runtime.ts +94 -94
  62. package/std/assembly/rt/rtrace.ts +15 -15
  63. package/std/assembly/rt/stub.ts +133 -133
  64. package/std/assembly/rt/tcms.ts +254 -254
  65. package/std/assembly/rt/tlsf.ts +592 -592
  66. package/std/assembly/rt.ts +90 -90
  67. package/std/assembly/set.ts +225 -225
  68. package/std/assembly/shared/feature.ts +68 -68
  69. package/std/assembly/shared/runtime.ts +13 -13
  70. package/std/assembly/shared/target.ts +11 -11
  71. package/std/assembly/shared/tsconfig.json +11 -11
  72. package/std/assembly/shared/typeinfo.ts +72 -72
  73. package/std/assembly/staticarray.ts +423 -423
  74. package/std/assembly/string.ts +850 -850
  75. package/std/assembly/symbol.ts +114 -114
  76. package/std/assembly/table.ts +16 -16
  77. package/std/assembly/toilscript.ts +16 -0
  78. package/std/assembly/tsconfig.json +6 -6
  79. package/std/assembly/typedarray.ts +1954 -1954
  80. package/std/assembly/uri.ts +17 -17
  81. package/std/assembly/util/bytes.ts +107 -107
  82. package/std/assembly/util/casemap.ts +497 -497
  83. package/std/assembly/util/error.ts +58 -58
  84. package/std/assembly/util/hash.ts +117 -117
  85. package/std/assembly/util/math.ts +1922 -1922
  86. package/std/assembly/util/memory.ts +290 -290
  87. package/std/assembly/util/number.ts +873 -873
  88. package/std/assembly/util/sort.ts +313 -313
  89. package/std/assembly/util/string.ts +1202 -1202
  90. package/std/assembly/util/uri.ts +275 -275
  91. package/std/assembly/vector.ts +4 -4
  92. package/std/assembly.json +16 -16
  93. package/std/portable/index.d.ts +461 -461
  94. package/std/portable/index.js +416 -416
  95. package/std/portable.json +11 -11
  96. package/std/types/assembly/index.d.ts +1 -1
  97. package/std/types/assembly/package.json +2 -2
  98. package/std/types/portable/index.d.ts +1 -1
  99. package/std/types/portable/package.json +2 -2
  100. package/tsconfig-base.json +13 -13
  101. package/util/README.md +23 -23
  102. package/util/browser/fs.js +1 -1
  103. package/util/browser/module.js +5 -5
  104. package/util/browser/path.js +520 -520
  105. package/util/browser/process.js +59 -59
  106. package/util/browser/url.js +23 -23
  107. package/util/cpu.d.ts +9 -9
  108. package/util/cpu.js +42 -42
  109. package/util/find.d.ts +6 -6
  110. package/util/find.js +20 -20
  111. package/util/node.d.ts +21 -21
  112. package/util/node.js +34 -34
  113. package/util/options.d.ts +70 -70
  114. package/util/options.js +262 -262
  115. package/util/terminal.d.ts +52 -52
  116. package/util/terminal.js +35 -35
  117. package/util/text.d.ts +26 -26
  118. package/util/text.js +114 -114
  119. package/util/tsconfig.json +9 -9
  120. package/util/web.d.ts +11 -11
  121. package/util/web.js +33 -33
@@ -1,326 +1,326 @@
1
- /// <reference path="./rt/index.d.ts" />
2
-
3
- import { HASH } from "./util/hash";
4
- import { Runtime } from "shared/runtime";
5
- import { E_KEYNOTFOUND } from "./util/error";
6
-
7
- // Open-addressing hash map with linear probing.
8
- // Single contiguous buffer, cache-friendly, zero GC overhead under runtime=memory.
9
-
10
- // @ts-ignore: decorator
11
- @inline const SLOT_EMPTY: u8 = 0;
12
- // @ts-ignore: decorator
13
- @inline const SLOT_OCCUPIED: u8 = 1;
14
- // @ts-ignore: decorator
15
- @inline const SLOT_DELETED: u8 = 2;
16
-
17
- // @ts-ignore: decorator
18
- @inline const FM_INITIAL_CAPACITY: i32 = 16;
19
-
20
- // Max load factor 75% = 3/4
21
- // @ts-ignore: decorator
22
- @inline const FM_LOAD_N: i32 = 3;
23
- // @ts-ignore: decorator
24
- @inline const FM_LOAD_D: i32 = 4;
25
-
26
- /** Structure of a FixedMap slot. */
27
- @unmanaged class FixedMapSlot<K,V> {
28
- hash: u32;
29
- state: u8;
30
- key: K;
31
- value: V;
32
- }
33
-
34
- /** Computes the alignment of a slot. */
35
- // @ts-ignore: decorator
36
- @inline
37
- function FM_SLOT_ALIGN<K,V>(): usize {
38
- const maxkv = sizeof<K>() > sizeof<V>() ? sizeof<K>() : sizeof<V>();
39
- const maxAll = maxkv > sizeof<u32>() ? maxkv : sizeof<u32>();
40
- return maxAll - 1;
41
- }
42
-
43
- /** Computes the aligned size of a slot. */
44
- // @ts-ignore: decorator
45
- @inline
46
- function FM_SLOT_SIZE<K,V>(): usize {
47
- const align = FM_SLOT_ALIGN<K,V>();
48
- return (offsetof<FixedMapSlot<K,V>>() + align) & ~align;
49
- }
50
-
51
- @final
52
- export class FixedMap<K,V> {
53
-
54
- private dataPtr: usize = 0;
55
- private _capacity: i32 = 0;
56
- private capacityMask: u32 = 0;
57
- private _count: i32 = 0;
58
- private _entriesUsed: i32 = 0;
59
-
60
- constructor(initialCapacity: i32 = FM_INITIAL_CAPACITY) {
61
- if (initialCapacity < 4) initialCapacity = 4;
62
- let cap: i32 = 4;
63
- while (cap < initialCapacity) cap <<= 1;
64
-
65
- let bufferSize = <usize>cap * FM_SLOT_SIZE<K,V>();
66
- let ptr: usize;
67
- if (ASC_RUNTIME == Runtime.Memory) {
68
- ptr = __alloc(bufferSize);
69
- } else {
70
- ptr = __new(bufferSize, idof<ArrayBuffer>());
71
- }
72
- memory.fill(ptr, 0, bufferSize);
73
- this.dataPtr = ptr;
74
- this._capacity = cap;
75
- this.capacityMask = <u32>(cap - 1);
76
- if (ASC_RUNTIME != Runtime.Memory) {
77
- __link(changetype<usize>(this), ptr, false);
78
- }
79
- }
80
-
81
- get size(): i32 {
82
- return this._count;
83
- }
84
-
85
- has(key: K): bool {
86
- return this.findSlot(key, HASH<K>(key)) != -1;
87
- }
88
-
89
- @operator("[]")
90
- get(key: K): V {
91
- let idx = this.findSlot(key, HASH<K>(key));
92
- if (idx == -1) throw new Error(E_KEYNOTFOUND);
93
- let slot = changetype<FixedMapSlot<K,V>>(
94
- this.dataPtr + <usize>idx * FM_SLOT_SIZE<K,V>()
95
- );
96
- return slot.value;
97
- }
98
-
99
- @operator("[]=")
100
- set(key: K, value: V): this {
101
- // Check load factor before insert
102
- if (this._entriesUsed * FM_LOAD_D >= this._capacity * FM_LOAD_N) {
103
- this.rehash(
104
- this._count * 2 > this._capacity
105
- ? this._capacity << 1
106
- : this._capacity
107
- );
108
- }
109
-
110
- let hashCode = HASH<K>(key);
111
- let mask = this.capacityMask;
112
- let start = hashCode & mask;
113
- let i = start;
114
- let data = this.dataPtr;
115
- let slotSize = FM_SLOT_SIZE<K,V>();
116
- let firstDeleted: i32 = -1;
117
-
118
- do {
119
- let slot = changetype<FixedMapSlot<K,V>>(data + <usize>i * slotSize);
120
- let state = slot.state;
121
-
122
- if (state == SLOT_OCCUPIED) {
123
- if (slot.hash == hashCode && slot.key == key) {
124
- slot.value = value;
125
- if (isManaged<V>()) {
126
- if (ASC_RUNTIME != Runtime.Memory) {
127
- __link(changetype<usize>(this), changetype<usize>(value), true);
128
- }
129
- }
130
- return this;
131
- }
132
- } else if (state == SLOT_EMPTY) {
133
- let insertIdx: u32 = firstDeleted != -1 ? <u32>firstDeleted : i;
134
- let insertSlot = changetype<FixedMapSlot<K,V>>(data + <usize>insertIdx * slotSize);
135
- insertSlot.hash = hashCode;
136
- insertSlot.state = SLOT_OCCUPIED;
137
- insertSlot.key = key;
138
- insertSlot.value = value;
139
- ++this._count;
140
- if (firstDeleted == -1) ++this._entriesUsed;
141
- if (isManaged<K>()) {
142
- if (ASC_RUNTIME != Runtime.Memory) {
143
- __link(changetype<usize>(this), changetype<usize>(key), true);
144
- }
145
- }
146
- if (isManaged<V>()) {
147
- if (ASC_RUNTIME != Runtime.Memory) {
148
- __link(changetype<usize>(this), changetype<usize>(value), true);
149
- }
150
- }
151
- return this;
152
- } else { // DELETED
153
- if (firstDeleted == -1) firstDeleted = <i32>i;
154
- }
155
-
156
- i = (i + 1) & mask;
157
- } while (i != start);
158
-
159
- // All slots are OCCUPIED or DELETED (shouldn't happen with load factor check)
160
- // Insert at firstDeleted if available
161
- if (firstDeleted != -1) {
162
- let insertSlot = changetype<FixedMapSlot<K,V>>(data + <usize>firstDeleted * slotSize);
163
- insertSlot.hash = hashCode;
164
- insertSlot.state = SLOT_OCCUPIED;
165
- insertSlot.key = key;
166
- insertSlot.value = value;
167
- ++this._count;
168
- if (isManaged<K>()) {
169
- if (ASC_RUNTIME != Runtime.Memory) {
170
- __link(changetype<usize>(this), changetype<usize>(key), true);
171
- }
172
- }
173
- if (isManaged<V>()) {
174
- if (ASC_RUNTIME != Runtime.Memory) {
175
- __link(changetype<usize>(this), changetype<usize>(value), true);
176
- }
177
- }
178
- }
179
- return this;
180
- }
181
-
182
- delete(key: K): bool {
183
- let idx = this.findSlot(key, HASH<K>(key));
184
- if (idx == -1) return false;
185
- let slot = changetype<FixedMapSlot<K,V>>(
186
- this.dataPtr + <usize>idx * FM_SLOT_SIZE<K,V>()
187
- );
188
- slot.state = SLOT_DELETED;
189
- --this._count;
190
- return true;
191
- }
192
-
193
- clear(): void {
194
- memory.fill(this.dataPtr, 0, <usize>this._capacity * FM_SLOT_SIZE<K,V>());
195
- this._count = 0;
196
- this._entriesUsed = 0;
197
- }
198
-
199
- keys(): K[] {
200
- let data = this.dataPtr;
201
- let cap = this._capacity;
202
- let slotSize = FM_SLOT_SIZE<K,V>();
203
- let keys = new Array<K>(this._count);
204
- let length = 0;
205
- for (let i = 0; i < cap; ++i) {
206
- let slot = changetype<FixedMapSlot<K,V>>(data + <usize>i * slotSize);
207
- if (slot.state == SLOT_OCCUPIED) {
208
- unchecked(keys[length++] = slot.key);
209
- }
210
- }
211
- keys.length = length;
212
- return keys;
213
- }
214
-
215
- values(): V[] {
216
- let data = this.dataPtr;
217
- let cap = this._capacity;
218
- let slotSize = FM_SLOT_SIZE<K,V>();
219
- let values = new Array<V>(this._count);
220
- let length = 0;
221
- for (let i = 0; i < cap; ++i) {
222
- let slot = changetype<FixedMapSlot<K,V>>(data + <usize>i * slotSize);
223
- if (slot.state == SLOT_OCCUPIED) {
224
- unchecked(values[length++] = slot.value);
225
- }
226
- }
227
- values.length = length;
228
- return values;
229
- }
230
-
231
- toString(): string {
232
- return "[object FixedMap]";
233
- }
234
-
235
- @inline
236
- private findSlot(key: K, hashCode: u32): i32 {
237
- let mask = this.capacityMask;
238
- let start = hashCode & mask;
239
- let i = start;
240
- let data = this.dataPtr;
241
- let slotSize = FM_SLOT_SIZE<K,V>();
242
- do {
243
- let slot = changetype<FixedMapSlot<K,V>>(data + <usize>i * slotSize);
244
- let state = slot.state;
245
- if (state == SLOT_EMPTY) return -1;
246
- if (state == SLOT_OCCUPIED && slot.hash == hashCode && slot.key == key) {
247
- return <i32>i;
248
- }
249
- i = (i + 1) & mask;
250
- } while (i != start);
251
- return -1;
252
- }
253
-
254
- private rehash(newCapacity: i32): void {
255
- let oldData = this.dataPtr;
256
- let oldCapacity = this._capacity;
257
- let slotSize = FM_SLOT_SIZE<K,V>();
258
- let newMask = <u32>(newCapacity - 1);
259
- let bufferSize = <usize>newCapacity * slotSize;
260
-
261
- let newData: usize;
262
- if (ASC_RUNTIME == Runtime.Memory) {
263
- newData = __alloc(bufferSize);
264
- } else {
265
- newData = __new(bufferSize, idof<ArrayBuffer>());
266
- }
267
- memory.fill(newData, 0, bufferSize);
268
-
269
- for (let i = 0; i < oldCapacity; ++i) {
270
- let oldSlot = changetype<FixedMapSlot<K,V>>(oldData + <usize>i * slotSize);
271
- if (oldSlot.state == SLOT_OCCUPIED) {
272
- let h = oldSlot.hash;
273
- let j = h & newMask;
274
- while (changetype<FixedMapSlot<K,V>>(newData + <usize>j * slotSize).state != SLOT_EMPTY) {
275
- j = (j + 1) & newMask;
276
- }
277
- let newSlot = changetype<FixedMapSlot<K,V>>(newData + <usize>j * slotSize);
278
- newSlot.hash = h;
279
- newSlot.state = SLOT_OCCUPIED;
280
- newSlot.key = oldSlot.key;
281
- newSlot.value = oldSlot.value;
282
- }
283
- }
284
-
285
- this.dataPtr = newData;
286
- this._capacity = newCapacity;
287
- this.capacityMask = newMask;
288
- this._entriesUsed = this._count;
289
-
290
- if (ASC_RUNTIME != Runtime.Memory) {
291
- __link(changetype<usize>(this), newData, false);
292
- }
293
- }
294
-
295
- // RT integration
296
-
297
- @unsafe private __visit(cookie: u32): void {
298
- if (ASC_RUNTIME != Runtime.Memory) {
299
- let data = this.dataPtr;
300
- if (data) {
301
- if (isManaged<K>() || isManaged<V>()) {
302
- let cap = this._capacity;
303
- let slotSize = FM_SLOT_SIZE<K,V>();
304
- for (let i = 0; i < cap; ++i) {
305
- let slot = changetype<FixedMapSlot<K,V>>(data + <usize>i * slotSize);
306
- if (slot.state == SLOT_OCCUPIED) {
307
- if (isManaged<K>()) {
308
- let val = changetype<usize>(slot.key);
309
- if (isNullable<K>()) {
310
- if (val) __visit(val, cookie);
311
- } else __visit(val, cookie);
312
- }
313
- if (isManaged<V>()) {
314
- let val = changetype<usize>(slot.value);
315
- if (isNullable<V>()) {
316
- if (val) __visit(val, cookie);
317
- } else __visit(val, cookie);
318
- }
319
- }
320
- }
321
- }
322
- __visit(data, cookie);
323
- }
324
- }
325
- }
326
- }
1
+ /// <reference path="./rt/index.d.ts" />
2
+
3
+ import { HASH } from "./util/hash";
4
+ import { Runtime } from "shared/runtime";
5
+ import { E_KEYNOTFOUND } from "./util/error";
6
+
7
+ // Open-addressing hash map with linear probing.
8
+ // Single contiguous buffer, cache-friendly, zero GC overhead under runtime=memory.
9
+
10
+ // @ts-ignore: decorator
11
+ @inline const SLOT_EMPTY: u8 = 0;
12
+ // @ts-ignore: decorator
13
+ @inline const SLOT_OCCUPIED: u8 = 1;
14
+ // @ts-ignore: decorator
15
+ @inline const SLOT_DELETED: u8 = 2;
16
+
17
+ // @ts-ignore: decorator
18
+ @inline const FM_INITIAL_CAPACITY: i32 = 16;
19
+
20
+ // Max load factor 75% = 3/4
21
+ // @ts-ignore: decorator
22
+ @inline const FM_LOAD_N: i32 = 3;
23
+ // @ts-ignore: decorator
24
+ @inline const FM_LOAD_D: i32 = 4;
25
+
26
+ /** Structure of a FixedMap slot. */
27
+ @unmanaged class FixedMapSlot<K,V> {
28
+ hash: u32;
29
+ state: u8;
30
+ key: K;
31
+ value: V;
32
+ }
33
+
34
+ /** Computes the alignment of a slot. */
35
+ // @ts-ignore: decorator
36
+ @inline
37
+ function FM_SLOT_ALIGN<K,V>(): usize {
38
+ const maxkv = sizeof<K>() > sizeof<V>() ? sizeof<K>() : sizeof<V>();
39
+ const maxAll = maxkv > sizeof<u32>() ? maxkv : sizeof<u32>();
40
+ return maxAll - 1;
41
+ }
42
+
43
+ /** Computes the aligned size of a slot. */
44
+ // @ts-ignore: decorator
45
+ @inline
46
+ function FM_SLOT_SIZE<K,V>(): usize {
47
+ const align = FM_SLOT_ALIGN<K,V>();
48
+ return (offsetof<FixedMapSlot<K,V>>() + align) & ~align;
49
+ }
50
+
51
+ @final
52
+ export class FixedMap<K,V> {
53
+
54
+ private dataPtr: usize = 0;
55
+ private _capacity: i32 = 0;
56
+ private capacityMask: u32 = 0;
57
+ private _count: i32 = 0;
58
+ private _entriesUsed: i32 = 0;
59
+
60
+ constructor(initialCapacity: i32 = FM_INITIAL_CAPACITY) {
61
+ if (initialCapacity < 4) initialCapacity = 4;
62
+ let cap: i32 = 4;
63
+ while (cap < initialCapacity) cap <<= 1;
64
+
65
+ let bufferSize = <usize>cap * FM_SLOT_SIZE<K,V>();
66
+ let ptr: usize;
67
+ if (ASC_RUNTIME == Runtime.Memory) {
68
+ ptr = __alloc(bufferSize);
69
+ } else {
70
+ ptr = __new(bufferSize, idof<ArrayBuffer>());
71
+ }
72
+ memory.fill(ptr, 0, bufferSize);
73
+ this.dataPtr = ptr;
74
+ this._capacity = cap;
75
+ this.capacityMask = <u32>(cap - 1);
76
+ if (ASC_RUNTIME != Runtime.Memory) {
77
+ __link(changetype<usize>(this), ptr, false);
78
+ }
79
+ }
80
+
81
+ get size(): i32 {
82
+ return this._count;
83
+ }
84
+
85
+ has(key: K): bool {
86
+ return this.findSlot(key, HASH<K>(key)) != -1;
87
+ }
88
+
89
+ @operator("[]")
90
+ get(key: K): V {
91
+ let idx = this.findSlot(key, HASH<K>(key));
92
+ if (idx == -1) throw new Error(E_KEYNOTFOUND);
93
+ let slot = changetype<FixedMapSlot<K,V>>(
94
+ this.dataPtr + <usize>idx * FM_SLOT_SIZE<K,V>()
95
+ );
96
+ return slot.value;
97
+ }
98
+
99
+ @operator("[]=")
100
+ set(key: K, value: V): this {
101
+ // Check load factor before insert
102
+ if (this._entriesUsed * FM_LOAD_D >= this._capacity * FM_LOAD_N) {
103
+ this.rehash(
104
+ this._count * 2 > this._capacity
105
+ ? this._capacity << 1
106
+ : this._capacity
107
+ );
108
+ }
109
+
110
+ let hashCode = HASH<K>(key);
111
+ let mask = this.capacityMask;
112
+ let start = hashCode & mask;
113
+ let i = start;
114
+ let data = this.dataPtr;
115
+ let slotSize = FM_SLOT_SIZE<K,V>();
116
+ let firstDeleted: i32 = -1;
117
+
118
+ do {
119
+ let slot = changetype<FixedMapSlot<K,V>>(data + <usize>i * slotSize);
120
+ let state = slot.state;
121
+
122
+ if (state == SLOT_OCCUPIED) {
123
+ if (slot.hash == hashCode && slot.key == key) {
124
+ slot.value = value;
125
+ if (isManaged<V>()) {
126
+ if (ASC_RUNTIME != Runtime.Memory) {
127
+ __link(changetype<usize>(this), changetype<usize>(value), true);
128
+ }
129
+ }
130
+ return this;
131
+ }
132
+ } else if (state == SLOT_EMPTY) {
133
+ let insertIdx: u32 = firstDeleted != -1 ? <u32>firstDeleted : i;
134
+ let insertSlot = changetype<FixedMapSlot<K,V>>(data + <usize>insertIdx * slotSize);
135
+ insertSlot.hash = hashCode;
136
+ insertSlot.state = SLOT_OCCUPIED;
137
+ insertSlot.key = key;
138
+ insertSlot.value = value;
139
+ ++this._count;
140
+ if (firstDeleted == -1) ++this._entriesUsed;
141
+ if (isManaged<K>()) {
142
+ if (ASC_RUNTIME != Runtime.Memory) {
143
+ __link(changetype<usize>(this), changetype<usize>(key), true);
144
+ }
145
+ }
146
+ if (isManaged<V>()) {
147
+ if (ASC_RUNTIME != Runtime.Memory) {
148
+ __link(changetype<usize>(this), changetype<usize>(value), true);
149
+ }
150
+ }
151
+ return this;
152
+ } else { // DELETED
153
+ if (firstDeleted == -1) firstDeleted = <i32>i;
154
+ }
155
+
156
+ i = (i + 1) & mask;
157
+ } while (i != start);
158
+
159
+ // All slots are OCCUPIED or DELETED (shouldn't happen with load factor check)
160
+ // Insert at firstDeleted if available
161
+ if (firstDeleted != -1) {
162
+ let insertSlot = changetype<FixedMapSlot<K,V>>(data + <usize>firstDeleted * slotSize);
163
+ insertSlot.hash = hashCode;
164
+ insertSlot.state = SLOT_OCCUPIED;
165
+ insertSlot.key = key;
166
+ insertSlot.value = value;
167
+ ++this._count;
168
+ if (isManaged<K>()) {
169
+ if (ASC_RUNTIME != Runtime.Memory) {
170
+ __link(changetype<usize>(this), changetype<usize>(key), true);
171
+ }
172
+ }
173
+ if (isManaged<V>()) {
174
+ if (ASC_RUNTIME != Runtime.Memory) {
175
+ __link(changetype<usize>(this), changetype<usize>(value), true);
176
+ }
177
+ }
178
+ }
179
+ return this;
180
+ }
181
+
182
+ delete(key: K): bool {
183
+ let idx = this.findSlot(key, HASH<K>(key));
184
+ if (idx == -1) return false;
185
+ let slot = changetype<FixedMapSlot<K,V>>(
186
+ this.dataPtr + <usize>idx * FM_SLOT_SIZE<K,V>()
187
+ );
188
+ slot.state = SLOT_DELETED;
189
+ --this._count;
190
+ return true;
191
+ }
192
+
193
+ clear(): void {
194
+ memory.fill(this.dataPtr, 0, <usize>this._capacity * FM_SLOT_SIZE<K,V>());
195
+ this._count = 0;
196
+ this._entriesUsed = 0;
197
+ }
198
+
199
+ keys(): K[] {
200
+ let data = this.dataPtr;
201
+ let cap = this._capacity;
202
+ let slotSize = FM_SLOT_SIZE<K,V>();
203
+ let keys = new Array<K>(this._count);
204
+ let length = 0;
205
+ for (let i = 0; i < cap; ++i) {
206
+ let slot = changetype<FixedMapSlot<K,V>>(data + <usize>i * slotSize);
207
+ if (slot.state == SLOT_OCCUPIED) {
208
+ unchecked(keys[length++] = slot.key);
209
+ }
210
+ }
211
+ keys.length = length;
212
+ return keys;
213
+ }
214
+
215
+ values(): V[] {
216
+ let data = this.dataPtr;
217
+ let cap = this._capacity;
218
+ let slotSize = FM_SLOT_SIZE<K,V>();
219
+ let values = new Array<V>(this._count);
220
+ let length = 0;
221
+ for (let i = 0; i < cap; ++i) {
222
+ let slot = changetype<FixedMapSlot<K,V>>(data + <usize>i * slotSize);
223
+ if (slot.state == SLOT_OCCUPIED) {
224
+ unchecked(values[length++] = slot.value);
225
+ }
226
+ }
227
+ values.length = length;
228
+ return values;
229
+ }
230
+
231
+ toString(): string {
232
+ return "[object FixedMap]";
233
+ }
234
+
235
+ @inline
236
+ private findSlot(key: K, hashCode: u32): i32 {
237
+ let mask = this.capacityMask;
238
+ let start = hashCode & mask;
239
+ let i = start;
240
+ let data = this.dataPtr;
241
+ let slotSize = FM_SLOT_SIZE<K,V>();
242
+ do {
243
+ let slot = changetype<FixedMapSlot<K,V>>(data + <usize>i * slotSize);
244
+ let state = slot.state;
245
+ if (state == SLOT_EMPTY) return -1;
246
+ if (state == SLOT_OCCUPIED && slot.hash == hashCode && slot.key == key) {
247
+ return <i32>i;
248
+ }
249
+ i = (i + 1) & mask;
250
+ } while (i != start);
251
+ return -1;
252
+ }
253
+
254
+ private rehash(newCapacity: i32): void {
255
+ let oldData = this.dataPtr;
256
+ let oldCapacity = this._capacity;
257
+ let slotSize = FM_SLOT_SIZE<K,V>();
258
+ let newMask = <u32>(newCapacity - 1);
259
+ let bufferSize = <usize>newCapacity * slotSize;
260
+
261
+ let newData: usize;
262
+ if (ASC_RUNTIME == Runtime.Memory) {
263
+ newData = __alloc(bufferSize);
264
+ } else {
265
+ newData = __new(bufferSize, idof<ArrayBuffer>());
266
+ }
267
+ memory.fill(newData, 0, bufferSize);
268
+
269
+ for (let i = 0; i < oldCapacity; ++i) {
270
+ let oldSlot = changetype<FixedMapSlot<K,V>>(oldData + <usize>i * slotSize);
271
+ if (oldSlot.state == SLOT_OCCUPIED) {
272
+ let h = oldSlot.hash;
273
+ let j = h & newMask;
274
+ while (changetype<FixedMapSlot<K,V>>(newData + <usize>j * slotSize).state != SLOT_EMPTY) {
275
+ j = (j + 1) & newMask;
276
+ }
277
+ let newSlot = changetype<FixedMapSlot<K,V>>(newData + <usize>j * slotSize);
278
+ newSlot.hash = h;
279
+ newSlot.state = SLOT_OCCUPIED;
280
+ newSlot.key = oldSlot.key;
281
+ newSlot.value = oldSlot.value;
282
+ }
283
+ }
284
+
285
+ this.dataPtr = newData;
286
+ this._capacity = newCapacity;
287
+ this.capacityMask = newMask;
288
+ this._entriesUsed = this._count;
289
+
290
+ if (ASC_RUNTIME != Runtime.Memory) {
291
+ __link(changetype<usize>(this), newData, false);
292
+ }
293
+ }
294
+
295
+ // RT integration
296
+
297
+ @unsafe private __visit(cookie: u32): void {
298
+ if (ASC_RUNTIME != Runtime.Memory) {
299
+ let data = this.dataPtr;
300
+ if (data) {
301
+ if (isManaged<K>() || isManaged<V>()) {
302
+ let cap = this._capacity;
303
+ let slotSize = FM_SLOT_SIZE<K,V>();
304
+ for (let i = 0; i < cap; ++i) {
305
+ let slot = changetype<FixedMapSlot<K,V>>(data + <usize>i * slotSize);
306
+ if (slot.state == SLOT_OCCUPIED) {
307
+ if (isManaged<K>()) {
308
+ let val = changetype<usize>(slot.key);
309
+ if (isNullable<K>()) {
310
+ if (val) __visit(val, cookie);
311
+ } else __visit(val, cookie);
312
+ }
313
+ if (isManaged<V>()) {
314
+ let val = changetype<usize>(slot.value);
315
+ if (isNullable<V>()) {
316
+ if (val) __visit(val, cookie);
317
+ } else __visit(val, cookie);
318
+ }
319
+ }
320
+ }
321
+ }
322
+ __visit(data, cookie);
323
+ }
324
+ }
325
+ }
326
+ }