porffor 0.1.0 → 0.2.0-3fad637

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 (659) hide show
  1. package/README.md +192 -204
  2. package/compiler/2c.js +385 -0
  3. package/compiler/builtins/base64.js +91 -91
  4. package/compiler/builtins.js +19 -13
  5. package/compiler/codeGen.js +1324 -418
  6. package/compiler/decompile.js +41 -16
  7. package/compiler/embedding.js +9 -5
  8. package/compiler/encoding.js +6 -114
  9. package/compiler/index.js +56 -17
  10. package/compiler/log.js +15 -0
  11. package/compiler/opt.js +357 -258
  12. package/compiler/parse.js +50 -3
  13. package/compiler/prototype.js +263 -56
  14. package/compiler/sections.js +51 -8
  15. package/compiler/wasmSpec.js +3 -0
  16. package/compiler/wrap.js +23 -9
  17. package/package.json +6 -1
  18. package/porf.cmd +1 -1
  19. package/rhemyn/README.md +37 -0
  20. package/rhemyn/compile.js +214 -0
  21. package/rhemyn/parse.js +321 -0
  22. package/rhemyn/test/parse.js +59 -0
  23. package/runner/index.js +54 -31
  24. package/runner/info.js +37 -2
  25. package/runner/profile.js +1 -2
  26. package/runner/repl.js +13 -11
  27. package/runner/results.json +1 -0
  28. package/runner/transform.js +15 -36
  29. package/runner/version.js +10 -0
  30. package/tmp.c +71 -0
  31. package/CNAME +0 -1
  32. package/index.html +0 -1264
  33. package/logo.png +0 -0
  34. package/sw.js +0 -26
  35. package/test/array_1.js +0 -8
  36. package/test/array_push.js +0 -8
  37. package/test/assignop_1.js +0 -15
  38. package/test/bitwise_1.js +0 -6
  39. package/test/bool_1.js +0 -3
  40. package/test/boolean.js +0 -6
  41. package/test/break_1.js +0 -6
  42. package/test/break_2.js +0 -12
  43. package/test/conditional_1.js +0 -3
  44. package/test/conditional_2.js +0 -4
  45. package/test/console_1.js +0 -2
  46. package/test/continue_1.js +0 -6
  47. package/test/continue_2.js +0 -10
  48. package/test/empty.js +0 -1
  49. package/test/ending_exp_1.js +0 -2
  50. package/test/ending_exp_2.js +0 -6
  51. package/test/eq_1.js +0 -4
  52. package/test/eq_2.js +0 -4
  53. package/test/eq_3.js +0 -5
  54. package/test/export_1.js +0 -9
  55. package/test/factorial.js +0 -3
  56. package/test/fibonacci.js +0 -16
  57. package/test/float_div0.js +0 -2
  58. package/test/float_frac.js +0 -2
  59. package/test/float_isfinite.js +0 -29
  60. package/test/float_isinteger.js +0 -13
  61. package/test/float_isnan.js +0 -20
  62. package/test/float_issafeinteger.js +0 -11
  63. package/test/float_large.js +0 -2
  64. package/test/float_math_funcs.js +0 -24
  65. package/test/float_math_random.js +0 -6
  66. package/test/float_nan.js +0 -3
  67. package/test/float_number_values.js +0 -12
  68. package/test/for_1.js +0 -4
  69. package/test/for_2.js +0 -4
  70. package/test/func_1.js +0 -16
  71. package/test/func_2.js +0 -6
  72. package/test/func_3.js +0 -10
  73. package/test/global_1.js +0 -8
  74. package/test/global_2.js +0 -10
  75. package/test/if_1.js +0 -6
  76. package/test/if_2.js +0 -9
  77. package/test/if_3.js +0 -7
  78. package/test/iife_1.js +0 -8
  79. package/test/iife_2.js +0 -8
  80. package/test/index.js +0 -93
  81. package/test/int_number_values.js +0 -6
  82. package/test/logic_1.js +0 -7
  83. package/test/logic_2.js +0 -7
  84. package/test/math_1.js +0 -6
  85. package/test/math_2.js +0 -12
  86. package/test/math_3.js +0 -6
  87. package/test/number_func.js +0 -4
  88. package/test/return_1.js +0 -8
  89. package/test/return_2.js +0 -11
  90. package/test/tailcall_1.js +0 -10
  91. package/test/throw_1.js +0 -2
  92. package/test/throw_2.js +0 -4
  93. package/test/throw_3.js +0 -2
  94. package/test/throw_4.js +0 -3
  95. package/test/try_1.js +0 -7
  96. package/test/unary_1.js +0 -4
  97. package/test/unary_2.js +0 -5
  98. package/test/unary_3.js +0 -6
  99. package/test/unary_4.js +0 -12
  100. package/test/unary_5.js +0 -8
  101. package/test/undefined_1.js +0 -8
  102. package/test/undefined_2.js +0 -10
  103. package/test/updateexp_1.js +0 -9
  104. package/test/vars_1.js +0 -5
  105. package/test/vars_2.js +0 -9
  106. package/test/while_1.js +0 -6
  107. package/test262/compare.js +0 -30
  108. package/test262/index.js +0 -314
  109. package/test262/node_modules/.bin/esparse +0 -12
  110. package/test262/node_modules/.bin/esparse.cmd +0 -17
  111. package/test262/node_modules/.bin/esparse.ps1 +0 -28
  112. package/test262/node_modules/.bin/esvalidate +0 -12
  113. package/test262/node_modules/.bin/esvalidate.cmd +0 -17
  114. package/test262/node_modules/.bin/esvalidate.ps1 +0 -28
  115. package/test262/node_modules/.bin/js-yaml +0 -12
  116. package/test262/node_modules/.bin/js-yaml.cmd +0 -17
  117. package/test262/node_modules/.bin/js-yaml.ps1 +0 -28
  118. package/test262/node_modules/.package-lock.json +0 -0
  119. package/test262/node_modules/@nodelib/fs.scandir/LICENSE +0 -21
  120. package/test262/node_modules/@nodelib/fs.scandir/README.md +0 -171
  121. package/test262/node_modules/@nodelib/fs.scandir/out/adapters/fs.d.ts +0 -20
  122. package/test262/node_modules/@nodelib/fs.scandir/out/adapters/fs.js +0 -19
  123. package/test262/node_modules/@nodelib/fs.scandir/out/constants.d.ts +0 -4
  124. package/test262/node_modules/@nodelib/fs.scandir/out/constants.js +0 -17
  125. package/test262/node_modules/@nodelib/fs.scandir/out/index.d.ts +0 -12
  126. package/test262/node_modules/@nodelib/fs.scandir/out/index.js +0 -26
  127. package/test262/node_modules/@nodelib/fs.scandir/out/providers/async.d.ts +0 -7
  128. package/test262/node_modules/@nodelib/fs.scandir/out/providers/async.js +0 -104
  129. package/test262/node_modules/@nodelib/fs.scandir/out/providers/common.d.ts +0 -1
  130. package/test262/node_modules/@nodelib/fs.scandir/out/providers/common.js +0 -13
  131. package/test262/node_modules/@nodelib/fs.scandir/out/providers/sync.d.ts +0 -5
  132. package/test262/node_modules/@nodelib/fs.scandir/out/providers/sync.js +0 -54
  133. package/test262/node_modules/@nodelib/fs.scandir/out/settings.d.ts +0 -20
  134. package/test262/node_modules/@nodelib/fs.scandir/out/settings.js +0 -24
  135. package/test262/node_modules/@nodelib/fs.scandir/out/types/index.d.ts +0 -20
  136. package/test262/node_modules/@nodelib/fs.scandir/out/types/index.js +0 -2
  137. package/test262/node_modules/@nodelib/fs.scandir/out/utils/fs.d.ts +0 -2
  138. package/test262/node_modules/@nodelib/fs.scandir/out/utils/fs.js +0 -19
  139. package/test262/node_modules/@nodelib/fs.scandir/out/utils/index.d.ts +0 -2
  140. package/test262/node_modules/@nodelib/fs.scandir/out/utils/index.js +0 -5
  141. package/test262/node_modules/@nodelib/fs.scandir/package.json +0 -44
  142. package/test262/node_modules/@nodelib/fs.stat/LICENSE +0 -21
  143. package/test262/node_modules/@nodelib/fs.stat/README.md +0 -126
  144. package/test262/node_modules/@nodelib/fs.stat/out/adapters/fs.d.ts +0 -13
  145. package/test262/node_modules/@nodelib/fs.stat/out/adapters/fs.js +0 -17
  146. package/test262/node_modules/@nodelib/fs.stat/out/index.d.ts +0 -12
  147. package/test262/node_modules/@nodelib/fs.stat/out/index.js +0 -26
  148. package/test262/node_modules/@nodelib/fs.stat/out/providers/async.d.ts +0 -4
  149. package/test262/node_modules/@nodelib/fs.stat/out/providers/async.js +0 -36
  150. package/test262/node_modules/@nodelib/fs.stat/out/providers/sync.d.ts +0 -3
  151. package/test262/node_modules/@nodelib/fs.stat/out/providers/sync.js +0 -23
  152. package/test262/node_modules/@nodelib/fs.stat/out/settings.d.ts +0 -16
  153. package/test262/node_modules/@nodelib/fs.stat/out/settings.js +0 -16
  154. package/test262/node_modules/@nodelib/fs.stat/out/types/index.d.ts +0 -4
  155. package/test262/node_modules/@nodelib/fs.stat/out/types/index.js +0 -2
  156. package/test262/node_modules/@nodelib/fs.stat/package.json +0 -37
  157. package/test262/node_modules/@nodelib/fs.walk/LICENSE +0 -21
  158. package/test262/node_modules/@nodelib/fs.walk/README.md +0 -215
  159. package/test262/node_modules/@nodelib/fs.walk/out/index.d.ts +0 -14
  160. package/test262/node_modules/@nodelib/fs.walk/out/index.js +0 -34
  161. package/test262/node_modules/@nodelib/fs.walk/out/providers/async.d.ts +0 -12
  162. package/test262/node_modules/@nodelib/fs.walk/out/providers/async.js +0 -30
  163. package/test262/node_modules/@nodelib/fs.walk/out/providers/index.d.ts +0 -4
  164. package/test262/node_modules/@nodelib/fs.walk/out/providers/index.js +0 -9
  165. package/test262/node_modules/@nodelib/fs.walk/out/providers/stream.d.ts +0 -12
  166. package/test262/node_modules/@nodelib/fs.walk/out/providers/stream.js +0 -34
  167. package/test262/node_modules/@nodelib/fs.walk/out/providers/sync.d.ts +0 -10
  168. package/test262/node_modules/@nodelib/fs.walk/out/providers/sync.js +0 -14
  169. package/test262/node_modules/@nodelib/fs.walk/out/readers/async.d.ts +0 -30
  170. package/test262/node_modules/@nodelib/fs.walk/out/readers/async.js +0 -97
  171. package/test262/node_modules/@nodelib/fs.walk/out/readers/common.d.ts +0 -7
  172. package/test262/node_modules/@nodelib/fs.walk/out/readers/common.js +0 -31
  173. package/test262/node_modules/@nodelib/fs.walk/out/readers/reader.d.ts +0 -6
  174. package/test262/node_modules/@nodelib/fs.walk/out/readers/reader.js +0 -11
  175. package/test262/node_modules/@nodelib/fs.walk/out/readers/sync.d.ts +0 -15
  176. package/test262/node_modules/@nodelib/fs.walk/out/readers/sync.js +0 -59
  177. package/test262/node_modules/@nodelib/fs.walk/out/settings.d.ts +0 -30
  178. package/test262/node_modules/@nodelib/fs.walk/out/settings.js +0 -26
  179. package/test262/node_modules/@nodelib/fs.walk/out/types/index.d.ts +0 -8
  180. package/test262/node_modules/@nodelib/fs.walk/out/types/index.js +0 -2
  181. package/test262/node_modules/@nodelib/fs.walk/package.json +0 -44
  182. package/test262/node_modules/argparse/CHANGELOG.md +0 -185
  183. package/test262/node_modules/argparse/LICENSE +0 -21
  184. package/test262/node_modules/argparse/README.md +0 -257
  185. package/test262/node_modules/argparse/index.js +0 -3
  186. package/test262/node_modules/argparse/lib/action/append/constant.js +0 -47
  187. package/test262/node_modules/argparse/lib/action/append.js +0 -53
  188. package/test262/node_modules/argparse/lib/action/count.js +0 -40
  189. package/test262/node_modules/argparse/lib/action/help.js +0 -47
  190. package/test262/node_modules/argparse/lib/action/store/constant.js +0 -43
  191. package/test262/node_modules/argparse/lib/action/store/false.js +0 -27
  192. package/test262/node_modules/argparse/lib/action/store/true.js +0 -26
  193. package/test262/node_modules/argparse/lib/action/store.js +0 -50
  194. package/test262/node_modules/argparse/lib/action/subparsers.js +0 -149
  195. package/test262/node_modules/argparse/lib/action/version.js +0 -47
  196. package/test262/node_modules/argparse/lib/action.js +0 -146
  197. package/test262/node_modules/argparse/lib/action_container.js +0 -482
  198. package/test262/node_modules/argparse/lib/argparse.js +0 -14
  199. package/test262/node_modules/argparse/lib/argument/error.js +0 -50
  200. package/test262/node_modules/argparse/lib/argument/exclusive.js +0 -54
  201. package/test262/node_modules/argparse/lib/argument/group.js +0 -75
  202. package/test262/node_modules/argparse/lib/argument_parser.js +0 -1161
  203. package/test262/node_modules/argparse/lib/const.js +0 -21
  204. package/test262/node_modules/argparse/lib/help/added_formatters.js +0 -87
  205. package/test262/node_modules/argparse/lib/help/formatter.js +0 -795
  206. package/test262/node_modules/argparse/lib/namespace.js +0 -76
  207. package/test262/node_modules/argparse/lib/utils.js +0 -57
  208. package/test262/node_modules/argparse/package.json +0 -34
  209. package/test262/node_modules/braces/CHANGELOG.md +0 -184
  210. package/test262/node_modules/braces/LICENSE +0 -21
  211. package/test262/node_modules/braces/README.md +0 -593
  212. package/test262/node_modules/braces/index.js +0 -170
  213. package/test262/node_modules/braces/lib/compile.js +0 -57
  214. package/test262/node_modules/braces/lib/constants.js +0 -57
  215. package/test262/node_modules/braces/lib/expand.js +0 -113
  216. package/test262/node_modules/braces/lib/parse.js +0 -333
  217. package/test262/node_modules/braces/lib/stringify.js +0 -32
  218. package/test262/node_modules/braces/lib/utils.js +0 -112
  219. package/test262/node_modules/braces/package.json +0 -77
  220. package/test262/node_modules/esprima/ChangeLog +0 -235
  221. package/test262/node_modules/esprima/LICENSE.BSD +0 -21
  222. package/test262/node_modules/esprima/README.md +0 -46
  223. package/test262/node_modules/esprima/bin/esparse.js +0 -139
  224. package/test262/node_modules/esprima/bin/esvalidate.js +0 -236
  225. package/test262/node_modules/esprima/dist/esprima.js +0 -6709
  226. package/test262/node_modules/esprima/package.json +0 -112
  227. package/test262/node_modules/fast-glob/LICENSE +0 -21
  228. package/test262/node_modules/fast-glob/README.md +0 -859
  229. package/test262/node_modules/fast-glob/out/index.d.ts +0 -40
  230. package/test262/node_modules/fast-glob/out/index.js +0 -102
  231. package/test262/node_modules/fast-glob/out/managers/tasks.d.ts +0 -22
  232. package/test262/node_modules/fast-glob/out/managers/tasks.js +0 -110
  233. package/test262/node_modules/fast-glob/out/providers/async.d.ts +0 -9
  234. package/test262/node_modules/fast-glob/out/providers/async.js +0 -23
  235. package/test262/node_modules/fast-glob/out/providers/filters/deep.d.ts +0 -16
  236. package/test262/node_modules/fast-glob/out/providers/filters/deep.js +0 -62
  237. package/test262/node_modules/fast-glob/out/providers/filters/entry.d.ts +0 -16
  238. package/test262/node_modules/fast-glob/out/providers/filters/entry.js +0 -63
  239. package/test262/node_modules/fast-glob/out/providers/filters/error.d.ts +0 -8
  240. package/test262/node_modules/fast-glob/out/providers/filters/error.js +0 -15
  241. package/test262/node_modules/fast-glob/out/providers/matchers/matcher.d.ts +0 -33
  242. package/test262/node_modules/fast-glob/out/providers/matchers/matcher.js +0 -45
  243. package/test262/node_modules/fast-glob/out/providers/matchers/partial.d.ts +0 -4
  244. package/test262/node_modules/fast-glob/out/providers/matchers/partial.js +0 -38
  245. package/test262/node_modules/fast-glob/out/providers/provider.d.ts +0 -19
  246. package/test262/node_modules/fast-glob/out/providers/provider.js +0 -48
  247. package/test262/node_modules/fast-glob/out/providers/stream.d.ts +0 -11
  248. package/test262/node_modules/fast-glob/out/providers/stream.js +0 -31
  249. package/test262/node_modules/fast-glob/out/providers/sync.d.ts +0 -9
  250. package/test262/node_modules/fast-glob/out/providers/sync.js +0 -23
  251. package/test262/node_modules/fast-glob/out/providers/transformers/entry.d.ts +0 -8
  252. package/test262/node_modules/fast-glob/out/providers/transformers/entry.js +0 -26
  253. package/test262/node_modules/fast-glob/out/readers/async.d.ts +0 -10
  254. package/test262/node_modules/fast-glob/out/readers/async.js +0 -35
  255. package/test262/node_modules/fast-glob/out/readers/reader.d.ts +0 -15
  256. package/test262/node_modules/fast-glob/out/readers/reader.js +0 -33
  257. package/test262/node_modules/fast-glob/out/readers/stream.d.ts +0 -14
  258. package/test262/node_modules/fast-glob/out/readers/stream.js +0 -55
  259. package/test262/node_modules/fast-glob/out/readers/sync.d.ts +0 -12
  260. package/test262/node_modules/fast-glob/out/readers/sync.js +0 -43
  261. package/test262/node_modules/fast-glob/out/settings.d.ts +0 -164
  262. package/test262/node_modules/fast-glob/out/settings.js +0 -57
  263. package/test262/node_modules/fast-glob/out/types/index.d.ts +0 -31
  264. package/test262/node_modules/fast-glob/out/types/index.js +0 -2
  265. package/test262/node_modules/fast-glob/out/utils/array.d.ts +0 -2
  266. package/test262/node_modules/fast-glob/out/utils/array.js +0 -22
  267. package/test262/node_modules/fast-glob/out/utils/errno.d.ts +0 -2
  268. package/test262/node_modules/fast-glob/out/utils/errno.js +0 -7
  269. package/test262/node_modules/fast-glob/out/utils/fs.d.ts +0 -4
  270. package/test262/node_modules/fast-glob/out/utils/fs.js +0 -19
  271. package/test262/node_modules/fast-glob/out/utils/index.d.ts +0 -8
  272. package/test262/node_modules/fast-glob/out/utils/index.js +0 -17
  273. package/test262/node_modules/fast-glob/out/utils/path.d.ts +0 -13
  274. package/test262/node_modules/fast-glob/out/utils/path.js +0 -68
  275. package/test262/node_modules/fast-glob/out/utils/pattern.d.ts +0 -47
  276. package/test262/node_modules/fast-glob/out/utils/pattern.js +0 -188
  277. package/test262/node_modules/fast-glob/out/utils/stream.d.ts +0 -4
  278. package/test262/node_modules/fast-glob/out/utils/stream.js +0 -17
  279. package/test262/node_modules/fast-glob/out/utils/string.d.ts +0 -2
  280. package/test262/node_modules/fast-glob/out/utils/string.js +0 -11
  281. package/test262/node_modules/fast-glob/package.json +0 -81
  282. package/test262/node_modules/fastq/.github/dependabot.yml +0 -11
  283. package/test262/node_modules/fastq/.github/workflows/ci.yml +0 -50
  284. package/test262/node_modules/fastq/LICENSE +0 -13
  285. package/test262/node_modules/fastq/README.md +0 -309
  286. package/test262/node_modules/fastq/bench.js +0 -66
  287. package/test262/node_modules/fastq/example.js +0 -14
  288. package/test262/node_modules/fastq/example.mjs +0 -11
  289. package/test262/node_modules/fastq/index.d.ts +0 -37
  290. package/test262/node_modules/fastq/package.json +0 -52
  291. package/test262/node_modules/fastq/queue.js +0 -289
  292. package/test262/node_modules/fastq/test/example.ts +0 -81
  293. package/test262/node_modules/fastq/test/promise.js +0 -248
  294. package/test262/node_modules/fastq/test/test.js +0 -566
  295. package/test262/node_modules/fastq/test/tsconfig.json +0 -11
  296. package/test262/node_modules/fill-range/LICENSE +0 -21
  297. package/test262/node_modules/fill-range/README.md +0 -237
  298. package/test262/node_modules/fill-range/index.js +0 -249
  299. package/test262/node_modules/fill-range/package.json +0 -69
  300. package/test262/node_modules/glob-parent/CHANGELOG.md +0 -110
  301. package/test262/node_modules/glob-parent/LICENSE +0 -15
  302. package/test262/node_modules/glob-parent/README.md +0 -137
  303. package/test262/node_modules/glob-parent/index.js +0 -42
  304. package/test262/node_modules/glob-parent/package.json +0 -48
  305. package/test262/node_modules/graceful-fs/LICENSE +0 -15
  306. package/test262/node_modules/graceful-fs/README.md +0 -143
  307. package/test262/node_modules/graceful-fs/clone.js +0 -23
  308. package/test262/node_modules/graceful-fs/graceful-fs.js +0 -448
  309. package/test262/node_modules/graceful-fs/legacy-streams.js +0 -118
  310. package/test262/node_modules/graceful-fs/package.json +0 -53
  311. package/test262/node_modules/graceful-fs/polyfills.js +0 -355
  312. package/test262/node_modules/is-extglob/LICENSE +0 -21
  313. package/test262/node_modules/is-extglob/README.md +0 -107
  314. package/test262/node_modules/is-extglob/index.js +0 -20
  315. package/test262/node_modules/is-extglob/package.json +0 -69
  316. package/test262/node_modules/is-glob/LICENSE +0 -21
  317. package/test262/node_modules/is-glob/README.md +0 -206
  318. package/test262/node_modules/is-glob/index.js +0 -150
  319. package/test262/node_modules/is-glob/package.json +0 -81
  320. package/test262/node_modules/is-number/LICENSE +0 -21
  321. package/test262/node_modules/is-number/README.md +0 -187
  322. package/test262/node_modules/is-number/index.js +0 -18
  323. package/test262/node_modules/is-number/package.json +0 -82
  324. package/test262/node_modules/js-yaml/CHANGELOG.md +0 -557
  325. package/test262/node_modules/js-yaml/LICENSE +0 -21
  326. package/test262/node_modules/js-yaml/README.md +0 -299
  327. package/test262/node_modules/js-yaml/bin/js-yaml.js +0 -132
  328. package/test262/node_modules/js-yaml/dist/js-yaml.js +0 -3989
  329. package/test262/node_modules/js-yaml/dist/js-yaml.min.js +0 -1
  330. package/test262/node_modules/js-yaml/index.js +0 -7
  331. package/test262/node_modules/js-yaml/lib/js-yaml/common.js +0 -59
  332. package/test262/node_modules/js-yaml/lib/js-yaml/dumper.js +0 -850
  333. package/test262/node_modules/js-yaml/lib/js-yaml/exception.js +0 -43
  334. package/test262/node_modules/js-yaml/lib/js-yaml/loader.js +0 -1644
  335. package/test262/node_modules/js-yaml/lib/js-yaml/mark.js +0 -76
  336. package/test262/node_modules/js-yaml/lib/js-yaml/schema/core.js +0 -18
  337. package/test262/node_modules/js-yaml/lib/js-yaml/schema/default_full.js +0 -25
  338. package/test262/node_modules/js-yaml/lib/js-yaml/schema/default_safe.js +0 -28
  339. package/test262/node_modules/js-yaml/lib/js-yaml/schema/failsafe.js +0 -17
  340. package/test262/node_modules/js-yaml/lib/js-yaml/schema/json.js +0 -25
  341. package/test262/node_modules/js-yaml/lib/js-yaml/schema.js +0 -108
  342. package/test262/node_modules/js-yaml/lib/js-yaml/type/binary.js +0 -138
  343. package/test262/node_modules/js-yaml/lib/js-yaml/type/bool.js +0 -35
  344. package/test262/node_modules/js-yaml/lib/js-yaml/type/float.js +0 -116
  345. package/test262/node_modules/js-yaml/lib/js-yaml/type/int.js +0 -173
  346. package/test262/node_modules/js-yaml/lib/js-yaml/type/js/function.js +0 -93
  347. package/test262/node_modules/js-yaml/lib/js-yaml/type/js/regexp.js +0 -60
  348. package/test262/node_modules/js-yaml/lib/js-yaml/type/js/undefined.js +0 -28
  349. package/test262/node_modules/js-yaml/lib/js-yaml/type/map.js +0 -8
  350. package/test262/node_modules/js-yaml/lib/js-yaml/type/merge.js +0 -12
  351. package/test262/node_modules/js-yaml/lib/js-yaml/type/null.js +0 -34
  352. package/test262/node_modules/js-yaml/lib/js-yaml/type/omap.js +0 -44
  353. package/test262/node_modules/js-yaml/lib/js-yaml/type/pairs.js +0 -53
  354. package/test262/node_modules/js-yaml/lib/js-yaml/type/seq.js +0 -8
  355. package/test262/node_modules/js-yaml/lib/js-yaml/type/set.js +0 -29
  356. package/test262/node_modules/js-yaml/lib/js-yaml/type/str.js +0 -8
  357. package/test262/node_modules/js-yaml/lib/js-yaml/type/timestamp.js +0 -88
  358. package/test262/node_modules/js-yaml/lib/js-yaml/type.js +0 -61
  359. package/test262/node_modules/js-yaml/lib/js-yaml.js +0 -39
  360. package/test262/node_modules/js-yaml/package.json +0 -49
  361. package/test262/node_modules/klaw/CHANGELOG.md +0 -62
  362. package/test262/node_modules/klaw/LICENSE +0 -15
  363. package/test262/node_modules/klaw/README.md +0 -252
  364. package/test262/node_modules/klaw/package.json +0 -40
  365. package/test262/node_modules/klaw/src/index.js +0 -56
  366. package/test262/node_modules/merge2/LICENSE +0 -21
  367. package/test262/node_modules/merge2/README.md +0 -144
  368. package/test262/node_modules/merge2/index.js +0 -144
  369. package/test262/node_modules/merge2/package.json +0 -43
  370. package/test262/node_modules/micromatch/LICENSE +0 -21
  371. package/test262/node_modules/micromatch/README.md +0 -1011
  372. package/test262/node_modules/micromatch/index.js +0 -467
  373. package/test262/node_modules/micromatch/package.json +0 -119
  374. package/test262/node_modules/picomatch/CHANGELOG.md +0 -136
  375. package/test262/node_modules/picomatch/LICENSE +0 -21
  376. package/test262/node_modules/picomatch/README.md +0 -708
  377. package/test262/node_modules/picomatch/index.js +0 -3
  378. package/test262/node_modules/picomatch/lib/constants.js +0 -179
  379. package/test262/node_modules/picomatch/lib/parse.js +0 -1091
  380. package/test262/node_modules/picomatch/lib/picomatch.js +0 -342
  381. package/test262/node_modules/picomatch/lib/scan.js +0 -391
  382. package/test262/node_modules/picomatch/lib/utils.js +0 -64
  383. package/test262/node_modules/picomatch/package.json +0 -81
  384. package/test262/node_modules/queue-microtask/LICENSE +0 -20
  385. package/test262/node_modules/queue-microtask/README.md +0 -90
  386. package/test262/node_modules/queue-microtask/index.d.ts +0 -2
  387. package/test262/node_modules/queue-microtask/index.js +0 -9
  388. package/test262/node_modules/queue-microtask/package.json +0 -55
  389. package/test262/node_modules/reusify/.coveralls.yml +0 -1
  390. package/test262/node_modules/reusify/.travis.yml +0 -28
  391. package/test262/node_modules/reusify/LICENSE +0 -22
  392. package/test262/node_modules/reusify/README.md +0 -145
  393. package/test262/node_modules/reusify/benchmarks/createNoCodeFunction.js +0 -30
  394. package/test262/node_modules/reusify/benchmarks/fib.js +0 -13
  395. package/test262/node_modules/reusify/benchmarks/reuseNoCodeFunction.js +0 -38
  396. package/test262/node_modules/reusify/package.json +0 -45
  397. package/test262/node_modules/reusify/reusify.js +0 -33
  398. package/test262/node_modules/reusify/test.js +0 -66
  399. package/test262/node_modules/run-parallel/LICENSE +0 -20
  400. package/test262/node_modules/run-parallel/README.md +0 -85
  401. package/test262/node_modules/run-parallel/index.js +0 -51
  402. package/test262/node_modules/run-parallel/package.json +0 -58
  403. package/test262/node_modules/sprintf-js/LICENSE +0 -24
  404. package/test262/node_modules/sprintf-js/README.md +0 -88
  405. package/test262/node_modules/sprintf-js/bower.json +0 -14
  406. package/test262/node_modules/sprintf-js/demo/angular.html +0 -20
  407. package/test262/node_modules/sprintf-js/dist/angular-sprintf.min.js +0 -4
  408. package/test262/node_modules/sprintf-js/dist/angular-sprintf.min.js.map +0 -1
  409. package/test262/node_modules/sprintf-js/dist/angular-sprintf.min.map +0 -1
  410. package/test262/node_modules/sprintf-js/dist/sprintf.min.js +0 -4
  411. package/test262/node_modules/sprintf-js/dist/sprintf.min.js.map +0 -1
  412. package/test262/node_modules/sprintf-js/dist/sprintf.min.map +0 -1
  413. package/test262/node_modules/sprintf-js/gruntfile.js +0 -36
  414. package/test262/node_modules/sprintf-js/package.json +0 -22
  415. package/test262/node_modules/sprintf-js/src/angular-sprintf.js +0 -18
  416. package/test262/node_modules/sprintf-js/src/sprintf.js +0 -208
  417. package/test262/node_modules/sprintf-js/test/test.js +0 -82
  418. package/test262/node_modules/test262-stream/.jshintignore +0 -2
  419. package/test262/node_modules/test262-stream/.jshintrc +0 -6
  420. package/test262/node_modules/test262-stream/.travis.yml +0 -5
  421. package/test262/node_modules/test262-stream/CONTRIBUTING.md +0 -37
  422. package/test262/node_modules/test262-stream/LICENSE-MICROSOFT.txt +0 -27
  423. package/test262/node_modules/test262-stream/LICENSE.txt +0 -27
  424. package/test262/node_modules/test262-stream/README.md +0 -71
  425. package/test262/node_modules/test262-stream/lib/builder.js +0 -46
  426. package/test262/node_modules/test262-stream/lib/compile.js +0 -24
  427. package/test262/node_modules/test262-stream/lib/create-scenarios.js +0 -29
  428. package/test262/node_modules/test262-stream/lib/index.js +0 -187
  429. package/test262/node_modules/test262-stream/lib/test-file.js +0 -150
  430. package/test262/node_modules/test262-stream/package.json +0 -26
  431. package/test262/node_modules/test262-stream/test/collateral/invalid-missing-harness/fake-test262/test/a-test-file.js +0 -16
  432. package/test262/node_modules/test262-stream/test/collateral/invalid-version-other-accepted/fake-test262/harness/assert.js +0 -17
  433. package/test262/node_modules/test262-stream/test/collateral/invalid-version-other-accepted/fake-test262/harness/doneprintHandle.js +0 -6
  434. package/test262/node_modules/test262-stream/test/collateral/invalid-version-other-accepted/fake-test262/harness/sta.js +0 -12
  435. package/test262/node_modules/test262-stream/test/collateral/invalid-version-other-accepted/fake-test262/package.json +0 -3
  436. package/test262/node_modules/test262-stream/test/collateral/invalid-version-other-accepted/fake-test262/test/strict.js +0 -9
  437. package/test262/node_modules/test262-stream/test/collateral/invalid-version-unsupported/fake-test262/harness/assert.js +0 -17
  438. package/test262/node_modules/test262-stream/test/collateral/invalid-version-unsupported/fake-test262/harness/doneprintHandle.js +0 -6
  439. package/test262/node_modules/test262-stream/test/collateral/invalid-version-unsupported/fake-test262/harness/sta.js +0 -12
  440. package/test262/node_modules/test262-stream/test/collateral/invalid-version-unsupported/fake-test262/package.json +0 -3
  441. package/test262/node_modules/test262-stream/test/collateral/invalid-version-unsupported/fake-test262/test/strict.js +0 -9
  442. package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-content/test/asyncNegative_default.js +0 -49
  443. package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-content/test/asyncNegative_strict_mode.js +0 -50
  444. package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-content/test/async_default.js +0 -48
  445. package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-content/test/async_strict_mode.js +0 -49
  446. package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-content/test/bothStrict_default.js +0 -46
  447. package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-content/test/bothStrict_strict_mode.js +0 -47
  448. package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-content/test/error_default.js +0 -39
  449. package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-content/test/error_strict_mode.js +0 -40
  450. package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-content/test/module_default.js +0 -37
  451. package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-content/test/module_strict_mode.js +0 -38
  452. package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-content/test/negative-empty_default.js +0 -37
  453. package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-content/test/negative-empty_strict_mode.js +0 -38
  454. package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-content/test/noStrict_default.js +0 -36
  455. package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-content/test/rawNoStrict_default.js +0 -14
  456. package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-content/test/rawStrict_default.js +0 -15
  457. package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-content/test/strict_strict_mode.js +0 -41
  458. package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-metadata/test/asyncNegative_default.json +0 -22
  459. package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-metadata/test/asyncNegative_strict_mode.json +0 -22
  460. package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-metadata/test/async_default.json +0 -18
  461. package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-metadata/test/async_strict_mode.json +0 -18
  462. package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-metadata/test/bothStrict_default.json +0 -24
  463. package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-metadata/test/bothStrict_strict_mode.json +0 -24
  464. package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-metadata/test/error_default.json +0 -19
  465. package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-metadata/test/error_strict_mode.json +0 -19
  466. package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-metadata/test/module_default.json +0 -17
  467. package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-metadata/test/module_strict_mode.json +0 -17
  468. package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-metadata/test/negative-empty_default.json +0 -19
  469. package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-metadata/test/negative-empty_strict_mode.json +0 -19
  470. package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-metadata/test/noStrict_default.json +0 -17
  471. package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-metadata/test/rawNoStrict_default.json +0 -14
  472. package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-metadata/test/rawStrict_default.json +0 -14
  473. package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-metadata/test/strict_strict_mode.json +0 -21
  474. package/test262/node_modules/test262-stream/test/collateral/valid-default/fake-test262/harness/assert.js +0 -17
  475. package/test262/node_modules/test262-stream/test/collateral/valid-default/fake-test262/harness/doneprintHandle.js +0 -6
  476. package/test262/node_modules/test262-stream/test/collateral/valid-default/fake-test262/harness/sta.js +0 -12
  477. package/test262/node_modules/test262-stream/test/collateral/valid-default/fake-test262/test/async.js +0 -10
  478. package/test262/node_modules/test262-stream/test/collateral/valid-default/fake-test262/test/asyncNegative.js +0 -11
  479. package/test262/node_modules/test262-stream/test/collateral/valid-default/fake-test262/test/bothStrict.js +0 -15
  480. package/test262/node_modules/test262-stream/test/collateral/valid-default/fake-test262/test/error.js +0 -8
  481. package/test262/node_modules/test262-stream/test/collateral/valid-default/fake-test262/test/module.js +0 -6
  482. package/test262/node_modules/test262-stream/test/collateral/valid-default/fake-test262/test/module_FIXTURE.js +0 -2
  483. package/test262/node_modules/test262-stream/test/collateral/valid-default/fake-test262/test/negative-empty.js +0 -6
  484. package/test262/node_modules/test262-stream/test/collateral/valid-default/fake-test262/test/noStrict.js +0 -5
  485. package/test262/node_modules/test262-stream/test/collateral/valid-default/fake-test262/test/rawNoStrict.js +0 -14
  486. package/test262/node_modules/test262-stream/test/collateral/valid-default/fake-test262/test/rawStrict.js +0 -15
  487. package/test262/node_modules/test262-stream/test/collateral/valid-default/fake-test262/test/strict.js +0 -9
  488. package/test262/node_modules/test262-stream/test/collateral/valid-extra-files/expected-content/test/bothStrict_default.js +0 -46
  489. package/test262/node_modules/test262-stream/test/collateral/valid-extra-files/expected-content/test/bothStrict_strict_mode.js +0 -47
  490. package/test262/node_modules/test262-stream/test/collateral/valid-extra-files/expected-metadata/test/bothStrict_default.json +0 -24
  491. package/test262/node_modules/test262-stream/test/collateral/valid-extra-files/expected-metadata/test/bothStrict_strict_mode.json +0 -24
  492. package/test262/node_modules/test262-stream/test/collateral/valid-extra-files/fake-test262/harness/assert.js +0 -17
  493. package/test262/node_modules/test262-stream/test/collateral/valid-extra-files/fake-test262/harness/doneprintHandle.js +0 -6
  494. package/test262/node_modules/test262-stream/test/collateral/valid-extra-files/fake-test262/harness/sta.js +0 -12
  495. package/test262/node_modules/test262-stream/test/collateral/valid-extra-files/fake-test262/test/bothStrict.js +0 -15
  496. package/test262/node_modules/test262-stream/test/collateral/valid-extra-files/fake-test262/test/zzz-0_FIXTURE.js +0 -2
  497. package/test262/node_modules/test262-stream/test/collateral/valid-extra-files/fake-test262/test/zzz-1_FIXTURE.js +0 -2
  498. package/test262/node_modules/test262-stream/test/collateral/valid-extra-files/fake-test262/test/zzz-2_FIXTURE.js +0 -2
  499. package/test262/node_modules/test262-stream/test/collateral/valid-extra-files/fake-test262/test/zzz-3_FIXTURE.js +0 -2
  500. package/test262/node_modules/test262-stream/test/collateral/valid-extra-files/fake-test262/test/zzz-4_FIXTURE.js +0 -2
  501. package/test262/node_modules/test262-stream/test/collateral/valid-extra-files/fake-test262/test/zzz-5_FIXTURE.js +0 -2
  502. package/test262/node_modules/test262-stream/test/collateral/valid-extra-files/fake-test262/test/zzz-6_FIXTURE.js +0 -2
  503. package/test262/node_modules/test262-stream/test/collateral/valid-extra-files/fake-test262/test/zzz-7_FIXTURE.js +0 -2
  504. package/test262/node_modules/test262-stream/test/collateral/valid-extra-files/fake-test262/test/zzz-8_FIXTURE.js +0 -2
  505. package/test262/node_modules/test262-stream/test/collateral/valid-extra-files/fake-test262/test/zzz-9_FIXTURE.txt +0 -2
  506. package/test262/node_modules/test262-stream/test/collateral/valid-insertionindex-with-copyright/expected-content/test/raw_default.js +0 -15
  507. package/test262/node_modules/test262-stream/test/collateral/valid-insertionindex-with-copyright/expected-content/test/runtime_default.js +0 -38
  508. package/test262/node_modules/test262-stream/test/collateral/valid-insertionindex-with-copyright/expected-content/test/runtime_strict_mode.js +0 -39
  509. package/test262/node_modules/test262-stream/test/collateral/valid-insertionindex-with-copyright/expected-metadata/test/raw_default.json +0 -14
  510. package/test262/node_modules/test262-stream/test/collateral/valid-insertionindex-with-copyright/expected-metadata/test/runtime_default.json +0 -15
  511. package/test262/node_modules/test262-stream/test/collateral/valid-insertionindex-with-copyright/expected-metadata/test/runtime_strict_mode.json +0 -15
  512. package/test262/node_modules/test262-stream/test/collateral/valid-insertionindex-with-copyright/fake-test262/harness/assert.js +0 -17
  513. package/test262/node_modules/test262-stream/test/collateral/valid-insertionindex-with-copyright/fake-test262/harness/sta.js +0 -12
  514. package/test262/node_modules/test262-stream/test/collateral/valid-insertionindex-with-copyright/fake-test262/test/raw.js +0 -15
  515. package/test262/node_modules/test262-stream/test/collateral/valid-insertionindex-with-copyright/fake-test262/test/runtime.js +0 -7
  516. package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-content/test/asyncNegative_default.js +0 -11
  517. package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-content/test/asyncNegative_strict_mode.js +0 -12
  518. package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-content/test/async_default.js +0 -10
  519. package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-content/test/async_strict_mode.js +0 -11
  520. package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-content/test/bothStrict_default.js +0 -15
  521. package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-content/test/bothStrict_strict_mode.js +0 -16
  522. package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-content/test/error_default.js +0 -8
  523. package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-content/test/error_strict_mode.js +0 -9
  524. package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-content/test/module_default.js +0 -6
  525. package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-content/test/module_strict_mode.js +0 -7
  526. package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-content/test/negative-empty_default.js +0 -6
  527. package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-content/test/negative-empty_strict_mode.js +0 -7
  528. package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-content/test/noStrict_default.js +0 -5
  529. package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-content/test/rawNoStrict_default.js +0 -14
  530. package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-content/test/rawStrict_default.js +0 -15
  531. package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-content/test/strict_strict_mode.js +0 -10
  532. package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-metadata/test/asyncNegative_default.json +0 -18
  533. package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-metadata/test/asyncNegative_strict_mode.json +0 -18
  534. package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-metadata/test/async_default.json +0 -14
  535. package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-metadata/test/async_strict_mode.json +0 -14
  536. package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-metadata/test/bothStrict_default.json +0 -21
  537. package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-metadata/test/bothStrict_strict_mode.json +0 -21
  538. package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-metadata/test/error_default.json +0 -16
  539. package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-metadata/test/error_strict_mode.json +0 -16
  540. package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-metadata/test/module_default.json +0 -14
  541. package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-metadata/test/module_strict_mode.json +0 -14
  542. package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-metadata/test/negative-empty_default.json +0 -16
  543. package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-metadata/test/negative-empty_strict_mode.json +0 -16
  544. package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-metadata/test/noStrict_default.json +0 -14
  545. package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-metadata/test/rawNoStrict_default.json +0 -14
  546. package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-metadata/test/rawStrict_default.json +0 -14
  547. package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-metadata/test/strict_strict_mode.json +0 -18
  548. package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/fake-test262/harness/assert.js +0 -17
  549. package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/fake-test262/harness/doneprintHandle.js +0 -6
  550. package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/fake-test262/harness/sta.js +0 -12
  551. package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/fake-test262/test/async.js +0 -10
  552. package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/fake-test262/test/asyncNegative.js +0 -11
  553. package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/fake-test262/test/bothStrict.js +0 -15
  554. package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/fake-test262/test/error.js +0 -8
  555. package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/fake-test262/test/module.js +0 -6
  556. package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/fake-test262/test/module_FIXTURE.js +0 -2
  557. package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/fake-test262/test/negative-empty.js +0 -6
  558. package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/fake-test262/test/noStrict.js +0 -5
  559. package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/fake-test262/test/rawNoStrict.js +0 -14
  560. package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/fake-test262/test/rawStrict.js +0 -15
  561. package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/fake-test262/test/strict.js +0 -9
  562. package/test262/node_modules/test262-stream/test/collateral/valid-version-ignored/expected-content/test/strict_strict_mode.js +0 -41
  563. package/test262/node_modules/test262-stream/test/collateral/valid-version-ignored/expected-metadata/test/strict_strict_mode.json +0 -21
  564. package/test262/node_modules/test262-stream/test/collateral/valid-version-ignored/fake-test262/harness/assert.js +0 -17
  565. package/test262/node_modules/test262-stream/test/collateral/valid-version-ignored/fake-test262/harness/doneprintHandle.js +0 -6
  566. package/test262/node_modules/test262-stream/test/collateral/valid-version-ignored/fake-test262/harness/sta.js +0 -12
  567. package/test262/node_modules/test262-stream/test/collateral/valid-version-ignored/fake-test262/package.json +0 -3
  568. package/test262/node_modules/test262-stream/test/collateral/valid-version-ignored/fake-test262/test/strict.js +0 -9
  569. package/test262/node_modules/test262-stream/test/collateral/valid-version-supported/expected-content/test/strict_strict_mode.js +0 -41
  570. package/test262/node_modules/test262-stream/test/collateral/valid-version-supported/expected-metadata/test/strict_strict_mode.json +0 -21
  571. package/test262/node_modules/test262-stream/test/collateral/valid-version-supported/fake-test262/harness/assert.js +0 -17
  572. package/test262/node_modules/test262-stream/test/collateral/valid-version-supported/fake-test262/harness/doneprintHandle.js +0 -6
  573. package/test262/node_modules/test262-stream/test/collateral/valid-version-supported/fake-test262/harness/sta.js +0 -12
  574. package/test262/node_modules/test262-stream/test/collateral/valid-version-supported/fake-test262/package.json +0 -3
  575. package/test262/node_modules/test262-stream/test/collateral/valid-version-supported/fake-test262/test/strict.js +0 -9
  576. package/test262/node_modules/test262-stream/test/collateral/valid-with-hashbang/expected-content/test/missing-raw-flag_default.js +0 -44
  577. package/test262/node_modules/test262-stream/test/collateral/valid-with-hashbang/expected-content/test/missing-raw-flag_strict_mode.js +0 -45
  578. package/test262/node_modules/test262-stream/test/collateral/valid-with-hashbang/expected-content/test/raw-with-ls-and-license-on-same-line_default.js +0 -20
  579. package/test262/node_modules/test262-stream/test/collateral/valid-with-hashbang/expected-content/test/raw-with-ls-multiline-block_default.js +0 -18
  580. package/test262/node_modules/test262-stream/test/collateral/valid-with-hashbang/expected-content/test/raw-with-ls_default.js +0 -17
  581. package/test262/node_modules/test262-stream/test/collateral/valid-with-hashbang/expected-content/test/raw-with-ps-and-license-on-same-line_default.js +0 -20
  582. package/test262/node_modules/test262-stream/test/collateral/valid-with-hashbang/expected-content/test/raw-with-ps-multiline-block_default.js +0 -18
  583. package/test262/node_modules/test262-stream/test/collateral/valid-with-hashbang/expected-content/test/raw-with-ps_default.js +0 -17
  584. package/test262/node_modules/test262-stream/test/collateral/valid-with-hashbang/expected-content/test/rawWithLicense_default.js +0 -21
  585. package/test262/node_modules/test262-stream/test/collateral/valid-with-hashbang/expected-content/test/raw_default.js +0 -17
  586. package/test262/node_modules/test262-stream/test/collateral/valid-with-hashbang/expected-metadata/test/missing-raw-flag_default.json +0 -22
  587. package/test262/node_modules/test262-stream/test/collateral/valid-with-hashbang/expected-metadata/test/missing-raw-flag_strict_mode.json +0 -22
  588. package/test262/node_modules/test262-stream/test/collateral/valid-with-hashbang/expected-metadata/test/raw-with-ls-and-license-on-same-line_default.json +0 -21
  589. package/test262/node_modules/test262-stream/test/collateral/valid-with-hashbang/expected-metadata/test/raw-with-ls-multiline-block_default.json +0 -21
  590. package/test262/node_modules/test262-stream/test/collateral/valid-with-hashbang/expected-metadata/test/raw-with-ls_default.json +0 -21
  591. package/test262/node_modules/test262-stream/test/collateral/valid-with-hashbang/expected-metadata/test/raw-with-ps-and-license-on-same-line_default.json +0 -21
  592. package/test262/node_modules/test262-stream/test/collateral/valid-with-hashbang/expected-metadata/test/raw-with-ps-multiline-block_default.json +0 -21
  593. package/test262/node_modules/test262-stream/test/collateral/valid-with-hashbang/expected-metadata/test/raw-with-ps_default.json +0 -21
  594. package/test262/node_modules/test262-stream/test/collateral/valid-with-hashbang/expected-metadata/test/rawWithLicense_default.json +0 -21
  595. package/test262/node_modules/test262-stream/test/collateral/valid-with-hashbang/expected-metadata/test/raw_default.json +0 -21
  596. package/test262/node_modules/test262-stream/test/collateral/valid-with-hashbang/fake-test262/harness/assert.js +0 -17
  597. package/test262/node_modules/test262-stream/test/collateral/valid-with-hashbang/fake-test262/harness/doneprintHandle.js +0 -6
  598. package/test262/node_modules/test262-stream/test/collateral/valid-with-hashbang/fake-test262/harness/sta.js +0 -12
  599. package/test262/node_modules/test262-stream/test/collateral/valid-with-hashbang/fake-test262/test/missing-raw-flag.js +0 -13
  600. package/test262/node_modules/test262-stream/test/collateral/valid-with-hashbang/fake-test262/test/raw-with-ls-and-license-on-same-line.js +0 -20
  601. package/test262/node_modules/test262-stream/test/collateral/valid-with-hashbang/fake-test262/test/raw-with-ls-multiline-block.js +0 -18
  602. package/test262/node_modules/test262-stream/test/collateral/valid-with-hashbang/fake-test262/test/raw-with-ls.js +0 -17
  603. package/test262/node_modules/test262-stream/test/collateral/valid-with-hashbang/fake-test262/test/raw-with-ps-and-license-on-same-line.js +0 -20
  604. package/test262/node_modules/test262-stream/test/collateral/valid-with-hashbang/fake-test262/test/raw-with-ps-multiline-block.js +0 -18
  605. package/test262/node_modules/test262-stream/test/collateral/valid-with-hashbang/fake-test262/test/raw-with-ps.js +0 -17
  606. package/test262/node_modules/test262-stream/test/collateral/valid-with-hashbang/fake-test262/test/raw.js +0 -17
  607. package/test262/node_modules/test262-stream/test/collateral/valid-with-hashbang/fake-test262/test/rawWithLicense.js +0 -21
  608. package/test262/node_modules/test262-stream/test/collateral/valid-with-includes/custom-includes/assert.js +0 -17
  609. package/test262/node_modules/test262-stream/test/collateral/valid-with-includes/custom-includes/doneprintHandle.js +0 -9
  610. package/test262/node_modules/test262-stream/test/collateral/valid-with-includes/custom-includes/sta.js +0 -13
  611. package/test262/node_modules/test262-stream/test/collateral/valid-with-includes/expected-content/test/async_default.js +0 -52
  612. package/test262/node_modules/test262-stream/test/collateral/valid-with-includes/expected-content/test/async_strict_mode.js +0 -53
  613. package/test262/node_modules/test262-stream/test/collateral/valid-with-includes/expected-content/test/bothStrict_default.js +0 -47
  614. package/test262/node_modules/test262-stream/test/collateral/valid-with-includes/expected-content/test/bothStrict_strict_mode.js +0 -48
  615. package/test262/node_modules/test262-stream/test/collateral/valid-with-includes/expected-metadata/test/async_default.json +0 -18
  616. package/test262/node_modules/test262-stream/test/collateral/valid-with-includes/expected-metadata/test/async_strict_mode.json +0 -18
  617. package/test262/node_modules/test262-stream/test/collateral/valid-with-includes/expected-metadata/test/bothStrict_default.json +0 -24
  618. package/test262/node_modules/test262-stream/test/collateral/valid-with-includes/expected-metadata/test/bothStrict_strict_mode.json +0 -24
  619. package/test262/node_modules/test262-stream/test/collateral/valid-with-includes/fake-test262/harness/assert.js +0 -17
  620. package/test262/node_modules/test262-stream/test/collateral/valid-with-includes/fake-test262/harness/doneprintHandle.js +0 -6
  621. package/test262/node_modules/test262-stream/test/collateral/valid-with-includes/fake-test262/test/async.js +0 -10
  622. package/test262/node_modules/test262-stream/test/collateral/valid-with-includes/fake-test262/test/bothStrict.js +0 -15
  623. package/test262/node_modules/test262-stream/test/collateral/valid-with-paths/expected-content/test/async/asyncNegative_default.js +0 -49
  624. package/test262/node_modules/test262-stream/test/collateral/valid-with-paths/expected-content/test/async/asyncNegative_strict_mode.js +0 -50
  625. package/test262/node_modules/test262-stream/test/collateral/valid-with-paths/expected-content/test/async/async_default.js +0 -48
  626. package/test262/node_modules/test262-stream/test/collateral/valid-with-paths/expected-content/test/async/async_strict_mode.js +0 -49
  627. package/test262/node_modules/test262-stream/test/collateral/valid-with-paths/expected-content/test/bothStrict_default.js +0 -46
  628. package/test262/node_modules/test262-stream/test/collateral/valid-with-paths/expected-content/test/bothStrict_strict_mode.js +0 -47
  629. package/test262/node_modules/test262-stream/test/collateral/valid-with-paths/expected-content/test/strict/no/noStrict_default.js +0 -36
  630. package/test262/node_modules/test262-stream/test/collateral/valid-with-paths/expected-content/test/strict/no/rawNoStrict_default.js +0 -14
  631. package/test262/node_modules/test262-stream/test/collateral/valid-with-paths/expected-metadata/test/async/asyncNegative_default.json +0 -22
  632. package/test262/node_modules/test262-stream/test/collateral/valid-with-paths/expected-metadata/test/async/asyncNegative_strict_mode.json +0 -22
  633. package/test262/node_modules/test262-stream/test/collateral/valid-with-paths/expected-metadata/test/async/async_default.json +0 -18
  634. package/test262/node_modules/test262-stream/test/collateral/valid-with-paths/expected-metadata/test/async/async_strict_mode.json +0 -18
  635. package/test262/node_modules/test262-stream/test/collateral/valid-with-paths/expected-metadata/test/bothStrict_default.json +0 -24
  636. package/test262/node_modules/test262-stream/test/collateral/valid-with-paths/expected-metadata/test/bothStrict_strict_mode.json +0 -24
  637. package/test262/node_modules/test262-stream/test/collateral/valid-with-paths/expected-metadata/test/strict/no/noStrict_default.json +0 -17
  638. package/test262/node_modules/test262-stream/test/collateral/valid-with-paths/expected-metadata/test/strict/no/rawNoStrict_default.json +0 -14
  639. package/test262/node_modules/test262-stream/test/collateral/valid-with-paths/fake-test262/harness/assert.js +0 -17
  640. package/test262/node_modules/test262-stream/test/collateral/valid-with-paths/fake-test262/harness/doneprintHandle.js +0 -6
  641. package/test262/node_modules/test262-stream/test/collateral/valid-with-paths/fake-test262/harness/sta.js +0 -12
  642. package/test262/node_modules/test262-stream/test/collateral/valid-with-paths/fake-test262/test/async/async.js +0 -10
  643. package/test262/node_modules/test262-stream/test/collateral/valid-with-paths/fake-test262/test/async/asyncNegative.js +0 -11
  644. package/test262/node_modules/test262-stream/test/collateral/valid-with-paths/fake-test262/test/bothStrict.js +0 -15
  645. package/test262/node_modules/test262-stream/test/collateral/valid-with-paths/fake-test262/test/error.js +0 -8
  646. package/test262/node_modules/test262-stream/test/collateral/valid-with-paths/fake-test262/test/negative-empty.js +0 -6
  647. package/test262/node_modules/test262-stream/test/collateral/valid-with-paths/fake-test262/test/strict/no/noStrict.js +0 -5
  648. package/test262/node_modules/test262-stream/test/collateral/valid-with-paths/fake-test262/test/strict/no/rawNoStrict.js +0 -14
  649. package/test262/node_modules/test262-stream/test/collateral/valid-with-paths/fake-test262/test/strict/rawStrict.js +0 -15
  650. package/test262/node_modules/test262-stream/test/collateral/valid-with-paths/fake-test262/test/strict/strict.js +0 -9
  651. package/test262/node_modules/test262-stream/test/test.js +0 -319
  652. package/test262/node_modules/to-regex-range/LICENSE +0 -21
  653. package/test262/node_modules/to-regex-range/README.md +0 -305
  654. package/test262/node_modules/to-regex-range/index.js +0 -288
  655. package/test262/node_modules/to-regex-range/package.json +0 -88
  656. package/test262/package-lock.json +0 -279
  657. package/test262/package.json +0 -6
  658. package/test262/prelude.js +0 -75
  659. package/test262/results.json +0 -1
