porffor 0.1.0 → 0.2.0-08a272e
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +199 -208
- package/compiler/2c.js +385 -0
- package/compiler/builtins/base64.js +91 -91
- package/compiler/builtins.js +19 -13
- package/compiler/codeGen.js +1420 -528
- package/compiler/decompile.js +41 -16
- package/compiler/embedding.js +9 -5
- package/compiler/encoding.js +6 -114
- package/compiler/index.js +56 -17
- package/compiler/log.js +15 -0
- package/compiler/opt.js +367 -258
- package/compiler/parse.js +49 -3
- package/compiler/prototype.js +263 -56
- package/compiler/sections.js +51 -8
- package/compiler/wasmSpec.js +3 -0
- package/compiler/wrap.js +23 -9
- package/package.json +6 -1
- package/porf.cmd +1 -1
- package/rhemyn/README.md +37 -0
- package/rhemyn/compile.js +214 -0
- package/rhemyn/parse.js +321 -0
- package/rhemyn/test/parse.js +59 -0
- package/runner/index.js +54 -31
- package/runner/info.js +37 -2
- package/runner/profile.js +1 -2
- package/runner/repl.js +13 -11
- package/runner/results.json +1 -0
- package/runner/transform.js +15 -36
- package/runner/version.js +10 -0
- package/CNAME +0 -1
- package/index.html +0 -1264
- package/logo.png +0 -0
- package/sw.js +0 -26
- package/test/array_1.js +0 -8
- package/test/array_push.js +0 -8
- package/test/assignop_1.js +0 -15
- package/test/bitwise_1.js +0 -6
- package/test/bool_1.js +0 -3
- package/test/boolean.js +0 -6
- package/test/break_1.js +0 -6
- package/test/break_2.js +0 -12
- package/test/conditional_1.js +0 -3
- package/test/conditional_2.js +0 -4
- package/test/console_1.js +0 -2
- package/test/continue_1.js +0 -6
- package/test/continue_2.js +0 -10
- package/test/empty.js +0 -1
- package/test/ending_exp_1.js +0 -2
- package/test/ending_exp_2.js +0 -6
- package/test/eq_1.js +0 -4
- package/test/eq_2.js +0 -4
- package/test/eq_3.js +0 -5
- package/test/export_1.js +0 -9
- package/test/factorial.js +0 -3
- package/test/fibonacci.js +0 -16
- package/test/float_div0.js +0 -2
- package/test/float_frac.js +0 -2
- package/test/float_isfinite.js +0 -29
- package/test/float_isinteger.js +0 -13
- package/test/float_isnan.js +0 -20
- package/test/float_issafeinteger.js +0 -11
- package/test/float_large.js +0 -2
- package/test/float_math_funcs.js +0 -24
- package/test/float_math_random.js +0 -6
- package/test/float_nan.js +0 -3
- package/test/float_number_values.js +0 -12
- package/test/for_1.js +0 -4
- package/test/for_2.js +0 -4
- package/test/func_1.js +0 -16
- package/test/func_2.js +0 -6
- package/test/func_3.js +0 -10
- package/test/global_1.js +0 -8
- package/test/global_2.js +0 -10
- package/test/if_1.js +0 -6
- package/test/if_2.js +0 -9
- package/test/if_3.js +0 -7
- package/test/iife_1.js +0 -8
- package/test/iife_2.js +0 -8
- package/test/index.js +0 -93
- package/test/int_number_values.js +0 -6
- package/test/logic_1.js +0 -7
- package/test/logic_2.js +0 -7
- package/test/math_1.js +0 -6
- package/test/math_2.js +0 -12
- package/test/math_3.js +0 -6
- package/test/number_func.js +0 -4
- package/test/return_1.js +0 -8
- package/test/return_2.js +0 -11
- package/test/tailcall_1.js +0 -10
- package/test/throw_1.js +0 -2
- package/test/throw_2.js +0 -4
- package/test/throw_3.js +0 -2
- package/test/throw_4.js +0 -3
- package/test/try_1.js +0 -7
- package/test/unary_1.js +0 -4
- package/test/unary_2.js +0 -5
- package/test/unary_3.js +0 -6
- package/test/unary_4.js +0 -12
- package/test/unary_5.js +0 -8
- package/test/undefined_1.js +0 -8
- package/test/undefined_2.js +0 -10
- package/test/updateexp_1.js +0 -9
- package/test/vars_1.js +0 -5
- package/test/vars_2.js +0 -9
- package/test/while_1.js +0 -6
- package/test262/compare.js +0 -30
- package/test262/index.js +0 -314
- package/test262/node_modules/.bin/esparse +0 -12
- package/test262/node_modules/.bin/esparse.cmd +0 -17
- package/test262/node_modules/.bin/esparse.ps1 +0 -28
- package/test262/node_modules/.bin/esvalidate +0 -12
- package/test262/node_modules/.bin/esvalidate.cmd +0 -17
- package/test262/node_modules/.bin/esvalidate.ps1 +0 -28
- package/test262/node_modules/.bin/js-yaml +0 -12
- package/test262/node_modules/.bin/js-yaml.cmd +0 -17
- package/test262/node_modules/.bin/js-yaml.ps1 +0 -28
- package/test262/node_modules/.package-lock.json +0 -0
- package/test262/node_modules/@nodelib/fs.scandir/LICENSE +0 -21
- package/test262/node_modules/@nodelib/fs.scandir/README.md +0 -171
- package/test262/node_modules/@nodelib/fs.scandir/out/adapters/fs.d.ts +0 -20
- package/test262/node_modules/@nodelib/fs.scandir/out/adapters/fs.js +0 -19
- package/test262/node_modules/@nodelib/fs.scandir/out/constants.d.ts +0 -4
- package/test262/node_modules/@nodelib/fs.scandir/out/constants.js +0 -17
- package/test262/node_modules/@nodelib/fs.scandir/out/index.d.ts +0 -12
- package/test262/node_modules/@nodelib/fs.scandir/out/index.js +0 -26
- package/test262/node_modules/@nodelib/fs.scandir/out/providers/async.d.ts +0 -7
- package/test262/node_modules/@nodelib/fs.scandir/out/providers/async.js +0 -104
- package/test262/node_modules/@nodelib/fs.scandir/out/providers/common.d.ts +0 -1
- package/test262/node_modules/@nodelib/fs.scandir/out/providers/common.js +0 -13
- package/test262/node_modules/@nodelib/fs.scandir/out/providers/sync.d.ts +0 -5
- package/test262/node_modules/@nodelib/fs.scandir/out/providers/sync.js +0 -54
- package/test262/node_modules/@nodelib/fs.scandir/out/settings.d.ts +0 -20
- package/test262/node_modules/@nodelib/fs.scandir/out/settings.js +0 -24
- package/test262/node_modules/@nodelib/fs.scandir/out/types/index.d.ts +0 -20
- package/test262/node_modules/@nodelib/fs.scandir/out/types/index.js +0 -2
- package/test262/node_modules/@nodelib/fs.scandir/out/utils/fs.d.ts +0 -2
- package/test262/node_modules/@nodelib/fs.scandir/out/utils/fs.js +0 -19
- package/test262/node_modules/@nodelib/fs.scandir/out/utils/index.d.ts +0 -2
- package/test262/node_modules/@nodelib/fs.scandir/out/utils/index.js +0 -5
- package/test262/node_modules/@nodelib/fs.scandir/package.json +0 -44
- package/test262/node_modules/@nodelib/fs.stat/LICENSE +0 -21
- package/test262/node_modules/@nodelib/fs.stat/README.md +0 -126
- package/test262/node_modules/@nodelib/fs.stat/out/adapters/fs.d.ts +0 -13
- package/test262/node_modules/@nodelib/fs.stat/out/adapters/fs.js +0 -17
- package/test262/node_modules/@nodelib/fs.stat/out/index.d.ts +0 -12
- package/test262/node_modules/@nodelib/fs.stat/out/index.js +0 -26
- package/test262/node_modules/@nodelib/fs.stat/out/providers/async.d.ts +0 -4
- package/test262/node_modules/@nodelib/fs.stat/out/providers/async.js +0 -36
- package/test262/node_modules/@nodelib/fs.stat/out/providers/sync.d.ts +0 -3
- package/test262/node_modules/@nodelib/fs.stat/out/providers/sync.js +0 -23
- package/test262/node_modules/@nodelib/fs.stat/out/settings.d.ts +0 -16
- package/test262/node_modules/@nodelib/fs.stat/out/settings.js +0 -16
- package/test262/node_modules/@nodelib/fs.stat/out/types/index.d.ts +0 -4
- package/test262/node_modules/@nodelib/fs.stat/out/types/index.js +0 -2
- package/test262/node_modules/@nodelib/fs.stat/package.json +0 -37
- package/test262/node_modules/@nodelib/fs.walk/LICENSE +0 -21
- package/test262/node_modules/@nodelib/fs.walk/README.md +0 -215
- package/test262/node_modules/@nodelib/fs.walk/out/index.d.ts +0 -14
- package/test262/node_modules/@nodelib/fs.walk/out/index.js +0 -34
- package/test262/node_modules/@nodelib/fs.walk/out/providers/async.d.ts +0 -12
- package/test262/node_modules/@nodelib/fs.walk/out/providers/async.js +0 -30
- package/test262/node_modules/@nodelib/fs.walk/out/providers/index.d.ts +0 -4
- package/test262/node_modules/@nodelib/fs.walk/out/providers/index.js +0 -9
- package/test262/node_modules/@nodelib/fs.walk/out/providers/stream.d.ts +0 -12
- package/test262/node_modules/@nodelib/fs.walk/out/providers/stream.js +0 -34
- package/test262/node_modules/@nodelib/fs.walk/out/providers/sync.d.ts +0 -10
- package/test262/node_modules/@nodelib/fs.walk/out/providers/sync.js +0 -14
- package/test262/node_modules/@nodelib/fs.walk/out/readers/async.d.ts +0 -30
- package/test262/node_modules/@nodelib/fs.walk/out/readers/async.js +0 -97
- package/test262/node_modules/@nodelib/fs.walk/out/readers/common.d.ts +0 -7
- package/test262/node_modules/@nodelib/fs.walk/out/readers/common.js +0 -31
- package/test262/node_modules/@nodelib/fs.walk/out/readers/reader.d.ts +0 -6
- package/test262/node_modules/@nodelib/fs.walk/out/readers/reader.js +0 -11
- package/test262/node_modules/@nodelib/fs.walk/out/readers/sync.d.ts +0 -15
- package/test262/node_modules/@nodelib/fs.walk/out/readers/sync.js +0 -59
- package/test262/node_modules/@nodelib/fs.walk/out/settings.d.ts +0 -30
- package/test262/node_modules/@nodelib/fs.walk/out/settings.js +0 -26
- package/test262/node_modules/@nodelib/fs.walk/out/types/index.d.ts +0 -8
- package/test262/node_modules/@nodelib/fs.walk/out/types/index.js +0 -2
- package/test262/node_modules/@nodelib/fs.walk/package.json +0 -44
- package/test262/node_modules/argparse/CHANGELOG.md +0 -185
- package/test262/node_modules/argparse/LICENSE +0 -21
- package/test262/node_modules/argparse/README.md +0 -257
- package/test262/node_modules/argparse/index.js +0 -3
- package/test262/node_modules/argparse/lib/action/append/constant.js +0 -47
- package/test262/node_modules/argparse/lib/action/append.js +0 -53
- package/test262/node_modules/argparse/lib/action/count.js +0 -40
- package/test262/node_modules/argparse/lib/action/help.js +0 -47
- package/test262/node_modules/argparse/lib/action/store/constant.js +0 -43
- package/test262/node_modules/argparse/lib/action/store/false.js +0 -27
- package/test262/node_modules/argparse/lib/action/store/true.js +0 -26
- package/test262/node_modules/argparse/lib/action/store.js +0 -50
- package/test262/node_modules/argparse/lib/action/subparsers.js +0 -149
- package/test262/node_modules/argparse/lib/action/version.js +0 -47
- package/test262/node_modules/argparse/lib/action.js +0 -146
- package/test262/node_modules/argparse/lib/action_container.js +0 -482
- package/test262/node_modules/argparse/lib/argparse.js +0 -14
- package/test262/node_modules/argparse/lib/argument/error.js +0 -50
- package/test262/node_modules/argparse/lib/argument/exclusive.js +0 -54
- package/test262/node_modules/argparse/lib/argument/group.js +0 -75
- package/test262/node_modules/argparse/lib/argument_parser.js +0 -1161
- package/test262/node_modules/argparse/lib/const.js +0 -21
- package/test262/node_modules/argparse/lib/help/added_formatters.js +0 -87
- package/test262/node_modules/argparse/lib/help/formatter.js +0 -795
- package/test262/node_modules/argparse/lib/namespace.js +0 -76
- package/test262/node_modules/argparse/lib/utils.js +0 -57
- package/test262/node_modules/argparse/package.json +0 -34
- package/test262/node_modules/braces/CHANGELOG.md +0 -184
- package/test262/node_modules/braces/LICENSE +0 -21
- package/test262/node_modules/braces/README.md +0 -593
- package/test262/node_modules/braces/index.js +0 -170
- package/test262/node_modules/braces/lib/compile.js +0 -57
- package/test262/node_modules/braces/lib/constants.js +0 -57
- package/test262/node_modules/braces/lib/expand.js +0 -113
- package/test262/node_modules/braces/lib/parse.js +0 -333
- package/test262/node_modules/braces/lib/stringify.js +0 -32
- package/test262/node_modules/braces/lib/utils.js +0 -112
- package/test262/node_modules/braces/package.json +0 -77
- package/test262/node_modules/esprima/ChangeLog +0 -235
- package/test262/node_modules/esprima/LICENSE.BSD +0 -21
- package/test262/node_modules/esprima/README.md +0 -46
- package/test262/node_modules/esprima/bin/esparse.js +0 -139
- package/test262/node_modules/esprima/bin/esvalidate.js +0 -236
- package/test262/node_modules/esprima/dist/esprima.js +0 -6709
- package/test262/node_modules/esprima/package.json +0 -112
- package/test262/node_modules/fast-glob/LICENSE +0 -21
- package/test262/node_modules/fast-glob/README.md +0 -859
- package/test262/node_modules/fast-glob/out/index.d.ts +0 -40
- package/test262/node_modules/fast-glob/out/index.js +0 -102
- package/test262/node_modules/fast-glob/out/managers/tasks.d.ts +0 -22
- package/test262/node_modules/fast-glob/out/managers/tasks.js +0 -110
- package/test262/node_modules/fast-glob/out/providers/async.d.ts +0 -9
- package/test262/node_modules/fast-glob/out/providers/async.js +0 -23
- package/test262/node_modules/fast-glob/out/providers/filters/deep.d.ts +0 -16
- package/test262/node_modules/fast-glob/out/providers/filters/deep.js +0 -62
- package/test262/node_modules/fast-glob/out/providers/filters/entry.d.ts +0 -16
- package/test262/node_modules/fast-glob/out/providers/filters/entry.js +0 -63
- package/test262/node_modules/fast-glob/out/providers/filters/error.d.ts +0 -8
- package/test262/node_modules/fast-glob/out/providers/filters/error.js +0 -15
- package/test262/node_modules/fast-glob/out/providers/matchers/matcher.d.ts +0 -33
- package/test262/node_modules/fast-glob/out/providers/matchers/matcher.js +0 -45
- package/test262/node_modules/fast-glob/out/providers/matchers/partial.d.ts +0 -4
- package/test262/node_modules/fast-glob/out/providers/matchers/partial.js +0 -38
- package/test262/node_modules/fast-glob/out/providers/provider.d.ts +0 -19
- package/test262/node_modules/fast-glob/out/providers/provider.js +0 -48
- package/test262/node_modules/fast-glob/out/providers/stream.d.ts +0 -11
- package/test262/node_modules/fast-glob/out/providers/stream.js +0 -31
- package/test262/node_modules/fast-glob/out/providers/sync.d.ts +0 -9
- package/test262/node_modules/fast-glob/out/providers/sync.js +0 -23
- package/test262/node_modules/fast-glob/out/providers/transformers/entry.d.ts +0 -8
- package/test262/node_modules/fast-glob/out/providers/transformers/entry.js +0 -26
- package/test262/node_modules/fast-glob/out/readers/async.d.ts +0 -10
- package/test262/node_modules/fast-glob/out/readers/async.js +0 -35
- package/test262/node_modules/fast-glob/out/readers/reader.d.ts +0 -15
- package/test262/node_modules/fast-glob/out/readers/reader.js +0 -33
- package/test262/node_modules/fast-glob/out/readers/stream.d.ts +0 -14
- package/test262/node_modules/fast-glob/out/readers/stream.js +0 -55
- package/test262/node_modules/fast-glob/out/readers/sync.d.ts +0 -12
- package/test262/node_modules/fast-glob/out/readers/sync.js +0 -43
- package/test262/node_modules/fast-glob/out/settings.d.ts +0 -164
- package/test262/node_modules/fast-glob/out/settings.js +0 -57
- package/test262/node_modules/fast-glob/out/types/index.d.ts +0 -31
- package/test262/node_modules/fast-glob/out/types/index.js +0 -2
- package/test262/node_modules/fast-glob/out/utils/array.d.ts +0 -2
- package/test262/node_modules/fast-glob/out/utils/array.js +0 -22
- package/test262/node_modules/fast-glob/out/utils/errno.d.ts +0 -2
- package/test262/node_modules/fast-glob/out/utils/errno.js +0 -7
- package/test262/node_modules/fast-glob/out/utils/fs.d.ts +0 -4
- package/test262/node_modules/fast-glob/out/utils/fs.js +0 -19
- package/test262/node_modules/fast-glob/out/utils/index.d.ts +0 -8
- package/test262/node_modules/fast-glob/out/utils/index.js +0 -17
- package/test262/node_modules/fast-glob/out/utils/path.d.ts +0 -13
- package/test262/node_modules/fast-glob/out/utils/path.js +0 -68
- package/test262/node_modules/fast-glob/out/utils/pattern.d.ts +0 -47
- package/test262/node_modules/fast-glob/out/utils/pattern.js +0 -188
- package/test262/node_modules/fast-glob/out/utils/stream.d.ts +0 -4
- package/test262/node_modules/fast-glob/out/utils/stream.js +0 -17
- package/test262/node_modules/fast-glob/out/utils/string.d.ts +0 -2
- package/test262/node_modules/fast-glob/out/utils/string.js +0 -11
- package/test262/node_modules/fast-glob/package.json +0 -81
- package/test262/node_modules/fastq/.github/dependabot.yml +0 -11
- package/test262/node_modules/fastq/.github/workflows/ci.yml +0 -50
- package/test262/node_modules/fastq/LICENSE +0 -13
- package/test262/node_modules/fastq/README.md +0 -309
- package/test262/node_modules/fastq/bench.js +0 -66
- package/test262/node_modules/fastq/example.js +0 -14
- package/test262/node_modules/fastq/example.mjs +0 -11
- package/test262/node_modules/fastq/index.d.ts +0 -37
- package/test262/node_modules/fastq/package.json +0 -52
- package/test262/node_modules/fastq/queue.js +0 -289
- package/test262/node_modules/fastq/test/example.ts +0 -81
- package/test262/node_modules/fastq/test/promise.js +0 -248
- package/test262/node_modules/fastq/test/test.js +0 -566
- package/test262/node_modules/fastq/test/tsconfig.json +0 -11
- package/test262/node_modules/fill-range/LICENSE +0 -21
- package/test262/node_modules/fill-range/README.md +0 -237
- package/test262/node_modules/fill-range/index.js +0 -249
- package/test262/node_modules/fill-range/package.json +0 -69
- package/test262/node_modules/glob-parent/CHANGELOG.md +0 -110
- package/test262/node_modules/glob-parent/LICENSE +0 -15
- package/test262/node_modules/glob-parent/README.md +0 -137
- package/test262/node_modules/glob-parent/index.js +0 -42
- package/test262/node_modules/glob-parent/package.json +0 -48
- package/test262/node_modules/graceful-fs/LICENSE +0 -15
- package/test262/node_modules/graceful-fs/README.md +0 -143
- package/test262/node_modules/graceful-fs/clone.js +0 -23
- package/test262/node_modules/graceful-fs/graceful-fs.js +0 -448
- package/test262/node_modules/graceful-fs/legacy-streams.js +0 -118
- package/test262/node_modules/graceful-fs/package.json +0 -53
- package/test262/node_modules/graceful-fs/polyfills.js +0 -355
- package/test262/node_modules/is-extglob/LICENSE +0 -21
- package/test262/node_modules/is-extglob/README.md +0 -107
- package/test262/node_modules/is-extglob/index.js +0 -20
- package/test262/node_modules/is-extglob/package.json +0 -69
- package/test262/node_modules/is-glob/LICENSE +0 -21
- package/test262/node_modules/is-glob/README.md +0 -206
- package/test262/node_modules/is-glob/index.js +0 -150
- package/test262/node_modules/is-glob/package.json +0 -81
- package/test262/node_modules/is-number/LICENSE +0 -21
- package/test262/node_modules/is-number/README.md +0 -187
- package/test262/node_modules/is-number/index.js +0 -18
- package/test262/node_modules/is-number/package.json +0 -82
- package/test262/node_modules/js-yaml/CHANGELOG.md +0 -557
- package/test262/node_modules/js-yaml/LICENSE +0 -21
- package/test262/node_modules/js-yaml/README.md +0 -299
- package/test262/node_modules/js-yaml/bin/js-yaml.js +0 -132
- package/test262/node_modules/js-yaml/dist/js-yaml.js +0 -3989
- package/test262/node_modules/js-yaml/dist/js-yaml.min.js +0 -1
- package/test262/node_modules/js-yaml/index.js +0 -7
- package/test262/node_modules/js-yaml/lib/js-yaml/common.js +0 -59
- package/test262/node_modules/js-yaml/lib/js-yaml/dumper.js +0 -850
- package/test262/node_modules/js-yaml/lib/js-yaml/exception.js +0 -43
- package/test262/node_modules/js-yaml/lib/js-yaml/loader.js +0 -1644
- package/test262/node_modules/js-yaml/lib/js-yaml/mark.js +0 -76
- package/test262/node_modules/js-yaml/lib/js-yaml/schema/core.js +0 -18
- package/test262/node_modules/js-yaml/lib/js-yaml/schema/default_full.js +0 -25
- package/test262/node_modules/js-yaml/lib/js-yaml/schema/default_safe.js +0 -28
- package/test262/node_modules/js-yaml/lib/js-yaml/schema/failsafe.js +0 -17
- package/test262/node_modules/js-yaml/lib/js-yaml/schema/json.js +0 -25
- package/test262/node_modules/js-yaml/lib/js-yaml/schema.js +0 -108
- package/test262/node_modules/js-yaml/lib/js-yaml/type/binary.js +0 -138
- package/test262/node_modules/js-yaml/lib/js-yaml/type/bool.js +0 -35
- package/test262/node_modules/js-yaml/lib/js-yaml/type/float.js +0 -116
- package/test262/node_modules/js-yaml/lib/js-yaml/type/int.js +0 -173
- package/test262/node_modules/js-yaml/lib/js-yaml/type/js/function.js +0 -93
- package/test262/node_modules/js-yaml/lib/js-yaml/type/js/regexp.js +0 -60
- package/test262/node_modules/js-yaml/lib/js-yaml/type/js/undefined.js +0 -28
- package/test262/node_modules/js-yaml/lib/js-yaml/type/map.js +0 -8
- package/test262/node_modules/js-yaml/lib/js-yaml/type/merge.js +0 -12
- package/test262/node_modules/js-yaml/lib/js-yaml/type/null.js +0 -34
- package/test262/node_modules/js-yaml/lib/js-yaml/type/omap.js +0 -44
- package/test262/node_modules/js-yaml/lib/js-yaml/type/pairs.js +0 -53
- package/test262/node_modules/js-yaml/lib/js-yaml/type/seq.js +0 -8
- package/test262/node_modules/js-yaml/lib/js-yaml/type/set.js +0 -29
- package/test262/node_modules/js-yaml/lib/js-yaml/type/str.js +0 -8
- package/test262/node_modules/js-yaml/lib/js-yaml/type/timestamp.js +0 -88
- package/test262/node_modules/js-yaml/lib/js-yaml/type.js +0 -61
- package/test262/node_modules/js-yaml/lib/js-yaml.js +0 -39
- package/test262/node_modules/js-yaml/package.json +0 -49
- package/test262/node_modules/klaw/CHANGELOG.md +0 -62
- package/test262/node_modules/klaw/LICENSE +0 -15
- package/test262/node_modules/klaw/README.md +0 -252
- package/test262/node_modules/klaw/package.json +0 -40
- package/test262/node_modules/klaw/src/index.js +0 -56
- package/test262/node_modules/merge2/LICENSE +0 -21
- package/test262/node_modules/merge2/README.md +0 -144
- package/test262/node_modules/merge2/index.js +0 -144
- package/test262/node_modules/merge2/package.json +0 -43
- package/test262/node_modules/micromatch/LICENSE +0 -21
- package/test262/node_modules/micromatch/README.md +0 -1011
- package/test262/node_modules/micromatch/index.js +0 -467
- package/test262/node_modules/micromatch/package.json +0 -119
- package/test262/node_modules/picomatch/CHANGELOG.md +0 -136
- package/test262/node_modules/picomatch/LICENSE +0 -21
- package/test262/node_modules/picomatch/README.md +0 -708
- package/test262/node_modules/picomatch/index.js +0 -3
- package/test262/node_modules/picomatch/lib/constants.js +0 -179
- package/test262/node_modules/picomatch/lib/parse.js +0 -1091
- package/test262/node_modules/picomatch/lib/picomatch.js +0 -342
- package/test262/node_modules/picomatch/lib/scan.js +0 -391
- package/test262/node_modules/picomatch/lib/utils.js +0 -64
- package/test262/node_modules/picomatch/package.json +0 -81
- package/test262/node_modules/queue-microtask/LICENSE +0 -20
- package/test262/node_modules/queue-microtask/README.md +0 -90
- package/test262/node_modules/queue-microtask/index.d.ts +0 -2
- package/test262/node_modules/queue-microtask/index.js +0 -9
- package/test262/node_modules/queue-microtask/package.json +0 -55
- package/test262/node_modules/reusify/.coveralls.yml +0 -1
- package/test262/node_modules/reusify/.travis.yml +0 -28
- package/test262/node_modules/reusify/LICENSE +0 -22
- package/test262/node_modules/reusify/README.md +0 -145
- package/test262/node_modules/reusify/benchmarks/createNoCodeFunction.js +0 -30
- package/test262/node_modules/reusify/benchmarks/fib.js +0 -13
- package/test262/node_modules/reusify/benchmarks/reuseNoCodeFunction.js +0 -38
- package/test262/node_modules/reusify/package.json +0 -45
- package/test262/node_modules/reusify/reusify.js +0 -33
- package/test262/node_modules/reusify/test.js +0 -66
- package/test262/node_modules/run-parallel/LICENSE +0 -20
- package/test262/node_modules/run-parallel/README.md +0 -85
- package/test262/node_modules/run-parallel/index.js +0 -51
- package/test262/node_modules/run-parallel/package.json +0 -58
- package/test262/node_modules/sprintf-js/LICENSE +0 -24
- package/test262/node_modules/sprintf-js/README.md +0 -88
- package/test262/node_modules/sprintf-js/bower.json +0 -14
- package/test262/node_modules/sprintf-js/demo/angular.html +0 -20
- package/test262/node_modules/sprintf-js/dist/angular-sprintf.min.js +0 -4
- package/test262/node_modules/sprintf-js/dist/angular-sprintf.min.js.map +0 -1
- package/test262/node_modules/sprintf-js/dist/angular-sprintf.min.map +0 -1
- package/test262/node_modules/sprintf-js/dist/sprintf.min.js +0 -4
- package/test262/node_modules/sprintf-js/dist/sprintf.min.js.map +0 -1
- package/test262/node_modules/sprintf-js/dist/sprintf.min.map +0 -1
- package/test262/node_modules/sprintf-js/gruntfile.js +0 -36
- package/test262/node_modules/sprintf-js/package.json +0 -22
- package/test262/node_modules/sprintf-js/src/angular-sprintf.js +0 -18
- package/test262/node_modules/sprintf-js/src/sprintf.js +0 -208
- package/test262/node_modules/sprintf-js/test/test.js +0 -82
- package/test262/node_modules/test262-stream/.jshintignore +0 -2
- package/test262/node_modules/test262-stream/.jshintrc +0 -6
- package/test262/node_modules/test262-stream/.travis.yml +0 -5
- package/test262/node_modules/test262-stream/CONTRIBUTING.md +0 -37
- package/test262/node_modules/test262-stream/LICENSE-MICROSOFT.txt +0 -27
- package/test262/node_modules/test262-stream/LICENSE.txt +0 -27
- package/test262/node_modules/test262-stream/README.md +0 -71
- package/test262/node_modules/test262-stream/lib/builder.js +0 -46
- package/test262/node_modules/test262-stream/lib/compile.js +0 -24
- package/test262/node_modules/test262-stream/lib/create-scenarios.js +0 -29
- package/test262/node_modules/test262-stream/lib/index.js +0 -187
- package/test262/node_modules/test262-stream/lib/test-file.js +0 -150
- package/test262/node_modules/test262-stream/package.json +0 -26
- package/test262/node_modules/test262-stream/test/collateral/invalid-missing-harness/fake-test262/test/a-test-file.js +0 -16
- package/test262/node_modules/test262-stream/test/collateral/invalid-version-other-accepted/fake-test262/harness/assert.js +0 -17
- package/test262/node_modules/test262-stream/test/collateral/invalid-version-other-accepted/fake-test262/harness/doneprintHandle.js +0 -6
- package/test262/node_modules/test262-stream/test/collateral/invalid-version-other-accepted/fake-test262/harness/sta.js +0 -12
- package/test262/node_modules/test262-stream/test/collateral/invalid-version-other-accepted/fake-test262/package.json +0 -3
- package/test262/node_modules/test262-stream/test/collateral/invalid-version-other-accepted/fake-test262/test/strict.js +0 -9
- package/test262/node_modules/test262-stream/test/collateral/invalid-version-unsupported/fake-test262/harness/assert.js +0 -17
- package/test262/node_modules/test262-stream/test/collateral/invalid-version-unsupported/fake-test262/harness/doneprintHandle.js +0 -6
- package/test262/node_modules/test262-stream/test/collateral/invalid-version-unsupported/fake-test262/harness/sta.js +0 -12
- package/test262/node_modules/test262-stream/test/collateral/invalid-version-unsupported/fake-test262/package.json +0 -3
- package/test262/node_modules/test262-stream/test/collateral/invalid-version-unsupported/fake-test262/test/strict.js +0 -9
- package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-content/test/asyncNegative_default.js +0 -49
- package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-content/test/asyncNegative_strict_mode.js +0 -50
- package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-content/test/async_default.js +0 -48
- package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-content/test/async_strict_mode.js +0 -49
- package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-content/test/bothStrict_default.js +0 -46
- package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-content/test/bothStrict_strict_mode.js +0 -47
- package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-content/test/error_default.js +0 -39
- package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-content/test/error_strict_mode.js +0 -40
- package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-content/test/module_default.js +0 -37
- package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-content/test/module_strict_mode.js +0 -38
- package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-content/test/negative-empty_default.js +0 -37
- package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-content/test/negative-empty_strict_mode.js +0 -38
- package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-content/test/noStrict_default.js +0 -36
- package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-content/test/rawNoStrict_default.js +0 -14
- package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-content/test/rawStrict_default.js +0 -15
- package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-content/test/strict_strict_mode.js +0 -41
- package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-metadata/test/asyncNegative_default.json +0 -22
- package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-metadata/test/asyncNegative_strict_mode.json +0 -22
- package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-metadata/test/async_default.json +0 -18
- package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-metadata/test/async_strict_mode.json +0 -18
- package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-metadata/test/bothStrict_default.json +0 -24
- package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-metadata/test/bothStrict_strict_mode.json +0 -24
- package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-metadata/test/error_default.json +0 -19
- package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-metadata/test/error_strict_mode.json +0 -19
- package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-metadata/test/module_default.json +0 -17
- package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-metadata/test/module_strict_mode.json +0 -17
- package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-metadata/test/negative-empty_default.json +0 -19
- package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-metadata/test/negative-empty_strict_mode.json +0 -19
- package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-metadata/test/noStrict_default.json +0 -17
- package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-metadata/test/rawNoStrict_default.json +0 -14
- package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-metadata/test/rawStrict_default.json +0 -14
- package/test262/node_modules/test262-stream/test/collateral/valid-default/expected-metadata/test/strict_strict_mode.json +0 -21
- package/test262/node_modules/test262-stream/test/collateral/valid-default/fake-test262/harness/assert.js +0 -17
- package/test262/node_modules/test262-stream/test/collateral/valid-default/fake-test262/harness/doneprintHandle.js +0 -6
- package/test262/node_modules/test262-stream/test/collateral/valid-default/fake-test262/harness/sta.js +0 -12
- package/test262/node_modules/test262-stream/test/collateral/valid-default/fake-test262/test/async.js +0 -10
- package/test262/node_modules/test262-stream/test/collateral/valid-default/fake-test262/test/asyncNegative.js +0 -11
- package/test262/node_modules/test262-stream/test/collateral/valid-default/fake-test262/test/bothStrict.js +0 -15
- package/test262/node_modules/test262-stream/test/collateral/valid-default/fake-test262/test/error.js +0 -8
- package/test262/node_modules/test262-stream/test/collateral/valid-default/fake-test262/test/module.js +0 -6
- package/test262/node_modules/test262-stream/test/collateral/valid-default/fake-test262/test/module_FIXTURE.js +0 -2
- package/test262/node_modules/test262-stream/test/collateral/valid-default/fake-test262/test/negative-empty.js +0 -6
- package/test262/node_modules/test262-stream/test/collateral/valid-default/fake-test262/test/noStrict.js +0 -5
- package/test262/node_modules/test262-stream/test/collateral/valid-default/fake-test262/test/rawNoStrict.js +0 -14
- package/test262/node_modules/test262-stream/test/collateral/valid-default/fake-test262/test/rawStrict.js +0 -15
- package/test262/node_modules/test262-stream/test/collateral/valid-default/fake-test262/test/strict.js +0 -9
- package/test262/node_modules/test262-stream/test/collateral/valid-extra-files/expected-content/test/bothStrict_default.js +0 -46
- package/test262/node_modules/test262-stream/test/collateral/valid-extra-files/expected-content/test/bothStrict_strict_mode.js +0 -47
- package/test262/node_modules/test262-stream/test/collateral/valid-extra-files/expected-metadata/test/bothStrict_default.json +0 -24
- package/test262/node_modules/test262-stream/test/collateral/valid-extra-files/expected-metadata/test/bothStrict_strict_mode.json +0 -24
- package/test262/node_modules/test262-stream/test/collateral/valid-extra-files/fake-test262/harness/assert.js +0 -17
- package/test262/node_modules/test262-stream/test/collateral/valid-extra-files/fake-test262/harness/doneprintHandle.js +0 -6
- package/test262/node_modules/test262-stream/test/collateral/valid-extra-files/fake-test262/harness/sta.js +0 -12
- package/test262/node_modules/test262-stream/test/collateral/valid-extra-files/fake-test262/test/bothStrict.js +0 -15
- package/test262/node_modules/test262-stream/test/collateral/valid-extra-files/fake-test262/test/zzz-0_FIXTURE.js +0 -2
- package/test262/node_modules/test262-stream/test/collateral/valid-extra-files/fake-test262/test/zzz-1_FIXTURE.js +0 -2
- package/test262/node_modules/test262-stream/test/collateral/valid-extra-files/fake-test262/test/zzz-2_FIXTURE.js +0 -2
- package/test262/node_modules/test262-stream/test/collateral/valid-extra-files/fake-test262/test/zzz-3_FIXTURE.js +0 -2
- package/test262/node_modules/test262-stream/test/collateral/valid-extra-files/fake-test262/test/zzz-4_FIXTURE.js +0 -2
- package/test262/node_modules/test262-stream/test/collateral/valid-extra-files/fake-test262/test/zzz-5_FIXTURE.js +0 -2
- package/test262/node_modules/test262-stream/test/collateral/valid-extra-files/fake-test262/test/zzz-6_FIXTURE.js +0 -2
- package/test262/node_modules/test262-stream/test/collateral/valid-extra-files/fake-test262/test/zzz-7_FIXTURE.js +0 -2
- package/test262/node_modules/test262-stream/test/collateral/valid-extra-files/fake-test262/test/zzz-8_FIXTURE.js +0 -2
- package/test262/node_modules/test262-stream/test/collateral/valid-extra-files/fake-test262/test/zzz-9_FIXTURE.txt +0 -2
- package/test262/node_modules/test262-stream/test/collateral/valid-insertionindex-with-copyright/expected-content/test/raw_default.js +0 -15
- package/test262/node_modules/test262-stream/test/collateral/valid-insertionindex-with-copyright/expected-content/test/runtime_default.js +0 -38
- package/test262/node_modules/test262-stream/test/collateral/valid-insertionindex-with-copyright/expected-content/test/runtime_strict_mode.js +0 -39
- package/test262/node_modules/test262-stream/test/collateral/valid-insertionindex-with-copyright/expected-metadata/test/raw_default.json +0 -14
- package/test262/node_modules/test262-stream/test/collateral/valid-insertionindex-with-copyright/expected-metadata/test/runtime_default.json +0 -15
- package/test262/node_modules/test262-stream/test/collateral/valid-insertionindex-with-copyright/expected-metadata/test/runtime_strict_mode.json +0 -15
- package/test262/node_modules/test262-stream/test/collateral/valid-insertionindex-with-copyright/fake-test262/harness/assert.js +0 -17
- package/test262/node_modules/test262-stream/test/collateral/valid-insertionindex-with-copyright/fake-test262/harness/sta.js +0 -12
- package/test262/node_modules/test262-stream/test/collateral/valid-insertionindex-with-copyright/fake-test262/test/raw.js +0 -15
- package/test262/node_modules/test262-stream/test/collateral/valid-insertionindex-with-copyright/fake-test262/test/runtime.js +0 -7
- package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-content/test/asyncNegative_default.js +0 -11
- package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-content/test/asyncNegative_strict_mode.js +0 -12
- package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-content/test/async_default.js +0 -10
- package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-content/test/async_strict_mode.js +0 -11
- package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-content/test/bothStrict_default.js +0 -15
- package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-content/test/bothStrict_strict_mode.js +0 -16
- package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-content/test/error_default.js +0 -8
- package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-content/test/error_strict_mode.js +0 -9
- package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-content/test/module_default.js +0 -6
- package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-content/test/module_strict_mode.js +0 -7
- package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-content/test/negative-empty_default.js +0 -6
- package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-content/test/negative-empty_strict_mode.js +0 -7
- package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-content/test/noStrict_default.js +0 -5
- package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-content/test/rawNoStrict_default.js +0 -14
- package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-content/test/rawStrict_default.js +0 -15
- package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-content/test/strict_strict_mode.js +0 -10
- package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-metadata/test/asyncNegative_default.json +0 -18
- package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-metadata/test/asyncNegative_strict_mode.json +0 -18
- package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-metadata/test/async_default.json +0 -14
- package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-metadata/test/async_strict_mode.json +0 -14
- package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-metadata/test/bothStrict_default.json +0 -21
- package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-metadata/test/bothStrict_strict_mode.json +0 -21
- package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-metadata/test/error_default.json +0 -16
- package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-metadata/test/error_strict_mode.json +0 -16
- package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-metadata/test/module_default.json +0 -14
- package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-metadata/test/module_strict_mode.json +0 -14
- package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-metadata/test/negative-empty_default.json +0 -16
- package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-metadata/test/negative-empty_strict_mode.json +0 -16
- package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-metadata/test/noStrict_default.json +0 -14
- package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-metadata/test/rawNoStrict_default.json +0 -14
- package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-metadata/test/rawStrict_default.json +0 -14
- package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/expected-metadata/test/strict_strict_mode.json +0 -18
- package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/fake-test262/harness/assert.js +0 -17
- package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/fake-test262/harness/doneprintHandle.js +0 -6
- package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/fake-test262/harness/sta.js +0 -12
- package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/fake-test262/test/async.js +0 -10
- package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/fake-test262/test/asyncNegative.js +0 -11
- package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/fake-test262/test/bothStrict.js +0 -15
- package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/fake-test262/test/error.js +0 -8
- package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/fake-test262/test/module.js +0 -6
- package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/fake-test262/test/module_FIXTURE.js +0 -2
- package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/fake-test262/test/negative-empty.js +0 -6
- package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/fake-test262/test/noStrict.js +0 -5
- package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/fake-test262/test/rawNoStrict.js +0 -14
- package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/fake-test262/test/rawStrict.js +0 -15
- package/test262/node_modules/test262-stream/test/collateral/valid-omit-runtime/fake-test262/test/strict.js +0 -9
- package/test262/node_modules/test262-stream/test/collateral/valid-version-ignored/expected-content/test/strict_strict_mode.js +0 -41
- package/test262/node_modules/test262-stream/test/collateral/valid-version-ignored/expected-metadata/test/strict_strict_mode.json +0 -21
- package/test262/node_modules/test262-stream/test/collateral/valid-version-ignored/fake-test262/harness/assert.js +0 -17
- package/test262/node_modules/test262-stream/test/collateral/valid-version-ignored/fake-test262/harness/doneprintHandle.js +0 -6
- package/test262/node_modules/test262-stream/test/collateral/valid-version-ignored/fake-test262/harness/sta.js +0 -12
- package/test262/node_modules/test262-stream/test/collateral/valid-version-ignored/fake-test262/package.json +0 -3
- package/test262/node_modules/test262-stream/test/collateral/valid-version-ignored/fake-test262/test/strict.js +0 -9
- package/test262/node_modules/test262-stream/test/collateral/valid-version-supported/expected-content/test/strict_strict_mode.js +0 -41
- package/test262/node_modules/test262-stream/test/collateral/valid-version-supported/expected-metadata/test/strict_strict_mode.json +0 -21
- package/test262/node_modules/test262-stream/test/collateral/valid-version-supported/fake-test262/harness/assert.js +0 -17
- package/test262/node_modules/test262-stream/test/collateral/valid-version-supported/fake-test262/harness/doneprintHandle.js +0 -6
- package/test262/node_modules/test262-stream/test/collateral/valid-version-supported/fake-test262/harness/sta.js +0 -12
- package/test262/node_modules/test262-stream/test/collateral/valid-version-supported/fake-test262/package.json +0 -3
- package/test262/node_modules/test262-stream/test/collateral/valid-version-supported/fake-test262/test/strict.js +0 -9
- package/test262/node_modules/test262-stream/test/collateral/valid-with-hashbang/expected-content/test/missing-raw-flag_default.js +0 -44
- package/test262/node_modules/test262-stream/test/collateral/valid-with-hashbang/expected-content/test/missing-raw-flag_strict_mode.js +0 -45
- 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
- package/test262/node_modules/test262-stream/test/collateral/valid-with-hashbang/expected-content/test/raw-with-ls-multiline-block_default.js +0 -18
- package/test262/node_modules/test262-stream/test/collateral/valid-with-hashbang/expected-content/test/raw-with-ls_default.js +0 -17
- 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
- package/test262/node_modules/test262-stream/test/collateral/valid-with-hashbang/expected-content/test/raw-with-ps-multiline-block_default.js +0 -18
- package/test262/node_modules/test262-stream/test/collateral/valid-with-hashbang/expected-content/test/raw-with-ps_default.js +0 -17
- package/test262/node_modules/test262-stream/test/collateral/valid-with-hashbang/expected-content/test/rawWithLicense_default.js +0 -21
- package/test262/node_modules/test262-stream/test/collateral/valid-with-hashbang/expected-content/test/raw_default.js +0 -17
- package/test262/node_modules/test262-stream/test/collateral/valid-with-hashbang/expected-metadata/test/missing-raw-flag_default.json +0 -22
- package/test262/node_modules/test262-stream/test/collateral/valid-with-hashbang/expected-metadata/test/missing-raw-flag_strict_mode.json +0 -22
- 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
- package/test262/node_modules/test262-stream/test/collateral/valid-with-hashbang/expected-metadata/test/raw-with-ls-multiline-block_default.json +0 -21
- package/test262/node_modules/test262-stream/test/collateral/valid-with-hashbang/expected-metadata/test/raw-with-ls_default.json +0 -21
- 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
- package/test262/node_modules/test262-stream/test/collateral/valid-with-hashbang/expected-metadata/test/raw-with-ps-multiline-block_default.json +0 -21
- package/test262/node_modules/test262-stream/test/collateral/valid-with-hashbang/expected-metadata/test/raw-with-ps_default.json +0 -21
- package/test262/node_modules/test262-stream/test/collateral/valid-with-hashbang/expected-metadata/test/rawWithLicense_default.json +0 -21
- package/test262/node_modules/test262-stream/test/collateral/valid-with-hashbang/expected-metadata/test/raw_default.json +0 -21
- package/test262/node_modules/test262-stream/test/collateral/valid-with-hashbang/fake-test262/harness/assert.js +0 -17
- package/test262/node_modules/test262-stream/test/collateral/valid-with-hashbang/fake-test262/harness/doneprintHandle.js +0 -6
- package/test262/node_modules/test262-stream/test/collateral/valid-with-hashbang/fake-test262/harness/sta.js +0 -12
- package/test262/node_modules/test262-stream/test/collateral/valid-with-hashbang/fake-test262/test/missing-raw-flag.js +0 -13
- 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
- package/test262/node_modules/test262-stream/test/collateral/valid-with-hashbang/fake-test262/test/raw-with-ls-multiline-block.js +0 -18
- package/test262/node_modules/test262-stream/test/collateral/valid-with-hashbang/fake-test262/test/raw-with-ls.js +0 -17
- 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
- package/test262/node_modules/test262-stream/test/collateral/valid-with-hashbang/fake-test262/test/raw-with-ps-multiline-block.js +0 -18
- package/test262/node_modules/test262-stream/test/collateral/valid-with-hashbang/fake-test262/test/raw-with-ps.js +0 -17
- package/test262/node_modules/test262-stream/test/collateral/valid-with-hashbang/fake-test262/test/raw.js +0 -17
- package/test262/node_modules/test262-stream/test/collateral/valid-with-hashbang/fake-test262/test/rawWithLicense.js +0 -21
- package/test262/node_modules/test262-stream/test/collateral/valid-with-includes/custom-includes/assert.js +0 -17
- package/test262/node_modules/test262-stream/test/collateral/valid-with-includes/custom-includes/doneprintHandle.js +0 -9
- package/test262/node_modules/test262-stream/test/collateral/valid-with-includes/custom-includes/sta.js +0 -13
- package/test262/node_modules/test262-stream/test/collateral/valid-with-includes/expected-content/test/async_default.js +0 -52
- package/test262/node_modules/test262-stream/test/collateral/valid-with-includes/expected-content/test/async_strict_mode.js +0 -53
- package/test262/node_modules/test262-stream/test/collateral/valid-with-includes/expected-content/test/bothStrict_default.js +0 -47
- package/test262/node_modules/test262-stream/test/collateral/valid-with-includes/expected-content/test/bothStrict_strict_mode.js +0 -48
- package/test262/node_modules/test262-stream/test/collateral/valid-with-includes/expected-metadata/test/async_default.json +0 -18
- package/test262/node_modules/test262-stream/test/collateral/valid-with-includes/expected-metadata/test/async_strict_mode.json +0 -18
- package/test262/node_modules/test262-stream/test/collateral/valid-with-includes/expected-metadata/test/bothStrict_default.json +0 -24
- package/test262/node_modules/test262-stream/test/collateral/valid-with-includes/expected-metadata/test/bothStrict_strict_mode.json +0 -24
- package/test262/node_modules/test262-stream/test/collateral/valid-with-includes/fake-test262/harness/assert.js +0 -17
- package/test262/node_modules/test262-stream/test/collateral/valid-with-includes/fake-test262/harness/doneprintHandle.js +0 -6
- package/test262/node_modules/test262-stream/test/collateral/valid-with-includes/fake-test262/test/async.js +0 -10
- package/test262/node_modules/test262-stream/test/collateral/valid-with-includes/fake-test262/test/bothStrict.js +0 -15
- package/test262/node_modules/test262-stream/test/collateral/valid-with-paths/expected-content/test/async/asyncNegative_default.js +0 -49
- package/test262/node_modules/test262-stream/test/collateral/valid-with-paths/expected-content/test/async/asyncNegative_strict_mode.js +0 -50
- package/test262/node_modules/test262-stream/test/collateral/valid-with-paths/expected-content/test/async/async_default.js +0 -48
- package/test262/node_modules/test262-stream/test/collateral/valid-with-paths/expected-content/test/async/async_strict_mode.js +0 -49
- package/test262/node_modules/test262-stream/test/collateral/valid-with-paths/expected-content/test/bothStrict_default.js +0 -46
- package/test262/node_modules/test262-stream/test/collateral/valid-with-paths/expected-content/test/bothStrict_strict_mode.js +0 -47
- package/test262/node_modules/test262-stream/test/collateral/valid-with-paths/expected-content/test/strict/no/noStrict_default.js +0 -36
- package/test262/node_modules/test262-stream/test/collateral/valid-with-paths/expected-content/test/strict/no/rawNoStrict_default.js +0 -14
- package/test262/node_modules/test262-stream/test/collateral/valid-with-paths/expected-metadata/test/async/asyncNegative_default.json +0 -22
- package/test262/node_modules/test262-stream/test/collateral/valid-with-paths/expected-metadata/test/async/asyncNegative_strict_mode.json +0 -22
- package/test262/node_modules/test262-stream/test/collateral/valid-with-paths/expected-metadata/test/async/async_default.json +0 -18
- package/test262/node_modules/test262-stream/test/collateral/valid-with-paths/expected-metadata/test/async/async_strict_mode.json +0 -18
- package/test262/node_modules/test262-stream/test/collateral/valid-with-paths/expected-metadata/test/bothStrict_default.json +0 -24
- package/test262/node_modules/test262-stream/test/collateral/valid-with-paths/expected-metadata/test/bothStrict_strict_mode.json +0 -24
- package/test262/node_modules/test262-stream/test/collateral/valid-with-paths/expected-metadata/test/strict/no/noStrict_default.json +0 -17
- package/test262/node_modules/test262-stream/test/collateral/valid-with-paths/expected-metadata/test/strict/no/rawNoStrict_default.json +0 -14
- package/test262/node_modules/test262-stream/test/collateral/valid-with-paths/fake-test262/harness/assert.js +0 -17
- package/test262/node_modules/test262-stream/test/collateral/valid-with-paths/fake-test262/harness/doneprintHandle.js +0 -6
- package/test262/node_modules/test262-stream/test/collateral/valid-with-paths/fake-test262/harness/sta.js +0 -12
- package/test262/node_modules/test262-stream/test/collateral/valid-with-paths/fake-test262/test/async/async.js +0 -10
- package/test262/node_modules/test262-stream/test/collateral/valid-with-paths/fake-test262/test/async/asyncNegative.js +0 -11
- package/test262/node_modules/test262-stream/test/collateral/valid-with-paths/fake-test262/test/bothStrict.js +0 -15
- package/test262/node_modules/test262-stream/test/collateral/valid-with-paths/fake-test262/test/error.js +0 -8
- package/test262/node_modules/test262-stream/test/collateral/valid-with-paths/fake-test262/test/negative-empty.js +0 -6
- package/test262/node_modules/test262-stream/test/collateral/valid-with-paths/fake-test262/test/strict/no/noStrict.js +0 -5
- package/test262/node_modules/test262-stream/test/collateral/valid-with-paths/fake-test262/test/strict/no/rawNoStrict.js +0 -14
- package/test262/node_modules/test262-stream/test/collateral/valid-with-paths/fake-test262/test/strict/rawStrict.js +0 -15
- package/test262/node_modules/test262-stream/test/collateral/valid-with-paths/fake-test262/test/strict/strict.js +0 -9
- package/test262/node_modules/test262-stream/test/test.js +0 -319
- package/test262/node_modules/to-regex-range/LICENSE +0 -21
- package/test262/node_modules/to-regex-range/README.md +0 -305
- package/test262/node_modules/to-regex-range/index.js +0 -288
- package/test262/node_modules/to-regex-range/package.json +0 -88
- package/test262/package-lock.json +0 -279
- package/test262/package.json +0 -6
- package/test262/prelude.js +0 -75
- package/test262/results.json +0 -1
package/compiler/codeGen.js
CHANGED
@@ -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
|
-
|
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,47 +153,72 @@ const generate = (scope, decl, global = false, name = undefined) => {
|
|
141
153
|
|
142
154
|
return [];
|
143
155
|
|
144
|
-
case 'TaggedTemplateExpression':
|
145
|
-
|
146
|
-
|
156
|
+
case 'TaggedTemplateExpression': {
|
157
|
+
const funcs = {
|
158
|
+
asm: str => {
|
159
|
+
let out = [];
|
147
160
|
|
148
|
-
|
149
|
-
|
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
|
-
|
152
|
-
|
153
|
-
|
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
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
}
|
171
|
+
if (asm[0] === 'returns') {
|
172
|
+
scope.returns = asm.slice(1).map(x => Valtype[x]);
|
173
|
+
continue;
|
174
|
+
}
|
160
175
|
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
176
|
+
if (asm[0] === 'memory') {
|
177
|
+
allocPage('asm instrinsic');
|
178
|
+
// todo: add to store/load offset insts
|
179
|
+
continue;
|
180
|
+
}
|
165
181
|
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
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
|
-
|
174
|
-
|
194
|
+
__internal_print_type: str => {
|
195
|
+
const type = getType(scope, str) - TYPES.number;
|
175
196
|
|
176
|
-
|
177
|
-
|
197
|
+
return [
|
198
|
+
...number(type),
|
199
|
+
[ Opcodes.call, importedFuncs.print ],
|
178
200
|
|
179
|
-
|
201
|
+
// newline
|
202
|
+
...number(10),
|
203
|
+
[ Opcodes.call, importedFuncs.printChar ]
|
204
|
+
];
|
205
|
+
}
|
180
206
|
}
|
181
207
|
|
182
|
-
|
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:
|
217
|
+
if (decl.type.startsWith('TS')) {
|
218
|
+
// ignore typescript nodes
|
219
|
+
return [];
|
220
|
+
}
|
221
|
+
|
185
222
|
return todo(`no generation for ${decl.type}!`);
|
186
223
|
}
|
187
224
|
};
|
@@ -269,19 +306,17 @@ const generateIdent = (scope, decl) => {
|
|
269
306
|
|
270
307
|
const generateReturn = (scope, decl) => {
|
271
308
|
if (decl.argument === null) {
|
272
|
-
if (!scope.returnType) scope.returnType = TYPES.undefined;
|
273
|
-
|
274
309
|
// just bare "return"
|
275
310
|
return [
|
276
311
|
...number(UNDEFINED), // "undefined" if func returns
|
312
|
+
...number(TYPES.undefined, Valtype.i32), // type undefined
|
277
313
|
[ Opcodes.return ]
|
278
314
|
];
|
279
315
|
}
|
280
316
|
|
281
|
-
if (!scope.returnType) scope.returnType = getNodeType(scope, decl.argument);
|
282
|
-
|
283
317
|
return [
|
284
318
|
...generate(scope, decl.argument),
|
319
|
+
...getNodeType(scope, decl.argument),
|
285
320
|
[ Opcodes.return ]
|
286
321
|
];
|
287
322
|
};
|
@@ -295,11 +330,13 @@ const localTmp = (scope, name, type = valtypeBinary) => {
|
|
295
330
|
return idx;
|
296
331
|
};
|
297
332
|
|
298
|
-
const
|
333
|
+
const isIntOp = op => op && (op[0] >= 0xb7 && op[0] <= 0xba);
|
334
|
+
|
335
|
+
const performLogicOp = (scope, op, left, right, leftType, rightType) => {
|
299
336
|
const checks = {
|
300
|
-
'||':
|
301
|
-
'&&':
|
302
|
-
|
337
|
+
'||': falsy,
|
338
|
+
'&&': truthy,
|
339
|
+
'??': nullish
|
303
340
|
};
|
304
341
|
|
305
342
|
if (!checks[op]) return todo(`logic operator ${op} not implemented yet`);
|
@@ -307,14 +344,52 @@ const performLogicOp = (scope, op, left, right) => {
|
|
307
344
|
// generic structure for {a} OP {b}
|
308
345
|
// -->
|
309
346
|
// _ = {a}; if (OP_CHECK) {b} else _
|
347
|
+
|
348
|
+
// if we can, use int tmp and convert at the end to help prevent unneeded conversions
|
349
|
+
// (like if we are in an if condition - very common)
|
350
|
+
const leftIsInt = isIntOp(left[left.length - 1]);
|
351
|
+
const rightIsInt = isIntOp(right[right.length - 1]);
|
352
|
+
|
353
|
+
const canInt = leftIsInt && rightIsInt;
|
354
|
+
|
355
|
+
if (canInt) {
|
356
|
+
// remove int -> float conversions from left and right
|
357
|
+
left.pop();
|
358
|
+
right.pop();
|
359
|
+
|
360
|
+
return [
|
361
|
+
...left,
|
362
|
+
[ Opcodes.local_tee, localTmp(scope, 'logictmpi', Valtype.i32) ],
|
363
|
+
...checks[op](scope, [], leftType, true, true),
|
364
|
+
[ Opcodes.if, Valtype.i32 ],
|
365
|
+
...right,
|
366
|
+
// note type
|
367
|
+
...rightType,
|
368
|
+
setLastType(scope),
|
369
|
+
[ Opcodes.else ],
|
370
|
+
[ Opcodes.local_get, localTmp(scope, 'logictmpi', Valtype.i32) ],
|
371
|
+
// note type
|
372
|
+
...leftType,
|
373
|
+
setLastType(scope),
|
374
|
+
[ Opcodes.end ],
|
375
|
+
Opcodes.i32_from
|
376
|
+
];
|
377
|
+
}
|
378
|
+
|
310
379
|
return [
|
311
380
|
...left,
|
312
381
|
[ Opcodes.local_tee, localTmp(scope, 'logictmp') ],
|
313
|
-
...checks[op],
|
382
|
+
...checks[op](scope, [], leftType, false, true),
|
314
383
|
[ Opcodes.if, valtypeBinary ],
|
315
384
|
...right,
|
385
|
+
// note type
|
386
|
+
...rightType,
|
387
|
+
setLastType(scope),
|
316
388
|
[ Opcodes.else ],
|
317
389
|
[ Opcodes.local_get, localTmp(scope, 'logictmp') ],
|
390
|
+
// note type
|
391
|
+
...leftType,
|
392
|
+
setLastType(scope),
|
318
393
|
[ Opcodes.end ]
|
319
394
|
];
|
320
395
|
};
|
@@ -325,15 +400,16 @@ const concatStrings = (scope, left, right, global, name, assign) => {
|
|
325
400
|
// todo: optimize by looking up names in arrays and using that if exists?
|
326
401
|
// todo: optimize this if using literals/known lengths?
|
327
402
|
|
328
|
-
scope.memory = true;
|
329
|
-
|
330
|
-
const pointer = arrays.get(name ?? '$undeclared');
|
331
|
-
|
332
403
|
const rightPointer = localTmp(scope, 'concat_right_pointer', Valtype.i32);
|
333
404
|
const rightLength = localTmp(scope, 'concat_right_length', Valtype.i32);
|
334
405
|
const leftLength = localTmp(scope, 'concat_left_length', Valtype.i32);
|
335
406
|
|
407
|
+
const aotWFA = process.argv.includes('-aot-well-formed-string-approximation');
|
408
|
+
if (aotWFA) addVarMeta(name, { wellFormed: undefined });
|
409
|
+
|
336
410
|
if (assign) {
|
411
|
+
const pointer = arrays.get(name ?? '$undeclared');
|
412
|
+
|
337
413
|
return [
|
338
414
|
// setup right
|
339
415
|
...right,
|
@@ -384,15 +460,12 @@ const concatStrings = (scope, left, right, global, name, assign) => {
|
|
384
460
|
|
385
461
|
const leftPointer = localTmp(scope, 'concat_left_pointer', Valtype.i32);
|
386
462
|
|
387
|
-
|
463
|
+
// alloc/assign array
|
464
|
+
const [ , pointer ] = makeArray(scope, {
|
388
465
|
rawElements: new Array(0)
|
389
466
|
}, global, name, true, 'i16');
|
390
467
|
|
391
468
|
return [
|
392
|
-
// setup new/out array
|
393
|
-
...newOut,
|
394
|
-
[ Opcodes.drop ],
|
395
|
-
|
396
469
|
// setup left
|
397
470
|
...left,
|
398
471
|
Opcodes.i32_to_u,
|
@@ -458,90 +531,309 @@ const concatStrings = (scope, left, right, global, name, assign) => {
|
|
458
531
|
];
|
459
532
|
};
|
460
533
|
|
461
|
-
const
|
462
|
-
//
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
number(0)
|
467
|
-
];
|
468
|
-
|
469
|
-
if (type === TYPES.string) {
|
470
|
-
// if "" (length = 0)
|
471
|
-
return [
|
472
|
-
// pointer
|
473
|
-
...wasm,
|
534
|
+
const compareStrings = (scope, left, right) => {
|
535
|
+
// todo: this should be rewritten into a func
|
536
|
+
// todo: convert left and right to strings if not
|
537
|
+
// todo: optimize by looking up names in arrays and using that if exists?
|
538
|
+
// todo: optimize this if using literals/known lengths?
|
474
539
|
|
475
|
-
|
476
|
-
|
540
|
+
const leftPointer = localTmp(scope, 'compare_left_pointer', Valtype.i32);
|
541
|
+
const leftLength = localTmp(scope, 'compare_left_length', Valtype.i32);
|
542
|
+
const rightPointer = localTmp(scope, 'compare_right_pointer', Valtype.i32);
|
543
|
+
const rightLength = localTmp(scope, 'compare_right_length', Valtype.i32);
|
477
544
|
|
478
|
-
|
479
|
-
|
480
|
-
Opcodes.i32_from_u
|
481
|
-
]
|
482
|
-
}
|
545
|
+
const index = localTmp(scope, 'compare_index', Valtype.i32);
|
546
|
+
const indexEnd = localTmp(scope, 'compare_index_end', Valtype.i32);
|
483
547
|
|
484
|
-
// if = 0
|
485
548
|
return [
|
486
|
-
|
549
|
+
// setup left
|
550
|
+
...left,
|
551
|
+
Opcodes.i32_to_u,
|
552
|
+
[ Opcodes.local_tee, leftPointer ],
|
487
553
|
|
488
|
-
|
489
|
-
|
554
|
+
// setup right
|
555
|
+
...right,
|
556
|
+
Opcodes.i32_to_u,
|
557
|
+
[ Opcodes.local_tee, rightPointer ],
|
558
|
+
|
559
|
+
// fast path: check leftPointer == rightPointer
|
560
|
+
// use if (block) for everything after to "return" a value early
|
561
|
+
[ Opcodes.i32_ne ],
|
562
|
+
[ Opcodes.if, Valtype.i32 ],
|
563
|
+
|
564
|
+
// get lengths
|
565
|
+
[ Opcodes.local_get, leftPointer ],
|
566
|
+
[ Opcodes.i32_load, Math.log2(ValtypeSize[valtype]) - 1, ...unsignedLEB128(0) ],
|
567
|
+
[ Opcodes.local_tee, leftLength ],
|
568
|
+
|
569
|
+
[ Opcodes.local_get, rightPointer ],
|
570
|
+
[ Opcodes.i32_load, Math.log2(ValtypeSize[valtype]) - 1, ...unsignedLEB128(0) ],
|
571
|
+
[ Opcodes.local_tee, rightLength ],
|
572
|
+
|
573
|
+
// fast path: check leftLength != rightLength
|
574
|
+
[ Opcodes.i32_ne ],
|
575
|
+
[ Opcodes.if, Blocktype.void ],
|
576
|
+
...number(0, Valtype.i32),
|
577
|
+
[ Opcodes.br, 1 ],
|
578
|
+
[ Opcodes.end ],
|
579
|
+
|
580
|
+
// no fast path for length = 0 as it would probably be slower for most of the time?
|
581
|
+
|
582
|
+
// tmp could have already been used
|
583
|
+
...number(0, Valtype.i32),
|
584
|
+
[ Opcodes.local_set, index ],
|
585
|
+
|
586
|
+
// setup index end as length * sizeof i16 (2)
|
587
|
+
// we do this instead of having to do mul/div each iter for perf™
|
588
|
+
[ Opcodes.local_get, leftLength ],
|
589
|
+
...number(ValtypeSize.i16, Valtype.i32),
|
590
|
+
[ Opcodes.i32_mul ],
|
591
|
+
[ Opcodes.local_set, indexEnd ],
|
592
|
+
|
593
|
+
// iterate over each char and check if eq
|
594
|
+
[ Opcodes.loop, Blocktype.void ],
|
595
|
+
|
596
|
+
// fetch left
|
597
|
+
[ Opcodes.local_get, index ],
|
598
|
+
[ Opcodes.local_get, leftPointer ],
|
599
|
+
[ Opcodes.i32_add ],
|
600
|
+
[ Opcodes.i32_load16_u, Math.log2(ValtypeSize.i16) - 1, ...unsignedLEB128(ValtypeSize.i32) ],
|
601
|
+
|
602
|
+
// fetch right
|
603
|
+
[ Opcodes.local_get, index ],
|
604
|
+
[ Opcodes.local_get, rightPointer ],
|
605
|
+
[ Opcodes.i32_add ],
|
606
|
+
[ Opcodes.i32_load16_u, Math.log2(ValtypeSize.i16) - 1, ...unsignedLEB128(ValtypeSize.i32) ],
|
607
|
+
|
608
|
+
// not equal, "return" false
|
609
|
+
[ Opcodes.i32_ne ],
|
610
|
+
[ Opcodes.if, Blocktype.void ],
|
611
|
+
...number(0, Valtype.i32),
|
612
|
+
[ Opcodes.br, 2 ],
|
613
|
+
[ Opcodes.end ],
|
614
|
+
|
615
|
+
// index += sizeof i16 (2)
|
616
|
+
[ Opcodes.local_get, index ],
|
617
|
+
...number(ValtypeSize.i16, Valtype.i32),
|
618
|
+
[ Opcodes.i32_add ],
|
619
|
+
[ Opcodes.local_tee, index ],
|
620
|
+
|
621
|
+
// if index != index end (length * sizeof 16), loop
|
622
|
+
[ Opcodes.local_get, indexEnd ],
|
623
|
+
[ Opcodes.i32_ne ],
|
624
|
+
[ Opcodes.br_if, 0 ],
|
625
|
+
[ Opcodes.end ],
|
626
|
+
|
627
|
+
// no failed checks, so true!
|
628
|
+
...number(1, Valtype.i32),
|
629
|
+
|
630
|
+
// pointers match, so true
|
631
|
+
[ Opcodes.else ],
|
632
|
+
...number(1, Valtype.i32),
|
633
|
+
[ Opcodes.end ],
|
634
|
+
|
635
|
+
// convert i32 result to valtype
|
636
|
+
// do not do as automatically added by binary exp gen for equality ops
|
637
|
+
// Opcodes.i32_from_u
|
490
638
|
];
|
491
639
|
};
|
492
640
|
|
493
|
-
const truthy = (scope, wasm, type) => {
|
494
|
-
|
495
|
-
if (type === TYPES._array) return [
|
641
|
+
const truthy = (scope, wasm, type, intIn = false, intOut = false) => {
|
642
|
+
if (isIntOp(wasm[wasm.length - 1])) return [
|
496
643
|
...wasm,
|
497
|
-
[ Opcodes.
|
498
|
-
number(1)
|
644
|
+
...(!intIn && intOut ? [ Opcodes.i32_to_u ] : [])
|
499
645
|
];
|
500
646
|
|
501
|
-
|
502
|
-
// if not "" (length = 0)
|
503
|
-
return [
|
504
|
-
// pointer
|
505
|
-
...wasm,
|
506
|
-
|
507
|
-
// get length
|
508
|
-
[ Opcodes.i32_load, Math.log2(ValtypeSize.i32) - 1, 0 ],
|
647
|
+
const tmp = localTmp(scope, `$logicinner_tmp${intIn ? '_int' : ''}`, intIn ? Valtype.i32 : valtypeBinary);
|
509
648
|
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
Opcodes.i32_from_u
|
514
|
-
]
|
515
|
-
}
|
649
|
+
const def = [
|
650
|
+
// if value != 0
|
651
|
+
[ Opcodes.local_get, tmp ],
|
516
652
|
|
517
|
-
|
518
|
-
|
519
|
-
...wasm,
|
653
|
+
// ...(intIn ? [ [ Opcodes.i32_eqz ] ] : [ ...Opcodes.eqz ]),
|
654
|
+
...(!intOut || (intIn && intOut) ? [] : [ Opcodes.i32_to_u ]),
|
520
655
|
|
521
656
|
/* Opcodes.eqz,
|
522
657
|
[ Opcodes.i32_eqz ],
|
523
658
|
Opcodes.i32_from */
|
524
659
|
];
|
660
|
+
|
661
|
+
return [
|
662
|
+
...wasm,
|
663
|
+
[ Opcodes.local_set, tmp ],
|
664
|
+
|
665
|
+
...typeSwitch(scope, type, {
|
666
|
+
// [TYPES.number]: def,
|
667
|
+
[TYPES._array]: [
|
668
|
+
// arrays are always truthy
|
669
|
+
...number(1, intOut ? Valtype.i32 : valtypeBinary)
|
670
|
+
],
|
671
|
+
[TYPES.string]: [
|
672
|
+
[ Opcodes.local_get, tmp ],
|
673
|
+
...(intIn ? [] : [ Opcodes.i32_to_u ]),
|
674
|
+
|
675
|
+
// get length
|
676
|
+
[ Opcodes.i32_load, Math.log2(ValtypeSize.i32) - 1, 0 ],
|
677
|
+
|
678
|
+
// if length != 0
|
679
|
+
/* [ Opcodes.i32_eqz ],
|
680
|
+
[ Opcodes.i32_eqz ], */
|
681
|
+
...(intOut ? [] : [ Opcodes.i32_from_u ])
|
682
|
+
],
|
683
|
+
default: def
|
684
|
+
}, intOut ? Valtype.i32 : valtypeBinary)
|
685
|
+
];
|
686
|
+
};
|
687
|
+
|
688
|
+
const falsy = (scope, wasm, type, intIn = false, intOut = false) => {
|
689
|
+
const tmp = localTmp(scope, `$logicinner_tmp${intIn ? '_int' : ''}`, intIn ? Valtype.i32 : valtypeBinary);
|
690
|
+
return [
|
691
|
+
...wasm,
|
692
|
+
[ Opcodes.local_set, tmp ],
|
693
|
+
|
694
|
+
...typeSwitch(scope, type, {
|
695
|
+
[TYPES._array]: [
|
696
|
+
// arrays are always truthy
|
697
|
+
...number(0, intOut ? Valtype.i32 : valtypeBinary)
|
698
|
+
],
|
699
|
+
[TYPES.string]: [
|
700
|
+
[ Opcodes.local_get, tmp ],
|
701
|
+
...(intIn ? [] : [ Opcodes.i32_to_u ]),
|
702
|
+
|
703
|
+
// get length
|
704
|
+
[ Opcodes.i32_load, Math.log2(ValtypeSize.i32) - 1, 0 ],
|
705
|
+
|
706
|
+
// if length == 0
|
707
|
+
[ Opcodes.i32_eqz ],
|
708
|
+
...(intOut ? [] : [ Opcodes.i32_from_u ])
|
709
|
+
],
|
710
|
+
default: [
|
711
|
+
// if value == 0
|
712
|
+
[ Opcodes.local_get, tmp ],
|
713
|
+
|
714
|
+
...(intIn ? [ [ Opcodes.i32_eqz ] ] : [ ...Opcodes.eqz ]),
|
715
|
+
...(intOut ? [] : [ Opcodes.i32_from_u ])
|
716
|
+
]
|
717
|
+
}, intOut ? Valtype.i32 : valtypeBinary)
|
718
|
+
];
|
719
|
+
};
|
720
|
+
|
721
|
+
const nullish = (scope, wasm, type, intIn = false, intOut = false) => {
|
722
|
+
const tmp = localTmp(scope, `$logicinner_tmp${intIn ? '_int' : ''}`, intIn ? Valtype.i32 : valtypeBinary);
|
723
|
+
return [
|
724
|
+
...wasm,
|
725
|
+
[ Opcodes.local_set, tmp ],
|
726
|
+
|
727
|
+
...typeSwitch(scope, type, {
|
728
|
+
[TYPES.undefined]: [
|
729
|
+
// undefined
|
730
|
+
...number(1, intOut ? Valtype.i32 : valtypeBinary)
|
731
|
+
],
|
732
|
+
[TYPES.object]: [
|
733
|
+
// object, null if == 0
|
734
|
+
[ Opcodes.local_get, tmp ],
|
735
|
+
|
736
|
+
...(intIn ? [ [ Opcodes.i32_eqz ] ] : [ ...Opcodes.eqz ]),
|
737
|
+
...(intOut ? [] : [ Opcodes.i32_from_u ])
|
738
|
+
],
|
739
|
+
default: [
|
740
|
+
// not
|
741
|
+
...number(0, intOut ? Valtype.i32 : valtypeBinary)
|
742
|
+
]
|
743
|
+
}, intOut ? Valtype.i32 : valtypeBinary)
|
744
|
+
];
|
525
745
|
};
|
526
746
|
|
527
|
-
const
|
747
|
+
const stringOnly = wasm => {
|
748
|
+
if (!Array.isArray(wasm[0])) return [ ...wasm, 'string_only' ];
|
749
|
+
if (wasm.length === 1) return [ [ ...wasm[0], 'string_only' ] ];
|
750
|
+
|
751
|
+
return [
|
752
|
+
[ ...wasm[0], 'string_only|start' ],
|
753
|
+
...wasm.slice(1, -1),
|
754
|
+
[ ...wasm[wasm.length - 1], 'string_only|end' ]
|
755
|
+
];
|
756
|
+
}
|
757
|
+
|
758
|
+
const performOp = (scope, op, left, right, leftType, rightType, _global = false, _name = '$undeclared', assign = false) => {
|
528
759
|
if (op === '||' || op === '&&' || op === '??') {
|
529
|
-
return performLogicOp(scope, op, left, right);
|
760
|
+
return performLogicOp(scope, op, left, right, leftType, rightType);
|
761
|
+
}
|
762
|
+
|
763
|
+
const eqOp = ['==', '===', '!=', '!==', '>', '>=', '<', '<='].includes(op);
|
764
|
+
const strictOp = op === '===' || op === '!==';
|
765
|
+
|
766
|
+
const startOut = [], endOut = [];
|
767
|
+
const finalise = out => startOut.concat(out, endOut);
|
768
|
+
|
769
|
+
// if strict (in)equal check types match
|
770
|
+
if (strictOp) {
|
771
|
+
// startOut.push(
|
772
|
+
// ...leftType,
|
773
|
+
// ...rightType,
|
774
|
+
// [ Opcodes.i32_eq ]
|
775
|
+
// );
|
776
|
+
|
777
|
+
// endOut.push(
|
778
|
+
// [ Opcodes.i32_and ]
|
779
|
+
// );
|
780
|
+
|
781
|
+
// startOut.push(
|
782
|
+
// [ Opcodes.block, Valtype.i32 ],
|
783
|
+
// ...leftType,
|
784
|
+
// ...rightType,
|
785
|
+
// [ Opcodes.i32_ne ],
|
786
|
+
// [ Opcodes.if, Blocktype.void ],
|
787
|
+
// ...number(op === '===' ? 0 : 1, Valtype.i32),
|
788
|
+
// [ Opcodes.br, 1 ],
|
789
|
+
// [ Opcodes.end ]
|
790
|
+
// );
|
791
|
+
|
792
|
+
// endOut.push(
|
793
|
+
// [ Opcodes.end ]
|
794
|
+
// );
|
795
|
+
|
796
|
+
endOut.push(
|
797
|
+
...leftType,
|
798
|
+
...rightType,
|
799
|
+
...(op === '===' ? [
|
800
|
+
[ Opcodes.i32_eq ],
|
801
|
+
[ Opcodes.i32_and ]
|
802
|
+
] : [
|
803
|
+
[ Opcodes.i32_ne ],
|
804
|
+
[ Opcodes.i32_or ]
|
805
|
+
])
|
806
|
+
);
|
530
807
|
}
|
531
808
|
|
532
|
-
if
|
533
|
-
|
534
|
-
// string concat (a + b)
|
535
|
-
return concatStrings(scope, left, right, _global, _name, assign);
|
536
|
-
}
|
809
|
+
// todo: if equality op and an operand is undefined, return false
|
810
|
+
// todo: niche null hell with 0
|
537
811
|
|
538
|
-
|
539
|
-
|
812
|
+
// if (leftType === TYPES.string || rightType === TYPES.string) {
|
813
|
+
// if (op === '+') {
|
814
|
+
// // string concat (a + b)
|
815
|
+
// return finalise(concatStrings(scope, left, right, _global, _name, assign));
|
816
|
+
// }
|
540
817
|
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
818
|
+
// // not an equality op, NaN
|
819
|
+
// if (!eqOp) return finalise(number(NaN));
|
820
|
+
|
821
|
+
// // else leave bool ops
|
822
|
+
// // todo: convert string to number if string and number/bool
|
823
|
+
// // todo: string (>|>=|<|<=) string
|
824
|
+
|
825
|
+
// // string comparison
|
826
|
+
// if (op === '===' || op === '==') {
|
827
|
+
// return finalise(compareStrings(scope, left, right));
|
828
|
+
// }
|
829
|
+
|
830
|
+
// if (op === '!==' || op === '!=') {
|
831
|
+
// return finalise([
|
832
|
+
// ...compareStrings(scope, left, right),
|
833
|
+
// [ Opcodes.i32_eqz ]
|
834
|
+
// ]);
|
835
|
+
// }
|
836
|
+
// }
|
545
837
|
|
546
838
|
let ops = operatorOpcode[valtype][op];
|
547
839
|
|
@@ -551,35 +843,99 @@ const performOp = (scope, op, left, right, leftType, rightType, _global = false,
|
|
551
843
|
includeBuiltin(scope, builtinName);
|
552
844
|
const idx = funcIndex[builtinName];
|
553
845
|
|
554
|
-
return [
|
846
|
+
return finalise([
|
555
847
|
...left,
|
556
848
|
...right,
|
557
849
|
[ Opcodes.call, idx ]
|
558
|
-
];
|
850
|
+
]);
|
559
851
|
}
|
560
852
|
|
561
853
|
if (!ops) return todo(`operator ${op} not implemented yet`); // throw new Error(`unknown operator ${op}`);
|
562
854
|
|
563
855
|
if (!Array.isArray(ops)) ops = [ ops ];
|
856
|
+
ops = [ ops ];
|
857
|
+
|
858
|
+
let tmpLeft, tmpRight;
|
859
|
+
// if equal op, check if strings for compareStrings
|
860
|
+
if (op === '===' || op === '==' || op === '!==' || op === '!=') (() => {
|
861
|
+
const knownLeft = knownType(scope, leftType);
|
862
|
+
const knownRight = knownType(scope, rightType);
|
863
|
+
|
864
|
+
// todo: intelligent partial skip later
|
865
|
+
// if neither known are string, stop this madness
|
866
|
+
if ((knownLeft != null && knownLeft !== TYPES.string) && (knownRight != null && knownRight !== TYPES.string)) {
|
867
|
+
return;
|
868
|
+
}
|
564
869
|
|
565
|
-
|
870
|
+
tmpLeft = localTmp(scope, '__tmpop_left');
|
871
|
+
tmpRight = localTmp(scope, '__tmpop_right');
|
872
|
+
|
873
|
+
ops.unshift(...stringOnly([
|
874
|
+
// if left is string
|
875
|
+
...leftType,
|
876
|
+
...number(TYPES.string, Valtype.i32),
|
877
|
+
[ Opcodes.i32_eq ],
|
878
|
+
|
879
|
+
// if right is string
|
880
|
+
...rightType,
|
881
|
+
...number(TYPES.string, Valtype.i32),
|
882
|
+
[ Opcodes.i32_eq ],
|
883
|
+
|
884
|
+
// if either are true
|
885
|
+
[ Opcodes.i32_or ],
|
886
|
+
[ Opcodes.if, Blocktype.void ],
|
887
|
+
|
888
|
+
// todo: convert non-strings to strings, for now fail immediately if one is not
|
889
|
+
// if left is not string
|
890
|
+
...leftType,
|
891
|
+
...number(TYPES.string, Valtype.i32),
|
892
|
+
[ Opcodes.i32_ne ],
|
893
|
+
|
894
|
+
// if right is not string
|
895
|
+
...rightType,
|
896
|
+
...number(TYPES.string, Valtype.i32),
|
897
|
+
[ Opcodes.i32_ne ],
|
898
|
+
|
899
|
+
// if either are true
|
900
|
+
[ Opcodes.i32_or ],
|
901
|
+
[ Opcodes.if, Blocktype.void ],
|
902
|
+
...number(0, Valtype.i32),
|
903
|
+
[ Opcodes.br, 1 ],
|
904
|
+
[ Opcodes.end ],
|
905
|
+
|
906
|
+
...compareStrings(scope, [ [ Opcodes.local_get, tmpLeft ] ], [ [ Opcodes.local_get, tmpRight ] ]),
|
907
|
+
// ...compareStrings(scope, [ [ Opcodes.local_get, tmpLeft ] ], [ [ Opcodes.local_get, tmpRight ] ]),
|
908
|
+
...(op === '!==' || op === '!=' ? [ [ Opcodes.i32_eqz ] ] : []),
|
909
|
+
[ Opcodes.br, 1 ],
|
910
|
+
[ Opcodes.end ],
|
911
|
+
]));
|
912
|
+
|
913
|
+
// if not already in block, add a block
|
914
|
+
// if (endOut.length === 0) {
|
915
|
+
startOut.push(stringOnly([ Opcodes.block, Valtype.i32 ]));
|
916
|
+
// endOut.push(stringOnly([ Opcodes.end ]));
|
917
|
+
endOut.unshift(stringOnly([ Opcodes.end ]));
|
918
|
+
// }
|
919
|
+
})();
|
920
|
+
|
921
|
+
return finalise([
|
566
922
|
...left,
|
923
|
+
...(tmpLeft != null ? stringOnly([ [ Opcodes.local_tee, tmpLeft ] ]) : []),
|
567
924
|
...right,
|
568
|
-
|
569
|
-
|
925
|
+
...(tmpRight != null ? stringOnly([ [ Opcodes.local_tee, tmpRight ] ]) : []),
|
926
|
+
...ops
|
927
|
+
]);
|
570
928
|
};
|
571
929
|
|
572
930
|
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
|
-
];
|
931
|
+
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
932
|
|
577
933
|
if (valtype !== 'i32' && ['==', '===', '!=', '!==', '>', '>=', '<', '<='].includes(decl.operator)) out.push(Opcodes.i32_from_u);
|
578
934
|
|
579
935
|
return out;
|
580
936
|
};
|
581
937
|
|
582
|
-
const asmFunc = (name, { wasm, params, locals: localTypes, globals: globalTypes = [], globalInits, returns, returnType,
|
938
|
+
const asmFunc = (name, { wasm, params, locals: localTypes, globals: globalTypes = [], globalInits, returns, returnType, localNames = [], globalNames = [] }) => {
|
583
939
|
const existing = funcs.find(x => x.name === name);
|
584
940
|
if (existing) return existing;
|
585
941
|
|
@@ -615,7 +971,6 @@ const asmFunc = (name, { wasm, params, locals: localTypes, globals: globalTypes
|
|
615
971
|
returns,
|
616
972
|
returnType: TYPES[returnType ?? 'number'],
|
617
973
|
wasm,
|
618
|
-
memory,
|
619
974
|
internal: true,
|
620
975
|
index: currentFuncIndex++
|
621
976
|
};
|
@@ -634,21 +989,45 @@ const includeBuiltin = (scope, builtin) => {
|
|
634
989
|
};
|
635
990
|
|
636
991
|
const generateLogicExp = (scope, decl) => {
|
637
|
-
return performLogicOp(scope, decl.operator, generate(scope, decl.left), generate(scope, decl.right));
|
992
|
+
return performLogicOp(scope, decl.operator, generate(scope, decl.left), generate(scope, decl.right), getNodeType(scope, decl.left), getNodeType(scope, decl.right));
|
638
993
|
};
|
639
994
|
|
995
|
+
// T = JS type, V = value/pointer
|
996
|
+
// 0bTTT
|
997
|
+
// qNAN: 0 11111111111 1000000000000000000000000000000000000000000000000001
|
998
|
+
// 50 bits usable: 0 11111111111 11??????????????????????????????????????????????????
|
999
|
+
// js type: 4 bits
|
1000
|
+
// internal type: ? bits
|
1001
|
+
// pointer: 32 bits
|
1002
|
+
// https://piotrduperas.com/posts/nan-boxing
|
1003
|
+
// 0x7ffc000000000000
|
1004
|
+
// budget: 50 bits
|
1005
|
+
// js type: 4 bits
|
1006
|
+
// internal type: ? bits
|
1007
|
+
// pointer: 32 bits
|
1008
|
+
|
1009
|
+
// generic
|
1010
|
+
// 1 23 4 5
|
1011
|
+
// 0 11111111111 11TTTTIIII??????????PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
|
1012
|
+
// 1: regular iEEE 754 double NaN
|
1013
|
+
// 2: extra 1 bit to identify NaN box
|
1014
|
+
// 3: js type
|
1015
|
+
// 4: internal type
|
1016
|
+
// 5: pointer
|
1017
|
+
|
640
1018
|
const TYPES = {
|
641
|
-
number:
|
642
|
-
boolean:
|
643
|
-
string:
|
644
|
-
undefined:
|
645
|
-
object:
|
646
|
-
function:
|
647
|
-
symbol:
|
648
|
-
bigint:
|
1019
|
+
number: 0x00,
|
1020
|
+
boolean: 0x01,
|
1021
|
+
string: 0x02,
|
1022
|
+
undefined: 0x03,
|
1023
|
+
object: 0x04,
|
1024
|
+
function: 0x05,
|
1025
|
+
symbol: 0x06,
|
1026
|
+
bigint: 0x07,
|
649
1027
|
|
650
1028
|
// these are not "typeof" types but tracked internally
|
651
|
-
_array:
|
1029
|
+
_array: 0x10,
|
1030
|
+
_regexp: 0x11
|
652
1031
|
};
|
653
1032
|
|
654
1033
|
const TYPE_NAMES = {
|
@@ -661,108 +1040,201 @@ const TYPE_NAMES = {
|
|
661
1040
|
[TYPES.symbol]: 'Symbol',
|
662
1041
|
[TYPES.bigint]: 'BigInt',
|
663
1042
|
|
664
|
-
[TYPES._array]: 'Array'
|
1043
|
+
[TYPES._array]: 'Array',
|
1044
|
+
[TYPES._regexp]: 'RegExp'
|
665
1045
|
};
|
666
1046
|
|
667
|
-
let typeStates = {};
|
668
|
-
|
669
1047
|
const getType = (scope, _name) => {
|
670
1048
|
const name = mapName(_name);
|
671
|
-
if (scope.locals[name]) return typeStates[name];
|
672
1049
|
|
673
|
-
if (
|
674
|
-
if (
|
675
|
-
if (globals[name]) return typeStates[name];
|
1050
|
+
if (scope.locals[name]) return [ [ Opcodes.local_get, scope.locals[name + '#type'].idx ] ];
|
1051
|
+
if (globals[name]) return [ [ Opcodes.global_get, globals[name + '#type'].idx ] ];
|
676
1052
|
|
677
|
-
|
678
|
-
if (name
|
1053
|
+
let type = TYPES.undefined;
|
1054
|
+
if (builtinVars[name]) type = TYPES[builtinVars[name].type ?? 'number'];
|
1055
|
+
if (builtinFuncs[name] !== undefined || importedFuncs[name] !== undefined || funcIndex[name] !== undefined || internalConstrs[name] !== undefined) type = TYPES.function;
|
679
1056
|
|
680
|
-
|
1057
|
+
if (name.startsWith('__Array_prototype_') && prototypeFuncs[TYPES._array][name.slice(18)] ||
|
1058
|
+
name.startsWith('__String_prototype_') && prototypeFuncs[TYPES.string][name.slice(19)]) type = TYPES.function;
|
1059
|
+
|
1060
|
+
return number(type, Valtype.i32);
|
681
1061
|
};
|
682
1062
|
|
683
|
-
const
|
684
|
-
|
685
|
-
return TYPES[typeof node.value];
|
686
|
-
}
|
1063
|
+
const setType = (scope, _name, type) => {
|
1064
|
+
const name = mapName(_name);
|
687
1065
|
|
688
|
-
|
689
|
-
return TYPES.function;
|
690
|
-
}
|
1066
|
+
const out = typeof type === 'number' ? number(type, Valtype.i32) : type;
|
691
1067
|
|
692
|
-
if (
|
693
|
-
|
694
|
-
|
1068
|
+
if (typedInput && scope.locals[name]?.metadata?.type != null) return [];
|
1069
|
+
if (scope.locals[name]) return [
|
1070
|
+
...out,
|
1071
|
+
[ Opcodes.local_set, scope.locals[name + '#type'].idx ]
|
1072
|
+
];
|
695
1073
|
|
696
|
-
if (
|
697
|
-
|
698
|
-
|
699
|
-
|
1074
|
+
if (typedInput && globals[name]?.metadata?.type != null) return [];
|
1075
|
+
if (globals[name]) return [
|
1076
|
+
...out,
|
1077
|
+
[ Opcodes.global_set, globals[name + '#type'].idx ]
|
1078
|
+
];
|
1079
|
+
|
1080
|
+
// throw new Error('could not find var');
|
1081
|
+
};
|
700
1082
|
|
701
|
-
|
702
|
-
|
1083
|
+
const getLastType = scope => {
|
1084
|
+
scope.gotLastType = true;
|
1085
|
+
return [ Opcodes.local_get, localTmp(scope, '#last_type', Valtype.i32) ];
|
1086
|
+
};
|
703
1087
|
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
const spl = name.slice(2).split('_');
|
1088
|
+
const setLastType = scope => {
|
1089
|
+
return [ Opcodes.local_set, localTmp(scope, '#last_type', Valtype.i32) ];
|
1090
|
+
};
|
708
1091
|
|
709
|
-
|
710
|
-
|
1092
|
+
const getNodeType = (scope, node) => {
|
1093
|
+
const inner = () => {
|
1094
|
+
if (node.type === 'Literal') {
|
1095
|
+
if (node.regex) return TYPES._regexp;
|
711
1096
|
|
712
|
-
|
713
|
-
protoFunc = prototypeFuncs[baseType]?.[func];
|
1097
|
+
return TYPES[typeof node.value];
|
714
1098
|
}
|
715
1099
|
|
716
|
-
|
717
|
-
|
718
|
-
|
1100
|
+
if (isFuncType(node.type)) {
|
1101
|
+
return TYPES.function;
|
1102
|
+
}
|
719
1103
|
|
720
|
-
|
721
|
-
|
1104
|
+
if (node.type === 'Identifier') {
|
1105
|
+
return getType(scope, node.name);
|
722
1106
|
}
|
723
1107
|
|
724
|
-
if (
|
1108
|
+
if (node.type === 'CallExpression' || node.type === 'NewExpression') {
|
1109
|
+
const name = node.callee.name;
|
1110
|
+
const func = funcs.find(x => x.name === name);
|
725
1111
|
|
726
|
-
|
727
|
-
|
1112
|
+
if (func) {
|
1113
|
+
// console.log(scope, func, func.returnType);
|
1114
|
+
if (func.returnType) return func.returnType;
|
1115
|
+
}
|
728
1116
|
|
729
|
-
|
730
|
-
|
731
|
-
}
|
1117
|
+
if (builtinFuncs[name]) return TYPES[builtinFuncs[name].returnType ?? 'number'];
|
1118
|
+
if (internalConstrs[name]) return internalConstrs[name].type;
|
732
1119
|
|
733
|
-
|
734
|
-
|
735
|
-
|
1120
|
+
// check if this is a prototype function
|
1121
|
+
// if so and there is only one impl (eg charCodeAt)
|
1122
|
+
// use that return type as that is the only possibility
|
1123
|
+
// (if non-matching type it would error out)
|
1124
|
+
if (name.startsWith('__')) {
|
1125
|
+
const spl = name.slice(2).split('_');
|
736
1126
|
|
737
|
-
|
738
|
-
|
739
|
-
|
1127
|
+
const func = spl[spl.length - 1];
|
1128
|
+
const protoFuncs = Object.values(prototypeFuncs).filter(x => x[func] != null);
|
1129
|
+
if (protoFuncs.length === 1) return protoFuncs[0].returnType ?? TYPES.number;
|
1130
|
+
}
|
740
1131
|
|
741
|
-
|
742
|
-
if (['==', '===', '!=', '!==', '>', '>=', '<', '<='].includes(node.operator)) return TYPES.boolean;
|
1132
|
+
if (scope.locals['#last_type']) return [ getLastType(scope) ];
|
743
1133
|
|
744
|
-
|
745
|
-
|
1134
|
+
// presume
|
1135
|
+
// todo: warn here?
|
1136
|
+
return TYPES.number;
|
746
1137
|
|
747
|
-
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
}
|
1138
|
+
// let protoFunc;
|
1139
|
+
// // ident.func()
|
1140
|
+
// if (name && name.startsWith('__')) {
|
1141
|
+
// const spl = name.slice(2).split('_');
|
752
1142
|
|
753
|
-
|
754
|
-
|
1143
|
+
// const baseName = spl.slice(0, -1).join('_');
|
1144
|
+
// const baseType = getType(scope, baseName);
|
755
1145
|
|
756
|
-
|
757
|
-
|
1146
|
+
// const func = spl[spl.length - 1];
|
1147
|
+
// protoFunc = prototypeFuncs[baseType]?.[func];
|
1148
|
+
// }
|
1149
|
+
|
1150
|
+
// // literal.func()
|
1151
|
+
// if (!name && node.callee.type === 'MemberExpression') {
|
1152
|
+
// if (node.callee.object.regex) {
|
1153
|
+
// const funcName = node.callee.property.name;
|
1154
|
+
// return Rhemyn[funcName] ? TYPES.boolean : TYPES.undefined;
|
1155
|
+
// }
|
1156
|
+
|
1157
|
+
// const baseType = getNodeType(scope, node.callee.object);
|
1158
|
+
|
1159
|
+
// const func = node.callee.property.name;
|
1160
|
+
// protoFunc = prototypeFuncs[baseType]?.[func];
|
1161
|
+
// }
|
1162
|
+
|
1163
|
+
// if (protoFunc) return protoFunc.returnType;
|
1164
|
+
}
|
1165
|
+
|
1166
|
+
if (node.type === 'ExpressionStatement') {
|
1167
|
+
return getNodeType(scope, node.expression);
|
1168
|
+
}
|
1169
|
+
|
1170
|
+
if (node.type === 'AssignmentExpression') {
|
1171
|
+
return getNodeType(scope, node.right);
|
1172
|
+
}
|
1173
|
+
|
1174
|
+
if (node.type === 'ArrayExpression') {
|
1175
|
+
return TYPES._array;
|
1176
|
+
}
|
1177
|
+
|
1178
|
+
if (node.type === 'BinaryExpression') {
|
1179
|
+
if (['==', '===', '!=', '!==', '>', '>=', '<', '<='].includes(node.operator)) return TYPES.boolean;
|
1180
|
+
return TYPES.number;
|
1181
|
+
|
1182
|
+
// todo: string concat types
|
1183
|
+
// if (node.operator !== '+') return TYPES.number;
|
1184
|
+
// else return [
|
1185
|
+
// // if left is string
|
1186
|
+
// ...getNodeType(scope, node.left),
|
1187
|
+
// ...number(TYPES.string, Valtype.i32),
|
1188
|
+
// [ Opcodes.i32_eq ],
|
1189
|
+
|
1190
|
+
// // if right is string
|
1191
|
+
// ...getNodeType(scope, node.right),
|
1192
|
+
// ...number(TYPES.string, Valtype.i32),
|
1193
|
+
// [ Opcodes.i32_eq ],
|
1194
|
+
|
1195
|
+
// // if either are true
|
1196
|
+
// [ Opcodes.i32_or ],
|
1197
|
+
// ];
|
1198
|
+
}
|
1199
|
+
|
1200
|
+
if (node.type === 'UnaryExpression') {
|
1201
|
+
if (node.operator === '!') return TYPES.boolean;
|
1202
|
+
if (node.operator === 'void') return TYPES.undefined;
|
1203
|
+
if (node.operator === 'delete') return TYPES.boolean;
|
1204
|
+
if (node.operator === 'typeof') return TYPES.string;
|
758
1205
|
|
759
|
-
|
760
|
-
|
1206
|
+
return TYPES.number;
|
1207
|
+
}
|
1208
|
+
|
1209
|
+
if (node.type === 'MemberExpression') {
|
1210
|
+
// hack: if something.length, number type
|
1211
|
+
if (node.property.name === 'length') return TYPES.number;
|
1212
|
+
|
1213
|
+
// we cannot guess
|
1214
|
+
return TYPES.number;
|
1215
|
+
}
|
1216
|
+
|
1217
|
+
if (scope.locals['#last_type']) return [ getLastType(scope) ];
|
1218
|
+
|
1219
|
+
// presume
|
1220
|
+
// todo: warn here?
|
1221
|
+
return TYPES.number;
|
1222
|
+
};
|
1223
|
+
|
1224
|
+
const ret = inner();
|
1225
|
+
// console.trace(node, ret);
|
1226
|
+
if (typeof ret === 'number') return number(ret, Valtype.i32);
|
1227
|
+
return ret;
|
761
1228
|
};
|
762
1229
|
|
763
1230
|
const generateLiteral = (scope, decl, global, name) => {
|
764
1231
|
if (decl.value === null) return number(NULL);
|
765
1232
|
|
1233
|
+
if (decl.regex) {
|
1234
|
+
scope.regex[name] = decl.regex;
|
1235
|
+
return number(1);
|
1236
|
+
}
|
1237
|
+
|
766
1238
|
switch (typeof decl.value) {
|
767
1239
|
case 'number':
|
768
1240
|
return number(decl.value);
|
@@ -772,27 +1244,16 @@ const generateLiteral = (scope, decl, global, name) => {
|
|
772
1244
|
return number(decl.value ? 1 : 0);
|
773
1245
|
|
774
1246
|
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
1247
|
const str = decl.value;
|
788
1248
|
const rawElements = new Array(str.length);
|
1249
|
+
let j = 0;
|
789
1250
|
for (let i = 0; i < str.length; i++) {
|
790
1251
|
rawElements[i] = str.charCodeAt(i);
|
791
1252
|
}
|
792
1253
|
|
793
1254
|
return makeArray(scope, {
|
794
1255
|
rawElements
|
795
|
-
}, global, name, false, 'i16');
|
1256
|
+
}, global, name, false, 'i16')[0];
|
796
1257
|
|
797
1258
|
default:
|
798
1259
|
return todo(`cannot generate literal of type ${typeof decl.value}`);
|
@@ -802,7 +1263,8 @@ const generateLiteral = (scope, decl, global, name) => {
|
|
802
1263
|
const countLeftover = wasm => {
|
803
1264
|
let count = 0, depth = 0;
|
804
1265
|
|
805
|
-
for (
|
1266
|
+
for (let i = 0; i < wasm.length; i++) {
|
1267
|
+
const inst = wasm[i];
|
806
1268
|
if (depth === 0 && (inst[0] === Opcodes.if || inst[0] === Opcodes.block || inst[0] === Opcodes.loop)) {
|
807
1269
|
if (inst[0] === Opcodes.if) count--;
|
808
1270
|
if (inst[1] !== Blocktype.void) count++;
|
@@ -811,11 +1273,12 @@ const countLeftover = wasm => {
|
|
811
1273
|
if (inst[0] === Opcodes.end) depth--;
|
812
1274
|
|
813
1275
|
if (depth === 0)
|
814
|
-
if ([Opcodes.throw,
|
1276
|
+
if ([Opcodes.throw,Opcodes.drop, Opcodes.local_set, Opcodes.global_set].includes(inst[0])) count--;
|
815
1277
|
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
1278
|
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
1279
|
else if ([Opcodes.i32_store, Opcodes.i64_store, Opcodes.f64_store, Opcodes.i32_store16].includes(inst[0])) count -= 2;
|
818
1280
|
else if (Opcodes.memory_copy[0] === inst[0] && Opcodes.memory_copy[1] === inst[1]) count -= 3;
|
1281
|
+
else if (inst[0] === Opcodes.return) count = 0;
|
819
1282
|
else if (inst[0] === Opcodes.call) {
|
820
1283
|
let func = funcs.find(x => x.index === inst[1]);
|
821
1284
|
if (func) {
|
@@ -823,6 +1286,8 @@ const countLeftover = wasm => {
|
|
823
1286
|
} else count--;
|
824
1287
|
if (func) count += func.returns.length;
|
825
1288
|
} else count--;
|
1289
|
+
|
1290
|
+
// console.log(count, decompile([ inst ]).slice(0, -1));
|
826
1291
|
}
|
827
1292
|
|
828
1293
|
return count;
|
@@ -843,7 +1308,7 @@ const generateExp = (scope, decl) => {
|
|
843
1308
|
return out;
|
844
1309
|
};
|
845
1310
|
|
846
|
-
const
|
1311
|
+
const CTArrayUtil = {
|
847
1312
|
getLengthI32: pointer => [
|
848
1313
|
...number(0, Valtype.i32),
|
849
1314
|
[ Opcodes.i32_load, Math.log2(ValtypeSize.i32) - 1, ...unsignedLEB128(pointer) ]
|
@@ -869,6 +1334,32 @@ const arrayUtil = {
|
|
869
1334
|
]
|
870
1335
|
};
|
871
1336
|
|
1337
|
+
const RTArrayUtil = {
|
1338
|
+
getLengthI32: pointer => [
|
1339
|
+
...pointer,
|
1340
|
+
[ Opcodes.i32_load, Math.log2(ValtypeSize.i32) - 1, 0 ]
|
1341
|
+
],
|
1342
|
+
|
1343
|
+
getLength: pointer => [
|
1344
|
+
...pointer,
|
1345
|
+
[ Opcodes.i32_load, Math.log2(ValtypeSize.i32) - 1, 0 ],
|
1346
|
+
Opcodes.i32_from_u
|
1347
|
+
],
|
1348
|
+
|
1349
|
+
setLengthI32: (pointer, value) => [
|
1350
|
+
...pointer,
|
1351
|
+
...value,
|
1352
|
+
[ Opcodes.i32_store, Math.log2(ValtypeSize.i32) - 1, 0 ]
|
1353
|
+
],
|
1354
|
+
|
1355
|
+
setLength: (pointer, value) => [
|
1356
|
+
...pointer,
|
1357
|
+
...value,
|
1358
|
+
Opcodes.i32_to_u,
|
1359
|
+
[ Opcodes.i32_store, Math.log2(ValtypeSize.i32) - 1, 0 ]
|
1360
|
+
]
|
1361
|
+
};
|
1362
|
+
|
872
1363
|
const generateCall = (scope, decl, _global, _name) => {
|
873
1364
|
/* const callee = decl.callee;
|
874
1365
|
const args = decl.arguments;
|
@@ -898,95 +1389,164 @@ const generateCall = (scope, decl, _global, _name) => {
|
|
898
1389
|
const lastInst = out[out.length - 1];
|
899
1390
|
if (lastInst && lastInst[0] === Opcodes.drop) {
|
900
1391
|
out.splice(out.length - 1, 1);
|
1392
|
+
|
1393
|
+
const finalStatement = parsed.body[parsed.body.length - 1];
|
1394
|
+
out.push(
|
1395
|
+
...getNodeType(scope, finalStatement),
|
1396
|
+
setLastType(scope)
|
1397
|
+
);
|
901
1398
|
} else if (countLeftover(out) === 0) {
|
902
1399
|
out.push(...number(UNDEFINED));
|
1400
|
+
out.push(
|
1401
|
+
...number(TYPES.undefined, Valtype.i32),
|
1402
|
+
setLastType(scope)
|
1403
|
+
);
|
903
1404
|
}
|
904
1405
|
|
1406
|
+
// if (lastInst && lastInst[0] === Opcodes.drop) {
|
1407
|
+
// out.splice(out.length - 1, 1);
|
1408
|
+
// } else if (countLeftover(out) === 0) {
|
1409
|
+
// out.push(...number(UNDEFINED));
|
1410
|
+
// }
|
1411
|
+
|
905
1412
|
return out;
|
906
1413
|
}
|
907
1414
|
|
908
|
-
let
|
909
|
-
let protoFunc, protoName, baseType, baseName = '$undeclared';
|
1415
|
+
let protoName, target;
|
910
1416
|
// ident.func()
|
911
1417
|
if (name && name.startsWith('__')) {
|
912
1418
|
const spl = name.slice(2).split('_');
|
913
1419
|
|
914
|
-
|
915
|
-
baseType = getType(scope, baseName);
|
1420
|
+
protoName = spl[spl.length - 1];
|
916
1421
|
|
917
|
-
|
918
|
-
|
919
|
-
protoName = func;
|
1422
|
+
target = { ...decl.callee };
|
1423
|
+
target.name = spl.slice(0, -1).join('_');
|
920
1424
|
}
|
921
1425
|
|
922
1426
|
// literal.func()
|
923
1427
|
if (!name && decl.callee.type === 'MemberExpression') {
|
924
|
-
|
1428
|
+
// megahack for /regex/.func()
|
1429
|
+
if (decl.callee.object.regex) {
|
1430
|
+
const funcName = decl.callee.property.name;
|
1431
|
+
const func = Rhemyn[funcName](decl.callee.object.regex.pattern, currentFuncIndex++);
|
1432
|
+
|
1433
|
+
funcIndex[func.name] = func.index;
|
1434
|
+
funcs.push(func);
|
1435
|
+
|
1436
|
+
return [
|
1437
|
+
// make string arg
|
1438
|
+
...generate(scope, decl.arguments[0]),
|
925
1439
|
|
926
|
-
|
927
|
-
|
928
|
-
|
1440
|
+
// call regex func
|
1441
|
+
Opcodes.i32_to_u,
|
1442
|
+
[ Opcodes.call, func.index ],
|
1443
|
+
Opcodes.i32_from_u,
|
1444
|
+
|
1445
|
+
...number(TYPES.boolean, Valtype.i32),
|
1446
|
+
setLastType(scope)
|
1447
|
+
];
|
1448
|
+
}
|
929
1449
|
|
930
|
-
|
931
|
-
|
1450
|
+
protoName = decl.callee.property.name;
|
1451
|
+
|
1452
|
+
target = decl.callee.object;
|
932
1453
|
}
|
933
1454
|
|
934
|
-
if (
|
935
|
-
|
1455
|
+
// if (protoName && baseType === TYPES.string && Rhemyn[protoName]) {
|
1456
|
+
// const func = Rhemyn[protoName](decl.arguments[0].regex.pattern, currentFuncIndex++);
|
936
1457
|
|
937
|
-
|
1458
|
+
// funcIndex[func.name] = func.index;
|
1459
|
+
// funcs.push(func);
|
938
1460
|
|
939
|
-
|
940
|
-
|
941
|
-
if (codeLog) log('codegen', 'cloning unknown dynamic pointer');
|
1461
|
+
// return [
|
1462
|
+
// generate(scope, decl.callee.object)
|
942
1463
|
|
943
|
-
|
944
|
-
|
945
|
-
|
946
|
-
|
947
|
-
|
1464
|
+
// // call regex func
|
1465
|
+
// [ Opcodes.call, func.index ],
|
1466
|
+
// Opcodes.i32_from_u
|
1467
|
+
// ];
|
1468
|
+
// }
|
948
1469
|
|
949
|
-
|
1470
|
+
if (protoName) {
|
1471
|
+
const protoCands = Object.keys(prototypeFuncs).reduce((acc, x) => {
|
1472
|
+
const f = prototypeFuncs[x][protoName];
|
1473
|
+
if (f) acc[x] = f;
|
1474
|
+
return acc;
|
1475
|
+
}, {});
|
950
1476
|
|
951
|
-
|
952
|
-
|
953
|
-
|
954
|
-
|
955
|
-
|
956
|
-
|
1477
|
+
// no prototype function candidates, ignore
|
1478
|
+
if (Object.keys(protoCands).length > 0) {
|
1479
|
+
// use local for cached i32 length as commonly used
|
1480
|
+
const lengthLocal = localTmp(scope, '__proto_length_cache', Valtype.i32);
|
1481
|
+
const pointerLocal = localTmp(scope, '__proto_pointer_cache', Valtype.i32);
|
1482
|
+
const getPointer = [ [ Opcodes.local_get, pointerLocal ] ];
|
957
1483
|
|
958
|
-
|
959
|
-
];
|
960
|
-
}
|
1484
|
+
// TODO: long-term, prototypes should be their individual separate funcs
|
961
1485
|
|
962
|
-
|
1486
|
+
let lengthI32CacheUsed = false;
|
1487
|
+
const protoBC = {};
|
1488
|
+
for (const x in protoCands) {
|
1489
|
+
const protoFunc = protoCands[x];
|
1490
|
+
if (protoFunc.noArgRetLength && decl.arguments.length === 0) {
|
1491
|
+
protoBC[x] = [
|
1492
|
+
...RTArrayUtil.getLength(getPointer),
|
963
1493
|
|
964
|
-
|
1494
|
+
...number(TYPES.number, Valtype.i32),
|
1495
|
+
setLastType(scope)
|
1496
|
+
];
|
1497
|
+
continue;
|
1498
|
+
}
|
965
1499
|
|
966
|
-
|
967
|
-
|
1500
|
+
// const protoLocal = protoFunc.local ? localTmp(scope, `__${TYPE_NAMES[x]}_${protoName}_tmp`, protoFunc.local) : -1;
|
1501
|
+
// const protoLocal2 = protoFunc.local2 ? localTmp(scope, `__${TYPE_NAMES[x]}_${protoName}_tmp2`, protoFunc.local2) : -1;
|
1502
|
+
const protoLocal = protoFunc.local ? localTmp(scope, `__${protoName}_tmp`, protoFunc.local) : -1;
|
1503
|
+
const protoLocal2 = protoFunc.local2 ? localTmp(scope, `__${protoName}_tmp2`, protoFunc.local2) : -1;
|
1504
|
+
|
1505
|
+
const protoOut = protoFunc(getPointer, {
|
1506
|
+
getCachedI32: () => {
|
1507
|
+
lengthI32CacheUsed = true;
|
1508
|
+
return [ [ Opcodes.local_get, lengthLocal ] ];
|
1509
|
+
},
|
1510
|
+
setCachedI32: () => [ [ Opcodes.local_set, lengthLocal ] ],
|
1511
|
+
get: () => RTArrayUtil.getLength(getPointer),
|
1512
|
+
getI32: () => RTArrayUtil.getLengthI32(getPointer),
|
1513
|
+
set: value => RTArrayUtil.setLength(getPointer, value),
|
1514
|
+
setI32: value => RTArrayUtil.setLengthI32(getPointer, value)
|
1515
|
+
}, generate(scope, decl.arguments[0] ?? DEFAULT_VALUE), protoLocal, protoLocal2, (length, itemType) => {
|
1516
|
+
return makeArray(scope, {
|
1517
|
+
rawElements: new Array(length)
|
1518
|
+
}, _global, _name, true, itemType);
|
1519
|
+
});
|
1520
|
+
|
1521
|
+
protoBC[x] = [
|
1522
|
+
[ Opcodes.block, valtypeBinary ],
|
1523
|
+
...protoOut,
|
1524
|
+
|
1525
|
+
...number(protoFunc.returnType ?? TYPES.number, Valtype.i32),
|
1526
|
+
setLastType(scope),
|
1527
|
+
[ Opcodes.end ]
|
1528
|
+
];
|
1529
|
+
}
|
968
1530
|
|
969
|
-
|
970
|
-
|
971
|
-
|
972
|
-
|
973
|
-
|
974
|
-
|
975
|
-
|
976
|
-
|
977
|
-
|
978
|
-
|
979
|
-
|
980
|
-
|
981
|
-
|
982
|
-
|
983
|
-
|
984
|
-
|
985
|
-
},
|
986
|
-
|
987
|
-
|
988
|
-
[ Opcodes.end ]
|
989
|
-
];
|
1531
|
+
return [
|
1532
|
+
...generate(scope, target),
|
1533
|
+
|
1534
|
+
Opcodes.i32_to_u,
|
1535
|
+
[ Opcodes.local_set, pointerLocal ],
|
1536
|
+
|
1537
|
+
...(!lengthI32CacheUsed ? [] : [
|
1538
|
+
...RTArrayUtil.getLengthI32(getPointer),
|
1539
|
+
[ Opcodes.local_set, lengthLocal ],
|
1540
|
+
]),
|
1541
|
+
|
1542
|
+
...typeSwitch(scope, getNodeType(scope, target), {
|
1543
|
+
...protoBC,
|
1544
|
+
|
1545
|
+
// TODO: error better
|
1546
|
+
default: internalThrow(scope, 'TypeError', `'${protoName}' proto func tried to be called on a type without an impl`)
|
1547
|
+
}, valtypeBinary),
|
1548
|
+
];
|
1549
|
+
}
|
990
1550
|
}
|
991
1551
|
|
992
1552
|
// TODO: only allows callee as literal
|
@@ -1030,34 +1590,50 @@ const generateCall = (scope, decl, _global, _name) => {
|
|
1030
1590
|
|
1031
1591
|
const func = funcs.find(x => x.index === idx);
|
1032
1592
|
|
1593
|
+
const userFunc = (funcIndex[name] && !importedFuncs[name] && !builtinFuncs[name] && !internalConstrs[name]) || idx === -1;
|
1594
|
+
const paramCount = func && (userFunc ? func.params.length / 2 : func.params.length);
|
1595
|
+
|
1033
1596
|
let args = decl.arguments;
|
1034
|
-
if (func && args.length <
|
1597
|
+
if (func && args.length < paramCount) {
|
1035
1598
|
// too little args, push undefineds
|
1036
|
-
args = args.concat(new Array(
|
1599
|
+
args = args.concat(new Array(paramCount - args.length).fill(DEFAULT_VALUE));
|
1037
1600
|
}
|
1038
1601
|
|
1039
|
-
if (func && args.length >
|
1602
|
+
if (func && args.length > paramCount) {
|
1040
1603
|
// too many args, slice extras off
|
1041
|
-
args = args.slice(0,
|
1604
|
+
args = args.slice(0, paramCount);
|
1042
1605
|
}
|
1043
1606
|
|
1044
|
-
if (func && func.memory) scope.memory = true;
|
1045
1607
|
if (func && func.throws) scope.throws = true;
|
1046
1608
|
|
1609
|
+
let out = [];
|
1047
1610
|
for (const arg of args) {
|
1048
|
-
out.
|
1611
|
+
out = out.concat(generate(scope, arg));
|
1612
|
+
if (userFunc) out = out.concat(getNodeType(scope, arg));
|
1049
1613
|
}
|
1050
1614
|
|
1051
1615
|
out.push([ Opcodes.call, idx ]);
|
1052
1616
|
|
1617
|
+
if (!userFunc) {
|
1618
|
+
// let type;
|
1619
|
+
// if (builtinFuncs[name]) type = TYPES[builtinFuncs[name].returnType ?? 'number'];
|
1620
|
+
// if (internalConstrs[name]) type = internalConstrs[name].type;
|
1621
|
+
// if (importedFuncs[name] && importedFuncs[]) type =
|
1622
|
+
|
1623
|
+
// if (type) out.push(
|
1624
|
+
// ...number(type, Valtype.i32),
|
1625
|
+
// [ Opcodes.local_set, localTmp(scope, '#last_type', Valtype.i32) ]
|
1626
|
+
// );
|
1627
|
+
} else out.push(setLastType(scope));
|
1628
|
+
|
1053
1629
|
return out;
|
1054
1630
|
};
|
1055
1631
|
|
1056
1632
|
const generateNew = (scope, decl, _global, _name) => {
|
1057
1633
|
// hack: basically treat this as a normal call for builtins for now
|
1058
1634
|
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)})`);
|
1635
|
+
if (internalConstrs[name] && !internalConstrs[name].notConstr) return internalConstrs[name].generate(scope, decl, _global, _name);
|
1636
|
+
if (!builtinFuncs[name]) return todo(`new statement is not supported yet`); // return todo(`new statement is not supported yet (new ${unhackName(name)})`);
|
1061
1637
|
|
1062
1638
|
return generateCall(scope, decl, _global, _name);
|
1063
1639
|
};
|
@@ -1073,14 +1649,131 @@ const unhackName = name => {
|
|
1073
1649
|
return name;
|
1074
1650
|
};
|
1075
1651
|
|
1652
|
+
const knownType = (scope, type) => {
|
1653
|
+
if (type.length === 1 && type[0][0] === Opcodes.i32_const) {
|
1654
|
+
return type[0][1];
|
1655
|
+
}
|
1656
|
+
|
1657
|
+
if (typedInput && type.length === 1 && type[0][0] === Opcodes.local_get) {
|
1658
|
+
const idx = type[0][1];
|
1659
|
+
|
1660
|
+
// type idx = var idx + 1
|
1661
|
+
const v = Object.values(scope.locals).find(x => x.idx === idx - 1);
|
1662
|
+
if (v.metadata?.type != null) return v.metadata.type;
|
1663
|
+
}
|
1664
|
+
|
1665
|
+
return null;
|
1666
|
+
};
|
1667
|
+
|
1668
|
+
const typeSwitch = (scope, type, bc, returns = valtypeBinary) => {
|
1669
|
+
const known = knownType(scope, type);
|
1670
|
+
if (known != null) {
|
1671
|
+
return bc[known] ?? bc.default;
|
1672
|
+
}
|
1673
|
+
|
1674
|
+
const tmp = localTmp(scope, '#typeswitch_tmp', Valtype.i32);
|
1675
|
+
|
1676
|
+
const out = [
|
1677
|
+
...type,
|
1678
|
+
[ Opcodes.local_set, tmp ],
|
1679
|
+
[ Opcodes.block, returns ]
|
1680
|
+
];
|
1681
|
+
|
1682
|
+
// todo: use br_table?
|
1683
|
+
|
1684
|
+
for (const x in bc) {
|
1685
|
+
if (x === 'default') continue;
|
1686
|
+
|
1687
|
+
// if type == x
|
1688
|
+
out.push([ Opcodes.local_get, tmp ]);
|
1689
|
+
out.push(...number(x, Valtype.i32));
|
1690
|
+
out.push([ Opcodes.i32_eq ]);
|
1691
|
+
|
1692
|
+
out.push([ Opcodes.if, Blocktype.void, `TYPESWITCH|${TYPE_NAMES[x]}` ]);
|
1693
|
+
out.push(...bc[x]);
|
1694
|
+
out.push([ Opcodes.br, 1 ]);
|
1695
|
+
out.push([ Opcodes.end ]);
|
1696
|
+
}
|
1697
|
+
|
1698
|
+
// default
|
1699
|
+
if (bc.default) out.push(...bc.default);
|
1700
|
+
else if (returns !== Blocktype.void) out.push(...number(0, returns));
|
1701
|
+
|
1702
|
+
out.push([ Opcodes.end, 'TYPESWITCH_end' ]);
|
1703
|
+
|
1704
|
+
return out;
|
1705
|
+
};
|
1706
|
+
|
1707
|
+
const allocVar = (scope, name, global = false) => {
|
1708
|
+
const target = global ? globals : scope.locals;
|
1709
|
+
|
1710
|
+
// already declared
|
1711
|
+
if (target[name]) {
|
1712
|
+
// parser should catch this but sanity check anyway
|
1713
|
+
// if (decl.kind !== 'var') return internalThrow(scope, 'SyntaxError', `Identifier '${unhackName(name)}' has already been declared`);
|
1714
|
+
|
1715
|
+
return target[name].idx;
|
1716
|
+
}
|
1717
|
+
|
1718
|
+
let idx = global ? globalInd++ : scope.localInd++;
|
1719
|
+
target[name] = { idx, type: valtypeBinary };
|
1720
|
+
|
1721
|
+
let typeIdx = global ? globalInd++ : scope.localInd++;
|
1722
|
+
target[name + '#type'] = { idx: typeIdx, type: Valtype.i32 };
|
1723
|
+
|
1724
|
+
return idx;
|
1725
|
+
};
|
1726
|
+
|
1727
|
+
const addVarMetadata = (scope, name, global = false, metadata = {}) => {
|
1728
|
+
const target = global ? globals : scope.locals;
|
1729
|
+
|
1730
|
+
target[name].metadata ??= {};
|
1731
|
+
for (const x in metadata) {
|
1732
|
+
if (metadata[x] != null) target[name].metadata[x] = metadata[x];
|
1733
|
+
}
|
1734
|
+
};
|
1735
|
+
|
1736
|
+
const typeAnnoToPorfType = x => {
|
1737
|
+
if (TYPES[x]) return TYPES[x];
|
1738
|
+
if (TYPES['_' + x]) return TYPES['_' + x];
|
1739
|
+
|
1740
|
+
switch (x) {
|
1741
|
+
case 'i32':
|
1742
|
+
return TYPES.number;
|
1743
|
+
}
|
1744
|
+
|
1745
|
+
return null;
|
1746
|
+
};
|
1747
|
+
|
1748
|
+
const extractTypeAnnotation = decl => {
|
1749
|
+
let a = decl;
|
1750
|
+
while (a.typeAnnotation) a = a.typeAnnotation;
|
1751
|
+
|
1752
|
+
let type, elementType;
|
1753
|
+
if (a.typeName) {
|
1754
|
+
type = a.typeName.name;
|
1755
|
+
} else if (a.type.endsWith('Keyword')) {
|
1756
|
+
type = a.type.slice(2, -7).toLowerCase();
|
1757
|
+
} else if (a.type === 'TSArrayType') {
|
1758
|
+
type = 'array';
|
1759
|
+
elementType = extractTypeAnnotation(a.elementType).type;
|
1760
|
+
}
|
1761
|
+
|
1762
|
+
const typeName = type;
|
1763
|
+
type = typeAnnoToPorfType(type);
|
1764
|
+
|
1765
|
+
// if (decl.name) console.log(decl.name, { type, elementType });
|
1766
|
+
|
1767
|
+
return { type, typeName, elementType };
|
1768
|
+
};
|
1769
|
+
|
1076
1770
|
const generateVar = (scope, decl) => {
|
1077
|
-
|
1771
|
+
let out = [];
|
1078
1772
|
|
1079
1773
|
const topLevel = scope.name === 'main';
|
1080
1774
|
|
1081
1775
|
// 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;
|
1776
|
+
const global = topLevel || decl._bare; // decl.kind === 'var';
|
1084
1777
|
|
1085
1778
|
for (const x of decl.declarations) {
|
1086
1779
|
const name = mapName(x.id.name);
|
@@ -1100,46 +1793,21 @@ const generateVar = (scope, decl) => {
|
|
1100
1793
|
continue; // always ignore
|
1101
1794
|
}
|
1102
1795
|
|
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`);
|
1796
|
+
let idx = allocVar(scope, name, global);
|
1108
1797
|
|
1109
|
-
|
1110
|
-
|
1111
|
-
idx = global ? globalInd++ : scope.localInd++;
|
1112
|
-
target[name] = { idx, type: valtypeBinary };
|
1798
|
+
if (typedInput && x.id.typeAnnotation) {
|
1799
|
+
addVarMetadata(scope, name, global, extractTypeAnnotation(x.id));
|
1113
1800
|
}
|
1114
1801
|
|
1115
|
-
typeStates[name] = x.init ? getNodeType(scope, x.init) : TYPES.undefined;
|
1116
|
-
|
1117
|
-
// x.init ??= DEFAULT_VALUE;
|
1118
1802
|
if (x.init) {
|
1119
|
-
out.
|
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
|
-
}
|
1803
|
+
out = out.concat(generate(scope, x.init, global, name));
|
1140
1804
|
|
1141
1805
|
out.push([ global ? Opcodes.global_set : Opcodes.local_set, idx ]);
|
1806
|
+
out.push(...setType(scope, name, getNodeType(scope, x.init)));
|
1142
1807
|
}
|
1808
|
+
|
1809
|
+
// hack: this follows spec properly but is mostly unneeded 😅
|
1810
|
+
// out.push(...setType(scope, name, x.init ? getNodeType(scope, x.init) : TYPES.undefined));
|
1143
1811
|
}
|
1144
1812
|
|
1145
1813
|
return out;
|
@@ -1165,8 +1833,6 @@ const generateAssign = (scope, decl) => {
|
|
1165
1833
|
const name = decl.left.object.name;
|
1166
1834
|
const pointer = arrays.get(name);
|
1167
1835
|
|
1168
|
-
scope.memory = true;
|
1169
|
-
|
1170
1836
|
const aotPointer = pointer != null;
|
1171
1837
|
|
1172
1838
|
const newValueTmp = localTmp(scope, '__length_setter_tmp');
|
@@ -1177,7 +1843,7 @@ const generateAssign = (scope, decl) => {
|
|
1177
1843
|
Opcodes.i32_to_u
|
1178
1844
|
]),
|
1179
1845
|
|
1180
|
-
...generate(scope, decl.right
|
1846
|
+
...generate(scope, decl.right),
|
1181
1847
|
[ Opcodes.local_tee, newValueTmp ],
|
1182
1848
|
|
1183
1849
|
Opcodes.i32_to_u,
|
@@ -1187,13 +1853,76 @@ const generateAssign = (scope, decl) => {
|
|
1187
1853
|
];
|
1188
1854
|
}
|
1189
1855
|
|
1856
|
+
const op = decl.operator.slice(0, -1) || '=';
|
1857
|
+
|
1858
|
+
// arr[i]
|
1859
|
+
if (decl.left.type === 'MemberExpression' && decl.left.computed) {
|
1860
|
+
const name = decl.left.object.name;
|
1861
|
+
const pointer = arrays.get(name);
|
1862
|
+
|
1863
|
+
const aotPointer = pointer != null;
|
1864
|
+
|
1865
|
+
const newValueTmp = localTmp(scope, '__member_setter_val_tmp');
|
1866
|
+
const pointerTmp = op === '=' ? -1 : localTmp(scope, '__member_setter_ptr_tmp', Valtype.i32);
|
1867
|
+
|
1868
|
+
return [
|
1869
|
+
...typeSwitch(scope, getNodeType(scope, decl.left.object), {
|
1870
|
+
[TYPES._array]: [
|
1871
|
+
...(aotPointer ? [] : [
|
1872
|
+
...generate(scope, decl.left.object),
|
1873
|
+
Opcodes.i32_to_u
|
1874
|
+
]),
|
1875
|
+
|
1876
|
+
// get index as valtype
|
1877
|
+
...generate(scope, decl.left.property),
|
1878
|
+
Opcodes.i32_to_u,
|
1879
|
+
|
1880
|
+
// turn into byte offset by * valtypeSize (4 for i32, 8 for i64/f64)
|
1881
|
+
...number(ValtypeSize[valtype], Valtype.i32),
|
1882
|
+
[ Opcodes.i32_mul ],
|
1883
|
+
...(aotPointer ? [] : [ [ Opcodes.i32_add ] ]),
|
1884
|
+
...(op === '=' ? [] : [ [ Opcodes.local_tee, pointerTmp ] ]),
|
1885
|
+
|
1886
|
+
...(op === '=' ? generate(scope, decl.right) : performOp(scope, op, [
|
1887
|
+
[ Opcodes.local_get, pointerTmp ],
|
1888
|
+
[ Opcodes.load, Math.log2(ValtypeSize[valtype]) - 1, ...unsignedLEB128((aotPointer ? pointer : 0) + ValtypeSize.i32) ]
|
1889
|
+
], generate(scope, decl.right), number(TYPES.number, Valtype.i32), getNodeType(scope, decl.right), false, name, true)),
|
1890
|
+
[ Opcodes.local_tee, newValueTmp ],
|
1891
|
+
|
1892
|
+
[ Opcodes.store, Math.log2(ValtypeSize[valtype]) - 1, ...unsignedLEB128((aotPointer ? pointer : 0) + ValtypeSize.i32) ]
|
1893
|
+
],
|
1894
|
+
|
1895
|
+
default: internalThrow(scope, 'TypeError', `Cannot assign member with non-array`)
|
1896
|
+
|
1897
|
+
// [TYPES.string]: [
|
1898
|
+
// // turn into byte offset by * sizeof i16
|
1899
|
+
// ...number(ValtypeSize.i16, Valtype.i32),
|
1900
|
+
// [ Opcodes.i32_mul ],
|
1901
|
+
// ...(aotPointer ? [] : [ [ Opcodes.i32_add ] ]),
|
1902
|
+
// ...(op === '=' ? [] : [ [ Opcodes.local_tee, pointerTmp ] ]),
|
1903
|
+
|
1904
|
+
// ...(op === '=' ? generate(scope, decl.right) : performOp(scope, op, [
|
1905
|
+
// [ Opcodes.local_get, pointerTmp ],
|
1906
|
+
// [ Opcodes.load, Math.log2(ValtypeSize[valtype]) - 1, ...unsignedLEB128((aotPointer ? pointer : 0) + ValtypeSize.i32) ]
|
1907
|
+
// ], generate(scope, decl.right), number(TYPES.string, Valtype.i32), getNodeType(scope, decl.right))),
|
1908
|
+
// [ Opcodes.local_tee, newValueTmp ],
|
1909
|
+
|
1910
|
+
// Opcodes.i32_to_u,
|
1911
|
+
// [ StoreOps.i16, Math.log2(ValtypeSize.i16) - 1, ...unsignedLEB128((aotPointer ? pointer : 0) + ValtypeSize.i32) ]
|
1912
|
+
// ]
|
1913
|
+
}, Blocktype.void),
|
1914
|
+
|
1915
|
+
[ Opcodes.local_get, newValueTmp ]
|
1916
|
+
];
|
1917
|
+
}
|
1918
|
+
|
1190
1919
|
const [ local, isGlobal ] = lookupName(scope, name);
|
1191
1920
|
|
1192
1921
|
if (local === undefined) {
|
1193
|
-
// todo: this should be a
|
1922
|
+
// todo: this should be a sloppy mode only thing
|
1194
1923
|
|
1195
1924
|
// only allow = for this
|
1196
|
-
if (
|
1925
|
+
if (op !== '=') return internalThrow(scope, 'ReferenceError', `${unhackName(name)} is not defined`);
|
1197
1926
|
|
1198
1927
|
if (builtinVars[name]) {
|
1199
1928
|
// just return rhs (eg `NaN = 2`)
|
@@ -1202,25 +1931,53 @@ const generateAssign = (scope, decl) => {
|
|
1202
1931
|
|
1203
1932
|
// set global and return (eg a = 2)
|
1204
1933
|
return [
|
1205
|
-
...generateVar(scope, { kind: 'var', declarations: [ { id: { name }, init: decl.right } ] }),
|
1934
|
+
...generateVar(scope, { kind: 'var', _bare: true, declarations: [ { id: { name }, init: decl.right } ] }),
|
1206
1935
|
[ Opcodes.global_get, globals[name].idx ]
|
1207
1936
|
];
|
1208
1937
|
}
|
1209
1938
|
|
1210
|
-
if (
|
1211
|
-
typeStates[name] = getNodeType(scope, decl.right);
|
1212
|
-
|
1939
|
+
if (op === '=') {
|
1213
1940
|
return [
|
1214
1941
|
...generate(scope, decl.right, isGlobal, name),
|
1215
1942
|
[ isGlobal ? Opcodes.global_set : Opcodes.local_set, local.idx ],
|
1216
|
-
[ isGlobal ? Opcodes.global_get : Opcodes.local_get, local.idx ]
|
1943
|
+
[ isGlobal ? Opcodes.global_get : Opcodes.local_get, local.idx ],
|
1944
|
+
|
1945
|
+
...setType(scope, name, getNodeType(scope, decl.right))
|
1946
|
+
];
|
1947
|
+
}
|
1948
|
+
|
1949
|
+
if (op === '||' || op === '&&' || op === '??') {
|
1950
|
+
// todo: is this needed?
|
1951
|
+
// for logical assignment ops, it is not left @= right ~= left = left @ right
|
1952
|
+
// instead, left @ (left = right)
|
1953
|
+
// eg, x &&= y ~= x && (x = y)
|
1954
|
+
|
1955
|
+
return [
|
1956
|
+
...performOp(scope, op, [
|
1957
|
+
[ isGlobal ? Opcodes.global_get : Opcodes.local_get, local.idx ]
|
1958
|
+
], [
|
1959
|
+
...generate(scope, decl.right),
|
1960
|
+
[ isGlobal ? Opcodes.global_set : Opcodes.local_set, local.idx ],
|
1961
|
+
[ isGlobal ? Opcodes.global_get : Opcodes.local_get, local.idx ]
|
1962
|
+
], getType(scope, name), getNodeType(scope, decl.right), isGlobal, name, true),
|
1963
|
+
[ isGlobal ? Opcodes.global_get : Opcodes.local_get, local.idx ],
|
1964
|
+
|
1965
|
+
getLastType(scope),
|
1966
|
+
// hack: type is idx+1
|
1967
|
+
[ isGlobal ? Opcodes.global_set : Opcodes.local_set, local.idx + 1 ],
|
1217
1968
|
];
|
1218
1969
|
}
|
1219
1970
|
|
1220
1971
|
return [
|
1221
|
-
...performOp(scope,
|
1972
|
+
...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
1973
|
[ isGlobal ? Opcodes.global_set : Opcodes.local_set, local.idx ],
|
1223
|
-
[ isGlobal ? Opcodes.global_get : Opcodes.local_get, local.idx ]
|
1974
|
+
[ isGlobal ? Opcodes.global_get : Opcodes.local_get, local.idx ],
|
1975
|
+
|
1976
|
+
// todo: string concat types
|
1977
|
+
|
1978
|
+
// hack: type is idx+1
|
1979
|
+
...number(TYPES.number, Valtype.i32),
|
1980
|
+
[ isGlobal ? Opcodes.global_set : Opcodes.local_set, local.idx + 1 ],
|
1224
1981
|
];
|
1225
1982
|
};
|
1226
1983
|
|
@@ -1245,13 +2002,14 @@ const generateUnary = (scope, decl) => {
|
|
1245
2002
|
|
1246
2003
|
case '!':
|
1247
2004
|
// !=
|
1248
|
-
return falsy(scope, generate(scope, decl.argument));
|
2005
|
+
return falsy(scope, generate(scope, decl.argument), getNodeType(scope, decl.argument), false, false);
|
1249
2006
|
|
1250
2007
|
case '~':
|
2008
|
+
// todo: does not handle Infinity properly (should convert to 0) (but opt const converting saves us sometimes)
|
1251
2009
|
return [
|
1252
2010
|
...generate(scope, decl.argument),
|
1253
2011
|
Opcodes.i32_to,
|
1254
|
-
[ Opcodes.i32_const, signedLEB128(-1) ],
|
2012
|
+
[ Opcodes.i32_const, ...signedLEB128(-1) ],
|
1255
2013
|
[ Opcodes.i32_xor ],
|
1256
2014
|
Opcodes.i32_from
|
1257
2015
|
];
|
@@ -1289,11 +2047,16 @@ const generateUnary = (scope, decl) => {
|
|
1289
2047
|
return out;
|
1290
2048
|
|
1291
2049
|
case 'typeof':
|
1292
|
-
|
2050
|
+
return typeSwitch(scope, getNodeType(scope, decl.argument), {
|
2051
|
+
[TYPES.number]: makeString(scope, 'number', false, '#typeof_result'),
|
2052
|
+
[TYPES.boolean]: makeString(scope, 'boolean', false, '#typeof_result'),
|
2053
|
+
[TYPES.string]: makeString(scope, 'string', false, '#typeof_result'),
|
2054
|
+
[TYPES.undefined]: makeString(scope, 'undefined', false, '#typeof_result'),
|
2055
|
+
[TYPES.function]: makeString(scope, 'function', false, '#typeof_result'),
|
1293
2056
|
|
1294
|
-
|
1295
|
-
|
1296
|
-
|
2057
|
+
// object and internal types
|
2058
|
+
default: makeString(scope, 'object', false, '#typeof_result'),
|
2059
|
+
});
|
1297
2060
|
|
1298
2061
|
default:
|
1299
2062
|
return todo(`unary operator ${decl.operator} not implemented yet`);
|
@@ -1332,9 +2095,9 @@ const generateUpdate = (scope, decl) => {
|
|
1332
2095
|
};
|
1333
2096
|
|
1334
2097
|
const generateIf = (scope, decl) => {
|
1335
|
-
const out = truthy(scope, generate(scope, decl.test), decl.test);
|
2098
|
+
const out = truthy(scope, generate(scope, decl.test), getNodeType(scope, decl.test), false, true);
|
1336
2099
|
|
1337
|
-
out.push(
|
2100
|
+
out.push([ Opcodes.if, Blocktype.void ]);
|
1338
2101
|
depth.push('if');
|
1339
2102
|
|
1340
2103
|
const consOut = generate(scope, decl.consequent);
|
@@ -1356,16 +2119,28 @@ const generateIf = (scope, decl) => {
|
|
1356
2119
|
};
|
1357
2120
|
|
1358
2121
|
const generateConditional = (scope, decl) => {
|
1359
|
-
const out =
|
2122
|
+
const out = truthy(scope, generate(scope, decl.test), getNodeType(scope, decl.test), false, true);
|
1360
2123
|
|
1361
|
-
out.push(
|
2124
|
+
out.push([ Opcodes.if, valtypeBinary ]);
|
1362
2125
|
depth.push('if');
|
1363
2126
|
|
1364
2127
|
out.push(...generate(scope, decl.consequent));
|
1365
2128
|
|
2129
|
+
// note type
|
2130
|
+
out.push(
|
2131
|
+
...getNodeType(scope, decl.consequent),
|
2132
|
+
setLastType(scope)
|
2133
|
+
);
|
2134
|
+
|
1366
2135
|
out.push([ Opcodes.else ]);
|
1367
2136
|
out.push(...generate(scope, decl.alternate));
|
1368
2137
|
|
2138
|
+
// note type
|
2139
|
+
out.push(
|
2140
|
+
...getNodeType(scope, decl.alternate),
|
2141
|
+
setLastType(scope)
|
2142
|
+
);
|
2143
|
+
|
1369
2144
|
out.push([ Opcodes.end ]);
|
1370
2145
|
depth.pop();
|
1371
2146
|
|
@@ -1422,9 +2197,148 @@ const generateWhile = (scope, decl) => {
|
|
1422
2197
|
return out;
|
1423
2198
|
};
|
1424
2199
|
|
2200
|
+
const generateForOf = (scope, decl) => {
|
2201
|
+
const out = [];
|
2202
|
+
|
2203
|
+
// todo: for of inside for of might fuck up?
|
2204
|
+
const pointer = localTmp(scope, 'forof_base_pointer', Valtype.i32);
|
2205
|
+
const length = localTmp(scope, 'forof_length', Valtype.i32);
|
2206
|
+
const counter = localTmp(scope, 'forof_counter', Valtype.i32);
|
2207
|
+
|
2208
|
+
out.push(
|
2209
|
+
// set pointer as right
|
2210
|
+
...generate(scope, decl.right),
|
2211
|
+
Opcodes.i32_to_u,
|
2212
|
+
[ Opcodes.local_set, pointer ],
|
2213
|
+
|
2214
|
+
// set counter as 0 (could be already used)
|
2215
|
+
...number(0, Valtype.i32),
|
2216
|
+
[ Opcodes.local_set, counter ],
|
2217
|
+
|
2218
|
+
// get length
|
2219
|
+
[ Opcodes.local_get, pointer ],
|
2220
|
+
[ Opcodes.i32_load, Math.log2(ValtypeSize.i32) - 1, 0 ],
|
2221
|
+
[ Opcodes.local_set, length ]
|
2222
|
+
);
|
2223
|
+
|
2224
|
+
depth.push('forof');
|
2225
|
+
|
2226
|
+
// setup local for left
|
2227
|
+
generate(scope, decl.left);
|
2228
|
+
|
2229
|
+
const leftName = decl.left.declarations[0].id.name;
|
2230
|
+
const [ local, isGlobal ] = lookupName(scope, leftName);
|
2231
|
+
|
2232
|
+
depth.push('block');
|
2233
|
+
depth.push('block');
|
2234
|
+
|
2235
|
+
// // todo: we should only do this for strings but we don't know at compile-time :(
|
2236
|
+
// hack: this is naughty and will break things!
|
2237
|
+
let newOut = number(0, Valtype.f64), newPointer = -1;
|
2238
|
+
if (pages.hasString) {
|
2239
|
+
0, [ newOut, newPointer ] = makeArray(scope, {
|
2240
|
+
rawElements: new Array(1)
|
2241
|
+
}, isGlobal, leftName, true, 'i16');
|
2242
|
+
}
|
2243
|
+
|
2244
|
+
// set type for local
|
2245
|
+
out.push(...typeSwitch(scope, getNodeType(scope, decl.right), {
|
2246
|
+
[TYPES._array]: [
|
2247
|
+
...setType(scope, leftName, TYPES.number),
|
2248
|
+
|
2249
|
+
[ Opcodes.loop, Blocktype.void ],
|
2250
|
+
|
2251
|
+
[ Opcodes.local_get, pointer ],
|
2252
|
+
[ Opcodes.load, Math.log2(ValtypeSize[valtype]) - 1, ...unsignedLEB128(ValtypeSize.i32) ],
|
2253
|
+
|
2254
|
+
[ isGlobal ? Opcodes.global_set : Opcodes.local_set, local.idx ],
|
2255
|
+
|
2256
|
+
[ Opcodes.block, Blocktype.void ],
|
2257
|
+
[ Opcodes.block, Blocktype.void ],
|
2258
|
+
...generate(scope, decl.body),
|
2259
|
+
[ Opcodes.end ],
|
2260
|
+
|
2261
|
+
// increment iter pointer by valtype size
|
2262
|
+
[ Opcodes.local_get, pointer ],
|
2263
|
+
...number(ValtypeSize[valtype], Valtype.i32),
|
2264
|
+
[ Opcodes.i32_add ],
|
2265
|
+
[ Opcodes.local_set, pointer ],
|
2266
|
+
|
2267
|
+
// increment counter by 1
|
2268
|
+
[ Opcodes.local_get, counter ],
|
2269
|
+
...number(1, Valtype.i32),
|
2270
|
+
[ Opcodes.i32_add ],
|
2271
|
+
[ Opcodes.local_tee, counter ],
|
2272
|
+
|
2273
|
+
// loop if counter != length
|
2274
|
+
[ Opcodes.local_get, length ],
|
2275
|
+
[ Opcodes.i32_ne ],
|
2276
|
+
[ Opcodes.br_if, 1 ],
|
2277
|
+
|
2278
|
+
[ Opcodes.end ],
|
2279
|
+
[ Opcodes.end ]
|
2280
|
+
],
|
2281
|
+
[TYPES.string]: [
|
2282
|
+
...setType(scope, leftName, TYPES.string),
|
2283
|
+
|
2284
|
+
[ Opcodes.loop, Blocktype.void ],
|
2285
|
+
|
2286
|
+
// setup new/out array
|
2287
|
+
...newOut,
|
2288
|
+
[ Opcodes.drop ],
|
2289
|
+
|
2290
|
+
...number(0, Valtype.i32), // base 0 for store after
|
2291
|
+
|
2292
|
+
// load current string ind {arg}
|
2293
|
+
[ Opcodes.local_get, pointer ],
|
2294
|
+
[ Opcodes.i32_load16_u, Math.log2(ValtypeSize.i16) - 1, ...unsignedLEB128(ValtypeSize.i32) ],
|
2295
|
+
|
2296
|
+
// store to new string ind 0
|
2297
|
+
[ Opcodes.i32_store16, Math.log2(ValtypeSize.i16) - 1, ...unsignedLEB128(newPointer + ValtypeSize.i32) ],
|
2298
|
+
|
2299
|
+
// return new string (page)
|
2300
|
+
...number(newPointer),
|
2301
|
+
|
2302
|
+
[ isGlobal ? Opcodes.global_set : Opcodes.local_set, local.idx ],
|
2303
|
+
|
2304
|
+
[ Opcodes.block, Blocktype.void ],
|
2305
|
+
[ Opcodes.block, Blocktype.void ],
|
2306
|
+
...generate(scope, decl.body),
|
2307
|
+
[ Opcodes.end ],
|
2308
|
+
|
2309
|
+
// increment iter pointer by valtype size
|
2310
|
+
[ Opcodes.local_get, pointer ],
|
2311
|
+
...number(ValtypeSize.i16, Valtype.i32),
|
2312
|
+
[ Opcodes.i32_add ],
|
2313
|
+
[ Opcodes.local_set, pointer ],
|
2314
|
+
|
2315
|
+
// increment counter by 1
|
2316
|
+
[ Opcodes.local_get, counter ],
|
2317
|
+
...number(1, Valtype.i32),
|
2318
|
+
[ Opcodes.i32_add ],
|
2319
|
+
[ Opcodes.local_tee, counter ],
|
2320
|
+
|
2321
|
+
// loop if counter != length
|
2322
|
+
[ Opcodes.local_get, length ],
|
2323
|
+
[ Opcodes.i32_ne ],
|
2324
|
+
[ Opcodes.br_if, 1 ],
|
2325
|
+
|
2326
|
+
[ Opcodes.end ],
|
2327
|
+
[ Opcodes.end ]
|
2328
|
+
],
|
2329
|
+
default: internalThrow(scope, 'TypeError', `Tried for..of on non-iterable type`)
|
2330
|
+
}, Blocktype.void));
|
2331
|
+
|
2332
|
+
depth.pop();
|
2333
|
+
depth.pop();
|
2334
|
+
depth.pop();
|
2335
|
+
|
2336
|
+
return out;
|
2337
|
+
};
|
2338
|
+
|
1425
2339
|
const getNearestLoop = () => {
|
1426
2340
|
for (let i = depth.length - 1; i >= 0; i--) {
|
1427
|
-
if (depth[i] === 'while' || depth[i] === 'for') return i;
|
2341
|
+
if (depth[i] === 'while' || depth[i] === 'for' || depth[i] === 'forof') return i;
|
1428
2342
|
}
|
1429
2343
|
|
1430
2344
|
return -1;
|
@@ -1508,13 +2422,25 @@ const generateAssignPat = (scope, decl) => {
|
|
1508
2422
|
};
|
1509
2423
|
|
1510
2424
|
let pages = new Map();
|
1511
|
-
const allocPage = reason => {
|
1512
|
-
if (pages.has(reason)) return pages.get(reason);
|
2425
|
+
const allocPage = (reason, type) => {
|
2426
|
+
if (pages.has(reason)) return pages.get(reason).ind;
|
2427
|
+
|
2428
|
+
if (reason.startsWith('array:')) pages.hasArray = true;
|
2429
|
+
if (reason.startsWith('string:')) pages.hasString = true;
|
2430
|
+
|
2431
|
+
const ind = pages.size;
|
2432
|
+
pages.set(reason, { ind, type });
|
2433
|
+
|
2434
|
+
if (allocLog) log('alloc', `allocated new page of memory (${ind}) | ${reason} (type: ${type})`);
|
2435
|
+
|
2436
|
+
return ind;
|
2437
|
+
};
|
1513
2438
|
|
1514
|
-
|
1515
|
-
pages.
|
2439
|
+
const freePage = reason => {
|
2440
|
+
const { ind } = pages.get(reason);
|
2441
|
+
pages.delete(reason);
|
1516
2442
|
|
1517
|
-
if (
|
2443
|
+
if (allocLog) log('alloc', `freed page of memory (${ind}) | ${reason}`);
|
1518
2444
|
|
1519
2445
|
return ind;
|
1520
2446
|
};
|
@@ -1528,7 +2454,7 @@ const itemTypeToValtype = {
|
|
1528
2454
|
i16: 'i32'
|
1529
2455
|
};
|
1530
2456
|
|
1531
|
-
const
|
2457
|
+
const StoreOps = {
|
1532
2458
|
i32: Opcodes.i32_store,
|
1533
2459
|
i64: Opcodes.i64_store,
|
1534
2460
|
f64: Opcodes.f64_store,
|
@@ -1537,13 +2463,32 @@ const storeOps = {
|
|
1537
2463
|
i16: Opcodes.i32_store16
|
1538
2464
|
};
|
1539
2465
|
|
2466
|
+
let data = [];
|
2467
|
+
|
2468
|
+
const compileBytes = (val, itemType, signed = true) => {
|
2469
|
+
// todo: this is a mess and needs confirming / ????
|
2470
|
+
switch (itemType) {
|
2471
|
+
case 'i8': return [ val % 256 ];
|
2472
|
+
case 'i16': return [ val % 256, Math.floor(val / 256) ];
|
2473
|
+
|
2474
|
+
case 'i32':
|
2475
|
+
case 'i64':
|
2476
|
+
return enforceFourBytes(signedLEB128(val));
|
2477
|
+
|
2478
|
+
case 'f64': return ieee754_binary64(val);
|
2479
|
+
}
|
2480
|
+
};
|
2481
|
+
|
1540
2482
|
const makeArray = (scope, decl, global = false, name = '$undeclared', initEmpty = false, itemType = valtype) => {
|
1541
2483
|
const out = [];
|
1542
2484
|
|
2485
|
+
let firstAssign = false;
|
1543
2486
|
if (!arrays.has(name) || name === '$undeclared') {
|
2487
|
+
firstAssign = true;
|
2488
|
+
|
1544
2489
|
// todo: can we just have 1 undeclared array? probably not? but this is not really memory efficient
|
1545
2490
|
const uniqueName = name === '$undeclared' ? name + Math.random().toString().slice(2) : name;
|
1546
|
-
arrays.set(name, allocPage(`${itemType === 'i16' ? 'string' : 'array'}: ${uniqueName}
|
2491
|
+
arrays.set(name, allocPage(`${itemType === 'i16' ? 'string' : 'array'}: ${uniqueName}`, itemType) * pageSize);
|
1547
2492
|
}
|
1548
2493
|
|
1549
2494
|
const pointer = arrays.get(name);
|
@@ -1551,8 +2496,29 @@ const makeArray = (scope, decl, global = false, name = '$undeclared', initEmpty
|
|
1551
2496
|
const useRawElements = !!decl.rawElements;
|
1552
2497
|
const elements = useRawElements ? decl.rawElements : decl.elements;
|
1553
2498
|
|
2499
|
+
const valtype = itemTypeToValtype[itemType];
|
1554
2500
|
const length = elements.length;
|
1555
2501
|
|
2502
|
+
if (firstAssign && useRawElements) {
|
2503
|
+
let bytes = compileBytes(length, 'i32');
|
2504
|
+
|
2505
|
+
if (!initEmpty) for (let i = 0; i < length; i++) {
|
2506
|
+
if (elements[i] == null) continue;
|
2507
|
+
|
2508
|
+
bytes.push(...compileBytes(elements[i], itemType));
|
2509
|
+
}
|
2510
|
+
|
2511
|
+
data.push({
|
2512
|
+
offset: pointer,
|
2513
|
+
bytes
|
2514
|
+
});
|
2515
|
+
|
2516
|
+
// local value as pointer
|
2517
|
+
out.push(...number(pointer));
|
2518
|
+
|
2519
|
+
return [ out, pointer ];
|
2520
|
+
}
|
2521
|
+
|
1556
2522
|
// store length as 0th array
|
1557
2523
|
out.push(
|
1558
2524
|
...number(0, Valtype.i32),
|
@@ -1560,8 +2526,7 @@ const makeArray = (scope, decl, global = false, name = '$undeclared', initEmpty
|
|
1560
2526
|
[ Opcodes.i32_store, Math.log2(ValtypeSize.i32) - 1, ...unsignedLEB128(pointer) ]
|
1561
2527
|
);
|
1562
2528
|
|
1563
|
-
const storeOp =
|
1564
|
-
const valtype = itemTypeToValtype[itemType];
|
2529
|
+
const storeOp = StoreOps[itemType];
|
1565
2530
|
|
1566
2531
|
if (!initEmpty) for (let i = 0; i < length; i++) {
|
1567
2532
|
if (elements[i] == null) continue;
|
@@ -1576,30 +2541,34 @@ const makeArray = (scope, decl, global = false, name = '$undeclared', initEmpty
|
|
1576
2541
|
// local value as pointer
|
1577
2542
|
out.push(...number(pointer));
|
1578
2543
|
|
1579
|
-
|
2544
|
+
return [ out, pointer ];
|
2545
|
+
};
|
1580
2546
|
|
1581
|
-
|
2547
|
+
const makeString = (scope, str, global = false, name = '$undeclared') => {
|
2548
|
+
const rawElements = new Array(str.length);
|
2549
|
+
for (let i = 0; i < str.length; i++) {
|
2550
|
+
rawElements[i] = str.charCodeAt(i);
|
2551
|
+
}
|
2552
|
+
|
2553
|
+
return makeArray(scope, {
|
2554
|
+
rawElements
|
2555
|
+
}, global, name, false, 'i16')[0];
|
1582
2556
|
};
|
1583
2557
|
|
1584
2558
|
let arrays = new Map();
|
1585
2559
|
const generateArray = (scope, decl, global = false, name = '$undeclared', initEmpty = false) => {
|
1586
|
-
return makeArray(scope, decl, global, name, initEmpty, valtype);
|
2560
|
+
return makeArray(scope, decl, global, name, initEmpty, valtype)[0];
|
1587
2561
|
};
|
1588
2562
|
|
1589
2563
|
export const generateMember = (scope, decl, _global, _name) => {
|
1590
|
-
const
|
2564
|
+
const name = decl.object.name;
|
2565
|
+
const pointer = arrays.get(name);
|
2566
|
+
|
2567
|
+
const aotPointer = pointer != null;
|
1591
2568
|
|
1592
2569
|
// hack: .length
|
1593
2570
|
if (decl.property.name === 'length') {
|
1594
2571
|
// 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
2572
|
return [
|
1604
2573
|
...(aotPointer ? number(0, Valtype.i32) : [
|
1605
2574
|
...generate(scope, decl.object),
|
@@ -1611,18 +2580,17 @@ export const generateMember = (scope, decl, _global, _name) => {
|
|
1611
2580
|
];
|
1612
2581
|
}
|
1613
2582
|
|
1614
|
-
//
|
1615
|
-
|
1616
|
-
|
1617
|
-
|
1618
|
-
|
1619
|
-
|
1620
|
-
|
1621
|
-
|
1622
|
-
const aotPointer = pointer != null;
|
2583
|
+
// // todo: we should only do this for strings but we don't know at compile-time :(
|
2584
|
+
// hack: this is naughty and will break things!
|
2585
|
+
let newOut = number(0, valtypeBinary), newPointer = -1;
|
2586
|
+
if (pages.hasString) {
|
2587
|
+
0, [ newOut, newPointer ] = makeArray(scope, {
|
2588
|
+
rawElements: new Array(1)
|
2589
|
+
}, _global, _name, true, 'i16');
|
2590
|
+
}
|
1623
2591
|
|
1624
|
-
|
1625
|
-
|
2592
|
+
return typeSwitch(scope, getNodeType(scope, decl.object), {
|
2593
|
+
[TYPES._array]: [
|
1626
2594
|
// get index as valtype
|
1627
2595
|
...generate(scope, decl.property),
|
1628
2596
|
|
@@ -1638,45 +2606,46 @@ export const generateMember = (scope, decl, _global, _name) => {
|
|
1638
2606
|
]),
|
1639
2607
|
|
1640
2608
|
// read from memory
|
1641
|
-
[ Opcodes.load, Math.log2(ValtypeSize[valtype]) - 1, ...unsignedLEB128((aotPointer ? pointer : 0) + ValtypeSize.i32) ]
|
1642
|
-
];
|
1643
|
-
}
|
2609
|
+
[ Opcodes.load, Math.log2(ValtypeSize[valtype]) - 1, ...unsignedLEB128((aotPointer ? pointer : 0) + ValtypeSize.i32) ],
|
1644
2610
|
|
1645
|
-
|
2611
|
+
...number(TYPES.number, Valtype.i32),
|
2612
|
+
setLastType(scope)
|
2613
|
+
],
|
1646
2614
|
|
1647
|
-
|
1648
|
-
|
1649
|
-
|
1650
|
-
|
2615
|
+
[TYPES.string]: [
|
2616
|
+
// setup new/out array
|
2617
|
+
...newOut,
|
2618
|
+
[ Opcodes.drop ],
|
1651
2619
|
|
1652
|
-
|
1653
|
-
// setup new/out array
|
1654
|
-
...newOut,
|
1655
|
-
[ Opcodes.drop ],
|
2620
|
+
...number(0, Valtype.i32), // base 0 for store later
|
1656
2621
|
|
1657
|
-
|
2622
|
+
...generate(scope, decl.property),
|
1658
2623
|
|
1659
|
-
|
2624
|
+
Opcodes.i32_to_u,
|
2625
|
+
...number(ValtypeSize.i16, Valtype.i32),
|
2626
|
+
[ Opcodes.i32_mul ],
|
1660
2627
|
|
1661
|
-
|
1662
|
-
|
1663
|
-
|
2628
|
+
...(aotPointer ? [] : [
|
2629
|
+
...generate(scope, decl.object),
|
2630
|
+
Opcodes.i32_to_u,
|
2631
|
+
[ Opcodes.i32_add ]
|
2632
|
+
]),
|
1664
2633
|
|
1665
|
-
|
1666
|
-
|
1667
|
-
|
1668
|
-
|
1669
|
-
|
2634
|
+
// load current string ind {arg}
|
2635
|
+
[ Opcodes.i32_load16_u, Math.log2(ValtypeSize.i16) - 1, ...unsignedLEB128((aotPointer ? pointer : 0) + ValtypeSize.i32) ],
|
2636
|
+
|
2637
|
+
// store to new string ind 0
|
2638
|
+
[ Opcodes.i32_store16, Math.log2(ValtypeSize.i16) - 1, ...unsignedLEB128(newPointer + ValtypeSize.i32) ],
|
1670
2639
|
|
1671
|
-
|
1672
|
-
|
2640
|
+
// return new string (page)
|
2641
|
+
...number(newPointer),
|
1673
2642
|
|
1674
|
-
|
1675
|
-
|
2643
|
+
...number(TYPES.string, Valtype.i32),
|
2644
|
+
setLastType(scope)
|
2645
|
+
],
|
1676
2646
|
|
1677
|
-
|
1678
|
-
|
1679
|
-
];
|
2647
|
+
default: [ [ Opcodes.unreachable ] ]
|
2648
|
+
});
|
1680
2649
|
};
|
1681
2650
|
|
1682
2651
|
const randId = () => Math.random().toString(16).slice(0, -4);
|
@@ -1721,22 +2690,25 @@ const generateFunc = (scope, decl) => {
|
|
1721
2690
|
if (decl.generator) return todo('generator functions are not supported');
|
1722
2691
|
|
1723
2692
|
const name = decl.id ? decl.id.name : `anonymous_${randId()}`;
|
1724
|
-
const params = decl.params
|
2693
|
+
const params = decl.params ?? [];
|
1725
2694
|
|
1726
2695
|
// const innerScope = { ...scope };
|
1727
2696
|
// TODO: share scope/locals between !!!
|
1728
2697
|
const innerScope = {
|
1729
2698
|
locals: {},
|
1730
2699
|
localInd: 0,
|
1731
|
-
|
1732
|
-
|
2700
|
+
// value, type
|
2701
|
+
returns: [ valtypeBinary, Valtype.i32 ],
|
1733
2702
|
throws: false,
|
1734
2703
|
name
|
1735
2704
|
};
|
1736
2705
|
|
1737
2706
|
for (let i = 0; i < params.length; i++) {
|
1738
|
-
|
1739
|
-
|
2707
|
+
allocVar(innerScope, params[i].name, false);
|
2708
|
+
|
2709
|
+
if (typedInput && params[i].typeAnnotation) {
|
2710
|
+
addVarMetadata(innerScope, params[i].name, false, extractTypeAnnotation(params[i]));
|
2711
|
+
}
|
1740
2712
|
}
|
1741
2713
|
|
1742
2714
|
let body = objectHack(decl.body);
|
@@ -1751,11 +2723,9 @@ const generateFunc = (scope, decl) => {
|
|
1751
2723
|
const wasm = generate(innerScope, body);
|
1752
2724
|
const func = {
|
1753
2725
|
name,
|
1754
|
-
params: Object.values(innerScope.locals).slice(0, params.length).map(x => x.type),
|
2726
|
+
params: Object.values(innerScope.locals).slice(0, params.length * 2).map(x => x.type),
|
1755
2727
|
returns: innerScope.returns,
|
1756
|
-
returnType: innerScope.returnType ?? TYPES.number,
|
1757
2728
|
locals: innerScope.locals,
|
1758
|
-
memory: innerScope.memory,
|
1759
2729
|
throws: innerScope.throws,
|
1760
2730
|
index: currentFuncIndex++
|
1761
2731
|
};
|
@@ -1768,121 +2738,13 @@ const generateFunc = (scope, decl) => {
|
|
1768
2738
|
}
|
1769
2739
|
}
|
1770
2740
|
|
1771
|
-
|
1772
|
-
|
1773
|
-
|
1774
|
-
|
1775
|
-
|
1776
|
-
|
1777
|
-
for (let i = 0; i < params.length; i++) {
|
1778
|
-
const name = params[i];
|
1779
|
-
const local = func.locals[name];
|
1780
|
-
if (local.type === Valtype.v128) {
|
1781
|
-
vecParams++;
|
1782
|
-
|
1783
|
-
/* func.memory = true; // mark func as using memory
|
1784
|
-
|
1785
|
-
wasm.unshift( // add v128 load for param
|
1786
|
-
[ Opcodes.i32_const, 0 ],
|
1787
|
-
[ ...Opcodes.v128_load, 0, i * 16 ],
|
1788
|
-
[ Opcodes.local_set, local.idx ]
|
1789
|
-
); */
|
1790
|
-
|
1791
|
-
// using params and replace_lane is noticably faster than just loading from memory (above) somehow
|
1792
|
-
|
1793
|
-
// extract valtype and lane count from vec type (i32x4 = i32 4, i8x16 = i8 16, etc)
|
1794
|
-
const { vecType } = local;
|
1795
|
-
let [ type, lanes ] = vecType.split('x');
|
1796
|
-
if (!type || !lanes) throw new Error('bad metadata from vec params'); // sanity check
|
1797
|
-
|
1798
|
-
lanes = parseInt(lanes);
|
1799
|
-
type = Valtype[type];
|
1800
|
-
|
1801
|
-
const name = params[i]; // get original param name
|
1802
|
-
|
1803
|
-
func.params.splice(offset, 1, ...new Array(lanes).fill(type)); // add new params of {type}, {lanes} times
|
1804
|
-
|
1805
|
-
// update index of original local
|
1806
|
-
// delete func.locals[name];
|
1807
|
-
|
1808
|
-
// add new locals for params
|
1809
|
-
for (let j = 0; j < lanes; j++) {
|
1810
|
-
func.locals[name + j] = { idx: offset + j, type, vecParamAutogen: true };
|
1811
|
-
}
|
1812
|
-
|
1813
|
-
// prepend wasm to generate expected v128 locals
|
1814
|
-
wasm.splice(i * 2 + offset * 2, 0,
|
1815
|
-
...i32x4(0, 0, 0, 0),
|
1816
|
-
...new Array(lanes).fill(0).flatMap((_, j) => [
|
1817
|
-
[ Opcodes.local_get, offset + j ],
|
1818
|
-
[ ...Opcodes[vecType + '_replace_lane'], j ]
|
1819
|
-
]),
|
1820
|
-
[ Opcodes.local_set, i ]
|
1821
|
-
);
|
1822
|
-
|
1823
|
-
offset += lanes;
|
1824
|
-
|
1825
|
-
// note: wrapping is disabled for now due to perf/dx concerns (so this will never run)
|
1826
|
-
/* if (!func.name.startsWith('#')) func.name = '##' + func.name;
|
1827
|
-
|
1828
|
-
// add vec type index to hash name prefix for wrapper to know how to wrap
|
1829
|
-
const vecTypeIdx = [ 'i8x16', 'i16x8', 'i32x4', 'i64x2', 'f32x4', 'f64x2' ].indexOf(local.vecType);
|
1830
|
-
const secondHash = func.name.slice(1).indexOf('#');
|
1831
|
-
func.name = '#' + func.name.slice(1, secondHash) + vecTypeIdx + func.name.slice(secondHash); */
|
1832
|
-
}
|
1833
|
-
}
|
1834
|
-
|
1835
|
-
if (offset !== 0) {
|
1836
|
-
// bump local indexes for all other locals after
|
1837
|
-
for (const x in func.locals) {
|
1838
|
-
const local = func.locals[x];
|
1839
|
-
if (!local.vecParamAutogen) local.idx += offset;
|
1840
|
-
}
|
1841
|
-
|
1842
|
-
// bump local indexes in wasm local.get/set
|
1843
|
-
for (let j = 0; j < wasm.length; j++) {
|
1844
|
-
const inst = wasm[j];
|
1845
|
-
if (j < offset * 2 + vecParams * 2) {
|
1846
|
-
if (inst[0] === Opcodes.local_set) inst[1] += offset;
|
1847
|
-
continue;
|
1848
|
-
}
|
1849
|
-
|
1850
|
-
if (inst[0] === Opcodes.local_get || inst[0] === Opcodes.local_set) inst[1] += offset;
|
1851
|
-
}
|
1852
|
-
}
|
1853
|
-
|
1854
|
-
// change v128 return into many <type> instead as unsupported return valtype
|
1855
|
-
const lastReturnLocal = wasm.length > 2 && wasm[wasm.length - 1][0] === Opcodes.return && Object.values(func.locals).find(x => x.idx === wasm[wasm.length - 2][1]);
|
1856
|
-
if (lastReturnLocal && lastReturnLocal.type === Valtype.v128) {
|
1857
|
-
const name = Object.keys(func.locals)[Object.values(func.locals).indexOf(lastReturnLocal)];
|
1858
|
-
// extract valtype and lane count from vec type (i32x4 = i32 4, i8x16 = i8 16, etc)
|
1859
|
-
const { vecType } = lastReturnLocal;
|
1860
|
-
let [ type, lanes ] = vecType.split('x');
|
1861
|
-
if (!type || !lanes) throw new Error('bad metadata from vec params'); // sanity check
|
1862
|
-
|
1863
|
-
lanes = parseInt(lanes);
|
1864
|
-
type = Valtype[type];
|
1865
|
-
|
1866
|
-
const vecIdx = lastReturnLocal.idx;
|
1867
|
-
|
1868
|
-
const lastIdx = Math.max(0, ...Object.values(func.locals).map(x => x.idx));
|
1869
|
-
const tmpIdx = [];
|
1870
|
-
for (let i = 0; i < lanes; i++) {
|
1871
|
-
const idx = lastIdx + i + 1;
|
1872
|
-
tmpIdx.push(idx);
|
1873
|
-
func.locals[name + i] = { idx, type, vecReturnAutogen: true };
|
1874
|
-
}
|
1875
|
-
|
1876
|
-
wasm.splice(wasm.length - 1, 1,
|
1877
|
-
...new Array(lanes).fill(0).flatMap((_, i) => [
|
1878
|
-
i === 0 ? null : [ Opcodes.local_get, vecIdx ],
|
1879
|
-
[ ...Opcodes[vecType + '_extract_lane'], i ],
|
1880
|
-
[ Opcodes.local_set, tmpIdx[i] ],
|
1881
|
-
].filter(x => x !== null)),
|
1882
|
-
...new Array(lanes).fill(0).map((_, i) => [ Opcodes.local_get, tmpIdx[i]])
|
2741
|
+
// add end return if not found
|
2742
|
+
if (name !== 'main' && wasm[wasm.length - 1]?.[0] !== Opcodes.return && countLeftover(wasm) === 0) {
|
2743
|
+
wasm.push(
|
2744
|
+
...number(0),
|
2745
|
+
...number(TYPES.undefined, Valtype.i32),
|
2746
|
+
[ Opcodes.return ]
|
1883
2747
|
);
|
1884
|
-
|
1885
|
-
func.returns = new Array(lanes).fill(type);
|
1886
2748
|
}
|
1887
2749
|
|
1888
2750
|
func.wasm = wasm;
|
@@ -1893,10 +2755,10 @@ const generateFunc = (scope, decl) => {
|
|
1893
2755
|
};
|
1894
2756
|
|
1895
2757
|
const generateCode = (scope, decl) => {
|
1896
|
-
|
2758
|
+
let out = [];
|
1897
2759
|
|
1898
2760
|
for (const x of decl.body) {
|
1899
|
-
out.
|
2761
|
+
out = out.concat(generate(scope, x));
|
1900
2762
|
}
|
1901
2763
|
|
1902
2764
|
return out;
|
@@ -1912,10 +2774,9 @@ const internalConstrs = {
|
|
1912
2774
|
|
1913
2775
|
// new Array(n)
|
1914
2776
|
|
1915
|
-
makeArray(scope, {
|
2777
|
+
const [ , pointer ] = makeArray(scope, {
|
1916
2778
|
rawElements: new Array(0)
|
1917
2779
|
}, global, name, true);
|
1918
|
-
const pointer = arrays.get(name ?? '$undeclared');
|
1919
2780
|
|
1920
2781
|
const arg = decl.arguments[0] ?? DEFAULT_VALUE;
|
1921
2782
|
|
@@ -1933,9 +2794,38 @@ const internalConstrs = {
|
|
1933
2794
|
];
|
1934
2795
|
},
|
1935
2796
|
type: TYPES._array
|
2797
|
+
},
|
2798
|
+
|
2799
|
+
__Array_of: {
|
2800
|
+
// this is not a constructor but best fits internal structure here
|
2801
|
+
generate: (scope, decl, global, name) => {
|
2802
|
+
// Array.of(i0, i1, ...)
|
2803
|
+
return generateArray(scope, {
|
2804
|
+
elements: decl.arguments
|
2805
|
+
}, global, name);
|
2806
|
+
},
|
2807
|
+
type: TYPES._array,
|
2808
|
+
notConstr: true
|
1936
2809
|
}
|
1937
2810
|
};
|
1938
2811
|
|
2812
|
+
// const _ = Array.prototype.push;
|
2813
|
+
// Array.prototype.push = function (a) {
|
2814
|
+
// const check = arr => {
|
2815
|
+
// for (const x of arr) {
|
2816
|
+
// if (x === undefined) {
|
2817
|
+
// console.trace(arr);
|
2818
|
+
// process.exit();
|
2819
|
+
// }
|
2820
|
+
// if (Array.isArray(x)) check(x);
|
2821
|
+
// }
|
2822
|
+
// };
|
2823
|
+
// if (Array.isArray(a) && !new Error().stack.includes('node:')) check(a);
|
2824
|
+
// // if (Array.isArray(a)) check(a);
|
2825
|
+
|
2826
|
+
// return _.apply(this, arguments);
|
2827
|
+
// };
|
2828
|
+
|
1939
2829
|
export default program => {
|
1940
2830
|
globals = {};
|
1941
2831
|
globalInd = 0;
|
@@ -1944,9 +2834,9 @@ export default program => {
|
|
1944
2834
|
funcs = [];
|
1945
2835
|
funcIndex = {};
|
1946
2836
|
depth = [];
|
1947
|
-
typeStates = {};
|
1948
2837
|
arrays = new Map();
|
1949
2838
|
pages = new Map();
|
2839
|
+
data = [];
|
1950
2840
|
currentFuncIndex = importedFuncs.length;
|
1951
2841
|
|
1952
2842
|
globalThis.valtype = 'f64';
|
@@ -1996,18 +2886,20 @@ export default program => {
|
|
1996
2886
|
body: program.body
|
1997
2887
|
};
|
1998
2888
|
|
2889
|
+
if (process.argv.includes('-ast-log')) console.log(program.body.body);
|
2890
|
+
|
1999
2891
|
generateFunc(scope, program);
|
2000
2892
|
|
2001
2893
|
const main = funcs[funcs.length - 1];
|
2002
2894
|
main.export = true;
|
2003
|
-
main.returns = [ valtypeBinary ];
|
2895
|
+
main.returns = [ valtypeBinary, Valtype.i32 ];
|
2004
2896
|
|
2005
2897
|
const lastInst = main.wasm[main.wasm.length - 1] ?? [ Opcodes.end ];
|
2006
2898
|
if (lastInst[0] === Opcodes.drop) {
|
2007
2899
|
main.wasm.splice(main.wasm.length - 1, 1);
|
2008
2900
|
|
2009
2901
|
const finalStatement = program.body.body[program.body.body.length - 1];
|
2010
|
-
main.
|
2902
|
+
main.wasm.push(...getNodeType(main, finalStatement));
|
2011
2903
|
}
|
2012
2904
|
|
2013
2905
|
if (lastInst[0] === Opcodes.end || lastInst[0] === Opcodes.local_set || lastInst[0] === Opcodes.global_set) {
|
@@ -2023,5 +2915,5 @@ export default program => {
|
|
2023
2915
|
// if blank main func and other exports, remove it
|
2024
2916
|
if (main.wasm.length === 0 && funcs.reduce((acc, x) => acc + (x.export ? 1 : 0), 0) > 1) funcs.splice(funcs.length - 1, 1);
|
2025
2917
|
|
2026
|
-
return { funcs, globals, tags, exceptions, pages };
|
2918
|
+
return { funcs, globals, tags, exceptions, pages, data };
|
2027
2919
|
};
|