json-as 1.3.6 → 1.3.8
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 +45 -0
- package/README.md +1 -1
- package/assembly/deserialize/helpers/uint.ts +4 -1
- package/assembly/deserialize/index/arbitrary.ts +7 -3
- package/assembly/deserialize/index/array.ts +42 -17
- package/assembly/deserialize/index/bool.ts +1 -1
- package/assembly/deserialize/index/date.ts +1 -1
- package/assembly/deserialize/index/float.ts +40 -1
- package/assembly/deserialize/index/integer.ts +68 -1
- package/assembly/deserialize/index/map.ts +1 -1
- package/assembly/deserialize/index/object.ts +1 -1
- package/assembly/deserialize/index/raw.ts +1 -1
- package/assembly/deserialize/index/set.ts +1 -1
- package/assembly/deserialize/index/staticarray.ts +4 -1
- package/assembly/deserialize/index/string.ts +32 -4
- package/assembly/deserialize/index/struct.ts +1 -1
- package/assembly/deserialize/index/typedarray.ts +30 -10
- package/assembly/deserialize/index/unsigned.ts +78 -1
- package/assembly/deserialize/index.ts +1 -0
- package/assembly/deserialize/{simple → naive}/array/arbitrary.ts +24 -5
- package/assembly/deserialize/{simple → naive}/array/array.ts +8 -2
- package/assembly/deserialize/naive/array/bool.ts +68 -0
- package/assembly/deserialize/{simple → naive}/array/box.ts +8 -2
- package/assembly/deserialize/naive/array/float.ts +63 -0
- package/assembly/deserialize/{simple → naive}/array/generic.ts +14 -7
- package/assembly/deserialize/naive/array/integer.ts +86 -0
- package/assembly/deserialize/naive/array/map.ts +47 -0
- package/assembly/deserialize/naive/array/object.ts +47 -0
- package/assembly/deserialize/{simple → naive}/array/raw.ts +34 -7
- package/assembly/deserialize/naive/array/string.ts +69 -0
- package/assembly/deserialize/naive/array/struct.ts +47 -0
- package/assembly/deserialize/{simple → naive}/array.ts +15 -10
- package/assembly/deserialize/{simple → naive}/bool.ts +6 -2
- package/assembly/deserialize/naive/float.ts +135 -0
- package/assembly/deserialize/{simple → naive}/integer.ts +10 -2
- package/assembly/deserialize/{simple → naive}/map.ts +106 -27
- package/assembly/deserialize/{simple → naive}/object.ts +65 -19
- package/assembly/deserialize/{simple → naive}/raw.ts +4 -1
- package/assembly/deserialize/{simple → naive}/set.ts +49 -19
- package/assembly/deserialize/{simple → naive}/staticarray/array.ts +1 -1
- package/assembly/deserialize/{simple → naive}/staticarray/bool.ts +1 -1
- package/assembly/deserialize/{simple → naive}/staticarray/float.ts +1 -1
- package/assembly/deserialize/{simple → naive}/staticarray/integer.ts +1 -1
- package/assembly/deserialize/{simple → naive}/staticarray/string.ts +11 -3
- package/assembly/deserialize/{simple → naive}/staticarray/struct.ts +1 -2
- package/assembly/deserialize/{simple → naive}/staticarray.ts +68 -18
- package/assembly/deserialize/naive/string.ts +199 -0
- package/assembly/deserialize/{simple → naive}/struct.ts +5 -1
- package/assembly/deserialize/{simple → naive}/typedarray.ts +17 -4
- package/assembly/deserialize/{simple → naive}/unsigned.ts +10 -15
- package/assembly/deserialize/simd/array/integer.ts +339 -62
- package/assembly/deserialize/simd/float.ts +303 -0
- package/assembly/deserialize/simd/integer.ts +233 -0
- package/assembly/deserialize/simd/string.ts +266 -107
- package/assembly/deserialize/swar/array/arbitrary.ts +11 -3
- package/assembly/deserialize/swar/array/array.ts +40 -9
- package/assembly/deserialize/swar/array/bool.ts +28 -5
- package/assembly/deserialize/swar/array/box.ts +11 -3
- package/assembly/deserialize/swar/array/float.ts +295 -7
- package/assembly/deserialize/swar/array/generic.ts +28 -7
- package/assembly/deserialize/swar/array/integer.ts +363 -112
- package/assembly/deserialize/swar/array/map.ts +11 -3
- package/assembly/deserialize/swar/array/object.ts +37 -25
- package/assembly/deserialize/swar/array/raw.ts +11 -3
- package/assembly/deserialize/swar/array/shared.ts +63 -14
- package/assembly/deserialize/swar/array/string.ts +140 -7
- package/assembly/deserialize/swar/array/struct.ts +66 -12
- package/assembly/deserialize/swar/array.ts +12 -51
- package/assembly/deserialize/swar/float.ts +304 -0
- package/assembly/deserialize/swar/integer.ts +246 -0
- package/assembly/deserialize/swar/string.ts +213 -294
- package/assembly/deserialize/swar/typedarray.ts +224 -0
- package/assembly/index.d.ts +3 -1
- package/assembly/index.ts +402 -261
- package/assembly/serialize/index/array.ts +1 -1
- package/assembly/serialize/index/bool.ts +1 -1
- package/assembly/serialize/index/date.ts +1 -1
- package/assembly/serialize/index/float.ts +5 -1
- package/assembly/serialize/index/integer.ts +1 -1
- package/assembly/serialize/index/map.ts +1 -1
- package/assembly/serialize/index/raw.ts +1 -1
- package/assembly/serialize/index/set.ts +1 -1
- package/assembly/serialize/index/staticarray.ts +1 -1
- package/assembly/serialize/index/string.ts +1 -1
- package/assembly/serialize/index/struct.ts +1 -1
- package/assembly/serialize/index/typedarray.ts +21 -12
- package/assembly/serialize/index.ts +1 -0
- package/assembly/serialize/naive/array.ts +351 -0
- package/assembly/serialize/{simple → naive}/float.ts +4 -1
- package/assembly/serialize/naive/integer.ts +19 -0
- package/assembly/serialize/{simple → naive}/map.ts +6 -2
- package/assembly/serialize/{simple → naive}/raw.ts +5 -1
- package/assembly/serialize/{simple → naive}/set.ts +6 -1
- package/assembly/serialize/{simple → naive}/staticarray.ts +6 -1
- package/assembly/serialize/{simple → naive}/string.ts +1 -2
- package/assembly/serialize/{simple → naive}/typedarray.ts +10 -3
- package/assembly/serialize/simd/string.ts +6 -2
- package/assembly/serialize/swar/string.ts +15 -141
- package/assembly/util/atoi-fast.ts +81 -0
- package/assembly/util/concat.ts +5 -1
- package/assembly/util/dragonbox-cache.ts +443 -2
- package/assembly/util/dragonbox.ts +53 -17
- package/assembly/util/itoa-fast.ts +241 -0
- package/assembly/util/masks.ts +18 -1
- package/assembly/util/parsefloat-fast.ts +167 -0
- package/assembly/util/scanValueEnd.ts +78 -0
- package/assembly/util/scientific.ts +132 -0
- package/assembly/util/simd-int.ts +191 -0
- package/assembly/util/snp.ts +4 -1
- package/assembly/util/swar-int.ts +248 -0
- package/assembly/util/swar.ts +13 -3
- package/lib/as-bs.ts +27 -6
- package/package.json +15 -11
- package/transform/lib/builder.d.ts.map +1 -1
- package/transform/lib/builder.js +13 -5
- package/transform/lib/builder.js.map +1 -1
- package/transform/lib/index.d.ts +5 -0
- package/transform/lib/index.d.ts.map +1 -1
- package/transform/lib/index.js +1046 -340
- package/transform/lib/index.js.map +1 -1
- package/transform/lib/linkers/alias.d.ts.map +1 -1
- package/transform/lib/linkers/alias.js.map +1 -1
- package/transform/lib/linkers/custom.d.ts.map +1 -1
- package/transform/lib/linkers/custom.js +3 -2
- package/transform/lib/linkers/custom.js.map +1 -1
- package/transform/lib/linkers/imports.d.ts.map +1 -1
- package/transform/lib/linkers/imports.js.map +1 -1
- package/transform/lib/types.d.ts.map +1 -1
- package/transform/lib/types.js +54 -16
- package/transform/lib/types.js.map +1 -1
- package/transform/lib/util.d.ts.map +1 -1
- package/transform/lib/util.js +1 -1
- package/transform/lib/util.js.map +1 -1
- package/transform/lib/visitor.d.ts.map +1 -1
- package/transform/lib/visitor.js +2 -1
- package/transform/lib/visitor.js.map +1 -1
- package/assembly/custom/util.ts +0 -310
- package/assembly/deserialize/simple/arbitrary.ts +0 -23
- package/assembly/deserialize/simple/array/bool.ts +0 -17
- package/assembly/deserialize/simple/array/float.ts +0 -28
- package/assembly/deserialize/simple/array/integer.ts +0 -27
- package/assembly/deserialize/simple/array/map.ts +0 -28
- package/assembly/deserialize/simple/array/object.ts +0 -28
- package/assembly/deserialize/simple/array/string.ts +0 -23
- package/assembly/deserialize/simple/array/struct.ts +0 -28
- package/assembly/deserialize/simple/float.ts +0 -201
- package/assembly/deserialize/simple/string.ts +0 -132
- package/assembly/serialize/simple/arbitrary.ts +0 -79
- package/assembly/serialize/simple/array.ts +0 -86
- package/assembly/serialize/simple/integer.ts +0 -20
- package/assembly/serialize/simple/object.ts +0 -42
- /package/assembly/deserialize/{simple → naive}/date.ts +0 -0
- /package/assembly/serialize/{simple → naive}/bool.ts +0 -0
- /package/assembly/serialize/{simple → naive}/date.ts +0 -0
- /package/assembly/serialize/{simple → naive}/struct.ts +0 -0
package/transform/lib/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Node, Type } from "assemblyscript/dist/assemblyscript.js";
|
|
1
|
+
import { Node, Type, } from "assemblyscript/dist/assemblyscript.js";
|
|
2
2
|
import { Transform } from "assemblyscript/dist/transform.js";
|
|
3
3
|
import { readFileSync, writeFileSync } from "fs";
|
|
4
4
|
import * as path from "path";
|
|
@@ -12,9 +12,29 @@ let indent = " ";
|
|
|
12
12
|
let id = 0;
|
|
13
13
|
const WRITE = process.env["JSON_WRITE"]?.trim();
|
|
14
14
|
const rawValue = process.env["JSON_DEBUG"]?.trim();
|
|
15
|
-
const DEBUG = rawValue === "true"
|
|
15
|
+
const DEBUG = rawValue === "true"
|
|
16
|
+
? 1
|
|
17
|
+
: rawValue === "false" || rawValue === ""
|
|
18
|
+
? 0
|
|
19
|
+
: isNaN(Number(rawValue))
|
|
20
|
+
? 0
|
|
21
|
+
: Number(rawValue);
|
|
16
22
|
const STRICT = process.env["JSON_STRICT"] && process.env["JSON_STRICT"] == "true";
|
|
17
23
|
const DEFAULT_JSON_CACHE_BYTES = 1 << 20;
|
|
24
|
+
export function normalizeJsonAsBaseRel(baseRel) {
|
|
25
|
+
if (baseRel.endsWith("json-as")) {
|
|
26
|
+
return "json-as" + baseRel.slice(baseRel.lastIndexOf("json-as") + 7);
|
|
27
|
+
}
|
|
28
|
+
if (!baseRel.startsWith(".") &&
|
|
29
|
+
!baseRel.startsWith("/") &&
|
|
30
|
+
!baseRel.startsWith("json-as")) {
|
|
31
|
+
return "./" + baseRel;
|
|
32
|
+
}
|
|
33
|
+
return baseRel;
|
|
34
|
+
}
|
|
35
|
+
export function computeImportBaseRel(fromDir, packageDir, p = path) {
|
|
36
|
+
return normalizeJsonAsBaseRel(path.posix.join(...p.relative(fromDir, packageDir).split(p.sep)));
|
|
37
|
+
}
|
|
18
38
|
function envFlagDefaultTrue(value) {
|
|
19
39
|
if (!value)
|
|
20
40
|
return true;
|
|
@@ -37,7 +57,11 @@ function parseJSONCacheConfig(value) {
|
|
|
37
57
|
if (!raw)
|
|
38
58
|
return { enabled: false, bytes: 0 };
|
|
39
59
|
const lower = raw.toLowerCase();
|
|
40
|
-
if (lower === "false" ||
|
|
60
|
+
if (lower === "false" ||
|
|
61
|
+
lower === "off" ||
|
|
62
|
+
lower === "no" ||
|
|
63
|
+
lower === "none" ||
|
|
64
|
+
lower === "0") {
|
|
41
65
|
return { enabled: false, bytes: 0 };
|
|
42
66
|
}
|
|
43
67
|
if (lower === "true" || lower === "on" || lower === "yes") {
|
|
@@ -53,7 +77,13 @@ function parseJSONCacheConfig(value) {
|
|
|
53
77
|
throw new Error(`Invalid JSON_CACHE value '${value}'.`);
|
|
54
78
|
}
|
|
55
79
|
const unit = suffix[0];
|
|
56
|
-
const scale = unit == "k" || unit == "K"
|
|
80
|
+
const scale = unit == "k" || unit == "K"
|
|
81
|
+
? 1_000
|
|
82
|
+
: unit == "m" || unit == "M"
|
|
83
|
+
? 1_000_000
|
|
84
|
+
: unit == "g" || unit == "G"
|
|
85
|
+
? 1_000_000_000
|
|
86
|
+
: 1;
|
|
57
87
|
let bytes = amount * scale;
|
|
58
88
|
if (suffix.endsWith("b")) {
|
|
59
89
|
bytes = Math.ceil(bytes / 8);
|
|
@@ -68,15 +98,42 @@ function parseJSONCacheConfig(value) {
|
|
|
68
98
|
}
|
|
69
99
|
const JSON_CACHE_CONFIG = parseJSONCacheConfig(process.env["JSON_CACHE"]);
|
|
70
100
|
function needsReferenceLoad(type) {
|
|
71
|
-
return type == "ArrayBuffer" ||
|
|
101
|
+
return (type == "ArrayBuffer" ||
|
|
102
|
+
type == "Int8Array" ||
|
|
103
|
+
type == "Uint8Array" ||
|
|
104
|
+
type == "Uint8ClampedArray" ||
|
|
105
|
+
type == "Int16Array" ||
|
|
106
|
+
type == "Uint16Array" ||
|
|
107
|
+
type == "Int32Array" ||
|
|
108
|
+
type == "Uint32Array" ||
|
|
109
|
+
type == "Int64Array" ||
|
|
110
|
+
type == "Uint64Array" ||
|
|
111
|
+
type == "Float32Array" ||
|
|
112
|
+
type == "Float64Array");
|
|
72
113
|
}
|
|
73
114
|
function getSerializeCall(type, realName) {
|
|
74
115
|
if (type == "ArrayBuffer") {
|
|
75
116
|
return `JSON.__serialize<ArrayBuffer>(load<ArrayBuffer>(ptr, offsetof<this>(${JSON.stringify(realName)})));\n`;
|
|
76
117
|
}
|
|
77
|
-
return needsReferenceLoad(type)
|
|
118
|
+
return needsReferenceLoad(type)
|
|
119
|
+
? `JSON.__serialize<${type}>(changetype<${type}>(load<usize>(ptr, offsetof<this>(${JSON.stringify(realName)}))));\n`
|
|
120
|
+
: `JSON.__serialize<${type}>(load<${type}>(ptr, offsetof<this>(${JSON.stringify(realName)})));\n`;
|
|
78
121
|
}
|
|
79
|
-
const CUSTOM_JSON_KINDS = new Set([
|
|
122
|
+
const CUSTOM_JSON_KINDS = new Set([
|
|
123
|
+
"any",
|
|
124
|
+
"string",
|
|
125
|
+
"number",
|
|
126
|
+
"object",
|
|
127
|
+
"array",
|
|
128
|
+
"boolean",
|
|
129
|
+
"null",
|
|
130
|
+
"any | null",
|
|
131
|
+
"string | null",
|
|
132
|
+
"number | null",
|
|
133
|
+
"object | null",
|
|
134
|
+
"array | null",
|
|
135
|
+
"boolean | null",
|
|
136
|
+
]);
|
|
80
137
|
function parseCustomJsonKind(method, decoratorName) {
|
|
81
138
|
const decorator = method.decorators?.find((v) => v.name.text.toLowerCase() == decoratorName);
|
|
82
139
|
if (!decorator || !decorator.args || decorator.args.length == 0)
|
|
@@ -84,7 +141,8 @@ function parseCustomJsonKind(method, decoratorName) {
|
|
|
84
141
|
if (decorator.args.length > 1)
|
|
85
142
|
throwError(`@${decoratorName} accepts at most one argument`, decorator.range);
|
|
86
143
|
const arg = decorator.args[0];
|
|
87
|
-
if (arg.kind != NodeKind.Literal ||
|
|
144
|
+
if (arg.kind != NodeKind.Literal ||
|
|
145
|
+
arg.literalKind != 2) {
|
|
88
146
|
throwError(`@${decoratorName} argument must be a string literal like @${decoratorName}("string")`, arg.range);
|
|
89
147
|
}
|
|
90
148
|
const kind = arg.value;
|
|
@@ -172,7 +230,11 @@ export class JSONTransform extends Visitor {
|
|
|
172
230
|
if (isDecoratedBase)
|
|
173
231
|
return;
|
|
174
232
|
this.collectInheritedFieldMembers(baseDecl, baseSource, members, visited);
|
|
175
|
-
const inheritedMembers = baseDecl.members.filter((v) => v.kind === NodeKind.FieldDeclaration &&
|
|
233
|
+
const inheritedMembers = baseDecl.members.filter((v) => v.kind === NodeKind.FieldDeclaration &&
|
|
234
|
+
!v.is(32) &&
|
|
235
|
+
!v.is(512) &&
|
|
236
|
+
!v.is(1024) &&
|
|
237
|
+
!v.decorators?.some((decorator) => decorator.name.text === "omit"));
|
|
176
238
|
for (let i = inheritedMembers.length - 1; i >= 0; i--) {
|
|
177
239
|
const inherited = inheritedMembers[i];
|
|
178
240
|
if (!members.some((member) => member.name.text == inherited.name.text)) {
|
|
@@ -186,7 +248,10 @@ export class JSONTransform extends Visitor {
|
|
|
186
248
|
const name = decorator.name.text;
|
|
187
249
|
return name === "json" || name === "serializable";
|
|
188
250
|
}))
|
|
189
|
-
throw new Error("Class " +
|
|
251
|
+
throw new Error("Class " +
|
|
252
|
+
node.name.text +
|
|
253
|
+
" is missing an @json or @serializable decorator in " +
|
|
254
|
+
node.range.source.internalPath);
|
|
190
255
|
this.visitClassDeclaration(node);
|
|
191
256
|
}
|
|
192
257
|
resolveType(type, source, visited = new Set()) {
|
|
@@ -195,7 +260,9 @@ export class JSONTransform extends Visitor {
|
|
|
195
260
|
return stripped;
|
|
196
261
|
}
|
|
197
262
|
visited.add(stripped);
|
|
198
|
-
const resolvedType = source.aliases
|
|
263
|
+
const resolvedType = source.aliases
|
|
264
|
+
.find((v) => stripNull(v.name) === stripped)
|
|
265
|
+
?.getBaseType();
|
|
199
266
|
if (resolvedType) {
|
|
200
267
|
return this.resolveType(resolvedType, source, visited);
|
|
201
268
|
}
|
|
@@ -234,9 +301,27 @@ export class JSONTransform extends Visitor {
|
|
|
234
301
|
return;
|
|
235
302
|
if (!this.schemas.has(source.internalPath))
|
|
236
303
|
this.schemas.set(source.internalPath, []);
|
|
237
|
-
const members = [
|
|
238
|
-
|
|
239
|
-
|
|
304
|
+
const members = [
|
|
305
|
+
...node.members.filter((v) => v.kind === NodeKind.FieldDeclaration &&
|
|
306
|
+
!v.is(32) &&
|
|
307
|
+
!v.is(512) &&
|
|
308
|
+
!v.is(1024) &&
|
|
309
|
+
!v.decorators?.some((decorator) => decorator.name.text === "omit")),
|
|
310
|
+
];
|
|
311
|
+
const serializers = [
|
|
312
|
+
...node.members.filter((v) => v.kind === NodeKind.MethodDeclaration &&
|
|
313
|
+
v.decorators &&
|
|
314
|
+
v.decorators.some((e) => e.name.text.toLowerCase() ===
|
|
315
|
+
"serializer") &&
|
|
316
|
+
!v.name.text.startsWith("__try")),
|
|
317
|
+
];
|
|
318
|
+
const deserializers = [
|
|
319
|
+
...node.members.filter((v) => v.kind === NodeKind.MethodDeclaration &&
|
|
320
|
+
v.decorators &&
|
|
321
|
+
v.decorators.some((e) => e.name.text.toLowerCase() ===
|
|
322
|
+
"deserializer") &&
|
|
323
|
+
!v.name.text.startsWith("__try")),
|
|
324
|
+
];
|
|
240
325
|
const schema = new Schema();
|
|
241
326
|
schema.node = node;
|
|
242
327
|
schema.name = source.getQualifiedName(node);
|
|
@@ -247,7 +332,10 @@ export class JSONTransform extends Visitor {
|
|
|
247
332
|
const depSearch = schema.deps.find((v) => v.name == extendsName);
|
|
248
333
|
if (depSearch) {
|
|
249
334
|
if (DEBUG > 0)
|
|
250
|
-
console.log("Found " +
|
|
335
|
+
console.log("Found " +
|
|
336
|
+
extendsName +
|
|
337
|
+
" in dependencies of " +
|
|
338
|
+
source.internalPath);
|
|
251
339
|
if (!schema.deps.some((v) => v.name == depSearch.name))
|
|
252
340
|
schema.deps.push(depSearch);
|
|
253
341
|
schema.parent = depSearch;
|
|
@@ -256,16 +344,26 @@ export class JSONTransform extends Visitor {
|
|
|
256
344
|
const internalSearch = source.getClass(extendsName);
|
|
257
345
|
if (internalSearch) {
|
|
258
346
|
if (DEBUG > 0)
|
|
259
|
-
console.log("Found " +
|
|
347
|
+
console.log("Found " +
|
|
348
|
+
extendsName +
|
|
349
|
+
" internally from " +
|
|
350
|
+
source.internalPath);
|
|
260
351
|
if (!this.visitedClasses.has(source.getFullPath(internalSearch))) {
|
|
261
352
|
this.visitClassDeclarationRef(internalSearch);
|
|
262
|
-
this.schemas
|
|
353
|
+
this.schemas
|
|
354
|
+
.get(internalSearch.range.source.internalPath)
|
|
355
|
+
.push(this.schema);
|
|
263
356
|
this.visitClassDeclaration(node);
|
|
264
357
|
return;
|
|
265
358
|
}
|
|
266
|
-
const schem = this.schemas
|
|
359
|
+
const schem = this.schemas
|
|
360
|
+
.get(internalSearch.range.source.internalPath)
|
|
361
|
+
?.find((s) => s.name == extendsName);
|
|
267
362
|
if (!schem)
|
|
268
|
-
throw new Error("Could not find schema for " +
|
|
363
|
+
throw new Error("Could not find schema for " +
|
|
364
|
+
internalSearch.name.text +
|
|
365
|
+
" in " +
|
|
366
|
+
internalSearch.range.source.internalPath);
|
|
269
367
|
schema.deps.push(schem);
|
|
270
368
|
schema.parent = schem;
|
|
271
369
|
}
|
|
@@ -273,7 +371,10 @@ export class JSONTransform extends Visitor {
|
|
|
273
371
|
const externalSearch = source.getImportedClass(extendsName, this.parser);
|
|
274
372
|
if (externalSearch) {
|
|
275
373
|
if (DEBUG > 0)
|
|
276
|
-
console.log("Found " +
|
|
374
|
+
console.log("Found " +
|
|
375
|
+
externalSearch.name.text +
|
|
376
|
+
" externally from " +
|
|
377
|
+
source.internalPath);
|
|
277
378
|
const externalSource = this.sources.get(externalSearch.range.source);
|
|
278
379
|
if (!this.visitedClasses.has(externalSource.getFullPath(externalSearch))) {
|
|
279
380
|
this.visitClassDeclarationRef(externalSearch);
|
|
@@ -281,9 +382,14 @@ export class JSONTransform extends Visitor {
|
|
|
281
382
|
this.visitClassDeclaration(node);
|
|
282
383
|
return;
|
|
283
384
|
}
|
|
284
|
-
const schem = this.schemas
|
|
385
|
+
const schem = this.schemas
|
|
386
|
+
.get(externalSource.internalPath)
|
|
387
|
+
?.find((s) => s.name == extendsName);
|
|
285
388
|
if (!schem)
|
|
286
|
-
throw new Error("Could not find schema for " +
|
|
389
|
+
throw new Error("Could not find schema for " +
|
|
390
|
+
externalSearch.name.text +
|
|
391
|
+
" in " +
|
|
392
|
+
externalSource.internalPath);
|
|
287
393
|
schema.deps.push(schem);
|
|
288
394
|
schema.parent = schem;
|
|
289
395
|
}
|
|
@@ -291,7 +397,10 @@ export class JSONTransform extends Visitor {
|
|
|
291
397
|
const availableSearch = source.getAvailableClass(extendsName, this.parser);
|
|
292
398
|
if (availableSearch) {
|
|
293
399
|
if (DEBUG > 0)
|
|
294
|
-
console.log("Found " +
|
|
400
|
+
console.log("Found " +
|
|
401
|
+
availableSearch.name.text +
|
|
402
|
+
" from available sources for " +
|
|
403
|
+
source.internalPath);
|
|
295
404
|
const availableSource = this.sources.get(availableSearch.range.source);
|
|
296
405
|
if (availableSearch.decorators?.some((decorator) => {
|
|
297
406
|
const name = decorator.name.text;
|
|
@@ -299,11 +408,15 @@ export class JSONTransform extends Visitor {
|
|
|
299
408
|
})) {
|
|
300
409
|
if (!this.visitedClasses.has(availableSource.getFullPath(availableSearch))) {
|
|
301
410
|
this.visitClassDeclarationRef(availableSearch);
|
|
302
|
-
this.schemas
|
|
411
|
+
this.schemas
|
|
412
|
+
.get(availableSource.internalPath)
|
|
413
|
+
.push(this.schema);
|
|
303
414
|
this.visitClassDeclaration(node);
|
|
304
415
|
return;
|
|
305
416
|
}
|
|
306
|
-
const schem = this.schemas
|
|
417
|
+
const schem = this.schemas
|
|
418
|
+
.get(availableSource.internalPath)
|
|
419
|
+
?.find((s) => s.name == extendsName);
|
|
307
420
|
if (schem) {
|
|
308
421
|
schema.deps.push(schem);
|
|
309
422
|
schema.parent = schem;
|
|
@@ -345,7 +458,8 @@ export class JSONTransform extends Visitor {
|
|
|
345
458
|
else if (["JSON.Box", "JSON.Obj", "JSON.Value", "JSON.Raw"].includes(type)) {
|
|
346
459
|
return types;
|
|
347
460
|
}
|
|
348
|
-
else if (node.isGeneric &&
|
|
461
|
+
else if (node.isGeneric &&
|
|
462
|
+
node.typeParameters.some((p) => p.name.text == type)) {
|
|
349
463
|
return types;
|
|
350
464
|
}
|
|
351
465
|
else if (type == node.name.text) {
|
|
@@ -361,7 +475,10 @@ export class JSONTransform extends Visitor {
|
|
|
361
475
|
const depSearch = schema.deps.find((v) => v.name == unknownType);
|
|
362
476
|
if (depSearch) {
|
|
363
477
|
if (DEBUG > 0)
|
|
364
|
-
console.log("Found " +
|
|
478
|
+
console.log("Found " +
|
|
479
|
+
unknownType +
|
|
480
|
+
" in dependencies of " +
|
|
481
|
+
source.internalPath);
|
|
365
482
|
if (!schema.deps.some((v) => v.name == depSearch.name)) {
|
|
366
483
|
schema.deps.push(depSearch);
|
|
367
484
|
}
|
|
@@ -370,37 +487,59 @@ export class JSONTransform extends Visitor {
|
|
|
370
487
|
const internalSearch = source.getClass(unknownType);
|
|
371
488
|
if (internalSearch) {
|
|
372
489
|
if (DEBUG > 0)
|
|
373
|
-
console.log("Found " +
|
|
490
|
+
console.log("Found " +
|
|
491
|
+
unknownType +
|
|
492
|
+
" internally from " +
|
|
493
|
+
source.internalPath);
|
|
374
494
|
if (!this.visitedClasses.has(source.getFullPath(internalSearch))) {
|
|
375
495
|
this.visitClassDeclarationRef(internalSearch);
|
|
376
|
-
const internalSchema = this.schemas
|
|
496
|
+
const internalSchema = this.schemas
|
|
497
|
+
.get(internalSearch.range.source.internalPath)
|
|
498
|
+
?.find((s) => s.name == unknownType);
|
|
377
499
|
schema.deps.push(internalSchema);
|
|
378
|
-
this.schemas
|
|
500
|
+
this.schemas
|
|
501
|
+
.get(internalSearch.range.source.internalPath)
|
|
502
|
+
.push(this.schema);
|
|
379
503
|
this.visitClassDeclaration(node);
|
|
380
504
|
return;
|
|
381
505
|
}
|
|
382
|
-
const schem = this.schemas
|
|
506
|
+
const schem = this.schemas
|
|
507
|
+
.get(internalSearch.range.source.internalPath)
|
|
508
|
+
?.find((s) => s.name == unknownType);
|
|
383
509
|
if (!schem)
|
|
384
|
-
throw new Error("Could not find schema for " +
|
|
510
|
+
throw new Error("Could not find schema for " +
|
|
511
|
+
internalSearch.name.text +
|
|
512
|
+
" in " +
|
|
513
|
+
internalSearch.range.source.internalPath);
|
|
385
514
|
schema.deps.push(schem);
|
|
386
515
|
}
|
|
387
516
|
else {
|
|
388
517
|
const externalSearch = source.getImportedClass(unknownType, this.parser);
|
|
389
518
|
if (externalSearch) {
|
|
390
519
|
if (DEBUG > 0)
|
|
391
|
-
console.log("Found " +
|
|
520
|
+
console.log("Found " +
|
|
521
|
+
externalSearch.name.text +
|
|
522
|
+
" externally from " +
|
|
523
|
+
source.internalPath);
|
|
392
524
|
const externalSource = this.sources.get(externalSearch.range.source);
|
|
393
525
|
if (!this.visitedClasses.has(externalSource.getFullPath(externalSearch))) {
|
|
394
526
|
this.visitClassDeclarationRef(externalSearch);
|
|
395
|
-
const externalSchema = this.schemas
|
|
527
|
+
const externalSchema = this.schemas
|
|
528
|
+
.get(externalSource.internalPath)
|
|
529
|
+
?.find((s) => s.name == unknownType);
|
|
396
530
|
schema.deps.push(externalSchema);
|
|
397
531
|
this.schemas.get(externalSource.internalPath).push(this.schema);
|
|
398
532
|
this.visitClassDeclaration(node);
|
|
399
533
|
return;
|
|
400
534
|
}
|
|
401
|
-
const schem = this.schemas
|
|
535
|
+
const schem = this.schemas
|
|
536
|
+
.get(externalSource.internalPath)
|
|
537
|
+
?.find((s) => s.name == unknownType);
|
|
402
538
|
if (!schem)
|
|
403
|
-
throw new Error("Could not find schema for " +
|
|
539
|
+
throw new Error("Could not find schema for " +
|
|
540
|
+
externalSearch.name.text +
|
|
541
|
+
" in " +
|
|
542
|
+
externalSource.internalPath);
|
|
404
543
|
schema.deps.push(schem);
|
|
405
544
|
}
|
|
406
545
|
}
|
|
@@ -419,11 +558,22 @@ export class JSONTransform extends Visitor {
|
|
|
419
558
|
let DESERIALIZE_CUSTOM = "";
|
|
420
559
|
let SERIALIZE_CUSTOM = "";
|
|
421
560
|
if (DEBUG > 0)
|
|
422
|
-
console.log("Created schema: " +
|
|
561
|
+
console.log("Created schema: " +
|
|
562
|
+
this.schema.name +
|
|
563
|
+
" in file " +
|
|
564
|
+
source.normalizedPath +
|
|
565
|
+
(this.schema.deps.length
|
|
566
|
+
? " with dependencies:\n " +
|
|
567
|
+
this.schema.deps.map((v) => v.name).join("\n ")
|
|
568
|
+
: ""));
|
|
423
569
|
if (serializers.length > 1)
|
|
424
|
-
throwError("Multiple serializers detected for class " +
|
|
570
|
+
throwError("Multiple serializers detected for class " +
|
|
571
|
+
node.name.text +
|
|
572
|
+
" but schemas can only have one serializer!", serializers[1].range);
|
|
425
573
|
if (deserializers.length > 1)
|
|
426
|
-
throwError("Multiple deserializers detected for class " +
|
|
574
|
+
throwError("Multiple deserializers detected for class " +
|
|
575
|
+
node.name.text +
|
|
576
|
+
" but schemas can only have one deserializer!", deserializers[1].range);
|
|
427
577
|
if (serializers.length) {
|
|
428
578
|
this.schema.custom = true;
|
|
429
579
|
const serializer = serializers[0];
|
|
@@ -432,11 +582,24 @@ export class JSONTransform extends Visitor {
|
|
|
432
582
|
this.schema.customJsonKind = serializerJsonKind;
|
|
433
583
|
CustomTransform.visit(serializer);
|
|
434
584
|
if (serializer.signature.parameters.length > 1)
|
|
435
|
-
throwError("Found too many parameters in custom serializer for " +
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
585
|
+
throwError("Found too many parameters in custom serializer for " +
|
|
586
|
+
this.schema.name +
|
|
587
|
+
", but serializers can only accept one parameter of type '" +
|
|
588
|
+
this.schema.name +
|
|
589
|
+
"'!", serializer.signature.parameters[1].range);
|
|
590
|
+
if (serializer.signature.parameters.length > 0 &&
|
|
591
|
+
serializer.signature.parameters[0].type.name.identifier
|
|
592
|
+
.text != node.name.text &&
|
|
593
|
+
serializer.signature.parameters[0].type.name.identifier
|
|
594
|
+
.text != "this")
|
|
595
|
+
throwError("Type of parameter for custom serializer does not match! It should be 'string'either be 'this' or '" +
|
|
596
|
+
this.schema.name +
|
|
597
|
+
"'", serializer.signature.parameters[0].type.range);
|
|
598
|
+
if (!serializer.signature.returnType ||
|
|
599
|
+
!(serializer.signature.returnType).name.identifier.text.includes("string"))
|
|
600
|
+
throwError("Could not find valid return type for serializer in " +
|
|
601
|
+
this.schema.name +
|
|
602
|
+
"!. Set the return type to type 'string' and try again", serializer.signature.returnType.range);
|
|
440
603
|
if (!serializer.decorators.some((v) => v.name.text == "inline")) {
|
|
441
604
|
serializer.decorators.push(Node.createDecorator(Node.createIdentifierExpression("inline", serializer.range), null, serializer.range));
|
|
442
605
|
}
|
|
@@ -446,13 +609,19 @@ export class JSONTransform extends Visitor {
|
|
|
446
609
|
SERIALIZE_CUSTOM += " const savedStackSize = bs.stackSize;\n";
|
|
447
610
|
}
|
|
448
611
|
SERIALIZE_CUSTOM += " const self = changetype<this>(ptr);\n";
|
|
449
|
-
SERIALIZE_CUSTOM +=
|
|
612
|
+
SERIALIZE_CUSTOM +=
|
|
613
|
+
" const data = self." +
|
|
614
|
+
serializer.name.text +
|
|
615
|
+
"(" +
|
|
616
|
+
(serializer.signature.parameters.length ? "self" : "") +
|
|
617
|
+
");\n";
|
|
450
618
|
if (hasCall) {
|
|
451
619
|
SERIALIZE_CUSTOM += " bs.offset = savedOffset;\n";
|
|
452
620
|
SERIALIZE_CUSTOM += " bs.stackSize = savedStackSize;\n";
|
|
453
621
|
}
|
|
454
622
|
SERIALIZE_CUSTOM += " const dataSize = data.length << 1;\n";
|
|
455
|
-
SERIALIZE_CUSTOM +=
|
|
623
|
+
SERIALIZE_CUSTOM +=
|
|
624
|
+
" memory.copy(bs.offset, changetype<usize>(data), dataSize);\n";
|
|
456
625
|
SERIALIZE_CUSTOM += " bs.offset += dataSize;\n";
|
|
457
626
|
SERIALIZE_CUSTOM += " }\n";
|
|
458
627
|
}
|
|
@@ -460,24 +629,43 @@ export class JSONTransform extends Visitor {
|
|
|
460
629
|
this.schema.custom = true;
|
|
461
630
|
const deserializer = deserializers[0];
|
|
462
631
|
const deserializerJsonKind = parseCustomJsonKind(deserializer, "deserializer");
|
|
463
|
-
if (this.schema.customJsonKind != "any" &&
|
|
632
|
+
if (this.schema.customJsonKind != "any" &&
|
|
633
|
+
deserializerJsonKind != "any" &&
|
|
634
|
+
this.schema.customJsonKind != deserializerJsonKind) {
|
|
464
635
|
throwError(`@serializer and @deserializer JSON types for ${this.schema.name} must match`, deserializer.range);
|
|
465
636
|
}
|
|
466
637
|
if (this.schema.customJsonKind == "any")
|
|
467
638
|
this.schema.customJsonKind = deserializerJsonKind;
|
|
468
639
|
if (!deserializer.signature.parameters.length)
|
|
469
|
-
throwError("Could not find any parameters in custom deserializer for " +
|
|
640
|
+
throwError("Could not find any parameters in custom deserializer for " +
|
|
641
|
+
this.schema.name +
|
|
642
|
+
". Deserializers must have one parameter like 'deserializer(data: string): " +
|
|
643
|
+
this.schema.name +
|
|
644
|
+
" {}'", deserializer.range);
|
|
470
645
|
if (deserializer.signature.parameters.length > 1)
|
|
471
|
-
throwError("Found too many parameters in custom deserializer for " +
|
|
472
|
-
|
|
646
|
+
throwError("Found too many parameters in custom deserializer for " +
|
|
647
|
+
this.schema.name +
|
|
648
|
+
", but deserializers can only accept one parameter of type 'string'!", deserializer.signature.parameters[1].range);
|
|
649
|
+
if (deserializer.signature.parameters[0].type.name
|
|
650
|
+
.identifier.text != "string")
|
|
473
651
|
throwError("Type of parameter for custom deserializer does not match! It must be 'string'", deserializer.signature.parameters[0].type.range);
|
|
474
|
-
if (!deserializer.signature.returnType ||
|
|
475
|
-
|
|
652
|
+
if (!deserializer.signature.returnType ||
|
|
653
|
+
!((deserializer.signature.returnType).name.identifier.text.includes(this.schema.name) ||
|
|
654
|
+
(deserializer.signature.returnType).name.identifier.text.includes("this")))
|
|
655
|
+
throwError("Could not find valid return type for deserializer in " +
|
|
656
|
+
this.schema.name +
|
|
657
|
+
"!. Set the return type to type '" +
|
|
658
|
+
this.schema.name +
|
|
659
|
+
"' or 'this' and try again", deserializer.signature.returnType.range);
|
|
476
660
|
if (!deserializer.decorators.some((v) => v.name.text == "inline")) {
|
|
477
661
|
deserializer.decorators.push(Node.createDecorator(Node.createIdentifierExpression("inline", deserializer.range), null, deserializer.range));
|
|
478
662
|
}
|
|
479
|
-
DESERIALIZE_CUSTOM +=
|
|
480
|
-
|
|
663
|
+
DESERIALIZE_CUSTOM +=
|
|
664
|
+
" @inline __DESERIALIZE_CUSTOM(data: string): this {\n";
|
|
665
|
+
DESERIALIZE_CUSTOM +=
|
|
666
|
+
" return inline.always(this." +
|
|
667
|
+
deserializer.name.text +
|
|
668
|
+
"(data));\n";
|
|
481
669
|
DESERIALIZE_CUSTOM += " }\n";
|
|
482
670
|
}
|
|
483
671
|
if (!members.length && !deserializers.length && !serializers.length) {
|
|
@@ -504,11 +692,19 @@ export class JSONTransform extends Visitor {
|
|
|
504
692
|
this.schema.byteSize += mem.byteSize;
|
|
505
693
|
if (member.decorators) {
|
|
506
694
|
for (const decorator of member.decorators) {
|
|
507
|
-
const decoratorName = decorator.name.text
|
|
695
|
+
const decoratorName = decorator.name.text
|
|
696
|
+
.toLowerCase()
|
|
697
|
+
.trim();
|
|
508
698
|
switch (decoratorName) {
|
|
509
699
|
case "alias": {
|
|
510
700
|
const arg = decorator.args[0];
|
|
511
|
-
if (!arg ||
|
|
701
|
+
if (!arg ||
|
|
702
|
+
(arg.kind != NodeKind.Literal &&
|
|
703
|
+
arg.literalKind !=
|
|
704
|
+
2 &&
|
|
705
|
+
arg.literalKind !=
|
|
706
|
+
1 &&
|
|
707
|
+
arg.literalKind != 0))
|
|
512
708
|
throwError("@alias must have an argument of type string or number", member.range);
|
|
513
709
|
mem.alias = arg.value.toString();
|
|
514
710
|
break;
|
|
@@ -544,7 +740,9 @@ export class JSONTransform extends Visitor {
|
|
|
544
740
|
const hasOptionalMembers = hasOmitIfMembers || hasOmitNullMembers;
|
|
545
741
|
const supportsFastOptionalPath = requestedFastPath && hasOptionalMembers;
|
|
546
742
|
const hasTypeParams = !!node.typeParameters && node.typeParameters.length > 0;
|
|
547
|
-
const useFastPath = requestedFastPath &&
|
|
743
|
+
const useFastPath = requestedFastPath &&
|
|
744
|
+
!hasTypeParams &&
|
|
745
|
+
(this.schema.static || supportsFastOptionalPath);
|
|
548
746
|
indent = " ";
|
|
549
747
|
if (this.schema.static == false) {
|
|
550
748
|
if (this.schema.members.some((v) => v.flags.has(PropertyFlags.OmitNull))) {
|
|
@@ -563,7 +761,10 @@ export class JSONTransform extends Visitor {
|
|
|
563
761
|
const realName = member.name;
|
|
564
762
|
const isLast = i == this.schema.members.length - 1;
|
|
565
763
|
if (member.value) {
|
|
566
|
-
if (member.value != "null" &&
|
|
764
|
+
if (member.value != "null" &&
|
|
765
|
+
member.value != "0" &&
|
|
766
|
+
member.value != "0.0" &&
|
|
767
|
+
member.value != "false") {
|
|
567
768
|
INITIALIZE += ` store<${member.type}>(changetype<usize>(this), ${member.value}, offsetof<this>(${JSON.stringify(member.name)}));\n`;
|
|
568
769
|
}
|
|
569
770
|
}
|
|
@@ -593,7 +794,9 @@ export class JSONTransform extends Visitor {
|
|
|
593
794
|
}
|
|
594
795
|
}
|
|
595
796
|
const SIMD_ENABLED = this.program.options.hasFeature(16);
|
|
596
|
-
if (!isRegular &&
|
|
797
|
+
if (!isRegular &&
|
|
798
|
+
!member.flags.has(PropertyFlags.OmitIf) &&
|
|
799
|
+
!member.flags.has(PropertyFlags.OmitNull))
|
|
597
800
|
isRegular = true;
|
|
598
801
|
if (isRegular && isPure) {
|
|
599
802
|
const keyPart = (isFirst ? "{" : ",") + aliasName + ":";
|
|
@@ -617,7 +820,9 @@ export class JSONTransform extends Visitor {
|
|
|
617
820
|
}
|
|
618
821
|
else {
|
|
619
822
|
if (member.flags.has(PropertyFlags.OmitNull)) {
|
|
620
|
-
SERIALIZE +=
|
|
823
|
+
SERIALIZE +=
|
|
824
|
+
indent +
|
|
825
|
+
`if ((block = load<usize>(ptr, offsetof<this>(${JSON.stringify(realName)}))) !== 0) {\n`;
|
|
621
826
|
indentInc();
|
|
622
827
|
const keyPart = aliasName + ":";
|
|
623
828
|
this.schema.byteSize += keyPart.length << 1;
|
|
@@ -638,12 +843,20 @@ export class JSONTransform extends Visitor {
|
|
|
638
843
|
if (member.flags.get(PropertyFlags.OmitIf).kind == NodeKind.Function) {
|
|
639
844
|
const arg = member.flags.get(PropertyFlags.OmitIf);
|
|
640
845
|
arg.declaration.signature.parameters[0].type = Node.createNamedType(Node.createSimpleTypeName("this", node.range), null, false, node.range);
|
|
641
|
-
arg.declaration.signature.returnType.name =
|
|
642
|
-
|
|
846
|
+
arg.declaration.signature.returnType.name =
|
|
847
|
+
Node.createSimpleTypeName("boolean", arg.declaration.signature.returnType.name
|
|
848
|
+
.range);
|
|
849
|
+
SERIALIZE +=
|
|
850
|
+
indent +
|
|
851
|
+
`if (!(${toString(member.flags.get(PropertyFlags.OmitIf))})(this)) {\n`;
|
|
643
852
|
}
|
|
644
853
|
else {
|
|
645
854
|
const expression = member.flags.get(PropertyFlags.OmitIf);
|
|
646
|
-
const rendered = expression.kind == NodeKind.Literal &&
|
|
855
|
+
const rendered = expression.kind == NodeKind.Literal &&
|
|
856
|
+
expression.literalKind ==
|
|
857
|
+
2
|
|
858
|
+
? JSON.stringify(expression.value).slice(1, -1)
|
|
859
|
+
: toString(expression);
|
|
647
860
|
SERIALIZE += indent + `if (!(${rendered})) {\n`;
|
|
648
861
|
}
|
|
649
862
|
indentInc();
|
|
@@ -671,7 +884,9 @@ export class JSONTransform extends Visitor {
|
|
|
671
884
|
};
|
|
672
885
|
for (const member of this.schema.members) {
|
|
673
886
|
const type = stripNull(member.type);
|
|
674
|
-
const customDep = this.schema.deps.find((dep) => dep &&
|
|
887
|
+
const customDep = this.schema.deps.find((dep) => dep &&
|
|
888
|
+
(dep.name == type || dep.name.endsWith("." + type)) &&
|
|
889
|
+
dep.custom);
|
|
675
890
|
const isCustomType = member.custom || !!customDep;
|
|
676
891
|
if (isCustomType || member.generic) {
|
|
677
892
|
addMemberToCustomBucket(sortedMembers, member, member.generic ? "any" : customDep?.customJsonKind || "any");
|
|
@@ -687,7 +902,9 @@ export class JSONTransform extends Visitor {
|
|
|
687
902
|
sortedMembers.object.push(member);
|
|
688
903
|
else if (isBoolean(type) || type.startsWith("JSON.Box<bool"))
|
|
689
904
|
sortedMembers.boolean.push(member);
|
|
690
|
-
else if (isPrimitive(type) ||
|
|
905
|
+
else if (isPrimitive(type) ||
|
|
906
|
+
type.startsWith("JSON.Box<") ||
|
|
907
|
+
isEnum(type, this.sources.get(this.schema.node.range.source), this.parser))
|
|
691
908
|
sortedMembers.number.push(member);
|
|
692
909
|
else if (isArray(type))
|
|
693
910
|
sortedMembers.array.push(member);
|
|
@@ -723,7 +940,7 @@ export class JSONTransform extends Visitor {
|
|
|
723
940
|
const SIGNED_INTEGER_TYPES = ["i8", "i16", "i32", "i64", "isize"];
|
|
724
941
|
const FLOAT_TYPES = ["f32", "f64"];
|
|
725
942
|
const INTEGER_TYPES = [...UNSIGNED_INTEGER_TYPES, ...SIGNED_INTEGER_TYPES];
|
|
726
|
-
const STRING_FIELD_DESERIALIZER =
|
|
943
|
+
const STRING_FIELD_DESERIALIZER = "__deserializeStringField";
|
|
727
944
|
const getArrayValueType = (type) => {
|
|
728
945
|
if (!type.startsWith("Array<") && !type.startsWith("StaticArray<"))
|
|
729
946
|
return null;
|
|
@@ -736,7 +953,9 @@ export class JSONTransform extends Visitor {
|
|
|
736
953
|
const fieldOffset = `offsetof<this>(${JSON.stringify(member.name)})`;
|
|
737
954
|
const valuePtr = keyOffset ? `${srcPtr} + ${keyOffset}` : srcPtr;
|
|
738
955
|
if (INTEGER_TYPES.includes(resolvedType)) {
|
|
739
|
-
const helper = SIGNED_INTEGER_TYPES.includes(resolvedType)
|
|
956
|
+
const helper = SIGNED_INTEGER_TYPES.includes(resolvedType)
|
|
957
|
+
? "__deserializeIntegerField"
|
|
958
|
+
: "__deserializeUnsignedField";
|
|
740
959
|
out.push(`${srcPtr} = ${helper}<${resolvedType}>(${valuePtr}, srcEnd, ${outPtr}, ${fieldOffset});`);
|
|
741
960
|
}
|
|
742
961
|
else if (["string", "String"].includes(resolvedType)) {
|
|
@@ -747,7 +966,7 @@ export class JSONTransform extends Visitor {
|
|
|
747
966
|
out.push(` ${srcPtr} = ${valuePtr} + 8;`);
|
|
748
967
|
out.push(" } else {");
|
|
749
968
|
}
|
|
750
|
-
out.push(` ${srcPtr} = ${STRING_FIELD_DESERIALIZER}<${member.type}>(${valuePtr}, srcEnd, ${outPtr}
|
|
969
|
+
out.push(` ${srcPtr} = ${STRING_FIELD_DESERIALIZER}<${member.type}>(${valuePtr}, srcEnd, ${outPtr}, ${fieldOffset});`);
|
|
751
970
|
if (member.node.type.isNullable) {
|
|
752
971
|
out.push(" }");
|
|
753
972
|
}
|
|
@@ -775,8 +994,11 @@ export class JSONTransform extends Visitor {
|
|
|
775
994
|
}
|
|
776
995
|
out.push("}");
|
|
777
996
|
}
|
|
778
|
-
else if (resolvedType.startsWith("JSON.Box<") ||
|
|
779
|
-
|
|
997
|
+
else if (resolvedType.startsWith("JSON.Box<") ||
|
|
998
|
+
resolvedType.startsWith("Box<")) {
|
|
999
|
+
const innerType = resolvedType
|
|
1000
|
+
.slice(resolvedType.indexOf("<") + 1, -1)
|
|
1001
|
+
.trim();
|
|
780
1002
|
out.push("{");
|
|
781
1003
|
if (member.node.type.isNullable) {
|
|
782
1004
|
out.push(` if (load<u64>(${valuePtr}) == 30399761348886638) {`);
|
|
@@ -788,7 +1010,11 @@ export class JSONTransform extends Visitor {
|
|
|
788
1010
|
out.push(` if (load<u64>(${valuePtr}) == 28429475166421108) {`);
|
|
789
1011
|
out.push(` store<${resolvedType}>(${outPtr}, changetype<${resolvedType}>(JSON.Box.from<${innerType}>(true)), ${fieldOffset});`);
|
|
790
1012
|
out.push(` ${srcPtr} = ${valuePtr} + 8;`);
|
|
791
|
-
out.push(" } else if (load<u64>(" +
|
|
1013
|
+
out.push(" } else if (load<u64>(" +
|
|
1014
|
+
valuePtr +
|
|
1015
|
+
") == 32370086184550502 && load<u16>(" +
|
|
1016
|
+
valuePtr +
|
|
1017
|
+
", 8) == 101) {");
|
|
792
1018
|
out.push(` store<${resolvedType}>(${outPtr}, changetype<${resolvedType}>(JSON.Box.from<${innerType}>(false)), ${fieldOffset});`);
|
|
793
1019
|
out.push(` ${srcPtr} = ${valuePtr} + 10;`);
|
|
794
1020
|
out.push(" } else break;");
|
|
@@ -848,13 +1074,17 @@ export class JSONTransform extends Visitor {
|
|
|
848
1074
|
out.push(`if (load<u64>(${srcPtr}) == 28429475166421108) {`);
|
|
849
1075
|
out.push(` store<${resolvedType}>(${outPtr}, true, ${fieldOffset});`);
|
|
850
1076
|
out.push(` ${srcPtr} += 8;`);
|
|
851
|
-
out.push("} else if (load<u64>(" +
|
|
1077
|
+
out.push("} else if (load<u64>(" +
|
|
1078
|
+
srcPtr +
|
|
1079
|
+
") == 32370086184550502 && load<u16>(" +
|
|
1080
|
+
srcPtr +
|
|
1081
|
+
", 8) == 101) {");
|
|
852
1082
|
out.push(` store<${resolvedType}>(${outPtr}, false, ${fieldOffset});`);
|
|
853
1083
|
out.push(` ${srcPtr} += 10;`);
|
|
854
1084
|
out.push("} else break;");
|
|
855
1085
|
}
|
|
856
1086
|
else if (FLOAT_TYPES.includes(resolvedType)) {
|
|
857
|
-
out.push(`${srcPtr} =
|
|
1087
|
+
out.push(`${srcPtr} = __deserializeFloatField<${resolvedType}>(${valuePtr}, srcEnd, ${outPtr}, ${fieldOffset});`);
|
|
858
1088
|
}
|
|
859
1089
|
else if (resolvedSchema && !resolvedSchema.custom) {
|
|
860
1090
|
if (fastPath) {
|
|
@@ -906,6 +1136,10 @@ export class JSONTransform extends Visitor {
|
|
|
906
1136
|
}
|
|
907
1137
|
else if (resolvedType.startsWith("Array<")) {
|
|
908
1138
|
const valueType = getArrayValueType(resolvedType);
|
|
1139
|
+
const rawInner = resolvedType
|
|
1140
|
+
.slice(resolvedType.indexOf("<") + 1, -1)
|
|
1141
|
+
.trim();
|
|
1142
|
+
const elementNullable = stripNull(rawInner) !== rawInner;
|
|
909
1143
|
out.push("{");
|
|
910
1144
|
if (member.node.type.isNullable) {
|
|
911
1145
|
out.push(` if (load<u64>(${valuePtr}) == 30399761348886638) {`);
|
|
@@ -922,13 +1156,27 @@ export class JSONTransform extends Visitor {
|
|
|
922
1156
|
out.push(" }");
|
|
923
1157
|
out.push(" let index = 0;");
|
|
924
1158
|
out.push(` ${srcPtr} = ${valuePtr} + 2;`);
|
|
1159
|
+
out.push(` ${srcPtr} = JSON.Util.skipWhitespace(${srcPtr}, srcEnd);`);
|
|
925
1160
|
out.push(` if (load<u16>(${srcPtr}) == 0x5d) {`);
|
|
926
1161
|
out.push(" value.length = 0;");
|
|
927
1162
|
out.push(` ${srcPtr} += 2;`);
|
|
928
1163
|
out.push(" } else while (true) {");
|
|
929
|
-
out.push(
|
|
930
|
-
|
|
1164
|
+
out.push(` ${srcPtr} = JSON.Util.skipWhitespace(${srcPtr}, srcEnd);`);
|
|
1165
|
+
if (elementNullable) {
|
|
1166
|
+
out.push(` if (index >= value.length) value.push(changetype<${valueType} | null>(0));`);
|
|
1167
|
+
out.push(` if (load<u64>(${srcPtr}) == 30399761348886638) {`);
|
|
1168
|
+
out.push(` store<usize>(value.dataStart + ((<usize>index) << alignof<${valueType}>()), 0);`);
|
|
1169
|
+
out.push(` ${srcPtr} += 8;`);
|
|
1170
|
+
out.push(" } else {");
|
|
1171
|
+
out.push(` ${srcPtr} = ${STRING_FIELD_DESERIALIZER}<${valueType}>(${srcPtr}, srcEnd, value.dataStart + ((<usize>index) << alignof<${valueType}>()));`);
|
|
1172
|
+
out.push(" }");
|
|
1173
|
+
}
|
|
1174
|
+
else {
|
|
1175
|
+
out.push(' if (index >= value.length) value.push("");');
|
|
1176
|
+
out.push(` ${srcPtr} = ${STRING_FIELD_DESERIALIZER}<${valueType}>(${srcPtr}, srcEnd, value.dataStart + ((<usize>index) << alignof<${valueType}>()));`);
|
|
1177
|
+
}
|
|
931
1178
|
out.push(" index++;");
|
|
1179
|
+
out.push(` ${srcPtr} = JSON.Util.skipWhitespace(${srcPtr}, srcEnd);`);
|
|
932
1180
|
out.push(` const code = load<u16>(${srcPtr});`);
|
|
933
1181
|
out.push(" if (code == 0x2c) {");
|
|
934
1182
|
out.push(` ${srcPtr} += 2;`);
|
|
@@ -957,6 +1205,7 @@ export class JSONTransform extends Visitor {
|
|
|
957
1205
|
out.push(" }");
|
|
958
1206
|
out.push(" let index = 0;");
|
|
959
1207
|
out.push(` ${srcPtr} = ${valuePtr} + 2;`);
|
|
1208
|
+
out.push(` ${srcPtr} = JSON.Util.skipWhitespace(${srcPtr}, srcEnd);`);
|
|
960
1209
|
out.push(` if (load<u16>(${srcPtr}) == 0x5d) {`);
|
|
961
1210
|
out.push(" value.length = 0;");
|
|
962
1211
|
out.push(` ${srcPtr} += 2;`);
|
|
@@ -975,6 +1224,7 @@ export class JSONTransform extends Visitor {
|
|
|
975
1224
|
out.push(` ${srcPtr} = changetype<nonnull<${valueType}>>(item).__DESERIALIZE_FAST<${valueType}>(${srcPtr}, srcEnd, item);`);
|
|
976
1225
|
out.push(` if (!${srcPtr}) break;`);
|
|
977
1226
|
out.push(" index++;");
|
|
1227
|
+
out.push(` ${srcPtr} = JSON.Util.skipWhitespace(${srcPtr}, srcEnd);`);
|
|
978
1228
|
out.push(` const code = load<u16>(${srcPtr});`);
|
|
979
1229
|
out.push(" if (code == 0x2c) {");
|
|
980
1230
|
out.push(` ${srcPtr} += 2;`);
|
|
@@ -993,66 +1243,28 @@ export class JSONTransform extends Visitor {
|
|
|
993
1243
|
out.push("}");
|
|
994
1244
|
return out;
|
|
995
1245
|
}
|
|
996
|
-
out.push(`
|
|
997
|
-
out.push(` if (
|
|
998
|
-
out.push(` value = changetype<${resolvedType}>(instantiate<nonnull<${resolvedType}>>());`);
|
|
999
|
-
out.push(` store<${resolvedType}>(${outPtr}, value, ${fieldOffset});`);
|
|
1000
|
-
out.push(" }");
|
|
1001
|
-
out.push(` if (load<u16>(${valuePtr}) == 0x5b && load<u16>(${valuePtr}, 2) == 0x5d) {`);
|
|
1002
|
-
out.push(" value.length = 0;");
|
|
1003
|
-
out.push(` ${srcPtr} = ${valuePtr} + 4;`);
|
|
1004
|
-
out.push(" } else {");
|
|
1005
|
-
out.push(` ${srcPtr} = deserializeArrayInto_SWAR<${resolvedType}>(${valuePtr}, srcEnd, value);`);
|
|
1006
|
-
out.push(` if (!${srcPtr}) break;`);
|
|
1007
|
-
out.push(" }");
|
|
1246
|
+
out.push(` ${srcPtr} = __deserializeArrayField_SWAR<${resolvedType}>(${valuePtr}, srcEnd, ${outPtr}, ${fieldOffset});`);
|
|
1247
|
+
out.push(` if (!${srcPtr}) break;`);
|
|
1008
1248
|
if (member.node.type.isNullable) {
|
|
1009
1249
|
out.push(" }");
|
|
1010
1250
|
}
|
|
1011
1251
|
out.push("}");
|
|
1012
1252
|
}
|
|
1013
1253
|
else if (resolvedType.startsWith("Map<")) {
|
|
1014
|
-
|
|
1015
|
-
out.push(`${srcPtr} = deserializeMapField<${resolvedType}>(${srcPtr}, srcEnd, ${outPtr}, ${fieldOffset});`);
|
|
1016
|
-
}
|
|
1017
|
-
else if (fastPath) {
|
|
1018
|
-
out.push("{");
|
|
1019
|
-
out.push(` let value = load<${resolvedType}>(${outPtr}, ${fieldOffset});`);
|
|
1020
|
-
out.push(" if (changetype<usize>(value) == 0) {");
|
|
1021
|
-
out.push(` value = new ${resolvedType}();`);
|
|
1022
|
-
out.push(` store<${resolvedType}>(${outPtr}, value, ${fieldOffset});`);
|
|
1023
|
-
out.push(" }");
|
|
1024
|
-
out.push(` ${srcPtr} = deserializeMapInto<${resolvedType}>(${srcPtr}, srcEnd, value);`);
|
|
1025
|
-
out.push("}");
|
|
1026
|
-
}
|
|
1027
|
-
else {
|
|
1028
|
-
out.push(`${srcPtr} = deserializeMapInto<${resolvedType}>(${srcPtr}, srcEnd, load<${resolvedType}>(${outPtr}, ${fieldOffset}));`);
|
|
1029
|
-
}
|
|
1254
|
+
out.push(`${srcPtr} = __deserializeMapField<${resolvedType}>(${srcPtr}, srcEnd, ${outPtr}, ${fieldOffset});`);
|
|
1030
1255
|
out.push(`if (!${srcPtr}) break;`);
|
|
1031
1256
|
}
|
|
1032
1257
|
else if (resolvedType.startsWith("Set<")) {
|
|
1033
|
-
|
|
1034
|
-
out.push(`${srcPtr} = deserializeSetField<${resolvedType}>(${srcPtr}, srcEnd, ${outPtr}, ${fieldOffset});`);
|
|
1035
|
-
}
|
|
1036
|
-
else if (fastPath) {
|
|
1037
|
-
out.push("{");
|
|
1038
|
-
out.push(` let value = load<${resolvedType}>(${outPtr}, ${fieldOffset});`);
|
|
1039
|
-
out.push(" if (changetype<usize>(value) == 0) {");
|
|
1040
|
-
out.push(` value = new ${resolvedType}();`);
|
|
1041
|
-
out.push(` store<${resolvedType}>(${outPtr}, value, ${fieldOffset});`);
|
|
1042
|
-
out.push(" }");
|
|
1043
|
-
out.push(` ${srcPtr} = deserializeSetInto<${resolvedType}>(${srcPtr}, srcEnd, value);`);
|
|
1044
|
-
out.push("}");
|
|
1045
|
-
}
|
|
1046
|
-
else {
|
|
1047
|
-
out.push(`${srcPtr} = deserializeSetInto<${resolvedType}>(${srcPtr}, srcEnd, load<${resolvedType}>(${outPtr}, ${fieldOffset}));`);
|
|
1048
|
-
}
|
|
1258
|
+
out.push(`${srcPtr} = __deserializeSetField<${resolvedType}>(${srcPtr}, srcEnd, ${outPtr}, ${fieldOffset});`);
|
|
1049
1259
|
out.push(`if (!${srcPtr}) break;`);
|
|
1050
1260
|
}
|
|
1051
1261
|
else if (resolvedType.startsWith("StaticArray<")) {
|
|
1052
|
-
out.push(`${srcPtr} =
|
|
1262
|
+
out.push(`${srcPtr} = __deserializeStaticArrayField<${resolvedType}>(${srcPtr}, srcEnd, ${outPtr}, ${fieldOffset});`);
|
|
1053
1263
|
out.push(`if (!${srcPtr}) break;`);
|
|
1054
1264
|
}
|
|
1055
|
-
else if (resolvedType == "JSON.Value" ||
|
|
1265
|
+
else if (resolvedType == "JSON.Value" ||
|
|
1266
|
+
resolvedType == "JSON.Obj" ||
|
|
1267
|
+
isEnum(resolvedType, this.sources.get(this.schema.node.range.source), this.parser)) {
|
|
1056
1268
|
out.push("break;");
|
|
1057
1269
|
}
|
|
1058
1270
|
else {
|
|
@@ -1066,7 +1278,8 @@ export class JSONTransform extends Visitor {
|
|
|
1066
1278
|
DESERIALIZE_FAST += indent + "do {\n";
|
|
1067
1279
|
indent += " ";
|
|
1068
1280
|
if (supportsFastOptionalPath) {
|
|
1069
|
-
DESERIALIZE_FAST +=
|
|
1281
|
+
DESERIALIZE_FAST +=
|
|
1282
|
+
indent + "if (load<u16>(srcStart) !== 0x7b) break; // {\n";
|
|
1070
1283
|
DESERIALIZE_FAST += indent + "srcStart += 2;\n";
|
|
1071
1284
|
DESERIALIZE_FAST += indent + "let seenAny = false;\n\n";
|
|
1072
1285
|
for (let i = 0; i < this.schema.members.length; i++) {
|
|
@@ -1082,14 +1295,17 @@ export class JSONTransform extends Visitor {
|
|
|
1082
1295
|
const inlineStringValue = ["string", "String"].includes(resolvedType);
|
|
1083
1296
|
const deserializerFirst = getDeserializer(member.type, "srcStart", "dst", member, inlineStringValue ? firstKeyOffset : 0, true);
|
|
1084
1297
|
const deserializerNext = getDeserializer(member.type, "srcStart", "dst", member, inlineStringValue ? nextKeyOffset : 0, true);
|
|
1085
|
-
const isOptional = member.flags.has(PropertyFlags.OmitNull) ||
|
|
1298
|
+
const isOptional = member.flags.has(PropertyFlags.OmitNull) ||
|
|
1299
|
+
member.flags.has(PropertyFlags.OmitIf);
|
|
1086
1300
|
if (!deserializerFirst.length || !deserializerNext.length) {
|
|
1087
1301
|
DESERIALIZE_FAST += indent + "break;\n\n";
|
|
1088
1302
|
continue;
|
|
1089
1303
|
}
|
|
1090
1304
|
DESERIALIZE_FAST += indent + "if (!seenAny) {\n";
|
|
1091
1305
|
indent += " ";
|
|
1092
|
-
DESERIALIZE_FAST +=
|
|
1306
|
+
DESERIALIZE_FAST +=
|
|
1307
|
+
indent +
|
|
1308
|
+
`if ( // ${firstKeySection}\n${(indent += " ")}${getComparisions(firstKeySection, "srcStart", "!=").join("\n" + indent + "|| ")}\n${(indent = indent.slice(0, -2))}) {\n`;
|
|
1093
1309
|
indent += " ";
|
|
1094
1310
|
if (isOptional) {
|
|
1095
1311
|
DESERIALIZE_FAST += indent + "// optional @omitnull field omitted\n";
|
|
@@ -1102,14 +1318,20 @@ export class JSONTransform extends Visitor {
|
|
|
1102
1318
|
indent += " ";
|
|
1103
1319
|
if (!inlineStringValue)
|
|
1104
1320
|
DESERIALIZE_FAST += indent + `srcStart += ${firstKeyOffset};\n`;
|
|
1105
|
-
DESERIALIZE_FAST +=
|
|
1321
|
+
DESERIALIZE_FAST +=
|
|
1322
|
+
indent +
|
|
1323
|
+
`if (JSON.Util.isSpace(load<u16>(${inlineStringValue ? `srcStart + ${firstKeyOffset}` : "srcStart"}))) break;\n`;
|
|
1324
|
+
DESERIALIZE_FAST +=
|
|
1325
|
+
indent + deserializerFirst.join("\n" + indent) + "\n";
|
|
1106
1326
|
DESERIALIZE_FAST += indent + "seenAny = true;\n";
|
|
1107
1327
|
indent = indent.slice(0, -2);
|
|
1108
1328
|
DESERIALIZE_FAST += indent + "}\n";
|
|
1109
1329
|
indent = indent.slice(0, -2);
|
|
1110
1330
|
DESERIALIZE_FAST += indent + "} else {\n";
|
|
1111
1331
|
indent += " ";
|
|
1112
|
-
DESERIALIZE_FAST +=
|
|
1332
|
+
DESERIALIZE_FAST +=
|
|
1333
|
+
indent +
|
|
1334
|
+
`if ( // ${nextKeySection}\n${(indent += " ")}${getComparisions(nextKeySection, "srcStart", "!=").join("\n" + indent + "|| ")}\n${(indent = indent.slice(0, -2))}) {\n`;
|
|
1113
1335
|
indent += " ";
|
|
1114
1336
|
if (isOptional) {
|
|
1115
1337
|
DESERIALIZE_FAST += indent + "// optional @omitnull field omitted\n";
|
|
@@ -1122,7 +1344,11 @@ export class JSONTransform extends Visitor {
|
|
|
1122
1344
|
indent += " ";
|
|
1123
1345
|
if (!inlineStringValue)
|
|
1124
1346
|
DESERIALIZE_FAST += indent + `srcStart += ${nextKeyOffset};\n`;
|
|
1125
|
-
DESERIALIZE_FAST +=
|
|
1347
|
+
DESERIALIZE_FAST +=
|
|
1348
|
+
indent +
|
|
1349
|
+
`if (JSON.Util.isSpace(load<u16>(${inlineStringValue ? `srcStart + ${nextKeyOffset}` : "srcStart"}))) break;\n`;
|
|
1350
|
+
DESERIALIZE_FAST +=
|
|
1351
|
+
indent + deserializerNext.join("\n" + indent) + "\n";
|
|
1126
1352
|
indent = indent.slice(0, -2);
|
|
1127
1353
|
DESERIALIZE_FAST += indent + "}\n";
|
|
1128
1354
|
indent = indent.slice(0, -2);
|
|
@@ -1136,7 +1362,9 @@ export class JSONTransform extends Visitor {
|
|
|
1136
1362
|
if (key.length <= 2)
|
|
1137
1363
|
throw new Error("Key cannot be empty!");
|
|
1138
1364
|
const keySection = (i == 0 ? "{" : ",") + key + ":";
|
|
1139
|
-
DESERIALIZE_FAST +=
|
|
1365
|
+
DESERIALIZE_FAST +=
|
|
1366
|
+
indent +
|
|
1367
|
+
`if ( // ${keySection}\n${(indent += " ")}${getComparisions(keySection, "srcStart", "!=").join("\n" + indent + "|| ")}\n${(indent = indent.slice(0, -2))}) break;\n`;
|
|
1140
1368
|
const keyOffset = keySection.length << 1;
|
|
1141
1369
|
const resolvedType = stripNull(member.type);
|
|
1142
1370
|
const inlineStringValue = ["string", "String"].includes(resolvedType);
|
|
@@ -1148,18 +1376,119 @@ export class JSONTransform extends Visitor {
|
|
|
1148
1376
|
DESERIALIZE_FAST += indent + "break;\n\n";
|
|
1149
1377
|
continue;
|
|
1150
1378
|
}
|
|
1379
|
+
DESERIALIZE_FAST +=
|
|
1380
|
+
indent +
|
|
1381
|
+
`if (JSON.Util.isSpace(load<u16>(${inlineStringValue ? `srcStart + ${keyOffset}` : "srcStart"}))) break;\n`;
|
|
1151
1382
|
DESERIALIZE_FAST += indent + deserializer.join("\n" + indent) + "\n\n";
|
|
1152
1383
|
}
|
|
1153
1384
|
}
|
|
1154
|
-
DESERIALIZE_FAST +=
|
|
1385
|
+
DESERIALIZE_FAST +=
|
|
1386
|
+
indent + "if (load<u16>(srcStart) !== 0x7d) break; // }\n";
|
|
1155
1387
|
DESERIALIZE_FAST += indent + "srcStart += 2;\n";
|
|
1156
1388
|
DESERIALIZE_FAST += indent + "return srcStart;\n";
|
|
1157
1389
|
indent = indent.slice(0, -2);
|
|
1158
1390
|
DESERIALIZE_FAST += indent + "} while (false);\n\n";
|
|
1391
|
+
const tier2Desers = this.schema.members.map((member) => getDeserializer(member.type, "srcStart", "dst", member, 0, true));
|
|
1392
|
+
const tier2Ok = tier2Desers.every((d) => d.length && !(d.length === 1 && d[0].trim() === "break;"));
|
|
1393
|
+
if (tier2Ok && !supportsFastOptionalPath) {
|
|
1394
|
+
const i1 = " ";
|
|
1395
|
+
const i2 = " ";
|
|
1396
|
+
const skip = i2 + "srcStart = JSON.Util.skipWhitespace(srcStart, srcEnd);\n";
|
|
1397
|
+
DESERIALIZE_FAST += i1 + "srcStart = start;\n";
|
|
1398
|
+
DESERIALIZE_FAST += i1 + "do {\n";
|
|
1399
|
+
DESERIALIZE_FAST += skip;
|
|
1400
|
+
DESERIALIZE_FAST += i2 + "if (load<u16>(srcStart) != 0x7b) break; // {\n";
|
|
1401
|
+
DESERIALIZE_FAST += i2 + "srcStart += 2;\n";
|
|
1402
|
+
for (let i = 0; i < this.schema.members.length; i++) {
|
|
1403
|
+
const member = this.schema.members[i];
|
|
1404
|
+
const key = JSON.stringify(member.alias || member.name);
|
|
1405
|
+
const keyBytes = key.length << 1;
|
|
1406
|
+
DESERIALIZE_FAST += "\n";
|
|
1407
|
+
DESERIALIZE_FAST += skip;
|
|
1408
|
+
DESERIALIZE_FAST +=
|
|
1409
|
+
i2 +
|
|
1410
|
+
`if ( // ${key}\n${i2} ` +
|
|
1411
|
+
getComparisions(key, "srcStart", "!=").join("\n" + i2 + " || ") +
|
|
1412
|
+
`\n${i2}) break;\n`;
|
|
1413
|
+
DESERIALIZE_FAST += i2 + `srcStart += ${keyBytes};\n`;
|
|
1414
|
+
DESERIALIZE_FAST += skip;
|
|
1415
|
+
DESERIALIZE_FAST +=
|
|
1416
|
+
i2 + "if (load<u16>(srcStart) != 0x3a) break; // :\n";
|
|
1417
|
+
DESERIALIZE_FAST += i2 + "srcStart += 2;\n";
|
|
1418
|
+
DESERIALIZE_FAST += skip;
|
|
1419
|
+
DESERIALIZE_FAST += i2 + tier2Desers[i].join("\n" + i2) + "\n";
|
|
1420
|
+
if (i < this.schema.members.length - 1) {
|
|
1421
|
+
DESERIALIZE_FAST += skip;
|
|
1422
|
+
DESERIALIZE_FAST +=
|
|
1423
|
+
i2 + "if (load<u16>(srcStart) != 0x2c) break; // ,\n";
|
|
1424
|
+
DESERIALIZE_FAST += i2 + "srcStart += 2;\n";
|
|
1425
|
+
}
|
|
1426
|
+
}
|
|
1427
|
+
DESERIALIZE_FAST += "\n";
|
|
1428
|
+
DESERIALIZE_FAST += skip;
|
|
1429
|
+
DESERIALIZE_FAST += i2 + "if (load<u16>(srcStart) != 0x7d) break; // }\n";
|
|
1430
|
+
DESERIALIZE_FAST += i2 + "srcStart += 2;\n";
|
|
1431
|
+
DESERIALIZE_FAST += i2 + "return srcStart;\n";
|
|
1432
|
+
DESERIALIZE_FAST += i1 + "} while (false);\n\n";
|
|
1433
|
+
}
|
|
1434
|
+
else if (tier2Ok && supportsFastOptionalPath) {
|
|
1435
|
+
const multi = this.schema.members.length > 1;
|
|
1436
|
+
const i1 = " ";
|
|
1437
|
+
const i2 = " ";
|
|
1438
|
+
const i3 = " ";
|
|
1439
|
+
DESERIALIZE_FAST += i1 + "srcStart = start;\n";
|
|
1440
|
+
DESERIALIZE_FAST += i1 + "do {\n";
|
|
1441
|
+
DESERIALIZE_FAST +=
|
|
1442
|
+
i2 + "srcStart = JSON.Util.skipWhitespace(srcStart, srcEnd);\n";
|
|
1443
|
+
DESERIALIZE_FAST += i2 + "if (load<u16>(srcStart) != 0x7b) break; // {\n";
|
|
1444
|
+
DESERIALIZE_FAST += i2 + "srcStart += 2;\n";
|
|
1445
|
+
DESERIALIZE_FAST += i2 + "let kp: usize = 0;\n";
|
|
1446
|
+
if (multi)
|
|
1447
|
+
DESERIALIZE_FAST += i2 + "let seenAny = false;\n";
|
|
1448
|
+
for (let i = 0; i < this.schema.members.length; i++) {
|
|
1449
|
+
const member = this.schema.members[i];
|
|
1450
|
+
const key = JSON.stringify(member.alias || member.name);
|
|
1451
|
+
const keyBytes = key.length << 1;
|
|
1452
|
+
DESERIALIZE_FAST += "\n";
|
|
1453
|
+
DESERIALIZE_FAST +=
|
|
1454
|
+
i2 + "kp = JSON.Util.skipWhitespace(srcStart, srcEnd);\n";
|
|
1455
|
+
if (multi && i > 0) {
|
|
1456
|
+
DESERIALIZE_FAST +=
|
|
1457
|
+
i2 +
|
|
1458
|
+
"if (seenAny && load<u16>(kp) == 0x2c) kp = JSON.Util.skipWhitespace(kp + 2, srcEnd);\n";
|
|
1459
|
+
}
|
|
1460
|
+
DESERIALIZE_FAST +=
|
|
1461
|
+
i2 +
|
|
1462
|
+
`if ( // ${key}\n${i2} ` +
|
|
1463
|
+
getComparisions(key, "kp", "==").join("\n" + i2 + " && ") +
|
|
1464
|
+
`\n${i2}) {\n`;
|
|
1465
|
+
DESERIALIZE_FAST += i3 + `kp += ${keyBytes};\n`;
|
|
1466
|
+
DESERIALIZE_FAST += i3 + "kp = JSON.Util.skipWhitespace(kp, srcEnd);\n";
|
|
1467
|
+
DESERIALIZE_FAST += i3 + "if (load<u16>(kp) != 0x3a) break; // :\n";
|
|
1468
|
+
DESERIALIZE_FAST +=
|
|
1469
|
+
i3 + "srcStart = JSON.Util.skipWhitespace(kp + 2, srcEnd);\n";
|
|
1470
|
+
DESERIALIZE_FAST += i3 + tier2Desers[i].join("\n" + i3) + "\n";
|
|
1471
|
+
if (multi)
|
|
1472
|
+
DESERIALIZE_FAST += i3 + "seenAny = true;\n";
|
|
1473
|
+
DESERIALIZE_FAST += i2 + "}\n";
|
|
1474
|
+
}
|
|
1475
|
+
DESERIALIZE_FAST += "\n";
|
|
1476
|
+
DESERIALIZE_FAST +=
|
|
1477
|
+
i2 + "srcStart = JSON.Util.skipWhitespace(srcStart, srcEnd);\n";
|
|
1478
|
+
DESERIALIZE_FAST += i2 + "if (load<u16>(srcStart) != 0x7d) break; // }\n";
|
|
1479
|
+
DESERIALIZE_FAST += i2 + "srcStart += 2;\n";
|
|
1480
|
+
DESERIALIZE_FAST += i2 + "return srcStart;\n";
|
|
1481
|
+
DESERIALIZE_FAST += i1 + "} while (false);\n\n";
|
|
1482
|
+
}
|
|
1159
1483
|
if (THROW_FAST_PATH) {
|
|
1160
|
-
DESERIALIZE_FAST +=
|
|
1161
|
-
|
|
1162
|
-
DESERIALIZE_FAST +=
|
|
1484
|
+
DESERIALIZE_FAST +=
|
|
1485
|
+
indent + "const failAt = srcStart ? srcStart : start;\n";
|
|
1486
|
+
DESERIALIZE_FAST +=
|
|
1487
|
+
indent +
|
|
1488
|
+
"const failEnd = failAt + 160 < srcEnd ? failAt + 160 : srcEnd;\n";
|
|
1489
|
+
DESERIALIZE_FAST +=
|
|
1490
|
+
indent +
|
|
1491
|
+
`throw new Error("Fast path failed for ${this.schema.name} at char offset " + ((failAt - start) >> 1).toString() + " near: " + JSON.Util.ptrToStr(failAt, failEnd));`;
|
|
1163
1492
|
}
|
|
1164
1493
|
else {
|
|
1165
1494
|
DESERIALIZE_FAST += indent + "return 0;";
|
|
@@ -1172,30 +1501,53 @@ export class JSONTransform extends Visitor {
|
|
|
1172
1501
|
if (!STRICT || sortedMembers.object.length || sortedMembers.array.length)
|
|
1173
1502
|
DESERIALIZE += indent + " let depth: i32 = 0;\n";
|
|
1174
1503
|
DESERIALIZE += indent + " let lastIndex: usize = 0;\n\n";
|
|
1175
|
-
DESERIALIZE +=
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
DESERIALIZE +=
|
|
1179
|
-
|
|
1504
|
+
DESERIALIZE +=
|
|
1505
|
+
indent +
|
|
1506
|
+
" while (srcStart < srcEnd && JSON.Util.isSpace(load<u16>(srcStart))) srcStart += 2;\n";
|
|
1507
|
+
DESERIALIZE +=
|
|
1508
|
+
indent +
|
|
1509
|
+
" while (srcEnd > srcStart && JSON.Util.isSpace(load<u16>(srcEnd - 2))) srcEnd -= 2;\n";
|
|
1510
|
+
DESERIALIZE +=
|
|
1511
|
+
indent +
|
|
1512
|
+
' if (srcStart - srcEnd == 0) throw new Error("Input string had zero length or was all whitespace");\n';
|
|
1513
|
+
DESERIALIZE +=
|
|
1514
|
+
indent +
|
|
1515
|
+
" if (load<u16>(srcStart) != 123) throw new Error(\"Expected '{' at start of object at position \" + (srcEnd - srcStart).toString());\n";
|
|
1516
|
+
DESERIALIZE +=
|
|
1517
|
+
indent +
|
|
1518
|
+
" if (load<u16>(srcEnd - 2) != 125) throw new Error(\"Expected '}' at end of object at position \" + (srcEnd - srcStart).toString());\n";
|
|
1180
1519
|
DESERIALIZE += indent + " srcStart += 2;\n\n";
|
|
1181
1520
|
DESERIALIZE += indent + " while (srcStart < srcEnd) {\n";
|
|
1182
1521
|
DESERIALIZE += indent + " let code = load<u16>(srcStart);\n";
|
|
1183
|
-
DESERIALIZE +=
|
|
1522
|
+
DESERIALIZE +=
|
|
1523
|
+
indent +
|
|
1524
|
+
" while (JSON.Util.isSpace(code)) code = load<u16>(srcStart += 2);\n";
|
|
1184
1525
|
DESERIALIZE += indent + " if (keyStart == 0) {\n";
|
|
1185
|
-
DESERIALIZE +=
|
|
1526
|
+
DESERIALIZE +=
|
|
1527
|
+
indent + " if (code == 34 && load<u16>(srcStart - 2) !== 92) {\n";
|
|
1186
1528
|
DESERIALIZE += indent + " if (isKey) {\n";
|
|
1187
1529
|
DESERIALIZE += indent + " keyStart = lastIndex;\n";
|
|
1188
1530
|
DESERIALIZE += indent + " keyEnd = srcStart;\n";
|
|
1189
1531
|
if (DEBUG > 1)
|
|
1190
|
-
DESERIALIZE +=
|
|
1191
|
-
|
|
1192
|
-
|
|
1532
|
+
DESERIALIZE +=
|
|
1533
|
+
indent +
|
|
1534
|
+
' console.log("Key: " + JSON.Util.ptrToStr(keyStart, keyEnd));\n';
|
|
1535
|
+
DESERIALIZE +=
|
|
1536
|
+
indent +
|
|
1537
|
+
" while (JSON.Util.isSpace((code = load<u16>((srcStart += 2))))) {}\n";
|
|
1538
|
+
DESERIALIZE +=
|
|
1539
|
+
indent +
|
|
1540
|
+
" if (code !== 58) throw new Error(\"Expected ':' after key at position \" + (srcEnd - srcStart).toString());\n";
|
|
1193
1541
|
DESERIALIZE += indent + " isKey = false;\n";
|
|
1194
1542
|
DESERIALIZE += indent + " } else {\n";
|
|
1195
1543
|
DESERIALIZE += indent + " isKey = true;\n";
|
|
1196
1544
|
DESERIALIZE += indent + " lastIndex = srcStart + 2;\n";
|
|
1197
1545
|
DESERIALIZE += indent + " }\n";
|
|
1198
1546
|
DESERIALIZE += indent + " }\n";
|
|
1547
|
+
if (STRICT)
|
|
1548
|
+
DESERIALIZE +=
|
|
1549
|
+
indent +
|
|
1550
|
+
' else if (!isKey && code != 44 && code != 125) throw new Error("Expected \'\\"\' to start key in JSON object at position " + (srcEnd - srcStart).toString());\n';
|
|
1199
1551
|
DESERIALIZE += indent + " srcStart += 2;\n";
|
|
1200
1552
|
DESERIALIZE += indent + " } else {\n";
|
|
1201
1553
|
const groupMembers = (members) => {
|
|
@@ -1219,7 +1571,9 @@ export class JSONTransform extends Visitor {
|
|
|
1219
1571
|
const generateGroups = (members, cb, type) => {
|
|
1220
1572
|
if (!members.length) {
|
|
1221
1573
|
if (STRICT) {
|
|
1222
|
-
DESERIALIZE +=
|
|
1574
|
+
DESERIALIZE +=
|
|
1575
|
+
indent +
|
|
1576
|
+
' throw new Error("Unexpected key value pair in JSON object \'" + JSON.Util.ptrToStr(keyStart, keyEnd) + ":" + JSON.Util.ptrToStr(lastIndex, srcStart) + "\' at position " + (srcEnd - srcStart).toString());\n';
|
|
1223
1577
|
}
|
|
1224
1578
|
else {
|
|
1225
1579
|
if (type == "string") {
|
|
@@ -1229,7 +1583,10 @@ export class JSONTransform extends Visitor {
|
|
|
1229
1583
|
DESERIALIZE += indent + " srcStart += 2;\n";
|
|
1230
1584
|
}
|
|
1231
1585
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
1232
|
-
if (type == "string" ||
|
|
1586
|
+
if (type == "string" ||
|
|
1587
|
+
type == "object" ||
|
|
1588
|
+
type == "array" ||
|
|
1589
|
+
type == "number")
|
|
1233
1590
|
DESERIALIZE += indent + " break;\n";
|
|
1234
1591
|
}
|
|
1235
1592
|
}
|
|
@@ -1244,7 +1601,9 @@ export class JSONTransform extends Visitor {
|
|
|
1244
1601
|
}
|
|
1245
1602
|
DESERIALIZE += " default: {\n";
|
|
1246
1603
|
if (STRICT) {
|
|
1247
|
-
DESERIALIZE +=
|
|
1604
|
+
DESERIALIZE +=
|
|
1605
|
+
indent +
|
|
1606
|
+
' throw new Error("Unexpected key value pair in JSON object \'" + JSON.Util.ptrToStr(keyStart, keyEnd) + ":" + JSON.Util.ptrToStr(lastIndex, srcStart) + "\' at position " + (srcEnd - srcStart).toString());\n';
|
|
1248
1607
|
}
|
|
1249
1608
|
else {
|
|
1250
1609
|
if (type == "string") {
|
|
@@ -1254,7 +1613,10 @@ export class JSONTransform extends Visitor {
|
|
|
1254
1613
|
DESERIALIZE += indent + " srcStart += 2;\n";
|
|
1255
1614
|
}
|
|
1256
1615
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
1257
|
-
if (type == "string" ||
|
|
1616
|
+
if (type == "string" ||
|
|
1617
|
+
type == "object" ||
|
|
1618
|
+
type == "array" ||
|
|
1619
|
+
type == "number")
|
|
1258
1620
|
DESERIALIZE += indent + " break;\n";
|
|
1259
1621
|
}
|
|
1260
1622
|
DESERIALIZE += " }\n";
|
|
@@ -1271,7 +1633,8 @@ export class JSONTransform extends Visitor {
|
|
|
1271
1633
|
DESERIALIZE += " const code32 = load<u32>(keyStart);\n";
|
|
1272
1634
|
}
|
|
1273
1635
|
if (members.some((m) => (m.alias || m.name).length << 1 == 6)) {
|
|
1274
|
-
DESERIALIZE +=
|
|
1636
|
+
DESERIALIZE +=
|
|
1637
|
+
" const code48 = load<u64>(keyStart) & 0x0000FFFFFFFFFFFF;\n";
|
|
1275
1638
|
}
|
|
1276
1639
|
if (members.some((m) => (m.alias || m.name).length << 1 == 8)) {
|
|
1277
1640
|
DESERIALIZE += " const code64 = load<u64>(keyStart);\n";
|
|
@@ -1287,15 +1650,34 @@ export class JSONTransform extends Visitor {
|
|
|
1287
1650
|
DESERIALIZE += " srcStart += 2;\n";
|
|
1288
1651
|
DESERIALIZE += " while (srcStart < srcEnd) {\n";
|
|
1289
1652
|
DESERIALIZE += " const code = load<u16>(srcStart);\n";
|
|
1290
|
-
DESERIALIZE +=
|
|
1653
|
+
DESERIALIZE +=
|
|
1654
|
+
" if (code == 34 && load<u16>(srcStart - 2) !== 92) {\n";
|
|
1291
1655
|
if (DEBUG > 1)
|
|
1292
|
-
DESERIALIZE +=
|
|
1656
|
+
DESERIALIZE +=
|
|
1657
|
+
' console.log("Value (string, ' +
|
|
1658
|
+
++id +
|
|
1659
|
+
'): " + JSON.Util.ptrToStr(lastIndex, srcStart + 2));';
|
|
1293
1660
|
generateGroups(sortedMembers.string, (group) => {
|
|
1294
1661
|
generateConsts(group);
|
|
1295
1662
|
const first = group[0];
|
|
1296
1663
|
const fName = first.alias || first.name;
|
|
1297
|
-
DESERIALIZE +=
|
|
1298
|
-
|
|
1664
|
+
DESERIALIZE +=
|
|
1665
|
+
indent +
|
|
1666
|
+
" if (" +
|
|
1667
|
+
(first.generic ? "isString<" + first.type + ">() && " : "") +
|
|
1668
|
+
getComparison(fName) +
|
|
1669
|
+
") { // " +
|
|
1670
|
+
fName +
|
|
1671
|
+
"\n";
|
|
1672
|
+
DESERIALIZE +=
|
|
1673
|
+
indent +
|
|
1674
|
+
" store<" +
|
|
1675
|
+
first.type +
|
|
1676
|
+
">(changetype<usize>(out), JSON.__deserialize<" +
|
|
1677
|
+
first.type +
|
|
1678
|
+
">(lastIndex, srcStart + 2), offsetof<this>(" +
|
|
1679
|
+
JSON.stringify(first.name) +
|
|
1680
|
+
"));\n";
|
|
1299
1681
|
DESERIALIZE += indent + " srcStart += 4;\n";
|
|
1300
1682
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
1301
1683
|
DESERIALIZE += indent + " break;\n";
|
|
@@ -1303,8 +1685,23 @@ export class JSONTransform extends Visitor {
|
|
|
1303
1685
|
for (let i = 1; i < group.length; i++) {
|
|
1304
1686
|
const mem = group[i];
|
|
1305
1687
|
const memName = mem.alias || mem.name;
|
|
1306
|
-
DESERIALIZE +=
|
|
1307
|
-
|
|
1688
|
+
DESERIALIZE +=
|
|
1689
|
+
indent +
|
|
1690
|
+
" else if (" +
|
|
1691
|
+
(mem.generic ? "isString<" + mem.type + ">() && " : "") +
|
|
1692
|
+
getComparison(memName) +
|
|
1693
|
+
") { // " +
|
|
1694
|
+
memName +
|
|
1695
|
+
"\n";
|
|
1696
|
+
DESERIALIZE +=
|
|
1697
|
+
indent +
|
|
1698
|
+
" store<" +
|
|
1699
|
+
mem.type +
|
|
1700
|
+
">(changetype<usize>(out), JSON.__deserialize<" +
|
|
1701
|
+
mem.type +
|
|
1702
|
+
">(lastIndex, srcStart + 2), offsetof<this>(" +
|
|
1703
|
+
JSON.stringify(mem.name) +
|
|
1704
|
+
"));\n";
|
|
1308
1705
|
DESERIALIZE += indent + " srcStart += 4;\n";
|
|
1309
1706
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
1310
1707
|
DESERIALIZE += indent + " break;\n";
|
|
@@ -1312,7 +1709,9 @@ export class JSONTransform extends Visitor {
|
|
|
1312
1709
|
}
|
|
1313
1710
|
if (STRICT) {
|
|
1314
1711
|
DESERIALIZE += " else {\n";
|
|
1315
|
-
DESERIALIZE +=
|
|
1712
|
+
DESERIALIZE +=
|
|
1713
|
+
indent +
|
|
1714
|
+
' throw new Error("Unexpected key value pair in JSON object \'" + JSON.Util.ptrToStr(keyStart, keyEnd) + ":" + JSON.Util.ptrToStr(lastIndex, srcStart) + "\' at position " + (srcEnd - srcStart).toString());\n';
|
|
1316
1715
|
DESERIALIZE += indent + " }\n";
|
|
1317
1716
|
}
|
|
1318
1717
|
else {
|
|
@@ -1335,15 +1734,40 @@ export class JSONTransform extends Visitor {
|
|
|
1335
1734
|
DESERIALIZE += " srcStart += 2;\n";
|
|
1336
1735
|
DESERIALIZE += " while (srcStart < srcEnd) {\n";
|
|
1337
1736
|
DESERIALIZE += " const code = load<u16>(srcStart);\n";
|
|
1338
|
-
DESERIALIZE +=
|
|
1737
|
+
DESERIALIZE +=
|
|
1738
|
+
" if (code == 44 || code == 125 || JSON.Util.isSpace(code)) {\n";
|
|
1339
1739
|
if (DEBUG > 1)
|
|
1340
|
-
DESERIALIZE +=
|
|
1740
|
+
DESERIALIZE +=
|
|
1741
|
+
' console.log("Value (number, ' +
|
|
1742
|
+
++id +
|
|
1743
|
+
'): " + JSON.Util.ptrToStr(lastIndex, srcStart));';
|
|
1341
1744
|
generateGroups(sortedMembers.number, (group) => {
|
|
1342
1745
|
generateConsts(group);
|
|
1343
1746
|
const first = group[0];
|
|
1344
1747
|
const fName = first.alias || first.name;
|
|
1345
|
-
DESERIALIZE +=
|
|
1346
|
-
|
|
1748
|
+
DESERIALIZE +=
|
|
1749
|
+
indent +
|
|
1750
|
+
" if (" +
|
|
1751
|
+
(first.generic
|
|
1752
|
+
? "(isInteger<" +
|
|
1753
|
+
first.type +
|
|
1754
|
+
">() || isFloat<" +
|
|
1755
|
+
first.type +
|
|
1756
|
+
">()) && "
|
|
1757
|
+
: "") +
|
|
1758
|
+
getComparison(fName) +
|
|
1759
|
+
") { // " +
|
|
1760
|
+
fName +
|
|
1761
|
+
"\n";
|
|
1762
|
+
DESERIALIZE +=
|
|
1763
|
+
indent +
|
|
1764
|
+
" store<" +
|
|
1765
|
+
first.type +
|
|
1766
|
+
">(changetype<usize>(out), JSON.__deserialize<" +
|
|
1767
|
+
first.type +
|
|
1768
|
+
">(lastIndex, srcStart), offsetof<this>(" +
|
|
1769
|
+
JSON.stringify(first.name) +
|
|
1770
|
+
"));\n";
|
|
1347
1771
|
DESERIALIZE += indent + " srcStart += 2;\n";
|
|
1348
1772
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
1349
1773
|
DESERIALIZE += indent + " break;\n";
|
|
@@ -1351,8 +1775,29 @@ export class JSONTransform extends Visitor {
|
|
|
1351
1775
|
for (let i = 1; i < group.length; i++) {
|
|
1352
1776
|
const mem = group[i];
|
|
1353
1777
|
const memName = mem.alias || mem.name;
|
|
1354
|
-
DESERIALIZE +=
|
|
1355
|
-
|
|
1778
|
+
DESERIALIZE +=
|
|
1779
|
+
indent +
|
|
1780
|
+
" else if (" +
|
|
1781
|
+
(mem.generic
|
|
1782
|
+
? "(isInteger<" +
|
|
1783
|
+
mem.type +
|
|
1784
|
+
">() || isFloat<" +
|
|
1785
|
+
mem.type +
|
|
1786
|
+
">()) && "
|
|
1787
|
+
: "") +
|
|
1788
|
+
getComparison(memName) +
|
|
1789
|
+
") { // " +
|
|
1790
|
+
memName +
|
|
1791
|
+
"\n";
|
|
1792
|
+
DESERIALIZE +=
|
|
1793
|
+
indent +
|
|
1794
|
+
" store<" +
|
|
1795
|
+
mem.type +
|
|
1796
|
+
">(changetype<usize>(out), JSON.__deserialize<" +
|
|
1797
|
+
mem.type +
|
|
1798
|
+
">(lastIndex, srcStart), offsetof<this>(" +
|
|
1799
|
+
JSON.stringify(mem.name) +
|
|
1800
|
+
"));\n";
|
|
1356
1801
|
DESERIALIZE += indent + " srcStart += 2;\n";
|
|
1357
1802
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
1358
1803
|
DESERIALIZE += indent + " break;\n";
|
|
@@ -1360,7 +1805,9 @@ export class JSONTransform extends Visitor {
|
|
|
1360
1805
|
}
|
|
1361
1806
|
if (STRICT) {
|
|
1362
1807
|
DESERIALIZE += " else {\n";
|
|
1363
|
-
DESERIALIZE +=
|
|
1808
|
+
DESERIALIZE +=
|
|
1809
|
+
indent +
|
|
1810
|
+
' throw new Error("Unexpected key value pair in JSON object \'" + JSON.Util.ptrToStr(keyStart, keyEnd) + ":" + JSON.Util.ptrToStr(lastIndex, srcStart) + "\' at position " + (srcEnd - srcStart).toString());\n';
|
|
1364
1811
|
DESERIALIZE += indent + " }\n";
|
|
1365
1812
|
}
|
|
1366
1813
|
else {
|
|
@@ -1386,34 +1833,68 @@ export class JSONTransform extends Visitor {
|
|
|
1386
1833
|
DESERIALIZE += " const code = load<u16>(srcStart);\n";
|
|
1387
1834
|
DESERIALIZE += " if (code == 34) {\n";
|
|
1388
1835
|
DESERIALIZE += " srcStart += 2;\n";
|
|
1389
|
-
DESERIALIZE +=
|
|
1836
|
+
DESERIALIZE +=
|
|
1837
|
+
" while (!(load<u16>(srcStart) == 34 && load<u16>(srcStart - 2) != 92)) srcStart += 2;\n";
|
|
1390
1838
|
DESERIALIZE += " } else if (code == 125) {\n";
|
|
1391
1839
|
DESERIALIZE += " if (--depth == 0) {\n";
|
|
1392
1840
|
DESERIALIZE += " srcStart += 2;\n";
|
|
1393
1841
|
if (DEBUG > 1)
|
|
1394
|
-
DESERIALIZE +=
|
|
1842
|
+
DESERIALIZE +=
|
|
1843
|
+
' console.log("Value (object, ' +
|
|
1844
|
+
++id +
|
|
1845
|
+
'): " + JSON.Util.ptrToStr(lastIndex, srcStart));';
|
|
1395
1846
|
indent = " ";
|
|
1396
1847
|
generateGroups(sortedMembers.object, (group) => {
|
|
1397
1848
|
generateConsts(group);
|
|
1398
1849
|
const first = group[0];
|
|
1399
1850
|
const fName = first.alias || first.name;
|
|
1400
|
-
DESERIALIZE +=
|
|
1401
|
-
|
|
1851
|
+
DESERIALIZE +=
|
|
1852
|
+
indent +
|
|
1853
|
+
" if (" +
|
|
1854
|
+
getComparison(fName) +
|
|
1855
|
+
") { // " +
|
|
1856
|
+
fName +
|
|
1857
|
+
"\n";
|
|
1858
|
+
DESERIALIZE +=
|
|
1859
|
+
indent +
|
|
1860
|
+
" store<" +
|
|
1861
|
+
first.type +
|
|
1862
|
+
">(changetype<usize>(out), JSON.__deserialize<" +
|
|
1863
|
+
first.type +
|
|
1864
|
+
">(lastIndex, srcStart), offsetof<this>(" +
|
|
1865
|
+
JSON.stringify(first.name) +
|
|
1866
|
+
"));\n";
|
|
1402
1867
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
1403
1868
|
DESERIALIZE += indent + " break;\n";
|
|
1404
1869
|
DESERIALIZE += indent + " }";
|
|
1405
1870
|
for (let i = 1; i < group.length; i++) {
|
|
1406
1871
|
const mem = group[i];
|
|
1407
1872
|
const memName = mem.alias || mem.name;
|
|
1408
|
-
DESERIALIZE +=
|
|
1409
|
-
|
|
1873
|
+
DESERIALIZE +=
|
|
1874
|
+
indent +
|
|
1875
|
+
" else if (" +
|
|
1876
|
+
getComparison(memName) +
|
|
1877
|
+
") { // " +
|
|
1878
|
+
memName +
|
|
1879
|
+
"\n";
|
|
1880
|
+
DESERIALIZE +=
|
|
1881
|
+
indent +
|
|
1882
|
+
" store<" +
|
|
1883
|
+
mem.type +
|
|
1884
|
+
">(changetype<usize>(out), JSON.__deserialize<" +
|
|
1885
|
+
mem.type +
|
|
1886
|
+
">(lastIndex, srcStart), offsetof<this>(" +
|
|
1887
|
+
JSON.stringify(mem.name) +
|
|
1888
|
+
"));\n";
|
|
1410
1889
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
1411
1890
|
DESERIALIZE += indent + " break;\n";
|
|
1412
1891
|
DESERIALIZE += indent + " }";
|
|
1413
1892
|
}
|
|
1414
1893
|
if (STRICT) {
|
|
1415
1894
|
DESERIALIZE += " else {\n";
|
|
1416
|
-
DESERIALIZE +=
|
|
1895
|
+
DESERIALIZE +=
|
|
1896
|
+
indent +
|
|
1897
|
+
' throw new Error("Unexpected key value pair in JSON object \'" + JSON.Util.ptrToStr(keyStart, keyEnd) + ":" + JSON.Util.ptrToStr(lastIndex, srcStart) + "\' at position " + (srcEnd - srcStart).toString());\n';
|
|
1417
1898
|
DESERIALIZE += indent + " }\n";
|
|
1418
1899
|
}
|
|
1419
1900
|
else {
|
|
@@ -1440,34 +1921,70 @@ export class JSONTransform extends Visitor {
|
|
|
1440
1921
|
DESERIALIZE += " const code = load<u16>(srcStart);\n";
|
|
1441
1922
|
DESERIALIZE += " if (code == 34) {\n";
|
|
1442
1923
|
DESERIALIZE += " srcStart += 2;\n";
|
|
1443
|
-
DESERIALIZE +=
|
|
1924
|
+
DESERIALIZE +=
|
|
1925
|
+
" while (!(load<u16>(srcStart) == 34 && load<u16>(srcStart - 2) != 92)) srcStart += 2;\n";
|
|
1444
1926
|
DESERIALIZE += " } else if (code == 93) {\n";
|
|
1445
1927
|
DESERIALIZE += " if (--depth == 0) {\n";
|
|
1446
1928
|
DESERIALIZE += " srcStart += 2;\n";
|
|
1447
1929
|
if (DEBUG > 1)
|
|
1448
|
-
DESERIALIZE +=
|
|
1930
|
+
DESERIALIZE +=
|
|
1931
|
+
' console.log("Value (object, ' +
|
|
1932
|
+
++id +
|
|
1933
|
+
'): " + JSON.Util.ptrToStr(lastIndex, srcStart));';
|
|
1449
1934
|
indent = " ";
|
|
1450
1935
|
generateGroups(sortedMembers.array, (group) => {
|
|
1451
1936
|
generateConsts(group);
|
|
1452
1937
|
const first = group[0];
|
|
1453
1938
|
const fName = first.alias || first.name;
|
|
1454
|
-
DESERIALIZE +=
|
|
1455
|
-
|
|
1939
|
+
DESERIALIZE +=
|
|
1940
|
+
indent +
|
|
1941
|
+
" if (" +
|
|
1942
|
+
(first.generic ? "isArray<" + first.type + ">() && " : "") +
|
|
1943
|
+
getComparison(fName) +
|
|
1944
|
+
") { // " +
|
|
1945
|
+
fName +
|
|
1946
|
+
"\n";
|
|
1947
|
+
DESERIALIZE +=
|
|
1948
|
+
indent +
|
|
1949
|
+
" store<" +
|
|
1950
|
+
first.type +
|
|
1951
|
+
">(changetype<usize>(out), JSON.__deserialize<" +
|
|
1952
|
+
first.type +
|
|
1953
|
+
">(lastIndex, srcStart), offsetof<this>(" +
|
|
1954
|
+
JSON.stringify(first.name) +
|
|
1955
|
+
"));\n";
|
|
1456
1956
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
1457
1957
|
DESERIALIZE += indent + " break;\n";
|
|
1458
1958
|
DESERIALIZE += indent + " }";
|
|
1459
1959
|
for (let i = 1; i < group.length; i++) {
|
|
1460
1960
|
const mem = group[i];
|
|
1461
1961
|
const memName = mem.alias || mem.name;
|
|
1462
|
-
DESERIALIZE +=
|
|
1463
|
-
|
|
1962
|
+
DESERIALIZE +=
|
|
1963
|
+
indent +
|
|
1964
|
+
" else if (" +
|
|
1965
|
+
(mem.generic ? "isArray" + mem.type + ">() && " : "") +
|
|
1966
|
+
getComparison(memName) +
|
|
1967
|
+
") { // " +
|
|
1968
|
+
memName +
|
|
1969
|
+
"\n";
|
|
1970
|
+
DESERIALIZE +=
|
|
1971
|
+
indent +
|
|
1972
|
+
" store<" +
|
|
1973
|
+
mem.type +
|
|
1974
|
+
">(changetype<usize>(out), JSON.__deserialize<" +
|
|
1975
|
+
mem.type +
|
|
1976
|
+
">(lastIndex, srcStart), offsetof<this>(" +
|
|
1977
|
+
JSON.stringify(mem.name) +
|
|
1978
|
+
"));\n";
|
|
1464
1979
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
1465
1980
|
DESERIALIZE += indent + " break;\n";
|
|
1466
1981
|
DESERIALIZE += indent + " }";
|
|
1467
1982
|
}
|
|
1468
1983
|
if (STRICT) {
|
|
1469
1984
|
DESERIALIZE += " else {\n";
|
|
1470
|
-
DESERIALIZE +=
|
|
1985
|
+
DESERIALIZE +=
|
|
1986
|
+
indent +
|
|
1987
|
+
' throw new Error("Unexpected key value pair in JSON object \'" + JSON.Util.ptrToStr(keyStart, keyEnd) + ":" + JSON.Util.ptrToStr(lastIndex, srcStart) + "\' at position " + (srcEnd - srcStart).toString());\n';
|
|
1471
1988
|
DESERIALIZE += indent + " }\n";
|
|
1472
1989
|
}
|
|
1473
1990
|
else {
|
|
@@ -1487,20 +2004,46 @@ export class JSONTransform extends Visitor {
|
|
|
1487
2004
|
}
|
|
1488
2005
|
if (!STRICT || sortedMembers.boolean.length) {
|
|
1489
2006
|
DESERIALIZE += mbElse + "if (code == 116) {\n";
|
|
1490
|
-
DESERIALIZE +=
|
|
2007
|
+
DESERIALIZE +=
|
|
2008
|
+
" if (load<u64>(srcStart) == 28429475166421108) {\n";
|
|
1491
2009
|
DESERIALIZE += " srcStart += 8;\n";
|
|
1492
2010
|
if (DEBUG > 1)
|
|
1493
|
-
DESERIALIZE +=
|
|
2011
|
+
DESERIALIZE +=
|
|
2012
|
+
' console.log("Value (bool, ' +
|
|
2013
|
+
++id +
|
|
2014
|
+
'): " + JSON.Util.ptrToStr(lastIndex, srcStart - 8));';
|
|
1494
2015
|
generateGroups(sortedMembers.boolean, (group) => {
|
|
1495
2016
|
generateConsts(group);
|
|
1496
2017
|
const first = group[0];
|
|
1497
2018
|
const fName = first.alias || first.name;
|
|
1498
|
-
DESERIALIZE +=
|
|
1499
|
-
|
|
1500
|
-
|
|
2019
|
+
DESERIALIZE +=
|
|
2020
|
+
indent +
|
|
2021
|
+
" if (" +
|
|
2022
|
+
(first.generic ? "isBoolean<" + first.type + ">() && " : "") +
|
|
2023
|
+
getComparison(fName) +
|
|
2024
|
+
") { // " +
|
|
2025
|
+
fName +
|
|
2026
|
+
"\n";
|
|
2027
|
+
if (first.type.startsWith("JSON.Box<bool") ||
|
|
2028
|
+
first.type.startsWith("JSON.Box<boolean") ||
|
|
2029
|
+
first.type.startsWith("Box<bool") ||
|
|
2030
|
+
first.type.startsWith("Box<boolean")) {
|
|
2031
|
+
DESERIALIZE +=
|
|
2032
|
+
indent +
|
|
2033
|
+
" store<" +
|
|
2034
|
+
first.type +
|
|
2035
|
+
">(changetype<usize>(out), changetype<" +
|
|
2036
|
+
first.type +
|
|
2037
|
+
">(JSON.Box.from<bool>(true)), offsetof<this>(" +
|
|
2038
|
+
JSON.stringify(first.name) +
|
|
2039
|
+
"));\n";
|
|
1501
2040
|
}
|
|
1502
2041
|
else {
|
|
1503
|
-
DESERIALIZE +=
|
|
2042
|
+
DESERIALIZE +=
|
|
2043
|
+
indent +
|
|
2044
|
+
" store<boolean>(changetype<usize>(out), true, offsetof<this>(" +
|
|
2045
|
+
JSON.stringify(first.name) +
|
|
2046
|
+
"));\n";
|
|
1504
2047
|
}
|
|
1505
2048
|
DESERIALIZE += indent + " srcStart += 2;\n";
|
|
1506
2049
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
@@ -1509,12 +2052,34 @@ export class JSONTransform extends Visitor {
|
|
|
1509
2052
|
for (let i = 1; i < group.length; i++) {
|
|
1510
2053
|
const mem = group[i];
|
|
1511
2054
|
const memName = mem.alias || mem.name;
|
|
1512
|
-
DESERIALIZE +=
|
|
1513
|
-
|
|
1514
|
-
|
|
2055
|
+
DESERIALIZE +=
|
|
2056
|
+
indent +
|
|
2057
|
+
" else if (" +
|
|
2058
|
+
(mem.generic ? "isBoolean<" + mem.type + ">() && " : "") +
|
|
2059
|
+
getComparison(memName) +
|
|
2060
|
+
") { // " +
|
|
2061
|
+
memName +
|
|
2062
|
+
"\n";
|
|
2063
|
+
if (mem.type.startsWith("JSON.Box<bool") ||
|
|
2064
|
+
mem.type.startsWith("JSON.Box<boolean") ||
|
|
2065
|
+
mem.type.startsWith("Box<bool") ||
|
|
2066
|
+
mem.type.startsWith("Box<boolean")) {
|
|
2067
|
+
DESERIALIZE +=
|
|
2068
|
+
indent +
|
|
2069
|
+
" store<" +
|
|
2070
|
+
mem.type +
|
|
2071
|
+
">(changetype<usize>(out), changetype<" +
|
|
2072
|
+
mem.type +
|
|
2073
|
+
">(JSON.Box.from<bool>(true)), offsetof<this>(" +
|
|
2074
|
+
JSON.stringify(mem.name) +
|
|
2075
|
+
"));\n";
|
|
1515
2076
|
}
|
|
1516
2077
|
else {
|
|
1517
|
-
DESERIALIZE +=
|
|
2078
|
+
DESERIALIZE +=
|
|
2079
|
+
indent +
|
|
2080
|
+
" store<boolean>(changetype<usize>(out), true, offsetof<this>(" +
|
|
2081
|
+
JSON.stringify(mem.name) +
|
|
2082
|
+
"));\n";
|
|
1518
2083
|
}
|
|
1519
2084
|
DESERIALIZE += indent + " srcStart += 2;\n";
|
|
1520
2085
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
@@ -1523,7 +2088,9 @@ export class JSONTransform extends Visitor {
|
|
|
1523
2088
|
}
|
|
1524
2089
|
if (STRICT) {
|
|
1525
2090
|
DESERIALIZE += " else {\n";
|
|
1526
|
-
DESERIALIZE +=
|
|
2091
|
+
DESERIALIZE +=
|
|
2092
|
+
indent +
|
|
2093
|
+
' throw new Error("Unexpected key value pair in JSON object \'" + JSON.Util.ptrToStr(keyStart, keyEnd) + ":" + JSON.Util.ptrToStr(lastIndex, srcStart) + "\' at position " + (srcEnd - srcStart).toString());\n';
|
|
1527
2094
|
DESERIALIZE += indent + " }\n";
|
|
1528
2095
|
}
|
|
1529
2096
|
else {
|
|
@@ -1536,7 +2103,8 @@ export class JSONTransform extends Visitor {
|
|
|
1536
2103
|
}, "boolean");
|
|
1537
2104
|
DESERIALIZE += " }";
|
|
1538
2105
|
DESERIALIZE += " else {\n";
|
|
1539
|
-
DESERIALIZE +=
|
|
2106
|
+
DESERIALIZE +=
|
|
2107
|
+
" throw new Error(\"Expected to find 'true' but found '\" + JSON.Util.ptrToStr(lastIndex, srcStart) + \"' instead at position \" + (srcEnd - srcStart).toString());\n";
|
|
1540
2108
|
DESERIALIZE += " }";
|
|
1541
2109
|
DESERIALIZE += "\n }";
|
|
1542
2110
|
mbElse = " else ";
|
|
@@ -1544,17 +2112,42 @@ export class JSONTransform extends Visitor {
|
|
|
1544
2112
|
DESERIALIZE += " {\n";
|
|
1545
2113
|
DESERIALIZE += " srcStart += 10;\n";
|
|
1546
2114
|
if (DEBUG > 1)
|
|
1547
|
-
DESERIALIZE +=
|
|
2115
|
+
DESERIALIZE +=
|
|
2116
|
+
' console.log("Value (bool, ' +
|
|
2117
|
+
++id +
|
|
2118
|
+
'): " + JSON.Util.ptrToStr(lastIndex, srcStart - 10));';
|
|
1548
2119
|
generateGroups(sortedMembers.boolean, (group) => {
|
|
1549
2120
|
generateConsts(group);
|
|
1550
2121
|
const first = group[0];
|
|
1551
2122
|
const fName = first.alias || first.name;
|
|
1552
|
-
DESERIALIZE +=
|
|
1553
|
-
|
|
1554
|
-
|
|
2123
|
+
DESERIALIZE +=
|
|
2124
|
+
indent +
|
|
2125
|
+
" if (" +
|
|
2126
|
+
(first.generic ? "isBoolean<" + first.type + ">() && " : "") +
|
|
2127
|
+
getComparison(fName) +
|
|
2128
|
+
") { // " +
|
|
2129
|
+
fName +
|
|
2130
|
+
"\n";
|
|
2131
|
+
if (first.type.startsWith("JSON.Box<bool") ||
|
|
2132
|
+
first.type.startsWith("JSON.Box<boolean") ||
|
|
2133
|
+
first.type.startsWith("Box<bool") ||
|
|
2134
|
+
first.type.startsWith("Box<boolean")) {
|
|
2135
|
+
DESERIALIZE +=
|
|
2136
|
+
indent +
|
|
2137
|
+
" store<" +
|
|
2138
|
+
first.type +
|
|
2139
|
+
">(changetype<usize>(out), changetype<" +
|
|
2140
|
+
first.type +
|
|
2141
|
+
">(JSON.Box.from<bool>(false)), offsetof<this>(" +
|
|
2142
|
+
JSON.stringify(first.name) +
|
|
2143
|
+
"));\n";
|
|
1555
2144
|
}
|
|
1556
2145
|
else {
|
|
1557
|
-
DESERIALIZE +=
|
|
2146
|
+
DESERIALIZE +=
|
|
2147
|
+
indent +
|
|
2148
|
+
" store<boolean>(changetype<usize>(out), false, offsetof<this>(" +
|
|
2149
|
+
JSON.stringify(first.name) +
|
|
2150
|
+
"));\n";
|
|
1558
2151
|
}
|
|
1559
2152
|
DESERIALIZE += indent + " srcStart += 2;\n";
|
|
1560
2153
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
@@ -1563,12 +2156,34 @@ export class JSONTransform extends Visitor {
|
|
|
1563
2156
|
for (let i = 1; i < group.length; i++) {
|
|
1564
2157
|
const mem = group[i];
|
|
1565
2158
|
const memName = mem.alias || mem.name;
|
|
1566
|
-
DESERIALIZE +=
|
|
1567
|
-
|
|
1568
|
-
|
|
2159
|
+
DESERIALIZE +=
|
|
2160
|
+
indent +
|
|
2161
|
+
" else if (" +
|
|
2162
|
+
(mem.generic ? "isBoolean<" + mem.type + ">() && " : "") +
|
|
2163
|
+
getComparison(memName) +
|
|
2164
|
+
") { // " +
|
|
2165
|
+
memName +
|
|
2166
|
+
"\n";
|
|
2167
|
+
if (mem.type.startsWith("JSON.Box<bool") ||
|
|
2168
|
+
mem.type.startsWith("JSON.Box<boolean") ||
|
|
2169
|
+
mem.type.startsWith("Box<bool") ||
|
|
2170
|
+
mem.type.startsWith("Box<boolean")) {
|
|
2171
|
+
DESERIALIZE +=
|
|
2172
|
+
indent +
|
|
2173
|
+
" store<" +
|
|
2174
|
+
mem.type +
|
|
2175
|
+
">(changetype<usize>(out), changetype<" +
|
|
2176
|
+
mem.type +
|
|
2177
|
+
">(JSON.Box.from<bool>(false)), offsetof<this>(" +
|
|
2178
|
+
JSON.stringify(mem.name) +
|
|
2179
|
+
"));\n";
|
|
1569
2180
|
}
|
|
1570
2181
|
else {
|
|
1571
|
-
DESERIALIZE +=
|
|
2182
|
+
DESERIALIZE +=
|
|
2183
|
+
indent +
|
|
2184
|
+
" store<boolean>(changetype<usize>(out), false, offsetof<this>(" +
|
|
2185
|
+
JSON.stringify(mem.name) +
|
|
2186
|
+
"));\n";
|
|
1572
2187
|
}
|
|
1573
2188
|
DESERIALIZE += indent + " srcStart += 2;\n";
|
|
1574
2189
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
@@ -1577,7 +2192,9 @@ export class JSONTransform extends Visitor {
|
|
|
1577
2192
|
}
|
|
1578
2193
|
if (STRICT) {
|
|
1579
2194
|
DESERIALIZE += " else {\n";
|
|
1580
|
-
DESERIALIZE +=
|
|
2195
|
+
DESERIALIZE +=
|
|
2196
|
+
indent +
|
|
2197
|
+
' throw new Error("Unexpected key value pair in JSON object \'" + JSON.Util.ptrToStr(keyStart, keyEnd) + ":" + JSON.Util.ptrToStr(lastIndex, srcStart) + "\' at position " + (srcEnd - srcStart).toString());\n';
|
|
1581
2198
|
DESERIALIZE += indent + " }\n";
|
|
1582
2199
|
}
|
|
1583
2200
|
else {
|
|
@@ -1594,16 +2211,31 @@ export class JSONTransform extends Visitor {
|
|
|
1594
2211
|
}
|
|
1595
2212
|
if (!STRICT || sortedMembers.null.length) {
|
|
1596
2213
|
DESERIALIZE += mbElse + "if (code == 110) {\n";
|
|
1597
|
-
DESERIALIZE +=
|
|
2214
|
+
DESERIALIZE +=
|
|
2215
|
+
" if (load<u64>(srcStart) == 30399761348886638) {\n";
|
|
1598
2216
|
DESERIALIZE += " srcStart += 8;\n";
|
|
1599
2217
|
if (DEBUG > 1)
|
|
1600
|
-
DESERIALIZE +=
|
|
2218
|
+
DESERIALIZE +=
|
|
2219
|
+
' console.log("Value (null, ' +
|
|
2220
|
+
++id +
|
|
2221
|
+
'): " + JSON.Util.ptrToStr(lastIndex, srcStart - 8));';
|
|
1601
2222
|
generateGroups(sortedMembers.null, (group) => {
|
|
1602
2223
|
generateConsts(group);
|
|
1603
2224
|
const first = group[0];
|
|
1604
2225
|
const fName = first.alias || first.name;
|
|
1605
|
-
DESERIALIZE +=
|
|
1606
|
-
|
|
2226
|
+
DESERIALIZE +=
|
|
2227
|
+
indent +
|
|
2228
|
+
" if (" +
|
|
2229
|
+
(first.generic ? "isNullable<" + first.type + ">() && " : "") +
|
|
2230
|
+
getComparison(fName) +
|
|
2231
|
+
") { // " +
|
|
2232
|
+
fName +
|
|
2233
|
+
"\n";
|
|
2234
|
+
DESERIALIZE +=
|
|
2235
|
+
indent +
|
|
2236
|
+
" store<usize>(changetype<usize>(out), 0, offsetof<this>(" +
|
|
2237
|
+
JSON.stringify(first.name) +
|
|
2238
|
+
"));\n";
|
|
1607
2239
|
DESERIALIZE += indent + " srcStart += 2;\n";
|
|
1608
2240
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
1609
2241
|
DESERIALIZE += indent + " break;\n";
|
|
@@ -1611,8 +2243,19 @@ export class JSONTransform extends Visitor {
|
|
|
1611
2243
|
for (let i = 1; i < group.length; i++) {
|
|
1612
2244
|
const mem = group[i];
|
|
1613
2245
|
const memName = mem.alias || mem.name;
|
|
1614
|
-
DESERIALIZE +=
|
|
1615
|
-
|
|
2246
|
+
DESERIALIZE +=
|
|
2247
|
+
indent +
|
|
2248
|
+
" else if (" +
|
|
2249
|
+
(mem.generic ? "isNullable<" + mem.type + ">() && " : "") +
|
|
2250
|
+
getComparison(memName) +
|
|
2251
|
+
") { // " +
|
|
2252
|
+
memName +
|
|
2253
|
+
"\n";
|
|
2254
|
+
DESERIALIZE +=
|
|
2255
|
+
indent +
|
|
2256
|
+
" store<usize>(changetype<usize>(out), 0, offsetof<this>(" +
|
|
2257
|
+
JSON.stringify(mem.name) +
|
|
2258
|
+
"));\n";
|
|
1616
2259
|
DESERIALIZE += indent + " srcStart += 2;\n";
|
|
1617
2260
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
1618
2261
|
DESERIALIZE += indent + " break;\n";
|
|
@@ -1620,7 +2263,9 @@ export class JSONTransform extends Visitor {
|
|
|
1620
2263
|
}
|
|
1621
2264
|
if (STRICT) {
|
|
1622
2265
|
DESERIALIZE += " else {\n";
|
|
1623
|
-
DESERIALIZE +=
|
|
2266
|
+
DESERIALIZE +=
|
|
2267
|
+
indent +
|
|
2268
|
+
' throw new Error("Unexpected key value pair in JSON object \'" + JSON.Util.ptrToStr(keyStart, keyEnd) + ":" + JSON.Util.ptrToStr(lastIndex, srcStart) + "\' at position " + (srcEnd - srcStart).toString());\n';
|
|
1624
2269
|
DESERIALIZE += indent + " }\n";
|
|
1625
2270
|
}
|
|
1626
2271
|
else {
|
|
@@ -1649,7 +2294,13 @@ export class JSONTransform extends Visitor {
|
|
|
1649
2294
|
SERIALIZE += indent + "store<u16>(bs.offset, 125, 0); // }\n";
|
|
1650
2295
|
SERIALIZE += indent + "bs.offset += 2;\n";
|
|
1651
2296
|
SERIALIZE += "}";
|
|
1652
|
-
SERIALIZE =
|
|
2297
|
+
SERIALIZE =
|
|
2298
|
+
SERIALIZE.slice(0, 32) +
|
|
2299
|
+
indent +
|
|
2300
|
+
"bs.proposeSize(" +
|
|
2301
|
+
this.schema.byteSize +
|
|
2302
|
+
");\n" +
|
|
2303
|
+
SERIALIZE.slice(32);
|
|
1653
2304
|
INITIALIZE += " return this;\n";
|
|
1654
2305
|
INITIALIZE += "}";
|
|
1655
2306
|
if (DEBUG > 0) {
|
|
@@ -1659,24 +2310,37 @@ export class JSONTransform extends Visitor {
|
|
|
1659
2310
|
}
|
|
1660
2311
|
const SERIALIZE_METHOD = SimpleParser.parseClassMember(SERIALIZE_CUSTOM || SERIALIZE, node);
|
|
1661
2312
|
const INITIALIZE_METHOD = SimpleParser.parseClassMember(INITIALIZE, node);
|
|
1662
|
-
const DESERIALIZE_CUSTOM_METHOD = DESERIALIZE_CUSTOM
|
|
2313
|
+
const DESERIALIZE_CUSTOM_METHOD = DESERIALIZE_CUSTOM
|
|
2314
|
+
? SimpleParser.parseClassMember(DESERIALIZE_CUSTOM, node)
|
|
2315
|
+
: null;
|
|
1663
2316
|
const DESERIALIZE_SLOW_METHOD = SimpleParser.parseClassMember(DESERIALIZE, node);
|
|
1664
|
-
const DESERIALIZE_FAST_METHOD = useFastPath
|
|
2317
|
+
const DESERIALIZE_FAST_METHOD = useFastPath
|
|
2318
|
+
? SimpleParser.parseClassMember(DESERIALIZE_FAST, node)
|
|
2319
|
+
: null;
|
|
1665
2320
|
if (!node.members.find((v) => v.name.text == "__SERIALIZE"))
|
|
1666
2321
|
node.members.push(SERIALIZE_METHOD);
|
|
1667
|
-
if (INITIALIZE_METHOD &&
|
|
2322
|
+
if (INITIALIZE_METHOD &&
|
|
2323
|
+
!node.members.find((v) => v.name.text == "__INITIALIZE"))
|
|
1668
2324
|
node.members.push(INITIALIZE_METHOD);
|
|
1669
|
-
if (DESERIALIZE_CUSTOM_METHOD &&
|
|
2325
|
+
if (DESERIALIZE_CUSTOM_METHOD &&
|
|
2326
|
+
!node.members.find((v) => v.name.text == "__DESERIALIZE_CUSTOM"))
|
|
1670
2327
|
node.members.push(DESERIALIZE_CUSTOM_METHOD);
|
|
1671
|
-
if (!DESERIALIZE_CUSTOM &&
|
|
2328
|
+
if (!DESERIALIZE_CUSTOM &&
|
|
2329
|
+
DESERIALIZE_SLOW_METHOD &&
|
|
2330
|
+
!node.members.find((v) => v.name.text == "__DESERIALIZE_SLOW"))
|
|
1672
2331
|
node.members.push(DESERIALIZE_SLOW_METHOD);
|
|
1673
|
-
if (!DESERIALIZE_CUSTOM &&
|
|
2332
|
+
if (!DESERIALIZE_CUSTOM &&
|
|
2333
|
+
useFastPath &&
|
|
2334
|
+
DESERIALIZE_FAST_METHOD &&
|
|
2335
|
+
!node.members.find((v) => v.name.text == "__DESERIALIZE_FAST"))
|
|
1674
2336
|
node.members.push(DESERIALIZE_FAST_METHOD);
|
|
1675
2337
|
super.visitClassDeclaration(node);
|
|
1676
2338
|
}
|
|
1677
2339
|
getSchema(name) {
|
|
1678
2340
|
name = stripNull(name);
|
|
1679
|
-
return this.schemas
|
|
2341
|
+
return (this.schemas
|
|
2342
|
+
.get(this.schema.node.range.source.internalPath)
|
|
2343
|
+
.find((s) => s.name == name) || null);
|
|
1680
2344
|
}
|
|
1681
2345
|
generateEmptyMethods(node) {
|
|
1682
2346
|
const SERIALIZE_EMPTY = "@inline __SERIALIZE(ptr: usize): void {\n bs.proposeSize(4);\n store<u32>(bs.offset, 8192123);\n bs.offset += 4;\n}";
|
|
@@ -1692,7 +2356,8 @@ export class JSONTransform extends Visitor {
|
|
|
1692
2356
|
const DESERIALIZE_SLOW_METHOD_EMPTY = SimpleParser.parseClassMember(DESERIALIZE_SLOW_EMPTY, node);
|
|
1693
2357
|
if (!node.members.find((v) => v.name.text == "__SERIALIZE"))
|
|
1694
2358
|
node.members.push(SERIALIZE_METHOD_EMPTY);
|
|
1695
|
-
if (INITIALIZE_METHOD_EMPTY &&
|
|
2359
|
+
if (INITIALIZE_METHOD_EMPTY &&
|
|
2360
|
+
!node.members.find((v) => v.name.text == "__INITIALIZE"))
|
|
1696
2361
|
node.members.push(INITIALIZE_METHOD_EMPTY);
|
|
1697
2362
|
if (!node.members.find((v) => v.name.text == "__DESERIALIZE_SLOW"))
|
|
1698
2363
|
node.members.push(DESERIALIZE_SLOW_METHOD_EMPTY);
|
|
@@ -1709,140 +2374,84 @@ export class JSONTransform extends Visitor {
|
|
|
1709
2374
|
this.baseCWD = this.baseCWD.replaceAll("/", path.sep);
|
|
1710
2375
|
const baseDir = path.resolve(fileURLToPath(import.meta.url), "..", "..", "..");
|
|
1711
2376
|
let fromPath = node.range.source.normalizedPath.replaceAll("/", path.sep);
|
|
1712
|
-
fromPath = fromPath.startsWith("~lib")
|
|
2377
|
+
fromPath = fromPath.startsWith("~lib")
|
|
2378
|
+
? fromPath.slice(5)
|
|
2379
|
+
: path.join(this.baseCWD, fromPath);
|
|
1713
2380
|
const bsImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "bs" || d.name.text == "bs"));
|
|
1714
2381
|
const jsonImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "JSON" || d.name.text == "JSON"));
|
|
1715
2382
|
const atoiImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "atoi" || d.name.text == "atoi"));
|
|
1716
|
-
const deserializeIntegerFieldImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "deserializeIntegerField" || d.name.text == "deserializeIntegerField"));
|
|
1717
|
-
const deserializeUnsignedFieldImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "deserializeUnsignedField" || d.name.text == "deserializeUnsignedField"));
|
|
1718
|
-
const deserializeFloatFieldImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "deserializeFloatField" || d.name.text == "deserializeFloatField"));
|
|
1719
2383
|
const scanValueEndImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "scanValueEnd" || d.name.text == "scanValueEnd"));
|
|
1720
|
-
const
|
|
1721
|
-
const deserializeArrayInto_SWARImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "deserializeArrayInto_SWAR" || d.name.text == "deserializeArrayInto_SWAR"));
|
|
1722
|
-
const deserializeMapFieldImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "deserializeMapField" || d.name.text == "deserializeMapField"));
|
|
1723
|
-
const deserializeMapIntoImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "deserializeMapInto" || d.name.text == "deserializeMapInto"));
|
|
1724
|
-
const deserializeSetFieldImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "deserializeSetField" || d.name.text == "deserializeSetField"));
|
|
1725
|
-
const deserializeSetIntoImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "deserializeSetInto" || d.name.text == "deserializeSetInto"));
|
|
1726
|
-
const deserializeStaticArrayFieldImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "deserializeStaticArrayField" || d.name.text == "deserializeStaticArrayField"));
|
|
1727
|
-
const deserializeStringFieldSWARImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "deserializeStringField_SWAR" || d.name.text == "deserializeStringField_SWAR"));
|
|
1728
|
-
const deserializeStringFieldSIMDImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "deserializeStringField_SIMD" || d.name.text == "deserializeStringField_SIMD"));
|
|
2384
|
+
const fieldHelpersImport = this.imports.find((i) => i.declarations?.find((d) => d.name.text == "__deserializeStringField"));
|
|
1729
2385
|
const sourceText = readFileSync(fromPath).toString();
|
|
1730
|
-
const hasLocalDeserializeIntegerField = /\bdeserializeIntegerField\b/.test(sourceText);
|
|
1731
|
-
const hasLocalDeserializeUnsignedField = /\bdeserializeUnsignedField\b/.test(sourceText);
|
|
1732
|
-
const hasLocalDeserializeFloatField = /\bdeserializeFloatField\b/.test(sourceText);
|
|
1733
2386
|
const hasLocalScanValueEnd = /\bscanValueEnd\b/.test(sourceText);
|
|
1734
|
-
const
|
|
1735
|
-
const hasLocaldeserializeArrayInto_SWAR = /\bdeserializeArrayInto_SWAR\b/.test(sourceText);
|
|
1736
|
-
const hasLocaldeserializeMapField = /\bdeserializeMapField\b/.test(sourceText);
|
|
1737
|
-
const hasLocaldeserializeMapInto = /\bdeserializeMapInto\b/.test(sourceText);
|
|
1738
|
-
const hasLocaldeserializeSetField = /\bdeserializeSetField\b/.test(sourceText);
|
|
1739
|
-
const hasLocaldeserializeSetInto = /\bdeserializeSetInto\b/.test(sourceText);
|
|
1740
|
-
const hasLocaldeserializeStaticArrayField = /\bdeserializeStaticArrayField\b/.test(sourceText);
|
|
1741
|
-
const hasLocalDeserializeStringFieldSWAR = /\bdeserializeStringField_SWAR\b/.test(sourceText);
|
|
1742
|
-
const hasLocalDeserializeStringFieldSIMD = /\bdeserializeStringField_SIMD\b/.test(sourceText);
|
|
1743
|
-
let baseRel = path.posix.join(...path.relative(path.dirname(fromPath), path.join(baseDir)).split(path.sep));
|
|
1744
|
-
if (baseRel.endsWith("json-as")) {
|
|
1745
|
-
baseRel = "json-as" + baseRel.slice(baseRel.indexOf("json-as") + 7);
|
|
1746
|
-
}
|
|
1747
|
-
else if (!baseRel.startsWith(".") && !baseRel.startsWith("/") && !baseRel.startsWith("json-as")) {
|
|
1748
|
-
baseRel = "./" + baseRel;
|
|
1749
|
-
}
|
|
2387
|
+
const baseRel = computeImportBaseRel(path.dirname(fromPath), path.join(baseDir));
|
|
1750
2388
|
if (!bsImport) {
|
|
1751
|
-
const replaceNode = Node.createImportStatement([
|
|
2389
|
+
const replaceNode = Node.createImportStatement([
|
|
2390
|
+
Node.createImportDeclaration(Node.createIdentifierExpression("bs", node.range, false), null, node.range),
|
|
2391
|
+
], Node.createStringLiteralExpression(path.posix.join(baseRel, "lib", "as-bs"), node.range), node.range);
|
|
1752
2392
|
node.range.source.statements.unshift(replaceNode);
|
|
1753
2393
|
if (DEBUG > 0)
|
|
1754
|
-
console.log("Added import: " +
|
|
2394
|
+
console.log("Added import: " +
|
|
2395
|
+
toString(replaceNode) +
|
|
2396
|
+
" to " +
|
|
2397
|
+
node.range.source.normalizedPath +
|
|
2398
|
+
"\n");
|
|
1755
2399
|
}
|
|
1756
2400
|
if (!jsonImport) {
|
|
1757
|
-
const replaceNode = Node.createImportStatement([
|
|
2401
|
+
const replaceNode = Node.createImportStatement([
|
|
2402
|
+
Node.createImportDeclaration(Node.createIdentifierExpression("JSON", node.range, false), null, node.range),
|
|
2403
|
+
], Node.createStringLiteralExpression(path.posix.join(baseRel, "assembly", "index"), node.range), node.range);
|
|
1758
2404
|
node.range.source.statements.unshift(replaceNode);
|
|
1759
2405
|
if (DEBUG > 0)
|
|
1760
|
-
console.log("Added import: " +
|
|
2406
|
+
console.log("Added import: " +
|
|
2407
|
+
toString(replaceNode) +
|
|
2408
|
+
" to " +
|
|
2409
|
+
node.range.source.normalizedPath +
|
|
2410
|
+
"\n");
|
|
1761
2411
|
}
|
|
1762
2412
|
if (!atoiImport) {
|
|
1763
|
-
const replaceNode = Node.createImportStatement([
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
console.log("Added import: " + toString(replaceNode) + " to " + node.range.source.normalizedPath + "\n");
|
|
1767
|
-
}
|
|
1768
|
-
if (!deserializeIntegerFieldImport && !hasLocalDeserializeIntegerField) {
|
|
1769
|
-
const replaceNode = Node.createImportStatement([Node.createImportDeclaration(Node.createIdentifierExpression("deserializeIntegerField", node.range, false), null, node.range)], Node.createStringLiteralExpression(path.posix.join(baseRel, "assembly", "deserialize", "simple", "integer"), node.range), node.range);
|
|
1770
|
-
node.range.source.statements.unshift(replaceNode);
|
|
1771
|
-
if (DEBUG > 0)
|
|
1772
|
-
console.log("Added import: " + toString(replaceNode) + " to " + node.range.source.normalizedPath + "\n");
|
|
1773
|
-
}
|
|
1774
|
-
if (!deserializeUnsignedFieldImport && !hasLocalDeserializeUnsignedField) {
|
|
1775
|
-
const replaceNode = Node.createImportStatement([Node.createImportDeclaration(Node.createIdentifierExpression("deserializeUnsignedField", node.range, false), null, node.range)], Node.createStringLiteralExpression(path.posix.join(baseRel, "assembly", "deserialize", "simple", "unsigned"), node.range), node.range);
|
|
2413
|
+
const replaceNode = Node.createImportStatement([
|
|
2414
|
+
Node.createImportDeclaration(Node.createIdentifierExpression("atoi", node.range, false), null, node.range),
|
|
2415
|
+
], Node.createStringLiteralExpression(path.posix.join(baseRel, "assembly", "util", "atoi"), node.range), node.range);
|
|
1776
2416
|
node.range.source.statements.unshift(replaceNode);
|
|
1777
2417
|
if (DEBUG > 0)
|
|
1778
|
-
console.log("Added import: " +
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
if (DEBUG > 0)
|
|
1784
|
-
console.log("Added import: " + toString(replaceNode) + " to " + node.range.source.normalizedPath + "\n");
|
|
2418
|
+
console.log("Added import: " +
|
|
2419
|
+
toString(replaceNode) +
|
|
2420
|
+
" to " +
|
|
2421
|
+
node.range.source.normalizedPath +
|
|
2422
|
+
"\n");
|
|
1785
2423
|
}
|
|
1786
2424
|
if (!scanValueEndImport && !hasLocalScanValueEnd) {
|
|
1787
|
-
const replaceNode = Node.createImportStatement([
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
console.log("Added import: " + toString(replaceNode) + " to " + node.range.source.normalizedPath + "\n");
|
|
1791
|
-
}
|
|
1792
|
-
if (!deserializeArrayField_SWARImport && !hasLocaldeserializeArrayField_SWAR) {
|
|
1793
|
-
const replaceNode = Node.createImportStatement([Node.createImportDeclaration(Node.createIdentifierExpression("deserializeArrayField_SWAR", node.range, false), null, node.range)], Node.createStringLiteralExpression(path.posix.join(baseRel, "assembly", "deserialize", "simple", "array"), node.range), node.range);
|
|
2425
|
+
const replaceNode = Node.createImportStatement([
|
|
2426
|
+
Node.createImportDeclaration(Node.createIdentifierExpression("scanValueEnd", node.range, false), null, node.range),
|
|
2427
|
+
], Node.createStringLiteralExpression(path.posix.join(baseRel, "assembly", "deserialize", "swar", "array", "shared"), node.range), node.range);
|
|
1794
2428
|
node.range.source.statements.unshift(replaceNode);
|
|
1795
2429
|
if (DEBUG > 0)
|
|
1796
|
-
console.log("Added import: " +
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
console.log("Added import: " + toString(replaceNode) + " to " + node.range.source.normalizedPath + "\n");
|
|
1815
|
-
}
|
|
1816
|
-
if (!deserializeSetFieldImport && !hasLocaldeserializeSetField) {
|
|
1817
|
-
const replaceNode = Node.createImportStatement([Node.createImportDeclaration(Node.createIdentifierExpression("deserializeSetField", node.range, false), null, node.range)], Node.createStringLiteralExpression(path.posix.join(baseRel, "assembly", "deserialize", "simple", "set"), node.range), node.range);
|
|
1818
|
-
node.range.source.statements.unshift(replaceNode);
|
|
1819
|
-
if (DEBUG > 0)
|
|
1820
|
-
console.log("Added import: " + toString(replaceNode) + " to " + node.range.source.normalizedPath + "\n");
|
|
1821
|
-
}
|
|
1822
|
-
if (!deserializeSetIntoImport && !hasLocaldeserializeSetInto) {
|
|
1823
|
-
const replaceNode = Node.createImportStatement([Node.createImportDeclaration(Node.createIdentifierExpression("deserializeSetInto", node.range, false), null, node.range)], Node.createStringLiteralExpression(path.posix.join(baseRel, "assembly", "deserialize", "simple", "set"), node.range), node.range);
|
|
1824
|
-
node.range.source.statements.unshift(replaceNode);
|
|
1825
|
-
if (DEBUG > 0)
|
|
1826
|
-
console.log("Added import: " + toString(replaceNode) + " to " + node.range.source.normalizedPath + "\n");
|
|
1827
|
-
}
|
|
1828
|
-
if (!deserializeStaticArrayFieldImport && !hasLocaldeserializeStaticArrayField) {
|
|
1829
|
-
const replaceNode = Node.createImportStatement([Node.createImportDeclaration(Node.createIdentifierExpression("deserializeStaticArrayField", node.range, false), null, node.range)], Node.createStringLiteralExpression(path.posix.join(baseRel, "assembly", "deserialize", "simple", "staticarray"), node.range), node.range);
|
|
1830
|
-
node.range.source.statements.unshift(replaceNode);
|
|
1831
|
-
if (DEBUG > 0)
|
|
1832
|
-
console.log("Added import: " + toString(replaceNode) + " to " + node.range.source.normalizedPath + "\n");
|
|
1833
|
-
}
|
|
1834
|
-
const codegenMode = getCodegenMode(this.program);
|
|
1835
|
-
if (codegenMode !== JSONMode.SIMD && !deserializeStringFieldSWARImport && !hasLocalDeserializeStringFieldSWAR) {
|
|
1836
|
-
const replaceNode = Node.createImportStatement([Node.createImportDeclaration(Node.createIdentifierExpression("deserializeStringField_SWAR", node.range, false), null, node.range)], Node.createStringLiteralExpression(path.posix.join(baseRel, "assembly", "deserialize", "swar", "string"), node.range), node.range);
|
|
1837
|
-
node.range.source.statements.unshift(replaceNode);
|
|
1838
|
-
if (DEBUG > 0)
|
|
1839
|
-
console.log("Added import: " + toString(replaceNode) + " to " + node.range.source.normalizedPath + "\n");
|
|
1840
|
-
}
|
|
1841
|
-
if (codegenMode === JSONMode.SIMD && !deserializeStringFieldSIMDImport && !hasLocalDeserializeStringFieldSIMD) {
|
|
1842
|
-
const replaceNode = Node.createImportStatement([Node.createImportDeclaration(Node.createIdentifierExpression("deserializeStringField_SIMD", node.range, false), null, node.range)], Node.createStringLiteralExpression(path.posix.join(baseRel, "assembly", "deserialize", "simd", "string"), node.range), node.range);
|
|
2430
|
+
console.log("Added import: " +
|
|
2431
|
+
toString(replaceNode) +
|
|
2432
|
+
" to " +
|
|
2433
|
+
node.range.source.normalizedPath +
|
|
2434
|
+
"\n");
|
|
2435
|
+
}
|
|
2436
|
+
if (!fieldHelpersImport) {
|
|
2437
|
+
const fieldHelper = (real, alias) => Node.createImportDeclaration(Node.createIdentifierExpression(real, node.range, false), Node.createIdentifierExpression(alias, node.range, false), node.range);
|
|
2438
|
+
const replaceNode = Node.createImportStatement([
|
|
2439
|
+
fieldHelper("deserializeIntegerField", "__deserializeIntegerField"),
|
|
2440
|
+
fieldHelper("deserializeUnsignedField", "__deserializeUnsignedField"),
|
|
2441
|
+
fieldHelper("deserializeFloatField", "__deserializeFloatField"),
|
|
2442
|
+
fieldHelper("deserializeStringField", "__deserializeStringField"),
|
|
2443
|
+
fieldHelper("deserializeArrayField_SWAR", "__deserializeArrayField_SWAR"),
|
|
2444
|
+
fieldHelper("deserializeMapField", "__deserializeMapField"),
|
|
2445
|
+
fieldHelper("deserializeSetField", "__deserializeSetField"),
|
|
2446
|
+
fieldHelper("deserializeStaticArrayField", "__deserializeStaticArrayField"),
|
|
2447
|
+
], Node.createStringLiteralExpression(path.posix.join(baseRel, "assembly", "deserialize"), node.range), node.range);
|
|
1843
2448
|
node.range.source.statements.unshift(replaceNode);
|
|
1844
2449
|
if (DEBUG > 0)
|
|
1845
|
-
console.log("Added import: " +
|
|
2450
|
+
console.log("Added import: " +
|
|
2451
|
+
toString(replaceNode) +
|
|
2452
|
+
" to " +
|
|
2453
|
+
node.range.source.normalizedPath +
|
|
2454
|
+
"\n");
|
|
1846
2455
|
}
|
|
1847
2456
|
}
|
|
1848
2457
|
getStores(data, simd = false) {
|
|
@@ -1855,19 +2464,39 @@ export class JSONTransform extends Visitor {
|
|
|
1855
2464
|
const name = "SIMD_" + (index == -1 ? this.simdStatements.length : index);
|
|
1856
2465
|
if (index == -1)
|
|
1857
2466
|
this.simdStatements.push(`const ${name} = ${num};`);
|
|
1858
|
-
out.push("store<v128>(bs.offset, " +
|
|
2467
|
+
out.push("store<v128>(bs.offset, " +
|
|
2468
|
+
name +
|
|
2469
|
+
", " +
|
|
2470
|
+
offset +
|
|
2471
|
+
"); // " +
|
|
2472
|
+
data.slice(offset >> 1, (offset >> 1) + 8));
|
|
1859
2473
|
offset += 16;
|
|
1860
2474
|
}
|
|
1861
2475
|
if (size == "u64") {
|
|
1862
|
-
out.push("store<u64>(bs.offset, " +
|
|
2476
|
+
out.push("store<u64>(bs.offset, " +
|
|
2477
|
+
num +
|
|
2478
|
+
", " +
|
|
2479
|
+
offset +
|
|
2480
|
+
"); // " +
|
|
2481
|
+
data.slice(offset >> 1, (offset >> 1) + 4));
|
|
1863
2482
|
offset += 8;
|
|
1864
2483
|
}
|
|
1865
2484
|
else if (size == "u32") {
|
|
1866
|
-
out.push("store<u32>(bs.offset, " +
|
|
2485
|
+
out.push("store<u32>(bs.offset, " +
|
|
2486
|
+
num +
|
|
2487
|
+
", " +
|
|
2488
|
+
offset +
|
|
2489
|
+
"); // " +
|
|
2490
|
+
data.slice(offset >> 1, (offset >> 1) + 2));
|
|
1867
2491
|
offset += 4;
|
|
1868
2492
|
}
|
|
1869
2493
|
else if (size == "u16") {
|
|
1870
|
-
out.push("store<u16>(bs.offset, " +
|
|
2494
|
+
out.push("store<u16>(bs.offset, " +
|
|
2495
|
+
num +
|
|
2496
|
+
", " +
|
|
2497
|
+
offset +
|
|
2498
|
+
"); // " +
|
|
2499
|
+
data.slice(offset >> 1, (offset >> 1) + 1));
|
|
1871
2500
|
offset += 2;
|
|
1872
2501
|
}
|
|
1873
2502
|
}
|
|
@@ -1875,7 +2504,31 @@ export class JSONTransform extends Visitor {
|
|
|
1875
2504
|
return out;
|
|
1876
2505
|
}
|
|
1877
2506
|
isValidType(type, node) {
|
|
1878
|
-
const validTypes = [
|
|
2507
|
+
const validTypes = [
|
|
2508
|
+
"string",
|
|
2509
|
+
"u8",
|
|
2510
|
+
"i8",
|
|
2511
|
+
"u16",
|
|
2512
|
+
"i16",
|
|
2513
|
+
"u32",
|
|
2514
|
+
"i32",
|
|
2515
|
+
"u64",
|
|
2516
|
+
"i64",
|
|
2517
|
+
"f32",
|
|
2518
|
+
"f64",
|
|
2519
|
+
"bool",
|
|
2520
|
+
"boolean",
|
|
2521
|
+
"Date",
|
|
2522
|
+
"JSON.Value",
|
|
2523
|
+
"JSON.Obj",
|
|
2524
|
+
"JSON.Raw",
|
|
2525
|
+
"Value",
|
|
2526
|
+
"Obj",
|
|
2527
|
+
"Raw",
|
|
2528
|
+
...this.schemas
|
|
2529
|
+
.get(this.schema.node.range.source.internalPath)
|
|
2530
|
+
.map((v) => v.name),
|
|
2531
|
+
];
|
|
1879
2532
|
const baseTypes = ["Array", "StaticArray", "Map", "Set", "JSON.Box", "Box"];
|
|
1880
2533
|
if (node && node.isGeneric && node.typeParameters)
|
|
1881
2534
|
validTypes.push(...node.typeParameters.map((v) => v.name.text));
|
|
@@ -1885,7 +2538,8 @@ export class JSONTransform extends Visitor {
|
|
|
1885
2538
|
return this.isValidType(type.slice(0, type.length - 7), node);
|
|
1886
2539
|
}
|
|
1887
2540
|
if (type.includes("<"))
|
|
1888
|
-
return baseTypes.includes(type.slice(0, type.indexOf("<"))) &&
|
|
2541
|
+
return (baseTypes.includes(type.slice(0, type.indexOf("<"))) &&
|
|
2542
|
+
this.isValidType(type.slice(type.indexOf("<") + 1, type.lastIndexOf(">")), node));
|
|
1889
2543
|
if (validTypes.includes(type))
|
|
1890
2544
|
return true;
|
|
1891
2545
|
return false;
|
|
@@ -1899,7 +2553,9 @@ var JSONMode;
|
|
|
1899
2553
|
})(JSONMode || (JSONMode = {}));
|
|
1900
2554
|
let MODE = JSONMode.SWAR;
|
|
1901
2555
|
function getCodegenMode(program) {
|
|
1902
|
-
let mode = program.options.hasFeature(16)
|
|
2556
|
+
let mode = program.options.hasFeature(16)
|
|
2557
|
+
? JSONMode.SIMD
|
|
2558
|
+
: JSONMode.SWAR;
|
|
1903
2559
|
if (process.env["JSON_MODE"]) {
|
|
1904
2560
|
switch (process.env["JSON_MODE"].toLowerCase().trim()) {
|
|
1905
2561
|
case "simd":
|
|
@@ -1946,7 +2602,10 @@ export default class Transformer extends Transform {
|
|
|
1946
2602
|
const sources = parser.sources
|
|
1947
2603
|
.filter((source) => {
|
|
1948
2604
|
const p = source.internalPath;
|
|
1949
|
-
if (p.startsWith("~lib/rt") ||
|
|
2605
|
+
if (p.startsWith("~lib/rt") ||
|
|
2606
|
+
p.startsWith("~lib/performance") ||
|
|
2607
|
+
p.startsWith("~lib/wasi_") ||
|
|
2608
|
+
p.startsWith("~lib/shared/")) {
|
|
1950
2609
|
return false;
|
|
1951
2610
|
}
|
|
1952
2611
|
return !isStdlib(source);
|
|
@@ -2013,10 +2672,15 @@ function toU32(data, offset = 0) {
|
|
|
2013
2672
|
return (data.charCodeAt(offset + 1) << 16) | data.charCodeAt(offset + 0);
|
|
2014
2673
|
}
|
|
2015
2674
|
function toU48(data, offset = 0) {
|
|
2016
|
-
return (BigInt(data.charCodeAt(offset + 2)) << 32n) |
|
|
2675
|
+
return ((BigInt(data.charCodeAt(offset + 2)) << 32n) |
|
|
2676
|
+
(BigInt(data.charCodeAt(offset + 1)) << 16n) |
|
|
2677
|
+
BigInt(data.charCodeAt(offset + 0)));
|
|
2017
2678
|
}
|
|
2018
2679
|
function toU64(data, offset = 0) {
|
|
2019
|
-
return (BigInt(data.charCodeAt(offset + 3)) << 48n) |
|
|
2680
|
+
return ((BigInt(data.charCodeAt(offset + 3)) << 48n) |
|
|
2681
|
+
(BigInt(data.charCodeAt(offset + 2)) << 32n) |
|
|
2682
|
+
(BigInt(data.charCodeAt(offset + 1)) << 16n) |
|
|
2683
|
+
BigInt(data.charCodeAt(offset + 0)));
|
|
2020
2684
|
}
|
|
2021
2685
|
function toMemCDecl(n, indent) {
|
|
2022
2686
|
let out = "";
|
|
@@ -2059,12 +2723,34 @@ function strToNum(data, simd = false, offset = 0) {
|
|
|
2059
2723
|
const out = [];
|
|
2060
2724
|
let n = data.length;
|
|
2061
2725
|
while (n >= 8 && simd) {
|
|
2062
|
-
out.push([
|
|
2726
|
+
out.push([
|
|
2727
|
+
"v128",
|
|
2728
|
+
"i16x8(" +
|
|
2729
|
+
data.charCodeAt(offset + 0) +
|
|
2730
|
+
", " +
|
|
2731
|
+
data.charCodeAt(offset + 1) +
|
|
2732
|
+
", " +
|
|
2733
|
+
data.charCodeAt(offset + 2) +
|
|
2734
|
+
", " +
|
|
2735
|
+
data.charCodeAt(offset + 3) +
|
|
2736
|
+
", " +
|
|
2737
|
+
data.charCodeAt(offset + 4) +
|
|
2738
|
+
", " +
|
|
2739
|
+
data.charCodeAt(offset + 5) +
|
|
2740
|
+
", " +
|
|
2741
|
+
data.charCodeAt(offset + 6) +
|
|
2742
|
+
", " +
|
|
2743
|
+
data.charCodeAt(offset + 7) +
|
|
2744
|
+
")",
|
|
2745
|
+
]);
|
|
2063
2746
|
offset += 8;
|
|
2064
2747
|
n -= 8;
|
|
2065
2748
|
}
|
|
2066
2749
|
while (n >= 4) {
|
|
2067
|
-
const value = (BigInt(data.charCodeAt(offset + 3)) << 48n) |
|
|
2750
|
+
const value = (BigInt(data.charCodeAt(offset + 3)) << 48n) |
|
|
2751
|
+
(BigInt(data.charCodeAt(offset + 2)) << 32n) |
|
|
2752
|
+
(BigInt(data.charCodeAt(offset + 1)) << 16n) |
|
|
2753
|
+
BigInt(data.charCodeAt(offset + 0));
|
|
2068
2754
|
out.push(["u64", value.toString()]);
|
|
2069
2755
|
offset += 4;
|
|
2070
2756
|
n -= 4;
|
|
@@ -2140,7 +2826,12 @@ function estimatedSerializedByteSize(type, source, parser) {
|
|
|
2140
2826
|
else if (isArray(baseType) || baseType.startsWith("Map<")) {
|
|
2141
2827
|
estimated = 4;
|
|
2142
2828
|
}
|
|
2143
|
-
else if (baseType == "JSON.Obj" ||
|
|
2829
|
+
else if (baseType == "JSON.Obj" ||
|
|
2830
|
+
baseType == "Obj" ||
|
|
2831
|
+
baseType == "JSON.Raw" ||
|
|
2832
|
+
baseType == "Raw" ||
|
|
2833
|
+
baseType == "JSON.Value" ||
|
|
2834
|
+
baseType == "Value") {
|
|
2144
2835
|
estimated = 4;
|
|
2145
2836
|
}
|
|
2146
2837
|
else if (baseType == "ArrayBuffer" || needsReferenceLoad(baseType)) {
|
|
@@ -2156,7 +2847,20 @@ function estimatedSerializedByteSize(type, source, parser) {
|
|
|
2156
2847
|
return estimated;
|
|
2157
2848
|
}
|
|
2158
2849
|
function isPrimitive(type) {
|
|
2159
|
-
const primitiveTypes = [
|
|
2850
|
+
const primitiveTypes = [
|
|
2851
|
+
"u8",
|
|
2852
|
+
"u16",
|
|
2853
|
+
"u32",
|
|
2854
|
+
"u64",
|
|
2855
|
+
"i8",
|
|
2856
|
+
"i16",
|
|
2857
|
+
"i32",
|
|
2858
|
+
"i64",
|
|
2859
|
+
"f32",
|
|
2860
|
+
"f64",
|
|
2861
|
+
"bool",
|
|
2862
|
+
"boolean",
|
|
2863
|
+
];
|
|
2160
2864
|
return primitiveTypes.some((v) => type.startsWith(v));
|
|
2161
2865
|
}
|
|
2162
2866
|
function isBoolean(type) {
|
|
@@ -2166,10 +2870,12 @@ function isString(type) {
|
|
|
2166
2870
|
return stripNull(type) == "string" || stripNull(type) == "String";
|
|
2167
2871
|
}
|
|
2168
2872
|
function isArray(type) {
|
|
2169
|
-
return type.startsWith("Array<") ||
|
|
2873
|
+
return (type.startsWith("Array<") ||
|
|
2874
|
+
type.startsWith("Set<") ||
|
|
2875
|
+
type.startsWith("StaticArray<"));
|
|
2170
2876
|
}
|
|
2171
2877
|
function isEnum(type, source, parser) {
|
|
2172
|
-
return source.getEnum(type) != null || source.getImportedEnum(type, parser) != null;
|
|
2878
|
+
return (source.getEnum(type) != null || source.getImportedEnum(type, parser) != null);
|
|
2173
2879
|
}
|
|
2174
2880
|
export function stripNull(type) {
|
|
2175
2881
|
if (type.endsWith(" | null")) {
|