@grain/stdlib 0.4.4 → 0.4.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/CHANGELOG.md +7 -0
- package/array.gr +76 -57
- package/buffer.gr +7 -4
- package/bytes.gr +10 -10
- package/char.gr +112 -56
- package/char.md +200 -0
- package/hash.gr +17 -13
- package/list.gr +78 -61
- package/map.gr +106 -110
- package/number.gr +25 -7
- package/number.md +34 -0
- package/option.gr +25 -25
- package/package.json +1 -1
- package/pervasives.gr +32 -20
- package/queue.gr +4 -1
- package/range.gr +26 -26
- package/runtime/dataStructures.gr +28 -29
- package/runtime/debug.gr +0 -1
- package/runtime/equal.gr +37 -16
- package/runtime/exception.gr +28 -15
- package/runtime/gc.gr +31 -18
- package/runtime/malloc.gr +19 -11
- package/runtime/numberUtils.gr +208 -105
- package/runtime/numbers.gr +217 -118
- package/runtime/string.gr +98 -39
- package/runtime/stringUtils.gr +6 -2
- package/runtime/unsafe/conv.gr +10 -10
- package/runtime/unsafe/memory.gr +14 -3
- package/runtime/unsafe/printWasm.gr +4 -4
- package/runtime/unsafe/tags.gr +2 -2
- package/runtime/unsafe/wasmf32.gr +9 -2
- package/runtime/unsafe/wasmf64.gr +9 -2
- package/runtime/unsafe/wasmi32.gr +65 -47
- package/runtime/unsafe/wasmi64.gr +78 -50
- package/runtime/wasi.gr +199 -45
- package/set.gr +111 -116
- package/stack.gr +26 -26
- package/string.gr +273 -119
- package/sys/file.gr +356 -177
- package/sys/process.gr +10 -6
- package/sys/random.gr +3 -6
- package/sys/time.gr +3 -3
package/runtime/string.gr
CHANGED
|
@@ -14,7 +14,7 @@ import WasmI32, {
|
|
|
14
14
|
geS as (>=),
|
|
15
15
|
gtS as (>),
|
|
16
16
|
leS as (<=),
|
|
17
|
-
ltS as (<)
|
|
17
|
+
ltS as (<),
|
|
18
18
|
} from "runtime/unsafe/wasmi32"
|
|
19
19
|
import WasmI64 from "runtime/unsafe/wasmi64"
|
|
20
20
|
import WasmF32 from "runtime/unsafe/wasmf32"
|
|
@@ -25,13 +25,21 @@ import NumberUtils from "runtime/numberUtils"
|
|
|
25
25
|
|
|
26
26
|
import { allocateString, allocateArray } from "runtime/dataStructures"
|
|
27
27
|
|
|
28
|
-
import foreign wasm fd_write: (
|
|
28
|
+
import foreign wasm fd_write: (
|
|
29
|
+
WasmI32,
|
|
30
|
+
WasmI32,
|
|
31
|
+
WasmI32,
|
|
32
|
+
WasmI32,
|
|
33
|
+
) -> WasmI32 from "wasi_snapshot_preview1"
|
|
29
34
|
|
|
30
|
-
primitive (!)
|
|
31
|
-
primitive (&&)
|
|
32
|
-
primitive (||)
|
|
35
|
+
primitive (!): Bool -> Bool = "@not"
|
|
36
|
+
primitive (&&): (Bool, Bool) -> Bool = "@and"
|
|
37
|
+
primitive (||): (Bool, Bool) -> Bool = "@or"
|
|
33
38
|
|
|
34
|
-
enum StringList {
|
|
39
|
+
enum StringList {
|
|
40
|
+
SLEmpty,
|
|
41
|
+
SLCons(String, StringList),
|
|
42
|
+
}
|
|
35
43
|
|
|
36
44
|
@disableGC
|
|
37
45
|
let slConsDisableGc = (a, b) => {
|
|
@@ -42,14 +50,14 @@ let slConsDisableGc = (a, b) => {
|
|
|
42
50
|
}
|
|
43
51
|
|
|
44
52
|
@disableGC
|
|
45
|
-
let mut _RUNTIME_TYPE_METADATA_PTR = 0x01n
|
|
53
|
+
let mut _RUNTIME_TYPE_METADATA_PTR = 0x01n
|
|
46
54
|
|
|
47
55
|
@disableGC
|
|
48
56
|
let initPtr = () => {
|
|
49
57
|
// hack to avoid incRef on this pointer
|
|
50
58
|
_RUNTIME_TYPE_METADATA_PTR = 0x408n
|
|
51
59
|
}
|
|
52
|
-
initPtr()
|
|
60
|
+
initPtr()
|
|
53
61
|
|
|
54
62
|
@disableGC
|
|
55
63
|
let findTypeMetadata = (moduleId, typeId) => {
|
|
@@ -82,7 +90,7 @@ let findTypeMetadata = (moduleId, typeId) => {
|
|
|
82
90
|
}
|
|
83
91
|
|
|
84
92
|
@disableGC
|
|
85
|
-
let getVariantName =
|
|
93
|
+
let getVariantName = variant => {
|
|
86
94
|
let moduleId = WasmI32.load(variant, 4n) >> 1n
|
|
87
95
|
let typeId = WasmI32.load(variant, 8n) >> 1n
|
|
88
96
|
let variantId = WasmI32.load(variant, 12n) >> 1n
|
|
@@ -113,7 +121,7 @@ let getVariantName = (variant) => {
|
|
|
113
121
|
}
|
|
114
122
|
|
|
115
123
|
@disableGC
|
|
116
|
-
let getRecordFieldNames =
|
|
124
|
+
let getRecordFieldNames = record_ => {
|
|
117
125
|
let moduleId = WasmI32.load(record_, 4n) >> 1n
|
|
118
126
|
let typeId = WasmI32.load(record_, 8n) >> 1n
|
|
119
127
|
let arity = WasmI32.load(record_, 12n)
|
|
@@ -132,7 +140,7 @@ let getRecordFieldNames = (record_) => {
|
|
|
132
140
|
let fieldLength = WasmI32.load(fields + fieldOffset, 4n)
|
|
133
141
|
let fieldName = allocateString(fieldLength)
|
|
134
142
|
Memory.copy(fieldName + 8n, fields + fieldOffset + 8n, fieldLength)
|
|
135
|
-
WasmI32.store(fieldArray +
|
|
143
|
+
WasmI32.store(fieldArray + i * 4n, fieldName, 8n)
|
|
136
144
|
|
|
137
145
|
fieldOffset += WasmI32.load(fields + fieldOffset, 0n)
|
|
138
146
|
}
|
|
@@ -144,8 +152,9 @@ let getRecordFieldNames = (record_) => {
|
|
|
144
152
|
@disableGC
|
|
145
153
|
let rec totalBytes = (acc, list) => {
|
|
146
154
|
match (list) {
|
|
147
|
-
SLCons(hd, tl) =>
|
|
148
|
-
|
|
155
|
+
SLCons(hd, tl) =>
|
|
156
|
+
totalBytes(acc + WasmI32.load(WasmI32.fromGrain(hd), 4n), tl),
|
|
157
|
+
SLEmpty => acc,
|
|
149
158
|
}
|
|
150
159
|
}
|
|
151
160
|
|
|
@@ -158,12 +167,12 @@ let rec writeStrings = (buf, list) => {
|
|
|
158
167
|
Memory.copy(buf, hd + 8n, hdSize)
|
|
159
168
|
writeStrings(buf + hdSize, tl)
|
|
160
169
|
},
|
|
161
|
-
SLEmpty => void
|
|
170
|
+
SLEmpty => void,
|
|
162
171
|
}
|
|
163
172
|
}
|
|
164
173
|
|
|
165
174
|
@disableGC
|
|
166
|
-
let join =
|
|
175
|
+
let join = list => {
|
|
167
176
|
let len = totalBytes(0n, list)
|
|
168
177
|
let str = allocateString(len)
|
|
169
178
|
writeStrings(str + 8n, list)
|
|
@@ -171,12 +180,12 @@ let join = (list) => {
|
|
|
171
180
|
}
|
|
172
181
|
|
|
173
182
|
@disableGC
|
|
174
|
-
let reverse =
|
|
183
|
+
let reverse = list => {
|
|
175
184
|
@disableGC
|
|
176
185
|
let rec iter = (list, acc) => {
|
|
177
186
|
match (list) {
|
|
178
187
|
SLEmpty => acc,
|
|
179
|
-
SLCons(first, rest) => iter(rest, slConsDisableGc(first, acc))
|
|
188
|
+
SLCons(first, rest) => iter(rest, slConsDisableGc(first, acc)),
|
|
180
189
|
}
|
|
181
190
|
}
|
|
182
191
|
Memory.incRef(WasmI32.fromGrain(SLEmpty))
|
|
@@ -240,7 +249,12 @@ let escape = (ptr, isString) => {
|
|
|
240
249
|
let mut newSize = 2n // extra space for quote characters
|
|
241
250
|
for (let mut i = 0n; i < size; i += 1n) {
|
|
242
251
|
let byte = WasmI32.load8U(ptr + i, startOffset)
|
|
243
|
-
if (
|
|
252
|
+
if (
|
|
253
|
+
byte >= _SEQ_B && byte <= _SEQ_R || /* b, f, n, r, t, v */
|
|
254
|
+
byte == _SEQ_V ||
|
|
255
|
+
byte == _SEQ_SLASH ||
|
|
256
|
+
byte == _SEQ_QUOTE
|
|
257
|
+
) {
|
|
244
258
|
newSize += 2n
|
|
245
259
|
} else {
|
|
246
260
|
newSize += 1n
|
|
@@ -254,7 +268,12 @@ let escape = (ptr, isString) => {
|
|
|
254
268
|
|
|
255
269
|
for (let mut i = 0n; i < size; i += 1n) {
|
|
256
270
|
let byte = WasmI32.load8U(ptr + i, startOffset)
|
|
257
|
-
if (
|
|
271
|
+
if (
|
|
272
|
+
byte >= _SEQ_B && byte <= _SEQ_R || /* b, f, n, r, t, v */
|
|
273
|
+
byte == _SEQ_V ||
|
|
274
|
+
byte == _SEQ_SLASH ||
|
|
275
|
+
byte == _SEQ_QUOTE
|
|
276
|
+
) {
|
|
258
277
|
WasmI32.store8(escapedString + j, _SEQ_SLASH, stringOffset)
|
|
259
278
|
j += 1n
|
|
260
279
|
let seq = match (byte) {
|
|
@@ -264,7 +283,7 @@ let escape = (ptr, isString) => {
|
|
|
264
283
|
r when r == _SEQ_R => 0x72n,
|
|
265
284
|
t when t == _SEQ_T => 0x74n,
|
|
266
285
|
v when v == _SEQ_V => 0x76n,
|
|
267
|
-
_ => byte
|
|
286
|
+
_ => byte,
|
|
268
287
|
}
|
|
269
288
|
WasmI32.store8(escapedString + j, seq, stringOffset)
|
|
270
289
|
j += 1n
|
|
@@ -390,7 +409,11 @@ let rec heapValueToString = (ptr, extraIndents, toplevel) => {
|
|
|
390
409
|
Memory.incRef(WasmI32.fromGrain(SLEmpty))
|
|
391
410
|
let mut strings = slConsDisableGc(rparen, SLEmpty)
|
|
392
411
|
for (let mut i = variantArity * 4n - 4n; i >= 0n; i -= 4n) {
|
|
393
|
-
let tmp = toStringHelp(
|
|
412
|
+
let tmp = toStringHelp(
|
|
413
|
+
WasmI32.load(ptr + i, 20n),
|
|
414
|
+
extraIndents,
|
|
415
|
+
false
|
|
416
|
+
)
|
|
394
417
|
strings = slConsDisableGc(tmp, strings)
|
|
395
418
|
Memory.decRef(WasmI32.fromGrain(tmp))
|
|
396
419
|
if (i > 0n) {
|
|
@@ -399,7 +422,10 @@ let rec heapValueToString = (ptr, extraIndents, toplevel) => {
|
|
|
399
422
|
}
|
|
400
423
|
Memory.incRef(WasmI32.fromGrain(variantName))
|
|
401
424
|
let lparen = "("
|
|
402
|
-
strings = slConsDisableGc(
|
|
425
|
+
strings = slConsDisableGc(
|
|
426
|
+
variantName,
|
|
427
|
+
slConsDisableGc(lparen, strings)
|
|
428
|
+
)
|
|
403
429
|
let string = join(strings)
|
|
404
430
|
Memory.decRef(WasmI32.fromGrain(variantName))
|
|
405
431
|
Memory.decRef(WasmI32.fromGrain(lparen))
|
|
@@ -418,10 +444,16 @@ let rec heapValueToString = (ptr, extraIndents, toplevel) => {
|
|
|
418
444
|
"<record value>"
|
|
419
445
|
} else {
|
|
420
446
|
let prevPadAmount = extraIndents * 2n
|
|
421
|
-
let prevSpacePadding = if (prevPadAmount == 0n)
|
|
447
|
+
let prevSpacePadding = if (prevPadAmount == 0n) {
|
|
448
|
+
""
|
|
449
|
+
} else {
|
|
422
450
|
let v = allocateString(prevPadAmount)
|
|
423
|
-
Memory.fill(
|
|
424
|
-
|
|
451
|
+
Memory.fill(
|
|
452
|
+
v + 8n,
|
|
453
|
+
0x20n,
|
|
454
|
+
prevPadAmount
|
|
455
|
+
) // create indentation for closing brace
|
|
456
|
+
WasmI32.toGrain(v): String
|
|
425
457
|
}
|
|
426
458
|
let padAmount = (extraIndents + 1n) * 2n
|
|
427
459
|
let spacePadding = allocateString(padAmount)
|
|
@@ -430,13 +462,26 @@ let rec heapValueToString = (ptr, extraIndents, toplevel) => {
|
|
|
430
462
|
Memory.incRef(WasmI32.fromGrain(SLEmpty))
|
|
431
463
|
let newline = "\n"
|
|
432
464
|
let rbrace = "}"
|
|
433
|
-
let mut strings = slConsDisableGc(
|
|
465
|
+
let mut strings = slConsDisableGc(
|
|
466
|
+
newline,
|
|
467
|
+
slConsDisableGc(prevSpacePadding, slConsDisableGc(rbrace, SLEmpty))
|
|
468
|
+
)
|
|
434
469
|
let colspace = ": "
|
|
435
470
|
let comlf = ",\n"
|
|
436
|
-
for (let mut i = recordArity * 4n - 4n; i >= 0n;
|
|
471
|
+
for (let mut i = recordArity * 4n - 4n; i >= 0n; i -= 4n) {
|
|
437
472
|
let fieldName = WasmI32.toGrain(WasmI32.load(fields + i, 8n)): String
|
|
438
|
-
let fieldValue = toStringHelp(
|
|
439
|
-
|
|
473
|
+
let fieldValue = toStringHelp(
|
|
474
|
+
WasmI32.load(ptr + i, 16n),
|
|
475
|
+
extraIndents + 1n,
|
|
476
|
+
false
|
|
477
|
+
)
|
|
478
|
+
strings = slConsDisableGc(
|
|
479
|
+
spacePadding,
|
|
480
|
+
slConsDisableGc(
|
|
481
|
+
fieldName,
|
|
482
|
+
slConsDisableGc(colspace, slConsDisableGc(fieldValue, strings))
|
|
483
|
+
)
|
|
484
|
+
)
|
|
440
485
|
Memory.decRef(WasmI32.fromGrain(fieldValue))
|
|
441
486
|
if (i > 0n) {
|
|
442
487
|
strings = slConsDisableGc(comlf, strings)
|
|
@@ -497,7 +542,10 @@ let rec heapValueToString = (ptr, extraIndents, toplevel) => {
|
|
|
497
542
|
let denominator = NumberUtils.itoa32(WasmI32.load(ptr, 12n), 10n)
|
|
498
543
|
Memory.incRef(WasmI32.fromGrain(SLEmpty))
|
|
499
544
|
let slash = "/"
|
|
500
|
-
let strings = slConsDisableGc(
|
|
545
|
+
let strings = slConsDisableGc(
|
|
546
|
+
numerator,
|
|
547
|
+
slConsDisableGc(slash, slConsDisableGc(denominator, SLEmpty))
|
|
548
|
+
)
|
|
501
549
|
let string = join(strings)
|
|
502
550
|
Memory.decRef(WasmI32.fromGrain(strings))
|
|
503
551
|
Memory.decRef(WasmI32.fromGrain(numerator))
|
|
@@ -513,7 +561,7 @@ let rec heapValueToString = (ptr, extraIndents, toplevel) => {
|
|
|
513
561
|
},
|
|
514
562
|
_ => {
|
|
515
563
|
"<unknown boxed number>"
|
|
516
|
-
}
|
|
564
|
+
},
|
|
517
565
|
}
|
|
518
566
|
},
|
|
519
567
|
t when t == Tags._GRAIN_TUPLE_HEAP_TAG => {
|
|
@@ -534,7 +582,11 @@ let rec heapValueToString = (ptr, extraIndents, toplevel) => {
|
|
|
534
582
|
void
|
|
535
583
|
}
|
|
536
584
|
for (let mut i = tupleLength * 4n - 4n; i >= 0n; i -= 4n) {
|
|
537
|
-
let item = toStringHelp(
|
|
585
|
+
let item = toStringHelp(
|
|
586
|
+
WasmI32.load(ptr + i, 8n),
|
|
587
|
+
extraIndents,
|
|
588
|
+
false
|
|
589
|
+
)
|
|
538
590
|
strings = slConsDisableGc(item, strings)
|
|
539
591
|
Memory.decRef(WasmI32.fromGrain(item))
|
|
540
592
|
if (i > 0n) {
|
|
@@ -563,14 +615,21 @@ let rec heapValueToString = (ptr, extraIndents, toplevel) => {
|
|
|
563
615
|
Memory.incRef(WasmI32.fromGrain(SLEmpty))
|
|
564
616
|
let strings = slConsDisableGc(
|
|
565
617
|
"<unknown heap tag type: 0x",
|
|
566
|
-
slConsDisableGc(
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
618
|
+
slConsDisableGc(
|
|
619
|
+
NumberUtils.itoa32(tag, 16n),
|
|
620
|
+
slConsDisableGc(
|
|
621
|
+
" | value: 0x",
|
|
622
|
+
slConsDisableGc(
|
|
623
|
+
NumberUtils.itoa32(ptr, 16n),
|
|
624
|
+
slConsDisableGc(">", SLEmpty)
|
|
625
|
+
)
|
|
626
|
+
)
|
|
627
|
+
)
|
|
628
|
+
)
|
|
570
629
|
let string = join(strings)
|
|
571
630
|
Memory.decRef(WasmI32.fromGrain(strings))
|
|
572
631
|
string
|
|
573
|
-
}
|
|
632
|
+
},
|
|
574
633
|
}
|
|
575
634
|
}, toStringHelp = (grainValue, extraIndents, toplevel) => {
|
|
576
635
|
if ((grainValue & 1n) != 0n) {
|
|
@@ -624,7 +683,7 @@ let rec heapValueToString = (ptr, extraIndents, toplevel) => {
|
|
|
624
683
|
}
|
|
625
684
|
|
|
626
685
|
@disableGC
|
|
627
|
-
export let rec toString =
|
|
686
|
+
export let rec toString = value => {
|
|
628
687
|
let value = WasmI32.fromGrain(value)
|
|
629
688
|
let ret = toStringHelp(value, 0n, true)
|
|
630
689
|
Memory.decRef(value)
|
|
@@ -633,7 +692,7 @@ export let rec toString = (value) => {
|
|
|
633
692
|
}
|
|
634
693
|
|
|
635
694
|
@disableGC
|
|
636
|
-
export let rec print =
|
|
695
|
+
export let rec print = value => {
|
|
637
696
|
// First convert the value to string, if it isn't one already. Calling
|
|
638
697
|
// toString will either return value instance itself if it's already a
|
|
639
698
|
// string, or a new string with the content of value object, which will need
|
package/runtime/stringUtils.gr
CHANGED
|
@@ -45,7 +45,11 @@ export let rec parseInt = (string: String, radix: Number) => {
|
|
|
45
45
|
let strEnd = offset + strLen
|
|
46
46
|
|
|
47
47
|
let radix = WasmI32.fromGrain(radix)
|
|
48
|
-
let result = if (
|
|
48
|
+
let result = if (
|
|
49
|
+
WasmI32.eqz(radix & Tags._GRAIN_NUMBER_TAG_MASK) ||
|
|
50
|
+
radix < WasmI32.fromGrain(2) ||
|
|
51
|
+
radix > WasmI32.fromGrain(36)
|
|
52
|
+
) {
|
|
49
53
|
Memory.incRef(WasmI32.fromGrain(Err))
|
|
50
54
|
Err("Radix must be an integer between 2 and 36")
|
|
51
55
|
} else if (WasmI32.eqz(strLen)) {
|
|
@@ -158,7 +162,7 @@ export let rec parseInt = (string: String, radix: Number) => {
|
|
|
158
162
|
},
|
|
159
163
|
_ => {
|
|
160
164
|
let value = if (negative) value else WasmI64.mul(value, -1N)
|
|
161
|
-
let number = WasmI32.toGrain(reducedInteger(value)):
|
|
165
|
+
let number = WasmI32.toGrain(reducedInteger(value)): Number
|
|
162
166
|
Memory.incRef(WasmI32.fromGrain(Ok))
|
|
163
167
|
Ok(number)
|
|
164
168
|
},
|
package/runtime/unsafe/conv.gr
CHANGED
|
@@ -6,13 +6,13 @@ import WasmF64 from "runtime/unsafe/wasmf64"
|
|
|
6
6
|
import Tags from "runtime/unsafe/tags"
|
|
7
7
|
|
|
8
8
|
@disableGC
|
|
9
|
-
export let toInt32 =
|
|
9
|
+
export let toInt32 = n => {
|
|
10
10
|
let ptr = Memory.malloc(12n)
|
|
11
11
|
WasmI32.store(ptr, Tags._GRAIN_BOXED_NUM_HEAP_TAG, 0n)
|
|
12
12
|
WasmI32.store(ptr, Tags._GRAIN_INT32_BOXED_NUM_TAG, 4n)
|
|
13
13
|
WasmI32.store(ptr, n, 8n)
|
|
14
14
|
|
|
15
|
-
WasmI32.toGrain(ptr)
|
|
15
|
+
WasmI32.toGrain(ptr): Int32
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
@disableGC
|
|
@@ -22,13 +22,13 @@ export let fromInt32 = (n: Int32) => {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
@disableGC
|
|
25
|
-
export let toInt64 =
|
|
25
|
+
export let toInt64 = n => {
|
|
26
26
|
let ptr = Memory.malloc(16n)
|
|
27
27
|
WasmI32.store(ptr, Tags._GRAIN_BOXED_NUM_HEAP_TAG, 0n)
|
|
28
28
|
WasmI32.store(ptr, Tags._GRAIN_INT64_BOXED_NUM_TAG, 4n)
|
|
29
29
|
WasmI64.store(ptr, n, 8n)
|
|
30
30
|
|
|
31
|
-
WasmI32.toGrain(ptr)
|
|
31
|
+
WasmI32.toGrain(ptr): Int64
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
@disableGC
|
|
@@ -38,13 +38,13 @@ export let fromInt64 = (n: Int64) => {
|
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
@disableGC
|
|
41
|
-
export let toFloat32 =
|
|
41
|
+
export let toFloat32 = n => {
|
|
42
42
|
let ptr = Memory.malloc(12n)
|
|
43
43
|
WasmI32.store(ptr, Tags._GRAIN_BOXED_NUM_HEAP_TAG, 0n)
|
|
44
44
|
WasmI32.store(ptr, Tags._GRAIN_FLOAT32_BOXED_NUM_TAG, 4n)
|
|
45
45
|
WasmF32.store(ptr, n, 8n)
|
|
46
46
|
|
|
47
|
-
WasmI32.toGrain(ptr)
|
|
47
|
+
WasmI32.toGrain(ptr): Float32
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
@disableGC
|
|
@@ -54,13 +54,13 @@ export let fromFloat32 = (n: Float32) => {
|
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
@disableGC
|
|
57
|
-
export let toFloat64 =
|
|
57
|
+
export let toFloat64 = n => {
|
|
58
58
|
let ptr = Memory.malloc(16n)
|
|
59
59
|
WasmI32.store(ptr, Tags._GRAIN_BOXED_NUM_HEAP_TAG, 0n)
|
|
60
60
|
WasmI32.store(ptr, Tags._GRAIN_FLOAT64_BOXED_NUM_TAG, 4n)
|
|
61
61
|
WasmF64.store(ptr, n, 8n)
|
|
62
62
|
|
|
63
|
-
WasmI32.toGrain(ptr)
|
|
63
|
+
WasmI32.toGrain(ptr): Float64
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
@disableGC
|
|
@@ -101,13 +101,13 @@ export let wasmI32ToNumber = (n: WasmI32) => {
|
|
|
101
101
|
// Just test if the untagged number is the same. If it didn't overflow, then
|
|
102
102
|
// we're good. We just need to cast the raw value into a Number at the type
|
|
103
103
|
// system level.
|
|
104
|
-
WasmI32.toGrain(simple):
|
|
104
|
+
WasmI32.toGrain(simple): Number
|
|
105
105
|
} else {
|
|
106
106
|
// If it did overflow, then the value differs and we need to discard it and
|
|
107
107
|
// allocate the number on the heap. A boxed 32 bit number actually is the
|
|
108
108
|
// same thing as an Int32. It only needs to be cast into Number.
|
|
109
109
|
let asInt32 = toInt32(n)
|
|
110
|
-
WasmI32.toGrain(WasmI32.fromGrain(asInt32)):
|
|
110
|
+
WasmI32.toGrain(WasmI32.fromGrain(asInt32)): Number
|
|
111
111
|
}
|
|
112
112
|
result
|
|
113
113
|
}
|
package/runtime/unsafe/memory.gr
CHANGED
|
@@ -1,13 +1,20 @@
|
|
|
1
1
|
/* grainc-flags --compilation-mode=runtime */
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
malloc,
|
|
5
|
+
free,
|
|
6
|
+
incRef,
|
|
7
|
+
decRef,
|
|
8
|
+
utoa32Buffered,
|
|
9
|
+
decimalCount32,
|
|
10
|
+
} from "runtime/gc"
|
|
4
11
|
import WasmI32, {
|
|
5
12
|
add as (+),
|
|
6
13
|
sub as (-),
|
|
7
14
|
shl as (<<),
|
|
8
15
|
eq as (==),
|
|
9
16
|
ne as (!=),
|
|
10
|
-
ltU as (<)
|
|
17
|
+
ltU as (<),
|
|
11
18
|
} from "runtime/unsafe/wasmi32"
|
|
12
19
|
|
|
13
20
|
export malloc
|
|
@@ -48,4 +55,8 @@ export let fill = (dest, c, n) => {
|
|
|
48
55
|
}
|
|
49
56
|
}
|
|
50
57
|
|
|
51
|
-
export primitive compare: (
|
|
58
|
+
export primitive compare: (
|
|
59
|
+
WasmI32,
|
|
60
|
+
WasmI32,
|
|
61
|
+
WasmI32,
|
|
62
|
+
) -> WasmI32 = "@wasm.memory_compare"
|
|
@@ -5,7 +5,7 @@ import Memory from "runtime/unsafe/memory"
|
|
|
5
5
|
// [FIXME] These all leak ATM (grain-lang/grain#791)
|
|
6
6
|
|
|
7
7
|
@disableGC
|
|
8
|
-
export let printI32 =
|
|
8
|
+
export let printI32 = val => {
|
|
9
9
|
Memory.incRef(WasmI32.fromGrain(print))
|
|
10
10
|
Memory.incRef(WasmI32.fromGrain(toString))
|
|
11
11
|
let conv = Conv.toInt32(val)
|
|
@@ -23,7 +23,7 @@ export let printI32 = (val) => {
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
@disableGC
|
|
26
|
-
export let printI64 =
|
|
26
|
+
export let printI64 = val => {
|
|
27
27
|
Memory.incRef(WasmI32.fromGrain(print))
|
|
28
28
|
Memory.incRef(WasmI32.fromGrain(toString))
|
|
29
29
|
let conv = Conv.toInt64(val)
|
|
@@ -41,7 +41,7 @@ export let printI64 = (val) => {
|
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
@disableGC
|
|
44
|
-
export let printF32 =
|
|
44
|
+
export let printF32 = val => {
|
|
45
45
|
Memory.incRef(WasmI32.fromGrain(print))
|
|
46
46
|
Memory.incRef(WasmI32.fromGrain(toString))
|
|
47
47
|
let conv = Conv.toFloat32(val)
|
|
@@ -59,7 +59,7 @@ export let printF32 = (val) => {
|
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
@disableGC
|
|
62
|
-
export let printF64 =
|
|
62
|
+
export let printF64 = val => {
|
|
63
63
|
Memory.incRef(WasmI32.fromGrain(print))
|
|
64
64
|
Memory.incRef(WasmI32.fromGrain(toString))
|
|
65
65
|
let conv = Conv.toFloat64(val)
|
package/runtime/unsafe/tags.gr
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* grainc-flags --compilation-mode=runtime */
|
|
2
2
|
|
|
3
|
-
export let _GRAIN_NUMBER_TAG_TYPE
|
|
4
|
-
export let _GRAIN_CONST_TAG_TYPE
|
|
3
|
+
export let _GRAIN_NUMBER_TAG_TYPE = 0b0001n
|
|
4
|
+
export let _GRAIN_CONST_TAG_TYPE = 0b0110n
|
|
5
5
|
export let _GRAIN_GENERIC_HEAP_TAG_TYPE = 0b0000n
|
|
6
6
|
|
|
7
7
|
export let _GRAIN_NUMBER_TAG_MASK = 0b0001n
|
|
@@ -2,7 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
// WebAssembly Memory Instructions
|
|
4
4
|
export primitive load: (WasmI32, WasmI32) -> WasmF32 = "@wasm.load_float32"
|
|
5
|
-
export primitive store: (
|
|
5
|
+
export primitive store: (
|
|
6
|
+
WasmI32,
|
|
7
|
+
WasmF32,
|
|
8
|
+
WasmI32,
|
|
9
|
+
) -> Void = "@wasm.store_float32"
|
|
6
10
|
|
|
7
11
|
// WebAssembly Unary Instructions
|
|
8
12
|
export primitive neg: WasmF32 -> WasmF32 = "@wasm.neg_float32"
|
|
@@ -18,7 +22,10 @@ export primitive add: (WasmF32, WasmF32) -> WasmF32 = "@wasm.add_float32"
|
|
|
18
22
|
export primitive sub: (WasmF32, WasmF32) -> WasmF32 = "@wasm.sub_float32"
|
|
19
23
|
export primitive mul: (WasmF32, WasmF32) -> WasmF32 = "@wasm.mul_float32"
|
|
20
24
|
export primitive div: (WasmF32, WasmF32) -> WasmF32 = "@wasm.div_float32"
|
|
21
|
-
export primitive copySign: (
|
|
25
|
+
export primitive copySign: (
|
|
26
|
+
WasmF32,
|
|
27
|
+
WasmF32,
|
|
28
|
+
) -> WasmF32 = "@wasm.copy_sign_float32"
|
|
22
29
|
export primitive min: (WasmF32, WasmF32) -> WasmF32 = "@wasm.min_float32"
|
|
23
30
|
export primitive max: (WasmF32, WasmF32) -> WasmF32 = "@wasm.max_float32"
|
|
24
31
|
export primitive eq: (WasmF32, WasmF32) -> Bool = "@wasm.eq_float32"
|
|
@@ -2,7 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
// WebAssembly Memory Instructions
|
|
4
4
|
export primitive load: (WasmI32, WasmI32) -> WasmF64 = "@wasm.load_float64"
|
|
5
|
-
export primitive store: (
|
|
5
|
+
export primitive store: (
|
|
6
|
+
WasmI32,
|
|
7
|
+
WasmF64,
|
|
8
|
+
WasmI32,
|
|
9
|
+
) -> Void = "@wasm.store_float64"
|
|
6
10
|
|
|
7
11
|
// WebAssembly Unary Instructions
|
|
8
12
|
export primitive neg: WasmF64 -> WasmF64 = "@wasm.neg_float64"
|
|
@@ -18,7 +22,10 @@ export primitive add: (WasmF64, WasmF64) -> WasmF64 = "@wasm.add_float64"
|
|
|
18
22
|
export primitive sub: (WasmF64, WasmF64) -> WasmF64 = "@wasm.sub_float64"
|
|
19
23
|
export primitive mul: (WasmF64, WasmF64) -> WasmF64 = "@wasm.mul_float64"
|
|
20
24
|
export primitive div: (WasmF64, WasmF64) -> WasmF64 = "@wasm.div_float64"
|
|
21
|
-
export primitive copySign: (
|
|
25
|
+
export primitive copySign: (
|
|
26
|
+
WasmF64,
|
|
27
|
+
WasmF64,
|
|
28
|
+
) -> WasmF64 = "@wasm.copy_sign_float64"
|
|
22
29
|
export primitive min: (WasmF64, WasmF64) -> WasmF64 = "@wasm.min_float64"
|
|
23
30
|
export primitive max: (WasmF64, WasmF64) -> WasmF64 = "@wasm.max_float64"
|
|
24
31
|
export primitive eq: (WasmF64, WasmF64) -> Bool = "@wasm.eq_float64"
|
|
@@ -1,58 +1,76 @@
|
|
|
1
1
|
/* grainc-flags --compilation-mode=runtime */
|
|
2
2
|
|
|
3
3
|
// WebAssembly Memory Instructions
|
|
4
|
-
export primitive load
|
|
5
|
-
export primitive load8S
|
|
6
|
-
export primitive load8U
|
|
7
|
-
export primitive load16S
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
export primitive
|
|
4
|
+
export primitive load: (WasmI32, WasmI32) -> WasmI32 = "@wasm.load_int32"
|
|
5
|
+
export primitive load8S: (WasmI32, WasmI32) -> WasmI32 = "@wasm.load_8_s_int32"
|
|
6
|
+
export primitive load8U: (WasmI32, WasmI32) -> WasmI32 = "@wasm.load_8_u_int32"
|
|
7
|
+
export primitive load16S: (
|
|
8
|
+
WasmI32,
|
|
9
|
+
WasmI32,
|
|
10
|
+
) -> WasmI32 = "@wasm.load_16_s_int32"
|
|
11
|
+
export primitive load16U: (
|
|
12
|
+
WasmI32,
|
|
13
|
+
WasmI32,
|
|
14
|
+
) -> WasmI32 = "@wasm.load_16_u_int32"
|
|
15
|
+
export primitive store: (
|
|
16
|
+
WasmI32,
|
|
17
|
+
WasmI32,
|
|
18
|
+
WasmI32,
|
|
19
|
+
) -> Void = "@wasm.store_int32"
|
|
20
|
+
export primitive store8: (
|
|
21
|
+
WasmI32,
|
|
22
|
+
WasmI32,
|
|
23
|
+
WasmI32,
|
|
24
|
+
) -> Void = "@wasm.store_8_int32"
|
|
25
|
+
export primitive store16: (
|
|
26
|
+
WasmI32,
|
|
27
|
+
WasmI32,
|
|
28
|
+
WasmI32,
|
|
29
|
+
) -> Void = "@wasm.store_16_int32"
|
|
12
30
|
|
|
13
31
|
// WebAssembly Unary Instructions
|
|
14
|
-
export primitive clz
|
|
15
|
-
export primitive ctz
|
|
16
|
-
export primitive popcnt
|
|
17
|
-
export primitive eqz
|
|
32
|
+
export primitive clz: WasmI32 -> WasmI32 = "@wasm.clz_int32"
|
|
33
|
+
export primitive ctz: WasmI32 -> WasmI32 = "@wasm.ctz_int32"
|
|
34
|
+
export primitive popcnt: WasmI32 -> WasmI32 = "@wasm.popcnt_int32"
|
|
35
|
+
export primitive eqz: WasmI32 -> Bool = "@wasm.eq_z_int32"
|
|
18
36
|
|
|
19
37
|
// WebAssembly Binary Instructions
|
|
20
|
-
export primitive add
|
|
21
|
-
export primitive sub
|
|
22
|
-
export primitive mul
|
|
23
|
-
export primitive divS
|
|
24
|
-
export primitive divU
|
|
25
|
-
export primitive remS
|
|
26
|
-
export primitive remU
|
|
27
|
-
export primitive and
|
|
28
|
-
export primitive or
|
|
29
|
-
export primitive xor
|
|
30
|
-
export primitive shl
|
|
31
|
-
export primitive shrS
|
|
32
|
-
export primitive shrU
|
|
33
|
-
export primitive rotl
|
|
34
|
-
export primitive rotr
|
|
35
|
-
export primitive eq
|
|
36
|
-
export primitive ne
|
|
37
|
-
export primitive ltS
|
|
38
|
-
export primitive ltU
|
|
39
|
-
export primitive leS
|
|
40
|
-
export primitive leU
|
|
41
|
-
export primitive gtS
|
|
42
|
-
export primitive gtU
|
|
43
|
-
export primitive geS
|
|
44
|
-
export primitive geU
|
|
38
|
+
export primitive add: (WasmI32, WasmI32) -> WasmI32 = "@wasm.add_int32"
|
|
39
|
+
export primitive sub: (WasmI32, WasmI32) -> WasmI32 = "@wasm.sub_int32"
|
|
40
|
+
export primitive mul: (WasmI32, WasmI32) -> WasmI32 = "@wasm.mul_int32"
|
|
41
|
+
export primitive divS: (WasmI32, WasmI32) -> WasmI32 = "@wasm.div_s_int32"
|
|
42
|
+
export primitive divU: (WasmI32, WasmI32) -> WasmI32 = "@wasm.div_u_int32"
|
|
43
|
+
export primitive remS: (WasmI32, WasmI32) -> WasmI32 = "@wasm.rem_s_int32"
|
|
44
|
+
export primitive remU: (WasmI32, WasmI32) -> WasmI32 = "@wasm.rem_u_int32"
|
|
45
|
+
export primitive and: (WasmI32, WasmI32) -> WasmI32 = "@wasm.and_int32"
|
|
46
|
+
export primitive or: (WasmI32, WasmI32) -> WasmI32 = "@wasm.or_int32"
|
|
47
|
+
export primitive xor: (WasmI32, WasmI32) -> WasmI32 = "@wasm.xor_int32"
|
|
48
|
+
export primitive shl: (WasmI32, WasmI32) -> WasmI32 = "@wasm.shl_int32"
|
|
49
|
+
export primitive shrS: (WasmI32, WasmI32) -> WasmI32 = "@wasm.shr_s_int32"
|
|
50
|
+
export primitive shrU: (WasmI32, WasmI32) -> WasmI32 = "@wasm.shr_u_int32"
|
|
51
|
+
export primitive rotl: (WasmI32, WasmI32) -> WasmI32 = "@wasm.rot_l_int32"
|
|
52
|
+
export primitive rotr: (WasmI32, WasmI32) -> WasmI32 = "@wasm.rot_r_int32"
|
|
53
|
+
export primitive eq: (WasmI32, WasmI32) -> Bool = "@wasm.eq_int32"
|
|
54
|
+
export primitive ne: (WasmI32, WasmI32) -> Bool = "@wasm.ne_int32"
|
|
55
|
+
export primitive ltS: (WasmI32, WasmI32) -> Bool = "@wasm.lt_s_int32"
|
|
56
|
+
export primitive ltU: (WasmI32, WasmI32) -> Bool = "@wasm.lt_u_int32"
|
|
57
|
+
export primitive leS: (WasmI32, WasmI32) -> Bool = "@wasm.le_s_int32"
|
|
58
|
+
export primitive leU: (WasmI32, WasmI32) -> Bool = "@wasm.le_u_int32"
|
|
59
|
+
export primitive gtS: (WasmI32, WasmI32) -> Bool = "@wasm.gt_s_int32"
|
|
60
|
+
export primitive gtU: (WasmI32, WasmI32) -> Bool = "@wasm.gt_u_int32"
|
|
61
|
+
export primitive geS: (WasmI32, WasmI32) -> Bool = "@wasm.ge_s_int32"
|
|
62
|
+
export primitive geU: (WasmI32, WasmI32) -> Bool = "@wasm.ge_u_int32"
|
|
45
63
|
|
|
46
64
|
// WebAssembly Conversion Instructions
|
|
47
|
-
export primitive wrapI64
|
|
48
|
-
export primitive truncF32S
|
|
49
|
-
export primitive truncF32U
|
|
50
|
-
export primitive truncF64S
|
|
51
|
-
export primitive truncF64U
|
|
52
|
-
export primitive reinterpretF32
|
|
53
|
-
export primitive extendS8
|
|
54
|
-
export primitive extendS16
|
|
65
|
+
export primitive wrapI64: WasmI64 -> WasmI32 = "@wasm.wrap_int64"
|
|
66
|
+
export primitive truncF32S: WasmF32 -> WasmI32 = "@wasm.trunc_s_float32_to_int32"
|
|
67
|
+
export primitive truncF32U: WasmF32 -> WasmI32 = "@wasm.trunc_u_float32_to_int32"
|
|
68
|
+
export primitive truncF64S: WasmF64 -> WasmI32 = "@wasm.trunc_s_float64_to_int32"
|
|
69
|
+
export primitive truncF64U: WasmF64 -> WasmI32 = "@wasm.trunc_u_float64_to_int32"
|
|
70
|
+
export primitive reinterpretF32: WasmF32 -> WasmI32 = "@wasm.reinterpret_float32"
|
|
71
|
+
export primitive extendS8: WasmI32 -> WasmI32 = "@wasm.extend_s8_int32"
|
|
72
|
+
export primitive extendS16: WasmI32 -> WasmI32 = "@wasm.extend_s16_int32"
|
|
55
73
|
|
|
56
74
|
// Grain Conversions
|
|
57
|
-
export primitive fromGrain
|
|
58
|
-
export primitive toGrain
|
|
75
|
+
export primitive fromGrain: a -> WasmI32 = "@wasm.fromGrain"
|
|
76
|
+
export primitive toGrain: WasmI32 -> a = "@wasm.toGrain"
|