json-as 1.2.6 → 1.3.1
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 +417 -0
- package/README.md +135 -36
- package/assembly/custom/util.ts +24 -70
- package/assembly/deserialize/float.ts +181 -0
- package/assembly/deserialize/helpers/uint.ts +12 -0
- package/assembly/deserialize/index/arbitrary.ts +25 -0
- package/assembly/deserialize/index/array.ts +61 -0
- package/assembly/deserialize/index/bool.ts +1 -0
- package/assembly/deserialize/index/date.ts +1 -0
- package/assembly/deserialize/index/float.ts +1 -0
- package/assembly/deserialize/index/integer.ts +1 -0
- package/assembly/deserialize/index/map.ts +1 -0
- package/assembly/deserialize/index/object.ts +1 -0
- package/assembly/deserialize/index/raw.ts +1 -0
- package/assembly/deserialize/index/set.ts +1 -0
- package/assembly/deserialize/index/staticarray.ts +1 -0
- package/assembly/deserialize/index/string.ts +15 -0
- package/assembly/deserialize/index/struct.ts +1 -0
- package/assembly/deserialize/index/typedarray.ts +15 -0
- package/assembly/deserialize/index/unsigned.ts +1 -0
- package/assembly/deserialize/index.ts +14 -0
- package/assembly/deserialize/integer.ts +42 -0
- package/assembly/deserialize/simd/array/integer.ts +307 -0
- package/assembly/deserialize/simd/string.ts +130 -11
- package/assembly/deserialize/simple/arbitrary.ts +5 -12
- package/assembly/deserialize/simple/array/arbitrary.ts +12 -36
- package/assembly/deserialize/simple/array/array.ts +2 -8
- package/assembly/deserialize/simple/array/bool.ts +2 -8
- package/assembly/deserialize/simple/array/box.ts +2 -8
- package/assembly/deserialize/simple/array/float.ts +2 -8
- package/assembly/deserialize/simple/array/integer.ts +2 -8
- package/assembly/deserialize/simple/array/map.ts +6 -26
- package/assembly/deserialize/simple/array/object.ts +6 -26
- package/assembly/deserialize/simple/array/raw.ts +18 -61
- package/assembly/deserialize/simple/array/string.ts +5 -10
- package/assembly/deserialize/simple/array/struct.ts +6 -26
- package/assembly/deserialize/simple/array.ts +2 -5
- package/assembly/deserialize/simple/bool.ts +2 -6
- package/assembly/deserialize/simple/map.ts +29 -102
- package/assembly/deserialize/simple/object.ts +24 -81
- package/assembly/deserialize/simple/raw.ts +1 -4
- package/assembly/deserialize/simple/set.ts +11 -37
- package/assembly/deserialize/simple/staticarray/array.ts +1 -1
- package/assembly/deserialize/simple/staticarray/bool.ts +1 -1
- package/assembly/deserialize/simple/staticarray/float.ts +1 -1
- package/assembly/deserialize/simple/staticarray/integer.ts +1 -1
- package/assembly/deserialize/simple/staticarray/string.ts +7 -14
- package/assembly/deserialize/simple/staticarray/struct.ts +1 -1
- package/assembly/deserialize/simple/staticarray.ts +57 -21
- package/assembly/deserialize/simple/string.ts +90 -10
- package/assembly/deserialize/simple/struct.ts +25 -121
- package/assembly/deserialize/simple/typedarray.ts +94 -0
- package/assembly/deserialize/swar/array/arbitrary.ts +8 -0
- package/assembly/deserialize/swar/array/array.ts +39 -0
- package/assembly/deserialize/swar/array/bool.ts +47 -0
- package/assembly/deserialize/swar/array/box.ts +8 -0
- package/assembly/deserialize/swar/array/float.ts +39 -0
- package/assembly/deserialize/swar/array/integer.ts +461 -0
- package/assembly/deserialize/swar/array/map.ts +7 -0
- package/assembly/deserialize/swar/array/object.ts +44 -0
- package/assembly/deserialize/swar/array/raw.ts +8 -0
- package/assembly/deserialize/swar/array/shared.ts +96 -0
- package/assembly/deserialize/swar/array/string.ts +39 -0
- package/assembly/deserialize/swar/array/struct.ts +44 -0
- package/assembly/deserialize/swar/array.ts +49 -0
- package/assembly/deserialize/swar/string.ts +648 -15
- package/assembly/deserialize/unsigned.ts +75 -0
- package/assembly/index.d.ts +1 -3
- package/assembly/index.ts +316 -374
- package/assembly/serialize/index/arbitrary.ts +75 -0
- package/assembly/serialize/index/array.ts +1 -0
- package/assembly/serialize/index/bool.ts +1 -0
- package/assembly/serialize/index/date.ts +1 -0
- package/assembly/serialize/index/float.ts +1 -0
- package/assembly/serialize/index/integer.ts +1 -0
- package/assembly/serialize/index/map.ts +1 -0
- package/assembly/serialize/index/object.ts +46 -0
- package/assembly/serialize/index/raw.ts +1 -0
- package/assembly/serialize/index/set.ts +1 -0
- package/assembly/serialize/index/staticarray.ts +1 -0
- package/assembly/serialize/index/string.ts +15 -0
- package/assembly/serialize/index/struct.ts +1 -0
- package/assembly/serialize/index/typedarray.ts +66 -0
- package/assembly/serialize/index.ts +13 -0
- package/assembly/serialize/simd/string.ts +4 -13
- package/assembly/serialize/simple/arbitrary.ts +6 -0
- package/assembly/serialize/simple/raw.ts +1 -5
- package/assembly/serialize/simple/string.ts +3 -11
- package/assembly/serialize/simple/typedarray.ts +63 -0
- package/assembly/serialize/swar/string.ts +6 -21
- package/assembly/util/concat.ts +1 -5
- package/assembly/util/index.ts +1 -0
- package/assembly/util/masks.ts +12 -18
- package/assembly/util/memory.ts +0 -0
- package/assembly/util/snp.ts +1 -4
- package/assembly/util/stringScan.ts +24 -0
- package/assembly/util/swar.ts +50 -6
- package/lib/as-bs.ts +137 -127
- package/package.json +26 -5
- package/transform/lib/builder.d.ts.map +1 -1
- package/transform/lib/builder.js +5 -13
- package/transform/lib/builder.js.map +1 -1
- package/transform/lib/index.d.ts +1 -0
- package/transform/lib/index.d.ts.map +1 -1
- package/transform/lib/index.js +672 -757
- package/transform/lib/index.js.map +1 -1
- package/transform/lib/linkers/alias.d.ts.map +1 -1
- package/transform/lib/linkers/alias.js.map +1 -1
- package/transform/lib/linkers/custom.d.ts.map +1 -1
- package/transform/lib/linkers/custom.js +8 -9
- package/transform/lib/linkers/custom.js.map +1 -1
- package/transform/lib/linkers/imports.d.ts.map +1 -1
- package/transform/lib/linkers/imports.js.map +1 -1
- package/transform/lib/types.d.ts +6 -0
- package/transform/lib/types.d.ts.map +1 -1
- package/transform/lib/types.js +83 -21
- package/transform/lib/types.js.map +1 -1
- package/transform/lib/util.d.ts.map +1 -1
- package/transform/lib/util.js +1 -1
- package/transform/lib/util.js.map +1 -1
- package/transform/lib/visitor.d.ts.map +1 -1
- package/transform/lib/visitor.js +1 -2
- package/transform/lib/visitor.js.map +1 -1
- package/.prettierrc +0 -3
- package/ARCHITECTURE.md +0 -320
- package/CONTRIBUTING.md +0 -238
- package/TODO +0 -1
- package/assembly/deserialize/simple/float.ts +0 -11
- package/assembly/deserialize/simple/integer.ts +0 -9
- package/assembly/test.ts +0 -30
- package/eslint.config.js +0 -60
- package/lib/tsconfig.json +0 -8
- package/tools/assemblyscript-eslint-local.js +0 -29
- package/tools/assemblyscript-eslint.js +0 -29
- package/transform/tsconfig.json +0 -35
package/transform/lib/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Node, Type
|
|
1
|
+
import { Node, Type } from "assemblyscript/dist/assemblyscript.js";
|
|
2
2
|
import { Transform } from "assemblyscript/dist/transform.js";
|
|
3
3
|
import { readFileSync, writeFileSync } from "fs";
|
|
4
4
|
import * as path from "path";
|
|
@@ -11,14 +11,71 @@ let indent = " ";
|
|
|
11
11
|
let id = 0;
|
|
12
12
|
const WRITE = process.env["JSON_WRITE"]?.trim();
|
|
13
13
|
const rawValue = process.env["JSON_DEBUG"]?.trim();
|
|
14
|
-
const DEBUG = rawValue === "true"
|
|
15
|
-
? 1
|
|
16
|
-
: rawValue === "false" || rawValue === ""
|
|
17
|
-
? 0
|
|
18
|
-
: isNaN(Number(rawValue))
|
|
19
|
-
? 0
|
|
20
|
-
: Number(rawValue);
|
|
14
|
+
const DEBUG = rawValue === "true" ? 1 : rawValue === "false" || rawValue === "" ? 0 : isNaN(Number(rawValue)) ? 0 : Number(rawValue);
|
|
21
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";
|
|
17
|
+
function needsReferenceLoad(type) {
|
|
18
|
+
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
|
+
}
|
|
20
|
+
function getSerializeCall(type, realName) {
|
|
21
|
+
if (type == "ArrayBuffer") {
|
|
22
|
+
return `JSON.__serialize<ArrayBuffer>(load<ArrayBuffer>(ptr, offsetof<this>(${JSON.stringify(realName)})));\n`;
|
|
23
|
+
}
|
|
24
|
+
return needsReferenceLoad(type) ? `JSON.__serialize<${type}>(changetype<${type}>(load<usize>(ptr, offsetof<this>(${JSON.stringify(realName)}))));\n` : `JSON.__serialize<${type}>(load<${type}>(ptr, offsetof<this>(${JSON.stringify(realName)})));\n`;
|
|
25
|
+
}
|
|
26
|
+
const CUSTOM_JSON_KINDS = new Set(["any", "string", "number", "object", "array", "boolean", "null", "any | null", "string | null", "number | null", "object | null", "array | null", "boolean | null"]);
|
|
27
|
+
function parseCustomJsonKind(method, decoratorName) {
|
|
28
|
+
const decorator = method.decorators?.find((v) => v.name.text.toLowerCase() == decoratorName);
|
|
29
|
+
if (!decorator || !decorator.args || decorator.args.length == 0)
|
|
30
|
+
return "any";
|
|
31
|
+
if (decorator.args.length > 1)
|
|
32
|
+
throwError(`@${decoratorName} accepts at most one argument`, decorator.range);
|
|
33
|
+
const arg = decorator.args[0];
|
|
34
|
+
if (arg.kind != 16 || arg.literalKind != 2) {
|
|
35
|
+
throwError(`@${decoratorName} argument must be a string literal like @${decoratorName}("string")`, arg.range);
|
|
36
|
+
}
|
|
37
|
+
const kind = arg.value;
|
|
38
|
+
if (!CUSTOM_JSON_KINDS.has(kind)) {
|
|
39
|
+
throwError(`Unsupported @${decoratorName} JSON type '${kind}'. Expected one of: any, string, number, object, array, boolean, null`, arg.range);
|
|
40
|
+
}
|
|
41
|
+
return kind;
|
|
42
|
+
}
|
|
43
|
+
function addMemberToCustomBucket(sortedMembers, member, kind) {
|
|
44
|
+
const isNullable = kind.endsWith(" | null");
|
|
45
|
+
const baseKind = isNullable ? kind.slice(0, kind.length - 7) : kind;
|
|
46
|
+
if (isNullable)
|
|
47
|
+
sortedMembers.null.push(member);
|
|
48
|
+
switch (baseKind) {
|
|
49
|
+
case "string":
|
|
50
|
+
sortedMembers.string.push(member);
|
|
51
|
+
break;
|
|
52
|
+
case "number":
|
|
53
|
+
sortedMembers.number.push(member);
|
|
54
|
+
break;
|
|
55
|
+
case "boolean":
|
|
56
|
+
sortedMembers.boolean.push(member);
|
|
57
|
+
break;
|
|
58
|
+
case "null":
|
|
59
|
+
if (!isNullable)
|
|
60
|
+
sortedMembers.null.push(member);
|
|
61
|
+
break;
|
|
62
|
+
case "array":
|
|
63
|
+
sortedMembers.array.push(member);
|
|
64
|
+
break;
|
|
65
|
+
case "object":
|
|
66
|
+
sortedMembers.object.push(member);
|
|
67
|
+
break;
|
|
68
|
+
default:
|
|
69
|
+
sortedMembers.string.push(member);
|
|
70
|
+
sortedMembers.number.push(member);
|
|
71
|
+
sortedMembers.object.push(member);
|
|
72
|
+
sortedMembers.array.push(member);
|
|
73
|
+
sortedMembers.boolean.push(member);
|
|
74
|
+
if (!isNullable)
|
|
75
|
+
sortedMembers.null.push(member);
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
22
79
|
export class JSONTransform extends Visitor {
|
|
23
80
|
static SN = new JSONTransform();
|
|
24
81
|
program;
|
|
@@ -30,16 +87,53 @@ export class JSONTransform extends Visitor {
|
|
|
30
87
|
imports = [];
|
|
31
88
|
simdStatements = [];
|
|
32
89
|
visitedClasses = new Set();
|
|
90
|
+
collectInheritedFieldMembers(node, source, members, visited = new Set()) {
|
|
91
|
+
if (!node.extendsType)
|
|
92
|
+
return;
|
|
93
|
+
const extendsName = source.resolveExtendsName(node);
|
|
94
|
+
if (!extendsName || visited.has(extendsName))
|
|
95
|
+
return;
|
|
96
|
+
visited.add(extendsName);
|
|
97
|
+
let baseDecl = source.getClass(extendsName);
|
|
98
|
+
let baseSource = baseDecl ? source : null;
|
|
99
|
+
if (!baseDecl) {
|
|
100
|
+
const imported = source.getImportedClass(extendsName, this.parser);
|
|
101
|
+
if (imported) {
|
|
102
|
+
baseDecl = imported;
|
|
103
|
+
baseSource = this.sources.get(imported.range.source);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
if (!baseDecl) {
|
|
107
|
+
const available = source.getAvailableClass(extendsName, this.parser);
|
|
108
|
+
if (available) {
|
|
109
|
+
baseDecl = available;
|
|
110
|
+
baseSource = this.sources.get(available.range.source);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
if (!baseDecl || !baseSource)
|
|
114
|
+
return;
|
|
115
|
+
const isDecoratedBase = !!baseDecl.decorators?.some((decorator) => {
|
|
116
|
+
const name = decorator.name.text;
|
|
117
|
+
return name === "json" || name === "serializable";
|
|
118
|
+
});
|
|
119
|
+
if (isDecoratedBase)
|
|
120
|
+
return;
|
|
121
|
+
this.collectInheritedFieldMembers(baseDecl, baseSource, members, visited);
|
|
122
|
+
const inheritedMembers = baseDecl.members.filter((v) => v.kind === 54 && !v.is(32) && !v.is(512) && !v.is(1024) && !v.decorators?.some((decorator) => decorator.name.text === "omit"));
|
|
123
|
+
for (let i = inheritedMembers.length - 1; i >= 0; i--) {
|
|
124
|
+
const inherited = inheritedMembers[i];
|
|
125
|
+
if (!members.some((member) => member.name.text == inherited.name.text)) {
|
|
126
|
+
members.unshift(inherited);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
33
130
|
visitClassDeclarationRef(node) {
|
|
34
131
|
if (!node.decorators?.length ||
|
|
35
132
|
!node.decorators.some((decorator) => {
|
|
36
133
|
const name = decorator.name.text;
|
|
37
134
|
return name === "json" || name === "serializable";
|
|
38
135
|
}))
|
|
39
|
-
throw new Error("Class " +
|
|
40
|
-
node.name.text +
|
|
41
|
-
" is missing an @json or @serializable decorator in " +
|
|
42
|
-
node.range.source.internalPath);
|
|
136
|
+
throw new Error("Class " + node.name.text + " is missing an @json or @serializable decorator in " + node.range.source.internalPath);
|
|
43
137
|
this.visitClassDeclaration(node);
|
|
44
138
|
}
|
|
45
139
|
resolveType(type, source, visited = new Set()) {
|
|
@@ -48,9 +142,7 @@ export class JSONTransform extends Visitor {
|
|
|
48
142
|
return stripped;
|
|
49
143
|
}
|
|
50
144
|
visited.add(stripped);
|
|
51
|
-
const resolvedType = source.aliases
|
|
52
|
-
.find((v) => stripNull(v.name) === stripped)
|
|
53
|
-
?.getBaseType();
|
|
145
|
+
const resolvedType = source.aliases.find((v) => stripNull(v.name) === stripped)?.getBaseType();
|
|
54
146
|
if (resolvedType) {
|
|
55
147
|
return this.resolveType(resolvedType, source, visited);
|
|
56
148
|
}
|
|
@@ -89,38 +181,20 @@ export class JSONTransform extends Visitor {
|
|
|
89
181
|
return;
|
|
90
182
|
if (!this.schemas.has(source.internalPath))
|
|
91
183
|
this.schemas.set(source.internalPath, []);
|
|
92
|
-
const members = [
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
v.flags !== 512 &&
|
|
96
|
-
v.flags !== 1024 &&
|
|
97
|
-
!v.decorators?.some((decorator) => decorator.name.text === "omit")),
|
|
98
|
-
];
|
|
99
|
-
const serializers = [
|
|
100
|
-
...node.members.filter((v) => v.kind === 58 &&
|
|
101
|
-
v.decorators &&
|
|
102
|
-
v.decorators.some((e) => e.name.text.toLowerCase() ===
|
|
103
|
-
"serializer")),
|
|
104
|
-
];
|
|
105
|
-
const deserializers = [
|
|
106
|
-
...node.members.filter((v) => v.kind === 58 &&
|
|
107
|
-
v.decorators &&
|
|
108
|
-
v.decorators.some((e) => e.name.text.toLowerCase() ===
|
|
109
|
-
"deserializer")),
|
|
110
|
-
];
|
|
184
|
+
const members = [...node.members.filter((v) => v.kind === 54 && !v.is(32) && !v.is(512) && !v.is(1024) && !v.decorators?.some((decorator) => decorator.name.text === "omit"))];
|
|
185
|
+
const serializers = [...node.members.filter((v) => v.kind === 58 && v.decorators && v.decorators.some((e) => e.name.text.toLowerCase() === "serializer") && !v.name.text.startsWith("__try"))];
|
|
186
|
+
const deserializers = [...node.members.filter((v) => v.kind === 58 && v.decorators && v.decorators.some((e) => e.name.text.toLowerCase() === "deserializer") && !v.name.text.startsWith("__try"))];
|
|
111
187
|
const schema = new Schema();
|
|
112
188
|
schema.node = node;
|
|
113
189
|
schema.name = source.getQualifiedName(node);
|
|
114
190
|
if (node.extendsType) {
|
|
191
|
+
this.collectInheritedFieldMembers(node, source, members);
|
|
115
192
|
const extendsName = source.resolveExtendsName(node);
|
|
116
193
|
if (!schema.parent) {
|
|
117
194
|
const depSearch = schema.deps.find((v) => v.name == extendsName);
|
|
118
195
|
if (depSearch) {
|
|
119
196
|
if (DEBUG > 0)
|
|
120
|
-
console.log("Found " +
|
|
121
|
-
extendsName +
|
|
122
|
-
" in dependencies of " +
|
|
123
|
-
source.internalPath);
|
|
197
|
+
console.log("Found " + extendsName + " in dependencies of " + source.internalPath);
|
|
124
198
|
if (!schema.deps.some((v) => v.name == depSearch.name))
|
|
125
199
|
schema.deps.push(depSearch);
|
|
126
200
|
schema.parent = depSearch;
|
|
@@ -129,26 +203,16 @@ export class JSONTransform extends Visitor {
|
|
|
129
203
|
const internalSearch = source.getClass(extendsName);
|
|
130
204
|
if (internalSearch) {
|
|
131
205
|
if (DEBUG > 0)
|
|
132
|
-
console.log("Found " +
|
|
133
|
-
extendsName +
|
|
134
|
-
" internally from " +
|
|
135
|
-
source.internalPath);
|
|
206
|
+
console.log("Found " + extendsName + " internally from " + source.internalPath);
|
|
136
207
|
if (!this.visitedClasses.has(source.getFullPath(internalSearch))) {
|
|
137
208
|
this.visitClassDeclarationRef(internalSearch);
|
|
138
|
-
this.schemas
|
|
139
|
-
.get(internalSearch.range.source.internalPath)
|
|
140
|
-
.push(this.schema);
|
|
209
|
+
this.schemas.get(internalSearch.range.source.internalPath).push(this.schema);
|
|
141
210
|
this.visitClassDeclaration(node);
|
|
142
211
|
return;
|
|
143
212
|
}
|
|
144
|
-
const schem = this.schemas
|
|
145
|
-
.get(internalSearch.range.source.internalPath)
|
|
146
|
-
?.find((s) => s.name == extendsName);
|
|
213
|
+
const schem = this.schemas.get(internalSearch.range.source.internalPath)?.find((s) => s.name == extendsName);
|
|
147
214
|
if (!schem)
|
|
148
|
-
throw new Error("Could not find schema for " +
|
|
149
|
-
internalSearch.name.text +
|
|
150
|
-
" in " +
|
|
151
|
-
internalSearch.range.source.internalPath);
|
|
215
|
+
throw new Error("Could not find schema for " + internalSearch.name.text + " in " + internalSearch.range.source.internalPath);
|
|
152
216
|
schema.deps.push(schem);
|
|
153
217
|
schema.parent = schem;
|
|
154
218
|
}
|
|
@@ -156,10 +220,7 @@ export class JSONTransform extends Visitor {
|
|
|
156
220
|
const externalSearch = source.getImportedClass(extendsName, this.parser);
|
|
157
221
|
if (externalSearch) {
|
|
158
222
|
if (DEBUG > 0)
|
|
159
|
-
console.log("Found " +
|
|
160
|
-
externalSearch.name.text +
|
|
161
|
-
" externally from " +
|
|
162
|
-
source.internalPath);
|
|
223
|
+
console.log("Found " + externalSearch.name.text + " externally from " + source.internalPath);
|
|
163
224
|
const externalSource = this.sources.get(externalSearch.range.source);
|
|
164
225
|
if (!this.visitedClasses.has(externalSource.getFullPath(externalSearch))) {
|
|
165
226
|
this.visitClassDeclarationRef(externalSearch);
|
|
@@ -167,17 +228,36 @@ export class JSONTransform extends Visitor {
|
|
|
167
228
|
this.visitClassDeclaration(node);
|
|
168
229
|
return;
|
|
169
230
|
}
|
|
170
|
-
const schem = this.schemas
|
|
171
|
-
.get(externalSource.internalPath)
|
|
172
|
-
?.find((s) => s.name == extendsName);
|
|
231
|
+
const schem = this.schemas.get(externalSource.internalPath)?.find((s) => s.name == extendsName);
|
|
173
232
|
if (!schem)
|
|
174
|
-
throw new Error("Could not find schema for " +
|
|
175
|
-
externalSearch.name.text +
|
|
176
|
-
" in " +
|
|
177
|
-
externalSource.internalPath);
|
|
233
|
+
throw new Error("Could not find schema for " + externalSearch.name.text + " in " + externalSource.internalPath);
|
|
178
234
|
schema.deps.push(schem);
|
|
179
235
|
schema.parent = schem;
|
|
180
236
|
}
|
|
237
|
+
else {
|
|
238
|
+
const availableSearch = source.getAvailableClass(extendsName, this.parser);
|
|
239
|
+
if (availableSearch) {
|
|
240
|
+
if (DEBUG > 0)
|
|
241
|
+
console.log("Found " + availableSearch.name.text + " from available sources for " + source.internalPath);
|
|
242
|
+
const availableSource = this.sources.get(availableSearch.range.source);
|
|
243
|
+
if (availableSearch.decorators?.some((decorator) => {
|
|
244
|
+
const name = decorator.name.text;
|
|
245
|
+
return name === "json" || name === "serializable";
|
|
246
|
+
})) {
|
|
247
|
+
if (!this.visitedClasses.has(availableSource.getFullPath(availableSearch))) {
|
|
248
|
+
this.visitClassDeclarationRef(availableSearch);
|
|
249
|
+
this.schemas.get(availableSource.internalPath).push(this.schema);
|
|
250
|
+
this.visitClassDeclaration(node);
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
const schem = this.schemas.get(availableSource.internalPath)?.find((s) => s.name == extendsName);
|
|
254
|
+
if (schem) {
|
|
255
|
+
schema.deps.push(schem);
|
|
256
|
+
schema.parent = schem;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
181
261
|
}
|
|
182
262
|
}
|
|
183
263
|
}
|
|
@@ -212,8 +292,7 @@ export class JSONTransform extends Visitor {
|
|
|
212
292
|
else if (["JSON.Box", "JSON.Obj", "JSON.Value", "JSON.Raw"].includes(type)) {
|
|
213
293
|
return types;
|
|
214
294
|
}
|
|
215
|
-
else if (node.isGeneric &&
|
|
216
|
-
node.typeParameters.some((p) => p.name.text == type)) {
|
|
295
|
+
else if (node.isGeneric && node.typeParameters.some((p) => p.name.text == type)) {
|
|
217
296
|
return types;
|
|
218
297
|
}
|
|
219
298
|
else if (type == node.name.text) {
|
|
@@ -229,10 +308,7 @@ export class JSONTransform extends Visitor {
|
|
|
229
308
|
const depSearch = schema.deps.find((v) => v.name == unknownType);
|
|
230
309
|
if (depSearch) {
|
|
231
310
|
if (DEBUG > 0)
|
|
232
|
-
console.log("Found " +
|
|
233
|
-
unknownType +
|
|
234
|
-
" in dependencies of " +
|
|
235
|
-
source.internalPath);
|
|
311
|
+
console.log("Found " + unknownType + " in dependencies of " + source.internalPath);
|
|
236
312
|
if (!schema.deps.some((v) => v.name == depSearch.name)) {
|
|
237
313
|
schema.deps.push(depSearch);
|
|
238
314
|
}
|
|
@@ -241,59 +317,37 @@ export class JSONTransform extends Visitor {
|
|
|
241
317
|
const internalSearch = source.getClass(unknownType);
|
|
242
318
|
if (internalSearch) {
|
|
243
319
|
if (DEBUG > 0)
|
|
244
|
-
console.log("Found " +
|
|
245
|
-
unknownType +
|
|
246
|
-
" internally from " +
|
|
247
|
-
source.internalPath);
|
|
320
|
+
console.log("Found " + unknownType + " internally from " + source.internalPath);
|
|
248
321
|
if (!this.visitedClasses.has(source.getFullPath(internalSearch))) {
|
|
249
322
|
this.visitClassDeclarationRef(internalSearch);
|
|
250
|
-
const internalSchema = this.schemas
|
|
251
|
-
.get(internalSearch.range.source.internalPath)
|
|
252
|
-
?.find((s) => s.name == unknownType);
|
|
323
|
+
const internalSchema = this.schemas.get(internalSearch.range.source.internalPath)?.find((s) => s.name == unknownType);
|
|
253
324
|
schema.deps.push(internalSchema);
|
|
254
|
-
this.schemas
|
|
255
|
-
.get(internalSearch.range.source.internalPath)
|
|
256
|
-
.push(this.schema);
|
|
325
|
+
this.schemas.get(internalSearch.range.source.internalPath).push(this.schema);
|
|
257
326
|
this.visitClassDeclaration(node);
|
|
258
327
|
return;
|
|
259
328
|
}
|
|
260
|
-
const schem = this.schemas
|
|
261
|
-
.get(internalSearch.range.source.internalPath)
|
|
262
|
-
?.find((s) => s.name == unknownType);
|
|
329
|
+
const schem = this.schemas.get(internalSearch.range.source.internalPath)?.find((s) => s.name == unknownType);
|
|
263
330
|
if (!schem)
|
|
264
|
-
throw new Error("Could not find schema for " +
|
|
265
|
-
internalSearch.name.text +
|
|
266
|
-
" in " +
|
|
267
|
-
internalSearch.range.source.internalPath);
|
|
331
|
+
throw new Error("Could not find schema for " + internalSearch.name.text + " in " + internalSearch.range.source.internalPath);
|
|
268
332
|
schema.deps.push(schem);
|
|
269
333
|
}
|
|
270
334
|
else {
|
|
271
335
|
const externalSearch = source.getImportedClass(unknownType, this.parser);
|
|
272
336
|
if (externalSearch) {
|
|
273
337
|
if (DEBUG > 0)
|
|
274
|
-
console.log("Found " +
|
|
275
|
-
externalSearch.name.text +
|
|
276
|
-
" externally from " +
|
|
277
|
-
source.internalPath);
|
|
338
|
+
console.log("Found " + externalSearch.name.text + " externally from " + source.internalPath);
|
|
278
339
|
const externalSource = this.sources.get(externalSearch.range.source);
|
|
279
340
|
if (!this.visitedClasses.has(externalSource.getFullPath(externalSearch))) {
|
|
280
341
|
this.visitClassDeclarationRef(externalSearch);
|
|
281
|
-
const externalSchema = this.schemas
|
|
282
|
-
.get(externalSource.internalPath)
|
|
283
|
-
?.find((s) => s.name == unknownType);
|
|
342
|
+
const externalSchema = this.schemas.get(externalSource.internalPath)?.find((s) => s.name == unknownType);
|
|
284
343
|
schema.deps.push(externalSchema);
|
|
285
344
|
this.schemas.get(externalSource.internalPath).push(this.schema);
|
|
286
345
|
this.visitClassDeclaration(node);
|
|
287
346
|
return;
|
|
288
347
|
}
|
|
289
|
-
const schem = this.schemas
|
|
290
|
-
.get(externalSource.internalPath)
|
|
291
|
-
?.find((s) => s.name == unknownType);
|
|
348
|
+
const schem = this.schemas.get(externalSource.internalPath)?.find((s) => s.name == unknownType);
|
|
292
349
|
if (!schem)
|
|
293
|
-
throw new Error("Could not find schema for " +
|
|
294
|
-
externalSearch.name.text +
|
|
295
|
-
" in " +
|
|
296
|
-
externalSource.internalPath);
|
|
350
|
+
throw new Error("Could not find schema for " + externalSearch.name.text + " in " + externalSource.internalPath);
|
|
297
351
|
schema.deps.push(schem);
|
|
298
352
|
}
|
|
299
353
|
}
|
|
@@ -303,103 +357,74 @@ export class JSONTransform extends Visitor {
|
|
|
303
357
|
this.schemas.get(source.internalPath).push(schema);
|
|
304
358
|
this.schema = schema;
|
|
305
359
|
this.visitedClasses.add(fullClassPath);
|
|
360
|
+
const codegenMode = getCodegenMode(this.program);
|
|
361
|
+
const useFastPath = USE_FAST_PATH && codegenMode !== JSONMode.NAIVE;
|
|
306
362
|
let SERIALIZE = "__SERIALIZE(ptr: usize): void {\n";
|
|
307
363
|
let INITIALIZE = "@inline __INITIALIZE(): this {\n";
|
|
308
|
-
let DESERIALIZE = "
|
|
364
|
+
let DESERIALIZE = "__DESERIALIZE_SLOW<__JSON_T>(srcStart: usize, srcEnd: usize, out: __JSON_T): usize {\n";
|
|
365
|
+
let DESERIALIZE_FAST = "@inline __DESERIALIZE_FAST<__JSON_T>(srcStart: usize, srcEnd: usize, out: __JSON_T): usize {\n";
|
|
309
366
|
let DESERIALIZE_CUSTOM = "";
|
|
310
367
|
let SERIALIZE_CUSTOM = "";
|
|
311
368
|
if (DEBUG > 0)
|
|
312
|
-
console.log("Created schema: " +
|
|
313
|
-
this.schema.name +
|
|
314
|
-
" in file " +
|
|
315
|
-
source.normalizedPath +
|
|
316
|
-
(this.schema.deps.length
|
|
317
|
-
? " with dependencies:\n " +
|
|
318
|
-
this.schema.deps.map((v) => v.name).join("\n ")
|
|
319
|
-
: ""));
|
|
369
|
+
console.log("Created schema: " + this.schema.name + " in file " + source.normalizedPath + (this.schema.deps.length ? " with dependencies:\n " + this.schema.deps.map((v) => v.name).join("\n ") : ""));
|
|
320
370
|
if (serializers.length > 1)
|
|
321
|
-
throwError("Multiple serializers detected for class " +
|
|
322
|
-
node.name.text +
|
|
323
|
-
" but schemas can only have one serializer!", serializers[1].range);
|
|
371
|
+
throwError("Multiple serializers detected for class " + node.name.text + " but schemas can only have one serializer!", serializers[1].range);
|
|
324
372
|
if (deserializers.length > 1)
|
|
325
|
-
throwError("Multiple deserializers detected for class " +
|
|
326
|
-
node.name.text +
|
|
327
|
-
" but schemas can only have one deserializer!", deserializers[1].range);
|
|
373
|
+
throwError("Multiple deserializers detected for class " + node.name.text + " but schemas can only have one deserializer!", deserializers[1].range);
|
|
328
374
|
if (serializers.length) {
|
|
329
375
|
this.schema.custom = true;
|
|
330
376
|
const serializer = serializers[0];
|
|
377
|
+
const serializerJsonKind = parseCustomJsonKind(serializer, "serializer");
|
|
331
378
|
const hasCall = CustomTransform.hasCall(serializer);
|
|
379
|
+
this.schema.customJsonKind = serializerJsonKind;
|
|
332
380
|
CustomTransform.visit(serializer);
|
|
333
381
|
if (serializer.signature.parameters.length > 1)
|
|
334
|
-
throwError("Found too many parameters in custom serializer for " +
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
if (serializer.signature.parameters.length > 0 &&
|
|
340
|
-
serializer.signature.parameters[0].type.name.identifier
|
|
341
|
-
.text != node.name.text &&
|
|
342
|
-
serializer.signature.parameters[0].type.name.identifier
|
|
343
|
-
.text != "this")
|
|
344
|
-
throwError("Type of parameter for custom serializer does not match! It should be 'string'either be 'this' or '" +
|
|
345
|
-
this.schema.name +
|
|
346
|
-
"'", serializer.signature.parameters[0].type.range);
|
|
347
|
-
if (!serializer.signature.returnType ||
|
|
348
|
-
!(serializer.signature.returnType).name.identifier.text.includes("string"))
|
|
349
|
-
throwError("Could not find valid return type for serializer in " +
|
|
350
|
-
this.schema.name +
|
|
351
|
-
"!. Set the return type to type 'string' and try again", serializer.signature.returnType.range);
|
|
382
|
+
throwError("Found too many parameters in custom serializer for " + this.schema.name + ", but serializers can only accept one parameter of type '" + this.schema.name + "'!", serializer.signature.parameters[1].range);
|
|
383
|
+
if (serializer.signature.parameters.length > 0 && serializer.signature.parameters[0].type.name.identifier.text != node.name.text && serializer.signature.parameters[0].type.name.identifier.text != "this")
|
|
384
|
+
throwError("Type of parameter for custom serializer does not match! It should be 'string'either be 'this' or '" + this.schema.name + "'", serializer.signature.parameters[0].type.range);
|
|
385
|
+
if (!serializer.signature.returnType || !serializer.signature.returnType.name.identifier.text.includes("string"))
|
|
386
|
+
throwError("Could not find valid return type for serializer in " + this.schema.name + "!. Set the return type to type 'string' and try again", serializer.signature.returnType.range);
|
|
352
387
|
if (!serializer.decorators.some((v) => v.name.text == "inline")) {
|
|
353
388
|
serializer.decorators.push(Node.createDecorator(Node.createIdentifierExpression("inline", serializer.range), null, serializer.range));
|
|
354
389
|
}
|
|
355
390
|
SERIALIZE_CUSTOM += " __SERIALIZE(ptr: usize): void {\n";
|
|
356
|
-
|
|
357
|
-
" const
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
if (hasCall)
|
|
363
|
-
SERIALIZE_CUSTOM += " bs.
|
|
391
|
+
if (hasCall) {
|
|
392
|
+
SERIALIZE_CUSTOM += " const savedOffset = bs.offset;\n";
|
|
393
|
+
SERIALIZE_CUSTOM += " const savedStackSize = bs.stackSize;\n";
|
|
394
|
+
}
|
|
395
|
+
SERIALIZE_CUSTOM += " const self = changetype<this>(ptr);\n";
|
|
396
|
+
SERIALIZE_CUSTOM += " const data = self." + serializer.name.text + "(" + (serializer.signature.parameters.length ? "self" : "") + ");\n";
|
|
397
|
+
if (hasCall) {
|
|
398
|
+
SERIALIZE_CUSTOM += " bs.offset = savedOffset;\n";
|
|
399
|
+
SERIALIZE_CUSTOM += " bs.stackSize = savedStackSize;\n";
|
|
400
|
+
}
|
|
364
401
|
SERIALIZE_CUSTOM += " const dataSize = data.length << 1;\n";
|
|
365
|
-
SERIALIZE_CUSTOM +=
|
|
366
|
-
" memory.copy(bs.offset, changetype<usize>(data), dataSize);\n";
|
|
402
|
+
SERIALIZE_CUSTOM += " memory.copy(bs.offset, changetype<usize>(data), dataSize);\n";
|
|
367
403
|
SERIALIZE_CUSTOM += " bs.offset += dataSize;\n";
|
|
368
404
|
SERIALIZE_CUSTOM += " }\n";
|
|
369
405
|
}
|
|
370
406
|
if (deserializers.length) {
|
|
371
407
|
this.schema.custom = true;
|
|
372
408
|
const deserializer = deserializers[0];
|
|
409
|
+
const deserializerJsonKind = parseCustomJsonKind(deserializer, "deserializer");
|
|
410
|
+
if (this.schema.customJsonKind != "any" && deserializerJsonKind != "any" && this.schema.customJsonKind != deserializerJsonKind) {
|
|
411
|
+
throwError(`@serializer and @deserializer JSON types for ${this.schema.name} must match`, deserializer.range);
|
|
412
|
+
}
|
|
413
|
+
if (this.schema.customJsonKind == "any")
|
|
414
|
+
this.schema.customJsonKind = deserializerJsonKind;
|
|
373
415
|
if (!deserializer.signature.parameters.length)
|
|
374
|
-
throwError("Could not find any parameters in custom deserializer for " +
|
|
375
|
-
this.schema.name +
|
|
376
|
-
". Deserializers must have one parameter like 'deserializer(data: string): " +
|
|
377
|
-
this.schema.name +
|
|
378
|
-
" {}'", deserializer.range);
|
|
416
|
+
throwError("Could not find any parameters in custom deserializer for " + this.schema.name + ". Deserializers must have one parameter like 'deserializer(data: string): " + this.schema.name + " {}'", deserializer.range);
|
|
379
417
|
if (deserializer.signature.parameters.length > 1)
|
|
380
|
-
throwError("Found too many parameters in custom deserializer for " +
|
|
381
|
-
|
|
382
|
-
", but deserializers can only accept one parameter of type 'string'!", deserializer.signature.parameters[1].range);
|
|
383
|
-
if (deserializer.signature.parameters[0].type.name
|
|
384
|
-
.identifier.text != "string")
|
|
418
|
+
throwError("Found too many parameters in custom deserializer for " + this.schema.name + ", but deserializers can only accept one parameter of type 'string'!", deserializer.signature.parameters[1].range);
|
|
419
|
+
if (deserializer.signature.parameters[0].type.name.identifier.text != "string")
|
|
385
420
|
throwError("Type of parameter for custom deserializer does not match! It must be 'string'", deserializer.signature.parameters[0].type.range);
|
|
386
|
-
if (!deserializer.signature.returnType ||
|
|
387
|
-
|
|
388
|
-
(deserializer.signature.returnType).name.identifier.text.includes("this")))
|
|
389
|
-
throwError("Could not find valid return type for deserializer in " +
|
|
390
|
-
this.schema.name +
|
|
391
|
-
"!. Set the return type to type '" +
|
|
392
|
-
this.schema.name +
|
|
393
|
-
"' or 'this' and try again", deserializer.signature.returnType.range);
|
|
421
|
+
if (!deserializer.signature.returnType || !(deserializer.signature.returnType.name.identifier.text.includes(this.schema.name) || deserializer.signature.returnType.name.identifier.text.includes("this")))
|
|
422
|
+
throwError("Could not find valid return type for deserializer in " + this.schema.name + "!. Set the return type to type '" + this.schema.name + "' or 'this' and try again", deserializer.signature.returnType.range);
|
|
394
423
|
if (!deserializer.decorators.some((v) => v.name.text == "inline")) {
|
|
395
424
|
deserializer.decorators.push(Node.createDecorator(Node.createIdentifierExpression("inline", deserializer.range), null, deserializer.range));
|
|
396
425
|
}
|
|
397
|
-
DESERIALIZE_CUSTOM +=
|
|
398
|
-
|
|
399
|
-
DESERIALIZE_CUSTOM +=
|
|
400
|
-
" return inline.always(this." +
|
|
401
|
-
deserializer.name.text +
|
|
402
|
-
"(JSON.Util.ptrToStr(srcStart, srcEnd)));\n";
|
|
426
|
+
DESERIALIZE_CUSTOM += " @inline __DESERIALIZE_CUSTOM(data: string): this {\n";
|
|
427
|
+
DESERIALIZE_CUSTOM += " return inline.always(this." + deserializer.name.text + "(data));\n";
|
|
403
428
|
DESERIALIZE_CUSTOM += " }\n";
|
|
404
429
|
}
|
|
405
430
|
if (!members.length && !deserializers.length && !serializers.length) {
|
|
@@ -422,22 +447,15 @@ export class JSONTransform extends Visitor {
|
|
|
422
447
|
mem.value = value;
|
|
423
448
|
mem.node = member;
|
|
424
449
|
mem.byteSize = sizeof(mem.type);
|
|
450
|
+
mem.custom = schema.deps.some((dep) => dep?.name == stripNull(type) && dep.custom);
|
|
425
451
|
this.schema.byteSize += mem.byteSize;
|
|
426
452
|
if (member.decorators) {
|
|
427
453
|
for (const decorator of member.decorators) {
|
|
428
|
-
const decoratorName = decorator.name.text
|
|
429
|
-
.toLowerCase()
|
|
430
|
-
.trim();
|
|
454
|
+
const decoratorName = decorator.name.text.toLowerCase().trim();
|
|
431
455
|
switch (decoratorName) {
|
|
432
456
|
case "alias": {
|
|
433
457
|
const arg = decorator.args[0];
|
|
434
|
-
if (!arg ||
|
|
435
|
-
(arg.kind != 16 &&
|
|
436
|
-
arg.literalKind !=
|
|
437
|
-
2 &&
|
|
438
|
-
arg.literalKind !=
|
|
439
|
-
1 &&
|
|
440
|
-
arg.literalKind != 0))
|
|
458
|
+
if (!arg || (arg.kind != 16 && arg.literalKind != 2 && arg.literalKind != 1 && arg.literalKind != 0))
|
|
441
459
|
throwError("@alias must have an argument of type string or number", member.range);
|
|
442
460
|
mem.alias = arg.value.toString();
|
|
443
461
|
break;
|
|
@@ -485,43 +503,40 @@ export class JSONTransform extends Visitor {
|
|
|
485
503
|
const aliasName = JSON.stringify(member.alias || member.name);
|
|
486
504
|
const realName = member.name;
|
|
487
505
|
const isLast = i == this.schema.members.length - 1;
|
|
488
|
-
if (
|
|
489
|
-
if (member.value
|
|
490
|
-
member.value != "0" &&
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
INITIALIZE += ` store<${member.type}>(changetype<usize>(this), ${member.value}, offsetof<this>(${JSON.stringify(member.name)}));\n`;
|
|
494
|
-
}
|
|
495
|
-
}
|
|
496
|
-
else if (member.generic) {
|
|
497
|
-
INITIALIZE += ` if (isManaged<nonnull<${member.type}>>() || isReference<nonnull<${member.type}>>()) {\n`;
|
|
498
|
-
INITIALIZE += ` store<${member.type}>(changetype<usize>(this), changetype<nonnull<${member.type}>>(__new(offsetof<nonnull<${member.type}>>(), idof<nonnull<${member.type}>>())), offsetof<this>(${JSON.stringify(member.name)}));\n`;
|
|
499
|
-
INITIALIZE += ` if (isDefined(this.${member.name}.__INITIALIZE)) changetype<nonnull<${member.type}>>(this.${member.name}).__INITIALIZE();\n`;
|
|
500
|
-
INITIALIZE += ` }\n`;
|
|
501
|
-
}
|
|
502
|
-
else if (!member.node.type.isNullable) {
|
|
503
|
-
if (this.getSchema(member.type)) {
|
|
504
|
-
INITIALIZE += ` store<${member.type}>(changetype<usize>(this), changetype<nonnull<${member.type}>>(__new(offsetof<nonnull<${member.type}>>(), idof<nonnull<${member.type}>>())).__INITIALIZE(), offsetof<this>(${JSON.stringify(member.name)}));\n`;
|
|
505
|
-
}
|
|
506
|
-
else if (member.type.startsWith("Array<")) {
|
|
507
|
-
INITIALIZE += ` store<${member.type}>(changetype<usize>(this), [], offsetof<this>(${JSON.stringify(member.name)}));\n`;
|
|
508
|
-
}
|
|
509
|
-
else if (member.type.startsWith("Map<")) {
|
|
510
|
-
INITIALIZE += ` store<${member.type}>(changetype<usize>(this), new ${member.type}(), offsetof<this>(${JSON.stringify(member.name)}));\n`;
|
|
511
|
-
}
|
|
512
|
-
else if (member.type.startsWith("Set<")) {
|
|
513
|
-
INITIALIZE += ` store<${member.type}>(changetype<usize>(this), new ${member.type}(), offsetof<this>(${JSON.stringify(member.name)}));\n`;
|
|
506
|
+
if (!useFastPath) {
|
|
507
|
+
if (member.value) {
|
|
508
|
+
if (member.value != "null" && member.value != "0" && member.value != "0.0" && member.value != "false") {
|
|
509
|
+
INITIALIZE += ` store<${member.type}>(changetype<usize>(this), ${member.value}, offsetof<this>(${JSON.stringify(member.name)}));\n`;
|
|
510
|
+
}
|
|
514
511
|
}
|
|
515
|
-
else if (member.
|
|
512
|
+
else if (member.generic) {
|
|
513
|
+
INITIALIZE += ` if (isManaged<nonnull<${member.type}>>() || isReference<nonnull<${member.type}>>()) {\n`;
|
|
514
|
+
INITIALIZE += ` store<${member.type}>(changetype<usize>(this), changetype<nonnull<${member.type}>>(__new(offsetof<nonnull<${member.type}>>(), idof<nonnull<${member.type}>>())), offsetof<this>(${JSON.stringify(member.name)}));\n`;
|
|
515
|
+
INITIALIZE += ` if (isDefined(this.${member.name}.__INITIALIZE)) changetype<nonnull<${member.type}>>(this.${member.name}).__INITIALIZE();\n`;
|
|
516
|
+
INITIALIZE += ` }\n`;
|
|
516
517
|
}
|
|
517
|
-
else if (member.type
|
|
518
|
-
|
|
518
|
+
else if (!member.node.type.isNullable) {
|
|
519
|
+
if (this.getSchema(member.type)) {
|
|
520
|
+
INITIALIZE += ` store<${member.type}>(changetype<usize>(this), changetype<nonnull<${member.type}>>(__new(offsetof<nonnull<${member.type}>>(), idof<nonnull<${member.type}>>())).__INITIALIZE(), offsetof<this>(${JSON.stringify(member.name)}));\n`;
|
|
521
|
+
}
|
|
522
|
+
else if (member.type.startsWith("Array<")) {
|
|
523
|
+
INITIALIZE += ` store<${member.type}>(changetype<usize>(this), [], offsetof<this>(${JSON.stringify(member.name)}));\n`;
|
|
524
|
+
}
|
|
525
|
+
else if (member.type.startsWith("Map<")) {
|
|
526
|
+
INITIALIZE += ` store<${member.type}>(changetype<usize>(this), new ${member.type}(), offsetof<this>(${JSON.stringify(member.name)}));\n`;
|
|
527
|
+
}
|
|
528
|
+
else if (member.type.startsWith("Set<")) {
|
|
529
|
+
INITIALIZE += ` store<${member.type}>(changetype<usize>(this), new ${member.type}(), offsetof<this>(${JSON.stringify(member.name)}));\n`;
|
|
530
|
+
}
|
|
531
|
+
else if (member.type.startsWith("StaticArray<")) {
|
|
532
|
+
}
|
|
533
|
+
else if (member.type == "string" || member.type == "String") {
|
|
534
|
+
INITIALIZE += ` store<${member.type}>(changetype<usize>(this), "", offsetof<this>(${JSON.stringify(member.name)}));\n`;
|
|
535
|
+
}
|
|
519
536
|
}
|
|
520
537
|
}
|
|
521
538
|
const SIMD_ENABLED = this.program.options.hasFeature(16);
|
|
522
|
-
if (!isRegular &&
|
|
523
|
-
!member.flags.has(PropertyFlags.OmitIf) &&
|
|
524
|
-
!member.flags.has(PropertyFlags.OmitNull))
|
|
539
|
+
if (!isRegular && !member.flags.has(PropertyFlags.OmitIf) && !member.flags.has(PropertyFlags.OmitNull))
|
|
525
540
|
isRegular = true;
|
|
526
541
|
if (isRegular && isPure) {
|
|
527
542
|
const keyPart = (isFirst ? "{" : ",") + aliasName + ":";
|
|
@@ -529,9 +544,7 @@ export class JSONTransform extends Visitor {
|
|
|
529
544
|
SERIALIZE += this.getStores(keyPart, SIMD_ENABLED)
|
|
530
545
|
.map((v) => indent + v + "\n")
|
|
531
546
|
.join("");
|
|
532
|
-
SERIALIZE +=
|
|
533
|
-
indent +
|
|
534
|
-
`JSON.__serialize<${member.type}>(load<${member.type}>(ptr, offsetof<this>(${JSON.stringify(realName)})));\n`;
|
|
547
|
+
SERIALIZE += indent + getSerializeCall(member.type, realName);
|
|
535
548
|
if (isFirst)
|
|
536
549
|
isFirst = false;
|
|
537
550
|
}
|
|
@@ -541,26 +554,20 @@ export class JSONTransform extends Visitor {
|
|
|
541
554
|
SERIALIZE += this.getStores(keyPart, SIMD_ENABLED)
|
|
542
555
|
.map((v) => indent + v + "\n")
|
|
543
556
|
.join("");
|
|
544
|
-
SERIALIZE +=
|
|
545
|
-
indent +
|
|
546
|
-
`JSON.__serialize<${member.type}>(load<${member.type}>(ptr, offsetof<this>(${JSON.stringify(realName)})));\n`;
|
|
557
|
+
SERIALIZE += indent + getSerializeCall(member.type, realName);
|
|
547
558
|
if (isFirst)
|
|
548
559
|
isFirst = false;
|
|
549
560
|
}
|
|
550
561
|
else {
|
|
551
562
|
if (member.flags.has(PropertyFlags.OmitNull)) {
|
|
552
|
-
SERIALIZE +=
|
|
553
|
-
indent +
|
|
554
|
-
`if ((block = load<usize>(ptr, offsetof<this>(${JSON.stringify(realName)}))) !== 0) {\n`;
|
|
563
|
+
SERIALIZE += indent + `if ((block = load<usize>(ptr, offsetof<this>(${JSON.stringify(realName)}))) !== 0) {\n`;
|
|
555
564
|
indentInc();
|
|
556
565
|
const keyPart = aliasName + ":";
|
|
557
566
|
this.schema.byteSize += keyPart.length << 1;
|
|
558
567
|
SERIALIZE += this.getStores(keyPart, SIMD_ENABLED)
|
|
559
568
|
.map((v) => indent + v + "\n")
|
|
560
569
|
.join("");
|
|
561
|
-
SERIALIZE +=
|
|
562
|
-
indent +
|
|
563
|
-
`JSON.__serialize<${member.type}>(load<${member.type}>(ptr, offsetof<this>(${JSON.stringify(realName)})));\n`;
|
|
570
|
+
SERIALIZE += indent + getSerializeCall(member.type, realName);
|
|
564
571
|
if (!isLast) {
|
|
565
572
|
this.schema.byteSize += 2;
|
|
566
573
|
SERIALIZE += indent + `store<u16>(bs.offset, 44, 0); // ,\n`;
|
|
@@ -574,25 +581,19 @@ export class JSONTransform extends Visitor {
|
|
|
574
581
|
if (member.flags.get(PropertyFlags.OmitIf).kind == 14) {
|
|
575
582
|
const arg = member.flags.get(PropertyFlags.OmitIf);
|
|
576
583
|
arg.declaration.signature.parameters[0].type = Node.createNamedType(Node.createSimpleTypeName("this", node.range), null, false, node.range);
|
|
577
|
-
arg.declaration.signature.returnType.name =
|
|
578
|
-
|
|
579
|
-
.range);
|
|
580
|
-
SERIALIZE +=
|
|
581
|
-
indent +
|
|
582
|
-
`if (!(${toString(member.flags.get(PropertyFlags.OmitIf))})(this)) {\n`;
|
|
584
|
+
arg.declaration.signature.returnType.name = Node.createSimpleTypeName("boolean", arg.declaration.signature.returnType.name.range);
|
|
585
|
+
SERIALIZE += indent + `if (!(${toString(member.flags.get(PropertyFlags.OmitIf))})(this)) {\n`;
|
|
583
586
|
}
|
|
584
587
|
else {
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
+
const expression = member.flags.get(PropertyFlags.OmitIf);
|
|
589
|
+
const rendered = expression.kind == 16 && expression.literalKind == 2 ? JSON.stringify(expression.value).slice(1, -1) : toString(expression);
|
|
590
|
+
SERIALIZE += indent + `if (!(${rendered})) {\n`;
|
|
588
591
|
}
|
|
589
592
|
indentInc();
|
|
590
593
|
SERIALIZE += this.getStores(aliasName + ":", SIMD_ENABLED)
|
|
591
594
|
.map((v) => indent + v + "\n")
|
|
592
595
|
.join("");
|
|
593
|
-
SERIALIZE +=
|
|
594
|
-
indent +
|
|
595
|
-
`JSON.__serialize<${member.type}>(load<${member.type}>(ptr, offsetof<this>(${JSON.stringify(realName)})));\n`;
|
|
596
|
+
SERIALIZE += indent + getSerializeCall(member.type, realName);
|
|
596
597
|
if (!isLast) {
|
|
597
598
|
this.schema.byteSize += 2;
|
|
598
599
|
SERIALIZE += indent + `store<u16>(bs.offset, 44, 0); // ,\n`;
|
|
@@ -613,13 +614,12 @@ export class JSONTransform extends Visitor {
|
|
|
613
614
|
};
|
|
614
615
|
for (const member of this.schema.members) {
|
|
615
616
|
const type = stripNull(member.type);
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
sortedMembers.
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
sortedMembers.null.push(member);
|
|
617
|
+
const customDep = this.schema.deps.find((dep) => dep && (dep.name == type || dep.name.endsWith("." + type)) && dep.custom);
|
|
618
|
+
const isCustomType = member.custom || !!customDep;
|
|
619
|
+
if (isCustomType || member.generic) {
|
|
620
|
+
addMemberToCustomBucket(sortedMembers, member, member.generic ? "any" : customDep?.customJsonKind || "any");
|
|
621
|
+
if (member.node.type.isNullable)
|
|
622
|
+
sortedMembers.null.push(member);
|
|
623
623
|
}
|
|
624
624
|
else {
|
|
625
625
|
if (member.node.type.isNullable)
|
|
@@ -628,9 +628,7 @@ export class JSONTransform extends Visitor {
|
|
|
628
628
|
sortedMembers.string.push(member);
|
|
629
629
|
else if (isBoolean(type) || type.startsWith("JSON.Box<bool"))
|
|
630
630
|
sortedMembers.boolean.push(member);
|
|
631
|
-
else if (isPrimitive(type) ||
|
|
632
|
-
type.startsWith("JSON.Box<") ||
|
|
633
|
-
isEnum(type, this.sources.get(this.schema.node.range.source), this.parser))
|
|
631
|
+
else if (isPrimitive(type) || type.startsWith("JSON.Box<") || isEnum(type, this.sources.get(this.schema.node.range.source), this.parser))
|
|
634
632
|
sortedMembers.number.push(member);
|
|
635
633
|
else if (isArray(type))
|
|
636
634
|
sortedMembers.array.push(member);
|
|
@@ -638,50 +636,270 @@ export class JSONTransform extends Visitor {
|
|
|
638
636
|
sortedMembers.object.push(member);
|
|
639
637
|
}
|
|
640
638
|
}
|
|
641
|
-
|
|
639
|
+
const getComparisions = (data, ptr, operator) => {
|
|
640
|
+
const dataBytes = data.length << 1;
|
|
641
|
+
let offset = 0;
|
|
642
|
+
const output = [];
|
|
643
|
+
while (offset < dataBytes) {
|
|
644
|
+
const rem = dataBytes - offset;
|
|
645
|
+
if (rem >= 8) {
|
|
646
|
+
output.push(`load<u64>(${ptr}, ${offset}) ${operator} 0x${toU64(data, offset >> 1).toString(16)}`);
|
|
647
|
+
offset += 8;
|
|
648
|
+
continue;
|
|
649
|
+
}
|
|
650
|
+
if (rem >= 4) {
|
|
651
|
+
output.push(`load<u32>(${ptr}, ${offset}) ${operator} 0x${toU32(data, offset >> 1).toString(16)}`);
|
|
652
|
+
offset += 4;
|
|
653
|
+
continue;
|
|
654
|
+
}
|
|
655
|
+
if (rem >= 2) {
|
|
656
|
+
output.push(`load<u16>(${ptr}, ${offset}) ${operator} 0x${data.charCodeAt(offset >> 1).toString(16)}`);
|
|
657
|
+
offset += 2;
|
|
658
|
+
continue;
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
return output;
|
|
662
|
+
};
|
|
663
|
+
const UNSIGNED_INTEGER_TYPES = ["u8", "u16", "u32", "u64", "usize"];
|
|
664
|
+
const SIGNED_INTEGER_TYPES = ["i8", "i16", "i32", "i64", "isize"];
|
|
665
|
+
const FLOAT_TYPES = ["f32", "f64"];
|
|
666
|
+
const INTEGER_TYPES = [...UNSIGNED_INTEGER_TYPES, ...SIGNED_INTEGER_TYPES];
|
|
667
|
+
const STRING_FIELD_DESERIALIZER = codegenMode === JSONMode.SIMD ? "deserializeStringField_SIMD" : "deserializeStringField_SWAR";
|
|
668
|
+
const getArrayValueType = (type) => {
|
|
669
|
+
if (type.startsWith("Array<") || type.startsWith("StaticArray<")) {
|
|
670
|
+
return stripNull(type.slice(type.indexOf("<") + 1, -1).trim());
|
|
671
|
+
}
|
|
672
|
+
return null;
|
|
673
|
+
};
|
|
674
|
+
const getDeserializer = (type, srcPtr, outPtr, member, keyOffset = 0) => {
|
|
675
|
+
const out = [];
|
|
676
|
+
const resolvedType = stripNull(type);
|
|
677
|
+
const fieldOffset = `offsetof<this>(${JSON.stringify(member.name)})`;
|
|
678
|
+
const fieldPtr = `${outPtr} + offsetof<this>(${JSON.stringify(member.name)})`;
|
|
679
|
+
const valuePtr = keyOffset ? `${srcPtr} + ${keyOffset}` : srcPtr;
|
|
680
|
+
if (INTEGER_TYPES.includes(resolvedType)) {
|
|
681
|
+
const helper = SIGNED_INTEGER_TYPES.includes(resolvedType) ? "deserializeIntegerField" : "deserializeUnsignedField";
|
|
682
|
+
out.push(`${srcPtr} = ${helper}<${resolvedType}>(${valuePtr}, srcEnd, ${fieldPtr});`);
|
|
683
|
+
}
|
|
684
|
+
else if (["string", "String"].includes(resolvedType)) {
|
|
685
|
+
out.push("{");
|
|
686
|
+
if (member.node.type.isNullable) {
|
|
687
|
+
out.push(` if (load<u64>(${valuePtr}) == 30399761348886638) {`);
|
|
688
|
+
out.push(` store<${member.type}>(${outPtr}, changetype<${member.type}>(0), ${fieldOffset});`);
|
|
689
|
+
out.push(` ${srcPtr} = ${valuePtr} + 8;`);
|
|
690
|
+
out.push(" } else {");
|
|
691
|
+
}
|
|
692
|
+
out.push(` ${srcPtr} = ${STRING_FIELD_DESERIALIZER}<${member.type}>(${valuePtr}, srcEnd, ${fieldPtr});`);
|
|
693
|
+
if (member.node.type.isNullable) {
|
|
694
|
+
out.push(" }");
|
|
695
|
+
}
|
|
696
|
+
out.push("}");
|
|
697
|
+
}
|
|
698
|
+
else if (isBoolean(resolvedType)) {
|
|
699
|
+
out.push("{");
|
|
700
|
+
out.push(` if (load<u64>(${srcPtr}) == 28429475166421108) {`);
|
|
701
|
+
out.push(` store<${resolvedType}>(${outPtr}, true, ${fieldOffset});`);
|
|
702
|
+
out.push(` ${srcPtr} += 8;`);
|
|
703
|
+
out.push(" } else if (load<u64>(" + srcPtr + ") == 32370086184550502 && load<u16>(" + srcPtr + ", 8) == 101) {");
|
|
704
|
+
out.push(` store<${resolvedType}>(${outPtr}, false, ${fieldOffset});`);
|
|
705
|
+
out.push(` ${srcPtr} += 10;`);
|
|
706
|
+
out.push(" } else break;");
|
|
707
|
+
out.push("}");
|
|
708
|
+
}
|
|
709
|
+
else if (FLOAT_TYPES.includes(resolvedType)) {
|
|
710
|
+
out.push(`${srcPtr} = deserializeFloatField<${resolvedType}>(${valuePtr}, srcEnd, ${fieldPtr});`);
|
|
711
|
+
}
|
|
712
|
+
else if (this.getSchema(resolvedType)) {
|
|
713
|
+
out.push("{");
|
|
714
|
+
if (member.node.type.isNullable) {
|
|
715
|
+
out.push(` if (load<u64>(${srcPtr}) == 30399761348886638) {`);
|
|
716
|
+
out.push(` store<${resolvedType}>(${outPtr}, changetype<${resolvedType}>(0), ${fieldOffset});`);
|
|
717
|
+
out.push(` ${srcPtr} += 8;`);
|
|
718
|
+
out.push(" } else {");
|
|
719
|
+
}
|
|
720
|
+
out.push(` let value = load<${resolvedType}>(${outPtr}, ${fieldOffset});`);
|
|
721
|
+
out.push(" if (changetype<usize>(value) == 0) {");
|
|
722
|
+
out.push(` value = changetype<${resolvedType}>(__new(offsetof<nonnull<${resolvedType}>>(), idof<nonnull<${resolvedType}>>()));`);
|
|
723
|
+
out.push(` store<${resolvedType}>(${outPtr}, value, ${fieldOffset});`);
|
|
724
|
+
out.push(" }");
|
|
725
|
+
out.push(` ${srcPtr} = changetype<nonnull<${resolvedType}>>(value).__DESERIALIZE<${resolvedType}>(${srcPtr}, srcEnd, value);`);
|
|
726
|
+
if (member.node.type.isNullable) {
|
|
727
|
+
out.push(" }");
|
|
728
|
+
}
|
|
729
|
+
out.push("}");
|
|
730
|
+
}
|
|
731
|
+
else if (resolvedType.startsWith("Array<")) {
|
|
732
|
+
const valueType = getArrayValueType(resolvedType);
|
|
733
|
+
if (valueType && ["string", "String"].includes(valueType)) {
|
|
734
|
+
out.push("{");
|
|
735
|
+
out.push(` if (load<u16>(${srcPtr}) != 0x5b) break;`);
|
|
736
|
+
out.push(` let value = load<${resolvedType}>(${outPtr}, ${fieldOffset});`);
|
|
737
|
+
out.push(" if (changetype<usize>(value) == 0) {");
|
|
738
|
+
out.push(` value = [];`);
|
|
739
|
+
out.push(` store<${resolvedType}>(${outPtr}, value, ${fieldOffset});`);
|
|
740
|
+
out.push(" }");
|
|
741
|
+
out.push(" let index = 0;");
|
|
742
|
+
out.push(` ${srcPtr} += 2;`);
|
|
743
|
+
out.push(` if (load<u16>(${srcPtr}) == 0x5d) {`);
|
|
744
|
+
out.push(" value.length = 0;");
|
|
745
|
+
out.push(` ${srcPtr} += 2;`);
|
|
746
|
+
out.push(" } else while (true) {");
|
|
747
|
+
out.push(' if (index >= value.length) value.push("");');
|
|
748
|
+
out.push(` ${srcPtr} = ${STRING_FIELD_DESERIALIZER}<${valueType}>(${srcPtr}, srcEnd, value.dataStart + ((<usize>index) << alignof<${valueType}>()));`);
|
|
749
|
+
out.push(" index++;");
|
|
750
|
+
out.push(` const code = load<u16>(${srcPtr});`);
|
|
751
|
+
out.push(" if (code == 0x2c) {");
|
|
752
|
+
out.push(` ${srcPtr} += 2;`);
|
|
753
|
+
out.push(" continue;");
|
|
754
|
+
out.push(" }");
|
|
755
|
+
out.push(" if (code == 0x5d) {");
|
|
756
|
+
out.push(" value.length = index;");
|
|
757
|
+
out.push(` ${srcPtr} += 2;`);
|
|
758
|
+
out.push(" break;");
|
|
759
|
+
out.push(" }");
|
|
760
|
+
out.push(" break;");
|
|
761
|
+
out.push(" }");
|
|
762
|
+
out.push("}");
|
|
763
|
+
}
|
|
764
|
+
else if (valueType && this.getSchema(valueType)) {
|
|
765
|
+
out.push("{");
|
|
766
|
+
out.push(` if (load<u16>(${srcPtr}) != 0x5b) break;`);
|
|
767
|
+
out.push(` let value = load<${resolvedType}>(${outPtr}, ${fieldOffset});`);
|
|
768
|
+
out.push(" if (changetype<usize>(value) == 0) {");
|
|
769
|
+
out.push(` value = [];`);
|
|
770
|
+
out.push(` store<${resolvedType}>(${outPtr}, value, ${fieldOffset});`);
|
|
771
|
+
out.push(" }");
|
|
772
|
+
out.push(" let index = 0;");
|
|
773
|
+
out.push(` ${srcPtr} += 2;`);
|
|
774
|
+
out.push(` if (load<u16>(${srcPtr}) == 0x5d) {`);
|
|
775
|
+
out.push(" value.length = 0;");
|
|
776
|
+
out.push(` ${srcPtr} += 2;`);
|
|
777
|
+
out.push(" } else while (true) {");
|
|
778
|
+
out.push(` let item: ${valueType};`);
|
|
779
|
+
out.push(" if (index < value.length) {");
|
|
780
|
+
out.push(" item = unchecked(value[index]);");
|
|
781
|
+
out.push(" if (changetype<usize>(item) == 0) {");
|
|
782
|
+
out.push(` item = changetype<${valueType}>(__new(offsetof<nonnull<${valueType}>>(), idof<nonnull<${valueType}>>()));`);
|
|
783
|
+
out.push(" unchecked((value[index] = item));");
|
|
784
|
+
out.push(" }");
|
|
785
|
+
out.push(" } else {");
|
|
786
|
+
out.push(` item = changetype<${valueType}>(__new(offsetof<nonnull<${valueType}>>(), idof<nonnull<${valueType}>>()));`);
|
|
787
|
+
out.push(" value.push(item);");
|
|
788
|
+
out.push(" }");
|
|
789
|
+
out.push(` ${srcPtr} = changetype<nonnull<${valueType}>>(item).__DESERIALIZE<${valueType}>(${srcPtr}, srcEnd, item);`);
|
|
790
|
+
out.push(" index++;");
|
|
791
|
+
out.push(` const code = load<u16>(${srcPtr});`);
|
|
792
|
+
out.push(" if (code == 0x2c) {");
|
|
793
|
+
out.push(` ${srcPtr} += 2;`);
|
|
794
|
+
out.push(" continue;");
|
|
795
|
+
out.push(" }");
|
|
796
|
+
out.push(" if (code == 0x5d) {");
|
|
797
|
+
out.push(" value.length = index;");
|
|
798
|
+
out.push(` ${srcPtr} += 2;`);
|
|
799
|
+
out.push(" break;");
|
|
800
|
+
out.push(" }");
|
|
801
|
+
out.push(" break;");
|
|
802
|
+
out.push(" }");
|
|
803
|
+
out.push("}");
|
|
804
|
+
}
|
|
805
|
+
else {
|
|
806
|
+
out.push(`${srcPtr} = deserializeArrayField_SWAR<${resolvedType}>(${srcPtr}, srcEnd, ${fieldPtr});`);
|
|
807
|
+
out.push(`if (!${srcPtr}) break;`);
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
else {
|
|
811
|
+
out.push("{");
|
|
812
|
+
out.push(` const valueStart = ${srcPtr};`);
|
|
813
|
+
out.push(" let depth: i32 = 0;");
|
|
814
|
+
out.push(" let inString = false;");
|
|
815
|
+
out.push(` while (${srcPtr} < srcEnd) {`);
|
|
816
|
+
out.push(` const code = load<u16>(${srcPtr});`);
|
|
817
|
+
out.push(" if (inString) {");
|
|
818
|
+
out.push(` if (code == 0x22 && load<u16>(${srcPtr} - 2) != 0x5c) inString = false;`);
|
|
819
|
+
out.push(` ${srcPtr} += 2;`);
|
|
820
|
+
out.push(" continue;");
|
|
821
|
+
out.push(" }");
|
|
822
|
+
out.push(" if (code == 0x22) {");
|
|
823
|
+
out.push(" inString = true;");
|
|
824
|
+
out.push(` ${srcPtr} += 2;`);
|
|
825
|
+
out.push(" continue;");
|
|
826
|
+
out.push(" }");
|
|
827
|
+
out.push(" if (code == 0x7b || code == 0x5b) {");
|
|
828
|
+
out.push(" depth++;");
|
|
829
|
+
out.push(` ${srcPtr} += 2;`);
|
|
830
|
+
out.push(" continue;");
|
|
831
|
+
out.push(" }");
|
|
832
|
+
out.push(" if (code == 0x7d || code == 0x5d) {");
|
|
833
|
+
out.push(" if (depth == 0) break;");
|
|
834
|
+
out.push(" depth--;");
|
|
835
|
+
out.push(` ${srcPtr} += 2;`);
|
|
836
|
+
out.push(" continue;");
|
|
837
|
+
out.push(" }");
|
|
838
|
+
out.push(" if (code == 0x2c && depth == 0) break;");
|
|
839
|
+
out.push(` ${srcPtr} += 2;`);
|
|
840
|
+
out.push(" }");
|
|
841
|
+
out.push(` if (inString || depth != 0 || ${srcPtr} <= valueStart) break;`);
|
|
842
|
+
out.push(` store<${resolvedType}>(${outPtr}, JSON.__deserialize<${resolvedType}>(valueStart, ${srcPtr}), ${fieldOffset});`);
|
|
843
|
+
out.push("}");
|
|
844
|
+
}
|
|
845
|
+
return out;
|
|
846
|
+
};
|
|
847
|
+
indent = " ";
|
|
848
|
+
DESERIALIZE_FAST += indent + "const dst = changetype<usize>(out);\n";
|
|
849
|
+
DESERIALIZE_FAST += indent + "do {\n";
|
|
850
|
+
indent += " ";
|
|
851
|
+
for (let i = 0; i < this.schema.members.length; i++) {
|
|
852
|
+
const member = this.schema.members[i];
|
|
853
|
+
const key = JSON.stringify(member.alias || member.name);
|
|
854
|
+
if (key.length <= 2)
|
|
855
|
+
throw new Error("Key cannot be empty!");
|
|
856
|
+
const keySection = (i == 0 ? "{" : ",") + key + ":";
|
|
857
|
+
DESERIALIZE_FAST += indent + `if ( // ${keySection}\n${(indent += " ")}${getComparisions(keySection, "srcStart", "!=").join("\n" + indent + "|| ")}\n${(indent = indent.slice(0, -2))}) break;\n`;
|
|
858
|
+
const keyOffset = keySection.length << 1;
|
|
859
|
+
const resolvedType = stripNull(member.type);
|
|
860
|
+
const inlineStringValue = ["string", "String"].includes(resolvedType);
|
|
861
|
+
if (!inlineStringValue) {
|
|
862
|
+
DESERIALIZE_FAST += indent + `srcStart += ${keyOffset};\n\n`;
|
|
863
|
+
}
|
|
864
|
+
const deserializer = getDeserializer(member.type, "srcStart", "dst", member, inlineStringValue ? keyOffset : 0);
|
|
865
|
+
if (!deserializer.length) {
|
|
866
|
+
DESERIALIZE_FAST += indent + "break;\n\n";
|
|
867
|
+
continue;
|
|
868
|
+
}
|
|
869
|
+
DESERIALIZE_FAST += indent + deserializer.join("\n" + indent) + "\n\n";
|
|
870
|
+
}
|
|
871
|
+
DESERIALIZE_FAST += indent + "if (load<u16>(srcStart) !== 0x7d) break; // }\n";
|
|
872
|
+
DESERIALIZE_FAST += indent + "srcStart += 2;\n";
|
|
873
|
+
DESERIALIZE_FAST += indent + "return srcStart;\n";
|
|
874
|
+
indent = indent.slice(0, -2);
|
|
875
|
+
DESERIALIZE_FAST += indent + "} while (false);\n\n";
|
|
876
|
+
DESERIALIZE_FAST += indent + 'throw new Error("Failed to parse JSON ");';
|
|
877
|
+
indent = indent.slice(0, -2);
|
|
878
|
+
DESERIALIZE_FAST += indent + "}";
|
|
642
879
|
DESERIALIZE += indent + " let keyStart: usize = 0;\n";
|
|
643
880
|
DESERIALIZE += indent + " let keyEnd: usize = 0;\n";
|
|
644
881
|
DESERIALIZE += indent + " let isKey = false;\n";
|
|
645
882
|
if (!STRICT || sortedMembers.object.length || sortedMembers.array.length)
|
|
646
883
|
DESERIALIZE += indent + " let depth: i32 = 0;\n";
|
|
647
884
|
DESERIALIZE += indent + " let lastIndex: usize = 0;\n\n";
|
|
648
|
-
DESERIALIZE +=
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
DESERIALIZE +=
|
|
652
|
-
|
|
653
|
-
" while (srcEnd > srcStart && JSON.Util.isSpace(load<u16>(srcEnd - 2))) srcEnd -= 2;\n";
|
|
654
|
-
DESERIALIZE +=
|
|
655
|
-
indent +
|
|
656
|
-
' if (srcStart - srcEnd == 0) throw new Error("Input string had zero length or was all whitespace");\n';
|
|
657
|
-
DESERIALIZE +=
|
|
658
|
-
indent +
|
|
659
|
-
" if (load<u16>(srcStart) != 123) throw new Error(\"Expected '{' at start of object at position \" + (srcEnd - srcStart).toString());\n";
|
|
660
|
-
DESERIALIZE +=
|
|
661
|
-
indent +
|
|
662
|
-
" if (load<u16>(srcEnd - 2) != 125) throw new Error(\"Expected '}' at end of object at position \" + (srcEnd - srcStart).toString());\n";
|
|
885
|
+
DESERIALIZE += indent + " while (srcStart < srcEnd && JSON.Util.isSpace(load<u16>(srcStart))) srcStart += 2;\n";
|
|
886
|
+
DESERIALIZE += indent + " while (srcEnd > srcStart && JSON.Util.isSpace(load<u16>(srcEnd - 2))) srcEnd -= 2;\n";
|
|
887
|
+
DESERIALIZE += indent + ' if (srcStart - srcEnd == 0) throw new Error("Input string had zero length or was all whitespace");\n';
|
|
888
|
+
DESERIALIZE += indent + " if (load<u16>(srcStart) != 123) throw new Error(\"Expected '{' at start of object at position \" + (srcEnd - srcStart).toString());\n";
|
|
889
|
+
DESERIALIZE += indent + " if (load<u16>(srcEnd - 2) != 125) throw new Error(\"Expected '}' at end of object at position \" + (srcEnd - srcStart).toString());\n";
|
|
663
890
|
DESERIALIZE += indent + " srcStart += 2;\n\n";
|
|
664
891
|
DESERIALIZE += indent + " while (srcStart < srcEnd) {\n";
|
|
665
892
|
DESERIALIZE += indent + " let code = load<u16>(srcStart);\n";
|
|
666
|
-
DESERIALIZE +=
|
|
667
|
-
indent +
|
|
668
|
-
" while (JSON.Util.isSpace(code)) code = load<u16>(srcStart += 2);\n";
|
|
893
|
+
DESERIALIZE += indent + " while (JSON.Util.isSpace(code)) code = load<u16>(srcStart += 2);\n";
|
|
669
894
|
DESERIALIZE += indent + " if (keyStart == 0) {\n";
|
|
670
|
-
DESERIALIZE +=
|
|
671
|
-
indent + " if (code == 34 && load<u16>(srcStart - 2) !== 92) {\n";
|
|
895
|
+
DESERIALIZE += indent + " if (code == 34 && load<u16>(srcStart - 2) !== 92) {\n";
|
|
672
896
|
DESERIALIZE += indent + " if (isKey) {\n";
|
|
673
897
|
DESERIALIZE += indent + " keyStart = lastIndex;\n";
|
|
674
898
|
DESERIALIZE += indent + " keyEnd = srcStart;\n";
|
|
675
899
|
if (DEBUG > 1)
|
|
676
|
-
DESERIALIZE +=
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
DESERIALIZE +=
|
|
680
|
-
indent +
|
|
681
|
-
" while (JSON.Util.isSpace((code = load<u16>((srcStart += 2))))) {}\n";
|
|
682
|
-
DESERIALIZE +=
|
|
683
|
-
indent +
|
|
684
|
-
" if (code !== 58) throw new Error(\"Expected ':' after key at position \" + (srcEnd - srcStart).toString());\n";
|
|
900
|
+
DESERIALIZE += indent + ' console.log("Key: " + JSON.Util.ptrToStr(keyStart, keyEnd));\n';
|
|
901
|
+
DESERIALIZE += indent + " while (JSON.Util.isSpace((code = load<u16>((srcStart += 2))))) {}\n";
|
|
902
|
+
DESERIALIZE += indent + " if (code !== 58) throw new Error(\"Expected ':' after key at position \" + (srcEnd - srcStart).toString());\n";
|
|
685
903
|
DESERIALIZE += indent + " isKey = false;\n";
|
|
686
904
|
DESERIALIZE += indent + " } else {\n";
|
|
687
905
|
DESERIALIZE += indent + " isKey = true;\n";
|
|
@@ -711,9 +929,7 @@ export class JSONTransform extends Visitor {
|
|
|
711
929
|
const generateGroups = (members, cb, type) => {
|
|
712
930
|
if (!members.length) {
|
|
713
931
|
if (STRICT) {
|
|
714
|
-
DESERIALIZE +=
|
|
715
|
-
indent +
|
|
716
|
-
' throw new Error("Unexpected key value pair in JSON object \'" + JSON.Util.ptrToStr(keyStart, keyEnd) + ":" + JSON.Util.ptrToStr(lastIndex, srcStart) + "\' at position " + (srcEnd - srcStart).toString());\n';
|
|
932
|
+
DESERIALIZE += indent + ' throw new Error("Unexpected key value pair in JSON object \'" + JSON.Util.ptrToStr(keyStart, keyEnd) + ":" + JSON.Util.ptrToStr(lastIndex, srcStart) + "\' at position " + (srcEnd - srcStart).toString());\n';
|
|
717
933
|
}
|
|
718
934
|
else {
|
|
719
935
|
if (type == "string") {
|
|
@@ -723,10 +939,7 @@ export class JSONTransform extends Visitor {
|
|
|
723
939
|
DESERIALIZE += indent + " srcStart += 2;\n";
|
|
724
940
|
}
|
|
725
941
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
726
|
-
if (type == "string" ||
|
|
727
|
-
type == "object" ||
|
|
728
|
-
type == "array" ||
|
|
729
|
-
type == "number")
|
|
942
|
+
if (type == "string" || type == "object" || type == "array" || type == "number")
|
|
730
943
|
DESERIALIZE += indent + " break;\n";
|
|
731
944
|
}
|
|
732
945
|
}
|
|
@@ -741,9 +954,7 @@ export class JSONTransform extends Visitor {
|
|
|
741
954
|
}
|
|
742
955
|
DESERIALIZE += " default: {\n";
|
|
743
956
|
if (STRICT) {
|
|
744
|
-
DESERIALIZE +=
|
|
745
|
-
indent +
|
|
746
|
-
' throw new Error("Unexpected key value pair in JSON object \'" + JSON.Util.ptrToStr(keyStart, keyEnd) + ":" + JSON.Util.ptrToStr(lastIndex, srcStart) + "\' at position " + (srcEnd - srcStart).toString());\n';
|
|
957
|
+
DESERIALIZE += indent + ' throw new Error("Unexpected key value pair in JSON object \'" + JSON.Util.ptrToStr(keyStart, keyEnd) + ":" + JSON.Util.ptrToStr(lastIndex, srcStart) + "\' at position " + (srcEnd - srcStart).toString());\n';
|
|
747
958
|
}
|
|
748
959
|
else {
|
|
749
960
|
if (type == "string") {
|
|
@@ -753,10 +964,7 @@ export class JSONTransform extends Visitor {
|
|
|
753
964
|
DESERIALIZE += indent + " srcStart += 2;\n";
|
|
754
965
|
}
|
|
755
966
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
756
|
-
if (type == "string" ||
|
|
757
|
-
type == "object" ||
|
|
758
|
-
type == "array" ||
|
|
759
|
-
type == "number")
|
|
967
|
+
if (type == "string" || type == "object" || type == "array" || type == "number")
|
|
760
968
|
DESERIALIZE += indent + " break;\n";
|
|
761
969
|
}
|
|
762
970
|
DESERIALIZE += " }\n";
|
|
@@ -773,8 +981,7 @@ export class JSONTransform extends Visitor {
|
|
|
773
981
|
DESERIALIZE += " const code32 = load<u32>(keyStart);\n";
|
|
774
982
|
}
|
|
775
983
|
if (members.some((m) => (m.alias || m.name).length << 1 == 6)) {
|
|
776
|
-
DESERIALIZE +=
|
|
777
|
-
" const code48 = load<u64>(keyStart) & 0x0000FFFFFFFFFFFF;\n";
|
|
984
|
+
DESERIALIZE += " const code48 = load<u64>(keyStart) & 0x0000FFFFFFFFFFFF;\n";
|
|
778
985
|
}
|
|
779
986
|
if (members.some((m) => (m.alias || m.name).length << 1 == 8)) {
|
|
780
987
|
DESERIALIZE += " const code64 = load<u64>(keyStart);\n";
|
|
@@ -790,34 +997,15 @@ export class JSONTransform extends Visitor {
|
|
|
790
997
|
DESERIALIZE += " srcStart += 2;\n";
|
|
791
998
|
DESERIALIZE += " while (srcStart < srcEnd) {\n";
|
|
792
999
|
DESERIALIZE += " const code = load<u16>(srcStart);\n";
|
|
793
|
-
DESERIALIZE +=
|
|
794
|
-
" if (code == 34 && load<u16>(srcStart - 2) !== 92) {\n";
|
|
1000
|
+
DESERIALIZE += " if (code == 34 && load<u16>(srcStart - 2) !== 92) {\n";
|
|
795
1001
|
if (DEBUG > 1)
|
|
796
|
-
DESERIALIZE +=
|
|
797
|
-
' console.log("Value (string, ' +
|
|
798
|
-
++id +
|
|
799
|
-
'): " + JSON.Util.ptrToStr(lastIndex, srcStart + 2));';
|
|
1002
|
+
DESERIALIZE += ' console.log("Value (string, ' + ++id + '): " + JSON.Util.ptrToStr(lastIndex, srcStart + 2));';
|
|
800
1003
|
generateGroups(sortedMembers.string, (group) => {
|
|
801
1004
|
generateConsts(group);
|
|
802
1005
|
const first = group[0];
|
|
803
1006
|
const fName = first.alias || first.name;
|
|
804
|
-
DESERIALIZE +=
|
|
805
|
-
|
|
806
|
-
" if (" +
|
|
807
|
-
(first.generic ? "isString<" + first.type + ">() && " : "") +
|
|
808
|
-
getComparison(fName) +
|
|
809
|
-
") { // " +
|
|
810
|
-
fName +
|
|
811
|
-
"\n";
|
|
812
|
-
DESERIALIZE +=
|
|
813
|
-
indent +
|
|
814
|
-
" store<" +
|
|
815
|
-
first.type +
|
|
816
|
-
">(changetype<usize>(out), JSON.__deserialize<" +
|
|
817
|
-
first.type +
|
|
818
|
-
">(lastIndex, srcStart + 2), offsetof<this>(" +
|
|
819
|
-
JSON.stringify(first.name) +
|
|
820
|
-
"));\n";
|
|
1007
|
+
DESERIALIZE += indent + " if (" + (first.generic ? "isString<" + first.type + ">() && " : "") + getComparison(fName) + ") { // " + fName + "\n";
|
|
1008
|
+
DESERIALIZE += indent + " store<" + first.type + ">(changetype<usize>(out), JSON.__deserialize<" + first.type + ">(lastIndex, srcStart + 2), offsetof<this>(" + JSON.stringify(first.name) + "));\n";
|
|
821
1009
|
DESERIALIZE += indent + " srcStart += 4;\n";
|
|
822
1010
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
823
1011
|
DESERIALIZE += indent + " break;\n";
|
|
@@ -825,23 +1013,8 @@ export class JSONTransform extends Visitor {
|
|
|
825
1013
|
for (let i = 1; i < group.length; i++) {
|
|
826
1014
|
const mem = group[i];
|
|
827
1015
|
const memName = mem.alias || mem.name;
|
|
828
|
-
DESERIALIZE +=
|
|
829
|
-
|
|
830
|
-
" else if (" +
|
|
831
|
-
(mem.generic ? "isString<" + mem.type + ">() && " : "") +
|
|
832
|
-
getComparison(memName) +
|
|
833
|
-
") { // " +
|
|
834
|
-
memName +
|
|
835
|
-
"\n";
|
|
836
|
-
DESERIALIZE +=
|
|
837
|
-
indent +
|
|
838
|
-
" store<" +
|
|
839
|
-
mem.type +
|
|
840
|
-
">(changetype<usize>(out), JSON.__deserialize<" +
|
|
841
|
-
mem.type +
|
|
842
|
-
">(lastIndex, srcStart + 2), offsetof<this>(" +
|
|
843
|
-
JSON.stringify(mem.name) +
|
|
844
|
-
"));\n";
|
|
1016
|
+
DESERIALIZE += indent + " else if (" + (mem.generic ? "isString<" + mem.type + ">() && " : "") + getComparison(memName) + ") { // " + memName + "\n";
|
|
1017
|
+
DESERIALIZE += indent + " store<" + mem.type + ">(changetype<usize>(out), JSON.__deserialize<" + mem.type + ">(lastIndex, srcStart + 2), offsetof<this>(" + JSON.stringify(mem.name) + "));\n";
|
|
845
1018
|
DESERIALIZE += indent + " srcStart += 4;\n";
|
|
846
1019
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
847
1020
|
DESERIALIZE += indent + " break;\n";
|
|
@@ -849,9 +1022,7 @@ export class JSONTransform extends Visitor {
|
|
|
849
1022
|
}
|
|
850
1023
|
if (STRICT) {
|
|
851
1024
|
DESERIALIZE += " else {\n";
|
|
852
|
-
DESERIALIZE +=
|
|
853
|
-
indent +
|
|
854
|
-
' throw new Error("Unexpected key value pair in JSON object \'" + JSON.Util.ptrToStr(keyStart, keyEnd) + ":" + JSON.Util.ptrToStr(lastIndex, srcStart) + "\' at position " + (srcEnd - srcStart).toString());\n';
|
|
1025
|
+
DESERIALIZE += indent + ' throw new Error("Unexpected key value pair in JSON object \'" + JSON.Util.ptrToStr(keyStart, keyEnd) + ":" + JSON.Util.ptrToStr(lastIndex, srcStart) + "\' at position " + (srcEnd - srcStart).toString());\n';
|
|
855
1026
|
DESERIALIZE += indent + " }\n";
|
|
856
1027
|
}
|
|
857
1028
|
else {
|
|
@@ -874,40 +1045,15 @@ export class JSONTransform extends Visitor {
|
|
|
874
1045
|
DESERIALIZE += " srcStart += 2;\n";
|
|
875
1046
|
DESERIALIZE += " while (srcStart < srcEnd) {\n";
|
|
876
1047
|
DESERIALIZE += " const code = load<u16>(srcStart);\n";
|
|
877
|
-
DESERIALIZE +=
|
|
878
|
-
" if (code == 44 || code == 125 || JSON.Util.isSpace(code)) {\n";
|
|
1048
|
+
DESERIALIZE += " if (code == 44 || code == 125 || JSON.Util.isSpace(code)) {\n";
|
|
879
1049
|
if (DEBUG > 1)
|
|
880
|
-
DESERIALIZE +=
|
|
881
|
-
' console.log("Value (number, ' +
|
|
882
|
-
++id +
|
|
883
|
-
'): " + JSON.Util.ptrToStr(lastIndex, srcStart));';
|
|
1050
|
+
DESERIALIZE += ' console.log("Value (number, ' + ++id + '): " + JSON.Util.ptrToStr(lastIndex, srcStart));';
|
|
884
1051
|
generateGroups(sortedMembers.number, (group) => {
|
|
885
1052
|
generateConsts(group);
|
|
886
1053
|
const first = group[0];
|
|
887
1054
|
const fName = first.alias || first.name;
|
|
888
|
-
DESERIALIZE +=
|
|
889
|
-
|
|
890
|
-
" if (" +
|
|
891
|
-
(first.generic
|
|
892
|
-
? "(isInteger<" +
|
|
893
|
-
first.type +
|
|
894
|
-
">() || isFloat<" +
|
|
895
|
-
first.type +
|
|
896
|
-
">()) && "
|
|
897
|
-
: "") +
|
|
898
|
-
getComparison(fName) +
|
|
899
|
-
") { // " +
|
|
900
|
-
fName +
|
|
901
|
-
"\n";
|
|
902
|
-
DESERIALIZE +=
|
|
903
|
-
indent +
|
|
904
|
-
" store<" +
|
|
905
|
-
first.type +
|
|
906
|
-
">(changetype<usize>(out), JSON.__deserialize<" +
|
|
907
|
-
first.type +
|
|
908
|
-
">(lastIndex, srcStart), offsetof<this>(" +
|
|
909
|
-
JSON.stringify(first.name) +
|
|
910
|
-
"));\n";
|
|
1055
|
+
DESERIALIZE += indent + " if (" + (first.generic ? "(isInteger<" + first.type + ">() || isFloat<" + first.type + ">()) && " : "") + getComparison(fName) + ") { // " + fName + "\n";
|
|
1056
|
+
DESERIALIZE += indent + " store<" + first.type + ">(changetype<usize>(out), JSON.__deserialize<" + first.type + ">(lastIndex, srcStart), offsetof<this>(" + JSON.stringify(first.name) + "));\n";
|
|
911
1057
|
DESERIALIZE += indent + " srcStart += 2;\n";
|
|
912
1058
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
913
1059
|
DESERIALIZE += indent + " break;\n";
|
|
@@ -915,29 +1061,8 @@ export class JSONTransform extends Visitor {
|
|
|
915
1061
|
for (let i = 1; i < group.length; i++) {
|
|
916
1062
|
const mem = group[i];
|
|
917
1063
|
const memName = mem.alias || mem.name;
|
|
918
|
-
DESERIALIZE +=
|
|
919
|
-
|
|
920
|
-
" else if (" +
|
|
921
|
-
(mem.generic
|
|
922
|
-
? "(isInteger<" +
|
|
923
|
-
mem.type +
|
|
924
|
-
">() || isFloat<" +
|
|
925
|
-
mem.type +
|
|
926
|
-
">()) && "
|
|
927
|
-
: "") +
|
|
928
|
-
getComparison(memName) +
|
|
929
|
-
") { // " +
|
|
930
|
-
memName +
|
|
931
|
-
"\n";
|
|
932
|
-
DESERIALIZE +=
|
|
933
|
-
indent +
|
|
934
|
-
" store<" +
|
|
935
|
-
mem.type +
|
|
936
|
-
">(changetype<usize>(out), JSON.__deserialize<" +
|
|
937
|
-
mem.type +
|
|
938
|
-
">(lastIndex, srcStart), offsetof<this>(" +
|
|
939
|
-
JSON.stringify(mem.name) +
|
|
940
|
-
"));\n";
|
|
1064
|
+
DESERIALIZE += indent + " else if (" + (mem.generic ? "(isInteger<" + mem.type + ">() || isFloat<" + mem.type + ">()) && " : "") + getComparison(memName) + ") { // " + memName + "\n";
|
|
1065
|
+
DESERIALIZE += indent + " store<" + mem.type + ">(changetype<usize>(out), JSON.__deserialize<" + mem.type + ">(lastIndex, srcStart), offsetof<this>(" + JSON.stringify(mem.name) + "));\n";
|
|
941
1066
|
DESERIALIZE += indent + " srcStart += 2;\n";
|
|
942
1067
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
943
1068
|
DESERIALIZE += indent + " break;\n";
|
|
@@ -945,9 +1070,7 @@ export class JSONTransform extends Visitor {
|
|
|
945
1070
|
}
|
|
946
1071
|
if (STRICT) {
|
|
947
1072
|
DESERIALIZE += " else {\n";
|
|
948
|
-
DESERIALIZE +=
|
|
949
|
-
indent +
|
|
950
|
-
' throw new Error("Unexpected key value pair in JSON object \'" + JSON.Util.ptrToStr(keyStart, keyEnd) + ":" + JSON.Util.ptrToStr(lastIndex, srcStart) + "\' at position " + (srcEnd - srcStart).toString());\n';
|
|
1073
|
+
DESERIALIZE += indent + ' throw new Error("Unexpected key value pair in JSON object \'" + JSON.Util.ptrToStr(keyStart, keyEnd) + ":" + JSON.Util.ptrToStr(lastIndex, srcStart) + "\' at position " + (srcEnd - srcStart).toString());\n';
|
|
951
1074
|
DESERIALIZE += indent + " }\n";
|
|
952
1075
|
}
|
|
953
1076
|
else {
|
|
@@ -973,70 +1096,34 @@ export class JSONTransform extends Visitor {
|
|
|
973
1096
|
DESERIALIZE += " const code = load<u16>(srcStart);\n";
|
|
974
1097
|
DESERIALIZE += " if (code == 34) {\n";
|
|
975
1098
|
DESERIALIZE += " srcStart += 2;\n";
|
|
976
|
-
DESERIALIZE +=
|
|
977
|
-
" while (!(load<u16>(srcStart) == 34 && load<u16>(srcStart - 2) != 92)) srcStart += 2;\n";
|
|
1099
|
+
DESERIALIZE += " while (!(load<u16>(srcStart) == 34 && load<u16>(srcStart - 2) != 92)) srcStart += 2;\n";
|
|
978
1100
|
DESERIALIZE += " } else if (code == 125) {\n";
|
|
979
1101
|
DESERIALIZE += " if (--depth == 0) {\n";
|
|
980
1102
|
DESERIALIZE += " srcStart += 2;\n";
|
|
981
1103
|
if (DEBUG > 1)
|
|
982
|
-
DESERIALIZE +=
|
|
983
|
-
' console.log("Value (object, ' +
|
|
984
|
-
++id +
|
|
985
|
-
'): " + JSON.Util.ptrToStr(lastIndex, srcStart));';
|
|
1104
|
+
DESERIALIZE += ' console.log("Value (object, ' + ++id + '): " + JSON.Util.ptrToStr(lastIndex, srcStart));';
|
|
986
1105
|
indent = " ";
|
|
987
1106
|
generateGroups(sortedMembers.object, (group) => {
|
|
988
1107
|
generateConsts(group);
|
|
989
1108
|
const first = group[0];
|
|
990
1109
|
const fName = first.alias || first.name;
|
|
991
|
-
DESERIALIZE +=
|
|
992
|
-
|
|
993
|
-
" if (" +
|
|
994
|
-
(first.generic ? "isDefined(out.__DESERIALIZE) &&" : "") +
|
|
995
|
-
getComparison(fName) +
|
|
996
|
-
") { // " +
|
|
997
|
-
fName +
|
|
998
|
-
"\n";
|
|
999
|
-
DESERIALIZE +=
|
|
1000
|
-
indent +
|
|
1001
|
-
" store<" +
|
|
1002
|
-
first.type +
|
|
1003
|
-
">(changetype<usize>(out), JSON.__deserialize<" +
|
|
1004
|
-
first.type +
|
|
1005
|
-
">(lastIndex, srcStart), offsetof<this>(" +
|
|
1006
|
-
JSON.stringify(first.name) +
|
|
1007
|
-
"));\n";
|
|
1110
|
+
DESERIALIZE += indent + " if (" + (first.generic ? "isDefined(out.__DESERIALIZE) &&" : "") + getComparison(fName) + ") { // " + fName + "\n";
|
|
1111
|
+
DESERIALIZE += indent + " store<" + first.type + ">(changetype<usize>(out), JSON.__deserialize<" + first.type + ">(lastIndex, srcStart), offsetof<this>(" + JSON.stringify(first.name) + "));\n";
|
|
1008
1112
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
1009
1113
|
DESERIALIZE += indent + " break;\n";
|
|
1010
1114
|
DESERIALIZE += indent + " }";
|
|
1011
1115
|
for (let i = 1; i < group.length; i++) {
|
|
1012
1116
|
const mem = group[i];
|
|
1013
1117
|
const memName = mem.alias || mem.name;
|
|
1014
|
-
DESERIALIZE +=
|
|
1015
|
-
|
|
1016
|
-
" else if (" +
|
|
1017
|
-
(mem.generic ? "isDefined(out.__DESERIALIZE) &&" : "") +
|
|
1018
|
-
getComparison(memName) +
|
|
1019
|
-
") { // " +
|
|
1020
|
-
memName +
|
|
1021
|
-
"\n";
|
|
1022
|
-
DESERIALIZE +=
|
|
1023
|
-
indent +
|
|
1024
|
-
" store<" +
|
|
1025
|
-
mem.type +
|
|
1026
|
-
">(changetype<usize>(out), JSON.__deserialize<" +
|
|
1027
|
-
mem.type +
|
|
1028
|
-
">(lastIndex, srcStart), offsetof<this>(" +
|
|
1029
|
-
JSON.stringify(mem.name) +
|
|
1030
|
-
"));\n";
|
|
1118
|
+
DESERIALIZE += indent + " else if (" + (mem.generic ? "isDefined(out.__DESERIALIZE) &&" : "") + getComparison(memName) + ") { // " + memName + "\n";
|
|
1119
|
+
DESERIALIZE += indent + " store<" + mem.type + ">(changetype<usize>(out), JSON.__deserialize<" + mem.type + ">(lastIndex, srcStart), offsetof<this>(" + JSON.stringify(mem.name) + "));\n";
|
|
1031
1120
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
1032
1121
|
DESERIALIZE += indent + " break;\n";
|
|
1033
1122
|
DESERIALIZE += indent + " }";
|
|
1034
1123
|
}
|
|
1035
1124
|
if (STRICT) {
|
|
1036
1125
|
DESERIALIZE += " else {\n";
|
|
1037
|
-
DESERIALIZE +=
|
|
1038
|
-
indent +
|
|
1039
|
-
' throw new Error("Unexpected key value pair in JSON object \'" + JSON.Util.ptrToStr(keyStart, keyEnd) + ":" + JSON.Util.ptrToStr(lastIndex, srcStart) + "\' at position " + (srcEnd - srcStart).toString());\n';
|
|
1126
|
+
DESERIALIZE += indent + ' throw new Error("Unexpected key value pair in JSON object \'" + JSON.Util.ptrToStr(keyStart, keyEnd) + ":" + JSON.Util.ptrToStr(lastIndex, srcStart) + "\' at position " + (srcEnd - srcStart).toString());\n';
|
|
1040
1127
|
DESERIALIZE += indent + " }\n";
|
|
1041
1128
|
}
|
|
1042
1129
|
else {
|
|
@@ -1063,70 +1150,34 @@ export class JSONTransform extends Visitor {
|
|
|
1063
1150
|
DESERIALIZE += " const code = load<u16>(srcStart);\n";
|
|
1064
1151
|
DESERIALIZE += " if (code == 34) {\n";
|
|
1065
1152
|
DESERIALIZE += " srcStart += 2;\n";
|
|
1066
|
-
DESERIALIZE +=
|
|
1067
|
-
" while (!(load<u16>(srcStart) == 34 && load<u16>(srcStart - 2) != 92)) srcStart += 2;\n";
|
|
1153
|
+
DESERIALIZE += " while (!(load<u16>(srcStart) == 34 && load<u16>(srcStart - 2) != 92)) srcStart += 2;\n";
|
|
1068
1154
|
DESERIALIZE += " } else if (code == 93) {\n";
|
|
1069
1155
|
DESERIALIZE += " if (--depth == 0) {\n";
|
|
1070
1156
|
DESERIALIZE += " srcStart += 2;\n";
|
|
1071
1157
|
if (DEBUG > 1)
|
|
1072
|
-
DESERIALIZE +=
|
|
1073
|
-
' console.log("Value (object, ' +
|
|
1074
|
-
++id +
|
|
1075
|
-
'): " + JSON.Util.ptrToStr(lastIndex, srcStart));';
|
|
1158
|
+
DESERIALIZE += ' console.log("Value (object, ' + ++id + '): " + JSON.Util.ptrToStr(lastIndex, srcStart));';
|
|
1076
1159
|
indent = " ";
|
|
1077
1160
|
generateGroups(sortedMembers.array, (group) => {
|
|
1078
1161
|
generateConsts(group);
|
|
1079
1162
|
const first = group[0];
|
|
1080
1163
|
const fName = first.alias || first.name;
|
|
1081
|
-
DESERIALIZE +=
|
|
1082
|
-
|
|
1083
|
-
" if (" +
|
|
1084
|
-
(first.generic ? "isArray<" + first.type + ">() && " : "") +
|
|
1085
|
-
getComparison(fName) +
|
|
1086
|
-
") { // " +
|
|
1087
|
-
fName +
|
|
1088
|
-
"\n";
|
|
1089
|
-
DESERIALIZE +=
|
|
1090
|
-
indent +
|
|
1091
|
-
" store<" +
|
|
1092
|
-
first.type +
|
|
1093
|
-
">(changetype<usize>(out), JSON.__deserialize<" +
|
|
1094
|
-
first.type +
|
|
1095
|
-
">(lastIndex, srcStart), offsetof<this>(" +
|
|
1096
|
-
JSON.stringify(first.name) +
|
|
1097
|
-
"));\n";
|
|
1164
|
+
DESERIALIZE += indent + " if (" + (first.generic ? "isArray<" + first.type + ">() && " : "") + getComparison(fName) + ") { // " + fName + "\n";
|
|
1165
|
+
DESERIALIZE += indent + " store<" + first.type + ">(changetype<usize>(out), JSON.__deserialize<" + first.type + ">(lastIndex, srcStart), offsetof<this>(" + JSON.stringify(first.name) + "));\n";
|
|
1098
1166
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
1099
1167
|
DESERIALIZE += indent + " break;\n";
|
|
1100
1168
|
DESERIALIZE += indent + " }";
|
|
1101
1169
|
for (let i = 1; i < group.length; i++) {
|
|
1102
1170
|
const mem = group[i];
|
|
1103
1171
|
const memName = mem.alias || mem.name;
|
|
1104
|
-
DESERIALIZE +=
|
|
1105
|
-
|
|
1106
|
-
" else if (" +
|
|
1107
|
-
(mem.generic ? "isArray" + mem.type + ">() && " : "") +
|
|
1108
|
-
getComparison(memName) +
|
|
1109
|
-
") { // " +
|
|
1110
|
-
memName +
|
|
1111
|
-
"\n";
|
|
1112
|
-
DESERIALIZE +=
|
|
1113
|
-
indent +
|
|
1114
|
-
" store<" +
|
|
1115
|
-
mem.type +
|
|
1116
|
-
">(changetype<usize>(out), JSON.__deserialize<" +
|
|
1117
|
-
mem.type +
|
|
1118
|
-
">(lastIndex, srcStart), offsetof<this>(" +
|
|
1119
|
-
JSON.stringify(mem.name) +
|
|
1120
|
-
"));\n";
|
|
1172
|
+
DESERIALIZE += indent + " else if (" + (mem.generic ? "isArray" + mem.type + ">() && " : "") + getComparison(memName) + ") { // " + memName + "\n";
|
|
1173
|
+
DESERIALIZE += indent + " store<" + mem.type + ">(changetype<usize>(out), JSON.__deserialize<" + mem.type + ">(lastIndex, srcStart), offsetof<this>(" + JSON.stringify(mem.name) + "));\n";
|
|
1121
1174
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
1122
1175
|
DESERIALIZE += indent + " break;\n";
|
|
1123
1176
|
DESERIALIZE += indent + " }";
|
|
1124
1177
|
}
|
|
1125
1178
|
if (STRICT) {
|
|
1126
1179
|
DESERIALIZE += " else {\n";
|
|
1127
|
-
DESERIALIZE +=
|
|
1128
|
-
indent +
|
|
1129
|
-
' throw new Error("Unexpected key value pair in JSON object \'" + JSON.Util.ptrToStr(keyStart, keyEnd) + ":" + JSON.Util.ptrToStr(lastIndex, srcStart) + "\' at position " + (srcEnd - srcStart).toString());\n';
|
|
1180
|
+
DESERIALIZE += indent + ' throw new Error("Unexpected key value pair in JSON object \'" + JSON.Util.ptrToStr(keyStart, keyEnd) + ":" + JSON.Util.ptrToStr(lastIndex, srcStart) + "\' at position " + (srcEnd - srcStart).toString());\n';
|
|
1130
1181
|
DESERIALIZE += indent + " }\n";
|
|
1131
1182
|
}
|
|
1132
1183
|
else {
|
|
@@ -1146,31 +1197,16 @@ export class JSONTransform extends Visitor {
|
|
|
1146
1197
|
}
|
|
1147
1198
|
if (!STRICT || sortedMembers.boolean.length) {
|
|
1148
1199
|
DESERIALIZE += mbElse + "if (code == 116) {\n";
|
|
1149
|
-
DESERIALIZE +=
|
|
1150
|
-
" if (load<u64>(srcStart) == 28429475166421108) {\n";
|
|
1200
|
+
DESERIALIZE += " if (load<u64>(srcStart) == 28429475166421108) {\n";
|
|
1151
1201
|
DESERIALIZE += " srcStart += 8;\n";
|
|
1152
1202
|
if (DEBUG > 1)
|
|
1153
|
-
DESERIALIZE +=
|
|
1154
|
-
' console.log("Value (bool, ' +
|
|
1155
|
-
++id +
|
|
1156
|
-
'): " + JSON.Util.ptrToStr(lastIndex, srcStart - 8));';
|
|
1203
|
+
DESERIALIZE += ' console.log("Value (bool, ' + ++id + '): " + JSON.Util.ptrToStr(lastIndex, srcStart - 8));';
|
|
1157
1204
|
generateGroups(sortedMembers.boolean, (group) => {
|
|
1158
1205
|
generateConsts(group);
|
|
1159
1206
|
const first = group[0];
|
|
1160
1207
|
const fName = first.alias || first.name;
|
|
1161
|
-
DESERIALIZE +=
|
|
1162
|
-
|
|
1163
|
-
" if (" +
|
|
1164
|
-
(first.generic ? "isBoolean<" + first.type + ">() && " : "") +
|
|
1165
|
-
getComparison(fName) +
|
|
1166
|
-
") { // " +
|
|
1167
|
-
fName +
|
|
1168
|
-
"\n";
|
|
1169
|
-
DESERIALIZE +=
|
|
1170
|
-
indent +
|
|
1171
|
-
" store<boolean>(changetype<usize>(out), true, offsetof<this>(" +
|
|
1172
|
-
JSON.stringify(first.name) +
|
|
1173
|
-
"));\n";
|
|
1208
|
+
DESERIALIZE += indent + " if (" + (first.generic ? "isBoolean<" + first.type + ">() && " : "") + getComparison(fName) + ") { // " + fName + "\n";
|
|
1209
|
+
DESERIALIZE += indent + " store<boolean>(changetype<usize>(out), true, offsetof<this>(" + JSON.stringify(first.name) + "));\n";
|
|
1174
1210
|
DESERIALIZE += indent + " srcStart += 2;\n";
|
|
1175
1211
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
1176
1212
|
DESERIALIZE += indent + " break;\n";
|
|
@@ -1178,19 +1214,8 @@ export class JSONTransform extends Visitor {
|
|
|
1178
1214
|
for (let i = 1; i < group.length; i++) {
|
|
1179
1215
|
const mem = group[i];
|
|
1180
1216
|
const memName = mem.alias || mem.name;
|
|
1181
|
-
DESERIALIZE +=
|
|
1182
|
-
|
|
1183
|
-
" else if (" +
|
|
1184
|
-
(mem.generic ? "isBoolean<" + mem.type + ">() && " : "") +
|
|
1185
|
-
getComparison(memName) +
|
|
1186
|
-
") { // " +
|
|
1187
|
-
memName +
|
|
1188
|
-
"\n";
|
|
1189
|
-
DESERIALIZE +=
|
|
1190
|
-
indent +
|
|
1191
|
-
" store<boolean>(changetype<usize>(out), true, offsetof<this>(" +
|
|
1192
|
-
JSON.stringify(mem.name) +
|
|
1193
|
-
"));\n";
|
|
1217
|
+
DESERIALIZE += indent + " else if (" + (mem.generic ? "isBoolean<" + mem.type + ">() && " : "") + getComparison(memName) + ") { // " + memName + "\n";
|
|
1218
|
+
DESERIALIZE += indent + " store<boolean>(changetype<usize>(out), true, offsetof<this>(" + JSON.stringify(mem.name) + "));\n";
|
|
1194
1219
|
DESERIALIZE += indent + " srcStart += 2;\n";
|
|
1195
1220
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
1196
1221
|
DESERIALIZE += indent + " break;\n";
|
|
@@ -1198,9 +1223,7 @@ export class JSONTransform extends Visitor {
|
|
|
1198
1223
|
}
|
|
1199
1224
|
if (STRICT) {
|
|
1200
1225
|
DESERIALIZE += " else {\n";
|
|
1201
|
-
DESERIALIZE +=
|
|
1202
|
-
indent +
|
|
1203
|
-
' throw new Error("Unexpected key value pair in JSON object \'" + JSON.Util.ptrToStr(keyStart, keyEnd) + ":" + JSON.Util.ptrToStr(lastIndex, srcStart) + "\' at position " + (srcEnd - srcStart).toString());\n';
|
|
1226
|
+
DESERIALIZE += indent + ' throw new Error("Unexpected key value pair in JSON object \'" + JSON.Util.ptrToStr(keyStart, keyEnd) + ":" + JSON.Util.ptrToStr(lastIndex, srcStart) + "\' at position " + (srcEnd - srcStart).toString());\n';
|
|
1204
1227
|
DESERIALIZE += indent + " }\n";
|
|
1205
1228
|
}
|
|
1206
1229
|
else {
|
|
@@ -1213,37 +1236,21 @@ export class JSONTransform extends Visitor {
|
|
|
1213
1236
|
}, "boolean");
|
|
1214
1237
|
DESERIALIZE += " }";
|
|
1215
1238
|
DESERIALIZE += " else {\n";
|
|
1216
|
-
DESERIALIZE +=
|
|
1217
|
-
" throw new Error(\"Expected to find 'true' but found '\" + JSON.Util.ptrToStr(lastIndex, srcStart) + \"' instead at position \" + (srcEnd - srcStart).toString());\n";
|
|
1239
|
+
DESERIALIZE += " throw new Error(\"Expected to find 'true' but found '\" + JSON.Util.ptrToStr(lastIndex, srcStart) + \"' instead at position \" + (srcEnd - srcStart).toString());\n";
|
|
1218
1240
|
DESERIALIZE += " }";
|
|
1219
1241
|
DESERIALIZE += "\n }";
|
|
1220
1242
|
mbElse = " else ";
|
|
1221
1243
|
DESERIALIZE += mbElse + "if (code == 102) {\n";
|
|
1222
|
-
DESERIALIZE +=
|
|
1223
|
-
" if (load<u64>(srcStart, 2) == 28429466576093281) {\n";
|
|
1244
|
+
DESERIALIZE += " {\n";
|
|
1224
1245
|
DESERIALIZE += " srcStart += 10;\n";
|
|
1225
1246
|
if (DEBUG > 1)
|
|
1226
|
-
DESERIALIZE +=
|
|
1227
|
-
' console.log("Value (bool, ' +
|
|
1228
|
-
++id +
|
|
1229
|
-
'): " + JSON.Util.ptrToStr(lastIndex, srcStart - 10));';
|
|
1247
|
+
DESERIALIZE += ' console.log("Value (bool, ' + ++id + '): " + JSON.Util.ptrToStr(lastIndex, srcStart - 10));';
|
|
1230
1248
|
generateGroups(sortedMembers.boolean, (group) => {
|
|
1231
1249
|
generateConsts(group);
|
|
1232
1250
|
const first = group[0];
|
|
1233
1251
|
const fName = first.alias || first.name;
|
|
1234
|
-
DESERIALIZE +=
|
|
1235
|
-
|
|
1236
|
-
" if (" +
|
|
1237
|
-
(first.generic ? "isBoolean<" + first.type + ">() && " : "") +
|
|
1238
|
-
getComparison(fName) +
|
|
1239
|
-
") { // " +
|
|
1240
|
-
fName +
|
|
1241
|
-
"\n";
|
|
1242
|
-
DESERIALIZE +=
|
|
1243
|
-
indent +
|
|
1244
|
-
" store<boolean>(changetype<usize>(out), false, offsetof<this>(" +
|
|
1245
|
-
JSON.stringify(first.name) +
|
|
1246
|
-
"));\n";
|
|
1252
|
+
DESERIALIZE += indent + " if (" + (first.generic ? "isBoolean<" + first.type + ">() && " : "") + getComparison(fName) + ") { // " + fName + "\n";
|
|
1253
|
+
DESERIALIZE += indent + " store<boolean>(changetype<usize>(out), false, offsetof<this>(" + JSON.stringify(first.name) + "));\n";
|
|
1247
1254
|
DESERIALIZE += indent + " srcStart += 2;\n";
|
|
1248
1255
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
1249
1256
|
DESERIALIZE += indent + " break;\n";
|
|
@@ -1251,19 +1258,8 @@ export class JSONTransform extends Visitor {
|
|
|
1251
1258
|
for (let i = 1; i < group.length; i++) {
|
|
1252
1259
|
const mem = group[i];
|
|
1253
1260
|
const memName = mem.alias || mem.name;
|
|
1254
|
-
DESERIALIZE +=
|
|
1255
|
-
|
|
1256
|
-
" else if (" +
|
|
1257
|
-
(mem.generic ? "isBoolean<" + mem.type + ">() && " : "") +
|
|
1258
|
-
getComparison(memName) +
|
|
1259
|
-
") { // " +
|
|
1260
|
-
memName +
|
|
1261
|
-
"\n";
|
|
1262
|
-
DESERIALIZE +=
|
|
1263
|
-
indent +
|
|
1264
|
-
" store<boolean>(changetype<usize>(out), false, offsetof<this>(" +
|
|
1265
|
-
JSON.stringify(mem.name) +
|
|
1266
|
-
"));\n";
|
|
1261
|
+
DESERIALIZE += indent + " else if (" + (mem.generic ? "isBoolean<" + mem.type + ">() && " : "") + getComparison(memName) + ") { // " + memName + "\n";
|
|
1262
|
+
DESERIALIZE += indent + " store<boolean>(changetype<usize>(out), false, offsetof<this>(" + JSON.stringify(mem.name) + "));\n";
|
|
1267
1263
|
DESERIALIZE += indent + " srcStart += 2;\n";
|
|
1268
1264
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
1269
1265
|
DESERIALIZE += indent + " break;\n";
|
|
@@ -1271,9 +1267,7 @@ export class JSONTransform extends Visitor {
|
|
|
1271
1267
|
}
|
|
1272
1268
|
if (STRICT) {
|
|
1273
1269
|
DESERIALIZE += " else {\n";
|
|
1274
|
-
DESERIALIZE +=
|
|
1275
|
-
indent +
|
|
1276
|
-
' throw new Error("Unexpected key value pair in JSON object \'" + JSON.Util.ptrToStr(keyStart, keyEnd) + ":" + JSON.Util.ptrToStr(lastIndex, srcStart) + "\' at position " + (srcEnd - srcStart).toString());\n';
|
|
1270
|
+
DESERIALIZE += indent + ' throw new Error("Unexpected key value pair in JSON object \'" + JSON.Util.ptrToStr(keyStart, keyEnd) + ":" + JSON.Util.ptrToStr(lastIndex, srcStart) + "\' at position " + (srcEnd - srcStart).toString());\n';
|
|
1277
1271
|
DESERIALIZE += indent + " }\n";
|
|
1278
1272
|
}
|
|
1279
1273
|
else {
|
|
@@ -1285,40 +1279,21 @@ export class JSONTransform extends Visitor {
|
|
|
1285
1279
|
}
|
|
1286
1280
|
}, "boolean");
|
|
1287
1281
|
DESERIALIZE += " }";
|
|
1288
|
-
DESERIALIZE += " else {\n";
|
|
1289
|
-
DESERIALIZE +=
|
|
1290
|
-
" throw new Error(\"Expected to find 'false' but found '\" + JSON.Util.ptrToStr(lastIndex, srcStart) + \"' instead at position \" + (srcEnd - srcStart).toString());\n";
|
|
1291
|
-
DESERIALIZE += " }";
|
|
1292
1282
|
DESERIALIZE += "\n }";
|
|
1293
1283
|
mbElse = " else ";
|
|
1294
1284
|
}
|
|
1295
1285
|
if (!STRICT || sortedMembers.null.length) {
|
|
1296
1286
|
DESERIALIZE += mbElse + "if (code == 110) {\n";
|
|
1297
|
-
DESERIALIZE +=
|
|
1298
|
-
" if (load<u64>(srcStart) == 30399761348886638) {\n";
|
|
1287
|
+
DESERIALIZE += " if (load<u64>(srcStart) == 30399761348886638) {\n";
|
|
1299
1288
|
DESERIALIZE += " srcStart += 8;\n";
|
|
1300
1289
|
if (DEBUG > 1)
|
|
1301
|
-
DESERIALIZE +=
|
|
1302
|
-
' console.log("Value (null, ' +
|
|
1303
|
-
++id +
|
|
1304
|
-
'): " + JSON.Util.ptrToStr(lastIndex, srcStart - 8));';
|
|
1290
|
+
DESERIALIZE += ' console.log("Value (null, ' + ++id + '): " + JSON.Util.ptrToStr(lastIndex, srcStart - 8));';
|
|
1305
1291
|
generateGroups(sortedMembers.null, (group) => {
|
|
1306
1292
|
generateConsts(group);
|
|
1307
1293
|
const first = group[0];
|
|
1308
1294
|
const fName = first.alias || first.name;
|
|
1309
|
-
DESERIALIZE +=
|
|
1310
|
-
|
|
1311
|
-
" if (" +
|
|
1312
|
-
(first.generic ? "isNullable<" + first.type + ">() && " : "") +
|
|
1313
|
-
getComparison(fName) +
|
|
1314
|
-
") { // " +
|
|
1315
|
-
fName +
|
|
1316
|
-
"\n";
|
|
1317
|
-
DESERIALIZE +=
|
|
1318
|
-
indent +
|
|
1319
|
-
" store<usize>(changetype<usize>(out), 0, offsetof<this>(" +
|
|
1320
|
-
JSON.stringify(first.name) +
|
|
1321
|
-
"));\n";
|
|
1295
|
+
DESERIALIZE += indent + " if (" + (first.generic ? "isNullable<" + first.type + ">() && " : "") + getComparison(fName) + ") { // " + fName + "\n";
|
|
1296
|
+
DESERIALIZE += indent + " store<usize>(changetype<usize>(out), 0, offsetof<this>(" + JSON.stringify(first.name) + "));\n";
|
|
1322
1297
|
DESERIALIZE += indent + " srcStart += 2;\n";
|
|
1323
1298
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
1324
1299
|
DESERIALIZE += indent + " break;\n";
|
|
@@ -1326,19 +1301,8 @@ export class JSONTransform extends Visitor {
|
|
|
1326
1301
|
for (let i = 1; i < group.length; i++) {
|
|
1327
1302
|
const mem = group[i];
|
|
1328
1303
|
const memName = mem.alias || mem.name;
|
|
1329
|
-
DESERIALIZE +=
|
|
1330
|
-
|
|
1331
|
-
" else if (" +
|
|
1332
|
-
(mem.generic ? "isNullable<" + mem.type + ">() && " : "") +
|
|
1333
|
-
getComparison(memName) +
|
|
1334
|
-
") { // " +
|
|
1335
|
-
memName +
|
|
1336
|
-
"\n";
|
|
1337
|
-
DESERIALIZE +=
|
|
1338
|
-
indent +
|
|
1339
|
-
" store<usize>(changetype<usize>(out), 0, offsetof<this>(" +
|
|
1340
|
-
JSON.stringify(mem.name) +
|
|
1341
|
-
"));\n";
|
|
1304
|
+
DESERIALIZE += indent + " else if (" + (mem.generic ? "isNullable<" + mem.type + ">() && " : "") + getComparison(memName) + ") { // " + memName + "\n";
|
|
1305
|
+
DESERIALIZE += indent + " store<usize>(changetype<usize>(out), 0, offsetof<this>(" + JSON.stringify(mem.name) + "));\n";
|
|
1342
1306
|
DESERIALIZE += indent + " srcStart += 2;\n";
|
|
1343
1307
|
DESERIALIZE += indent + " keyStart = 0;\n";
|
|
1344
1308
|
DESERIALIZE += indent + " break;\n";
|
|
@@ -1346,9 +1310,7 @@ export class JSONTransform extends Visitor {
|
|
|
1346
1310
|
}
|
|
1347
1311
|
if (STRICT) {
|
|
1348
1312
|
DESERIALIZE += " else {\n";
|
|
1349
|
-
DESERIALIZE +=
|
|
1350
|
-
indent +
|
|
1351
|
-
' throw new Error("Unexpected key value pair in JSON object \'" + JSON.Util.ptrToStr(keyStart, keyEnd) + ":" + JSON.Util.ptrToStr(lastIndex, srcStart) + "\' at position " + (srcEnd - srcStart).toString());\n';
|
|
1313
|
+
DESERIALIZE += indent + ' throw new Error("Unexpected key value pair in JSON object \'" + JSON.Util.ptrToStr(keyStart, keyEnd) + ":" + JSON.Util.ptrToStr(lastIndex, srcStart) + "\' at position " + (srcEnd - srcStart).toString());\n';
|
|
1352
1314
|
DESERIALIZE += indent + " }\n";
|
|
1353
1315
|
}
|
|
1354
1316
|
else {
|
|
@@ -1371,58 +1333,62 @@ export class JSONTransform extends Visitor {
|
|
|
1371
1333
|
indentDec();
|
|
1372
1334
|
DESERIALIZE += ` }\n`;
|
|
1373
1335
|
indentDec();
|
|
1374
|
-
DESERIALIZE += ` return
|
|
1336
|
+
DESERIALIZE += ` return srcStart;\n}\n`;
|
|
1375
1337
|
indent = " ";
|
|
1376
1338
|
this.schema.byteSize += 2;
|
|
1377
1339
|
SERIALIZE += indent + "store<u16>(bs.offset, 125, 0); // }\n";
|
|
1378
1340
|
SERIALIZE += indent + "bs.offset += 2;\n";
|
|
1379
1341
|
SERIALIZE += "}";
|
|
1380
|
-
SERIALIZE =
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
");\n" +
|
|
1386
|
-
SERIALIZE.slice(32);
|
|
1387
|
-
INITIALIZE += " return this;\n";
|
|
1388
|
-
INITIALIZE += "}";
|
|
1342
|
+
SERIALIZE = SERIALIZE.slice(0, 32) + indent + "bs.proposeSize(" + this.schema.byteSize + ");\n" + SERIALIZE.slice(32);
|
|
1343
|
+
if (!useFastPath) {
|
|
1344
|
+
INITIALIZE += " return this;\n";
|
|
1345
|
+
INITIALIZE += "}";
|
|
1346
|
+
}
|
|
1389
1347
|
if (DEBUG > 0) {
|
|
1390
1348
|
console.log(SERIALIZE_CUSTOM || SERIALIZE);
|
|
1391
|
-
|
|
1349
|
+
if (!useFastPath)
|
|
1350
|
+
console.log(INITIALIZE);
|
|
1392
1351
|
console.log(DESERIALIZE_CUSTOM || DESERIALIZE);
|
|
1393
1352
|
}
|
|
1353
|
+
const DESERIALIZE_DIRECT = useFastPath ? DESERIALIZE_FAST.replace("@inline __DESERIALIZE_FAST<__JSON_T>(srcStart: usize, srcEnd: usize, out: __JSON_T): usize {", "@inline __DESERIALIZE<__JSON_T>(srcStart: usize, srcEnd: usize, out: __JSON_T): usize {") : DESERIALIZE.replace("__DESERIALIZE_SLOW<__JSON_T>", "__DESERIALIZE<__JSON_T>");
|
|
1394
1354
|
const SERIALIZE_METHOD = SimpleParser.parseClassMember(SERIALIZE_CUSTOM || SERIALIZE, node);
|
|
1395
|
-
const INITIALIZE_METHOD = SimpleParser.parseClassMember(INITIALIZE, node);
|
|
1396
|
-
const
|
|
1355
|
+
const INITIALIZE_METHOD = !useFastPath ? SimpleParser.parseClassMember(INITIALIZE, node) : null;
|
|
1356
|
+
const DESERIALIZE_CUSTOM_METHOD = DESERIALIZE_CUSTOM ? SimpleParser.parseClassMember(DESERIALIZE_CUSTOM, node) : null;
|
|
1357
|
+
const DESERIALIZE_METHOD = DESERIALIZE_CUSTOM ? null : SimpleParser.parseClassMember(DESERIALIZE_DIRECT, node);
|
|
1358
|
+
const DESERIALIZE_FAST_METHOD = useFastPath ? SimpleParser.parseClassMember(DESERIALIZE_FAST, node) : null;
|
|
1397
1359
|
if (!node.members.find((v) => v.name.text == "__SERIALIZE"))
|
|
1398
1360
|
node.members.push(SERIALIZE_METHOD);
|
|
1399
|
-
if (!node.members.find((v) => v.name.text == "__INITIALIZE"))
|
|
1361
|
+
if (!useFastPath && INITIALIZE_METHOD && !node.members.find((v) => v.name.text == "__INITIALIZE"))
|
|
1400
1362
|
node.members.push(INITIALIZE_METHOD);
|
|
1401
|
-
if (!node.members.find((v) => v.name.text == "
|
|
1363
|
+
if (DESERIALIZE_CUSTOM_METHOD && !node.members.find((v) => v.name.text == "__DESERIALIZE_CUSTOM"))
|
|
1364
|
+
node.members.push(DESERIALIZE_CUSTOM_METHOD);
|
|
1365
|
+
if (DESERIALIZE_METHOD && !node.members.find((v) => v.name.text == "__DESERIALIZE"))
|
|
1402
1366
|
node.members.push(DESERIALIZE_METHOD);
|
|
1367
|
+
if (!DESERIALIZE_CUSTOM && useFastPath && DESERIALIZE_FAST_METHOD && !node.members.find((v) => v.name.text == "__DESERIALIZE_FAST"))
|
|
1368
|
+
node.members.push(DESERIALIZE_FAST_METHOD);
|
|
1403
1369
|
super.visitClassDeclaration(node);
|
|
1404
1370
|
}
|
|
1405
1371
|
getSchema(name) {
|
|
1406
1372
|
name = stripNull(name);
|
|
1407
|
-
return (this.
|
|
1408
|
-
.get(this.schema.node.range.source.internalPath)
|
|
1409
|
-
.find((s) => s.name == name) || null);
|
|
1373
|
+
return this.schemas.get(this.schema.node.range.source.internalPath).find((s) => s.name == name) || null;
|
|
1410
1374
|
}
|
|
1411
1375
|
generateEmptyMethods(node) {
|
|
1412
1376
|
const SERIALIZE_EMPTY = "@inline __SERIALIZE(ptr: usize): void {\n bs.proposeSize(4);\n store<u32>(bs.offset, 8192123);\n bs.offset += 4;\n}";
|
|
1413
1377
|
const INITIALIZE_EMPTY = "@inline __INITIALIZE(): this {\n return this;\n}";
|
|
1414
|
-
const DESERIALIZE_EMPTY = "@inline __DESERIALIZE<__JSON_T>(srcStart: usize, srcEnd: usize, out: __JSON_T):
|
|
1378
|
+
const DESERIALIZE_EMPTY = "@inline __DESERIALIZE<__JSON_T>(srcStart: usize, srcEnd: usize, out: __JSON_T): usize {\n return srcEnd;\n}";
|
|
1379
|
+
const useFastPath = USE_FAST_PATH && getCodegenMode(this.program) !== JSONMode.NAIVE;
|
|
1415
1380
|
if (DEBUG > 0) {
|
|
1416
1381
|
console.log(SERIALIZE_EMPTY);
|
|
1417
|
-
|
|
1382
|
+
if (!useFastPath)
|
|
1383
|
+
console.log(INITIALIZE_EMPTY);
|
|
1418
1384
|
console.log(DESERIALIZE_EMPTY);
|
|
1419
1385
|
}
|
|
1420
1386
|
const SERIALIZE_METHOD_EMPTY = SimpleParser.parseClassMember(SERIALIZE_EMPTY, node);
|
|
1421
|
-
const INITIALIZE_METHOD_EMPTY = SimpleParser.parseClassMember(INITIALIZE_EMPTY, node);
|
|
1387
|
+
const INITIALIZE_METHOD_EMPTY = !useFastPath ? SimpleParser.parseClassMember(INITIALIZE_EMPTY, node) : null;
|
|
1422
1388
|
const DESERIALIZE_METHOD_EMPTY = SimpleParser.parseClassMember(DESERIALIZE_EMPTY, node);
|
|
1423
1389
|
if (!node.members.find((v) => v.name.text == "__SERIALIZE"))
|
|
1424
1390
|
node.members.push(SERIALIZE_METHOD_EMPTY);
|
|
1425
|
-
if (!node.members.find((v) => v.name.text == "__INITIALIZE"))
|
|
1391
|
+
if (!useFastPath && INITIALIZE_METHOD_EMPTY && !node.members.find((v) => v.name.text == "__INITIALIZE"))
|
|
1426
1392
|
node.members.push(INITIALIZE_METHOD_EMPTY);
|
|
1427
1393
|
if (!node.members.find((v) => v.name.text == "__DESERIALIZE"))
|
|
1428
1394
|
node.members.push(DESERIALIZE_METHOD_EMPTY);
|
|
@@ -1439,56 +1405,84 @@ export class JSONTransform extends Visitor {
|
|
|
1439
1405
|
this.baseCWD = this.baseCWD.replaceAll("/", path.sep);
|
|
1440
1406
|
const baseDir = path.resolve(fileURLToPath(import.meta.url), "..", "..", "..");
|
|
1441
1407
|
let fromPath = node.range.source.normalizedPath.replaceAll("/", path.sep);
|
|
1442
|
-
|
|
1443
|
-
if (!isLib &&
|
|
1444
|
-
!this.parser.sources.some((s) => s.normalizedPath.startsWith("assembly/index"))) {
|
|
1445
|
-
const newPath = path.join(baseDir, "assembly", "index.ts");
|
|
1446
|
-
this.parser.parseFile(readFileSync(newPath).toString(), newPath, false);
|
|
1447
|
-
}
|
|
1448
|
-
else if (isLib &&
|
|
1449
|
-
!this.parser.sources.some((s) => s.normalizedPath.startsWith("~lib/json-as/assembly/index"))) {
|
|
1450
|
-
const newPath = "~lib/json-as/assembly/index.ts";
|
|
1451
|
-
this.parser.parseFile(readFileSync(path.join(baseDir, "assembly", "index.ts")).toString(), newPath, false);
|
|
1452
|
-
}
|
|
1453
|
-
fromPath = fromPath.startsWith("~lib")
|
|
1454
|
-
? fromPath.slice(5)
|
|
1455
|
-
: path.join(this.baseCWD, fromPath);
|
|
1408
|
+
fromPath = fromPath.startsWith("~lib") ? fromPath.slice(5) : path.join(this.baseCWD, fromPath);
|
|
1456
1409
|
const bsImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "bs" || d.name.text == "bs"));
|
|
1457
1410
|
const jsonImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "JSON" || d.name.text == "JSON"));
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1411
|
+
const atoiImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "atoi" || d.name.text == "atoi"));
|
|
1412
|
+
const deserializeIntegerFieldImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "deserializeIntegerField" || d.name.text == "deserializeIntegerField"));
|
|
1413
|
+
const deserializeUnsignedFieldImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "deserializeUnsignedField" || d.name.text == "deserializeUnsignedField"));
|
|
1414
|
+
const deserializeFloatFieldImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "deserializeFloatField" || d.name.text == "deserializeFloatField"));
|
|
1415
|
+
const deserializeArrayField_SWARImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "deserializeArrayField_SWAR" || d.name.text == "deserializeArrayField_SWAR"));
|
|
1416
|
+
const deserializeStringFieldSWARImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "deserializeStringField_SWAR" || d.name.text == "deserializeStringField_SWAR"));
|
|
1417
|
+
const deserializeStringFieldSIMDImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "deserializeStringField_SIMD" || d.name.text == "deserializeStringField_SIMD"));
|
|
1418
|
+
const sourceText = readFileSync(fromPath).toString();
|
|
1419
|
+
const hasLocalDeserializeIntegerField = /\bdeserializeIntegerField\b/.test(sourceText);
|
|
1420
|
+
const hasLocalDeserializeUnsignedField = /\bdeserializeUnsignedField\b/.test(sourceText);
|
|
1421
|
+
const hasLocalDeserializeFloatField = /\bdeserializeFloatField\b/.test(sourceText);
|
|
1422
|
+
const hasLocaldeserializeArrayField_SWAR = /\bdeserializeArrayField_SWAR\b/.test(sourceText);
|
|
1423
|
+
const hasLocalDeserializeStringFieldSWAR = /\bdeserializeStringField_SWAR\b/.test(sourceText);
|
|
1424
|
+
const hasLocalDeserializeStringFieldSIMD = /\bdeserializeStringField_SIMD\b/.test(sourceText);
|
|
1425
|
+
let baseRel = path.posix.join(...path.relative(path.dirname(fromPath), path.join(baseDir)).split(path.sep));
|
|
1461
1426
|
if (baseRel.endsWith("json-as")) {
|
|
1462
1427
|
baseRel = "json-as" + baseRel.slice(baseRel.indexOf("json-as") + 7);
|
|
1463
1428
|
}
|
|
1464
|
-
else if (!baseRel.startsWith(".") &&
|
|
1465
|
-
!baseRel.startsWith("/") &&
|
|
1466
|
-
!baseRel.startsWith("json-as")) {
|
|
1429
|
+
else if (!baseRel.startsWith(".") && !baseRel.startsWith("/") && !baseRel.startsWith("json-as")) {
|
|
1467
1430
|
baseRel = "./" + baseRel;
|
|
1468
1431
|
}
|
|
1469
1432
|
if (!bsImport) {
|
|
1470
|
-
const replaceNode = Node.createImportStatement([
|
|
1471
|
-
Node.createImportDeclaration(Node.createIdentifierExpression("bs", node.range, false), null, node.range),
|
|
1472
|
-
], Node.createStringLiteralExpression(path.posix.join(baseRel, "lib", "as-bs"), node.range), node.range);
|
|
1433
|
+
const replaceNode = Node.createImportStatement([Node.createImportDeclaration(Node.createIdentifierExpression("bs", node.range, false), null, node.range)], Node.createStringLiteralExpression(path.posix.join(baseRel, "lib", "as-bs"), node.range), node.range);
|
|
1473
1434
|
node.range.source.statements.unshift(replaceNode);
|
|
1474
1435
|
if (DEBUG > 0)
|
|
1475
|
-
console.log("Added import: " +
|
|
1476
|
-
toString(replaceNode) +
|
|
1477
|
-
" to " +
|
|
1478
|
-
node.range.source.normalizedPath +
|
|
1479
|
-
"\n");
|
|
1436
|
+
console.log("Added import: " + toString(replaceNode) + " to " + node.range.source.normalizedPath + "\n");
|
|
1480
1437
|
}
|
|
1481
1438
|
if (!jsonImport) {
|
|
1482
|
-
const replaceNode = Node.createImportStatement([
|
|
1483
|
-
|
|
1484
|
-
|
|
1439
|
+
const replaceNode = Node.createImportStatement([Node.createImportDeclaration(Node.createIdentifierExpression("JSON", node.range, false), null, node.range)], Node.createStringLiteralExpression(path.posix.join(baseRel, "assembly", "index"), node.range), node.range);
|
|
1440
|
+
node.range.source.statements.unshift(replaceNode);
|
|
1441
|
+
if (DEBUG > 0)
|
|
1442
|
+
console.log("Added import: " + toString(replaceNode) + " to " + node.range.source.normalizedPath + "\n");
|
|
1443
|
+
}
|
|
1444
|
+
if (!atoiImport) {
|
|
1445
|
+
const replaceNode = Node.createImportStatement([Node.createImportDeclaration(Node.createIdentifierExpression("atoi", node.range, false), null, node.range)], Node.createStringLiteralExpression(path.posix.join(baseRel, "assembly", "util", "atoi"), node.range), node.range);
|
|
1446
|
+
node.range.source.statements.unshift(replaceNode);
|
|
1447
|
+
if (DEBUG > 0)
|
|
1448
|
+
console.log("Added import: " + toString(replaceNode) + " to " + node.range.source.normalizedPath + "\n");
|
|
1449
|
+
}
|
|
1450
|
+
if (!deserializeIntegerFieldImport && !hasLocalDeserializeIntegerField) {
|
|
1451
|
+
const replaceNode = Node.createImportStatement([Node.createImportDeclaration(Node.createIdentifierExpression("deserializeIntegerField", node.range, false), null, node.range)], Node.createStringLiteralExpression(path.posix.join(baseRel, "assembly", "deserialize", "integer"), node.range), node.range);
|
|
1452
|
+
node.range.source.statements.unshift(replaceNode);
|
|
1453
|
+
if (DEBUG > 0)
|
|
1454
|
+
console.log("Added import: " + toString(replaceNode) + " to " + node.range.source.normalizedPath + "\n");
|
|
1455
|
+
}
|
|
1456
|
+
if (!deserializeUnsignedFieldImport && !hasLocalDeserializeUnsignedField) {
|
|
1457
|
+
const replaceNode = Node.createImportStatement([Node.createImportDeclaration(Node.createIdentifierExpression("deserializeUnsignedField", node.range, false), null, node.range)], Node.createStringLiteralExpression(path.posix.join(baseRel, "assembly", "deserialize", "unsigned"), node.range), node.range);
|
|
1458
|
+
node.range.source.statements.unshift(replaceNode);
|
|
1459
|
+
if (DEBUG > 0)
|
|
1460
|
+
console.log("Added import: " + toString(replaceNode) + " to " + node.range.source.normalizedPath + "\n");
|
|
1461
|
+
}
|
|
1462
|
+
if (!deserializeFloatFieldImport && !hasLocalDeserializeFloatField) {
|
|
1463
|
+
const replaceNode = Node.createImportStatement([Node.createImportDeclaration(Node.createIdentifierExpression("deserializeFloatField", node.range, false), null, node.range)], Node.createStringLiteralExpression(path.posix.join(baseRel, "assembly", "deserialize", "float"), node.range), node.range);
|
|
1464
|
+
node.range.source.statements.unshift(replaceNode);
|
|
1465
|
+
if (DEBUG > 0)
|
|
1466
|
+
console.log("Added import: " + toString(replaceNode) + " to " + node.range.source.normalizedPath + "\n");
|
|
1467
|
+
}
|
|
1468
|
+
if (!deserializeArrayField_SWARImport && !hasLocaldeserializeArrayField_SWAR) {
|
|
1469
|
+
const replaceNode = Node.createImportStatement([Node.createImportDeclaration(Node.createIdentifierExpression("deserializeArrayField_SWAR", node.range, false), null, node.range)], Node.createStringLiteralExpression(path.posix.join(baseRel, "assembly", "deserialize", "simple", "array"), node.range), node.range);
|
|
1470
|
+
node.range.source.statements.unshift(replaceNode);
|
|
1471
|
+
if (DEBUG > 0)
|
|
1472
|
+
console.log("Added import: " + toString(replaceNode) + " to " + node.range.source.normalizedPath + "\n");
|
|
1473
|
+
}
|
|
1474
|
+
const codegenMode = getCodegenMode(this.program);
|
|
1475
|
+
if (codegenMode !== JSONMode.SIMD && !deserializeStringFieldSWARImport && !hasLocalDeserializeStringFieldSWAR) {
|
|
1476
|
+
const replaceNode = Node.createImportStatement([Node.createImportDeclaration(Node.createIdentifierExpression("deserializeStringField_SWAR", node.range, false), null, node.range)], Node.createStringLiteralExpression(path.posix.join(baseRel, "assembly", "deserialize", "swar", "string"), node.range), node.range);
|
|
1485
1477
|
node.range.source.statements.unshift(replaceNode);
|
|
1486
1478
|
if (DEBUG > 0)
|
|
1487
|
-
console.log("Added import: " +
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1479
|
+
console.log("Added import: " + toString(replaceNode) + " to " + node.range.source.normalizedPath + "\n");
|
|
1480
|
+
}
|
|
1481
|
+
if (codegenMode === JSONMode.SIMD && !deserializeStringFieldSIMDImport && !hasLocalDeserializeStringFieldSIMD) {
|
|
1482
|
+
const replaceNode = Node.createImportStatement([Node.createImportDeclaration(Node.createIdentifierExpression("deserializeStringField_SIMD", node.range, false), null, node.range)], Node.createStringLiteralExpression(path.posix.join(baseRel, "assembly", "deserialize", "simd", "string"), node.range), node.range);
|
|
1483
|
+
node.range.source.statements.unshift(replaceNode);
|
|
1484
|
+
if (DEBUG > 0)
|
|
1485
|
+
console.log("Added import: " + toString(replaceNode) + " to " + node.range.source.normalizedPath + "\n");
|
|
1492
1486
|
}
|
|
1493
1487
|
}
|
|
1494
1488
|
getStores(data, simd = false) {
|
|
@@ -1499,41 +1493,21 @@ export class JSONTransform extends Visitor {
|
|
|
1499
1493
|
if (size == "v128" && simd) {
|
|
1500
1494
|
const index = this.simdStatements.findIndex((v) => v.includes(num));
|
|
1501
1495
|
const name = "SIMD_" + (index == -1 ? this.simdStatements.length : index);
|
|
1502
|
-
if (index
|
|
1496
|
+
if (index == -1)
|
|
1503
1497
|
this.simdStatements.push(`const ${name} = ${num};`);
|
|
1504
|
-
out.push("store<v128>(bs.offset, " +
|
|
1505
|
-
name +
|
|
1506
|
-
", " +
|
|
1507
|
-
offset +
|
|
1508
|
-
"); // " +
|
|
1509
|
-
data.slice(offset >> 1, (offset >> 1) + 8));
|
|
1498
|
+
out.push("store<v128>(bs.offset, " + name + ", " + offset + "); // " + data.slice(offset >> 1, (offset >> 1) + 8));
|
|
1510
1499
|
offset += 16;
|
|
1511
1500
|
}
|
|
1512
1501
|
if (size == "u64") {
|
|
1513
|
-
out.push("store<u64>(bs.offset, " +
|
|
1514
|
-
num +
|
|
1515
|
-
", " +
|
|
1516
|
-
offset +
|
|
1517
|
-
"); // " +
|
|
1518
|
-
data.slice(offset >> 1, (offset >> 1) + 4));
|
|
1502
|
+
out.push("store<u64>(bs.offset, " + num + ", " + offset + "); // " + data.slice(offset >> 1, (offset >> 1) + 4));
|
|
1519
1503
|
offset += 8;
|
|
1520
1504
|
}
|
|
1521
1505
|
else if (size == "u32") {
|
|
1522
|
-
out.push("store<u32>(bs.offset, " +
|
|
1523
|
-
num +
|
|
1524
|
-
", " +
|
|
1525
|
-
offset +
|
|
1526
|
-
"); // " +
|
|
1527
|
-
data.slice(offset >> 1, (offset >> 1) + 2));
|
|
1506
|
+
out.push("store<u32>(bs.offset, " + num + ", " + offset + "); // " + data.slice(offset >> 1, (offset >> 1) + 2));
|
|
1528
1507
|
offset += 4;
|
|
1529
1508
|
}
|
|
1530
1509
|
else if (size == "u16") {
|
|
1531
|
-
out.push("store<u16>(bs.offset, " +
|
|
1532
|
-
num +
|
|
1533
|
-
", " +
|
|
1534
|
-
offset +
|
|
1535
|
-
"); // " +
|
|
1536
|
-
data.slice(offset >> 1, (offset >> 1) + 1));
|
|
1510
|
+
out.push("store<u16>(bs.offset, " + num + ", " + offset + "); // " + data.slice(offset >> 1, (offset >> 1) + 1));
|
|
1537
1511
|
offset += 2;
|
|
1538
1512
|
}
|
|
1539
1513
|
}
|
|
@@ -1541,31 +1515,7 @@ export class JSONTransform extends Visitor {
|
|
|
1541
1515
|
return out;
|
|
1542
1516
|
}
|
|
1543
1517
|
isValidType(type, node) {
|
|
1544
|
-
const validTypes = [
|
|
1545
|
-
"string",
|
|
1546
|
-
"u8",
|
|
1547
|
-
"i8",
|
|
1548
|
-
"u16",
|
|
1549
|
-
"i16",
|
|
1550
|
-
"u32",
|
|
1551
|
-
"i32",
|
|
1552
|
-
"u64",
|
|
1553
|
-
"i64",
|
|
1554
|
-
"f32",
|
|
1555
|
-
"f64",
|
|
1556
|
-
"bool",
|
|
1557
|
-
"boolean",
|
|
1558
|
-
"Date",
|
|
1559
|
-
"JSON.Value",
|
|
1560
|
-
"JSON.Obj",
|
|
1561
|
-
"JSON.Raw",
|
|
1562
|
-
"Value",
|
|
1563
|
-
"Obj",
|
|
1564
|
-
"Raw",
|
|
1565
|
-
...this.schemas
|
|
1566
|
-
.get(this.schema.node.range.source.internalPath)
|
|
1567
|
-
.map((v) => v.name),
|
|
1568
|
-
];
|
|
1518
|
+
const validTypes = ["string", "u8", "i8", "u16", "i16", "u32", "i32", "u64", "i64", "f32", "f64", "bool", "boolean", "Date", "JSON.Value", "JSON.Obj", "JSON.Raw", "Value", "Obj", "Raw", ...this.schemas.get(this.schema.node.range.source.internalPath).map((v) => v.name)];
|
|
1569
1519
|
const baseTypes = ["Array", "StaticArray", "Map", "Set", "JSON.Box", "Box"];
|
|
1570
1520
|
if (node && node.isGeneric && node.typeParameters)
|
|
1571
1521
|
validTypes.push(...node.typeParameters.map((v) => v.name.text));
|
|
@@ -1575,8 +1525,7 @@ export class JSONTransform extends Visitor {
|
|
|
1575
1525
|
return this.isValidType(type.slice(0, type.length - 7), node);
|
|
1576
1526
|
}
|
|
1577
1527
|
if (type.includes("<"))
|
|
1578
|
-
return
|
|
1579
|
-
this.isValidType(type.slice(type.indexOf("<") + 1, type.lastIndexOf(">")), node));
|
|
1528
|
+
return baseTypes.includes(type.slice(0, type.indexOf("<"))) && this.isValidType(type.slice(type.indexOf("<") + 1, type.lastIndexOf(">")), node);
|
|
1580
1529
|
if (validTypes.includes(type))
|
|
1581
1530
|
return true;
|
|
1582
1531
|
return false;
|
|
@@ -1589,6 +1538,23 @@ var JSONMode;
|
|
|
1589
1538
|
JSONMode[JSONMode["NAIVE"] = 2] = "NAIVE";
|
|
1590
1539
|
})(JSONMode || (JSONMode = {}));
|
|
1591
1540
|
let MODE = JSONMode.SWAR;
|
|
1541
|
+
function getCodegenMode(program) {
|
|
1542
|
+
let mode = program.options.hasFeature(16) ? JSONMode.SIMD : JSONMode.SWAR;
|
|
1543
|
+
if (process.env["JSON_MODE"]) {
|
|
1544
|
+
switch (process.env["JSON_MODE"].toLowerCase().trim()) {
|
|
1545
|
+
case "simd":
|
|
1546
|
+
mode = JSONMode.SIMD;
|
|
1547
|
+
break;
|
|
1548
|
+
case "swar":
|
|
1549
|
+
mode = JSONMode.SWAR;
|
|
1550
|
+
break;
|
|
1551
|
+
case "naive":
|
|
1552
|
+
mode = JSONMode.NAIVE;
|
|
1553
|
+
break;
|
|
1554
|
+
}
|
|
1555
|
+
}
|
|
1556
|
+
return mode;
|
|
1557
|
+
}
|
|
1592
1558
|
export default class Transformer extends Transform {
|
|
1593
1559
|
afterInitialize(program) {
|
|
1594
1560
|
if (program.options.hasFeature(16))
|
|
@@ -1610,24 +1576,16 @@ export default class Transformer extends Transform {
|
|
|
1610
1576
|
}
|
|
1611
1577
|
}
|
|
1612
1578
|
program.registerConstantInteger("JSON_MODE", Type.i32, i64_new(MODE));
|
|
1613
|
-
if (process.env["JSON_CACHE"]?.trim().toLowerCase() === "true" ||
|
|
1614
|
-
process.env["JSON_CACHE"]?.trim().toLowerCase() === "1") {
|
|
1579
|
+
if (process.env["JSON_CACHE"]?.trim().toLowerCase() === "true" || process.env["JSON_CACHE"]?.trim().toLowerCase() === "1") {
|
|
1615
1580
|
program.registerConstantInteger("JSON_CACHE", Type.bool, i64_one);
|
|
1616
1581
|
}
|
|
1617
1582
|
}
|
|
1618
1583
|
afterParse(parser) {
|
|
1619
|
-
const transformer = JSONTransform
|
|
1620
|
-
transformer.schemas = new Map();
|
|
1621
|
-
transformer.sources = new SourceSet();
|
|
1622
|
-
transformer.visitedClasses = new Set();
|
|
1623
|
-
transformer.simdStatements = [];
|
|
1584
|
+
const transformer = new JSONTransform();
|
|
1624
1585
|
const sources = parser.sources
|
|
1625
1586
|
.filter((source) => {
|
|
1626
1587
|
const p = source.internalPath;
|
|
1627
|
-
if (p.startsWith("~lib/rt") ||
|
|
1628
|
-
p.startsWith("~lib/performance") ||
|
|
1629
|
-
p.startsWith("~lib/wasi_") ||
|
|
1630
|
-
p.startsWith("~lib/shared/")) {
|
|
1588
|
+
if (p.startsWith("~lib/rt") || p.startsWith("~lib/performance") || p.startsWith("~lib/wasi_") || p.startsWith("~lib/shared/")) {
|
|
1631
1589
|
return false;
|
|
1632
1590
|
}
|
|
1633
1591
|
return !isStdlib(source);
|
|
@@ -1688,22 +1646,16 @@ function sortMembers(members) {
|
|
|
1688
1646
|
});
|
|
1689
1647
|
}
|
|
1690
1648
|
function toU16(data, offset = 0) {
|
|
1691
|
-
return data.charCodeAt(offset + 0)
|
|
1649
|
+
return data.charCodeAt(offset + 0);
|
|
1692
1650
|
}
|
|
1693
1651
|
function toU32(data, offset = 0) {
|
|
1694
|
-
return (
|
|
1695
|
-
data.charCodeAt(offset + 0)).toString();
|
|
1652
|
+
return (data.charCodeAt(offset + 1) << 16) | data.charCodeAt(offset + 0);
|
|
1696
1653
|
}
|
|
1697
1654
|
function toU48(data, offset = 0) {
|
|
1698
|
-
return (
|
|
1699
|
-
(BigInt(data.charCodeAt(offset + 1)) << 16n) |
|
|
1700
|
-
BigInt(data.charCodeAt(offset + 0))).toString();
|
|
1655
|
+
return (BigInt(data.charCodeAt(offset + 2)) << 32n) | (BigInt(data.charCodeAt(offset + 1)) << 16n) | BigInt(data.charCodeAt(offset + 0));
|
|
1701
1656
|
}
|
|
1702
1657
|
function toU64(data, offset = 0) {
|
|
1703
|
-
return (
|
|
1704
|
-
(BigInt(data.charCodeAt(offset + 2)) << 32n) |
|
|
1705
|
-
(BigInt(data.charCodeAt(offset + 1)) << 16n) |
|
|
1706
|
-
BigInt(data.charCodeAt(offset + 0))).toString();
|
|
1658
|
+
return (BigInt(data.charCodeAt(offset + 3)) << 48n) | (BigInt(data.charCodeAt(offset + 2)) << 32n) | (BigInt(data.charCodeAt(offset + 1)) << 16n) | BigInt(data.charCodeAt(offset + 0));
|
|
1707
1659
|
}
|
|
1708
1660
|
function toMemCDecl(n, indent) {
|
|
1709
1661
|
let out = "";
|
|
@@ -1746,34 +1698,12 @@ function strToNum(data, simd = false, offset = 0) {
|
|
|
1746
1698
|
const out = [];
|
|
1747
1699
|
let n = data.length;
|
|
1748
1700
|
while (n >= 8 && simd) {
|
|
1749
|
-
out.push([
|
|
1750
|
-
"v128",
|
|
1751
|
-
"i16x8(" +
|
|
1752
|
-
data.charCodeAt(offset + 0) +
|
|
1753
|
-
", " +
|
|
1754
|
-
data.charCodeAt(offset + 1) +
|
|
1755
|
-
", " +
|
|
1756
|
-
data.charCodeAt(offset + 2) +
|
|
1757
|
-
", " +
|
|
1758
|
-
data.charCodeAt(offset + 3) +
|
|
1759
|
-
", " +
|
|
1760
|
-
data.charCodeAt(offset + 4) +
|
|
1761
|
-
", " +
|
|
1762
|
-
data.charCodeAt(offset + 5) +
|
|
1763
|
-
", " +
|
|
1764
|
-
data.charCodeAt(offset + 6) +
|
|
1765
|
-
", " +
|
|
1766
|
-
data.charCodeAt(offset + 7) +
|
|
1767
|
-
")",
|
|
1768
|
-
]);
|
|
1701
|
+
out.push(["v128", "i16x8(" + data.charCodeAt(offset + 0) + ", " + data.charCodeAt(offset + 1) + ", " + data.charCodeAt(offset + 2) + ", " + data.charCodeAt(offset + 3) + ", " + data.charCodeAt(offset + 4) + ", " + data.charCodeAt(offset + 5) + ", " + data.charCodeAt(offset + 6) + ", " + data.charCodeAt(offset + 7) + ")"]);
|
|
1769
1702
|
offset += 8;
|
|
1770
1703
|
n -= 8;
|
|
1771
1704
|
}
|
|
1772
1705
|
while (n >= 4) {
|
|
1773
|
-
const value = (BigInt(data.charCodeAt(offset + 3)) << 48n) |
|
|
1774
|
-
(BigInt(data.charCodeAt(offset + 2)) << 32n) |
|
|
1775
|
-
(BigInt(data.charCodeAt(offset + 1)) << 16n) |
|
|
1776
|
-
BigInt(data.charCodeAt(offset + 0));
|
|
1706
|
+
const value = (BigInt(data.charCodeAt(offset + 3)) << 48n) | (BigInt(data.charCodeAt(offset + 2)) << 32n) | (BigInt(data.charCodeAt(offset + 1)) << 16n) | BigInt(data.charCodeAt(offset + 0));
|
|
1777
1707
|
out.push(["u64", value.toString()]);
|
|
1778
1708
|
offset += 4;
|
|
1779
1709
|
n -= 4;
|
|
@@ -1824,20 +1754,7 @@ function sizeof(type) {
|
|
|
1824
1754
|
return 0;
|
|
1825
1755
|
}
|
|
1826
1756
|
function isPrimitive(type) {
|
|
1827
|
-
const primitiveTypes = [
|
|
1828
|
-
"u8",
|
|
1829
|
-
"u16",
|
|
1830
|
-
"u32",
|
|
1831
|
-
"u64",
|
|
1832
|
-
"i8",
|
|
1833
|
-
"i16",
|
|
1834
|
-
"i32",
|
|
1835
|
-
"i64",
|
|
1836
|
-
"f32",
|
|
1837
|
-
"f64",
|
|
1838
|
-
"bool",
|
|
1839
|
-
"boolean",
|
|
1840
|
-
];
|
|
1757
|
+
const primitiveTypes = ["u8", "u16", "u32", "u64", "i8", "i16", "i32", "i64", "f32", "f64", "bool", "boolean"];
|
|
1841
1758
|
return primitiveTypes.some((v) => type.startsWith(v));
|
|
1842
1759
|
}
|
|
1843
1760
|
function isBoolean(type) {
|
|
@@ -1847,12 +1764,10 @@ function isString(type) {
|
|
|
1847
1764
|
return stripNull(type) == "string" || stripNull(type) == "String";
|
|
1848
1765
|
}
|
|
1849
1766
|
function isArray(type) {
|
|
1850
|
-
return
|
|
1851
|
-
type.startsWith("Set<") ||
|
|
1852
|
-
type.startsWith("StaticArray<"));
|
|
1767
|
+
return type.startsWith("Array<") || type.startsWith("Set<") || type.startsWith("StaticArray<");
|
|
1853
1768
|
}
|
|
1854
1769
|
function isEnum(type, source, parser) {
|
|
1855
|
-
return
|
|
1770
|
+
return source.getEnum(type) != null || source.getImportedEnum(type, parser) != null;
|
|
1856
1771
|
}
|
|
1857
1772
|
export function stripNull(type) {
|
|
1858
1773
|
if (type.endsWith(" | null")) {
|