json-as 1.2.6 → 1.3.0

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