json-as 1.3.2 → 1.3.3

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.
@@ -13,7 +13,59 @@ const WRITE = process.env["JSON_WRITE"]?.trim();
13
13
  const rawValue = process.env["JSON_DEBUG"]?.trim();
14
14
  const DEBUG = rawValue === "true" ? 1 : rawValue === "false" || rawValue === "" ? 0 : isNaN(Number(rawValue)) ? 0 : Number(rawValue);
15
15
  const STRICT = process.env["JSON_STRICT"] && process.env["JSON_STRICT"] == "true";
16
- const USE_FAST_PATH = process.env["JSON_USE_FAST_PATH"]?.trim() === "1";
16
+ const DEFAULT_JSON_CACHE_BYTES = 1 << 20;
17
+ function envFlagDefaultTrue(value) {
18
+ if (!value)
19
+ return true;
20
+ switch (value.trim().toLowerCase()) {
21
+ case "0":
22
+ case "false":
23
+ case "off":
24
+ case "no":
25
+ return false;
26
+ default:
27
+ return true;
28
+ }
29
+ }
30
+ const USE_FAST_PATH = envFlagDefaultTrue(process.env["JSON_USE_FAST_PATH"]);
31
+ const THROW_FAST_PATH = process.env["JSON_FAST_PATH_THROW"]?.trim() === "1";
32
+ function parseJSONCacheConfig(value) {
33
+ if (!value)
34
+ return { enabled: false, bytes: 0 };
35
+ const raw = value.trim();
36
+ if (!raw)
37
+ return { enabled: false, bytes: 0 };
38
+ const lower = raw.toLowerCase();
39
+ if (lower === "false" || lower === "off" || lower === "no" || lower === "none" || lower === "0") {
40
+ return { enabled: false, bytes: 0 };
41
+ }
42
+ if (lower === "true" || lower === "on" || lower === "yes") {
43
+ return { enabled: true, bytes: DEFAULT_JSON_CACHE_BYTES };
44
+ }
45
+ const match = /^(\d+)\s*([kKmMgG]?[bB])?$/.exec(raw);
46
+ if (!match) {
47
+ throw new Error(`Invalid JSON_CACHE value '${value}'. Expected true/false or <int>[kb|mb|gb|KB|MB|GB].`);
48
+ }
49
+ const amount = Number(match[1]);
50
+ const suffix = match[2] || "B";
51
+ if (!Number.isFinite(amount)) {
52
+ throw new Error(`Invalid JSON_CACHE value '${value}'.`);
53
+ }
54
+ const unit = suffix[0];
55
+ const scale = unit == "k" || unit == "K" ? 1_000 : unit == "m" || unit == "M" ? 1_000_000 : unit == "g" || unit == "G" ? 1_000_000_000 : 1;
56
+ let bytes = amount * scale;
57
+ if (suffix.endsWith("b")) {
58
+ bytes = Math.ceil(bytes / 8);
59
+ }
60
+ if (bytes <= 0) {
61
+ return { enabled: false, bytes: 0 };
62
+ }
63
+ if (bytes > 0xffff_ffff) {
64
+ throw new Error(`JSON_CACHE value '${value}' is too large (max 4GB).`);
65
+ }
66
+ return { enabled: true, bytes: Math.floor(bytes) };
67
+ }
68
+ const JSON_CACHE_CONFIG = parseJSONCacheConfig(process.env["JSON_CACHE"]);
17
69
  function needsReferenceLoad(type) {
18
70
  return type == "ArrayBuffer" || type == "Int8Array" || type == "Uint8Array" || type == "Uint8ClampedArray" || type == "Int16Array" || type == "Uint16Array" || type == "Int32Array" || type == "Uint32Array" || type == "Int64Array" || type == "Uint64Array" || type == "Float32Array" || type == "Float64Array";
19
71
  }
