@grain/stdlib 0.5.13 → 0.6.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.
- package/CHANGELOG.md +201 -0
- package/LICENSE +1 -1
- package/README.md +25 -2
- package/array.gr +1512 -199
- package/array.md +2032 -94
- package/bigint.gr +239 -140
- package/bigint.md +450 -106
- package/buffer.gr +595 -102
- package/buffer.md +903 -145
- package/bytes.gr +401 -110
- package/bytes.md +551 -63
- package/char.gr +228 -49
- package/char.md +373 -7
- package/exception.gr +26 -12
- package/exception.md +29 -5
- package/float32.gr +130 -109
- package/float32.md +185 -57
- package/float64.gr +112 -99
- package/float64.md +185 -57
- package/hash.gr +62 -40
- package/hash.md +27 -3
- package/int16.gr +430 -0
- package/int16.md +618 -0
- package/int32.gr +200 -269
- package/int32.md +254 -289
- package/int64.gr +142 -225
- package/int64.md +254 -289
- package/int8.gr +511 -0
- package/int8.md +786 -0
- package/json.gr +2071 -0
- package/json.md +646 -0
- package/list.gr +120 -68
- package/list.md +125 -80
- package/map.gr +560 -57
- package/map.md +672 -56
- package/marshal.gr +239 -227
- package/marshal.md +36 -4
- package/number.gr +626 -676
- package/number.md +738 -153
- package/option.gr +33 -35
- package/option.md +58 -42
- package/package.json +2 -2
- package/path.gr +148 -187
- package/path.md +47 -96
- package/pervasives.gr +75 -416
- package/pervasives.md +85 -180
- package/priorityqueue.gr +433 -74
- package/priorityqueue.md +422 -54
- package/queue.gr +362 -80
- package/queue.md +433 -38
- package/random.gr +67 -75
- package/random.md +68 -40
- package/range.gr +135 -63
- package/range.md +198 -43
- package/rational.gr +284 -0
- package/rational.md +545 -0
- package/regex.gr +933 -1066
- package/regex.md +59 -60
- package/result.gr +23 -25
- package/result.md +54 -39
- package/runtime/atof/common.gr +78 -82
- package/runtime/atof/common.md +22 -10
- package/runtime/atof/decimal.gr +102 -127
- package/runtime/atof/decimal.md +28 -7
- package/runtime/atof/lemire.gr +56 -71
- package/runtime/atof/lemire.md +9 -1
- package/runtime/atof/parse.gr +83 -110
- package/runtime/atof/parse.md +12 -2
- package/runtime/atof/slow.gr +28 -35
- package/runtime/atof/slow.md +9 -1
- package/runtime/atof/table.gr +19 -18
- package/runtime/atof/table.md +10 -2
- package/runtime/atoi/parse.gr +153 -136
- package/runtime/atoi/parse.md +50 -1
- package/runtime/bigint.gr +410 -517
- package/runtime/bigint.md +71 -57
- package/runtime/compare.gr +176 -85
- package/runtime/compare.md +31 -1
- package/runtime/dataStructures.gr +144 -32
- package/runtime/dataStructures.md +267 -31
- package/runtime/debugPrint.gr +34 -15
- package/runtime/debugPrint.md +37 -5
- package/runtime/equal.gr +53 -52
- package/runtime/equal.md +30 -1
- package/runtime/exception.gr +38 -47
- package/runtime/exception.md +10 -8
- package/runtime/gc.gr +23 -152
- package/runtime/gc.md +13 -17
- package/runtime/malloc.gr +31 -31
- package/runtime/malloc.md +11 -3
- package/runtime/numberUtils.gr +193 -174
- package/runtime/numberUtils.md +29 -9
- package/runtime/numbers.gr +1695 -1021
- package/runtime/numbers.md +1098 -134
- package/runtime/string.gr +543 -245
- package/runtime/string.md +76 -6
- package/runtime/unsafe/constants.gr +30 -13
- package/runtime/unsafe/constants.md +80 -0
- package/runtime/unsafe/conv.gr +55 -28
- package/runtime/unsafe/conv.md +41 -9
- package/runtime/unsafe/memory.gr +10 -30
- package/runtime/unsafe/memory.md +15 -19
- package/runtime/unsafe/tags.gr +37 -21
- package/runtime/unsafe/tags.md +88 -8
- package/runtime/unsafe/wasmf32.gr +30 -36
- package/runtime/unsafe/wasmf32.md +64 -56
- package/runtime/unsafe/wasmf64.gr +30 -36
- package/runtime/unsafe/wasmf64.md +64 -56
- package/runtime/unsafe/wasmi32.gr +49 -66
- package/runtime/unsafe/wasmi32.md +102 -94
- package/runtime/unsafe/wasmi64.gr +52 -79
- package/runtime/unsafe/wasmi64.md +108 -100
- package/runtime/utils/printing.gr +13 -15
- package/runtime/utils/printing.md +11 -3
- package/runtime/wasi.gr +294 -295
- package/runtime/wasi.md +62 -42
- package/set.gr +574 -64
- package/set.md +634 -54
- package/stack.gr +181 -64
- package/stack.md +271 -42
- package/string.gr +453 -533
- package/string.md +241 -151
- package/uint16.gr +369 -0
- package/uint16.md +585 -0
- package/uint32.gr +470 -0
- package/uint32.md +737 -0
- package/uint64.gr +471 -0
- package/uint64.md +737 -0
- package/uint8.gr +369 -0
- package/uint8.md +585 -0
- package/uri.gr +1093 -0
- package/uri.md +477 -0
- package/{sys → wasi}/file.gr +914 -500
- package/{sys → wasi}/file.md +454 -50
- package/wasi/process.gr +292 -0
- package/{sys → wasi}/process.md +164 -6
- package/wasi/random.gr +77 -0
- package/wasi/random.md +80 -0
- package/{sys → wasi}/time.gr +15 -22
- package/{sys → wasi}/time.md +5 -5
- package/immutablearray.gr +0 -929
- package/immutablearray.md +0 -1038
- package/immutablemap.gr +0 -493
- package/immutablemap.md +0 -479
- package/immutablepriorityqueue.gr +0 -360
- package/immutablepriorityqueue.md +0 -291
- package/immutableset.gr +0 -498
- package/immutableset.md +0 -449
- package/runtime/debug.gr +0 -2
- package/runtime/debug.md +0 -6
- package/runtime/unsafe/errors.gr +0 -36
- package/runtime/unsafe/errors.md +0 -204
- package/sys/process.gr +0 -254
- package/sys/random.gr +0 -79
- package/sys/random.md +0 -66
package/marshal.gr
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Utilities for serializing and deserializing Grain data.
|
|
3
3
|
*
|
|
4
|
-
* @example
|
|
4
|
+
* @example from "marshal" include Marshal
|
|
5
|
+
*
|
|
6
|
+
* @example Marshal.marshal(1)
|
|
7
|
+
* @example Marshal.marshal("Hello World")
|
|
8
|
+
* @example Marshal.unmarshal(b"\x03\x00\x00\x00")
|
|
5
9
|
*
|
|
6
10
|
* @since v0.5.3
|
|
7
11
|
*/
|
|
12
|
+
module Marshal
|
|
8
13
|
|
|
9
14
|
/*
|
|
10
15
|
SERIALIZED BINARY FORMAT
|
|
@@ -20,16 +25,13 @@
|
|
|
20
25
|
or a "pointer" to a heap-allocated value.
|
|
21
26
|
*/
|
|
22
27
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
and as (&),
|
|
31
|
-
eq as (==),
|
|
32
|
-
ne as (!=),
|
|
28
|
+
from "runtime/unsafe/wasmi32" include WasmI32
|
|
29
|
+
use WasmI32.{
|
|
30
|
+
(+),
|
|
31
|
+
(*),
|
|
32
|
+
(&),
|
|
33
|
+
(==),
|
|
34
|
+
(!=),
|
|
33
35
|
gtU as (>),
|
|
34
36
|
ltU as (<),
|
|
35
37
|
leU as (<=),
|
|
@@ -37,14 +39,14 @@ import WasmI32, {
|
|
|
37
39
|
store,
|
|
38
40
|
fromGrain,
|
|
39
41
|
toGrain,
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
42
|
+
}
|
|
43
|
+
from "runtime/unsafe/wasmi64" include WasmI64
|
|
44
|
+
from "runtime/unsafe/memory" include Memory
|
|
45
|
+
from "runtime/unsafe/tags" include Tags
|
|
46
|
+
from "runtime/dataStructures" include DataStructures
|
|
47
|
+
use DataStructures.{ allocateBytes, newInt32 }
|
|
48
|
+
from "map" include Map
|
|
49
|
+
from "set" include Set
|
|
48
50
|
|
|
49
51
|
@unsafe
|
|
50
52
|
let roundTo8 = n => {
|
|
@@ -53,8 +55,7 @@ let roundTo8 = n => {
|
|
|
53
55
|
|
|
54
56
|
@unsafe
|
|
55
57
|
let isHeapPtr = value =>
|
|
56
|
-
(value & Tags._GRAIN_GENERIC_TAG_MASK) ==
|
|
57
|
-
Tags._GRAIN_GENERIC_HEAP_TAG_TYPE
|
|
58
|
+
(value & Tags._GRAIN_GENERIC_TAG_MASK) == Tags._GRAIN_GENERIC_HEAP_TAG_TYPE
|
|
58
59
|
|
|
59
60
|
@unsafe
|
|
60
61
|
let rec size = (value, acc, valuesSeen, toplevel) => {
|
|
@@ -74,9 +75,8 @@ let rec size = (value, acc, valuesSeen, toplevel) => {
|
|
|
74
75
|
}
|
|
75
76
|
let heapPtr = value
|
|
76
77
|
match (load(heapPtr, 0n)) {
|
|
77
|
-
t when
|
|
78
|
-
t == Tags.
|
|
79
|
-
) => {
|
|
78
|
+
t when t == Tags._GRAIN_STRING_HEAP_TAG ||
|
|
79
|
+
t == Tags._GRAIN_BYTES_HEAP_TAG => {
|
|
80
80
|
acc + roundTo8(8n + load(heapPtr, 4n))
|
|
81
81
|
},
|
|
82
82
|
t when t == Tags._GRAIN_ADT_HEAP_TAG => {
|
|
@@ -142,14 +142,8 @@ let rec size = (value, acc, valuesSeen, toplevel) => {
|
|
|
142
142
|
t when t == Tags._GRAIN_BOXED_NUM_HEAP_TAG => {
|
|
143
143
|
let tag = load(heapPtr, 4n)
|
|
144
144
|
match (tag) {
|
|
145
|
-
t when
|
|
146
|
-
t == Tags.
|
|
147
|
-
t == Tags._GRAIN_INT64_BOXED_NUM_TAG ||
|
|
148
|
-
t == Tags._GRAIN_FLOAT32_BOXED_NUM_TAG ||
|
|
149
|
-
t == Tags._GRAIN_FLOAT64_BOXED_NUM_TAG
|
|
150
|
-
) => {
|
|
151
|
-
// The 32-bit values only take 12 bytes of memory, but we report 16
|
|
152
|
-
// for alignment
|
|
145
|
+
t when t == Tags._GRAIN_INT64_BOXED_NUM_TAG ||
|
|
146
|
+
t == Tags._GRAIN_FLOAT64_BOXED_NUM_TAG => {
|
|
153
147
|
acc + 16n
|
|
154
148
|
},
|
|
155
149
|
t when t == Tags._GRAIN_BIGINT_BOXED_NUM_TAG => {
|
|
@@ -166,6 +160,15 @@ let rec size = (value, acc, valuesSeen, toplevel) => {
|
|
|
166
160
|
},
|
|
167
161
|
}
|
|
168
162
|
},
|
|
163
|
+
t when t == Tags._GRAIN_INT32_HEAP_TAG ||
|
|
164
|
+
t == Tags._GRAIN_FLOAT32_HEAP_TAG ||
|
|
165
|
+
t == Tags._GRAIN_UINT32_HEAP_TAG => {
|
|
166
|
+
acc + 8n
|
|
167
|
+
},
|
|
168
|
+
t when t == Tags._GRAIN_UINT64_HEAP_TAG => {
|
|
169
|
+
// 16 for alignment
|
|
170
|
+
acc + 16n
|
|
171
|
+
},
|
|
169
172
|
_ => {
|
|
170
173
|
fail "Unknown heap type"
|
|
171
174
|
},
|
|
@@ -193,9 +196,7 @@ let rec marshalHeap = (heapPtr, buf, offset, valuesSeen) => {
|
|
|
193
196
|
Map.set(asInt32, offsetAsInt32, valuesSeen)
|
|
194
197
|
|
|
195
198
|
match (load(heapPtr, 0n)) {
|
|
196
|
-
t when
|
|
197
|
-
t == Tags._GRAIN_STRING_HEAP_TAG || t == Tags._GRAIN_BYTES_HEAP_TAG
|
|
198
|
-
) => {
|
|
199
|
+
t when t == Tags._GRAIN_STRING_HEAP_TAG || t == Tags._GRAIN_BYTES_HEAP_TAG => {
|
|
199
200
|
let size = 8n + load(heapPtr, 4n)
|
|
200
201
|
Memory.copy(buf + offset, heapPtr, size)
|
|
201
202
|
roundTo8(offset + size)
|
|
@@ -214,7 +215,7 @@ let rec marshalHeap = (heapPtr, buf, offset, valuesSeen) => {
|
|
|
214
215
|
let asInt32 = toGrain(newInt32(value)): Int32
|
|
215
216
|
match (Map.get(asInt32, valuesSeen)) {
|
|
216
217
|
Some(value) => {
|
|
217
|
-
let ptr = load(fromGrain(value),
|
|
218
|
+
let ptr = load(fromGrain(value), 4n)
|
|
218
219
|
store(buf, ptr, offset + i + 20n)
|
|
219
220
|
},
|
|
220
221
|
None => {
|
|
@@ -243,7 +244,7 @@ let rec marshalHeap = (heapPtr, buf, offset, valuesSeen) => {
|
|
|
243
244
|
let asInt32 = toGrain(newInt32(value)): Int32
|
|
244
245
|
match (Map.get(asInt32, valuesSeen)) {
|
|
245
246
|
Some(value) => {
|
|
246
|
-
let ptr = load(fromGrain(value),
|
|
247
|
+
let ptr = load(fromGrain(value), 4n)
|
|
247
248
|
store(buf, ptr, offset + i + 16n)
|
|
248
249
|
},
|
|
249
250
|
None => {
|
|
@@ -272,7 +273,7 @@ let rec marshalHeap = (heapPtr, buf, offset, valuesSeen) => {
|
|
|
272
273
|
let asInt32 = toGrain(newInt32(value)): Int32
|
|
273
274
|
match (Map.get(asInt32, valuesSeen)) {
|
|
274
275
|
Some(value) => {
|
|
275
|
-
let ptr = load(fromGrain(value),
|
|
276
|
+
let ptr = load(fromGrain(value), 4n)
|
|
276
277
|
store(buf, ptr, offset + i + 8n)
|
|
277
278
|
},
|
|
278
279
|
None => {
|
|
@@ -301,7 +302,7 @@ let rec marshalHeap = (heapPtr, buf, offset, valuesSeen) => {
|
|
|
301
302
|
let asInt32 = toGrain(newInt32(value)): Int32
|
|
302
303
|
match (Map.get(asInt32, valuesSeen)) {
|
|
303
304
|
Some(value) => {
|
|
304
|
-
let ptr = load(fromGrain(value),
|
|
305
|
+
let ptr = load(fromGrain(value), 4n)
|
|
305
306
|
store(buf, ptr, offset + i + 8n)
|
|
306
307
|
},
|
|
307
308
|
None => {
|
|
@@ -330,7 +331,7 @@ let rec marshalHeap = (heapPtr, buf, offset, valuesSeen) => {
|
|
|
330
331
|
let asInt32 = toGrain(newInt32(value)): Int32
|
|
331
332
|
match (Map.get(asInt32, valuesSeen)) {
|
|
332
333
|
Some(value) => {
|
|
333
|
-
let ptr = load(fromGrain(value),
|
|
334
|
+
let ptr = load(fromGrain(value), 4n)
|
|
334
335
|
store(buf, ptr, offset + i + 16n)
|
|
335
336
|
},
|
|
336
337
|
None => {
|
|
@@ -348,10 +349,6 @@ let rec marshalHeap = (heapPtr, buf, offset, valuesSeen) => {
|
|
|
348
349
|
t when t == Tags._GRAIN_BOXED_NUM_HEAP_TAG => {
|
|
349
350
|
let tag = load(heapPtr, 4n)
|
|
350
351
|
match (tag) {
|
|
351
|
-
t when t == Tags._GRAIN_INT32_BOXED_NUM_TAG => {
|
|
352
|
-
Memory.copy(buf + offset, heapPtr, 12n)
|
|
353
|
-
offset + 16n
|
|
354
|
-
},
|
|
355
352
|
t when t == Tags._GRAIN_INT64_BOXED_NUM_TAG => {
|
|
356
353
|
Memory.copy(buf + offset, heapPtr, 16n)
|
|
357
354
|
offset + 16n
|
|
@@ -361,26 +358,22 @@ let rec marshalHeap = (heapPtr, buf, offset, valuesSeen) => {
|
|
|
361
358
|
Memory.copy(buf + offset, heapPtr, size)
|
|
362
359
|
offset + size
|
|
363
360
|
},
|
|
364
|
-
t when t == Tags._GRAIN_FLOAT32_BOXED_NUM_TAG => {
|
|
365
|
-
Memory.copy(buf + offset, heapPtr, 12n)
|
|
366
|
-
offset + 16n
|
|
367
|
-
},
|
|
368
361
|
t when t == Tags._GRAIN_FLOAT64_BOXED_NUM_TAG => {
|
|
369
362
|
Memory.copy(buf + offset, heapPtr, 16n)
|
|
370
363
|
offset + 16n
|
|
371
364
|
},
|
|
372
365
|
t when t == Tags._GRAIN_RATIONAL_BOXED_NUM_TAG => {
|
|
373
366
|
Memory.copy(buf + offset, heapPtr, 8n)
|
|
374
|
-
let
|
|
367
|
+
let payloadOffset = offset + 16n
|
|
375
368
|
store(buf, payloadOffset, offset + 8n)
|
|
376
|
-
payloadOffset = marshalHeap(
|
|
369
|
+
let payloadOffset = marshalHeap(
|
|
377
370
|
load(heapPtr, 8n),
|
|
378
371
|
buf,
|
|
379
372
|
payloadOffset,
|
|
380
373
|
valuesSeen
|
|
381
374
|
)
|
|
382
375
|
store(buf, payloadOffset, offset + 12n)
|
|
383
|
-
payloadOffset = marshalHeap(
|
|
376
|
+
let payloadOffset = marshalHeap(
|
|
384
377
|
load(heapPtr, 12n),
|
|
385
378
|
buf,
|
|
386
379
|
payloadOffset,
|
|
@@ -393,6 +386,16 @@ let rec marshalHeap = (heapPtr, buf, offset, valuesSeen) => {
|
|
|
393
386
|
},
|
|
394
387
|
}
|
|
395
388
|
},
|
|
389
|
+
t when t == Tags._GRAIN_INT32_HEAP_TAG ||
|
|
390
|
+
t == Tags._GRAIN_FLOAT32_HEAP_TAG ||
|
|
391
|
+
t == Tags._GRAIN_UINT32_HEAP_TAG => {
|
|
392
|
+
Memory.copy(buf + offset, heapPtr, 8n)
|
|
393
|
+
offset + 8n
|
|
394
|
+
},
|
|
395
|
+
t when t == Tags._GRAIN_UINT64_HEAP_TAG => {
|
|
396
|
+
Memory.copy(buf + offset, heapPtr, 16n)
|
|
397
|
+
offset + 16n
|
|
398
|
+
},
|
|
396
399
|
_ => {
|
|
397
400
|
fail "Unknown heap type"
|
|
398
401
|
},
|
|
@@ -419,13 +422,19 @@ let marshal = (value, buf) => {
|
|
|
419
422
|
* @param value: The value to serialize
|
|
420
423
|
* @returns A byte-based representation of the value
|
|
421
424
|
*
|
|
425
|
+
* @example Marshal.marshal(1) == b"\x03\x00\x00\x00"
|
|
426
|
+
* @example Marshal.marshal("🌾") == Marshal.marshal("🌾")
|
|
427
|
+
*
|
|
422
428
|
* @since v0.5.3
|
|
423
429
|
*/
|
|
424
430
|
@unsafe
|
|
425
|
-
|
|
431
|
+
provide let marshal = value => {
|
|
426
432
|
let valuePtr = fromGrain(value)
|
|
427
|
-
let
|
|
433
|
+
let size = size(valuePtr)
|
|
434
|
+
let buf = allocateBytes(size)
|
|
435
|
+
Memory.fill(buf + 8n, 0n, size)
|
|
428
436
|
marshal(valuePtr, buf + 8n)
|
|
437
|
+
ignore(value)
|
|
429
438
|
toGrain(buf): Bytes
|
|
430
439
|
}
|
|
431
440
|
|
|
@@ -440,13 +449,11 @@ let reportError = (message, offset) => {
|
|
|
440
449
|
@unsafe
|
|
441
450
|
let validateStack = (value, offset) => {
|
|
442
451
|
match (value) {
|
|
443
|
-
_ when (
|
|
444
|
-
value == fromGrain(true) ||
|
|
452
|
+
_ when value == fromGrain(true) ||
|
|
445
453
|
value == fromGrain(false) ||
|
|
446
454
|
value == fromGrain(void) ||
|
|
447
455
|
(value & Tags._GRAIN_NUMBER_TAG_MASK) == Tags._GRAIN_NUMBER_TAG_TYPE ||
|
|
448
|
-
(value & Tags._GRAIN_GENERIC_TAG_MASK) == Tags.
|
|
449
|
-
) =>
|
|
456
|
+
(value & Tags._GRAIN_GENERIC_TAG_MASK) == Tags._GRAIN_SHORTVAL_TAG_TYPE =>
|
|
450
457
|
None,
|
|
451
458
|
_ => reportError("Unknown value", offset),
|
|
452
459
|
}
|
|
@@ -459,276 +466,281 @@ let rec validateHeap = (buf, bufSize, offset, valuesChecked) => {
|
|
|
459
466
|
|
|
460
467
|
let valuePtr = buf + offset
|
|
461
468
|
match (load(valuePtr, 0n)) {
|
|
462
|
-
t when
|
|
463
|
-
t == Tags._GRAIN_STRING_HEAP_TAG || t == Tags._GRAIN_BYTES_HEAP_TAG
|
|
464
|
-
) => {
|
|
469
|
+
t when t == Tags._GRAIN_STRING_HEAP_TAG || t == Tags._GRAIN_BYTES_HEAP_TAG => {
|
|
465
470
|
let size = 8n + load(valuePtr, 4n)
|
|
466
471
|
if (offset + size > bufSize) {
|
|
467
|
-
reportError("String/Bytes length exceeds buffer size", offset)
|
|
468
|
-
} else {
|
|
469
|
-
None
|
|
472
|
+
return reportError("String/Bytes length exceeds buffer size", offset)
|
|
470
473
|
}
|
|
471
474
|
},
|
|
472
475
|
t when t == Tags._GRAIN_ADT_HEAP_TAG => {
|
|
473
476
|
let arity = load(valuePtr, 16n)
|
|
474
477
|
let size = 20n + arity * 4n
|
|
475
478
|
|
|
476
|
-
|
|
477
|
-
reportError("Enum payload size exceeds buffer size", offset)
|
|
478
|
-
} else {
|
|
479
|
-
None
|
|
479
|
+
if (offset + size > bufSize) {
|
|
480
|
+
return reportError("Enum payload size exceeds buffer size", offset)
|
|
480
481
|
}
|
|
481
482
|
|
|
482
483
|
let a = arity * 4n
|
|
483
484
|
for (let mut i = 0n; i < a; i += 4n) {
|
|
484
|
-
if (Option.isSome(error)) break
|
|
485
|
-
|
|
486
485
|
let value = load(valuePtr + i, 20n)
|
|
487
486
|
if (isHeapPtr(value)) {
|
|
488
487
|
let asInt32 = toGrain(newInt32(value)): Int32
|
|
489
488
|
if (Set.contains(asInt32, valuesChecked)) {
|
|
490
489
|
continue
|
|
491
490
|
}
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
491
|
+
match (validateHeap(buf, bufSize, value, valuesChecked)) {
|
|
492
|
+
Some(e) => return Some(e),
|
|
493
|
+
None => void,
|
|
494
|
+
}
|
|
496
495
|
} else {
|
|
497
|
-
|
|
496
|
+
match (validateStack(value, offset)) {
|
|
497
|
+
Some(e) => return Some(e),
|
|
498
|
+
None => void,
|
|
499
|
+
}
|
|
498
500
|
}
|
|
499
501
|
}
|
|
500
|
-
|
|
501
|
-
error
|
|
502
502
|
},
|
|
503
503
|
t when t == Tags._GRAIN_RECORD_HEAP_TAG => {
|
|
504
504
|
let arity = load(valuePtr, 12n)
|
|
505
505
|
let size = 16n + arity * 4n
|
|
506
506
|
|
|
507
|
-
|
|
508
|
-
reportError("Record payload size exceeds buffer size", offset)
|
|
509
|
-
} else {
|
|
510
|
-
None
|
|
507
|
+
if (offset + size > bufSize) {
|
|
508
|
+
return reportError("Record payload size exceeds buffer size", offset)
|
|
511
509
|
}
|
|
512
510
|
|
|
513
511
|
let a = arity * 4n
|
|
514
512
|
for (let mut i = 0n; i < a; i += 4n) {
|
|
515
|
-
if (Option.isSome(error)) break
|
|
516
|
-
|
|
517
513
|
let value = load(valuePtr + i, 16n)
|
|
518
514
|
if (isHeapPtr(value)) {
|
|
519
515
|
let asInt32 = toGrain(newInt32(value)): Int32
|
|
520
516
|
if (Set.contains(asInt32, valuesChecked)) {
|
|
521
517
|
continue
|
|
522
518
|
}
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
519
|
+
match (validateHeap(buf, bufSize, value, valuesChecked)) {
|
|
520
|
+
Some(e) => return Some(e),
|
|
521
|
+
None => void,
|
|
522
|
+
}
|
|
527
523
|
} else {
|
|
528
|
-
|
|
524
|
+
match (validateStack(value, offset)) {
|
|
525
|
+
Some(e) => return Some(e),
|
|
526
|
+
None => void,
|
|
527
|
+
}
|
|
529
528
|
}
|
|
530
529
|
}
|
|
531
|
-
|
|
532
|
-
error
|
|
533
530
|
},
|
|
534
531
|
t when t == Tags._GRAIN_ARRAY_HEAP_TAG => {
|
|
535
532
|
let arity = load(valuePtr, 4n)
|
|
536
533
|
let size = 8n + arity * 4n
|
|
537
534
|
|
|
538
|
-
|
|
539
|
-
reportError("Array payload size exceeds buffer size", offset)
|
|
540
|
-
} else {
|
|
541
|
-
None
|
|
535
|
+
if (offset + size > bufSize) {
|
|
536
|
+
return reportError("Array payload size exceeds buffer size", offset)
|
|
542
537
|
}
|
|
543
538
|
|
|
544
539
|
let a = arity * 4n
|
|
545
540
|
for (let mut i = 0n; i < a; i += 4n) {
|
|
546
|
-
if (Option.isSome(error)) break
|
|
547
|
-
|
|
548
541
|
let value = load(valuePtr + i, 8n)
|
|
549
542
|
if (isHeapPtr(value)) {
|
|
550
543
|
let asInt32 = toGrain(newInt32(value)): Int32
|
|
551
544
|
if (Set.contains(asInt32, valuesChecked)) {
|
|
552
545
|
continue
|
|
553
546
|
}
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
547
|
+
match (validateHeap(buf, bufSize, value, valuesChecked)) {
|
|
548
|
+
Some(e) => return Some(e),
|
|
549
|
+
None => void,
|
|
550
|
+
}
|
|
558
551
|
} else {
|
|
559
|
-
|
|
552
|
+
match (validateStack(value, offset)) {
|
|
553
|
+
Some(e) => return Some(e),
|
|
554
|
+
None => void,
|
|
555
|
+
}
|
|
560
556
|
}
|
|
561
557
|
}
|
|
562
|
-
|
|
563
|
-
error
|
|
564
558
|
},
|
|
565
559
|
t when t == Tags._GRAIN_TUPLE_HEAP_TAG => {
|
|
566
560
|
let arity = load(valuePtr, 4n)
|
|
567
561
|
let size = 8n + arity * 4n
|
|
568
562
|
|
|
569
|
-
|
|
570
|
-
reportError("Tuple payload size exceeds buffer size", offset)
|
|
571
|
-
} else {
|
|
572
|
-
None
|
|
563
|
+
if (offset + size > bufSize) {
|
|
564
|
+
return reportError("Tuple payload size exceeds buffer size", offset)
|
|
573
565
|
}
|
|
574
566
|
|
|
575
567
|
let a = arity * 4n
|
|
576
568
|
for (let mut i = 0n; i < a; i += 4n) {
|
|
577
|
-
if (Option.isSome(error)) break
|
|
578
|
-
|
|
579
569
|
let value = load(valuePtr + i, 8n)
|
|
580
570
|
if (isHeapPtr(value)) {
|
|
581
571
|
let asInt32 = toGrain(newInt32(value)): Int32
|
|
582
572
|
if (Set.contains(asInt32, valuesChecked)) {
|
|
583
573
|
continue
|
|
584
574
|
}
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
575
|
+
match (validateHeap(buf, bufSize, value, valuesChecked)) {
|
|
576
|
+
Some(e) => return Some(e),
|
|
577
|
+
None => void,
|
|
578
|
+
}
|
|
589
579
|
} else {
|
|
590
|
-
|
|
580
|
+
match (validateStack(value, offset)) {
|
|
581
|
+
Some(e) => return Some(e),
|
|
582
|
+
None => void,
|
|
583
|
+
}
|
|
591
584
|
}
|
|
592
585
|
}
|
|
593
|
-
|
|
594
|
-
error
|
|
595
586
|
},
|
|
596
587
|
t when t == Tags._GRAIN_LAMBDA_HEAP_TAG => {
|
|
597
588
|
let arity = load(valuePtr, 12n)
|
|
598
589
|
let size = 16n + arity * 4n
|
|
599
590
|
|
|
600
|
-
|
|
601
|
-
reportError("Closure payload size exceeds buffer size", offset)
|
|
602
|
-
} else {
|
|
603
|
-
None
|
|
591
|
+
if (offset + size > bufSize) {
|
|
592
|
+
return reportError("Closure payload size exceeds buffer size", offset)
|
|
604
593
|
}
|
|
605
594
|
|
|
606
595
|
let a = arity * 4n
|
|
607
596
|
for (let mut i = 0n; i < a; i += 4n) {
|
|
608
|
-
if (Option.isSome(error)) break
|
|
609
|
-
|
|
610
597
|
let value = load(valuePtr + i, 16n)
|
|
611
598
|
if (isHeapPtr(value)) {
|
|
612
599
|
let asInt32 = toGrain(newInt32(value)): Int32
|
|
613
600
|
if (Set.contains(asInt32, valuesChecked)) {
|
|
614
601
|
continue
|
|
615
602
|
}
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
603
|
+
match (validateHeap(buf, bufSize, value, valuesChecked)) {
|
|
604
|
+
Some(e) => return Some(e),
|
|
605
|
+
None => void,
|
|
606
|
+
}
|
|
620
607
|
} else {
|
|
621
|
-
|
|
608
|
+
match (validateStack(value, offset)) {
|
|
609
|
+
Some(e) => return Some(e),
|
|
610
|
+
None => void,
|
|
611
|
+
}
|
|
622
612
|
}
|
|
623
613
|
}
|
|
624
|
-
|
|
625
|
-
error
|
|
626
614
|
},
|
|
627
615
|
t when t == Tags._GRAIN_BOXED_NUM_HEAP_TAG => {
|
|
628
616
|
let tag = load(valuePtr, 4n)
|
|
629
617
|
match (tag) {
|
|
630
|
-
t when t == Tags._GRAIN_INT32_BOXED_NUM_TAG => {
|
|
631
|
-
if (offset + 12n > bufSize) {
|
|
632
|
-
reportError(
|
|
633
|
-
"Not enough bytes remaining in buffer for Int32/Number",
|
|
634
|
-
offset
|
|
635
|
-
)
|
|
636
|
-
} else {
|
|
637
|
-
None
|
|
638
|
-
}
|
|
639
|
-
},
|
|
640
618
|
t when t == Tags._GRAIN_INT64_BOXED_NUM_TAG => {
|
|
641
619
|
if (offset + 16n > bufSize) {
|
|
642
|
-
reportError(
|
|
620
|
+
return reportError(
|
|
643
621
|
"Not enough bytes remaining in buffer for Int64/Number",
|
|
644
622
|
offset
|
|
645
623
|
)
|
|
646
|
-
} else {
|
|
647
|
-
None
|
|
648
624
|
}
|
|
649
625
|
},
|
|
650
626
|
t when t == Tags._GRAIN_BIGINT_BOXED_NUM_TAG => {
|
|
651
627
|
let size = 16n + load(valuePtr, 8n) * 8n
|
|
652
628
|
if (offset + size > bufSize) {
|
|
653
|
-
reportError(
|
|
654
|
-
|
|
655
|
-
None
|
|
656
|
-
}
|
|
657
|
-
},
|
|
658
|
-
t when t == Tags._GRAIN_FLOAT32_BOXED_NUM_TAG => {
|
|
659
|
-
if (offset + 12n > bufSize) {
|
|
660
|
-
reportError(
|
|
661
|
-
"Not enough bytes remaining in buffer for Float32/Number",
|
|
629
|
+
return reportError(
|
|
630
|
+
"BigInt/Number payload size exeeds buffer size",
|
|
662
631
|
offset
|
|
663
632
|
)
|
|
664
|
-
} else {
|
|
665
|
-
None
|
|
666
633
|
}
|
|
667
634
|
},
|
|
668
635
|
t when t == Tags._GRAIN_FLOAT64_BOXED_NUM_TAG => {
|
|
669
636
|
if (offset + 16n > bufSize) {
|
|
670
|
-
reportError(
|
|
637
|
+
return reportError(
|
|
671
638
|
"Not enough bytes remaining in buffer for Float64/Number",
|
|
672
639
|
offset
|
|
673
640
|
)
|
|
674
|
-
} else {
|
|
675
|
-
None
|
|
676
641
|
}
|
|
677
642
|
},
|
|
678
643
|
t when t == Tags._GRAIN_RATIONAL_BOXED_NUM_TAG => {
|
|
679
644
|
if (offset + 16n > bufSize) {
|
|
680
|
-
reportError(
|
|
645
|
+
return reportError(
|
|
681
646
|
"Not enough bytes remaining in buffer for Rational/Number",
|
|
682
647
|
offset
|
|
683
648
|
)
|
|
684
649
|
} else {
|
|
685
650
|
let numeratorOffset = load(valuePtr, 8n)
|
|
686
651
|
let denominatorOffset = load(valuePtr, 12n)
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
652
|
+
match (validateHeap(buf, bufSize, numeratorOffset, valuesChecked)) {
|
|
653
|
+
Some(err) => return Some(err),
|
|
654
|
+
None => void,
|
|
655
|
+
}
|
|
656
|
+
match (validateHeap(buf, bufSize, denominatorOffset, valuesChecked)) {
|
|
657
|
+
Some(err) => return Some(err),
|
|
658
|
+
None => void,
|
|
659
|
+
}
|
|
660
|
+
if (
|
|
661
|
+
load(buf, numeratorOffset) != Tags._GRAIN_BOXED_NUM_HEAP_TAG &&
|
|
662
|
+
load(buf, numeratorOffset + 4n) !=
|
|
663
|
+
Tags._GRAIN_BIGINT_BOXED_NUM_TAG
|
|
664
|
+
) {
|
|
665
|
+
return reportError(
|
|
666
|
+
"Rational/Number numerator was not in the expected format",
|
|
667
|
+
offset
|
|
668
|
+
)
|
|
669
|
+
}
|
|
670
|
+
if (
|
|
671
|
+
load(buf, denominatorOffset) != Tags._GRAIN_BOXED_NUM_HEAP_TAG &&
|
|
672
|
+
load(buf, denominatorOffset + 4n) !=
|
|
673
|
+
Tags._GRAIN_BIGINT_BOXED_NUM_TAG
|
|
674
|
+
) {
|
|
675
|
+
return reportError(
|
|
676
|
+
"Rational/Number denominator was not in the expected format",
|
|
677
|
+
offset
|
|
678
|
+
)
|
|
679
|
+
}
|
|
680
|
+
match (validateHeap(buf, bufSize, denominatorOffset, valuesChecked)) {
|
|
681
|
+
Some(e) => return Some(e),
|
|
682
|
+
None => void,
|
|
683
|
+
}
|
|
684
|
+
if (
|
|
685
|
+
load(buf, numeratorOffset) != Tags._GRAIN_BOXED_NUM_HEAP_TAG &&
|
|
686
|
+
load(buf, numeratorOffset + 4n) !=
|
|
695
687
|
Tags._GRAIN_BIGINT_BOXED_NUM_TAG
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
load(buf, denominatorOffset) !=
|
|
706
|
-
Tags._GRAIN_BOXED_NUM_HEAP_TAG &&
|
|
707
|
-
load(buf, denominatorOffset + 4n) !=
|
|
688
|
+
) {
|
|
689
|
+
return reportError(
|
|
690
|
+
"Rational/Number numerator was not in the expected format",
|
|
691
|
+
offset
|
|
692
|
+
)
|
|
693
|
+
}
|
|
694
|
+
let denominatorError = if (
|
|
695
|
+
load(buf, denominatorOffset) != Tags._GRAIN_BOXED_NUM_HEAP_TAG &&
|
|
696
|
+
load(buf, denominatorOffset + 4n) !=
|
|
708
697
|
Tags._GRAIN_BIGINT_BOXED_NUM_TAG
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
} else {
|
|
715
|
-
None
|
|
716
|
-
}
|
|
717
|
-
Option.or(numeratorError, denominatorError)
|
|
718
|
-
} else {
|
|
719
|
-
error
|
|
698
|
+
) {
|
|
699
|
+
return reportError(
|
|
700
|
+
"Rational/Number denominator was not in the expected format",
|
|
701
|
+
offset
|
|
702
|
+
)
|
|
720
703
|
}
|
|
721
704
|
}
|
|
722
705
|
},
|
|
723
|
-
_ =>
|
|
724
|
-
None
|
|
725
|
-
},
|
|
706
|
+
_ => void,
|
|
726
707
|
}
|
|
727
708
|
},
|
|
728
|
-
|
|
729
|
-
|
|
709
|
+
t when t == Tags._GRAIN_INT32_HEAP_TAG => {
|
|
710
|
+
if (offset + 8n > bufSize) {
|
|
711
|
+
return reportError(
|
|
712
|
+
"Not enough bytes remaining in buffer for Int32",
|
|
713
|
+
offset
|
|
714
|
+
)
|
|
715
|
+
}
|
|
716
|
+
},
|
|
717
|
+
t when t == Tags._GRAIN_FLOAT32_HEAP_TAG => {
|
|
718
|
+
if (offset + 8n > bufSize) {
|
|
719
|
+
return reportError(
|
|
720
|
+
"Not enough bytes remaining in buffer for Float32",
|
|
721
|
+
offset
|
|
722
|
+
)
|
|
723
|
+
}
|
|
724
|
+
},
|
|
725
|
+
t when t == Tags._GRAIN_UINT32_HEAP_TAG => {
|
|
726
|
+
if (offset + 8n > bufSize) {
|
|
727
|
+
return reportError(
|
|
728
|
+
"Not enough bytes remaining in buffer for Uint32",
|
|
729
|
+
offset
|
|
730
|
+
)
|
|
731
|
+
}
|
|
732
|
+
},
|
|
733
|
+
t when t == Tags._GRAIN_UINT64_HEAP_TAG => {
|
|
734
|
+
if (offset + 16n > bufSize) {
|
|
735
|
+
return reportError(
|
|
736
|
+
"Not enough bytes remaining in buffer for Uint64",
|
|
737
|
+
offset
|
|
738
|
+
)
|
|
739
|
+
}
|
|
730
740
|
},
|
|
741
|
+
_ => void,
|
|
731
742
|
}
|
|
743
|
+
return None
|
|
732
744
|
}
|
|
733
745
|
|
|
734
746
|
@unsafe
|
|
@@ -742,15 +754,12 @@ let validate = (buf, bufSize) => {
|
|
|
742
754
|
} else {
|
|
743
755
|
// Handle non-heap values: booleans, chars, void, etc.
|
|
744
756
|
match (value) {
|
|
745
|
-
_ when (
|
|
746
|
-
value == fromGrain(true) ||
|
|
757
|
+
_ when value == fromGrain(true) ||
|
|
747
758
|
value == fromGrain(false) ||
|
|
748
759
|
value == fromGrain(void) ||
|
|
749
|
-
(value & Tags._GRAIN_NUMBER_TAG_MASK) ==
|
|
750
|
-
Tags.
|
|
751
|
-
|
|
752
|
-
) =>
|
|
753
|
-
None,
|
|
760
|
+
(value & Tags._GRAIN_NUMBER_TAG_MASK) == Tags._GRAIN_NUMBER_TAG_TYPE ||
|
|
761
|
+
(value & Tags._GRAIN_GENERIC_TAG_MASK) ==
|
|
762
|
+
Tags._GRAIN_SHORTVAL_TAG_TYPE => None,
|
|
754
763
|
_ => reportError("Unknown value", 0n),
|
|
755
764
|
}
|
|
756
765
|
}
|
|
@@ -763,9 +772,7 @@ let rec unmarshalHeap = (buf, offset, valuesUnmarshaled) => {
|
|
|
763
772
|
|
|
764
773
|
let valuePtr = buf + offset
|
|
765
774
|
match (load(valuePtr, 0n)) {
|
|
766
|
-
t when
|
|
767
|
-
t == Tags._GRAIN_STRING_HEAP_TAG || t == Tags._GRAIN_BYTES_HEAP_TAG
|
|
768
|
-
) => {
|
|
775
|
+
t when t == Tags._GRAIN_STRING_HEAP_TAG || t == Tags._GRAIN_BYTES_HEAP_TAG => {
|
|
769
776
|
let size = 8n + load(valuePtr, 4n)
|
|
770
777
|
let value = Memory.malloc(size)
|
|
771
778
|
Memory.copy(value, valuePtr, size)
|
|
@@ -792,7 +799,7 @@ let rec unmarshalHeap = (buf, offset, valuesUnmarshaled) => {
|
|
|
792
799
|
let asInt32 = toGrain(newInt32(subvalue)): Int32
|
|
793
800
|
match (Map.get(asInt32, valuesUnmarshaled)) {
|
|
794
801
|
Some(ptr) => {
|
|
795
|
-
let ptr = load(fromGrain(ptr),
|
|
802
|
+
let ptr = load(fromGrain(ptr), 4n)
|
|
796
803
|
store(value + i, Memory.incRef(ptr), 20n)
|
|
797
804
|
},
|
|
798
805
|
None => {
|
|
@@ -827,7 +834,7 @@ let rec unmarshalHeap = (buf, offset, valuesUnmarshaled) => {
|
|
|
827
834
|
let asInt32 = toGrain(newInt32(subvalue)): Int32
|
|
828
835
|
match (Map.get(asInt32, valuesUnmarshaled)) {
|
|
829
836
|
Some(ptr) => {
|
|
830
|
-
let ptr = load(fromGrain(ptr),
|
|
837
|
+
let ptr = load(fromGrain(ptr), 4n)
|
|
831
838
|
store(value + i, Memory.incRef(ptr), 16n)
|
|
832
839
|
},
|
|
833
840
|
None => {
|
|
@@ -862,7 +869,7 @@ let rec unmarshalHeap = (buf, offset, valuesUnmarshaled) => {
|
|
|
862
869
|
let asInt32 = toGrain(newInt32(subvalue)): Int32
|
|
863
870
|
match (Map.get(asInt32, valuesUnmarshaled)) {
|
|
864
871
|
Some(ptr) => {
|
|
865
|
-
let ptr = load(fromGrain(ptr),
|
|
872
|
+
let ptr = load(fromGrain(ptr), 4n)
|
|
866
873
|
store(value + i, Memory.incRef(ptr), 8n)
|
|
867
874
|
},
|
|
868
875
|
None => {
|
|
@@ -897,7 +904,7 @@ let rec unmarshalHeap = (buf, offset, valuesUnmarshaled) => {
|
|
|
897
904
|
let asInt32 = toGrain(newInt32(subvalue)): Int32
|
|
898
905
|
match (Map.get(asInt32, valuesUnmarshaled)) {
|
|
899
906
|
Some(ptr) => {
|
|
900
|
-
let ptr = load(fromGrain(ptr),
|
|
907
|
+
let ptr = load(fromGrain(ptr), 4n)
|
|
901
908
|
store(value + i, Memory.incRef(ptr), 8n)
|
|
902
909
|
},
|
|
903
910
|
None => {
|
|
@@ -932,7 +939,7 @@ let rec unmarshalHeap = (buf, offset, valuesUnmarshaled) => {
|
|
|
932
939
|
let asInt32 = toGrain(newInt32(subvalue)): Int32
|
|
933
940
|
match (Map.get(asInt32, valuesUnmarshaled)) {
|
|
934
941
|
Some(ptr) => {
|
|
935
|
-
let ptr = load(fromGrain(ptr),
|
|
942
|
+
let ptr = load(fromGrain(ptr), 4n)
|
|
936
943
|
store(value + i, Memory.incRef(ptr), 16n)
|
|
937
944
|
},
|
|
938
945
|
None => {
|
|
@@ -953,15 +960,6 @@ let rec unmarshalHeap = (buf, offset, valuesUnmarshaled) => {
|
|
|
953
960
|
t when t == Tags._GRAIN_BOXED_NUM_HEAP_TAG => {
|
|
954
961
|
let tag = load(valuePtr, 4n)
|
|
955
962
|
match (tag) {
|
|
956
|
-
t when t == Tags._GRAIN_INT32_BOXED_NUM_TAG => {
|
|
957
|
-
let value = Memory.malloc(12n)
|
|
958
|
-
Memory.copy(value, valuePtr, 12n)
|
|
959
|
-
|
|
960
|
-
let asInt32 = toGrain(newInt32(value)): Int32
|
|
961
|
-
Map.set(offsetAsInt32, asInt32, valuesUnmarshaled)
|
|
962
|
-
|
|
963
|
-
value
|
|
964
|
-
},
|
|
965
963
|
t when t == Tags._GRAIN_INT64_BOXED_NUM_TAG => {
|
|
966
964
|
let value = Memory.malloc(16n)
|
|
967
965
|
Memory.copy(value, valuePtr, 16n)
|
|
@@ -981,15 +979,6 @@ let rec unmarshalHeap = (buf, offset, valuesUnmarshaled) => {
|
|
|
981
979
|
|
|
982
980
|
value
|
|
983
981
|
},
|
|
984
|
-
t when t == Tags._GRAIN_FLOAT32_BOXED_NUM_TAG => {
|
|
985
|
-
let value = Memory.malloc(12n)
|
|
986
|
-
Memory.copy(value, valuePtr, 12n)
|
|
987
|
-
|
|
988
|
-
let asInt32 = toGrain(newInt32(value)): Int32
|
|
989
|
-
Map.set(offsetAsInt32, asInt32, valuesUnmarshaled)
|
|
990
|
-
|
|
991
|
-
value
|
|
992
|
-
},
|
|
993
982
|
t when t == Tags._GRAIN_FLOAT64_BOXED_NUM_TAG => {
|
|
994
983
|
let value = Memory.malloc(16n)
|
|
995
984
|
Memory.copy(value, valuePtr, 16n)
|
|
@@ -1017,6 +1006,26 @@ let rec unmarshalHeap = (buf, offset, valuesUnmarshaled) => {
|
|
|
1017
1006
|
},
|
|
1018
1007
|
}
|
|
1019
1008
|
},
|
|
1009
|
+
t when t == Tags._GRAIN_INT32_HEAP_TAG ||
|
|
1010
|
+
t == Tags._GRAIN_FLOAT32_HEAP_TAG ||
|
|
1011
|
+
t == Tags._GRAIN_UINT32_HEAP_TAG => {
|
|
1012
|
+
let value = Memory.malloc(8n)
|
|
1013
|
+
Memory.copy(value, valuePtr, 8n)
|
|
1014
|
+
|
|
1015
|
+
let asInt32 = toGrain(newInt32(value)): Int32
|
|
1016
|
+
Map.set(offsetAsInt32, asInt32, valuesUnmarshaled)
|
|
1017
|
+
|
|
1018
|
+
value
|
|
1019
|
+
},
|
|
1020
|
+
t when t == Tags._GRAIN_UINT64_HEAP_TAG => {
|
|
1021
|
+
let value = Memory.malloc(16n)
|
|
1022
|
+
Memory.copy(value, valuePtr, 16n)
|
|
1023
|
+
|
|
1024
|
+
let asInt32 = toGrain(newInt32(value)): Int32
|
|
1025
|
+
Map.set(offsetAsInt32, asInt32, valuesUnmarshaled)
|
|
1026
|
+
|
|
1027
|
+
value
|
|
1028
|
+
},
|
|
1020
1029
|
_ => {
|
|
1021
1030
|
fail "Unknown heap type"
|
|
1022
1031
|
},
|
|
@@ -1045,10 +1054,13 @@ let unmarshal = buf => {
|
|
|
1045
1054
|
* @param bytes: The data to deserialize
|
|
1046
1055
|
* @returns An in-memory value
|
|
1047
1056
|
*
|
|
1057
|
+
* @example Marshal.unmarshal(Marshal.marshal('🌾')) == Ok('🌾')
|
|
1058
|
+
* @example Marshal.unmarshal(b"\x03\x00\x00\x00") == Ok(1)
|
|
1059
|
+
*
|
|
1048
1060
|
* @since v0.5.3
|
|
1049
1061
|
*/
|
|
1050
1062
|
@unsafe
|
|
1051
|
-
|
|
1063
|
+
provide let unmarshal = (bytes: Bytes) => {
|
|
1052
1064
|
let buf = fromGrain(bytes) + 8n
|
|
1053
1065
|
let bufSize = load(fromGrain(bytes), 4n)
|
|
1054
1066
|
match (validate(buf, bufSize)) {
|