json-as 0.9.29 → 1.0.0-alpha.2
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/.github/workflows/nodejs.yml +0 -3
- package/.gitmodules +0 -0
- package/.prettierrc.json +3 -2
- package/CHANGELOG +24 -0
- package/LICENSE +1 -1
- package/README.md +23 -7
- package/as-test.config.json +1 -1
- package/asconfig.json +2 -2
- package/assembly/__benches__/misc.bench.ts +0 -34
- package/assembly/__tests__/bool.spec.ts +1 -1
- package/assembly/__tests__/simd/string.spec.ts +32 -0
- package/assembly/custom/memory.ts +25 -0
- package/assembly/custom/util.ts +14 -92
- package/assembly/deserialize/simd/string.ts +103 -0
- package/assembly/deserialize/simple/arbitrary.ts +17 -0
- package/assembly/deserialize/simple/array/arbitrary.ts +113 -0
- package/assembly/deserialize/simple/array/array.ts +18 -0
- package/assembly/deserialize/simple/array/bool.ts +17 -0
- package/assembly/deserialize/simple/array/float.ts +28 -0
- package/assembly/deserialize/simple/array/integer.ts +27 -0
- package/assembly/deserialize/simple/array/map.ts +18 -0
- package/assembly/deserialize/simple/array/object.ts +18 -0
- package/assembly/deserialize/simple/array/string.ts +22 -0
- package/assembly/deserialize/simple/array.ts +48 -0
- package/assembly/deserialize/simple/bool.ts +9 -0
- package/assembly/deserialize/simple/date.ts +11 -0
- package/assembly/deserialize/simple/float.ts +10 -0
- package/assembly/deserialize/simple/integer.ts +5 -0
- package/assembly/deserialize/simple/map.ts +154 -0
- package/assembly/deserialize/simple/object.ts +158 -0
- package/assembly/deserialize/simple/string.ts +48 -0
- package/assembly/globals/tables.ts +417 -0
- package/assembly/index.d.ts +9 -13
- package/assembly/index.ts +261 -146
- package/assembly/serialize/simd/string.ts +176 -0
- package/assembly/serialize/simple/arbitrary.ts +36 -0
- package/assembly/serialize/simple/array.ts +32 -0
- package/assembly/serialize/simple/bool.ts +19 -0
- package/assembly/serialize/simple/date.ts +13 -0
- package/assembly/serialize/simple/float.ts +7 -0
- package/assembly/serialize/simple/integer.ts +7 -0
- package/assembly/serialize/simple/map.ts +43 -0
- package/assembly/serialize/simple/object.ts +7 -0
- package/assembly/serialize/simple/string.ts +48 -0
- package/assembly/test.ts +36 -27
- package/assembly/tsconfig.json +2 -91
- package/assembly/types.ts +0 -0
- package/assembly/util/atoi.ts +35 -0
- package/assembly/util/bytes.ts +12 -0
- package/assembly/util/concat.ts +9 -0
- package/assembly/util/getArrayDepth.ts +17 -0
- package/assembly/util/index.ts +5 -0
- package/assembly/util/isSpace.ts +4 -0
- package/assembly/util/nextPowerOf2.ts +4 -0
- package/assembly/util/ptrToStr.ts +7 -0
- package/assembly/util/snp.ts +69 -0
- package/bench.js +5 -5
- package/modules/as-bs/LICENSE +21 -0
- package/modules/as-bs/README.md +95 -0
- package/modules/as-bs/assembly/index.ts +166 -0
- package/modules/as-bs/assembly/tsconfig.json +97 -0
- package/modules/as-bs/index.ts +1 -0
- package/modules/as-bs/package.json +32 -0
- package/package.json +41 -48
- package/transform/lib/builder.js +1275 -0
- package/transform/lib/builder.js.map +1 -0
- package/transform/lib/index.js +548 -443
- package/transform/lib/index.js.map +1 -1
- package/transform/lib/linker.js +16 -0
- package/transform/lib/linker.js.map +1 -0
- package/transform/lib/types.js +26 -0
- package/transform/lib/types.js.map +1 -0
- package/transform/lib/util.js +47 -0
- package/transform/lib/util.js.map +1 -0
- package/transform/lib/visitor.js +510 -430
- package/transform/lib/visitor.js.map +1 -0
- package/transform/package.json +1 -33
- package/transform/src/builder.ts +1371 -0
- package/transform/src/index.ts +574 -340
- package/transform/src/linker.ts +21 -0
- package/transform/src/types.ts +28 -0
- package/transform/src/util.ts +56 -0
- package/transform/src/visitor.ts +531 -0
- package/transform/tsconfig.json +3 -1
- package/assembly/__benches__/as-tral.d.ts +0 -1
- package/assembly/__tests__/date.spec.ts +0 -12
- package/assembly/custom/bs.ts +0 -202
- package/assembly/deserialize/array/array.ts +0 -31
- package/assembly/deserialize/array/bool.ts +0 -19
- package/assembly/deserialize/array/float.ts +0 -24
- package/assembly/deserialize/array/integer.ts +0 -24
- package/assembly/deserialize/array/map.ts +0 -27
- package/assembly/deserialize/array/object.ts +0 -27
- package/assembly/deserialize/array/string.ts +0 -29
- package/assembly/deserialize/array.ts +0 -46
- package/assembly/deserialize/bool.ts +0 -34
- package/assembly/deserialize/date.ts +0 -19
- package/assembly/deserialize/float.ts +0 -21
- package/assembly/deserialize/integer.ts +0 -16
- package/assembly/deserialize/map.ts +0 -139
- package/assembly/deserialize/object.ts +0 -211
- package/assembly/deserialize/string.ts +0 -149
- package/assembly/serialize/array.ts +0 -44
- package/assembly/serialize/bool.ts +0 -10
- package/assembly/serialize/date.ts +0 -4
- package/assembly/serialize/float.ts +0 -4
- package/assembly/serialize/integer.ts +0 -5
- package/assembly/serialize/map.ts +0 -24
- package/assembly/serialize/object.ts +0 -13
- package/assembly/serialize/string.ts +0 -284
package/assembly/index.ts
CHANGED
|
@@ -1,23 +1,30 @@
|
|
|
1
1
|
/// <reference path="./index.d.ts" />
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
|
|
17
|
-
import { deserializeInteger, deserializeInteger_Safe } from "./deserialize/integer";
|
|
18
|
-
import { deserializeString, deserializeString_Safe } from "./deserialize/string";
|
|
2
|
+
import { bs } from "../modules/as-bs";
|
|
3
|
+
|
|
4
|
+
import { serializeString } from "./serialize/simple/string";
|
|
5
|
+
import { serializeArray } from "./serialize/simple/array";
|
|
6
|
+
import { serializeMap } from "./serialize/simple/map";
|
|
7
|
+
import { deserializeBoolean } from "./deserialize/simple/bool";
|
|
8
|
+
import { deserializeArray } from "./deserialize/simple/array";
|
|
9
|
+
import { deserializeFloat } from "./deserialize/simple/float";
|
|
10
|
+
import { deserializeObject } from "./deserialize/simple/object";
|
|
11
|
+
import { deserializeMap } from "./deserialize/simple/map";
|
|
12
|
+
import { deserializeDate } from "./deserialize/simple/date";
|
|
13
|
+
import { deserializeInteger } from "./deserialize/simple/integer";
|
|
14
|
+
import { deserializeString } from "./deserialize/simple/string";
|
|
15
|
+
import { serializeArbitrary } from "./serialize/simple/arbitrary";
|
|
16
|
+
|
|
19
17
|
import { Sink } from "./custom/sink";
|
|
20
|
-
import {
|
|
18
|
+
import { NULL_WORD, QUOTE } from "./custom/chars";
|
|
19
|
+
import { dtoa_buffered, itoa_buffered } from "util/number";
|
|
20
|
+
import { serializeBool } from "./serialize/simple/bool";
|
|
21
|
+
import { serializeInteger } from "./serialize/simple/integer";
|
|
22
|
+
import { serializeFloat } from "./serialize/simple/float";
|
|
23
|
+
import { serializeObject } from "./serialize/simple/object";
|
|
24
|
+
import { ptrToStr } from "./util/ptrToStr";
|
|
25
|
+
import { bytes } from "./util";
|
|
26
|
+
|
|
27
|
+
export type Raw = string;
|
|
21
28
|
|
|
22
29
|
/**
|
|
23
30
|
* Offset of the 'storage' property in the JSON.Value class.
|
|
@@ -29,6 +36,158 @@ import { getArrayDepth } from "./custom/util";
|
|
|
29
36
|
* JSON Encoder/Decoder for AssemblyScript
|
|
30
37
|
*/
|
|
31
38
|
export namespace JSON {
|
|
39
|
+
/**
|
|
40
|
+
* Serializes valid JSON data
|
|
41
|
+
* ```js
|
|
42
|
+
* JSON.stringify<T>(data)
|
|
43
|
+
* ```
|
|
44
|
+
* @param data T
|
|
45
|
+
* @returns string
|
|
46
|
+
*/
|
|
47
|
+
export function stringify<T>(data: T, out: string | null = null): string {
|
|
48
|
+
if (isBoolean<T>()) {
|
|
49
|
+
if (out) {
|
|
50
|
+
if (<bool>data == true) {
|
|
51
|
+
out = changetype<string>(__renew(changetype<usize>(out), 8));
|
|
52
|
+
store<u64>(changetype<usize>(out), 28429475166421108);
|
|
53
|
+
} else {
|
|
54
|
+
out = changetype<string>(__renew(changetype<usize>(out), 10));
|
|
55
|
+
store<u64>(changetype<usize>(out), 32370086184550502);
|
|
56
|
+
store<u16>(changetype<usize>(out), 101, 8);
|
|
57
|
+
}
|
|
58
|
+
return out;
|
|
59
|
+
}
|
|
60
|
+
return data ? "true" : "false";
|
|
61
|
+
} else if (isInteger<T>() && nameof<T>() == "usize" && data == 0) {
|
|
62
|
+
if (out) {
|
|
63
|
+
out = changetype<string>(__renew(changetype<usize>(out), 8));
|
|
64
|
+
store<u64>(changetype<usize>(out), 30399761348886638);
|
|
65
|
+
return out;
|
|
66
|
+
}
|
|
67
|
+
return NULL_WORD;
|
|
68
|
+
} else if (isInteger<T>(data)) {
|
|
69
|
+
if (out) {
|
|
70
|
+
out = changetype<string>(__renew(changetype<usize>(out), sizeof<T>() << 3));
|
|
71
|
+
|
|
72
|
+
// @ts-ignore
|
|
73
|
+
const bytes = itoa_buffered(changetype<usize>(out), data) << 1;
|
|
74
|
+
return (out = changetype<string>(__renew(changetype<usize>(out), bytes)));
|
|
75
|
+
}
|
|
76
|
+
return data.toString();
|
|
77
|
+
} else if (isFloat<T>(data)) {
|
|
78
|
+
if (out) {
|
|
79
|
+
out = changetype<string>(__renew(changetype<usize>(out), 64));
|
|
80
|
+
|
|
81
|
+
// @ts-ignore
|
|
82
|
+
const bytes = dtoa_buffered(changetype<usize>(out), data) << 1;
|
|
83
|
+
return (out = changetype<string>(__renew(changetype<usize>(out), bytes)));
|
|
84
|
+
}
|
|
85
|
+
return data.toString();
|
|
86
|
+
// @ts-ignore: Function is generated by transform
|
|
87
|
+
} else if (isNullable<T>() && changetype<usize>(data) == <usize>0) {
|
|
88
|
+
if (out) {
|
|
89
|
+
out = changetype<string>(__renew(changetype<usize>(out), 8));
|
|
90
|
+
store<u64>(changetype<usize>(out), 30399761348886638);
|
|
91
|
+
return out;
|
|
92
|
+
}
|
|
93
|
+
return NULL_WORD;
|
|
94
|
+
// @ts-ignore
|
|
95
|
+
} else if (isString<nonnull<T>>()) {
|
|
96
|
+
if (out) {
|
|
97
|
+
out = changetype<string>(__renew(changetype<usize>(out), bytes(data) + 4));
|
|
98
|
+
// const oldSize = bs.byteLength;
|
|
99
|
+
const oldBuf = bs.buffer;
|
|
100
|
+
const newSize = bytes(data) + 4;
|
|
101
|
+
const newBuf = __new(newSize, idof<string>());
|
|
102
|
+
bs.setBuffer(newBuf);
|
|
103
|
+
serializeString(changetype<string>(data));
|
|
104
|
+
bs.setBuffer(oldBuf);
|
|
105
|
+
return changetype<string>(newBuf);
|
|
106
|
+
}
|
|
107
|
+
serializeString(changetype<string>(data));
|
|
108
|
+
return bs.out<string>();
|
|
109
|
+
// @ts-ignore: Supplied by transform
|
|
110
|
+
} else if (isDefined(data.__SERIALIZE) && isDefined(data.__ALLOCATE)) {
|
|
111
|
+
// @ts-ignore
|
|
112
|
+
data.__ALLOCATE();
|
|
113
|
+
// @ts-ignore
|
|
114
|
+
data.__SERIALIZE(changetype<usize>(data));
|
|
115
|
+
return bs.out<string>();
|
|
116
|
+
// @ts-ignore: Supplied by transform
|
|
117
|
+
} else if (data instanceof Date) {
|
|
118
|
+
out = out ? changetype<string>(__renew(changetype<usize>(out), 52)) : changetype<string>(__new(52, idof<string>()));
|
|
119
|
+
|
|
120
|
+
store<u16>(changetype<usize>(out), QUOTE);
|
|
121
|
+
memory.copy(changetype<usize>(out) + 2, changetype<usize>(data.toISOString()), 48);
|
|
122
|
+
store<u16>(changetype<usize>(out), 50);
|
|
123
|
+
return out;
|
|
124
|
+
} else if (data instanceof Array) {
|
|
125
|
+
// @ts-ignore
|
|
126
|
+
serializeArray(changetype<nonnull<T>>(data));
|
|
127
|
+
return bs.out<string>();
|
|
128
|
+
} else if (data instanceof Map) {
|
|
129
|
+
// @ts-ignore
|
|
130
|
+
serializeMap(changetype<nonnull<T>>(data));
|
|
131
|
+
return bs.out<string>();
|
|
132
|
+
} else if (data instanceof JSON.Value) {
|
|
133
|
+
serializeArbitrary(data);
|
|
134
|
+
return bs.out<string>();
|
|
135
|
+
} else if (data instanceof JSON.Box) {
|
|
136
|
+
return JSON.stringify(data.value);
|
|
137
|
+
} else {
|
|
138
|
+
ERROR(`Could not serialize data of type ${nameof<T>()}. Make sure to add the correct decorators to classes.`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Parses valid JSON strings into their original format
|
|
144
|
+
* ```js
|
|
145
|
+
* JSON.parse<T>(data)
|
|
146
|
+
* ```
|
|
147
|
+
* @param data string
|
|
148
|
+
* @returns T
|
|
149
|
+
*/
|
|
150
|
+
export function parse<T>(data: string): T {
|
|
151
|
+
const dataSize = bytes(data);
|
|
152
|
+
const dataPtr = changetype<usize>(data);
|
|
153
|
+
if (isBoolean<T>()) {
|
|
154
|
+
return deserializeBoolean(dataPtr, dataPtr + dataSize) as T;
|
|
155
|
+
} else if (isInteger<T>()) {
|
|
156
|
+
return deserializeInteger<T>(dataPtr, dataPtr + dataSize);
|
|
157
|
+
} else if (isFloat<T>()) {
|
|
158
|
+
return deserializeFloat<T>(dataPtr, dataPtr + dataSize);
|
|
159
|
+
} else if (isNullable<T>() && data.length == 4 && data == "null") {
|
|
160
|
+
// @ts-ignore
|
|
161
|
+
return null;
|
|
162
|
+
} else if (isString<T>()) {
|
|
163
|
+
// @ts-ignore
|
|
164
|
+
return deserializeString(dataPtr, dataPtr + dataSize);
|
|
165
|
+
} else if (isArray<T>()) {
|
|
166
|
+
// @ts-ignore
|
|
167
|
+
return deserializeArray<nonnull<T>>(dataPtr, dataPtr + dataSize, changetype<usize>(instantiate<T>()));
|
|
168
|
+
}
|
|
169
|
+
let type: nonnull<T> = changetype<nonnull<T>>(0);
|
|
170
|
+
// @ts-ignore: Defined by transform
|
|
171
|
+
if (isDefined(type.__DESERIALIZE) && isDefined(type.__INITIALIZE)) {
|
|
172
|
+
const out = __new(offsetof<nonnull<T>>(), idof<nonnull<T>>());
|
|
173
|
+
// @ts-ignore
|
|
174
|
+
changetype<nonnull<T>>(out).__INITIALIZE();
|
|
175
|
+
// @ts-ignore
|
|
176
|
+
return deserializeObject<nonnull<T>>(dataPtr, dataPtr + dataSize, out);
|
|
177
|
+
} else if (type instanceof Map) {
|
|
178
|
+
// @ts-ignore
|
|
179
|
+
return deserializeMap<nonnull<T>>(dataPtr, dataPtr + dataSize);
|
|
180
|
+
} else if (type instanceof Date) {
|
|
181
|
+
// @ts-ignore
|
|
182
|
+
return deserializeDate(dataPtr, dataPtr + dataSize);
|
|
183
|
+
} else if (type instanceof JSON.Box) {
|
|
184
|
+
// @ts-ignore
|
|
185
|
+
return new JSON.Box(JSON.parse<indexof<T>>(data));
|
|
186
|
+
} else {
|
|
187
|
+
ERROR(`Could not deserialize data ${data} to type ${nameof<T>()}. Make sure to add the correct decorators to classes.`);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
32
191
|
/**
|
|
33
192
|
* Enum representing the different types supported by JSON.
|
|
34
193
|
*/
|
|
@@ -42,11 +201,15 @@ export namespace JSON {
|
|
|
42
201
|
F64 = 6,
|
|
43
202
|
Bool = 7,
|
|
44
203
|
String = 8,
|
|
45
|
-
|
|
46
|
-
Array =
|
|
204
|
+
Object = 9,
|
|
205
|
+
Array = 10,
|
|
206
|
+
Struct = 11,
|
|
47
207
|
}
|
|
208
|
+
|
|
48
209
|
export type Raw = string;
|
|
210
|
+
|
|
49
211
|
export class Value {
|
|
212
|
+
static METHODS: Map<u32, u32> = new Map<u32, u32>();
|
|
50
213
|
public type: i32;
|
|
51
214
|
|
|
52
215
|
// @ts-ignore
|
|
@@ -103,11 +266,19 @@ export namespace JSON {
|
|
|
103
266
|
if (idof<T>() !== idof<Map<string, JSON.Value>>()) {
|
|
104
267
|
abort("Maps must be of type Map<string, JSON.Value>!");
|
|
105
268
|
}
|
|
106
|
-
this.type = JSON.Types.
|
|
269
|
+
this.type = JSON.Types.Struct;
|
|
107
270
|
store<T>(changetype<usize>(this), value, STORAGE);
|
|
108
|
-
|
|
271
|
+
// @ts-ignore
|
|
272
|
+
} else if (isDefined(value.__SERIALIZE)) {
|
|
273
|
+
this.type = idof<T>() + JSON.Types.Struct;
|
|
274
|
+
// @ts-ignore
|
|
275
|
+
if (!JSON.Value.METHODS.has(idof<T>())) JSON.Value.METHODS.set(idof<T>(), value.__SERIALIZE.index);
|
|
276
|
+
// @ts-ignore
|
|
277
|
+
store<T>(changetype<usize>(this), value, STORAGE);
|
|
278
|
+
// @ts-ignore
|
|
279
|
+
} else if (isArray<T>() && idof<valueof<T>>() == idof<JSON.Value>()) {
|
|
109
280
|
// @ts-ignore: T satisfies constraints of any[]
|
|
110
|
-
this.type = JSON.Types.Array
|
|
281
|
+
this.type = JSON.Types.Array;
|
|
111
282
|
store<T>(changetype<usize>(this), value, STORAGE);
|
|
112
283
|
}
|
|
113
284
|
}
|
|
@@ -122,7 +293,6 @@ export namespace JSON {
|
|
|
122
293
|
|
|
123
294
|
/**
|
|
124
295
|
* Converts the JSON.Value to a string representation.
|
|
125
|
-
* @param useString - If true, treats Buffer as a string.
|
|
126
296
|
* @returns The string representation of the JSON.Value.
|
|
127
297
|
*/
|
|
128
298
|
toString(): string {
|
|
@@ -139,7 +309,7 @@ export namespace JSON {
|
|
|
139
309
|
return '"' + this.get<string>() + '"';
|
|
140
310
|
case JSON.Types.Bool:
|
|
141
311
|
return this.get<boolean>() ? "true" : "false";
|
|
142
|
-
|
|
312
|
+
case JSON.Types.Array: {
|
|
143
313
|
const arr = this.get<JSON.Value[]>();
|
|
144
314
|
if (!arr.length) return "[]";
|
|
145
315
|
const out = Sink.fromStringLiteral("[");
|
|
@@ -156,158 +326,103 @@ export namespace JSON {
|
|
|
156
326
|
out.write("]");
|
|
157
327
|
return out.toString();
|
|
158
328
|
}
|
|
329
|
+
default: {
|
|
330
|
+
const fn = JSON.Value.METHODS.get(this.type - JSON.Types.Struct);
|
|
331
|
+
const value = this.get<usize>();
|
|
332
|
+
return call_indirect<string>(fn, 0, value);
|
|
333
|
+
}
|
|
159
334
|
}
|
|
160
335
|
}
|
|
161
336
|
}
|
|
337
|
+
|
|
338
|
+
/**
|
|
339
|
+
* Box for primitive types
|
|
340
|
+
*/
|
|
162
341
|
export class Box<T> {
|
|
163
342
|
constructor(public value: T) {}
|
|
164
|
-
|
|
165
|
-
|
|
343
|
+
/**
|
|
344
|
+
* Creates a reference to a primitive type
|
|
345
|
+
* This means that it can create a nullable primitive
|
|
346
|
+
* ```js
|
|
347
|
+
* JSON.stringify<Box<i32> | null>(null);
|
|
348
|
+
* // null
|
|
349
|
+
* ```
|
|
350
|
+
* @param from T
|
|
351
|
+
* @returns Box<T>
|
|
352
|
+
*/
|
|
166
353
|
@inline static from<T>(value: T): Box<T> {
|
|
167
354
|
return new Box(value);
|
|
168
355
|
}
|
|
169
356
|
}
|
|
170
357
|
|
|
171
|
-
|
|
172
|
-
* Stringifies valid JSON data.
|
|
173
|
-
* ```js
|
|
174
|
-
* JSON.stringify<T>(data)
|
|
175
|
-
* ```
|
|
176
|
-
* @param data T
|
|
177
|
-
* @returns string
|
|
178
|
-
*/
|
|
179
|
-
export function stringify<T>(data: T /*, options: SerializeOptions = DEFAULT_SERIALIZE_OPTIONS*/): string {
|
|
358
|
+
export function __serialize<T>(src: T): void {
|
|
180
359
|
if (isBoolean<T>()) {
|
|
181
|
-
|
|
182
|
-
} else if (isInteger<T>() && nameof<T>() == "usize" &&
|
|
183
|
-
|
|
360
|
+
serializeBool(src as bool);
|
|
361
|
+
} else if (isInteger<T>() && nameof<T>() == "usize" && src == 0) {
|
|
362
|
+
bs.ensureSize(8);
|
|
363
|
+
store<u64>(bs.offset, 30399761348886638);
|
|
364
|
+
bs.offset += 8;
|
|
184
365
|
} else if (isInteger<T>()) {
|
|
185
366
|
// @ts-ignore
|
|
186
|
-
|
|
187
|
-
} else if (isFloat<T>(
|
|
367
|
+
serializeInteger<T>(src);
|
|
368
|
+
} else if (isFloat<T>(src)) {
|
|
188
369
|
// @ts-ignore
|
|
189
|
-
|
|
370
|
+
serializeFloat<T>(src);
|
|
190
371
|
// @ts-ignore: Function is generated by transform
|
|
191
|
-
} else if (isNullable<T>() && changetype<usize>(
|
|
192
|
-
|
|
193
|
-
|
|
372
|
+
} else if (isNullable<T>() && changetype<usize>(src) == <usize>0) {
|
|
373
|
+
bs.ensureSize(8);
|
|
374
|
+
store<u64>(bs.offset, 30399761348886638);
|
|
375
|
+
bs.offset += 8;
|
|
194
376
|
} else if (isString<nonnull<T>>()) {
|
|
195
|
-
|
|
377
|
+
serializeString(src as string);
|
|
196
378
|
// @ts-ignore: Supplied by transform
|
|
197
|
-
} else if (isDefined(
|
|
198
|
-
/*if (options.pretty) {
|
|
199
|
-
// @ts-ignore
|
|
200
|
-
return serializeObject_Pretty(changetype<nonnull<T>>(data));
|
|
201
|
-
}*/
|
|
202
|
-
// @ts-ignore
|
|
203
|
-
return serializeObject(changetype<nonnull<T>>(data));
|
|
204
|
-
} else if (data instanceof Date) {
|
|
205
|
-
// @ts-ignore
|
|
206
|
-
return serializeDate(changetype<nonnull<T>>(data));
|
|
207
|
-
} else if (data instanceof Array) {
|
|
208
|
-
// @ts-ignore
|
|
209
|
-
return serializeArray(changetype<nonnull<T>>(data));
|
|
210
|
-
} else if (data instanceof Map) {
|
|
211
|
-
// @ts-ignore
|
|
212
|
-
return serializeMap(changetype<nonnull<T>>(data));
|
|
213
|
-
} else {
|
|
214
|
-
throw new Error(`Could not serialize data of type ${nameof<T>()}. Make sure to add the correct decorators to classes.`);
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
/**
|
|
218
|
-
* Parses valid JSON strings into their original format.
|
|
219
|
-
* ```js
|
|
220
|
-
* JSON.parse<T>(data)
|
|
221
|
-
* ```
|
|
222
|
-
* @param data string
|
|
223
|
-
* @returns T
|
|
224
|
-
*/
|
|
225
|
-
export function parse<T>(data: string): T {
|
|
226
|
-
if (isBoolean<T>()) {
|
|
227
|
-
return deserializeBoolean(data) as T;
|
|
228
|
-
} else if (isInteger<T>()) {
|
|
229
|
-
return deserializeInteger<T>(data);
|
|
230
|
-
} else if (isFloat<T>()) {
|
|
231
|
-
return deserializeFloat<T>(data);
|
|
232
|
-
} else if (isNullable<T>() && data.length === 4 && data == "null") {
|
|
233
|
-
// @ts-ignore
|
|
234
|
-
return null;
|
|
235
|
-
} else if (isString<T>()) {
|
|
379
|
+
} else if (isDefined(src.__SERIALIZE)) {
|
|
236
380
|
// @ts-ignore
|
|
237
|
-
|
|
238
|
-
} else if (
|
|
239
|
-
// @ts-ignore
|
|
240
|
-
return deserializeArray<nonnull<T>>(data);
|
|
241
|
-
}
|
|
242
|
-
let type: nonnull<T> = changetype<nonnull<T>>(0);
|
|
243
|
-
// @ts-ignore: Defined by transform
|
|
244
|
-
if (isDefined(type.__DESERIALIZE)) {
|
|
381
|
+
serializeObject(changetype<nonnull<T>>(src));
|
|
382
|
+
} else if (src instanceof Date) {
|
|
245
383
|
// @ts-ignore
|
|
246
|
-
|
|
247
|
-
} else if (
|
|
384
|
+
serializeDate(changetype<nonnull<T>>(src));
|
|
385
|
+
} else if (src instanceof Array) {
|
|
248
386
|
// @ts-ignore
|
|
249
|
-
|
|
250
|
-
} else if (
|
|
387
|
+
serializeArray(changetype<nonnull<T>>(src));
|
|
388
|
+
} else if (src instanceof Map) {
|
|
251
389
|
// @ts-ignore
|
|
252
|
-
|
|
390
|
+
serializeMap(changetype<nonnull<T>>(src));
|
|
391
|
+
} else if (src instanceof JSON.Value) {
|
|
392
|
+
serializeArbitrary(src);
|
|
393
|
+
} else if (src instanceof JSON.Box) {
|
|
394
|
+
__serialize(src.value);
|
|
253
395
|
} else {
|
|
254
|
-
|
|
396
|
+
ERROR(`Could not serialize provided data. Make sure to add the correct decorators to classes.`);
|
|
255
397
|
}
|
|
256
398
|
}
|
|
257
|
-
|
|
258
|
-
* Parses valid JSON strings into their original format (safely).
|
|
259
|
-
* ```js
|
|
260
|
-
* JSON.parseSafe<T>(data)
|
|
261
|
-
* ```
|
|
262
|
-
* @param data string
|
|
263
|
-
* @returns T
|
|
264
|
-
*/
|
|
265
|
-
|
|
266
|
-
// @ts-ignore: Decorator
|
|
267
|
-
@inline export function parseSafe<T>(data: string): T {
|
|
399
|
+
export function __deserialize<T>(srcStart: usize, srcEnd: usize, dst: usize = 0): T {
|
|
268
400
|
if (isBoolean<T>()) {
|
|
269
|
-
|
|
401
|
+
// @ts-ignore: type
|
|
402
|
+
return deserializeBoolean(srcStart, srcEnd);
|
|
270
403
|
} else if (isInteger<T>()) {
|
|
271
|
-
return
|
|
404
|
+
return deserializeInteger<T>(srcStart, srcEnd);
|
|
272
405
|
} else if (isFloat<T>()) {
|
|
273
|
-
return deserializeFloat<T>(
|
|
274
|
-
} else if (isNullable<T>() && data.length === 4 && data == "null") {
|
|
275
|
-
// @ts-ignore
|
|
276
|
-
return null;
|
|
406
|
+
return deserializeFloat<T>(srcStart, srcEnd);
|
|
277
407
|
} else if (isString<T>()) {
|
|
278
|
-
// @ts-ignore
|
|
279
|
-
return
|
|
408
|
+
// @ts-ignore: type
|
|
409
|
+
return deserializeString(srcStart, srcEnd, dst);
|
|
280
410
|
} else if (isArray<T>()) {
|
|
281
411
|
// @ts-ignore
|
|
282
|
-
return
|
|
283
|
-
}
|
|
284
|
-
let type: nonnull<T> = changetype<nonnull<T>>(0);
|
|
285
|
-
// @ts-ignore: Defined by transform
|
|
286
|
-
if (isDefined(type.__DESERIALIZE)) {
|
|
287
|
-
// @ts-ignore
|
|
288
|
-
return deserializeObject_Safe<nonnull<T>>(data.trimStart());
|
|
289
|
-
} else if (type instanceof Map) {
|
|
290
|
-
// @ts-ignore
|
|
291
|
-
return deserializeMap_Safe<nonnull<T>>(data.trimStart());
|
|
292
|
-
} else if (type instanceof Date) {
|
|
293
|
-
// @ts-ignore
|
|
294
|
-
return deserializeDate_Safe(data);
|
|
412
|
+
return deserializeArray<T>(srcStart, srcEnd, dst);
|
|
295
413
|
} else {
|
|
296
|
-
|
|
414
|
+
let type: nonnull<T> = changetype<nonnull<T>>(0);
|
|
415
|
+
// @ts-ignore: declared by transform
|
|
416
|
+
if (isDefined(type.__DESERIALIZE)) {
|
|
417
|
+
return deserializeObject<T>(srcStart, srcEnd, dst);
|
|
418
|
+
} else if (type instanceof Map) {
|
|
419
|
+
// @ts-ignore: type
|
|
420
|
+
return deserializeMap<T>(srcStart, srcEnd, dst);
|
|
421
|
+
} else if (type instanceof Date) {
|
|
422
|
+
// @ts-ignore: type
|
|
423
|
+
return deserializeDate(srcStart, srcEnd);
|
|
424
|
+
}
|
|
297
425
|
}
|
|
426
|
+
throw new Error(`Could not deserialize data '${ptrToStr(srcStart, srcEnd).slice(0, 100)}' to type. Make sure to add the correct decorators to classes.`);
|
|
298
427
|
}
|
|
299
428
|
}
|
|
300
|
-
|
|
301
|
-
// This allows JSON.stringify and JSON.parse to be available globally through an alias
|
|
302
|
-
// @ts-ignore: Decorator
|
|
303
|
-
@global @inline function __SERIALIZE<T>(data: T): string {
|
|
304
|
-
return JSON.stringify(data);
|
|
305
|
-
}
|
|
306
|
-
// @ts-ignore: Decorator
|
|
307
|
-
@global @inline function __DESERIALIZE<T>(data: string): T {
|
|
308
|
-
return JSON.parse<T>(data);
|
|
309
|
-
}
|
|
310
|
-
// @ts-ignore: Decorator
|
|
311
|
-
@global @inline function __DESERIALIZE_SAFE<T>(data: string): T {
|
|
312
|
-
return JSON.parseSafe<T>(data);
|
|
313
|
-
}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { bs } from "../../../modules/as-bs";
|
|
2
|
+
import { BACK_SLASH } from "../../custom/chars";
|
|
3
|
+
import { SERIALIZE_ESCAPE_TABLE } from "../../globals/tables";
|
|
4
|
+
import { OBJECT, TOTAL_OVERHEAD } from "rt/common";
|
|
5
|
+
|
|
6
|
+
const SPLAT_34 = i16x8.splat(34); /* " */
|
|
7
|
+
const SPLAT_92 = i16x8.splat(92); /* \ */
|
|
8
|
+
|
|
9
|
+
const SPLAT_32 = i16x8.splat(32); /* [ESC] */
|
|
10
|
+
const SPLAT_0 = i16x8.splat(0); /* 0 */
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Serializes strings into their JSON counterparts using SIMD operations
|
|
14
|
+
* @param srcStart pointer to begin serializing at
|
|
15
|
+
* @param srcEnd pointer to end serialization at
|
|
16
|
+
*/
|
|
17
|
+
export function serializeString_SIMD(src: string): void {
|
|
18
|
+
const srcSize = changetype<OBJECT>(changetype<usize>(src) - TOTAL_OVERHEAD).rtSize;
|
|
19
|
+
let srcStart = changetype<usize>(src);
|
|
20
|
+
const srcEnd = srcStart + srcSize;
|
|
21
|
+
bs.ensureSize(srcSize + 4);
|
|
22
|
+
const srcEnd16 = srcEnd - 15;
|
|
23
|
+
|
|
24
|
+
store<u8>(changetype<usize>(bs.offset), 34); /* " */
|
|
25
|
+
bs.offset += 2;
|
|
26
|
+
|
|
27
|
+
while (srcStart < srcEnd16) {
|
|
28
|
+
const block = v128.load(srcStart);
|
|
29
|
+
v128.store(bs.offset, block);
|
|
30
|
+
|
|
31
|
+
const backslash_indices = i16x8.eq(block, SPLAT_92);
|
|
32
|
+
const quote_indices = i16x8.eq(block, SPLAT_34);
|
|
33
|
+
const escape_indices = i16x8.lt_u(block, SPLAT_32);
|
|
34
|
+
const sieve = v128.or(v128.or(backslash_indices, quote_indices), escape_indices);
|
|
35
|
+
|
|
36
|
+
let mask = i16x8.bitmask(sieve);
|
|
37
|
+
|
|
38
|
+
while (mask != 0) {
|
|
39
|
+
const lane_index = ctz(mask) << 1;
|
|
40
|
+
const dst_offset = bs.offset + lane_index;
|
|
41
|
+
const src_offset = srcStart + lane_index;
|
|
42
|
+
const code = load<u16>(src_offset) << 2;
|
|
43
|
+
const escaped = load<u32>(SERIALIZE_ESCAPE_TABLE + code);
|
|
44
|
+
|
|
45
|
+
mask &= mask - 1;
|
|
46
|
+
|
|
47
|
+
if ((escaped & 0xffff) != BACK_SLASH) {
|
|
48
|
+
bs.ensureSize(10);
|
|
49
|
+
store<u64>(dst_offset, 13511005048209500);
|
|
50
|
+
store<u32>(dst_offset, escaped, 8);
|
|
51
|
+
v128.store(dst_offset, v128.load(src_offset, 2), 12);
|
|
52
|
+
bs.offset += 10;
|
|
53
|
+
} else {
|
|
54
|
+
bs.ensureSize(2);
|
|
55
|
+
store<u32>(dst_offset, escaped);
|
|
56
|
+
v128.store(dst_offset, v128.load(src_offset, 2), 4);
|
|
57
|
+
bs.offset += 2;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
srcStart += 16;
|
|
62
|
+
bs.offset += 16;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
let rem = srcEnd - srcStart;
|
|
66
|
+
|
|
67
|
+
if (rem & 8) {
|
|
68
|
+
const block = v128.load64_zero(srcStart);
|
|
69
|
+
v128.store64_lane(bs.offset, block, 0);
|
|
70
|
+
|
|
71
|
+
const backslash_indices = i16x8.eq(block, SPLAT_92);
|
|
72
|
+
const quote_indices = i16x8.eq(block, SPLAT_34);
|
|
73
|
+
const escape_indices = i16x8.lt_u(block, SPLAT_32);
|
|
74
|
+
const zero_indices = i16x8.eq(block, SPLAT_0);
|
|
75
|
+
const sieve = v128.and(v128.or(v128.or(backslash_indices, quote_indices), escape_indices), v128.not(zero_indices));
|
|
76
|
+
|
|
77
|
+
let mask = i16x8.bitmask(sieve);
|
|
78
|
+
while (mask != 0) {
|
|
79
|
+
let lane_index = ctz(mask) << 1;
|
|
80
|
+
const dst_offset = bs.offset + lane_index;
|
|
81
|
+
const src_offset = srcStart + lane_index;
|
|
82
|
+
const code = load<u16>(src_offset) << 2;
|
|
83
|
+
const escaped = load<u32>(SERIALIZE_ESCAPE_TABLE + code);
|
|
84
|
+
mask &= mask - 1;
|
|
85
|
+
|
|
86
|
+
if ((escaped & 0xffff) != BACK_SLASH) {
|
|
87
|
+
bs.ensureSize(10);
|
|
88
|
+
store<u64>(dst_offset, 13511005048209500);
|
|
89
|
+
store<u32>(dst_offset, escaped, 8);
|
|
90
|
+
while (lane_index < 6) {
|
|
91
|
+
store<u8>(bs.offset + lane_index, load<u8>(srcStart + lane_index, 2), 12);
|
|
92
|
+
lane_index += 2;
|
|
93
|
+
}
|
|
94
|
+
bs.offset += 10;
|
|
95
|
+
} else {
|
|
96
|
+
bs.ensureSize(2);
|
|
97
|
+
store<u32>(dst_offset, escaped);
|
|
98
|
+
|
|
99
|
+
while (lane_index < 6) {
|
|
100
|
+
store<u8>(bs.offset + lane_index, load<u8>(srcStart + lane_index, 2), 4);
|
|
101
|
+
lane_index += 2;
|
|
102
|
+
}
|
|
103
|
+
bs.offset += 2;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
bs.offset += 8;
|
|
108
|
+
srcStart += 8;
|
|
109
|
+
}
|
|
110
|
+
if (rem & 4) {
|
|
111
|
+
const block = load<u32>(srcStart);
|
|
112
|
+
const codeA = block & 0xffff;
|
|
113
|
+
const codeB = (block >> 16) & 0xffff;
|
|
114
|
+
|
|
115
|
+
if (codeA == 92 || codeA == 34 || codeA < 32) {
|
|
116
|
+
const escaped = load<u32>(SERIALIZE_ESCAPE_TABLE + (codeA << 2));
|
|
117
|
+
|
|
118
|
+
if ((escaped & 0xffff) != BACK_SLASH) {
|
|
119
|
+
bs.ensureSize(10);
|
|
120
|
+
store<u64>(bs.offset, 13511005048209500);
|
|
121
|
+
store<u32>(bs.offset, escaped, 8);
|
|
122
|
+
bs.offset += 12;
|
|
123
|
+
} else {
|
|
124
|
+
bs.ensureSize(2);
|
|
125
|
+
store<u32>(bs.offset, escaped);
|
|
126
|
+
bs.offset += 4;
|
|
127
|
+
}
|
|
128
|
+
} else {
|
|
129
|
+
store<u16>(bs.offset, codeA);
|
|
130
|
+
bs.offset += 2;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (codeB == 92 || codeB == 34 || codeB < 32) {
|
|
134
|
+
const escaped = load<u32>(SERIALIZE_ESCAPE_TABLE + (codeB << 2));
|
|
135
|
+
|
|
136
|
+
if ((escaped & 0xffff) != BACK_SLASH) {
|
|
137
|
+
bs.ensureSize(10);
|
|
138
|
+
store<u64>(bs.offset, 13511005048209500);
|
|
139
|
+
store<u32>(bs.offset, escaped, 8);
|
|
140
|
+
bs.offset += 12;
|
|
141
|
+
} else {
|
|
142
|
+
bs.ensureSize(2);
|
|
143
|
+
store<u32>(bs.offset, escaped);
|
|
144
|
+
bs.offset += 4;
|
|
145
|
+
}
|
|
146
|
+
} else {
|
|
147
|
+
store<u16>(bs.offset, codeB);
|
|
148
|
+
bs.offset += 2;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
srcStart += 4;
|
|
152
|
+
}
|
|
153
|
+
if (rem & 2) {
|
|
154
|
+
const code = load<u16>(srcStart);
|
|
155
|
+
if (code == 92 || code == 34 || code < 32) {
|
|
156
|
+
const escaped = load<u32>(SERIALIZE_ESCAPE_TABLE + (code << 2));
|
|
157
|
+
|
|
158
|
+
if ((escaped & 0xffff) != BACK_SLASH) {
|
|
159
|
+
bs.ensureSize(10);
|
|
160
|
+
store<u64>(bs.offset, 13511005048209500);
|
|
161
|
+
store<u32>(bs.offset, escaped, 8);
|
|
162
|
+
bs.offset += 12;
|
|
163
|
+
} else {
|
|
164
|
+
bs.ensureSize(2);
|
|
165
|
+
store<u32>(bs.offset, escaped);
|
|
166
|
+
bs.offset += 4;
|
|
167
|
+
}
|
|
168
|
+
} else {
|
|
169
|
+
store<u16>(bs.offset, code);
|
|
170
|
+
bs.offset += 2;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
store<u8>(bs.offset, 34); /* " */
|
|
175
|
+
bs.offset += 2;
|
|
176
|
+
}
|