@@ -671,6 +723,11 @@ export class JSONTransform extends Visitor {
671
723
  const FLOAT_TYPES = ["f32", "f64"];
672
724
  const INTEGER_TYPES = [...UNSIGNED_INTEGER_TYPES, ...SIGNED_INTEGER_TYPES];
673
725
  const STRING_FIELD_DESERIALIZER = codegenMode === JSONMode.SIMD ? "deserializeStringField_SIMD" : "deserializeStringField_SWAR";
726
+ const getArrayValueType = (type) => {
727
+ if (!type.startsWith("Array<") && !type.startsWith("StaticArray<"))
728
+ return null;
729
+ return stripNull(type.slice(type.indexOf("<") + 1, -1).trim());
730
+ };
674
731
  const getDeserializer = (type, srcPtr, outPtr, member, keyOffset = 0, fastPath = false) => {
675
732
  const out = [];
676
733
  const resolvedType = stripNull(type);
@@ -800,7 +857,24 @@ export class JSONTransform extends Visitor {
800
857
  }
801
858
  else if (resolvedSchema && !resolvedSchema.custom) {
802
859
  if (fastPath) {
803
- out.push("break;");
860
+ out.push("{");
861
+ if (member.node.type.isNullable) {
862
+ out.push(` if (load<u64>(${valuePtr}) == 30399761348886638) {`);
863
+ out.push(` store<${resolvedType}>(${outPtr}, changetype<${resolvedType}>(0), ${fieldOffset});`);
864
+ out.push(` ${srcPtr} = ${valuePtr} + 8;`);
865
+ out.push(" } else {");
866
+ }
867
+ out.push(` let value = load<${resolvedType}>(${outPtr}, ${fieldOffset});`);
868
+ out.push(` if (changetype<usize>(value) == 0) {`);
869
+ out.push(` value = changetype<${resolvedType}>(__new(offsetof<nonnull<${resolvedType}>>(), idof<nonnull<${resolvedType}>>()));`);
870
+ out.push(` store<${resolvedType}>(${outPtr}, value, ${fieldOffset});`);
871
+ out.push(" }");
872
+ out.push(` ${srcPtr} = changetype<nonnull<${resolvedType}>>(value).__DESERIALIZE_FAST<${resolvedType}>(${valuePtr}, srcEnd, value);`);
873
+ out.push(` if (!${srcPtr}) break;`);
874
+ if (member.node.type.isNullable) {
875
+ out.push(" }");
876
+ }
877
+ out.push("}");
804
878
  return out;
805
879
  }
806
880
  out.push("{");
@@ -830,6 +904,7 @@ export class JSONTransform extends Visitor {
830
904
  out.push("}");
831
905
  }
832
906
  else if (resolvedType.startsWith("Array<")) {
907
+ const valueType = getArrayValueType(resolvedType);
833
908
  out.push("{");
834
909
  if (member.node.type.isNullable) {
835
910
  out.push(` if (load<u64>(${valuePtr}) == 30399761348886638) {`);
@@ -837,23 +912,96 @@ export class JSONTransform extends Visitor {
837
912
  out.push(` ${srcPtr} = ${valuePtr} + 8;`);
838
913
  out.push(" } else {");
839
914
  }
840
- out.push(` if (load<u16>(${valuePtr}) == 0x5b && load<u16>(${valuePtr}, 2) == 0x5d) {`);
841
- out.push(` let value = load<${resolvedType}>(${outPtr}, ${fieldOffset});`);
842
- if (member.node.type.isNullable) {
843
- out.push(` if (changetype<usize>(value) == 0) {`);
844
- out.push(` value = changetype<${resolvedType}>(instantiate<nonnull<${resolvedType}>>());`);
845
- out.push(` store<${resolvedType}>(${outPtr}, value, ${fieldOffset});`);
915
+ if (fastPath && valueType && ["string", "String"].includes(valueType)) {
916
+ out.push(` if (load<u16>(${valuePtr}) != 0x5b) break;`);
917
+ out.push(` let value = load<${resolvedType}>(${outPtr}, ${fieldOffset});`);
918
+ out.push(" if (changetype<usize>(value) == 0) {");
919
+ out.push(` value = instantiate<nonnull<${resolvedType}>>();`);
920
+ out.push(` store<${resolvedType}>(${outPtr}, value, ${fieldOffset});`);
921
+ out.push(" }");
922
+ out.push(" let index = 0;");
923
+ out.push(` ${srcPtr} = ${valuePtr} + 2;`);
924
+ out.push(` if (load<u16>(${srcPtr}) == 0x5d) {`);
925
+ out.push(" value.length = 0;");
926
+ out.push(` ${srcPtr} += 2;`);
927
+ out.push(" } else while (true) {");
928
+ out.push(' if (index >= value.length) value.push("");');
929
+ out.push(` ${srcPtr} = ${STRING_FIELD_DESERIALIZER}<${valueType}>(${srcPtr}, srcEnd, value.dataStart + ((<usize>index) << alignof<${valueType}>()));`);
930
+ out.push(" index++;");
931
+ out.push(` const code = load<u16>(${srcPtr});`);
932
+ out.push(" if (code == 0x2c) {");
933
+ out.push(` ${srcPtr} += 2;`);
934
+ out.push(" continue;");
935
+ out.push(" }");
936
+ out.push(" if (code == 0x5d) {");
937
+ out.push(" value.length = index;");
938
+ out.push(` ${srcPtr} += 2;`);
939
+ out.push(" break;");
846
940
  out.push(" }");
941
+ out.push(" break;");
942
+ out.push(" }");
943
+ if (member.node.type.isNullable) {
944
+ out.push(" }");
945
+ }
946
+ out.push("}");
947
+ return out;
847
948
  }
949
+ const valueSchema = valueType ? this.getSchema(valueType) : null;
950
+ if (fastPath && valueType && valueSchema && !valueSchema.custom) {
951
+ out.push(` if (load<u16>(${valuePtr}) != 0x5b) break;`);
952
+ out.push(` let value = load<${resolvedType}>(${outPtr}, ${fieldOffset});`);
953
+ out.push(" if (changetype<usize>(value) == 0) {");
954
+ out.push(` value = instantiate<nonnull<${resolvedType}>>();`);
955
+ out.push(` store<${resolvedType}>(${outPtr}, value, ${fieldOffset});`);
956
+ out.push(" }");
957
+ out.push(" let index = 0;");
958
+ out.push(` ${srcPtr} = ${valuePtr} + 2;`);
959
+ out.push(` if (load<u16>(${srcPtr}) == 0x5d) {`);
960
+ out.push(" value.length = 0;");
961
+ out.push(` ${srcPtr} += 2;`);
962
+ out.push(" } else while (true) {");
963
+ out.push(` let item: ${valueType};`);
964
+ out.push(" if (index < value.length) {");
965
+ out.push(" item = unchecked(value[index]);");
966
+ out.push(" if (changetype<usize>(item) == 0) {");
967
+ out.push(` item = changetype<${valueType}>(__new(offsetof<nonnull<${valueType}>>(), idof<nonnull<${valueType}>>()));`);
968
+ out.push(" unchecked((value[index] = item));");
969
+ out.push(" }");
970
+ out.push(" } else {");
971
+ out.push(` item = changetype<${valueType}>(__new(offsetof<nonnull<${valueType}>>(), idof<nonnull<${valueType}>>()));`);
972
+ out.push(" value.push(item);");
973
+ out.push(" }");
974
+ out.push(` ${srcPtr} = changetype<nonnull<${valueType}>>(item).__DESERIALIZE_FAST<${valueType}>(${srcPtr}, srcEnd, item);`);
975
+ out.push(` if (!${srcPtr}) break;`);
976
+ out.push(" index++;");
977
+ out.push(` const code = load<u16>(${srcPtr});`);
978
+ out.push(" if (code == 0x2c) {");
979
+ out.push(` ${srcPtr} += 2;`);
980
+ out.push(" continue;");
981
+ out.push(" }");
982
+ out.push(" if (code == 0x5d) {");
983
+ out.push(" value.length = index;");
984
+ out.push(` ${srcPtr} += 2;`);
985
+ out.push(" break;");
986
+ out.push(" }");
987
+ out.push(" break;");
988
+ out.push(" }");
989
+ if (member.node.type.isNullable) {
990
+ out.push(" }");
991
+ }
992
+ out.push("}");
993
+ return out;
994
+ }
995
+ out.push(` let value = load<${resolvedType}>(${outPtr}, ${fieldOffset});`);
996
+ out.push(` if (changetype<usize>(value) == 0) {`);
997
+ out.push(` value = changetype<${resolvedType}>(instantiate<nonnull<${resolvedType}>>());`);
998
+ out.push(` store<${resolvedType}>(${outPtr}, value, ${fieldOffset});`);
999
+ out.push(" }");
1000
+ out.push(` if (load<u16>(${valuePtr}) == 0x5b && load<u16>(${valuePtr}, 2) == 0x5d) {`);
848
1001
  out.push(" value.length = 0;");
849
1002
  out.push(` ${srcPtr} = ${valuePtr} + 4;`);
850
1003
  out.push(" } else {");
851
- if (member.node.type.isNullable) {
852
- out.push(` ${srcPtr} = deserializeArrayField_SWAR<${resolvedType}>(${valuePtr}, srcEnd, ${outPtr}, ${fieldOffset});`);
853
- }
854
- else {
855
- out.push(` ${srcPtr} = deserializeArrayInto_SWAR<${resolvedType}>(${valuePtr}, srcEnd, load<${resolvedType}>(${outPtr}, ${fieldOffset}));`);
856
- }
1004
+ out.push(` ${srcPtr} = deserializeArrayInto_SWAR<${resolvedType}>(${valuePtr}, srcEnd, value);`);
857
1005
  out.push(` if (!${srcPtr}) break;`);
858
1006
  out.push(" }");
859
1007
  if (member.node.type.isNullable) {
@@ -865,6 +1013,16 @@ export class JSONTransform extends Visitor {
865
1013
  if (member.node.type.isNullable) {
866
1014
  out.push(`${srcPtr} = deserializeMapField<${resolvedType}>(${srcPtr}, srcEnd, ${outPtr}, ${fieldOffset});`);
867
1015
  }
1016
+ else if (fastPath) {
1017
+ out.push("{");
1018
+ out.push(` let value = load<${resolvedType}>(${outPtr}, ${fieldOffset});`);
1019
+ out.push(" if (changetype<usize>(value) == 0) {");
1020
+ out.push(` value = new ${resolvedType}();`);
1021
+ out.push(` store<${resolvedType}>(${outPtr}, value, ${fieldOffset});`);
1022
+ out.push(" }");
1023
+ out.push(` ${srcPtr} = deserializeMapInto<${resolvedType}>(${srcPtr}, srcEnd, value);`);
1024
+ out.push("}");
1025
+ }
868
1026
  else {
869
1027
  out.push(`${srcPtr} = deserializeMapInto<${resolvedType}>(${srcPtr}, srcEnd, load<${resolvedType}>(${outPtr}, ${fieldOffset}));`);
870
1028
  }
@@ -874,6 +1032,16 @@ export class JSONTransform extends Visitor {
874
1032
  if (member.node.type.isNullable) {
875
1033
  out.push(`${srcPtr} = deserializeSetField<${resolvedType}>(${srcPtr}, srcEnd, ${outPtr}, ${fieldOffset});`);
876
1034
  }
1035
+ else if (fastPath) {
1036
+ out.push("{");
1037
+ out.push(` let value = load<${resolvedType}>(${outPtr}, ${fieldOffset});`);
1038
+ out.push(" if (changetype<usize>(value) == 0) {");
1039
+ out.push(` value = new ${resolvedType}();`);
1040
+ out.push(` store<${resolvedType}>(${outPtr}, value, ${fieldOffset});`);
1041
+ out.push(" }");
1042
+ out.push(` ${srcPtr} = deserializeSetInto<${resolvedType}>(${srcPtr}, srcEnd, value);`);
1043
+ out.push("}");
1044
+ }
877
1045
  else {
878
1046
  out.push(`${srcPtr} = deserializeSetInto<${resolvedType}>(${srcPtr}, srcEnd, load<${resolvedType}>(${outPtr}, ${fieldOffset}));`);
879
1047
  }
@@ -893,6 +1061,7 @@ export class JSONTransform extends Visitor {
893
1061
  };
894
1062
  indent = " ";
895
1063
  DESERIALIZE_FAST += indent + "const start = srcStart;\n";
1064
+ DESERIALIZE_FAST += indent + "const dst = changetype<usize>(out);\n";
896
1065
  DESERIALIZE_FAST += indent + "do {\n";
897
1066
  indent += " ";
898
1067
  if (supportsFastOptionalPath) {
@@ -910,8 +1079,8 @@ export class JSONTransform extends Visitor {
910
1079
  const nextKeyOffset = nextKeySection.length << 1;
911
1080
  const resolvedType = stripNull(member.type);
912
1081
  const inlineStringValue = ["string", "String"].includes(resolvedType);
913
- const deserializerFirst = getDeserializer(member.type, "srcStart", "changetype<usize>(out)", member, inlineStringValue ? firstKeyOffset : 0, true);
914
- const deserializerNext = getDeserializer(member.type, "srcStart", "changetype<usize>(out)", member, inlineStringValue ? nextKeyOffset : 0, true);
1082
+ const deserializerFirst = getDeserializer(member.type, "srcStart", "dst", member, inlineStringValue ? firstKeyOffset : 0, true);
1083
+ const deserializerNext = getDeserializer(member.type, "srcStart", "dst", member, inlineStringValue ? nextKeyOffset : 0, true);
915
1084
  const isOptional = member.flags.has(PropertyFlags.OmitNull) || member.flags.has(PropertyFlags.OmitIf);
916
1085
  if (!deserializerFirst.length || !deserializerNext.length) {
917
1086
  DESERIALIZE_FAST += indent + "break;\n\n";
@@ -973,7 +1142,7 @@ export class JSONTransform extends Visitor {
973
1142
  if (!inlineStringValue) {
974
1143
  DESERIALIZE_FAST += indent + `srcStart += ${keyOffset};\n\n`;
975
1144
  }
976
- const deserializer = getDeserializer(member.type, "srcStart", "changetype<usize>(out)", member, inlineStringValue ? keyOffset : 0, true);
1145
+ const deserializer = getDeserializer(member.type, "srcStart", "dst", member, inlineStringValue ? keyOffset : 0, true);
977
1146
  if (!deserializer.length) {
978
1147
  DESERIALIZE_FAST += indent + "break;\n\n";
979
1148
  continue;
@@ -986,9 +1155,14 @@ export class JSONTransform extends Visitor {
986
1155
  DESERIALIZE_FAST += indent + "return srcStart;\n";
987
1156
  indent = indent.slice(0, -2);
988
1157
  DESERIALIZE_FAST += indent + "} while (false);\n\n";
989
- DESERIALIZE_FAST += indent + "if (isDefined(out.__INITIALIZE)) out.__INITIALIZE();\n";
990
- DESERIALIZE_FAST += indent + "const end = JSON.Util.scanValueEnd(start, srcEnd);\n";
991
- DESERIALIZE_FAST += indent + "return out.__DESERIALIZE_SLOW(start, end ? end : srcEnd, out);";
1158
+ if (THROW_FAST_PATH) {
1159
+ DESERIALIZE_FAST += indent + "const failAt = srcStart ? srcStart : start;\n";
1160
+ DESERIALIZE_FAST += indent + "const failEnd = failAt + 160 < srcEnd ? failAt + 160 : srcEnd;\n";
1161
+ DESERIALIZE_FAST += indent + `throw new Error("Fast path failed for ${this.schema.name} at char offset " + ((failAt - start) >> 1).toString() + " near: " + JSON.Util.ptrToStr(failAt, failEnd));`;
1162
+ }
1163
+ else {
1164
+ DESERIALIZE_FAST += indent + "return 0;";
1165
+ }
992
1166
  indent = indent.slice(0, -2);
993
1167
  DESERIALIZE_FAST += indent + "}";
994
1168
  DESERIALIZE += indent + " let keyStart: usize = 0;\n";
@@ -1322,15 +1496,7 @@ export class JSONTransform extends Visitor {
1322
1496
  const fName = first.alias || first.name;
1323
1497
  DESERIALIZE += indent + " if (" + (first.generic ? "isBoolean<" + first.type + ">() && " : "") + getComparison(fName) + ") { // " + fName + "\n";
1324
1498
  if (first.type.startsWith("JSON.Box<bool") || first.type.startsWith("JSON.Box<boolean") || first.type.startsWith("Box<bool") || first.type.startsWith("Box<boolean")) {
1325
- DESERIALIZE +=
1326
- indent +
1327
- " store<" +
1328
- first.type +
1329
- ">(changetype<usize>(out), changetype<" +
1330
- first.type +
1331
- ">(JSON.Box.from<bool>(true)), offsetof<this>(" +
1332
- JSON.stringify(first.name) +
1333
- "));\n";
1499
+ DESERIALIZE += indent + " store<" + first.type + ">(changetype<usize>(out), changetype<" + first.type + ">(JSON.Box.from<bool>(true)), offsetof<this>(" + JSON.stringify(first.name) + "));\n";
1334
1500
  }
1335
1501
  else {
1336
1502
  DESERIALIZE += indent + " store<boolean>(changetype<usize>(out), true, offsetof<this>(" + JSON.stringify(first.name) + "));\n";
@@ -1344,15 +1510,7 @@ export class JSONTransform extends Visitor {
1344
1510
  const memName = mem.alias || mem.name;
1345
1511
  DESERIALIZE += indent + " else if (" + (mem.generic ? "isBoolean<" + mem.type + ">() && " : "") + getComparison(memName) + ") { // " + memName + "\n";
1346
1512
  if (mem.type.startsWith("JSON.Box<bool") || mem.type.startsWith("JSON.Box<boolean") || mem.type.startsWith("Box<bool") || mem.type.startsWith("Box<boolean")) {
1347
- DESERIALIZE +=
1348
- indent +
1349
- " store<" +
1350
- mem.type +
1351
- ">(changetype<usize>(out), changetype<" +
1352
- mem.type +
1353
- ">(JSON.Box.from<bool>(true)), offsetof<this>(" +
1354
- JSON.stringify(mem.name) +
1355
- "));\n";
1513
+ DESERIALIZE += indent + " store<" + mem.type + ">(changetype<usize>(out), changetype<" + mem.type + ">(JSON.Box.from<bool>(true)), offsetof<this>(" + JSON.stringify(mem.name) + "));\n";
1356
1514
  }
1357
1515
  else {
1358
1516
  DESERIALIZE += indent + " store<boolean>(changetype<usize>(out), true, offsetof<this>(" + JSON.stringify(mem.name) + "));\n";
@@ -1392,15 +1550,7 @@ export class JSONTransform extends Visitor {
1392
1550
  const fName = first.alias || first.name;
1393
1551
  DESERIALIZE += indent + " if (" + (first.generic ? "isBoolean<" + first.type + ">() && " : "") + getComparison(fName) + ") { // " + fName + "\n";
1394
1552
  if (first.type.startsWith("JSON.Box<bool") || first.type.startsWith("JSON.Box<boolean") || first.type.startsWith("Box<bool") || first.type.startsWith("Box<boolean")) {
1395
- DESERIALIZE +=
1396
- indent +
1397
- " store<" +
1398
- first.type +
1399
- ">(changetype<usize>(out), changetype<" +
1400
- first.type +
1401
- ">(JSON.Box.from<bool>(false)), offsetof<this>(" +
1402
- JSON.stringify(first.name) +
1403
- "));\n";
1553
+ DESERIALIZE += indent + " store<" + first.type + ">(changetype<usize>(out), changetype<" + first.type + ">(JSON.Box.from<bool>(false)), offsetof<this>(" + JSON.stringify(first.name) + "));\n";
1404
1554
  }
1405
1555
  else {
1406
1556
  DESERIALIZE += indent + " store<boolean>(changetype<usize>(out), false, offsetof<this>(" + JSON.stringify(first.name) + "));\n";
@@ -1414,15 +1564,7 @@ export class JSONTransform extends Visitor {
1414
1564
  const memName = mem.alias || mem.name;
1415
1565
  DESERIALIZE += indent + " else if (" + (mem.generic ? "isBoolean<" + mem.type + ">() && " : "") + getComparison(memName) + ") { // " + memName + "\n";
1416
1566
  if (mem.type.startsWith("JSON.Box<bool") || mem.type.startsWith("JSON.Box<boolean") || mem.type.startsWith("Box<bool") || mem.type.startsWith("Box<boolean")) {
1417
- DESERIALIZE +=
1418
- indent +
1419
- " store<" +
1420
- mem.type +
1421
- ">(changetype<usize>(out), changetype<" +
1422
- mem.type +
1423
- ">(JSON.Box.from<bool>(false)), offsetof<this>(" +
1424
- JSON.stringify(mem.name) +
1425
- "));\n";
1567
+ DESERIALIZE += indent + " store<" + mem.type + ">(changetype<usize>(out), changetype<" + mem.type + ">(JSON.Box.from<bool>(false)), offsetof<this>(" + JSON.stringify(mem.name) + "));\n";
1426
1568
  }
1427
1569
  else {
1428
1570
  DESERIALIZE += indent + " store<boolean>(changetype<usize>(out), false, offsetof<this>(" + JSON.stringify(mem.name) + "));\n";
@@ -1793,8 +1935,9 @@ export default class Transformer extends Transform {
1793
1935
  }
1794
1936
  }
1795
1937
  program.registerConstantInteger("JSON_MODE", Type.i32, i64_new(MODE));
1796
- if (process.env["JSON_CACHE"]?.trim().toLowerCase() === "true" || process.env["JSON_CACHE"]?.trim().toLowerCase() === "1") {
1938
+ if (JSON_CACHE_CONFIG.enabled) {
1797
1939
  program.registerConstantInteger("JSON_CACHE", Type.bool, i64_one);
1940
+ program.registerConstantInteger("JSON_CACHE_SIZE", Type.u32, i64_new(JSON_CACHE_CONFIG.bytes));
1798
1941
  }
1799
1942
  }
1800
1943
  afterParse(parser) {