@grain/stdlib 0.4.6 → 0.5.0
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/CHANGELOG.md +73 -0
- package/array.gr +18 -18
- package/array.md +18 -18
- package/bigint.gr +497 -0
- package/bigint.md +811 -0
- package/buffer.gr +49 -213
- package/buffer.md +24 -17
- package/bytes.gr +100 -202
- package/bytes.md +19 -0
- package/char.gr +63 -133
- package/exception.md +6 -0
- package/float32.gr +39 -78
- package/float64.gr +43 -78
- package/hash.gr +37 -37
- package/int32.gr +152 -198
- package/int32.md +104 -0
- package/int64.gr +151 -197
- package/int64.md +104 -0
- package/list.gr +467 -70
- package/list.md +1141 -0
- package/map.gr +192 -7
- package/map.md +525 -0
- package/number.gr +30 -54
- package/number.md +3 -3
- package/option.md +1 -1
- package/package.json +3 -3
- package/pervasives.gr +499 -59
- package/pervasives.md +1116 -0
- package/queue.gr +4 -0
- package/queue.md +10 -0
- package/random.gr +196 -0
- package/random.md +179 -0
- package/regex.gr +1833 -842
- package/regex.md +11 -11
- package/result.md +1 -1
- package/runtime/bigint.gr +2045 -0
- package/runtime/bigint.md +326 -0
- package/runtime/dataStructures.gr +99 -278
- package/runtime/dataStructures.md +391 -0
- package/runtime/debug.md +6 -0
- package/runtime/equal.gr +5 -23
- package/runtime/equal.md +6 -0
- package/runtime/exception.md +30 -0
- package/runtime/gc.gr +20 -3
- package/runtime/gc.md +36 -0
- package/runtime/malloc.gr +13 -11
- package/runtime/malloc.md +55 -0
- package/runtime/numberUtils.gr +91 -41
- package/runtime/numberUtils.md +54 -0
- package/runtime/numbers.gr +1043 -391
- package/runtime/numbers.md +300 -0
- package/runtime/string.gr +136 -230
- package/runtime/string.md +24 -0
- package/runtime/stringUtils.gr +58 -38
- package/runtime/stringUtils.md +6 -0
- package/runtime/unsafe/constants.gr +17 -0
- package/runtime/unsafe/constants.md +72 -0
- package/runtime/unsafe/conv.md +71 -0
- package/runtime/unsafe/errors.md +204 -0
- package/runtime/unsafe/memory.md +54 -0
- package/runtime/unsafe/printWasm.md +24 -0
- package/runtime/unsafe/tags.gr +9 -8
- package/runtime/unsafe/tags.md +120 -0
- package/runtime/unsafe/wasmf32.md +168 -0
- package/runtime/unsafe/wasmf64.md +168 -0
- package/runtime/unsafe/wasmi32.md +282 -0
- package/runtime/unsafe/wasmi64.md +300 -0
- package/runtime/utils/printing.gr +62 -0
- package/runtime/utils/printing.md +18 -0
- package/runtime/wasi.gr +1 -1
- package/runtime/wasi.md +839 -0
- package/set.gr +17 -8
- package/set.md +24 -21
- package/stack.gr +3 -3
- package/stack.md +4 -6
- package/string.gr +194 -329
- package/string.md +3 -3
- package/sys/file.gr +245 -429
- package/sys/process.gr +27 -45
- package/sys/random.gr +47 -16
- package/sys/random.md +38 -0
- package/sys/time.gr +11 -27
|
@@ -0,0 +1,391 @@
|
|
|
1
|
+
### DataStructures.**allocateArray**
|
|
2
|
+
|
|
3
|
+
```grain
|
|
4
|
+
allocateArray : WasmI32 -> WasmI32
|
|
5
|
+
```
|
|
6
|
+
|
|
7
|
+
Allocates a new Grain array.
|
|
8
|
+
|
|
9
|
+
Parameters:
|
|
10
|
+
|
|
11
|
+
|param|type|description|
|
|
12
|
+
|-----|----|-----------|
|
|
13
|
+
|`numElts`|`WasmI32`|The number of elements to be contained in this array|
|
|
14
|
+
|
|
15
|
+
Returns:
|
|
16
|
+
|
|
17
|
+
|type|description|
|
|
18
|
+
|----|-----------|
|
|
19
|
+
|`WasmI32`|The pointer to the array|
|
|
20
|
+
|
|
21
|
+
### DataStructures.**allocateTuple**
|
|
22
|
+
|
|
23
|
+
```grain
|
|
24
|
+
allocateTuple : WasmI32 -> WasmI32
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Allocates a new Grain tuple.
|
|
28
|
+
|
|
29
|
+
Parameters:
|
|
30
|
+
|
|
31
|
+
|param|type|description|
|
|
32
|
+
|-----|----|-----------|
|
|
33
|
+
|`numElts`|`WasmI32`|The number of elements to be contained in this tuple|
|
|
34
|
+
|
|
35
|
+
Returns:
|
|
36
|
+
|
|
37
|
+
|type|description|
|
|
38
|
+
|----|-----------|
|
|
39
|
+
|`WasmI32`|The pointer to the tuple|
|
|
40
|
+
|
|
41
|
+
### DataStructures.**allocateBytes**
|
|
42
|
+
|
|
43
|
+
```grain
|
|
44
|
+
allocateBytes : WasmI32 -> WasmI32
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Allocates a new Grain bytes.
|
|
48
|
+
|
|
49
|
+
Parameters:
|
|
50
|
+
|
|
51
|
+
|param|type|description|
|
|
52
|
+
|-----|----|-----------|
|
|
53
|
+
|`size`|`WasmI32`|The number of bytes to be contained in this buffer|
|
|
54
|
+
|
|
55
|
+
Returns:
|
|
56
|
+
|
|
57
|
+
|type|description|
|
|
58
|
+
|----|-----------|
|
|
59
|
+
|`WasmI32`|The pointer to the bytes|
|
|
60
|
+
|
|
61
|
+
### DataStructures.**allocateString**
|
|
62
|
+
|
|
63
|
+
```grain
|
|
64
|
+
allocateString : WasmI32 -> WasmI32
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Allocates a new Grain string.
|
|
68
|
+
|
|
69
|
+
Parameters:
|
|
70
|
+
|
|
71
|
+
|param|type|description|
|
|
72
|
+
|-----|----|-----------|
|
|
73
|
+
|`size`|`WasmI32`|The size (in bytes) of the string to allocate|
|
|
74
|
+
|
|
75
|
+
Returns:
|
|
76
|
+
|
|
77
|
+
|type|description|
|
|
78
|
+
|----|-----------|
|
|
79
|
+
|`WasmI32`|The pointer to the string|
|
|
80
|
+
|
|
81
|
+
### DataStructures.**allocateInt32**
|
|
82
|
+
|
|
83
|
+
```grain
|
|
84
|
+
allocateInt32 : () -> WasmI32
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Allocates a new Int32.
|
|
88
|
+
|
|
89
|
+
Returns:
|
|
90
|
+
|
|
91
|
+
|type|description|
|
|
92
|
+
|----|-----------|
|
|
93
|
+
|`WasmI32`|The pointer to the empty Int32|
|
|
94
|
+
|
|
95
|
+
### DataStructures.**newInt32**
|
|
96
|
+
|
|
97
|
+
```grain
|
|
98
|
+
newInt32 : WasmI32 -> WasmI32
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Allocates a new Int32 with a prepopulated value
|
|
102
|
+
|
|
103
|
+
Parameters:
|
|
104
|
+
|
|
105
|
+
|param|type|description|
|
|
106
|
+
|-----|----|-----------|
|
|
107
|
+
|`value`|`WasmI32`|The value to store|
|
|
108
|
+
|
|
109
|
+
Returns:
|
|
110
|
+
|
|
111
|
+
|type|description|
|
|
112
|
+
|----|-----------|
|
|
113
|
+
|`WasmI32`|The pointer to the Int32|
|
|
114
|
+
|
|
115
|
+
### DataStructures.**allocateInt64**
|
|
116
|
+
|
|
117
|
+
```grain
|
|
118
|
+
allocateInt64 : () -> WasmI32
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Allocates a new Int64.
|
|
122
|
+
|
|
123
|
+
Returns:
|
|
124
|
+
|
|
125
|
+
|type|description|
|
|
126
|
+
|----|-----------|
|
|
127
|
+
|`WasmI32`|The pointer to the empty Int64|
|
|
128
|
+
|
|
129
|
+
### DataStructures.**newInt64**
|
|
130
|
+
|
|
131
|
+
```grain
|
|
132
|
+
newInt64 : WasmI64 -> WasmI32
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Allocates a new Int64 with a prepopulated value
|
|
136
|
+
|
|
137
|
+
Parameters:
|
|
138
|
+
|
|
139
|
+
|param|type|description|
|
|
140
|
+
|-----|----|-----------|
|
|
141
|
+
|`value`|`WasmI64`|The value to store|
|
|
142
|
+
|
|
143
|
+
Returns:
|
|
144
|
+
|
|
145
|
+
|type|description|
|
|
146
|
+
|----|-----------|
|
|
147
|
+
|`WasmI32`|The pointer to the Int64|
|
|
148
|
+
|
|
149
|
+
### DataStructures.**allocateFloat32**
|
|
150
|
+
|
|
151
|
+
```grain
|
|
152
|
+
allocateFloat32 : () -> WasmI32
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Allocates a new Float32.
|
|
156
|
+
|
|
157
|
+
Returns:
|
|
158
|
+
|
|
159
|
+
|type|description|
|
|
160
|
+
|----|-----------|
|
|
161
|
+
|`WasmI32`|The pointer to the empty Float32|
|
|
162
|
+
|
|
163
|
+
### DataStructures.**newFloat32**
|
|
164
|
+
|
|
165
|
+
```grain
|
|
166
|
+
newFloat32 : WasmF32 -> WasmI32
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
Allocates a new Float32 with a prepopulated value
|
|
170
|
+
|
|
171
|
+
Parameters:
|
|
172
|
+
|
|
173
|
+
|param|type|description|
|
|
174
|
+
|-----|----|-----------|
|
|
175
|
+
|`value`|`WasmF32`|The value to store|
|
|
176
|
+
|
|
177
|
+
Returns:
|
|
178
|
+
|
|
179
|
+
|type|description|
|
|
180
|
+
|----|-----------|
|
|
181
|
+
|`WasmI32`|the pointer to the Float32|
|
|
182
|
+
|
|
183
|
+
### DataStructures.**allocateFloat64**
|
|
184
|
+
|
|
185
|
+
```grain
|
|
186
|
+
allocateFloat64 : () -> WasmI32
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
Allocates a new Float64.
|
|
190
|
+
|
|
191
|
+
Returns:
|
|
192
|
+
|
|
193
|
+
|type|description|
|
|
194
|
+
|----|-----------|
|
|
195
|
+
|`WasmI32`|The pointer to the empty Float64|
|
|
196
|
+
|
|
197
|
+
### DataStructures.**newFloat64**
|
|
198
|
+
|
|
199
|
+
```grain
|
|
200
|
+
newFloat64 : WasmF64 -> WasmI32
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
Allocates a new Float64 with a prepopulated value
|
|
204
|
+
|
|
205
|
+
Parameters:
|
|
206
|
+
|
|
207
|
+
|param|type|description|
|
|
208
|
+
|-----|----|-----------|
|
|
209
|
+
|`value`|`WasmF64`|The value to store|
|
|
210
|
+
|
|
211
|
+
Returns:
|
|
212
|
+
|
|
213
|
+
|type|description|
|
|
214
|
+
|----|-----------|
|
|
215
|
+
|`WasmI32`|The pointer to the Float64|
|
|
216
|
+
|
|
217
|
+
### DataStructures.**allocateRational**
|
|
218
|
+
|
|
219
|
+
```grain
|
|
220
|
+
allocateRational : () -> WasmI32
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
Allocates a new Rational.
|
|
224
|
+
|
|
225
|
+
Returns:
|
|
226
|
+
|
|
227
|
+
|type|description|
|
|
228
|
+
|----|-----------|
|
|
229
|
+
|`WasmI32`|The pointer to the empty Rational|
|
|
230
|
+
|
|
231
|
+
### DataStructures.**newRational**
|
|
232
|
+
|
|
233
|
+
```grain
|
|
234
|
+
newRational : (WasmI32, WasmI32) -> WasmI32
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
Allocates a new Rational with a prepopulated value
|
|
238
|
+
|
|
239
|
+
Parameters:
|
|
240
|
+
|
|
241
|
+
|param|type|description|
|
|
242
|
+
|-----|----|-----------|
|
|
243
|
+
|`value`|`WasmI32`|The numerator value to store|
|
|
244
|
+
|`value`|`WasmI32`|The denominator value to store|
|
|
245
|
+
|
|
246
|
+
Returns:
|
|
247
|
+
|
|
248
|
+
|type|description|
|
|
249
|
+
|----|-----------|
|
|
250
|
+
|`WasmI32`|The pointer to the Rational|
|
|
251
|
+
|
|
252
|
+
### DataStructures.**loadAdtVariant**
|
|
253
|
+
|
|
254
|
+
```grain
|
|
255
|
+
loadAdtVariant : WasmI32 -> WasmI32
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
Load the (tagged) variant of an ADT.
|
|
259
|
+
|
|
260
|
+
Parameters:
|
|
261
|
+
|
|
262
|
+
|param|type|description|
|
|
263
|
+
|-----|----|-----------|
|
|
264
|
+
|`ptr`|`WasmI32`|Untagged pointer to the ADT|
|
|
265
|
+
|
|
266
|
+
Returns:
|
|
267
|
+
|
|
268
|
+
|type|description|
|
|
269
|
+
|----|-----------|
|
|
270
|
+
|`WasmI32`|The (tagged) ADT variant id|
|
|
271
|
+
|
|
272
|
+
### DataStructures.**stringSize**
|
|
273
|
+
|
|
274
|
+
```grain
|
|
275
|
+
stringSize : WasmI32 -> WasmI32
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
Load an untagged string's size.
|
|
279
|
+
|
|
280
|
+
Parameters:
|
|
281
|
+
|
|
282
|
+
|param|type|description|
|
|
283
|
+
|-----|----|-----------|
|
|
284
|
+
|`ptr`|`WasmI32`|Untagged pointer to the string|
|
|
285
|
+
|
|
286
|
+
Returns:
|
|
287
|
+
|
|
288
|
+
|type|description|
|
|
289
|
+
|----|-----------|
|
|
290
|
+
|`WasmI32`|The string size (in bytes)|
|
|
291
|
+
|
|
292
|
+
### DataStructures.**bytesSize**
|
|
293
|
+
|
|
294
|
+
```grain
|
|
295
|
+
bytesSize : WasmI32 -> WasmI32
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
Load an untagged Bytes' size.
|
|
299
|
+
|
|
300
|
+
Parameters:
|
|
301
|
+
|
|
302
|
+
|param|type|description|
|
|
303
|
+
|-----|----|-----------|
|
|
304
|
+
|`ptr`|`WasmI32`|Untagged pointer to the Bytes|
|
|
305
|
+
|
|
306
|
+
Returns:
|
|
307
|
+
|
|
308
|
+
|type|description|
|
|
309
|
+
|----|-----------|
|
|
310
|
+
|`WasmI32`|The Bytes size (in bytes)|
|
|
311
|
+
|
|
312
|
+
### DataStructures.**tagSimpleNumber**
|
|
313
|
+
|
|
314
|
+
```grain
|
|
315
|
+
tagSimpleNumber : WasmI32 -> Number
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
Tag a simple number.
|
|
319
|
+
|
|
320
|
+
Parameters:
|
|
321
|
+
|
|
322
|
+
|param|type|description|
|
|
323
|
+
|-----|----|-----------|
|
|
324
|
+
|`num`|`WasmI32`|The number to tag|
|
|
325
|
+
|
|
326
|
+
Returns:
|
|
327
|
+
|
|
328
|
+
|type|description|
|
|
329
|
+
|----|-----------|
|
|
330
|
+
|`Number`|The tagged number|
|
|
331
|
+
|
|
332
|
+
### DataStructures.**untagSimpleNumber**
|
|
333
|
+
|
|
334
|
+
```grain
|
|
335
|
+
untagSimpleNumber : Number -> WasmI32
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
Untag a simple number.
|
|
339
|
+
|
|
340
|
+
Parameters:
|
|
341
|
+
|
|
342
|
+
|param|type|description|
|
|
343
|
+
|-----|----|-----------|
|
|
344
|
+
|`num`|`Number`|The number to untag|
|
|
345
|
+
|
|
346
|
+
Returns:
|
|
347
|
+
|
|
348
|
+
|type|description|
|
|
349
|
+
|----|-----------|
|
|
350
|
+
|`WasmI32`|The untagged number|
|
|
351
|
+
|
|
352
|
+
### DataStructures.**tagChar**
|
|
353
|
+
|
|
354
|
+
```grain
|
|
355
|
+
tagChar : WasmI32 -> Char
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
Tag a char.
|
|
359
|
+
|
|
360
|
+
Parameters:
|
|
361
|
+
|
|
362
|
+
|param|type|description|
|
|
363
|
+
|-----|----|-----------|
|
|
364
|
+
|`num`|`WasmI32`|The usv to tag|
|
|
365
|
+
|
|
366
|
+
Returns:
|
|
367
|
+
|
|
368
|
+
|type|description|
|
|
369
|
+
|----|-----------|
|
|
370
|
+
|`Char`|The tagged char|
|
|
371
|
+
|
|
372
|
+
### DataStructures.**untagChar**
|
|
373
|
+
|
|
374
|
+
```grain
|
|
375
|
+
untagChar : Char -> WasmI32
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
Untag a char.
|
|
379
|
+
|
|
380
|
+
Parameters:
|
|
381
|
+
|
|
382
|
+
|param|type|description|
|
|
383
|
+
|-----|----|-----------|
|
|
384
|
+
|`num`|`Char`|The char to untag|
|
|
385
|
+
|
|
386
|
+
Returns:
|
|
387
|
+
|
|
388
|
+
|type|description|
|
|
389
|
+
|----|-----------|
|
|
390
|
+
|`WasmI32`|The untagged usv|
|
|
391
|
+
|
package/runtime/debug.md
ADDED
package/runtime/equal.gr
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* grainc-flags --
|
|
1
|
+
/* grainc-flags --no-pervasives */
|
|
2
2
|
|
|
3
3
|
import WasmI32, {
|
|
4
4
|
eq as (==),
|
|
@@ -14,7 +14,6 @@ import WasmI32, {
|
|
|
14
14
|
} from "runtime/unsafe/wasmi32"
|
|
15
15
|
import WasmI64 from "runtime/unsafe/wasmi64"
|
|
16
16
|
import Tags from "runtime/unsafe/tags"
|
|
17
|
-
import Memory from "runtime/unsafe/memory"
|
|
18
17
|
|
|
19
18
|
primitive (!): Bool -> Bool = "@not"
|
|
20
19
|
primitive (||): (Bool, Bool) -> Bool = "@or"
|
|
@@ -22,8 +21,10 @@ primitive (&&): (Bool, Bool) -> Bool = "@and"
|
|
|
22
21
|
|
|
23
22
|
import { isNumber, numberEqual } from "runtime/numbers"
|
|
24
23
|
|
|
24
|
+
@unsafe
|
|
25
25
|
let cycleMarker = 0x80000000n
|
|
26
26
|
|
|
27
|
+
@unsafe
|
|
27
28
|
let rec heapEqualHelp = (heapTag, xptr, yptr) => {
|
|
28
29
|
match (heapTag) {
|
|
29
30
|
t when t == Tags._GRAIN_ADT_HEAP_TAG => {
|
|
@@ -157,22 +158,6 @@ let rec heapEqualHelp = (heapTag, xptr, yptr) => {
|
|
|
157
158
|
result
|
|
158
159
|
}
|
|
159
160
|
},
|
|
160
|
-
t when t == Tags._GRAIN_CHAR_HEAP_TAG => {
|
|
161
|
-
let byte = WasmI32.load8U(xptr, 4n)
|
|
162
|
-
let n = if ((byte & 0x80n) == 0x00n) {
|
|
163
|
-
1n
|
|
164
|
-
} else if ((byte & 0xF0n) == 0xF0n) {
|
|
165
|
-
4n
|
|
166
|
-
} else if ((byte & 0xE0n) == 0xE0n) {
|
|
167
|
-
3n
|
|
168
|
-
} else {
|
|
169
|
-
2n
|
|
170
|
-
}
|
|
171
|
-
// WebAssembly is little-endian, so bytes are in reverse order
|
|
172
|
-
let x = WasmI32.load(xptr, 4n) << (4n - n) * 8n
|
|
173
|
-
let y = WasmI32.load(yptr, 4n) << (4n - n) * 8n
|
|
174
|
-
x == y
|
|
175
|
-
},
|
|
176
161
|
t when t == Tags._GRAIN_TUPLE_HEAP_TAG => {
|
|
177
162
|
let xsize = WasmI32.load(xptr, 4n)
|
|
178
163
|
let ysize = WasmI32.load(yptr, 4n)
|
|
@@ -222,10 +207,7 @@ let rec heapEqualHelp = (heapTag, xptr, yptr) => {
|
|
|
222
207
|
}
|
|
223
208
|
}
|
|
224
209
|
|
|
210
|
+
@unsafe
|
|
225
211
|
export let rec equal = (x: a, y: a) => {
|
|
226
|
-
|
|
227
|
-
Memory.decRef(WasmI32.fromGrain(x))
|
|
228
|
-
Memory.decRef(WasmI32.fromGrain(y))
|
|
229
|
-
Memory.decRef(WasmI32.fromGrain(equal))
|
|
230
|
-
ret
|
|
212
|
+
equalHelp(WasmI32.fromGrain(x), WasmI32.fromGrain(y))
|
|
231
213
|
}
|
package/runtime/equal.md
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
### Exception.**Option**
|
|
2
|
+
|
|
3
|
+
```grain
|
|
4
|
+
type Option<a>
|
|
5
|
+
```
|
|
6
|
+
|
|
7
|
+
### Exception.**printers**
|
|
8
|
+
|
|
9
|
+
```grain
|
|
10
|
+
printers : WasmI32
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### Exception.**dangerouslyRegisterBasePrinter**
|
|
14
|
+
|
|
15
|
+
```grain
|
|
16
|
+
dangerouslyRegisterBasePrinter : a -> Void
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### Exception.**dangerouslyRegisterPrinter**
|
|
20
|
+
|
|
21
|
+
```grain
|
|
22
|
+
dangerouslyRegisterPrinter : a -> Void
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Exception.**printException**
|
|
26
|
+
|
|
27
|
+
```grain
|
|
28
|
+
printException : Exception -> Void
|
|
29
|
+
```
|
|
30
|
+
|
package/runtime/gc.gr
CHANGED
|
@@ -45,8 +45,18 @@ primitive unbox: Box<a> -> a = "@unbox"
|
|
|
45
45
|
|
|
46
46
|
exception DecRefError
|
|
47
47
|
|
|
48
|
-
|
|
49
|
-
|
|
48
|
+
let decimalCount32Dummy = (n: WasmI32) => 0n
|
|
49
|
+
let utoa32BufferedDummy = (a: WasmI32, b: WasmI32, c: WasmI32) => void
|
|
50
|
+
|
|
51
|
+
// When these boxes are backpatched, the reference count of each function will
|
|
52
|
+
// fall to zero which would cause them to be freed. We can't free anything that
|
|
53
|
+
// got allocated in runtime mode (since that memory space is not managed by the
|
|
54
|
+
// GC, so here we prevent that by manually setting a higher refcount.
|
|
55
|
+
WasmI32.store(WasmI32.fromGrain(decimalCount32Dummy) - 8n, 2n, 0n)
|
|
56
|
+
WasmI32.store(WasmI32.fromGrain(utoa32BufferedDummy) - 8n, 2n, 0n)
|
|
57
|
+
|
|
58
|
+
export let decimalCount32 = box(decimalCount32Dummy)
|
|
59
|
+
export let utoa32Buffered = box(utoa32BufferedDummy)
|
|
50
60
|
|
|
51
61
|
let mut _DEBUG = false
|
|
52
62
|
|
|
@@ -205,6 +215,14 @@ let rec decRef = (userPtr: WasmI32, ignoreZeros: Bool) => {
|
|
|
205
215
|
}
|
|
206
216
|
}, decRefChildren = (userPtr: WasmI32) => {
|
|
207
217
|
match (WasmI32.load(userPtr, 0n)) {
|
|
218
|
+
t when t == Tags._GRAIN_BOXED_NUM_HEAP_TAG => {
|
|
219
|
+
let tag = WasmI32.load(userPtr, 4n)
|
|
220
|
+
if (userPtr == Tags._GRAIN_RATIONAL_BOXED_NUM_TAG) {
|
|
221
|
+
// decRef underlying BigInts
|
|
222
|
+
ignore(decRef(WasmI32.load(userPtr, 8n), false))
|
|
223
|
+
ignore(decRef(WasmI32.load(userPtr, 12n), false))
|
|
224
|
+
}
|
|
225
|
+
},
|
|
208
226
|
t when t == Tags._GRAIN_ADT_HEAP_TAG => {
|
|
209
227
|
let arity = WasmI32.load(userPtr, 16n)
|
|
210
228
|
let maxOffset = arity * 4n
|
|
@@ -242,7 +260,6 @@ let rec decRef = (userPtr: WasmI32, ignoreZeros: Bool) => {
|
|
|
242
260
|
}
|
|
243
261
|
}
|
|
244
262
|
|
|
245
|
-
export let decRefIgnoreZeros = userPtr => decRef(userPtr, true)
|
|
246
263
|
export let decRef = userPtr => decRef(userPtr, false)
|
|
247
264
|
|
|
248
265
|
// For debugging:
|
package/runtime/gc.md
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
### Gc.**decimalCount32**
|
|
2
|
+
|
|
3
|
+
```grain
|
|
4
|
+
decimalCount32 : Box<WasmI32 -> WasmI32>
|
|
5
|
+
```
|
|
6
|
+
|
|
7
|
+
### Gc.**utoa32Buffered**
|
|
8
|
+
|
|
9
|
+
```grain
|
|
10
|
+
utoa32Buffered : Box<(WasmI32, WasmI32, WasmI32) -> Void>
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### Gc.**malloc**
|
|
14
|
+
|
|
15
|
+
```grain
|
|
16
|
+
malloc : WasmI32 -> WasmI32
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### Gc.**free**
|
|
20
|
+
|
|
21
|
+
```grain
|
|
22
|
+
free : WasmI32 -> Void
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Gc.**incRef**
|
|
26
|
+
|
|
27
|
+
```grain
|
|
28
|
+
incRef : WasmI32 -> WasmI32
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Gc.**decRef**
|
|
32
|
+
|
|
33
|
+
```grain
|
|
34
|
+
decRef : WasmI32 -> WasmI32
|
|
35
|
+
```
|
|
36
|
+
|
package/runtime/malloc.gr
CHANGED
|
@@ -30,6 +30,8 @@ primitive (||): (Bool, Bool) -> Bool = "@or"
|
|
|
30
30
|
|
|
31
31
|
primitive throw: Exception -> a = "@throw"
|
|
32
32
|
|
|
33
|
+
primitive heapBase: WasmI32 = "@heap.base"
|
|
34
|
+
|
|
33
35
|
/* UNDERSTANDING THE STRUCTURE OF THE FREE LIST
|
|
34
36
|
* The original K&R definition for the free list entry type was the following:
|
|
35
37
|
*
|
|
@@ -80,7 +82,7 @@ export let _RESERVED_RUNTIME_SPACE = 0x4000n
|
|
|
80
82
|
* The base the heap. The block at this address will be size 0 and
|
|
81
83
|
* serve as the root of the free list.
|
|
82
84
|
*/
|
|
83
|
-
let _BASE = _RESERVED_RUNTIME_SPACE
|
|
85
|
+
let _BASE = heapBase + _RESERVED_RUNTIME_SPACE
|
|
84
86
|
|
|
85
87
|
/**
|
|
86
88
|
* The start pointer of the heap.
|
|
@@ -114,8 +116,8 @@ let setSize = (ptr: WasmI32, val: WasmI32) => {
|
|
|
114
116
|
/**
|
|
115
117
|
* Requests that the heap be grown by the given number of bytes.
|
|
116
118
|
*
|
|
117
|
-
* @param nbytes:
|
|
118
|
-
* @
|
|
119
|
+
* @param nbytes: The number of bytes requested
|
|
120
|
+
* @returns The pointer to the beginning of the extended region if successful or -1 otherwise
|
|
119
121
|
*/
|
|
120
122
|
let growHeap = (nbytes: WasmI32) => {
|
|
121
123
|
let mut reqSize = 0n
|
|
@@ -162,7 +164,7 @@ let growHeap = (nbytes: WasmI32) => {
|
|
|
162
164
|
/**
|
|
163
165
|
* Frees the given allocated pointer.
|
|
164
166
|
*
|
|
165
|
-
* @param ap:
|
|
167
|
+
* @param ap: The pointer to free
|
|
166
168
|
*/
|
|
167
169
|
export let free = (ap: WasmI32) => {
|
|
168
170
|
let mut blockPtr = ap - 8n // 8 bytes for malloc header
|
|
@@ -210,8 +212,8 @@ export let free = (ap: WasmI32) => {
|
|
|
210
212
|
* (if you can't tell from the fact that the name is reminiscient
|
|
211
213
|
* of the 1970s, the name of this function is taken from K&R).
|
|
212
214
|
*
|
|
213
|
-
* @param nbytes:
|
|
214
|
-
* @
|
|
215
|
+
* @param nbytes: The number of bytes to try to grow the heap by
|
|
216
|
+
* @returns A pointer to the start of the free list if successful or -1 otherwise
|
|
215
217
|
*/
|
|
216
218
|
let morecore = (nbytes: WasmI32) => {
|
|
217
219
|
let origSize = heapSize
|
|
@@ -235,8 +237,8 @@ let morecore = (nbytes: WasmI32) => {
|
|
|
235
237
|
/**
|
|
236
238
|
* Allocates the requested number of bytes, returning a pointer.
|
|
237
239
|
*
|
|
238
|
-
* @param nbytes:
|
|
239
|
-
* @
|
|
240
|
+
* @param nbytes: The number of bytes to allocate
|
|
241
|
+
* @returns The pointer to the allocated region (8-byte aligned) or -1 if the allocation failed
|
|
240
242
|
*/
|
|
241
243
|
export let malloc = (nb: WasmI32) => {
|
|
242
244
|
let mut nbytes = nb
|
|
@@ -300,10 +302,10 @@ export let malloc = (nb: WasmI32) => {
|
|
|
300
302
|
}
|
|
301
303
|
|
|
302
304
|
/**
|
|
303
|
-
* Returns the current free list pointer
|
|
304
|
-
*
|
|
305
|
+
* Returns the current free list pointer.
|
|
306
|
+
* Used for debugging.
|
|
305
307
|
*
|
|
306
|
-
* @
|
|
308
|
+
* @returns The free list pointer
|
|
307
309
|
*/
|
|
308
310
|
export let getFreePtr = () => {
|
|
309
311
|
freePtr
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
### Malloc.**_RESERVED_RUNTIME_SPACE**
|
|
2
|
+
|
|
3
|
+
```grain
|
|
4
|
+
_RESERVED_RUNTIME_SPACE : WasmI32
|
|
5
|
+
```
|
|
6
|
+
|
|
7
|
+
### Malloc.**free**
|
|
8
|
+
|
|
9
|
+
```grain
|
|
10
|
+
free : WasmI32 -> Void
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Frees the given allocated pointer.
|
|
14
|
+
|
|
15
|
+
Parameters:
|
|
16
|
+
|
|
17
|
+
|param|type|description|
|
|
18
|
+
|-----|----|-----------|
|
|
19
|
+
|`ap`|`WasmI32`|The pointer to free|
|
|
20
|
+
|
|
21
|
+
### Malloc.**malloc**
|
|
22
|
+
|
|
23
|
+
```grain
|
|
24
|
+
malloc : WasmI32 -> WasmI32
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Allocates the requested number of bytes, returning a pointer.
|
|
28
|
+
|
|
29
|
+
Parameters:
|
|
30
|
+
|
|
31
|
+
|param|type|description|
|
|
32
|
+
|-----|----|-----------|
|
|
33
|
+
|`nbytes`|`WasmI32`|The number of bytes to allocate|
|
|
34
|
+
|
|
35
|
+
Returns:
|
|
36
|
+
|
|
37
|
+
|type|description|
|
|
38
|
+
|----|-----------|
|
|
39
|
+
|`WasmI32`|The pointer to the allocated region (8-byte aligned) or -1 if the allocation failed|
|
|
40
|
+
|
|
41
|
+
### Malloc.**getFreePtr**
|
|
42
|
+
|
|
43
|
+
```grain
|
|
44
|
+
getFreePtr : () -> WasmI32
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Returns the current free list pointer.
|
|
48
|
+
Used for debugging.
|
|
49
|
+
|
|
50
|
+
Returns:
|
|
51
|
+
|
|
52
|
+
|type|description|
|
|
53
|
+
|----|-----------|
|
|
54
|
+
|`WasmI32`|The free list pointer|
|
|
55
|
+
|