json-as 1.3.5 → 1.3.7
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 +17 -1
- package/assembly/deserialize/helpers/uint.ts +4 -1
- package/assembly/deserialize/index/arbitrary.ts +5 -1
- package/assembly/deserialize/index/array.ts +13 -3
- package/assembly/deserialize/index/integer.ts +68 -1
- package/assembly/deserialize/index/string.ts +4 -1
- package/assembly/deserialize/index/typedarray.ts +13 -3
- package/assembly/deserialize/index/unsigned.ts +78 -1
- package/assembly/deserialize/simd/array/integer.ts +327 -50
- package/assembly/deserialize/simd/integer.ts +233 -0
- package/assembly/deserialize/simd/string.ts +45 -11
- package/assembly/deserialize/simple/arbitrary.ts +11 -4
- package/assembly/deserialize/simple/array/arbitrary.ts +24 -5
- package/assembly/deserialize/simple/array/array.ts +8 -2
- package/assembly/deserialize/simple/array/bool.ts +38 -7
- package/assembly/deserialize/simple/array/box.ts +8 -2
- package/assembly/deserialize/simple/array/float.ts +36 -9
- package/assembly/deserialize/simple/array/generic.ts +12 -4
- package/assembly/deserialize/simple/array/integer.ts +8 -2
- package/assembly/deserialize/simple/array/map.ts +26 -6
- package/assembly/deserialize/simple/array/object.ts +26 -6
- package/assembly/deserialize/simple/array/raw.ts +34 -7
- package/assembly/deserialize/simple/array/string.ts +8 -2
- package/assembly/deserialize/simple/array/struct.ts +26 -6
- package/assembly/deserialize/simple/array.ts +13 -3
- package/assembly/deserialize/simple/bool.ts +6 -2
- package/assembly/deserialize/simple/float.ts +6 -1
- package/assembly/deserialize/simple/integer.ts +10 -2
- package/assembly/deserialize/simple/map.ts +95 -22
- package/assembly/deserialize/simple/object.ts +63 -14
- package/assembly/deserialize/simple/raw.ts +4 -1
- package/assembly/deserialize/simple/set.ts +59 -14
- package/assembly/deserialize/simple/staticarray/string.ts +11 -3
- package/assembly/deserialize/simple/staticarray.ts +64 -14
- package/assembly/deserialize/simple/string.ts +5 -92
- package/assembly/deserialize/simple/struct.ts +5 -1
- package/assembly/deserialize/simple/typedarray.ts +16 -3
- package/assembly/deserialize/simple/unsigned.ts +10 -15
- package/assembly/deserialize/swar/array/arbitrary.ts +5 -1
- package/assembly/deserialize/swar/array/array.ts +30 -6
- package/assembly/deserialize/swar/array/bool.ts +22 -4
- package/assembly/deserialize/swar/array/box.ts +5 -1
- package/assembly/deserialize/swar/array/float.ts +15 -3
- package/assembly/deserialize/swar/array/generic.ts +24 -7
- package/assembly/deserialize/swar/array/integer.ts +328 -84
- package/assembly/deserialize/swar/array/map.ts +5 -1
- package/assembly/deserialize/swar/array/object.ts +27 -7
- package/assembly/deserialize/swar/array/raw.ts +5 -1
- package/assembly/deserialize/swar/array/shared.ts +36 -11
- package/assembly/deserialize/swar/array/string.ts +20 -4
- package/assembly/deserialize/swar/array/struct.ts +27 -7
- package/assembly/deserialize/swar/array.ts +19 -4
- package/assembly/deserialize/swar/integer.ts +246 -0
- package/assembly/deserialize/swar/string.ts +98 -194
- package/assembly/index.d.ts +3 -1
- package/assembly/index.ts +312 -81
- package/assembly/serialize/index/float.ts +5 -1
- package/assembly/serialize/index/typedarray.ts +25 -7
- package/assembly/serialize/simd/string.ts +6 -2
- package/assembly/serialize/simple/array.ts +179 -1
- package/assembly/serialize/simple/float.ts +4 -1
- package/assembly/serialize/simple/integer.ts +9 -9
- package/assembly/serialize/simple/map.ts +6 -2
- package/assembly/serialize/simple/raw.ts +5 -1
- package/assembly/serialize/simple/set.ts +6 -1
- package/assembly/serialize/simple/staticarray.ts +6 -1
- package/assembly/serialize/simple/string.ts +0 -1
- package/assembly/serialize/simple/typedarray.ts +10 -3
- package/assembly/serialize/swar/string.ts +25 -8
- package/assembly/tsconfig.json +1 -21
- 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 +43 -14
- package/assembly/util/itoa-fast.ts +230 -0
- package/assembly/util/masks.ts +18 -1
- package/assembly/util/parsefloat-fast.ts +167 -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 +13 -5
- package/package.json +12 -4
- 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 +1 -0
- package/transform/lib/index.d.ts.map +1 -1
- package/transform/lib/index.js +1030 -241
- 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/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,26 @@ 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
|
+
}
|
|
18
35
|
function envFlagDefaultTrue(value) {
|
|
19
36
|
if (!value)
|
|
20
37
|
return true;
|
|
@@ -37,7 +54,11 @@ function parseJSONCacheConfig(value) {
|
|
|
37
54
|
if (!raw)
|
|
38
55
|
return { enabled: false, bytes: 0 };
|
|
39
56
|
const lower = raw.toLowerCase();
|
|
40
|
-
if (lower === "false" ||
|
|
57
|
+
if (lower === "false" ||
|
|
58
|
+
lower === "off" ||
|
|
59
|
+
lower === "no" ||
|
|
60
|
+
lower === "none" ||
|
|
61
|
+
lower === "0") {
|
|
41
62
|
return { enabled: false, bytes: 0 };
|
|
42
63
|
}
|
|
43
64
|
if (lower === "true" || lower === "on" || lower === "yes") {
|
|
@@ -53,7 +74,13 @@ function parseJSONCacheConfig(value) {
|
|
|
53
74
|
throw new Error(`Invalid JSON_CACHE value '${value}'.`);
|
|
54
75
|
}
|
|
55
76
|
const unit = suffix[0];
|
|
56
|
-
const scale = unit == "k" || unit == "K"
|
|
77
|
+
const scale = unit == "k" || unit == "K"
|
|
78
|
+
? 1_000
|
|
79
|
+
: unit == "m" || unit == "M"
|
|
80
|
+
? 1_000_000
|
|
81
|
+
: unit == "g" || unit == "G"
|
|
82
|
+
? 1_000_000_000
|
|
83
|
+
: 1;
|
|
57
84
|
let bytes = amount * scale;
|
|
58
85
|
if (suffix.endsWith("b")) {
|
|
59
86
|
bytes = Math.ceil(bytes / 8);
|
|
@@ -68,15 +95,42 @@ function parseJSONCacheConfig(value) {
|
|
|
68
95
|
}
|
|
69
96
|
const JSON_CACHE_CONFIG = parseJSONCacheConfig(process.env["JSON_CACHE"]);
|
|
70
97
|
function needsReferenceLoad(type) {
|
|
71
|
-
return type == "ArrayBuffer" ||
|
|
98
|
+
return (type == "ArrayBuffer" ||
|
|
99
|
+
type == "Int8Array" ||
|
|
100
|
+
type == "Uint8Array" ||
|
|
101
|
+
type == "Uint8ClampedArray" ||
|
|
102
|
+
type == "Int16Array" ||
|
|
103
|
+
type == "Uint16Array" ||
|
|
104
|
+
type == "Int32Array" ||
|
|
105
|
+
type == "Uint32Array" ||
|
|
106
|
+
type == "Int64Array" ||
|
|
107
|
+
type == "Uint64Array" ||
|
|
108
|
+
type == "Float32Array" ||
|
|
109
|
+
type == "Float64Array");
|
|
72
110
|
}
|
|
73
111
|
function getSerializeCall(type, realName) {
|
|
74
112
|
if (type == "ArrayBuffer") {
|
|
75
113
|
return `JSON.__serialize<ArrayBuffer>(load<ArrayBuffer>(ptr, offsetof<this>(${JSON.stringify(realName)})));\n`;
|
|
76
114
|
}
|
|
77
|
-
return needsReferenceLoad(type)
|
|
115
|
+
return needsReferenceLoad(type)
|
|
116
|
+
? `JSON.__serialize<${type}>(changetype<${type}>(load<usize>(ptr, offsetof<this>(${JSON.stringify(realName)}))));\n`
|
|
117
|
+
: `JSON.__serialize<${type}>(load<${type}>(ptr, offsetof<this>(${JSON.stringify(realName)})));\n`;
|
|
78
118
|
}
|
|
79
|
-
const CUSTOM_JSON_KINDS = new Set([
|
|
119
|
+
const CUSTOM_JSON_KINDS = new Set([
|
|
120
|
+
"any",
|
|
121
|
+
"string",
|
|
122
|
+
"number",
|
|
123
|
+
"object",
|
|
124
|
+
"array",
|
|
125
|
+
"boolean",
|
|
126
|
+
"null",
|
|
127
|
+
"any | null",
|
|
128
|
+
"string | null",
|
|
129
|
+
"number | null",
|
|
130
|
+
"object | null",
|
|
131
|
+
"array | null",
|
|
132
|
+
"boolean | null",
|
|
133
|
+
]);
|
|
80
134
|
function parseCustomJsonKind(method, decoratorName) {
|
|
81
135
|
const decorator = method.decorators?.find((v) => v.name.text.toLowerCase() == decoratorName);
|
|
82
136
|
if (!decorator || !decorator.args || decorator.args.length == 0)
|
|
@@ -84,7 +138,8 @@ function parseCustomJsonKind(method, decoratorName) {
|
|
|
84
138
|
if (decorator.args.length > 1)
|
|
85
139
|
throwError(`@${decoratorName} accepts at most one argument`, decorator.range);
|
|
86
140
|
const arg = decorator.args[0];
|
|
87
|
-
if (arg.kind != NodeKind.Literal ||
|
|
141
|
+
if (arg.kind != NodeKind.Literal ||
|
|
142
|
+
arg.literalKind != 2) {
|
|
88
143
|
throwError(`@${decoratorName} argument must be a string literal like @${decoratorName}("string")`, arg.range);
|
|
89
144
|
}
|
|
90
145
|
const kind = arg.value;
|
|
@@ -172,7 +227,11 @@ export class JSONTransform extends Visitor {
|
|
|
172
227
|
if (isDecoratedBase)
|
|
173
228
|
return;
|
|
174
229
|
this.collectInheritedFieldMembers(baseDecl, baseSource, members, visited);
|
|
175
|
-
const inheritedMembers = baseDecl.members.filter((v) => v.kind === NodeKind.FieldDeclaration &&
|
|
230
|
+
const inheritedMembers = baseDecl.members.filter((v) => v.kind === NodeKind.FieldDeclaration &&
|
|
231
|
+
!v.is(32) &&
|
|
232
|
+
!v.is(512) &&
|
|
233
|
+
!v.is(1024) &&
|
|
234
|
+
!v.decorators?.some((decorator) => decorator.name.text === "omit"));
|
|
176
235
|
for (let i = inheritedMembers.length - 1; i >= 0; i--) {
|
|
177
236
|
const inherited = inheritedMembers[i];
|
|
178
237
|
if (!members.some((member) => member.name.text == inherited.name.text)) {
|
|
@@ -186,7 +245,10 @@ export class JSONTransform extends Visitor {
|
|
|
186
245
|
const name = decorator.name.text;
|
|
187
246
|
return name === "json" || name === "serializable";
|
|
188
247
|
}))
|
|
189
|
-
throw new Error("Class " +
|
|
248
|
+
throw new Error("Class " +
|
|
249
|
+
node.name.text +
|
|
250
|
+
" is missing an @json or @serializable decorator in " +
|
|
251
|
+
node.range.source.internalPath);
|
|
190
252
|
this.visitClassDeclaration(node);
|
|
191
253
|
}
|
|
192
254
|
resolveType(type, source, visited = new Set()) {
|
|
@@ -195,7 +257,9 @@ export class JSONTransform extends Visitor {
|
|
|
195
257
|
return stripped;
|
|
196
258
|
}
|
|
197
259
|
visited.add(stripped);
|
|
198
|
-
const resolvedType = source.aliases
|
|
260
|
+
const resolvedType = source.aliases
|
|
261
|
+
.find((v) => stripNull(v.name) === stripped)
|
|
262
|
+
?.getBaseType();
|
|
199
263
|
if (resolvedType) {
|
|
200
264
|
return this.resolveType(resolvedType, source, visited);
|
|
201
265
|
}
|
|
@@ -234,9 +298,27 @@ export class JSONTransform extends Visitor {
|
|
|
234
298
|
return;
|
|
235
299
|
if (!this.schemas.has(source.internalPath))
|
|
236
300
|
this.schemas.set(source.internalPath, []);
|
|
237
|
-
const members = [
|
|
238
|
-
|
|
239
|
-
|
|
301
|
+
const members = [
|
|
302
|
+
...node.members.filter((v) => v.kind === NodeKind.FieldDeclaration &&
|
|
303
|
+
!v.is(32) &&
|
|
304
|
+
!v.is(512) &&
|
|
305
|
+
!v.is(1024) &&
|
|
306
|
+
!v.decorators?.some((decorator) => decorator.name.text === "omit")),
|
|
307
|
+
];
|
|
308
|
+
const serializers = [
|
|
309
|
+
...node.members.filter((v) => v.kind === NodeKind.MethodDeclaration &&
|
|
310
|
+
v.decorators &&
|
|
311
|
+
v.decorators.some((e) => e.name.text.toLowerCase() ===
|
|
312
|
+
"serializer") &&
|
|
313
|
+
!v.name.text.startsWith("__try")),
|
|
314
|
+
];
|
|
315
|
+
const deserializers = [
|
|
316
|
+
...node.members.filter((v) => v.kind === NodeKind.MethodDeclaration &&
|
|
317
|
+
v.decorators &&
|
|
318
|
+
v.decorators.some((e) => e.name.text.toLowerCase() ===
|
|
319
|
+
"deserializer") &&
|
|
320
|
+
!v.name.text.startsWith("__try")),
|
|
321
|
+
];
|
|
240
322
|
const schema = new Schema();
|
|
241
323
|
schema.node = node;
|
|
242
324
|
schema.name = source.getQualifiedName(node);
|
|
@@ -247,7 +329,10 @@ export class JSONTransform extends Visitor {
|
|
|
247
329
|
const depSearch = schema.deps.find((v) => v.name == extendsName);
|
|
248
330
|
if (depSearch) {
|
|
249
331
|
if (DEBUG > 0)
|
|
250
|
-
console.log("Found " +
|
|
332
|
+
console.log("Found " +
|
|
333
|
+
extendsName +
|
|
334
|
+
" in dependencies of " +
|
|
335
|
+
source.internalPath);
|
|
251
336
|
if (!schema.deps.some((v) => v.name == depSearch.name))
|
|
252
337
|
schema.deps.push(depSearch);
|
|
253
338
|
schema.parent = depSearch;
|
|
@@ -256,16 +341,26 @@ export class JSONTransform extends Visitor {
|
|
|
256
341
|
const internalSearch = source.getClass(extendsName);
|
|
257
342
|
if (internalSearch) {
|
|
258
343
|
if (DEBUG > 0)
|
|
259
|
-
console.log("Found " +
|
|
344
|
+
console.log("Found " +
|
|
345
|
+
extendsName +
|
|
346
|
+
" internally from " +
|
|
347
|
+
source.internalPath);
|
|
260
348
|
if (!this.visitedClasses.has(source.getFullPath(internalSearch))) {
|
|
261
349
|
this.visitClassDeclarationRef(internalSearch);
|
|
262
|
-
this.schemas
|
|
350
|
+
this.schemas
|
|
351
|
+
.get(internalSearch.range.source.internalPath)
|
|
352
|
+
.push(this.schema);
|
|
263
353
|
this.visitClassDeclaration(node);
|
|
264
354
|
return;
|
|
265
355
|
}
|
|
266
|
-
const schem = this.schemas
|
|
356
|
+
const schem = this.schemas
|
|
357
|
+
.get(internalSearch.range.source.internalPath)
|
|
358
|
+
?.find((s) => s.name == extendsName);
|
|
267
359
|
if (!schem)
|
|
268
|
-
throw new Error("Could not find schema for " +
|
|
360
|
+
throw new Error("Could not find schema for " +
|
|
361
|
+
internalSearch.name.text +
|
|
362
|
+
" in " +
|
|
363
|
+
internalSearch.range.source.internalPath);
|
|
269
364
|
schema.deps.push(schem);
|
|
270
365
|
schema.parent = schem;
|
|
271
366
|
}
|
|
@@ -273,7 +368,10 @@ export class JSONTransform extends Visitor {
|
|
|
273
368
|
const externalSearch = source.getImportedClass(extendsName, this.parser);
|
|
274
369
|
if (externalSearch) {
|
|
275
370
|
if (DEBUG > 0)
|
|
276
|
-
console.log("Found " +
|
|
371
|
+
console.log("Found " +
|
|
372
|
+
externalSearch.name.text +
|
|
373
|
+
" externally from " +
|
|
374
|
+
source.internalPath);
|
|
277
375
|
const externalSource = this.sources.get(externalSearch.range.source);
|
|
278
376
|
if (!this.visitedClasses.has(externalSource.getFullPath(externalSearch))) {
|
|
279
377
|
this.visitClassDeclarationRef(externalSearch);
|
|
@@ -281,9 +379,14 @@ export class JSONTransform extends Visitor {
|
|
|
281
379
|
this.visitClassDeclaration(node);
|
|
282
380
|
return;
|
|
283
381
|
}
|
|
284
|
-
const schem = this.schemas
|
|
382
|
+
const schem = this.schemas
|
|
383
|
+
.get(externalSource.internalPath)
|
|
384
|
+
?.find((s) => s.name == extendsName);
|
|
285
385
|
if (!schem)
|
|
286
|
-
throw new Error("Could not find schema for " +
|
|
386
|
+
throw new Error("Could not find schema for " +
|
|
387
|
+
externalSearch.name.text +
|
|
388
|
+
" in " +
|
|
389
|
+
externalSource.internalPath);
|
|
287
390
|
schema.deps.push(schem);
|
|
288
391
|
schema.parent = schem;
|
|
289
392
|
}
|
|
@@ -291,7 +394,10 @@ export class JSONTransform extends Visitor {
|
|
|
291
394
|
const availableSearch = source.getAvailableClass(extendsName, this.parser);
|
|
292
395
|
if (availableSearch) {
|
|
293
396
|
if (DEBUG > 0)
|
|
294
|
-
console.log("Found " +
|
|
397
|
+
console.log("Found " +
|
|
398
|
+
availableSearch.name.text +
|
|
399
|
+
" from available sources for " +
|
|
400
|
+
source.internalPath);
|
|
295
401
|
const availableSource = this.sources.get(availableSearch.range.source);
|
|
296
402
|
if (availableSearch.decorators?.some((decorator) => {
|
|
297
403
|
const name = decorator.name.text;
|
|
@@ -299,11 +405,15 @@ export class JSONTransform extends Visitor {
|
|
|
299
405
|
})) {
|
|
300
406
|
if (!this.visitedClasses.has(availableSource.getFullPath(availableSearch))) {
|
|
301
407
|
this.visitClassDeclarationRef(availableSearch);
|
|
302
|
-
this.schemas
|
|
408
|
+
this.schemas
|
|
409
|
+
.get(availableSource.internalPath)
|
|
410
|
+
.push(this.schema);
|
|
303
411
|
this.visitClassDeclaration(node);
|
|
304
412
|
return;
|
|
305
413
|
}
|
|
306
|
-
const schem = this.schemas
|
|
414
|
+
const schem = this.schemas
|
|
415
|
+
.get(availableSource.internalPath)
|
|
416
|
+
?.find((s) => s.name == extendsName);
|
|
307
417
|
if (schem) {
|
|
308
418
|
schema.deps.push(schem);
|
|
309
419
|
schema.parent = schem;
|
|
@@ -345,7 +455,8 @@ export class JSONTransform extends Visitor {
|
|
|
345
455
|
else if (["JSON.Box", "JSON.Obj", "JSON.Value", "JSON.Raw"].includes(type)) {
|
|
346
456
|
return types;
|
|
347
457
|
}
|
|
348
|
-
else if (node.isGeneric &&
|
|
458
|
+
else if (node.isGeneric &&
|
|
459
|
+
node.typeParameters.some((p) => p.name.text == type)) {
|
|
349
460
|
return types;
|
|
350
461
|
}
|
|
351
462
|
else if (type == node.name.text) {
|
|
@@ -361,7 +472,10 @@ export class JSONTransform extends Visitor {
|
|
|
361
472
|
const depSearch = schema.deps.find((v) => v.name == unknownType);
|
|
362
473
|
if (depSearch) {
|
|
363
474
|
if (DEBUG > 0)
|
|
364
|
-
console.log("Found " +
|
|
475
|
+
console.log("Found " +
|
|
476
|
+
unknownType +
|
|
477
|
+
" in dependencies of " +
|
|
478
|
+
source.internalPath);
|
|
365
479
|
if (!schema.deps.some((v) => v.name == depSearch.name)) {
|
|
366
480
|
schema.deps.push(depSearch);
|
|
367
481
|
}
|
|
@@ -370,37 +484,59 @@ export class JSONTransform extends Visitor {
|
|
|
370
484
|
const internalSearch = source.getClass(unknownType);
|
|
371
485
|
if (internalSearch) {
|
|
372
486
|
if (DEBUG > 0)
|
|
373
|
-
console.log("Found " +
|
|
487
|
+
console.log("Found " +
|
|
488
|
+
unknownType +
|
|
489
|
+
" internally from " +
|
|
490
|
+
source.internalPath);
|
|
374
491
|
if (!this.visitedClasses.has(source.getFullPath(internalSearch))) {
|
|
375
492
|
this.visitClassDeclarationRef(internalSearch);
|
|
376
|
-
const internalSchema = this.schemas
|
|
493
|
+
const internalSchema = this.schemas
|
|
494
|
+
.get(internalSearch.range.source.internalPath)
|
|
495
|
+
?.find((s) => s.name == unknownType);
|
|
377
496
|
schema.deps.push(internalSchema);
|
|
378
|
-
this.schemas
|
|
497
|
+
this.schemas
|
|
498
|
+
.get(internalSearch.range.source.internalPath)
|
|
499
|
+
.push(this.schema);
|
|
379
500
|
this.visitClassDeclaration(node);
|
|
380
501
|
return;
|
|
381
502
|
}
|
|
382
|
-
const schem = this.schemas
|
|
503
|
+
const schem = this.schemas
|
|
504
|
+
.get(internalSearch.range.source.internalPath)
|
|
505
|
+
?.find((s) => s.name == unknownType);
|
|
383
506
|
if (!schem)
|
|
384
|
-
throw new Error("Could not find schema for " +
|
|
507
|
+
throw new Error("Could not find schema for " +
|
|
508
|
+
internalSearch.name.text +
|
|
509
|
+
" in " +
|
|
510
|
+
internalSearch.range.source.internalPath);
|
|
385
511
|
schema.deps.push(schem);
|
|
386
512
|
}
|
|
387
513
|
else {
|
|
388
514
|
const externalSearch = source.getImportedClass(unknownType, this.parser);
|
|
389
515
|
if (externalSearch) {
|
|
390
516
|
if (DEBUG > 0)
|
|
391
|
-
console.log("Found " +
|
|
517
|
+
console.log("Found " +
|
|
518
|
+
externalSearch.name.text +
|
|
519
|
+
" externally from " +
|
|
520
|
+
source.internalPath);
|
|
392
521
|
const externalSource = this.sources.get(externalSearch.range.source);
|
|
393
522
|
if (!this.visitedClasses.has(externalSource.getFullPath(externalSearch))) {
|
|
394
523
|
this.visitClassDeclarationRef(externalSearch);
|
|
395
|
-
const externalSchema = this.schemas
|
|
524
|
+
const externalSchema = this.schemas
|
|
525
|
+
.get(externalSource.internalPath)
|
|
526
|
+
?.find((s) => s.name == unknownType);
|
|
396
527
|
schema.deps.push(externalSchema);
|
|
397
528
|
this.schemas.get(externalSource.internalPath).push(this.schema);
|
|
398
529
|
this.visitClassDeclaration(node);
|
|
399
530
|
return;
|
|
400
531
|
}
|
|
401
|
-
const schem = this.schemas
|
|
532
|
+
const schem = this.schemas
|
|
533
|
+
.get(externalSource.internalPath)
|
|
534
|
+
?.find((s) => s.name == unknownType);
|
|
402
535
|
if (!schem)
|
|
403
|
-
throw new Error("Could not find schema for " +
|
|
536
|
+
throw new Error("Could not find schema for " +
|
|
537
|
+
externalSearch.name.text +
|
|
538
|
+
" in " +
|
|
539
|
+
externalSource.internalPath);
|
|
404
540
|
schema.deps.push(schem);
|
|
405
541
|
}
|
|
406
542
|
}
|
|
@@ -419,11 +555,22 @@ export class JSONTransform extends Visitor {
|
|
|
419
555
|
let DESERIALIZE_CUSTOM = "";
|
|
420
556
|
let SERIALIZE_CUSTOM = "";
|
|
421
557
|
if (DEBUG > 0)
|
|
422
|
-
console.log("Created schema: " +
|
|
558
|
+
console.log("Created schema: " +
|
|
559
|
+
this.schema.name +
|
|
560
|
+
" in file " +
|
|
561
|
+
source.normalizedPath +
|
|
562
|
+
(this.schema.deps.length
|
|
563
|
+
? " with dependencies:\n " +
|
|
564
|
+
this.schema.deps.map((v) => v.name).join("\n ")
|
|
565
|
+
: ""));
|
|
423
566
|
if (serializers.length > 1)
|
|
424
|
-
throwError("Multiple serializers detected for class " +
|
|
567
|
+
throwError("Multiple serializers detected for class " +
|
|
568
|
+
node.name.text +
|
|
569
|
+
" but schemas can only have one serializer!", serializers[1].range);
|
|
425
570
|
if (deserializers.length > 1)
|
|
426
|
-
throwError("Multiple deserializers detected for class " +
|
|
571
|
+
throwError("Multiple deserializers detected for class " +
|
|
572
|
+
node.name.text +
|
|
573
|
+
" but schemas can only have one deserializer!", deserializers[1].range);
|
|
427
574
|
if (serializers.length) {
|
|
428
575
|
this.schema.custom = true;
|
|
429
576
|
const serializer = serializers[0];
|
|
@@ -432,11 +579,24 @@ export class JSONTransform extends Visitor {
|
|
|
432
579
|
this.schema.customJsonKind = serializerJsonKind;
|
|
433
580
|
CustomTransform.visit(serializer);
|
|
434
581
|
if (serializer.signature.parameters.length > 1)
|
|
435
|
-
throwError("Found too many parameters in custom serializer for " +
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
582
|
+
throwError("Found too many parameters in custom serializer for " +
|
|
583
|
+
this.schema.name +
|
|
584
|
+
", but serializers can only accept one parameter of type '" +
|
|
585
|
+
this.schema.name +
|
|
586
|
+
"'!", serializer.signature.parameters[1].range);
|
|
587
|
+
if (serializer.signature.parameters.length > 0 &&
|
|
588
|
+
serializer.signature.parameters[0].type.name.identifier
|
|
589
|
+
.text != node.name.text &&
|
|
590
|
+
serializer.signature.parameters[0].type.name.identifier
|
|
591
|
+
.text != "this")
|
|
592
|
+
throwError("Type of parameter for custom serializer does not match! It should be 'string'either be 'this' or '" +
|
|
593
|
+
this.schema.name +
|
|
594
|
+
"'", serializer.signature.parameters[0].type.range);
|
|
595
|
+
if (!serializer.signature.returnType ||
|
|
596
|
+
!(serializer.signature.returnType).name.identifier.text.includes("string"))
|
|
597
|
+
throwError("Could not find valid return type for serializer in " +
|
|
598
|
+
this.schema.name +
|
|
599
|
+
"!. Set the return type to type 'string' and try again", serializer.signature.returnType.range);
|
|
440
600
|
if (!serializer.decorators.some((v) => v.name.text == "inline")) {
|
|
441
601
|
serializer.decorators.push(Node.createDecorator(Node.createIdentifierExpression("inline", serializer.range), null, serializer.range));
|
|
442
602
|
}
|
|
@@ -446,13 +606,19 @@ export class JSONTransform extends Visitor {
|
|
|
446
606
|
SERIALIZE_CUSTOM += " const savedStackSize = bs.stackSize;\n";
|
|
447
607
|
}
|
|
448
608
|
SERIALIZE_CUSTOM += " const self = changetype<this>(ptr);\n";
|
|
449
|
-
SERIALIZE_CUSTOM +=
|
|
609
|
+
SERIALIZE_CUSTOM +=
|
|
610
|
+
" const data = self." +
|
|
611
|
+
serializer.name.text +
|
|
612
|
+
"(" +
|
|
613
|
+
(serializer.signature.parameters.length ? "self" : "") +
|
|
614
|
+
");\n";
|
|
450
615
|
if (hasCall) {
|
|
451
616
|
SERIALIZE_CUSTOM += " bs.offset = savedOffset;\n";
|
|
452
617
|
SERIALIZE_CUSTOM += " bs.stackSize = savedStackSize;\n";
|
|
453
618
|
}
|
|
454
619
|
SERIALIZE_CUSTOM += " const dataSize = data.length << 1;\n";
|
|
455
|
-
SERIALIZE_CUSTOM +=
|
|
620
|
+
SERIALIZE_CUSTOM +=
|
|
621
|
+
" memory.copy(bs.offset, changetype<usize>(data), dataSize);\n";
|
|
456
622
|
SERIALIZE_CUSTOM += " bs.offset += dataSize;\n";
|
|
457
623
|
SERIALIZE_CUSTOM += " }\n";
|
|
458
624
|
}
|
|
@@ -460,24 +626,43 @@ export class JSONTransform extends Visitor {
|
|
|
460
626
|
this.schema.custom = true;
|
|
461
627
|
const deserializer = deserializers[0];
|
|
462
628
|
const deserializerJsonKind = parseCustomJsonKind(deserializer, "deserializer");
|
|
463
|
-
if (this.schema.customJsonKind != "any" &&
|
|
629
|
+
if (this.schema.customJsonKind != "any" &&
|
|
630
|
+
deserializerJsonKind != "any" &&
|
|
631
|
+
this.schema.customJsonKind != deserializerJsonKind) {
|
|
464
632
|
throwError(`@serializer and @deserializer JSON types for ${this.schema.name} must match`, deserializer.range);
|
|
465
633
|
}
|
|
466
634
|
if (this.schema.customJsonKind == "any")
|
|
467
635
|
this.schema.customJsonKind = deserializerJsonKind;
|
|
468
636
|
if (!deserializer.signature.parameters.length)
|
|
469
|
-
throwError("Could not find any parameters in custom deserializer for " +
|
|
637
|
+
throwError("Could not find any parameters in custom deserializer for " +
|
|
638
|
+
this.schema.name +
|
|
639
|
+
". Deserializers must have one parameter like 'deserializer(data: string): " +
|
|
640
|
+
this.schema.name +
|
|
641
|
+
" {}'", deserializer.range);
|
|
470
642
|
if (deserializer.signature.parameters.length > 1)
|
|
471
|
-
throwError("Found too many parameters in custom deserializer for " +
|
|
472
|
-
|
|
643
|
+
throwError("Found too many parameters in custom deserializer for " +
|
|
644
|
+
this.schema.name +
|
|
645
|
+
", but deserializers can only accept one parameter of type 'string'!", deserializer.signature.parameters[1].range);
|
|
646
|
+
if (deserializer.signature.parameters[0].type.name
|
|
647
|
+
.identifier.text != "string")
|
|
473
648
|
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
|
-
|
|
649
|
+
if (!deserializer.signature.returnType ||
|
|
650
|
+
!((deserializer.signature.returnType).name.identifier.text.includes(this.schema.name) ||
|
|
651
|
+
(deserializer.signature.returnType).name.identifier.text.includes("this")))
|
|
652
|
+
throwError("Could not find valid return type for deserializer in " +
|
|
653
|
+
this.schema.name +
|
|
654
|
+
"!. Set the return type to type '" +
|
|
655
|
+
this.schema.name +
|
|
656
|
+
"' or 'this' and try again", deserializer.signature.returnType.range);
|
|
476
657
|
if (!deserializer.decorators.some((v) => v.name.text == "inline")) {
|
|
477
658
|
deserializer.decorators.push(Node.createDecorator(Node.createIdentifierExpression("inline", deserializer.range), null, deserializer.range));
|
|
478
659
|
}
|
|
479
|
-
DESERIALIZE_CUSTOM +=
|
|
480
|
-
|
|
660
|
+
DESERIALIZE_CUSTOM +=
|
|
661
|
+
" @inline __DESERIALIZE_CUSTOM(data: string): this {\n";
|
|
662
|
+
DESERIALIZE_CUSTOM +=
|
|
663
|
+
" return inline.always(this." +
|
|
664
|
+
deserializer.name.text +
|
|
665
|
+
"(data));\n";
|
|
481
666
|
DESERIALIZE_CUSTOM += " }\n";
|
|
482
667
|
}
|
|
483
668
|
if (!members.length && !deserializers.length && !serializers.length) {
|
|
@@ -504,11 +689,19 @@ export class JSONTransform extends Visitor {
|
|
|
504
689
|
this.schema.byteSize += mem.byteSize;
|
|
505
690
|
if (member.decorators) {
|
|
506
691
|
for (const decorator of member.decorators) {
|
|
507
|
-
const decoratorName = decorator.name.text
|
|
692
|
+
const decoratorName = decorator.name.text
|
|
693
|
+
.toLowerCase()
|
|
694
|
+
.trim();
|
|
508
695
|
switch (decoratorName) {
|
|
509
696
|
case "alias": {
|
|
510
697
|
const arg = decorator.args[0];
|
|
511
|
-
if (!arg ||
|
|
698
|
+
if (!arg ||
|
|
699
|
+
(arg.kind != NodeKind.Literal &&
|
|
700
|
+
arg.literalKind !=
|
|
701
|
+
2 &&
|
|
702
|
+
arg.literalKind !=
|
|
703
|
+
1 &&
|
|
704
|
+
arg.literalKind != 0))
|
|
512
705
|
throwError("@alias must have an argument of type string or number", member.range);
|
|
513
706
|
mem.alias = arg.value.toString();
|
|
514
707
|
break;
|
|
@@ -544,7 +737,9 @@ export class JSONTransform extends Visitor {
|
|
|
544
737
|
const hasOptionalMembers = hasOmitIfMembers || hasOmitNullMembers;
|
|
545
738
|
const supportsFastOptionalPath = requestedFastPath && hasOptionalMembers;
|
|
546
739
|
const hasTypeParams = !!node.typeParameters && node.typeParameters.length > 0;
|
|
547
|
-
const useFastPath = requestedFastPath &&
|
|
740
|
+
const useFastPath = requestedFastPath &&
|
|
741
|
+
!hasTypeParams &&
|
|
742
|
+
(this.schema.static || supportsFastOptionalPath);
|
|
548
743
|
indent = " ";
|
|
549
744
|
if (this.schema.static == false) {
|
|
550
745
|
if (this.schema.members.some((v) => v.flags.has(PropertyFlags.OmitNull))) {
|
|
@@ -563,7 +758,10 @@ export class JSONTransform extends Visitor {
|
|
|
563
758
|
const realName = member.name;
|
|
564
759
|
const isLast = i == this.schema.members.length - 1;
|
|
565
760
|
if (member.value) {
|
|
566
|
-
if (member.value != "null" &&
|
|
761
|
+
if (member.value != "null" &&
|
|
762
|
+
member.value != "0" &&
|
|
763
|
+
member.value != "0.0" &&
|
|
764
|
+
member.value != "false") {
|
|
567
765
|
INITIALIZE += ` store<${member.type}>(changetype<usize>(this), ${member.value}, offsetof<this>(${JSON.stringify(member.name)}));\n`;
|
|
568
766
|
}
|
|
569
767
|
}
|
|
@@ -593,7 +791,9 @@ export class JSONTransform extends Visitor {
|
|
|
593
791
|
}
|
|
594
792
|
}
|
|
595
793
|
const SIMD_ENABLED = this.program.options.hasFeature(16);
|
|
596
|
-
if (!isRegular &&
|
|
794
|
+
if (!isRegular &&
|
|
795
|
+
!member.flags.has(PropertyFlags.OmitIf) &&
|
|
796
|
+
!member.flags.has(PropertyFlags.OmitNull))
|
|
597
797
|
isRegular = true;
|
|
598
798
|
if (isRegular && isPure) {
|
|
599
799
|
const keyPart = (isFirst ? "{" : ",") + aliasName + ":";
|
|
@@ -617,7 +817,9 @@ export class JSONTransform extends Visitor {
|
|
|
617
817
|
}
|
|
618
818
|
else {
|
|
619
819
|
if (member.flags.has(PropertyFlags.OmitNull)) {
|
|
620
|
-
SERIALIZE +=
|
|
820
|
+
SERIALIZE +=
|
|
821
|
+
indent +
|
|
822
|
+
`if ((block = load<usize>(ptr, offsetof<this>(${JSON.stringify(realName)}))) !== 0) {\n`;
|
|
621
823
|
indentInc();
|
|
622
824
|
const keyPart = aliasName + ":";
|
|
623
825
|
this.schema.byteSize += keyPart.length << 1;
|
|
@@ -638,12 +840,20 @@ export class JSONTransform extends Visitor {
|
|
|
638
840
|
if (member.flags.get(PropertyFlags.OmitIf).kind == NodeKind.Function) {
|
|
639
841
|
const arg = member.flags.get(PropertyFlags.OmitIf);
|
|
640
842
|
arg.declaration.signature.parameters[0].type = Node.createNamedType(Node.createSimpleTypeName("this", node.range), null, false, node.range);
|
|
641
|
-
arg.declaration.signature.returnType.name =
|
|
642
|
-
|
|
843
|
+
arg.declaration.signature.returnType.name =
|
|
844
|
+
Node.createSimpleTypeName("boolean", arg.declaration.signature.returnType.name
|
|
845
|
+
.range);
|
|
846
|
+
SERIALIZE +=
|
|
847
|
+
indent +
|
|
848
|
+
`if (!(${toString(member.flags.get(PropertyFlags.OmitIf))})(this)) {\n`;
|
|
643
849
|
}
|
|
644
850
|
else {
|
|
645
851
|
const expression = member.flags.get(PropertyFlags.OmitIf);
|
|
646
|
-
const rendered = expression.kind == NodeKind.Literal &&
|
|
852
|
+
const rendered = expression.kind == NodeKind.Literal &&
|
|
853
|
+
expression.literalKind ==
|
|
854
|
+
2
|
|
855
|
+
? JSON.stringify(expression.value).slice(1, -1)
|
|
856
|
+
: toString(expression);
|
|
647
857
|
SERIALIZE += indent + `if (!(${rendered})) {\n`;
|
|
648
858
|
}
|
|
649
859
|
indentInc();
|
|
@@ -671,7 +881,9 @@ export class JSONTransform extends Visitor {
|
|
|
671
881
|
};
|
|
672
882
|
for (const member of this.schema.members) {
|
|
673
883
|
const type = stripNull(member.type);
|
|
674
|
-
const customDep = this.schema.deps.find((dep) => dep &&
|
|
884
|
+
const customDep = this.schema.deps.find((dep) => dep &&
|
|
885
|
+
(dep.name == type || dep.name.endsWith("." + type)) &&
|
|
886
|
+
dep.custom);
|
|
675
887
|
const isCustomType = member.custom || !!customDep;
|
|
676
888
|
if (isCustomType || member.generic) {
|
|
677
889
|
addMemberToCustomBucket(sortedMembers, member, member.generic ? "any" : customDep?.customJsonKind || "any");
|
|
@@ -687,7 +899,9 @@ export class JSONTransform extends Visitor {
|
|
|
687
899
|
sortedMembers.object.push(member);
|
|
688
900
|
else if (isBoolean(type) || type.startsWith("JSON.Box<bool"))
|
|
689
901
|
sortedMembers.boolean.push(member);
|
|
690
|
-
else if (isPrimitive(type) ||
|
|
902
|
+
else if (isPrimitive(type) ||
|
|
903
|
+
type.startsWith("JSON.Box<") ||
|
|
904
|
+
isEnum(type, this.sources.get(this.schema.node.range.source), this.parser))
|
|
691
905
|
sortedMembers.number.push(member);
|
|
692
906
|
else if (isArray(type))
|
|
693
907
|
sortedMembers.array.push(member);
|
|
@@ -723,7 +937,9 @@ export class JSONTransform extends Visitor {
|
|
|
723
937
|
const SIGNED_INTEGER_TYPES = ["i8", "i16", "i32", "i64", "isize"];
|
|
724
938
|
const FLOAT_TYPES = ["f32", "f64"];
|
|
725
939
|
const INTEGER_TYPES = [...UNSIGNED_INTEGER_TYPES, ...SIGNED_INTEGER_TYPES];
|
|
726
|
-
const STRING_FIELD_DESERIALIZER = codegenMode === JSONMode.SIMD
|
|
940
|
+
const STRING_FIELD_DESERIALIZER = codegenMode === JSONMode.SIMD
|
|
941
|
+
? "deserializeStringField_SIMD"
|
|
942
|
+
: "deserializeStringField_SWAR";
|
|
727
943
|
const getArrayValueType = (type) => {
|
|
728
944
|
if (!type.startsWith("Array<") && !type.startsWith("StaticArray<"))
|
|
729
945
|
return null;
|
|
@@ -736,7 +952,9 @@ export class JSONTransform extends Visitor {
|
|
|
736
952
|
const fieldOffset = `offsetof<this>(${JSON.stringify(member.name)})`;
|
|
737
953
|
const valuePtr = keyOffset ? `${srcPtr} + ${keyOffset}` : srcPtr;
|
|
738
954
|
if (INTEGER_TYPES.includes(resolvedType)) {
|
|
739
|
-
const helper = SIGNED_INTEGER_TYPES.includes(resolvedType)
|
|
955
|
+
const helper = SIGNED_INTEGER_TYPES.includes(resolvedType)
|
|
956
|
+
? "deserializeIntegerField"
|
|
957
|
+
: "deserializeUnsignedField";
|
|
740
958
|
out.push(`${srcPtr} = ${helper}<${resolvedType}>(${valuePtr}, srcEnd, ${outPtr}, ${fieldOffset});`);
|
|
741
959
|
}
|
|
742
960
|
else if (["string", "String"].includes(resolvedType)) {
|
|
@@ -775,8 +993,11 @@ export class JSONTransform extends Visitor {
|
|
|
775
993
|
}
|
|
776
994
|
out.push("}");
|
|
777
995
|
}
|
|
778
|
-
else if (resolvedType.startsWith("JSON.Box<") ||
|
|
779
|
-
|
|
996
|
+
else if (resolvedType.startsWith("JSON.Box<") ||
|
|
997
|
+
resolvedType.startsWith("Box<")) {
|
|
998
|
+
const innerType = resolvedType
|
|
999
|
+
.slice(resolvedType.indexOf("<") + 1, -1)
|
|
1000
|
+
.trim();
|
|
780
1001
|
out.push("{");
|
|
781
1002
|
if (member.node.type.isNullable) {
|
|
782
1003
|
out.push(` if (load<u64>(${valuePtr}) == 30399761348886638) {`);
|
|
@@ -788,7 +1009,11 @@ export class JSONTransform extends Visitor {
|
|
|
788
1009
|
out.push(` if (load<u64>(${valuePtr}) == 28429475166421108) {`);
|
|
789
1010
|
out.push(` store<${resolvedType}>(${outPtr}, changetype<${resolvedType}>(JSON.Box.from<${innerType}>(true)), ${fieldOffset});`);
|
|
790
1011
|
out.push(` ${srcPtr} = ${valuePtr} + 8;`);
|
|
791
|
-
out.push(" } else if (load<u64>(" +
|
|
1012
|
+
out.push(" } else if (load<u64>(" +
|
|
1013
|
+
valuePtr +
|
|
1014
|
+
") == 32370086184550502 && load<u16>(" +
|
|
1015
|
+
valuePtr +
|
|
1016
|
+
", 8) == 101) {");
|
|
792
1017
|
out.push(` store<${resolvedType}>(${outPtr}, changetype<${resolvedType}>(JSON.Box.from<${innerType}>(false)), ${fieldOffset});`);
|
|
793
1018
|
out.push(` ${srcPtr} = ${valuePtr} + 10;`);
|
|
794
1019
|
out.push(" } else break;");
|
|
@@ -848,7 +1073,11 @@ export class JSONTransform extends Visitor {
|
|
|
848
1073
|
out.push(`if (load<u64>(${srcPtr}) == 28429475166421108) {`);
|
|
849
1074
|
out.push(` store<${resolvedType}>(${outPtr}, true, ${fieldOffset});`);
|
|
850
1075
|
out.push(` ${srcPtr} += 8;`);
|
|
851
|
-
out.push("} else if (load<u64>(" +
|
|
1076
|
+
out.push("} else if (load<u64>(" +
|
|
1077
|
+
srcPtr +
|
|
1078
|
+
") == 32370086184550502 && load<u16>(" +
|
|
1079
|
+
srcPtr +
|
|
1080
|
+
", 8) == 101) {");
|
|
852
1081
|
out.push(` store<${resolvedType}>(${outPtr}, false, ${fieldOffset});`);
|
|
853
1082
|
out.push(` ${srcPtr} += 10;`);
|
|
854
1083
|
out.push("} else break;");
|
|
@@ -1052,7 +1281,9 @@ export class JSONTransform extends Visitor {
|
|
|
1052
1281
|
out.push(`${srcPtr} = deserializeStaticArrayField<${resolvedType}>(${srcPtr}, srcEnd, ${outPtr}, ${fieldOffset});`);
|
|
1053
1282
|
out.push(`if (!${srcPtr}) break;`);
|
|
1054
1283
|
}
|
|
1055
|
-
else if (resolvedType == "JSON.Value" ||
|
|
1284
|
+
else if (resolvedType == "JSON.Value" ||
|
|
1285
|
+
resolvedType == "JSON.Obj" ||
|
|
1286
|
+
isEnum(resolvedType, this.sources.get(this.schema.node.range.source), this.parser)) {
|
|
1056
1287
|
out.push("break;");
|
|
1057
1288
|
}
|
|
1058
1289
|
else {
|
|
@@ -1066,7 +1297,8 @@ export class JSONTransform extends Visitor {
|
|
|
1066
1297
|
DESERIALIZE_FAST += indent + "do {\n";
|
|
1067
1298
|
indent += " ";
|
|
1068
1299
|
if (supportsFastOptionalPath) {
|
|
1069
|
-
DESERIALIZE_FAST +=
|
|
1300
|
+
DESERIALIZE_FAST +=
|
|
1301
|
+
indent + "if (load<u16>(srcStart) !== 0x7b) break; // {\n";
|
|
1070
1302
|
DESERIALIZE_FAST += indent + "srcStart += 2;\n";
|
|
1071
1303
|
DESERIALIZE_FAST += indent + "let seenAny = false;\n\n";
|
|
1072
1304
|
for (let i = 0; i < this.schema.members.length; i++) {
|
|
@@ -1082,14 +1314,17 @@ export class JSONTransform extends Visitor {
|
|
|
1082
1314
|
const inlineStringValue = ["string", "String"].includes(resolvedType);
|
|
1083
1315
|
const deserializerFirst = getDeserializer(member.type, "srcStart", "dst", member, inlineStringValue ? firstKeyOffset : 0, true);
|
|
1084
1316
|
const deserializerNext = getDeserializer(member.type, "srcStart", "dst", member, inlineStringValue ? nextKeyOffset : 0, true);
|
|
1085
|
-
const isOptional = member.flags.has(PropertyFlags.OmitNull) ||
|
|
1317
|
+
const isOptional = member.flags.has(PropertyFlags.OmitNull) ||
|
|
1318
|
+
member.flags.has(PropertyFlags.OmitIf);
|
|
1086
1319
|
if (!deserializerFirst.length || !deserializerNext.length) {
|
|
1087
1320
|
DESERIALIZE_FAST += indent + "break;\n\n";
|
|
1088
1321
|
continue;
|
|
1089
1322
|
}
|
|
1090
1323
|
DESERIALIZE_FAST += indent + "if (!seenAny) {\n";
|
|
1091
1324
|
indent += " ";
|
|
1092
|
-
DESERIALIZE_FAST +=
|
|
1325
|
+
DESERIALIZE_FAST +=
|
|
1326
|
+
indent +
|
|
1327
|
+
`if ( // ${firstKeySection}\n${(indent += " ")}${getComparisions(firstKeySection, "srcStart", "!=").join("\n" + indent + "|| ")}\n${(indent = indent.slice(0, -2))}) {\n`;
|
|
1093
1328
|
indent += " ";
|
|
1094
1329
|
if (isOptional) {
|
|
1095
1330
|
DESERIALIZE_FAST += indent + "// optional @omitnull field omitted\n";
|
|
@@ -1102,14 +1337,17 @@ export class JSONTransform extends Visitor {
|
|
|
1102
1337
|
indent += " ";
|
|
1103
1338
|
if (!inlineStringValue)
|
|
1104
1339
|
DESERIALIZE_FAST += indent + `srcStart += ${firstKeyOffset};\n`;
|
|
1105
|
-
DESERIALIZE_FAST +=
|
|
1340
|
+
DESERIALIZE_FAST +=
|
|
1341
|
+
indent + deserializerFirst.join("\n" + indent) + "\n";
|
|
1106
1342
|
DESERIALIZE_FAST += indent + "seenAny = true;\n";
|
|
1107
1343
|
indent = indent.slice(0, -2);
|
|
1108
1344
|
DESERIALIZE_FAST += indent + "}\n";
|
|
1109
1345
|
indent = indent.slice(0, -2);
|
|
1110
1346
|
DESERIALIZE_FAST += indent + "} else {\n";
|
|
1111
1347
|
indent += " ";
|
|
1112
|
-
DESERIALIZE_FAST +=
|
|
1348
|
+
DESERIALIZE_FAST +=
|
|
1349
|
+
indent +
|
|
1350
|
+
`if ( // ${nextKeySection}\n${(indent += " ")}${getComparisions(nextKeySection, "srcStart", "!=").join("\n" + indent + "|| ")}\n${(indent = indent.slice(0, -2))}) {\n`;
|
|
1113
1351
|
indent += " ";
|
|
1114
1352
|
if (isOptional) {
|
|
1115
1353
|
DESERIALIZE_FAST += indent + "// optional @omitnull field omitted\n";
|
|
@@ -1122,7 +1360,8 @@ export class JSONTransform extends Visitor {
|
|
|
1122
1360
|
indent += " ";
|
|
1123
1361
|
if (!inlineStringValue)
|
|
1124
1362
|
DESERIALIZE_FAST += indent + `srcStart += ${nextKeyOffset};\n`;
|
|
1125
|
-
DESERIALIZE_FAST +=
|
|
1363
|
+
DESERIALIZE_FAST +=
|
|
1364
|
+
indent + deserializerNext.join("\n" + indent) + "\n";
|
|
1126
1365
|
indent = indent.slice(0, -2);
|
|
1127
1366
|
DESERIALIZE_FAST += indent + "}\n";
|
|
1128
1367
|
indent = indent.slice(0, -2);
|
|
@@ -1136,7 +1375,9 @@ export class JSONTransform extends Visitor {
|
|
|
1136
1375
|
if (key.length <= 2)
|
|
1137
1376
|
throw new Error("Key cannot be empty!");
|
|
1138
1377
|
const keySection = (i == 0 ? "{" : ",") + key + ":";
|
|
1139
|
-
DESERIALIZE_FAST +=
|
|
1378
|
+
DESERIALIZE_FAST +=
|
|
1379
|
+
indent +
|
|
1380
|
+
`if ( // ${keySection}\n${(indent += " ")}${getComparisions(keySection, "srcStart", "!=").join("\n" + indent + "|| ")}\n${(indent = indent.slice(0, -2))}) break;\n`;
|
|
1140
1381
|
const keyOffset = keySection.length << 1;
|
|
1141
1382
|
const resolvedType = stripNull(member.type);
|
|
1142
1383
|
const inlineStringValue = ["string", "String"].includes(resolvedType);
|
|
@@ -1151,15 +1392,21 @@ export class JSONTransform extends Visitor {
|
|
|
1151
1392
|
DESERIALIZE_FAST += indent + deserializer.join("\n" + indent) + "\n\n";
|
|
1152
1393
|
}
|
|
1153
1394
|
}
|
|
1154
|
-
DESERIALIZE_FAST +=
|
|
1395
|
+
DESERIALIZE_FAST +=
|
|
1396
|
+
indent + "if (load<u16>(srcStart) !== 0x7d) break; // }\n";
|
|
1155
1397
|
DESERIALIZE_FAST += indent + "srcStart += 2;\n";
|
|
1156
1398
|
DESERIALIZE_FAST += indent + "return srcStart;\n";
|
|
1157
1399
|
indent = indent.slice(0, -2);
|
|
1158
1400
|
DESERIALIZE_FAST += indent + "} while (false);\n\n";
|
|
1159
1401
|
if (THROW_FAST_PATH) {
|
|
1160
|
-
DESERIALIZE_FAST +=
|
|
1161
|
-
|
|
1162
|
-
DESERIALIZE_FAST +=
|
|
1402
|
+
DESERIALIZE_FAST +=
|
|
1403
|
+
indent + "const failAt = srcStart ? srcStart : start;\n";
|
|
1404
|
+
DESERIALIZE_FAST +=
|
|
1405
|
+
indent +
|
|
1406
|
+
"const failEnd = failAt + 160 < srcEnd ? failAt + 160 : srcEnd;\n";
|
|
1407
|
+
DESERIALIZE_FAST +=
|
|
1408
|
+
indent +
|
|
1409
|
+
`throw new Error("Fast path failed for ${this.schema.name} at char offset " + ((failAt - start) >> 1).toString() + " near: " + JSON.Util.ptrToStr(failAt, failEnd));`;
|
|
1163
1410
|
}
|
|
1164
1411
|
else {
|
|
1165
1412
|
DESERIALIZE_FAST += indent + "return 0;";
|
|
@@ -1172,24 +1419,43 @@ export class JSONTransform extends Visitor {
|
|
|
1172
1419
|
if (!STRICT || sortedMembers.object.length || sortedMembers.array.length)
|
|
1173
1420
|
DESERIALIZE += indent + " let depth: i32 = 0;\n";
|
|
1174
1421
|
DESERIALIZE += indent + " let lastIndex: usize = 0;\n\n";
|
|
1175
|
-
DESERIALIZE +=
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
DESERIALIZE +=
|
|
1179
|
-
|
|
1422
|
+
DESERIALIZE +=
|
|
1423
|
+
indent +
|
|
1424
|
+
" while (srcStart < srcEnd && JSON.Util.isSpace(load<u16>(srcStart))) srcStart += 2;\n";
|
|
1425
|
+
DESERIALIZE +=
|
|
1426
|
+
indent +
|
|
1427
|
+
" while (srcEnd > srcStart && JSON.Util.isSpace(load<u16>(srcEnd - 2))) srcEnd -= 2;\n";
|
|
1428
|
+
DESERIALIZE +=
|
|
1429
|
+
indent +
|
|
1430
|
+
' if (srcStart - srcEnd == 0) throw new Error("Input string had zero length or was all whitespace");\n';
|
|
1431
|
+
DESERIALIZE +=
|
|
1432
|
+
indent +
|
|
1433
|
+
" if (load<u16>(srcStart) != 123) throw new Error(\"Expected '{' at start of object at position \" + (srcEnd - srcStart).toString());\n";
|
|
1434
|
+
DESERIALIZE +=
|
|
1435
|
+
indent +
|
|
1436
|
+
" if (load<u16>(srcEnd - 2) != 125) throw new Error(\"Expected '}' at end of object at position \" + (srcEnd - srcStart).toString());\n";
|
|
1180
1437
|
DESERIALIZE += indent + " srcStart += 2;\n\n";
|
|
1181
1438
|
DESERIALIZE += indent + " while (srcStart < srcEnd) {\n";
|
|
1182
1439
|
DESERIALIZE += indent + " let code = load<u16>(srcStart);\n";
|
|
1183
|
-
DESERIALIZE +=
|
|
1440
|
+
DESERIALIZE +=
|
|
1441
|
+
indent +
|
|
1442
|
+
" while (JSON.Util.isSpace(code)) code = load<u16>(srcStart += 2);\n";
|
|
1184
1443
|
DESERIALIZE += indent + " if (keyStart == 0) {\n";
|
|
1185
|
-
DESERIALIZE +=
|
|
1444
|
+
DESERIALIZE +=
|
|
1445
|
+
indent + " if (code == 34 && load<u16>(srcStart - 2) !== 92) {\n";
|
|
1186
1446
|
DESERIALIZE += indent + " if (isKey) {\n";
|
|
1187
1447
|
DESERIALIZE += indent + " keyStart = lastIndex;\n";
|
|
1188
1448
|
DESERIALIZE += indent + " keyEnd = srcStart;\n";
|
|
1189
1449
|
if (DEBUG > 1)
|
|
1190
|
-
DESERIALIZE +=
|
|
1191
|
-
|
|
1192
|
-
|
|
1450
|
+
DESERIALIZE +=
|
|
1451
|
+
indent +
|
|
1452
|
+
' console.log("Key: " + JSON.Util.ptrToStr(keyStart, keyEnd));\n';
|
|
1453
|
+
DESERIALIZE +=
|
|
1454
|
+
indent +
|
|
1455
|
+
" while (JSON.Util.isSpace((code = load<u16>((srcStart += 2))))) {}\n";
|
|
1456
|
+
DESERIALIZE +=
|
|
1457
|
+
indent +
|
|
1458
|
+
" if (code !== 58) throw new Error(\"Expected ':' after key at position \" + (srcEnd - srcStart).toString());\n";
|
|
1193
1459
|
DESERIALIZE += indent + " isKey = false;\n";
|
|
1194
1460
|
DESERIALIZE += indent + " } else {\n";
|
|
1195
1461
|
DESERIALIZE += indent + " isKey = true;\n";
|
|
@@ -1219,7 +1485,9 @@ export class JSONTransform extends Visitor {
|
|
|
1219
1485
|
const generateGroups = (members, cb, type) => {
|
|
1220
1486
|
if (!members.length) {
|
|
1221
1487
|
if (STRICT) {
|
|
1222
|
-
DESERIALIZE +=
|
|
1488
|
+
DESERIALIZE +=
|
|
1489
|
+
indent +
|
|
1490
|
+
' 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
1491
|
}
|
|
1224
1492
|
else {
|
|
1225
1493
|
if (type == "string") {
|
|
@@ -1229,7 +1497,10 @@ export class JSONTransform extends Visitor {
|
|
|
1229
1497
|
DESERIALIZE += indent + " srcStart += 2;\n";
|
|
1230
1498
|
}
|
|
1231
1499
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
1232
|
-
if (type == "string" ||
|
|
1500
|
+
if (type == "string" ||
|
|
1501
|
+
type == "object" ||
|
|
1502
|
+
type == "array" ||
|
|
1503
|
+
type == "number")
|
|
1233
1504
|
DESERIALIZE += indent + " break;\n";
|
|
1234
1505
|
}
|
|
1235
1506
|
}
|
|
@@ -1244,7 +1515,9 @@ export class JSONTransform extends Visitor {
|
|
|
1244
1515
|
}
|
|
1245
1516
|
DESERIALIZE += " default: {\n";
|
|
1246
1517
|
if (STRICT) {
|
|
1247
|
-
DESERIALIZE +=
|
|
1518
|
+
DESERIALIZE +=
|
|
1519
|
+
indent +
|
|
1520
|
+
' 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
1521
|
}
|
|
1249
1522
|
else {
|
|
1250
1523
|
if (type == "string") {
|
|
@@ -1254,7 +1527,10 @@ export class JSONTransform extends Visitor {
|
|
|
1254
1527
|
DESERIALIZE += indent + " srcStart += 2;\n";
|
|
1255
1528
|
}
|
|
1256
1529
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
1257
|
-
if (type == "string" ||
|
|
1530
|
+
if (type == "string" ||
|
|
1531
|
+
type == "object" ||
|
|
1532
|
+
type == "array" ||
|
|
1533
|
+
type == "number")
|
|
1258
1534
|
DESERIALIZE += indent + " break;\n";
|
|
1259
1535
|
}
|
|
1260
1536
|
DESERIALIZE += " }\n";
|
|
@@ -1271,7 +1547,8 @@ export class JSONTransform extends Visitor {
|
|
|
1271
1547
|
DESERIALIZE += " const code32 = load<u32>(keyStart);\n";
|
|
1272
1548
|
}
|
|
1273
1549
|
if (members.some((m) => (m.alias || m.name).length << 1 == 6)) {
|
|
1274
|
-
DESERIALIZE +=
|
|
1550
|
+
DESERIALIZE +=
|
|
1551
|
+
" const code48 = load<u64>(keyStart) & 0x0000FFFFFFFFFFFF;\n";
|
|
1275
1552
|
}
|
|
1276
1553
|
if (members.some((m) => (m.alias || m.name).length << 1 == 8)) {
|
|
1277
1554
|
DESERIALIZE += " const code64 = load<u64>(keyStart);\n";
|
|
@@ -1287,15 +1564,34 @@ export class JSONTransform extends Visitor {
|
|
|
1287
1564
|
DESERIALIZE += " srcStart += 2;\n";
|
|
1288
1565
|
DESERIALIZE += " while (srcStart < srcEnd) {\n";
|
|
1289
1566
|
DESERIALIZE += " const code = load<u16>(srcStart);\n";
|
|
1290
|
-
DESERIALIZE +=
|
|
1567
|
+
DESERIALIZE +=
|
|
1568
|
+
" if (code == 34 && load<u16>(srcStart - 2) !== 92) {\n";
|
|
1291
1569
|
if (DEBUG > 1)
|
|
1292
|
-
DESERIALIZE +=
|
|
1570
|
+
DESERIALIZE +=
|
|
1571
|
+
' console.log("Value (string, ' +
|
|
1572
|
+
++id +
|
|
1573
|
+
'): " + JSON.Util.ptrToStr(lastIndex, srcStart + 2));';
|
|
1293
1574
|
generateGroups(sortedMembers.string, (group) => {
|
|
1294
1575
|
generateConsts(group);
|
|
1295
1576
|
const first = group[0];
|
|
1296
1577
|
const fName = first.alias || first.name;
|
|
1297
|
-
DESERIALIZE +=
|
|
1298
|
-
|
|
1578
|
+
DESERIALIZE +=
|
|
1579
|
+
indent +
|
|
1580
|
+
" if (" +
|
|
1581
|
+
(first.generic ? "isString<" + first.type + ">() && " : "") +
|
|
1582
|
+
getComparison(fName) +
|
|
1583
|
+
") { // " +
|
|
1584
|
+
fName +
|
|
1585
|
+
"\n";
|
|
1586
|
+
DESERIALIZE +=
|
|
1587
|
+
indent +
|
|
1588
|
+
" store<" +
|
|
1589
|
+
first.type +
|
|
1590
|
+
">(changetype<usize>(out), JSON.__deserialize<" +
|
|
1591
|
+
first.type +
|
|
1592
|
+
">(lastIndex, srcStart + 2), offsetof<this>(" +
|
|
1593
|
+
JSON.stringify(first.name) +
|
|
1594
|
+
"));\n";
|
|
1299
1595
|
DESERIALIZE += indent + " srcStart += 4;\n";
|
|
1300
1596
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
1301
1597
|
DESERIALIZE += indent + " break;\n";
|
|
@@ -1303,8 +1599,23 @@ export class JSONTransform extends Visitor {
|
|
|
1303
1599
|
for (let i = 1; i < group.length; i++) {
|
|
1304
1600
|
const mem = group[i];
|
|
1305
1601
|
const memName = mem.alias || mem.name;
|
|
1306
|
-
DESERIALIZE +=
|
|
1307
|
-
|
|
1602
|
+
DESERIALIZE +=
|
|
1603
|
+
indent +
|
|
1604
|
+
" else if (" +
|
|
1605
|
+
(mem.generic ? "isString<" + mem.type + ">() && " : "") +
|
|
1606
|
+
getComparison(memName) +
|
|
1607
|
+
") { // " +
|
|
1608
|
+
memName +
|
|
1609
|
+
"\n";
|
|
1610
|
+
DESERIALIZE +=
|
|
1611
|
+
indent +
|
|
1612
|
+
" store<" +
|
|
1613
|
+
mem.type +
|
|
1614
|
+
">(changetype<usize>(out), JSON.__deserialize<" +
|
|
1615
|
+
mem.type +
|
|
1616
|
+
">(lastIndex, srcStart + 2), offsetof<this>(" +
|
|
1617
|
+
JSON.stringify(mem.name) +
|
|
1618
|
+
"));\n";
|
|
1308
1619
|
DESERIALIZE += indent + " srcStart += 4;\n";
|
|
1309
1620
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
1310
1621
|
DESERIALIZE += indent + " break;\n";
|
|
@@ -1312,7 +1623,9 @@ export class JSONTransform extends Visitor {
|
|
|
1312
1623
|
}
|
|
1313
1624
|
if (STRICT) {
|
|
1314
1625
|
DESERIALIZE += " else {\n";
|
|
1315
|
-
DESERIALIZE +=
|
|
1626
|
+
DESERIALIZE +=
|
|
1627
|
+
indent +
|
|
1628
|
+
' 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
1629
|
DESERIALIZE += indent + " }\n";
|
|
1317
1630
|
}
|
|
1318
1631
|
else {
|
|
@@ -1335,15 +1648,40 @@ export class JSONTransform extends Visitor {
|
|
|
1335
1648
|
DESERIALIZE += " srcStart += 2;\n";
|
|
1336
1649
|
DESERIALIZE += " while (srcStart < srcEnd) {\n";
|
|
1337
1650
|
DESERIALIZE += " const code = load<u16>(srcStart);\n";
|
|
1338
|
-
DESERIALIZE +=
|
|
1651
|
+
DESERIALIZE +=
|
|
1652
|
+
" if (code == 44 || code == 125 || JSON.Util.isSpace(code)) {\n";
|
|
1339
1653
|
if (DEBUG > 1)
|
|
1340
|
-
DESERIALIZE +=
|
|
1654
|
+
DESERIALIZE +=
|
|
1655
|
+
' console.log("Value (number, ' +
|
|
1656
|
+
++id +
|
|
1657
|
+
'): " + JSON.Util.ptrToStr(lastIndex, srcStart));';
|
|
1341
1658
|
generateGroups(sortedMembers.number, (group) => {
|
|
1342
1659
|
generateConsts(group);
|
|
1343
1660
|
const first = group[0];
|
|
1344
1661
|
const fName = first.alias || first.name;
|
|
1345
|
-
DESERIALIZE +=
|
|
1346
|
-
|
|
1662
|
+
DESERIALIZE +=
|
|
1663
|
+
indent +
|
|
1664
|
+
" if (" +
|
|
1665
|
+
(first.generic
|
|
1666
|
+
? "(isInteger<" +
|
|
1667
|
+
first.type +
|
|
1668
|
+
">() || isFloat<" +
|
|
1669
|
+
first.type +
|
|
1670
|
+
">()) && "
|
|
1671
|
+
: "") +
|
|
1672
|
+
getComparison(fName) +
|
|
1673
|
+
") { // " +
|
|
1674
|
+
fName +
|
|
1675
|
+
"\n";
|
|
1676
|
+
DESERIALIZE +=
|
|
1677
|
+
indent +
|
|
1678
|
+
" store<" +
|
|
1679
|
+
first.type +
|
|
1680
|
+
">(changetype<usize>(out), JSON.__deserialize<" +
|
|
1681
|
+
first.type +
|
|
1682
|
+
">(lastIndex, srcStart), offsetof<this>(" +
|
|
1683
|
+
JSON.stringify(first.name) +
|
|
1684
|
+
"));\n";
|
|
1347
1685
|
DESERIALIZE += indent + " srcStart += 2;\n";
|
|
1348
1686
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
1349
1687
|
DESERIALIZE += indent + " break;\n";
|
|
@@ -1351,8 +1689,29 @@ export class JSONTransform extends Visitor {
|
|
|
1351
1689
|
for (let i = 1; i < group.length; i++) {
|
|
1352
1690
|
const mem = group[i];
|
|
1353
1691
|
const memName = mem.alias || mem.name;
|
|
1354
|
-
DESERIALIZE +=
|
|
1355
|
-
|
|
1692
|
+
DESERIALIZE +=
|
|
1693
|
+
indent +
|
|
1694
|
+
" else if (" +
|
|
1695
|
+
(mem.generic
|
|
1696
|
+
? "(isInteger<" +
|
|
1697
|
+
mem.type +
|
|
1698
|
+
">() || isFloat<" +
|
|
1699
|
+
mem.type +
|
|
1700
|
+
">()) && "
|
|
1701
|
+
: "") +
|
|
1702
|
+
getComparison(memName) +
|
|
1703
|
+
") { // " +
|
|
1704
|
+
memName +
|
|
1705
|
+
"\n";
|
|
1706
|
+
DESERIALIZE +=
|
|
1707
|
+
indent +
|
|
1708
|
+
" store<" +
|
|
1709
|
+
mem.type +
|
|
1710
|
+
">(changetype<usize>(out), JSON.__deserialize<" +
|
|
1711
|
+
mem.type +
|
|
1712
|
+
">(lastIndex, srcStart), offsetof<this>(" +
|
|
1713
|
+
JSON.stringify(mem.name) +
|
|
1714
|
+
"));\n";
|
|
1356
1715
|
DESERIALIZE += indent + " srcStart += 2;\n";
|
|
1357
1716
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
1358
1717
|
DESERIALIZE += indent + " break;\n";
|
|
@@ -1360,7 +1719,9 @@ export class JSONTransform extends Visitor {
|
|
|
1360
1719
|
}
|
|
1361
1720
|
if (STRICT) {
|
|
1362
1721
|
DESERIALIZE += " else {\n";
|
|
1363
|
-
DESERIALIZE +=
|
|
1722
|
+
DESERIALIZE +=
|
|
1723
|
+
indent +
|
|
1724
|
+
' 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
1725
|
DESERIALIZE += indent + " }\n";
|
|
1365
1726
|
}
|
|
1366
1727
|
else {
|
|
@@ -1386,34 +1747,68 @@ export class JSONTransform extends Visitor {
|
|
|
1386
1747
|
DESERIALIZE += " const code = load<u16>(srcStart);\n";
|
|
1387
1748
|
DESERIALIZE += " if (code == 34) {\n";
|
|
1388
1749
|
DESERIALIZE += " srcStart += 2;\n";
|
|
1389
|
-
DESERIALIZE +=
|
|
1750
|
+
DESERIALIZE +=
|
|
1751
|
+
" while (!(load<u16>(srcStart) == 34 && load<u16>(srcStart - 2) != 92)) srcStart += 2;\n";
|
|
1390
1752
|
DESERIALIZE += " } else if (code == 125) {\n";
|
|
1391
1753
|
DESERIALIZE += " if (--depth == 0) {\n";
|
|
1392
1754
|
DESERIALIZE += " srcStart += 2;\n";
|
|
1393
1755
|
if (DEBUG > 1)
|
|
1394
|
-
DESERIALIZE +=
|
|
1756
|
+
DESERIALIZE +=
|
|
1757
|
+
' console.log("Value (object, ' +
|
|
1758
|
+
++id +
|
|
1759
|
+
'): " + JSON.Util.ptrToStr(lastIndex, srcStart));';
|
|
1395
1760
|
indent = " ";
|
|
1396
1761
|
generateGroups(sortedMembers.object, (group) => {
|
|
1397
1762
|
generateConsts(group);
|
|
1398
1763
|
const first = group[0];
|
|
1399
1764
|
const fName = first.alias || first.name;
|
|
1400
|
-
DESERIALIZE +=
|
|
1401
|
-
|
|
1765
|
+
DESERIALIZE +=
|
|
1766
|
+
indent +
|
|
1767
|
+
" if (" +
|
|
1768
|
+
getComparison(fName) +
|
|
1769
|
+
") { // " +
|
|
1770
|
+
fName +
|
|
1771
|
+
"\n";
|
|
1772
|
+
DESERIALIZE +=
|
|
1773
|
+
indent +
|
|
1774
|
+
" store<" +
|
|
1775
|
+
first.type +
|
|
1776
|
+
">(changetype<usize>(out), JSON.__deserialize<" +
|
|
1777
|
+
first.type +
|
|
1778
|
+
">(lastIndex, srcStart), offsetof<this>(" +
|
|
1779
|
+
JSON.stringify(first.name) +
|
|
1780
|
+
"));\n";
|
|
1402
1781
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
1403
1782
|
DESERIALIZE += indent + " break;\n";
|
|
1404
1783
|
DESERIALIZE += indent + " }";
|
|
1405
1784
|
for (let i = 1; i < group.length; i++) {
|
|
1406
1785
|
const mem = group[i];
|
|
1407
1786
|
const memName = mem.alias || mem.name;
|
|
1408
|
-
DESERIALIZE +=
|
|
1409
|
-
|
|
1787
|
+
DESERIALIZE +=
|
|
1788
|
+
indent +
|
|
1789
|
+
" else if (" +
|
|
1790
|
+
getComparison(memName) +
|
|
1791
|
+
") { // " +
|
|
1792
|
+
memName +
|
|
1793
|
+
"\n";
|
|
1794
|
+
DESERIALIZE +=
|
|
1795
|
+
indent +
|
|
1796
|
+
" store<" +
|
|
1797
|
+
mem.type +
|
|
1798
|
+
">(changetype<usize>(out), JSON.__deserialize<" +
|
|
1799
|
+
mem.type +
|
|
1800
|
+
">(lastIndex, srcStart), offsetof<this>(" +
|
|
1801
|
+
JSON.stringify(mem.name) +
|
|
1802
|
+
"));\n";
|
|
1410
1803
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
1411
1804
|
DESERIALIZE += indent + " break;\n";
|
|
1412
1805
|
DESERIALIZE += indent + " }";
|
|
1413
1806
|
}
|
|
1414
1807
|
if (STRICT) {
|
|
1415
1808
|
DESERIALIZE += " else {\n";
|
|
1416
|
-
DESERIALIZE +=
|
|
1809
|
+
DESERIALIZE +=
|
|
1810
|
+
indent +
|
|
1811
|
+
' 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
1812
|
DESERIALIZE += indent + " }\n";
|
|
1418
1813
|
}
|
|
1419
1814
|
else {
|
|
@@ -1440,34 +1835,70 @@ export class JSONTransform extends Visitor {
|
|
|
1440
1835
|
DESERIALIZE += " const code = load<u16>(srcStart);\n";
|
|
1441
1836
|
DESERIALIZE += " if (code == 34) {\n";
|
|
1442
1837
|
DESERIALIZE += " srcStart += 2;\n";
|
|
1443
|
-
DESERIALIZE +=
|
|
1838
|
+
DESERIALIZE +=
|
|
1839
|
+
" while (!(load<u16>(srcStart) == 34 && load<u16>(srcStart - 2) != 92)) srcStart += 2;\n";
|
|
1444
1840
|
DESERIALIZE += " } else if (code == 93) {\n";
|
|
1445
1841
|
DESERIALIZE += " if (--depth == 0) {\n";
|
|
1446
1842
|
DESERIALIZE += " srcStart += 2;\n";
|
|
1447
1843
|
if (DEBUG > 1)
|
|
1448
|
-
DESERIALIZE +=
|
|
1844
|
+
DESERIALIZE +=
|
|
1845
|
+
' console.log("Value (object, ' +
|
|
1846
|
+
++id +
|
|
1847
|
+
'): " + JSON.Util.ptrToStr(lastIndex, srcStart));';
|
|
1449
1848
|
indent = " ";
|
|
1450
1849
|
generateGroups(sortedMembers.array, (group) => {
|
|
1451
1850
|
generateConsts(group);
|
|
1452
1851
|
const first = group[0];
|
|
1453
1852
|
const fName = first.alias || first.name;
|
|
1454
|
-
DESERIALIZE +=
|
|
1455
|
-
|
|
1853
|
+
DESERIALIZE +=
|
|
1854
|
+
indent +
|
|
1855
|
+
" if (" +
|
|
1856
|
+
(first.generic ? "isArray<" + first.type + ">() && " : "") +
|
|
1857
|
+
getComparison(fName) +
|
|
1858
|
+
") { // " +
|
|
1859
|
+
fName +
|
|
1860
|
+
"\n";
|
|
1861
|
+
DESERIALIZE +=
|
|
1862
|
+
indent +
|
|
1863
|
+
" store<" +
|
|
1864
|
+
first.type +
|
|
1865
|
+
">(changetype<usize>(out), JSON.__deserialize<" +
|
|
1866
|
+
first.type +
|
|
1867
|
+
">(lastIndex, srcStart), offsetof<this>(" +
|
|
1868
|
+
JSON.stringify(first.name) +
|
|
1869
|
+
"));\n";
|
|
1456
1870
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
1457
1871
|
DESERIALIZE += indent + " break;\n";
|
|
1458
1872
|
DESERIALIZE += indent + " }";
|
|
1459
1873
|
for (let i = 1; i < group.length; i++) {
|
|
1460
1874
|
const mem = group[i];
|
|
1461
1875
|
const memName = mem.alias || mem.name;
|
|
1462
|
-
DESERIALIZE +=
|
|
1463
|
-
|
|
1876
|
+
DESERIALIZE +=
|
|
1877
|
+
indent +
|
|
1878
|
+
" else if (" +
|
|
1879
|
+
(mem.generic ? "isArray" + mem.type + ">() && " : "") +
|
|
1880
|
+
getComparison(memName) +
|
|
1881
|
+
") { // " +
|
|
1882
|
+
memName +
|
|
1883
|
+
"\n";
|
|
1884
|
+
DESERIALIZE +=
|
|
1885
|
+
indent +
|
|
1886
|
+
" store<" +
|
|
1887
|
+
mem.type +
|
|
1888
|
+
">(changetype<usize>(out), JSON.__deserialize<" +
|
|
1889
|
+
mem.type +
|
|
1890
|
+
">(lastIndex, srcStart), offsetof<this>(" +
|
|
1891
|
+
JSON.stringify(mem.name) +
|
|
1892
|
+
"));\n";
|
|
1464
1893
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
1465
1894
|
DESERIALIZE += indent + " break;\n";
|
|
1466
1895
|
DESERIALIZE += indent + " }";
|
|
1467
1896
|
}
|
|
1468
1897
|
if (STRICT) {
|
|
1469
1898
|
DESERIALIZE += " else {\n";
|
|
1470
|
-
DESERIALIZE +=
|
|
1899
|
+
DESERIALIZE +=
|
|
1900
|
+
indent +
|
|
1901
|
+
' 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
1902
|
DESERIALIZE += indent + " }\n";
|
|
1472
1903
|
}
|
|
1473
1904
|
else {
|
|
@@ -1487,20 +1918,46 @@ export class JSONTransform extends Visitor {
|
|
|
1487
1918
|
}
|
|
1488
1919
|
if (!STRICT || sortedMembers.boolean.length) {
|
|
1489
1920
|
DESERIALIZE += mbElse + "if (code == 116) {\n";
|
|
1490
|
-
DESERIALIZE +=
|
|
1921
|
+
DESERIALIZE +=
|
|
1922
|
+
" if (load<u64>(srcStart) == 28429475166421108) {\n";
|
|
1491
1923
|
DESERIALIZE += " srcStart += 8;\n";
|
|
1492
1924
|
if (DEBUG > 1)
|
|
1493
|
-
DESERIALIZE +=
|
|
1925
|
+
DESERIALIZE +=
|
|
1926
|
+
' console.log("Value (bool, ' +
|
|
1927
|
+
++id +
|
|
1928
|
+
'): " + JSON.Util.ptrToStr(lastIndex, srcStart - 8));';
|
|
1494
1929
|
generateGroups(sortedMembers.boolean, (group) => {
|
|
1495
1930
|
generateConsts(group);
|
|
1496
1931
|
const first = group[0];
|
|
1497
1932
|
const fName = first.alias || first.name;
|
|
1498
|
-
DESERIALIZE +=
|
|
1499
|
-
|
|
1500
|
-
|
|
1933
|
+
DESERIALIZE +=
|
|
1934
|
+
indent +
|
|
1935
|
+
" if (" +
|
|
1936
|
+
(first.generic ? "isBoolean<" + first.type + ">() && " : "") +
|
|
1937
|
+
getComparison(fName) +
|
|
1938
|
+
") { // " +
|
|
1939
|
+
fName +
|
|
1940
|
+
"\n";
|
|
1941
|
+
if (first.type.startsWith("JSON.Box<bool") ||
|
|
1942
|
+
first.type.startsWith("JSON.Box<boolean") ||
|
|
1943
|
+
first.type.startsWith("Box<bool") ||
|
|
1944
|
+
first.type.startsWith("Box<boolean")) {
|
|
1945
|
+
DESERIALIZE +=
|
|
1946
|
+
indent +
|
|
1947
|
+
" store<" +
|
|
1948
|
+
first.type +
|
|
1949
|
+
">(changetype<usize>(out), changetype<" +
|
|
1950
|
+
first.type +
|
|
1951
|
+
">(JSON.Box.from<bool>(true)), offsetof<this>(" +
|
|
1952
|
+
JSON.stringify(first.name) +
|
|
1953
|
+
"));\n";
|
|
1501
1954
|
}
|
|
1502
1955
|
else {
|
|
1503
|
-
DESERIALIZE +=
|
|
1956
|
+
DESERIALIZE +=
|
|
1957
|
+
indent +
|
|
1958
|
+
" store<boolean>(changetype<usize>(out), true, offsetof<this>(" +
|
|
1959
|
+
JSON.stringify(first.name) +
|
|
1960
|
+
"));\n";
|
|
1504
1961
|
}
|
|
1505
1962
|
DESERIALIZE += indent + " srcStart += 2;\n";
|
|
1506
1963
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
@@ -1509,12 +1966,34 @@ export class JSONTransform extends Visitor {
|
|
|
1509
1966
|
for (let i = 1; i < group.length; i++) {
|
|
1510
1967
|
const mem = group[i];
|
|
1511
1968
|
const memName = mem.alias || mem.name;
|
|
1512
|
-
DESERIALIZE +=
|
|
1513
|
-
|
|
1514
|
-
|
|
1969
|
+
DESERIALIZE +=
|
|
1970
|
+
indent +
|
|
1971
|
+
" else if (" +
|
|
1972
|
+
(mem.generic ? "isBoolean<" + mem.type + ">() && " : "") +
|
|
1973
|
+
getComparison(memName) +
|
|
1974
|
+
") { // " +
|
|
1975
|
+
memName +
|
|
1976
|
+
"\n";
|
|
1977
|
+
if (mem.type.startsWith("JSON.Box<bool") ||
|
|
1978
|
+
mem.type.startsWith("JSON.Box<boolean") ||
|
|
1979
|
+
mem.type.startsWith("Box<bool") ||
|
|
1980
|
+
mem.type.startsWith("Box<boolean")) {
|
|
1981
|
+
DESERIALIZE +=
|
|
1982
|
+
indent +
|
|
1983
|
+
" store<" +
|
|
1984
|
+
mem.type +
|
|
1985
|
+
">(changetype<usize>(out), changetype<" +
|
|
1986
|
+
mem.type +
|
|
1987
|
+
">(JSON.Box.from<bool>(true)), offsetof<this>(" +
|
|
1988
|
+
JSON.stringify(mem.name) +
|
|
1989
|
+
"));\n";
|
|
1515
1990
|
}
|
|
1516
1991
|
else {
|
|
1517
|
-
DESERIALIZE +=
|
|
1992
|
+
DESERIALIZE +=
|
|
1993
|
+
indent +
|
|
1994
|
+
" store<boolean>(changetype<usize>(out), true, offsetof<this>(" +
|
|
1995
|
+
JSON.stringify(mem.name) +
|
|
1996
|
+
"));\n";
|
|
1518
1997
|
}
|
|
1519
1998
|
DESERIALIZE += indent + " srcStart += 2;\n";
|
|
1520
1999
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
@@ -1523,7 +2002,9 @@ export class JSONTransform extends Visitor {
|
|
|
1523
2002
|
}
|
|
1524
2003
|
if (STRICT) {
|
|
1525
2004
|
DESERIALIZE += " else {\n";
|
|
1526
|
-
DESERIALIZE +=
|
|
2005
|
+
DESERIALIZE +=
|
|
2006
|
+
indent +
|
|
2007
|
+
' 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
2008
|
DESERIALIZE += indent + " }\n";
|
|
1528
2009
|
}
|
|
1529
2010
|
else {
|
|
@@ -1536,7 +2017,8 @@ export class JSONTransform extends Visitor {
|
|
|
1536
2017
|
}, "boolean");
|
|
1537
2018
|
DESERIALIZE += " }";
|
|
1538
2019
|
DESERIALIZE += " else {\n";
|
|
1539
|
-
DESERIALIZE +=
|
|
2020
|
+
DESERIALIZE +=
|
|
2021
|
+
" throw new Error(\"Expected to find 'true' but found '\" + JSON.Util.ptrToStr(lastIndex, srcStart) + \"' instead at position \" + (srcEnd - srcStart).toString());\n";
|
|
1540
2022
|
DESERIALIZE += " }";
|
|
1541
2023
|
DESERIALIZE += "\n }";
|
|
1542
2024
|
mbElse = " else ";
|
|
@@ -1544,17 +2026,42 @@ export class JSONTransform extends Visitor {
|
|
|
1544
2026
|
DESERIALIZE += " {\n";
|
|
1545
2027
|
DESERIALIZE += " srcStart += 10;\n";
|
|
1546
2028
|
if (DEBUG > 1)
|
|
1547
|
-
DESERIALIZE +=
|
|
2029
|
+
DESERIALIZE +=
|
|
2030
|
+
' console.log("Value (bool, ' +
|
|
2031
|
+
++id +
|
|
2032
|
+
'): " + JSON.Util.ptrToStr(lastIndex, srcStart - 10));';
|
|
1548
2033
|
generateGroups(sortedMembers.boolean, (group) => {
|
|
1549
2034
|
generateConsts(group);
|
|
1550
2035
|
const first = group[0];
|
|
1551
2036
|
const fName = first.alias || first.name;
|
|
1552
|
-
DESERIALIZE +=
|
|
1553
|
-
|
|
1554
|
-
|
|
2037
|
+
DESERIALIZE +=
|
|
2038
|
+
indent +
|
|
2039
|
+
" if (" +
|
|
2040
|
+
(first.generic ? "isBoolean<" + first.type + ">() && " : "") +
|
|
2041
|
+
getComparison(fName) +
|
|
2042
|
+
") { // " +
|
|
2043
|
+
fName +
|
|
2044
|
+
"\n";
|
|
2045
|
+
if (first.type.startsWith("JSON.Box<bool") ||
|
|
2046
|
+
first.type.startsWith("JSON.Box<boolean") ||
|
|
2047
|
+
first.type.startsWith("Box<bool") ||
|
|
2048
|
+
first.type.startsWith("Box<boolean")) {
|
|
2049
|
+
DESERIALIZE +=
|
|
2050
|
+
indent +
|
|
2051
|
+
" store<" +
|
|
2052
|
+
first.type +
|
|
2053
|
+
">(changetype<usize>(out), changetype<" +
|
|
2054
|
+
first.type +
|
|
2055
|
+
">(JSON.Box.from<bool>(false)), offsetof<this>(" +
|
|
2056
|
+
JSON.stringify(first.name) +
|
|
2057
|
+
"));\n";
|
|
1555
2058
|
}
|
|
1556
2059
|
else {
|
|
1557
|
-
DESERIALIZE +=
|
|
2060
|
+
DESERIALIZE +=
|
|
2061
|
+
indent +
|
|
2062
|
+
" store<boolean>(changetype<usize>(out), false, offsetof<this>(" +
|
|
2063
|
+
JSON.stringify(first.name) +
|
|
2064
|
+
"));\n";
|
|
1558
2065
|
}
|
|
1559
2066
|
DESERIALIZE += indent + " srcStart += 2;\n";
|
|
1560
2067
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
@@ -1563,12 +2070,34 @@ export class JSONTransform extends Visitor {
|
|
|
1563
2070
|
for (let i = 1; i < group.length; i++) {
|
|
1564
2071
|
const mem = group[i];
|
|
1565
2072
|
const memName = mem.alias || mem.name;
|
|
1566
|
-
DESERIALIZE +=
|
|
1567
|
-
|
|
1568
|
-
|
|
2073
|
+
DESERIALIZE +=
|
|
2074
|
+
indent +
|
|
2075
|
+
" else if (" +
|
|
2076
|
+
(mem.generic ? "isBoolean<" + mem.type + ">() && " : "") +
|
|
2077
|
+
getComparison(memName) +
|
|
2078
|
+
") { // " +
|
|
2079
|
+
memName +
|
|
2080
|
+
"\n";
|
|
2081
|
+
if (mem.type.startsWith("JSON.Box<bool") ||
|
|
2082
|
+
mem.type.startsWith("JSON.Box<boolean") ||
|
|
2083
|
+
mem.type.startsWith("Box<bool") ||
|
|
2084
|
+
mem.type.startsWith("Box<boolean")) {
|
|
2085
|
+
DESERIALIZE +=
|
|
2086
|
+
indent +
|
|
2087
|
+
" store<" +
|
|
2088
|
+
mem.type +
|
|
2089
|
+
">(changetype<usize>(out), changetype<" +
|
|
2090
|
+
mem.type +
|
|
2091
|
+
">(JSON.Box.from<bool>(false)), offsetof<this>(" +
|
|
2092
|
+
JSON.stringify(mem.name) +
|
|
2093
|
+
"));\n";
|
|
1569
2094
|
}
|
|
1570
2095
|
else {
|
|
1571
|
-
DESERIALIZE +=
|
|
2096
|
+
DESERIALIZE +=
|
|
2097
|
+
indent +
|
|
2098
|
+
" store<boolean>(changetype<usize>(out), false, offsetof<this>(" +
|
|
2099
|
+
JSON.stringify(mem.name) +
|
|
2100
|
+
"));\n";
|
|
1572
2101
|
}
|
|
1573
2102
|
DESERIALIZE += indent + " srcStart += 2;\n";
|
|
1574
2103
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
@@ -1577,7 +2106,9 @@ export class JSONTransform extends Visitor {
|
|
|
1577
2106
|
}
|
|
1578
2107
|
if (STRICT) {
|
|
1579
2108
|
DESERIALIZE += " else {\n";
|
|
1580
|
-
DESERIALIZE +=
|
|
2109
|
+
DESERIALIZE +=
|
|
2110
|
+
indent +
|
|
2111
|
+
' 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
2112
|
DESERIALIZE += indent + " }\n";
|
|
1582
2113
|
}
|
|
1583
2114
|
else {
|
|
@@ -1594,16 +2125,31 @@ export class JSONTransform extends Visitor {
|
|
|
1594
2125
|
}
|
|
1595
2126
|
if (!STRICT || sortedMembers.null.length) {
|
|
1596
2127
|
DESERIALIZE += mbElse + "if (code == 110) {\n";
|
|
1597
|
-
DESERIALIZE +=
|
|
2128
|
+
DESERIALIZE +=
|
|
2129
|
+
" if (load<u64>(srcStart) == 30399761348886638) {\n";
|
|
1598
2130
|
DESERIALIZE += " srcStart += 8;\n";
|
|
1599
2131
|
if (DEBUG > 1)
|
|
1600
|
-
DESERIALIZE +=
|
|
2132
|
+
DESERIALIZE +=
|
|
2133
|
+
' console.log("Value (null, ' +
|
|
2134
|
+
++id +
|
|
2135
|
+
'): " + JSON.Util.ptrToStr(lastIndex, srcStart - 8));';
|
|
1601
2136
|
generateGroups(sortedMembers.null, (group) => {
|
|
1602
2137
|
generateConsts(group);
|
|
1603
2138
|
const first = group[0];
|
|
1604
2139
|
const fName = first.alias || first.name;
|
|
1605
|
-
DESERIALIZE +=
|
|
1606
|
-
|
|
2140
|
+
DESERIALIZE +=
|
|
2141
|
+
indent +
|
|
2142
|
+
" if (" +
|
|
2143
|
+
(first.generic ? "isNullable<" + first.type + ">() && " : "") +
|
|
2144
|
+
getComparison(fName) +
|
|
2145
|
+
") { // " +
|
|
2146
|
+
fName +
|
|
2147
|
+
"\n";
|
|
2148
|
+
DESERIALIZE +=
|
|
2149
|
+
indent +
|
|
2150
|
+
" store<usize>(changetype<usize>(out), 0, offsetof<this>(" +
|
|
2151
|
+
JSON.stringify(first.name) +
|
|
2152
|
+
"));\n";
|
|
1607
2153
|
DESERIALIZE += indent + " srcStart += 2;\n";
|
|
1608
2154
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
1609
2155
|
DESERIALIZE += indent + " break;\n";
|
|
@@ -1611,8 +2157,19 @@ export class JSONTransform extends Visitor {
|
|
|
1611
2157
|
for (let i = 1; i < group.length; i++) {
|
|
1612
2158
|
const mem = group[i];
|
|
1613
2159
|
const memName = mem.alias || mem.name;
|
|
1614
|
-
DESERIALIZE +=
|
|
1615
|
-
|
|
2160
|
+
DESERIALIZE +=
|
|
2161
|
+
indent +
|
|
2162
|
+
" else if (" +
|
|
2163
|
+
(mem.generic ? "isNullable<" + mem.type + ">() && " : "") +
|
|
2164
|
+
getComparison(memName) +
|
|
2165
|
+
") { // " +
|
|
2166
|
+
memName +
|
|
2167
|
+
"\n";
|
|
2168
|
+
DESERIALIZE +=
|
|
2169
|
+
indent +
|
|
2170
|
+
" store<usize>(changetype<usize>(out), 0, offsetof<this>(" +
|
|
2171
|
+
JSON.stringify(mem.name) +
|
|
2172
|
+
"));\n";
|
|
1616
2173
|
DESERIALIZE += indent + " srcStart += 2;\n";
|
|
1617
2174
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
1618
2175
|
DESERIALIZE += indent + " break;\n";
|
|
@@ -1620,7 +2177,9 @@ export class JSONTransform extends Visitor {
|
|
|
1620
2177
|
}
|
|
1621
2178
|
if (STRICT) {
|
|
1622
2179
|
DESERIALIZE += " else {\n";
|
|
1623
|
-
DESERIALIZE +=
|
|
2180
|
+
DESERIALIZE +=
|
|
2181
|
+
indent +
|
|
2182
|
+
' 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
2183
|
DESERIALIZE += indent + " }\n";
|
|
1625
2184
|
}
|
|
1626
2185
|
else {
|
|
@@ -1649,7 +2208,13 @@ export class JSONTransform extends Visitor {
|
|
|
1649
2208
|
SERIALIZE += indent + "store<u16>(bs.offset, 125, 0); // }\n";
|
|
1650
2209
|
SERIALIZE += indent + "bs.offset += 2;\n";
|
|
1651
2210
|
SERIALIZE += "}";
|
|
1652
|
-
SERIALIZE =
|
|
2211
|
+
SERIALIZE =
|
|
2212
|
+
SERIALIZE.slice(0, 32) +
|
|
2213
|
+
indent +
|
|
2214
|
+
"bs.proposeSize(" +
|
|
2215
|
+
this.schema.byteSize +
|
|
2216
|
+
");\n" +
|
|
2217
|
+
SERIALIZE.slice(32);
|
|
1653
2218
|
INITIALIZE += " return this;\n";
|
|
1654
2219
|
INITIALIZE += "}";
|
|
1655
2220
|
if (DEBUG > 0) {
|
|
@@ -1659,24 +2224,37 @@ export class JSONTransform extends Visitor {
|
|
|
1659
2224
|
}
|
|
1660
2225
|
const SERIALIZE_METHOD = SimpleParser.parseClassMember(SERIALIZE_CUSTOM || SERIALIZE, node);
|
|
1661
2226
|
const INITIALIZE_METHOD = SimpleParser.parseClassMember(INITIALIZE, node);
|
|
1662
|
-
const DESERIALIZE_CUSTOM_METHOD = DESERIALIZE_CUSTOM
|
|
2227
|
+
const DESERIALIZE_CUSTOM_METHOD = DESERIALIZE_CUSTOM
|
|
2228
|
+
? SimpleParser.parseClassMember(DESERIALIZE_CUSTOM, node)
|
|
2229
|
+
: null;
|
|
1663
2230
|
const DESERIALIZE_SLOW_METHOD = SimpleParser.parseClassMember(DESERIALIZE, node);
|
|
1664
|
-
const DESERIALIZE_FAST_METHOD = useFastPath
|
|
2231
|
+
const DESERIALIZE_FAST_METHOD = useFastPath
|
|
2232
|
+
? SimpleParser.parseClassMember(DESERIALIZE_FAST, node)
|
|
2233
|
+
: null;
|
|
1665
2234
|
if (!node.members.find((v) => v.name.text == "__SERIALIZE"))
|
|
1666
2235
|
node.members.push(SERIALIZE_METHOD);
|
|
1667
|
-
if (INITIALIZE_METHOD &&
|
|
2236
|
+
if (INITIALIZE_METHOD &&
|
|
2237
|
+
!node.members.find((v) => v.name.text == "__INITIALIZE"))
|
|
1668
2238
|
node.members.push(INITIALIZE_METHOD);
|
|
1669
|
-
if (DESERIALIZE_CUSTOM_METHOD &&
|
|
2239
|
+
if (DESERIALIZE_CUSTOM_METHOD &&
|
|
2240
|
+
!node.members.find((v) => v.name.text == "__DESERIALIZE_CUSTOM"))
|
|
1670
2241
|
node.members.push(DESERIALIZE_CUSTOM_METHOD);
|
|
1671
|
-
if (!DESERIALIZE_CUSTOM &&
|
|
2242
|
+
if (!DESERIALIZE_CUSTOM &&
|
|
2243
|
+
DESERIALIZE_SLOW_METHOD &&
|
|
2244
|
+
!node.members.find((v) => v.name.text == "__DESERIALIZE_SLOW"))
|
|
1672
2245
|
node.members.push(DESERIALIZE_SLOW_METHOD);
|
|
1673
|
-
if (!DESERIALIZE_CUSTOM &&
|
|
2246
|
+
if (!DESERIALIZE_CUSTOM &&
|
|
2247
|
+
useFastPath &&
|
|
2248
|
+
DESERIALIZE_FAST_METHOD &&
|
|
2249
|
+
!node.members.find((v) => v.name.text == "__DESERIALIZE_FAST"))
|
|
1674
2250
|
node.members.push(DESERIALIZE_FAST_METHOD);
|
|
1675
2251
|
super.visitClassDeclaration(node);
|
|
1676
2252
|
}
|
|
1677
2253
|
getSchema(name) {
|
|
1678
2254
|
name = stripNull(name);
|
|
1679
|
-
return this.schemas
|
|
2255
|
+
return (this.schemas
|
|
2256
|
+
.get(this.schema.node.range.source.internalPath)
|
|
2257
|
+
.find((s) => s.name == name) || null);
|
|
1680
2258
|
}
|
|
1681
2259
|
generateEmptyMethods(node) {
|
|
1682
2260
|
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 +2270,8 @@ export class JSONTransform extends Visitor {
|
|
|
1692
2270
|
const DESERIALIZE_SLOW_METHOD_EMPTY = SimpleParser.parseClassMember(DESERIALIZE_SLOW_EMPTY, node);
|
|
1693
2271
|
if (!node.members.find((v) => v.name.text == "__SERIALIZE"))
|
|
1694
2272
|
node.members.push(SERIALIZE_METHOD_EMPTY);
|
|
1695
|
-
if (INITIALIZE_METHOD_EMPTY &&
|
|
2273
|
+
if (INITIALIZE_METHOD_EMPTY &&
|
|
2274
|
+
!node.members.find((v) => v.name.text == "__INITIALIZE"))
|
|
1696
2275
|
node.members.push(INITIALIZE_METHOD_EMPTY);
|
|
1697
2276
|
if (!node.members.find((v) => v.name.text == "__DESERIALIZE_SLOW"))
|
|
1698
2277
|
node.members.push(DESERIALIZE_SLOW_METHOD_EMPTY);
|
|
@@ -1709,23 +2288,37 @@ export class JSONTransform extends Visitor {
|
|
|
1709
2288
|
this.baseCWD = this.baseCWD.replaceAll("/", path.sep);
|
|
1710
2289
|
const baseDir = path.resolve(fileURLToPath(import.meta.url), "..", "..", "..");
|
|
1711
2290
|
let fromPath = node.range.source.normalizedPath.replaceAll("/", path.sep);
|
|
1712
|
-
fromPath = fromPath.startsWith("~lib")
|
|
2291
|
+
fromPath = fromPath.startsWith("~lib")
|
|
2292
|
+
? fromPath.slice(5)
|
|
2293
|
+
: path.join(this.baseCWD, fromPath);
|
|
1713
2294
|
const bsImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "bs" || d.name.text == "bs"));
|
|
1714
2295
|
const jsonImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "JSON" || d.name.text == "JSON"));
|
|
1715
2296
|
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" ||
|
|
1717
|
-
|
|
1718
|
-
const
|
|
2297
|
+
const deserializeIntegerFieldImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "deserializeIntegerField" ||
|
|
2298
|
+
d.name.text == "deserializeIntegerField"));
|
|
2299
|
+
const deserializeUnsignedFieldImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "deserializeUnsignedField" ||
|
|
2300
|
+
d.name.text == "deserializeUnsignedField"));
|
|
2301
|
+
const deserializeFloatFieldImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "deserializeFloatField" ||
|
|
2302
|
+
d.name.text == "deserializeFloatField"));
|
|
1719
2303
|
const scanValueEndImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "scanValueEnd" || d.name.text == "scanValueEnd"));
|
|
1720
|
-
const deserializeArrayField_SWARImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "deserializeArrayField_SWAR" ||
|
|
1721
|
-
|
|
1722
|
-
const
|
|
1723
|
-
|
|
1724
|
-
const
|
|
1725
|
-
|
|
1726
|
-
const
|
|
1727
|
-
|
|
1728
|
-
const
|
|
2304
|
+
const deserializeArrayField_SWARImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "deserializeArrayField_SWAR" ||
|
|
2305
|
+
d.name.text == "deserializeArrayField_SWAR"));
|
|
2306
|
+
const deserializeArrayInto_SWARImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "deserializeArrayInto_SWAR" ||
|
|
2307
|
+
d.name.text == "deserializeArrayInto_SWAR"));
|
|
2308
|
+
const deserializeMapFieldImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "deserializeMapField" ||
|
|
2309
|
+
d.name.text == "deserializeMapField"));
|
|
2310
|
+
const deserializeMapIntoImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "deserializeMapInto" ||
|
|
2311
|
+
d.name.text == "deserializeMapInto"));
|
|
2312
|
+
const deserializeSetFieldImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "deserializeSetField" ||
|
|
2313
|
+
d.name.text == "deserializeSetField"));
|
|
2314
|
+
const deserializeSetIntoImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "deserializeSetInto" ||
|
|
2315
|
+
d.name.text == "deserializeSetInto"));
|
|
2316
|
+
const deserializeStaticArrayFieldImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "deserializeStaticArrayField" ||
|
|
2317
|
+
d.name.text == "deserializeStaticArrayField"));
|
|
2318
|
+
const deserializeStringFieldSWARImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "deserializeStringField_SWAR" ||
|
|
2319
|
+
d.name.text == "deserializeStringField_SWAR"));
|
|
2320
|
+
const deserializeStringFieldSIMDImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "deserializeStringField_SIMD" ||
|
|
2321
|
+
d.name.text == "deserializeStringField_SIMD"));
|
|
1729
2322
|
const sourceText = readFileSync(fromPath).toString();
|
|
1730
2323
|
const hasLocalDeserializeIntegerField = /\bdeserializeIntegerField\b/.test(sourceText);
|
|
1731
2324
|
const hasLocalDeserializeUnsignedField = /\bdeserializeUnsignedField\b/.test(sourceText);
|
|
@@ -1740,109 +2333,208 @@ export class JSONTransform extends Visitor {
|
|
|
1740
2333
|
const hasLocaldeserializeStaticArrayField = /\bdeserializeStaticArrayField\b/.test(sourceText);
|
|
1741
2334
|
const hasLocalDeserializeStringFieldSWAR = /\bdeserializeStringField_SWAR\b/.test(sourceText);
|
|
1742
2335
|
const hasLocalDeserializeStringFieldSIMD = /\bdeserializeStringField_SIMD\b/.test(sourceText);
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
}
|
|
1747
|
-
else if (!baseRel.startsWith(".") && !baseRel.startsWith("/") && !baseRel.startsWith("json-as")) {
|
|
1748
|
-
baseRel = "./" + baseRel;
|
|
1749
|
-
}
|
|
2336
|
+
const baseRel = normalizeJsonAsBaseRel(path.posix.join(...path
|
|
2337
|
+
.relative(path.dirname(fromPath), path.join(baseDir))
|
|
2338
|
+
.split(path.sep)));
|
|
1750
2339
|
if (!bsImport) {
|
|
1751
|
-
const replaceNode = Node.createImportStatement([
|
|
2340
|
+
const replaceNode = Node.createImportStatement([
|
|
2341
|
+
Node.createImportDeclaration(Node.createIdentifierExpression("bs", node.range, false), null, node.range),
|
|
2342
|
+
], Node.createStringLiteralExpression(path.posix.join(baseRel, "lib", "as-bs"), node.range), node.range);
|
|
1752
2343
|
node.range.source.statements.unshift(replaceNode);
|
|
1753
2344
|
if (DEBUG > 0)
|
|
1754
|
-
console.log("Added import: " +
|
|
2345
|
+
console.log("Added import: " +
|
|
2346
|
+
toString(replaceNode) +
|
|
2347
|
+
" to " +
|
|
2348
|
+
node.range.source.normalizedPath +
|
|
2349
|
+
"\n");
|
|
1755
2350
|
}
|
|
1756
2351
|
if (!jsonImport) {
|
|
1757
|
-
const replaceNode = Node.createImportStatement([
|
|
2352
|
+
const replaceNode = Node.createImportStatement([
|
|
2353
|
+
Node.createImportDeclaration(Node.createIdentifierExpression("JSON", node.range, false), null, node.range),
|
|
2354
|
+
], Node.createStringLiteralExpression(path.posix.join(baseRel, "assembly", "index"), node.range), node.range);
|
|
1758
2355
|
node.range.source.statements.unshift(replaceNode);
|
|
1759
2356
|
if (DEBUG > 0)
|
|
1760
|
-
console.log("Added import: " +
|
|
2357
|
+
console.log("Added import: " +
|
|
2358
|
+
toString(replaceNode) +
|
|
2359
|
+
" to " +
|
|
2360
|
+
node.range.source.normalizedPath +
|
|
2361
|
+
"\n");
|
|
1761
2362
|
}
|
|
1762
2363
|
if (!atoiImport) {
|
|
1763
|
-
const replaceNode = Node.createImportStatement([
|
|
2364
|
+
const replaceNode = Node.createImportStatement([
|
|
2365
|
+
Node.createImportDeclaration(Node.createIdentifierExpression("atoi", node.range, false), null, node.range),
|
|
2366
|
+
], Node.createStringLiteralExpression(path.posix.join(baseRel, "assembly", "util", "atoi"), node.range), node.range);
|
|
1764
2367
|
node.range.source.statements.unshift(replaceNode);
|
|
1765
2368
|
if (DEBUG > 0)
|
|
1766
|
-
console.log("Added import: " +
|
|
2369
|
+
console.log("Added import: " +
|
|
2370
|
+
toString(replaceNode) +
|
|
2371
|
+
" to " +
|
|
2372
|
+
node.range.source.normalizedPath +
|
|
2373
|
+
"\n");
|
|
1767
2374
|
}
|
|
1768
2375
|
if (!deserializeIntegerFieldImport && !hasLocalDeserializeIntegerField) {
|
|
1769
|
-
const replaceNode = Node.createImportStatement([
|
|
2376
|
+
const replaceNode = Node.createImportStatement([
|
|
2377
|
+
Node.createImportDeclaration(Node.createIdentifierExpression("deserializeIntegerField", node.range, false), null, node.range),
|
|
2378
|
+
], Node.createStringLiteralExpression(path.posix.join(baseRel, "assembly", "deserialize", "index", "integer"), node.range), node.range);
|
|
1770
2379
|
node.range.source.statements.unshift(replaceNode);
|
|
1771
2380
|
if (DEBUG > 0)
|
|
1772
|
-
console.log("Added import: " +
|
|
2381
|
+
console.log("Added import: " +
|
|
2382
|
+
toString(replaceNode) +
|
|
2383
|
+
" to " +
|
|
2384
|
+
node.range.source.normalizedPath +
|
|
2385
|
+
"\n");
|
|
1773
2386
|
}
|
|
1774
2387
|
if (!deserializeUnsignedFieldImport && !hasLocalDeserializeUnsignedField) {
|
|
1775
|
-
const replaceNode = Node.createImportStatement([
|
|
2388
|
+
const replaceNode = Node.createImportStatement([
|
|
2389
|
+
Node.createImportDeclaration(Node.createIdentifierExpression("deserializeUnsignedField", node.range, false), null, node.range),
|
|
2390
|
+
], Node.createStringLiteralExpression(path.posix.join(baseRel, "assembly", "deserialize", "index", "unsigned"), node.range), node.range);
|
|
1776
2391
|
node.range.source.statements.unshift(replaceNode);
|
|
1777
2392
|
if (DEBUG > 0)
|
|
1778
|
-
console.log("Added import: " +
|
|
2393
|
+
console.log("Added import: " +
|
|
2394
|
+
toString(replaceNode) +
|
|
2395
|
+
" to " +
|
|
2396
|
+
node.range.source.normalizedPath +
|
|
2397
|
+
"\n");
|
|
1779
2398
|
}
|
|
1780
2399
|
if (!deserializeFloatFieldImport && !hasLocalDeserializeFloatField) {
|
|
1781
|
-
const replaceNode = Node.createImportStatement([
|
|
2400
|
+
const replaceNode = Node.createImportStatement([
|
|
2401
|
+
Node.createImportDeclaration(Node.createIdentifierExpression("deserializeFloatField", node.range, false), null, node.range),
|
|
2402
|
+
], Node.createStringLiteralExpression(path.posix.join(baseRel, "assembly", "deserialize", "simple", "float"), node.range), node.range);
|
|
1782
2403
|
node.range.source.statements.unshift(replaceNode);
|
|
1783
2404
|
if (DEBUG > 0)
|
|
1784
|
-
console.log("Added import: " +
|
|
2405
|
+
console.log("Added import: " +
|
|
2406
|
+
toString(replaceNode) +
|
|
2407
|
+
" to " +
|
|
2408
|
+
node.range.source.normalizedPath +
|
|
2409
|
+
"\n");
|
|
1785
2410
|
}
|
|
1786
2411
|
if (!scanValueEndImport && !hasLocalScanValueEnd) {
|
|
1787
|
-
const replaceNode = Node.createImportStatement([
|
|
2412
|
+
const replaceNode = Node.createImportStatement([
|
|
2413
|
+
Node.createImportDeclaration(Node.createIdentifierExpression("scanValueEnd", node.range, false), null, node.range),
|
|
2414
|
+
], Node.createStringLiteralExpression(path.posix.join(baseRel, "assembly", "deserialize", "swar", "array", "shared"), node.range), node.range);
|
|
1788
2415
|
node.range.source.statements.unshift(replaceNode);
|
|
1789
2416
|
if (DEBUG > 0)
|
|
1790
|
-
console.log("Added import: " +
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
2417
|
+
console.log("Added import: " +
|
|
2418
|
+
toString(replaceNode) +
|
|
2419
|
+
" to " +
|
|
2420
|
+
node.range.source.normalizedPath +
|
|
2421
|
+
"\n");
|
|
2422
|
+
}
|
|
2423
|
+
if (!deserializeArrayField_SWARImport &&
|
|
2424
|
+
!hasLocaldeserializeArrayField_SWAR) {
|
|
2425
|
+
const replaceNode = Node.createImportStatement([
|
|
2426
|
+
Node.createImportDeclaration(Node.createIdentifierExpression("deserializeArrayField_SWAR", node.range, false), null, node.range),
|
|
2427
|
+
], Node.createStringLiteralExpression(path.posix.join(baseRel, "assembly", "deserialize", "simple", "array"), 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
|
-
|
|
2430
|
+
console.log("Added import: " +
|
|
2431
|
+
toString(replaceNode) +
|
|
2432
|
+
" to " +
|
|
2433
|
+
node.range.source.normalizedPath +
|
|
2434
|
+
"\n");
|
|
2435
|
+
}
|
|
2436
|
+
if (!deserializeArrayInto_SWARImport &&
|
|
2437
|
+
!hasLocaldeserializeArrayInto_SWAR) {
|
|
2438
|
+
const replaceNode = Node.createImportStatement([
|
|
2439
|
+
Node.createImportDeclaration(Node.createIdentifierExpression("deserializeArrayInto_SWAR", node.range, false), null, node.range),
|
|
2440
|
+
], Node.createStringLiteralExpression(path.posix.join(baseRel, "assembly", "deserialize", "swar", "array"), node.range), node.range);
|
|
1800
2441
|
node.range.source.statements.unshift(replaceNode);
|
|
1801
2442
|
if (DEBUG > 0)
|
|
1802
|
-
console.log("Added import: " +
|
|
2443
|
+
console.log("Added import: " +
|
|
2444
|
+
toString(replaceNode) +
|
|
2445
|
+
" to " +
|
|
2446
|
+
node.range.source.normalizedPath +
|
|
2447
|
+
"\n");
|
|
1803
2448
|
}
|
|
1804
2449
|
if (!deserializeMapFieldImport && !hasLocaldeserializeMapField) {
|
|
1805
|
-
const replaceNode = Node.createImportStatement([
|
|
2450
|
+
const replaceNode = Node.createImportStatement([
|
|
2451
|
+
Node.createImportDeclaration(Node.createIdentifierExpression("deserializeMapField", node.range, false), null, node.range),
|
|
2452
|
+
], Node.createStringLiteralExpression(path.posix.join(baseRel, "assembly", "deserialize", "simple", "map"), node.range), node.range);
|
|
1806
2453
|
node.range.source.statements.unshift(replaceNode);
|
|
1807
2454
|
if (DEBUG > 0)
|
|
1808
|
-
console.log("Added import: " +
|
|
2455
|
+
console.log("Added import: " +
|
|
2456
|
+
toString(replaceNode) +
|
|
2457
|
+
" to " +
|
|
2458
|
+
node.range.source.normalizedPath +
|
|
2459
|
+
"\n");
|
|
1809
2460
|
}
|
|
1810
2461
|
if (!deserializeMapIntoImport && !hasLocaldeserializeMapInto) {
|
|
1811
|
-
const replaceNode = Node.createImportStatement([
|
|
2462
|
+
const replaceNode = Node.createImportStatement([
|
|
2463
|
+
Node.createImportDeclaration(Node.createIdentifierExpression("deserializeMapInto", node.range, false), null, node.range),
|
|
2464
|
+
], Node.createStringLiteralExpression(path.posix.join(baseRel, "assembly", "deserialize", "simple", "map"), node.range), node.range);
|
|
1812
2465
|
node.range.source.statements.unshift(replaceNode);
|
|
1813
2466
|
if (DEBUG > 0)
|
|
1814
|
-
console.log("Added import: " +
|
|
2467
|
+
console.log("Added import: " +
|
|
2468
|
+
toString(replaceNode) +
|
|
2469
|
+
" to " +
|
|
2470
|
+
node.range.source.normalizedPath +
|
|
2471
|
+
"\n");
|
|
1815
2472
|
}
|
|
1816
2473
|
if (!deserializeSetFieldImport && !hasLocaldeserializeSetField) {
|
|
1817
|
-
const replaceNode = Node.createImportStatement([
|
|
2474
|
+
const replaceNode = Node.createImportStatement([
|
|
2475
|
+
Node.createImportDeclaration(Node.createIdentifierExpression("deserializeSetField", node.range, false), null, node.range),
|
|
2476
|
+
], Node.createStringLiteralExpression(path.posix.join(baseRel, "assembly", "deserialize", "simple", "set"), node.range), node.range);
|
|
1818
2477
|
node.range.source.statements.unshift(replaceNode);
|
|
1819
2478
|
if (DEBUG > 0)
|
|
1820
|
-
console.log("Added import: " +
|
|
2479
|
+
console.log("Added import: " +
|
|
2480
|
+
toString(replaceNode) +
|
|
2481
|
+
" to " +
|
|
2482
|
+
node.range.source.normalizedPath +
|
|
2483
|
+
"\n");
|
|
1821
2484
|
}
|
|
1822
2485
|
if (!deserializeSetIntoImport && !hasLocaldeserializeSetInto) {
|
|
1823
|
-
const replaceNode = Node.createImportStatement([
|
|
2486
|
+
const replaceNode = Node.createImportStatement([
|
|
2487
|
+
Node.createImportDeclaration(Node.createIdentifierExpression("deserializeSetInto", node.range, false), null, node.range),
|
|
2488
|
+
], Node.createStringLiteralExpression(path.posix.join(baseRel, "assembly", "deserialize", "simple", "set"), node.range), node.range);
|
|
1824
2489
|
node.range.source.statements.unshift(replaceNode);
|
|
1825
2490
|
if (DEBUG > 0)
|
|
1826
|
-
console.log("Added import: " +
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
2491
|
+
console.log("Added import: " +
|
|
2492
|
+
toString(replaceNode) +
|
|
2493
|
+
" to " +
|
|
2494
|
+
node.range.source.normalizedPath +
|
|
2495
|
+
"\n");
|
|
2496
|
+
}
|
|
2497
|
+
if (!deserializeStaticArrayFieldImport &&
|
|
2498
|
+
!hasLocaldeserializeStaticArrayField) {
|
|
2499
|
+
const replaceNode = Node.createImportStatement([
|
|
2500
|
+
Node.createImportDeclaration(Node.createIdentifierExpression("deserializeStaticArrayField", node.range, false), null, node.range),
|
|
2501
|
+
], Node.createStringLiteralExpression(path.posix.join(baseRel, "assembly", "deserialize", "simple", "staticarray"), node.range), node.range);
|
|
1830
2502
|
node.range.source.statements.unshift(replaceNode);
|
|
1831
2503
|
if (DEBUG > 0)
|
|
1832
|
-
console.log("Added import: " +
|
|
2504
|
+
console.log("Added import: " +
|
|
2505
|
+
toString(replaceNode) +
|
|
2506
|
+
" to " +
|
|
2507
|
+
node.range.source.normalizedPath +
|
|
2508
|
+
"\n");
|
|
1833
2509
|
}
|
|
1834
2510
|
const codegenMode = getCodegenMode(this.program);
|
|
1835
|
-
if (codegenMode !== JSONMode.SIMD &&
|
|
1836
|
-
|
|
2511
|
+
if (codegenMode !== JSONMode.SIMD &&
|
|
2512
|
+
!deserializeStringFieldSWARImport &&
|
|
2513
|
+
!hasLocalDeserializeStringFieldSWAR) {
|
|
2514
|
+
const replaceNode = Node.createImportStatement([
|
|
2515
|
+
Node.createImportDeclaration(Node.createIdentifierExpression("deserializeStringField_SWAR", node.range, false), null, node.range),
|
|
2516
|
+
], Node.createStringLiteralExpression(path.posix.join(baseRel, "assembly", "deserialize", "swar", "string"), node.range), node.range);
|
|
1837
2517
|
node.range.source.statements.unshift(replaceNode);
|
|
1838
2518
|
if (DEBUG > 0)
|
|
1839
|
-
console.log("Added import: " +
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
2519
|
+
console.log("Added import: " +
|
|
2520
|
+
toString(replaceNode) +
|
|
2521
|
+
" to " +
|
|
2522
|
+
node.range.source.normalizedPath +
|
|
2523
|
+
"\n");
|
|
2524
|
+
}
|
|
2525
|
+
if (codegenMode === JSONMode.SIMD &&
|
|
2526
|
+
!deserializeStringFieldSIMDImport &&
|
|
2527
|
+
!hasLocalDeserializeStringFieldSIMD) {
|
|
2528
|
+
const replaceNode = Node.createImportStatement([
|
|
2529
|
+
Node.createImportDeclaration(Node.createIdentifierExpression("deserializeStringField_SIMD", node.range, false), null, node.range),
|
|
2530
|
+
], Node.createStringLiteralExpression(path.posix.join(baseRel, "assembly", "deserialize", "simd", "string"), node.range), node.range);
|
|
1843
2531
|
node.range.source.statements.unshift(replaceNode);
|
|
1844
2532
|
if (DEBUG > 0)
|
|
1845
|
-
console.log("Added import: " +
|
|
2533
|
+
console.log("Added import: " +
|
|
2534
|
+
toString(replaceNode) +
|
|
2535
|
+
" to " +
|
|
2536
|
+
node.range.source.normalizedPath +
|
|
2537
|
+
"\n");
|
|
1846
2538
|
}
|
|
1847
2539
|
}
|
|
1848
2540
|
getStores(data, simd = false) {
|
|
@@ -1855,19 +2547,39 @@ export class JSONTransform extends Visitor {
|
|
|
1855
2547
|
const name = "SIMD_" + (index == -1 ? this.simdStatements.length : index);
|
|
1856
2548
|
if (index == -1)
|
|
1857
2549
|
this.simdStatements.push(`const ${name} = ${num};`);
|
|
1858
|
-
out.push("store<v128>(bs.offset, " +
|
|
2550
|
+
out.push("store<v128>(bs.offset, " +
|
|
2551
|
+
name +
|
|
2552
|
+
", " +
|
|
2553
|
+
offset +
|
|
2554
|
+
"); // " +
|
|
2555
|
+
data.slice(offset >> 1, (offset >> 1) + 8));
|
|
1859
2556
|
offset += 16;
|
|
1860
2557
|
}
|
|
1861
2558
|
if (size == "u64") {
|
|
1862
|
-
out.push("store<u64>(bs.offset, " +
|
|
2559
|
+
out.push("store<u64>(bs.offset, " +
|
|
2560
|
+
num +
|
|
2561
|
+
", " +
|
|
2562
|
+
offset +
|
|
2563
|
+
"); // " +
|
|
2564
|
+
data.slice(offset >> 1, (offset >> 1) + 4));
|
|
1863
2565
|
offset += 8;
|
|
1864
2566
|
}
|
|
1865
2567
|
else if (size == "u32") {
|
|
1866
|
-
out.push("store<u32>(bs.offset, " +
|
|
2568
|
+
out.push("store<u32>(bs.offset, " +
|
|
2569
|
+
num +
|
|
2570
|
+
", " +
|
|
2571
|
+
offset +
|
|
2572
|
+
"); // " +
|
|
2573
|
+
data.slice(offset >> 1, (offset >> 1) + 2));
|
|
1867
2574
|
offset += 4;
|
|
1868
2575
|
}
|
|
1869
2576
|
else if (size == "u16") {
|
|
1870
|
-
out.push("store<u16>(bs.offset, " +
|
|
2577
|
+
out.push("store<u16>(bs.offset, " +
|
|
2578
|
+
num +
|
|
2579
|
+
", " +
|
|
2580
|
+
offset +
|
|
2581
|
+
"); // " +
|
|
2582
|
+
data.slice(offset >> 1, (offset >> 1) + 1));
|
|
1871
2583
|
offset += 2;
|
|
1872
2584
|
}
|
|
1873
2585
|
}
|
|
@@ -1875,7 +2587,31 @@ export class JSONTransform extends Visitor {
|
|
|
1875
2587
|
return out;
|
|
1876
2588
|
}
|
|
1877
2589
|
isValidType(type, node) {
|
|
1878
|
-
const validTypes = [
|
|
2590
|
+
const validTypes = [
|
|
2591
|
+
"string",
|
|
2592
|
+
"u8",
|
|
2593
|
+
"i8",
|
|
2594
|
+
"u16",
|
|
2595
|
+
"i16",
|
|
2596
|
+
"u32",
|
|
2597
|
+
"i32",
|
|
2598
|
+
"u64",
|
|
2599
|
+
"i64",
|
|
2600
|
+
"f32",
|
|
2601
|
+
"f64",
|
|
2602
|
+
"bool",
|
|
2603
|
+
"boolean",
|
|
2604
|
+
"Date",
|
|
2605
|
+
"JSON.Value",
|
|
2606
|
+
"JSON.Obj",
|
|
2607
|
+
"JSON.Raw",
|
|
2608
|
+
"Value",
|
|
2609
|
+
"Obj",
|
|
2610
|
+
"Raw",
|
|
2611
|
+
...this.schemas
|
|
2612
|
+
.get(this.schema.node.range.source.internalPath)
|
|
2613
|
+
.map((v) => v.name),
|
|
2614
|
+
];
|
|
1879
2615
|
const baseTypes = ["Array", "StaticArray", "Map", "Set", "JSON.Box", "Box"];
|
|
1880
2616
|
if (node && node.isGeneric && node.typeParameters)
|
|
1881
2617
|
validTypes.push(...node.typeParameters.map((v) => v.name.text));
|
|
@@ -1885,7 +2621,8 @@ export class JSONTransform extends Visitor {
|
|
|
1885
2621
|
return this.isValidType(type.slice(0, type.length - 7), node);
|
|
1886
2622
|
}
|
|
1887
2623
|
if (type.includes("<"))
|
|
1888
|
-
return baseTypes.includes(type.slice(0, type.indexOf("<"))) &&
|
|
2624
|
+
return (baseTypes.includes(type.slice(0, type.indexOf("<"))) &&
|
|
2625
|
+
this.isValidType(type.slice(type.indexOf("<") + 1, type.lastIndexOf(">")), node));
|
|
1889
2626
|
if (validTypes.includes(type))
|
|
1890
2627
|
return true;
|
|
1891
2628
|
return false;
|
|
@@ -1899,7 +2636,9 @@ var JSONMode;
|
|
|
1899
2636
|
})(JSONMode || (JSONMode = {}));
|
|
1900
2637
|
let MODE = JSONMode.SWAR;
|
|
1901
2638
|
function getCodegenMode(program) {
|
|
1902
|
-
let mode = program.options.hasFeature(16)
|
|
2639
|
+
let mode = program.options.hasFeature(16)
|
|
2640
|
+
? JSONMode.SIMD
|
|
2641
|
+
: JSONMode.SWAR;
|
|
1903
2642
|
if (process.env["JSON_MODE"]) {
|
|
1904
2643
|
switch (process.env["JSON_MODE"].toLowerCase().trim()) {
|
|
1905
2644
|
case "simd":
|
|
@@ -1946,7 +2685,10 @@ export default class Transformer extends Transform {
|
|
|
1946
2685
|
const sources = parser.sources
|
|
1947
2686
|
.filter((source) => {
|
|
1948
2687
|
const p = source.internalPath;
|
|
1949
|
-
if (p.startsWith("~lib/rt") ||
|
|
2688
|
+
if (p.startsWith("~lib/rt") ||
|
|
2689
|
+
p.startsWith("~lib/performance") ||
|
|
2690
|
+
p.startsWith("~lib/wasi_") ||
|
|
2691
|
+
p.startsWith("~lib/shared/")) {
|
|
1950
2692
|
return false;
|
|
1951
2693
|
}
|
|
1952
2694
|
return !isStdlib(source);
|
|
@@ -2013,10 +2755,15 @@ function toU32(data, offset = 0) {
|
|
|
2013
2755
|
return (data.charCodeAt(offset + 1) << 16) | data.charCodeAt(offset + 0);
|
|
2014
2756
|
}
|
|
2015
2757
|
function toU48(data, offset = 0) {
|
|
2016
|
-
return (BigInt(data.charCodeAt(offset + 2)) << 32n) |
|
|
2758
|
+
return ((BigInt(data.charCodeAt(offset + 2)) << 32n) |
|
|
2759
|
+
(BigInt(data.charCodeAt(offset + 1)) << 16n) |
|
|
2760
|
+
BigInt(data.charCodeAt(offset + 0)));
|
|
2017
2761
|
}
|
|
2018
2762
|
function toU64(data, offset = 0) {
|
|
2019
|
-
return (BigInt(data.charCodeAt(offset + 3)) << 48n) |
|
|
2763
|
+
return ((BigInt(data.charCodeAt(offset + 3)) << 48n) |
|
|
2764
|
+
(BigInt(data.charCodeAt(offset + 2)) << 32n) |
|
|
2765
|
+
(BigInt(data.charCodeAt(offset + 1)) << 16n) |
|
|
2766
|
+
BigInt(data.charCodeAt(offset + 0)));
|
|
2020
2767
|
}
|
|
2021
2768
|
function toMemCDecl(n, indent) {
|
|
2022
2769
|
let out = "";
|
|
@@ -2059,12 +2806,34 @@ function strToNum(data, simd = false, offset = 0) {
|
|
|
2059
2806
|
const out = [];
|
|
2060
2807
|
let n = data.length;
|
|
2061
2808
|
while (n >= 8 && simd) {
|
|
2062
|
-
out.push([
|
|
2809
|
+
out.push([
|
|
2810
|
+
"v128",
|
|
2811
|
+
"i16x8(" +
|
|
2812
|
+
data.charCodeAt(offset + 0) +
|
|
2813
|
+
", " +
|
|
2814
|
+
data.charCodeAt(offset + 1) +
|
|
2815
|
+
", " +
|
|
2816
|
+
data.charCodeAt(offset + 2) +
|
|
2817
|
+
", " +
|
|
2818
|
+
data.charCodeAt(offset + 3) +
|
|
2819
|
+
", " +
|
|
2820
|
+
data.charCodeAt(offset + 4) +
|
|
2821
|
+
", " +
|
|
2822
|
+
data.charCodeAt(offset + 5) +
|
|
2823
|
+
", " +
|
|
2824
|
+
data.charCodeAt(offset + 6) +
|
|
2825
|
+
", " +
|
|
2826
|
+
data.charCodeAt(offset + 7) +
|
|
2827
|
+
")",
|
|
2828
|
+
]);
|
|
2063
2829
|
offset += 8;
|
|
2064
2830
|
n -= 8;
|
|
2065
2831
|
}
|
|
2066
2832
|
while (n >= 4) {
|
|
2067
|
-
const value = (BigInt(data.charCodeAt(offset + 3)) << 48n) |
|
|
2833
|
+
const value = (BigInt(data.charCodeAt(offset + 3)) << 48n) |
|
|
2834
|
+
(BigInt(data.charCodeAt(offset + 2)) << 32n) |
|
|
2835
|
+
(BigInt(data.charCodeAt(offset + 1)) << 16n) |
|
|
2836
|
+
BigInt(data.charCodeAt(offset + 0));
|
|
2068
2837
|
out.push(["u64", value.toString()]);
|
|
2069
2838
|
offset += 4;
|
|
2070
2839
|
n -= 4;
|
|
@@ -2140,7 +2909,12 @@ function estimatedSerializedByteSize(type, source, parser) {
|
|
|
2140
2909
|
else if (isArray(baseType) || baseType.startsWith("Map<")) {
|
|
2141
2910
|
estimated = 4;
|
|
2142
2911
|
}
|
|
2143
|
-
else if (baseType == "JSON.Obj" ||
|
|
2912
|
+
else if (baseType == "JSON.Obj" ||
|
|
2913
|
+
baseType == "Obj" ||
|
|
2914
|
+
baseType == "JSON.Raw" ||
|
|
2915
|
+
baseType == "Raw" ||
|
|
2916
|
+
baseType == "JSON.Value" ||
|
|
2917
|
+
baseType == "Value") {
|
|
2144
2918
|
estimated = 4;
|
|
2145
2919
|
}
|
|
2146
2920
|
else if (baseType == "ArrayBuffer" || needsReferenceLoad(baseType)) {
|
|
@@ -2156,7 +2930,20 @@ function estimatedSerializedByteSize(type, source, parser) {
|
|
|
2156
2930
|
return estimated;
|
|
2157
2931
|
}
|
|
2158
2932
|
function isPrimitive(type) {
|
|
2159
|
-
const primitiveTypes = [
|
|
2933
|
+
const primitiveTypes = [
|
|
2934
|
+
"u8",
|
|
2935
|
+
"u16",
|
|
2936
|
+
"u32",
|
|
2937
|
+
"u64",
|
|
2938
|
+
"i8",
|
|
2939
|
+
"i16",
|
|
2940
|
+
"i32",
|
|
2941
|
+
"i64",
|
|
2942
|
+
"f32",
|
|
2943
|
+
"f64",
|
|
2944
|
+
"bool",
|
|
2945
|
+
"boolean",
|
|
2946
|
+
];
|
|
2160
2947
|
return primitiveTypes.some((v) => type.startsWith(v));
|
|
2161
2948
|
}
|
|
2162
2949
|
function isBoolean(type) {
|
|
@@ -2166,10 +2953,12 @@ function isString(type) {
|
|
|
2166
2953
|
return stripNull(type) == "string" || stripNull(type) == "String";
|
|
2167
2954
|
}
|
|
2168
2955
|
function isArray(type) {
|
|
2169
|
-
return type.startsWith("Array<") ||
|
|
2956
|
+
return (type.startsWith("Array<") ||
|
|
2957
|
+
type.startsWith("Set<") ||
|
|
2958
|
+
type.startsWith("StaticArray<"));
|
|
2170
2959
|
}
|
|
2171
2960
|
function isEnum(type, source, parser) {
|
|
2172
|
-
return source.getEnum(type) != null || source.getImportedEnum(type, parser) != null;
|
|
2961
|
+
return (source.getEnum(type) != null || source.getImportedEnum(type, parser) != null);
|
|
2173
2962
|
}
|
|
2174
2963
|
export function stripNull(type) {
|
|
2175
2964
|
if (type.endsWith(" | null")) {
|