-
-
Notifications
You must be signed in to change notification settings - Fork 51
/
Copy pathjs-value.ts
123 lines (113 loc) · 3.07 KB
/
js-value.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import { Memory } from "./memory.js";
import { assertNever, pointer } from "./types.js";
export const enum Kind {
Boolean = 0,
String = 1,
Number = 2,
Object = 3,
Null = 4,
Undefined = 5,
Function = 6,
Symbol = 7,
BigInt = 8,
}
export const decode = (
kind: Kind,
payload1: number,
payload2: number,
memory: Memory
) => {
switch (kind) {
case Kind.Boolean:
switch (payload1) {
case 0:
return false;
case 1:
return true;
}
case Kind.Number:
return payload2;
case Kind.String:
case Kind.Object:
case Kind.Function:
case Kind.Symbol:
case Kind.BigInt:
return memory.getObject(payload1);
case Kind.Null:
return null;
case Kind.Undefined:
return undefined;
default:
assertNever(kind, `JSValue Type kind "${kind}" is not supported`);
}
};
// Note:
// `decodeValues` assumes that the size of RawJSValue is 16.
export const decodeArray = (ptr: pointer, length: number, memory: Memory) => {
let result = [];
for (let index = 0; index < length; index++) {
const base = ptr + 16 * index;
const kind = memory.readUint32(base);
const payload1 = memory.readUint32(base + 4);
const payload2 = memory.readFloat64(base + 8);
result.push(decode(kind, payload1, payload2, memory));
}
return result;
};
export const write = (
value: any,
kind_ptr: pointer,
payload1_ptr: pointer,
payload2_ptr: pointer,
is_exception: boolean,
memory: Memory
) => {
const exceptionBit = (is_exception ? 1 : 0) << 31;
if (value === null) {
memory.writeUint32(kind_ptr, exceptionBit | Kind.Null);
return;
}
const writeRef = (kind: Kind) => {
memory.writeUint32(kind_ptr, exceptionBit | kind);
memory.writeUint32(payload1_ptr, memory.retain(value));
};
const type = typeof value;
switch (type) {
case "boolean": {
memory.writeUint32(kind_ptr, exceptionBit | Kind.Boolean);
memory.writeUint32(payload1_ptr, value ? 1 : 0);
break;
}
case "number": {
memory.writeUint32(kind_ptr, exceptionBit | Kind.Number);
memory.writeFloat64(payload2_ptr, value);
break;
}
case "string": {
writeRef(Kind.String);
break;
}
case "undefined": {
memory.writeUint32(kind_ptr, exceptionBit | Kind.Undefined);
break;
}
case "object": {
writeRef(Kind.Object);
break;
}
case "function": {
writeRef(Kind.Function);
break;
}
case "symbol": {
writeRef(Kind.Symbol);
break;
}
case "bigint": {
writeRef(Kind.BigInt);
break;
}
default:
assertNever(type, `Type "${type}" is not supported yet`);
}
};