@@ -1,10 +1,12 @@
1
1
  import { Blocktype, Opcodes, Valtype, PageSize, ValtypeSize } from "./wasmSpec.js";
2
- import { signedLEB128, unsignedLEB128 } from "./encoding.js";
2
+ import { ieee754_binary64, signedLEB128, unsignedLEB128 } from "./encoding.js";
3
3
  import { operatorOpcode } from "./expression.js";
4
4
  import { BuiltinFuncs, BuiltinVars, importedFuncs, NULL, UNDEFINED } from "./builtins.js";
5
5
  import { PrototypeFuncs } from "./prototype.js";
6
- import { number, i32x4 } from "./embedding.js";
6
+ import { number, i32x4, enforceOneByte, enforceTwoBytes, enforceFourBytes, enforceEightBytes } from "./embedding.js";
7
+ import { log } from "./log.js";
7
8
  import parse from "./parse.js";
9
+ import * as Rhemyn from "../rhemyn/compile.js";
8
10
 
9
11
  let globals = {};
10
12
  let globalInd = 0;
@@ -35,7 +37,14 @@ const debug = str => {
35
37
  };
36
38
 
37
39
  const todo = msg => {
38
- throw new Error(`todo: ${msg}`);
40
+ class TodoError extends Error {
41
+ constructor(message) {
42
+ super(message);
43
+ this.name = 'TodoError';
44
+ }
45
+ }
46
+
47
+ throw new TodoError(`todo: ${msg}`);
39
48
 
40
49
  const code = [];
41
50
 
@@ -101,6 +110,9 @@ const generate = (scope, decl, global = false, name = undefined) => {
101
110
  case 'WhileStatement':
102
111
  return generateWhile(scope, decl);
103
112
 
113
+ case 'ForOfStatement':
114
+ return generateForOf(scope, decl);
115
+
104
116
  case 'BreakStatement':
105
117
  return generateBreak(scope, decl);
106
118
 
@@ -141,45 +153,65 @@ const generate = (scope, decl, global = false, name = undefined) => {
141
153
 
142
154
  return [];
143
155
 
144
- case 'TaggedTemplateExpression':
145
- // hack for inline asm
146
- if (decl.tag.name !== 'asm') return todo('tagged template expressions not implemented');
156
+ case 'TaggedTemplateExpression': {
157
+ const funcs = {
158
+ asm: str => {
159
+ let out = [];
147
160
 
148
- const str = decl.quasi.quasis[0].value.raw;
149
- let out = [];
161
+ for (const line of str.split('\n')) {
162
+ const asm = line.trim().split(';;')[0].split(' ');
163
+ if (asm[0] === '') continue; // blank
150
164
 
151
- for (const line of str.split('\n')) {
152
- const asm = line.trim().split(';;')[0].split(' ');
153
- if (asm[0] === '') continue; // blank
165
+ if (asm[0] === 'local') {
166
+ const [ name, idx, type ] = asm.slice(1);
167
+ scope.locals[name] = { idx: parseInt(idx), type: Valtype[type] };
168
+ continue;
169
+ }
154
170
 
155
- if (asm[0] === 'local') {
156
- const [ name, idx, type ] = asm.slice(1);
157
- scope.locals[name] = { idx: parseInt(idx), type: Valtype[type] };
158
- continue;
159
- }
171
+ if (asm[0] === 'returns') {
172
+ scope.returns = asm.slice(1).map(x => Valtype[x]);
173
+ continue;
174
+ }
160
175
 
161
- if (asm[0] === 'returns') {
162
- scope.returns = asm.slice(1).map(x => Valtype[x]);
163
- continue;
164
- }
176
+ if (asm[0] === 'memory') {
177
+ allocPage('asm instrinsic');
178
+ // todo: add to store/load offset insts
179
+ continue;
180
+ }
165
181
 
166
- if (asm[0] === 'memory') {
167
- scope.memory = true;
168
- allocPage('asm instrinsic');
169
- // todo: add to store/load offset insts
170
- continue;
171
- }
182
+ let inst = Opcodes[asm[0].replace('.', '_')];
183
+ if (!inst) throw new Error(`inline asm: inst ${asm[0]} not found`);
184
+
185
+ if (!Array.isArray(inst)) inst = [ inst ];
186
+ const immediates = asm.slice(1).map(x => parseInt(x));
187
+
188
+ out.push([ ...inst, ...immediates ]);
189
+ }
190
+
191
+ return out;
192
+ },
172
193
 
173
- let inst = Opcodes[asm[0].replace('.', '_')];
174
- if (!inst) throw new Error(`inline asm: inst ${asm[0]} not found`);
194
+ __internal_print_type: str => {
195
+ const type = getType(scope, str) - TYPES.number;
175
196
 
176
- if (!Array.isArray(inst)) inst = [ inst ];
177
- const immediates = asm.slice(1).map(x => parseInt(x));
197
+ return [
198
+ ...number(type),
199
+ [ Opcodes.call, importedFuncs.print ],
178
200
 
179
- out.push([ ...inst, ...immediates ]);
201
+ // newline
202
+ ...number(10),
203
+ [ Opcodes.call, importedFuncs.printChar ]
204
+ ];
205
+ }
180
206
  }
181
207
 
182
- return out;
208
+ const name = decl.tag.name;
209
+ // hack for inline asm
210
+ if (!funcs[name]) return todo('tagged template expressions not implemented');
211
+
212
+ const str = decl.quasi.quasis[0].value.raw;
213
+ return funcs[name](str);
214
+ }
183
215
 
184
216
  default:
185
217
  return todo(`no generation for ${decl.type}!`);
@@ -269,19 +301,17 @@ const generateIdent = (scope, decl) => {
269
301
 
270
302
  const generateReturn = (scope, decl) => {
271
303
  if (decl.argument === null) {
272
- if (!scope.returnType) scope.returnType = TYPES.undefined;
273
-
274
304
  // just bare "return"
275
305
  return [
276
306
  ...number(UNDEFINED), // "undefined" if func returns
307
+ ...number(TYPES.undefined, Valtype.i32), // type undefined
277
308
  [ Opcodes.return ]
278
309
  ];
279
310
  }
280
311
 
281
- if (!scope.returnType) scope.returnType = getNodeType(scope, decl.argument);
282
-
283
312
  return [
284
313
  ...generate(scope, decl.argument),
314
+ ...getNodeType(scope, decl.argument),
285
315
  [ Opcodes.return ]
286
316
  ];
287
317
  };
@@ -295,11 +325,13 @@ const localTmp = (scope, name, type = valtypeBinary) => {
295
325
  return idx;
296
326
  };
297
327
 
298
- const performLogicOp = (scope, op, left, right) => {
328
+ const isIntOp = op => op && (op[0] >= 0xb7 && op[0] <= 0xba);
329
+
330
+ const performLogicOp = (scope, op, left, right, leftType, rightType) => {
299
331
  const checks = {
300
- '||': Opcodes.eqz,
301
- '&&': [ Opcodes.i32_to ]
302
- // todo: ??
332
+ '||': falsy,
333
+ '&&': truthy,
334
+ '??': nullish
303
335
  };
304
336
 
305
337
  if (!checks[op]) return todo(`logic operator ${op} not implemented yet`);
@@ -307,14 +339,52 @@ const performLogicOp = (scope, op, left, right) => {
307
339
  // generic structure for {a} OP {b}
308
340
  // -->
309
341
  // _ = {a}; if (OP_CHECK) {b} else _
342
+
343
+ // if we can, use int tmp and convert at the end to help prevent unneeded conversions
344
+ // (like if we are in an if condition - very common)
345
+ const leftIsInt = isIntOp(left[left.length - 1]);
346
+ const rightIsInt = isIntOp(right[right.length - 1]);
347
+
348
+ const canInt = leftIsInt && rightIsInt;
349
+
350
+ if (canInt) {
351
+ // remove int -> float conversions from left and right
352
+ left.pop();
353
+ right.pop();
354
+
355
+ return [
356
+ ...left,
357
+ [ Opcodes.local_tee, localTmp(scope, 'logictmpi', Valtype.i32) ],
358
+ ...checks[op](scope, [], leftType, true, true),
359
+ [ Opcodes.if, Valtype.i32 ],
360
+ ...right,
361
+ // note type
362
+ ...rightType,
363
+ [ Opcodes.local_set, localTmp(scope, '#last_type', Valtype.i32) ],
364
+ [ Opcodes.else ],
365
+ [ Opcodes.local_get, localTmp(scope, 'logictmpi', Valtype.i32) ],
366
+ // note type
367
+ ...leftType,
368
+ [ Opcodes.local_set, localTmp(scope, '#last_type', Valtype.i32) ],
369
+ [ Opcodes.end ],
370
+ Opcodes.i32_from
371
+ ];
372
+ }
373
+
310
374
  return [
311
375
  ...left,
312
376
  [ Opcodes.local_tee, localTmp(scope, 'logictmp') ],
313
- ...checks[op],
377
+ ...checks[op](scope, [], leftType, false, true),
314
378
  [ Opcodes.if, valtypeBinary ],
315
379
  ...right,
380
+ // note type
381
+ ...rightType,
382
+ [ Opcodes.local_set, localTmp(scope, '#last_type', Valtype.i32) ],
316
383
  [ Opcodes.else ],
317
384
  [ Opcodes.local_get, localTmp(scope, 'logictmp') ],
385
+ // note type
386
+ ...leftType,
387
+ [ Opcodes.local_set, localTmp(scope, '#last_type', Valtype.i32) ],
318
388
  [ Opcodes.end ]
319
389
  ];
320
390
  };
@@ -325,15 +395,16 @@ const concatStrings = (scope, left, right, global, name, assign) => {
325
395
  // todo: optimize by looking up names in arrays and using that if exists?
326
396
  // todo: optimize this if using literals/known lengths?
327
397
 
328
- scope.memory = true;
329
-
330
- const pointer = arrays.get(name ?? '$undeclared');
331
-
332
398
  const rightPointer = localTmp(scope, 'concat_right_pointer', Valtype.i32);
333
399
  const rightLength = localTmp(scope, 'concat_right_length', Valtype.i32);
334
400
  const leftLength = localTmp(scope, 'concat_left_length', Valtype.i32);
335
401
 
402
+ const aotWFA = process.argv.includes('-aot-well-formed-string-approximation');
403
+ if (aotWFA) addVarMeta(name, { wellFormed: undefined });
404
+
336
405
  if (assign) {
406
+ const pointer = arrays.get(name ?? '$undeclared');
407
+
337
408
  return [
338
409
  // setup right
339
410
  ...right,
@@ -384,15 +455,12 @@ const concatStrings = (scope, left, right, global, name, assign) => {
384
455
 
385
456
  const leftPointer = localTmp(scope, 'concat_left_pointer', Valtype.i32);
386
457
 
387
- const newOut = makeArray(scope, {
458
+ // alloc/assign array
459
+ const [ , pointer ] = makeArray(scope, {
388
460
  rawElements: new Array(0)
389
461
  }, global, name, true, 'i16');
390
462
 
391
463
  return [
392
- // setup new/out array
393
- ...newOut,
394
- [ Opcodes.drop ],
395
-
396
464
  // setup left
397
465
  ...left,
398
466
  Opcodes.i32_to_u,
@@ -458,90 +526,309 @@ const concatStrings = (scope, left, right, global, name, assign) => {
458
526
  ];
459
527
  };
460
528
 
461
- const falsy = (scope, wasm, type) => {
462
- // arrays are always truthy
463
- if (type === TYPES._array) return [
464
- ...wasm,
465
- [ Opcodes.drop ],
466
- number(0)
467
- ];
468
-
469
- if (type === TYPES.string) {
470
- // if "" (length = 0)
471
- return [
472
- // pointer
473
- ...wasm,
529
+ const compareStrings = (scope, left, right) => {
530
+ // todo: this should be rewritten into a func
531
+ // todo: convert left and right to strings if not
532
+ // todo: optimize by looking up names in arrays and using that if exists?
533
+ // todo: optimize this if using literals/known lengths?
474
534
 
475
- // get length
476
- [ Opcodes.i32_load, Math.log2(ValtypeSize.i32) - 1, 0 ],
535
+ const leftPointer = localTmp(scope, 'compare_left_pointer', Valtype.i32);
536
+ const leftLength = localTmp(scope, 'compare_left_length', Valtype.i32);
537
+ const rightPointer = localTmp(scope, 'compare_right_pointer', Valtype.i32);
538
+ const rightLength = localTmp(scope, 'compare_right_length', Valtype.i32);
477
539
 
478
- // if length == 0
479
- [ Opcodes.i32_eqz ],
480
- Opcodes.i32_from_u
481
- ]
482
- }
540
+ const index = localTmp(scope, 'compare_index', Valtype.i32);
541
+ const indexEnd = localTmp(scope, 'compare_index_end', Valtype.i32);
483
542
 
484
- // if = 0
485
543
  return [
486
- ...wasm,
544
+ // setup left
545
+ ...left,
546
+ Opcodes.i32_to_u,
547
+ [ Opcodes.local_tee, leftPointer ],
487
548
 
488
- ...Opcodes.eqz,
489
- Opcodes.i32_from_u
549
+ // setup right
550
+ ...right,
551
+ Opcodes.i32_to_u,
552
+ [ Opcodes.local_tee, rightPointer ],
553
+
554
+ // fast path: check leftPointer == rightPointer
555
+ // use if (block) for everything after to "return" a value early
556
+ [ Opcodes.i32_ne ],
557
+ [ Opcodes.if, Valtype.i32 ],
558
+
559
+ // get lengths
560
+ [ Opcodes.local_get, leftPointer ],
561
+ [ Opcodes.i32_load, Math.log2(ValtypeSize[valtype]) - 1, ...unsignedLEB128(0) ],
562
+ [ Opcodes.local_tee, leftLength ],
563
+
564
+ [ Opcodes.local_get, rightPointer ],
565
+ [ Opcodes.i32_load, Math.log2(ValtypeSize[valtype]) - 1, ...unsignedLEB128(0) ],
566
+ [ Opcodes.local_tee, rightLength ],
567
+
568
+ // fast path: check leftLength != rightLength
569
+ [ Opcodes.i32_ne ],
570
+ [ Opcodes.if, Blocktype.void ],
571
+ ...number(0, Valtype.i32),
572
+ [ Opcodes.br, 1 ],
573
+ [ Opcodes.end ],
574
+
575
+ // no fast path for length = 0 as it would probably be slower for most of the time?
576
+
577
+ // tmp could have already been used
578
+ ...number(0, Valtype.i32),
579
+ [ Opcodes.local_set, index ],
580
+
581
+ // setup index end as length * sizeof i16 (2)
582
+ // we do this instead of having to do mul/div each iter for perf™
583
+ [ Opcodes.local_get, leftLength ],
584
+ ...number(ValtypeSize.i16, Valtype.i32),
585
+ [ Opcodes.i32_mul ],
586
+ [ Opcodes.local_set, indexEnd ],
587
+
588
+ // iterate over each char and check if eq
589
+ [ Opcodes.loop, Blocktype.void ],
590
+
591
+ // fetch left
592
+ [ Opcodes.local_get, index ],
593
+ [ Opcodes.local_get, leftPointer ],
594
+ [ Opcodes.i32_add ],
595
+ [ Opcodes.i32_load16_u, Math.log2(ValtypeSize.i16) - 1, ...unsignedLEB128(ValtypeSize.i32) ],
596
+
597
+ // fetch right
598
+ [ Opcodes.local_get, index ],
599
+ [ Opcodes.local_get, rightPointer ],
600
+ [ Opcodes.i32_add ],
601
+ [ Opcodes.i32_load16_u, Math.log2(ValtypeSize.i16) - 1, ...unsignedLEB128(ValtypeSize.i32) ],
602
+
603
+ // not equal, "return" false
604
+ [ Opcodes.i32_ne ],
605
+ [ Opcodes.if, Blocktype.void ],
606
+ ...number(0, Valtype.i32),
607
+ [ Opcodes.br, 2 ],
608
+ [ Opcodes.end ],
609
+
610
+ // index += sizeof i16 (2)
611
+ [ Opcodes.local_get, index ],
612
+ ...number(ValtypeSize.i16, Valtype.i32),
613
+ [ Opcodes.i32_add ],
614
+ [ Opcodes.local_tee, index ],
615
+
616
+ // if index != index end (length * sizeof 16), loop
617
+ [ Opcodes.local_get, indexEnd ],
618
+ [ Opcodes.i32_ne ],
619
+ [ Opcodes.br_if, 0 ],
620
+ [ Opcodes.end ],
621
+
622
+ // no failed checks, so true!
623
+ ...number(1, Valtype.i32),
624
+
625
+ // pointers match, so true
626
+ [ Opcodes.else ],
627
+ ...number(1, Valtype.i32),
628
+ [ Opcodes.end ],
629
+
630
+ // convert i32 result to valtype
631
+ // do not do as automatically added by binary exp gen for equality ops
632
+ // Opcodes.i32_from_u
490
633
  ];
491
634
  };
492
635
 
493
- const truthy = (scope, wasm, type) => {
494
- // arrays are always truthy
495
- if (type === TYPES._array) return [
636
+ const truthy = (scope, wasm, type, intIn = false, intOut = false) => {
637
+ if (isIntOp(wasm[wasm.length - 1])) return [
496
638
  ...wasm,
497
- [ Opcodes.drop ],
498
- number(1)
639
+ ...(!intIn && intOut ? [ Opcodes.i32_to_u ] : [])
499
640
  ];
500
641
 
501
- if (type === TYPES.string) {
502
- // if not "" (length = 0)
503
- return [
504
- // pointer
505
- ...wasm,
642
+ const tmp = localTmp(scope, `$logicinner_tmp${intIn ? '_int' : ''}`, intIn ? Valtype.i32 : valtypeBinary);
506
643
 
507
- // get length
508
- [ Opcodes.i32_load, Math.log2(ValtypeSize.i32) - 1, 0 ],
644
+ const def = [
645
+ // if value != 0
646
+ [ Opcodes.local_get, tmp ],
509
647
 
510
- // if length != 0
511
- /* [ Opcodes.i32_eqz ],
512
- [ Opcodes.i32_eqz ], */
513
- Opcodes.i32_from_u
514
- ]
515
- }
516
-
517
- // if != 0
518
- return [
519
- ...wasm,
648
+ // ...(intIn ? [ [ Opcodes.i32_eqz ] ] : [ ...Opcodes.eqz ]),
649
+ ...(!intOut || (intIn && intOut) ? [] : [ Opcodes.i32_to_u ]),
520
650
 
521
651
  /* Opcodes.eqz,
522
652
  [ Opcodes.i32_eqz ],
523
653
  Opcodes.i32_from */
524
654
  ];
655
+
656
+ return [
657
+ ...wasm,
658
+ [ Opcodes.local_set, tmp ],
659
+
660
+ ...typeSwitch(scope, type, {
661
+ // [TYPES.number]: def,
662
+ [TYPES._array]: [
663
+ // arrays are always truthy
664
+ ...number(1, intOut ? Valtype.i32 : valtypeBinary)
665
+ ],
666
+ [TYPES.string]: [
667
+ [ Opcodes.local_get, tmp ],
668
+ ...(intIn ? [] : [ Opcodes.i32_to_u ]),
669
+
670
+ // get length
671
+ [ Opcodes.i32_load, Math.log2(ValtypeSize.i32) - 1, 0 ],
672
+
673
+ // if length != 0
674
+ /* [ Opcodes.i32_eqz ],
675
+ [ Opcodes.i32_eqz ], */
676
+ ...(intOut ? [] : [ Opcodes.i32_from_u ])
677
+ ],
678
+ default: def
679
+ }, intOut ? Valtype.i32 : valtypeBinary)
680
+ ];
681
+ };
682
+
683
+ const falsy = (scope, wasm, type, intIn = false, intOut = false) => {
684
+ const tmp = localTmp(scope, `$logicinner_tmp${intIn ? '_int' : ''}`, intIn ? Valtype.i32 : valtypeBinary);
685
+ return [
686
+ ...wasm,
687
+ [ Opcodes.local_set, tmp ],
688
+
689
+ ...typeSwitch(scope, type, {
690
+ [TYPES._array]: [
691
+ // arrays are always truthy
692
+ ...number(0, intOut ? Valtype.i32 : valtypeBinary)
693
+ ],
694
+ [TYPES.string]: [
695
+ [ Opcodes.local_get, tmp ],
696
+ ...(intIn ? [] : [ Opcodes.i32_to_u ]),
697
+
698
+ // get length
699
+ [ Opcodes.i32_load, Math.log2(ValtypeSize.i32) - 1, 0 ],
700
+
701
+ // if length == 0
702
+ [ Opcodes.i32_eqz ],
703
+ ...(intOut ? [] : [ Opcodes.i32_from_u ])
704
+ ],
705
+ default: [
706
+ // if value == 0
707
+ [ Opcodes.local_get, tmp ],
708
+
709
+ ...(intIn ? [ [ Opcodes.i32_eqz ] ] : [ ...Opcodes.eqz ]),
710
+ ...(intOut ? [] : [ Opcodes.i32_from_u ])
711
+ ]
712
+ }, intOut ? Valtype.i32 : valtypeBinary)
713
+ ];
525
714
  };
526
715
 
527
- const performOp = (scope, op, left, right, leftType, rightType, _global = false, _name = '$unspecified', assign = false) => {
716
+ const nullish = (scope, wasm, type, intIn = false, intOut = false) => {
717
+ const tmp = localTmp(scope, `$logicinner_tmp${intIn ? '_int' : ''}`, intIn ? Valtype.i32 : valtypeBinary);
718
+ return [
719
+ ...wasm,
720
+ [ Opcodes.local_set, tmp ],
721
+
722
+ ...typeSwitch(scope, type, {
723
+ [TYPES.undefined]: [
724
+ // undefined
725
+ ...number(1, intOut ? Valtype.i32 : valtypeBinary)
726
+ ],
727
+ [TYPES.object]: [
728
+ // object, null if == 0
729
+ [ Opcodes.local_get, tmp ],
730
+
731
+ ...(intIn ? [ [ Opcodes.i32_eqz ] ] : [ ...Opcodes.eqz ]),
732
+ ...(intOut ? [] : [ Opcodes.i32_from_u ])
733
+ ],
734
+ default: [
735
+ // not
736
+ ...number(0, intOut ? Valtype.i32 : valtypeBinary)
737
+ ]
738
+ }, intOut ? Valtype.i32 : valtypeBinary)
739
+ ];
740
+ };
741
+
742
+ const stringOnly = wasm => {
743
+ if (!Array.isArray(wasm[0])) return [ ...wasm, 'string_only' ];
744
+ if (wasm.length === 1) return [ [ ...wasm[0], 'string_only' ] ];
745
+
746
+ return [
747
+ [ ...wasm[0], 'string_only|start' ],
748
+ ...wasm.slice(1, -1),
749
+ [ ...wasm[wasm.length - 1], 'string_only|end' ]
750
+ ];
751
+ }
752
+
753
+ const performOp = (scope, op, left, right, leftType, rightType, _global = false, _name = '$undeclared', assign = false) => {
528
754
  if (op === '||' || op === '&&' || op === '??') {
529
- return performLogicOp(scope, op, left, right);
755
+ return performLogicOp(scope, op, left, right, leftType, rightType);
756
+ }
757
+
758
+ const eqOp = ['==', '===', '!=', '!==', '>', '>=', '<', '<='].includes(op);
759
+ const strictOp = op === '===' || op === '!==';
760
+
761
+ const startOut = [], endOut = [];
762
+ const finalise = out => startOut.concat(out, endOut);
763
+
764
+ // if strict (in)equal check types match
765
+ if (strictOp) {
766
+ // startOut.push(
767
+ // ...leftType,
768
+ // ...rightType,
769
+ // [ Opcodes.i32_eq ]
770
+ // );
771
+
772
+ // endOut.push(
773
+ // [ Opcodes.i32_and ]
774
+ // );
775
+
776
+ // startOut.push(
777
+ // [ Opcodes.block, Valtype.i32 ],
778
+ // ...leftType,
779
+ // ...rightType,
780
+ // [ Opcodes.i32_ne ],
781
+ // [ Opcodes.if, Blocktype.void ],
782
+ // ...number(op === '===' ? 0 : 1, Valtype.i32),
783
+ // [ Opcodes.br, 1 ],
784
+ // [ Opcodes.end ]
785
+ // );
786
+
787
+ // endOut.push(
788
+ // [ Opcodes.end ]
789
+ // );
790
+
791
+ endOut.push(
792
+ ...leftType,
793
+ ...rightType,
794
+ ...(op === '===' ? [
795
+ [ Opcodes.i32_eq ],
796
+ [ Opcodes.i32_and ]
797
+ ] : [
798
+ [ Opcodes.i32_ne ],
799
+ [ Opcodes.i32_or ]
800
+ ])
801
+ );
530
802
  }
531
803
 
532
- if (leftType === TYPES.string || rightType === TYPES.string) {
533
- if (op === '+') {
534
- // string concat (a + b)
535
- return concatStrings(scope, left, right, _global, _name, assign);
536
- }
804
+ // todo: if equality op and an operand is undefined, return false
805
+ // todo: niche null hell with 0
537
806
 
538
- // any other math op, NaN
539
- if (!['==', '===', '!=', '!==', '>', '>=', '<', '<='].includes(op)) return number(NaN);
807
+ // if (leftType === TYPES.string || rightType === TYPES.string) {
808
+ // if (op === '+') {
809
+ // // string concat (a + b)
810
+ // return finalise(concatStrings(scope, left, right, _global, _name, assign));
811
+ // }
540
812
 
541
- // else leave bool ops
542
- // todo: convert string to number if string and number or le/ge op
543
- // todo: string equality
544
- }
813
+ // // not an equality op, NaN
814
+ // if (!eqOp) return finalise(number(NaN));
815
+
816
+ // // else leave bool ops
817
+ // // todo: convert string to number if string and number/bool
818
+ // // todo: string (>|>=|<|<=) string
819
+
820
+ // // string comparison
821
+ // if (op === '===' || op === '==') {
822
+ // return finalise(compareStrings(scope, left, right));
823
+ // }
824
+
825
+ // if (op === '!==' || op === '!=') {
826
+ // return finalise([
827
+ // ...compareStrings(scope, left, right),
828
+ // [ Opcodes.i32_eqz ]
829
+ // ]);
830
+ // }
831
+ // }
545
832
 
546
833
  let ops = operatorOpcode[valtype][op];
547
834
 
@@ -551,35 +838,90 @@ const performOp = (scope, op, left, right, leftType, rightType, _global = false,
551
838
  includeBuiltin(scope, builtinName);
552
839
  const idx = funcIndex[builtinName];
553
840
 
554
- return [
841
+ return finalise([
555
842
  ...left,
556
843
  ...right,
557
844
  [ Opcodes.call, idx ]
558
- ];
845
+ ]);
559
846
  }
560
847
 
561
848
  if (!ops) return todo(`operator ${op} not implemented yet`); // throw new Error(`unknown operator ${op}`);
562
849
 
563
850
  if (!Array.isArray(ops)) ops = [ ops ];
851
+ ops = [ ops ];
852
+
853
+ let tmpLeft, tmpRight;
854
+ // if equal op, check if strings for compareStrings
855
+ if (op === '===' || op === '==' || op === '!==' || op === '!=') {
856
+ tmpLeft = localTmp(scope, '__tmpop_left');
857
+ tmpRight = localTmp(scope, '__tmpop_right');
858
+
859
+ ops.unshift(...stringOnly([
860
+ // if left is string
861
+ ...leftType,
862
+ ...number(TYPES.string, Valtype.i32),
863
+ [ Opcodes.i32_eq ],
864
+
865
+ // if right is string
866
+ ...rightType,
867
+ ...number(TYPES.string, Valtype.i32),
868
+ [ Opcodes.i32_eq ],
869
+
870
+ // if either are true
871
+ [ Opcodes.i32_or ],
872
+ [ Opcodes.if, Blocktype.void ],
873
+
874
+ // todo: convert non-strings to strings, for now fail immediately if one is not
875
+ // if left is not string
876
+ ...leftType,
877
+ ...number(TYPES.string, Valtype.i32),
878
+ [ Opcodes.i32_ne ],
879
+
880
+ // if right is not string
881
+ ...rightType,
882
+ ...number(TYPES.string, Valtype.i32),
883
+ [ Opcodes.i32_ne ],
884
+
885
+ // if either are true
886
+ [ Opcodes.i32_or ],
887
+ [ Opcodes.if, Blocktype.void ],
888
+ ...number(0, Valtype.i32),
889
+ [ Opcodes.br, 1 ],
890
+ [ Opcodes.end ],
564
891
 
565
- return [
892
+ ...compareStrings(scope, [ [ Opcodes.local_get, tmpLeft ] ], [ [ Opcodes.local_get, tmpRight ] ]),
893
+ // ...compareStrings(scope, [ [ Opcodes.local_get, tmpLeft ] ], [ [ Opcodes.local_get, tmpRight ] ]),
894
+ ...(op === '!==' || op === '!=' ? [ [ Opcodes.i32_eqz ] ] : []),
895
+ [ Opcodes.br, 1 ],
896
+ [ Opcodes.end ],
897
+ ]));
898
+
899
+ // if not already in block, add a block
900
+ // if (endOut.length === 0) {
901
+ startOut.push(stringOnly([ Opcodes.block, Valtype.i32 ]));
902
+ // endOut.push(stringOnly([ Opcodes.end ]));
903
+ endOut.unshift(stringOnly([ Opcodes.end ]));
904
+ // }
905
+ }
906
+
907
+ return finalise([
566
908
  ...left,
909
+ ...(tmpLeft != null ? stringOnly([ [ Opcodes.local_tee, tmpLeft ] ]) : []),
567
910
  ...right,
568
- ops
569
- ];
911
+ ...(tmpRight != null ? stringOnly([ [ Opcodes.local_tee, tmpRight ] ]) : []),
912
+ ...ops
913
+ ]);
570
914
  };
571
915
 
572
916
  const generateBinaryExp = (scope, decl, _global, _name) => {
573
- const out = [
574
- ...performOp(scope, decl.operator, generate(scope, decl.left), generate(scope, decl.right), getNodeType(scope, decl.left), getNodeType(scope, decl.right), _global, _name)
575
- ];
917
+ const out = performOp(scope, decl.operator, generate(scope, decl.left), generate(scope, decl.right), getNodeType(scope, decl.left), getNodeType(scope, decl.right), _global, _name);
576
918
 
577
919
  if (valtype !== 'i32' && ['==', '===', '!=', '!==', '>', '>=', '<', '<='].includes(decl.operator)) out.push(Opcodes.i32_from_u);
578
920
 
579
921
  return out;
580
922
  };
581
923
 
582
- const asmFunc = (name, { wasm, params, locals: localTypes, globals: globalTypes = [], globalInits, returns, returnType, memory, localNames = [], globalNames = [] }) => {
924
+ const asmFunc = (name, { wasm, params, locals: localTypes, globals: globalTypes = [], globalInits, returns, returnType, localNames = [], globalNames = [] }) => {
583
925
  const existing = funcs.find(x => x.name === name);
584
926
  if (existing) return existing;
585
927
 
@@ -615,7 +957,6 @@ const asmFunc = (name, { wasm, params, locals: localTypes, globals: globalTypes
615
957
  returns,
616
958
  returnType: TYPES[returnType ?? 'number'],
617
959
  wasm,
618
- memory,
619
960
  internal: true,
620
961
  index: currentFuncIndex++
621
962
  };
@@ -634,21 +975,56 @@ const includeBuiltin = (scope, builtin) => {
634
975
  };
635
976
 
636
977
  const generateLogicExp = (scope, decl) => {
637
- return performLogicOp(scope, decl.operator, generate(scope, decl.left), generate(scope, decl.right));
978
+ return performLogicOp(scope, decl.operator, generate(scope, decl.left), generate(scope, decl.right), getNodeType(scope, decl.left), getNodeType(scope, decl.right));
638
979
  };
639
980
 
981
+ // T = JS type, V = value/pointer
982
+ // 0bTTT
983
+ // qNAN: 0 11111111111 1000000000000000000000000000000000000000000000000001
984
+ // 50 bits usable: 0 11111111111 11??????????????????????????????????????????????????
985
+ // js type: 4 bits
986
+ // internal type: ? bits
987
+ // pointer: 32 bits
988
+ // https://piotrduperas.com/posts/nan-boxing
989
+ // 0x7ffc000000000000
990
+ // budget: 50 bits
991
+ // js type: 4 bits
992
+ // internal type: ? bits
993
+ // pointer: 32 bits
994
+
995
+ // generic
996
+ // 1 23 4 5
997
+ // 0 11111111111 11TTTTIIII??????????PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
998
+ // 1: regular iEEE 754 double NaN
999
+ // 2: extra 1 bit to identify NaN box
1000
+ // 3: js type
1001
+ // 4: internal type
1002
+ // 5: pointer
1003
+
640
1004
  const TYPES = {
641
- number: 0xffffffffffff0,
642
- boolean: 0xffffffffffff1,
643
- string: 0xffffffffffff2,
644
- undefined: 0xffffffffffff3,
645
- object: 0xffffffffffff4,
646
- function: 0xffffffffffff5,
647
- symbol: 0xffffffffffff6,
648
- bigint: 0xffffffffffff7,
1005
+ number: 0x00,
1006
+ boolean: 0x01,
1007
+ string: 0x02,
1008
+ undefined: 0x03,
1009
+ object: 0x04,
1010
+ function: 0x05,
1011
+ symbol: 0x06,
1012
+ bigint: 0x07,
649
1013
 
650
1014
  // these are not "typeof" types but tracked internally
651
- _array: 0xffffffffffff8
1015
+ _array: 0x10,
1016
+ _regexp: 0x11,
1017
+
1018
+ // typed arrays
1019
+ _int8array: 0x20,
1020
+ _uint8array: 0x21,
1021
+ _uint8clampedarray: 0x22,
1022
+ _int16array: 0x23,
1023
+ _uint16array: 0x24,
1024
+ _int32array: 0x25,
1025
+ _uint32array: 0x26,
1026
+ _float32array: 0x27,
1027
+ _float64array: 0x28,
652
1028
  };
653
1029
 
654
1030
  const TYPE_NAMES = {
@@ -661,108 +1037,178 @@ const TYPE_NAMES = {
661
1037
  [TYPES.symbol]: 'Symbol',
662
1038
  [TYPES.bigint]: 'BigInt',
663
1039
 
664
- [TYPES._array]: 'Array'
1040
+ [TYPES._array]: 'Array',
1041
+ [TYPES._regexp]: 'RegExp'
665
1042
  };
666
1043
 
667
- let typeStates = {};
668
-
669
1044
  const getType = (scope, _name) => {
670
1045
  const name = mapName(_name);
671
- if (scope.locals[name]) return typeStates[name];
672
1046
 
673
- if (builtinVars[name]) return TYPES[builtinVars[name].type ?? 'number'];
674
- if (builtinFuncs[name] !== undefined || importedFuncs[name] !== undefined || funcIndex[name] !== undefined || internalConstrs[name] !== undefined) return TYPES.function;
675
- if (globals[name]) return typeStates[name];
1047
+ if (scope.locals[name]) return [ [ Opcodes.local_get, scope.locals[name + '#type'].idx ] ];
1048
+ if (globals[name]) return [ [ Opcodes.global_get, globals[name + '#type'].idx ] ];
1049
+
1050
+ let type = TYPES.undefined;
1051
+ if (builtinVars[name]) type = TYPES[builtinVars[name].type ?? 'number'];
1052
+ if (builtinFuncs[name] !== undefined || importedFuncs[name] !== undefined || funcIndex[name] !== undefined || internalConstrs[name] !== undefined) type = TYPES.function;
676
1053
 
677
- if (name.startsWith('__Array_prototype_') && prototypeFuncs[TYPES._array][name.slice(18)]) return TYPES.function;
678
- if (name.startsWith('__String_prototype_') && prototypeFuncs[TYPES.string][name.slice(19)]) return TYPES.function;
1054
+ if (name.startsWith('__Array_prototype_') && prototypeFuncs[TYPES._array][name.slice(18)] ||
1055
+ name.startsWith('__String_prototype_') && prototypeFuncs[TYPES.string][name.slice(19)]) type = TYPES.function;
679
1056
 
680
- return TYPES.undefined;
1057
+ return number(type, Valtype.i32);
681
1058
  };
682
1059
 
683
- const getNodeType = (scope, node) => {
684
- if (node.type === 'Literal') {
685
- return TYPES[typeof node.value];
686
- }
1060
+ const setType = (scope, _name, type) => {
1061
+ const name = mapName(_name);
687
1062
 
688
- if (isFuncType(node.type)) {
689
- return TYPES.function;
690
- }
1063
+ const out = typeof type === 'number' ? number(type, Valtype.i32) : type;
691
1064
 
692
- if (node.type === 'Identifier') {
693
- return getType(scope, node.name);
694
- }
1065
+ if (scope.locals[name]) return [
1066
+ ...out,
1067
+ [ Opcodes.local_set, scope.locals[name + '#type'].idx ]
1068
+ ];
695
1069
 
696
- if (node.type === 'CallExpression' || node.type === 'NewExpression') {
697
- const name = node.callee.name;
698
- const func = funcs.find(x => x.name === name);
699
- if (func) return func.returnType ?? TYPES.number;
1070
+ if (globals[name]) return [
1071
+ ...out,
1072
+ [ Opcodes.global_set, globals[name + '#type'].idx ]
1073
+ ];
1074
+
1075
+ // throw new Error('could not find var');
1076
+ };
700
1077
 
701
- if (builtinFuncs[name]) return TYPES[builtinFuncs[name].returnType ?? 'number'];
702
- if (internalConstrs[name]) return internalConstrs[name].type;
1078
+ const getNodeType = (scope, node) => {
1079
+ const inner = () => {
1080
+ if (node.type === 'Literal') {
1081
+ if (node.regex) return TYPES._regexp;
703
1082
 
704
- let protoFunc;
705
- // ident.func()
706
- if (name && name.startsWith('__')) {
707
- const spl = name.slice(2).split('_');
1083
+ return TYPES[typeof node.value];
1084
+ }
708
1085
 
709
- const baseName = spl.slice(0, -1).join('_');
710
- const baseType = getType(scope, baseName);
1086
+ if (isFuncType(node.type)) {
1087
+ return TYPES.function;
1088
+ }
711
1089
 
712
- const func = spl[spl.length - 1];
713
- protoFunc = prototypeFuncs[baseType]?.[func];
1090
+ if (node.type === 'Identifier') {
1091
+ return getType(scope, node.name);
714
1092
  }
715
1093
 
716
- // literal.func()
717
- if (!name && node.callee.type === 'MemberExpression') {
718
- const baseType = getNodeType(scope, node.callee.object);
1094
+ if (node.type === 'CallExpression' || node.type === 'NewExpression') {
1095
+ const name = node.callee.name;
1096
+ const func = funcs.find(x => x.name === name);
1097
+
1098
+ if (func) {
1099
+ // console.log(scope, func, func.returnType);
1100
+ if (func.returnType) return func.returnType;
1101
+ }
1102
+
1103
+ if (builtinFuncs[name]) return TYPES[builtinFuncs[name].returnType ?? 'number'];
1104
+ if (internalConstrs[name]) return internalConstrs[name].type;
1105
+
1106
+ if (scope.locals['#last_type']) return [ [ Opcodes.local_get, localTmp(scope, '#last_type', Valtype.i32) ] ];
719
1107
 
720
- const func = node.callee.property.name;
721
- protoFunc = prototypeFuncs[baseType]?.[func];
1108
+ // presume
1109
+ // todo: warn here?
1110
+ return TYPES.number;
1111
+
1112
+ // let protoFunc;
1113
+ // // ident.func()
1114
+ // if (name && name.startsWith('__')) {
1115
+ // const spl = name.slice(2).split('_');
1116
+
1117
+ // const baseName = spl.slice(0, -1).join('_');
1118
+ // const baseType = getType(scope, baseName);
1119
+
1120
+ // const func = spl[spl.length - 1];
1121
+ // protoFunc = prototypeFuncs[baseType]?.[func];
1122
+ // }
1123
+
1124
+ // // literal.func()
1125
+ // if (!name && node.callee.type === 'MemberExpression') {
1126
+ // if (node.callee.object.regex) {
1127
+ // const funcName = node.callee.property.name;
1128
+ // return Rhemyn[funcName] ? TYPES.boolean : TYPES.undefined;
1129
+ // }
1130
+
1131
+ // const baseType = getNodeType(scope, node.callee.object);
1132
+
1133
+ // const func = node.callee.property.name;
1134
+ // protoFunc = prototypeFuncs[baseType]?.[func];
1135
+ // }
1136
+
1137
+ // if (protoFunc) return protoFunc.returnType;
722
1138
  }
723
1139
 
724
- if (protoFunc) return protoFunc.returnType ?? TYPES.number;
1140
+ if (node.type === 'ExpressionStatement') {
1141
+ return getNodeType(scope, node.expression);
1142
+ }
725
1143
 
726
- return TYPES.number;
727
- }
1144
+ if (node.type === 'AssignmentExpression') {
1145
+ return getNodeType(scope, node.right);
1146
+ }
728
1147
 
729
- if (node.type === 'ExpressionStatement') {
730
- return getNodeType(scope, node.expression);
731
- }
1148
+ if (node.type === 'ArrayExpression') {
1149
+ return TYPES._array;
1150
+ }
732
1151
 
733
- if (node.type === 'AssignmentExpression') {
734
- return getNodeType(scope, node.right);
735
- }
1152
+ if (node.type === 'BinaryExpression') {
1153
+ if (['==', '===', '!=', '!==', '>', '>=', '<', '<='].includes(node.operator)) return TYPES.boolean;
1154
+ return TYPES.number;
1155
+
1156
+ // todo: string concat types
1157
+ // if (node.operator !== '+') return TYPES.number;
1158
+ // else return [
1159
+ // // if left is string
1160
+ // ...getNodeType(scope, node.left),
1161
+ // ...number(TYPES.string, Valtype.i32),
1162
+ // [ Opcodes.i32_eq ],
1163
+
1164
+ // // if right is string
1165
+ // ...getNodeType(scope, node.right),
1166
+ // ...number(TYPES.string, Valtype.i32),
1167
+ // [ Opcodes.i32_eq ],
1168
+
1169
+ // // if either are true
1170
+ // [ Opcodes.i32_or ],
1171
+ // ];
1172
+ }
736
1173
 
737
- if (node.type === 'ArrayExpression') {
738
- return TYPES._array;
739
- }
1174
+ if (node.type === 'UnaryExpression') {
1175
+ if (node.operator === '!') return TYPES.boolean;
1176
+ if (node.operator === 'void') return TYPES.undefined;
1177
+ if (node.operator === 'delete') return TYPES.boolean;
1178
+ if (node.operator === 'typeof') return TYPES.string;
740
1179
 
741
- if (node.type === 'BinaryExpression') {
742
- if (['==', '===', '!=', '!==', '>', '>=', '<', '<='].includes(node.operator)) return TYPES.boolean;
1180
+ return TYPES.number;
1181
+ }
743
1182
 
744
- if (node.operator === '+' && (getNodeType(scope, node.left) === TYPES.string || getNodeType(scope, node.right) === TYPES.string)) return TYPES.string;
745
- }
1183
+ if (node.type === 'MemberExpression') {
1184
+ // hack: if something.length, number type
1185
+ if (node.property.name === 'length') return TYPES.number;
746
1186
 
747
- if (node.type === 'UnaryExpression') {
748
- if (node.operator === '!') return TYPES.boolean;
749
- if (node.operator === 'void') return TYPES.undefined;
750
- if (node.operator === 'delete') return TYPES.boolean;
751
- }
1187
+ // we cannot guess
1188
+ return TYPES.number;
1189
+ }
752
1190
 
753
- if (node.type === 'MemberExpression') {
754
- const objectType = getNodeType(scope, node.object);
1191
+ if (scope.locals['#last_type']) return [ [ Opcodes.local_get, localTmp(scope, '#last_type', Valtype.i32) ] ];
755
1192
 
756
- if (objectType === TYPES.string && node.computed) return TYPES.string;
757
- }
1193
+ // presume
1194
+ // todo: warn here?
1195
+ return TYPES.number;
1196
+ };
758
1197
 
759
- // default to number
760
- return TYPES.number;
1198
+ const ret = inner();
1199
+ // console.trace(node, ret);
1200
+ if (typeof ret === 'number') return number(ret, Valtype.i32);
1201
+ return ret;
761
1202
  };
762
1203
 
763
1204
  const generateLiteral = (scope, decl, global, name) => {
764
1205
  if (decl.value === null) return number(NULL);
765
1206
 
1207
+ if (decl.regex) {
1208
+ scope.regex[name] = decl.regex;
1209
+ return number(1);
1210
+ }
1211
+
766
1212
  switch (typeof decl.value) {
767
1213
  case 'number':
768
1214
  return number(decl.value);
@@ -772,27 +1218,16 @@ const generateLiteral = (scope, decl, global, name) => {
772
1218
  return number(decl.value ? 1 : 0);
773
1219
 
774
1220
  case 'string':
775
- // this is a terrible hack which changes type strings ("number" etc) to known const number values
776
- switch (decl.value) {
777
- case 'number': return number(TYPES.number);
778
- case 'boolean': return number(TYPES.boolean);
779
- case 'string': return number(TYPES.string);
780
- case 'undefined': return number(TYPES.undefined);
781
- case 'object': return number(TYPES.object);
782
- case 'function': return number(TYPES.function);
783
- case 'symbol': return number(TYPES.symbol);
784
- case 'bigint': return number(TYPES.bigint);
785
- }
786
-
787
1221
  const str = decl.value;
788
1222
  const rawElements = new Array(str.length);
1223
+ let j = 0;
789
1224
  for (let i = 0; i < str.length; i++) {
790
1225
  rawElements[i] = str.charCodeAt(i);
791
1226
  }
792
1227
 
793
1228
  return makeArray(scope, {
794
1229
  rawElements
795
- }, global, name, false, 'i16');
1230
+ }, global, name, false, 'i16')[0];
796
1231
 
797
1232
  default:
798
1233
  return todo(`cannot generate literal of type ${typeof decl.value}`);
@@ -802,7 +1237,8 @@ const generateLiteral = (scope, decl, global, name) => {
802
1237
  const countLeftover = wasm => {
803
1238
  let count = 0, depth = 0;
804
1239
 
805
- for (const inst of wasm) {
1240
+ for (let i = 0; i < wasm.length; i++) {
1241
+ const inst = wasm[i];
806
1242
  if (depth === 0 && (inst[0] === Opcodes.if || inst[0] === Opcodes.block || inst[0] === Opcodes.loop)) {
807
1243
  if (inst[0] === Opcodes.if) count--;
808
1244
  if (inst[1] !== Blocktype.void) count++;
@@ -811,11 +1247,12 @@ const countLeftover = wasm => {
811
1247
  if (inst[0] === Opcodes.end) depth--;
812
1248
 
813
1249
  if (depth === 0)
814
- if ([Opcodes.throw, Opcodes.return, Opcodes.drop, Opcodes.local_set, Opcodes.global_set].includes(inst[0])) count--;
1250
+ if ([Opcodes.throw,Opcodes.drop, Opcodes.local_set, Opcodes.global_set].includes(inst[0])) count--;
815
1251
  else if ([null, Opcodes.i32_eqz, Opcodes.i64_eqz, Opcodes.f64_ceil, Opcodes.f64_floor, Opcodes.f64_trunc, Opcodes.f64_nearest, Opcodes.f64_sqrt, Opcodes.local_tee, Opcodes.i32_wrap_i64, Opcodes.i64_extend_i32_s, Opcodes.i64_extend_i32_u, Opcodes.f32_demote_f64, Opcodes.f64_promote_f32, Opcodes.f64_convert_i32_s, Opcodes.f64_convert_i32_u, Opcodes.i32_clz, Opcodes.i32_ctz, Opcodes.i32_popcnt, Opcodes.f64_neg, Opcodes.end, Opcodes.i32_trunc_sat_f64_s[0], Opcodes.i32x4_extract_lane, Opcodes.i16x8_extract_lane, Opcodes.i32_load, Opcodes.i64_load, Opcodes.f64_load, Opcodes.v128_load, Opcodes.i32_load16_u, Opcodes.i32_load16_s, Opcodes.memory_grow].includes(inst[0]) && (inst[0] !== 0xfc || inst[1] < 0x0a)) {}
816
1252
  else if ([Opcodes.local_get, Opcodes.global_get, Opcodes.f64_const, Opcodes.i32_const, Opcodes.i64_const, Opcodes.v128_const].includes(inst[0])) count++;
817
1253
  else if ([Opcodes.i32_store, Opcodes.i64_store, Opcodes.f64_store, Opcodes.i32_store16].includes(inst[0])) count -= 2;
818
1254
  else if (Opcodes.memory_copy[0] === inst[0] && Opcodes.memory_copy[1] === inst[1]) count -= 3;
1255
+ else if (inst[0] === Opcodes.return) count = 0;
819
1256
  else if (inst[0] === Opcodes.call) {
820
1257
  let func = funcs.find(x => x.index === inst[1]);
821
1258
  if (func) {
@@ -823,6 +1260,8 @@ const countLeftover = wasm => {
823
1260
  } else count--;
824
1261
  if (func) count += func.returns.length;
825
1262
  } else count--;
1263
+
1264
+ // console.log(count, decompile([ inst ]).slice(0, -1));
826
1265
  }
827
1266
 
828
1267
  return count;
@@ -843,7 +1282,7 @@ const generateExp = (scope, decl) => {
843
1282
  return out;
844
1283
  };
845
1284
 
846
- const arrayUtil = {
1285
+ const CTArrayUtil = {
847
1286
  getLengthI32: pointer => [
848
1287
  ...number(0, Valtype.i32),
849
1288
  [ Opcodes.i32_load, Math.log2(ValtypeSize.i32) - 1, ...unsignedLEB128(pointer) ]
@@ -869,6 +1308,32 @@ const arrayUtil = {
869
1308
  ]
870
1309
  };
871
1310
 
1311
+ const RTArrayUtil = {
1312
+ getLengthI32: pointer => [
1313
+ ...pointer,
1314
+ [ Opcodes.i32_load, Math.log2(ValtypeSize.i32) - 1, 0 ]
1315
+ ],
1316
+
1317
+ getLength: pointer => [
1318
+ ...pointer,
1319
+ [ Opcodes.i32_load, Math.log2(ValtypeSize.i32) - 1, 0 ],
1320
+ Opcodes.i32_from_u
1321
+ ],
1322
+
1323
+ setLengthI32: (pointer, value) => [
1324
+ ...pointer,
1325
+ ...value,
1326
+ [ Opcodes.i32_store, Math.log2(ValtypeSize.i32) - 1, 0 ]
1327
+ ],
1328
+
1329
+ setLength: (pointer, value) => [
1330
+ ...pointer,
1331
+ ...value,
1332
+ Opcodes.i32_to_u,
1333
+ [ Opcodes.i32_store, Math.log2(ValtypeSize.i32) - 1, 0 ]
1334
+ ]
1335
+ };
1336
+
872
1337
  const generateCall = (scope, decl, _global, _name) => {
873
1338
  /* const callee = decl.callee;
874
1339
  const args = decl.arguments;
@@ -898,95 +1363,166 @@ const generateCall = (scope, decl, _global, _name) => {
898
1363
  const lastInst = out[out.length - 1];
899
1364
  if (lastInst && lastInst[0] === Opcodes.drop) {
900
1365
  out.splice(out.length - 1, 1);
1366
+
1367
+ const finalStatement = parsed.body[parsed.body.length - 1];
1368
+ out.push(
1369
+ ...getNodeType(scope, finalStatement),
1370
+ [ Opcodes.local_set, localTmp(scope, '#last_type', Valtype.i32) ]
1371
+ );
901
1372
  } else if (countLeftover(out) === 0) {
902
1373
  out.push(...number(UNDEFINED));
1374
+ out.push(
1375
+ ...number(TYPES.undefined, Valtype.i32),
1376
+ [ Opcodes.local_set, localTmp(scope, '#last_type', Valtype.i32) ]
1377
+ );
903
1378
  }
904
1379
 
1380
+ // if (lastInst && lastInst[0] === Opcodes.drop) {
1381
+ // out.splice(out.length - 1, 1);
1382
+ // } else if (countLeftover(out) === 0) {
1383
+ // out.push(...number(UNDEFINED));
1384
+ // }
1385
+
905
1386
  return out;
906
1387
  }
907
1388
 
908
- let out = [];
909
- let protoFunc, protoName, baseType, baseName = '$undeclared';
1389
+ let protoName, target;
910
1390
  // ident.func()
911
1391
  if (name && name.startsWith('__')) {
912
1392
  const spl = name.slice(2).split('_');
913
1393
 
914
- baseName = spl.slice(0, -1).join('_');
915
- baseType = getType(scope, baseName);
916
-
917
1394
  const func = spl[spl.length - 1];
918
- protoFunc = prototypeFuncs[baseType]?.[func] ?? Object.values(prototypeFuncs).map(x => x[func]).find(x => x);
919
1395
  protoName = func;
1396
+
1397
+ target = { ...decl.callee };
1398
+ target.name = spl.slice(0, -1).join('_');
920
1399
  }
921
1400
 
922
1401
  // literal.func()
923
1402
  if (!name && decl.callee.type === 'MemberExpression') {
924
- baseType = getNodeType(scope, decl.callee.object);
1403
+ // megahack for /regex/.func()
1404
+ if (decl.callee.object.regex) {
1405
+ const funcName = decl.callee.property.name;
1406
+ const func = Rhemyn[funcName](decl.callee.object.regex.pattern, currentFuncIndex++);
1407
+
1408
+ funcIndex[func.name] = func.index;
1409
+ funcs.push(func);
1410
+
1411
+ return [
1412
+ // make string arg
1413
+ ...generate(scope, decl.arguments[0]),
1414
+
1415
+ // call regex func
1416
+ Opcodes.i32_to_u,
1417
+ [ Opcodes.call, func.index ],
1418
+ Opcodes.i32_from_u,
1419
+
1420
+ ...number(TYPES.boolean, Valtype.i32),
1421
+ [ Opcodes.local_set, localTmp(scope, '#last_type', Valtype.i32) ]
1422
+ ];
1423
+ }
925
1424
 
926
1425
  const func = decl.callee.property.name;
927
- protoFunc = prototypeFuncs[baseType]?.[func] ?? Object.values(prototypeFuncs).map(x => x[func]).find(x => x);
928
1426
  protoName = func;
929
1427
 
930
- out = generate(scope, decl.callee.object);
931
- out.push([ Opcodes.drop ]);
1428
+ target = decl.callee.object;
932
1429
  }
933
1430
 
934
- if (protoFunc) {
935
- scope.memory = true;
1431
+ // if (protoName && baseType === TYPES.string && Rhemyn[protoName]) {
1432
+ // const func = Rhemyn[protoName](decl.arguments[0].regex.pattern, currentFuncIndex++);
936
1433
 
937
- let pointer = arrays.get(baseName);
1434
+ // funcIndex[func.name] = func.index;
1435
+ // funcs.push(func);
938
1436
 
939
- if (pointer == null) {
940
- // unknown dynamic pointer, so clone to new pointer which we know aot. now that's what I call inefficient™
941
- if (codeLog) log('codegen', 'cloning unknown dynamic pointer');
1437
+ // return [
1438
+ // generate(scope, decl.callee.object)
942
1439
 
943
- // register array
944
- makeArray(scope, {
945
- rawElements: new Array(0)
946
- }, _global, baseName, true, baseType === TYPES.string ? 'i16' : valtype);
947
- pointer = arrays.get(baseName);
1440
+ // // call regex func
1441
+ // [ Opcodes.call, func.index ],
1442
+ // Opcodes.i32_from_u
1443
+ // ];
1444
+ // }
948
1445
 
949
- const [ local, isGlobal ] = lookupName(scope, baseName);
1446
+ if (protoName) {
1447
+ const protoCands = Object.keys(prototypeFuncs).reduce((acc, x) => {
1448
+ const f = prototypeFuncs[x][protoName];
1449
+ if (f) acc[x] = f;
1450
+ return acc;
1451
+ }, {});
950
1452
 
951
- out = [
952
- // clone to new pointer
953
- ...number(pointer, Valtype.i32), // dst = new pointer
954
- [ isGlobal ? Opcodes.global_get : Opcodes.local_get, local.idx ], // src = unknown pointer
955
- Opcodes.i32_to_u,
956
- ...number(pageSize, Valtype.i32), // size = pagesize
1453
+ // no prototype function candidates, ignore
1454
+ if (Object.keys(protoCands).length > 0) {
1455
+ // use local for cached i32 length as commonly used
1456
+ const lengthLocal = localTmp(scope, '__proto_length_cache', Valtype.i32);
1457
+ const pointerLocal = localTmp(scope, '__proto_pointer_cache', Valtype.i32);
1458
+ const getPointer = [ [ Opcodes.local_get, pointerLocal ] ];
957
1459
 
958
- [ ...Opcodes.memory_copy, 0x00, 0x00 ],
959
- ];
960
- }
1460
+ // TODO: long-term, prototypes should be their individual separate funcs
1461
+
1462
+ let lengthI32CacheUsed = false;
1463
+ const protoBC = {};
1464
+ for (const x in protoCands) {
1465
+ const protoFunc = protoCands[x];
1466
+ if (protoFunc.noArgRetLength && decl.arguments.length === 0) {
1467
+ protoBC[x] = [
1468
+ ...RTArrayUtil.getLength(getPointer),
1469
+
1470
+ ...number(TYPES.number, Valtype.i32),
1471
+ [ Opcodes.local_set, localTmp(scope, '#last_type', Valtype.i32) ],
1472
+ ];
1473
+ continue;
1474
+ }
961
1475
 
962
- if (protoFunc.noArgRetLength && decl.arguments.length === 0) return arrayUtil.getLength(pointer)
1476
+ // const protoLocal = protoFunc.local ? localTmp(scope, `__${TYPE_NAMES[x]}_${protoName}_tmp`, protoFunc.local) : -1;
1477
+ // const protoLocal2 = protoFunc.local2 ? localTmp(scope, `__${TYPE_NAMES[x]}_${protoName}_tmp2`, protoFunc.local2) : -1;
1478
+ const protoLocal = protoFunc.local ? localTmp(scope, `__${protoName}_tmp`, protoFunc.local) : -1;
1479
+ const protoLocal2 = protoFunc.local2 ? localTmp(scope, `__${protoName}_tmp2`, protoFunc.local2) : -1;
1480
+
1481
+ const protoOut = protoFunc(getPointer, {
1482
+ getCachedI32: () => {
1483
+ lengthI32CacheUsed = true;
1484
+ return [ [ Opcodes.local_get, lengthLocal ] ];
1485
+ },
1486
+ setCachedI32: () => [ [ Opcodes.local_set, lengthLocal ] ],
1487
+ get: () => RTArrayUtil.getLength(getPointer),
1488
+ getI32: () => RTArrayUtil.getLengthI32(getPointer),
1489
+ set: value => RTArrayUtil.setLength(getPointer, value),
1490
+ setI32: value => RTArrayUtil.setLengthI32(getPointer, value)
1491
+ }, generate(scope, decl.arguments[0] ?? DEFAULT_VALUE), protoLocal, protoLocal2, (length, itemType) => {
1492
+ return makeArray(scope, {
1493
+ rawElements: new Array(length)
1494
+ }, _global, _name, true, itemType);
1495
+ });
1496
+
1497
+ protoBC[x] = [
1498
+ [ Opcodes.block, valtypeBinary ],
1499
+ ...protoOut,
1500
+
1501
+ ...number(protoFunc.returnType ?? TYPES.number, Valtype.i32),
1502
+ [ Opcodes.local_set, localTmp(scope, '#last_type', Valtype.i32) ],
1503
+ [ Opcodes.end ]
1504
+ ];
1505
+ }
963
1506
 
964
- let protoLocal = protoFunc.local ? localTmp(scope, `__${TYPE_NAMES[baseType]}_${protoName}_tmp`, protoFunc.local) : -1;
1507
+ return [
1508
+ ...generate(scope, target),
965
1509
 
966
- // use local for cached i32 length as commonly used
967
- let lengthLocal = localTmp(scope, '__proto_length_cache', Valtype.i32);
1510
+ Opcodes.i32_to_u,
1511
+ [ Opcodes.local_set, pointerLocal ],
968
1512
 
969
- return [
970
- ...out,
971
-
972
- ...arrayUtil.getLengthI32(pointer),
973
- [ Opcodes.local_set, lengthLocal ],
974
-
975
- [ Opcodes.block, valtypeBinary ],
976
- ...protoFunc(pointer, {
977
- cachedI32: [ [ Opcodes.local_get, lengthLocal ] ],
978
- get: arrayUtil.getLength(pointer),
979
- getI32: arrayUtil.getLengthI32(pointer),
980
- set: value => arrayUtil.setLength(pointer, value),
981
- setI32: value => arrayUtil.setLengthI32(pointer, value)
982
- }, generate(scope, decl.arguments[0] ?? DEFAULT_VALUE), protoLocal, (length, itemType) => {
983
- const out = makeArray(scope, {
984
- rawElements: new Array(length)
985
- }, _global, _name, true, itemType);
986
- return [ out, arrays.get(_name ?? '$undeclared') ];
987
- }),
988
- [ Opcodes.end ]
989
- ];
1513
+ ...(!lengthI32CacheUsed ? [] : [
1514
+ ...RTArrayUtil.getLengthI32(getPointer),
1515
+ [ Opcodes.local_set, lengthLocal ],
1516
+ ]),
1517
+
1518
+ ...typeSwitch(scope, getNodeType(scope, target), {
1519
+ ...protoBC,
1520
+
1521
+ // TODO: error better
1522
+ default: internalThrow(scope, 'TypeError', `'${protoName}' proto func tried to be called on a type without an impl`)
1523
+ }, valtypeBinary),
1524
+ ];
1525
+ }
990
1526
  }
991
1527
 
992
1528
  // TODO: only allows callee as literal
@@ -1030,34 +1566,50 @@ const generateCall = (scope, decl, _global, _name) => {
1030
1566
 
1031
1567
  const func = funcs.find(x => x.index === idx);
1032
1568
 
1569
+ const userFunc = (funcIndex[name] && !importedFuncs[name] && !builtinFuncs[name] && !internalConstrs[name]) || idx === -1;
1570
+ const paramCount = func && (userFunc ? func.params.length / 2 : func.params.length);
1571
+
1033
1572
  let args = decl.arguments;
1034
- if (func && args.length < func.params.length) {
1573
+ if (func && args.length < paramCount) {
1035
1574
  // too little args, push undefineds
1036
- args = args.concat(new Array(func.params.length - args.length).fill(DEFAULT_VALUE));
1575
+ args = args.concat(new Array(paramCount - args.length).fill(DEFAULT_VALUE));
1037
1576
  }
1038
1577
 
1039
- if (func && args.length > func.params.length) {
1578
+ if (func && args.length > paramCount) {
1040
1579
  // too many args, slice extras off
1041
- args = args.slice(0, func.params.length);
1580
+ args = args.slice(0, paramCount);
1042
1581
  }
1043
1582
 
1044
- if (func && func.memory) scope.memory = true;
1045
1583
  if (func && func.throws) scope.throws = true;
1046
1584
 
1585
+ let out = [];
1047
1586
  for (const arg of args) {
1048
- out.push(...generate(scope, arg));
1587
+ out = out.concat(generate(scope, arg));
1588
+ if (userFunc) out = out.concat(getNodeType(scope, arg));
1049
1589
  }
1050
1590
 
1051
1591
  out.push([ Opcodes.call, idx ]);
1052
1592
 
1593
+ if (!userFunc) {
1594
+ // let type;
1595
+ // if (builtinFuncs[name]) type = TYPES[builtinFuncs[name].returnType ?? 'number'];
1596
+ // if (internalConstrs[name]) type = internalConstrs[name].type;
1597
+ // if (importedFuncs[name] && importedFuncs[]) type =
1598
+
1599
+ // if (type) out.push(
1600
+ // ...number(type, Valtype.i32),
1601
+ // [ Opcodes.local_set, localTmp(scope, '#last_type', Valtype.i32) ]
1602
+ // );
1603
+ } else out.push([ Opcodes.local_set, localTmp(scope, '#last_type', Valtype.i32) ]);
1604
+
1053
1605
  return out;
1054
1606
  };
1055
1607
 
1056
1608
  const generateNew = (scope, decl, _global, _name) => {
1057
1609
  // hack: basically treat this as a normal call for builtins for now
1058
1610
  const name = mapName(decl.callee.name);
1059
- if (internalConstrs[name]) return internalConstrs[name].generate(scope, decl, _global, _name);
1060
- if (!builtinFuncs[name]) return todo(`new statement is not supported yet (new ${unhackName(name)})`);
1611
+ if (internalConstrs[name] && !internalConstrs[name].notConstr) return internalConstrs[name].generate(scope, decl, _global, _name);
1612
+ if (!builtinFuncs[name]) return todo(`new statement is not supported yet`); // return todo(`new statement is not supported yet (new ${unhackName(name)})`);
1061
1613
 
1062
1614
  return generateCall(scope, decl, _global, _name);
1063
1615
  };
@@ -1073,14 +1625,67 @@ const unhackName = name => {
1073
1625
  return name;
1074
1626
  };
1075
1627
 
1628
+ const typeSwitch = (scope, type, bc, returns = valtypeBinary) => {
1629
+ const tmp = localTmp(scope, '#typeswitch_tmp', Valtype.i32);
1630
+
1631
+ const out = [
1632
+ ...type,
1633
+ [ Opcodes.local_set, tmp ],
1634
+ [ Opcodes.block, returns ]
1635
+ ];
1636
+
1637
+ // todo: use br_table?
1638
+
1639
+ for (const x in bc) {
1640
+ if (x === 'default') continue;
1641
+
1642
+ // if type == x
1643
+ out.push([ Opcodes.local_get, tmp ]);
1644
+ out.push(...number(x, Valtype.i32));
1645
+ out.push([ Opcodes.i32_eq ]);
1646
+
1647
+ out.push([ Opcodes.if, Blocktype.void, `TYPESWITCH|${TYPE_NAMES[x]}` ]);
1648
+ out.push(...bc[x]);
1649
+ out.push([ Opcodes.br, 1 ]);
1650
+ out.push([ Opcodes.end ]);
1651
+ }
1652
+
1653
+ // default
1654
+ if (bc.default) out.push(...bc.default);
1655
+ else if (returns !== Blocktype.void) out.push(...number(0, returns));
1656
+
1657
+ out.push([ Opcodes.end, 'TYPESWITCH_end' ]);
1658
+
1659
+ return out;
1660
+ };
1661
+
1662
+ const allocVar = (scope, name, global = false) => {
1663
+ const target = global ? globals : scope.locals;
1664
+
1665
+ // already declared
1666
+ if (target[name]) {
1667
+ // parser should catch this but sanity check anyway
1668
+ // if (decl.kind !== 'var') return internalThrow(scope, 'SyntaxError', `Identifier '${unhackName(name)}' has already been declared`);
1669
+
1670
+ return target[name].idx;
1671
+ }
1672
+
1673
+ let idx = global ? globalInd++ : scope.localInd++;
1674
+ target[name] = { idx, type: valtypeBinary };
1675
+
1676
+ let typeIdx = global ? globalInd++ : scope.localInd++;
1677
+ target[name + '#type'] = { idx: typeIdx, type: Valtype.i32 };
1678
+
1679
+ return idx;
1680
+ };
1681
+
1076
1682
  const generateVar = (scope, decl) => {
1077
- const out = [];
1683
+ let out = [];
1078
1684
 
1079
1685
  const topLevel = scope.name === 'main';
1080
1686
 
1081
1687
  // global variable if in top scope (main) and var ..., or if wanted
1082
- const global = decl.kind === 'var';
1083
- const target = global ? globals : scope.locals;
1688
+ const global = topLevel || decl._bare; // decl.kind === 'var';
1084
1689
 
1085
1690
  for (const x of decl.declarations) {
1086
1691
  const name = mapName(x.id.name);
@@ -1100,46 +1705,16 @@ const generateVar = (scope, decl) => {
1100
1705
  continue; // always ignore
1101
1706
  }
1102
1707
 
1103
- let idx;
1104
- // already declared
1105
- if (target[name]) {
1106
- // parser should catch this but sanity check anyway
1107
- if (decl.kind !== 'var') return internalThrow(scope, 'SyntaxError', `Identifier '${unhackName(name)}' has already been declared`);
1108
-
1109
- idx = target[name].idx;
1110
- } else {
1111
- idx = global ? globalInd++ : scope.localInd++;
1112
- target[name] = { idx, type: valtypeBinary };
1113
- }
1114
-
1115
- typeStates[name] = x.init ? getNodeType(scope, x.init) : TYPES.undefined;
1116
-
1117
- // x.init ??= DEFAULT_VALUE;
1708
+ let idx = allocVar(scope, name, global);
1118
1709
  if (x.init) {
1119
- out.push(...generate(scope, x.init, global, name));
1120
-
1121
- // if our value is the result of a function, infer the type from that func's return value
1122
- if (out[out.length - 1][0] === Opcodes.call) {
1123
- const ind = out[out.length - 1][1];
1124
- if (ind >= importedFuncs.length) { // not an imported func
1125
- const func = funcs.find(x => x.index === ind);
1126
- if (!func) throw new Error('could not find func being called as var value to infer type'); // sanity check
1127
-
1128
- const returns = func.returns;
1129
- if (returns.length > 1) throw new Error('func returning >1 value being set as 1 local'); // sanity check
1130
-
1131
- target[name].type = func.returns[0];
1132
- if (target[name].type === Valtype.v128) {
1133
- // specify vec subtype inferred from first vec type in function name
1134
- target[name].vecType = func.name.split('_').find(x => x.includes('x'));
1135
- }
1136
- } else {
1137
- // we do not have imports that return yet, ignore for now
1138
- }
1139
- }
1710
+ out = out.concat(generate(scope, x.init, global, name));
1140
1711
 
1141
1712
  out.push([ global ? Opcodes.global_set : Opcodes.local_set, idx ]);
1713
+ out.push(...setType(scope, name, getNodeType(scope, x.init)));
1142
1714
  }
1715
+
1716
+ // hack: this follows spec properly but is mostly unneeded 😅
1717
+ // out.push(...setType(scope, name, x.init ? getNodeType(scope, x.init) : TYPES.undefined));
1143
1718
  }
1144
1719
 
1145
1720
  return out;
@@ -1165,8 +1740,6 @@ const generateAssign = (scope, decl) => {
1165
1740
  const name = decl.left.object.name;
1166
1741
  const pointer = arrays.get(name);
1167
1742
 
1168
- scope.memory = true;
1169
-
1170
1743
  const aotPointer = pointer != null;
1171
1744
 
1172
1745
  const newValueTmp = localTmp(scope, '__length_setter_tmp');
@@ -1177,7 +1750,7 @@ const generateAssign = (scope, decl) => {
1177
1750
  Opcodes.i32_to_u
1178
1751
  ]),
1179
1752
 
1180
- ...generate(scope, decl.right, false, name),
1753
+ ...generate(scope, decl.right),
1181
1754
  [ Opcodes.local_tee, newValueTmp ],
1182
1755
 
1183
1756
  Opcodes.i32_to_u,
@@ -1187,13 +1760,76 @@ const generateAssign = (scope, decl) => {
1187
1760
  ];
1188
1761
  }
1189
1762
 
1763
+ const op = decl.operator.slice(0, -1) || '=';
1764
+
1765
+ // arr[i]
1766
+ if (decl.left.type === 'MemberExpression' && decl.left.computed) {
1767
+ const name = decl.left.object.name;
1768
+ const pointer = arrays.get(name);
1769
+
1770
+ const aotPointer = pointer != null;
1771
+
1772
+ const newValueTmp = localTmp(scope, '__member_setter_val_tmp');
1773
+ const pointerTmp = op === '=' ? -1 : localTmp(scope, '__member_setter_ptr_tmp', Valtype.i32);
1774
+
1775
+ return [
1776
+ ...typeSwitch(scope, getNodeType(scope, decl.left.object), {
1777
+ [TYPES._array]: [
1778
+ ...(aotPointer ? [] : [
1779
+ ...generate(scope, decl.left.object),
1780
+ Opcodes.i32_to_u
1781
+ ]),
1782
+
1783
+ // get index as valtype
1784
+ ...generate(scope, decl.left.property),
1785
+ Opcodes.i32_to_u,
1786
+
1787
+ // turn into byte offset by * valtypeSize (4 for i32, 8 for i64/f64)
1788
+ ...number(ValtypeSize[valtype], Valtype.i32),
1789
+ [ Opcodes.i32_mul ],
1790
+ ...(aotPointer ? [] : [ [ Opcodes.i32_add ] ]),
1791
+ ...(op === '=' ? [] : [ [ Opcodes.local_tee, pointerTmp ] ]),
1792
+
1793
+ ...(op === '=' ? generate(scope, decl.right) : performOp(scope, op, [
1794
+ [ Opcodes.local_get, pointerTmp ],
1795
+ [ Opcodes.load, Math.log2(ValtypeSize[valtype]) - 1, ...unsignedLEB128((aotPointer ? pointer : 0) + ValtypeSize.i32) ]
1796
+ ], generate(scope, decl.right), number(TYPES.number, Valtype.i32), getNodeType(scope, decl.right), false, name, true)),
1797
+ [ Opcodes.local_tee, newValueTmp ],
1798
+
1799
+ [ Opcodes.store, Math.log2(ValtypeSize[valtype]) - 1, ...unsignedLEB128((aotPointer ? pointer : 0) + ValtypeSize.i32) ]
1800
+ ],
1801
+
1802
+ default: internalThrow(scope, 'TypeError', `Cannot assign member with non-array`)
1803
+
1804
+ // [TYPES.string]: [
1805
+ // // turn into byte offset by * sizeof i16
1806
+ // ...number(ValtypeSize.i16, Valtype.i32),
1807
+ // [ Opcodes.i32_mul ],
1808
+ // ...(aotPointer ? [] : [ [ Opcodes.i32_add ] ]),
1809
+ // ...(op === '=' ? [] : [ [ Opcodes.local_tee, pointerTmp ] ]),
1810
+
1811
+ // ...(op === '=' ? generate(scope, decl.right) : performOp(scope, op, [
1812
+ // [ Opcodes.local_get, pointerTmp ],
1813
+ // [ Opcodes.load, Math.log2(ValtypeSize[valtype]) - 1, ...unsignedLEB128((aotPointer ? pointer : 0) + ValtypeSize.i32) ]
1814
+ // ], generate(scope, decl.right), number(TYPES.string, Valtype.i32), getNodeType(scope, decl.right))),
1815
+ // [ Opcodes.local_tee, newValueTmp ],
1816
+
1817
+ // Opcodes.i32_to_u,
1818
+ // [ StoreOps.i16, Math.log2(ValtypeSize.i16) - 1, ...unsignedLEB128((aotPointer ? pointer : 0) + ValtypeSize.i32) ]
1819
+ // ]
1820
+ }, Blocktype.void),
1821
+
1822
+ [ Opcodes.local_get, newValueTmp ]
1823
+ ];
1824
+ }
1825
+
1190
1826
  const [ local, isGlobal ] = lookupName(scope, name);
1191
1827
 
1192
1828
  if (local === undefined) {
1193
- // todo: this should be a devtools/repl/??? only thing
1829
+ // todo: this should be a sloppy mode only thing
1194
1830
 
1195
1831
  // only allow = for this
1196
- if (decl.operator !== '=') return internalThrow(scope, 'ReferenceError', `${unhackName(name)} is not defined`);
1832
+ if (op !== '=') return internalThrow(scope, 'ReferenceError', `${unhackName(name)} is not defined`);
1197
1833
 
1198
1834
  if (builtinVars[name]) {
1199
1835
  // just return rhs (eg `NaN = 2`)
@@ -1202,25 +1838,53 @@ const generateAssign = (scope, decl) => {
1202
1838
 
1203
1839
  // set global and return (eg a = 2)
1204
1840
  return [
1205
- ...generateVar(scope, { kind: 'var', declarations: [ { id: { name }, init: decl.right } ] }),
1841
+ ...generateVar(scope, { kind: 'var', _bare: true, declarations: [ { id: { name }, init: decl.right } ] }),
1206
1842
  [ Opcodes.global_get, globals[name].idx ]
1207
1843
  ];
1208
1844
  }
1209
1845
 
1210
- if (decl.operator === '=') {
1211
- typeStates[name] = getNodeType(scope, decl.right);
1212
-
1846
+ if (op === '=') {
1213
1847
  return [
1214
1848
  ...generate(scope, decl.right, isGlobal, name),
1215
1849
  [ isGlobal ? Opcodes.global_set : Opcodes.local_set, local.idx ],
1216
- [ isGlobal ? Opcodes.global_get : Opcodes.local_get, local.idx ]
1850
+ [ isGlobal ? Opcodes.global_get : Opcodes.local_get, local.idx ],
1851
+
1852
+ ...setType(scope, name, getNodeType(scope, decl.right))
1853
+ ];
1854
+ }
1855
+
1856
+ if (op === '||' || op === '&&' || op === '??') {
1857
+ // todo: is this needed?
1858
+ // for logical assignment ops, it is not left @= right ~= left = left @ right
1859
+ // instead, left @ (left = right)
1860
+ // eg, x &&= y ~= x && (x = y)
1861
+
1862
+ return [
1863
+ ...performOp(scope, op, [
1864
+ [ isGlobal ? Opcodes.global_get : Opcodes.local_get, local.idx ]
1865
+ ], [
1866
+ ...generate(scope, decl.right),
1867
+ [ isGlobal ? Opcodes.global_set : Opcodes.local_set, local.idx ],
1868
+ [ isGlobal ? Opcodes.global_get : Opcodes.local_get, local.idx ]
1869
+ ], getType(scope, name), getNodeType(scope, decl.right), isGlobal, name, true),
1870
+ [ isGlobal ? Opcodes.global_get : Opcodes.local_get, local.idx ],
1871
+
1872
+ [ Opcodes.local_get, localTmp(scope, '#last_type', Valtype.i32) ],
1873
+ // hack: type is idx+1
1874
+ [ isGlobal ? Opcodes.global_set : Opcodes.local_set, local.idx + 1 ],
1217
1875
  ];
1218
1876
  }
1219
1877
 
1220
1878
  return [
1221
- ...performOp(scope, decl.operator.slice(0, -1), [ [ isGlobal ? Opcodes.global_get : Opcodes.local_get, local.idx ] ], generate(scope, decl.right), getType(scope, name), getNodeType(scope, decl.right), isGlobal, name, true),
1879
+ ...performOp(scope, op, [ [ isGlobal ? Opcodes.global_get : Opcodes.local_get, local.idx ] ], generate(scope, decl.right), getType(scope, name), getNodeType(scope, decl.right), isGlobal, name, true),
1222
1880
  [ isGlobal ? Opcodes.global_set : Opcodes.local_set, local.idx ],
1223
- [ isGlobal ? Opcodes.global_get : Opcodes.local_get, local.idx ]
1881
+ [ isGlobal ? Opcodes.global_get : Opcodes.local_get, local.idx ],
1882
+
1883
+ // todo: string concat types
1884
+
1885
+ // hack: type is idx+1
1886
+ ...number(TYPES.number, Valtype.i32),
1887
+ [ isGlobal ? Opcodes.global_set : Opcodes.local_set, local.idx + 1 ],
1224
1888
  ];
1225
1889
  };
1226
1890
 
@@ -1245,13 +1909,14 @@ const generateUnary = (scope, decl) => {
1245
1909
 
1246
1910
  case '!':
1247
1911
  // !=
1248
- return falsy(scope, generate(scope, decl.argument));
1912
+ return falsy(scope, generate(scope, decl.argument), getNodeType(scope, decl.argument), false, false);
1249
1913
 
1250
1914
  case '~':
1915
+ // todo: does not handle Infinity properly (should convert to 0) (but opt const converting saves us sometimes)
1251
1916
  return [
1252
1917
  ...generate(scope, decl.argument),
1253
1918
  Opcodes.i32_to,
1254
- [ Opcodes.i32_const, signedLEB128(-1) ],
1919
+ [ Opcodes.i32_const, ...signedLEB128(-1) ],
1255
1920
  [ Opcodes.i32_xor ],
1256
1921
  Opcodes.i32_from
1257
1922
  ];
@@ -1289,11 +1954,16 @@ const generateUnary = (scope, decl) => {
1289
1954
  return out;
1290
1955
 
1291
1956
  case 'typeof':
1292
- const type = getNodeType(scope, decl.argument);
1957
+ return typeSwitch(scope, getNodeType(scope, decl.argument), {
1958
+ [TYPES.number]: makeString(scope, 'number', false, '#typeof_result'),
1959
+ [TYPES.boolean]: makeString(scope, 'boolean', false, '#typeof_result'),
1960
+ [TYPES.string]: makeString(scope, 'string', false, '#typeof_result'),
1961
+ [TYPES.undefined]: makeString(scope, 'undefined', false, '#typeof_result'),
1962
+ [TYPES.function]: makeString(scope, 'function', false, '#typeof_result'),
1293
1963
 
1294
- // for custom types, just return object
1295
- if (type > 0xffffffffffff7) return number(TYPES.object);
1296
- return number(type);
1964
+ // object and internal types
1965
+ default: makeString(scope, 'object', false, '#typeof_result'),
1966
+ });
1297
1967
 
1298
1968
  default:
1299
1969
  return todo(`unary operator ${decl.operator} not implemented yet`);
@@ -1332,9 +2002,9 @@ const generateUpdate = (scope, decl) => {
1332
2002
  };
1333
2003
 
1334
2004
  const generateIf = (scope, decl) => {
1335
- const out = truthy(scope, generate(scope, decl.test), decl.test);
2005
+ const out = truthy(scope, generate(scope, decl.test), getNodeType(scope, decl.test), false, true);
1336
2006
 
1337
- out.push(Opcodes.i32_to, [ Opcodes.if, Blocktype.void ]);
2007
+ out.push([ Opcodes.if, Blocktype.void ]);
1338
2008
  depth.push('if');
1339
2009
 
1340
2010
  const consOut = generate(scope, decl.consequent);
@@ -1356,16 +2026,28 @@ const generateIf = (scope, decl) => {
1356
2026
  };
1357
2027
 
1358
2028
  const generateConditional = (scope, decl) => {
1359
- const out = [ ...generate(scope, decl.test) ];
2029
+ const out = truthy(scope, generate(scope, decl.test), getNodeType(scope, decl.test), false, true);
1360
2030
 
1361
- out.push(Opcodes.i32_to, [ Opcodes.if, valtypeBinary ]);
2031
+ out.push([ Opcodes.if, valtypeBinary ]);
1362
2032
  depth.push('if');
1363
2033
 
1364
2034
  out.push(...generate(scope, decl.consequent));
1365
2035
 
2036
+ // note type
2037
+ out.push(
2038
+ ...getNodeType(scope, decl.consequent),
2039
+ [ Opcodes.local_set, localTmp(scope, '#last_type', Valtype.i32) ]
2040
+ );
2041
+
1366
2042
  out.push([ Opcodes.else ]);
1367
2043
  out.push(...generate(scope, decl.alternate));
1368
2044
 
2045
+ // note type
2046
+ out.push(
2047
+ ...getNodeType(scope, decl.alternate),
2048
+ [ Opcodes.local_set, localTmp(scope, '#last_type', Valtype.i32) ]
2049
+ );
2050
+
1369
2051
  out.push([ Opcodes.end ]);
1370
2052
  depth.pop();
1371
2053
 
@@ -1422,9 +2104,148 @@ const generateWhile = (scope, decl) => {
1422
2104
  return out;
1423
2105
  };
1424
2106
 
2107
+ const generateForOf = (scope, decl) => {
2108
+ const out = [];
2109
+
2110
+ // todo: for of inside for of might fuck up?
2111
+ const pointer = localTmp(scope, 'forof_base_pointer', Valtype.i32);
2112
+ const length = localTmp(scope, 'forof_length', Valtype.i32);
2113
+ const counter = localTmp(scope, 'forof_counter', Valtype.i32);
2114
+
2115
+ out.push(
2116
+ // set pointer as right
2117
+ ...generate(scope, decl.right),
2118
+ Opcodes.i32_to_u,
2119
+ [ Opcodes.local_set, pointer ],
2120
+
2121
+ // set counter as 0 (could be already used)
2122
+ ...number(0, Valtype.i32),
2123
+ [ Opcodes.local_set, counter ],
2124
+
2125
+ // get length
2126
+ [ Opcodes.local_get, pointer ],
2127
+ [ Opcodes.i32_load, Math.log2(ValtypeSize.i32) - 1, 0 ],
2128
+ [ Opcodes.local_set, length ]
2129
+ );
2130
+
2131
+ depth.push('forof');
2132
+
2133
+ // setup local for left
2134
+ generate(scope, decl.left);
2135
+
2136
+ const leftName = decl.left.declarations[0].id.name;
2137
+ const [ local, isGlobal ] = lookupName(scope, leftName);
2138
+
2139
+ depth.push('block');
2140
+ depth.push('block');
2141
+
2142
+ // // todo: we should only do this for strings but we don't know at compile-time :(
2143
+ // hack: this is naughty and will break things!
2144
+ let newOut = number(0, Valtype.f64), newPointer = -1;
2145
+ if (pages.hasString) {
2146
+ 0, [ newOut, newPointer ] = makeArray(scope, {
2147
+ rawElements: new Array(1)
2148
+ }, isGlobal, leftName, true, 'i16');
2149
+ }
2150
+
2151
+ // set type for local
2152
+ out.push(...typeSwitch(scope, getNodeType(scope, decl.right), {
2153
+ [TYPES._array]: [
2154
+ ...setType(scope, leftName, TYPES.number),
2155
+
2156
+ [ Opcodes.loop, Blocktype.void ],
2157
+
2158
+ [ Opcodes.local_get, pointer ],
2159
+ [ Opcodes.load, Math.log2(ValtypeSize[valtype]) - 1, ...unsignedLEB128(ValtypeSize.i32) ],
2160
+
2161
+ [ isGlobal ? Opcodes.global_set : Opcodes.local_set, local.idx ],
2162
+
2163
+ [ Opcodes.block, Blocktype.void ],
2164
+ [ Opcodes.block, Blocktype.void ],
2165
+ ...generate(scope, decl.body),
2166
+ [ Opcodes.end ],
2167
+
2168
+ // increment iter pointer by valtype size
2169
+ [ Opcodes.local_get, pointer ],
2170
+ ...number(ValtypeSize[valtype], Valtype.i32),
2171
+ [ Opcodes.i32_add ],
2172
+ [ Opcodes.local_set, pointer ],
2173
+
2174
+ // increment counter by 1
2175
+ [ Opcodes.local_get, counter ],
2176
+ ...number(1, Valtype.i32),
2177
+ [ Opcodes.i32_add ],
2178
+ [ Opcodes.local_tee, counter ],
2179
+
2180
+ // loop if counter != length
2181
+ [ Opcodes.local_get, length ],
2182
+ [ Opcodes.i32_ne ],
2183
+ [ Opcodes.br_if, 1 ],
2184
+
2185
+ [ Opcodes.end ],
2186
+ [ Opcodes.end ]
2187
+ ],
2188
+ [TYPES.string]: [
2189
+ ...setType(scope, leftName, TYPES.string),
2190
+
2191
+ [ Opcodes.loop, Blocktype.void ],
2192
+
2193
+ // setup new/out array
2194
+ ...newOut,
2195
+ [ Opcodes.drop ],
2196
+
2197
+ ...number(0, Valtype.i32), // base 0 for store after
2198
+
2199
+ // load current string ind {arg}
2200
+ [ Opcodes.local_get, pointer ],
2201
+ [ Opcodes.i32_load16_u, Math.log2(ValtypeSize.i16) - 1, ...unsignedLEB128(ValtypeSize.i32) ],
2202
+
2203
+ // store to new string ind 0
2204
+ [ Opcodes.i32_store16, Math.log2(ValtypeSize.i16) - 1, ...unsignedLEB128(newPointer + ValtypeSize.i32) ],
2205
+
2206
+ // return new string (page)
2207
+ ...number(newPointer),
2208
+
2209
+ [ isGlobal ? Opcodes.global_set : Opcodes.local_set, local.idx ],
2210
+
2211
+ [ Opcodes.block, Blocktype.void ],
2212
+ [ Opcodes.block, Blocktype.void ],
2213
+ ...generate(scope, decl.body),
2214
+ [ Opcodes.end ],
2215
+
2216
+ // increment iter pointer by valtype size
2217
+ [ Opcodes.local_get, pointer ],
2218
+ ...number(ValtypeSize.i16, Valtype.i32),
2219
+ [ Opcodes.i32_add ],
2220
+ [ Opcodes.local_set, pointer ],
2221
+
2222
+ // increment counter by 1
2223
+ [ Opcodes.local_get, counter ],
2224
+ ...number(1, Valtype.i32),
2225
+ [ Opcodes.i32_add ],
2226
+ [ Opcodes.local_tee, counter ],
2227
+
2228
+ // loop if counter != length
2229
+ [ Opcodes.local_get, length ],
2230
+ [ Opcodes.i32_ne ],
2231
+ [ Opcodes.br_if, 1 ],
2232
+
2233
+ [ Opcodes.end ],
2234
+ [ Opcodes.end ]
2235
+ ],
2236
+ default: internalThrow(scope, 'TypeError', `Tried for..of on non-iterable type`)
2237
+ }, Blocktype.void));
2238
+
2239
+ depth.pop();
2240
+ depth.pop();
2241
+ depth.pop();
2242
+
2243
+ return out;
2244
+ };
2245
+
1425
2246
  const getNearestLoop = () => {
1426
2247
  for (let i = depth.length - 1; i >= 0; i--) {
1427
- if (depth[i] === 'while' || depth[i] === 'for') return i;
2248
+ if (depth[i] === 'while' || depth[i] === 'for' || depth[i] === 'forof') return i;
1428
2249
  }
1429
2250
 
1430
2251
  return -1;
@@ -1508,13 +2329,25 @@ const generateAssignPat = (scope, decl) => {
1508
2329
  };
1509
2330
 
1510
2331
  let pages = new Map();
1511
- const allocPage = reason => {
1512
- if (pages.has(reason)) return pages.get(reason);
2332
+ const allocPage = (reason, type) => {
2333
+ if (pages.has(reason)) return pages.get(reason).ind;
2334
+
2335
+ if (reason.startsWith('array:')) pages.hasArray = true;
2336
+ if (reason.startsWith('string:')) pages.hasString = true;
2337
+
2338
+ const ind = pages.size;
2339
+ pages.set(reason, { ind, type });
2340
+
2341
+ if (allocLog) log('alloc', `allocated new page of memory (${ind}) | ${reason} (type: ${type})`);
2342
+
2343
+ return ind;
2344
+ };
1513
2345
 
1514
- let ind = pages.size;
1515
- pages.set(reason, ind);
2346
+ const freePage = reason => {
2347
+ const { ind } = pages.get(reason);
2348
+ pages.delete(reason);
1516
2349
 
1517
- if (codeLog) log('codegen', `allocated new page of memory (${ind}) | ${reason}`);
2350
+ if (allocLog) log('alloc', `freed page of memory (${ind}) | ${reason}`);
1518
2351
 
1519
2352
  return ind;
1520
2353
  };
@@ -1528,7 +2361,7 @@ const itemTypeToValtype = {
1528
2361
  i16: 'i32'
1529
2362
  };
1530
2363
 
1531
- const storeOps = {
2364
+ const StoreOps = {
1532
2365
  i32: Opcodes.i32_store,
1533
2366
  i64: Opcodes.i64_store,
1534
2367
  f64: Opcodes.f64_store,
@@ -1537,13 +2370,32 @@ const storeOps = {
1537
2370
  i16: Opcodes.i32_store16
1538
2371
  };
1539
2372
 
2373
+ let data = [];
2374
+
2375
+ const compileBytes = (val, itemType, signed = true) => {
2376
+ // todo: this is a mess and needs confirming / ????
2377
+ switch (itemType) {
2378
+ case 'i8': return [ val % 256 ];
2379
+ case 'i16': return [ val % 256, Math.floor(val / 256) ];
2380
+
2381
+ case 'i32':
2382
+ case 'i64':
2383
+ return enforceFourBytes(signedLEB128(val));
2384
+
2385
+ case 'f64': return ieee754_binary64(val);
2386
+ }
2387
+ };
2388
+
1540
2389
  const makeArray = (scope, decl, global = false, name = '$undeclared', initEmpty = false, itemType = valtype) => {
1541
2390
  const out = [];
1542
2391
 
2392
+ let firstAssign = false;
1543
2393
  if (!arrays.has(name) || name === '$undeclared') {
2394
+ firstAssign = true;
2395
+
1544
2396
  // todo: can we just have 1 undeclared array? probably not? but this is not really memory efficient
1545
2397
  const uniqueName = name === '$undeclared' ? name + Math.random().toString().slice(2) : name;
1546
- arrays.set(name, allocPage(`${itemType === 'i16' ? 'string' : 'array'}: ${uniqueName}`) * pageSize);
2398
+ arrays.set(name, allocPage(`${itemType === 'i16' ? 'string' : 'array'}: ${uniqueName}`, itemType) * pageSize);
1547
2399
  }
1548
2400
 
1549
2401
  const pointer = arrays.get(name);
@@ -1551,8 +2403,29 @@ const makeArray = (scope, decl, global = false, name = '$undeclared', initEmpty
1551
2403
  const useRawElements = !!decl.rawElements;
1552
2404
  const elements = useRawElements ? decl.rawElements : decl.elements;
1553
2405
 
2406
+ const valtype = itemTypeToValtype[itemType];
1554
2407
  const length = elements.length;
1555
2408
 
2409
+ if (firstAssign && useRawElements) {
2410
+ let bytes = compileBytes(length, 'i32');
2411
+
2412
+ if (!initEmpty) for (let i = 0; i < length; i++) {
2413
+ if (elements[i] == null) continue;
2414
+
2415
+ bytes.push(...compileBytes(elements[i], itemType));
2416
+ }
2417
+
2418
+ data.push({
2419
+ offset: pointer,
2420
+ bytes
2421
+ });
2422
+
2423
+ // local value as pointer
2424
+ out.push(...number(pointer));
2425
+
2426
+ return [ out, pointer ];
2427
+ }
2428
+
1556
2429
  // store length as 0th array
1557
2430
  out.push(
1558
2431
  ...number(0, Valtype.i32),
@@ -1560,8 +2433,7 @@ const makeArray = (scope, decl, global = false, name = '$undeclared', initEmpty
1560
2433
  [ Opcodes.i32_store, Math.log2(ValtypeSize.i32) - 1, ...unsignedLEB128(pointer) ]
1561
2434
  );
1562
2435
 
1563
- const storeOp = storeOps[itemType];
1564
- const valtype = itemTypeToValtype[itemType];
2436
+ const storeOp = StoreOps[itemType];
1565
2437
 
1566
2438
  if (!initEmpty) for (let i = 0; i < length; i++) {
1567
2439
  if (elements[i] == null) continue;
@@ -1576,30 +2448,34 @@ const makeArray = (scope, decl, global = false, name = '$undeclared', initEmpty
1576
2448
  // local value as pointer
1577
2449
  out.push(...number(pointer));
1578
2450
 
1579
- scope.memory = true;
2451
+ return [ out, pointer ];
2452
+ };
1580
2453
 
1581
- return out;
2454
+ const makeString = (scope, str, global = false, name = '$undeclared') => {
2455
+ const rawElements = new Array(str.length);
2456
+ for (let i = 0; i < str.length; i++) {
2457
+ rawElements[i] = str.charCodeAt(i);
2458
+ }
2459
+
2460
+ return makeArray(scope, {
2461
+ rawElements
2462
+ }, global, name, false, 'i16')[0];
1582
2463
  };
1583
2464
 
1584
2465
  let arrays = new Map();
1585
2466
  const generateArray = (scope, decl, global = false, name = '$undeclared', initEmpty = false) => {
1586
- return makeArray(scope, decl, global, name, initEmpty, valtype);
2467
+ return makeArray(scope, decl, global, name, initEmpty, valtype)[0];
1587
2468
  };
1588
2469
 
1589
2470
  export const generateMember = (scope, decl, _global, _name) => {
1590
- const type = getNodeType(scope, decl.object);
2471
+ const name = decl.object.name;
2472
+ const pointer = arrays.get(name);
2473
+
2474
+ const aotPointer = pointer != null;
1591
2475
 
1592
2476
  // hack: .length
1593
2477
  if (decl.property.name === 'length') {
1594
2478
  // if (![TYPES._array, TYPES.string].includes(type)) return number(UNDEFINED);
1595
-
1596
- const name = decl.object.name;
1597
- const pointer = arrays.get(name);
1598
-
1599
- scope.memory = true;
1600
-
1601
- const aotPointer = pointer != null;
1602
-
1603
2479
  return [
1604
2480
  ...(aotPointer ? number(0, Valtype.i32) : [
1605
2481
  ...generate(scope, decl.object),
@@ -1611,18 +2487,17 @@ export const generateMember = (scope, decl, _global, _name) => {
1611
2487
  ];
1612
2488
  }
1613
2489
 
1614
- // this is just for arr[ind] for now. objects are partially supported via object hack (a.b -> __a_b)
1615
- if (![TYPES._array, TYPES.string].includes(type)) return todo(`computed member expression for objects are not supported yet`);
1616
-
1617
- const name = decl.object.name;
1618
- const pointer = arrays.get(name);
1619
-
1620
- scope.memory = true;
1621
-
1622
- const aotPointer = pointer != null;
2490
+ // // todo: we should only do this for strings but we don't know at compile-time :(
2491
+ // hack: this is naughty and will break things!
2492
+ let newOut = number(0, Valtype.f64), newPointer = -1;
2493
+ if (pages.hasString) {
2494
+ 0, [ newOut, newPointer ] = makeArray(scope, {
2495
+ rawElements: new Array(1)
2496
+ }, _global, _name, true, 'i16');
2497
+ }
1623
2498
 
1624
- if (type === TYPES._array) {
1625
- return [
2499
+ return typeSwitch(scope, getNodeType(scope, decl.object), {
2500
+ [TYPES._array]: [
1626
2501
  // get index as valtype
1627
2502
  ...generate(scope, decl.property),
1628
2503
 
@@ -1638,45 +2513,46 @@ export const generateMember = (scope, decl, _global, _name) => {
1638
2513
  ]),
1639
2514
 
1640
2515
  // read from memory
1641
- [ Opcodes.load, Math.log2(ValtypeSize[valtype]) - 1, ...unsignedLEB128((aotPointer ? pointer : 0) + ValtypeSize.i32) ]
1642
- ];
1643
- }
2516
+ [ Opcodes.load, Math.log2(ValtypeSize[valtype]) - 1, ...unsignedLEB128((aotPointer ? pointer : 0) + ValtypeSize.i32) ],
1644
2517
 
1645
- // string
2518
+ ...number(TYPES.number, Valtype.i32),
2519
+ [ Opcodes.local_set, localTmp(scope, '#last_type', Valtype.i32) ]
2520
+ ],
1646
2521
 
1647
- const newOut = makeArray(scope, {
1648
- rawElements: new Array(1)
1649
- }, _global, _name, true, 'i16');
1650
- const newPointer = arrays.get(_name ?? '$undeclared');
2522
+ [TYPES.string]: [
2523
+ // setup new/out array
2524
+ ...newOut,
2525
+ [ Opcodes.drop ],
1651
2526
 
1652
- return [
1653
- // setup new/out array
1654
- ...newOut,
1655
- [ Opcodes.drop ],
2527
+ ...number(0, Valtype.i32), // base 0 for store later
1656
2528
 
1657
- ...number(0, Valtype.i32), // base 0 for store later
2529
+ ...generate(scope, decl.property),
1658
2530
 
1659
- ...generate(scope, decl.property),
2531
+ Opcodes.i32_to_u,
2532
+ ...number(ValtypeSize.i16, Valtype.i32),
2533
+ [ Opcodes.i32_mul ],
1660
2534
 
1661
- Opcodes.i32_to_u,
1662
- ...number(ValtypeSize.i16, Valtype.i32),
1663
- [ Opcodes.i32_mul ],
2535
+ ...(aotPointer ? [] : [
2536
+ ...generate(scope, decl.object),
2537
+ Opcodes.i32_to_u,
2538
+ [ Opcodes.i32_add ]
2539
+ ]),
1664
2540
 
1665
- ...(aotPointer ? [] : [
1666
- ...generate(scope, decl.object),
1667
- Opcodes.i32_to_u,
1668
- [ Opcodes.i32_add ]
1669
- ]),
2541
+ // load current string ind {arg}
2542
+ [ Opcodes.i32_load16_u, Math.log2(ValtypeSize.i16) - 1, ...unsignedLEB128((aotPointer ? pointer : 0) + ValtypeSize.i32) ],
1670
2543
 
1671
- // load current string ind {arg}
1672
- [ Opcodes.i32_load16_u, Math.log2(ValtypeSize.i16) - 1, ...unsignedLEB128((aotPointer ? pointer : 0) + ValtypeSize.i32) ],
2544
+ // store to new string ind 0
2545
+ [ Opcodes.i32_store16, Math.log2(ValtypeSize.i16) - 1, ...unsignedLEB128(newPointer + ValtypeSize.i32) ],
1673
2546
 
1674
- // store to new string ind 0
1675
- [ Opcodes.i32_store16, Math.log2(ValtypeSize.i16) - 1, ...unsignedLEB128(newPointer + ValtypeSize.i32) ],
2547
+ // return new string (page)
2548
+ ...number(newPointer),
1676
2549
 
1677
- // return new string (page)
1678
- ...number(newPointer)
1679
- ];
2550
+ ...number(TYPES.string, Valtype.i32),
2551
+ [ Opcodes.local_set, localTmp(scope, '#last_type', Valtype.i32) ]
2552
+ ],
2553
+
2554
+ default: [ [ Opcodes.unreachable ] ]
2555
+ });
1680
2556
  };
1681
2557
 
1682
2558
  const randId = () => Math.random().toString(16).slice(0, -4);
@@ -1728,15 +2604,14 @@ const generateFunc = (scope, decl) => {
1728
2604
  const innerScope = {
1729
2605
  locals: {},
1730
2606
  localInd: 0,
1731
- returns: [ valtypeBinary ],
1732
- memory: false,
2607
+ // value, type
2608
+ returns: [ valtypeBinary, Valtype.i32 ],
1733
2609
  throws: false,
1734
2610
  name
1735
2611
  };
1736
2612
 
1737
2613
  for (let i = 0; i < params.length; i++) {
1738
- const param = params[i];
1739
- innerScope.locals[param] = { idx: innerScope.localInd++, type: valtypeBinary };
2614
+ allocVar(innerScope, params[i], false);
1740
2615
  }
1741
2616
 
1742
2617
  let body = objectHack(decl.body);
@@ -1751,11 +2626,9 @@ const generateFunc = (scope, decl) => {
1751
2626
  const wasm = generate(innerScope, body);
1752
2627
  const func = {
1753
2628
  name,
1754
- params: Object.values(innerScope.locals).slice(0, params.length).map(x => x.type),
2629
+ params: Object.values(innerScope.locals).slice(0, params.length * 2).map(x => x.type),
1755
2630
  returns: innerScope.returns,
1756
- returnType: innerScope.returnType ?? TYPES.number,
1757
2631
  locals: innerScope.locals,
1758
- memory: innerScope.memory,
1759
2632
  throws: innerScope.throws,
1760
2633
  index: currentFuncIndex++
1761
2634
  };
@@ -1768,8 +2641,13 @@ const generateFunc = (scope, decl) => {
1768
2641
  }
1769
2642
  }
1770
2643
 
1771
- if (name !== 'main' && func.returns.length !== 0 && wasm[wasm.length - 1]?.[0] !== Opcodes.return && countLeftover(wasm) === 0) {
1772
- wasm.push(...number(0), [ Opcodes.return ]);
2644
+ // add end return if not found
2645
+ if (name !== 'main' && wasm[wasm.length - 1]?.[0] !== Opcodes.return && countLeftover(wasm) === 0) {
2646
+ wasm.push(
2647
+ ...number(0),
2648
+ ...number(TYPES.undefined, Valtype.i32),
2649
+ [ Opcodes.return ]
2650
+ );
1773
2651
  }
1774
2652
 
1775
2653
  // change v128 params into many <type> (i32x4 -> i32/etc) instead as unsupported param valtype
@@ -1780,9 +2658,7 @@ const generateFunc = (scope, decl) => {
1780
2658
  if (local.type === Valtype.v128) {
1781
2659
  vecParams++;
1782
2660
 
1783
- /* func.memory = true; // mark func as using memory
1784
-
1785
- wasm.unshift( // add v128 load for param
2661
+ /* wasm.unshift( // add v128 load for param
1786
2662
  [ Opcodes.i32_const, 0 ],
1787
2663
  [ ...Opcodes.v128_load, 0, i * 16 ],
1788
2664
  [ Opcodes.local_set, local.idx ]
@@ -1893,10 +2769,10 @@ const generateFunc = (scope, decl) => {
1893
2769
  };
1894
2770
 
1895
2771
  const generateCode = (scope, decl) => {
1896
- const out = [];
2772
+ let out = [];
1897
2773
 
1898
2774
  for (const x of decl.body) {
1899
- out.push(...generate(scope, x));
2775
+ out = out.concat(generate(scope, x));
1900
2776
  }
1901
2777
 
1902
2778
  return out;
@@ -1912,10 +2788,9 @@ const internalConstrs = {
1912
2788
 
1913
2789
  // new Array(n)
1914
2790
 
1915
- makeArray(scope, {
2791
+ const [ , pointer ] = makeArray(scope, {
1916
2792
  rawElements: new Array(0)
1917
2793
  }, global, name, true);
1918
- const pointer = arrays.get(name ?? '$undeclared');
1919
2794
 
1920
2795
  const arg = decl.arguments[0] ?? DEFAULT_VALUE;
1921
2796
 
@@ -1933,9 +2808,38 @@ const internalConstrs = {
1933
2808
  ];
1934
2809
  },
1935
2810
  type: TYPES._array
2811
+ },
2812
+
2813
+ __Array_of: {
2814
+ // this is not a constructor but best fits internal structure here
2815
+ generate: (scope, decl, global, name) => {
2816
+ // Array.of(i0, i1, ...)
2817
+ return generateArray(scope, {
2818
+ elements: decl.arguments
2819
+ }, global, name);
2820
+ },
2821
+ type: TYPES._array,
2822
+ notConstr: true
1936
2823
  }
1937
2824
  };
1938
2825
 
2826
+ // const _ = Array.prototype.push;
2827
+ // Array.prototype.push = function (a) {
2828
+ // const check = arr => {
2829
+ // for (const x of arr) {
2830
+ // if (x === undefined) {
2831
+ // console.trace(arr);
2832
+ // process.exit();
2833
+ // }
2834
+ // if (Array.isArray(x)) check(x);
2835
+ // }
2836
+ // };
2837
+ // if (Array.isArray(a) && !new Error().stack.includes('node:')) check(a);
2838
+ // // if (Array.isArray(a)) check(a);
2839
+
2840
+ // return _.apply(this, arguments);
2841
+ // };
2842
+
1939
2843
  export default program => {
1940
2844
  globals = {};
1941
2845
  globalInd = 0;
@@ -1944,9 +2848,9 @@ export default program => {
1944
2848
  funcs = [];
1945
2849
  funcIndex = {};
1946
2850
  depth = [];
1947
- typeStates = {};
1948
2851
  arrays = new Map();
1949
2852
  pages = new Map();
2853
+ data = [];
1950
2854
  currentFuncIndex = importedFuncs.length;
1951
2855
 
1952
2856
  globalThis.valtype = 'f64';
@@ -1996,18 +2900,20 @@ export default program => {
1996
2900
  body: program.body
1997
2901
  };
1998
2902
 
2903
+ if (process.argv.includes('-ast-log')) console.log(program.body.body);
2904
+
1999
2905
  generateFunc(scope, program);
2000
2906
 
2001
2907
  const main = funcs[funcs.length - 1];
2002
2908
  main.export = true;
2003
- main.returns = [ valtypeBinary ];
2909
+ main.returns = [ valtypeBinary, Valtype.i32 ];
2004
2910
 
2005
2911
  const lastInst = main.wasm[main.wasm.length - 1] ?? [ Opcodes.end ];
2006
2912
  if (lastInst[0] === Opcodes.drop) {
2007
2913
  main.wasm.splice(main.wasm.length - 1, 1);
2008
2914
 
2009
2915
  const finalStatement = program.body.body[program.body.body.length - 1];
2010
- main.returnType = getNodeType(main, finalStatement);
2916
+ main.wasm.push(...getNodeType(main, finalStatement));
2011
2917
  }
2012
2918
 
2013
2919
  if (lastInst[0] === Opcodes.end || lastInst[0] === Opcodes.local_set || lastInst[0] === Opcodes.global_set) {
@@ -2023,5 +2929,5 @@ export default program => {
2023
2929
  // if blank main func and other exports, remove it
2024
2930
  if (main.wasm.length === 0 && funcs.reduce((acc, x) => acc + (x.export ? 1 : 0), 0) > 1) funcs.splice(funcs.length - 1, 1);
2025
2931
 
2026
- return { funcs, globals, tags, exceptions, pages };
2932
+ return { funcs, globals, tags, exceptions, pages, data };
2027
2933
  };