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,254 +1,254 @@
1
- import { BLOCK, BLOCK_OVERHEAD, OBJECT_OVERHEAD, OBJECT_MAXSIZE, TOTAL_OVERHEAD, DEBUG, TRACE, RTRACE } from "./common";
2
- import { onvisit, oncollect } from "./rtrace";
3
- import { E_ALLOCATION_TOO_LARGE, E_ALREADY_PINNED, E_NOT_PINNED } from "../util/error";
4
-
5
- // === TCMS: A Two-Color Mark & Sweep garbage collector ===
6
-
7
- // ╒═════════════╤══════════════ Colors ═══════════════════════════╕
8
- // │ Color │ Meaning │
9
- // ├─────────────┼─────────────────────────────────────────────────┤
10
- // │ WHITE* │ Unreachable │
11
- // │ BLACK* │ Reachable │
12
- // │ TRANSPARENT │ Manually pinned (always reachable) │
13
- // └─────────────┴─────────────────────────────────────────────────┘
14
- // * flipped between cycles
15
-
16
- // @ts-ignore: decorator
17
- @lazy let white = 0;
18
- // @ts-ignore: decorator
19
- @inline const transparent = 3;
20
- // @ts-ignore: decorator
21
- @inline const COLOR_MASK = 3;
22
-
23
- /** Size in memory of all objects currently managed by the GC. */
24
- // @ts-ignore: decorator
25
- @lazy let total: usize = 0;
26
-
27
- // @ts-ignore: decorator
28
- @lazy let fromSpace = initLazy(changetype<Object>(memory.data(offsetof<Object>())));
29
- // @ts-ignore: decorator
30
- @lazy let toSpace = initLazy(changetype<Object>(memory.data(offsetof<Object>())));
31
- // @ts-ignore: decorator
32
- @lazy let pinSpace = initLazy(changetype<Object>(memory.data(offsetof<Object>())));
33
-
34
- function initLazy(space: Object): Object {
35
- space.nextWithColor = changetype<usize>(space);
36
- space.prev = space;
37
- return space;
38
- }
39
-
40
- /** Visit cookie indicating scanning of an object. */
41
- // @ts-ignore: decorator
42
- @inline const VISIT_SCAN = 0;
43
-
44
- // ╒═══════════════ Managed object layout (32-bit) ════════════════╕
45
- // 3 2 1
46
- // 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 bits
47
- // ├─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┤
48
- // │ Memory manager block │
49
- // ╞═══════════════════════════════════════════════════════════╤═══╡
50
- // │ next │ C │ = nextWithColor
51
- // ├───────────────────────────────────────────────────────────┴───┤
52
- // │ prev │
53
- // ├───────────────────────────────────────────────────────────────┤
54
- // │ rtId │
55
- // ├───────────────────────────────────────────────────────────────┤
56
- // │ rtSize │
57
- // ╞>ptr═══════════════════════════════════════════════════════════╡
58
- // │ ... │
59
- // C: color
60
-
61
- /** Represents a managed object in memory, consisting of a header followed by the object's data. */
62
- @unmanaged class Object extends BLOCK {
63
- /** Pointer to the next object with color flags stored in the alignment bits. */
64
- nextWithColor: usize; // *u32
65
- /** Pointer to the previous object. */
66
- prev: Object; // *u32
67
- /** Runtime id. */
68
- rtId: u32;
69
- /** Runtime size. */
70
- rtSize: u32;
71
-
72
- /** Gets the pointer to the next object. */
73
- get next(): Object {
74
- return changetype<Object>(this.nextWithColor & ~COLOR_MASK);
75
- }
76
-
77
- /** Sets the pointer to the next object. */
78
- set next(obj: Object) {
79
- this.nextWithColor = changetype<usize>(obj) | (this.nextWithColor & COLOR_MASK);
80
- }
81
-
82
- /** Gets this object's color. */
83
- get color(): i32 {
84
- return i32(this.nextWithColor & COLOR_MASK);
85
- }
86
-
87
- /** Sets this object's color. */
88
- set color(color: i32) {
89
- this.nextWithColor = (this.nextWithColor & ~COLOR_MASK) | color;
90
- }
91
-
92
- /** Gets the size of this object in memory. */
93
- get size(): usize {
94
- return BLOCK_OVERHEAD + (this.mmInfo & ~3);
95
- }
96
-
97
- /** Unlinks this object from its list. */
98
- unlink(): void {
99
- let next = this.next;
100
- if (next == null) {
101
- if (DEBUG) assert(this.prev == null && changetype<usize>(this) < __heap_base);
102
- return; // static data not yet linked
103
- }
104
- let prev = this.prev;
105
- if (DEBUG) assert(prev);
106
- next.prev = prev;
107
- prev.next = next;
108
- }
109
-
110
- /** Links this object to the specified list, with the given color. */
111
- linkTo(list: Object, withColor: i32): void {
112
- let prev = list.prev;
113
- this.nextWithColor = changetype<usize>(list) | withColor;
114
- this.prev = prev;
115
- prev.next = this;
116
- list.prev = this;
117
- }
118
- }
119
-
120
- // Garbage collector interface
121
-
122
- // @ts-ignore: decorator
123
- @global @unsafe
124
- export function __new(size: usize, id: i32): usize {
125
- if (size > OBJECT_MAXSIZE) throw new Error(E_ALLOCATION_TOO_LARGE);
126
- let obj = changetype<Object>(__alloc(OBJECT_OVERHEAD + size) - BLOCK_OVERHEAD);
127
- obj.rtId = id;
128
- obj.rtSize = <u32>size;
129
- obj.linkTo(fromSpace, white);
130
- total += obj.size;
131
- return changetype<usize>(obj) + TOTAL_OVERHEAD;
132
- }
133
-
134
- // @ts-ignore: decorator
135
- @global @unsafe
136
- export function __renew(oldPtr: usize, size: usize): usize {
137
- let oldObj = changetype<Object>(oldPtr - TOTAL_OVERHEAD);
138
- if (oldPtr < __heap_base) { // move to heap for simplicity
139
- let newPtr = __new(size, oldObj.rtId);
140
- memory.copy(newPtr, oldPtr, min(size, oldObj.rtSize));
141
- return newPtr;
142
- }
143
- if (size > OBJECT_MAXSIZE) throw new Error(E_ALLOCATION_TOO_LARGE);
144
- total -= oldObj.size;
145
- let newPtr = __realloc(oldPtr - OBJECT_OVERHEAD, OBJECT_OVERHEAD + size) + OBJECT_OVERHEAD;
146
- let newObj = changetype<Object>(newPtr - TOTAL_OVERHEAD);
147
- newObj.rtSize = <u32>size;
148
-
149
- // Replace with new object
150
- newObj.next.prev = newObj;
151
- newObj.prev.next = newObj;
152
-
153
- total += newObj.size;
154
- return newPtr;
155
- }
156
-
157
- // @ts-ignore: decorator
158
- @global @unsafe
159
- export function __link(parentPtr: usize, childPtr: usize, expectMultiple: bool): void {
160
- // nop
161
- }
162
-
163
- // @ts-ignore: decorator
164
- @global @unsafe
165
- export function __visit(ptr: usize, cookie: i32): void {
166
- if (!ptr) return;
167
- let obj = changetype<Object>(ptr - TOTAL_OVERHEAD);
168
- if (RTRACE) if (!onvisit(obj)) return;
169
- if (obj.color == white) {
170
- obj.unlink(); // from fromSpace
171
- obj.linkTo(toSpace, i32(!white));
172
- }
173
- }
174
-
175
- // @ts-ignore: decorator
176
- @global @unsafe
177
- export function __pin(ptr: usize): usize {
178
- if (ptr) {
179
- let obj = changetype<Object>(ptr - TOTAL_OVERHEAD);
180
- if (obj.color == transparent) {
181
- throw new Error(E_ALREADY_PINNED);
182
- }
183
- obj.unlink(); // from fromSpace
184
- obj.linkTo(pinSpace, transparent);
185
- }
186
- return ptr;
187
- }
188
-
189
- // @ts-ignore: decorator
190
- @global @unsafe
191
- export function __unpin(ptr: usize): void {
192
- if (!ptr) return;
193
- let obj = changetype<Object>(ptr - TOTAL_OVERHEAD);
194
- if (obj.color != transparent) {
195
- throw new Error(E_NOT_PINNED);
196
- }
197
- obj.unlink(); // from pinSpace
198
- obj.linkTo(fromSpace, white);
199
- }
200
-
201
- // @ts-ignore: decorator
202
- @global @unsafe
203
- export function __collect(): void {
204
- if (TRACE) trace("GC at", 1, total);
205
-
206
- // Mark roots (add to toSpace)
207
- __visit_globals(VISIT_SCAN);
208
-
209
- // Mark direct members of pinned objects (add to toSpace)
210
- let pn = pinSpace;
211
- let iter = pn.next;
212
- while (iter != pn) {
213
- if (DEBUG) assert(iter.color == transparent);
214
- __visit_members(changetype<usize>(iter) + TOTAL_OVERHEAD, VISIT_SCAN);
215
- iter = iter.next;
216
- }
217
-
218
- // Mark what's reachable from toSpace
219
- let black = i32(!white);
220
- let to = toSpace;
221
- iter = to.next;
222
- while (iter != to) {
223
- if (DEBUG) assert(iter.color == black);
224
- __visit_members(changetype<usize>(iter) + TOTAL_OVERHEAD, VISIT_SCAN);
225
- iter = iter.next;
226
- }
227
-
228
- // Sweep what's left in fromSpace
229
- let from = fromSpace;
230
- iter = from.next;
231
- while (iter != from) {
232
- if (DEBUG) assert(iter.color == white);
233
- let newNext = iter.next;
234
- if (changetype<usize>(iter) < __heap_base) {
235
- iter.nextWithColor = 0; // may become linked again
236
- iter.prev = changetype<Object>(0);
237
- } else {
238
- total -= iter.size;
239
- if (isDefined(__finalize)) __finalize(changetype<usize>(iter) + TOTAL_OVERHEAD);
240
- __free(changetype<usize>(iter) + BLOCK_OVERHEAD);
241
- }
242
- iter = newNext;
243
- }
244
- from.nextWithColor = changetype<usize>(from);
245
- from.prev = from;
246
-
247
- // Flip spaces and colors
248
- fromSpace = to;
249
- toSpace = from;
250
- white = black;
251
-
252
- if (TRACE) trace("GC done at", 1, total);
253
- if (RTRACE) oncollect(total);
254
- }
1
+ import { BLOCK, BLOCK_OVERHEAD, OBJECT_OVERHEAD, OBJECT_MAXSIZE, TOTAL_OVERHEAD, DEBUG, TRACE, RTRACE } from "./common";
2
+ import { onvisit, oncollect } from "./rtrace";
3
+ import { E_ALLOCATION_TOO_LARGE, E_ALREADY_PINNED, E_NOT_PINNED } from "../util/error";
4
+
5
+ // === TCMS: A Two-Color Mark & Sweep garbage collector ===
6
+
7
+ // ╒═════════════╤══════════════ Colors ═══════════════════════════╕
8
+ // │ Color │ Meaning │
9
+ // ├─────────────┼─────────────────────────────────────────────────┤
10
+ // │ WHITE* │ Unreachable │
11
+ // │ BLACK* │ Reachable │
12
+ // │ TRANSPARENT │ Manually pinned (always reachable) │
13
+ // └─────────────┴─────────────────────────────────────────────────┘
14
+ // * flipped between cycles
15
+
16
+ // @ts-ignore: decorator
17
+ @lazy let white = 0;
18
+ // @ts-ignore: decorator
19
+ @inline const transparent = 3;
20
+ // @ts-ignore: decorator
21
+ @inline const COLOR_MASK = 3;
22
+
23
+ /** Size in memory of all objects currently managed by the GC. */
24
+ // @ts-ignore: decorator
25
+ @lazy let total: usize = 0;
26
+
27
+ // @ts-ignore: decorator
28
+ @lazy let fromSpace = initLazy(changetype<Object>(memory.data(offsetof<Object>())));
29
+ // @ts-ignore: decorator
30
+ @lazy let toSpace = initLazy(changetype<Object>(memory.data(offsetof<Object>())));
31
+ // @ts-ignore: decorator
32
+ @lazy let pinSpace = initLazy(changetype<Object>(memory.data(offsetof<Object>())));
33
+
34
+ function initLazy(space: Object): Object {
35
+ space.nextWithColor = changetype<usize>(space);
36
+ space.prev = space;
37
+ return space;
38
+ }
39
+
40
+ /** Visit cookie indicating scanning of an object. */
41
+ // @ts-ignore: decorator
42
+ @inline const VISIT_SCAN = 0;
43
+
44
+ // ╒═══════════════ Managed object layout (32-bit) ════════════════╕
45
+ // 3 2 1
46
+ // 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 bits
47
+ // ├─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┤
48
+ // │ Memory manager block │
49
+ // ╞═══════════════════════════════════════════════════════════╤═══╡
50
+ // │ next │ C │ = nextWithColor
51
+ // ├───────────────────────────────────────────────────────────┴───┤
52
+ // │ prev │
53
+ // ├───────────────────────────────────────────────────────────────┤
54
+ // │ rtId │
55
+ // ├───────────────────────────────────────────────────────────────┤
56
+ // │ rtSize │
57
+ // ╞>ptr═══════════════════════════════════════════════════════════╡
58
+ // │ ... │
59
+ // C: color
60
+
61
+ /** Represents a managed object in memory, consisting of a header followed by the object's data. */
62
+ @unmanaged class Object extends BLOCK {
63
+ /** Pointer to the next object with color flags stored in the alignment bits. */
64
+ nextWithColor: usize; // *u32
65
+ /** Pointer to the previous object. */
66
+ prev: Object; // *u32
67
+ /** Runtime id. */
68
+ rtId: u32;
69
+ /** Runtime size. */
70
+ rtSize: u32;
71
+
72
+ /** Gets the pointer to the next object. */
73
+ get next(): Object {
74
+ return changetype<Object>(this.nextWithColor & ~COLOR_MASK);
75
+ }
76
+
77
+ /** Sets the pointer to the next object. */
78
+ set next(obj: Object) {
79
+ this.nextWithColor = changetype<usize>(obj) | (this.nextWithColor & COLOR_MASK);
80
+ }
81
+
82
+ /** Gets this object's color. */
83
+ get color(): i32 {
84
+ return i32(this.nextWithColor & COLOR_MASK);
85
+ }
86
+
87
+ /** Sets this object's color. */
88
+ set color(color: i32) {
89
+ this.nextWithColor = (this.nextWithColor & ~COLOR_MASK) | color;
90
+ }
91
+
92
+ /** Gets the size of this object in memory. */
93
+ get size(): usize {
94
+ return BLOCK_OVERHEAD + (this.mmInfo & ~3);
95
+ }
96
+
97
+ /** Unlinks this object from its list. */
98
+ unlink(): void {
99
+ let next = this.next;
100
+ if (next == null) {
101
+ if (DEBUG) assert(this.prev == null && changetype<usize>(this) < __heap_base);
102
+ return; // static data not yet linked
103
+ }
104
+ let prev = this.prev;
105
+ if (DEBUG) assert(prev);
106
+ next.prev = prev;
107
+ prev.next = next;
108
+ }
109
+
110
+ /** Links this object to the specified list, with the given color. */
111
+ linkTo(list: Object, withColor: i32): void {
112
+ let prev = list.prev;
113
+ this.nextWithColor = changetype<usize>(list) | withColor;
114
+ this.prev = prev;
115
+ prev.next = this;
116
+ list.prev = this;
117
+ }
118
+ }
119
+
120
+ // Garbage collector interface
121
+
122
+ // @ts-ignore: decorator
123
+ @global @unsafe
124
+ export function __new(size: usize, id: i32): usize {
125
+ if (size > OBJECT_MAXSIZE) throw new Error(E_ALLOCATION_TOO_LARGE);
126
+ let obj = changetype<Object>(__alloc(OBJECT_OVERHEAD + size) - BLOCK_OVERHEAD);
127
+ obj.rtId = id;
128
+ obj.rtSize = <u32>size;
129
+ obj.linkTo(fromSpace, white);
130
+ total += obj.size;
131
+ return changetype<usize>(obj) + TOTAL_OVERHEAD;
132
+ }
133
+
134
+ // @ts-ignore: decorator
135
+ @global @unsafe
136
+ export function __renew(oldPtr: usize, size: usize): usize {
137
+ let oldObj = changetype<Object>(oldPtr - TOTAL_OVERHEAD);
138
+ if (oldPtr < __heap_base) { // move to heap for simplicity
139
+ let newPtr = __new(size, oldObj.rtId);
140
+ memory.copy(newPtr, oldPtr, min(size, oldObj.rtSize));
141
+ return newPtr;
142
+ }
143
+ if (size > OBJECT_MAXSIZE) throw new Error(E_ALLOCATION_TOO_LARGE);
144
+ total -= oldObj.size;
145
+ let newPtr = __realloc(oldPtr - OBJECT_OVERHEAD, OBJECT_OVERHEAD + size) + OBJECT_OVERHEAD;
146
+ let newObj = changetype<Object>(newPtr - TOTAL_OVERHEAD);
147
+ newObj.rtSize = <u32>size;
148
+
149
+ // Replace with new object
150
+ newObj.next.prev = newObj;
151
+ newObj.prev.next = newObj;
152
+
153
+ total += newObj.size;
154
+ return newPtr;
155
+ }
156
+
157
+ // @ts-ignore: decorator
158
+ @global @unsafe
159
+ export function __link(parentPtr: usize, childPtr: usize, expectMultiple: bool): void {
160
+ // nop
161
+ }
162
+
163
+ // @ts-ignore: decorator
164
+ @global @unsafe
165
+ export function __visit(ptr: usize, cookie: i32): void {
166
+ if (!ptr) return;
167
+ let obj = changetype<Object>(ptr - TOTAL_OVERHEAD);
168
+ if (RTRACE) if (!onvisit(obj)) return;
169
+ if (obj.color == white) {
170
+ obj.unlink(); // from fromSpace
171
+ obj.linkTo(toSpace, i32(!white));
172
+ }
173
+ }
174
+
175
+ // @ts-ignore: decorator
176
+ @global @unsafe
177
+ export function __pin(ptr: usize): usize {
178
+ if (ptr) {
179
+ let obj = changetype<Object>(ptr - TOTAL_OVERHEAD);
180
+ if (obj.color == transparent) {
181
+ throw new Error(E_ALREADY_PINNED);
182
+ }
183
+ obj.unlink(); // from fromSpace
184
+ obj.linkTo(pinSpace, transparent);
185
+ }
186
+ return ptr;
187
+ }
188
+
189
+ // @ts-ignore: decorator
190
+ @global @unsafe
191
+ export function __unpin(ptr: usize): void {
192
+ if (!ptr) return;
193
+ let obj = changetype<Object>(ptr - TOTAL_OVERHEAD);
194
+ if (obj.color != transparent) {
195
+ throw new Error(E_NOT_PINNED);
196
+ }
197
+ obj.unlink(); // from pinSpace
198
+ obj.linkTo(fromSpace, white);
199
+ }
200
+
201
+ // @ts-ignore: decorator
202
+ @global @unsafe
203
+ export function __collect(): void {
204
+ if (TRACE) trace("GC at", 1, total);
205
+
206
+ // Mark roots (add to toSpace)
207
+ __visit_globals(VISIT_SCAN);
208
+
209
+ // Mark direct members of pinned objects (add to toSpace)
210
+ let pn = pinSpace;
211
+ let iter = pn.next;
212
+ while (iter != pn) {
213
+ if (DEBUG) assert(iter.color == transparent);
214
+ __visit_members(changetype<usize>(iter) + TOTAL_OVERHEAD, VISIT_SCAN);
215
+ iter = iter.next;
216
+ }
217
+
218
+ // Mark what's reachable from toSpace
219
+ let black = i32(!white);
220
+ let to = toSpace;
221
+ iter = to.next;
222
+ while (iter != to) {
223
+ if (DEBUG) assert(iter.color == black);
224
+ __visit_members(changetype<usize>(iter) + TOTAL_OVERHEAD, VISIT_SCAN);
225
+ iter = iter.next;
226
+ }
227
+
228
+ // Sweep what's left in fromSpace
229
+ let from = fromSpace;
230
+ iter = from.next;
231
+ while (iter != from) {
232
+ if (DEBUG) assert(iter.color == white);
233
+ let newNext = iter.next;
234
+ if (changetype<usize>(iter) < __heap_base) {
235
+ iter.nextWithColor = 0; // may become linked again
236
+ iter.prev = changetype<Object>(0);
237
+ } else {
238
+ total -= iter.size;
239
+ if (isDefined(__finalize)) __finalize(changetype<usize>(iter) + TOTAL_OVERHEAD);
240
+ __free(changetype<usize>(iter) + BLOCK_OVERHEAD);
241
+ }
242
+ iter = newNext;
243
+ }
244
+ from.nextWithColor = changetype<usize>(from);
245
+ from.prev = from;
246
+
247
+ // Flip spaces and colors
248
+ fromSpace = to;
249
+ toSpace = from;
250
+ white = black;
251
+
252
+ if (TRACE) trace("GC done at", 1, total);
253
+ if (RTRACE) oncollect(total);
254
+ }