json-as 1.3.9 → 1.5.0
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 +60 -19
- package/README.md +120 -21
- package/assembly/custom/chars.ts +39 -78
- package/assembly/deserialize/index/arbitrary.ts +28 -10
- package/assembly/deserialize/index/float.ts +2 -4
- package/assembly/deserialize/index/integer.ts +2 -4
- package/assembly/deserialize/index/object.ts +6 -1
- package/assembly/deserialize/index/string.ts +2 -7
- package/assembly/deserialize/index/unsigned.ts +2 -4
- package/assembly/deserialize/naive/array/arbitrary.ts +3 -136
- package/assembly/deserialize/naive/array/array.ts +30 -1
- package/assembly/deserialize/naive/array/integer.ts +2 -7
- package/assembly/deserialize/naive/array/map.ts +10 -14
- package/assembly/deserialize/naive/array/object.ts +10 -14
- package/assembly/deserialize/naive/array/struct.ts +19 -1
- package/assembly/deserialize/naive/bool.ts +1 -5
- package/assembly/deserialize/naive/date.ts +1 -2
- package/assembly/deserialize/naive/float.ts +4 -11
- package/assembly/deserialize/naive/integer.ts +2 -4
- package/assembly/deserialize/naive/map.ts +42 -205
- package/assembly/deserialize/naive/object.ts +291 -174
- package/assembly/deserialize/naive/raw.ts +1 -5
- package/assembly/deserialize/naive/set.ts +3 -6
- package/assembly/deserialize/naive/staticarray.ts +2 -4
- package/assembly/deserialize/naive/string.ts +68 -24
- package/assembly/deserialize/naive/typedarray.ts +1 -2
- package/assembly/deserialize/naive/unsigned.ts +2 -4
- package/assembly/deserialize/simd/array/integer.ts +5 -13
- package/assembly/deserialize/simd/float.ts +5 -12
- package/assembly/deserialize/simd/integer.ts +6 -15
- package/assembly/deserialize/simd/string.ts +21 -43
- package/assembly/deserialize/swar/array/arbitrary.ts +1 -2
- package/assembly/deserialize/swar/array/array.ts +2 -4
- package/assembly/deserialize/swar/array/bool.ts +2 -4
- package/assembly/deserialize/swar/array/box.ts +1 -2
- package/assembly/deserialize/swar/array/float.ts +8 -21
- package/assembly/deserialize/swar/array/generic.ts +2 -4
- package/assembly/deserialize/swar/array/integer.ts +13 -27
- package/assembly/deserialize/swar/array/map.ts +1 -2
- package/assembly/deserialize/swar/array/object.ts +2 -4
- package/assembly/deserialize/swar/array/raw.ts +1 -2
- package/assembly/deserialize/swar/array/shared.ts +9 -21
- package/assembly/deserialize/swar/array/string.ts +4 -10
- package/assembly/deserialize/swar/array/struct.ts +3 -9
- package/assembly/deserialize/swar/array.ts +1 -3
- package/assembly/deserialize/swar/float.ts +7 -17
- package/assembly/deserialize/swar/integer.ts +6 -15
- package/assembly/deserialize/swar/string.ts +40 -54
- package/assembly/deserialize/swar/typedarray.ts +4 -4
- package/assembly/index.d.ts +259 -21
- package/assembly/index.ts +1704 -266
- package/assembly/serialize/index/arbitrary.ts +70 -4
- package/assembly/serialize/index/jsonarray.ts +51 -0
- package/assembly/serialize/index/object.ts +39 -14
- package/assembly/serialize/index/string.ts +1 -2
- package/assembly/serialize/index/typedarray.ts +1 -2
- package/assembly/serialize/index.ts +1 -0
- package/assembly/serialize/naive/array.ts +23 -34
- package/assembly/serialize/naive/bool.ts +0 -1
- package/assembly/serialize/naive/float.ts +16 -25
- package/assembly/serialize/naive/integer.ts +1 -5
- package/assembly/serialize/naive/raw.ts +1 -2
- package/assembly/serialize/naive/set.ts +0 -4
- package/assembly/serialize/naive/staticarray.ts +0 -5
- package/assembly/serialize/naive/string.ts +11 -7
- package/assembly/serialize/naive/typedarray.ts +0 -6
- package/assembly/serialize/simd/string.ts +1 -3
- package/assembly/serialize/swar/string.ts +2 -4
- package/assembly/util/atoi-fast.ts +4 -14
- package/assembly/util/atoi.ts +1 -2
- package/assembly/util/bytes.ts +1 -2
- package/assembly/util/idofd.ts +1 -2
- package/assembly/util/isSpace.ts +1 -2
- package/assembly/util/itoa-fast.ts +9 -15
- package/assembly/util/nextPowerOf2.ts +1 -2
- package/assembly/util/parsefloat-fast.ts +4 -7
- package/assembly/util/ptrToStr.ts +1 -2
- package/assembly/util/scanValueEnd.ts +1 -2
- package/assembly/util/scanValueEndSimd.ts +198 -0
- package/assembly/util/scanValueEndSwar.ts +184 -0
- package/assembly/util/scientific.ts +8 -14
- package/assembly/util/simd-int.ts +4 -8
- package/assembly/util/snp.ts +2 -7
- package/assembly/util/stringScan.ts +2 -4
- package/assembly/util/swar-int.ts +8 -16
- package/assembly/util/swar.ts +2 -4
- package/lib/as-bs.ts +57 -42
- package/package.json +27 -10
- package/transform/lib/builder.d.ts +0 -1
- package/transform/lib/builder.js +0 -1
- package/transform/lib/index.d.ts +0 -1
- package/transform/lib/index.js +617 -326
- package/transform/lib/linkers/alias.d.ts +0 -1
- package/transform/lib/linkers/alias.js +0 -1
- package/transform/lib/linkers/custom.d.ts +0 -1
- package/transform/lib/linkers/custom.js +0 -1
- package/transform/lib/linkers/imports.d.ts +0 -1
- package/transform/lib/linkers/imports.js +0 -1
- package/transform/lib/types.d.ts +4 -2
- package/transform/lib/types.js +5 -1
- package/transform/lib/util.d.ts +0 -1
- package/transform/lib/util.js +0 -1
- package/transform/lib/visitor.d.ts +0 -1
- package/transform/lib/visitor.js +0 -1
- package/assembly/util/dragonbox-cache.ts +0 -445
- package/assembly/util/dragonbox.ts +0 -660
- package/transform/lib/builder.d.ts.map +0 -1
- package/transform/lib/builder.js.map +0 -1
- package/transform/lib/index.d.ts.map +0 -1
- package/transform/lib/index.js.map +0 -1
- package/transform/lib/linkers/alias.d.ts.map +0 -1
- package/transform/lib/linkers/alias.js.map +0 -1
- package/transform/lib/linkers/custom.d.ts.map +0 -1
- package/transform/lib/linkers/custom.js.map +0 -1
- package/transform/lib/linkers/imports.d.ts.map +0 -1
- package/transform/lib/linkers/imports.js.map +0 -1
- package/transform/lib/types.d.ts.map +0 -1
- package/transform/lib/types.js.map +0 -1
- package/transform/lib/util.d.ts.map +0 -1
- package/transform/lib/util.js.map +0 -1
- package/transform/lib/visitor.d.ts.map +0 -1
- package/transform/lib/visitor.js.map +0 -1
package/transform/lib/index.js
CHANGED
|
@@ -301,10 +301,135 @@ export class JSONTransform extends Visitor {
|
|
|
301
301
|
return;
|
|
302
302
|
if (!this.schemas.has(source.internalPath))
|
|
303
303
|
this.schemas.set(source.internalPath, []);
|
|
304
|
+
const lazyInner = new Map();
|
|
305
|
+
const lazyMode = classLazyMode(node);
|
|
306
|
+
const hasCustomSerde = node.members.some((m) => m.kind === NodeKind.MethodDeclaration &&
|
|
307
|
+
(m.decorators?.some((d) => {
|
|
308
|
+
const t = d.name.text.toLowerCase();
|
|
309
|
+
return t === "serializer" || t === "deserializer";
|
|
310
|
+
}) ??
|
|
311
|
+
false));
|
|
312
|
+
let __hasLazy = false;
|
|
313
|
+
const __lazyValInits = new Map();
|
|
314
|
+
for (let i = node.members.length - 1; i >= 0; i--) {
|
|
315
|
+
const fd = node.members[i];
|
|
316
|
+
if (fd.kind !== NodeKind.FieldDeclaration ||
|
|
317
|
+
fd.is(32) ||
|
|
318
|
+
fd.is(512) ||
|
|
319
|
+
fd.is(1024) ||
|
|
320
|
+
!fd.type)
|
|
321
|
+
continue;
|
|
322
|
+
const written = toString(fd.type).trim();
|
|
323
|
+
const decos = fd.decorators;
|
|
324
|
+
const hasDeco = (name) => decos?.some((d) => d.name.text === name) ??
|
|
325
|
+
false;
|
|
326
|
+
let inner = lazyWrapperInner(fd.type);
|
|
327
|
+
if (inner === null) {
|
|
328
|
+
if (hasDeco("lazy")) {
|
|
329
|
+
inner = written;
|
|
330
|
+
}
|
|
331
|
+
else if (lazyMode !== "none" &&
|
|
332
|
+
!hasDeco("eager") &&
|
|
333
|
+
!hasDeco("omit")) {
|
|
334
|
+
if (lazyMode === "all")
|
|
335
|
+
inner = written;
|
|
336
|
+
else if (lazyAutoCost(this.resolveType(written, source), source, this.parser) >= LAZY_AUTO_THRESHOLD)
|
|
337
|
+
inner = written;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
if (inner === null)
|
|
341
|
+
continue;
|
|
342
|
+
if (hasCustomSerde)
|
|
343
|
+
throwError("Lazy fields (@lazy / JSON.Lazy<T> / @json({ lazy })) are not supported " +
|
|
344
|
+
"on a class with a custom @serializer/@deserializer - the custom methods " +
|
|
345
|
+
"bypass the generated (de)serializer, so the deferred slot is never filled. " +
|
|
346
|
+
"Remove the lazy marker or the custom (de)serializer.", fd.range);
|
|
347
|
+
const fname = fd.name.text;
|
|
348
|
+
const key = JSON.stringify(fname);
|
|
349
|
+
const T = inner;
|
|
350
|
+
const baseT = stripNull(T);
|
|
351
|
+
const storesScalar = isPrimitive(baseT) || isEnum(baseT, source, this.parser);
|
|
352
|
+
const valueType = storesScalar || baseT != T ? T : `${T} | null`;
|
|
353
|
+
const valueDefault = isBoolean(baseT)
|
|
354
|
+
? "false"
|
|
355
|
+
: storesScalar
|
|
356
|
+
? "0"
|
|
357
|
+
: "null";
|
|
358
|
+
const fdInit = fd.initializer;
|
|
359
|
+
const fieldDefault = fdInit ? toString(fdInit) : null;
|
|
360
|
+
const refDefault = fieldDefault != null
|
|
361
|
+
? fieldDefault
|
|
362
|
+
: !storesScalar && baseT == T && !baseT.startsWith("StaticArray<")
|
|
363
|
+
? baseT == "string" || baseT == "String"
|
|
364
|
+
? '""'
|
|
365
|
+
: `new ${baseT}()`
|
|
366
|
+
: null;
|
|
367
|
+
__hasLazy = true;
|
|
368
|
+
const omitIfDeco = decos?.find((d) => d.name.text === "omitif");
|
|
369
|
+
lazyInner.set("__" + fname + "_lz", {
|
|
370
|
+
inner: T,
|
|
371
|
+
valueType,
|
|
372
|
+
omitNull: hasDeco("omitnull"),
|
|
373
|
+
omitIf: omitIfDeco?.args?.[0] ?? null,
|
|
374
|
+
});
|
|
375
|
+
const packScalar = baseT === "i8" ||
|
|
376
|
+
baseT === "u8" ||
|
|
377
|
+
baseT === "i16" ||
|
|
378
|
+
baseT === "u16" ||
|
|
379
|
+
baseT === "i32" ||
|
|
380
|
+
baseT === "u32" ||
|
|
381
|
+
baseT === "bool" ||
|
|
382
|
+
baseT === "boolean" ||
|
|
383
|
+
baseT === "f32";
|
|
384
|
+
const encVal = (v) => baseT === "f32"
|
|
385
|
+
? `(<u64>reinterpret<u32>(${v}))`
|
|
386
|
+
: `(<u64><u32>(${v}))`;
|
|
387
|
+
const decSlot = (lz) => baseT === "f32"
|
|
388
|
+
? `reinterpret<f32>(<u32>(${lz}))`
|
|
389
|
+
: `(<${T}>(<u32>(${lz})))`;
|
|
390
|
+
const lowered = (packScalar
|
|
391
|
+
? [
|
|
392
|
+
`@alias(${key}) private __${fname}_lz: u64 = ${fieldDefault != null
|
|
393
|
+
? `(((<u64>0xffffffff) << 32) | ${encVal(`<${T}>(${fieldDefault})`)})`
|
|
394
|
+
: "0"};`,
|
|
395
|
+
`get ${fname}(): ${T} {\n` +
|
|
396
|
+
` const __lz = this.__${fname}_lz;\n` +
|
|
397
|
+
` if ((__lz >>> 32) == 0xffffffff) return ${decSlot("__lz")};\n` +
|
|
398
|
+
` if (__lz != 0) {\n` +
|
|
399
|
+
` const __v = JSON.__deserialize<${T}>(<usize>(__lz >>> 32), <usize>(<u32>__lz));\n` +
|
|
400
|
+
` this.__${fname}_lz = ((<u64>0xffffffff) << 32) | ${encVal("__v")};\n` +
|
|
401
|
+
` return __v;\n` +
|
|
402
|
+
` }\n` +
|
|
403
|
+
` return ${valueDefault};\n}`,
|
|
404
|
+
`set ${fname}(value: ${T}) {\n` +
|
|
405
|
+
` this.__${fname}_lz = ((<u64>0xffffffff) << 32) | ${encVal("value")};\n}`,
|
|
406
|
+
]
|
|
407
|
+
: [
|
|
408
|
+
`@alias(${key}) private __${fname}_lz: u64 = ${refDefault != null ? "u64.MAX_VALUE" : "0"};`,
|
|
409
|
+
`private __${fname}_val: ${valueType} = ${refDefault ?? valueDefault};`,
|
|
410
|
+
`get ${fname}(): ${T} {\n` +
|
|
411
|
+
` const __lz = this.__${fname}_lz;\n` +
|
|
412
|
+
` if (__lz != 0 && __lz != u64.MAX_VALUE) {\n` +
|
|
413
|
+
` this.__${fname}_val = JSON.__deserialize<${T}>(<usize>(__lz >>> 32), <usize>(<u32>__lz));\n` +
|
|
414
|
+
` this.__${fname}_lz = u64.MAX_VALUE;\n` +
|
|
415
|
+
` }\n` +
|
|
416
|
+
` return this.__${fname}_val as ${T};\n}`,
|
|
417
|
+
`set ${fname}(value: ${T}) {\n` +
|
|
418
|
+
` this.__${fname}_val = value;\n` +
|
|
419
|
+
` this.__${fname}_lz = u64.MAX_VALUE;\n}`,
|
|
420
|
+
]).map((src) => SimpleParser.parseClassMember(src, node));
|
|
421
|
+
node.members.splice(i, 1, ...lowered);
|
|
422
|
+
if (!packScalar && refDefault != null) {
|
|
423
|
+
__lazyValInits.set(`__${fname}_lz`, ` store<${valueType}>(changetype<usize>(this), ${refDefault}, offsetof<this>(${JSON.stringify(`__${fname}_val`)}));\n`);
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
if (__hasLazy) {
|
|
427
|
+
node.members.push(SimpleParser.parseClassMember(`private __src: string = "";`, node), SimpleParser.parseClassMember(`__SET_SRC(s: string): void { this.__src = s; }`, node));
|
|
428
|
+
}
|
|
304
429
|
const members = [
|
|
305
430
|
...node.members.filter((v) => v.kind === NodeKind.FieldDeclaration &&
|
|
306
431
|
!v.is(32) &&
|
|
307
|
-
!v.is(512) &&
|
|
432
|
+
(!v.is(512) || lazyInner.has(v.name.text)) &&
|
|
308
433
|
!v.is(1024) &&
|
|
309
434
|
!v.decorators?.some((decorator) => decorator.name.text === "omit")),
|
|
310
435
|
];
|
|
@@ -455,7 +580,7 @@ export class JSONTransform extends Visitor {
|
|
|
455
580
|
else if (isString(type) || isPrimitive(type)) {
|
|
456
581
|
return types;
|
|
457
582
|
}
|
|
458
|
-
else if (["JSON.Box", "JSON.Obj", "JSON.Value", "JSON.Raw"].includes(type)) {
|
|
583
|
+
else if (["JSON.Box", "JSON.Obj", "JSON.Arr", "JSON.Value", "JSON.Raw"].includes(type)) {
|
|
459
584
|
return types;
|
|
460
585
|
}
|
|
461
586
|
else if (node.isGeneric &&
|
|
@@ -549,12 +674,11 @@ export class JSONTransform extends Visitor {
|
|
|
549
674
|
this.schemas.get(source.internalPath).push(schema);
|
|
550
675
|
this.schema = schema;
|
|
551
676
|
this.visitedClasses.add(fullClassPath);
|
|
552
|
-
const
|
|
553
|
-
const requestedFastPath = USE_FAST_PATH && codegenMode !== JSONMode.NAIVE;
|
|
677
|
+
const requestedFastPath = USE_FAST_PATH;
|
|
554
678
|
let SERIALIZE = "__SERIALIZE(ptr: usize): void {\n";
|
|
555
|
-
let INITIALIZE = "
|
|
679
|
+
let INITIALIZE = " __INITIALIZE(): this {\n";
|
|
556
680
|
let DESERIALIZE = "__DESERIALIZE_SLOW<__JSON_T>(srcStart: usize, srcEnd: usize, out: __JSON_T): usize {\n";
|
|
557
|
-
let DESERIALIZE_FAST = "
|
|
681
|
+
let DESERIALIZE_FAST = "__DESERIALIZE_FAST<__JSON_T>(srcStart: usize, srcEnd: usize, out: __JSON_T): usize {\n";
|
|
558
682
|
let DESERIALIZE_CUSTOM = "";
|
|
559
683
|
let SERIALIZE_CUSTOM = "";
|
|
560
684
|
if (DEBUG > 0)
|
|
@@ -660,12 +784,9 @@ export class JSONTransform extends Visitor {
|
|
|
660
784
|
if (!deserializer.decorators.some((v) => v.name.text == "inline")) {
|
|
661
785
|
deserializer.decorators.push(Node.createDecorator(Node.createIdentifierExpression("inline", deserializer.range), null, deserializer.range));
|
|
662
786
|
}
|
|
787
|
+
DESERIALIZE_CUSTOM += " __DESERIALIZE_CUSTOM(data: string): this {\n";
|
|
663
788
|
DESERIALIZE_CUSTOM +=
|
|
664
|
-
"
|
|
665
|
-
DESERIALIZE_CUSTOM +=
|
|
666
|
-
" return inline.always(this." +
|
|
667
|
-
deserializer.name.text +
|
|
668
|
-
"(data));\n";
|
|
789
|
+
" return this." + deserializer.name.text + "(data);\n";
|
|
669
790
|
DESERIALIZE_CUSTOM += " }\n";
|
|
670
791
|
}
|
|
671
792
|
if (!members.length && !deserializers.length && !serializers.length) {
|
|
@@ -689,6 +810,19 @@ export class JSONTransform extends Visitor {
|
|
|
689
810
|
mem.node = member;
|
|
690
811
|
mem.byteSize = estimatedSerializedByteSize(mem.type, source, this.parser);
|
|
691
812
|
mem.custom = schema.deps.some((dep) => dep?.name == stripNull(type) && dep.custom);
|
|
813
|
+
const lzInner = lazyInner.get(name.text);
|
|
814
|
+
if (lzInner !== undefined) {
|
|
815
|
+
mem.flags.set(PropertyFlags.Lazy, null);
|
|
816
|
+
mem.lazyInner = lzInner.inner;
|
|
817
|
+
if (lzInner.omitNull) {
|
|
818
|
+
mem.flags.set(PropertyFlags.OmitNull, null);
|
|
819
|
+
this.schema.static = false;
|
|
820
|
+
}
|
|
821
|
+
if (lzInner.omitIf) {
|
|
822
|
+
mem.flags.set(PropertyFlags.OmitIf, lzInner.omitIf);
|
|
823
|
+
this.schema.static = false;
|
|
824
|
+
}
|
|
825
|
+
}
|
|
692
826
|
this.schema.byteSize += mem.byteSize;
|
|
693
827
|
if (member.decorators) {
|
|
694
828
|
for (const decorator of member.decorators) {
|
|
@@ -717,6 +851,10 @@ export class JSONTransform extends Visitor {
|
|
|
717
851
|
this.schema.static = false;
|
|
718
852
|
break;
|
|
719
853
|
}
|
|
854
|
+
case "optional": {
|
|
855
|
+
mem.flags.set(PropertyFlags.Optional, null);
|
|
856
|
+
break;
|
|
857
|
+
}
|
|
720
858
|
case "omitnull": {
|
|
721
859
|
if (isPrimitive(type)) {
|
|
722
860
|
throwError("@omitnull cannot be used on primitive types!", member.range);
|
|
@@ -733,11 +871,12 @@ export class JSONTransform extends Visitor {
|
|
|
733
871
|
}
|
|
734
872
|
this.schema.members.push(mem);
|
|
735
873
|
}
|
|
736
|
-
|
|
737
|
-
this.schema.members = sortMembers(this.schema.members);
|
|
874
|
+
this.schema.members = sortMembers(this.schema.members);
|
|
738
875
|
const hasOmitIfMembers = this.schema.members.some((v) => v.flags.has(PropertyFlags.OmitIf));
|
|
739
876
|
const hasOmitNullMembers = this.schema.members.some((v) => v.flags.has(PropertyFlags.OmitNull));
|
|
740
|
-
const
|
|
877
|
+
const hasExplicitOptionalMembers = this.schema.members.some((v) => v.flags.has(PropertyFlags.Optional));
|
|
878
|
+
const hasOptionalMembers = hasOmitIfMembers || hasOmitNullMembers || hasExplicitOptionalMembers;
|
|
879
|
+
const hasLazyMembers = this.schema.members.some((v) => v.flags.has(PropertyFlags.Lazy));
|
|
741
880
|
const supportsFastOptionalPath = requestedFastPath && hasOptionalMembers;
|
|
742
881
|
const hasTypeParams = !!node.typeParameters && node.typeParameters.length > 0;
|
|
743
882
|
const useFastPath = requestedFastPath &&
|
|
@@ -748,6 +887,9 @@ export class JSONTransform extends Visitor {
|
|
|
748
887
|
if (this.schema.members.some((v) => v.flags.has(PropertyFlags.OmitNull))) {
|
|
749
888
|
SERIALIZE += indent + "let block: usize = 0;\n";
|
|
750
889
|
}
|
|
890
|
+
if (hasOptionalMembers) {
|
|
891
|
+
SERIALIZE += indent + "let wrote = false;\n";
|
|
892
|
+
}
|
|
751
893
|
this.schema.byteSize += 2;
|
|
752
894
|
SERIALIZE += indent + "store<u16>(bs.offset, 123, 0); // {\n";
|
|
753
895
|
SERIALIZE += indent + "bs.offset += 2;\n";
|
|
@@ -755,18 +897,69 @@ export class JSONTransform extends Visitor {
|
|
|
755
897
|
const isPure = this.schema.static;
|
|
756
898
|
let isRegular = isPure;
|
|
757
899
|
let isFirst = true;
|
|
900
|
+
const serValue = (member, realName) => {
|
|
901
|
+
if (!member.flags.has(PropertyFlags.Lazy))
|
|
902
|
+
return getSerializeCall(member.type, realName);
|
|
903
|
+
const T = member.lazyInner;
|
|
904
|
+
const baseName = realName.slice(0, -3);
|
|
905
|
+
const baseT = stripNull(T);
|
|
906
|
+
const packScalar = baseT === "i8" ||
|
|
907
|
+
baseT === "u8" ||
|
|
908
|
+
baseT === "i16" ||
|
|
909
|
+
baseT === "u16" ||
|
|
910
|
+
baseT === "i32" ||
|
|
911
|
+
baseT === "u32" ||
|
|
912
|
+
baseT === "bool" ||
|
|
913
|
+
baseT === "boolean" ||
|
|
914
|
+
baseT === "f32";
|
|
915
|
+
if (packScalar) {
|
|
916
|
+
const dec = baseT === "f32"
|
|
917
|
+
? `reinterpret<f32>(<u32>(__s))`
|
|
918
|
+
: `(<${T}>(<u32>(__s)))`;
|
|
919
|
+
const def = baseT === "bool" || baseT === "boolean" ? "false" : "0";
|
|
920
|
+
return (`{\n` +
|
|
921
|
+
` const __s = this.${realName};\n` +
|
|
922
|
+
` if ((__s >>> 32) == 0xffffffff) {\n` +
|
|
923
|
+
` JSON.__serialize<${T}>(${dec});\n` +
|
|
924
|
+
` } else if (__s != 0) {\n` +
|
|
925
|
+
` const __hi = <usize>(__s >>> 32);\n` +
|
|
926
|
+
` const __len = (<usize>(<u32>__s)) - __hi;\n` +
|
|
927
|
+
` bs.ensureSize(<u32>__len);\n` +
|
|
928
|
+
` memory.copy(bs.offset, __hi, __len);\n` +
|
|
929
|
+
` bs.offset += __len;\n` +
|
|
930
|
+
` } else {\n` +
|
|
931
|
+
` JSON.__serialize<${T}>(${def});\n` +
|
|
932
|
+
` }\n` +
|
|
933
|
+
`}\n`);
|
|
934
|
+
}
|
|
935
|
+
return (`{\n` +
|
|
936
|
+
` const __s = this.${realName};\n` +
|
|
937
|
+
` if (__s == u64.MAX_VALUE) {\n` +
|
|
938
|
+
` JSON.__serialize<${T}>(this.${baseName}_val as ${T});\n` +
|
|
939
|
+
` } else if (__s != 0) {\n` +
|
|
940
|
+
` const __hi = <usize>(__s >>> 32);\n` +
|
|
941
|
+
` const __len = (<usize>(<u32>__s)) - __hi;\n` +
|
|
942
|
+
` bs.ensureSize(<u32>__len);\n` +
|
|
943
|
+
` memory.copy(bs.offset, __hi, __len);\n` +
|
|
944
|
+
` bs.offset += __len;\n` +
|
|
945
|
+
` } else {\n` +
|
|
946
|
+
(isPrimitive(baseT)
|
|
947
|
+
? ` JSON.__serialize<${T}>(0);\n`
|
|
948
|
+
: ` bs.ensureSize(8);\n` +
|
|
949
|
+
` store<u64>(bs.offset, 0x006c006c0075006e);\n` +
|
|
950
|
+
` bs.offset += 8;\n`) +
|
|
951
|
+
` }\n` +
|
|
952
|
+
`}\n`);
|
|
953
|
+
};
|
|
758
954
|
for (let i = 0; i < this.schema.members.length; i++) {
|
|
759
955
|
const member = this.schema.members[i];
|
|
760
956
|
const aliasName = JSON.stringify(member.alias || member.name);
|
|
761
957
|
const realName = member.name;
|
|
762
|
-
const isLast = i == this.schema.members.length - 1;
|
|
763
958
|
if (member.value) {
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
INITIALIZE += ` store<${member.type}>(changetype<usize>(this), ${member.value}, offsetof<this>(${JSON.stringify(member.name)}));\n`;
|
|
769
|
-
}
|
|
959
|
+
INITIALIZE += ` store<${member.type}>(changetype<usize>(this), ${member.value}, offsetof<this>(${JSON.stringify(member.name)}));\n`;
|
|
960
|
+
const __valInit = __lazyValInits.get(member.name);
|
|
961
|
+
if (__valInit)
|
|
962
|
+
INITIALIZE += __valInit;
|
|
770
963
|
}
|
|
771
964
|
else if (member.generic) {
|
|
772
965
|
INITIALIZE += ` if (isManaged<nonnull<${member.type}>>() || isReference<nonnull<${member.type}>>()) {\n`;
|
|
@@ -793,6 +986,9 @@ export class JSONTransform extends Visitor {
|
|
|
793
986
|
INITIALIZE += ` store<${member.type}>(changetype<usize>(this), "", offsetof<this>(${JSON.stringify(member.name)}));\n`;
|
|
794
987
|
}
|
|
795
988
|
}
|
|
989
|
+
else {
|
|
990
|
+
INITIALIZE += ` store<${member.type}>(changetype<usize>(this), null, offsetof<this>(${JSON.stringify(member.name)}));\n`;
|
|
991
|
+
}
|
|
796
992
|
const SIMD_ENABLED = this.program.options.hasFeature(16);
|
|
797
993
|
if (!isRegular &&
|
|
798
994
|
!member.flags.has(PropertyFlags.OmitIf) &&
|
|
@@ -801,40 +997,69 @@ export class JSONTransform extends Visitor {
|
|
|
801
997
|
if (isRegular && isPure) {
|
|
802
998
|
const keyPart = (isFirst ? "{" : ",") + aliasName + ":";
|
|
803
999
|
this.schema.byteSize += keyPart.length << 1;
|
|
1000
|
+
if (hasLazyMembers)
|
|
1001
|
+
SERIALIZE += indent + `bs.ensureSize(${keyPart.length << 1});\n`;
|
|
804
1002
|
SERIALIZE += this.getStores(keyPart, SIMD_ENABLED)
|
|
805
1003
|
.map((v) => indent + v + "\n")
|
|
806
1004
|
.join("");
|
|
807
|
-
SERIALIZE += indent +
|
|
1005
|
+
SERIALIZE += indent + serValue(member, realName);
|
|
808
1006
|
if (isFirst)
|
|
809
1007
|
isFirst = false;
|
|
810
1008
|
}
|
|
811
1009
|
else if (isRegular && !isPure) {
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
1010
|
+
if (isFirst && hasOptionalMembers) {
|
|
1011
|
+
const keyPart = aliasName + ":";
|
|
1012
|
+
this.schema.byteSize += 2 + (keyPart.length << 1);
|
|
1013
|
+
SERIALIZE +=
|
|
1014
|
+
indent +
|
|
1015
|
+
"if (wrote) { store<u16>(bs.offset, 44, 0); bs.offset += 2; } // ,\n";
|
|
1016
|
+
if (hasLazyMembers)
|
|
1017
|
+
SERIALIZE += indent + `bs.ensureSize(${keyPart.length << 1});\n`;
|
|
1018
|
+
SERIALIZE += this.getStores(keyPart, SIMD_ENABLED)
|
|
1019
|
+
.map((v) => indent + v + "\n")
|
|
1020
|
+
.join("");
|
|
1021
|
+
SERIALIZE += indent + serValue(member, realName);
|
|
1022
|
+
}
|
|
1023
|
+
else {
|
|
1024
|
+
const keyPart = (isFirst ? "" : ",") + aliasName + ":";
|
|
1025
|
+
this.schema.byteSize += keyPart.length << 1;
|
|
1026
|
+
if (hasLazyMembers)
|
|
1027
|
+
SERIALIZE += indent + `bs.ensureSize(${keyPart.length << 1});\n`;
|
|
1028
|
+
SERIALIZE += this.getStores(keyPart, SIMD_ENABLED)
|
|
1029
|
+
.map((v) => indent + v + "\n")
|
|
1030
|
+
.join("");
|
|
1031
|
+
SERIALIZE += indent + serValue(member, realName);
|
|
1032
|
+
}
|
|
818
1033
|
if (isFirst)
|
|
819
1034
|
isFirst = false;
|
|
820
1035
|
}
|
|
821
1036
|
else {
|
|
822
1037
|
if (member.flags.has(PropertyFlags.OmitNull)) {
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
1038
|
+
let omitNullCond;
|
|
1039
|
+
if (member.flags.has(PropertyFlags.Lazy)) {
|
|
1040
|
+
const base = realName.slice(0, -3);
|
|
1041
|
+
omitNullCond =
|
|
1042
|
+
`!JSON.__lazyIsNull(` +
|
|
1043
|
+
`load<usize>(ptr, offsetof<this>(${JSON.stringify(base + "_val")})), ` +
|
|
1044
|
+
`load<u64>(ptr, offsetof<this>(${JSON.stringify(realName)})))`;
|
|
1045
|
+
}
|
|
1046
|
+
else {
|
|
1047
|
+
omitNullCond = `(block = load<usize>(ptr, offsetof<this>(${JSON.stringify(realName)}))) !== 0`;
|
|
1048
|
+
}
|
|
1049
|
+
SERIALIZE += indent + `if (${omitNullCond}) {\n`;
|
|
826
1050
|
indentInc();
|
|
827
1051
|
const keyPart = aliasName + ":";
|
|
828
|
-
this.schema.byteSize += keyPart.length << 1;
|
|
1052
|
+
this.schema.byteSize += 2 + (keyPart.length << 1);
|
|
1053
|
+
SERIALIZE +=
|
|
1054
|
+
indent +
|
|
1055
|
+
"if (wrote) { store<u16>(bs.offset, 44, 0); bs.offset += 2; } // ,\n";
|
|
1056
|
+
if (hasLazyMembers)
|
|
1057
|
+
SERIALIZE += indent + `bs.ensureSize(${keyPart.length << 1});\n`;
|
|
829
1058
|
SERIALIZE += this.getStores(keyPart, SIMD_ENABLED)
|
|
830
1059
|
.map((v) => indent + v + "\n")
|
|
831
1060
|
.join("");
|
|
832
|
-
SERIALIZE += indent +
|
|
833
|
-
|
|
834
|
-
this.schema.byteSize += 2;
|
|
835
|
-
SERIALIZE += indent + `store<u16>(bs.offset, 44, 0); // ,\n`;
|
|
836
|
-
SERIALIZE += indent + `bs.offset += 2;\n`;
|
|
837
|
-
}
|
|
1061
|
+
SERIALIZE += indent + serValue(member, realName);
|
|
1062
|
+
SERIALIZE += indent + "wrote = true;\n";
|
|
838
1063
|
indentDec();
|
|
839
1064
|
this.schema.byteSize += 2;
|
|
840
1065
|
SERIALIZE += indent + `}\n`;
|
|
@@ -860,15 +1085,15 @@ export class JSONTransform extends Visitor {
|
|
|
860
1085
|
SERIALIZE += indent + `if (!(${rendered})) {\n`;
|
|
861
1086
|
}
|
|
862
1087
|
indentInc();
|
|
1088
|
+
this.schema.byteSize += 2;
|
|
1089
|
+
SERIALIZE +=
|
|
1090
|
+
indent +
|
|
1091
|
+
"if (wrote) { store<u16>(bs.offset, 44, 0); bs.offset += 2; } // ,\n";
|
|
863
1092
|
SERIALIZE += this.getStores(aliasName + ":", SIMD_ENABLED)
|
|
864
1093
|
.map((v) => indent + v + "\n")
|
|
865
1094
|
.join("");
|
|
866
|
-
SERIALIZE += indent +
|
|
867
|
-
|
|
868
|
-
this.schema.byteSize += 2;
|
|
869
|
-
SERIALIZE += indent + `store<u16>(bs.offset, 44, 0); // ,\n`;
|
|
870
|
-
SERIALIZE += indent + `bs.offset += 2;\n`;
|
|
871
|
-
}
|
|
1095
|
+
SERIALIZE += indent + serValue(member, realName);
|
|
1096
|
+
SERIALIZE += indent + "wrote = true;\n";
|
|
872
1097
|
indentDec();
|
|
873
1098
|
SERIALIZE += indent + `}\n`;
|
|
874
1099
|
}
|
|
@@ -906,12 +1131,29 @@ export class JSONTransform extends Visitor {
|
|
|
906
1131
|
type.startsWith("JSON.Box<") ||
|
|
907
1132
|
isEnum(type, this.sources.get(this.schema.node.range.source), this.parser))
|
|
908
1133
|
sortedMembers.number.push(member);
|
|
909
|
-
else if (isArray(type))
|
|
1134
|
+
else if (isArray(type) || type == "JSON.Arr" || type == "Arr")
|
|
910
1135
|
sortedMembers.array.push(member);
|
|
911
1136
|
else
|
|
912
1137
|
sortedMembers.object.push(member);
|
|
913
1138
|
}
|
|
914
1139
|
}
|
|
1140
|
+
const lazyMembers = this.schema.members.filter((member) => member.flags.has(PropertyFlags.Lazy));
|
|
1141
|
+
const withLazyMembers = (members) => {
|
|
1142
|
+
if (!lazyMembers.length)
|
|
1143
|
+
return members;
|
|
1144
|
+
const out = members.slice();
|
|
1145
|
+
for (const member of lazyMembers) {
|
|
1146
|
+
if (!out.includes(member))
|
|
1147
|
+
out.push(member);
|
|
1148
|
+
}
|
|
1149
|
+
return out;
|
|
1150
|
+
};
|
|
1151
|
+
const slowStringMembers = withLazyMembers(sortedMembers.string);
|
|
1152
|
+
const slowNumberMembers = withLazyMembers(sortedMembers.number);
|
|
1153
|
+
const slowObjectMembers = withLazyMembers(sortedMembers.object);
|
|
1154
|
+
const slowArrayMembers = withLazyMembers(sortedMembers.array);
|
|
1155
|
+
const slowBooleanMembers = withLazyMembers(sortedMembers.boolean);
|
|
1156
|
+
const slowNullMembers = withLazyMembers(sortedMembers.null);
|
|
915
1157
|
const getComparisions = (data, ptr, operator) => {
|
|
916
1158
|
const dataBytes = data.length << 1;
|
|
917
1159
|
let offset = 0;
|
|
@@ -952,6 +1194,17 @@ export class JSONTransform extends Visitor {
|
|
|
952
1194
|
const resolvedSchema = this.getSchema(resolvedType);
|
|
953
1195
|
const fieldOffset = `offsetof<this>(${JSON.stringify(member.name)})`;
|
|
954
1196
|
const valuePtr = keyOffset ? `${srcPtr} + ${keyOffset}` : srcPtr;
|
|
1197
|
+
if (member.flags.has(PropertyFlags.Lazy)) {
|
|
1198
|
+
const lazyInner = member.lazyInner;
|
|
1199
|
+
out.push("{");
|
|
1200
|
+
out.push(` const valueStart = JSON.Util.skipWhitespace(${valuePtr}, srcEnd);`);
|
|
1201
|
+
out.push(` const valueEnd = JSON.Util.scanValueEnd<${lazyInner}>(valueStart, srcEnd);`);
|
|
1202
|
+
out.push(" if (!valueEnd) break;");
|
|
1203
|
+
out.push(` store<u64>(${outPtr}, ((<u64>valueStart) << 32) | (<u64>(<u32>valueEnd)), ${fieldOffset});`);
|
|
1204
|
+
out.push(` ${srcPtr} = valueEnd;`);
|
|
1205
|
+
out.push("}");
|
|
1206
|
+
return out;
|
|
1207
|
+
}
|
|
955
1208
|
if (INTEGER_TYPES.includes(resolvedType)) {
|
|
956
1209
|
const helper = SIGNED_INTEGER_TYPES.includes(resolvedType)
|
|
957
1210
|
? "__deserializeIntegerField"
|
|
@@ -1099,9 +1352,18 @@ export class JSONTransform extends Visitor {
|
|
|
1099
1352
|
out.push(` if (changetype<usize>(value) == 0) {`);
|
|
1100
1353
|
out.push(` value = changetype<${resolvedType}>(__new(offsetof<nonnull<${resolvedType}>>(), idof<nonnull<${resolvedType}>>()));`);
|
|
1101
1354
|
out.push(` store<${resolvedType}>(${outPtr}, value, ${fieldOffset});`);
|
|
1355
|
+
out.push(` changetype<nonnull<${resolvedType}>>(value).__INITIALIZE();`);
|
|
1102
1356
|
out.push(" }");
|
|
1103
|
-
out.push(`
|
|
1104
|
-
out.push(` if (
|
|
1357
|
+
out.push(` const __fe = changetype<nonnull<${resolvedType}>>(value).__DESERIALIZE_FAST<${resolvedType}>(${valuePtr}, srcEnd, value);`);
|
|
1358
|
+
out.push(` if (__fe) {`);
|
|
1359
|
+
out.push(` ${srcPtr} = __fe;`);
|
|
1360
|
+
out.push(` } else {`);
|
|
1361
|
+
out.push(` const __ve = JSON.Util.scanValueEnd<${resolvedType}>(${valuePtr}, srcEnd);`);
|
|
1362
|
+
out.push(` if (!__ve) break;`);
|
|
1363
|
+
out.push(` changetype<nonnull<${resolvedType}>>(value).__INITIALIZE();`);
|
|
1364
|
+
out.push(` changetype<nonnull<${resolvedType}>>(value).__DESERIALIZE_SLOW<${resolvedType}>(${valuePtr}, __ve, value);`);
|
|
1365
|
+
out.push(` ${srcPtr} = __ve;`);
|
|
1366
|
+
out.push(` }`);
|
|
1105
1367
|
if (member.node.type.isNullable) {
|
|
1106
1368
|
out.push(" }");
|
|
1107
1369
|
}
|
|
@@ -1121,7 +1383,7 @@ export class JSONTransform extends Visitor {
|
|
|
1121
1383
|
out.push(` store<${resolvedType}>(${outPtr}, value, ${fieldOffset});`);
|
|
1122
1384
|
out.push(" }");
|
|
1123
1385
|
out.push(` const valueStart = ${valuePtr};`);
|
|
1124
|
-
out.push(` const valueEnd = JSON.Util.scanValueEnd(valueStart, srcEnd);`);
|
|
1386
|
+
out.push(` const valueEnd = JSON.Util.scanValueEnd<${resolvedType}>(valueStart, srcEnd);`);
|
|
1125
1387
|
out.push(" if (!valueEnd) break;");
|
|
1126
1388
|
if (fastPath) {
|
|
1127
1389
|
out.push(` ${srcPtr} = changetype<nonnull<${resolvedType}>>(value).__DESERIALIZE_FAST<${resolvedType}>(valueStart, valueEnd, value);`);
|
|
@@ -1216,13 +1478,24 @@ export class JSONTransform extends Visitor {
|
|
|
1216
1478
|
out.push(" if (changetype<usize>(item) == 0) {");
|
|
1217
1479
|
out.push(` item = changetype<${valueType}>(__new(offsetof<nonnull<${valueType}>>(), idof<nonnull<${valueType}>>()));`);
|
|
1218
1480
|
out.push(" unchecked((value[index] = item));");
|
|
1481
|
+
out.push(` changetype<nonnull<${valueType}>>(item).__INITIALIZE();`);
|
|
1219
1482
|
out.push(" }");
|
|
1220
1483
|
out.push(" } else {");
|
|
1221
1484
|
out.push(` item = changetype<${valueType}>(__new(offsetof<nonnull<${valueType}>>(), idof<nonnull<${valueType}>>()));`);
|
|
1222
1485
|
out.push(" value.push(item);");
|
|
1486
|
+
out.push(` changetype<nonnull<${valueType}>>(item).__INITIALIZE();`);
|
|
1223
1487
|
out.push(" }");
|
|
1224
|
-
out.push(`
|
|
1225
|
-
out.push(`
|
|
1488
|
+
out.push(` const __es = ${srcPtr};`);
|
|
1489
|
+
out.push(` const __ee = changetype<nonnull<${valueType}>>(item).__DESERIALIZE_FAST<${valueType}>(${srcPtr}, srcEnd, item);`);
|
|
1490
|
+
out.push(` if (__ee) {`);
|
|
1491
|
+
out.push(` ${srcPtr} = __ee;`);
|
|
1492
|
+
out.push(` } else {`);
|
|
1493
|
+
out.push(` const __ve = JSON.Util.scanValueEnd<${valueType}>(__es, srcEnd);`);
|
|
1494
|
+
out.push(` if (!__ve) break;`);
|
|
1495
|
+
out.push(` changetype<nonnull<${valueType}>>(item).__INITIALIZE();`);
|
|
1496
|
+
out.push(` changetype<nonnull<${valueType}>>(item).__DESERIALIZE_SLOW<${valueType}>(__es, __ve, item);`);
|
|
1497
|
+
out.push(` ${srcPtr} = __ve;`);
|
|
1498
|
+
out.push(` }`);
|
|
1226
1499
|
out.push(" index++;");
|
|
1227
1500
|
out.push(` ${srcPtr} = JSON.Util.skipWhitespace(${srcPtr}, srcEnd);`);
|
|
1228
1501
|
out.push(` const code = load<u16>(${srcPtr});`);
|
|
@@ -1243,7 +1516,7 @@ export class JSONTransform extends Visitor {
|
|
|
1243
1516
|
out.push("}");
|
|
1244
1517
|
return out;
|
|
1245
1518
|
}
|
|
1246
|
-
out.push(` ${srcPtr} = __deserializeArrayField_SWAR<${resolvedType}
|
|
1519
|
+
out.push(` ${srcPtr} = __deserializeArrayField_SWAR<nonnull<${resolvedType}>>(${valuePtr}, srcEnd, ${outPtr}, ${fieldOffset});`);
|
|
1247
1520
|
out.push(` if (!${srcPtr}) break;`);
|
|
1248
1521
|
if (member.node.type.isNullable) {
|
|
1249
1522
|
out.push(" }");
|
|
@@ -1264,6 +1537,7 @@ export class JSONTransform extends Visitor {
|
|
|
1264
1537
|
}
|
|
1265
1538
|
else if (resolvedType == "JSON.Value" ||
|
|
1266
1539
|
resolvedType == "JSON.Obj" ||
|
|
1540
|
+
resolvedType == "JSON.Arr" ||
|
|
1267
1541
|
isEnum(resolvedType, this.sources.get(this.schema.node.range.source), this.parser)) {
|
|
1268
1542
|
out.push("break;");
|
|
1269
1543
|
}
|
|
@@ -1273,6 +1547,29 @@ export class JSONTransform extends Visitor {
|
|
|
1273
1547
|
return out;
|
|
1274
1548
|
};
|
|
1275
1549
|
indent = " ";
|
|
1550
|
+
const FAST_CHUNK_SIZE = 32;
|
|
1551
|
+
const fastChunkMethods = [];
|
|
1552
|
+
let fastChunkId = 0;
|
|
1553
|
+
const chunkFastBlocks = (blocks, tag, callIndent) => {
|
|
1554
|
+
if (blocks.length <= FAST_CHUNK_SIZE)
|
|
1555
|
+
return blocks.join("");
|
|
1556
|
+
let calls = "";
|
|
1557
|
+
for (let c = 0; c < blocks.length; c += FAST_CHUNK_SIZE) {
|
|
1558
|
+
const name = `__DESERIALIZE_FAST_${tag}_${fastChunkId++}`;
|
|
1559
|
+
const body = blocks
|
|
1560
|
+
.slice(c, c + FAST_CHUNK_SIZE)
|
|
1561
|
+
.join("")
|
|
1562
|
+
.replace(/\bbreak;/g, "return 0;");
|
|
1563
|
+
fastChunkMethods.push(`${name}(srcStart: usize, srcEnd: usize, dst: usize): usize {\n${body}\n return srcStart;\n}`);
|
|
1564
|
+
calls +=
|
|
1565
|
+
`${callIndent}srcStart = this.${name}(srcStart, srcEnd, dst);\n` +
|
|
1566
|
+
`${callIndent}if (srcStart == 0) break;\n`;
|
|
1567
|
+
}
|
|
1568
|
+
return calls;
|
|
1569
|
+
};
|
|
1570
|
+
const chunkFastBlocksOptional = (blocks, _tag, _callIndent, _needsKp) => {
|
|
1571
|
+
return blocks.join("");
|
|
1572
|
+
};
|
|
1276
1573
|
DESERIALIZE_FAST += indent + "const start = srcStart;\n";
|
|
1277
1574
|
DESERIALIZE_FAST += indent + "const dst = changetype<usize>(out);\n";
|
|
1278
1575
|
DESERIALIZE_FAST += indent + "do {\n";
|
|
@@ -1282,6 +1579,7 @@ export class JSONTransform extends Visitor {
|
|
|
1282
1579
|
indent + "if (load<u16>(srcStart) !== 0x7b) break; // {\n";
|
|
1283
1580
|
DESERIALIZE_FAST += indent + "srcStart += 2;\n";
|
|
1284
1581
|
DESERIALIZE_FAST += indent + "let seenAny = false;\n\n";
|
|
1582
|
+
const t1opt = [];
|
|
1285
1583
|
for (let i = 0; i < this.schema.members.length; i++) {
|
|
1286
1584
|
const member = this.schema.members[i];
|
|
1287
1585
|
const key = JSON.stringify(member.alias || member.name);
|
|
@@ -1298,89 +1596,92 @@ export class JSONTransform extends Visitor {
|
|
|
1298
1596
|
const isOptional = member.flags.has(PropertyFlags.OmitNull) ||
|
|
1299
1597
|
member.flags.has(PropertyFlags.OmitIf);
|
|
1300
1598
|
if (!deserializerFirst.length || !deserializerNext.length) {
|
|
1301
|
-
|
|
1599
|
+
t1opt.push(indent + "break;\n\n");
|
|
1302
1600
|
continue;
|
|
1303
1601
|
}
|
|
1304
|
-
|
|
1602
|
+
let blk = indent + "if (!seenAny) {\n";
|
|
1305
1603
|
indent += " ";
|
|
1306
|
-
|
|
1604
|
+
blk +=
|
|
1307
1605
|
indent +
|
|
1308
1606
|
`if ( // ${firstKeySection}\n${(indent += " ")}${getComparisions(firstKeySection, "srcStart", "!=").join("\n" + indent + "|| ")}\n${(indent = indent.slice(0, -2))}) {\n`;
|
|
1309
1607
|
indent += " ";
|
|
1310
1608
|
if (isOptional) {
|
|
1311
|
-
|
|
1609
|
+
blk += indent + "// optional @omitnull field omitted\n";
|
|
1312
1610
|
}
|
|
1313
1611
|
else {
|
|
1314
|
-
|
|
1612
|
+
blk += indent + "break;\n";
|
|
1315
1613
|
}
|
|
1316
1614
|
indent = indent.slice(0, -2);
|
|
1317
|
-
|
|
1615
|
+
blk += indent + "} else {\n";
|
|
1318
1616
|
indent += " ";
|
|
1319
1617
|
if (!inlineStringValue)
|
|
1320
|
-
|
|
1321
|
-
|
|
1618
|
+
blk += indent + `srcStart += ${firstKeyOffset};\n`;
|
|
1619
|
+
blk +=
|
|
1322
1620
|
indent +
|
|
1323
1621
|
`if (JSON.Util.isSpace(load<u16>(${inlineStringValue ? `srcStart + ${firstKeyOffset}` : "srcStart"}))) break;\n`;
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
DESERIALIZE_FAST += indent + "seenAny = true;\n";
|
|
1622
|
+
blk += indent + deserializerFirst.join("\n" + indent) + "\n";
|
|
1623
|
+
blk += indent + "seenAny = true;\n";
|
|
1327
1624
|
indent = indent.slice(0, -2);
|
|
1328
|
-
|
|
1625
|
+
blk += indent + "}\n";
|
|
1329
1626
|
indent = indent.slice(0, -2);
|
|
1330
|
-
|
|
1627
|
+
blk += indent + "} else {\n";
|
|
1331
1628
|
indent += " ";
|
|
1332
|
-
|
|
1629
|
+
blk +=
|
|
1333
1630
|
indent +
|
|
1334
1631
|
`if ( // ${nextKeySection}\n${(indent += " ")}${getComparisions(nextKeySection, "srcStart", "!=").join("\n" + indent + "|| ")}\n${(indent = indent.slice(0, -2))}) {\n`;
|
|
1335
1632
|
indent += " ";
|
|
1336
1633
|
if (isOptional) {
|
|
1337
|
-
|
|
1634
|
+
blk += indent + "// optional @omitnull field omitted\n";
|
|
1338
1635
|
}
|
|
1339
1636
|
else {
|
|
1340
|
-
|
|
1637
|
+
blk += indent + "break;\n";
|
|
1341
1638
|
}
|
|
1342
1639
|
indent = indent.slice(0, -2);
|
|
1343
|
-
|
|
1640
|
+
blk += indent + "} else {\n";
|
|
1344
1641
|
indent += " ";
|
|
1345
1642
|
if (!inlineStringValue)
|
|
1346
|
-
|
|
1347
|
-
|
|
1643
|
+
blk += indent + `srcStart += ${nextKeyOffset};\n`;
|
|
1644
|
+
blk +=
|
|
1348
1645
|
indent +
|
|
1349
1646
|
`if (JSON.Util.isSpace(load<u16>(${inlineStringValue ? `srcStart + ${nextKeyOffset}` : "srcStart"}))) break;\n`;
|
|
1350
|
-
|
|
1351
|
-
indent + deserializerNext.join("\n" + indent) + "\n";
|
|
1647
|
+
blk += indent + deserializerNext.join("\n" + indent) + "\n";
|
|
1352
1648
|
indent = indent.slice(0, -2);
|
|
1353
|
-
|
|
1649
|
+
blk += indent + "}\n";
|
|
1354
1650
|
indent = indent.slice(0, -2);
|
|
1355
|
-
|
|
1651
|
+
blk += indent + "}\n\n";
|
|
1652
|
+
t1opt.push(blk);
|
|
1356
1653
|
}
|
|
1654
|
+
DESERIALIZE_FAST += chunkFastBlocksOptional(t1opt, "T1O", indent, false);
|
|
1357
1655
|
}
|
|
1358
1656
|
else {
|
|
1657
|
+
const t1blocks = [];
|
|
1359
1658
|
for (let i = 0; i < this.schema.members.length; i++) {
|
|
1360
1659
|
const member = this.schema.members[i];
|
|
1361
1660
|
const key = JSON.stringify(member.alias || member.name);
|
|
1362
1661
|
if (key.length <= 2)
|
|
1363
1662
|
throw new Error("Key cannot be empty!");
|
|
1364
1663
|
const keySection = (i == 0 ? "{" : ",") + key + ":";
|
|
1365
|
-
|
|
1366
|
-
indent +
|
|
1367
|
-
`if ( // ${keySection}\n${(indent += " ")}${getComparisions(keySection, "srcStart", "!=").join("\n" + indent + "|| ")}\n${(indent = indent.slice(0, -2))}) break;\n`;
|
|
1664
|
+
let blk = indent +
|
|
1665
|
+
`if ( // ${keySection}\n${(indent += " ")}${getComparisions(keySection, "srcStart", "!=").join("\n" + indent + "|| ")}\n${(indent = indent.slice(0, -2))}) break;\n`;
|
|
1368
1666
|
const keyOffset = keySection.length << 1;
|
|
1369
1667
|
const resolvedType = stripNull(member.type);
|
|
1370
1668
|
const inlineStringValue = ["string", "String"].includes(resolvedType);
|
|
1371
1669
|
if (!inlineStringValue) {
|
|
1372
|
-
|
|
1670
|
+
blk += indent + `srcStart += ${keyOffset};\n\n`;
|
|
1373
1671
|
}
|
|
1374
1672
|
const deserializer = getDeserializer(member.type, "srcStart", "dst", member, inlineStringValue ? keyOffset : 0, true);
|
|
1375
1673
|
if (!deserializer.length) {
|
|
1376
|
-
|
|
1674
|
+
blk += indent + "break;\n\n";
|
|
1675
|
+
t1blocks.push(blk);
|
|
1377
1676
|
continue;
|
|
1378
1677
|
}
|
|
1379
|
-
|
|
1678
|
+
blk +=
|
|
1380
1679
|
indent +
|
|
1381
1680
|
`if (JSON.Util.isSpace(load<u16>(${inlineStringValue ? `srcStart + ${keyOffset}` : "srcStart"}))) break;\n`;
|
|
1382
|
-
|
|
1681
|
+
blk += indent + deserializer.join("\n" + indent) + "\n\n";
|
|
1682
|
+
t1blocks.push(blk);
|
|
1383
1683
|
}
|
|
1684
|
+
DESERIALIZE_FAST += chunkFastBlocks(t1blocks, "T1", indent);
|
|
1384
1685
|
}
|
|
1385
1686
|
DESERIALIZE_FAST +=
|
|
1386
1687
|
indent + "if (load<u16>(srcStart) !== 0x7d) break; // }\n";
|
|
@@ -1399,31 +1700,32 @@ export class JSONTransform extends Visitor {
|
|
|
1399
1700
|
DESERIALIZE_FAST += skip;
|
|
1400
1701
|
DESERIALIZE_FAST += i2 + "if (load<u16>(srcStart) != 0x7b) break; // {\n";
|
|
1401
1702
|
DESERIALIZE_FAST += i2 + "srcStart += 2;\n";
|
|
1703
|
+
const t2blocks = [];
|
|
1402
1704
|
for (let i = 0; i < this.schema.members.length; i++) {
|
|
1403
1705
|
const member = this.schema.members[i];
|
|
1404
1706
|
const key = JSON.stringify(member.alias || member.name);
|
|
1405
1707
|
const keyBytes = key.length << 1;
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1708
|
+
let blk = "\n";
|
|
1709
|
+
blk += skip;
|
|
1710
|
+
blk +=
|
|
1409
1711
|
i2 +
|
|
1410
1712
|
`if ( // ${key}\n${i2} ` +
|
|
1411
1713
|
getComparisions(key, "srcStart", "!=").join("\n" + i2 + " || ") +
|
|
1412
1714
|
`\n${i2}) break;\n`;
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
DESERIALIZE_FAST += i2 + tier2Desers[i].join("\n" + i2) + "\n";
|
|
1715
|
+
blk += i2 + `srcStart += ${keyBytes};\n`;
|
|
1716
|
+
blk += skip;
|
|
1717
|
+
blk += i2 + "if (load<u16>(srcStart) != 0x3a) break; // :\n";
|
|
1718
|
+
blk += i2 + "srcStart += 2;\n";
|
|
1719
|
+
blk += skip;
|
|
1720
|
+
blk += i2 + tier2Desers[i].join("\n" + i2) + "\n";
|
|
1420
1721
|
if (i < this.schema.members.length - 1) {
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
DESERIALIZE_FAST += i2 + "srcStart += 2;\n";
|
|
1722
|
+
blk += skip;
|
|
1723
|
+
blk += i2 + "if (load<u16>(srcStart) != 0x2c) break; // ,\n";
|
|
1724
|
+
blk += i2 + "srcStart += 2;\n";
|
|
1425
1725
|
}
|
|
1726
|
+
t2blocks.push(blk);
|
|
1426
1727
|
}
|
|
1728
|
+
DESERIALIZE_FAST += chunkFastBlocks(t2blocks, "T2", i2);
|
|
1427
1729
|
DESERIALIZE_FAST += "\n";
|
|
1428
1730
|
DESERIALIZE_FAST += skip;
|
|
1429
1731
|
DESERIALIZE_FAST += i2 + "if (load<u16>(srcStart) != 0x7d) break; // }\n";
|
|
@@ -1445,33 +1747,34 @@ export class JSONTransform extends Visitor {
|
|
|
1445
1747
|
DESERIALIZE_FAST += i2 + "let kp: usize = 0;\n";
|
|
1446
1748
|
if (multi)
|
|
1447
1749
|
DESERIALIZE_FAST += i2 + "let seenAny = false;\n";
|
|
1750
|
+
const t2opt = [];
|
|
1448
1751
|
for (let i = 0; i < this.schema.members.length; i++) {
|
|
1449
1752
|
const member = this.schema.members[i];
|
|
1450
1753
|
const key = JSON.stringify(member.alias || member.name);
|
|
1451
1754
|
const keyBytes = key.length << 1;
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
i2 + "kp = JSON.Util.skipWhitespace(srcStart, srcEnd);\n";
|
|
1755
|
+
let blk = "\n";
|
|
1756
|
+
blk += i2 + "kp = JSON.Util.skipWhitespace(srcStart, srcEnd);\n";
|
|
1455
1757
|
if (multi && i > 0) {
|
|
1456
|
-
|
|
1758
|
+
blk +=
|
|
1457
1759
|
i2 +
|
|
1458
1760
|
"if (seenAny && load<u16>(kp) == 0x2c) kp = JSON.Util.skipWhitespace(kp + 2, srcEnd);\n";
|
|
1459
1761
|
}
|
|
1460
|
-
|
|
1762
|
+
blk +=
|
|
1461
1763
|
i2 +
|
|
1462
1764
|
`if ( // ${key}\n${i2} ` +
|
|
1463
1765
|
getComparisions(key, "kp", "==").join("\n" + i2 + " && ") +
|
|
1464
1766
|
`\n${i2}) {\n`;
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
DESERIALIZE_FAST += i3 + tier2Desers[i].join("\n" + i3) + "\n";
|
|
1767
|
+
blk += i3 + `kp += ${keyBytes};\n`;
|
|
1768
|
+
blk += i3 + "kp = JSON.Util.skipWhitespace(kp, srcEnd);\n";
|
|
1769
|
+
blk += i3 + "if (load<u16>(kp) != 0x3a) break; // :\n";
|
|
1770
|
+
blk += i3 + "srcStart = JSON.Util.skipWhitespace(kp + 2, srcEnd);\n";
|
|
1771
|
+
blk += i3 + tier2Desers[i].join("\n" + i3) + "\n";
|
|
1471
1772
|
if (multi)
|
|
1472
|
-
|
|
1473
|
-
|
|
1773
|
+
blk += i3 + "seenAny = true;\n";
|
|
1774
|
+
blk += i2 + "}\n";
|
|
1775
|
+
t2opt.push(blk);
|
|
1474
1776
|
}
|
|
1777
|
+
DESERIALIZE_FAST += chunkFastBlocksOptional(t2opt, "T2O", i2, true);
|
|
1475
1778
|
DESERIALIZE_FAST += "\n";
|
|
1476
1779
|
DESERIALIZE_FAST +=
|
|
1477
1780
|
i2 + "srcStart = JSON.Util.skipWhitespace(srcStart, srcEnd);\n";
|
|
@@ -1498,7 +1801,7 @@ export class JSONTransform extends Visitor {
|
|
|
1498
1801
|
DESERIALIZE += indent + " let keyStart: usize = 0;\n";
|
|
1499
1802
|
DESERIALIZE += indent + " let keyEnd: usize = 0;\n";
|
|
1500
1803
|
DESERIALIZE += indent + " let isKey = false;\n";
|
|
1501
|
-
if (!STRICT ||
|
|
1804
|
+
if (!STRICT || slowObjectMembers.length || slowArrayMembers.length)
|
|
1502
1805
|
DESERIALIZE += indent + " let depth: i32 = 0;\n";
|
|
1503
1806
|
DESERIALIZE += indent + " let lastIndex: usize = 0;\n\n";
|
|
1504
1807
|
DESERIALIZE +=
|
|
@@ -1643,8 +1946,37 @@ export class JSONTransform extends Visitor {
|
|
|
1643
1946
|
DESERIALIZE += toMemCDecl(Math.max(...members.map((m) => (m.alias || m.name).length << 1)), " ");
|
|
1644
1947
|
}
|
|
1645
1948
|
};
|
|
1949
|
+
const getLazyRangeStore = (member, valueStart, valueEnd, prefix) => {
|
|
1950
|
+
return (prefix +
|
|
1951
|
+
`store<u64>(changetype<usize>(out), ((<u64>${valueStart}) << 32) | (<u64>(<u32>${valueEnd})), offsetof<this>(${JSON.stringify(member.name)}));\n`);
|
|
1952
|
+
};
|
|
1953
|
+
const getSlowValueStore = (member, valueStart, valueEnd, prefix) => {
|
|
1954
|
+
if (member.flags.has(PropertyFlags.Lazy))
|
|
1955
|
+
return getLazyRangeStore(member, valueStart, valueEnd, prefix);
|
|
1956
|
+
return (prefix +
|
|
1957
|
+
`store<${member.type}>(changetype<usize>(out), JSON.__deserialize<${member.type}>(${valueStart}, ${valueEnd}), offsetof<this>(${JSON.stringify(member.name)}));\n`);
|
|
1958
|
+
};
|
|
1959
|
+
const getSlowBooleanStore = (member, value, valueStart, valueEnd, prefix) => {
|
|
1960
|
+
if (member.flags.has(PropertyFlags.Lazy))
|
|
1961
|
+
return getLazyRangeStore(member, valueStart, valueEnd, prefix);
|
|
1962
|
+
if (member.type.startsWith("JSON.Box<bool") ||
|
|
1963
|
+
member.type.startsWith("JSON.Box<boolean") ||
|
|
1964
|
+
member.type.startsWith("Box<bool") ||
|
|
1965
|
+
member.type.startsWith("Box<boolean")) {
|
|
1966
|
+
return (prefix +
|
|
1967
|
+
`store<${member.type}>(changetype<usize>(out), changetype<${member.type}>(JSON.Box.from<bool>(${value})), offsetof<this>(${JSON.stringify(member.name)}));\n`);
|
|
1968
|
+
}
|
|
1969
|
+
return (prefix +
|
|
1970
|
+
`store<boolean>(changetype<usize>(out), ${value}, offsetof<this>(${JSON.stringify(member.name)}));\n`);
|
|
1971
|
+
};
|
|
1972
|
+
const getSlowNullStore = (member, valueStart, valueEnd, prefix) => {
|
|
1973
|
+
if (member.flags.has(PropertyFlags.Lazy))
|
|
1974
|
+
return getLazyRangeStore(member, valueStart, valueEnd, prefix);
|
|
1975
|
+
return (prefix +
|
|
1976
|
+
`store<usize>(changetype<usize>(out), 0, offsetof<this>(${JSON.stringify(member.name)}));\n`);
|
|
1977
|
+
};
|
|
1646
1978
|
let mbElse = " ";
|
|
1647
|
-
if (!STRICT ||
|
|
1979
|
+
if (!STRICT || slowStringMembers.length) {
|
|
1648
1980
|
DESERIALIZE += mbElse + "if (code == 34) {\n";
|
|
1649
1981
|
DESERIALIZE += " lastIndex = srcStart;\n";
|
|
1650
1982
|
DESERIALIZE += " srcStart += 2;\n";
|
|
@@ -1657,7 +1989,7 @@ export class JSONTransform extends Visitor {
|
|
|
1657
1989
|
' console.log("Value (string, ' +
|
|
1658
1990
|
++id +
|
|
1659
1991
|
'): " + JSON.Util.ptrToStr(lastIndex, srcStart + 2));';
|
|
1660
|
-
generateGroups(
|
|
1992
|
+
generateGroups(slowStringMembers, (group) => {
|
|
1661
1993
|
generateConsts(group);
|
|
1662
1994
|
const first = group[0];
|
|
1663
1995
|
const fName = first.alias || first.name;
|
|
@@ -1669,15 +2001,7 @@ export class JSONTransform extends Visitor {
|
|
|
1669
2001
|
") { // " +
|
|
1670
2002
|
fName +
|
|
1671
2003
|
"\n";
|
|
1672
|
-
DESERIALIZE +=
|
|
1673
|
-
indent +
|
|
1674
|
-
" store<" +
|
|
1675
|
-
first.type +
|
|
1676
|
-
">(changetype<usize>(out), JSON.__deserialize<" +
|
|
1677
|
-
first.type +
|
|
1678
|
-
">(lastIndex, srcStart + 2), offsetof<this>(" +
|
|
1679
|
-
JSON.stringify(first.name) +
|
|
1680
|
-
"));\n";
|
|
2004
|
+
DESERIALIZE += getSlowValueStore(first, "lastIndex", "srcStart + 2", indent + " ");
|
|
1681
2005
|
DESERIALIZE += indent + " srcStart += 4;\n";
|
|
1682
2006
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
1683
2007
|
DESERIALIZE += indent + " break;\n";
|
|
@@ -1693,15 +2017,7 @@ export class JSONTransform extends Visitor {
|
|
|
1693
2017
|
") { // " +
|
|
1694
2018
|
memName +
|
|
1695
2019
|
"\n";
|
|
1696
|
-
DESERIALIZE +=
|
|
1697
|
-
indent +
|
|
1698
|
-
" store<" +
|
|
1699
|
-
mem.type +
|
|
1700
|
-
">(changetype<usize>(out), JSON.__deserialize<" +
|
|
1701
|
-
mem.type +
|
|
1702
|
-
">(lastIndex, srcStart + 2), offsetof<this>(" +
|
|
1703
|
-
JSON.stringify(mem.name) +
|
|
1704
|
-
"));\n";
|
|
2020
|
+
DESERIALIZE += getSlowValueStore(mem, "lastIndex", "srcStart + 2", indent + " ");
|
|
1705
2021
|
DESERIALIZE += indent + " srcStart += 4;\n";
|
|
1706
2022
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
1707
2023
|
DESERIALIZE += indent + " break;\n";
|
|
@@ -1728,7 +2044,7 @@ export class JSONTransform extends Visitor {
|
|
|
1728
2044
|
DESERIALIZE += " }\n";
|
|
1729
2045
|
mbElse = " else ";
|
|
1730
2046
|
}
|
|
1731
|
-
if (!STRICT ||
|
|
2047
|
+
if (!STRICT || slowNumberMembers.length) {
|
|
1732
2048
|
DESERIALIZE += mbElse + "if (code - 48 <= 9 || code == 45) {\n";
|
|
1733
2049
|
DESERIALIZE += " lastIndex = srcStart;\n";
|
|
1734
2050
|
DESERIALIZE += " srcStart += 2;\n";
|
|
@@ -1741,7 +2057,7 @@ export class JSONTransform extends Visitor {
|
|
|
1741
2057
|
' console.log("Value (number, ' +
|
|
1742
2058
|
++id +
|
|
1743
2059
|
'): " + JSON.Util.ptrToStr(lastIndex, srcStart));';
|
|
1744
|
-
generateGroups(
|
|
2060
|
+
generateGroups(slowNumberMembers, (group) => {
|
|
1745
2061
|
generateConsts(group);
|
|
1746
2062
|
const first = group[0];
|
|
1747
2063
|
const fName = first.alias || first.name;
|
|
@@ -1759,15 +2075,7 @@ export class JSONTransform extends Visitor {
|
|
|
1759
2075
|
") { // " +
|
|
1760
2076
|
fName +
|
|
1761
2077
|
"\n";
|
|
1762
|
-
DESERIALIZE +=
|
|
1763
|
-
indent +
|
|
1764
|
-
" store<" +
|
|
1765
|
-
first.type +
|
|
1766
|
-
">(changetype<usize>(out), JSON.__deserialize<" +
|
|
1767
|
-
first.type +
|
|
1768
|
-
">(lastIndex, srcStart), offsetof<this>(" +
|
|
1769
|
-
JSON.stringify(first.name) +
|
|
1770
|
-
"));\n";
|
|
2078
|
+
DESERIALIZE += getSlowValueStore(first, "lastIndex", "srcStart", indent + " ");
|
|
1771
2079
|
DESERIALIZE += indent + " srcStart += 2;\n";
|
|
1772
2080
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
1773
2081
|
DESERIALIZE += indent + " break;\n";
|
|
@@ -1789,15 +2097,7 @@ export class JSONTransform extends Visitor {
|
|
|
1789
2097
|
") { // " +
|
|
1790
2098
|
memName +
|
|
1791
2099
|
"\n";
|
|
1792
|
-
DESERIALIZE +=
|
|
1793
|
-
indent +
|
|
1794
|
-
" store<" +
|
|
1795
|
-
mem.type +
|
|
1796
|
-
">(changetype<usize>(out), JSON.__deserialize<" +
|
|
1797
|
-
mem.type +
|
|
1798
|
-
">(lastIndex, srcStart), offsetof<this>(" +
|
|
1799
|
-
JSON.stringify(mem.name) +
|
|
1800
|
-
"));\n";
|
|
2100
|
+
DESERIALIZE += getSlowValueStore(mem, "lastIndex", "srcStart", indent + " ");
|
|
1801
2101
|
DESERIALIZE += indent + " srcStart += 2;\n";
|
|
1802
2102
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
1803
2103
|
DESERIALIZE += indent + " break;\n";
|
|
@@ -1824,7 +2124,7 @@ export class JSONTransform extends Visitor {
|
|
|
1824
2124
|
DESERIALIZE += " }";
|
|
1825
2125
|
mbElse = " else ";
|
|
1826
2126
|
}
|
|
1827
|
-
if (!STRICT ||
|
|
2127
|
+
if (!STRICT || slowObjectMembers.length) {
|
|
1828
2128
|
DESERIALIZE += mbElse + "if (code == 123) {\n";
|
|
1829
2129
|
DESERIALIZE += " lastIndex = srcStart;\n";
|
|
1830
2130
|
DESERIALIZE += " depth++;\n";
|
|
@@ -1844,7 +2144,7 @@ export class JSONTransform extends Visitor {
|
|
|
1844
2144
|
++id +
|
|
1845
2145
|
'): " + JSON.Util.ptrToStr(lastIndex, srcStart));';
|
|
1846
2146
|
indent = " ";
|
|
1847
|
-
generateGroups(
|
|
2147
|
+
generateGroups(slowObjectMembers, (group) => {
|
|
1848
2148
|
generateConsts(group);
|
|
1849
2149
|
const first = group[0];
|
|
1850
2150
|
const fName = first.alias || first.name;
|
|
@@ -1855,15 +2155,7 @@ export class JSONTransform extends Visitor {
|
|
|
1855
2155
|
") { // " +
|
|
1856
2156
|
fName +
|
|
1857
2157
|
"\n";
|
|
1858
|
-
DESERIALIZE +=
|
|
1859
|
-
indent +
|
|
1860
|
-
" store<" +
|
|
1861
|
-
first.type +
|
|
1862
|
-
">(changetype<usize>(out), JSON.__deserialize<" +
|
|
1863
|
-
first.type +
|
|
1864
|
-
">(lastIndex, srcStart), offsetof<this>(" +
|
|
1865
|
-
JSON.stringify(first.name) +
|
|
1866
|
-
"));\n";
|
|
2158
|
+
DESERIALIZE += getSlowValueStore(first, "lastIndex", "srcStart", indent + " ");
|
|
1867
2159
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
1868
2160
|
DESERIALIZE += indent + " break;\n";
|
|
1869
2161
|
DESERIALIZE += indent + " }";
|
|
@@ -1877,15 +2169,7 @@ export class JSONTransform extends Visitor {
|
|
|
1877
2169
|
") { // " +
|
|
1878
2170
|
memName +
|
|
1879
2171
|
"\n";
|
|
1880
|
-
DESERIALIZE +=
|
|
1881
|
-
indent +
|
|
1882
|
-
" store<" +
|
|
1883
|
-
mem.type +
|
|
1884
|
-
">(changetype<usize>(out), JSON.__deserialize<" +
|
|
1885
|
-
mem.type +
|
|
1886
|
-
">(lastIndex, srcStart), offsetof<this>(" +
|
|
1887
|
-
JSON.stringify(mem.name) +
|
|
1888
|
-
"));\n";
|
|
2172
|
+
DESERIALIZE += getSlowValueStore(mem, "lastIndex", "srcStart", indent + " ");
|
|
1889
2173
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
1890
2174
|
DESERIALIZE += indent + " break;\n";
|
|
1891
2175
|
DESERIALIZE += indent + " }";
|
|
@@ -1912,7 +2196,7 @@ export class JSONTransform extends Visitor {
|
|
|
1912
2196
|
DESERIALIZE += " }";
|
|
1913
2197
|
mbElse = " else ";
|
|
1914
2198
|
}
|
|
1915
|
-
if (!STRICT ||
|
|
2199
|
+
if (!STRICT || slowArrayMembers.length) {
|
|
1916
2200
|
DESERIALIZE += mbElse + "if (code == 91) {\n";
|
|
1917
2201
|
DESERIALIZE += " lastIndex = srcStart;\n";
|
|
1918
2202
|
DESERIALIZE += " depth++;\n";
|
|
@@ -1932,7 +2216,7 @@ export class JSONTransform extends Visitor {
|
|
|
1932
2216
|
++id +
|
|
1933
2217
|
'): " + JSON.Util.ptrToStr(lastIndex, srcStart));';
|
|
1934
2218
|
indent = " ";
|
|
1935
|
-
generateGroups(
|
|
2219
|
+
generateGroups(slowArrayMembers, (group) => {
|
|
1936
2220
|
generateConsts(group);
|
|
1937
2221
|
const first = group[0];
|
|
1938
2222
|
const fName = first.alias || first.name;
|
|
@@ -1944,15 +2228,7 @@ export class JSONTransform extends Visitor {
|
|
|
1944
2228
|
") { // " +
|
|
1945
2229
|
fName +
|
|
1946
2230
|
"\n";
|
|
1947
|
-
DESERIALIZE +=
|
|
1948
|
-
indent +
|
|
1949
|
-
" store<" +
|
|
1950
|
-
first.type +
|
|
1951
|
-
">(changetype<usize>(out), JSON.__deserialize<" +
|
|
1952
|
-
first.type +
|
|
1953
|
-
">(lastIndex, srcStart), offsetof<this>(" +
|
|
1954
|
-
JSON.stringify(first.name) +
|
|
1955
|
-
"));\n";
|
|
2231
|
+
DESERIALIZE += getSlowValueStore(first, "lastIndex", "srcStart", indent + " ");
|
|
1956
2232
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
1957
2233
|
DESERIALIZE += indent + " break;\n";
|
|
1958
2234
|
DESERIALIZE += indent + " }";
|
|
@@ -1967,15 +2243,7 @@ export class JSONTransform extends Visitor {
|
|
|
1967
2243
|
") { // " +
|
|
1968
2244
|
memName +
|
|
1969
2245
|
"\n";
|
|
1970
|
-
DESERIALIZE +=
|
|
1971
|
-
indent +
|
|
1972
|
-
" store<" +
|
|
1973
|
-
mem.type +
|
|
1974
|
-
">(changetype<usize>(out), JSON.__deserialize<" +
|
|
1975
|
-
mem.type +
|
|
1976
|
-
">(lastIndex, srcStart), offsetof<this>(" +
|
|
1977
|
-
JSON.stringify(mem.name) +
|
|
1978
|
-
"));\n";
|
|
2246
|
+
DESERIALIZE += getSlowValueStore(mem, "lastIndex", "srcStart", indent + " ");
|
|
1979
2247
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
1980
2248
|
DESERIALIZE += indent + " break;\n";
|
|
1981
2249
|
DESERIALIZE += indent + " }";
|
|
@@ -2002,7 +2270,7 @@ export class JSONTransform extends Visitor {
|
|
|
2002
2270
|
DESERIALIZE += " }";
|
|
2003
2271
|
mbElse = " else ";
|
|
2004
2272
|
}
|
|
2005
|
-
if (!STRICT ||
|
|
2273
|
+
if (!STRICT || slowBooleanMembers.length) {
|
|
2006
2274
|
DESERIALIZE += mbElse + "if (code == 116) {\n";
|
|
2007
2275
|
DESERIALIZE +=
|
|
2008
2276
|
" if (load<u64>(srcStart) == 28429475166421108) {\n";
|
|
@@ -2012,7 +2280,7 @@ export class JSONTransform extends Visitor {
|
|
|
2012
2280
|
' console.log("Value (bool, ' +
|
|
2013
2281
|
++id +
|
|
2014
2282
|
'): " + JSON.Util.ptrToStr(lastIndex, srcStart - 8));';
|
|
2015
|
-
generateGroups(
|
|
2283
|
+
generateGroups(slowBooleanMembers, (group) => {
|
|
2016
2284
|
generateConsts(group);
|
|
2017
2285
|
const first = group[0];
|
|
2018
2286
|
const fName = first.alias || first.name;
|
|
@@ -2024,27 +2292,7 @@ export class JSONTransform extends Visitor {
|
|
|
2024
2292
|
") { // " +
|
|
2025
2293
|
fName +
|
|
2026
2294
|
"\n";
|
|
2027
|
-
|
|
2028
|
-
first.type.startsWith("JSON.Box<boolean") ||
|
|
2029
|
-
first.type.startsWith("Box<bool") ||
|
|
2030
|
-
first.type.startsWith("Box<boolean")) {
|
|
2031
|
-
DESERIALIZE +=
|
|
2032
|
-
indent +
|
|
2033
|
-
" store<" +
|
|
2034
|
-
first.type +
|
|
2035
|
-
">(changetype<usize>(out), changetype<" +
|
|
2036
|
-
first.type +
|
|
2037
|
-
">(JSON.Box.from<bool>(true)), offsetof<this>(" +
|
|
2038
|
-
JSON.stringify(first.name) +
|
|
2039
|
-
"));\n";
|
|
2040
|
-
}
|
|
2041
|
-
else {
|
|
2042
|
-
DESERIALIZE +=
|
|
2043
|
-
indent +
|
|
2044
|
-
" store<boolean>(changetype<usize>(out), true, offsetof<this>(" +
|
|
2045
|
-
JSON.stringify(first.name) +
|
|
2046
|
-
"));\n";
|
|
2047
|
-
}
|
|
2295
|
+
DESERIALIZE += getSlowBooleanStore(first, "true", "srcStart - 8", "srcStart", indent + " ");
|
|
2048
2296
|
DESERIALIZE += indent + " srcStart += 2;\n";
|
|
2049
2297
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
2050
2298
|
DESERIALIZE += indent + " break;\n";
|
|
@@ -2060,27 +2308,7 @@ export class JSONTransform extends Visitor {
|
|
|
2060
2308
|
") { // " +
|
|
2061
2309
|
memName +
|
|
2062
2310
|
"\n";
|
|
2063
|
-
|
|
2064
|
-
mem.type.startsWith("JSON.Box<boolean") ||
|
|
2065
|
-
mem.type.startsWith("Box<bool") ||
|
|
2066
|
-
mem.type.startsWith("Box<boolean")) {
|
|
2067
|
-
DESERIALIZE +=
|
|
2068
|
-
indent +
|
|
2069
|
-
" store<" +
|
|
2070
|
-
mem.type +
|
|
2071
|
-
">(changetype<usize>(out), changetype<" +
|
|
2072
|
-
mem.type +
|
|
2073
|
-
">(JSON.Box.from<bool>(true)), offsetof<this>(" +
|
|
2074
|
-
JSON.stringify(mem.name) +
|
|
2075
|
-
"));\n";
|
|
2076
|
-
}
|
|
2077
|
-
else {
|
|
2078
|
-
DESERIALIZE +=
|
|
2079
|
-
indent +
|
|
2080
|
-
" store<boolean>(changetype<usize>(out), true, offsetof<this>(" +
|
|
2081
|
-
JSON.stringify(mem.name) +
|
|
2082
|
-
"));\n";
|
|
2083
|
-
}
|
|
2311
|
+
DESERIALIZE += getSlowBooleanStore(mem, "true", "srcStart - 8", "srcStart", indent + " ");
|
|
2084
2312
|
DESERIALIZE += indent + " srcStart += 2;\n";
|
|
2085
2313
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
2086
2314
|
DESERIALIZE += indent + " break;\n";
|
|
@@ -2116,7 +2344,7 @@ export class JSONTransform extends Visitor {
|
|
|
2116
2344
|
' console.log("Value (bool, ' +
|
|
2117
2345
|
++id +
|
|
2118
2346
|
'): " + JSON.Util.ptrToStr(lastIndex, srcStart - 10));';
|
|
2119
|
-
generateGroups(
|
|
2347
|
+
generateGroups(slowBooleanMembers, (group) => {
|
|
2120
2348
|
generateConsts(group);
|
|
2121
2349
|
const first = group[0];
|
|
2122
2350
|
const fName = first.alias || first.name;
|
|
@@ -2128,27 +2356,7 @@ export class JSONTransform extends Visitor {
|
|
|
2128
2356
|
") { // " +
|
|
2129
2357
|
fName +
|
|
2130
2358
|
"\n";
|
|
2131
|
-
|
|
2132
|
-
first.type.startsWith("JSON.Box<boolean") ||
|
|
2133
|
-
first.type.startsWith("Box<bool") ||
|
|
2134
|
-
first.type.startsWith("Box<boolean")) {
|
|
2135
|
-
DESERIALIZE +=
|
|
2136
|
-
indent +
|
|
2137
|
-
" store<" +
|
|
2138
|
-
first.type +
|
|
2139
|
-
">(changetype<usize>(out), changetype<" +
|
|
2140
|
-
first.type +
|
|
2141
|
-
">(JSON.Box.from<bool>(false)), offsetof<this>(" +
|
|
2142
|
-
JSON.stringify(first.name) +
|
|
2143
|
-
"));\n";
|
|
2144
|
-
}
|
|
2145
|
-
else {
|
|
2146
|
-
DESERIALIZE +=
|
|
2147
|
-
indent +
|
|
2148
|
-
" store<boolean>(changetype<usize>(out), false, offsetof<this>(" +
|
|
2149
|
-
JSON.stringify(first.name) +
|
|
2150
|
-
"));\n";
|
|
2151
|
-
}
|
|
2359
|
+
DESERIALIZE += getSlowBooleanStore(first, "false", "srcStart - 10", "srcStart", indent + " ");
|
|
2152
2360
|
DESERIALIZE += indent + " srcStart += 2;\n";
|
|
2153
2361
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
2154
2362
|
DESERIALIZE += indent + " break;\n";
|
|
@@ -2164,27 +2372,7 @@ export class JSONTransform extends Visitor {
|
|
|
2164
2372
|
") { // " +
|
|
2165
2373
|
memName +
|
|
2166
2374
|
"\n";
|
|
2167
|
-
|
|
2168
|
-
mem.type.startsWith("JSON.Box<boolean") ||
|
|
2169
|
-
mem.type.startsWith("Box<bool") ||
|
|
2170
|
-
mem.type.startsWith("Box<boolean")) {
|
|
2171
|
-
DESERIALIZE +=
|
|
2172
|
-
indent +
|
|
2173
|
-
" store<" +
|
|
2174
|
-
mem.type +
|
|
2175
|
-
">(changetype<usize>(out), changetype<" +
|
|
2176
|
-
mem.type +
|
|
2177
|
-
">(JSON.Box.from<bool>(false)), offsetof<this>(" +
|
|
2178
|
-
JSON.stringify(mem.name) +
|
|
2179
|
-
"));\n";
|
|
2180
|
-
}
|
|
2181
|
-
else {
|
|
2182
|
-
DESERIALIZE +=
|
|
2183
|
-
indent +
|
|
2184
|
-
" store<boolean>(changetype<usize>(out), false, offsetof<this>(" +
|
|
2185
|
-
JSON.stringify(mem.name) +
|
|
2186
|
-
"));\n";
|
|
2187
|
-
}
|
|
2375
|
+
DESERIALIZE += getSlowBooleanStore(mem, "false", "srcStart - 10", "srcStart", indent + " ");
|
|
2188
2376
|
DESERIALIZE += indent + " srcStart += 2;\n";
|
|
2189
2377
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
2190
2378
|
DESERIALIZE += indent + " break;\n";
|
|
@@ -2209,7 +2397,7 @@ export class JSONTransform extends Visitor {
|
|
|
2209
2397
|
DESERIALIZE += "\n }";
|
|
2210
2398
|
mbElse = " else ";
|
|
2211
2399
|
}
|
|
2212
|
-
if (!STRICT ||
|
|
2400
|
+
if (!STRICT || slowNullMembers.length) {
|
|
2213
2401
|
DESERIALIZE += mbElse + "if (code == 110) {\n";
|
|
2214
2402
|
DESERIALIZE +=
|
|
2215
2403
|
" if (load<u64>(srcStart) == 30399761348886638) {\n";
|
|
@@ -2219,7 +2407,7 @@ export class JSONTransform extends Visitor {
|
|
|
2219
2407
|
' console.log("Value (null, ' +
|
|
2220
2408
|
++id +
|
|
2221
2409
|
'): " + JSON.Util.ptrToStr(lastIndex, srcStart - 8));';
|
|
2222
|
-
generateGroups(
|
|
2410
|
+
generateGroups(slowNullMembers, (group) => {
|
|
2223
2411
|
generateConsts(group);
|
|
2224
2412
|
const first = group[0];
|
|
2225
2413
|
const fName = first.alias || first.name;
|
|
@@ -2231,11 +2419,7 @@ export class JSONTransform extends Visitor {
|
|
|
2231
2419
|
") { // " +
|
|
2232
2420
|
fName +
|
|
2233
2421
|
"\n";
|
|
2234
|
-
DESERIALIZE +=
|
|
2235
|
-
indent +
|
|
2236
|
-
" store<usize>(changetype<usize>(out), 0, offsetof<this>(" +
|
|
2237
|
-
JSON.stringify(first.name) +
|
|
2238
|
-
"));\n";
|
|
2422
|
+
DESERIALIZE += getSlowNullStore(first, "srcStart - 8", "srcStart", indent + " ");
|
|
2239
2423
|
DESERIALIZE += indent + " srcStart += 2;\n";
|
|
2240
2424
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
2241
2425
|
DESERIALIZE += indent + " break;\n";
|
|
@@ -2251,11 +2435,7 @@ export class JSONTransform extends Visitor {
|
|
|
2251
2435
|
") { // " +
|
|
2252
2436
|
memName +
|
|
2253
2437
|
"\n";
|
|
2254
|
-
DESERIALIZE +=
|
|
2255
|
-
indent +
|
|
2256
|
-
" store<usize>(changetype<usize>(out), 0, offsetof<this>(" +
|
|
2257
|
-
JSON.stringify(mem.name) +
|
|
2258
|
-
"));\n";
|
|
2438
|
+
DESERIALIZE += getSlowNullStore(mem, "srcStart - 8", "srcStart", indent + " ");
|
|
2259
2439
|
DESERIALIZE += indent + " srcStart += 2;\n";
|
|
2260
2440
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
2261
2441
|
DESERIALIZE += indent + " break;\n";
|
|
@@ -2308,6 +2488,11 @@ export class JSONTransform extends Visitor {
|
|
|
2308
2488
|
console.log(INITIALIZE);
|
|
2309
2489
|
console.log(DESERIALIZE_CUSTOM || DESERIALIZE);
|
|
2310
2490
|
}
|
|
2491
|
+
const WIDE_STRUCT_FIELD_LIMIT = 32;
|
|
2492
|
+
if (this.schema.members.length > WIDE_STRUCT_FIELD_LIMIT) {
|
|
2493
|
+
INITIALIZE = INITIALIZE.replace(/^@inline /, "");
|
|
2494
|
+
DESERIALIZE_FAST = DESERIALIZE_FAST.replace(/^@inline /, "");
|
|
2495
|
+
}
|
|
2311
2496
|
const SERIALIZE_METHOD = SimpleParser.parseClassMember(SERIALIZE_CUSTOM || SERIALIZE, node);
|
|
2312
2497
|
const INITIALIZE_METHOD = SimpleParser.parseClassMember(INITIALIZE, node);
|
|
2313
2498
|
const DESERIALIZE_CUSTOM_METHOD = DESERIALIZE_CUSTOM
|
|
@@ -2334,6 +2519,13 @@ export class JSONTransform extends Visitor {
|
|
|
2334
2519
|
DESERIALIZE_FAST_METHOD &&
|
|
2335
2520
|
!node.members.find((v) => v.name.text == "__DESERIALIZE_FAST"))
|
|
2336
2521
|
node.members.push(DESERIALIZE_FAST_METHOD);
|
|
2522
|
+
if (useFastPath && !DESERIALIZE_CUSTOM) {
|
|
2523
|
+
for (const chunk of fastChunkMethods) {
|
|
2524
|
+
const chunkMethod = SimpleParser.parseClassMember(chunk, node);
|
|
2525
|
+
if (!node.members.find((v) => v.name.text == chunkMethod.name.text))
|
|
2526
|
+
node.members.push(chunkMethod);
|
|
2527
|
+
}
|
|
2528
|
+
}
|
|
2337
2529
|
super.visitClassDeclaration(node);
|
|
2338
2530
|
}
|
|
2339
2531
|
getSchema(name) {
|
|
@@ -2343,9 +2535,9 @@ export class JSONTransform extends Visitor {
|
|
|
2343
2535
|
.find((s) => s.name == name) || null);
|
|
2344
2536
|
}
|
|
2345
2537
|
generateEmptyMethods(node) {
|
|
2346
|
-
const SERIALIZE_EMPTY = "
|
|
2347
|
-
const INITIALIZE_EMPTY = "
|
|
2348
|
-
const DESERIALIZE_SLOW_EMPTY = "
|
|
2538
|
+
const SERIALIZE_EMPTY = "__SERIALIZE(ptr: usize): void {\n bs.proposeSize(4);\n store<u32>(bs.offset, 8192123);\n bs.offset += 4;\n}";
|
|
2539
|
+
const INITIALIZE_EMPTY = "__INITIALIZE(): this {\n return this;\n}";
|
|
2540
|
+
const DESERIALIZE_SLOW_EMPTY = "__DESERIALIZE_SLOW<__JSON_T>(srcStart: usize, srcEnd: usize, out: __JSON_T): usize {\n return srcEnd;\n}";
|
|
2349
2541
|
if (DEBUG > 0) {
|
|
2350
2542
|
console.log(SERIALIZE_EMPTY);
|
|
2351
2543
|
console.log(INITIALIZE_EMPTY);
|
|
@@ -2521,9 +2713,11 @@ export class JSONTransform extends Visitor {
|
|
|
2521
2713
|
"Date",
|
|
2522
2714
|
"JSON.Value",
|
|
2523
2715
|
"JSON.Obj",
|
|
2716
|
+
"JSON.Arr",
|
|
2524
2717
|
"JSON.Raw",
|
|
2525
2718
|
"Value",
|
|
2526
2719
|
"Obj",
|
|
2720
|
+
"Arr",
|
|
2527
2721
|
"Raw",
|
|
2528
2722
|
...this.schemas
|
|
2529
2723
|
.get(this.schema.node.range.source.internalPath)
|
|
@@ -2552,25 +2746,8 @@ var JSONMode;
|
|
|
2552
2746
|
JSONMode[JSONMode["NAIVE"] = 2] = "NAIVE";
|
|
2553
2747
|
})(JSONMode || (JSONMode = {}));
|
|
2554
2748
|
let MODE = JSONMode.SWAR;
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
? JSONMode.SIMD
|
|
2558
|
-
: JSONMode.SWAR;
|
|
2559
|
-
if (process.env["JSON_MODE"]) {
|
|
2560
|
-
switch (process.env["JSON_MODE"].toLowerCase().trim()) {
|
|
2561
|
-
case "simd":
|
|
2562
|
-
mode = JSONMode.SIMD;
|
|
2563
|
-
break;
|
|
2564
|
-
case "swar":
|
|
2565
|
-
mode = JSONMode.SWAR;
|
|
2566
|
-
break;
|
|
2567
|
-
case "naive":
|
|
2568
|
-
mode = JSONMode.NAIVE;
|
|
2569
|
-
break;
|
|
2570
|
-
}
|
|
2571
|
-
}
|
|
2572
|
-
return mode;
|
|
2573
|
-
}
|
|
2749
|
+
let MODE_TEXT = "SWAR";
|
|
2750
|
+
const STAGES = process.env["JSON_STAGES"] !== undefined;
|
|
2574
2751
|
export default class Transformer extends Transform {
|
|
2575
2752
|
afterInitialize(program) {
|
|
2576
2753
|
if (program.options.hasFeature(16))
|
|
@@ -2591,6 +2768,21 @@ export default class Transformer extends Transform {
|
|
|
2591
2768
|
}
|
|
2592
2769
|
}
|
|
2593
2770
|
}
|
|
2771
|
+
switch (MODE) {
|
|
2772
|
+
case JSONMode.SWAR:
|
|
2773
|
+
MODE_TEXT = "SWAR";
|
|
2774
|
+
break;
|
|
2775
|
+
case JSONMode.SIMD:
|
|
2776
|
+
MODE_TEXT = "SIMD";
|
|
2777
|
+
break;
|
|
2778
|
+
case JSONMode.NAIVE:
|
|
2779
|
+
MODE_TEXT = "NAIVE";
|
|
2780
|
+
break;
|
|
2781
|
+
}
|
|
2782
|
+
if (STAGES)
|
|
2783
|
+
console.log("[transform]: Finished initializing transformer in " +
|
|
2784
|
+
MODE_TEXT +
|
|
2785
|
+
" mode");
|
|
2594
2786
|
program.registerConstantInteger("JSON_MODE", Type.i32, i64_new(MODE));
|
|
2595
2787
|
if (JSON_CACHE_CONFIG.enabled) {
|
|
2596
2788
|
program.registerConstantInteger("JSON_CACHE", Type.bool, i64_one);
|
|
@@ -2599,6 +2791,8 @@ export default class Transformer extends Transform {
|
|
|
2599
2791
|
}
|
|
2600
2792
|
afterParse(parser) {
|
|
2601
2793
|
const transformer = new JSONTransform();
|
|
2794
|
+
if (STAGES)
|
|
2795
|
+
console.log("[transform]: Walking AST and generating schemas");
|
|
2602
2796
|
const sources = parser.sources
|
|
2603
2797
|
.filter((source) => {
|
|
2604
2798
|
const p = source.internalPath;
|
|
@@ -2648,22 +2842,17 @@ export default class Transformer extends Transform {
|
|
|
2648
2842
|
writeFileSync(path.join(process.cwd(), this.baseDir, removeExtension(source.normalizedPath) + ".tmp.ts"), toString(source));
|
|
2649
2843
|
}
|
|
2650
2844
|
}
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
const bMove = b.flags.has(PropertyFlags.OmitIf) || b.flags.has(PropertyFlags.OmitNull);
|
|
2657
|
-
if (aMove && !bMove) {
|
|
2658
|
-
return -1;
|
|
2659
|
-
}
|
|
2660
|
-
else if (!aMove && bMove) {
|
|
2661
|
-
return 1;
|
|
2662
|
-
}
|
|
2663
|
-
else {
|
|
2664
|
-
return 0;
|
|
2845
|
+
for (const source of parser.sources) {
|
|
2846
|
+
const p = source.internalPath;
|
|
2847
|
+
if (p === "assembly/index" || p.endsWith("/json-as/assembly/index")) {
|
|
2848
|
+
source.sourceKind = 2;
|
|
2849
|
+
}
|
|
2665
2850
|
}
|
|
2666
|
-
|
|
2851
|
+
if (STAGES)
|
|
2852
|
+
console.log("[transform]: Finished generating " +
|
|
2853
|
+
transformer.schemas.size +
|
|
2854
|
+
" schemas");
|
|
2855
|
+
}
|
|
2667
2856
|
}
|
|
2668
2857
|
function toU16(data, offset = 0) {
|
|
2669
2858
|
return data.charCodeAt(offset + 0);
|
|
@@ -2808,6 +2997,92 @@ function sizeof(type) {
|
|
|
2808
2997
|
else
|
|
2809
2998
|
return 0;
|
|
2810
2999
|
}
|
|
3000
|
+
function classLazyMode(node) {
|
|
3001
|
+
const dec = node.decorators?.find((d) => {
|
|
3002
|
+
const n = d.name.text;
|
|
3003
|
+
return n === "json" || n === "serializable";
|
|
3004
|
+
});
|
|
3005
|
+
if (!dec || !dec.args || dec.args.length === 0)
|
|
3006
|
+
return "none";
|
|
3007
|
+
const arg = dec.args[0];
|
|
3008
|
+
if (arg.kind !== NodeKind.Literal ||
|
|
3009
|
+
arg.literalKind !== 6)
|
|
3010
|
+
return "none";
|
|
3011
|
+
const obj = arg;
|
|
3012
|
+
for (let i = 0; i < obj.names.length; i++) {
|
|
3013
|
+
if (obj.names[i].text !== "lazy")
|
|
3014
|
+
continue;
|
|
3015
|
+
const v = obj.values[i];
|
|
3016
|
+
if (v.kind === NodeKind.Literal &&
|
|
3017
|
+
v.literalKind === 2) {
|
|
3018
|
+
const s = v.value;
|
|
3019
|
+
if (s === "none" || s === "auto" || s === "all")
|
|
3020
|
+
return s;
|
|
3021
|
+
}
|
|
3022
|
+
throwError(`@json lazy must be "none", "auto", or "all"`, v.range);
|
|
3023
|
+
}
|
|
3024
|
+
return "none";
|
|
3025
|
+
}
|
|
3026
|
+
const LAZY_AUTO_THRESHOLD = 10;
|
|
3027
|
+
function lazyTypeCost(type, source, parser) {
|
|
3028
|
+
const base = stripNull(type);
|
|
3029
|
+
if (isPrimitive(base) || isBoolean(base) || isEnum(base, source, parser))
|
|
3030
|
+
return 1;
|
|
3031
|
+
if (base === "Date")
|
|
3032
|
+
return 4;
|
|
3033
|
+
if (isString(base))
|
|
3034
|
+
return 10;
|
|
3035
|
+
if (base === "JSON.Value" ||
|
|
3036
|
+
base === "Value" ||
|
|
3037
|
+
base === "JSON.Obj" ||
|
|
3038
|
+
base === "Obj" ||
|
|
3039
|
+
base === "JSON.Arr" ||
|
|
3040
|
+
base === "Arr" ||
|
|
3041
|
+
base === "JSON.Raw" ||
|
|
3042
|
+
base === "Raw")
|
|
3043
|
+
return 15;
|
|
3044
|
+
return 20;
|
|
3045
|
+
}
|
|
3046
|
+
function lazyAutoCost(type, source, parser) {
|
|
3047
|
+
const direct = lazyTypeCost(type, source, parser);
|
|
3048
|
+
if (direct < 20)
|
|
3049
|
+
return direct;
|
|
3050
|
+
const decl = source.getClass(stripNull(type));
|
|
3051
|
+
if (!decl)
|
|
3052
|
+
return 20;
|
|
3053
|
+
let sum = 0;
|
|
3054
|
+
for (let i = 0; i < decl.members.length; i++) {
|
|
3055
|
+
const m = decl.members[i];
|
|
3056
|
+
if (m.kind !== NodeKind.FieldDeclaration)
|
|
3057
|
+
continue;
|
|
3058
|
+
const fd = m;
|
|
3059
|
+
if (fd.is(32) ||
|
|
3060
|
+
fd.is(512) ||
|
|
3061
|
+
fd.is(1024) ||
|
|
3062
|
+
!fd.type)
|
|
3063
|
+
continue;
|
|
3064
|
+
sum += lazyTypeCost(toString(fd.type), source, parser);
|
|
3065
|
+
if (sum >= LAZY_AUTO_THRESHOLD)
|
|
3066
|
+
return sum;
|
|
3067
|
+
}
|
|
3068
|
+
return sum;
|
|
3069
|
+
}
|
|
3070
|
+
function lazyWrapperInner(typeNode) {
|
|
3071
|
+
if (!typeNode || typeNode.kind !== NodeKind.NamedType)
|
|
3072
|
+
return null;
|
|
3073
|
+
const named = typeNode;
|
|
3074
|
+
let seg = named.name;
|
|
3075
|
+
while (seg.next)
|
|
3076
|
+
seg = seg.next;
|
|
3077
|
+
if (seg.identifier.text !== "Lazy")
|
|
3078
|
+
return null;
|
|
3079
|
+
if (!named.typeArguments || named.typeArguments.length !== 1)
|
|
3080
|
+
return null;
|
|
3081
|
+
let inner = toString(named.typeArguments[0]).trim();
|
|
3082
|
+
if (named.isNullable && !inner.endsWith("null"))
|
|
3083
|
+
inner += " | null";
|
|
3084
|
+
return inner;
|
|
3085
|
+
}
|
|
2811
3086
|
function estimatedSerializedByteSize(type, source, parser) {
|
|
2812
3087
|
const trimmed = type.trim();
|
|
2813
3088
|
const baseType = stripNull(trimmed);
|
|
@@ -2828,6 +3103,8 @@ function estimatedSerializedByteSize(type, source, parser) {
|
|
|
2828
3103
|
}
|
|
2829
3104
|
else if (baseType == "JSON.Obj" ||
|
|
2830
3105
|
baseType == "Obj" ||
|
|
3106
|
+
baseType == "JSON.Arr" ||
|
|
3107
|
+
baseType == "Arr" ||
|
|
2831
3108
|
baseType == "JSON.Raw" ||
|
|
2832
3109
|
baseType == "Raw" ||
|
|
2833
3110
|
baseType == "JSON.Value" ||
|
|
@@ -2886,6 +3163,21 @@ export function stripNull(type) {
|
|
|
2886
3163
|
}
|
|
2887
3164
|
return type;
|
|
2888
3165
|
}
|
|
3166
|
+
function sortMembers(members) {
|
|
3167
|
+
return members.sort((a, b) => {
|
|
3168
|
+
const aMove = a.flags.has(PropertyFlags.OmitIf) || a.flags.has(PropertyFlags.OmitNull);
|
|
3169
|
+
const bMove = b.flags.has(PropertyFlags.OmitIf) || b.flags.has(PropertyFlags.OmitNull);
|
|
3170
|
+
if (aMove && !bMove) {
|
|
3171
|
+
return -1;
|
|
3172
|
+
}
|
|
3173
|
+
else if (!aMove && bMove) {
|
|
3174
|
+
return 1;
|
|
3175
|
+
}
|
|
3176
|
+
else {
|
|
3177
|
+
return 0;
|
|
3178
|
+
}
|
|
3179
|
+
});
|
|
3180
|
+
}
|
|
2889
3181
|
function getComparison(data) {
|
|
2890
3182
|
switch (data.length << 1) {
|
|
2891
3183
|
case 2: {
|
|
@@ -2905,4 +3197,3 @@ function getComparison(data) {
|
|
|
2905
3197
|
}
|
|
2906
3198
|
}
|
|
2907
3199
|
}
|
|
2908
|
-
//# sourceMappingURL=index.js.map
|