json-as 1.1.4 → 1.1.6
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 +10 -2
- package/README.md +1 -1
- package/assembly/__benches__/abc.bench.ts +3 -0
- package/assembly/__benches__/large.bench.ts +3 -0
- package/assembly/__benches__/medium.bench.ts +3 -0
- package/assembly/__benches__/small.bench.ts +3 -0
- package/assembly/__benches__/vec3.bench.ts +3 -0
- package/assembly/__tests__/lib/index.ts +1 -1
- package/assembly/__tests__/test.spec.ts +122 -0
- package/index.ts +1 -26
- package/package.json +1 -1
- package/run-bench.as.sh +3 -3
- package/run-bench.js.sh +1 -1
- package/run-tests.sh +0 -3
- package/transform/lib/index.js +120 -87
- package/transform/lib/index.js.map +1 -1
- package/transform/src/index.ts +123 -98
- package/assembly/__tests__/misc.spec.ts +0 -149
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## 2025-05-23 - 1.1.6
|
|
4
|
+
|
|
5
|
+
- fix: null and boolean fields would miscalculate offsets when deserializing
|
|
6
|
+
|
|
7
|
+
## 2025-05-23 - 1.1.5
|
|
8
|
+
|
|
9
|
+
- fix: index.js didn't point to correct file, thus creating a compiler crash
|
|
10
|
+
|
|
11
|
+
## 2025-05-23 - 1.1.4
|
|
4
12
|
|
|
5
13
|
- revert: grouping properties in favor of memory.compare
|
|
6
14
|
|
|
@@ -209,4 +217,4 @@
|
|
|
209
217
|
- feat: reduce memory usage so that it is viable for low-memory environments
|
|
210
218
|
- feat: write to a central buffer and reduce memory overhead
|
|
211
219
|
- feat: rewrite the transform to properly resolve schemas and link them together
|
|
212
|
-
- feat: pre-allocate and compute the minimum size of a schema to avoid memory out of range errors
|
|
220
|
+
- feat: pre-allocate and compute the minimum size of a schema to avoid memory out of range errors
|
package/README.md
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { JSON } from "..";
|
|
2
|
+
import { expect } from "../__tests__/lib";
|
|
2
3
|
import { bench } from "./lib/bench";
|
|
3
4
|
|
|
4
5
|
const v1 = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
5
6
|
const v2 = '"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"';
|
|
6
7
|
|
|
8
|
+
expect(JSON.stringify(v1)).toBe(v2);
|
|
9
|
+
|
|
7
10
|
bench(
|
|
8
11
|
"Serialize Alphabet",
|
|
9
12
|
() => {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { JSON } from "..";
|
|
2
|
+
import { expect } from "../__tests__/lib";
|
|
2
3
|
import { bench } from "./lib/bench";
|
|
3
4
|
|
|
4
5
|
|
|
@@ -114,6 +115,8 @@ const v1: LargeJSON = {
|
|
|
114
115
|
|
|
115
116
|
const v2 = `{"id":2,"name":"Medium Object","age":18,"email":"me@jairus.dev","street":"I don't want to say my street","city":"I don't want to say this either","state":"It really depends","zip":"I forget what it is","tags":["me","dogs","mountains","bar","foo"],"theme":"Hyper Term Black","notifications":true,"language":"en-US","movement":[{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3}]}`;
|
|
116
117
|
|
|
118
|
+
expect(JSON.stringify(v1)).toBe(v2);
|
|
119
|
+
expect(JSON.stringify(JSON.parse<LargeJSON>(v2))).toBe(v2)
|
|
117
120
|
bench(
|
|
118
121
|
"Serialize Large Object",
|
|
119
122
|
() => {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { JSON } from "..";
|
|
2
|
+
import { expect } from "../__tests__/lib";
|
|
2
3
|
import { bench } from "./lib/bench";
|
|
3
4
|
|
|
4
5
|
|
|
@@ -29,6 +30,8 @@ const v1: MediumJSON = {
|
|
|
29
30
|
|
|
30
31
|
const v2 = `{"id":2,"name":"Medium Object","age":18,"email":"me@jairus.dev","street":"I don't want to say my street","city":"I don't want to say this either","state":"It really depends","zip":"I forget what it is","tags":["me","dogs","mountains","bar","foo"]}`;
|
|
31
32
|
|
|
33
|
+
expect(JSON.stringify(v1)).toBe(v2);
|
|
34
|
+
|
|
32
35
|
bench(
|
|
33
36
|
"Serialize Medium Object",
|
|
34
37
|
() => {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { JSON } from "..";
|
|
2
|
+
import { expect } from "../__tests__/lib";
|
|
2
3
|
import { bench } from "./lib/bench";
|
|
3
4
|
|
|
4
5
|
|
|
@@ -16,6 +17,8 @@ const v1: SmallJSON = {
|
|
|
16
17
|
};
|
|
17
18
|
const v2 = '{"id":1,"name":"Small Object","active":true}';
|
|
18
19
|
|
|
20
|
+
expect(JSON.stringify(v1)).toBe(v2);
|
|
21
|
+
|
|
19
22
|
bench(
|
|
20
23
|
"Serialize Small Object",
|
|
21
24
|
() => {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { JSON } from "..";
|
|
2
|
+
import { expect } from "../__tests__/lib";
|
|
2
3
|
import { bench } from "./lib/bench";
|
|
3
4
|
|
|
4
5
|
|
|
@@ -12,6 +13,8 @@ class Vec3 {
|
|
|
12
13
|
const v1: Vec3 = { x: 1, y: 2, z: 3 };
|
|
13
14
|
const v2 = '{"x":1,"y":2,"z":3}';
|
|
14
15
|
|
|
16
|
+
expect(JSON.stringify(v1)).toBe(v2);
|
|
17
|
+
|
|
15
18
|
bench(
|
|
16
19
|
"Serialize Vec3",
|
|
17
20
|
() => {
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { JSON } from "../";
|
|
2
|
+
import { describe, expect } from "./lib";
|
|
3
|
+
import { DerivedObject, Null, ObjWithStrangeKey, ObjectWithFloat, OmitIf, Player, Vec3 } from "./types";
|
|
4
|
+
|
|
5
|
+
// describe("Should serialize objects", () => {
|
|
6
|
+
// expect(
|
|
7
|
+
// JSON.stringify<Vec3>({
|
|
8
|
+
// x: 3.4,
|
|
9
|
+
// y: 1.2,
|
|
10
|
+
// z: 8.3,
|
|
11
|
+
// }),
|
|
12
|
+
// ).toBe('{"x":3.4,"y":1.2,"z":8.3}');
|
|
13
|
+
|
|
14
|
+
// expect(
|
|
15
|
+
// JSON.stringify<Player>({
|
|
16
|
+
// firstName: "Emmet",
|
|
17
|
+
// lastName: "West",
|
|
18
|
+
// lastActive: [8, 27, 2022],
|
|
19
|
+
// age: 23,
|
|
20
|
+
// pos: {
|
|
21
|
+
// x: 3.4,
|
|
22
|
+
// y: 1.2,
|
|
23
|
+
// z: 8.3,
|
|
24
|
+
// },
|
|
25
|
+
// isVerified: true,
|
|
26
|
+
// }),
|
|
27
|
+
// ).toBe('{"firstName":"Emmet","lastName":"West","lastActive":[8,27,2022],"age":23,"pos":{"x":3.4,"y":1.2,"z":8.3},"isVerified":true}');
|
|
28
|
+
|
|
29
|
+
// expect(JSON.stringify<ObjectWithFloat>({ f: 7.23 })).toBe('{"f":7.23}');
|
|
30
|
+
|
|
31
|
+
// expect(JSON.stringify<ObjectWithFloat>({ f: 0.000001 })).toBe('{"f":0.000001}');
|
|
32
|
+
|
|
33
|
+
// expect(JSON.stringify<ObjectWithFloat>({ f: 1e-7 })).toBe('{"f":1e-7}');
|
|
34
|
+
|
|
35
|
+
// expect(JSON.stringify<ObjectWithFloat>({ f: 1e20 })).toBe('{"f":100000000000000000000.0}');
|
|
36
|
+
|
|
37
|
+
// expect(JSON.stringify<ObjectWithFloat>({ f: 1e21 })).toBe('{"f":1e+21}');
|
|
38
|
+
|
|
39
|
+
// expect(JSON.stringify<ObjWithStrangeKey<string>>({ data: "foo" })).toBe('{"a\\\\\\t\\"\\u0002b`c":"foo"}');
|
|
40
|
+
// });
|
|
41
|
+
|
|
42
|
+
// describe("Should serialize @omit'ed objects", () => {
|
|
43
|
+
// expect(
|
|
44
|
+
// JSON.stringify(<OmitIf>{
|
|
45
|
+
// y: 1,
|
|
46
|
+
// }),
|
|
47
|
+
// ).toBe('{"x":1,"y":1,"z":1}');
|
|
48
|
+
// });
|
|
49
|
+
// describe("Should deserialize class inheritance", () => {
|
|
50
|
+
// const jsonStr = '{"a":"1","b":"2"}';
|
|
51
|
+
// const obj = JSON.parse<DerivedObject>(jsonStr);
|
|
52
|
+
|
|
53
|
+
// expect((obj instanceof DerivedObject).toString()).toBe("true");
|
|
54
|
+
// expect(obj.a).toBe("1");
|
|
55
|
+
// expect(obj.b).toBe("2");
|
|
56
|
+
// });
|
|
57
|
+
|
|
58
|
+
// describe("Should deserialize nulls", () => {
|
|
59
|
+
// expect(JSON.stringify(JSON.parse<Null>("null"))).toBe("null");
|
|
60
|
+
// });
|
|
61
|
+
|
|
62
|
+
// describe("Should deserialize integer arrays", () => {
|
|
63
|
+
// expect(JSON.stringify(JSON.parse<u32[]>("[0,100,101]"))).toBe(JSON.stringify([0, 100, 101]));
|
|
64
|
+
|
|
65
|
+
// expect(JSON.stringify(JSON.parse<i32[]>("[0,100,101,-100,-101]"))).toBe(JSON.stringify([0, 100, 101, -100, -101]));
|
|
66
|
+
// });
|
|
67
|
+
|
|
68
|
+
// describe("Should deserialize float arrays", () => {
|
|
69
|
+
// expect(JSON.stringify(JSON.parse<f64[]>("[7.23,1000.0,1000.0,1.23456,1.23456,0.0,7.23]"))).toBe(JSON.stringify([7.23, 1000.0, 1000.0, 1.23456, 1.23456, 0.0, 7.23]));
|
|
70
|
+
|
|
71
|
+
// expect(JSON.stringify(JSON.parse<f64[]>("[1e+21,1e+22,1e-7,1e-8,1e-9]"))).toBe(JSON.stringify([1e21, 1e22, 1e-7, 1e-8, 1e-9]));
|
|
72
|
+
// });
|
|
73
|
+
|
|
74
|
+
// describe("Should deserialize boolean arrays", () => {
|
|
75
|
+
// expect(JSON.stringify(JSON.parse<boolean[]>("[true,false]"))).toBe(JSON.stringify([true, false]));
|
|
76
|
+
// });
|
|
77
|
+
|
|
78
|
+
// describe("Should deserialize string arrays", () => {
|
|
79
|
+
// expect(JSON.stringify(JSON.parse<string[]>('["string \\"with random spa\\nces and \\nnewlines\\n\\n\\n"]'))).toBe(JSON.stringify(['string "with random spa\nces and \nnewlines\n\n\n']));
|
|
80
|
+
// });
|
|
81
|
+
|
|
82
|
+
// describe("Should deserialize nested integer arrays", () => {
|
|
83
|
+
// expect(JSON.stringify(JSON.parse<i64[][]>("[[100,101],[-100,-101],[0]]"))).toBe(JSON.stringify([[100, 101], [-100, -101], [0]]));
|
|
84
|
+
// });
|
|
85
|
+
|
|
86
|
+
// describe("Should deserialize nested float arrays", () => {
|
|
87
|
+
// expect(JSON.stringify(JSON.parse<f64[][]>("[[7.23],[1000.0],[1000.0],[1.23456],[1.23456],[0.0],[7.23]]"))).toBe(JSON.stringify([[7.23], [1000.0], [1000.0], [1.23456], [1.23456], [0.0], [7.23]]));
|
|
88
|
+
// });
|
|
89
|
+
|
|
90
|
+
// describe("Should deserialize nested boolean arrays", () => {
|
|
91
|
+
// expect(JSON.stringify(JSON.parse<boolean[][]>("[[true],[false]]"))).toBe(JSON.stringify([[true], [false]]));
|
|
92
|
+
// });
|
|
93
|
+
|
|
94
|
+
// describe("Should deserialize object arrays", () => {
|
|
95
|
+
// expect(JSON.stringify(JSON.parse<Vec3[]>('[{"x":3.4,"y":1.2,"z":8.3},{"x":3.4,"y":-2.1,"z":9.3}]'))).toBe(
|
|
96
|
+
// JSON.stringify(<Vec3[]>[
|
|
97
|
+
// { x: 3.4, y: 1.2, z: 8.3 },
|
|
98
|
+
// { x: 3.4, y: -2.1, z: 9.3 },
|
|
99
|
+
// ]),
|
|
100
|
+
// );
|
|
101
|
+
// });
|
|
102
|
+
|
|
103
|
+
// describe("Should deserialize Objects", () => {
|
|
104
|
+
// expect(JSON.stringify(JSON.parse<Vec3>('{"x":3.4,"y":1.2,"z":8.3}'))).toBe(JSON.stringify(<Vec3>{ x: 3.4, y: 1.2, z: 8.3 }));
|
|
105
|
+
|
|
106
|
+
// expect(JSON.stringify(JSON.parse<Player>('{"firstName":"Emmet","lastName":"West","lastActive":[8,27,2022],"age":23,"pos":{"x":3.4,"y":1.2,"z":8.3},"isVerified":true}'))).toBe(
|
|
107
|
+
// JSON.stringify(<Player>{
|
|
108
|
+
// firstName: "Emmet",
|
|
109
|
+
// lastName: "West",
|
|
110
|
+
// lastActive: [8, 27, 2022],
|
|
111
|
+
// age: 23,
|
|
112
|
+
// pos: { x: 3.4, y: 1.2, z: 8.3 },
|
|
113
|
+
// isVerified: true,
|
|
114
|
+
// }),
|
|
115
|
+
// );
|
|
116
|
+
|
|
117
|
+
// expect(JSON.stringify(JSON.parse<ObjectWithFloat>('{"f":7.23}'))).toBe(JSON.stringify(<ObjectWithFloat>{ f: 7.23 }));
|
|
118
|
+
|
|
119
|
+
// expect(JSON.stringify(JSON.parse<ObjectWithFloat>('{"f":0.000001}'))).toBe(JSON.stringify(<ObjectWithFloat>{ f: 0.000001 }));
|
|
120
|
+
|
|
121
|
+
// expect(JSON.stringify(JSON.parse<ObjWithStrangeKey<string>>('{"a\\\\\\t\\"\\u0002b`c":"foo"}'))).toBe(JSON.stringify(<ObjWithStrangeKey<string>>{ data: "foo" }));
|
|
122
|
+
// });
|
package/index.ts
CHANGED
|
@@ -1,26 +1 @@
|
|
|
1
|
-
|
|
2
|
-
accessUrl: string = "https://example.com";
|
|
3
|
-
cardTypes: number[] = [1, 2, 3];
|
|
4
|
-
customService: string = "Contact us at support@example.com";
|
|
5
|
-
invoiceApplicationStatus: number = 1;
|
|
6
|
-
isCertification: bool = true;
|
|
7
|
-
isOnlineRecharge: bool = false;
|
|
8
|
-
loginTypes: number[] = [0, 1]; // e.g. 0 = password, 1 = OTP
|
|
9
|
-
record: string = "ICP 12345678";
|
|
10
|
-
regCompanyAudit: number = 2;
|
|
11
|
-
regCompanyPipeline: number[] = [101, 102, 103];
|
|
12
|
-
regPwdLimit: number = 8; // min password length
|
|
13
|
-
serverTime: i64 = 1650000000000; // dummy timestamp
|
|
14
|
-
srvDescription: string = "A demo service for handling customer operations.";
|
|
15
|
-
srvHiddenMenu: string[] = ["admin", "beta"];
|
|
16
|
-
srvHost: string = "srv.example.com";
|
|
17
|
-
srvId: number = 999;
|
|
18
|
-
srvKeywords: string[] = ["finance", "payments", "online"];
|
|
19
|
-
srvLogoImgUrl: string = "https://example.com/logo.png";
|
|
20
|
-
srvName: string = "ExampleService";
|
|
21
|
-
srvPageId: number = 5;
|
|
22
|
-
thirdAuthUrl: string = "https://auth.example.com";
|
|
23
|
-
userCenterStyle: number = 1; // e.g. 1 = modern, 0 = legacy
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
console.log(JSON.stringify(new SrvInfo()))
|
|
1
|
+
export { JSON } from "./assembly/index";
|
package/package.json
CHANGED
package/run-bench.as.sh
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
2
|
RUNTIMES=${RUNTIMES:-"minimal stub"}
|
|
3
3
|
ENGINES=${ENGINES:-"liftoff ignition sparkplug turbofan llvm"}
|
|
4
|
-
for file in ./assembly/__benches__
|
|
4
|
+
for file in ./assembly/__benches__/*.bench.ts; do
|
|
5
5
|
filename=$(basename -- "$file")
|
|
6
6
|
output_wasi=
|
|
7
7
|
for runtime in $RUNTIMES; do
|
|
@@ -20,8 +20,8 @@ for file in ./assembly/__benches__/vec3.bench.ts; do
|
|
|
20
20
|
exit 1
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
wasm-opt -all -O4 "${output}.2" -o "${output%.wasm}.wasi.wasm"
|
|
24
|
+
rm "${output}.2"
|
|
25
25
|
|
|
26
26
|
for engine in $ENGINES; do
|
|
27
27
|
echo -e "$filename (asc/$runtime/$engine)\n"
|
package/run-bench.js.sh
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
2
|
RUNTIMES=${RUNTIMES:-"v8-liftoff v8-ignition v8-sparkplug v8-turbofan jsc-default"}
|
|
3
3
|
npx tsc -p ./bench > /dev/null 2>&1
|
|
4
|
-
for file in ./bench
|
|
4
|
+
for file in ./bench/*.bench.ts; do
|
|
5
5
|
filename=$(basename -- "$file")
|
|
6
6
|
file_js="${filename%.ts}.js"
|
|
7
7
|
|
package/run-tests.sh
CHANGED
package/transform/lib/index.js
CHANGED
|
@@ -300,6 +300,7 @@ class JSONTransform extends Visitor {
|
|
|
300
300
|
sortedMembers.object.push(member);
|
|
301
301
|
}
|
|
302
302
|
indent = "";
|
|
303
|
+
let shouldGroup = false;
|
|
303
304
|
DESERIALIZE += indent + " let keyStart: usize = 0;\n";
|
|
304
305
|
DESERIALIZE += indent + " let keyEnd: usize = 0;\n";
|
|
305
306
|
DESERIALIZE += indent + " let isKey = false;\n";
|
|
@@ -358,7 +359,8 @@ class JSONTransform extends Visitor {
|
|
|
358
359
|
DESERIALIZE += "\n }\n";
|
|
359
360
|
}
|
|
360
361
|
DESERIALIZE += " }\n";
|
|
361
|
-
|
|
362
|
+
if (!(members[0].node.type.isNullable || isBoolean(members[0].type)))
|
|
363
|
+
DESERIALIZE += " break;\n";
|
|
362
364
|
};
|
|
363
365
|
const generateComparisions = (members) => {
|
|
364
366
|
if (members.some((m) => (m.alias || m.name).length << 1 == 2)) {
|
|
@@ -373,6 +375,9 @@ class JSONTransform extends Visitor {
|
|
|
373
375
|
if (members.some((m) => (m.alias || m.name).length << 1 == 8)) {
|
|
374
376
|
DESERIALIZE += " const code64 = load<u64>(keyStart);\n";
|
|
375
377
|
}
|
|
378
|
+
if (members.some((m) => (m.alias || m.name).length << 1 > 8)) {
|
|
379
|
+
DESERIALIZE += toMemCDecl(Math.max(...members.map((m) => (m.alias || m.name).length << 1)), " ");
|
|
380
|
+
}
|
|
376
381
|
const complex = isStruct(members[0].type) || members[0].type != "JSON.Obj" || isArray(members[0].type);
|
|
377
382
|
const firstMemberName = members[0].alias || members[0].name;
|
|
378
383
|
DESERIALIZE += indent + " if (" + getComparision(firstMemberName) + ") { // " + firstMemberName + "\n";
|
|
@@ -411,7 +416,7 @@ class JSONTransform extends Visitor {
|
|
|
411
416
|
DESERIALIZE += " while (srcStart < srcEnd) {\n";
|
|
412
417
|
DESERIALIZE += " const code = load<u16>(srcStart);\n";
|
|
413
418
|
DESERIALIZE += " if (code == 34 && load<u16>(srcStart - 2) !== 92) {\n";
|
|
414
|
-
|
|
419
|
+
generateGroups(sortedMembers.string, generateComparisions);
|
|
415
420
|
DESERIALIZE += " }\n";
|
|
416
421
|
DESERIALIZE += " srcStart += 2;\n";
|
|
417
422
|
DESERIALIZE += " }\n";
|
|
@@ -425,7 +430,7 @@ class JSONTransform extends Visitor {
|
|
|
425
430
|
DESERIALIZE += " while (srcStart < srcEnd) {\n";
|
|
426
431
|
DESERIALIZE += " const code = load<u16>(srcStart);\n";
|
|
427
432
|
DESERIALIZE += " if (code == 44 || code == 125 || JSON.Util.isSpace(code)) {\n";
|
|
428
|
-
|
|
433
|
+
generateGroups(sortedMembers.number, generateComparisions);
|
|
429
434
|
DESERIALIZE += " }\n";
|
|
430
435
|
DESERIALIZE += " srcStart += 2;\n";
|
|
431
436
|
DESERIALIZE += " }\n";
|
|
@@ -446,7 +451,7 @@ class JSONTransform extends Visitor {
|
|
|
446
451
|
DESERIALIZE += " if (--depth == 0) {\n";
|
|
447
452
|
DESERIALIZE += " srcStart += 2;\n";
|
|
448
453
|
indent = " ";
|
|
449
|
-
|
|
454
|
+
generateGroups(sortedMembers.object, generateComparisions);
|
|
450
455
|
indent = "";
|
|
451
456
|
DESERIALIZE += " }\n";
|
|
452
457
|
DESERIALIZE += " } else if (code == 123) depth++;\n";
|
|
@@ -469,7 +474,7 @@ class JSONTransform extends Visitor {
|
|
|
469
474
|
DESERIALIZE += " if (--depth == 0) {\n";
|
|
470
475
|
DESERIALIZE += " srcStart += 2;\n";
|
|
471
476
|
indent = " ";
|
|
472
|
-
|
|
477
|
+
generateGroups(sortedMembers.array, generateComparisions);
|
|
473
478
|
indent = "";
|
|
474
479
|
DESERIALIZE += " }\n";
|
|
475
480
|
DESERIALIZE += " } else if (code == 91) depth++;\n";
|
|
@@ -482,65 +487,88 @@ class JSONTransform extends Visitor {
|
|
|
482
487
|
DESERIALIZE += mbElse + "if (code == 116) {\n";
|
|
483
488
|
DESERIALIZE += " if (load<u64>(srcStart) == 28429475166421108) {\n";
|
|
484
489
|
DESERIALIZE += " srcStart += 8;\n";
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
DESERIALIZE += indent + "
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
490
|
+
generateGroups(sortedMembers.boolean, (group) => {
|
|
491
|
+
if (group.some((m) => (m.alias || m.name).length << 1 == 2)) {
|
|
492
|
+
DESERIALIZE += " const code16 = load<u16>(keyStart);\n";
|
|
493
|
+
}
|
|
494
|
+
if (group.some((m) => (m.alias || m.name).length << 1 == 4)) {
|
|
495
|
+
DESERIALIZE += " const code32 = load<u32>(keyStart);\n";
|
|
496
|
+
}
|
|
497
|
+
if (group.some((m) => (m.alias || m.name).length << 1 == 6)) {
|
|
498
|
+
DESERIALIZE += " const code48 = load<u64>(keyStart) & 0x0000FFFFFFFFFFFF;\n";
|
|
499
|
+
}
|
|
500
|
+
if (group.some((m) => (m.alias || m.name).length << 1 == 8)) {
|
|
501
|
+
DESERIALIZE += " const code64 = load<u64>(keyStart);\n";
|
|
502
|
+
}
|
|
503
|
+
if (group.some((m) => (m.alias || m.name).length << 1 > 8)) {
|
|
504
|
+
DESERIALIZE += toMemCDecl(Math.max(...group.map((m) => (m.alias || m.name).length << 1)), " ");
|
|
505
|
+
}
|
|
506
|
+
const firstMemberName = group[0].alias || group[0].name;
|
|
507
|
+
DESERIALIZE += indent + " if (" + getComparision(firstMemberName) + ") { // " + firstMemberName + "\n";
|
|
508
|
+
DESERIALIZE += indent + " store<" + group[0].type + ">(changetype<usize>(out), true, offsetof<this>(" + JSON.stringify(group[0].name) + "));\n";
|
|
509
|
+
DESERIALIZE += indent + " srcStart += 2;\n";
|
|
510
|
+
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
511
|
+
DESERIALIZE += indent + " break;\n";
|
|
512
|
+
DESERIALIZE += indent + " }";
|
|
513
|
+
for (let i = 1; i < group.length; i++) {
|
|
514
|
+
const member = group[i];
|
|
515
|
+
const memberName = member.alias || member.name;
|
|
516
|
+
DESERIALIZE += indent + " else if (" + getComparision(memberName) + ") { // " + memberName + "\n";
|
|
517
|
+
DESERIALIZE += indent + " store<" + member.type + ">(changetype<usize>(out), true, offsetof<this>(" + JSON.stringify(member.name) + "));\n";
|
|
518
|
+
DESERIALIZE += indent + " srcStart += 2;\n";
|
|
519
|
+
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
520
|
+
DESERIALIZE += indent + " break;\n";
|
|
521
|
+
DESERIALIZE += indent + " }";
|
|
522
|
+
}
|
|
523
|
+
if (STRICT) {
|
|
524
|
+
DESERIALIZE += " else {\n";
|
|
525
|
+
DESERIALIZE += indent + ' throw new Error("Unexpected key in JSON object \'" + String.fromCharCode(load<u16>(srcStart)) + "\' at position " + (srcEnd - srcStart).toString());\n';
|
|
526
|
+
DESERIALIZE += indent + " }\n";
|
|
527
|
+
}
|
|
528
|
+
});
|
|
519
529
|
DESERIALIZE += " }";
|
|
520
530
|
mbElse = " else ";
|
|
521
531
|
DESERIALIZE += " else if (load<u64>(srcStart, 2) == 28429466576093281) {\n";
|
|
522
532
|
DESERIALIZE += " srcStart += 10;\n";
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
533
|
+
generateGroups(sortedMembers.boolean, (group) => {
|
|
534
|
+
if (group.some((m) => (m.alias || m.name).length << 1 == 2)) {
|
|
535
|
+
DESERIALIZE += " const code16 = load<u16>(keyStart);\n";
|
|
536
|
+
}
|
|
537
|
+
if (group.some((m) => (m.alias || m.name).length << 1 == 4)) {
|
|
538
|
+
DESERIALIZE += " const code32 = load<u32>(keyStart);\n";
|
|
539
|
+
}
|
|
540
|
+
if (group.some((m) => (m.alias || m.name).length << 1 == 6)) {
|
|
541
|
+
DESERIALIZE += " const code48 = load<u64>(keyStart) & 0x0000FFFFFFFFFFFF;\n";
|
|
542
|
+
}
|
|
543
|
+
if (group.some((m) => (m.alias || m.name).length << 1 == 8)) {
|
|
544
|
+
DESERIALIZE += " const code64 = load<u64>(keyStart);\n";
|
|
545
|
+
}
|
|
546
|
+
if (group.some((m) => (m.alias || m.name).length << 1 > 8)) {
|
|
547
|
+
DESERIALIZE += toMemCDecl(Math.max(...group.map((m) => (m.alias || m.name).length << 1)), " ");
|
|
548
|
+
}
|
|
549
|
+
const firstMemberName = group[0].alias || group[0].name;
|
|
550
|
+
DESERIALIZE += indent + " if (" + getComparision(firstMemberName) + ") { // " + firstMemberName + "\n";
|
|
551
|
+
DESERIALIZE += indent + " store<" + group[0].type + ">(changetype<usize>(out), false, offsetof<this>(" + JSON.stringify(group[0].name) + "));\n";
|
|
534
552
|
DESERIALIZE += indent + " srcStart += 2;\n";
|
|
535
553
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
536
554
|
DESERIALIZE += indent + " break;\n";
|
|
537
555
|
DESERIALIZE += indent + " }";
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
556
|
+
for (let i = 1; i < group.length; i++) {
|
|
557
|
+
const member = group[i];
|
|
558
|
+
const memberName = member.alias || member.name;
|
|
559
|
+
DESERIALIZE += indent + " else if (" + getComparision(memberName) + ") { // " + memberName + "\n";
|
|
560
|
+
DESERIALIZE += indent + " store<" + member.type + ">(changetype<usize>(out), false, offsetof<this>(" + JSON.stringify(member.name) + "));\n";
|
|
561
|
+
DESERIALIZE += indent + " srcStart += 2;\n";
|
|
562
|
+
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
563
|
+
DESERIALIZE += indent + " break;\n";
|
|
564
|
+
DESERIALIZE += indent + " }";
|
|
565
|
+
}
|
|
566
|
+
if (STRICT) {
|
|
567
|
+
DESERIALIZE += " else {\n";
|
|
568
|
+
DESERIALIZE += indent + ' throw new Error("Unexpected key in JSON object \'" + String.fromCharCode(load<u16>(srcStart)) + "\' at position " + (srcEnd - srcStart).toString());\n';
|
|
569
|
+
DESERIALIZE += indent + " }\n";
|
|
570
|
+
}
|
|
571
|
+
});
|
|
544
572
|
DESERIALIZE += " }\n";
|
|
545
573
|
DESERIALIZE += " }";
|
|
546
574
|
}
|
|
@@ -548,40 +576,45 @@ class JSONTransform extends Visitor {
|
|
|
548
576
|
DESERIALIZE += mbElse + "if (code == 110) {\n";
|
|
549
577
|
DESERIALIZE += " if (load<u64>(srcStart) == 30399761348886638) {\n";
|
|
550
578
|
DESERIALIZE += " srcStart += 8;\n";
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
for (let i = 1; i < sortedMembers.null.length; i++) {
|
|
571
|
-
const member = sortedMembers.null[i];
|
|
572
|
-
const memberName = member.alias || member.name;
|
|
573
|
-
DESERIALIZE += indent + " else if (" + getComparision(memberName) + ") { // " + memberName + "\n";
|
|
574
|
-
DESERIALIZE += indent + " store<" + member.type + ">(changetype<usize>(out), null, offsetof<this>(" + JSON.stringify(member.name) + "));\n";
|
|
579
|
+
generateGroups(sortedMembers.null, (group) => {
|
|
580
|
+
if (group.some((m) => (m.alias || m.name).length << 1 == 2)) {
|
|
581
|
+
DESERIALIZE += " const code16 = load<u16>(keyStart);\n";
|
|
582
|
+
}
|
|
583
|
+
if (group.some((m) => (m.alias || m.name).length << 1 == 4)) {
|
|
584
|
+
DESERIALIZE += " const code32 = load<u32>(keyStart);\n";
|
|
585
|
+
}
|
|
586
|
+
if (group.some((m) => (m.alias || m.name).length << 1 == 6)) {
|
|
587
|
+
DESERIALIZE += " const code48 = load<u64>(keyStart) & 0x0000FFFFFFFFFFFF;\n";
|
|
588
|
+
}
|
|
589
|
+
if (group.some((m) => (m.alias || m.name).length << 1 == 8)) {
|
|
590
|
+
DESERIALIZE += " const code64 = load<u64>(keyStart);\n";
|
|
591
|
+
}
|
|
592
|
+
if (group.some((m) => (m.alias || m.name).length << 1 > 8)) {
|
|
593
|
+
DESERIALIZE += toMemCDecl(Math.max(...group.map((m) => (m.alias || m.name).length << 1)), " ");
|
|
594
|
+
}
|
|
595
|
+
const firstMemberName = group[0].alias || group[0].name;
|
|
596
|
+
DESERIALIZE += indent + " if (" + getComparision(firstMemberName) + ") { // " + firstMemberName + "\n";
|
|
597
|
+
DESERIALIZE += indent + " store<" + group[0].type + ">(changetype<usize>(out), null, offsetof<this>(" + JSON.stringify(group[0].name) + "));\n";
|
|
575
598
|
DESERIALIZE += indent + " srcStart += 2;\n";
|
|
576
599
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
577
600
|
DESERIALIZE += indent + " break;\n";
|
|
578
601
|
DESERIALIZE += indent + " }";
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
602
|
+
for (let i = 1; i < group.length; i++) {
|
|
603
|
+
const member = group[i];
|
|
604
|
+
const memberName = member.alias || member.name;
|
|
605
|
+
DESERIALIZE += indent + " else if (" + getComparision(memberName) + ") { // " + memberName + "\n";
|
|
606
|
+
DESERIALIZE += indent + " store<" + group[0].type + ">(changetype<usize>(out), null, offsetof<this>(" + JSON.stringify(group[0].name) + "));\n";
|
|
607
|
+
DESERIALIZE += indent + " srcStart += 2;\n";
|
|
608
|
+
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
609
|
+
DESERIALIZE += indent + " break;\n";
|
|
610
|
+
DESERIALIZE += indent + " }";
|
|
611
|
+
}
|
|
612
|
+
if (STRICT) {
|
|
613
|
+
DESERIALIZE += " else {\n";
|
|
614
|
+
DESERIALIZE += indent + ' throw new Error("Unexpected key in JSON object \'" + String.fromCharCode(load<u16>(srcStart)) + "\' at position " + (srcEnd - srcStart).toString());\n';
|
|
615
|
+
DESERIALIZE += indent + " }\n";
|
|
616
|
+
}
|
|
617
|
+
});
|
|
585
618
|
DESERIALIZE += " }";
|
|
586
619
|
DESERIALIZE += "\n }";
|
|
587
620
|
mbElse = " else ";
|
|
@@ -936,7 +969,7 @@ function getComparision(data) {
|
|
|
936
969
|
return "code64 == " + toU64(data);
|
|
937
970
|
}
|
|
938
971
|
default: {
|
|
939
|
-
return
|
|
972
|
+
return toMemCCheck(data);
|
|
940
973
|
}
|
|
941
974
|
}
|
|
942
975
|
}
|