| 100 | |
| 101 | /* Decode any tag -> JS value; mirrors `decodeBytes` but inspects (not asserts) the tag. */ |
| 102 | function decodeAny(exps, handle) { |
| 103 | const tagPtr = exps.wasm_alloc(4); |
| 104 | let cap = 256; |
| 105 | let dstPtr = exps.wasm_alloc(cap); |
| 106 | let n = exps.host_edge_decode(handle, tagPtr, dstPtr, cap); |
| 107 | if (n < 0) { |
| 108 | const needed = -n; |
| 109 | exps.wasm_free(dstPtr, cap); |
| 110 | cap = needed; |
| 111 | dstPtr = exps.wasm_alloc(cap); |
| 112 | n = exps.host_edge_decode(handle, tagPtr, dstPtr, cap); |
| 113 | } |
| 114 | const tag = new DataView(exps.memory.buffer).getUint32(tagPtr, true); |
| 115 | exps.wasm_free(tagPtr, 4); |
| 116 | const bytes = n > 0 ? new Uint8Array(exps.memory.buffer, dstPtr, n).slice() : new Uint8Array(0); |
| 117 | exps.wasm_free(dstPtr, cap); |
| 118 | switch (tag) { |
| 119 | case TAG_NONE: return null; |
| 120 | case TAG_BOOL: return bytes[0] !== 0; |
| 121 | case TAG_INT: return Number(new DataView(bytes.buffer, bytes.byteOffset, 16).getBigInt64(0, true)); |
| 122 | case TAG_FLOAT: return new DataView(bytes.buffer, bytes.byteOffset, 8).getFloat64(0, true); |
| 123 | case TAG_BYTES: return TD.decode(bytes); |
| 124 | default: throw new Error(`unknown handle tag ${tag}`); |
| 125 | } |
| 126 | } |
| 127 | |
| 128 | /* JS value -> handle; chooses tag from typeof. Bigint also accepted for int. */ |
| 129 | function encodeAny(exps, value) { |