json-as 1.3.3 → 1.3.4
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 +5 -0
- package/assembly/deserialize/simd/string.ts +20 -0
- package/assembly/deserialize/swar/array/shared.ts +17 -3
- package/assembly/deserialize/swar/string.ts +21 -0
- package/assembly/index.ts +5 -1
- package/assembly/serialize/simd/string.ts +43 -16
- package/assembly/serialize/simple/array.ts +47 -6
- package/assembly/serialize/simple/bool.ts +12 -0
- package/assembly/serialize/simple/float.ts +14 -0
- package/assembly/serialize/simple/integer.ts +6 -0
- package/assembly/serialize/simple/set.ts +59 -5
- package/assembly/serialize/simple/staticarray.ts +57 -3
- package/assembly/serialize/simple/typedarray.ts +29 -9
- package/assembly/serialize/swar/string.ts +165 -18
- package/package.json +1 -1
- package/transform/lib/index.d.ts.map +1 -1
- package/transform/lib/index.js +88 -16
- package/transform/lib/index.js.map +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { bs
|
|
2
|
-
import { BACK_SLASH } from "../../custom/chars";
|
|
1
|
+
import { bs } from "../../../lib/as-bs";
|
|
2
|
+
import { BACK_SLASH, QUOTE } from "../../custom/chars";
|
|
3
3
|
import { SERIALIZE_ESCAPE_TABLE } from "../../globals/tables";
|
|
4
4
|
import { u16_to_hex4_swar } from "../../util/swar";
|
|
5
5
|
import { OBJECT, TOTAL_OVERHEAD } from "rt/common";
|
|
@@ -11,18 +11,166 @@ import { OBJECT, TOTAL_OVERHEAD } from "rt/common";
|
|
|
11
11
|
|
|
12
12
|
export function serializeString_SWAR(src: string): void {
|
|
13
13
|
let srcStart = changetype<usize>(src);
|
|
14
|
+
const srcInitial = srcStart;
|
|
15
|
+
const srcSize = changetype<OBJECT>(srcStart - TOTAL_OVERHEAD).rtSize;
|
|
16
|
+
const srcEnd = srcStart + srcSize;
|
|
17
|
+
do {
|
|
18
|
+
const srcEnd8Fast = srcEnd - 8;
|
|
19
|
+
bs.proposeSize(srcSize + 4);
|
|
20
|
+
|
|
21
|
+
const dstStart = bs.offset;
|
|
22
|
+
let dst = dstStart + 2;
|
|
23
|
+
|
|
24
|
+
while (srcStart < srcEnd8Fast) {
|
|
25
|
+
const block = load<u64>(srcStart);
|
|
26
|
+
if ((block & 0xff00_ff00_ff00_ff00) != 0) break;
|
|
27
|
+
const lo = block & 0x00ff_00ff_00ff_00ff;
|
|
28
|
+
const asciiMask = ((lo - 0x0020_0020_0020_0020) | ((lo ^ 0x0022_0022_0022_0022) - 0x0001_0001_0001_0001) | ((lo ^ 0x005c_005c_005c_005c) - 0x0001_0001_0001_0001)) & (0x0080_0080_0080_0080 & ~lo);
|
|
29
|
+
if (asciiMask != 0) break;
|
|
30
|
+
store<u64>(dst, block);
|
|
31
|
+
srcStart += 8;
|
|
32
|
+
dst += 8;
|
|
33
|
+
}
|
|
34
|
+
if (srcStart < srcEnd8Fast) break;
|
|
35
|
+
|
|
36
|
+
while (srcStart <= srcEnd - 2) {
|
|
37
|
+
const code = load<u16>(srcStart);
|
|
38
|
+
if (code > 0x7f || code == BACK_SLASH || code == QUOTE || code < 32) break;
|
|
39
|
+
store<u16>(dst, code);
|
|
40
|
+
srcStart += 2;
|
|
41
|
+
dst += 2;
|
|
42
|
+
}
|
|
43
|
+
if (srcStart <= srcEnd - 2) break;
|
|
44
|
+
|
|
45
|
+
store<u16>(dstStart, QUOTE);
|
|
46
|
+
store<u16>(dst, QUOTE);
|
|
47
|
+
bs.offset = dst + 2;
|
|
48
|
+
return;
|
|
49
|
+
} while (false);
|
|
50
|
+
|
|
51
|
+
srcStart = srcInitial;
|
|
52
|
+
const srcEnd8 = srcEnd - 8;
|
|
53
|
+
|
|
54
|
+
bs.proposeSize(srcSize + 4);
|
|
55
|
+
store<u16>(bs.offset, 34); // "
|
|
56
|
+
bs.offset += 2;
|
|
57
|
+
|
|
58
|
+
while (srcStart < srcEnd8) {
|
|
59
|
+
const block = load<u64>(srcStart);
|
|
60
|
+
let mask = detect_escapable_u64_swar_safe(block);
|
|
61
|
+
store<u64>(bs.offset, block);
|
|
62
|
+
|
|
63
|
+
if (mask === 0) {
|
|
64
|
+
srcStart += 8;
|
|
65
|
+
bs.offset += 8;
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
do {
|
|
70
|
+
const laneIdx = usize(ctz(mask) >> 3);
|
|
71
|
+
const srcIdx = srcStart + laneIdx;
|
|
72
|
+
// Even (0 2 4 6) -> Confirmed ASCII Escape
|
|
73
|
+
// Odd (1 3 5 7) -> Possibly a Unicode code unit or surrogate
|
|
74
|
+
if ((laneIdx & 1) === 0) {
|
|
75
|
+
mask &= mask - 1;
|
|
76
|
+
const code = load<u16>(srcIdx);
|
|
77
|
+
const escaped = load<u32>(SERIALIZE_ESCAPE_TABLE + (code << 2));
|
|
78
|
+
|
|
79
|
+
if ((escaped & 0xffff) != BACK_SLASH) {
|
|
80
|
+
bs.growSize(10);
|
|
81
|
+
const dstIdx = bs.offset + laneIdx;
|
|
82
|
+
store<u64>(dstIdx, U00_MARKER);
|
|
83
|
+
store<u32>(dstIdx, escaped, 8);
|
|
84
|
+
store<u64>(dstIdx, load<u64>(srcIdx, 2), 12);
|
|
85
|
+
bs.offset += 10;
|
|
86
|
+
} else {
|
|
87
|
+
bs.growSize(2);
|
|
88
|
+
const dstIdx = bs.offset + laneIdx;
|
|
89
|
+
store<u32>(dstIdx, escaped);
|
|
90
|
+
store<u64>(dstIdx, load<u64>(srcIdx, 2), 4);
|
|
91
|
+
bs.offset += 2;
|
|
92
|
+
}
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
mask &= mask - 1;
|
|
96
|
+
|
|
97
|
+
const code = load<u16>(srcIdx - 1);
|
|
98
|
+
if (code < 0xd800 || code > 0xdfff) continue;
|
|
99
|
+
|
|
100
|
+
if (code <= 0xdbff && srcIdx + 2 < srcEnd) {
|
|
101
|
+
const next = load<u16>(srcIdx, 1);
|
|
102
|
+
if (next >= 0xdc00 && next <= 0xdfff) {
|
|
103
|
+
// paired surrogate
|
|
104
|
+
// mask &= ~(0xFF << ((laneIdx+2) << 3));
|
|
105
|
+
mask &= mask - 1;
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
bs.growSize(10);
|
|
111
|
+
|
|
112
|
+
// unpaired high/low surrogate
|
|
113
|
+
const dstIdx = bs.offset + laneIdx - 1;
|
|
114
|
+
store<u32>(dstIdx, U_MARKER); // \u
|
|
115
|
+
store<u64>(dstIdx, u16_to_hex4_swar(code), 4);
|
|
116
|
+
store<u64>(dstIdx, load<u64>(srcIdx, 1), 12);
|
|
117
|
+
bs.offset += 10;
|
|
118
|
+
} while (mask !== 0);
|
|
119
|
+
|
|
120
|
+
srcStart += 8;
|
|
121
|
+
bs.offset += 8;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
while (srcStart <= srcEnd - 2) {
|
|
125
|
+
const code = load<u16>(srcStart);
|
|
126
|
+
|
|
127
|
+
if (code == BACK_SLASH || code == QUOTE || code < 32) {
|
|
128
|
+
const escaped = load<u32>(SERIALIZE_ESCAPE_TABLE + (code << 2));
|
|
129
|
+
if ((escaped & 0xffff) != BACK_SLASH) {
|
|
130
|
+
bs.growSize(10);
|
|
131
|
+
store<u64>(bs.offset, U00_MARKER);
|
|
132
|
+
store<u32>(bs.offset, escaped, 8);
|
|
133
|
+
bs.offset += 12;
|
|
134
|
+
} else {
|
|
135
|
+
bs.growSize(2);
|
|
136
|
+
store<u32>(bs.offset, escaped);
|
|
137
|
+
bs.offset += 4;
|
|
138
|
+
}
|
|
139
|
+
srcStart += 2;
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (code < 0xd800 || code > 0xdfff) {
|
|
144
|
+
store<u16>(bs.offset, code);
|
|
145
|
+
bs.offset += 2;
|
|
146
|
+
srcStart += 2;
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
14
149
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
150
|
+
if (code <= 0xdbff && srcStart + 2 <= srcEnd - 2) {
|
|
151
|
+
const next = load<u16>(srcStart, 2);
|
|
152
|
+
if (next >= 0xdc00 && next <= 0xdfff) {
|
|
153
|
+
// valid surrogate pair
|
|
154
|
+
store<u16>(bs.offset, code);
|
|
155
|
+
store<u16>(bs.offset + 2, next);
|
|
156
|
+
bs.offset += 4;
|
|
157
|
+
srcStart += 4;
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
23
160
|
}
|
|
161
|
+
|
|
162
|
+
// unpaired high/low surrogate
|
|
163
|
+
write_u_escape(code);
|
|
164
|
+
srcStart += 2;
|
|
165
|
+
continue;
|
|
24
166
|
}
|
|
25
167
|
|
|
168
|
+
store<u16>(bs.offset, 34); // "
|
|
169
|
+
bs.offset += 2;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
export function serializeString_SWAR_ExperimentalTableEscapes(src: string): void {
|
|
173
|
+
let srcStart = changetype<usize>(src);
|
|
26
174
|
const srcSize = changetype<OBJECT>(srcStart - TOTAL_OVERHEAD).rtSize;
|
|
27
175
|
const srcEnd = srcStart + srcSize;
|
|
28
176
|
const srcEnd8 = srcEnd - 8;
|
|
@@ -32,10 +180,9 @@ export function serializeString_SWAR(src: string): void {
|
|
|
32
180
|
bs.offset += 2;
|
|
33
181
|
|
|
34
182
|
while (srcStart < srcEnd8) {
|
|
35
|
-
|
|
36
|
-
store<u64>(bs.offset, block);
|
|
37
|
-
|
|
183
|
+
const block = load<u64>(srcStart);
|
|
38
184
|
let mask = detect_escapable_u64_swar_safe(block);
|
|
185
|
+
store<u64>(bs.offset, block);
|
|
39
186
|
|
|
40
187
|
if (mask === 0) {
|
|
41
188
|
srcStart += 8;
|
|
@@ -49,7 +196,7 @@ export function serializeString_SWAR(src: string): void {
|
|
|
49
196
|
// Even (0 2 4 6) -> Confirmed ASCII Escape
|
|
50
197
|
// Odd (1 3 5 7) -> Possibly a Unicode code unit or surrogate
|
|
51
198
|
if ((laneIdx & 1) === 0) {
|
|
52
|
-
mask &=
|
|
199
|
+
mask &= mask - 1;
|
|
53
200
|
const code = load<u16>(srcIdx);
|
|
54
201
|
const escaped = load<u32>(SERIALIZE_ESCAPE_TABLE + (code << 2));
|
|
55
202
|
|
|
@@ -69,7 +216,7 @@ export function serializeString_SWAR(src: string): void {
|
|
|
69
216
|
}
|
|
70
217
|
continue;
|
|
71
218
|
}
|
|
72
|
-
mask &=
|
|
219
|
+
mask &= mask - 1;
|
|
73
220
|
|
|
74
221
|
const code = load<u16>(srcIdx - 1);
|
|
75
222
|
if (code < 0xd800 || code > 0xdfff) continue;
|
|
@@ -101,7 +248,7 @@ export function serializeString_SWAR(src: string): void {
|
|
|
101
248
|
while (srcStart <= srcEnd - 2) {
|
|
102
249
|
const code = load<u16>(srcStart);
|
|
103
250
|
|
|
104
|
-
if (code ==
|
|
251
|
+
if (code == BACK_SLASH || code == QUOTE || code < 32) {
|
|
105
252
|
const escaped = load<u32>(SERIALIZE_ESCAPE_TABLE + (code << 2));
|
|
106
253
|
if ((escaped & 0xffff) != BACK_SLASH) {
|
|
107
254
|
bs.growSize(10);
|
|
@@ -144,8 +291,6 @@ export function serializeString_SWAR(src: string): void {
|
|
|
144
291
|
|
|
145
292
|
store<u16>(bs.offset, 34); // "
|
|
146
293
|
bs.offset += 2;
|
|
147
|
-
|
|
148
|
-
if (isDefined(JSON_CACHE)) sc.insertCached(changetype<usize>(src), srcStart, srcSize);
|
|
149
294
|
}
|
|
150
295
|
|
|
151
296
|
// @ts-expect-error: @inline is a valid decorator
|
|
@@ -158,8 +303,10 @@ export function serializeString_SWAR(src: string): void {
|
|
|
158
303
|
|
|
159
304
|
// @ts-expect-error: @inline is a valid decorator
|
|
160
305
|
@inline export function detect_escapable_u64_swar_safe(block: u64): u64 {
|
|
306
|
+
const hi = block & 0xff00_ff00_ff00_ff00;
|
|
161
307
|
const lo = block & 0x00ff_00ff_00ff_00ff;
|
|
162
308
|
const ascii_mask = ((lo - 0x0020_0020_0020_0020) | ((lo ^ 0x0022_0022_0022_0022) - 0x0001_0001_0001_0001) | ((lo ^ 0x005c_005c_005c_005c) - 0x0001_0001_0001_0001)) & (0x0080_0080_0080_0080 & ~lo);
|
|
309
|
+
if (hi == 0) return ascii_mask;
|
|
163
310
|
const hi_mask = ((block - 0x0100_0100_0100_0100) & ~block & 0x8000_8000_8000_8000) ^ 0x8000_8000_8000_8000;
|
|
164
311
|
return (ascii_mask & (~hi_mask >> 8)) | hi_mask;
|
|
165
312
|
}
|
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAA4G,eAAe,EAA8G,MAAM,EAAE,OAAO,EAAS,MAAM,EAA6C,MAAM,uCAAuC,CAAC;AAC3X,OAAO,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAC;AAK7D,OAAO,EAA2B,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAE7E,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAA4G,eAAe,EAA8G,MAAM,EAAE,OAAO,EAAS,MAAM,EAA6C,MAAM,uCAAuC,CAAC;AAC3X,OAAO,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAC;AAK7D,OAAO,EAA2B,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAE7E,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAuJvC,qBAAa,aAAc,SAAQ,OAAO;IACxC,MAAM,CAAC,EAAE,EAAE,aAAa,CAAuB;IAExC,OAAO,EAAG,OAAO,CAAC;IAClB,OAAO,EAAG,MAAM,CAAC;IACjB,MAAM,EAAG,MAAM,CAAC;IAChB,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAA+B;IAC7D,MAAM,EAAG,MAAM,CAAC;IAChB,OAAO,EAAE,SAAS,CAAmB;IACrC,OAAO,EAAE,eAAe,EAAE,CAAM;IAChC,cAAc,EAAE,MAAM,EAAE,CAAM;IAE9B,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,CAAqB;IAEvD,OAAO,CAAC,4BAA4B;IA6CpC,wBAAwB,CAAC,IAAI,EAAE,gBAAgB,GAAG,IAAI;IAYtD,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,cAAoB,GAAG,MAAM;IAsC3E,qBAAqB,CAAC,IAAI,EAAE,gBAAgB,GAAG,IAAI;IAuiDnD,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAItC,oBAAoB,CAAC,IAAI,EAAE,gBAAgB,GAAG,IAAI;IA4ClD,oBAAoB,CAAC,IAAI,EAAE,eAAe,GAAG,IAAI;IAIjD,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAI/B,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IA+J9B,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,OAAe,GAAG,MAAM,EAAE;IA0BxD,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB,GAAG,OAAO;CAc3D;AA4BD,MAAM,CAAC,OAAO,OAAO,WAAY,SAAQ,SAAS;IAChD,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAyBvD,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;CAwDjC;AA+MD,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAO9C"}
|
package/transform/lib/index.js
CHANGED
|
@@ -75,6 +75,9 @@ function getSerializeCall(type, realName) {
|
|
|
75
75
|
}
|
|
76
76
|
return needsReferenceLoad(type) ? `JSON.__serialize<${type}>(changetype<${type}>(load<usize>(ptr, offsetof<this>(${JSON.stringify(realName)}))));\n` : `JSON.__serialize<${type}>(load<${type}>(ptr, offsetof<this>(${JSON.stringify(realName)})));\n`;
|
|
77
77
|
}
|
|
78
|
+
function isRawType(type) {
|
|
79
|
+
return type == "JSON.Raw" || type == "Raw";
|
|
80
|
+
}
|
|
78
81
|
const CUSTOM_JSON_KINDS = new Set(["any", "string", "number", "object", "array", "boolean", "null", "any | null", "string | null", "number | null", "object | null", "array | null", "boolean | null"]);
|
|
79
82
|
function parseCustomJsonKind(method, decoratorName) {
|
|
80
83
|
const decorator = method.decorators?.find((v) => v.name.text.toLowerCase() == decoratorName);
|
|
@@ -498,7 +501,7 @@ export class JSONTransform extends Visitor {
|
|
|
498
501
|
mem.type = type;
|
|
499
502
|
mem.value = value;
|
|
500
503
|
mem.node = member;
|
|
501
|
-
mem.byteSize =
|
|
504
|
+
mem.byteSize = estimatedSerializedByteSize(mem.type, source, this.parser);
|
|
502
505
|
mem.custom = schema.deps.some((dep) => dep?.name == stripNull(type) && dep.custom);
|
|
503
506
|
this.schema.byteSize += mem.byteSize;
|
|
504
507
|
if (member.decorators) {
|
|
@@ -682,8 +685,14 @@ export class JSONTransform extends Visitor {
|
|
|
682
685
|
sortedMembers.null.push(member);
|
|
683
686
|
if (isString(type) || type == "Date")
|
|
684
687
|
sortedMembers.string.push(member);
|
|
685
|
-
else if (type
|
|
688
|
+
else if (isRawType(type)) {
|
|
689
|
+
sortedMembers.string.push(member);
|
|
690
|
+
sortedMembers.number.push(member);
|
|
691
|
+
sortedMembers.boolean.push(member);
|
|
692
|
+
sortedMembers.null.push(member);
|
|
686
693
|
sortedMembers.object.push(member);
|
|
694
|
+
sortedMembers.array.push(member);
|
|
695
|
+
}
|
|
687
696
|
else if (isBoolean(type) || type.startsWith("JSON.Box<bool"))
|
|
688
697
|
sortedMembers.boolean.push(member);
|
|
689
698
|
else if (isPrimitive(type) || type.startsWith("JSON.Box<") || isEnum(type, this.sources.get(this.schema.node.range.source), this.parser))
|
|
@@ -763,7 +772,7 @@ export class JSONTransform extends Visitor {
|
|
|
763
772
|
out.push(` if (load<u16>(${valuePtr}) != 0x22) break;`);
|
|
764
773
|
out.push(` let dateEnd = ${valuePtr} + 2;`);
|
|
765
774
|
out.push(` while (dateEnd < srcEnd) {`);
|
|
766
|
-
out.push(" if (load<u16>(dateEnd) == 0x22 &&
|
|
775
|
+
out.push(" if (load<u16>(dateEnd) == 0x22 && JSON.Util.isUnescapedQuote(dateEnd)) break;");
|
|
767
776
|
out.push(" dateEnd += 2;");
|
|
768
777
|
out.push(" }");
|
|
769
778
|
out.push(" if (dateEnd >= srcEnd) break;");
|
|
@@ -808,7 +817,7 @@ export class JSONTransform extends Visitor {
|
|
|
808
817
|
}
|
|
809
818
|
out.push("}");
|
|
810
819
|
}
|
|
811
|
-
else if (resolvedType
|
|
820
|
+
else if (isRawType(resolvedType)) {
|
|
812
821
|
out.push("{");
|
|
813
822
|
out.push(` const valueStart = ${srcPtr};`);
|
|
814
823
|
out.push(" let depth: i32 = 0;");
|
|
@@ -816,7 +825,7 @@ export class JSONTransform extends Visitor {
|
|
|
816
825
|
out.push(` while (${srcPtr} < srcEnd) {`);
|
|
817
826
|
out.push(` const code = load<u16>(${srcPtr});`);
|
|
818
827
|
out.push(" if (inString) {");
|
|
819
|
-
out.push(` if (code == 0x22 &&
|
|
828
|
+
out.push(` if (code == 0x22 && JSON.Util.isUnescapedQuote(${srcPtr})) inString = false;`);
|
|
820
829
|
out.push(` ${srcPtr} += 2;`);
|
|
821
830
|
out.push(" continue;");
|
|
822
831
|
out.push(" }");
|
|
@@ -1181,7 +1190,7 @@ export class JSONTransform extends Visitor {
|
|
|
1181
1190
|
DESERIALIZE += indent + " let code = load<u16>(srcStart);\n";
|
|
1182
1191
|
DESERIALIZE += indent + " while (JSON.Util.isSpace(code)) code = load<u16>(srcStart += 2);\n";
|
|
1183
1192
|
DESERIALIZE += indent + " if (keyStart == 0) {\n";
|
|
1184
|
-
DESERIALIZE += indent + " if (code == 34 &&
|
|
1193
|
+
DESERIALIZE += indent + " if (code == 34 && JSON.Util.isUnescapedQuote(srcStart)) {\n";
|
|
1185
1194
|
DESERIALIZE += indent + " if (isKey) {\n";
|
|
1186
1195
|
DESERIALIZE += indent + " keyStart = lastIndex;\n";
|
|
1187
1196
|
DESERIALIZE += indent + " keyEnd = srcStart;\n";
|
|
@@ -1286,7 +1295,7 @@ export class JSONTransform extends Visitor {
|
|
|
1286
1295
|
DESERIALIZE += " srcStart += 2;\n";
|
|
1287
1296
|
DESERIALIZE += " while (srcStart < srcEnd) {\n";
|
|
1288
1297
|
DESERIALIZE += " const code = load<u16>(srcStart);\n";
|
|
1289
|
-
DESERIALIZE += " if (code == 34 &&
|
|
1298
|
+
DESERIALIZE += " if (code == 34 && JSON.Util.isUnescapedQuote(srcStart)) {\n";
|
|
1290
1299
|
if (DEBUG > 1)
|
|
1291
1300
|
DESERIALIZE += ' console.log("Value (string, ' + ++id + '): " + JSON.Util.ptrToStr(lastIndex, srcStart + 2));';
|
|
1292
1301
|
generateGroups(sortedMembers.string, (group) => {
|
|
@@ -1385,7 +1394,7 @@ export class JSONTransform extends Visitor {
|
|
|
1385
1394
|
DESERIALIZE += " const code = load<u16>(srcStart);\n";
|
|
1386
1395
|
DESERIALIZE += " if (code == 34) {\n";
|
|
1387
1396
|
DESERIALIZE += " srcStart += 2;\n";
|
|
1388
|
-
DESERIALIZE += " while (!(load<u16>(srcStart) == 34 &&
|
|
1397
|
+
DESERIALIZE += " while (!(load<u16>(srcStart) == 34 && JSON.Util.isUnescapedQuote(srcStart))) srcStart += 2;\n";
|
|
1389
1398
|
DESERIALIZE += " } else if (code == 125) {\n";
|
|
1390
1399
|
DESERIALIZE += " if (--depth == 0) {\n";
|
|
1391
1400
|
DESERIALIZE += " srcStart += 2;\n";
|
|
@@ -1439,7 +1448,7 @@ export class JSONTransform extends Visitor {
|
|
|
1439
1448
|
DESERIALIZE += " const code = load<u16>(srcStart);\n";
|
|
1440
1449
|
DESERIALIZE += " if (code == 34) {\n";
|
|
1441
1450
|
DESERIALIZE += " srcStart += 2;\n";
|
|
1442
|
-
DESERIALIZE += " while (!(load<u16>(srcStart) == 34 &&
|
|
1451
|
+
DESERIALIZE += " while (!(load<u16>(srcStart) == 34 && JSON.Util.isUnescapedQuote(srcStart))) srcStart += 2;\n";
|
|
1443
1452
|
DESERIALIZE += " } else if (code == 93) {\n";
|
|
1444
1453
|
DESERIALIZE += " if (--depth == 0) {\n";
|
|
1445
1454
|
DESERIALIZE += " srcStart += 2;\n";
|
|
@@ -1495,7 +1504,10 @@ export class JSONTransform extends Visitor {
|
|
|
1495
1504
|
const first = group[0];
|
|
1496
1505
|
const fName = first.alias || first.name;
|
|
1497
1506
|
DESERIALIZE += indent + " if (" + (first.generic ? "isBoolean<" + first.type + ">() && " : "") + getComparison(fName) + ") { // " + fName + "\n";
|
|
1498
|
-
if (
|
|
1507
|
+
if (isRawType(first.type)) {
|
|
1508
|
+
DESERIALIZE += indent + " store<" + first.type + ">(changetype<usize>(out), JSON.__deserialize<" + first.type + ">(srcStart - 8, srcStart), offsetof<this>(" + JSON.stringify(first.name) + "));\n";
|
|
1509
|
+
}
|
|
1510
|
+
else if (first.type.startsWith("JSON.Box<bool") || first.type.startsWith("JSON.Box<boolean") || first.type.startsWith("Box<bool") || first.type.startsWith("Box<boolean")) {
|
|
1499
1511
|
DESERIALIZE += indent + " store<" + first.type + ">(changetype<usize>(out), changetype<" + first.type + ">(JSON.Box.from<bool>(true)), offsetof<this>(" + JSON.stringify(first.name) + "));\n";
|
|
1500
1512
|
}
|
|
1501
1513
|
else {
|
|
@@ -1509,7 +1521,10 @@ export class JSONTransform extends Visitor {
|
|
|
1509
1521
|
const mem = group[i];
|
|
1510
1522
|
const memName = mem.alias || mem.name;
|
|
1511
1523
|
DESERIALIZE += indent + " else if (" + (mem.generic ? "isBoolean<" + mem.type + ">() && " : "") + getComparison(memName) + ") { // " + memName + "\n";
|
|
1512
|
-
if (
|
|
1524
|
+
if (isRawType(mem.type)) {
|
|
1525
|
+
DESERIALIZE += indent + " store<" + mem.type + ">(changetype<usize>(out), JSON.__deserialize<" + mem.type + ">(srcStart - 8, srcStart), offsetof<this>(" + JSON.stringify(mem.name) + "));\n";
|
|
1526
|
+
}
|
|
1527
|
+
else if (mem.type.startsWith("JSON.Box<bool") || mem.type.startsWith("JSON.Box<boolean") || mem.type.startsWith("Box<bool") || mem.type.startsWith("Box<boolean")) {
|
|
1513
1528
|
DESERIALIZE += indent + " store<" + mem.type + ">(changetype<usize>(out), changetype<" + mem.type + ">(JSON.Box.from<bool>(true)), offsetof<this>(" + JSON.stringify(mem.name) + "));\n";
|
|
1514
1529
|
}
|
|
1515
1530
|
else {
|
|
@@ -1549,7 +1564,10 @@ export class JSONTransform extends Visitor {
|
|
|
1549
1564
|
const first = group[0];
|
|
1550
1565
|
const fName = first.alias || first.name;
|
|
1551
1566
|
DESERIALIZE += indent + " if (" + (first.generic ? "isBoolean<" + first.type + ">() && " : "") + getComparison(fName) + ") { // " + fName + "\n";
|
|
1552
|
-
if (
|
|
1567
|
+
if (isRawType(first.type)) {
|
|
1568
|
+
DESERIALIZE += indent + " store<" + first.type + ">(changetype<usize>(out), JSON.__deserialize<" + first.type + ">(srcStart - 10, srcStart), offsetof<this>(" + JSON.stringify(first.name) + "));\n";
|
|
1569
|
+
}
|
|
1570
|
+
else if (first.type.startsWith("JSON.Box<bool") || first.type.startsWith("JSON.Box<boolean") || first.type.startsWith("Box<bool") || first.type.startsWith("Box<boolean")) {
|
|
1553
1571
|
DESERIALIZE += indent + " store<" + first.type + ">(changetype<usize>(out), changetype<" + first.type + ">(JSON.Box.from<bool>(false)), offsetof<this>(" + JSON.stringify(first.name) + "));\n";
|
|
1554
1572
|
}
|
|
1555
1573
|
else {
|
|
@@ -1563,7 +1581,10 @@ export class JSONTransform extends Visitor {
|
|
|
1563
1581
|
const mem = group[i];
|
|
1564
1582
|
const memName = mem.alias || mem.name;
|
|
1565
1583
|
DESERIALIZE += indent + " else if (" + (mem.generic ? "isBoolean<" + mem.type + ">() && " : "") + getComparison(memName) + ") { // " + memName + "\n";
|
|
1566
|
-
if (
|
|
1584
|
+
if (isRawType(mem.type)) {
|
|
1585
|
+
DESERIALIZE += indent + " store<" + mem.type + ">(changetype<usize>(out), JSON.__deserialize<" + mem.type + ">(srcStart - 10, srcStart), offsetof<this>(" + JSON.stringify(mem.name) + "));\n";
|
|
1586
|
+
}
|
|
1587
|
+
else if (mem.type.startsWith("JSON.Box<bool") || mem.type.startsWith("JSON.Box<boolean") || mem.type.startsWith("Box<bool") || mem.type.startsWith("Box<boolean")) {
|
|
1567
1588
|
DESERIALIZE += indent + " store<" + mem.type + ">(changetype<usize>(out), changetype<" + mem.type + ">(JSON.Box.from<bool>(false)), offsetof<this>(" + JSON.stringify(mem.name) + "));\n";
|
|
1568
1589
|
}
|
|
1569
1590
|
else {
|
|
@@ -1602,7 +1623,12 @@ export class JSONTransform extends Visitor {
|
|
|
1602
1623
|
const first = group[0];
|
|
1603
1624
|
const fName = first.alias || first.name;
|
|
1604
1625
|
DESERIALIZE += indent + " if (" + (first.generic ? "isNullable<" + first.type + ">() && " : "") + getComparison(fName) + ") { // " + fName + "\n";
|
|
1605
|
-
|
|
1626
|
+
if (isRawType(first.type) && !first.node.type.isNullable) {
|
|
1627
|
+
DESERIALIZE += indent + " store<" + first.type + ">(changetype<usize>(out), JSON.__deserialize<" + first.type + ">(srcStart - 8, srcStart), offsetof<this>(" + JSON.stringify(first.name) + "));\n";
|
|
1628
|
+
}
|
|
1629
|
+
else {
|
|
1630
|
+
DESERIALIZE += indent + " store<usize>(changetype<usize>(out), 0, offsetof<this>(" + JSON.stringify(first.name) + "));\n";
|
|
1631
|
+
}
|
|
1606
1632
|
DESERIALIZE += indent + " srcStart += 2;\n";
|
|
1607
1633
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
1608
1634
|
DESERIALIZE += indent + " break;\n";
|
|
@@ -1611,7 +1637,12 @@ export class JSONTransform extends Visitor {
|
|
|
1611
1637
|
const mem = group[i];
|
|
1612
1638
|
const memName = mem.alias || mem.name;
|
|
1613
1639
|
DESERIALIZE += indent + " else if (" + (mem.generic ? "isNullable<" + mem.type + ">() && " : "") + getComparison(memName) + ") { // " + memName + "\n";
|
|
1614
|
-
|
|
1640
|
+
if (isRawType(mem.type) && !mem.node.type.isNullable) {
|
|
1641
|
+
DESERIALIZE += indent + " store<" + mem.type + ">(changetype<usize>(out), JSON.__deserialize<" + mem.type + ">(srcStart - 8, srcStart), offsetof<this>(" + JSON.stringify(mem.name) + "));\n";
|
|
1642
|
+
}
|
|
1643
|
+
else {
|
|
1644
|
+
DESERIALIZE += indent + " store<usize>(changetype<usize>(out), 0, offsetof<this>(" + JSON.stringify(mem.name) + "));\n";
|
|
1645
|
+
}
|
|
1615
1646
|
DESERIALIZE += indent + " srcStart += 2;\n";
|
|
1616
1647
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
1617
1648
|
DESERIALIZE += indent + " break;\n";
|
|
@@ -2104,15 +2135,56 @@ function sizeof(type) {
|
|
|
2104
2135
|
return 20;
|
|
2105
2136
|
else if (type == "i32")
|
|
2106
2137
|
return 22;
|
|
2138
|
+
else if (type == "usize")
|
|
2139
|
+
return 40;
|
|
2140
|
+
else if (type == "isize")
|
|
2141
|
+
return 42;
|
|
2107
2142
|
else if (type == "u64")
|
|
2108
2143
|
return 40;
|
|
2109
2144
|
else if (type == "i64")
|
|
2110
|
-
return
|
|
2145
|
+
return 42;
|
|
2146
|
+
else if (type == "f32")
|
|
2147
|
+
return 34;
|
|
2148
|
+
else if (type == "f64")
|
|
2149
|
+
return 66;
|
|
2111
2150
|
else if (type == "bool" || type == "boolean")
|
|
2112
2151
|
return 10;
|
|
2113
2152
|
else
|
|
2114
2153
|
return 0;
|
|
2115
2154
|
}
|
|
2155
|
+
function estimatedSerializedByteSize(type, source, parser) {
|
|
2156
|
+
const trimmed = type.trim();
|
|
2157
|
+
const baseType = stripNull(trimmed);
|
|
2158
|
+
const nullable = trimmed != baseType;
|
|
2159
|
+
let estimated = sizeof(baseType);
|
|
2160
|
+
if (estimated == 0) {
|
|
2161
|
+
if (isEnum(baseType, source, parser)) {
|
|
2162
|
+
estimated = 22;
|
|
2163
|
+
}
|
|
2164
|
+
else if (baseType == "Date") {
|
|
2165
|
+
estimated = 52;
|
|
2166
|
+
}
|
|
2167
|
+
else if (isString(baseType)) {
|
|
2168
|
+
estimated = 4;
|
|
2169
|
+
}
|
|
2170
|
+
else if (isArray(baseType) || baseType.startsWith("Map<")) {
|
|
2171
|
+
estimated = 4;
|
|
2172
|
+
}
|
|
2173
|
+
else if (baseType == "JSON.Obj" || baseType == "Obj" || baseType == "JSON.Raw" || baseType == "Raw" || baseType == "JSON.Value" || baseType == "Value") {
|
|
2174
|
+
estimated = 4;
|
|
2175
|
+
}
|
|
2176
|
+
else if (baseType == "ArrayBuffer" || needsReferenceLoad(baseType)) {
|
|
2177
|
+
estimated = 4;
|
|
2178
|
+
}
|
|
2179
|
+
else {
|
|
2180
|
+
estimated = 4;
|
|
2181
|
+
}
|
|
2182
|
+
}
|
|
2183
|
+
if (nullable) {
|
|
2184
|
+
estimated = Math.max(estimated, 8);
|
|
2185
|
+
}
|
|
2186
|
+
return estimated;
|
|
2187
|
+
}
|
|
2116
2188
|
function isPrimitive(type) {
|
|
2117
2189
|
const primitiveTypes = ["u8", "u16", "u32", "u64", "i8", "i16", "i32", "i64", "f32", "f64", "bool", "boolean"];
|
|
2118
2190
|
return primitiveTypes.some((v) => type.startsWith(v));
|