binaryen 0.0.5.0 → 0.0.6.0
raw patch · 571 files changed
+43073/−50101 lines, 571 filesbinary-addedPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
- Binaryen.Op: allTrueVecI64x2 :: Op
- Binaryen.Op: anyTrueVecI64x2 :: Op
+ Binaryen.Index: instance GHC.Classes.Ord Binaryen.Index.Index
+ Binaryen.Index: instance GHC.Enum.Enum Binaryen.Index.Index
+ Binaryen.Index: instance GHC.Real.Integral Binaryen.Index.Index
+ Binaryen.Index: instance GHC.Real.Real Binaryen.Index.Index
- Binaryen.Expression: refFunc :: Module -> Ptr CChar -> IO Expression
+ Binaryen.Expression: refFunc :: Module -> Ptr CChar -> Type -> IO Expression
- Binaryen.Module: getNumExports :: Module -> IO Word32
+ Binaryen.Module: getNumExports :: Module -> IO Index
- Binaryen.Module: getNumFunctions :: Module -> IO Word32
+ Binaryen.Module: getNumFunctions :: Module -> IO Index
Files
- README.md +2/−1
- binaryen.cabal +94/−57
- binaryen/CHANGELOG.md +15/−0
- binaryen/CMakeLists.txt +9/−1
- binaryen/auto_update_tests.py +3/−16
- binaryen/check.py +31/−36
- binaryen/requirements-dev.txt +8/−0
- binaryen/scripts/binaryen-lit.in +33/−0
- binaryen/scripts/clean_c_api_trace.py +0/−37
- binaryen/scripts/fuzz_opt.py +243/−74
- binaryen/scripts/gen-s-parser.py +45/−5
- binaryen/scripts/not.py +30/−0
- binaryen/scripts/process_optimize_instructions.py +0/−16
- binaryen/scripts/test/generate_lld_tests.py +7/−2
- binaryen/scripts/test/lld.py +9/−5
- binaryen/scripts/test/shared.py +16/−22
- binaryen/scripts/test/wasm_opt.py +4/−2
- binaryen/src/abi/abi.h +0/−33
- binaryen/src/abi/stack.h +0/−144
- binaryen/src/abi/wasm-object.h +0/−40
- binaryen/src/asm_v_wasm.h +0/−17
- binaryen/src/asmjs/asm_v_wasm.cpp +0/−38
- binaryen/src/asmjs/shared-constants.cpp +1/−9
- binaryen/src/asmjs/shared-constants.h +2/−10
- binaryen/src/binaryen-c.cpp +62/−186
- binaryen/src/binaryen-c.h +59/−93
- binaryen/src/config.h +1/−1
- binaryen/src/dataflow/utils.h +1/−2
- binaryen/src/gen-s-parser.inc +319/−65
- binaryen/src/ir/CMakeLists.txt +1/−0
- binaryen/src/ir/ExpressionAnalyzer.cpp +142/−322
- binaryen/src/ir/ExpressionManipulator.cpp +81/−287
- binaryen/src/ir/LocalGraph.cpp +0/−1
- binaryen/src/ir/ReFinalize.cpp +15/−2
- binaryen/src/ir/abstract.h +5/−0
- binaryen/src/ir/branch-utils.h +119/−124
- binaryen/src/ir/cost.h +178/−325
- binaryen/src/ir/effects.h +361/−295
- binaryen/src/ir/features.h +0/−2
- binaryen/src/ir/global-utils.h +3/−2
- binaryen/src/ir/module-splitting.cpp +595/−0
- binaryen/src/ir/module-splitting.h +76/−0
- binaryen/src/ir/module-utils.h +151/−27
- binaryen/src/ir/names.h +35/−0
- binaryen/src/ir/properties.h +51/−49
- binaryen/src/ir/type-updating.h +23/−34
- binaryen/src/ir/utils.h +8/−126
- binaryen/src/js/binaryen.js-post.js +34/−30
- binaryen/src/literal.h +85/−12
- binaryen/src/parsing.h +1/−2
- binaryen/src/pass.h +20/−12
- binaryen/src/passes/Asyncify.cpp +9/−6
- binaryen/src/passes/CMakeLists.txt +1/−3
- binaryen/src/passes/CodePushing.cpp +2/−2
- binaryen/src/passes/DeadArgumentElimination.cpp +40/−7
- binaryen/src/passes/DeadCodeElimination.cpp +95/−491
- binaryen/src/passes/Directize.cpp +33/−12
- binaryen/src/passes/DuplicateImportElimination.cpp +0/−1
- binaryen/src/passes/EmscriptenPIC.cpp +0/−221
- binaryen/src/passes/Flatten.cpp +2/−0
- binaryen/src/passes/FuncCastEmulation.cpp +20/−19
- binaryen/src/passes/GenerateDynCalls.cpp +3/−3
- binaryen/src/passes/I64ToI32Lowering.cpp +8/−6
- binaryen/src/passes/Inlining.cpp +24/−15
- binaryen/src/passes/InstrumentLocals.cpp +7/−3
- binaryen/src/passes/InstrumentMemory.cpp +0/−1
- binaryen/src/passes/LegalizeJSInterface.cpp +3/−4
- binaryen/src/passes/LogExecution.cpp +0/−1
- binaryen/src/passes/LoopInvariantCodeMotion.cpp +8/−5
- binaryen/src/passes/Memory64Lowering.cpp +101/−0
- binaryen/src/passes/MemoryPacking.cpp +116/−12
- binaryen/src/passes/MergeBlocks.cpp +5/−1
- binaryen/src/passes/OptimizeInstructions.cpp +2434/−1933
- binaryen/src/passes/PickLoadSigns.cpp +4/−0
- binaryen/src/passes/PostAssemblyScript.cpp +10/−11
- binaryen/src/passes/PostEmscripten.cpp +2/−38
- binaryen/src/passes/Precompute.cpp +37/−0
- binaryen/src/passes/Print.cpp +557/−117
- binaryen/src/passes/ReReloop.cpp +1/−5
- binaryen/src/passes/RemoveNonJSOps.cpp +0/−7
- binaryen/src/passes/RemoveUnusedBrs.cpp +25/−11
- binaryen/src/passes/RemoveUnusedModuleElements.cpp +0/−1
- binaryen/src/passes/RemoveUnusedNames.cpp +15/−29
- binaryen/src/passes/ReplaceStackPointer.cpp +0/−103
- binaryen/src/passes/SafeHeap.cpp +13/−9
- binaryen/src/passes/SimplifyLocals.cpp +11/−4
- binaryen/src/passes/Souperify.cpp +1/−2
- binaryen/src/passes/SpillPointers.cpp +0/−206
- binaryen/src/passes/StackCheck.cpp +38/−39
- binaryen/src/passes/TrapMode.cpp +12/−2
- binaryen/src/passes/Vacuum.cpp +65/−148
- binaryen/src/passes/WasmIntrinsics.cpp +2/−2
- binaryen/src/passes/pass.cpp +23/−26
- binaryen/src/passes/passes.h +1/−4
- binaryen/src/passes/wasm-intrinsics.wat +0/−34
- binaryen/src/shared-constants.h +3/−1
- binaryen/src/shell-interface.h +1/−1
- binaryen/src/support/bits.cpp +33/−1
- binaryen/src/support/bits.h +3/−0
- binaryen/src/support/file.h +1/−1
- binaryen/src/support/small_vector.h +8/−0
- binaryen/src/support/space.h +84/−0
- binaryen/src/support/string.h +4/−0
- binaryen/src/tools/execution-results.h +69/−14
- binaryen/src/tools/fuzzing.h +466/−175
- binaryen/src/tools/optimization-options.h +8/−1
- binaryen/src/tools/tool-options.h +3/−1
- binaryen/src/tools/wasm-ctor-eval.cpp +2/−1
- binaryen/src/tools/wasm-dis.cpp +1/−3
- binaryen/src/tools/wasm-emscripten-finalize.cpp +12/−67
- binaryen/src/tools/wasm-metadce.cpp +1/−1
- binaryen/src/tools/wasm-opt.cpp +20/−7
- binaryen/src/tools/wasm-reduce.cpp +23/−6
- binaryen/src/tools/wasm-shell.cpp +1/−2
- binaryen/src/tools/wasm-split.cpp +671/−0
- binaryen/src/tools/wasm2c-wrapper.h +56/−27
- binaryen/src/tools/wasm2js.cpp +1/−1
- binaryen/src/wasm-binary.h +103/−94
- binaryen/src/wasm-builder.h +153/−72
- binaryen/src/wasm-delegations-fields.h +674/−0
- binaryen/src/wasm-delegations.h +84/−0
- binaryen/src/wasm-emscripten.h +1/−10
- binaryen/src/wasm-features.h +10/−1
- binaryen/src/wasm-interpreter.h +421/−30
- binaryen/src/wasm-module-building.h +0/−9
- binaryen/src/wasm-printing.h +0/−70
- binaryen/src/wasm-s-parser.h +33/−9
- binaryen/src/wasm-stack.h +4/−63
- binaryen/src/wasm-traversal.h +308/−1367
- binaryen/src/wasm-type.h +185/−87
- binaryen/src/wasm-validator.h +0/−1
- binaryen/src/wasm.h +213/−43
- binaryen/src/wasm/literal.cpp +265/−122
- binaryen/src/wasm/wasm-binary.cpp +713/−241
- binaryen/src/wasm/wasm-debug.cpp +27/−6
- binaryen/src/wasm/wasm-emscripten.cpp +31/−103
- binaryen/src/wasm/wasm-io.cpp +1/−1
- binaryen/src/wasm/wasm-s-parser.cpp +375/−156
- binaryen/src/wasm/wasm-stack.cpp +227/−30
- binaryen/src/wasm/wasm-type.cpp +1374/−882
- binaryen/src/wasm/wasm-validator.cpp +316/−119
- binaryen/src/wasm/wasm.cpp +258/−140
- binaryen/src/wasm2js.h +157/−146
- binaryen/test/atomics.wast +6/−6
- binaryen/test/atomics.wast.from-wast +6/−6
- binaryen/test/atomics.wast.fromBinary +6/−6
- binaryen/test/atomics.wast.fromBinary.noDebugInfo +6/−6
- binaryen/test/atomics64.wast +6/−6
- binaryen/test/atomics64.wast.from-wast +6/−6
- binaryen/test/atomics64.wast.fromBinary +6/−6
- binaryen/test/atomics64.wast.fromBinary.noDebugInfo +6/−6
- binaryen/test/bad_params.asm.js +0/−30
- binaryen/test/binaryen.js/atomics.js +3/−3
- binaryen/test/binaryen.js/atomics.js.txt +3/−3
- binaryen/test/binaryen.js/emit_asmjs.js.txt +14/−26
- binaryen/test/binaryen.js/exception-handling.js.txt +4/−4
- binaryen/test/binaryen.js/expressions.js +7/−6
- binaryen/test/binaryen.js/expressions.js.txt +2/−2
- binaryen/test/binaryen.js/kitchen-sink.js +15/−7
- binaryen/test/binaryen.js/kitchen-sink.js.txt +50/−67
- binaryen/test/binaryen.js/validation_errors.js.txt +2/−2
- binaryen/test/debugInfo.asm.js +0/−102
- binaryen/test/dylib.wasm.fromBinary +3/−3
- binaryen/test/dynamicLibrary.asm.js +0/−136
- binaryen/test/emcc_O2_hello_world.asm.js +0/−2293
- binaryen/test/emcc_hello_world.asm.js +0/−7101
- binaryen/test/empty.asm.js +0/−4
- binaryen/test/empty_4GB.asm.js +0/−4
- binaryen/test/example/c-api-kitchen-sink.c +44/−18
- binaryen/test/example/c-api-kitchen-sink.txt +28/−29
- binaryen/test/example/c-api-kitchen-sink.txt.txt +0/−2236
- binaryen/test/example/c-api-unused-mem.txt +1/−1
- binaryen/test/example/cpp-unit.cpp +14/−0
- binaryen/test/example/hash.cpp +142/−0
- binaryen/test/example/hash.txt +1/−0
- binaryen/test/example/module-splitting.cpp +397/−0
- binaryen/test/example/module-splitting.txt +981/−0
- binaryen/test/example/space.cpp +115/−0
- binaryen/test/example/space.txt +1/−0
- binaryen/test/example/stack-utils.cpp +2/−5
- binaryen/test/example/type-builder.cpp +142/−0
- binaryen/test/example/type-builder.txt +24/−0
- binaryen/test/example/typeinfo.cpp +177/−159
- binaryen/test/export-import.wast.fromBinary.noDebugInfo +2/−2
- binaryen/test/extended-names.wast +6/−0
- binaryen/test/extended-names.wast.from-wast +6/−0
- binaryen/test/extended-names.wast.fromBinary +7/−0
- binaryen/test/extended-names.wast.fromBinary.noDebugInfo +7/−0
- binaryen/test/extra-unreachable.wast +5/−5
- binaryen/test/extra-unreachable.wast.from-wast +5/−4
- binaryen/test/fib-dbg.wasm.fromBinary +4/−4
- binaryen/test/gc.wast +5/−0
- binaryen/test/gc.wast.from-wast +7/−2
- binaryen/test/gc.wast.fromBinary +7/−2
- binaryen/test/gc.wast.fromBinary.noDebugInfo +7/−2
- binaryen/test/heap-types.wast +185/−0
- binaryen/test/heap-types.wast.from-wast +199/−0
- binaryen/test/heap-types.wast.fromBinary +196/−0
- binaryen/test/heap-types.wast.fromBinary.noDebugInfo +196/−0
- binaryen/test/hello_world.asm.js +0/−10
- binaryen/test/i64-setTempRet0.asm.js +0/−24
- binaryen/test/importedSignCast.asm.js +0/−14
- binaryen/test/imported_memory.wast.fromBinary.noDebugInfo +1/−1
- binaryen/test/imported_memory_growth.wast.fromBinary.noDebugInfo +1/−1
- binaryen/test/lit/CMakeLists.txt +1/−0
- binaryen/test/lit/lit.cfg.py +21/−0
- binaryen/test/lit/lit.site.cfg.py.in +7/−0
- binaryen/test/lit/parse-error.wast +10/−0
- binaryen/test/lit/validation/shared-memory.wast +11/−0
- binaryen/test/lit/wasm-emscripten-finalize/bigint.wat +22/−0
- binaryen/test/lit/wasm-emscripten-finalize/passive-pic.wat +38/−0
- binaryen/test/lit/wasm-split/basic.wast +141/−0
- binaryen/test/lit/wasm-split/call_exports.mjs +25/−0
- binaryen/test/lit/wasm-split/export-name-already-exists.wast +8/−0
- binaryen/test/lit/wasm-split/initial-table.wast +13/−0
- binaryen/test/lit/wasm-split/instrument-funcs.wast +75/−0
- binaryen/test/lit/wasm-split/instrument-memory-too-small.wast +10/−0
- binaryen/test/lit/wasm-split/invalid-options.wast +64/−0
- binaryen/test/lit/wasm-split/mismatched-hashes.wast +23/−0
- binaryen/test/lit/wasm-split/name-collision.wast +16/−0
- binaryen/test/lit/wasm-split/profile-guided.wast +67/−0
- binaryen/test/lit/wasm-split/verbose.wast +14/−0
- binaryen/test/lld/basic_safe_stack.wat +0/−2
- binaryen/test/lld/basic_safe_stack.wat.out +0/−4
- binaryen/test/lld/bigint.wat +0/−10
- binaryen/test/lld/bigint.wat.out +0/−42
- binaryen/test/lld/duplicate_imports.wat.out +1/−2
- binaryen/test/lld/em_asm.wat +0/−2
- binaryen/test/lld/em_asm.wat.mem.out +0/−4
- binaryen/test/lld/em_asm.wat.out +0/−4
- binaryen/test/lld/em_asm64.cpp +8/−0
- binaryen/test/lld/em_asm64.wat +68/−0
- binaryen/test/lld/em_asm64.wat.out +99/−0
- binaryen/test/lld/em_asm_O0.wat +0/−2
- binaryen/test/lld/em_asm_O0.wat.out +0/−4
- binaryen/test/lld/em_asm_main_thread.wat.out +0/−1
- binaryen/test/lld/em_asm_shared.wat +15/−15
- binaryen/test/lld/em_asm_shared.wat.out +25/−47
- binaryen/test/lld/em_asm_table.wat.out +0/−1
- binaryen/test/lld/em_js_O0.wat.out +0/−1
- binaryen/test/lld/gdollar_mainmodule.wat +0/−20
- binaryen/test/lld/gdollar_mainmodule.wat.out +0/−73
- binaryen/test/lld/hello_world.passive.wat.out +0/−1
- binaryen/test/lld/hello_world.wat +0/−2
- binaryen/test/lld/hello_world.wat.mem.out +0/−4
- binaryen/test/lld/hello_world.wat.out +0/−4
- binaryen/test/lld/init.wat +0/−2
- binaryen/test/lld/init.wat.out +0/−4
- binaryen/test/lld/longjmp.wat +0/−2
- binaryen/test/lld/longjmp.wat.out +0/−4
- binaryen/test/lld/main_module.wat.out +13/−41
- binaryen/test/lld/main_module_table.wat.out +5/−31
- binaryen/test/lld/main_module_table_2.wat.out +6/−31
- binaryen/test/lld/main_module_table_3.wat.out +6/−31
- binaryen/test/lld/main_module_table_4.wat.out +6/−29
- binaryen/test/lld/main_module_table_5.wat.out +7/−21
- binaryen/test/lld/recursive.wat +0/−2
- binaryen/test/lld/recursive.wat.out +0/−4
- binaryen/test/lld/recursive_safe_stack.wat.out +0/−1
- binaryen/test/lld/reserved_func_ptr.wat +0/−2
- binaryen/test/lld/reserved_func_ptr.wat.out +0/−4
- binaryen/test/lld/safe_stack_standalone-wasm.wat.out +0/−1
- binaryen/test/lld/shared.wat +13/−13
- binaryen/test/lld/shared.wat.out +21/−40
- binaryen/test/lld/shared_add_to_table.wasm.out +24/−45
- binaryen/test/lld/shared_longjmp.wat +27/−27
- binaryen/test/lld/shared_longjmp.wat.out +36/−55
- binaryen/test/lld/standalone-wasm-with-start.wat.out +0/−1
- binaryen/test/lld/standalone-wasm.wat.out +0/−1
- binaryen/test/lld/standalone-wasm2.wat.out +0/−1
- binaryen/test/lld/standalone-wasm3.wat.out +0/−1
- binaryen/test/memorygrowth-minimal.asm.js +0/−41
- binaryen/test/memorygrowth.asm.js +0/−2387
- binaryen/test/metadce/outside.wast +0/−4
- binaryen/test/metadce/outside.wast.dced +0/−4
- binaryen/test/metadce/outside.wast.dced.stdout +1/−1
- binaryen/test/min.asm.js +0/−52
- binaryen/test/min.wast.from-wast +1/−1
- binaryen/test/min.wast.fromBinary +1/−1
- binaryen/test/min.wast.fromBinary.noDebugInfo +1/−1
- binaryen/test/multivalue.wast.from-wast +2/−2
- binaryen/test/multivalue.wast.fromBinary +1/−1
- binaryen/test/multivalue.wast.fromBinary.noDebugInfo +1/−1
- binaryen/test/noffi_f32.asm.js +0/−21
- binaryen/test/noffi_i64.asm.js +0/−21
- binaryen/test/passes/O.bin.txt +2/−2
- binaryen/test/passes/O3_inlining.txt +2/−6
- binaryen/test/passes/O3_low-memory-unused_metrics.txt +26/−26
- binaryen/test/passes/O4_disable-bulk-memory.txt +20/−29
- binaryen/test/passes/O_all-features.txt +12/−0
- binaryen/test/passes/O_all-features.wast +16/−0
- binaryen/test/passes/O_all-features_ignore-implicit-traps.txt +8/−0
- binaryen/test/passes/O_all-features_ignore-implicit-traps.wast +17/−0
- binaryen/test/passes/O_fast-math.txt +13/−1
- binaryen/test/passes/O_fast-math.wast +18/−0
- binaryen/test/passes/Os_print-stack-ir_all-features.txt +0/−54
- binaryen/test/passes/Os_print-stack-ir_all-features.wast +0/−20
- binaryen/test/passes/Oz_fuzz-exec_all-features.txt +220/−0
- binaryen/test/passes/Oz_fuzz-exec_all-features.wast +182/−0
- binaryen/test/passes/asyncify_enable-multivalue.txt +208/−200
- binaryen/test/passes/asyncify_mod-asyncify-always-and-only-unwind.txt +38/−36
- binaryen/test/passes/asyncify_mod-asyncify-never-unwind.txt +39/−37
- binaryen/test/passes/asyncify_mod-asyncify-never-unwind_O.txt +2/−2
- binaryen/test/passes/asyncify_optimize-level=1.txt +38/−38
- binaryen/test/passes/asyncify_pass-arg=asyncify-imports@env.import,env.import2.txt +130/−122
- binaryen/test/passes/converge_O3_metrics.bin.txt +24/−32
- binaryen/test/passes/dae_all-features.txt +293/−0
- binaryen/test/passes/dae_all-features.wast +174/−0
- binaryen/test/passes/dae_enable-tail-call.txt +0/−281
- binaryen/test/passes/dae_enable-tail-call.wast +0/−163
- binaryen/test/passes/dce_all-features.txt +169/−74
- binaryen/test/passes/dce_all-features.wast +57/−0
- binaryen/test/passes/dce_vacuum.bin.txt +0/−98
- binaryen/test/passes/dce_vacuum.txt +0/−25
- binaryen/test/passes/dce_vacuum.wasm binary
- binaryen/test/passes/dce_vacuum.wast +0/−51
- binaryen/test/passes/dce_vacuum_remove-unused-names.bin.txt +94/−0
- binaryen/test/passes/dce_vacuum_remove-unused-names.txt +25/−0
- binaryen/test/passes/dce_vacuum_remove-unused-names.wasm binary
- binaryen/test/passes/dce_vacuum_remove-unused-names.wast +51/−0
- binaryen/test/passes/directize_all-features.txt +223/−0
- binaryen/test/passes/directize_all-features.wast +223/−0
- binaryen/test/passes/directize_enable-tail-call.txt +0/−211
- binaryen/test/passes/directize_enable-tail-call.wast +0/−209
- binaryen/test/passes/fannkuch0_dwarf.bin.txt +1/−1
- binaryen/test/passes/fannkuch3_dwarf.bin.txt +2/−2
- binaryen/test/passes/fannkuch3_manyopts_dwarf.bin.txt +199/−211
- binaryen/test/passes/fib2_dwarf.bin.txt +1/−1
- binaryen/test/passes/fib2_emptylocspan_dwarf.bin.txt +1/−1
- binaryen/test/passes/fib_nonzero-low-pc_dwarf.bin.txt +5/−5
- binaryen/test/passes/flatten.bin.txt +1/−1
- binaryen/test/passes/flatten_dfo_O3_enable-threads.txt +1/−1
- binaryen/test/passes/flatten_i64-to-i32-lowering.txt +21/−0
- binaryen/test/passes/flatten_i64-to-i32-lowering.wast +12/−1
- binaryen/test/passes/flatten_simplify-locals-nonesting_dfo_O3.txt +1/−1
- binaryen/test/passes/fpcast-emu.txt +1/−1
- binaryen/test/passes/fpcast-emu_pass-arg=max-func-params@5.txt +43/−0
- binaryen/test/passes/fpcast-emu_pass-arg=max-func-params@5.wast +14/−0
- binaryen/test/passes/func-metrics.txt +1/−1
- binaryen/test/passes/fuzz-exec_O.txt +27/−30
- binaryen/test/passes/fuzz-exec_all-features.txt +14/−2
- binaryen/test/passes/fuzz-exec_all-features.wast +8/−2
- binaryen/test/passes/fuzz_metrics_noprint.bin.txt +25/−25
- binaryen/test/passes/ignore_missing_func_dwarf.bin.txt +2/−2
- binaryen/test/passes/inlining-optimizing_optimize-level=3.txt +140/−139
- binaryen/test/passes/inlining_all-features.txt +39/−0
- binaryen/test/passes/inlining_all-features.wast +35/−0
- binaryen/test/passes/instrument-locals_all-features.txt +0/−269
- binaryen/test/passes/instrument-locals_all-features.wast +0/−54
- binaryen/test/passes/instrument-locals_all-features_disable-typed-function-references.txt +286/−0
- binaryen/test/passes/instrument-locals_all-features_disable-typed-function-references.wast +69/−0
- binaryen/test/passes/interesting-pass-mix.txt +15/−8
- binaryen/test/passes/legalize-js-interface-minimally.txt +1/−1
- binaryen/test/passes/memory-packing_all-features.txt +109/−42
- binaryen/test/passes/memory-packing_all-features.wast +68/−7
- binaryen/test/passes/memory-packing_all-features_zero-filled-memory.txt +4/−0
- binaryen/test/passes/memory-packing_all-features_zero-filled-memory.wast +6/−0
- binaryen/test/passes/memory64-lowering_enable-memory64_enable-bulk-memory.txt +168/−0
- binaryen/test/passes/memory64-lowering_enable-memory64_enable-bulk-memory.wast +31/−0
- binaryen/test/passes/multi_line_table_dwarf.bin.txt +4/−4
- binaryen/test/passes/optimize-instructions_all-features.txt +5703/−4660
- binaryen/test/passes/optimize-instructions_all-features.wast +6181/−5170
- binaryen/test/passes/optimize-instructions_fuzz-exec.txt +383/−0
- binaryen/test/passes/optimize-instructions_fuzz-exec.wast +352/−0
- binaryen/test/passes/optimize-instructions_optimize-level=2_all-features_ignore-implicit-traps.txt +10/−10
- binaryen/test/passes/pick-load-signs_all-features.txt +24/−0
- binaryen/test/passes/pick-load-signs_all-features.wast +23/−0
- binaryen/test/passes/post-emscripten.txt +6/−80
- binaryen/test/passes/post-emscripten.wast +6/−69
- binaryen/test/passes/precompute_all-features.txt +1/−1
- binaryen/test/passes/print-call-graph.txt +0/−4
- binaryen/test/passes/print-call-graph.wast +0/−4
- binaryen/test/passes/remove-non-js-ops.txt +4/−32
- binaryen/test/passes/remove-unused-brs_enable-multivalue.txt +93/−4
- binaryen/test/passes/remove-unused-brs_enable-multivalue.wast +67/−0
- binaryen/test/passes/remove-unused-brs_shrink-level=1.txt +2/−2
- binaryen/test/passes/remove-unused-module-elements_all-features.txt +2/−2
- binaryen/test/passes/remove-unused-module-elements_all-features.wast +2/−2
- binaryen/test/passes/remove-unused-names_code-folding_all-features.txt +0/−3
- binaryen/test/passes/remove-unused-names_code-folding_all-features.wast +0/−1
- binaryen/test/passes/remove-unused-names_remove-unused-brs_vacuum.txt +0/−4
- binaryen/test/passes/remove-unused-names_remove-unused-brs_vacuum.wast +0/−4
- binaryen/test/passes/remove-unused-nonfunction-module-elements_all-features.txt +2/−2
- binaryen/test/passes/remove-unused-nonfunction-module-elements_all-features.wast +2/−2
- binaryen/test/passes/reverse_dwarf_abbrevs.bin.txt +2/−2
- binaryen/test/passes/roundtrip_signed.bin.txt +26/−0
- binaryen/test/passes/roundtrip_signed.passes +1/−0
- binaryen/test/passes/roundtrip_signed.wasm binary
- binaryen/test/passes/safe-heap_disable-simd.txt +0/−1912
- binaryen/test/passes/safe-heap_disable-simd.wast +0/−4
- binaryen/test/passes/safe-heap_enable-threads_enable-simd.txt +86/−85
- binaryen/test/passes/safe-heap_enable-threads_enable-simd.wast +0/−1
- binaryen/test/passes/safe-heap_enable-threads_enable-simd64.txt +86/−85
- binaryen/test/passes/safe-heap_enable-threads_enable-simd64.wast +1/−1
- binaryen/test/passes/safe-heap_low-memory-unused_enable-threads_enable-simd.txt +86/−85
- binaryen/test/passes/safe-heap_low-memory-unused_enable-threads_enable-simd.wast +1/−1
- binaryen/test/passes/safe-heap_start-function.passes +1/−0
- binaryen/test/passes/safe-heap_start-function.txt +1932/−0
- binaryen/test/passes/safe-heap_start-function.wast +11/−0
- binaryen/test/passes/simplify-globals_all-features_fuzz-exec.txt +20/−0
- binaryen/test/passes/simplify-globals_all-features_fuzz-exec.wast +14/−0
- binaryen/test/passes/simplify-locals_all-features.txt +21/−3
- binaryen/test/passes/simplify-locals_all-features.wast +20/−0
- binaryen/test/passes/simplify-locals_all-features_disable-exception-handling.txt +2/−2
- binaryen/test/passes/spill-pointers.txt +0/−1291
- binaryen/test/passes/spill-pointers.wast +0/−338
- binaryen/test/passes/stack-check_enable-mutable-globals.txt +22/−0
- binaryen/test/passes/stack-check_enable-mutable-globals.wast +10/−0
- binaryen/test/passes/strip-debug.bin.txt +1/−1
- binaryen/test/passes/strip-producers.bin.txt +1/−1
- binaryen/test/passes/strip-target-features_roundtrip_print-features_all-features.txt +1/−0
- binaryen/test/passes/translate-to-fuzz_all-features.txt +1134/−1009
- binaryen/test/passes/translate-to-fuzz_all-features.wast +0/−101
- binaryen/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt +42/−0
- binaryen/test/passes/translate-to-fuzz_all-features_metrics_noprint.wast +101/−0
- binaryen/test/passes/vacuum_all-features.txt +0/−6
- binaryen/test/print/min.minified.txt +1/−1
- binaryen/test/print/min.txt +1/−1
- binaryen/test/reference-types.wast.fromBinary.noDebugInfo +2/−2
- binaryen/test/simd.wast +252/−6
- binaryen/test/simd.wast.from-wast +256/−8
- binaryen/test/simd.wast.fromBinary +256/−8
- binaryen/test/simd.wast.fromBinary.noDebugInfo +402/−154
- binaryen/test/spec/old_float_exprs.wast +24/−24
- binaryen/test/spec/old_import.wast +7/−7
- binaryen/test/spec/simd.wast +98/−16
- binaryen/test/threads.asm.js +0/−147
- binaryen/test/threads.wasm-only.asm.js +0/−48
- binaryen/test/try-body-multiple-insts.wasm binary
- binaryen/test/try-body-multiple-insts.wasm.fromBinary +0/−26
- binaryen/test/two_sides.asm.js +0/−30
- binaryen/test/typed-function-references.wast +44/−0
- binaryen/test/typed-function-references.wast.from-wast +69/−0
- binaryen/test/typed-function-references.wast.fromBinary +100/−0
- binaryen/test/typed-function-references.wast.fromBinary.noDebugInfo +100/−0
- binaryen/test/unit.asm.js +0/−811
- binaryen/test/unit/input/hello_world.wat +11/−0
- binaryen/test/unit/input/random_data.txt +1/−0
- binaryen/test/unit/test_errors.py +0/−40
- binaryen/test/unit/test_features.py +4/−3
- binaryen/test/unit/test_initial_fuzz.py +35/−0
- binaryen/test/unit/test_memory_packing.py +5/−4
- binaryen/test/unit/test_tail_call_type.py +2/−2
- binaryen/test/unreachable-import_wasm-only.asm.js +0/−107
- binaryen/test/unreachable-instr-type.wast +1/−1
- binaryen/test/unreachable-instr-type.wast.from-wast +1/−1
- binaryen/test/use-import-and-drop.asm.js +0/−19
- binaryen/test/wasm-only.asm.js +0/−484
- binaryen/test/wasm2js.asserts.js +14/−26
- binaryen/test/wasm2js.traps.js +14/−26
- binaryen/test/wasm2js/add_div.2asm.js +14/−26
- binaryen/test/wasm2js/add_div.2asm.js.opt +14/−26
- binaryen/test/wasm2js/atomic_fence.2asm.js +33/−49
- binaryen/test/wasm2js/atomic_fence.2asm.js.opt +14/−26
- binaryen/test/wasm2js/atomics_32.2asm.js +49/−62
- binaryen/test/wasm2js/atomics_32.2asm.js.opt +49/−62
- binaryen/test/wasm2js/atomics_32.wast +3/−3
- binaryen/test/wasm2js/base64.2asm.js +14/−26
- binaryen/test/wasm2js/base64.2asm.js.opt +14/−26
- binaryen/test/wasm2js/br.2asm.js +28/−34
- binaryen/test/wasm2js/br_table.2asm.js +34/−40
- binaryen/test/wasm2js/br_table_hoisting.2asm.js +14/−26
- binaryen/test/wasm2js/br_table_hoisting.2asm.js.opt +14/−26
- binaryen/test/wasm2js/br_table_temp.2asm.js +34/−40
- binaryen/test/wasm2js/br_table_temp.2asm.js.opt +17/−29
- binaryen/test/wasm2js/br_table_to_loop.2asm.js +14/−26
- binaryen/test/wasm2js/br_table_to_loop.2asm.js.opt +14/−26
- binaryen/test/wasm2js/break-drop.2asm.js +14/−26
- binaryen/test/wasm2js/bulk-memory.2asm.js +192/−249
- binaryen/test/wasm2js/bulk-memory.2asm.js.opt +178/−241
- binaryen/test/wasm2js/comments.2asm.js +28/−52
- binaryen/test/wasm2js/conversions-modified.2asm.js +14/−26
- binaryen/test/wasm2js/conversions-modified.2asm.js.opt +16/−28
- binaryen/test/wasm2js/deterministic.2asm.js +22/−35
- binaryen/test/wasm2js/deterministic.2asm.js.opt +22/−35
- binaryen/test/wasm2js/dot_import.2asm.js +14/−26
- binaryen/test/wasm2js/dot_import.2asm.js.opt +14/−26
- binaryen/test/wasm2js/dynamicLibrary.2asm.js +48/−55
- binaryen/test/wasm2js/dynamicLibrary.2asm.js.opt +48/−55
- binaryen/test/wasm2js/empty_export.2asm.js +14/−26
- binaryen/test/wasm2js/empty_export.2asm.js.opt +14/−26
- binaryen/test/wasm2js/empty_table.2asm.js +14/−26
- binaryen/test/wasm2js/emscripten-grow-no.2asm.js +49/−59
- binaryen/test/wasm2js/emscripten-grow-no.2asm.js.opt +49/−59
- binaryen/test/wasm2js/emscripten-grow-yes.2asm.js +60/−70
- binaryen/test/wasm2js/emscripten-grow-yes.2asm.js.opt +60/−70
- binaryen/test/wasm2js/emscripten.2asm.js +51/−62
- binaryen/test/wasm2js/emscripten.2asm.js.opt +63/−74
- binaryen/test/wasm2js/emscripten.wast +1/−1
- binaryen/test/wasm2js/endianness.2asm.js +36/−49
- binaryen/test/wasm2js/excess_fallthrough.2asm.js +29/−39
- binaryen/test/wasm2js/excess_fallthrough.2asm.js.opt +14/−26
- binaryen/test/wasm2js/f32.2asm.js +15/−32
- binaryen/test/wasm2js/f32_cmp.2asm.js +14/−26
- binaryen/test/wasm2js/f64_cmp.2asm.js +14/−26
- binaryen/test/wasm2js/fac.2asm.js +14/−26
- binaryen/test/wasm2js/float-ops.2asm.js +14/−26
- binaryen/test/wasm2js/float-ops.2asm.js.opt +16/−28
- binaryen/test/wasm2js/float_literals-modified.2asm.js +14/−26
- binaryen/test/wasm2js/float_literals-modified.2asm.js.opt +14/−26
- binaryen/test/wasm2js/float_misc.2asm.js +16/−38
- binaryen/test/wasm2js/forward.2asm.js +14/−26
- binaryen/test/wasm2js/func-ptr-offset.2asm.js +14/−26
- binaryen/test/wasm2js/func-ptr-offset.2asm.js.opt +14/−26
- binaryen/test/wasm2js/func_ptrs.2asm.js +42/−78
- binaryen/test/wasm2js/get-set-local.2asm.js +14/−26
- binaryen/test/wasm2js/get-set-local.2asm.js.opt +14/−26
- binaryen/test/wasm2js/get_local.2asm.js +14/−26
- binaryen/test/wasm2js/global_i64.2asm.js +14/−26
- binaryen/test/wasm2js/global_i64.2asm.js.opt +14/−26
- binaryen/test/wasm2js/grow-memory-tricky.2asm.js +33/−49
- binaryen/test/wasm2js/grow-memory-tricky.2asm.js.opt +33/−49
- binaryen/test/wasm2js/grow_memory.2asm.js +33/−49
- binaryen/test/wasm2js/i32.2asm.js +14/−26
- binaryen/test/wasm2js/i64-add-sub.2asm.js +14/−26
- binaryen/test/wasm2js/i64-add-sub.2asm.js.opt +15/−29
- binaryen/test/wasm2js/i64-ctz.2asm.js +14/−26
- binaryen/test/wasm2js/i64-ctz.2asm.js.opt +26/−42
- binaryen/test/wasm2js/i64-lowering.2asm.js +14/−26
- binaryen/test/wasm2js/i64-lowering.2asm.js.opt +14/−26
- binaryen/test/wasm2js/i64-rotate.2asm.js +14/−26
- binaryen/test/wasm2js/i64-rotate.2asm.js.opt +22/−34
- binaryen/test/wasm2js/i64-select.2asm.js +14/−26
- binaryen/test/wasm2js/i64-select.2asm.js.opt +14/−26
- binaryen/test/wasm2js/i64-shifts.2asm.js +14/−26
- binaryen/test/wasm2js/i64-shifts.2asm.js.opt +16/−28
- binaryen/test/wasm2js/if_unreachable.2asm.js +14/−26
- binaryen/test/wasm2js/if_unreachable.2asm.js.opt +14/−26
- binaryen/test/wasm2js/indirect-select.2asm.js +14/−26
- binaryen/test/wasm2js/indirect-select.2asm.js.opt +14/−26
- binaryen/test/wasm2js/int_exprs.2asm.js +266/−494
- binaryen/test/wasm2js/labels.2asm.js +14/−26
- binaryen/test/wasm2js/left-to-right.2asm.js +36/−49
- binaryen/test/wasm2js/minified-memory.2asm.js +32/−46
- binaryen/test/wasm2js/minified-memory.2asm.js.opt +32/−46
- binaryen/test/wasm2js/minus_minus.2asm.js +14/−26
- binaryen/test/wasm2js/minus_minus.2asm.js.opt +14/−26
- binaryen/test/wasm2js/nested-selects.2asm.js +14/−26
- binaryen/test/wasm2js/nested-selects.2asm.js.opt +14/−26
- binaryen/test/wasm2js/ordering.2asm.js +14/−26
- binaryen/test/wasm2js/ordering.2asm.js.opt +14/−26
- binaryen/test/wasm2js/reinterpret.2asm.js +14/−26
- binaryen/test/wasm2js/reinterpret.2asm.js.opt +14/−26
- binaryen/test/wasm2js/reinterpret_scratch.2asm.js +26/−39
- binaryen/test/wasm2js/reinterpret_scratch.2asm.js.opt +26/−39
- binaryen/test/wasm2js/set_local.2asm.js +14/−26
- binaryen/test/wasm2js/sign_ext.2asm.js +14/−26
- binaryen/test/wasm2js/sign_ext.2asm.js.opt +14/−26
- binaryen/test/wasm2js/stack-modified.2asm.js +14/−26
- binaryen/test/wasm2js/stack-modified.2asm.js.opt +14/−26
- binaryen/test/wasm2js/start_func.2asm.js +33/−49
- binaryen/test/wasm2js/start_func.2asm.js.opt +33/−49
- binaryen/test/wasm2js/switch.2asm.js +14/−26
- binaryen/test/wasm2js/tee_local.2asm.js +14/−26
- binaryen/test/wasm2js/traps.2asm.js +75/−127
- binaryen/test/wasm2js/unaligned.2asm.js +26/−39
- binaryen/test/wasm2js/unaligned.2asm.js.opt +26/−39
- binaryen/test/wasm2js/unary-ops.2asm.js +14/−26
- binaryen/test/wasm2js/unary-ops.2asm.js.opt +27/−43
- binaryen/test/wasm2js/unreachable-get-cycle.2asm.js +14/−26
- binaryen/test/wasm2js/unreachable-get-cycle.2asm.js.opt +14/−26
- binaryen/test/wasm2js/unreachable-insts.2asm.js +14/−26
- binaryen/test/wasm2js/unreachable-insts.2asm.js.opt +14/−26
- binaryen/test/wasm2js/unreachable-later.2asm.js +14/−26
- binaryen/test/wasm2js/unreachable-later.2asm.js.opt +14/−26
- binaryen/third_party/llvm-project/DWARFEmitter.cpp +3/−1
- binaryen/third_party/llvm-project/include/llvm/ObjectYAML/DWARFYAML.h +1/−0
- src/Binaryen/Expression.hs +1/−1
- src/Binaryen/Index.hs +13/−5
- src/Binaryen/Module.hs +19/−9
- src/Binaryen/Op.hs +0/−4
README.md view
@@ -16,7 +16,7 @@ | Haskell bindings version | Bundled Binaryen version | | ------------------------ | ------------------------ |-| 0.0.5.\* | version_98 |+| 0.0.6.\* | version_99 | Older versions of this package links against the system-wide `binaryen` library, so before building the package, please check the Binaryen version and make sure@@ -28,6 +28,7 @@ | 0.0.2.\* | version_94 | | 0.0.3.\* | version_96 | | 0.0.4.\* | version_97 |+| 0.0.5.\* | version_98 | ## How to build
binaryen.cabal view
@@ -4,10 +4,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: dd229f4cad11bdebeaef89df68685de75858bc5d1ec3d969f606f0519e5e34b8+-- hash: 15122c50a2315bce9fd4a209364778dc7a50ec2775a053a7501cd0a59659de50 name: binaryen-version: 0.0.5.0+version: 0.0.6.0 synopsis: Haskell bindings to binaryen description: Haskell bindings to [binaryen](https://github.com/WebAssembly/binaryen). Provides complete bindings to the C API, which can be useful for building WebAssembly toolchains in Haskell. category: Compiler@@ -28,10 +28,11 @@ binaryen/LICENSE binaryen/media/example.png binaryen/README.md+ binaryen/requirements-dev.txt binaryen/scripts/__init__.py+ binaryen/scripts/binaryen-lit.in binaryen/scripts/clang-format-diff.sh binaryen/scripts/clang-tidy-diff.sh- binaryen/scripts/clean_c_api_trace.py binaryen/scripts/embedwat.py binaryen/scripts/emcc-tests.sh binaryen/scripts/fuzz_opt.py@@ -40,7 +41,7 @@ binaryen/scripts/fuzz_relooper.py binaryen/scripts/fuzz_shell.js binaryen/scripts/gen-s-parser.py- binaryen/scripts/process_optimize_instructions.py+ binaryen/scripts/not.py binaryen/scripts/storage.py binaryen/scripts/strip_local_names.py binaryen/scripts/test/__init__.py@@ -57,10 +58,7 @@ binaryen/scripts/test/wasm_opt.py binaryen/scripts/validation_shell.js binaryen/scripts/wasm2js.js- binaryen/src/abi/abi.h binaryen/src/abi/js.h- binaryen/src/abi/stack.h- binaryen/src/abi/wasm-object.h binaryen/src/asm_v_wasm.h binaryen/src/asmjs/asm_v_wasm.cpp binaryen/src/asmjs/asmangle.cpp@@ -120,6 +118,8 @@ binaryen/src/ir/manipulation.h binaryen/src/ir/match.h binaryen/src/ir/memory-utils.h+ binaryen/src/ir/module-splitting.cpp+ binaryen/src/ir/module-splitting.h binaryen/src/ir/module-utils.h binaryen/src/ir/names.h binaryen/src/ir/parents.h@@ -155,7 +155,6 @@ binaryen/src/passes/DuplicateFunctionElimination.cpp binaryen/src/passes/DuplicateImportElimination.cpp binaryen/src/passes/DWARF.cpp- binaryen/src/passes/EmscriptenPIC.cpp binaryen/src/passes/ExtractFunction.cpp binaryen/src/passes/Flatten.cpp binaryen/src/passes/FuncCastEmulation.cpp@@ -170,6 +169,7 @@ binaryen/src/passes/LocalCSE.cpp binaryen/src/passes/LogExecution.cpp binaryen/src/passes/LoopInvariantCodeMotion.cpp+ binaryen/src/passes/Memory64Lowering.cpp binaryen/src/passes/MemoryPacking.cpp binaryen/src/passes/MergeBlocks.cpp binaryen/src/passes/MergeLocals.cpp@@ -199,14 +199,12 @@ binaryen/src/passes/RemoveUnusedNames.cpp binaryen/src/passes/ReorderFunctions.cpp binaryen/src/passes/ReorderLocals.cpp- binaryen/src/passes/ReplaceStackPointer.cpp binaryen/src/passes/ReReloop.cpp binaryen/src/passes/RoundTrip.cpp binaryen/src/passes/SafeHeap.cpp binaryen/src/passes/SimplifyGlobals.cpp binaryen/src/passes/SimplifyLocals.cpp binaryen/src/passes/Souperify.cpp- binaryen/src/passes/SpillPointers.cpp binaryen/src/passes/SSAify.cpp binaryen/src/passes/StackCheck.cpp binaryen/src/passes/StackIR.cpp@@ -246,6 +244,7 @@ binaryen/src/support/safe_integer.h binaryen/src/support/small_vector.h binaryen/src/support/sorted_vector.h+ binaryen/src/support/space.h binaryen/src/support/string.h binaryen/src/support/threads.cpp binaryen/src/support/threads.h@@ -270,17 +269,19 @@ binaryen/src/tools/wasm-opt.cpp binaryen/src/tools/wasm-reduce.cpp binaryen/src/tools/wasm-shell.cpp+ binaryen/src/tools/wasm-split.cpp binaryen/src/tools/wasm2c-wrapper.h binaryen/src/tools/wasm2js.cpp binaryen/src/wasm-binary.h binaryen/src/wasm-builder.h binaryen/src/wasm-debug.h+ binaryen/src/wasm-delegations-fields.h+ binaryen/src/wasm-delegations.h binaryen/src/wasm-emscripten.h binaryen/src/wasm-features.h binaryen/src/wasm-interpreter.h binaryen/src/wasm-io.h binaryen/src/wasm-module-building.h- binaryen/src/wasm-printing.h binaryen/src/wasm-s-parser.h binaryen/src/wasm-stack.h binaryen/src/wasm-traversal.h@@ -313,7 +314,6 @@ binaryen/test/atomics64.wast.from-wast binaryen/test/atomics64.wast.fromBinary binaryen/test/atomics64.wast.fromBinary.noDebugInfo- binaryen/test/bad_params.asm.js binaryen/test/bigswitch.cpp binaryen/test/bigswitch.txt binaryen/test/binaryen.js/atomics.js@@ -446,7 +446,6 @@ binaryen/test/ctor-eval/unsafe_store3.wast binaryen/test/ctor-eval/unsafe_store3.wast.ctors binaryen/test/ctor-eval/unsafe_store3.wast.out- binaryen/test/debugInfo.asm.js binaryen/test/duplicate_types.wast binaryen/test/duplicate_types.wast.from-wast binaryen/test/duplicate_types.wast.fromBinary@@ -457,13 +456,8 @@ binaryen/test/duplicated_names_collision.wasm.fromBinary binaryen/test/dylib.wasm binaryen/test/dylib.wasm.fromBinary- binaryen/test/dynamicLibrary.asm.js binaryen/test/elided-br.wasm binaryen/test/elided-br.wasm.fromBinary- binaryen/test/emcc_hello_world.asm.js- binaryen/test/emcc_O2_hello_world.asm.js- binaryen/test/empty.asm.js- binaryen/test/empty_4GB.asm.js binaryen/test/empty_imported_table.wast binaryen/test/empty_imported_table.wast.from-wast binaryen/test/empty_imported_table.wast.fromBinary@@ -480,7 +474,6 @@ binaryen/test/example/c-api-hello-world.txt binaryen/test/example/c-api-kitchen-sink.c binaryen/test/example/c-api-kitchen-sink.txt- binaryen/test/example/c-api-kitchen-sink.txt.txt binaryen/test/example/c-api-relooper-unreachable-if.cpp binaryen/test/example/c-api-relooper-unreachable-if.txt binaryen/test/example/c-api-unused-mem.cpp@@ -489,8 +482,12 @@ binaryen/test/example/cpp-threads.txt binaryen/test/example/cpp-unit.cpp binaryen/test/example/cpp-unit.txt+ binaryen/test/example/hash.cpp+ binaryen/test/example/hash.txt binaryen/test/example/match.cpp binaryen/test/example/match.txt+ binaryen/test/example/module-splitting.cpp+ binaryen/test/example/module-splitting.txt binaryen/test/example/relooper-fuzz.c binaryen/test/example/relooper-fuzz.txt binaryen/test/example/relooper-fuzz1.c@@ -513,8 +510,12 @@ binaryen/test/example/relooper-merge7.txt binaryen/test/example/small_vector.cpp binaryen/test/example/small_vector.txt+ binaryen/test/example/space.cpp+ binaryen/test/example/space.txt binaryen/test/example/stack-utils.cpp binaryen/test/example/stack-utils.txt+ binaryen/test/example/type-builder.cpp+ binaryen/test/example/type-builder.txt binaryen/test/example/typeinfo.cpp binaryen/test/example/typeinfo.txt binaryen/test/exception-handling.wast@@ -525,6 +526,10 @@ binaryen/test/export-import.wast.from-wast binaryen/test/export-import.wast.fromBinary binaryen/test/export-import.wast.fromBinary.noDebugInfo+ binaryen/test/extended-names.wast+ binaryen/test/extended-names.wast.from-wast+ binaryen/test/extended-names.wast.fromBinary+ binaryen/test/extended-names.wast.fromBinary.noDebugInfo binaryen/test/externref.wast.from-wast binaryen/test/externref.wast.fromBinary binaryen/test/externref.wast.fromBinary.noDebugInfo@@ -563,16 +568,18 @@ binaryen/test/grow_memory.wast.from-wast binaryen/test/grow_memory.wast.fromBinary binaryen/test/grow_memory.wast.fromBinary.noDebugInfo+ binaryen/test/heap-types.wast+ binaryen/test/heap-types.wast.from-wast+ binaryen/test/heap-types.wast.fromBinary+ binaryen/test/heap-types.wast.fromBinary.noDebugInfo binaryen/test/hello_libcxx.cpp binaryen/test/hello_libcxx.txt- binaryen/test/hello_world.asm.js binaryen/test/hello_world.c binaryen/test/hello_world.txt binaryen/test/hello_world.wast.from-wast binaryen/test/hello_world.wast.fromBinary binaryen/test/hello_world.wast.fromBinary.noDebugInfo binaryen/test/hello_world.wat- binaryen/test/i64-setTempRet0.asm.js binaryen/test/imported_memory.wast binaryen/test/imported_memory.wast.from-wast binaryen/test/imported_memory.wast.fromBinary@@ -581,7 +588,6 @@ binaryen/test/imported_memory_growth.wast.from-wast binaryen/test/imported_memory_growth.wast.fromBinary binaryen/test/imported_memory_growth.wast.fromBinary.noDebugInfo- binaryen/test/importedSignCast.asm.js binaryen/test/int_ops.c binaryen/test/int_ops.emcc binaryen/test/int_ops.post.js@@ -597,11 +603,27 @@ binaryen/test/linker/foo.c binaryen/test/linker/main.c binaryen/test/linker/quux.c+ binaryen/test/lit/CMakeLists.txt+ binaryen/test/lit/lit.cfg.py+ binaryen/test/lit/lit.site.cfg.py.in+ binaryen/test/lit/parse-error.wast+ binaryen/test/lit/validation/shared-memory.wast+ binaryen/test/lit/wasm-emscripten-finalize/bigint.wat+ binaryen/test/lit/wasm-emscripten-finalize/passive-pic.wat+ binaryen/test/lit/wasm-split/basic.wast+ binaryen/test/lit/wasm-split/call_exports.mjs+ binaryen/test/lit/wasm-split/export-name-already-exists.wast+ binaryen/test/lit/wasm-split/initial-table.wast+ binaryen/test/lit/wasm-split/instrument-funcs.wast+ binaryen/test/lit/wasm-split/instrument-memory-too-small.wast+ binaryen/test/lit/wasm-split/invalid-options.wast+ binaryen/test/lit/wasm-split/mismatched-hashes.wast+ binaryen/test/lit/wasm-split/name-collision.wast+ binaryen/test/lit/wasm-split/profile-guided.wast+ binaryen/test/lit/wasm-split/verbose.wast binaryen/test/lld/basic_safe_stack.s binaryen/test/lld/basic_safe_stack.wat binaryen/test/lld/basic_safe_stack.wat.out- binaryen/test/lld/bigint.wat- binaryen/test/lld/bigint.wat.out binaryen/test/lld/duplicate_imports.wat binaryen/test/lld/duplicate_imports.wat.out binaryen/test/lld/em_asm.cpp@@ -609,6 +631,9 @@ binaryen/test/lld/em_asm.wat.mem.mem binaryen/test/lld/em_asm.wat.mem.out binaryen/test/lld/em_asm.wat.out+ binaryen/test/lld/em_asm64.cpp+ binaryen/test/lld/em_asm64.wat+ binaryen/test/lld/em_asm64.wat.out binaryen/test/lld/em_asm_main_thread.wat binaryen/test/lld/em_asm_main_thread.wat.out binaryen/test/lld/em_asm_O0.c@@ -621,8 +646,6 @@ binaryen/test/lld/em_asm_table.wat.out binaryen/test/lld/em_js_O0.wat binaryen/test/lld/em_js_O0.wat.out- binaryen/test/lld/gdollar_mainmodule.wat- binaryen/test/lld/gdollar_mainmodule.wat.out binaryen/test/lld/hello_world.c binaryen/test/lld/hello_world.passive.wat binaryen/test/lld/hello_world.passive.wat.out@@ -691,8 +714,6 @@ binaryen/test/memory-shared.wast.from-wast binaryen/test/memory-shared.wast.fromBinary binaryen/test/memory-shared.wast.fromBinary.noDebugInfo- binaryen/test/memorygrowth-minimal.asm.js- binaryen/test/memorygrowth.asm.js binaryen/test/metadatas.wasm binaryen/test/metadatas.wasm.fromBinary binaryen/test/metadce/all-outside.wast@@ -739,7 +760,6 @@ binaryen/test/metadce/threaded_unrooted_cycle.wast.dced binaryen/test/metadce/threaded_unrooted_cycle.wast.dced.stdout binaryen/test/metadce/threaded_unrooted_cycle.wast.graph.txt- binaryen/test/min.asm.js binaryen/test/min.wast binaryen/test/min.wast.from-wast binaryen/test/min.wast.fromBinary@@ -758,8 +778,6 @@ binaryen/test/newsyntax.wast.from-wast binaryen/test/newsyntax.wast.fromBinary binaryen/test/newsyntax.wast.fromBinary.noDebugInfo- binaryen/test/noffi_f32.asm.js- binaryen/test/noffi_i64.asm.js binaryen/test/nonspec-bulk-memory.wast binaryen/test/nonspec-bulk-memory.wast.from-wast binaryen/test/nonspec-bulk-memory.wast.fromBinary@@ -825,14 +843,14 @@ binaryen/test/passes/converge_O3_metrics.wasm binaryen/test/passes/dae-optimizing.txt binaryen/test/passes/dae-optimizing.wast- binaryen/test/passes/dae_enable-tail-call.txt- binaryen/test/passes/dae_enable-tail-call.wast+ binaryen/test/passes/dae_all-features.txt+ binaryen/test/passes/dae_all-features.wast binaryen/test/passes/dce_all-features.txt binaryen/test/passes/dce_all-features.wast- binaryen/test/passes/dce_vacuum.bin.txt- binaryen/test/passes/dce_vacuum.txt- binaryen/test/passes/dce_vacuum.wasm- binaryen/test/passes/dce_vacuum.wast+ binaryen/test/passes/dce_vacuum_remove-unused-names.bin.txt+ binaryen/test/passes/dce_vacuum_remove-unused-names.txt+ binaryen/test/passes/dce_vacuum_remove-unused-names.wasm+ binaryen/test/passes/dce_vacuum_remove-unused-names.wast binaryen/test/passes/dealign.txt binaryen/test/passes/dealign.wast binaryen/test/passes/dealign64.passes@@ -840,8 +858,8 @@ binaryen/test/passes/dealign64.wast binaryen/test/passes/denan.txt binaryen/test/passes/denan.wast- binaryen/test/passes/directize_enable-tail-call.txt- binaryen/test/passes/directize_enable-tail-call.wast+ binaryen/test/passes/directize_all-features.txt+ binaryen/test/passes/directize_all-features.wast binaryen/test/passes/duplicate-function-elimination_all-features.txt binaryen/test/passes/duplicate-function-elimination_all-features.wast binaryen/test/passes/duplicate-function-elimination_optimize-level=1.txt@@ -908,6 +926,8 @@ binaryen/test/passes/flatten_simplify-locals-nonesting_souperify_enable-threads.wast binaryen/test/passes/fpcast-emu.txt binaryen/test/passes/fpcast-emu.wast+ binaryen/test/passes/fpcast-emu_pass-arg=max-func-params@5.txt+ binaryen/test/passes/fpcast-emu_pass-arg=max-func-params@5.wast binaryen/test/passes/func-metrics.txt binaryen/test/passes/func-metrics.wast binaryen/test/passes/fuzz-exec_all-features.txt@@ -943,8 +963,8 @@ binaryen/test/passes/inlining_enable-tail-call.wast binaryen/test/passes/inlining_optimize-level=3.txt binaryen/test/passes/inlining_optimize-level=3.wast- binaryen/test/passes/instrument-locals_all-features.txt- binaryen/test/passes/instrument-locals_all-features.wast+ binaryen/test/passes/instrument-locals_all-features_disable-typed-function-references.txt+ binaryen/test/passes/instrument-locals_all-features_disable-typed-function-references.wast binaryen/test/passes/instrument-memory.txt binaryen/test/passes/instrument-memory.wast binaryen/test/passes/instrument-memory64.passes@@ -967,6 +987,10 @@ binaryen/test/passes/log-execution.wast binaryen/test/passes/memory-packing_all-features.txt binaryen/test/passes/memory-packing_all-features.wast+ binaryen/test/passes/memory-packing_all-features_zero-filled-memory.txt+ binaryen/test/passes/memory-packing_all-features_zero-filled-memory.wast+ binaryen/test/passes/memory64-lowering_enable-memory64_enable-bulk-memory.txt+ binaryen/test/passes/memory64-lowering_enable-memory64_enable-bulk-memory.wast binaryen/test/passes/merge-blocks.txt binaryen/test/passes/merge-blocks.wast binaryen/test/passes/merge-blocks_remove-unused-brs.txt@@ -1017,6 +1041,10 @@ binaryen/test/passes/O3_print-stack-ir.wast binaryen/test/passes/O4_disable-bulk-memory.txt binaryen/test/passes/O4_disable-bulk-memory.wast+ binaryen/test/passes/O_all-features.txt+ binaryen/test/passes/O_all-features.wast+ binaryen/test/passes/O_all-features_ignore-implicit-traps.txt+ binaryen/test/passes/O_all-features_ignore-implicit-traps.wast binaryen/test/passes/O_fast-math.txt binaryen/test/passes/O_fast-math.wast binaryen/test/passes/optimize-added-constants-propagate_low-memory-unused.txt@@ -1025,14 +1053,20 @@ binaryen/test/passes/optimize-added-constants_low-memory-unused.wast binaryen/test/passes/optimize-instructions_all-features.txt binaryen/test/passes/optimize-instructions_all-features.wast+ binaryen/test/passes/optimize-instructions_fuzz-exec.txt+ binaryen/test/passes/optimize-instructions_fuzz-exec.wast binaryen/test/passes/optimize-instructions_optimize-level=2_all-features_ignore-implicit-traps.txt binaryen/test/passes/optimize-instructions_optimize-level=2_all-features_ignore-implicit-traps.wast binaryen/test/passes/Os_print-stack-ir_all-features.txt binaryen/test/passes/Os_print-stack-ir_all-features.wast binaryen/test/passes/Oz.txt binaryen/test/passes/Oz.wast+ binaryen/test/passes/Oz_fuzz-exec_all-features.txt+ binaryen/test/passes/Oz_fuzz-exec_all-features.wast binaryen/test/passes/pick-load-signs.txt binaryen/test/passes/pick-load-signs.wast+ binaryen/test/passes/pick-load-signs_all-features.txt+ binaryen/test/passes/pick-load-signs_all-features.wast binaryen/test/passes/post-assemblyscript-finalize.txt binaryen/test/passes/post-assemblyscript-finalize.wast binaryen/test/passes/post-assemblyscript.txt@@ -1102,6 +1136,9 @@ binaryen/test/passes/reverse_dwarf_abbrevs.wasm binaryen/test/passes/roundtrip.txt binaryen/test/passes/roundtrip.wast+ binaryen/test/passes/roundtrip_signed.bin.txt+ binaryen/test/passes/roundtrip_signed.passes+ binaryen/test/passes/roundtrip_signed.wasm binaryen/test/passes/rse_all-features.txt binaryen/test/passes/rse_all-features.wast binaryen/test/passes/safe-heap_disable-simd.txt@@ -1113,10 +1150,15 @@ binaryen/test/passes/safe-heap_enable-threads_enable-simd64.wast binaryen/test/passes/safe-heap_low-memory-unused_enable-threads_enable-simd.txt binaryen/test/passes/safe-heap_low-memory-unused_enable-threads_enable-simd.wast+ binaryen/test/passes/safe-heap_start-function.passes+ binaryen/test/passes/safe-heap_start-function.txt+ binaryen/test/passes/safe-heap_start-function.wast binaryen/test/passes/simplify-globals-optimizing_enable-mutable-globals.txt binaryen/test/passes/simplify-globals-optimizing_enable-mutable-globals.wast binaryen/test/passes/simplify-globals_all-features.txt binaryen/test/passes/simplify-globals_all-features.wast+ binaryen/test/passes/simplify-globals_all-features_fuzz-exec.txt+ binaryen/test/passes/simplify-globals_all-features_fuzz-exec.wast binaryen/test/passes/simplify-locals-nonesting.txt binaryen/test/passes/simplify-locals-nonesting.wast binaryen/test/passes/simplify-locals-nostructure.txt@@ -1133,8 +1175,6 @@ binaryen/test/passes/simplify-locals_all-features_disable-exception-handling.wast binaryen/test/passes/souperify.txt binaryen/test/passes/souperify.wast- binaryen/test/passes/spill-pointers.txt- binaryen/test/passes/spill-pointers.wast binaryen/test/passes/ssa-nomerge_enable-simd.txt binaryen/test/passes/ssa-nomerge_enable-simd.wast binaryen/test/passes/ssa_enable-threads.txt@@ -1159,7 +1199,8 @@ binaryen/test/passes/too_much_for_liveness.passes binaryen/test/passes/too_much_for_liveness.wasm binaryen/test/passes/translate-to-fuzz_all-features.txt- binaryen/test/passes/translate-to-fuzz_all-features.wast+ binaryen/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt+ binaryen/test/passes/translate-to-fuzz_all-features_metrics_noprint.wast binaryen/test/passes/trap-mode-clamp.txt binaryen/test/passes/trap-mode-clamp.wast binaryen/test/passes/trap-mode-js.txt@@ -1389,12 +1430,10 @@ binaryen/test/tail-call.wast.from-wast binaryen/test/tail-call.wast.fromBinary binaryen/test/tail-call.wast.fromBinary.noDebugInfo- binaryen/test/threads.asm.js- binaryen/test/threads.wasm-only.asm.js- binaryen/test/try-body-multiple-insts.wasm- binaryen/test/try-body-multiple-insts.wasm.fromBinary- binaryen/test/two_sides.asm.js- binaryen/test/unit.asm.js+ binaryen/test/typed-function-references.wast+ binaryen/test/typed-function-references.wast.from-wast+ binaryen/test/typed-function-references.wast.fromBinary+ binaryen/test/typed-function-references.wast.fromBinary.noDebugInfo binaryen/test/unit.wast.from-wast binaryen/test/unit.wast.fromBinary binaryen/test/unit.wast.fromBinary.noDebugInfo@@ -1417,7 +1456,9 @@ binaryen/test/unit/input/empty_lld.wat binaryen/test/unit/input/exception_handling_target_feature.wasm binaryen/test/unit/input/gc_target_feature.wasm+ binaryen/test/unit/input/hello_world.wat binaryen/test/unit/input/mutable_globals_target_feature.wasm+ binaryen/test/unit/input/random_data.txt binaryen/test/unit/input/reference_types_target_feature.wasm binaryen/test/unit/input/signext_target_feature.wasm binaryen/test/unit/input/simd_target_feature.wasm@@ -1428,9 +1469,9 @@ binaryen/test/unit/test_asyncify.py binaryen/test/unit/test_datacount.py binaryen/test/unit/test_dwarf.py- binaryen/test/unit/test_errors.py binaryen/test/unit/test_features.py binaryen/test/unit/test_finalize.py+ binaryen/test/unit/test_initial_fuzz.py binaryen/test/unit/test_memory_packing.py binaryen/test/unit/test_poppy_validation.py binaryen/test/unit/test_stack_ir.py@@ -1442,7 +1483,6 @@ binaryen/test/unreachable-code.wast.from-wast binaryen/test/unreachable-code.wast.fromBinary binaryen/test/unreachable-code.wast.fromBinary.noDebugInfo- binaryen/test/unreachable-import_wasm-only.asm.js binaryen/test/unreachable-instr-type.wast binaryen/test/unreachable-instr-type.wast.from-wast binaryen/test/unreachable-instr-type.wast.fromBinary@@ -1453,12 +1493,10 @@ binaryen/test/untaken-br_if.wast.from-wast binaryen/test/untaken-br_if.wast.fromBinary binaryen/test/untaken-br_if.wast.fromBinary.noDebugInfo- binaryen/test/use-import-and-drop.asm.js binaryen/test/validator/invalid_export.wast binaryen/test/validator/invalid_import.wast binaryen/test/validator/invalid_number.wast binaryen/test/validator/invalid_return.wast- binaryen/test/wasm-only.asm.js binaryen/test/wasm2asm.asserts.js binaryen/test/wasm2asm.traps.js binaryen/test/wasm2js.asserts.js@@ -1990,6 +2028,7 @@ binaryen/src/ir/ExpressionAnalyzer.cpp binaryen/src/ir/ExpressionManipulator.cpp binaryen/src/ir/LocalGraph.cpp+ binaryen/src/ir/module-splitting.cpp binaryen/src/ir/ReFinalize.cpp binaryen/src/ir/stack-utils.cpp binaryen/src/passes/AlignmentLowering.cpp@@ -2008,7 +2047,6 @@ binaryen/src/passes/DuplicateFunctionElimination.cpp binaryen/src/passes/DuplicateImportElimination.cpp binaryen/src/passes/DWARF.cpp- binaryen/src/passes/EmscriptenPIC.cpp binaryen/src/passes/ExtractFunction.cpp binaryen/src/passes/Flatten.cpp binaryen/src/passes/FuncCastEmulation.cpp@@ -2022,6 +2060,7 @@ binaryen/src/passes/LocalCSE.cpp binaryen/src/passes/LogExecution.cpp binaryen/src/passes/LoopInvariantCodeMotion.cpp+ binaryen/src/passes/Memory64Lowering.cpp binaryen/src/passes/MemoryPacking.cpp binaryen/src/passes/MergeBlocks.cpp binaryen/src/passes/MergeLocals.cpp@@ -2049,14 +2088,12 @@ binaryen/src/passes/RemoveUnusedNames.cpp binaryen/src/passes/ReorderFunctions.cpp binaryen/src/passes/ReorderLocals.cpp- binaryen/src/passes/ReplaceStackPointer.cpp binaryen/src/passes/ReReloop.cpp binaryen/src/passes/RoundTrip.cpp binaryen/src/passes/SafeHeap.cpp binaryen/src/passes/SimplifyGlobals.cpp binaryen/src/passes/SimplifyLocals.cpp binaryen/src/passes/Souperify.cpp- binaryen/src/passes/SpillPointers.cpp binaryen/src/passes/SSAify.cpp binaryen/src/passes/StackCheck.cpp binaryen/src/passes/StackIR.cpp
binaryen/CHANGELOG.md view
@@ -15,6 +15,21 @@ Current Trunk ------------- +- `RefFunc` C and JS API constructors (`BinaryenRefFunc` and `ref.func`+ respectively) now take an extra `type` parameter, similar to `RefNull`. This+ is necessary for typed function references support.+- JS API functions for atomic notify/wait instructions are renamed.+ - `module.atomic.notify` -> `module.memory.atomic.notify`+ - `module.i32.atomic.wait` -> `module.memory.atomic.wait32`+ - `module.i64.atomic.wait` -> `module.memory.atomic.wait64`+- Remove old/broken SpollPointers pass. This pass: Spills values that might be+ pointers to the C stack. This allows Boehm-style GC to see them properly.+ This can be revived if needed from git history (#3261).+- Make `NUM_PARAMS` in `FuncCastEmulation` a runtime configuration option named+ `max-func-params`. This defaults to the original value of 16.+- `BinaryenGetFunction`, `BinaryenGetGlobal` and `BinaryenGetEvent` now return+ `NULL` instead of aborting when the respective element does not yet exist.+ v98 ---
binaryen/CMakeLists.txt view
@@ -82,7 +82,7 @@ set(_install_name_dir INSTALL_NAME_DIR "@rpath") set(_install_rpath "@loader_path/../lib") elseif(UNIX)- set(_install_rpath "\$ORIGIN/../lib")+ set(_install_rpath "\$ORIGIN/../${CMAKE_INSTALL_LIBDIR}") if(${CMAKE_SYSTEM_NAME} MATCHES "(FreeBSD|DragonFly)") set_property(TARGET ${name} APPEND_STRING PROPERTY LINK_FLAGS " -Wl,-z,origin ")@@ -214,6 +214,7 @@ add_compile_flag("-Wextra") add_compile_flag("-Wno-unused-parameter") add_compile_flag("-fno-omit-frame-pointer")+ add_compile_flag("-fno-rtti") # TODO(https://github.com/WebAssembly/binaryen/pull/2314): Remove these two # flags once we resolve the issue. add_compile_flag("-Wno-implicit-int-float-conversion")@@ -221,6 +222,7 @@ add_compile_flag("-Wswitch") # we explicitly expect this in the code if(WIN32) add_compile_flag("-D_GNU_SOURCE")+ add_compile_flag("-D__STDC_FORMAT_MACROS") add_link_flag("-Wl,--stack,8388608") elseif(NOT EMSCRIPTEN) add_compile_flag("-fPIC")@@ -276,6 +278,9 @@ add_subdirectory(src/wasm) add_subdirectory(third_party) +# Configure lit tests+add_subdirectory(test/lit)+ # Object files set(binaryen_objs $<TARGET_OBJECTS:passes>@@ -331,6 +336,7 @@ binaryen_add_executable(wasm-dis src/tools/wasm-dis.cpp) binaryen_add_executable(wasm-ctor-eval src/tools/wasm-ctor-eval.cpp) binaryen_add_executable(wasm-reduce src/tools/wasm-reduce.cpp)+binaryen_add_executable(wasm-split src/tools/wasm-split.cpp) # binaryen.js@@ -388,3 +394,5 @@ set_property(TARGET binaryen_js PROPERTY CXX_STANDARD_REQUIRED ON) install(TARGETS binaryen_js DESTINATION ${CMAKE_INSTALL_BINDIR}) endif()++configure_file(scripts/binaryen-lit.in ${CMAKE_BINARY_DIR}/bin/binaryen-lit @ONLY)
binaryen/auto_update_tests.py view
@@ -29,27 +29,14 @@ def update_example_tests(): print('\n[ checking example testcases... ]\n')- for t in shared.get_tests(shared.get_test_dir('example')):- basename = os.path.basename(t)+ for src in shared.get_tests(shared.get_test_dir('example')):+ basename = os.path.basename(src) output_file = os.path.join(shared.options.binaryen_bin, 'example') libdir = os.path.join(shared.BINARYEN_INSTALL_DIR, 'lib') cmd = ['-I' + os.path.join(shared.options.binaryen_root, 'src'), '-g', '-pthread', '-o', output_file]- if t.endswith('.txt'):- # check if there is a trace in the file, if so, we should build it- out = subprocess.Popen([os.path.join(shared.options.binaryen_root, 'scripts', 'clean_c_api_trace.py'), t], stdout=subprocess.PIPE).communicate()[0]- if len(out) == 0:- print(' (no trace in ', basename, ')')- continue- print(' (will check trace in ', basename, ')')- src = 'trace.cpp'- with open(src, 'wb') as o:- o.write(out)- expected = t + '.txt'- else:- src = t- expected = os.path.splitext(t)[0] + '.txt' if not src.endswith(('.c', '.cpp')): continue+ expected = os.path.splitext(src)[0] + '.txt' # windows + gcc will need some work if shared.skip_if_on_windows('gcc'): return
binaryen/check.py view
@@ -29,11 +29,6 @@ from scripts.test import wasm_opt -if shared.options.interpreter:- print('[ using wasm interpreter at "%s" ]' % shared.options.interpreter)- assert os.path.exists(shared.options.interpreter), 'interpreter not found'-- def get_changelog_version(): with open(os.path.join(shared.options.binaryen_root, 'CHANGELOG.md')) as f: lines = f.readlines()@@ -47,7 +42,7 @@ def run_help_tests(): print('[ checking --help is useful... ]\n') - not_executable_suffix = ['.txt', '.js', '.ilk', '.pdb', '.dll', '.wasm', '.manifest']+ not_executable_suffix = ['.txt', '.js', '.ilk', '.pdb', '.dll', '.wasm', '.manifest', 'binaryen-lit'] bin_files = [os.path.join(shared.options.binaryen_bin, f) for f in os.listdir(shared.options.binaryen_bin)] executables = [f for f in bin_files if os.path.isfile(f) and not any(f.endswith(s) for s in not_executable_suffix)] executables = sorted(executables)@@ -291,37 +286,24 @@ for t in sorted(os.listdir(shared.get_test_dir('example'))): output_file = 'example'- cmd = ['-I' + os.path.join(shared.options.binaryen_root, 'src'), '-g', '-pthread', '-o', output_file]- if t.endswith('.txt'):- # check if there is a trace in the file, if so, we should build it- out = subprocess.check_output([os.path.join(shared.options.binaryen_root, 'scripts', 'clean_c_api_trace.py'), os.path.join(shared.get_test_dir('example'), t)])- if len(out) == 0:- print(' (no trace in ', t, ')')- continue- print(' (will check trace in ', t, ')')- src = 'trace.cpp'- with open(src, 'wb') as o:- o.write(out)- expected = os.path.join(shared.get_test_dir('example'), t + '.txt')- else:- src = os.path.join(shared.get_test_dir('example'), t)- expected = os.path.join(shared.get_test_dir('example'), '.'.join(t.split('.')[:-1]) + '.txt')- if src.endswith(('.c', '.cpp')):- # build the C file separately- libpath = os.path.join(os.path.dirname(shared.options.binaryen_bin), 'lib')- extra = [shared.NATIVECC, src, '-c', '-o', 'example.o',- '-I' + os.path.join(shared.options.binaryen_root, 'src'), '-g', '-L' + libpath, '-pthread']- if src.endswith('.cpp'):- extra += ['-std=c++' + str(shared.cxx_standard)]- if os.environ.get('COMPILER_FLAGS'):- for f in os.environ.get('COMPILER_FLAGS').split(' '):- extra.append(f)- print('build: ', ' '.join(extra))- subprocess.check_call(extra)- # Link against the binaryen C library DSO, using an executable-relative rpath- cmd = ['example.o', '-L' + libpath, '-lbinaryen'] + cmd + ['-Wl,-rpath,' + libpath]- else:+ cmd = ['-I' + os.path.join(shared.options.binaryen_root, 't'), '-g', '-pthread', '-o', output_file]+ if not t.endswith(('.c', '.cpp')): continue+ src = os.path.join(shared.get_test_dir('example'), t)+ expected = os.path.join(shared.get_test_dir('example'), '.'.join(t.split('.')[:-1]) + '.txt')+ # build the C file separately+ libpath = shared.options.binaryen_lib+ extra = [shared.NATIVECC, src, '-c', '-o', 'example.o',+ '-I' + os.path.join(shared.options.binaryen_root, 'src'), '-g', '-L' + libpath, '-pthread']+ if src.endswith('.cpp'):+ extra += ['-std=c++' + str(shared.cxx_standard)]+ if os.environ.get('COMPILER_FLAGS'):+ for f in os.environ.get('COMPILER_FLAGS').split(' '):+ extra.append(f)+ print('build: ', ' '.join(extra))+ subprocess.check_call(extra)+ # Link against the binaryen C library DSO, using an executable-relative rpath+ cmd = ['example.o', '-L' + libpath, '-lbinaryen'] + cmd + ['-Wl,-rpath,' + libpath] print(' ', t, src, expected) if os.environ.get('COMPILER_FLAGS'): for f in os.environ.get('COMPILER_FLAGS').split(' '):@@ -346,6 +328,18 @@ raise Exception("unittest failed") +def run_lit():+ lit_script = os.path.join(shared.options.binaryen_bin, 'binaryen-lit')+ lit_tests = os.path.join(shared.options.binaryen_root, 'test', 'lit')+ # lit expects to be run as its own executable+ cmd = [sys.executable, lit_script, lit_tests, '-vv']+ result = subprocess.run(cmd)+ if result.returncode != 0:+ shared.num_failures += 1+ if shared.options.abort_on_first_failure and shared.num_failures:+ raise Exception("lit test failed")++ TEST_SUITES = OrderedDict([ ('help-messages', run_help_tests), ('wasm-opt', wasm_opt.test_wasm_opt),@@ -363,6 +357,7 @@ ('unit', run_unittest), ('binaryenjs', binaryenjs.test_binaryen_js), ('binaryenjs_wasm', binaryenjs.test_binaryen_wasm),+ ('lit', run_lit), ])
+ binaryen/requirements-dev.txt view
@@ -0,0 +1,8 @@+# These requirements are only needed for developers who want to run the test+# suite or flake8, not for end users.++# Install with `pip3 install -r requirements-dev.txt`++flake8==3.7.8+filecheck==0.0.17+lit==0.11.0.post1
+ binaryen/scripts/binaryen-lit.in view
@@ -0,0 +1,33 @@+#!/usr/bin/env python3+#+# Copyright 2020 WebAssembly Community Group participants+#+# Licensed under the Apache License, Version 2.0 (the "License");+# you may not use this file except in compliance with the License.+# You may obtain a copy of the License at+#+# http://www.apache.org/licenses/LICENSE-2.0+#+# Unless required by applicable law or agreed to in writing, software+# distributed under the License is distributed on an "AS IS" BASIS,+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+# See the License for the specific language governing permissions and+# limitations under the License.++import os+from lit.main import main++# A simple wrapper around `lit` test running. Loosely based on+# llvm's llvm-lit script++builtin_parameters = {+ 'config_map': {+ os.path.normcase(os.path.normpath('@CMAKE_SOURCE_DIR@/test/lit/lit.cfg.py')):+ os.path.normcase(os.path.normpath('@CMAKE_BINARY_DIR@/test/lit/lit.site.cfg.py'))+ }+}++print(builtin_parameters)++if __name__ == '__main__':+ main(builtin_parameters)
− binaryen/scripts/clean_c_api_trace.py
@@ -1,37 +0,0 @@-#!/usr/bin/env python3-#-# Copyright 2016 WebAssembly Community Group participants-#-# Licensed under the Apache License, Version 2.0 (the "License");-# you may not use this file except in compliance with the License.-# You may obtain a copy of the License at-#-# http://www.apache.org/licenses/LICENSE-2.0-#-# Unless required by applicable law or agreed to in writing, software-# distributed under the License is distributed on an "AS IS" BASIS,-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.-# See the License for the specific language governing permissions and-# limitations under the License.--"""Cleans up output from the C api, makes a runnable C file-"""--import sys--trace = open(sys.argv[1]).read()--start = trace.find('// beginning a Binaryen API trace')-end = trace.rfind('// ending a Binaryen API trace')-if start >= 0:- trace = trace[start:end]-- while 1:- start = trace.find('\n(')- if start < 0:- break- end = trace.find('\n)', start + 1)- assert end > 0- trace = trace[:start] + trace[end + 2:]-- print(trace)
binaryen/scripts/fuzz_opt.py view
@@ -28,7 +28,9 @@ import traceback from test import shared+from test import support + assert sys.version_info.major == 3, 'requires Python 3!' # parameters@@ -68,9 +70,10 @@ return random.randint(INPUT_SIZE_MIN, 2 * INPUT_SIZE_MEAN - INPUT_SIZE_MIN) -def run(cmd):- print(' '.join(cmd))- return subprocess.check_output(cmd, text=True)+def run(cmd, stderr=None, silent=False):+ if not silent:+ print(' '.join(cmd))+ return subprocess.check_output(cmd, stderr=stderr, text=True) def run_unchecked(cmd):@@ -102,12 +105,11 @@ def randomize_feature_opts(): global FEATURE_OPTS FEATURE_OPTS = CONSTANT_FEATURE_OPTS[:]- # half the time apply all the possible opts. this lets all test runners work at max- # capacity at least half the time, as otherwise if they need almost all the opts, the- # chance of getting them is exponentially small.- if random.random() < 0.5:+ # 1/3 the time apply all the possible opts, 1/3 none of them, to maximize+ # coverage both ways, and 1/3 pick each one randomly+ if random.random() < 0.33333: FEATURE_OPTS += POSSIBLE_FEATURE_OPTS- else:+ elif random.random() < 0.5: for possible in POSSIBLE_FEATURE_OPTS: if random.random() < 0.5: FEATURE_OPTS.append(possible)@@ -116,15 +118,19 @@ print('randomized feature opts:', ' '.join(FEATURE_OPTS)) -FUZZ_OPTS = None-NANS = None-OOB = None-LEGALIZE = None-ORIGINAL_V8_OPTS = shared.V8_OPTS[:]+def randomize_fuzz_settings():+ # a list of the optimizations to run on the wasm+ global FUZZ_OPTS + # a boolean whether NaN values are allowed, or we de-NaN them+ global NANS -def randomize_fuzz_settings():- global FUZZ_OPTS, NANS, OOB, LEGALIZE+ # a boolean whether out of bounds operations are allowed, or we bounds-enforce them+ global OOB++ # a boolean whether we legalize the wasm for JS+ global LEGALIZE+ FUZZ_OPTS = [] if random.random() < 0.5: NANS = True@@ -141,25 +147,93 @@ FUZZ_OPTS += ['--legalize-js-interface'] else: LEGALIZE = False- extra_v8_opts = []- # 50% of the time test v8 normally, that is, the same way it runs in- # production (which as of 07/15/2020 means baseline, then tier up to- # optimizing, but that may change in the future).+ print('randomized settings (NaNs, OOB, legalize):', NANS, OOB, LEGALIZE)+++IMPORTANT_INITIAL_CONTENTS = [+ os.path.join('passes', 'optimize-instructions_all-features.wast'),+ os.path.join('passes', 'optimize-instructions_fuzz-exec.wast'),+]+IMPORTANT_INITIAL_CONTENTS = [os.path.join(shared.get_test_dir('.'), t) for t in IMPORTANT_INITIAL_CONTENTS]+++def pick_initial_contents():+ # if we use an initial wasm file's contents as the basis for the+ # fuzzing, then that filename, or None if we start entirely from scratch+ global INITIAL_CONTENTS++ INITIAL_CONTENTS = None+ # half the time don't use any initial contents if random.random() < 0.5:- # test either the optimizing compiler or the baseline compiler, with- # equal probability. it's useful to do this because the normal tier-up- # mode does not check them both equally (typically baseline does not get- # enough testing, as we quickly leave it), and also because the tiering- # up is nondeterministic (when optimized code becomes ready, we switch- # to it)- if random.random() < 0.5:- extra_v8_opts += ['--no-liftoff']- else:- extra_v8_opts += ['--liftoff', '--no-wasm-tier-up']- shared.V8_OPTS = ORIGINAL_V8_OPTS + extra_v8_opts- print('randomized settings (NaNs, OOB, legalize, extra V8_OPTS):', NANS, OOB, LEGALIZE, extra_v8_opts)+ return+ # some of the time use initial contents that are known to be especially+ # important+ if random.random() < 0.5:+ test_name = random.choice(IMPORTANT_INITIAL_CONTENTS)+ else:+ test_name = random.choice(all_tests)+ print('initial contents:', test_name)+ assert os.path.exists(test_name)+ # tests that check validation errors are not helpful for us+ if '.fail.' in test_name:+ print('initial contents is just a .fail test')+ return+ if os.path.basename(test_name) in [+ # contains too many segments to run in a wasm VM+ 'limit-segments_disable-bulk-memory.wast',+ # https://github.com/WebAssembly/binaryen/issues/3203+ 'simd.wast',+ # corner cases of escaping of names is not interesting+ 'names.wast',+ # huge amount of locals that make it extremely slow+ 'too_much_for_liveness.wasm'+ ]:+ print('initial contents is disallowed')+ return + if test_name.endswith('.wast'):+ # this can contain multiple modules, pick one+ split_parts = support.split_wast(test_name)+ if len(split_parts) > 1:+ index = random.randint(0, len(split_parts) - 1)+ chosen = split_parts[index]+ module, asserts = chosen+ if not module:+ # there is no module in this choice (just asserts), ignore it+ print('initial contents has no module')+ return+ test_name = 'initial.wat'+ with open(test_name, 'w') as f:+ f.write(module)+ print(' picked submodule %d from multi-module wast' % index) + global FEATURE_OPTS+ FEATURE_OPTS += [+ # has not been enabled in the fuzzer yet+ '--disable-exception-handling',+ # has not been fuzzed in general yet+ '--disable-memory64',+ # has not been fuzzed in general yet+ '--disable-gc',+ # DWARF is incompatible with multivalue atm; it's more important to+ # fuzz multivalue since we aren't actually fuzzing DWARF here+ '--strip-dwarf',+ ]++ # the given wasm may not work with the chosen feature opts. for example, if+ # we pick atomics.wast but want to run with --disable-atomics, then we'd+ # error. test the wasm.+ try:+ run([in_bin('wasm-opt'), test_name] + FEATURE_OPTS,+ stderr=subprocess.PIPE,+ silent=True)+ except Exception:+ print('(initial contents not valid for features, ignoring)')+ return++ INITIAL_CONTENTS = test_name++ # Test outputs we want to ignore are marked this way. IGNORE = '[binaryen-fuzzer-ignore]' @@ -302,14 +376,27 @@ del os.environ['BINARYEN_MAX_INTERPRETER_DEPTH'] -def run_d8_js(js, args=[]):- return run_vm([shared.V8] + shared.V8_OPTS + [js] + (['--'] if args else []) + args)+V8_LIFTOFF_ARGS = ['--liftoff', '--no-wasm-tier-up'] -def run_d8_wasm(wasm):- return run_d8_js(in_binaryen('scripts', 'fuzz_shell.js'), [wasm])+# default to running with liftoff enabled, because we need to pick either+# liftoff or turbofan for consistency (otherwise running the same command twice+# may have different results due to NaN nondeterminism), and liftoff is faster+# for small things+def run_d8_js(js, args=[], liftoff=True):+ cmd = [shared.V8] + shared.V8_OPTS+ if liftoff:+ cmd += V8_LIFTOFF_ARGS+ cmd += [js]+ if args:+ cmd += ['--'] + args+ return run_vm(cmd) +def run_d8_wasm(wasm, liftoff=True):+ return run_d8_js(in_binaryen('scripts', 'fuzz_shell.js'), [wasm], liftoff=liftoff)++ class TestCaseHandler: # how frequent this handler will be run. 1 means always run it, 0.5 means half the # time@@ -335,19 +422,6 @@ return self.num_runs -# Run VMs and compare results--class VM:- def __init__(self, name, run, can_compare_to_self, can_compare_to_others):- self.name = name- self.run = run- self.can_compare_to_self = can_compare_to_self- self.can_compare_to_others = can_compare_to_others-- def can_run(self, wasm):- return True-- # Fuzz the interpreter with --fuzz-exec. class FuzzExec(TestCaseHandler): frequency = 1@@ -362,23 +436,57 @@ def __init__(self): super(CompareVMs, self).__init__() - def byn_run(wasm):- return run_bynterp(wasm, ['--fuzz-exec-before'])+ class BinaryenInterpreter:+ name = 'binaryen interpreter' - def v8_run(wasm):- run([in_bin('wasm-opt'), wasm, '--emit-js-wrapper=' + wasm + '.js'] + FEATURE_OPTS)- return run_vm([shared.V8, wasm + '.js'] + shared.V8_OPTS + ['--', wasm])+ def run(self, wasm):+ return run_bynterp(wasm, ['--fuzz-exec-before']) - def yes():- return True+ def can_run(self, wasm):+ return True - def if_legal_and_no_nans():- return LEGALIZE and not NANS+ def can_compare_to_self(self):+ return True - def if_no_nans():- return not NANS+ def can_compare_to_others(self):+ return True - class Wasm2C(VM):+ class D8:+ name = 'd8'++ def run(self, wasm, extra_d8_flags=[]):+ run([in_bin('wasm-opt'), wasm, '--emit-js-wrapper=' + wasm + '.js'] + FEATURE_OPTS)+ return run_vm([shared.V8, wasm + '.js'] + shared.V8_OPTS + extra_d8_flags + ['--', wasm])++ def can_run(self, wasm):+ # INITIAL_CONTENT is disallowed because some initial spec testcases+ # have names that require mangling, see+ # https://github.com/WebAssembly/binaryen/pull/3216+ return not INITIAL_CONTENTS++ def can_compare_to_self(self):+ # With nans, VM differences can confuse us, so only very simple VMs+ # can compare to themselves after opts in that case.+ return not NANS++ def can_compare_to_others(self):+ # If not legalized, the JS will fail immediately, so no point to+ # compare to others.+ return LEGALIZE and not NANS++ class D8Liftoff(D8):+ name = 'd8_liftoff'++ def run(self, wasm):+ return super(D8Liftoff, self).run(wasm, extra_d8_flags=V8_LIFTOFF_ARGS)++ class D8TurboFan(D8):+ name = 'd8_turbofan'++ def run(self, wasm):+ return super(D8TurboFan, self).run(wasm, extra_d8_flags=['--no-liftoff'])++ class Wasm2C: name = 'wasm2c' def __init__(self):@@ -433,7 +541,11 @@ def run(self, wasm): run([in_bin('wasm-opt'), wasm, '--emit-wasm2c-wrapper=main.c'] + FEATURE_OPTS) run(['wasm2c', wasm, '-o', 'wasm.c'])- compile_cmd = ['emcc', 'main.c', 'wasm.c', os.path.join(self.wasm2c_dir, 'wasm-rt-impl.c'), '-I' + self.wasm2c_dir, '-lm']+ compile_cmd = ['emcc', 'main.c', 'wasm.c',+ os.path.join(self.wasm2c_dir, 'wasm-rt-impl.c'),+ '-I' + self.wasm2c_dir,+ '-lm',+ '-s', 'ALLOW_MEMORY_GROWTH'] # disable the signal handler: emcc looks like unix, but wasm has # no signals compile_cmd += ['-DWASM_RT_MEMCHECK_SIGNAL_HANDLER=0']@@ -464,14 +576,8 @@ # NaNs can differ from wasm VMs return not NANS - self.vms = [- VM('binaryen interpreter', byn_run, can_compare_to_self=yes, can_compare_to_others=yes),- # with nans, VM differences can confuse us, so only very simple VMs can compare to themselves after opts in that case.- # if not legalized, the JS will fail immediately, so no point to compare to others- VM('d8', v8_run, can_compare_to_self=if_no_nans, can_compare_to_others=if_legal_and_no_nans),- Wasm2C(),- Wasm2C2Wasm(),- ]+ self.vms = [BinaryenInterpreter(), D8(), D8Liftoff(), D8TurboFan(),+ Wasm2C(), Wasm2C2Wasm()] def handle_pair(self, input, before_wasm, after_wasm, opts): before = self.run_vms(before_wasm)@@ -483,6 +589,7 @@ vm_results = {} for vm in self.vms: if vm.can_run(wasm):+ print(f'[CompareVMs] running {vm.name}') vm_results[vm] = fix_output(vm.run(wasm)) # compare between the vms on this specific input@@ -635,6 +742,13 @@ return run_vm([shared.NODEJS, js_file, 'a.wasm']) def can_run_on_feature_opts(self, feature_opts):+ # TODO: properly handle memory growth. right now the wasm2js handler+ # uses --emscripten which assumes the Memory is created before, and+ # wasm2js.js just starts with a size of 1 and no limit. We should switch+ # to non-emscripten mode or adding memory information, or check+ # specifically for growth here+ if INITIAL_CONTENTS:+ return False return all([x in feature_opts for x in ['--disable-exception-handling', '--disable-simd', '--disable-threads', '--disable-bulk-memory', '--disable-nontrapping-float-to-int', '--disable-tail-call', '--disable-sign-ext', '--disable-reference-types', '--disable-multivalue', '--disable-gc']]) @@ -692,6 +806,15 @@ return all([x in feature_opts for x in ['--disable-exception-handling', '--disable-simd', '--disable-tail-call', '--disable-reference-types', '--disable-multivalue', '--disable-gc']]) +# Check that the text format round-trips without error.+class RoundtripText(TestCaseHandler):+ frequency = 0.05++ def handle(self, wasm):+ run([in_bin('wasm-dis'), wasm, '-o', 'a.wast'])+ run([in_bin('wasm-opt'), 'a.wast'] + FEATURE_OPTS)++ # The global list of all test case handlers testcase_handlers = [ FuzzExec(),@@ -699,14 +822,29 @@ CheckDeterminism(), Wasm2JS(), Asyncify(),+ RoundtripText() ] +test_suffixes = ['*.wasm', '*.wast', '*.wat']+core_tests = shared.get_tests(shared.get_test_dir('.'), test_suffixes)+passes_tests = shared.get_tests(shared.get_test_dir('passes'), test_suffixes)+spec_tests = shared.get_tests(shared.get_test_dir('spec'), test_suffixes)+wasm2js_tests = shared.get_tests(shared.get_test_dir('wasm2js'), test_suffixes)+lld_tests = shared.get_tests(shared.get_test_dir('lld'), test_suffixes)+unit_tests = shared.get_tests(shared.get_test_dir(os.path.join('unit', 'input')), test_suffixes)+all_tests = core_tests + passes_tests + spec_tests + wasm2js_tests + lld_tests + unit_tests++ # Do one test, given an input file for -ttf and some optimizations to run-def test_one(random_input, opts, given_wasm):+def test_one(random_input, given_wasm): randomize_pass_debug() randomize_feature_opts() randomize_fuzz_settings()+ pick_initial_contents()++ opts = randomize_opt_flags()+ print('randomized opts:', ' '.join(opts)) print() if given_wasm:@@ -719,6 +857,8 @@ # emit the target features section so that reduction can work later, # without needing to specify the features generate_command = [in_bin('wasm-opt'), random_input, '-ttf', '-o', 'a.wasm', '--emit-target-features'] + FUZZ_OPTS + FEATURE_OPTS+ if INITIAL_CONTENTS:+ generate_command += ['--initial-fuzz=' + INITIAL_CONTENTS] if PRINT_WATS: printed = run(generate_command + ['--print']) with open('a.printed.wast', 'w') as f:@@ -840,10 +980,16 @@ # core opts while 1: choice = random.choice(opt_choices)- if '--flatten' in choice:+ if '--flatten' in choice or '-O4' in choice: if has_flatten: print('avoiding multiple --flatten in a single command, due to exponential overhead') continue+ if '--disable-exception-handling' not in FEATURE_OPTS:+ print('avoiding --flatten due to exception catching which does not support it yet')+ continue+ if INITIAL_CONTENTS and os.path.getsize(INITIAL_CONTENTS) > 2000:+ print('avoiding --flatten due using a large amount of initial contents, which may blow up')+ continue else: has_flatten = True flag_groups.append(choice)@@ -925,10 +1071,13 @@ with open(raw_input_data, 'wb') as f: f.write(bytes([random.randint(0, 255) for x in range(input_size)])) assert os.path.getsize(raw_input_data) == input_size- opts = randomize_opt_flags()- print('randomized opts:', ' '.join(opts))+ # remove the generated wasm file, so that we can tell if the fuzzer+ # fails to create one+ if os.path.exists('a.wasm'):+ os.remove('a.wasm')+ # run an iteration of the fuzzer try:- total_wasm_size += test_one(raw_input_data, opts, given_wasm)+ total_wasm_size += test_one(raw_input_data, given_wasm) except KeyboardInterrupt: print('(stopping by user request)') break@@ -953,6 +1102,26 @@ # is likely to be called within wasm-reduce script itself, so # original.wasm and reduce.sh should not be overwritten. if not given_wasm:+ # We can't do this if a.wasm doesn't exist, which can be the+ # case if we failed to even generate the wasm.+ if not os.path.exists('a.wasm'):+ print('''\+================================================================================+You found a bug in the fuzzer itself! It failed to generate a valid wasm file+from the random input. Please report it with++ seed: %(seed)d++and the exact version of Binaryen you found it on, plus the exact Python+version (hopefully deterministic random numbers will be identical).++You can run that testcase again with "fuzz_opt.py %(seed)d"++(We can't automatically reduce this testcase since we can only run the reducer+on valid wasm files.)+================================================================================+ ''' % {'seed': seed})+ break # show some useful info about filing a bug and reducing the # testcase (to make reduction simple, save "original.wasm" on # the side, so that we can autoreduce using the name "a.wasm"
binaryen/scripts/gen-s-parser.py view
@@ -201,9 +201,9 @@ ("i64.extend16_s", "makeUnary(s, UnaryOp::ExtendS16Int64)"), ("i64.extend32_s", "makeUnary(s, UnaryOp::ExtendS32Int64)"), # atomic instructions- ("atomic.notify", "makeAtomicNotify(s)"),- ("i32.atomic.wait", "makeAtomicWait(s, Type::i32)"),- ("i64.atomic.wait", "makeAtomicWait(s, Type::i64)"),+ ("memory.atomic.notify", "makeAtomicNotify(s)"),+ ("memory.atomic.wait32", "makeAtomicWait(s, Type::i32)"),+ ("memory.atomic.wait64", "makeAtomicWait(s, Type::i64)"), ("atomic.fence", "makeAtomicFence(s)"), ("i32.atomic.load8_u", "makeLoad(s, Type::i32, /*isAtomic=*/true)"), ("i32.atomic.load16_u", "makeLoad(s, Type::i32, /*isAtomic=*/true)"),@@ -332,6 +332,7 @@ ("i32x4.le_u", "makeBinary(s, BinaryOp::LeUVecI32x4)"), ("i32x4.ge_s", "makeBinary(s, BinaryOp::GeSVecI32x4)"), ("i32x4.ge_u", "makeBinary(s, BinaryOp::GeUVecI32x4)"),+ ("i64x2.eq", "makeBinary(s, BinaryOp::EqVecI64x2)"), ("f32x4.eq", "makeBinary(s, BinaryOp::EqVecF32x4)"), ("f32x4.ne", "makeBinary(s, BinaryOp::NeVecF32x4)"), ("f32x4.lt", "makeBinary(s, BinaryOp::LtVecF32x4)"),@@ -350,6 +351,19 @@ ("v128.xor", "makeBinary(s, BinaryOp::XorVec128)"), ("v128.andnot", "makeBinary(s, BinaryOp::AndNotVec128)"), ("v128.bitselect", "makeSIMDTernary(s, SIMDTernaryOp::Bitselect)"),+ ("v8x16.signselect", "makeSIMDTernary(s, SIMDTernaryOp::SignSelectVec8x16)"),+ ("v16x8.signselect", "makeSIMDTernary(s, SIMDTernaryOp::SignSelectVec16x8)"),+ ("v32x4.signselect", "makeSIMDTernary(s, SIMDTernaryOp::SignSelectVec32x4)"),+ ("v64x2.signselect", "makeSIMDTernary(s, SIMDTernaryOp::SignSelectVec64x2)"),+ ("v128.load8_lane", "makeSIMDLoadStoreLane(s, LoadLaneVec8x16)"),+ ("v128.load16_lane", "makeSIMDLoadStoreLane(s, LoadLaneVec16x8)"),+ ("v128.load32_lane", "makeSIMDLoadStoreLane(s, LoadLaneVec32x4)"),+ ("v128.load64_lane", "makeSIMDLoadStoreLane(s, LoadLaneVec64x2)"),+ ("v128.store8_lane", "makeSIMDLoadStoreLane(s, StoreLaneVec8x16)"),+ ("v128.store16_lane", "makeSIMDLoadStoreLane(s, StoreLaneVec16x8)"),+ ("v128.store32_lane", "makeSIMDLoadStoreLane(s, StoreLaneVec32x4)"),+ ("v128.store64_lane", "makeSIMDLoadStoreLane(s, StoreLaneVec64x2)"),+ ("i8x16.popcnt", "makeUnary(s, UnaryOp::PopcntVecI8x16)"), ("i8x16.abs", "makeUnary(s, UnaryOp::AbsVecI8x16)"), ("i8x16.neg", "makeUnary(s, UnaryOp::NegVecI8x16)"), ("i8x16.any_true", "makeUnary(s, UnaryOp::AnyTrueVecI8x16)"),@@ -390,6 +404,11 @@ ("i16x8.max_s", "makeBinary(s, BinaryOp::MaxSVecI16x8)"), ("i16x8.max_u", "makeBinary(s, BinaryOp::MaxUVecI16x8)"), ("i16x8.avgr_u", "makeBinary(s, BinaryOp::AvgrUVecI16x8)"),+ ("i16x8.q15mulr_sat_s", "makeBinary(s, BinaryOp::Q15MulrSatSVecI16x8)"),+ ("i16x8.extmul_low_i8x16_s", "makeBinary(s, BinaryOp::ExtMulLowSVecI16x8)"),+ ("i16x8.extmul_high_i8x16_s", "makeBinary(s, BinaryOp::ExtMulHighSVecI16x8)"),+ ("i16x8.extmul_low_i8x16_u", "makeBinary(s, BinaryOp::ExtMulLowUVecI16x8)"),+ ("i16x8.extmul_high_i8x16_u", "makeBinary(s, BinaryOp::ExtMulHighUVecI16x8)"), ("i32x4.abs", "makeUnary(s, UnaryOp::AbsVecI32x4)"), ("i32x4.neg", "makeUnary(s, UnaryOp::NegVecI32x4)"), ("i32x4.any_true", "makeUnary(s, UnaryOp::AnyTrueVecI32x4)"),@@ -406,15 +425,22 @@ ("i32x4.max_s", "makeBinary(s, BinaryOp::MaxSVecI32x4)"), ("i32x4.max_u", "makeBinary(s, BinaryOp::MaxUVecI32x4)"), ("i32x4.dot_i16x8_s", "makeBinary(s, BinaryOp::DotSVecI16x8ToVecI32x4)"),+ ("i32x4.extmul_low_i16x8_s", "makeBinary(s, BinaryOp::ExtMulLowSVecI32x4)"),+ ("i32x4.extmul_high_i16x8_s", "makeBinary(s, BinaryOp::ExtMulHighSVecI32x4)"),+ ("i32x4.extmul_low_i16x8_u", "makeBinary(s, BinaryOp::ExtMulLowUVecI32x4)"),+ ("i32x4.extmul_high_i16x8_u", "makeBinary(s, BinaryOp::ExtMulHighUVecI32x4)"), ("i64x2.neg", "makeUnary(s, UnaryOp::NegVecI64x2)"),- ("i64x2.any_true", "makeUnary(s, UnaryOp::AnyTrueVecI64x2)"),- ("i64x2.all_true", "makeUnary(s, UnaryOp::AllTrueVecI64x2)"),+ ("i64x2.bitmask", "makeUnary(s, UnaryOp::BitmaskVecI64x2)"), ("i64x2.shl", "makeSIMDShift(s, SIMDShiftOp::ShlVecI64x2)"), ("i64x2.shr_s", "makeSIMDShift(s, SIMDShiftOp::ShrSVecI64x2)"), ("i64x2.shr_u", "makeSIMDShift(s, SIMDShiftOp::ShrUVecI64x2)"), ("i64x2.add", "makeBinary(s, BinaryOp::AddVecI64x2)"), ("i64x2.sub", "makeBinary(s, BinaryOp::SubVecI64x2)"), ("i64x2.mul", "makeBinary(s, BinaryOp::MulVecI64x2)"),+ ("i64x2.extmul_low_i32x4_s", "makeBinary(s, BinaryOp::ExtMulLowSVecI64x2)"),+ ("i64x2.extmul_high_i32x4_s", "makeBinary(s, BinaryOp::ExtMulHighSVecI64x2)"),+ ("i64x2.extmul_low_i32x4_u", "makeBinary(s, BinaryOp::ExtMulLowUVecI64x2)"),+ ("i64x2.extmul_high_i32x4_u", "makeBinary(s, BinaryOp::ExtMulHighUVecI64x2)"), ("f32x4.abs", "makeUnary(s, UnaryOp::AbsVecF32x4)"), ("f32x4.neg", "makeUnary(s, UnaryOp::NegVecF32x4)"), ("f32x4.sqrt", "makeUnary(s, UnaryOp::SqrtVecF32x4)"),@@ -481,7 +507,18 @@ ("i32x4.widen_high_i16x8_s", "makeUnary(s, UnaryOp::WidenHighSVecI16x8ToVecI32x4)"), ("i32x4.widen_low_i16x8_u", "makeUnary(s, UnaryOp::WidenLowUVecI16x8ToVecI32x4)"), ("i32x4.widen_high_i16x8_u", "makeUnary(s, UnaryOp::WidenHighUVecI16x8ToVecI32x4)"),+ ("i64x2.widen_low_i32x4_s", "makeUnary(s, UnaryOp::WidenLowSVecI32x4ToVecI64x2)"),+ ("i64x2.widen_high_i32x4_s", "makeUnary(s, UnaryOp::WidenHighSVecI32x4ToVecI64x2)"),+ ("i64x2.widen_low_i32x4_u", "makeUnary(s, UnaryOp::WidenLowUVecI32x4ToVecI64x2)"),+ ("i64x2.widen_high_i32x4_u", "makeUnary(s, UnaryOp::WidenHighUVecI32x4ToVecI64x2)"), ("v8x16.swizzle", "makeBinary(s, BinaryOp::SwizzleVec8x16)"),+ ("i16x8.extadd_pairwise_i8x16_s", "makeUnary(s, UnaryOp::ExtAddPairwiseSVecI8x16ToI16x8)"),+ ("i16x8.extadd_pairwise_i8x16_u", "makeUnary(s, UnaryOp::ExtAddPairwiseUVecI8x16ToI16x8)"),+ ("i32x4.extadd_pairwise_i16x8_s", "makeUnary(s, UnaryOp::ExtAddPairwiseSVecI16x8ToI32x4)"),+ ("i32x4.extadd_pairwise_i16x8_u", "makeUnary(s, UnaryOp::ExtAddPairwiseUVecI16x8ToI32x4)"),+ # prefetch instructions+ ("prefetch.t", "makePrefetch(s, PrefetchOp::PrefetchTemporal)"),+ ("prefetch.nt", "makePrefetch(s, PrefetchOp::PrefetchNontemporal)"), # reference types instructions # TODO Add table instructions ("ref.null", "makeRefNull(s)"),@@ -496,6 +533,9 @@ ("tuple.make", "makeTupleMake(s)"), ("tuple.extract", "makeTupleExtract(s)"), ("pop", "makePop(s)"),+ # Typed function references instructions+ ("call_ref", "makeCallRef(s, /*isReturn=*/false)"),+ ("return_call_ref", "makeCallRef(s, /*isReturn=*/true)"), # GC ("ref.eq", "makeRefEq(s)"), ("i31.new", "makeI31New(s)"),
+ binaryen/scripts/not.py view
@@ -0,0 +1,30 @@+#!/usr/bin/env python3++# Copyright 2020 WebAssembly Community Group participants+#+# Licensed under the Apache License, Version 2.0 (the "License");+# you may not use this file except in compliance with the License.+# You may obtain a copy of the License at+#+# http://www.apache.org/licenses/LICENSE-2.0+#+# Unless required by applicable law or agreed to in writing, software+# distributed under the License is distributed on an "AS IS" BASIS,+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+# See the License for the specific language governing permissions and+# limitations under the License.++import sys+import subprocess+++# Emulate the `not` tool from LLVM's test infrastructure for use with lit and+# FileCheck. It succeeds if the given subcommand fails and vice versa.+def main():+ cmd = sys.argv[1:]+ result = subprocess.run(cmd)+ sys.exit(0 if result.returncode != 0 else 1)+++if __name__ == '__main__':+ main()
− binaryen/scripts/process_optimize_instructions.py
@@ -1,16 +0,0 @@-#!/usr/bin/python--import os--root = os.path.dirname(os.path.dirname(__file__))--infile = os.path.join(root, 'src', 'passes', 'OptimizeInstructions.wast')-outfile = os.path.join(root, 'src', 'passes',- 'OptimizeInstructions.wast.processed')--out = open(outfile, 'w')--for line in open(infile):- out.write('"' + line.strip().replace('"', '\\"') + '\\n"\n')--out.close()
binaryen/scripts/test/generate_lld_tests.py view
@@ -48,10 +48,10 @@ wasm_path = os.path.join(lld_path, wasm_file) wat_path = os.path.join(lld_path, wat_file) is_shared = 'shared' in src_file+ is_64 = '64' in src_file compile_cmd = [ os.path.join(llvm_bin, 'clang'), src_path, '-o', obj_path,- '--target=wasm32-emscripten', '-mllvm', '-enable-emscripten-sjlj', '-c', '-nostdinc',@@ -67,7 +67,6 @@ obj_path, '-o', wasm_path, '--allow-undefined', '--export', '__wasm_call_ctors',- '--export', '__data_end', '--global-base=568', ] # We had a regression where this test only worked if debug names@@ -81,6 +80,12 @@ link_cmd.append('--experimental-pic') else: link_cmd.append('--entry=main')++ if is_64:+ compile_cmd.append('--target=wasm64-emscripten')+ link_cmd.append('-mwasm64')+ else:+ compile_cmd.append('--target=wasm32-emscripten') try: support.run_command(compile_cmd)
binaryen/scripts/test/lld.py view
@@ -26,8 +26,6 @@ ret += ['--side-module'] if 'standalone-wasm' in filename: ret += ['--standalone-wasm']- if 'bigint' in filename:- ret += ['--bigint'] return ret @@ -51,7 +49,10 @@ else: continue - cmd = shared.WASM_EMSCRIPTEN_FINALIZE + [input_path, '-S'] + args+ cmd = shared.WASM_EMSCRIPTEN_FINALIZE + args+ if '64' in input_path:+ cmd += ['--enable-memory64', '--bigint']+ cmd += [input_path, '-S'] cmd += args_for_finalize(os.path.basename(input_path)) actual = support.run_command(cmd) @@ -96,9 +97,12 @@ out_path = input_path + ext if ext != '.out' and not os.path.exists(out_path): continue- cmd = shared.WASM_EMSCRIPTEN_FINALIZE + [input_path, '-S'] + \- ext_args+ cmd = shared.WASM_EMSCRIPTEN_FINALIZE + ext_args+ if '64' in input_path:+ cmd += ['--enable-memory64', '--bigint']+ cmd += [input_path, '-S'] cmd += args_for_finalize(os.path.basename(input_path)) actual = support.run_command(cmd)+ with open(out_path, 'w') as o: o.write(actual)
@@ -49,15 +49,17 @@ help=('If set, the whole test suite will run to completion independent of' ' earlier errors.')) parser.add_argument(- '--interpreter', dest='interpreter', default='',- help='Specifies the wasm interpreter executable to run tests on.')- parser.add_argument( '--binaryen-bin', dest='binaryen_bin', default='',- help=('Specifies a path to where the built Binaryen executables reside at.'- ' Default: bin/ of current directory (i.e. assume an in-tree build).'+ help=('Specifies the path to the Binaryen executables in the CMake build'+ ' directory. Default: bin/ of current directory (i.e. assume an'+ ' in-tree build).' ' If not specified, the environment variable BINARYEN_ROOT= can also' ' be used to adjust this.')) parser.add_argument(+ '--binaryen-lib', dest='binaryen_lib', default='',+ help=('Specifies a path to where the built Binaryen shared library resides at.'+ ' Default: ./lib relative to bin specified above.'))+ parser.add_argument( '--binaryen-root', dest='binaryen_root', default='', help=('Specifies a path to the root of the Binaryen repository tree.' ' Default: the directory where this file check.py resides.'))@@ -123,10 +125,17 @@ options.binaryen_bin = os.path.normpath(os.path.abspath(options.binaryen_bin)) +if not options.binaryen_lib:+ options.binaryen_lib = os.path.join(os.path.dirname(options.binaryen_bin), 'lib')++options.binaryen_lib = os.path.normpath(os.path.abspath(options.binaryen_lib))++options.binaryen_build = os.path.dirname(options.binaryen_bin)+ # ensure BINARYEN_ROOT is set up os.environ['BINARYEN_ROOT'] = os.path.dirname(options.binaryen_bin) -wasm_dis_filenames = ['wasm-dis', 'wasm-dis.exe']+wasm_dis_filenames = ['wasm-dis', 'wasm-dis.exe', 'wasm-dis.js'] if not any(os.path.isfile(os.path.join(options.binaryen_bin, f)) for f in wasm_dis_filenames): warn('Binaryen not found (or has not been successfully built to bin/ ?')@@ -182,7 +191,7 @@ which('gcc') or which('clang')) NATIVEXX = (os.environ.get('CXX') or which('mingw32-g++') or which('g++') or which('clang++'))-NODEJS = os.getenv('NODE', which('nodejs') or which('node'))+NODEJS = os.getenv('NODE', which('node') or which('nodejs')) MOZJS = which('mozjs') or which('spidermonkey') V8 = which('v8') or which('d8') @@ -261,18 +270,7 @@ if NODEJS is None: warn('no node found (did not check proper js form)') -try:- if MOZJS is not None:- subprocess.check_call([MOZJS, '--version'],- stdout=subprocess.PIPE,- stderr=subprocess.PIPE)-except (OSError, subprocess.CalledProcessError):- MOZJS = None-if MOZJS is None:- warn('no mozjs found (did not check native wasm support nor asm.js'- ' validation)') - # utilities # removes a file if it exists, using any and all ways of doing so@@ -380,10 +378,6 @@ if options.test_name_filter: tests = fnmatch.filter(tests, options.test_name_filter) return sorted(tests)---if not options.interpreter:- warn('no interpreter provided (did not test spec interpreter validation)') if not options.spec_tests:
binaryen/scripts/test/wasm_opt.py view
@@ -57,7 +57,8 @@ passes_file = os.path.join(shared.get_test_dir('passes'), passname + '.passes') if os.path.exists(passes_file): passname = open(passes_file).read().strip()- opts = [('--' + p if not p.startswith('O') and p != 'g' else '-' + p) for p in passname.split('_')]+ passes = [p for p in passname.split('_') if p != 'noprint']+ opts = [('--' + p if not p.startswith('O') and p != 'g' else '-' + p) for p in passes] actual = '' for module, asserts in support.split_wast(t): assert len(asserts) == 0@@ -171,7 +172,8 @@ passes_file = os.path.join(shared.get_test_dir('passes'), passname + '.passes') if os.path.exists(passes_file): passname = open(passes_file).read().strip()- opts = [('--' + p if not p.startswith('O') and p != 'g' else '-' + p) for p in passname.split('_')]+ passes = [p for p in passname.split('_') if p != 'noprint']+ opts = [('--' + p if not p.startswith('O') and p != 'g' else '-' + p) for p in passes] actual = '' for module, asserts in support.split_wast(t): assert len(asserts) == 0
− binaryen/src/abi/abi.h
@@ -1,33 +0,0 @@-/*- * Copyright 2017 WebAssembly Community Group participants- *- * Licensed under the Apache License, Version 2.0 (the "License");- * you may not use this file except in compliance with the License.- * You may obtain a copy of the License at- *- * http://www.apache.org/licenses/LICENSE-2.0- *- * Unless required by applicable law or agreed to in writing, software- * distributed under the License is distributed on an "AS IS" BASIS,- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.- * See the License for the specific language governing permissions and- * limitations under the License.- */--#ifndef wasm_abi_abi_h-#define wasm_abi_abi_h--#include "wasm.h"--namespace wasm {--namespace ABI {--// The pointer type. Will need to update this for wasm64-const static Type PointerType = Type::i32;--} // namespace ABI--} // namespace wasm--#endif // wasm_abi_abi_h
− binaryen/src/abi/stack.h
@@ -1,144 +0,0 @@-/*- * Copyright 2017 WebAssembly Community Group participants- *- * Licensed under the Apache License, Version 2.0 (the "License");- * you may not use this file except in compliance with the License.- * You may obtain a copy of the License at- *- * http://www.apache.org/licenses/LICENSE-2.0- *- * Unless required by applicable law or agreed to in writing, software- * distributed under the License is distributed on an "AS IS" BASIS,- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.- * See the License for the specific language governing permissions and- * limitations under the License.- */--#ifndef wasm_abi_stack_h-#define wasm_abi_stack_h--#include "abi.h"-#include "asmjs/shared-constants.h"-#include "ir/find_all.h"-#include "ir/global-utils.h"-#include "shared-constants.h"-#include "wasm-builder.h"-#include "wasm.h"--namespace wasm {--namespace ABI {--enum { StackAlign = 16 };--inline Index stackAlign(Index size) {- return (size + StackAlign - 1) & -StackAlign;-}--// Allocate some space on the stack, and assign it to a local.-// The local will have the same constant value in all the function, so you can-// just local.get it anywhere there.-//-// FIXME: This function assumes that the stack grows upward, per the convention-// used by fastcomp. The stack grows downward when using the WASM backend.--inline void-getStackSpace(Index local, Function* func, Index size, Module& wasm) {- // Attempt to locate the stack pointer by recognizing code idioms- // used by Emscripten. First, look for a global initialized to an- // imported variable named "STACKTOP" in environment "env".- auto* stackPointer =- GlobalUtils::getGlobalInitializedToImport(wasm, ENV, "STACKTOP");- // Starting with Emscripten 1.38.24, the stack pointer variable is- // initialized with a literal constant, eliminating the import that- // we used to locate the stack pointer by name. We must match a more- // complicated idiom, expecting to see the module structured as follows:- //- //(module- // ...- // (export "stackSave" (func $stackSave))- // ...- // (func $stackSave (; 410 ;) (; has Stack IR ;) (result i32)- // (global.get $STACKTOP)- // )- // ...- //)- if (!stackPointer) {- auto* stackSaveFunctionExport = wasm.getExportOrNull("stackSave");- if (stackSaveFunctionExport &&- stackSaveFunctionExport->kind == ExternalKind::Function) {- auto* stackSaveFunction =- wasm.getFunction(stackSaveFunctionExport->value);- assert(!stackSaveFunction->imported());- auto* globalGet = stackSaveFunction->body->dynCast<GlobalGet>();- if (globalGet) {- stackPointer = wasm.getGlobal(globalGet->name);- }- }- }- if (!stackPointer) {- Fatal() << "getStackSpace: failed to find the stack pointer";- }- // align the size- size = stackAlign(size);- // TODO: find existing stack usage, and add on top of that - carefully- Builder builder(wasm);- auto* block = builder.makeBlock();- block->list.push_back(builder.makeLocalSet(- local, builder.makeGlobalGet(stackPointer->name, PointerType)));- // TODO: add stack max check- Expression* added;- if (PointerType == Type::i32) {- added = builder.makeBinary(AddInt32,- builder.makeLocalGet(local, PointerType),- builder.makeConst(int32_t(size)));- } else {- WASM_UNREACHABLE("unhandled PointerType");- }- block->list.push_back(builder.makeGlobalSet(stackPointer->name, added));- auto makeStackRestore = [&]() {- return builder.makeGlobalSet(stackPointer->name,- builder.makeLocalGet(local, PointerType));- };- // add stack restores to the returns- FindAllPointers<Return> finder(func->body);- for (auto** ptr : finder.list) {- auto* ret = (*ptr)->cast<Return>();- if (ret->value && ret->value->type != Type::unreachable) {- // handle the returned value- auto* block = builder.makeBlock();- auto temp = builder.addVar(func, ret->value->type);- block->list.push_back(builder.makeLocalSet(temp, ret->value));- block->list.push_back(makeStackRestore());- block->list.push_back(- builder.makeReturn(builder.makeLocalGet(temp, ret->value->type)));- block->finalize();- *ptr = block;- } else {- // restore, then return- *ptr = builder.makeSequence(makeStackRestore(), ret);- }- }- // add stack restores to the body- if (func->body->type == Type::none) {- block->list.push_back(func->body);- block->list.push_back(makeStackRestore());- } else if (func->body->type == Type::unreachable) {- block->list.push_back(func->body);- // no need to restore the old stack value, we're gone anyhow- } else {- // save the return value- auto temp = builder.addVar(func, func->sig.results);- block->list.push_back(builder.makeLocalSet(temp, func->body));- block->list.push_back(makeStackRestore());- block->list.push_back(builder.makeLocalGet(temp, func->sig.results));- }- block->finalize();- func->body = block;-}--} // namespace ABI--} // namespace wasm--#endif // wasm_abi_stack_h
− binaryen/src/abi/wasm-object.h
@@ -1,40 +0,0 @@-/*- * Copyright 2018 WebAssembly Community Group participants- *- * Licensed under the Apache License, Version 2.0 (the "License");- * you may not use this file except in compliance with the License.- * You may obtain a copy of the License at- *- * http://www.apache.org/licenses/LICENSE-2.0- *- * Unless required by applicable law or agreed to in writing, software- * distributed under the License is distributed on an "AS IS" BASIS,- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.- * See the License for the specific language governing permissions and- * limitations under the License.- */--//-// Contains definitions used for wasm object files.-// See: https://github.com/WebAssembly/tool-conventions/blob/master/Linking.md-//--#ifndef wasm_abi_wasm_object_h-#define wasm_abi_wasm_object_h--namespace wasm {--namespace ABI {-enum LinkType : unsigned {- WASM_STACK_POINTER = 0x1,- WASM_SYMBOL_INFO = 0x2,- WASM_DATA_SIZE = 0x3,- WASM_DATA_ALIGNMENT = 0x4,- WASM_SEGMENT_INFO = 0x5,- WASM_INIT_FUNCS = 0x6,-};-} // namespace ABI--} // namespace wasm--#endif // wasm_abi_wasm_object_h
binaryen/src/asm_v_wasm.h view
@@ -23,26 +23,12 @@ namespace wasm { -Type asmToWasmType(AsmType asmType);- AsmType wasmToAsmType(Type type); char getSig(Type type); std::string getSig(Function* func); std::string getSig(Type results, Type params); -template<typename T,- typename std::enable_if<std::is_base_of<Expression, T>::value>::type* =- nullptr>-std::string getSig(T* call) {- std::string ret;- ret += getSig(call->type);- for (auto operand : call->operands) {- ret += getSig(operand->type);- }- return ret;-}- template<typename ListType> std::string getSig(Type result, const ListType& operands) { std::string ret;@@ -62,9 +48,6 @@ } return ret; }--// converts an f32 to an f64 if necessary-Expression* ensureDouble(Expression* expr, MixedArena& allocator); } // namespace wasm
binaryen/src/asmjs/asm_v_wasm.cpp view
@@ -19,28 +19,6 @@ namespace wasm { -Type asmToWasmType(AsmType asmType) {- switch (asmType) {- case ASM_INT:- return Type::i32;- case ASM_DOUBLE:- return Type::f64;- case ASM_FLOAT:- return Type::f32;- case ASM_INT64:- return Type::i64;- case ASM_NONE:- return Type::none;- case ASM_FLOAT32X4:- case ASM_FLOAT64X2:- case ASM_INT8X16:- case ASM_INT16X8:- case ASM_INT32X4:- return Type::v128;- }- WASM_UNREACHABLE("invalid type");-}- AsmType wasmToAsmType(Type type) { TODO_SINGLE_COMPOUND(type); switch (type.getBasic()) {@@ -102,10 +80,6 @@ WASM_UNREACHABLE("invalid type"); } -std::string getSig(Function* func) {- return getSig(func->sig.results, func->sig.params);-}- std::string getSig(Type results, Type params) { assert(!results.isTuple()); std::string sig;@@ -114,18 +88,6 @@ sig += getSig(param); } return sig;-}--Expression* ensureDouble(Expression* expr, MixedArena& allocator) {- if (expr->type == Type::f32) {- auto conv = allocator.alloc<Unary>();- conv->op = PromoteFloat32;- conv->value = expr;- conv->type = Type::f64;- return conv;- }- assert(expr->type == Type::f64);- return expr; } } // namespace wasm
@@ -18,11 +18,6 @@ namespace wasm { -cashew::IString GLOBAL("global");-cashew::IString NAN_("NaN");-cashew::IString INFINITY_("Infinity");-cashew::IString NAN__("nan");-cashew::IString INFINITY__("infinity"); cashew::IString TOPMOST("topmost"); cashew::IString INT8ARRAY("Int8Array"); cashew::IString INT16ARRAY("Int16Array");@@ -34,7 +29,6 @@ cashew::IString FLOAT64ARRAY("Float64Array"); cashew::IString ARRAY_BUFFER("ArrayBuffer"); cashew::IString ASM_MODULE("asmModule");-cashew::IString IMPOSSIBLE_CONTINUE("impossible-continue"); cashew::IString MATH("Math"); cashew::IString IMUL("imul"); cashew::IString CLZ32("clz32");@@ -55,10 +49,10 @@ cashew::IString I32U_DIV("i32u-div"); cashew::IString I32S_REM("i32s-rem"); cashew::IString I32U_REM("i32u-rem");-cashew::IString GLOBAL_MATH("global.Math"); cashew::IString ABS("abs"); cashew::IString FLOOR("floor"); cashew::IString CEIL("ceil");+cashew::IString TRUNC("trunc"); cashew::IString SQRT("sqrt"); cashew::IString POW("pow"); cashew::IString I32_TEMP("asm2wasm_i32_temp");@@ -93,8 +87,6 @@ cashew::IString INT64_TO_32_HIGH_BITS("i64toi32_i32$HIGH_BITS"); cashew::IString WASM_NEAREST_F32("__wasm_nearest_f32"); cashew::IString WASM_NEAREST_F64("__wasm_nearest_f64");-cashew::IString WASM_TRUNC_F32("__wasm_trunc_f32");-cashew::IString WASM_TRUNC_F64("__wasm_trunc_f64"); cashew::IString WASM_I64_MUL("__wasm_i64_mul"); cashew::IString WASM_I64_SDIV("__wasm_i64_sdiv"); cashew::IString WASM_I64_UDIV("__wasm_i64_udiv");
@@ -21,11 +21,6 @@ namespace wasm { -extern cashew::IString GLOBAL;-extern cashew::IString NAN_;-extern cashew::IString INFINITY_;-extern cashew::IString NAN__;-extern cashew::IString INFINITY__; extern cashew::IString TOPMOST; extern cashew::IString INT8ARRAY; extern cashew::IString INT16ARRAY;@@ -37,7 +32,6 @@ extern cashew::IString FLOAT64ARRAY; extern cashew::IString ARRAY_BUFFER; extern cashew::IString ASM_MODULE;-extern cashew::IString IMPOSSIBLE_CONTINUE; extern cashew::IString MATH; extern cashew::IString IMUL; extern cashew::IString CLZ32;@@ -58,10 +52,10 @@ extern cashew::IString I32U_DIV; extern cashew::IString I32S_REM; extern cashew::IString I32U_REM;-extern cashew::IString GLOBAL_MATH; extern cashew::IString ABS; extern cashew::IString FLOOR; extern cashew::IString CEIL;+extern cashew::IString TRUNC; extern cashew::IString SQRT; extern cashew::IString POW; extern cashew::IString I32_TEMP;@@ -73,8 +67,8 @@ extern cashew::IString INSTRUMENT; extern cashew::IString MATH_IMUL; extern cashew::IString MATH_ABS;-extern cashew::IString MATH_CEIL; extern cashew::IString MATH_CLZ32;+extern cashew::IString MATH_CEIL; extern cashew::IString MATH_FLOOR; extern cashew::IString MATH_TRUNC; extern cashew::IString MATH_SQRT;@@ -96,8 +90,6 @@ extern cashew::IString INT64_TO_32_HIGH_BITS; extern cashew::IString WASM_NEAREST_F32; extern cashew::IString WASM_NEAREST_F64;-extern cashew::IString WASM_TRUNC_F32;-extern cashew::IString WASM_TRUNC_F64; extern cashew::IString WASM_I64_MUL; extern cashew::IString WASM_I64_SDIV; extern cashew::IString WASM_I64_UDIV;
binaryen/src/binaryen-c.cpp view
@@ -29,7 +29,6 @@ #include "wasm-binary.h" #include "wasm-builder.h" #include "wasm-interpreter.h"-#include "wasm-printing.h" #include "wasm-s-parser.h" #include "wasm-validator.h" #include "wasm.h"@@ -178,152 +177,14 @@ BinaryenExpressionId BinaryenInvalidId(void) { return Expression::Id::InvalidId; }-BinaryenExpressionId BinaryenBlockId(void) { return Expression::Id::BlockId; }-BinaryenExpressionId BinaryenIfId(void) { return Expression::Id::IfId; }-BinaryenExpressionId BinaryenLoopId(void) { return Expression::Id::LoopId; }-BinaryenExpressionId BinaryenBreakId(void) { return Expression::Id::BreakId; }-BinaryenExpressionId BinaryenSwitchId(void) { return Expression::Id::SwitchId; }-BinaryenExpressionId BinaryenCallId(void) { return Expression::Id::CallId; }-BinaryenExpressionId BinaryenCallIndirectId(void) {- return Expression::Id::CallIndirectId;-}-BinaryenExpressionId BinaryenLocalGetId(void) {- return Expression::Id::LocalGetId;-}-BinaryenExpressionId BinaryenLocalSetId(void) {- return Expression::Id::LocalSetId;-}-BinaryenExpressionId BinaryenGlobalGetId(void) {- return Expression::Id::GlobalGetId;-}-BinaryenExpressionId BinaryenGlobalSetId(void) {- return Expression::Id::GlobalSetId;-}-BinaryenExpressionId BinaryenLoadId(void) { return Expression::Id::LoadId; }-BinaryenExpressionId BinaryenStoreId(void) { return Expression::Id::StoreId; }-BinaryenExpressionId BinaryenConstId(void) { return Expression::Id::ConstId; }-BinaryenExpressionId BinaryenUnaryId(void) { return Expression::Id::UnaryId; }-BinaryenExpressionId BinaryenBinaryId(void) { return Expression::Id::BinaryId; }-BinaryenExpressionId BinaryenSelectId(void) { return Expression::Id::SelectId; }-BinaryenExpressionId BinaryenDropId(void) { return Expression::Id::DropId; }-BinaryenExpressionId BinaryenReturnId(void) { return Expression::Id::ReturnId; }-BinaryenExpressionId BinaryenMemorySizeId(void) {- return Expression::Id::MemorySizeId;-}-BinaryenExpressionId BinaryenMemoryGrowId(void) {- return Expression::Id::MemoryGrowId;-}-BinaryenExpressionId BinaryenNopId(void) { return Expression::Id::NopId; }-BinaryenExpressionId BinaryenUnreachableId(void) {- return Expression::Id::UnreachableId;-}-BinaryenExpressionId BinaryenAtomicCmpxchgId(void) {- return Expression::Id::AtomicCmpxchgId;-}-BinaryenExpressionId BinaryenAtomicRMWId(void) {- return Expression::Id::AtomicRMWId;-}-BinaryenExpressionId BinaryenAtomicWaitId(void) {- return Expression::Id::AtomicWaitId;-}-BinaryenExpressionId BinaryenAtomicNotifyId(void) {- return Expression::Id::AtomicNotifyId;-}-BinaryenExpressionId BinaryenAtomicFenceId(void) {- return Expression::Id::AtomicFenceId;-}-BinaryenExpressionId BinaryenSIMDExtractId(void) {- return Expression::Id::SIMDExtractId;-}-BinaryenExpressionId BinaryenSIMDReplaceId(void) {- return Expression::Id::SIMDReplaceId;-}-BinaryenExpressionId BinaryenSIMDShuffleId(void) {- return Expression::Id::SIMDShuffleId;-}-BinaryenExpressionId BinaryenSIMDTernaryId(void) {- return Expression::Id::SIMDTernaryId;-}-BinaryenExpressionId BinaryenSIMDShiftId(void) {- return Expression::Id::SIMDShiftId;-}-BinaryenExpressionId BinaryenSIMDLoadId(void) {- return Expression::Id::SIMDLoadId;-}-BinaryenExpressionId BinaryenMemoryInitId(void) {- return Expression::Id::MemoryInitId;-}-BinaryenExpressionId BinaryenDataDropId(void) {- return Expression::Id::DataDropId;-}-BinaryenExpressionId BinaryenMemoryCopyId(void) {- return Expression::Id::MemoryCopyId;-}-BinaryenExpressionId BinaryenMemoryFillId(void) {- return Expression::Id::MemoryFillId;-}-BinaryenExpressionId BinaryenRefNullId(void) {- return Expression::Id::RefNullId;-}-BinaryenExpressionId BinaryenRefIsNullId(void) {- return Expression::Id::RefIsNullId;-}-BinaryenExpressionId BinaryenRefFuncId(void) {- return Expression::Id::RefFuncId;-}-BinaryenExpressionId BinaryenRefEqId(void) { return Expression::Id::RefEqId; }-BinaryenExpressionId BinaryenTryId(void) { return Expression::Id::TryId; }-BinaryenExpressionId BinaryenThrowId(void) { return Expression::Id::ThrowId; }-BinaryenExpressionId BinaryenRethrowId(void) {- return Expression::Id::RethrowId;-}-BinaryenExpressionId BinaryenBrOnExnId(void) {- return Expression::Id::BrOnExnId;-}-BinaryenExpressionId BinaryenTupleMakeId(void) {- return Expression::Id::TupleMakeId;-}-BinaryenExpressionId BinaryenTupleExtractId(void) {- return Expression::Id::TupleExtractId;-}-BinaryenExpressionId BinaryenPopId(void) { return Expression::Id::PopId; }-BinaryenExpressionId BinaryenI31NewId(void) { return Expression::Id::I31NewId; }-BinaryenExpressionId BinaryenI31GetId(void) { return Expression::Id::I31GetId; }-BinaryenExpressionId BinaryenRefTestId(void) {- return Expression::Id::RefTestId;-}-BinaryenExpressionId BinaryenRefCastId(void) {- return Expression::Id::RefCastId;-}-BinaryenExpressionId BinaryenBrOnCastId(void) {- return Expression::Id::BrOnCastId;-}-BinaryenExpressionId BinaryenRttCanonId(void) {- return Expression::Id::RttCanonId;-}-BinaryenExpressionId BinaryenRttSubId(void) { return Expression::Id::RttSubId; }-BinaryenExpressionId BinaryenStructNewId(void) {- return Expression::Id::StructNewId;-}-BinaryenExpressionId BinaryenStructGetId(void) {- return Expression::Id::StructGetId;-}-BinaryenExpressionId BinaryenStructSetId(void) {- return Expression::Id::StructSetId;-}-BinaryenExpressionId BinaryenArrayNewId(void) {- return Expression::Id::ArrayNewId;-}-BinaryenExpressionId BinaryenArrayGetId(void) {- return Expression::Id::ArrayGetId;-}-BinaryenExpressionId BinaryenArraySetId(void) {- return Expression::Id::ArraySetId;-}-BinaryenExpressionId BinaryenArrayLenId(void) {- return Expression::Id::ArrayLenId;-} +#define DELEGATE(CLASS_TO_VISIT) \+ BinaryenExpressionId Binaryen##CLASS_TO_VISIT##Id(void) { \+ return Expression::Id::CLASS_TO_VISIT##Id; \+ }++#include "wasm-delegations.h"+ // External kinds BinaryenExternalKind BinaryenExternalFunction(void) {@@ -562,12 +423,12 @@ BinaryenOp BinaryenLeFloat64(void) { return LeFloat64; } BinaryenOp BinaryenGtFloat64(void) { return GtFloat64; } BinaryenOp BinaryenGeFloat64(void) { return GeFloat64; }-BinaryenOp BinaryenAtomicRMWAdd(void) { return AtomicRMWOp::Add; }-BinaryenOp BinaryenAtomicRMWSub(void) { return AtomicRMWOp::Sub; }-BinaryenOp BinaryenAtomicRMWAnd(void) { return AtomicRMWOp::And; }-BinaryenOp BinaryenAtomicRMWOr(void) { return AtomicRMWOp::Or; }-BinaryenOp BinaryenAtomicRMWXor(void) { return AtomicRMWOp::Xor; }-BinaryenOp BinaryenAtomicRMWXchg(void) { return AtomicRMWOp::Xchg; }+BinaryenOp BinaryenAtomicRMWAdd(void) { return RMWAdd; }+BinaryenOp BinaryenAtomicRMWSub(void) { return RMWSub; }+BinaryenOp BinaryenAtomicRMWAnd(void) { return RMWAnd; }+BinaryenOp BinaryenAtomicRMWOr(void) { return RMWOr; }+BinaryenOp BinaryenAtomicRMWXor(void) { return RMWXor; }+BinaryenOp BinaryenAtomicRMWXchg(void) { return RMWXchg; } BinaryenOp BinaryenTruncSatSFloat32ToInt32(void) { return TruncSatSFloat32ToInt32; }@@ -719,8 +580,6 @@ return DotSVecI16x8ToVecI32x4; } BinaryenOp BinaryenNegVecI64x2(void) { return NegVecI64x2; }-BinaryenOp BinaryenAnyTrueVecI64x2(void) { return AnyTrueVecI64x2; }-BinaryenOp BinaryenAllTrueVecI64x2(void) { return AllTrueVecI64x2; } BinaryenOp BinaryenShlVecI64x2(void) { return ShlVecI64x2; } BinaryenOp BinaryenShrSVecI64x2(void) { return ShrSVecI64x2; } BinaryenOp BinaryenShrUVecI64x2(void) { return ShrUVecI64x2; }@@ -1325,9 +1184,11 @@ Builder(*(Module*)module).makeRefIsNull((Expression*)value)); } -BinaryenExpressionRef BinaryenRefFunc(BinaryenModuleRef module,- const char* func) {- return static_cast<Expression*>(Builder(*(Module*)module).makeRefFunc(func));+BinaryenExpressionRef+BinaryenRefFunc(BinaryenModuleRef module, const char* func, BinaryenType type) {+ Type type_(type);+ return static_cast<Expression*>(+ Builder(*(Module*)module).makeRefFunc(func, type_)); } BinaryenExpressionRef BinaryenRefEq(BinaryenModuleRef module,@@ -1412,8 +1273,7 @@ ((Expression*)expr)->type = Type(type); } void BinaryenExpressionPrint(BinaryenExpressionRef expr) {- WasmPrinter::printExpression((Expression*)expr, std::cout);- std::cout << '\n';+ std::cout << *(Expression*)expr << '\n'; } void BinaryenExpressionFinalize(BinaryenExpressionRef expr) { ReFinalizeNode().visit((Expression*)expr);@@ -3131,7 +2991,7 @@ BinaryenIndex numVarTypes, BinaryenExpressionRef body) { auto* ret = new Function;- ret->name = name;+ ret->setExplicitName(name); ret->sig = Signature(Type(params), Type(results)); for (BinaryenIndex i = 0; i < numVarTypes; i++) { ret->vars.push_back(Type(varTypes[i]));@@ -3149,21 +3009,21 @@ } BinaryenFunctionRef BinaryenGetFunction(BinaryenModuleRef module, const char* name) {- return ((Module*)module)->getFunction(name);+ return ((Module*)module)->getFunctionOrNull(name); } void BinaryenRemoveFunction(BinaryenModuleRef module, const char* name) { ((Module*)module)->removeFunction(name); }-uint32_t BinaryenGetNumFunctions(BinaryenModuleRef module) {+BinaryenIndex BinaryenGetNumFunctions(BinaryenModuleRef module) { return ((Module*)module)->functions.size(); } BinaryenFunctionRef BinaryenGetFunctionByIndex(BinaryenModuleRef module,- BinaryenIndex id) {+ BinaryenIndex index) { const auto& functions = ((Module*)module)->functions;- if (functions.size() <= id) {- Fatal() << "invalid function id.";+ if (functions.size() <= index) {+ Fatal() << "invalid function index."; }- return functions[id].get();+ return functions[index].get(); } // Globals@@ -3174,7 +3034,7 @@ int8_t mutable_, BinaryenExpressionRef init) { auto* ret = new Global();- ret->name = name;+ ret->setExplicitName(name); ret->type = Type(type); ret->mutable_ = !!mutable_; ret->init = (Expression*)init;@@ -3183,11 +3043,22 @@ } BinaryenGlobalRef BinaryenGetGlobal(BinaryenModuleRef module, const char* name) {- return ((Module*)module)->getGlobal(name);+ return ((Module*)module)->getGlobalOrNull(name); } void BinaryenRemoveGlobal(BinaryenModuleRef module, const char* name) { ((Module*)module)->removeGlobal(name); }+BinaryenIndex BinaryenGetNumGlobals(BinaryenModuleRef module) {+ return ((Module*)module)->globals.size();+}+BinaryenGlobalRef BinaryenGetGlobalByIndex(BinaryenModuleRef module,+ BinaryenIndex index) {+ const auto& globals = ((Module*)module)->globals;+ if (globals.size() <= index) {+ Fatal() << "invalid global index.";+ }+ return globals[index].get();+} // Events @@ -3197,7 +3068,7 @@ BinaryenType params, BinaryenType results) { auto* ret = new Event();- ret->name = name;+ ret->setExplicitName(name); ret->attribute = attribute; ret->sig = Signature(Type(params), Type(results)); ((Module*)module)->addEvent(ret);@@ -3205,7 +3076,7 @@ } BinaryenEventRef BinaryenGetEvent(BinaryenModuleRef module, const char* name) {- return ((Module*)module)->getEvent(name);+ return ((Module*)module)->getEventOrNull(name); } void BinaryenRemoveEvent(BinaryenModuleRef module, const char* name) { ((Module*)module)->removeEvent(name);@@ -3330,9 +3201,24 @@ ((Module*)module)->addExport(ret); return ret; }+BinaryenExportRef BinaryenGetExport(BinaryenModuleRef module,+ const char* externalName) {+ return ((Module*)module)->getExportOrNull(externalName);+} void BinaryenRemoveExport(BinaryenModuleRef module, const char* externalName) { ((Module*)module)->removeExport(externalName); }+BinaryenIndex BinaryenGetNumExports(BinaryenModuleRef module) {+ return ((Module*)module)->exports.size();+}+BinaryenExportRef BinaryenGetExportByIndex(BinaryenModuleRef module,+ BinaryenIndex index) {+ const auto& exports = ((Module*)module)->exports;+ if (exports.size() <= index) {+ Fatal() << "invalid export index.";+ }+ return exports[index].get();+} // Function table. One per module @@ -3412,7 +3298,8 @@ wasm->addExport(memoryExport.release()); } for (BinaryenIndex i = 0; i < numSegments; i++) {- wasm->memory.segments.emplace_back(segmentPassive[i],+ wasm->memory.segments.emplace_back(Name(),+ segmentPassive[i], (Expression*)segmentOffsets[i], segments[i], segmentSizes[i]);@@ -3518,7 +3405,7 @@ } void BinaryenModulePrint(BinaryenModuleRef module) {- WasmPrinter::printModule((Module*)module);+ std::cout << *(Module*)module; } void BinaryenModulePrintAsmjs(BinaryenModuleRef module) {@@ -3682,7 +3569,7 @@ // use a stringstream as an std::ostream. Extract the std::string // representation, and then store in the output. std::stringstream ss;- WasmPrinter::printModule((Module*)module, ss);+ ss << *(Module*)module; const auto temp = ss.str(); const auto ctemp = temp.c_str();@@ -3727,7 +3614,7 @@ char* BinaryenModuleAllocateAndWriteText(BinaryenModuleRef module) { std::stringstream ss;- WasmPrinter::printModule((Module*)module, ss);+ ss << *(Module*)module; const std::string out = ss.str(); const int len = out.length() + 1;@@ -3822,7 +3709,7 @@ BinaryenModuleRef module) { PassRunner passRunner((Module*)module); passRunner.options = globalPassOptions;- passRunner.addDefaultOptimizationPasses();+ passRunner.addDefaultFunctionOptimizationPasses(); passRunner.runOnFunction((Function*)func); } void BinaryenFunctionRunPasses(BinaryenFunctionRef func,@@ -3948,17 +3835,6 @@ } const char* BinaryenExportGetValue(BinaryenExportRef export_) { return ((Export*)export_)->value.c_str();-}-uint32_t BinaryenGetNumExports(BinaryenModuleRef module) {- return ((Module*)module)->exports.size();-}-BinaryenExportRef BinaryenGetExportByIndex(BinaryenModuleRef module,- BinaryenIndex id) {- const auto& exports = ((Module*)module)->exports;- if (exports.size() <= id) {- Fatal() << "invalid export id.";- }- return exports[id].get(); } //
binaryen/src/binaryen-c.h view
@@ -25,7 +25,7 @@ // graph (CFG) as input. // // The final part of the API contains miscellaneous utilities like-// debugging/tracing for the API itself.+// debugging for the API itself. // // --------------- //@@ -125,70 +125,12 @@ typedef uint32_t BinaryenExpressionId; BINARYEN_API BinaryenExpressionId BinaryenInvalidId(void);-BINARYEN_API BinaryenExpressionId BinaryenBlockId(void);-BINARYEN_API BinaryenExpressionId BinaryenIfId(void);-BINARYEN_API BinaryenExpressionId BinaryenLoopId(void);-BINARYEN_API BinaryenExpressionId BinaryenBreakId(void);-BINARYEN_API BinaryenExpressionId BinaryenSwitchId(void);-BINARYEN_API BinaryenExpressionId BinaryenCallId(void);-BINARYEN_API BinaryenExpressionId BinaryenCallIndirectId(void);-BINARYEN_API BinaryenExpressionId BinaryenLocalGetId(void);-BINARYEN_API BinaryenExpressionId BinaryenLocalSetId(void);-BINARYEN_API BinaryenExpressionId BinaryenGlobalGetId(void);-BINARYEN_API BinaryenExpressionId BinaryenGlobalSetId(void);-BINARYEN_API BinaryenExpressionId BinaryenLoadId(void);-BINARYEN_API BinaryenExpressionId BinaryenStoreId(void);-BINARYEN_API BinaryenExpressionId BinaryenConstId(void);-BINARYEN_API BinaryenExpressionId BinaryenUnaryId(void);-BINARYEN_API BinaryenExpressionId BinaryenBinaryId(void);-BINARYEN_API BinaryenExpressionId BinaryenSelectId(void);-BINARYEN_API BinaryenExpressionId BinaryenDropId(void);-BINARYEN_API BinaryenExpressionId BinaryenReturnId(void);-BINARYEN_API BinaryenExpressionId BinaryenMemorySizeId(void);-BINARYEN_API BinaryenExpressionId BinaryenMemoryGrowId(void);-BINARYEN_API BinaryenExpressionId BinaryenNopId(void);-BINARYEN_API BinaryenExpressionId BinaryenUnreachableId(void);-BINARYEN_API BinaryenExpressionId BinaryenAtomicCmpxchgId(void);-BINARYEN_API BinaryenExpressionId BinaryenAtomicRMWId(void);-BINARYEN_API BinaryenExpressionId BinaryenAtomicWaitId(void);-BINARYEN_API BinaryenExpressionId BinaryenAtomicNotifyId(void);-BINARYEN_API BinaryenExpressionId BinaryenAtomicFenceId(void);-BINARYEN_API BinaryenExpressionId BinaryenSIMDExtractId(void);-BINARYEN_API BinaryenExpressionId BinaryenSIMDReplaceId(void);-BINARYEN_API BinaryenExpressionId BinaryenSIMDShuffleId(void);-BINARYEN_API BinaryenExpressionId BinaryenSIMDTernaryId(void);-BINARYEN_API BinaryenExpressionId BinaryenSIMDShiftId(void);-BINARYEN_API BinaryenExpressionId BinaryenSIMDLoadId(void);-BINARYEN_API BinaryenExpressionId BinaryenMemoryInitId(void);-BINARYEN_API BinaryenExpressionId BinaryenDataDropId(void);-BINARYEN_API BinaryenExpressionId BinaryenMemoryCopyId(void);-BINARYEN_API BinaryenExpressionId BinaryenMemoryFillId(void);-BINARYEN_API BinaryenExpressionId BinaryenRefNullId(void);-BINARYEN_API BinaryenExpressionId BinaryenRefIsNullId(void);-BINARYEN_API BinaryenExpressionId BinaryenRefFuncId(void);-BINARYEN_API BinaryenExpressionId BinaryenRefEqId(void);-BINARYEN_API BinaryenExpressionId BinaryenTryId(void);-BINARYEN_API BinaryenExpressionId BinaryenThrowId(void);-BINARYEN_API BinaryenExpressionId BinaryenRethrowId(void);-BINARYEN_API BinaryenExpressionId BinaryenBrOnExnId(void);-BINARYEN_API BinaryenExpressionId BinaryenTupleMakeId(void);-BINARYEN_API BinaryenExpressionId BinaryenTupleExtractId(void);-BINARYEN_API BinaryenExpressionId BinaryenPopId(void);-BINARYEN_API BinaryenExpressionId BinaryenI31NewId(void);-BINARYEN_API BinaryenExpressionId BinaryenI31GetId(void);-BINARYEN_API BinaryenExpressionId BinaryenRefTestId(void);-BINARYEN_API BinaryenExpressionId BinaryenRefCastId(void);-BINARYEN_API BinaryenExpressionId BinaryenBrOnCastId(void);-BINARYEN_API BinaryenExpressionId BinaryenRttCanonId(void);-BINARYEN_API BinaryenExpressionId BinaryenRttSubId(void);-BINARYEN_API BinaryenExpressionId BinaryenStructNewId(void);-BINARYEN_API BinaryenExpressionId BinaryenStructGetId(void);-BINARYEN_API BinaryenExpressionId BinaryenStructSetId(void);-BINARYEN_API BinaryenExpressionId BinaryenArrayNewId(void);-BINARYEN_API BinaryenExpressionId BinaryenArrayGetId(void);-BINARYEN_API BinaryenExpressionId BinaryenArraySetId(void);-BINARYEN_API BinaryenExpressionId BinaryenArrayLenId(void); +#define DELEGATE(CLASS_TO_VISIT) \+ BINARYEN_API BinaryenExpressionId Binaryen##CLASS_TO_VISIT##Id(void);++#include "wasm-delegations.h"+ // External kinds (call to get the value of each; you can cache them) typedef uint32_t BinaryenExternalKind;@@ -484,6 +426,7 @@ BINARYEN_API BinaryenOp BinaryenXorVec128(void); BINARYEN_API BinaryenOp BinaryenAndNotVec128(void); BINARYEN_API BinaryenOp BinaryenBitselectVec128(void);+// TODO: Add i8x16.popcnt to C and JS APIs once merged to the proposal BINARYEN_API BinaryenOp BinaryenAbsVecI8x16(void); BINARYEN_API BinaryenOp BinaryenNegVecI8x16(void); BINARYEN_API BinaryenOp BinaryenAnyTrueVecI8x16(void);@@ -524,6 +467,8 @@ BINARYEN_API BinaryenOp BinaryenMaxSVecI16x8(void); BINARYEN_API BinaryenOp BinaryenMaxUVecI16x8(void); BINARYEN_API BinaryenOp BinaryenAvgrUVecI16x8(void);+// TODO: Add i16x8.q15mulr_sat_s to C and JS APIs once merged to the proposal+// TODO: Add extending multiplications to APIs once they are merged as well BINARYEN_API BinaryenOp BinaryenAbsVecI32x4(void); BINARYEN_API BinaryenOp BinaryenNegVecI32x4(void); BINARYEN_API BinaryenOp BinaryenAnyTrueVecI32x4(void);@@ -541,8 +486,6 @@ BINARYEN_API BinaryenOp BinaryenMaxUVecI32x4(void); BINARYEN_API BinaryenOp BinaryenDotSVecI16x8ToVecI32x4(void); BINARYEN_API BinaryenOp BinaryenNegVecI64x2(void);-BINARYEN_API BinaryenOp BinaryenAnyTrueVecI64x2(void);-BINARYEN_API BinaryenOp BinaryenAllTrueVecI64x2(void); BINARYEN_API BinaryenOp BinaryenShlVecI64x2(void); BINARYEN_API BinaryenOp BinaryenShrSVecI64x2(void); BINARYEN_API BinaryenOp BinaryenShrUVecI64x2(void);@@ -583,6 +526,7 @@ BINARYEN_API BinaryenOp BinaryenFloorVecF64x2(void); BINARYEN_API BinaryenOp BinaryenTruncVecF64x2(void); BINARYEN_API BinaryenOp BinaryenNearestVecF64x2(void);+// TODO: Add extending pairwise adds to C and JS APIs once merged BINARYEN_API BinaryenOp BinaryenTruncSatSVecF32x4ToVecI32x4(void); BINARYEN_API BinaryenOp BinaryenTruncSatUVecF32x4ToVecI32x4(void); BINARYEN_API BinaryenOp BinaryenTruncSatSVecF64x2ToVecI64x2(void);@@ -847,7 +791,8 @@ BINARYEN_API BinaryenExpressionRef BinaryenRefIsNull(BinaryenModuleRef module, BinaryenExpressionRef value); BINARYEN_API BinaryenExpressionRef BinaryenRefFunc(BinaryenModuleRef module,- const char* func);+ const char* func,+ BinaryenType type); BINARYEN_API BinaryenExpressionRef BinaryenRefEq(BinaryenModuleRef module, BinaryenExpressionRef left, BinaryenExpressionRef right);@@ -1459,47 +1404,47 @@ // AtomicWait -// Gets the pointer expression of an `atomic.wait` expression.+// Gets the pointer expression of an `memory.atomic.wait` expression. BINARYEN_API BinaryenExpressionRef BinaryenAtomicWaitGetPtr(BinaryenExpressionRef expr);-// Sets the pointer expression of an `atomic.wait` expression.+// Sets the pointer expression of an `memory.atomic.wait` expression. BINARYEN_API void BinaryenAtomicWaitSetPtr(BinaryenExpressionRef expr, BinaryenExpressionRef ptrExpr);-// Gets the expression representing the expected value of an `atomic.wait`-// expression.+// Gets the expression representing the expected value of an+// `memory.atomic.wait` expression. BINARYEN_API BinaryenExpressionRef BinaryenAtomicWaitGetExpected(BinaryenExpressionRef expr);-// Sets the expression representing the expected value of an `atomic.wait`-// expression.+// Sets the expression representing the expected value of an+// `memory.atomic.wait` expression. BINARYEN_API void BinaryenAtomicWaitSetExpected(BinaryenExpressionRef expr, BinaryenExpressionRef expectedExpr);-// Gets the timeout expression of an `atomic.wait` expression.+// Gets the timeout expression of an `memory.atomic.wait` expression. BINARYEN_API BinaryenExpressionRef BinaryenAtomicWaitGetTimeout(BinaryenExpressionRef expr);-// Sets the timeout expression of an `atomic.wait` expression.+// Sets the timeout expression of an `memory.atomic.wait` expression. BINARYEN_API void BinaryenAtomicWaitSetTimeout(BinaryenExpressionRef expr, BinaryenExpressionRef timeoutExpr);-// Gets the expected type of an `atomic.wait` expression.+// Gets the expected type of an `memory.atomic.wait` expression. BINARYEN_API BinaryenType BinaryenAtomicWaitGetExpectedType(BinaryenExpressionRef expr);-// Sets the expected type of an `atomic.wait` expression.+// Sets the expected type of an `memory.atomic.wait` expression. BINARYEN_API void BinaryenAtomicWaitSetExpectedType(BinaryenExpressionRef expr, BinaryenType expectedType); // AtomicNotify -// Gets the pointer expression of an `atomic.notify` expression.+// Gets the pointer expression of an `memory.atomic.notify` expression. BINARYEN_API BinaryenExpressionRef BinaryenAtomicNotifyGetPtr(BinaryenExpressionRef expr);-// Sets the pointer expression of an `atomic.notify` expression.+// Sets the pointer expression of an `memory.atomic.notify` expression. BINARYEN_API void BinaryenAtomicNotifySetPtr(BinaryenExpressionRef expr, BinaryenExpressionRef ptrExpr);-// Gets the notify count expression of an `atomic.notify` expression.+// Gets the notify count expression of an `memory.atomic.notify` expression. BINARYEN_API BinaryenExpressionRef BinaryenAtomicNotifyGetNotifyCount(BinaryenExpressionRef expr);-// Sets the notify count expression of an `atomic.notify` expression.+// Sets the notify count expression of an `memory.atomic.notify` expression. BINARYEN_API void BinaryenAtomicNotifySetNotifyCount(BinaryenExpressionRef expr, BinaryenExpressionRef notifyCountExpr);@@ -1926,7 +1871,8 @@ BinaryenType* varTypes, BinaryenIndex numVarTypes, BinaryenExpressionRef body);-// Gets a function reference by name.+// Gets a function reference by name. Returns NULL if the function does not+// exist. BINARYEN_API BinaryenFunctionRef BinaryenGetFunction(BinaryenModuleRef module, const char* name); // Removes a function by name.@@ -1934,10 +1880,10 @@ const char* name); // Gets the number of functions in the module.-BINARYEN_API uint32_t BinaryenGetNumFunctions(BinaryenModuleRef module);-// Get function pointer from its index.+BINARYEN_API BinaryenIndex BinaryenGetNumFunctions(BinaryenModuleRef module);+// Gets the function at the specified index. BINARYEN_API BinaryenFunctionRef-BinaryenGetFunctionByIndex(BinaryenModuleRef module, BinaryenIndex id);+BinaryenGetFunctionByIndex(BinaryenModuleRef module, BinaryenIndex index); // Imports @@ -1977,47 +1923,72 @@ WASM_DEPRECATED BinaryenExportRef BinaryenAddExport(BinaryenModuleRef module, const char* internalName, const char* externalName);+// Adds a function export to the module. BINARYEN_API BinaryenExportRef BinaryenAddFunctionExport( BinaryenModuleRef module, const char* internalName, const char* externalName);+// Adds a table export to the module. BINARYEN_API BinaryenExportRef BinaryenAddTableExport(BinaryenModuleRef module, const char* internalName, const char* externalName);+// Adds a memory export to the module. BINARYEN_API BinaryenExportRef BinaryenAddMemoryExport( BinaryenModuleRef module, const char* internalName, const char* externalName);+// Adds a global export to the module. BINARYEN_API BinaryenExportRef BinaryenAddGlobalExport( BinaryenModuleRef module, const char* internalName, const char* externalName);+// Adds an event export to the module. BINARYEN_API BinaryenExportRef BinaryenAddEventExport(BinaryenModuleRef module, const char* internalName, const char* externalName);+// Gets an export reference by external name. Returns NULL if the export does+// not exist.+BINARYEN_API BinaryenExportRef BinaryenGetExport(BinaryenModuleRef module,+ const char* externalName);+// Removes an export by external name. BINARYEN_API void BinaryenRemoveExport(BinaryenModuleRef module, const char* externalName);+// Gets the number of exports in the module.+BINARYEN_API BinaryenIndex BinaryenGetNumExports(BinaryenModuleRef module);+// Gets the export at the specified index.+BINARYEN_API BinaryenExportRef+BinaryenGetExportByIndex(BinaryenModuleRef module, BinaryenIndex index); // Globals BINARYEN_REF(Global); +// Adds a global to the module. BINARYEN_API BinaryenGlobalRef BinaryenAddGlobal(BinaryenModuleRef module, const char* name, BinaryenType type, int8_t mutable_, BinaryenExpressionRef init);-// Gets a global reference by name.+// Gets a global reference by name. Returns NULL if the global does not exist. BINARYEN_API BinaryenGlobalRef BinaryenGetGlobal(BinaryenModuleRef module, const char* name);+// Removes a global by name. BINARYEN_API void BinaryenRemoveGlobal(BinaryenModuleRef module, const char* name);+// Gets the number of globals in the module.+BINARYEN_API BinaryenIndex BinaryenGetNumGlobals(BinaryenModuleRef module);+// Gets the global at the specified index.+BINARYEN_API BinaryenGlobalRef+BinaryenGetGlobalByIndex(BinaryenModuleRef module, BinaryenIndex index); // Events BINARYEN_REF(Event); +// Adds an event to the module. BINARYEN_API BinaryenEventRef BinaryenAddEvent(BinaryenModuleRef module, const char* name, uint32_t attribute, BinaryenType params, BinaryenType results);+// Gets an event reference by name. Returns NULL if the event does not exist. BINARYEN_API BinaryenEventRef BinaryenGetEvent(BinaryenModuleRef module, const char* name);+// Removes an event by name. BINARYEN_API void BinaryenRemoveEvent(BinaryenModuleRef module, const char* name); @@ -2385,11 +2356,6 @@ BINARYEN_API const char* BinaryenExportGetName(BinaryenExportRef export_); // Gets the internal name of the specified export. BINARYEN_API const char* BinaryenExportGetValue(BinaryenExportRef export_);-// Gets the number of exports in the module.-BINARYEN_API uint32_t BinaryenGetNumExports(BinaryenModuleRef module);-// Get export pointer from its index.-BINARYEN_API BinaryenExportRef-BinaryenGetExportByIndex(BinaryenModuleRef module, BinaryenIndex id); // // ========= Custom sections =========@@ -2549,10 +2515,10 @@ // ========= Utilities ========= // -// Enable or disable coloring for the WASM printer+// Enable or disable coloring for the Wasm printer BINARYEN_API void BinaryenSetColorsEnabled(int enabled); -// Query whether color is enable for the WASM printer+// Query whether color is enable for the Wasm printer BINARYEN_API int BinaryenAreColorsEnabled(); #ifdef __cplusplus } // extern "C"
binaryen/src/config.h view
@@ -1,1 +1,1 @@-#define PROJECT_VERSION "98"+#define PROJECT_VERSION "98 (version_99)"
binaryen/src/dataflow/utils.h view
@@ -26,7 +26,6 @@ #define wasm_dataflow_utils_h #include "dataflow/node.h"-#include "wasm-printing.h" #include "wasm.h" namespace wasm {@@ -47,7 +46,7 @@ break; case Node::Type::Expr: { o << "expr ";- WasmPrinter::printExpression(node->expr, o, true);+ o << *node->expr << '\n'; break; } case Node::Type::Phi:
binaryen/src/gen-s-parser.inc view
@@ -4,8 +4,8 @@ #ifdef INSTRUCTION_PARSER #undef INSTRUCTION_PARSER-char op[28] = {'\0'};-strncpy(op, s[0]->c_str(), 27);+char op[30] = {'\0'};+strncpy(op, s[0]->c_str(), 29); switch (op[0]) { case 'a': { switch (op[1]) {@@ -50,17 +50,9 @@ default: goto parse_error; } }- case 't': {- switch (op[7]) {- case 'f':- if (strcmp(op, "atomic.fence") == 0) { return makeAtomicFence(s); }- goto parse_error;- case 'n':- if (strcmp(op, "atomic.notify") == 0) { return makeAtomicNotify(s); }- goto parse_error;- default: goto parse_error;- }- }+ case 't':+ if (strcmp(op, "atomic.fence") == 0) { return makeAtomicFence(s); }+ goto parse_error; default: goto parse_error; } }@@ -107,9 +99,17 @@ case '\0': if (strcmp(op, "call") == 0) { return makeCall(s, /*isReturn=*/false); } goto parse_error;- case '_':- if (strcmp(op, "call_indirect") == 0) { return makeCallIndirect(s, /*isReturn=*/false); }- goto parse_error;+ case '_': {+ switch (op[5]) {+ case 'i':+ if (strcmp(op, "call_indirect") == 0) { return makeCallIndirect(s, /*isReturn=*/false); }+ goto parse_error;+ case 'r':+ if (strcmp(op, "call_ref") == 0) { return makeCallRef(s, /*isReturn=*/false); }+ goto parse_error;+ default: goto parse_error;+ }+ } default: goto parse_error; } }@@ -799,13 +799,56 @@ if (strcmp(op, "i16x8.eq") == 0) { return makeBinary(s, BinaryOp::EqVecI16x8); } goto parse_error; case 'x': {- switch (op[19]) {- case 's':- if (strcmp(op, "i16x8.extract_lane_s") == 0) { return makeSIMDExtract(s, SIMDExtractOp::ExtractLaneSVecI16x8, 8); }- goto parse_error;- case 'u':- if (strcmp(op, "i16x8.extract_lane_u") == 0) { return makeSIMDExtract(s, SIMDExtractOp::ExtractLaneUVecI16x8, 8); }- goto parse_error;+ switch (op[9]) {+ case 'a': {+ switch (op[28]) {+ case 's':+ if (strcmp(op, "i16x8.extadd_pairwise_i8x16_s") == 0) { return makeUnary(s, UnaryOp::ExtAddPairwiseSVecI8x16ToI16x8); }+ goto parse_error;+ case 'u':+ if (strcmp(op, "i16x8.extadd_pairwise_i8x16_u") == 0) { return makeUnary(s, UnaryOp::ExtAddPairwiseUVecI8x16ToI16x8); }+ goto parse_error;+ default: goto parse_error;+ }+ }+ case 'm': {+ switch (op[13]) {+ case 'h': {+ switch (op[24]) {+ case 's':+ if (strcmp(op, "i16x8.extmul_high_i8x16_s") == 0) { return makeBinary(s, BinaryOp::ExtMulHighSVecI16x8); }+ goto parse_error;+ case 'u':+ if (strcmp(op, "i16x8.extmul_high_i8x16_u") == 0) { return makeBinary(s, BinaryOp::ExtMulHighUVecI16x8); }+ goto parse_error;+ default: goto parse_error;+ }+ }+ case 'l': {+ switch (op[23]) {+ case 's':+ if (strcmp(op, "i16x8.extmul_low_i8x16_s") == 0) { return makeBinary(s, BinaryOp::ExtMulLowSVecI16x8); }+ goto parse_error;+ case 'u':+ if (strcmp(op, "i16x8.extmul_low_i8x16_u") == 0) { return makeBinary(s, BinaryOp::ExtMulLowUVecI16x8); }+ goto parse_error;+ default: goto parse_error;+ }+ }+ default: goto parse_error;+ }+ }+ case 'r': {+ switch (op[19]) {+ case 's':+ if (strcmp(op, "i16x8.extract_lane_s") == 0) { return makeSIMDExtract(s, SIMDExtractOp::ExtractLaneSVecI16x8, 8); }+ goto parse_error;+ case 'u':+ if (strcmp(op, "i16x8.extract_lane_u") == 0) { return makeSIMDExtract(s, SIMDExtractOp::ExtractLaneUVecI16x8, 8); }+ goto parse_error;+ default: goto parse_error;+ }+ } default: goto parse_error; } }@@ -934,6 +977,9 @@ default: goto parse_error; } }+ case 'q':+ if (strcmp(op, "i16x8.q15mulr_sat_s") == 0) { return makeBinary(s, BinaryOp::Q15MulrSatSVecI16x8); }+ goto parse_error; case 'r': if (strcmp(op, "i16x8.replace_lane") == 0) { return makeSIMDReplace(s, SIMDReplaceOp::ReplaceLaneVecI16x8, 8); } goto parse_error;@@ -1189,9 +1235,6 @@ default: goto parse_error; } }- case 'w':- if (strcmp(op, "i32.atomic.wait") == 0) { return makeAtomicWait(s, Type::i32); }- goto parse_error; default: goto parse_error; } }@@ -1520,9 +1563,52 @@ case 'q': if (strcmp(op, "i32x4.eq") == 0) { return makeBinary(s, BinaryOp::EqVecI32x4); } goto parse_error;- case 'x':- if (strcmp(op, "i32x4.extract_lane") == 0) { return makeSIMDExtract(s, SIMDExtractOp::ExtractLaneVecI32x4, 4); }- goto parse_error;+ case 'x': {+ switch (op[9]) {+ case 'a': {+ switch (op[28]) {+ case 's':+ if (strcmp(op, "i32x4.extadd_pairwise_i16x8_s") == 0) { return makeUnary(s, UnaryOp::ExtAddPairwiseSVecI16x8ToI32x4); }+ goto parse_error;+ case 'u':+ if (strcmp(op, "i32x4.extadd_pairwise_i16x8_u") == 0) { return makeUnary(s, UnaryOp::ExtAddPairwiseUVecI16x8ToI32x4); }+ goto parse_error;+ default: goto parse_error;+ }+ }+ case 'm': {+ switch (op[13]) {+ case 'h': {+ switch (op[24]) {+ case 's':+ if (strcmp(op, "i32x4.extmul_high_i16x8_s") == 0) { return makeBinary(s, BinaryOp::ExtMulHighSVecI32x4); }+ goto parse_error;+ case 'u':+ if (strcmp(op, "i32x4.extmul_high_i16x8_u") == 0) { return makeBinary(s, BinaryOp::ExtMulHighUVecI32x4); }+ goto parse_error;+ default: goto parse_error;+ }+ }+ case 'l': {+ switch (op[23]) {+ case 's':+ if (strcmp(op, "i32x4.extmul_low_i16x8_s") == 0) { return makeBinary(s, BinaryOp::ExtMulLowSVecI32x4); }+ goto parse_error;+ case 'u':+ if (strcmp(op, "i32x4.extmul_low_i16x8_u") == 0) { return makeBinary(s, BinaryOp::ExtMulLowUVecI32x4); }+ goto parse_error;+ default: goto parse_error;+ }+ }+ default: goto parse_error;+ }+ }+ case 'r':+ if (strcmp(op, "i32x4.extract_lane") == 0) { return makeSIMDExtract(s, SIMDExtractOp::ExtractLaneVecI32x4, 4); }+ goto parse_error;+ default: goto parse_error;+ }+ } default: goto parse_error; } }@@ -1909,9 +1995,6 @@ default: goto parse_error; } }- case 'w':- if (strcmp(op, "i64.atomic.wait") == 0) { return makeAtomicWait(s, Type::i64); }- goto parse_error; default: goto parse_error; } }@@ -2237,23 +2320,55 @@ } case 'x': { switch (op[6]) {- case 'a': {+ case 'a':+ if (strcmp(op, "i64x2.add") == 0) { return makeBinary(s, BinaryOp::AddVecI64x2); }+ goto parse_error;+ case 'b':+ if (strcmp(op, "i64x2.bitmask") == 0) { return makeUnary(s, UnaryOp::BitmaskVecI64x2); }+ goto parse_error;+ case 'e': { switch (op[7]) {- case 'd':- if (strcmp(op, "i64x2.add") == 0) { return makeBinary(s, BinaryOp::AddVecI64x2); }- goto parse_error;- case 'l':- if (strcmp(op, "i64x2.all_true") == 0) { return makeUnary(s, UnaryOp::AllTrueVecI64x2); }- goto parse_error;- case 'n':- if (strcmp(op, "i64x2.any_true") == 0) { return makeUnary(s, UnaryOp::AnyTrueVecI64x2); }+ case 'q':+ if (strcmp(op, "i64x2.eq") == 0) { return makeBinary(s, BinaryOp::EqVecI64x2); } goto parse_error;+ case 'x': {+ switch (op[9]) {+ case 'm': {+ switch (op[13]) {+ case 'h': {+ switch (op[24]) {+ case 's':+ if (strcmp(op, "i64x2.extmul_high_i32x4_s") == 0) { return makeBinary(s, BinaryOp::ExtMulHighSVecI64x2); }+ goto parse_error;+ case 'u':+ if (strcmp(op, "i64x2.extmul_high_i32x4_u") == 0) { return makeBinary(s, BinaryOp::ExtMulHighUVecI64x2); }+ goto parse_error;+ default: goto parse_error;+ }+ }+ case 'l': {+ switch (op[23]) {+ case 's':+ if (strcmp(op, "i64x2.extmul_low_i32x4_s") == 0) { return makeBinary(s, BinaryOp::ExtMulLowSVecI64x2); }+ goto parse_error;+ case 'u':+ if (strcmp(op, "i64x2.extmul_low_i32x4_u") == 0) { return makeBinary(s, BinaryOp::ExtMulLowUVecI64x2); }+ goto parse_error;+ default: goto parse_error;+ }+ }+ default: goto parse_error;+ }+ }+ case 'r':+ if (strcmp(op, "i64x2.extract_lane") == 0) { return makeSIMDExtract(s, SIMDExtractOp::ExtractLaneVecI64x2, 2); }+ goto parse_error;+ default: goto parse_error;+ }+ } default: goto parse_error; } }- case 'e':- if (strcmp(op, "i64x2.extract_lane") == 0) { return makeSIMDExtract(s, SIMDExtractOp::ExtractLaneVecI64x2, 2); }- goto parse_error; case 'l': { switch (op[15]) { case 's':@@ -2315,6 +2430,33 @@ default: goto parse_error; } }+ case 'w': {+ switch (op[12]) {+ case 'h': {+ switch (op[23]) {+ case 's':+ if (strcmp(op, "i64x2.widen_high_i32x4_s") == 0) { return makeUnary(s, UnaryOp::WidenHighSVecI32x4ToVecI64x2); }+ goto parse_error;+ case 'u':+ if (strcmp(op, "i64x2.widen_high_i32x4_u") == 0) { return makeUnary(s, UnaryOp::WidenHighUVecI32x4ToVecI64x2); }+ goto parse_error;+ default: goto parse_error;+ }+ }+ case 'l': {+ switch (op[22]) {+ case 's':+ if (strcmp(op, "i64x2.widen_low_i32x4_s") == 0) { return makeUnary(s, UnaryOp::WidenLowSVecI32x4ToVecI64x2); }+ goto parse_error;+ case 'u':+ if (strcmp(op, "i64x2.widen_low_i32x4_u") == 0) { return makeUnary(s, UnaryOp::WidenLowUVecI32x4ToVecI64x2); }+ goto parse_error;+ default: goto parse_error;+ }+ }+ default: goto parse_error;+ }+ } default: goto parse_error; } }@@ -2492,6 +2634,9 @@ default: goto parse_error; } }+ case 'p':+ if (strcmp(op, "i8x16.popcnt") == 0) { return makeUnary(s, UnaryOp::PopcntVecI8x16); }+ goto parse_error; case 'r': if (strcmp(op, "i8x16.replace_lane") == 0) { return makeSIMDReplace(s, SIMDReplaceOp::ReplaceLaneVecI8x16, 16); } goto parse_error;@@ -2574,6 +2719,25 @@ } case 'm': { switch (op[7]) {+ case 'a': {+ switch (op[14]) {+ case 'n':+ if (strcmp(op, "memory.atomic.notify") == 0) { return makeAtomicNotify(s); }+ goto parse_error;+ case 'w': {+ switch (op[18]) {+ case '3':+ if (strcmp(op, "memory.atomic.wait32") == 0) { return makeAtomicWait(s, Type::i32); }+ goto parse_error;+ case '6':+ if (strcmp(op, "memory.atomic.wait64") == 0) { return makeAtomicWait(s, Type::i64); }+ goto parse_error;+ default: goto parse_error;+ }+ }+ default: goto parse_error;+ }+ } case 'c': if (strcmp(op, "memory.copy") == 0) { return makeMemoryCopy(s); } goto parse_error;@@ -2595,9 +2759,25 @@ case 'n': if (strcmp(op, "nop") == 0) { return makeNop(); } goto parse_error;- case 'p':- if (strcmp(op, "pop") == 0) { return makePop(s); }- goto parse_error;+ case 'p': {+ switch (op[1]) {+ case 'o':+ if (strcmp(op, "pop") == 0) { return makePop(s); }+ goto parse_error;+ case 'r': {+ switch (op[9]) {+ case 'n':+ if (strcmp(op, "prefetch.nt") == 0) { return makePrefetch(s, PrefetchOp::PrefetchNontemporal); }+ goto parse_error;+ case 't':+ if (strcmp(op, "prefetch.t") == 0) { return makePrefetch(s, PrefetchOp::PrefetchTemporal); }+ goto parse_error;+ default: goto parse_error;+ }+ }+ default: goto parse_error;+ }+ } case 'r': { switch (op[1]) { case 'e': {@@ -2640,9 +2820,17 @@ case '\0': if (strcmp(op, "return_call") == 0) { return makeCall(s, /*isReturn=*/true); } goto parse_error;- case '_':- if (strcmp(op, "return_call_indirect") == 0) { return makeCallIndirect(s, /*isReturn=*/true); }- goto parse_error;+ case '_': {+ switch (op[12]) {+ case 'i':+ if (strcmp(op, "return_call_indirect") == 0) { return makeCallIndirect(s, /*isReturn=*/true); }+ goto parse_error;+ case 'r':+ if (strcmp(op, "return_call_ref") == 0) { return makeCallRef(s, /*isReturn=*/true); }+ goto parse_error;+ default: goto parse_error;+ }+ } default: goto parse_error; } }@@ -2776,11 +2964,33 @@ case '\0': if (strcmp(op, "v128.load") == 0) { return makeLoad(s, Type::v128, /*isAtomic=*/false); } goto parse_error;- case '3':- if (strcmp(op, "v128.load32_zero") == 0) { return makeSIMDLoad(s, SIMDLoadOp::Load32Zero); }+ case '1':+ if (strcmp(op, "v128.load16_lane") == 0) { return makeSIMDLoadStoreLane(s, LoadLaneVec16x8); } goto parse_error;- case '6':- if (strcmp(op, "v128.load64_zero") == 0) { return makeSIMDLoad(s, SIMDLoadOp::Load64Zero); }+ case '3': {+ switch (op[12]) {+ case 'l':+ if (strcmp(op, "v128.load32_lane") == 0) { return makeSIMDLoadStoreLane(s, LoadLaneVec32x4); }+ goto parse_error;+ case 'z':+ if (strcmp(op, "v128.load32_zero") == 0) { return makeSIMDLoad(s, SIMDLoadOp::Load32Zero); }+ goto parse_error;+ default: goto parse_error;+ }+ }+ case '6': {+ switch (op[12]) {+ case 'l':+ if (strcmp(op, "v128.load64_lane") == 0) { return makeSIMDLoadStoreLane(s, LoadLaneVec64x2); }+ goto parse_error;+ case 'z':+ if (strcmp(op, "v128.load64_zero") == 0) { return makeSIMDLoad(s, SIMDLoadOp::Load64Zero); }+ goto parse_error;+ default: goto parse_error;+ }+ }+ case '8':+ if (strcmp(op, "v128.load8_lane") == 0) { return makeSIMDLoadStoreLane(s, LoadLaneVec8x16); } goto parse_error; default: goto parse_error; }@@ -2791,27 +3001,68 @@ case 'o': if (strcmp(op, "v128.or") == 0) { return makeBinary(s, BinaryOp::OrVec128); } goto parse_error;- case 's':- if (strcmp(op, "v128.store") == 0) { return makeStore(s, Type::v128, /*isAtomic=*/false); }- goto parse_error;+ case 's': {+ switch (op[10]) {+ case '\0':+ if (strcmp(op, "v128.store") == 0) { return makeStore(s, Type::v128, /*isAtomic=*/false); }+ goto parse_error;+ case '1':+ if (strcmp(op, "v128.store16_lane") == 0) { return makeSIMDLoadStoreLane(s, StoreLaneVec16x8); }+ goto parse_error;+ case '3':+ if (strcmp(op, "v128.store32_lane") == 0) { return makeSIMDLoadStoreLane(s, StoreLaneVec32x4); }+ goto parse_error;+ case '6':+ if (strcmp(op, "v128.store64_lane") == 0) { return makeSIMDLoadStoreLane(s, StoreLaneVec64x2); }+ goto parse_error;+ case '8':+ if (strcmp(op, "v128.store8_lane") == 0) { return makeSIMDLoadStoreLane(s, StoreLaneVec8x16); }+ goto parse_error;+ default: goto parse_error;+ }+ } case 'x': if (strcmp(op, "v128.xor") == 0) { return makeBinary(s, BinaryOp::XorVec128); } goto parse_error; default: goto parse_error; } }- case '6':- if (strcmp(op, "v16x8.load_splat") == 0) { return makeSIMDLoad(s, SIMDLoadOp::LoadSplatVec16x8); }+ case '6': {+ switch (op[6]) {+ case 'l':+ if (strcmp(op, "v16x8.load_splat") == 0) { return makeSIMDLoad(s, SIMDLoadOp::LoadSplatVec16x8); }+ goto parse_error;+ case 's':+ if (strcmp(op, "v16x8.signselect") == 0) { return makeSIMDTernary(s, SIMDTernaryOp::SignSelectVec16x8); }+ goto parse_error;+ default: goto parse_error;+ }+ }+ default: goto parse_error;+ }+ }+ case '3': {+ switch (op[6]) {+ case 'l':+ if (strcmp(op, "v32x4.load_splat") == 0) { return makeSIMDLoad(s, SIMDLoadOp::LoadSplatVec32x4); } goto parse_error;+ case 's':+ if (strcmp(op, "v32x4.signselect") == 0) { return makeSIMDTernary(s, SIMDTernaryOp::SignSelectVec32x4); }+ goto parse_error; default: goto parse_error; } }- case '3':- if (strcmp(op, "v32x4.load_splat") == 0) { return makeSIMDLoad(s, SIMDLoadOp::LoadSplatVec32x4); }- goto parse_error;- case '6':- if (strcmp(op, "v64x2.load_splat") == 0) { return makeSIMDLoad(s, SIMDLoadOp::LoadSplatVec64x2); }- goto parse_error;+ case '6': {+ switch (op[6]) {+ case 'l':+ if (strcmp(op, "v64x2.load_splat") == 0) { return makeSIMDLoad(s, SIMDLoadOp::LoadSplatVec64x2); }+ goto parse_error;+ case 's':+ if (strcmp(op, "v64x2.signselect") == 0) { return makeSIMDTernary(s, SIMDTernaryOp::SignSelectVec64x2); }+ goto parse_error;+ default: goto parse_error;+ }+ } case '8': { switch (op[6]) { case 'l':@@ -2821,6 +3072,9 @@ switch (op[7]) { case 'h': if (strcmp(op, "v8x16.shuffle") == 0) { return makeSIMDShuffle(s); }+ goto parse_error;+ case 'i':+ if (strcmp(op, "v8x16.signselect") == 0) { return makeSIMDTernary(s, SIMDTernaryOp::SignSelectVec8x16); } goto parse_error; case 'w': if (strcmp(op, "v8x16.swizzle") == 0) { return makeBinary(s, BinaryOp::SwizzleVec8x16); }
binaryen/src/ir/CMakeLists.txt view
@@ -5,6 +5,7 @@ LocalGraph.cpp ReFinalize.cpp stack-utils.cpp+ module-splitting.cpp ${ir_HEADERS} ) add_library(ir OBJECT ${ir_SOURCES})
binaryen/src/ir/ExpressionAnalyzer.cpp view
@@ -96,186 +96,6 @@ return false; } -//-// Allows visiting the immediate fields of the expression. This is-// useful for comparisons and hashing.-//-// The passed-in visitor object must implement:-// * visitScopeName - a Name that represents a block or loop scope-// * visitNonScopeName - a non-scope name-// * visitInt - anything that has a short enumeration, including-// opcodes, # of bytes in a load, bools, etc. - must be-// guaranteed to fit in an int32 or less.-// * visitLiteral - a Literal-// * visitType - a Type-// * visitIndex - an Index-// * visitAddress - an Address-//--namespace {--template<typename T> void visitImmediates(Expression* curr, T& visitor) {- struct ImmediateVisitor : public OverriddenVisitor<ImmediateVisitor> {- T& visitor;-- ImmediateVisitor(Expression* curr, T& visitor) : visitor(visitor) {- this->visit(curr);- }-- void visitBlock(Block* curr) { visitor.visitScopeName(curr->name); }- void visitIf(If* curr) {}- void visitLoop(Loop* curr) { visitor.visitScopeName(curr->name); }- void visitBreak(Break* curr) { visitor.visitScopeName(curr->name); }- void visitSwitch(Switch* curr) {- for (auto target : curr->targets) {- visitor.visitScopeName(target);- }- visitor.visitScopeName(curr->default_);- }- void visitCall(Call* curr) {- visitor.visitNonScopeName(curr->target);- visitor.visitInt(curr->isReturn);- }- void visitCallIndirect(CallIndirect* curr) {- visitor.visitInt(curr->sig.params.getID());- visitor.visitInt(curr->sig.results.getID());- visitor.visitInt(curr->isReturn);- }- void visitLocalGet(LocalGet* curr) { visitor.visitIndex(curr->index); }- void visitLocalSet(LocalSet* curr) { visitor.visitIndex(curr->index); }- void visitGlobalGet(GlobalGet* curr) {- visitor.visitNonScopeName(curr->name);- }- void visitGlobalSet(GlobalSet* curr) {- visitor.visitNonScopeName(curr->name);- }- void visitLoad(Load* curr) {- visitor.visitInt(curr->bytes);- if (curr->type != Type::unreachable &&- curr->bytes < curr->type.getByteSize()) {- visitor.visitInt(curr->signed_);- }- visitor.visitAddress(curr->offset);- visitor.visitAddress(curr->align);- visitor.visitInt(curr->isAtomic);- }- void visitStore(Store* curr) {- visitor.visitInt(curr->bytes);- visitor.visitAddress(curr->offset);- visitor.visitAddress(curr->align);- visitor.visitInt(curr->isAtomic);- visitor.visitInt(curr->valueType.getID());- }- void visitAtomicRMW(AtomicRMW* curr) {- visitor.visitInt(curr->op);- visitor.visitInt(curr->bytes);- visitor.visitAddress(curr->offset);- }- void visitAtomicCmpxchg(AtomicCmpxchg* curr) {- visitor.visitInt(curr->bytes);- visitor.visitAddress(curr->offset);- }- void visitAtomicWait(AtomicWait* curr) {- visitor.visitAddress(curr->offset);- visitor.visitType(curr->expectedType);- }- void visitAtomicNotify(AtomicNotify* curr) {- visitor.visitAddress(curr->offset);- }- void visitAtomicFence(AtomicFence* curr) { visitor.visitInt(curr->order); }- void visitSIMDExtract(SIMDExtract* curr) {- visitor.visitInt(curr->op);- visitor.visitInt(curr->index);- }- void visitSIMDReplace(SIMDReplace* curr) {- visitor.visitInt(curr->op);- visitor.visitInt(curr->index);- }- void visitSIMDShuffle(SIMDShuffle* curr) {- for (auto x : curr->mask) {- visitor.visitInt(x);- }- }- void visitSIMDTernary(SIMDTernary* curr) { visitor.visitInt(curr->op); }- void visitSIMDShift(SIMDShift* curr) { visitor.visitInt(curr->op); }- void visitSIMDLoad(SIMDLoad* curr) {- visitor.visitInt(curr->op);- visitor.visitAddress(curr->offset);- visitor.visitAddress(curr->align);- }- void visitMemoryInit(MemoryInit* curr) {- visitor.visitIndex(curr->segment);- }- void visitDataDrop(DataDrop* curr) { visitor.visitIndex(curr->segment); }- void visitMemoryCopy(MemoryCopy* curr) {}- void visitMemoryFill(MemoryFill* curr) {}- void visitConst(Const* curr) { visitor.visitLiteral(curr->value); }- void visitUnary(Unary* curr) { visitor.visitInt(curr->op); }- void visitBinary(Binary* curr) { visitor.visitInt(curr->op); }- void visitSelect(Select* curr) {}- void visitDrop(Drop* curr) {}- void visitReturn(Return* curr) {}- void visitMemorySize(MemorySize* curr) {}- void visitMemoryGrow(MemoryGrow* curr) {}- void visitRefNull(RefNull* curr) { visitor.visitType(curr->type); }- void visitRefIsNull(RefIsNull* curr) {}- void visitRefFunc(RefFunc* curr) { visitor.visitNonScopeName(curr->func); }- void visitRefEq(RefEq* curr) {}- void visitTry(Try* curr) {}- void visitThrow(Throw* curr) { visitor.visitNonScopeName(curr->event); }- void visitRethrow(Rethrow* curr) {}- void visitBrOnExn(BrOnExn* curr) {- visitor.visitScopeName(curr->name);- visitor.visitNonScopeName(curr->event);- }- void visitNop(Nop* curr) {}- void visitUnreachable(Unreachable* curr) {}- void visitPop(Pop* curr) {}- void visitTupleMake(TupleMake* curr) {}- void visitTupleExtract(TupleExtract* curr) {- visitor.visitIndex(curr->index);- }- void visitI31New(I31New* curr) {}- void visitI31Get(I31Get* curr) { visitor.visitInt(curr->signed_); }- void visitRefTest(RefTest* curr) {- WASM_UNREACHABLE("TODO (gc): ref.test");- }- void visitRefCast(RefCast* curr) {- WASM_UNREACHABLE("TODO (gc): ref.cast");- }- void visitBrOnCast(BrOnCast* curr) {- WASM_UNREACHABLE("TODO (gc): br_on_cast");- }- void visitRttCanon(RttCanon* curr) {- WASM_UNREACHABLE("TODO (gc): rtt.canon");- }- void visitRttSub(RttSub* curr) { WASM_UNREACHABLE("TODO (gc): rtt.sub"); }- void visitStructNew(StructNew* curr) {- WASM_UNREACHABLE("TODO (gc): struct.new");- }- void visitStructGet(StructGet* curr) {- WASM_UNREACHABLE("TODO (gc): struct.get");- }- void visitStructSet(StructSet* curr) {- WASM_UNREACHABLE("TODO (gc): struct.set");- }- void visitArrayNew(ArrayNew* curr) {- WASM_UNREACHABLE("TODO (gc): array.new");- }- void visitArrayGet(ArrayGet* curr) {- WASM_UNREACHABLE("TODO (gc): array.get");- }- void visitArraySet(ArraySet* curr) {- WASM_UNREACHABLE("TODO (gc): array.set");- }- void visitArrayLen(ArrayLen* curr) {- WASM_UNREACHABLE("TODO (gc): array.len");- }- } singleton(curr, visitor);-}--} // namespace- bool ExpressionAnalyzer::flexibleEqual(Expression* left, Expression* right, ExprComparer comparer) {@@ -285,80 +105,6 @@ std::vector<Expression*> leftStack; std::vector<Expression*> rightStack; - struct Immediates {- Comparer& parent;-- Immediates(Comparer& parent) : parent(parent) {}-- SmallVector<Name, 1> scopeNames;- SmallVector<Name, 1> nonScopeNames;- SmallVector<int32_t, 3> ints;- SmallVector<Literal, 1> literals;- SmallVector<Type, 1> types;- SmallVector<Index, 1> indexes;- SmallVector<Address, 2> addresses;-- void visitScopeName(Name curr) { scopeNames.push_back(curr); }- void visitNonScopeName(Name curr) { nonScopeNames.push_back(curr); }- void visitInt(int32_t curr) { ints.push_back(curr); }- void visitLiteral(Literal curr) { literals.push_back(curr); }- void visitType(Type curr) { types.push_back(curr); }- void visitIndex(Index curr) { indexes.push_back(curr); }- void visitAddress(Address curr) { addresses.push_back(curr); }-- // Comparison is by value, except for names, which must match.- bool operator==(const Immediates& other) {- if (scopeNames.size() != other.scopeNames.size()) {- return false;- }- for (Index i = 0; i < scopeNames.size(); i++) {- auto leftName = scopeNames[i];- auto rightName = other.scopeNames[i];- auto iter = parent.rightNames.find(leftName);- // If it's not found, that means it was defined out of the expression- // being compared, in which case we can just treat it literally - it- // must be exactly identical.- if (iter != parent.rightNames.end()) {- leftName = iter->second;- }- if (leftName != rightName) {- return false;- }- }- if (nonScopeNames != other.nonScopeNames) {- return false;- }- if (ints != other.ints) {- return false;- }- if (literals != other.literals) {- return false;- }- if (types != other.types) {- return false;- }- if (indexes != other.indexes) {- return false;- }- if (addresses != other.addresses) {- return false;- }- return true;- }-- bool operator!=(const Immediates& other) { return !(*this == other); }-- void clear() {- scopeNames.clear();- nonScopeNames.clear();- ints.clear();- literals.clear();- types.clear();- indexes.clear();- addresses.clear();- }- };- bool noteNames(Name left, Name right) { if (left.is() != right.is()) { return false;@@ -371,8 +117,6 @@ } bool compare(Expression* left, Expression* right, ExprComparer comparer) {- Immediates leftImmediates(*this), rightImmediates(*this);- // The empty name is the same on both sides. rightNames[Name()] = Name(); @@ -390,45 +134,16 @@ if (!left) { continue; }+ // There are actual expressions to compare here. Start with the custom+ // comparer function that was provided. if (comparer(left, right)) {- continue; // comparison hook, before all the rest+ continue; }- // continue with normal structural comparison- if (left->_id != right->_id) {+ if (left->type != right->type) { return false; }- // Blocks and loops introduce scoping.- if (auto* block = left->dynCast<Block>()) {- if (!noteNames(block->name, right->cast<Block>()->name)) {- return false;- }- } else if (auto* loop = left->dynCast<Loop>()) {- if (!noteNames(loop->name, right->cast<Loop>()->name)) {- return false;- }- } else {- // For all other nodes, compare their immediate values- visitImmediates(left, leftImmediates);- visitImmediates(right, rightImmediates);- if (leftImmediates != rightImmediates) {- return false;- }- leftImmediates.clear();- rightImmediates.clear();- }- // Add child nodes.- Index counter = 0;- for (auto* child : ChildIterator(left)) {- leftStack.push_back(child);- counter++;- }- for (auto* child : ChildIterator(right)) {- rightStack.push_back(child);- counter--;- }- // The number of child nodes must match (e.g. return has an optional- // one).- if (counter != 0) {+ // Do the actual comparison, updating the names and stacks accordingly.+ if (!compareNodes(left, right)) { return false; } }@@ -437,6 +152,97 @@ } return true; }++ bool compareNodes(Expression* left, Expression* right) {+ if (left->_id != right->_id) {+ return false;+ }++#define DELEGATE_ID left->_id++// Create cast versions of it for later operations.+#define DELEGATE_START(id) \+ auto* castLeft = left->cast<id>(); \+ WASM_UNUSED(castLeft); \+ auto* castRight = right->cast<id>(); \+ WASM_UNUSED(castRight);++// Handle each type of field, comparing it appropriately.+#define DELEGATE_FIELD_CHILD(id, name) \+ leftStack.push_back(castLeft->name); \+ rightStack.push_back(castRight->name);++#define DELEGATE_FIELD_CHILD_VECTOR(id, name) \+ if (castLeft->name.size() != castRight->name.size()) { \+ return false; \+ } \+ for (auto* child : castLeft->name) { \+ leftStack.push_back(child); \+ } \+ for (auto* child : castRight->name) { \+ rightStack.push_back(child); \+ }++#define COMPARE_FIELD(name) \+ if (castLeft->name != castRight->name) { \+ return false; \+ }++#define DELEGATE_FIELD_INT(id, name) COMPARE_FIELD(name)+#define DELEGATE_FIELD_LITERAL(id, name) COMPARE_FIELD(name)+#define DELEGATE_FIELD_NAME(id, name) COMPARE_FIELD(name)+#define DELEGATE_FIELD_SIGNATURE(id, name) COMPARE_FIELD(name)+#define DELEGATE_FIELD_TYPE(id, name) COMPARE_FIELD(name)+#define DELEGATE_FIELD_ADDRESS(id, name) COMPARE_FIELD(name)++#define COMPARE_LIST(name) \+ if (castLeft->name.size() != castRight->name.size()) { \+ return false; \+ } \+ for (Index i = 0; i < castLeft->name.size(); i++) { \+ if (castLeft->name[i] != castRight->name[i]) { \+ return false; \+ } \+ }++#define DELEGATE_FIELD_INT_ARRAY(id, name) COMPARE_LIST(name)++#define DELEGATE_FIELD_SCOPE_NAME_DEF(id, name) \+ if (castLeft->name.is() != castRight->name.is()) { \+ return false; \+ } \+ rightNames[castLeft->name] = castRight->name;++#define DELEGATE_FIELD_SCOPE_NAME_USE(id, name) \+ if (!compareNames(castLeft->name, castRight->name)) { \+ return false; \+ }++#define DELEGATE_FIELD_SCOPE_NAME_USE_VECTOR(id, name) \+ if (castLeft->name.size() != castRight->name.size()) { \+ return false; \+ } \+ for (Index i = 0; i < castLeft->name.size(); i++) { \+ if (!compareNames(castLeft->name[i], castRight->name[i])) { \+ return false; \+ } \+ }++#include "wasm-delegations-fields.h"++ return true;+ }++ bool compareNames(Name left, Name right) {+ auto iter = rightNames.find(left);+ // If it's not found, that means it was defined out of the expression+ // being compared, in which case we can just treat it literally - it+ // must be exactly identical.+ if (iter != rightNames.end()) {+ left = iter->second;+ }+ return left == right;+ } }; return Comparer().compare(left, right, comparer);@@ -452,12 +258,6 @@ std::map<Name, Index> internalNames; ExpressionStack stack; - void noteScopeName(Name curr) {- if (curr.is()) {- internalNames[curr] = internalCounter++;- }- }- Hasher(Expression* curr) { stack.push_back(curr); @@ -465,6 +265,9 @@ curr = stack.back(); stack.pop_back(); if (!curr) {+ // This was an optional child that was not present. Hash a 0 to+ // represent that.+ rehash(digest, 0); continue; } rehash(digest, curr->_id);@@ -477,27 +280,51 @@ // call_imports type, etc. The simplest thing is just to hash the // type for all of them. rehash(digest, curr->type.getID());- // Blocks and loops introduce scoping.- if (auto* block = curr->dynCast<Block>()) {- noteScopeName(block->name);- } else if (auto* loop = curr->dynCast<Loop>()) {- noteScopeName(loop->name);- } else {- // For all other nodes, compare their immediate values- visitImmediates(curr, *this);- }- // Hash children- Index counter = 0;- for (auto* child : ChildIterator(curr)) {- stack.push_back(child);- counter++;- }- // Sometimes children are optional, e.g. return, so we must hash- // their number as well.- rehash(digest, counter);+ // Hash the contents of the expression.+ hashExpression(curr); } } + void hashExpression(Expression* curr) {++#define DELEGATE_ID curr->_id++// Create cast versions of it for later operations.+#define DELEGATE_START(id) \+ auto* cast = curr->cast<id>(); \+ WASM_UNUSED(cast);++// Handle each type of field, comparing it appropriately.+#define DELEGATE_GET_FIELD(id, name) cast->name++#define DELEGATE_FIELD_CHILD(id, name) stack.push_back(cast->name);++#define HASH_FIELD(name) rehash(digest, cast->name);++#define DELEGATE_FIELD_INT(id, name) HASH_FIELD(name)+#define DELEGATE_FIELD_LITERAL(id, name) HASH_FIELD(name)+#define DELEGATE_FIELD_SIGNATURE(id, name) HASH_FIELD(name)++#define DELEGATE_FIELD_NAME(id, name) visitNonScopeName(cast->name)+#define DELEGATE_FIELD_TYPE(id, name) visitType(cast->name);+#define DELEGATE_FIELD_ADDRESS(id, name) visitAddress(cast->name);++// Note that we only note the scope name, but do not also visit it. That means+// that (block $x) and (block) get the same hash. In other words, we only change+// the hash based on uses of scope names, that is when there is a noticeable+// difference in break targets.+#define DELEGATE_FIELD_SCOPE_NAME_DEF(id, name) noteScopeName(cast->name);++#define DELEGATE_FIELD_SCOPE_NAME_USE(id, name) visitScopeName(cast->name);++#include "wasm-delegations-fields.h"+ }++ void noteScopeName(Name curr) {+ if (curr.is()) {+ internalNames[curr] = internalCounter++;+ }+ } void visitScopeName(Name curr) { // Names are relative, we give the same hash for // (block $x (br $x))@@ -508,14 +335,7 @@ rehash(digest, internalNames[curr]); } void visitNonScopeName(Name curr) { rehash(digest, uint64_t(curr.str)); }- void visitInt(int32_t curr) { rehash(digest, curr); }- void visitLiteral(Literal curr) { rehash(digest, curr); } void visitType(Type curr) { rehash(digest, curr.getID()); }- void visitIndex(Index curr) {- static_assert(sizeof(Index) == sizeof(uint32_t),- "wasm64 will need changes here");- rehash(digest, curr);- } void visitAddress(Address curr) { rehash(digest, curr.addr); } };
binaryen/src/ir/ExpressionManipulator.cpp view
@@ -23,298 +23,92 @@ Expression* flexibleCopy(Expression* original, Module& wasm, CustomCopier custom) {- struct Copier : public OverriddenVisitor<Copier, Expression*> {- Module& wasm;- CustomCopier custom;+ // Perform the copy using a stack of tasks (avoiding recusion).+ struct CopyTask {+ // The thing to copy.+ Expression* original;+ // The location of the pointer to write the copy to.+ Expression** destPointer;+ };+ std::vector<CopyTask> tasks;+ Expression* ret;+ tasks.push_back({original, &ret});+ while (!tasks.empty()) {+ auto task = tasks.back();+ tasks.pop_back();+ // If the custom copier handled this one, we have nothing to do.+ auto* copy = custom(task.original);+ if (copy) {+ *task.destPointer = copy;+ continue;+ }+ // If the original is a null, just copy that. (This can happen for an+ // optional child.)+ auto* original = task.original;+ if (original == nullptr) {+ *task.destPointer = nullptr;+ continue;+ }+ // Allocate a new copy, and copy the fields. - Builder builder;+#define DELEGATE_ID original->_id - Copier(Module& wasm, CustomCopier custom)- : wasm(wasm), custom(custom), builder(wasm) {}+// Allocate a new expression of the right type, and create cast versions of it+// for later operations.+#define DELEGATE_START(id) \+ copy = wasm.allocator.alloc<id>(); \+ auto* castOriginal = original->cast<id>(); \+ WASM_UNUSED(castOriginal); \+ auto* castCopy = copy->cast<id>(); \+ WASM_UNUSED(castCopy); - Expression* copy(Expression* curr) {- if (!curr) {- return nullptr;- }- auto* ret = custom(curr);- if (ret) {- return ret;- }- return OverriddenVisitor<Copier, Expression*>::visit(curr);- }+// Handle each type of field, copying it appropriately.+#define DELEGATE_FIELD_CHILD(id, name) \+ tasks.push_back({castOriginal->name, &castCopy->name}); - Expression* visitBlock(Block* curr) {- ExpressionList list(wasm.allocator);- for (Index i = 0; i < curr->list.size(); i++) {- list.push_back(copy(curr->list[i]));- }- return builder.makeBlock(curr->name, list, curr->type);- }- Expression* visitIf(If* curr) {- return builder.makeIf(copy(curr->condition),- copy(curr->ifTrue),- copy(curr->ifFalse),- curr->type);- }- Expression* visitLoop(Loop* curr) {- return builder.makeLoop(curr->name, copy(curr->body), curr->type);- }- Expression* visitBreak(Break* curr) {- return builder.makeBreak(- curr->name, copy(curr->value), copy(curr->condition));- }- Expression* visitSwitch(Switch* curr) {- return builder.makeSwitch(curr->targets,- curr->default_,- copy(curr->condition),- copy(curr->value));- }- Expression* visitCall(Call* curr) {- auto* ret =- builder.makeCall(curr->target, {}, curr->type, curr->isReturn);- for (Index i = 0; i < curr->operands.size(); i++) {- ret->operands.push_back(copy(curr->operands[i]));- }- return ret;- }- Expression* visitCallIndirect(CallIndirect* curr) {- std::vector<Expression*> copiedOps;- for (auto op : curr->operands) {- copiedOps.push_back(copy(op));- }- return builder.makeCallIndirect(- copy(curr->target), copiedOps, curr->sig, curr->isReturn);- }- Expression* visitLocalGet(LocalGet* curr) {- return builder.makeLocalGet(curr->index, curr->type);- }- Expression* visitLocalSet(LocalSet* curr) {- if (curr->isTee()) {- return builder.makeLocalTee(curr->index, copy(curr->value), curr->type);- } else {- return builder.makeLocalSet(curr->index, copy(curr->value));- }- }- Expression* visitGlobalGet(GlobalGet* curr) {- return builder.makeGlobalGet(curr->name, curr->type);- }- Expression* visitGlobalSet(GlobalSet* curr) {- return builder.makeGlobalSet(curr->name, copy(curr->value));- }- Expression* visitLoad(Load* curr) {- if (curr->isAtomic) {- return builder.makeAtomicLoad(- curr->bytes, curr->offset, copy(curr->ptr), curr->type);- }- return builder.makeLoad(curr->bytes,- LoadUtils::isSignRelevant(curr) ? curr->signed_- : false,- curr->offset,- curr->align,- copy(curr->ptr),- curr->type);- }- Expression* visitStore(Store* curr) {- if (curr->isAtomic) {- return builder.makeAtomicStore(curr->bytes,- curr->offset,- copy(curr->ptr),- copy(curr->value),- curr->valueType);- }- return builder.makeStore(curr->bytes,- curr->offset,- curr->align,- copy(curr->ptr),- copy(curr->value),- curr->valueType);- }- Expression* visitAtomicRMW(AtomicRMW* curr) {- return builder.makeAtomicRMW(curr->op,- curr->bytes,- curr->offset,- copy(curr->ptr),- copy(curr->value),- curr->type);- }- Expression* visitAtomicCmpxchg(AtomicCmpxchg* curr) {- return builder.makeAtomicCmpxchg(curr->bytes,- curr->offset,- copy(curr->ptr),- copy(curr->expected),- copy(curr->replacement),- curr->type);- }- Expression* visitAtomicWait(AtomicWait* curr) {- return builder.makeAtomicWait(copy(curr->ptr),- copy(curr->expected),- copy(curr->timeout),- curr->expectedType,- curr->offset);- }- Expression* visitAtomicNotify(AtomicNotify* curr) {- return builder.makeAtomicNotify(- copy(curr->ptr), copy(curr->notifyCount), curr->offset);- }- Expression* visitAtomicFence(AtomicFence* curr) {- return builder.makeAtomicFence();- }- Expression* visitSIMDExtract(SIMDExtract* curr) {- return builder.makeSIMDExtract(curr->op, copy(curr->vec), curr->index);- }- Expression* visitSIMDReplace(SIMDReplace* curr) {- return builder.makeSIMDReplace(- curr->op, copy(curr->vec), curr->index, copy(curr->value));- }- Expression* visitSIMDShuffle(SIMDShuffle* curr) {- return builder.makeSIMDShuffle(- copy(curr->left), copy(curr->right), curr->mask);- }- Expression* visitSIMDTernary(SIMDTernary* curr) {- return builder.makeSIMDTernary(- curr->op, copy(curr->a), copy(curr->b), copy(curr->c));- }- Expression* visitSIMDShift(SIMDShift* curr) {- return builder.makeSIMDShift(- curr->op, copy(curr->vec), copy(curr->shift));- }- Expression* visitSIMDLoad(SIMDLoad* curr) {- return builder.makeSIMDLoad(- curr->op, curr->offset, curr->align, copy(curr->ptr));- }- Expression* visitConst(Const* curr) {- return builder.makeConst(curr->value);- }- Expression* visitMemoryInit(MemoryInit* curr) {- return builder.makeMemoryInit(- curr->segment, copy(curr->dest), copy(curr->offset), copy(curr->size));- }- Expression* visitDataDrop(DataDrop* curr) {- return builder.makeDataDrop(curr->segment);- }- Expression* visitMemoryCopy(MemoryCopy* curr) {- return builder.makeMemoryCopy(- copy(curr->dest), copy(curr->source), copy(curr->size));- }- Expression* visitMemoryFill(MemoryFill* curr) {- return builder.makeMemoryFill(- copy(curr->dest), copy(curr->value), copy(curr->size));- }- Expression* visitUnary(Unary* curr) {- return builder.makeUnary(curr->op, copy(curr->value));- }- Expression* visitBinary(Binary* curr) {- return builder.makeBinary(curr->op, copy(curr->left), copy(curr->right));- }- Expression* visitSelect(Select* curr) {- return builder.makeSelect(copy(curr->condition),- copy(curr->ifTrue),- copy(curr->ifFalse),- curr->type);- }- Expression* visitDrop(Drop* curr) {- return builder.makeDrop(copy(curr->value));- }- Expression* visitReturn(Return* curr) {- return builder.makeReturn(copy(curr->value));- }- Expression* visitMemorySize(MemorySize* curr) {- return builder.makeMemorySize();- }- Expression* visitMemoryGrow(MemoryGrow* curr) {- return builder.makeMemoryGrow(copy(curr->delta));- }- Expression* visitRefNull(RefNull* curr) {- return builder.makeRefNull(curr->type);- }- Expression* visitRefIsNull(RefIsNull* curr) {- return builder.makeRefIsNull(copy(curr->value));- }- Expression* visitRefFunc(RefFunc* curr) {- return builder.makeRefFunc(curr->func);- }- Expression* visitRefEq(RefEq* curr) {- return builder.makeRefEq(copy(curr->left), copy(curr->right));- }- Expression* visitTry(Try* curr) {- return builder.makeTry(- copy(curr->body), copy(curr->catchBody), curr->type);- }- Expression* visitThrow(Throw* curr) {- std::vector<Expression*> operands;- for (Index i = 0; i < curr->operands.size(); i++) {- operands.push_back(copy(curr->operands[i]));- }- return builder.makeThrow(curr->event, std::move(operands));- }- Expression* visitRethrow(Rethrow* curr) {- return builder.makeRethrow(copy(curr->exnref));- }- Expression* visitBrOnExn(BrOnExn* curr) {- return builder.makeBrOnExn(- curr->name, curr->event, copy(curr->exnref), curr->sent);- }- Expression* visitNop(Nop* curr) { return builder.makeNop(); }- Expression* visitUnreachable(Unreachable* curr) {- return builder.makeUnreachable();- }- Expression* visitPop(Pop* curr) { return builder.makePop(curr->type); }- Expression* visitTupleMake(TupleMake* curr) {- std::vector<Expression*> operands;- for (auto* op : curr->operands) {- operands.push_back(copy(op));- }- return builder.makeTupleMake(std::move(operands));- }- Expression* visitTupleExtract(TupleExtract* curr) {- return builder.makeTupleExtract(copy(curr->tuple), curr->index);- }- Expression* visitI31New(I31New* curr) {- return builder.makeI31New(copy(curr->value));- }- Expression* visitI31Get(I31Get* curr) {- return builder.makeI31Get(copy(curr->i31), curr->signed_);- }- Expression* visitRefTest(RefTest* curr) {- WASM_UNREACHABLE("TODO (gc): ref.test");- }- Expression* visitRefCast(RefCast* curr) {- WASM_UNREACHABLE("TODO (gc): ref.cast");- }- Expression* visitBrOnCast(BrOnCast* curr) {- WASM_UNREACHABLE("TODO (gc): br_on_cast");- }- Expression* visitRttCanon(RttCanon* curr) {- WASM_UNREACHABLE("TODO (gc): rtt.canon");- }- Expression* visitRttSub(RttSub* curr) {- WASM_UNREACHABLE("TODO (gc): rtt.sub");- }- Expression* visitStructNew(StructNew* curr) {- WASM_UNREACHABLE("TODO (gc): struct.new");- }- Expression* visitStructGet(StructGet* curr) {- WASM_UNREACHABLE("TODO (gc): struct.get");- }- Expression* visitStructSet(StructSet* curr) {- WASM_UNREACHABLE("TODO (gc): struct.set");- }- Expression* visitArrayNew(ArrayNew* curr) {- WASM_UNREACHABLE("TODO (gc): array.new");- }- Expression* visitArrayGet(ArrayGet* curr) {- WASM_UNREACHABLE("TODO (gc): array.get");- }- Expression* visitArraySet(ArraySet* curr) {- WASM_UNREACHABLE("TODO (gc): array.set");- }- Expression* visitArrayLen(ArrayLen* curr) {- WASM_UNREACHABLE("TODO (gc): array.len");- }- };+#define DELEGATE_FIELD_CHILD_VECTOR(id, name) \+ castCopy->name.resize(castOriginal->name.size()); \+ for (Index i = 0; i < castOriginal->name.size(); i++) { \+ tasks.push_back({castOriginal->name[i], &castCopy->name[i]}); \+ } - Copier copier(wasm, custom);- return copier.copy(original);+#define COPY_FIELD(name) castCopy->name = castOriginal->name;++#define DELEGATE_FIELD_INT(id, name) COPY_FIELD(name)+#define DELEGATE_FIELD_LITERAL(id, name) COPY_FIELD(name)+#define DELEGATE_FIELD_NAME(id, name) COPY_FIELD(name)+#define DELEGATE_FIELD_SCOPE_NAME_DEF(id, name) COPY_FIELD(name)+#define DELEGATE_FIELD_SCOPE_NAME_USE(id, name) COPY_FIELD(name)+#define DELEGATE_FIELD_SIGNATURE(id, name) COPY_FIELD(name)+#define DELEGATE_FIELD_TYPE(id, name) COPY_FIELD(name)+#define DELEGATE_FIELD_ADDRESS(id, name) COPY_FIELD(name)++#define COPY_FIELD_LIST(name) \+ for (Index i = 0; i < castOriginal->name.size(); i++) { \+ castCopy->name[i] = castOriginal->name[i]; \+ }++#define COPY_VECTOR(name) \+ castCopy->name.resize(castOriginal->name.size()); \+ COPY_FIELD_LIST(name)++#define COPY_ARRAY(name) \+ assert(castCopy->name.size() == castOriginal->name.size()); \+ COPY_FIELD_LIST(name)++#define DELEGATE_FIELD_SCOPE_NAME_USE_VECTOR(id, name) COPY_VECTOR(name)++#define DELEGATE_FIELD_INT_ARRAY(id, name) COPY_ARRAY(name)++#include "wasm-delegations-fields.h"++ // The type can be simply copied.+ copy->type = original->type;++ // Write the copy to where it should be referred to.+ *task.destPointer = copy;+ }+ return ret; } // Splice an item into the middle of a block's list
binaryen/src/ir/LocalGraph.cpp view
@@ -20,7 +20,6 @@ #include <ir/find_all.h> #include <ir/local-graph.h> #include <wasm-builder.h>-#include <wasm-printing.h> namespace wasm {
binaryen/src/ir/ReFinalize.cpp view
@@ -109,6 +109,10 @@ void ReFinalize::visitSIMDTernary(SIMDTernary* curr) { curr->finalize(); } void ReFinalize::visitSIMDShift(SIMDShift* curr) { curr->finalize(); } void ReFinalize::visitSIMDLoad(SIMDLoad* curr) { curr->finalize(); }+void ReFinalize::visitSIMDLoadStoreLane(SIMDLoadStoreLane* curr) {+ curr->finalize();+}+void ReFinalize::visitPrefetch(Prefetch* curr) { curr->finalize(); } void ReFinalize::visitMemoryInit(MemoryInit* curr) { curr->finalize(); } void ReFinalize::visitDataDrop(DataDrop* curr) { curr->finalize(); } void ReFinalize::visitMemoryCopy(MemoryCopy* curr) { curr->finalize(); }@@ -123,7 +127,11 @@ void ReFinalize::visitMemoryGrow(MemoryGrow* curr) { curr->finalize(); } void ReFinalize::visitRefNull(RefNull* curr) { curr->finalize(); } void ReFinalize::visitRefIsNull(RefIsNull* curr) { curr->finalize(); }-void ReFinalize::visitRefFunc(RefFunc* curr) { curr->finalize(); }+void ReFinalize::visitRefFunc(RefFunc* curr) {+ // TODO: should we look up the function and update the type from there? This+ // could handle a change to the function's type, but is also not really what+ // this class has been meant to do.+} void ReFinalize::visitRefEq(RefEq* curr) { curr->finalize(); } void ReFinalize::visitTry(Try* curr) { curr->finalize(); } void ReFinalize::visitThrow(Throw* curr) { curr->finalize(); }@@ -143,11 +151,16 @@ void ReFinalize::visitTupleExtract(TupleExtract* curr) { curr->finalize(); } void ReFinalize::visitI31New(I31New* curr) { curr->finalize(); } void ReFinalize::visitI31Get(I31Get* curr) { curr->finalize(); }+void ReFinalize::visitCallRef(CallRef* curr) { curr->finalize(); } void ReFinalize::visitRefTest(RefTest* curr) { curr->finalize(); } void ReFinalize::visitRefCast(RefCast* curr) { curr->finalize(); } void ReFinalize::visitBrOnCast(BrOnCast* curr) { curr->finalize();- WASM_UNREACHABLE("TODO (gc): br_on_cast");+ if (curr->type == Type::unreachable) {+ replaceUntaken(curr->ref, nullptr);+ } else {+ updateBreakValueType(curr->name, curr->getCastType());+ } } void ReFinalize::visitRttCanon(RttCanon* curr) { curr->finalize(); } void ReFinalize::visitRttSub(RttSub* curr) { curr->finalize(); }
binaryen/src/ir/abstract.h view
@@ -27,6 +27,7 @@ enum Op { // Unary+ Abs, Neg, // Binary Add,@@ -91,6 +92,8 @@ } case Type::f32: { switch (op) {+ case Abs:+ return AbsFloat32; case Neg: return NegFloat32; default:@@ -100,6 +103,8 @@ } case Type::f64: { switch (op) {+ case Abs:+ return AbsFloat64; case Neg: return NegFloat64; default:
binaryen/src/ir/branch-utils.h view
@@ -28,111 +28,127 @@ // Some branches are obviously not actually reachable (e.g. (br $out // (unreachable))) -inline bool isBranchReachable(Break* br) {- return !(br->value && br->value->type == Type::unreachable) &&- !(br->condition && br->condition->type == Type::unreachable);+inline bool isBranchReachable(Expression* expr) {+ // If any child is unreachable, the branch is not taken. Note that expr itself+ // may be unreachable regardless (as in the case of a simple Break with no+ // condition, which is still taken).+ for (auto child : ChildIterator(expr)) {+ if (child->type == Type::unreachable) {+ return false;+ }+ }+ return true; } -inline bool isBranchReachable(Switch* sw) {- return !(sw->value && sw->value->type == Type::unreachable) &&- sw->condition->type != Type::unreachable;-}+// Perform a generic operation on uses of scope names (branch targets) in an+// expression. The provided function receives a Name& which it can modify if it+// needs to.+template<typename T> void operateOnScopeNameUses(Expression* expr, T func) {+#define DELEGATE_ID expr->_id -inline bool isBranchReachable(BrOnExn* br) {- return br->exnref->type != Type::unreachable;+#define DELEGATE_START(id) \+ auto* cast = expr->cast<id>(); \+ WASM_UNUSED(cast);++#define DELEGATE_GET_FIELD(id, name) cast->name++#define DELEGATE_FIELD_SCOPE_NAME_USE(id, name) func(cast->name);++#define DELEGATE_FIELD_CHILD(id, name)+#define DELEGATE_FIELD_INT(id, name)+#define DELEGATE_FIELD_LITERAL(id, name)+#define DELEGATE_FIELD_NAME(id, name)+#define DELEGATE_FIELD_SCOPE_NAME_DEF(id, name)+#define DELEGATE_FIELD_SIGNATURE(id, name)+#define DELEGATE_FIELD_TYPE(id, name)+#define DELEGATE_FIELD_ADDRESS(id, name)+#define DELEGATE_FIELD_CHILD_VECTOR(id, name)+#define DELEGATE_FIELD_INT_ARRAY(id, name)++#include "wasm-delegations-fields.h" } -inline bool isBranchReachable(Expression* expr) {- if (auto* br = expr->dynCast<Break>()) {- return isBranchReachable(br);- } else if (auto* sw = expr->dynCast<Switch>()) {- return isBranchReachable(sw);- } else if (auto* br = expr->dynCast<BrOnExn>()) {- return isBranchReachable(br);- }- WASM_UNREACHABLE("unexpected expression type");+// Similar to operateOnScopeNameUses, but also passes in the type that is sent+// if the branch is taken. The type is none if there is no value.+template<typename T>+void operateOnScopeNameUsesAndSentTypes(Expression* expr, T func) {+ operateOnScopeNameUses(expr, [&](Name& name) {+ // There isn't a delegate mechanism for getting a sent value, so do a direct+ // if-else chain. This will need to be updated with new br variants.+ if (auto* br = expr->dynCast<Break>()) {+ func(name, br->value ? br->value->type : Type::none);+ } else if (auto* sw = expr->dynCast<Switch>()) {+ func(name, sw->value ? sw->value->type : Type::none);+ } else if (auto* br = expr->dynCast<BrOnExn>()) {+ func(name, br->sent);+ } else if (auto* br = expr->dynCast<BrOnCast>()) {+ func(name, br->getCastType());+ } else {+ WASM_UNREACHABLE("bad br type");+ }+ }); } -using NameSet = std::set<Name>;+// Perform a generic operation on definitions of scope names in an expression.+// The provided function receives a Name& which it can modify if it needs to.+template<typename T> void operateOnScopeNameDefs(Expression* expr, T func) {+#define DELEGATE_ID expr->_id -inline NameSet getUniqueTargets(Break* br) { return {br->name}; }+#define DELEGATE_START(id) \+ auto* cast = expr->cast<id>(); \+ WASM_UNUSED(cast); -inline NameSet getUniqueTargets(Switch* sw) {- NameSet ret;- for (auto target : sw->targets) {- ret.insert(target);- }- ret.insert(sw->default_);- return ret;+#define DELEGATE_FIELD_SCOPE_NAME_DEF(id, name) func(cast->name)++#define DELEGATE_FIELD_CHILD(id, name)+#define DELEGATE_FIELD_INT(id, name)+#define DELEGATE_FIELD_LITERAL(id, name)+#define DELEGATE_FIELD_NAME(id, name)+#define DELEGATE_FIELD_SIGNATURE(id, name)+#define DELEGATE_FIELD_TYPE(id, name)+#define DELEGATE_FIELD_ADDRESS(id, name)+#define DELEGATE_FIELD_CHILD_VECTOR(id, name)+#define DELEGATE_FIELD_INT_ARRAY(id, name)+#define DELEGATE_FIELD_SCOPE_NAME_USE(id, name)+#define DELEGATE_FIELD_SCOPE_NAME_USE_VECTOR(id, name)++#include "wasm-delegations-fields.h" } -inline NameSet getUniqueTargets(BrOnExn* br) { return {br->name}; }+using NameSet = std::set<Name>; inline NameSet getUniqueTargets(Expression* expr) {- if (auto* br = expr->dynCast<Break>()) {- return getUniqueTargets(br);- }- if (auto* br = expr->dynCast<Switch>()) {- return getUniqueTargets(br);- }- if (auto* br = expr->dynCast<BrOnExn>()) {- return getUniqueTargets(br);- }- return {};+ NameSet ret;+ operateOnScopeNameUses(expr, [&](Name& name) { ret.insert(name); });+ return ret; }+ // If we branch to 'from', change that to 'to' instead. inline bool replacePossibleTarget(Expression* branch, Name from, Name to) { bool worked = false;- if (auto* br = branch->dynCast<Break>()) {- if (br->name == from) {- br->name = to;- worked = true;- }- } else if (auto* sw = branch->dynCast<Switch>()) {- for (auto& target : sw->targets) {- if (target == from) {- target = to;- worked = true;- }- }- if (sw->default_ == from) {- sw->default_ = to;- worked = true;- }- } else if (auto* br = branch->dynCast<BrOnExn>()) {- if (br->name == from) {- br->name = to;+ operateOnScopeNameUses(branch, [&](Name& name) {+ if (name == from) {+ name = to; worked = true; }- } else {- WASM_UNREACHABLE("unexpected expression type");- }+ }); return worked; } -// returns the set of targets to which we branch that are-// outside of a node+// Returns the set of targets to which we branch that are+// outside of an expression. inline NameSet getExitingBranches(Expression* ast) {- struct Scanner : public PostWalker<Scanner> {+ struct Scanner+ : public PostWalker<Scanner, UnifiedExpressionVisitor<Scanner>> { NameSet targets; - void visitBreak(Break* curr) { targets.insert(curr->name); }- void visitSwitch(Switch* curr) {- for (auto target : curr->targets) {- targets.insert(target);- }- targets.insert(curr->default_);- }- void visitBrOnExn(BrOnExn* curr) { targets.insert(curr->name); }- void visitBlock(Block* curr) {- if (curr->name.is()) {- targets.erase(curr->name);- }- }- void visitLoop(Loop* curr) {- if (curr->name.is()) {- targets.erase(curr->name);- }+ void visitExpression(Expression* curr) {+ operateOnScopeNameDefs(curr, [&](Name& name) {+ if (name.is()) {+ targets.erase(name);+ }+ });+ operateOnScopeNameUses(curr, [&](Name& name) { targets.insert(name); }); } }; Scanner scanner;@@ -144,18 +160,16 @@ // returns the list of all branch targets in a node inline NameSet getBranchTargets(Expression* ast) {- struct Scanner : public PostWalker<Scanner> {+ struct Scanner+ : public PostWalker<Scanner, UnifiedExpressionVisitor<Scanner>> { NameSet targets; - void visitBlock(Block* curr) {- if (curr->name.is()) {- targets.insert(curr->name);- }- }- void visitLoop(Loop* curr) {- if (curr->name.is()) {- targets.insert(curr->name);- }+ void visitExpression(Expression* curr) {+ operateOnScopeNameDefs(curr, [&](Name& name) {+ if (name.is()) {+ targets.insert(name);+ }+ }); } }; Scanner scanner;@@ -166,52 +180,33 @@ // Finds if there are branches targeting a name. Note that since names are // unique in our IR, we just need to look for the name, and do not need // to analyze scoping.-struct BranchSeeker : public PostWalker<BranchSeeker> {+struct BranchSeeker+ : public PostWalker<BranchSeeker, UnifiedExpressionVisitor<BranchSeeker>> { Name target; Index found = 0;- Type valueType;+ // None indicates no value is sent.+ Type valueType = Type::none; BranchSeeker(Name target) : target(target) {} - void noteFound(Expression* value) {- noteFound(value ? value->type : Type::none);- }-- void noteFound(Type type) {+ void noteFound(Type newType) { found++;- if (found == 1) {- valueType = Type::unreachable;- }- if (type != Type::unreachable) {- valueType = type;- }- }-- void visitBreak(Break* curr) {- // check the break- if (curr->name == target) {- noteFound(curr->value);+ if (newType != Type::none) {+ if (found == 1) {+ valueType = newType;+ } else {+ valueType = Type::getLeastUpperBound(valueType, newType);+ } } } - void visitSwitch(Switch* curr) {- // check the switch- for (auto name : curr->targets) {+ void visitExpression(Expression* curr) {+ operateOnScopeNameUsesAndSentTypes(curr, [&](Name& name, Type type) { if (name == target) {- noteFound(curr->value);+ noteFound(type); }- }- if (curr->default_ == target) {- noteFound(curr->value);- }- }-- void visitBrOnExn(BrOnExn* curr) {- // check the br_on_exn- if (curr->name == target) {- noteFound(curr->sent);- }+ }); } static bool has(Expression* tree, Name target) {
binaryen/src/ir/cost.h view
@@ -24,7 +24,7 @@ // Measure the execution cost of an AST. Very handwave-ey -struct CostAnalyzer : public Visitor<CostAnalyzer, Index> {+struct CostAnalyzer : public OverriddenVisitor<CostAnalyzer, Index> { CostAnalyzer(Expression* ast) { cost = visit(ast); } Index cost;@@ -65,18 +65,38 @@ } return ret; }+ Index visitCallRef(CallRef* curr) {+ Index ret = 5 + visit(curr->target);+ for (auto* child : curr->operands) {+ ret += visit(child);+ }+ return ret;+ } Index visitLocalGet(LocalGet* curr) { return 0; }- Index visitLocalSet(LocalSet* curr) { return 1; }+ Index visitLocalSet(LocalSet* curr) { return 1 + visit(curr->value); } Index visitGlobalGet(GlobalGet* curr) { return 1; }- Index visitGlobalSet(GlobalSet* curr) { return 2; }+ Index visitGlobalSet(GlobalSet* curr) { return 2 + visit(curr->value); } Index visitLoad(Load* curr) { return 1 + visit(curr->ptr) + 10 * curr->isAtomic; } Index visitStore(Store* curr) { return 2 + visit(curr->ptr) + visit(curr->value) + 10 * curr->isAtomic; }- Index visitAtomicRMW(AtomicRMW* curr) { return 100; }- Index visitAtomicCmpxchg(AtomicCmpxchg* curr) { return 100; }+ Index visitAtomicRMW(AtomicRMW* curr) {+ return 100 + visit(curr->ptr) + visit(curr->value);+ }+ Index visitAtomicCmpxchg(AtomicCmpxchg* curr) {+ return 100 + visit(curr->ptr) + visit(curr->expected) ++ visit(curr->replacement);+ }+ Index visitAtomicWait(AtomicWait* curr) {+ return 100 + visit(curr->ptr) + visit(curr->expected) ++ visit(curr->timeout);+ }+ Index visitAtomicNotify(AtomicNotify* curr) {+ return 100 + visit(curr->ptr) + visit(curr->notifyCount);+ }+ Index visitAtomicFence(AtomicFence* curr) { return 100; } Index visitConst(Const* curr) { return 1; } Index visitUnary(Unary* curr) { Index ret = 0;@@ -157,6 +177,7 @@ case AnyTrueVecI8x16: case AllTrueVecI8x16: case BitmaskVecI8x16:+ case PopcntVecI8x16: case AbsVecI16x8: case NegVecI16x8: case AnyTrueVecI16x8:@@ -168,8 +189,7 @@ case AllTrueVecI32x4: case BitmaskVecI32x4: case NegVecI64x2:- case AnyTrueVecI64x2:- case AllTrueVecI64x2:+ case BitmaskVecI64x2: case AbsVecF32x4: case NegVecF32x4: case SqrtVecF32x4:@@ -184,6 +204,10 @@ case FloorVecF64x2: case TruncVecF64x2: case NearestVecF64x2:+ case ExtAddPairwiseSVecI8x16ToI16x8:+ case ExtAddPairwiseUVecI8x16ToI16x8:+ case ExtAddPairwiseSVecI16x8ToI32x4:+ case ExtAddPairwiseUVecI16x8ToI32x4: case TruncSatSVecF32x4ToVecI32x4: case TruncSatUVecF32x4ToVecI32x4: case TruncSatSVecF64x2ToVecI64x2:@@ -200,7 +224,12 @@ case WidenHighSVecI16x8ToVecI32x4: case WidenLowUVecI16x8ToVecI32x4: case WidenHighUVecI16x8ToVecI32x4:- return 1;+ case WidenLowSVecI32x4ToVecI64x2:+ case WidenHighSVecI32x4ToVecI64x2:+ case WidenLowUVecI32x4ToVecI64x2:+ case WidenHighUVecI32x4ToVecI64x2:+ ret = 1;+ break; case InvalidUnary: WASM_UNREACHABLE("invalid unary op"); }@@ -210,8 +239,6 @@ Index ret = 0; switch (curr->op) { case AddInt32:- ret = 1;- break; case SubInt32: ret = 1; break;@@ -219,44 +246,20 @@ ret = 2; break; case DivSInt32:- ret = 3;- break; case DivUInt32:- ret = 3;- break; case RemSInt32:- ret = 3;- break; case RemUInt32: ret = 3; break; case AndInt32:- ret = 1;- break; case OrInt32:- ret = 1;- break; case XorInt32:- ret = 1;- break; case ShlInt32:- ret = 1;- break; case ShrUInt32:- ret = 1;- break; case ShrSInt32:- ret = 1;- break; case RotLInt32:- ret = 1;- break; case RotRInt32:- ret = 1;- break; case AddInt64:- ret = 1;- break; case SubInt64: ret = 1; break;@@ -264,44 +267,22 @@ ret = 2; break; case DivSInt64:- ret = 3;- break; case DivUInt64:- ret = 3;- break; case RemSInt64:- ret = 3;- break; case RemUInt64: ret = 3; break; case AndInt64:- ret = 1;- break; case OrInt64:- ret = 1;- break; case XorInt64: ret = 1; break; case ShlInt64:- ret = 1;- break; case ShrUInt64:- ret = 1;- break; case ShrSInt64:- ret = 1;- break; case RotLInt64:- ret = 1;- break; case RotRInt64:- ret = 1;- break; case AddFloat32:- ret = 1;- break; case SubFloat32: ret = 1; break;@@ -312,17 +293,9 @@ ret = 3; break; case CopySignFloat32:- ret = 1;- break; case MinFloat32:- ret = 1;- break; case MaxFloat32:- ret = 1;- break; case AddFloat64:- ret = 1;- break; case SubFloat64: ret = 1; break;@@ -333,263 +306,92 @@ ret = 3; break; case CopySignFloat64:- ret = 1;- break; case MinFloat64:- ret = 1;- break; case MaxFloat64:- ret = 1;- break;+ case EqInt32:+ case NeInt32: case LtUInt32:- ret = 1;- break; case LtSInt32:- ret = 1;- break; case LeUInt32:- ret = 1;- break; case LeSInt32:- ret = 1;- break; case GtUInt32:- ret = 1;- break; case GtSInt32:- ret = 1;- break; case GeUInt32:- ret = 1;- break; case GeSInt32:- ret = 1;- break;+ case EqInt64:+ case NeInt64: case LtUInt64:- ret = 1;- break; case LtSInt64:- ret = 1;- break; case LeUInt64:- ret = 1;- break; case LeSInt64:- ret = 1;- break; case GtUInt64:- ret = 1;- break; case GtSInt64:- ret = 1;- break; case GeUInt64:- ret = 1;- break; case GeSInt64:- ret = 1;- break;+ case EqFloat32:+ case NeFloat32: case LtFloat32:- ret = 1;- break; case GtFloat32:- ret = 1;- break; case LeFloat32:- ret = 1;- break; case GeFloat32:- ret = 1;- break;+ case EqFloat64:+ case NeFloat64: case LtFloat64:- ret = 1;- break; case GtFloat64:- ret = 1;- break; case LeFloat64:- ret = 1;- break; case GeFloat64:- ret = 1;- break;- case EqInt32:- ret = 1;- break;- case NeInt32:- ret = 1;- break;- case EqInt64:- ret = 1;- break;- case NeInt64:- ret = 1;- break;- case EqFloat32:- ret = 1;- break;- case NeFloat32:- ret = 1;- break;- case EqFloat64:- ret = 1;- break;- case NeFloat64:- ret = 1;- break; case EqVecI8x16:- ret = 1;- break; case NeVecI8x16:- ret = 1;- break; case LtSVecI8x16:- ret = 1;- break; case LtUVecI8x16:- ret = 1;- break; case LeSVecI8x16:- ret = 1;- break; case LeUVecI8x16:- ret = 1;- break; case GtSVecI8x16:- ret = 1;- break; case GtUVecI8x16:- ret = 1;- break; case GeSVecI8x16:- ret = 1;- break; case GeUVecI8x16:- ret = 1;- break; case EqVecI16x8:- ret = 1;- break; case NeVecI16x8:- ret = 1;- break; case LtSVecI16x8:- ret = 1;- break; case LtUVecI16x8:- ret = 1;- break; case LeSVecI16x8:- ret = 1;- break; case LeUVecI16x8:- ret = 1;- break; case GtSVecI16x8:- ret = 1;- break; case GtUVecI16x8:- ret = 1;- break; case GeSVecI16x8:- ret = 1;- break; case GeUVecI16x8:- ret = 1;- break; case EqVecI32x4:- ret = 1;- break; case NeVecI32x4:- ret = 1;- break; case LtSVecI32x4:- ret = 1;- break; case LtUVecI32x4:- ret = 1;- break; case LeSVecI32x4:- ret = 1;- break; case LeUVecI32x4:- ret = 1;- break; case GtSVecI32x4:- ret = 1;- break; case GtUVecI32x4:- ret = 1;- break; case GeSVecI32x4:- ret = 1;- break; case GeUVecI32x4:- ret = 1;- break;+ case EqVecI64x2: case EqVecF32x4:- ret = 1;- break; case NeVecF32x4:- ret = 1;- break; case LtVecF32x4:- ret = 1;- break; case LeVecF32x4:- ret = 1;- break; case GtVecF32x4:- ret = 1;- break; case GeVecF32x4:- ret = 1;- break; case EqVecF64x2:- ret = 1;- break; case NeVecF64x2:- ret = 1;- break; case LtVecF64x2:- ret = 1;- break; case LeVecF64x2:- ret = 1;- break; case GtVecF64x2:- ret = 1;- break; case GeVecF64x2:- ret = 1;- break; case AndVec128:- ret = 1;- break; case OrVec128:- ret = 1;- break; case XorVec128:- ret = 1;- break; case AndNotVec128:- ret = 1;- break; case AddVecI8x16:- ret = 1;- break; case AddSatSVecI8x16:- ret = 1;- break; case AddSatUVecI8x16:- ret = 1;- break; case SubVecI8x16:- ret = 1;- break; case SubSatSVecI8x16:- ret = 1;- break; case SubSatUVecI8x16: ret = 1; break;@@ -597,35 +399,15 @@ ret = 2; break; case MinSVecI8x16:- ret = 1;- break; case MinUVecI8x16:- ret = 1;- break; case MaxSVecI8x16:- ret = 1;- break; case MaxUVecI8x16:- ret = 1;- break; case AvgrUVecI8x16:- ret = 1;- break; case AddVecI16x8:- ret = 1;- break; case AddSatSVecI16x8:- ret = 1;- break; case AddSatUVecI16x8:- ret = 1;- break; case SubVecI16x8:- ret = 1;- break; case SubSatSVecI16x8:- ret = 1;- break; case SubSatUVecI16x8: ret = 1; break;@@ -633,23 +415,16 @@ ret = 2; break; case MinSVecI16x8:- ret = 1;- break; case MinUVecI16x8:- ret = 1;- break; case MaxSVecI16x8:- ret = 1;- break; case MaxUVecI16x8:- ret = 1;- break; case AvgrUVecI16x8:- ret = 1;- break;+ case Q15MulrSatSVecI16x8:+ case ExtMulLowSVecI16x8:+ case ExtMulHighSVecI16x8:+ case ExtMulLowUVecI16x8:+ case ExtMulHighUVecI16x8: case AddVecI32x4:- ret = 1;- break; case SubVecI32x4: ret = 1; break;@@ -657,32 +432,22 @@ ret = 2; break; case MinSVecI32x4:- ret = 1;- break; case MinUVecI32x4:- ret = 1;- break; case MaxSVecI32x4:- ret = 1;- break; case MaxUVecI32x4:- ret = 1;- break; case DotSVecI16x8ToVecI32x4:- ret = 1;- break;+ case ExtMulLowSVecI32x4:+ case ExtMulHighSVecI32x4:+ case ExtMulLowUVecI32x4:+ case ExtMulHighUVecI32x4: case AddVecI64x2:- ret = 1;- break; case SubVecI64x2:- ret = 1;- break; case MulVecI64x2:- ret = 1;- break;+ case ExtMulLowSVecI64x2:+ case ExtMulHighSVecI64x2:+ case ExtMulLowUVecI64x2:+ case ExtMulHighUVecI64x2: case AddVecF32x4:- ret = 1;- break; case SubVecF32x4: ret = 1; break;@@ -693,20 +458,10 @@ ret = 3; break; case MinVecF32x4:- ret = 1;- break; case MaxVecF32x4:- ret = 1;- break; case PMinVecF32x4:- ret = 1;- break; case PMaxVecF32x4:- ret = 1;- break; case AddVecF64x2:- ret = 1;- break; case SubVecF64x2: ret = 1; break;@@ -717,29 +472,13 @@ ret = 3; break; case MinVecF64x2:- ret = 1;- break; case MaxVecF64x2:- ret = 1;- break; case PMinVecF64x2:- ret = 1;- break; case PMaxVecF64x2:- ret = 1;- break; case NarrowSVecI16x8ToVecI8x16:- ret = 1;- break; case NarrowUVecI16x8ToVecI8x16:- ret = 1;- break; case NarrowSVecI32x4ToVecI16x8:- ret = 1;- break; case NarrowUVecI32x4ToVecI16x8:- ret = 1;- break; case SwizzleVec8x16: ret = 1; break;@@ -749,13 +488,56 @@ return ret + visit(curr->left) + visit(curr->right); } Index visitSelect(Select* curr) {- return 2 + visit(curr->condition) + visit(curr->ifTrue) ++ return 1 + visit(curr->condition) + visit(curr->ifTrue) + visit(curr->ifFalse); } Index visitDrop(Drop* curr) { return visit(curr->value); } Index visitReturn(Return* curr) { return maybeVisit(curr->value); } Index visitMemorySize(MemorySize* curr) { return 1; }- Index visitMemoryGrow(MemoryGrow* curr) { return 100; }+ Index visitMemoryGrow(MemoryGrow* curr) { return 100 + visit(curr->delta); }+ Index visitMemoryInit(MemoryInit* curr) {+ return 6 + visit(curr->dest) + visit(curr->offset) + visit(curr->size);+ }+ Index visitMemoryCopy(MemoryCopy* curr) {+ return 6 + visit(curr->dest) + visit(curr->source) + visit(curr->size);+ }+ Index visitMemoryFill(MemoryFill* curr) {+ return 6 + visit(curr->dest) + visit(curr->value) + visit(curr->size);+ }+ Index visitSIMDLoad(SIMDLoad* curr) { return 1 + visit(curr->ptr); }+ Index visitSIMDLoadStoreLane(SIMDLoadStoreLane* curr) {+ return 1 + Index(curr->isStore()) + visit(curr->ptr) + visit(curr->vec);+ }+ Index visitSIMDReplace(SIMDReplace* curr) {+ return 2 + visit(curr->vec) + visit(curr->value);+ }+ Index visitSIMDExtract(SIMDExtract* curr) { return 1 + visit(curr->vec); }+ Index visitSIMDTernary(SIMDTernary* curr) {+ Index ret = 0;+ switch (curr->op) {+ case Bitselect:+ case SignSelectVec8x16:+ case SignSelectVec16x8:+ case SignSelectVec32x4:+ case SignSelectVec64x2:+ ret = 1;+ break;+ case QFMAF32x4:+ case QFMSF32x4:+ case QFMAF64x2:+ case QFMSF64x2:+ ret = 2;+ break;+ }+ return ret + visit(curr->a) + visit(curr->b) + visit(curr->c);+ }+ Index visitSIMDShift(SIMDShift* curr) {+ return 1 + visit(curr->vec) + visit(curr->shift);+ }+ Index visitSIMDShuffle(SIMDShuffle* curr) {+ return 1 + visit(curr->left) + visit(curr->right);+ }+ Index visitPrefetch(Prefetch* curr) { return 0 + visit(curr->ptr); } Index visitRefNull(RefNull* curr) { return 1; } Index visitRefIsNull(RefIsNull* curr) { return 1 + visit(curr->value); } Index visitRefFunc(RefFunc* curr) { return 1; }@@ -764,15 +546,86 @@ } Index visitTry(Try* curr) { // We assume no exception will be thrown in most cases- return visit(curr->body);+ return visit(curr->body) + maybeVisit(curr->catchBody); }- Index visitThrow(Throw* curr) { return 100; }- Index visitRethrow(Rethrow* curr) { return 100; }+ Index visitThrow(Throw* curr) {+ Index ret = 100;+ for (auto* child : curr->operands) {+ ret += visit(child);+ }+ return ret;+ }+ Index visitRethrow(Rethrow* curr) { return 100 + visit(curr->exnref); } Index visitBrOnExn(BrOnExn* curr) { return 1 + visit(curr->exnref) + curr->sent.size(); }+ Index visitTupleMake(TupleMake* curr) {+ Index ret = 0;+ for (auto* child : curr->operands) {+ ret += visit(child);+ }+ return ret;+ }+ Index visitTupleExtract(TupleExtract* curr) { return visit(curr->tuple); }+ Index visitPop(Pop* curr) { return 0; } Index visitNop(Nop* curr) { return 0; } Index visitUnreachable(Unreachable* curr) { return 0; }+ Index visitDataDrop(DataDrop* curr) { return 5; }+ Index visitI31New(I31New* curr) { return 3 + visit(curr->value); }+ Index visitI31Get(I31Get* curr) { return 2 + visit(curr->i31); }+ Index visitRefTest(RefTest* curr) {+ return 2 + nullCheckCost(curr->ref) + visit(curr->ref) + visit(curr->rtt);+ }+ Index visitRefCast(RefCast* curr) {+ return 2 + nullCheckCost(curr->ref) + visit(curr->ref) + visit(curr->rtt);+ }+ Index visitBrOnCast(BrOnCast* curr) {+ return 3 + nullCheckCost(curr->ref) + visit(curr->ref) + visit(curr->rtt);+ }+ Index visitRttCanon(RttCanon* curr) {+ // TODO: investigate actual RTT costs in VMs+ return 1;+ }+ Index visitRttSub(RttSub* curr) {+ // TODO: investigate actual RTT costs in VMs+ return 2 + visit(curr->parent);+ }+ Index visitStructNew(StructNew* curr) {+ // While allocation itself is almost free with generational GC, there is+ // at least some baseline cost, plus writing the fields. (If we use default+ // values for the fields, then it is possible they are all 0 and if so, we+ // can get that almost for free as well, so don't add anything there.)+ Index ret = 4 + visit(curr->rtt) + curr->operands.size();+ for (auto* child : curr->operands) {+ ret += visit(child);+ }+ return ret;+ }+ Index visitStructGet(StructGet* curr) {+ return 1 + nullCheckCost(curr->ref) + visit(curr->ref);+ }+ Index visitStructSet(StructSet* curr) {+ return 2 + nullCheckCost(curr->ref) + visit(curr->ref) + visit(curr->value);+ }+ Index visitArrayNew(ArrayNew* curr) {+ return 4 + visit(curr->rtt) + visit(curr->size) + visit(curr->init);+ }+ Index visitArrayGet(ArrayGet* curr) {+ return 1 + nullCheckCost(curr->ref) + visit(curr->ref) + visit(curr->index);+ }+ Index visitArraySet(ArraySet* curr) {+ return 2 + nullCheckCost(curr->ref) + visit(curr->ref) ++ visit(curr->index) + visit(curr->value);+ }+ Index visitArrayLen(ArrayLen* curr) {+ return 1 + nullCheckCost(curr->ref) + visit(curr->ref);+ }++private:+ Index nullCheckCost(Expression* ref) {+ // A nullable type requires a bounds check in most VMs.+ return ref->type.isNullable();+ } }; } // namespace wasm
binaryen/src/ir/effects.h view
@@ -25,15 +25,15 @@ // Look for side effects, including control flow // TODO: optimize -struct EffectAnalyzer- : public PostWalker<EffectAnalyzer, OverriddenVisitor<EffectAnalyzer>> {+class EffectAnalyzer {+public: EffectAnalyzer(const PassOptions& passOptions, FeatureSet features, Expression* ast = nullptr) : ignoreImplicitTraps(passOptions.ignoreImplicitTraps), debugInfo(passOptions.debugInfo), features(features) { if (ast) {- analyze(ast);+ walk(ast); } } @@ -41,12 +41,20 @@ bool debugInfo; FeatureSet features; - void analyze(Expression* ast) {- breakTargets.clear();- walk(ast);- assert(tryDepth == 0);+ // Walk an expression and all its children.+ void walk(Expression* ast) {+ pre();+ InternalAnalyzer(*this).walk(ast);+ post(); } + // Visit an expression, without any children.+ void visit(Expression* ast) {+ pre();+ InternalAnalyzer(*this).visit(ast);+ post();+ }+ // Core effect tracking // Definitely branches out of this expression, or does a return, etc.@@ -63,10 +71,14 @@ std::set<Name> globalsWritten; bool readsMemory = false; bool writesMemory = false;- // a load or div/rem, which may trap. we ignore trap differences, so it is ok- // to reorder these, but we can't remove them, as they count as side effects,- // and we can't move them in a way that would cause other noticeable (global)- // side effects+ // A trap, either from an unreachable instruction, or from an implicit trap+ // that we do not ignore (see below).+ // Note that we ignore trap differences, so it is ok to reorder traps with+ // each other, but it is not ok to remove them or reorder them with other+ // effects in a noticeable way.+ bool trap = false;+ // A trap from an instruction like a load or div/rem, which may trap on corner+ // cases. If we do not ignore implicit traps then these are counted as a trap. bool implicitTrap = false; // An atomic load/store/RMW/Cmpxchg or an operator that has a defined ordering // wrt atomics (e.g. memory.grow)@@ -82,38 +94,6 @@ // body. For example, (drop (exnref.pop)) should set this to true. bool danglingPop = false; - static void scan(EffectAnalyzer* self, Expression** currp) {- Expression* curr = *currp;- // We need to decrement try depth before catch starts, so handle it- // separately- if (curr->is<Try>()) {- self->pushTask(doVisitTry, currp);- self->pushTask(doEndCatch, currp);- self->pushTask(scan, &curr->cast<Try>()->catchBody);- self->pushTask(doStartCatch, currp);- self->pushTask(scan, &curr->cast<Try>()->body);- self->pushTask(doStartTry, currp);- return;- }- PostWalker<EffectAnalyzer, OverriddenVisitor<EffectAnalyzer>>::scan(self,- currp);- }-- static void doStartTry(EffectAnalyzer* self, Expression** currp) {- self->tryDepth++;- }-- static void doStartCatch(EffectAnalyzer* self, Expression** currp) {- assert(self->tryDepth > 0 && "try depth cannot be negative");- self->tryDepth--;- self->catchDepth++;- }-- static void doEndCatch(EffectAnalyzer* self, Expression** currp) {- assert(self->catchDepth > 0 && "catch depth cannot be negative");- self->catchDepth--;- }- // Helper functions to check for various effect types bool accessesLocal() const {@@ -134,21 +114,21 @@ return branchesOut || throws || hasExternalBreakTargets(); } - bool hasGlobalSideEffects() const {- return calls || globalsWritten.size() > 0 || writesMemory || isAtomic ||- throws;+ // Changes something in globally-stored state.+ bool writesGlobalState() const {+ return globalsWritten.size() || writesMemory || isAtomic || calls; }+ bool readsGlobalState() const {+ return globalsRead.size() || readsMemory || isAtomic || calls;+ }+ bool hasSideEffects() const {- return hasGlobalSideEffects() || localsWritten.size() > 0 ||- transfersControlFlow() || implicitTrap || danglingPop;+ return localsWritten.size() > 0 || danglingPop || writesGlobalState() ||+ trap || throws || transfersControlFlow(); } bool hasAnything() const { return hasSideEffects() || accessesLocal() || readsMemory ||- accessesGlobal() || isAtomic;- }-- bool noticesGlobalSideEffects() const {- return calls || readsMemory || isAtomic || globalsRead.size();+ accessesGlobal(); } // check if we break to anything external from ourselves@@ -160,7 +140,7 @@ if ((transfersControlFlow() && other.hasSideEffects()) || (other.transfersControlFlow() && hasSideEffects()) || ((writesMemory || calls) && other.accessesMemory()) ||- (accessesMemory() && (other.writesMemory || other.calls)) ||+ ((other.writesMemory || other.calls) && accessesMemory()) || (danglingPop || other.danglingPop)) { return true; }@@ -171,7 +151,7 @@ return true; } for (auto local : localsWritten) {- if (other.localsWritten.count(local) || other.localsRead.count(local)) {+ if (other.localsRead.count(local) || other.localsWritten.count(local)) { return true; } }@@ -180,13 +160,13 @@ return true; } }- if ((accessesGlobal() && other.calls) ||- (other.accessesGlobal() && calls)) {+ if ((other.calls && accessesGlobal()) ||+ (calls && other.accessesGlobal())) { return true; } for (auto global : globalsWritten) {- if (other.globalsWritten.count(global) ||- other.globalsRead.count(global)) {+ if (other.globalsRead.count(global) ||+ other.globalsWritten.count(global)) { return true; } }@@ -195,14 +175,21 @@ return true; } }- // we are ok to reorder implicit traps, but not conditionalize them- if ((implicitTrap && other.transfersControlFlow()) ||- (other.implicitTrap && transfersControlFlow())) {+ // We are ok to reorder implicit traps, but not conditionalize them.+ if ((trap && other.transfersControlFlow()) ||+ (other.trap && transfersControlFlow())) { return true; }- // we can't reorder an implicit trap in a way that alters global state- if ((implicitTrap && other.hasGlobalSideEffects()) ||- (other.implicitTrap && hasGlobalSideEffects())) {+ // Note that the above includes disallowing the reordering of a trap with an+ // exception (as an exception can transfer control flow inside the current+ // function, so transfersControlFlow would be true) - while we allow the+ // reordering of traps with each other, we do not reorder exceptions with+ // anything.+ assert(!((trap && other.throws) || (throws && other.trap)));+ // We can't reorder an implicit trap in a way that could alter what global+ // state is modified.+ if ((trap && other.writesGlobalState()) ||+ (other.trap && writesGlobalState())) { return true; } return false;@@ -213,6 +200,7 @@ calls = calls || other.calls; readsMemory = readsMemory || other.readsMemory; writesMemory = writesMemory || other.writesMemory;+ trap = trap || other.trap; implicitTrap = implicitTrap || other.implicitTrap; isAtomic = isAtomic || other.isAtomic; throws = throws || other.throws;@@ -255,167 +243,205 @@ std::set<Name> breakTargets; - void visitBlock(Block* curr) {- if (curr->name.is()) {- breakTargets.erase(curr->name); // these were internal breaks+private:+ struct InternalAnalyzer+ : public PostWalker<InternalAnalyzer, OverriddenVisitor<InternalAnalyzer>> {++ EffectAnalyzer& parent;++ InternalAnalyzer(EffectAnalyzer& parent) : parent(parent) {}++ static void scan(InternalAnalyzer* self, Expression** currp) {+ Expression* curr = *currp;+ // We need to decrement try depth before catch starts, so handle it+ // separately+ if (curr->is<Try>()) {+ self->pushTask(doVisitTry, currp);+ self->pushTask(doEndCatch, currp);+ self->pushTask(scan, &curr->cast<Try>()->catchBody);+ self->pushTask(doStartCatch, currp);+ self->pushTask(scan, &curr->cast<Try>()->body);+ self->pushTask(doStartTry, currp);+ return;+ }+ PostWalker<InternalAnalyzer, OverriddenVisitor<InternalAnalyzer>>::scan(+ self, currp); }- }- void visitIf(If* curr) {}- void visitLoop(Loop* curr) {- if (curr->name.is()) {- breakTargets.erase(curr->name); // these were internal breaks++ static void doStartTry(InternalAnalyzer* self, Expression** currp) {+ self->parent.tryDepth++; }- // if the loop is unreachable, then there is branching control flow:- // (1) if the body is unreachable because of a (return), uncaught (br)- // etc., then we already noted branching, so it is ok to mark it again- // (if we have *caught* (br)s, then they did not lead to the loop body- // being unreachable). (same logic applies to blocks)- // (2) if the loop is unreachable because it only has branches up to the- // loop top, but no way to get out, then it is an infinite loop, and we- // consider that a branching side effect (note how the same logic does- // not apply to blocks).- if (curr->type == Type::unreachable) {- branchesOut = true;++ static void doStartCatch(InternalAnalyzer* self, Expression** currp) {+ assert(self->parent.tryDepth > 0 && "try depth cannot be negative");+ self->parent.tryDepth--;+ self->parent.catchDepth++; }- }- void visitBreak(Break* curr) { breakTargets.insert(curr->name); }- void visitSwitch(Switch* curr) {- for (auto name : curr->targets) {- breakTargets.insert(name);++ static void doEndCatch(InternalAnalyzer* self, Expression** currp) {+ assert(self->parent.catchDepth > 0 && "catch depth cannot be negative");+ self->parent.catchDepth--; }- breakTargets.insert(curr->default_);- } - void visitCall(Call* curr) {- calls = true;- // When EH is enabled, any call can throw.- if (features.hasExceptionHandling() && tryDepth == 0) {- throws = true;+ void visitBlock(Block* curr) {+ if (curr->name.is()) {+ parent.breakTargets.erase(curr->name); // these were internal breaks+ } }- if (curr->isReturn) {- branchesOut = true;+ void visitIf(If* curr) {}+ void visitLoop(Loop* curr) {+ if (curr->name.is()) {+ parent.breakTargets.erase(curr->name); // these were internal breaks+ }+ // if the loop is unreachable, then there is branching control flow:+ // (1) if the body is unreachable because of a (return), uncaught (br)+ // etc., then we already noted branching, so it is ok to mark it+ // again (if we have *caught* (br)s, then they did not lead to the+ // loop body being unreachable). (same logic applies to blocks)+ // (2) if the loop is unreachable because it only has branches up to the+ // loop top, but no way to get out, then it is an infinite loop, and+ // we consider that a branching side effect (note how the same logic+ // does not apply to blocks).+ if (curr->type == Type::unreachable) {+ parent.branchesOut = true;+ } }- if (debugInfo) {- // debugInfo call imports must be preserved very strongly, do not- // move code around them- // FIXME: we could check if the call is to an import- branchesOut = true;+ void visitBreak(Break* curr) { parent.breakTargets.insert(curr->name); }+ void visitSwitch(Switch* curr) {+ for (auto name : curr->targets) {+ parent.breakTargets.insert(name);+ }+ parent.breakTargets.insert(curr->default_); }- }- void visitCallIndirect(CallIndirect* curr) {- calls = true;- if (features.hasExceptionHandling() && tryDepth == 0) {- throws = true;++ void visitCall(Call* curr) {+ parent.calls = true;+ // When EH is enabled, any call can throw.+ if (parent.features.hasExceptionHandling() && parent.tryDepth == 0) {+ parent.throws = true;+ }+ if (curr->isReturn) {+ parent.branchesOut = true;+ }+ if (parent.debugInfo) {+ // debugInfo call imports must be preserved very strongly, do not+ // move code around them+ // FIXME: we could check if the call is to an import+ parent.branchesOut = true;+ } }- if (curr->isReturn) {- branchesOut = true;+ void visitCallIndirect(CallIndirect* curr) {+ parent.calls = true;+ if (parent.features.hasExceptionHandling() && parent.tryDepth == 0) {+ parent.throws = true;+ }+ if (curr->isReturn) {+ parent.branchesOut = true;+ } }- }- void visitLocalGet(LocalGet* curr) { localsRead.insert(curr->index); }- void visitLocalSet(LocalSet* curr) { localsWritten.insert(curr->index); }- void visitGlobalGet(GlobalGet* curr) { globalsRead.insert(curr->name); }- void visitGlobalSet(GlobalSet* curr) { globalsWritten.insert(curr->name); }- void visitLoad(Load* curr) {- readsMemory = true;- isAtomic |= curr->isAtomic;- if (!ignoreImplicitTraps) {- implicitTrap = true;+ void visitLocalGet(LocalGet* curr) {+ parent.localsRead.insert(curr->index); }- }- void visitStore(Store* curr) {- writesMemory = true;- isAtomic |= curr->isAtomic;- if (!ignoreImplicitTraps) {- implicitTrap = true;+ void visitLocalSet(LocalSet* curr) {+ parent.localsWritten.insert(curr->index); }- }- void visitAtomicRMW(AtomicRMW* curr) {- readsMemory = true;- writesMemory = true;- isAtomic = true;- if (!ignoreImplicitTraps) {- implicitTrap = true;+ void visitGlobalGet(GlobalGet* curr) {+ parent.globalsRead.insert(curr->name); }- }- void visitAtomicCmpxchg(AtomicCmpxchg* curr) {- readsMemory = true;- writesMemory = true;- isAtomic = true;- if (!ignoreImplicitTraps) {- implicitTrap = true;+ void visitGlobalSet(GlobalSet* curr) {+ parent.globalsWritten.insert(curr->name); }- }- void visitAtomicWait(AtomicWait* curr) {- readsMemory = true;- // AtomicWait doesn't strictly write memory, but it does modify the waiters- // list associated with the specified address, which we can think of as a- // write.- writesMemory = true;- isAtomic = true;- if (!ignoreImplicitTraps) {- implicitTrap = true;+ void visitLoad(Load* curr) {+ parent.readsMemory = true;+ parent.isAtomic |= curr->isAtomic;+ parent.implicitTrap = true; }- }- void visitAtomicNotify(AtomicNotify* curr) {- // AtomicNotify doesn't strictly write memory, but it does modify the- // waiters list associated with the specified address, which we can think of- // as a write.- readsMemory = true;- writesMemory = true;- isAtomic = true;- if (!ignoreImplicitTraps) {- implicitTrap = true;+ void visitStore(Store* curr) {+ parent.writesMemory = true;+ parent.isAtomic |= curr->isAtomic;+ parent.implicitTrap = true; }- }- void visitAtomicFence(AtomicFence* curr) {- // AtomicFence should not be reordered with any memory operations, so we set- // these to true.- readsMemory = true;- writesMemory = true;- isAtomic = true;- }- void visitSIMDExtract(SIMDExtract* curr) {}- void visitSIMDReplace(SIMDReplace* curr) {}- void visitSIMDShuffle(SIMDShuffle* curr) {}- void visitSIMDTernary(SIMDTernary* curr) {}- void visitSIMDShift(SIMDShift* curr) {}- void visitSIMDLoad(SIMDLoad* curr) {- readsMemory = true;- if (!ignoreImplicitTraps) {- implicitTrap = true;+ void visitAtomicRMW(AtomicRMW* curr) {+ parent.readsMemory = true;+ parent.writesMemory = true;+ parent.isAtomic = true;+ parent.implicitTrap = true; }- }- void visitMemoryInit(MemoryInit* curr) {- writesMemory = true;- if (!ignoreImplicitTraps) {- implicitTrap = true;+ void visitAtomicCmpxchg(AtomicCmpxchg* curr) {+ parent.readsMemory = true;+ parent.writesMemory = true;+ parent.isAtomic = true;+ parent.implicitTrap = true; }- }- void visitDataDrop(DataDrop* curr) {- // data.drop does not actually write memory, but it does alter the size of- // a segment, which can be noticeable later by memory.init, so we need to- // mark it as having a global side effect of some kind.- writesMemory = true;- if (!ignoreImplicitTraps) {- implicitTrap = true;+ void visitAtomicWait(AtomicWait* curr) {+ parent.readsMemory = true;+ // AtomicWait doesn't strictly write memory, but it does modify the+ // waiters list associated with the specified address, which we can think+ // of as a write.+ parent.writesMemory = true;+ parent.isAtomic = true;+ parent.implicitTrap = true; }- }- void visitMemoryCopy(MemoryCopy* curr) {- readsMemory = true;- writesMemory = true;- if (!ignoreImplicitTraps) {- implicitTrap = true;+ void visitAtomicNotify(AtomicNotify* curr) {+ // AtomicNotify doesn't strictly write memory, but it does modify the+ // waiters list associated with the specified address, which we can think+ // of as a write.+ parent.readsMemory = true;+ parent.writesMemory = true;+ parent.isAtomic = true;+ parent.implicitTrap = true; }- }- void visitMemoryFill(MemoryFill* curr) {- writesMemory = true;- if (!ignoreImplicitTraps) {- implicitTrap = true;+ void visitAtomicFence(AtomicFence* curr) {+ // AtomicFence should not be reordered with any memory operations, so we+ // set these to true.+ parent.readsMemory = true;+ parent.writesMemory = true;+ parent.isAtomic = true; }- }- void visitConst(Const* curr) {}- void visitUnary(Unary* curr) {- if (!ignoreImplicitTraps) {+ void visitSIMDExtract(SIMDExtract* curr) {}+ void visitSIMDReplace(SIMDReplace* curr) {}+ void visitSIMDShuffle(SIMDShuffle* curr) {}+ void visitSIMDTernary(SIMDTernary* curr) {}+ void visitSIMDShift(SIMDShift* curr) {}+ void visitSIMDLoad(SIMDLoad* curr) {+ parent.readsMemory = true;+ parent.implicitTrap = true;+ }+ void visitSIMDLoadStoreLane(SIMDLoadStoreLane* curr) {+ if (curr->isLoad()) {+ parent.readsMemory = true;+ } else {+ parent.writesMemory = true;+ }+ parent.implicitTrap = true;+ }+ void visitPrefetch(Prefetch* curr) {+ // Do not reorder with respect to other memory ops+ parent.writesMemory = true;+ parent.readsMemory = true;+ }+ void visitMemoryInit(MemoryInit* curr) {+ parent.writesMemory = true;+ parent.implicitTrap = true;+ }+ void visitDataDrop(DataDrop* curr) {+ // data.drop does not actually write memory, but it does alter the size of+ // a segment, which can be noticeable later by memory.init, so we need to+ // mark it as having a global side effect of some kind.+ parent.writesMemory = true;+ parent.implicitTrap = true;+ }+ void visitMemoryCopy(MemoryCopy* curr) {+ parent.readsMemory = true;+ parent.writesMemory = true;+ parent.implicitTrap = true;+ }+ void visitMemoryFill(MemoryFill* curr) {+ parent.writesMemory = true;+ parent.implicitTrap = true;+ }+ void visitConst(Const* curr) {}+ void visitUnary(Unary* curr) { switch (curr->op) { case TruncSFloat32ToInt32: case TruncSFloat32ToInt64:@@ -425,16 +451,13 @@ case TruncSFloat64ToInt64: case TruncUFloat64ToInt32: case TruncUFloat64ToInt64: {- implicitTrap = true;+ parent.implicitTrap = true; break; }- default: {- }+ default: {} } }- }- void visitBinary(Binary* curr) {- if (!ignoreImplicitTraps) {+ void visitBinary(Binary* curr) { switch (curr->op) { case DivSInt32: case DivUInt32:@@ -444,100 +467,130 @@ case DivUInt64: case RemSInt64: case RemUInt64: {- implicitTrap = true;+ // div and rem may contain implicit trap only if RHS is+ // non-constant or constant which equal zero or -1 for+ // signed divisions. Reminder traps only with zero+ // divider.+ if (auto* c = curr->right->dynCast<Const>()) {+ if (c->value.isZero()) {+ parent.implicitTrap = true;+ } else if ((curr->op == DivSInt32 || curr->op == DivSInt64) &&+ c->value.getInteger() == -1LL) {+ parent.implicitTrap = true;+ }+ } else {+ parent.implicitTrap = true;+ } break; }- default: {- }+ default: {} } }- }- void visitSelect(Select* curr) {}- void visitDrop(Drop* curr) {}- void visitReturn(Return* curr) { branchesOut = true; }- void visitMemorySize(MemorySize* curr) {- // memory.size accesses the size of the memory, and thus can be modeled as- // reading memory- readsMemory = true;- // Atomics are sequentially consistent with memory.size.- isAtomic = true;- }- void visitMemoryGrow(MemoryGrow* curr) {- calls = true;- // memory.grow technically does a read-modify-write operation on the memory- // size in the successful case, modifying the set of valid addresses, and- // just a read operation in the failure case- readsMemory = true;- writesMemory = true;- // Atomics are also sequentially consistent with memory.grow.- isAtomic = true;- }- void visitRefNull(RefNull* curr) {}- void visitRefIsNull(RefIsNull* curr) {}- void visitRefFunc(RefFunc* curr) {}- void visitRefEq(RefEq* curr) {}- void visitTry(Try* curr) {}- void visitThrow(Throw* curr) {- if (tryDepth == 0) {- throws = true;+ void visitSelect(Select* curr) {}+ void visitDrop(Drop* curr) {}+ void visitReturn(Return* curr) { parent.branchesOut = true; }+ void visitMemorySize(MemorySize* curr) {+ // memory.size accesses the size of the memory, and thus can be modeled as+ // reading memory+ parent.readsMemory = true;+ // Atomics are sequentially consistent with memory.size.+ parent.isAtomic = true; }- }- void visitRethrow(Rethrow* curr) {- if (tryDepth == 0) {- throws = true;+ void visitMemoryGrow(MemoryGrow* curr) {+ parent.calls = true;+ // memory.grow technically does a read-modify-write operation on the+ // memory size in the successful case, modifying the set of valid+ // addresses, and just a read operation in the failure case+ parent.readsMemory = true;+ parent.writesMemory = true;+ // Atomics are also sequentially consistent with memory.grow.+ parent.isAtomic = true; }- if (!ignoreImplicitTraps) { // rethrow traps when the arg is null- implicitTrap = true;+ void visitRefNull(RefNull* curr) {}+ void visitRefIsNull(RefIsNull* curr) {}+ void visitRefFunc(RefFunc* curr) {}+ void visitRefEq(RefEq* curr) {}+ void visitTry(Try* curr) {}+ void visitThrow(Throw* curr) {+ if (parent.tryDepth == 0) {+ parent.throws = true;+ } }- }- void visitBrOnExn(BrOnExn* curr) {- breakTargets.insert(curr->name);- if (!ignoreImplicitTraps) { // br_on_exn traps when the arg is null- implicitTrap = true;+ void visitRethrow(Rethrow* curr) {+ if (parent.tryDepth == 0) {+ parent.throws = true;+ }+ // traps when the arg is null+ parent.implicitTrap = true; }- }- void visitNop(Nop* curr) {}- void visitUnreachable(Unreachable* curr) { branchesOut = true; }- void visitPop(Pop* curr) {- if (catchDepth == 0) {- danglingPop = true;+ void visitBrOnExn(BrOnExn* curr) {+ parent.breakTargets.insert(curr->name);+ // traps when the arg is null+ parent.implicitTrap = true; }- }- void visitTupleMake(TupleMake* curr) {}- void visitTupleExtract(TupleExtract* curr) {}- void visitI31New(I31New* curr) {}- void visitI31Get(I31Get* curr) {}- void visitRefTest(RefTest* curr) { WASM_UNREACHABLE("TODO (gc): ref.test"); }- void visitRefCast(RefCast* curr) { WASM_UNREACHABLE("TODO (gc): ref.cast"); }- void visitBrOnCast(BrOnCast* curr) {- WASM_UNREACHABLE("TODO (gc): br_on_cast");- }- void visitRttCanon(RttCanon* curr) {- WASM_UNREACHABLE("TODO (gc): rtt.canon");- }- void visitRttSub(RttSub* curr) { WASM_UNREACHABLE("TODO (gc): rtt.sub"); }- void visitStructNew(StructNew* curr) {- WASM_UNREACHABLE("TODO (gc): struct.new");- }- void visitStructGet(StructGet* curr) {- WASM_UNREACHABLE("TODO (gc): struct.get");- }- void visitStructSet(StructSet* curr) {- WASM_UNREACHABLE("TODO (gc): struct.set");- }- void visitArrayNew(ArrayNew* curr) {- WASM_UNREACHABLE("TODO (gc): array.new");- }- void visitArrayGet(ArrayGet* curr) {- WASM_UNREACHABLE("TODO (gc): array.get");- }- void visitArraySet(ArraySet* curr) {- WASM_UNREACHABLE("TODO (gc): array.set");- }- void visitArrayLen(ArrayLen* curr) {- WASM_UNREACHABLE("TODO (gc): array.len");- }+ void visitNop(Nop* curr) {}+ void visitUnreachable(Unreachable* curr) { parent.trap = true; }+ void visitPop(Pop* curr) {+ if (parent.catchDepth == 0) {+ parent.danglingPop = true;+ }+ }+ void visitTupleMake(TupleMake* curr) {}+ void visitTupleExtract(TupleExtract* curr) {}+ void visitI31New(I31New* curr) {}+ void visitI31Get(I31Get* curr) {}+ void visitCallRef(CallRef* curr) {+ parent.calls = true;+ if (parent.features.hasExceptionHandling() && parent.tryDepth == 0) {+ parent.throws = true;+ }+ if (curr->isReturn) {+ parent.branchesOut = true;+ }+ // traps when the arg is null+ parent.implicitTrap = true;+ }+ void visitRefTest(RefTest* curr) {}+ void visitRefCast(RefCast* curr) {+ // Traps if the ref is not null and it has an invalid rtt.+ parent.implicitTrap = true;+ }+ void visitBrOnCast(BrOnCast* curr) {+ parent.breakTargets.insert(curr->name);+ }+ void visitRttCanon(RttCanon* curr) {}+ void visitRttSub(RttSub* curr) {}+ void visitStructNew(StructNew* curr) {}+ void visitStructGet(StructGet* curr) {+ // traps when the arg is null+ if (curr->ref->type.isNullable()) {+ parent.implicitTrap = true;+ }+ }+ void visitStructSet(StructSet* curr) {+ // traps when the arg is null+ if (curr->ref->type.isNullable()) {+ parent.implicitTrap = true;+ }+ }+ void visitArrayNew(ArrayNew* curr) {}+ void visitArrayGet(ArrayGet* curr) {+ // traps when the arg is null or the index out of bounds+ parent.implicitTrap = true;+ }+ void visitArraySet(ArraySet* curr) {+ // traps when the arg is null or the index out of bounds+ parent.implicitTrap = true;+ }+ void visitArrayLen(ArrayLen* curr) {+ // traps when the arg is null+ if (curr->ref->type.isNullable()) {+ parent.implicitTrap = true;+ }+ }+ }; +public: // Helpers static bool canReorder(const PassOptions& passOptions,@@ -611,6 +664,19 @@ void ignoreBranches() { branchesOut = false; breakTargets.clear();+ }++private:+ void pre() { breakTargets.clear(); }++ void post() {+ assert(tryDepth == 0);++ if (ignoreImplicitTraps) {+ implicitTrap = false;+ } else if (implicitTrap) {+ trap = true;+ } } };
binaryen/src/ir/features.h view
@@ -57,8 +57,6 @@ case AnyTrueVecI32x4: case AllTrueVecI32x4: case NegVecI64x2:- case AnyTrueVecI64x2:- case AllTrueVecI64x2: case AbsVecF32x4: case NegVecF32x4: case SqrtVecF32x4:
binaryen/src/ir/global-utils.h view
@@ -56,13 +56,14 @@ inline bool canInitializeGlobal(const Expression* curr) { if (auto* tuple = curr->dynCast<TupleMake>()) { for (auto* op : tuple->operands) {- if (!Properties::isSingleConstantExpression(op) && !op->is<GlobalGet>()) {+ if (!canInitializeGlobal(op)) { return false; } } return true; }- return Properties::isSingleConstantExpression(curr) || curr->is<GlobalGet>();+ return Properties::isSingleConstantExpression(curr) ||+ curr->is<GlobalGet>() || curr->is<RttCanon>() || curr->is<RttSub>(); } } // namespace GlobalUtils
+ binaryen/src/ir/module-splitting.cpp view
@@ -0,0 +1,595 @@+/*+ * Copyright 2020 WebAssembly Community Group participants+ *+ * Licensed under the Apache License, Version 2.0 (the "License");+ * you may not use this file except in compliance with the License.+ * You may obtain a copy of the License at+ *+ * http://www.apache.org/licenses/LICENSE-2.0+ *+ * Unless required by applicable law or agreed to in writing, software+ * distributed under the License is distributed on an "AS IS" BASIS,+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+ * See the License for the specific language governing permissions and+ * limitations under the License.+ */++// The process of module splitting involves these steps:+//+// 1. Create the new secondary module.+//+// 2. Export globals, events, tables, and memories from the primary module and+// import them in the secondary module.+//+// 3. Move the deferred functions from the primary to the secondary module.+//+// 4. For any secondary function exported from the primary module, export in+// its place a trampoline function that makes an indirect call to its+// placeholder function (and eventually to the original secondary+// function), allocating a new table slot for the placeholder if necessary.+//+// 5. Rewrite direct calls from primary functions to secondary functions to be+// indirect calls to their placeholder functions (and eventually to their+// original secondary functions), allocating new table slots for the+// placeholders if necessary.+//+// 6. For each primary function directly called from a secondary function,+// export the primary function if it is not already exported and import it+// into the secondary module.+//+// 7. Replace all references to secondary functions in the primary module's+// table segments with references to imported placeholder functions.+//+// 8. Create new active table segments in the secondary module that will+// replace all the placeholder function references in the table with+// references to their corresponding secondary functions upon+// instantiation.+//+// Functions can be used or referenced three ways in a WebAssembly module: they+// can be exported, called, or placed in a table. The above procedure introduces+// a layer of indirection to each of those mechanisms that removes all+// references to secondary functions from the primary module but restores the+// original program's semantics once the secondary module is instantiated. As+// more mechanisms that reference functions are added in the future, such as+// ref.func instructions, they will have to be modified to use a similar layer+// of indirection.+//+// The code as currently written makes a few assumptions about the module that+// is being split:+//+// 1. It assumes that mutable-globals is allowed. This could be worked around+// by introducing wrapper functions for globals and rewriting secondary+// code that accesses them, but now that mutable-globals is shipped on all+// browsers, hopefully that extra complexity won't be necessary.+//+// 2. It assumes that either all table segment offsets are constants or there+// is exactly one segment that may have a non-constant offset. It also+// assumes that all segments are active segments (although Binaryen does+// not yet support passive table segments anyway).+//+// 3. It assumes that each function appears in the table at most once. This+// isn't necessarily true in general or even for LLVM output after function+// deduplication. Relaxing this assumption would just require slightly more+// complex code, so it is a good candidate for a follow up PR.++#include "ir/module-splitting.h"+#include "ir/manipulation.h"+#include "ir/module-utils.h"+#include "ir/names.h"+#include "pass.h"+#include "wasm-builder.h"+#include "wasm.h"++namespace std {++// Used in ModuleSplitter::shareImportableItems+template<> struct hash<pair<wasm::ExternalKind, wasm::Name>> {+ size_t operator()(const pair<wasm::ExternalKind, wasm::Name>& p) const {+ auto digest = wasm::hash(p.first);+ wasm::rehash(digest, p.second);+ return digest;+ }+};++} // namespace std++namespace wasm {++namespace ModuleSplitting {++namespace {++template<class F> void forEachElement(Table& table, F f) {+ for (auto& segment : table.segments) {+ Name base = "";+ Index offset = 0;+ if (auto* c = segment.offset->dynCast<Const>()) {+ offset = c->value.geti32();+ } else if (auto* g = segment.offset->dynCast<GlobalGet>()) {+ base = g->name;+ }+ for (size_t i = 0; i < segment.data.size(); ++i) {+ f(base, offset + i, segment.data[i]);+ }+ }+}++struct TableSlotManager {+ struct Slot {+ // If `global` is empty, then this slot is at a statically known index.+ Name global;+ Index index = 0;++ // Generate code to compute the index of this table slot+ Expression* makeExpr(Module& module);+ };+ Module& module;+ Table& table;+ Table::Segment* activeSegment = nullptr;+ Slot activeBase;+ std::map<Name, Slot> funcIndices;++ TableSlotManager(Module& module);++ // Returns the table index for `func`, allocating a new index if necessary.+ Slot getSlot(Name func);+ void addSlot(Name func, Slot slot);+};++Expression* TableSlotManager::Slot::makeExpr(Module& module) {+ Builder builder(module);+ auto makeIndex = [&]() { return builder.makeConst(int32_t(index)); };+ if (global.size()) {+ Expression* getBase = builder.makeGlobalGet(global, Type::i32);+ return index == 0 ? getBase+ : builder.makeBinary(AddInt32, getBase, makeIndex());+ } else {+ return makeIndex();+ }+}++void TableSlotManager::addSlot(Name func, Slot slot) {+ auto it = funcIndices.insert(std::make_pair(func, slot));+ assert(it.second && "Function already has multiple table slots");+}++TableSlotManager::TableSlotManager(Module& module)+ : module(module), table(module.table) {++ // If there is exactly one table segment and that segment has a non-constant+ // offset, append new items to the end of that segment. In all other cases,+ // append new items at constant offsets after all existing items at constant+ // offsets.+ if (table.segments.size() == 1 && !table.segments[0].offset->is<Const>()) {+ assert(table.segments[0].offset->is<GlobalGet>() &&+ "Unexpected initializer instruction");+ activeSegment = &table.segments[0];+ activeBase = {table.segments[0].offset->cast<GlobalGet>()->name, 0};+ } else {+ // Finds the segment with the highest occupied table slot so that new items+ // can be inserted contiguously at the end of it without accidentally+ // overwriting any other items. TODO: be more clever about filling gaps in+ // the table, if that is ever useful.+ Index maxIndex = 0;+ for (auto& segment : table.segments) {+ assert(segment.offset->is<Const>() &&+ "Unexpected non-const segment offset with multiple segments");+ Index segmentBase = segment.offset->cast<Const>()->value.geti32();+ if (segmentBase + segment.data.size() >= maxIndex) {+ maxIndex = segmentBase + segment.data.size();+ activeSegment = &segment;+ activeBase = {"", segmentBase};+ }+ }+ }+ // Initialize funcIndices with the functions already in the table.+ forEachElement(table, [&](Name base, Index offset, Name func) {+ addSlot(func, {base, offset});+ });+}++TableSlotManager::Slot TableSlotManager::getSlot(Name func) {+ auto slotIt = funcIndices.find(func);+ if (slotIt != funcIndices.end()) {+ return slotIt->second;+ }++ // If there are no segments yet, allocate one.+ if (activeSegment == nullptr) {+ table.exists = true;+ assert(table.segments.size() == 0);+ table.segments.emplace_back(Builder(module).makeConst(int32_t(0)));+ activeSegment = &table.segments.back();+ }++ Slot newSlot = {activeBase.global,+ activeBase.index + Index(activeSegment->data.size())};+ activeSegment->data.push_back(func);+ addSlot(func, newSlot);+ if (table.initial <= newSlot.index) {+ table.initial = newSlot.index + 1;+ }+ if (table.max <= newSlot.index) {+ table.max = newSlot.index + 1;+ }+ return newSlot;+}++struct ModuleSplitter {+ const Config& config;+ std::unique_ptr<Module> secondaryPtr;++ Module& primary;+ Module& secondary;++ const std::pair<std::set<Name>, std::set<Name>> classifiedFuncs;+ const std::set<Name>& primaryFuncs;+ const std::set<Name>& secondaryFuncs;++ TableSlotManager tableManager;++ // Map from internal function names to (one of) their corresponding export+ // names.+ std::map<Name, Name> exportedPrimaryFuncs;++ // Initialization helpers+ static std::unique_ptr<Module> initSecondary(const Module& primary);+ static std::pair<std::set<Name>, std::set<Name>>+ classifyFunctions(const Module& primary, const Config& config);+ static std::map<Name, Name> initExportedPrimaryFuncs(const Module& primary);++ // Other helpers+ void exportImportFunction(Name func);++ // Main splitting steps+ void moveSecondaryFunctions();+ void thunkExportedSecondaryFunctions();+ void indirectCallsToSecondaryFunctions();+ void exportImportCalledPrimaryFunctions();+ void setupTablePatching();+ void shareImportableItems();++ ModuleSplitter(Module& primary, const Config& config)+ : config(config), secondaryPtr(initSecondary(primary)), primary(primary),+ secondary(*secondaryPtr),+ classifiedFuncs(classifyFunctions(primary, config)),+ primaryFuncs(classifiedFuncs.first),+ secondaryFuncs(classifiedFuncs.second), tableManager(primary),+ exportedPrimaryFuncs(initExportedPrimaryFuncs(primary)) {+ moveSecondaryFunctions();+ thunkExportedSecondaryFunctions();+ indirectCallsToSecondaryFunctions();+ exportImportCalledPrimaryFunctions();+ setupTablePatching();+ shareImportableItems();+ }+};++std::unique_ptr<Module> ModuleSplitter::initSecondary(const Module& primary) {+ // Create the secondary module and copy trivial properties.+ auto secondary = std::make_unique<Module>();+ secondary->features = primary.features;+ secondary->hasFeaturesSection = primary.hasFeaturesSection;+ return secondary;+}++std::pair<std::set<Name>, std::set<Name>>+ModuleSplitter::classifyFunctions(const Module& primary, const Config& config) {+ std::set<Name> primaryFuncs, secondaryFuncs;+ for (auto& func : primary.functions) {+ if (func->imported() || config.primaryFuncs.count(func->name)) {+ primaryFuncs.insert(func->name);+ } else {+ assert(func->name != primary.start && "The start function must be kept");+ secondaryFuncs.insert(func->name);+ }+ }+ return std::make_pair(primaryFuncs, secondaryFuncs);+}++std::map<Name, Name>+ModuleSplitter::initExportedPrimaryFuncs(const Module& primary) {+ std::map<Name, Name> functionExportNames;+ for (auto& ex : primary.exports) {+ if (ex->kind == ExternalKind::Function) {+ functionExportNames[ex->value] = ex->name;+ }+ }+ return functionExportNames;+}++void ModuleSplitter::exportImportFunction(Name funcName) {+ Name exportName;+ // If the function is already exported, use the existing export name.+ // Otherwise, create a new export for it.+ auto exportIt = exportedPrimaryFuncs.find(funcName);+ if (exportIt != exportedPrimaryFuncs.end()) {+ exportName = exportIt->second;+ } else {+ exportName = Names::getValidExportName(+ primary, config.newExportPrefix + funcName.c_str());+ primary.addExport(+ Builder::makeExport(exportName, funcName, ExternalKind::Function));+ exportedPrimaryFuncs[funcName] = exportName;+ }+ // Import the function if it is not already imported into the secondary+ // module.+ if (secondary.getFunctionOrNull(funcName) == nullptr) {+ auto func =+ Builder::makeFunction(funcName, primary.getFunction(funcName)->sig, {});+ func->module = config.importNamespace;+ func->base = exportName;+ secondary.addFunction(std::move(func));+ }+}++void ModuleSplitter::moveSecondaryFunctions() {+ // Move the specified functions from the primary to the secondary module.+ for (auto funcName : secondaryFuncs) {+ auto* func = primary.getFunction(funcName);+ ModuleUtils::copyFunction(func, secondary);+ primary.removeFunction(funcName);+ }+}++void ModuleSplitter::thunkExportedSecondaryFunctions() {+ // Update exports of secondary functions in the primary module to export+ // wrapper functions that indirectly call the secondary functions. We are+ // adding secondary function names to the primary table here, but they will be+ // replaced with placeholder functions later along with any references to+ // secondary functions that were already in the table.+ Builder builder(primary);+ for (auto& ex : primary.exports) {+ if (ex->kind != ExternalKind::Function ||+ !secondaryFuncs.count(ex->value)) {+ continue;+ }+ Name secondaryFunc = ex->value;+ if (primary.getFunctionOrNull(secondaryFunc)) {+ // We've already created a thunk for this function+ continue;+ }+ auto tableSlot = tableManager.getSlot(secondaryFunc);+ auto func = std::make_unique<Function>();++ func->name = secondaryFunc;+ func->sig = secondary.getFunction(secondaryFunc)->sig;+ std::vector<Expression*> args;+ for (size_t i = 0, size = func->sig.params.size(); i < size; ++i) {+ args.push_back(builder.makeLocalGet(i, func->sig.params[i]));+ }+ func->body =+ builder.makeCallIndirect(tableSlot.makeExpr(primary), args, func->sig);+ primary.addFunction(std::move(func));+ }+}++void ModuleSplitter::indirectCallsToSecondaryFunctions() {+ // Update direct calls of secondary functions to be indirect calls of their+ // corresponding table indices instead.+ struct CallIndirector : public WalkerPass<PostWalker<CallIndirector>> {+ ModuleSplitter& parent;+ Builder builder;+ CallIndirector(ModuleSplitter& parent)+ : parent(parent), builder(parent.primary) {}+ void visitCall(Call* curr) {+ if (!parent.secondaryFuncs.count(curr->target)) {+ return;+ }+ replaceCurrent(builder.makeCallIndirect(+ parent.tableManager.getSlot(curr->target).makeExpr(parent.primary),+ curr->operands,+ parent.secondary.getFunction(curr->target)->sig,+ curr->isReturn));+ }+ void visitRefFunc(RefFunc* curr) {+ assert(false && "TODO: handle ref.func as well");+ }+ };+ PassRunner runner(&primary);+ CallIndirector(*this).run(&runner, &primary);+}++void ModuleSplitter::exportImportCalledPrimaryFunctions() {+ // Find primary functions called in the secondary module.+ ModuleUtils::ParallelFunctionAnalysis<std::vector<Name>> callCollector(+ secondary, [&](Function* func, std::vector<Name>& calledPrimaryFuncs) {+ struct CallCollector : PostWalker<CallCollector> {+ const std::set<Name>& primaryFuncs;+ std::vector<Name>& calledPrimaryFuncs;+ CallCollector(const std::set<Name>& primaryFuncs,+ std::vector<Name>& calledPrimaryFuncs)+ : primaryFuncs(primaryFuncs), calledPrimaryFuncs(calledPrimaryFuncs) {+ }+ void visitCall(Call* curr) {+ if (primaryFuncs.count(curr->target)) {+ calledPrimaryFuncs.push_back(curr->target);+ }+ }+ void visitRefFunc(RefFunc* curr) {+ assert(false && "TODO: handle ref.func as well");+ }+ };+ CallCollector(primaryFuncs, calledPrimaryFuncs).walkFunction(func);+ });+ std::set<Name> calledPrimaryFuncs;+ for (auto& entry : callCollector.map) {+ auto& calledFuncs = entry.second;+ calledPrimaryFuncs.insert(calledFuncs.begin(), calledFuncs.end());+ }++ // Ensure each called primary function is exported and imported+ for (auto func : calledPrimaryFuncs) {+ exportImportFunction(func);+ }+}++void ModuleSplitter::setupTablePatching() {+ std::map<Index, Name> replacedElems;+ // Replace table references to secondary functions with an imported+ // placeholder that encodes the table index in its name:+ // `importNamespace`.`index`.+ forEachElement(primary.table, [&](Name, Index index, Name& elem) {+ if (secondaryFuncs.count(elem)) {+ replacedElems[index] = elem;+ auto* secondaryFunc = secondary.getFunction(elem);+ auto placeholder = std::make_unique<Function>();+ placeholder->module = config.placeholderNamespace;+ placeholder->base = std::to_string(index);+ placeholder->name = Names::getValidFunctionName(+ primary,+ std::string("placeholder_") + std::string(placeholder->base.c_str()));+ placeholder->hasExplicitName = false;+ placeholder->sig = secondaryFunc->sig;+ elem = placeholder->name;+ primary.addFunction(std::move(placeholder));+ }+ });++ if (replacedElems.size() == 0) {+ // No placeholders to patch out of the table+ return;+ }++ if (tableManager.activeBase.global.size()) {+ assert(primary.table.segments.size() == 1 &&+ "Unexpected number of segments with non-const base");+ assert(secondary.table.segments.size() == 0);+ // Since addition is not currently allowed in initializer expressions, we+ // need to start the new secondary segment where the primary segment starts.+ // The secondary segment will contain the same primary functions as the+ // primary module except in positions where it needs to overwrite a+ // placeholder function. All primary functions in the table therefore need+ // to be imported into the second module. TODO: use better strategies here,+ // such as using ref.func in the start function or standardizing addition in+ // initializer expressions.+ const Table::Segment& primarySeg = primary.table.segments.front();+ std::vector<Name> secondaryElems;+ secondaryElems.reserve(primarySeg.data.size());++ // Copy functions from the primary segment to the secondary segment,+ // replacing placeholders and creating new exports and imports as necessary.+ auto replacement = replacedElems.begin();+ for (Index i = 0;+ i < primarySeg.data.size() && replacement != replacedElems.end();+ ++i) {+ if (replacement->first == i) {+ // primarySeg.data[i] is a placeholder, so use the secondary function.+ secondaryElems.push_back(replacement->second);+ ++replacement;+ } else {+ exportImportFunction(primarySeg.data[i]);+ secondaryElems.push_back(primarySeg.data[i]);+ }+ }++ auto offset = ExpressionManipulator::copy(primarySeg.offset, secondary);+ secondary.table.segments.emplace_back(offset, secondaryElems);+ return;+ }++ // Create active table segments in the secondary module to patch in the+ // original functions when it is instantiated.+ Index currBase = replacedElems.begin()->first;+ std::vector<Name> currData;+ auto finishSegment = [&]() {+ auto* offset = Builder(secondary).makeConst(int32_t(currBase));+ secondary.table.segments.emplace_back(offset, currData);+ };+ for (auto curr = replacedElems.begin(); curr != replacedElems.end(); ++curr) {+ if (curr->first != currBase + currData.size()) {+ finishSegment();+ currBase = curr->first;+ currData.clear();+ }+ currData.push_back(curr->second);+ }+ if (currData.size()) {+ finishSegment();+ }+}++void ModuleSplitter::shareImportableItems() {+ // Map internal names to (one of) their corresponding export names. Don't+ // consider functions because they have already been imported and exported as+ // necessary.+ std::unordered_map<std::pair<ExternalKind, Name>, Name> exports;+ for (auto& ex : primary.exports) {+ if (ex->kind != ExternalKind::Function) {+ exports[std::make_pair(ex->kind, ex->value)] = ex->name;+ }+ }++ auto makeImportExport = [&](Importable& primaryItem,+ Importable& secondaryItem,+ const std::string& genericExportName,+ ExternalKind kind) {+ secondaryItem.name = primaryItem.name;+ secondaryItem.hasExplicitName = primaryItem.hasExplicitName;+ secondaryItem.module = config.importNamespace;+ auto exportIt = exports.find(std::make_pair(kind, primaryItem.name));+ if (exportIt != exports.end()) {+ secondaryItem.base = exportIt->second;+ } else {+ Name exportName = Names::getValidExportName(+ primary, config.newExportPrefix + genericExportName);+ primary.addExport(new Export{exportName, primaryItem.name, kind});+ secondaryItem.base = exportName;+ }+ };++ // TODO: Be more selective by only sharing global items that are actually used+ // in the secondary module, just like we do for functions.++ if (primary.memory.exists) {+ secondary.memory.exists = true;+ secondary.memory.initial = primary.memory.initial;+ secondary.memory.max = primary.memory.max;+ secondary.memory.shared = primary.memory.shared;+ secondary.memory.indexType = primary.memory.indexType;+ makeImportExport(+ primary.memory, secondary.memory, "memory", ExternalKind::Memory);+ }++ if (primary.table.exists) {+ secondary.table.exists = true;+ secondary.table.initial = primary.table.initial;+ secondary.table.max = primary.table.max;+ makeImportExport(+ primary.table, secondary.table, "table", ExternalKind::Table);+ }++ for (auto& global : primary.globals) {+ if (global->mutable_) {+ assert(primary.features.hasMutableGlobals() &&+ "TODO: add wrapper functions for disallowed mutable globals");+ }+ auto secondaryGlobal = std::make_unique<Global>();+ secondaryGlobal->type = global->type;+ secondaryGlobal->mutable_ = global->mutable_;+ secondaryGlobal->init =+ global->init == nullptr+ ? nullptr+ : ExpressionManipulator::copy(global->init, secondary);+ makeImportExport(*global, *secondaryGlobal, "global", ExternalKind::Global);+ secondary.addGlobal(std::move(secondaryGlobal));+ }++ for (auto& event : primary.events) {+ auto secondaryEvent = std::make_unique<Event>();+ secondaryEvent->attribute = event->attribute;+ secondaryEvent->sig = event->sig;+ makeImportExport(*event, *secondaryEvent, "event", ExternalKind::Event);+ secondary.addEvent(std::move(secondaryEvent));+ }+}++} // anonymous namespace++std::unique_ptr<Module> splitFunctions(Module& primary, const Config& config) {+ return std::move(ModuleSplitter(primary, config).secondaryPtr);+}++} // namespace ModuleSplitting++} // namespace wasm
+ binaryen/src/ir/module-splitting.h view
@@ -0,0 +1,76 @@+/*+ * Copyright 2020 WebAssembly Community Group participants+ *+ * Licensed under the Apache License, Version 2.0 (the "License");+ * you may not use this file except in compliance with the License.+ * You may obtain a copy of the License at+ *+ * http://www.apache.org/licenses/LICENSE-2.0+ *+ * Unless required by applicable law or agreed to in writing, software+ * distributed under the License is distributed on an "AS IS" BASIS,+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+ * See the License for the specific language governing permissions and+ * limitations under the License.+ */++// module-splitting.h: Provides an interface for decomposing WebAssembly modules+// into multiple modules that can be loaded independently. This works by moving+// functions to a new secondary module and rewriting the primary module to call+// them indirectly. Until the secondary module is instantiated, those indirect+// calls will go to placeholder functions newly imported into the primary+// module. If the primary module has a single segment with a non-constant+// offset, the placeholder function import names are the offsets from that base+// global of the corresponding functions in the table. Otherwise, the+// placeholder import names are the absolute table indices of the corresponding+// functions. The secondary module imports all of its dependencies from the+// primary module.+//+// This code currently makes a few assumptions about the modules that will be+// split and will fail assertions if those assumptions are not true.+//+// 1) It assumes that mutable-globals are allowed.+//+// 2) It assumes that either all segment offsets are constants or there is+// exactly one segment that may have a non-constant offset.+//+// 3) It assumes that each function appears in the table at most once.+//+// These requirements will be relaxed as necessary in the future, but for now+// this code should be considered experimental and used with care.++#ifndef wasm_ir_module_splitting_h+#define wasm_ir_module_splitting_h++#include "wasm.h"++namespace wasm {++namespace ModuleSplitting {++struct Config {+ // The set of functions to keep in the primary module. All others are split+ // out into the new secondary module. Must include the start function if it+ // exists. May or may not include imported functions, which are always kept in+ // the primary module regardless.+ std::set<Name> primaryFuncs;+ // The namespace from which to import primary functions into the secondary+ // module.+ Name importNamespace = "primary";+ // The namespace from which to import placeholder functions into the primary+ // module.+ Name placeholderNamespace = "placeholder";+ // The prefix to attach to the name of any newly created exports. This can be+ // used to differentiate between "real" exports of the module and exports that+ // should only be consumed by the secondary module.+ std::string newExportPrefix = "";+};++// Returns the new secondary module and modifies the `primary` module in place.+std::unique_ptr<Module> splitFunctions(Module& primary, const Config& config);++} // namespace ModuleSplitting++} // namespace wasm++#endif // wasm_ir_module_splitting_h
binaryen/src/ir/module-utils.h view
@@ -308,7 +308,9 @@ struct FunctionInfo { std::set<Function*> callsTo; std::set<Function*> calledBy;- bool hasIndirectCall = false;+ // A non-direct call is any call that is not direct. That includes+ // CallIndirect and CallRef.+ bool hasNonDirectCall = false; }; typedef std::map<Function*, T> Map;@@ -329,10 +331,10 @@ void visitCall(Call* curr) { info.callsTo.insert(module->getFunction(curr->target)); }- void visitCallIndirect(CallIndirect* curr) {- info.hasIndirectCall = true;+ info.hasNonDirectCall = true; }+ void visitCallRef(CallRef* curr) { info.hasNonDirectCall = true; } private: Module* module;@@ -354,7 +356,7 @@ } } - enum IndirectCalls { IgnoreIndirectCalls, IndirectCallsHaveProperty };+ enum NonDirectCalls { IgnoreNonDirectCalls, NonDirectCallsHaveProperty }; // Propagate a property from a function to those that call it. //@@ -365,13 +367,13 @@ void propagateBack(std::function<bool(const T&)> hasProperty, std::function<bool(const T&)> canHaveProperty, std::function<void(T&, Function*)> addProperty,- IndirectCalls indirectCalls) {+ NonDirectCalls nonDirectCalls) { // The work queue contains items we just learned can change the state. UniqueDeferredQueue<Function*> work; for (auto& func : wasm.functions) { if (hasProperty(map[func.get()]) ||- (indirectCalls == IndirectCallsHaveProperty &&- map[func.get()].hasIndirectCall)) {+ (nonDirectCalls == NonDirectCallsHaveProperty &&+ map[func.get()].hasNonDirectCall)) { addProperty(map[func.get()], func.get()); work.push(func.get()); }@@ -390,19 +392,33 @@ } }; -// Helper function for collecting the type signatures used in a module+// Helper function for collecting all the types that are declared in a module,+// which means the HeapTypes (that are non-basic, that is, not eqref etc., which+// do not need to be defined). //-// Used when emitting or printing a module to give signatures canonical-// indices. Signatures are sorted in order of decreasing frequency to minize the+// Used when emitting or printing a module to give HeapTypes canonical+// indices. HeapTypes are sorted in order of decreasing frequency to minize the // size of their collective encoding. Both a vector mapping indices to-// signatures and a map mapping signatures to indices are produced.-inline void-collectSignatures(Module& wasm,- std::vector<Signature>& signatures,- std::unordered_map<Signature, Index>& sigIndices) {- using Counts = std::unordered_map<Signature, size_t>;+// HeapTypes and a map mapping HeapTypes to indices are produced.+inline void collectHeapTypes(Module& wasm,+ std::vector<HeapType>& types,+ std::unordered_map<HeapType, Index>& typeIndices) {+ struct Counts : public std::unordered_map<HeapType, size_t> {+ bool isRelevant(Type type) {+ if (type.isRef()) {+ return !type.getHeapType().isBasic();+ }+ return type.isRtt();+ }+ void note(HeapType type) { (*this)[type]++; }+ void maybeNote(Type type) {+ if (isRelevant(type)) {+ note(type.getHeapType());+ }+ }+ }; - // Collect the signature use counts for a single function+ // Collect the type use counts for a single function auto updateCounts = [&](Function* func, Counts& counts) { if (func->imported()) { return;@@ -412,13 +428,23 @@ Counts& counts; TypeCounter(Counts& counts) : counts(counts) {}+ void visitExpression(Expression* curr) { if (auto* call = curr->dynCast<CallIndirect>()) {- counts[call->sig]++;+ counts.note(call->sig);+ } else if (curr->is<RefNull>()) {+ counts.maybeNote(curr->type);+ } else if (curr->is<RttCanon>() || curr->is<RttSub>()) {+ counts.note(curr->type.getRtt().heapType);+ } else if (auto* get = curr->dynCast<StructGet>()) {+ counts.maybeNote(get->ref->type);+ } else if (auto* set = curr->dynCast<StructSet>()) {+ counts.maybeNote(set->ref->type); } else if (Properties::isControlFlowStructure(curr)) {- // TODO: Allow control flow to have input types as well+ counts.maybeNote(curr->type); if (curr->type.isTuple()) {- counts[Signature(Type::none, curr->type)]++;+ // TODO: Allow control flow to have input types as well+ counts.note(Signature(Type::none, curr->type)); } } }@@ -431,29 +457,127 @@ // Collect all the counts. Counts counts; for (auto& curr : wasm.functions) {- counts[curr->sig]++;+ counts.note(curr->sig);+ for (auto type : curr->vars) {+ counts.maybeNote(type);+ if (type.isTuple()) {+ for (auto t : type) {+ counts.maybeNote(t);+ }+ }+ } } for (auto& curr : wasm.events) {- counts[curr->sig]++;+ counts.note(curr->sig); }+ for (auto& curr : wasm.globals) {+ counts.maybeNote(curr->type);+ } for (auto& pair : analysis.map) { Counts& functionCounts = pair.second; for (auto& innerPair : functionCounts) { counts[innerPair.first] += innerPair.second; } }- std::vector<std::pair<Signature, size_t>> sorted(counts.begin(),- counts.end());+ // A generic utility to traverse the child types of a type.+ // TODO: work with tlively to refactor this to a shared place+ auto walkRelevantChildren = [&](HeapType type,+ std::function<void(HeapType)> callback) {+ auto callIfRelevant = [&](Type type) {+ if (counts.isRelevant(type)) {+ callback(type.getHeapType());+ }+ };+ if (type.isSignature()) {+ auto sig = type.getSignature();+ for (Type type : {sig.params, sig.results}) {+ for (auto element : type) {+ callIfRelevant(element);+ }+ }+ } else if (type.isArray()) {+ callIfRelevant(type.getArray().element.type);+ } else if (type.isStruct()) {+ auto fields = type.getStruct().fields;+ for (auto field : fields) {+ callIfRelevant(field.type);+ }+ }+ };+ // Recursively traverse each reference type, which may have a child type that+ // is itself a reference type. This reflects an appearance in the binary+ // format that is in the type section itself.+ // As we do this we may find more and more types, as nested children of+ // previous ones. Each such type will appear in the type section once, so+ // we just need to visit it once.+ // TODO: handle struct and array fields+ std::unordered_set<HeapType> newTypes;+ for (auto& pair : counts) {+ newTypes.insert(pair.first);+ }+ while (!newTypes.empty()) {+ auto iter = newTypes.begin();+ auto type = *iter;+ newTypes.erase(iter);+ walkRelevantChildren(type, [&](HeapType type) {+ if (!counts.count(type)) {+ newTypes.insert(type);+ }+ counts.note(type);+ });+ }++ // We must sort all the dependencies of a type before it. For example,+ // (func (param (ref (func)))) must appear after (func). To do that, find the+ // depth of dependencies of each type. For example, if A depends on B+ // which depends on C, then A's depth is 2, B's is 1, and C's is 0 (assuming+ // no other dependencies).+ Counts depthOfDependencies;+ std::unordered_map<HeapType, std::unordered_set<HeapType>> isDependencyOf;+ // To calculate the depth of dependencies, we'll do a flow analysis, visiting+ // each type as we find out new things about it.+ std::set<HeapType> toVisit;+ for (auto& pair : counts) {+ auto type = pair.first;+ depthOfDependencies[type] = 0;+ toVisit.insert(type);+ walkRelevantChildren(type, [&](HeapType childType) {+ isDependencyOf[childType].insert(type); // XXX flip?+ });+ }+ while (!toVisit.empty()) {+ auto iter = toVisit.begin();+ auto type = *iter;+ toVisit.erase(iter);+ // Anything that depends on this has a depth of dependencies equal to this+ // type's, plus this type itself.+ auto newDepth = depthOfDependencies[type] + 1;+ if (newDepth > counts.size()) {+ Fatal() << "Cyclic types detected, cannot sort them.";+ }+ for (auto& other : isDependencyOf[type]) {+ if (depthOfDependencies[other] < newDepth) {+ // We found something new to propagate.+ depthOfDependencies[other] = newDepth;+ toVisit.insert(other);+ }+ }+ }+ // Sort by frequency and then simplicity, and also keeping every type+ // before things that depend on it.+ std::vector<std::pair<HeapType, size_t>> sorted(counts.begin(), counts.end()); std::sort(sorted.begin(), sorted.end(), [&](auto a, auto b) {- // order by frequency then simplicity+ if (depthOfDependencies[a.first] != depthOfDependencies[b.first]) {+ return depthOfDependencies[a.first] < depthOfDependencies[b.first];+ } if (a.second != b.second) { return a.second > b.second; } return a.first < b.first; }); for (Index i = 0; i < sorted.size(); ++i) {- sigIndices[sorted[i].first] = i;- signatures.push_back(sorted[i].first);+ typeIndices[sorted[i].first] = i;+ types.push_back(sorted[i].first); } }
binaryen/src/ir/names.h view
@@ -46,6 +46,41 @@ } } +// Given a root of a name, finds a valid name with perhaps a number appended+// to it, by calling a function to check if a name is valid.+inline Name+getValidName(Module& module, Name root, std::function<bool(Name)> check) {+ if (check(root)) {+ return root;+ }+ auto prefixed = std::string(root.str) + '_';+ Index num = 0;+ while (1) {+ auto name = prefixed + std::to_string(num);+ if (check(name)) {+ return name;+ }+ num++;+ }+}++inline Name getValidExportName(Module& module, Name root) {+ return getValidName(+ module, root, [&](Name test) { return !module.getExportOrNull(test); });+}+inline Name getValidGlobalName(Module& module, Name root) {+ return getValidName(+ module, root, [&](Name test) { return !module.getGlobalOrNull(test); });+}+inline Name getValidFunctionName(Module& module, Name root) {+ return getValidName(+ module, root, [&](Name test) { return !module.getFunctionOrNull(test); });+}+inline Name getValidEventName(Module& module, Name root) {+ return getValidName(+ module, root, [&](Name test) { return !module.getEventOrNull(test); });+}+ } // namespace Names } // namespace wasm
binaryen/src/ir/properties.h view
@@ -19,6 +19,7 @@ #include "ir/bits.h" #include "ir/effects.h"+#include "ir/match.h" #include "wasm.h" namespace wasm {@@ -79,6 +80,10 @@ return false; } +// A constant expression is something like a Const: it has a fixed value known+// at compile time, and passes that propagate constants can try to propagate it.+// Constant expressions are also allowed in global initializers in wasm.+// TODO: look into adding more things here like RttCanon. inline bool isSingleConstantExpression(const Expression* curr) { return curr->is<Const>() || curr->is<RefNull>() || curr->is<RefFunc>() || (curr->is<I31New>() && curr->cast<I31New>()->value->is<Const>());@@ -105,7 +110,7 @@ } else if (auto* n = curr->dynCast<RefNull>()) { return Literal(n->type); } else if (auto* r = curr->dynCast<RefFunc>()) {- return Literal(r->func);+ return Literal(r->func, r->type); } else if (auto* i = curr->dynCast<I31New>()) { if (auto* c = i->value->dynCast<Const>()) { return Literal::makeI31(c->value.geti32());@@ -131,84 +136,81 @@ // Check if an expression is a sign-extend, and if so, returns the value // that is extended, otherwise nullptr inline Expression* getSignExtValue(Expression* curr) {- if (auto* outer = curr->dynCast<Binary>()) {- if (outer->op == ShrSInt32) {- if (auto* outerConst = outer->right->dynCast<Const>()) {- if (outerConst->value.geti32() != 0) {- if (auto* inner = outer->left->dynCast<Binary>()) {- if (inner->op == ShlInt32) {- if (auto* innerConst = inner->right->dynCast<Const>()) {- if (outerConst->value == innerConst->value) {- return inner->left;- }- }- }- }- }- }- }+ // We only care about i32s here, and ignore i64s, unreachables, etc.+ if (curr->type != Type::i32) {+ return nullptr; }+ using namespace Match;+ int32_t leftShift = 0, rightShift = 0;+ Expression* extended = nullptr;+ if (matches(curr,+ binary(ShrSInt32,+ binary(ShlInt32, any(&extended), i32(&leftShift)),+ i32(&rightShift))) &&+ leftShift == rightShift && leftShift != 0) {+ return extended;+ } return nullptr; } // gets the size of the sign-extended value inline Index getSignExtBits(Expression* curr) {- return 32 - Bits::getEffectiveShifts(curr->cast<Binary>()->right);+ assert(curr->type == Type::i32);+ auto* rightShift = curr->cast<Binary>()->right;+ return 32 - Bits::getEffectiveShifts(rightShift); } // Check if an expression is almost a sign-extend: perhaps the inner shift // is too large. We can split the shifts in that case, which is sometimes // useful (e.g. if we can remove the signext) inline Expression* getAlmostSignExt(Expression* curr) {- if (auto* outer = curr->dynCast<Binary>()) {- if (outer->op == ShrSInt32) {- if (auto* outerConst = outer->right->dynCast<Const>()) {- if (outerConst->value.geti32() != 0) {- if (auto* inner = outer->left->dynCast<Binary>()) {- if (inner->op == ShlInt32) {- if (auto* innerConst = inner->right->dynCast<Const>()) {- if (Bits::getEffectiveShifts(outerConst) <=- Bits::getEffectiveShifts(innerConst)) {- return inner->left;- }- }- }- }- }- }- }+ using namespace Match;+ int32_t leftShift = 0, rightShift = 0;+ Expression* extended = nullptr;+ if (matches(curr,+ binary(ShrSInt32,+ binary(ShlInt32, any(&extended), i32(&leftShift)),+ i32(&rightShift))) &&+ Bits::getEffectiveShifts(rightShift, Type::i32) <=+ Bits::getEffectiveShifts(leftShift, Type::i32) &&+ rightShift != 0) {+ return extended; } return nullptr; } // gets the size of the almost sign-extended value, as well as the // extra shifts, if any-inline Index getAlmostSignExtBits(Expression* curr, Index& extraShifts) {- extraShifts = Bits::getEffectiveShifts(- curr->cast<Binary>()->left->cast<Binary>()->right) -- Bits::getEffectiveShifts(curr->cast<Binary>()->right);+inline Index getAlmostSignExtBits(Expression* curr, Index& extraLeftShifts) {+ auto* leftShift = curr->cast<Binary>()->left->cast<Binary>()->right;+ auto* rightShift = curr->cast<Binary>()->right;+ extraLeftShifts =+ Bits::getEffectiveShifts(leftShift) - Bits::getEffectiveShifts(rightShift); return getSignExtBits(curr); } // Check if an expression is a zero-extend, and if so, returns the value // that is extended, otherwise nullptr inline Expression* getZeroExtValue(Expression* curr) {- if (auto* binary = curr->dynCast<Binary>()) {- if (binary->op == AndInt32) {- if (auto* c = binary->right->dynCast<Const>()) {- if (Bits::getMaskedBits(c->value.geti32())) {- return binary->right;- }- }- }+ // We only care about i32s here, and ignore i64s, unreachables, etc.+ if (curr->type != Type::i32) {+ return nullptr; }+ using namespace Match;+ int32_t mask = 0;+ Expression* extended = nullptr;+ if (matches(curr, binary(AndInt32, any(&extended), i32(&mask))) &&+ Bits::getMaskedBits(mask) != 0) {+ return extended;+ } return nullptr; } // gets the size of the sign-extended value inline Index getZeroExtBits(Expression* curr) {- return Bits::getMaskedBits(- curr->cast<Binary>()->right->cast<Const>()->value.geti32());+ assert(curr->type == Type::i32);+ int32_t mask = curr->cast<Binary>()->right->cast<Const>()->value.geti32();+ return Bits::getMaskedBits(mask); } // Returns a falling-through value, that is, it looks through a local.tee
binaryen/src/ir/type-updating.h view
@@ -17,6 +17,7 @@ #ifndef wasm_ir_type_updating_h #define wasm_ir_type_updating_h +#include "ir/branch-utils.h" #include "wasm-traversal.h" namespace wasm {@@ -56,17 +57,11 @@ if (block->name.is()) { blockInfos[block->name].block = block; }- } else if (auto* br = curr->dynCast<Break>()) {- // ensure info exists, discoverBreaks can then fill it- blockInfos[br->name];- } else if (auto* sw = curr->dynCast<Switch>()) {- // ensure info exists, discoverBreaks can then fill it- for (auto target : sw->targets) {- blockInfos[target];- }- blockInfos[sw->default_];- } else if (auto* br = curr->dynCast<BrOnExn>()) {- blockInfos[br->name];+ } else {+ BranchUtils::operateOnScopeNameUses(curr, [&](Name& name) {+ // ensure info exists, discoverBreaks can then fill it+ blockInfos[name];+ }); } // add a break to the info, for break and switch discoverBreaks(curr, +1);@@ -147,32 +142,22 @@ discoverBreaks(curr, parent ? +1 : -1); } - // adds (or removes) breaks depending on break/switch contents- void discoverBreaks(Expression* curr, int change) {- if (auto* br = curr->dynCast<Break>()) {- noteBreakChange(br->name, change, br->value);- } else if (auto* sw = curr->dynCast<Switch>()) {- applySwitchChanges(sw, change);- } else if (auto* br = curr->dynCast<BrOnExn>()) {- noteBreakChange(br->name, change, br->sent);- }- }-- void applySwitchChanges(Switch* sw, int change) {- std::set<Name> seen;- for (auto target : sw->targets) {- if (seen.insert(target).second) {- noteBreakChange(target, change, sw->value);- }- }- if (seen.insert(sw->default_).second) {- noteBreakChange(sw->default_, change, sw->value);+ // Applies a type change to a node, and potentially to its parents.+ void changeType(Expression* curr, Type type) {+ if (curr->type != type) {+ curr->type = type;+ propagateTypesUp(curr); } } - // note the addition of a node- void noteBreakChange(Name name, int change, Expression* value) {- noteBreakChange(name, change, value ? value->type : Type::none);+ // adds (or removes) breaks depending on break/switch contents+ void discoverBreaks(Expression* curr, int change) {+ BranchUtils::operateOnScopeNameUsesAndSentTypes(+ curr,+ [&](Name& name, Type type) { noteBreakChange(name, change, type); });+ // TODO: it may be faster to accumulate all changes to a set first, then+ // call noteBreakChange on the unique values, as a switch can be quite+ // large and have lots of repeated targets. } void noteBreakChange(Name name, int change, Type type) {@@ -313,6 +298,10 @@ if (curr->type == Type::unreachable) { propagateTypesUp(curr); }+ }++ bool hasBreaks(Block* block) {+ return block->name.is() && blockInfos[block->name].numBreaks > 0; } };
binaryen/src/ir/utils.h view
@@ -111,70 +111,11 @@ std::map<Name, Type> breakValues; - void visitBlock(Block* curr);- void visitIf(If* curr);- void visitLoop(Loop* curr);- void visitBreak(Break* curr);- void visitSwitch(Switch* curr);- void visitCall(Call* curr);- void visitCallIndirect(CallIndirect* curr);- void visitLocalGet(LocalGet* curr);- void visitLocalSet(LocalSet* curr);- void visitGlobalGet(GlobalGet* curr);- void visitGlobalSet(GlobalSet* curr);- void visitLoad(Load* curr);- void visitStore(Store* curr);- void visitAtomicRMW(AtomicRMW* curr);- void visitAtomicCmpxchg(AtomicCmpxchg* curr);- void visitAtomicWait(AtomicWait* curr);- void visitAtomicNotify(AtomicNotify* curr);- void visitAtomicFence(AtomicFence* curr);- void visitSIMDExtract(SIMDExtract* curr);- void visitSIMDReplace(SIMDReplace* curr);- void visitSIMDShuffle(SIMDShuffle* curr);- void visitSIMDTernary(SIMDTernary* curr);- void visitSIMDShift(SIMDShift* curr);- void visitSIMDLoad(SIMDLoad* curr);- void visitMemoryInit(MemoryInit* curr);- void visitDataDrop(DataDrop* curr);- void visitMemoryCopy(MemoryCopy* curr);- void visitMemoryFill(MemoryFill* curr);- void visitConst(Const* curr);- void visitUnary(Unary* curr);- void visitBinary(Binary* curr);- void visitSelect(Select* curr);- void visitDrop(Drop* curr);- void visitReturn(Return* curr);- void visitMemorySize(MemorySize* curr);- void visitMemoryGrow(MemoryGrow* curr);- void visitRefNull(RefNull* curr);- void visitRefIsNull(RefIsNull* curr);- void visitRefFunc(RefFunc* curr);- void visitRefEq(RefEq* curr);- void visitTry(Try* curr);- void visitThrow(Throw* curr);- void visitRethrow(Rethrow* curr);- void visitBrOnExn(BrOnExn* curr);- void visitNop(Nop* curr);- void visitUnreachable(Unreachable* curr);- void visitPop(Pop* curr);- void visitTupleMake(TupleMake* curr);- void visitTupleExtract(TupleExtract* curr);- void visitI31New(I31New* curr);- void visitI31Get(I31Get* curr);- void visitRefTest(RefTest* curr);- void visitRefCast(RefCast* curr);- void visitBrOnCast(BrOnCast* curr);- void visitRttCanon(RttCanon* curr);- void visitRttSub(RttSub* curr);- void visitStructNew(StructNew* curr);- void visitStructGet(StructGet* curr);- void visitStructSet(StructSet* curr);- void visitArrayNew(ArrayNew* curr);- void visitArrayGet(ArrayGet* curr);- void visitArraySet(ArraySet* curr);- void visitArrayLen(ArrayLen* curr);+#define DELEGATE(CLASS_TO_VISIT) \+ void visit##CLASS_TO_VISIT(CLASS_TO_VISIT* curr); +#include "wasm-delegations.h"+ void visitFunction(Function* curr); void visitExport(Export* curr);@@ -195,69 +136,10 @@ // Re-finalize a single node. This is slow, if you want to refinalize // an entire ast, use ReFinalize struct ReFinalizeNode : public OverriddenVisitor<ReFinalizeNode> {- void visitBlock(Block* curr) { curr->finalize(); }- void visitIf(If* curr) { curr->finalize(); }- void visitLoop(Loop* curr) { curr->finalize(); }- void visitBreak(Break* curr) { curr->finalize(); }- void visitSwitch(Switch* curr) { curr->finalize(); }- void visitCall(Call* curr) { curr->finalize(); }- void visitCallIndirect(CallIndirect* curr) { curr->finalize(); }- void visitLocalGet(LocalGet* curr) { curr->finalize(); }- void visitLocalSet(LocalSet* curr) { curr->finalize(); }- void visitGlobalGet(GlobalGet* curr) { curr->finalize(); }- void visitGlobalSet(GlobalSet* curr) { curr->finalize(); }- void visitLoad(Load* curr) { curr->finalize(); }- void visitStore(Store* curr) { curr->finalize(); }- void visitAtomicRMW(AtomicRMW* curr) { curr->finalize(); }- void visitAtomicCmpxchg(AtomicCmpxchg* curr) { curr->finalize(); }- void visitAtomicWait(AtomicWait* curr) { curr->finalize(); }- void visitAtomicNotify(AtomicNotify* curr) { curr->finalize(); }- void visitAtomicFence(AtomicFence* curr) { curr->finalize(); }- void visitSIMDExtract(SIMDExtract* curr) { curr->finalize(); }- void visitSIMDReplace(SIMDReplace* curr) { curr->finalize(); }- void visitSIMDShuffle(SIMDShuffle* curr) { curr->finalize(); }- void visitSIMDTernary(SIMDTernary* curr) { curr->finalize(); }- void visitSIMDShift(SIMDShift* curr) { curr->finalize(); }- void visitSIMDLoad(SIMDLoad* curr) { curr->finalize(); }- void visitMemoryInit(MemoryInit* curr) { curr->finalize(); }- void visitDataDrop(DataDrop* curr) { curr->finalize(); }- void visitMemoryCopy(MemoryCopy* curr) { curr->finalize(); }- void visitMemoryFill(MemoryFill* curr) { curr->finalize(); }- void visitConst(Const* curr) { curr->finalize(); }- void visitUnary(Unary* curr) { curr->finalize(); }- void visitBinary(Binary* curr) { curr->finalize(); }- void visitSelect(Select* curr) { curr->finalize(); }- void visitDrop(Drop* curr) { curr->finalize(); }- void visitReturn(Return* curr) { curr->finalize(); }- void visitMemorySize(MemorySize* curr) { curr->finalize(); }- void visitMemoryGrow(MemoryGrow* curr) { curr->finalize(); }- void visitRefNull(RefNull* curr) { curr->finalize(); }- void visitRefIsNull(RefIsNull* curr) { curr->finalize(); }- void visitRefFunc(RefFunc* curr) { curr->finalize(); }- void visitRefEq(RefEq* curr) { curr->finalize(); }- void visitTry(Try* curr) { curr->finalize(); }- void visitThrow(Throw* curr) { curr->finalize(); }- void visitRethrow(Rethrow* curr) { curr->finalize(); }- void visitBrOnExn(BrOnExn* curr) { curr->finalize(); }- void visitNop(Nop* curr) { curr->finalize(); }- void visitUnreachable(Unreachable* curr) { curr->finalize(); }- void visitPop(Pop* curr) { curr->finalize(); }- void visitTupleMake(TupleMake* curr) { curr->finalize(); }- void visitTupleExtract(TupleExtract* curr) { curr->finalize(); }- void visitI31New(I31New* curr) { curr->finalize(); }- void visitI31Get(I31Get* curr) { curr->finalize(); }- void visitRefTest(RefTest* curr) { curr->finalize(); }- void visitRefCast(RefCast* curr) { curr->finalize(); }- void visitBrOnCast(BrOnCast* curr) { curr->finalize(); }- void visitRttCanon(RttCanon* curr) { curr->finalize(); }- void visitRttSub(RttSub* curr) { curr->finalize(); }- void visitStructNew(StructNew* curr) { curr->finalize(); }- void visitStructGet(StructGet* curr) { curr->finalize(); }- void visitStructSet(StructSet* curr) { curr->finalize(); }- void visitArrayNew(ArrayNew* curr) { curr->finalize(); }- void visitArrayGet(ArrayGet* curr) { curr->finalize(); }- void visitArraySet(ArraySet* curr) { curr->finalize(); }- void visitArrayLen(ArrayLen* curr) { curr->finalize(); }+#define DELEGATE(CLASS_TO_VISIT) \+ void visit##CLASS_TO_VISIT(CLASS_TO_VISIT* curr) { curr->finalize(); }++#include "wasm-delegations.h" void visitExport(Export* curr) { WASM_UNREACHABLE("unimp"); } void visitGlobal(Global* curr) { WASM_UNREACHABLE("unimp"); }
binaryen/src/js/binaryen.js-post.js view
@@ -9,7 +9,7 @@ } function strToStack(str) {- return str ? allocate(intArrayFromString(str), 'i8', ALLOC_STACK) : 0;+ return str ? allocate(intArrayFromString(str), ALLOC_STACK) : 0; } function i32sToStack(i32s) {@@ -99,6 +99,7 @@ 'Pop', 'I31New', 'I31Get',+ 'CallRef', 'RefTest', 'RefCast', 'BrOnCast',@@ -415,8 +416,6 @@ 'MaxSVecI32x4', 'MaxUVecI32x4', 'NegVecI64x2',- 'AnyTrueVecI64x2',- 'AllTrueVecI64x2', 'ShlVecI64x2', 'ShrSVecI64x2', 'ShrUVecI64x2',@@ -629,6 +628,17 @@ }, 'fill'(dest, value, size) { return Module['_BinaryenMemoryFill'](module, dest, value, size);+ },+ 'atomic': {+ 'notify'(ptr, notifyCount) {+ return Module['_BinaryenAtomicNotify'](module, ptr, notifyCount);+ },+ 'wait32'(ptr, expected, timeout) {+ return Module['_BinaryenAtomicWait'](module, ptr, expected, timeout, Module['i32']);+ },+ 'wait64'(ptr, expected, timeout) {+ return Module['_BinaryenAtomicWait'](module, ptr, expected, timeout, Module['i64']);+ } } } @@ -889,9 +899,6 @@ return Module['_BinaryenAtomicCmpxchg'](module, 2, offset, ptr, expected, replacement, Module['i32']) }, },- 'wait'(ptr, expected, timeout) {- return Module['_BinaryenAtomicWait'](module, ptr, expected, timeout, Module['i32']);- } }, 'pop'() { return Module['_BinaryenPop'](module, Module['i32']);@@ -1193,9 +1200,6 @@ return Module['_BinaryenAtomicCmpxchg'](module, 4, offset, ptr, expected, replacement, Module['i64']) }, },- 'wait'(ptr, expected, timeout) {- return Module['_BinaryenAtomicWait'](module, ptr, expected, timeout, Module['i64']);- } }, 'pop'() { return Module['_BinaryenPop'](module, Module['i64']);@@ -1822,12 +1826,6 @@ 'neg'(value) { return Module['_BinaryenUnary'](module, Module['NegVecI64x2'], value); },- 'any_true'(value) {- return Module['_BinaryenUnary'](module, Module['AnyTrueVecI64x2'], value);- },- 'all_true'(value) {- return Module['_BinaryenUnary'](module, Module['AllTrueVecI64x2'], value);- }, 'shl'(vec, shift) { return Module['_BinaryenSIMDShift'](module, Module['ShlVecI64x2'], vec, shift); },@@ -2107,8 +2105,8 @@ 'is_null'(value) { return Module['_BinaryenRefIsNull'](module, value); },- 'func'(func) {- return preserveStack(() => Module['_BinaryenRefFunc'](module, strToStack(func)));+ 'func'(func, type) {+ return preserveStack(() => Module['_BinaryenRefFunc'](module, strToStack(func), type)); }, 'eq'(left, right) { return Module['_BinaryenRefEq'](module, left, right);@@ -2132,9 +2130,6 @@ }; self['atomic'] = {- 'notify'(ptr, notifyCount) {- return Module['_BinaryenAtomicNotify'](module, ptr, notifyCount);- }, 'fence'() { return Module['_BinaryenAtomicFence'](module); }@@ -2289,7 +2284,7 @@ const segmentOffset = new Array(segmentsLen); for (let i = 0; i < segmentsLen; i++) { const { data, offset, passive } = segments[i];- segmentData[i] = allocate(data, 'i8', ALLOC_STACK);+ segmentData[i] = allocate(data, ALLOC_STACK); segmentDataLen[i] = data.length; segmentPassive[i] = passive; segmentOffset[i] = offset;@@ -2337,18 +2332,27 @@ Module['_BinaryenAddCustomSection'](module, strToStack(name), i8sToStack(contents), contents.length) ); };+ self['getExport'] = function(externalName) {+ return preserveStack(() => Module['_BinaryenGetExport'](module, strToStack(externalName)));+ }; self['getNumExports'] = function() { return Module['_BinaryenGetNumExports'](module);- }- self['getExportByIndex'] = function(id) {- return Module['_BinaryenGetExportByIndex'](module, id);- }+ };+ self['getExportByIndex'] = function(index) {+ return Module['_BinaryenGetExportByIndex'](module, index);+ }; self['getNumFunctions'] = function() { return Module['_BinaryenGetNumFunctions'](module);- }- self['getFunctionByIndex'] = function(id) {- return Module['_BinaryenGetFunctionByIndex'](module, id);- }+ };+ self['getFunctionByIndex'] = function(index) {+ return Module['_BinaryenGetFunctionByIndex'](module, index);+ };+ self['getNumGlobals'] = function() {+ return Module['_BinaryenGetNumGlobals'](module);+ };+ self['getGlobalByIndex'] = function(index) {+ return Module['_BinaryenGetGlobalByIndex'](module, index);+ }; self['emitText'] = function() { const old = out; let ret = '';@@ -2990,7 +2994,7 @@ Object.defineProperty(Module, 'readBinary', { writable: true }); Module['readBinary'] = function(data) {- const buffer = allocate(data, 'i8', ALLOC_NORMAL);+ const buffer = allocate(data, ALLOC_NORMAL); const ptr = Module['_BinaryenModuleRead'](buffer, data.length); _free(buffer); return wrapModule(ptr);
binaryen/src/literal.h view
@@ -31,6 +31,10 @@ class Literals; struct ExceptionPackage;+struct GCData;+// Subclass the vector type so that this is not easily confused with a vector of+// types (which could be confusing on the Literal constructor).+struct RttSupers : std::vector<Type> {}; class Literal { // store only integers, whose bits are deterministic. floats@@ -43,6 +47,24 @@ Name func; // exnref package. `nullptr` indicates a `null` value. std::unique_ptr<ExceptionPackage> exn;+ // A reference to GC data, either a Struct or an Array. For both of those+ // we store the referred data as a Literals object (which is natural for an+ // Array, and for a Struct, is just the fields in order). The type is used+ // to indicate whether this is a Struct or an Array, and of what type.+ std::shared_ptr<GCData> gcData;+ // RTT values are "structural" in that the MVP doc says that multiple+ // invocations of ref.canon return things that are observably identical, and+ // the same is true for ref.sub. That is, what matters is the types; there+ // is no unique identifier created in each ref.canon/sub. To track the+ // types, we maintain a simple vector of the supertypes. Thus, an rtt.canon+ // of type A will have an empty vector; an rtt.sub of type B of that initial+ // canon would have a vector of size 1 containing A; a subsequent rtt.sub+ // would have A, B, and so forth.+ // (This encoding is very inefficient and not at all what a production VM+ // would do, but it is simple.)+ // The unique_ptr here is to avoid increasing the size of the union as well+ // as the Literal class itself.+ std::unique_ptr<RttSupers> rttSupers; // TODO: Literals of type `externref` can only be `null` currently but we // will need to represent extern values eventually, to // 1) run the spec tests and fuzzer with reference types enabled and@@ -55,7 +77,7 @@ Literal() : v128(), type(Type::none) {} explicit Literal(Type type);- explicit Literal(Type::BasicID typeId) : Literal(Type(typeId)) {}+ explicit Literal(Type::BasicType type) : Literal(Type(type)) {} explicit Literal(int32_t init) : i32(init), type(Type::i32) {} explicit Literal(uint32_t init) : i32(init), type(Type::i32) {} explicit Literal(int64_t init) : i64(init), type(Type::i64) {}@@ -71,16 +93,14 @@ explicit Literal(const std::array<Literal, 8>&); explicit Literal(const std::array<Literal, 4>&); explicit Literal(const std::array<Literal, 2>&);- explicit Literal(Name func) : func(func), type(Type::funcref) {}+ explicit Literal(Name func, Type type) : func(func), type(type) {} explicit Literal(std::unique_ptr<ExceptionPackage>&& exn) : exn(std::move(exn)), type(Type::exnref) {}+ explicit Literal(std::shared_ptr<GCData> gcData, Type type);+ explicit Literal(std::unique_ptr<RttSupers>&& rttSupers, Type type); Literal(const Literal& other); Literal& operator=(const Literal& other);- ~Literal() {- if (type.isException()) {- exn.~unique_ptr();- }- }+ ~Literal(); bool isConcrete() const { return type != Type::none; } bool isNone() const { return type == Type::none; }@@ -92,6 +112,9 @@ if (type.isException()) { return !exn; }+ if (isGCData()) {+ return !gcData;+ } return true; } return false;@@ -114,6 +137,18 @@ WASM_UNREACHABLE("unexpected type"); } }+ bool isNegative() const {+ switch (type.getBasic()) {+ case Type::i32:+ case Type::f32:+ return i32 < 0;+ case Type::i64:+ case Type::f64:+ return i64 < 0;+ default:+ WASM_UNREACHABLE("unexpected type");+ }+ } bool isSignedMin() const { switch (type.getBasic()) { case Type::i32:@@ -144,6 +179,7 @@ WASM_UNREACHABLE("unexpected type"); } }+ bool isGCData() const { return type.isStruct() || type.isArray(); } static Literals makeZeros(Type type); static Literals makeOnes(Type type);@@ -221,7 +257,9 @@ assert(type.isNullable()); return Literal(type); }- static Literal makeFunc(Name func) { return Literal(func.c_str()); }+ static Literal makeFunc(Name func, Type type = Type::funcref) {+ return Literal(func, type);+ } static Literal makeExn(std::unique_ptr<ExceptionPackage>&& exn) { return Literal(std::move(exn)); }@@ -262,6 +300,8 @@ return func; } ExceptionPackage getExceptionPackage() const;+ std::shared_ptr<GCData> getGCData() const;+ const RttSupers& getRttSupers() const; // careful! int32_t* geti32Ptr() {@@ -451,6 +491,7 @@ Literal leUI32x4(const Literal& other) const; Literal geSI32x4(const Literal& other) const; Literal geUI32x4(const Literal& other) const;+ Literal eqI64x2(const Literal& other) const; Literal eqF32x4(const Literal& other) const; Literal neF32x4(const Literal& other) const; Literal ltF32x4(const Literal& other) const;@@ -488,6 +529,7 @@ Literal maxSI8x16(const Literal& other) const; Literal maxUI8x16(const Literal& other) const; Literal avgrUI8x16(const Literal& other) const;+ Literal popcntI8x16() const; Literal absI16x8() const; Literal negI16x8() const; Literal anyTrueI16x8() const;@@ -508,6 +550,11 @@ Literal maxSI16x8(const Literal& other) const; Literal maxUI16x8(const Literal& other) const; Literal avgrUI16x8(const Literal& other) const;+ Literal q15MulrSatSI16x8(const Literal& other) const;+ Literal extMulLowSI16x8(const Literal& other) const;+ Literal extMulHighSI16x8(const Literal& other) const;+ Literal extMulLowUI16x8(const Literal& other) const;+ Literal extMulHighUI16x8(const Literal& other) const; Literal absI32x4() const; Literal negI32x4() const; Literal anyTrueI32x4() const;@@ -524,15 +571,21 @@ Literal maxSI32x4(const Literal& other) const; Literal maxUI32x4(const Literal& other) const; Literal dotSI16x8toI32x4(const Literal& other) const;+ Literal extMulLowSI32x4(const Literal& other) const;+ Literal extMulHighSI32x4(const Literal& other) const;+ Literal extMulLowUI32x4(const Literal& other) const;+ Literal extMulHighUI32x4(const Literal& other) const; Literal negI64x2() const;- Literal anyTrueI64x2() const;- Literal allTrueI64x2() const; Literal shlI64x2(const Literal& other) const; Literal shrSI64x2(const Literal& other) const; Literal shrUI64x2(const Literal& other) const; Literal addI64x2(const Literal& other) const; Literal subI64x2(const Literal& other) const; Literal mulI64x2(const Literal& other) const;+ Literal extMulLowSI64x2(const Literal& other) const;+ Literal extMulHighSI64x2(const Literal& other) const;+ Literal extMulLowUI64x2(const Literal& other) const;+ Literal extMulHighUI64x2(const Literal& other) const; Literal absF32x4() const; Literal negF32x4() const; Literal sqrtF32x4() const;@@ -585,6 +638,11 @@ Literal widenHighUToVecI32x4() const; Literal swizzleVec8x16(const Literal& other) const; + // Checks if an RTT value is a sub-rtt of another, that is, whether GC data+ // with this object's RTT can be successfuly cast using the other RTT+ // according to the wasm rules for that.+ bool isSubRtt(const Literal& other) const;+ private: Literal addSatSI8(const Literal& other) const; Literal addSatUI8(const Literal& other) const;@@ -611,7 +669,9 @@ assert(lit.isConcrete()); } #endif- };+ }+ Literals(size_t initialSize) : SmallVector(initialSize) {}+ Type getType() { std::vector<Type> types; for (auto& val : *this) {@@ -640,6 +700,14 @@ std::ostream& operator<<(std::ostream& o, wasm::Literals literals); std::ostream& operator<<(std::ostream& o, const ExceptionPackage& exn); +// A GC Struct or Array is a set of values with a run-time type saying what it+// is.+struct GCData {+ Literal rtt;+ Literals values;+ GCData(Literal rtt, Literals values) : rtt(rtt), values(values) {}+};+ } // namespace wasm namespace std {@@ -702,7 +770,12 @@ } else if (a.type.isRef()) { return hashRef(); } else if (a.type.isRtt()) {- WASM_UNREACHABLE("TODO: rtt literals");+ const auto& supers = a.getRttSupers();+ wasm::rehash(digest, supers.size());+ for (auto super : supers) {+ wasm::rehash(digest, super.getID());+ }+ return digest; } WASM_UNREACHABLE("unexpected type"); }
binaryen/src/parsing.h view
@@ -22,12 +22,11 @@ #include <sstream> #include <string> -#include "asmjs/shared-constants.h" #include "mixed_arena.h" #include "shared-constants.h" #include "support/colors.h" #include "support/utilities.h"-#include "wasm-printing.h"+#include "wasm-traversal.h" #include "wasm.h" namespace wasm {
binaryen/src/pass.h view
@@ -69,14 +69,15 @@ // More generally, with 2 items we may have a local.get, but no way to // require it to be saved instead of directly consumed. Index alwaysInlineMaxSize = 2;- // Function size which we inline when functions are lightweight (no loops- // and calls) and we are doing aggressive optimisation for speed (-O3).- // In particular it's nice that with this limit we can inline the clamp- // functions (i32s-div, f64-to-int, etc.), that can affect perf.- Index flexibleInlineMaxSize = 20; // Function size which we inline when there is only one caller. // FIXME: this should logically be higher than flexibleInlineMaxSize. Index oneCallerInlineMaxSize = 15;+ // Function size above which we never inline, ignoring the various flexible+ // factors (like whether we are optimizing for size or speed) that could+ // influence us.+ // This is checked after alwaysInlineMaxSize and oneCallerInlineMaxSize, but+ // the order normally won't matter.+ Index flexibleInlineMaxSize = 20; // Loops usually mean the function does heavy work, so the call overhead // is not significant and we do not inline such functions by default. bool allowFunctionsWithLoops = false;@@ -107,6 +108,15 @@ // forth (which IEEE floats do not, strictly speaking). This is inspired by // gcc/clang's -ffast-math flag. bool fastMath = false;+ // Whether to assume that an imported memory is zero-initialized. Without+ // this, we can do fewer optimizations on memory segments, because if memory+ // *was* modified then the wasm's segments may trample those previous+ // modifications. If memory was zero-initialized then we can remove zeros from+ // the wasm's segments.+ // (This is not a problem if the memory is *not* imported, since then wasm+ // creates it and we know it is all zeros right before the active segments are+ // applied.)+ bool zeroFilledMemory = false; // Whether to try to preserve debug info through, which are special calls. bool debugInfo = false; // Arbitrary string arguments from the commandline, which we forward to@@ -226,9 +236,11 @@ // doesn't help anyhow and also is bad for e.g. printing // which is a pass) // this method returns whether we are in passDebug mode, and which value:- // 1: run pass by pass, validating in between- // 2: also save the last pass, so it breakage happens we can print the last- // one 3: also dump out byn-* files for each pass+ // 1: log out each pass that we run, and validate in between (can pass+ // --no-validation to skip validation).+ // 2: like 1, and also save the last pass's output, so if breakage happens we+ // can print a useful error. also logs out names of nested passes.+ // 3: like 1, and also dumps out byn-* files for each pass as it is run. static int getPassDebug(); protected:@@ -255,10 +267,6 @@ class Pass { public: virtual ~Pass() = default;-- // Override this to perform preparation work before the pass runs.- // This will be called before the pass is run on a module.- virtual void prepareToRun(PassRunner* runner, Module* module) {} // Implement this with code to run the pass on the whole module virtual void run(PassRunner* runner, Module* module) {
binaryen/src/passes/Asyncify.cpp view
@@ -677,7 +677,7 @@ } info.canChangeState = true; },- scanner.IgnoreIndirectCalls);+ scanner.IgnoreNonDirectCalls); map.swap(scanner.map); @@ -1408,8 +1408,10 @@ bool allImportsCanChangeState = stateChangingImports == "" && ignoreImports == ""; String::Split listedImports(stateChangingImports, ",");- auto ignoreIndirect = runner->options.getArgumentOrDefault(- "asyncify-ignore-indirect", "") == "";+ // TODO: consider renaming asyncify-ignore-indirect to+ // asyncify-ignore-nondirect, but that could break users.+ auto ignoreNonDirect = runner->options.getArgumentOrDefault(+ "asyncify-ignore-indirect", "") == ""; std::string removeListInput = runner->options.getArgumentOrDefault("asyncify-removelist", ""); if (removeListInput.empty()) {@@ -1462,7 +1464,7 @@ // Scan the module. ModuleAnalyzer analyzer(*module, canImportChangeState,- ignoreIndirect,+ ignoreNonDirect, removeList, addList, onlyList,@@ -1488,6 +1490,7 @@ // because the flow changes add many branches, break up if-elses, etc., // all of which extend the live ranges of locals. In other words, it is // not possible to coalesce well afterwards.+ runner.add("remove-unused-names"); runner.add("simplify-locals-nonesting"); runner.add("reorder-locals"); runner.add("coalesce-locals");@@ -1569,9 +1572,9 @@ builder.makeIf(builder.makeBinary(GtUInt32, stackPos, stackEnd), builder.makeUnreachable())); body->finalize();- auto* func = builder.makeFunction(+ auto func = builder.makeFunction( name, Signature(Type(params), Type::none), {}, body);- module->addFunction(func);+ module->addFunction(std::move(func)); module->addExport(builder.makeExport(name, name, ExternalKind::Function)); };
binaryen/src/passes/CMakeLists.txt view
@@ -25,7 +25,6 @@ DuplicateImportElimination.cpp DuplicateFunctionElimination.cpp DWARF.cpp- EmscriptenPIC.cpp ExtractFunction.cpp Flatten.cpp FuncCastEmulation.cpp@@ -39,6 +38,7 @@ LocalCSE.cpp LogExecution.cpp LoopInvariantCodeMotion.cpp+ Memory64Lowering.cpp MemoryPacking.cpp MergeBlocks.cpp MergeLocals.cpp@@ -64,7 +64,6 @@ RemoveImports.cpp RemoveMemory.cpp RemoveNonJSOps.cpp- ReplaceStackPointer.cpp RemoveUnusedBrs.cpp RemoveUnusedNames.cpp RemoveUnusedModuleElements.cpp@@ -76,7 +75,6 @@ SimplifyGlobals.cpp SimplifyLocals.cpp Souperify.cpp- SpillPointers.cpp StackCheck.cpp SSAify.cpp Untee.cpp
binaryen/src/passes/CodePushing.cpp view
@@ -160,7 +160,7 @@ firstPushable < pushPoint); // everything that matters if you want to be pushed past the pushPoint EffectAnalyzer cumulativeEffects(passOptions, features);- cumulativeEffects.analyze(list[pushPoint]);+ cumulativeEffects.walk(list[pushPoint]); // it is ok to ignore the branching here, that is the crucial point of this // opt // TODO: it would be ok to ignore thrown exceptions here, if we know they@@ -194,7 +194,7 @@ } } else { // something that can't be pushed, so it might block further pushing- cumulativeEffects.analyze(list[i]);+ cumulativeEffects.walk(list[i]); } assert(i > 0); i--;
binaryen/src/passes/DeadArgumentElimination.cpp view
@@ -72,7 +72,11 @@ // see inhibits our optimizations, but TODO: an export // could be worked around by exporting a thunk that // adds the parameter.- bool hasUnseenCalls = false;+ // This is atomic so that we can write to it from any function at any time+ // during the parallel analysis phase which is run in DAEScanner.+ std::atomic<bool> hasUnseenCalls;++ DAEFunctionInfo() { hasUnseenCalls = false; } }; typedef std::unordered_map<Name, DAEFunctionInfo> DAEFunctionInfoMap;@@ -139,12 +143,29 @@ } } + void visitCallRef(CallRef* curr) {+ if (curr->isReturn) {+ info->hasTailCalls = true;+ }+ }+ void visitDrop(Drop* curr) { if (auto* call = curr->value->dynCast<Call>()) { info->droppedCalls[call] = getCurrentPointer(); } } + void visitRefFunc(RefFunc* curr) {+ // We can't modify another function in parallel.+ assert((*infoMap).count(curr->func));+ // Treat a ref.func as an unseen call, preventing us from changing the+ // function's type. If we did change it, it could be an observable+ // difference from the outside, if the reference escapes, for example.+ // TODO: look for actual escaping?+ // TODO: create a thunk for external uses that allow internal optimizations+ (*infoMap)[curr->func].hasUnseenCalls = true;+ }+ // main entry point void doWalkFunction(Function* func) {@@ -152,14 +173,22 @@ info = &((*infoMap)[func->name]); CFGWalker<DAEScanner, Visitor<DAEScanner>, DAEBlockInfo>::doWalkFunction( func);- // If there are relevant params, check if they are used. (If- // we can't optimize the function anyhow, there's no point.)+ // If there are relevant params, check if they are used. If we can't+ // optimize the function anyhow, there's no point (note that our check here+ // is technically racy - another thread could update hasUnseenCalls to true+ // around when we check it - but that just means that we might or might not+ // do some extra work, as we'll ignore the results later if we have unseen+ // calls. That is, the check for hasUnseenCalls here is just a minor+ // optimization to avoid pointless work. We can avoid that work if either+ // we know there is an unseen call before the parallel analysis that we are+ // part of, say if we are exported, or if another parallel function finds a+ // RefFunc to us and updates it before we check it). if (numParams > 0 && !info->hasUnseenCalls) {- findUnusedParams(func);+ findUnusedParams(); } } - void findUnusedParams(Function* func) {+ void findUnusedParams() { // Flow the incoming parameter values, see if they reach a read. // Once we've seen a parameter at a block, we need never consider it there // again.@@ -242,8 +271,9 @@ DAEFunctionInfoMap infoMap; // Ensure they all exist so the parallel threads don't modify the data // structure.- ModuleUtils::iterDefinedFunctions(- *module, [&](Function* func) { infoMap[func->name]; });+ for (auto& func : module->functions) {+ infoMap[func->name];+ } // Check the influence of the table and exports. for (auto& curr : module->exports) { if (curr->kind == ExternalKind::Function) {@@ -326,6 +356,9 @@ for (auto& pair : allCalls) { auto name = pair.first; auto& calls = pair.second;+ if (infoMap[name].hasUnseenCalls) {+ continue;+ } auto* func = module->getFunction(name); auto numParams = func->getNumParams(); if (numParams == 0) {
binaryen/src/passes/DeadCodeElimination.cpp view
@@ -28,8 +28,8 @@ // have no side effects. // -#include <ir/block-utils.h>-#include <ir/branch-utils.h>+#include <ir/iteration.h>+#include <ir/properties.h> #include <ir/type-updating.h> #include <pass.h> #include <vector>@@ -39,7 +39,9 @@ namespace wasm { struct DeadCodeElimination- : public WalkerPass<PostWalker<DeadCodeElimination>> {+ : public WalkerPass<+ PostWalker<DeadCodeElimination,+ UnifiedExpressionVisitor<DeadCodeElimination>>> { bool isFunctionParallel() override { return true; } Pass* create() override { return new DeadCodeElimination; }@@ -58,514 +60,116 @@ return expression; } - // whether the current code is actually reachable- bool reachable;- void doWalkFunction(Function* func) {- reachable = true; typeUpdater.walk(func->body); walk(func->body); } - std::set<Name> reachableBreaks;-- void addBreak(Name name) {- // we normally have already reduced unreachable code into (unreachable)- // nodes, so we would not get to this place at all anyhow, the breaking- // instruction itself would be removed. However, an exception are things- // like (block (result i32) (call $x) (unreachable)) , which has type i32- // despite not being exited.- // TODO: optimize such cases- if (reachable) {- reachableBreaks.insert(name);- }- }-- // if a child exists and is unreachable, we can replace ourselves with it- bool isDead(Expression* child) {- return child && child->type == Type::unreachable;- }-- // a similar check, assumes the child exists- bool isUnreachable(Expression* child) {- return child->type == Type::unreachable;- }-- // things that stop control flow-- void visitBreak(Break* curr) {- if (isDead(curr->value)) {- // the condition is evaluated last, so if the value was unreachable, the- // whole thing is- replaceCurrent(curr->value);- return;- }- if (isDead(curr->condition)) {- if (curr->value) {- auto* block = getModule()->allocator.alloc<Block>();- block->list.resize(2);- block->list[0] = drop(curr->value);- block->list[1] = curr->condition;- // if we previously returned a value, then this block- // must have the same type, so it fits in the ast- // properly. it ends in an unreachable- // anyhow, so that is ok.- block->finalize(curr->type);- replaceCurrent(block);- } else {- replaceCurrent(curr->condition);- }- return;- }- addBreak(curr->name);- if (!curr->condition) {- reachable = false;- }- }-- void visitSwitch(Switch* curr) {- if (isDead(curr->value)) {- replaceCurrent(curr->value);- return;- }- if (isUnreachable(curr->condition)) {- if (curr->value) {- auto* block = getModule()->allocator.alloc<Block>();- block->list.resize(2);- block->list[0] = drop(curr->value);- block->list[1] = curr->condition;- block->finalize(curr->type);- replaceCurrent(block);- } else {- replaceCurrent(curr->condition);+ void visitExpression(Expression* curr) {+ if (!Properties::isControlFlowStructure(curr)) {+ // Control flow structures require special handling, but others are+ // simple.+ if (curr->type == Type::unreachable) {+ // This may be dead code. Check if there is an unreachable child.+ bool hasUnreachableChild = false;+ for (auto* child : ChildIterator(curr)) {+ if (child->type == Type::unreachable) {+ hasUnreachableChild = true;+ break;+ }+ }+ if (hasUnreachableChild) {+ // This is indeed unreachable code, made unreachable by that child.+ Builder builder(*getModule());+ std::vector<Expression*> remainingChildren;+ bool afterUnreachable = false;+ for (auto* child : ChildIterator(curr)) {+ if (afterUnreachable) {+ typeUpdater.noteRecursiveRemoval(child);+ continue;+ }+ if (child->type == Type::unreachable) {+ remainingChildren.push_back(child);+ afterUnreachable = true;+ } else {+ remainingChildren.push_back(builder.makeDrop(child));+ }+ }+ if (remainingChildren.size() == 1) {+ replaceCurrent(remainingChildren[0]);+ } else {+ replaceCurrent(builder.makeBlock(remainingChildren));+ }+ } } return; }- for (auto target : curr->targets) {- addBreak(target);- }- addBreak(curr->default_);- reachable = false;- }-- void visitReturn(Return* curr) {- if (isDead(curr->value)) {- replaceCurrent(curr->value);- return;- }- reachable = false;- }-- void visitUnreachable(Unreachable* curr) { reachable = false; }-- void visitBlock(Block* curr) {- auto& list = curr->list;- // if we are currently unreachable (before we take into account- // breaks to the block) then a child may be unreachable, and we- // can shorten- if (!reachable && list.size() > 1) {- // to do here: nothing to remove after it)- for (Index i = 0; i < list.size() - 1; i++) {+ // This is a control flow structure.+ if (auto* block = curr->dynCast<Block>()) {+ auto& list = block->list;+ // The index from which to remove, which is one after the first+ // unreachable instruction. Note that 0 is not a valid value, so we can+ // use it as such.+ Index removeFromHere = 0;+ for (Index i = 0; i < list.size(); i++) { if (list[i]->type == Type::unreachable) {- list.resize(i + 1);+ removeFromHere = i + 1; break; } }- }- if (curr->name.is()) {- reachable = reachable || reachableBreaks.count(curr->name);- reachableBreaks.erase(curr->name);- }- if (list.size() == 1 && isUnreachable(list[0])) {- replaceCurrent(- BlockUtils::simplifyToContentsWithPossibleTypeChange(curr, this));- } else {- // the block may have had a type, but can now be unreachable, which allows- // more reduction outside- typeUpdater.maybeUpdateTypeToUnreachable(curr);- }- }-- void visitLoop(Loop* curr) {- if (curr->name.is()) {- reachableBreaks.erase(curr->name);- }- if (isUnreachable(curr->body) &&- !BranchUtils::BranchSeeker::has(curr->body, curr->name)) {- replaceCurrent(curr->body);- return;- }- }-- // ifs and trys need special handling: only one of (if body and else body /- // try body and catch body) should be reachable to make the whole of (if /- // try) to be reachable.-- // stack of reachable state, for forking and joining- std::vector<bool> ifStack;- std::vector<bool> tryStack;-- static void doAfterIfCondition(DeadCodeElimination* self,- Expression** currp) {- self->ifStack.push_back(self->reachable);- }-- static void doAfterIfElseTrue(DeadCodeElimination* self, Expression** currp) {- assert((*currp)->cast<If>()->ifFalse);- bool reachableBefore = self->ifStack.back();- self->ifStack.pop_back();- self->ifStack.push_back(self->reachable);- self->reachable = reachableBefore;- }-- void visitIf(If* curr) {- // the ifStack has the branch that joins us, either from before if just an- // if, or the ifTrue if an if-else- reachable = reachable || ifStack.back();- ifStack.pop_back();- if (isUnreachable(curr->condition)) {- replaceCurrent(curr->condition);- }- // the if may have had a type, but can now be unreachable, which allows more- // reduction outside- typeUpdater.maybeUpdateTypeToUnreachable(curr);- }-- static void doBeforeTryBody(DeadCodeElimination* self, Expression** currp) {- self->tryStack.push_back(self->reachable);- }-- static void doAfterTryBody(DeadCodeElimination* self, Expression** currp) {- bool reachableBefore = self->tryStack.back();- self->tryStack.pop_back();- self->tryStack.push_back(self->reachable);- self->reachable = reachableBefore;- }-- void visitTry(Try* curr) {- // the tryStack has the branch that joins us- reachable = reachable || tryStack.back();- tryStack.pop_back();- // the try may have had a type, but can now be unreachable, which allows- // more reduction outside- typeUpdater.maybeUpdateTypeToUnreachable(curr);- }-- void visitThrow(Throw* curr) { reachable = false; }-- void visitRethrow(Rethrow* curr) { reachable = false; }-- void visitBrOnExn(BrOnExn* curr) {- if (isDead(curr->exnref)) {- replaceCurrent(curr->exnref);- return;- }- addBreak(curr->name);- }-- static void scan(DeadCodeElimination* self, Expression** currp) {- auto* curr = *currp;- if (!self->reachable) {-// convert to an unreachable safely-#define DELEGATE(CLASS_TO_VISIT) \- { \- auto* parent = self->typeUpdater.parents[curr]; \- self->typeUpdater.noteRecursiveRemoval(curr); \- ExpressionManipulator::convert<CLASS_TO_VISIT, Unreachable>( \- static_cast<CLASS_TO_VISIT*>(curr)); \- self->typeUpdater.noteAddition(curr, parent); \- break; \- }- switch (curr->_id) {- case Expression::Id::BlockId:- DELEGATE(Block);- case Expression::Id::IfId:- DELEGATE(If);- case Expression::Id::LoopId:- DELEGATE(Loop);- case Expression::Id::BreakId:- DELEGATE(Break);- case Expression::Id::SwitchId:- DELEGATE(Switch);- case Expression::Id::CallId:- DELEGATE(Call);- case Expression::Id::CallIndirectId:- DELEGATE(CallIndirect);- case Expression::Id::LocalGetId:- DELEGATE(LocalGet);- case Expression::Id::LocalSetId:- DELEGATE(LocalSet);- case Expression::Id::GlobalGetId:- DELEGATE(GlobalGet);- case Expression::Id::GlobalSetId:- DELEGATE(GlobalSet);- case Expression::Id::LoadId:- DELEGATE(Load);- case Expression::Id::StoreId:- DELEGATE(Store);- case Expression::Id::ConstId:- DELEGATE(Const);- case Expression::Id::UnaryId:- DELEGATE(Unary);- case Expression::Id::BinaryId:- DELEGATE(Binary);- case Expression::Id::SelectId:- DELEGATE(Select);- case Expression::Id::DropId:- DELEGATE(Drop);- case Expression::Id::ReturnId:- DELEGATE(Return);- case Expression::Id::MemorySizeId:- DELEGATE(MemorySize);- case Expression::Id::MemoryGrowId:- DELEGATE(MemoryGrow);- case Expression::Id::NopId:- DELEGATE(Nop);- case Expression::Id::UnreachableId:- break;- case Expression::Id::AtomicCmpxchgId:- DELEGATE(AtomicCmpxchg);- case Expression::Id::AtomicRMWId:- DELEGATE(AtomicRMW);- case Expression::Id::AtomicWaitId:- DELEGATE(AtomicWait);- case Expression::Id::AtomicNotifyId:- DELEGATE(AtomicNotify);- case Expression::Id::AtomicFenceId:- DELEGATE(AtomicFence);- case Expression::Id::SIMDExtractId:- DELEGATE(SIMDExtract);- case Expression::Id::SIMDReplaceId:- DELEGATE(SIMDReplace);- case Expression::Id::SIMDShuffleId:- DELEGATE(SIMDShuffle);- case Expression::Id::SIMDTernaryId:- DELEGATE(SIMDTernary);- case Expression::Id::SIMDShiftId:- DELEGATE(SIMDShift);- case Expression::Id::SIMDLoadId:- DELEGATE(SIMDLoad);- case Expression::Id::MemoryInitId:- DELEGATE(MemoryInit);- case Expression::Id::DataDropId:- DELEGATE(DataDrop);- case Expression::Id::MemoryCopyId:- DELEGATE(MemoryCopy);- case Expression::Id::MemoryFillId:- DELEGATE(MemoryFill);- case Expression::Id::PopId:- DELEGATE(Pop);- case Expression::Id::RefNullId:- DELEGATE(RefNull);- case Expression::Id::RefIsNullId:- DELEGATE(RefIsNull);- case Expression::Id::RefFuncId:- DELEGATE(RefFunc);- case Expression::Id::RefEqId:- DELEGATE(RefEq);- case Expression::Id::TryId:- DELEGATE(Try);- case Expression::Id::ThrowId:- DELEGATE(Throw);- case Expression::Id::RethrowId:- DELEGATE(Rethrow);- case Expression::Id::BrOnExnId:- DELEGATE(BrOnExn);- case Expression::Id::TupleMakeId:- DELEGATE(TupleMake);- case Expression::Id::TupleExtractId:- DELEGATE(TupleExtract);- case Expression::Id::I31NewId:- DELEGATE(I31New);- case Expression::Id::I31GetId:- DELEGATE(I31Get);- case Expression::Id::RefTestId:- DELEGATE(RefTest);- case Expression::Id::RefCastId:- DELEGATE(RefCast);- case Expression::Id::BrOnCastId:- DELEGATE(BrOnCast);- case Expression::Id::RttCanonId:- DELEGATE(RttCanon);- case Expression::Id::RttSubId:- DELEGATE(RttSub);- case Expression::Id::StructNewId:- DELEGATE(StructNew);- case Expression::Id::StructGetId:- DELEGATE(StructGet);- case Expression::Id::StructSetId:- DELEGATE(StructSet);- case Expression::Id::ArrayNewId:- DELEGATE(ArrayNew);- case Expression::Id::ArrayGetId:- DELEGATE(ArrayGet);- case Expression::Id::ArraySetId:- DELEGATE(ArraySet);- case Expression::Id::ArrayLenId:- DELEGATE(ArrayLen);- case Expression::Id::InvalidId:- WASM_UNREACHABLE("unimp");- case Expression::Id::NumExpressionIds:- WASM_UNREACHABLE("unimp");- }-#undef DELEGATE- return;- }- if (curr->is<If>()) {- self->pushTask(DeadCodeElimination::doVisitIf, currp);- if (curr->cast<If>()->ifFalse) {- self->pushTask(DeadCodeElimination::scan, &curr->cast<If>()->ifFalse);- self->pushTask(DeadCodeElimination::doAfterIfElseTrue, currp);- }- self->pushTask(DeadCodeElimination::scan, &curr->cast<If>()->ifTrue);- self->pushTask(DeadCodeElimination::doAfterIfCondition, currp);- self->pushTask(DeadCodeElimination::scan, &curr->cast<If>()->condition);- } else if (curr->is<Try>()) {- self->pushTask(DeadCodeElimination::doVisitTry, currp);- self->pushTask(DeadCodeElimination::scan, &curr->cast<Try>()->catchBody);- self->pushTask(DeadCodeElimination::doAfterTryBody, currp);- self->pushTask(DeadCodeElimination::scan, &curr->cast<Try>()->body);- self->pushTask(DeadCodeElimination::doBeforeTryBody, currp);- } else {- super::scan(self, currp);- }- }-- // other things-- // we don't need to drop unreachable nodes- Expression* drop(Expression* toDrop) {- if (toDrop->type == Type::unreachable) {- return toDrop;- }- return Builder(*getModule()).makeDrop(toDrop);- }-- template<typename T> Expression* handleCall(T* curr) {- for (Index i = 0; i < curr->operands.size(); i++) {- if (isUnreachable(curr->operands[i])) {- if (i > 0) {- auto* block = getModule()->allocator.alloc<Block>();- Index newSize = i + 1;- block->list.resize(newSize);- Index j = 0;- for (; j < newSize; j++) {- block->list[j] = drop(curr->operands[j]);- }- block->finalize(curr->type);- return replaceCurrent(block);- } else {- return replaceCurrent(curr->operands[i]);+ if (removeFromHere != 0) {+ for (Index i = removeFromHere; i < list.size(); i++) {+ typeUpdater.noteRecursiveRemoval(list[i]); }+ list.resize(removeFromHere);+ if (list.size() == 1 && list[0]->is<Unreachable>()) {+ replaceCurrent(list[0]);+ return;+ } }- }- return curr;- }-- void visitCall(Call* curr) {- handleCall(curr);- if (curr->isReturn) {- reachable = false;- }- }-- void visitCallIndirect(CallIndirect* curr) {- if (handleCall(curr) != curr) {- return;- }- if (isUnreachable(curr->target)) {- auto* block = getModule()->allocator.alloc<Block>();- for (auto* operand : curr->operands) {- block->list.push_back(drop(operand));+ // Finally, if there is no need for a concrete type (which is when there+ // is one marked, but nothing breaks to it, and also the block does not+ // have a concrete value flowing out) then remove it, which may allow+ // more reduction.+ if (block->type.isConcrete() && list.back()->type == Type::unreachable &&+ !typeUpdater.hasBreaks(block)) {+ typeUpdater.changeType(block, Type::unreachable); }- block->list.push_back(curr->target);- block->finalize(curr->type);- replaceCurrent(block);- }- if (curr->isReturn) {- reachable = false;- }- }-- // Append the reachable operands of the current node to a block, and replace- // it with the block- void blockifyReachableOperands(std::vector<Expression*>&& list, Type type) {- for (size_t i = 0; i < list.size(); ++i) {- auto* elem = list[i];- if (isUnreachable(elem)) {- auto* replacement = elem;- if (i > 0) {- auto* block = getModule()->allocator.alloc<Block>();- for (size_t j = 0; j < i; ++j) {- block->list.push_back(drop(list[j]));- }- block->list.push_back(list[i]);- block->finalize(type);- replacement = block;+ } else if (auto* iff = curr->dynCast<If>()) {+ if (iff->condition->type == Type::unreachable) {+ typeUpdater.noteRecursiveRemoval(iff->ifTrue);+ if (iff->ifFalse) {+ typeUpdater.noteRecursiveRemoval(iff->ifFalse); }- replaceCurrent(replacement);+ replaceCurrent(iff->condition); return; }+ // If both arms are unreachable, there is no need for a concrete type,+ // which may allow more reduction.+ if (iff->type != Type::unreachable && iff->ifFalse &&+ iff->ifTrue->type == Type::unreachable &&+ iff->ifFalse->type == Type::unreachable) {+ typeUpdater.changeType(iff, Type::unreachable);+ }+ } else if (auto* loop = curr->dynCast<Loop>()) {+ // The loop body may have unreachable type if it branches back to the+ // loop top, for example. The only case we look for here is where we've+ // already removed the entire body as dead code.+ if (loop->body->is<Unreachable>()) {+ replaceCurrent(loop->body);+ }+ } else if (auto* tryy = curr->dynCast<Try>()) {+ // If both try body and catch body are unreachable, there is no need for a+ // concrete type, which may allow more reduction.+ if (tryy->type != Type::unreachable &&+ tryy->body->type == Type::unreachable &&+ tryy->catchBody->type == Type::unreachable) {+ typeUpdater.changeType(tryy, Type::unreachable);+ }+ } else {+ WASM_UNREACHABLE("unimplemented DCE control flow structure"); } }-- void visitLocalSet(LocalSet* curr) {- blockifyReachableOperands({curr->value}, curr->type);- }-- void visitGlobalSet(GlobalSet* curr) {- blockifyReachableOperands({curr->value}, curr->type);- }-- void visitLoad(Load* curr) {- blockifyReachableOperands({curr->ptr}, curr->type);- }-- void visitStore(Store* curr) {- blockifyReachableOperands({curr->ptr, curr->value}, curr->type);- }-- void visitAtomicRMW(AtomicRMW* curr) {- blockifyReachableOperands({curr->ptr, curr->value}, curr->type);- }-- void visitAtomicCmpxchg(AtomicCmpxchg* curr) {- blockifyReachableOperands({curr->ptr, curr->expected, curr->replacement},- curr->type);- }-- void visitUnary(Unary* curr) {- blockifyReachableOperands({curr->value}, curr->type);- }-- void visitBinary(Binary* curr) {- blockifyReachableOperands({curr->left, curr->right}, curr->type);- }-- void visitSelect(Select* curr) {- blockifyReachableOperands({curr->ifTrue, curr->ifFalse, curr->condition},- curr->type);- }-- void visitDrop(Drop* curr) {- blockifyReachableOperands({curr->value}, curr->type);- }-- void visitMemorySize(MemorySize* curr) {}-- void visitMemoryGrow(MemoryGrow* curr) {- blockifyReachableOperands({curr->delta}, curr->type);- }-- void visitRefIsNull(RefIsNull* curr) {- blockifyReachableOperands({curr->value}, curr->type);- }-- void visitRefEq(RefEq* curr) {- blockifyReachableOperands({curr->left, curr->right}, curr->type);- }-- void visitFunction(Function* curr) { assert(reachableBreaks.size() == 0); } }; Pass* createDeadCodeEliminationPass() { return new DeadCodeElimination(); }
binaryen/src/passes/Directize.cpp view
@@ -22,7 +22,6 @@ #include <unordered_map> -#include "asm_v_wasm.h" #include "ir/table-utils.h" #include "ir/utils.h" #include "pass.h"@@ -42,6 +41,9 @@ FunctionDirectizer(TableUtils::FlatTable* flatTable) : flatTable(flatTable) {} void visitCallIndirect(CallIndirect* curr) {+ if (!flatTable) {+ return;+ } if (auto* c = curr->target->dynCast<Const>()) { Index index = c->value.geti32(); // If the index is invalid, or the type is wrong, we can@@ -69,6 +71,15 @@ } } + void visitCallRef(CallRef* curr) {+ if (auto* ref = curr->target->dynCast<RefFunc>()) {+ // We know the target!+ replaceCurrent(+ Builder(*getModule())+ .makeCall(ref->func, curr->operands, curr->type, curr->isReturn));+ }+ }+ void doWalkFunction(Function* func) { WalkerPass<PostWalker<FunctionDirectizer>>::doWalkFunction(func); if (changedTypes) {@@ -77,7 +88,9 @@ } private:+ // If null, then we cannot optimize call_indirects. TableUtils::FlatTable* flatTable;+ bool changedTypes = false; void replaceWithUnreachable(CallIndirect* call) {@@ -93,23 +106,31 @@ struct Directize : public Pass { void run(PassRunner* runner, Module* module) override {+ bool canOptimizeCallIndirect = true;+ TableUtils::FlatTable flatTable(module->table); if (!module->table.exists) {- return;- }- if (module->table.imported()) {- return;- }- for (auto& ex : module->exports) {- if (ex->kind == ExternalKind::Table) {- return;+ canOptimizeCallIndirect = false;+ } else if (module->table.imported()) {+ canOptimizeCallIndirect = false;+ } else {+ for (auto& ex : module->exports) {+ if (ex->kind == ExternalKind::Table) {+ canOptimizeCallIndirect = false;+ } }+ if (!flatTable.valid) {+ canOptimizeCallIndirect = false;+ } }- TableUtils::FlatTable flatTable(module->table);- if (!flatTable.valid) {+ // Without typed function references, all we can do is optimize table+ // accesses, so if we can't do that, stop.+ if (!canOptimizeCallIndirect &&+ !module->features.hasTypedFunctionReferences()) { return; } // The table exists and is constant, so this is possible.- FunctionDirectizer(&flatTable).run(runner, module);+ FunctionDirectizer(canOptimizeCallIndirect ? &flatTable : nullptr)+ .run(runner, module); } };
binaryen/src/passes/DuplicateImportElimination.cpp view
@@ -20,7 +20,6 @@ // TODO: non-function imports too // -#include "asm_v_wasm.h" #include "ir/import-utils.h" #include "opt-utils.h" #include "pass.h"
− binaryen/src/passes/EmscriptenPIC.cpp
@@ -1,221 +0,0 @@-/*- * Copyright 2020 WebAssembly Community Group participants- *- * Licensed under the Apache License, Version 2.0 (the "License");- * you may not use this file except in compliance with the License.- * You may obtain a copy of the License at- *- * http://www.apache.org/licenses/LICENSE-2.0- *- * Unless required by applicable law or agreed to in writing, software- * distributed under the License is distributed on an "AS IS" BASIS,- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.- * See the License for the specific language governing permissions and- * limitations under the License.- */--//-// Convert LLVM PIC ABI to emscripten ABI-//-// When generating -fPIC code llvm will generate imports call GOT.mem and-// GOT.func in order to access the addresses of external global data and-// functions.-//-// However emscripten uses a different ABI where function and data addresses-// are available at runtime via special `g$foo` and `fp$bar` function calls.-//-// Here we internalize all such wasm globals and generte code that sets their-// value based on the result of call `g$foo` and `fp$bar` functions at runtime.-//-// A function called `__assign_got_enties` is generated by this pass that-// performs all the assignments.-//--#include "abi/js.h"-#include "asm_v_wasm.h"-#include "ir/import-utils.h"-#include "ir/table-utils.h"-#include "pass.h"-#include "shared-constants.h"-#include "support/debug.h"--#define DEBUG_TYPE "emscripten-pic"--namespace wasm {--static Global* ensureGlobalImport(Module* module, Name name, Type type) {- // See if its already imported.- // FIXME: O(N)- ImportInfo info(*module);- if (auto* g = info.getImportedGlobal(ENV, name)) {- return g;- }- // Failing that create a new import.- auto import = new Global;- import->name = name;- import->module = ENV;- import->base = name;- import->type = type;- module->addGlobal(import);- return import;-}--static Function*-ensureFunctionImport(Module* module, Name name, Signature sig) {- // See if its already imported.- // FIXME: O(N)- ImportInfo info(*module);- if (auto* f = info.getImportedFunction(ENV, name)) {- return f;- }- // Failing that create a new import.- auto import = new Function;- import->name = name;- import->module = ENV;- import->base = name;- import->sig = sig;- module->addFunction(import);- return import;-}--struct EmscriptenPIC : public WalkerPass<PostWalker<EmscriptenPIC>> {-- EmscriptenPIC(bool sideModule) : sideModule(sideModule) {}-- void visitGlobal(Global* curr) {- if (!curr->imported()) {- return;- }- if (curr->module == "GOT.func") {- gotFuncEntries.push_back(curr);- } else if (curr->module == "GOT.mem") {- gotMemEntries.push_back(curr);- } else {- return;- }- // Make this an internal, non-imported, global.- curr->module.clear();- curr->init = Builder(*getModule()).makeConst(int32_t(0));- }-- void visitModule(Module* module) {- BYN_TRACE("generateAssignGOTEntriesFunction\n");- if (!gotFuncEntries.size() && !gotMemEntries.size()) {- return;- }-- Builder builder(*getModule());- Function* assignFunc = builder.makeFunction(- ASSIGN_GOT_ENTRIES, std::vector<NameType>{}, Type::none, {});- Block* block = builder.makeBlock();- assignFunc->body = block;-- bool hasSingleMemorySegment =- module->memory.exists && module->memory.segments.size() == 1;-- for (Global* g : gotMemEntries) {- // If this global is defined in this module, we export its address- // relative to the relocatable memory. If we are in a main module, we can- // just use that location (since if other modules have this symbol too, we- // will "win" as we are loaded first). Otherwise, import a g$ getter. Note- // that this depends on memory having a single segment, so we know the- // offset, and that the export is a global.- auto base = g->base;- if (hasSingleMemorySegment && !sideModule) {- if (auto* ex = module->getExportOrNull(base)) {- if (ex->kind == ExternalKind::Global) {- // The base relative to which we are computed is the offset of the- // singleton segment.- auto* relativeBase = ExpressionManipulator::copy(- module->memory.segments[0].offset, *module);-- auto* offset = builder.makeGlobalGet(- ex->value, module->getGlobal(ex->value)->type);- auto* add = builder.makeBinary(AddInt32, relativeBase, offset);- GlobalSet* globalSet = builder.makeGlobalSet(g->name, add);- block->list.push_back(globalSet);- continue;- }- }- }- Name getter(std::string("g$") + base.c_str());- ensureFunctionImport(module, getter, Signature(Type::none, Type::i32));- Expression* call = builder.makeCall(getter, {}, Type::i32);- GlobalSet* globalSet = builder.makeGlobalSet(g->name, call);- block->list.push_back(globalSet);- }-- ImportInfo importInfo(*module);-- // We may have to add things to the table.- Global* tableBase = nullptr;-- for (Global* g : gotFuncEntries) {- // The function has to exist either as export or an import.- // Note that we don't search for the function by name since its internal- // name may be different.- auto* ex = module->getExportOrNull(g->base);- // If this is exported then it must be one of the functions implemented- // here, and if this is a main module, then we can simply place the- // function in the table: the loader will see it there and resolve all- // other uses to this one.- if (ex && !sideModule) {- assert(ex->kind == ExternalKind::Function);- auto* f = module->getFunction(ex->value);- if (f->imported()) {- Fatal() << "GOT.func entry is both imported and exported: "- << g->base;- }- // The base relative to which we are computed is the offset of the- // singleton segment, which we must ensure exists- if (!tableBase) {- tableBase = ensureGlobalImport(module, TABLE_BASE, Type::i32);- }- if (!module->table.exists) {- module->table.exists = true;- }- if (module->table.segments.empty()) {- module->table.segments.resize(1);- module->table.segments[0].offset =- builder.makeGlobalGet(tableBase->name, Type::i32);- }- auto tableIndex =- TableUtils::getOrAppend(module->table, f->name, *module);- auto* c = LiteralUtils::makeFromInt32(tableIndex, Type::i32, *module);- auto* getBase = builder.makeGlobalGet(tableBase->name, Type::i32);- auto* add = builder.makeBinary(AddInt32, getBase, c);- auto* globalSet = builder.makeGlobalSet(g->name, add);- block->list.push_back(globalSet);- continue;- }- // This is imported or in a side module. Create an fp$ import to get the- // function table index from the dynamic loader.- auto* f = importInfo.getImportedFunction(ENV, g->base);- if (!f) {- if (!ex) {- Fatal() << "GOT.func entry with no import/export: " << g->base;- }- f = module->getFunction(ex->value);- }- Name getter(- (std::string("fp$") + g->base.c_str() + std::string("$") + getSig(f))- .c_str());- ensureFunctionImport(module, getter, Signature(Type::none, Type::i32));- auto* call = builder.makeCall(getter, {}, Type::i32);- auto* globalSet = builder.makeGlobalSet(g->name, call);- block->list.push_back(globalSet);- }-- module->addFunction(assignFunc);- }-- std::vector<Global*> gotFuncEntries;- std::vector<Global*> gotMemEntries;- bool sideModule;-};--Pass* createEmscriptenPICPass() { return new EmscriptenPIC(true); }--Pass* createEmscriptenPICMainModulePass() { return new EmscriptenPIC(false); }--} // namespace wasm
binaryen/src/passes/Flatten.cpp view
@@ -17,6 +17,8 @@ // // Flattens code into "Flat IR" form. See ir/flat.h. //+// TODO: handle non-nullability+// #include <ir/branch-utils.h> #include <ir/effects.h>
binaryen/src/passes/FuncCastEmulation.cpp view
@@ -28,7 +28,8 @@ // params must be identical, i.e., the "ABI" must match. // -#include <asm_v_wasm.h>+#include <string>+ #include <ir/literal-utils.h> #include <pass.h> #include <wasm-builder.h>@@ -36,11 +37,6 @@ namespace wasm { -// This should be enough for everybody. (As described above, we need this-// to match when dynamically linking, and also dynamic linking is why we-// can't just detect this automatically in the module we see.)-static const int NUM_PARAMS = 16;- // Converts a value to the ABI type of i64. static Expression* toABI(Expression* value, Module* module) { Builder builder(*module);@@ -134,20 +130,23 @@ : public WalkerPass<PostWalker<ParallelFuncCastEmulation>> { bool isFunctionParallel() override { return true; } - Pass* create() override { return new ParallelFuncCastEmulation(ABIType); }+ Pass* create() override {+ return new ParallelFuncCastEmulation(ABIType, numParams);+ } - ParallelFuncCastEmulation(Signature ABIType) : ABIType(ABIType) {}+ ParallelFuncCastEmulation(Signature ABIType, Index numParams)+ : ABIType(ABIType), numParams(numParams) {} void visitCallIndirect(CallIndirect* curr) {- if (curr->operands.size() > NUM_PARAMS) {- Fatal() << "FuncCastEmulation::NUM_PARAMS needs to be at least "+ if (curr->operands.size() > numParams) {+ Fatal() << "max-func-params needs to be at least " << curr->operands.size(); } for (Expression*& operand : curr->operands) { operand = toABI(operand, getModule()); } // Add extra operands as needed.- while (curr->operands.size() < NUM_PARAMS) {+ while (curr->operands.size() < numParams) { curr->operands.push_back(LiteralUtils::makeZero(Type::i64, *getModule())); } // Set the new types@@ -162,20 +161,22 @@ private: // The signature of a call with the right params and return Signature ABIType;+ Index numParams; }; struct FuncCastEmulation : public Pass { void run(PassRunner* runner, Module* module) override {+ Index numParams =+ std::stoul(runner->options.getArgumentOrDefault("max-func-params", "16")); // we just need the one ABI function type for all indirect calls- Signature ABIType(Type(std::vector<Type>(NUM_PARAMS, Type::i64)),- Type::i64);+ Signature ABIType(Type(std::vector<Type>(numParams, Type::i64)), Type::i64); // Add a thunk for each function in the table, and do the call through it. std::unordered_map<Name, Name> funcThunks; for (auto& segment : module->table.segments) { for (auto& name : segment.data) { auto iter = funcThunks.find(name); if (iter == funcThunks.end()) {- auto thunk = makeThunk(name, module);+ auto thunk = makeThunk(name, module, numParams); funcThunks[name] = thunk; name = thunk; } else {@@ -184,12 +185,12 @@ } } // update call_indirects- ParallelFuncCastEmulation(ABIType).run(runner, module);+ ParallelFuncCastEmulation(ABIType, numParams).run(runner, module); } private: // Creates a thunk for a function, casting args and return value as needed.- Name makeThunk(Name name, Module* module) {+ Name makeThunk(Name name, Module* module, Index numParams) { Name thunk = std::string("byn$fpcast-emu$") + name.str; if (module->getFunctionOrNull(thunk)) { Fatal() << "FuncCastEmulation::makeThunk seems a thunk name already in "@@ -207,15 +208,15 @@ } auto* call = builder.makeCall(name, callOperands, type); std::vector<Type> thunkParams;- for (Index i = 0; i < NUM_PARAMS; i++) {+ for (Index i = 0; i < numParams; i++) { thunkParams.push_back(Type::i64); }- auto* thunkFunc =+ auto thunkFunc = builder.makeFunction(thunk, Signature(Type(thunkParams), Type::i64), {}, // no vars toABI(call, module));- module->addFunction(thunkFunc);+ module->addFunction(std::move(thunkFunc)); return thunk; } };
binaryen/src/passes/GenerateDynCalls.cpp view
@@ -120,7 +120,7 @@ for (const auto& param : sig.params) { params.emplace_back(std::to_string(p++), param); }- Function* f = builder.makeFunction(name, std::move(params), sig.results, {});+ auto f = builder.makeFunction(name, std::move(params), sig.results, {}); Expression* fptr = builder.makeLocalGet(0, Type::i32); std::vector<Expression*> args; Index i = 0;@@ -130,8 +130,8 @@ Expression* call = builder.makeCallIndirect(fptr, args, sig); f->body = call; - wasm->addFunction(f);- exportFunction(*wasm, f->name, true);+ wasm->addFunction(std::move(f));+ exportFunction(*wasm, name, true); } Pass* createGenerateDynCallsPass() { return new GenerateDynCalls(false); }
binaryen/src/passes/I64ToI32Lowering.cpp view
@@ -22,7 +22,6 @@ // #include "abi/js.h"-#include "asmjs/shared-constants.h" #include "emscripten-optimizer/istring.h" #include "ir/flat.h" #include "ir/iteration.h"@@ -114,11 +113,10 @@ } originallyI64Globals.insert(curr->name); curr->type = Type::i32;- auto* high = builder->makeGlobal(makeHighName(curr->name),- Type::i32,- builder->makeConst(int32_t(0)),- Builder::Mutable);- module->addGlobal(high);+ auto high = builder->makeGlobal(makeHighName(curr->name),+ Type::i32,+ builder->makeConst(int32_t(0)),+ Builder::Mutable); if (curr->imported()) { Fatal() << "TODO: imported i64 globals"; } else {@@ -135,6 +133,7 @@ } curr->init->type = Type::i32; }+ module->addGlobal(std::move(high)); } // For functions that return 64-bit values, we use this global variable@@ -219,6 +218,9 @@ // returns nullptr; template<typename T> T* visitGenericCall(T* curr, BuilderFunc<T> callBuilder) {+ if (handleUnreachable(curr)) {+ return nullptr;+ } bool fixed = false; std::vector<Expression*> args; for (auto* e : curr->operands) {
binaryen/src/passes/Inlining.cpp view
@@ -17,8 +17,6 @@ // // Inlining. //-// This uses some simple heuristics to decide when to inline.-// // Two versions are provided: inlining and inlining-optimizing. You // probably want the optimizing version, which will optimize locations // we inlined into, as inlining by itself creates a block to house the@@ -62,25 +60,21 @@ // See pass.h for how defaults for these options were chosen. bool worthInlining(PassOptions& options) {- // if it's big, it's just not worth doing (TODO: investigate more)- if (size > options.inlining.flexibleInlineMaxSize) {- return false;- }- // if it's so small we have a guarantee that after we optimize the- // size will not increase, inline it+ // If it's small enough that we always want to inline such things, do so. if (size <= options.inlining.alwaysInlineMaxSize) { return true; }- // if it has one use, then inlining it would likely reduce code size- // since we are just moving code around, + optimizing, so worth it- // if small enough that we are pretty sure its ok- // FIXME: move this check to be first in this function, since we should- // return true if oneCallerInlineMaxSize is bigger than- // flexibleInlineMaxSize (which it typically should be).+ // If it has one use, then inlining it would likely reduce code size, at+ // least for reasonable function sizes. if (refs == 1 && !usedGlobally && size <= options.inlining.oneCallerInlineMaxSize) { return true; }+ // If it's so big that we have no flexible options that could allow it,+ // do not inline.+ if (size > options.inlining.flexibleInlineMaxSize) {+ return false;+ } // More than one use, so we can't eliminate it after inlining, // so only worth it if we really care about speed and don't care // about size. First, check if it has calls. In that case it is not@@ -217,6 +211,12 @@ handleReturnCall(curr, curr->sig.results); } }+ void visitCallRef(CallRef* curr) {+ if (curr->isReturn) {+ handleReturnCall(curr,+ curr->target->type.getHeapType().getSignature().results);+ }+ } void visitLocalGet(LocalGet* curr) { curr->index = localMapping[curr->index]; }@@ -326,7 +326,6 @@ PassRunner runner(module); FunctionInfoScanner(&infos).run(&runner, module); // fill in global uses- // anything exported or used in a table should not be inlined for (auto& ex : module->exports) { if (ex->kind == ExternalKind::Function) { infos[ex->value].usedGlobally = true;@@ -336,6 +335,16 @@ for (auto name : segment.data) { infos[name].usedGlobally = true; }+ }+ for (auto& global : module->globals) {+ if (!global->imported()) {+ for (auto* ref : FindAll<RefFunc>(global->init).list) {+ infos[ref->func].usedGlobally = true;+ }+ }+ }+ if (module->start.is()) {+ infos[module->start].usedGlobally = true; } }
binaryen/src/passes/InstrumentLocals.cpp view
@@ -43,7 +43,6 @@ // ) // ) -#include "asm_v_wasm.h" #include "asmjs/shared-constants.h" #include "shared-constants.h" #include <pass.h>@@ -135,8 +134,13 @@ Builder builder(*getModule()); Name import;+ auto type = curr->value->type;+ if (type.isFunction() && type != Type::funcref) {+ // FIXME: support typed function references+ return;+ } TODO_SINGLE_COMPOUND(curr->value->type);- switch (curr->value->type.getBasic()) {+ switch (type.getBasic()) { case Type::i32: import = set_i32; break;@@ -171,7 +175,7 @@ break; case Type::unreachable: return; // nothing to do here- case Type::none:+ default: WASM_UNREACHABLE("unexpected type"); } curr->value = builder.makeCall(import,
binaryen/src/passes/InstrumentMemory.cpp view
@@ -52,7 +52,6 @@ // ) // ) -#include "asm_v_wasm.h" #include "asmjs/shared-constants.h" #include "shared-constants.h" #include <pass.h>
binaryen/src/passes/LegalizeJSInterface.cpp view
@@ -30,7 +30,6 @@ // table even to a signature that is not legal. // -#include "asm_v_wasm.h" #include "asmjs/shared-constants.h" #include "ir/import-utils.h" #include "ir/literal-utils.h"@@ -54,7 +53,7 @@ .getArgumentOrDefault("legalize-js-interface-export-originals", "") .empty(); // for each illegal export, we must export a legalized stub instead- std::vector<Export*> newExports;+ std::vector<std::unique_ptr<Export>> newExports; for (auto& ex : module->exports) { if (ex->kind == ExternalKind::Function) { // if it's an import, ignore it@@ -82,8 +81,8 @@ } } }- for (auto* ex : newExports) {- module->addExport(ex);+ for (auto& ex : newExports) {+ module->addExport(std::move(ex)); } // Avoid iterator invalidation later. std::vector<Function*> originalFunctions;
binaryen/src/passes/LogExecution.cpp view
@@ -28,7 +28,6 @@ // value. // -#include "asm_v_wasm.h" #include "asmjs/shared-constants.h" #include "shared-constants.h" #include <pass.h>
binaryen/src/passes/LoopInvariantCodeMotion.cpp view
@@ -114,17 +114,20 @@ } if (interestingToMove(curr)) { // Let's see if we can move this out.- // Global side effects would prevent this - we might end up+ // Global state changes would prevent this - we might end up // executing them just once. // And we must also move across anything not moved out already, // so check for issues there too. // The rest of the loop's effects matter too, we must also // take into account global state like interacting loads and // stores.- bool unsafeToMove = effects.hasGlobalSideEffects() ||- effectsSoFar.invalidates(effects) ||- (effects.noticesGlobalSideEffects() &&- loopEffects.hasGlobalSideEffects());+ bool unsafeToMove =+ effects.writesGlobalState() || effectsSoFar.invalidates(effects) ||+ (effects.readsGlobalState() && loopEffects.writesGlobalState());+ // TODO: look into optimizing this with exceptions. for now, disallow+ if (effects.throws || loopEffects.throws) {+ unsafeToMove = true;+ } if (!unsafeToMove) { // So far so good. Check if our local dependencies are all // outside of the loop, in which case everything is good -
+ binaryen/src/passes/Memory64Lowering.cpp view
@@ -0,0 +1,101 @@+/*+ * Copyright 2020 WebAssembly Community Group participants+ *+ * Licensed under the Apache License, Version 2.0 (the "License");+ * you may not use this file except in compliance with the License.+ * You may obtain a copy of the License at+ *+ * http://www.apache.org/licenses/LICENSE-2.0+ *+ * Unless required by applicable law or agreed to in writing, software+ * distributed under the License is distributed on an "AS IS" BASIS,+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+ * See the License for the specific language governing permissions and+ * limitations under the License.+ */++//+// Lowers a module with loads and stores that access a 64-bit memory with+// one that works as-is on wasm32.+//+// TODO(wvo): make this run in parallel if needed.++#include "ir/bits.h"+#include "pass.h"+#include "wasm-builder.h"+#include "wasm.h"++namespace wasm {++struct Memory64Lowering : public WalkerPass<PostWalker<Memory64Lowering>> {++ void run(PassRunner* runner, Module* module) override {+ if (module->memory.is64()) {+ super::run(runner, module);+ }+ }++ void wrapAddress64(Expression*& ptr) {+ if (ptr->type == Type::unreachable) {+ return;+ }+ auto& module = *getModule();+ assert(module.memory.is64());+ assert(ptr->type == Type::i64);+ Builder builder(module);+ ptr = builder.makeUnary(UnaryOp::WrapInt64, ptr);+ }++ void extendAddress64(Expression*& ptr) {+ if (ptr->type == Type::unreachable) {+ return;+ }+ auto& module = *getModule();+ assert(module.memory.is64());+ assert(ptr->type == Type::i64);+ ptr->type = Type::i32;+ Builder builder(module);+ ptr = builder.makeUnary(UnaryOp::ExtendUInt32, ptr);+ }++ void visitLoad(Load* curr) { wrapAddress64(curr->ptr); }++ void visitStore(Store* curr) { wrapAddress64(curr->ptr); }++ void visitMemorySize(MemorySize* curr) {+ auto size = static_cast<Expression*>(curr);+ extendAddress64(size);+ curr->ptrType = Type::i32;+ replaceCurrent(size);+ }++ void visitMemoryGrow(MemoryGrow* curr) {+ wrapAddress64(curr->delta);+ auto size = static_cast<Expression*>(curr);+ extendAddress64(size);+ curr->ptrType = Type::i32;+ replaceCurrent(size);+ }++ void visitMemoryInit(MemoryInit* curr) { wrapAddress64(curr->dest); }++ void visitMemoryFill(MemoryFill* curr) {+ wrapAddress64(curr->dest);+ wrapAddress64(curr->size);+ }++ void visitMemoryCopy(MemoryCopy* curr) {+ wrapAddress64(curr->dest);+ wrapAddress64(curr->source);+ wrapAddress64(curr->size);+ }++ void visitMemory(Memory* memory) {+ // This is visited last.+ memory->indexType = Type::i32;+ }+};++Pass* createMemory64LoweringPass() { return new Memory64Lowering(); }++} // namespace wasm
binaryen/src/passes/MemoryPacking.cpp view
@@ -30,14 +30,18 @@ #include "ir/manipulation.h" #include "ir/module-utils.h"+#include "ir/names.h" #include "ir/utils.h" #include "pass.h"+#include "support/space.h" #include "wasm-binary.h" #include "wasm-builder.h" #include "wasm.h" namespace wasm { +namespace {+ // A subsection of an orginal memory segment. If `isZero` is true, memory.fill // will be used instead of memory.init for this range. struct Range {@@ -74,8 +78,6 @@ // data.drop: 2 byte opcode + ~1 byte index immediate const size_t DATA_DROP_SIZE = 3; -namespace {- Expression* makeGtShiftedMemorySize(Builder& builder, Module& module, MemoryInit* curr) { return builder.makeBinary(@@ -89,14 +91,13 @@ } // anonymous namespace struct MemoryPacking : public Pass {- size_t dropStateGlobalCount = 0;- // FIXME: Chrome has a bug decoding section indices that prevents it from // using more than 63. Just use WebLimitations::MaxDataSegments once this is // fixed. See https://bugs.chromium.org/p/v8/issues/detail?id=10151. uint32_t maxSegments; void run(PassRunner* runner, Module* module) override;+ bool canOptimize(const Memory& memory, const PassOptions& passOptions); void optimizeBulkMemoryOps(PassRunner* runner, Module* module); void getSegmentReferrers(Module* module, std::vector<Referrers>& referrers); void dropUnusedSegments(std::vector<Memory::Segment>& segments,@@ -121,13 +122,14 @@ }; void MemoryPacking::run(PassRunner* runner, Module* module) {- if (!module->memory.exists) {+ if (!canOptimize(module->memory, runner->options)) { return; } maxSegments = module->features.hasBulkMemory() ? 63 : uint32_t(WebLimitations::MaxDataSegments);+ auto& segments = module->memory.segments; // For each segment, a list of bulk memory instructions that refer to it@@ -154,6 +156,7 @@ auto& currReferrers = referrers[origIndex]; std::vector<Range> ranges;+ if (canSplit(segment, currReferrers)) { calculateRanges(segment, currReferrers, ranges); } else {@@ -176,8 +179,88 @@ } } +bool MemoryPacking::canOptimize(const Memory& memory,+ const PassOptions& passOptions) {+ if (!memory.exists) {+ return false;+ }++ // We must optimize under the assumption that memory has been initialized to+ // zero. That is the case for a memory declared in the module, but for a+ // memory that is imported, we must be told that it is zero-initialized.+ if (memory.imported() && !passOptions.zeroFilledMemory) {+ return false;+ }++ auto& segments = memory.segments;++ // One segment is always ok to optimize, as it does not have the potential+ // problems handled below.+ if (segments.size() <= 1) {+ return true;+ }+ // Check if it is ok for us to optimize.+ Address maxAddress = 0;+ for (auto& segment : segments) {+ if (!segment.isPassive) {+ auto* c = segment.offset->dynCast<Const>();+ // If an active segment has a non-constant offset, then what gets written+ // cannot be known until runtime. That is, the active segments are written+ // out at startup, in order, and one may trample the data of another, like+ //+ // (data (i32.const 100) "a")+ // (data (i32.const 100) "\00")+ //+ // It is *not* ok to optimize out the zero in the last segment, as it is+ // actually needed, it will zero out the "a" that was written earlier. And+ // if a segment has an imported offset,+ //+ // (data (i32.const 100) "a")+ // (data (global.get $x) "\00")+ //+ // then we can't tell if that last segment will end up overwriting or not.+ // The only case we can easily handle is if there is just a single+ // segment, which we handled earlier. (Note that that includes the main+ // case of having a non-constant offset, dynamic linking, in which we have+ // a single segment.)+ if (!c) {+ return false;+ }+ // Note the maximum address so far.+ maxAddress = std::max(+ maxAddress, Address(c->value.getInteger() + segment.data.size()));+ }+ }+ // All active segments have constant offsets, known at this time, so we may be+ // able to optimize, but must still check for the trampling problem mentioned+ // earlier.+ // TODO: optimize in the trampling case+ DisjointSpans space;+ for (auto& segment : segments) {+ if (!segment.isPassive) {+ auto* c = segment.offset->cast<Const>();+ Address start = c->value.getInteger();+ DisjointSpans::Span span{start, start + segment.data.size()};+ if (space.addAndCheckOverlap(span)) {+ std::cerr << "warning: active memory segments have overlap, which "+ << "prevents some optimizations.\n";+ return false;+ }+ }+ }+ return true;+}+ bool MemoryPacking::canSplit(const Memory::Segment& segment, const Referrers& referrers) {+ // Don't mess with segments related to llvm coverage tools such as+ // __llvm_covfun. There segments are expected/parsed by external downstream+ // tools (llvm-cov) so they need to be left intact.+ // See https://clang.llvm.org/docs/SourceBasedCodeCoverage.html+ if (segment.name.is() && segment.name.startsWith("__llvm")) {+ return false;+ }+ if (segment.isPassive) { for (auto* referrer : referrers) { if (auto* init = referrer->dynCast<MemoryInit>()) {@@ -188,10 +271,10 @@ } } return true;- } else {- // Active segments can only be split if they have constant offsets- return segment.offset->is<Const>(); }++ // Active segments can only be split if they have constant offsets+ return segment.offset->is<Const>(); } void MemoryPacking::calculateRanges(const Memory::Segment& segment,@@ -431,6 +514,7 @@ std::vector<Range>& ranges, std::vector<Memory::Segment>& packed, size_t segmentsRemaining) {+ size_t segmentCount = 0; for (size_t i = 0; i < ranges.size(); ++i) { Range& range = ranges[i]; if (range.isZero) {@@ -454,7 +538,22 @@ range.end = lastNonzero->end; ranges.erase(ranges.begin() + i + 1, lastNonzero + 1); }- packed.emplace_back(segment.isPassive,+ Name name;+ if (segment.name.is()) {+ // Name the first range after the original segment and all following+ // ranges get numbered accordingly. This means that for segments that+ // canot be split (segments that contains a single range) the input and+ // output segment have the same name.+ if (!segmentCount) {+ name = segment.name;+ } else {+ name = std::string(segment.name.c_str()) + "." ++ std::to_string(segmentCount);+ }+ segmentCount++;+ }+ packed.emplace_back(name,+ segment.isPassive, offset, &segment.data[range.start], range.end - range.start);@@ -494,8 +593,8 @@ if (dropStateGlobal != Name()) { return dropStateGlobal; }- dropStateGlobal = Name(std::string("__mem_segment_drop_state_") +- std::to_string(dropStateGlobalCount++));+ dropStateGlobal =+ Names::getValidGlobalName(*module, "__mem_segment_drop_state"); module->addGlobal(builder.makeGlobal(dropStateGlobal, Type::i32, builder.makeConst(int32_t(0)),@@ -514,10 +613,16 @@ size_t start = init->offset->cast<Const>()->value.geti32(); size_t end = start + init->size->cast<Const>()->value.geti32(); + // Segment index used in emitted memory.init instructions+ size_t initIndex = segmentIndex;+ // Index of the range from which this memory.init starts reading size_t firstRangeIdx = 0; while (firstRangeIdx < ranges.size() && ranges[firstRangeIdx].end <= start) {+ if (!ranges[firstRangeIdx].isZero) {+ ++initIndex;+ } ++firstRangeIdx; } @@ -568,7 +673,6 @@ size_t bytesWritten = 0; - size_t initIndex = segmentIndex; for (size_t i = firstRangeIdx; i < ranges.size() && ranges[i].start < end; ++i) { auto& range = ranges[i];
binaryen/src/passes/MergeBlocks.cpp view
@@ -564,7 +564,7 @@ void visitCall(Call* curr) { handleCall(curr); } - void visitCallIndirect(CallIndirect* curr) {+ template<typename T> void handleNonDirectCall(T* curr) { FeatureSet features = getModule()->features; Block* outer = nullptr; for (Index i = 0; i < curr->operands.size(); i++) {@@ -580,6 +580,10 @@ } optimize(curr, curr->target, outer); }++ void visitCallIndirect(CallIndirect* curr) { handleNonDirectCall(curr); }++ void visitCallRef(CallRef* curr) { handleNonDirectCall(curr); } void visitThrow(Throw* curr) { Block* outer = nullptr;
binaryen/src/passes/OptimizeInstructions.cpp view
@@ -19,1938 +19,2439 @@ // #include <algorithm>-#include <type_traits>--#include <ir/abstract.h>-#include <ir/bits.h>-#include <ir/cost.h>-#include <ir/effects.h>-#include <ir/literal-utils.h>-#include <ir/load-utils.h>-#include <ir/manipulation.h>-#include <ir/match.h>-#include <ir/properties.h>-#include <ir/utils.h>-#include <pass.h>-#include <support/threads.h>-#include <wasm-s-parser.h>-#include <wasm.h>--// TODO: Use the new sign-extension opcodes where appropriate. This needs to be-// conditionalized on the availability of atomics.--namespace wasm {--Name I32_EXPR = "i32.expr";-Name I64_EXPR = "i64.expr";-Name F32_EXPR = "f32.expr";-Name F64_EXPR = "f64.expr";-Name ANY_EXPR = "any.expr";--// Useful information about locals-struct LocalInfo {- static const Index kUnknown = Index(-1);-- Index maxBits;- Index signExtedBits;-};--struct LocalScanner : PostWalker<LocalScanner> {- std::vector<LocalInfo>& localInfo;- const PassOptions& passOptions;-- LocalScanner(std::vector<LocalInfo>& localInfo,- const PassOptions& passOptions)- : localInfo(localInfo), passOptions(passOptions) {}-- void doWalkFunction(Function* func) {- // prepare- localInfo.resize(func->getNumLocals());- for (Index i = 0; i < func->getNumLocals(); i++) {- auto& info = localInfo[i];- if (func->isParam(i)) {- info.maxBits = getBitsForType(func->getLocalType(i)); // worst-case- info.signExtedBits = LocalInfo::kUnknown; // we will never know anything- } else {- info.maxBits = info.signExtedBits = 0; // we are open to learning- }- }- // walk- PostWalker<LocalScanner>::doWalkFunction(func);- // finalize- for (Index i = 0; i < func->getNumLocals(); i++) {- auto& info = localInfo[i];- if (info.signExtedBits == LocalInfo::kUnknown) {- info.signExtedBits = 0;- }- }- }-- void visitLocalSet(LocalSet* curr) {- auto* func = getFunction();- if (func->isParam(curr->index)) {- return;- }- auto type = getFunction()->getLocalType(curr->index);- if (type != Type::i32 && type != Type::i64) {- return;- }- // an integer var, worth processing- auto* value = Properties::getFallthrough(- curr->value, passOptions, getModule()->features);- auto& info = localInfo[curr->index];- info.maxBits = std::max(info.maxBits, Bits::getMaxBits(value, this));- auto signExtBits = LocalInfo::kUnknown;- if (Properties::getSignExtValue(value)) {- signExtBits = Properties::getSignExtBits(value);- } else if (auto* load = value->dynCast<Load>()) {- if (LoadUtils::isSignRelevant(load) && load->signed_) {- signExtBits = load->bytes * 8;- }- }- if (info.signExtedBits == 0) {- info.signExtedBits = signExtBits; // first info we see- } else if (info.signExtedBits != signExtBits) {- // contradictory information, give up- info.signExtedBits = LocalInfo::kUnknown;- }- }-- // define this for the templated getMaxBits method. we know nothing here yet- // about locals, so return the maxes- Index getMaxBitsForLocal(LocalGet* get) { return getBitsForType(get->type); }-- Index getBitsForType(Type type) {- TODO_SINGLE_COMPOUND(type);- switch (type.getBasic()) {- case Type::i32:- return 32;- case Type::i64:- return 64;- default:- return -1;- }- }-};--// Create a custom matcher for checking side effects-template<class Opt> struct PureMatcherKind {};-template<class Opt>-struct Match::Internal::KindTypeRegistry<PureMatcherKind<Opt>> {- using matched_t = Expression*;- using data_t = Opt*;-};-template<class Opt> struct Match::Internal::MatchSelf<PureMatcherKind<Opt>> {- bool operator()(Expression* curr, Opt* opt) {- return !opt->effects(curr).hasSideEffects();- }-};--// Main pass class-struct OptimizeInstructions- : public WalkerPass<- PostWalker<OptimizeInstructions,- UnifiedExpressionVisitor<OptimizeInstructions>>> {- bool isFunctionParallel() override { return true; }-- Pass* create() override { return new OptimizeInstructions; }-- bool fastMath;-- void doWalkFunction(Function* func) {- fastMath = getPassOptions().fastMath;- // first, scan locals- {- LocalScanner scanner(localInfo, getPassOptions());- scanner.setModule(getModule());- scanner.walkFunction(func);- }- // main walk- super::doWalkFunction(func);- }-- void visitExpression(Expression* curr) {- // we may be able to apply multiple patterns, one may open opportunities- // that look deeper NB: patterns must not have cycles- while (1) {- auto* handOptimized = handOptimize(curr);- if (handOptimized) {- curr = handOptimized;- replaceCurrent(curr);- continue;- }- break;- }- }-- EffectAnalyzer effects(Expression* expr) {- return EffectAnalyzer(getPassOptions(), getModule()->features, expr);- }-- decltype(auto) pure(Expression** binder) {- using namespace Match::Internal;- return Matcher<PureMatcherKind<OptimizeInstructions>>(binder, this);- }-- bool canReorder(Expression* a, Expression* b) {- return EffectAnalyzer::canReorder(- getPassOptions(), getModule()->features, a, b);- }-- // Optimizations that don't yet fit in the pattern DSL, but could be- // eventually maybe- Expression* handOptimize(Expression* curr) {- FeatureSet features = getModule()->features;- // if this contains dead code, don't bother trying to optimize it, the type- // might change (if might not be unreachable if just one arm is, for- // example). this optimization pass focuses on actually executing code. the- // only exceptions are control flow changes- if (curr->type == Type::unreachable && !curr->is<Break>() &&- !curr->is<Switch>() && !curr->is<If>()) {- return nullptr;- }- if (auto* binary = curr->dynCast<Binary>()) {- if (isSymmetric(binary)) {- canonicalize(binary);- }- }-- {- // TODO: It is an ongoing project to port more transformations to the- // match API. Once most of the transformations have been ported, the- // `using namespace Match` can be hoisted to function scope and this extra- // block scope can be removed.- using namespace Match;- Builder builder(*getModule());- {- // try to get rid of (0 - ..), that is, a zero only used to negate an- // int. an add of a subtract can be flipped in order to remove it:- // (i32.add- // (i32.sub- // (i32.const 0)- // X- // )- // Y- // )- // =>- // (i32.sub- // Y- // X- // )- // Note that this reorders X and Y, so we need to be careful about that.- Expression *x, *y;- Binary* sub;- if (matches(curr,- binary(AddInt32,- binary(&sub, SubInt32, i32(0), any(&x)),- any(&y))) &&- canReorder(x, y)) {- sub->left = y;- sub->right = x;- return sub;- }- }- {- // The flip case is even easier, as no reordering occurs:- // (i32.add- // Y- // (i32.sub- // (i32.const 0)- // X- // )- // )- // =>- // (i32.sub- // Y- // X- // )- Expression* y;- Binary* sub;- if (matches(curr,- binary(AddInt32,- any(&y),- binary(&sub, SubInt32, i32(0), any())))) {- sub->left = y;- return sub;- }- }- {- // eqz((signed)x % C_pot) => eqz(x & (abs(C_pot) - 1))- Const* c;- Binary* inner;- if (matches(curr,- unary(Abstract::EqZ,- binary(&inner, Abstract::RemS, any(), ival(&c)))) &&- (c->value.isSignedMin() ||- Bits::isPowerOf2(c->value.abs().getInteger()))) {- inner->op = Abstract::getBinary(c->type, Abstract::And);- if (c->value.isSignedMin()) {- c->value = Literal::makeSignedMax(c->type);- } else {- c->value = c->value.abs().sub(Literal::makeOne(c->type));- }- return curr;- }- }- {- // try de-morgan's AND law,- // (eqz X) and (eqz Y) === eqz (X or Y)- // Note that the OR and XOR laws do not work here, as these- // are not booleans (we could check if they are, but a boolean- // would already optimize with the eqz anyhow, unless propagating).- // But for AND, the left is true iff X and Y are each all zero bits,- // and the right is true if the union of their bits is zero; same.- Unary* un;- Binary* bin;- Expression *x, *y;- if (matches(curr,- binary(&bin,- AndInt32,- unary(&un, EqZInt32, any(&x)),- unary(EqZInt32, any(&y))))) {- bin->op = OrInt32;- bin->left = x;- bin->right = y;- un->value = bin;- return un;- }- }- {- // i32.eqz(i32.wrap_i64(x)) => i64.eqz(x)- // where maxBits(x) <= 32- Unary* inner;- Expression* x;- if (matches(curr, unary(EqZInt32, unary(&inner, WrapInt64, any(&x)))) &&- Bits::getMaxBits(x, this) <= 32) {- inner->op = EqZInt64;- inner->value = x;- return inner;- }- }- {- // x <<>> (C & (31 | 63)) ==> x <<>> C'- // x <<>> (y & (31 | 63)) ==> x <<>> y- // where '<<>>':- // '<<', '>>', '>>>'. 'rotl' or 'rotr'- BinaryOp op;- Const* c;- Expression *x, *y;-- // x <<>> C- if (matches(curr, binary(&op, any(&x), ival(&c))) &&- Abstract::hasAnyShift(op)) {- // truncate RHS constant to effective size as:- // i32(x) <<>> const(C & 31))- // i64(x) <<>> const(C & 63))- c->value = c->value.and_(- Literal::makeFromInt32(c->type.getByteSize() * 8 - 1, c->type));- // x <<>> 0 ==> x- if (c->value.isZero()) {- return x;- }- }- if (matches(- curr,- binary(&op, any(&x), binary(Abstract::And, any(&y), ival(&c)))) &&- Abstract::hasAnyShift(op)) {- // i32(x) <<>> (y & 31) ==> x <<>> y- // i64(x) <<>> (y & 63) ==> x <<>> y- if ((c->type == Type::i32 && (c->value.geti32() & 31) == 31) ||- (c->type == Type::i64 && (c->value.geti64() & 63LL) == 63LL)) {- curr->cast<Binary>()->right = y;- return curr;- }- }- }- }-- if (auto* select = curr->dynCast<Select>()) {- return optimizeSelect(select);- }-- if (auto* binary = curr->dynCast<Binary>()) {- if (auto* ext = Properties::getAlmostSignExt(binary)) {- Index extraShifts;- auto bits = Properties::getAlmostSignExtBits(binary, extraShifts);- if (extraShifts == 0) {- if (auto* load =- Properties::getFallthrough(ext, getPassOptions(), features)- ->dynCast<Load>()) {- // pattern match a load of 8 bits and a sign extend using a shl of- // 24 then shr_s of 24 as well, etc.- if (LoadUtils::canBeSigned(load) &&- ((load->bytes == 1 && bits == 8) ||- (load->bytes == 2 && bits == 16))) {- // if the value falls through, we can't alter the load, as it- // might be captured in a tee- if (load->signed_ == true || load == ext) {- load->signed_ = true;- return ext;- }- }- }- }- // if the sign-extend input cannot have a sign bit, we don't need it- // we also don't need it if it already has an identical-sized sign- // extend- if (Bits::getMaxBits(ext, this) + extraShifts < bits ||- isSignExted(ext, bits)) {- return removeAlmostSignExt(binary);- }- } else if (binary->op == EqInt32 || binary->op == NeInt32) {- if (auto* c = binary->right->dynCast<Const>()) {- if (auto* ext = Properties::getSignExtValue(binary->left)) {- // we are comparing a sign extend to a constant, which means we can- // use a cheaper zext- auto bits = Properties::getSignExtBits(binary->left);- binary->left = makeZeroExt(ext, bits);- // when we replace the sign-ext of the non-constant with a zero-ext,- // we are forcing the high bits to be all zero, instead of all zero- // or all one depending on the sign bit. so we may be changing the- // high bits from all one to all zero:- // * if the constant value's higher bits are mixed, then it can't- // be equal anyhow- // * if they are all zero, we may get a false true if the- // non-constant's upper bits were one. this can only happen if- // the non-constant's sign bit is set, so this false true is a- // risk only if the constant's sign bit is set (otherwise,- // false). But a constant with a sign bit but with upper bits- // zero is impossible to be equal to a sign-extended value- // anyhow, so the entire thing is false.- // * if they were all one, we may get a false false, if the only- // difference is in those upper bits. that means we are equal on- // the other bits, including the sign bit. so we can just mask- // off the upper bits in the constant value, in this case,- // forcing them to zero like we do in the zero-extend.- int32_t constValue = c->value.geti32();- auto upperConstValue = constValue & ~Bits::lowBitMask(bits);- uint32_t count = Bits::popCount(upperConstValue);- auto constSignBit = constValue & (1 << (bits - 1));- if ((count > 0 && count < 32 - bits) ||- (constSignBit && count == 0)) {- // mixed or [zero upper const bits with sign bit set]; the- // compared values can never be identical, so force something- // definitely impossible even after zext- assert(bits < 32);- c->value = Literal(int32_t(0x80000000));- // TODO: if no side effects, we can just replace it all with 1 or- // 0- } else {- // otherwise, they are all ones, so we can mask them off as- // mentioned before- c->value = c->value.and_(Literal(Bits::lowBitMask(bits)));- }- return binary;- }- } else if (auto* left = Properties::getSignExtValue(binary->left)) {- if (auto* right = Properties::getSignExtValue(binary->right)) {- auto bits = Properties::getSignExtBits(binary->left);- if (Properties::getSignExtBits(binary->right) == bits) {- // we are comparing two sign-exts with the same bits, so we may as- // well replace both with cheaper zexts- binary->left = makeZeroExt(left, bits);- binary->right = makeZeroExt(right, bits);- return binary;- }- } else if (auto* load = binary->right->dynCast<Load>()) {- // we are comparing a load to a sign-ext, we may be able to switch- // to zext- auto leftBits = Properties::getSignExtBits(binary->left);- if (load->signed_ && leftBits == load->bytes * 8) {- load->signed_ = false;- binary->left = makeZeroExt(left, leftBits);- return binary;- }- }- } else if (auto* load = binary->left->dynCast<Load>()) {- if (auto* right = Properties::getSignExtValue(binary->right)) {- // we are comparing a load to a sign-ext, we may be able to switch- // to zext- auto rightBits = Properties::getSignExtBits(binary->right);- if (load->signed_ && rightBits == load->bytes * 8) {- load->signed_ = false;- binary->right = makeZeroExt(right, rightBits);- return binary;- }- }- }- // note that both left and right may be consts, but then we let- // precompute compute the constant result- } else if (binary->op == AddInt32) {- if (auto* ret = optimizeAddedConstants(binary)) {- return ret;- }- } else if (binary->op == SubInt32) {- if (auto* ret = optimizeAddedConstants(binary)) {- return ret;- }- }- // a bunch of operations on a constant right side can be simplified- if (auto* right = binary->right->dynCast<Const>()) {- if (binary->op == AndInt32) {- auto mask = right->value.geti32();- // and with -1 does nothing (common in asm.js output)- if (mask == -1) {- return binary->left;- }- // small loads do not need to be masked, the load itself masks- if (auto* load = binary->left->dynCast<Load>()) {- if ((load->bytes == 1 && mask == 0xff) ||- (load->bytes == 2 && mask == 0xffff)) {- load->signed_ = false;- return binary->left;- }- } else if (auto maskedBits = Bits::getMaskedBits(mask)) {- if (Bits::getMaxBits(binary->left, this) <= maskedBits) {- // a mask of lower bits is not needed if we are already smaller- return binary->left;- }- }- }- // some math operations have trivial results- if (auto* ret = optimizeWithConstantOnRight(binary)) {- return ret;- }- // the square of some operations can be merged- if (auto* left = binary->left->dynCast<Binary>()) {- if (left->op == binary->op) {- if (auto* leftRight = left->right->dynCast<Const>()) {- if (left->op == AndInt32) {- leftRight->value = leftRight->value.and_(right->value);- return left;- } else if (left->op == OrInt32) {- leftRight->value = leftRight->value.or_(right->value);- return left;- } else if (left->op == ShlInt32 || left->op == ShrUInt32 ||- left->op == ShrSInt32 || left->op == ShlInt64 ||- left->op == ShrUInt64 || left->op == ShrSInt64) {- // shifts only use an effective amount from the constant, so- // adding must be done carefully- auto total = Bits::getEffectiveShifts(leftRight) +- Bits::getEffectiveShifts(right);- if (total == Bits::getEffectiveShifts(total, right->type)) {- // no overflow, we can do this- leftRight->value = Literal::makeFromInt32(total, right->type);- return left;- } // TODO: handle overflows- }- }- }- }- if (right->type == Type::i32) {- BinaryOp op;- int32_t c = right->value.geti32();- // First, try to lower signed operations to unsigned if that is- // possible. Some unsigned operations like div_u or rem_u are usually- // faster on VMs. Also this opens more possibilities for further- // simplifications afterwards.- if (c >= 0 &&- (op = makeUnsignedBinaryOp(binary->op)) != InvalidBinary &&- Bits::getMaxBits(binary->left, this) <= 31) {- binary->op = op;- }- if (c < 0 && c > std::numeric_limits<int32_t>::min() &&- binary->op == DivUInt32) {- // u32(x) / C ==> u32(x) >= C iff C > 2^31- // We avoid applying this for C == 2^31 due to conflict- // with other rule which transform to more prefereble- // right shift operation.- binary->op = c == -1 ? EqInt32 : GeUInt32;- return binary;- }- if (Bits::isPowerOf2((uint32_t)c)) {- switch (binary->op) {- case MulInt32:- return optimizePowerOf2Mul(binary, (uint32_t)c);- case RemUInt32:- return optimizePowerOf2URem(binary, (uint32_t)c);- case DivUInt32:- return optimizePowerOf2UDiv(binary, (uint32_t)c);- default:- break;- }- }- }- if (right->type == Type::i64) {- BinaryOp op;- int64_t c = right->value.geti64();- // See description above for Type::i32- if (c >= 0 &&- (op = makeUnsignedBinaryOp(binary->op)) != InvalidBinary &&- Bits::getMaxBits(binary->left, this) <= 63) {- binary->op = op;- }- if (getPassOptions().shrinkLevel == 0 && c < 0 &&- c > std::numeric_limits<int64_t>::min() &&- binary->op == DivUInt64) {- // u64(x) / C ==> u64(u64(x) >= C) iff C > 2^63- // We avoid applying this for C == 2^31 due to conflict- // with other rule which transform to more prefereble- // right shift operation.- // And apply this only for shrinkLevel == 0 due to it- // increasing size by one byte.- binary->op = c == -1LL ? EqInt64 : GeUInt64;- binary->type = Type::i32;- return Builder(*getModule()).makeUnary(ExtendUInt32, binary);- }- if (Bits::isPowerOf2((uint64_t)c)) {- switch (binary->op) {- case MulInt64:- return optimizePowerOf2Mul(binary, (uint64_t)c);- case RemUInt64:- return optimizePowerOf2URem(binary, (uint64_t)c);- case DivUInt64:- return optimizePowerOf2UDiv(binary, (uint64_t)c);- default:- break;- }- }- }- }- // a bunch of operations on a constant left side can be simplified- if (binary->left->is<Const>()) {- if (auto* ret = optimizeWithConstantOnLeft(binary)) {- return ret;- }- }- // bitwise operations- // for and and or, we can potentially conditionalize- if (binary->op == AndInt32 || binary->op == OrInt32) {- if (auto* ret = conditionalizeExpensiveOnBitwise(binary)) {- return ret;- }- }- // for or, we can potentially combine- if (binary->op == OrInt32) {- if (auto* ret = combineOr(binary)) {- return ret;- }- }- // relation/comparisons allow for math optimizations- if (binary->isRelational()) {- if (auto* ret = optimizeRelational(binary)) {- return ret;- }- }- // finally, try more expensive operations on the binary in- // the case that they have no side effects- if (!effects(binary->left).hasSideEffects()) {- if (ExpressionAnalyzer::equal(binary->left, binary->right)) {- if (auto* ret = optimizeBinaryWithEqualEffectlessChildren(binary)) {- return ret;- }- }- }-- if (auto* ret = deduplicateBinary(binary)) {- return ret;- }- } else if (auto* unary = curr->dynCast<Unary>()) {- if (unary->op == EqZInt32) {- if (auto* inner = unary->value->dynCast<Binary>()) {- // Try to invert a relational operation using De Morgan's law- auto op = invertBinaryOp(inner->op);- if (op != InvalidBinary) {- inner->op = op;- return inner;- }- }- // eqz of a sign extension can be of zero-extension- if (auto* ext = Properties::getSignExtValue(unary->value)) {- // we are comparing a sign extend to a constant, which means we can- // use a cheaper zext- auto bits = Properties::getSignExtBits(unary->value);- unary->value = makeZeroExt(ext, bits);- return unary;- }- }-- if (auto* ret = deduplicateUnary(unary)) {- return ret;- }- } else if (auto* set = curr->dynCast<GlobalSet>()) {- // optimize out a set of a get- auto* get = set->value->dynCast<GlobalGet>();- if (get && get->name == set->name) {- ExpressionManipulator::nop(curr);- }- } else if (auto* iff = curr->dynCast<If>()) {- iff->condition = optimizeBoolean(iff->condition);- if (iff->ifFalse) {- if (auto* unary = iff->condition->dynCast<Unary>()) {- if (unary->op == EqZInt32) {- // flip if-else arms to get rid of an eqz- iff->condition = unary->value;- std::swap(iff->ifTrue, iff->ifFalse);- }- }- if (iff->condition->type != Type::unreachable &&- ExpressionAnalyzer::equal(iff->ifTrue, iff->ifFalse)) {- // sides are identical, fold- // if we can replace the if with one arm, and no side effects in the- // condition, do that- auto needCondition = effects(iff->condition).hasSideEffects();- auto isSubType = Type::isSubType(iff->ifTrue->type, iff->type);- if (isSubType && !needCondition) {- return iff->ifTrue;- } else {- Builder builder(*getModule());- if (isSubType) {- return builder.makeSequence(builder.makeDrop(iff->condition),- iff->ifTrue);- } else {- // the types diff. as the condition is reachable, that means the- // if must be concrete while the arm is not- assert(iff->type.isConcrete() &&- iff->ifTrue->type == Type::unreachable);- // emit a block with a forced type- auto* ret = builder.makeBlock();- if (needCondition) {- ret->list.push_back(builder.makeDrop(iff->condition));- }- ret->list.push_back(iff->ifTrue);- ret->finalize(iff->type);- return ret;- }- }- }- }- } else if (auto* br = curr->dynCast<Break>()) {- if (br->condition) {- br->condition = optimizeBoolean(br->condition);- }- } else if (auto* load = curr->dynCast<Load>()) {- optimizeMemoryAccess(load->ptr, load->offset);- } else if (auto* store = curr->dynCast<Store>()) {- optimizeMemoryAccess(store->ptr, store->offset);- // stores of fewer bits truncates anyhow- if (auto* binary = store->value->dynCast<Binary>()) {- if (binary->op == AndInt32) {- if (auto* right = binary->right->dynCast<Const>()) {- if (right->type == Type::i32) {- auto mask = right->value.geti32();- if ((store->bytes == 1 && mask == 0xff) ||- (store->bytes == 2 && mask == 0xffff)) {- store->value = binary->left;- }- }- }- } else if (auto* ext = Properties::getSignExtValue(binary)) {- // if sign extending the exact bit size we store, we can skip the- // extension if extending something bigger, then we just alter bits we- // don't save anyhow- if (Properties::getSignExtBits(binary) >= Index(store->bytes) * 8) {- store->value = ext;- }- }- } else if (auto* unary = store->value->dynCast<Unary>()) {- if (unary->op == WrapInt64) {- // instead of wrapping to 32, just store some of the bits in the i64- store->valueType = Type::i64;- store->value = unary->value;- }- }- } else if (auto* memCopy = curr->dynCast<MemoryCopy>()) {- assert(features.hasBulkMemory());- if (auto* ret = optimizeMemoryCopy(memCopy)) {- return ret;- }- }- return nullptr;- }-- Index getMaxBitsForLocal(LocalGet* get) {- // check what we know about the local- return localInfo[get->index].maxBits;- }--private:- // Information about our locals- std::vector<LocalInfo> localInfo;-- // Canonicalizing the order of a symmetric binary helps us- // write more concise pattern matching code elsewhere.- void canonicalize(Binary* binary) {- assert(isSymmetric(binary));- auto swap = [&]() {- assert(canReorder(binary->left, binary->right));- std::swap(binary->left, binary->right);- };- auto maybeSwap = [&]() {- if (canReorder(binary->left, binary->right)) {- swap();- }- };- // Prefer a const on the right.- if (binary->left->is<Const>() && !binary->right->is<Const>()) {- return swap();- }- if (binary->right->is<Const>()) {- return;- }- // Prefer a get on the right.- if (binary->left->is<LocalGet>() && !binary->right->is<LocalGet>()) {- return maybeSwap();- }- // Sort by the node id type, if different.- if (binary->left->_id != binary->right->_id) {- if (binary->left->_id > binary->right->_id) {- return maybeSwap();- }- return;- }- // If the children have the same node id, we have to go deeper.- if (auto* left = binary->left->dynCast<Unary>()) {- auto* right = binary->right->cast<Unary>();- if (left->op > right->op) {- return maybeSwap();- }- }- if (auto* left = binary->left->dynCast<Binary>()) {- auto* right = binary->right->cast<Binary>();- if (left->op > right->op) {- return maybeSwap();- }- }- if (auto* left = binary->left->dynCast<LocalGet>()) {- auto* right = binary->right->cast<LocalGet>();- if (left->index > right->index) {- return maybeSwap();- }- }- }-- // Optimize given that the expression is flowing into a boolean context- Expression* optimizeBoolean(Expression* boolean) {- // TODO use a general getFallthroughs- if (auto* unary = boolean->dynCast<Unary>()) {- if (unary) {- if (unary->op == EqZInt32) {- auto* unary2 = unary->value->dynCast<Unary>();- if (unary2 && unary2->op == EqZInt32) {- // double eqz- return unary2->value;- }- if (auto* binary = unary->value->dynCast<Binary>()) {- // !(x <=> y) ==> x <!=> y- auto op = invertBinaryOp(binary->op);- if (op != InvalidBinary) {- binary->op = op;- return binary;- }- }- }- }- } else if (auto* binary = boolean->dynCast<Binary>()) {- if (binary->op == SubInt32) {- if (auto* c = binary->left->dynCast<Const>()) {- if (c->value.geti32() == 0) {- // bool(0 - x) ==> bool(x)- return binary->right;- }- }- } else if (binary->op == OrInt32) {- // an or flowing into a boolean context can consider each input as- // boolean- binary->left = optimizeBoolean(binary->left);- binary->right = optimizeBoolean(binary->right);- } else if (binary->op == NeInt32) {- if (auto* c = binary->right->dynCast<Const>()) {- // x != 0 is just x if it's used as a bool- if (c->value.geti32() == 0) {- return binary->left;- }- // TODO: Perhaps use it for separate final pass???- // x != -1 ==> x ^ -1- // if (num->value.geti32() == -1) {- // binary->op = XorInt32;- // return binary;- // }- }- }- if (auto* ext = Properties::getSignExtValue(binary)) {- // use a cheaper zero-extent, we just care about the boolean value- // anyhow- return makeZeroExt(ext, Properties::getSignExtBits(binary));- }- } else if (auto* block = boolean->dynCast<Block>()) {- if (block->type == Type::i32 && block->list.size() > 0) {- block->list.back() = optimizeBoolean(block->list.back());- }- } else if (auto* iff = boolean->dynCast<If>()) {- if (iff->type == Type::i32) {- iff->ifTrue = optimizeBoolean(iff->ifTrue);- iff->ifFalse = optimizeBoolean(iff->ifFalse);- }- } else if (auto* select = boolean->dynCast<Select>()) {- select->ifTrue = optimizeBoolean(select->ifTrue);- select->ifFalse = optimizeBoolean(select->ifFalse);- } else if (auto* tryy = boolean->dynCast<Try>()) {- if (tryy->type == Type::i32) {- tryy->body = optimizeBoolean(tryy->body);- tryy->catchBody = optimizeBoolean(tryy->catchBody);- }- }- // TODO: recurse into br values?- return boolean;- }-- Expression* optimizeSelect(Select* curr) {- using namespace Match;- Builder builder(*getModule());- curr->condition = optimizeBoolean(curr->condition);- {- // Constant condition, we can just pick the correct side (barring side- // effects)- Expression *ifTrue, *ifFalse;- if (matches(curr, select(pure(&ifTrue), any(&ifFalse), i32(0)))) {- return ifFalse;- }- if (matches(curr, select(any(&ifTrue), any(&ifFalse), i32(0)))) {- return builder.makeSequence(builder.makeDrop(ifTrue), ifFalse);- }- int32_t cond;- if (matches(curr, select(any(&ifTrue), pure(&ifFalse), i32(&cond)))) {- // The condition must be non-zero because a zero would have matched one- // of the previous patterns.- assert(cond != 0);- return ifTrue;- }- // Don't bother when `ifFalse` isn't pure - we would need to reverse the- // order using a temp local, which would be bad- }- {- // Flip select to remove eqz if we can reorder- Select* s;- Expression *ifTrue, *ifFalse, *c;- if (matches(- curr,- select(- &s, any(&ifTrue), any(&ifFalse), unary(EqZInt32, any(&c)))) &&- canReorder(ifTrue, ifFalse)) {- s->ifTrue = ifFalse;- s->ifFalse = ifTrue;- s->condition = c;- }- }- {- // Simplify selects between 0 and 1- Expression* c;- bool reversed = matches(curr, select(ival(0), ival(1), any(&c)));- if (reversed || matches(curr, select(ival(1), ival(0), any(&c)))) {- if (reversed) {- c = optimizeBoolean(builder.makeUnary(EqZInt32, c));- }- if (!Properties::emitsBoolean(c)) {- // cond ? 1 : 0 ==> !!cond- c = builder.makeUnary(EqZInt32, builder.makeUnary(EqZInt32, c));- }- return curr->type == Type::i64 ? builder.makeUnary(ExtendUInt32, c) : c;- }- }- {- // Sides are identical, fold- Expression *ifTrue, *ifFalse, *c;- if (matches(curr, select(any(&ifTrue), any(&ifFalse), any(&c))) &&- ExpressionAnalyzer::equal(ifTrue, ifFalse)) {- auto value = effects(ifTrue);- if (value.hasSideEffects()) {- // At best we don't need the condition, but need to execute the- // value twice. a block is larger than a select by 2 bytes, and we- // must drop one value, so 3, while we save the condition, so it's- // not clear this is worth it, TODO- } else {- // value has no side effects- auto condition = effects(c);- if (!condition.hasSideEffects()) {- return ifTrue;- } else {- // The condition is last, so we need a new local, and it may be a- // bad idea to use a block like we do for an if. Do it only if we- // can reorder- if (!condition.invalidates(value)) {- return builder.makeSequence(builder.makeDrop(c), ifTrue);- }- }- }- }- }- return nullptr;- }-- // find added constants in an expression tree, including multiplied/shifted,- // and combine them note that we ignore division/shift-right, as rounding- // makes this nonlinear, so not a valid opt- Expression* optimizeAddedConstants(Binary* binary) {- uint32_t constant = 0;- std::vector<Const*> constants;-- struct SeekState {- Expression* curr;- int mul;- SeekState(Expression* curr, int mul) : curr(curr), mul(mul) {}- };- std::vector<SeekState> seekStack;- seekStack.emplace_back(binary, 1);- while (!seekStack.empty()) {- auto state = seekStack.back();- seekStack.pop_back();- auto curr = state.curr;- auto mul = state.mul;- if (auto* c = curr->dynCast<Const>()) {- uint32_t value = c->value.geti32();- if (value != 0) {- constant += value * mul;- constants.push_back(c);- }- continue;- } else if (auto* binary = curr->dynCast<Binary>()) {- if (binary->op == AddInt32) {- seekStack.emplace_back(binary->right, mul);- seekStack.emplace_back(binary->left, mul);- continue;- } else if (binary->op == SubInt32) {- // if the left is a zero, ignore it, it's how we negate ints- auto* left = binary->left->dynCast<Const>();- seekStack.emplace_back(binary->right, -mul);- if (!left || left->value.geti32() != 0) {- seekStack.emplace_back(binary->left, mul);- }- continue;- } else if (binary->op == ShlInt32) {- if (auto* c = binary->right->dynCast<Const>()) {- seekStack.emplace_back(- binary->left, mul * Bits::pow2(Bits::getEffectiveShifts(c)));- continue;- }- } else if (binary->op == MulInt32) {- if (auto* c = binary->left->dynCast<Const>()) {- seekStack.emplace_back(binary->right, mul * c->value.geti32());- continue;- } else if (auto* c = binary->right->dynCast<Const>()) {- seekStack.emplace_back(binary->left, mul * c->value.geti32());- continue;- }- }- }- };- // find all factors- if (constants.size() <= 1) {- // nothing much to do, except for the trivial case of adding/subbing a- // zero- if (auto* c = binary->right->dynCast<Const>()) {- if (c->value.geti32() == 0) {- return binary->left;- }- }- return nullptr;- }- // wipe out all constants, we'll replace with a single added one- for (auto* c : constants) {- c->value = Literal(int32_t(0));- }- // remove added/subbed zeros- struct ZeroRemover : public PostWalker<ZeroRemover> {- // TODO: we could save the binarys and costs we drop, and reuse them later-- PassOptions& passOptions;-- ZeroRemover(PassOptions& passOptions) : passOptions(passOptions) {}-- void visitBinary(Binary* curr) {- FeatureSet features = getModule()->features;- auto* left = curr->left->dynCast<Const>();- auto* right = curr->right->dynCast<Const>();- if (curr->op == AddInt32) {- if (left && left->value.geti32() == 0) {- replaceCurrent(curr->right);- return;- }- if (right && right->value.geti32() == 0) {- replaceCurrent(curr->left);- return;- }- } else if (curr->op == SubInt32) {- // we must leave a left zero, as it is how we negate ints- if (right && right->value.geti32() == 0) {- replaceCurrent(curr->left);- return;- }- } else if (curr->op == ShlInt32) {- // shifting a 0 is a 0, or anything by 0 has no effect, all unless the- // shift has side effects- if (((left && left->value.geti32() == 0) ||- (right && Bits::getEffectiveShifts(right) == 0)) &&- !EffectAnalyzer(passOptions, features, curr->right)- .hasSideEffects()) {- replaceCurrent(curr->left);- return;- }- } else if (curr->op == MulInt32) {- // multiplying by zero is a zero, unless the other side has side- // effects- if (left && left->value.geti32() == 0 &&- !EffectAnalyzer(passOptions, features, curr->right)- .hasSideEffects()) {- replaceCurrent(left);- return;- }- if (right && right->value.geti32() == 0 &&- !EffectAnalyzer(passOptions, features, curr->left)- .hasSideEffects()) {- replaceCurrent(right);- return;- }- }- }- };- Expression* walked = binary;- ZeroRemover remover(getPassOptions());- remover.setModule(getModule());- remover.walk(walked);- if (constant == 0) {- return walked; // nothing more to do- }- if (auto* c = walked->dynCast<Const>()) {- assert(c->value.geti32() == 0);- c->value = Literal(constant);- return c;- }- Builder builder(*getModule());- return builder.makeBinary(- AddInt32, walked, builder.makeConst(Literal(constant)));- }-- // expensive1 | expensive2 can be turned into expensive1 ? 1 : expensive2,- // and expensive | cheap can be turned into cheap ? 1 : expensive,- // so that we can avoid one expensive computation, if it has no side effects.- Expression* conditionalizeExpensiveOnBitwise(Binary* binary) {- // this operation can increase code size, so don't always do it- auto& options = getPassRunner()->options;- if (options.optimizeLevel < 2 || options.shrinkLevel > 0) {- return nullptr;- }- const auto MIN_COST = 7;- assert(binary->op == AndInt32 || binary->op == OrInt32);- if (binary->right->is<Const>()) {- return nullptr; // trivial- }- // bitwise logical operator on two non-numerical values, check if they are- // boolean- auto* left = binary->left;- auto* right = binary->right;- if (!Properties::emitsBoolean(left) || !Properties::emitsBoolean(right)) {- return nullptr;- }- auto leftEffects = effects(left);- auto rightEffects = effects(right);- auto leftHasSideEffects = leftEffects.hasSideEffects();- auto rightHasSideEffects = rightEffects.hasSideEffects();- if (leftHasSideEffects && rightHasSideEffects) {- return nullptr; // both must execute- }- // canonicalize with side effects, if any, happening on the left- if (rightHasSideEffects) {- if (CostAnalyzer(left).cost < MIN_COST) {- return nullptr; // avoidable code is too cheap- }- if (leftEffects.invalidates(rightEffects)) {- return nullptr; // cannot reorder- }- std::swap(left, right);- } else if (leftHasSideEffects) {- if (CostAnalyzer(right).cost < MIN_COST) {- return nullptr; // avoidable code is too cheap- }- } else {- // no side effects, reorder based on cost estimation- auto leftCost = CostAnalyzer(left).cost;- auto rightCost = CostAnalyzer(right).cost;- if (std::max(leftCost, rightCost) < MIN_COST) {- return nullptr; // avoidable code is too cheap- }- // canonicalize with expensive code on the right- if (leftCost > rightCost) {- std::swap(left, right);- }- }- // worth it! perform conditionalization- Builder builder(*getModule());- if (binary->op == OrInt32) {- return builder.makeIf(- left, builder.makeConst(Literal(int32_t(1))), right);- } else { // &- return builder.makeIf(- left, right, builder.makeConst(Literal(int32_t(0))));- }- }-- // We can combine `or` operations, e.g.- // (x > y) | (x == y) ==> x >= y- Expression* combineOr(Binary* binary) {- assert(binary->op == OrInt32);- if (auto* left = binary->left->dynCast<Binary>()) {- if (auto* right = binary->right->dynCast<Binary>()) {- if (left->op != right->op &&- ExpressionAnalyzer::equal(left->left, right->left) &&- ExpressionAnalyzer::equal(left->right, right->right) &&- !effects(left->left).hasSideEffects() &&- !effects(left->right).hasSideEffects()) {- switch (left->op) {- // (x > y) | (x == y) ==> x >= y- case EqInt32: {- if (right->op == GtSInt32) {- left->op = GeSInt32;- return left;- }- break;- }- default: {- }- }- }- }- }- return nullptr;- }-- // fold constant factors into the offset- void optimizeMemoryAccess(Expression*& ptr, Address& offset) {- // ptr may be a const, but it isn't worth folding that in (we still have a- // const); in fact, it's better to do the opposite for gzip purposes as well- // as for readability.- auto* last = ptr->dynCast<Const>();- if (last) {- uint64_t value64 = last->value.getInteger();- uint64_t offset64 = offset;- if (getModule()->memory.is64()) {- last->value = Literal(int64_t(value64 + offset64));- offset = 0;- } else {- // don't do this if it would wrap the pointer- if (value64 <= uint64_t(std::numeric_limits<int32_t>::max()) &&- offset64 <= uint64_t(std::numeric_limits<int32_t>::max()) &&- value64 + offset64 <=- uint64_t(std::numeric_limits<int32_t>::max())) {- last->value = Literal(int32_t(value64 + offset64));- offset = 0;- }- }- }- }-- // Optimize a multiply by a power of two on the right, which- // can be a shift.- // This doesn't shrink code size, and VMs likely optimize it anyhow,- // but it's still worth doing since- // * Often shifts are more common than muls.- // * The constant is smaller.- template<typename T> Expression* optimizePowerOf2Mul(Binary* binary, T c) {- static_assert(std::is_same<T, uint32_t>::value ||- std::is_same<T, uint64_t>::value,- "type mismatch");- auto shifts = Bits::countTrailingZeroes(c);- binary->op = std::is_same<T, uint32_t>::value ? ShlInt32 : ShlInt64;- binary->right->cast<Const>()->value = Literal(static_cast<T>(shifts));- return binary;- }-- // Optimize an unsigned divide / remainder by a power of two on the right- // This doesn't shrink code size, and VMs likely optimize it anyhow,- // but it's still worth doing since- // * Usually ands are more common than urems.- // * The constant is slightly smaller.- template<typename T> Expression* optimizePowerOf2UDiv(Binary* binary, T c) {- static_assert(std::is_same<T, uint32_t>::value ||- std::is_same<T, uint64_t>::value,- "type mismatch");- auto shifts = Bits::countTrailingZeroes(c);- binary->op = std::is_same<T, uint32_t>::value ? ShrUInt32 : ShrUInt64;- binary->right->cast<Const>()->value = Literal(static_cast<T>(shifts));- return binary;- }-- template<typename T> Expression* optimizePowerOf2URem(Binary* binary, T c) {- static_assert(std::is_same<T, uint32_t>::value ||- std::is_same<T, uint64_t>::value,- "type mismatch");- binary->op = std::is_same<T, uint32_t>::value ? AndInt32 : AndInt64;- binary->right->cast<Const>()->value = Literal(c - 1);- return binary;- }-- Expression* makeZeroExt(Expression* curr, int32_t bits) {- Builder builder(*getModule());- return builder.makeBinary(- AndInt32, curr, builder.makeConst(Literal(Bits::lowBitMask(bits))));- }-- // given an "almost" sign extend - either a proper one, or it- // has too many shifts left - we remove the sign extend. If there are- // too many shifts, we split the shifts first, so this removes the- // two sign extend shifts and adds one (smaller one)- Expression* removeAlmostSignExt(Binary* outer) {- auto* inner = outer->left->cast<Binary>();- auto* outerConst = outer->right->cast<Const>();- auto* innerConst = inner->right->cast<Const>();- auto* value = inner->left;- if (outerConst->value == innerConst->value) {- return value;- }- // add a shift, by reusing the existing node- innerConst->value = innerConst->value.sub(outerConst->value);- return inner;- }-- // check if an expression is already sign-extended- bool isSignExted(Expression* curr, Index bits) {- if (Properties::getSignExtValue(curr)) {- return Properties::getSignExtBits(curr) == bits;- }- if (auto* get = curr->dynCast<LocalGet>()) {- // check what we know about the local- return localInfo[get->index].signExtedBits == bits;- }- return false;- }-- // optimize trivial math operations, given that the right side of a binary- // is a constant- Expression* optimizeWithConstantOnRight(Binary* curr) {- using namespace Match;- Builder builder(*getModule());- Expression* left;- auto* right = curr->right->cast<Const>();- auto type = curr->right->type;-- // Operations on zero- if (matches(curr, binary(Abstract::Shl, any(&left), ival(0))) ||- matches(curr, binary(Abstract::ShrU, any(&left), ival(0))) ||- matches(curr, binary(Abstract::ShrS, any(&left), ival(0))) ||- matches(curr, binary(Abstract::Or, any(&left), ival(0))) ||- matches(curr, binary(Abstract::Xor, any(&left), ival(0)))) {- return left;- }- if (matches(curr, binary(Abstract::Mul, pure(&left), ival(0))) ||- matches(curr, binary(Abstract::And, pure(&left), ival(0)))) {- return right;- }- // x == 0 ==> eqz x- if (matches(curr, binary(Abstract::Eq, any(&left), ival(0)))) {- return builder.makeUnary(Abstract::getUnary(type, Abstract::EqZ), left);- }- // Operations on one- // (signed)x % 1 ==> 0- if (matches(curr, binary(Abstract::RemS, pure(&left), ival(1)))) {- right->value = Literal::makeZero(type);- return right;- }- // (signed)x % C_pot != 0 ==> (x & (abs(C_pot) - 1)) != 0- {- Const* c;- Binary* inner;- if (matches(curr,- binary(Abstract::Ne,- binary(&inner, Abstract::RemS, any(), ival(&c)),- ival(0))) &&- (c->value.isSignedMin() ||- Bits::isPowerOf2(c->value.abs().getInteger()))) {- inner->op = Abstract::getBinary(c->type, Abstract::And);- if (c->value.isSignedMin()) {- c->value = Literal::makeSignedMax(c->type);- } else {- c->value = c->value.abs().sub(Literal::makeOne(c->type));- }- return curr;- }- }- // bool(x) | 1 ==> 1- if (matches(curr, binary(Abstract::Or, pure(&left), ival(1))) &&- Bits::getMaxBits(left, this) == 1) {- return right;- }- // bool(x) & 1 ==> bool(x)- if (matches(curr, binary(Abstract::And, any(&left), ival(1))) &&- Bits::getMaxBits(left, this) == 1) {- return left;- }- // bool(x) == 1 ==> bool(x)- if (matches(curr, binary(EqInt32, any(&left), i32(1))) &&- Bits::getMaxBits(left, this) == 1) {- return left;- }- // i64(bool(x)) == 1 ==> i32(bool(x))- // i64(bool(x)) != 0 ==> i32(bool(x))- if ((matches(curr, binary(EqInt64, any(&left), i64(1))) ||- matches(curr, binary(NeInt64, any(&left), i64(0)))) &&- Bits::getMaxBits(left, this) == 1) {- return builder.makeUnary(WrapInt64, left);- }- // bool(x) != 1 ==> !bool(x)- if (matches(curr, binary(Abstract::Ne, any(&left), ival(1))) &&- Bits::getMaxBits(curr->left, this) == 1) {- return builder.makeUnary(Abstract::getUnary(type, Abstract::EqZ), left);- }-- // Operations on all 1s- // x & -1 ==> x- if (matches(curr, binary(Abstract::And, any(&left), ival(-1)))) {- return left;- }- // x | -1 ==> -1- if (matches(curr, binary(Abstract::Or, pure(&left), ival(-1)))) {- return right;- }- // (signed)x % -1 ==> 0- if (matches(curr, binary(Abstract::RemS, pure(&left), ival(-1)))) {- right->value = Literal::makeZero(type);- return right;- }- // (unsigned)x > -1 ==> 0- if (matches(curr, binary(Abstract::GtU, pure(&left), ival(-1)))) {- right->value = Literal::makeZero(Type::i32);- right->type = Type::i32;- return right;- }- // (unsigned)x < -1 ==> x != -1- // Friendlier to JS emitting as we don't need to write an unsigned -1 value- // which is large.- if (matches(curr, binary(Abstract::LtU, any(), ival(-1)))) {- curr->op = Abstract::getBinary(type, Abstract::Ne);- return curr;- }- // x * -1 ==> 0 - x- if (matches(curr, binary(Abstract::Mul, any(&left), ival(-1)))) {- right->value = Literal::makeZero(type);- curr->op = Abstract::getBinary(type, Abstract::Sub);- curr->left = right;- curr->right = left;- return curr;- }- // (unsigned)x <= -1 ==> 1- if (matches(curr, binary(Abstract::LeU, pure(&left), ival(-1)))) {- right->value = Literal::makeOne(Type::i32);- right->type = Type::i32;- return right;- }- {- // ~(1 << x) aka (1 << x) ^ -1 ==> rotl(-2, x)- Expression* x;- if (matches(curr,- binary(Abstract::Xor,- binary(Abstract::Shl, ival(1), any(&x)),- ival(-1)))) {- curr->op = Abstract::getBinary(type, Abstract::RotL);- right->value = Literal::makeFromInt32(-2, type);- curr->left = right;- curr->right = x;- return curr;- }- }- {- // Wasm binary encoding uses signed LEBs, which slightly favor negative- // numbers: -64 is more efficient than +64 etc., as well as other powers- // of two 7 bits etc. higher. we therefore prefer x - -64 over x + 64. in- // theory we could just prefer negative numbers over positive, but that- // can have bad effects on gzip compression (as it would mean more- // subtractions than the more common additions). TODO: Simplify this by- // adding an ival matcher than can bind int64_t vars.- int64_t value;- if ((matches(curr, binary(Abstract::Add, any(), ival(&value))) ||- matches(curr, binary(Abstract::Sub, any(), ival(&value)))) &&- (value == 0x40 || value == 0x2000 || value == 0x100000 ||- value == 0x8000000 || value == 0x400000000LL ||- value == 0x20000000000LL || value == 0x1000000000000LL ||- value == 0x80000000000000LL || value == 0x4000000000000000LL)) {- right->value = right->value.neg();- if (matches(curr, binary(Abstract::Add, any(), constant()))) {- curr->op = Abstract::getBinary(type, Abstract::Sub);- } else {- curr->op = Abstract::getBinary(type, Abstract::Add);- }- return curr;- }- }- {- double value;- if (matches(curr, binary(Abstract::Sub, any(), fval(&value))) &&- value == 0.0) {- // x - (-0.0) ==> x + 0.0- if (std::signbit(value)) {- curr->op = Abstract::getBinary(type, Abstract::Add);- right->value = right->value.neg();- return curr;- } else if (fastMath) {- // x - 0.0 ==> x- return curr->left;- }- }- }- {- // x + (-0.0) ==> x- double value;- if (fastMath &&- matches(curr, binary(Abstract::Add, any(), fval(&value))) &&- value == 0.0 && std::signbit(value)) {- return curr->left;- }- }- // x * -1.0 ==> -x- if (fastMath && matches(curr, binary(Abstract::Mul, any(), fval(-1.0)))) {- return builder.makeUnary(Abstract::getUnary(type, Abstract::Neg), left);- }- if (matches(curr, binary(Abstract::Mul, any(&left), constant(1))) ||- matches(curr, binary(Abstract::DivS, any(&left), constant(1))) ||- matches(curr, binary(Abstract::DivU, any(&left), constant(1)))) {- if (curr->type.isInteger() || fastMath) {- return left;- }- }- return nullptr;- }-- // optimize trivial math operations, given that the left side of a binary- // is a constant. since we canonicalize constants to the right for symmetrical- // operations, we only need to handle asymmetrical ones here- // TODO: templatize on type?- Expression* optimizeWithConstantOnLeft(Binary* binary) {- auto type = binary->left->type;- auto* left = binary->left->cast<Const>();- if (type.isInteger()) {- // operations on zero- if (left->value == Literal::makeFromInt32(0, type)) {- if ((binary->op == Abstract::getBinary(type, Abstract::Shl) ||- binary->op == Abstract::getBinary(type, Abstract::ShrU) ||- binary->op == Abstract::getBinary(type, Abstract::ShrS)) &&- !effects(binary->right).hasSideEffects()) {- return binary->left;- }- }- }- return nullptr;- }-- // TODO: templatize on type?- Expression* optimizeRelational(Binary* binary) {- // TODO: inequalities can also work, if the constants do not overflow- auto type = binary->right->type;- // integer math, even on 2s complement, allows stuff like- // x + 5 == 7- // =>- // x == 2- if (binary->left->type.isInteger()) {- if (binary->op == Abstract::getBinary(type, Abstract::Eq) ||- binary->op == Abstract::getBinary(type, Abstract::Ne)) {- if (auto* left = binary->left->dynCast<Binary>()) {- if (left->op == Abstract::getBinary(type, Abstract::Add) ||- left->op == Abstract::getBinary(type, Abstract::Sub)) {- if (auto* leftConst = left->right->dynCast<Const>()) {- if (auto* rightConst = binary->right->dynCast<Const>()) {- return combineRelationalConstants(- binary, left, leftConst, nullptr, rightConst);- } else if (auto* rightBinary = binary->right->dynCast<Binary>()) {- if (rightBinary->op ==- Abstract::getBinary(type, Abstract::Add) ||- rightBinary->op ==- Abstract::getBinary(type, Abstract::Sub)) {- if (auto* rightConst = rightBinary->right->dynCast<Const>()) {- return combineRelationalConstants(- binary, left, leftConst, rightBinary, rightConst);- }- }- }- }- }- }- }- }- return nullptr;- }-- Expression* deduplicateUnary(Unary* unaryOuter) {- if (auto* unaryInner = unaryOuter->value->dynCast<Unary>()) {- if (unaryInner->op == unaryOuter->op) {- switch (unaryInner->op) {- case NegFloat32:- case NegFloat64: {- // neg(neg(x)) ==> x- return unaryInner->value;- }- case AbsFloat32:- case CeilFloat32:- case FloorFloat32:- case TruncFloat32:- case NearestFloat32:- case AbsFloat64:- case CeilFloat64:- case FloorFloat64:- case TruncFloat64:- case NearestFloat64: {- // unaryOp(unaryOp(x)) ==> unaryOp(x)- return unaryInner;- }- case ExtendS8Int32:- case ExtendS16Int32: {- assert(getModule()->features.hasSignExt());- return unaryInner;- }- case EqZInt32: {- // eqz(eqz(bool(x))) ==> bool(x)- if (Bits::getMaxBits(unaryInner->value, this) == 1) {- return unaryInner->value;- }- break;- }- default: {- }- }- }- }- return nullptr;- }-- Expression* deduplicateBinary(Binary* outer) {- Type type = outer->type;- if (type.isInteger()) {- if (auto* inner = outer->right->dynCast<Binary>()) {- if (outer->op == inner->op) {- if (!EffectAnalyzer(- getPassOptions(), getModule()->features, outer->left)- .hasSideEffects()) {- if (ExpressionAnalyzer::equal(inner->left, outer->left)) {- // x - (x - y) ==> y- // x ^ (x ^ y) ==> y- if (outer->op == Abstract::getBinary(type, Abstract::Sub) ||- outer->op == Abstract::getBinary(type, Abstract::Xor)) {- return inner->right;- }- // x & (x & y) ==> x & y- // x | (x | y) ==> x | y- if (outer->op == Abstract::getBinary(type, Abstract::And) ||- outer->op == Abstract::getBinary(type, Abstract::Or)) {- return inner;- }- }- if (ExpressionAnalyzer::equal(inner->right, outer->left) &&- canReorder(outer->left, inner->left)) {- // x ^ (y ^ x) ==> y- // (note that we need the check for reordering here because if- // e.g. y writes to a local that x reads, the second appearance- // of x would be different from the first)- if (outer->op == Abstract::getBinary(type, Abstract::Xor)) {- return inner->left;- }-- // x & (y & x) ==> y & x- // x | (y | x) ==> y | x- // (here we need the check for reordering for the more obvious- // reason that previously x appeared before y, and now y appears- // first; or, if we tried to emit x [&|] y here, reversing the- // order, we'd be in the same situation as the previous comment)- if (outer->op == Abstract::getBinary(type, Abstract::And) ||- outer->op == Abstract::getBinary(type, Abstract::Or)) {- return inner;- }- }- }- }- }- if (auto* inner = outer->left->dynCast<Binary>()) {- if (outer->op == inner->op) {- if (!EffectAnalyzer(- getPassOptions(), getModule()->features, outer->right)- .hasSideEffects()) {- if (ExpressionAnalyzer::equal(inner->right, outer->right)) {- // (x ^ y) ^ y ==> x- if (outer->op == Abstract::getBinary(type, Abstract::Xor)) {- return inner->left;- }- // (x % y) % y ==> x % y- // (x & y) & y ==> x & y- // (x | y) | y ==> x | y- if (outer->op == Abstract::getBinary(type, Abstract::RemS) ||- outer->op == Abstract::getBinary(type, Abstract::RemU) ||- outer->op == Abstract::getBinary(type, Abstract::And) ||- outer->op == Abstract::getBinary(type, Abstract::Or)) {- return inner;- }- }- // See comments in the parallel code earlier about ordering here.- if (ExpressionAnalyzer::equal(inner->left, outer->right) &&- canReorder(inner->left, inner->right)) {- // (x ^ y) ^ x ==> y- if (outer->op == Abstract::getBinary(type, Abstract::Xor)) {- return inner->right;- }- // (x & y) & x ==> x & y- // (x | y) | x ==> x | y- if (outer->op == Abstract::getBinary(type, Abstract::And) ||- outer->op == Abstract::getBinary(type, Abstract::Or)) {- return inner;- }- }- }- }- }- }- return nullptr;- }-- // given a relational binary with a const on both sides, combine the constants- // left is also a binary, and has a constant; right may be just a constant, in- // which case right is nullptr- Expression* combineRelationalConstants(Binary* binary,- Binary* left,- Const* leftConst,- Binary* right,- Const* rightConst) {- auto type = binary->right->type;- // we fold constants to the right- Literal extra = leftConst->value;- if (left->op == Abstract::getBinary(type, Abstract::Sub)) {- extra = extra.neg();- }- if (right && right->op == Abstract::getBinary(type, Abstract::Sub)) {- extra = extra.neg();- }- rightConst->value = rightConst->value.sub(extra);- binary->left = left->left;- return binary;- }-- Expression* optimizeMemoryCopy(MemoryCopy* memCopy) {- PassOptions options = getPassOptions();-- if (options.ignoreImplicitTraps) {- if (ExpressionAnalyzer::equal(memCopy->dest, memCopy->source)) {- // memory.copy(x, x, sz) ==> {drop(x), drop(x), drop(sz)}- Builder builder(*getModule());- return builder.makeBlock({builder.makeDrop(memCopy->dest),- builder.makeDrop(memCopy->source),- builder.makeDrop(memCopy->size)});- }- }-- // memory.copy(dst, src, C) ==> store(dst, load(src))- if (auto* csize = memCopy->size->dynCast<Const>()) {- auto bytes = csize->value.geti32();- Builder builder(*getModule());-- switch (bytes) {- case 0: {- if (options.ignoreImplicitTraps) {- // memory.copy(dst, src, 0) ==> {drop(dst), drop(src)}- return builder.makeBlock({builder.makeDrop(memCopy->dest),- builder.makeDrop(memCopy->source)});- }- break;- }- case 1:- case 2:- case 4: {- return builder.makeStore(- bytes, // bytes- 0, // offset- 1, // align- memCopy->dest,- builder.makeLoad(bytes, false, 0, 1, memCopy->source, Type::i32),- Type::i32);- }- case 8: {- return builder.makeStore(- bytes, // bytes- 0, // offset- 1, // align- memCopy->dest,- builder.makeLoad(bytes, false, 0, 1, memCopy->source, Type::i64),- Type::i64);- }- case 16: {- if (options.shrinkLevel == 0) {- // This adds an extra 2 bytes so apply it only for- // minimal shrink level- if (getModule()->features.hasSIMD()) {- return builder.makeStore(- bytes, // bytes- 0, // offset- 1, // align- memCopy->dest,- builder.makeLoad(- bytes, false, 0, 1, memCopy->source, Type::v128),- Type::v128);- }- }- }- default: {- }- }- }- return nullptr;- }-- // given a binary expression with equal children and no side effects in- // either, we can fold various things- Expression* optimizeBinaryWithEqualEffectlessChildren(Binary* binary) {- // TODO add: perhaps worth doing 2*x if x is quite large?- switch (binary->op) {- case SubInt32:- case XorInt32:- case SubInt64:- case XorInt64:- return LiteralUtils::makeZero(binary->left->type, *getModule());- case NeInt32:- case LtSInt32:- case LtUInt32:- case GtSInt32:- case GtUInt32:- case NeInt64:- case LtSInt64:- case LtUInt64:- case GtSInt64:- case GtUInt64:- return LiteralUtils::makeZero(Type::i32, *getModule());- case AndInt32:- case OrInt32:- case AndInt64:- case OrInt64:- return binary->left;- case EqInt32:- case LeSInt32:- case LeUInt32:- case GeSInt32:- case GeUInt32:- case EqInt64:- case LeSInt64:- case LeUInt64:- case GeSInt64:- case GeUInt64:- return LiteralUtils::makeFromInt32(1, Type::i32, *getModule());- default:- return nullptr;- }- }-- BinaryOp invertBinaryOp(BinaryOp op) {- // use de-morgan's laws- switch (op) {- case EqInt32:- return NeInt32;- case NeInt32:- return EqInt32;- case LtSInt32:- return GeSInt32;- case LtUInt32:- return GeUInt32;- case LeSInt32:- return GtSInt32;- case LeUInt32:- return GtUInt32;- case GtSInt32:- return LeSInt32;- case GtUInt32:- return LeUInt32;- case GeSInt32:- return LtSInt32;- case GeUInt32:- return LtUInt32;-- case EqInt64:- return NeInt64;- case NeInt64:- return EqInt64;- case LtSInt64:- return GeSInt64;- case LtUInt64:- return GeUInt64;- case LeSInt64:- return GtSInt64;- case LeUInt64:- return GtUInt64;- case GtSInt64:- return LeSInt64;- case GtUInt64:- return LeUInt64;- case GeSInt64:- return LtSInt64;- case GeUInt64:- return LtUInt64;-- case EqFloat32:- return NeFloat32;- case NeFloat32:- return EqFloat32;-- case EqFloat64:- return NeFloat64;- case NeFloat64:- return EqFloat64;-- default:- return InvalidBinary;- }- }-- BinaryOp makeUnsignedBinaryOp(BinaryOp op) {- switch (op) {- case DivSInt32:- return DivUInt32;- case RemSInt32:- return RemUInt32;- case ShrSInt32:- return ShrUInt32;- case LtSInt32:- return LtUInt32;- case LeSInt32:- return LeUInt32;- case GtSInt32:- return GtUInt32;- case GeSInt32:- return GeUInt32;-- case DivSInt64:- return DivUInt64;- case RemSInt64:- return RemUInt64;- case ShrSInt64:- return ShrUInt64;- case LtSInt64:- return LtUInt64;- case LeSInt64:- return LeUInt64;- case GtSInt64:- return GtUInt64;- case GeSInt64:- return GeUInt64;-- default:- return InvalidBinary;- }- }-- bool isSymmetric(Binary* binary) {- if (Properties::isSymmetric(binary)) {- return true;- }- switch (binary->op) {- case AddFloat32:- case MulFloat32:- case AddFloat64:- case MulFloat64: {- // If the LHS is known to be non-NaN, the operands can commute.- // We don't care about the RHS because right now we only know if- // an expression is non-NaN if it is constant, but if the RHS is- // constant, then this expression is already canonicalized.- if (auto* c = binary->left->dynCast<Const>()) {- return !c->value.isNaN();- }- return false;- }- default:- return false;- }- }-};--Pass* createOptimizeInstructionsPass() { return new OptimizeInstructions(); }+#include <cmath>+#include <type_traits>++#include <ir/abstract.h>+#include <ir/bits.h>+#include <ir/cost.h>+#include <ir/effects.h>+#include <ir/literal-utils.h>+#include <ir/load-utils.h>+#include <ir/manipulation.h>+#include <ir/match.h>+#include <ir/properties.h>+#include <ir/utils.h>+#include <pass.h>+#include <support/threads.h>+#include <wasm.h>++// TODO: Use the new sign-extension opcodes where appropriate. This needs to be+// conditionalized on the availability of atomics.++namespace wasm {++Name I32_EXPR = "i32.expr";+Name I64_EXPR = "i64.expr";+Name F32_EXPR = "f32.expr";+Name F64_EXPR = "f64.expr";+Name ANY_EXPR = "any.expr";++// Useful information about locals+struct LocalInfo {+ static const Index kUnknown = Index(-1);++ Index maxBits;+ Index signExtedBits;+};++struct LocalScanner : PostWalker<LocalScanner> {+ std::vector<LocalInfo>& localInfo;+ const PassOptions& passOptions;++ LocalScanner(std::vector<LocalInfo>& localInfo,+ const PassOptions& passOptions)+ : localInfo(localInfo), passOptions(passOptions) {}++ void doWalkFunction(Function* func) {+ // prepare+ localInfo.resize(func->getNumLocals());+ for (Index i = 0; i < func->getNumLocals(); i++) {+ auto& info = localInfo[i];+ if (func->isParam(i)) {+ info.maxBits = getBitsForType(func->getLocalType(i)); // worst-case+ info.signExtedBits = LocalInfo::kUnknown; // we will never know anything+ } else {+ info.maxBits = info.signExtedBits = 0; // we are open to learning+ }+ }+ // walk+ PostWalker<LocalScanner>::doWalkFunction(func);+ // finalize+ for (Index i = 0; i < func->getNumLocals(); i++) {+ auto& info = localInfo[i];+ if (info.signExtedBits == LocalInfo::kUnknown) {+ info.signExtedBits = 0;+ }+ }+ }++ void visitLocalSet(LocalSet* curr) {+ auto* func = getFunction();+ if (func->isParam(curr->index)) {+ return;+ }+ auto type = getFunction()->getLocalType(curr->index);+ if (type != Type::i32 && type != Type::i64) {+ return;+ }+ // an integer var, worth processing+ auto* value = Properties::getFallthrough(+ curr->value, passOptions, getModule()->features);+ auto& info = localInfo[curr->index];+ info.maxBits = std::max(info.maxBits, Bits::getMaxBits(value, this));+ auto signExtBits = LocalInfo::kUnknown;+ if (Properties::getSignExtValue(value)) {+ signExtBits = Properties::getSignExtBits(value);+ } else if (auto* load = value->dynCast<Load>()) {+ if (LoadUtils::isSignRelevant(load) && load->signed_) {+ signExtBits = load->bytes * 8;+ }+ }+ if (info.signExtedBits == 0) {+ info.signExtedBits = signExtBits; // first info we see+ } else if (info.signExtedBits != signExtBits) {+ // contradictory information, give up+ info.signExtedBits = LocalInfo::kUnknown;+ }+ }++ // define this for the templated getMaxBits method. we know nothing here yet+ // about locals, so return the maxes+ Index getMaxBitsForLocal(LocalGet* get) { return getBitsForType(get->type); }++ Index getBitsForType(Type type) {+ if (!type.isBasic()) {+ return -1;+ }+ switch (type.getBasic()) {+ case Type::i32:+ return 32;+ case Type::i64:+ return 64;+ default:+ return -1;+ }+ }+};++namespace {+// perform some final optimizations+struct FinalOptimizer : public PostWalker<FinalOptimizer> {+ const PassOptions& passOptions;++ FinalOptimizer(const PassOptions& passOptions) : passOptions(passOptions) {}++ void visitBinary(Binary* curr) {+ if (auto* replacement = optimize(curr)) {+ replaceCurrent(replacement);+ }+ }++ Binary* optimize(Binary* curr) {+ using namespace Abstract;+ using namespace Match;+ {+ Const* c;+ if (matches(curr, binary(Add, any(), ival(&c)))) {+ // normalize x + (-C) ==> x - C+ if (c->value.isNegative()) {+ c->value = c->value.neg();+ curr->op = Abstract::getBinary(c->type, Sub);+ }+ // Wasm binary encoding uses signed LEBs, which slightly favor negative+ // numbers: -64 is more efficient than +64 etc., as well as other powers+ // of two 7 bits etc. higher. we therefore prefer x - -64 over x + 64.+ // in theory we could just prefer negative numbers over positive, but+ // that can have bad effects on gzip compression (as it would mean more+ // subtractions than the more common additions).+ int64_t value = c->value.getInteger();+ if (value == 0x40LL || value == 0x2000LL || value == 0x100000LL ||+ value == 0x8000000LL || value == 0x400000000LL ||+ value == 0x20000000000LL || value == 0x1000000000000LL ||+ value == 0x80000000000000LL || value == 0x4000000000000000LL) {+ c->value = c->value.neg();+ if (curr->op == Abstract::getBinary(c->type, Add)) {+ curr->op = Abstract::getBinary(c->type, Sub);+ } else {+ curr->op = Abstract::getBinary(c->type, Add);+ }+ }+ return curr;+ }+ }+ return nullptr;+ }+};++} // anonymous namespace++// Create a custom matcher for checking side effects+template<class Opt> struct PureMatcherKind {};+template<class Opt>+struct Match::Internal::KindTypeRegistry<PureMatcherKind<Opt>> {+ using matched_t = Expression*;+ using data_t = Opt*;+};+template<class Opt> struct Match::Internal::MatchSelf<PureMatcherKind<Opt>> {+ bool operator()(Expression* curr, Opt* opt) {+ return !opt->effects(curr).hasSideEffects();+ }+};++// Main pass class+struct OptimizeInstructions+ : public WalkerPass<+ PostWalker<OptimizeInstructions,+ UnifiedExpressionVisitor<OptimizeInstructions>>> {+ bool isFunctionParallel() override { return true; }++ Pass* create() override { return new OptimizeInstructions; }++ bool fastMath;++ void doWalkFunction(Function* func) {+ fastMath = getPassOptions().fastMath;+ // first, scan locals+ {+ LocalScanner scanner(localInfo, getPassOptions());+ scanner.setModule(getModule());+ scanner.walkFunction(func);+ }+ // main walk+ super::doWalkFunction(func);+ {+ FinalOptimizer optimizer(getPassOptions());+ optimizer.walkFunction(func);+ }+ }++ void visitExpression(Expression* curr) {+ // if this contains dead code, don't bother trying to optimize it, the type+ // might change (if might not be unreachable if just one arm is, for+ // example). this optimization pass focuses on actually executing code. the+ // only exceptions are control flow changes+ if (curr->is<Const>() || curr->is<Call>() || curr->is<Nop>() ||+ (curr->type == Type::unreachable && !curr->is<Break>() &&+ !curr->is<Switch>() && !curr->is<If>())) {+ return;+ }+ // we may be able to apply multiple patterns, one may open opportunities+ // that look deeper NB: patterns must not have cycles+ while ((curr = handOptimize(curr))) {+ replaceCurrent(curr);+ }+ }++ EffectAnalyzer effects(Expression* expr) {+ return EffectAnalyzer(getPassOptions(), getModule()->features, expr);+ }++ decltype(auto) pure(Expression** binder) {+ using namespace Match::Internal;+ return Matcher<PureMatcherKind<OptimizeInstructions>>(binder, this);+ }++ bool canReorder(Expression* a, Expression* b) {+ return EffectAnalyzer::canReorder(+ getPassOptions(), getModule()->features, a, b);+ }++ // Optimizations that don't yet fit in the pattern DSL, but could be+ // eventually maybe+ Expression* handOptimize(Expression* curr) {+ if (curr->is<Const>()) {+ return nullptr;+ }++ FeatureSet features = getModule()->features;++ if (auto* binary = curr->dynCast<Binary>()) {+ if (shouldCanonicalize(binary)) {+ canonicalize(binary);+ }+ }++ {+ // TODO: It is an ongoing project to port more transformations to the+ // match API. Once most of the transformations have been ported, the+ // `using namespace Match` can be hoisted to function scope and this extra+ // block scope can be removed.+ using namespace Match;+ using namespace Abstract;+ Builder builder(*getModule());+ {+ // try to get rid of (0 - ..), that is, a zero only used to negate an+ // int. an add of a subtract can be flipped in order to remove it:+ // (ival.add+ // (ival.sub+ // (ival.const 0)+ // X+ // )+ // Y+ // )+ // =>+ // (ival.sub+ // Y+ // X+ // )+ // Note that this reorders X and Y, so we need to be careful about that.+ Expression *x, *y;+ Binary* sub;+ if (matches(+ curr,+ binary(Add, binary(&sub, Sub, ival(0), any(&x)), any(&y))) &&+ canReorder(x, y)) {+ sub->left = y;+ sub->right = x;+ return sub;+ }+ }+ {+ // The flip case is even easier, as no reordering occurs:+ // (ival.add+ // Y+ // (ival.sub+ // (ival.const 0)+ // X+ // )+ // )+ // =>+ // (ival.sub+ // Y+ // X+ // )+ Expression* y;+ Binary* sub;+ if (matches(curr,+ binary(Add, any(&y), binary(&sub, Sub, ival(0), any())))) {+ sub->left = y;+ return sub;+ }+ }+ {+ // eqz(x - y) => x == y+ Binary* inner;+ if (matches(curr, unary(EqZ, binary(&inner, Sub, any(), any())))) {+ inner->op = Abstract::getBinary(inner->left->type, Eq);+ inner->type = Type::i32;+ return inner;+ }+ }+ {+ // eqz(x + C) => x == -C+ Const* c;+ Binary* inner;+ if (matches(curr, unary(EqZ, binary(&inner, Add, any(), ival(&c))))) {+ c->value = c->value.neg();+ inner->op = Abstract::getBinary(c->type, Eq);+ inner->type = Type::i32;+ return inner;+ }+ }+ {+ // eqz((signed)x % C_pot) => eqz(x & (abs(C_pot) - 1))+ Const* c;+ Binary* inner;+ if (matches(curr, unary(EqZ, binary(&inner, RemS, any(), ival(&c)))) &&+ (c->value.isSignedMin() ||+ Bits::isPowerOf2(c->value.abs().getInteger()))) {+ inner->op = Abstract::getBinary(c->type, And);+ if (c->value.isSignedMin()) {+ c->value = Literal::makeSignedMax(c->type);+ } else {+ c->value = c->value.abs().sub(Literal::makeOne(c->type));+ }+ return curr;+ }+ }+ {+ // try de-morgan's AND law,+ // (eqz X) and (eqz Y) === eqz (X or Y)+ // Note that the OR and XOR laws do not work here, as these+ // are not booleans (we could check if they are, but a boolean+ // would already optimize with the eqz anyhow, unless propagating).+ // But for AND, the left is true iff X and Y are each all zero bits,+ // and the right is true if the union of their bits is zero; same.+ Unary* un;+ Binary* bin;+ Expression *x, *y;+ if (matches(curr,+ binary(&bin,+ AndInt32,+ unary(&un, EqZInt32, any(&x)),+ unary(EqZInt32, any(&y))))) {+ bin->op = OrInt32;+ bin->left = x;+ bin->right = y;+ un->value = bin;+ return un;+ }+ }+ {+ // i32.eqz(i32.wrap_i64(x)) => i64.eqz(x)+ // where maxBits(x) <= 32+ Unary* inner;+ Expression* x;+ if (matches(curr, unary(EqZInt32, unary(&inner, WrapInt64, any(&x)))) &&+ Bits::getMaxBits(x, this) <= 32) {+ inner->op = EqZInt64;+ inner->value = x;+ return inner;+ }+ }+ {+ // x <<>> (C & (31 | 63)) ==> x <<>> C'+ // x <<>> (y & (31 | 63)) ==> x <<>> y+ // x <<>> (y & (32 | 64)) ==> x+ // where '<<>>':+ // '<<', '>>', '>>>'. 'rotl' or 'rotr'+ BinaryOp op;+ Const* c;+ Expression *x, *y;++ // x <<>> C+ if (matches(curr, binary(&op, any(&x), ival(&c))) &&+ Abstract::hasAnyShift(op)) {+ // truncate RHS constant to effective size as:+ // i32(x) <<>> const(C & 31))+ // i64(x) <<>> const(C & 63))+ c->value = c->value.and_(+ Literal::makeFromInt32(c->type.getByteSize() * 8 - 1, c->type));+ // x <<>> 0 ==> x+ if (c->value.isZero()) {+ return x;+ }+ }+ if (matches(curr,+ binary(&op, any(&x), binary(And, any(&y), ival(&c)))) &&+ Abstract::hasAnyShift(op)) {+ // i32(x) <<>> (y & 31) ==> x <<>> y+ // i64(x) <<>> (y & 63) ==> x <<>> y+ if ((c->type == Type::i32 && (c->value.geti32() & 31) == 31) ||+ (c->type == Type::i64 && (c->value.geti64() & 63LL) == 63LL)) {+ curr->cast<Binary>()->right = y;+ return curr;+ }+ // i32(x) <<>> (y & C) ==> x, where (C & 31) == 0+ // i64(x) <<>> (y & C) ==> x, where (C & 63) == 0+ if (((c->type == Type::i32 && (c->value.geti32() & 31) == 0) ||+ (c->type == Type::i64 && (c->value.geti64() & 63LL) == 0LL)) &&+ !effects(y).hasSideEffects()) {+ return x;+ }+ }+ }+ {+ // unsigned(x) >= 0 => i32(1)+ Const* c;+ Expression* x;+ if (matches(curr, binary(GeU, pure(&x), ival(&c))) &&+ c->value.isZero()) {+ c->value = Literal::makeOne(Type::i32);+ c->type = Type::i32;+ return c;+ }+ // unsigned(x) < 0 => i32(0)+ if (matches(curr, binary(LtU, pure(&x), ival(&c))) &&+ c->value.isZero()) {+ c->value = Literal::makeZero(Type::i32);+ c->type = Type::i32;+ return c;+ }+ }+ }++ if (auto* select = curr->dynCast<Select>()) {+ return optimizeSelect(select);+ }++ if (auto* binary = curr->dynCast<Binary>()) {+ if (auto* ext = Properties::getAlmostSignExt(binary)) {+ Index extraLeftShifts;+ auto bits = Properties::getAlmostSignExtBits(binary, extraLeftShifts);+ if (extraLeftShifts == 0) {+ if (auto* load =+ Properties::getFallthrough(ext, getPassOptions(), features)+ ->dynCast<Load>()) {+ // pattern match a load of 8 bits and a sign extend using a shl of+ // 24 then shr_s of 24 as well, etc.+ if (LoadUtils::canBeSigned(load) &&+ ((load->bytes == 1 && bits == 8) ||+ (load->bytes == 2 && bits == 16))) {+ // if the value falls through, we can't alter the load, as it+ // might be captured in a tee+ if (load->signed_ == true || load == ext) {+ load->signed_ = true;+ return ext;+ }+ }+ }+ }+ // We can in some cases remove part of a sign extend, that is,+ // (x << A) >> B => x << (A - B)+ // If the sign-extend input cannot have a sign bit, we don't need it.+ if (Bits::getMaxBits(ext, this) + extraLeftShifts < bits) {+ return removeAlmostSignExt(binary);+ }+ // We also don't need it if it already has an identical-sized sign+ // extend applied to it. That is, if it is already a sign-extended+ // value, then another sign extend will do nothing. We do need to be+ // careful of the extra shifts, though.+ if (isSignExted(ext, bits) && extraLeftShifts == 0) {+ return removeAlmostSignExt(binary);+ }+ } else if (binary->op == EqInt32 || binary->op == NeInt32) {+ if (auto* c = binary->right->dynCast<Const>()) {+ if (auto* ext = Properties::getSignExtValue(binary->left)) {+ // We are comparing a sign extend to a constant, which means we can+ // use a cheaper zero-extend in some cases. That is,+ // (x << S) >> S ==/!= C => x & T ==/!= C+ // where S and T are the matching values for sign/zero extend of the+ // same size. For example, for an effective 8-bit value:+ // (x << 24) >> 24 ==/!= C => x & 255 ==/!= C+ //+ // The key thing to track here are the upper bits plus the sign bit;+ // call those the "relevant bits". This is crucial because x is+ // sign-extended, that is, its effective sign bit is spread to all+ // the upper bits, which means that the relevant bits on the left+ // side are either all 0, or all 1.+ auto bits = Properties::getSignExtBits(binary->left);+ uint32_t right = c->value.geti32();+ uint32_t numRelevantBits = 32 - bits + 1;+ uint32_t setRelevantBits =+ Bits::popCount(right >> uint32_t(bits - 1));+ // If all the relevant bits on C are zero+ // then we can mask off the high bits instead of sign-extending x.+ // This is valid because if x is negative, then the comparison was+ // false before (negative vs positive), and will still be false+ // as the sign bit will remain to cause a difference. And if x is+ // positive then the upper bits would be zero anyhow.+ if (setRelevantBits == 0) {+ binary->left = makeZeroExt(ext, bits);+ return binary;+ } else if (setRelevantBits == numRelevantBits) {+ // If all those bits are one, then we can do something similar if+ // we also zero-extend on the right as well. This is valid+ // because, as in the previous case, the sign bit differentiates+ // the two sides when they are different, and if the sign bit is+ // identical, then the upper bits don't matter, so masking them+ // off both sides is fine.+ binary->left = makeZeroExt(ext, bits);+ c->value = c->value.and_(Literal(Bits::lowBitMask(bits)));+ return binary;+ } else {+ // Otherwise, C's relevant bits are mixed, and then the two sides+ // can never be equal, as the left side's bits cannot be mixed.+ Builder builder(*getModule());+ // The result is either always true, or always false.+ c->value = Literal::makeFromInt32(binary->op == NeInt32, c->type);+ return builder.makeSequence(builder.makeDrop(ext), c);+ }+ }+ } else if (auto* left = Properties::getSignExtValue(binary->left)) {+ if (auto* right = Properties::getSignExtValue(binary->right)) {+ auto bits = Properties::getSignExtBits(binary->left);+ if (Properties::getSignExtBits(binary->right) == bits) {+ // we are comparing two sign-exts with the same bits, so we may as+ // well replace both with cheaper zexts+ binary->left = makeZeroExt(left, bits);+ binary->right = makeZeroExt(right, bits);+ return binary;+ }+ } else if (auto* load = binary->right->dynCast<Load>()) {+ // we are comparing a load to a sign-ext, we may be able to switch+ // to zext+ auto leftBits = Properties::getSignExtBits(binary->left);+ if (load->signed_ && leftBits == load->bytes * 8) {+ load->signed_ = false;+ binary->left = makeZeroExt(left, leftBits);+ return binary;+ }+ }+ } else if (auto* load = binary->left->dynCast<Load>()) {+ if (auto* right = Properties::getSignExtValue(binary->right)) {+ // we are comparing a load to a sign-ext, we may be able to switch+ // to zext+ auto rightBits = Properties::getSignExtBits(binary->right);+ if (load->signed_ && rightBits == load->bytes * 8) {+ load->signed_ = false;+ binary->right = makeZeroExt(right, rightBits);+ return binary;+ }+ }+ }+ // note that both left and right may be consts, but then we let+ // precompute compute the constant result+ } else if (binary->op == AddInt32 || binary->op == AddInt64 ||+ binary->op == SubInt32 || binary->op == SubInt64) {+ if (auto* ret = optimizeAddedConstants(binary)) {+ return ret;+ }+ } else if (binary->op == MulFloat32 || binary->op == MulFloat64 ||+ binary->op == DivFloat32 || binary->op == DivFloat64) {+ if (binary->left->type == binary->right->type) {+ if (auto* leftUnary = binary->left->dynCast<Unary>()) {+ if (leftUnary->op ==+ Abstract::getUnary(binary->type, Abstract::Abs)) {+ if (auto* rightUnary = binary->right->dynCast<Unary>()) {+ if (leftUnary->op == rightUnary->op) { // both are abs ops+ // abs(x) * abs(y) ==> abs(x * y)+ // abs(x) / abs(y) ==> abs(x / y)+ binary->left = leftUnary->value;+ binary->right = rightUnary->value;+ leftUnary->value = binary;+ return leftUnary;+ }+ }+ }+ }+ }+ }+ // a bunch of operations on a constant right side can be simplified+ if (auto* right = binary->right->dynCast<Const>()) {+ if (binary->op == AndInt32) {+ auto mask = right->value.geti32();+ // and with -1 does nothing (common in asm.js output)+ if (mask == -1) {+ return binary->left;+ }+ // small loads do not need to be masked, the load itself masks+ if (auto* load = binary->left->dynCast<Load>()) {+ if ((load->bytes == 1 && mask == 0xff) ||+ (load->bytes == 2 && mask == 0xffff)) {+ load->signed_ = false;+ return binary->left;+ }+ } else if (auto maskedBits = Bits::getMaskedBits(mask)) {+ if (Bits::getMaxBits(binary->left, this) <= maskedBits) {+ // a mask of lower bits is not needed if we are already smaller+ return binary->left;+ }+ }+ }+ // some math operations have trivial results+ if (auto* ret = optimizeWithConstantOnRight(binary)) {+ return ret;+ }+ // the square of some operations can be merged+ if (auto* left = binary->left->dynCast<Binary>()) {+ if (left->op == binary->op) {+ if (auto* leftRight = left->right->dynCast<Const>()) {+ if (left->op == AndInt32 || left->op == AndInt64) {+ leftRight->value = leftRight->value.and_(right->value);+ return left;+ } else if (left->op == OrInt32 || left->op == OrInt64) {+ leftRight->value = leftRight->value.or_(right->value);+ return left;+ } else if (left->op == XorInt32 || left->op == XorInt64) {+ leftRight->value = leftRight->value.xor_(right->value);+ return left;+ } else if (left->op == MulInt32 || left->op == MulInt64) {+ leftRight->value = leftRight->value.mul(right->value);+ return left;++ // TODO:+ // handle signed / unsigned divisions. They are more complex+ } else if (left->op == ShlInt32 || left->op == ShrUInt32 ||+ left->op == ShrSInt32 || left->op == ShlInt64 ||+ left->op == ShrUInt64 || left->op == ShrSInt64) {+ // shifts only use an effective amount from the constant, so+ // adding must be done carefully+ auto total = Bits::getEffectiveShifts(leftRight) ++ Bits::getEffectiveShifts(right);+ if (total == Bits::getEffectiveShifts(total, right->type)) {+ // no overflow, we can do this+ leftRight->value = Literal::makeFromInt32(total, right->type);+ return left;+ } // TODO: handle overflows+ }+ }+ }+ }+ if (right->type == Type::i32) {+ BinaryOp op;+ int32_t c = right->value.geti32();+ // First, try to lower signed operations to unsigned if that is+ // possible. Some unsigned operations like div_u or rem_u are usually+ // faster on VMs. Also this opens more possibilities for further+ // simplifications afterwards.+ if (c >= 0 &&+ (op = makeUnsignedBinaryOp(binary->op)) != InvalidBinary &&+ Bits::getMaxBits(binary->left, this) <= 31) {+ binary->op = op;+ }+ if (c < 0 && c > std::numeric_limits<int32_t>::min() &&+ binary->op == DivUInt32) {+ // u32(x) / C ==> u32(x) >= C iff C > 2^31+ // We avoid applying this for C == 2^31 due to conflict+ // with other rule which transform to more prefereble+ // right shift operation.+ binary->op = c == -1 ? EqInt32 : GeUInt32;+ return binary;+ }+ if (Bits::isPowerOf2((uint32_t)c)) {+ switch (binary->op) {+ case MulInt32:+ return optimizePowerOf2Mul(binary, (uint32_t)c);+ case RemUInt32:+ return optimizePowerOf2URem(binary, (uint32_t)c);+ case DivUInt32:+ return optimizePowerOf2UDiv(binary, (uint32_t)c);+ default:+ break;+ }+ }+ }+ if (right->type == Type::i64) {+ BinaryOp op;+ int64_t c = right->value.geti64();+ // See description above for Type::i32+ if (c >= 0 &&+ (op = makeUnsignedBinaryOp(binary->op)) != InvalidBinary &&+ Bits::getMaxBits(binary->left, this) <= 63) {+ binary->op = op;+ }+ if (getPassOptions().shrinkLevel == 0 && c < 0 &&+ c > std::numeric_limits<int64_t>::min() &&+ binary->op == DivUInt64) {+ // u64(x) / C ==> u64(u64(x) >= C) iff C > 2^63+ // We avoid applying this for C == 2^31 due to conflict+ // with other rule which transform to more prefereble+ // right shift operation.+ // And apply this only for shrinkLevel == 0 due to it+ // increasing size by one byte.+ binary->op = c == -1LL ? EqInt64 : GeUInt64;+ binary->type = Type::i32;+ return Builder(*getModule()).makeUnary(ExtendUInt32, binary);+ }+ if (Bits::isPowerOf2((uint64_t)c)) {+ switch (binary->op) {+ case MulInt64:+ return optimizePowerOf2Mul(binary, (uint64_t)c);+ case RemUInt64:+ return optimizePowerOf2URem(binary, (uint64_t)c);+ case DivUInt64:+ return optimizePowerOf2UDiv(binary, (uint64_t)c);+ default:+ break;+ }+ }+ }+ if (binary->op == DivFloat32) {+ float c = right->value.getf32();+ if (Bits::isPowerOf2InvertibleFloat(c)) {+ return optimizePowerOf2FDiv(binary, c);+ }+ }+ if (binary->op == DivFloat64) {+ double c = right->value.getf64();+ if (Bits::isPowerOf2InvertibleFloat(c)) {+ return optimizePowerOf2FDiv(binary, c);+ }+ }+ }+ // a bunch of operations on a constant left side can be simplified+ if (binary->left->is<Const>()) {+ if (auto* ret = optimizeWithConstantOnLeft(binary)) {+ return ret;+ }+ }+ // bitwise operations+ // for and and or, we can potentially conditionalize+ if (binary->op == AndInt32 || binary->op == OrInt32) {+ if (auto* ret = conditionalizeExpensiveOnBitwise(binary)) {+ return ret;+ }+ }+ // for or, we can potentially combine+ if (binary->op == OrInt32) {+ if (auto* ret = combineOr(binary)) {+ return ret;+ }+ }+ // relation/comparisons allow for math optimizations+ if (binary->isRelational()) {+ if (auto* ret = optimizeRelational(binary)) {+ return ret;+ }+ }+ // finally, try more expensive operations on the binary in+ // the case that they have no side effects+ if (!effects(binary->left).hasSideEffects()) {+ if (ExpressionAnalyzer::equal(binary->left, binary->right)) {+ if (auto* ret = optimizeBinaryWithEqualEffectlessChildren(binary)) {+ return ret;+ }+ }+ }++ if (auto* ret = deduplicateBinary(binary)) {+ return ret;+ }+ } else if (auto* unary = curr->dynCast<Unary>()) {+ if (unary->op == EqZInt32) {+ if (auto* inner = unary->value->dynCast<Binary>()) {+ // Try to invert a relational operation using De Morgan's law+ auto op = invertBinaryOp(inner->op);+ if (op != InvalidBinary) {+ inner->op = op;+ return inner;+ }+ }+ // eqz of a sign extension can be of zero-extension+ if (auto* ext = Properties::getSignExtValue(unary->value)) {+ // we are comparing a sign extend to a constant, which means we can+ // use a cheaper zext+ auto bits = Properties::getSignExtBits(unary->value);+ unary->value = makeZeroExt(ext, bits);+ return unary;+ }+ } else if (unary->op == AbsFloat32 || unary->op == AbsFloat64) {+ // abs(-x) ==> abs(x)+ if (auto* unaryInner = unary->value->dynCast<Unary>()) {+ if (unaryInner->op ==+ Abstract::getUnary(unaryInner->type, Abstract::Neg)) {+ unary->value = unaryInner->value;+ return unary;+ }+ }+ // abs(x * x) ==> x * x+ // abs(x / x) ==> x / x+ if (auto* binary = unary->value->dynCast<Binary>()) {+ if ((binary->op == Abstract::getBinary(binary->type, Abstract::Mul) ||+ binary->op ==+ Abstract::getBinary(binary->type, Abstract::DivS)) &&+ ExpressionAnalyzer::equal(binary->left, binary->right)) {+ return binary;+ }+ // abs(0 - x) ==> abs(x),+ // only for fast math+ if (fastMath &&+ binary->op == Abstract::getBinary(binary->type, Abstract::Sub)) {+ if (auto* c = binary->left->dynCast<Const>()) {+ if (c->value.isZero()) {+ unary->value = binary->right;+ return unary;+ }+ }+ }+ }+ }++ if (auto* ret = deduplicateUnary(unary)) {+ return ret;+ }+ } else if (auto* set = curr->dynCast<GlobalSet>()) {+ // optimize out a set of a get+ auto* get = set->value->dynCast<GlobalGet>();+ if (get && get->name == set->name) {+ ExpressionManipulator::nop(curr);+ }+ } else if (auto* iff = curr->dynCast<If>()) {+ iff->condition = optimizeBoolean(iff->condition);+ if (iff->ifFalse) {+ if (auto* unary = iff->condition->dynCast<Unary>()) {+ if (unary->op == EqZInt32) {+ // flip if-else arms to get rid of an eqz+ iff->condition = unary->value;+ std::swap(iff->ifTrue, iff->ifFalse);+ }+ }+ if (iff->condition->type != Type::unreachable &&+ ExpressionAnalyzer::equal(iff->ifTrue, iff->ifFalse)) {+ // sides are identical, fold+ // if we can replace the if with one arm, and no side effects in the+ // condition, do that+ auto needCondition = effects(iff->condition).hasSideEffects();+ auto isSubType = Type::isSubType(iff->ifTrue->type, iff->type);+ if (isSubType && !needCondition) {+ return iff->ifTrue;+ } else {+ Builder builder(*getModule());+ if (isSubType) {+ return builder.makeSequence(builder.makeDrop(iff->condition),+ iff->ifTrue);+ } else {+ // the types diff. as the condition is reachable, that means the+ // if must be concrete while the arm is not+ assert(iff->type.isConcrete() &&+ iff->ifTrue->type == Type::unreachable);+ // emit a block with a forced type+ auto* ret = builder.makeBlock();+ if (needCondition) {+ ret->list.push_back(builder.makeDrop(iff->condition));+ }+ ret->list.push_back(iff->ifTrue);+ ret->finalize(iff->type);+ return ret;+ }+ }+ }+ }+ } else if (auto* br = curr->dynCast<Break>()) {+ if (br->condition) {+ br->condition = optimizeBoolean(br->condition);+ }+ } else if (auto* load = curr->dynCast<Load>()) {+ optimizeMemoryAccess(load->ptr, load->offset);+ } else if (auto* store = curr->dynCast<Store>()) {+ optimizeMemoryAccess(store->ptr, store->offset);+ if (store->valueType.isInteger()) {+ // truncates constant values during stores+ // (i32|i64).store(8|16|32)(p, C) ==>+ // (i32|i64).store(8|16|32)(p, C & mask)+ if (auto* c = store->value->dynCast<Const>()) {+ if (store->valueType == Type::i64 && store->bytes == 4) {+ c->value = c->value.and_(Literal(uint64_t(0xffffffff)));+ } else {+ c->value = c->value.and_(Literal::makeFromInt32(+ Bits::lowBitMask(store->bytes * 8), store->valueType));+ }+ }+ }+ // stores of fewer bits truncates anyhow+ if (auto* binary = store->value->dynCast<Binary>()) {+ if (binary->op == AndInt32) {+ if (auto* right = binary->right->dynCast<Const>()) {+ if (right->type == Type::i32) {+ auto mask = right->value.geti32();+ if ((store->bytes == 1 && mask == 0xff) ||+ (store->bytes == 2 && mask == 0xffff)) {+ store->value = binary->left;+ }+ }+ }+ } else if (auto* ext = Properties::getSignExtValue(binary)) {+ // if sign extending the exact bit size we store, we can skip the+ // extension if extending something bigger, then we just alter bits we+ // don't save anyhow+ if (Properties::getSignExtBits(binary) >= Index(store->bytes) * 8) {+ store->value = ext;+ }+ }+ } else if (auto* unary = store->value->dynCast<Unary>()) {+ if (unary->op == WrapInt64) {+ // instead of wrapping to 32, just store some of the bits in the i64+ store->valueType = Type::i64;+ store->value = unary->value;+ }+ }+ } else if (auto* memCopy = curr->dynCast<MemoryCopy>()) {+ assert(features.hasBulkMemory());+ if (auto* ret = optimizeMemoryCopy(memCopy)) {+ return ret;+ }+ }+ return nullptr;+ }++ Index getMaxBitsForLocal(LocalGet* get) {+ // check what we know about the local+ return localInfo[get->index].maxBits;+ }++private:+ // Information about our locals+ std::vector<LocalInfo> localInfo;++ // Canonicalizing the order of a symmetric binary helps us+ // write more concise pattern matching code elsewhere.+ void canonicalize(Binary* binary) {+ assert(shouldCanonicalize(binary));+ auto swap = [&]() {+ assert(canReorder(binary->left, binary->right));+ if (binary->isRelational()) {+ binary->op = reverseRelationalOp(binary->op);+ }+ std::swap(binary->left, binary->right);+ };+ auto maybeSwap = [&]() {+ if (canReorder(binary->left, binary->right)) {+ swap();+ }+ };+ // Prefer a const on the right.+ if (binary->left->is<Const>() && !binary->right->is<Const>()) {+ return swap();+ }+ if (auto* c = binary->right->dynCast<Const>()) {+ // x - C ==> x + (-C)+ // Prefer use addition if there is a constant on the right.+ if (binary->op == Abstract::getBinary(c->type, Abstract::Sub)) {+ c->value = c->value.neg();+ binary->op = Abstract::getBinary(c->type, Abstract::Add);+ }+ return;+ }+ // Prefer a get on the right.+ if (binary->left->is<LocalGet>() && !binary->right->is<LocalGet>()) {+ return maybeSwap();+ }+ // Sort by the node id type, if different.+ if (binary->left->_id != binary->right->_id) {+ if (binary->left->_id > binary->right->_id) {+ return maybeSwap();+ }+ return;+ }+ // If the children have the same node id, we have to go deeper.+ if (auto* left = binary->left->dynCast<Unary>()) {+ auto* right = binary->right->cast<Unary>();+ if (left->op > right->op) {+ return maybeSwap();+ }+ }+ if (auto* left = binary->left->dynCast<Binary>()) {+ auto* right = binary->right->cast<Binary>();+ if (left->op > right->op) {+ return maybeSwap();+ }+ }+ if (auto* left = binary->left->dynCast<LocalGet>()) {+ auto* right = binary->right->cast<LocalGet>();+ if (left->index > right->index) {+ return maybeSwap();+ }+ }+ }++ // Optimize given that the expression is flowing into a boolean context+ Expression* optimizeBoolean(Expression* boolean) {+ // TODO use a general getFallthroughs+ if (auto* unary = boolean->dynCast<Unary>()) {+ if (unary) {+ if (unary->op == EqZInt32) {+ auto* unary2 = unary->value->dynCast<Unary>();+ if (unary2 && unary2->op == EqZInt32) {+ // double eqz+ return unary2->value;+ }+ if (auto* binary = unary->value->dynCast<Binary>()) {+ // !(x <=> y) ==> x <!=> y+ auto op = invertBinaryOp(binary->op);+ if (op != InvalidBinary) {+ binary->op = op;+ return binary;+ }+ }+ }+ }+ } else if (auto* binary = boolean->dynCast<Binary>()) {+ if (binary->op == SubInt32) {+ if (auto* c = binary->left->dynCast<Const>()) {+ if (c->value.geti32() == 0) {+ // bool(0 - x) ==> bool(x)+ return binary->right;+ }+ }+ } else if (binary->op == OrInt32) {+ // an or flowing into a boolean context can consider each input as+ // boolean+ binary->left = optimizeBoolean(binary->left);+ binary->right = optimizeBoolean(binary->right);+ } else if (binary->op == NeInt32) {+ if (auto* c = binary->right->dynCast<Const>()) {+ // x != 0 is just x if it's used as a bool+ if (c->value.geti32() == 0) {+ return binary->left;+ }+ // TODO: Perhaps use it for separate final pass???+ // x != -1 ==> x ^ -1+ // if (num->value.geti32() == -1) {+ // binary->op = XorInt32;+ // return binary;+ // }+ }+ } else if (binary->op == RemSInt32) {+ // bool(i32(x) % C_pot) ==> bool(x & (C_pot - 1))+ // bool(i32(x) % min_s) ==> bool(x & max_s)+ if (auto* c = binary->right->dynCast<Const>()) {+ if (c->value.isSignedMin() ||+ Bits::isPowerOf2(c->value.abs().geti32())) {+ binary->op = AndInt32;+ if (c->value.isSignedMin()) {+ c->value = Literal::makeSignedMax(Type::i32);+ } else {+ c->value = c->value.abs().sub(Literal::makeOne(Type::i32));+ }+ return binary;+ }+ }+ }+ if (auto* ext = Properties::getSignExtValue(binary)) {+ // use a cheaper zero-extent, we just care about the boolean value+ // anyhow+ return makeZeroExt(ext, Properties::getSignExtBits(binary));+ }+ } else if (auto* block = boolean->dynCast<Block>()) {+ if (block->type == Type::i32 && block->list.size() > 0) {+ block->list.back() = optimizeBoolean(block->list.back());+ }+ } else if (auto* iff = boolean->dynCast<If>()) {+ if (iff->type == Type::i32) {+ iff->ifTrue = optimizeBoolean(iff->ifTrue);+ iff->ifFalse = optimizeBoolean(iff->ifFalse);+ }+ } else if (auto* select = boolean->dynCast<Select>()) {+ select->ifTrue = optimizeBoolean(select->ifTrue);+ select->ifFalse = optimizeBoolean(select->ifFalse);+ } else if (auto* tryy = boolean->dynCast<Try>()) {+ if (tryy->type == Type::i32) {+ tryy->body = optimizeBoolean(tryy->body);+ tryy->catchBody = optimizeBoolean(tryy->catchBody);+ }+ }+ // TODO: recurse into br values?+ return boolean;+ }++ Expression* optimizeSelect(Select* curr) {+ using namespace Match;+ Builder builder(*getModule());+ curr->condition = optimizeBoolean(curr->condition);+ {+ // Constant condition, we can just pick the correct side (barring side+ // effects)+ Expression *ifTrue, *ifFalse;+ if (matches(curr, select(pure(&ifTrue), any(&ifFalse), i32(0)))) {+ return ifFalse;+ }+ if (matches(curr, select(any(&ifTrue), any(&ifFalse), i32(0)))) {+ return builder.makeSequence(builder.makeDrop(ifTrue), ifFalse);+ }+ int32_t cond;+ if (matches(curr, select(any(&ifTrue), pure(&ifFalse), i32(&cond)))) {+ // The condition must be non-zero because a zero would have matched one+ // of the previous patterns.+ assert(cond != 0);+ return ifTrue;+ }+ // Don't bother when `ifFalse` isn't pure - we would need to reverse the+ // order using a temp local, which would be bad+ }+ {+ // Flip select to remove eqz if we can reorder+ Select* s;+ Expression *ifTrue, *ifFalse, *c;+ if (matches(+ curr,+ select(+ &s, any(&ifTrue), any(&ifFalse), unary(EqZInt32, any(&c)))) &&+ canReorder(ifTrue, ifFalse)) {+ s->ifTrue = ifFalse;+ s->ifFalse = ifTrue;+ s->condition = c;+ }+ }+ {+ // Simplify selects between 0 and 1+ Expression* c;+ bool reversed = matches(curr, select(ival(0), ival(1), any(&c)));+ if (reversed || matches(curr, select(ival(1), ival(0), any(&c)))) {+ if (reversed) {+ c = optimizeBoolean(builder.makeUnary(EqZInt32, c));+ }+ if (!Properties::emitsBoolean(c)) {+ // cond ? 1 : 0 ==> !!cond+ c = builder.makeUnary(EqZInt32, builder.makeUnary(EqZInt32, c));+ }+ return curr->type == Type::i64 ? builder.makeUnary(ExtendUInt32, c) : c;+ }+ }+ {+ // Sides are identical, fold+ Expression *ifTrue, *ifFalse, *c;+ if (matches(curr, select(any(&ifTrue), any(&ifFalse), any(&c))) &&+ ExpressionAnalyzer::equal(ifTrue, ifFalse)) {+ auto value = effects(ifTrue);+ if (value.hasSideEffects()) {+ // At best we don't need the condition, but need to execute the+ // value twice. a block is larger than a select by 2 bytes, and we+ // must drop one value, so 3, while we save the condition, so it's+ // not clear this is worth it, TODO+ } else {+ // value has no side effects+ auto condition = effects(c);+ if (!condition.hasSideEffects()) {+ return ifTrue;+ } else {+ // The condition is last, so we need a new local, and it may be a+ // bad idea to use a block like we do for an if. Do it only if we+ // can reorder+ if (!condition.invalidates(value)) {+ return builder.makeSequence(builder.makeDrop(c), ifTrue);+ }+ }+ }+ }+ }+ return nullptr;+ }++ // find added constants in an expression tree, including multiplied/shifted,+ // and combine them note that we ignore division/shift-right, as rounding+ // makes this nonlinear, so not a valid opt+ Expression* optimizeAddedConstants(Binary* binary) {+ assert(binary->type.isInteger());++ uint64_t constant = 0;+ std::vector<Const*> constants;++ struct SeekState {+ Expression* curr;+ uint64_t mul;+ SeekState(Expression* curr, uint64_t mul) : curr(curr), mul(mul) {}+ };+ std::vector<SeekState> seekStack;+ seekStack.emplace_back(binary, 1);+ while (!seekStack.empty()) {+ auto state = seekStack.back();+ seekStack.pop_back();+ auto curr = state.curr;+ auto mul = state.mul;+ if (auto* c = curr->dynCast<Const>()) {+ uint64_t value = c->value.getInteger();+ if (value != 0ULL) {+ constant += value * mul;+ constants.push_back(c);+ }+ continue;+ } else if (auto* binary = curr->dynCast<Binary>()) {+ if (binary->op == Abstract::getBinary(binary->type, Abstract::Add)) {+ seekStack.emplace_back(binary->right, mul);+ seekStack.emplace_back(binary->left, mul);+ continue;+ } else if (binary->op ==+ Abstract::getBinary(binary->type, Abstract::Sub)) {+ // if the left is a zero, ignore it, it's how we negate ints+ auto* left = binary->left->dynCast<Const>();+ seekStack.emplace_back(binary->right, -mul);+ if (!left || !left->value.isZero()) {+ seekStack.emplace_back(binary->left, mul);+ }+ continue;+ } else if (binary->op ==+ Abstract::getBinary(binary->type, Abstract::Shl)) {+ if (auto* c = binary->right->dynCast<Const>()) {+ seekStack.emplace_back(binary->left,+ mul << Bits::getEffectiveShifts(c));+ continue;+ }+ } else if (binary->op ==+ Abstract::getBinary(binary->type, Abstract::Mul)) {+ if (auto* c = binary->left->dynCast<Const>()) {+ seekStack.emplace_back(binary->right,+ mul * (uint64_t)c->value.getInteger());+ continue;+ } else if (auto* c = binary->right->dynCast<Const>()) {+ seekStack.emplace_back(binary->left,+ mul * (uint64_t)c->value.getInteger());+ continue;+ }+ }+ }+ };+ // find all factors+ if (constants.size() <= 1) {+ // nothing much to do, except for the trivial case of adding/subbing a+ // zero+ if (auto* c = binary->right->dynCast<Const>()) {+ if (c->value.isZero()) {+ return binary->left;+ }+ }+ return nullptr;+ }+ // wipe out all constants, we'll replace with a single added one+ for (auto* c : constants) {+ c->value = Literal::makeZero(c->type);+ }+ // remove added/subbed zeros+ struct ZeroRemover : public PostWalker<ZeroRemover> {+ // TODO: we could save the binarys and costs we drop, and reuse them later++ PassOptions& passOptions;++ ZeroRemover(PassOptions& passOptions) : passOptions(passOptions) {}++ void visitBinary(Binary* curr) {+ if (!curr->type.isInteger()) {+ return;+ }+ FeatureSet features = getModule()->features;+ auto type = curr->type;+ auto* left = curr->left->dynCast<Const>();+ auto* right = curr->right->dynCast<Const>();+ // Canonicalization prefers an add instead of a subtract wherever+ // possible. That prevents a subtracted constant on the right,+ // as it would be added. And for a zero on the left, it can't be+ // removed (it is how we negate ints).+ if (curr->op == Abstract::getBinary(type, Abstract::Add)) {+ if (left && left->value.isZero()) {+ replaceCurrent(curr->right);+ return;+ }+ if (right && right->value.isZero()) {+ replaceCurrent(curr->left);+ return;+ }+ } else if (curr->op == Abstract::getBinary(type, Abstract::Shl)) {+ // shifting a 0 is a 0, or anything by 0 has no effect, all unless the+ // shift has side effects+ if (((left && left->value.isZero()) ||+ (right && Bits::getEffectiveShifts(right) == 0)) &&+ !EffectAnalyzer(passOptions, features, curr->right)+ .hasSideEffects()) {+ replaceCurrent(curr->left);+ return;+ }+ } else if (curr->op == Abstract::getBinary(type, Abstract::Mul)) {+ // multiplying by zero is a zero, unless the other side has side+ // effects+ if (left && left->value.isZero() &&+ !EffectAnalyzer(passOptions, features, curr->right)+ .hasSideEffects()) {+ replaceCurrent(left);+ return;+ }+ if (right && right->value.isZero() &&+ !EffectAnalyzer(passOptions, features, curr->left)+ .hasSideEffects()) {+ replaceCurrent(right);+ return;+ }+ }+ }+ };+ Expression* walked = binary;+ ZeroRemover remover(getPassOptions());+ remover.setModule(getModule());+ remover.walk(walked);+ if (constant == 0ULL) {+ return walked; // nothing more to do+ }+ if (auto* c = walked->dynCast<Const>()) {+ assert(c->value.isZero());+ // Accumulated 64-bit constant value in 32-bit context will be wrapped+ // during downcasting. So it's valid unification for 32-bit and 64-bit+ // values.+ c->value = Literal::makeFromInt64(constant, c->type);+ return c;+ }+ Builder builder(*getModule());+ return builder.makeBinary(+ Abstract::getBinary(walked->type, Abstract::Add),+ walked,+ builder.makeConst(Literal::makeFromInt64(constant, walked->type)));+ }++ // expensive1 | expensive2 can be turned into expensive1 ? 1 : expensive2,+ // and expensive | cheap can be turned into cheap ? 1 : expensive,+ // so that we can avoid one expensive computation, if it has no side effects.+ Expression* conditionalizeExpensiveOnBitwise(Binary* binary) {+ // this operation can increase code size, so don't always do it+ auto& options = getPassRunner()->options;+ if (options.optimizeLevel < 2 || options.shrinkLevel > 0) {+ return nullptr;+ }+ const auto MIN_COST = 7;+ assert(binary->op == AndInt32 || binary->op == OrInt32);+ if (binary->right->is<Const>()) {+ return nullptr; // trivial+ }+ // bitwise logical operator on two non-numerical values, check if they are+ // boolean+ auto* left = binary->left;+ auto* right = binary->right;+ if (!Properties::emitsBoolean(left) || !Properties::emitsBoolean(right)) {+ return nullptr;+ }+ auto leftEffects = effects(left);+ auto rightEffects = effects(right);+ auto leftHasSideEffects = leftEffects.hasSideEffects();+ auto rightHasSideEffects = rightEffects.hasSideEffects();+ if (leftHasSideEffects && rightHasSideEffects) {+ return nullptr; // both must execute+ }+ // canonicalize with side effects, if any, happening on the left+ if (rightHasSideEffects) {+ if (CostAnalyzer(left).cost < MIN_COST) {+ return nullptr; // avoidable code is too cheap+ }+ if (leftEffects.invalidates(rightEffects)) {+ return nullptr; // cannot reorder+ }+ std::swap(left, right);+ } else if (leftHasSideEffects) {+ if (CostAnalyzer(right).cost < MIN_COST) {+ return nullptr; // avoidable code is too cheap+ }+ } else {+ // no side effects, reorder based on cost estimation+ auto leftCost = CostAnalyzer(left).cost;+ auto rightCost = CostAnalyzer(right).cost;+ if (std::max(leftCost, rightCost) < MIN_COST) {+ return nullptr; // avoidable code is too cheap+ }+ // canonicalize with expensive code on the right+ if (leftCost > rightCost) {+ std::swap(left, right);+ }+ }+ // worth it! perform conditionalization+ Builder builder(*getModule());+ if (binary->op == OrInt32) {+ return builder.makeIf(+ left, builder.makeConst(Literal(int32_t(1))), right);+ } else { // &+ return builder.makeIf(+ left, right, builder.makeConst(Literal(int32_t(0))));+ }+ }++ // We can combine `or` operations, e.g.+ // (x > y) | (x == y) ==> x >= y+ Expression* combineOr(Binary* binary) {+ assert(binary->op == OrInt32);+ if (auto* left = binary->left->dynCast<Binary>()) {+ if (auto* right = binary->right->dynCast<Binary>()) {+ if (left->op != right->op &&+ ExpressionAnalyzer::equal(left->left, right->left) &&+ ExpressionAnalyzer::equal(left->right, right->right) &&+ !effects(left->left).hasSideEffects() &&+ !effects(left->right).hasSideEffects()) {+ switch (left->op) {+ // (x > y) | (x == y) ==> x >= y+ case EqInt32: {+ if (right->op == GtSInt32) {+ left->op = GeSInt32;+ return left;+ }+ break;+ }+ default: {+ }+ }+ }+ }+ }+ return nullptr;+ }++ // fold constant factors into the offset+ void optimizeMemoryAccess(Expression*& ptr, Address& offset) {+ // ptr may be a const, but it isn't worth folding that in (we still have a+ // const); in fact, it's better to do the opposite for gzip purposes as well+ // as for readability.+ auto* last = ptr->dynCast<Const>();+ if (last) {+ uint64_t value64 = last->value.getInteger();+ uint64_t offset64 = offset;+ if (getModule()->memory.is64()) {+ last->value = Literal(int64_t(value64 + offset64));+ offset = 0;+ } else {+ // don't do this if it would wrap the pointer+ if (value64 <= uint64_t(std::numeric_limits<int32_t>::max()) &&+ offset64 <= uint64_t(std::numeric_limits<int32_t>::max()) &&+ value64 + offset64 <=+ uint64_t(std::numeric_limits<int32_t>::max())) {+ last->value = Literal(int32_t(value64 + offset64));+ offset = 0;+ }+ }+ }+ }++ // Optimize a multiply by a power of two on the right, which+ // can be a shift.+ // This doesn't shrink code size, and VMs likely optimize it anyhow,+ // but it's still worth doing since+ // * Often shifts are more common than muls.+ // * The constant is smaller.+ template<typename T> Expression* optimizePowerOf2Mul(Binary* binary, T c) {+ static_assert(std::is_same<T, uint32_t>::value ||+ std::is_same<T, uint64_t>::value,+ "type mismatch");+ auto shifts = Bits::countTrailingZeroes(c);+ binary->op = std::is_same<T, uint32_t>::value ? ShlInt32 : ShlInt64;+ binary->right->cast<Const>()->value = Literal(static_cast<T>(shifts));+ return binary;+ }++ // Optimize an unsigned divide / remainder by a power of two on the right+ // This doesn't shrink code size, and VMs likely optimize it anyhow,+ // but it's still worth doing since+ // * Usually ands are more common than urems.+ // * The constant is slightly smaller.+ template<typename T> Expression* optimizePowerOf2URem(Binary* binary, T c) {+ static_assert(std::is_same<T, uint32_t>::value ||+ std::is_same<T, uint64_t>::value,+ "type mismatch");+ binary->op = std::is_same<T, uint32_t>::value ? AndInt32 : AndInt64;+ binary->right->cast<Const>()->value = Literal(c - 1);+ return binary;+ }++ template<typename T> Expression* optimizePowerOf2UDiv(Binary* binary, T c) {+ static_assert(std::is_same<T, uint32_t>::value ||+ std::is_same<T, uint64_t>::value,+ "type mismatch");+ auto shifts = Bits::countTrailingZeroes(c);+ binary->op = std::is_same<T, uint32_t>::value ? ShrUInt32 : ShrUInt64;+ binary->right->cast<Const>()->value = Literal(static_cast<T>(shifts));+ return binary;+ }++ template<typename T> Expression* optimizePowerOf2FDiv(Binary* binary, T c) {+ //+ // x / C_pot => x * (C_pot ^ -1)+ //+ // Explanation:+ // Floating point numbers are represented as:+ // ((-1) ^ sign) * (2 ^ (exp - bias)) * (1 + significand)+ //+ // If we have power of two numbers, then the mantissa (significand)+ // is all zeros. Let's focus on the exponent, ignoring the sign part:+ // (2 ^ (exp - bias))+ //+ // and for inverted power of two floating point:+ // 1.0 / (2 ^ (exp - bias)) -> 2 ^ -(exp - bias)+ //+ // So inversion of C_pot is valid because it changes only the sign+ // of the exponent part and doesn't touch the significand part,+ // which remains the same (zeros).+ static_assert(std::is_same<T, float>::value ||+ std::is_same<T, double>::value,+ "type mismatch");+ double invDivisor = 1.0 / (double)c;+ binary->op = std::is_same<T, float>::value ? MulFloat32 : MulFloat64;+ binary->right->cast<Const>()->value = Literal(static_cast<T>(invDivisor));+ return binary;+ }++ Expression* makeZeroExt(Expression* curr, int32_t bits) {+ Builder builder(*getModule());+ return builder.makeBinary(+ AndInt32, curr, builder.makeConst(Literal(Bits::lowBitMask(bits))));+ }++ // given an "almost" sign extend - either a proper one, or it+ // has too many shifts left - we remove the sign extend. If there are+ // too many shifts, we split the shifts first, so this removes the+ // two sign extend shifts and adds one (smaller one)+ Expression* removeAlmostSignExt(Binary* outer) {+ auto* inner = outer->left->cast<Binary>();+ auto* outerConst = outer->right->cast<Const>();+ auto* innerConst = inner->right->cast<Const>();+ auto* value = inner->left;+ if (outerConst->value == innerConst->value) {+ return value;+ }+ // add a shift, by reusing the existing node+ innerConst->value = innerConst->value.sub(outerConst->value);+ return inner;+ }++ // check if an expression is already sign-extended+ bool isSignExted(Expression* curr, Index bits) {+ if (Properties::getSignExtValue(curr)) {+ return Properties::getSignExtBits(curr) == bits;+ }+ if (auto* get = curr->dynCast<LocalGet>()) {+ // check what we know about the local+ return localInfo[get->index].signExtedBits == bits;+ }+ return false;+ }++ // optimize trivial math operations, given that the right side of a binary+ // is a constant+ Expression* optimizeWithConstantOnRight(Binary* curr) {+ using namespace Match;+ using namespace Abstract;+ Builder builder(*getModule());+ Expression* left;+ auto* right = curr->right->cast<Const>();+ auto type = curr->right->type;++ // Operations on zero+ if (matches(curr, binary(Shl, any(&left), ival(0))) ||+ matches(curr, binary(ShrU, any(&left), ival(0))) ||+ matches(curr, binary(ShrS, any(&left), ival(0))) ||+ matches(curr, binary(Or, any(&left), ival(0))) ||+ matches(curr, binary(Xor, any(&left), ival(0)))) {+ return left;+ }+ if (matches(curr, binary(Mul, pure(&left), ival(0))) ||+ matches(curr, binary(And, pure(&left), ival(0)))) {+ return right;+ }+ // x == 0 ==> eqz x+ if (matches(curr, binary(Eq, any(&left), ival(0)))) {+ return builder.makeUnary(Abstract::getUnary(type, EqZ), left);+ }+ // Operations on one+ // (signed)x % 1 ==> 0+ if (matches(curr, binary(RemS, pure(&left), ival(1)))) {+ right->value = Literal::makeZero(type);+ return right;+ }+ // (signed)x % C_pot != 0 ==> (x & (abs(C_pot) - 1)) != 0+ {+ Const* c;+ Binary* inner;+ if (matches(curr,+ binary(Ne, binary(&inner, RemS, any(), ival(&c)), ival(0))) &&+ (c->value.isSignedMin() ||+ Bits::isPowerOf2(c->value.abs().getInteger()))) {+ inner->op = Abstract::getBinary(c->type, And);+ if (c->value.isSignedMin()) {+ c->value = Literal::makeSignedMax(c->type);+ } else {+ c->value = c->value.abs().sub(Literal::makeOne(c->type));+ }+ return curr;+ }+ }+ // i32(bool(x)) == 1 ==> i32(bool(x))+ // i32(bool(x)) != 0 ==> i32(bool(x))+ // i32(bool(x)) & 1 ==> i32(bool(x))+ // i64(bool(x)) & 1 ==> i64(bool(x))+ if ((matches(curr, binary(EqInt32, any(&left), i32(1))) ||+ matches(curr, binary(NeInt32, any(&left), i32(0))) ||+ matches(curr, binary(And, any(&left), ival(1)))) &&+ Bits::getMaxBits(left, this) == 1) {+ return left;+ }+ // i64(bool(x)) == 1 ==> i32(bool(x))+ // i64(bool(x)) != 0 ==> i32(bool(x))+ if ((matches(curr, binary(EqInt64, any(&left), i64(1))) ||+ matches(curr, binary(NeInt64, any(&left), i64(0)))) &&+ Bits::getMaxBits(left, this) == 1) {+ return builder.makeUnary(WrapInt64, left);+ }+ // bool(x) != 1 ==> !bool(x)+ if (matches(curr, binary(Ne, any(&left), ival(1))) &&+ Bits::getMaxBits(left, this) == 1) {+ return builder.makeUnary(Abstract::getUnary(type, EqZ), left);+ }+ // bool(x) | 1 ==> 1+ if (matches(curr, binary(Or, pure(&left), ival(1))) &&+ Bits::getMaxBits(left, this) == 1) {+ return right;+ }++ // Operations on all 1s+ // x & -1 ==> x+ if (matches(curr, binary(And, any(&left), ival(-1)))) {+ return left;+ }+ // x | -1 ==> -1+ if (matches(curr, binary(Or, pure(&left), ival(-1)))) {+ return right;+ }+ // (signed)x % -1 ==> 0+ if (matches(curr, binary(RemS, pure(&left), ival(-1)))) {+ right->value = Literal::makeZero(type);+ return right;+ }+ // i32(x) / i32.min_s ==> x == i32.min_s+ if (matches(+ curr,+ binary(DivSInt32, any(), i32(std::numeric_limits<int32_t>::min())))) {+ curr->op = EqInt32;+ return curr;+ }+ // i64(x) / i64.min_s ==> i64(x == i64.min_s)+ // only for zero shrink level+ if (getPassOptions().shrinkLevel == 0 &&+ matches(+ curr,+ binary(DivSInt64, any(), i64(std::numeric_limits<int64_t>::min())))) {+ curr->op = EqInt64;+ curr->type = Type::i32;+ return Builder(*getModule()).makeUnary(ExtendUInt32, curr);+ }+ // (unsigned)x < 0 ==> i32(0)+ if (matches(curr, binary(LtU, pure(&left), ival(0)))) {+ right->value = Literal::makeZero(Type::i32);+ right->type = Type::i32;+ return right;+ }+ // (unsigned)x <= -1 ==> i32(1)+ if (matches(curr, binary(LeU, pure(&left), ival(-1)))) {+ right->value = Literal::makeOne(Type::i32);+ right->type = Type::i32;+ return right;+ }+ // (unsigned)x > -1 ==> i32(0)+ if (matches(curr, binary(GtU, pure(&left), ival(-1)))) {+ right->value = Literal::makeZero(Type::i32);+ right->type = Type::i32;+ return right;+ }+ // (unsigned)x >= 0 ==> i32(1)+ if (matches(curr, binary(GeU, pure(&left), ival(0)))) {+ right->value = Literal::makeOne(Type::i32);+ right->type = Type::i32;+ return right;+ }+ // (unsigned)x < -1 ==> x != -1+ // Friendlier to JS emitting as we don't need to write an unsigned -1 value+ // which is large.+ if (matches(curr, binary(LtU, any(), ival(-1)))) {+ curr->op = Abstract::getBinary(type, Ne);+ return curr;+ }+ // (unsigned)x <= 0 ==> x == 0+ if (matches(curr, binary(LeU, any(), ival(0)))) {+ curr->op = Abstract::getBinary(type, Eq);+ return curr;+ }+ // (unsigned)x > 0 ==> x != 0+ if (matches(curr, binary(GtU, any(), ival(0)))) {+ curr->op = Abstract::getBinary(type, Ne);+ return curr;+ }+ // (unsigned)x >= -1 ==> x == -1+ if (matches(curr, binary(GeU, any(), ival(-1)))) {+ curr->op = Abstract::getBinary(type, Eq);+ return curr;+ }+ {+ Const* c;+ // (signed)x < (i32|i64).min_s ==> i32(0)+ if (matches(curr, binary(LtS, pure(&left), ival(&c))) &&+ c->value.isSignedMin()) {+ right->value = Literal::makeZero(Type::i32);+ right->type = Type::i32;+ return right;+ }+ // (signed)x <= (i32|i64).max_s ==> i32(1)+ if (matches(curr, binary(LeS, pure(&left), ival(&c))) &&+ c->value.isSignedMax()) {+ right->value = Literal::makeOne(Type::i32);+ right->type = Type::i32;+ return right;+ }+ // (signed)x > (i32|i64).max_s ==> i32(0)+ if (matches(curr, binary(GtS, pure(&left), ival(&c))) &&+ c->value.isSignedMax()) {+ right->value = Literal::makeZero(Type::i32);+ right->type = Type::i32;+ return right;+ }+ // (signed)x >= (i32|i64).min_s ==> i32(1)+ if (matches(curr, binary(GeS, pure(&left), ival(&c))) &&+ c->value.isSignedMin()) {+ right->value = Literal::makeOne(Type::i32);+ right->type = Type::i32;+ return right;+ }+ // (signed)x < (i32|i64).max_s ==> x != (i32|i64).max_s+ if (matches(curr, binary(LtS, any(), ival(&c))) &&+ c->value.isSignedMax()) {+ curr->op = Abstract::getBinary(type, Ne);+ return curr;+ }+ // (signed)x <= (i32|i64).min_s ==> x == (i32|i64).min_s+ if (matches(curr, binary(LeS, any(), ival(&c))) &&+ c->value.isSignedMin()) {+ curr->op = Abstract::getBinary(type, Eq);+ return curr;+ }+ // (signed)x > (i32|i64).min_s ==> x != (i32|i64).min_s+ if (matches(curr, binary(GtS, any(), ival(&c))) &&+ c->value.isSignedMin()) {+ curr->op = Abstract::getBinary(type, Ne);+ return curr;+ }+ // (signed)x >= (i32|i64).max_s ==> x == (i32|i64).max_s+ if (matches(curr, binary(GeS, any(), ival(&c))) &&+ c->value.isSignedMax()) {+ curr->op = Abstract::getBinary(type, Eq);+ return curr;+ }+ }+ // x * -1 ==> 0 - x+ if (matches(curr, binary(Mul, any(&left), ival(-1)))) {+ right->value = Literal::makeZero(type);+ curr->op = Abstract::getBinary(type, Sub);+ curr->left = right;+ curr->right = left;+ return curr;+ }+ {+ // ~(1 << x) aka (1 << x) ^ -1 ==> rotl(-2, x)+ Expression* x;+ if (matches(curr, binary(Xor, binary(Shl, ival(1), any(&x)), ival(-1)))) {+ curr->op = Abstract::getBinary(type, RotL);+ right->value = Literal::makeFromInt32(-2, type);+ curr->left = right;+ curr->right = x;+ return curr;+ }+ }+ {+ double value;+ if (matches(curr, binary(Sub, any(), fval(&value))) && value == 0.0) {+ // x - (-0.0) ==> x + 0.0+ if (std::signbit(value)) {+ curr->op = Abstract::getBinary(type, Add);+ right->value = right->value.neg();+ return curr;+ } else if (fastMath) {+ // x - 0.0 ==> x+ return curr->left;+ }+ }+ }+ {+ // x * 2.0 ==> x + x+ // but we apply this only for simple expressions like+ // local.get and global.get for avoid using extra local+ // variable.+ Expression* x;+ if (matches(curr, binary(Mul, any(&x), fval(2.0))) &&+ (x->is<LocalGet>() || x->is<GlobalGet>())) {+ curr->op = Abstract::getBinary(type, Abstract::Add);+ curr->right = ExpressionManipulator::copy(x, *getModule());+ return curr;+ }+ }+ {+ // x + (-0.0) ==> x+ double value;+ if (fastMath && matches(curr, binary(Add, any(), fval(&value))) &&+ value == 0.0 && std::signbit(value)) {+ return curr->left;+ }+ }+ // -x * fval(C) ==> x * -C+ // -x / fval(C) ==> x / -C+ if (matches(curr, binary(Mul, unary(Neg, any(&left)), fval())) ||+ matches(curr, binary(DivS, unary(Neg, any(&left)), fval()))) {+ right->value = right->value.neg();+ curr->left = left;+ return curr;+ }+ // x * -1.0 ==>+ // -x, if fastMath == true+ // -0.0 - x, if fastMath == false+ if (matches(curr, binary(Mul, any(), fval(-1.0)))) {+ if (fastMath) {+ return builder.makeUnary(Abstract::getUnary(type, Neg), left);+ }+ // x * -1.0 ==> -0.0 - x+ curr->op = Abstract::getBinary(type, Sub);+ right->value = Literal::makeZero(type).neg();+ std::swap(curr->left, curr->right);+ return curr;+ }+ if (matches(curr, binary(Mul, any(&left), constant(1))) ||+ matches(curr, binary(DivS, any(&left), constant(1))) ||+ matches(curr, binary(DivU, any(&left), constant(1)))) {+ if (curr->type.isInteger() || fastMath) {+ return left;+ }+ }+ return nullptr;+ }++ // optimize trivial math operations, given that the left side of a binary+ // is a constant. since we canonicalize constants to the right for symmetrical+ // operations, we only need to handle asymmetrical ones here+ // TODO: templatize on type?+ Expression* optimizeWithConstantOnLeft(Binary* curr) {+ using namespace Match;+ using namespace Abstract;++ auto type = curr->left->type;+ auto* left = curr->left->cast<Const>();+ // 0 <<>> x ==> 0+ if (Abstract::hasAnyShift(curr->op) && left->value.isZero() &&+ !effects(curr->right).hasSideEffects()) {+ return curr->left;+ }+ // (signed)-1 >> x ==> -1+ // rotl(-1, x) ==> -1+ // rotr(-1, x) ==> -1+ if ((curr->op == Abstract::getBinary(type, ShrS) ||+ curr->op == Abstract::getBinary(type, RotL) ||+ curr->op == Abstract::getBinary(type, RotR)) &&+ left->value.getInteger() == -1LL &&+ !effects(curr->right).hasSideEffects()) {+ return curr->left;+ }+ {+ // C1 - (x + C2) ==> (C1 - C2) - x+ Const *c1, *c2;+ Expression* x;+ if (matches(curr,+ binary(Sub, ival(&c1), binary(Add, any(&x), ival(&c2))))) {+ left->value = c1->value.sub(c2->value);+ curr->right = x;+ return curr;+ }+ // C1 - (C2 - x) ==> x + (C1 - C2)+ if (matches(curr,+ binary(Sub, ival(&c1), binary(Sub, ival(&c2), any(&x))))) {+ left->value = c1->value.sub(c2->value);+ curr->op = Abstract::getBinary(type, Add);+ curr->right = x;+ std::swap(curr->left, curr->right);+ return curr;+ }+ }+ {+ // fval(C) / -x ==> -C / x+ Expression* right;+ if (matches(curr, binary(DivS, fval(), unary(Neg, any(&right))))) {+ left->value = left->value.neg();+ curr->right = right;+ return curr;+ }+ }+ return nullptr;+ }++ // TODO: templatize on type?+ Expression* optimizeRelational(Binary* curr) {+ auto type = curr->right->type;+ if (curr->left->type.isInteger()) {+ if (curr->op == Abstract::getBinary(type, Abstract::Eq) ||+ curr->op == Abstract::getBinary(type, Abstract::Ne)) {+ if (auto* left = curr->left->dynCast<Binary>()) {+ // TODO: inequalities can also work, if the constants do not overflow+ // integer math, even on 2s complement, allows stuff like+ // x + 5 == 7+ // =>+ // x == 2+ if (left->op == Abstract::getBinary(type, Abstract::Add)) {+ if (auto* leftConst = left->right->dynCast<Const>()) {+ if (auto* rightConst = curr->right->dynCast<Const>()) {+ return combineRelationalConstants(+ curr, left, leftConst, nullptr, rightConst);+ } else if (auto* rightBinary = curr->right->dynCast<Binary>()) {+ if (rightBinary->op ==+ Abstract::getBinary(type, Abstract::Add)) {+ if (auto* rightConst = rightBinary->right->dynCast<Const>()) {+ return combineRelationalConstants(+ curr, left, leftConst, rightBinary, rightConst);+ }+ }+ }+ }+ }+ }+ }+ // x - y == 0 => x == y+ // x - y != 0 => x != y+ // unsigned(x - y) > 0 => x != y+ // unsigned(x - y) <= 0 => x == y+ {+ using namespace Abstract;+ using namespace Match;++ Binary* inner;+ // unsigned(x - y) > 0 => x != y+ if (matches(curr,+ binary(GtU, binary(&inner, Sub, any(), any()), ival(0)))) {+ curr->op = Abstract::getBinary(type, Ne);+ curr->right = inner->right;+ curr->left = inner->left;+ return curr;+ }+ // unsigned(x - y) <= 0 => x == y+ if (matches(curr,+ binary(LeU, binary(&inner, Sub, any(), any()), ival(0)))) {+ curr->op = Abstract::getBinary(type, Eq);+ curr->right = inner->right;+ curr->left = inner->left;+ return curr;+ }+ // x - y == 0 => x == y+ // x - y != 0 => x != y+ // This is not true for signed comparisons like x -y < 0 due to overflow+ // effects (e.g. 8 - 0x80000000 < 0 is not the same as 8 < 0x80000000).+ if (matches(curr,+ binary(Eq, binary(&inner, Sub, any(), any()), ival(0))) ||+ matches(curr,+ binary(Ne, binary(&inner, Sub, any(), any()), ival(0)))) {+ curr->right = inner->right;+ curr->left = inner->left;+ return curr;+ }+ }+ }+ return nullptr;+ }++ Expression* deduplicateUnary(Unary* unaryOuter) {+ if (auto* unaryInner = unaryOuter->value->dynCast<Unary>()) {+ if (unaryInner->op == unaryOuter->op) {+ switch (unaryInner->op) {+ case NegFloat32:+ case NegFloat64: {+ // neg(neg(x)) ==> x+ return unaryInner->value;+ }+ case AbsFloat32:+ case CeilFloat32:+ case FloorFloat32:+ case TruncFloat32:+ case NearestFloat32:+ case AbsFloat64:+ case CeilFloat64:+ case FloorFloat64:+ case TruncFloat64:+ case NearestFloat64: {+ // unaryOp(unaryOp(x)) ==> unaryOp(x)+ return unaryInner;+ }+ case ExtendS8Int32:+ case ExtendS16Int32: {+ assert(getModule()->features.hasSignExt());+ return unaryInner;+ }+ case EqZInt32: {+ // eqz(eqz(bool(x))) ==> bool(x)+ if (Bits::getMaxBits(unaryInner->value, this) == 1) {+ return unaryInner->value;+ }+ break;+ }+ default: {+ }+ }+ }+ }+ return nullptr;+ }++ Expression* deduplicateBinary(Binary* outer) {+ Type type = outer->type;+ if (type.isInteger()) {+ if (auto* inner = outer->right->dynCast<Binary>()) {+ if (outer->op == inner->op) {+ if (!EffectAnalyzer(+ getPassOptions(), getModule()->features, outer->left)+ .hasSideEffects()) {+ if (ExpressionAnalyzer::equal(inner->left, outer->left)) {+ // x - (x - y) ==> y+ // x ^ (x ^ y) ==> y+ if (outer->op == Abstract::getBinary(type, Abstract::Sub) ||+ outer->op == Abstract::getBinary(type, Abstract::Xor)) {+ return inner->right;+ }+ // x & (x & y) ==> x & y+ // x | (x | y) ==> x | y+ if (outer->op == Abstract::getBinary(type, Abstract::And) ||+ outer->op == Abstract::getBinary(type, Abstract::Or)) {+ return inner;+ }+ }+ if (ExpressionAnalyzer::equal(inner->right, outer->left) &&+ canReorder(outer->left, inner->left)) {+ // x ^ (y ^ x) ==> y+ // (note that we need the check for reordering here because if+ // e.g. y writes to a local that x reads, the second appearance+ // of x would be different from the first)+ if (outer->op == Abstract::getBinary(type, Abstract::Xor)) {+ return inner->left;+ }++ // x & (y & x) ==> y & x+ // x | (y | x) ==> y | x+ // (here we need the check for reordering for the more obvious+ // reason that previously x appeared before y, and now y appears+ // first; or, if we tried to emit x [&|] y here, reversing the+ // order, we'd be in the same situation as the previous comment)+ if (outer->op == Abstract::getBinary(type, Abstract::And) ||+ outer->op == Abstract::getBinary(type, Abstract::Or)) {+ return inner;+ }+ }+ }+ }+ }+ if (auto* inner = outer->left->dynCast<Binary>()) {+ if (outer->op == inner->op) {+ if (!EffectAnalyzer(+ getPassOptions(), getModule()->features, outer->right)+ .hasSideEffects()) {+ if (ExpressionAnalyzer::equal(inner->right, outer->right)) {+ // (x ^ y) ^ y ==> x+ if (outer->op == Abstract::getBinary(type, Abstract::Xor)) {+ return inner->left;+ }+ // (x % y) % y ==> x % y+ // (x & y) & y ==> x & y+ // (x | y) | y ==> x | y+ if (outer->op == Abstract::getBinary(type, Abstract::RemS) ||+ outer->op == Abstract::getBinary(type, Abstract::RemU) ||+ outer->op == Abstract::getBinary(type, Abstract::And) ||+ outer->op == Abstract::getBinary(type, Abstract::Or)) {+ return inner;+ }+ }+ // See comments in the parallel code earlier about ordering here.+ if (ExpressionAnalyzer::equal(inner->left, outer->right) &&+ canReorder(inner->left, inner->right)) {+ // (x ^ y) ^ x ==> y+ if (outer->op == Abstract::getBinary(type, Abstract::Xor)) {+ return inner->right;+ }+ // (x & y) & x ==> x & y+ // (x | y) | x ==> x | y+ if (outer->op == Abstract::getBinary(type, Abstract::And) ||+ outer->op == Abstract::getBinary(type, Abstract::Or)) {+ return inner;+ }+ }+ }+ }+ }+ }+ return nullptr;+ }++ // given a relational binary with a const on both sides, combine the constants+ // left is also a binary, and has a constant; right may be just a constant, in+ // which case right is nullptr+ Expression* combineRelationalConstants(Binary* binary,+ Binary* left,+ Const* leftConst,+ Binary* right,+ Const* rightConst) {+ auto type = binary->right->type;+ // we fold constants to the right+ Literal extra = leftConst->value;+ if (left->op == Abstract::getBinary(type, Abstract::Sub)) {+ extra = extra.neg();+ }+ if (right && right->op == Abstract::getBinary(type, Abstract::Sub)) {+ extra = extra.neg();+ }+ rightConst->value = rightConst->value.sub(extra);+ binary->left = left->left;+ return binary;+ }++ Expression* optimizeMemoryCopy(MemoryCopy* memCopy) {+ PassOptions options = getPassOptions();++ if (options.ignoreImplicitTraps) {+ if (ExpressionAnalyzer::equal(memCopy->dest, memCopy->source)) {+ // memory.copy(x, x, sz) ==> {drop(x), drop(x), drop(sz)}+ Builder builder(*getModule());+ return builder.makeBlock({builder.makeDrop(memCopy->dest),+ builder.makeDrop(memCopy->source),+ builder.makeDrop(memCopy->size)});+ }+ }++ // memory.copy(dst, src, C) ==> store(dst, load(src))+ if (auto* csize = memCopy->size->dynCast<Const>()) {+ auto bytes = csize->value.geti32();+ Builder builder(*getModule());++ switch (bytes) {+ case 0: {+ if (options.ignoreImplicitTraps) {+ // memory.copy(dst, src, 0) ==> {drop(dst), drop(src)}+ return builder.makeBlock({builder.makeDrop(memCopy->dest),+ builder.makeDrop(memCopy->source)});+ }+ break;+ }+ case 1:+ case 2:+ case 4: {+ return builder.makeStore(+ bytes, // bytes+ 0, // offset+ 1, // align+ memCopy->dest,+ builder.makeLoad(bytes, false, 0, 1, memCopy->source, Type::i32),+ Type::i32);+ }+ case 8: {+ return builder.makeStore(+ bytes, // bytes+ 0, // offset+ 1, // align+ memCopy->dest,+ builder.makeLoad(bytes, false, 0, 1, memCopy->source, Type::i64),+ Type::i64);+ }+ case 16: {+ if (options.shrinkLevel == 0) {+ // This adds an extra 2 bytes so apply it only for+ // minimal shrink level+ if (getModule()->features.hasSIMD()) {+ return builder.makeStore(+ bytes, // bytes+ 0, // offset+ 1, // align+ memCopy->dest,+ builder.makeLoad(+ bytes, false, 0, 1, memCopy->source, Type::v128),+ Type::v128);+ }+ }+ }+ default: {+ }+ }+ }+ return nullptr;+ }++ // given a binary expression with equal children and no side effects in+ // either, we can fold various things+ Expression* optimizeBinaryWithEqualEffectlessChildren(Binary* binary) {+ // TODO add: perhaps worth doing 2*x if x is quite large?+ switch (binary->op) {+ case SubInt32:+ case XorInt32:+ case SubInt64:+ case XorInt64:+ return LiteralUtils::makeZero(binary->left->type, *getModule());+ case NeInt32:+ case LtSInt32:+ case LtUInt32:+ case GtSInt32:+ case GtUInt32:+ case NeInt64:+ case LtSInt64:+ case LtUInt64:+ case GtSInt64:+ case GtUInt64:+ return LiteralUtils::makeZero(Type::i32, *getModule());+ case AndInt32:+ case OrInt32:+ case AndInt64:+ case OrInt64:+ return binary->left;+ case EqInt32:+ case LeSInt32:+ case LeUInt32:+ case GeSInt32:+ case GeUInt32:+ case EqInt64:+ case LeSInt64:+ case LeUInt64:+ case GeSInt64:+ case GeUInt64:+ return LiteralUtils::makeFromInt32(1, Type::i32, *getModule());+ default:+ return nullptr;+ }+ }++ BinaryOp invertBinaryOp(BinaryOp op) {+ // use de-morgan's laws+ switch (op) {+ case EqInt32:+ return NeInt32;+ case NeInt32:+ return EqInt32;+ case LtSInt32:+ return GeSInt32;+ case LtUInt32:+ return GeUInt32;+ case LeSInt32:+ return GtSInt32;+ case LeUInt32:+ return GtUInt32;+ case GtSInt32:+ return LeSInt32;+ case GtUInt32:+ return LeUInt32;+ case GeSInt32:+ return LtSInt32;+ case GeUInt32:+ return LtUInt32;++ case EqInt64:+ return NeInt64;+ case NeInt64:+ return EqInt64;+ case LtSInt64:+ return GeSInt64;+ case LtUInt64:+ return GeUInt64;+ case LeSInt64:+ return GtSInt64;+ case LeUInt64:+ return GtUInt64;+ case GtSInt64:+ return LeSInt64;+ case GtUInt64:+ return LeUInt64;+ case GeSInt64:+ return LtSInt64;+ case GeUInt64:+ return LtUInt64;++ case EqFloat32:+ return NeFloat32;+ case NeFloat32:+ return EqFloat32;++ case EqFloat64:+ return NeFloat64;+ case NeFloat64:+ return EqFloat64;++ default:+ return InvalidBinary;+ }+ }++ BinaryOp reverseRelationalOp(BinaryOp op) {+ switch (op) {+ case EqInt32:+ return EqInt32;+ case NeInt32:+ return NeInt32;+ case LtSInt32:+ return GtSInt32;+ case LtUInt32:+ return GtUInt32;+ case LeSInt32:+ return GeSInt32;+ case LeUInt32:+ return GeUInt32;+ case GtSInt32:+ return LtSInt32;+ case GtUInt32:+ return LtUInt32;+ case GeSInt32:+ return LeSInt32;+ case GeUInt32:+ return LeUInt32;++ case EqInt64:+ return EqInt64;+ case NeInt64:+ return NeInt64;+ case LtSInt64:+ return GtSInt64;+ case LtUInt64:+ return GtUInt64;+ case LeSInt64:+ return GeSInt64;+ case LeUInt64:+ return GeUInt64;+ case GtSInt64:+ return LtSInt64;+ case GtUInt64:+ return LtUInt64;+ case GeSInt64:+ return LeSInt64;+ case GeUInt64:+ return LeUInt64;++ case EqFloat32:+ return EqFloat32;+ case NeFloat32:+ return NeFloat32;+ case LtFloat32:+ return GtFloat32;+ case LeFloat32:+ return GeFloat32;+ case GtFloat32:+ return LtFloat32;+ case GeFloat32:+ return LeFloat32;++ case EqFloat64:+ return EqFloat64;+ case NeFloat64:+ return NeFloat64;+ case LtFloat64:+ return GtFloat64;+ case LeFloat64:+ return GeFloat64;+ case GtFloat64:+ return LtFloat64;+ case GeFloat64:+ return LeFloat64;++ default:+ return InvalidBinary;+ }+ }++ BinaryOp makeUnsignedBinaryOp(BinaryOp op) {+ switch (op) {+ case DivSInt32:+ return DivUInt32;+ case RemSInt32:+ return RemUInt32;+ case ShrSInt32:+ return ShrUInt32;+ case LtSInt32:+ return LtUInt32;+ case LeSInt32:+ return LeUInt32;+ case GtSInt32:+ return GtUInt32;+ case GeSInt32:+ return GeUInt32;++ case DivSInt64:+ return DivUInt64;+ case RemSInt64:+ return RemUInt64;+ case ShrSInt64:+ return ShrUInt64;+ case LtSInt64:+ return LtUInt64;+ case LeSInt64:+ return LeUInt64;+ case GtSInt64:+ return GtUInt64;+ case GeSInt64:+ return GeUInt64;++ default:+ return InvalidBinary;+ }+ }++ bool shouldCanonicalize(Binary* binary) {+ if ((binary->op == SubInt32 || binary->op == SubInt64) &&+ binary->right->is<Const>() && !binary->left->is<Const>()) {+ return true;+ }+ if (Properties::isSymmetric(binary) || binary->isRelational()) {+ return true;+ }+ switch (binary->op) {+ case AddFloat32:+ case MulFloat32:+ case AddFloat64:+ case MulFloat64: {+ // If the LHS is known to be non-NaN, the operands can commute.+ // We don't care about the RHS because right now we only know if+ // an expression is non-NaN if it is constant, but if the RHS is+ // constant, then this expression is already canonicalized.+ if (auto* c = binary->left->dynCast<Const>()) {+ return !c->value.isNaN();+ }+ return false;+ }+ default:+ return false;+ }+ }+};++Pass* createOptimizeInstructionsPass() { return new OptimizeInstructions; } } // namespace wasm
binaryen/src/passes/PickLoadSigns.cpp view
@@ -109,6 +109,10 @@ load->bytes * 8)) { // unsigned usages exist but the wrong size continue; }+ // Atomic operations are always unsigned, never signed.+ if (load->isAtomic) {+ continue;+ } // we can pick the optimal one. our hope is to remove 2 items per // signed use (two shifts), so we factor that in load->signed_ = usage.signedUsages * 2 >= usage.unsignedUsages;
binaryen/src/passes/PostAssemblyScript.cpp view
@@ -28,7 +28,6 @@ #include <unordered_map> #include <unordered_set> #ifdef POST_ASSEMBLYSCRIPT_DEBUG-#include "wasm-printing.h" #include <iostream> #endif @@ -468,14 +467,14 @@ if (allBalanced) { #ifdef POST_ASSEMBLYSCRIPT_DEBUG std::cerr << " eliminating ";- WasmPrinter::printExpression(retain, std::cerr, true);+ std::cerr << *retain << '\n'; std::cerr << " reaching\n"; #endif redundantRetains.insert(retainLocation); for (auto** getLocation : releaseLocations) { #ifdef POST_ASSEMBLYSCRIPT_DEBUG std::cerr << " ";- WasmPrinter::printExpression(*getLocation, std::cerr, true);+ std::cerr << **getLocation << '\n'; std::cerr << "\n"; #endif redundantReleases.insert(getLocation);@@ -483,28 +482,28 @@ #ifdef POST_ASSEMBLYSCRIPT_DEBUG } else { std::cerr << " cannot eliminate ";- WasmPrinter::printExpression(retain, std::cerr, true);+ std::cerr << *retain << '\n'; std::cerr << " - unbalanced\n"; #endif } #ifdef POST_ASSEMBLYSCRIPT_DEBUG } else { std::cerr << " cannot eliminate ";- WasmPrinter::printExpression(retain, std::cerr, true);+ std::cerr << *retain << '\n'; std::cerr << " - zero releases\n"; #endif } #ifdef POST_ASSEMBLYSCRIPT_DEBUG } else { std::cerr << " cannot eliminate ";- WasmPrinter::printExpression(retain, std::cerr, true);+ std::cerr << *retain << '\n'; std::cerr << " - retains allocation\n"; #endif } #ifdef POST_ASSEMBLYSCRIPT_DEBUG } else { std::cerr << " cannot eliminate ";- WasmPrinter::printExpression(retain, std::cerr, true);+ std::cerr << *retain << '\n'; std::cerr << " - reaches return\n"; #endif }@@ -560,7 +559,7 @@ // __release(__retain(__alloc(...))) - unnecessary allocation #ifdef POST_ASSEMBLYSCRIPT_DEBUG std::cerr << " finalizing ";- WasmPrinter::printExpression(curr, std::cerr, true);+ std::cerr << *curr << '\n'; std::cerr << " - unnecessary allocation\n"; #endif Builder builder(*getModule());@@ -574,7 +573,7 @@ // __release(__retain(...)) - unnecessary pair #ifdef POST_ASSEMBLYSCRIPT_DEBUG std::cerr << " finalizing ";- WasmPrinter::printExpression(curr, std::cerr, true);+ std::cerr << *curr << '\n'; std::cerr << " - unnecessary pair\n"; #endif Builder builder(*getModule());@@ -586,7 +585,7 @@ // __release(42) - unnecessary static release #ifdef POST_ASSEMBLYSCRIPT_DEBUG std::cerr << " finalizing ";- WasmPrinter::printExpression(curr, std::cerr, true);+ std::cerr << *curr << '\n'; std::cerr << " - static release\n"; #endif Builder builder(*getModule());@@ -598,7 +597,7 @@ // __retain(42) - unnecessary static retain #ifdef POST_ASSEMBLYSCRIPT_DEBUG std::cerr << " finalizing ";- WasmPrinter::printExpression(curr, std::cerr, true);+ std::cerr << *curr << '\n'; std::cerr << " - static retain\n"; #endif replaceCurrent(retainedConst);
binaryen/src/passes/PostEmscripten.cpp view
@@ -41,46 +41,10 @@ return F->imported() && F->module == ENV && F->base.startsWith("invoke_"); } -struct OptimizeCalls : public WalkerPass<PostWalker<OptimizeCalls>> {- bool isFunctionParallel() override { return true; }-- Pass* create() override { return new OptimizeCalls; }-- void visitCall(Call* curr) {- // special asm.js imports can be optimized- auto* func = getModule()->getFunction(curr->target);- if (!func->imported()) {- return;- }- if (func->module == GLOBAL_MATH) {- if (func->base == POW) {- if (auto* exponent = curr->operands[1]->dynCast<Const>()) {- if (exponent->value == Literal(double(2.0))) {- // This is just a square operation, do a multiply- Localizer localizer(curr->operands[0], getFunction(), getModule());- Builder builder(*getModule());- replaceCurrent(builder.makeBinary(- MulFloat64,- localizer.expr,- builder.makeLocalGet(localizer.index, localizer.expr->type)));- } else if (exponent->value == Literal(double(0.5))) {- // This is just a square root operation- replaceCurrent(- Builder(*getModule()).makeUnary(SqrtFloat64, curr->operands[0]));- }- }- }- }- }-};- } // namespace struct PostEmscripten : public Pass { void run(PassRunner* runner, Module* module) override {- // Optimize calls- OptimizeCalls().run(runner, module);- // Optimize exceptions optimizeExceptions(runner, module); }@@ -122,12 +86,12 @@ } }); - // Assume an indirect call might throw.+ // Assume a non-direct call might throw. analyzer.propagateBack( [](const Info& info) { return info.canThrow; }, [](const Info& info) { return true; }, [](Info& info, Function* reason) { info.canThrow = true; },- analyzer.IndirectCallsHaveProperty);+ analyzer.NonDirectCallsHaveProperty); // Apply the information. struct OptimizeInvokes : public WalkerPass<PostWalker<OptimizeInvokes>> {
binaryen/src/passes/Precompute.cpp view
@@ -177,6 +177,9 @@ if (flow.breakTo == NONCONSTANT_FLOW) { return; }+ if (!canEmitConstantFor(flow.values)) {+ return;+ } if (flow.breakTo == RETURN_FLOW) { // this expression causes a return. if it's already a return, reuse the // node@@ -223,6 +226,9 @@ // Precompute an expression, returning a flow, which may be a constant // (that we can replace the expression with if replaceExpression is set). Flow precomputeExpression(Expression* curr, bool replaceExpression = true) {+ if (!canEmitConstantFor(curr->type)) {+ return Flow(NONCONSTANT_FLOW);+ } try { return PrecomputingExpressionRunner( getModule(), getValues, replaceExpression)@@ -337,6 +343,37 @@ } } }+ }++ bool canEmitConstantFor(const Literals& values) {+ for (auto& value : values) {+ if (!canEmitConstantFor(value)) {+ return false;+ }+ }+ return true;+ }++ bool canEmitConstantFor(const Literal& value) {+ // A null is fine to emit a constant for - we'll emit a RefNull. Otherwise,+ // see below about references to GC data.+ if (value.isNull()) {+ return true;+ }+ // A function is fine to emit a constant for - we'll emit a RefFunc, which+ // is compact and immutable, so there can't be a problem.+ if (value.type.isFunction()) {+ return true;+ }+ return canEmitConstantFor(value.type);+ }++ bool canEmitConstantFor(Type type) {+ // Don't try to precompute a reference. We can't replace it with a constant+ // expression, as that would make a copy of it by value.+ // For now, don't try to precompute an Rtt. TODO figure out when that would+ // be safe and useful.+ return !type.isRef() && !type.isRtt(); } };
binaryen/src/passes/Print.cpp view
@@ -21,12 +21,22 @@ #include <ir/module-utils.h> #include <pass.h> #include <pretty_printing.h>-#include <wasm-printing.h> #include <wasm-stack.h> #include <wasm.h> namespace wasm { +static std::ostream& printExpression(Expression* expression,+ std::ostream& o,+ bool minify = false,+ bool full = false);++static std::ostream&+printStackInst(StackInst* inst, std::ostream& o, Function* func = nullptr);++static std::ostream&+printStackIR(StackIR* ir, std::ostream& o, Function* func = nullptr);+ namespace { bool isFullForced() {@@ -57,6 +67,101 @@ return printName(name, o); } +static void+printHeapTypeName(std::ostream& os, HeapType type, bool first = true);++// Prints the name of a type. This output is guaranteed to not contain spaces.+static void printTypeName(std::ostream& os, Type type) {+ if (type.isBasic()) {+ os << type;+ return;+ }+ if (type.isRtt()) {+ auto rtt = type.getRtt();+ os << "rtt_";+ if (rtt.hasDepth()) {+ os << rtt.depth << '_';+ }+ printHeapTypeName(os, rtt.heapType);+ return;+ }+ if (type.isTuple()) {+ auto sep = "";+ for (auto t : type) {+ os << sep;+ sep = "_";+ printTypeName(os, t);+ }+ return;+ }+ if (type.isRef()) {+ os << "ref";+ if (type.isNullable()) {+ os << "?";+ }+ os << "|";+ printHeapTypeName(os, type.getHeapType(), false);+ os << "|";+ return;+ }+ WASM_UNREACHABLE("unsupported print type");+}++static void printFieldName(std::ostream& os, const Field& field) {+ if (field.mutable_) {+ os << "mut:";+ }+ if (field.type == Type::i32 && field.packedType != Field::not_packed) {+ if (field.packedType == Field::i8) {+ os << "i8";+ } else if (field.packedType == Field::i16) {+ os << "i16";+ } else {+ WASM_UNREACHABLE("invalid packed type");+ }+ } else {+ printTypeName(os, field.type);+ }+}++// Prints the name of a heap type. As with printTypeName, this output is+// guaranteed to not contain spaces.+static void printHeapTypeName(std::ostream& os, HeapType type, bool first) {+ if (type.isBasic()) {+ os << type;+ return;+ }+ if (first) {+ os << '$';+ }+ if (type.isSignature()) {+ auto sig = type.getSignature();+ printTypeName(os, sig.params);+ if (first) {+ os << "_=>_";+ } else {+ os << "_->_";+ }+ printTypeName(os, sig.results);+ } else if (type.isStruct()) {+ auto struct_ = type.getStruct();+ os << "{";+ auto sep = "";+ for (auto& field : struct_.fields) {+ os << sep;+ sep = "_";+ printFieldName(os, field);+ }+ os << "}";+ } else if (type.isArray()) {+ os << "[";+ printFieldName(os, type.getArray().element);+ os << "]";+ } else {+ os << type;+ }+}+ // Unlike the default format, tuple types in s-expressions should not have // commas. struct SExprType {@@ -64,8 +169,8 @@ SExprType(Type type) : type(type){}; }; -static std::ostream& operator<<(std::ostream& o, const SExprType& localType) {- Type type = localType.type;+static std::ostream& operator<<(std::ostream& o, const SExprType& sType) {+ Type type = sType.type; if (type.isTuple()) { o << '('; auto sep = "";@@ -74,35 +179,50 @@ sep = " "; } o << ')';+ } else if (type.isRtt()) {+ auto rtt = type.getRtt();+ o << "(rtt ";+ if (rtt.hasDepth()) {+ o << rtt.depth << ' ';+ }+ printHeapTypeName(o, rtt.heapType);+ o << ')';+ } else if (type.isRef() && !type.isBasic()) {+ o << "(ref ";+ if (type.isNullable()) {+ o << "null ";+ }+ printHeapTypeName(o, type.getHeapType());+ o << ')'; } else {- o << type;+ printTypeName(o, sType.type); } return o; } -// Wrapper for printing signature names-struct SigName {- Signature sig;- SigName(Signature sig) : sig(sig) {}+// TODO: try to simplify or even remove this, as we may be able to do the same+// things with SExprType+struct ResultTypeName {+ Type type;+ ResultTypeName(Type type) : type(type) {} }; -std::ostream& operator<<(std::ostream& os, SigName sigName) {- auto printType = [&](Type type) {- if (type == Type::none) {- os << "none";- } else {- auto sep = "";- for (const auto& t : type) {- os << sep << t;- sep = "_";- }+std::ostream& operator<<(std::ostream& os, ResultTypeName typeName) {+ auto type = typeName.type;+ os << "(result ";+ if (type.isTuple()) {+ // Tuple types are not printed in parens, we can just emit them one after+ // the other in the same list as the "result".+ auto sep = "";+ for (auto t : type) {+ os << sep;+ sep = " ";+ os << SExprType(t); }- };-- os << '$';- printType(sigName.sig.params);- os << "_=>_";- printType(sigName.sig.results);+ } else {+ os << SExprType(type);+ }+ os << ')'; return os; } @@ -131,13 +251,13 @@ printName(curr->name, o); } if (curr->type.isConcrete()) {- o << ' ' << ResultType(curr->type);+ o << ' ' << ResultTypeName(curr->type); } } void visitIf(If* curr) { printMedium(o, "if"); if (curr->type.isConcrete()) {- o << ' ' << ResultType(curr->type);+ o << ' ' << ResultTypeName(curr->type); } } void visitLoop(Loop* curr) {@@ -147,7 +267,7 @@ printName(curr->name, o); } if (curr->type.isConcrete()) {- o << ' ' << ResultType(curr->type);+ o << ' ' << ResultTypeName(curr->type); } } void visitBreak(Break* curr) {@@ -181,7 +301,8 @@ } else { printMedium(o, "call_indirect (type "); }- o << SigName(curr->sig) << ')';+ printHeapTypeName(o, curr->sig);+ o << ')'; } void visitLocalGet(LocalGet* curr) { printMedium(o, "local.get ");@@ -274,22 +395,22 @@ prepareColor(o); printRMWSize(o, curr->type, curr->bytes); switch (curr->op) {- case Add:+ case RMWAdd: o << "add"; break;- case Sub:+ case RMWSub: o << "sub"; break;- case And:+ case RMWAnd: o << "and"; break;- case Or:+ case RMWOr: o << "or"; break;- case Xor:+ case RMWXor: o << "xor"; break;- case Xchg:+ case RMWXchg: o << "xchg"; break; }@@ -317,13 +438,15 @@ } void visitAtomicWait(AtomicWait* curr) { prepareColor(o);- o << forceConcrete(curr->expectedType) << ".atomic.wait";+ Type type = forceConcrete(curr->expectedType);+ assert(type == Type::i32 || type == Type::i64);+ o << "memory.atomic.wait" << (type == Type::i32 ? "32" : "64"); if (curr->offset) { o << " offset=" << curr->offset; } } void visitAtomicNotify(AtomicNotify* curr) {- printMedium(o, "atomic.notify");+ printMedium(o, "memory.atomic.notify"); if (curr->offset) { o << " offset=" << curr->offset; }@@ -408,6 +531,18 @@ case QFMSF64x2: o << "f64x2.qfms"; break;+ case SignSelectVec8x16:+ o << "v8x16.signselect";+ break;+ case SignSelectVec16x8:+ o << "v16x8.signselect";+ break;+ case SignSelectVec32x4:+ o << "v32x4.signselect";+ break;+ case SignSelectVec64x2:+ o << "v64x2.signselect";+ break; } } void visitSIMDShift(SIMDShift* curr) {@@ -499,6 +634,61 @@ o << " align=" << curr->align; } }+ void visitSIMDLoadStoreLane(SIMDLoadStoreLane* curr) {+ prepareColor(o);+ switch (curr->op) {+ case LoadLaneVec8x16:+ o << "v128.load8_lane";+ break;+ case LoadLaneVec16x8:+ o << "v128.load16_lane";+ break;+ case LoadLaneVec32x4:+ o << "v128.load32_lane";+ break;+ case LoadLaneVec64x2:+ o << "v128.load64_lane";+ break;+ case StoreLaneVec8x16:+ o << "v128.store8_lane";+ break;+ case StoreLaneVec16x8:+ o << "v128.store16_lane";+ break;+ case StoreLaneVec32x4:+ o << "v128.store32_lane";+ break;+ case StoreLaneVec64x2:+ o << "v128.store64_lane";+ break;+ }+ restoreNormalColor(o);+ if (curr->offset) {+ o << " offset=" << curr->offset;+ }+ if (curr->align != curr->getMemBytes()) {+ o << " align=" << curr->align;+ }+ o << " " << int(curr->index);+ }+ void visitPrefetch(Prefetch* curr) {+ prepareColor(o);+ switch (curr->op) {+ case PrefetchTemporal:+ o << "prefetch.t";+ break;+ case PrefetchNontemporal:+ o << "prefetch.nt";+ break;+ }+ restoreNormalColor(o);+ if (curr->offset) {+ o << " offset=" << curr->offset;+ }+ if (curr->align != 1) {+ o << " align=" << curr->align;+ }+ } void visitMemoryInit(MemoryInit* curr) { prepareColor(o); o << "memory.init " << curr->segment;@@ -737,6 +927,9 @@ case BitmaskVecI8x16: o << "i8x16.bitmask"; break;+ case PopcntVecI8x16:+ o << "i8x16.popcnt";+ break; case AbsVecI16x8: o << "i16x8.abs"; break;@@ -770,11 +963,8 @@ case NegVecI64x2: o << "i64x2.neg"; break;- case AnyTrueVecI64x2:- o << "i64x2.any_true";- break;- case AllTrueVecI64x2:- o << "i64x2.all_true";+ case BitmaskVecI64x2:+ o << "i64x2.bitmask"; break; case AbsVecF32x4: o << "f32x4.abs";@@ -818,6 +1008,18 @@ case NearestVecF64x2: o << "f64x2.nearest"; break;+ case ExtAddPairwiseSVecI8x16ToI16x8:+ o << "i16x8.extadd_pairwise_i8x16_s";+ break;+ case ExtAddPairwiseUVecI8x16ToI16x8:+ o << "i16x8.extadd_pairwise_i8x16_u";+ break;+ case ExtAddPairwiseSVecI16x8ToI32x4:+ o << "i32x4.extadd_pairwise_i16x8_s";+ break;+ case ExtAddPairwiseUVecI16x8ToI32x4:+ o << "i32x4.extadd_pairwise_i16x8_u";+ break; case TruncSatSVecF32x4ToVecI32x4: o << "i32x4.trunc_sat_f32x4_s"; break;@@ -866,6 +1068,18 @@ case WidenHighUVecI16x8ToVecI32x4: o << "i32x4.widen_high_i16x8_u"; break;+ case WidenLowSVecI32x4ToVecI64x2:+ o << "i64x2.widen_low_i32x4_s";+ break;+ case WidenHighSVecI32x4ToVecI64x2:+ o << "i64x2.widen_high_i32x4_s";+ break;+ case WidenLowUVecI32x4ToVecI64x2:+ o << "i64x2.widen_low_i32x4_u";+ break;+ case WidenHighUVecI32x4ToVecI64x2:+ o << "i64x2.widen_high_i32x4_u";+ break; case InvalidUnary: WASM_UNREACHABLE("unvalid unary operator"); }@@ -1195,6 +1409,9 @@ case GeUVecI32x4: o << "i32x4.ge_u"; break;+ case EqVecI64x2:+ o << "i64x2.eq";+ break; case EqVecF32x4: o << "f32x4.eq"; break;@@ -1317,6 +1534,22 @@ case AvgrUVecI16x8: o << "i16x8.avgr_u"; break;+ case Q15MulrSatSVecI16x8:+ o << "i16x8.q15mulr_sat_s";+ break;+ case ExtMulLowSVecI16x8:+ o << "i16x8.extmul_low_i8x16_s";+ break;+ case ExtMulHighSVecI16x8:+ o << "i16x8.extmul_high_i8x16_s";+ break;+ case ExtMulLowUVecI16x8:+ o << "i16x8.extmul_low_i8x16_u";+ break;+ case ExtMulHighUVecI16x8:+ o << "i16x8.extmul_high_i8x16_u";+ break;+ case AddVecI32x4: o << "i32x4.add"; break;@@ -1341,6 +1574,19 @@ case DotSVecI16x8ToVecI32x4: o << "i32x4.dot_i16x8_s"; break;+ case ExtMulLowSVecI32x4:+ o << "i32x4.extmul_low_i16x8_s";+ break;+ case ExtMulHighSVecI32x4:+ o << "i32x4.extmul_high_i16x8_s";+ break;+ case ExtMulLowUVecI32x4:+ o << "i32x4.extmul_low_i16x8_u";+ break;+ case ExtMulHighUVecI32x4:+ o << "i32x4.extmul_high_i16x8_u";+ break;+ case AddVecI64x2: o << "i64x2.add"; break;@@ -1350,6 +1596,18 @@ case MulVecI64x2: o << "i64x2.mul"; break;+ case ExtMulLowSVecI64x2:+ o << "i64x2.extmul_low_i32x4_s";+ break;+ case ExtMulHighSVecI64x2:+ o << "i64x2.extmul_high_i32x4_s";+ break;+ case ExtMulLowUVecI64x2:+ o << "i64x2.extmul_low_i32x4_u";+ break;+ case ExtMulHighUVecI64x2:+ o << "i64x2.extmul_high_i32x4_u";+ break; case AddVecF32x4: o << "f32x4.add";@@ -1425,7 +1683,7 @@ void visitSelect(Select* curr) { prepareColor(o) << "select"; if (curr->type.isRef()) {- o << " (result " << curr->type << ')';+ o << ' ' << ResultTypeName(curr->type); } } void visitDrop(Drop* curr) { printMedium(o, "drop"); }@@ -1434,7 +1692,7 @@ void visitMemoryGrow(MemoryGrow* curr) { printMedium(o, "memory.grow"); } void visitRefNull(RefNull* curr) { printMedium(o, "ref.null ");- o << curr->type.getHeapType();+ printHeapTypeName(o, curr->type.getHeapType()); } void visitRefIsNull(RefIsNull* curr) { printMedium(o, "ref.is_null"); } void visitRefFunc(RefFunc* curr) {@@ -1478,49 +1736,93 @@ void visitI31Get(I31Get* curr) { printMedium(o, curr->signed_ ? "i31.get_s" : "i31.get_u"); }+ void visitCallRef(CallRef* curr) {+ if (curr->isReturn) {+ printMedium(o, "return_call_ref");+ } else {+ printMedium(o, "call_ref");+ }+ } void visitRefTest(RefTest* curr) {- printMedium(o, "ref.test");- WASM_UNREACHABLE("TODO (gc): ref.test");+ printMedium(o, "ref.test ");+ printHeapTypeName(o, curr->getCastType().getHeapType()); } void visitRefCast(RefCast* curr) {- printMedium(o, "ref.cast");- WASM_UNREACHABLE("TODO (gc): ref.cast");+ printMedium(o, "ref.cast ");+ printHeapTypeName(o, curr->getCastType().getHeapType()); } void visitBrOnCast(BrOnCast* curr) {- printMedium(o, "br_on_cast");- WASM_UNREACHABLE("TODO (gc): br_on_cast");+ printMedium(o, "br_on_cast ");+ printName(curr->name, o);+ o << " ";+ printHeapTypeName(o, curr->getCastType().getHeapType()); } void visitRttCanon(RttCanon* curr) {- printMedium(o, "rtt.canon");- WASM_UNREACHABLE("TODO (gc): rtt.canon");+ printMedium(o, "rtt.canon ");+ printHeapTypeName(o, curr->type.getRtt().heapType); } void visitRttSub(RttSub* curr) {- printMedium(o, "rtt.sub");- WASM_UNREACHABLE("TODO (gc): rtt.sub");+ printMedium(o, "rtt.sub ");+ printHeapTypeName(o, curr->type.getRtt().heapType); } void visitStructNew(StructNew* curr) {- WASM_UNREACHABLE("TODO (gc): struct.new");+ printMedium(o, "struct.new_");+ if (curr->isWithDefault()) {+ o << "default_";+ }+ o << "with_rtt ";+ printHeapTypeName(o, curr->rtt->type.getHeapType()); } void visitStructGet(StructGet* curr) {- WASM_UNREACHABLE("TODO (gc): struct.get");+ const auto& field =+ curr->ref->type.getHeapType().getStruct().fields[curr->index];+ if (field.type == Type::i32 && field.packedType != Field::not_packed) {+ if (curr->signed_) {+ printMedium(o, "struct.get_s ");+ } else {+ printMedium(o, "struct.get_u ");+ }+ } else {+ printMedium(o, "struct.get ");+ }+ printHeapTypeName(o, curr->ref->type.getHeapType());+ o << ' ';+ o << curr->index; } void visitStructSet(StructSet* curr) {- printMedium(o, "struct.set");- WASM_UNREACHABLE("TODO (gc): struct.set");+ printMedium(o, "struct.set ");+ printHeapTypeName(o, curr->ref->type.getHeapType());+ o << ' ';+ o << curr->index; } void visitArrayNew(ArrayNew* curr) {- WASM_UNREACHABLE("TODO (gc): array.new");+ printMedium(o, "array.new_");+ if (curr->isWithDefault()) {+ o << "default_";+ }+ o << "with_rtt ";+ printHeapTypeName(o, curr->rtt->type.getHeapType()); } void visitArrayGet(ArrayGet* curr) {- WASM_UNREACHABLE("TODO (gc): array.get");+ const auto& element = curr->ref->type.getHeapType().getArray().element;+ if (element.type == Type::i32 && element.packedType != Field::not_packed) {+ if (curr->signed_) {+ printMedium(o, "array.get_s ");+ } else {+ printMedium(o, "array.get_u ");+ }+ } else {+ printMedium(o, "array.get ");+ }+ printHeapTypeName(o, curr->ref->type.getHeapType()); } void visitArraySet(ArraySet* curr) {- printMedium(o, "array.set");- WASM_UNREACHABLE("TODO (gc): array.set");+ printMedium(o, "array.set ");+ printHeapTypeName(o, curr->ref->type.getHeapType()); } void visitArrayLen(ArrayLen* curr) {- printMedium(o, "array.len");- WASM_UNREACHABLE("TODO (gc): array.len");+ printMedium(o, "array.len ");+ printHeapTypeName(o, curr->ref->type.getHeapType()); } }; @@ -1536,9 +1838,9 @@ bool full = false; // whether to not elide nodes in output when possible // (like implicit blocks) and to emit types- bool printStackIR = false; // whether to print stack IR if it is present- // (if false, and Stack IR is there, we just- // note it exists)+ bool stackIR = false; // whether to print stack IR if it is present+ // (if false, and Stack IR is there, we just+ // note it exists) Module* currModule = nullptr; Function* currFunction = nullptr;@@ -1598,7 +1900,7 @@ void setFull(bool full_) { full = full_; } - void setPrintStackIR(bool printStackIR_) { printStackIR = printStackIR_; }+ void setStackIR(bool stackIR_) { stackIR = stackIR_; } void setDebugInfo(bool debugInfo_) { debugInfo = debugInfo_; } @@ -1908,6 +2210,21 @@ printFullLine(curr->ptr); decIndent(); }+ void visitSIMDLoadStoreLane(SIMDLoadStoreLane* curr) {+ o << '(';+ PrintExpressionContents(currFunction, o).visit(curr);+ incIndent();+ printFullLine(curr->ptr);+ printFullLine(curr->vec);+ decIndent();+ }+ void visitPrefetch(Prefetch* curr) {+ o << '(';+ PrintExpressionContents(currFunction, o).visit(curr);+ incIndent();+ printFullLine(curr->ptr);+ decIndent();+ } void visitMemoryInit(MemoryInit* curr) { o << '('; PrintExpressionContents(currFunction, o).visit(curr);@@ -2125,82 +2442,186 @@ printFullLine(curr->i31); decIndent(); }+ void visitCallRef(CallRef* curr) {+ o << '(';+ PrintExpressionContents(currFunction, o).visit(curr);+ incIndent();+ for (auto operand : curr->operands) {+ printFullLine(operand);+ }+ printFullLine(curr->target);+ decIndent();+ } void visitRefTest(RefTest* curr) { o << '('; PrintExpressionContents(currFunction, o).visit(curr);- WASM_UNREACHABLE("TODO (gc): ref.test");+ incIndent();+ printFullLine(curr->ref);+ printFullLine(curr->rtt);+ decIndent(); } void visitRefCast(RefCast* curr) { o << '('; PrintExpressionContents(currFunction, o).visit(curr);- WASM_UNREACHABLE("TODO (gc): ref.cast");+ incIndent();+ printFullLine(curr->ref);+ printFullLine(curr->rtt);+ decIndent(); } void visitBrOnCast(BrOnCast* curr) { o << '('; PrintExpressionContents(currFunction, o).visit(curr);- WASM_UNREACHABLE("TODO (gc): br_on_cast");+ incIndent();+ printFullLine(curr->ref);+ printFullLine(curr->rtt);+ decIndent(); } void visitRttCanon(RttCanon* curr) { o << '('; PrintExpressionContents(currFunction, o).visit(curr);- WASM_UNREACHABLE("TODO (gc): rtt.canon");+ o << ')'; } void visitRttSub(RttSub* curr) { o << '('; PrintExpressionContents(currFunction, o).visit(curr);- WASM_UNREACHABLE("TODO (gc): rtt.sub");+ incIndent();+ printFullLine(curr->parent);+ decIndent(); } void visitStructNew(StructNew* curr) { o << '('; PrintExpressionContents(currFunction, o).visit(curr);- WASM_UNREACHABLE("TODO (gc): struct.new");+ incIndent();+ printFullLine(curr->rtt);+ for (auto& operand : curr->operands) {+ printFullLine(operand);+ }+ decIndent(); } void visitStructGet(StructGet* curr) { o << '('; PrintExpressionContents(currFunction, o).visit(curr);- WASM_UNREACHABLE("TODO (gc): struct.get");+ incIndent();+ printFullLine(curr->ref);+ decIndent(); } void visitStructSet(StructSet* curr) { o << '('; PrintExpressionContents(currFunction, o).visit(curr);- WASM_UNREACHABLE("TODO (gc): struct.set");+ incIndent();+ printFullLine(curr->ref);+ printFullLine(curr->value);+ decIndent(); } void visitArrayNew(ArrayNew* curr) { o << '('; PrintExpressionContents(currFunction, o).visit(curr);- WASM_UNREACHABLE("TODO (gc): array.new");+ incIndent();+ printFullLine(curr->rtt);+ printFullLine(curr->size);+ if (curr->init) {+ printFullLine(curr->init);+ }+ decIndent(); } void visitArrayGet(ArrayGet* curr) { o << '('; PrintExpressionContents(currFunction, o).visit(curr);- WASM_UNREACHABLE("TODO (gc): array.get");+ incIndent();+ printFullLine(curr->ref);+ printFullLine(curr->index);+ decIndent(); } void visitArraySet(ArraySet* curr) { o << '('; PrintExpressionContents(currFunction, o).visit(curr);- WASM_UNREACHABLE("TODO (gc): array.set");+ incIndent();+ printFullLine(curr->ref);+ printFullLine(curr->index);+ printFullLine(curr->value);+ decIndent(); } void visitArrayLen(ArrayLen* curr) { o << '('; PrintExpressionContents(currFunction, o).visit(curr);- WASM_UNREACHABLE("TODO (gc): array.len");+ incIndent();+ printFullLine(curr->ref);+ decIndent(); } // Module-level visitors- void handleSignature(Signature curr, Name* funcName = nullptr) {+ void handleSignature(Signature curr, Name name = Name()) { o << "(func";- if (funcName) {- o << " $" << *funcName;+ if (name.is()) {+ o << " $" << name; } if (curr.params.size() > 0) { o << maybeSpace;- o << ParamType(curr.params);+ o << "(param ";+ auto sep = "";+ for (auto type : curr.params) {+ o << sep << SExprType(type);+ sep = " ";+ }+ o << ')'; } if (curr.results.size() > 0) { o << maybeSpace;- o << ResultType(curr.results);+ o << "(result ";+ auto sep = "";+ for (auto type : curr.results) {+ o << sep << SExprType(type);+ sep = " ";+ }+ o << ')'; } o << ")"; }+ void handleFieldBody(const Field& field) {+ if (field.mutable_) {+ o << "(mut ";+ }+ if (field.type == Type::i32 && field.packedType != Field::not_packed) {+ if (field.packedType == Field::i8) {+ o << "i8";+ } else if (field.packedType == Field::i16) {+ o << "i16";+ } else {+ WASM_UNREACHABLE("invalid packed type");+ }+ } else {+ o << SExprType(field.type);+ }+ if (field.mutable_) {+ o << ')';+ }+ }+ void handleArray(const Array& curr) {+ o << "(array ";+ handleFieldBody(curr.element);+ o << ')';+ }+ void handleStruct(const Struct& curr) {+ o << "(struct ";+ auto sep = "";+ for (auto field : curr.fields) {+ o << sep << "(field ";+ handleFieldBody(field);+ o << ')';+ sep = " ";+ }+ o << ')';+ }+ void handleHeapType(HeapType type) {+ if (type.isSignature()) {+ handleSignature(type.getSignature());+ } else if (type.isArray()) {+ handleArray(type.getArray());+ } else if (type.isStruct()) {+ handleStruct(type.getStruct());+ } else {+ o << type;+ }+ } void visitExport(Export* curr) { o << '('; printMedium(o, "export ");@@ -2279,7 +2700,7 @@ lastPrintedLocation = {0, 0, 0}; o << '('; emitImportHeader(curr);- handleSignature(curr->sig, &curr->name);+ handleSignature(curr->sig, curr->name); o << ')'; o << maybeNewLine; }@@ -2293,7 +2714,7 @@ o << '('; printMajor(o, "func "); printName(curr->name, o);- if (!printStackIR && curr->stackIR && !minify) {+ if (!stackIR && curr->stackIR && !minify) { o << " (; has Stack IR ;)"; } if (curr->sig.params.size() > 0) {@@ -2303,13 +2724,13 @@ o << '('; printMinor(o, "param "); printLocal(i, currFunction, o);- o << ' ' << param << ')';+ o << ' ' << SExprType(param) << ')'; ++i; } } if (curr->sig.results != Type::none) { o << maybeSpace;- o << ResultType(curr->sig.results);+ o << ResultTypeName(curr->sig.results); } incIndent(); for (size_t i = curr->getVarIndexBase(); i < curr->getNumLocals(); i++) {@@ -2321,7 +2742,7 @@ o << maybeNewLine; } // Print the body.- if (!printStackIR || !curr->stackIR) {+ if (!stackIR || !curr->stackIR) { // It is ok to emit a block here, as a function can directly contain a // list, even if our ast avoids that for simplicity. We can just do that // optimization here..@@ -2336,7 +2757,7 @@ } } else { // Print the stack IR.- WasmPrinter::printStackIR(curr->stackIR.get(), o, curr);+ printStackIR(curr->stackIR.get(), o, curr); } if (currFunction->epilogLocation.size() && lastPrintedLocation != *currFunction->epilogLocation.begin()) {@@ -2460,6 +2881,10 @@ doIndent(o, indent); o << '('; printMajor(o, "data ");+ if (segment.name.is()) {+ printName(segment.name, o);+ o << ' ';+ } if (segment.isPassive) { printMedium(o, "passive"); } else {@@ -2528,15 +2953,16 @@ printName(curr->name, o); } incIndent();- std::vector<Signature> signatures;- std::unordered_map<Signature, Index> indices;- ModuleUtils::collectSignatures(*curr, signatures, indices);- for (auto sig : signatures) {+ std::vector<HeapType> types;+ std::unordered_map<HeapType, Index> indices;+ ModuleUtils::collectHeapTypes(*curr, types, indices);+ for (auto type : types) { doIndent(o, indent); o << '('; printMedium(o, "type") << ' ';- o << SigName(sig) << ' ';- handleSignature(sig);+ printHeapTypeName(o, type);+ o << ' ';+ handleHeapType(type); o << ")" << maybeNewLine; } ModuleUtils::iterImportedMemories(@@ -2669,29 +3095,17 @@ void run(PassRunner* runner, Module* module) override { PrintSExpression print(o); print.setDebugInfo(runner->options.debugInfo);- print.setPrintStackIR(true);+ print.setStackIR(true); print.visitModule(module); } }; Pass* createPrintStackIRPass() { return new PrintStackIR(); } -// Print individual expressions--std::ostream& WasmPrinter::printModule(Module* module, std::ostream& o) {- PassRunner runner(module);- Printer(&o).run(&runner, module);- return o;-}--std::ostream& WasmPrinter::printModule(Module* module) {- return printModule(module, std::cout);-}--std::ostream& WasmPrinter::printExpression(Expression* expression,- std::ostream& o,- bool minify,- bool full) {+static std::ostream& printExpression(Expression* expression,+ std::ostream& o,+ bool minify,+ bool full) { if (!expression) { o << "(null expression)"; return o;@@ -2706,8 +3120,8 @@ return o; } -std::ostream&-WasmPrinter::printStackInst(StackInst* inst, std::ostream& o, Function* func) {+static std::ostream&+printStackInst(StackInst* inst, std::ostream& o, Function* func) { switch (inst->op) { case StackInst::Basic: { PrintExpressionContents(func, o).visit(inst->origin);@@ -2741,8 +3155,8 @@ return o; } -std::ostream&-WasmPrinter::printStackIR(StackIR* ir, std::ostream& o, Function* func) {+static std::ostream&+printStackIR(StackIR* ir, std::ostream& o, Function* func) { size_t indent = func ? 2 : 0; auto doIndent = [&indent, &o]() { for (size_t j = 0; j < indent; j++) {@@ -2806,3 +3220,29 @@ } } // namespace wasm++namespace std {++std::ostream& operator<<(std::ostream& o, wasm::Module& module) {+ wasm::PassRunner runner(&module);+ wasm::Printer(&o).run(&runner, &module);+ return o;+}++std::ostream& operator<<(std::ostream& o, wasm::Expression& expression) {+ return wasm::printExpression(&expression, o);+}++std::ostream& operator<<(std::ostream& o, wasm::Expression* expression) {+ return wasm::printExpression(expression, o);+}++std::ostream& operator<<(std::ostream& o, wasm::StackInst& inst) {+ return wasm::printStackInst(&inst, o);+}++std::ostream& operator<<(std::ostream& o, wasm::StackIR& ir) {+ return wasm::printStackIR(&ir, o);+}++} // namespace std
binaryen/src/passes/ReReloop.cpp view
@@ -31,10 +31,6 @@ #include "wasm-traversal.h" #include "wasm.h" -#ifdef RERELOOP_DEBUG-#include <wasm-printing.h>-#endif- namespace wasm { struct ReReloop final : public Pass {@@ -362,7 +358,7 @@ } } // TODO: should this be in the relooper itself?- ReFinalize().walk(function->body);+ ReFinalize().walkFunctionInModule(function, module); } };
binaryen/src/passes/RemoveNonJSOps.cpp view
@@ -299,13 +299,6 @@ functionCall = WASM_NEAREST_F64; break; - case TruncFloat32:- functionCall = WASM_TRUNC_F32;- break;- case TruncFloat64:- functionCall = WASM_TRUNC_F64;- break;- case PopcntInt64: functionCall = WASM_POPCNT64; break;
binaryen/src/passes/RemoveUnusedBrs.cpp view
@@ -930,6 +930,17 @@ !iff->ifFalse->type.isSingle()) { return nullptr; }+ if (iff->condition->type == Type::unreachable) {+ // An if with an unreachable condition may nonetheless have a type+ // that is not unreachable,+ //+ // (if (result i32) (unreachable) ..)+ //+ // Turning such an if into a select would change the type of the+ // expression, which would require updating types further up. Avoid+ // that, leaving dead code elimination to that dedicated pass.+ return nullptr;+ } // This is always helpful for code size, but can be a tradeoff with // performance as we run both code paths. So when shrinking we always // try to do this, but otherwise must consider more carefully.@@ -937,20 +948,23 @@ passOptions, iff->ifTrue, iff->ifFalse)) { return nullptr; }- // Check if side effects allow this.+ // Check if side effects allow this: we need to execute the two arms+ // unconditionally, and also to make the condition run last. FeatureSet features = getModule()->features;+ EffectAnalyzer ifTrue(passOptions, features, iff->ifTrue);+ if (ifTrue.hasSideEffects()) {+ return nullptr;+ }+ EffectAnalyzer ifFalse(passOptions, features, iff->ifFalse);+ if (ifFalse.hasSideEffects()) {+ return nullptr;+ } EffectAnalyzer condition(passOptions, features, iff->condition);- if (!condition.hasSideEffects()) {- EffectAnalyzer ifTrue(passOptions, features, iff->ifTrue);- if (!ifTrue.hasSideEffects()) {- EffectAnalyzer ifFalse(passOptions, features, iff->ifFalse);- if (!ifFalse.hasSideEffects()) {- return Builder(*getModule())- .makeSelect(iff->condition, iff->ifTrue, iff->ifFalse);- }- }+ if (condition.invalidates(ifTrue) || condition.invalidates(ifFalse)) {+ return nullptr; }- return nullptr;+ return Builder(*getModule())+ .makeSelect(iff->condition, iff->ifTrue, iff->ifFalse); } void visitLocalSet(LocalSet* curr) {
binaryen/src/passes/RemoveUnusedModuleElements.cpp view
@@ -22,7 +22,6 @@ #include <memory> -#include "asm_v_wasm.h" #include "ir/module-utils.h" #include "ir/utils.h" #include "pass.h"
binaryen/src/passes/RemoveUnusedNames.cpp view
@@ -19,12 +19,15 @@ // merge names when possible (by merging their blocks) // +#include <ir/branch-utils.h> #include <pass.h> #include <wasm.h> namespace wasm { -struct RemoveUnusedNames : public WalkerPass<PostWalker<RemoveUnusedNames>> {+struct RemoveUnusedNames+ : public WalkerPass<PostWalker<RemoveUnusedNames,+ UnifiedExpressionVisitor<RemoveUnusedNames>>> { bool isFunctionParallel() override { return true; } Pass* create() override { return new RemoveUnusedNames; }@@ -33,17 +36,19 @@ // a parent block, we know if it was branched to std::map<Name, std::set<Expression*>> branchesSeen; - void visitBreak(Break* curr) { branchesSeen[curr->name].insert(curr); }-- void visitSwitch(Switch* curr) {- for (auto name : curr->targets) {- branchesSeen[name].insert(curr);+ void visitExpression(Expression* curr) {+ if (auto* block = curr->dynCast<Block>()) {+ visitBlock(block);+ return; }- branchesSeen[curr->default_].insert(curr);+ if (auto* loop = curr->dynCast<Loop>()) {+ visitLoop(loop);+ return;+ }+ BranchUtils::operateOnScopeNameUses(+ curr, [&](Name& name) { branchesSeen[name].insert(curr); }); } - void visitBrOnExn(BrOnExn* curr) { branchesSeen[curr->name].insert(curr); }- void handleBreakTarget(Name& name) { if (name.is()) { if (branchesSeen.find(name) == branchesSeen.end()) {@@ -62,26 +67,7 @@ // same place as breaking out of us, we just need one name (and block) auto& branches = branchesSeen[curr->name]; for (auto* branch : branches) {- if (Break* br = branch->dynCast<Break>()) {- if (br->name == curr->name) {- br->name = child->name;- }- } else if (Switch* sw = branch->dynCast<Switch>()) {- for (auto& target : sw->targets) {- if (target == curr->name) {- target = child->name;- }- }- if (sw->default_ == curr->name) {- sw->default_ = child->name;- }- } else if (BrOnExn* br = branch->dynCast<BrOnExn>()) {- if (br->name == curr->name) {- br->name = child->name;- }- } else {- WASM_UNREACHABLE("unexpected expr type");- }+ BranchUtils::replacePossibleTarget(branch, curr->name, child->name); } child->finalize(child->type); replaceCurrent(child);
− binaryen/src/passes/ReplaceStackPointer.cpp
@@ -1,103 +0,0 @@-/*- * Copyright 2020 WebAssembly Community Group participants- *- * Licensed under the Apache License, Version 2.0 (the "License");- * you may not use this file except in compliance with the License.- * You may obtain a copy of the License at- *- * http://www.apache.org/licenses/LICENSE-2.0- *- * Unless required by applicable law or agreed to in writing, software- * distributed under the License is distributed on an "AS IS" BASIS,- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.- * See the License for the specific language governing permissions and- * limitations under the License.- */--//-// Convert llvm's stack pointer usage from from global.get/global.set into-// cals to external stackSave/stackRestore.-// This is needed to emscripten SIDE_MODULE code where mutable global imports-// are not yet permitted by default.-//--#include "abi/js.h"-#include "ir/import-utils.h"-#include "pass.h"-#include "support/debug.h"-#include "wasm-emscripten.h"--#define DEBUG_TYPE "replace-stack-pointer"--namespace wasm {--static Name STACK_SAVE("stackSave");-static Name STACK_RESTORE("stackRestore");--struct ReplaceStackPointer- : public WalkerPass<PostWalker<ReplaceStackPointer>> {- void visitGlobalGet(GlobalGet* curr) {- if (getModule()->getGlobalOrNull(curr->name) == stackPointer) {- needStackSave = true;- if (!builder) {- builder = make_unique<Builder>(*getModule());- }- replaceCurrent(builder->makeCall(STACK_SAVE, {}, Type::i32));- }- }-- void visitGlobalSet(GlobalSet* curr) {- if (getModule()->getGlobalOrNull(curr->name) == stackPointer) {- needStackRestore = true;- if (!builder) {- builder = make_unique<Builder>(*getModule());- }- replaceCurrent(- builder->makeCall(STACK_RESTORE, {curr->value}, Type::none));- }- }-- void doWalkModule(Module* module) {- stackPointer = getStackPointerGlobal(*module);- if (!stackPointer) {- BYN_DEBUG(std::cerr << "no stack pointer found\n");- return;- }- BYN_DEBUG(std::cerr << "stack pointer found\n");- super::doWalkModule(module);- if (needStackSave) {- ensureFunctionImport(- module, STACK_SAVE, Signature(Type::none, Type::i32));- }- if (needStackRestore) {- ensureFunctionImport(- module, STACK_RESTORE, Signature(Type::i32, Type::none));- }- // Finally remove the stack pointer global itself. This avoids importing- // a mutable global.- module->removeGlobal(stackPointer->name);- }-- void ensureFunctionImport(Module* module, Name name, Signature sig) {- ImportInfo info(*module);- if (info.getImportedFunction(ENV, name)) {- return;- }- auto import = new Function;- import->name = name;- import->module = ENV;- import->base = name;- import->sig = sig;- module->addFunction(import);- }--private:- std::unique_ptr<Builder> builder;- Global* stackPointer = nullptr;- bool needStackSave = false;- bool needStackRestore = false;-};--Pass* createReplaceStackPointerPass() { return new ReplaceStackPointer; }--} // namespace wasm
binaryen/src/passes/SafeHeap.cpp view
@@ -20,7 +20,6 @@ // top of sbrk()-addressible memory, and incorrect alignment notation. // -#include "asm_v_wasm.h" #include "asmjs/shared-constants.h" #include "ir/bits.h" #include "ir/import-utils.h"@@ -31,7 +30,6 @@ namespace wasm { -static const Name DYNAMICTOP_PTR_IMPORT("DYNAMICTOP_PTR"); static const Name GET_SBRK_PTR("emscripten_get_sbrk_ptr"); static const Name SBRK("sbrk"); static const Name SEGFAULT_IMPORT("segfault");@@ -68,6 +66,10 @@ // If the getSbrkPtr function is implemented in the wasm, we must not // instrument that, as it would lead to infinite recursion of it calling // SAFE_HEAP_LOAD that calls it and so forth.+ // As well as the getSbrkPtr function we also avoid instrumenting the+ // module start function. This is because this function is used in+ // shared memory builds to load the passive memory segments, which in+ // turn means that value of sbrk() is not available. Name getSbrkPtr; bool isFunctionParallel() override { return true; }@@ -79,7 +81,12 @@ AccessInstrumenter(Name getSbrkPtr) : getSbrkPtr(getSbrkPtr) {} void visitLoad(Load* curr) {- if (getFunction()->name == getSbrkPtr || curr->type == Type::unreachable) {+ // As well as the getSbrkPtr function we also avoid insturmenting the+ // module start function. This is because this function is used in+ // shared memory builds to load the passive memory segments, which in+ // turn means that value of sbrk() is not available.+ if (getFunction()->name == getModule()->start ||+ getFunction()->name == getSbrkPtr || curr->type == Type::unreachable) { return; } Builder builder(*getModule());@@ -90,7 +97,8 @@ } void visitStore(Store* curr) {- if (getFunction()->name == getSbrkPtr || curr->type == Type::unreachable) {+ if (getFunction()->name == getModule()->start ||+ getFunction()->name == getSbrkPtr || curr->type == Type::unreachable) { return; } Builder builder(*getModule());@@ -119,11 +127,7 @@ void addImports(Module* module) { ImportInfo info(*module); auto indexType = module->memory.indexType;- // Older emscripten imports env.DYNAMICTOP_PTR.- // Newer emscripten imports or exports emscripten_get_sbrk_ptr().- if (auto* existing = info.getImportedGlobal(ENV, DYNAMICTOP_PTR_IMPORT)) {- dynamicTopPtr = existing->name;- } else if (auto* existing = info.getImportedFunction(ENV, GET_SBRK_PTR)) {+ if (auto* existing = info.getImportedFunction(ENV, GET_SBRK_PTR)) { getSbrkPtr = existing->name; } else if (auto* existing = module->getExportOrNull(GET_SBRK_PTR)) { getSbrkPtr = existing->value;
binaryen/src/passes/SimplifyLocals.cpp view
@@ -964,16 +964,23 @@ } anotherCycle = true; }+ // Nothing more to do, ignore the copy.+ return; } else if (func->getLocalType(curr->index) == func->getLocalType(get->index)) {- // There is a new equivalence now.+ // There is a new equivalence now. Remove all the old ones, and add+ // the new one.+ // Note that we ignore the case of subtyping here, to keep this+ // optimization simple by assuming all equivalent indexes also have+ // the same type. TODO: consider optimizing this. equivalences.reset(curr->index); equivalences.add(curr->index, get->index);+ return; }- } else {- // A new value is assigned here.- equivalences.reset(curr->index); }+ // A new value of some kind is assigned here, and it's not something we+ // could handle earlier, so remove all the old equivalent ones.+ equivalences.reset(curr->index); } void visitLocalGet(LocalGet* curr) {
binaryen/src/passes/Souperify.cpp view
@@ -464,8 +464,7 @@ case Node::Type::Expr: { if (debug()) { std::cout << "; ";- WasmPrinter::printExpression(node->expr, std::cout, true);- std::cout << '\n';+ std::cout << *node->expr << '\n'; } std::cout << "%" << indexing[node] << " = "; printExpression(node);
− binaryen/src/passes/SpillPointers.cpp
@@ -1,206 +0,0 @@-/*- * Copyright 2017 WebAssembly Community Group participants- *- * Licensed under the Apache License, Version 2.0 (the "License");- * you may not use this file except in compliance with the License.- * You may obtain a copy of the License at- *- * http://www.apache.org/licenses/LICENSE-2.0- *- * Unless required by applicable law or agreed to in writing, software- * distributed under the License is distributed on an "AS IS" BASIS,- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.- * See the License for the specific language governing permissions and- * limitations under the License.- */--//-// Spills values that might be pointers to the C stack. This allows-// Boehm-style GC to see them properly.-//-// To reduce the overhead of the extra operations added here, you-// should probably run optimizations after doing it.-// TODO: add a dead store elimination pass, which would help here-//-// * There is currently no check that there is enough stack space.-//--#include "abi/abi.h"-#include "abi/stack.h"-#include "cfg/liveness-traversal.h"-#include "pass.h"-#include "wasm-builder.h"-#include "wasm.h"--namespace wasm {--struct SpillPointers- : public WalkerPass<LivenessWalker<SpillPointers, Visitor<SpillPointers>>> {- bool isFunctionParallel() override { return true; }-- Pass* create() override { return new SpillPointers; }-- // a mapping of the pointers to all the spillable things. We need to know- // how to replace them, and as we spill we may modify them. This map- // gives us, for an Expression** seen during the walk (and placed in the- // basic block, which is what we iterate on for efficiency) => the- // current actual pointer, which may have moded- std::unordered_map<Expression**, Expression**> actualPointers;-- // note calls in basic blocks- template<typename T> void visitSpillable(T* curr) {- // if in unreachable code, ignore- if (!currBasicBlock) {- return;- }- auto* pointer = getCurrentPointer();- currBasicBlock->contents.actions.emplace_back(pointer);- // starts out as correct, may change later- actualPointers[pointer] = pointer;- }-- void visitCall(Call* curr) { visitSpillable(curr); }- void visitCallIndirect(CallIndirect* curr) { visitSpillable(curr); }-- // main entry point-- void doWalkFunction(Function* func) {- if (!canRun(func)) {- return;- }- super::doWalkFunction(func);- spillPointers();- }-- // map pointers to their offset in the spill area- typedef std::unordered_map<Index, Index> PointerMap;-- void spillPointers() {- // we only care about possible pointers- auto* func = getFunction();- PointerMap pointerMap;- for (Index i = 0; i < func->getNumLocals(); i++) {- if (func->getLocalType(i) == ABI::PointerType) {- auto offset = pointerMap.size() * ABI::PointerType.getByteSize();- pointerMap[i] = offset;- }- }- // find calls and spill around them- bool spilled = false;- Index spillLocal = -1;- for (auto& curr : basicBlocks) {- if (liveBlocks.count(curr.get()) == 0) {- continue; // ignore dead blocks- }- auto& liveness = curr->contents;- auto& actions = liveness.actions;- Index lastCall = -1;- for (Index i = 0; i < actions.size(); i++) {- auto& action = liveness.actions[i];- if (action.isOther()) {- lastCall = i;- }- }- if (lastCall == Index(-1)) {- continue; // nothing to see here- }- // scan through the block, spilling around the calls- // TODO: we can filter on pointerMap everywhere- SetOfLocals live = liveness.end;- for (int i = int(actions.size()) - 1; i >= 0; i--) {- auto& action = actions[i];- if (action.isGet()) {- live.insert(action.index);- } else if (action.isSet()) {- live.erase(action.index);- } else if (action.isOther()) {- std::vector<Index> toSpill;- for (auto index : live) {- if (pointerMap.count(index) > 0) {- toSpill.push_back(index);- }- }- if (!toSpill.empty()) {- // we now have a call + the information about which locals- // should be spilled- if (!spilled) {- // prepare stack support: get a pointer to stack space big enough- // for all our data- spillLocal = Builder::addVar(func, ABI::PointerType);- spilled = true;- }- // the origin was seen at walk, but the thing may have moved- auto* pointer = actualPointers[action.origin];- spillPointersAroundCall(- pointer, toSpill, spillLocal, pointerMap, func, getModule());- }- } else {- WASM_UNREACHABLE("unexpected action");- }- }- }- if (spilled) {- // get the stack space, and set the local to it- ABI::getStackSpace(spillLocal,- func,- ABI::PointerType.getByteSize() * pointerMap.size(),- *getModule());- }- }-- void spillPointersAroundCall(Expression** origin,- std::vector<Index>& toSpill,- Index spillLocal,- PointerMap& pointerMap,- Function* func,- Module* module) {- auto* call = *origin;- if (call->type == Type::unreachable) {- return; // the call is never reached anyhow, ignore- }- Builder builder(*module);- auto* block = builder.makeBlock();- // move the operands into locals, as we must spill after they are executed- auto handleOperand = [&](Expression*& operand) {- auto temp = builder.addVar(func, operand->type);- auto* set = builder.makeLocalSet(temp, operand);- block->list.push_back(set);- block->finalize();- if (actualPointers.count(&operand) > 0) {- // this is something we track, and it's moving - update- actualPointers[&operand] = &set->value;- }- operand = builder.makeLocalGet(temp, operand->type);- };- if (call->is<Call>()) {- for (auto*& operand : call->cast<Call>()->operands) {- handleOperand(operand);- }- } else if (call->is<CallIndirect>()) {- for (auto*& operand : call->cast<CallIndirect>()->operands) {- handleOperand(operand);- }- handleOperand(call->cast<CallIndirect>()->target);- } else {- WASM_UNREACHABLE("unexpected expr");- }- // add the spills- for (auto index : toSpill) {- block->list.push_back(- builder.makeStore(ABI::PointerType.getByteSize(),- pointerMap[index],- ABI::PointerType.getByteSize(),- builder.makeLocalGet(spillLocal, ABI::PointerType),- builder.makeLocalGet(index, ABI::PointerType),- ABI::PointerType));- }- // add the (modified) call- block->list.push_back(call);- block->finalize();- *origin = block;- }-};--Pass* createSpillPointersPass() { return new SpillPointers(); }--} // namespace wasm
binaryen/src/passes/StackCheck.cpp view
@@ -22,6 +22,7 @@ #include "abi/js.h" #include "ir/import-utils.h"+#include "ir/names.h" #include "pass.h" #include "shared-constants.h" #include "support/debug.h"@@ -31,11 +32,6 @@ namespace wasm { -// The base is where the stack begins. As it goes down, that is the highest-// valid address.-static Name STACK_BASE("__stack_base");-// The limit is the farthest it can grow to, which is the lowest valid address.-static Name STACK_LIMIT("__stack_limit"); // Exported function to set the base and the limit. static Name SET_STACK_LIMITS("__set_stack_limits"); @@ -52,30 +48,18 @@ } } -static void addExportedFunction(Module& module, Function* function) {- module.addFunction(function);- auto export_ = new Export;- export_->name = export_->value = function->name;- export_->kind = ExternalKind::Function;- module.addExport(export_);-}--static void generateSetStackLimitFunctions(Module& module) {- Builder builder(module);- Function* limitsFunc = builder.makeFunction(- SET_STACK_LIMITS, Signature({Type::i32, Type::i32}, Type::none), {});- LocalGet* getBase = builder.makeLocalGet(0, Type::i32);- Expression* storeBase = builder.makeGlobalSet(STACK_BASE, getBase);- LocalGet* getLimit = builder.makeLocalGet(1, Type::i32);- Expression* storeLimit = builder.makeGlobalSet(STACK_LIMIT, getLimit);- limitsFunc->body = builder.makeBlock({storeBase, storeLimit});- addExportedFunction(module, limitsFunc);+static void addExportedFunction(Module& module,+ std::unique_ptr<Function> function) {+ auto export_ =+ Builder::makeExport(function->name, function->name, ExternalKind::Function);+ module.addFunction(std::move(function));+ module.addExport(std::move(export_)); } struct EnforceStackLimits : public WalkerPass<PostWalker<EnforceStackLimits>> {- EnforceStackLimits(Global* stackPointer,- Global* stackBase,- Global* stackLimit,+ EnforceStackLimits(const Global* stackPointer,+ const Global* stackBase,+ const Global* stackLimit, Builder& builder, Name handler) : stackPointer(stackPointer), stackBase(stackBase), stackLimit(stackLimit),@@ -127,9 +111,9 @@ } private:- Global* stackPointer;- Global* stackBase;- Global* stackLimit;+ const Global* stackPointer;+ const Global* stackBase;+ const Global* stackLimit; Builder& builder; Name handler; };@@ -142,6 +126,10 @@ return; } + // Pick appropriate names.+ auto stackBaseName = Names::getValidGlobalName(*module, "__stack_base");+ auto stackLimitName = Names::getValidGlobalName(*module, "__stack_limit");+ Name handler; auto handlerName = runner->options.getArgumentOrDefault("stack-check-handler", "");@@ -151,22 +139,33 @@ } Builder builder(*module);- Global* stackBase = builder.makeGlobal(STACK_BASE,++ // Add the globals.+ auto stackBase =+ module->addGlobal(builder.makeGlobal(stackBaseName, stackPointer->type, builder.makeConst(int32_t(0)),- Builder::Mutable);- module->addGlobal(stackBase);-- Global* stackLimit = builder.makeGlobal(STACK_LIMIT,- stackPointer->type,- builder.makeConst(int32_t(0)),- Builder::Mutable);- module->addGlobal(stackLimit);+ Builder::Mutable));+ auto stackLimit =+ module->addGlobal(builder.makeGlobal(stackLimitName,+ stackPointer->type,+ builder.makeConst(int32_t(0)),+ Builder::Mutable)); + // Instrument all the code. PassRunner innerRunner(module); EnforceStackLimits(stackPointer, stackBase, stackLimit, builder, handler) .run(&innerRunner, module);- generateSetStackLimitFunctions(*module);++ // Generate the exported function.+ auto limitsFunc = builder.makeFunction(+ SET_STACK_LIMITS, Signature({Type::i32, Type::i32}, Type::none), {});+ auto* getBase = builder.makeLocalGet(0, Type::i32);+ auto* storeBase = builder.makeGlobalSet(stackBaseName, getBase);+ auto* getLimit = builder.makeLocalGet(1, Type::i32);+ auto* storeLimit = builder.makeGlobalSet(stackLimitName, getLimit);+ limitsFunc->body = builder.makeBlock({storeBase, storeLimit});+ addExportedFunction(*module, std::move(limitsFunc)); } };
binaryen/src/passes/TrapMode.cpp view
@@ -20,14 +20,12 @@ // generates a check and replaces the result with zero in that case. // -#include "asm_v_wasm.h" #include "asmjs/shared-constants.h" #include "ir/trapping.h" #include "mixed_arena.h" #include "pass.h" #include "support/name.h" #include "wasm-builder.h"-#include "wasm-printing.h" #include "wasm-type.h" #include "wasm.h" @@ -37,6 +35,18 @@ Name I64U_REM("i64u-rem"); Name I64S_DIV("i64s-div"); Name I64U_DIV("i64u-div");++static Expression* ensureDouble(Expression* expr, MixedArena& allocator) {+ if (expr->type == Type::f32) {+ auto conv = allocator.alloc<Unary>();+ conv->op = PromoteFloat32;+ conv->value = expr;+ conv->type = Type::f64;+ return conv;+ }+ assert(expr->type == Type::f64);+ return expr;+} Name getBinaryFuncName(Binary* curr) { switch (curr->op) {
binaryen/src/passes/Vacuum.cpp view
@@ -20,6 +20,7 @@ #include <ir/block-utils.h> #include <ir/effects.h>+#include <ir/iteration.h> #include <ir/literal-utils.h> #include <ir/type-updating.h> #include <ir/utils.h>@@ -49,169 +50,85 @@ walk(func->body); } - // Returns nullptr if curr is dead, curr if it must stay as is, or another- // node if it can be replaced. Takes into account:+ // Returns nullptr if curr is dead, curr if it must stay as is, or one of its+ // children if it can be replaced. Takes into account:+ // // * The result may be used or unused.- // * The type may or may not matter (a drop can drop anything, for example).+ // * The type may or may not matter.+ //+ // For example,+ //+ // (drop+ // (i32.eqz+ // (call ..)))+ //+ // The drop means that the value is not used later. And while the call has+ // side effects, the i32.eqz does not. So when we are called on the i32.eqz,+ // and told the result does not matter, we can return the call. Note that in+ // this case the type does not matter either, as drop doesn't care, and anyhow+ // i32.eqz returns the same type as it receives. But for an expression that+ // returns a different type, if the type matters then we cannot replace it. Expression* optimize(Expression* curr, bool resultUsed, bool typeMatters) { FeatureSet features = getModule()->features; auto type = curr->type;- // An unreachable node must not be changed.+ // If the type is none, then we can never replace it with another type.+ if (type == Type::none) {+ typeMatters = true;+ }+ // An unreachable node must not be changed. DCE will remove those. if (type == Type::unreachable) { return curr; }- // We iterate on possible replacements. If a replacement changes the type,- // stop and go back.+ // resultUsed only makes sense when the type is concrete+ assert(!resultUsed || curr->type != Type::none);+ // If we actually need the result, then we must not change anything.+ // TODO: maybe there is something clever though?+ if (resultUsed) {+ return curr;+ }+ // We iterate on possible replacements. auto* prev = curr; while (1) {+ // If a replacement changes the type, and the type matters, return the+ // previous one and stop. if (typeMatters && curr->type != type) { return prev; } prev = curr;- switch (curr->_id) {- case Expression::Id::NopId:- return nullptr; // never needed-- case Expression::Id::BlockId:- return curr; // not always needed, but handled in visitBlock()- case Expression::Id::IfId:- return curr; // not always needed, but handled in visitIf()- case Expression::Id::LoopId:- return curr; // not always needed, but handled in visitLoop()- case Expression::Id::DropId:- return curr; // not always needed, but handled in visitDrop()- case Expression::Id::TryId:- return curr; // not always needed, but handled in visitTry()-- case Expression::Id::BreakId:- case Expression::Id::SwitchId:- case Expression::Id::BrOnExnId:- case Expression::Id::CallId:- case Expression::Id::CallIndirectId:- case Expression::Id::LocalSetId:- case Expression::Id::StoreId:- case Expression::Id::ReturnId:- case Expression::Id::GlobalSetId:- case Expression::Id::MemorySizeId:- case Expression::Id::MemoryGrowId:- case Expression::Id::UnreachableId:- return curr; // always needed-- case Expression::Id::LoadId: {- // it is ok to remove a load if the result is not used, and it has no- // side effects (the load itself may trap, if we are not ignoring such- // things)- auto* load = curr->cast<Load>();- if (!resultUsed && !EffectAnalyzer(getPassOptions(), features, curr)- .hasSideEffects()) {- if (!typeMatters || load->ptr->type == type) {- return load->ptr;- }- }- return curr;- }- case Expression::Id::ConstId:- case Expression::Id::LocalGetId:- case Expression::Id::GlobalGetId: {- if (!resultUsed) {- return nullptr;- }- return curr;- }-- case Expression::Id::UnaryId:- case Expression::Id::BinaryId:- case Expression::Id::SelectId: {- if (resultUsed) {- return curr; // used, keep it- }- // for unary, binary, and select, we need to check their arguments for- // side effects, as well as the node itself, as some unaries and- // binaries have implicit traps- if (auto* unary = curr->dynCast<Unary>()) {- EffectAnalyzer tester(getPassOptions(), features);- tester.visitUnary(unary);- if (tester.hasSideEffects()) {- return curr;- }- if (EffectAnalyzer(getPassOptions(), features, unary->value)- .hasSideEffects()) {- curr = unary->value;- continue;- } else {- return nullptr;- }- } else if (auto* binary = curr->dynCast<Binary>()) {- EffectAnalyzer tester(getPassOptions(), features);- tester.visitBinary(binary);- if (tester.hasSideEffects()) {- return curr;- }- if (EffectAnalyzer(getPassOptions(), features, binary->left)- .hasSideEffects()) {- if (EffectAnalyzer(getPassOptions(), features, binary->right)- .hasSideEffects()) {- return curr; // leave them- } else {- curr = binary->left;- continue;- }- } else {- if (EffectAnalyzer(getPassOptions(), features, binary->right)- .hasSideEffects()) {- curr = binary->right;- continue;- } else {- return nullptr;- }- }- } else {- // TODO: if two have side effects, we could replace the select with- // say an add?- auto* select = curr->cast<Select>();- if (EffectAnalyzer(getPassOptions(), features, select->ifTrue)- .hasSideEffects()) {- if (EffectAnalyzer(getPassOptions(), features, select->ifFalse)- .hasSideEffects()) {- return curr; // leave them- } else {- if (EffectAnalyzer(- getPassOptions(), features, select->condition)- .hasSideEffects()) {- return curr; // leave them- } else {- curr = select->ifTrue;- continue;- }- }- } else {- if (EffectAnalyzer(getPassOptions(), features, select->ifFalse)- .hasSideEffects()) {- if (EffectAnalyzer(- getPassOptions(), features, select->condition)- .hasSideEffects()) {- return curr; // leave them- } else {- curr = select->ifFalse;- continue;- }- } else {- if (EffectAnalyzer(- getPassOptions(), features, select->condition)- .hasSideEffects()) {- curr = select->condition;- continue;- } else {- return nullptr;- }- }- }- }+ // Some instructions have special handling in visit*, and we should do+ // nothing for them here.+ if (curr->is<Drop>() || curr->is<Block>() || curr->is<If>() ||+ curr->is<Loop>() || curr->is<Try>()) {+ return curr;+ }+ // Check if this expression itself has side effects, ignoring children.+ EffectAnalyzer self(getPassOptions(), features);+ self.visit(curr);+ if (self.hasSideEffects()) {+ return curr;+ }+ // The result isn't used, and this has no side effects itself, so we can+ // get rid of it. However, the children may have side effects.+ SmallVector<Expression*, 1> childrenWithEffects;+ for (auto* child : ChildIterator(curr)) {+ if (EffectAnalyzer(getPassOptions(), features, child)+ .hasSideEffects()) {+ childrenWithEffects.push_back(child); }-- default:- return curr; // assume needed }+ if (childrenWithEffects.empty()) {+ return nullptr;+ }+ if (childrenWithEffects.size() == 1) {+ // We know the result isn't used, and curr has no side effects, so we+ // can skip curr and keep looking into the child.+ curr = childrenWithEffects[0];+ continue;+ }+ // TODO: with multiple children with side effects, we can perhaps figure+ // out something clever, like a block with drops, or an i32.add for just+ // two, etc.+ return curr; } }
binaryen/src/passes/WasmIntrinsics.cpp view
@@ -2,8 +2,8 @@ #include "passes/intrinsics-module.h" -static const char theModule[24267] = {-59, 59, 32, 65, 32, 108, 97, 114, 103, 101, 32, 87, 65, 83, 84, 32, 98, 108, 111, 98, 32, 119, 104, 105, 99, 104, 32, 99, 111, 110, 116, 97, 105, 110, 115, 32, 116, 104, 101, 32, 105, 109, 112, 108, 101, 109, 101, 110, 116, 97, 116, 105, 111, 110, 115, 32, 111, 102, 32, 97, 108, 108, 32, 116, 104, 101, 32, 105, 110, 116, 114, 105, 110, 115, 105, 99, 115, 10, 59, 59, 32, 116, 104, 97, 116, 32, 119, 101, 32, 105, 110, 106, 101, 99, 116, 32, 97, 115, 32, 112, 97, 114, 116, 32, 111, 102, 32, 116, 104, 105, 115, 32, 109, 111, 100, 117, 108, 101, 46, 32, 84, 104, 105, 115, 32, 98, 108, 111, 98, 32, 119, 97, 115, 32, 103, 101, 110, 101, 114, 97, 116, 101, 100, 32, 102, 114, 111, 109, 32, 97, 32, 82, 117, 115, 116, 10, 59, 59, 32, 112, 114, 111, 103, 114, 97, 109, 32, 91, 49, 93, 32, 119, 104, 105, 99, 104, 32, 117, 115, 101, 115, 32, 116, 104, 101, 32, 82, 117, 115, 116, 32, 99, 111, 109, 112, 105, 108, 101, 114, 45, 98, 117, 105, 108, 116, 105, 110, 115, 32, 112, 114, 111, 106, 101, 99, 116, 46, 32, 73, 116, 39, 115, 32, 110, 111, 116, 10, 59, 59, 32, 110, 101, 99, 101, 115, 115, 97, 114, 105, 108, 121, 32, 112, 101, 114, 102, 101, 99, 116, 32, 98, 117, 116, 32, 103, 101, 116, 115, 32, 116, 104, 101, 32, 106, 111, 98, 32, 100, 111, 110, 101, 33, 32, 84, 104, 101, 32, 105, 100, 101, 97, 32, 104, 101, 114, 101, 32, 105, 115, 32, 116, 104, 97, 116, 32, 119, 101, 32, 105, 110, 106, 101, 99, 116, 10, 59, 59, 32, 116, 104, 101, 115, 101, 32, 112, 114, 101, 116, 116, 121, 32, 101, 97, 114, 108, 121, 32, 115, 111, 32, 116, 104, 101, 121, 32, 99, 97, 110, 32, 99, 111, 110, 116, 105, 110, 117, 101, 32, 116, 111, 32, 98, 101, 32, 111, 112, 116, 105, 109, 105, 122, 101, 100, 32, 98, 121, 32, 102, 117, 114, 116, 104, 101, 114, 32, 112, 97, 115, 115, 101, 115, 10, 59, 59, 32, 40, 97, 107, 97, 32, 105, 110, 108, 105, 110, 105, 110, 103, 32, 97, 110, 100, 32, 119, 104, 97, 116, 110, 111, 116, 41, 10, 59, 59, 10, 59, 59, 32, 76, 79, 67, 65, 76, 32, 77, 79, 68, 83, 32, 100, 111, 110, 101, 32, 98, 121, 32, 104, 97, 110, 100, 32, 97, 102, 116, 101, 114, 119, 97, 114, 100, 115, 58, 10, 59, 59, 32, 32, 42, 32, 82, 101, 109, 111, 118, 101, 32, 104, 97, 114, 100, 99, 111, 100, 101, 100, 32, 97, 100, 100, 114, 101, 115, 115, 32, 49, 48, 50, 52, 32, 119, 104, 105, 99, 104, 32, 119, 97, 115, 32, 117, 115, 101, 100, 32, 102, 111, 114, 32, 116, 101, 109, 112, 111, 114, 97, 114, 121, 32, 100, 97, 116, 97, 59, 32, 105, 110, 115, 116, 101, 97, 100, 10, 59, 59, 32, 32, 32, 32, 97, 100, 100, 32, 36, 119, 97, 115, 109, 45, 105, 110, 116, 114, 105, 110, 115, 105, 99, 115, 45, 116, 101, 109, 112, 45, 105, 54, 52, 32, 103, 108, 111, 98, 97, 108, 32, 102, 111, 114, 32, 116, 104, 97, 116, 46, 10, 59, 59, 32, 32, 42, 32, 70, 105, 120, 32, 102, 117, 110, 99, 116, 105, 111, 110, 32, 116, 121, 112, 101, 32, 111, 102, 32, 95, 95, 119, 97, 115, 109, 95, 99, 116, 122, 95, 105, 54, 52, 44, 32, 119, 104, 105, 99, 104, 32, 119, 97, 115, 32, 119, 114, 111, 110, 103, 32, 115, 111, 109, 101, 104, 111, 119, 44, 10, 59, 59, 32, 32, 32, 32, 105, 51, 50, 44, 32, 105, 51, 50, 32, 61, 62, 32, 105, 51, 50, 32, 105, 110, 115, 116, 101, 97, 100, 32, 111, 102, 32, 105, 54, 52, 32, 61, 62, 32, 105, 54, 52, 10, 59, 59, 32, 32, 42, 32, 82, 101, 109, 111, 118, 101, 32, 117, 110, 110, 101, 99, 101, 115, 115, 97, 114, 121, 32, 109, 101, 109, 111, 114, 121, 32, 105, 109, 112, 111, 114, 116, 46, 10, 59, 59, 10, 59, 59, 32, 91, 49, 93, 58, 32, 104, 116, 116, 112, 115, 58, 47, 47, 103, 105, 115, 116, 46, 103, 105, 116, 104, 117, 98, 46, 99, 111, 109, 47, 97, 108, 101, 120, 99, 114, 105, 99, 104, 116, 111, 110, 47, 101, 55, 101, 97, 54, 55, 98, 99, 100, 100, 49, 55, 99, 101, 52, 98, 54, 50, 53, 52, 101, 54, 54, 102, 55, 55, 49, 54, 53, 54, 57, 48, 10, 10, 40, 109, 111, 100, 117, 108, 101, 10, 32, 40, 116, 121, 112, 101, 32, 36, 48, 32, 40, 102, 117, 110, 99, 32, 40, 112, 97, 114, 97, 109, 32, 105, 54, 52, 32, 105, 54, 52, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 54, 52, 41, 41, 41, 10, 32, 40, 116, 121, 112, 101, 32, 36, 49, 32, 40, 102, 117, 110, 99, 32, 40, 112, 97, 114, 97, 109, 32, 102, 51, 50, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 102, 51, 50, 41, 41, 41, 10, 32, 40, 116, 121, 112, 101, 32, 36, 50, 32, 40, 102, 117, 110, 99, 32, 40, 112, 97, 114, 97, 109, 32, 102, 54, 52, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 102, 54, 52, 41, 41, 41, 10, 32, 40, 116, 121, 112, 101, 32, 36, 51, 32, 40, 102, 117, 110, 99, 32, 40, 112, 97, 114, 97, 109, 32, 105, 51, 50, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 41, 41, 10, 32, 40, 116, 121, 112, 101, 32, 36, 52, 32, 40, 102, 117, 110, 99, 32, 40, 112, 97, 114, 97, 109, 32, 105, 51, 50, 32, 105, 51, 50, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 41, 41, 10, 32, 40, 116, 121, 112, 101, 32, 36, 53, 32, 40, 102, 117, 110, 99, 32, 40, 112, 97, 114, 97, 109, 32, 105, 54, 52, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 54, 52, 41, 41, 41, 10, 32, 40, 101, 120, 112, 111, 114, 116, 32, 34, 95, 95, 119, 97, 115, 109, 95, 105, 54, 52, 95, 115, 100, 105, 118, 34, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 105, 54, 52, 95, 115, 100, 105, 118, 41, 41, 10, 32, 40, 101, 120, 112, 111, 114, 116, 32, 34, 95, 95, 119, 97, 115, 109, 95, 105, 54, 52, 95, 117, 100, 105, 118, 34, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 105, 54, 52, 95, 117, 100, 105, 118, 41, 41, 10, 32, 40, 101, 120, 112, 111, 114, 116, 32, 34, 95, 95, 119, 97, 115, 109, 95, 105, 54, 52, 95, 115, 114, 101, 109, 34, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 105, 54, 52, 95, 115, 114, 101, 109, 41, 41, 10, 32, 40, 101, 120, 112, 111, 114, 116, 32, 34, 95, 95, 119, 97, 115, 109, 95, 105, 54, 52, 95, 117, 114, 101, 109, 34, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 105, 54, 52, 95, 117, 114, 101, 109, 41, 41, 10, 32, 40, 101, 120, 112, 111, 114, 116, 32, 34, 95, 95, 119, 97, 115, 109, 95, 105, 54, 52, 95, 109, 117, 108, 34, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 105, 54, 52, 95, 109, 117, 108, 41, 41, 10, 32, 40, 101, 120, 112, 111, 114, 116, 32, 34, 95, 95, 119, 97, 115, 109, 95, 116, 114, 117, 110, 99, 95, 102, 51, 50, 34, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 116, 114, 117, 110, 99, 95, 102, 51, 50, 41, 41, 10, 32, 40, 101, 120, 112, 111, 114, 116, 32, 34, 95, 95, 119, 97, 115, 109, 95, 116, 114, 117, 110, 99, 95, 102, 54, 52, 34, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 116, 114, 117, 110, 99, 95, 102, 54, 52, 41, 41, 10, 32, 40, 101, 120, 112, 111, 114, 116, 32, 34, 95, 95, 119, 97, 115, 109, 95, 99, 116, 122, 95, 105, 51, 50, 34, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 99, 116, 122, 95, 105, 51, 50, 41, 41, 10, 32, 40, 101, 120, 112, 111, 114, 116, 32, 34, 95, 95, 119, 97, 115, 109, 95, 99, 116, 122, 95, 105, 54, 52, 34, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 99, 116, 122, 95, 105, 54, 52, 41, 41, 10, 32, 40, 101, 120, 112, 111, 114, 116, 32, 34, 95, 95, 119, 97, 115, 109, 95, 114, 111, 116, 108, 95, 105, 51, 50, 34, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 114, 111, 116, 108, 95, 105, 51, 50, 41, 41, 10, 32, 40, 101, 120, 112, 111, 114, 116, 32, 34, 95, 95, 119, 97, 115, 109, 95, 114, 111, 116, 114, 95, 105, 51, 50, 34, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 114, 111, 116, 114, 95, 105, 51, 50, 41, 41, 10, 32, 40, 101, 120, 112, 111, 114, 116, 32, 34, 95, 95, 119, 97, 115, 109, 95, 114, 111, 116, 108, 95, 105, 54, 52, 34, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 114, 111, 116, 108, 95, 105, 54, 52, 41, 41, 10, 32, 40, 101, 120, 112, 111, 114, 116, 32, 34, 95, 95, 119, 97, 115, 109, 95, 114, 111, 116, 114, 95, 105, 54, 52, 34, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 114, 111, 116, 114, 95, 105, 54, 52, 41, 41, 10, 32, 40, 101, 120, 112, 111, 114, 116, 32, 34, 95, 95, 119, 97, 115, 109, 95, 110, 101, 97, 114, 101, 115, 116, 95, 102, 51, 50, 34, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 110, 101, 97, 114, 101, 115, 116, 95, 102, 51, 50, 41, 41, 10, 32, 40, 101, 120, 112, 111, 114, 116, 32, 34, 95, 95, 119, 97, 115, 109, 95, 110, 101, 97, 114, 101, 115, 116, 95, 102, 54, 52, 34, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 110, 101, 97, 114, 101, 115, 116, 95, 102, 54, 52, 41, 41, 10, 32, 40, 101, 120, 112, 111, 114, 116, 32, 34, 95, 95, 119, 97, 115, 109, 95, 112, 111, 112, 99, 110, 116, 95, 105, 51, 50, 34, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 112, 111, 112, 99, 110, 116, 95, 105, 51, 50, 41, 41, 10, 32, 40, 101, 120, 112, 111, 114, 116, 32, 34, 95, 95, 119, 97, 115, 109, 95, 112, 111, 112, 99, 110, 116, 95, 105, 54, 52, 34, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 112, 111, 112, 99, 110, 116, 95, 105, 54, 52, 41, 41, 10, 32, 40, 103, 108, 111, 98, 97, 108, 32, 36, 95, 95, 119, 97, 115, 109, 45, 105, 110, 116, 114, 105, 110, 115, 105, 99, 115, 45, 116, 101, 109, 112, 45, 105, 54, 52, 32, 40, 109, 117, 116, 32, 105, 54, 52, 41, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 48, 41, 41, 10, 10, 32, 59, 59, 32, 108, 111, 119, 101, 114, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 105, 51, 50, 46, 112, 111, 112, 99, 110, 116, 32, 105, 110, 115, 116, 114, 117, 99, 116, 105, 111, 110, 44, 32, 99, 111, 117, 110, 116, 115, 32, 116, 104, 101, 32, 110, 117, 109, 98, 101, 114, 32, 111, 102, 32, 98, 105, 116, 115, 32, 115, 101, 116, 32, 105, 110, 32, 116, 104, 101, 10, 32, 59, 59, 32, 105, 110, 112, 117, 116, 32, 97, 110, 100, 32, 114, 101, 116, 117, 114, 110, 115, 32, 116, 104, 101, 32, 114, 101, 115, 117, 108, 116, 10, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 112, 111, 112, 99, 110, 116, 95, 105, 51, 50, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 48, 32, 105, 51, 50, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 10, 32, 32, 40, 108, 111, 99, 97, 108, 32, 36, 118, 97, 114, 36, 49, 32, 105, 51, 50, 41, 10, 32, 32, 40, 98, 108, 111, 99, 107, 32, 36, 108, 97, 98, 101, 108, 36, 49, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 10, 32, 32, 32, 40, 108, 111, 111, 112, 32, 36, 108, 97, 98, 101, 108, 36, 50, 10, 32, 32, 32, 32, 40, 100, 114, 111, 112, 10, 32, 32, 32, 32, 32, 40, 98, 114, 95, 105, 102, 32, 36, 108, 97, 98, 101, 108, 36, 49, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 101, 113, 122, 10, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 115, 101, 116, 32, 36, 118, 97, 114, 36, 48, 10, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 115, 117, 98, 10, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 49, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 115, 101, 116, 32, 36, 118, 97, 114, 36, 49, 10, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 100, 100, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 49, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 40, 98, 114, 32, 36, 108, 97, 98, 101, 108, 36, 50, 41, 10, 32, 32, 32, 41, 10, 32, 32, 41, 10, 32, 41, 10, 32, 59, 59, 32, 108, 111, 119, 101, 114, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 105, 54, 52, 46, 112, 111, 112, 99, 110, 116, 32, 105, 110, 115, 116, 114, 117, 99, 116, 105, 111, 110, 44, 32, 99, 111, 117, 110, 116, 115, 32, 116, 104, 101, 32, 110, 117, 109, 98, 101, 114, 32, 111, 102, 32, 98, 105, 116, 115, 32, 115, 101, 116, 32, 105, 110, 32, 116, 104, 101, 10, 32, 59, 59, 32, 105, 110, 112, 117, 116, 32, 97, 110, 100, 32, 114, 101, 116, 117, 114, 110, 115, 32, 116, 104, 101, 32, 114, 101, 115, 117, 108, 116, 10, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 112, 111, 112, 99, 110, 116, 95, 105, 54, 52, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 48, 32, 105, 54, 52, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 54, 52, 41, 10, 32, 32, 40, 108, 111, 99, 97, 108, 32, 36, 118, 97, 114, 36, 49, 32, 105, 54, 52, 41, 10, 32, 32, 40, 98, 108, 111, 99, 107, 32, 36, 108, 97, 98, 101, 108, 36, 49, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 54, 52, 41, 10, 32, 32, 32, 40, 108, 111, 111, 112, 32, 36, 108, 97, 98, 101, 108, 36, 50, 10, 32, 32, 32, 32, 40, 100, 114, 111, 112, 10, 32, 32, 32, 32, 32, 40, 98, 114, 95, 105, 102, 32, 36, 108, 97, 98, 101, 108, 36, 49, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 101, 113, 122, 10, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 115, 101, 116, 32, 36, 118, 97, 114, 36, 48, 10, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 117, 98, 10, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 49, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 115, 101, 116, 32, 36, 118, 97, 114, 36, 49, 10, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 97, 100, 100, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 49, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 40, 98, 114, 32, 36, 108, 97, 98, 101, 108, 36, 50, 41, 10, 32, 32, 32, 41, 10, 32, 32, 41, 10, 32, 41, 10, 32, 59, 59, 32, 108, 111, 119, 101, 114, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 105, 54, 52, 46, 100, 105, 118, 95, 115, 32, 105, 110, 115, 116, 114, 117, 99, 116, 105, 111, 110, 44, 32, 114, 101, 116, 117, 114, 110, 32, 36, 118, 97, 114, 48, 32, 47, 32, 36, 118, 97, 114, 36, 49, 10, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 105, 54, 52, 95, 115, 100, 105, 118, 32, 40, 59, 32, 48, 32, 59, 41, 32, 40, 116, 121, 112, 101, 32, 36, 48, 41, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 48, 32, 105, 54, 52, 41, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 49, 32, 105, 54, 52, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 54, 52, 41, 10, 32, 32, 40, 99, 97, 108, 108, 32, 36, 95, 90, 78, 49, 55, 99, 111, 109, 112, 105, 108, 101, 114, 95, 98, 117, 105, 108, 116, 105, 110, 115, 51, 105, 110, 116, 52, 115, 100, 105, 118, 51, 68, 105, 118, 51, 100, 105, 118, 49, 55, 104, 101, 55, 56, 102, 99, 52, 56, 51, 101, 52, 49, 100, 55, 101, 99, 55, 69, 10, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 41, 10, 32, 41, 10, 32, 59, 59, 32, 108, 111, 119, 101, 114, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 105, 54, 52, 46, 100, 105, 118, 95, 117, 32, 105, 110, 115, 116, 114, 117, 99, 116, 105, 111, 110, 44, 32, 114, 101, 116, 117, 114, 110, 32, 36, 118, 97, 114, 48, 32, 47, 32, 36, 118, 97, 114, 36, 49, 10, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 105, 54, 52, 95, 117, 100, 105, 118, 32, 40, 59, 32, 49, 32, 59, 41, 32, 40, 116, 121, 112, 101, 32, 36, 48, 41, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 48, 32, 105, 54, 52, 41, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 49, 32, 105, 54, 52, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 54, 52, 41, 10, 32, 32, 40, 99, 97, 108, 108, 32, 36, 95, 90, 78, 49, 55, 99, 111, 109, 112, 105, 108, 101, 114, 95, 98, 117, 105, 108, 116, 105, 110, 115, 51, 105, 110, 116, 52, 117, 100, 105, 118, 49, 48, 100, 105, 118, 109, 111, 100, 95, 117, 54, 52, 49, 55, 104, 54, 48, 50, 54, 57, 49, 48, 98, 53, 101, 100, 48, 56, 101, 52, 48, 69, 10, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 41, 10, 32, 41, 10, 32, 59, 59, 32, 108, 111, 119, 101, 114, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 105, 54, 52, 46, 114, 101, 109, 95, 115, 32, 105, 110, 115, 116, 114, 117, 99, 116, 105, 111, 110, 44, 32, 114, 101, 116, 117, 114, 110, 32, 36, 118, 97, 114, 48, 32, 37, 32, 36, 118, 97, 114, 36, 49, 10, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 105, 54, 52, 95, 115, 114, 101, 109, 32, 40, 59, 32, 50, 32, 59, 41, 32, 40, 116, 121, 112, 101, 32, 36, 48, 41, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 48, 32, 105, 54, 52, 41, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 49, 32, 105, 54, 52, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 54, 52, 41, 10, 32, 32, 40, 99, 97, 108, 108, 32, 36, 95, 90, 78, 49, 55, 99, 111, 109, 112, 105, 108, 101, 114, 95, 98, 117, 105, 108, 116, 105, 110, 115, 51, 105, 110, 116, 52, 115, 100, 105, 118, 51, 77, 111, 100, 52, 109, 111, 100, 95, 49, 55, 104, 50, 99, 98, 98, 55, 98, 98, 102, 51, 54, 101, 52, 49, 100, 54, 56, 69, 10, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 41, 10, 32, 41, 10, 32, 59, 59, 32, 108, 111, 119, 101, 114, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 105, 54, 52, 46, 114, 101, 109, 95, 117, 32, 105, 110, 115, 116, 114, 117, 99, 116, 105, 111, 110, 44, 32, 114, 101, 116, 117, 114, 110, 32, 36, 118, 97, 114, 48, 32, 37, 32, 36, 118, 97, 114, 36, 49, 10, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 105, 54, 52, 95, 117, 114, 101, 109, 32, 40, 59, 32, 51, 32, 59, 41, 32, 40, 116, 121, 112, 101, 32, 36, 48, 41, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 48, 32, 105, 54, 52, 41, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 49, 32, 105, 54, 52, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 54, 52, 41, 10, 32, 32, 40, 100, 114, 111, 112, 10, 32, 32, 32, 40, 99, 97, 108, 108, 32, 36, 95, 90, 78, 49, 55, 99, 111, 109, 112, 105, 108, 101, 114, 95, 98, 117, 105, 108, 116, 105, 110, 115, 51, 105, 110, 116, 52, 117, 100, 105, 118, 49, 48, 100, 105, 118, 109, 111, 100, 95, 117, 54, 52, 49, 55, 104, 54, 48, 50, 54, 57, 49, 48, 98, 53, 101, 100, 48, 56, 101, 52, 48, 69, 10, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 41, 10, 32, 32, 41, 10, 32, 32, 40, 103, 108, 111, 98, 97, 108, 46, 103, 101, 116, 32, 36, 95, 95, 119, 97, 115, 109, 45, 105, 110, 116, 114, 105, 110, 115, 105, 99, 115, 45, 116, 101, 109, 112, 45, 105, 54, 52, 41, 10, 32, 41, 10, 32, 59, 59, 32, 108, 111, 119, 101, 114, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 105, 54, 52, 46, 109, 117, 108, 32, 105, 110, 115, 116, 114, 117, 99, 116, 105, 111, 110, 44, 32, 114, 101, 116, 117, 114, 110, 32, 36, 118, 97, 114, 48, 32, 42, 32, 36, 118, 97, 114, 36, 49, 10, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 105, 54, 52, 95, 109, 117, 108, 32, 40, 59, 32, 52, 32, 59, 41, 32, 40, 116, 121, 112, 101, 32, 36, 48, 41, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 48, 32, 105, 54, 52, 41, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 49, 32, 105, 54, 52, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 54, 52, 41, 10, 32, 32, 40, 99, 97, 108, 108, 32, 36, 95, 90, 78, 49, 55, 99, 111, 109, 112, 105, 108, 101, 114, 95, 98, 117, 105, 108, 116, 105, 110, 115, 51, 105, 110, 116, 51, 109, 117, 108, 51, 77, 117, 108, 51, 109, 117, 108, 49, 55, 104, 48, 55, 48, 101, 57, 97, 49, 99, 54, 57, 102, 97, 101, 99, 53, 98, 69, 10, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 41, 10, 32, 41, 10, 32, 59, 59, 32, 108, 111, 119, 101, 114, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 102, 51, 50, 46, 116, 114, 117, 110, 99, 32, 105, 110, 115, 116, 114, 117, 99, 116, 105, 111, 110, 44, 32, 114, 111, 117, 110, 100, 115, 32, 116, 111, 32, 116, 104, 101, 32, 110, 101, 97, 114, 101, 115, 116, 32, 105, 110, 116, 101, 103, 101, 114, 44, 10, 32, 59, 59, 32, 116, 111, 119, 97, 114, 100, 115, 32, 122, 101, 114, 111, 10, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 116, 114, 117, 110, 99, 95, 102, 51, 50, 32, 40, 59, 32, 53, 32, 59, 41, 32, 40, 116, 121, 112, 101, 32, 36, 49, 41, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 48, 32, 102, 51, 50, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 102, 51, 50, 41, 10, 32, 32, 40, 115, 101, 108, 101, 99, 116, 10, 32, 32, 32, 40, 102, 51, 50, 46, 99, 101, 105, 108, 10, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 41, 10, 32, 32, 32, 40, 102, 51, 50, 46, 102, 108, 111, 111, 114, 10, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 41, 10, 32, 32, 32, 40, 102, 51, 50, 46, 108, 116, 10, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 40, 102, 51, 50, 46, 99, 111, 110, 115, 116, 32, 48, 41, 10, 32, 32, 32, 41, 10, 32, 32, 41, 10, 32, 41, 10, 32, 59, 59, 32, 108, 111, 119, 101, 114, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 102, 54, 52, 46, 116, 114, 117, 110, 99, 32, 105, 110, 115, 116, 114, 117, 99, 116, 105, 111, 110, 44, 32, 114, 111, 117, 110, 100, 115, 32, 116, 111, 32, 116, 104, 101, 32, 110, 101, 97, 114, 101, 115, 116, 32, 105, 110, 116, 101, 103, 101, 114, 44, 10, 32, 59, 59, 32, 116, 111, 119, 97, 114, 100, 115, 32, 122, 101, 114, 111, 10, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 116, 114, 117, 110, 99, 95, 102, 54, 52, 32, 40, 59, 32, 54, 32, 59, 41, 32, 40, 116, 121, 112, 101, 32, 36, 50, 41, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 48, 32, 102, 54, 52, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 102, 54, 52, 41, 10, 32, 32, 40, 115, 101, 108, 101, 99, 116, 10, 32, 32, 32, 40, 102, 54, 52, 46, 99, 101, 105, 108, 10, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 41, 10, 32, 32, 32, 40, 102, 54, 52, 46, 102, 108, 111, 111, 114, 10, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 41, 10, 32, 32, 32, 40, 102, 54, 52, 46, 108, 116, 10, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 40, 102, 54, 52, 46, 99, 111, 110, 115, 116, 32, 48, 41, 10, 32, 32, 32, 41, 10, 32, 32, 41, 10, 32, 41, 10, 32, 59, 59, 32, 108, 111, 119, 101, 114, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 105, 51, 50, 46, 99, 116, 122, 32, 105, 110, 115, 116, 114, 117, 99, 116, 105, 111, 110, 44, 32, 99, 111, 117, 110, 116, 105, 110, 103, 32, 116, 104, 101, 32, 110, 117, 109, 98, 101, 114, 32, 111, 102, 32, 122, 101, 114, 111, 115, 32, 105, 110, 32, 36, 118, 97, 114, 36, 48, 10, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 99, 116, 122, 95, 105, 51, 50, 32, 40, 59, 32, 55, 32, 59, 41, 32, 40, 116, 121, 112, 101, 32, 36, 51, 41, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 48, 32, 105, 51, 50, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 10, 32, 32, 40, 105, 102, 10, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 40, 114, 101, 116, 117, 114, 110, 10, 32, 32, 32, 32, 40, 105, 51, 50, 46, 115, 117, 98, 10, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 51, 49, 41, 10, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 108, 122, 10, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 120, 111, 114, 10, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 100, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 45, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 41, 10, 32, 32, 41, 10, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 51, 50, 41, 10, 32, 41, 10, 32, 59, 59, 32, 108, 111, 119, 101, 114, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 105, 54, 52, 46, 99, 116, 122, 32, 105, 110, 115, 116, 114, 117, 99, 116, 105, 111, 110, 44, 32, 99, 111, 117, 110, 116, 105, 110, 103, 32, 116, 104, 101, 32, 110, 117, 109, 98, 101, 114, 32, 111, 102, 32, 122, 101, 114, 111, 115, 32, 105, 110, 32, 36, 118, 97, 114, 36, 48, 10, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 99, 116, 122, 95, 105, 54, 52, 32, 40, 59, 32, 56, 32, 59, 41, 32, 40, 116, 121, 112, 101, 32, 36, 53, 41, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 48, 32, 105, 54, 52, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 54, 52, 41, 10, 32, 32, 40, 105, 102, 10, 32, 32, 32, 40, 105, 51, 50, 46, 101, 113, 122, 10, 32, 32, 32, 32, 40, 105, 54, 52, 46, 101, 113, 122, 10, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 41, 10, 32, 32, 32, 40, 114, 101, 116, 117, 114, 110, 10, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 117, 98, 10, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 54, 51, 41, 10, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 108, 122, 10, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 120, 111, 114, 10, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 97, 100, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 45, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 41, 10, 32, 32, 41, 10, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 54, 52, 41, 10, 32, 41, 10, 32, 59, 59, 32, 108, 111, 119, 101, 114, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 105, 51, 50, 46, 114, 111, 116, 108, 32, 105, 110, 115, 116, 114, 117, 99, 116, 105, 111, 110, 44, 32, 114, 111, 116, 97, 116, 105, 110, 103, 32, 116, 104, 101, 32, 102, 105, 114, 115, 116, 32, 97, 114, 103, 117, 109, 101, 110, 116, 44, 32, 119, 105, 116, 104, 10, 32, 59, 59, 32, 119, 114, 97, 112, 97, 114, 111, 117, 110, 100, 44, 32, 98, 121, 32, 116, 104, 101, 32, 115, 101, 99, 111, 110, 100, 32, 97, 114, 103, 117, 109, 101, 110, 116, 10, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 114, 111, 116, 108, 95, 105, 51, 50, 32, 40, 59, 32, 56, 32, 59, 41, 32, 40, 116, 121, 112, 101, 32, 36, 52, 41, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 48, 32, 105, 51, 50, 41, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 49, 32, 105, 51, 50, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 10, 32, 32, 40, 108, 111, 99, 97, 108, 32, 36, 118, 97, 114, 36, 50, 32, 105, 51, 50, 41, 10, 32, 32, 40, 105, 51, 50, 46, 111, 114, 10, 32, 32, 32, 40, 105, 51, 50, 46, 115, 104, 108, 10, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 115, 104, 114, 95, 117, 10, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 45, 49, 41, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 50, 10, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 51, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 41, 10, 32, 32, 32, 40, 105, 51, 50, 46, 115, 104, 114, 95, 117, 10, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 115, 104, 108, 10, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 45, 49, 41, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 49, 10, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 115, 117, 98, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 48, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 51, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 41, 10, 32, 32, 41, 10, 32, 41, 10, 32, 59, 59, 32, 108, 111, 119, 101, 114, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 105, 51, 50, 46, 114, 111, 116, 114, 32, 105, 110, 115, 116, 114, 117, 99, 116, 105, 111, 110, 44, 32, 114, 111, 116, 97, 116, 105, 110, 103, 32, 116, 104, 101, 32, 102, 105, 114, 115, 116, 32, 97, 114, 103, 117, 109, 101, 110, 116, 44, 32, 119, 105, 116, 104, 10, 32, 59, 59, 32, 119, 114, 97, 112, 97, 114, 111, 117, 110, 100, 44, 32, 98, 121, 32, 116, 104, 101, 32, 115, 101, 99, 111, 110, 100, 32, 97, 114, 103, 117, 109, 101, 110, 116, 10, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 114, 111, 116, 114, 95, 105, 51, 50, 32, 40, 59, 32, 57, 32, 59, 41, 32, 40, 116, 121, 112, 101, 32, 36, 52, 41, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 48, 32, 105, 51, 50, 41, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 49, 32, 105, 51, 50, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 10, 32, 32, 40, 108, 111, 99, 97, 108, 32, 36, 118, 97, 114, 36, 50, 32, 105, 51, 50, 41, 10, 32, 32, 40, 105, 51, 50, 46, 111, 114, 10, 32, 32, 32, 40, 105, 51, 50, 46, 115, 104, 114, 95, 117, 10, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 115, 104, 108, 10, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 45, 49, 41, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 50, 10, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 51, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 41, 10, 32, 32, 32, 40, 105, 51, 50, 46, 115, 104, 108, 10, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 115, 104, 114, 95, 117, 10, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 45, 49, 41, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 49, 10, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 115, 117, 98, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 48, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 51, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 41, 10, 32, 32, 41, 10, 32, 41, 10, 32, 59, 59, 32, 108, 111, 119, 101, 114, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 105, 54, 52, 46, 114, 111, 116, 108, 32, 105, 110, 115, 116, 114, 117, 99, 116, 105, 111, 110, 44, 32, 114, 111, 116, 97, 116, 105, 110, 103, 32, 116, 104, 101, 32, 102, 105, 114, 115, 116, 32, 97, 114, 103, 117, 109, 101, 110, 116, 44, 32, 119, 105, 116, 104, 10, 32, 59, 59, 32, 119, 114, 97, 112, 97, 114, 111, 117, 110, 100, 44, 32, 98, 121, 32, 116, 104, 101, 32, 115, 101, 99, 111, 110, 100, 32, 97, 114, 103, 117, 109, 101, 110, 116, 10, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 114, 111, 116, 108, 95, 105, 54, 52, 32, 40, 59, 32, 49, 48, 32, 59, 41, 32, 40, 116, 121, 112, 101, 32, 36, 48, 41, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 48, 32, 105, 54, 52, 41, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 49, 32, 105, 54, 52, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 54, 52, 41, 10, 32, 32, 40, 108, 111, 99, 97, 108, 32, 36, 118, 97, 114, 36, 50, 32, 105, 54, 52, 41, 10, 32, 32, 40, 105, 54, 52, 46, 111, 114, 10, 32, 32, 32, 40, 105, 54, 52, 46, 115, 104, 108, 10, 32, 32, 32, 32, 40, 105, 54, 52, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 104, 114, 95, 117, 10, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 45, 49, 41, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 50, 10, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 54, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 41, 10, 32, 32, 32, 40, 105, 54, 52, 46, 115, 104, 114, 95, 117, 10, 32, 32, 32, 32, 40, 105, 54, 52, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 104, 108, 10, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 45, 49, 41, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 49, 10, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 117, 98, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 48, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 54, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 41, 10, 32, 32, 41, 10, 32, 41, 10, 32, 59, 59, 32, 108, 111, 119, 101, 114, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 105, 54, 52, 46, 114, 111, 116, 114, 32, 105, 110, 115, 116, 114, 117, 99, 116, 105, 111, 110, 44, 32, 114, 111, 116, 97, 116, 105, 110, 103, 32, 116, 104, 101, 32, 102, 105, 114, 115, 116, 32, 97, 114, 103, 117, 109, 101, 110, 116, 44, 32, 119, 105, 116, 104, 10, 32, 59, 59, 32, 119, 114, 97, 112, 97, 114, 111, 117, 110, 100, 44, 32, 98, 121, 32, 116, 104, 101, 32, 115, 101, 99, 111, 110, 100, 32, 97, 114, 103, 117, 109, 101, 110, 116, 10, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 114, 111, 116, 114, 95, 105, 54, 52, 32, 40, 59, 32, 49, 49, 32, 59, 41, 32, 40, 116, 121, 112, 101, 32, 36, 48, 41, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 48, 32, 105, 54, 52, 41, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 49, 32, 105, 54, 52, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 54, 52, 41, 10, 32, 32, 40, 108, 111, 99, 97, 108, 32, 36, 118, 97, 114, 36, 50, 32, 105, 54, 52, 41, 10, 32, 32, 40, 105, 54, 52, 46, 111, 114, 10, 32, 32, 32, 40, 105, 54, 52, 46, 115, 104, 114, 95, 117, 10, 32, 32, 32, 32, 40, 105, 54, 52, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 104, 108, 10, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 45, 49, 41, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 50, 10, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 54, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 41, 10, 32, 32, 32, 40, 105, 54, 52, 46, 115, 104, 108, 10, 32, 32, 32, 32, 40, 105, 54, 52, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 104, 114, 95, 117, 10, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 45, 49, 41, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 49, 10, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 117, 98, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 48, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 54, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 41, 10, 32, 32, 41, 10, 32, 41, 10, 32, 59, 59, 32, 108, 111, 119, 101, 114, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 102, 51, 50, 46, 110, 101, 97, 114, 101, 115, 116, 32, 105, 110, 115, 116, 114, 117, 99, 116, 105, 111, 110, 44, 32, 114, 111, 117, 110, 100, 105, 110, 103, 32, 116, 104, 101, 32, 105, 110, 112, 117, 116, 32, 116, 111, 32, 116, 104, 101, 32, 110, 101, 97, 114, 101, 115, 116, 10, 32, 59, 59, 32, 105, 110, 116, 101, 103, 101, 114, 32, 119, 104, 105, 108, 101, 32, 98, 114, 101, 97, 107, 105, 110, 103, 32, 116, 105, 101, 115, 32, 98, 121, 32, 114, 111, 117, 110, 100, 105, 110, 103, 32, 116, 111, 32, 101, 118, 101, 110, 10, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 110, 101, 97, 114, 101, 115, 116, 95, 102, 51, 50, 32, 40, 59, 32, 49, 50, 32, 59, 41, 32, 40, 116, 121, 112, 101, 32, 36, 49, 41, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 48, 32, 102, 51, 50, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 102, 51, 50, 41, 10, 32, 32, 40, 108, 111, 99, 97, 108, 32, 36, 118, 97, 114, 36, 49, 32, 102, 51, 50, 41, 10, 32, 32, 40, 108, 111, 99, 97, 108, 32, 36, 118, 97, 114, 36, 50, 32, 102, 51, 50, 41, 10, 32, 32, 40, 105, 102, 10, 32, 32, 32, 40, 105, 51, 50, 46, 101, 113, 122, 10, 32, 32, 32, 32, 40, 102, 51, 50, 46, 108, 116, 10, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 50, 10, 32, 32, 32, 32, 32, 32, 40, 102, 51, 50, 46, 115, 117, 98, 10, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 49, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 102, 51, 50, 46, 102, 108, 111, 111, 114, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 40, 102, 51, 50, 46, 99, 111, 110, 115, 116, 32, 48, 46, 53, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 41, 10, 32, 32, 32, 40, 98, 108, 111, 99, 107, 10, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 115, 101, 116, 32, 36, 118, 97, 114, 36, 48, 10, 32, 32, 32, 32, 32, 40, 102, 51, 50, 46, 99, 101, 105, 108, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 40, 105, 102, 10, 32, 32, 32, 32, 32, 40, 102, 51, 50, 46, 103, 116, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 32, 32, 32, 40, 102, 51, 50, 46, 99, 111, 110, 115, 116, 32, 48, 46, 53, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 40, 114, 101, 116, 117, 114, 110, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 115, 101, 116, 32, 36, 118, 97, 114, 36, 49, 10, 32, 32, 32, 32, 32, 40, 115, 101, 108, 101, 99, 116, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 40, 102, 51, 50, 46, 101, 113, 10, 32, 32, 32, 32, 32, 32, 32, 40, 102, 51, 50, 46, 115, 117, 98, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 50, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 102, 51, 50, 46, 109, 117, 108, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 102, 51, 50, 46, 99, 111, 110, 115, 116, 32, 48, 46, 53, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 102, 51, 50, 46, 102, 108, 111, 111, 114, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 40, 102, 51, 50, 46, 99, 111, 110, 115, 116, 32, 48, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 41, 10, 32, 32, 41, 10, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 41, 10, 32, 59, 59, 32, 108, 111, 119, 101, 114, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 102, 54, 52, 46, 110, 101, 97, 114, 101, 115, 116, 32, 105, 110, 115, 116, 114, 117, 99, 116, 105, 111, 110, 44, 32, 114, 111, 117, 110, 100, 105, 110, 103, 32, 116, 104, 101, 32, 105, 110, 112, 117, 116, 32, 116, 111, 32, 116, 104, 101, 32, 110, 101, 97, 114, 101, 115, 116, 10, 32, 59, 59, 32, 105, 110, 116, 101, 103, 101, 114, 32, 119, 104, 105, 108, 101, 32, 98, 114, 101, 97, 107, 105, 110, 103, 32, 116, 105, 101, 115, 32, 98, 121, 32, 114, 111, 117, 110, 100, 105, 110, 103, 32, 116, 111, 32, 101, 118, 101, 110, 10, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 110, 101, 97, 114, 101, 115, 116, 95, 102, 54, 52, 32, 40, 59, 32, 49, 51, 32, 59, 41, 32, 40, 116, 121, 112, 101, 32, 36, 50, 41, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 48, 32, 102, 54, 52, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 102, 54, 52, 41, 10, 32, 32, 40, 108, 111, 99, 97, 108, 32, 36, 118, 97, 114, 36, 49, 32, 102, 54, 52, 41, 10, 32, 32, 40, 108, 111, 99, 97, 108, 32, 36, 118, 97, 114, 36, 50, 32, 102, 54, 52, 41, 10, 32, 32, 40, 105, 102, 10, 32, 32, 32, 40, 105, 51, 50, 46, 101, 113, 122, 10, 32, 32, 32, 32, 40, 102, 54, 52, 46, 108, 116, 10, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 50, 10, 32, 32, 32, 32, 32, 32, 40, 102, 54, 52, 46, 115, 117, 98, 10, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 49, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 102, 54, 52, 46, 102, 108, 111, 111, 114, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 40, 102, 54, 52, 46, 99, 111, 110, 115, 116, 32, 48, 46, 53, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 41, 10, 32, 32, 32, 40, 98, 108, 111, 99, 107, 10, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 115, 101, 116, 32, 36, 118, 97, 114, 36, 48, 10, 32, 32, 32, 32, 32, 40, 102, 54, 52, 46, 99, 101, 105, 108, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 40, 105, 102, 10, 32, 32, 32, 32, 32, 40, 102, 54, 52, 46, 103, 116, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 32, 32, 32, 40, 102, 54, 52, 46, 99, 111, 110, 115, 116, 32, 48, 46, 53, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 40, 114, 101, 116, 117, 114, 110, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 115, 101, 116, 32, 36, 118, 97, 114, 36, 49, 10, 32, 32, 32, 32, 32, 40, 115, 101, 108, 101, 99, 116, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 40, 102, 54, 52, 46, 101, 113, 10, 32, 32, 32, 32, 32, 32, 32, 40, 102, 54, 52, 46, 115, 117, 98, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 50, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 102, 54, 52, 46, 109, 117, 108, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 102, 54, 52, 46, 99, 111, 110, 115, 116, 32, 48, 46, 53, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 102, 54, 52, 46, 102, 108, 111, 111, 114, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 40, 102, 54, 52, 46, 99, 111, 110, 115, 116, 32, 48, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 41, 10, 32, 32, 41, 10, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 41, 10, 32, 40, 102, 117, 110, 99, 32, 36, 95, 90, 78, 49, 55, 99, 111, 109, 112, 105, 108, 101, 114, 95, 98, 117, 105, 108, 116, 105, 110, 115, 51, 105, 110, 116, 52, 117, 100, 105, 118, 49, 48, 100, 105, 118, 109, 111, 100, 95, 117, 54, 52, 49, 55, 104, 54, 48, 50, 54, 57, 49, 48, 98, 53, 101, 100, 48, 56, 101, 52, 48, 69, 32, 40, 59, 32, 49, 52, 32, 59, 41, 32, 40, 116, 121, 112, 101, 32, 36, 48, 41, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 48, 32, 105, 54, 52, 41, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 49, 32, 105, 54, 52, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 54, 52, 41, 10, 32, 32, 40, 108, 111, 99, 97, 108, 32, 36, 118, 97, 114, 36, 50, 32, 105, 51, 50, 41, 10, 32, 32, 40, 108, 111, 99, 97, 108, 32, 36, 118, 97, 114, 36, 51, 32, 105, 51, 50, 41, 10, 32, 32, 40, 108, 111, 99, 97, 108, 32, 36, 118, 97, 114, 36, 52, 32, 105, 51, 50, 41, 10, 32, 32, 40, 108, 111, 99, 97, 108, 32, 36, 118, 97, 114, 36, 53, 32, 105, 54, 52, 41, 10, 32, 32, 40, 108, 111, 99, 97, 108, 32, 36, 118, 97, 114, 36, 54, 32, 105, 54, 52, 41, 10, 32, 32, 40, 108, 111, 99, 97, 108, 32, 36, 118, 97, 114, 36, 55, 32, 105, 54, 52, 41, 10, 32, 32, 40, 108, 111, 99, 97, 108, 32, 36, 118, 97, 114, 36, 56, 32, 105, 54, 52, 41, 10, 32, 32, 40, 98, 108, 111, 99, 107, 32, 36, 108, 97, 98, 101, 108, 36, 49, 10, 32, 32, 32, 40, 98, 108, 111, 99, 107, 32, 36, 108, 97, 98, 101, 108, 36, 50, 10, 32, 32, 32, 32, 40, 98, 108, 111, 99, 107, 32, 36, 108, 97, 98, 101, 108, 36, 51, 10, 32, 32, 32, 32, 32, 40, 98, 108, 111, 99, 107, 32, 36, 108, 97, 98, 101, 108, 36, 52, 10, 32, 32, 32, 32, 32, 32, 40, 98, 108, 111, 99, 107, 32, 36, 108, 97, 98, 101, 108, 36, 53, 10, 32, 32, 32, 32, 32, 32, 32, 40, 98, 108, 111, 99, 107, 32, 36, 108, 97, 98, 101, 108, 36, 54, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 98, 108, 111, 99, 107, 32, 36, 108, 97, 98, 101, 108, 36, 55, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 98, 108, 111, 99, 107, 32, 36, 108, 97, 98, 101, 108, 36, 56, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 98, 108, 111, 99, 107, 32, 36, 108, 97, 98, 101, 108, 36, 57, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 98, 108, 111, 99, 107, 32, 36, 108, 97, 98, 101, 108, 36, 49, 48, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 98, 108, 111, 99, 107, 32, 36, 108, 97, 98, 101, 108, 36, 49, 49, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 102, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 50, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 119, 114, 97, 112, 95, 105, 54, 52, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 104, 114, 95, 117, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 51, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 98, 108, 111, 99, 107, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 98, 114, 95, 105, 102, 32, 36, 108, 97, 98, 101, 108, 36, 49, 49, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 101, 113, 122, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 51, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 119, 114, 97, 112, 95, 105, 54, 52, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 98, 114, 95, 105, 102, 32, 36, 108, 97, 98, 101, 108, 36, 57, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 101, 113, 122, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 52, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 119, 114, 97, 112, 95, 105, 54, 52, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 104, 114, 95, 117, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 51, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 98, 114, 95, 105, 102, 32, 36, 108, 97, 98, 101, 108, 36, 56, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 108, 101, 95, 117, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 50, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 115, 117, 98, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 108, 122, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 52, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 108, 122, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 51, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 98, 114, 32, 36, 108, 97, 98, 101, 108, 36, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 98, 114, 95, 105, 102, 32, 36, 108, 97, 98, 101, 108, 36, 50, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 103, 101, 95, 117, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 52, 50, 57, 52, 57, 54, 55, 50, 57, 54, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 103, 108, 111, 98, 97, 108, 46, 115, 101, 116, 32, 36, 95, 95, 119, 97, 115, 109, 45, 105, 110, 116, 114, 105, 110, 115, 105, 99, 115, 45, 116, 101, 109, 112, 45, 105, 54, 52, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 101, 120, 116, 101, 110, 100, 95, 105, 51, 50, 95, 117, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 115, 117, 98, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 50, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 119, 114, 97, 112, 95, 105, 54, 52, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 109, 117, 108, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 50, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 100, 105, 118, 95, 117, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 51, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 119, 114, 97, 112, 95, 105, 54, 52, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 114, 101, 116, 117, 114, 110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 101, 120, 116, 101, 110, 100, 95, 105, 51, 50, 95, 117, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 115, 101, 116, 32, 36, 118, 97, 114, 36, 51, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 119, 114, 97, 112, 95, 105, 54, 52, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 104, 114, 95, 117, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 51, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 98, 114, 95, 105, 102, 32, 36, 108, 97, 98, 101, 108, 36, 55, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 101, 113, 122, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 119, 114, 97, 112, 95, 105, 54, 52, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 98, 114, 95, 105, 102, 32, 36, 108, 97, 98, 101, 108, 36, 54, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 101, 113, 122, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 98, 114, 95, 105, 102, 32, 36, 108, 97, 98, 101, 108, 36, 54, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 52, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 100, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 45, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 103, 108, 111, 98, 97, 108, 46, 115, 101, 116, 32, 36, 95, 95, 119, 97, 115, 109, 45, 105, 110, 116, 114, 105, 110, 115, 105, 99, 115, 45, 116, 101, 109, 112, 45, 105, 54, 52, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 111, 114, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 104, 108, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 101, 120, 116, 101, 110, 100, 95, 105, 51, 50, 95, 117, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 52, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 51, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 52, 50, 57, 52, 57, 54, 55, 50, 57, 53, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 114, 101, 116, 117, 114, 110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 101, 120, 116, 101, 110, 100, 95, 105, 51, 50, 95, 117, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 115, 104, 114, 95, 117, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 116, 122, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 51, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 117, 110, 114, 101, 97, 99, 104, 97, 98, 108, 101, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 98, 114, 95, 105, 102, 32, 36, 108, 97, 98, 101, 108, 36, 53, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 101, 113, 122, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 52, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 100, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 45, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 115, 101, 116, 32, 36, 118, 97, 114, 36, 51, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 115, 117, 98, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 48, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 50, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 115, 117, 98, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 100, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 108, 122, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 51, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 108, 122, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 98, 114, 32, 36, 108, 97, 98, 101, 108, 36, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 115, 101, 116, 32, 36, 118, 97, 114, 36, 51, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 115, 117, 98, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 54, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 115, 101, 116, 32, 36, 118, 97, 114, 36, 50, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 100, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 98, 114, 32, 36, 108, 97, 98, 101, 108, 36, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 103, 108, 111, 98, 97, 108, 46, 115, 101, 116, 32, 36, 95, 95, 119, 97, 115, 109, 45, 105, 110, 116, 114, 105, 110, 115, 105, 99, 115, 45, 116, 101, 109, 112, 45, 105, 54, 52, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 104, 108, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 101, 120, 116, 101, 110, 100, 95, 105, 51, 50, 95, 117, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 115, 117, 98, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 109, 117, 108, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 52, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 100, 105, 118, 95, 117, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 51, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 114, 101, 116, 117, 114, 110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 101, 120, 116, 101, 110, 100, 95, 105, 51, 50, 95, 117, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 52, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 40, 98, 114, 95, 105, 102, 32, 36, 108, 97, 98, 101, 108, 36, 52, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 108, 116, 95, 117, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 50, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 115, 117, 98, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 108, 122, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 108, 122, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 51, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 40, 98, 114, 32, 36, 108, 97, 98, 101, 108, 36, 50, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 40, 103, 108, 111, 98, 97, 108, 46, 115, 101, 116, 32, 36, 95, 95, 119, 97, 115, 109, 45, 105, 110, 116, 114, 105, 110, 115, 105, 99, 115, 45, 116, 101, 109, 112, 45, 105, 54, 52, 10, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 101, 120, 116, 101, 110, 100, 95, 105, 51, 50, 95, 117, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 52, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 119, 114, 97, 112, 95, 105, 54, 52, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 40, 98, 114, 95, 105, 102, 32, 36, 108, 97, 98, 101, 108, 36, 49, 10, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 101, 113, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 40, 114, 101, 116, 117, 114, 110, 10, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 104, 114, 95, 117, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 101, 120, 116, 101, 110, 100, 95, 105, 51, 50, 95, 117, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 116, 122, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 115, 101, 116, 32, 36, 118, 97, 114, 36, 51, 10, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 115, 117, 98, 10, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 54, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 115, 101, 116, 32, 36, 118, 97, 114, 36, 50, 10, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 100, 100, 10, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 49, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 115, 101, 116, 32, 36, 118, 97, 114, 36, 53, 10, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 104, 114, 95, 117, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 101, 120, 116, 101, 110, 100, 95, 105, 51, 50, 95, 117, 10, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 54, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 115, 101, 116, 32, 36, 118, 97, 114, 36, 48, 10, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 104, 108, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 101, 120, 116, 101, 110, 100, 95, 105, 51, 50, 95, 117, 10, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 54, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 40, 98, 108, 111, 99, 107, 32, 36, 108, 97, 98, 101, 108, 36, 49, 51, 10, 32, 32, 32, 32, 32, 40, 105, 102, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 32, 32, 32, 40, 98, 108, 111, 99, 107, 10, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 115, 101, 116, 32, 36, 118, 97, 114, 36, 56, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 97, 100, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 45, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 111, 112, 32, 36, 108, 97, 98, 101, 108, 36, 49, 53, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 115, 101, 116, 32, 36, 118, 97, 114, 36, 53, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 117, 98, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 53, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 111, 114, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 104, 108, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 53, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 104, 114, 95, 117, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 54, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 54, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 104, 114, 95, 115, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 117, 98, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 56, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 53, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 54, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 115, 101, 116, 32, 36, 118, 97, 114, 36, 48, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 111, 114, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 104, 108, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 55, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 115, 101, 116, 32, 36, 118, 97, 114, 36, 55, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 54, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 54, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 98, 114, 95, 105, 102, 32, 36, 108, 97, 98, 101, 108, 36, 49, 53, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 50, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 100, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 45, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 40, 98, 114, 32, 36, 108, 97, 98, 101, 108, 36, 49, 51, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 40, 103, 108, 111, 98, 97, 108, 46, 115, 101, 116, 32, 36, 95, 95, 119, 97, 115, 109, 45, 105, 110, 116, 114, 105, 110, 115, 105, 99, 115, 45, 116, 101, 109, 112, 45, 105, 54, 52, 10, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 53, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 40, 114, 101, 116, 117, 114, 110, 10, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 111, 114, 10, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 104, 108, 10, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 49, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 54, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 41, 10, 32, 32, 32, 40, 103, 108, 111, 98, 97, 108, 46, 115, 101, 116, 32, 36, 95, 95, 119, 97, 115, 109, 45, 105, 110, 116, 114, 105, 110, 115, 105, 99, 115, 45, 116, 101, 109, 112, 45, 105, 54, 52, 10, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 41, 10, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 115, 101, 116, 32, 36, 118, 97, 114, 36, 48, 10, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 48, 41, 10, 32, 32, 32, 41, 10, 32, 32, 41, 10, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 41, 10, 32, 40, 102, 117, 110, 99, 32, 36, 95, 90, 78, 49, 55, 99, 111, 109, 112, 105, 108, 101, 114, 95, 98, 117, 105, 108, 116, 105, 110, 115, 51, 105, 110, 116, 51, 109, 117, 108, 51, 77, 117, 108, 51, 109, 117, 108, 49, 55, 104, 48, 55, 48, 101, 57, 97, 49, 99, 54, 57, 102, 97, 101, 99, 53, 98, 69, 32, 40, 59, 32, 49, 53, 32, 59, 41, 32, 40, 116, 121, 112, 101, 32, 36, 48, 41, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 48, 32, 105, 54, 52, 41, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 49, 32, 105, 54, 52, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 54, 52, 41, 10, 32, 32, 40, 108, 111, 99, 97, 108, 32, 36, 118, 97, 114, 36, 50, 32, 105, 51, 50, 41, 10, 32, 32, 40, 108, 111, 99, 97, 108, 32, 36, 118, 97, 114, 36, 51, 32, 105, 51, 50, 41, 10, 32, 32, 40, 108, 111, 99, 97, 108, 32, 36, 118, 97, 114, 36, 52, 32, 105, 51, 50, 41, 10, 32, 32, 40, 108, 111, 99, 97, 108, 32, 36, 118, 97, 114, 36, 53, 32, 105, 51, 50, 41, 10, 32, 32, 40, 108, 111, 99, 97, 108, 32, 36, 118, 97, 114, 36, 54, 32, 105, 51, 50, 41, 10, 32, 32, 40, 105, 54, 52, 46, 111, 114, 10, 32, 32, 32, 40, 105, 54, 52, 46, 115, 104, 108, 10, 32, 32, 32, 32, 40, 105, 54, 52, 46, 101, 120, 116, 101, 110, 100, 95, 105, 51, 50, 95, 117, 10, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 100, 100, 10, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 100, 100, 10, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 100, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 100, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 109, 117, 108, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 52, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 115, 104, 114, 95, 117, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 50, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 119, 114, 97, 112, 95, 105, 54, 52, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 49, 54, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 53, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 115, 104, 114, 95, 117, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 51, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 119, 114, 97, 112, 95, 105, 54, 52, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 49, 54, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 109, 117, 108, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 119, 114, 97, 112, 95, 105, 54, 52, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 104, 114, 95, 117, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 51, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 109, 117, 108, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 119, 114, 97, 112, 95, 105, 54, 52, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 104, 114, 95, 117, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 51, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 115, 104, 114, 95, 117, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 50, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 100, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 115, 104, 114, 95, 117, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 54, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 109, 117, 108, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 50, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 54, 53, 53, 51, 53, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 51, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 54, 53, 53, 51, 53, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 49, 54, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 109, 117, 108, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 53, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 49, 54, 41, 10, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 115, 104, 114, 95, 117, 10, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 50, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 100, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 54, 53, 53, 51, 53, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 109, 117, 108, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 52, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 49, 54, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 51, 50, 41, 10, 32, 32, 32, 41, 10, 32, 32, 32, 40, 105, 54, 52, 46, 101, 120, 116, 101, 110, 100, 95, 105, 51, 50, 95, 117, 10, 32, 32, 32, 32, 40, 105, 51, 50, 46, 111, 114, 10, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 115, 104, 108, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 49, 54, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 54, 41, 10, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 54, 53, 53, 51, 53, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 41, 10, 32, 32, 41, 10, 32, 41, 10, 32, 40, 102, 117, 110, 99, 32, 36, 95, 90, 78, 49, 55, 99, 111, 109, 112, 105, 108, 101, 114, 95, 98, 117, 105, 108, 116, 105, 110, 115, 51, 105, 110, 116, 52, 115, 100, 105, 118, 51, 68, 105, 118, 51, 100, 105, 118, 49, 55, 104, 101, 55, 56, 102, 99, 52, 56, 51, 101, 52, 49, 100, 55, 101, 99, 55, 69, 32, 40, 59, 32, 49, 54, 32, 59, 41, 32, 40, 116, 121, 112, 101, 32, 36, 48, 41, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 48, 32, 105, 54, 52, 41, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 49, 32, 105, 54, 52, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 54, 52, 41, 10, 32, 32, 40, 108, 111, 99, 97, 108, 32, 36, 118, 97, 114, 36, 50, 32, 105, 54, 52, 41, 10, 32, 32, 40, 105, 54, 52, 46, 115, 117, 98, 10, 32, 32, 32, 40, 105, 54, 52, 46, 120, 111, 114, 10, 32, 32, 32, 32, 40, 105, 54, 52, 46, 100, 105, 118, 95, 117, 10, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 117, 98, 10, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 120, 111, 114, 10, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 50, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 104, 114, 95, 115, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 54, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 117, 98, 10, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 120, 111, 114, 10, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 50, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 104, 114, 95, 115, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 54, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 48, 10, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 104, 114, 95, 115, 10, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 120, 111, 114, 10, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 54, 51, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 41, 10, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 41, 10, 32, 41, 10, 32, 40, 102, 117, 110, 99, 32, 36, 95, 90, 78, 49, 55, 99, 111, 109, 112, 105, 108, 101, 114, 95, 98, 117, 105, 108, 116, 105, 110, 115, 51, 105, 110, 116, 52, 115, 100, 105, 118, 51, 77, 111, 100, 52, 109, 111, 100, 95, 49, 55, 104, 50, 99, 98, 98, 55, 98, 98, 102, 51, 54, 101, 52, 49, 100, 54, 56, 69, 32, 40, 59, 32, 49, 55, 32, 59, 41, 32, 40, 116, 121, 112, 101, 32, 36, 48, 41, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 48, 32, 105, 54, 52, 41, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 49, 32, 105, 54, 52, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 54, 52, 41, 10, 32, 32, 40, 108, 111, 99, 97, 108, 32, 36, 118, 97, 114, 36, 50, 32, 105, 54, 52, 41, 10, 32, 32, 40, 105, 54, 52, 46, 115, 117, 98, 10, 32, 32, 32, 40, 105, 54, 52, 46, 120, 111, 114, 10, 32, 32, 32, 32, 40, 105, 54, 52, 46, 114, 101, 109, 95, 117, 10, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 117, 98, 10, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 120, 111, 114, 10, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 50, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 104, 114, 95, 115, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 54, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 117, 98, 10, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 120, 111, 114, 10, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 48, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 104, 114, 95, 115, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 54, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 41, 10, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 41, 10, 32, 41, 10, 32, 59, 59, 32, 99, 117, 115, 116, 111, 109, 32, 115, 101, 99, 116, 105, 111, 110, 32, 34, 108, 105, 110, 107, 105, 110, 103, 34, 44, 32, 115, 105, 122, 101, 32, 51, 10, 41, 10, 0+static const char theModule[23513] = {+59, 59, 32, 65, 32, 108, 97, 114, 103, 101, 32, 87, 65, 83, 84, 32, 98, 108, 111, 98, 32, 119, 104, 105, 99, 104, 32, 99, 111, 110, 116, 97, 105, 110, 115, 32, 116, 104, 101, 32, 105, 109, 112, 108, 101, 109, 101, 110, 116, 97, 116, 105, 111, 110, 115, 32, 111, 102, 32, 97, 108, 108, 32, 116, 104, 101, 32, 105, 110, 116, 114, 105, 110, 115, 105, 99, 115, 10, 59, 59, 32, 116, 104, 97, 116, 32, 119, 101, 32, 105, 110, 106, 101, 99, 116, 32, 97, 115, 32, 112, 97, 114, 116, 32, 111, 102, 32, 116, 104, 105, 115, 32, 109, 111, 100, 117, 108, 101, 46, 32, 84, 104, 105, 115, 32, 98, 108, 111, 98, 32, 119, 97, 115, 32, 103, 101, 110, 101, 114, 97, 116, 101, 100, 32, 102, 114, 111, 109, 32, 97, 32, 82, 117, 115, 116, 10, 59, 59, 32, 112, 114, 111, 103, 114, 97, 109, 32, 91, 49, 93, 32, 119, 104, 105, 99, 104, 32, 117, 115, 101, 115, 32, 116, 104, 101, 32, 82, 117, 115, 116, 32, 99, 111, 109, 112, 105, 108, 101, 114, 45, 98, 117, 105, 108, 116, 105, 110, 115, 32, 112, 114, 111, 106, 101, 99, 116, 46, 32, 73, 116, 39, 115, 32, 110, 111, 116, 10, 59, 59, 32, 110, 101, 99, 101, 115, 115, 97, 114, 105, 108, 121, 32, 112, 101, 114, 102, 101, 99, 116, 32, 98, 117, 116, 32, 103, 101, 116, 115, 32, 116, 104, 101, 32, 106, 111, 98, 32, 100, 111, 110, 101, 33, 32, 84, 104, 101, 32, 105, 100, 101, 97, 32, 104, 101, 114, 101, 32, 105, 115, 32, 116, 104, 97, 116, 32, 119, 101, 32, 105, 110, 106, 101, 99, 116, 10, 59, 59, 32, 116, 104, 101, 115, 101, 32, 112, 114, 101, 116, 116, 121, 32, 101, 97, 114, 108, 121, 32, 115, 111, 32, 116, 104, 101, 121, 32, 99, 97, 110, 32, 99, 111, 110, 116, 105, 110, 117, 101, 32, 116, 111, 32, 98, 101, 32, 111, 112, 116, 105, 109, 105, 122, 101, 100, 32, 98, 121, 32, 102, 117, 114, 116, 104, 101, 114, 32, 112, 97, 115, 115, 101, 115, 10, 59, 59, 32, 40, 97, 107, 97, 32, 105, 110, 108, 105, 110, 105, 110, 103, 32, 97, 110, 100, 32, 119, 104, 97, 116, 110, 111, 116, 41, 10, 59, 59, 10, 59, 59, 32, 76, 79, 67, 65, 76, 32, 77, 79, 68, 83, 32, 100, 111, 110, 101, 32, 98, 121, 32, 104, 97, 110, 100, 32, 97, 102, 116, 101, 114, 119, 97, 114, 100, 115, 58, 10, 59, 59, 32, 32, 42, 32, 82, 101, 109, 111, 118, 101, 32, 104, 97, 114, 100, 99, 111, 100, 101, 100, 32, 97, 100, 100, 114, 101, 115, 115, 32, 49, 48, 50, 52, 32, 119, 104, 105, 99, 104, 32, 119, 97, 115, 32, 117, 115, 101, 100, 32, 102, 111, 114, 32, 116, 101, 109, 112, 111, 114, 97, 114, 121, 32, 100, 97, 116, 97, 59, 32, 105, 110, 115, 116, 101, 97, 100, 10, 59, 59, 32, 32, 32, 32, 97, 100, 100, 32, 36, 119, 97, 115, 109, 45, 105, 110, 116, 114, 105, 110, 115, 105, 99, 115, 45, 116, 101, 109, 112, 45, 105, 54, 52, 32, 103, 108, 111, 98, 97, 108, 32, 102, 111, 114, 32, 116, 104, 97, 116, 46, 10, 59, 59, 32, 32, 42, 32, 70, 105, 120, 32, 102, 117, 110, 99, 116, 105, 111, 110, 32, 116, 121, 112, 101, 32, 111, 102, 32, 95, 95, 119, 97, 115, 109, 95, 99, 116, 122, 95, 105, 54, 52, 44, 32, 119, 104, 105, 99, 104, 32, 119, 97, 115, 32, 119, 114, 111, 110, 103, 32, 115, 111, 109, 101, 104, 111, 119, 44, 10, 59, 59, 32, 32, 32, 32, 105, 51, 50, 44, 32, 105, 51, 50, 32, 61, 62, 32, 105, 51, 50, 32, 105, 110, 115, 116, 101, 97, 100, 32, 111, 102, 32, 105, 54, 52, 32, 61, 62, 32, 105, 54, 52, 10, 59, 59, 32, 32, 42, 32, 82, 101, 109, 111, 118, 101, 32, 117, 110, 110, 101, 99, 101, 115, 115, 97, 114, 121, 32, 109, 101, 109, 111, 114, 121, 32, 105, 109, 112, 111, 114, 116, 46, 10, 59, 59, 10, 59, 59, 32, 91, 49, 93, 58, 32, 104, 116, 116, 112, 115, 58, 47, 47, 103, 105, 115, 116, 46, 103, 105, 116, 104, 117, 98, 46, 99, 111, 109, 47, 97, 108, 101, 120, 99, 114, 105, 99, 104, 116, 111, 110, 47, 101, 55, 101, 97, 54, 55, 98, 99, 100, 100, 49, 55, 99, 101, 52, 98, 54, 50, 53, 52, 101, 54, 54, 102, 55, 55, 49, 54, 53, 54, 57, 48, 10, 10, 40, 109, 111, 100, 117, 108, 101, 10, 32, 40, 116, 121, 112, 101, 32, 36, 48, 32, 40, 102, 117, 110, 99, 32, 40, 112, 97, 114, 97, 109, 32, 105, 54, 52, 32, 105, 54, 52, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 54, 52, 41, 41, 41, 10, 32, 40, 116, 121, 112, 101, 32, 36, 49, 32, 40, 102, 117, 110, 99, 32, 40, 112, 97, 114, 97, 109, 32, 102, 51, 50, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 102, 51, 50, 41, 41, 41, 10, 32, 40, 116, 121, 112, 101, 32, 36, 50, 32, 40, 102, 117, 110, 99, 32, 40, 112, 97, 114, 97, 109, 32, 102, 54, 52, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 102, 54, 52, 41, 41, 41, 10, 32, 40, 116, 121, 112, 101, 32, 36, 51, 32, 40, 102, 117, 110, 99, 32, 40, 112, 97, 114, 97, 109, 32, 105, 51, 50, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 41, 41, 10, 32, 40, 116, 121, 112, 101, 32, 36, 52, 32, 40, 102, 117, 110, 99, 32, 40, 112, 97, 114, 97, 109, 32, 105, 51, 50, 32, 105, 51, 50, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 41, 41, 10, 32, 40, 116, 121, 112, 101, 32, 36, 53, 32, 40, 102, 117, 110, 99, 32, 40, 112, 97, 114, 97, 109, 32, 105, 54, 52, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 54, 52, 41, 41, 41, 10, 32, 40, 101, 120, 112, 111, 114, 116, 32, 34, 95, 95, 119, 97, 115, 109, 95, 105, 54, 52, 95, 115, 100, 105, 118, 34, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 105, 54, 52, 95, 115, 100, 105, 118, 41, 41, 10, 32, 40, 101, 120, 112, 111, 114, 116, 32, 34, 95, 95, 119, 97, 115, 109, 95, 105, 54, 52, 95, 117, 100, 105, 118, 34, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 105, 54, 52, 95, 117, 100, 105, 118, 41, 41, 10, 32, 40, 101, 120, 112, 111, 114, 116, 32, 34, 95, 95, 119, 97, 115, 109, 95, 105, 54, 52, 95, 115, 114, 101, 109, 34, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 105, 54, 52, 95, 115, 114, 101, 109, 41, 41, 10, 32, 40, 101, 120, 112, 111, 114, 116, 32, 34, 95, 95, 119, 97, 115, 109, 95, 105, 54, 52, 95, 117, 114, 101, 109, 34, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 105, 54, 52, 95, 117, 114, 101, 109, 41, 41, 10, 32, 40, 101, 120, 112, 111, 114, 116, 32, 34, 95, 95, 119, 97, 115, 109, 95, 105, 54, 52, 95, 109, 117, 108, 34, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 105, 54, 52, 95, 109, 117, 108, 41, 41, 10, 32, 40, 101, 120, 112, 111, 114, 116, 32, 34, 95, 95, 119, 97, 115, 109, 95, 99, 116, 122, 95, 105, 51, 50, 34, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 99, 116, 122, 95, 105, 51, 50, 41, 41, 10, 32, 40, 101, 120, 112, 111, 114, 116, 32, 34, 95, 95, 119, 97, 115, 109, 95, 99, 116, 122, 95, 105, 54, 52, 34, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 99, 116, 122, 95, 105, 54, 52, 41, 41, 10, 32, 40, 101, 120, 112, 111, 114, 116, 32, 34, 95, 95, 119, 97, 115, 109, 95, 114, 111, 116, 108, 95, 105, 51, 50, 34, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 114, 111, 116, 108, 95, 105, 51, 50, 41, 41, 10, 32, 40, 101, 120, 112, 111, 114, 116, 32, 34, 95, 95, 119, 97, 115, 109, 95, 114, 111, 116, 114, 95, 105, 51, 50, 34, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 114, 111, 116, 114, 95, 105, 51, 50, 41, 41, 10, 32, 40, 101, 120, 112, 111, 114, 116, 32, 34, 95, 95, 119, 97, 115, 109, 95, 114, 111, 116, 108, 95, 105, 54, 52, 34, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 114, 111, 116, 108, 95, 105, 54, 52, 41, 41, 10, 32, 40, 101, 120, 112, 111, 114, 116, 32, 34, 95, 95, 119, 97, 115, 109, 95, 114, 111, 116, 114, 95, 105, 54, 52, 34, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 114, 111, 116, 114, 95, 105, 54, 52, 41, 41, 10, 32, 40, 101, 120, 112, 111, 114, 116, 32, 34, 95, 95, 119, 97, 115, 109, 95, 110, 101, 97, 114, 101, 115, 116, 95, 102, 51, 50, 34, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 110, 101, 97, 114, 101, 115, 116, 95, 102, 51, 50, 41, 41, 10, 32, 40, 101, 120, 112, 111, 114, 116, 32, 34, 95, 95, 119, 97, 115, 109, 95, 110, 101, 97, 114, 101, 115, 116, 95, 102, 54, 52, 34, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 110, 101, 97, 114, 101, 115, 116, 95, 102, 54, 52, 41, 41, 10, 32, 40, 101, 120, 112, 111, 114, 116, 32, 34, 95, 95, 119, 97, 115, 109, 95, 112, 111, 112, 99, 110, 116, 95, 105, 51, 50, 34, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 112, 111, 112, 99, 110, 116, 95, 105, 51, 50, 41, 41, 10, 32, 40, 101, 120, 112, 111, 114, 116, 32, 34, 95, 95, 119, 97, 115, 109, 95, 112, 111, 112, 99, 110, 116, 95, 105, 54, 52, 34, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 112, 111, 112, 99, 110, 116, 95, 105, 54, 52, 41, 41, 10, 32, 40, 103, 108, 111, 98, 97, 108, 32, 36, 95, 95, 119, 97, 115, 109, 45, 105, 110, 116, 114, 105, 110, 115, 105, 99, 115, 45, 116, 101, 109, 112, 45, 105, 54, 52, 32, 40, 109, 117, 116, 32, 105, 54, 52, 41, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 48, 41, 41, 10, 10, 32, 59, 59, 32, 108, 111, 119, 101, 114, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 105, 51, 50, 46, 112, 111, 112, 99, 110, 116, 32, 105, 110, 115, 116, 114, 117, 99, 116, 105, 111, 110, 44, 32, 99, 111, 117, 110, 116, 115, 32, 116, 104, 101, 32, 110, 117, 109, 98, 101, 114, 32, 111, 102, 32, 98, 105, 116, 115, 32, 115, 101, 116, 32, 105, 110, 32, 116, 104, 101, 10, 32, 59, 59, 32, 105, 110, 112, 117, 116, 32, 97, 110, 100, 32, 114, 101, 116, 117, 114, 110, 115, 32, 116, 104, 101, 32, 114, 101, 115, 117, 108, 116, 10, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 112, 111, 112, 99, 110, 116, 95, 105, 51, 50, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 48, 32, 105, 51, 50, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 10, 32, 32, 40, 108, 111, 99, 97, 108, 32, 36, 118, 97, 114, 36, 49, 32, 105, 51, 50, 41, 10, 32, 32, 40, 98, 108, 111, 99, 107, 32, 36, 108, 97, 98, 101, 108, 36, 49, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 10, 32, 32, 32, 40, 108, 111, 111, 112, 32, 36, 108, 97, 98, 101, 108, 36, 50, 10, 32, 32, 32, 32, 40, 100, 114, 111, 112, 10, 32, 32, 32, 32, 32, 40, 98, 114, 95, 105, 102, 32, 36, 108, 97, 98, 101, 108, 36, 49, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 101, 113, 122, 10, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 115, 101, 116, 32, 36, 118, 97, 114, 36, 48, 10, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 115, 117, 98, 10, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 49, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 115, 101, 116, 32, 36, 118, 97, 114, 36, 49, 10, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 100, 100, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 49, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 40, 98, 114, 32, 36, 108, 97, 98, 101, 108, 36, 50, 41, 10, 32, 32, 32, 41, 10, 32, 32, 41, 10, 32, 41, 10, 32, 59, 59, 32, 108, 111, 119, 101, 114, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 105, 54, 52, 46, 112, 111, 112, 99, 110, 116, 32, 105, 110, 115, 116, 114, 117, 99, 116, 105, 111, 110, 44, 32, 99, 111, 117, 110, 116, 115, 32, 116, 104, 101, 32, 110, 117, 109, 98, 101, 114, 32, 111, 102, 32, 98, 105, 116, 115, 32, 115, 101, 116, 32, 105, 110, 32, 116, 104, 101, 10, 32, 59, 59, 32, 105, 110, 112, 117, 116, 32, 97, 110, 100, 32, 114, 101, 116, 117, 114, 110, 115, 32, 116, 104, 101, 32, 114, 101, 115, 117, 108, 116, 10, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 112, 111, 112, 99, 110, 116, 95, 105, 54, 52, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 48, 32, 105, 54, 52, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 54, 52, 41, 10, 32, 32, 40, 108, 111, 99, 97, 108, 32, 36, 118, 97, 114, 36, 49, 32, 105, 54, 52, 41, 10, 32, 32, 40, 98, 108, 111, 99, 107, 32, 36, 108, 97, 98, 101, 108, 36, 49, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 54, 52, 41, 10, 32, 32, 32, 40, 108, 111, 111, 112, 32, 36, 108, 97, 98, 101, 108, 36, 50, 10, 32, 32, 32, 32, 40, 100, 114, 111, 112, 10, 32, 32, 32, 32, 32, 40, 98, 114, 95, 105, 102, 32, 36, 108, 97, 98, 101, 108, 36, 49, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 101, 113, 122, 10, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 115, 101, 116, 32, 36, 118, 97, 114, 36, 48, 10, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 117, 98, 10, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 49, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 115, 101, 116, 32, 36, 118, 97, 114, 36, 49, 10, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 97, 100, 100, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 49, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 40, 98, 114, 32, 36, 108, 97, 98, 101, 108, 36, 50, 41, 10, 32, 32, 32, 41, 10, 32, 32, 41, 10, 32, 41, 10, 32, 59, 59, 32, 108, 111, 119, 101, 114, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 105, 54, 52, 46, 100, 105, 118, 95, 115, 32, 105, 110, 115, 116, 114, 117, 99, 116, 105, 111, 110, 44, 32, 114, 101, 116, 117, 114, 110, 32, 36, 118, 97, 114, 48, 32, 47, 32, 36, 118, 97, 114, 36, 49, 10, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 105, 54, 52, 95, 115, 100, 105, 118, 32, 40, 59, 32, 48, 32, 59, 41, 32, 40, 116, 121, 112, 101, 32, 36, 48, 41, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 48, 32, 105, 54, 52, 41, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 49, 32, 105, 54, 52, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 54, 52, 41, 10, 32, 32, 40, 99, 97, 108, 108, 32, 36, 95, 90, 78, 49, 55, 99, 111, 109, 112, 105, 108, 101, 114, 95, 98, 117, 105, 108, 116, 105, 110, 115, 51, 105, 110, 116, 52, 115, 100, 105, 118, 51, 68, 105, 118, 51, 100, 105, 118, 49, 55, 104, 101, 55, 56, 102, 99, 52, 56, 51, 101, 52, 49, 100, 55, 101, 99, 55, 69, 10, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 41, 10, 32, 41, 10, 32, 59, 59, 32, 108, 111, 119, 101, 114, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 105, 54, 52, 46, 100, 105, 118, 95, 117, 32, 105, 110, 115, 116, 114, 117, 99, 116, 105, 111, 110, 44, 32, 114, 101, 116, 117, 114, 110, 32, 36, 118, 97, 114, 48, 32, 47, 32, 36, 118, 97, 114, 36, 49, 10, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 105, 54, 52, 95, 117, 100, 105, 118, 32, 40, 59, 32, 49, 32, 59, 41, 32, 40, 116, 121, 112, 101, 32, 36, 48, 41, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 48, 32, 105, 54, 52, 41, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 49, 32, 105, 54, 52, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 54, 52, 41, 10, 32, 32, 40, 99, 97, 108, 108, 32, 36, 95, 90, 78, 49, 55, 99, 111, 109, 112, 105, 108, 101, 114, 95, 98, 117, 105, 108, 116, 105, 110, 115, 51, 105, 110, 116, 52, 117, 100, 105, 118, 49, 48, 100, 105, 118, 109, 111, 100, 95, 117, 54, 52, 49, 55, 104, 54, 48, 50, 54, 57, 49, 48, 98, 53, 101, 100, 48, 56, 101, 52, 48, 69, 10, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 41, 10, 32, 41, 10, 32, 59, 59, 32, 108, 111, 119, 101, 114, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 105, 54, 52, 46, 114, 101, 109, 95, 115, 32, 105, 110, 115, 116, 114, 117, 99, 116, 105, 111, 110, 44, 32, 114, 101, 116, 117, 114, 110, 32, 36, 118, 97, 114, 48, 32, 37, 32, 36, 118, 97, 114, 36, 49, 10, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 105, 54, 52, 95, 115, 114, 101, 109, 32, 40, 59, 32, 50, 32, 59, 41, 32, 40, 116, 121, 112, 101, 32, 36, 48, 41, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 48, 32, 105, 54, 52, 41, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 49, 32, 105, 54, 52, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 54, 52, 41, 10, 32, 32, 40, 99, 97, 108, 108, 32, 36, 95, 90, 78, 49, 55, 99, 111, 109, 112, 105, 108, 101, 114, 95, 98, 117, 105, 108, 116, 105, 110, 115, 51, 105, 110, 116, 52, 115, 100, 105, 118, 51, 77, 111, 100, 52, 109, 111, 100, 95, 49, 55, 104, 50, 99, 98, 98, 55, 98, 98, 102, 51, 54, 101, 52, 49, 100, 54, 56, 69, 10, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 41, 10, 32, 41, 10, 32, 59, 59, 32, 108, 111, 119, 101, 114, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 105, 54, 52, 46, 114, 101, 109, 95, 117, 32, 105, 110, 115, 116, 114, 117, 99, 116, 105, 111, 110, 44, 32, 114, 101, 116, 117, 114, 110, 32, 36, 118, 97, 114, 48, 32, 37, 32, 36, 118, 97, 114, 36, 49, 10, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 105, 54, 52, 95, 117, 114, 101, 109, 32, 40, 59, 32, 51, 32, 59, 41, 32, 40, 116, 121, 112, 101, 32, 36, 48, 41, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 48, 32, 105, 54, 52, 41, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 49, 32, 105, 54, 52, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 54, 52, 41, 10, 32, 32, 40, 100, 114, 111, 112, 10, 32, 32, 32, 40, 99, 97, 108, 108, 32, 36, 95, 90, 78, 49, 55, 99, 111, 109, 112, 105, 108, 101, 114, 95, 98, 117, 105, 108, 116, 105, 110, 115, 51, 105, 110, 116, 52, 117, 100, 105, 118, 49, 48, 100, 105, 118, 109, 111, 100, 95, 117, 54, 52, 49, 55, 104, 54, 48, 50, 54, 57, 49, 48, 98, 53, 101, 100, 48, 56, 101, 52, 48, 69, 10, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 41, 10, 32, 32, 41, 10, 32, 32, 40, 103, 108, 111, 98, 97, 108, 46, 103, 101, 116, 32, 36, 95, 95, 119, 97, 115, 109, 45, 105, 110, 116, 114, 105, 110, 115, 105, 99, 115, 45, 116, 101, 109, 112, 45, 105, 54, 52, 41, 10, 32, 41, 10, 32, 59, 59, 32, 108, 111, 119, 101, 114, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 105, 54, 52, 46, 109, 117, 108, 32, 105, 110, 115, 116, 114, 117, 99, 116, 105, 111, 110, 44, 32, 114, 101, 116, 117, 114, 110, 32, 36, 118, 97, 114, 48, 32, 42, 32, 36, 118, 97, 114, 36, 49, 10, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 105, 54, 52, 95, 109, 117, 108, 32, 40, 59, 32, 52, 32, 59, 41, 32, 40, 116, 121, 112, 101, 32, 36, 48, 41, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 48, 32, 105, 54, 52, 41, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 49, 32, 105, 54, 52, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 54, 52, 41, 10, 32, 32, 40, 99, 97, 108, 108, 32, 36, 95, 90, 78, 49, 55, 99, 111, 109, 112, 105, 108, 101, 114, 95, 98, 117, 105, 108, 116, 105, 110, 115, 51, 105, 110, 116, 51, 109, 117, 108, 51, 77, 117, 108, 51, 109, 117, 108, 49, 55, 104, 48, 55, 48, 101, 57, 97, 49, 99, 54, 57, 102, 97, 101, 99, 53, 98, 69, 10, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 41, 10, 32, 41, 10, 32, 59, 59, 32, 108, 111, 119, 101, 114, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 105, 51, 50, 46, 99, 116, 122, 32, 105, 110, 115, 116, 114, 117, 99, 116, 105, 111, 110, 44, 32, 99, 111, 117, 110, 116, 105, 110, 103, 32, 116, 104, 101, 32, 110, 117, 109, 98, 101, 114, 32, 111, 102, 32, 122, 101, 114, 111, 115, 32, 105, 110, 32, 36, 118, 97, 114, 36, 48, 10, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 99, 116, 122, 95, 105, 51, 50, 32, 40, 59, 32, 55, 32, 59, 41, 32, 40, 116, 121, 112, 101, 32, 36, 51, 41, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 48, 32, 105, 51, 50, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 10, 32, 32, 40, 105, 102, 10, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 40, 114, 101, 116, 117, 114, 110, 10, 32, 32, 32, 32, 40, 105, 51, 50, 46, 115, 117, 98, 10, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 51, 49, 41, 10, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 108, 122, 10, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 120, 111, 114, 10, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 100, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 45, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 41, 10, 32, 32, 41, 10, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 51, 50, 41, 10, 32, 41, 10, 32, 59, 59, 32, 108, 111, 119, 101, 114, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 105, 54, 52, 46, 99, 116, 122, 32, 105, 110, 115, 116, 114, 117, 99, 116, 105, 111, 110, 44, 32, 99, 111, 117, 110, 116, 105, 110, 103, 32, 116, 104, 101, 32, 110, 117, 109, 98, 101, 114, 32, 111, 102, 32, 122, 101, 114, 111, 115, 32, 105, 110, 32, 36, 118, 97, 114, 36, 48, 10, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 99, 116, 122, 95, 105, 54, 52, 32, 40, 59, 32, 56, 32, 59, 41, 32, 40, 116, 121, 112, 101, 32, 36, 53, 41, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 48, 32, 105, 54, 52, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 54, 52, 41, 10, 32, 32, 40, 105, 102, 10, 32, 32, 32, 40, 105, 51, 50, 46, 101, 113, 122, 10, 32, 32, 32, 32, 40, 105, 54, 52, 46, 101, 113, 122, 10, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 41, 10, 32, 32, 32, 40, 114, 101, 116, 117, 114, 110, 10, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 117, 98, 10, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 54, 51, 41, 10, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 108, 122, 10, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 120, 111, 114, 10, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 97, 100, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 45, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 41, 10, 32, 32, 41, 10, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 54, 52, 41, 10, 32, 41, 10, 32, 59, 59, 32, 108, 111, 119, 101, 114, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 105, 51, 50, 46, 114, 111, 116, 108, 32, 105, 110, 115, 116, 114, 117, 99, 116, 105, 111, 110, 44, 32, 114, 111, 116, 97, 116, 105, 110, 103, 32, 116, 104, 101, 32, 102, 105, 114, 115, 116, 32, 97, 114, 103, 117, 109, 101, 110, 116, 44, 32, 119, 105, 116, 104, 10, 32, 59, 59, 32, 119, 114, 97, 112, 97, 114, 111, 117, 110, 100, 44, 32, 98, 121, 32, 116, 104, 101, 32, 115, 101, 99, 111, 110, 100, 32, 97, 114, 103, 117, 109, 101, 110, 116, 10, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 114, 111, 116, 108, 95, 105, 51, 50, 32, 40, 59, 32, 56, 32, 59, 41, 32, 40, 116, 121, 112, 101, 32, 36, 52, 41, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 48, 32, 105, 51, 50, 41, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 49, 32, 105, 51, 50, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 10, 32, 32, 40, 108, 111, 99, 97, 108, 32, 36, 118, 97, 114, 36, 50, 32, 105, 51, 50, 41, 10, 32, 32, 40, 105, 51, 50, 46, 111, 114, 10, 32, 32, 32, 40, 105, 51, 50, 46, 115, 104, 108, 10, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 115, 104, 114, 95, 117, 10, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 45, 49, 41, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 50, 10, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 51, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 41, 10, 32, 32, 32, 40, 105, 51, 50, 46, 115, 104, 114, 95, 117, 10, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 115, 104, 108, 10, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 45, 49, 41, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 49, 10, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 115, 117, 98, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 48, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 51, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 41, 10, 32, 32, 41, 10, 32, 41, 10, 32, 59, 59, 32, 108, 111, 119, 101, 114, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 105, 51, 50, 46, 114, 111, 116, 114, 32, 105, 110, 115, 116, 114, 117, 99, 116, 105, 111, 110, 44, 32, 114, 111, 116, 97, 116, 105, 110, 103, 32, 116, 104, 101, 32, 102, 105, 114, 115, 116, 32, 97, 114, 103, 117, 109, 101, 110, 116, 44, 32, 119, 105, 116, 104, 10, 32, 59, 59, 32, 119, 114, 97, 112, 97, 114, 111, 117, 110, 100, 44, 32, 98, 121, 32, 116, 104, 101, 32, 115, 101, 99, 111, 110, 100, 32, 97, 114, 103, 117, 109, 101, 110, 116, 10, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 114, 111, 116, 114, 95, 105, 51, 50, 32, 40, 59, 32, 57, 32, 59, 41, 32, 40, 116, 121, 112, 101, 32, 36, 52, 41, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 48, 32, 105, 51, 50, 41, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 49, 32, 105, 51, 50, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 51, 50, 41, 10, 32, 32, 40, 108, 111, 99, 97, 108, 32, 36, 118, 97, 114, 36, 50, 32, 105, 51, 50, 41, 10, 32, 32, 40, 105, 51, 50, 46, 111, 114, 10, 32, 32, 32, 40, 105, 51, 50, 46, 115, 104, 114, 95, 117, 10, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 115, 104, 108, 10, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 45, 49, 41, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 50, 10, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 51, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 41, 10, 32, 32, 32, 40, 105, 51, 50, 46, 115, 104, 108, 10, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 115, 104, 114, 95, 117, 10, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 45, 49, 41, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 49, 10, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 115, 117, 98, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 48, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 51, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 41, 10, 32, 32, 41, 10, 32, 41, 10, 32, 59, 59, 32, 108, 111, 119, 101, 114, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 105, 54, 52, 46, 114, 111, 116, 108, 32, 105, 110, 115, 116, 114, 117, 99, 116, 105, 111, 110, 44, 32, 114, 111, 116, 97, 116, 105, 110, 103, 32, 116, 104, 101, 32, 102, 105, 114, 115, 116, 32, 97, 114, 103, 117, 109, 101, 110, 116, 44, 32, 119, 105, 116, 104, 10, 32, 59, 59, 32, 119, 114, 97, 112, 97, 114, 111, 117, 110, 100, 44, 32, 98, 121, 32, 116, 104, 101, 32, 115, 101, 99, 111, 110, 100, 32, 97, 114, 103, 117, 109, 101, 110, 116, 10, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 114, 111, 116, 108, 95, 105, 54, 52, 32, 40, 59, 32, 49, 48, 32, 59, 41, 32, 40, 116, 121, 112, 101, 32, 36, 48, 41, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 48, 32, 105, 54, 52, 41, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 49, 32, 105, 54, 52, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 54, 52, 41, 10, 32, 32, 40, 108, 111, 99, 97, 108, 32, 36, 118, 97, 114, 36, 50, 32, 105, 54, 52, 41, 10, 32, 32, 40, 105, 54, 52, 46, 111, 114, 10, 32, 32, 32, 40, 105, 54, 52, 46, 115, 104, 108, 10, 32, 32, 32, 32, 40, 105, 54, 52, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 104, 114, 95, 117, 10, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 45, 49, 41, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 50, 10, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 54, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 41, 10, 32, 32, 32, 40, 105, 54, 52, 46, 115, 104, 114, 95, 117, 10, 32, 32, 32, 32, 40, 105, 54, 52, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 104, 108, 10, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 45, 49, 41, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 49, 10, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 117, 98, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 48, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 54, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 41, 10, 32, 32, 41, 10, 32, 41, 10, 32, 59, 59, 32, 108, 111, 119, 101, 114, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 105, 54, 52, 46, 114, 111, 116, 114, 32, 105, 110, 115, 116, 114, 117, 99, 116, 105, 111, 110, 44, 32, 114, 111, 116, 97, 116, 105, 110, 103, 32, 116, 104, 101, 32, 102, 105, 114, 115, 116, 32, 97, 114, 103, 117, 109, 101, 110, 116, 44, 32, 119, 105, 116, 104, 10, 32, 59, 59, 32, 119, 114, 97, 112, 97, 114, 111, 117, 110, 100, 44, 32, 98, 121, 32, 116, 104, 101, 32, 115, 101, 99, 111, 110, 100, 32, 97, 114, 103, 117, 109, 101, 110, 116, 10, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 114, 111, 116, 114, 95, 105, 54, 52, 32, 40, 59, 32, 49, 49, 32, 59, 41, 32, 40, 116, 121, 112, 101, 32, 36, 48, 41, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 48, 32, 105, 54, 52, 41, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 49, 32, 105, 54, 52, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 54, 52, 41, 10, 32, 32, 40, 108, 111, 99, 97, 108, 32, 36, 118, 97, 114, 36, 50, 32, 105, 54, 52, 41, 10, 32, 32, 40, 105, 54, 52, 46, 111, 114, 10, 32, 32, 32, 40, 105, 54, 52, 46, 115, 104, 114, 95, 117, 10, 32, 32, 32, 32, 40, 105, 54, 52, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 104, 108, 10, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 45, 49, 41, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 50, 10, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 54, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 41, 10, 32, 32, 32, 40, 105, 54, 52, 46, 115, 104, 108, 10, 32, 32, 32, 32, 40, 105, 54, 52, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 104, 114, 95, 117, 10, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 45, 49, 41, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 49, 10, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 117, 98, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 48, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 54, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 41, 10, 32, 32, 41, 10, 32, 41, 10, 32, 59, 59, 32, 108, 111, 119, 101, 114, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 102, 51, 50, 46, 110, 101, 97, 114, 101, 115, 116, 32, 105, 110, 115, 116, 114, 117, 99, 116, 105, 111, 110, 44, 32, 114, 111, 117, 110, 100, 105, 110, 103, 32, 116, 104, 101, 32, 105, 110, 112, 117, 116, 32, 116, 111, 32, 116, 104, 101, 32, 110, 101, 97, 114, 101, 115, 116, 10, 32, 59, 59, 32, 105, 110, 116, 101, 103, 101, 114, 32, 119, 104, 105, 108, 101, 32, 98, 114, 101, 97, 107, 105, 110, 103, 32, 116, 105, 101, 115, 32, 98, 121, 32, 114, 111, 117, 110, 100, 105, 110, 103, 32, 116, 111, 32, 101, 118, 101, 110, 10, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 110, 101, 97, 114, 101, 115, 116, 95, 102, 51, 50, 32, 40, 59, 32, 49, 50, 32, 59, 41, 32, 40, 116, 121, 112, 101, 32, 36, 49, 41, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 48, 32, 102, 51, 50, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 102, 51, 50, 41, 10, 32, 32, 40, 108, 111, 99, 97, 108, 32, 36, 118, 97, 114, 36, 49, 32, 102, 51, 50, 41, 10, 32, 32, 40, 108, 111, 99, 97, 108, 32, 36, 118, 97, 114, 36, 50, 32, 102, 51, 50, 41, 10, 32, 32, 40, 105, 102, 10, 32, 32, 32, 40, 105, 51, 50, 46, 101, 113, 122, 10, 32, 32, 32, 32, 40, 102, 51, 50, 46, 108, 116, 10, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 50, 10, 32, 32, 32, 32, 32, 32, 40, 102, 51, 50, 46, 115, 117, 98, 10, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 49, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 102, 51, 50, 46, 102, 108, 111, 111, 114, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 40, 102, 51, 50, 46, 99, 111, 110, 115, 116, 32, 48, 46, 53, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 41, 10, 32, 32, 32, 40, 98, 108, 111, 99, 107, 10, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 115, 101, 116, 32, 36, 118, 97, 114, 36, 48, 10, 32, 32, 32, 32, 32, 40, 102, 51, 50, 46, 99, 101, 105, 108, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 40, 105, 102, 10, 32, 32, 32, 32, 32, 40, 102, 51, 50, 46, 103, 116, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 32, 32, 32, 40, 102, 51, 50, 46, 99, 111, 110, 115, 116, 32, 48, 46, 53, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 40, 114, 101, 116, 117, 114, 110, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 115, 101, 116, 32, 36, 118, 97, 114, 36, 49, 10, 32, 32, 32, 32, 32, 40, 115, 101, 108, 101, 99, 116, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 40, 102, 51, 50, 46, 101, 113, 10, 32, 32, 32, 32, 32, 32, 32, 40, 102, 51, 50, 46, 115, 117, 98, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 50, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 102, 51, 50, 46, 109, 117, 108, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 102, 51, 50, 46, 99, 111, 110, 115, 116, 32, 48, 46, 53, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 102, 51, 50, 46, 102, 108, 111, 111, 114, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 40, 102, 51, 50, 46, 99, 111, 110, 115, 116, 32, 48, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 41, 10, 32, 32, 41, 10, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 41, 10, 32, 59, 59, 32, 108, 111, 119, 101, 114, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 102, 54, 52, 46, 110, 101, 97, 114, 101, 115, 116, 32, 105, 110, 115, 116, 114, 117, 99, 116, 105, 111, 110, 44, 32, 114, 111, 117, 110, 100, 105, 110, 103, 32, 116, 104, 101, 32, 105, 110, 112, 117, 116, 32, 116, 111, 32, 116, 104, 101, 32, 110, 101, 97, 114, 101, 115, 116, 10, 32, 59, 59, 32, 105, 110, 116, 101, 103, 101, 114, 32, 119, 104, 105, 108, 101, 32, 98, 114, 101, 97, 107, 105, 110, 103, 32, 116, 105, 101, 115, 32, 98, 121, 32, 114, 111, 117, 110, 100, 105, 110, 103, 32, 116, 111, 32, 101, 118, 101, 110, 10, 32, 40, 102, 117, 110, 99, 32, 36, 95, 95, 119, 97, 115, 109, 95, 110, 101, 97, 114, 101, 115, 116, 95, 102, 54, 52, 32, 40, 59, 32, 49, 51, 32, 59, 41, 32, 40, 116, 121, 112, 101, 32, 36, 50, 41, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 48, 32, 102, 54, 52, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 102, 54, 52, 41, 10, 32, 32, 40, 108, 111, 99, 97, 108, 32, 36, 118, 97, 114, 36, 49, 32, 102, 54, 52, 41, 10, 32, 32, 40, 108, 111, 99, 97, 108, 32, 36, 118, 97, 114, 36, 50, 32, 102, 54, 52, 41, 10, 32, 32, 40, 105, 102, 10, 32, 32, 32, 40, 105, 51, 50, 46, 101, 113, 122, 10, 32, 32, 32, 32, 40, 102, 54, 52, 46, 108, 116, 10, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 50, 10, 32, 32, 32, 32, 32, 32, 40, 102, 54, 52, 46, 115, 117, 98, 10, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 49, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 102, 54, 52, 46, 102, 108, 111, 111, 114, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 40, 102, 54, 52, 46, 99, 111, 110, 115, 116, 32, 48, 46, 53, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 41, 10, 32, 32, 32, 40, 98, 108, 111, 99, 107, 10, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 115, 101, 116, 32, 36, 118, 97, 114, 36, 48, 10, 32, 32, 32, 32, 32, 40, 102, 54, 52, 46, 99, 101, 105, 108, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 40, 105, 102, 10, 32, 32, 32, 32, 32, 40, 102, 54, 52, 46, 103, 116, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 32, 32, 32, 40, 102, 54, 52, 46, 99, 111, 110, 115, 116, 32, 48, 46, 53, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 40, 114, 101, 116, 117, 114, 110, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 115, 101, 116, 32, 36, 118, 97, 114, 36, 49, 10, 32, 32, 32, 32, 32, 40, 115, 101, 108, 101, 99, 116, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 40, 102, 54, 52, 46, 101, 113, 10, 32, 32, 32, 32, 32, 32, 32, 40, 102, 54, 52, 46, 115, 117, 98, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 50, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 102, 54, 52, 46, 109, 117, 108, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 102, 54, 52, 46, 99, 111, 110, 115, 116, 32, 48, 46, 53, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 102, 54, 52, 46, 102, 108, 111, 111, 114, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 40, 102, 54, 52, 46, 99, 111, 110, 115, 116, 32, 48, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 41, 10, 32, 32, 41, 10, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 41, 10, 32, 40, 102, 117, 110, 99, 32, 36, 95, 90, 78, 49, 55, 99, 111, 109, 112, 105, 108, 101, 114, 95, 98, 117, 105, 108, 116, 105, 110, 115, 51, 105, 110, 116, 52, 117, 100, 105, 118, 49, 48, 100, 105, 118, 109, 111, 100, 95, 117, 54, 52, 49, 55, 104, 54, 48, 50, 54, 57, 49, 48, 98, 53, 101, 100, 48, 56, 101, 52, 48, 69, 32, 40, 59, 32, 49, 52, 32, 59, 41, 32, 40, 116, 121, 112, 101, 32, 36, 48, 41, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 48, 32, 105, 54, 52, 41, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 49, 32, 105, 54, 52, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 54, 52, 41, 10, 32, 32, 40, 108, 111, 99, 97, 108, 32, 36, 118, 97, 114, 36, 50, 32, 105, 51, 50, 41, 10, 32, 32, 40, 108, 111, 99, 97, 108, 32, 36, 118, 97, 114, 36, 51, 32, 105, 51, 50, 41, 10, 32, 32, 40, 108, 111, 99, 97, 108, 32, 36, 118, 97, 114, 36, 52, 32, 105, 51, 50, 41, 10, 32, 32, 40, 108, 111, 99, 97, 108, 32, 36, 118, 97, 114, 36, 53, 32, 105, 54, 52, 41, 10, 32, 32, 40, 108, 111, 99, 97, 108, 32, 36, 118, 97, 114, 36, 54, 32, 105, 54, 52, 41, 10, 32, 32, 40, 108, 111, 99, 97, 108, 32, 36, 118, 97, 114, 36, 55, 32, 105, 54, 52, 41, 10, 32, 32, 40, 108, 111, 99, 97, 108, 32, 36, 118, 97, 114, 36, 56, 32, 105, 54, 52, 41, 10, 32, 32, 40, 98, 108, 111, 99, 107, 32, 36, 108, 97, 98, 101, 108, 36, 49, 10, 32, 32, 32, 40, 98, 108, 111, 99, 107, 32, 36, 108, 97, 98, 101, 108, 36, 50, 10, 32, 32, 32, 32, 40, 98, 108, 111, 99, 107, 32, 36, 108, 97, 98, 101, 108, 36, 51, 10, 32, 32, 32, 32, 32, 40, 98, 108, 111, 99, 107, 32, 36, 108, 97, 98, 101, 108, 36, 52, 10, 32, 32, 32, 32, 32, 32, 40, 98, 108, 111, 99, 107, 32, 36, 108, 97, 98, 101, 108, 36, 53, 10, 32, 32, 32, 32, 32, 32, 32, 40, 98, 108, 111, 99, 107, 32, 36, 108, 97, 98, 101, 108, 36, 54, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 98, 108, 111, 99, 107, 32, 36, 108, 97, 98, 101, 108, 36, 55, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 98, 108, 111, 99, 107, 32, 36, 108, 97, 98, 101, 108, 36, 56, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 98, 108, 111, 99, 107, 32, 36, 108, 97, 98, 101, 108, 36, 57, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 98, 108, 111, 99, 107, 32, 36, 108, 97, 98, 101, 108, 36, 49, 48, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 98, 108, 111, 99, 107, 32, 36, 108, 97, 98, 101, 108, 36, 49, 49, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 102, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 50, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 119, 114, 97, 112, 95, 105, 54, 52, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 104, 114, 95, 117, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 51, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 98, 108, 111, 99, 107, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 98, 114, 95, 105, 102, 32, 36, 108, 97, 98, 101, 108, 36, 49, 49, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 101, 113, 122, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 51, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 119, 114, 97, 112, 95, 105, 54, 52, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 98, 114, 95, 105, 102, 32, 36, 108, 97, 98, 101, 108, 36, 57, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 101, 113, 122, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 52, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 119, 114, 97, 112, 95, 105, 54, 52, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 104, 114, 95, 117, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 51, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 98, 114, 95, 105, 102, 32, 36, 108, 97, 98, 101, 108, 36, 56, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 108, 101, 95, 117, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 50, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 115, 117, 98, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 108, 122, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 52, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 108, 122, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 51, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 98, 114, 32, 36, 108, 97, 98, 101, 108, 36, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 98, 114, 95, 105, 102, 32, 36, 108, 97, 98, 101, 108, 36, 50, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 103, 101, 95, 117, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 52, 50, 57, 52, 57, 54, 55, 50, 57, 54, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 103, 108, 111, 98, 97, 108, 46, 115, 101, 116, 32, 36, 95, 95, 119, 97, 115, 109, 45, 105, 110, 116, 114, 105, 110, 115, 105, 99, 115, 45, 116, 101, 109, 112, 45, 105, 54, 52, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 101, 120, 116, 101, 110, 100, 95, 105, 51, 50, 95, 117, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 115, 117, 98, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 50, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 119, 114, 97, 112, 95, 105, 54, 52, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 109, 117, 108, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 50, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 100, 105, 118, 95, 117, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 51, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 119, 114, 97, 112, 95, 105, 54, 52, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 114, 101, 116, 117, 114, 110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 101, 120, 116, 101, 110, 100, 95, 105, 51, 50, 95, 117, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 115, 101, 116, 32, 36, 118, 97, 114, 36, 51, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 119, 114, 97, 112, 95, 105, 54, 52, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 104, 114, 95, 117, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 51, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 98, 114, 95, 105, 102, 32, 36, 108, 97, 98, 101, 108, 36, 55, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 101, 113, 122, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 119, 114, 97, 112, 95, 105, 54, 52, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 98, 114, 95, 105, 102, 32, 36, 108, 97, 98, 101, 108, 36, 54, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 101, 113, 122, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 98, 114, 95, 105, 102, 32, 36, 108, 97, 98, 101, 108, 36, 54, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 52, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 100, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 45, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 103, 108, 111, 98, 97, 108, 46, 115, 101, 116, 32, 36, 95, 95, 119, 97, 115, 109, 45, 105, 110, 116, 114, 105, 110, 115, 105, 99, 115, 45, 116, 101, 109, 112, 45, 105, 54, 52, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 111, 114, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 104, 108, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 101, 120, 116, 101, 110, 100, 95, 105, 51, 50, 95, 117, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 52, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 51, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 52, 50, 57, 52, 57, 54, 55, 50, 57, 53, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 114, 101, 116, 117, 114, 110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 101, 120, 116, 101, 110, 100, 95, 105, 51, 50, 95, 117, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 115, 104, 114, 95, 117, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 116, 122, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 51, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 117, 110, 114, 101, 97, 99, 104, 97, 98, 108, 101, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 98, 114, 95, 105, 102, 32, 36, 108, 97, 98, 101, 108, 36, 53, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 101, 113, 122, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 52, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 100, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 45, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 115, 101, 116, 32, 36, 118, 97, 114, 36, 51, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 115, 117, 98, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 48, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 50, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 115, 117, 98, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 100, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 108, 122, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 51, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 108, 122, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 98, 114, 32, 36, 108, 97, 98, 101, 108, 36, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 115, 101, 116, 32, 36, 118, 97, 114, 36, 51, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 115, 117, 98, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 54, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 115, 101, 116, 32, 36, 118, 97, 114, 36, 50, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 100, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 98, 114, 32, 36, 108, 97, 98, 101, 108, 36, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 103, 108, 111, 98, 97, 108, 46, 115, 101, 116, 32, 36, 95, 95, 119, 97, 115, 109, 45, 105, 110, 116, 114, 105, 110, 115, 105, 99, 115, 45, 116, 101, 109, 112, 45, 105, 54, 52, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 104, 108, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 101, 120, 116, 101, 110, 100, 95, 105, 51, 50, 95, 117, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 115, 117, 98, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 109, 117, 108, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 52, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 100, 105, 118, 95, 117, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 51, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 114, 101, 116, 117, 114, 110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 101, 120, 116, 101, 110, 100, 95, 105, 51, 50, 95, 117, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 52, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 40, 98, 114, 95, 105, 102, 32, 36, 108, 97, 98, 101, 108, 36, 52, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 108, 116, 95, 117, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 50, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 115, 117, 98, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 108, 122, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 108, 122, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 51, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 40, 98, 114, 32, 36, 108, 97, 98, 101, 108, 36, 50, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 40, 103, 108, 111, 98, 97, 108, 46, 115, 101, 116, 32, 36, 95, 95, 119, 97, 115, 109, 45, 105, 110, 116, 114, 105, 110, 115, 105, 99, 115, 45, 116, 101, 109, 112, 45, 105, 54, 52, 10, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 101, 120, 116, 101, 110, 100, 95, 105, 51, 50, 95, 117, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 52, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 119, 114, 97, 112, 95, 105, 54, 52, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 40, 98, 114, 95, 105, 102, 32, 36, 108, 97, 98, 101, 108, 36, 49, 10, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 101, 113, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 40, 114, 101, 116, 117, 114, 110, 10, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 104, 114, 95, 117, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 101, 120, 116, 101, 110, 100, 95, 105, 51, 50, 95, 117, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 116, 122, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 115, 101, 116, 32, 36, 118, 97, 114, 36, 51, 10, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 115, 117, 98, 10, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 54, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 115, 101, 116, 32, 36, 118, 97, 114, 36, 50, 10, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 100, 100, 10, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 49, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 115, 101, 116, 32, 36, 118, 97, 114, 36, 53, 10, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 104, 114, 95, 117, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 101, 120, 116, 101, 110, 100, 95, 105, 51, 50, 95, 117, 10, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 54, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 115, 101, 116, 32, 36, 118, 97, 114, 36, 48, 10, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 104, 108, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 101, 120, 116, 101, 110, 100, 95, 105, 51, 50, 95, 117, 10, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 54, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 40, 98, 108, 111, 99, 107, 32, 36, 108, 97, 98, 101, 108, 36, 49, 51, 10, 32, 32, 32, 32, 32, 40, 105, 102, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 32, 32, 32, 40, 98, 108, 111, 99, 107, 10, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 115, 101, 116, 32, 36, 118, 97, 114, 36, 56, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 97, 100, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 45, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 111, 112, 32, 36, 108, 97, 98, 101, 108, 36, 49, 53, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 115, 101, 116, 32, 36, 118, 97, 114, 36, 53, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 117, 98, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 53, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 111, 114, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 104, 108, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 53, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 104, 114, 95, 117, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 54, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 54, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 104, 114, 95, 115, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 117, 98, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 56, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 53, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 54, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 115, 101, 116, 32, 36, 118, 97, 114, 36, 48, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 111, 114, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 104, 108, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 55, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 115, 101, 116, 32, 36, 118, 97, 114, 36, 55, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 54, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 54, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 98, 114, 95, 105, 102, 32, 36, 108, 97, 98, 101, 108, 36, 49, 53, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 50, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 100, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 45, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 40, 98, 114, 32, 36, 108, 97, 98, 101, 108, 36, 49, 51, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 40, 103, 108, 111, 98, 97, 108, 46, 115, 101, 116, 32, 36, 95, 95, 119, 97, 115, 109, 45, 105, 110, 116, 114, 105, 110, 115, 105, 99, 115, 45, 116, 101, 109, 112, 45, 105, 54, 52, 10, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 53, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 40, 114, 101, 116, 117, 114, 110, 10, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 111, 114, 10, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 104, 108, 10, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 49, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 54, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 41, 10, 32, 32, 32, 40, 103, 108, 111, 98, 97, 108, 46, 115, 101, 116, 32, 36, 95, 95, 119, 97, 115, 109, 45, 105, 110, 116, 114, 105, 110, 115, 105, 99, 115, 45, 116, 101, 109, 112, 45, 105, 54, 52, 10, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 41, 10, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 115, 101, 116, 32, 36, 118, 97, 114, 36, 48, 10, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 48, 41, 10, 32, 32, 32, 41, 10, 32, 32, 41, 10, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 41, 10, 32, 40, 102, 117, 110, 99, 32, 36, 95, 90, 78, 49, 55, 99, 111, 109, 112, 105, 108, 101, 114, 95, 98, 117, 105, 108, 116, 105, 110, 115, 51, 105, 110, 116, 51, 109, 117, 108, 51, 77, 117, 108, 51, 109, 117, 108, 49, 55, 104, 48, 55, 48, 101, 57, 97, 49, 99, 54, 57, 102, 97, 101, 99, 53, 98, 69, 32, 40, 59, 32, 49, 53, 32, 59, 41, 32, 40, 116, 121, 112, 101, 32, 36, 48, 41, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 48, 32, 105, 54, 52, 41, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 49, 32, 105, 54, 52, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 54, 52, 41, 10, 32, 32, 40, 108, 111, 99, 97, 108, 32, 36, 118, 97, 114, 36, 50, 32, 105, 51, 50, 41, 10, 32, 32, 40, 108, 111, 99, 97, 108, 32, 36, 118, 97, 114, 36, 51, 32, 105, 51, 50, 41, 10, 32, 32, 40, 108, 111, 99, 97, 108, 32, 36, 118, 97, 114, 36, 52, 32, 105, 51, 50, 41, 10, 32, 32, 40, 108, 111, 99, 97, 108, 32, 36, 118, 97, 114, 36, 53, 32, 105, 51, 50, 41, 10, 32, 32, 40, 108, 111, 99, 97, 108, 32, 36, 118, 97, 114, 36, 54, 32, 105, 51, 50, 41, 10, 32, 32, 40, 105, 54, 52, 46, 111, 114, 10, 32, 32, 32, 40, 105, 54, 52, 46, 115, 104, 108, 10, 32, 32, 32, 32, 40, 105, 54, 52, 46, 101, 120, 116, 101, 110, 100, 95, 105, 51, 50, 95, 117, 10, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 100, 100, 10, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 100, 100, 10, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 100, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 100, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 109, 117, 108, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 52, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 115, 104, 114, 95, 117, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 50, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 119, 114, 97, 112, 95, 105, 54, 52, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 49, 54, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 53, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 115, 104, 114, 95, 117, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 51, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 119, 114, 97, 112, 95, 105, 54, 52, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 49, 54, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 109, 117, 108, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 119, 114, 97, 112, 95, 105, 54, 52, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 104, 114, 95, 117, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 51, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 109, 117, 108, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 119, 114, 97, 112, 95, 105, 54, 52, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 104, 114, 95, 117, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 51, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 115, 104, 114, 95, 117, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 50, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 100, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 115, 104, 114, 95, 117, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 54, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 109, 117, 108, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 50, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 54, 53, 53, 51, 53, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 51, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 54, 53, 53, 51, 53, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 49, 54, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 109, 117, 108, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 53, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 49, 54, 41, 10, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 115, 104, 114, 95, 117, 10, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 50, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 100, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 54, 53, 53, 51, 53, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 109, 117, 108, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 52, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 49, 54, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 51, 50, 41, 10, 32, 32, 32, 41, 10, 32, 32, 32, 40, 105, 54, 52, 46, 101, 120, 116, 101, 110, 100, 95, 105, 51, 50, 95, 117, 10, 32, 32, 32, 32, 40, 105, 51, 50, 46, 111, 114, 10, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 115, 104, 108, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 49, 54, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 97, 110, 100, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 54, 41, 10, 32, 32, 32, 32, 32, 32, 40, 105, 51, 50, 46, 99, 111, 110, 115, 116, 32, 54, 53, 53, 51, 53, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 41, 10, 32, 32, 41, 10, 32, 41, 10, 32, 40, 102, 117, 110, 99, 32, 36, 95, 90, 78, 49, 55, 99, 111, 109, 112, 105, 108, 101, 114, 95, 98, 117, 105, 108, 116, 105, 110, 115, 51, 105, 110, 116, 52, 115, 100, 105, 118, 51, 68, 105, 118, 51, 100, 105, 118, 49, 55, 104, 101, 55, 56, 102, 99, 52, 56, 51, 101, 52, 49, 100, 55, 101, 99, 55, 69, 32, 40, 59, 32, 49, 54, 32, 59, 41, 32, 40, 116, 121, 112, 101, 32, 36, 48, 41, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 48, 32, 105, 54, 52, 41, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 49, 32, 105, 54, 52, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 54, 52, 41, 10, 32, 32, 40, 108, 111, 99, 97, 108, 32, 36, 118, 97, 114, 36, 50, 32, 105, 54, 52, 41, 10, 32, 32, 40, 105, 54, 52, 46, 115, 117, 98, 10, 32, 32, 32, 40, 105, 54, 52, 46, 120, 111, 114, 10, 32, 32, 32, 32, 40, 105, 54, 52, 46, 100, 105, 118, 95, 117, 10, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 117, 98, 10, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 120, 111, 114, 10, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 50, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 104, 114, 95, 115, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 54, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 117, 98, 10, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 120, 111, 114, 10, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 50, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 104, 114, 95, 115, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 54, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 48, 10, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 104, 114, 95, 115, 10, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 120, 111, 114, 10, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 54, 51, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 41, 10, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 41, 10, 32, 41, 10, 32, 40, 102, 117, 110, 99, 32, 36, 95, 90, 78, 49, 55, 99, 111, 109, 112, 105, 108, 101, 114, 95, 98, 117, 105, 108, 116, 105, 110, 115, 51, 105, 110, 116, 52, 115, 100, 105, 118, 51, 77, 111, 100, 52, 109, 111, 100, 95, 49, 55, 104, 50, 99, 98, 98, 55, 98, 98, 102, 51, 54, 101, 52, 49, 100, 54, 56, 69, 32, 40, 59, 32, 49, 55, 32, 59, 41, 32, 40, 116, 121, 112, 101, 32, 36, 48, 41, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 48, 32, 105, 54, 52, 41, 32, 40, 112, 97, 114, 97, 109, 32, 36, 118, 97, 114, 36, 49, 32, 105, 54, 52, 41, 32, 40, 114, 101, 115, 117, 108, 116, 32, 105, 54, 52, 41, 10, 32, 32, 40, 108, 111, 99, 97, 108, 32, 36, 118, 97, 114, 36, 50, 32, 105, 54, 52, 41, 10, 32, 32, 40, 105, 54, 52, 46, 115, 117, 98, 10, 32, 32, 32, 40, 105, 54, 52, 46, 120, 111, 114, 10, 32, 32, 32, 32, 40, 105, 54, 52, 46, 114, 101, 109, 95, 117, 10, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 117, 98, 10, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 120, 111, 114, 10, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 50, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 104, 114, 95, 115, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 54, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 117, 98, 10, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 120, 111, 114, 10, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 116, 101, 101, 32, 36, 118, 97, 114, 36, 48, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 115, 104, 114, 95, 115, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 105, 54, 52, 46, 99, 111, 110, 115, 116, 32, 54, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 49, 41, 10, 32, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 48, 41, 10, 32, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 41, 10, 32, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 32, 41, 10, 32, 32, 32, 40, 108, 111, 99, 97, 108, 46, 103, 101, 116, 32, 36, 118, 97, 114, 36, 50, 41, 10, 32, 32, 41, 10, 32, 41, 10, 32, 59, 59, 32, 99, 117, 115, 116, 111, 109, 32, 115, 101, 99, 116, 105, 111, 110, 32, 34, 108, 105, 110, 107, 105, 110, 103, 34, 44, 32, 115, 105, 122, 101, 32, 51, 10, 41, 10, 0 }; namespace wasm {
binaryen/src/passes/pass.cpp view
@@ -126,12 +126,6 @@ registerPass("emit-target-features", "emit the target features section in the output", createEmitTargetFeaturesPass);- registerPass("emscripten-pic",- "Convert PIC ABI from llvm to emscripten",- createEmscriptenPICPass);- registerPass("emscripten-pic-main-module",- "Convert PIC ABI from llvm to emscripten",- createEmscriptenPICMainModulePass); registerPass("extract-function", "leaves just one function (useful for debugging)", createExtractFunctionPass);@@ -190,6 +184,10 @@ registerPass("limit-segments", "attempt to merge segments to fit within web limits", createLimitSegmentsPass);+ registerPass("memory64-lowering",+ "lower loads and stores to a 64-bit memory to instead use a "+ "32-bit one",+ createMemory64LoweringPass); registerPass("memory-packing", "packs memory into separate segments, skipping zeros", createMemoryPackingPass);@@ -299,10 +297,6 @@ registerPass("rereloop", "re-optimize control flow using the relooper algorithm", createReReloopPass);- registerPass("replace-stack-pointer",- "Replace llvm-generated stack pointer global with calls with "- "imported functions.",- createReplaceStackPointerPass); registerPass( "rse", "remove redundant local.sets", createRedundantSetEliminationPass); registerPass("roundtrip",@@ -339,9 +333,6 @@ registerPass("souperify-single-use", "emit Souper IR in text form (single-use nodes only)", createSouperifySingleUsePass);- registerPass("spill-pointers",- "spill pointers to the C stack (useful for Boehm-style GC)",- createSpillPointersPass); registerPass("stub-unsupported-js", "stub out unsupported JS operations", createStubUnsupportedJSOpsPass);@@ -410,6 +401,7 @@ add("local-cse"); } add("dce");+ add("remove-unused-names"); add("remove-unused-brs"); add("remove-unused-names"); add("optimize-instructions");@@ -542,28 +534,34 @@ void PassRunner::run() { static const int passDebug = getPassDebug();- if (!isNested && (options.debug || passDebug)) {+ // Emit logging information when asked for. At passDebug level 1+ we log+ // the main passes, while in 2 we also log nested ones. Note that for+ // nested ones we can only emit their name - we can't validate, or save the+ // file, or print, as the wasm may be in an intermediate state that is not+ // valid.+ if (options.debug || (passDebug == 2 || (passDebug && !isNested))) { // for debug logging purposes, run each pass in full before running the // other auto totalTime = std::chrono::duration<double>(0);- size_t padding = 0; WasmValidator::Flags validationFlags = WasmValidator::Minimal; if (options.validateGlobally) { validationFlags = validationFlags | WasmValidator::Globally; }- std::cerr << "[PassRunner] running passes..." << std::endl;+ auto what = isNested ? "nested passes" : "passes";+ std::cerr << "[PassRunner] running " << what << std::endl;+ size_t padding = 0; for (auto& pass : passes) { padding = std::max(padding, pass->name.size()); }- if (passDebug >= 3) {+ if (passDebug >= 3 && !isNested) { dumpWast("before", wasm); } for (auto& pass : passes) { // ignoring the time, save a printout of the module before, in case this // pass breaks it, so we can print the before and after std::stringstream moduleBefore;- if (passDebug == 2) {- WasmPrinter::printModule(wasm, moduleBefore);+ if (passDebug == 2 && !isNested) {+ moduleBefore << *wasm << '\n'; } // prepare to run std::cerr << "[PassRunner] running pass: " << pass->name << "... ";@@ -582,11 +580,11 @@ std::chrono::duration<double> diff = after - before; std::cerr << diff.count() << " seconds." << std::endl; totalTime += diff;- if (options.validate) {+ if (options.validate && !isNested) { // validate, ignoring the time std::cerr << "[PassRunner] (validating)\n"; if (!WasmValidator().validate(*wasm, validationFlags)) {- WasmPrinter::printModule(wasm);+ std::cout << *wasm << '\n'; if (passDebug >= 2) { Fatal() << "Last pass (" << pass->name << ") broke validation. Here is the module before: \n"@@ -603,12 +601,12 @@ dumpWast(pass->name, wasm); } }- std::cerr << "[PassRunner] passes took " << totalTime.count() << " seconds."- << std::endl;- if (options.validate) {+ std::cerr << "[PassRunner] " << what << " took " << totalTime.count()+ << " seconds." << std::endl;+ if (options.validate && !isNested) { std::cerr << "[PassRunner] (final validation)\n"; if (!WasmValidator().validate(*wasm, validationFlags)) {- WasmPrinter::printModule(wasm);+ std::cout << *wasm << '\n'; Fatal() << "final module does not validate\n"; } }@@ -672,7 +670,6 @@ } void PassRunner::doAdd(std::unique_ptr<Pass> pass) {- pass->prepareToRun(this, wasm); passes.emplace_back(std::move(pass)); }
binaryen/src/passes/passes.h view
@@ -41,8 +41,6 @@ Pass* createDuplicateImportEliminationPass(); Pass* createDuplicateFunctionEliminationPass(); Pass* createEmitTargetFeaturesPass();-Pass* createEmscriptenPICPass();-Pass* createEmscriptenPICMainModulePass(); Pass* createExtractFunctionPass(); Pass* createFlattenPass(); Pass* createFuncCastEmulationPass();@@ -63,6 +61,7 @@ Pass* createInstrumentLocalsPass(); Pass* createInstrumentMemoryPass(); Pass* createLoopInvariantCodeMotionPass();+Pass* createMemory64LoweringPass(); Pass* createMemoryPackingPass(); Pass* createMergeBlocksPass(); Pass* createMergeLocalsPass();@@ -99,7 +98,6 @@ Pass* createRemoveUnusedNamesPass(); Pass* createReorderFunctionsPass(); Pass* createReorderLocalsPass();-Pass* createReplaceStackPointerPass(); Pass* createReReloopPass(); Pass* createRedundantSetEliminationPass(); Pass* createRoundTripPass();@@ -118,7 +116,6 @@ Pass* createStripTargetFeaturesPass(); Pass* createSouperifyPass(); Pass* createSouperifySingleUsePass();-Pass* createSpillPointersPass(); Pass* createStubUnsupportedJSOpsPass(); Pass* createSSAifyPass(); Pass* createSSAifyNoMergePass();
binaryen/src/passes/wasm-intrinsics.wat view
@@ -26,8 +26,6 @@ (export "__wasm_i64_srem" (func $__wasm_i64_srem)) (export "__wasm_i64_urem" (func $__wasm_i64_urem)) (export "__wasm_i64_mul" (func $__wasm_i64_mul))- (export "__wasm_trunc_f32" (func $__wasm_trunc_f32))- (export "__wasm_trunc_f64" (func $__wasm_trunc_f64)) (export "__wasm_ctz_i32" (func $__wasm_ctz_i32)) (export "__wasm_ctz_i64" (func $__wasm_ctz_i64)) (export "__wasm_rotl_i32" (func $__wasm_rotl_i32))@@ -142,38 +140,6 @@ (call $_ZN17compiler_builtins3int3mul3Mul3mul17h070e9a1c69faec5bE (local.get $var$0) (local.get $var$1)- )- )- ;; lowering of the f32.trunc instruction, rounds to the nearest integer,- ;; towards zero- (func $__wasm_trunc_f32 (; 5 ;) (type $1) (param $var$0 f32) (result f32)- (select- (f32.ceil- (local.get $var$0)- )- (f32.floor- (local.get $var$0)- )- (f32.lt- (local.get $var$0)- (f32.const 0)- )- )- )- ;; lowering of the f64.trunc instruction, rounds to the nearest integer,- ;; towards zero- (func $__wasm_trunc_f64 (; 6 ;) (type $2) (param $var$0 f64) (result f64)- (select- (f64.ceil- (local.get $var$0)- )- (f64.floor- (local.get $var$0)- )- (f64.lt- (local.get $var$0)- (f64.const 0)- ) ) ) ;; lowering of the i32.ctz instruction, counting the number of zeros in $var$0
@@ -39,9 +39,12 @@ extern Name EXPORT; extern Name IMPORT; extern Name TABLE;+extern Name GLOBAL; extern Name ELEM; extern Name LOCAL; extern Name TYPE;+extern Name REF;+extern Name NULL_; extern Name CALL; extern Name CALL_IMPORT; extern Name CALL_INDIRECT;@@ -64,7 +67,6 @@ extern Name SHARED; extern Name EVENT; extern Name ATTR;-extern Name ASSIGN_GOT_ENTRIES; } // namespace wasm
binaryen/src/shell-interface.h view
@@ -98,7 +98,7 @@ void importGlobals(std::map<Name, Literals>& globals, Module& wasm) override { // add spectest globals ModuleUtils::iterImportedGlobals(wasm, [&](Global* import) {- if (import->module == SPECTEST && import->base.startsWith(GLOBAL)) {+ if (import->module == SPECTEST && import->base.startsWith("global_")) { TODO_SINGLE_COMPOUND(import->type); switch (import->type.getBasic()) { case Type::i32:
binaryen/src/support/bits.cpp view
@@ -157,6 +157,38 @@ int ceilLog2(uint64_t v) { return 64 - countLeadingZeroes(v - 1); } +bool isPowerOf2InvertibleFloat(float v) {+ // Power of two floating points should have zero as their significands,+ // so here we just mask the exponent range of "v" and compare it with the+ // unmasked input value. If they are equal, our value is a power of+ // two. Also, we reject all values which are less than the minimal possible+ // power of two or greater than the maximum possible power of two.+ // We check values only with exponent in more limited ranges+ // [-126..+126] for floats and [-1022..+1022] for doubles for avoiding+ // overflows and reject NaNs, infinity and denormals. We also reject+ // "asymmetric exponents", like +1023, because the range of+ // (non-NaN, non-infinity) values is -1022..+1023, and it is convenient in+ // optimizations to depend on being able to invert a power of two without+ // losing precision.+ // This function used in OptimizeInstruction pass.+ const uint32_t MIN_POT = 0x01U << 23; // 0x1p-126+ const uint32_t MAX_POT = 0xFDU << 23; // 0x1p+126+ const uint32_t EXP_MASK = 0xFFU << 23; // mask only exponent+ const uint32_t SIGN_MASK = ~0U >> 1; // mask everything except sign+ auto u = bit_cast<uint32_t>(v) & SIGN_MASK;+ return u >= MIN_POT && u <= MAX_POT && (u & EXP_MASK) == u;+}++bool isPowerOf2InvertibleFloat(double v) {+ // See isPowerOf2InvertibleFloat(float)+ const uint64_t MIN_POT = 0x001ULL << 52; // 0x1p-1022+ const uint64_t MAX_POT = 0x7FDULL << 52; // 0x1p+1022+ const uint64_t EXP_MASK = 0x7FFULL << 52; // mask only exponent+ const uint64_t SIGN_MASK = ~0ULL >> 1; // mask everything except sign+ auto u = bit_cast<uint64_t>(v) & SIGN_MASK;+ return u >= MIN_POT && u <= MAX_POT && (u & EXP_MASK) == u;+}+ uint32_t log2(uint32_t v) { if (!isPowerOf2(v)) { WASM_UNREACHABLE("value should be a power of two");@@ -164,7 +196,7 @@ return 31 - countLeadingZeroes(v); } -uint32_t pow2(uint32_t v) { return 1 << v; }+uint32_t pow2(uint32_t v) { return v < 32 ? 1 << v : 0; } } // namespace Bits
binaryen/src/support/bits.h view
@@ -77,6 +77,9 @@ return v != 0 && (v & (v - 1)) == 0; } +bool isPowerOf2InvertibleFloat(float);+bool isPowerOf2InvertibleFloat(double);+ template<typename T, typename U> inline static T rotateLeft(T val, U count) { auto value = typename std::make_unsigned<T>::type(val); U mask = sizeof(T) * CHAR_BIT - 1;
binaryen/src/support/file.h view
@@ -15,7 +15,7 @@ */ //-// FIle helpers.+// File helpers. // #ifndef wasm_support_file_h
binaryen/src/support/small_vector.h view
@@ -46,6 +46,7 @@ push_back(item); } }+ SmallVector(size_t initialSize) { resize(initialSize); } T& operator[](size_t i) { if (i < N) {@@ -109,6 +110,13 @@ void clear() { usedFixed = 0; flexible.clear();+ }++ void resize(size_t newSize) {+ usedFixed = std::min(N, newSize);+ if (newSize > N) {+ flexible.resize(newSize - N);+ } } bool operator==(const SmallVector<T, N>& other) const {
+ binaryen/src/support/space.h view
@@ -0,0 +1,84 @@+/*+ * Copyright 2020 WebAssembly Community Group participants+ *+ * Licensed under the Apache License, Version 2.0 (the "License");+ * you may not use this file except in compliance with the License.+ * You may obtain a copy of the License at+ *+ * http://www.apache.org/licenses/LICENSE-2.0+ *+ * Unless required by applicable law or agreed to in writing, software+ * distributed under the License is distributed on an "AS IS" BASIS,+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+ * See the License for the specific language governing permissions and+ * limitations under the License.+ */++#ifndef wasm_support_space_h+#define wasm_support_space_h++#include "utilities.h"+#include <wasm.h>++namespace wasm {++struct DisjointSpans {+ // A span of form [a, b), i.e., that does not include the end point.+ struct Span {+ Address left, right;++ bool checkOverlap(const Span& other) const {+ return !(left >= other.right || right <= other.left);+ }+ };++ struct SortByLeft {+ bool operator()(const Span& left, const Span& right) const {+ return left.left < right.left ||+ (left.left == right.left && left.right < right.right);+ }+ };++ // The spans seen so far. Guaranteed to be disjoint.+ std::set<Span, SortByLeft> spans;++ // Adds an item and checks overlap while doing so, returning true if such+ // overlap exists.+ bool addAndCheckOverlap(Span span) {+ // Insert the new span. We can then find its predecessor and successor.+ // They are disjoint by assumption, so the question is then does the new+ // span overlap with them, or not.+ decltype(spans)::iterator iter;+ bool inserted;+ std::tie(iter, inserted) = spans.insert(span);+ if (!inserted) {+ // This exact span was already there, so there is definite overlap.+ return true;+ }+ // Check predecessor and successor, if they exist.+ if (iter != spans.begin() && std::prev(iter)->checkOverlap(span)) {+ return true;+ }+ if (std::next(iter) != spans.end() && std::next(iter)->checkOverlap(span)) {+ return true;+ }+ return false;+ }++ // Inefficient - mostly for testing.+ void add(Span span) { addAndCheckOverlap(span); }++ // Inefficient - mostly for testing.+ bool checkOverlap(Span span) {+ bool existsBefore = spans.find(span) != spans.end();+ auto hasOverlap = addAndCheckOverlap(span);+ if (!existsBefore) {+ spans.erase(span);+ }+ return hasOverlap;+ }+};++} // namespace wasm++#endif // wasm_support_space_h
binaryen/src/support/string.h view
@@ -115,6 +115,10 @@ return input.substr(0, size); } +inline bool isNumber(const std::string& str) {+ return !str.empty() && std::all_of(str.begin(), str.end(), ::isdigit);+}+ } // namespace String } // namespace wasm
binaryen/src/tools/execution-results.h view
@@ -29,6 +29,14 @@ struct LoggingExternalInterface : public ShellExternalInterface { Loggings& loggings; + struct State {+ // Legalization for JS emits get/setTempRet0 calls ("temp ret 0" means a+ // temporary return value of 32 bits; "0" is the only important value for+ // 64-bit legalization, which needs one such 32-bit chunk in addition to+ // the normal return value which can handle 32 bits).+ uint32_t tempRet0 = 0;+ } state;+ LoggingExternalInterface(Loggings& loggings) : loggings(loggings) {} Literals callImport(Function* import, LiteralList& arguments) override {@@ -40,7 +48,24 @@ loggings.push_back(argument); } std::cout << "]\n";+ return {};+ } else if (import->module == ENV) {+ if (import->base == "log_execution") {+ std::cout << "[LoggingExternalInterface log-execution";+ for (auto argument : arguments) {+ std::cout << ' ' << argument;+ }+ std::cout << "]\n";+ return {};+ } else if (import->base == "setTempRet0") {+ state.tempRet0 = arguments[0].geti32();+ return {};+ } else if (import->base == "getTempRet0") {+ return {Literal(state.tempRet0)};+ } }+ std::cerr << "[LoggingExternalInterface ignoring an unknown import "+ << import->module << " . " << import->base << '\n'; return {}; } };@@ -69,14 +94,6 @@ if (func->sig.results != Type::none) { // this has a result Literals ret = run(func, wasm, instance);- // We cannot compare funcrefs by name because function names can- // change (after duplicate function elimination or roundtripping)- // while the function contents are still the same- for (Literal& val : ret) {- if (val.type == Type::funcref && !val.isNull()) {- val = Literal::makeFunc(Name("funcref"));- }- } results[exp->name] = ret; // ignore the result if we hit an unreachable and returned no value if (ret.size() > 0) {@@ -98,11 +115,46 @@ ExecutionResults optimizedResults; optimizedResults.get(wasm); if (optimizedResults != *this) {- std::cout << "[fuzz-exec] optimization passes changed execution results";+ std::cout << "[fuzz-exec] optimization passes changed results\n"; exit(1); } } + bool areEqual(Literal a, Literal b) {+ if (a.type != b.type) {+ std::cout << "types not identical! " << a << " != " << b << '\n';+ return false;+ }+ if (a.type.isRef()) {+ // Don't compare references - only their types. There are several issues+ // here that we can't fully handle, see+ // https://github.com/WebAssembly/binaryen/issues/3378, but the core issue+ // is that we are comparing results between two separate wasm modules (and+ // a separate instance of each) - we can't really identify an identical+ // reference between such things. We can only compare things structurally,+ // for which we compare the types.+ return true;+ }+ if (a != b) {+ std::cout << "values not identical! " << a << " != " << b << '\n';+ return false;+ }+ return true;+ }++ bool areEqual(Literals a, Literals b) {+ if (a.size() != b.size()) {+ std::cout << "literal counts not identical! " << a << " != " << b << '\n';+ return false;+ }+ for (Index i = 0; i < a.size(); i++) {+ if (!areEqual(a[i], b[i])) {+ return false;+ }+ }+ return true;+ }+ bool operator==(ExecutionResults& other) { for (auto& iter : other.results) { auto name = iter.first;@@ -111,15 +163,18 @@ return false; } std::cout << "[fuzz-exec] comparing " << name << '\n';- if (results[name] != other.results[name]) {- std::cout << "not identical! " << results[name]- << " != " << other.results[name] << "\n";+ if (!areEqual(results[name], other.results[name])) { return false; } }- if (loggings != other.loggings) {- std::cout << "logging not identical!\n";+ if (loggings.size() != other.loggings.size()) {+ std::cout << "logging counts not identical!\n"; return false;+ }+ for (Index i = 0; i < loggings.size(); i++) {+ if (!areEqual(loggings[i], other.loggings[i])) {+ return false;+ } } return true; }
binaryen/src/tools/fuzzing.h view
@@ -31,6 +31,7 @@ #include <ir/find_all.h> #include <ir/literal-utils.h> #include <ir/manipulation.h>+#include <ir/names.h> #include <ir/utils.h> #include <support/file.h> #include <tools/optimization-options.h>@@ -188,6 +189,9 @@ void setAllowOOB(bool allowOOB_) { allowOOB = allowOOB_; } void build() {+ if (HANG_LIMIT > 0) {+ prepareHangLimitSupport();+ } if (allowMemory) { setupMemory(); }@@ -196,6 +200,7 @@ if (wasm.features.hasExceptionHandling()) { setupEvents(); }+ modifyInitialFunctions(); addImportLoggingSupport(); // keep adding functions until we run out of input while (!finishedInput) {@@ -205,6 +210,9 @@ if (HANG_LIMIT > 0) { addHangLimitSupport(); }+ if (allowMemory) {+ finalizeMemory();+ } finalizeTable(); } @@ -241,7 +249,7 @@ // the memory that we use, a small portion so that we have a good chance of // looking at writes (we also look outside of this region with small // probability) this should be a power of 2- static const int USABLE_MEMORY = 16;+ const Address USABLE_MEMORY = 16; // the number of runtime iterations (function calls, loop backbranches) we // allow before we stop execution with a trap, to prevent hangs. 0 means@@ -313,30 +321,37 @@ } return Type(types); }+ if (type.isFunction() && type != Type::funcref) {+ // TODO: specific typed function references types.+ return type;+ } SmallVector<Type, 2> options; options.push_back(type); // includes itself- TODO_SINGLE_COMPOUND(type);- switch (type.getBasic()) {- case Type::anyref:- if (wasm.features.hasReferenceTypes()) {- options.push_back(Type::funcref);- options.push_back(Type::externref);- if (wasm.features.hasExceptionHandling()) {- options.push_back(Type::exnref);+ // TODO: interesting uses of typed function types+ // TODO: interesting subtypes of compound types+ if (type.isBasic()) {+ switch (type.getBasic()) {+ case Type::anyref:+ if (wasm.features.hasReferenceTypes()) {+ options.push_back(Type::funcref);+ options.push_back(Type::externref);+ if (wasm.features.hasExceptionHandling()) {+ options.push_back(Type::exnref);+ }+ if (wasm.features.hasGC()) {+ options.push_back(Type::eqref);+ options.push_back(Type::i31ref);+ } }+ break;+ case Type::eqref: if (wasm.features.hasGC()) {- options.push_back(Type::eqref); options.push_back(Type::i31ref); }- }- break;- case Type::eqref:- if (wasm.features.hasGC()) {- options.push_back(Type::i31ref);- }- break;- default:- break;+ break;+ default:+ break;+ } } return pick(options); }@@ -406,64 +421,161 @@ wasm.addExport( builder.makeExport(hasher->name, hasher->name, ExternalKind::Function)); // Export memory so JS fuzzing can use it- wasm.addExport(builder.makeExport("memory", "0", ExternalKind::Memory));+ if (!wasm.getExportOrNull("memory")) {+ wasm.addExport(builder.makeExport("memory", "0", ExternalKind::Memory));+ } } void setupTable() { wasm.table.exists = true;+ wasm.table.initial = wasm.table.max = 0; wasm.table.segments.emplace_back(builder.makeConst(int32_t(0))); } std::map<Type, std::vector<Name>> globalsByType; void setupGlobals() {+ // If there were initial wasm contents, there may be imported globals. That+ // would be a problem in the fuzzer harness as we'd error if we do not+ // provide them (and provide the proper type, etc.).+ // Avoid that, so that all the standard fuzzing infrastructure can always+ // run the wasm.+ for (auto& global : wasm.globals) {+ if (global->imported()) {+ // Remove import info from imported globals, and give them a simple+ // initializer.+ global->module = global->base = Name();+ global->init = makeConst(global->type);+ } else {+ // If the initialization referred to an imported global, it no longer+ // can point to the same global after we make it a non-imported global+ // (as wasm doesn't allow that - you can only use an imported one).+ if (global->init->is<GlobalGet>()) {+ global->init = makeConst(global->type);+ }+ }+ } for (size_t index = upTo(MAX_GLOBALS); index > 0; --index) { auto type = getConcreteType();- auto* global =- builder.makeGlobal(std::string("global$") + std::to_string(index),+ auto global =+ builder.makeGlobal(Names::getValidGlobalName(wasm, "global$"), type, makeConst(type), Builder::Mutable);- wasm.addGlobal(global); globalsByType[type].push_back(global->name);+ wasm.addGlobal(std::move(global)); } } void setupEvents() { Index num = upTo(3); for (size_t i = 0; i < num; i++) {- auto* event =- builder.makeEvent(std::string("event$") + std::to_string(i),+ auto event =+ builder.makeEvent(Names::getValidEventName(wasm, "event$"), WASM_EVENT_ATTRIBUTE_EXCEPTION, Signature(getControlFlowType(), Type::none));- wasm.addEvent(event);+ wasm.addEvent(std::move(event)); } } + void finalizeMemory() {+ for (auto& segment : wasm.memory.segments) {+ Address maxOffset = segment.data.size();+ if (!segment.isPassive) {+ if (auto* offset = segment.offset->dynCast<GlobalGet>()) {+ // Using a non-imported global in a segment offset is not valid in+ // wasm. This can occur due to us making what used to be an imported+ // global, in initial contents, be not imported any more. To fix that,+ // replace such invalid things with a constant.+ // Note that it is still possible in theory to have imported globals+ // here, as we only do the above for initial contents. While the+ // fuzzer doesn't do so as of the time of this comment, do a check+ // for full generality, so that this code essentially does "if this+ // is invalid wasm, fix it up."+ if (!wasm.getGlobal(offset->name)->imported()) {+ // TODO: It would be better to avoid segment overlap so that+ // MemoryPacking can run.+ segment.offset =+ builder.makeConst(Literal::makeFromInt32(0, Type::i32));+ }+ }+ if (auto* offset = segment.offset->dynCast<Const>()) {+ maxOffset = maxOffset + offset->value.getInteger();+ }+ }+ wasm.memory.initial = std::max(+ wasm.memory.initial,+ Address((maxOffset + Memory::kPageSize - 1) / Memory::kPageSize));+ }+ wasm.memory.initial = std::max(wasm.memory.initial, USABLE_MEMORY);+ // Avoid an unlimited memory size, which would make fuzzing very difficult+ // as different VMs will run out of system memory in different ways.+ if (wasm.memory.max == Memory::kUnlimitedSize) {+ wasm.memory.max = wasm.memory.initial;+ }+ if (wasm.memory.max <= wasm.memory.initial) {+ // To allow growth to work (which a testcase may assume), try to make the+ // maximum larger than the initial.+ // TODO: scan the wasm for grow instructions?+ wasm.memory.max =+ std::min(Address(wasm.memory.initial + 1), Address(Memory::kMaxSize32));+ }+ // Avoid an imported memory (which the fuzz harness would need to handle).+ wasm.memory.module = wasm.memory.base = Name();+ }+ void finalizeTable() {- wasm.table.initial = wasm.table.segments[0].data.size();+ for (auto& segment : wasm.table.segments) {+ // If the offset is a global that was imported (which is ok) but no+ // longer is (not ok) we need to change that.+ if (auto* offset = segment.offset->dynCast<GlobalGet>()) {+ if (!wasm.getGlobal(offset->name)->imported()) {+ // TODO: the segments must not overlap...+ segment.offset =+ builder.makeConst(Literal::makeFromInt32(0, Type::i32));+ }+ }+ Address maxOffset = segment.data.size();+ if (auto* offset = segment.offset->dynCast<Const>()) {+ maxOffset = maxOffset + offset->value.getInteger();+ }+ wasm.table.initial = std::max(wasm.table.initial, maxOffset);+ } wasm.table.max = oneIn(2) ? Address(Table::kUnlimitedSize) : wasm.table.initial;+ // Avoid an imported table (which the fuzz harness would need to handle).+ wasm.table.module = wasm.table.base = Name(); } - const Name HANG_LIMIT_GLOBAL = "hangLimit";+ Name HANG_LIMIT_GLOBAL; + void prepareHangLimitSupport() {+ HANG_LIMIT_GLOBAL = Names::getValidGlobalName(wasm, "hangLimit");+ }+ void addHangLimitSupport() {- auto* glob = builder.makeGlobal(HANG_LIMIT_GLOBAL,- Type::i32,- builder.makeConst(int32_t(HANG_LIMIT)),- Builder::Mutable);- wasm.addGlobal(glob);+ auto glob = builder.makeGlobal(HANG_LIMIT_GLOBAL,+ Type::i32,+ builder.makeConst(int32_t(HANG_LIMIT)),+ Builder::Mutable);+ wasm.addGlobal(std::move(glob)); + Name exportName = "hangLimitInitializer";+ auto funcName = Names::getValidFunctionName(wasm, exportName); auto* func = new Function;- func->name = "hangLimitInitializer";+ func->name = funcName; func->sig = Signature(Type::none, Type::none);- func->body =- builder.makeGlobalSet(glob->name, builder.makeConst(int32_t(HANG_LIMIT)));+ func->body = builder.makeGlobalSet(HANG_LIMIT_GLOBAL,+ builder.makeConst(int32_t(HANG_LIMIT))); wasm.addFunction(func); + if (wasm.getExportOrNull(exportName)) {+ // We must export our actual hang limit function - remove anything+ // previously existing.+ wasm.removeExport(exportName);+ } auto* export_ = new Export;- export_->name = func->name;+ export_->name = exportName; export_->value = func->name; export_->kind = ExternalKind::Function; wasm.addExport(export_);@@ -496,41 +608,66 @@ // function generation state - Function* func = nullptr;- std::vector<Expression*> breakableStack; // things we can break to- Index labelIndex;+ struct FunctionCreationContext {+ TranslateToFuzzReader& parent; - // a list of things relevant to computing the odds of an infinite loop,- // which we try to minimize the risk of- std::vector<Expression*> hangStack;+ Function* func; - std::map<Type, std::vector<Index>>- typeLocals; // type => list of locals with that type+ std::vector<Expression*> breakableStack; // things we can break to+ Index labelIndex = 0; + // a list of things relevant to computing the odds of an infinite loop,+ // which we try to minimize the risk of+ std::vector<Expression*> hangStack;++ // type => list of locals with that type+ std::map<Type, std::vector<Index>> typeLocals;++ FunctionCreationContext(TranslateToFuzzReader& parent, Function* func)+ : parent(parent), func(func) {+ parent.funcContext = this;+ }++ ~FunctionCreationContext() {+ if (parent.HANG_LIMIT > 0) {+ parent.addHangLimitChecks(func);+ }+ assert(breakableStack.empty());+ assert(hangStack.empty());+ parent.funcContext = nullptr;+ }+ };++ FunctionCreationContext* funcContext = nullptr;++ Index numAddedFunctions = 0;+ Function* addFunction() { LOGGING_PERCENT = upToSquared(100);- Index num = wasm.functions.size();- func = new Function;- func->name = std::string("func_") + std::to_string(num);- assert(typeLocals.empty());+ auto* func = new Function;+ func->name = Names::getValidFunctionName(wasm, "func");+ FunctionCreationContext context(*this, func);+ assert(funcContext->typeLocals.empty()); Index numParams = upToSquared(MAX_PARAMS); std::vector<Type> params; params.reserve(numParams); for (Index i = 0; i < numParams; i++) { auto type = getSingleConcreteType();- typeLocals[type].push_back(params.size());+ funcContext->typeLocals[type].push_back(params.size()); params.push_back(type); } func->sig = Signature(Type(params), getControlFlowType()); Index numVars = upToSquared(MAX_VARS); for (Index i = 0; i < numVars; i++) { auto type = getConcreteType();- typeLocals[type].push_back(params.size() + func->vars.size());+ if (type.isRef() && !type.isNullable()) {+ // We can't use a nullable type as a var, which is null-initialized.+ continue;+ }+ funcContext->typeLocals[type].push_back(params.size() ++ func->vars.size()); func->vars.push_back(type); }- labelIndex = 0;- assert(breakableStack.empty());- assert(hangStack.empty()); // with small chance, make the body unreachable auto bodyType = func->sig.results; if (oneIn(10)) {@@ -558,15 +695,11 @@ fixLabels(func); } // Add hang limit checks after all other operations on the function body.- if (HANG_LIMIT > 0) {- addHangLimitChecks(func);- }- assert(breakableStack.empty());- assert(hangStack.empty()); wasm.addFunction(func); // export some, but not all (to allow inlining etc.). make sure to // export at least one, though, to keep each testcase interesting- if (num == 0 || oneIn(2)) {+ if ((numAddedFunctions == 0 || oneIn(2)) &&+ !wasm.getExportOrNull(func->name)) { auto* export_ = new Export; export_->name = func->name; export_->value = func->name;@@ -577,8 +710,7 @@ while (oneIn(3) && !finishedInput) { wasm.table.segments[0].data.push_back(func->name); }- // cleanup- typeLocals.clear();+ numAddedFunctions++; return func; } @@ -675,7 +807,16 @@ void visitExpression(Expression* curr) { if (parent.oneIn(10)) {- // Replace it!+ // For constants, perform only a small tweaking in some cases.+ if (auto* c = curr->dynCast<Const>()) {+ if (parent.oneIn(2)) {+ c->value = parent.tweak(c->value);+ return;+ }+ }+ // TODO: more minor tweaks to immediates, like making a load atomic or+ // not, changing an offset, etc.+ // Perform a general replacement. // (This is not always valid due to nesting of labels, but // we'll fix that up later.) replaceCurrent(parent.make(curr->type));@@ -774,10 +915,83 @@ ReFinalize().walkFunctionInModule(func, &wasm); } + void modifyInitialFunctions() {+ if (wasm.functions.empty()) {+ return;+ }+ // Pick a chance to fuzz the contents of a function.+ const int RESOLUTION = 10;+ auto chance = upTo(RESOLUTION + 1);+ for (auto& ref : wasm.functions) {+ auto* func = ref.get();+ FunctionCreationContext context(*this, func);+ if (func->imported()) {+ // We can't allow extra imports, as the fuzzing infrastructure wouldn't+ // know what to provide.+ func->module = func->base = Name();+ func->body = make(func->sig.results);+ }+ // Optionally, fuzz the function contents.+ if (upTo(RESOLUTION) >= chance) {+ dropToLog(func);+ // TODO add some locals? and the rest of addFunction's operations?+ // TODO: interposition, replace initial a(b) with a(RANDOM_THING(b))+ // TODO: if we add OOB checks after creation, then we can do it on+ // initial contents too, and it may be nice to *not* run these+ // passes, like we don't run them on new functions. But, we may+ // still want to run them some of the time, at least, so that we+ // check variations on initial testcases even at the risk of OOB.+ recombine(func);+ mutate(func);+ fixLabels(func);+ }+ }+ // Remove a start function - the fuzzing harness expects code to run only+ // from exports.+ wasm.start = Name();+ }++ // Initial wasm contents may have come from a test that uses the drop pattern:+ //+ // (drop ..something interesting..)+ //+ // The dropped interesting thing is optimized to some other interesting thing+ // by a pass, and we verify it is the expected one. But this does not use the+ // value in a way the fuzzer can notice. Replace some drops with a logging+ // operation instead.+ void dropToLog(Function* func) {+ // Don't always do this.+ if (oneIn(2)) {+ return;+ }+ struct Modder : public PostWalker<Modder> {+ Module& wasm;+ TranslateToFuzzReader& parent;++ Modder(Module& wasm, TranslateToFuzzReader& parent)+ : wasm(wasm), parent(parent) {}++ void visitDrop(Drop* curr) {+ if (parent.isLoggableType(curr->value->type) && parent.oneIn(2)) {+ replaceCurrent(parent.builder.makeCall(std::string("log-") ++ curr->value->type.toString(),+ {curr->value},+ Type::none));+ }+ }+ };+ Modder modder(wasm, *this);+ modder.walk(func->body);+ }+ // the fuzzer external interface sends in zeros (simpler to compare // across invocations from JS or wasm-opt etc.). Add invocations in // the wasm, so they run everywhere void addInvocations(Function* func) {+ Name name = func->name.str + std::string("_invoker");+ if (wasm.getFunctionOrNull(name) || wasm.getExportOrNull(name)) {+ return;+ } std::vector<Expression*> invocations; while (oneIn(2) && !finishedInput) { std::vector<Expression*> args;@@ -799,19 +1013,19 @@ return; } auto* invoker = new Function;- invoker->name = func->name.str + std::string("_invoker");+ invoker->name = name; invoker->sig = Signature(Type::none, Type::none); invoker->body = builder.makeBlock(invocations); wasm.addFunction(invoker); auto* export_ = new Export;- export_->name = invoker->name;- export_->value = invoker->name;+ export_->name = name;+ export_->value = name; export_->kind = ExternalKind::Function; wasm.addExport(export_); } Name makeLabel() {- return std::string("label$") + std::to_string(labelIndex++);+ return std::string("label$") + std::to_string(funcContext->labelIndex++); } // Weighting for the core make* methods. Some nodes are important enough that@@ -870,13 +1084,16 @@ WeightedOption{&Self::makeGlobalGet, Important}, WeightedOption{&Self::makeConst, Important}); if (canMakeControlFlow) {- options.add(FeatureSet::MVP,- WeightedOption{&Self::makeBlock, Important},- WeightedOption{&Self::makeIf, Important},- WeightedOption{&Self::makeLoop, Important},- WeightedOption{&Self::makeBreak, Important},- &Self::makeCall,- &Self::makeCallIndirect);+ options+ .add(FeatureSet::MVP,+ WeightedOption{&Self::makeBlock, Important},+ WeightedOption{&Self::makeIf, Important},+ WeightedOption{&Self::makeLoop, Important},+ WeightedOption{&Self::makeBreak, Important},+ &Self::makeCall,+ &Self::makeCallIndirect)+ .add(FeatureSet::TypedFunctionReferences | FeatureSet::ReferenceTypes,+ &Self::makeCallRef); } if (type.isSingle()) { options@@ -906,6 +1123,7 @@ options.add(FeatureSet::ReferenceTypes | FeatureSet::GC, &Self::makeI31New); }+ // TODO: struct.get and other GC things return (this->*pick(options))(type); } @@ -935,7 +1153,9 @@ &Self::makeNop, &Self::makeGlobalSet) .add(FeatureSet::BulkMemory, &Self::makeBulkMemory)- .add(FeatureSet::Atomics, &Self::makeAtomic);+ .add(FeatureSet::Atomics, &Self::makeAtomic)+ .add(FeatureSet::TypedFunctionReferences | FeatureSet::ReferenceTypes,+ &Self::makeCallRef); return (this->*pick(options))(Type::none); } @@ -943,22 +1163,25 @@ using Self = TranslateToFuzzReader; auto options = FeatureOptions<Expression* (Self::*)(Type)>(); using WeightedOption = decltype(options)::WeightedOption;- options.add(FeatureSet::MVP,- WeightedOption{&Self::makeLocalSet, VeryImportant},- WeightedOption{&Self::makeBlock, Important},- WeightedOption{&Self::makeIf, Important},- WeightedOption{&Self::makeLoop, Important},- WeightedOption{&Self::makeBreak, Important},- WeightedOption{&Self::makeStore, Important},- WeightedOption{&Self::makeUnary, Important},- WeightedOption{&Self::makeBinary, Important},- WeightedOption{&Self::makeUnreachable, Important},- &Self::makeCall,- &Self::makeCallIndirect,- &Self::makeSelect,- &Self::makeSwitch,- &Self::makeDrop,- &Self::makeReturn);+ options+ .add(FeatureSet::MVP,+ WeightedOption{&Self::makeLocalSet, VeryImportant},+ WeightedOption{&Self::makeBlock, Important},+ WeightedOption{&Self::makeIf, Important},+ WeightedOption{&Self::makeLoop, Important},+ WeightedOption{&Self::makeBreak, Important},+ WeightedOption{&Self::makeStore, Important},+ WeightedOption{&Self::makeUnary, Important},+ WeightedOption{&Self::makeBinary, Important},+ WeightedOption{&Self::makeUnreachable, Important},+ &Self::makeCall,+ &Self::makeCallIndirect,+ &Self::makeSelect,+ &Self::makeSwitch,+ &Self::makeDrop,+ &Self::makeReturn)+ .add(FeatureSet::TypedFunctionReferences | FeatureSet::ReferenceTypes,+ &Self::makeCallRef); return (this->*pick(options))(Type::unreachable); } @@ -975,8 +1198,8 @@ } assert(type == Type::unreachable); Expression* ret = nullptr;- if (func->sig.results.isConcrete()) {- ret = makeTrivial(func->sig.results);+ if (funcContext->func->sig.results.isConcrete()) {+ ret = makeTrivial(funcContext->func->sig.results); } return builder.makeReturn(ret); }@@ -987,7 +1210,7 @@ auto* ret = builder.makeBlock(); ret->type = type; // so we have it during child creation ret->name = makeLabel();- breakableStack.push_back(ret);+ funcContext->breakableStack.push_back(ret); Index num = upToSquared(BLOCK_FACTOR - 1); // we add another later if (nesting >= NESTING_LIMIT / 2) { // smaller blocks past the limit@@ -1012,7 +1235,7 @@ } else { ret->list.push_back(make(type)); }- breakableStack.pop_back();+ funcContext->breakableStack.pop_back(); if (type.isConcrete()) { ret->finalize(type); } else {@@ -1030,8 +1253,8 @@ auto* ret = wasm.allocator.alloc<Loop>(); ret->type = type; // so we have it during child creation ret->name = makeLabel();- breakableStack.push_back(ret);- hangStack.push_back(ret);+ funcContext->breakableStack.push_back(ret);+ funcContext->hangStack.push_back(ret); // either create random content, or do something more targeted if (oneIn(2)) { ret->body = makeMaybeBlock(type);@@ -1044,8 +1267,8 @@ list.push_back(make(type)); // final element, so we have the right type ret->body = builder.makeBlock(list, type); }- breakableStack.pop_back();- hangStack.pop_back();+ funcContext->breakableStack.pop_back();+ funcContext->hangStack.pop_back(); ret->finalize(type); return ret; }@@ -1077,26 +1300,26 @@ Expression* makeIf(Type type) { auto* condition = makeCondition();- hangStack.push_back(nullptr);+ funcContext->hangStack.push_back(nullptr); auto* ret = buildIf({condition, makeMaybeBlock(type), makeMaybeBlock(type)}, type);- hangStack.pop_back();+ funcContext->hangStack.pop_back(); return ret; } Expression* makeBreak(Type type) {- if (breakableStack.empty()) {+ if (funcContext->breakableStack.empty()) { return makeTrivial(type); } Expression* condition = nullptr; if (type != Type::unreachable) {- hangStack.push_back(nullptr);+ funcContext->hangStack.push_back(nullptr); condition = makeCondition(); } // we need to find a proper target to break to; try a few times int tries = TRIES; while (tries-- > 0) {- auto* target = pick(breakableStack);+ auto* target = pick(funcContext->breakableStack); auto name = getTargetName(target); auto valueType = getTargetType(target); if (type.isConcrete()) {@@ -1106,7 +1329,7 @@ continue; } auto* ret = builder.makeBreak(name, make(type), condition);- hangStack.pop_back();+ funcContext->hangStack.pop_back(); return ret; } else if (type == Type::none) { if (valueType != Type::none) {@@ -1114,7 +1337,7 @@ continue; } auto* ret = builder.makeBreak(name, nullptr, condition);- hangStack.pop_back();+ funcContext->hangStack.pop_back(); return ret; } else { assert(type == Type::unreachable);@@ -1126,9 +1349,9 @@ // to a loop, we prefer there to be a condition along the // way, to reduce the chance of infinite looping size_t conditions = 0;- int i = hangStack.size();+ int i = funcContext->hangStack.size(); while (--i >= 0) {- auto* item = hangStack[i];+ auto* item = funcContext->hangStack[i]; if (item == nullptr) { conditions++; } else if (auto* loop = item->cast<Loop>()) {@@ -1162,22 +1385,21 @@ } // we failed to find something if (type != Type::unreachable) {- hangStack.pop_back();+ funcContext->hangStack.pop_back(); } return makeTrivial(type); } Expression* makeCall(Type type) {- // seems ok, go on int tries = TRIES; bool isReturn; while (tries-- > 0) {- Function* target = func;+ Function* target = funcContext->func; if (!wasm.functions.empty() && !oneIn(wasm.functions.size())) { target = pick(wasm.functions).get(); } isReturn = type == Type::unreachable && wasm.features.hasTailCall() &&- func->sig.results == target->sig.results;+ funcContext->func->sig.results == target->sig.results; if (target->sig.results != type && !isReturn) { continue; }@@ -1189,7 +1411,7 @@ return builder.makeCall(target->name, args, type, isReturn); } // we failed to find something- return make(type);+ return makeTrivial(type); } Expression* makeCallIndirect(Type type) {@@ -1206,7 +1428,7 @@ // TODO: handle unreachable targetFn = wasm.getFunction(data[i]); isReturn = type == Type::unreachable && wasm.features.hasTailCall() &&- func->sig.results == targetFn->sig.results;+ funcContext->func->sig.results == targetFn->sig.results; if (targetFn->sig.results == type || isReturn) { break; }@@ -1215,7 +1437,7 @@ i = 0; } if (i == start) {- return make(type);+ return makeTrivial(type); } } // with high probability, make sure the type is valid otherwise, most are@@ -1233,8 +1455,37 @@ return builder.makeCallIndirect(target, args, targetFn->sig, isReturn); } + Expression* makeCallRef(Type type) {+ // look for a call target with the right type+ Function* target;+ bool isReturn;+ size_t i = 0;+ while (1) {+ if (i == TRIES || wasm.functions.empty()) {+ // We can't find a proper target, give up.+ return makeTrivial(type);+ }+ // TODO: handle unreachable+ target = wasm.functions[upTo(wasm.functions.size())].get();+ isReturn = type == Type::unreachable && wasm.features.hasTailCall() &&+ funcContext->func->sig.results == target->sig.results;+ if (target->sig.results == type || isReturn) {+ break;+ }+ i++;+ }+ std::vector<Expression*> args;+ for (const auto& type : target->sig.params) {+ args.push_back(make(type));+ }+ auto targetType = Type(HeapType(target->sig), Nullable);+ // TODO: half the time make a completely random item with that type.+ return builder.makeCallRef(+ builder.makeRefFunc(target->name, targetType), args, type, isReturn);+ }+ Expression* makeLocalGet(Type type) {- auto& locals = typeLocals[type];+ auto& locals = funcContext->typeLocals[type]; if (locals.empty()) { return makeConst(type); }@@ -1249,7 +1500,7 @@ } else { valueType = getConcreteType(); }- auto& locals = typeLocals[valueType];+ auto& locals = funcContext->typeLocals[valueType]; if (locals.empty()) { return makeTrivial(type); }@@ -1536,6 +1787,43 @@ return store; } + // Makes a small change to a constant value.+ Literal tweak(Literal value) {+ auto type = value.type;+ if (type.isVector()) {+ // TODO: tweak each lane?+ return value;+ }+ // +- 1+ switch (upTo(5)) {+ case 0:+ value = value.add(Literal::makeNegOne(type));+ break;+ case 1:+ value = value.add(Literal::makeOne(type));+ break;+ default: {+ }+ }+ // For floats, optionally add a non-integer adjustment in +- [-1, 1]+ if (type.isFloat() && oneIn(2)) {+ const int RANGE = 1000;+ auto RANGE_LITERAL = Literal::makeFromInt32(RANGE, type);+ // adjustment -> [0, 2 * RANGE]+ auto adjustment = Literal::makeFromInt32(upTo(2 * RANGE + 1), type);+ // adjustment -> [-RANGE, RANGE]+ adjustment = adjustment.sub(RANGE_LITERAL);+ // adjustment -> [-1, 1]+ adjustment = adjustment.div(RANGE_LITERAL);+ value = value.add(adjustment);+ }+ // Flip sign.+ if (oneIn(2)) {+ value = value.mul(Literal::makeNegOne(type));+ }+ return value;+ }+ Literal makeLiteral(Type type) { if (type == Type::v128) { // generate each lane individually for random lane interpretation@@ -1587,38 +1875,6 @@ } } - // Optional tweaking of the value by a small adjustment.- auto tweak = [this, type](Literal value) {- // +- 1- switch (upTo(5)) {- case 0:- value = value.add(Literal::makeNegOne(type));- break;- case 1:- value = value.add(Literal::makeOne(type));- break;- default: {- }- }- // For floats, optionally add a non-integer adjustment in +- [-1, 1]- if (type.isFloat() && oneIn(2)) {- const int RANGE = 1000;- auto RANGE_LITERAL = Literal::makeFromInt32(RANGE, type);- // adjustment -> [0, 2 * RANGE]- auto adjustment = Literal::makeFromInt32(upTo(2 * RANGE + 1), type);- // adjustment -> [-RANGE, RANGE]- adjustment = adjustment.sub(RANGE_LITERAL);- // adjustment -> [-1, 1]- adjustment = adjustment.div(RANGE_LITERAL);- value = value.add(adjustment);- }- // Flip sign.- if (oneIn(2)) {- value = value.mul(Literal::makeNegOne(type));- }- return value;- };- switch (upTo(4)) { case 0: { // totally random, entire range@@ -1803,19 +2059,41 @@ // 'func' is the pointer to the last created function and can be null when // we set up globals (before we create any functions), in which case we // can't use ref.func.- if (type == Type::funcref && func && oneIn(2)) {+ if (type == Type::funcref && funcContext && oneIn(2)) { // First set to target to the last created function, and try to select // among other existing function if possible- Function* target = func;+ Function* target = funcContext->func; if (!wasm.functions.empty() && !oneIn(wasm.functions.size())) { target = pick(wasm.functions).get(); }- return builder.makeRefFunc(target->name);+ auto type = Type(HeapType(target->sig), Nullable);+ return builder.makeRefFunc(target->name, type); } if (type == Type::i31ref) { return builder.makeI31New(makeConst(Type::i32)); }- return builder.makeRefNull(type);+ if (oneIn(2) && type.isNullable()) {+ return builder.makeRefNull(type);+ }+ // TODO: randomize the order+ for (auto& func : wasm.functions) {+ // FIXME: RefFunc type should be non-nullable, but we emit nullable+ // types for now.+ if (type == Type(HeapType(func->sig), Nullable)) {+ return builder.makeRefFunc(func->name, type);+ }+ }+ // We failed to find a function, so create a null reference if we can.+ if (type.isNullable()) {+ return builder.makeRefNull(type);+ }+ // Last resort: create a function.+ auto* func = wasm.addFunction(builder.makeFunction(+ Names::getValidFunctionName(wasm, "ref_func_target"),+ type.getHeapType().getSignature(),+ {},+ builder.makeUnreachable()));+ return builder.makeRefFunc(func->name, type); } if (type.isTuple()) { std::vector<Expression*> operands;@@ -1890,9 +2168,7 @@ AnyTrueVecI16x8, AllTrueVecI16x8, AnyTrueVecI32x4,- AllTrueVecI32x4,- AnyTrueVecI64x2,- AllTrueVecI64x2),+ AllTrueVecI32x4), make(Type::v128)}); } case Type::funcref:@@ -2012,6 +2288,7 @@ return buildUnary({SplatVecF64x2, make(Type::f64)}); case 4: return buildUnary({pick(NotVec128,+ // TODO: i8x16.popcnt once merged NegVecI8x16, NegVecI16x8, NegVecI32x4,@@ -2240,6 +2517,9 @@ MinUVecI8x16, MaxSVecI8x16, MaxUVecI8x16,+ // TODO: avgr_u+ // TODO: q15mulr_sat_s+ // TODO: extmul AddVecI16x8, AddSatSVecI16x8, AddSatUVecI16x8,@@ -2306,7 +2586,7 @@ Expression* makeSwitch(Type type) { assert(type == Type::unreachable);- if (breakableStack.empty()) {+ if (funcContext->breakableStack.empty()) { return make(type); } // we need to find proper targets to break to; try a bunch@@ -2314,7 +2594,7 @@ std::vector<Name> names; Type valueType = Type::unreachable; while (tries-- > 0) {- auto* target = pick(breakableStack);+ auto* target = pick(funcContext->breakableStack); auto name = getTargetName(target); auto currValueType = getTargetType(target); if (names.empty()) {@@ -2343,8 +2623,9 @@ } Expression* makeReturn(Type type) {- return builder.makeReturn(- func->sig.results.isConcrete() ? make(func->sig.results) : nullptr);+ return builder.makeReturn(funcContext->func->sig.results.isConcrete()+ ? make(funcContext->func->sig.results)+ : nullptr); } Expression* makeNop(Type type) {@@ -2424,17 +2705,13 @@ auto* ptr = makePointer(); if (oneIn(2)) { auto* value = make(type);- return builder.makeAtomicRMW(pick(AtomicRMWOp::Add,- AtomicRMWOp::Sub,- AtomicRMWOp::And,- AtomicRMWOp::Or,- AtomicRMWOp::Xor,- AtomicRMWOp::Xchg),- bytes,- offset,- ptr,- value,- type);+ return builder.makeAtomicRMW(+ pick(RMWAdd, RMWSub, RMWAnd, RMWOr, RMWXor, RMWXchg),+ bytes,+ offset,+ ptr,+ value,+ type); } else { auto* expected = make(type); auto* replacement = make(type);@@ -2451,6 +2728,7 @@ if (type != Type::v128) { return makeSIMDExtract(type); }+ // TODO: Add SIMDLoadStoreLane once it is generally available switch (upTo(7)) { case 0: return makeUnary(Type::v128);@@ -2762,6 +3040,7 @@ Type::anyref, Type::eqref, Type::i31ref));+ // TODO: emit typed function references types } Type getSingleConcreteType() { return pick(getSingleConcreteTypes()); }@@ -2787,12 +3066,24 @@ Type getEqReferenceType() { return pick(getEqReferenceTypes()); } + Type getMVPType() {+ return pick(items(FeatureOptions<Type>().add(+ FeatureSet::MVP, Type::i32, Type::i64, Type::f32, Type::f64)));+ }+ Type getTupleType() { std::vector<Type> elements;- size_t numElements = 2 + upTo(MAX_TUPLE_SIZE - 1);- elements.resize(numElements);- for (size_t i = 0; i < numElements; ++i) {- elements[i] = getSingleConcreteType();+ size_t maxElements = 2 + upTo(MAX_TUPLE_SIZE - 1);+ for (size_t i = 0; i < maxElements; ++i) {+ auto type = getSingleConcreteType();+ // Don't add a non-nullable type into a tuple, as currently we can't spill+ // them into locals (that would require a "let").+ if (!type.isNullable()) {+ elements.push_back(type);+ }+ }+ while (elements.size() < 2) {+ elements.push_back(getMVPType()); } return Type(elements); }
binaryen/src/tools/optimization-options.h view
@@ -193,7 +193,14 @@ "-ffm", "Optimize floats without handling corner cases of NaNs and rounding", Options::Arguments::Zero,- [this](Options*, const std::string&) { passOptions.fastMath = true; });+ [this](Options*, const std::string&) { passOptions.fastMath = true; })+ .add("--zero-filled-memory",+ "-uim",+ "Assume that an imported memory will be zero-initialized",+ Options::Arguments::Zero,+ [this](Options*, const std::string&) {+ passOptions.zeroFilledMemory = true;+ }); // add passes in registry for (const auto& p : PassRegistry::get()->getRegisteredNames()) { (*this).add(
binaryen/src/tools/tool-options.h view
@@ -89,6 +89,8 @@ .addFeature(FeatureSet::Multivalue, "multivalue functions") .addFeature(FeatureSet::GC, "garbage collection") .addFeature(FeatureSet::Memory64, "memory64")+ .addFeature(FeatureSet::TypedFunctionReferences,+ "typed function references") .add("--no-validation", "-n", "Disables validation, assumes inputs are correct",@@ -140,7 +142,7 @@ return *this; } - void applyFeatures(Module& module) {+ void applyFeatures(Module& module) const { if (hasFeatureOptions) { if (!detectFeatures && module.hasFeaturesSection) { FeatureSet optionsFeatures = FeatureSet::MVP;
binaryen/src/tools/wasm-ctor-eval.cpp view
@@ -24,6 +24,7 @@ #include <memory> +#include "asmjs/shared-constants.h" #include "ir/global-utils.h" #include "ir/import-utils.h" #include "ir/literal-utils.h"@@ -465,7 +466,7 @@ options.applyFeatures(wasm); if (!WasmValidator().validate(wasm)) {- WasmPrinter::printModule(&wasm);+ std::cout << wasm << '\n'; Fatal() << "error in validating input"; }
binaryen/src/tools/wasm-dis.cpp view
@@ -22,7 +22,6 @@ #include "support/command-line.h" #include "support/file.h" #include "wasm-io.h"-#include "wasm-printing.h" using namespace cashew; using namespace wasm;@@ -76,8 +75,7 @@ std::cerr << "Printing..." << std::endl; } Output output(options.extra["output"], Flags::Text);- WasmPrinter::printModule(&wasm, output.getStream());- output << '\n';+ output.getStream() << wasm << '\n'; if (options.debug) { std::cerr << "Done." << std::endl;
binaryen/src/tools/wasm-emscripten-finalize.cpp view
@@ -30,7 +30,6 @@ #include "wasm-binary.h" #include "wasm-emscripten.h" #include "wasm-io.h"-#include "wasm-printing.h" #include "wasm-validator.h" #define DEBUG_TYPE "emscripten"@@ -51,7 +50,6 @@ bool debugInfo = false; bool DWARF = false; bool sideModule = false;- bool legacyPIC = true; bool legalizeJavaScriptFFI = true; bool bigInt = false; bool checkStackOverflow = false;@@ -114,9 +112,7 @@ "", "Use new/llvm PIC abi", Options::Arguments::Zero,- [&legacyPIC](Options* o, const std::string& argument) {- legacyPIC = false;- })+ [&](Options* o, const std::string& argument) {}) .add("--input-source-map", "-ism", "Consume source map from the specified file",@@ -225,32 +221,7 @@ options.applyFeatures(wasm); BYN_TRACE_WITH_TYPE("emscripten-dump", "Module before:\n");- BYN_DEBUG_WITH_TYPE("emscripten-dump",- WasmPrinter::printModule(&wasm, std::cerr));-- uint32_t dataSize = 0;-- if (!sideModule) {- if (globalBase == INVALID_BASE) {- Fatal() << "globalBase must be set";- }- Export* dataEndExport = wasm.getExport("__data_end");- if (dataEndExport == nullptr) {- Fatal() << "__data_end export not found";- }- Global* dataEnd = wasm.getGlobal(dataEndExport->value);- if (dataEnd == nullptr) {- Fatal() << "__data_end global not found";- }- if (dataEnd->type != Type::i32) {- Fatal() << "__data_end global has wrong type";- }- if (dataEnd->imported()) {- Fatal() << "__data_end must not be an imported global";- }- Const* dataEndConst = dataEnd->init->cast<Const>();- dataSize = dataEndConst->value.geti32() - globalBase;- }+ BYN_DEBUG_WITH_TYPE("emscripten-dump", std::cerr << &wasm); EmscriptenGlueGenerator generator(wasm); generator.standalone = standaloneWasm;@@ -259,14 +230,7 @@ generator.onlyI64DynCalls = onlyI64DynCalls; generator.noDynCalls = noDynCalls; - std::vector<Name> initializerFunctions;-- // The wasm backend emits "__indirect_function_table" as the import name for- // the table, while older emscripten expects "table"- if (wasm.table.imported() && !minimizeWasmChanges) {- wasm.table.base = Name("table");- }- wasm.updateMaps();+ Name initializerFunction; if (!standaloneWasm) { // This is also not needed in standalone mode since standalone mode uses@@ -278,7 +242,7 @@ passRunner.setDebug(options.debug); passRunner.setDebugInfo(debugInfo); - if (checkStackOverflow && !sideModule) {+ if (checkStackOverflow) { if (!standaloneWasm) { // In standalone mode we don't set a handler at all.. which means // just trap on overflow.@@ -288,18 +252,6 @@ passRunner.add("stack-check"); } - if (sideModule) {- passRunner.add("replace-stack-pointer");- }-- if (legacyPIC) {- if (sideModule) {- passRunner.add("emscripten-pic");- } else {- passRunner.add("emscripten-pic-main-module");- }- }- if (!noDynCalls && !standaloneWasm) { // If not standalone wasm then JS is relevant and we need dynCalls. if (onlyI64DynCalls) {@@ -329,24 +281,18 @@ if (sideModule) { BYN_TRACE("finalizing as side module\n");- generator.generatePostInstantiateFunction();+ // The emscripten PIC ABI still expects a function named+ // __post_instantiate to be exported by side module.+ if (auto* e = wasm.getExportOrNull(WASM_CALL_CTORS)) {+ e->name = "__post_instantiate";+ } } else { BYN_TRACE("finalizing as regular module\n");- generator.internalizeStackPointerGlobal();- // For side modules these gets called via __post_instantiate- if (Function* F = wasm.getFunctionOrNull(ASSIGN_GOT_ENTRIES)) {- auto* ex = new Export();- ex->value = F->name;- ex->name = F->name;- ex->kind = ExternalKind::Function;- wasm.addExport(ex);- initializerFunctions.push_back(F->name);- } // Costructors get called from crt1 in wasm standalone mode. // Unless there is no entry point. if (!standaloneWasm || !wasm.getExportOrNull("_start")) { if (auto* e = wasm.getExportOrNull(WASM_CALL_CTORS)) {- initializerFunctions.push_back(e->name);+ initializerFunction = e->name; } } }@@ -354,7 +300,7 @@ BYN_TRACE("generated metadata\n"); // Substantial changes to the wasm are done, enough to create the metadata. std::string metadata =- generator.generateEmscriptenMetadata(dataSize, initializerFunctions);+ generator.generateEmscriptenMetadata(initializerFunction); // Finally, separate out data segments if relevant (they may have been needed // for metadata).@@ -367,8 +313,7 @@ } BYN_TRACE_WITH_TYPE("emscripten-dump", "Module after:\n");- BYN_DEBUG_WITH_TYPE("emscripten-dump",- WasmPrinter::printModule(&wasm, std::cerr));+ BYN_DEBUG_WITH_TYPE("emscripten-dump", std::cerr << wasm << '\n'); // Write the modified wasm if the user asked us to, either by specifying an // output file, or requesting text output (which goes to stdout by default).
binaryen/src/tools/wasm-metadce.cpp view
@@ -511,7 +511,7 @@ if (options.passOptions.validate) { if (!WasmValidator().validate(wasm)) {- WasmPrinter::printModule(&wasm);+ std::cout << wasm << '\n'; Fatal() << "error in validating input"; } }
binaryen/src/tools/wasm-opt.cpp view
@@ -34,7 +34,6 @@ #include "wasm-binary.h" #include "wasm-interpreter.h" #include "wasm-io.h"-#include "wasm-printing.h" #include "wasm-s-parser.h" #include "wasm-validator.h" #include "wasm2c-wrapper.h"@@ -81,6 +80,7 @@ bool fuzzExecAfter = false; std::string extraFuzzCommand; bool translateToFuzz = false;+ std::string initialFuzz; bool fuzzPasses = false; bool fuzzMemory = true; bool fuzzOOB = true;@@ -141,6 +141,13 @@ "fuzzing", Options::Arguments::Zero, [&](Options* o, const std::string& arguments) { translateToFuzz = true; })+ .add("--initial-fuzz",+ "-if",+ "Initial wasm content in translate-to-fuzz (-ttf) mode",+ Options::Arguments::One,+ [&initialFuzz](Options* o, const std::string& argument) {+ initialFuzz = argument;+ }) .add("--fuzz-passes", "-fp", "Pick a random set of passes to run, useful for fuzzing. this depends "@@ -219,12 +226,18 @@ // to print would not be reached). if (std::find(options.passes.begin(), options.passes.end(), "print") != options.passes.end()) {- WasmPrinter::printModule(&wasm);+ std::cout << wasm << '\n'; } Fatal() << message; }; - if (!translateToFuzz) {+ // In normal (non-translate-to-fuzz) mode we read the input file. In+ // translate-to-fuzz mode the input file is the random data, and used later+ // down in TranslateToFuzzReader, but there is also an optional initial fuzz+ // file that if it exists we read it, then add more fuzz on top.+ if (!translateToFuzz || initialFuzz.size()) {+ std::string inputFile =+ translateToFuzz ? initialFuzz : options.extra["infile"]; ModuleReader reader; // Enable DWARF parsing if we were asked for debug info, and were not // asked to remove it.@@ -232,7 +245,7 @@ !willRemoveDebugInfo(options.passes)); reader.setProfile(options.profile); try {- reader.read(options.extra["infile"], wasm, inputSourceMapFilename);+ reader.read(inputFile, wasm, inputSourceMapFilename); } catch (ParseException& p) { p.dump(std::cerr); std::cerr << '\n';@@ -253,8 +266,8 @@ exitOnInvalidWasm("error validating input"); } }- } else {- // translate-to-fuzz+ }+ if (translateToFuzz) { options.applyFeatures(wasm); TranslateToFuzzReader reader(wasm, options.extra["infile"]); if (fuzzPasses) {@@ -265,7 +278,7 @@ reader.build(); if (options.passOptions.validate) { if (!WasmValidator().validate(wasm)) {- WasmPrinter::printModule(&wasm);+ std::cout << wasm << '\n'; Fatal() << "error after translate-to-fuzz"; } }
binaryen/src/tools/wasm-reduce.cpp view
@@ -287,7 +287,9 @@ currCommand += " -g "; } if (!binary) {- currCommand += " -S ";+ currCommand += " -S --all-features ";+ } else {+ currCommand += " --detect-features "; } if (verbose) { std::cerr << "| trying pass command: " << currCommand << "\n";@@ -578,7 +580,10 @@ continue; // no conversion } Expression* fixed = nullptr;- TODO_SINGLE_COMPOUND(curr->type);+ if (!curr->type.isBasic() || !child->type.isBasic()) {+ // TODO: handle compound types+ continue;+ } switch (curr->type.getBasic()) { case Type::i32: { TODO_SINGLE_COMPOUND(child->type);@@ -937,6 +942,11 @@ replaceCurrent(Builder(*getModule()).replaceWithIdenticalType(curr)); } }+ void visitRefFunc(RefFunc* curr) {+ if (names.count(curr->func)) {+ replaceCurrent(Builder(*getModule()).replaceWithIdenticalType(curr));+ }+ } void visitExport(Export* curr) { if (names.count(curr->value)) { exportsToRemove.push_back(curr->name);@@ -1034,7 +1044,12 @@ builder->makeConstantExpression(Literal::makeZeros(curr->type)); return tryToReplaceCurrent(n); }- Const* c = builder->makeConst(int32_t(0));+ if (!curr->type.isNumber()) {+ return false;+ }+ // It's a number: try to replace it with a 0 or a 1 (trying more values+ // could make sense too, but these handle most cases).+ auto* c = builder->makeConst(Literal::makeZero(curr->type)); if (tryToReplaceCurrent(c)) { return true; }@@ -1204,10 +1219,12 @@ "(read-written) binary\n"; { // read and write it- auto cmd = Path::getBinaryenBinaryTool("wasm-opt") + " " + input +- " --detect-features -o " + test;+ auto cmd =+ Path::getBinaryenBinaryTool("wasm-opt") + " " + input + " -o " + test; if (!binary) {- cmd += " -S";+ cmd += " -S --all-features";+ } else {+ cmd += " --detect-features"; } ProgramResult readWrite(cmd); if (readWrite.failed()) {
binaryen/src/tools/wasm-shell.cpp view
@@ -28,7 +28,6 @@ #include "support/command-line.h" #include "support/file.h" #include "wasm-interpreter.h"-#include "wasm-printing.h" #include "wasm-s-parser.h" #include "wasm-validator.h" @@ -311,7 +310,7 @@ modules[moduleName]->features = FeatureSet::All; bool valid = WasmValidator().validate(*modules[moduleName]); if (!valid) {- WasmPrinter::printModule(modules[moduleName].get());+ std::cout << *modules[moduleName] << '\n'; Fatal() << "module failed to validate, see above"; } run_asserts(moduleName,
+ binaryen/src/tools/wasm-split.cpp view
@@ -0,0 +1,671 @@+/*+ * Copyright 2020 WebAssembly Community Group participants+ *+ * Licensed under the Apache License, Version 2.0 (the "License");+ * you may not use this file except in compliance with the License.+ * You may obtain a copy of the License at+ *+ * http://www.apache.org/licenses/LICENSE-2.0+ *+ * Unless required by applicable law or agreed to in writing, software+ * distributed under the License is distributed on an "AS IS" BASIS,+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+ * See the License for the specific language governing permissions and+ * limitations under the License.+ */++// wasm-split: Split a module in two or instrument a module to inform future+// splitting.++#include "ir/module-splitting.h"+#include "ir/module-utils.h"+#include "ir/names.h"+#include "support/file.h"+#include "support/name.h"+#include "support/utilities.h"+#include "tool-options.h"+#include "wasm-builder.h"+#include "wasm-io.h"+#include "wasm-type.h"+#include "wasm-validator.h"+#include <sstream>++using namespace wasm;++namespace {++const std::string DEFAULT_PROFILE_EXPORT("__write_profile");++std::set<Name> parseNameList(const std::string& list) {+ std::set<Name> names;+ std::istringstream stream(list);+ for (std::string name; std::getline(stream, name, ',');) {+ names.insert(name);+ }+ return names;+}++struct WasmSplitOptions : ToolOptions {+ bool verbose = false;+ bool emitBinary = true;++ bool instrument = false;++ std::string profileFile;+ std::string profileExport = DEFAULT_PROFILE_EXPORT;++ std::set<Name> keepFuncs;+ std::set<Name> splitFuncs;++ std::string input;+ std::string output;+ std::string primaryOutput;+ std::string secondaryOutput;++ std::string importNamespace;+ std::string placeholderNamespace;+ std::string exportPrefix;++ // A hack to ensure the split and instrumented modules have the same table+ // size when using Emscripten's SPLIT_MODULE mode with dynamic linking. TODO:+ // Figure out a more elegant solution for that use case and remove this.+ int initialTableSize = -1;++ WasmSplitOptions();+ bool validate();+ void parse(int argc, const char* argv[]);+};++WasmSplitOptions::WasmSplitOptions()+ : ToolOptions("wasm-split",+ "Split a module into a primary module and a secondary "+ "module or instrument a module to gather a profile that "+ "can inform future splitting.") {+ (*this)+ .add("--instrument",+ "",+ "Instrument the module to generate a profile that can be used to "+ "guide splitting",+ Options::Arguments::Zero,+ [&](Options* o, const std::string& argument) { instrument = true; })+ .add(+ "--profile",+ "",+ "The profile to use to guide splitting. May not be used with "+ "--instrument.",+ Options::Arguments::One,+ [&](Options* o, const std::string& argument) { profileFile = argument; })+ .add("--profile-export",+ "",+ "The export name of the function the embedder calls to write the "+ "profile into memory. Defaults to `__write_profile`. Must be used "+ "with --instrument.",+ Options::Arguments::One,+ [&](Options* o, const std::string& argument) {+ profileExport = argument;+ })+ .add("--keep-funcs",+ "",+ "Comma-separated list of functions to keep in the primary module, "+ "regardless of any profile.",+ Options::Arguments::One,+ [&](Options* o, const std::string& argument) {+ keepFuncs = parseNameList(argument);+ })+ .add("--split-funcs",+ "",+ "Comma-separated list of functions to split into the secondary "+ "module, regardless of any profile. If there is no profile, then "+ "this defaults to all functions defined in the module.",+ Options::Arguments::One,+ [&](Options* o, const std::string& argument) {+ splitFuncs = parseNameList(argument);+ })+ .add("--output",+ "-o",+ "Output file. Only usable with --instrument.",+ Options::Arguments::One,+ [&](Options* o, const std::string& argument) { output = argument; })+ .add("--primary-output",+ "-o1",+ "Output file for the primary module. Not usable with --instrument.",+ Options::Arguments::One,+ [&](Options* o, const std::string& argument) {+ primaryOutput = argument;+ })+ .add("--secondary-output",+ "-o2",+ "Output file for the secondary module. Not usable with --instrument.",+ Options::Arguments::One,+ [&](Options* o, const std::string& argument) {+ secondaryOutput = argument;+ })+ .add("--import-namespace",+ "",+ "The namespace from which to import objects from the primary "+ "module into the secondary module.",+ Options::Arguments::One,+ [&](Options* o, const std::string& argument) {+ importNamespace = argument;+ })+ .add("--placeholder-namespace",+ "",+ "The namespace from which to import placeholder functions into "+ "the primary module.",+ Options::Arguments::One,+ [&](Options* o, const std::string& argument) {+ placeholderNamespace = argument;+ })+ .add(+ "--export-prefix",+ "",+ "An identifying prefix to prepend to new export names created "+ "by module splitting.",+ Options::Arguments::One,+ [&](Options* o, const std::string& argument) { exportPrefix = argument; })+ .add("--verbose",+ "-v",+ "Verbose output mode. Prints the functions that will be kept "+ "and split out when splitting a module.",+ Options::Arguments::Zero,+ [&](Options* o, const std::string& argument) {+ verbose = true;+ quiet = false;+ })+ .add("--emit-text",+ "-S",+ "Emit text instead of binary for the output file or files.",+ Options::Arguments::Zero,+ [&](Options* o, const std::string& argument) { emitBinary = false; })+ .add("--debuginfo",+ "-g",+ "Emit names section in wasm binary (or full debuginfo in wast)",+ Options::Arguments::Zero,+ [&](Options* o, const std::string& arguments) {+ passOptions.debugInfo = true;+ })+ .add("--initial-table",+ "",+ "A hack to ensure the split and instrumented modules have the same "+ "table size when using Emscripten's SPLIT_MODULE mode with dynamic "+ "linking. TODO: Figure out a more elegant solution for that use "+ "case and remove this.",+ Options::Arguments::One,+ [&](Options* o, const std::string& argument) {+ initialTableSize = std::stoi(argument);+ })+ .add_positional(+ "INFILE",+ Options::Arguments::One,+ [&](Options* o, const std::string& argument) { input = argument; });+}++bool WasmSplitOptions::validate() {+ bool valid = true;+ auto fail = [&](auto msg) {+ std::cerr << "error: " << msg << "\n";+ valid = false;+ };++ if (!input.size()) {+ fail("no input file");+ }+ if (instrument) {+ using Opt = std::pair<const std::string&, const std::string>;+ for (auto& opt : {Opt{profileFile, "--profile"},+ Opt{primaryOutput, "primary output"},+ Opt{secondaryOutput, "secondary output"},+ Opt{importNamespace, "--import-namespace"},+ Opt{placeholderNamespace, "--placeholder-namespace"},+ Opt{exportPrefix, "--export-prefix"}}) {+ if (opt.first.size()) {+ fail(opt.second + " cannot be used with --instrument");+ }+ }+ if (keepFuncs.size()) {+ fail("--keep-funcs cannot be used with --instrument");+ }+ if (splitFuncs.size()) {+ fail("--split-funcs cannot be used with --instrument");+ }+ } else {+ if (output.size()) {+ fail(+ "must provide separate primary and secondary output with -o1 and -o2");+ }+ if (profileExport != DEFAULT_PROFILE_EXPORT) {+ fail("--profile-export must be used with --instrument");+ }+ }++ std::vector<Name> impossible;+ std::set_intersection(keepFuncs.begin(),+ keepFuncs.end(),+ splitFuncs.begin(),+ splitFuncs.end(),+ std::inserter(impossible, impossible.end()));+ for (auto& func : impossible) {+ fail(std::string("Cannot both keep and split out function ") ++ func.c_str());+ }++ return valid;+}++void WasmSplitOptions::parse(int argc, const char* argv[]) {+ ToolOptions::parse(argc, argv);+ // Since --quiet is defined in ToolOptions but --verbose is defined here,+ // --quiet doesn't know to unset --verbose. Fix it up here.+ if (quiet && verbose) {+ verbose = false;+ }+}++void parseInput(Module& wasm, const WasmSplitOptions& options) {+ ModuleReader reader;+ reader.setProfile(options.profile);+ try {+ reader.read(options.input, wasm);+ } catch (ParseException& p) {+ p.dump(std::cerr);+ std::cerr << '\n';+ Fatal() << "error parsing wasm";+ } catch (std::bad_alloc&) {+ Fatal() << "error building module, std::bad_alloc (possibly invalid "+ "request for silly amounts of memory)";+ }+ options.applyFeatures(wasm);+}++// Add a global monotonic counter and a timestamp global for each function, code+// at the beginning of each function to set its timestamp, and a new exported+// function for dumping the profile data.+struct Instrumenter : public Pass {+ PassRunner* runner = nullptr;+ Module* wasm = nullptr;++ const std::string& profileExport;+ uint64_t moduleHash;++ Name counterGlobal;+ std::vector<Name> functionGlobals;++ Instrumenter(const std::string& profileExport, uint64_t moduleHash);++ void run(PassRunner* runner, Module* wasm) override;+ void addGlobals();+ void instrumentFuncs();+ void addProfileExport();+};++Instrumenter::Instrumenter(const std::string& profileExport,+ uint64_t moduleHash)+ : profileExport(profileExport), moduleHash(moduleHash) {}++void Instrumenter::run(PassRunner* runner, Module* wasm) {+ this->runner = runner;+ this->wasm = wasm;+ addGlobals();+ instrumentFuncs();+ addProfileExport();+}++void Instrumenter::addGlobals() {+ // Create fresh global names (over-reserves, but that's ok)+ counterGlobal = Names::getValidGlobalName(*wasm, "monotonic_counter");+ functionGlobals.reserve(wasm->functions.size());+ ModuleUtils::iterDefinedFunctions(*wasm, [&](Function* func) {+ functionGlobals.push_back(Names::getValidGlobalName(+ *wasm, std::string(func->name.c_str()) + "_timestamp"));+ });++ // Create and add new globals+ auto addGlobal = [&](Name name) {+ auto global = Builder::makeGlobal(+ name,+ Type::i32,+ Builder(*wasm).makeConst(Literal::makeZero(Type::i32)),+ Builder::Mutable);+ global->hasExplicitName = true;+ wasm->addGlobal(std::move(global));+ };+ addGlobal(counterGlobal);+ for (auto& name : functionGlobals) {+ addGlobal(name);+ }+}++void Instrumenter::instrumentFuncs() {+ // Inject the following code at the beginning of each function to advance the+ // monotonic counter and set the function's timestamp if it hasn't already+ // been set.+ //+ // (if (i32.eqz (global.get $timestamp))+ // (block+ // (global.set $monotonic_counter+ // (i32.add+ // (global.get $monotonic_counter)+ // (i32.const 1)+ // )+ // )+ // (global.set $timestamp+ // (global.get $monotonic_counter)+ // )+ // )+ // )+ Builder builder(*wasm);+ auto globalIt = functionGlobals.begin();+ ModuleUtils::iterDefinedFunctions(*wasm, [&](Function* func) {+ func->body = builder.makeSequence(+ builder.makeIf(+ builder.makeUnary(EqZInt32,+ builder.makeGlobalGet(*globalIt, Type::i32)),+ builder.makeSequence(+ builder.makeGlobalSet(+ counterGlobal,+ builder.makeBinary(AddInt32,+ builder.makeGlobalGet(counterGlobal, Type::i32),+ builder.makeConst(Literal::makeOne(Type::i32)))),+ builder.makeGlobalSet(+ *globalIt, builder.makeGlobalGet(counterGlobal, Type::i32)))),+ func->body,+ func->body->type);+ ++globalIt;+ });+}++// wasm-split profile format:+//+// The wasm-split profile is a binary format designed to be simple to produce+// and consume. It is comprised of:+//+// 1. An 8-byte module hash+//+// 2. A 4-byte timestamp for each defined function+//+// The module hash is meant to guard against bugs where the module that was+// instrumented and the module that is being split are different. The timestamps+// are non-zero for functions that were called during the instrumented run and 0+// otherwise. Functions with smaller non-zero timestamps were called earlier in+// the instrumented run than funtions with larger timestamps.++void Instrumenter::addProfileExport() {+ // Create and export a function to dump the profile into a given memory+ // buffer. The function takes the available address and buffer size as+ // arguments and returns the total size of the profile. It only actually+ // writes the profile if the given space is sufficient to hold it.+ auto name = Names::getValidFunctionName(*wasm, profileExport);+ auto writeProfile = Builder::makeFunction(+ name, Signature({Type::i32, Type::i32}, Type::i32), {});+ writeProfile->hasExplicitName = true;+ writeProfile->setLocalName(0, "addr");+ writeProfile->setLocalName(1, "size");++ // Calculate the size of the profile:+ // 8 bytes module hash ++ // 4 bytes for the timestamp for each function+ const size_t profileSize = 8 + 4 * functionGlobals.size();++ // Create the function body+ Builder builder(*wasm);+ auto getAddr = [&]() { return builder.makeLocalGet(0, Type::i32); };+ auto getSize = [&]() { return builder.makeLocalGet(1, Type::i32); };+ auto hashConst = [&]() { return builder.makeConst(int64_t(moduleHash)); };+ auto profileSizeConst = [&]() {+ return builder.makeConst(int32_t(profileSize));+ };++ // Write the hash followed by all the time stamps+ Expression* writeData =+ builder.makeStore(8, 0, 1, getAddr(), hashConst(), Type::i64);++ uint32_t offset = 8;+ for (const auto& global : functionGlobals) {+ writeData = builder.blockify(+ writeData,+ builder.makeStore(4,+ offset,+ 1,+ getAddr(),+ builder.makeGlobalGet(global, Type::i32),+ Type::i32));+ offset += 4;+ }++ writeProfile->body = builder.makeSequence(+ builder.makeIf(builder.makeBinary(GeUInt32, getSize(), profileSizeConst()),+ writeData),+ profileSizeConst());++ // Create an export for the function+ wasm->addFunction(std::move(writeProfile));+ wasm->addExport(+ Builder::makeExport(profileExport, name, ExternalKind::Function));++ // Also make sure there is a memory with enough pages to write into+ size_t pages = (profileSize + Memory::kPageSize - 1) / Memory::kPageSize;+ if (!wasm->memory.exists) {+ wasm->memory.exists = true;+ wasm->memory.initial = pages;+ wasm->memory.max = pages;+ } else if (wasm->memory.initial < pages) {+ wasm->memory.initial = pages;+ if (wasm->memory.max < pages) {+ wasm->memory.max = pages;+ }+ }++ // TODO: export the memory if it is not already exported.+}++uint64_t hashFile(const std::string& filename) {+ auto contents(read_file<std::vector<char>>(filename, Flags::Binary));+ size_t digest = 0;+ // Don't use `hash` or `rehash` - they aren't deterministic between executions+ for (char c : contents) {+ hash_combine(digest, c);+ }+ return uint64_t(digest);+}++void adjustTableSize(Module& wasm, int initialSize) {+ if (initialSize < 0) {+ return;+ }+ if (!wasm.table.exists) {+ Fatal() << "--initial-table used but there is no table";+ }+ if ((uint64_t)initialSize < wasm.table.initial) {+ Fatal() << "Specified initial table size too small, should be at least "+ << wasm.table.initial;+ }+ if ((uint64_t)initialSize > wasm.table.max) {+ Fatal() << "Specified initial table size larger than max table size "+ << wasm.table.max;+ }+ wasm.table.initial = initialSize;+}++void instrumentModule(Module& wasm, const WasmSplitOptions& options) {+ // Check that the profile export name is not already taken+ if (wasm.getExportOrNull(options.profileExport) != nullptr) {+ Fatal() << "error: Export " << options.profileExport << " already exists.";+ }++ uint64_t moduleHash = hashFile(options.input);+ PassRunner runner(&wasm, options.passOptions);+ Instrumenter(options.profileExport, moduleHash).run(&runner, &wasm);++ adjustTableSize(wasm, options.initialTableSize);++ // Write the output modules+ ModuleWriter writer;+ writer.setBinary(options.emitBinary);+ writer.setDebugInfo(options.passOptions.debugInfo);+ writer.write(wasm, options.output);+}++// See "wasm-split profile format" above for more information.+std::set<Name> readProfile(Module& wasm, const WasmSplitOptions& options) {+ auto profileData =+ read_file<std::vector<char>>(options.profileFile, Flags::Binary);+ size_t i = 0;+ auto readi32 = [&]() {+ if (i + 4 > profileData.size()) {+ Fatal() << "Unexpected end of profile data";+ }+ uint32_t i32 = 0;+ i32 |= uint32_t(uint8_t(profileData[i++]));+ i32 |= uint32_t(uint8_t(profileData[i++])) << 8;+ i32 |= uint32_t(uint8_t(profileData[i++])) << 16;+ i32 |= uint32_t(uint8_t(profileData[i++])) << 24;+ return i32;+ };++ // Read and compare the 8-byte module hash.+ uint64_t expected = readi32();+ expected |= uint64_t(readi32()) << 32;+ if (expected != hashFile(options.input)) {+ Fatal() << "error: checksum in profile does not match module checksum. "+ << "The split module must be the original module that was "+ << "instrumented to generate the profile.";+ }++ std::set<Name> keptFuncs;+ ModuleUtils::iterDefinedFunctions(wasm, [&](Function* func) {+ uint32_t timestamp = readi32();+ // TODO: provide an option to set the timestamp threshold. For now, kee the+ // function if the profile shows it being run at all.+ if (timestamp > 0) {+ keptFuncs.insert(func->name);+ }+ });++ if (i != profileData.size()) {+ // TODO: Handle concatenated profile data.+ Fatal() << "Unexpected extra profile data";+ }++ return keptFuncs;+}++void splitModule(Module& wasm, const WasmSplitOptions& options) {+ std::set<Name> keepFuncs;++ if (options.profileFile.size()) {+ // Use the profile to initialize `keepFuncs`+ keepFuncs = readProfile(wasm, options);+ }++ // Add in the functions specified with --keep-funcs+ for (auto& func : options.keepFuncs) {+ if (!options.quiet && wasm.getFunctionOrNull(func) == nullptr) {+ std::cerr << "warning: function " << func << " does not exist\n";+ }+ keepFuncs.insert(func);+ }++ // Remove the functions specified with --remove-funcs+ for (auto& func : options.splitFuncs) {+ auto* function = wasm.getFunctionOrNull(func);+ if (!options.quiet && function == nullptr) {+ std::cerr << "warning: function " << func << " does not exist\n";+ }+ if (function && function->imported()) {+ if (!options.quiet) {+ std::cerr << "warning: cannot split out imported function " << func+ << "\n";+ }+ } else {+ keepFuncs.erase(func);+ }+ }++ if (!options.quiet && keepFuncs.size() == 0) {+ std::cerr << "warning: not keeping any functions in the primary module\n";+ }++ // If warnings are enabled, check that any functions are being split out.+ if (!options.quiet) {+ std::set<Name> splitFuncs;+ ModuleUtils::iterDefinedFunctions(wasm, [&](Function* func) {+ if (keepFuncs.count(func->name) == 0) {+ splitFuncs.insert(func->name);+ }+ });++ if (splitFuncs.size() == 0) {+ std::cerr+ << "warning: not splitting any functions out to the secondary module\n";+ }++ // Dump the kept and split functions if we are verbose+ if (options.verbose) {+ auto printCommaSeparated = [&](auto funcs) {+ for (auto it = funcs.begin(); it != funcs.end(); ++it) {+ if (it != funcs.begin()) {+ std::cout << ", ";+ }+ std::cout << *it;+ }+ };++ std::cout << "Keeping functions: ";+ printCommaSeparated(keepFuncs);+ std::cout << "\n";++ std::cout << "Splitting out functions: ";+ printCommaSeparated(splitFuncs);+ std::cout << "\n";+ }+ }++ // Actually perform the splitting+ ModuleSplitting::Config config;+ config.primaryFuncs = std::move(keepFuncs);+ if (options.importNamespace.size()) {+ config.importNamespace = options.importNamespace;+ }+ if (options.placeholderNamespace.size()) {+ config.placeholderNamespace = options.placeholderNamespace;+ }+ if (options.exportPrefix.size()) {+ config.newExportPrefix = options.exportPrefix;+ }+ std::unique_ptr<Module> secondary =+ ModuleSplitting::splitFunctions(wasm, config);++ adjustTableSize(wasm, options.initialTableSize);+ adjustTableSize(*secondary, options.initialTableSize);++ // Write the output modules+ ModuleWriter writer;+ writer.setBinary(options.emitBinary);+ writer.setDebugInfo(options.passOptions.debugInfo);+ writer.write(wasm, options.primaryOutput);+ writer.write(*secondary, options.secondaryOutput);+}++} // anonymous namespace++int main(int argc, const char* argv[]) {+ WasmSplitOptions options;+ options.parse(argc, argv);++ if (!options.validate()) {+ Fatal() << "Invalid command line arguments";+ }++ Module wasm;+ parseInput(wasm, options);++ if (options.passOptions.validate && !WasmValidator().validate(wasm)) {+ Fatal() << "error validating input";+ }++ if (options.instrument) {+ instrumentModule(wasm, options);+ } else {+ splitModule(wasm, options);+ }+}
binaryen/src/tools/wasm2c-wrapper.h view
@@ -25,6 +25,58 @@ namespace wasm { +// Mangle a name in (hopefully) exactly the same way wasm2c does.+static std::string wasm2cMangle(Name name, Signature sig) {+ const char escapePrefix = 'Z';+ std::string mangled = "Z_";+ const char* original = name.str;+ unsigned char c;+ while ((c = *original++)) {+ if ((isalnum(c) && c != escapePrefix) || c == '_') {+ // This character is ok to emit as it is.+ mangled += c;+ } else {+ // This must be escaped, as prefix + hex character code.+ mangled += escapePrefix;+ std::stringstream ss;+ ss << std::hex << std::uppercase << unsigned(c);+ mangled += ss.str();+ }+ }++ // Emit the result and params.+ mangled += "Z_";++ auto wasm2cSignature = [](Type type) {+ TODO_SINGLE_COMPOUND(type);+ switch (type.getBasic()) {+ case Type::none:+ return 'v';+ case Type::i32:+ return 'i';+ case Type::i64:+ return 'j';+ case Type::f32:+ return 'f';+ case Type::f64:+ return 'd';+ default:+ Fatal() << "unhandled wasm2c wrapper signature type: " << type;+ }+ };++ mangled += wasm2cSignature(sig.results);+ if (sig.params.isTuple()) {+ for (const auto& param : sig.params) {+ mangled += wasm2cSignature(param);+ }+ } else {+ mangled += wasm2cSignature(sig.params);+ }++ return mangled;+}+ static std::string generateWasm2CWrapper(Module& wasm) { // First, emit implementations of the wasm's imports so that the wasm2c code // can call them. The names use wasm2c's name mangling.@@ -142,35 +194,12 @@ } } - // Emit the callee's name with wasm2c name mangling.- ret += std::string("(*Z_") + exp->name.str + "Z_";+ // Call the export.+ ret += "(*"; - auto wasm2cSignature = [](Type type) {- TODO_SINGLE_COMPOUND(type);- switch (type.getBasic()) {- case Type::none:- return 'v';- case Type::i32:- return 'i';- case Type::i64:- return 'j';- case Type::f32:- return 'f';- case Type::f64:- return 'd';- default:- Fatal() << "unhandled wasm2c wrapper signature type: " << type;- }- };+ // Emit the callee's name with wasm2c name mangling.+ ret += wasm2cMangle(exp->name, func->sig); - ret += wasm2cSignature(result);- if (func->sig.params.isTuple()) {- for (const auto& param : func->sig.params) {- ret += wasm2cSignature(param);- }- } else {- ret += wasm2cSignature(func->sig.params);- } ret += ")("; // Emit the parameters (all 0s, like the other wrappers).
binaryen/src/tools/wasm2js.cpp view
@@ -984,7 +984,7 @@ if (options.passOptions.validate) { if (!WasmValidator().validate(wasm)) {- WasmPrinter::printModule(&wasm);+ std::cout << wasm << '\n'; Fatal() << "error in validating input"; } }
binaryen/src/wasm-binary.h view
@@ -25,8 +25,6 @@ #include <ostream> #include <type_traits> -#include "asm_v_wasm.h"-#include "asmjs/shared-constants.h" #include "ir/import-utils.h" #include "ir/module-utils.h" #include "parsing.h"@@ -340,6 +338,8 @@ f32 = -0x3, // 0x7d f64 = -0x4, // 0x7c v128 = -0x5, // 0x7b+ i8 = -0x6, // 0x7a+ i16 = -0x7, // 0x79 // function reference type funcref = -0x10, // 0x70 // opaque host reference type@@ -348,12 +348,22 @@ anyref = -0x12, // 0x6e // comparable reference type eqref = -0x13, // 0x6d+ // nullable typed function reference type, with parameter+ nullable = -0x14, // 0x6c+ // non-nullable typed function reference type, with parameter+ nonnullable = -0x15, // 0x6b // integer reference type i31ref = -0x16, // 0x6a- // exception reference type- exnref = -0x18, // 0x68+ // run-time type info type, with depth index n+ rtt_n = -0x17, // 0x69+ // run-time type info type, without depth index n+ rtt = -0x18, // 0x68+ // exception reference type TODO remove; the code for now is incorrect+ exnref = -0x19, // 0x67 // func_type form- Func = -0x20, // 0x60+ Func = -0x20, // 0x60+ Struct = -0x21, // 0x5f+ Array = -0x22, // 0x5e // block_type Empty = -0x40 // 0x40 };@@ -388,6 +398,7 @@ extern const char* MultivalueFeature; extern const char* GCFeature; extern const char* Memory64Feature;+extern const char* TypedFunctionReferencesFeature; enum Subsection { NameModule = 0,@@ -771,6 +782,7 @@ I32x4LeU = 0x3e, I32x4GeS = 0x3f, I32x4GeU = 0x40,+ I64x2Eq = 0xc0, F32x4Eq = 0x41, F32x4Ne = 0x42, F32x4Lt = 0x43,@@ -791,6 +803,20 @@ V128Xor = 0x51, V128Bitselect = 0x52, + V8x16SignSelect = 0x7d,+ V16x8SignSelect = 0x7e,+ V32x4SignSelect = 0x7f,+ V64x2SignSelect = 0x94,++ V128Load8Lane = 0x58,+ V128Load16Lane = 0x59,+ V128Load32Lane = 0x5a,+ V128Load64Lane = 0x5b,+ V128Store8Lane = 0x5c,+ V128Store16Lane = 0x5d,+ V128Store32Lane = 0x5e,+ V128Store64Lane = 0x5f,+ I8x16Abs = 0x60, I8x16Neg = 0x61, I8x16AnyTrue = 0x62,@@ -814,6 +840,8 @@ I8x16MaxU = 0x79, I8x16AvgrU = 0x7b, + I8x16Popcnt = 0x7c,+ I16x8Abs = 0x80, I16x8Neg = 0x81, I16x8AnyTrue = 0x82,@@ -840,6 +868,7 @@ I16x8MaxS = 0x98, I16x8MaxU = 0x99, I16x8AvgrU = 0x9b,+ I16x8Q15MulrSatS = 0x9c, I32x4Abs = 0xa0, I32x4Neg = 0xa1,@@ -862,9 +891,12 @@ I32x4MaxU = 0xb9, I32x4DotSVecI16x8 = 0xba, + I64x2Bitmask = 0xc4,+ I64x2WidenLowSI32x4 = 0xc7,+ I64x2WidenHighSI32x4 = 0xc8,+ I64x2WidenLowUI32x4 = 0xc9,+ I64x2WidenHighUI32x4 = 0xca, I64x2Neg = 0xc1,- I64x2AnyTrue = 0xc2,- I64x2AllTrue = 0xc3, I64x2Shl = 0xcb, I64x2ShrS = 0xcc, I64x2ShrU = 0xcd,@@ -905,6 +937,11 @@ F64x2PMin = 0xf6, F64x2PMax = 0xf7, + I16x8ExtAddPairWiseSI8x16 = 0xc2,+ I16x8ExtAddPairWiseUI8x16 = 0xc3,+ I32x4ExtAddPairWiseSI16x8 = 0xa5,+ I32x4ExtAddPairWiseUI16x8 = 0xa6,+ I32x4TruncSatSF32x4 = 0xf8, I32x4TruncSatUF32x4 = 0xf9, F32x4ConvertSI32x4 = 0xfa,@@ -923,6 +960,24 @@ F64x2ConvertSI64x2 = 0x0102, F64x2ConvertUI64x2 = 0x0103, + I16x8ExtMulLowSI8x16 = 0x9a,+ I16x8ExtMulHighSI8x16 = 0x9d,+ I16x8ExtMulLowUI8x16 = 0x9e,+ I16x8ExtMulHighUI8x16 = 0x9f,+ I32x4ExtMulLowSI16x8 = 0xbb,+ I32x4ExtMulHighSI16x8 = 0xbd,+ I32x4ExtMulLowUI16x8 = 0xbe,+ I32x4ExtMulHighUI16x8 = 0xbf,+ I64x2ExtMulLowSI32x4 = 0xd2,+ I64x2ExtMulHighSI32x4 = 0xd3,+ I64x2ExtMulLowUI32x4 = 0xd6,+ I64x2ExtMulHighUI32x4 = 0xd7,++ // prefetch opcodes++ PrefetchT = 0xc5,+ PrefetchNT = 0xc6,+ // bulk memory opcodes MemoryInit = 0x08,@@ -944,6 +999,11 @@ Rethrow = 0x09, BrOnExn = 0x0a, + // typed function references opcodes++ CallRef = 0x14,+ RetCallRef = 0x15,+ // gc opcodes RefEq = 0xd5,@@ -986,82 +1046,6 @@ } // namespace BinaryConsts -inline S32LEB binaryType(Type type) {- int ret = 0;- TODO_SINGLE_COMPOUND(type);- switch (type.getBasic()) {- // None only used for block signatures. TODO: Separate out?- case Type::none:- ret = BinaryConsts::EncodedType::Empty;- break;- case Type::i32:- ret = BinaryConsts::EncodedType::i32;- break;- case Type::i64:- ret = BinaryConsts::EncodedType::i64;- break;- case Type::f32:- ret = BinaryConsts::EncodedType::f32;- break;- case Type::f64:- ret = BinaryConsts::EncodedType::f64;- break;- case Type::v128:- ret = BinaryConsts::EncodedType::v128;- break;- case Type::funcref:- ret = BinaryConsts::EncodedType::funcref;- break;- case Type::externref:- ret = BinaryConsts::EncodedType::externref;- break;- case Type::exnref:- ret = BinaryConsts::EncodedType::exnref;- break;- case Type::anyref:- ret = BinaryConsts::EncodedType::anyref;- break;- case Type::eqref:- ret = BinaryConsts::EncodedType::eqref;- break;- case Type::i31ref:- ret = BinaryConsts::EncodedType::i31ref;- break;- case Type::unreachable:- WASM_UNREACHABLE("unexpected type");- }- return S32LEB(ret);-}--inline S32LEB binaryHeapType(HeapType type) {- int ret = 0;- switch (type.kind) {- case HeapType::FuncKind:- ret = BinaryConsts::EncodedHeapType::func;- break;- case HeapType::ExternKind:- ret = BinaryConsts::EncodedHeapType::extern_;- break;- case HeapType::ExnKind:- ret = BinaryConsts::EncodedHeapType::exn;- break;- case HeapType::AnyKind:- ret = BinaryConsts::EncodedHeapType::any;- break;- case HeapType::EqKind:- ret = BinaryConsts::EncodedHeapType::eq;- break;- case HeapType::I31Kind:- ret = BinaryConsts::EncodedHeapType::i31;- break;- case HeapType::SignatureKind:- case HeapType::StructKind:- case HeapType::ArrayKind:- WASM_UNREACHABLE("TODO: compound GC types");- }- return S32LEB(ret); // TODO: Actually encoded as s33-}- // Writes out wasm to the binary format class WasmBinaryWriter {@@ -1168,7 +1152,7 @@ uint32_t getFunctionIndex(Name name) const; uint32_t getGlobalIndex(Name name) const; uint32_t getEventIndex(Name name) const;- uint32_t getTypeIndex(Signature sig) const;+ uint32_t getTypeIndex(HeapType type) const; void writeFunctionTableDeclaration(); void writeTableElements();@@ -1211,12 +1195,16 @@ Module* getModule() { return wasm; } + void writeType(Type type);+ void writeHeapType(HeapType type);+ void writeField(const Field& field);+ private: Module* wasm; BufferWithRandomAccess& o; BinaryIndexes indexes;- std::unordered_map<Signature, Index> typeIndices;- std::vector<Signature> types;+ std::unordered_map<HeapType, Index> typeIndices;+ std::vector<HeapType> types; bool debugInfo = true; std::ostream* sourceMap = nullptr;@@ -1260,8 +1248,8 @@ std::set<BinaryConsts::Section> seenSections; - // All signatures present in the type section- std::vector<Signature> signatures;+ // All types defined in the type section+ std::vector<HeapType> types; public: WasmBinaryBuilder(Module& wasm, const std::vector<char>& input)@@ -1288,19 +1276,26 @@ uint64_t getU64LEB(); int32_t getS32LEB(); int64_t getS64LEB();+ uint64_t getUPtrLEB();++ // Read a value and get a type for it. Type getType();+ // Get a type given the initial S32LEB has already been read, and is provided.+ Type getType(int initial);+ HeapType getHeapType();+ Mutability getMutability();+ Field getField(); Type getConcreteType(); Name getInlineString(); void verifyInt8(int8_t x); void verifyInt16(int16_t x); void verifyInt32(int32_t x); void verifyInt64(int64_t x);- void ungetInt8(); void readHeader(); void readStart(); void readMemory();- void readSignatures();+ void readTypes(); // gets a name in the combined import+defined space Name getFunctionName(Index index);@@ -1318,6 +1313,9 @@ std::vector<Signature> functionSignatures; void readFunctionSignatures();+ Signature getSignatureByFunctionIndex(Index index);+ Signature getSignatureByTypeIndex(Index index);+ size_t nextLabel; Name getNextLabel();@@ -1338,7 +1336,7 @@ Index endOfFunction = -1; // we store globals here before wasm.addGlobal after we know their names- std::vector<Global*> globals;+ std::vector<std::unique_ptr<Global>> globals; // we store global imports here before wasm.addGlobalImport after we know // their names std::vector<Global*> globalImports;@@ -1451,19 +1449,20 @@ // Gets a block of expressions. If it's just one, return that singleton. Expression* getBlockOrSingleton(Type type); + BreakTarget getBreakTarget(int32_t offset);++ void readMemoryAccess(Address& alignment, Address& offset);+ void visitIf(If* curr); void visitLoop(Loop* curr);- BreakTarget getBreakTarget(int32_t offset); void visitBreak(Break* curr, uint8_t code); void visitSwitch(Switch* curr);- void visitCall(Call* curr); void visitCallIndirect(CallIndirect* curr); void visitLocalGet(LocalGet* curr); void visitLocalSet(LocalSet* curr, uint8_t code); void visitGlobalGet(GlobalGet* curr); void visitGlobalSet(GlobalSet* curr);- void readMemoryAccess(Address& alignment, Address& offset); bool maybeVisitLoad(Expression*& out, uint8_t code, bool isAtomic); bool maybeVisitStore(Expression*& out, uint8_t code, bool isAtomic); bool maybeVisitNontrappingTrunc(Expression*& out, uint32_t code);@@ -1486,6 +1485,8 @@ bool maybeVisitSIMDTernary(Expression*& out, uint32_t code); bool maybeVisitSIMDShift(Expression*& out, uint32_t code); bool maybeVisitSIMDLoad(Expression*& out, uint32_t code);+ bool maybeVisitSIMDLoadStoreLane(Expression*& out, uint32_t code);+ bool maybeVisitPrefetch(Expression*& out, uint32_t code); bool maybeVisitMemoryInit(Expression*& out, uint32_t code); bool maybeVisitDataDrop(Expression*& out, uint32_t code); bool maybeVisitMemoryCopy(Expression*& out, uint32_t code);@@ -1519,8 +1520,16 @@ void visitThrow(Throw* curr); void visitRethrow(Rethrow* curr); void visitBrOnExn(BrOnExn* curr);+ void visitCallRef(CallRef* curr); void throwError(std::string text);++ // Struct/Array instructions have an unnecessary heap type that is just for+ // validation (except for the case of unreachability, but that's not a problem+ // anyhow, we can ignore it there). That is, we also have a reference / rtt+ // child from which we can infer the type anyhow, and we just need to check+ // that type is the same.+ void validateHeapTypeUsingChild(Expression* child, HeapType heapType); private: bool hasDWARFSections();
binaryen/src/wasm-builder.h view
@@ -41,11 +41,11 @@ // make* functions, other globals - Function* makeFunction(Name name,- Signature sig,- std::vector<Type>&& vars,- Expression* body = nullptr) {- auto* func = new Function;+ static std::unique_ptr<Function> makeFunction(Name name,+ Signature sig,+ std::vector<Type>&& vars,+ Expression* body = nullptr) {+ auto func = std::make_unique<Function>(); func->name = name; func->sig = sig; func->body = body;@@ -53,12 +53,12 @@ return func; } - Function* makeFunction(Name name,- std::vector<NameType>&& params,- Type resultType,- std::vector<NameType>&& vars,- Expression* body = nullptr) {- auto* func = new Function;+ static std::unique_ptr<Function> makeFunction(Name name,+ std::vector<NameType>&& params,+ Type resultType,+ std::vector<NameType>&& vars,+ Expression* body = nullptr) {+ auto func = std::make_unique<Function>(); func->name = name; func->body = body; std::vector<Type> paramVec;@@ -78,14 +78,36 @@ return func; } - Export* makeExport(Name name, Name value, ExternalKind kind) {- auto* export_ = new Export();+ static std::unique_ptr<Export>+ makeExport(Name name, Name value, ExternalKind kind) {+ auto export_ = std::make_unique<Export>(); export_->name = name; export_->value = value; export_->kind = kind; return export_; } + enum Mutability { Mutable, Immutable };++ static std::unique_ptr<Global>+ makeGlobal(Name name, Type type, Expression* init, Mutability mutable_) {+ auto glob = std::make_unique<Global>();+ glob->name = name;+ glob->type = type;+ glob->init = init;+ glob->mutable_ = mutable_ == Mutable;+ return glob;+ }++ static std::unique_ptr<Event>+ makeEvent(Name name, uint32_t attribute, Signature sig) {+ auto event = std::make_unique<Event>();+ event->name = name;+ event->attribute = attribute;+ event->sig = sig;+ return event;+ }+ // IR nodes Nop* makeNop() { return wasm.allocator.alloc<Nop>(); }@@ -221,8 +243,9 @@ call->finalize(); return call; }+ template<typename T> CallIndirect* makeCallIndirect(Expression* target,- const std::vector<Expression*>& args,+ const T& args, Signature sig, bool isReturn = false) { auto* call = wasm.allocator.alloc<CallIndirect>();@@ -234,6 +257,19 @@ call->finalize(); return call; }+ template<typename T>+ CallRef* makeCallRef(Expression* target,+ const T& args,+ Type type,+ bool isReturn = false) {+ auto* call = wasm.allocator.alloc<CallRef>();+ call->type = type;+ call->target = target;+ call->operands.set(args);+ call->isReturn = isReturn;+ call->finalize();+ return call;+ } LocalGet* makeLocalGet(Index index, Type type) { auto* ret = wasm.allocator.alloc<LocalGet>(); ret->index = index;@@ -434,6 +470,32 @@ ret->finalize(); return ret; }+ SIMDLoadStoreLane* makeSIMDLoadStoreLane(SIMDLoadStoreLaneOp op,+ Address offset,+ Address align,+ uint8_t index,+ Expression* ptr,+ Expression* vec) {+ auto* ret = wasm.allocator.alloc<SIMDLoadStoreLane>();+ ret->op = op;+ ret->offset = offset;+ ret->align = align;+ ret->index = index;+ ret->ptr = ptr;+ ret->vec = vec;+ ret->finalize();+ return ret;+ }+ Prefetch*+ makePrefetch(PrefetchOp op, Address offset, Address align, Expression* ptr) {+ auto* ret = wasm.allocator.alloc<Prefetch>();+ ret->op = op;+ ret->offset = offset;+ ret->align = align;+ ret->ptr = ptr;+ ret->finalize();+ return ret;+ } MemoryInit* makeMemoryInit(uint32_t segment, Expression* dest, Expression* offset,@@ -549,10 +611,10 @@ ret->finalize(); return ret; }- RefFunc* makeRefFunc(Name func) {+ RefFunc* makeRefFunc(Name func, Type type) { auto* ret = wasm.allocator.alloc<RefFunc>(); ret->func = func;- ret->finalize();+ ret->finalize(type); return ret; } RefEq* makeRefEq(Expression* left, Expression* right) {@@ -639,75 +701,104 @@ ret->finalize(); return ret; }- RefTest* makeRefTest() {+ RefTest* makeRefTest(Expression* ref, Expression* rtt) { auto* ret = wasm.allocator.alloc<RefTest>();- WASM_UNREACHABLE("TODO (gc): ref.test");+ ret->ref = ref;+ ret->rtt = rtt; ret->finalize(); return ret; }- RefCast* makeRefCast() {+ RefCast* makeRefCast(Expression* ref, Expression* rtt) { auto* ret = wasm.allocator.alloc<RefCast>();- WASM_UNREACHABLE("TODO (gc): ref.cast");+ ret->ref = ref;+ ret->rtt = rtt; ret->finalize(); return ret; }- BrOnCast* makeBrOnCast() {+ BrOnCast*+ makeBrOnCast(Name name, HeapType heapType, Expression* ref, Expression* rtt) { auto* ret = wasm.allocator.alloc<BrOnCast>();- WASM_UNREACHABLE("TODO (gc): br_on_cast");+ ret->name = name;+ ret->castType = Type(heapType, Nullable);+ ret->ref = ref;+ ret->rtt = rtt; ret->finalize(); return ret; }- RttCanon* makeRttCanon() {+ RttCanon* makeRttCanon(HeapType heapType) { auto* ret = wasm.allocator.alloc<RttCanon>();- WASM_UNREACHABLE("TODO (gc): rtt.canon");+ ret->type = Type(Rtt(0, heapType)); ret->finalize(); return ret; }- RttSub* makeRttSub() {+ RttSub* makeRttSub(HeapType heapType, Expression* parent) { auto* ret = wasm.allocator.alloc<RttSub>();- WASM_UNREACHABLE("TODO (gc): rtt.sub");+ ret->parent = parent;+ auto parentRtt = parent->type.getRtt();+ if (parentRtt.hasDepth()) {+ ret->type = Type(Rtt(parentRtt.depth + 1, heapType));+ } else {+ ret->type = Type(Rtt(heapType));+ } ret->finalize(); return ret; }- StructNew* makeStructNew() {+ template<typename T>+ StructNew* makeStructNew(Expression* rtt, const T& args) { auto* ret = wasm.allocator.alloc<StructNew>();- WASM_UNREACHABLE("TODO (gc): struct.new");+ ret->rtt = rtt;+ ret->operands.set(args); ret->finalize(); return ret; }- StructGet* makeStructGet() {+ StructGet*+ makeStructGet(Index index, Expression* ref, Type type, bool signed_ = false) { auto* ret = wasm.allocator.alloc<StructGet>();- WASM_UNREACHABLE("TODO (gc): struct.get");+ ret->index = index;+ ret->ref = ref;+ ret->type = type;+ ret->signed_ = signed_; ret->finalize(); return ret; }- StructSet* makeStructSet() {+ StructSet* makeStructSet(Index index, Expression* ref, Expression* value) { auto* ret = wasm.allocator.alloc<StructSet>();- WASM_UNREACHABLE("TODO (gc): struct.set");+ ret->index = index;+ ret->ref = ref;+ ret->value = value; ret->finalize(); return ret; }- ArrayNew* makeArrayNew() {+ ArrayNew*+ makeArrayNew(Expression* rtt, Expression* size, Expression* init = nullptr) { auto* ret = wasm.allocator.alloc<ArrayNew>();- WASM_UNREACHABLE("TODO (gc): array.new");+ ret->rtt = rtt;+ ret->size = size;+ ret->init = init; ret->finalize(); return ret; }- ArrayGet* makeArrayGet() {+ ArrayGet*+ makeArrayGet(Expression* ref, Expression* index, bool signed_ = false) { auto* ret = wasm.allocator.alloc<ArrayGet>();- WASM_UNREACHABLE("TODO (gc): array.get");+ ret->ref = ref;+ ret->index = index;+ ret->signed_ = signed_; ret->finalize(); return ret; }- ArraySet* makeArraySet() {+ ArraySet*+ makeArraySet(Expression* ref, Expression* index, Expression* value) { auto* ret = wasm.allocator.alloc<ArraySet>();- WASM_UNREACHABLE("TODO (gc): array.set");+ ret->ref = ref;+ ret->index = index;+ ret->value = value; ret->finalize(); return ret; }- ArrayLen* makeArrayLen() {+ ArrayLen* makeArrayLen(Expression* ref) { auto* ret = wasm.allocator.alloc<ArrayLen>();- WASM_UNREACHABLE("TODO (gc): array.len");+ ret->ref = ref; ret->finalize(); return ret; }@@ -724,24 +815,28 @@ // Make a constant expression. This might be a wasm Const, or something // else of constant value like ref.null. Expression* makeConstantExpression(Literal value) {- TODO_SINGLE_COMPOUND(value.type);- switch (value.type.getBasic()) {- case Type::funcref:- if (!value.isNull()) {- return makeRefFunc(value.getFunc());- }- return makeRefNull(value.type);+ auto type = value.type;+ if (type.isNumber()) {+ return makeConst(value);+ }+ if (value.isNull()) {+ return makeRefNull(type);+ }+ if (type.isFunction()) {+ return makeRefFunc(value.getFunc(), type);+ }+ TODO_SINGLE_COMPOUND(type);+ switch (type.getBasic()) { case Type::externref: case Type::exnref: // TODO: ExceptionPackage? case Type::anyref: case Type::eqref: assert(value.isNull() && "unexpected non-null reference type literal");- return makeRefNull(value.type);+ return makeRefNull(type); case Type::i31ref: return makeI31New(makeConst(value.geti31())); default:- assert(value.type.isNumber());- return makeConst(value);+ WASM_UNREACHABLE("invalid constant expression"); } } @@ -906,6 +1001,13 @@ if (curr->type.isTuple()) { return makeConstantExpression(Literal::makeZeros(curr->type)); }+ if (curr->type.isNullable()) {+ return ExpressionManipulator::refNull(curr, curr->type);+ }+ if (curr->type.isFunction()) {+ // We can't do any better, keep the original.+ return curr;+ } Literal value; // TODO: reuse node conditionally when possible for literals TODO_SINGLE_COMPOUND(curr->type);@@ -929,6 +1031,7 @@ break; } case Type::funcref:+ WASM_UNREACHABLE("handled above"); case Type::externref: case Type::exnref: case Type::anyref:@@ -942,28 +1045,6 @@ return ExpressionManipulator::unreachable(curr); } return makeConst(value);- }-- // Module-level helpers-- enum Mutability { Mutable, Immutable };-- static Global*- makeGlobal(Name name, Type type, Expression* init, Mutability mutable_) {- auto* glob = new Global;- glob->name = name;- glob->type = type;- glob->init = init;- glob->mutable_ = mutable_ == Mutable;- return glob;- }-- static Event* makeEvent(Name name, uint32_t attribute, Signature sig) {- auto* event = new Event;- event->name = name;- event->attribute = attribute;- event->sig = sig;- return event; } };
+ binaryen/src/wasm-delegations-fields.h view
@@ -0,0 +1,674 @@+/*+ * Copyright 2020 WebAssembly Community Group participants+ *+ * Licensed under the Apache License, Version 2.0 (the "License");+ * you may not use this file except in compliance with the License.+ * You may obtain a copy of the License at+ *+ * http://www.apache.org/licenses/LICENSE-2.0+ *+ * Unless required by applicable law or agreed to in writing, software+ * distributed under the License is distributed on an "AS IS" BASIS,+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+ * See the License for the specific language governing permissions and+ * limitations under the License.+ */++// Implements a switch on an expression class ID, and has a case for each id+// in which it runs delegates on the fields and immediates. You should include+// this file after defining the relevant DELEGATE_* macros.+//+// All defines used here are undefed automatically at the end for you.+//+// Most of the defines are necessary, and you will get an error if you forget+// them, but some are optional and some imply others, see below.+//+// The defines are as follows:+//+// DELEGATE_START(id) - called at the start of a case for an expression class.+//+// DELEGATE_END(id) - called at the end of a case.+//+// DELEGATE_GET_FIELD(id, name) - called to get a field by its name. This must+// know the object on which to get it, so it is just useful for the case+// where you operate on a single such object, but in that case it is nice+// because then other things can be defined automatically for you, see later.+//+// DELEGATE_FIELD_CHILD(id, name) - called for each child field (note: children+// are visited in reverse order, which is convenient for walking by pushing+// them to a stack first).+//+// DELEGATE_FIELD_OPTIONAL_CHILD(id, name) - called for a child that may not be+// present (like a Return's value). If you do not define this then+// DELEGATE_FIELD_CHILD is called.+//+// DELEGATE_FIELD_CHILD_VECTOR(id, name) - called for a variable-sized vector of+// child pointers. If this is not defined, and DELEGATE_GET_FIELD is, then+// DELEGATE_FIELD_CHILD is called on them.+//+// DELEGATE_FIELD_INT(id, name) - called for an integer field (bool, enum,+// Index, int32, or int64).+//+// DELEGATE_FIELD_INT_ARRAY(id, name) - called for a std::array of fixed size of+// integer values (like a SIMD mask). If this is not defined, and+// DELEGATE_GET_FIELD is, then DELEGATE_FIELD_INT is called on them.+//+// DELEGATE_FIELD_LITERAL(id, name) - called for a Literal.+//+// DELEGATE_FIELD_NAME(id, name) - called for a Name.+//+// DELEGATE_FIELD_SCOPE_NAME_DEF(id, name) - called for a scope name definition+// (like a block's name).+//+// DELEGATE_FIELD_SCOPE_NAME_USE(id, name) - called for a scope name use (like+// a break's target).+//+// DELEGATE_FIELD_SCOPE_NAME_USE_VECTOR(id, name) - called for a variable-sized+// vector of scope names (like a switch's targets). If this is not defined,+// and DELEGATE_GET_FIELD is, then DELEGATE_FIELD_SCOPE_NAME_USE is called on+// them.+//+// DELEGATE_FIELD_SIGNATURE(id, name) - called for a Signature.+//+// DELEGATE_FIELD_TYPE(id, name) - called for a Type.+//+// DELEGATE_FIELD_ADDRESS(id, name) - called for an Address.++#ifndef DELEGATE_START+#define DELEGATE_START(id)+#endif++#ifndef DELEGATE_END+#define DELEGATE_END(id)+#endif++#ifndef DELEGATE_FIELD_CHILD+#error please define DELEGATE_FIELD_CHILD(id, name)+#endif++#ifndef DELEGATE_FIELD_OPTIONAL_CHILD+#define DELEGATE_FIELD_OPTIONAL_CHILD(id, name) DELEGATE_FIELD_CHILD(id, name)+#endif++#ifndef DELEGATE_FIELD_CHILD_VECTOR+#ifdef DELEGATE_GET_FIELD+#define DELEGATE_FIELD_CHILD_VECTOR(id, name) \+ for (int i = int((DELEGATE_GET_FIELD(id, name)).size()) - 1; i >= 0; i--) { \+ DELEGATE_FIELD_CHILD(id, name[i]); \+ }+#else+#error please define DELEGATE_FIELD_CHILD_VECTOR(id, name)+#endif+#endif++#ifndef DELEGATE_FIELD_INT+#error please define DELEGATE_FIELD_INT(id, name)+#endif++#ifndef DELEGATE_FIELD_INT_ARRAY+#ifdef DELEGATE_GET_FIELD+#define DELEGATE_FIELD_INT_ARRAY(id, name) \+ for (Index i = 0; i < (DELEGATE_GET_FIELD(id, name)).size(); i++) { \+ DELEGATE_FIELD_INT(id, name[i]); \+ }+#else+#error please define DELEGATE_FIELD_INT_ARRAY(id, name)+#endif+#endif++#ifndef DELEGATE_FIELD_LITERAL+#error please define DELEGATE_FIELD_LITERAL(id, name)+#endif++#ifndef DELEGATE_FIELD_NAME+#error please define DELEGATE_FIELD_NAME(id, name)+#endif++#ifndef DELEGATE_FIELD_SCOPE_NAME_DEF+#error please define DELEGATE_FIELD_SCOPE_NAME_DEF(id, name)+#endif++#ifndef DELEGATE_FIELD_SCOPE_NAME_USE+#error please define DELEGATE_FIELD_SCOPE_NAME_USE(id, name)+#endif++#ifndef DELEGATE_FIELD_SCOPE_NAME_USE_VECTOR+#ifdef DELEGATE_GET_FIELD+#define DELEGATE_FIELD_SCOPE_NAME_USE_VECTOR(id, name) \+ for (Index i = 0; i < (DELEGATE_GET_FIELD(id, name)).size(); i++) { \+ DELEGATE_FIELD_SCOPE_NAME_USE(id, name[i]); \+ }+#else+#error please define DELEGATE_FIELD_SCOPE_NAME_USE_VECTOR(id, name)+#endif+#endif++#ifndef DELEGATE_FIELD_SIGNATURE+#error please define DELEGATE_FIELD_SIGNATURE(id, name)+#endif++#ifndef DELEGATE_FIELD_TYPE+#error please define DELEGATE_FIELD_TYPE(id, name)+#endif++#ifndef DELEGATE_FIELD_ADDRESS+#error please define DELEGATE_FIELD_ADDRESS(id, name)+#endif++switch (DELEGATE_ID) {+ case Expression::Id::InvalidId:+ case Expression::Id::NumExpressionIds: {+ WASM_UNREACHABLE("unexpected expression type");+ }+ case Expression::Id::BlockId: {+ DELEGATE_START(Block);+ DELEGATE_FIELD_CHILD_VECTOR(Block, list);+ DELEGATE_FIELD_SCOPE_NAME_DEF(Block, name);+ DELEGATE_END(Block);+ break;+ }+ case Expression::Id::IfId: {+ DELEGATE_START(If);+ DELEGATE_FIELD_OPTIONAL_CHILD(If, ifFalse);+ DELEGATE_FIELD_CHILD(If, ifTrue);+ DELEGATE_FIELD_CHILD(If, condition);+ DELEGATE_END(If);+ break;+ }+ case Expression::Id::LoopId: {+ DELEGATE_START(Loop);+ DELEGATE_FIELD_CHILD(Loop, body);+ DELEGATE_FIELD_SCOPE_NAME_DEF(Loop, name);+ DELEGATE_END(Loop);+ break;+ }+ case Expression::Id::BreakId: {+ DELEGATE_START(Break);+ DELEGATE_FIELD_OPTIONAL_CHILD(Break, condition);+ DELEGATE_FIELD_OPTIONAL_CHILD(Break, value);+ DELEGATE_FIELD_SCOPE_NAME_USE(Break, name);+ DELEGATE_END(Break);+ break;+ }+ case Expression::Id::SwitchId: {+ DELEGATE_START(Switch);+ DELEGATE_FIELD_CHILD(Switch, condition);+ DELEGATE_FIELD_OPTIONAL_CHILD(Switch, value);+ DELEGATE_FIELD_SCOPE_NAME_USE(Switch, default_);+ DELEGATE_FIELD_SCOPE_NAME_USE_VECTOR(Switch, targets);+ DELEGATE_END(Switch);+ break;+ }+ case Expression::Id::CallId: {+ DELEGATE_START(Call);+ DELEGATE_FIELD_CHILD_VECTOR(Call, operands);+ DELEGATE_FIELD_NAME(Call, target);+ DELEGATE_FIELD_INT(Call, isReturn);+ DELEGATE_END(Call);+ break;+ }+ case Expression::Id::CallIndirectId: {+ DELEGATE_START(CallIndirect);+ DELEGATE_FIELD_CHILD(CallIndirect, target);+ DELEGATE_FIELD_CHILD_VECTOR(CallIndirect, operands);+ DELEGATE_FIELD_SIGNATURE(CallIndirect, sig);+ DELEGATE_FIELD_INT(CallIndirect, isReturn);+ DELEGATE_END(CallIndirect);+ break;+ }+ case Expression::Id::LocalGetId: {+ DELEGATE_START(LocalGet);+ DELEGATE_FIELD_INT(LocalGet, index);+ DELEGATE_END(LocalGet);+ break;+ }+ case Expression::Id::LocalSetId: {+ DELEGATE_START(LocalSet);+ DELEGATE_FIELD_CHILD(LocalSet, value);+ DELEGATE_FIELD_INT(LocalSet, index);+ DELEGATE_END(LocalSet);+ break;+ }+ case Expression::Id::GlobalGetId: {+ DELEGATE_START(GlobalGet);+ DELEGATE_FIELD_INT(GlobalGet, name);+ DELEGATE_END(GlobalGet);+ break;+ }+ case Expression::Id::GlobalSetId: {+ DELEGATE_START(GlobalSet);+ DELEGATE_FIELD_CHILD(GlobalSet, value);+ DELEGATE_FIELD_INT(GlobalSet, name);+ DELEGATE_END(GlobalSet);+ break;+ }+ case Expression::Id::LoadId: {+ DELEGATE_START(Load);+ DELEGATE_FIELD_CHILD(Load, ptr);+ DELEGATE_FIELD_INT(Load, bytes);+ DELEGATE_FIELD_INT(Load, signed_);+ DELEGATE_FIELD_ADDRESS(Load, offset);+ DELEGATE_FIELD_ADDRESS(Load, align);+ DELEGATE_FIELD_INT(Load, isAtomic);+ DELEGATE_END(Load);+ break;+ }+ case Expression::Id::StoreId: {+ DELEGATE_START(Store);+ DELEGATE_FIELD_CHILD(Store, value);+ DELEGATE_FIELD_CHILD(Store, ptr);+ DELEGATE_FIELD_INT(Store, bytes);+ DELEGATE_FIELD_ADDRESS(Store, offset);+ DELEGATE_FIELD_ADDRESS(Store, align);+ DELEGATE_FIELD_INT(Store, isAtomic);+ DELEGATE_FIELD_TYPE(Store, valueType);+ DELEGATE_END(Store);+ break;+ }+ case Expression::Id::AtomicRMWId: {+ DELEGATE_START(AtomicRMW);+ DELEGATE_FIELD_CHILD(AtomicRMW, value);+ DELEGATE_FIELD_CHILD(AtomicRMW, ptr);+ DELEGATE_FIELD_INT(AtomicRMW, op);+ DELEGATE_FIELD_INT(AtomicRMW, bytes);+ DELEGATE_FIELD_ADDRESS(AtomicRMW, offset);+ DELEGATE_END(AtomicRMW);+ break;+ }+ case Expression::Id::AtomicCmpxchgId: {+ DELEGATE_START(AtomicCmpxchg);+ DELEGATE_FIELD_CHILD(AtomicCmpxchg, replacement);+ DELEGATE_FIELD_CHILD(AtomicCmpxchg, expected);+ DELEGATE_FIELD_CHILD(AtomicCmpxchg, ptr);+ DELEGATE_FIELD_INT(AtomicCmpxchg, bytes);+ DELEGATE_FIELD_ADDRESS(AtomicCmpxchg, offset);+ DELEGATE_END(AtomicCmpxchgId);+ break;+ }+ case Expression::Id::AtomicWaitId: {+ DELEGATE_START(AtomicWait);+ DELEGATE_FIELD_CHILD(AtomicWait, timeout);+ DELEGATE_FIELD_CHILD(AtomicWait, expected);+ DELEGATE_FIELD_CHILD(AtomicWait, ptr);+ DELEGATE_FIELD_ADDRESS(AtomicWait, offset);+ DELEGATE_FIELD_TYPE(AtomicWait, expectedType);+ DELEGATE_END(AtomicWait);+ break;+ }+ case Expression::Id::AtomicNotifyId: {+ DELEGATE_START(AtomicNotify);+ DELEGATE_FIELD_CHILD(AtomicNotify, notifyCount);+ DELEGATE_FIELD_CHILD(AtomicNotify, ptr);+ DELEGATE_FIELD_ADDRESS(AtomicNotify, offset);+ DELEGATE_END(AtomicNotify);+ break;+ }+ case Expression::Id::AtomicFenceId: {+ DELEGATE_START(AtomicFence);+ DELEGATE_FIELD_INT(AtomicFence, order);+ DELEGATE_END(AtomicFence);+ break;+ }+ case Expression::Id::SIMDExtractId: {+ DELEGATE_START(SIMDExtract);+ DELEGATE_FIELD_CHILD(SIMDExtract, vec);+ DELEGATE_FIELD_INT(SIMDExtract, op);+ DELEGATE_FIELD_INT(SIMDExtract, index);+ DELEGATE_END(SIMDExtract);+ break;+ }+ case Expression::Id::SIMDReplaceId: {+ DELEGATE_START(SIMDReplace);+ DELEGATE_FIELD_CHILD(SIMDReplace, value);+ DELEGATE_FIELD_CHILD(SIMDReplace, vec);+ DELEGATE_FIELD_INT(SIMDReplace, op);+ DELEGATE_FIELD_INT(SIMDReplace, index);+ DELEGATE_END(SIMDReplace);+ break;+ }+ case Expression::Id::SIMDShuffleId: {+ DELEGATE_START(SIMDShuffle);+ DELEGATE_FIELD_CHILD(SIMDShuffle, right);+ DELEGATE_FIELD_CHILD(SIMDShuffle, left);+ DELEGATE_FIELD_INT_ARRAY(SIMDShuffle, mask);+ DELEGATE_END(SIMDShuffle);+ break;+ }+ case Expression::Id::SIMDTernaryId: {+ DELEGATE_START(SIMDTernary);+ DELEGATE_FIELD_CHILD(SIMDTernary, c);+ DELEGATE_FIELD_CHILD(SIMDTernary, b);+ DELEGATE_FIELD_CHILD(SIMDTernary, a);+ DELEGATE_FIELD_INT(SIMDTernary, op);+ DELEGATE_END(SIMDTernary);+ break;+ }+ case Expression::Id::SIMDShiftId: {+ DELEGATE_START(SIMDShift);+ DELEGATE_FIELD_CHILD(SIMDShift, shift);+ DELEGATE_FIELD_CHILD(SIMDShift, vec);+ DELEGATE_FIELD_INT(SIMDShift, op);+ DELEGATE_END(SIMDShift);+ break;+ }+ case Expression::Id::SIMDLoadId: {+ DELEGATE_START(SIMDLoad);+ DELEGATE_FIELD_CHILD(SIMDLoad, ptr);+ DELEGATE_FIELD_INT(SIMDLoad, op);+ DELEGATE_FIELD_ADDRESS(SIMDLoad, offset);+ DELEGATE_FIELD_ADDRESS(SIMDLoad, align);+ DELEGATE_END(SIMDLoad);+ break;+ }+ case Expression::Id::SIMDLoadStoreLaneId: {+ DELEGATE_START(SIMDLoadStoreLane);+ DELEGATE_FIELD_CHILD(SIMDLoadStoreLane, vec);+ DELEGATE_FIELD_CHILD(SIMDLoadStoreLane, ptr);+ DELEGATE_FIELD_INT(SIMDLoadStoreLane, op);+ DELEGATE_FIELD_ADDRESS(SIMDLoadStoreLane, offset);+ DELEGATE_FIELD_ADDRESS(SIMDLoadStoreLane, align);+ DELEGATE_FIELD_INT(SIMDLoadStoreLane, index);+ DELEGATE_END(SIMDLoadStoreLane);+ break;+ }+ case Expression::Id::PrefetchId: {+ DELEGATE_START(Prefetch);+ DELEGATE_FIELD_CHILD(Prefetch, ptr);+ DELEGATE_FIELD_INT(Prefetch, op);+ DELEGATE_FIELD_ADDRESS(Prefetch, offset);+ DELEGATE_FIELD_ADDRESS(Prefetch, align);+ DELEGATE_END(Prefetch);+ break;+ }+ case Expression::Id::MemoryInitId: {+ DELEGATE_START(MemoryInit);+ DELEGATE_FIELD_CHILD(MemoryInit, size);+ DELEGATE_FIELD_CHILD(MemoryInit, offset);+ DELEGATE_FIELD_CHILD(MemoryInit, dest);+ DELEGATE_FIELD_INT(MemoryInit, segment);+ DELEGATE_END(MemoryInit);+ break;+ }+ case Expression::Id::DataDropId: {+ DELEGATE_START(DataDrop);+ DELEGATE_FIELD_INT(DataDrop, segment);+ DELEGATE_END(DataDrop);+ break;+ }+ case Expression::Id::MemoryCopyId: {+ DELEGATE_START(MemoryCopy);+ DELEGATE_FIELD_CHILD(MemoryCopy, size);+ DELEGATE_FIELD_CHILD(MemoryCopy, source);+ DELEGATE_FIELD_CHILD(MemoryCopy, dest);+ DELEGATE_END(MemoryCopy);+ break;+ }+ case Expression::Id::MemoryFillId: {+ DELEGATE_START(MemoryFill);+ DELEGATE_FIELD_CHILD(MemoryFill, size);+ DELEGATE_FIELD_CHILD(MemoryFill, value);+ DELEGATE_FIELD_CHILD(MemoryFill, dest);+ DELEGATE_END(MemoryFill);+ break;+ }+ case Expression::Id::ConstId: {+ DELEGATE_START(Const);+ DELEGATE_FIELD_LITERAL(Const, value);+ DELEGATE_END(Const);+ break;+ }+ case Expression::Id::UnaryId: {+ DELEGATE_START(Unary);+ DELEGATE_FIELD_CHILD(Unary, value);+ DELEGATE_FIELD_INT(Unary, op);+ DELEGATE_END(Unary);+ break;+ }+ case Expression::Id::BinaryId: {+ DELEGATE_START(Binary);+ DELEGATE_FIELD_CHILD(Binary, right);+ DELEGATE_FIELD_CHILD(Binary, left);+ DELEGATE_FIELD_INT(Binary, op);+ DELEGATE_END(Binary);+ break;+ }+ case Expression::Id::SelectId: {+ DELEGATE_START(Select);+ DELEGATE_FIELD_CHILD(Select, condition);+ DELEGATE_FIELD_CHILD(Select, ifFalse);+ DELEGATE_FIELD_CHILD(Select, ifTrue);+ DELEGATE_END(Select);+ break;+ }+ case Expression::Id::DropId: {+ DELEGATE_START(Drop);+ DELEGATE_FIELD_CHILD(Drop, value);+ DELEGATE_END(Drop);+ break;+ }+ case Expression::Id::ReturnId: {+ DELEGATE_START(Return);+ DELEGATE_FIELD_OPTIONAL_CHILD(Return, value);+ DELEGATE_END(Return);+ break;+ }+ case Expression::Id::MemorySizeId: {+ DELEGATE_START(MemorySize);+ DELEGATE_END(MemorySize);+ break;+ }+ case Expression::Id::MemoryGrowId: {+ DELEGATE_START(MemoryGrow);+ DELEGATE_FIELD_CHILD(MemoryGrow, delta);+ DELEGATE_END(MemoryGrow);+ break;+ }+ case Expression::Id::RefNullId: {+ DELEGATE_START(RefNull);+ DELEGATE_FIELD_TYPE(RefNull, type);+ DELEGATE_END(RefNull);+ break;+ }+ case Expression::Id::RefIsNullId: {+ DELEGATE_START(RefIsNull);+ DELEGATE_FIELD_CHILD(RefIsNull, value);+ DELEGATE_END(RefIsNull);+ break;+ }+ case Expression::Id::RefFuncId: {+ DELEGATE_START(RefFunc);+ DELEGATE_FIELD_NAME(RefFunc, func);+ DELEGATE_END(RefFunc);+ break;+ }+ case Expression::Id::RefEqId: {+ DELEGATE_START(RefEq);+ DELEGATE_FIELD_CHILD(RefEq, right);+ DELEGATE_FIELD_CHILD(RefEq, left);+ DELEGATE_END(RefEq);+ break;+ }+ case Expression::Id::TryId: {+ DELEGATE_START(Try);+ DELEGATE_FIELD_CHILD(Try, catchBody);+ DELEGATE_FIELD_CHILD(Try, body);+ DELEGATE_END(Try);+ break;+ }+ case Expression::Id::ThrowId: {+ DELEGATE_START(Throw);+ DELEGATE_FIELD_CHILD_VECTOR(Throw, operands);+ DELEGATE_FIELD_NAME(Throw, event);+ DELEGATE_END(Throw);+ break;+ }+ case Expression::Id::RethrowId: {+ DELEGATE_START(Rethrow);+ DELEGATE_FIELD_CHILD(Rethrow, exnref);+ DELEGATE_END(Rethrow);+ break;+ }+ case Expression::Id::BrOnExnId: {+ DELEGATE_START(BrOnExn);+ DELEGATE_FIELD_CHILD(BrOnExn, exnref);+ DELEGATE_FIELD_SCOPE_NAME_USE(BrOnExn, name);+ DELEGATE_FIELD_NAME(BrOnExn, event);+ DELEGATE_FIELD_TYPE(BrOnExn, sent);+ DELEGATE_END(BrOnExn);+ break;+ }+ case Expression::Id::NopId: {+ DELEGATE_START(Nop);+ DELEGATE_END(Nop);+ break;+ }+ case Expression::Id::UnreachableId: {+ DELEGATE_START(Unreachable);+ DELEGATE_END(Unreachable);+ break;+ }+ case Expression::Id::PopId: {+ DELEGATE_START(Pop);+ DELEGATE_END(Pop);+ break;+ }+ case Expression::Id::TupleMakeId: {+ DELEGATE_START(TupleMake);+ DELEGATE_FIELD_CHILD_VECTOR(Tuple, operands);+ DELEGATE_END(TupleMake);+ break;+ }+ case Expression::Id::TupleExtractId: {+ DELEGATE_START(TupleExtract);+ DELEGATE_FIELD_CHILD(TupleExtract, tuple);+ DELEGATE_FIELD_INT(TupleExtract, index);+ DELEGATE_END(TupleExtract);+ break;+ }+ case Expression::Id::I31NewId: {+ DELEGATE_START(I31New);+ DELEGATE_FIELD_CHILD(I31New, value);+ DELEGATE_END(I31New);+ break;+ }+ case Expression::Id::I31GetId: {+ DELEGATE_START(I31Get);+ DELEGATE_FIELD_CHILD(I31Get, i31);+ DELEGATE_FIELD_INT(I31Get, signed_);+ DELEGATE_END(I31Get);+ break;+ }+ case Expression::Id::CallRefId: {+ DELEGATE_START(CallRef);+ DELEGATE_FIELD_CHILD(CallRef, target);+ DELEGATE_FIELD_CHILD_VECTOR(CallRef, operands);+ DELEGATE_FIELD_INT(CallRef, isReturn);+ DELEGATE_END(CallRef);+ break;+ }+ case Expression::Id::RefTestId: {+ DELEGATE_START(RefTest);+ DELEGATE_FIELD_CHILD(RefTest, ref);+ DELEGATE_FIELD_CHILD(RefTest, rtt);+ DELEGATE_END(RefTest);+ break;+ }+ case Expression::Id::RefCastId: {+ DELEGATE_START(RefCast);+ DELEGATE_FIELD_CHILD(RefCast, ref);+ DELEGATE_FIELD_CHILD(RefCast, rtt);+ DELEGATE_END(RefCast);+ break;+ }+ case Expression::Id::BrOnCastId: {+ DELEGATE_START(BrOnCast);+ DELEGATE_FIELD_SCOPE_NAME_USE(BrOnCast, name);+ DELEGATE_FIELD_TYPE(BrOnCast, castType);+ DELEGATE_FIELD_CHILD(BrOnCast, ref);+ DELEGATE_FIELD_CHILD(BrOnCast, rtt);+ DELEGATE_END(BrOnCast);+ break;+ }+ case Expression::Id::RttCanonId: {+ DELEGATE_START(RttCanon);+ DELEGATE_END(RttCanon);+ break;+ }+ case Expression::Id::RttSubId: {+ DELEGATE_START(RttSub);+ DELEGATE_FIELD_CHILD(RttSub, parent);+ DELEGATE_END(RttSub);+ break;+ }+ case Expression::Id::StructNewId: {+ DELEGATE_START(StructNew);+ DELEGATE_FIELD_CHILD(StructNew, rtt);+ DELEGATE_FIELD_CHILD_VECTOR(StructNew, operands);+ DELEGATE_END(StructNew);+ break;+ }+ case Expression::Id::StructGetId: {+ DELEGATE_START(StructGet);+ DELEGATE_FIELD_INT(StructGet, index);+ DELEGATE_FIELD_CHILD(StructGet, ref);+ DELEGATE_FIELD_INT(StructGet, signed_);+ DELEGATE_END(StructGet);+ break;+ }+ case Expression::Id::StructSetId: {+ DELEGATE_START(StructSet);+ DELEGATE_FIELD_INT(StructSet, index);+ DELEGATE_FIELD_CHILD(StructSet, ref);+ DELEGATE_FIELD_CHILD(StructSet, value);+ DELEGATE_END(StructSet);+ break;+ }+ case Expression::Id::ArrayNewId: {+ DELEGATE_START(ArrayNew);+ DELEGATE_FIELD_CHILD(ArrayNew, rtt);+ DELEGATE_FIELD_CHILD(ArrayNew, size);+ DELEGATE_FIELD_OPTIONAL_CHILD(ArrayNew, init);+ DELEGATE_END(ArrayNew);+ break;+ }+ case Expression::Id::ArrayGetId: {+ DELEGATE_START(ArrayGet);+ DELEGATE_FIELD_CHILD(ArrayGet, ref);+ DELEGATE_FIELD_CHILD(ArrayGet, index);+ DELEGATE_FIELD_INT(ArrayGet, signed_);+ DELEGATE_END(ArrayGet);+ break;+ }+ case Expression::Id::ArraySetId: {+ DELEGATE_START(ArraySet);+ DELEGATE_FIELD_CHILD(ArrayGet, ref);+ DELEGATE_FIELD_CHILD(ArrayGet, index);+ DELEGATE_FIELD_CHILD(ArrayGet, value);+ DELEGATE_END(ArraySet);+ break;+ }+ case Expression::Id::ArrayLenId: {+ DELEGATE_START(ArrayLen);+ DELEGATE_FIELD_CHILD(ArrayLen, ref);+ DELEGATE_END(ArrayLen);+ break;+ }+}++#undef DELEGATE_ID+#undef DELEGATE_START+#undef DELEGATE_END+#undef DELEGATE_FIELD_CHILD+#undef DELEGATE_FIELD_OPTIONAL_CHILD+#undef DELEGATE_FIELD_CHILD_VECTOR+#undef DELEGATE_FIELD_INT+#undef DELEGATE_FIELD_INT_ARRAY+#undef DELEGATE_FIELD_LITERAL+#undef DELEGATE_FIELD_NAME+#undef DELEGATE_FIELD_SCOPE_NAME_DEF+#undef DELEGATE_FIELD_SCOPE_NAME_USE+#undef DELEGATE_FIELD_SCOPE_NAME_USE_VECTOR+#undef DELEGATE_FIELD_SIGNATURE+#undef DELEGATE_FIELD_TYPE+#undef DELEGATE_FIELD_ADDRESS+#undef DELEGATE_GET_FIELD
+ binaryen/src/wasm-delegations.h view
@@ -0,0 +1,84 @@+/*+ * Copyright 2020 WebAssembly Community Group participants+ *+ * Licensed under the Apache License, Version 2.0 (the "License");+ * you may not use this file except in compliance with the License.+ * You may obtain a copy of the License at+ *+ * http://www.apache.org/licenses/LICENSE-2.0+ *+ * Unless required by applicable law or agreed to in writing, software+ * distributed under the License is distributed on an "AS IS" BASIS,+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+ * See the License for the specific language governing permissions and+ * limitations under the License.+ */++DELEGATE(Nop);+DELEGATE(Block);+DELEGATE(If);+DELEGATE(Loop);+DELEGATE(Break);+DELEGATE(Switch);+DELEGATE(Call);+DELEGATE(CallIndirect);+DELEGATE(LocalGet);+DELEGATE(LocalSet);+DELEGATE(GlobalGet);+DELEGATE(GlobalSet);+DELEGATE(Load);+DELEGATE(Store);+DELEGATE(AtomicRMW);+DELEGATE(AtomicCmpxchg);+DELEGATE(AtomicWait);+DELEGATE(AtomicNotify);+DELEGATE(AtomicFence);+DELEGATE(SIMDExtract);+DELEGATE(SIMDReplace);+DELEGATE(SIMDShuffle);+DELEGATE(SIMDTernary);+DELEGATE(SIMDShift);+DELEGATE(SIMDLoad);+DELEGATE(SIMDLoadStoreLane);+DELEGATE(Prefetch);+DELEGATE(MemoryInit);+DELEGATE(DataDrop);+DELEGATE(MemoryCopy);+DELEGATE(MemoryFill);+DELEGATE(Const);+DELEGATE(Unary);+DELEGATE(Binary);+DELEGATE(Select);+DELEGATE(Drop);+DELEGATE(Return);+DELEGATE(MemorySize);+DELEGATE(MemoryGrow);+DELEGATE(Unreachable);+DELEGATE(Pop);+DELEGATE(RefNull);+DELEGATE(RefIsNull);+DELEGATE(RefFunc);+DELEGATE(RefEq);+DELEGATE(Try);+DELEGATE(Throw);+DELEGATE(Rethrow);+DELEGATE(BrOnExn);+DELEGATE(TupleMake);+DELEGATE(TupleExtract);+DELEGATE(I31New);+DELEGATE(I31Get);+DELEGATE(CallRef);+DELEGATE(RefTest);+DELEGATE(RefCast);+DELEGATE(BrOnCast);+DELEGATE(RttCanon);+DELEGATE(RttSub);+DELEGATE(StructNew);+DELEGATE(StructGet);+DELEGATE(StructSet);+DELEGATE(ArrayNew);+DELEGATE(ArrayGet);+DELEGATE(ArraySet);+DELEGATE(ArrayLen);++#undef DELEGATE
binaryen/src/wasm-emscripten.h view
@@ -33,16 +33,7 @@ : wasm(wasm), builder(wasm), stackPointerOffset(stackPointerOffset), useStackPointerGlobal(stackPointerOffset == 0) {} - Function* generateAssignGOTEntriesFunction();- void generatePostInstantiateFunction();-- // Remove the import of a mutable __stack_pointer and instead initialize the- // stack pointer from an immutable import.- void internalizeStackPointerGlobal();-- std::string- generateEmscriptenMetadata(Address staticBump,- std::vector<Name> const& initializerFunctions);+ std::string generateEmscriptenMetadata(Name initializer); void fixInvokeFunctionNames();
binaryen/src/wasm-features.h view
@@ -38,7 +38,8 @@ Multivalue = 1 << 9, GC = 1 << 10, Memory64 = 1 << 11,- All = (1 << 12) - 1+ TypedFunctionReferences = 1 << 12,+ All = (1 << 13) - 1 }; static std::string toString(Feature f) {@@ -67,6 +68,8 @@ return "gc"; case Memory64: return "memory64";+ case TypedFunctionReferences:+ return "typed-function-references"; default: WASM_UNREACHABLE("unexpected feature"); }@@ -92,6 +95,9 @@ bool hasMultivalue() const { return (features & Multivalue) != 0; } bool hasGC() const { return (features & GC) != 0; } bool hasMemory64() const { return (features & Memory64) != 0; }+ bool hasTypedFunctionReferences() const {+ return (features & TypedFunctionReferences) != 0;+ } bool hasAll() const { return (features & All) != 0; } void makeMVP() { features = MVP; }@@ -110,6 +116,9 @@ void setMultivalue(bool v = true) { set(Multivalue, v); } void setGC(bool v = true) { set(GC, v); } void setMemory64(bool v = true) { set(Memory64, v); }+ void setTypedFunctionReferences(bool v = true) {+ set(TypedFunctionReferences, v);+ } void setAll(bool v = true) { features = v ? All : MVP; } void enable(const FeatureSet& other) { features |= other.features; }
binaryen/src/wasm-interpreter.h view
@@ -60,6 +60,7 @@ Flow(Literals& values) : values(values) {} Flow(Literals&& values) : values(std::move(values)) {} Flow(Name breakTo) : values(), breakTo(breakTo) {}+ Flow(Name breakTo, Literal value) : values{value}, breakTo(breakTo) {} Literals values; Name breakTo; // if non-null, a break is going on@@ -463,6 +464,8 @@ return value.allTrueI8x16(); case BitmaskVecI8x16: return value.bitmaskI8x16();+ case PopcntVecI8x16:+ return value.popcntI8x16(); case AbsVecI16x8: return value.absI16x8(); case NegVecI16x8:@@ -485,10 +488,8 @@ return value.bitmaskI32x4(); case NegVecI64x2: return value.negI64x2();- case AnyTrueVecI64x2:- return value.anyTrueI64x2();- case AllTrueVecI64x2:- return value.allTrueI64x2();+ case BitmaskVecI64x2:+ WASM_UNREACHABLE("unimp"); case AbsVecF32x4: return value.absF32x4(); case NegVecF32x4:@@ -517,6 +518,14 @@ return value.truncF64x2(); case NearestVecF64x2: return value.nearestF64x2();+ case ExtAddPairwiseSVecI8x16ToI16x8:+ WASM_UNREACHABLE("unimp");+ case ExtAddPairwiseUVecI8x16ToI16x8:+ WASM_UNREACHABLE("unimp");+ case ExtAddPairwiseSVecI16x8ToI32x4:+ WASM_UNREACHABLE("unimp");+ case ExtAddPairwiseUVecI16x8ToI32x4:+ WASM_UNREACHABLE("unimp"); case TruncSatSVecF32x4ToVecI32x4: return value.truncSatToSI32x4(); case TruncSatUVecF32x4ToVecI32x4:@@ -549,6 +558,11 @@ return value.widenLowUToVecI32x4(); case WidenHighUVecI16x8ToVecI32x4: return value.widenHighUToVecI32x4();+ case WidenLowSVecI32x4ToVecI64x2:+ case WidenHighSVecI32x4ToVecI64x2:+ case WidenLowUVecI32x4ToVecI64x2:+ case WidenHighUVecI32x4ToVecI64x2:+ WASM_UNREACHABLE("unimp"); case InvalidUnary: WASM_UNREACHABLE("invalid unary op"); }@@ -794,6 +808,8 @@ return left.geSI32x4(right); case GeUVecI32x4: return left.geUI32x4(right);+ case EqVecI64x2:+ return left.eqI64x2(right); case EqVecF32x4: return left.eqF32x4(right); case NeVecF32x4:@@ -876,6 +892,16 @@ return left.maxUI16x8(right); case AvgrUVecI16x8: return left.avgrUI16x8(right);+ case Q15MulrSatSVecI16x8:+ return left.q15MulrSatSI16x8(right);+ case ExtMulLowSVecI16x8:+ return left.extMulLowSI16x8(right);+ case ExtMulHighSVecI16x8:+ return left.extMulHighSI16x8(right);+ case ExtMulLowUVecI16x8:+ return left.extMulLowUI16x8(right);+ case ExtMulHighUVecI16x8:+ return left.extMulHighUI16x8(right); case AddVecI32x4: return left.addI32x4(right); case SubVecI32x4:@@ -892,12 +918,28 @@ return left.maxUI32x4(right); case DotSVecI16x8ToVecI32x4: return left.dotSI16x8toI32x4(right);+ case ExtMulLowSVecI32x4:+ return left.extMulLowSI32x4(right);+ case ExtMulHighSVecI32x4:+ return left.extMulHighSI32x4(right);+ case ExtMulLowUVecI32x4:+ return left.extMulLowUI32x4(right);+ case ExtMulHighUVecI32x4:+ return left.extMulHighUI32x4(right); case AddVecI64x2: return left.addI64x2(right); case SubVecI64x2: return left.subI64x2(right); case MulVecI64x2: return left.mulI64x2(right);+ case ExtMulLowSVecI64x2:+ return left.extMulLowSI64x2(right);+ case ExtMulHighSVecI64x2:+ return left.extMulHighSI64x2(right);+ case ExtMulLowUVecI64x2:+ return left.extMulLowUI64x2(right);+ case ExtMulHighUVecI64x2:+ return left.extMulHighUI64x2(right); case AddVecF32x4: return left.addF32x4(right);@@ -1039,7 +1081,7 @@ case Bitselect: return c.bitselectV128(a, b); default:- // TODO: implement qfma/qfms+ // TODO: implement qfma/qfms and signselect WASM_UNREACHABLE("not implemented"); } }@@ -1125,6 +1167,14 @@ NOTE_ENTER("Nop"); return Flow(); }+ Flow visitPrefetch(Prefetch* curr) {+ NOTE_ENTER("Prefetch");+ Flow flow = visit(curr->ptr);+ if (flow.breaking()) {+ return flow;+ }+ return Flow();+ } Flow visitUnreachable(Unreachable* curr) { NOTE_ENTER("Unreachable"); trap("unreachable");@@ -1240,7 +1290,11 @@ Flow visitSIMDLoadSplat(SIMDLoad* curr) { WASM_UNREACHABLE("unimp"); } Flow visitSIMDLoadExtend(SIMDLoad* curr) { WASM_UNREACHABLE("unimp"); } Flow visitSIMDLoadZero(SIMDLoad* curr) { WASM_UNREACHABLE("unimp"); }+ Flow visitSIMDLoadStoreLane(SIMDLoadStoreLane* curr) {+ WASM_UNREACHABLE("unimp");+ } Flow visitPop(Pop* curr) { WASM_UNREACHABLE("unimp"); }+ Flow visitCallRef(CallRef* curr) { WASM_UNREACHABLE("unimp"); } Flow visitRefNull(RefNull* curr) { NOTE_ENTER("RefNull"); return Literal::makeNull(curr->type);@@ -1258,7 +1312,7 @@ Flow visitRefFunc(RefFunc* curr) { NOTE_ENTER("RefFunc"); NOTE_NAME(curr->func);- return Literal::makeFunc(curr->func);+ return Literal::makeFunc(curr->func, curr->type); } Flow visitRefEq(RefEq* curr) { NOTE_ENTER("RefEq");@@ -1344,58 +1398,287 @@ NOTE_EVAL1(value); return Literal(value.geti31(curr->signed_)); }++ // Helper for ref.test, ref.cast, and br_on_cast, which share almost all their+ // logic except for what they return.+ struct Cast {+ enum Outcome {+ // We took a break before doing anything.+ Break,+ // The input was null.+ Null,+ // The cast succeeded.+ Success,+ // The cast failed.+ Failure+ } outcome;++ Flow breaking;+ Literal originalRef;+ Literal castRef;+ };++ template<typename T> Cast doCast(T* curr) {+ Cast cast;+ Flow ref = this->visit(curr->ref);+ if (ref.breaking()) {+ cast.outcome = cast.Break;+ cast.breaking = ref;+ return cast;+ }+ Flow rtt = this->visit(curr->rtt);+ if (rtt.breaking()) {+ cast.outcome = cast.Break;+ cast.breaking = rtt;+ return cast;+ }+ cast.originalRef = ref.getSingleValue();+ auto gcData = cast.originalRef.getGCData();+ if (!gcData) {+ cast.outcome = cast.Null;+ return cast;+ }+ auto refRtt = gcData->rtt;+ auto intendedRtt = rtt.getSingleValue();+ if (!refRtt.isSubRtt(intendedRtt)) {+ cast.outcome = cast.Failure;+ } else {+ cast.outcome = cast.Success;+ cast.castRef =+ Literal(gcData, Type(intendedRtt.type.getHeapType(), Nullable));+ }+ return cast;+ }+ Flow visitRefTest(RefTest* curr) { NOTE_ENTER("RefTest");- WASM_UNREACHABLE("TODO (gc): ref.test");+ auto cast = doCast(curr);+ if (cast.outcome == cast.Break) {+ return cast.breaking;+ }+ return Literal(int32_t(cast.outcome == cast.Success)); } Flow visitRefCast(RefCast* curr) { NOTE_ENTER("RefCast");- WASM_UNREACHABLE("TODO (gc): ref.cast");+ auto cast = doCast(curr);+ if (cast.outcome == cast.Break) {+ return cast.breaking;+ }+ if (cast.outcome == cast.Null) {+ return Literal::makeNull(curr->type);+ }+ if (cast.outcome == cast.Failure) {+ trap("cast error");+ }+ assert(cast.outcome == cast.Success);+ return cast.castRef; } Flow visitBrOnCast(BrOnCast* curr) { NOTE_ENTER("BrOnCast");- WASM_UNREACHABLE("TODO (gc): br_on_cast");- }- Flow visitRttCanon(RttCanon* curr) {- NOTE_ENTER("RttCanon");- WASM_UNREACHABLE("TODO (gc): rtt.canon");+ auto cast = doCast(curr);+ if (cast.outcome == cast.Break) {+ return cast.breaking;+ }+ if (cast.outcome == cast.Null || cast.outcome == cast.Failure) {+ return cast.originalRef;+ }+ assert(cast.outcome == cast.Success);+ return Flow(curr->name, cast.castRef); }+ Flow visitRttCanon(RttCanon* curr) { return Literal(curr->type); } Flow visitRttSub(RttSub* curr) {- NOTE_ENTER("RttSub");- WASM_UNREACHABLE("TODO (gc): rtt.sub");+ Flow parent = this->visit(curr->parent);+ if (parent.breaking()) {+ return parent;+ }+ auto parentValue = parent.getSingleValue();+ auto newSupers = std::make_unique<RttSupers>(parentValue.getRttSupers());+ newSupers->push_back(parentValue.type);+ return Literal(std::move(newSupers), curr->type); } Flow visitStructNew(StructNew* curr) { NOTE_ENTER("StructNew");- WASM_UNREACHABLE("TODO (gc): struct.new");+ auto rtt = this->visit(curr->rtt);+ if (rtt.breaking()) {+ return rtt;+ }+ const auto& fields = curr->rtt->type.getHeapType().getStruct().fields;+ Literals data(fields.size());+ for (Index i = 0; i < fields.size(); i++) {+ if (curr->isWithDefault()) {+ data[i] = Literal::makeZero(fields[i].type);+ } else {+ auto value = this->visit(curr->operands[i]);+ if (value.breaking()) {+ return value;+ }+ data[i] = value.getSingleValue();+ }+ }+ return Flow(Literal(std::make_shared<GCData>(rtt.getSingleValue(), data),+ curr->type)); } Flow visitStructGet(StructGet* curr) { NOTE_ENTER("StructGet");- WASM_UNREACHABLE("TODO (gc): struct.get");+ Flow ref = this->visit(curr->ref);+ if (ref.breaking()) {+ return ref;+ }+ auto data = ref.getSingleValue().getGCData();+ if (!data) {+ trap("null ref");+ }+ auto field = curr->ref->type.getHeapType().getStruct().fields[curr->index];+ return extendForPacking(data->values[curr->index], field, curr->signed_); } Flow visitStructSet(StructSet* curr) { NOTE_ENTER("StructSet");- WASM_UNREACHABLE("TODO (gc): struct.set");+ Flow ref = this->visit(curr->ref);+ if (ref.breaking()) {+ return ref;+ }+ Flow value = this->visit(curr->value);+ if (value.breaking()) {+ return value;+ }+ auto data = ref.getSingleValue().getGCData();+ if (!data) {+ trap("null ref");+ }+ auto field = curr->ref->type.getHeapType().getStruct().fields[curr->index];+ data->values[curr->index] =+ truncateForPacking(value.getSingleValue(), field);+ return Flow(); } Flow visitArrayNew(ArrayNew* curr) { NOTE_ENTER("ArrayNew");- WASM_UNREACHABLE("TODO (gc): array.new");+ auto rtt = this->visit(curr->rtt);+ if (rtt.breaking()) {+ return rtt;+ }+ auto size = this->visit(curr->size);+ if (size.breaking()) {+ return size;+ }+ const auto& element = curr->rtt->type.getHeapType().getArray().element;+ Index num = size.getSingleValue().geti32();+ Literals data(num);+ if (curr->isWithDefault()) {+ for (Index i = 0; i < num; i++) {+ data[i] = Literal::makeZero(element.type);+ }+ } else {+ auto init = this->visit(curr->init);+ if (init.breaking()) {+ return init;+ }+ auto value = init.getSingleValue();+ for (Index i = 0; i < num; i++) {+ data[i] = value;+ }+ }+ return Flow(Literal(std::make_shared<GCData>(rtt.getSingleValue(), data),+ curr->type)); } Flow visitArrayGet(ArrayGet* curr) { NOTE_ENTER("ArrayGet");- WASM_UNREACHABLE("TODO (gc): array.get");+ Flow ref = this->visit(curr->ref);+ if (ref.breaking()) {+ return ref;+ }+ Flow index = this->visit(curr->index);+ if (index.breaking()) {+ return index;+ }+ auto data = ref.getSingleValue().getGCData();+ if (!data) {+ trap("null ref");+ }+ Index i = index.getSingleValue().geti32();+ if (i >= data->values.size()) {+ trap("array oob");+ }+ auto field = curr->ref->type.getHeapType().getArray().element;+ return extendForPacking(data->values[i], field, curr->signed_); } Flow visitArraySet(ArraySet* curr) { NOTE_ENTER("ArraySet");- WASM_UNREACHABLE("TODO (gc): array.set");+ Flow ref = this->visit(curr->ref);+ if (ref.breaking()) {+ return ref;+ }+ Flow index = this->visit(curr->index);+ if (index.breaking()) {+ return index;+ }+ Flow value = this->visit(curr->value);+ if (value.breaking()) {+ return value;+ }+ auto data = ref.getSingleValue().getGCData();+ if (!data) {+ trap("null ref");+ }+ Index i = index.getSingleValue().geti32();+ if (i >= data->values.size()) {+ trap("array oob");+ }+ auto field = curr->ref->type.getHeapType().getArray().element;+ data->values[i] = truncateForPacking(value.getSingleValue(), field);+ return Flow(); } Flow visitArrayLen(ArrayLen* curr) { NOTE_ENTER("ArrayLen");- WASM_UNREACHABLE("TODO (gc): array.len");+ Flow ref = this->visit(curr->ref);+ if (ref.breaking()) {+ return ref;+ }+ auto data = ref.getSingleValue().getGCData();+ if (!data) {+ trap("null ref");+ }+ return Literal(int32_t(data->values.size())); } virtual void trap(const char* why) { WASM_UNREACHABLE("unimp"); } virtual void throwException(Literal exn) { WASM_UNREACHABLE("unimp"); }++private:+ // Truncate the value if we need to. The storage is just a list of Literals,+ // so we can't just write the value like we would to a C struct field and+ // expect it to truncate for us. Instead, we truncate so the stored value is+ // proper for the type.+ Literal truncateForPacking(Literal value, const Field& field) {+ if (field.type == Type::i32) {+ int32_t c = value.geti32();+ if (field.packedType == Field::i8) {+ value = Literal(c & 0xff);+ } else if (field.packedType == Field::i16) {+ value = Literal(c & 0xffff);+ }+ }+ return value;+ }++ Literal extendForPacking(Literal value, const Field& field, bool signed_) {+ if (field.type == Type::i32) {+ int32_t c = value.geti32();+ if (field.packedType == Field::i8) {+ // The stored value should already be truncated.+ assert(c == (c & 0xff));+ if (signed_) {+ value = Literal((c << 24) >> 24);+ }+ } else if (field.packedType == Field::i16) {+ assert(c == (c & 0xffff));+ if (signed_) {+ value = Literal((c << 16) >> 16);+ }+ }+ }+ return value;+ } }; // Execute a suspected constant expression (precompute and C-API).@@ -1562,11 +1845,14 @@ } return Flow(NONCONSTANT_FLOW); }- Flow visitCallIndirect(CallIndirect* curr) { NOTE_ENTER("CallIndirect"); return Flow(NONCONSTANT_FLOW); }+ Flow visitCallRef(CallRef* curr) {+ NOTE_ENTER("CallRef");+ return Flow(NONCONSTANT_FLOW);+ } Flow visitLoad(Load* curr) { NOTE_ENTER("Load"); return Flow(NONCONSTANT_FLOW);@@ -1627,6 +1913,10 @@ NOTE_ENTER("SIMDLoadExtend"); return Flow(NONCONSTANT_FLOW); }+ Flow visitSIMDLoadStoreLane(SIMDLoadStoreLane* curr) {+ NOTE_ENTER("SIMDLoadStoreLane");+ return Flow(NONCONSTANT_FLOW);+ } Flow visitPop(Pop* curr) { NOTE_ENTER("Pop"); return Flow(NONCONSTANT_FLOW);@@ -2060,6 +2350,37 @@ } return ret; }+ Flow visitCallRef(CallRef* curr) {+ NOTE_ENTER("CallRef");+ LiteralList arguments;+ Flow flow = this->generateArguments(curr->operands, arguments);+ if (flow.breaking()) {+ return flow;+ }+ Flow target = this->visit(curr->target);+ if (target.breaking()) {+ return target;+ }+ if (target.getSingleValue().isNull()) {+ trap("null target in call_ref");+ }+ Name funcName = target.getSingleValue().getFunc();+ auto* func = instance.wasm.getFunction(funcName);+ Flow ret;+ if (func->imported()) {+ ret.values = instance.externalInterface->callImport(func, arguments);+ } else {+ ret.values = instance.callFunctionInternal(funcName, arguments);+ }+#ifdef WASM_INTERPRETER_DEBUG+ std::cout << "(returned to " << scope.function->name << ")\n";+#endif+ // TODO: make this a proper tail call (return first)+ if (curr->isReturn) {+ ret.breakTo = RETURN_FLOW;+ }+ return ret;+ } Flow visitLocalGet(LocalGet* curr) { NOTE_ENTER("LocalGet");@@ -2158,22 +2479,22 @@ NOTE_EVAL1(loaded); auto computed = value.getSingleValue(); switch (curr->op) {- case Add:+ case RMWAdd: computed = loaded.add(computed); break;- case Sub:+ case RMWSub: computed = loaded.sub(computed); break;- case And:+ case RMWAnd: computed = loaded.and_(computed); break;- case Or:+ case RMWOr: computed = loaded.or_(computed); break;- case Xor:+ case RMWXor: computed = loaded.xor_(computed); break;- case Xchg:+ case RMWXchg: break; } instance.doAtomicStore(addr, curr->bytes, computed);@@ -2369,7 +2690,7 @@ } NOTE_EVAL1(flow); Address src = instance.getFinalAddress(- curr, flow.getSingleValue(), curr->op == Load32Zero ? 32 : 64);+ curr, flow.getSingleValue(), curr->getMemBytes()); auto zero = Literal::makeZero(curr->op == Load32Zero ? Type::i32 : Type::i64); if (curr->op == Load32Zero) {@@ -2379,6 +2700,76 @@ auto val = Literal(instance.externalInterface->load64u(src)); return Literal(std::array<Literal, 2>{{val, zero}}); }+ }+ Flow visitSIMDLoadStoreLane(SIMDLoadStoreLane* curr) {+ NOTE_ENTER("SIMDLoadStoreLane");+ Flow flow = this->visit(curr->ptr);+ if (flow.breaking()) {+ return flow;+ }+ NOTE_EVAL1(flow);+ Address addr = instance.getFinalAddress(+ curr, flow.getSingleValue(), curr->getMemBytes());+ flow = this->visit(curr->vec);+ if (flow.breaking()) {+ return flow;+ }+ Literal vec = flow.getSingleValue();+ switch (curr->op) {+ case LoadLaneVec8x16:+ case StoreLaneVec8x16: {+ std::array<Literal, 16> lanes = vec.getLanesUI8x16();+ if (curr->isLoad()) {+ lanes[curr->index] =+ Literal(instance.externalInterface->load8u(addr));+ return Literal(lanes);+ } else {+ instance.externalInterface->store8(addr,+ lanes[curr->index].geti32());+ return {};+ }+ }+ case LoadLaneVec16x8:+ case StoreLaneVec16x8: {+ std::array<Literal, 8> lanes = vec.getLanesUI16x8();+ if (curr->isLoad()) {+ lanes[curr->index] =+ Literal(instance.externalInterface->load16u(addr));+ return Literal(lanes);+ } else {+ instance.externalInterface->store16(addr,+ lanes[curr->index].geti32());+ return {};+ }+ }+ case LoadLaneVec32x4:+ case StoreLaneVec32x4: {+ std::array<Literal, 4> lanes = vec.getLanesI32x4();+ if (curr->isLoad()) {+ lanes[curr->index] =+ Literal(instance.externalInterface->load32u(addr));+ return Literal(lanes);+ } else {+ instance.externalInterface->store32(addr,+ lanes[curr->index].geti32());+ return {};+ }+ }+ case StoreLaneVec64x2:+ case LoadLaneVec64x2: {+ std::array<Literal, 2> lanes = vec.getLanesI64x2();+ if (curr->isLoad()) {+ lanes[curr->index] =+ Literal(instance.externalInterface->load64u(addr));+ return Literal(lanes);+ } else {+ instance.externalInterface->store64(addr,+ lanes[curr->index].geti64());+ return {};+ }+ }+ }+ WASM_UNREACHABLE("unexpected op"); } Flow visitMemorySize(MemorySize* curr) { NOTE_ENTER("MemorySize");
binaryen/src/wasm-module-building.h view
@@ -122,15 +122,6 @@ return; } - // Before parallelism, create all passes on the main thread here, to ensure- // prepareToRun() is called for each pass before we start to optimize- // functions.- {- PassRunner passRunner(wasm, passOptions);- addPrePasses(passRunner);- passRunner.addDefaultFunctionOptimizationPasses();- }- // prepare work list endMarker = new Function(); list = new std::atomic<Function*>[numFunctions];
− binaryen/src/wasm-printing.h
@@ -1,70 +0,0 @@-/*- * Copyright 2016 WebAssembly Community Group participants- *- * Licensed under the Apache License, Version 2.0 (the "License");- * you may not use this file except in compliance with the License.- * You may obtain a copy of the License at- *- * http://www.apache.org/licenses/LICENSE-2.0- *- * Unless required by applicable law or agreed to in writing, software- * distributed under the License is distributed on an "AS IS" BASIS,- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.- * See the License for the specific language governing permissions and- * limitations under the License.- */--#ifndef wasm_wasm_printing_h-#define wasm_wasm_printing_h--#include <ostream>--#include "pass.h"-#include "wasm.h"--namespace wasm {--struct WasmPrinter {- static std::ostream& printModule(Module* module, std::ostream& o);-- static std::ostream& printModule(Module* module);-- static std::ostream& printExpression(Expression* expression,- std::ostream& o,- bool minify = false,- bool full = false);-- static std::ostream&- printStackInst(StackInst* inst, std::ostream& o, Function* func = nullptr);-- static std::ostream&- printStackIR(StackIR* ir, std::ostream& o, Function* func = nullptr);-};--} // namespace wasm--namespace std {--inline std::ostream& operator<<(std::ostream& o, wasm::Module& module) {- return wasm::WasmPrinter::printModule(&module, o);-}--inline std::ostream& operator<<(std::ostream& o, wasm::Expression& expression) {- return wasm::WasmPrinter::printExpression(&expression, o);-}--inline std::ostream& operator<<(std::ostream& o, wasm::Expression* expression) {- return wasm::WasmPrinter::printExpression(expression, o);-}--inline std::ostream& operator<<(std::ostream& o, wasm::StackInst& inst) {- return wasm::WasmPrinter::printStackInst(&inst, o);-}--inline std::ostream& operator<<(std::ostream& o, wasm::StackIR& ir) {- return wasm::WasmPrinter::printStackIR(&ir, o);-}--} // namespace std--#endif // wasm_wasm_printing_h
binaryen/src/wasm-s-parser.h view
@@ -77,6 +77,11 @@ Element* setString(cashew::IString str__, bool dollared__, bool quoted__); Element* setMetadata(size_t line_, size_t col_, SourceLocation* startLoc_); + // comparisons+ bool operator==(Name name) { return isStr() && str() == name; }++ template<typename T> bool operator!=(T t) { return !(*this == t); }+ // printing friend std::ostream& operator<<(std::ostream& o, Element& e); void dump();@@ -112,16 +117,21 @@ Module& wasm; MixedArena& allocator; IRProfile profile;- std::vector<Signature> signatures;- std::unordered_map<std::string, size_t> signatureIndices;++ // The main list of types declared in the module+ std::vector<HeapType> types;+ std::unordered_map<std::string, size_t> typeIndices;+ std::vector<Name> functionNames; std::vector<Name> globalNames; std::vector<Name> eventNames; int functionCounter = 0; int globalCounter = 0; int eventCounter = 0;+ int tableCounter = 0;+ int memoryCounter = 0; // we need to know function return types before we parse their contents- std::map<Name, Type> functionTypes;+ std::map<Name, Signature> functionSignatures; std::unordered_map<cashew::IString, Index> debugInfoFileIndices; public:@@ -142,7 +152,6 @@ UniqueNameMapper nameMapper; - Signature getFunctionSignature(Element& s); Name getFunctionName(Element& s); Name getGlobalName(Element& s); Name getEventName(Element& s);@@ -210,6 +219,8 @@ Expression* makeSIMDTernary(Element& s, SIMDTernaryOp op); Expression* makeSIMDShift(Element& s, SIMDShiftOp op); Expression* makeSIMDLoad(Element& s, SIMDLoadOp op);+ Expression* makeSIMDLoadStoreLane(Element& s, SIMDLoadStoreLaneOp op);+ Expression* makePrefetch(Element& s, PrefetchOp op); Expression* makeMemoryInit(Element& s); Expression* makeDataDrop(Element& s); Expression* makeMemoryCopy(Element& s);@@ -243,6 +254,7 @@ Expression* makeBrOnExn(Element& s); Expression* makeTupleMake(Element& s); Expression* makeTupleExtract(Element& s);+ Expression* makeCallRef(Element& s, bool isReturn); Expression* makeI31New(Element& s); Expression* makeI31Get(Element& s, bool signed_); Expression* makeRefTest(Element& s);@@ -251,12 +263,11 @@ Expression* makeRttCanon(Element& s); Expression* makeRttSub(Element& s); Expression* makeStructNew(Element& s, bool default_);- Expression* makeStructGet(Element& s);- Expression* makeStructGet(Element& s, bool signed_);+ Index getStructIndex(const HeapType& type, Element& s);+ Expression* makeStructGet(Element& s, bool signed_ = false); Expression* makeStructSet(Element& s); Expression* makeArrayNew(Element& s, bool default_);- Expression* makeArrayGet(Element& s);- Expression* makeArrayGet(Element& s, bool signed_);+ Expression* makeArrayGet(Element& s, bool signed_ = false); Expression* makeArraySet(Element& s); Expression* makeArrayLen(Element& s); @@ -278,17 +289,30 @@ void stringToBinary(const char* input, size_t size, std::vector<char>& data); void parseMemory(Element& s, bool preParseImport = false); void parseData(Element& s);- void parseInnerData(Element& s, Index i, Expression* offset, bool isPassive);+ void parseInnerData(+ Element& s, Index i, Name name, Expression* offset, bool isPassive); void parseExport(Element& s); void parseImport(Element& s); void parseGlobal(Element& s, bool preParseImport = false); void parseTable(Element& s, bool preParseImport = false); void parseElem(Element& s); void parseInnerElem(Element& s, Index i = 1, Expression* offset = nullptr);++ // Parses something like (func ..), (array ..), (struct)+ HeapType parseHeapType(Element& s);+ void parseType(Element& s); void parseEvent(Element& s, bool preParseImport = false); Function::DebugLocation getDebugLocation(const SourceLocation& loc);++ // Struct/Array instructions have an unnecessary heap type that is just for+ // validation (except for the case of unreachability, but that's not a problem+ // anyhow, we can ignore it there). That is, we also have a reference / rtt+ // child from which we can infer the type anyhow, and we just need to check+ // that type is the same.+ void+ validateHeapTypeUsingChild(Expression* child, HeapType heapType, Element& s); }; } // namespace wasm
binaryen/src/wasm-stack.h view
@@ -99,69 +99,10 @@ } } - void visitBlock(Block* curr);- void visitIf(If* curr);- void visitLoop(Loop* curr);- void visitBreak(Break* curr);- void visitSwitch(Switch* curr);- void visitCall(Call* curr);- void visitCallIndirect(CallIndirect* curr);- void visitLocalGet(LocalGet* curr);- void visitLocalSet(LocalSet* curr);- void visitGlobalGet(GlobalGet* curr);- void visitGlobalSet(GlobalSet* curr);- void visitLoad(Load* curr);- void visitStore(Store* curr);- void visitAtomicRMW(AtomicRMW* curr);- void visitAtomicCmpxchg(AtomicCmpxchg* curr);- void visitAtomicWait(AtomicWait* curr);- void visitAtomicNotify(AtomicNotify* curr);- void visitAtomicFence(AtomicFence* curr);- void visitSIMDExtract(SIMDExtract* curr);- void visitSIMDReplace(SIMDReplace* curr);- void visitSIMDShuffle(SIMDShuffle* curr);- void visitSIMDTernary(SIMDTernary* curr);- void visitSIMDShift(SIMDShift* curr);- void visitSIMDLoad(SIMDLoad* curr);- void visitMemoryInit(MemoryInit* curr);- void visitDataDrop(DataDrop* curr);- void visitMemoryCopy(MemoryCopy* curr);- void visitMemoryFill(MemoryFill* curr);- void visitConst(Const* curr);- void visitUnary(Unary* curr);- void visitBinary(Binary* curr);- void visitSelect(Select* curr);- void visitReturn(Return* curr);- void visitMemorySize(MemorySize* curr);- void visitMemoryGrow(MemoryGrow* curr);- void visitRefNull(RefNull* curr);- void visitRefIsNull(RefIsNull* curr);- void visitRefFunc(RefFunc* curr);- void visitRefEq(RefEq* curr);- void visitTry(Try* curr);- void visitThrow(Throw* curr);- void visitRethrow(Rethrow* curr);- void visitBrOnExn(BrOnExn* curr);- void visitNop(Nop* curr);- void visitUnreachable(Unreachable* curr);- void visitDrop(Drop* curr);- void visitPop(Pop* curr);- void visitTupleMake(TupleMake* curr);- void visitTupleExtract(TupleExtract* curr);- void visitI31New(I31New* curr);- void visitI31Get(I31Get* curr);- void visitRefTest(RefTest* curr);- void visitRefCast(RefCast* curr);- void visitBrOnCast(BrOnCast* curr);- void visitRttCanon(RttCanon* curr);- void visitRttSub(RttSub* curr);- void visitStructNew(StructNew* curr);- void visitStructGet(StructGet* curr);- void visitStructSet(StructSet* curr);- void visitArrayNew(ArrayNew* curr);- void visitArrayGet(ArrayGet* curr);- void visitArraySet(ArraySet* curr);- void visitArrayLen(ArrayLen* curr);+#define DELEGATE(CLASS_TO_VISIT) \+ void visit##CLASS_TO_VISIT(CLASS_TO_VISIT* curr);++#include "wasm-delegations.h" void emitResultType(Type type); void emitIfElse(If* curr);
binaryen/src/wasm-traversal.h view
@@ -37,1373 +37,314 @@ template<typename SubType, typename ReturnType = void> struct Visitor { // Expression visitors- ReturnType visitBlock(Block* curr) { return ReturnType(); }- ReturnType visitIf(If* curr) { return ReturnType(); }- ReturnType visitLoop(Loop* curr) { return ReturnType(); }- ReturnType visitBreak(Break* curr) { return ReturnType(); }- ReturnType visitSwitch(Switch* curr) { return ReturnType(); }- ReturnType visitCall(Call* curr) { return ReturnType(); }- ReturnType visitCallIndirect(CallIndirect* curr) { return ReturnType(); }- ReturnType visitLocalGet(LocalGet* curr) { return ReturnType(); }- ReturnType visitLocalSet(LocalSet* curr) { return ReturnType(); }- ReturnType visitGlobalGet(GlobalGet* curr) { return ReturnType(); }- ReturnType visitGlobalSet(GlobalSet* curr) { return ReturnType(); }- ReturnType visitLoad(Load* curr) { return ReturnType(); }- ReturnType visitStore(Store* curr) { return ReturnType(); }- ReturnType visitAtomicRMW(AtomicRMW* curr) { return ReturnType(); }- ReturnType visitAtomicCmpxchg(AtomicCmpxchg* curr) { return ReturnType(); }- ReturnType visitAtomicWait(AtomicWait* curr) { return ReturnType(); }- ReturnType visitAtomicNotify(AtomicNotify* curr) { return ReturnType(); }- ReturnType visitAtomicFence(AtomicFence* curr) { return ReturnType(); }- ReturnType visitSIMDExtract(SIMDExtract* curr) { return ReturnType(); }- ReturnType visitSIMDReplace(SIMDReplace* curr) { return ReturnType(); }- ReturnType visitSIMDShuffle(SIMDShuffle* curr) { return ReturnType(); }- ReturnType visitSIMDTernary(SIMDTernary* curr) { return ReturnType(); }- ReturnType visitSIMDShift(SIMDShift* curr) { return ReturnType(); }- ReturnType visitSIMDLoad(SIMDLoad* curr) { return ReturnType(); }- ReturnType visitMemoryInit(MemoryInit* curr) { return ReturnType(); }- ReturnType visitDataDrop(DataDrop* curr) { return ReturnType(); }- ReturnType visitMemoryCopy(MemoryCopy* curr) { return ReturnType(); }- ReturnType visitMemoryFill(MemoryFill* curr) { return ReturnType(); }- ReturnType visitConst(Const* curr) { return ReturnType(); }- ReturnType visitUnary(Unary* curr) { return ReturnType(); }- ReturnType visitBinary(Binary* curr) { return ReturnType(); }- ReturnType visitSelect(Select* curr) { return ReturnType(); }- ReturnType visitDrop(Drop* curr) { return ReturnType(); }- ReturnType visitReturn(Return* curr) { return ReturnType(); }- ReturnType visitMemorySize(MemorySize* curr) { return ReturnType(); }- ReturnType visitMemoryGrow(MemoryGrow* curr) { return ReturnType(); }- ReturnType visitRefNull(RefNull* curr) { return ReturnType(); }- ReturnType visitRefIsNull(RefIsNull* curr) { return ReturnType(); }- ReturnType visitRefFunc(RefFunc* curr) { return ReturnType(); }- ReturnType visitRefEq(RefEq* curr) { return ReturnType(); }- ReturnType visitTry(Try* curr) { return ReturnType(); }- ReturnType visitThrow(Throw* curr) { return ReturnType(); }- ReturnType visitRethrow(Rethrow* curr) { return ReturnType(); }- ReturnType visitBrOnExn(BrOnExn* curr) { return ReturnType(); }- ReturnType visitNop(Nop* curr) { return ReturnType(); }- ReturnType visitUnreachable(Unreachable* curr) { return ReturnType(); }- ReturnType visitPop(Pop* curr) { return ReturnType(); }- ReturnType visitTupleMake(TupleMake* curr) { return ReturnType(); }- ReturnType visitTupleExtract(TupleExtract* curr) { return ReturnType(); }- ReturnType visitI31New(I31New* curr) { return ReturnType(); }- ReturnType visitI31Get(I31Get* curr) { return ReturnType(); }- ReturnType visitRefTest(RefTest* curr) { return ReturnType(); }- ReturnType visitRefCast(RefCast* curr) { return ReturnType(); }- ReturnType visitBrOnCast(BrOnCast* curr) { return ReturnType(); }- ReturnType visitRttCanon(RttCanon* curr) { return ReturnType(); }- ReturnType visitRttSub(RttSub* curr) { return ReturnType(); }- ReturnType visitStructNew(StructNew* curr) { return ReturnType(); }- ReturnType visitStructGet(StructGet* curr) { return ReturnType(); }- ReturnType visitStructSet(StructSet* curr) { return ReturnType(); }- ReturnType visitArrayNew(ArrayNew* curr) { return ReturnType(); }- ReturnType visitArrayGet(ArrayGet* curr) { return ReturnType(); }- ReturnType visitArraySet(ArraySet* curr) { return ReturnType(); }- ReturnType visitArrayLen(ArrayLen* curr) { return ReturnType(); }- // Module-level visitors- ReturnType visitExport(Export* curr) { return ReturnType(); }- ReturnType visitGlobal(Global* curr) { return ReturnType(); }- ReturnType visitFunction(Function* curr) { return ReturnType(); }- ReturnType visitTable(Table* curr) { return ReturnType(); }- ReturnType visitMemory(Memory* curr) { return ReturnType(); }- ReturnType visitEvent(Event* curr) { return ReturnType(); }- ReturnType visitModule(Module* curr) { return ReturnType(); }-- ReturnType visit(Expression* curr) {- assert(curr);--#define DELEGATE(CLASS_TO_VISIT) \- return static_cast<SubType*>(this)->visit##CLASS_TO_VISIT( \- static_cast<CLASS_TO_VISIT*>(curr))-- switch (curr->_id) {- case Expression::Id::BlockId:- DELEGATE(Block);- case Expression::Id::IfId:- DELEGATE(If);- case Expression::Id::LoopId:- DELEGATE(Loop);- case Expression::Id::BreakId:- DELEGATE(Break);- case Expression::Id::SwitchId:- DELEGATE(Switch);- case Expression::Id::CallId:- DELEGATE(Call);- case Expression::Id::CallIndirectId:- DELEGATE(CallIndirect);- case Expression::Id::LocalGetId:- DELEGATE(LocalGet);- case Expression::Id::LocalSetId:- DELEGATE(LocalSet);- case Expression::Id::GlobalGetId:- DELEGATE(GlobalGet);- case Expression::Id::GlobalSetId:- DELEGATE(GlobalSet);- case Expression::Id::LoadId:- DELEGATE(Load);- case Expression::Id::StoreId:- DELEGATE(Store);- case Expression::Id::AtomicRMWId:- DELEGATE(AtomicRMW);- case Expression::Id::AtomicCmpxchgId:- DELEGATE(AtomicCmpxchg);- case Expression::Id::AtomicWaitId:- DELEGATE(AtomicWait);- case Expression::Id::AtomicNotifyId:- DELEGATE(AtomicNotify);- case Expression::Id::AtomicFenceId:- DELEGATE(AtomicFence);- case Expression::Id::SIMDExtractId:- DELEGATE(SIMDExtract);- case Expression::Id::SIMDReplaceId:- DELEGATE(SIMDReplace);- case Expression::Id::SIMDShuffleId:- DELEGATE(SIMDShuffle);- case Expression::Id::SIMDTernaryId:- DELEGATE(SIMDTernary);- case Expression::Id::SIMDShiftId:- DELEGATE(SIMDShift);- case Expression::Id::SIMDLoadId:- DELEGATE(SIMDLoad);- case Expression::Id::MemoryInitId:- DELEGATE(MemoryInit);- case Expression::Id::DataDropId:- DELEGATE(DataDrop);- case Expression::Id::MemoryCopyId:- DELEGATE(MemoryCopy);- case Expression::Id::MemoryFillId:- DELEGATE(MemoryFill);- case Expression::Id::ConstId:- DELEGATE(Const);- case Expression::Id::UnaryId:- DELEGATE(Unary);- case Expression::Id::BinaryId:- DELEGATE(Binary);- case Expression::Id::SelectId:- DELEGATE(Select);- case Expression::Id::DropId:- DELEGATE(Drop);- case Expression::Id::ReturnId:- DELEGATE(Return);- case Expression::Id::MemorySizeId:- DELEGATE(MemorySize);- case Expression::Id::MemoryGrowId:- DELEGATE(MemoryGrow);- case Expression::Id::RefNullId:- DELEGATE(RefNull);- case Expression::Id::RefIsNullId:- DELEGATE(RefIsNull);- case Expression::Id::RefFuncId:- DELEGATE(RefFunc);- case Expression::Id::RefEqId:- DELEGATE(RefEq);- case Expression::Id::TryId:- DELEGATE(Try);- case Expression::Id::ThrowId:- DELEGATE(Throw);- case Expression::Id::RethrowId:- DELEGATE(Rethrow);- case Expression::Id::BrOnExnId:- DELEGATE(BrOnExn);- case Expression::Id::NopId:- DELEGATE(Nop);- case Expression::Id::UnreachableId:- DELEGATE(Unreachable);- case Expression::Id::PopId:- DELEGATE(Pop);- case Expression::Id::TupleMakeId:- DELEGATE(TupleMake);- case Expression::Id::TupleExtractId:- DELEGATE(TupleExtract);- case Expression::Id::I31NewId:- DELEGATE(I31New);- case Expression::Id::I31GetId:- DELEGATE(I31Get);- case Expression::Id::RefTestId:- DELEGATE(RefTest);- case Expression::Id::RefCastId:- DELEGATE(RefCast);- case Expression::Id::BrOnCastId:- DELEGATE(BrOnCast);- case Expression::Id::RttCanonId:- DELEGATE(RttCanon);- case Expression::Id::RttSubId:- DELEGATE(RttSub);- case Expression::Id::StructNewId:- DELEGATE(StructNew);- case Expression::Id::StructGetId:- DELEGATE(StructGet);- case Expression::Id::StructSetId:- DELEGATE(StructSet);- case Expression::Id::ArrayNewId:- DELEGATE(ArrayNew);- case Expression::Id::ArrayGetId:- DELEGATE(ArrayGet);- case Expression::Id::ArraySetId:- DELEGATE(ArraySet);- case Expression::Id::ArrayLenId:- DELEGATE(ArrayLen);- case Expression::Id::InvalidId:- default:- WASM_UNREACHABLE("unexpected expression type");- }--#undef DELEGATE- }-};--// A visitor which must be overridden for each visitor that is reached.--template<typename SubType, typename ReturnType = void>-struct OverriddenVisitor {-// Expression visitors, which must be overridden-#define UNIMPLEMENTED(CLASS_TO_VISIT) \- ReturnType visit##CLASS_TO_VISIT(CLASS_TO_VISIT* curr) { \- static_assert( \- &SubType::visit##CLASS_TO_VISIT != \- &OverriddenVisitor<SubType, ReturnType>::visit##CLASS_TO_VISIT, \- "Derived class must implement visit" #CLASS_TO_VISIT); \- WASM_UNREACHABLE("Derived class must implement visit" #CLASS_TO_VISIT); \- }-- UNIMPLEMENTED(Block);- UNIMPLEMENTED(If);- UNIMPLEMENTED(Loop);- UNIMPLEMENTED(Break);- UNIMPLEMENTED(Switch);- UNIMPLEMENTED(Call);- UNIMPLEMENTED(CallIndirect);- UNIMPLEMENTED(LocalGet);- UNIMPLEMENTED(LocalSet);- UNIMPLEMENTED(GlobalGet);- UNIMPLEMENTED(GlobalSet);- UNIMPLEMENTED(Load);- UNIMPLEMENTED(Store);- UNIMPLEMENTED(AtomicRMW);- UNIMPLEMENTED(AtomicCmpxchg);- UNIMPLEMENTED(AtomicWait);- UNIMPLEMENTED(AtomicNotify);- UNIMPLEMENTED(AtomicFence);- UNIMPLEMENTED(SIMDExtract);- UNIMPLEMENTED(SIMDReplace);- UNIMPLEMENTED(SIMDShuffle);- UNIMPLEMENTED(SIMDTernary);- UNIMPLEMENTED(SIMDShift);- UNIMPLEMENTED(SIMDLoad);- UNIMPLEMENTED(MemoryInit);- UNIMPLEMENTED(DataDrop);- UNIMPLEMENTED(MemoryCopy);- UNIMPLEMENTED(MemoryFill);- UNIMPLEMENTED(Const);- UNIMPLEMENTED(Unary);- UNIMPLEMENTED(Binary);- UNIMPLEMENTED(Select);- UNIMPLEMENTED(Drop);- UNIMPLEMENTED(Return);- UNIMPLEMENTED(MemorySize);- UNIMPLEMENTED(MemoryGrow);- UNIMPLEMENTED(RefNull);- UNIMPLEMENTED(RefIsNull);- UNIMPLEMENTED(RefFunc);- UNIMPLEMENTED(RefEq);- UNIMPLEMENTED(Try);- UNIMPLEMENTED(Throw);- UNIMPLEMENTED(Rethrow);- UNIMPLEMENTED(BrOnExn);- UNIMPLEMENTED(Nop);- UNIMPLEMENTED(Unreachable);- UNIMPLEMENTED(Pop);- UNIMPLEMENTED(TupleMake);- UNIMPLEMENTED(TupleExtract);- UNIMPLEMENTED(I31New);- UNIMPLEMENTED(I31Get);- UNIMPLEMENTED(RefTest);- UNIMPLEMENTED(RefCast);- UNIMPLEMENTED(BrOnCast);- UNIMPLEMENTED(RttCanon);- UNIMPLEMENTED(RttSub);- UNIMPLEMENTED(StructNew);- UNIMPLEMENTED(StructGet);- UNIMPLEMENTED(StructSet);- UNIMPLEMENTED(ArrayNew);- UNIMPLEMENTED(ArrayGet);- UNIMPLEMENTED(ArraySet);- UNIMPLEMENTED(ArrayLen);- UNIMPLEMENTED(Export);- UNIMPLEMENTED(Global);- UNIMPLEMENTED(Function);- UNIMPLEMENTED(Table);- UNIMPLEMENTED(Memory);- UNIMPLEMENTED(Event);- UNIMPLEMENTED(Module);--#undef UNIMPLEMENTED-- ReturnType visit(Expression* curr) {- assert(curr);--#define DELEGATE(CLASS_TO_VISIT) \- return static_cast<SubType*>(this)->visit##CLASS_TO_VISIT( \- static_cast<CLASS_TO_VISIT*>(curr))-- switch (curr->_id) {- case Expression::Id::BlockId:- DELEGATE(Block);- case Expression::Id::IfId:- DELEGATE(If);- case Expression::Id::LoopId:- DELEGATE(Loop);- case Expression::Id::BreakId:- DELEGATE(Break);- case Expression::Id::SwitchId:- DELEGATE(Switch);- case Expression::Id::CallId:- DELEGATE(Call);- case Expression::Id::CallIndirectId:- DELEGATE(CallIndirect);- case Expression::Id::LocalGetId:- DELEGATE(LocalGet);- case Expression::Id::LocalSetId:- DELEGATE(LocalSet);- case Expression::Id::GlobalGetId:- DELEGATE(GlobalGet);- case Expression::Id::GlobalSetId:- DELEGATE(GlobalSet);- case Expression::Id::LoadId:- DELEGATE(Load);- case Expression::Id::StoreId:- DELEGATE(Store);- case Expression::Id::AtomicRMWId:- DELEGATE(AtomicRMW);- case Expression::Id::AtomicCmpxchgId:- DELEGATE(AtomicCmpxchg);- case Expression::Id::AtomicWaitId:- DELEGATE(AtomicWait);- case Expression::Id::AtomicNotifyId:- DELEGATE(AtomicNotify);- case Expression::Id::AtomicFenceId:- DELEGATE(AtomicFence);- case Expression::Id::SIMDExtractId:- DELEGATE(SIMDExtract);- case Expression::Id::SIMDReplaceId:- DELEGATE(SIMDReplace);- case Expression::Id::SIMDShuffleId:- DELEGATE(SIMDShuffle);- case Expression::Id::SIMDTernaryId:- DELEGATE(SIMDTernary);- case Expression::Id::SIMDShiftId:- DELEGATE(SIMDShift);- case Expression::Id::SIMDLoadId:- DELEGATE(SIMDLoad);- case Expression::Id::MemoryInitId:- DELEGATE(MemoryInit);- case Expression::Id::DataDropId:- DELEGATE(DataDrop);- case Expression::Id::MemoryCopyId:- DELEGATE(MemoryCopy);- case Expression::Id::MemoryFillId:- DELEGATE(MemoryFill);- case Expression::Id::ConstId:- DELEGATE(Const);- case Expression::Id::UnaryId:- DELEGATE(Unary);- case Expression::Id::BinaryId:- DELEGATE(Binary);- case Expression::Id::SelectId:- DELEGATE(Select);- case Expression::Id::DropId:- DELEGATE(Drop);- case Expression::Id::ReturnId:- DELEGATE(Return);- case Expression::Id::MemorySizeId:- DELEGATE(MemorySize);- case Expression::Id::MemoryGrowId:- DELEGATE(MemoryGrow);- case Expression::Id::RefNullId:- DELEGATE(RefNull);- case Expression::Id::RefIsNullId:- DELEGATE(RefIsNull);- case Expression::Id::RefFuncId:- DELEGATE(RefFunc);- case Expression::Id::RefEqId:- DELEGATE(RefEq);- case Expression::Id::TryId:- DELEGATE(Try);- case Expression::Id::ThrowId:- DELEGATE(Throw);- case Expression::Id::RethrowId:- DELEGATE(Rethrow);- case Expression::Id::BrOnExnId:- DELEGATE(BrOnExn);- case Expression::Id::NopId:- DELEGATE(Nop);- case Expression::Id::UnreachableId:- DELEGATE(Unreachable);- case Expression::Id::PopId:- DELEGATE(Pop);- case Expression::Id::TupleMakeId:- DELEGATE(TupleMake);- case Expression::Id::TupleExtractId:- DELEGATE(TupleExtract);- case Expression::Id::I31NewId:- DELEGATE(I31New);- case Expression::Id::I31GetId:- DELEGATE(I31Get);- case Expression::Id::RefTestId:- DELEGATE(RefTest);- case Expression::Id::RefCastId:- DELEGATE(RefCast);- case Expression::Id::BrOnCastId:- DELEGATE(BrOnCast);- case Expression::Id::RttCanonId:- DELEGATE(RttCanon);- case Expression::Id::RttSubId:- DELEGATE(RttSub);- case Expression::Id::StructNewId:- DELEGATE(StructNew);- case Expression::Id::StructGetId:- DELEGATE(StructGet);- case Expression::Id::StructSetId:- DELEGATE(StructSet);- case Expression::Id::ArrayNewId:- DELEGATE(ArrayNew);- case Expression::Id::ArrayGetId:- DELEGATE(ArrayGet);- case Expression::Id::ArraySetId:- DELEGATE(ArraySet);- case Expression::Id::ArrayLenId:- DELEGATE(ArrayLen);- case Expression::Id::InvalidId:- default:- WASM_UNREACHABLE("unexpected expression type");- }--#undef DELEGATE- }-};--// Visit with a single unified visitor, called on every node, instead of-// separate visit* per node--template<typename SubType, typename ReturnType = void>-struct UnifiedExpressionVisitor : public Visitor<SubType, ReturnType> {- // called on each node- ReturnType visitExpression(Expression* curr) { return ReturnType(); }-- // redirects- ReturnType visitBlock(Block* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }- ReturnType visitIf(If* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }- ReturnType visitLoop(Loop* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }- ReturnType visitBreak(Break* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }- ReturnType visitSwitch(Switch* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }- ReturnType visitCall(Call* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }- ReturnType visitCallIndirect(CallIndirect* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }- ReturnType visitLocalGet(LocalGet* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }- ReturnType visitLocalSet(LocalSet* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }- ReturnType visitGlobalGet(GlobalGet* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }- ReturnType visitGlobalSet(GlobalSet* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }- ReturnType visitLoad(Load* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }- ReturnType visitStore(Store* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }- ReturnType visitAtomicRMW(AtomicRMW* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }- ReturnType visitAtomicCmpxchg(AtomicCmpxchg* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }- ReturnType visitAtomicWait(AtomicWait* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }- ReturnType visitAtomicNotify(AtomicNotify* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }- ReturnType visitAtomicFence(AtomicFence* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }- ReturnType visitSIMDExtract(SIMDExtract* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }- ReturnType visitSIMDReplace(SIMDReplace* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }- ReturnType visitSIMDShuffle(SIMDShuffle* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }- ReturnType visitSIMDTernary(SIMDTernary* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }- ReturnType visitSIMDShift(SIMDShift* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }- ReturnType visitSIMDLoad(SIMDLoad* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }- ReturnType visitMemoryInit(MemoryInit* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }- ReturnType visitDataDrop(DataDrop* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }- ReturnType visitMemoryCopy(MemoryCopy* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }- ReturnType visitMemoryFill(MemoryFill* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }- ReturnType visitConst(Const* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }- ReturnType visitUnary(Unary* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }- ReturnType visitBinary(Binary* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }- ReturnType visitSelect(Select* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }- ReturnType visitDrop(Drop* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }- ReturnType visitReturn(Return* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }- ReturnType visitMemorySize(MemorySize* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }- ReturnType visitMemoryGrow(MemoryGrow* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }- ReturnType visitRefNull(RefNull* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }- ReturnType visitRefIsNull(RefIsNull* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }- ReturnType visitRefFunc(RefFunc* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }- ReturnType visitRefEq(RefEq* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }- ReturnType visitTry(Try* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }- ReturnType visitThrow(Throw* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }- ReturnType visitRethrow(Rethrow* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }- ReturnType visitBrOnExn(BrOnExn* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }- ReturnType visitNop(Nop* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }- ReturnType visitUnreachable(Unreachable* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }- ReturnType visitPop(Pop* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }- ReturnType visitTupleMake(TupleMake* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }- ReturnType visitTupleExtract(TupleExtract* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }- ReturnType visitI31New(I31New* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }- ReturnType visitI31Get(I31Get* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }- ReturnType visitRefTest(RefTest* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }- ReturnType visitRefCast(RefCast* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }- ReturnType visitBrOnCast(BrOnCast* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }- ReturnType visitRttCanon(RttCanon* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }- ReturnType visitRttSub(RttSub* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }- ReturnType visitStructNew(StructNew* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }- ReturnType visitStructGet(StructGet* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }- ReturnType visitStructSet(StructSet* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }- ReturnType visitArrayNew(ArrayNew* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }- ReturnType visitArrayGet(ArrayGet* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }- ReturnType visitArraySet(ArraySet* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }- ReturnType visitArrayLen(ArrayLen* curr) {- return static_cast<SubType*>(this)->visitExpression(curr);- }-};--//-// Base class for all WasmWalkers, which can traverse an AST-// and provide the option to replace nodes while doing so.-//-// Subclass and implement the visit*()-// calls to run code on different node types.-//-template<typename SubType, typename VisitorType>-struct Walker : public VisitorType {- // Useful methods for visitor implementions-- // Replace the current node. You can call this in your visit*() methods.- // Note that the visit*() for the result node is not called for you (i.e.,- // just one visit*() method is called by the traversal; if you replace a node,- // and you want to process the output, you must do that explicitly).- Expression* replaceCurrent(Expression* expression) {- // Copy debug info, if present.- if (currFunction) {- auto& debugLocations = currFunction->debugLocations;- if (!debugLocations.empty()) {- auto* curr = getCurrent();- auto iter = debugLocations.find(curr);- if (iter != debugLocations.end()) {- auto location = iter->second;- debugLocations.erase(iter);- debugLocations[expression] = location;- }- }- }- return *replacep = expression;- }-- Expression* getCurrent() { return *replacep; }-- Expression** getCurrentPointer() { return replacep; }-- // Get the current module- Module* getModule() { return currModule; }-- // Get the current function- Function* getFunction() { return currFunction; }-- // Walk starting-- void walkGlobal(Global* global) {- walk(global->init);- static_cast<SubType*>(this)->visitGlobal(global);- }-- void walkFunction(Function* func) {- setFunction(func);- static_cast<SubType*>(this)->doWalkFunction(func);- static_cast<SubType*>(this)->visitFunction(func);- setFunction(nullptr);- }-- void walkEvent(Event* event) {- static_cast<SubType*>(this)->visitEvent(event);- }-- void walkFunctionInModule(Function* func, Module* module) {- setModule(module);- setFunction(func);- static_cast<SubType*>(this)->doWalkFunction(func);- static_cast<SubType*>(this)->visitFunction(func);- setFunction(nullptr);- setModule(nullptr);- }-- // override this to provide custom functionality- void doWalkFunction(Function* func) { walk(func->body); }-- void walkTable(Table* table) {- for (auto& segment : table->segments) {- walk(segment.offset);- }- static_cast<SubType*>(this)->visitTable(table);- }-- void walkMemory(Memory* memory) {- for (auto& segment : memory->segments) {- if (!segment.isPassive) {- walk(segment.offset);- }- }- static_cast<SubType*>(this)->visitMemory(memory);- }-- void walkModule(Module* module) {- setModule(module);- static_cast<SubType*>(this)->doWalkModule(module);- static_cast<SubType*>(this)->visitModule(module);- setModule(nullptr);- }-- // override this to provide custom functionality- void doWalkModule(Module* module) {- // Dispatch statically through the SubType.- SubType* self = static_cast<SubType*>(this);- for (auto& curr : module->exports) {- self->visitExport(curr.get());- }- for (auto& curr : module->globals) {- if (curr->imported()) {- self->visitGlobal(curr.get());- } else {- self->walkGlobal(curr.get());- }- }- for (auto& curr : module->functions) {- if (curr->imported()) {- self->visitFunction(curr.get());- } else {- self->walkFunction(curr.get());- }- }- for (auto& curr : module->events) {- if (curr->imported()) {- self->visitEvent(curr.get());- } else {- self->walkEvent(curr.get());- }- }- self->walkTable(&module->table);- self->walkMemory(&module->memory);- }-- // Walk implementation. We don't use recursion as ASTs may be highly- // nested.-- // Tasks receive the this pointer and a pointer to the pointer to operate on- typedef void (*TaskFunc)(SubType*, Expression**);-- struct Task {- TaskFunc func;- Expression** currp;- Task() {}- Task(TaskFunc func, Expression** currp) : func(func), currp(currp) {}- };-- void pushTask(TaskFunc func, Expression** currp) {- assert(*currp);- stack.emplace_back(func, currp);- }- void maybePushTask(TaskFunc func, Expression** currp) {- if (*currp) {- stack.emplace_back(func, currp);- }- }- Task popTask() {- auto ret = stack.back();- stack.pop_back();- return ret;- }-- void walk(Expression*& root) {- assert(stack.size() == 0);- pushTask(SubType::scan, &root);- while (stack.size() > 0) {- auto task = popTask();- replacep = task.currp;- assert(*task.currp);- task.func(static_cast<SubType*>(this), task.currp);- }- }-- // subclasses implement this to define the proper order of execution- static void scan(SubType* self, Expression** currp) { abort(); }-- // task hooks to call visitors-- static void doVisitBlock(SubType* self, Expression** currp) {- self->visitBlock((*currp)->cast<Block>());- }- static void doVisitIf(SubType* self, Expression** currp) {- self->visitIf((*currp)->cast<If>());- }- static void doVisitLoop(SubType* self, Expression** currp) {- self->visitLoop((*currp)->cast<Loop>());- }- static void doVisitBreak(SubType* self, Expression** currp) {- self->visitBreak((*currp)->cast<Break>());- }- static void doVisitSwitch(SubType* self, Expression** currp) {- self->visitSwitch((*currp)->cast<Switch>());- }- static void doVisitCall(SubType* self, Expression** currp) {- self->visitCall((*currp)->cast<Call>());- }- static void doVisitCallIndirect(SubType* self, Expression** currp) {- self->visitCallIndirect((*currp)->cast<CallIndirect>());- }- static void doVisitLocalGet(SubType* self, Expression** currp) {- self->visitLocalGet((*currp)->cast<LocalGet>());- }- static void doVisitLocalSet(SubType* self, Expression** currp) {- self->visitLocalSet((*currp)->cast<LocalSet>());- }- static void doVisitGlobalGet(SubType* self, Expression** currp) {- self->visitGlobalGet((*currp)->cast<GlobalGet>());- }- static void doVisitGlobalSet(SubType* self, Expression** currp) {- self->visitGlobalSet((*currp)->cast<GlobalSet>());- }- static void doVisitLoad(SubType* self, Expression** currp) {- self->visitLoad((*currp)->cast<Load>());- }- static void doVisitStore(SubType* self, Expression** currp) {- self->visitStore((*currp)->cast<Store>());- }- static void doVisitAtomicRMW(SubType* self, Expression** currp) {- self->visitAtomicRMW((*currp)->cast<AtomicRMW>());- }- static void doVisitAtomicCmpxchg(SubType* self, Expression** currp) {- self->visitAtomicCmpxchg((*currp)->cast<AtomicCmpxchg>());- }- static void doVisitAtomicWait(SubType* self, Expression** currp) {- self->visitAtomicWait((*currp)->cast<AtomicWait>());- }- static void doVisitAtomicNotify(SubType* self, Expression** currp) {- self->visitAtomicNotify((*currp)->cast<AtomicNotify>());- }- static void doVisitAtomicFence(SubType* self, Expression** currp) {- self->visitAtomicFence((*currp)->cast<AtomicFence>());- }- static void doVisitSIMDExtract(SubType* self, Expression** currp) {- self->visitSIMDExtract((*currp)->cast<SIMDExtract>());- }- static void doVisitSIMDReplace(SubType* self, Expression** currp) {- self->visitSIMDReplace((*currp)->cast<SIMDReplace>());- }- static void doVisitSIMDShuffle(SubType* self, Expression** currp) {- self->visitSIMDShuffle((*currp)->cast<SIMDShuffle>());- }- static void doVisitSIMDTernary(SubType* self, Expression** currp) {- self->visitSIMDTernary((*currp)->cast<SIMDTernary>());- }- static void doVisitSIMDShift(SubType* self, Expression** currp) {- self->visitSIMDShift((*currp)->cast<SIMDShift>());- }- static void doVisitSIMDLoad(SubType* self, Expression** currp) {- self->visitSIMDLoad((*currp)->cast<SIMDLoad>());- }- static void doVisitMemoryInit(SubType* self, Expression** currp) {- self->visitMemoryInit((*currp)->cast<MemoryInit>());- }- static void doVisitDataDrop(SubType* self, Expression** currp) {- self->visitDataDrop((*currp)->cast<DataDrop>());- }- static void doVisitMemoryCopy(SubType* self, Expression** currp) {- self->visitMemoryCopy((*currp)->cast<MemoryCopy>());- }- static void doVisitMemoryFill(SubType* self, Expression** currp) {- self->visitMemoryFill((*currp)->cast<MemoryFill>());- }- static void doVisitConst(SubType* self, Expression** currp) {- self->visitConst((*currp)->cast<Const>());- }- static void doVisitUnary(SubType* self, Expression** currp) {- self->visitUnary((*currp)->cast<Unary>());- }- static void doVisitBinary(SubType* self, Expression** currp) {- self->visitBinary((*currp)->cast<Binary>());- }- static void doVisitSelect(SubType* self, Expression** currp) {- self->visitSelect((*currp)->cast<Select>());- }- static void doVisitDrop(SubType* self, Expression** currp) {- self->visitDrop((*currp)->cast<Drop>());- }- static void doVisitReturn(SubType* self, Expression** currp) {- self->visitReturn((*currp)->cast<Return>());- }- static void doVisitMemorySize(SubType* self, Expression** currp) {- self->visitMemorySize((*currp)->cast<MemorySize>());- }- static void doVisitMemoryGrow(SubType* self, Expression** currp) {- self->visitMemoryGrow((*currp)->cast<MemoryGrow>());- }- static void doVisitRefNull(SubType* self, Expression** currp) {- self->visitRefNull((*currp)->cast<RefNull>());- }- static void doVisitRefIsNull(SubType* self, Expression** currp) {- self->visitRefIsNull((*currp)->cast<RefIsNull>());- }- static void doVisitRefFunc(SubType* self, Expression** currp) {- self->visitRefFunc((*currp)->cast<RefFunc>());- }- static void doVisitRefEq(SubType* self, Expression** currp) {- self->visitRefEq((*currp)->cast<RefEq>());- }- static void doVisitTry(SubType* self, Expression** currp) {- self->visitTry((*currp)->cast<Try>());- }- static void doVisitThrow(SubType* self, Expression** currp) {- self->visitThrow((*currp)->cast<Throw>());- }- static void doVisitRethrow(SubType* self, Expression** currp) {- self->visitRethrow((*currp)->cast<Rethrow>());- }- static void doVisitBrOnExn(SubType* self, Expression** currp) {- self->visitBrOnExn((*currp)->cast<BrOnExn>());- }- static void doVisitNop(SubType* self, Expression** currp) {- self->visitNop((*currp)->cast<Nop>());- }- static void doVisitUnreachable(SubType* self, Expression** currp) {- self->visitUnreachable((*currp)->cast<Unreachable>());- }- static void doVisitPop(SubType* self, Expression** currp) {- self->visitPop((*currp)->cast<Pop>());- }- static void doVisitTupleMake(SubType* self, Expression** currp) {- self->visitTupleMake((*currp)->cast<TupleMake>());- }- static void doVisitTupleExtract(SubType* self, Expression** currp) {- self->visitTupleExtract((*currp)->cast<TupleExtract>());- }- static void doVisitI31New(SubType* self, Expression** currp) {- self->visitI31New((*currp)->cast<I31New>());- }- static void doVisitI31Get(SubType* self, Expression** currp) {- self->visitI31Get((*currp)->cast<I31Get>());- }- static void doVisitRefTest(SubType* self, Expression** currp) {- self->visitRefTest((*currp)->cast<RefTest>());- }- static void doVisitRefCast(SubType* self, Expression** currp) {- self->visitRefCast((*currp)->cast<RefCast>());- }- static void doVisitBrOnCast(SubType* self, Expression** currp) {- self->visitBrOnCast((*currp)->cast<BrOnCast>());- }- static void doVisitRttCanon(SubType* self, Expression** currp) {- self->visitRttCanon((*currp)->cast<RttCanon>());- }- static void doVisitRttSub(SubType* self, Expression** currp) {- self->visitRttSub((*currp)->cast<RttSub>());- }- static void doVisitStructNew(SubType* self, Expression** currp) {- self->visitStructNew((*currp)->cast<StructNew>());- }- static void doVisitStructGet(SubType* self, Expression** currp) {- self->visitStructGet((*currp)->cast<StructGet>());- }- static void doVisitStructSet(SubType* self, Expression** currp) {- self->visitStructSet((*currp)->cast<StructSet>());- }- static void doVisitArrayNew(SubType* self, Expression** currp) {- self->visitArrayNew((*currp)->cast<ArrayNew>());- }- static void doVisitArrayGet(SubType* self, Expression** currp) {- self->visitArrayGet((*currp)->cast<ArrayGet>());- }- static void doVisitArraySet(SubType* self, Expression** currp) {- self->visitArraySet((*currp)->cast<ArraySet>());- }- static void doVisitArrayLen(SubType* self, Expression** currp) {- self->visitArrayLen((*currp)->cast<ArrayLen>());- }-- void setModule(Module* module) { currModule = module; }-- void setFunction(Function* func) { currFunction = func; }--private:- // the address of the current node, used to replace it- Expression** replacep = nullptr;- SmallVector<Task, 10> stack; // stack of tasks- Function* currFunction = nullptr; // current function being processed- Module* currModule = nullptr; // current module being processed-};--// Walks in post-order, i.e., children first. When there isn't an obvious-// order to operands, we follow them in order of execution.--template<typename SubType, typename VisitorType = Visitor<SubType>>-struct PostWalker : public Walker<SubType, VisitorType> {-- static void scan(SubType* self, Expression** currp) {- Expression* curr = *currp;- switch (curr->_id) {- case Expression::Id::InvalidId:- abort();- case Expression::Id::BlockId: {- self->pushTask(SubType::doVisitBlock, currp);- auto& list = curr->cast<Block>()->list;- for (int i = int(list.size()) - 1; i >= 0; i--) {- self->pushTask(SubType::scan, &list[i]);- }- break;- }- case Expression::Id::IfId: {- self->pushTask(SubType::doVisitIf, currp);- self->maybePushTask(SubType::scan, &curr->cast<If>()->ifFalse);- self->pushTask(SubType::scan, &curr->cast<If>()->ifTrue);- self->pushTask(SubType::scan, &curr->cast<If>()->condition);- break;- }- case Expression::Id::LoopId: {- self->pushTask(SubType::doVisitLoop, currp);- self->pushTask(SubType::scan, &curr->cast<Loop>()->body);- break;- }- case Expression::Id::BreakId: {- self->pushTask(SubType::doVisitBreak, currp);- self->maybePushTask(SubType::scan, &curr->cast<Break>()->condition);- self->maybePushTask(SubType::scan, &curr->cast<Break>()->value);- break;- }- case Expression::Id::SwitchId: {- self->pushTask(SubType::doVisitSwitch, currp);- self->pushTask(SubType::scan, &curr->cast<Switch>()->condition);- self->maybePushTask(SubType::scan, &curr->cast<Switch>()->value);- break;- }- case Expression::Id::CallId: {- self->pushTask(SubType::doVisitCall, currp);- auto& list = curr->cast<Call>()->operands;- for (int i = int(list.size()) - 1; i >= 0; i--) {- self->pushTask(SubType::scan, &list[i]);- }- break;- }- case Expression::Id::CallIndirectId: {- self->pushTask(SubType::doVisitCallIndirect, currp);- auto& list = curr->cast<CallIndirect>()->operands;- self->pushTask(SubType::scan, &curr->cast<CallIndirect>()->target);- for (int i = int(list.size()) - 1; i >= 0; i--) {- self->pushTask(SubType::scan, &list[i]);- }- break;- }- case Expression::Id::LocalGetId: {- // TODO: optimize leaves with a direct call?- self->pushTask(SubType::doVisitLocalGet, currp);- break;- }- case Expression::Id::LocalSetId: {- self->pushTask(SubType::doVisitLocalSet, currp);- self->pushTask(SubType::scan, &curr->cast<LocalSet>()->value);- break;- }- case Expression::Id::GlobalGetId: {- self->pushTask(SubType::doVisitGlobalGet, currp);- break;- }- case Expression::Id::GlobalSetId: {- self->pushTask(SubType::doVisitGlobalSet, currp);- self->pushTask(SubType::scan, &curr->cast<GlobalSet>()->value);- break;- }- case Expression::Id::LoadId: {- self->pushTask(SubType::doVisitLoad, currp);- self->pushTask(SubType::scan, &curr->cast<Load>()->ptr);- break;- }- case Expression::Id::StoreId: {- self->pushTask(SubType::doVisitStore, currp);- self->pushTask(SubType::scan, &curr->cast<Store>()->value);- self->pushTask(SubType::scan, &curr->cast<Store>()->ptr);- break;- }- case Expression::Id::AtomicRMWId: {- self->pushTask(SubType::doVisitAtomicRMW, currp);- self->pushTask(SubType::scan, &curr->cast<AtomicRMW>()->value);- self->pushTask(SubType::scan, &curr->cast<AtomicRMW>()->ptr);- break;- }- case Expression::Id::AtomicCmpxchgId: {- self->pushTask(SubType::doVisitAtomicCmpxchg, currp);- self->pushTask(SubType::scan,- &curr->cast<AtomicCmpxchg>()->replacement);- self->pushTask(SubType::scan, &curr->cast<AtomicCmpxchg>()->expected);- self->pushTask(SubType::scan, &curr->cast<AtomicCmpxchg>()->ptr);- break;- }- case Expression::Id::AtomicWaitId: {- self->pushTask(SubType::doVisitAtomicWait, currp);- self->pushTask(SubType::scan, &curr->cast<AtomicWait>()->timeout);- self->pushTask(SubType::scan, &curr->cast<AtomicWait>()->expected);- self->pushTask(SubType::scan, &curr->cast<AtomicWait>()->ptr);- break;- }- case Expression::Id::AtomicNotifyId: {- self->pushTask(SubType::doVisitAtomicNotify, currp);- self->pushTask(SubType::scan, &curr->cast<AtomicNotify>()->notifyCount);- self->pushTask(SubType::scan, &curr->cast<AtomicNotify>()->ptr);- break;- }- case Expression::Id::AtomicFenceId: {- self->pushTask(SubType::doVisitAtomicFence, currp);- break;- }- case Expression::Id::SIMDExtractId: {- self->pushTask(SubType::doVisitSIMDExtract, currp);- self->pushTask(SubType::scan, &curr->cast<SIMDExtract>()->vec);- break;- }- case Expression::Id::SIMDReplaceId: {- self->pushTask(SubType::doVisitSIMDReplace, currp);- self->pushTask(SubType::scan, &curr->cast<SIMDReplace>()->value);- self->pushTask(SubType::scan, &curr->cast<SIMDReplace>()->vec);- break;- }- case Expression::Id::SIMDShuffleId: {- self->pushTask(SubType::doVisitSIMDShuffle, currp);- self->pushTask(SubType::scan, &curr->cast<SIMDShuffle>()->right);- self->pushTask(SubType::scan, &curr->cast<SIMDShuffle>()->left);- break;- }- case Expression::Id::SIMDTernaryId: {- self->pushTask(SubType::doVisitSIMDTernary, currp);- self->pushTask(SubType::scan, &curr->cast<SIMDTernary>()->c);- self->pushTask(SubType::scan, &curr->cast<SIMDTernary>()->b);- self->pushTask(SubType::scan, &curr->cast<SIMDTernary>()->a);- break;- }- case Expression::Id::SIMDShiftId: {- self->pushTask(SubType::doVisitSIMDShift, currp);- self->pushTask(SubType::scan, &curr->cast<SIMDShift>()->shift);- self->pushTask(SubType::scan, &curr->cast<SIMDShift>()->vec);- break;- }- case Expression::Id::SIMDLoadId: {- self->pushTask(SubType::doVisitSIMDLoad, currp);- self->pushTask(SubType::scan, &curr->cast<SIMDLoad>()->ptr);- break;- }- case Expression::Id::MemoryInitId: {- self->pushTask(SubType::doVisitMemoryInit, currp);- self->pushTask(SubType::scan, &curr->cast<MemoryInit>()->size);- self->pushTask(SubType::scan, &curr->cast<MemoryInit>()->offset);- self->pushTask(SubType::scan, &curr->cast<MemoryInit>()->dest);- break;- }- case Expression::Id::DataDropId: {- self->pushTask(SubType::doVisitDataDrop, currp);- break;- }- case Expression::Id::MemoryCopyId: {- self->pushTask(SubType::doVisitMemoryCopy, currp);- self->pushTask(SubType::scan, &curr->cast<MemoryCopy>()->size);- self->pushTask(SubType::scan, &curr->cast<MemoryCopy>()->source);- self->pushTask(SubType::scan, &curr->cast<MemoryCopy>()->dest);- break;- }- case Expression::Id::MemoryFillId: {- self->pushTask(SubType::doVisitMemoryFill, currp);- self->pushTask(SubType::scan, &curr->cast<MemoryFill>()->size);- self->pushTask(SubType::scan, &curr->cast<MemoryFill>()->value);- self->pushTask(SubType::scan, &curr->cast<MemoryFill>()->dest);- break;- }- case Expression::Id::ConstId: {- self->pushTask(SubType::doVisitConst, currp);- break;- }- case Expression::Id::UnaryId: {- self->pushTask(SubType::doVisitUnary, currp);- self->pushTask(SubType::scan, &curr->cast<Unary>()->value);- break;- }- case Expression::Id::BinaryId: {- self->pushTask(SubType::doVisitBinary, currp);- self->pushTask(SubType::scan, &curr->cast<Binary>()->right);- self->pushTask(SubType::scan, &curr->cast<Binary>()->left);- break;- }- case Expression::Id::SelectId: {- self->pushTask(SubType::doVisitSelect, currp);- self->pushTask(SubType::scan, &curr->cast<Select>()->condition);- self->pushTask(SubType::scan, &curr->cast<Select>()->ifFalse);- self->pushTask(SubType::scan, &curr->cast<Select>()->ifTrue);- break;- }- case Expression::Id::DropId: {- self->pushTask(SubType::doVisitDrop, currp);- self->pushTask(SubType::scan, &curr->cast<Drop>()->value);- break;- }- case Expression::Id::ReturnId: {- self->pushTask(SubType::doVisitReturn, currp);- self->maybePushTask(SubType::scan, &curr->cast<Return>()->value);- break;- }- case Expression::Id::MemorySizeId:- self->pushTask(SubType::doVisitMemorySize, currp);- break;- case Expression::Id::MemoryGrowId:- self->pushTask(SubType::doVisitMemoryGrow, currp);- self->pushTask(SubType::scan, &curr->cast<MemoryGrow>()->delta);- break;- case Expression::Id::RefNullId: {- self->pushTask(SubType::doVisitRefNull, currp);- break;- }- case Expression::Id::RefIsNullId: {- self->pushTask(SubType::doVisitRefIsNull, currp);- self->pushTask(SubType::scan, &curr->cast<RefIsNull>()->value);- break;- }- case Expression::Id::RefFuncId: {- self->pushTask(SubType::doVisitRefFunc, currp);- break;- }- case Expression::Id::RefEqId: {- self->pushTask(SubType::doVisitRefEq, currp);- self->pushTask(SubType::scan, &curr->cast<RefEq>()->right);- self->pushTask(SubType::scan, &curr->cast<RefEq>()->left);- break;- }- case Expression::Id::TryId: {- self->pushTask(SubType::doVisitTry, currp);- self->pushTask(SubType::scan, &curr->cast<Try>()->catchBody);- self->pushTask(SubType::scan, &curr->cast<Try>()->body);- break;- }- case Expression::Id::ThrowId: {- self->pushTask(SubType::doVisitThrow, currp);- auto& list = curr->cast<Throw>()->operands;- for (int i = int(list.size()) - 1; i >= 0; i--) {- self->pushTask(SubType::scan, &list[i]);- }- break;- }- case Expression::Id::RethrowId: {- self->pushTask(SubType::doVisitRethrow, currp);- self->pushTask(SubType::scan, &curr->cast<Rethrow>()->exnref);- break;- }- case Expression::Id::BrOnExnId: {- self->pushTask(SubType::doVisitBrOnExn, currp);- self->pushTask(SubType::scan, &curr->cast<BrOnExn>()->exnref);- break;- }- case Expression::Id::NopId: {- self->pushTask(SubType::doVisitNop, currp);- break;- }- case Expression::Id::UnreachableId: {- self->pushTask(SubType::doVisitUnreachable, currp);- break;- }- case Expression::Id::PopId: {- self->pushTask(SubType::doVisitPop, currp);- break;- }- case Expression::Id::TupleMakeId: {- self->pushTask(SubType::doVisitTupleMake, currp);- auto& operands = curr->cast<TupleMake>()->operands;- for (int i = int(operands.size()) - 1; i >= 0; --i) {- self->pushTask(SubType::scan, &operands[i]);- }- break;- }- case Expression::Id::TupleExtractId: {- self->pushTask(SubType::doVisitTupleExtract, currp);- self->pushTask(SubType::scan, &curr->cast<TupleExtract>()->tuple);- break;- }- case Expression::Id::I31NewId: {- self->pushTask(SubType::doVisitI31New, currp);- self->pushTask(SubType::scan, &curr->cast<I31New>()->value);- break;- }- case Expression::Id::I31GetId: {- self->pushTask(SubType::doVisitI31Get, currp);- self->pushTask(SubType::scan, &curr->cast<I31Get>()->i31);- break;- }- case Expression::Id::RefTestId:- self->pushTask(SubType::doVisitRefTest, currp);- WASM_UNREACHABLE("TODO (gc): ref.test");- break;- case Expression::Id::RefCastId:- self->pushTask(SubType::doVisitRefCast, currp);- WASM_UNREACHABLE("TODO (gc): ref.cast");- break;- case Expression::Id::BrOnCastId:- self->pushTask(SubType::doVisitBrOnCast, currp);- WASM_UNREACHABLE("TODO (gc): br_on_cast");- break;- case Expression::Id::RttCanonId:- self->pushTask(SubType::doVisitRttCanon, currp);- WASM_UNREACHABLE("TODO (gc): rtt.canon");- break;- case Expression::Id::RttSubId:- self->pushTask(SubType::doVisitRttSub, currp);- WASM_UNREACHABLE("TODO (gc): rtt.sub");- break;- case Expression::Id::StructNewId:- self->pushTask(SubType::doVisitStructNew, currp);- WASM_UNREACHABLE("TODO (gc): struct.new");- break;- case Expression::Id::StructGetId:- self->pushTask(SubType::doVisitStructGet, currp);- WASM_UNREACHABLE("TODO (gc): struct.get");- break;- case Expression::Id::StructSetId:- self->pushTask(SubType::doVisitStructSet, currp);- WASM_UNREACHABLE("TODO (gc): struct.set");- break;- case Expression::Id::ArrayNewId:- self->pushTask(SubType::doVisitArrayNew, currp);- WASM_UNREACHABLE("TODO (gc): array.new");- break;- case Expression::Id::ArrayGetId:- self->pushTask(SubType::doVisitArrayGet, currp);- WASM_UNREACHABLE("TODO (gc): array.get");- break;- case Expression::Id::ArraySetId:- self->pushTask(SubType::doVisitArraySet, currp);- WASM_UNREACHABLE("TODO (gc): array.set");- break;- case Expression::Id::ArrayLenId:- self->pushTask(SubType::doVisitArrayLen, currp);- WASM_UNREACHABLE("TODO (gc): array.len");- break;- case Expression::Id::NumExpressionIds:- WASM_UNREACHABLE("unexpected expression type");- }+#define DELEGATE(CLASS_TO_VISIT) \+ ReturnType visit##CLASS_TO_VISIT(CLASS_TO_VISIT* curr) { \+ return ReturnType(); \+ }+#include "wasm-delegations.h"++ // Module-level visitors+ ReturnType visitExport(Export* curr) { return ReturnType(); }+ ReturnType visitGlobal(Global* curr) { return ReturnType(); }+ ReturnType visitFunction(Function* curr) { return ReturnType(); }+ ReturnType visitTable(Table* curr) { return ReturnType(); }+ ReturnType visitMemory(Memory* curr) { return ReturnType(); }+ ReturnType visitEvent(Event* curr) { return ReturnType(); }+ ReturnType visitModule(Module* curr) { return ReturnType(); }++ ReturnType visit(Expression* curr) {+ assert(curr);++ switch (curr->_id) {+#define DELEGATE(CLASS_TO_VISIT) \+ case Expression::Id::CLASS_TO_VISIT##Id: \+ return static_cast<SubType*>(this)->visit##CLASS_TO_VISIT( \+ static_cast<CLASS_TO_VISIT*>(curr))++#include "wasm-delegations.h"++ default:+ WASM_UNREACHABLE("unexpected expression type");+ }+ }+};++// A visitor which must be overridden for each visitor that is reached.++template<typename SubType, typename ReturnType = void>+struct OverriddenVisitor {+// Expression visitors, which must be overridden+#define DELEGATE(CLASS_TO_VISIT) \+ ReturnType visit##CLASS_TO_VISIT(CLASS_TO_VISIT* curr) { \+ static_assert( \+ &SubType::visit##CLASS_TO_VISIT != \+ &OverriddenVisitor<SubType, ReturnType>::visit##CLASS_TO_VISIT, \+ "Derived class must implement visit" #CLASS_TO_VISIT); \+ WASM_UNREACHABLE("Derived class must implement visit" #CLASS_TO_VISIT); \+ }++#include "wasm-delegations.h"++ ReturnType visit(Expression* curr) {+ assert(curr);++ switch (curr->_id) {+#define DELEGATE(CLASS_TO_VISIT) \+ case Expression::Id::CLASS_TO_VISIT##Id: \+ return static_cast<SubType*>(this)->visit##CLASS_TO_VISIT( \+ static_cast<CLASS_TO_VISIT*>(curr))++#include "wasm-delegations.h"++ default:+ WASM_UNREACHABLE("unexpected expression type");+ }+ }+};++// Visit with a single unified visitor, called on every node, instead of+// separate visit* per node++template<typename SubType, typename ReturnType = void>+struct UnifiedExpressionVisitor : public Visitor<SubType, ReturnType> {+ // called on each node+ ReturnType visitExpression(Expression* curr) { return ReturnType(); }++ // redirects+#define DELEGATE(CLASS_TO_VISIT) \+ ReturnType visit##CLASS_TO_VISIT(CLASS_TO_VISIT* curr) { \+ return static_cast<SubType*>(this)->visitExpression(curr); \+ }++#include "wasm-delegations.h"+};++//+// Base class for all WasmWalkers, which can traverse an AST+// and provide the option to replace nodes while doing so.+//+// Subclass and implement the visit*()+// calls to run code on different node types.+//+template<typename SubType, typename VisitorType>+struct Walker : public VisitorType {+ // Useful methods for visitor implementions++ // Replace the current node. You can call this in your visit*() methods.+ // Note that the visit*() for the result node is not called for you (i.e.,+ // just one visit*() method is called by the traversal; if you replace a node,+ // and you want to process the output, you must do that explicitly).+ Expression* replaceCurrent(Expression* expression) {+ // Copy debug info, if present.+ if (currFunction) {+ auto& debugLocations = currFunction->debugLocations;+ if (!debugLocations.empty()) {+ auto* curr = getCurrent();+ auto iter = debugLocations.find(curr);+ if (iter != debugLocations.end()) {+ auto location = iter->second;+ debugLocations.erase(iter);+ debugLocations[expression] = location;+ }+ }+ }+ return *replacep = expression;+ }++ Expression* getCurrent() { return *replacep; }++ Expression** getCurrentPointer() { return replacep; }++ // Get the current module+ Module* getModule() { return currModule; }++ // Get the current function+ Function* getFunction() { return currFunction; }++ // Walk starting++ void walkGlobal(Global* global) {+ walk(global->init);+ static_cast<SubType*>(this)->visitGlobal(global);+ }++ void walkFunction(Function* func) {+ setFunction(func);+ static_cast<SubType*>(this)->doWalkFunction(func);+ static_cast<SubType*>(this)->visitFunction(func);+ setFunction(nullptr);+ }++ void walkEvent(Event* event) {+ static_cast<SubType*>(this)->visitEvent(event);+ }++ void walkFunctionInModule(Function* func, Module* module) {+ setModule(module);+ setFunction(func);+ static_cast<SubType*>(this)->doWalkFunction(func);+ static_cast<SubType*>(this)->visitFunction(func);+ setFunction(nullptr);+ setModule(nullptr);+ }++ // override this to provide custom functionality+ void doWalkFunction(Function* func) { walk(func->body); }++ void walkTable(Table* table) {+ for (auto& segment : table->segments) {+ walk(segment.offset);+ }+ static_cast<SubType*>(this)->visitTable(table);+ }++ void walkMemory(Memory* memory) {+ for (auto& segment : memory->segments) {+ if (!segment.isPassive) {+ walk(segment.offset);+ }+ }+ static_cast<SubType*>(this)->visitMemory(memory);+ }++ void walkModule(Module* module) {+ setModule(module);+ static_cast<SubType*>(this)->doWalkModule(module);+ static_cast<SubType*>(this)->visitModule(module);+ setModule(nullptr);+ }++ // override this to provide custom functionality+ void doWalkModule(Module* module) {+ // Dispatch statically through the SubType.+ SubType* self = static_cast<SubType*>(this);+ for (auto& curr : module->exports) {+ self->visitExport(curr.get());+ }+ for (auto& curr : module->globals) {+ if (curr->imported()) {+ self->visitGlobal(curr.get());+ } else {+ self->walkGlobal(curr.get());+ }+ }+ for (auto& curr : module->functions) {+ if (curr->imported()) {+ self->visitFunction(curr.get());+ } else {+ self->walkFunction(curr.get());+ }+ }+ for (auto& curr : module->events) {+ if (curr->imported()) {+ self->visitEvent(curr.get());+ } else {+ self->walkEvent(curr.get());+ }+ }+ self->walkTable(&module->table);+ self->walkMemory(&module->memory);+ }++ // Walk implementation. We don't use recursion as ASTs may be highly+ // nested.++ // Tasks receive the this pointer and a pointer to the pointer to operate on+ typedef void (*TaskFunc)(SubType*, Expression**);++ struct Task {+ TaskFunc func;+ Expression** currp;+ Task() {}+ Task(TaskFunc func, Expression** currp) : func(func), currp(currp) {}+ };++ void pushTask(TaskFunc func, Expression** currp) {+ assert(*currp);+ stack.emplace_back(func, currp);+ }+ void maybePushTask(TaskFunc func, Expression** currp) {+ if (*currp) {+ stack.emplace_back(func, currp);+ }+ }+ Task popTask() {+ auto ret = stack.back();+ stack.pop_back();+ return ret;+ }++ void walk(Expression*& root) {+ assert(stack.size() == 0);+ pushTask(SubType::scan, &root);+ while (stack.size() > 0) {+ auto task = popTask();+ replacep = task.currp;+ assert(*task.currp);+ task.func(static_cast<SubType*>(this), task.currp);+ }+ }++ // subclasses implement this to define the proper order of execution+ static void scan(SubType* self, Expression** currp) { abort(); }++ // task hooks to call visitors++#define DELEGATE(CLASS_TO_VISIT) \+ static void doVisit##CLASS_TO_VISIT(SubType* self, Expression** currp) { \+ self->visit##CLASS_TO_VISIT((*currp)->cast<CLASS_TO_VISIT>()); \+ }++#include "wasm-delegations.h"++ void setModule(Module* module) { currModule = module; }++ void setFunction(Function* func) { currFunction = func; }++private:+ // the address of the current node, used to replace it+ Expression** replacep = nullptr;+ SmallVector<Task, 10> stack; // stack of tasks+ Function* currFunction = nullptr; // current function being processed+ Module* currModule = nullptr; // current module being processed+};++// Walks in post-order, i.e., children first. When there isn't an obvious+// order to operands, we follow them in order of execution.++template<typename SubType, typename VisitorType = Visitor<SubType>>+struct PostWalker : public Walker<SubType, VisitorType> {++ static void scan(SubType* self, Expression** currp) {+ Expression* curr = *currp;++#define DELEGATE_ID curr->_id++#define DELEGATE_START(id) \+ self->pushTask(SubType::doVisit##id, currp); \+ auto* cast = curr->cast<id>(); \+ WASM_UNUSED(cast);++#define DELEGATE_GET_FIELD(id, name) cast->name++#define DELEGATE_FIELD_CHILD(id, name) \+ self->pushTask(SubType::scan, &cast->name);++#define DELEGATE_FIELD_OPTIONAL_CHILD(id, name) \+ self->maybePushTask(SubType::scan, &cast->name);++#define DELEGATE_FIELD_INT(id, name)+#define DELEGATE_FIELD_INT_ARRAY(id, name)+#define DELEGATE_FIELD_LITERAL(id, name)+#define DELEGATE_FIELD_NAME(id, name)+#define DELEGATE_FIELD_SCOPE_NAME_DEF(id, name)+#define DELEGATE_FIELD_SCOPE_NAME_USE(id, name)+#define DELEGATE_FIELD_SCOPE_NAME_USE_VECTOR(id, name)+#define DELEGATE_FIELD_SIGNATURE(id, name)+#define DELEGATE_FIELD_TYPE(id, name)+#define DELEGATE_FIELD_ADDRESS(id, name)++#include "wasm-delegations-fields.h" } };
binaryen/src/wasm-type.h view
@@ -17,6 +17,7 @@ #ifndef wasm_wasm_type_h #define wasm_wasm_type_h +#include "support/name.h" #include "wasm-features.h" #include <ostream> #include <vector>@@ -31,15 +32,37 @@ namespace wasm { +// The types defined in this file. All of them are small and typically passed by+// value except for `Tuple` and `Struct`, which may own an unbounded amount of+// data.+class Type;+class HeapType;+struct Tuple;+struct Signature;+struct Field;+struct Struct;+struct Array;+struct Rtt;++enum Nullability { NonNullable, Nullable };+enum Mutability { Immutable, Mutable };++// The type used for interning IDs in the public interfaces of Type and+// HeapType.+using TypeID = uint64_t;+ class Type { // The `id` uniquely represents each type, so type equality is just a- // comparison of the ids. For basic types the `id` is just the `BasicID`+ // comparison of the ids. For basic types the `id` is just the `BasicType` // enum value below, and for constructed types the `id` is the address of the // canonical representation of the type, making lookups cheap for all types.+ // Since `Type` is really just a single integer, it should be passed by value.+ // This is a uintptr_t rather than a TypeID (uint64_t) to save memory on+ // 32-bit platforms. uintptr_t id; public:- enum BasicID : uint32_t {+ enum BasicType : uint32_t { none, unreachable, i32,@@ -53,29 +76,30 @@ anyref, eqref, i31ref,- _last_basic_id = i31ref, };+ static constexpr BasicType _last_basic_type = i31ref; - Type() = default;+ Type() : id(none) {} - // BasicID can be implicitly upgraded to Type- constexpr Type(BasicID id) : id(id){};+ // BasicType can be implicitly upgraded to Type+ constexpr Type(BasicType id) : id(id) {} - // But converting raw uint32_t is more dangerous, so make it explicit- explicit Type(uint64_t id) : id(id){};+ // But converting raw TypeID is more dangerous, so make it explicit+ explicit Type(TypeID id) : id(id) {} // Construct tuple from a list of single types Type(std::initializer_list<Type>); // Construct from tuple description- explicit Type(const struct Tuple&);+ Type(const Tuple&);+ Type(Tuple&&); // Construct from a heap type description. Also covers construction from // Signature, Struct or Array via implicit conversion to HeapType.- explicit Type(const struct HeapType&, bool nullable);+ Type(HeapType, Nullability nullable); // Construct from rtt description- explicit Type(const struct Rtt&);+ Type(Rtt); // Predicates // Compound Concrete@@ -101,8 +125,8 @@ // │ Tuple ║ │ x │ │ x │ │ // │ Rtt ║ │ x │ x │ x │ │ // └─────────────╨───┴───┴───┴───┴───────┘- constexpr bool isBasic() const { return id <= _last_basic_id; }- constexpr bool isCompound() const { return id > _last_basic_id; }+ constexpr bool isBasic() const { return id <= _last_basic_type; }+ constexpr bool isCompound() const { return id > _last_basic_type; } constexpr bool isConcrete() const { return id >= i32; } constexpr bool isInteger() const { return id == i32 || id == i64; } constexpr bool isFloat() const { return id == f32 || id == f64; }@@ -115,6 +139,8 @@ bool isException() const; bool isNullable() const; bool isRtt() const;+ bool isStruct() const;+ bool isArray() const; private: template<bool (Type::*pred)() const> bool hasPredicate() {@@ -130,19 +156,19 @@ bool hasVector() { return hasPredicate<&Type::isVector>(); } bool hasRef() { return hasPredicate<&Type::isRef>(); } - constexpr uint64_t getID() const { return id; }- constexpr BasicID getBasic() const {+ constexpr TypeID getID() const { return id; }+ constexpr BasicType getBasic() const { assert(isBasic() && "Basic type expected");- return static_cast<BasicID>(id);+ return static_cast<BasicType>(id); } - // (In)equality must be defined for both Type and BasicID because it is+ // (In)equality must be defined for both Type and BasicType because it is // otherwise ambiguous whether to convert both this and other to int or // convert other to Type. bool operator==(const Type& other) const { return id == other.id; }- bool operator==(const BasicID& otherId) const { return id == otherId; }+ bool operator==(const BasicType& other) const { return id == other; } bool operator!=(const Type& other) const { return id != other.id; }- bool operator!=(const BasicID& otherId) const { return id != otherId; }+ bool operator!=(const BasicType& other) const { return id != other; } // Order types by some notion of simplicity bool operator<(const Type& other) const;@@ -157,9 +183,13 @@ // Returns the feature set required to use this type. FeatureSet getFeatures() const; - // Gets the heap type corresponding to this type+ // Gets the heap type corresponding to this type, assuming that it is a+ // reference or Rtt type. HeapType getHeapType() const; + // Gets the Rtt for this type, assuming that it is an Rtt type.+ Rtt getRtt() const;+ // Returns a number type based on its size in bytes and whether it is a float // type. static Type get(unsigned byteSize, bool float_);@@ -251,17 +281,90 @@ std::string toString() const; }; +class HeapType {+ // Unlike `Type`, which represents the types of values on the WebAssembly+ // stack, `HeapType` is used to describe the structures that reference types+ // refer to. HeapTypes are canonicalized and interned exactly like Types and+ // should also be passed by value.+ uintptr_t id;++public:+ enum BasicHeapType : uint32_t {+ func,+ ext,+ exn,+ any,+ eq,+ i31,+ };+ static constexpr BasicHeapType _last_basic_type = i31;++ // BasicHeapType can be implicitly upgraded to HeapType+ constexpr HeapType(BasicHeapType id) : id(id) {}++ // But converting raw TypeID is more dangerous, so make it explicit+ explicit HeapType(TypeID id) : id(id) {}++ HeapType(Signature signature);+ HeapType(const Struct& struct_);+ HeapType(Struct&& struct_);+ HeapType(Array array);++ constexpr bool isBasic() const { return id <= _last_basic_type; }+ constexpr bool isCompound() const { return id > _last_basic_type; }+ bool isFunction() const;+ bool isSignature() const;+ bool isStruct() const;+ bool isArray() const;++ Signature getSignature() const;+ const Struct& getStruct() const;+ Array getArray() const;++ constexpr TypeID getID() const { return id; }+ constexpr BasicHeapType getBasic() const {+ assert(isBasic() && "Basic heap type expected");+ return static_cast<BasicHeapType>(id);+ }++ // (In)equality must be defined for both HeapType and BasicHeapType because it+ // is otherwise ambiguous whether to convert both this and other to int or+ // convert other to HeapType.+ bool operator==(const HeapType& other) const { return id == other.id; }+ bool operator==(const BasicHeapType& other) const { return id == other; }+ bool operator!=(const HeapType& other) const { return id != other.id; }+ bool operator!=(const BasicHeapType& other) const { return id != other; }++ bool operator<(const HeapType& other) const;+ std::string toString() const;+};+ typedef std::vector<Type> TypeList; +// Passed by reference rather than by value because it can own an unbounded+// amount of data. struct Tuple { TypeList types; Tuple() : types() {}- Tuple(std::initializer_list<Type> types) : types(types) {}- Tuple(const TypeList& types) : types(types) {}- Tuple(TypeList&& types) : types(std::move(types)) {}+ Tuple(std::initializer_list<Type> types) : types(types) { validate(); }+ Tuple(const TypeList& types) : types(types) { validate(); }+ Tuple(TypeList&& types) : types(std::move(types)) { validate(); } bool operator==(const Tuple& other) const { return types == other.types; } bool operator!=(const Tuple& other) const { return !(*this == other); }+ bool operator<(const Tuple& other) const { return types < other.types; } std::string toString() const;++ // Prevent accidental copies+ Tuple& operator=(const Tuple&) = delete;++private:+ void validate() {+#ifndef NDEBUG+ for (auto type : types) {+ assert(type.isSingle());+ }+#endif+ } }; struct Signature {@@ -284,12 +387,13 @@ i8, i16, } packedType; // applicable iff type=i32- bool mutable_;+ Mutability mutable_;+ Name name; - Field(Type type, bool mutable_ = false)- : type(type), packedType(not_packed), mutable_(mutable_) {}- Field(PackedType packedType, bool mutable_ = false)- : type(Type::i32), packedType(packedType), mutable_(mutable_) {}+ Field(Type type, Mutability mutable_, Name name = Name())+ : type(type), packedType(not_packed), mutable_(mutable_), name(name) {}+ Field(PackedType packedType, Mutability mutable_, Name name = Name())+ : type(Type::i32), packedType(packedType), mutable_(mutable_), name(name) {} constexpr bool isPacked() const { if (packedType != not_packed) {@@ -300,15 +404,20 @@ } bool operator==(const Field& other) const {+ // Note that the name is not checked here - it is pure metadata for printing+ // purposes only. return type == other.type && packedType == other.packedType && mutable_ == other.mutable_; } bool operator!=(const Field& other) const { return !(*this == other); }+ bool operator<(const Field& other) const; std::string toString() const; }; typedef std::vector<Field> FieldList; +// Passed by reference rather than by value because it can own an unbounded+// amount of data. struct Struct { FieldList fields; Struct(const Struct& other) : fields(other.fields) {}@@ -316,84 +425,73 @@ Struct(FieldList&& fields) : fields(std::move(fields)) {} bool operator==(const Struct& other) const { return fields == other.fields; } bool operator!=(const Struct& other) const { return !(*this == other); }+ bool operator<(const Struct& other) const { return fields < other.fields; } std::string toString() const;++ // Prevent accidental copies+ Struct& operator=(const Struct&) = delete; }; struct Array { Field element; Array(const Array& other) : element(other.element) {}- Array(const Field& element) : element(element) {}- Array(Field&& element) : element(std::move(element)) {}+ Array(Field element) : element(element) {} bool operator==(const Array& other) const { return element == other.element; } bool operator!=(const Array& other) const { return !(*this == other); }- std::string toString() const;-};--struct HeapType {- enum Kind {- FuncKind,- ExternKind,- ExnKind,- AnyKind,- EqKind,- I31Kind,- _last_basic_kind = I31Kind,- SignatureKind,- StructKind,- ArrayKind,- } kind;- union {- Signature signature;- Struct struct_;- Array array;- };- HeapType(Kind kind) : kind(kind) { assert(kind <= _last_basic_kind); }- HeapType(const Signature& signature)- : kind(SignatureKind), signature(signature) {}- HeapType(Signature&& signature)- : kind(SignatureKind), signature(std::move(signature)) {}- HeapType(const Struct& struct_) : kind(StructKind), struct_(struct_) {}- HeapType(Struct&& struct_) : kind(StructKind), struct_(std::move(struct_)) {}- HeapType(const Array& array) : kind(ArrayKind), array(array) {}- HeapType(Array&& array) : kind(ArrayKind), array(std::move(array)) {}- HeapType(const HeapType& other);- ~HeapType();-- bool isSignature() const { return kind == SignatureKind; }- Signature getSignature() const {- assert(isSignature() && "Not a signature");- return signature;- }- bool isStruct() const { return kind == StructKind; }- Struct getStruct() const {- assert(isStruct() && "Not a struct");- return struct_;- }- bool isArray() const { return kind == ArrayKind; }- Array getArray() const {- assert(isArray() && "Not an array");- return array;- }- bool isException() const { return kind == ExnKind; }-- bool operator==(const HeapType& other) const;- bool operator!=(const HeapType& other) const { return !(*this == other); }- HeapType& operator=(const HeapType& other);+ bool operator<(const Array& other) const { return element < other.element; } std::string toString() const; }; struct Rtt {+ // An Rtt can have no depth specified+ static constexpr uint32_t NoDepth = -1; uint32_t depth; HeapType heapType;- Rtt(uint32_t depth, const HeapType& heapType)- : depth(depth), heapType(heapType) {}- Rtt(uint32_t depth, HeapType&& heapType)- : depth(depth), heapType(std::move(heapType)) {}+ Rtt(HeapType heapType) : depth(NoDepth), heapType(heapType) {}+ Rtt(uint32_t depth, HeapType heapType) : depth(depth), heapType(heapType) {} bool operator==(const Rtt& other) const { return depth == other.depth && heapType == other.heapType; } bool operator!=(const Rtt& other) const { return !(*this == other); }+ bool operator<(const Rtt& other) const;+ bool hasDepth() { return depth != uint32_t(NoDepth); } std::string toString() const;+};++// TypeBuilder - allows for the construction of recursive types. Contains a+// table of `n` mutable HeapTypes and can construct temporary types that are+// backed by those HeapTypes, refering to them by reference. Those temporary+// types are owned by the TypeBuilder and should only be used in the+// construction of HeapTypes to insert into the TypeBuilder. Temporary types+// should never be used in the construction of normal Types, only other+// temporary types.+struct TypeBuilder {+ struct Impl;+ std::unique_ptr<Impl> impl;++ TypeBuilder(size_t n);+ ~TypeBuilder();++ TypeBuilder(TypeBuilder& other) = delete;+ TypeBuilder(TypeBuilder&& other) = delete;+ TypeBuilder& operator=(TypeBuilder&) = delete;++ // Sets the heap type at index `i`. May only be called before `build`.+ void setHeapType(size_t i, Signature signature);+ void setHeapType(size_t i, const Struct& struct_);+ void setHeapType(size_t i, Struct&& struct_);+ void setHeapType(size_t i, Array array);++ // Gets a temporary type or heap type for use in initializing the+ // TypeBuilder's HeapTypes. Temporary Ref and Rtt types are backed by the+ // HeapType at index `i`.+ Type getTempTupleType(const Tuple&);+ Type getTempRefType(size_t i, Nullability nullable);+ Type getTempRttType(size_t i, uint32_t depth);++ // Canonicalizes and returns all of the heap types. May only be called once+ // all of the heap types have been initialized with `setHeapType`.+ std::vector<HeapType> build(); }; std::ostream& operator<<(std::ostream&, Type);
binaryen/src/wasm-validator.h view
@@ -43,7 +43,6 @@ #include <sstream> #include <unordered_set> -#include "wasm-printing.h" #include "wasm.h" namespace wasm {
binaryen/src/wasm.h view
@@ -28,6 +28,7 @@ #include <array> #include <cassert> #include <map>+#include <ostream> #include <string> #include <vector> @@ -161,6 +162,7 @@ AnyTrueVecI8x16, AllTrueVecI8x16, BitmaskVecI8x16,+ PopcntVecI8x16, AbsVecI16x8, NegVecI16x8, AnyTrueVecI16x8,@@ -172,8 +174,7 @@ AllTrueVecI32x4, BitmaskVecI32x4, NegVecI64x2,- AnyTrueVecI64x2,- AllTrueVecI64x2,+ BitmaskVecI64x2, AbsVecF32x4, NegVecF32x4, SqrtVecF32x4,@@ -188,6 +189,10 @@ FloorVecF64x2, TruncVecF64x2, NearestVecF64x2,+ ExtAddPairwiseSVecI8x16ToI16x8,+ ExtAddPairwiseUVecI8x16ToI16x8,+ ExtAddPairwiseSVecI16x8ToI32x4,+ ExtAddPairwiseUVecI16x8ToI32x4, // SIMD conversions TruncSatSVecF32x4ToVecI32x4,@@ -206,6 +211,10 @@ WidenHighSVecI16x8ToVecI32x4, WidenLowUVecI16x8ToVecI32x4, WidenHighUVecI16x8ToVecI32x4,+ WidenLowSVecI32x4ToVecI64x2,+ WidenHighSVecI32x4ToVecI64x2,+ WidenLowUVecI32x4ToVecI64x2,+ WidenHighUVecI32x4ToVecI64x2, InvalidUnary };@@ -350,6 +359,7 @@ LeUVecI32x4, GeSVecI32x4, GeUVecI32x4,+ EqVecI64x2, EqVecF32x4, NeVecF32x4, LtVecF32x4,@@ -392,6 +402,11 @@ MaxSVecI16x8, MaxUVecI16x8, AvgrUVecI16x8,+ Q15MulrSatSVecI16x8,+ ExtMulLowSVecI16x8,+ ExtMulHighSVecI16x8,+ ExtMulLowUVecI16x8,+ ExtMulHighUVecI16x8, AddVecI32x4, SubVecI32x4, MulVecI32x4,@@ -400,9 +415,17 @@ MaxSVecI32x4, MaxUVecI32x4, DotSVecI16x8ToVecI32x4,+ ExtMulLowSVecI32x4,+ ExtMulHighSVecI32x4,+ ExtMulLowUVecI32x4,+ ExtMulHighUVecI32x4, AddVecI64x2, SubVecI64x2, MulVecI64x2,+ ExtMulLowSVecI64x2,+ ExtMulHighSVecI64x2,+ ExtMulLowUVecI64x2,+ ExtMulHighUVecI64x2, AddVecF32x4, SubVecF32x4, MulVecF32x4,@@ -432,7 +455,7 @@ InvalidBinary }; -enum AtomicRMWOp { Add, Sub, And, Or, Xor, Xchg };+enum AtomicRMWOp { RMWAdd, RMWSub, RMWAnd, RMWOr, RMWXor, RMWXchg }; enum SIMDExtractOp { ExtractLaneSVecI8x16,@@ -481,11 +504,37 @@ LoadExtSVec32x2ToVecI64x2, LoadExtUVec32x2ToVecI64x2, Load32Zero,- Load64Zero+ Load64Zero, }; -enum SIMDTernaryOp { Bitselect, QFMAF32x4, QFMSF32x4, QFMAF64x2, QFMSF64x2 };+enum SIMDLoadStoreLaneOp {+ LoadLaneVec8x16,+ LoadLaneVec16x8,+ LoadLaneVec32x4,+ LoadLaneVec64x2,+ StoreLaneVec8x16,+ StoreLaneVec16x8,+ StoreLaneVec32x4,+ StoreLaneVec64x2,+}; +enum SIMDTernaryOp {+ Bitselect,+ QFMAF32x4,+ QFMSF32x4,+ QFMAF64x2,+ QFMSF64x2,+ SignSelectVec8x16,+ SignSelectVec16x8,+ SignSelectVec32x4,+ SignSelectVec64x2+};++enum PrefetchOp {+ PrefetchTemporal,+ PrefetchNontemporal,+};+ // // Expressions //@@ -533,6 +582,7 @@ MemorySizeId, MemoryGrowId, NopId,+ PrefetchId, UnreachableId, AtomicRMWId, AtomicCmpxchgId,@@ -545,6 +595,7 @@ SIMDTernaryId, SIMDShiftId, SIMDLoadId,+ SIMDLoadStoreLaneId, MemoryInitId, DataDropId, MemoryCopyId,@@ -562,6 +613,7 @@ TupleExtractId, I31NewId, I31GetId,+ CallRefId, RefTestId, RefCastId, BrOnCastId,@@ -660,11 +712,13 @@ // needed (which may require scanning the block) void finalize(Type type_); + enum Breakability { Unknown, HasBreak, NoBreak };+ // set the type given you know its type, and you know if there is a break to // this block. this avoids the need to scan the contents of the block in the // case that it might be unreachable, so it is recommended if you already know // the type and breakability anyhow.- void finalize(Type type_, bool hasBreak);+ void finalize(Type type_, Breakability breakability); }; class If : public SpecificExpression<Expression::IfId> {@@ -970,6 +1024,37 @@ void finalize(); }; +class SIMDLoadStoreLane+ : public SpecificExpression<Expression::SIMDLoadStoreLaneId> {+public:+ SIMDLoadStoreLane() = default;+ SIMDLoadStoreLane(MixedArena& allocator) {}++ SIMDLoadStoreLaneOp op;+ Address offset;+ Address align;+ uint8_t index;+ Expression* ptr;+ Expression* vec;++ bool isStore();+ bool isLoad() { return !isStore(); }+ Index getMemBytes();+ void finalize();+};++class Prefetch : public SpecificExpression<Expression::PrefetchId> {+public:+ Prefetch() = default;+ Prefetch(MixedArena& allocator) : Prefetch() {}++ PrefetchOp op;+ Address offset;+ Address align;+ Expression* ptr;+ void finalize();+};+ class MemoryInit : public SpecificExpression<Expression::MemoryInitId> { public: MemoryInit() = default;@@ -1153,6 +1238,7 @@ Name func; void finalize();+ void finalize(Type type_); }; class RefEq : public SpecificExpression<Expression::RefEqId> {@@ -1248,97 +1334,181 @@ void finalize(); }; +class CallRef : public SpecificExpression<Expression::CallRefId> {+public:+ CallRef(MixedArena& allocator) : operands(allocator) {}+ ExpressionList operands;+ Expression* target;+ bool isReturn = false;++ void finalize();+ void finalize(Type type_);+};+ class RefTest : public SpecificExpression<Expression::RefTestId> { public: RefTest(MixedArena& allocator) {} - void finalize() { WASM_UNREACHABLE("TODO (gc): ref.test"); }+ Expression* ref;+ Expression* rtt;++ void finalize();++ Type getCastType(); }; class RefCast : public SpecificExpression<Expression::RefCastId> { public: RefCast(MixedArena& allocator) {} - void finalize() { WASM_UNREACHABLE("TODO (gc): ref.cast"); }+ Expression* ref;+ Expression* rtt;++ void finalize();++ Type getCastType(); }; class BrOnCast : public SpecificExpression<Expression::BrOnCastId> { public: BrOnCast(MixedArena& allocator) {} - void finalize() { WASM_UNREACHABLE("TODO (gc): br_on_cast"); }+ Name name;+ // The cast type cannot be inferred from rtt if rtt is unreachable, so we must+ // store it explicitly.+ Type castType;+ Expression* ref;+ Expression* rtt;++ void finalize();++ Type getCastType(); }; class RttCanon : public SpecificExpression<Expression::RttCanonId> { public: RttCanon(MixedArena& allocator) {} - void finalize() { WASM_UNREACHABLE("TODO (gc): rtt.canon"); }+ void finalize(); }; class RttSub : public SpecificExpression<Expression::RttSubId> { public: RttSub(MixedArena& allocator) {} - void finalize() { WASM_UNREACHABLE("TODO (gc): rtt.sub"); }+ Expression* parent;++ void finalize(); }; class StructNew : public SpecificExpression<Expression::StructNewId> { public:- StructNew(MixedArena& allocator) {}+ StructNew(MixedArena& allocator) : operands(allocator) {} - void finalize() { WASM_UNREACHABLE("TODO (gc): struct.new"); }+ Expression* rtt;+ // A struct.new_with_default has empty operands. This does leave the case of a+ // struct with no fields ambiguous, but it doesn't make a difference in that+ // case, and binaryen doesn't guarantee roundtripping binaries anyhow.+ ExpressionList operands;++ bool isWithDefault() { return operands.empty(); }++ void finalize(); }; class StructGet : public SpecificExpression<Expression::StructGetId> { public: StructGet(MixedArena& allocator) {} - void finalize() { WASM_UNREACHABLE("TODO (gc): struct.get"); }+ Index index;+ Expression* ref;+ // Packed fields have a sign.+ bool signed_ = false;++ void finalize(); }; class StructSet : public SpecificExpression<Expression::StructSetId> { public: StructSet(MixedArena& allocator) {} - void finalize() { WASM_UNREACHABLE("TODO (gc): struct.set"); }+ Index index;+ Expression* ref;+ Expression* value;++ void finalize(); }; class ArrayNew : public SpecificExpression<Expression::ArrayNewId> { public: ArrayNew(MixedArena& allocator) {} - void finalize() { WASM_UNREACHABLE("TODO (gc): array.new"); }+ Expression* rtt;+ Expression* size;+ // If set, then the initial value is assigned to all entries in the array. If+ // not set, this is array.new_with_default and the default of the type is+ // used.+ Expression* init = nullptr;++ bool isWithDefault() { return !init; }++ void finalize(); }; class ArrayGet : public SpecificExpression<Expression::ArrayGetId> { public: ArrayGet(MixedArena& allocator) {} - void finalize() { WASM_UNREACHABLE("TODO (gc): array.get"); }+ Expression* ref;+ Expression* index;+ // Packed fields have a sign.+ bool signed_ = false;++ void finalize(); }; class ArraySet : public SpecificExpression<Expression::ArraySetId> { public: ArraySet(MixedArena& allocator) {} - void finalize() { WASM_UNREACHABLE("TODO (gc): array.set"); }+ Expression* ref;+ Expression* index;+ Expression* value;++ void finalize(); }; class ArrayLen : public SpecificExpression<Expression::ArrayLenId> { public: ArrayLen(MixedArena& allocator) {} - void finalize() { WASM_UNREACHABLE("TODO (gc): array.len"); }+ Expression* ref;++ void finalize(); }; // Globals struct Importable {+ Name name;++ // Explicit names are ones that we read from the input file and+ // will be written the name section in the output file.+ // Implicit names are names that binaryen generated for internal+ // use only and will not be written the name section.+ bool hasExplicitName = false;+ // If these are set, then this is an import, as module.base Name module, base; - bool imported() { return module.is(); }+ bool imported() const { return module.is(); }++ void setName(Name name_, bool hasExplicitName_) {+ name = name_;+ hasExplicitName = hasExplicitName_;+ }++ void setExplicitName(Name name_) { setName(name_, true); } }; class Function;@@ -1366,10 +1536,10 @@ // control flow, have, like 'end' for loop and block. We keep these in a // separate map because they are rare and we optimize for the storage space // for the common type of instruction which just needs a Span. We implement- // this as a simple struct with two elements (as two extra elements is the- // maximum currently needed; due to 'catch' and 'end' for try-catch). The- // second value may be 0, indicating it is not used.- struct DelimiterLocations : public std::array<BinaryLocation, 2> {+ // this as a simple array with one element at the moment (more elements may+ // be necessary in the future).+ // TODO: If we are sure we won't need more, make this a single value?+ struct DelimiterLocations : public std::array<BinaryLocation, 1> { DelimiterLocations() { // Ensure zero-initialization. for (auto& item : *this) {@@ -1378,14 +1548,7 @@ } }; - enum DelimiterId {- // All control flow structures have an end, so use index 0 for that.- End = 0,- // Use index 1 for all other current things.- Else = 1,- Catch = 1,- Invalid = -1- };+ enum DelimiterId { Else = 0, Catch = 0, Invalid = -1 }; std::unordered_map<Expression*, DelimiterLocations> delimiters; // DWARF debug info can refer to multiple interesting positions in a function.@@ -1411,7 +1574,6 @@ class Function : public Importable { public:- Name name; Signature sig; // parameters and return value IRProfile profile = IRProfile::Normal; std::vector<Type> vars; // non-param locals@@ -1523,7 +1685,6 @@ // been defined or imported. The table can exist but be empty and have no // defined initial or max size. bool exists = false;- Name name; Address initial = 0; Address max = kMaxSize; std::vector<Segment> segments;@@ -1548,6 +1709,8 @@ (uint64_t(4) * 1024 * 1024 * 1024) / kPageSize; struct Segment {+ // For use in name section only+ Name name; bool isPassive = false; Expression* offset = nullptr; std::vector<char> data; // TODO: optimize@@ -1561,15 +1724,18 @@ Segment(Expression* offset, std::vector<char>& init) : offset(offset) { data.swap(init); }- Segment(bool isPassive, Expression* offset, const char* init, Address size)- : isPassive(isPassive), offset(offset) {+ Segment(Name name,+ bool isPassive,+ Expression* offset,+ const char* init,+ Address size)+ : name(name), isPassive(isPassive), offset(offset) { data.resize(size); std::copy_n(init, size, data.begin()); } }; bool exists = false;- Name name; Address initial = 0; // sizes are in pages Address max = kMaxSize32; std::vector<Segment> segments;@@ -1594,7 +1760,6 @@ class Global : public Importable { public:- Name name; Type type; Expression* init = nullptr; bool mutable_ = false;@@ -1605,7 +1770,6 @@ class Event : public Importable { public:- Name name; // Kind of event. Currently only WASM_EVENT_ATTRIBUTE_EXCEPTION is possible. uint32_t attribute = WASM_EVENT_ATTRIBUTE_EXCEPTION; Signature sig;@@ -1686,10 +1850,10 @@ Global* addGlobal(Global* curr); Event* addEvent(Event* curr); - Export* addExport(std::unique_ptr<Export> curr);- Function* addFunction(std::unique_ptr<Function> curr);- Global* addGlobal(std::unique_ptr<Global> curr);- Event* addEvent(std::unique_ptr<Event> curr);+ Export* addExport(std::unique_ptr<Export>&& curr);+ Function* addFunction(std::unique_ptr<Function>&& curr);+ Global* addGlobal(std::unique_ptr<Global>&& curr);+ Event* addEvent(std::unique_ptr<Event>&& curr); void addStart(const Name& s); @@ -1716,6 +1880,12 @@ return std::hash<wasm::Address::address64_t>()(a.addr); } };++std::ostream& operator<<(std::ostream& o, wasm::Module& module);+std::ostream& operator<<(std::ostream& o, wasm::Expression& expression);+std::ostream& operator<<(std::ostream& o, wasm::StackInst& inst);+std::ostream& operator<<(std::ostream& o, wasm::StackIR& ir);+ } // namespace std #endif // wasm_wasm_h
binaryen/src/wasm/literal.cpp view
@@ -37,6 +37,11 @@ assert(type != Type::unreachable && (!type.isRef() || type.isNullable())); if (type.isException()) { new (&exn) std::unique_ptr<ExceptionPackage>();+ } else if (isGCData()) {+ new (&gcData) std::shared_ptr<GCData>();+ } else if (type.isRtt()) {+ // Allocate a new RttSupers (with no data).+ new (&rttSupers) auto(std::make_unique<RttSupers>()); } else { memset(&v128, 0, 16); }@@ -47,6 +52,19 @@ memcpy(&v128, init, 16); } +Literal::Literal(std::shared_ptr<GCData> gcData, Type type)+ : gcData(gcData), type(type) {+ // Null data is only allowed if nullable.+ assert(gcData || type.isNullable());+ // The type must be a proper type for GC data.+ assert(isGCData());+}++Literal::Literal(std::unique_ptr<RttSupers>&& rttSupers, Type type)+ : rttSupers(std::move(rttSupers)), type(type) {+ assert(type.isRtt());+}+ Literal::Literal(const Literal& other) : type(other.type) { if (type.isException()) { // Avoid calling the destructor on an uninitialized value@@ -55,8 +73,13 @@ } else { new (&exn) std::unique_ptr<ExceptionPackage>(); }+ } else if (other.isGCData()) {+ new (&gcData) std::shared_ptr<GCData>(other.gcData); } else if (type.isFunction()) { func = other.func;+ } else if (type.isRtt()) {+ // Allocate a new RttSupers with a copy of the other's data.+ new (&rttSupers) auto(std::make_unique<RttSupers>(*other.rttSupers)); } else { TODO_SINGLE_COMPOUND(type); switch (type.getBasic()) {@@ -86,6 +109,21 @@ } } +Literal::~Literal() {+ if (type.isException()) {+ exn.~unique_ptr();+ } else if (isGCData()) {+ gcData.~shared_ptr();+ } else if (type.isRtt()) {+ rttSupers.~unique_ptr();+ } else if (type.isFunction()) {+ // Nothing special to do.+ } else {+ // Basic types need no special handling.+ assert(type.isBasic());+ }+}+ Literal& Literal::operator=(const Literal& other) { if (this != &other) { this->~Literal();@@ -162,6 +200,8 @@ } else { return makeNull(type); }+ } else if (type.isRtt()) {+ return Literal(type); } else { return makeFromInt32(0, type); }@@ -189,6 +229,16 @@ return *exn; } +std::shared_ptr<GCData> Literal::getGCData() const {+ assert(isGCData());+ return gcData;+}++const RttSupers& Literal::getRttSupers() const {+ assert(type.isRtt());+ return *rttSupers;+}+ Literal Literal::castToF32() { assert(type == Type::i32); Literal ret(Type::f32);@@ -322,7 +372,7 @@ } else if (type.isRef()) { return compareRef(); } else if (type.isRtt()) {- WASM_UNREACHABLE("TODO: rtt literals");+ return *rttSupers == *other.rttSupers; } WASM_UNREACHABLE("unexpected type"); }@@ -422,58 +472,72 @@ std::ostream& operator<<(std::ostream& o, Literal literal) { prepareMinorColor(o);- TODO_SINGLE_COMPOUND(literal.type);- switch (literal.type.getBasic()) {- case Type::none:- o << "?";- break;- case Type::i32:- o << literal.geti32();- break;- case Type::i64:- o << literal.geti64();- break;- case Type::f32:- literal.printFloat(o, literal.getf32());- break;- case Type::f64:- literal.printDouble(o, literal.getf64());- break;- case Type::v128:- o << "i32x4 ";- literal.printVec128(o, literal.getv128());- break;- case Type::funcref:- if (literal.isNull()) {- o << "funcref(null)";- } else {- o << "funcref(" << literal.getFunc() << ")";- }- break;- case Type::externref:- assert(literal.isNull() && "unexpected non-null externref literal");- o << "externref(null)";- break;- case Type::exnref:- if (literal.isNull()) {- o << "exnref(null)";- } else {- o << "exnref(" << literal.getExceptionPackage() << ")";- }- break;- case Type::anyref:- assert(literal.isNull() && "unexpected non-null anyref literal");- o << "anyref(null)";- break;- case Type::eqref:- assert(literal.isNull() && "unexpected non-null eqref literal");- o << "eqref(null)";- break;- case Type::i31ref:- o << "i31ref(" << literal.geti31() << ")";- break;- case Type::unreachable:- WASM_UNREACHABLE("invalid type");+ if (literal.type.isFunction()) {+ if (literal.isNull()) {+ o << "funcref(null)";+ } else {+ o << "funcref(" << literal.getFunc() << ")";+ }+ } else if (literal.isGCData()) {+ auto data = literal.getGCData();+ if (data) {+ o << "[ref " << data->rtt << ' ' << data->values << ']';+ } else {+ o << "[ref null " << literal.type << ']';+ }+ } else if (literal.type.isRtt()) {+ o << "[rtt ";+ for (Type super : literal.getRttSupers()) {+ o << super << " :> ";+ }+ o << literal.type << ']';+ } else {+ TODO_SINGLE_COMPOUND(literal.type);+ switch (literal.type.getBasic()) {+ case Type::none:+ o << "?";+ break;+ case Type::i32:+ o << literal.geti32();+ break;+ case Type::i64:+ o << literal.geti64();+ break;+ case Type::f32:+ literal.printFloat(o, literal.getf32());+ break;+ case Type::f64:+ literal.printDouble(o, literal.getf64());+ break;+ case Type::v128:+ o << "i32x4 ";+ literal.printVec128(o, literal.getv128());+ break;+ case Type::externref:+ assert(literal.isNull() && "unexpected non-null externref literal");+ o << "externref(null)";+ break;+ case Type::exnref:+ if (literal.isNull()) {+ o << "exnref(null)";+ } else {+ o << "exnref(" << literal.getExceptionPackage() << ")";+ }+ break;+ case Type::anyref:+ assert(literal.isNull() && "unexpected non-null anyref literal");+ o << "anyref(null)";+ break;+ case Type::eqref:+ assert(literal.isNull() && "unexpected non-null eqref literal");+ o << "eqref(null)";+ break;+ case Type::i31ref:+ o << "i31ref(" << literal.geti31() << ")";+ break;+ default:+ WASM_UNREACHABLE("invalid type");+ } } restoreNormalColor(o); return o;@@ -837,6 +901,40 @@ return Literal(float(getf64())); } +// Wasm has nondeterministic rules for NaN propagation in some operations. For+// example. f32.neg is deterministic and just flips the sign, even of a NaN, but+// f32.add is nondeterministic, and if one or more of the inputs is a NaN, then+//+// * if all NaNs are canonical NaNs, the output is some arbitrary canonical NaN+// * otherwise the output is some arbitrary arithmetic NaN+//+// (canonical = NaN payload is 1000..000; arithmetic: 1???..???, that is, the+// high bit is 1 and all others can be 0 or 1)+//+// For many things we don't need to care, and can just do a normal C++ add for+// an f32.add, for example - the wasm rules are specified so that things like+// that just work (in order for such math to be fast). However, for our+// optimizer, it is useful to "standardize" NaNs when there is nondeterminism.+// That is, when there are multiple valid outputs, it's nice to emit the same+// one consistently, so that it doesn't look like the optimization changed+// something. In other words, if the valid output of an expression is a set of+// valid NaNs, and after optimization the output is still that same set, then+// the optimization is valid. And if the interpreter picks the same NaN in both+// cases from that identical set then nothing looks wrong to the fuzzer.+template<typename T> static Literal standardizeNaN(T result) {+ if (!std::isnan(result)) {+ return Literal(result);+ }+ // Pick a simple canonical payload, and positive.+ if (sizeof(T) == 4) {+ return Literal(Literal(uint32_t(0x7fc00000u)).reinterpretf32());+ } else if (sizeof(T) == 8) {+ return Literal(Literal(uint64_t(0x7ff8000000000000ull)).reinterpretf64());+ } else {+ WASM_UNREACHABLE("invalid float");+ }+}+ Literal Literal::add(const Literal& other) const { switch (type.getBasic()) { case Type::i32:@@ -844,9 +942,9 @@ case Type::i64: return Literal(uint64_t(i64) + uint64_t(other.i64)); case Type::f32:- return Literal(getf32() + other.getf32());+ return standardizeNaN(getf32() + other.getf32()); case Type::f64:- return Literal(getf64() + other.getf64());+ return standardizeNaN(getf64() + other.getf64()); case Type::v128: case Type::funcref: case Type::externref:@@ -868,9 +966,9 @@ case Type::i64: return Literal(uint64_t(i64) - uint64_t(other.i64)); case Type::f32:- return Literal(getf32() - other.getf32());+ return standardizeNaN(getf32() - other.getf32()); case Type::f64:- return Literal(getf64() - other.getf64());+ return standardizeNaN(getf64() - other.getf64()); case Type::v128: case Type::funcref: case Type::externref:@@ -963,9 +1061,9 @@ case Type::i64: return Literal(uint64_t(i64) * uint64_t(other.i64)); case Type::f32:- return Literal(getf32() * other.getf32());+ return standardizeNaN(getf32() * other.getf32()); case Type::f64:- return Literal(getf64() * other.getf64());+ return standardizeNaN(getf64() * other.getf64()); case Type::v128: case Type::funcref: case Type::externref:@@ -989,10 +1087,8 @@ case FP_ZERO: switch (std::fpclassify(lhs)) { case FP_NAN:- return Literal(setQuietNaN(lhs)); case FP_ZERO:- return Literal(- std::copysign(std::numeric_limits<float>::quiet_NaN(), sign));+ return standardizeNaN(lhs / rhs); case FP_NORMAL: // fallthrough case FP_SUBNORMAL: // fallthrough case FP_INFINITE:@@ -1005,7 +1101,7 @@ case FP_INFINITE: // fallthrough case FP_NORMAL: // fallthrough case FP_SUBNORMAL:- return Literal(lhs / rhs);+ return standardizeNaN(lhs / rhs); default: WASM_UNREACHABLE("invalid fp classification"); }@@ -1017,10 +1113,8 @@ case FP_ZERO: switch (std::fpclassify(lhs)) { case FP_NAN:- return Literal(setQuietNaN(lhs)); case FP_ZERO:- return Literal(- std::copysign(std::numeric_limits<double>::quiet_NaN(), sign));+ return standardizeNaN(lhs / rhs); case FP_NORMAL: // fallthrough case FP_SUBNORMAL: // fallthrough case FP_INFINITE:@@ -1033,7 +1127,7 @@ case FP_INFINITE: // fallthrough case FP_NORMAL: // fallthrough case FP_SUBNORMAL:- return Literal(lhs / rhs);+ return standardizeNaN(lhs / rhs); default: WASM_UNREACHABLE("invalid fp classification"); }@@ -1380,39 +1474,29 @@ switch (type.getBasic()) { case Type::f32: { auto l = getf32(), r = other.getf32();- if (l == r && l == 0) {- return Literal(std::signbit(l) ? l : r);+ if (std::isnan(l)) {+ return standardizeNaN(l); }- auto result = std::min(l, r);- bool lnan = std::isnan(l), rnan = std::isnan(r);- if (!std::isnan(result) && !lnan && !rnan) {- return Literal(result);+ if (std::isnan(r)) {+ return standardizeNaN(r); }- if (!lnan && !rnan) {- return Literal((int32_t)0x7fc00000).castToF32();+ if (l == r && l == 0) {+ return Literal(std::signbit(l) ? l : r); }- return Literal(lnan ? l : r)- .castToI32()- .or_(Literal(0xc00000))- .castToF32();+ return Literal(std::min(l, r)); } case Type::f64: { auto l = getf64(), r = other.getf64();- if (l == r && l == 0) {- return Literal(std::signbit(l) ? l : r);+ if (std::isnan(l)) {+ return standardizeNaN(l); }- auto result = std::min(l, r);- bool lnan = std::isnan(l), rnan = std::isnan(r);- if (!std::isnan(result) && !lnan && !rnan) {- return Literal(result);+ if (std::isnan(r)) {+ return standardizeNaN(r); }- if (!lnan && !rnan) {- return Literal((int64_t)0x7ff8000000000000LL).castToF64();+ if (l == r && l == 0) {+ return Literal(std::signbit(l) ? l : r); }- return Literal(lnan ? l : r)- .castToI64()- .or_(Literal(int64_t(0x8000000000000LL)))- .castToF64();+ return Literal(std::min(l, r)); } default: WASM_UNREACHABLE("unexpected type");@@ -1423,39 +1507,29 @@ switch (type.getBasic()) { case Type::f32: { auto l = getf32(), r = other.getf32();- if (l == r && l == 0) {- return Literal(std::signbit(l) ? r : l);+ if (std::isnan(l)) {+ return standardizeNaN(l); }- auto result = std::max(l, r);- bool lnan = std::isnan(l), rnan = std::isnan(r);- if (!std::isnan(result) && !lnan && !rnan) {- return Literal(result);+ if (std::isnan(r)) {+ return standardizeNaN(r); }- if (!lnan && !rnan) {- return Literal((int32_t)0x7fc00000).castToF32();+ if (l == r && l == 0) {+ return Literal(std::signbit(l) ? r : l); }- return Literal(lnan ? l : r)- .castToI32()- .or_(Literal(0xc00000))- .castToF32();+ return Literal(std::max(l, r)); } case Type::f64: { auto l = getf64(), r = other.getf64();- if (l == r && l == 0) {- return Literal(std::signbit(l) ? r : l);+ if (std::isnan(l)) {+ return standardizeNaN(l); }- auto result = std::max(l, r);- bool lnan = std::isnan(l), rnan = std::isnan(r);- if (!std::isnan(result) && !lnan && !rnan) {- return Literal(result);+ if (std::isnan(r)) {+ return standardizeNaN(r); }- if (!lnan && !rnan) {- return Literal((int64_t)0x7ff8000000000000LL).castToF64();+ if (l == r && l == 0) {+ return Literal(std::signbit(l) ? r : l); }- return Literal(lnan ? l : r)- .castToI64()- .or_(Literal(int64_t(0x8000000000000LL)))- .castToF64();+ return Literal(std::max(l, r)); } default: WASM_UNREACHABLE("unexpected type");@@ -1558,7 +1632,8 @@ return Literal(bytes); } -template<Type::BasicID Ty, int Lanes> static Literal splat(const Literal& val) {+template<Type::BasicType Ty, int Lanes>+static Literal splat(const Literal& val) { assert(val.type == Ty); LaneArray<Lanes> lanes; lanes.fill(val);@@ -1653,6 +1728,9 @@ Literal Literal::negI8x16() const { return unary<16, &Literal::getLanesUI8x16, &Literal::neg>(*this); }+Literal Literal::popcntI8x16() const {+ return unary<16, &Literal::getLanesUI8x16, &Literal::popCount>(*this);+} Literal Literal::negI16x8() const { return unary<8, &Literal::getLanesUI16x8, &Literal::neg>(*this); }@@ -1790,12 +1868,6 @@ Literal Literal::bitmaskI32x4() const { return bitmask<4, &Literal::getLanesI32x4>(*this); }-Literal Literal::anyTrueI64x2() const {- return any_true<2, &Literal::getLanesI64x2>(*this);-}-Literal Literal::allTrueI64x2() const {- return all_true<2, &Literal::getLanesI64x2>(*this);-} template<int Lanes, LaneArray<Lanes> (Literal::*IntoLanes)() const,@@ -1953,6 +2025,10 @@ Literal Literal::geUI32x4(const Literal& other) const { return compare<4, &Literal::getLanesI32x4, &Literal::geU>(*this, other); }+Literal Literal::eqI64x2(const Literal& other) const {+ return compare<2, &Literal::getLanesI64x2, &Literal::eq, int64_t>(*this,+ other);+} Literal Literal::eqF32x4(const Literal& other) const { return compare<4, &Literal::getLanesF32x4, &Literal::eq>(*this, other); }@@ -2097,6 +2173,9 @@ Literal Literal::avgrUI16x8(const Literal& other) const { return binary<8, &Literal::getLanesUI16x8, &Literal::avgrUInt>(*this, other); }+Literal Literal::q15MulrSatSI16x8(const Literal& other) const {+ WASM_UNREACHABLE("TODO: implement Q15 rounding, saturating multiplication");+} Literal Literal::addI32x4(const Literal& other) const { return binary<4, &Literal::getLanesI32x4, &Literal::add>(*this, other); }@@ -2274,6 +2353,43 @@ return widen<4, &Literal::getLanesUI16x8, LaneOrder::High>(*this); } +Literal Literal::extMulLowSI16x8(const Literal& other) const {+ WASM_UNREACHABLE("TODO: implement SIMD extending multiplications");+}+Literal Literal::extMulHighSI16x8(const Literal& other) const {+ WASM_UNREACHABLE("TODO: implement SIMD extending multiplications");+}+Literal Literal::extMulLowUI16x8(const Literal& other) const {+ WASM_UNREACHABLE("TODO: implement SIMD extending multiplications");+}+Literal Literal::extMulHighUI16x8(const Literal& other) const {+ WASM_UNREACHABLE("TODO: implement SIMD extending multiplications");+}+Literal Literal::extMulLowSI32x4(const Literal& other) const {+ WASM_UNREACHABLE("TODO: implement SIMD extending multiplications");+}+Literal Literal::extMulHighSI32x4(const Literal& other) const {+ WASM_UNREACHABLE("TODO: implement SIMD extending multiplications");+}+Literal Literal::extMulLowUI32x4(const Literal& other) const {+ WASM_UNREACHABLE("TODO: implement SIMD extending multiplications");+}+Literal Literal::extMulHighUI32x4(const Literal& other) const {+ WASM_UNREACHABLE("TODO: implement SIMD extending multiplications");+}+Literal Literal::extMulLowSI64x2(const Literal& other) const {+ WASM_UNREACHABLE("TODO: implement SIMD extending multiplications");+}+Literal Literal::extMulHighSI64x2(const Literal& other) const {+ WASM_UNREACHABLE("TODO: implement SIMD extending multiplications");+}+Literal Literal::extMulLowUI64x2(const Literal& other) const {+ WASM_UNREACHABLE("TODO: implement SIMD extending multiplications");+}+Literal Literal::extMulHighUI64x2(const Literal& other) const {+ WASM_UNREACHABLE("TODO: implement SIMD extending multiplications");+}+ Literal Literal::swizzleVec8x16(const Literal& other) const { auto lanes = getLanesUI8x16(); auto indices = other.getLanesUI8x16();@@ -2283,6 +2399,33 @@ result[i] = index >= 16 ? Literal(int32_t(0)) : lanes[index]; } return Literal(result);+}++bool Literal::isSubRtt(const Literal& other) const {+ assert(type.isRtt() && other.type.isRtt());+ // For this literal to be a sub-rtt of the other rtt, the supers must be a+ // superset. That is, if other is a->b->c then we should be a->b->c as well+ // with possibly ->d->.. added. The rttSupers array represents those chains,+ // but only the supers, which means the last item in the chain is simply the+ // type of the literal.+ const auto& supers = getRttSupers();+ const auto& otherSupers = other.getRttSupers();+ if (otherSupers.size() > supers.size()) {+ return false;+ }+ for (Index i = 0; i < otherSupers.size(); i++) {+ if (supers[i] != otherSupers[i]) {+ return false;+ }+ }+ // If we have more supers than other, compare that extra super. Otherwise,+ // we have the same amount of supers, and must be completely identical to+ // other.+ if (otherSupers.size() < supers.size()) {+ return other.type == supers[otherSupers.size()];+ } else {+ return other.type == type;+ } } } // namespace wasm
binaryen/src/wasm/wasm-binary.cpp view
@@ -31,7 +31,7 @@ void WasmBinaryWriter::prepare() { // Collect function types and their frequencies. Collect information in each // function in parallel, then merge.- ModuleUtils::collectSignatures(*wasm, types, typeIndices);+ ModuleUtils::collectHeapTypes(*wasm, types, typeIndices); importInfo = wasm::make_unique<ImportInfo>(*wasm); } @@ -215,14 +215,29 @@ auto start = startSection(BinaryConsts::Section::Type); o << U32LEB(types.size()); for (Index i = 0; i < types.size(); ++i) {- Signature& sig = types[i];- BYN_TRACE("write " << sig.params << " -> " << sig.results << std::endl);- o << S32LEB(BinaryConsts::EncodedType::Func);- for (auto& sigType : {sig.params, sig.results}) {- o << U32LEB(sigType.size());- for (const auto& type : sigType) {- o << binaryType(type);+ auto type = types[i];+ BYN_TRACE("write " << type << std::endl);+ if (type.isSignature()) {+ o << S32LEB(BinaryConsts::EncodedType::Func);+ auto sig = type.getSignature();+ for (auto& sigType : {sig.params, sig.results}) {+ o << U32LEB(sigType.size());+ for (const auto& type : sigType) {+ writeType(type);+ } }+ } else if (type.isStruct()) {+ o << S32LEB(BinaryConsts::EncodedType::Struct);+ auto fields = type.getStruct().fields;+ o << U32LEB(fields.size());+ for (const auto& field : fields) {+ writeField(field);+ }+ } else if (type.isArray()) {+ o << S32LEB(BinaryConsts::EncodedType::Array);+ writeField(type.getArray().element);+ } else {+ WASM_UNREACHABLE("TODO GC type writing"); } } finishSection(start);@@ -250,7 +265,7 @@ BYN_TRACE("write one global\n"); writeImportHeader(global); o << U32LEB(int32_t(ExternalKind::Global));- o << binaryType(global->type);+ writeType(global->type); o << U32LEB(global->mutable_); }); ModuleUtils::iterImportedEvents(*wasm, [&](Event* event) {@@ -389,7 +404,7 @@ BYN_TRACE("write one\n"); size_t i = 0; for (const auto& t : global->type) {- o << binaryType(t);+ writeType(t); o << U32LEB(global->mutable_); if (global->type.size() == 1) { writeExpression(global->init);@@ -490,9 +505,14 @@ return it->second; } -uint32_t WasmBinaryWriter::getTypeIndex(Signature sig) const {- auto it = typeIndices.find(sig);- assert(it != typeIndices.end());+uint32_t WasmBinaryWriter::getTypeIndex(HeapType type) const {+ auto it = typeIndices.find(type);+#ifndef NDEBUG+ if (it == typeIndices.end()) {+ std::cout << "Missing type: " << type << '\n';+ assert(0);+ }+#endif return it->second; } @@ -628,7 +648,7 @@ } // table names- if (wasm->table.exists && wasm->table.name.is()) {+ if (wasm->table.exists && wasm->table.hasExplicitName) { auto substart = startSubsection(BinaryConsts::UserSections::Subsection::NameTable); o << U32LEB(1) << U32LEB(0); // currently exactly 1 table at index 0@@ -637,7 +657,7 @@ } // memory names- if (wasm->memory.exists && wasm->memory.name.is()) {+ if (wasm->memory.exists && wasm->memory.hasExplicitName) { auto substart = startSubsection(BinaryConsts::UserSections::Subsection::NameMemory); o << U32LEB(1) << U32LEB(0); // currently exactly 1 memory at index 0@@ -650,7 +670,7 @@ std::vector<std::pair<Index, Global*>> globalsWithNames; Index checked = 0; auto check = [&](Global* curr) {- if (curr->name.is()) {+ if (curr->hasExplicitName) { globalsWithNames.push_back({checked, curr}); } checked++;@@ -670,7 +690,31 @@ } } - // TODO: label, type, element and data names+ // memory names+ if (wasm->memory.exists) {+ Index count = 0;+ for (auto& seg : wasm->memory.segments) {+ if (seg.name.is()) {+ count++;+ }+ }++ if (count) {+ auto substart =+ startSubsection(BinaryConsts::UserSections::Subsection::NameData);+ o << U32LEB(count);+ for (Index i = 0; i < wasm->memory.segments.size(); i++) {+ auto& seg = wasm->memory.segments[i];+ if (seg.name.is()) {+ o << U32LEB(i);+ writeEscapedName(seg.name.str);+ }+ }+ finishSubsection(substart);+ }+ }++ // TODO: label, type, and element names // see: https://github.com/WebAssembly/extended-name-section finishSection(start);@@ -799,6 +843,8 @@ return BinaryConsts::UserSections::GCFeature; case FeatureSet::Memory64: return BinaryConsts::UserSections::Memory64Feature;+ case FeatureSet::TypedFunctionReferences:+ return BinaryConsts::UserSections::TypedFunctionReferencesFeature; default: WASM_UNREACHABLE("unexpected feature flag"); }@@ -865,7 +911,6 @@ void WasmBinaryWriter::writeDebugLocationEnd(Expression* curr, Function* func) { if (func && !func->expressionLocations.empty()) { auto& span = binaryLocations.expressions.at(curr);- assert(span.end == 0); span.end = o.size(); } }@@ -951,6 +996,121 @@ } } +void WasmBinaryWriter::writeType(Type type) {+ if (type.isRef() && !type.isBasic()) {+ if (type.isNullable()) {+ o << S32LEB(BinaryConsts::EncodedType::nullable);+ } else {+ o << S32LEB(BinaryConsts::EncodedType::nonnullable);+ }+ writeHeapType(type.getHeapType());+ return;+ }+ if (type.isRtt()) {+ auto rtt = type.getRtt();+ if (rtt.hasDepth()) {+ o << S32LEB(BinaryConsts::EncodedType::rtt_n);+ o << U32LEB(rtt.depth);+ } else {+ o << S32LEB(BinaryConsts::EncodedType::rtt);+ }+ writeHeapType(rtt.heapType);+ return;+ }+ int ret = 0;+ TODO_SINGLE_COMPOUND(type);+ switch (type.getBasic()) {+ // None only used for block signatures. TODO: Separate out?+ case Type::none:+ ret = BinaryConsts::EncodedType::Empty;+ break;+ case Type::i32:+ ret = BinaryConsts::EncodedType::i32;+ break;+ case Type::i64:+ ret = BinaryConsts::EncodedType::i64;+ break;+ case Type::f32:+ ret = BinaryConsts::EncodedType::f32;+ break;+ case Type::f64:+ ret = BinaryConsts::EncodedType::f64;+ break;+ case Type::v128:+ ret = BinaryConsts::EncodedType::v128;+ break;+ case Type::funcref:+ ret = BinaryConsts::EncodedType::funcref;+ break;+ case Type::externref:+ ret = BinaryConsts::EncodedType::externref;+ break;+ case Type::exnref:+ ret = BinaryConsts::EncodedType::exnref;+ break;+ case Type::anyref:+ ret = BinaryConsts::EncodedType::anyref;+ break;+ case Type::eqref:+ ret = BinaryConsts::EncodedType::eqref;+ break;+ case Type::i31ref:+ ret = BinaryConsts::EncodedType::i31ref;+ break;+ default:+ WASM_UNREACHABLE("unexpected type");+ }+ o << S32LEB(ret);+}++void WasmBinaryWriter::writeHeapType(HeapType type) {+ if (type.isSignature() || type.isStruct() || type.isArray()) {+ o << S64LEB(getTypeIndex(type)); // TODO: Actually s33+ return;+ }+ int ret = 0;+ if (type.isBasic()) {+ switch (type.getBasic()) {+ case HeapType::func:+ ret = BinaryConsts::EncodedHeapType::func;+ break;+ case HeapType::ext:+ ret = BinaryConsts::EncodedHeapType::extern_;+ break;+ case HeapType::exn:+ ret = BinaryConsts::EncodedHeapType::exn;+ break;+ case HeapType::any:+ ret = BinaryConsts::EncodedHeapType::any;+ break;+ case HeapType::eq:+ ret = BinaryConsts::EncodedHeapType::eq;+ break;+ case HeapType::i31:+ ret = BinaryConsts::EncodedHeapType::i31;+ break;+ }+ } else {+ WASM_UNREACHABLE("TODO: compound GC types");+ }+ o << S64LEB(ret); // TODO: Actually s33+}++void WasmBinaryWriter::writeField(const Field& field) {+ if (field.type == Type::i32 && field.packedType != Field::not_packed) {+ if (field.packedType == Field::i8) {+ o << S32LEB(BinaryConsts::EncodedType::i8);+ } else if (field.packedType == Field::i16) {+ o << S32LEB(BinaryConsts::EncodedType::i16);+ } else {+ WASM_UNREACHABLE("invalid packed type");+ }+ } else {+ writeType(field.type);+ }+ o << U32LEB(field.mutable_);+}+ // reader bool WasmBinaryBuilder::hasDWARFSections() {@@ -1021,7 +1181,7 @@ readMemory(); break; case BinaryConsts::Section::Type:- readSignatures();+ readTypes(); break; case BinaryConsts::Section::Import: readImports();@@ -1216,17 +1376,17 @@ return ret.value; } -Type WasmBinaryBuilder::getType() {- int type = getS32LEB();+uint64_t WasmBinaryBuilder::getUPtrLEB() {+ return wasm.memory.is64() ? getU64LEB() : getU32LEB();+}++Type WasmBinaryBuilder::getType(int initial) { // Single value types are negative; signature indices are non-negative- if (type >= 0) {- // TODO: Handle block input types properly- if (size_t(type) >= signatures.size()) {- throwError("invalid signature index: " + std::to_string(type));- }- return signatures[type].results;+ if (initial >= 0) {+ // TODO: Handle block input types properly.+ return getSignatureByTypeIndex(initial).results; }- switch (type) {+ switch (initial) { // None only used for block signatures. TODO: Separate out? case BinaryConsts::EncodedType::Empty: return Type::none;@@ -1250,42 +1410,87 @@ return Type::anyref; case BinaryConsts::EncodedType::eqref: return Type::eqref;+ case BinaryConsts::EncodedType::nullable:+ return Type(getHeapType(), Nullable);+ case BinaryConsts::EncodedType::nonnullable:+ // FIXME: for now, force all inputs to be nullable+ return Type(getHeapType(), Nullable); case BinaryConsts::EncodedType::i31ref:- return Type::i31ref;+ // FIXME: for now, force all inputs to be nullable+ return Type(HeapType::BasicHeapType::i31, Nullable);+ case BinaryConsts::EncodedType::rtt_n: {+ auto depth = getU32LEB();+ auto heapType = getHeapType();+ return Type(Rtt(depth, heapType));+ }+ case BinaryConsts::EncodedType::rtt: {+ return Type(Rtt(getHeapType()));+ } default:- throwError("invalid wasm type: " + std::to_string(type));+ throwError("invalid wasm type: " + std::to_string(initial)); } WASM_UNREACHABLE("unexpected type"); } +Type WasmBinaryBuilder::getType() { return getType(getS32LEB()); }+ HeapType WasmBinaryBuilder::getHeapType() {- int type = getS32LEB(); // TODO: Actually encoded as s33+ auto type = getS64LEB(); // TODO: Actually s33 // Single heap types are negative; heap type indices are non-negative if (type >= 0) {- if (size_t(type) >= signatures.size()) {+ if (size_t(type) >= types.size()) { throwError("invalid signature index: " + std::to_string(type)); }- return HeapType(signatures[type]);+ return types[type]; } switch (type) { case BinaryConsts::EncodedHeapType::func:- return HeapType::FuncKind;+ return HeapType::func; case BinaryConsts::EncodedHeapType::extern_:- return HeapType::ExternKind;+ return HeapType::ext; case BinaryConsts::EncodedHeapType::exn:- return HeapType::ExnKind;+ return HeapType::exn; case BinaryConsts::EncodedHeapType::any:- return HeapType::AnyKind;+ return HeapType::any; case BinaryConsts::EncodedHeapType::eq:- return HeapType::EqKind;+ return HeapType::eq; case BinaryConsts::EncodedHeapType::i31:- return HeapType::I31Kind;+ return HeapType::i31; default: throwError("invalid wasm heap type: " + std::to_string(type)); } WASM_UNREACHABLE("unexpected type"); } +Mutability WasmBinaryBuilder::getMutability() {+ switch (getU32LEB()) {+ case 0:+ return Immutable;+ case 1:+ return Mutable;+ default:+ throw ParseException("Expected 0 or 1 for mutability");+ }+}++Field WasmBinaryBuilder::getField() {+ // The value may be a general wasm type, or one of the types only possible in+ // a field.+ auto initial = getS32LEB();+ if (initial == BinaryConsts::EncodedType::i8) {+ auto mutable_ = getMutability();+ return Field(Field::i8, mutable_);+ }+ if (initial == BinaryConsts::EncodedType::i16) {+ auto mutable_ = getMutability();+ return Field(Field::i16, mutable_);+ }+ // It's a regular wasm value.+ auto type = getType(initial);+ auto mutable_ = getMutability();+ return Field(type, mutable_);+}+ Type WasmBinaryBuilder::getConcreteType() { auto type = getType(); if (!type.isConcrete()) {@@ -1339,12 +1544,6 @@ } } -void WasmBinaryBuilder::ungetInt8() {- assert(pos > 0);- BYN_TRACE("ungetInt8 (at " << pos << ")\n");- pos--;-}- void WasmBinaryBuilder::readHeader() { BYN_TRACE("== readHeader\n"); verifyInt32(BinaryConsts::Magic);@@ -1376,29 +1575,40 @@ Memory::kUnlimitedSize); } -void WasmBinaryBuilder::readSignatures() {- BYN_TRACE("== readSignatures\n");+void WasmBinaryBuilder::readTypes() {+ BYN_TRACE("== readTypes\n"); size_t numTypes = getU32LEB(); BYN_TRACE("num: " << numTypes << std::endl); for (size_t i = 0; i < numTypes; i++) { BYN_TRACE("read one\n");- std::vector<Type> params;- std::vector<Type> results; auto form = getS32LEB();- if (form != BinaryConsts::EncodedType::Func) {- throwError("bad signature form " + std::to_string(form));- }- size_t numParams = getU32LEB();- BYN_TRACE("num params: " << numParams << std::endl);- for (size_t j = 0; j < numParams; j++) {- params.push_back(getConcreteType());- }- auto numResults = getU32LEB();- BYN_TRACE("num results: " << numResults << std::endl);- for (size_t j = 0; j < numResults; j++) {- results.push_back(getConcreteType());+ if (form == BinaryConsts::EncodedType::Func) {+ std::vector<Type> params;+ std::vector<Type> results;+ size_t numParams = getU32LEB();+ BYN_TRACE("num params: " << numParams << std::endl);+ for (size_t j = 0; j < numParams; j++) {+ params.push_back(getConcreteType());+ }+ auto numResults = getU32LEB();+ BYN_TRACE("num results: " << numResults << std::endl);+ for (size_t j = 0; j < numResults; j++) {+ results.push_back(getConcreteType());+ }+ types.emplace_back(Signature(Type(params), Type(results)));+ } else if (form == BinaryConsts::EncodedType::Struct) {+ FieldList fields;+ size_t numFields = getU32LEB();+ BYN_TRACE("num fields: " << numFields << std::endl);+ for (size_t j = 0; j < numFields; j++) {+ fields.push_back(getField());+ }+ types.emplace_back(Struct(fields));+ } else if (form == BinaryConsts::EncodedType::Array) {+ types.emplace_back(Array(getField()));+ } else {+ throwError("bad type form " + std::to_string(form)); }- signatures.emplace_back(Type(params), Type(results)); } } @@ -1450,6 +1660,11 @@ size_t num = getU32LEB(); BYN_TRACE("num: " << num << std::endl); Builder builder(wasm);+ size_t tableCounter = 0;+ size_t memoryCounter = 0;+ size_t functionCounter = 0;+ size_t globalCounter = 0;+ size_t eventCounter = 0; for (size_t i = 0; i < num; i++) { BYN_TRACE("read one\n"); auto module = getInlineString();@@ -1460,23 +1675,21 @@ // could occur later due to the names section. switch (kind) { case ExternalKind::Function: {- auto name = Name(std::string("fimport$") + std::to_string(i));+ Name name(std::string("fimport$") + std::to_string(functionCounter++)); auto index = getU32LEB();- if (index >= signatures.size()) {- throwError("invalid function index " + std::to_string(index) + " / " +- std::to_string(signatures.size()));- }- auto* curr = builder.makeFunction(name, signatures[index], {});+ auto curr =+ builder.makeFunction(name, getSignatureByTypeIndex(index), {}); curr->module = module; curr->base = base;- wasm.addFunction(curr);- functionImports.push_back(curr);+ functionImports.push_back(curr.get());+ wasm.addFunction(std::move(curr)); break; } case ExternalKind::Table: {+ Name name(std::string("timport$") + std::to_string(tableCounter++)); wasm.table.module = module; wasm.table.base = base;- wasm.table.name = Name(std::string("timport$") + std::to_string(i));+ wasm.table.name = name; auto elementType = getS32LEB(); WASM_UNUSED(elementType); if (elementType != BinaryConsts::EncodedType::funcref) {@@ -1499,9 +1712,10 @@ break; } case ExternalKind::Memory: {+ Name name(std::string("mimport$") + std::to_string(memoryCounter++)); wasm.memory.module = module; wasm.memory.base = base;- wasm.memory.name = Name(std::string("mimport$") + std::to_string(i));+ wasm.memory.name = name; wasm.memory.exists = true; getResizableLimits(wasm.memory.initial, wasm.memory.max,@@ -1511,32 +1725,29 @@ break; } case ExternalKind::Global: {- auto name = Name(std::string("gimport$") + std::to_string(i));+ Name name(std::string("gimport$") + std::to_string(globalCounter++)); auto type = getConcreteType(); auto mutable_ = getU32LEB();- auto* curr =+ auto curr = builder.makeGlobal(name, type, nullptr, mutable_ ? Builder::Mutable : Builder::Immutable); curr->module = module; curr->base = base;- wasm.addGlobal(curr);- globalImports.push_back(curr);+ globalImports.push_back(curr.get());+ wasm.addGlobal(std::move(curr)); break; } case ExternalKind::Event: {- auto name = Name(std::string("eimport$") + std::to_string(i));+ Name name(std::string("eimport$") + std::to_string(eventCounter++)); auto attribute = getU32LEB(); auto index = getU32LEB();- if (index >= signatures.size()) {- throwError("invalid event index " + std::to_string(index) + " / " +- std::to_string(signatures.size()));- }- auto* curr = builder.makeEvent(name, attribute, signatures[index]);+ auto curr =+ builder.makeEvent(name, attribute, getSignatureByTypeIndex(index)); curr->module = module; curr->base = base;- wasm.addEvent(curr);+ wasm.addEvent(std::move(curr)); break; } default: {@@ -1564,13 +1775,34 @@ for (size_t i = 0; i < num; i++) { BYN_TRACE("read one\n"); auto index = getU32LEB();- if (index >= signatures.size()) {- throwError("invalid function type index for function");- }- functionSignatures.push_back(signatures[index]);+ functionSignatures.push_back(getSignatureByTypeIndex(index)); } } +Signature WasmBinaryBuilder::getSignatureByFunctionIndex(Index index) {+ Signature sig;+ if (index < functionImports.size()) {+ return functionImports[index]->sig;+ }+ Index adjustedIndex = index - functionImports.size();+ if (adjustedIndex >= functionSignatures.size()) {+ throwError("invalid function index");+ }+ return functionSignatures[adjustedIndex];+}++Signature WasmBinaryBuilder::getSignatureByTypeIndex(Index index) {+ if (index >= types.size()) {+ throwError("invalid type index " + std::to_string(index) + " / " ++ std::to_string(types.size()));+ }+ auto heapType = types[index];+ if (!heapType.isSignature()) {+ throwError("invalid signature type " + heapType.toString());+ }+ return heapType.getSignature();+}+ void WasmBinaryBuilder::readFunctions() { BYN_TRACE("== readFunctions\n"); size_t total = getU32LEB();@@ -2055,8 +2287,8 @@ for (auto* func : functions) { wasm.addFunction(func); }- for (auto* global : globals) {- wasm.addGlobal(global);+ for (auto& global : globals) {+ wasm.addGlobal(std::move(global)); } // now that we have names, apply things@@ -2224,12 +2456,9 @@ BYN_TRACE("read one\n"); auto attribute = getU32LEB(); auto typeIndex = getU32LEB();- if (typeIndex >= signatures.size()) {- throwError("invalid event index " + std::to_string(typeIndex) + " / " +- std::to_string(signatures.size()));- }- wasm.addEvent(Builder::makeEvent(- "event$" + std::to_string(i), attribute, signatures[typeIndex]));+ wasm.addEvent(Builder::makeEvent("event$" + std::to_string(i),+ attribute,+ getSignatureByTypeIndex(typeIndex))); } } @@ -2294,9 +2523,9 @@ } auto numFunctionImports = functionImports.size(); if (index < numFunctionImports) {- functionImports[index]->name = name;+ functionImports[index]->setExplicitName(name); } else if (index - numFunctionImports < functions.size()) {- functions[index - numFunctionImports]->name = name;+ functions[index - numFunctionImports]->setExplicitName(name); } else { std::cerr << "warning: function index out of bounds in name section, " "function subsection: "@@ -2351,7 +2580,7 @@ auto index = getU32LEB(); auto rawName = getInlineString(); if (index == 0) {- wasm.table.name = escape(rawName);+ wasm.table.setExplicitName(escape(rawName)); } else { std::cerr << "warning: table index out of bounds in name section, " "table subsection: "@@ -2365,7 +2594,7 @@ auto index = getU32LEB(); auto rawName = getInlineString(); if (index == 0) {- wasm.memory.name = escape(rawName);+ wasm.memory.setExplicitName(escape(rawName)); } else { std::cerr << "warning: memory index out of bounds in name section, " "memory subsection: "@@ -2373,6 +2602,20 @@ << std::to_string(index) << std::endl; } }+ } else if (nameType == BinaryConsts::UserSections::Subsection::NameData) {+ auto num = getU32LEB();+ for (size_t i = 0; i < num; i++) {+ auto index = getU32LEB();+ auto rawName = getInlineString();+ if (index < wasm.memory.segments.size()) {+ wasm.memory.segments[i].name = rawName;+ } else {+ std::cerr << "warning: memory index out of bounds in name section, "+ "memory subsection: "+ << std::string(rawName.str) << " at index "+ << std::to_string(index) << std::endl;+ }+ } } else if (nameType == BinaryConsts::UserSections::Subsection::NameGlobal) { auto num = getU32LEB(); std::set<Name> usedNames;@@ -2387,9 +2630,9 @@ } auto numGlobalImports = globalImports.size(); if (index < numGlobalImports) {- globalImports[index]->name = name;+ globalImports[index]->setExplicitName(name); } else if (index - numGlobalImports < globals.size()) {- globals[index - numGlobalImports]->name = name;+ globals[index - numGlobalImports]->setExplicitName(name); } else { std::cerr << "warning: global index out of bounds in name section, " "global subsection: "@@ -2461,6 +2704,9 @@ wasm.features.setGC(); } else if (name == BinaryConsts::UserSections::Memory64Feature) { wasm.features.setMemory64();+ } else if (name ==+ BinaryConsts::UserSections::TypedFunctionReferencesFeature) {+ wasm.features.setTypedFunctionReferences(); } } }@@ -2573,7 +2819,12 @@ break; case BinaryConsts::End: curr = nullptr;- continueControlFlow(BinaryLocations::End, startPos);+ // Pop the current control flow structure off the stack. If there is none+ // then this is the "end" of the function itself, which also emits an+ // "end" byte.+ if (!controlFlowStack.empty()) {+ controlFlowStack.pop_back();+ } break; case BinaryConsts::Else: curr = nullptr;@@ -2625,6 +2876,16 @@ visitMemoryGrow(grow); break; }+ case BinaryConsts::CallRef:+ visitCallRef((curr = allocator.alloc<CallRef>())->cast<CallRef>());+ break;+ case BinaryConsts::RetCallRef: {+ auto call = allocator.alloc<CallRef>();+ call->isReturn = true;+ curr = call;+ visitCallRef(call);+ break;+ } case BinaryConsts::AtomicPrefix: { code = static_cast<uint8_t>(getU32LEB()); if (maybeVisitLoad(curr, code, /*isAtomic=*/true)) {@@ -2704,6 +2965,12 @@ if (maybeVisitSIMDLoad(curr, opcode)) { break; }+ if (maybeVisitSIMDLoadStoreLane(curr, opcode)) {+ break;+ }+ if (maybeVisitPrefetch(curr, opcode)) {+ break;+ } throwError("invalid code after SIMD prefix: " + std::to_string(opcode)); break; }@@ -2798,22 +3065,12 @@ void WasmBinaryBuilder::continueControlFlow(BinaryLocations::DelimiterId id, BinaryLocation pos) { if (DWARF && currFunction) {- if (controlFlowStack.empty()) {- // We reached the end of the function, which is also marked with an- // "end", like a control flow structure.- assert(id == BinaryLocations::End);- assert(pos + 1 == endOfFunction);- return;- } assert(!controlFlowStack.empty()); auto currControlFlow = controlFlowStack.back(); // We are called after parsing the byte, so we need to subtract one to // get its position. currFunction->delimiterLocations[currControlFlow][id] = pos - codeSectionLocation;- if (id == BinaryLocations::End) {- controlFlowStack.pop_back();- } } } @@ -2901,8 +3158,9 @@ } pushBlockElements(curr, curr->type, start); curr->finalize(curr->type,- breakTargetNames.find(curr->name) !=- breakTargetNames.end() /* hasBreak */);+ breakTargetNames.find(curr->name) != breakTargetNames.end()+ ? Block::HasBreak+ : Block::NoBreak); breakStack.pop_back(); breakTargetNames.erase(curr->name); }@@ -3034,17 +3292,7 @@ void WasmBinaryBuilder::visitCall(Call* curr) { BYN_TRACE("zz node: Call\n"); auto index = getU32LEB();- Signature sig;- if (index < functionImports.size()) {- auto* import = functionImports[index];- sig = import->sig;- } else {- Index adjustedIndex = index - functionImports.size();- if (adjustedIndex >= functionSignatures.size()) {- throwError("invalid call index");- }- sig = functionSignatures[adjustedIndex];- }+ auto sig = getSignatureByFunctionIndex(index); auto num = sig.params.size(); curr->operands.resize(num); for (size_t i = 0; i < num; i++) {@@ -3058,10 +3306,7 @@ void WasmBinaryBuilder::visitCallIndirect(CallIndirect* curr) { BYN_TRACE("zz node: CallIndirect\n"); auto index = getU32LEB();- if (index >= signatures.size()) {- throwError("bad call_indirect function index");- }- curr->sig = signatures[index];+ curr->sig = getSignatureByTypeIndex(index); auto reserved = getU32LEB(); if (reserved != 0) { throwError("Invalid flags field in call_indirect");@@ -3115,7 +3360,7 @@ if (adjustedIndex >= globals.size()) { throwError("invalid global index"); }- auto* glob = globals[adjustedIndex];+ auto& glob = globals[adjustedIndex]; curr->name = glob->name; curr->type = glob->type; }@@ -3146,92 +3391,96 @@ throwError("Alignment must be of a reasonable size"); } alignment = Bits::pow2(rawAlignment);- offset = getU32LEB();+ offset = getUPtrLEB(); } bool WasmBinaryBuilder::maybeVisitLoad(Expression*& out, uint8_t code, bool isAtomic) { Load* curr;+ auto allocate = [&]() {+ curr = allocator.alloc<Load>();+ // The signed field does not matter in some cases (where the size of the+ // load is equal to the size of the type, in which case we do not extend),+ // but give it a default value nonetheless, to make hashing and other code+ // simpler, so that they do not need to consider whether the sign matters or+ // not.+ curr->signed_ = false;+ }; if (!isAtomic) { switch (code) { case BinaryConsts::I32LoadMem8S:- curr = allocator.alloc<Load>();+ allocate(); curr->bytes = 1; curr->type = Type::i32; curr->signed_ = true; break; case BinaryConsts::I32LoadMem8U:- curr = allocator.alloc<Load>();+ allocate(); curr->bytes = 1; curr->type = Type::i32;- curr->signed_ = false; break; case BinaryConsts::I32LoadMem16S:- curr = allocator.alloc<Load>();+ allocate(); curr->bytes = 2; curr->type = Type::i32; curr->signed_ = true; break; case BinaryConsts::I32LoadMem16U:- curr = allocator.alloc<Load>();+ allocate(); curr->bytes = 2; curr->type = Type::i32;- curr->signed_ = false; break; case BinaryConsts::I32LoadMem:- curr = allocator.alloc<Load>();+ allocate(); curr->bytes = 4; curr->type = Type::i32; break; case BinaryConsts::I64LoadMem8S:- curr = allocator.alloc<Load>();+ allocate(); curr->bytes = 1; curr->type = Type::i64; curr->signed_ = true; break; case BinaryConsts::I64LoadMem8U:- curr = allocator.alloc<Load>();+ allocate(); curr->bytes = 1; curr->type = Type::i64;- curr->signed_ = false; break; case BinaryConsts::I64LoadMem16S:- curr = allocator.alloc<Load>();+ allocate(); curr->bytes = 2; curr->type = Type::i64; curr->signed_ = true; break; case BinaryConsts::I64LoadMem16U:- curr = allocator.alloc<Load>();+ allocate(); curr->bytes = 2; curr->type = Type::i64;- curr->signed_ = false; break; case BinaryConsts::I64LoadMem32S:- curr = allocator.alloc<Load>();+ allocate(); curr->bytes = 4; curr->type = Type::i64; curr->signed_ = true; break; case BinaryConsts::I64LoadMem32U:- curr = allocator.alloc<Load>();+ allocate(); curr->bytes = 4; curr->type = Type::i64;- curr->signed_ = false; break; case BinaryConsts::I64LoadMem:- curr = allocator.alloc<Load>();+ allocate(); curr->bytes = 8; curr->type = Type::i64; break; case BinaryConsts::F32LoadMem:- curr = allocator.alloc<Load>();+ allocate(); curr->bytes = 4; curr->type = Type::f32; break; case BinaryConsts::F64LoadMem:- curr = allocator.alloc<Load>();+ allocate(); curr->bytes = 8; curr->type = Type::f64; break;@@ -3242,44 +3491,43 @@ } else { switch (code) { case BinaryConsts::I32AtomicLoad8U:- curr = allocator.alloc<Load>();+ allocate(); curr->bytes = 1; curr->type = Type::i32; break; case BinaryConsts::I32AtomicLoad16U:- curr = allocator.alloc<Load>();+ allocate(); curr->bytes = 2; curr->type = Type::i32; break; case BinaryConsts::I32AtomicLoad:- curr = allocator.alloc<Load>();+ allocate(); curr->bytes = 4; curr->type = Type::i32; break; case BinaryConsts::I64AtomicLoad8U:- curr = allocator.alloc<Load>();+ allocate(); curr->bytes = 1; curr->type = Type::i64; break; case BinaryConsts::I64AtomicLoad16U:- curr = allocator.alloc<Load>();+ allocate(); curr->bytes = 2; curr->type = Type::i64; break; case BinaryConsts::I64AtomicLoad32U:- curr = allocator.alloc<Load>();+ allocate(); curr->bytes = 4; curr->type = Type::i64; break; case BinaryConsts::I64AtomicLoad:- curr = allocator.alloc<Load>();+ allocate(); curr->bytes = 8; curr->type = Type::i64; break; default: return false; }- curr->signed_ = false; BYN_TRACE("zz node: AtomicLoad\n"); } @@ -3406,7 +3654,7 @@ // Set curr to the given opcode, type and size. #define SET(opcode, optype, size) \- curr->op = opcode; \+ curr->op = RMW##opcode; \ curr->type = optype; \ curr->bytes = size @@ -4139,6 +4387,10 @@ curr = allocator.alloc<Binary>(); curr->op = GeUVecI32x4; break;+ case BinaryConsts::I64x2Eq:+ curr = allocator.alloc<Binary>();+ curr->op = EqVecI64x2;+ break; case BinaryConsts::F32x4Eq: curr = allocator.alloc<Binary>(); curr->op = EqVecF32x4;@@ -4299,6 +4551,26 @@ curr = allocator.alloc<Binary>(); curr->op = AvgrUVecI16x8; break;+ case BinaryConsts::I16x8Q15MulrSatS:+ curr = allocator.alloc<Binary>();+ curr->op = Q15MulrSatSVecI16x8;+ break;+ case BinaryConsts::I16x8ExtMulLowSI8x16:+ curr = allocator.alloc<Binary>();+ curr->op = ExtMulLowSVecI16x8;+ break;+ case BinaryConsts::I16x8ExtMulHighSI8x16:+ curr = allocator.alloc<Binary>();+ curr->op = ExtMulHighSVecI16x8;+ break;+ case BinaryConsts::I16x8ExtMulLowUI8x16:+ curr = allocator.alloc<Binary>();+ curr->op = ExtMulLowUVecI16x8;+ break;+ case BinaryConsts::I16x8ExtMulHighUI8x16:+ curr = allocator.alloc<Binary>();+ curr->op = ExtMulHighUVecI16x8;+ break; case BinaryConsts::I32x4Add: curr = allocator.alloc<Binary>(); curr->op = AddVecI32x4;@@ -4331,6 +4603,22 @@ curr = allocator.alloc<Binary>(); curr->op = DotSVecI16x8ToVecI32x4; break;+ case BinaryConsts::I32x4ExtMulLowSI16x8:+ curr = allocator.alloc<Binary>();+ curr->op = ExtMulLowSVecI32x4;+ break;+ case BinaryConsts::I32x4ExtMulHighSI16x8:+ curr = allocator.alloc<Binary>();+ curr->op = ExtMulHighSVecI32x4;+ break;+ case BinaryConsts::I32x4ExtMulLowUI16x8:+ curr = allocator.alloc<Binary>();+ curr->op = ExtMulLowUVecI32x4;+ break;+ case BinaryConsts::I32x4ExtMulHighUI16x8:+ curr = allocator.alloc<Binary>();+ curr->op = ExtMulHighUVecI32x4;+ break; case BinaryConsts::I64x2Add: curr = allocator.alloc<Binary>(); curr->op = AddVecI64x2;@@ -4343,6 +4631,22 @@ curr = allocator.alloc<Binary>(); curr->op = MulVecI64x2; break;+ case BinaryConsts::I64x2ExtMulLowSI32x4:+ curr = allocator.alloc<Binary>();+ curr->op = ExtMulLowSVecI64x2;+ break;+ case BinaryConsts::I64x2ExtMulHighSI32x4:+ curr = allocator.alloc<Binary>();+ curr->op = ExtMulHighSVecI64x2;+ break;+ case BinaryConsts::I64x2ExtMulLowUI32x4:+ curr = allocator.alloc<Binary>();+ curr->op = ExtMulLowUVecI64x2;+ break;+ case BinaryConsts::I64x2ExtMulHighUI32x4:+ curr = allocator.alloc<Binary>();+ curr->op = ExtMulHighUVecI64x2;+ break; case BinaryConsts::F32x4Add: curr = allocator.alloc<Binary>(); curr->op = AddVecF32x4;@@ -4468,6 +4772,10 @@ curr = allocator.alloc<Unary>(); curr->op = NotVec128; break;+ case BinaryConsts::I8x16Popcnt:+ curr = allocator.alloc<Unary>();+ curr->op = PopcntVecI8x16;+ break; case BinaryConsts::I8x16Abs: curr = allocator.alloc<Unary>(); curr->op = AbsVecI8x16;@@ -4532,13 +4840,9 @@ curr = allocator.alloc<Unary>(); curr->op = NegVecI64x2; break;- case BinaryConsts::I64x2AnyTrue:- curr = allocator.alloc<Unary>();- curr->op = AnyTrueVecI64x2;- break;- case BinaryConsts::I64x2AllTrue:+ case BinaryConsts::I64x2Bitmask: curr = allocator.alloc<Unary>();- curr->op = AllTrueVecI64x2;+ curr->op = BitmaskVecI64x2; break; case BinaryConsts::F32x4Abs: curr = allocator.alloc<Unary>();@@ -4596,6 +4900,22 @@ curr = allocator.alloc<Unary>(); curr->op = NearestVecF64x2; break;+ case BinaryConsts::I16x8ExtAddPairWiseSI8x16:+ curr = allocator.alloc<Unary>();+ curr->op = ExtAddPairwiseSVecI8x16ToI16x8;+ break;+ case BinaryConsts::I16x8ExtAddPairWiseUI8x16:+ curr = allocator.alloc<Unary>();+ curr->op = ExtAddPairwiseUVecI8x16ToI16x8;+ break;+ case BinaryConsts::I32x4ExtAddPairWiseSI16x8:+ curr = allocator.alloc<Unary>();+ curr->op = ExtAddPairwiseSVecI16x8ToI32x4;+ break;+ case BinaryConsts::I32x4ExtAddPairWiseUI16x8:+ curr = allocator.alloc<Unary>();+ curr->op = ExtAddPairwiseUVecI16x8ToI32x4;+ break; case BinaryConsts::I32x4TruncSatSF32x4: curr = allocator.alloc<Unary>(); curr->op = TruncSatSVecF32x4ToVecI32x4;@@ -4660,6 +4980,22 @@ curr = allocator.alloc<Unary>(); curr->op = WidenHighUVecI16x8ToVecI32x4; break;+ case BinaryConsts::I64x2WidenLowSI32x4:+ curr = allocator.alloc<Unary>();+ curr->op = WidenLowSVecI32x4ToVecI64x2;+ break;+ case BinaryConsts::I64x2WidenHighSI32x4:+ curr = allocator.alloc<Unary>();+ curr->op = WidenHighSVecI32x4ToVecI64x2;+ break;+ case BinaryConsts::I64x2WidenLowUI32x4:+ curr = allocator.alloc<Unary>();+ curr->op = WidenLowUVecI32x4ToVecI64x2;+ break;+ case BinaryConsts::I64x2WidenHighUI32x4:+ curr = allocator.alloc<Unary>();+ curr->op = WidenHighUVecI32x4ToVecI64x2;+ break; default: return false; }@@ -4813,6 +5149,22 @@ curr = allocator.alloc<SIMDTernary>(); curr->op = Bitselect; break;+ case BinaryConsts::V8x16SignSelect:+ curr = allocator.alloc<SIMDTernary>();+ curr->op = SignSelectVec8x16;+ break;+ case BinaryConsts::V16x8SignSelect:+ curr = allocator.alloc<SIMDTernary>();+ curr->op = SignSelectVec16x8;+ break;+ case BinaryConsts::V32x4SignSelect:+ curr = allocator.alloc<SIMDTernary>();+ curr->op = SignSelectVec32x4;+ break;+ case BinaryConsts::V64x2SignSelect:+ curr = allocator.alloc<SIMDTernary>();+ curr->op = SignSelectVec64x2;+ break; case BinaryConsts::F32x4QFMA: curr = allocator.alloc<SIMDTernary>(); curr->op = QFMAF32x4;@@ -4973,6 +5325,75 @@ return true; } +bool WasmBinaryBuilder::maybeVisitSIMDLoadStoreLane(Expression*& out,+ uint32_t code) {+ SIMDLoadStoreLaneOp op;+ size_t lanes;+ switch (code) {+ case BinaryConsts::V128Load8Lane:+ op = LoadLaneVec8x16;+ lanes = 16;+ break;+ case BinaryConsts::V128Load16Lane:+ op = LoadLaneVec16x8;+ lanes = 8;+ break;+ case BinaryConsts::V128Load32Lane:+ op = LoadLaneVec32x4;+ lanes = 4;+ break;+ case BinaryConsts::V128Load64Lane:+ op = LoadLaneVec64x2;+ lanes = 2;+ break;+ case BinaryConsts::V128Store8Lane:+ op = StoreLaneVec8x16;+ lanes = 16;+ break;+ case BinaryConsts::V128Store16Lane:+ op = StoreLaneVec16x8;+ lanes = 8;+ break;+ case BinaryConsts::V128Store32Lane:+ op = StoreLaneVec32x4;+ lanes = 4;+ break;+ case BinaryConsts::V128Store64Lane:+ op = StoreLaneVec64x2;+ lanes = 2;+ break;+ default:+ return false;+ }+ auto* curr = allocator.alloc<SIMDLoadStoreLane>();+ curr->op = op;+ readMemoryAccess(curr->align, curr->offset);+ curr->index = getLaneIndex(lanes);+ curr->vec = popNonVoidExpression();+ curr->ptr = popNonVoidExpression();+ curr->finalize();+ out = curr;+ return true;+}++bool WasmBinaryBuilder::maybeVisitPrefetch(Expression*& out, uint32_t code) {+ PrefetchOp op;+ switch (code) {+ case BinaryConsts::PrefetchT:+ op = PrefetchTemporal;+ break;+ case BinaryConsts::PrefetchNT:+ op = PrefetchNontemporal;+ break;+ default:+ return false;+ }+ Address align, offset;+ readMemoryAccess(align, offset);+ out = Builder(wasm).makePrefetch(op, offset, align, popNonVoidExpression());+ return true;+}+ void WasmBinaryBuilder::visitSelect(Select* curr, uint8_t code) { BYN_TRACE("zz node: Select, code " << int32_t(code) << std::endl); if (code == BinaryConsts::SelectWithType) {@@ -5051,7 +5472,10 @@ throwError("ref.func: invalid call index"); } functionRefs[index].push_back(curr); // we don't know function names yet- curr->finalize();+ // To support typed function refs, we give the reference not just a general+ // funcref, but a specific subtype with the actual signature.+ // FIXME: for now, emit a nullable type here+ curr->finalize(Type(HeapType(getSignatureByFunctionIndex(index)), Nullable)); } void WasmBinaryBuilder::visitRefEq(RefEq* curr) {@@ -5195,6 +5619,32 @@ curr->finalize(); } +void WasmBinaryBuilder::visitCallRef(CallRef* curr) {+ BYN_TRACE("zz node: CallRef\n");+ curr->target = popNonVoidExpression();+ auto type = curr->target->type;+ if (type == Type::unreachable) {+ // If our input is unreachable, then we cannot even find out how many inputs+ // we have, and just set ourselves to unreachable as well.+ curr->finalize(type);+ return;+ }+ if (!type.isRef()) {+ throwError("Non-ref type for a call_ref: " + type.toString());+ }+ auto heapType = type.getHeapType();+ if (!heapType.isSignature()) {+ throwError("Invalid reference type for a call_ref: " + type.toString());+ }+ auto sig = heapType.getSignature();+ auto num = sig.params.size();+ curr->operands.resize(num);+ for (size_t i = 0; i < num; i++) {+ curr->operands[num - i - 1] = popNonVoidExpression();+ }+ curr->finalize(sig.results);+}+ bool WasmBinaryBuilder::maybeVisitI31New(Expression*& out, uint32_t code) { if (code != BinaryConsts::I31New) { return false;@@ -5230,10 +5680,13 @@ if (code != BinaryConsts::RefTest) { return false; }- auto* curr = allocator.alloc<RefTest>();- WASM_UNREACHABLE("TODO (gc): ref.test");- curr->finalize();- out = curr;+ auto heapType1 = getHeapType();+ auto heapType2 = getHeapType();+ auto* ref = popNonVoidExpression();+ validateHeapTypeUsingChild(ref, heapType1);+ auto* rtt = popNonVoidExpression();+ validateHeapTypeUsingChild(rtt, heapType2);+ out = Builder(wasm).makeRefTest(ref, rtt); return true; } @@ -5241,10 +5694,13 @@ if (code != BinaryConsts::RefCast) { return false; }- auto* curr = allocator.alloc<RefCast>();- WASM_UNREACHABLE("TODO (gc): ref.cast");- curr->finalize();- out = curr;+ auto heapType1 = getHeapType();+ auto heapType2 = getHeapType();+ auto* ref = popNonVoidExpression();+ validateHeapTypeUsingChild(ref, heapType1);+ auto* rtt = popNonVoidExpression();+ validateHeapTypeUsingChild(rtt, heapType2);+ out = Builder(wasm).makeRefCast(ref, rtt); return true; } @@ -5252,10 +5708,14 @@ if (code != BinaryConsts::BrOnCast) { return false; }- auto* curr = allocator.alloc<BrOnCast>();- WASM_UNREACHABLE("TODO (gc): br_on_cast");- curr->finalize();- out = curr;+ auto name = getBreakTarget(getU32LEB()).name;+ auto heapType1 = getHeapType();+ auto heapType2 = getHeapType();+ auto* ref = popNonVoidExpression();+ validateHeapTypeUsingChild(ref, heapType1);+ auto* rtt = popNonVoidExpression();+ validateHeapTypeUsingChild(rtt, heapType2);+ out = Builder(wasm).makeBrOnCast(name, heapType2, ref, rtt); return true; } @@ -5263,10 +5723,8 @@ if (code != BinaryConsts::RttCanon) { return false; }- auto* curr = allocator.alloc<RttCanon>();- WASM_UNREACHABLE("TODO (gc): rtt.canon");- curr->finalize();- out = curr;+ auto heapType = getHeapType();+ out = Builder(wasm).makeRttCanon(heapType); return true; } @@ -5274,30 +5732,31 @@ if (code != BinaryConsts::RttSub) { return false; }- auto* curr = allocator.alloc<RttSub>();- WASM_UNREACHABLE("TODO (gc): rtt.sub");- curr->finalize();- out = curr;+ // FIXME: the binary format may also have an extra heap type and index that+ // are not needed+ auto heapType = getHeapType();+ auto* parent = popNonVoidExpression();+ out = Builder(wasm).makeRttSub(heapType, parent); return true; } bool WasmBinaryBuilder::maybeVisitStructNew(Expression*& out, uint32_t code) {- StructNew* curr;- switch (code) {- case BinaryConsts::StructNewWithRtt:- curr = allocator.alloc<StructNew>();- // ...- break;- case BinaryConsts::StructNewDefaultWithRtt:- curr = allocator.alloc<StructNew>();- // ...- break;- default:- return false;+ if (code != BinaryConsts::StructNewWithRtt &&+ code != BinaryConsts::StructNewDefaultWithRtt) {+ return false; }- WASM_UNREACHABLE("TODO (gc): struct.new");- curr->finalize();- out = curr;+ auto heapType = getHeapType();+ auto* rtt = popNonVoidExpression();+ validateHeapTypeUsingChild(rtt, heapType);+ std::vector<Expression*> operands;+ if (code == BinaryConsts::StructNewWithRtt) {+ auto numOperands = heapType.getStruct().fields.size();+ operands.resize(numOperands);+ for (Index i = 0; i < numOperands; i++) {+ operands[numOperands - i - 1] = popNonVoidExpression();+ }+ }+ out = Builder(wasm).makeStructNew(rtt, operands); return true; } @@ -5306,20 +5765,22 @@ switch (code) { case BinaryConsts::StructGet: curr = allocator.alloc<StructGet>();- // ... break; case BinaryConsts::StructGetS: curr = allocator.alloc<StructGet>();- // ...+ curr->signed_ = true; break; case BinaryConsts::StructGetU: curr = allocator.alloc<StructGet>();- // ...+ curr->signed_ = false; break; default: return false; }- WASM_UNREACHABLE("TODO (gc): struct.get");+ auto heapType = getHeapType();+ curr->index = getU32LEB();+ curr->ref = popNonVoidExpression();+ validateHeapTypeUsingChild(curr->ref, heapType); curr->finalize(); out = curr; return true;@@ -5330,53 +5791,50 @@ return false; } auto* curr = allocator.alloc<StructSet>();- WASM_UNREACHABLE("TODO (gc): struct.set");+ auto heapType = getHeapType();+ curr->index = getU32LEB();+ curr->ref = popNonVoidExpression();+ validateHeapTypeUsingChild(curr->ref, heapType);+ curr->value = popNonVoidExpression(); curr->finalize(); out = curr; return true; } bool WasmBinaryBuilder::maybeVisitArrayNew(Expression*& out, uint32_t code) {- ArrayNew* curr;- switch (code) {- case BinaryConsts::ArrayNewWithRtt:- curr = allocator.alloc<ArrayNew>();- // ...- break;- case BinaryConsts::ArrayNewDefaultWithRtt:- curr = allocator.alloc<ArrayNew>();- // ...- break;- default:- return false;+ if (code != BinaryConsts::ArrayNewWithRtt &&+ code != BinaryConsts::ArrayNewDefaultWithRtt) {+ return false; }- WASM_UNREACHABLE("TODO (gc): array.new");- curr->finalize();- out = curr;+ auto heapType = getHeapType();+ auto* rtt = popNonVoidExpression();+ validateHeapTypeUsingChild(rtt, heapType);+ auto* size = popNonVoidExpression();+ Expression* init = nullptr;+ if (code == BinaryConsts::ArrayNewWithRtt) {+ init = popNonVoidExpression();+ }+ out = Builder(wasm).makeArrayNew(rtt, size, init); return true; } bool WasmBinaryBuilder::maybeVisitArrayGet(Expression*& out, uint32_t code) {- ArrayGet* curr;+ bool signed_ = false; switch (code) { case BinaryConsts::ArrayGet:- curr = allocator.alloc<ArrayGet>();- // ...+ case BinaryConsts::ArrayGetU: break; case BinaryConsts::ArrayGetS:- curr = allocator.alloc<ArrayGet>();- // ...- break;- case BinaryConsts::ArrayGetU:- curr = allocator.alloc<ArrayGet>();- // ...+ signed_ = true; break; default: return false; }- WASM_UNREACHABLE("TODO (gc): array.get");- curr->finalize();- out = curr;+ auto heapType = getHeapType();+ auto* ref = popNonVoidExpression();+ validateHeapTypeUsingChild(ref, heapType);+ auto* index = popNonVoidExpression();+ out = Builder(wasm).makeArrayGet(ref, index, signed_); return true; } @@ -5384,10 +5842,12 @@ if (code != BinaryConsts::ArraySet) { return false; }- auto* curr = allocator.alloc<ArraySet>();- WASM_UNREACHABLE("TODO (gc): array.set");- curr->finalize();- out = curr;+ auto heapType = getHeapType();+ auto* ref = popNonVoidExpression();+ validateHeapTypeUsingChild(ref, heapType);+ auto* index = popNonVoidExpression();+ auto* value = popNonVoidExpression();+ out = Builder(wasm).makeArraySet(ref, index, value); return true; } @@ -5395,15 +5855,27 @@ if (code != BinaryConsts::ArrayLen) { return false; }- auto* curr = allocator.alloc<ArrayLen>();- WASM_UNREACHABLE("TODO (gc): array.len");- curr->finalize();- out = curr;+ auto heapType = getHeapType();+ auto* ref = popNonVoidExpression();+ validateHeapTypeUsingChild(ref, heapType);+ out = Builder(wasm).makeArrayLen(ref); return true; } void WasmBinaryBuilder::throwError(std::string text) { throw ParseException(text, 0, pos);+}++void WasmBinaryBuilder::validateHeapTypeUsingChild(Expression* child,+ HeapType heapType) {+ if (child->type == Type::unreachable) {+ return;+ }+ if ((!child->type.isRef() && !child->type.isRtt()) ||+ child->type.getHeapType() != heapType) {+ throwError("bad heap type: expected " + heapType.toString() ++ " but found " + child->type.toString());+ } } } // namespace wasm
binaryen/src/wasm/wasm-debug.cpp view
@@ -635,6 +635,17 @@ } }; +// A tombstone value is a value that is placed where something used to exist,+// but no longer does, like a reference to a function that was DCE'd out during+// linking. In theory the value can be any invalid location, and tools will+// basically ignore it.+// Earlier LLVM used to use 0 there, and newer versions use -1 or -2 depending+// on the DWARF section. For now, support them all, but TODO stop supporting 0,+// as there are apparently some possible corner cases where 0 is a valid value.+static bool isTombstone(uint32_t x) {+ return x == 0 || x == uint32_t(-1) || x == uint32_t(-2);+}+ // Update debug lines, and update the locationUpdater with debug line offset // changes so we can update offsets into the debug line section. static void updateDebugLines(llvm::DWARFYAML::Data& data,@@ -656,7 +667,7 @@ omittingRange = false; } if (state.update(opcode, table)) {- if (state.addr == 0) {+ if (isTombstone(state.addr)) { omittingRange = true; } if (omittingRange) {@@ -680,6 +691,8 @@ newAddr = locationUpdater.getNewFuncStart(oldAddr); } else if (locationUpdater.hasOldDelimiter(oldAddr)) { newAddr = locationUpdater.getNewDelimiter(oldAddr);+ } else if (locationUpdater.hasOldExprEnd(oldAddr)) {+ newAddr = locationUpdater.getNewExprEnd(oldAddr); } if (newAddr && state.needToEmit()) { // LLVM sometimes emits the same address more than once. We should@@ -851,7 +864,8 @@ static void updateCompileUnits(const BinaryenDWARFInfo& info, llvm::DWARFYAML::Data& yaml,- LocationUpdater& locationUpdater) {+ LocationUpdater& locationUpdater,+ bool is64) { // The context has the high-level information we need, and the YAML is where // we write changes. First, iterate over the compile units. size_t compileUnitIndex = 0;@@ -860,6 +874,13 @@ yaml.CompileUnits, [&](const std::unique_ptr<llvm::DWARFUnit>& CU, llvm::DWARFYAML::Unit& yamlUnit) {+ // Our Memory64Lowering pass may change the "architecture" of the DWARF+ // data. AddrSize will cause all DW_AT_low_pc to be written as 32/64-bit.+ auto NewAddrSize = is64 ? 8 : 4;+ if (NewAddrSize != yamlUnit.AddrSize) {+ yamlUnit.AddrSize = NewAddrSize;+ yamlUnit.AddrSizeChanged = true;+ } // Process the DIEs in each compile unit. iterContextAndYAML( CU->dies(),@@ -891,14 +912,14 @@ // If this is an end marker (0, 0), or an invalid range (0, x) or (x, 0) // then just emit it as it is - either to mark the end, or to mark an // invalid entry.- if (oldStart == 0 || oldEnd == 0) {+ if (isTombstone(oldStart) || isTombstone(oldEnd)) { newStart = oldStart; newEnd = oldEnd; } else { // This was a valid entry; update it. newStart = locationUpdater.getNewStart(oldStart); newEnd = locationUpdater.getNewEnd(oldEnd);- if (newStart == 0 || newEnd == 0) {+ if (isTombstone(newStart) || isTombstone(newEnd)) { // This part of the range no longer has a mapping, so we must skip it. // Don't use (0, 0) as that would be an end marker; emit something // invalid for the debugger to ignore.@@ -925,7 +946,7 @@ } static bool isEndMarkerLoc(const llvm::DWARFYAML::Loc& loc) {- return loc.Start == 0 && loc.End == 0;+ return isTombstone(loc.Start) && isTombstone(loc.End); } // Update the .debug_loc section.@@ -1037,7 +1058,7 @@ updateDebugLines(data, locationUpdater); - updateCompileUnits(info, data, locationUpdater);+ updateCompileUnits(info, data, locationUpdater, wasm.memory.is64()); updateRanges(data, locationUpdater);
binaryen/src/wasm/wasm-emscripten.cpp view
@@ -38,7 +38,6 @@ cashew::IString EM_JS_PREFIX("__em_js__"); static Name STACK_INIT("stack$init");-static Name POST_INSTANTIATE("__post_instantiate"); void addExportedFunction(Module& wasm, Function* function) { wasm.addFunction(function);@@ -75,73 +74,6 @@ return nullptr; } -// For emscripten SIDE_MODULE we generate a single exported function called-// __post_instantiate which calls two functions:-//-// - __assign_got_enties-// - __wasm_call_ctors-//-// The former is function we generate here which calls imported g$XXX functions-// order to assign values to any globals imported from GOT.func or GOT.mem.-// These globals hold address of functions and globals respectively.-//-// The later is the constructor function generaed by lld which performs any-// fixups on the memory section and calls static constructors.-void EmscriptenGlueGenerator::generatePostInstantiateFunction() {- BYN_TRACE("generatePostInstantiateFunction\n");- Builder builder(wasm);- Function* post_instantiate = builder.makeFunction(- POST_INSTANTIATE, std::vector<NameType>{}, Type::none, {});- wasm.addFunction(post_instantiate);-- if (Function* F = wasm.getFunctionOrNull(ASSIGN_GOT_ENTRIES)) {- // call __assign_got_enties from post_instantiate- Expression* call = builder.makeCall(F->name, {}, Type::none);- post_instantiate->body = builder.blockify(post_instantiate->body, call);- }-- // The names of standard imports/exports used by lld doesn't quite match that- // expected by emscripten.- // TODO(sbc): Unify these- if (auto* e = wasm.getExportOrNull(WASM_CALL_CTORS)) {- Expression* call = builder.makeCall(e->value, {}, Type::none);- post_instantiate->body = builder.blockify(post_instantiate->body, call);- wasm.removeExport(WASM_CALL_CTORS);- }-- auto* ex = new Export();- ex->value = post_instantiate->name;- ex->name = POST_INSTANTIATE;- ex->kind = ExternalKind::Function;- wasm.addExport(ex);-}--// lld can sometimes produce a build with an imported mutable __stack_pointer-// (i.e. when linking with -fpie). This method internalizes the-// __stack_pointer and initializes it from an immutable global instead.-// For -shared builds we instead call replaceStackPointerGlobal.-void EmscriptenGlueGenerator::internalizeStackPointerGlobal() {- Global* stackPointer = getStackPointerGlobal(wasm);- if (!stackPointer || !stackPointer->imported() || !stackPointer->mutable_) {- return;- }-- Name internalName = stackPointer->name;- Name externalName = internalName.c_str() + std::string("_import");-- // Rename the imported global, and make it immutable- stackPointer->name = externalName;- stackPointer->mutable_ = false;- wasm.updateMaps();-- // Create a new global with the old name that is not imported.- Builder builder(wasm);- auto* init = builder.makeGlobalGet(externalName, stackPointer->type);- auto* sp = builder.makeGlobal(- internalName, stackPointer->type, init, Builder::Mutable);- wasm.addGlobal(sp);-}- const Address UNKNOWN_OFFSET(uint32_t(-1)); std::vector<Address> getSegmentOffsets(Module& wasm) {@@ -153,9 +85,19 @@ OffsetSearcher(std::unordered_map<unsigned, Address>& offsets) : offsets(offsets) {} void visitMemoryInit(MemoryInit* curr) {+ // The desitination of the memory.init is either a constant+ // or the result of an addition with __memory_base in the+ // case of PIC code. auto* dest = curr->dest->dynCast<Const>(); if (!dest) {- return;+ auto* add = curr->dest->dynCast<Binary>();+ if (!add) {+ return;+ }+ dest = add->left->dynCast<Const>();+ if (!dest) {+ return;+ } } auto it = offsets.find(curr->segment); if (it != offsets.end()) {@@ -235,12 +177,10 @@ std::string codeForConstAddr(Module& wasm, std::vector<Address> const& segmentOffsets,- int32_t address) {+ int64_t address) { const char* str = stringAtAddr(wasm, segmentOffsets, address); if (!str) {- // If we can't find the segment corresponding with the address, then we- // omitted the segment and the address points to an empty string.- return escape("");+ Fatal() << "unable to find data for ASM/EM_JS const at: " << address; } return escape(str); }@@ -292,10 +232,9 @@ void process(); private:- void createAsmConst(uint32_t id, std::string code, Signature sig, Name name);+ void createAsmConst(uint64_t id, std::string code, Signature sig, Name name); Signature asmConstSig(Signature baseSig); Name nameForImportWithSig(Signature sig, Proxying proxy);- void queueImport(Name importName, Signature baseSig); void addImports(); Proxying proxyType(Name name); @@ -352,7 +291,7 @@ } if (auto* bin = arg->dynCast<Binary>()) {- if (bin->op == AddInt32) {+ if (bin->op == AddInt32 || bin->op == AddInt64) { // In the dynamic linking case the address of the string constant // is the result of adding its offset to __memory_base. // In this case are only looking for the offset from __memory_base@@ -362,12 +301,21 @@ } } + if (auto* unary = arg->dynCast<Unary>()) {+ if (unary->op == WrapInt64) {+ // This cast may be inserted around the string constant in the+ // Memory64Lowering pass.+ arg = unary->value;+ continue;+ }+ }+ Fatal() << "Unexpected arg0 type (" << getExpressionName(arg) << ") in call to: " << importName; } auto* value = arg->cast<Const>();- int32_t address = value->value.geti32();+ int64_t address = value->value.getInteger(); auto code = codeForConstAddr(wasm, segmentOffsets, address); createAsmConst(address, code, sig, importName); }@@ -389,7 +337,7 @@ addImports(); } -void AsmConstWalker::createAsmConst(uint32_t id,+void AsmConstWalker::createAsmConst(uint64_t id, std::string code, Signature sig, Name name) {@@ -410,21 +358,6 @@ baseSig.results); } -Name AsmConstWalker::nameForImportWithSig(Signature sig, Proxying proxy) {- std::string fixedTarget = EM_ASM_PREFIX.str + std::string("_") +- proxyingSuffix(proxy) +- getSig(sig.results, sig.params);- return Name(fixedTarget.c_str());-}--void AsmConstWalker::queueImport(Name importName, Signature baseSig) {- auto import = new Function;- import->name = import->base = importName;- import->module = ENV;- import->sig = baseSig;- queuedImports.push_back(std::unique_ptr<Function>(import));-}- void AsmConstWalker::addImports() { for (auto& import : queuedImports) { wasm.addFunction(import.release());@@ -464,7 +397,7 @@ Fatal() << "Unexpected generated __em_js__ function body: " << curr->name; } auto* addrConst = consts.list[0];- int32_t address = addrConst->value.geti32();+ int64_t address = addrConst->value.getInteger(); auto code = codeForConstAddr(wasm, segmentOffsets, address); codeByName[funcName] = code; }@@ -501,8 +434,8 @@ o << "]"; } -std::string EmscriptenGlueGenerator::generateEmscriptenMetadata(- Address staticBump, std::vector<Name> const& initializerFunctions) {+std::string+EmscriptenGlueGenerator::generateEmscriptenMetadata(Name initializer) { bool commaFirst; auto nextElement = [&commaFirst]() { if (commaFirst) {@@ -547,16 +480,11 @@ meta << "\n },\n"; } - meta << " \"staticBump\": " << staticBump << ",\n"; meta << " \"tableSize\": " << wasm.table.initial.addr << ",\n"; - if (!initializerFunctions.empty()) {+ if (initializer.is()) { meta << " \"initializers\": [";- commaFirst = true;- for (const auto& func : initializerFunctions) {- meta << nextElement();- meta << "\"" << func.c_str() << "\"";- }+ meta << "\n \"" << initializer.c_str() << "\""; meta << "\n ],\n"; }
binaryen/src/wasm/wasm-io.cpp view
@@ -121,7 +121,7 @@ #define DEBUG_TYPE "writer" void ModuleWriter::writeText(Module& wasm, Output& output) {- WasmPrinter::printModule(&wasm, output.getStream());+ output.getStream() << wasm; } void ModuleWriter::writeText(Module& wasm, std::string filename) {
binaryen/src/wasm/wasm-s-parser.cpp view
@@ -20,11 +20,11 @@ #include <cmath> #include <limits> -#include "asm_v_wasm.h"-#include "asmjs/shared-constants.h" #include "ir/branch-utils.h" #include "shared-constants.h"+#include "support/string.h" #include "wasm-binary.h"+#include "wasm-builder.h" #define abort_on(str) \ { throw ParseException(std::string("abort_on ") + str); }@@ -50,6 +50,9 @@ namespace wasm { +static Name STRUCT("struct"), FIELD("field"), ARRAY("array"), I8("i8"),+ I16("i16"), RTT("rtt");+ static Address getAddress(const Element* s) { return atoll(s->c_str()); } static void@@ -63,6 +66,10 @@ return s.isList() && s.size() > 0 && s[0]->isStr() && s[0]->str() == str; } +static bool elementStartsWith(Element* s, IString str) {+ return elementStartsWith(*s, str);+}+ Element::List& Element::list() { if (!isList()) { throw ParseException("expected list", line, col);@@ -451,25 +458,6 @@ } } -Signature SExpressionWasmBuilder::getFunctionSignature(Element& s) {- if (s.dollared()) {- auto it = signatureIndices.find(s.str().str);- if (it == signatureIndices.end()) {- throw ParseException(- "unknown function type in getFunctionSignature", s.line, s.col);- }- return signatures[it->second];- } else {- // index- size_t offset = atoi(s.str().c_str());- if (offset >= signatures.size()) {- throw ParseException(- "unknown function type in getFunctionSignature", s.line, s.col);- }- return signatures[offset];- }-}- Name SExpressionWasmBuilder::getGlobalName(Element& s) { if (s.dollared()) { return s.str();@@ -538,14 +526,10 @@ } localIndex++; Type type;- if (s[i]->isStr()) {- type = stringToType(s[i]->str());- } else {- if (elementStartsWith(s, PARAM)) {- throw ParseException(- "params may not have tuple types", s[i]->line, s[i]->col);- }- type = elementToType(*s[i]);+ type = elementToType(*s[i]);+ if (elementStartsWith(s, PARAM) && type.isTuple()) {+ throw ParseException(+ "params may not have tuple types", s[i]->line, s[i]->col); } namedParams.emplace_back(name, type); }@@ -557,7 +541,7 @@ assert(elementStartsWith(s, RESULT)); std::vector<Type> types; for (size_t i = 1; i < s.size(); i++) {- types.push_back(stringToType(s[i]->str()));+ types.push_back(elementToType(*s[i])); } return types; }@@ -570,7 +554,11 @@ if (s.size() != 2) { throw ParseException("invalid type reference", s.line, s.col); }- return getFunctionSignature(*s[1]);+ auto heapType = parseHeapType(*s[1]);+ if (!heapType.isSignature()) {+ throw ParseException("expected signature type", s.line, s.col);+ }+ return heapType.getSignature(); } // Prases typeuse, a reference to a type definition. It is in the form of either@@ -632,9 +620,9 @@ } // Add implicitly defined type to global list so it has an index- if (std::find(signatures.begin(), signatures.end(), functionSignature) ==- signatures.end()) {- signatures.push_back(functionSignature);+ auto heapType = HeapType(functionSignature);+ if (std::find(types.begin(), types.end(), heapType) == types.end()) {+ types.push_back(heapType); } // If only (type) is specified, populate `namedParams`@@ -675,7 +663,7 @@ functionCounter++; Signature sig; parseTypeUse(s, i, sig);- functionTypes[name] = sig.results;+ functionSignatures[name] = sig; } size_t SExpressionWasmBuilder::parseFunctionNames(Element& s,@@ -714,6 +702,7 @@ Name name, exportName; size_t i = parseFunctionNames(s, name, exportName);+ bool hasExplicitName = name.is(); if (!preParseImport) { if (!name.is()) { // unnamed, use an index@@ -762,11 +751,11 @@ throw ParseException("!preParseImport in func", s.line, s.col); } auto im = make_unique<Function>();- im->name = name;+ im->setName(name, hasExplicitName); im->module = importModule; im->base = importBase; im->sig = sig;- functionTypes[name] = sig.results;+ functionSignatures[name] = sig; if (wasm.getFunctionOrNull(im->name)) { throw ParseException("duplicate import", s.line, s.col); }@@ -879,7 +868,8 @@ return Type::eqref; } if (strncmp(str, "i31ref", 6) == 0 && (prefix || str[6] == 0)) {- return Type::i31ref;+ // FIXME: for now, force all inputs to be nullable+ return Type(HeapType::BasicHeapType::i31, Nullable); } if (allowError) { return Type::none;@@ -891,32 +881,32 @@ bool prefix) { if (str[0] == 'a') { if (str[1] == 'n' && str[2] == 'y' && (prefix || str[3] == 0)) {- return HeapType::AnyKind;+ return HeapType::any; } } if (str[0] == 'e') { if (str[1] == 'q' && (prefix || str[2] == 0)) {- return HeapType::EqKind;+ return HeapType::eq; } if (str[1] == 'x') { if (str[2] == 'n' && (prefix || str[3] == 0)) {- return HeapType::ExnKind;+ return HeapType::exn; } if (str[2] == 't' && str[3] == 'e' && str[4] == 'r' && str[5] == 'n' && (prefix || str[6] == 0)) {- return HeapType::ExternKind;+ return HeapType::ext; } } } if (str[0] == 'i') { if (str[1] == '3' && str[2] == '1' && (prefix || str[3] == 0)) {- return HeapType::I31Kind;+ return HeapType::i31; } } if (str[0] == 'f') { if (str[1] == 'u' && str[2] == 'n' && str[3] == 'c' && (prefix || str[4] == 0)) {- return HeapType::FuncKind;+ return HeapType::func; } } throw ParseException(std::string("invalid wasm heap type: ") + str);@@ -924,12 +914,50 @@ Type SExpressionWasmBuilder::elementToType(Element& s) { if (s.isStr()) {- return stringToType(s.str(), false, false);+ return stringToType(s.str()); }- auto& tuple = s.list();+ auto& list = s.list();+ auto size = list.size();+ if (elementStartsWith(s, REF)) {+ // It's a reference. It should be in the form+ // (ref $name)+ // or+ // (ref null $name)+ // and also $name can be the expanded structure of the type and not a name,+ // so something like (ref (func (result i32))), etc.+ if (size != 2 && size != 3) {+ throw ParseException(+ std::string("invalid reference type size"), s.line, s.col);+ }+ if (size == 3 && *list[1] != NULL_) {+ throw ParseException(+ std::string("invalid reference type qualifier"), s.line, s.col);+ }+ // FIXME: for now, force all inputs to be nullable+ Nullability nullable = Nullable;+ size_t i = 1;+ if (size == 3) {+ nullable = Nullable;+ i++;+ }+ return Type(parseHeapType(*s[i]), nullable);+ }+ if (elementStartsWith(s, RTT)) {+ // It's an RTT, something like (rtt N $typename) or just (rtt $typename)+ // if there is no depth.+ if (s[1]->dollared()) {+ auto heapType = parseHeapType(*s[1]);+ return Type(Rtt(heapType));+ } else {+ auto depth = atoi(s[1]->str().c_str());+ auto heapType = parseHeapType(*s[2]);+ return Type(Rtt(depth, heapType));+ }+ }+ // It's a tuple. std::vector<Type> types; for (size_t i = 0; i < s.size(); ++i) {- types.push_back(stringToType(tuple[i]->str()));+ types.push_back(elementToType(*list[i])); } return Type(types); }@@ -1299,8 +1327,12 @@ size_t i = 1; offset = 0; align = fallbackAlign;+ // Parse "align=X" and "offset=X" arguments, bailing out on anything else. while (!s[i]->isList()) { const char* str = s[i]->c_str();+ if (strncmp(str, "align", 5) != 0 && strncmp(str, "offset", 6) != 0) {+ return i;+ } const char* eq = strchr(str, '='); if (!eq) { throw ParseException(@@ -1404,17 +1436,17 @@ ret->type = type; ret->bytes = bytes; if (!strncmp(extra, "add", 3)) {- ret->op = Add;+ ret->op = RMWAdd; } else if (!strncmp(extra, "and", 3)) {- ret->op = And;+ ret->op = RMWAnd; } else if (!strncmp(extra, "or", 2)) {- ret->op = Or;+ ret->op = RMWOr; } else if (!strncmp(extra, "sub", 3)) {- ret->op = Sub;+ ret->op = RMWSub; } else if (!strncmp(extra, "xor", 3)) {- ret->op = Xor;+ ret->op = RMWXor; } else if (!strncmp(extra, "xchg", 4)) {- ret->op = Xchg;+ ret->op = RMWXchg; } else { throw ParseException("bad atomic rmw operator", s.line, s.col); }@@ -1460,11 +1492,12 @@ } else if (type == Type::i64) { expectedAlign = 8; } else {- WASM_UNREACHABLE("Invalid prefix for atomic.wait");+ WASM_UNREACHABLE("Invalid prefix for memory.atomic.wait"); } size_t i = parseMemAttributes(s, ret->offset, align, expectedAlign); if (align != expectedAlign) {- throw ParseException("Align of atomic.wait must match size", s.line, s.col);+ throw ParseException(+ "Align of memory.atomic.wait must match size", s.line, s.col); } ret->ptr = parseExpression(s[i]); ret->expected = parseExpression(s[i + 1]);@@ -1479,7 +1512,8 @@ Address align; size_t i = parseMemAttributes(s, ret->offset, align, 4); if (align != 4) {- throw ParseException("Align of atomic.notify must be 4", s.line, s.col);+ throw ParseException(+ "Align of memory.atomic.notify must be 4", s.line, s.col); } ret->ptr = parseExpression(s[i]); ret->notifyCount = parseExpression(s[i + 1]);@@ -1591,6 +1625,51 @@ return ret; } +Expression*+SExpressionWasmBuilder::makeSIMDLoadStoreLane(Element& s,+ SIMDLoadStoreLaneOp op) {+ auto* ret = allocator.alloc<SIMDLoadStoreLane>();+ ret->op = op;+ Address defaultAlign;+ size_t lanes;+ switch (op) {+ case LoadLaneVec8x16:+ case StoreLaneVec8x16:+ defaultAlign = 1;+ lanes = 16;+ break;+ case LoadLaneVec16x8:+ case StoreLaneVec16x8:+ defaultAlign = 2;+ lanes = 8;+ break;+ case LoadLaneVec32x4:+ case StoreLaneVec32x4:+ defaultAlign = 4;+ lanes = 4;+ break;+ case LoadLaneVec64x2:+ case StoreLaneVec64x2:+ defaultAlign = 8;+ lanes = 2;+ break;+ default:+ WASM_UNREACHABLE("Unexpected SIMDLoadStoreLane op");+ }+ size_t i = parseMemAttributes(s, ret->offset, ret->align, defaultAlign);+ ret->index = parseLaneIndex(s[i++], lanes);+ ret->ptr = parseExpression(s[i++]);+ ret->vec = parseExpression(s[i]);+ ret->finalize();+ return ret;+}++Expression* SExpressionWasmBuilder::makePrefetch(Element& s, PrefetchOp op) {+ Address offset, align;+ size_t i = parseMemAttributes(s, offset, align, /*defaultAlign*/ 1);+ return Builder(wasm).makePrefetch(op, offset, align, parseExpression(s[i]));+}+ Expression* SExpressionWasmBuilder::makeMemoryInit(Element& s) { auto ret = allocator.alloc<MemoryInit>(); ret->segment = atoi(s[1]->str().c_str());@@ -1729,7 +1808,7 @@ auto target = getFunctionName(*s[1]); auto ret = allocator.alloc<Call>(); ret->target = target;- ret->type = functionTypes[ret->target];+ ret->type = functionSignatures[ret->target].results; parseCallOperands(s, 2, s.size(), ret); ret->isReturn = isReturn; ret->finalize();@@ -1829,9 +1908,15 @@ if (s.size() != 2) { throw ParseException("invalid heap type reference", s.line, s.col); }- auto heapType = stringToHeapType(s[1]->str()); auto ret = allocator.alloc<RefNull>();- ret->finalize(heapType);+ // The heap type may be just "func", that is, the whole thing is just+ // (ref.null func), or it may be the name of a defined type, such as+ // (ref.null $struct.FOO)+ if (s[1]->dollared()) {+ ret->finalize(parseHeapType(*s[1]));+ } else {+ ret->finalize(stringToHeapType(s[1]->str()));+ } return ret; } @@ -1846,7 +1931,9 @@ auto func = getFunctionName(*s[1]); auto ret = allocator.alloc<RefFunc>(); ret->func = func;- ret->finalize();+ // To support typed function refs, we give the reference not just a general+ // funcref, but a specific subtype with the actual signature.+ ret->finalize(Type(HeapType(functionSignatures[func]), Nullable)); return ret; } @@ -1979,6 +2066,24 @@ return ret; } +Expression* SExpressionWasmBuilder::makeCallRef(Element& s, bool isReturn) {+ auto ret = allocator.alloc<CallRef>();+ parseCallOperands(s, 1, s.size() - 1, ret);+ ret->target = parseExpression(s[s.size() - 1]);+ ret->isReturn = isReturn;+ if (!ret->target->type.isRef()) {+ throw ParseException("Non-reference type for a call_ref", s.line, s.col);+ }+ auto heapType = ret->target->type.getHeapType();+ if (!heapType.isSignature()) {+ throw ParseException(+ "Invalid reference type for a call_ref", s.line, s.col);+ }+ auto sig = heapType.getSignature();+ ret->finalize(sig.results);+ return ret;+}+ Expression* SExpressionWasmBuilder::makeI31New(Element& s) { auto ret = allocator.alloc<I31New>(); ret->value = parseExpression(s[1]);@@ -1995,101 +2100,125 @@ } Expression* SExpressionWasmBuilder::makeRefTest(Element& s) {- auto ret = allocator.alloc<RefTest>();- WASM_UNREACHABLE("TODO (gc): ref.test");- ret->finalize();- return ret;+ auto heapType = parseHeapType(*s[1]);+ auto* ref = parseExpression(*s[2]);+ auto* rtt = parseExpression(*s[3]);+ validateHeapTypeUsingChild(rtt, heapType, s);+ return Builder(wasm).makeRefTest(ref, rtt); } Expression* SExpressionWasmBuilder::makeRefCast(Element& s) {- auto ret = allocator.alloc<RefCast>();- WASM_UNREACHABLE("TODO (gc): ref.cast");- ret->finalize();- return ret;+ auto heapType = parseHeapType(*s[1]);+ auto* ref = parseExpression(*s[2]);+ auto* rtt = parseExpression(*s[3]);+ validateHeapTypeUsingChild(rtt, heapType, s);+ return Builder(wasm).makeRefCast(ref, rtt); } Expression* SExpressionWasmBuilder::makeBrOnCast(Element& s) {- auto ret = allocator.alloc<BrOnCast>();- WASM_UNREACHABLE("TODO (gc): br_on_cast");- ret->finalize();- return ret;+ auto name = getLabel(*s[1]);+ auto heapType = parseHeapType(*s[2]);+ auto* ref = parseExpression(*s[3]);+ auto* rtt = parseExpression(*s[4]);+ validateHeapTypeUsingChild(rtt, heapType, s);+ return Builder(wasm).makeBrOnCast(name, heapType, ref, rtt); } Expression* SExpressionWasmBuilder::makeRttCanon(Element& s) {- auto ret = allocator.alloc<RttCanon>();- WASM_UNREACHABLE("TODO (gc): rtt.canon");- ret->finalize();- return ret;+ return Builder(wasm).makeRttCanon(parseHeapType(*s[1])); } Expression* SExpressionWasmBuilder::makeRttSub(Element& s) {- auto ret = allocator.alloc<RttSub>();- WASM_UNREACHABLE("TODO (gc): rtt.sub");- ret->finalize();- return ret;+ auto heapType = parseHeapType(*s[1]);+ auto parent = parseExpression(*s[2]);+ return Builder(wasm).makeRttSub(heapType, parent); } Expression* SExpressionWasmBuilder::makeStructNew(Element& s, bool default_) {- auto ret = allocator.alloc<StructNew>();- WASM_UNREACHABLE("TODO (gc): struct.new");- ret->finalize();- return ret;+ auto heapType = parseHeapType(*s[1]);+ auto* rtt = parseExpression(*s[2]);+ validateHeapTypeUsingChild(rtt, heapType, s);+ auto numOperands = s.size() - 3;+ if (default_ && numOperands > 0) {+ throw ParseException(+ "arguments provided for struct.new_with_default", s.line, s.col);+ }+ std::vector<Expression*> operands;+ operands.resize(numOperands);+ for (Index i = 0; i < numOperands; i++) {+ operands[i] = parseExpression(*s[i + 3]);+ }+ return Builder(wasm).makeStructNew(rtt, operands); } -Expression* SExpressionWasmBuilder::makeStructGet(Element& s) {- auto ret = allocator.alloc<StructGet>();- WASM_UNREACHABLE("TODO (gc): struct.get");- ret->finalize();- return ret;+Index SExpressionWasmBuilder::getStructIndex(const HeapType& type, Element& s) {+ if (s.dollared()) {+ auto name = s.str();+ auto struct_ = type.getStruct();+ auto& fields = struct_.fields;+ for (Index i = 0; i < fields.size(); i++) {+ if (fields[i].name == name) {+ return i;+ }+ }+ throw ParseException("bad struct name", s.line, s.col);+ }+ // this is a numeric index+ return atoi(s.c_str()); } Expression* SExpressionWasmBuilder::makeStructGet(Element& s, bool signed_) {- auto ret = allocator.alloc<StructGet>();- WASM_UNREACHABLE("TODO (gc): struct.get_s/u");- ret->finalize();- return ret;+ auto heapType = parseHeapType(*s[1]);+ auto index = getStructIndex(heapType, *s[2]);+ auto type = heapType.getStruct().fields[index].type;+ auto ref = parseExpression(*s[3]);+ validateHeapTypeUsingChild(ref, heapType, s);+ return Builder(wasm).makeStructGet(index, ref, type, signed_); } Expression* SExpressionWasmBuilder::makeStructSet(Element& s) {- auto ret = allocator.alloc<StructSet>();- WASM_UNREACHABLE("TODO (gc): struct.set");- ret->finalize();- return ret;+ auto heapType = parseHeapType(*s[1]);+ auto index = getStructIndex(heapType, *s[2]);+ auto ref = parseExpression(*s[3]);+ validateHeapTypeUsingChild(ref, heapType, s);+ auto value = parseExpression(*s[4]);+ return Builder(wasm).makeStructSet(index, ref, value); } Expression* SExpressionWasmBuilder::makeArrayNew(Element& s, bool default_) {- auto ret = allocator.alloc<ArrayNew>();- WASM_UNREACHABLE("TODO (gc): array.new");- ret->finalize();- return ret;-}--Expression* SExpressionWasmBuilder::makeArrayGet(Element& s) {- auto ret = allocator.alloc<ArrayGet>();- WASM_UNREACHABLE("TODO (gc): array.get");- ret->finalize();- return ret;+ auto heapType = parseHeapType(*s[1]);+ auto* rtt = parseExpression(*s[2]);+ validateHeapTypeUsingChild(rtt, heapType, s);+ auto* size = parseExpression(*s[3]);+ Expression* init = nullptr;+ if (!default_) {+ init = parseExpression(*s[4]);+ }+ return Builder(wasm).makeArrayNew(rtt, size, init); } Expression* SExpressionWasmBuilder::makeArrayGet(Element& s, bool signed_) {- auto ret = allocator.alloc<ArrayGet>();- WASM_UNREACHABLE("TODO (gc): array.get_s/u");- ret->finalize();- return ret;+ auto heapType = parseHeapType(*s[1]);+ auto ref = parseExpression(*s[2]);+ validateHeapTypeUsingChild(ref, heapType, s);+ auto index = parseExpression(*s[3]);+ return Builder(wasm).makeArrayGet(ref, index, signed_); } Expression* SExpressionWasmBuilder::makeArraySet(Element& s) {- auto ret = allocator.alloc<ArraySet>();- WASM_UNREACHABLE("TODO (gc): array.set");- ret->finalize();- return ret;+ auto heapType = parseHeapType(*s[1]);+ auto ref = parseExpression(*s[2]);+ validateHeapTypeUsingChild(ref, heapType, s);+ auto index = parseExpression(*s[3]);+ auto value = parseExpression(*s[4]);+ return Builder(wasm).makeArraySet(ref, index, value); } Expression* SExpressionWasmBuilder::makeArrayLen(Element& s) {- auto ret = allocator.alloc<ArrayLen>();- WASM_UNREACHABLE("TODO (gc): array.len");- ret->finalize();- return ret;+ auto heapType = parseHeapType(*s[1]);+ auto ref = parseExpression(*s[2]);+ validateHeapTypeUsingChild(ref, heapType, s);+ return Builder(wasm).makeArrayLen(ref); } // converts an s-expression string representing binary data into an output@@ -2185,7 +2314,7 @@ wasm.memory.shared = false; Index i = 1; if (s[i]->dollared()) {- wasm.memory.name = s[i++]->str();+ wasm.memory.setExplicitName(s[i++]->str()); } i = parseMemoryIndex(s, i); Name importModule, importBase;@@ -2216,7 +2345,7 @@ // (memory (data ..)) format auto j = parseMemoryIndex(inner, 1); auto offset = allocator.alloc<Const>()->set(Literal(int32_t(0)));- parseInnerData(inner, j, offset, false);+ parseInnerData(inner, j, {}, offset, false); wasm.memory.initial = wasm.memory.segments[0].data.size(); return; }@@ -2261,6 +2390,10 @@ bool isPassive = false; Expression* offset = nullptr; Index i = 1;+ Name name;+ if (s[i]->dollared()) {+ name = s[i++]->str();+ } if (s[i]->isStr()) { // data is passive or named if (s[i]->str() == PASSIVE) {@@ -2274,13 +2407,11 @@ if (s.size() != 3 && s.size() != 4) { throw ParseException("Unexpected data items", s.line, s.col); }- parseInnerData(s, s.size() - 1, offset, isPassive);+ parseInnerData(s, s.size() - 1, name, offset, isPassive); } -void SExpressionWasmBuilder::parseInnerData(Element& s,- Index i,- Expression* offset,- bool isPassive) {+void SExpressionWasmBuilder::parseInnerData(+ Element& s, Index i, Name name, Expression* offset, bool isPassive) { std::vector<char> data; while (i < s.size()) { const char* input = s[i++]->c_str();@@ -2289,7 +2420,7 @@ } } wasm.memory.segments.emplace_back(- isPassive, offset, data.data(), data.size());+ name, isPassive, offset, data.data(), data.size()); } void SExpressionWasmBuilder::parseExport(Element& s) {@@ -2358,7 +2489,8 @@ (*s[3])[newStyleInner]->dollared()) { name = (*s[3])[newStyleInner++]->str(); }- if (!name.is()) {+ bool hasExplicitName = name.is();+ if (!hasExplicitName) { if (kind == ExternalKind::Function) { name = Name("fimport$" + std::to_string(functionCounter++)); functionNames.push_back(name);@@ -2366,9 +2498,9 @@ name = Name("gimport$" + std::to_string(globalCounter++)); globalNames.push_back(name); } else if (kind == ExternalKind::Memory) {- name = Name("mimport$" + std::to_string(0));+ name = Name("mimport$" + std::to_string(memoryCounter++)); } else if (kind == ExternalKind::Table) {- name = Name("timport$" + std::to_string(0));+ name = Name("timport$" + std::to_string(tableCounter++)); } else if (kind == ExternalKind::Event) { name = Name("eimport$" + std::to_string(eventCounter++)); eventNames.push_back(name);@@ -2396,10 +2528,10 @@ auto func = make_unique<Function>(); j = parseTypeUse(inner, j, func->sig);- func->name = name;+ func->setName(name, hasExplicitName); func->module = module; func->base = base;- functionTypes[name] = func->sig.results;+ functionSignatures[name] = func->sig; wasm.addFunction(func.release()); } else if (kind == ExternalKind::Global) { Type type;@@ -2415,14 +2547,14 @@ mutable_ = true; } auto global = make_unique<Global>();- global->name = name;+ global->setName(name, hasExplicitName); global->module = module; global->base = base; global->type = type; global->mutable_ = mutable_; wasm.addGlobal(global.release()); } else if (kind == ExternalKind::Table) {- wasm.table.name = name;+ wasm.table.setName(name, hasExplicitName); wasm.table.module = module; wasm.table.base = base; if (j < inner.size() - 1) {@@ -2440,7 +2572,7 @@ j++; // funcref // ends with the table element type } else if (kind == ExternalKind::Memory) {- wasm.memory.name = name;+ wasm.memory.setName(name, hasExplicitName); wasm.memory.module = module; wasm.memory.base = base; if (inner[j]->isList()) {@@ -2465,7 +2597,7 @@ } event->attribute = atoi(attrElem[1]->c_str()); j = parseTypeUse(inner, j, event->sig);- event->name = name;+ event->setName(name, hasExplicitName); event->module = module; event->base = base; wasm.addEvent(event.release());@@ -2480,7 +2612,7 @@ std::unique_ptr<Global> global = make_unique<Global>(); size_t i = 1; if (s[i]->dollared() && !(s[i]->isStr() && isType(s[i]->str()))) {- global->name = s[i++]->str();+ global->setExplicitName(s[i++]->str()); } else { global->name = Name::fromInt(globalCounter); }@@ -2569,7 +2701,7 @@ return; // empty table in old notation } if (s[i]->dollared()) {- wasm.table.name = s[i++]->str();+ wasm.table.setExplicitName(s[i++]->str()); } if (i == s.size()) { return;@@ -2662,30 +2794,102 @@ wasm.table.segments.push_back(segment); } +HeapType SExpressionWasmBuilder::parseHeapType(Element& s) {+ if (s.isStr()) {+ // It's a string.+ if (s.dollared()) {+ auto it = typeIndices.find(s.str().str);+ if (it == typeIndices.end()) {+ throw ParseException("unknown dollared function type", s.line, s.col);+ }+ return types[it->second];+ } else {+ // It may be a numerical index, or it may be a built-in type name like+ // "i31".+ auto* str = s.str().c_str();+ if (String::isNumber(str)) {+ size_t offset = atoi(str);+ if (offset >= types.size()) {+ throw ParseException("unknown indexed function type", s.line, s.col);+ }+ return types[offset];+ }+ return stringToHeapType(str, /* prefix = */ false);+ }+ }+ // It's a list.+ if (*s[0] == FUNC) {+ std::vector<Type> params;+ std::vector<Type> results;+ for (size_t k = 1; k < s.size(); k++) {+ Element& curr = *s[k];+ if (elementStartsWith(curr, PARAM)) {+ auto newParams = parseParamOrLocal(curr);+ params.insert(params.end(), newParams.begin(), newParams.end());+ } else if (elementStartsWith(curr, RESULT)) {+ auto newResults = parseResults(curr);+ results.insert(results.end(), newResults.begin(), newResults.end());+ }+ }+ return Signature(Type(params), Type(results));+ }+ // It's a struct or an array.+ auto parseField = [&](Element* t) {+ Mutability mutable_ = Immutable;+ // t is a list, containing either+ // TYPE+ // or+ // (field TYPE)+ // or+ // (field $name TYPE)+ Name name;+ if (elementStartsWith(t, FIELD)) {+ if (t->size() == 3) {+ name = (*t)[1]->str();+ }+ t = (*t)[t->size() - 1];+ }+ // The element may also be (mut (..)).+ if (elementStartsWith(t, MUT)) {+ mutable_ = Mutable;+ t = (*t)[1];+ }+ if (t->isStr()) {+ // t is a simple string name like "i32". It can be a normal wasm type, or+ // one of the special types only available in fields.+ if (*t == I8) {+ return Field(Field::i8, mutable_, name);+ } else if (*t == I16) {+ return Field(Field::i16, mutable_, name);+ }+ }+ // Otherwise it's an arbitrary type.+ return Field(elementToType(*t), mutable_, name);+ };+ if (elementStartsWith(s, STRUCT)) {+ FieldList fields;+ for (size_t k = 1; k < s.size(); k++) {+ fields.emplace_back(parseField(s[k]));+ }+ return Struct(fields);+ }+ if (elementStartsWith(s, ARRAY)) {+ return Array(parseField(s[1]));+ }+ throw ParseException("invalid heap type", s.line, s.col);+}+ void SExpressionWasmBuilder::parseType(Element& s) {- std::vector<Type> params;- std::vector<Type> results; size_t i = 1; if (s[i]->isStr()) { std::string name = s[i]->str().str;- if (signatureIndices.find(name) != signatureIndices.end()) {+ if (typeIndices.find(name) != typeIndices.end()) { throw ParseException("duplicate function type", s.line, s.col); }- signatureIndices[name] = signatures.size();+ typeIndices[name] = types.size(); i++; }- Element& func = *s[i];- for (size_t k = 1; k < func.size(); k++) {- Element& curr = *func[k];- if (elementStartsWith(curr, PARAM)) {- auto newParams = parseParamOrLocal(curr);- params.insert(params.end(), newParams.begin(), newParams.end());- } else if (elementStartsWith(curr, RESULT)) {- auto newResults = parseResults(curr);- results.insert(results.end(), newResults.begin(), newResults.end());- }- }- signatures.emplace_back(Type(params), Type(results));+ types.emplace_back(parseHeapType(*s[i])); } void SExpressionWasmBuilder::parseEvent(Element& s, bool preParseImport) {@@ -2695,7 +2899,7 @@ // Parse name if (s[i]->isStr() && s[i]->dollared()) { auto& inner = *s[i++];- event->name = inner.str();+ event->setExplicitName(inner.str()); if (wasm.getEventOrNull(event->name)) { throw ParseException("duplicate event", inner.line, inner.col); }@@ -2773,6 +2977,21 @@ } wasm.addEvent(event.release());+}++void SExpressionWasmBuilder::validateHeapTypeUsingChild(Expression* child,+ HeapType heapType,+ Element& s) {+ if (child->type == Type::unreachable) {+ return;+ }+ if ((!child->type.isRef() && !child->type.isRtt()) ||+ child->type.getHeapType() != heapType) {+ throw ParseException("bad heap type: expected " + heapType.toString() ++ " but found " + child->type.toString(),+ s.line,+ s.col);+ } } } // namespace wasm
binaryen/src/wasm/wasm-stack.cpp view
@@ -20,13 +20,15 @@ namespace wasm { +static Name IMPOSSIBLE_CONTINUE("impossible-continue");+ void BinaryInstWriter::emitResultType(Type type) { if (type == Type::unreachable) {- o << binaryType(Type::none);+ parent.writeType(Type::none); } else if (type.isTuple()) { o << S32LEB(parent.getTypeIndex(Signature(Type::none, type))); } else {- o << binaryType(type);+ parent.writeType(type); } } @@ -351,7 +353,7 @@ o << int8_t(BinaryConsts::AtomicPrefix); #define CASE_FOR_OP(Op) \- case Op: \+ case RMW##Op: \ switch (curr->type.getBasic()) { \ case Type::i32: \ switch (curr->bytes) { \@@ -558,6 +560,18 @@ case QFMSF64x2: o << U32LEB(BinaryConsts::F64x2QFMS); break;+ case SignSelectVec8x16:+ o << U32LEB(BinaryConsts::V8x16SignSelect);+ break;+ case SignSelectVec16x8:+ o << U32LEB(BinaryConsts::V16x8SignSelect);+ break;+ case SignSelectVec32x4:+ o << U32LEB(BinaryConsts::V32x4SignSelect);+ break;+ case SignSelectVec64x2:+ o << U32LEB(BinaryConsts::V64x2SignSelect);+ break; } } @@ -647,6 +661,53 @@ emitMemoryAccess(curr->align, /*(unused) bytes=*/0, curr->offset); } +void BinaryInstWriter::visitSIMDLoadStoreLane(SIMDLoadStoreLane* curr) {+ o << int8_t(BinaryConsts::SIMDPrefix);+ switch (curr->op) {+ case LoadLaneVec8x16:+ o << U32LEB(BinaryConsts::V128Load8Lane);+ break;+ case LoadLaneVec16x8:+ o << U32LEB(BinaryConsts::V128Load16Lane);+ break;+ case LoadLaneVec32x4:+ o << U32LEB(BinaryConsts::V128Load32Lane);+ break;+ case LoadLaneVec64x2:+ o << U32LEB(BinaryConsts::V128Load64Lane);+ break;+ case StoreLaneVec8x16:+ o << U32LEB(BinaryConsts::V128Store8Lane);+ break;+ case StoreLaneVec16x8:+ o << U32LEB(BinaryConsts::V128Store16Lane);+ break;+ case StoreLaneVec32x4:+ o << U32LEB(BinaryConsts::V128Store32Lane);+ break;+ case StoreLaneVec64x2:+ o << U32LEB(BinaryConsts::V128Store64Lane);+ break;+ }+ assert(curr->align);+ emitMemoryAccess(curr->align, /*(unused) bytes=*/0, curr->offset);+ o << curr->index;+}++void BinaryInstWriter::visitPrefetch(Prefetch* curr) {+ o << int8_t(BinaryConsts::SIMDPrefix);+ switch (curr->op) {+ case PrefetchTemporal:+ o << U32LEB(BinaryConsts::PrefetchT);+ break;+ case PrefetchNontemporal:+ o << U32LEB(BinaryConsts::PrefetchNT);+ break;+ }+ assert(curr->align);+ emitMemoryAccess(curr->align, /*(unused) bytes=*/0, curr->offset);+}+ void BinaryInstWriter::visitMemoryInit(MemoryInit* curr) { o << int8_t(BinaryConsts::MiscPrefix); o << U32LEB(BinaryConsts::MemoryInit);@@ -938,6 +999,10 @@ o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::I8x16Bitmask); break;+ case PopcntVecI8x16:+ o << int8_t(BinaryConsts::SIMDPrefix)+ << U32LEB(BinaryConsts::I8x16Popcnt);+ break; case AbsVecI16x8: o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::I16x8Abs); break;@@ -977,13 +1042,9 @@ case NegVecI64x2: o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::I64x2Neg); break;- case AnyTrueVecI64x2:- o << int8_t(BinaryConsts::SIMDPrefix)- << U32LEB(BinaryConsts::I64x2AnyTrue);- break;- case AllTrueVecI64x2:+ case BitmaskVecI64x2: o << int8_t(BinaryConsts::SIMDPrefix)- << U32LEB(BinaryConsts::I64x2AllTrue);+ << U32LEB(BinaryConsts::I64x2Bitmask); break; case AbsVecF32x4: o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::F32x4Abs);@@ -1029,6 +1090,22 @@ o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::F64x2Nearest); break;+ case ExtAddPairwiseSVecI8x16ToI16x8:+ o << int8_t(BinaryConsts::SIMDPrefix)+ << U32LEB(BinaryConsts::I16x8ExtAddPairWiseSI8x16);+ break;+ case ExtAddPairwiseUVecI8x16ToI16x8:+ o << int8_t(BinaryConsts::SIMDPrefix)+ << U32LEB(BinaryConsts::I16x8ExtAddPairWiseUI8x16);+ break;+ case ExtAddPairwiseSVecI16x8ToI32x4:+ o << int8_t(BinaryConsts::SIMDPrefix)+ << U32LEB(BinaryConsts::I32x4ExtAddPairWiseSI16x8);+ break;+ case ExtAddPairwiseUVecI16x8ToI32x4:+ o << int8_t(BinaryConsts::SIMDPrefix)+ << U32LEB(BinaryConsts::I32x4ExtAddPairWiseUI16x8);+ break; case TruncSatSVecF32x4ToVecI32x4: o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::I32x4TruncSatSF32x4);@@ -1093,6 +1170,22 @@ o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::I32x4WidenHighUI16x8); break;+ case WidenLowSVecI32x4ToVecI64x2:+ o << int8_t(BinaryConsts::SIMDPrefix)+ << U32LEB(BinaryConsts::I64x2WidenLowSI32x4);+ break;+ case WidenHighSVecI32x4ToVecI64x2:+ o << int8_t(BinaryConsts::SIMDPrefix)+ << U32LEB(BinaryConsts::I64x2WidenHighSI32x4);+ break;+ case WidenLowUVecI32x4ToVecI64x2:+ o << int8_t(BinaryConsts::SIMDPrefix)+ << U32LEB(BinaryConsts::I64x2WidenLowUI32x4);+ break;+ case WidenHighUVecI32x4ToVecI64x2:+ o << int8_t(BinaryConsts::SIMDPrefix)+ << U32LEB(BinaryConsts::I64x2WidenHighUI32x4);+ break; case InvalidUnary: WASM_UNREACHABLE("invalid unary op"); }@@ -1422,6 +1515,9 @@ case GeUVecI32x4: o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::I32x4GeU); break;+ case EqVecI64x2:+ o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::I64x2Eq);+ break; case EqVecF32x4: o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::F32x4Eq); break;@@ -1550,6 +1646,26 @@ case AvgrUVecI16x8: o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::I16x8AvgrU); break;+ case Q15MulrSatSVecI16x8:+ o << int8_t(BinaryConsts::SIMDPrefix)+ << U32LEB(BinaryConsts::I16x8Q15MulrSatS);+ break;+ case ExtMulLowSVecI16x8:+ o << int8_t(BinaryConsts::SIMDPrefix)+ << U32LEB(BinaryConsts::I16x8ExtMulLowSI8x16);+ break;+ case ExtMulHighSVecI16x8:+ o << int8_t(BinaryConsts::SIMDPrefix)+ << U32LEB(BinaryConsts::I16x8ExtMulHighSI8x16);+ break;+ case ExtMulLowUVecI16x8:+ o << int8_t(BinaryConsts::SIMDPrefix)+ << U32LEB(BinaryConsts::I16x8ExtMulLowUI8x16);+ break;+ case ExtMulHighUVecI16x8:+ o << int8_t(BinaryConsts::SIMDPrefix)+ << U32LEB(BinaryConsts::I16x8ExtMulHighUI8x16);+ break; case AddVecI32x4: o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::I32x4Add); break;@@ -1575,6 +1691,22 @@ o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::I32x4DotSVecI16x8); break;+ case ExtMulLowSVecI32x4:+ o << int8_t(BinaryConsts::SIMDPrefix)+ << U32LEB(BinaryConsts::I32x4ExtMulLowSI16x8);+ break;+ case ExtMulHighSVecI32x4:+ o << int8_t(BinaryConsts::SIMDPrefix)+ << U32LEB(BinaryConsts::I32x4ExtMulHighSI16x8);+ break;+ case ExtMulLowUVecI32x4:+ o << int8_t(BinaryConsts::SIMDPrefix)+ << U32LEB(BinaryConsts::I32x4ExtMulLowUI16x8);+ break;+ case ExtMulHighUVecI32x4:+ o << int8_t(BinaryConsts::SIMDPrefix)+ << U32LEB(BinaryConsts::I32x4ExtMulHighUI16x8);+ break; case AddVecI64x2: o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::I64x2Add); break;@@ -1584,6 +1716,22 @@ case MulVecI64x2: o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::I64x2Mul); break;+ case ExtMulLowSVecI64x2:+ o << int8_t(BinaryConsts::SIMDPrefix)+ << U32LEB(BinaryConsts::I64x2ExtMulLowSI32x4);+ break;+ case ExtMulHighSVecI64x2:+ o << int8_t(BinaryConsts::SIMDPrefix)+ << U32LEB(BinaryConsts::I64x2ExtMulHighSI32x4);+ break;+ case ExtMulLowUVecI64x2:+ o << int8_t(BinaryConsts::SIMDPrefix)+ << U32LEB(BinaryConsts::I64x2ExtMulLowUI32x4);+ break;+ case ExtMulHighUVecI64x2:+ o << int8_t(BinaryConsts::SIMDPrefix)+ << U32LEB(BinaryConsts::I64x2ExtMulHighUI32x4);+ break; case AddVecF32x4: o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::F32x4Add);@@ -1665,8 +1813,8 @@ if (curr->type.isRef()) { o << int8_t(BinaryConsts::SelectWithType) << U32LEB(curr->type.size()); for (size_t i = 0; i < curr->type.size(); i++) {- o << binaryType(curr->type != Type::unreachable ? curr->type- : Type::none);+ parent.writeType(curr->type != Type::unreachable ? curr->type+ : Type::none); } } else { o << int8_t(BinaryConsts::Select);@@ -1688,8 +1836,8 @@ } void BinaryInstWriter::visitRefNull(RefNull* curr) {- o << int8_t(BinaryConsts::RefNull)- << binaryHeapType(curr->type.getHeapType());+ o << int8_t(BinaryConsts::RefNull);+ parent.writeHeapType(curr->type.getHeapType()); } void BinaryInstWriter::visitRefIsNull(RefIsNull* curr) {@@ -1784,69 +1932,116 @@ << U32LEB(curr->signed_ ? BinaryConsts::I31GetS : BinaryConsts::I31GetU); } +void BinaryInstWriter::visitCallRef(CallRef* curr) {+ o << int8_t(curr->isReturn ? BinaryConsts::RetCallRef+ : BinaryConsts::CallRef);+}+ void BinaryInstWriter::visitRefTest(RefTest* curr) { o << int8_t(BinaryConsts::GCPrefix) << U32LEB(BinaryConsts::RefTest);- WASM_UNREACHABLE("TODO (gc): ref.test");+ parent.writeHeapType(curr->ref->type.getHeapType());+ parent.writeHeapType(curr->getCastType().getHeapType()); } void BinaryInstWriter::visitRefCast(RefCast* curr) { o << int8_t(BinaryConsts::GCPrefix) << U32LEB(BinaryConsts::RefCast);- WASM_UNREACHABLE("TODO (gc): ref.cast");+ parent.writeHeapType(curr->ref->type.getHeapType());+ parent.writeHeapType(curr->getCastType().getHeapType()); } void BinaryInstWriter::visitBrOnCast(BrOnCast* curr) {- o << int8_t(BinaryConsts::GCPrefix) << U32LEB(BinaryConsts::BrOnCast);- WASM_UNREACHABLE("TODO (gc): br_on_cast");+ o << int8_t(BinaryConsts::GCPrefix) << U32LEB(BinaryConsts::BrOnCast)+ << U32LEB(getBreakIndex(curr->name));+ parent.writeHeapType(curr->ref->type.getHeapType());+ parent.writeHeapType(curr->getCastType().getHeapType()); } void BinaryInstWriter::visitRttCanon(RttCanon* curr) { o << int8_t(BinaryConsts::GCPrefix) << U32LEB(BinaryConsts::RttCanon);- WASM_UNREACHABLE("TODO (gc): rtt.canon");+ parent.writeHeapType(curr->type.getRtt().heapType); } void BinaryInstWriter::visitRttSub(RttSub* curr) { o << int8_t(BinaryConsts::GCPrefix) << U32LEB(BinaryConsts::RttSub);- WASM_UNREACHABLE("TODO (gc): rtt.sub");+ // FIXME: the binary format may also have an extra heap type and index that+ // are not needed+ parent.writeHeapType(curr->type.getRtt().heapType); } void BinaryInstWriter::visitStructNew(StructNew* curr) {- WASM_UNREACHABLE("TODO (gc): struct.new");+ o << int8_t(BinaryConsts::GCPrefix);+ if (curr->isWithDefault()) {+ o << U32LEB(BinaryConsts::StructNewDefaultWithRtt);+ } else {+ o << U32LEB(BinaryConsts::StructNewWithRtt);+ }+ parent.writeHeapType(curr->rtt->type.getHeapType()); } void BinaryInstWriter::visitStructGet(StructGet* curr) {- WASM_UNREACHABLE("TODO (gc): struct.get");+ const auto& heapType = curr->ref->type.getHeapType();+ const auto& field = heapType.getStruct().fields[curr->index];+ int8_t op;+ if (field.type != Type::i32 || field.packedType == Field::not_packed) {+ op = BinaryConsts::StructGet;+ } else if (curr->signed_) {+ op = BinaryConsts::StructGetS;+ } else {+ op = BinaryConsts::StructGetU;+ }+ o << int8_t(BinaryConsts::GCPrefix) << U32LEB(op);+ parent.writeHeapType(heapType);+ o << U32LEB(curr->index); } void BinaryInstWriter::visitStructSet(StructSet* curr) { o << int8_t(BinaryConsts::GCPrefix) << U32LEB(BinaryConsts::StructSet);- WASM_UNREACHABLE("TODO (gc): struct.set");+ parent.writeHeapType(curr->ref->type.getHeapType());+ o << U32LEB(curr->index); } void BinaryInstWriter::visitArrayNew(ArrayNew* curr) {- WASM_UNREACHABLE("TODO (gc): array.new");+ o << int8_t(BinaryConsts::GCPrefix);+ if (curr->isWithDefault()) {+ o << U32LEB(BinaryConsts::ArrayNewDefaultWithRtt);+ } else {+ o << U32LEB(BinaryConsts::ArrayNewWithRtt);+ }+ parent.writeHeapType(curr->rtt->type.getHeapType()); } void BinaryInstWriter::visitArrayGet(ArrayGet* curr) {- WASM_UNREACHABLE("TODO (gc): array.get");+ auto heapType = curr->ref->type.getHeapType();+ const auto& field = heapType.getArray().element;+ int8_t op;+ if (field.type != Type::i32 || field.packedType == Field::not_packed) {+ op = BinaryConsts::ArrayGet;+ } else if (curr->signed_) {+ op = BinaryConsts::ArrayGetS;+ } else {+ op = BinaryConsts::ArrayGetU;+ }+ o << int8_t(BinaryConsts::GCPrefix) << U32LEB(op);+ parent.writeHeapType(heapType); } void BinaryInstWriter::visitArraySet(ArraySet* curr) { o << int8_t(BinaryConsts::GCPrefix) << U32LEB(BinaryConsts::ArraySet);- WASM_UNREACHABLE("TODO (gc): array.set");+ parent.writeHeapType(curr->ref->type.getHeapType()); } void BinaryInstWriter::visitArrayLen(ArrayLen* curr) { o << int8_t(BinaryConsts::GCPrefix) << U32LEB(BinaryConsts::ArrayLen);- WASM_UNREACHABLE("TODO (gc): array.len");+ parent.writeHeapType(curr->ref->type.getHeapType()); } void BinaryInstWriter::emitScopeEnd(Expression* curr) { assert(!breakStack.empty()); breakStack.pop_back();+ o << int8_t(BinaryConsts::End); if (func && !sourceMap) {- parent.writeExtraDebugLocation(curr, func, BinaryLocations::End);+ parent.writeDebugLocationEnd(curr, func); }- o << int8_t(BinaryConsts::End); } void BinaryInstWriter::emitFunctionEnd() { o << int8_t(BinaryConsts::End); }@@ -1875,7 +2070,8 @@ o << U32LEB(func->getNumVars()); for (Index i = varStart; i < varEnd; i++) { mappedLocals[std::make_pair(i, 0)] = i;- o << U32LEB(1) << binaryType(func->getLocalType(i));+ o << U32LEB(1);+ parent.writeType(func->getLocalType(i)); } return; }@@ -1904,7 +2100,8 @@ setScratchLocals(); o << U32LEB(numLocalsByType.size()); for (auto& typeCount : numLocalsByType) {- o << U32LEB(typeCount.second) << binaryType(typeCount.first);+ o << U32LEB(typeCount.second);+ parent.writeType(typeCount.first); } }
binaryen/src/wasm/wasm-type.cpp view
@@ -19,885 +19,1377 @@ #include <shared_mutex> #include <sstream> #include <unordered_map>--#include "compiler-support.h"-#include "support/hash.h"-#include "wasm-features.h"-#include "wasm-type.h"--namespace wasm {--struct TypeInfo {- enum Kind {- TupleKind,- RefKind,- RttKind,- } kind;- struct Ref {- HeapType heapType;- bool nullable;- };- union {- Tuple tuple;- Ref ref;- Rtt rtt;- };-- TypeInfo(const Tuple& tuple) : kind(TupleKind), tuple(tuple) {}- TypeInfo(Tuple&& tuple) : kind(TupleKind), tuple(std::move(tuple)) {}- TypeInfo(const HeapType& heapType, bool nullable)- : kind(RefKind), ref{heapType, nullable} {}- TypeInfo(HeapType&& heapType, bool nullable)- : kind(RefKind), ref{std::move(heapType), nullable} {}- TypeInfo(const Rtt& rtt) : kind(RttKind), rtt(rtt) {}- TypeInfo(Rtt&& rtt) : kind(RttKind), rtt(std::move(rtt)) {}- TypeInfo(const TypeInfo& other) {- kind = other.kind;- switch (kind) {- case TupleKind:- new (&tuple) auto(other.tuple);- return;- case RefKind:- new (&ref) auto(other.ref);- return;- case RttKind:- new (&rtt) auto(other.rtt);- return;- }- WASM_UNREACHABLE("unexpected kind");- }- ~TypeInfo() {- switch (kind) {- case TupleKind: {- tuple.~Tuple();- return;- }- case RefKind: {- ref.~Ref();- return;- }- case RttKind: {- rtt.~Rtt();- return;- }- }- WASM_UNREACHABLE("unexpected kind");- }-- constexpr bool isTuple() const { return kind == TupleKind; }- constexpr bool isRef() const { return kind == RefKind; }- constexpr bool isRtt() const { return kind == RttKind; }-- bool isNullable() const { return kind == RefKind && ref.nullable; }-- bool operator==(const TypeInfo& other) const {- if (kind != other.kind) {- return false;- }- switch (kind) {- case TupleKind:- return tuple == other.tuple;- case RefKind:- return ref.heapType == other.ref.heapType &&- ref.nullable == other.ref.nullable;- case RttKind:- return rtt == other.rtt;- }- WASM_UNREACHABLE("unexpected kind");- }- bool operator!=(const TypeInfo& other) const { return !(*this == other); }- TypeInfo& operator=(const TypeInfo& other) {- if (&other != this) {- this->~TypeInfo();- new (this) auto(other);- }- return *this;- }-- std::string toString() const;-};--std::ostream& operator<<(std::ostream&, TypeInfo);--} // namespace wasm--namespace std {--template<> class hash<wasm::TypeList> {-public:- size_t operator()(const wasm::TypeList& types) const {- auto digest = wasm::hash(types.size());- for (auto type : types) {- wasm::rehash(digest, type);- }- return digest;- }-};--template<> class hash<wasm::FieldList> {-public:- size_t operator()(const wasm::FieldList& fields) const {- auto digest = wasm::hash(fields.size());- for (auto field : fields) {- wasm::rehash(digest, field);- }- return digest;- }-};--template<> class hash<wasm::TypeInfo> {-public:- size_t operator()(const wasm::TypeInfo& info) const {- auto digest = wasm::hash(info.kind);- switch (info.kind) {- case wasm::TypeInfo::TupleKind: {- wasm::rehash(digest, info.tuple);- return digest;- }- case wasm::TypeInfo::RefKind: {- wasm::rehash(digest, info.ref.heapType);- wasm::rehash(digest, info.ref.nullable);- return digest;- }- case wasm::TypeInfo::RttKind: {- wasm::rehash(digest, info.rtt);- return digest;- }- }- WASM_UNREACHABLE("unexpected kind");- }-};--size_t hash<wasm::Type>::operator()(const wasm::Type& type) const {- return wasm::hash(type.getID());-}--size_t hash<wasm::Tuple>::operator()(const wasm::Tuple& tuple) const {- return wasm::hash(tuple.types);-}--size_t hash<wasm::Signature>::operator()(const wasm::Signature& sig) const {- auto digest = wasm::hash(sig.params);- wasm::rehash(digest, sig.results);- return digest;-}--size_t hash<wasm::Field>::operator()(const wasm::Field& field) const {- auto digest = wasm::hash(field.type);- wasm::rehash(digest, field.packedType);- wasm::rehash(digest, field.mutable_);- return digest;-}--size_t hash<wasm::Struct>::operator()(const wasm::Struct& struct_) const {- return wasm::hash(struct_.fields);-}--size_t hash<wasm::Array>::operator()(const wasm::Array& array) const {- return wasm::hash(array.element);-}--size_t hash<wasm::HeapType>::operator()(const wasm::HeapType& heapType) const {- auto digest = wasm::hash(heapType.kind);- switch (heapType.kind) {- case wasm::HeapType::FuncKind:- case wasm::HeapType::ExternKind:- case wasm::HeapType::AnyKind:- case wasm::HeapType::EqKind:- case wasm::HeapType::I31Kind:- case wasm::HeapType::ExnKind:- return digest;- case wasm::HeapType::SignatureKind:- wasm::rehash(digest, heapType.signature);- return digest;- case wasm::HeapType::StructKind:- wasm::rehash(digest, heapType.struct_);- return digest;- case wasm::HeapType::ArrayKind:- wasm::rehash(digest, heapType.array);- return digest;- }- WASM_UNREACHABLE("unexpected kind");-}--size_t hash<wasm::Rtt>::operator()(const wasm::Rtt& rtt) const {- auto digest = wasm::hash(rtt.depth);- wasm::rehash(digest, rtt.heapType);- return digest;-}--} // namespace std--namespace wasm {--namespace {--std::mutex mutex;--// Track unique_ptrs for constructed types to avoid leaks-std::vector<std::unique_ptr<TypeInfo>> constructedTypes;--// Maps from constructed types to the canonical Type ID.-std::unordered_map<TypeInfo, uintptr_t> indices = {- // If a Type is constructed from a list of types, the list of types becomes- // implicitly converted to a TypeInfo before canonicalizing its id. This is- // also the case if a list of just one type is provided, even though such a- // list of types will be canonicalized to the BasicID of the single type. As- // such, the following entries are solely placeholders to enable the lookup- // of lists of just one type to the BasicID of the single type.- {TypeInfo(Tuple()), Type::none},- {TypeInfo({Type::unreachable}), Type::unreachable},- {TypeInfo({Type::i32}), Type::i32},- {TypeInfo({Type::i64}), Type::i64},- {TypeInfo({Type::f32}), Type::f32},- {TypeInfo({Type::f64}), Type::f64},- {TypeInfo({Type::v128}), Type::v128},- {TypeInfo({Type::funcref}), Type::funcref},- {TypeInfo(HeapType(HeapType::FuncKind), true), Type::funcref},- {TypeInfo({Type::externref}), Type::externref},- {TypeInfo(HeapType(HeapType::ExternKind), true), Type::externref},- {TypeInfo({Type::exnref}), Type::exnref},- {TypeInfo(HeapType(HeapType::ExnKind), true), Type::exnref},- {TypeInfo({Type::anyref}), Type::anyref},- {TypeInfo(HeapType(HeapType::AnyKind), true), Type::anyref},- {TypeInfo({Type::eqref}), Type::eqref},- {TypeInfo(HeapType(HeapType::EqKind), true), Type::eqref},- {TypeInfo({Type::i31ref}), Type::i31ref},- {TypeInfo(HeapType(HeapType::I31Kind), false), Type::i31ref},-};--} // anonymous namespace--static uintptr_t canonicalize(const TypeInfo& info) {- std::lock_guard<std::mutex> lock(mutex);- auto indexIt = indices.find(info);- if (indexIt != indices.end()) {- return indexIt->second;- }- auto ptr = std::make_unique<TypeInfo>(info);- auto id = uintptr_t(ptr.get());- constructedTypes.push_back(std::move(ptr));- assert(id > Type::_last_basic_id);- indices[info] = id;- return id;-}--static TypeInfo* getTypeInfo(const Type& type) {- return (TypeInfo*)type.getID();-}--Type::Type(std::initializer_list<Type> types) : Type(Tuple(types)) {}--Type::Type(const Tuple& tuple) {- auto& types = tuple.types;-#ifndef NDEBUG- for (Type t : types) {- assert(t.isSingle());- }-#endif- if (types.size() == 0) {- id = none;- return;- }- if (types.size() == 1) {- *this = types[0];- return;- }- id = canonicalize(TypeInfo(tuple));-}--Type::Type(const HeapType& heapType, bool nullable) {-#ifndef NDEBUG- switch (heapType.kind) {- case HeapType::FuncKind:- case HeapType::ExternKind:- case HeapType::AnyKind:- case HeapType::EqKind:- case HeapType::I31Kind:- case HeapType::ExnKind:- case HeapType::SignatureKind:- break;- case HeapType::StructKind:- for (Field f : heapType.struct_.fields) {- assert(f.type.isSingle());- }- break;- case HeapType::ArrayKind:- assert(heapType.array.element.type.isSingle());- break;- }-#endif- id = canonicalize(TypeInfo(heapType, nullable));-}--Type::Type(const Rtt& rtt) { id = canonicalize(TypeInfo(rtt)); }--bool Type::isTuple() const {- if (isBasic()) {- return false;- } else {- return getTypeInfo(*this)->isTuple();- }-}--bool Type::isRef() const {- if (isBasic()) {- return id >= funcref && id <= i31ref;- } else {- return getTypeInfo(*this)->isRef();- }-}--bool Type::isFunction() const {- if (isBasic()) {- return id == funcref;- } else {- auto* info = getTypeInfo(*this);- return info->isRef() && info->ref.heapType.isSignature();- }-}--bool Type::isException() const {- if (isBasic()) {- return id == exnref;- } else {- auto* info = getTypeInfo(*this);- return info->isRef() && info->ref.heapType.isException();- }-}--bool Type::isNullable() const {- if (isBasic()) {- return id >= funcref && id <= eqref; // except i31ref- } else {- return getTypeInfo(*this)->isNullable();- }-}--bool Type::isRtt() const {- if (isBasic()) {- return false;- } else {- return getTypeInfo(*this)->isRtt();- }-}--bool Type::operator<(const Type& other) const {- return std::lexicographical_compare(begin(),- end(),- other.begin(),- other.end(),- [](const Type& a, const Type& b) {- TODO_SINGLE_COMPOUND(a);- TODO_SINGLE_COMPOUND(b);- return a.getBasic() < b.getBasic();- });-}--unsigned Type::getByteSize() const {- // TODO: alignment?- auto getSingleByteSize = [](Type t) {- switch (t.getBasic()) {- case Type::i32:- case Type::f32:- return 4;- case Type::i64:- case Type::f64:- return 8;- case Type::v128:- return 16;- case Type::funcref:- case Type::externref:- case Type::exnref:- case Type::anyref:- case Type::eqref:- case Type::i31ref:- case Type::none:- case Type::unreachable:- break;- }- WASM_UNREACHABLE("invalid type");- };-- if (isTuple()) {- unsigned size = 0;- for (const auto& t : *this) {- size += getSingleByteSize(t);- }- return size;- }- return getSingleByteSize(*this);-}--Type Type::reinterpret() const {- assert(!isTuple() && "Unexpected tuple type");- switch ((*begin()).getBasic()) {- case Type::i32:- return f32;- case Type::i64:- return f64;- case Type::f32:- return i32;- case Type::f64:- return i64;- default:- WASM_UNREACHABLE("invalid type");- }-}--FeatureSet Type::getFeatures() const {- auto getSingleFeatures = [](Type t) -> FeatureSet {- TODO_SINGLE_COMPOUND(t);- switch (t.getBasic()) {- case Type::v128:- return FeatureSet::SIMD;- case Type::funcref:- case Type::externref:- return FeatureSet::ReferenceTypes;- case Type::exnref:- return FeatureSet::ReferenceTypes | FeatureSet::ExceptionHandling;- case Type::anyref:- case Type::eqref:- case Type::i31ref:- return FeatureSet::ReferenceTypes | FeatureSet::GC;- default:- return FeatureSet::MVP;- }- };-- if (isTuple()) {- FeatureSet feats = FeatureSet::Multivalue;- for (const auto& t : *this) {- feats |= getSingleFeatures(t);- }- return feats;- }- return getSingleFeatures(*this);-}--HeapType Type::getHeapType() const {- if (isRef()) {- if (isCompound()) {- return getTypeInfo(*this)->ref.heapType;- }- switch (getBasic()) {- case funcref:- return HeapType::FuncKind;- case externref:- return HeapType::ExternKind;- case exnref:- return HeapType::ExnKind;- case anyref:- return HeapType::AnyKind;- case eqref:- return HeapType::EqKind;- case i31ref:- return HeapType::I31Kind;- default:- break;- }- }- WASM_UNREACHABLE("unexpected type");-}--Type Type::get(unsigned byteSize, bool float_) {- if (byteSize < 4) {- return Type::i32;- }- if (byteSize == 4) {- return float_ ? Type::f32 : Type::i32;- }- if (byteSize == 8) {- return float_ ? Type::f64 : Type::i64;- }- if (byteSize == 16) {- return Type::v128;- }- WASM_UNREACHABLE("invalid size");-}--bool Type::isSubType(Type left, Type right) {- if (left == right) {- return true;- }- if (left.isRef() && right.isRef()) {- return right == Type::anyref ||- (left == Type::i31ref && right == Type::eqref);- }- if (left.isTuple() && right.isTuple()) {- if (left.size() != right.size()) {- return false;- }- for (size_t i = 0; i < left.size(); ++i) {- if (!isSubType(left[i], right[i])) {- return false;- }- }- return true;- }- return false;-}--Type Type::getLeastUpperBound(Type a, Type b) {- if (a == b) {- return a;- }- if (a == Type::unreachable) {- return b;- }- if (b == Type::unreachable) {- return a;- }- if (a.size() != b.size()) {- return Type::none; // a poison value that must not be consumed- }- if (a.isRef()) {- if (b.isRef()) {- if ((a == Type::i31ref && b == Type::eqref) ||- (a == Type::eqref && b == Type::i31ref)) {- return Type::eqref;- }- // The LUB of two different reference types is anyref, which may or may- // not be a valid type depending on whether the anyref feature is enabled.- // When anyref is disabled, it is possible for the finalization of invalid- // code to introduce a use of anyref via this function, but that is not a- // problem because it will be caught and rejected by validation.- return Type::anyref;- }- return Type::none;- }- if (a.isTuple()) {- TypeList types;- types.resize(a.size());- for (size_t i = 0; i < types.size(); ++i) {- types[i] = getLeastUpperBound(a[i], b[i]);- if (types[i] == Type::none) {- return Type::none;- }- }- return Type(types);- }- return Type::none;-}--Type::Iterator Type::end() const {- if (isTuple()) {- return Iterator(this, getTypeInfo(*this)->tuple.types.size());- } else {- // TODO: unreachable is special and expands to {unreachable} currently.- // see also: https://github.com/WebAssembly/binaryen/issues/3062- return Iterator(this, size_t(id != Type::none));- }-}--const Type& Type::Iterator::operator*() const {- if (parent->isTuple()) {- return getTypeInfo(*parent)->tuple.types[index];- } else {- // TODO: see comment in Type::end()- assert(index == 0 && parent->id != Type::none && "Index out of bounds");- return *parent;- }-}--const Type& Type::operator[](size_t index) const {- if (isTuple()) {- return getTypeInfo(*this)->tuple.types[index];- } else {- assert(index == 0 && "Index out of bounds");- return *begin();- }-}--HeapType::HeapType(const HeapType& other) : kind(other.kind) {- switch (kind) {- case FuncKind:- case ExternKind:- case AnyKind:- case EqKind:- case I31Kind:- case ExnKind:- return;- case SignatureKind:- new (&signature) auto(other.signature);- return;- case StructKind:- new (&struct_) auto(other.struct_);- return;- case ArrayKind:- new (&array) auto(other.array);- return;- }- WASM_UNREACHABLE("unexpected kind");-}--HeapType::~HeapType() {- switch (kind) {- case FuncKind:- case ExternKind:- case AnyKind:- case EqKind:- case I31Kind:- case ExnKind:- return;- case SignatureKind:- signature.~Signature();- return;- case StructKind:- struct_.~Struct();- return;- case ArrayKind:- array.~Array();- return;- }-}--bool HeapType::operator==(const HeapType& other) const {- if (kind != other.kind) {- return false;- }- switch (kind) {- case FuncKind:- case ExternKind:- case AnyKind:- case EqKind:- case I31Kind:- case ExnKind:- return true;- case SignatureKind:- return signature == other.signature;- case StructKind:- return struct_ == other.struct_;- case ArrayKind:- return array == other.array;- }- WASM_UNREACHABLE("unexpected kind");-}--HeapType& HeapType::operator=(const HeapType& other) {- if (&other != this) {- this->~HeapType();- new (this) auto(other);- }- return *this;-}--namespace {--std::ostream&-printPrefixedTypes(std::ostream& os, const char* prefix, Type type) {- os << '(' << prefix;- for (const auto& t : type) {- os << " " << t;- }- os << ')';- return os;-}--template<typename T> std::string genericToString(const T& t) {- std::ostringstream ss;- ss << t;- return ss.str();-}--} // anonymous namespace--std::string Type::toString() const { return genericToString(*this); }--std::string ParamType::toString() const { return genericToString(*this); }--std::string ResultType::toString() const { return genericToString(*this); }--std::string Tuple::toString() const { return genericToString(*this); }--std::string Signature::toString() const { return genericToString(*this); }--std::string Struct::toString() const { return genericToString(*this); }--std::string Array::toString() const { return genericToString(*this); }--std::string HeapType::toString() const { return genericToString(*this); }--std::string Rtt::toString() const { return genericToString(*this); }--std::string TypeInfo::toString() const { return genericToString(*this); }--bool Signature::operator<(const Signature& other) const {- if (results < other.results) {- return true;- } else if (other.results < results) {- return false;- } else {- return params < other.params;- }-}--std::ostream& operator<<(std::ostream& os, Type type) {- if (type.isBasic()) {- switch (type.getBasic()) {- case Type::none:- os << "none";- break;- case Type::unreachable:- os << "unreachable";- break;- case Type::i32:- os << "i32";- break;- case Type::i64:- os << "i64";- break;- case Type::f32:- os << "f32";- break;- case Type::f64:- os << "f64";- break;- case Type::v128:- os << "v128";- break;- case Type::funcref:- os << "funcref";- break;- case Type::externref:- os << "externref";- break;- case Type::exnref:- os << "exnref";- break;- case Type::anyref:- os << "anyref";- break;- case Type::eqref:- os << "eqref";- break;- case Type::i31ref:- os << "i31ref";- break;- }- } else {- os << *getTypeInfo(type);- }- return os;-}--std::ostream& operator<<(std::ostream& os, ParamType param) {- return printPrefixedTypes(os, "param", param.type);-}--std::ostream& operator<<(std::ostream& os, ResultType param) {- return printPrefixedTypes(os, "result", param.type);-}--std::ostream& operator<<(std::ostream& os, Tuple tuple) {- auto& types = tuple.types;- auto size = types.size();- os << "(";- if (size) {- os << types[0];- for (size_t i = 1; i < size; ++i) {- os << " " << types[i];- }- }- return os << ")";-}--std::ostream& operator<<(std::ostream& os, Signature sig) {- os << "(func";- if (sig.params.getID() != Type::none) {- os << " ";- printPrefixedTypes(os, "param", sig.params);- }- if (sig.results.getID() != Type::none) {- os << " ";- printPrefixedTypes(os, "result", sig.results);- }- return os << ")";-}--std::ostream& operator<<(std::ostream& os, Field field) {- if (field.mutable_) {- os << "(mut ";- }- if (field.isPacked()) {- auto packedType = field.packedType;- if (packedType == Field::PackedType::i8) {- os << "i8";- } else if (packedType == Field::PackedType::i16) {- os << "i16";- } else {- WASM_UNREACHABLE("unexpected packed type");- }- } else {- os << field.type;- }- if (field.mutable_) {- os << ")";- }- return os;-};--std::ostream& operator<<(std::ostream& os, Struct struct_) {- os << "(struct";- if (struct_.fields.size()) {- os << " (field";- for (auto f : struct_.fields) {- os << " " << f;- }- os << ")";- }- return os << ")";-}--std::ostream& operator<<(std::ostream& os, Array array) {- return os << "(array " << array.element << ")";-}--std::ostream& operator<<(std::ostream& os, HeapType heapType) {- switch (heapType.kind) {- case wasm::HeapType::FuncKind:- return os << "func";- case wasm::HeapType::ExternKind:- return os << "extern";- case wasm::HeapType::AnyKind:- return os << "any";- case wasm::HeapType::EqKind:- return os << "eq";- case wasm::HeapType::I31Kind:- return os << "i31";- case wasm::HeapType::ExnKind:- return os << "exn";- case wasm::HeapType::SignatureKind:- return os << heapType.signature;- case wasm::HeapType::StructKind:- return os << heapType.struct_;- case wasm::HeapType::ArrayKind:- return os << heapType.array;- }- WASM_UNREACHABLE("unexpected kind");-}--std::ostream& operator<<(std::ostream& os, Rtt rtt) {- return os << "(rtt " << rtt.depth << " " << rtt.heapType << ")";-}--std::ostream& operator<<(std::ostream& os, TypeInfo info) {- switch (info.kind) {- case TypeInfo::TupleKind: {- return os << info.tuple;- }- case TypeInfo::RefKind: {- os << "(ref ";- if (info.ref.nullable) {- os << "null ";- }- return os << info.ref.heapType << ")";- }- case TypeInfo::RttKind: {- return os << info.rtt;- }- }- WASM_UNREACHABLE("unexpected kind");-}--} // namespace wasm+#include <unordered_set>++#include "compiler-support.h"+#include "support/hash.h"+#include "wasm-features.h"+#include "wasm-type.h"++namespace wasm {++namespace {++struct TypeInfo {+ using type_t = Type;+ enum Kind {+ TupleKind,+ RefKind,+ RttKind,+ } kind;+ struct Ref {+ HeapType heapType;+ Nullability nullable;+ };+ union {+ Tuple tuple;+ Ref ref;+ Rtt rtt;+ };++ TypeInfo(const Tuple& tuple) : kind(TupleKind), tuple(tuple) {}+ TypeInfo(Tuple&& tuple) : kind(TupleKind), tuple(std::move(tuple)) {}+ TypeInfo(HeapType heapType, Nullability nullable)+ : kind(RefKind), ref{heapType, nullable} {}+ TypeInfo(Rtt rtt) : kind(RttKind), rtt(rtt) {}+ TypeInfo(const TypeInfo& other);+ ~TypeInfo();++ constexpr bool isTuple() const { return kind == TupleKind; }+ constexpr bool isRef() const { return kind == RefKind; }+ constexpr bool isRtt() const { return kind == RttKind; }++ bool isNullable() const { return kind == RefKind && ref.nullable; }++ bool operator==(const TypeInfo& other) const;+ bool operator!=(const TypeInfo& other) const { return !(*this == other); }+ bool operator<(const TypeInfo& other) const;+};++struct HeapTypeInfo {+ using type_t = HeapType;+ enum Kind {+ SignatureKind,+ StructKind,+ ArrayKind,+ } kind;+ union {+ Signature signature;+ Struct struct_;+ Array array;+ };++ HeapTypeInfo(Signature sig) : kind(SignatureKind), signature(sig) {}+ HeapTypeInfo(const Struct& struct_) : kind(StructKind), struct_(struct_) {}+ HeapTypeInfo(Struct&& struct_)+ : kind(StructKind), struct_(std::move(struct_)) {}+ HeapTypeInfo(Array array) : kind(ArrayKind), array(array) {}+ HeapTypeInfo(const HeapTypeInfo& other);+ ~HeapTypeInfo();++ constexpr bool isSignature() const { return kind == SignatureKind; }+ constexpr bool isStruct() const { return kind == StructKind; }+ constexpr bool isArray() const { return kind == ArrayKind; }++ HeapTypeInfo& operator=(const HeapTypeInfo& other);+ bool operator==(const HeapTypeInfo& other) const;+ bool operator!=(const HeapTypeInfo& other) const { return !(*this == other); }+ bool operator<(const HeapTypeInfo& other) const;+};++} // anonymous namespace+} // namespace wasm++namespace std {++template<> class hash<wasm::TypeInfo> {+public:+ size_t operator()(const wasm::TypeInfo&) const;+};++template<> class hash<wasm::HeapTypeInfo> {+public:+ size_t operator()(const wasm::HeapTypeInfo&) const;+};++} // namespace std++namespace wasm {+namespace {++TypeInfo* getTypeInfo(Type type) {+ assert(type.isCompound());+ return (TypeInfo*)type.getID();+}++HeapTypeInfo* getHeapTypeInfo(HeapType ht) {+ assert(ht.isCompound());+ return (HeapTypeInfo*)ht.getID();+}++TypeInfo::TypeInfo(const TypeInfo& other) {+ kind = other.kind;+ switch (kind) {+ case TupleKind:+ new (&tuple) auto(other.tuple);+ return;+ case RefKind:+ new (&ref) auto(other.ref);+ return;+ case RttKind:+ new (&rtt) auto(other.rtt);+ return;+ }+ WASM_UNREACHABLE("unexpected kind");+}++TypeInfo::~TypeInfo() {+ switch (kind) {+ case TupleKind:+ tuple.~Tuple();+ return;+ case RefKind:+ ref.~Ref();+ return;+ case RttKind:+ rtt.~Rtt();+ return;+ }+ WASM_UNREACHABLE("unexpected kind");+}++bool TypeInfo::operator==(const TypeInfo& other) const {+ if (kind != other.kind) {+ return false;+ }+ switch (kind) {+ case TupleKind:+ return tuple == other.tuple;+ case RefKind:+ return ref.heapType == other.ref.heapType &&+ ref.nullable == other.ref.nullable;+ case RttKind:+ return rtt == other.rtt;+ }+ WASM_UNREACHABLE("unexpected kind");+}++bool TypeInfo::operator<(const TypeInfo& other) const {+ if (kind != other.kind) {+ return kind < other.kind;+ }+ switch (kind) {+ case TupleKind:+ return tuple < other.tuple;+ case RefKind:+ if (ref.nullable != other.ref.nullable) {+ return ref.nullable < other.ref.nullable;+ }+ return ref.heapType < other.ref.heapType;+ case RttKind:+ return rtt < other.rtt;+ }+ WASM_UNREACHABLE("unexpected kind");+}++HeapTypeInfo::HeapTypeInfo(const HeapTypeInfo& other) {+ kind = other.kind;+ switch (kind) {+ case SignatureKind:+ new (&signature) auto(other.signature);+ return;+ case StructKind:+ new (&struct_) auto(other.struct_);+ return;+ case ArrayKind:+ new (&array) auto(other.array);+ return;+ }+ WASM_UNREACHABLE("unexpected kind");+}++HeapTypeInfo::~HeapTypeInfo() {+ switch (kind) {+ case SignatureKind:+ signature.~Signature();+ return;+ case StructKind:+ struct_.~Struct();+ return;+ case ArrayKind:+ array.~Array();+ return;+ }+ WASM_UNREACHABLE("unexpected kind");+}++HeapTypeInfo& HeapTypeInfo::operator=(const HeapTypeInfo& other) {+ if (&other != this) {+ this->~HeapTypeInfo();+ new (this) HeapTypeInfo(other);+ }+ return *this;+}++bool HeapTypeInfo::operator==(const HeapTypeInfo& other) const {+ if (kind != other.kind) {+ return false;+ }+ switch (kind) {+ case SignatureKind:+ return signature == other.signature;+ case StructKind:+ return struct_ == other.struct_;+ case ArrayKind:+ return array == other.array;+ }+ WASM_UNREACHABLE("unexpected kind");+}++bool HeapTypeInfo::operator<(const HeapTypeInfo& other) const {+ if (kind != other.kind) {+ return kind < other.kind;+ }+ switch (kind) {+ case SignatureKind:+ return signature < other.signature;+ case StructKind:+ return struct_ < other.struct_;+ case ArrayKind:+ return array < other.array;+ }+ WASM_UNREACHABLE("unexpected kind");+}++template<typename Info> struct Store {+ std::mutex mutex;++ // Track unique_ptrs for constructed types to avoid leaks.+ std::vector<std::unique_ptr<Info>> constructedTypes;++ // Maps from constructed types to their canonical Type IDs.+ std::unordered_map<Info, uintptr_t> typeIDs;++ typename Info::type_t canonicalize(const Info& info) {+ std::lock_guard<std::mutex> lock(mutex);+ auto indexIt = typeIDs.find(info);+ if (indexIt != typeIDs.end()) {+ return typename Info::type_t(indexIt->second);+ }+ auto ptr = std::make_unique<Info>(info);+ auto id = uintptr_t(ptr.get());+ constructedTypes.push_back(std::move(ptr));+ assert(id > Info::type_t::_last_basic_type);+ typeIDs[info] = id;+ return typename Info::type_t(id);+ }+};++struct TypeStore : Store<TypeInfo> {+ Type canonicalize(TypeInfo info) {+ if (info.isTuple()) {+ if (info.tuple.types.size() == 0) {+ return Type::none;+ }+ if (info.tuple.types.size() == 1) {+ return info.tuple.types[0];+ }+ }+ if (info.isRef() && info.ref.heapType.isBasic()) {+ if (info.ref.nullable) {+ switch (info.ref.heapType.getBasic()) {+ case HeapType::func:+ return Type::funcref;+ case HeapType::ext:+ return Type::externref;+ case HeapType::exn:+ return Type::exnref;+ case HeapType::any:+ return Type::anyref;+ case HeapType::eq:+ return Type::eqref;+ case HeapType::i31:+ break;+ }+ } else {+ if (info.ref.heapType == HeapType::i31) {+ return Type::i31ref;+ }+ }+ }+ return Store<TypeInfo>::canonicalize(info);+ }+};++using HeapTypeStore = Store<HeapTypeInfo>;++TypeStore globalTypeStore;+HeapTypeStore globalHeapTypeStore;++// Specialized to simplify programming generically over Types and HeapTypes.+template<typename T> struct MetaTypeInfo {};++template<> struct MetaTypeInfo<Type> {+ constexpr static TypeStore& globalStore = globalTypeStore;+ static TypeInfo* getInfo(Type type) { return getTypeInfo(type); }+};++template<> struct MetaTypeInfo<HeapType> {+ constexpr static HeapTypeStore& globalStore = globalHeapTypeStore;+ static HeapTypeInfo* getInfo(HeapType ht) { return getHeapTypeInfo(ht); }+};++} // anonymous namespace++Type::Type(std::initializer_list<Type> types) : Type(Tuple(types)) {}++Type::Type(const Tuple& tuple) {+ new (this) Type(globalTypeStore.canonicalize(tuple));+}++Type::Type(Tuple&& tuple) {+ new (this) Type(globalTypeStore.canonicalize(std::move(tuple)));+}++Type::Type(HeapType heapType, Nullability nullable) {+ new (this) Type(globalTypeStore.canonicalize(TypeInfo(heapType, nullable)));+}++Type::Type(Rtt rtt) { new (this) Type(globalTypeStore.canonicalize(rtt)); }++bool Type::isTuple() const {+ if (isBasic()) {+ return false;+ } else {+ return getTypeInfo(*this)->isTuple();+ }+}++bool Type::isRef() const {+ if (isBasic()) {+ return id >= funcref && id <= i31ref;+ } else {+ return getTypeInfo(*this)->isRef();+ }+}++bool Type::isFunction() const {+ if (isBasic()) {+ return id == funcref;+ } else {+ auto* info = getTypeInfo(*this);+ return info->isRef() && info->ref.heapType.isFunction();+ }+}++bool Type::isException() const {+ if (isBasic()) {+ return id == exnref;+ } else {+ auto* info = getTypeInfo(*this);+ return info->isRef() && info->ref.heapType == HeapType::exn;+ }+}++bool Type::isNullable() const {+ if (isBasic()) {+ return id >= funcref && id <= eqref; // except i31ref+ } else {+ return getTypeInfo(*this)->isNullable();+ }+}++bool Type::isRtt() const {+ if (isBasic()) {+ return false;+ } else {+ return getTypeInfo(*this)->isRtt();+ }+}++bool Type::isStruct() const { return isRef() && getHeapType().isStruct(); }++bool Type::isArray() const { return isRef() && getHeapType().isArray(); }++bool Type::operator<(const Type& other) const {+ if (*this == other) {+ return false;+ }+ if (isBasic() && other.isBasic()) {+ return getBasic() < other.getBasic();+ }+ if (isBasic()) {+ return true;+ }+ if (other.isBasic()) {+ return false;+ }+ return *getTypeInfo(*this) < *getTypeInfo(other);+};++unsigned Type::getByteSize() const {+ // TODO: alignment?+ auto getSingleByteSize = [](Type t) {+ switch (t.getBasic()) {+ case Type::i32:+ case Type::f32:+ return 4;+ case Type::i64:+ case Type::f64:+ return 8;+ case Type::v128:+ return 16;+ case Type::funcref:+ case Type::externref:+ case Type::exnref:+ case Type::anyref:+ case Type::eqref:+ case Type::i31ref:+ case Type::none:+ case Type::unreachable:+ break;+ }+ WASM_UNREACHABLE("invalid type");+ };++ if (isTuple()) {+ unsigned size = 0;+ for (const auto& t : *this) {+ size += getSingleByteSize(t);+ }+ return size;+ }+ return getSingleByteSize(*this);+}++Type Type::reinterpret() const {+ assert(!isTuple() && "Unexpected tuple type");+ switch ((*begin()).getBasic()) {+ case Type::i32:+ return f32;+ case Type::i64:+ return f64;+ case Type::f32:+ return i32;+ case Type::f64:+ return i64;+ default:+ WASM_UNREACHABLE("invalid type");+ }+}++FeatureSet Type::getFeatures() const {+ auto getSingleFeatures = [](Type t) -> FeatureSet {+ if (t.isRef()) {+ // A reference type implies we need that feature. Some also require more,+ // such as GC or exceptions.+ auto heapType = t.getHeapType();+ if (heapType.isStruct() || heapType.isArray()) {+ return FeatureSet::ReferenceTypes | FeatureSet::GC;+ }+ if (heapType.isBasic()) {+ switch (heapType.getBasic()) {+ case HeapType::BasicHeapType::exn:+ return FeatureSet::ReferenceTypes | FeatureSet::ExceptionHandling;+ case HeapType::BasicHeapType::any:+ case HeapType::BasicHeapType::eq:+ case HeapType::BasicHeapType::i31:+ return FeatureSet::ReferenceTypes | FeatureSet::GC;+ default: {}+ }+ }+ // Note: Technically typed function references also require the typed+ // function references feature, however, we use these types internally+ // regardless of the presence of features (in particular, since during+ // load of the wasm we don't know the features yet, so we apply the more+ // refined types), so we don't add that in any case here.+ return FeatureSet::ReferenceTypes;+ } else if (t.isRtt()) {+ return FeatureSet::ReferenceTypes | FeatureSet::GC;+ }+ TODO_SINGLE_COMPOUND(t);+ switch (t.getBasic()) {+ case Type::v128:+ return FeatureSet::SIMD;+ default:+ return FeatureSet::MVP;+ }+ };++ if (isTuple()) {+ FeatureSet feats = FeatureSet::Multivalue;+ for (const auto& t : *this) {+ feats |= getSingleFeatures(t);+ }+ return feats;+ }+ return getSingleFeatures(*this);+}++HeapType Type::getHeapType() const {+ if (isBasic()) {+ switch (getBasic()) {+ case Type::none:+ case Type::unreachable:+ case Type::i32:+ case Type::i64:+ case Type::f32:+ case Type::f64:+ case Type::v128:+ break;+ case Type::funcref:+ return HeapType::func;+ case Type::externref:+ return HeapType::ext;+ case Type::exnref:+ return HeapType::exn;+ case Type::anyref:+ return HeapType::any;+ case Type::eqref:+ return HeapType::eq;+ case Type::i31ref:+ return HeapType::i31;+ }+ WASM_UNREACHABLE("Unexpected type");+ } else {+ auto* info = getTypeInfo(*this);+ switch (info->kind) {+ case TypeInfo::TupleKind:+ break;+ case TypeInfo::RefKind:+ return info->ref.heapType;+ case TypeInfo::RttKind:+ return info->rtt.heapType;+ }+ WASM_UNREACHABLE("Unexpected type");+ }+}++Rtt Type::getRtt() const {+ assert(isRtt());+ return getTypeInfo(*this)->rtt;+}++Type Type::get(unsigned byteSize, bool float_) {+ if (byteSize < 4) {+ return Type::i32;+ }+ if (byteSize == 4) {+ return float_ ? Type::f32 : Type::i32;+ }+ if (byteSize == 8) {+ return float_ ? Type::f64 : Type::i64;+ }+ if (byteSize == 16) {+ return Type::v128;+ }+ WASM_UNREACHABLE("invalid size");+}++bool Type::isSubType(Type left, Type right) {+ if (left == right) {+ return true;+ }+ if (left.isRef() && right.isRef()) {+ // Everything is a subtype of anyref.+ if (right == Type::anyref) {+ return true;+ }+ // Various things are subtypes of eqref.+ auto leftHeap = left.getHeapType();+ auto rightHeap = right.getHeapType();+ if ((leftHeap == HeapType::i31 || leftHeap.isArray() ||+ leftHeap.isStruct()) &&+ rightHeap == HeapType::eq &&+ (!left.isNullable() || right.isNullable())) {+ return true;+ }+ // All typed function signatures are subtypes of funcref.+ if (leftHeap.isSignature() && rightHeap == HeapType::func &&+ (!left.isNullable() || right.isNullable())) {+ return true;+ }+ // A non-nullable type is a supertype of a nullable one+ if (leftHeap == rightHeap && !left.isNullable()) {+ // The only difference is the nullability.+ assert(right.isNullable());+ return true;+ }+ return false;+ }+ if (left.isTuple() && right.isTuple()) {+ if (left.size() != right.size()) {+ return false;+ }+ for (size_t i = 0; i < left.size(); ++i) {+ if (!isSubType(left[i], right[i])) {+ return false;+ }+ }+ return true;+ }+ if (left.isRtt() && right.isRtt()) {+ auto leftRtt = left.getRtt();+ auto rightRtt = right.getRtt();+ // (rtt n $x) is a subtype of (rtt $x), that is, if the only difference in+ // information is that the left side specifies a depth while the right side+ // allows any depth.+ return leftRtt.heapType == rightRtt.heapType && leftRtt.hasDepth() &&+ !rightRtt.hasDepth();+ }+ return false;+}++Type Type::getLeastUpperBound(Type a, Type b) {+ if (a == b) {+ return a;+ }+ if (a == Type::unreachable) {+ return b;+ }+ if (b == Type::unreachable) {+ return a;+ }+ if (a.size() != b.size()) {+ return Type::none; // a poison value that must not be consumed+ }+ if (a.isRef()) {+ if (b.isRef()) {+ if (a.isFunction() && b.isFunction()) {+ return Type::funcref;+ }+ if ((a == Type::i31ref && b == Type::eqref) ||+ (a == Type::eqref && b == Type::i31ref)) {+ return Type::eqref;+ }+ // The LUB of two different reference types is anyref, which may or may+ // not be a valid type depending on whether the anyref feature is enabled.+ // When anyref is disabled, it is possible for the finalization of invalid+ // code to introduce a use of anyref via this function, but that is not a+ // problem because it will be caught and rejected by validation.+ return Type::anyref;+ }+ return Type::none;+ }+ if (a.isTuple()) {+ TypeList types;+ types.resize(a.size());+ for (size_t i = 0; i < types.size(); ++i) {+ types[i] = getLeastUpperBound(a[i], b[i]);+ if (types[i] == Type::none) {+ return Type::none;+ }+ }+ return Type(types);+ }+ return Type::none;+}++Type::Iterator Type::end() const {+ if (isTuple()) {+ return Iterator(this, getTypeInfo(*this)->tuple.types.size());+ } else {+ // TODO: unreachable is special and expands to {unreachable} currently.+ // see also: https://github.com/WebAssembly/binaryen/issues/3062+ return Iterator(this, size_t(id != Type::none));+ }+}++const Type& Type::Iterator::operator*() const {+ if (parent->isTuple()) {+ return getTypeInfo(*parent)->tuple.types[index];+ } else {+ // TODO: see comment in Type::end()+ assert(index == 0 && parent->id != Type::none && "Index out of bounds");+ return *parent;+ }+}++const Type& Type::operator[](size_t index) const {+ if (isTuple()) {+ return getTypeInfo(*this)->tuple.types[index];+ } else {+ assert(index == 0 && "Index out of bounds");+ return *begin();+ }+}++HeapType::HeapType(Signature signature) {+ new (this) HeapType(globalHeapTypeStore.canonicalize(signature));+}++HeapType::HeapType(const Struct& struct_) {+ new (this) HeapType(globalHeapTypeStore.canonicalize(struct_));+}++HeapType::HeapType(Struct&& struct_) {+ new (this) HeapType(globalHeapTypeStore.canonicalize(std::move(struct_)));+}++HeapType::HeapType(Array array) {+ new (this) HeapType(globalHeapTypeStore.canonicalize(array));+}++bool HeapType::isFunction() const {+ if (isBasic()) {+ return id == func;+ } else {+ return getHeapTypeInfo(*this)->isSignature();+ }+}++bool HeapType::isSignature() const {+ if (isBasic()) {+ return false;+ } else {+ return getHeapTypeInfo(*this)->isSignature();+ }+}++bool HeapType::isStruct() const {+ if (isBasic()) {+ return false;+ } else {+ return getHeapTypeInfo(*this)->isStruct();+ }+}++bool HeapType::operator<(const HeapType& other) const {+ if (*this == other) {+ return false;+ }+ if (isBasic() && other.isBasic()) {+ return getBasic() < other.getBasic();+ }+ if (isBasic()) {+ return true;+ }+ if (other.isBasic()) {+ return false;+ }+ return *getHeapTypeInfo(*this) < *getHeapTypeInfo(other);+}++bool HeapType::isArray() const {+ if (isBasic()) {+ return false;+ } else {+ return getHeapTypeInfo(*this)->isArray();+ }+}++Signature HeapType::getSignature() const {+ assert(isSignature());+ return getHeapTypeInfo(*this)->signature;+}++const Struct& HeapType::getStruct() const {+ assert(isStruct());+ return getHeapTypeInfo(*this)->struct_;+}++Array HeapType::getArray() const {+ assert(isArray());+ return getHeapTypeInfo(*this)->array;+}++bool Signature::operator<(const Signature& other) const {+ if (results != other.results) {+ return results < other.results;+ }+ return params < other.params;+}++bool Field::operator<(const Field& other) const {+ if (mutable_ != other.mutable_) {+ return mutable_ < other.mutable_;+ }+ if (type == Type::i32 && other.type == Type::i32) {+ return packedType < other.packedType;+ }+ return type < other.type;+}++bool Rtt::operator<(const Rtt& other) const {+ if (depth != other.depth) {+ return depth < other.depth;+ }+ return heapType < other.heapType;+}++namespace {++std::ostream&+printPrefixedTypes(std::ostream& os, const char* prefix, Type type) {+ os << '(' << prefix;+ for (const auto& t : type) {+ os << " " << t;+ }+ os << ')';+ return os;+}++template<typename T> std::string genericToString(const T& t) {+ std::ostringstream ss;+ ss << t;+ return ss.str();+}++} // anonymous namespace++std::string Type::toString() const { return genericToString(*this); }++std::string ParamType::toString() const { return genericToString(*this); }++std::string ResultType::toString() const { return genericToString(*this); }++std::string Tuple::toString() const { return genericToString(*this); }++std::string Signature::toString() const { return genericToString(*this); }++std::string Struct::toString() const { return genericToString(*this); }++std::string Array::toString() const { return genericToString(*this); }++std::string HeapType::toString() const { return genericToString(*this); }++std::string Rtt::toString() const { return genericToString(*this); }++std::ostream& operator<<(std::ostream&, TypeInfo);+std::ostream& operator<<(std::ostream&, HeapTypeInfo);++std::ostream& operator<<(std::ostream& os, Type type) {+ if (type.isBasic()) {+ switch (type.getBasic()) {+ case Type::none:+ return os << "none";+ case Type::unreachable:+ return os << "unreachable";+ case Type::i32:+ return os << "i32";+ case Type::i64:+ return os << "i64";+ case Type::f32:+ return os << "f32";+ case Type::f64:+ return os << "f64";+ case Type::v128:+ return os << "v128";+ case Type::funcref:+ return os << "funcref";+ case Type::externref:+ return os << "externref";+ case Type::exnref:+ return os << "exnref";+ case Type::anyref:+ return os << "anyref";+ case Type::eqref:+ return os << "eqref";+ case Type::i31ref:+ return os << "i31ref";+ }+ }+ return os << *getTypeInfo(type);+}++std::ostream& operator<<(std::ostream& os, ParamType param) {+ return printPrefixedTypes(os, "param", param.type);+}++std::ostream& operator<<(std::ostream& os, ResultType param) {+ return printPrefixedTypes(os, "result", param.type);+}++std::ostream& operator<<(std::ostream& os, Tuple tuple) {+ auto& types = tuple.types;+ auto size = types.size();+ os << "(";+ if (size) {+ os << types[0];+ for (size_t i = 1; i < size; ++i) {+ os << " " << types[i];+ }+ }+ return os << ")";+}++std::ostream& operator<<(std::ostream& os, Signature sig) {+ os << "(func";+ if (sig.params.getID() != Type::none) {+ os << " ";+ printPrefixedTypes(os, "param", sig.params);+ }+ if (sig.results.getID() != Type::none) {+ os << " ";+ printPrefixedTypes(os, "result", sig.results);+ }+ return os << ")";+}++std::ostream& operator<<(std::ostream& os, Field field) {+ if (field.mutable_) {+ os << "(mut ";+ }+ if (field.isPacked()) {+ auto packedType = field.packedType;+ if (packedType == Field::PackedType::i8) {+ os << "i8";+ } else if (packedType == Field::PackedType::i16) {+ os << "i16";+ } else {+ WASM_UNREACHABLE("unexpected packed type");+ }+ } else {+ os << field.type;+ }+ if (field.mutable_) {+ os << ")";+ }+ return os;+};++std::ostream& operator<<(std::ostream& os, Struct struct_) {+ os << "(struct";+ if (struct_.fields.size()) {+ os << " (field";+ for (auto f : struct_.fields) {+ os << " " << f;+ }+ os << ")";+ }+ return os << ")";+}++std::ostream& operator<<(std::ostream& os, Array array) {+ return os << "(array " << array.element << ")";+}++std::ostream& operator<<(std::ostream& os, HeapType heapType) {+ if (heapType.isBasic()) {+ switch (heapType.getBasic()) {+ case HeapType::func:+ return os << "func";+ case HeapType::ext:+ return os << "extern";+ case HeapType::exn:+ return os << "exn";+ case HeapType::any:+ return os << "any";+ case HeapType::eq:+ return os << "eq";+ case HeapType::i31:+ return os << "i31";+ }+ }+ return os << *getHeapTypeInfo(heapType);+}++std::ostream& operator<<(std::ostream& os, Rtt rtt) {+ return os << "(rtt " << rtt.depth << " " << rtt.heapType << ")";+}++std::ostream& operator<<(std::ostream& os, TypeInfo info) {+ switch (info.kind) {+ case TypeInfo::TupleKind: {+ return os << info.tuple;+ }+ case TypeInfo::RefKind: {+ os << "(ref ";+ if (info.ref.nullable) {+ os << "null ";+ }+ return os << info.ref.heapType << ")";+ }+ case TypeInfo::RttKind: {+ return os << info.rtt;+ }+ }+ WASM_UNREACHABLE("unexpected kind");+}++std::ostream& operator<<(std::ostream& os, HeapTypeInfo info) {+ switch (info.kind) {+ case HeapTypeInfo::SignatureKind:+ return os << info.signature;+ case HeapTypeInfo::StructKind:+ return os << info.struct_;+ case HeapTypeInfo::ArrayKind:+ return os << info.array;+ }+ WASM_UNREACHABLE("unexpected kind");+}++struct TypeBuilder::Impl {+ TypeStore typeStore;+ HeapTypeStore heapTypeStore;++ struct Entry {+ // HeapTypeInfo has no default constructor, so pick an arbitrary default.+ HeapTypeInfo info = Signature();+ bool initialized = false;+ void set(HeapTypeInfo&& hti) {+ info = hti;+ initialized = true;+ }+ HeapType get() { return HeapType(TypeID(&info)); }+ };++ std::vector<Entry> entries;+};++TypeBuilder::TypeBuilder(size_t n) {+ impl = std::make_unique<TypeBuilder::Impl>();+ impl->entries.resize(n);+}++TypeBuilder::~TypeBuilder() = default;++void TypeBuilder::setHeapType(size_t i, Signature signature) {+ assert(i < impl->entries.size() && "Index out of bounds");+ impl->entries[i].set(signature);+}++void TypeBuilder::setHeapType(size_t i, const Struct& struct_) {+ assert(i < impl->entries.size() && "index out of bounds");+ impl->entries[i].set(struct_);+}++void TypeBuilder::setHeapType(size_t i, Struct&& struct_) {+ assert(i < impl->entries.size() && "index out of bounds");+ impl->entries[i].set(std::move(struct_));+}++void TypeBuilder::setHeapType(size_t i, Array array) {+ assert(i < impl->entries.size() && "index out of bounds");+ impl->entries[i].set(array);+}++Type TypeBuilder::getTempTupleType(const Tuple& tuple) {+ return impl->typeStore.canonicalize(tuple);+}++Type TypeBuilder::getTempRefType(size_t i, Nullability nullable) {+ assert(i < impl->entries.size() && "Index out of bounds");+ return impl->typeStore.canonicalize(+ TypeInfo(impl->entries[i].get(), nullable));+}++Type TypeBuilder::getTempRttType(size_t i, uint32_t depth) {+ assert(i < impl->entries.size() && "Index out of bounds");+ return impl->typeStore.canonicalize(Rtt(depth, impl->entries[i].get()));+}++namespace {++// Implements the algorithm to canonicalize the HeapTypes in a TypeBuilder,+// replacing and deduplicating the temporary type and heaptypes backed by+// storage owned by the TypeBuilder into normal types and heap types backed by+// the global stores.+struct Canonicalizer {+ TypeBuilder& builder;++ struct Item {+ enum Kind {+ TypeKind,+ HeapTypeKind,+ } kind;+ union {+ Type* type;+ HeapType* heapType;+ };+ Item(Type* type) : kind(TypeKind), type(type) {}+ Item(HeapType* heapType) : kind(HeapTypeKind), heapType(heapType) {}+ };++ // IDs of scanned Types and HeapTypes, used to prevent repeated scanning.+ std::unordered_set<TypeID> scanned;++ // The work list of Types and HeapTypes remaining to be scanned.+ std::vector<Item> scanList;++ // The list of Types and HeapTypes to visit constructed in forward preorder+ // and eventually traversed in reverse to give a reverse postorder.+ std::vector<Item> visitList;++ // Maps Type and HeapType IDs to the IDs of Types and HeapTypes they can+ // reach in the type graph. Only considers compound Types and HeapTypes.+ std::unordered_map<TypeID, std::unordered_set<TypeID>> reaches;++ // Maps Types and HeapTypes backed by the TypeBuilder's Stores to globally+ // canonical Types and HeapTypes.+ std::unordered_map<Type, Type> canonicalTypes;+ std::unordered_map<HeapType, HeapType> canonicalHeapTypes;++ // The fully canonicalized heap types.+ std::vector<HeapType> results;++ Canonicalizer(TypeBuilder& builder);+ template<typename T1, typename T2> void noteChild(T1 parent, T2* child);+ void scanHeapType(HeapType* ht);+ void scanType(Type* child);+ void makeReachabilityFixedPoint();++ // Replaces the pointee Type or HeapType of `type` with its globally canonical+ // equivalent, recording the substitution for future use in either+ // `canonicalTypes` or `canonicalHeapTypes`.+ template<typename T>+ void canonicalize(T* type, std::unordered_map<T, T>& canonicals);+};++// Traverse the type graph rooted at the initialized HeapTypeInfos in reverse+// postorder, replacing in place all Types and HeapTypes backed by the+// TypeBuilder's Stores with equivalent globally canonicalized Types and+// HeapTypes.+Canonicalizer::Canonicalizer(TypeBuilder& builder) : builder(builder) {+ // Initialize `results` to hold all the temporary HeapTypes. Since we are+ // canonicalizing all Types and HeapTypes in place, this will end up holding+ // all the canonicalized HeapTypes instead. Also seed the scan list with these+ // HeapTypes.+ results.reserve(builder.impl->entries.size());+ for (auto& entry : builder.impl->entries) {+ assert(entry.initialized && "Cannot access uninitialized HeapType");+ results.push_back(entry.get());+ scanList.push_back(&results.back());+ }++ // Traverse the type graph reachable from the heap types, calculating+ // reachability and collecting a list of types and heap types that need to be+ // canonicalized. We must scan in depth-first order so that we can do a+ // postorder traversal later.+ while (scanList.size() != 0) {+ auto item = scanList.back();+ scanList.pop_back();+ switch (item.kind) {+ case Item::TypeKind:+ scanType(item.type);+ break;+ case Item::HeapTypeKind:+ scanHeapType(item.heapType);+ break;+ }+ }++ // Check for recursive types and heap types. TODO: pre-canonicalize these into+ // their minimal finite representations.+ makeReachabilityFixedPoint();+ for (auto& reach : reaches) {+ if (reach.second.count(reach.first) != 0) {+ WASM_UNREACHABLE("TODO: support recursive types");+ }+ }++ // Visit the types and heap types in reverse postorder, replacing them with+ // their canonicalized versions.+ for (auto it = visitList.rbegin(); it != visitList.rend(); ++it) {+ switch (it->kind) {+ case Item::TypeKind:+ canonicalize(it->type, canonicalTypes);+ break;+ case Item::HeapTypeKind:+ canonicalize(it->heapType, canonicalHeapTypes);+ break;+ }+ }+}++template<typename T1, typename T2>+void Canonicalizer::noteChild(T1 parent, T2* child) {+ if (child->isCompound()) {+ reaches[parent.getID()].insert(child->getID());+ scanList.push_back(child);+ }+}++void Canonicalizer::scanHeapType(HeapType* ht) {+ assert(ht->isCompound());+ visitList.push_back(ht);+ if (scanned.count(ht->getID())) {+ return;+ }+ scanned.insert(ht->getID());++ auto* info = getHeapTypeInfo(*ht);+ switch (info->kind) {+ case HeapTypeInfo::SignatureKind:+ noteChild(*ht, &info->signature.params);+ noteChild(*ht, &info->signature.results);+ break;+ case HeapTypeInfo::StructKind:+ for (auto& field : info->struct_.fields) {+ noteChild(*ht, &field.type);+ }+ break;+ case HeapTypeInfo::ArrayKind:+ noteChild(*ht, &info->array.element.type);+ break;+ }+};++void Canonicalizer::scanType(Type* type) {+ assert(type->isCompound());+ visitList.push_back(type);+ if (scanned.count(type->getID())) {+ return;+ }+ scanned.insert(type->getID());++ auto* info = getTypeInfo(*type);+ switch (info->kind) {+ case TypeInfo::TupleKind:+ for (auto& child : info->tuple.types) {+ noteChild(*type, &child);+ }+ break;+ case TypeInfo::RefKind:+ noteChild(*type, &info->ref.heapType);+ break;+ case TypeInfo::RttKind:+ noteChild(*type, &info->rtt.heapType);+ break;+ }+}++void Canonicalizer::makeReachabilityFixedPoint() {+ // Naively calculate the transitive closure of the reachability graph.+ bool changed;+ do {+ changed = false;+ for (auto& entry : reaches) {+ auto& reachable = entry.second;+ std::unordered_set<TypeID> nextReachable;+ for (auto& other : reachable) {+ auto& otherReaches = reaches[other];+ nextReachable.insert(otherReaches.begin(), otherReaches.end());+ }+ size_t oldSize = reachable.size();+ reachable.insert(nextReachable.begin(), nextReachable.end());+ if (reachable.size() != oldSize) {+ changed = true;+ }+ }+ } while (changed);+}++template<typename T>+void Canonicalizer::canonicalize(T* type,+ std::unordered_map<T, T>& canonicals) {+ auto it = canonicals.find(*type);+ if (it != canonicals.end()) {+ *type = it->second;+ } else {+ // Get the globally canonicalized version of the type+ auto* info = MetaTypeInfo<T>::getInfo(*type);+ T canonical = MetaTypeInfo<T>::globalStore.canonicalize(*info);+ canonicals.insert({*type, canonical});+ *type = canonical;+ }+}++} // anonymous namespace++std::vector<HeapType> TypeBuilder::build() {+ return Canonicalizer(*this).results;+}++} // namespace wasm++namespace std {++template<> class hash<wasm::TypeList> {+public:+ size_t operator()(const wasm::TypeList& types) const {+ auto digest = wasm::hash(types.size());+ for (auto type : types) {+ wasm::rehash(digest, type);+ }+ return digest;+ }+};++template<> class hash<wasm::FieldList> {+public:+ size_t operator()(const wasm::FieldList& fields) const {+ auto digest = wasm::hash(fields.size());+ for (auto field : fields) {+ wasm::rehash(digest, field);+ }+ return digest;+ }+};++size_t hash<wasm::TypeInfo>::operator()(const wasm::TypeInfo& info) const {+ auto digest = wasm::hash(info.kind);+ switch (info.kind) {+ case wasm::TypeInfo::TupleKind:+ wasm::rehash(digest, info.tuple);+ return digest;+ case wasm::TypeInfo::RefKind:+ wasm::rehash(digest, info.ref.heapType);+ wasm::rehash(digest, info.ref.nullable);+ return digest;+ case wasm::TypeInfo::RttKind:+ wasm::rehash(digest, info.rtt);+ return digest;+ }+ WASM_UNREACHABLE("unexpected kind");+}++size_t hash<wasm::HeapTypeInfo>::+operator()(const wasm::HeapTypeInfo& info) const {+ auto digest = wasm::hash(info.kind);+ switch (info.kind) {+ case wasm::HeapTypeInfo::SignatureKind:+ wasm::rehash(digest, info.signature);+ return digest;+ case wasm::HeapTypeInfo::StructKind:+ wasm::rehash(digest, info.struct_);+ return digest;+ case wasm::HeapTypeInfo::ArrayKind:+ wasm::rehash(digest, info.array);+ return digest;+ }+ WASM_UNREACHABLE("unexpected kind");+}++size_t hash<wasm::Type>::operator()(const wasm::Type& type) const {+ return wasm::hash(type.getID());+}++size_t hash<wasm::Tuple>::operator()(const wasm::Tuple& tuple) const {+ return wasm::hash(tuple.types);+}++size_t hash<wasm::Signature>::operator()(const wasm::Signature& sig) const {+ auto digest = wasm::hash(sig.params);+ wasm::rehash(digest, sig.results);+ return digest;+}++size_t hash<wasm::Field>::operator()(const wasm::Field& field) const {+ auto digest = wasm::hash(field.type);+ wasm::rehash(digest, field.packedType);+ wasm::rehash(digest, field.mutable_);+ // Note that the name is not hashed here - it is pure metadata for printing+ // purposes only.+ return digest;+}++size_t hash<wasm::Struct>::operator()(const wasm::Struct& struct_) const {+ return wasm::hash(struct_.fields);+}++size_t hash<wasm::Array>::operator()(const wasm::Array& array) const {+ return wasm::hash(array.element);+}++size_t hash<wasm::HeapType>::operator()(const wasm::HeapType& heapType) const {+ return wasm::hash(heapType.getID());+}++size_t hash<wasm::Rtt>::operator()(const wasm::Rtt& rtt) const {+ auto digest = wasm::hash(rtt.depth);+ wasm::rehash(digest, rtt.heapType);+ return digest;+}++} // namespace std
binaryen/src/wasm/wasm-validator.cpp view
@@ -25,7 +25,6 @@ #include "ir/stack-utils.h" #include "ir/utils.h" #include "support/colors.h"-#include "wasm-printing.h" #include "wasm-validator.h" #include "wasm.h" @@ -41,10 +40,12 @@ return stream; } -// Extra overload for Expressions, to print type info too+// Extra overload for Expressions, to print their contents. inline std::ostream& printModuleComponent(Expression* curr, std::ostream& stream) {- WasmPrinter::printExpression(curr, stream, false, true) << std::endl;+ if (curr) {+ stream << *curr << '\n';+ } return stream; } @@ -317,6 +318,7 @@ void visitSIMDTernary(SIMDTernary* curr); void visitSIMDShift(SIMDShift* curr); void visitSIMDLoad(SIMDLoad* curr);+ void visitSIMDLoadStoreLane(SIMDLoadStoreLane* curr); void visitMemoryInit(MemoryInit* curr); void visitDataDrop(DataDrop* curr); void visitMemoryCopy(MemoryCopy* curr);@@ -338,6 +340,7 @@ void visitBrOnExn(BrOnExn* curr); void visitTupleMake(TupleMake* curr); void visitTupleExtract(TupleExtract* curr);+ void visitCallRef(CallRef* curr); void visitI31New(I31New* curr); void visitI31Get(I31Get* curr); void visitRefTest(RefTest* curr);@@ -405,6 +408,49 @@ size_t align, Type type, Index bytes, bool isAtomic, Expression* curr); void validateMemBytes(uint8_t bytes, Type type, Expression* curr); + template<typename T> void validateReturnCall(T* curr) {+ shouldBeTrue(!curr->isReturn || getModule()->features.hasTailCall(),+ curr,+ "return_call* requires tail calls to be enabled");+ }++ template<typename T>+ void validateCallParamsAndResult(T* curr, Signature sig) {+ if (!shouldBeTrue(curr->operands.size() == sig.params.size(),+ curr,+ "call* param number must match")) {+ return;+ }+ size_t i = 0;+ for (const auto& param : sig.params) {+ if (!shouldBeSubTypeOrFirstIsUnreachable(curr->operands[i]->type,+ param,+ curr,+ "call param types must match") &&+ !info.quiet) {+ getStream() << "(on argument " << i << ")\n";+ }+ ++i;+ }+ if (curr->isReturn) {+ shouldBeEqual(curr->type,+ Type(Type::unreachable),+ curr,+ "return_call* should have unreachable type");+ shouldBeEqual(+ getFunction()->sig.results,+ sig.results,+ curr,+ "return_call* callee return type must match caller return type");+ } else {+ shouldBeEqualOrFirstIsUnreachable(+ curr->type,+ sig.results,+ curr,+ "call* type must match callee return type");+ }+ }+ Type indexType() { return getModule()->memory.indexType; } }; @@ -747,9 +793,7 @@ } void FunctionValidator::visitCall(Call* curr) {- shouldBeTrue(!curr->isReturn || getModule()->features.hasTailCall(),- curr,- "return_call requires tail calls to be enabled");+ validateReturnCall(curr); if (!info.validateGlobally) { return; }@@ -757,107 +801,16 @@ if (!shouldBeTrue(!!target, curr, "call target must exist")) { return; }- if (!shouldBeTrue(curr->operands.size() == target->sig.params.size(),- curr,- "call param number must match")) {- return;- }- size_t i = 0;- for (const auto& param : target->sig.params) {- if (!shouldBeSubTypeOrFirstIsUnreachable(curr->operands[i]->type,- param,- curr,- "call param types must match") &&- !info.quiet) {- getStream() << "(on argument " << i << ")\n";- }- ++i;- }- if (curr->isReturn) {- shouldBeEqual(curr->type,- Type(Type::unreachable),- curr,- "return_call should have unreachable type");- shouldBeEqual(- getFunction()->sig.results,- target->sig.results,- curr,- "return_call callee return type must match caller return type");- } else {- if (curr->type == Type::unreachable) {- bool hasUnreachableOperand = std::any_of(- curr->operands.begin(), curr->operands.end(), [](Expression* op) {- return op->type == Type::unreachable;- });- shouldBeTrue(- hasUnreachableOperand,- curr,- "calls may only be unreachable if they have unreachable operands");- } else {- shouldBeEqual(curr->type,- target->sig.results,- curr,- "call type must match callee return type");- }- }+ validateCallParamsAndResult(curr, target->sig); } void FunctionValidator::visitCallIndirect(CallIndirect* curr) {- shouldBeTrue(!curr->isReturn || getModule()->features.hasTailCall(),- curr,- "return_call_indirect requires tail calls to be enabled");- if (!info.validateGlobally) {- return;- }+ validateReturnCall(curr); shouldBeEqualOrFirstIsUnreachable(curr->target->type, Type(Type::i32), curr, "indirect call target must be an i32");- if (!shouldBeTrue(curr->operands.size() == curr->sig.params.size(),- curr,- "call param number must match")) {- return;- }- size_t i = 0;- for (const auto& param : curr->sig.params) {- if (!shouldBeSubTypeOrFirstIsUnreachable(curr->operands[i]->type,- param,- curr,- "call param types must match") &&- !info.quiet) {- getStream() << "(on argument " << i << ")\n";- }- ++i;- }- if (curr->isReturn) {- shouldBeEqual(curr->type,- Type(Type::unreachable),- curr,- "return_call_indirect should have unreachable type");- shouldBeEqual(- getFunction()->sig.results,- curr->sig.results,- curr,- "return_call_indirect callee return type must match caller return type");- } else {- if (curr->type == Type::unreachable) {- if (curr->target->type != Type::unreachable) {- bool hasUnreachableOperand = std::any_of(- curr->operands.begin(), curr->operands.end(), [](Expression* op) {- return op->type == Type::unreachable;- });- shouldBeTrue(hasUnreachableOperand,- curr,- "call_indirects may only be unreachable if they have "- "unreachable operands");- }- } else {- shouldBeEqual(curr->type,- curr->sig.results,- curr,- "call_indirect type must match callee return type");- }- }+ validateCallParamsAndResult(curr, curr->sig); } void FunctionValidator::visitConst(Const* curr) {@@ -1267,6 +1220,59 @@ validateAlignment(curr->align, memAlignType, bytes, /*isAtomic=*/false, curr); } +void FunctionValidator::visitSIMDLoadStoreLane(SIMDLoadStoreLane* curr) {+ shouldBeTrue(+ getModule()->memory.exists, curr, "Memory operations require a memory");+ shouldBeTrue(+ getModule()->features.hasSIMD(), curr, "SIMD operation (SIMD is disabled)");+ if (curr->isLoad()) {+ shouldBeEqualOrFirstIsUnreachable(+ curr->type, Type(Type::v128), curr, "loadX_lane must have type v128");+ } else {+ shouldBeEqualOrFirstIsUnreachable(+ curr->type, Type(Type::none), curr, "storeX_lane must have type none");+ }+ shouldBeEqualOrFirstIsUnreachable(+ curr->ptr->type,+ indexType(),+ curr,+ "loadX_lane or storeX_lane address must match memory index type");+ shouldBeEqualOrFirstIsUnreachable(+ curr->vec->type,+ Type(Type::v128),+ curr,+ "loadX_lane or storeX_lane vector argument must have type v128");+ size_t lanes;+ Type memAlignType = Type::none;+ switch (curr->op) {+ case LoadLaneVec8x16:+ case StoreLaneVec8x16:+ lanes = 16;+ memAlignType = Type::i32;+ break;+ case LoadLaneVec16x8:+ case StoreLaneVec16x8:+ lanes = 8;+ memAlignType = Type::i32;+ break;+ case LoadLaneVec32x4:+ case StoreLaneVec32x4:+ lanes = 4;+ memAlignType = Type::i32;+ break;+ case LoadLaneVec64x2:+ case StoreLaneVec64x2:+ lanes = 2;+ memAlignType = Type::i64;+ break;+ default:+ WASM_UNREACHABLE("Unexpected SIMDLoadStoreLane op");+ }+ Index bytes = curr->getMemBytes();+ validateAlignment(curr->align, memAlignType, bytes, /*isAtomic=*/false, curr);+ shouldBeTrue(curr->index < lanes, curr, "invalid lane index");+}+ void FunctionValidator::visitMemoryInit(MemoryInit* curr) { shouldBeTrue(getModule()->features.hasBulkMemory(), curr,@@ -1529,6 +1535,7 @@ case GtUVecI32x4: case GeSVecI32x4: case GeUVecI32x4:+ case EqVecI64x2: case EqVecF32x4: case NeVecF32x4: case LtVecF32x4:@@ -1557,6 +1564,11 @@ case MaxSVecI8x16: case MaxUVecI8x16: case AvgrUVecI8x16:+ case Q15MulrSatSVecI16x8:+ case ExtMulLowSVecI16x8:+ case ExtMulHighSVecI16x8:+ case ExtMulLowUVecI16x8:+ case ExtMulHighUVecI16x8: case AddVecI16x8: case AddSatSVecI16x8: case AddSatUVecI16x8:@@ -1577,9 +1589,17 @@ case MaxSVecI32x4: case MaxUVecI32x4: case DotSVecI16x8ToVecI32x4:+ case ExtMulLowSVecI32x4:+ case ExtMulHighSVecI32x4:+ case ExtMulLowUVecI32x4:+ case ExtMulHighUVecI32x4: case AddVecI64x2: case SubVecI64x2: case MulVecI64x2:+ case ExtMulLowSVecI64x2:+ case ExtMulHighSVecI64x2:+ case ExtMulLowUVecI64x2:+ case ExtMulHighUVecI64x2: case AddVecF32x4: case SubVecF32x4: case MulVecF32x4:@@ -1824,6 +1844,7 @@ curr->value->type, Type(Type::f64), curr, "expected f64 splat value"); break; case NotVec128:+ case PopcntVecI8x16: case AbsVecI8x16: case AbsVecI16x8: case AbsVecI32x4:@@ -1845,6 +1866,10 @@ case FloorVecF64x2: case TruncVecF64x2: case NearestVecF64x2:+ case ExtAddPairwiseSVecI8x16ToI16x8:+ case ExtAddPairwiseUVecI8x16ToI16x8:+ case ExtAddPairwiseSVecI16x8ToI32x4:+ case ExtAddPairwiseUVecI16x8ToI32x4: case TruncSatSVecF32x4ToVecI32x4: case TruncSatUVecF32x4ToVecI32x4: case TruncSatSVecF64x2ToVecI64x2:@@ -1861,6 +1886,10 @@ case WidenHighSVecI16x8ToVecI32x4: case WidenLowUVecI16x8ToVecI32x4: case WidenHighUVecI16x8ToVecI32x4:+ case WidenLowSVecI32x4ToVecI64x2:+ case WidenHighSVecI32x4ToVecI64x2:+ case WidenLowUVecI32x4ToVecI64x2:+ case WidenHighUVecI32x4ToVecI64x2: shouldBeEqual(curr->type, Type(Type::v128), curr, "expected v128 type"); shouldBeEqual( curr->value->type, Type(Type::v128), curr, "expected v128 operand");@@ -1868,14 +1897,13 @@ case AnyTrueVecI8x16: case AnyTrueVecI16x8: case AnyTrueVecI32x4:- case AnyTrueVecI64x2: case AllTrueVecI8x16: case AllTrueVecI16x8: case AllTrueVecI32x4:- case AllTrueVecI64x2: case BitmaskVecI8x16: case BitmaskVecI16x8: case BitmaskVecI32x4:+ case BitmaskVecI64x2: shouldBeEqual(curr->type, Type(Type::i32), curr, "expected i32 type"); shouldBeEqual( curr->value->type, Type(Type::v128), curr, "expected v128 operand");@@ -1944,6 +1972,8 @@ shouldBeTrue(getModule()->features.hasReferenceTypes(), curr, "ref.null requires reference-types to be enabled");+ shouldBeTrue(+ curr->type.isNullable(), curr, "ref.null types must be nullable"); } void FunctionValidator::visitRefIsNull(RefIsNull* curr) {@@ -1960,8 +1990,15 @@ shouldBeTrue(getModule()->features.hasReferenceTypes(), curr, "ref.func requires reference-types to be enabled");+ if (!info.validateGlobally) {+ return;+ } auto* func = getModule()->getFunctionOrNull(curr->func); shouldBeTrue(!!func, curr, "function argument of ref.func must exist");+ shouldBeTrue(curr->type.isFunction(),+ curr,+ "ref.func must have a function reference type");+ // TODO: check for non-nullability } void FunctionValidator::visitRefEq(RefEq* curr) {@@ -2010,13 +2047,13 @@ shouldBeTrue(getModule()->features.hasExceptionHandling(), curr, "throw requires exception-handling to be enabled");- if (!info.validateGlobally) {- return;- } shouldBeEqual(curr->type, Type(Type::unreachable), curr, "throw's type must be unreachable");+ if (!info.validateGlobally) {+ return;+ } auto* event = getModule()->getEventOrNull(curr->event); if (!shouldBeTrue(!!event, curr, "throw's event must exist")) { return;@@ -2127,6 +2164,20 @@ } } +void FunctionValidator::visitCallRef(CallRef* curr) {+ validateReturnCall(curr);+ shouldBeTrue(getModule()->features.hasTypedFunctionReferences(),+ curr,+ "call_ref requires typed-function-references to be enabled");+ if (curr->target->type != Type::unreachable) {+ shouldBeTrue(curr->target->type.isFunction(),+ curr,+ "call_ref target must be a function reference");+ validateCallParamsAndResult(+ curr, curr->target->type.getHeapType().getSignature());+ }+}+ void FunctionValidator::visitI31New(I31New* curr) { shouldBeTrue( getModule()->features.hasGC(), curr, "i31.new requires gc to be enabled");@@ -2140,9 +2191,11 @@ shouldBeTrue(getModule()->features.hasGC(), curr, "i31.get_s/u requires gc to be enabled");+ // FIXME: use i31ref here, which is non-nullable, when we support non-+ // nullability. shouldBeSubTypeOrFirstIsUnreachable( curr->i31->type,- Type::i31ref,+ Type(HeapType::i31, Nullable), curr->i31, "i31.get_s/u's argument should be i31ref"); }@@ -2150,77 +2203,220 @@ void FunctionValidator::visitRefTest(RefTest* curr) { shouldBeTrue( getModule()->features.hasGC(), curr, "ref.test requires gc to be enabled");- WASM_UNREACHABLE("TODO (gc): ref.test");+ if (curr->ref->type != Type::unreachable) {+ shouldBeTrue(+ curr->ref->type.isRef(), curr, "ref.test ref must have ref type");+ }+ if (curr->rtt->type != Type::unreachable) {+ shouldBeTrue(+ curr->rtt->type.isRtt(), curr, "ref.test rtt must have rtt type");+ } } void FunctionValidator::visitRefCast(RefCast* curr) { shouldBeTrue( getModule()->features.hasGC(), curr, "ref.cast requires gc to be enabled");- WASM_UNREACHABLE("TODO (gc): ref.cast");+ if (curr->ref->type != Type::unreachable) {+ shouldBeTrue(+ curr->ref->type.isRef(), curr, "ref.cast ref must have ref type");+ }+ if (curr->rtt->type != Type::unreachable) {+ shouldBeTrue(+ curr->rtt->type.isRtt(), curr, "ref.cast rtt must have rtt type");+ } } void FunctionValidator::visitBrOnCast(BrOnCast* curr) { shouldBeTrue(getModule()->features.hasGC(), curr, "br_on_cast requires gc to be enabled");- WASM_UNREACHABLE("TODO (gc): br_on_cast");+ if (curr->ref->type != Type::unreachable) {+ shouldBeTrue(+ curr->ref->type.isRef(), curr, "br_on_cast ref must have ref type");+ }+ if (curr->rtt->type != Type::unreachable) {+ shouldBeTrue(+ curr->rtt->type.isRtt(), curr, "br_on_cast rtt must have rtt type");+ shouldBeEqual(curr->rtt->type.getHeapType(),+ curr->castType.getHeapType(),+ curr,+ "br_on_cast rtt must have the proper heap type");+ noteBreak(curr->name, curr->castType, curr);+ } } void FunctionValidator::visitRttCanon(RttCanon* curr) { shouldBeTrue( getModule()->features.hasGC(), curr, "rtt.canon requires gc to be enabled");- WASM_UNREACHABLE("TODO (gc): rtt.canon");+ shouldBeTrue(curr->type.isRtt(), curr, "rtt.canon must have RTT type");+ auto rtt = curr->type.getRtt();+ shouldBeEqual(rtt.depth, Index(0), curr, "rtt.canon has a depth of 0"); } void FunctionValidator::visitRttSub(RttSub* curr) { shouldBeTrue( getModule()->features.hasGC(), curr, "rtt.sub requires gc to be enabled");- WASM_UNREACHABLE("TODO (gc): rtt.sub");+ shouldBeTrue(curr->type.isRtt(), curr, "rtt.sub must have RTT type");+ if (curr->parent->type != Type::unreachable) {+ shouldBeTrue(+ curr->parent->type.isRtt(), curr, "rtt.sub parent must have RTT type");+ auto parentRtt = curr->parent->type.getRtt();+ auto rtt = curr->type.getRtt();+ if (rtt.hasDepth() && parentRtt.hasDepth()) {+ shouldBeEqual(rtt.depth,+ parentRtt.depth + 1,+ curr,+ "rtt.canon has a depth of 1 over the parent");+ }+ } } void FunctionValidator::visitStructNew(StructNew* curr) { shouldBeTrue(getModule()->features.hasGC(), curr, "struct.new requires gc to be enabled");- WASM_UNREACHABLE("TODO (gc): struct.new");+ if (curr->type == Type::unreachable) {+ return;+ }+ if (!shouldBeTrue(+ curr->rtt->type.isRtt(), curr, "struct.new rtt must be rtt")) {+ return;+ }+ auto heapType = curr->rtt->type.getHeapType();+ if (!shouldBeTrue(+ heapType.isStruct(), curr, "struct.new heap type must be struct")) {+ return;+ }+ const auto& fields = heapType.getStruct().fields;+ if (curr->isWithDefault()) {+ shouldBeTrue(curr->operands.empty(),+ curr,+ "struct.new_with_default should have no operands");+ // All the fields must be defaultable.+ for (const auto& field : fields) {+ // TODO: add type.isDefaultable()?+ shouldBeTrue(!field.type.isRef() || field.type.isNullable(),+ field,+ "struct.new_with_default value type must be defaultable");+ }+ } else {+ // All the fields must have the proper type.+ for (Index i = 0; i < fields.size(); i++) {+ shouldBeSubType(curr->operands[i]->type,+ fields[i].type,+ curr,+ "struct.new operand must have proper type");+ }+ } } void FunctionValidator::visitStructGet(StructGet* curr) { shouldBeTrue(getModule()->features.hasGC(), curr, "struct.get requires gc to be enabled");- WASM_UNREACHABLE("TODO (gc): struct.get");+ const auto& fields = curr->ref->type.getHeapType().getStruct().fields;+ shouldBeTrue(curr->index < fields.size(), curr, "bad struct.get field");+ auto field = fields[curr->index];+ // If the type is not packed, it must be marked internally as unsigned, by+ // convention.+ if (field.type != Type::i32 || field.packedType == Field::not_packed) {+ shouldBeFalse(curr->signed_, curr, "non-packed get cannot be signed");+ }+ if (curr->ref->type == Type::unreachable) {+ return;+ }+ shouldBeEqual(+ curr->type, field.type, curr, "struct.get must have the proper type"); } void FunctionValidator::visitStructSet(StructSet* curr) { shouldBeTrue(getModule()->features.hasGC(), curr, "struct.set requires gc to be enabled");- WASM_UNREACHABLE("TODO (gc): struct.set");+ if (curr->ref->type != Type::unreachable) {+ const auto& fields = curr->ref->type.getHeapType().getStruct().fields;+ shouldBeTrue(curr->index < fields.size(), curr, "bad struct.get field");+ shouldBeEqual(curr->value->type,+ fields[curr->index].type,+ curr,+ "struct.set must have the proper type");+ } } void FunctionValidator::visitArrayNew(ArrayNew* curr) { shouldBeTrue( getModule()->features.hasGC(), curr, "array.new requires gc to be enabled");- WASM_UNREACHABLE("TODO (gc): array.new");+ shouldBeEqualOrFirstIsUnreachable(+ curr->size->type, Type(Type::i32), curr, "array.new size must be an i32");+ if (curr->type == Type::unreachable) {+ return;+ }+ if (!shouldBeTrue(+ curr->rtt->type.isRtt(), curr, "array.new rtt must be rtt")) {+ return;+ }+ auto heapType = curr->rtt->type.getHeapType();+ if (!shouldBeTrue(+ heapType.isArray(), curr, "array.new heap type must be array")) {+ return;+ }+ const auto& element = heapType.getArray().element;+ if (curr->isWithDefault()) {+ shouldBeTrue(+ !curr->init, curr, "array.new_with_default should have no init");+ // The element must be defaultable.+ // TODO: add type.isDefaultable()?+ shouldBeTrue(!element.type.isRef() || element.type.isNullable(),+ element,+ "array.new_with_default value type must be defaultable");+ } else {+ shouldBeTrue(!!curr->init, curr, "array.new should have an init");+ // The inits must have the proper type.+ shouldBeSubType(curr->init->type,+ element.type,+ curr,+ "array.new init must have proper type");+ } } void FunctionValidator::visitArrayGet(ArrayGet* curr) { shouldBeTrue( getModule()->features.hasGC(), curr, "array.get requires gc to be enabled");- WASM_UNREACHABLE("TODO (gc): array.get");+ shouldBeEqualOrFirstIsUnreachable(+ curr->index->type, Type(Type::i32), curr, "array.get index must be an i32");+ if (curr->type == Type::unreachable) {+ return;+ }+ const auto& element = curr->ref->type.getHeapType().getArray().element;+ // If the type is not packed, it must be marked internally as unsigned, by+ // convention.+ if (element.type != Type::i32 || element.packedType == Field::not_packed) {+ shouldBeFalse(curr->signed_, curr, "non-packed get cannot be signed");+ }+ shouldBeEqual(+ curr->type, element.type, curr, "array.get must have the proper type"); } void FunctionValidator::visitArraySet(ArraySet* curr) { shouldBeTrue( getModule()->features.hasGC(), curr, "array.set requires gc to be enabled");- WASM_UNREACHABLE("TODO (gc): array.set");+ shouldBeEqualOrFirstIsUnreachable(+ curr->index->type, Type(Type::i32), curr, "array.set index must be an i32");+ if (curr->type == Type::unreachable) {+ return;+ }+ const auto& element = curr->ref->type.getHeapType().getArray().element;+ shouldBeEqual(curr->value->type,+ element.type,+ curr,+ "array.set must have the proper type"); } void FunctionValidator::visitArrayLen(ArrayLen* curr) { shouldBeTrue( getModule()->features.hasGC(), curr, "array.len requires gc to be enabled");- WASM_UNREACHABLE("TODO (gc): array.len");+ shouldBeEqualOrFirstIsUnreachable(+ curr->type, Type(Type::i32), curr, "array.len result must be an i32"); } void FunctionValidator::visitFunction(Function* curr) {@@ -2241,9 +2437,10 @@ for (const auto& var : curr->vars) { features |= var.getFeatures(); shouldBeTrue(var.isConcrete(), curr, "vars must be concretely typed");+ // TODO: check for nullability } shouldBeTrue(features <= getModule()->features,- curr,+ curr->name, "all used types should be allowed"); if (curr->profile == IRProfile::Poppy) { shouldBeTrue(
binaryen/src/wasm/wasm.cpp view
@@ -16,7 +16,6 @@ #include "wasm.h" #include "ir/branch-utils.h"-#include "wasm-printing.h" #include "wasm-traversal.h" namespace wasm {@@ -47,6 +46,7 @@ const char* MultivalueFeature = "multivalue"; const char* GCFeature = "gc"; const char* Memory64Feature = "memory64";+const char* TypedFunctionReferencesFeature = "typed-function-references"; } // namespace UserSections } // namespace BinaryConsts @@ -59,6 +59,7 @@ Name NEW_SIZE("newSize"); Name MODULE("module"); Name START("start");+Name GLOBAL("global"); Name FUNC("func"); Name PARAM("param"); Name RESULT("result");@@ -71,6 +72,8 @@ Name ELEM("elem"); Name LOCAL("local"); Name TYPE("type");+Name REF("ref");+Name NULL_("null"); Name CALL("call"); Name CALL_INDIRECT("call_indirect"); Name BLOCK("block");@@ -92,16 +95,10 @@ Name SHARED("shared"); Name EVENT("event"); Name ATTR("attr");-Name ASSIGN_GOT_ENTRIES("__assign_got_enties"); // Expressions -void Expression::dump() {- WasmPrinter::printExpression(this,- std::cerr,- /*minify=*/false,- /*full=*/true);-}+void Expression::dump() { std::cout << *this << '\n'; } const char* getExpressionName(Expression* curr) { switch (curr->_id) {@@ -154,15 +151,15 @@ case Expression::Id::UnreachableId: return "unreachable"; case Expression::Id::AtomicCmpxchgId:- return "atomic_cmpxchg";+ return "atomic.cmpxchg"; case Expression::Id::AtomicRMWId:- return "atomic_rmw";+ return "atomic.rmw"; case Expression::Id::AtomicWaitId:- return "atomic_wait";+ return "atomic.wait"; case Expression::Id::AtomicNotifyId:- return "atomic_notify";+ return "atomic.notify"; case Expression::Id::AtomicFenceId:- return "atomic_fence";+ return "atomic.fence"; case Expression::Id::SIMDExtractId: return "simd_extract"; case Expression::Id::SIMDReplaceId:@@ -175,14 +172,18 @@ return "simd_shift"; case Expression::Id::SIMDLoadId: return "simd_load";+ case Expression::Id::SIMDLoadStoreLaneId:+ return "simd_load_store_lane";+ case Expression::Id::PrefetchId:+ return "prefetch"; case Expression::Id::MemoryInitId:- return "memory_init";+ return "memory.init"; case Expression::Id::DataDropId:- return "data_drop";+ return "data.drop"; case Expression::Id::MemoryCopyId:- return "memory_copy";+ return "memory.copy"; case Expression::Id::MemoryFillId:- return "memory_fill";+ return "memory.fill"; case Expression::Id::PopId: return "pop"; case Expression::Id::RefNullId:@@ -209,6 +210,8 @@ return "i31.new"; case Expression::Id::I31GetId: return "i31.get";+ case Expression::Id::CallRefId:+ return "call_ref"; case Expression::Id::RefTestId: return "ref.test"; case Expression::Id::RefCastId:@@ -260,72 +263,12 @@ } } -// core AST type checking--struct TypeSeeker : public PostWalker<TypeSeeker> {- Expression* target; // look for this one- Name targetName;- std::vector<Type> types;-- TypeSeeker(Expression* target, Name targetName)- : target(target), targetName(targetName) {- Expression* temp = target;- walk(temp);- }-- void visitBreak(Break* curr) {- if (curr->name == targetName) {- types.push_back(curr->value ? curr->value->type : Type::none);- }- }-- void visitSwitch(Switch* curr) {- for (auto name : curr->targets) {- if (name == targetName) {- types.push_back(curr->value ? curr->value->type : Type::none);- }- }- if (curr->default_ == targetName) {- types.push_back(curr->value ? curr->value->type : Type::none);- }- }-- void visitBrOnExn(BrOnExn* curr) {- if (curr->name == targetName) {- types.push_back(curr->sent);- }- }-- void visitBlock(Block* curr) {- if (curr == target) {- if (curr->list.size() > 0) {- types.push_back(curr->list.back()->type);- } else {- types.push_back(Type::none);- }- } else if (curr->name == targetName) {- // ignore all breaks til now, they were captured by someone with the same- // name- types.clear();- }- }-- void visitLoop(Loop* curr) {- if (curr == target) {- types.push_back(curr->body->type);- } else if (curr->name == targetName) {- // ignore all breaks til now, they were captured by someone with the same- // name- types.clear();- }- }-};- // a block is unreachable if one of its elements is unreachable, // and there are no branches to it-static void handleUnreachable(Block* block,- bool breakabilityKnown = false,- bool hasBreak = false) {++static void+handleUnreachable(Block* block,+ Block::Breakability breakability = Block::Unknown) { if (block->type == Type::unreachable) { return; // nothing to do }@@ -343,10 +286,12 @@ if (child->type == Type::unreachable) { // there is an unreachable child, so we are unreachable, unless we have a // break- if (!breakabilityKnown) {- hasBreak = BranchUtils::BranchSeeker::has(block, block->name);+ if (breakability == Block::Unknown) {+ breakability = BranchUtils::BranchSeeker::has(block, block->name)+ ? Block::HasBreak+ : Block::NoBreak; }- if (!hasBreak) {+ if (breakability == Block::NoBreak) { block->type = Type::unreachable; } return;@@ -355,41 +300,35 @@ } void Block::finalize() {+ if (list.size() == 0) {+ type = Type::none;+ return;+ }+ // The default type is what is at the end. Next we need to see if breaks and/+ // or unreachabitily change that.+ type = list.back()->type; if (!name.is()) {- if (list.size() > 0) {- // nothing branches here, so this is easy- // normally the type is the type of the final child- type = list.back()->type;- // and even if we have an unreachable child somewhere,- // we still mark ourselves as having that type,- // (block (result i32)- // (return)- // (i32.const 10)- // )- if (type.isConcrete()) {- return;- }- // if we are unreachable, we are done- if (type == Type::unreachable) {- return;- }- // we may still be unreachable if we have an unreachable- // child- for (auto* child : list) {- if (child->type == Type::unreachable) {- type = Type::unreachable;- return;- }- }+ // Nothing branches here, so this is easy.+ handleUnreachable(this, NoBreak);+ return;+ }++ // The default type is according to the value that flows out.+ BranchUtils::BranchSeeker seeker(this->name);+ Expression* temp = this;+ seeker.walk(temp);+ if (seeker.found) {+ // Take the branch values into account.+ if (seeker.valueType != Type::none) {+ type = Type::getLeastUpperBound(type, seeker.valueType); } else {+ // No value is sent, but as we have a branch we are not unreachable. type = Type::none; }- return;+ } else {+ // There are no branches, so this block may be unreachable.+ handleUnreachable(this, NoBreak); }-- TypeSeeker seeker(this, this->name);- type = Type::mergeTypes(seeker.types);- handleUnreachable(this); } void Block::finalize(Type type_) {@@ -399,10 +338,10 @@ } } -void Block::finalize(Type type_, bool hasBreak) {+void Block::finalize(Type type_, Breakability breakability) { type = type_; if (type == Type::none && list.size() > 0) {- handleUnreachable(this, true, hasBreak);+ handleUnreachable(this, breakability); } } @@ -456,13 +395,16 @@ void Switch::finalize() { type = Type::unreachable; } -template<typename T> void handleUnreachableOperands(T* curr) {+// Sets the type to unreachable if there is an unreachable operand. Returns true+// if so.+template<typename T> bool handleUnreachableOperands(T* curr) { for (auto* child : curr->operands) { if (child->type == Type::unreachable) { curr->type = Type::unreachable;- break;+ return true; } }+ return false; } void Call::finalize() {@@ -674,6 +616,52 @@ WASM_UNREACHABLE("unexpected op"); } +void SIMDLoadStoreLane::finalize() {+ assert(ptr && vec);+ type = isLoad() ? Type::v128 : Type::none;+ if (ptr->type == Type::unreachable || vec->type == Type::unreachable) {+ type = Type::unreachable;+ }+}++Index SIMDLoadStoreLane::getMemBytes() {+ switch (op) {+ case LoadLaneVec8x16:+ case StoreLaneVec8x16:+ return 1;+ case LoadLaneVec16x8:+ case StoreLaneVec16x8:+ return 2;+ case LoadLaneVec32x4:+ case StoreLaneVec32x4:+ return 4;+ case LoadLaneVec64x2:+ case StoreLaneVec64x2:+ return 8;+ }+ WASM_UNREACHABLE("unexpected op");+}++bool SIMDLoadStoreLane::isStore() {+ switch (op) {+ case StoreLaneVec8x16:+ case StoreLaneVec16x8:+ case StoreLaneVec32x4:+ case StoreLaneVec64x2:+ return true;+ case LoadLaneVec16x8:+ case LoadLaneVec32x4:+ case LoadLaneVec64x2:+ case LoadLaneVec8x16:+ return false;+ }+ WASM_UNREACHABLE("unexpected op");+}++void Prefetch::finalize() {+ type = ptr->type == Type::unreachable ? Type::unreachable : Type::none;+}+ Const* Const::set(Literal value_) { value = value_; type = value.type;@@ -782,6 +770,7 @@ case AbsVecI8x16: case AbsVecI16x8: case AbsVecI32x4:+ case PopcntVecI8x16: case NegVecI8x16: case NegVecI16x8: case NegVecI32x4:@@ -800,6 +789,10 @@ case FloorVecF64x2: case TruncVecF64x2: case NearestVecF64x2:+ case ExtAddPairwiseSVecI8x16ToI16x8:+ case ExtAddPairwiseUVecI8x16ToI16x8:+ case ExtAddPairwiseSVecI16x8ToI32x4:+ case ExtAddPairwiseUVecI16x8ToI32x4: case TruncSatSVecF32x4ToVecI32x4: case TruncSatUVecF32x4ToVecI32x4: case TruncSatSVecF64x2ToVecI64x2:@@ -816,19 +809,22 @@ case WidenHighSVecI16x8ToVecI32x4: case WidenLowUVecI16x8ToVecI32x4: case WidenHighUVecI16x8ToVecI32x4:+ case WidenLowSVecI32x4ToVecI64x2:+ case WidenHighSVecI32x4ToVecI64x2:+ case WidenLowUVecI32x4ToVecI64x2:+ case WidenHighUVecI32x4ToVecI64x2: type = Type::v128; break; case AnyTrueVecI8x16: case AnyTrueVecI16x8: case AnyTrueVecI32x4:- case AnyTrueVecI64x2: case AllTrueVecI8x16: case AllTrueVecI16x8: case AllTrueVecI32x4:- case AllTrueVecI64x2: case BitmaskVecI8x16: case BitmaskVecI16x8: case BitmaskVecI32x4:+ case BitmaskVecI64x2: type = Type::i32; break; @@ -920,15 +916,13 @@ } } -void RefNull::finalize(HeapType heapType) { type = Type(heapType, true); }+void RefNull::finalize(HeapType heapType) { type = Type(heapType, Nullable); } void RefNull::finalize(Type type_) {- assert(type_ == Type::unreachable || type_.isNullable()); type = type_; } void RefNull::finalize() {- assert(type == Type::unreachable || type.isNullable()); } void RefIsNull::finalize() {@@ -939,8 +933,13 @@ type = Type::i32; } -void RefFunc::finalize() { type = Type::funcref; }+void RefFunc::finalize() {+ // No-op. We assume that the full proper typed function type has been applied+ // previously.+} +void RefFunc::finalize(Type type_) { type = type_; }+ void RefEq::finalize() { if (left->type == Type::unreachable || right->type == Type::unreachable) { type = Type::unreachable;@@ -1009,19 +1008,138 @@ } } -// TODO (gc): ref.test-// TODO (gc): ref.cast-// TODO (gc): br_on_cast-// TODO (gc): rtt.canon-// TODO (gc): rtt.sub-// TODO (gc): struct.new-// TODO (gc): struct.get-// TODO (gc): struct.set-// TODO (gc): array.new-// TODO (gc): array.get-// TODO (gc): array.set-// TODO (gc): array.len+void CallRef::finalize() {+ handleUnreachableOperands(this);+ if (isReturn) {+ type = Type::unreachable;+ }+ if (target->type == Type::unreachable) {+ type = Type::unreachable;+ }+} +void CallRef::finalize(Type type_) {+ type = type_;+ finalize();+}++void RefTest::finalize() {+ if (ref->type == Type::unreachable || rtt->type == Type::unreachable) {+ type = Type::unreachable;+ } else {+ type = Type::i32;+ }+}++// Helper to get the cast type for a cast instruction. They all look at the rtt+// operand's type.+template<typename T> static Type doGetCastType(T* curr) {+ if (curr->rtt->type == Type::unreachable) {+ // We don't have the RTT type, so just return unreachable. The type in this+ // case should not matter in practice, but it may be seen while debugging.+ return Type::unreachable;+ }+ // TODO: make non-nullable when we support that+ return Type(curr->rtt->type.getHeapType(), Nullable);+}++Type RefTest::getCastType() { return doGetCastType(this); }++void RefCast::finalize() {+ if (ref->type == Type::unreachable || rtt->type == Type::unreachable) {+ type = Type::unreachable;+ } else {+ type = getCastType();+ }+}++Type RefCast::getCastType() { return doGetCastType(this); }++void BrOnCast::finalize() {+ if (ref->type == Type::unreachable || rtt->type == Type::unreachable) {+ type = Type::unreachable;+ } else {+ type = ref->type;+ }+}++Type BrOnCast::getCastType() { return castType; }++void RttCanon::finalize() {+ // Nothing to do - the type must have been set already during construction.+}++void RttSub::finalize() {+ if (parent->type == Type::unreachable) {+ type = Type::unreachable;+ }+ // Else nothing to do - the type must have been set already during+ // construction.+}++void StructNew::finalize() {+ if (rtt->type == Type::unreachable) {+ type = Type::unreachable;+ return;+ }+ if (handleUnreachableOperands(this)) {+ return;+ }+ // TODO: make non-nullable when we support that+ type = Type(rtt->type.getHeapType(), Nullable);+}++void StructGet::finalize() {+ if (ref->type == Type::unreachable) {+ type = Type::unreachable;+ } else {+ type = ref->type.getHeapType().getStruct().fields[index].type;+ }+}++void StructSet::finalize() {+ if (ref->type == Type::unreachable) {+ type = Type::unreachable;+ } else {+ type = Type::none;+ }+}++void ArrayNew::finalize() {+ if (rtt->type == Type::unreachable || size->type == Type::unreachable ||+ (init && init->type == Type::unreachable)) {+ type = Type::unreachable;+ return;+ }+ // TODO: make non-nullable when we support that+ type = Type(rtt->type.getHeapType(), Nullable);+}++void ArrayGet::finalize() {+ if (ref->type == Type::unreachable || index->type == Type::unreachable) {+ type = Type::unreachable;+ } else {+ type = ref->type.getHeapType().getArray().element.type;+ }+}++void ArraySet::finalize() {+ if (ref->type == Type::unreachable || index->type == Type::unreachable ||+ value->type == Type::unreachable) {+ type = Type::unreachable;+ } else {+ type = Type::none;+ }+}++void ArrayLen::finalize() {+ if (ref->type == Type::unreachable) {+ type = Type::unreachable;+ } else {+ type = Type::i32;+ }+}+ size_t Function::getNumParams() { return sig.params.size(); } size_t Function::getNumVars() { return vars.size(); }@@ -1197,20 +1315,20 @@ return addModuleElement(events, eventsMap, curr, "addEvent"); } -Export* Module::addExport(std::unique_ptr<Export> curr) {+Export* Module::addExport(std::unique_ptr<Export>&& curr) { return addModuleElement(exports, exportsMap, std::move(curr), "addExport"); } -Function* Module::addFunction(std::unique_ptr<Function> curr) {+Function* Module::addFunction(std::unique_ptr<Function>&& curr) { return addModuleElement( functions, functionsMap, std::move(curr), "addFunction"); } -Global* Module::addGlobal(std::unique_ptr<Global> curr) {+Global* Module::addGlobal(std::unique_ptr<Global>&& curr) { return addModuleElement(globals, globalsMap, std::move(curr), "addGlobal"); } -Event* Module::addEvent(std::unique_ptr<Event> curr) {+Event* Module::addEvent(std::unique_ptr<Event>&& curr) { return addModuleElement(events, eventsMap, std::move(curr), "addEvent"); }
binaryen/src/wasm2js.h view
@@ -92,6 +92,37 @@ return false; } +bool hasActiveSegments(Module& wasm) {+ for (Index i = 0; i < wasm.memory.segments.size(); i++) {+ if (!wasm.memory.segments[i].isPassive) {+ return true;+ }+ }+ return false;+}++bool needsBufferView(Module& wasm) {+ if (!wasm.memory.exists) {+ return false;+ }++ // If there are any active segments, initActiveSegments needs access+ // to bufferView.+ if (hasActiveSegments(wasm)) {+ return true;+ }++ // The special support functions are emitted as part of the JS glue, if we+ // need them.+ bool need = false;+ ModuleUtils::iterImportedFunctions(wasm, [&](Function* import) {+ if (ABI::wasm2js::isHelper(import->base)) {+ need = true;+ }+ });+ return need;+}+ IString stringToIString(std::string str) { return IString(str.c_str(), false); } // Used when taking a wasm name and generating a JS identifier. Each scope here@@ -373,7 +404,7 @@ #ifndef NDEBUG if (!WasmValidator().validate(*wasm)) {- WasmPrinter::printModule(wasm);+ std::cout << *wasm << '\n'; Fatal() << "error in validating wasm2js output"; } #endif@@ -381,9 +412,9 @@ Ref ret = ValueBuilder::makeToplevel(); Ref asmFunc = ValueBuilder::makeFunction(funcName); ret[1]->push_back(asmFunc);- ValueBuilder::appendArgumentToFunction(asmFunc, GLOBAL); ValueBuilder::appendArgumentToFunction(asmFunc, ENV); + // add memory import if (wasm->memory.exists) { if (wasm->memory.imported()) { // find memory and buffer in imports@@ -415,8 +446,15 @@ ValueBuilder::makeName(WASM_MEMORY_GROW)))); } } else {- // find memory as third argument- ValueBuilder::appendArgumentToFunction(asmFunc, BUFFER);+ Ref theVar = ValueBuilder::makeVar();+ asmFunc[3]->push_back(theVar);+ ValueBuilder::appendToVar(+ theVar,+ BUFFER,+ ValueBuilder::makeNew(ValueBuilder::makeCall(+ ValueBuilder::makeName("ArrayBuffer"),+ ValueBuilder::makeInt(Address::address32_t(wasm->memory.initial.addr *+ Memory::kPageSize))))); } } @@ -429,6 +467,7 @@ FUNCTION_TABLE, ValueBuilder::makeDot(ValueBuilder::makeName(ENV), wasm->table.base)); }+ // create heaps, etc addBasics(asmFunc[3], wasm); ModuleUtils::iterImportedFunctions(@@ -479,6 +518,18 @@ asmFunc[3]->push_back(ValueBuilder::makeName("// EMSCRIPTEN_END_FUNCS\n")); } + if (needsBufferView(*wasm)) {+ asmFunc[3]->push_back(+ ValueBuilder::makeBinary(ValueBuilder::makeName("bufferView"),+ SET,+ ValueBuilder::makeName(HEAPU8)));+ }+ if (hasActiveSegments(*wasm)) {+ asmFunc[3]->push_back(+ ValueBuilder::makeCall(ValueBuilder::makeName("initActiveSegments"),+ ValueBuilder::makeName(ENV)));+ }+ addTable(asmFunc[3], wasm); addStart(asmFunc[3], wasm); addExports(asmFunc[3], wasm);@@ -491,12 +542,10 @@ auto addHeap = [&](IString name, IString view) { Ref theVar = ValueBuilder::makeVar(); ast->push_back(theVar);- ValueBuilder::appendToVar(- theVar,- name,- ValueBuilder::makeNew(ValueBuilder::makeCall(- ValueBuilder::makeDot(ValueBuilder::makeName(GLOBAL), view),- ValueBuilder::makeName(BUFFER))));+ ValueBuilder::appendToVar(theVar,+ name,+ ValueBuilder::makeNew(ValueBuilder::makeCall(+ view, ValueBuilder::makeName(BUFFER)))); }; addHeap(HEAP8, INT8ARRAY); addHeap(HEAP16, INT16ARRAY);@@ -512,10 +561,7 @@ Ref theVar = ValueBuilder::makeVar(); ast->push_back(theVar); ValueBuilder::appendToVar(- theVar,- name,- ValueBuilder::makeDot(- ValueBuilder::makeDot(ValueBuilder::makeName(GLOBAL), MATH), base));+ theVar, name, ValueBuilder::makeDot(ValueBuilder::makeName(MATH), base)); }; addMath(MATH_IMUL, IMUL); addMath(MATH_FROUND, FROUND);@@ -525,6 +571,7 @@ addMath(MATH_MAX, MAX); addMath(MATH_FLOOR, FLOOR); addMath(MATH_CEIL, CEIL);+ addMath(MATH_TRUNC, TRUNC); addMath(MATH_SQRT, SQRT); // abort function Ref abortVar = ValueBuilder::makeVar();@@ -537,16 +584,11 @@ // NaN and Infinity variables Ref nanVar = ValueBuilder::makeVar(); ast->push_back(nanVar);- ValueBuilder::appendToVar(- nanVar,- "nan",- ValueBuilder::makeDot(ValueBuilder::makeName(GLOBAL), "NaN"));+ ValueBuilder::appendToVar(nanVar, "nan", ValueBuilder::makeName("NaN")); Ref infinityVar = ValueBuilder::makeVar(); ast->push_back(infinityVar); ValueBuilder::appendToVar(- infinityVar,- "infinity",- ValueBuilder::makeDot(ValueBuilder::makeName(GLOBAL), "Infinity"));+ infinityVar, "infinity", ValueBuilder::makeName("Infinity")); } void Wasm2JSBuilder::addFunctionImport(Ref ast, Function* import) {@@ -1624,6 +1666,11 @@ ret = ValueBuilder::makeCall( MATH_FLOOR, visit(curr->value, EXPRESSION_RESULT)); break;+ case TruncFloat32:+ case TruncFloat64:+ ret = ValueBuilder::makeCall(+ MATH_TRUNC, visit(curr->value, EXPRESSION_RESULT));+ break; case SqrtFloat32: case SqrtFloat64: ret = ValueBuilder::makeCall(@@ -1677,8 +1724,6 @@ // TODO: more complex unary conversions case NearestFloat32: case NearestFloat64:- case TruncFloat32:- case TruncFloat64: WASM_UNREACHABLE( "operation should have been removed in previous passes"); @@ -1939,6 +1984,7 @@ } Ref visitNop(Nop* curr) { return ValueBuilder::makeToplevel(); }+ Ref visitPrefetch(Prefetch* curr) { return ValueBuilder::makeToplevel(); } Ref visitUnreachable(Unreachable* curr) { return ValueBuilder::makeCall(ABORT_FUNC);@@ -1979,22 +2025,22 @@ getHeapAndAdjustedPointer(curr->bytes, curr->ptr, curr->offset); IString target; switch (curr->op) {- case AtomicRMWOp::Add:+ case RMWAdd: target = IString("add"); break;- case AtomicRMWOp::Sub:+ case RMWSub: target = IString("sub"); break;- case AtomicRMWOp::And:+ case RMWAnd: target = IString("and"); break;- case AtomicRMWOp::Or:+ case RMWOr: target = IString("or"); break;- case AtomicRMWOp::Xor:+ case RMWXor: target = IString("xor"); break;- case AtomicRMWOp::Xchg:+ case RMWXchg: target = IString("exchange"); break; default:@@ -2070,6 +2116,10 @@ unimplemented(curr); WASM_UNREACHABLE("unimp"); }+ Ref visitSIMDLoadStoreLane(SIMDLoadStoreLane* curr) {+ unimplemented(curr);+ WASM_UNREACHABLE("unimp");+ } Ref visitMemoryInit(MemoryInit* curr) { ABI::wasm2js::ensureHelpers(module, ABI::wasm2js::MEMORY_INIT); return ValueBuilder::makeCall(ABI::wasm2js::MEMORY_INIT,@@ -2149,6 +2199,10 @@ unimplemented(curr); WASM_UNREACHABLE("unimp"); }+ Ref visitCallRef(CallRef* curr) {+ unimplemented(curr);+ WASM_UNREACHABLE("unimp");+ } Ref visitRefTest(RefTest* curr) { unimplemented(curr); WASM_UNREACHABLE("unimp");@@ -2289,12 +2343,11 @@ Ref newHEAP8 = ValueBuilder::makeVar(); ValueBuilder::appendToBlock(block, newHEAP8);- ValueBuilder::appendToVar(- newHEAP8,- IString("newHEAP8"),- ValueBuilder::makeNew(ValueBuilder::makeCall(- ValueBuilder::makeDot(ValueBuilder::makeName(GLOBAL), INT8ARRAY),- ValueBuilder::makeName(IString("newBuffer")))));+ ValueBuilder::appendToVar(newHEAP8,+ IString("newHEAP8"),+ ValueBuilder::makeNew(ValueBuilder::makeCall(+ ValueBuilder::makeName(INT8ARRAY),+ ValueBuilder::makeName(IString("newBuffer"))))); ValueBuilder::appendToBlock( block,@@ -2303,12 +2356,6 @@ IString("set")), ValueBuilder::makeName(HEAP8))); - ValueBuilder::appendToBlock(- block,- ValueBuilder::makeBinary(ValueBuilder::makeName(HEAP8),- SET,- ValueBuilder::makeName(IString("newHEAP8"))));- auto setHeap = [&](IString name, IString view) { ValueBuilder::appendToBlock( block,@@ -2316,7 +2363,7 @@ ValueBuilder::makeName(name), SET, ValueBuilder::makeNew(ValueBuilder::makeCall(- ValueBuilder::makeDot(ValueBuilder::makeName(GLOBAL), view),+ ValueBuilder::makeName(view), ValueBuilder::makeName(IString("newBuffer")))))); }; @@ -2343,9 +2390,17 @@ ValueBuilder::makeDot(ValueBuilder::makeName("memory"), ValueBuilder::makeName(BUFFER)), SET,- ValueBuilder::makeName(IString("newBuffer"))));+ ValueBuilder::makeName(BUFFER))); } + if (needsBufferView(*wasm)) {+ ValueBuilder::appendToBlock(+ block,+ ValueBuilder::makeBinary(ValueBuilder::makeName("bufferView"),+ SET,+ ValueBuilder::makeName(HEAPU8)));+ }+ memoryGrowFunc[3]->push_back( ValueBuilder::makeReturn(ValueBuilder::makeName(IString("oldPages")))); @@ -2377,9 +2432,7 @@ void emitPostEmscripten(); void emitPostES6(); - void emitMemory(std::string buffer,- std::string segmentWriter,- std::function<std::string(std::string)> accessGlobal);+ void emitMemory(); void emitSpecialSupport(); }; @@ -2411,11 +2464,12 @@ << "}\n\n"; } + emitMemory(); emitSpecialSupport(); } void Wasm2JSGlue::emitPreEmscripten() {- out << "function instantiate(asmLibraryArg, wasmMemory) {\n";+ out << "function instantiate(asmLibraryArg) {\n"; } void Wasm2JSGlue::emitPreES6() {@@ -2462,29 +2516,7 @@ } void Wasm2JSGlue::emitPostEmscripten() {- emitMemory("wasmMemory.buffer", "writeSegment", [](std::string globalName) {- return std::string("asmLibraryArg['") + asmangle(globalName) + "']";- });-- out << "return asmFunc({\n"- << " 'Int8Array': Int8Array,\n"- << " 'Int16Array': Int16Array,\n"- << " 'Int32Array': Int32Array,\n"- << " 'Uint8Array': Uint8Array,\n"- << " 'Uint16Array': Uint16Array,\n"- << " 'Uint32Array': Uint32Array,\n"- << " 'Float32Array': Float32Array,\n"- << " 'Float64Array': Float64Array,\n"- << " 'NaN': NaN,\n"- << " 'Infinity': Infinity,\n"- << " 'Math': Math\n"- << " },\n"- << " asmLibraryArg,\n"- << " wasmMemory.buffer\n"- << ")"- << "\n"- << "\n"- << "}";+ out << " return asmFunc(asmLibraryArg);\n}\n"; } void Wasm2JSGlue::emitPostES6() {@@ -2494,32 +2526,15 @@ // // Note that the translation here expects that the lower values of this memory // can be used for conversions, so make sure there's at least one page.- if (wasm.memory.exists) {+ if (wasm.memory.exists && wasm.memory.imported()) { out << "var mem" << moduleName.str << " = new ArrayBuffer(" << wasm.memory.initial.addr * Memory::kPageSize << ");\n";-- emitMemory(std::string("mem") + moduleName.str,- std::string("assign") + moduleName.str,- [](std::string globalName) { return globalName; }); } // Actually invoke the `asmFunc` generated function, passing in all global // values followed by all imports- out << "var ret" << moduleName.str << " = " << moduleName.str << "({\n"- << " Math,\n"- << " Int8Array,\n"- << " Uint8Array,\n"- << " Int16Array,\n"- << " Uint16Array,\n"- << " Int32Array,\n"- << " Uint32Array,\n"- << " Float32Array,\n"- << " Float64Array,\n"- << " NaN,\n"- << " Infinity\n"- << " }, {\n";-- out << " abort: function() { throw new Error('abort'); }";+ out << "var ret" << moduleName.str << " = " << moduleName.str << "(";+ out << " { abort: function() { throw new Error('abort'); }"; ModuleUtils::iterImportedFunctions(wasm, [&](Function* import) { // The special helpers are emitted in the glue, see code and comments@@ -2549,11 +2564,7 @@ out << ",\n " << asmangle(import->base.str); }); - if (wasm.memory.exists && !wasm.memory.imported()) {- out << "\n },\n mem" << moduleName.str << "\n);\n";- } else {- out << "\n });\n";- }+ out << "\n });\n"; if (flags.allowAsserts) { return;@@ -2584,28 +2595,35 @@ } } -void Wasm2JSGlue::emitMemory(- std::string buffer,- std::string segmentWriter,- std::function<std::string(std::string)> accessGlobal) {- if (!wasm.memory.exists) {- return;- }- // Create a helper bufferView to access the buffer if we need one. We use it- // for creating memory segments if we have any (we may not if the segments are- // shipped in a side .mem file, for example), and also in bulk memory- // operations.- if (!wasm.memory.segments.empty() || wasm.features.hasBulkMemory()) {- out << "var bufferView = new Uint8Array(" << buffer << ");\n";+void Wasm2JSGlue::emitMemory() {+ if (needsBufferView(wasm)) {+ // Create a helper bufferView to access the buffer if we need one. We use it+ // for creating memory segments if we have any (we may not if the segments+ // are shipped in a side .mem file, for example), and also in bulk memory+ // operations.+ // This will get assigned during `asmFunc` (and potentially re-assigned+ // during __wasm_memory_grow).+ // TODO: We should probably just share a single HEAPU8 var.+ out << " var bufferView;\n"; }+ // If there are no memory segments, we don't need to emit any support code for // segment creation.- if (wasm.memory.segments.empty()) {+ if ((!wasm.memory.exists) || wasm.memory.segments.empty()) { return; } + // If we have passive memory segments, we need to store those.+ for (auto& seg : wasm.memory.segments) {+ if (seg.isPassive) {+ out << " var memorySegments = {};\n";+ break;+ }+ }+ out <<- R"(for (var base64ReverseLookup = new Uint8Array(123/*'z'+1*/), i = 25; i >= 0; --i) {+ R"( var base64ReverseLookup = new Uint8Array(123/*'z'+1*/);+ for (var i = 25; i >= 0; --i) { base64ReverseLookup[48+i] = 52+i; // '0-9' base64ReverseLookup[65+i] = i; // 'A-Z' base64ReverseLookup[97+i] = 26+i; // 'a-z'@@ -2628,29 +2646,13 @@ out << R"( return uint8Array;)"; }- out << R"( + out << R"( }- )";-- auto globalOffset = [&](const Memory::Segment& segment) {- if (auto* c = segment.offset->dynCast<Const>()) {- return std::to_string(c->value.getInteger());- }- if (auto* get = segment.offset->dynCast<GlobalGet>()) {- auto internalName = get->name;- auto importedName = wasm.getGlobal(internalName)->base;- return accessGlobal(asmangle(importedName.str));- }- Fatal() << "non-constant offsets aren't supported yet\n";- };+)"; for (Index i = 0; i < wasm.memory.segments.size(); i++) { auto& seg = wasm.memory.segments[i];- if (!seg.isPassive) {- // Plain active segments are decoded directly into the main memory.- out << "base64DecodeToExistingUint8Array(bufferView, "- << globalOffset(seg) << ", \"" << base64Encode(seg.data) << "\");\n";- } else {+ if (seg.isPassive) { // Fancy passive segments are decoded into typed arrays on the side, for // later copying. out << "memorySegments[" << i@@ -2659,6 +2661,32 @@ << ", 0, \"" << base64Encode(seg.data) << "\");\n"; } }++ if (hasActiveSegments(wasm)) {+ auto globalOffset = [&](const Memory::Segment& segment) {+ if (auto* c = segment.offset->dynCast<Const>()) {+ return std::to_string(c->value.getInteger());+ }+ if (auto* get = segment.offset->dynCast<GlobalGet>()) {+ auto internalName = get->name;+ auto importedName = wasm.getGlobal(internalName)->base;+ return std::string("imports[") + asmangle(importedName.str) + "]";+ }+ Fatal() << "non-constant offsets aren't supported yet\n";+ };++ out << "function initActiveSegments(imports) {\n";+ for (Index i = 0; i < wasm.memory.segments.size(); i++) {+ auto& seg = wasm.memory.segments[i];+ if (!seg.isPassive) {+ // Plain active segments are decoded directly into the main memory.+ out << " base64DecodeToExistingUint8Array(bufferView, "+ << globalOffset(seg) << ", \"" << base64Encode(seg.data)+ << "\");\n";+ }+ }+ out << "}\n";+ } } void Wasm2JSGlue::emitSpecialSupport() {@@ -2733,15 +2761,6 @@ var f64ScratchView = new Float64Array(scratchBuffer); )"; - // If we have passive memory segments, or bulk memory operations that operate- // on segment indexes, we need to store those.- bool needMemorySegmentsList = false;- for (auto& seg : wasm.memory.segments) {- if (seg.isPassive) {- needMemorySegmentsList = true;- }- }- ModuleUtils::iterImportedFunctions(wasm, [&](Function* import) { if (import->base == ABI::wasm2js::SCRATCH_STORE_I32) { out << R"(@@ -2780,7 +2799,6 @@ } )"; } else if (import->base == ABI::wasm2js::MEMORY_INIT) {- needMemorySegmentsList = true; out << R"( function wasm2js_memory_init(segment, dest, offset, size) { // TODO: traps on invalid things@@ -2804,7 +2822,6 @@ } )"; } else if (import->base == ABI::wasm2js::DATA_DROP) {- needMemorySegmentsList = true; out << R"( function wasm2js_data_drop(segment) { // TODO: traps on invalid things@@ -2874,12 +2891,6 @@ )"; } });-- if (needMemorySegmentsList) {- out << R"(- var memorySegments = {};- )";- } out << '\n'; }
binaryen/test/atomics.wast view
@@ -138,40 +138,40 @@ (local $0 i32) (local $1 i64) (drop- (i32.atomic.wait+ (memory.atomic.wait32 (local.get $0) (local.get $0) (local.get $1) ) ) (drop- (i32.atomic.wait offset=4 align=4+ (memory.atomic.wait32 offset=4 align=4 (local.get $0) (local.get $0) (local.get $1) ) ) (drop- (atomic.notify+ (memory.atomic.notify (local.get $0) (local.get $0) ) ) (drop- (atomic.notify offset=24 align=4+ (memory.atomic.notify offset=24 align=4 (local.get $0) (local.get $0) ) ) (drop- (i64.atomic.wait+ (memory.atomic.wait64 (local.get $0) (local.get $1) (local.get $1) ) ) (drop- (i64.atomic.wait align=8 offset=16+ (memory.atomic.wait64 align=8 offset=16 (local.get $0) (local.get $1) (local.get $1)
binaryen/test/atomics.wast.from-wast view
@@ -138,40 +138,40 @@ (local $0 i32) (local $1 i64) (drop- (i32.atomic.wait+ (memory.atomic.wait32 (local.get $0) (local.get $0) (local.get $1) ) ) (drop- (i32.atomic.wait offset=4+ (memory.atomic.wait32 offset=4 (local.get $0) (local.get $0) (local.get $1) ) ) (drop- (atomic.notify+ (memory.atomic.notify (local.get $0) (local.get $0) ) ) (drop- (atomic.notify offset=24+ (memory.atomic.notify offset=24 (local.get $0) (local.get $0) ) ) (drop- (i64.atomic.wait+ (memory.atomic.wait64 (local.get $0) (local.get $1) (local.get $1) ) ) (drop- (i64.atomic.wait offset=16+ (memory.atomic.wait64 offset=16 (local.get $0) (local.get $1) (local.get $1)
binaryen/test/atomics.wast.fromBinary view
@@ -138,40 +138,40 @@ (local $0 i32) (local $1 i64) (drop- (i32.atomic.wait+ (memory.atomic.wait32 (local.get $0) (local.get $0) (local.get $1) ) ) (drop- (i32.atomic.wait offset=4+ (memory.atomic.wait32 offset=4 (local.get $0) (local.get $0) (local.get $1) ) ) (drop- (atomic.notify+ (memory.atomic.notify (local.get $0) (local.get $0) ) ) (drop- (atomic.notify offset=24+ (memory.atomic.notify offset=24 (local.get $0) (local.get $0) ) ) (drop- (i64.atomic.wait+ (memory.atomic.wait64 (local.get $0) (local.get $1) (local.get $1) ) ) (drop- (i64.atomic.wait offset=16+ (memory.atomic.wait64 offset=16 (local.get $0) (local.get $1) (local.get $1)
binaryen/test/atomics.wast.fromBinary.noDebugInfo view
@@ -138,40 +138,40 @@ (local $0 i32) (local $1 i64) (drop- (i32.atomic.wait+ (memory.atomic.wait32 (local.get $0) (local.get $0) (local.get $1) ) ) (drop- (i32.atomic.wait offset=4+ (memory.atomic.wait32 offset=4 (local.get $0) (local.get $0) (local.get $1) ) ) (drop- (atomic.notify+ (memory.atomic.notify (local.get $0) (local.get $0) ) ) (drop- (atomic.notify offset=24+ (memory.atomic.notify offset=24 (local.get $0) (local.get $0) ) ) (drop- (i64.atomic.wait+ (memory.atomic.wait64 (local.get $0) (local.get $1) (local.get $1) ) ) (drop- (i64.atomic.wait offset=16+ (memory.atomic.wait64 offset=16 (local.get $0) (local.get $1) (local.get $1)
binaryen/test/atomics64.wast view
@@ -142,40 +142,40 @@ (local $1 i64) (local $2 i32) (drop- (i32.atomic.wait+ (memory.atomic.wait32 (local.get $0) (local.get $2) (local.get $1) ) ) (drop- (i32.atomic.wait offset=4 align=4+ (memory.atomic.wait32 offset=4 align=4 (local.get $0) (local.get $2) (local.get $1) ) ) (drop- (atomic.notify+ (memory.atomic.notify (local.get $0) (local.get $2) ) ) (drop- (atomic.notify offset=24 align=4+ (memory.atomic.notify offset=24 align=4 (local.get $0) (local.get $2) ) ) (drop- (i64.atomic.wait+ (memory.atomic.wait64 (local.get $0) (local.get $1) (local.get $1) ) ) (drop- (i64.atomic.wait align=8 offset=16+ (memory.atomic.wait64 align=8 offset=16 (local.get $0) (local.get $1) (local.get $1)
binaryen/test/atomics64.wast.from-wast view
@@ -142,40 +142,40 @@ (local $1 i64) (local $2 i32) (drop- (i32.atomic.wait+ (memory.atomic.wait32 (local.get $0) (local.get $2) (local.get $1) ) ) (drop- (i32.atomic.wait offset=4+ (memory.atomic.wait32 offset=4 (local.get $0) (local.get $2) (local.get $1) ) ) (drop- (atomic.notify+ (memory.atomic.notify (local.get $0) (local.get $2) ) ) (drop- (atomic.notify offset=24+ (memory.atomic.notify offset=24 (local.get $0) (local.get $2) ) ) (drop- (i64.atomic.wait+ (memory.atomic.wait64 (local.get $0) (local.get $1) (local.get $1) ) ) (drop- (i64.atomic.wait offset=16+ (memory.atomic.wait64 offset=16 (local.get $0) (local.get $1) (local.get $1)
binaryen/test/atomics64.wast.fromBinary view
@@ -142,40 +142,40 @@ (local $1 i64) (local $2 i64) (drop- (i32.atomic.wait+ (memory.atomic.wait32 (local.get $1) (local.get $0) (local.get $2) ) ) (drop- (i32.atomic.wait offset=4+ (memory.atomic.wait32 offset=4 (local.get $1) (local.get $0) (local.get $2) ) ) (drop- (atomic.notify+ (memory.atomic.notify (local.get $1) (local.get $0) ) ) (drop- (atomic.notify offset=24+ (memory.atomic.notify offset=24 (local.get $1) (local.get $0) ) ) (drop- (i64.atomic.wait+ (memory.atomic.wait64 (local.get $1) (local.get $2) (local.get $2) ) ) (drop- (i64.atomic.wait offset=16+ (memory.atomic.wait64 offset=16 (local.get $1) (local.get $2) (local.get $2)
binaryen/test/atomics64.wast.fromBinary.noDebugInfo view
@@ -142,40 +142,40 @@ (local $1 i64) (local $2 i64) (drop- (i32.atomic.wait+ (memory.atomic.wait32 (local.get $1) (local.get $0) (local.get $2) ) ) (drop- (i32.atomic.wait offset=4+ (memory.atomic.wait32 offset=4 (local.get $1) (local.get $0) (local.get $2) ) ) (drop- (atomic.notify+ (memory.atomic.notify (local.get $1) (local.get $0) ) ) (drop- (atomic.notify offset=24+ (memory.atomic.notify offset=24 (local.get $1) (local.get $0) ) ) (drop- (i64.atomic.wait+ (memory.atomic.wait64 (local.get $1) (local.get $2) (local.get $2) ) ) (drop- (i64.atomic.wait offset=16+ (memory.atomic.wait64 offset=16 (local.get $1) (local.get $2) (local.get $2)
− binaryen/test/bad_params.asm.js
@@ -1,30 +0,0 @@-function asm(global, env, buffer) {- "use asm";-- function missing(x, y) {- x = x | 0;- y = +y;- }-- function extra(x, y) {- x = x | 0;- y = +y;- }-- function mix(a) {- a = a | 0;- }-- function ex() {- missing();- missing(1);- extra(1, +2, 3);- extra(1, +2, 3, 4);- mix();- mix(1);- mix(1, 2);- }-- return { ex: ex };-}-
binaryen/test/binaryen.js/atomics.js view
@@ -59,21 +59,21 @@ ), // wait and notify module.drop(- module.i32.atomic.wait(+ module.memory.atomic.wait32( module.i32.const(0), module.i32.const(0), module.i64.const(0) ) ), module.drop(- module.i64.atomic.wait(+ module.memory.atomic.wait64( module.i32.const(0), module.i64.const(0), module.i64.const(0) ) ), module.drop(- module.atomic.notify(+ module.memory.atomic.notify( module.i32.const(0), module.i32.const(0) )
binaryen/test/binaryen.js/atomics.js.txt view
@@ -45,21 +45,21 @@ ) ) (drop- (i32.atomic.wait+ (memory.atomic.wait32 (i32.const 0) (i32.const 0) (i64.const 0) ) ) (drop- (i64.atomic.wait+ (memory.atomic.wait64 (i32.const 0) (i64.const 0) (i64.const 0) ) ) (drop- (atomic.notify+ (memory.atomic.notify (i32.const 0) (i32.const 0) )
binaryen/test/binaryen.js/emit_asmjs.js.txt view
@@ -1,17 +1,18 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function main($0) { $0 = $0 | 0; return $0 | 0;@@ -22,20 +23,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } }); export var main = retasmFunc.main;
binaryen/test/binaryen.js/exception-handling.js.txt view
@@ -28,7 +28,7 @@ ) ) -getExpressionInfo(throw) = {"id":45,"type":1,"event":"e"}-getExpressionInfo(br_on_exn) = {"id":47,"type":9,"name":"l","event":"e"}-getExpressionInfo(rethrow) = {"id":46,"type":1}-getExpressionInfo(try) = {"id":44,"type":0}+getExpressionInfo(throw) = {"id":47,"type":1,"event":"e"}+getExpressionInfo(br_on_exn) = {"id":49,"type":9,"name":"l","event":"e"}+getExpressionInfo(rethrow) = {"id":48,"type":1}+getExpressionInfo(try) = {"id":46,"type":0}
binaryen/test/binaryen.js/expressions.js view
@@ -901,7 +901,7 @@ var ptr = module.i32.const(2); var expected = module.i32.const(3); var timeout = module.i64.const(4);- const theAtomicWait = binaryen.AtomicWait(module.i32.atomic.wait(ptr, expected, timeout));+ const theAtomicWait = binaryen.AtomicWait(module.memory.atomic.wait32(ptr, expected, timeout)); assert(theAtomicWait instanceof binaryen.AtomicWait); assert(theAtomicWait instanceof binaryen.Expression); assert(theAtomicWait.ptr === ptr);@@ -926,7 +926,7 @@ assert( theAtomicWait.toText() ==- "(i64.atomic.wait\n (i32.const 5)\n (i32.const 6)\n (i64.const 7)\n)\n"+ "(memory.atomic.wait64\n (i32.const 5)\n (i32.const 6)\n (i64.const 7)\n)\n" ); module.dispose();@@ -938,7 +938,7 @@ var ptr = module.i32.const(1); var notifyCount = module.i32.const(2);- const theAtomicNotify = binaryen.AtomicNotify(module.atomic.notify(ptr, notifyCount));+ const theAtomicNotify = binaryen.AtomicNotify(module.memory.atomic.notify(ptr, notifyCount)); assert(theAtomicNotify instanceof binaryen.AtomicNotify); assert(theAtomicNotify instanceof binaryen.Expression); assert(theAtomicNotify.ptr === ptr);@@ -957,7 +957,7 @@ assert( theAtomicNotify.toText() ==- "(atomic.notify\n (i32.const 3)\n (i32.const 4)\n)\n"+ "(memory.atomic.notify\n (i32.const 3)\n (i32.const 4)\n)\n" ); module.dispose();@@ -1378,7 +1378,7 @@ const module = new binaryen.Module(); var func = "a";- const theRefFunc = binaryen.RefFunc(module.ref.func(func));+ const theRefFunc = binaryen.RefFunc(module.ref.func(func, binaryen.funcref)); assert(theRefFunc instanceof binaryen.RefFunc); assert(theRefFunc instanceof binaryen.Expression); assert(theRefFunc.func === func);@@ -1388,7 +1388,8 @@ assert(theRefFunc.func === func); theRefFunc.type = binaryen.f64; theRefFunc.finalize();- assert(theRefFunc.type === binaryen.funcref);+ // TODO The type is a subtype of funcref, but we can't check that in the JS+ // API atm. console.log(theRefFunc.toText()); assert(
binaryen/test/binaryen.js/expressions.js.txt view
@@ -128,14 +128,14 @@ ) # AtomicWait-(i64.atomic.wait+(memory.atomic.wait64 (i32.const 5) (i32.const 6) (i64.const 7) ) # AtomicNotify-(atomic.notify+(memory.atomic.notify (i32.const 3) (i32.const 4) )
binaryen/test/binaryen.js/kitchen-sink.js view
@@ -169,6 +169,7 @@ console.log("TupleExtractId: " + binaryen.TupleExtractId); console.log("I31NewId: " + binaryen.I31NewId); console.log("I31GetId: " + binaryen.I31GetId);+ console.log("CallRefId: " + binaryen.CallRefId); console.log("RefTestId: " + binaryen.RefTestId); console.log("RefCastId: " + binaryen.RefCastId); console.log("BrOnCastId: " + binaryen.BrOnCastId);@@ -280,8 +281,6 @@ module.i32x4.all_true(module.v128.const(v128_bytes)), module.i32x4.bitmask(module.v128.const(v128_bytes)), module.i64x2.neg(module.v128.const(v128_bytes)),- module.i64x2.any_true(module.v128.const(v128_bytes)),- module.i64x2.all_true(module.v128.const(v128_bytes)), module.f32x4.abs(module.v128.const(v128_bytes)), module.f32x4.neg(module.v128.const(v128_bytes)), module.f32x4.sqrt(module.v128.const(v128_bytes)),@@ -539,8 +538,8 @@ // Reference types module.ref.is_null(module.ref.null(binaryen.externref)), module.ref.is_null(module.ref.null(binaryen.funcref)),- module.ref.is_null(module.ref.func("kitchen()sinker")),- module.select(temp10, module.ref.null(binaryen.funcref), module.ref.func("kitchen()sinker"), binaryen.funcref),+ module.ref.is_null(module.ref.func("kitchen()sinker", binaryen.funcref)),+ module.select(temp10, module.ref.null(binaryen.funcref), module.ref.func("kitchen()sinker", binaryen.funcref), binaryen.funcref), // GC module.ref.eq(module.ref.null(binaryen.eqref), module.ref.null(binaryen.eqref)),@@ -570,14 +569,14 @@ ) ), module.drop(- module.i32.atomic.wait(+ module.memory.atomic.wait32( module.i32.const(0), module.i32.const(0), module.i64.const(0) ) ), module.drop(- module.atomic.notify(+ module.memory.atomic.notify( module.i32.const(0), module.i32.const(0) )@@ -1034,7 +1033,16 @@ var expected_data = ["hello, world", "segment data 2"]; var expected_passive = [false, false]; - var global = module.addGlobal("a-global", binaryen.i32, false, module.i32.const(expected_offsets[1]))+ var glos = [+ module.addGlobal("a-global", binaryen.i32, false, module.i32.const(expected_offsets[1])),+ module.addGlobal("a-global2", binaryen.i32, false, module.i32.const(2)),+ module.addGlobal("a-global3", binaryen.i32, false, module.i32.const(3))+ ];++ for (i = 0; i < module.getNumGlobals(); i++) {+ assert(module.getGlobalByIndex(i) === glos[i]);+ }+ module.setMemory(1, 256, "mem", [ { passive: expected_passive[0],
binaryen/test/binaryen.js/kitchen-sink.js.txt view
@@ -41,7 +41,7 @@ Features.Multivalue: 512 Features.GC: 1024 Features.Memory64: 2048-Features.All: 4095+Features.All: 8191 InvalidId: 0 BlockId: 1 IfId: 2@@ -65,46 +65,47 @@ MemorySizeId: 20 MemoryGrowId: 21 NopId: 22-UnreachableId: 23-AtomicCmpxchgId: 25-AtomicRMWId: 24-AtomicWaitId: 26-AtomicNotifyId: 27-SIMDExtractId: 29-SIMDReplaceId: 30-SIMDShuffleId: 31-SIMDTernaryId: 32-SIMDShiftId: 33-SIMDLoadId: 34-MemoryInitId: 35-DataDropId: 36-MemoryCopyId: 37-MemoryFillId: 38-PopId: 39-RefNullId: 40-RefIsNullId: 41-RefFuncId: 42-RefEqId: 43-TryId: 44-ThrowId: 45-RethrowId: 46-BrOnExnId: 47-TupleMakeId: 48-TupleExtractId: 49-I31NewId: 50-I31GetId: 51-RefTestId: 52-RefCastId: 53-BrOnCastId: 54-RttCanonId: 55-RttSubId: 56-StructNewId: 57-StructGetId: 58-StructSetId: 59-ArrayNewId: 60-ArrayGetId: 61-ArraySetId: 62-ArrayLenId: 63+UnreachableId: 24+AtomicCmpxchgId: 26+AtomicRMWId: 25+AtomicWaitId: 27+AtomicNotifyId: 28+SIMDExtractId: 30+SIMDReplaceId: 31+SIMDShuffleId: 32+SIMDTernaryId: 33+SIMDShiftId: 34+SIMDLoadId: 35+MemoryInitId: 37+DataDropId: 38+MemoryCopyId: 39+MemoryFillId: 40+PopId: 41+RefNullId: 42+RefIsNullId: 43+RefFuncId: 44+RefEqId: 45+TryId: 46+ThrowId: 47+RethrowId: 48+BrOnExnId: 49+TupleMakeId: 50+TupleExtractId: 51+I31NewId: 52+I31GetId: 53+CallRefId: 54+RefTestId: 55+RefCastId: 56+BrOnCastId: 57+RttCanonId: 58+RttSubId: 59+StructNewId: 60+StructGetId: 61+StructSetId: 62+ArrayNewId: 63+ArrayGetId: 64+ArraySetId: 65+ArrayLenId: 66 getExpressionInfo={"id":15,"type":4,"op":6} (f32.neg (f32.const -33.61199951171875)@@ -482,16 +483,6 @@ ) ) (drop- (i64x2.any_true- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i64x2.all_true- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop (f32x4.abs (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d) )@@ -1896,14 +1887,14 @@ ) ) (drop- (i32.atomic.wait+ (memory.atomic.wait32 (i32.const 0) (i32.const 0) (i64.const 0) ) ) (drop- (atomic.notify+ (memory.atomic.notify (i32.const 0) (i32.const 0) )@@ -2364,16 +2355,6 @@ ) ) (drop- (i64x2.any_true- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i64x2.all_true- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop (f32x4.abs (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d) )@@ -3778,14 +3759,14 @@ ) ) (drop- (i32.atomic.wait+ (memory.atomic.wait32 (i32.const 0) (i32.const 0) (i64.const 0) ) ) (drop- (atomic.notify+ (memory.atomic.notify (i32.const 0) (i32.const 0) )@@ -4390,8 +4371,8 @@ ) [wasm-validator error in function func] local.set's value type must be correct, on -[none] (local.set $0- [i64] (i64.const 1234)+(local.set $0+ (i64.const 1234) ) validation: 0 test_parsing text:@@ -4431,6 +4412,8 @@ (table $0 1 funcref) (elem (i32.const 0) $fn0 $fn1 $fn2) (global $a-global i32 (i32.const 125))+ (global $a-global2 i32 (i32.const 2))+ (global $a-global3 i32 (i32.const 3)) (export "export0" (func $fn0)) (export "export1" (func $fn1)) (export "export2" (func $fn2))
binaryen/test/binaryen.js/validation_errors.js.txt view
@@ -1,6 +1,6 @@ [wasm-validator error in function test] unexpected false: global.get name must be valid, on -[i32] (global.get $missing)+(global.get $missing) 0 [wasm-validator error in function test] unexpected false: local.get index must be small enough, on -[i32] (local.get $0)+(local.get $0) 0
− binaryen/test/debugInfo.asm.js
@@ -1,102 +0,0 @@-function () {- "use asm";- var STACKTOP = 0;- function add(x, y) {- x = x | 0;- y = y | 0;- x = x; //@line 5 "tests/hello_world.c"- y = y; //@line 6 "tests/hello_world.c"- x = y; //@line 314159 "tests/other_file.cpp"- return x + y | 0;- }- function ret(x) {- x = x | 0;- x = x << 1; //@line 50 "return.cpp"- return x + 1 | 0; //@line 100 "return.cpp"- }- function opts(x, y) {- x = x | 0;- y = y | 0;- x = (x + y) | 0; //@line 1 "even-opted.cpp"- y = y >> x; //@line 2 "even-opted.cpp"- x = (x | 0) % (y | 0); //@line 3 "even-opted.cpp"- return x + y | 0;- }- function fib($0) {- $0 = $0|0;- var $$0$lcssa = 0, $$01518 = 0, $$01518$phi = 0, $$01617 = 0, $$019 = 0, $1 = 0, $2 = 0, $3 = 0, $exitcond = 0, label = 0, sp = 0;- sp = STACKTOP;- $1 = ($0|0)>(0); //@line 3 "fib.c"- if ($1) {- $$01518 = 0;$$01617 = 0;$$019 = 1;- } else {- $$0$lcssa = 1;- return ($$0$lcssa|0); //@line 8 "fib.c"- }- while(1) {- $2 = (($$019) + ($$01518))|0; //@line 4 "fib.c"- $3 = (($$01617) + 1)|0; //@line 3 "fib.c"- $exitcond = ($3|0)==($0|0); //@line 3 "fib.c"- if ($exitcond) {- $$0$lcssa = $2;- break;- } else {- $$01518$phi = $$019;$$01617 = $3;$$019 = $2;$$01518 = $$01518$phi;- }- }- return ($$0$lcssa|0); //@line 8 "fib.c"- }- function switch_reach($p) {- $p = $p|0;- var $0 = 0, $call = 0, $magic = 0, $rc$0 = 0, $switch$split2D = 0, label = 0, sp = 0;- sp = STACKTOP;- $magic = ((($p)) + 52|0);- $0 = $magic;- $switch$split2D = ($0|0)<(1369188723);- if ($switch$split2D) {- switch ($0|0) {- case -1108210269: {- label = 2;- break;- }- default: {- $rc$0 = 0;- }- }- } else {- switch ($0|0) {- case 1369188723: {- label = 2;- break;- }- default: {- $rc$0 = 0;- }- }- }- if ((label|0) == 2) {- $call = switch_reach($p) | 0;- $rc$0 = $call;- }- switch_reach($p) | 0;- return ($rc$0|0); //@line 59950 "/tmp/emscripten_test_binaryen2_28hnAe/src.c"- }- function nofile() {- nofile(); //@line 1337- }- function inlineMe(x, y) {- x = x | 0;- y = y | 0;- x = x + y | 0; //@line 120 "inline_me.c"- y = x + y | 0; //@line 121 "inline_me.c"- x = x + y | 0; //@line 122 "inline_me.c"- return x | 0; //@line 123 "inline_me.c"- }- function inlineInto(x, y) {- x = x | 0;- y = y | 0;- return inlineMe(x | 0, y | 0) | 0; //@line 125 "inline_me.c"- }- return { add: add, ret: ret, opts: opts, fib: fib, switch_reach: switch_reach, nofile: nofile, inlineInto: inlineInto };-}-
binaryen/test/dylib.wasm.fromBinary view
@@ -3,9 +3,9 @@ (type $none_=>_none (func)) (type $i32_=>_i32 (func (param i32) (result i32))) (type $i32_i32_=>_i32 (func (param i32 i32) (result i32)))- (import "env" "memory" (memory $mimport$5 0))- (data (global.get $gimport$4) "*\00\00\00")- (import "env" "__memory_base" (global $gimport$4 i32))+ (import "env" "memory" (memory $mimport$0 0))+ (data (global.get $gimport$0) "*\00\00\00")+ (import "env" "__memory_base" (global $gimport$0 i32)) (import "env" "g$waka_mine" (func $fimport$0 (result i32))) (import "env" "g$waka_others" (func $fimport$1 (result i32))) (import "env" "fp$_Z16waka_func_theirsi$ii" (func $fimport$2 (result i32)))
− binaryen/test/dynamicLibrary.asm.js
@@ -1,136 +0,0 @@-Module["asm"] = (function(global, env, buffer) {- 'almost asm';- - - var HEAP8 = new global.Int8Array(buffer);- var HEAP16 = new global.Int16Array(buffer);- var HEAP32 = new global.Int32Array(buffer);- var HEAPU8 = new global.Uint8Array(buffer);- var HEAPU16 = new global.Uint16Array(buffer);- var HEAPU32 = new global.Uint32Array(buffer);- var HEAPF32 = new global.Float32Array(buffer);- var HEAPF64 = new global.Float64Array(buffer);--- var DYNAMICTOP_PTR=env.DYNAMICTOP_PTR|0;- var tempDoublePtr=env.tempDoublePtr|0;- var ABORT=env.ABORT|0;- var memoryBase=env.memoryBase|0;- var tableBase=env.tableBase|0;-- var STACKTOP = 0, STACK_MAX = 0;-- var __THREW__ = 0;- var threwValue = 0;- var setjmpId = 0;- var undef = 0;- var nan = global.NaN, inf = global.Infinity;- var tempInt = 0, tempBigInt = 0, tempBigIntP = 0, tempBigIntS = 0, tempBigIntR = 0.0, tempBigIntI = 0, tempBigIntD = 0, tempValue = 0, tempDouble = 0.0;- var tempRet0 = 0;-- var Math_floor=global.Math.floor;- var Math_abs=global.Math.abs;- var Math_sqrt=global.Math.sqrt;- var Math_pow=global.Math.pow;- var Math_cos=global.Math.cos;- var Math_sin=global.Math.sin;- var Math_tan=global.Math.tan;- var Math_acos=global.Math.acos;- var Math_asin=global.Math.asin;- var Math_atan=global.Math.atan;- var Math_atan2=global.Math.atan2;- var Math_exp=global.Math.exp;- var Math_log=global.Math.log;- var Math_ceil=global.Math.ceil;- var Math_imul=global.Math.imul;- var Math_min=global.Math.min;- var Math_max=global.Math.max;- var Math_clz32=global.Math.clz32;- var Math_fround=global.Math.fround;- var abort=env.abort;- var assert=env.assert;- var enlargeMemory=env.enlargeMemory;- var getTotalMemory=env.getTotalMemory;- var abortOnCannotGrowMemory=env.abortOnCannotGrowMemory;- var abortStackOverflow=env.abortStackOverflow;- var setTempRet0=env.setTempRet0;- var getTempRet0=env.getTempRet0;- var _puts=env._puts;- var tempFloat = Math_fround(0);- const f0 = Math_fround(0);--// EMSCRIPTEN_START_FUNCS--function stackAlloc(size) {- size = size|0;- var ret = 0;- ret = STACKTOP;- STACKTOP = (STACKTOP + size)|0;- STACKTOP = (STACKTOP + 15)&-16;- if ((STACKTOP|0) >= (STACK_MAX|0)) abortStackOverflow(size|0);-- return ret|0;-}-function stackSave() {- return STACKTOP|0;-}-function stackRestore(top) {- top = top|0;- STACKTOP = top;-}-function establishStackSpace(stackBase, stackMax) {- stackBase = stackBase|0;- stackMax = stackMax|0;- STACKTOP = stackBase;- STACK_MAX = stackMax;-}--function setThrew(threw, value) {- threw = threw|0;- value = value|0;- if ((__THREW__|0) == 0) {- __THREW__ = threw;- threwValue = value;- }-}--function ___cxx_global_var_init() {- var label = 0, sp = 0;- sp = STACKTOP;- __ZN3FooC2Ev((memoryBase + (5242912) | 0));- return;-}-function __ZN3FooC2Ev($0) {- $0 = $0|0;- var $1 = 0, label = 0, sp = 0;- sp = STACKTOP;- STACKTOP = STACKTOP + 16|0; if ((STACKTOP|0) >= (STACK_MAX|0)) abortStackOverflow(16|0);- $1 = $0;- (_puts(((memoryBase + (0) | 0)|0))|0);- STACKTOP = sp;return;-}-function __GLOBAL__sub_I_liblib_cpp() {- var label = 0, sp = 0;- sp = STACKTOP;- ___cxx_global_var_init();- return;-}-function runPostSets() {- var temp = 0;-}-function __post_instantiate() {- STACKTOP = (memoryBase + (32) | 0);- STACK_MAX = STACKTOP + 5242880 | 0;- runPostSets();- __GLOBAL__sub_I_liblib_cpp();-}-- ---// EMSCRIPTEN_END_FUNCS--- return { __ZN3FooC2Ev: __ZN3FooC2Ev, __post_instantiate: __post_instantiate, runPostSets: runPostSets, _global: 5242912 };-})-;
− binaryen/test/emcc_O2_hello_world.asm.js
@@ -1,2293 +0,0 @@-Module["asm"] = (function(global,env,buffer) {-- 'use asm';- - - var HEAP8 = new global.Int8Array(buffer);- var HEAP16 = new global.Int16Array(buffer);- var HEAP32 = new global.Int32Array(buffer);- var HEAPU8 = new global.Uint8Array(buffer);- var HEAPU16 = new global.Uint16Array(buffer);- var HEAPU32 = new global.Uint32Array(buffer);- var HEAPF32 = new global.Float32Array(buffer);- var HEAPF64 = new global.Float64Array(buffer);--- var STACKTOP=env.STACKTOP|0;- var STACK_MAX=env.STACK_MAX|0;- var tempDoublePtr=env.tempDoublePtr|0;- var ABORT=env.ABORT|0;-- var __THREW__ = 0;- var threwValue = 0;- var setjmpId = 0;- var undef = 0;- var nan = global.NaN, inf = global.Infinity;- var tempInt = 0, tempBigInt = 0, tempBigIntP = 0, tempBigIntS = 0, tempBigIntR = 0.0, tempBigIntI = 0, tempBigIntD = 0, tempValue = 0, tempDouble = 0.0;-- var tempRet0 = 0;- var tempRet1 = 0;- var tempRet2 = 0;- var tempRet3 = 0;- var tempRet4 = 0;- var tempRet5 = 0;- var tempRet6 = 0;- var tempRet7 = 0;- var tempRet8 = 0;- var tempRet9 = 0;- var Math_floor=global.Math.floor;- var Math_abs=global.Math.abs;- var Math_sqrt=global.Math.sqrt;- var Math_pow=global.Math.pow;- var Math_cos=global.Math.cos;- var Math_sin=global.Math.sin;- var Math_tan=global.Math.tan;- var Math_acos=global.Math.acos;- var Math_asin=global.Math.asin;- var Math_atan=global.Math.atan;- var Math_atan2=global.Math.atan2;- var Math_exp=global.Math.exp;- var Math_log=global.Math.log;- var Math_ceil=global.Math.ceil;- var Math_imul=global.Math.imul;- var Math_min=global.Math.min;- var Math_clz32=global.Math.clz32;- var abort=env.abort;- var assert=env.assert;- var invoke_ii=env.invoke_ii;- var invoke_iiii=env.invoke_iiii;- var invoke_vi=env.invoke_vi;- var _pthread_cleanup_pop=env._pthread_cleanup_pop;- var _pthread_self=env._pthread_self;- var _sysconf=env._sysconf;- var ___lock=env.___lock;- var ___syscall6=env.___syscall6;- var ___setErrNo=env.___setErrNo;- var _abort=env._abort;- var _sbrk=env._sbrk;- var _time=env._time;- var _pthread_cleanup_push=env._pthread_cleanup_push;- var _emscripten_memcpy_big=env._emscripten_memcpy_big;- var ___syscall54=env.___syscall54;- var ___unlock=env.___unlock;- var ___syscall140=env.___syscall140;- var _emscripten_set_main_loop_timing=env._emscripten_set_main_loop_timing;- var _emscripten_set_main_loop=env._emscripten_set_main_loop;- var ___syscall146=env.___syscall146;- var tempFloat = 0.0;--// EMSCRIPTEN_START_FUNCS--function _malloc(i1) {- i1 = i1 | 0;- var i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, i18 = 0, i19 = 0, i20 = 0, i21 = 0, i22 = 0, i23 = 0, i24 = 0, i25 = 0, i26 = 0, i27 = 0, i28 = 0, i29 = 0, i30 = 0, i31 = 0, i32 = 0, i33 = 0, i34 = 0, i35 = 0, i36 = 0, i37 = 0, i38 = 0, i39 = 0, i40 = 0, i41 = 0, i42 = 0, i43 = 0, i44 = 0, i45 = 0, i46 = 0, i47 = 0, i48 = 0, i49 = 0, i50 = 0, i51 = 0, i52 = 0, i53 = 0, i54 = 0, i55 = 0, i56 = 0, i57 = 0, i58 = 0, i59 = 0, i60 = 0, i61 = 0, i62 = 0, i63 = 0, i64 = 0, i65 = 0, i66 = 0, i67 = 0, i68 = 0, i69 = 0, i70 = 0, i71 = 0, i72 = 0, i73 = 0, i74 = 0, i75 = 0, i76 = 0, i77 = 0, i78 = 0, i79 = 0, i80 = 0, i81 = 0, i82 = 0, i83 = 0, i84 = 0, i85 = 0, i86 = 0, i87 = 0, i88 = 0, i89 = 0, i90 = 0, i91 = 0, i92 = 0;- do if (i1 >>> 0 < 245) {- i2 = i1 >>> 0 < 11 ? 16 : i1 + 11 & -8;- i3 = i2 >>> 3;- i4 = HEAP32[44] | 0;- i5 = i4 >>> i3;- if (i5 & 3) {- i6 = (i5 & 1 ^ 1) + i3 | 0;- i7 = 216 + (i6 << 1 << 2) | 0;- i8 = i7 + 8 | 0;- i9 = HEAP32[i8 >> 2] | 0;- i10 = i9 + 8 | 0;- i11 = HEAP32[i10 >> 2] | 0;- do if ((i7 | 0) != (i11 | 0)) {- if (i11 >>> 0 < (HEAP32[48] | 0) >>> 0) _abort();- i12 = i11 + 12 | 0;- if ((HEAP32[i12 >> 2] | 0) == (i9 | 0)) {- HEAP32[i12 >> 2] = i7;- HEAP32[i8 >> 2] = i11;- break;- } else _abort();- } else HEAP32[44] = i4 & ~(1 << i6); while (0);- i11 = i6 << 3;- HEAP32[i9 + 4 >> 2] = i11 | 3;- i8 = i9 + i11 + 4 | 0;- HEAP32[i8 >> 2] = HEAP32[i8 >> 2] | 1;- i13 = i10;- return i13 | 0;- }- i8 = HEAP32[46] | 0;- if (i2 >>> 0 > i8 >>> 0) {- if (i5) {- i11 = 2 << i3;- i7 = i5 << i3 & (i11 | 0 - i11);- i11 = (i7 & 0 - i7) + -1 | 0;- i7 = i11 >>> 12 & 16;- i12 = i11 >>> i7;- i11 = i12 >>> 5 & 8;- i14 = i12 >>> i11;- i12 = i14 >>> 2 & 4;- i15 = i14 >>> i12;- i14 = i15 >>> 1 & 2;- i16 = i15 >>> i14;- i15 = i16 >>> 1 & 1;- i17 = (i11 | i7 | i12 | i14 | i15) + (i16 >>> i15) | 0;- i15 = 216 + (i17 << 1 << 2) | 0;- i16 = i15 + 8 | 0;- i14 = HEAP32[i16 >> 2] | 0;- i12 = i14 + 8 | 0;- i7 = HEAP32[i12 >> 2] | 0;- do if ((i15 | 0) != (i7 | 0)) {- if (i7 >>> 0 < (HEAP32[48] | 0) >>> 0) _abort();- i11 = i7 + 12 | 0;- if ((HEAP32[i11 >> 2] | 0) == (i14 | 0)) {- HEAP32[i11 >> 2] = i15;- HEAP32[i16 >> 2] = i7;- i18 = HEAP32[46] | 0;- break;- } else _abort();- } else {- HEAP32[44] = i4 & ~(1 << i17);- i18 = i8;- } while (0);- i8 = (i17 << 3) - i2 | 0;- HEAP32[i14 + 4 >> 2] = i2 | 3;- i4 = i14 + i2 | 0;- HEAP32[i4 + 4 >> 2] = i8 | 1;- HEAP32[i4 + i8 >> 2] = i8;- if (i18) {- i7 = HEAP32[49] | 0;- i16 = i18 >>> 3;- i15 = 216 + (i16 << 1 << 2) | 0;- i3 = HEAP32[44] | 0;- i5 = 1 << i16;- if (i3 & i5) {- i16 = i15 + 8 | 0;- i10 = HEAP32[i16 >> 2] | 0;- if (i10 >>> 0 < (HEAP32[48] | 0) >>> 0) _abort(); else {- i19 = i16;- i20 = i10;- }- } else {- HEAP32[44] = i3 | i5;- i19 = i15 + 8 | 0;- i20 = i15;- }- HEAP32[i19 >> 2] = i7;- HEAP32[i20 + 12 >> 2] = i7;- HEAP32[i7 + 8 >> 2] = i20;- HEAP32[i7 + 12 >> 2] = i15;- }- HEAP32[46] = i8;- HEAP32[49] = i4;- i13 = i12;- return i13 | 0;- }- i4 = HEAP32[45] | 0;- if (i4) {- i8 = (i4 & 0 - i4) + -1 | 0;- i4 = i8 >>> 12 & 16;- i15 = i8 >>> i4;- i8 = i15 >>> 5 & 8;- i7 = i15 >>> i8;- i15 = i7 >>> 2 & 4;- i5 = i7 >>> i15;- i7 = i5 >>> 1 & 2;- i3 = i5 >>> i7;- i5 = i3 >>> 1 & 1;- i10 = HEAP32[480 + ((i8 | i4 | i15 | i7 | i5) + (i3 >>> i5) << 2) >> 2] | 0;- i5 = (HEAP32[i10 + 4 >> 2] & -8) - i2 | 0;- i3 = i10;- i7 = i10;- while (1) {- i10 = HEAP32[i3 + 16 >> 2] | 0;- if (!i10) {- i15 = HEAP32[i3 + 20 >> 2] | 0;- if (!i15) {- i21 = i5;- i22 = i7;- break;- } else i23 = i15;- } else i23 = i10;- i10 = (HEAP32[i23 + 4 >> 2] & -8) - i2 | 0;- i15 = i10 >>> 0 < i5 >>> 0;- i5 = i15 ? i10 : i5;- i3 = i23;- i7 = i15 ? i23 : i7;- }- i7 = HEAP32[48] | 0;- if (i22 >>> 0 < i7 >>> 0) _abort();- i3 = i22 + i2 | 0;- if (i22 >>> 0 >= i3 >>> 0) _abort();- i5 = HEAP32[i22 + 24 >> 2] | 0;- i12 = HEAP32[i22 + 12 >> 2] | 0;- do if ((i12 | 0) == (i22 | 0)) {- i14 = i22 + 20 | 0;- i17 = HEAP32[i14 >> 2] | 0;- if (!i17) {- i15 = i22 + 16 | 0;- i10 = HEAP32[i15 >> 2] | 0;- if (!i10) {- i24 = 0;- break;- } else {- i25 = i10;- i26 = i15;- }- } else {- i25 = i17;- i26 = i14;- }- while (1) {- i14 = i25 + 20 | 0;- i17 = HEAP32[i14 >> 2] | 0;- if (i17) {- i25 = i17;- i26 = i14;- continue;- }- i14 = i25 + 16 | 0;- i17 = HEAP32[i14 >> 2] | 0;- if (!i17) {- i27 = i25;- i28 = i26;- break;- } else {- i25 = i17;- i26 = i14;- }- }- if (i28 >>> 0 < i7 >>> 0) _abort(); else {- HEAP32[i28 >> 2] = 0;- i24 = i27;- break;- }- } else {- i14 = HEAP32[i22 + 8 >> 2] | 0;- if (i14 >>> 0 < i7 >>> 0) _abort();- i17 = i14 + 12 | 0;- if ((HEAP32[i17 >> 2] | 0) != (i22 | 0)) _abort();- i15 = i12 + 8 | 0;- if ((HEAP32[i15 >> 2] | 0) == (i22 | 0)) {- HEAP32[i17 >> 2] = i12;- HEAP32[i15 >> 2] = i14;- i24 = i12;- break;- } else _abort();- } while (0);- do if (i5) {- i12 = HEAP32[i22 + 28 >> 2] | 0;- i7 = 480 + (i12 << 2) | 0;- if ((i22 | 0) == (HEAP32[i7 >> 2] | 0)) {- HEAP32[i7 >> 2] = i24;- if (!i24) {- HEAP32[45] = HEAP32[45] & ~(1 << i12);- break;- }- } else {- if (i5 >>> 0 < (HEAP32[48] | 0) >>> 0) _abort();- i12 = i5 + 16 | 0;- if ((HEAP32[i12 >> 2] | 0) == (i22 | 0)) HEAP32[i12 >> 2] = i24; else HEAP32[i5 + 20 >> 2] = i24;- if (!i24) break;- }- i12 = HEAP32[48] | 0;- if (i24 >>> 0 < i12 >>> 0) _abort();- HEAP32[i24 + 24 >> 2] = i5;- i7 = HEAP32[i22 + 16 >> 2] | 0;- do if (i7) if (i7 >>> 0 < i12 >>> 0) _abort(); else {- HEAP32[i24 + 16 >> 2] = i7;- HEAP32[i7 + 24 >> 2] = i24;- break;- } while (0);- i7 = HEAP32[i22 + 20 >> 2] | 0;- if (i7) if (i7 >>> 0 < (HEAP32[48] | 0) >>> 0) _abort(); else {- HEAP32[i24 + 20 >> 2] = i7;- HEAP32[i7 + 24 >> 2] = i24;- break;- }- } while (0);- if (i21 >>> 0 < 16) {- i5 = i21 + i2 | 0;- HEAP32[i22 + 4 >> 2] = i5 | 3;- i7 = i22 + i5 + 4 | 0;- HEAP32[i7 >> 2] = HEAP32[i7 >> 2] | 1;- } else {- HEAP32[i22 + 4 >> 2] = i2 | 3;- HEAP32[i3 + 4 >> 2] = i21 | 1;- HEAP32[i3 + i21 >> 2] = i21;- i7 = HEAP32[46] | 0;- if (i7) {- i5 = HEAP32[49] | 0;- i12 = i7 >>> 3;- i7 = 216 + (i12 << 1 << 2) | 0;- i14 = HEAP32[44] | 0;- i15 = 1 << i12;- if (i14 & i15) {- i12 = i7 + 8 | 0;- i17 = HEAP32[i12 >> 2] | 0;- if (i17 >>> 0 < (HEAP32[48] | 0) >>> 0) _abort(); else {- i29 = i12;- i30 = i17;- }- } else {- HEAP32[44] = i14 | i15;- i29 = i7 + 8 | 0;- i30 = i7;- }- HEAP32[i29 >> 2] = i5;- HEAP32[i30 + 12 >> 2] = i5;- HEAP32[i5 + 8 >> 2] = i30;- HEAP32[i5 + 12 >> 2] = i7;- }- HEAP32[46] = i21;- HEAP32[49] = i3;- }- i13 = i22 + 8 | 0;- return i13 | 0;- } else i31 = i2;- } else i31 = i2;- } else if (i1 >>> 0 <= 4294967231) {- i7 = i1 + 11 | 0;- i5 = i7 & -8;- i15 = HEAP32[45] | 0;- if (i15) {- i14 = 0 - i5 | 0;- i17 = i7 >>> 8;- if (i17) if (i5 >>> 0 > 16777215) i32 = 31; else {- i7 = (i17 + 1048320 | 0) >>> 16 & 8;- i12 = i17 << i7;- i17 = (i12 + 520192 | 0) >>> 16 & 4;- i10 = i12 << i17;- i12 = (i10 + 245760 | 0) >>> 16 & 2;- i4 = 14 - (i17 | i7 | i12) + (i10 << i12 >>> 15) | 0;- i32 = i5 >>> (i4 + 7 | 0) & 1 | i4 << 1;- } else i32 = 0;- i4 = HEAP32[480 + (i32 << 2) >> 2] | 0;- L123 : do if (!i4) {- i33 = i14;- i34 = 0;- i35 = 0;- i36 = 86;- } else {- i12 = i14;- i10 = 0;- i7 = i5 << ((i32 | 0) == 31 ? 0 : 25 - (i32 >>> 1) | 0);- i17 = i4;- i8 = 0;- while (1) {- i16 = HEAP32[i17 + 4 >> 2] & -8;- i9 = i16 - i5 | 0;- if (i9 >>> 0 < i12 >>> 0) if ((i16 | 0) == (i5 | 0)) {- i37 = i9;- i38 = i17;- i39 = i17;- i36 = 90;- break L123;- } else {- i40 = i9;- i41 = i17;- } else {- i40 = i12;- i41 = i8;- }- i9 = HEAP32[i17 + 20 >> 2] | 0;- i17 = HEAP32[i17 + 16 + (i7 >>> 31 << 2) >> 2] | 0;- i16 = (i9 | 0) == 0 | (i9 | 0) == (i17 | 0) ? i10 : i9;- i9 = (i17 | 0) == 0;- if (i9) {- i33 = i40;- i34 = i16;- i35 = i41;- i36 = 86;- break;- } else {- i12 = i40;- i10 = i16;- i7 = i7 << (i9 & 1 ^ 1);- i8 = i41;- }- }- } while (0);- if ((i36 | 0) == 86) {- if ((i34 | 0) == 0 & (i35 | 0) == 0) {- i4 = 2 << i32;- i14 = i15 & (i4 | 0 - i4);- if (!i14) {- i31 = i5;- break;- }- i4 = (i14 & 0 - i14) + -1 | 0;- i14 = i4 >>> 12 & 16;- i2 = i4 >>> i14;- i4 = i2 >>> 5 & 8;- i3 = i2 >>> i4;- i2 = i3 >>> 2 & 4;- i8 = i3 >>> i2;- i3 = i8 >>> 1 & 2;- i7 = i8 >>> i3;- i8 = i7 >>> 1 & 1;- i42 = HEAP32[480 + ((i4 | i14 | i2 | i3 | i8) + (i7 >>> i8) << 2) >> 2] | 0;- } else i42 = i34;- if (!i42) {- i43 = i33;- i44 = i35;- } else {- i37 = i33;- i38 = i42;- i39 = i35;- i36 = 90;- }- }- if ((i36 | 0) == 90) while (1) {- i36 = 0;- i8 = (HEAP32[i38 + 4 >> 2] & -8) - i5 | 0;- i7 = i8 >>> 0 < i37 >>> 0;- i3 = i7 ? i8 : i37;- i8 = i7 ? i38 : i39;- i7 = HEAP32[i38 + 16 >> 2] | 0;- if (i7) {- i37 = i3;- i38 = i7;- i39 = i8;- i36 = 90;- continue;- }- i38 = HEAP32[i38 + 20 >> 2] | 0;- if (!i38) {- i43 = i3;- i44 = i8;- break;- } else {- i37 = i3;- i39 = i8;- i36 = 90;- }- }- if ((i44 | 0) != 0 ? i43 >>> 0 < ((HEAP32[46] | 0) - i5 | 0) >>> 0 : 0) {- i15 = HEAP32[48] | 0;- if (i44 >>> 0 < i15 >>> 0) _abort();- i8 = i44 + i5 | 0;- if (i44 >>> 0 >= i8 >>> 0) _abort();- i3 = HEAP32[i44 + 24 >> 2] | 0;- i7 = HEAP32[i44 + 12 >> 2] | 0;- do if ((i7 | 0) == (i44 | 0)) {- i2 = i44 + 20 | 0;- i14 = HEAP32[i2 >> 2] | 0;- if (!i14) {- i4 = i44 + 16 | 0;- i10 = HEAP32[i4 >> 2] | 0;- if (!i10) {- i45 = 0;- break;- } else {- i46 = i10;- i47 = i4;- }- } else {- i46 = i14;- i47 = i2;- }- while (1) {- i2 = i46 + 20 | 0;- i14 = HEAP32[i2 >> 2] | 0;- if (i14) {- i46 = i14;- i47 = i2;- continue;- }- i2 = i46 + 16 | 0;- i14 = HEAP32[i2 >> 2] | 0;- if (!i14) {- i48 = i46;- i49 = i47;- break;- } else {- i46 = i14;- i47 = i2;- }- }- if (i49 >>> 0 < i15 >>> 0) _abort(); else {- HEAP32[i49 >> 2] = 0;- i45 = i48;- break;- }- } else {- i2 = HEAP32[i44 + 8 >> 2] | 0;- if (i2 >>> 0 < i15 >>> 0) _abort();- i14 = i2 + 12 | 0;- if ((HEAP32[i14 >> 2] | 0) != (i44 | 0)) _abort();- i4 = i7 + 8 | 0;- if ((HEAP32[i4 >> 2] | 0) == (i44 | 0)) {- HEAP32[i14 >> 2] = i7;- HEAP32[i4 >> 2] = i2;- i45 = i7;- break;- } else _abort();- } while (0);- do if (i3) {- i7 = HEAP32[i44 + 28 >> 2] | 0;- i15 = 480 + (i7 << 2) | 0;- if ((i44 | 0) == (HEAP32[i15 >> 2] | 0)) {- HEAP32[i15 >> 2] = i45;- if (!i45) {- HEAP32[45] = HEAP32[45] & ~(1 << i7);- break;- }- } else {- if (i3 >>> 0 < (HEAP32[48] | 0) >>> 0) _abort();- i7 = i3 + 16 | 0;- if ((HEAP32[i7 >> 2] | 0) == (i44 | 0)) HEAP32[i7 >> 2] = i45; else HEAP32[i3 + 20 >> 2] = i45;- if (!i45) break;- }- i7 = HEAP32[48] | 0;- if (i45 >>> 0 < i7 >>> 0) _abort();- HEAP32[i45 + 24 >> 2] = i3;- i15 = HEAP32[i44 + 16 >> 2] | 0;- do if (i15) if (i15 >>> 0 < i7 >>> 0) _abort(); else {- HEAP32[i45 + 16 >> 2] = i15;- HEAP32[i15 + 24 >> 2] = i45;- break;- } while (0);- i15 = HEAP32[i44 + 20 >> 2] | 0;- if (i15) if (i15 >>> 0 < (HEAP32[48] | 0) >>> 0) _abort(); else {- HEAP32[i45 + 20 >> 2] = i15;- HEAP32[i15 + 24 >> 2] = i45;- break;- }- } while (0);- do if (i43 >>> 0 >= 16) {- HEAP32[i44 + 4 >> 2] = i5 | 3;- HEAP32[i8 + 4 >> 2] = i43 | 1;- HEAP32[i8 + i43 >> 2] = i43;- i3 = i43 >>> 3;- if (i43 >>> 0 < 256) {- i15 = 216 + (i3 << 1 << 2) | 0;- i7 = HEAP32[44] | 0;- i2 = 1 << i3;- if (i7 & i2) {- i3 = i15 + 8 | 0;- i4 = HEAP32[i3 >> 2] | 0;- if (i4 >>> 0 < (HEAP32[48] | 0) >>> 0) _abort(); else {- i50 = i3;- i51 = i4;- }- } else {- HEAP32[44] = i7 | i2;- i50 = i15 + 8 | 0;- i51 = i15;- }- HEAP32[i50 >> 2] = i8;- HEAP32[i51 + 12 >> 2] = i8;- HEAP32[i8 + 8 >> 2] = i51;- HEAP32[i8 + 12 >> 2] = i15;- break;- }- i15 = i43 >>> 8;- if (i15) if (i43 >>> 0 > 16777215) i52 = 31; else {- i2 = (i15 + 1048320 | 0) >>> 16 & 8;- i7 = i15 << i2;- i15 = (i7 + 520192 | 0) >>> 16 & 4;- i4 = i7 << i15;- i7 = (i4 + 245760 | 0) >>> 16 & 2;- i3 = 14 - (i15 | i2 | i7) + (i4 << i7 >>> 15) | 0;- i52 = i43 >>> (i3 + 7 | 0) & 1 | i3 << 1;- } else i52 = 0;- i3 = 480 + (i52 << 2) | 0;- HEAP32[i8 + 28 >> 2] = i52;- i7 = i8 + 16 | 0;- HEAP32[i7 + 4 >> 2] = 0;- HEAP32[i7 >> 2] = 0;- i7 = HEAP32[45] | 0;- i4 = 1 << i52;- if (!(i7 & i4)) {- HEAP32[45] = i7 | i4;- HEAP32[i3 >> 2] = i8;- HEAP32[i8 + 24 >> 2] = i3;- HEAP32[i8 + 12 >> 2] = i8;- HEAP32[i8 + 8 >> 2] = i8;- break;- }- i4 = i43 << ((i52 | 0) == 31 ? 0 : 25 - (i52 >>> 1) | 0);- i7 = HEAP32[i3 >> 2] | 0;- while (1) {- if ((HEAP32[i7 + 4 >> 2] & -8 | 0) == (i43 | 0)) {- i53 = i7;- i36 = 148;- break;- }- i3 = i7 + 16 + (i4 >>> 31 << 2) | 0;- i2 = HEAP32[i3 >> 2] | 0;- if (!i2) {- i54 = i3;- i55 = i7;- i36 = 145;- break;- } else {- i4 = i4 << 1;- i7 = i2;- }- }- if ((i36 | 0) == 145) if (i54 >>> 0 < (HEAP32[48] | 0) >>> 0) _abort(); else {- HEAP32[i54 >> 2] = i8;- HEAP32[i8 + 24 >> 2] = i55;- HEAP32[i8 + 12 >> 2] = i8;- HEAP32[i8 + 8 >> 2] = i8;- break;- } else if ((i36 | 0) == 148) {- i7 = i53 + 8 | 0;- i4 = HEAP32[i7 >> 2] | 0;- i2 = HEAP32[48] | 0;- if (i4 >>> 0 >= i2 >>> 0 & i53 >>> 0 >= i2 >>> 0) {- HEAP32[i4 + 12 >> 2] = i8;- HEAP32[i7 >> 2] = i8;- HEAP32[i8 + 8 >> 2] = i4;- HEAP32[i8 + 12 >> 2] = i53;- HEAP32[i8 + 24 >> 2] = 0;- break;- } else _abort();- }- } else {- i4 = i43 + i5 | 0;- HEAP32[i44 + 4 >> 2] = i4 | 3;- i7 = i44 + i4 + 4 | 0;- HEAP32[i7 >> 2] = HEAP32[i7 >> 2] | 1;- } while (0);- i13 = i44 + 8 | 0;- return i13 | 0;- } else i31 = i5;- } else i31 = i5;- } else i31 = -1; while (0);- i44 = HEAP32[46] | 0;- if (i44 >>> 0 >= i31 >>> 0) {- i43 = i44 - i31 | 0;- i53 = HEAP32[49] | 0;- if (i43 >>> 0 > 15) {- i55 = i53 + i31 | 0;- HEAP32[49] = i55;- HEAP32[46] = i43;- HEAP32[i55 + 4 >> 2] = i43 | 1;- HEAP32[i55 + i43 >> 2] = i43;- HEAP32[i53 + 4 >> 2] = i31 | 3;- } else {- HEAP32[46] = 0;- HEAP32[49] = 0;- HEAP32[i53 + 4 >> 2] = i44 | 3;- i43 = i53 + i44 + 4 | 0;- HEAP32[i43 >> 2] = HEAP32[i43 >> 2] | 1;- }- i13 = i53 + 8 | 0;- return i13 | 0;- }- i53 = HEAP32[47] | 0;- if (i53 >>> 0 > i31 >>> 0) {- i43 = i53 - i31 | 0;- HEAP32[47] = i43;- i53 = HEAP32[50] | 0;- i44 = i53 + i31 | 0;- HEAP32[50] = i44;- HEAP32[i44 + 4 >> 2] = i43 | 1;- HEAP32[i53 + 4 >> 2] = i31 | 3;- i13 = i53 + 8 | 0;- return i13 | 0;- }- do if (!(HEAP32[162] | 0)) {- i53 = _sysconf(30) | 0;- if (!(i53 + -1 & i53)) {- HEAP32[164] = i53;- HEAP32[163] = i53;- HEAP32[165] = -1;- HEAP32[166] = -1;- HEAP32[167] = 0;- HEAP32[155] = 0;- HEAP32[162] = (_time(0) | 0) & -16 ^ 1431655768;- break;- } else _abort();- } while (0);- i53 = i31 + 48 | 0;- i43 = HEAP32[164] | 0;- i44 = i31 + 47 | 0;- i55 = i43 + i44 | 0;- i54 = 0 - i43 | 0;- i43 = i55 & i54;- if (i43 >>> 0 <= i31 >>> 0) {- i13 = 0;- return i13 | 0;- }- i52 = HEAP32[154] | 0;- if ((i52 | 0) != 0 ? (i51 = HEAP32[152] | 0, i50 = i51 + i43 | 0, i50 >>> 0 <= i51 >>> 0 | i50 >>> 0 > i52 >>> 0) : 0) {- i13 = 0;- return i13 | 0;- }- L257 : do if (!(HEAP32[155] & 4)) {- i52 = HEAP32[50] | 0;- L259 : do if (i52) {- i50 = 624;- while (1) {- i51 = HEAP32[i50 >> 2] | 0;- if (i51 >>> 0 <= i52 >>> 0 ? (i45 = i50 + 4 | 0, (i51 + (HEAP32[i45 >> 2] | 0) | 0) >>> 0 > i52 >>> 0) : 0) {- i56 = i50;- i57 = i45;- break;- }- i50 = HEAP32[i50 + 8 >> 2] | 0;- if (!i50) {- i36 = 173;- break L259;- }- }- i50 = i55 - (HEAP32[47] | 0) & i54;- if (i50 >>> 0 < 2147483647) {- i45 = _sbrk(i50 | 0) | 0;- if ((i45 | 0) == ((HEAP32[i56 >> 2] | 0) + (HEAP32[i57 >> 2] | 0) | 0)) {- if ((i45 | 0) != (-1 | 0)) {- i58 = i45;- i59 = i50;- i36 = 193;- break L257;- }- } else {- i60 = i45;- i61 = i50;- i36 = 183;- }- }- } else i36 = 173; while (0);- do if ((i36 | 0) == 173 ? (i52 = _sbrk(0) | 0, (i52 | 0) != (-1 | 0)) : 0) {- i5 = i52;- i50 = HEAP32[163] | 0;- i45 = i50 + -1 | 0;- if (!(i45 & i5)) i62 = i43; else i62 = i43 - i5 + (i45 + i5 & 0 - i50) | 0;- i50 = HEAP32[152] | 0;- i5 = i50 + i62 | 0;- if (i62 >>> 0 > i31 >>> 0 & i62 >>> 0 < 2147483647) {- i45 = HEAP32[154] | 0;- if ((i45 | 0) != 0 ? i5 >>> 0 <= i50 >>> 0 | i5 >>> 0 > i45 >>> 0 : 0) break;- i45 = _sbrk(i62 | 0) | 0;- if ((i45 | 0) == (i52 | 0)) {- i58 = i52;- i59 = i62;- i36 = 193;- break L257;- } else {- i60 = i45;- i61 = i62;- i36 = 183;- }- }- } while (0);- L279 : do if ((i36 | 0) == 183) {- i45 = 0 - i61 | 0;- do if (i53 >>> 0 > i61 >>> 0 & (i61 >>> 0 < 2147483647 & (i60 | 0) != (-1 | 0)) ? (i52 = HEAP32[164] | 0, i5 = i44 - i61 + i52 & 0 - i52, i5 >>> 0 < 2147483647) : 0) if ((_sbrk(i5 | 0) | 0) == (-1 | 0)) {- _sbrk(i45 | 0) | 0;- break L279;- } else {- i63 = i5 + i61 | 0;- break;- } else i63 = i61; while (0);- if ((i60 | 0) != (-1 | 0)) {- i58 = i60;- i59 = i63;- i36 = 193;- break L257;- }- } while (0);- HEAP32[155] = HEAP32[155] | 4;- i36 = 190;- } else i36 = 190; while (0);- if ((((i36 | 0) == 190 ? i43 >>> 0 < 2147483647 : 0) ? (i63 = _sbrk(i43 | 0) | 0, i43 = _sbrk(0) | 0, i63 >>> 0 < i43 >>> 0 & ((i63 | 0) != (-1 | 0) & (i43 | 0) != (-1 | 0))) : 0) ? (i60 = i43 - i63 | 0, i60 >>> 0 > (i31 + 40 | 0) >>> 0) : 0) {- i58 = i63;- i59 = i60;- i36 = 193;- }- if ((i36 | 0) == 193) {- i60 = (HEAP32[152] | 0) + i59 | 0;- HEAP32[152] = i60;- if (i60 >>> 0 > (HEAP32[153] | 0) >>> 0) HEAP32[153] = i60;- i60 = HEAP32[50] | 0;- do if (i60) {- i63 = 624;- do {- i43 = HEAP32[i63 >> 2] | 0;- i61 = i63 + 4 | 0;- i44 = HEAP32[i61 >> 2] | 0;- if ((i58 | 0) == (i43 + i44 | 0)) {- i64 = i43;- i65 = i61;- i66 = i44;- i67 = i63;- i36 = 203;- break;- }- i63 = HEAP32[i63 + 8 >> 2] | 0;- } while ((i63 | 0) != 0);- if (((i36 | 0) == 203 ? (HEAP32[i67 + 12 >> 2] & 8 | 0) == 0 : 0) ? i60 >>> 0 < i58 >>> 0 & i60 >>> 0 >= i64 >>> 0 : 0) {- HEAP32[i65 >> 2] = i66 + i59;- i63 = i60 + 8 | 0;- i44 = (i63 & 7 | 0) == 0 ? 0 : 0 - i63 & 7;- i63 = i60 + i44 | 0;- i61 = i59 - i44 + (HEAP32[47] | 0) | 0;- HEAP32[50] = i63;- HEAP32[47] = i61;- HEAP32[i63 + 4 >> 2] = i61 | 1;- HEAP32[i63 + i61 + 4 >> 2] = 40;- HEAP32[51] = HEAP32[166];- break;- }- i61 = HEAP32[48] | 0;- if (i58 >>> 0 < i61 >>> 0) {- HEAP32[48] = i58;- i68 = i58;- } else i68 = i61;- i61 = i58 + i59 | 0;- i63 = 624;- while (1) {- if ((HEAP32[i63 >> 2] | 0) == (i61 | 0)) {- i69 = i63;- i70 = i63;- i36 = 211;- break;- }- i63 = HEAP32[i63 + 8 >> 2] | 0;- if (!i63) {- i71 = 624;- break;- }- }- if ((i36 | 0) == 211) if (!(HEAP32[i70 + 12 >> 2] & 8)) {- HEAP32[i69 >> 2] = i58;- i63 = i70 + 4 | 0;- HEAP32[i63 >> 2] = (HEAP32[i63 >> 2] | 0) + i59;- i63 = i58 + 8 | 0;- i44 = i58 + ((i63 & 7 | 0) == 0 ? 0 : 0 - i63 & 7) | 0;- i63 = i61 + 8 | 0;- i43 = i61 + ((i63 & 7 | 0) == 0 ? 0 : 0 - i63 & 7) | 0;- i63 = i44 + i31 | 0;- i53 = i43 - i44 - i31 | 0;- HEAP32[i44 + 4 >> 2] = i31 | 3;- do if ((i43 | 0) != (i60 | 0)) {- if ((i43 | 0) == (HEAP32[49] | 0)) {- i62 = (HEAP32[46] | 0) + i53 | 0;- HEAP32[46] = i62;- HEAP32[49] = i63;- HEAP32[i63 + 4 >> 2] = i62 | 1;- HEAP32[i63 + i62 >> 2] = i62;- break;- }- i62 = HEAP32[i43 + 4 >> 2] | 0;- if ((i62 & 3 | 0) == 1) {- i57 = i62 & -8;- i56 = i62 >>> 3;- L331 : do if (i62 >>> 0 >= 256) {- i54 = HEAP32[i43 + 24 >> 2] | 0;- i55 = HEAP32[i43 + 12 >> 2] | 0;- do if ((i55 | 0) == (i43 | 0)) {- i45 = i43 + 16 | 0;- i5 = i45 + 4 | 0;- i52 = HEAP32[i5 >> 2] | 0;- if (!i52) {- i50 = HEAP32[i45 >> 2] | 0;- if (!i50) {- i72 = 0;- break;- } else {- i73 = i50;- i74 = i45;- }- } else {- i73 = i52;- i74 = i5;- }- while (1) {- i5 = i73 + 20 | 0;- i52 = HEAP32[i5 >> 2] | 0;- if (i52) {- i73 = i52;- i74 = i5;- continue;- }- i5 = i73 + 16 | 0;- i52 = HEAP32[i5 >> 2] | 0;- if (!i52) {- i75 = i73;- i76 = i74;- break;- } else {- i73 = i52;- i74 = i5;- }- }- if (i76 >>> 0 < i68 >>> 0) _abort(); else {- HEAP32[i76 >> 2] = 0;- i72 = i75;- break;- }- } else {- i5 = HEAP32[i43 + 8 >> 2] | 0;- if (i5 >>> 0 < i68 >>> 0) _abort();- i52 = i5 + 12 | 0;- if ((HEAP32[i52 >> 2] | 0) != (i43 | 0)) _abort();- i45 = i55 + 8 | 0;- if ((HEAP32[i45 >> 2] | 0) == (i43 | 0)) {- HEAP32[i52 >> 2] = i55;- HEAP32[i45 >> 2] = i5;- i72 = i55;- break;- } else _abort();- } while (0);- if (!i54) break;- i55 = HEAP32[i43 + 28 >> 2] | 0;- i5 = 480 + (i55 << 2) | 0;- do if ((i43 | 0) != (HEAP32[i5 >> 2] | 0)) {- if (i54 >>> 0 < (HEAP32[48] | 0) >>> 0) _abort();- i45 = i54 + 16 | 0;- if ((HEAP32[i45 >> 2] | 0) == (i43 | 0)) HEAP32[i45 >> 2] = i72; else HEAP32[i54 + 20 >> 2] = i72;- if (!i72) break L331;- } else {- HEAP32[i5 >> 2] = i72;- if (i72) break;- HEAP32[45] = HEAP32[45] & ~(1 << i55);- break L331;- } while (0);- i55 = HEAP32[48] | 0;- if (i72 >>> 0 < i55 >>> 0) _abort();- HEAP32[i72 + 24 >> 2] = i54;- i5 = i43 + 16 | 0;- i45 = HEAP32[i5 >> 2] | 0;- do if (i45) if (i45 >>> 0 < i55 >>> 0) _abort(); else {- HEAP32[i72 + 16 >> 2] = i45;- HEAP32[i45 + 24 >> 2] = i72;- break;- } while (0);- i45 = HEAP32[i5 + 4 >> 2] | 0;- if (!i45) break;- if (i45 >>> 0 < (HEAP32[48] | 0) >>> 0) _abort(); else {- HEAP32[i72 + 20 >> 2] = i45;- HEAP32[i45 + 24 >> 2] = i72;- break;- }- } else {- i45 = HEAP32[i43 + 8 >> 2] | 0;- i55 = HEAP32[i43 + 12 >> 2] | 0;- i54 = 216 + (i56 << 1 << 2) | 0;- do if ((i45 | 0) != (i54 | 0)) {- if (i45 >>> 0 < i68 >>> 0) _abort();- if ((HEAP32[i45 + 12 >> 2] | 0) == (i43 | 0)) break;- _abort();- } while (0);- if ((i55 | 0) == (i45 | 0)) {- HEAP32[44] = HEAP32[44] & ~(1 << i56);- break;- }- do if ((i55 | 0) == (i54 | 0)) i77 = i55 + 8 | 0; else {- if (i55 >>> 0 < i68 >>> 0) _abort();- i5 = i55 + 8 | 0;- if ((HEAP32[i5 >> 2] | 0) == (i43 | 0)) {- i77 = i5;- break;- }- _abort();- } while (0);- HEAP32[i45 + 12 >> 2] = i55;- HEAP32[i77 >> 2] = i45;- } while (0);- i78 = i43 + i57 | 0;- i79 = i57 + i53 | 0;- } else {- i78 = i43;- i79 = i53;- }- i56 = i78 + 4 | 0;- HEAP32[i56 >> 2] = HEAP32[i56 >> 2] & -2;- HEAP32[i63 + 4 >> 2] = i79 | 1;- HEAP32[i63 + i79 >> 2] = i79;- i56 = i79 >>> 3;- if (i79 >>> 0 < 256) {- i62 = 216 + (i56 << 1 << 2) | 0;- i54 = HEAP32[44] | 0;- i5 = 1 << i56;- do if (!(i54 & i5)) {- HEAP32[44] = i54 | i5;- i80 = i62 + 8 | 0;- i81 = i62;- } else {- i56 = i62 + 8 | 0;- i52 = HEAP32[i56 >> 2] | 0;- if (i52 >>> 0 >= (HEAP32[48] | 0) >>> 0) {- i80 = i56;- i81 = i52;- break;- }- _abort();- } while (0);- HEAP32[i80 >> 2] = i63;- HEAP32[i81 + 12 >> 2] = i63;- HEAP32[i63 + 8 >> 2] = i81;- HEAP32[i63 + 12 >> 2] = i62;- break;- }- i5 = i79 >>> 8;- do if (!i5) i82 = 0; else {- if (i79 >>> 0 > 16777215) {- i82 = 31;- break;- }- i54 = (i5 + 1048320 | 0) >>> 16 & 8;- i57 = i5 << i54;- i52 = (i57 + 520192 | 0) >>> 16 & 4;- i56 = i57 << i52;- i57 = (i56 + 245760 | 0) >>> 16 & 2;- i50 = 14 - (i52 | i54 | i57) + (i56 << i57 >>> 15) | 0;- i82 = i79 >>> (i50 + 7 | 0) & 1 | i50 << 1;- } while (0);- i5 = 480 + (i82 << 2) | 0;- HEAP32[i63 + 28 >> 2] = i82;- i62 = i63 + 16 | 0;- HEAP32[i62 + 4 >> 2] = 0;- HEAP32[i62 >> 2] = 0;- i62 = HEAP32[45] | 0;- i50 = 1 << i82;- if (!(i62 & i50)) {- HEAP32[45] = i62 | i50;- HEAP32[i5 >> 2] = i63;- HEAP32[i63 + 24 >> 2] = i5;- HEAP32[i63 + 12 >> 2] = i63;- HEAP32[i63 + 8 >> 2] = i63;- break;- }- i50 = i79 << ((i82 | 0) == 31 ? 0 : 25 - (i82 >>> 1) | 0);- i62 = HEAP32[i5 >> 2] | 0;- while (1) {- if ((HEAP32[i62 + 4 >> 2] & -8 | 0) == (i79 | 0)) {- i83 = i62;- i36 = 281;- break;- }- i5 = i62 + 16 + (i50 >>> 31 << 2) | 0;- i57 = HEAP32[i5 >> 2] | 0;- if (!i57) {- i84 = i5;- i85 = i62;- i36 = 278;- break;- } else {- i50 = i50 << 1;- i62 = i57;- }- }- if ((i36 | 0) == 278) if (i84 >>> 0 < (HEAP32[48] | 0) >>> 0) _abort(); else {- HEAP32[i84 >> 2] = i63;- HEAP32[i63 + 24 >> 2] = i85;- HEAP32[i63 + 12 >> 2] = i63;- HEAP32[i63 + 8 >> 2] = i63;- break;- } else if ((i36 | 0) == 281) {- i62 = i83 + 8 | 0;- i50 = HEAP32[i62 >> 2] | 0;- i57 = HEAP32[48] | 0;- if (i50 >>> 0 >= i57 >>> 0 & i83 >>> 0 >= i57 >>> 0) {- HEAP32[i50 + 12 >> 2] = i63;- HEAP32[i62 >> 2] = i63;- HEAP32[i63 + 8 >> 2] = i50;- HEAP32[i63 + 12 >> 2] = i83;- HEAP32[i63 + 24 >> 2] = 0;- break;- } else _abort();- }- } else {- i50 = (HEAP32[47] | 0) + i53 | 0;- HEAP32[47] = i50;- HEAP32[50] = i63;- HEAP32[i63 + 4 >> 2] = i50 | 1;- } while (0);- i13 = i44 + 8 | 0;- return i13 | 0;- } else i71 = 624;- while (1) {- i63 = HEAP32[i71 >> 2] | 0;- if (i63 >>> 0 <= i60 >>> 0 ? (i53 = i63 + (HEAP32[i71 + 4 >> 2] | 0) | 0, i53 >>> 0 > i60 >>> 0) : 0) {- i86 = i53;- break;- }- i71 = HEAP32[i71 + 8 >> 2] | 0;- }- i44 = i86 + -47 | 0;- i53 = i44 + 8 | 0;- i63 = i44 + ((i53 & 7 | 0) == 0 ? 0 : 0 - i53 & 7) | 0;- i53 = i60 + 16 | 0;- i44 = i63 >>> 0 < i53 >>> 0 ? i60 : i63;- i63 = i44 + 8 | 0;- i43 = i58 + 8 | 0;- i61 = (i43 & 7 | 0) == 0 ? 0 : 0 - i43 & 7;- i43 = i58 + i61 | 0;- i50 = i59 + -40 - i61 | 0;- HEAP32[50] = i43;- HEAP32[47] = i50;- HEAP32[i43 + 4 >> 2] = i50 | 1;- HEAP32[i43 + i50 + 4 >> 2] = 40;- HEAP32[51] = HEAP32[166];- i50 = i44 + 4 | 0;- HEAP32[i50 >> 2] = 27;- HEAP32[i63 >> 2] = HEAP32[156];- HEAP32[i63 + 4 >> 2] = HEAP32[157];- HEAP32[i63 + 8 >> 2] = HEAP32[158];- HEAP32[i63 + 12 >> 2] = HEAP32[159];- HEAP32[156] = i58;- HEAP32[157] = i59;- HEAP32[159] = 0;- HEAP32[158] = i63;- i63 = i44 + 24 | 0;- do {- i63 = i63 + 4 | 0;- HEAP32[i63 >> 2] = 7;- } while ((i63 + 4 | 0) >>> 0 < i86 >>> 0);- if ((i44 | 0) != (i60 | 0)) {- i63 = i44 - i60 | 0;- HEAP32[i50 >> 2] = HEAP32[i50 >> 2] & -2;- HEAP32[i60 + 4 >> 2] = i63 | 1;- HEAP32[i44 >> 2] = i63;- i43 = i63 >>> 3;- if (i63 >>> 0 < 256) {- i61 = 216 + (i43 << 1 << 2) | 0;- i62 = HEAP32[44] | 0;- i57 = 1 << i43;- if (i62 & i57) {- i43 = i61 + 8 | 0;- i5 = HEAP32[i43 >> 2] | 0;- if (i5 >>> 0 < (HEAP32[48] | 0) >>> 0) _abort(); else {- i87 = i43;- i88 = i5;- }- } else {- HEAP32[44] = i62 | i57;- i87 = i61 + 8 | 0;- i88 = i61;- }- HEAP32[i87 >> 2] = i60;- HEAP32[i88 + 12 >> 2] = i60;- HEAP32[i60 + 8 >> 2] = i88;- HEAP32[i60 + 12 >> 2] = i61;- break;- }- i61 = i63 >>> 8;- if (i61) if (i63 >>> 0 > 16777215) i89 = 31; else {- i57 = (i61 + 1048320 | 0) >>> 16 & 8;- i62 = i61 << i57;- i61 = (i62 + 520192 | 0) >>> 16 & 4;- i5 = i62 << i61;- i62 = (i5 + 245760 | 0) >>> 16 & 2;- i43 = 14 - (i61 | i57 | i62) + (i5 << i62 >>> 15) | 0;- i89 = i63 >>> (i43 + 7 | 0) & 1 | i43 << 1;- } else i89 = 0;- i43 = 480 + (i89 << 2) | 0;- HEAP32[i60 + 28 >> 2] = i89;- HEAP32[i60 + 20 >> 2] = 0;- HEAP32[i53 >> 2] = 0;- i62 = HEAP32[45] | 0;- i5 = 1 << i89;- if (!(i62 & i5)) {- HEAP32[45] = i62 | i5;- HEAP32[i43 >> 2] = i60;- HEAP32[i60 + 24 >> 2] = i43;- HEAP32[i60 + 12 >> 2] = i60;- HEAP32[i60 + 8 >> 2] = i60;- break;- }- i5 = i63 << ((i89 | 0) == 31 ? 0 : 25 - (i89 >>> 1) | 0);- i62 = HEAP32[i43 >> 2] | 0;- while (1) {- if ((HEAP32[i62 + 4 >> 2] & -8 | 0) == (i63 | 0)) {- i90 = i62;- i36 = 307;- break;- }- i43 = i62 + 16 + (i5 >>> 31 << 2) | 0;- i57 = HEAP32[i43 >> 2] | 0;- if (!i57) {- i91 = i43;- i92 = i62;- i36 = 304;- break;- } else {- i5 = i5 << 1;- i62 = i57;- }- }- if ((i36 | 0) == 304) if (i91 >>> 0 < (HEAP32[48] | 0) >>> 0) _abort(); else {- HEAP32[i91 >> 2] = i60;- HEAP32[i60 + 24 >> 2] = i92;- HEAP32[i60 + 12 >> 2] = i60;- HEAP32[i60 + 8 >> 2] = i60;- break;- } else if ((i36 | 0) == 307) {- i62 = i90 + 8 | 0;- i5 = HEAP32[i62 >> 2] | 0;- i63 = HEAP32[48] | 0;- if (i5 >>> 0 >= i63 >>> 0 & i90 >>> 0 >= i63 >>> 0) {- HEAP32[i5 + 12 >> 2] = i60;- HEAP32[i62 >> 2] = i60;- HEAP32[i60 + 8 >> 2] = i5;- HEAP32[i60 + 12 >> 2] = i90;- HEAP32[i60 + 24 >> 2] = 0;- break;- } else _abort();- }- }- } else {- i5 = HEAP32[48] | 0;- if ((i5 | 0) == 0 | i58 >>> 0 < i5 >>> 0) HEAP32[48] = i58;- HEAP32[156] = i58;- HEAP32[157] = i59;- HEAP32[159] = 0;- HEAP32[53] = HEAP32[162];- HEAP32[52] = -1;- i5 = 0;- do {- i62 = 216 + (i5 << 1 << 2) | 0;- HEAP32[i62 + 12 >> 2] = i62;- HEAP32[i62 + 8 >> 2] = i62;- i5 = i5 + 1 | 0;- } while ((i5 | 0) != 32);- i5 = i58 + 8 | 0;- i62 = (i5 & 7 | 0) == 0 ? 0 : 0 - i5 & 7;- i5 = i58 + i62 | 0;- i63 = i59 + -40 - i62 | 0;- HEAP32[50] = i5;- HEAP32[47] = i63;- HEAP32[i5 + 4 >> 2] = i63 | 1;- HEAP32[i5 + i63 + 4 >> 2] = 40;- HEAP32[51] = HEAP32[166];- } while (0);- i59 = HEAP32[47] | 0;- if (i59 >>> 0 > i31 >>> 0) {- i58 = i59 - i31 | 0;- HEAP32[47] = i58;- i59 = HEAP32[50] | 0;- i60 = i59 + i31 | 0;- HEAP32[50] = i60;- HEAP32[i60 + 4 >> 2] = i58 | 1;- HEAP32[i59 + 4 >> 2] = i31 | 3;- i13 = i59 + 8 | 0;- return i13 | 0;- }- }- HEAP32[(___errno_location() | 0) >> 2] = 12;- i13 = 0;- return i13 | 0;-}--function _free(i1) {- i1 = i1 | 0;- var i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, i18 = 0, i19 = 0, i20 = 0, i21 = 0, i22 = 0, i23 = 0, i24 = 0, i25 = 0, i26 = 0, i27 = 0, i28 = 0, i29 = 0, i30 = 0, i31 = 0, i32 = 0, i33 = 0, i34 = 0, i35 = 0, i36 = 0, i37 = 0;- if (!i1) return;- i2 = i1 + -8 | 0;- i3 = HEAP32[48] | 0;- if (i2 >>> 0 < i3 >>> 0) _abort();- i4 = HEAP32[i1 + -4 >> 2] | 0;- i1 = i4 & 3;- if ((i1 | 0) == 1) _abort();- i5 = i4 & -8;- i6 = i2 + i5 | 0;- do if (!(i4 & 1)) {- i7 = HEAP32[i2 >> 2] | 0;- if (!i1) return;- i8 = i2 + (0 - i7) | 0;- i9 = i7 + i5 | 0;- if (i8 >>> 0 < i3 >>> 0) _abort();- if ((i8 | 0) == (HEAP32[49] | 0)) {- i10 = i6 + 4 | 0;- i11 = HEAP32[i10 >> 2] | 0;- if ((i11 & 3 | 0) != 3) {- i12 = i8;- i13 = i9;- break;- }- HEAP32[46] = i9;- HEAP32[i10 >> 2] = i11 & -2;- HEAP32[i8 + 4 >> 2] = i9 | 1;- HEAP32[i8 + i9 >> 2] = i9;- return;- }- i11 = i7 >>> 3;- if (i7 >>> 0 < 256) {- i7 = HEAP32[i8 + 8 >> 2] | 0;- i10 = HEAP32[i8 + 12 >> 2] | 0;- i14 = 216 + (i11 << 1 << 2) | 0;- if ((i7 | 0) != (i14 | 0)) {- if (i7 >>> 0 < i3 >>> 0) _abort();- if ((HEAP32[i7 + 12 >> 2] | 0) != (i8 | 0)) _abort();- }- if ((i10 | 0) == (i7 | 0)) {- HEAP32[44] = HEAP32[44] & ~(1 << i11);- i12 = i8;- i13 = i9;- break;- }- if ((i10 | 0) != (i14 | 0)) {- if (i10 >>> 0 < i3 >>> 0) _abort();- i14 = i10 + 8 | 0;- if ((HEAP32[i14 >> 2] | 0) == (i8 | 0)) i15 = i14; else _abort();- } else i15 = i10 + 8 | 0;- HEAP32[i7 + 12 >> 2] = i10;- HEAP32[i15 >> 2] = i7;- i12 = i8;- i13 = i9;- break;- }- i7 = HEAP32[i8 + 24 >> 2] | 0;- i10 = HEAP32[i8 + 12 >> 2] | 0;- do if ((i10 | 0) == (i8 | 0)) {- i14 = i8 + 16 | 0;- i11 = i14 + 4 | 0;- i16 = HEAP32[i11 >> 2] | 0;- if (!i16) {- i17 = HEAP32[i14 >> 2] | 0;- if (!i17) {- i18 = 0;- break;- } else {- i19 = i17;- i20 = i14;- }- } else {- i19 = i16;- i20 = i11;- }- while (1) {- i11 = i19 + 20 | 0;- i16 = HEAP32[i11 >> 2] | 0;- if (i16) {- i19 = i16;- i20 = i11;- continue;- }- i11 = i19 + 16 | 0;- i16 = HEAP32[i11 >> 2] | 0;- if (!i16) {- i21 = i19;- i22 = i20;- break;- } else {- i19 = i16;- i20 = i11;- }- }- if (i22 >>> 0 < i3 >>> 0) _abort(); else {- HEAP32[i22 >> 2] = 0;- i18 = i21;- break;- }- } else {- i11 = HEAP32[i8 + 8 >> 2] | 0;- if (i11 >>> 0 < i3 >>> 0) _abort();- i16 = i11 + 12 | 0;- if ((HEAP32[i16 >> 2] | 0) != (i8 | 0)) _abort();- i14 = i10 + 8 | 0;- if ((HEAP32[i14 >> 2] | 0) == (i8 | 0)) {- HEAP32[i16 >> 2] = i10;- HEAP32[i14 >> 2] = i11;- i18 = i10;- break;- } else _abort();- } while (0);- if (i7) {- i10 = HEAP32[i8 + 28 >> 2] | 0;- i11 = 480 + (i10 << 2) | 0;- if ((i8 | 0) == (HEAP32[i11 >> 2] | 0)) {- HEAP32[i11 >> 2] = i18;- if (!i18) {- HEAP32[45] = HEAP32[45] & ~(1 << i10);- i12 = i8;- i13 = i9;- break;- }- } else {- if (i7 >>> 0 < (HEAP32[48] | 0) >>> 0) _abort();- i10 = i7 + 16 | 0;- if ((HEAP32[i10 >> 2] | 0) == (i8 | 0)) HEAP32[i10 >> 2] = i18; else HEAP32[i7 + 20 >> 2] = i18;- if (!i18) {- i12 = i8;- i13 = i9;- break;- }- }- i10 = HEAP32[48] | 0;- if (i18 >>> 0 < i10 >>> 0) _abort();- HEAP32[i18 + 24 >> 2] = i7;- i11 = i8 + 16 | 0;- i14 = HEAP32[i11 >> 2] | 0;- do if (i14) if (i14 >>> 0 < i10 >>> 0) _abort(); else {- HEAP32[i18 + 16 >> 2] = i14;- HEAP32[i14 + 24 >> 2] = i18;- break;- } while (0);- i14 = HEAP32[i11 + 4 >> 2] | 0;- if (i14) if (i14 >>> 0 < (HEAP32[48] | 0) >>> 0) _abort(); else {- HEAP32[i18 + 20 >> 2] = i14;- HEAP32[i14 + 24 >> 2] = i18;- i12 = i8;- i13 = i9;- break;- } else {- i12 = i8;- i13 = i9;- }- } else {- i12 = i8;- i13 = i9;- }- } else {- i12 = i2;- i13 = i5;- } while (0);- if (i12 >>> 0 >= i6 >>> 0) _abort();- i5 = i6 + 4 | 0;- i2 = HEAP32[i5 >> 2] | 0;- if (!(i2 & 1)) _abort();- if (!(i2 & 2)) {- if ((i6 | 0) == (HEAP32[50] | 0)) {- i18 = (HEAP32[47] | 0) + i13 | 0;- HEAP32[47] = i18;- HEAP32[50] = i12;- HEAP32[i12 + 4 >> 2] = i18 | 1;- if ((i12 | 0) != (HEAP32[49] | 0)) return;- HEAP32[49] = 0;- HEAP32[46] = 0;- return;- }- if ((i6 | 0) == (HEAP32[49] | 0)) {- i18 = (HEAP32[46] | 0) + i13 | 0;- HEAP32[46] = i18;- HEAP32[49] = i12;- HEAP32[i12 + 4 >> 2] = i18 | 1;- HEAP32[i12 + i18 >> 2] = i18;- return;- }- i18 = (i2 & -8) + i13 | 0;- i3 = i2 >>> 3;- do if (i2 >>> 0 >= 256) {- i21 = HEAP32[i6 + 24 >> 2] | 0;- i22 = HEAP32[i6 + 12 >> 2] | 0;- do if ((i22 | 0) == (i6 | 0)) {- i20 = i6 + 16 | 0;- i19 = i20 + 4 | 0;- i15 = HEAP32[i19 >> 2] | 0;- if (!i15) {- i1 = HEAP32[i20 >> 2] | 0;- if (!i1) {- i23 = 0;- break;- } else {- i24 = i1;- i25 = i20;- }- } else {- i24 = i15;- i25 = i19;- }- while (1) {- i19 = i24 + 20 | 0;- i15 = HEAP32[i19 >> 2] | 0;- if (i15) {- i24 = i15;- i25 = i19;- continue;- }- i19 = i24 + 16 | 0;- i15 = HEAP32[i19 >> 2] | 0;- if (!i15) {- i26 = i24;- i27 = i25;- break;- } else {- i24 = i15;- i25 = i19;- }- }- if (i27 >>> 0 < (HEAP32[48] | 0) >>> 0) _abort(); else {- HEAP32[i27 >> 2] = 0;- i23 = i26;- break;- }- } else {- i19 = HEAP32[i6 + 8 >> 2] | 0;- if (i19 >>> 0 < (HEAP32[48] | 0) >>> 0) _abort();- i15 = i19 + 12 | 0;- if ((HEAP32[i15 >> 2] | 0) != (i6 | 0)) _abort();- i20 = i22 + 8 | 0;- if ((HEAP32[i20 >> 2] | 0) == (i6 | 0)) {- HEAP32[i15 >> 2] = i22;- HEAP32[i20 >> 2] = i19;- i23 = i22;- break;- } else _abort();- } while (0);- if (i21) {- i22 = HEAP32[i6 + 28 >> 2] | 0;- i9 = 480 + (i22 << 2) | 0;- if ((i6 | 0) == (HEAP32[i9 >> 2] | 0)) {- HEAP32[i9 >> 2] = i23;- if (!i23) {- HEAP32[45] = HEAP32[45] & ~(1 << i22);- break;- }- } else {- if (i21 >>> 0 < (HEAP32[48] | 0) >>> 0) _abort();- i22 = i21 + 16 | 0;- if ((HEAP32[i22 >> 2] | 0) == (i6 | 0)) HEAP32[i22 >> 2] = i23; else HEAP32[i21 + 20 >> 2] = i23;- if (!i23) break;- }- i22 = HEAP32[48] | 0;- if (i23 >>> 0 < i22 >>> 0) _abort();- HEAP32[i23 + 24 >> 2] = i21;- i9 = i6 + 16 | 0;- i8 = HEAP32[i9 >> 2] | 0;- do if (i8) if (i8 >>> 0 < i22 >>> 0) _abort(); else {- HEAP32[i23 + 16 >> 2] = i8;- HEAP32[i8 + 24 >> 2] = i23;- break;- } while (0);- i8 = HEAP32[i9 + 4 >> 2] | 0;- if (i8) if (i8 >>> 0 < (HEAP32[48] | 0) >>> 0) _abort(); else {- HEAP32[i23 + 20 >> 2] = i8;- HEAP32[i8 + 24 >> 2] = i23;- break;- }- }- } else {- i8 = HEAP32[i6 + 8 >> 2] | 0;- i22 = HEAP32[i6 + 12 >> 2] | 0;- i21 = 216 + (i3 << 1 << 2) | 0;- if ((i8 | 0) != (i21 | 0)) {- if (i8 >>> 0 < (HEAP32[48] | 0) >>> 0) _abort();- if ((HEAP32[i8 + 12 >> 2] | 0) != (i6 | 0)) _abort();- }- if ((i22 | 0) == (i8 | 0)) {- HEAP32[44] = HEAP32[44] & ~(1 << i3);- break;- }- if ((i22 | 0) != (i21 | 0)) {- if (i22 >>> 0 < (HEAP32[48] | 0) >>> 0) _abort();- i21 = i22 + 8 | 0;- if ((HEAP32[i21 >> 2] | 0) == (i6 | 0)) i28 = i21; else _abort();- } else i28 = i22 + 8 | 0;- HEAP32[i8 + 12 >> 2] = i22;- HEAP32[i28 >> 2] = i8;- } while (0);- HEAP32[i12 + 4 >> 2] = i18 | 1;- HEAP32[i12 + i18 >> 2] = i18;- if ((i12 | 0) == (HEAP32[49] | 0)) {- HEAP32[46] = i18;- return;- } else i29 = i18;- } else {- HEAP32[i5 >> 2] = i2 & -2;- HEAP32[i12 + 4 >> 2] = i13 | 1;- HEAP32[i12 + i13 >> 2] = i13;- i29 = i13;- }- i13 = i29 >>> 3;- if (i29 >>> 0 < 256) {- i2 = 216 + (i13 << 1 << 2) | 0;- i5 = HEAP32[44] | 0;- i18 = 1 << i13;- if (i5 & i18) {- i13 = i2 + 8 | 0;- i28 = HEAP32[i13 >> 2] | 0;- if (i28 >>> 0 < (HEAP32[48] | 0) >>> 0) _abort(); else {- i30 = i13;- i31 = i28;- }- } else {- HEAP32[44] = i5 | i18;- i30 = i2 + 8 | 0;- i31 = i2;- }- HEAP32[i30 >> 2] = i12;- HEAP32[i31 + 12 >> 2] = i12;- HEAP32[i12 + 8 >> 2] = i31;- HEAP32[i12 + 12 >> 2] = i2;- return;- }- i2 = i29 >>> 8;- if (i2) if (i29 >>> 0 > 16777215) i32 = 31; else {- i31 = (i2 + 1048320 | 0) >>> 16 & 8;- i30 = i2 << i31;- i2 = (i30 + 520192 | 0) >>> 16 & 4;- i18 = i30 << i2;- i30 = (i18 + 245760 | 0) >>> 16 & 2;- i5 = 14 - (i2 | i31 | i30) + (i18 << i30 >>> 15) | 0;- i32 = i29 >>> (i5 + 7 | 0) & 1 | i5 << 1;- } else i32 = 0;- i5 = 480 + (i32 << 2) | 0;- HEAP32[i12 + 28 >> 2] = i32;- HEAP32[i12 + 20 >> 2] = 0;- HEAP32[i12 + 16 >> 2] = 0;- i30 = HEAP32[45] | 0;- i18 = 1 << i32;- do if (i30 & i18) {- i31 = i29 << ((i32 | 0) == 31 ? 0 : 25 - (i32 >>> 1) | 0);- i2 = HEAP32[i5 >> 2] | 0;- while (1) {- if ((HEAP32[i2 + 4 >> 2] & -8 | 0) == (i29 | 0)) {- i33 = i2;- i34 = 130;- break;- }- i28 = i2 + 16 + (i31 >>> 31 << 2) | 0;- i13 = HEAP32[i28 >> 2] | 0;- if (!i13) {- i35 = i28;- i36 = i2;- i34 = 127;- break;- } else {- i31 = i31 << 1;- i2 = i13;- }- }- if ((i34 | 0) == 127) if (i35 >>> 0 < (HEAP32[48] | 0) >>> 0) _abort(); else {- HEAP32[i35 >> 2] = i12;- HEAP32[i12 + 24 >> 2] = i36;- HEAP32[i12 + 12 >> 2] = i12;- HEAP32[i12 + 8 >> 2] = i12;- break;- } else if ((i34 | 0) == 130) {- i2 = i33 + 8 | 0;- i31 = HEAP32[i2 >> 2] | 0;- i9 = HEAP32[48] | 0;- if (i31 >>> 0 >= i9 >>> 0 & i33 >>> 0 >= i9 >>> 0) {- HEAP32[i31 + 12 >> 2] = i12;- HEAP32[i2 >> 2] = i12;- HEAP32[i12 + 8 >> 2] = i31;- HEAP32[i12 + 12 >> 2] = i33;- HEAP32[i12 + 24 >> 2] = 0;- break;- } else _abort();- }- } else {- HEAP32[45] = i30 | i18;- HEAP32[i5 >> 2] = i12;- HEAP32[i12 + 24 >> 2] = i5;- HEAP32[i12 + 12 >> 2] = i12;- HEAP32[i12 + 8 >> 2] = i12;- } while (0);- i12 = (HEAP32[52] | 0) + -1 | 0;- HEAP32[52] = i12;- if (!i12) i37 = 632; else return;- while (1) {- i12 = HEAP32[i37 >> 2] | 0;- if (!i12) break; else i37 = i12 + 8 | 0;- }- HEAP32[52] = -1;- return;-}--function ___stdio_write(i1, i2, i3) {- i1 = i1 | 0;- i2 = i2 | 0;- i3 = i3 | 0;- var i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, i18 = 0, i19 = 0, i20 = 0, i21 = 0, i22 = 0, i23 = 0, i24 = 0;- i4 = STACKTOP;- STACKTOP = STACKTOP + 48 | 0;- i5 = i4 + 16 | 0;- i6 = i4;- i7 = i4 + 32 | 0;- i8 = i1 + 28 | 0;- i9 = HEAP32[i8 >> 2] | 0;- HEAP32[i7 >> 2] = i9;- i10 = i1 + 20 | 0;- i11 = (HEAP32[i10 >> 2] | 0) - i9 | 0;- HEAP32[i7 + 4 >> 2] = i11;- HEAP32[i7 + 8 >> 2] = i2;- HEAP32[i7 + 12 >> 2] = i3;- i2 = i1 + 60 | 0;- i9 = i1 + 44 | 0;- i12 = i7;- i7 = 2;- i13 = i11 + i3 | 0;- while (1) {- if (!(HEAP32[2] | 0)) {- HEAP32[i5 >> 2] = HEAP32[i2 >> 2];- HEAP32[i5 + 4 >> 2] = i12;- HEAP32[i5 + 8 >> 2] = i7;- i14 = ___syscall_ret(___syscall146(146, i5 | 0) | 0) | 0;- } else {- _pthread_cleanup_push(4, i1 | 0);- HEAP32[i6 >> 2] = HEAP32[i2 >> 2];- HEAP32[i6 + 4 >> 2] = i12;- HEAP32[i6 + 8 >> 2] = i7;- i11 = ___syscall_ret(___syscall146(146, i6 | 0) | 0) | 0;- _pthread_cleanup_pop(0);- i14 = i11;- }- if ((i13 | 0) == (i14 | 0)) {- i15 = 6;- break;- }- if ((i14 | 0) < 0) {- i16 = i12;- i17 = i7;- i15 = 8;- break;- }- i11 = i13 - i14 | 0;- i18 = HEAP32[i12 + 4 >> 2] | 0;- if (i14 >>> 0 <= i18 >>> 0) if ((i7 | 0) == 2) {- HEAP32[i8 >> 2] = (HEAP32[i8 >> 2] | 0) + i14;- i19 = i18;- i20 = i14;- i21 = i12;- i22 = 2;- } else {- i19 = i18;- i20 = i14;- i21 = i12;- i22 = i7;- } else {- i23 = HEAP32[i9 >> 2] | 0;- HEAP32[i8 >> 2] = i23;- HEAP32[i10 >> 2] = i23;- i19 = HEAP32[i12 + 12 >> 2] | 0;- i20 = i14 - i18 | 0;- i21 = i12 + 8 | 0;- i22 = i7 + -1 | 0;- }- HEAP32[i21 >> 2] = (HEAP32[i21 >> 2] | 0) + i20;- HEAP32[i21 + 4 >> 2] = i19 - i20;- i12 = i21;- i7 = i22;- i13 = i11;- }- if ((i15 | 0) == 6) {- i13 = HEAP32[i9 >> 2] | 0;- HEAP32[i1 + 16 >> 2] = i13 + (HEAP32[i1 + 48 >> 2] | 0);- i9 = i13;- HEAP32[i8 >> 2] = i9;- HEAP32[i10 >> 2] = i9;- i24 = i3;- } else if ((i15 | 0) == 8) {- HEAP32[i1 + 16 >> 2] = 0;- HEAP32[i8 >> 2] = 0;- HEAP32[i10 >> 2] = 0;- HEAP32[i1 >> 2] = HEAP32[i1 >> 2] | 32;- if ((i17 | 0) == 2) i24 = 0; else i24 = i3 - (HEAP32[i16 + 4 >> 2] | 0) | 0;- }- STACKTOP = i4;- return i24 | 0;-}--function ___fwritex(i1, i2, i3) {- i1 = i1 | 0;- i2 = i2 | 0;- i3 = i3 | 0;- var i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0;- i4 = i3 + 16 | 0;- i5 = HEAP32[i4 >> 2] | 0;- if (!i5) if (!(___towrite(i3) | 0)) {- i6 = HEAP32[i4 >> 2] | 0;- i7 = 5;- } else i8 = 0; else {- i6 = i5;- i7 = 5;- }- L5 : do if ((i7 | 0) == 5) {- i5 = i3 + 20 | 0;- i4 = HEAP32[i5 >> 2] | 0;- i9 = i4;- if ((i6 - i4 | 0) >>> 0 < i2 >>> 0) {- i8 = FUNCTION_TABLE_iiii[HEAP32[i3 + 36 >> 2] & 7](i3, i1, i2) | 0;- break;- }- L10 : do if ((HEAP8[i3 + 75 >> 0] | 0) > -1) {- i4 = i2;- while (1) {- if (!i4) {- i10 = i2;- i11 = i1;- i12 = i9;- i13 = 0;- break L10;- }- i14 = i4 + -1 | 0;- if ((HEAP8[i1 + i14 >> 0] | 0) == 10) {- i15 = i4;- break;- } else i4 = i14;- }- if ((FUNCTION_TABLE_iiii[HEAP32[i3 + 36 >> 2] & 7](i3, i1, i15) | 0) >>> 0 < i15 >>> 0) {- i8 = i15;- break L5;- }- i10 = i2 - i15 | 0;- i11 = i1 + i15 | 0;- i12 = HEAP32[i5 >> 2] | 0;- i13 = i15;- } else {- i10 = i2;- i11 = i1;- i12 = i9;- i13 = 0;- } while (0);- _memcpy(i12 | 0, i11 | 0, i10 | 0) | 0;- HEAP32[i5 >> 2] = (HEAP32[i5 >> 2] | 0) + i10;- i8 = i13 + i10 | 0;- } while (0);- return i8 | 0;-}--function _fflush(i1) {- i1 = i1 | 0;- var i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0;- do if (i1) {- if ((HEAP32[i1 + 76 >> 2] | 0) <= -1) {- i2 = ___fflush_unlocked(i1) | 0;- break;- }- i3 = (___lockfile(i1) | 0) == 0;- i4 = ___fflush_unlocked(i1) | 0;- if (i3) i2 = i4; else {- ___unlockfile(i1);- i2 = i4;- }- } else {- if (!(HEAP32[14] | 0)) i5 = 0; else i5 = _fflush(HEAP32[14] | 0) | 0;- ___lock(36);- i4 = HEAP32[8] | 0;- if (!i4) i6 = i5; else {- i3 = i4;- i4 = i5;- while (1) {- if ((HEAP32[i3 + 76 >> 2] | 0) > -1) i7 = ___lockfile(i3) | 0; else i7 = 0;- if ((HEAP32[i3 + 20 >> 2] | 0) >>> 0 > (HEAP32[i3 + 28 >> 2] | 0) >>> 0) i8 = ___fflush_unlocked(i3) | 0 | i4; else i8 = i4;- if (i7) ___unlockfile(i3);- i3 = HEAP32[i3 + 56 >> 2] | 0;- if (!i3) {- i6 = i8;- break;- } else i4 = i8;- }- }- ___unlock(36);- i2 = i6;- } while (0);- return i2 | 0;-}--function _strlen(i1) {- i1 = i1 | 0;- var i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0;- i2 = i1;- L1 : do if (!(i2 & 3)) {- i3 = i1;- i4 = 4;- } else {- i5 = i1;- i6 = i2;- while (1) {- if (!(HEAP8[i5 >> 0] | 0)) {- i7 = i6;- break L1;- }- i8 = i5 + 1 | 0;- i6 = i8;- if (!(i6 & 3)) {- i3 = i8;- i4 = 4;- break;- } else i5 = i8;- }- } while (0);- if ((i4 | 0) == 4) {- i4 = i3;- while (1) {- i3 = HEAP32[i4 >> 2] | 0;- if (!((i3 & -2139062144 ^ -2139062144) & i3 + -16843009)) i4 = i4 + 4 | 0; else {- i9 = i3;- i10 = i4;- break;- }- }- if (!((i9 & 255) << 24 >> 24)) i11 = i10; else {- i9 = i10;- while (1) {- i10 = i9 + 1 | 0;- if (!(HEAP8[i10 >> 0] | 0)) {- i11 = i10;- break;- } else i9 = i10;- }- }- i7 = i11;- }- return i7 - i2 | 0;-}--function ___overflow(i1, i2) {- i1 = i1 | 0;- i2 = i2 | 0;- var i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0;- i3 = STACKTOP;- STACKTOP = STACKTOP + 16 | 0;- i4 = i3;- i5 = i2 & 255;- HEAP8[i4 >> 0] = i5;- i6 = i1 + 16 | 0;- i7 = HEAP32[i6 >> 2] | 0;- if (!i7) if (!(___towrite(i1) | 0)) {- i8 = HEAP32[i6 >> 2] | 0;- i9 = 4;- } else i10 = -1; else {- i8 = i7;- i9 = 4;- }- do if ((i9 | 0) == 4) {- i7 = i1 + 20 | 0;- i6 = HEAP32[i7 >> 2] | 0;- if (i6 >>> 0 < i8 >>> 0 ? (i11 = i2 & 255, (i11 | 0) != (HEAP8[i1 + 75 >> 0] | 0)) : 0) {- HEAP32[i7 >> 2] = i6 + 1;- HEAP8[i6 >> 0] = i5;- i10 = i11;- break;- }- if ((FUNCTION_TABLE_iiii[HEAP32[i1 + 36 >> 2] & 7](i1, i4, 1) | 0) == 1) i10 = HEAPU8[i4 >> 0] | 0; else i10 = -1;- } while (0);- STACKTOP = i3;- return i10 | 0;-}--function ___fflush_unlocked(i1) {- i1 = i1 | 0;- var i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0;- i2 = i1 + 20 | 0;- i3 = i1 + 28 | 0;- if ((HEAP32[i2 >> 2] | 0) >>> 0 > (HEAP32[i3 >> 2] | 0) >>> 0 ? (FUNCTION_TABLE_iiii[HEAP32[i1 + 36 >> 2] & 7](i1, 0, 0) | 0, (HEAP32[i2 >> 2] | 0) == 0) : 0) i4 = -1; else {- i5 = i1 + 4 | 0;- i6 = HEAP32[i5 >> 2] | 0;- i7 = i1 + 8 | 0;- i8 = HEAP32[i7 >> 2] | 0;- if (i6 >>> 0 < i8 >>> 0) FUNCTION_TABLE_iiii[HEAP32[i1 + 40 >> 2] & 7](i1, i6 - i8 | 0, 1) | 0;- HEAP32[i1 + 16 >> 2] = 0;- HEAP32[i3 >> 2] = 0;- HEAP32[i2 >> 2] = 0;- HEAP32[i7 >> 2] = 0;- HEAP32[i5 >> 2] = 0;- i4 = 0;- }- return i4 | 0;-}--function _memcpy(i1, i2, i3) {- i1 = i1 | 0;- i2 = i2 | 0;- i3 = i3 | 0;- var i4 = 0;- if ((i3 | 0) >= 4096) return _emscripten_memcpy_big(i1 | 0, i2 | 0, i3 | 0) | 0;- i4 = i1 | 0;- if ((i1 & 3) == (i2 & 3)) {- while (i1 & 3) {- if (!i3) return i4 | 0;- HEAP8[i1 >> 0] = HEAP8[i2 >> 0] | 0;- i1 = i1 + 1 | 0;- i2 = i2 + 1 | 0;- i3 = i3 - 1 | 0;- }- while ((i3 | 0) >= 4) {- HEAP32[i1 >> 2] = HEAP32[i2 >> 2];- i1 = i1 + 4 | 0;- i2 = i2 + 4 | 0;- i3 = i3 - 4 | 0;- }- }- while ((i3 | 0) > 0) {- HEAP8[i1 >> 0] = HEAP8[i2 >> 0] | 0;- i1 = i1 + 1 | 0;- i2 = i2 + 1 | 0;- i3 = i3 - 1 | 0;- }- return i4 | 0;-}--function runPostSets() {}-function _memset(i1, i2, i3) {- i1 = i1 | 0;- i2 = i2 | 0;- i3 = i3 | 0;- var i4 = 0, i5 = 0, i6 = 0, i7 = 0;- i4 = i1 + i3 | 0;- if ((i3 | 0) >= 20) {- i2 = i2 & 255;- i5 = i1 & 3;- i6 = i2 | i2 << 8 | i2 << 16 | i2 << 24;- i7 = i4 & ~3;- if (i5) {- i5 = i1 + 4 - i5 | 0;- while ((i1 | 0) < (i5 | 0)) {- HEAP8[i1 >> 0] = i2;- i1 = i1 + 1 | 0;- }- }- while ((i1 | 0) < (i7 | 0)) {- HEAP32[i1 >> 2] = i6;- i1 = i1 + 4 | 0;- }- }- while ((i1 | 0) < (i4 | 0)) {- HEAP8[i1 >> 0] = i2;- i1 = i1 + 1 | 0;- }- return i1 - i3 | 0;-}--function _puts(i1) {- i1 = i1 | 0;- var i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0;- i2 = HEAP32[13] | 0;- if ((HEAP32[i2 + 76 >> 2] | 0) > -1) i3 = ___lockfile(i2) | 0; else i3 = 0;- do if ((_fputs(i1, i2) | 0) < 0) i4 = 1; else {- if ((HEAP8[i2 + 75 >> 0] | 0) != 10 ? (i5 = i2 + 20 | 0, i6 = HEAP32[i5 >> 2] | 0, i6 >>> 0 < (HEAP32[i2 + 16 >> 2] | 0) >>> 0) : 0) {- HEAP32[i5 >> 2] = i6 + 1;- HEAP8[i6 >> 0] = 10;- i4 = 0;- break;- }- i4 = (___overflow(i2, 10) | 0) < 0;- } while (0);- if (i3) ___unlockfile(i2);- return i4 << 31 >> 31 | 0;-}--function ___stdio_seek(i1, i2, i3) {- i1 = i1 | 0;- i2 = i2 | 0;- i3 = i3 | 0;- var i4 = 0, i5 = 0, i6 = 0, i7 = 0;- i4 = STACKTOP;- STACKTOP = STACKTOP + 32 | 0;- i5 = i4;- i6 = i4 + 20 | 0;- HEAP32[i5 >> 2] = HEAP32[i1 + 60 >> 2];- HEAP32[i5 + 4 >> 2] = 0;- HEAP32[i5 + 8 >> 2] = i2;- HEAP32[i5 + 12 >> 2] = i6;- HEAP32[i5 + 16 >> 2] = i3;- if ((___syscall_ret(___syscall140(140, i5 | 0) | 0) | 0) < 0) {- HEAP32[i6 >> 2] = -1;- i7 = -1;- } else i7 = HEAP32[i6 >> 2] | 0;- STACKTOP = i4;- return i7 | 0;-}--function ___towrite(i1) {- i1 = i1 | 0;- var i2 = 0, i3 = 0, i4 = 0;- i2 = i1 + 74 | 0;- i3 = HEAP8[i2 >> 0] | 0;- HEAP8[i2 >> 0] = i3 + 255 | i3;- i3 = HEAP32[i1 >> 2] | 0;- if (!(i3 & 8)) {- HEAP32[i1 + 8 >> 2] = 0;- HEAP32[i1 + 4 >> 2] = 0;- i2 = HEAP32[i1 + 44 >> 2] | 0;- HEAP32[i1 + 28 >> 2] = i2;- HEAP32[i1 + 20 >> 2] = i2;- HEAP32[i1 + 16 >> 2] = i2 + (HEAP32[i1 + 48 >> 2] | 0);- i4 = 0;- } else {- HEAP32[i1 >> 2] = i3 | 32;- i4 = -1;- }- return i4 | 0;-}--function _fwrite(i1, i2, i3, i4) {- i1 = i1 | 0;- i2 = i2 | 0;- i3 = i3 | 0;- i4 = i4 | 0;- var i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0;- i5 = Math_imul(i3, i2) | 0;- if ((HEAP32[i4 + 76 >> 2] | 0) > -1) {- i6 = (___lockfile(i4) | 0) == 0;- i7 = ___fwritex(i1, i5, i4) | 0;- if (i6) i8 = i7; else {- ___unlockfile(i4);- i8 = i7;- }- } else i8 = ___fwritex(i1, i5, i4) | 0;- if ((i8 | 0) == (i5 | 0)) i9 = i3; else i9 = (i8 >>> 0) / (i2 >>> 0) | 0;- return i9 | 0;-}--function ___stdout_write(i1, i2, i3) {- i1 = i1 | 0;- i2 = i2 | 0;- i3 = i3 | 0;- var i4 = 0, i5 = 0;- i4 = STACKTOP;- STACKTOP = STACKTOP + 80 | 0;- i5 = i4;- HEAP32[i1 + 36 >> 2] = 5;- if ((HEAP32[i1 >> 2] & 64 | 0) == 0 ? (HEAP32[i5 >> 2] = HEAP32[i1 + 60 >> 2], HEAP32[i5 + 4 >> 2] = 21505, HEAP32[i5 + 8 >> 2] = i4 + 12, (___syscall54(54, i5 | 0) | 0) != 0) : 0) HEAP8[i1 + 75 >> 0] = -1;- i5 = ___stdio_write(i1, i2, i3) | 0;- STACKTOP = i4;- return i5 | 0;-}--function copyTempDouble(i1) {- i1 = i1 | 0;- HEAP8[tempDoublePtr >> 0] = HEAP8[i1 >> 0];- HEAP8[tempDoublePtr + 1 >> 0] = HEAP8[i1 + 1 >> 0];- HEAP8[tempDoublePtr + 2 >> 0] = HEAP8[i1 + 2 >> 0];- HEAP8[tempDoublePtr + 3 >> 0] = HEAP8[i1 + 3 >> 0];- HEAP8[tempDoublePtr + 4 >> 0] = HEAP8[i1 + 4 >> 0];- HEAP8[tempDoublePtr + 5 >> 0] = HEAP8[i1 + 5 >> 0];- HEAP8[tempDoublePtr + 6 >> 0] = HEAP8[i1 + 6 >> 0];- HEAP8[tempDoublePtr + 7 >> 0] = HEAP8[i1 + 7 >> 0];-}--function ___stdio_close(i1) {- i1 = i1 | 0;- var i2 = 0, i3 = 0;- i2 = STACKTOP;- STACKTOP = STACKTOP + 16 | 0;- i3 = i2;- HEAP32[i3 >> 2] = HEAP32[i1 + 60 >> 2];- i1 = ___syscall_ret(___syscall6(6, i3 | 0) | 0) | 0;- STACKTOP = i2;- return i1 | 0;-}--function copyTempFloat(i1) {- i1 = i1 | 0;- HEAP8[tempDoublePtr >> 0] = HEAP8[i1 >> 0];- HEAP8[tempDoublePtr + 1 >> 0] = HEAP8[i1 + 1 >> 0];- HEAP8[tempDoublePtr + 2 >> 0] = HEAP8[i1 + 2 >> 0];- HEAP8[tempDoublePtr + 3 >> 0] = HEAP8[i1 + 3 >> 0];-}--function ___syscall_ret(i1) {- i1 = i1 | 0;- var i2 = 0;- if (i1 >>> 0 > 4294963200) {- HEAP32[(___errno_location() | 0) >> 2] = 0 - i1;- i2 = -1;- } else i2 = i1;- return i2 | 0;-}--function dynCall_iiii(i1, i2, i3, i4) {- i1 = i1 | 0;- i2 = i2 | 0;- i3 = i3 | 0;- i4 = i4 | 0;- return FUNCTION_TABLE_iiii[i1 & 7](i2 | 0, i3 | 0, i4 | 0) | 0;-}-function stackAlloc(i1) {- i1 = i1 | 0;- var i2 = 0;- i2 = STACKTOP;- STACKTOP = STACKTOP + i1 | 0;- STACKTOP = STACKTOP + 15 & -16;- return i2 | 0;-}--function ___errno_location() {- var i1 = 0;- if (!(HEAP32[2] | 0)) i1 = 60; else i1 = HEAP32[(_pthread_self() | 0) + 60 >> 2] | 0;- return i1 | 0;-}--function setThrew(i1, i2) {- i1 = i1 | 0;- i2 = i2 | 0;- if (!__THREW__) {- __THREW__ = i1;- threwValue = i2;- }-}--function _fputs(i1, i2) {- i1 = i1 | 0;- i2 = i2 | 0;- return (_fwrite(i1, _strlen(i1) | 0, 1, i2) | 0) + -1 | 0;-}--function dynCall_ii(i1, i2) {- i1 = i1 | 0;- i2 = i2 | 0;- return FUNCTION_TABLE_ii[i1 & 1](i2 | 0) | 0;-}--function _cleanup_418(i1) {- i1 = i1 | 0;- if (!(HEAP32[i1 + 68 >> 2] | 0)) ___unlockfile(i1);- return;-}--function establishStackSpace(i1, i2) {- i1 = i1 | 0;- i2 = i2 | 0;- STACKTOP = i1;- STACK_MAX = i2;-}--function dynCall_vi(i1, i2) {- i1 = i1 | 0;- i2 = i2 | 0;- FUNCTION_TABLE_vi[i1 & 7](i2 | 0);-}--function b1(i1, i2, i3) {- i1 = i1 | 0;- i2 = i2 | 0;- i3 = i3 | 0;- abort(1);- return 0;-}--function stackRestore(i1) {- i1 = i1 | 0;- STACKTOP = i1;-}--function setTempRet0(i1) {- i1 = i1 | 0;- tempRet0 = i1;-}--function b0(i1) {- i1 = i1 | 0;- abort(0);- return 0;-}--function ___unlockfile(i1) {- i1 = i1 | 0;- return;-}--function ___lockfile(i1) {- i1 = i1 | 0;- return 0;-}--function getTempRet0() {- return tempRet0 | 0;-}--function _main() {- _puts(672) | 0;- return 0;-}--function stackSave() {- return STACKTOP | 0;-}--function b2(i1) {- i1 = i1 | 0;- abort(2);-}--// EMSCRIPTEN_END_FUNCS-var FUNCTION_TABLE_ii = [b0,___stdio_close];-var FUNCTION_TABLE_iiii = [b1,b1,___stdout_write,___stdio_seek,b1,___stdio_write,b1,b1];-var FUNCTION_TABLE_vi = [b2,b2,b2,b2,_cleanup_418,b2,b2,b2];-- return { _free: _free, _main: _main, _memset: _memset, _malloc: _malloc, _memcpy: _memcpy, _fflush: _fflush, ___errno_location: ___errno_location, runPostSets: runPostSets, stackAlloc: stackAlloc, stackSave: stackSave, stackRestore: stackRestore, establishStackSpace: establishStackSpace, setThrew: setThrew, setTempRet0: setTempRet0, getTempRet0: getTempRet0, dynCall_ii: dynCall_ii, dynCall_iiii: dynCall_iiii, dynCall_vi: dynCall_vi };-})-;
− binaryen/test/emcc_hello_world.asm.js
@@ -1,7101 +0,0 @@-Module["asm"] = (function(global, env, buffer) {- 'almost asm';- - - var HEAP8 = new global.Int8Array(buffer);- var HEAP16 = new global.Int16Array(buffer);- var HEAP32 = new global.Int32Array(buffer);- var HEAPU8 = new global.Uint8Array(buffer);- var HEAPU16 = new global.Uint16Array(buffer);- var HEAPU32 = new global.Uint32Array(buffer);- var HEAPF32 = new global.Float32Array(buffer);- var HEAPF64 = new global.Float64Array(buffer);--- var STACKTOP=env.STACKTOP|0;- var STACK_MAX=env.STACK_MAX|0;- var tempDoublePtr=env.tempDoublePtr|0;- var ABORT=env.ABORT|0;- var cttz_i8=env.cttz_i8|0;-- var __THREW__ = 0;- var threwValue = 0;- var setjmpId = 0;- var undef = 0;- var nan = global.NaN, inf = global.Infinity;- var tempInt = 0, tempBigInt = 0, tempBigIntP = 0, tempBigIntS = 0, tempBigIntR = 0.0, tempBigIntI = 0, tempBigIntD = 0, tempValue = 0, tempDouble = 0.0;-- var tempRet0 = 0;- var tempRet1 = 0;- var tempRet2 = 0;- var tempRet3 = 0;- var tempRet4 = 0;- var tempRet5 = 0;- var tempRet6 = 0;- var tempRet7 = 0;- var tempRet8 = 0;- var tempRet9 = 0;- var Math_floor=global.Math.floor;- var Math_abs=global.Math.abs;- var Math_sqrt=global.Math.sqrt;- var Math_pow=global.Math.pow;- var Math_cos=global.Math.cos;- var Math_sin=global.Math.sin;- var Math_tan=global.Math.tan;- var Math_acos=global.Math.acos;- var Math_asin=global.Math.asin;- var Math_atan=global.Math.atan;- var Math_atan2=global.Math.atan2;- var Math_exp=global.Math.exp;- var Math_log=global.Math.log;- var Math_ceil=global.Math.ceil;- var Math_imul=global.Math.imul;- var Math_min=global.Math.min;- var Math_clz32=global.Math.clz32;- var abort=env.abort;- var assert=env.assert;- var nullFunc_ii=env.nullFunc_ii;- var nullFunc_iiii=env.nullFunc_iiii;- var nullFunc_vi=env.nullFunc_vi;- var invoke_ii=env.invoke_ii;- var invoke_iiii=env.invoke_iiii;- var invoke_vi=env.invoke_vi;- var _pthread_cleanup_pop=env._pthread_cleanup_pop;- var ___lock=env.___lock;- var _emscripten_set_main_loop=env._emscripten_set_main_loop;- var _pthread_self=env._pthread_self;- var _abort=env._abort;- var _emscripten_set_main_loop_timing=env._emscripten_set_main_loop_timing;- var ___syscall6=env.___syscall6;- var _sbrk=env._sbrk;- var _time=env._time;- var ___setErrNo=env.___setErrNo;- var _emscripten_memcpy_big=env._emscripten_memcpy_big;- var ___syscall54=env.___syscall54;- var ___unlock=env.___unlock;- var ___syscall140=env.___syscall140;- var _pthread_cleanup_push=env._pthread_cleanup_push;- var _sysconf=env._sysconf;- var ___syscall146=env.___syscall146;- var _llvm_cttz_i32=env._llvm_cttz_i32;- var tempFloat = 0.0;--// EMSCRIPTEN_START_FUNCS-function stackAlloc(size) {- size = size|0;- var ret = 0;- ret = STACKTOP;- STACKTOP = (STACKTOP + size)|0;- STACKTOP = (STACKTOP + 15)&-16;-if ((STACKTOP|0) >= (STACK_MAX|0)) abort();-- return ret|0;-}-function stackSave() {- return STACKTOP|0;-}-function stackRestore(top) {- top = top|0;- STACKTOP = top;-}-function establishStackSpace(stackBase, stackMax) {- stackBase = stackBase|0;- stackMax = stackMax|0;- STACKTOP = stackBase;- STACK_MAX = stackMax;-}--function setThrew(threw, value) {- threw = threw|0;- value = value|0;- if ((__THREW__|0) == 0) {- __THREW__ = threw;- threwValue = value;- }-}-function copyTempFloat(ptr) {- ptr = ptr|0;- HEAP8[tempDoublePtr>>0] = HEAP8[ptr>>0];- HEAP8[tempDoublePtr+1>>0] = HEAP8[ptr+1>>0];- HEAP8[tempDoublePtr+2>>0] = HEAP8[ptr+2>>0];- HEAP8[tempDoublePtr+3>>0] = HEAP8[ptr+3>>0];-}-function copyTempDouble(ptr) {- ptr = ptr|0;- HEAP8[tempDoublePtr>>0] = HEAP8[ptr>>0];- HEAP8[tempDoublePtr+1>>0] = HEAP8[ptr+1>>0];- HEAP8[tempDoublePtr+2>>0] = HEAP8[ptr+2>>0];- HEAP8[tempDoublePtr+3>>0] = HEAP8[ptr+3>>0];- HEAP8[tempDoublePtr+4>>0] = HEAP8[ptr+4>>0];- HEAP8[tempDoublePtr+5>>0] = HEAP8[ptr+5>>0];- HEAP8[tempDoublePtr+6>>0] = HEAP8[ptr+6>>0];- HEAP8[tempDoublePtr+7>>0] = HEAP8[ptr+7>>0];-}--function setTempRet0(value) {- value = value|0;- tempRet0 = value;-}-function getTempRet0() {- return tempRet0|0;-}--function _main() {- var $retval = 0, $vararg_buffer = 0, label = 0, sp = 0;- sp = STACKTOP;- STACKTOP = STACKTOP + 16|0; if ((STACKTOP|0) >= (STACK_MAX|0)) abort();- $vararg_buffer = sp;- $retval = 0;- (_printf(672,$vararg_buffer)|0);- STACKTOP = sp;return 0;-}-function _frexp($x,$e) {- $x = +$x;- $e = $e|0;- var $0 = 0, $1 = 0, $2 = 0, $3 = 0, $4 = 0, $5 = 0, $6 = 0, $7 = 0.0, $call = 0.0, $conv = 0, $mul = 0.0, $retval$0 = 0.0, $storemerge = 0, $sub = 0, $sub8 = 0, $tobool1 = 0, $x$addr$0 = 0.0, label = 0, sp = 0;- sp = STACKTOP;- HEAPF64[tempDoublePtr>>3] = $x;$0 = HEAP32[tempDoublePtr>>2]|0;- $1 = HEAP32[tempDoublePtr+4>>2]|0;- $2 = (_bitshift64Lshr(($0|0),($1|0),52)|0);- $3 = tempRet0;- $conv = $2 & 2047;- switch ($conv|0) {- case 0: {- $tobool1 = $x != 0.0;- if ($tobool1) {- $mul = $x * 1.8446744073709552E+19;- $call = (+_frexp($mul,$e));- $4 = HEAP32[$e>>2]|0;- $sub = (($4) + -64)|0;- $storemerge = $sub;$x$addr$0 = $call;- } else {- $storemerge = 0;$x$addr$0 = $x;- }- HEAP32[$e>>2] = $storemerge;- $retval$0 = $x$addr$0;- break;- }- case 2047: {- $retval$0 = $x;- break;- }- default: {- $sub8 = (($conv) + -1022)|0;- HEAP32[$e>>2] = $sub8;- $5 = $1 & -2146435073;- $6 = $5 | 1071644672;- HEAP32[tempDoublePtr>>2] = $0;HEAP32[tempDoublePtr+4>>2] = $6;$7 = +HEAPF64[tempDoublePtr>>3];- $retval$0 = $7;- }- }- return (+$retval$0);-}-function _frexpl($x,$e) {- $x = +$x;- $e = $e|0;- var $call = 0.0, label = 0, sp = 0;- sp = STACKTOP;- $call = (+_frexp($x,$e));- return (+$call);-}-function _strerror($e) {- $e = $e|0;- var $0 = 0, $1 = 0, $arrayidx = 0, $cmp = 0, $conv = 0, $dec = 0, $i$012 = 0, $i$012$lcssa = 0, $i$111 = 0, $inc = 0, $incdec$ptr = 0, $incdec$ptr$lcssa = 0, $s$0$lcssa = 0, $s$010 = 0, $s$1 = 0, $tobool = 0, $tobool5 = 0, $tobool5$9 = 0, $tobool8 = 0, label = 0;- var sp = 0;- sp = STACKTOP;- $i$012 = 0;- while(1) {- $arrayidx = (687 + ($i$012)|0);- $0 = HEAP8[$arrayidx>>0]|0;- $conv = $0&255;- $cmp = ($conv|0)==($e|0);- if ($cmp) {- $i$012$lcssa = $i$012;- label = 2;- break;- }- $inc = (($i$012) + 1)|0;- $tobool = ($inc|0)==(87);- if ($tobool) {- $i$111 = 87;$s$010 = 775;- label = 5;- break;- } else {- $i$012 = $inc;- }- }- if ((label|0) == 2) {- $tobool5$9 = ($i$012$lcssa|0)==(0);- if ($tobool5$9) {- $s$0$lcssa = 775;- } else {- $i$111 = $i$012$lcssa;$s$010 = 775;- label = 5;- }- }- if ((label|0) == 5) {- while(1) {- label = 0;- $s$1 = $s$010;- while(1) {- $1 = HEAP8[$s$1>>0]|0;- $tobool8 = ($1<<24>>24)==(0);- $incdec$ptr = ((($s$1)) + 1|0);- if ($tobool8) {- $incdec$ptr$lcssa = $incdec$ptr;- break;- } else {- $s$1 = $incdec$ptr;- }- }- $dec = (($i$111) + -1)|0;- $tobool5 = ($dec|0)==(0);- if ($tobool5) {- $s$0$lcssa = $incdec$ptr$lcssa;- break;- } else {- $i$111 = $dec;$s$010 = $incdec$ptr$lcssa;- label = 5;- }- }- }- return ($s$0$lcssa|0);-}-function ___errno_location() {- var $0 = 0, $1 = 0, $call$i = 0, $errno_ptr = 0, $retval$0 = 0, $tobool = 0, label = 0, sp = 0;- sp = STACKTOP;- $0 = HEAP32[4]|0;- $tobool = ($0|0)==(0|0);- if ($tobool) {- $retval$0 = 60;- } else {- $call$i = (_pthread_self()|0);- $errno_ptr = ((($call$i)) + 60|0);- $1 = HEAP32[$errno_ptr>>2]|0;- $retval$0 = $1;- }- return ($retval$0|0);-}-function ___stdio_close($f) {- $f = $f|0;- var $0 = 0, $call = 0, $call1 = 0, $fd = 0, $vararg_buffer = 0, label = 0, sp = 0;- sp = STACKTOP;- STACKTOP = STACKTOP + 16|0; if ((STACKTOP|0) >= (STACK_MAX|0)) abort();- $vararg_buffer = sp;- $fd = ((($f)) + 60|0);- $0 = HEAP32[$fd>>2]|0;- HEAP32[$vararg_buffer>>2] = $0;- $call = (___syscall6(6,($vararg_buffer|0))|0);- $call1 = (___syscall_ret($call)|0);- STACKTOP = sp;return ($call1|0);-}-function ___stdout_write($f,$buf,$len) {- $f = $f|0;- $buf = $buf|0;- $len = $len|0;- var $0 = 0, $1 = 0, $and = 0, $call = 0, $call3 = 0, $fd = 0, $lbf = 0, $tio = 0, $tobool = 0, $tobool2 = 0, $vararg_buffer = 0, $vararg_ptr1 = 0, $vararg_ptr2 = 0, $write = 0, label = 0, sp = 0;- sp = STACKTOP;- STACKTOP = STACKTOP + 80|0; if ((STACKTOP|0) >= (STACK_MAX|0)) abort();- $vararg_buffer = sp;- $tio = sp + 12|0;- $write = ((($f)) + 36|0);- HEAP32[$write>>2] = 4;- $0 = HEAP32[$f>>2]|0;- $and = $0 & 64;- $tobool = ($and|0)==(0);- if ($tobool) {- $fd = ((($f)) + 60|0);- $1 = HEAP32[$fd>>2]|0;- HEAP32[$vararg_buffer>>2] = $1;- $vararg_ptr1 = ((($vararg_buffer)) + 4|0);- HEAP32[$vararg_ptr1>>2] = 21505;- $vararg_ptr2 = ((($vararg_buffer)) + 8|0);- HEAP32[$vararg_ptr2>>2] = $tio;- $call = (___syscall54(54,($vararg_buffer|0))|0);- $tobool2 = ($call|0)==(0);- if (!($tobool2)) {- $lbf = ((($f)) + 75|0);- HEAP8[$lbf>>0] = -1;- }- }- $call3 = (___stdio_write($f,$buf,$len)|0);- STACKTOP = sp;return ($call3|0);-}-function ___stdio_seek($f,$off,$whence) {- $f = $f|0;- $off = $off|0;- $whence = $whence|0;- var $$pre = 0, $0 = 0, $1 = 0, $call = 0, $call1 = 0, $cmp = 0, $fd = 0, $ret = 0, $vararg_buffer = 0, $vararg_ptr1 = 0, $vararg_ptr2 = 0, $vararg_ptr3 = 0, $vararg_ptr4 = 0, label = 0, sp = 0;- sp = STACKTOP;- STACKTOP = STACKTOP + 32|0; if ((STACKTOP|0) >= (STACK_MAX|0)) abort();- $vararg_buffer = sp;- $ret = sp + 20|0;- $fd = ((($f)) + 60|0);- $0 = HEAP32[$fd>>2]|0;- HEAP32[$vararg_buffer>>2] = $0;- $vararg_ptr1 = ((($vararg_buffer)) + 4|0);- HEAP32[$vararg_ptr1>>2] = 0;- $vararg_ptr2 = ((($vararg_buffer)) + 8|0);- HEAP32[$vararg_ptr2>>2] = $off;- $vararg_ptr3 = ((($vararg_buffer)) + 12|0);- HEAP32[$vararg_ptr3>>2] = $ret;- $vararg_ptr4 = ((($vararg_buffer)) + 16|0);- HEAP32[$vararg_ptr4>>2] = $whence;- $call = (___syscall140(140,($vararg_buffer|0))|0);- $call1 = (___syscall_ret($call)|0);- $cmp = ($call1|0)<(0);- if ($cmp) {- HEAP32[$ret>>2] = -1;- $1 = -1;- } else {- $$pre = HEAP32[$ret>>2]|0;- $1 = $$pre;- }- STACKTOP = sp;return ($1|0);-}-function _fflush($f) {- $f = $f|0;- var $0 = 0, $1 = 0, $2 = 0, $3 = 0, $4 = 0, $5 = 0, $call = 0, $call1 = 0, $call1$18 = 0, $call16 = 0, $call22 = 0, $call7 = 0, $cmp = 0, $cmp14 = 0, $cmp20 = 0, $cond10 = 0, $cond19 = 0, $f$addr$0 = 0, $f$addr$0$19 = 0, $f$addr$022 = 0;- var $lock = 0, $lock13 = 0, $next = 0, $or = 0, $phitmp = 0, $r$0$lcssa = 0, $r$021 = 0, $r$1 = 0, $retval$0 = 0, $tobool = 0, $tobool11 = 0, $tobool11$20 = 0, $tobool24 = 0, $tobool5 = 0, $wbase = 0, $wpos = 0, label = 0, sp = 0;- sp = STACKTOP;- $tobool = ($f|0)==(0|0);- do {- if ($tobool) {- $1 = HEAP32[3]|0;- $tobool5 = ($1|0)==(0|0);- if ($tobool5) {- $cond10 = 0;- } else {- $2 = HEAP32[3]|0;- $call7 = (_fflush($2)|0);- $cond10 = $call7;- }- ___lock(((44)|0));- $f$addr$0$19 = HEAP32[(40)>>2]|0;- $tobool11$20 = ($f$addr$0$19|0)==(0|0);- if ($tobool11$20) {- $r$0$lcssa = $cond10;- } else {- $f$addr$022 = $f$addr$0$19;$r$021 = $cond10;- while(1) {- $lock13 = ((($f$addr$022)) + 76|0);- $3 = HEAP32[$lock13>>2]|0;- $cmp14 = ($3|0)>(-1);- if ($cmp14) {- $call16 = (___lockfile($f$addr$022)|0);- $cond19 = $call16;- } else {- $cond19 = 0;- }- $wpos = ((($f$addr$022)) + 20|0);- $4 = HEAP32[$wpos>>2]|0;- $wbase = ((($f$addr$022)) + 28|0);- $5 = HEAP32[$wbase>>2]|0;- $cmp20 = ($4>>>0)>($5>>>0);- if ($cmp20) {- $call22 = (___fflush_unlocked($f$addr$022)|0);- $or = $call22 | $r$021;- $r$1 = $or;- } else {- $r$1 = $r$021;- }- $tobool24 = ($cond19|0)==(0);- if (!($tobool24)) {- ___unlockfile($f$addr$022);- }- $next = ((($f$addr$022)) + 56|0);- $f$addr$0 = HEAP32[$next>>2]|0;- $tobool11 = ($f$addr$0|0)==(0|0);- if ($tobool11) {- $r$0$lcssa = $r$1;- break;- } else {- $f$addr$022 = $f$addr$0;$r$021 = $r$1;- }- }- }- ___unlock(((44)|0));- $retval$0 = $r$0$lcssa;- } else {- $lock = ((($f)) + 76|0);- $0 = HEAP32[$lock>>2]|0;- $cmp = ($0|0)>(-1);- if (!($cmp)) {- $call1$18 = (___fflush_unlocked($f)|0);- $retval$0 = $call1$18;- break;- }- $call = (___lockfile($f)|0);- $phitmp = ($call|0)==(0);- $call1 = (___fflush_unlocked($f)|0);- if ($phitmp) {- $retval$0 = $call1;- } else {- ___unlockfile($f);- $retval$0 = $call1;- }- }- } while(0);- return ($retval$0|0);-}-function _printf($fmt,$varargs) {- $fmt = $fmt|0;- $varargs = $varargs|0;- var $0 = 0, $ap = 0, $call = 0, label = 0, sp = 0;- sp = STACKTOP;- STACKTOP = STACKTOP + 16|0; if ((STACKTOP|0) >= (STACK_MAX|0)) abort();- $ap = sp;- HEAP32[$ap>>2] = $varargs;- $0 = HEAP32[2]|0;- $call = (_vfprintf($0,$fmt,$ap)|0);- STACKTOP = sp;return ($call|0);-}-function ___lockfile($f) {- $f = $f|0;- var label = 0, sp = 0;- sp = STACKTOP;- return 0;-}-function ___unlockfile($f) {- $f = $f|0;- var label = 0, sp = 0;- sp = STACKTOP;- return;-}-function ___stdio_write($f,$buf,$len) {- $f = $f|0;- $buf = $buf|0;- $len = $len|0;- var $$pre = 0, $0 = 0, $1 = 0, $10 = 0, $11 = 0, $12 = 0, $13 = 0, $14 = 0, $2 = 0, $3 = 0, $4 = 0, $5 = 0, $6 = 0, $7 = 0, $8 = 0, $9 = 0, $add = 0, $add$ptr = 0, $add$ptr41 = 0, $add$ptr46 = 0;- var $buf31 = 0, $buf_size = 0, $call = 0, $call10 = 0, $call7 = 0, $call9 = 0, $cmp = 0, $cmp17 = 0, $cmp22 = 0, $cmp29 = 0, $cmp38 = 0, $cnt$0 = 0, $cnt$1 = 0, $dec = 0, $fd8 = 0, $incdec$ptr = 0, $iov$0 = 0, $iov$0$lcssa57 = 0, $iov$1 = 0, $iov_base2 = 0;- var $iov_len = 0, $iov_len24 = 0, $iov_len28 = 0, $iov_len3 = 0, $iov_len50 = 0, $iov_len50$phi$trans$insert = 0, $iovcnt$0 = 0, $iovcnt$0$lcssa58 = 0, $iovcnt$1 = 0, $iovs = 0, $or = 0, $rem$0 = 0, $retval$0 = 0, $sub = 0, $sub$ptr$sub = 0, $sub26 = 0, $sub36 = 0, $sub51 = 0, $tobool = 0, $vararg_buffer = 0;- var $vararg_buffer3 = 0, $vararg_ptr1 = 0, $vararg_ptr2 = 0, $vararg_ptr6 = 0, $vararg_ptr7 = 0, $wbase = 0, $wend = 0, $wend19 = 0, $wpos = 0, label = 0, sp = 0;- sp = STACKTOP;- STACKTOP = STACKTOP + 48|0; if ((STACKTOP|0) >= (STACK_MAX|0)) abort();- $vararg_buffer3 = sp + 16|0;- $vararg_buffer = sp;- $iovs = sp + 32|0;- $wbase = ((($f)) + 28|0);- $0 = HEAP32[$wbase>>2]|0;- HEAP32[$iovs>>2] = $0;- $iov_len = ((($iovs)) + 4|0);- $wpos = ((($f)) + 20|0);- $1 = HEAP32[$wpos>>2]|0;- $sub$ptr$sub = (($1) - ($0))|0;- HEAP32[$iov_len>>2] = $sub$ptr$sub;- $iov_base2 = ((($iovs)) + 8|0);- HEAP32[$iov_base2>>2] = $buf;- $iov_len3 = ((($iovs)) + 12|0);- HEAP32[$iov_len3>>2] = $len;- $add = (($sub$ptr$sub) + ($len))|0;- $fd8 = ((($f)) + 60|0);- $buf31 = ((($f)) + 44|0);- $iov$0 = $iovs;$iovcnt$0 = 2;$rem$0 = $add;- while(1) {- $2 = HEAP32[4]|0;- $tobool = ($2|0)==(0|0);- if ($tobool) {- $4 = HEAP32[$fd8>>2]|0;- HEAP32[$vararg_buffer3>>2] = $4;- $vararg_ptr6 = ((($vararg_buffer3)) + 4|0);- HEAP32[$vararg_ptr6>>2] = $iov$0;- $vararg_ptr7 = ((($vararg_buffer3)) + 8|0);- HEAP32[$vararg_ptr7>>2] = $iovcnt$0;- $call9 = (___syscall146(146,($vararg_buffer3|0))|0);- $call10 = (___syscall_ret($call9)|0);- $cnt$0 = $call10;- } else {- _pthread_cleanup_push((5|0),($f|0));- $3 = HEAP32[$fd8>>2]|0;- HEAP32[$vararg_buffer>>2] = $3;- $vararg_ptr1 = ((($vararg_buffer)) + 4|0);- HEAP32[$vararg_ptr1>>2] = $iov$0;- $vararg_ptr2 = ((($vararg_buffer)) + 8|0);- HEAP32[$vararg_ptr2>>2] = $iovcnt$0;- $call = (___syscall146(146,($vararg_buffer|0))|0);- $call7 = (___syscall_ret($call)|0);- _pthread_cleanup_pop(0);- $cnt$0 = $call7;- }- $cmp = ($rem$0|0)==($cnt$0|0);- if ($cmp) {- label = 6;- break;- }- $cmp17 = ($cnt$0|0)<(0);- if ($cmp17) {- $iov$0$lcssa57 = $iov$0;$iovcnt$0$lcssa58 = $iovcnt$0;- label = 8;- break;- }- $sub26 = (($rem$0) - ($cnt$0))|0;- $iov_len28 = ((($iov$0)) + 4|0);- $10 = HEAP32[$iov_len28>>2]|0;- $cmp29 = ($cnt$0>>>0)>($10>>>0);- if ($cmp29) {- $11 = HEAP32[$buf31>>2]|0;- HEAP32[$wbase>>2] = $11;- HEAP32[$wpos>>2] = $11;- $sub36 = (($cnt$0) - ($10))|0;- $incdec$ptr = ((($iov$0)) + 8|0);- $dec = (($iovcnt$0) + -1)|0;- $iov_len50$phi$trans$insert = ((($iov$0)) + 12|0);- $$pre = HEAP32[$iov_len50$phi$trans$insert>>2]|0;- $14 = $$pre;$cnt$1 = $sub36;$iov$1 = $incdec$ptr;$iovcnt$1 = $dec;- } else {- $cmp38 = ($iovcnt$0|0)==(2);- if ($cmp38) {- $12 = HEAP32[$wbase>>2]|0;- $add$ptr41 = (($12) + ($cnt$0)|0);- HEAP32[$wbase>>2] = $add$ptr41;- $14 = $10;$cnt$1 = $cnt$0;$iov$1 = $iov$0;$iovcnt$1 = 2;- } else {- $14 = $10;$cnt$1 = $cnt$0;$iov$1 = $iov$0;$iovcnt$1 = $iovcnt$0;- }- }- $13 = HEAP32[$iov$1>>2]|0;- $add$ptr46 = (($13) + ($cnt$1)|0);- HEAP32[$iov$1>>2] = $add$ptr46;- $iov_len50 = ((($iov$1)) + 4|0);- $sub51 = (($14) - ($cnt$1))|0;- HEAP32[$iov_len50>>2] = $sub51;- $iov$0 = $iov$1;$iovcnt$0 = $iovcnt$1;$rem$0 = $sub26;- }- if ((label|0) == 6) {- $5 = HEAP32[$buf31>>2]|0;- $buf_size = ((($f)) + 48|0);- $6 = HEAP32[$buf_size>>2]|0;- $add$ptr = (($5) + ($6)|0);- $wend = ((($f)) + 16|0);- HEAP32[$wend>>2] = $add$ptr;- $7 = $5;- HEAP32[$wbase>>2] = $7;- HEAP32[$wpos>>2] = $7;- $retval$0 = $len;- }- else if ((label|0) == 8) {- $wend19 = ((($f)) + 16|0);- HEAP32[$wend19>>2] = 0;- HEAP32[$wbase>>2] = 0;- HEAP32[$wpos>>2] = 0;- $8 = HEAP32[$f>>2]|0;- $or = $8 | 32;- HEAP32[$f>>2] = $or;- $cmp22 = ($iovcnt$0$lcssa58|0)==(2);- if ($cmp22) {- $retval$0 = 0;- } else {- $iov_len24 = ((($iov$0$lcssa57)) + 4|0);- $9 = HEAP32[$iov_len24>>2]|0;- $sub = (($len) - ($9))|0;- $retval$0 = $sub;- }- }- STACKTOP = sp;return ($retval$0|0);-}-function _vfprintf($f,$fmt,$ap) {- $f = $f|0;- $fmt = $fmt|0;- $ap = $ap|0;- var $$call21 = 0, $0 = 0, $1 = 0, $2 = 0, $3 = 0, $4 = 0, $5 = 0, $6 = 0, $7 = 0, $add$ptr = 0, $and = 0, $and11 = 0, $and36 = 0, $ap2 = 0, $buf = 0, $buf_size = 0, $call = 0, $call21 = 0, $call21$30 = 0, $call6 = 0;- var $cmp = 0, $cmp5 = 0, $cmp7 = 0, $cond = 0, $internal_buf = 0, $lock = 0, $mode = 0, $nl_arg = 0, $nl_type = 0, $or = 0, $ret$1 = 0, $ret$1$ = 0, $retval$0 = 0, $tobool = 0, $tobool22 = 0, $tobool26 = 0, $tobool37 = 0, $tobool41 = 0, $vacopy_currentptr = 0, $wbase = 0;- var $wend = 0, $wpos = 0, $write = 0, dest = 0, label = 0, sp = 0, stop = 0;- sp = STACKTOP;- STACKTOP = STACKTOP + 224|0; if ((STACKTOP|0) >= (STACK_MAX|0)) abort();- $ap2 = sp + 120|0;- $nl_type = sp + 80|0;- $nl_arg = sp;- $internal_buf = sp + 136|0;- dest=$nl_type; stop=dest+40|0; do { HEAP32[dest>>2]=0|0; dest=dest+4|0; } while ((dest|0) < (stop|0));- $vacopy_currentptr = HEAP32[$ap>>2]|0;- HEAP32[$ap2>>2] = $vacopy_currentptr;- $call = (_printf_core(0,$fmt,$ap2,$nl_arg,$nl_type)|0);- $cmp = ($call|0)<(0);- if ($cmp) {- $retval$0 = -1;- } else {- $lock = ((($f)) + 76|0);- $0 = HEAP32[$lock>>2]|0;- $cmp5 = ($0|0)>(-1);- if ($cmp5) {- $call6 = (___lockfile($f)|0);- $cond = $call6;- } else {- $cond = 0;- }- $1 = HEAP32[$f>>2]|0;- $and = $1 & 32;- $mode = ((($f)) + 74|0);- $2 = HEAP8[$mode>>0]|0;- $cmp7 = ($2<<24>>24)<(1);- if ($cmp7) {- $and11 = $1 & -33;- HEAP32[$f>>2] = $and11;- }- $buf_size = ((($f)) + 48|0);- $3 = HEAP32[$buf_size>>2]|0;- $tobool = ($3|0)==(0);- if ($tobool) {- $buf = ((($f)) + 44|0);- $4 = HEAP32[$buf>>2]|0;- HEAP32[$buf>>2] = $internal_buf;- $wbase = ((($f)) + 28|0);- HEAP32[$wbase>>2] = $internal_buf;- $wpos = ((($f)) + 20|0);- HEAP32[$wpos>>2] = $internal_buf;- HEAP32[$buf_size>>2] = 80;- $add$ptr = ((($internal_buf)) + 80|0);- $wend = ((($f)) + 16|0);- HEAP32[$wend>>2] = $add$ptr;- $call21 = (_printf_core($f,$fmt,$ap2,$nl_arg,$nl_type)|0);- $tobool22 = ($4|0)==(0|0);- if ($tobool22) {- $ret$1 = $call21;- } else {- $write = ((($f)) + 36|0);- $5 = HEAP32[$write>>2]|0;- (FUNCTION_TABLE_iiii[$5 & 7]($f,0,0)|0);- $6 = HEAP32[$wpos>>2]|0;- $tobool26 = ($6|0)==(0|0);- $$call21 = $tobool26 ? -1 : $call21;- HEAP32[$buf>>2] = $4;- HEAP32[$buf_size>>2] = 0;- HEAP32[$wend>>2] = 0;- HEAP32[$wbase>>2] = 0;- HEAP32[$wpos>>2] = 0;- $ret$1 = $$call21;- }- } else {- $call21$30 = (_printf_core($f,$fmt,$ap2,$nl_arg,$nl_type)|0);- $ret$1 = $call21$30;- }- $7 = HEAP32[$f>>2]|0;- $and36 = $7 & 32;- $tobool37 = ($and36|0)==(0);- $ret$1$ = $tobool37 ? $ret$1 : -1;- $or = $7 | $and;- HEAP32[$f>>2] = $or;- $tobool41 = ($cond|0)==(0);- if (!($tobool41)) {- ___unlockfile($f);- }- $retval$0 = $ret$1$;- }- STACKTOP = sp;return ($retval$0|0);-}-function ___fwritex($s,$l,$f) {- $s = $s|0;- $l = $l|0;- $f = $f|0;- var $$pre = 0, $$pre31 = 0, $0 = 0, $1 = 0, $10 = 0, $2 = 0, $3 = 0, $4 = 0, $5 = 0, $6 = 0, $7 = 0, $8 = 0, $9 = 0, $add = 0, $add$ptr = 0, $add$ptr26 = 0, $arrayidx = 0, $call = 0, $call16 = 0, $call4 = 0;- var $cmp = 0, $cmp11 = 0, $cmp17 = 0, $cmp6 = 0, $i$0 = 0, $i$0$lcssa36 = 0, $i$1 = 0, $l$addr$0 = 0, $lbf = 0, $retval$0 = 0, $s$addr$0 = 0, $sub = 0, $sub$ptr$sub = 0, $sub21 = 0, $tobool = 0, $tobool1 = 0, $tobool9 = 0, $wend = 0, $wpos = 0, $write = 0;- var $write15 = 0, label = 0, sp = 0;- sp = STACKTOP;- $wend = ((($f)) + 16|0);- $0 = HEAP32[$wend>>2]|0;- $tobool = ($0|0)==(0|0);- if ($tobool) {- $call = (___towrite($f)|0);- $tobool1 = ($call|0)==(0);- if ($tobool1) {- $$pre = HEAP32[$wend>>2]|0;- $3 = $$pre;- label = 5;- } else {- $retval$0 = 0;- }- } else {- $1 = $0;- $3 = $1;- label = 5;- }- L5: do {- if ((label|0) == 5) {- $wpos = ((($f)) + 20|0);- $2 = HEAP32[$wpos>>2]|0;- $sub$ptr$sub = (($3) - ($2))|0;- $cmp = ($sub$ptr$sub>>>0)<($l>>>0);- $4 = $2;- if ($cmp) {- $write = ((($f)) + 36|0);- $5 = HEAP32[$write>>2]|0;- $call4 = (FUNCTION_TABLE_iiii[$5 & 7]($f,$s,$l)|0);- $retval$0 = $call4;- break;- }- $lbf = ((($f)) + 75|0);- $6 = HEAP8[$lbf>>0]|0;- $cmp6 = ($6<<24>>24)>(-1);- L10: do {- if ($cmp6) {- $i$0 = $l;- while(1) {- $tobool9 = ($i$0|0)==(0);- if ($tobool9) {- $9 = $4;$i$1 = 0;$l$addr$0 = $l;$s$addr$0 = $s;- break L10;- }- $sub = (($i$0) + -1)|0;- $arrayidx = (($s) + ($sub)|0);- $7 = HEAP8[$arrayidx>>0]|0;- $cmp11 = ($7<<24>>24)==(10);- if ($cmp11) {- $i$0$lcssa36 = $i$0;- break;- } else {- $i$0 = $sub;- }- }- $write15 = ((($f)) + 36|0);- $8 = HEAP32[$write15>>2]|0;- $call16 = (FUNCTION_TABLE_iiii[$8 & 7]($f,$s,$i$0$lcssa36)|0);- $cmp17 = ($call16>>>0)<($i$0$lcssa36>>>0);- if ($cmp17) {- $retval$0 = $i$0$lcssa36;- break L5;- }- $add$ptr = (($s) + ($i$0$lcssa36)|0);- $sub21 = (($l) - ($i$0$lcssa36))|0;- $$pre31 = HEAP32[$wpos>>2]|0;- $9 = $$pre31;$i$1 = $i$0$lcssa36;$l$addr$0 = $sub21;$s$addr$0 = $add$ptr;- } else {- $9 = $4;$i$1 = 0;$l$addr$0 = $l;$s$addr$0 = $s;- }- } while(0);- _memcpy(($9|0),($s$addr$0|0),($l$addr$0|0))|0;- $10 = HEAP32[$wpos>>2]|0;- $add$ptr26 = (($10) + ($l$addr$0)|0);- HEAP32[$wpos>>2] = $add$ptr26;- $add = (($i$1) + ($l$addr$0))|0;- $retval$0 = $add;- }- } while(0);- return ($retval$0|0);-}-function ___towrite($f) {- $f = $f|0;- var $0 = 0, $1 = 0, $2 = 0, $3 = 0, $4 = 0, $add$ptr = 0, $and = 0, $buf = 0, $buf_size = 0, $conv = 0, $conv3 = 0, $mode = 0, $or = 0, $or5 = 0, $rend = 0, $retval$0 = 0, $rpos = 0, $sub = 0, $tobool = 0, $wbase = 0;- var $wend = 0, $wpos = 0, label = 0, sp = 0;- sp = STACKTOP;- $mode = ((($f)) + 74|0);- $0 = HEAP8[$mode>>0]|0;- $conv = $0 << 24 >> 24;- $sub = (($conv) + 255)|0;- $or = $sub | $conv;- $conv3 = $or&255;- HEAP8[$mode>>0] = $conv3;- $1 = HEAP32[$f>>2]|0;- $and = $1 & 8;- $tobool = ($and|0)==(0);- if ($tobool) {- $rend = ((($f)) + 8|0);- HEAP32[$rend>>2] = 0;- $rpos = ((($f)) + 4|0);- HEAP32[$rpos>>2] = 0;- $buf = ((($f)) + 44|0);- $2 = HEAP32[$buf>>2]|0;- $wbase = ((($f)) + 28|0);- HEAP32[$wbase>>2] = $2;- $wpos = ((($f)) + 20|0);- HEAP32[$wpos>>2] = $2;- $3 = $2;- $buf_size = ((($f)) + 48|0);- $4 = HEAP32[$buf_size>>2]|0;- $add$ptr = (($3) + ($4)|0);- $wend = ((($f)) + 16|0);- HEAP32[$wend>>2] = $add$ptr;- $retval$0 = 0;- } else {- $or5 = $1 | 32;- HEAP32[$f>>2] = $or5;- $retval$0 = -1;- }- return ($retval$0|0);-}-function _wcrtomb($s,$wc,$st) {- $s = $s|0;- $wc = $wc|0;- $st = $st|0;- var $0 = 0, $and = 0, $and19 = 0, $and23 = 0, $and36 = 0, $and41 = 0, $and45 = 0, $call = 0, $cmp = 0, $cmp11 = 0, $cmp2 = 0, $cmp28 = 0, $cmp9 = 0, $conv = 0, $conv16 = 0, $conv21 = 0, $conv25 = 0, $conv33 = 0, $conv38 = 0, $conv43 = 0;- var $conv47 = 0, $conv5 = 0, $conv7 = 0, $incdec$ptr = 0, $incdec$ptr17 = 0, $incdec$ptr22 = 0, $incdec$ptr34 = 0, $incdec$ptr39 = 0, $incdec$ptr44 = 0, $or = 0, $or$cond = 0, $or15 = 0, $or20 = 0, $or24 = 0, $or32 = 0, $or37 = 0, $or42 = 0, $or46 = 0, $or6 = 0, $retval$0 = 0;- var $shr$28 = 0, $shr14$26 = 0, $shr18$27 = 0, $shr31$23 = 0, $shr35$24 = 0, $shr40$25 = 0, $sub27 = 0, $tobool = 0, label = 0, sp = 0;- sp = STACKTOP;- $tobool = ($s|0)==(0|0);- do {- if ($tobool) {- $retval$0 = 1;- } else {- $cmp = ($wc>>>0)<(128);- if ($cmp) {- $conv = $wc&255;- HEAP8[$s>>0] = $conv;- $retval$0 = 1;- break;- }- $cmp2 = ($wc>>>0)<(2048);- if ($cmp2) {- $shr$28 = $wc >>> 6;- $or = $shr$28 | 192;- $conv5 = $or&255;- $incdec$ptr = ((($s)) + 1|0);- HEAP8[$s>>0] = $conv5;- $and = $wc & 63;- $or6 = $and | 128;- $conv7 = $or6&255;- HEAP8[$incdec$ptr>>0] = $conv7;- $retval$0 = 2;- break;- }- $cmp9 = ($wc>>>0)<(55296);- $0 = $wc & -8192;- $cmp11 = ($0|0)==(57344);- $or$cond = $cmp9 | $cmp11;- if ($or$cond) {- $shr14$26 = $wc >>> 12;- $or15 = $shr14$26 | 224;- $conv16 = $or15&255;- $incdec$ptr17 = ((($s)) + 1|0);- HEAP8[$s>>0] = $conv16;- $shr18$27 = $wc >>> 6;- $and19 = $shr18$27 & 63;- $or20 = $and19 | 128;- $conv21 = $or20&255;- $incdec$ptr22 = ((($s)) + 2|0);- HEAP8[$incdec$ptr17>>0] = $conv21;- $and23 = $wc & 63;- $or24 = $and23 | 128;- $conv25 = $or24&255;- HEAP8[$incdec$ptr22>>0] = $conv25;- $retval$0 = 3;- break;- }- $sub27 = (($wc) + -65536)|0;- $cmp28 = ($sub27>>>0)<(1048576);- if ($cmp28) {- $shr31$23 = $wc >>> 18;- $or32 = $shr31$23 | 240;- $conv33 = $or32&255;- $incdec$ptr34 = ((($s)) + 1|0);- HEAP8[$s>>0] = $conv33;- $shr35$24 = $wc >>> 12;- $and36 = $shr35$24 & 63;- $or37 = $and36 | 128;- $conv38 = $or37&255;- $incdec$ptr39 = ((($s)) + 2|0);- HEAP8[$incdec$ptr34>>0] = $conv38;- $shr40$25 = $wc >>> 6;- $and41 = $shr40$25 & 63;- $or42 = $and41 | 128;- $conv43 = $or42&255;- $incdec$ptr44 = ((($s)) + 3|0);- HEAP8[$incdec$ptr39>>0] = $conv43;- $and45 = $wc & 63;- $or46 = $and45 | 128;- $conv47 = $or46&255;- HEAP8[$incdec$ptr44>>0] = $conv47;- $retval$0 = 4;- break;- } else {- $call = (___errno_location()|0);- HEAP32[$call>>2] = 84;- $retval$0 = -1;- break;- }- }- } while(0);- return ($retval$0|0);-}-function _wctomb($s,$wc) {- $s = $s|0;- $wc = $wc|0;- var $call = 0, $retval$0 = 0, $tobool = 0, label = 0, sp = 0;- sp = STACKTOP;- $tobool = ($s|0)==(0|0);- if ($tobool) {- $retval$0 = 0;- } else {- $call = (_wcrtomb($s,$wc,0)|0);- $retval$0 = $call;- }- return ($retval$0|0);-}-function _memchr($src,$c,$n) {- $src = $src|0;- $c = $c|0;- $n = $n|0;- var $0 = 0, $1 = 0, $2 = 0, $3 = 0, $4 = 0, $5 = 0, $6 = 0, $7 = 0, $and = 0, $and$39 = 0, $and15 = 0, $and16 = 0, $cmp = 0, $cmp11 = 0, $cmp11$32 = 0, $cmp28 = 0, $cmp8 = 0, $cond = 0, $conv1 = 0, $dec = 0;- var $dec34 = 0, $incdec$ptr = 0, $incdec$ptr21 = 0, $incdec$ptr33 = 0, $lnot = 0, $mul = 0, $n$addr$0$lcssa = 0, $n$addr$0$lcssa61 = 0, $n$addr$043 = 0, $n$addr$1$lcssa = 0, $n$addr$133 = 0, $n$addr$133$lcssa = 0, $n$addr$227 = 0, $n$addr$3 = 0, $neg = 0, $or$cond = 0, $or$cond$42 = 0, $s$0$lcssa = 0, $s$0$lcssa60 = 0, $s$044 = 0;- var $s$128 = 0, $s$2 = 0, $sub = 0, $sub22 = 0, $tobool = 0, $tobool$40 = 0, $tobool2 = 0, $tobool2$41 = 0, $tobool2$lcssa = 0, $tobool25 = 0, $tobool25$26 = 0, $tobool36 = 0, $w$0$lcssa = 0, $w$034 = 0, $w$034$lcssa = 0, $xor = 0, label = 0, sp = 0;- sp = STACKTOP;- $conv1 = $c & 255;- $0 = $src;- $and$39 = $0 & 3;- $tobool$40 = ($and$39|0)!=(0);- $tobool2$41 = ($n|0)!=(0);- $or$cond$42 = $tobool2$41 & $tobool$40;- L1: do {- if ($or$cond$42) {- $1 = $c&255;- $n$addr$043 = $n;$s$044 = $src;- while(1) {- $2 = HEAP8[$s$044>>0]|0;- $cmp = ($2<<24>>24)==($1<<24>>24);- if ($cmp) {- $n$addr$0$lcssa61 = $n$addr$043;$s$0$lcssa60 = $s$044;- label = 6;- break L1;- }- $incdec$ptr = ((($s$044)) + 1|0);- $dec = (($n$addr$043) + -1)|0;- $3 = $incdec$ptr;- $and = $3 & 3;- $tobool = ($and|0)!=(0);- $tobool2 = ($dec|0)!=(0);- $or$cond = $tobool2 & $tobool;- if ($or$cond) {- $n$addr$043 = $dec;$s$044 = $incdec$ptr;- } else {- $n$addr$0$lcssa = $dec;$s$0$lcssa = $incdec$ptr;$tobool2$lcssa = $tobool2;- label = 5;- break;- }- }- } else {- $n$addr$0$lcssa = $n;$s$0$lcssa = $src;$tobool2$lcssa = $tobool2$41;- label = 5;- }- } while(0);- if ((label|0) == 5) {- if ($tobool2$lcssa) {- $n$addr$0$lcssa61 = $n$addr$0$lcssa;$s$0$lcssa60 = $s$0$lcssa;- label = 6;- } else {- $n$addr$3 = 0;$s$2 = $s$0$lcssa;- }- }- L8: do {- if ((label|0) == 6) {- $4 = HEAP8[$s$0$lcssa60>>0]|0;- $5 = $c&255;- $cmp8 = ($4<<24>>24)==($5<<24>>24);- if ($cmp8) {- $n$addr$3 = $n$addr$0$lcssa61;$s$2 = $s$0$lcssa60;- } else {- $mul = Math_imul($conv1, 16843009)|0;- $cmp11$32 = ($n$addr$0$lcssa61>>>0)>(3);- L11: do {- if ($cmp11$32) {- $n$addr$133 = $n$addr$0$lcssa61;$w$034 = $s$0$lcssa60;- while(1) {- $6 = HEAP32[$w$034>>2]|0;- $xor = $6 ^ $mul;- $sub = (($xor) + -16843009)|0;- $neg = $xor & -2139062144;- $and15 = $neg ^ -2139062144;- $and16 = $and15 & $sub;- $lnot = ($and16|0)==(0);- if (!($lnot)) {- $n$addr$133$lcssa = $n$addr$133;$w$034$lcssa = $w$034;- break;- }- $incdec$ptr21 = ((($w$034)) + 4|0);- $sub22 = (($n$addr$133) + -4)|0;- $cmp11 = ($sub22>>>0)>(3);- if ($cmp11) {- $n$addr$133 = $sub22;$w$034 = $incdec$ptr21;- } else {- $n$addr$1$lcssa = $sub22;$w$0$lcssa = $incdec$ptr21;- label = 11;- break L11;- }- }- $n$addr$227 = $n$addr$133$lcssa;$s$128 = $w$034$lcssa;- } else {- $n$addr$1$lcssa = $n$addr$0$lcssa61;$w$0$lcssa = $s$0$lcssa60;- label = 11;- }- } while(0);- if ((label|0) == 11) {- $tobool25$26 = ($n$addr$1$lcssa|0)==(0);- if ($tobool25$26) {- $n$addr$3 = 0;$s$2 = $w$0$lcssa;- break;- } else {- $n$addr$227 = $n$addr$1$lcssa;$s$128 = $w$0$lcssa;- }- }- while(1) {- $7 = HEAP8[$s$128>>0]|0;- $cmp28 = ($7<<24>>24)==($5<<24>>24);- if ($cmp28) {- $n$addr$3 = $n$addr$227;$s$2 = $s$128;- break L8;- }- $incdec$ptr33 = ((($s$128)) + 1|0);- $dec34 = (($n$addr$227) + -1)|0;- $tobool25 = ($dec34|0)==(0);- if ($tobool25) {- $n$addr$3 = 0;$s$2 = $incdec$ptr33;- break;- } else {- $n$addr$227 = $dec34;$s$128 = $incdec$ptr33;- }- }- }- }- } while(0);- $tobool36 = ($n$addr$3|0)!=(0);- $cond = $tobool36 ? $s$2 : 0;- return ($cond|0);-}-function ___syscall_ret($r) {- $r = $r|0;- var $call = 0, $cmp = 0, $retval$0 = 0, $sub = 0, label = 0, sp = 0;- sp = STACKTOP;- $cmp = ($r>>>0)>(4294963200);- if ($cmp) {- $sub = (0 - ($r))|0;- $call = (___errno_location()|0);- HEAP32[$call>>2] = $sub;- $retval$0 = -1;- } else {- $retval$0 = $r;- }- return ($retval$0|0);-}-function ___fflush_unlocked($f) {- $f = $f|0;- var $0 = 0, $1 = 0, $2 = 0, $3 = 0, $4 = 0, $5 = 0, $6 = 0, $cmp = 0, $cmp4 = 0, $rend = 0, $retval$0 = 0, $rpos = 0, $seek = 0, $sub$ptr$lhs$cast = 0, $sub$ptr$rhs$cast = 0, $sub$ptr$sub = 0, $tobool = 0, $wbase = 0, $wend = 0, $wpos = 0;- var $write = 0, label = 0, sp = 0;- sp = STACKTOP;- $wpos = ((($f)) + 20|0);- $0 = HEAP32[$wpos>>2]|0;- $wbase = ((($f)) + 28|0);- $1 = HEAP32[$wbase>>2]|0;- $cmp = ($0>>>0)>($1>>>0);- if ($cmp) {- $write = ((($f)) + 36|0);- $2 = HEAP32[$write>>2]|0;- (FUNCTION_TABLE_iiii[$2 & 7]($f,0,0)|0);- $3 = HEAP32[$wpos>>2]|0;- $tobool = ($3|0)==(0|0);- if ($tobool) {- $retval$0 = -1;- } else {- label = 3;- }- } else {- label = 3;- }- if ((label|0) == 3) {- $rpos = ((($f)) + 4|0);- $4 = HEAP32[$rpos>>2]|0;- $rend = ((($f)) + 8|0);- $5 = HEAP32[$rend>>2]|0;- $cmp4 = ($4>>>0)<($5>>>0);- if ($cmp4) {- $seek = ((($f)) + 40|0);- $6 = HEAP32[$seek>>2]|0;- $sub$ptr$lhs$cast = $4;- $sub$ptr$rhs$cast = $5;- $sub$ptr$sub = (($sub$ptr$lhs$cast) - ($sub$ptr$rhs$cast))|0;- (FUNCTION_TABLE_iiii[$6 & 7]($f,$sub$ptr$sub,1)|0);- }- $wend = ((($f)) + 16|0);- HEAP32[$wend>>2] = 0;- HEAP32[$wbase>>2] = 0;- HEAP32[$wpos>>2] = 0;- HEAP32[$rend>>2] = 0;- HEAP32[$rpos>>2] = 0;- $retval$0 = 0;- }- return ($retval$0|0);-}-function _cleanup($p) {- $p = $p|0;- var $0 = 0, $lockcount = 0, $tobool = 0, label = 0, sp = 0;- sp = STACKTOP;- $lockcount = ((($p)) + 68|0);- $0 = HEAP32[$lockcount>>2]|0;- $tobool = ($0|0)==(0);- if ($tobool) {- ___unlockfile($p);- }- return;-}-function _printf_core($f,$fmt,$ap,$nl_arg,$nl_type) {- $f = $f|0;- $fmt = $fmt|0;- $ap = $ap|0;- $nl_arg = $nl_arg|0;- $nl_type = $nl_type|0;- var $$ = 0, $$$i = 0, $$396$i = 0.0, $$404$i = 0.0, $$l10n$0 = 0, $$lcssa = 0, $$p$i = 0, $$p$inc468$i = 0, $$pr$i = 0, $$pr477$i = 0, $$pre = 0, $$pre$i = 0, $$pre357 = 0, $$pre564$i = 0, $$pre566$i = 0, $$pre567$i = 0, $$sub514$i = 0, $$sub562$i = 0, $0 = 0, $1 = 0;- var $10 = 0, $100 = 0, $101 = 0, $102 = 0, $103 = 0, $104 = 0, $105 = 0, $106 = 0, $107 = 0, $108 = 0, $109 = 0, $11 = 0, $110 = 0, $111 = 0, $112 = 0, $113 = 0, $114 = 0, $115 = 0, $116 = 0, $117 = 0;- var $118 = 0, $119 = 0, $12 = 0, $120 = 0, $121 = 0, $122 = 0, $123 = 0, $124 = 0, $125 = 0, $126 = 0, $127 = 0, $128 = 0, $129 = 0, $13 = 0, $130 = 0, $131 = 0, $132 = 0, $133 = 0, $134 = 0, $135 = 0;- var $136 = 0, $137 = 0, $138 = 0, $139 = 0, $14 = 0, $140 = 0, $141 = 0, $142 = 0, $143 = 0, $144 = 0, $145 = 0, $146 = 0, $147 = 0, $148 = 0, $149 = 0, $15 = 0, $150 = 0, $151 = 0, $152 = 0, $153 = 0;- var $154 = 0, $155 = 0, $156 = 0, $157 = 0, $158 = 0, $159 = 0, $16 = 0, $160 = 0, $161 = 0, $162 = 0, $163 = 0, $164 = 0, $165 = 0, $166 = 0, $167 = 0, $168 = 0, $169 = 0, $17 = 0, $170 = 0, $171 = 0;- var $172 = 0, $173 = 0, $174 = 0, $175 = 0, $176 = 0, $177 = 0, $178 = 0, $179 = 0, $18 = 0, $180 = 0, $181 = 0.0, $182 = 0, $183 = 0, $184 = 0, $185 = 0, $186 = 0, $187 = 0, $188 = 0, $189 = 0, $19 = 0;- var $190 = 0, $191 = 0, $192 = 0, $193 = 0, $194 = 0, $195 = 0, $196 = 0, $197 = 0, $198 = 0, $199 = 0, $2 = 0, $20 = 0, $200 = 0, $201 = 0, $202 = 0, $203 = 0, $204 = 0, $205 = 0, $206 = 0, $207 = 0;- var $208 = 0, $209 = 0, $21 = 0, $210 = 0, $211 = 0, $212 = 0, $213 = 0, $214 = 0, $215 = 0, $216 = 0, $217 = 0, $218 = 0, $219 = 0, $22 = 0, $220 = 0, $221 = 0, $222 = 0, $223 = 0, $224 = 0, $225 = 0;- var $226 = 0, $227 = 0, $228 = 0, $229 = 0, $23 = 0, $230 = 0, $231 = 0, $232 = 0, $233 = 0, $234 = 0, $235 = 0, $236 = 0, $237 = 0, $238 = 0, $239 = 0, $24 = 0, $240 = 0, $241 = 0, $242 = 0, $243 = 0;- var $244 = 0, $245 = 0, $246 = 0, $247 = 0, $248 = 0, $249 = 0, $25 = 0, $250 = 0, $251 = 0, $252 = 0, $253 = 0, $254 = 0, $255 = 0, $256 = 0, $257 = 0, $258 = 0, $259 = 0, $26 = 0, $260 = 0, $261 = 0;- var $262 = 0, $263 = 0, $264 = 0, $265 = 0, $266 = 0, $267 = 0, $268 = 0, $27 = 0, $28 = 0, $29 = 0, $3 = 0, $30 = 0, $31 = 0, $32 = 0, $33 = 0, $34 = 0, $35 = 0, $36 = 0, $37 = 0, $38 = 0;- var $39 = 0, $4 = 0, $40 = 0, $41 = 0, $42 = 0, $43 = 0, $44 = 0, $45 = 0, $46 = 0, $47 = 0, $48 = 0, $49 = 0, $5 = 0, $50 = 0, $51 = 0, $52 = 0, $53 = 0, $54 = 0, $55 = 0, $56 = 0;- var $57 = 0, $58 = 0, $59 = 0, $6 = 0, $60 = 0, $61 = 0, $62 = 0, $63 = 0, $64 = 0, $65 = 0, $66 = 0, $67 = 0, $68 = 0, $69 = 0, $7 = 0, $70 = 0, $71 = 0, $72 = 0, $73 = 0, $74 = 0;- var $75 = 0, $76 = 0, $77 = 0, $78 = 0, $79 = 0, $8 = 0, $80 = 0, $81 = 0, $82 = 0, $83 = 0, $84 = 0, $85 = 0, $86 = 0, $87 = 0, $88 = 0, $89 = 0, $9 = 0, $90 = 0, $91 = 0, $92 = 0;- var $93 = 0, $94 = 0, $95 = 0, $96 = 0, $97 = 0, $98 = 0, $99 = 0, $a$0 = 0, $a$1 = 0, $a$1$lcssa$i = 0, $a$1549$i = 0, $a$2 = 0, $a$2$ph$i = 0, $a$3$lcssa$i = 0, $a$3539$i = 0, $a$5$lcssa$i = 0, $a$5521$i = 0, $a$6$i = 0, $a$8$i = 0, $a$9$ph$i = 0;- var $add = 0, $add$i = 0, $add$i$203 = 0, $add$i$239 = 0, $add$i$lcssa = 0, $add$ptr = 0, $add$ptr139 = 0, $add$ptr205 = 0, $add$ptr213$i = 0, $add$ptr257 = 0, $add$ptr311$i = 0, $add$ptr311$z$4$i = 0, $add$ptr340 = 0, $add$ptr354$i = 0, $add$ptr358$i = 0, $add$ptr359 = 0, $add$ptr373$i = 0, $add$ptr43 = 0, $add$ptr43$arrayidx31 = 0, $add$ptr442$i = 0;- var $add$ptr442$z$3$i = 0, $add$ptr473 = 0, $add$ptr65$i = 0, $add$ptr671$i = 0, $add$ptr742$i = 0, $add$ptr88 = 0, $add113$i = 0, $add150$i = 0, $add154$i = 0, $add163$i = 0, $add165$i = 0, $add269 = 0, $add269$p$0 = 0, $add273$i = 0, $add275$i = 0, $add284$i = 0, $add313$i = 0, $add322 = 0, $add355$i = 0, $add395 = 0;- var $add410$i = 0.0, $add412 = 0, $add414$i = 0, $add441 = 0, $add477$neg$i = 0, $add561$i = 0, $add608$i = 0, $add612$i = 0, $add620$i = 0, $add653$i = 0, $add67$i = 0, $add737$i = 0, $add810$i = 0, $add87$i = 0.0, $add90$i = 0.0, $and = 0, $and$i = 0, $and$i$216 = 0, $and$i$231 = 0, $and$i$238 = 0;- var $and$i$244 = 0, $and$i$406$i = 0, $and$i$412$i = 0, $and$i$418$i = 0, $and$i$424$i = 0, $and$i$430$i = 0, $and$i$436$i = 0, $and$i$442$i = 0, $and$i$448$i = 0, $and$i$454$i = 0, $and$i$460$i = 0, $and$i$466$i = 0, $and$i$472$i = 0, $and$i$i = 0, $and12$i = 0, $and134$i = 0, $and210 = 0, $and214 = 0, $and216 = 0, $and219 = 0;- var $and249 = 0, $and254 = 0, $and263 = 0, $and282$i = 0, $and289 = 0, $and294 = 0, $and309 = 0, $and309$fl$4 = 0, $and36$i = 0, $and379$i = 0, $and483$i = 0, $and610$pre$phi$iZ2D = 0, $and62$i = 0, $arg = 0, $arglist_current = 0, $arglist_current2 = 0, $arglist_next = 0, $arglist_next3 = 0, $argpos$0 = 0, $arraydecay208$add$ptr213$i = 0;- var $arrayidx$i = 0, $arrayidx$i$236 = 0, $arrayidx114 = 0, $arrayidx117$i = 0, $arrayidx119 = 0, $arrayidx124 = 0, $arrayidx132 = 0, $arrayidx16 = 0, $arrayidx173 = 0, $arrayidx192 = 0, $arrayidx251$i = 0, $arrayidx31 = 0, $arrayidx35 = 0, $arrayidx370 = 0, $arrayidx453$i = 0, $arrayidx469 = 0, $arrayidx481 = 0, $arrayidx489$i = 0, $arrayidx68 = 0, $arrayidx73 = 0;- var $arrayidx81 = 0, $big$i = 0, $buf = 0, $buf$i = 0, $call = 0, $call344 = 0, $call345 = 0, $call356 = 0, $call384 = 0, $call411 = 0, $call55$i = 0.0, $carry$0544$i = 0, $carry262$0535$i = 0, $cmp = 0, $cmp1 = 0, $cmp103$i = 0, $cmp105 = 0, $cmp111 = 0, $cmp116 = 0, $cmp126 = 0;- var $cmp127$i = 0, $cmp13 = 0, $cmp147$i = 0, $cmp165 = 0, $cmp176 = 0, $cmp18 = 0, $cmp181 = 0, $cmp184 = 0, $cmp188$i = 0, $cmp196$i = 0, $cmp205$i = 0, $cmp211 = 0, $cmp225$547$i = 0, $cmp225$i = 0, $cmp228$i = 0, $cmp235$543$i = 0, $cmp235$i = 0, $cmp240 = 0, $cmp249$i = 0, $cmp259$537$i = 0;- var $cmp259$i = 0, $cmp265$i = 0, $cmp270 = 0, $cmp277$533$i = 0, $cmp277$i = 0, $cmp299$i = 0, $cmp306 = 0, $cmp308$i = 0, $cmp315$i = 0, $cmp323 = 0, $cmp324$529$i = 0, $cmp324$i = 0, $cmp333$i = 0, $cmp338$i = 0, $cmp350$i = 0, $cmp363$525$i = 0, $cmp37 = 0, $cmp374$i = 0, $cmp377 = 0, $cmp377$314 = 0;- var $cmp38$i = 0, $cmp385 = 0, $cmp385$i = 0, $cmp390 = 0, $cmp390$i = 0, $cmp397 = 0, $cmp403$i = 0, $cmp404 = 0, $cmp404$324 = 0, $cmp411$i = 0, $cmp413 = 0, $cmp416$519$i = 0, $cmp416$i = 0, $cmp420$i = 0, $cmp421 = 0, $cmp433$515$i = 0, $cmp433$i = 0, $cmp434 = 0, $cmp442 = 0, $cmp443$i = 0;- var $cmp450$i = 0, $cmp450$lcssa$i = 0, $cmp466 = 0, $cmp470$i = 0, $cmp473$i = 0, $cmp478 = 0, $cmp478$295 = 0, $cmp48$i = 0, $cmp495$511$i = 0, $cmp495$i = 0, $cmp50 = 0, $cmp50$308 = 0, $cmp505$i = 0, $cmp515$i = 0, $cmp528$i = 0, $cmp563$i = 0, $cmp577$i = 0, $cmp59$i = 0, $cmp614$i = 0, $cmp617$i = 0;- var $cmp623$i = 0, $cmp636$506$i = 0, $cmp636$i = 0, $cmp65 = 0, $cmp660$i = 0, $cmp665$i = 0, $cmp673$i = 0, $cmp678$491$i = 0, $cmp678$i = 0, $cmp686$i = 0, $cmp707$486$i = 0, $cmp707$i = 0, $cmp710$487$i = 0, $cmp710$i = 0, $cmp722$483$i = 0, $cmp722$i = 0, $cmp727$i = 0, $cmp745$i = 0, $cmp748$499$i = 0, $cmp748$i = 0;- var $cmp75 = 0, $cmp760$i = 0, $cmp765$i = 0, $cmp770$495$i = 0, $cmp770$i = 0, $cmp777$i = 0, $cmp790$i = 0, $cmp818$i = 0, $cmp82$i = 0, $cmp94$i = 0, $cmp97 = 0, $cnt$0 = 0, $cnt$1 = 0, $cnt$1$lcssa = 0, $cond$i = 0, $cond100$i = 0, $cond233$i = 0, $cond245 = 0, $cond271$i = 0, $cond304$i = 0;- var $cond354 = 0, $cond426 = 0, $cond43$i = 0, $cond53$i = 0, $cond629$i = 0, $cond732$i = 0, $cond800$i = 0, $conv$4$i = 0, $conv$4$i$197 = 0, $conv$4$i$211 = 0, $conv$i = 0, $conv$i$205 = 0, $conv1$i = 0, $conv111$i = 0, $conv114$i = 0, $conv116$i = 0, $conv118$393$i = 0, $conv120 = 0, $conv121$i = 0, $conv123$i = 0.0;- var $conv134 = 0, $conv163 = 0, $conv174 = 0, $conv174$lcssa = 0, $conv207 = 0, $conv216$i = 0, $conv218$i = 0.0, $conv229 = 0, $conv232 = 0, $conv242$i$lcssa = 0, $conv32 = 0, $conv48 = 0, $conv48$307 = 0, $conv48311 = 0, $conv58 = 0, $conv644$i = 0, $conv646$i = 0, $conv69 = 0, $conv83 = 0, $d$0$542$i = 0;- var $d$0$i = 0, $d$0545$i = 0, $d$1534$i = 0, $d$2$lcssa$i = 0, $d$2520$i = 0, $d$4$i = 0, $d$5494$i = 0, $d$6488$i = 0, $d$7500$i = 0, $dec$i = 0, $dec476$i = 0, $dec481$i = 0, $dec78$i = 0, $div274$i = 0, $div356$i = 0, $div378$i = 0, $div384$i = 0, $e$0531$i = 0, $e$1$i = 0, $e$2517$i = 0;- var $e$4$i = 0, $e$5$ph$i = 0, $e2$i = 0, $ebuf0$i = 0, $estr$0$i = 0, $estr$1$lcssa$i = 0, $estr$1507$i = 0, $estr$2$i = 0, $exitcond$i = 0, $expanded = 0, $expanded10 = 0, $expanded11 = 0, $expanded13 = 0, $expanded14 = 0, $expanded15 = 0, $expanded4 = 0, $expanded6 = 0, $expanded7 = 0, $expanded8 = 0, $fl$0284 = 0;- var $fl$0310 = 0, $fl$1 = 0, $fl$1$and219 = 0, $fl$3 = 0, $fl$4 = 0, $fl$6 = 0, $i$0$lcssa = 0, $i$0$lcssa368 = 0, $i$0316 = 0, $i$0530$i = 0, $i$07$i = 0, $i$07$i$201 = 0, $i$1$lcssa$i = 0, $i$1325 = 0, $i$1526$i = 0, $i$2299 = 0, $i$2299$lcssa = 0, $i$2516$i = 0, $i$3296 = 0, $i$3512$i = 0;- var $i137 = 0, $i86 = 0, $idxprom$i = 0, $inc = 0, $inc$i = 0, $inc425$i = 0, $inc438$i = 0, $inc468$i = 0, $inc488 = 0, $inc500$i = 0, $incdec$ptr = 0, $incdec$ptr$i = 0, $incdec$ptr$i$204 = 0, $incdec$ptr$i$212 = 0, $incdec$ptr$i$212$lcssa = 0, $incdec$ptr$i$225 = 0, $incdec$ptr$i$lcssa = 0, $incdec$ptr106$i = 0, $incdec$ptr112$i = 0, $incdec$ptr115$i = 0;- var $incdec$ptr122$i = 0, $incdec$ptr137$i = 0, $incdec$ptr169 = 0, $incdec$ptr169$lcssa = 0, $incdec$ptr169269 = 0, $incdec$ptr169271 = 0, $incdec$ptr169271$lcssa414 = 0, $incdec$ptr169272 = 0, $incdec$ptr169274 = 0, $incdec$ptr169275 = 0, $incdec$ptr169276$lcssa = 0, $incdec$ptr169276301 = 0, $incdec$ptr217$i = 0, $incdec$ptr217$i$lcssa = 0, $incdec$ptr23 = 0, $incdec$ptr246$i = 0, $incdec$ptr288$i = 0, $incdec$ptr292$570$i = 0, $incdec$ptr292$a$3$571$i = 0, $incdec$ptr292$a$3$i = 0;- var $incdec$ptr292$a$3573$i = 0, $incdec$ptr292$i = 0, $incdec$ptr296$i = 0, $incdec$ptr383 = 0, $incdec$ptr410 = 0, $incdec$ptr419$i = 0, $incdec$ptr423$i = 0, $incdec$ptr62 = 0, $incdec$ptr639$i = 0, $incdec$ptr645$i = 0, $incdec$ptr647$i = 0, $incdec$ptr681$i = 0, $incdec$ptr689$i = 0, $incdec$ptr698$i = 0, $incdec$ptr698$i$lcssa = 0, $incdec$ptr725$i = 0, $incdec$ptr734$i = 0, $incdec$ptr773$i = 0, $incdec$ptr776$i = 0, $incdec$ptr808$i = 0;- var $isdigit = 0, $isdigit$6$i = 0, $isdigit$6$i$199 = 0, $isdigit$i = 0, $isdigit$i$207 = 0, $isdigit188 = 0, $isdigit190 = 0, $isdigittmp = 0, $isdigittmp$ = 0, $isdigittmp$5$i = 0, $isdigittmp$5$i$198 = 0, $isdigittmp$i = 0, $isdigittmp$i$206 = 0, $isdigittmp187 = 0, $isdigittmp189 = 0, $isdigittmp8$i = 0, $isdigittmp8$i$200 = 0, $j$0$524$i = 0, $j$0$i = 0, $j$0527$i = 0;- var $j$1513$i = 0, $j$2$i = 0, $l$0 = 0, $l$0$i = 0, $l$1$i = 0, $l$1315 = 0, $l$2 = 0, $l10n$0 = 0, $l10n$0$lcssa = 0, $l10n$0$phi = 0, $l10n$1 = 0, $l10n$2 = 0, $l10n$3 = 0, $land$ext$neg$i = 0, $lnot$ext = 0, $lnot$i = 0, $lnot455$i = 0, $lnot483 = 0, $lor$ext$i = 0, $mb = 0;- var $mul$i = 0, $mul$i$202 = 0, $mul$i$240 = 0.0, $mul125$i = 0.0, $mul202$i = 0.0, $mul220$i = 0.0, $mul286$i = 0, $mul286$i$lcssa = 0, $mul322$i = 0, $mul328$i = 0, $mul335$i = 0, $mul349$i = 0, $mul367$i = 0, $mul406$i = 0.0, $mul407$i = 0.0, $mul431$i = 0, $mul437$i = 0, $mul499$i = 0, $mul513$i = 0, $mul80$i = 0.0;- var $mul80$i$lcssa = 0.0, $notlhs$i = 0, $notrhs$i = 0, $or = 0, $or$cond = 0, $or$cond$i = 0, $or$cond1$not$i = 0, $or$cond192 = 0, $or$cond193 = 0, $or$cond195 = 0, $or$cond2$i = 0, $or$cond384 = 0, $or$cond395$i = 0, $or$cond397$i = 0, $or$cond401$i = 0, $or$i = 0, $or$i$241 = 0, $or100 = 0, $or120$i = 0, $or246 = 0;- var $or504$i = 0, $or613$i = 0, $p$0 = 0, $p$1 = 0, $p$2 = 0, $p$2$add322 = 0, $p$3 = 0, $p$4365 = 0, $p$5 = 0, $p$addr$2$$sub514398$i = 0, $p$addr$2$$sub562399$i = 0, $p$addr$2$i = 0, $p$addr$3$i = 0, $p$addr$4$lcssa$i = 0, $p$addr$4489$i = 0, $p$addr$5$lcssa$i = 0, $p$addr$5501$i = 0, $pl$0 = 0, $pl$0$i = 0, $pl$1 = 0;- var $pl$1$i = 0, $pl$2 = 0, $prefix$0 = 0, $prefix$0$add$ptr65$i = 0, $prefix$0$i = 0, $prefix$1 = 0, $prefix$2 = 0, $r$0$a$9$i = 0, $re$1482$i = 0, $rem360$i = 0, $rem370$i = 0, $rem494$510$i = 0, $rem494$i = 0, $retval$0 = 0, $retval$0$i = 0, $round$0481$i = 0.0, $round377$1$i = 0.0, $s$0$i = 0, $s$1$i = 0, $s$1$i$lcssa = 0;- var $s$addr$0$lcssa$i$229 = 0, $s$addr$06$i = 0, $s$addr$06$i$221 = 0, $s35$0$i = 0, $s668$0492$i = 0, $s668$1$i = 0, $s715$0$lcssa$i = 0, $s715$0484$i = 0, $s753$0$i = 0, $s753$1496$i = 0, $s753$2$i = 0, $shl = 0, $shl280$i = 0, $shl60 = 0, $shr = 0, $shr283$i = 0, $shr285$i = 0, $small$0$i = 0.0, $small$1$i = 0.0, $st$0 = 0;- var $st$0$lcssa415 = 0, $storemerge = 0, $storemerge$186282 = 0, $storemerge$186309 = 0, $storemerge$191 = 0, $sub = 0, $sub$i = 0.0, $sub$ptr$div$i = 0, $sub$ptr$div321$i = 0, $sub$ptr$div347$i = 0, $sub$ptr$div430$i = 0, $sub$ptr$div511$i = 0, $sub$ptr$lhs$cast = 0, $sub$ptr$lhs$cast$i = 0, $sub$ptr$lhs$cast160$i = 0, $sub$ptr$lhs$cast305$i = 0, $sub$ptr$lhs$cast317 = 0, $sub$ptr$lhs$cast344$i = 0, $sub$ptr$lhs$cast361 = 0, $sub$ptr$lhs$cast431 = 0;- var $sub$ptr$lhs$cast508$i = 0, $sub$ptr$lhs$cast694$i = 0, $sub$ptr$rhs$cast = 0, $sub$ptr$rhs$cast$i = 0, $sub$ptr$rhs$cast152$i = 0, $sub$ptr$rhs$cast161$i = 0, $sub$ptr$rhs$cast174$i = 0, $sub$ptr$rhs$cast267 = 0, $sub$ptr$rhs$cast306$i = 0, $sub$ptr$rhs$cast318 = 0, $sub$ptr$rhs$cast319$i = 0, $sub$ptr$rhs$cast345$i = 0, $sub$ptr$rhs$cast362 = 0, $sub$ptr$rhs$cast428$i = 0, $sub$ptr$rhs$cast432 = 0, $sub$ptr$rhs$cast634$504$i = 0, $sub$ptr$rhs$cast634$i = 0, $sub$ptr$rhs$cast649$i = 0, $sub$ptr$rhs$cast695$i = 0, $sub$ptr$rhs$cast788$i = 0;- var $sub$ptr$rhs$cast812$i = 0, $sub$ptr$sub = 0, $sub$ptr$sub$i = 0, $sub$ptr$sub145$i = 0, $sub$ptr$sub153$i = 0, $sub$ptr$sub159$i = 0, $sub$ptr$sub162$i = 0, $sub$ptr$sub172$i = 0, $sub$ptr$sub175$i = 0, $sub$ptr$sub268 = 0, $sub$ptr$sub307$i = 0, $sub$ptr$sub319 = 0, $sub$ptr$sub320$i = 0, $sub$ptr$sub346$i = 0, $sub$ptr$sub363 = 0, $sub$ptr$sub429$i = 0, $sub$ptr$sub433 = 0, $sub$ptr$sub433$p$5 = 0, $sub$ptr$sub510$i = 0, $sub$ptr$sub635$505$i = 0;- var $sub$ptr$sub635$i = 0, $sub$ptr$sub650$i = 0, $sub$ptr$sub650$pn$i = 0, $sub$ptr$sub696$i = 0, $sub$ptr$sub789$i = 0, $sub$ptr$sub813$i = 0, $sub101 = 0, $sub124$i = 0.0, $sub135 = 0, $sub146$i = 0, $sub164 = 0, $sub175 = 0, $sub181$i = 0, $sub203$i = 0, $sub219$i = 0.0, $sub256$i = 0, $sub264$i = 0, $sub281$i = 0, $sub336$i = 0, $sub343$i = 0;- var $sub357$i = 0, $sub389 = 0, $sub409$i = 0, $sub478$i = 0, $sub480$i = 0, $sub514$i = 0, $sub54 = 0, $sub562$i = 0, $sub59 = 0, $sub626$le$i = 0, $sub735$i = 0, $sub74$i = 0, $sub806$i = 0, $sub84 = 0, $sub85$i = 0.0, $sub86$i = 0.0, $sub88$i = 0.0, $sub91$i = 0.0, $sub97$i = 0, $sum = 0;- var $t$0 = 0, $t$1 = 0, $t$addr$0$i = 0, $t$addr$1$i = 0, $tobool = 0, $tobool$i = 0, $tobool$i$217 = 0, $tobool$i$232 = 0, $tobool$i$245 = 0, $tobool$i$407$i = 0, $tobool$i$413$i = 0, $tobool$i$419$i = 0, $tobool$i$425$i = 0, $tobool$i$431$i = 0, $tobool$i$437$i = 0, $tobool$i$443$i = 0, $tobool$i$449$i = 0, $tobool$i$455$i = 0, $tobool$i$461$i = 0, $tobool$i$467$i = 0;- var $tobool$i$473$i = 0, $tobool$i$i = 0, $tobool13$i = 0, $tobool135$i = 0, $tobool139$i = 0, $tobool140$i = 0, $tobool141 = 0, $tobool178 = 0, $tobool208 = 0, $tobool217 = 0, $tobool222$i = 0, $tobool244$i = 0, $tobool25 = 0, $tobool255 = 0, $tobool264 = 0, $tobool28 = 0, $tobool290 = 0, $tobool290$569$i = 0, $tobool290$i = 0, $tobool294$i = 0;- var $tobool295 = 0, $tobool314 = 0, $tobool341$i = 0, $tobool349 = 0, $tobool357 = 0, $tobool37$i = 0, $tobool371$i = 0, $tobool380 = 0, $tobool380$i = 0, $tobool400$i = 0, $tobool407 = 0, $tobool459 = 0, $tobool462 = 0, $tobool470 = 0, $tobool484$i = 0, $tobool490$i = 0, $tobool55 = 0, $tobool56$i = 0, $tobool63$i = 0, $tobool76$i = 0;- var $tobool76552$i = 0, $tobool781$i = 0, $tobool79$i = 0, $tobool9$i = 0, $tobool90 = 0, $w$0 = 0, $w$1 = 0, $w$2 = 0, $w$add165$i = 0, $w$add653$i = 0, $wc = 0, $ws$0317 = 0, $ws$1326 = 0, $xor = 0, $xor$i = 0, $xor167$i = 0, $xor186$i = 0, $xor449 = 0, $xor457 = 0, $xor655$i = 0;- var $xor816$i = 0, $y$addr$0$i = 0.0, $y$addr$1$i = 0.0, $y$addr$2$i = 0.0, $y$addr$3$i = 0.0, $y$addr$4$i = 0.0, $z$0$i = 0, $z$0$lcssa = 0, $z$0302 = 0, $z$1 = 0, $z$1$lcssa$i = 0, $z$1548$i = 0, $z$2 = 0, $z$2$i = 0, $z$2$i$lcssa = 0, $z$3$lcssa$i = 0, $z$3538$i = 0, $z$4$i = 0, $z$7$add$ptr742$i = 0, $z$7$i = 0;- var $z$7$i$lcssa = 0, $z$7$ph$i = 0, label = 0, sp = 0;- sp = STACKTOP;- STACKTOP = STACKTOP + 624|0; if ((STACKTOP|0) >= (STACK_MAX|0)) abort();- $big$i = sp + 24|0;- $e2$i = sp + 16|0;- $buf$i = sp + 588|0;- $ebuf0$i = sp + 576|0;- $arg = sp;- $buf = sp + 536|0;- $wc = sp + 8|0;- $mb = sp + 528|0;- $tobool25 = ($f|0)!=(0|0);- $add$ptr205 = ((($buf)) + 40|0);- $sub$ptr$lhs$cast317 = $add$ptr205;- $add$ptr340 = ((($buf)) + 39|0);- $arrayidx370 = ((($wc)) + 4|0);- $arrayidx$i$236 = ((($ebuf0$i)) + 12|0);- $incdec$ptr106$i = ((($ebuf0$i)) + 11|0);- $sub$ptr$rhs$cast$i = $buf$i;- $sub$ptr$lhs$cast160$i = $arrayidx$i$236;- $sub$ptr$sub159$i = (($sub$ptr$lhs$cast160$i) - ($sub$ptr$rhs$cast$i))|0;- $sub$ptr$sub145$i = (-2 - ($sub$ptr$rhs$cast$i))|0;- $sub$ptr$sub153$i = (($sub$ptr$lhs$cast160$i) + 2)|0;- $add$ptr213$i = ((($big$i)) + 288|0);- $add$ptr671$i = ((($buf$i)) + 9|0);- $sub$ptr$lhs$cast694$i = $add$ptr671$i;- $incdec$ptr689$i = ((($buf$i)) + 8|0);- $cnt$0 = 0;$incdec$ptr169275 = $fmt;$l$0 = 0;$l10n$0 = 0;- L1: while(1) {- $cmp = ($cnt$0|0)>(-1);- do {- if ($cmp) {- $sub = (2147483647 - ($cnt$0))|0;- $cmp1 = ($l$0|0)>($sub|0);- if ($cmp1) {- $call = (___errno_location()|0);- HEAP32[$call>>2] = 75;- $cnt$1 = -1;- break;- } else {- $add = (($l$0) + ($cnt$0))|0;- $cnt$1 = $add;- break;- }- } else {- $cnt$1 = $cnt$0;- }- } while(0);- $0 = HEAP8[$incdec$ptr169275>>0]|0;- $tobool = ($0<<24>>24)==(0);- if ($tobool) {- $cnt$1$lcssa = $cnt$1;$l10n$0$lcssa = $l10n$0;- label = 242;- break;- } else {- $1 = $0;$incdec$ptr169274 = $incdec$ptr169275;- }- L9: while(1) {- switch ($1<<24>>24) {- case 37: {- $incdec$ptr169276301 = $incdec$ptr169274;$z$0302 = $incdec$ptr169274;- label = 9;- break L9;- break;- }- case 0: {- $incdec$ptr169276$lcssa = $incdec$ptr169274;$z$0$lcssa = $incdec$ptr169274;- break L9;- break;- }- default: {- }- }- $incdec$ptr = ((($incdec$ptr169274)) + 1|0);- $$pre = HEAP8[$incdec$ptr>>0]|0;- $1 = $$pre;$incdec$ptr169274 = $incdec$ptr;- }- L12: do {- if ((label|0) == 9) {- while(1) {- label = 0;- $arrayidx16 = ((($incdec$ptr169276301)) + 1|0);- $2 = HEAP8[$arrayidx16>>0]|0;- $cmp18 = ($2<<24>>24)==(37);- if (!($cmp18)) {- $incdec$ptr169276$lcssa = $incdec$ptr169276301;$z$0$lcssa = $z$0302;- break L12;- }- $incdec$ptr23 = ((($z$0302)) + 1|0);- $add$ptr = ((($incdec$ptr169276301)) + 2|0);- $3 = HEAP8[$add$ptr>>0]|0;- $cmp13 = ($3<<24>>24)==(37);- if ($cmp13) {- $incdec$ptr169276301 = $add$ptr;$z$0302 = $incdec$ptr23;- label = 9;- } else {- $incdec$ptr169276$lcssa = $add$ptr;$z$0$lcssa = $incdec$ptr23;- break;- }- }- }- } while(0);- $sub$ptr$lhs$cast = $z$0$lcssa;- $sub$ptr$rhs$cast = $incdec$ptr169275;- $sub$ptr$sub = (($sub$ptr$lhs$cast) - ($sub$ptr$rhs$cast))|0;- if ($tobool25) {- $4 = HEAP32[$f>>2]|0;- $and$i = $4 & 32;- $tobool$i = ($and$i|0)==(0);- if ($tobool$i) {- (___fwritex($incdec$ptr169275,$sub$ptr$sub,$f)|0);- }- }- $tobool28 = ($z$0$lcssa|0)==($incdec$ptr169275|0);- if (!($tobool28)) {- $l10n$0$phi = $l10n$0;$cnt$0 = $cnt$1;$incdec$ptr169275 = $incdec$ptr169276$lcssa;$l$0 = $sub$ptr$sub;$l10n$0 = $l10n$0$phi;- continue;- }- $arrayidx31 = ((($incdec$ptr169276$lcssa)) + 1|0);- $5 = HEAP8[$arrayidx31>>0]|0;- $conv32 = $5 << 24 >> 24;- $isdigittmp = (($conv32) + -48)|0;- $isdigit = ($isdigittmp>>>0)<(10);- if ($isdigit) {- $arrayidx35 = ((($incdec$ptr169276$lcssa)) + 2|0);- $6 = HEAP8[$arrayidx35>>0]|0;- $cmp37 = ($6<<24>>24)==(36);- $add$ptr43 = ((($incdec$ptr169276$lcssa)) + 3|0);- $add$ptr43$arrayidx31 = $cmp37 ? $add$ptr43 : $arrayidx31;- $$l10n$0 = $cmp37 ? 1 : $l10n$0;- $isdigittmp$ = $cmp37 ? $isdigittmp : -1;- $$pre357 = HEAP8[$add$ptr43$arrayidx31>>0]|0;- $7 = $$pre357;$argpos$0 = $isdigittmp$;$l10n$1 = $$l10n$0;$storemerge = $add$ptr43$arrayidx31;- } else {- $7 = $5;$argpos$0 = -1;$l10n$1 = $l10n$0;$storemerge = $arrayidx31;- }- $conv48$307 = $7 << 24 >> 24;- $8 = $conv48$307 & -32;- $cmp50$308 = ($8|0)==(32);- L25: do {- if ($cmp50$308) {- $9 = $7;$conv48311 = $conv48$307;$fl$0310 = 0;$storemerge$186309 = $storemerge;- while(1) {- $sub54 = (($conv48311) + -32)|0;- $shl = 1 << $sub54;- $and = $shl & 75913;- $tobool55 = ($and|0)==(0);- if ($tobool55) {- $12 = $9;$fl$0284 = $fl$0310;$storemerge$186282 = $storemerge$186309;- break L25;- }- $conv58 = $9 << 24 >> 24;- $sub59 = (($conv58) + -32)|0;- $shl60 = 1 << $sub59;- $or = $shl60 | $fl$0310;- $incdec$ptr62 = ((($storemerge$186309)) + 1|0);- $10 = HEAP8[$incdec$ptr62>>0]|0;- $conv48 = $10 << 24 >> 24;- $11 = $conv48 & -32;- $cmp50 = ($11|0)==(32);- if ($cmp50) {- $9 = $10;$conv48311 = $conv48;$fl$0310 = $or;$storemerge$186309 = $incdec$ptr62;- } else {- $12 = $10;$fl$0284 = $or;$storemerge$186282 = $incdec$ptr62;- break;- }- }- } else {- $12 = $7;$fl$0284 = 0;$storemerge$186282 = $storemerge;- }- } while(0);- $cmp65 = ($12<<24>>24)==(42);- do {- if ($cmp65) {- $arrayidx68 = ((($storemerge$186282)) + 1|0);- $13 = HEAP8[$arrayidx68>>0]|0;- $conv69 = $13 << 24 >> 24;- $isdigittmp189 = (($conv69) + -48)|0;- $isdigit190 = ($isdigittmp189>>>0)<(10);- if ($isdigit190) {- $arrayidx73 = ((($storemerge$186282)) + 2|0);- $14 = HEAP8[$arrayidx73>>0]|0;- $cmp75 = ($14<<24>>24)==(36);- if ($cmp75) {- $arrayidx81 = (($nl_type) + ($isdigittmp189<<2)|0);- HEAP32[$arrayidx81>>2] = 10;- $15 = HEAP8[$arrayidx68>>0]|0;- $conv83 = $15 << 24 >> 24;- $sub84 = (($conv83) + -48)|0;- $i86 = (($nl_arg) + ($sub84<<3)|0);- $16 = $i86;- $17 = $16;- $18 = HEAP32[$17>>2]|0;- $19 = (($16) + 4)|0;- $20 = $19;- $21 = HEAP32[$20>>2]|0;- $add$ptr88 = ((($storemerge$186282)) + 3|0);- $l10n$2 = 1;$storemerge$191 = $add$ptr88;$w$0 = $18;- } else {- label = 24;- }- } else {- label = 24;- }- if ((label|0) == 24) {- label = 0;- $tobool90 = ($l10n$1|0)==(0);- if (!($tobool90)) {- $retval$0 = -1;- break L1;- }- if (!($tobool25)) {- $fl$1 = $fl$0284;$incdec$ptr169269 = $arrayidx68;$l10n$3 = 0;$w$1 = 0;- break;- }- $arglist_current = HEAP32[$ap>>2]|0;- $22 = $arglist_current;- $23 = ((0) + 4|0);- $expanded4 = $23;- $expanded = (($expanded4) - 1)|0;- $24 = (($22) + ($expanded))|0;- $25 = ((0) + 4|0);- $expanded8 = $25;- $expanded7 = (($expanded8) - 1)|0;- $expanded6 = $expanded7 ^ -1;- $26 = $24 & $expanded6;- $27 = $26;- $28 = HEAP32[$27>>2]|0;- $arglist_next = ((($27)) + 4|0);- HEAP32[$ap>>2] = $arglist_next;- $l10n$2 = 0;$storemerge$191 = $arrayidx68;$w$0 = $28;- }- $cmp97 = ($w$0|0)<(0);- if ($cmp97) {- $or100 = $fl$0284 | 8192;- $sub101 = (0 - ($w$0))|0;- $fl$1 = $or100;$incdec$ptr169269 = $storemerge$191;$l10n$3 = $l10n$2;$w$1 = $sub101;- } else {- $fl$1 = $fl$0284;$incdec$ptr169269 = $storemerge$191;$l10n$3 = $l10n$2;$w$1 = $w$0;- }- } else {- $conv$4$i = $12 << 24 >> 24;- $isdigittmp$5$i = (($conv$4$i) + -48)|0;- $isdigit$6$i = ($isdigittmp$5$i>>>0)<(10);- if ($isdigit$6$i) {- $29 = $storemerge$186282;$i$07$i = 0;$isdigittmp8$i = $isdigittmp$5$i;- while(1) {- $mul$i = ($i$07$i*10)|0;- $add$i = (($mul$i) + ($isdigittmp8$i))|0;- $incdec$ptr$i = ((($29)) + 1|0);- $30 = HEAP8[$incdec$ptr$i>>0]|0;- $conv$i = $30 << 24 >> 24;- $isdigittmp$i = (($conv$i) + -48)|0;- $isdigit$i = ($isdigittmp$i>>>0)<(10);- if ($isdigit$i) {- $29 = $incdec$ptr$i;$i$07$i = $add$i;$isdigittmp8$i = $isdigittmp$i;- } else {- $add$i$lcssa = $add$i;$incdec$ptr$i$lcssa = $incdec$ptr$i;- break;- }- }- $cmp105 = ($add$i$lcssa|0)<(0);- if ($cmp105) {- $retval$0 = -1;- break L1;- } else {- $fl$1 = $fl$0284;$incdec$ptr169269 = $incdec$ptr$i$lcssa;$l10n$3 = $l10n$1;$w$1 = $add$i$lcssa;- }- } else {- $fl$1 = $fl$0284;$incdec$ptr169269 = $storemerge$186282;$l10n$3 = $l10n$1;$w$1 = 0;- }- }- } while(0);- $31 = HEAP8[$incdec$ptr169269>>0]|0;- $cmp111 = ($31<<24>>24)==(46);- L46: do {- if ($cmp111) {- $arrayidx114 = ((($incdec$ptr169269)) + 1|0);- $32 = HEAP8[$arrayidx114>>0]|0;- $cmp116 = ($32<<24>>24)==(42);- if (!($cmp116)) {- $conv$4$i$197 = $32 << 24 >> 24;- $isdigittmp$5$i$198 = (($conv$4$i$197) + -48)|0;- $isdigit$6$i$199 = ($isdigittmp$5$i$198>>>0)<(10);- if ($isdigit$6$i$199) {- $49 = $arrayidx114;$i$07$i$201 = 0;$isdigittmp8$i$200 = $isdigittmp$5$i$198;- } else {- $incdec$ptr169272 = $arrayidx114;$p$0 = 0;- break;- }- while(1) {- $mul$i$202 = ($i$07$i$201*10)|0;- $add$i$203 = (($mul$i$202) + ($isdigittmp8$i$200))|0;- $incdec$ptr$i$204 = ((($49)) + 1|0);- $50 = HEAP8[$incdec$ptr$i$204>>0]|0;- $conv$i$205 = $50 << 24 >> 24;- $isdigittmp$i$206 = (($conv$i$205) + -48)|0;- $isdigit$i$207 = ($isdigittmp$i$206>>>0)<(10);- if ($isdigit$i$207) {- $49 = $incdec$ptr$i$204;$i$07$i$201 = $add$i$203;$isdigittmp8$i$200 = $isdigittmp$i$206;- } else {- $incdec$ptr169272 = $incdec$ptr$i$204;$p$0 = $add$i$203;- break L46;- }- }- }- $arrayidx119 = ((($incdec$ptr169269)) + 2|0);- $33 = HEAP8[$arrayidx119>>0]|0;- $conv120 = $33 << 24 >> 24;- $isdigittmp187 = (($conv120) + -48)|0;- $isdigit188 = ($isdigittmp187>>>0)<(10);- if ($isdigit188) {- $arrayidx124 = ((($incdec$ptr169269)) + 3|0);- $34 = HEAP8[$arrayidx124>>0]|0;- $cmp126 = ($34<<24>>24)==(36);- if ($cmp126) {- $arrayidx132 = (($nl_type) + ($isdigittmp187<<2)|0);- HEAP32[$arrayidx132>>2] = 10;- $35 = HEAP8[$arrayidx119>>0]|0;- $conv134 = $35 << 24 >> 24;- $sub135 = (($conv134) + -48)|0;- $i137 = (($nl_arg) + ($sub135<<3)|0);- $36 = $i137;- $37 = $36;- $38 = HEAP32[$37>>2]|0;- $39 = (($36) + 4)|0;- $40 = $39;- $41 = HEAP32[$40>>2]|0;- $add$ptr139 = ((($incdec$ptr169269)) + 4|0);- $incdec$ptr169272 = $add$ptr139;$p$0 = $38;- break;- }- }- $tobool141 = ($l10n$3|0)==(0);- if (!($tobool141)) {- $retval$0 = -1;- break L1;- }- if ($tobool25) {- $arglist_current2 = HEAP32[$ap>>2]|0;- $42 = $arglist_current2;- $43 = ((0) + 4|0);- $expanded11 = $43;- $expanded10 = (($expanded11) - 1)|0;- $44 = (($42) + ($expanded10))|0;- $45 = ((0) + 4|0);- $expanded15 = $45;- $expanded14 = (($expanded15) - 1)|0;- $expanded13 = $expanded14 ^ -1;- $46 = $44 & $expanded13;- $47 = $46;- $48 = HEAP32[$47>>2]|0;- $arglist_next3 = ((($47)) + 4|0);- HEAP32[$ap>>2] = $arglist_next3;- $incdec$ptr169272 = $arrayidx119;$p$0 = $48;- } else {- $incdec$ptr169272 = $arrayidx119;$p$0 = 0;- }- } else {- $incdec$ptr169272 = $incdec$ptr169269;$p$0 = -1;- }- } while(0);- $incdec$ptr169271 = $incdec$ptr169272;$st$0 = 0;- while(1) {- $51 = HEAP8[$incdec$ptr169271>>0]|0;- $conv163 = $51 << 24 >> 24;- $sub164 = (($conv163) + -65)|0;- $cmp165 = ($sub164>>>0)>(57);- if ($cmp165) {- $retval$0 = -1;- break L1;- }- $incdec$ptr169 = ((($incdec$ptr169271)) + 1|0);- $arrayidx173 = ((3611 + (($st$0*58)|0)|0) + ($sub164)|0);- $52 = HEAP8[$arrayidx173>>0]|0;- $conv174 = $52&255;- $sub175 = (($conv174) + -1)|0;- $cmp176 = ($sub175>>>0)<(8);- if ($cmp176) {- $incdec$ptr169271 = $incdec$ptr169;$st$0 = $conv174;- } else {- $$lcssa = $52;$conv174$lcssa = $conv174;$incdec$ptr169$lcssa = $incdec$ptr169;$incdec$ptr169271$lcssa414 = $incdec$ptr169271;$st$0$lcssa415 = $st$0;- break;- }- }- $tobool178 = ($$lcssa<<24>>24)==(0);- if ($tobool178) {- $retval$0 = -1;- break;- }- $cmp181 = ($$lcssa<<24>>24)==(19);- $cmp184 = ($argpos$0|0)>(-1);- do {- if ($cmp181) {- if ($cmp184) {- $retval$0 = -1;- break L1;- } else {- label = 52;- }- } else {- if ($cmp184) {- $arrayidx192 = (($nl_type) + ($argpos$0<<2)|0);- HEAP32[$arrayidx192>>2] = $conv174$lcssa;- $53 = (($nl_arg) + ($argpos$0<<3)|0);- $54 = $53;- $55 = $54;- $56 = HEAP32[$55>>2]|0;- $57 = (($54) + 4)|0;- $58 = $57;- $59 = HEAP32[$58>>2]|0;- $60 = $arg;- $61 = $60;- HEAP32[$61>>2] = $56;- $62 = (($60) + 4)|0;- $63 = $62;- HEAP32[$63>>2] = $59;- label = 52;- break;- }- if (!($tobool25)) {- $retval$0 = 0;- break L1;- }- _pop_arg_336($arg,$conv174$lcssa,$ap);- }- } while(0);- if ((label|0) == 52) {- label = 0;- if (!($tobool25)) {- $cnt$0 = $cnt$1;$incdec$ptr169275 = $incdec$ptr169$lcssa;$l$0 = $sub$ptr$sub;$l10n$0 = $l10n$3;- continue;- }- }- $64 = HEAP8[$incdec$ptr169271$lcssa414>>0]|0;- $conv207 = $64 << 24 >> 24;- $tobool208 = ($st$0$lcssa415|0)!=(0);- $and210 = $conv207 & 15;- $cmp211 = ($and210|0)==(3);- $or$cond192 = $tobool208 & $cmp211;- $and214 = $conv207 & -33;- $t$0 = $or$cond192 ? $and214 : $conv207;- $and216 = $fl$1 & 8192;- $tobool217 = ($and216|0)==(0);- $and219 = $fl$1 & -65537;- $fl$1$and219 = $tobool217 ? $fl$1 : $and219;- L75: do {- switch ($t$0|0) {- case 110: {- switch ($st$0$lcssa415|0) {- case 0: {- $71 = HEAP32[$arg>>2]|0;- HEAP32[$71>>2] = $cnt$1;- $cnt$0 = $cnt$1;$incdec$ptr169275 = $incdec$ptr169$lcssa;$l$0 = $sub$ptr$sub;$l10n$0 = $l10n$3;- continue L1;- break;- }- case 1: {- $72 = HEAP32[$arg>>2]|0;- HEAP32[$72>>2] = $cnt$1;- $cnt$0 = $cnt$1;$incdec$ptr169275 = $incdec$ptr169$lcssa;$l$0 = $sub$ptr$sub;$l10n$0 = $l10n$3;- continue L1;- break;- }- case 2: {- $73 = ($cnt$1|0)<(0);- $74 = $73 << 31 >> 31;- $75 = HEAP32[$arg>>2]|0;- $76 = $75;- $77 = $76;- HEAP32[$77>>2] = $cnt$1;- $78 = (($76) + 4)|0;- $79 = $78;- HEAP32[$79>>2] = $74;- $cnt$0 = $cnt$1;$incdec$ptr169275 = $incdec$ptr169$lcssa;$l$0 = $sub$ptr$sub;$l10n$0 = $l10n$3;- continue L1;- break;- }- case 3: {- $conv229 = $cnt$1&65535;- $80 = HEAP32[$arg>>2]|0;- HEAP16[$80>>1] = $conv229;- $cnt$0 = $cnt$1;$incdec$ptr169275 = $incdec$ptr169$lcssa;$l$0 = $sub$ptr$sub;$l10n$0 = $l10n$3;- continue L1;- break;- }- case 4: {- $conv232 = $cnt$1&255;- $81 = HEAP32[$arg>>2]|0;- HEAP8[$81>>0] = $conv232;- $cnt$0 = $cnt$1;$incdec$ptr169275 = $incdec$ptr169$lcssa;$l$0 = $sub$ptr$sub;$l10n$0 = $l10n$3;- continue L1;- break;- }- case 6: {- $82 = HEAP32[$arg>>2]|0;- HEAP32[$82>>2] = $cnt$1;- $cnt$0 = $cnt$1;$incdec$ptr169275 = $incdec$ptr169$lcssa;$l$0 = $sub$ptr$sub;$l10n$0 = $l10n$3;- continue L1;- break;- }- case 7: {- $83 = ($cnt$1|0)<(0);- $84 = $83 << 31 >> 31;- $85 = HEAP32[$arg>>2]|0;- $86 = $85;- $87 = $86;- HEAP32[$87>>2] = $cnt$1;- $88 = (($86) + 4)|0;- $89 = $88;- HEAP32[$89>>2] = $84;- $cnt$0 = $cnt$1;$incdec$ptr169275 = $incdec$ptr169$lcssa;$l$0 = $sub$ptr$sub;$l10n$0 = $l10n$3;- continue L1;- break;- }- default: {- $cnt$0 = $cnt$1;$incdec$ptr169275 = $incdec$ptr169$lcssa;$l$0 = $sub$ptr$sub;$l10n$0 = $l10n$3;- continue L1;- }- }- break;- }- case 112: {- $cmp240 = ($p$0>>>0)>(8);- $cond245 = $cmp240 ? $p$0 : 8;- $or246 = $fl$1$and219 | 8;- $fl$3 = $or246;$p$1 = $cond245;$t$1 = 120;- label = 64;- break;- }- case 88: case 120: {- $fl$3 = $fl$1$and219;$p$1 = $p$0;$t$1 = $t$0;- label = 64;- break;- }- case 111: {- $116 = $arg;- $117 = $116;- $118 = HEAP32[$117>>2]|0;- $119 = (($116) + 4)|0;- $120 = $119;- $121 = HEAP32[$120>>2]|0;- $122 = ($118|0)==(0);- $123 = ($121|0)==(0);- $124 = $122 & $123;- if ($124) {- $s$addr$0$lcssa$i$229 = $add$ptr205;- } else {- $126 = $118;$129 = $121;$s$addr$06$i$221 = $add$ptr205;- while(1) {- $125 = $126 & 7;- $127 = $125 | 48;- $128 = $127&255;- $incdec$ptr$i$225 = ((($s$addr$06$i$221)) + -1|0);- HEAP8[$incdec$ptr$i$225>>0] = $128;- $130 = (_bitshift64Lshr(($126|0),($129|0),3)|0);- $131 = tempRet0;- $132 = ($130|0)==(0);- $133 = ($131|0)==(0);- $134 = $132 & $133;- if ($134) {- $s$addr$0$lcssa$i$229 = $incdec$ptr$i$225;- break;- } else {- $126 = $130;$129 = $131;$s$addr$06$i$221 = $incdec$ptr$i$225;- }- }- }- $and263 = $fl$1$and219 & 8;- $tobool264 = ($and263|0)==(0);- if ($tobool264) {- $a$0 = $s$addr$0$lcssa$i$229;$fl$4 = $fl$1$and219;$p$2 = $p$0;$pl$1 = 0;$prefix$1 = 4091;- label = 77;- } else {- $sub$ptr$rhs$cast267 = $s$addr$0$lcssa$i$229;- $sub$ptr$sub268 = (($sub$ptr$lhs$cast317) - ($sub$ptr$rhs$cast267))|0;- $add269 = (($sub$ptr$sub268) + 1)|0;- $cmp270 = ($p$0|0)<($add269|0);- $add269$p$0 = $cmp270 ? $add269 : $p$0;- $a$0 = $s$addr$0$lcssa$i$229;$fl$4 = $fl$1$and219;$p$2 = $add269$p$0;$pl$1 = 0;$prefix$1 = 4091;- label = 77;- }- break;- }- case 105: case 100: {- $135 = $arg;- $136 = $135;- $137 = HEAP32[$136>>2]|0;- $138 = (($135) + 4)|0;- $139 = $138;- $140 = HEAP32[$139>>2]|0;- $141 = ($140|0)<(0);- if ($141) {- $142 = (_i64Subtract(0,0,($137|0),($140|0))|0);- $143 = tempRet0;- $144 = $arg;- $145 = $144;- HEAP32[$145>>2] = $142;- $146 = (($144) + 4)|0;- $147 = $146;- HEAP32[$147>>2] = $143;- $148 = $142;$149 = $143;$pl$0 = 1;$prefix$0 = 4091;- label = 76;- break L75;- }- $and289 = $fl$1$and219 & 2048;- $tobool290 = ($and289|0)==(0);- if ($tobool290) {- $and294 = $fl$1$and219 & 1;- $tobool295 = ($and294|0)==(0);- $$ = $tobool295 ? 4091 : (4093);- $148 = $137;$149 = $140;$pl$0 = $and294;$prefix$0 = $$;- label = 76;- } else {- $148 = $137;$149 = $140;$pl$0 = 1;$prefix$0 = (4092);- label = 76;- }- break;- }- case 117: {- $65 = $arg;- $66 = $65;- $67 = HEAP32[$66>>2]|0;- $68 = (($65) + 4)|0;- $69 = $68;- $70 = HEAP32[$69>>2]|0;- $148 = $67;$149 = $70;$pl$0 = 0;$prefix$0 = 4091;- label = 76;- break;- }- case 99: {- $161 = $arg;- $162 = $161;- $163 = HEAP32[$162>>2]|0;- $164 = (($161) + 4)|0;- $165 = $164;- $166 = HEAP32[$165>>2]|0;- $167 = $163&255;- HEAP8[$add$ptr340>>0] = $167;- $a$2 = $add$ptr340;$fl$6 = $and219;$p$5 = 1;$pl$2 = 0;$prefix$2 = 4091;$z$2 = $add$ptr205;- break;- }- case 109: {- $call344 = (___errno_location()|0);- $168 = HEAP32[$call344>>2]|0;- $call345 = (_strerror($168)|0);- $a$1 = $call345;- label = 82;- break;- }- case 115: {- $169 = HEAP32[$arg>>2]|0;- $tobool349 = ($169|0)!=(0|0);- $cond354 = $tobool349 ? $169 : 4101;- $a$1 = $cond354;- label = 82;- break;- }- case 67: {- $170 = $arg;- $171 = $170;- $172 = HEAP32[$171>>2]|0;- $173 = (($170) + 4)|0;- $174 = $173;- $175 = HEAP32[$174>>2]|0;- HEAP32[$wc>>2] = $172;- HEAP32[$arrayidx370>>2] = 0;- HEAP32[$arg>>2] = $wc;- $p$4365 = -1;- label = 86;- break;- }- case 83: {- $cmp377$314 = ($p$0|0)==(0);- if ($cmp377$314) {- _pad($f,32,$w$1,0,$fl$1$and219);- $i$0$lcssa368 = 0;- label = 98;- } else {- $p$4365 = $p$0;- label = 86;- }- break;- }- case 65: case 71: case 70: case 69: case 97: case 103: case 102: case 101: {- $181 = +HEAPF64[$arg>>3];- HEAP32[$e2$i>>2] = 0;- HEAPF64[tempDoublePtr>>3] = $181;$182 = HEAP32[tempDoublePtr>>2]|0;- $183 = HEAP32[tempDoublePtr+4>>2]|0;- $184 = ($183|0)<(0);- if ($184) {- $sub$i = -$181;- $pl$0$i = 1;$prefix$0$i = 4108;$y$addr$0$i = $sub$i;- } else {- $and$i$238 = $fl$1$and219 & 2048;- $tobool9$i = ($and$i$238|0)==(0);- if ($tobool9$i) {- $and12$i = $fl$1$and219 & 1;- $tobool13$i = ($and12$i|0)==(0);- $$$i = $tobool13$i ? (4109) : (4114);- $pl$0$i = $and12$i;$prefix$0$i = $$$i;$y$addr$0$i = $181;- } else {- $pl$0$i = 1;$prefix$0$i = (4111);$y$addr$0$i = $181;- }- }- HEAPF64[tempDoublePtr>>3] = $y$addr$0$i;$185 = HEAP32[tempDoublePtr>>2]|0;- $186 = HEAP32[tempDoublePtr+4>>2]|0;- $187 = $186 & 2146435072;- $188 = ($187>>>0)<(2146435072);- $189 = (0)<(0);- $190 = ($187|0)==(2146435072);- $191 = $190 & $189;- $192 = $188 | $191;- do {- if ($192) {- $call55$i = (+_frexpl($y$addr$0$i,$e2$i));- $mul$i$240 = $call55$i * 2.0;- $tobool56$i = $mul$i$240 != 0.0;- if ($tobool56$i) {- $195 = HEAP32[$e2$i>>2]|0;- $dec$i = (($195) + -1)|0;- HEAP32[$e2$i>>2] = $dec$i;- }- $or$i$241 = $t$0 | 32;- $cmp59$i = ($or$i$241|0)==(97);- if ($cmp59$i) {- $and62$i = $t$0 & 32;- $tobool63$i = ($and62$i|0)==(0);- $add$ptr65$i = ((($prefix$0$i)) + 9|0);- $prefix$0$add$ptr65$i = $tobool63$i ? $prefix$0$i : $add$ptr65$i;- $add67$i = $pl$0$i | 2;- $196 = ($p$0>>>0)>(11);- $sub74$i = (12 - ($p$0))|0;- $tobool76552$i = ($sub74$i|0)==(0);- $tobool76$i = $196 | $tobool76552$i;- do {- if ($tobool76$i) {- $y$addr$1$i = $mul$i$240;- } else {- $re$1482$i = $sub74$i;$round$0481$i = 8.0;- while(1) {- $dec78$i = (($re$1482$i) + -1)|0;- $mul80$i = $round$0481$i * 16.0;- $tobool79$i = ($dec78$i|0)==(0);- if ($tobool79$i) {- $mul80$i$lcssa = $mul80$i;- break;- } else {- $re$1482$i = $dec78$i;$round$0481$i = $mul80$i;- }- }- $197 = HEAP8[$prefix$0$add$ptr65$i>>0]|0;- $cmp82$i = ($197<<24>>24)==(45);- if ($cmp82$i) {- $sub85$i = -$mul$i$240;- $sub86$i = $sub85$i - $mul80$i$lcssa;- $add87$i = $mul80$i$lcssa + $sub86$i;- $sub88$i = -$add87$i;- $y$addr$1$i = $sub88$i;- break;- } else {- $add90$i = $mul$i$240 + $mul80$i$lcssa;- $sub91$i = $add90$i - $mul80$i$lcssa;- $y$addr$1$i = $sub91$i;- break;- }- }- } while(0);- $198 = HEAP32[$e2$i>>2]|0;- $cmp94$i = ($198|0)<(0);- $sub97$i = (0 - ($198))|0;- $cond100$i = $cmp94$i ? $sub97$i : $198;- $199 = ($cond100$i|0)<(0);- $200 = $199 << 31 >> 31;- $201 = (_fmt_u($cond100$i,$200,$arrayidx$i$236)|0);- $cmp103$i = ($201|0)==($arrayidx$i$236|0);- if ($cmp103$i) {- HEAP8[$incdec$ptr106$i>>0] = 48;- $estr$0$i = $incdec$ptr106$i;- } else {- $estr$0$i = $201;- }- $202 = $198 >> 31;- $203 = $202 & 2;- $204 = (($203) + 43)|0;- $conv111$i = $204&255;- $incdec$ptr112$i = ((($estr$0$i)) + -1|0);- HEAP8[$incdec$ptr112$i>>0] = $conv111$i;- $add113$i = (($t$0) + 15)|0;- $conv114$i = $add113$i&255;- $incdec$ptr115$i = ((($estr$0$i)) + -2|0);- HEAP8[$incdec$ptr115$i>>0] = $conv114$i;- $notrhs$i = ($p$0|0)<(1);- $and134$i = $fl$1$and219 & 8;- $tobool135$i = ($and134$i|0)==(0);- $s$0$i = $buf$i;$y$addr$2$i = $y$addr$1$i;- while(1) {- $conv116$i = (~~(($y$addr$2$i)));- $arrayidx117$i = (4075 + ($conv116$i)|0);- $205 = HEAP8[$arrayidx117$i>>0]|0;- $conv118$393$i = $205&255;- $or120$i = $conv118$393$i | $and62$i;- $conv121$i = $or120$i&255;- $incdec$ptr122$i = ((($s$0$i)) + 1|0);- HEAP8[$s$0$i>>0] = $conv121$i;- $conv123$i = (+($conv116$i|0));- $sub124$i = $y$addr$2$i - $conv123$i;- $mul125$i = $sub124$i * 16.0;- $sub$ptr$lhs$cast$i = $incdec$ptr122$i;- $sub$ptr$sub$i = (($sub$ptr$lhs$cast$i) - ($sub$ptr$rhs$cast$i))|0;- $cmp127$i = ($sub$ptr$sub$i|0)==(1);- do {- if ($cmp127$i) {- $notlhs$i = $mul125$i == 0.0;- $or$cond1$not$i = $notrhs$i & $notlhs$i;- $or$cond$i = $tobool135$i & $or$cond1$not$i;- if ($or$cond$i) {- $s$1$i = $incdec$ptr122$i;- break;- }- $incdec$ptr137$i = ((($s$0$i)) + 2|0);- HEAP8[$incdec$ptr122$i>>0] = 46;- $s$1$i = $incdec$ptr137$i;- } else {- $s$1$i = $incdec$ptr122$i;- }- } while(0);- $tobool139$i = $mul125$i != 0.0;- if ($tobool139$i) {- $s$0$i = $s$1$i;$y$addr$2$i = $mul125$i;- } else {- $s$1$i$lcssa = $s$1$i;- break;- }- }- $tobool140$i = ($p$0|0)!=(0);- $$pre566$i = $s$1$i$lcssa;- $sub146$i = (($sub$ptr$sub145$i) + ($$pre566$i))|0;- $cmp147$i = ($sub146$i|0)<($p$0|0);- $or$cond384 = $tobool140$i & $cmp147$i;- $sub$ptr$rhs$cast152$i = $incdec$ptr115$i;- $add150$i = (($sub$ptr$sub153$i) + ($p$0))|0;- $add154$i = (($add150$i) - ($sub$ptr$rhs$cast152$i))|0;- $sub$ptr$rhs$cast161$i = $incdec$ptr115$i;- $sub$ptr$sub162$i = (($sub$ptr$sub159$i) - ($sub$ptr$rhs$cast161$i))|0;- $add163$i = (($sub$ptr$sub162$i) + ($$pre566$i))|0;- $l$0$i = $or$cond384 ? $add154$i : $add163$i;- $add165$i = (($l$0$i) + ($add67$i))|0;- _pad($f,32,$w$1,$add165$i,$fl$1$and219);- $206 = HEAP32[$f>>2]|0;- $and$i$418$i = $206 & 32;- $tobool$i$419$i = ($and$i$418$i|0)==(0);- if ($tobool$i$419$i) {- (___fwritex($prefix$0$add$ptr65$i,$add67$i,$f)|0);- }- $xor167$i = $fl$1$and219 ^ 65536;- _pad($f,48,$w$1,$add165$i,$xor167$i);- $sub$ptr$sub172$i = (($$pre566$i) - ($sub$ptr$rhs$cast$i))|0;- $207 = HEAP32[$f>>2]|0;- $and$i$424$i = $207 & 32;- $tobool$i$425$i = ($and$i$424$i|0)==(0);- if ($tobool$i$425$i) {- (___fwritex($buf$i,$sub$ptr$sub172$i,$f)|0);- }- $sub$ptr$rhs$cast174$i = $incdec$ptr115$i;- $sub$ptr$sub175$i = (($sub$ptr$lhs$cast160$i) - ($sub$ptr$rhs$cast174$i))|0;- $sum = (($sub$ptr$sub172$i) + ($sub$ptr$sub175$i))|0;- $sub181$i = (($l$0$i) - ($sum))|0;- _pad($f,48,$sub181$i,0,0);- $208 = HEAP32[$f>>2]|0;- $and$i$430$i = $208 & 32;- $tobool$i$431$i = ($and$i$430$i|0)==(0);- if ($tobool$i$431$i) {- (___fwritex($incdec$ptr115$i,$sub$ptr$sub175$i,$f)|0);- }- $xor186$i = $fl$1$and219 ^ 8192;- _pad($f,32,$w$1,$add165$i,$xor186$i);- $cmp188$i = ($add165$i|0)<($w$1|0);- $w$add165$i = $cmp188$i ? $w$1 : $add165$i;- $retval$0$i = $w$add165$i;- break;- }- $cmp196$i = ($p$0|0)<(0);- $$p$i = $cmp196$i ? 6 : $p$0;- if ($tobool56$i) {- $mul202$i = $mul$i$240 * 268435456.0;- $209 = HEAP32[$e2$i>>2]|0;- $sub203$i = (($209) + -28)|0;- HEAP32[$e2$i>>2] = $sub203$i;- $210 = $sub203$i;$y$addr$3$i = $mul202$i;- } else {- $$pre564$i = HEAP32[$e2$i>>2]|0;- $210 = $$pre564$i;$y$addr$3$i = $mul$i$240;- }- $cmp205$i = ($210|0)<(0);- $arraydecay208$add$ptr213$i = $cmp205$i ? $big$i : $add$ptr213$i;- $sub$ptr$rhs$cast345$i = $arraydecay208$add$ptr213$i;- $y$addr$4$i = $y$addr$3$i;$z$0$i = $arraydecay208$add$ptr213$i;- while(1) {- $conv216$i = (~~(($y$addr$4$i))>>>0);- HEAP32[$z$0$i>>2] = $conv216$i;- $incdec$ptr217$i = ((($z$0$i)) + 4|0);- $conv218$i = (+($conv216$i>>>0));- $sub219$i = $y$addr$4$i - $conv218$i;- $mul220$i = $sub219$i * 1.0E+9;- $tobool222$i = $mul220$i != 0.0;- if ($tobool222$i) {- $y$addr$4$i = $mul220$i;$z$0$i = $incdec$ptr217$i;- } else {- $incdec$ptr217$i$lcssa = $incdec$ptr217$i;- break;- }- }- $$pr$i = HEAP32[$e2$i>>2]|0;- $cmp225$547$i = ($$pr$i|0)>(0);- if ($cmp225$547$i) {- $211 = $$pr$i;$a$1549$i = $arraydecay208$add$ptr213$i;$z$1548$i = $incdec$ptr217$i$lcssa;- while(1) {- $cmp228$i = ($211|0)>(29);- $cond233$i = $cmp228$i ? 29 : $211;- $d$0$542$i = ((($z$1548$i)) + -4|0);- $cmp235$543$i = ($d$0$542$i>>>0)<($a$1549$i>>>0);- do {- if ($cmp235$543$i) {- $a$2$ph$i = $a$1549$i;- } else {- $carry$0544$i = 0;$d$0545$i = $d$0$542$i;- while(1) {- $212 = HEAP32[$d$0545$i>>2]|0;- $213 = (_bitshift64Shl(($212|0),0,($cond233$i|0))|0);- $214 = tempRet0;- $215 = (_i64Add(($213|0),($214|0),($carry$0544$i|0),0)|0);- $216 = tempRet0;- $217 = (___uremdi3(($215|0),($216|0),1000000000,0)|0);- $218 = tempRet0;- HEAP32[$d$0545$i>>2] = $217;- $219 = (___udivdi3(($215|0),($216|0),1000000000,0)|0);- $220 = tempRet0;- $d$0$i = ((($d$0545$i)) + -4|0);- $cmp235$i = ($d$0$i>>>0)<($a$1549$i>>>0);- if ($cmp235$i) {- $conv242$i$lcssa = $219;- break;- } else {- $carry$0544$i = $219;$d$0545$i = $d$0$i;- }- }- $tobool244$i = ($conv242$i$lcssa|0)==(0);- if ($tobool244$i) {- $a$2$ph$i = $a$1549$i;- break;- }- $incdec$ptr246$i = ((($a$1549$i)) + -4|0);- HEAP32[$incdec$ptr246$i>>2] = $conv242$i$lcssa;- $a$2$ph$i = $incdec$ptr246$i;- }- } while(0);- $z$2$i = $z$1548$i;- while(1) {- $cmp249$i = ($z$2$i>>>0)>($a$2$ph$i>>>0);- if (!($cmp249$i)) {- $z$2$i$lcssa = $z$2$i;- break;- }- $arrayidx251$i = ((($z$2$i)) + -4|0);- $221 = HEAP32[$arrayidx251$i>>2]|0;- $lnot$i = ($221|0)==(0);- if ($lnot$i) {- $z$2$i = $arrayidx251$i;- } else {- $z$2$i$lcssa = $z$2$i;- break;- }- }- $222 = HEAP32[$e2$i>>2]|0;- $sub256$i = (($222) - ($cond233$i))|0;- HEAP32[$e2$i>>2] = $sub256$i;- $cmp225$i = ($sub256$i|0)>(0);- if ($cmp225$i) {- $211 = $sub256$i;$a$1549$i = $a$2$ph$i;$z$1548$i = $z$2$i$lcssa;- } else {- $$pr477$i = $sub256$i;$a$1$lcssa$i = $a$2$ph$i;$z$1$lcssa$i = $z$2$i$lcssa;- break;- }- }- } else {- $$pr477$i = $$pr$i;$a$1$lcssa$i = $arraydecay208$add$ptr213$i;$z$1$lcssa$i = $incdec$ptr217$i$lcssa;- }- $cmp259$537$i = ($$pr477$i|0)<(0);- if ($cmp259$537$i) {- $add273$i = (($$p$i) + 25)|0;- $div274$i = (($add273$i|0) / 9)&-1;- $add275$i = (($div274$i) + 1)|0;- $cmp299$i = ($or$i$241|0)==(102);- $223 = $$pr477$i;$a$3539$i = $a$1$lcssa$i;$z$3538$i = $z$1$lcssa$i;- while(1) {- $sub264$i = (0 - ($223))|0;- $cmp265$i = ($sub264$i|0)>(9);- $cond271$i = $cmp265$i ? 9 : $sub264$i;- $cmp277$533$i = ($a$3539$i>>>0)<($z$3538$i>>>0);- do {- if ($cmp277$533$i) {- $shl280$i = 1 << $cond271$i;- $sub281$i = (($shl280$i) + -1)|0;- $shr285$i = 1000000000 >>> $cond271$i;- $carry262$0535$i = 0;$d$1534$i = $a$3539$i;- while(1) {- $225 = HEAP32[$d$1534$i>>2]|0;- $and282$i = $225 & $sub281$i;- $shr283$i = $225 >>> $cond271$i;- $add284$i = (($shr283$i) + ($carry262$0535$i))|0;- HEAP32[$d$1534$i>>2] = $add284$i;- $mul286$i = Math_imul($and282$i, $shr285$i)|0;- $incdec$ptr288$i = ((($d$1534$i)) + 4|0);- $cmp277$i = ($incdec$ptr288$i>>>0)<($z$3538$i>>>0);- if ($cmp277$i) {- $carry262$0535$i = $mul286$i;$d$1534$i = $incdec$ptr288$i;- } else {- $mul286$i$lcssa = $mul286$i;- break;- }- }- $226 = HEAP32[$a$3539$i>>2]|0;- $tobool290$i = ($226|0)==(0);- $incdec$ptr292$i = ((($a$3539$i)) + 4|0);- $incdec$ptr292$a$3$i = $tobool290$i ? $incdec$ptr292$i : $a$3539$i;- $tobool294$i = ($mul286$i$lcssa|0)==(0);- if ($tobool294$i) {- $incdec$ptr292$a$3573$i = $incdec$ptr292$a$3$i;$z$4$i = $z$3538$i;- break;- }- $incdec$ptr296$i = ((($z$3538$i)) + 4|0);- HEAP32[$z$3538$i>>2] = $mul286$i$lcssa;- $incdec$ptr292$a$3573$i = $incdec$ptr292$a$3$i;$z$4$i = $incdec$ptr296$i;- } else {- $224 = HEAP32[$a$3539$i>>2]|0;- $tobool290$569$i = ($224|0)==(0);- $incdec$ptr292$570$i = ((($a$3539$i)) + 4|0);- $incdec$ptr292$a$3$571$i = $tobool290$569$i ? $incdec$ptr292$570$i : $a$3539$i;- $incdec$ptr292$a$3573$i = $incdec$ptr292$a$3$571$i;$z$4$i = $z$3538$i;- }- } while(0);- $cond304$i = $cmp299$i ? $arraydecay208$add$ptr213$i : $incdec$ptr292$a$3573$i;- $sub$ptr$lhs$cast305$i = $z$4$i;- $sub$ptr$rhs$cast306$i = $cond304$i;- $sub$ptr$sub307$i = (($sub$ptr$lhs$cast305$i) - ($sub$ptr$rhs$cast306$i))|0;- $sub$ptr$div$i = $sub$ptr$sub307$i >> 2;- $cmp308$i = ($sub$ptr$div$i|0)>($add275$i|0);- $add$ptr311$i = (($cond304$i) + ($add275$i<<2)|0);- $add$ptr311$z$4$i = $cmp308$i ? $add$ptr311$i : $z$4$i;- $227 = HEAP32[$e2$i>>2]|0;- $add313$i = (($227) + ($cond271$i))|0;- HEAP32[$e2$i>>2] = $add313$i;- $cmp259$i = ($add313$i|0)<(0);- if ($cmp259$i) {- $223 = $add313$i;$a$3539$i = $incdec$ptr292$a$3573$i;$z$3538$i = $add$ptr311$z$4$i;- } else {- $a$3$lcssa$i = $incdec$ptr292$a$3573$i;$z$3$lcssa$i = $add$ptr311$z$4$i;- break;- }- }- } else {- $a$3$lcssa$i = $a$1$lcssa$i;$z$3$lcssa$i = $z$1$lcssa$i;- }- $cmp315$i = ($a$3$lcssa$i>>>0)<($z$3$lcssa$i>>>0);- do {- if ($cmp315$i) {- $sub$ptr$rhs$cast319$i = $a$3$lcssa$i;- $sub$ptr$sub320$i = (($sub$ptr$rhs$cast345$i) - ($sub$ptr$rhs$cast319$i))|0;- $sub$ptr$div321$i = $sub$ptr$sub320$i >> 2;- $mul322$i = ($sub$ptr$div321$i*9)|0;- $228 = HEAP32[$a$3$lcssa$i>>2]|0;- $cmp324$529$i = ($228>>>0)<(10);- if ($cmp324$529$i) {- $e$1$i = $mul322$i;- break;- } else {- $e$0531$i = $mul322$i;$i$0530$i = 10;- }- while(1) {- $mul328$i = ($i$0530$i*10)|0;- $inc$i = (($e$0531$i) + 1)|0;- $cmp324$i = ($228>>>0)<($mul328$i>>>0);- if ($cmp324$i) {- $e$1$i = $inc$i;- break;- } else {- $e$0531$i = $inc$i;$i$0530$i = $mul328$i;- }- }- } else {- $e$1$i = 0;- }- } while(0);- $cmp333$i = ($or$i$241|0)!=(102);- $mul335$i = $cmp333$i ? $e$1$i : 0;- $sub336$i = (($$p$i) - ($mul335$i))|0;- $cmp338$i = ($or$i$241|0)==(103);- $tobool341$i = ($$p$i|0)!=(0);- $229 = $tobool341$i & $cmp338$i;- $land$ext$neg$i = $229 << 31 >> 31;- $sub343$i = (($sub336$i) + ($land$ext$neg$i))|0;- $sub$ptr$lhs$cast344$i = $z$3$lcssa$i;- $sub$ptr$sub346$i = (($sub$ptr$lhs$cast344$i) - ($sub$ptr$rhs$cast345$i))|0;- $sub$ptr$div347$i = $sub$ptr$sub346$i >> 2;- $230 = ($sub$ptr$div347$i*9)|0;- $mul349$i = (($230) + -9)|0;- $cmp350$i = ($sub343$i|0)<($mul349$i|0);- if ($cmp350$i) {- $add$ptr354$i = ((($arraydecay208$add$ptr213$i)) + 4|0);- $add355$i = (($sub343$i) + 9216)|0;- $div356$i = (($add355$i|0) / 9)&-1;- $sub357$i = (($div356$i) + -1024)|0;- $add$ptr358$i = (($add$ptr354$i) + ($sub357$i<<2)|0);- $rem360$i = (($add355$i|0) % 9)&-1;- $j$0$524$i = (($rem360$i) + 1)|0;- $cmp363$525$i = ($j$0$524$i|0)<(9);- if ($cmp363$525$i) {- $i$1526$i = 10;$j$0527$i = $j$0$524$i;- while(1) {- $mul367$i = ($i$1526$i*10)|0;- $j$0$i = (($j$0527$i) + 1)|0;- $exitcond$i = ($j$0$i|0)==(9);- if ($exitcond$i) {- $i$1$lcssa$i = $mul367$i;- break;- } else {- $i$1526$i = $mul367$i;$j$0527$i = $j$0$i;- }- }- } else {- $i$1$lcssa$i = 10;- }- $231 = HEAP32[$add$ptr358$i>>2]|0;- $rem370$i = (($231>>>0) % ($i$1$lcssa$i>>>0))&-1;- $tobool371$i = ($rem370$i|0)==(0);- $add$ptr373$i = ((($add$ptr358$i)) + 4|0);- $cmp374$i = ($add$ptr373$i|0)==($z$3$lcssa$i|0);- $or$cond395$i = $cmp374$i & $tobool371$i;- do {- if ($or$cond395$i) {- $a$8$i = $a$3$lcssa$i;$d$4$i = $add$ptr358$i;$e$4$i = $e$1$i;- } else {- $div378$i = (($231>>>0) / ($i$1$lcssa$i>>>0))&-1;- $and379$i = $div378$i & 1;- $tobool380$i = ($and379$i|0)==(0);- $$396$i = $tobool380$i ? 9007199254740992.0 : 9007199254740994.0;- $div384$i = (($i$1$lcssa$i|0) / 2)&-1;- $cmp385$i = ($rem370$i>>>0)<($div384$i>>>0);- if ($cmp385$i) {- $small$0$i = 0.5;- } else {- $cmp390$i = ($rem370$i|0)==($div384$i|0);- $or$cond397$i = $cmp374$i & $cmp390$i;- $$404$i = $or$cond397$i ? 1.0 : 1.5;- $small$0$i = $$404$i;- }- $tobool400$i = ($pl$0$i|0)==(0);- do {- if ($tobool400$i) {- $round377$1$i = $$396$i;$small$1$i = $small$0$i;- } else {- $232 = HEAP8[$prefix$0$i>>0]|0;- $cmp403$i = ($232<<24>>24)==(45);- if (!($cmp403$i)) {- $round377$1$i = $$396$i;$small$1$i = $small$0$i;- break;- }- $mul406$i = -$$396$i;- $mul407$i = -$small$0$i;- $round377$1$i = $mul406$i;$small$1$i = $mul407$i;- }- } while(0);- $sub409$i = (($231) - ($rem370$i))|0;- HEAP32[$add$ptr358$i>>2] = $sub409$i;- $add410$i = $round377$1$i + $small$1$i;- $cmp411$i = $add410$i != $round377$1$i;- if (!($cmp411$i)) {- $a$8$i = $a$3$lcssa$i;$d$4$i = $add$ptr358$i;$e$4$i = $e$1$i;- break;- }- $add414$i = (($sub409$i) + ($i$1$lcssa$i))|0;- HEAP32[$add$ptr358$i>>2] = $add414$i;- $cmp416$519$i = ($add414$i>>>0)>(999999999);- if ($cmp416$519$i) {- $a$5521$i = $a$3$lcssa$i;$d$2520$i = $add$ptr358$i;- while(1) {- $incdec$ptr419$i = ((($d$2520$i)) + -4|0);- HEAP32[$d$2520$i>>2] = 0;- $cmp420$i = ($incdec$ptr419$i>>>0)<($a$5521$i>>>0);- if ($cmp420$i) {- $incdec$ptr423$i = ((($a$5521$i)) + -4|0);- HEAP32[$incdec$ptr423$i>>2] = 0;- $a$6$i = $incdec$ptr423$i;- } else {- $a$6$i = $a$5521$i;- }- $233 = HEAP32[$incdec$ptr419$i>>2]|0;- $inc425$i = (($233) + 1)|0;- HEAP32[$incdec$ptr419$i>>2] = $inc425$i;- $cmp416$i = ($inc425$i>>>0)>(999999999);- if ($cmp416$i) {- $a$5521$i = $a$6$i;$d$2520$i = $incdec$ptr419$i;- } else {- $a$5$lcssa$i = $a$6$i;$d$2$lcssa$i = $incdec$ptr419$i;- break;- }- }- } else {- $a$5$lcssa$i = $a$3$lcssa$i;$d$2$lcssa$i = $add$ptr358$i;- }- $sub$ptr$rhs$cast428$i = $a$5$lcssa$i;- $sub$ptr$sub429$i = (($sub$ptr$rhs$cast345$i) - ($sub$ptr$rhs$cast428$i))|0;- $sub$ptr$div430$i = $sub$ptr$sub429$i >> 2;- $mul431$i = ($sub$ptr$div430$i*9)|0;- $234 = HEAP32[$a$5$lcssa$i>>2]|0;- $cmp433$515$i = ($234>>>0)<(10);- if ($cmp433$515$i) {- $a$8$i = $a$5$lcssa$i;$d$4$i = $d$2$lcssa$i;$e$4$i = $mul431$i;- break;- } else {- $e$2517$i = $mul431$i;$i$2516$i = 10;- }- while(1) {- $mul437$i = ($i$2516$i*10)|0;- $inc438$i = (($e$2517$i) + 1)|0;- $cmp433$i = ($234>>>0)<($mul437$i>>>0);- if ($cmp433$i) {- $a$8$i = $a$5$lcssa$i;$d$4$i = $d$2$lcssa$i;$e$4$i = $inc438$i;- break;- } else {- $e$2517$i = $inc438$i;$i$2516$i = $mul437$i;- }- }- }- } while(0);- $add$ptr442$i = ((($d$4$i)) + 4|0);- $cmp443$i = ($z$3$lcssa$i>>>0)>($add$ptr442$i>>>0);- $add$ptr442$z$3$i = $cmp443$i ? $add$ptr442$i : $z$3$lcssa$i;- $a$9$ph$i = $a$8$i;$e$5$ph$i = $e$4$i;$z$7$ph$i = $add$ptr442$z$3$i;- } else {- $a$9$ph$i = $a$3$lcssa$i;$e$5$ph$i = $e$1$i;$z$7$ph$i = $z$3$lcssa$i;- }- $sub626$le$i = (0 - ($e$5$ph$i))|0;- $z$7$i = $z$7$ph$i;- while(1) {- $cmp450$i = ($z$7$i>>>0)>($a$9$ph$i>>>0);- if (!($cmp450$i)) {- $cmp450$lcssa$i = 0;$z$7$i$lcssa = $z$7$i;- break;- }- $arrayidx453$i = ((($z$7$i)) + -4|0);- $235 = HEAP32[$arrayidx453$i>>2]|0;- $lnot455$i = ($235|0)==(0);- if ($lnot455$i) {- $z$7$i = $arrayidx453$i;- } else {- $cmp450$lcssa$i = 1;$z$7$i$lcssa = $z$7$i;- break;- }- }- do {- if ($cmp338$i) {- $236 = $tobool341$i&1;- $inc468$i = $236 ^ 1;- $$p$inc468$i = (($inc468$i) + ($$p$i))|0;- $cmp470$i = ($$p$inc468$i|0)>($e$5$ph$i|0);- $cmp473$i = ($e$5$ph$i|0)>(-5);- $or$cond2$i = $cmp470$i & $cmp473$i;- if ($or$cond2$i) {- $dec476$i = (($t$0) + -1)|0;- $add477$neg$i = (($$p$inc468$i) + -1)|0;- $sub478$i = (($add477$neg$i) - ($e$5$ph$i))|0;- $p$addr$2$i = $sub478$i;$t$addr$0$i = $dec476$i;- } else {- $sub480$i = (($t$0) + -2)|0;- $dec481$i = (($$p$inc468$i) + -1)|0;- $p$addr$2$i = $dec481$i;$t$addr$0$i = $sub480$i;- }- $and483$i = $fl$1$and219 & 8;- $tobool484$i = ($and483$i|0)==(0);- if (!($tobool484$i)) {- $and610$pre$phi$iZ2D = $and483$i;$p$addr$3$i = $p$addr$2$i;$t$addr$1$i = $t$addr$0$i;- break;- }- do {- if ($cmp450$lcssa$i) {- $arrayidx489$i = ((($z$7$i$lcssa)) + -4|0);- $237 = HEAP32[$arrayidx489$i>>2]|0;- $tobool490$i = ($237|0)==(0);- if ($tobool490$i) {- $j$2$i = 9;- break;- }- $rem494$510$i = (($237>>>0) % 10)&-1;- $cmp495$511$i = ($rem494$510$i|0)==(0);- if ($cmp495$511$i) {- $i$3512$i = 10;$j$1513$i = 0;- } else {- $j$2$i = 0;- break;- }- while(1) {- $mul499$i = ($i$3512$i*10)|0;- $inc500$i = (($j$1513$i) + 1)|0;- $rem494$i = (($237>>>0) % ($mul499$i>>>0))&-1;- $cmp495$i = ($rem494$i|0)==(0);- if ($cmp495$i) {- $i$3512$i = $mul499$i;$j$1513$i = $inc500$i;- } else {- $j$2$i = $inc500$i;- break;- }- }- } else {- $j$2$i = 9;- }- } while(0);- $or504$i = $t$addr$0$i | 32;- $cmp505$i = ($or504$i|0)==(102);- $sub$ptr$lhs$cast508$i = $z$7$i$lcssa;- $sub$ptr$sub510$i = (($sub$ptr$lhs$cast508$i) - ($sub$ptr$rhs$cast345$i))|0;- $sub$ptr$div511$i = $sub$ptr$sub510$i >> 2;- $238 = ($sub$ptr$div511$i*9)|0;- $mul513$i = (($238) + -9)|0;- if ($cmp505$i) {- $sub514$i = (($mul513$i) - ($j$2$i))|0;- $cmp515$i = ($sub514$i|0)<(0);- $$sub514$i = $cmp515$i ? 0 : $sub514$i;- $cmp528$i = ($p$addr$2$i|0)<($$sub514$i|0);- $p$addr$2$$sub514398$i = $cmp528$i ? $p$addr$2$i : $$sub514$i;- $and610$pre$phi$iZ2D = 0;$p$addr$3$i = $p$addr$2$$sub514398$i;$t$addr$1$i = $t$addr$0$i;- break;- } else {- $add561$i = (($mul513$i) + ($e$5$ph$i))|0;- $sub562$i = (($add561$i) - ($j$2$i))|0;- $cmp563$i = ($sub562$i|0)<(0);- $$sub562$i = $cmp563$i ? 0 : $sub562$i;- $cmp577$i = ($p$addr$2$i|0)<($$sub562$i|0);- $p$addr$2$$sub562399$i = $cmp577$i ? $p$addr$2$i : $$sub562$i;- $and610$pre$phi$iZ2D = 0;$p$addr$3$i = $p$addr$2$$sub562399$i;$t$addr$1$i = $t$addr$0$i;- break;- }- } else {- $$pre567$i = $fl$1$and219 & 8;- $and610$pre$phi$iZ2D = $$pre567$i;$p$addr$3$i = $$p$i;$t$addr$1$i = $t$0;- }- } while(0);- $239 = $p$addr$3$i | $and610$pre$phi$iZ2D;- $240 = ($239|0)!=(0);- $lor$ext$i = $240&1;- $or613$i = $t$addr$1$i | 32;- $cmp614$i = ($or613$i|0)==(102);- if ($cmp614$i) {- $cmp617$i = ($e$5$ph$i|0)>(0);- $add620$i = $cmp617$i ? $e$5$ph$i : 0;- $estr$2$i = 0;$sub$ptr$sub650$pn$i = $add620$i;- } else {- $cmp623$i = ($e$5$ph$i|0)<(0);- $cond629$i = $cmp623$i ? $sub626$le$i : $e$5$ph$i;- $241 = ($cond629$i|0)<(0);- $242 = $241 << 31 >> 31;- $243 = (_fmt_u($cond629$i,$242,$arrayidx$i$236)|0);- $sub$ptr$rhs$cast634$504$i = $243;- $sub$ptr$sub635$505$i = (($sub$ptr$lhs$cast160$i) - ($sub$ptr$rhs$cast634$504$i))|0;- $cmp636$506$i = ($sub$ptr$sub635$505$i|0)<(2);- if ($cmp636$506$i) {- $estr$1507$i = $243;- while(1) {- $incdec$ptr639$i = ((($estr$1507$i)) + -1|0);- HEAP8[$incdec$ptr639$i>>0] = 48;- $sub$ptr$rhs$cast634$i = $incdec$ptr639$i;- $sub$ptr$sub635$i = (($sub$ptr$lhs$cast160$i) - ($sub$ptr$rhs$cast634$i))|0;- $cmp636$i = ($sub$ptr$sub635$i|0)<(2);- if ($cmp636$i) {- $estr$1507$i = $incdec$ptr639$i;- } else {- $estr$1$lcssa$i = $incdec$ptr639$i;- break;- }- }- } else {- $estr$1$lcssa$i = $243;- }- $244 = $e$5$ph$i >> 31;- $245 = $244 & 2;- $246 = (($245) + 43)|0;- $conv644$i = $246&255;- $incdec$ptr645$i = ((($estr$1$lcssa$i)) + -1|0);- HEAP8[$incdec$ptr645$i>>0] = $conv644$i;- $conv646$i = $t$addr$1$i&255;- $incdec$ptr647$i = ((($estr$1$lcssa$i)) + -2|0);- HEAP8[$incdec$ptr647$i>>0] = $conv646$i;- $sub$ptr$rhs$cast649$i = $incdec$ptr647$i;- $sub$ptr$sub650$i = (($sub$ptr$lhs$cast160$i) - ($sub$ptr$rhs$cast649$i))|0;- $estr$2$i = $incdec$ptr647$i;$sub$ptr$sub650$pn$i = $sub$ptr$sub650$i;- }- $add608$i = (($pl$0$i) + 1)|0;- $add612$i = (($add608$i) + ($p$addr$3$i))|0;- $l$1$i = (($add612$i) + ($lor$ext$i))|0;- $add653$i = (($l$1$i) + ($sub$ptr$sub650$pn$i))|0;- _pad($f,32,$w$1,$add653$i,$fl$1$and219);- $247 = HEAP32[$f>>2]|0;- $and$i$436$i = $247 & 32;- $tobool$i$437$i = ($and$i$436$i|0)==(0);- if ($tobool$i$437$i) {- (___fwritex($prefix$0$i,$pl$0$i,$f)|0);- }- $xor655$i = $fl$1$and219 ^ 65536;- _pad($f,48,$w$1,$add653$i,$xor655$i);- do {- if ($cmp614$i) {- $cmp660$i = ($a$9$ph$i>>>0)>($arraydecay208$add$ptr213$i>>>0);- $r$0$a$9$i = $cmp660$i ? $arraydecay208$add$ptr213$i : $a$9$ph$i;- $d$5494$i = $r$0$a$9$i;- while(1) {- $248 = HEAP32[$d$5494$i>>2]|0;- $249 = (_fmt_u($248,0,$add$ptr671$i)|0);- $cmp673$i = ($d$5494$i|0)==($r$0$a$9$i|0);- do {- if ($cmp673$i) {- $cmp686$i = ($249|0)==($add$ptr671$i|0);- if (!($cmp686$i)) {- $s668$1$i = $249;- break;- }- HEAP8[$incdec$ptr689$i>>0] = 48;- $s668$1$i = $incdec$ptr689$i;- } else {- $cmp678$491$i = ($249>>>0)>($buf$i>>>0);- if ($cmp678$491$i) {- $s668$0492$i = $249;- } else {- $s668$1$i = $249;- break;- }- while(1) {- $incdec$ptr681$i = ((($s668$0492$i)) + -1|0);- HEAP8[$incdec$ptr681$i>>0] = 48;- $cmp678$i = ($incdec$ptr681$i>>>0)>($buf$i>>>0);- if ($cmp678$i) {- $s668$0492$i = $incdec$ptr681$i;- } else {- $s668$1$i = $incdec$ptr681$i;- break;- }- }- }- } while(0);- $250 = HEAP32[$f>>2]|0;- $and$i$442$i = $250 & 32;- $tobool$i$443$i = ($and$i$442$i|0)==(0);- if ($tobool$i$443$i) {- $sub$ptr$rhs$cast695$i = $s668$1$i;- $sub$ptr$sub696$i = (($sub$ptr$lhs$cast694$i) - ($sub$ptr$rhs$cast695$i))|0;- (___fwritex($s668$1$i,$sub$ptr$sub696$i,$f)|0);- }- $incdec$ptr698$i = ((($d$5494$i)) + 4|0);- $cmp665$i = ($incdec$ptr698$i>>>0)>($arraydecay208$add$ptr213$i>>>0);- if ($cmp665$i) {- $incdec$ptr698$i$lcssa = $incdec$ptr698$i;- break;- } else {- $d$5494$i = $incdec$ptr698$i;- }- }- $251 = ($239|0)==(0);- do {- if (!($251)) {- $252 = HEAP32[$f>>2]|0;- $and$i$448$i = $252 & 32;- $tobool$i$449$i = ($and$i$448$i|0)==(0);- if (!($tobool$i$449$i)) {- break;- }- (___fwritex(4143,1,$f)|0);- }- } while(0);- $cmp707$486$i = ($incdec$ptr698$i$lcssa>>>0)<($z$7$i$lcssa>>>0);- $cmp710$487$i = ($p$addr$3$i|0)>(0);- $253 = $cmp710$487$i & $cmp707$486$i;- if ($253) {- $d$6488$i = $incdec$ptr698$i$lcssa;$p$addr$4489$i = $p$addr$3$i;- while(1) {- $254 = HEAP32[$d$6488$i>>2]|0;- $255 = (_fmt_u($254,0,$add$ptr671$i)|0);- $cmp722$483$i = ($255>>>0)>($buf$i>>>0);- if ($cmp722$483$i) {- $s715$0484$i = $255;- while(1) {- $incdec$ptr725$i = ((($s715$0484$i)) + -1|0);- HEAP8[$incdec$ptr725$i>>0] = 48;- $cmp722$i = ($incdec$ptr725$i>>>0)>($buf$i>>>0);- if ($cmp722$i) {- $s715$0484$i = $incdec$ptr725$i;- } else {- $s715$0$lcssa$i = $incdec$ptr725$i;- break;- }- }- } else {- $s715$0$lcssa$i = $255;- }- $256 = HEAP32[$f>>2]|0;- $and$i$454$i = $256 & 32;- $tobool$i$455$i = ($and$i$454$i|0)==(0);- if ($tobool$i$455$i) {- $cmp727$i = ($p$addr$4489$i|0)>(9);- $cond732$i = $cmp727$i ? 9 : $p$addr$4489$i;- (___fwritex($s715$0$lcssa$i,$cond732$i,$f)|0);- }- $incdec$ptr734$i = ((($d$6488$i)) + 4|0);- $sub735$i = (($p$addr$4489$i) + -9)|0;- $cmp707$i = ($incdec$ptr734$i>>>0)<($z$7$i$lcssa>>>0);- $cmp710$i = ($p$addr$4489$i|0)>(9);- $257 = $cmp710$i & $cmp707$i;- if ($257) {- $d$6488$i = $incdec$ptr734$i;$p$addr$4489$i = $sub735$i;- } else {- $p$addr$4$lcssa$i = $sub735$i;- break;- }- }- } else {- $p$addr$4$lcssa$i = $p$addr$3$i;- }- $add737$i = (($p$addr$4$lcssa$i) + 9)|0;- _pad($f,48,$add737$i,9,0);- } else {- $add$ptr742$i = ((($a$9$ph$i)) + 4|0);- $z$7$add$ptr742$i = $cmp450$lcssa$i ? $z$7$i$lcssa : $add$ptr742$i;- $cmp748$499$i = ($p$addr$3$i|0)>(-1);- if ($cmp748$499$i) {- $tobool781$i = ($and610$pre$phi$iZ2D|0)==(0);- $d$7500$i = $a$9$ph$i;$p$addr$5501$i = $p$addr$3$i;- while(1) {- $258 = HEAP32[$d$7500$i>>2]|0;- $259 = (_fmt_u($258,0,$add$ptr671$i)|0);- $cmp760$i = ($259|0)==($add$ptr671$i|0);- if ($cmp760$i) {- HEAP8[$incdec$ptr689$i>>0] = 48;- $s753$0$i = $incdec$ptr689$i;- } else {- $s753$0$i = $259;- }- $cmp765$i = ($d$7500$i|0)==($a$9$ph$i|0);- do {- if ($cmp765$i) {- $incdec$ptr776$i = ((($s753$0$i)) + 1|0);- $260 = HEAP32[$f>>2]|0;- $and$i$460$i = $260 & 32;- $tobool$i$461$i = ($and$i$460$i|0)==(0);- if ($tobool$i$461$i) {- (___fwritex($s753$0$i,1,$f)|0);- }- $cmp777$i = ($p$addr$5501$i|0)<(1);- $or$cond401$i = $tobool781$i & $cmp777$i;- if ($or$cond401$i) {- $s753$2$i = $incdec$ptr776$i;- break;- }- $261 = HEAP32[$f>>2]|0;- $and$i$466$i = $261 & 32;- $tobool$i$467$i = ($and$i$466$i|0)==(0);- if (!($tobool$i$467$i)) {- $s753$2$i = $incdec$ptr776$i;- break;- }- (___fwritex(4143,1,$f)|0);- $s753$2$i = $incdec$ptr776$i;- } else {- $cmp770$495$i = ($s753$0$i>>>0)>($buf$i>>>0);- if ($cmp770$495$i) {- $s753$1496$i = $s753$0$i;- } else {- $s753$2$i = $s753$0$i;- break;- }- while(1) {- $incdec$ptr773$i = ((($s753$1496$i)) + -1|0);- HEAP8[$incdec$ptr773$i>>0] = 48;- $cmp770$i = ($incdec$ptr773$i>>>0)>($buf$i>>>0);- if ($cmp770$i) {- $s753$1496$i = $incdec$ptr773$i;- } else {- $s753$2$i = $incdec$ptr773$i;- break;- }- }- }- } while(0);- $sub$ptr$rhs$cast788$i = $s753$2$i;- $sub$ptr$sub789$i = (($sub$ptr$lhs$cast694$i) - ($sub$ptr$rhs$cast788$i))|0;- $262 = HEAP32[$f>>2]|0;- $and$i$472$i = $262 & 32;- $tobool$i$473$i = ($and$i$472$i|0)==(0);- if ($tobool$i$473$i) {- $cmp790$i = ($p$addr$5501$i|0)>($sub$ptr$sub789$i|0);- $cond800$i = $cmp790$i ? $sub$ptr$sub789$i : $p$addr$5501$i;- (___fwritex($s753$2$i,$cond800$i,$f)|0);- }- $sub806$i = (($p$addr$5501$i) - ($sub$ptr$sub789$i))|0;- $incdec$ptr808$i = ((($d$7500$i)) + 4|0);- $cmp745$i = ($incdec$ptr808$i>>>0)<($z$7$add$ptr742$i>>>0);- $cmp748$i = ($sub806$i|0)>(-1);- $263 = $cmp745$i & $cmp748$i;- if ($263) {- $d$7500$i = $incdec$ptr808$i;$p$addr$5501$i = $sub806$i;- } else {- $p$addr$5$lcssa$i = $sub806$i;- break;- }- }- } else {- $p$addr$5$lcssa$i = $p$addr$3$i;- }- $add810$i = (($p$addr$5$lcssa$i) + 18)|0;- _pad($f,48,$add810$i,18,0);- $264 = HEAP32[$f>>2]|0;- $and$i$i = $264 & 32;- $tobool$i$i = ($and$i$i|0)==(0);- if (!($tobool$i$i)) {- break;- }- $sub$ptr$rhs$cast812$i = $estr$2$i;- $sub$ptr$sub813$i = (($sub$ptr$lhs$cast160$i) - ($sub$ptr$rhs$cast812$i))|0;- (___fwritex($estr$2$i,$sub$ptr$sub813$i,$f)|0);- }- } while(0);- $xor816$i = $fl$1$and219 ^ 8192;- _pad($f,32,$w$1,$add653$i,$xor816$i);- $cmp818$i = ($add653$i|0)<($w$1|0);- $w$add653$i = $cmp818$i ? $w$1 : $add653$i;- $retval$0$i = $w$add653$i;- } else {- $and36$i = $t$0 & 32;- $tobool37$i = ($and36$i|0)!=(0);- $cond$i = $tobool37$i ? 4127 : 4131;- $cmp38$i = ($y$addr$0$i != $y$addr$0$i) | (0.0 != 0.0);- $cond43$i = $tobool37$i ? 4135 : 4139;- $pl$1$i = $cmp38$i ? 0 : $pl$0$i;- $s35$0$i = $cmp38$i ? $cond43$i : $cond$i;- $add$i$239 = (($pl$1$i) + 3)|0;- _pad($f,32,$w$1,$add$i$239,$and219);- $193 = HEAP32[$f>>2]|0;- $and$i$406$i = $193 & 32;- $tobool$i$407$i = ($and$i$406$i|0)==(0);- if ($tobool$i$407$i) {- (___fwritex($prefix$0$i,$pl$1$i,$f)|0);- $$pre$i = HEAP32[$f>>2]|0;- $194 = $$pre$i;- } else {- $194 = $193;- }- $and$i$412$i = $194 & 32;- $tobool$i$413$i = ($and$i$412$i|0)==(0);- if ($tobool$i$413$i) {- (___fwritex($s35$0$i,3,$f)|0);- }- $xor$i = $fl$1$and219 ^ 8192;- _pad($f,32,$w$1,$add$i$239,$xor$i);- $cmp48$i = ($add$i$239|0)<($w$1|0);- $cond53$i = $cmp48$i ? $w$1 : $add$i$239;- $retval$0$i = $cond53$i;- }- } while(0);- $cnt$0 = $cnt$1;$incdec$ptr169275 = $incdec$ptr169$lcssa;$l$0 = $retval$0$i;$l10n$0 = $l10n$3;- continue L1;- break;- }- default: {- $a$2 = $incdec$ptr169275;$fl$6 = $fl$1$and219;$p$5 = $p$0;$pl$2 = 0;$prefix$2 = 4091;$z$2 = $add$ptr205;- }- }- } while(0);- L308: do {- if ((label|0) == 64) {- label = 0;- $90 = $arg;- $91 = $90;- $92 = HEAP32[$91>>2]|0;- $93 = (($90) + 4)|0;- $94 = $93;- $95 = HEAP32[$94>>2]|0;- $and249 = $t$1 & 32;- $96 = ($92|0)==(0);- $97 = ($95|0)==(0);- $98 = $96 & $97;- if ($98) {- $a$0 = $add$ptr205;$fl$4 = $fl$3;$p$2 = $p$1;$pl$1 = 0;$prefix$1 = 4091;- label = 77;- } else {- $101 = $95;$99 = $92;$s$addr$06$i = $add$ptr205;- while(1) {- $idxprom$i = $99 & 15;- $arrayidx$i = (4075 + ($idxprom$i)|0);- $100 = HEAP8[$arrayidx$i>>0]|0;- $conv$4$i$211 = $100&255;- $or$i = $conv$4$i$211 | $and249;- $conv1$i = $or$i&255;- $incdec$ptr$i$212 = ((($s$addr$06$i)) + -1|0);- HEAP8[$incdec$ptr$i$212>>0] = $conv1$i;- $102 = (_bitshift64Lshr(($99|0),($101|0),4)|0);- $103 = tempRet0;- $104 = ($102|0)==(0);- $105 = ($103|0)==(0);- $106 = $104 & $105;- if ($106) {- $incdec$ptr$i$212$lcssa = $incdec$ptr$i$212;- break;- } else {- $101 = $103;$99 = $102;$s$addr$06$i = $incdec$ptr$i$212;- }- }- $107 = $arg;- $108 = $107;- $109 = HEAP32[$108>>2]|0;- $110 = (($107) + 4)|0;- $111 = $110;- $112 = HEAP32[$111>>2]|0;- $113 = ($109|0)==(0);- $114 = ($112|0)==(0);- $115 = $113 & $114;- $and254 = $fl$3 & 8;- $tobool255 = ($and254|0)==(0);- $or$cond193 = $tobool255 | $115;- if ($or$cond193) {- $a$0 = $incdec$ptr$i$212$lcssa;$fl$4 = $fl$3;$p$2 = $p$1;$pl$1 = 0;$prefix$1 = 4091;- label = 77;- } else {- $shr = $t$1 >> 4;- $add$ptr257 = (4091 + ($shr)|0);- $a$0 = $incdec$ptr$i$212$lcssa;$fl$4 = $fl$3;$p$2 = $p$1;$pl$1 = 2;$prefix$1 = $add$ptr257;- label = 77;- }- }- }- else if ((label|0) == 76) {- label = 0;- $150 = (_fmt_u($148,$149,$add$ptr205)|0);- $a$0 = $150;$fl$4 = $fl$1$and219;$p$2 = $p$0;$pl$1 = $pl$0;$prefix$1 = $prefix$0;- label = 77;- }- else if ((label|0) == 82) {- label = 0;- $call356 = (_memchr($a$1,0,$p$0)|0);- $tobool357 = ($call356|0)==(0|0);- $sub$ptr$lhs$cast361 = $call356;- $sub$ptr$rhs$cast362 = $a$1;- $sub$ptr$sub363 = (($sub$ptr$lhs$cast361) - ($sub$ptr$rhs$cast362))|0;- $add$ptr359 = (($a$1) + ($p$0)|0);- $z$1 = $tobool357 ? $add$ptr359 : $call356;- $p$3 = $tobool357 ? $p$0 : $sub$ptr$sub363;- $a$2 = $a$1;$fl$6 = $and219;$p$5 = $p$3;$pl$2 = 0;$prefix$2 = 4091;$z$2 = $z$1;- }- else if ((label|0) == 86) {- label = 0;- $176 = HEAP32[$arg>>2]|0;- $i$0316 = 0;$l$1315 = 0;$ws$0317 = $176;- while(1) {- $177 = HEAP32[$ws$0317>>2]|0;- $tobool380 = ($177|0)==(0);- if ($tobool380) {- $i$0$lcssa = $i$0316;$l$2 = $l$1315;- break;- }- $call384 = (_wctomb($mb,$177)|0);- $cmp385 = ($call384|0)<(0);- $sub389 = (($p$4365) - ($i$0316))|0;- $cmp390 = ($call384>>>0)>($sub389>>>0);- $or$cond195 = $cmp385 | $cmp390;- if ($or$cond195) {- $i$0$lcssa = $i$0316;$l$2 = $call384;- break;- }- $incdec$ptr383 = ((($ws$0317)) + 4|0);- $add395 = (($call384) + ($i$0316))|0;- $cmp377 = ($p$4365>>>0)>($add395>>>0);- if ($cmp377) {- $i$0316 = $add395;$l$1315 = $call384;$ws$0317 = $incdec$ptr383;- } else {- $i$0$lcssa = $add395;$l$2 = $call384;- break;- }- }- $cmp397 = ($l$2|0)<(0);- if ($cmp397) {- $retval$0 = -1;- break L1;- }- _pad($f,32,$w$1,$i$0$lcssa,$fl$1$and219);- $cmp404$324 = ($i$0$lcssa|0)==(0);- if ($cmp404$324) {- $i$0$lcssa368 = 0;- label = 98;- } else {- $178 = HEAP32[$arg>>2]|0;- $i$1325 = 0;$ws$1326 = $178;- while(1) {- $179 = HEAP32[$ws$1326>>2]|0;- $tobool407 = ($179|0)==(0);- if ($tobool407) {- $i$0$lcssa368 = $i$0$lcssa;- label = 98;- break L308;- }- $incdec$ptr410 = ((($ws$1326)) + 4|0);- $call411 = (_wctomb($mb,$179)|0);- $add412 = (($call411) + ($i$1325))|0;- $cmp413 = ($add412|0)>($i$0$lcssa|0);- if ($cmp413) {- $i$0$lcssa368 = $i$0$lcssa;- label = 98;- break L308;- }- $180 = HEAP32[$f>>2]|0;- $and$i$231 = $180 & 32;- $tobool$i$232 = ($and$i$231|0)==(0);- if ($tobool$i$232) {- (___fwritex($mb,$call411,$f)|0);- }- $cmp404 = ($add412>>>0)<($i$0$lcssa>>>0);- if ($cmp404) {- $i$1325 = $add412;$ws$1326 = $incdec$ptr410;- } else {- $i$0$lcssa368 = $i$0$lcssa;- label = 98;- break;- }- }- }- }- } while(0);- if ((label|0) == 98) {- label = 0;- $xor = $fl$1$and219 ^ 8192;- _pad($f,32,$w$1,$i$0$lcssa368,$xor);- $cmp421 = ($w$1|0)>($i$0$lcssa368|0);- $cond426 = $cmp421 ? $w$1 : $i$0$lcssa368;- $cnt$0 = $cnt$1;$incdec$ptr169275 = $incdec$ptr169$lcssa;$l$0 = $cond426;$l10n$0 = $l10n$3;- continue;- }- if ((label|0) == 77) {- label = 0;- $cmp306 = ($p$2|0)>(-1);- $and309 = $fl$4 & -65537;- $and309$fl$4 = $cmp306 ? $and309 : $fl$4;- $151 = $arg;- $152 = $151;- $153 = HEAP32[$152>>2]|0;- $154 = (($151) + 4)|0;- $155 = $154;- $156 = HEAP32[$155>>2]|0;- $157 = ($153|0)!=(0);- $158 = ($156|0)!=(0);- $159 = $157 | $158;- $tobool314 = ($p$2|0)!=(0);- $or$cond = $tobool314 | $159;- if ($or$cond) {- $sub$ptr$rhs$cast318 = $a$0;- $sub$ptr$sub319 = (($sub$ptr$lhs$cast317) - ($sub$ptr$rhs$cast318))|0;- $160 = $159&1;- $lnot$ext = $160 ^ 1;- $add322 = (($lnot$ext) + ($sub$ptr$sub319))|0;- $cmp323 = ($p$2|0)>($add322|0);- $p$2$add322 = $cmp323 ? $p$2 : $add322;- $a$2 = $a$0;$fl$6 = $and309$fl$4;$p$5 = $p$2$add322;$pl$2 = $pl$1;$prefix$2 = $prefix$1;$z$2 = $add$ptr205;- } else {- $a$2 = $add$ptr205;$fl$6 = $and309$fl$4;$p$5 = 0;$pl$2 = $pl$1;$prefix$2 = $prefix$1;$z$2 = $add$ptr205;- }- }- $sub$ptr$lhs$cast431 = $z$2;- $sub$ptr$rhs$cast432 = $a$2;- $sub$ptr$sub433 = (($sub$ptr$lhs$cast431) - ($sub$ptr$rhs$cast432))|0;- $cmp434 = ($p$5|0)<($sub$ptr$sub433|0);- $sub$ptr$sub433$p$5 = $cmp434 ? $sub$ptr$sub433 : $p$5;- $add441 = (($pl$2) + ($sub$ptr$sub433$p$5))|0;- $cmp442 = ($w$1|0)<($add441|0);- $w$2 = $cmp442 ? $add441 : $w$1;- _pad($f,32,$w$2,$add441,$fl$6);- $265 = HEAP32[$f>>2]|0;- $and$i$244 = $265 & 32;- $tobool$i$245 = ($and$i$244|0)==(0);- if ($tobool$i$245) {- (___fwritex($prefix$2,$pl$2,$f)|0);- }- $xor449 = $fl$6 ^ 65536;- _pad($f,48,$w$2,$add441,$xor449);- _pad($f,48,$sub$ptr$sub433$p$5,$sub$ptr$sub433,0);- $266 = HEAP32[$f>>2]|0;- $and$i$216 = $266 & 32;- $tobool$i$217 = ($and$i$216|0)==(0);- if ($tobool$i$217) {- (___fwritex($a$2,$sub$ptr$sub433,$f)|0);- }- $xor457 = $fl$6 ^ 8192;- _pad($f,32,$w$2,$add441,$xor457);- $cnt$0 = $cnt$1;$incdec$ptr169275 = $incdec$ptr169$lcssa;$l$0 = $w$2;$l10n$0 = $l10n$3;- }- L343: do {- if ((label|0) == 242) {- $tobool459 = ($f|0)==(0|0);- if ($tobool459) {- $tobool462 = ($l10n$0$lcssa|0)==(0);- if ($tobool462) {- $retval$0 = 0;- } else {- $i$2299 = 1;- while(1) {- $arrayidx469 = (($nl_type) + ($i$2299<<2)|0);- $267 = HEAP32[$arrayidx469>>2]|0;- $tobool470 = ($267|0)==(0);- if ($tobool470) {- $i$2299$lcssa = $i$2299;- break;- }- $add$ptr473 = (($nl_arg) + ($i$2299<<3)|0);- _pop_arg_336($add$ptr473,$267,$ap);- $inc = (($i$2299) + 1)|0;- $cmp466 = ($inc|0)<(10);- if ($cmp466) {- $i$2299 = $inc;- } else {- $retval$0 = 1;- break L343;- }- }- $cmp478$295 = ($i$2299$lcssa|0)<(10);- if ($cmp478$295) {- $i$3296 = $i$2299$lcssa;- while(1) {- $arrayidx481 = (($nl_type) + ($i$3296<<2)|0);- $268 = HEAP32[$arrayidx481>>2]|0;- $lnot483 = ($268|0)==(0);- $inc488 = (($i$3296) + 1)|0;- if (!($lnot483)) {- $retval$0 = -1;- break L343;- }- $cmp478 = ($inc488|0)<(10);- if ($cmp478) {- $i$3296 = $inc488;- } else {- $retval$0 = 1;- break;- }- }- } else {- $retval$0 = 1;- }- }- } else {- $retval$0 = $cnt$1$lcssa;- }- }- } while(0);- STACKTOP = sp;return ($retval$0|0);-}-function _pop_arg_336($arg,$type,$ap) {- $arg = $arg|0;- $type = $type|0;- $ap = $ap|0;- var $0 = 0, $1 = 0, $10 = 0, $100 = 0, $101 = 0, $102 = 0, $103 = 0.0, $104 = 0, $105 = 0, $106 = 0, $107 = 0, $108 = 0, $109 = 0, $11 = 0, $110 = 0.0, $12 = 0, $13 = 0, $14 = 0, $15 = 0, $16 = 0;- var $17 = 0, $18 = 0, $19 = 0, $2 = 0, $20 = 0, $21 = 0, $22 = 0, $23 = 0, $24 = 0, $25 = 0, $26 = 0, $27 = 0, $28 = 0, $29 = 0, $3 = 0, $30 = 0, $31 = 0, $32 = 0, $33 = 0, $34 = 0;- var $35 = 0, $36 = 0, $37 = 0, $38 = 0, $39 = 0, $4 = 0, $40 = 0, $41 = 0, $42 = 0, $43 = 0, $44 = 0, $45 = 0, $46 = 0, $47 = 0, $48 = 0, $49 = 0, $5 = 0, $50 = 0, $51 = 0, $52 = 0;- var $53 = 0, $54 = 0, $55 = 0, $56 = 0, $57 = 0, $58 = 0, $59 = 0, $6 = 0, $60 = 0, $61 = 0, $62 = 0, $63 = 0, $64 = 0, $65 = 0, $66 = 0, $67 = 0, $68 = 0, $69 = 0, $7 = 0, $70 = 0;- var $71 = 0, $72 = 0, $73 = 0, $74 = 0, $75 = 0, $76 = 0, $77 = 0, $78 = 0, $79 = 0, $8 = 0, $80 = 0, $81 = 0, $82 = 0, $83 = 0, $84 = 0, $85 = 0, $86 = 0, $87 = 0, $88 = 0, $89 = 0;- var $9 = 0, $90 = 0, $91 = 0, $92 = 0, $93 = 0, $94 = 0, $95 = 0, $96 = 0, $97 = 0, $98 = 0, $99 = 0, $arglist_current = 0, $arglist_current11 = 0, $arglist_current14 = 0, $arglist_current17 = 0, $arglist_current2 = 0, $arglist_current20 = 0, $arglist_current23 = 0, $arglist_current26 = 0, $arglist_current5 = 0;- var $arglist_current8 = 0, $arglist_next = 0, $arglist_next12 = 0, $arglist_next15 = 0, $arglist_next18 = 0, $arglist_next21 = 0, $arglist_next24 = 0, $arglist_next27 = 0, $arglist_next3 = 0, $arglist_next6 = 0, $arglist_next9 = 0, $cmp = 0, $conv12 = 0, $conv17$mask = 0, $conv22 = 0, $conv27$mask = 0, $expanded = 0, $expanded28 = 0, $expanded30 = 0, $expanded31 = 0;- var $expanded32 = 0, $expanded34 = 0, $expanded35 = 0, $expanded37 = 0, $expanded38 = 0, $expanded39 = 0, $expanded41 = 0, $expanded42 = 0, $expanded44 = 0, $expanded45 = 0, $expanded46 = 0, $expanded48 = 0, $expanded49 = 0, $expanded51 = 0, $expanded52 = 0, $expanded53 = 0, $expanded55 = 0, $expanded56 = 0, $expanded58 = 0, $expanded59 = 0;- var $expanded60 = 0, $expanded62 = 0, $expanded63 = 0, $expanded65 = 0, $expanded66 = 0, $expanded67 = 0, $expanded69 = 0, $expanded70 = 0, $expanded72 = 0, $expanded73 = 0, $expanded74 = 0, $expanded76 = 0, $expanded77 = 0, $expanded79 = 0, $expanded80 = 0, $expanded81 = 0, $expanded83 = 0, $expanded84 = 0, $expanded86 = 0, $expanded87 = 0;- var $expanded88 = 0, $expanded90 = 0, $expanded91 = 0, $expanded93 = 0, $expanded94 = 0, $expanded95 = 0, label = 0, sp = 0;- sp = STACKTOP;- $cmp = ($type>>>0)>(20);- L1: do {- if (!($cmp)) {- do {- switch ($type|0) {- case 9: {- $arglist_current = HEAP32[$ap>>2]|0;- $0 = $arglist_current;- $1 = ((0) + 4|0);- $expanded28 = $1;- $expanded = (($expanded28) - 1)|0;- $2 = (($0) + ($expanded))|0;- $3 = ((0) + 4|0);- $expanded32 = $3;- $expanded31 = (($expanded32) - 1)|0;- $expanded30 = $expanded31 ^ -1;- $4 = $2 & $expanded30;- $5 = $4;- $6 = HEAP32[$5>>2]|0;- $arglist_next = ((($5)) + 4|0);- HEAP32[$ap>>2] = $arglist_next;- HEAP32[$arg>>2] = $6;- break L1;- break;- }- case 10: {- $arglist_current2 = HEAP32[$ap>>2]|0;- $7 = $arglist_current2;- $8 = ((0) + 4|0);- $expanded35 = $8;- $expanded34 = (($expanded35) - 1)|0;- $9 = (($7) + ($expanded34))|0;- $10 = ((0) + 4|0);- $expanded39 = $10;- $expanded38 = (($expanded39) - 1)|0;- $expanded37 = $expanded38 ^ -1;- $11 = $9 & $expanded37;- $12 = $11;- $13 = HEAP32[$12>>2]|0;- $arglist_next3 = ((($12)) + 4|0);- HEAP32[$ap>>2] = $arglist_next3;- $14 = ($13|0)<(0);- $15 = $14 << 31 >> 31;- $16 = $arg;- $17 = $16;- HEAP32[$17>>2] = $13;- $18 = (($16) + 4)|0;- $19 = $18;- HEAP32[$19>>2] = $15;- break L1;- break;- }- case 11: {- $arglist_current5 = HEAP32[$ap>>2]|0;- $20 = $arglist_current5;- $21 = ((0) + 4|0);- $expanded42 = $21;- $expanded41 = (($expanded42) - 1)|0;- $22 = (($20) + ($expanded41))|0;- $23 = ((0) + 4|0);- $expanded46 = $23;- $expanded45 = (($expanded46) - 1)|0;- $expanded44 = $expanded45 ^ -1;- $24 = $22 & $expanded44;- $25 = $24;- $26 = HEAP32[$25>>2]|0;- $arglist_next6 = ((($25)) + 4|0);- HEAP32[$ap>>2] = $arglist_next6;- $27 = $arg;- $28 = $27;- HEAP32[$28>>2] = $26;- $29 = (($27) + 4)|0;- $30 = $29;- HEAP32[$30>>2] = 0;- break L1;- break;- }- case 12: {- $arglist_current8 = HEAP32[$ap>>2]|0;- $31 = $arglist_current8;- $32 = ((0) + 8|0);- $expanded49 = $32;- $expanded48 = (($expanded49) - 1)|0;- $33 = (($31) + ($expanded48))|0;- $34 = ((0) + 8|0);- $expanded53 = $34;- $expanded52 = (($expanded53) - 1)|0;- $expanded51 = $expanded52 ^ -1;- $35 = $33 & $expanded51;- $36 = $35;- $37 = $36;- $38 = $37;- $39 = HEAP32[$38>>2]|0;- $40 = (($37) + 4)|0;- $41 = $40;- $42 = HEAP32[$41>>2]|0;- $arglist_next9 = ((($36)) + 8|0);- HEAP32[$ap>>2] = $arglist_next9;- $43 = $arg;- $44 = $43;- HEAP32[$44>>2] = $39;- $45 = (($43) + 4)|0;- $46 = $45;- HEAP32[$46>>2] = $42;- break L1;- break;- }- case 13: {- $arglist_current11 = HEAP32[$ap>>2]|0;- $47 = $arglist_current11;- $48 = ((0) + 4|0);- $expanded56 = $48;- $expanded55 = (($expanded56) - 1)|0;- $49 = (($47) + ($expanded55))|0;- $50 = ((0) + 4|0);- $expanded60 = $50;- $expanded59 = (($expanded60) - 1)|0;- $expanded58 = $expanded59 ^ -1;- $51 = $49 & $expanded58;- $52 = $51;- $53 = HEAP32[$52>>2]|0;- $arglist_next12 = ((($52)) + 4|0);- HEAP32[$ap>>2] = $arglist_next12;- $conv12 = $53&65535;- $54 = $conv12 << 16 >> 16;- $55 = ($54|0)<(0);- $56 = $55 << 31 >> 31;- $57 = $arg;- $58 = $57;- HEAP32[$58>>2] = $54;- $59 = (($57) + 4)|0;- $60 = $59;- HEAP32[$60>>2] = $56;- break L1;- break;- }- case 14: {- $arglist_current14 = HEAP32[$ap>>2]|0;- $61 = $arglist_current14;- $62 = ((0) + 4|0);- $expanded63 = $62;- $expanded62 = (($expanded63) - 1)|0;- $63 = (($61) + ($expanded62))|0;- $64 = ((0) + 4|0);- $expanded67 = $64;- $expanded66 = (($expanded67) - 1)|0;- $expanded65 = $expanded66 ^ -1;- $65 = $63 & $expanded65;- $66 = $65;- $67 = HEAP32[$66>>2]|0;- $arglist_next15 = ((($66)) + 4|0);- HEAP32[$ap>>2] = $arglist_next15;- $conv17$mask = $67 & 65535;- $68 = $arg;- $69 = $68;- HEAP32[$69>>2] = $conv17$mask;- $70 = (($68) + 4)|0;- $71 = $70;- HEAP32[$71>>2] = 0;- break L1;- break;- }- case 15: {- $arglist_current17 = HEAP32[$ap>>2]|0;- $72 = $arglist_current17;- $73 = ((0) + 4|0);- $expanded70 = $73;- $expanded69 = (($expanded70) - 1)|0;- $74 = (($72) + ($expanded69))|0;- $75 = ((0) + 4|0);- $expanded74 = $75;- $expanded73 = (($expanded74) - 1)|0;- $expanded72 = $expanded73 ^ -1;- $76 = $74 & $expanded72;- $77 = $76;- $78 = HEAP32[$77>>2]|0;- $arglist_next18 = ((($77)) + 4|0);- HEAP32[$ap>>2] = $arglist_next18;- $conv22 = $78&255;- $79 = $conv22 << 24 >> 24;- $80 = ($79|0)<(0);- $81 = $80 << 31 >> 31;- $82 = $arg;- $83 = $82;- HEAP32[$83>>2] = $79;- $84 = (($82) + 4)|0;- $85 = $84;- HEAP32[$85>>2] = $81;- break L1;- break;- }- case 16: {- $arglist_current20 = HEAP32[$ap>>2]|0;- $86 = $arglist_current20;- $87 = ((0) + 4|0);- $expanded77 = $87;- $expanded76 = (($expanded77) - 1)|0;- $88 = (($86) + ($expanded76))|0;- $89 = ((0) + 4|0);- $expanded81 = $89;- $expanded80 = (($expanded81) - 1)|0;- $expanded79 = $expanded80 ^ -1;- $90 = $88 & $expanded79;- $91 = $90;- $92 = HEAP32[$91>>2]|0;- $arglist_next21 = ((($91)) + 4|0);- HEAP32[$ap>>2] = $arglist_next21;- $conv27$mask = $92 & 255;- $93 = $arg;- $94 = $93;- HEAP32[$94>>2] = $conv27$mask;- $95 = (($93) + 4)|0;- $96 = $95;- HEAP32[$96>>2] = 0;- break L1;- break;- }- case 17: {- $arglist_current23 = HEAP32[$ap>>2]|0;- $97 = $arglist_current23;- $98 = ((0) + 8|0);- $expanded84 = $98;- $expanded83 = (($expanded84) - 1)|0;- $99 = (($97) + ($expanded83))|0;- $100 = ((0) + 8|0);- $expanded88 = $100;- $expanded87 = (($expanded88) - 1)|0;- $expanded86 = $expanded87 ^ -1;- $101 = $99 & $expanded86;- $102 = $101;- $103 = +HEAPF64[$102>>3];- $arglist_next24 = ((($102)) + 8|0);- HEAP32[$ap>>2] = $arglist_next24;- HEAPF64[$arg>>3] = $103;- break L1;- break;- }- case 18: {- $arglist_current26 = HEAP32[$ap>>2]|0;- $104 = $arglist_current26;- $105 = ((0) + 8|0);- $expanded91 = $105;- $expanded90 = (($expanded91) - 1)|0;- $106 = (($104) + ($expanded90))|0;- $107 = ((0) + 8|0);- $expanded95 = $107;- $expanded94 = (($expanded95) - 1)|0;- $expanded93 = $expanded94 ^ -1;- $108 = $106 & $expanded93;- $109 = $108;- $110 = +HEAPF64[$109>>3];- $arglist_next27 = ((($109)) + 8|0);- HEAP32[$ap>>2] = $arglist_next27;- HEAPF64[$arg>>3] = $110;- break L1;- break;- }- default: {- break L1;- }- }- } while(0);- }- } while(0);- return;-}-function _fmt_u($0,$1,$s) {- $0 = $0|0;- $1 = $1|0;- $s = $s|0;- var $10 = 0, $11 = 0, $12 = 0, $13 = 0, $14 = 0, $15 = 0, $16 = 0, $17 = 0, $18 = 0, $19 = 0, $2 = 0, $20 = 0, $21 = 0, $22 = 0, $3 = 0, $4 = 0, $5 = 0, $6 = 0, $7 = 0, $8 = 0;- var $9 = 0, $add5 = 0, $conv6 = 0, $div9 = 0, $incdec$ptr = 0, $incdec$ptr$lcssa = 0, $incdec$ptr7 = 0, $rem4 = 0, $s$addr$0$lcssa = 0, $s$addr$013 = 0, $s$addr$1$lcssa = 0, $s$addr$19 = 0, $tobool$8 = 0, $x$addr$0$lcssa$off0 = 0, $y$010 = 0, label = 0, sp = 0;- sp = STACKTOP;- $2 = ($1>>>0)>(0);- $3 = ($0>>>0)>(4294967295);- $4 = ($1|0)==(0);- $5 = $4 & $3;- $6 = $2 | $5;- if ($6) {- $7 = $0;$8 = $1;$s$addr$013 = $s;- while(1) {- $9 = (___uremdi3(($7|0),($8|0),10,0)|0);- $10 = tempRet0;- $11 = $9 | 48;- $12 = $11&255;- $incdec$ptr = ((($s$addr$013)) + -1|0);- HEAP8[$incdec$ptr>>0] = $12;- $13 = (___udivdi3(($7|0),($8|0),10,0)|0);- $14 = tempRet0;- $15 = ($8>>>0)>(9);- $16 = ($7>>>0)>(4294967295);- $17 = ($8|0)==(9);- $18 = $17 & $16;- $19 = $15 | $18;- if ($19) {- $7 = $13;$8 = $14;$s$addr$013 = $incdec$ptr;- } else {- $21 = $13;$22 = $14;$incdec$ptr$lcssa = $incdec$ptr;- break;- }- }- $s$addr$0$lcssa = $incdec$ptr$lcssa;$x$addr$0$lcssa$off0 = $21;- } else {- $s$addr$0$lcssa = $s;$x$addr$0$lcssa$off0 = $0;- }- $tobool$8 = ($x$addr$0$lcssa$off0|0)==(0);- if ($tobool$8) {- $s$addr$1$lcssa = $s$addr$0$lcssa;- } else {- $s$addr$19 = $s$addr$0$lcssa;$y$010 = $x$addr$0$lcssa$off0;- while(1) {- $rem4 = (($y$010>>>0) % 10)&-1;- $add5 = $rem4 | 48;- $conv6 = $add5&255;- $incdec$ptr7 = ((($s$addr$19)) + -1|0);- HEAP8[$incdec$ptr7>>0] = $conv6;- $div9 = (($y$010>>>0) / 10)&-1;- $20 = ($y$010>>>0)<(10);- if ($20) {- $s$addr$1$lcssa = $incdec$ptr7;- break;- } else {- $s$addr$19 = $incdec$ptr7;$y$010 = $div9;- }- }- }- return ($s$addr$1$lcssa|0);-}-function _pad($f,$c,$w,$l,$fl) {- $f = $f|0;- $c = $c|0;- $w = $w|0;- $l = $l|0;- $fl = $fl|0;- var $$pre = 0, $0 = 0, $1 = 0, $2 = 0, $3 = 0, $4 = 0, $and = 0, $and$i = 0, $and$i$15 = 0, $cmp = 0, $cmp1 = 0, $cmp3 = 0, $cmp3$14 = 0, $cond = 0, $l$addr$0$lcssa21 = 0, $l$addr$017 = 0, $or$cond = 0, $pad = 0, $sub = 0, $sub5 = 0;- var $tobool = 0, $tobool$i = 0, $tobool$i$16 = 0, $tobool$i18 = 0, label = 0, sp = 0;- sp = STACKTOP;- STACKTOP = STACKTOP + 256|0; if ((STACKTOP|0) >= (STACK_MAX|0)) abort();- $pad = sp;- $and = $fl & 73728;- $tobool = ($and|0)==(0);- $cmp = ($w|0)>($l|0);- $or$cond = $cmp & $tobool;- do {- if ($or$cond) {- $sub = (($w) - ($l))|0;- $cmp1 = ($sub>>>0)>(256);- $cond = $cmp1 ? 256 : $sub;- _memset(($pad|0),($c|0),($cond|0))|0;- $cmp3$14 = ($sub>>>0)>(255);- $0 = HEAP32[$f>>2]|0;- $and$i$15 = $0 & 32;- $tobool$i$16 = ($and$i$15|0)==(0);- if ($cmp3$14) {- $1 = (($w) - ($l))|0;- $4 = $0;$l$addr$017 = $sub;$tobool$i18 = $tobool$i$16;- while(1) {- if ($tobool$i18) {- (___fwritex($pad,256,$f)|0);- $$pre = HEAP32[$f>>2]|0;- $2 = $$pre;- } else {- $2 = $4;- }- $sub5 = (($l$addr$017) + -256)|0;- $cmp3 = ($sub5>>>0)>(255);- $and$i = $2 & 32;- $tobool$i = ($and$i|0)==(0);- if ($cmp3) {- $4 = $2;$l$addr$017 = $sub5;$tobool$i18 = $tobool$i;- } else {- break;- }- }- $3 = $1 & 255;- if ($tobool$i) {- $l$addr$0$lcssa21 = $3;- } else {- break;- }- } else {- if ($tobool$i$16) {- $l$addr$0$lcssa21 = $sub;- } else {- break;- }- }- (___fwritex($pad,$l$addr$0$lcssa21,$f)|0);- }- } while(0);- STACKTOP = sp;return;-}-function _malloc($bytes) {- $bytes = $bytes|0;- var $$lcssa = 0, $$lcssa290 = 0, $$pre = 0, $$pre$i = 0, $$pre$i$177 = 0, $$pre$i$56$i = 0, $$pre$i$i = 0, $$pre$phi$i$178Z2D = 0, $$pre$phi$i$57$iZ2D = 0, $$pre$phi$i$iZ2D = 0, $$pre$phi$iZ2D = 0, $$pre$phiZ2D = 0, $$pre241 = 0, $$pre5$i$i = 0, $0 = 0, $1 = 0, $10 = 0, $100 = 0, $101 = 0, $102 = 0;- var $103 = 0, $104 = 0, $105 = 0, $106 = 0, $107 = 0, $108 = 0, $109 = 0, $11 = 0, $110 = 0, $111 = 0, $112 = 0, $113 = 0, $114 = 0, $115 = 0, $116 = 0, $117 = 0, $118 = 0, $119 = 0, $12 = 0, $120 = 0;- var $121 = 0, $122 = 0, $123 = 0, $124 = 0, $125 = 0, $126 = 0, $127 = 0, $128 = 0, $129 = 0, $13 = 0, $130 = 0, $131 = 0, $132 = 0, $133 = 0, $134 = 0, $135 = 0, $136 = 0, $137 = 0, $138 = 0, $139 = 0;- var $14 = 0, $140 = 0, $141 = 0, $142 = 0, $143 = 0, $144 = 0, $145 = 0, $146 = 0, $147 = 0, $148 = 0, $149 = 0, $15 = 0, $150 = 0, $151 = 0, $152 = 0, $153 = 0, $154 = 0, $155 = 0, $156 = 0, $157 = 0;- var $158 = 0, $159 = 0, $16 = 0, $160 = 0, $161 = 0, $162 = 0, $163 = 0, $164 = 0, $165 = 0, $166 = 0, $167 = 0, $168 = 0, $169 = 0, $17 = 0, $170 = 0, $171 = 0, $172 = 0, $173 = 0, $174 = 0, $175 = 0;- var $176 = 0, $177 = 0, $178 = 0, $179 = 0, $18 = 0, $180 = 0, $181 = 0, $182 = 0, $183 = 0, $184 = 0, $185 = 0, $186 = 0, $187 = 0, $188 = 0, $189 = 0, $19 = 0, $190 = 0, $191 = 0, $192 = 0, $193 = 0;- var $194 = 0, $195 = 0, $196 = 0, $197 = 0, $198 = 0, $199 = 0, $2 = 0, $20 = 0, $200 = 0, $201 = 0, $202 = 0, $203 = 0, $204 = 0, $205 = 0, $206 = 0, $207 = 0, $208 = 0, $21 = 0, $22 = 0, $23 = 0;- var $24 = 0, $25 = 0, $26 = 0, $27 = 0, $28 = 0, $29 = 0, $3 = 0, $30 = 0, $31 = 0, $32 = 0, $33 = 0, $34 = 0, $35 = 0, $36 = 0, $37 = 0, $38 = 0, $39 = 0, $4 = 0, $40 = 0, $41 = 0;- var $42 = 0, $43 = 0, $44 = 0, $45 = 0, $46 = 0, $47 = 0, $48 = 0, $49 = 0, $5 = 0, $50 = 0, $51 = 0, $52 = 0, $53 = 0, $54 = 0, $55 = 0, $56 = 0, $57 = 0, $58 = 0, $59 = 0, $6 = 0;- var $60 = 0, $61 = 0, $62 = 0, $63 = 0, $64 = 0, $65 = 0, $66 = 0, $67 = 0, $68 = 0, $69 = 0, $7 = 0, $70 = 0, $71 = 0, $72 = 0, $73 = 0, $74 = 0, $75 = 0, $76 = 0, $77 = 0, $78 = 0;- var $79 = 0, $8 = 0, $80 = 0, $81 = 0, $82 = 0, $83 = 0, $84 = 0, $85 = 0, $86 = 0, $87 = 0, $88 = 0, $89 = 0, $9 = 0, $90 = 0, $91 = 0, $92 = 0, $93 = 0, $94 = 0, $95 = 0, $96 = 0;- var $97 = 0, $98 = 0, $99 = 0, $F$0$i$i = 0, $F104$0 = 0, $F197$0$i = 0, $F224$0$i$i = 0, $F290$0$i = 0, $I252$0$i$i = 0, $I316$0$i = 0, $I57$0$i$i = 0, $K105$0$i$i = 0, $K305$0$i$i = 0, $K373$0$i = 0, $R$1$i = 0, $R$1$i$168 = 0, $R$1$i$168$lcssa = 0, $R$1$i$i = 0, $R$1$i$i$lcssa = 0, $R$1$i$lcssa = 0;- var $R$3$i = 0, $R$3$i$171 = 0, $R$3$i$i = 0, $RP$1$i = 0, $RP$1$i$167 = 0, $RP$1$i$167$lcssa = 0, $RP$1$i$i = 0, $RP$1$i$i$lcssa = 0, $RP$1$i$lcssa = 0, $T$0$i = 0, $T$0$i$58$i = 0, $T$0$i$58$i$lcssa = 0, $T$0$i$58$i$lcssa283 = 0, $T$0$i$i = 0, $T$0$i$i$lcssa = 0, $T$0$i$i$lcssa284 = 0, $T$0$i$lcssa = 0, $T$0$i$lcssa293 = 0, $add$i = 0, $add$i$146 = 0;- var $add$i$180 = 0, $add$i$i = 0, $add$ptr = 0, $add$ptr$i = 0, $add$ptr$i$1$i$i = 0, $add$ptr$i$11$i = 0, $add$ptr$i$161 = 0, $add$ptr$i$193 = 0, $add$ptr$i$21$i = 0, $add$ptr$i$32$i = 0, $add$ptr$i$i = 0, $add$ptr$i$i$i = 0, $add$ptr$i$i$i$lcssa = 0, $add$ptr14$i$i = 0, $add$ptr15$i$i = 0, $add$ptr16$i$i = 0, $add$ptr166 = 0, $add$ptr169 = 0, $add$ptr17$i$i = 0, $add$ptr178 = 0;- var $add$ptr181$i = 0, $add$ptr182 = 0, $add$ptr189$i = 0, $add$ptr190$i = 0, $add$ptr193 = 0, $add$ptr199 = 0, $add$ptr2$i$i = 0, $add$ptr205$i$i = 0, $add$ptr212$i$i = 0, $add$ptr225$i = 0, $add$ptr227$i = 0, $add$ptr24$i$i = 0, $add$ptr262$i = 0, $add$ptr269$i = 0, $add$ptr273$i = 0, $add$ptr282$i = 0, $add$ptr3$i$i = 0, $add$ptr30$i$i = 0, $add$ptr369$i$i = 0, $add$ptr4$i$26$i = 0;- var $add$ptr4$i$37$i = 0, $add$ptr4$i$i = 0, $add$ptr4$i$i$i = 0, $add$ptr441$i = 0, $add$ptr5$i$i = 0, $add$ptr6$i$30$i = 0, $add$ptr6$i$i = 0, $add$ptr6$i$i$i = 0, $add$ptr7$i$i = 0, $add$ptr8$i122$i = 0, $add$ptr95 = 0, $add$ptr98 = 0, $add10$i = 0, $add101$i = 0, $add110$i = 0, $add13$i = 0, $add14$i = 0, $add140$i = 0, $add144 = 0, $add150$i = 0;- var $add17$i = 0, $add17$i$183 = 0, $add177$i = 0, $add18$i = 0, $add19$i = 0, $add2 = 0, $add20$i = 0, $add206$i$i = 0, $add212$i = 0, $add215$i = 0, $add22$i = 0, $add246$i = 0, $add26$i$i = 0, $add268$i = 0, $add269$i$i = 0, $add274$i$i = 0, $add278$i$i = 0, $add280$i$i = 0, $add283$i$i = 0, $add337$i = 0;- var $add342$i = 0, $add346$i = 0, $add348$i = 0, $add351$i = 0, $add46$i = 0, $add50 = 0, $add51$i = 0, $add54 = 0, $add54$i = 0, $add58 = 0, $add62 = 0, $add64 = 0, $add74$i$i = 0, $add77$i = 0, $add78$i = 0, $add79$i$i = 0, $add8 = 0, $add82$i = 0, $add83$i$i = 0, $add85$i$i = 0;- var $add86$i = 0, $add88$i$i = 0, $add9$i = 0, $add90$i = 0, $add92$i = 0, $and = 0, $and$i = 0, $and$i$12$i = 0, $and$i$14$i = 0, $and$i$143 = 0, $and$i$22$i = 0, $and$i$33$i = 0, $and$i$i = 0, $and$i$i$i = 0, $and100$i = 0, $and103$i = 0, $and104$i = 0, $and106 = 0, $and11$i = 0, $and119$i$i = 0;- var $and12$i = 0, $and13$i = 0, $and13$i$i = 0, $and133$i$i = 0, $and14 = 0, $and145 = 0, $and17$i = 0, $and194$i = 0, $and194$i$204 = 0, $and199$i = 0, $and209$i$i = 0, $and21$i = 0, $and21$i$149 = 0, $and227$i$i = 0, $and236$i = 0, $and264$i$i = 0, $and268$i$i = 0, $and273$i$i = 0, $and282$i$i = 0, $and29$i = 0;- var $and292$i = 0, $and295$i$i = 0, $and3$i = 0, $and3$i$24$i = 0, $and3$i$35$i = 0, $and3$i$i = 0, $and3$i$i$i = 0, $and30$i = 0, $and318$i$i = 0, $and32$i = 0, $and32$i$i = 0, $and33$i$i = 0, $and331$i = 0, $and336$i = 0, $and341$i = 0, $and350$i = 0, $and363$i = 0, $and37$i$i = 0, $and387$i = 0, $and4 = 0;- var $and40$i$i = 0, $and41 = 0, $and42$i = 0, $and43 = 0, $and46 = 0, $and49 = 0, $and49$i = 0, $and49$i$i = 0, $and53 = 0, $and57 = 0, $and6$i = 0, $and6$i$38$i = 0, $and6$i$i = 0, $and61 = 0, $and64$i = 0, $and68$i = 0, $and69$i$i = 0, $and7 = 0, $and7$i$i = 0, $and73$i = 0;- var $and73$i$i = 0, $and74 = 0, $and77$i = 0, $and78$i$i = 0, $and8$i = 0, $and80$i = 0, $and81$i = 0, $and85$i = 0, $and87$i$i = 0, $and89$i = 0, $and9$i = 0, $and96$i$i = 0, $arrayidx = 0, $arrayidx$i = 0, $arrayidx$i$150 = 0, $arrayidx$i$20$i = 0, $arrayidx$i$48$i = 0, $arrayidx$i$i = 0, $arrayidx103 = 0, $arrayidx103$i$i = 0;- var $arrayidx106$i = 0, $arrayidx107$i$i = 0, $arrayidx113$i = 0, $arrayidx113$i$159 = 0, $arrayidx121$i = 0, $arrayidx123$i$i = 0, $arrayidx126$i$i = 0, $arrayidx126$i$i$lcssa = 0, $arrayidx137$i = 0, $arrayidx143$i$i = 0, $arrayidx148$i = 0, $arrayidx151$i = 0, $arrayidx151$i$i = 0, $arrayidx154$i = 0, $arrayidx155$i = 0, $arrayidx161$i = 0, $arrayidx165$i = 0, $arrayidx165$i$169 = 0, $arrayidx178$i$i = 0, $arrayidx184$i = 0;- var $arrayidx184$i$i = 0, $arrayidx195$i$i = 0, $arrayidx196$i = 0, $arrayidx204$i = 0, $arrayidx212$i = 0, $arrayidx223$i$i = 0, $arrayidx228$i = 0, $arrayidx23$i = 0, $arrayidx239$i = 0, $arrayidx245$i = 0, $arrayidx256$i = 0, $arrayidx27$i = 0, $arrayidx287$i$i = 0, $arrayidx289$i = 0, $arrayidx290$i$i = 0, $arrayidx325$i$i = 0, $arrayidx325$i$i$lcssa = 0, $arrayidx355$i = 0, $arrayidx358$i = 0, $arrayidx394$i = 0;- var $arrayidx394$i$lcssa = 0, $arrayidx40$i = 0, $arrayidx44$i = 0, $arrayidx61$i = 0, $arrayidx65$i = 0, $arrayidx66 = 0, $arrayidx71$i = 0, $arrayidx75$i = 0, $arrayidx91$i$i = 0, $arrayidx92$i$i = 0, $arrayidx94$i = 0, $arrayidx94$i$156 = 0, $arrayidx96$i$i = 0, $base$i$i$lcssa = 0, $base226$i$lcssa = 0, $bk = 0, $bk$i = 0, $bk$i$163 = 0, $bk$i$46$i = 0, $bk$i$i = 0;- var $bk102$i$i = 0, $bk122 = 0, $bk124 = 0, $bk136$i = 0, $bk139$i$i = 0, $bk158$i$i = 0, $bk161$i$i = 0, $bk218$i = 0, $bk220$i = 0, $bk246$i$i = 0, $bk248$i$i = 0, $bk302$i$i = 0, $bk311$i = 0, $bk313$i = 0, $bk338$i$i = 0, $bk357$i$i = 0, $bk360$i$i = 0, $bk370$i = 0, $bk407$i = 0, $bk429$i = 0;- var $bk43$i$i = 0, $bk432$i = 0, $bk47$i = 0, $bk55$i$i = 0, $bk67$i$i = 0, $bk74$i$i = 0, $bk78 = 0, $bk82$i$i = 0, $br$2$ph$i = 0, $call$i$i = 0, $call107$i = 0, $call131$i = 0, $call132$i = 0, $call275$i = 0, $call37$i = 0, $call6$i$i = 0, $call68$i = 0, $call83$i = 0, $child$i$i = 0, $child166$i$i = 0;- var $child289$i$i = 0, $child357$i = 0, $cmp = 0, $cmp$i = 0, $cmp$i$13$i = 0, $cmp$i$140 = 0, $cmp$i$15$i = 0, $cmp$i$179 = 0, $cmp$i$2$i$i = 0, $cmp$i$23$i = 0, $cmp$i$34$i = 0, $cmp$i$9$i = 0, $cmp$i$i$i = 0, $cmp1 = 0, $cmp1$i = 0, $cmp1$i$i = 0, $cmp10 = 0, $cmp100$i$i = 0, $cmp102$i = 0, $cmp104$i$i = 0;- var $cmp105$i = 0, $cmp106$i$i = 0, $cmp107$i = 0, $cmp107$i$157 = 0, $cmp108$i = 0, $cmp108$i$i = 0, $cmp112$i$i = 0, $cmp113 = 0, $cmp114$i = 0, $cmp116$i = 0, $cmp118$i = 0, $cmp119$i = 0, $cmp12$i = 0, $cmp120$i$53$i = 0, $cmp120$i$i = 0, $cmp121$i = 0, $cmp123$i = 0, $cmp124$i$i = 0, $cmp126$i = 0, $cmp127$i = 0;- var $cmp128 = 0, $cmp128$i = 0, $cmp128$i$i = 0, $cmp130$i = 0, $cmp133$i = 0, $cmp133$i$196 = 0, $cmp133$i$i = 0, $cmp135$i = 0, $cmp137$i = 0, $cmp137$i$197 = 0, $cmp137$i$i = 0, $cmp138$i = 0, $cmp139 = 0, $cmp140$i = 0, $cmp141$not$i = 0, $cmp142$i = 0, $cmp144$i$i = 0, $cmp146 = 0, $cmp15 = 0, $cmp15$i = 0;- var $cmp151$i = 0, $cmp152$i = 0, $cmp153$i$i = 0, $cmp155$i = 0, $cmp156 = 0, $cmp156$i = 0, $cmp156$i$i = 0, $cmp157$i = 0, $cmp159$i = 0, $cmp159$i$199 = 0, $cmp16 = 0, $cmp160$i$i = 0, $cmp162 = 0, $cmp162$i = 0, $cmp162$i$200 = 0, $cmp166$i = 0, $cmp168$i$i = 0, $cmp171$i = 0, $cmp172$i$i = 0, $cmp174$i = 0;- var $cmp180$i = 0, $cmp185$i = 0, $cmp185$i$i = 0, $cmp186 = 0, $cmp186$i = 0, $cmp189$i$i = 0, $cmp19$i = 0, $cmp190$i = 0, $cmp191$i = 0, $cmp198$i = 0, $cmp2$i$i = 0, $cmp2$i$i$i = 0, $cmp20$i$i = 0, $cmp203$i = 0, $cmp205$i = 0, $cmp208$i = 0, $cmp209$i = 0, $cmp21$i = 0, $cmp215$i$i = 0, $cmp217$i = 0;- var $cmp218$i = 0, $cmp221$i = 0, $cmp224$i = 0, $cmp228$i = 0, $cmp229$i = 0, $cmp233$i = 0, $cmp236$i$i = 0, $cmp24$i = 0, $cmp24$i$i = 0, $cmp246$i = 0, $cmp250$i = 0, $cmp254$i$i = 0, $cmp257$i = 0, $cmp258$i$i = 0, $cmp26$i = 0, $cmp265$i = 0, $cmp27$i$i = 0, $cmp28$i = 0, $cmp28$i$i = 0, $cmp284$i = 0;- var $cmp29 = 0, $cmp3$i$i = 0, $cmp301$i = 0, $cmp306$i$i = 0, $cmp31 = 0, $cmp319$i = 0, $cmp319$i$i = 0, $cmp32$i = 0, $cmp32$i$185 = 0, $cmp323$i = 0, $cmp327$i$i = 0, $cmp33$i = 0, $cmp332$i$i = 0, $cmp34$i = 0, $cmp34$i$i = 0, $cmp35$i = 0, $cmp350$i$i = 0, $cmp36$i = 0, $cmp36$i$i = 0, $cmp374$i = 0;- var $cmp38$i = 0, $cmp38$i$i = 0, $cmp388$i = 0, $cmp396$i = 0, $cmp40$i = 0, $cmp401$i = 0, $cmp41$i$i = 0, $cmp42$i$i = 0, $cmp422$i = 0, $cmp43$i = 0, $cmp44$i$i = 0, $cmp45$i = 0, $cmp45$i$155 = 0, $cmp46$i = 0, $cmp46$i$49$i = 0, $cmp46$i$i = 0, $cmp48$i = 0, $cmp49$i = 0, $cmp5 = 0, $cmp51$i = 0;- var $cmp54$i$i = 0, $cmp55$i = 0, $cmp55$i$187 = 0, $cmp57$i = 0, $cmp57$i$188 = 0, $cmp57$i$i = 0, $cmp59$i$i = 0, $cmp60$i = 0, $cmp60$i$i = 0, $cmp62$i = 0, $cmp63$i = 0, $cmp63$i$i = 0, $cmp65$i = 0, $cmp66$i = 0, $cmp66$i$190 = 0, $cmp69$i = 0, $cmp7$i$i = 0, $cmp70 = 0, $cmp72$i = 0, $cmp75$i$i = 0;- var $cmp76 = 0, $cmp76$i = 0, $cmp79 = 0, $cmp81$i = 0, $cmp81$i$191 = 0, $cmp81$i$i = 0, $cmp83$i$i = 0, $cmp85$i = 0, $cmp86$i$i = 0, $cmp89$i = 0, $cmp9$i$i = 0, $cmp90$i = 0, $cmp91$i = 0, $cmp93$i = 0, $cmp95$i = 0, $cmp96$i = 0, $cmp97$7$i = 0, $cmp97$i = 0, $cmp97$i$i = 0, $cmp99 = 0;- var $cond = 0, $cond$i = 0, $cond$i$16$i = 0, $cond$i$25$i = 0, $cond$i$36$i = 0, $cond$i$i = 0, $cond$i$i$i = 0, $cond$v$0$i = 0, $cond115$i$i = 0, $cond13$i$i = 0, $cond15$i$i = 0, $cond2$i = 0, $cond2$i$i = 0, $cond3$i = 0, $cond315$i$i = 0, $cond383$i = 0, $cond4$i = 0, $exitcond$i$i = 0, $fd$i = 0, $fd$i$164 = 0;- var $fd$i$i = 0, $fd103$i$i = 0, $fd123 = 0, $fd139$i = 0, $fd140$i$i = 0, $fd148$i$i = 0, $fd160$i$i = 0, $fd219$i = 0, $fd247$i$i = 0, $fd303$i$i = 0, $fd312$i = 0, $fd339$i$i = 0, $fd344$i$i = 0, $fd359$i$i = 0, $fd371$i = 0, $fd408$i = 0, $fd416$i = 0, $fd431$i = 0, $fd50$i = 0, $fd54$i$i = 0;- var $fd59$i$i = 0, $fd68$pre$phi$i$iZ2D = 0, $fd69 = 0, $fd78$i$i = 0, $fd85$i$i = 0, $fd9 = 0, $head = 0, $head$i = 0, $head$i$154 = 0, $head$i$17$i = 0, $head$i$29$i = 0, $head$i$42$i = 0, $head$i$i = 0, $head$i$i$i = 0, $head118$i$i = 0, $head168 = 0, $head173 = 0, $head177 = 0, $head179 = 0, $head179$i = 0;- var $head182$i = 0, $head187$i = 0, $head189$i = 0, $head195 = 0, $head198 = 0, $head208$i$i = 0, $head211$i$i = 0, $head23$i$i = 0, $head25 = 0, $head265$i = 0, $head268$i = 0, $head271$i = 0, $head274$i = 0, $head279$i = 0, $head281$i = 0, $head29$i = 0, $head29$i$i = 0, $head317$i$i = 0, $head32$i$i = 0, $head34$i$i = 0;- var $head386$i = 0, $head7$i$31$i = 0, $head7$i$i = 0, $head7$i$i$i = 0, $head94 = 0, $head97 = 0, $head99$i = 0, $i$01$i$i = 0, $idx$0$i = 0, $inc$i$i = 0, $index$i = 0, $index$i$172 = 0, $index$i$54$i = 0, $index$i$i = 0, $index288$i$i = 0, $index356$i = 0, $nb$0 = 0, $neg = 0, $neg$i = 0, $neg$i$173 = 0;- var $neg$i$182 = 0, $neg$i$i = 0, $neg103$i = 0, $neg13 = 0, $neg132$i$i = 0, $neg48$i = 0, $neg73 = 0, $next$i = 0, $next$i$i = 0, $next$i$i$i = 0, $next231$i = 0, $not$cmp150$i$i = 0, $not$cmp346$i$i = 0, $not$cmp418$i = 0, $oldfirst$0$i$i = 0, $or$cond$i = 0, $or$cond$i$189 = 0, $or$cond1$i = 0, $or$cond1$i$184 = 0, $or$cond2$i = 0;- var $or$cond3$i = 0, $or$cond4$i = 0, $or$cond5$i = 0, $or$cond7$i = 0, $or$cond8$i = 0, $or$cond98$i = 0, $or$i = 0, $or$i$195 = 0, $or$i$28$i = 0, $or$i$i = 0, $or$i$i$i = 0, $or101$i$i = 0, $or110 = 0, $or167 = 0, $or172 = 0, $or176 = 0, $or178$i = 0, $or180 = 0, $or183$i = 0, $or186$i = 0;- var $or188$i = 0, $or19$i$i = 0, $or194 = 0, $or197 = 0, $or204$i = 0, $or210$i$i = 0, $or22$i$i = 0, $or23 = 0, $or232$i$i = 0, $or26 = 0, $or264$i = 0, $or267$i = 0, $or270$i = 0, $or275$i = 0, $or278$i = 0, $or28$i$i = 0, $or280$i = 0, $or297$i = 0, $or300$i$i = 0, $or33$i$i = 0;- var $or368$i = 0, $or40 = 0, $or44$i$i = 0, $or93 = 0, $or96 = 0, $p$0$i$i = 0, $parent$i = 0, $parent$i$162 = 0, $parent$i$51$i = 0, $parent$i$i = 0, $parent135$i = 0, $parent138$i$i = 0, $parent149$i = 0, $parent162$i$i = 0, $parent165$i$i = 0, $parent166$i = 0, $parent179$i$i = 0, $parent196$i$i = 0, $parent226$i = 0, $parent240$i = 0;- var $parent257$i = 0, $parent301$i$i = 0, $parent337$i$i = 0, $parent361$i$i = 0, $parent369$i = 0, $parent406$i = 0, $parent433$i = 0, $qsize$0$i$i = 0, $retval$0 = 0, $rsize$0$i = 0, $rsize$0$i$152 = 0, $rsize$0$i$lcssa = 0, $rsize$1$i = 0, $rsize$3$i = 0, $rsize$4$lcssa$i = 0, $rsize$49$i = 0, $rst$0$i = 0, $rst$1$i = 0, $sflags193$i = 0, $sflags235$i = 0;- var $shl = 0, $shl$i = 0, $shl$i$144 = 0, $shl$i$19$i = 0, $shl$i$47$i = 0, $shl$i$i = 0, $shl102 = 0, $shl105 = 0, $shl116$i$i = 0, $shl12 = 0, $shl127$i$i = 0, $shl131$i$i = 0, $shl15$i = 0, $shl18$i = 0, $shl192$i = 0, $shl195$i = 0, $shl198$i = 0, $shl22 = 0, $shl221$i$i = 0, $shl226$i$i = 0;- var $shl265$i$i = 0, $shl270$i$i = 0, $shl276$i$i = 0, $shl279$i$i = 0, $shl288$i = 0, $shl291$i = 0, $shl294$i$i = 0, $shl31$i = 0, $shl316$i$i = 0, $shl326$i$i = 0, $shl333$i = 0, $shl338$i = 0, $shl344$i = 0, $shl347$i = 0, $shl35 = 0, $shl362$i = 0, $shl37 = 0, $shl384$i = 0, $shl39$i$i = 0, $shl395$i = 0;- var $shl48$i$i = 0, $shl52$i = 0, $shl60$i = 0, $shl65 = 0, $shl70$i$i = 0, $shl72 = 0, $shl75$i$i = 0, $shl81$i$i = 0, $shl84$i$i = 0, $shl9$i = 0, $shl90 = 0, $shl95$i$i = 0, $shr = 0, $shr$i = 0, $shr$i$139 = 0, $shr$i$45$i = 0, $shr$i$i = 0, $shr101 = 0, $shr11$i = 0, $shr11$i$147 = 0;- var $shr110$i$i = 0, $shr12$i = 0, $shr123$i$i = 0, $shr15$i = 0, $shr16$i = 0, $shr16$i$148 = 0, $shr19$i = 0, $shr194$i = 0, $shr20$i = 0, $shr214$i$i = 0, $shr253$i$i = 0, $shr263$i$i = 0, $shr267$i$i = 0, $shr27$i = 0, $shr272$i$i = 0, $shr277$i$i = 0, $shr281$i$i = 0, $shr283$i = 0, $shr3 = 0, $shr310$i$i = 0;- var $shr318$i = 0, $shr322$i$i = 0, $shr330$i = 0, $shr335$i = 0, $shr340$i = 0, $shr345$i = 0, $shr349$i = 0, $shr378$i = 0, $shr391$i = 0, $shr4$i = 0, $shr41$i = 0, $shr45 = 0, $shr47 = 0, $shr48 = 0, $shr5$i = 0, $shr5$i$142 = 0, $shr51 = 0, $shr52 = 0, $shr55 = 0, $shr56 = 0;- var $shr58$i$i = 0, $shr59 = 0, $shr60 = 0, $shr63 = 0, $shr68$i$i = 0, $shr7$i = 0, $shr7$i$145 = 0, $shr72$i = 0, $shr72$i$i = 0, $shr75$i = 0, $shr76$i = 0, $shr77$i$i = 0, $shr79$i = 0, $shr8$i = 0, $shr80$i = 0, $shr82$i$i = 0, $shr83$i = 0, $shr84$i = 0, $shr86$i$i = 0, $shr87$i = 0;- var $shr88$i = 0, $shr91$i = 0, $size$i$i = 0, $size$i$i$i = 0, $size$i$i$lcssa = 0, $size188$i = 0, $size188$i$lcssa = 0, $size245$i = 0, $sizebits$0$i = 0, $sizebits$0$shl52$i = 0, $sp$0$i$i = 0, $sp$0$i$i$i = 0, $sp$0108$i = 0, $sp$0108$i$lcssa = 0, $sp$1107$i = 0, $sp$1107$i$lcssa = 0, $ssize$0$i = 0, $ssize$2$ph$i = 0, $ssize$5$i = 0, $sub = 0;- var $sub$i = 0, $sub$i$138 = 0, $sub$i$181 = 0, $sub$i$i = 0, $sub$ptr$lhs$cast$i = 0, $sub$ptr$lhs$cast$i$39$i = 0, $sub$ptr$lhs$cast$i$i = 0, $sub$ptr$rhs$cast$i = 0, $sub$ptr$rhs$cast$i$40$i = 0, $sub$ptr$rhs$cast$i$i = 0, $sub$ptr$sub$i = 0, $sub$ptr$sub$i$41$i = 0, $sub$ptr$sub$i$i = 0, $sub10$i = 0, $sub101$i = 0, $sub101$rsize$4$i = 0, $sub112$i = 0, $sub113$i$i = 0, $sub118$i = 0, $sub14$i = 0;- var $sub16$i$i = 0, $sub160 = 0, $sub172$i = 0, $sub18$i$i = 0, $sub190 = 0, $sub2$i = 0, $sub22$i = 0, $sub260$i = 0, $sub262$i$i = 0, $sub266$i$i = 0, $sub271$i$i = 0, $sub275$i$i = 0, $sub30$i = 0, $sub31$i = 0, $sub31$rsize$0$i = 0, $sub313$i$i = 0, $sub329$i = 0, $sub33$i = 0, $sub334$i = 0, $sub339$i = 0;- var $sub343$i = 0, $sub381$i = 0, $sub4$i = 0, $sub41$i = 0, $sub42 = 0, $sub44 = 0, $sub5$i$27$i = 0, $sub5$i$i = 0, $sub5$i$i$i = 0, $sub50$i = 0, $sub6$i = 0, $sub63$i = 0, $sub67$i = 0, $sub67$i$i = 0, $sub70$i = 0, $sub71$i$i = 0, $sub76$i$i = 0, $sub80$i$i = 0, $sub91 = 0, $sub99$i = 0;- var $t$0$i = 0, $t$0$i$151 = 0, $t$2$i = 0, $t$4$ph$i = 0, $t$4$v$4$i = 0, $t$48$i = 0, $tbase$796$i = 0, $tobool$i$i = 0, $tobool107 = 0, $tobool195$i = 0, $tobool200$i = 0, $tobool228$i$i = 0, $tobool237$i = 0, $tobool293$i = 0, $tobool296$i$i = 0, $tobool30$i = 0, $tobool364$i = 0, $tobool97$i$i = 0, $tsize$795$i = 0, $v$0$i = 0;- var $v$0$i$153 = 0, $v$0$i$lcssa = 0, $v$1$i = 0, $v$3$i = 0, $v$4$lcssa$i = 0, $v$410$i = 0, $xor$i$i = 0, label = 0, sp = 0;- sp = STACKTOP;- $cmp = ($bytes>>>0)<(245);- do {- if ($cmp) {- $cmp1 = ($bytes>>>0)<(11);- $add2 = (($bytes) + 11)|0;- $and = $add2 & -8;- $cond = $cmp1 ? 16 : $and;- $shr = $cond >>> 3;- $0 = HEAP32[44]|0;- $shr3 = $0 >>> $shr;- $and4 = $shr3 & 3;- $cmp5 = ($and4|0)==(0);- if (!($cmp5)) {- $neg = $shr3 & 1;- $and7 = $neg ^ 1;- $add8 = (($and7) + ($shr))|0;- $shl = $add8 << 1;- $arrayidx = (216 + ($shl<<2)|0);- $1 = ((($arrayidx)) + 8|0);- $2 = HEAP32[$1>>2]|0;- $fd9 = ((($2)) + 8|0);- $3 = HEAP32[$fd9>>2]|0;- $cmp10 = ($arrayidx|0)==($3|0);- do {- if ($cmp10) {- $shl12 = 1 << $add8;- $neg13 = $shl12 ^ -1;- $and14 = $0 & $neg13;- HEAP32[44] = $and14;- } else {- $4 = HEAP32[(192)>>2]|0;- $cmp15 = ($3>>>0)<($4>>>0);- if ($cmp15) {- _abort();- // unreachable;- }- $bk = ((($3)) + 12|0);- $5 = HEAP32[$bk>>2]|0;- $cmp16 = ($5|0)==($2|0);- if ($cmp16) {- HEAP32[$bk>>2] = $arrayidx;- HEAP32[$1>>2] = $3;- break;- } else {- _abort();- // unreachable;- }- }- } while(0);- $shl22 = $add8 << 3;- $or23 = $shl22 | 3;- $head = ((($2)) + 4|0);- HEAP32[$head>>2] = $or23;- $add$ptr = (($2) + ($shl22)|0);- $head25 = ((($add$ptr)) + 4|0);- $6 = HEAP32[$head25>>2]|0;- $or26 = $6 | 1;- HEAP32[$head25>>2] = $or26;- $retval$0 = $fd9;- return ($retval$0|0);- }- $7 = HEAP32[(184)>>2]|0;- $cmp29 = ($cond>>>0)>($7>>>0);- if ($cmp29) {- $cmp31 = ($shr3|0)==(0);- if (!($cmp31)) {- $shl35 = $shr3 << $shr;- $shl37 = 2 << $shr;- $sub = (0 - ($shl37))|0;- $or40 = $shl37 | $sub;- $and41 = $shl35 & $or40;- $sub42 = (0 - ($and41))|0;- $and43 = $and41 & $sub42;- $sub44 = (($and43) + -1)|0;- $shr45 = $sub44 >>> 12;- $and46 = $shr45 & 16;- $shr47 = $sub44 >>> $and46;- $shr48 = $shr47 >>> 5;- $and49 = $shr48 & 8;- $add50 = $and49 | $and46;- $shr51 = $shr47 >>> $and49;- $shr52 = $shr51 >>> 2;- $and53 = $shr52 & 4;- $add54 = $add50 | $and53;- $shr55 = $shr51 >>> $and53;- $shr56 = $shr55 >>> 1;- $and57 = $shr56 & 2;- $add58 = $add54 | $and57;- $shr59 = $shr55 >>> $and57;- $shr60 = $shr59 >>> 1;- $and61 = $shr60 & 1;- $add62 = $add58 | $and61;- $shr63 = $shr59 >>> $and61;- $add64 = (($add62) + ($shr63))|0;- $shl65 = $add64 << 1;- $arrayidx66 = (216 + ($shl65<<2)|0);- $8 = ((($arrayidx66)) + 8|0);- $9 = HEAP32[$8>>2]|0;- $fd69 = ((($9)) + 8|0);- $10 = HEAP32[$fd69>>2]|0;- $cmp70 = ($arrayidx66|0)==($10|0);- do {- if ($cmp70) {- $shl72 = 1 << $add64;- $neg73 = $shl72 ^ -1;- $and74 = $0 & $neg73;- HEAP32[44] = $and74;- $13 = $7;- } else {- $11 = HEAP32[(192)>>2]|0;- $cmp76 = ($10>>>0)<($11>>>0);- if ($cmp76) {- _abort();- // unreachable;- }- $bk78 = ((($10)) + 12|0);- $12 = HEAP32[$bk78>>2]|0;- $cmp79 = ($12|0)==($9|0);- if ($cmp79) {- HEAP32[$bk78>>2] = $arrayidx66;- HEAP32[$8>>2] = $10;- $$pre = HEAP32[(184)>>2]|0;- $13 = $$pre;- break;- } else {- _abort();- // unreachable;- }- }- } while(0);- $shl90 = $add64 << 3;- $sub91 = (($shl90) - ($cond))|0;- $or93 = $cond | 3;- $head94 = ((($9)) + 4|0);- HEAP32[$head94>>2] = $or93;- $add$ptr95 = (($9) + ($cond)|0);- $or96 = $sub91 | 1;- $head97 = ((($add$ptr95)) + 4|0);- HEAP32[$head97>>2] = $or96;- $add$ptr98 = (($add$ptr95) + ($sub91)|0);- HEAP32[$add$ptr98>>2] = $sub91;- $cmp99 = ($13|0)==(0);- if (!($cmp99)) {- $14 = HEAP32[(196)>>2]|0;- $shr101 = $13 >>> 3;- $shl102 = $shr101 << 1;- $arrayidx103 = (216 + ($shl102<<2)|0);- $15 = HEAP32[44]|0;- $shl105 = 1 << $shr101;- $and106 = $15 & $shl105;- $tobool107 = ($and106|0)==(0);- if ($tobool107) {- $or110 = $15 | $shl105;- HEAP32[44] = $or110;- $$pre241 = ((($arrayidx103)) + 8|0);- $$pre$phiZ2D = $$pre241;$F104$0 = $arrayidx103;- } else {- $16 = ((($arrayidx103)) + 8|0);- $17 = HEAP32[$16>>2]|0;- $18 = HEAP32[(192)>>2]|0;- $cmp113 = ($17>>>0)<($18>>>0);- if ($cmp113) {- _abort();- // unreachable;- } else {- $$pre$phiZ2D = $16;$F104$0 = $17;- }- }- HEAP32[$$pre$phiZ2D>>2] = $14;- $bk122 = ((($F104$0)) + 12|0);- HEAP32[$bk122>>2] = $14;- $fd123 = ((($14)) + 8|0);- HEAP32[$fd123>>2] = $F104$0;- $bk124 = ((($14)) + 12|0);- HEAP32[$bk124>>2] = $arrayidx103;- }- HEAP32[(184)>>2] = $sub91;- HEAP32[(196)>>2] = $add$ptr95;- $retval$0 = $fd69;- return ($retval$0|0);- }- $19 = HEAP32[(180)>>2]|0;- $cmp128 = ($19|0)==(0);- if ($cmp128) {- $nb$0 = $cond;- } else {- $sub$i = (0 - ($19))|0;- $and$i = $19 & $sub$i;- $sub2$i = (($and$i) + -1)|0;- $shr$i = $sub2$i >>> 12;- $and3$i = $shr$i & 16;- $shr4$i = $sub2$i >>> $and3$i;- $shr5$i = $shr4$i >>> 5;- $and6$i = $shr5$i & 8;- $add$i = $and6$i | $and3$i;- $shr7$i = $shr4$i >>> $and6$i;- $shr8$i = $shr7$i >>> 2;- $and9$i = $shr8$i & 4;- $add10$i = $add$i | $and9$i;- $shr11$i = $shr7$i >>> $and9$i;- $shr12$i = $shr11$i >>> 1;- $and13$i = $shr12$i & 2;- $add14$i = $add10$i | $and13$i;- $shr15$i = $shr11$i >>> $and13$i;- $shr16$i = $shr15$i >>> 1;- $and17$i = $shr16$i & 1;- $add18$i = $add14$i | $and17$i;- $shr19$i = $shr15$i >>> $and17$i;- $add20$i = (($add18$i) + ($shr19$i))|0;- $arrayidx$i = (480 + ($add20$i<<2)|0);- $20 = HEAP32[$arrayidx$i>>2]|0;- $head$i = ((($20)) + 4|0);- $21 = HEAP32[$head$i>>2]|0;- $and21$i = $21 & -8;- $sub22$i = (($and21$i) - ($cond))|0;- $rsize$0$i = $sub22$i;$t$0$i = $20;$v$0$i = $20;- while(1) {- $arrayidx23$i = ((($t$0$i)) + 16|0);- $22 = HEAP32[$arrayidx23$i>>2]|0;- $cmp$i = ($22|0)==(0|0);- if ($cmp$i) {- $arrayidx27$i = ((($t$0$i)) + 20|0);- $23 = HEAP32[$arrayidx27$i>>2]|0;- $cmp28$i = ($23|0)==(0|0);- if ($cmp28$i) {- $rsize$0$i$lcssa = $rsize$0$i;$v$0$i$lcssa = $v$0$i;- break;- } else {- $cond4$i = $23;- }- } else {- $cond4$i = $22;- }- $head29$i = ((($cond4$i)) + 4|0);- $24 = HEAP32[$head29$i>>2]|0;- $and30$i = $24 & -8;- $sub31$i = (($and30$i) - ($cond))|0;- $cmp32$i = ($sub31$i>>>0)<($rsize$0$i>>>0);- $sub31$rsize$0$i = $cmp32$i ? $sub31$i : $rsize$0$i;- $cond$v$0$i = $cmp32$i ? $cond4$i : $v$0$i;- $rsize$0$i = $sub31$rsize$0$i;$t$0$i = $cond4$i;$v$0$i = $cond$v$0$i;- }- $25 = HEAP32[(192)>>2]|0;- $cmp33$i = ($v$0$i$lcssa>>>0)<($25>>>0);- if ($cmp33$i) {- _abort();- // unreachable;- }- $add$ptr$i = (($v$0$i$lcssa) + ($cond)|0);- $cmp35$i = ($v$0$i$lcssa>>>0)<($add$ptr$i>>>0);- if (!($cmp35$i)) {- _abort();- // unreachable;- }- $parent$i = ((($v$0$i$lcssa)) + 24|0);- $26 = HEAP32[$parent$i>>2]|0;- $bk$i = ((($v$0$i$lcssa)) + 12|0);- $27 = HEAP32[$bk$i>>2]|0;- $cmp40$i = ($27|0)==($v$0$i$lcssa|0);- do {- if ($cmp40$i) {- $arrayidx61$i = ((($v$0$i$lcssa)) + 20|0);- $31 = HEAP32[$arrayidx61$i>>2]|0;- $cmp62$i = ($31|0)==(0|0);- if ($cmp62$i) {- $arrayidx65$i = ((($v$0$i$lcssa)) + 16|0);- $32 = HEAP32[$arrayidx65$i>>2]|0;- $cmp66$i = ($32|0)==(0|0);- if ($cmp66$i) {- $R$3$i = 0;- break;- } else {- $R$1$i = $32;$RP$1$i = $arrayidx65$i;- }- } else {- $R$1$i = $31;$RP$1$i = $arrayidx61$i;- }- while(1) {- $arrayidx71$i = ((($R$1$i)) + 20|0);- $33 = HEAP32[$arrayidx71$i>>2]|0;- $cmp72$i = ($33|0)==(0|0);- if (!($cmp72$i)) {- $R$1$i = $33;$RP$1$i = $arrayidx71$i;- continue;- }- $arrayidx75$i = ((($R$1$i)) + 16|0);- $34 = HEAP32[$arrayidx75$i>>2]|0;- $cmp76$i = ($34|0)==(0|0);- if ($cmp76$i) {- $R$1$i$lcssa = $R$1$i;$RP$1$i$lcssa = $RP$1$i;- break;- } else {- $R$1$i = $34;$RP$1$i = $arrayidx75$i;- }- }- $cmp81$i = ($RP$1$i$lcssa>>>0)<($25>>>0);- if ($cmp81$i) {- _abort();- // unreachable;- } else {- HEAP32[$RP$1$i$lcssa>>2] = 0;- $R$3$i = $R$1$i$lcssa;- break;- }- } else {- $fd$i = ((($v$0$i$lcssa)) + 8|0);- $28 = HEAP32[$fd$i>>2]|0;- $cmp45$i = ($28>>>0)<($25>>>0);- if ($cmp45$i) {- _abort();- // unreachable;- }- $bk47$i = ((($28)) + 12|0);- $29 = HEAP32[$bk47$i>>2]|0;- $cmp48$i = ($29|0)==($v$0$i$lcssa|0);- if (!($cmp48$i)) {- _abort();- // unreachable;- }- $fd50$i = ((($27)) + 8|0);- $30 = HEAP32[$fd50$i>>2]|0;- $cmp51$i = ($30|0)==($v$0$i$lcssa|0);- if ($cmp51$i) {- HEAP32[$bk47$i>>2] = $27;- HEAP32[$fd50$i>>2] = $28;- $R$3$i = $27;- break;- } else {- _abort();- // unreachable;- }- }- } while(0);- $cmp90$i = ($26|0)==(0|0);- do {- if (!($cmp90$i)) {- $index$i = ((($v$0$i$lcssa)) + 28|0);- $35 = HEAP32[$index$i>>2]|0;- $arrayidx94$i = (480 + ($35<<2)|0);- $36 = HEAP32[$arrayidx94$i>>2]|0;- $cmp95$i = ($v$0$i$lcssa|0)==($36|0);- if ($cmp95$i) {- HEAP32[$arrayidx94$i>>2] = $R$3$i;- $cond2$i = ($R$3$i|0)==(0|0);- if ($cond2$i) {- $shl$i = 1 << $35;- $neg$i = $shl$i ^ -1;- $37 = HEAP32[(180)>>2]|0;- $and103$i = $37 & $neg$i;- HEAP32[(180)>>2] = $and103$i;- break;- }- } else {- $38 = HEAP32[(192)>>2]|0;- $cmp107$i = ($26>>>0)<($38>>>0);- if ($cmp107$i) {- _abort();- // unreachable;- }- $arrayidx113$i = ((($26)) + 16|0);- $39 = HEAP32[$arrayidx113$i>>2]|0;- $cmp114$i = ($39|0)==($v$0$i$lcssa|0);- if ($cmp114$i) {- HEAP32[$arrayidx113$i>>2] = $R$3$i;- } else {- $arrayidx121$i = ((($26)) + 20|0);- HEAP32[$arrayidx121$i>>2] = $R$3$i;- }- $cmp126$i = ($R$3$i|0)==(0|0);- if ($cmp126$i) {- break;- }- }- $40 = HEAP32[(192)>>2]|0;- $cmp130$i = ($R$3$i>>>0)<($40>>>0);- if ($cmp130$i) {- _abort();- // unreachable;- }- $parent135$i = ((($R$3$i)) + 24|0);- HEAP32[$parent135$i>>2] = $26;- $arrayidx137$i = ((($v$0$i$lcssa)) + 16|0);- $41 = HEAP32[$arrayidx137$i>>2]|0;- $cmp138$i = ($41|0)==(0|0);- do {- if (!($cmp138$i)) {- $cmp142$i = ($41>>>0)<($40>>>0);- if ($cmp142$i) {- _abort();- // unreachable;- } else {- $arrayidx148$i = ((($R$3$i)) + 16|0);- HEAP32[$arrayidx148$i>>2] = $41;- $parent149$i = ((($41)) + 24|0);- HEAP32[$parent149$i>>2] = $R$3$i;- break;- }- }- } while(0);- $arrayidx154$i = ((($v$0$i$lcssa)) + 20|0);- $42 = HEAP32[$arrayidx154$i>>2]|0;- $cmp155$i = ($42|0)==(0|0);- if (!($cmp155$i)) {- $43 = HEAP32[(192)>>2]|0;- $cmp159$i = ($42>>>0)<($43>>>0);- if ($cmp159$i) {- _abort();- // unreachable;- } else {- $arrayidx165$i = ((($R$3$i)) + 20|0);- HEAP32[$arrayidx165$i>>2] = $42;- $parent166$i = ((($42)) + 24|0);- HEAP32[$parent166$i>>2] = $R$3$i;- break;- }- }- }- } while(0);- $cmp174$i = ($rsize$0$i$lcssa>>>0)<(16);- if ($cmp174$i) {- $add177$i = (($rsize$0$i$lcssa) + ($cond))|0;- $or178$i = $add177$i | 3;- $head179$i = ((($v$0$i$lcssa)) + 4|0);- HEAP32[$head179$i>>2] = $or178$i;- $add$ptr181$i = (($v$0$i$lcssa) + ($add177$i)|0);- $head182$i = ((($add$ptr181$i)) + 4|0);- $44 = HEAP32[$head182$i>>2]|0;- $or183$i = $44 | 1;- HEAP32[$head182$i>>2] = $or183$i;- } else {- $or186$i = $cond | 3;- $head187$i = ((($v$0$i$lcssa)) + 4|0);- HEAP32[$head187$i>>2] = $or186$i;- $or188$i = $rsize$0$i$lcssa | 1;- $head189$i = ((($add$ptr$i)) + 4|0);- HEAP32[$head189$i>>2] = $or188$i;- $add$ptr190$i = (($add$ptr$i) + ($rsize$0$i$lcssa)|0);- HEAP32[$add$ptr190$i>>2] = $rsize$0$i$lcssa;- $45 = HEAP32[(184)>>2]|0;- $cmp191$i = ($45|0)==(0);- if (!($cmp191$i)) {- $46 = HEAP32[(196)>>2]|0;- $shr194$i = $45 >>> 3;- $shl195$i = $shr194$i << 1;- $arrayidx196$i = (216 + ($shl195$i<<2)|0);- $47 = HEAP32[44]|0;- $shl198$i = 1 << $shr194$i;- $and199$i = $47 & $shl198$i;- $tobool200$i = ($and199$i|0)==(0);- if ($tobool200$i) {- $or204$i = $47 | $shl198$i;- HEAP32[44] = $or204$i;- $$pre$i = ((($arrayidx196$i)) + 8|0);- $$pre$phi$iZ2D = $$pre$i;$F197$0$i = $arrayidx196$i;- } else {- $48 = ((($arrayidx196$i)) + 8|0);- $49 = HEAP32[$48>>2]|0;- $50 = HEAP32[(192)>>2]|0;- $cmp208$i = ($49>>>0)<($50>>>0);- if ($cmp208$i) {- _abort();- // unreachable;- } else {- $$pre$phi$iZ2D = $48;$F197$0$i = $49;- }- }- HEAP32[$$pre$phi$iZ2D>>2] = $46;- $bk218$i = ((($F197$0$i)) + 12|0);- HEAP32[$bk218$i>>2] = $46;- $fd219$i = ((($46)) + 8|0);- HEAP32[$fd219$i>>2] = $F197$0$i;- $bk220$i = ((($46)) + 12|0);- HEAP32[$bk220$i>>2] = $arrayidx196$i;- }- HEAP32[(184)>>2] = $rsize$0$i$lcssa;- HEAP32[(196)>>2] = $add$ptr$i;- }- $add$ptr225$i = ((($v$0$i$lcssa)) + 8|0);- $retval$0 = $add$ptr225$i;- return ($retval$0|0);- }- } else {- $nb$0 = $cond;- }- } else {- $cmp139 = ($bytes>>>0)>(4294967231);- if ($cmp139) {- $nb$0 = -1;- } else {- $add144 = (($bytes) + 11)|0;- $and145 = $add144 & -8;- $51 = HEAP32[(180)>>2]|0;- $cmp146 = ($51|0)==(0);- if ($cmp146) {- $nb$0 = $and145;- } else {- $sub$i$138 = (0 - ($and145))|0;- $shr$i$139 = $add144 >>> 8;- $cmp$i$140 = ($shr$i$139|0)==(0);- if ($cmp$i$140) {- $idx$0$i = 0;- } else {- $cmp1$i = ($and145>>>0)>(16777215);- if ($cmp1$i) {- $idx$0$i = 31;- } else {- $sub4$i = (($shr$i$139) + 1048320)|0;- $shr5$i$142 = $sub4$i >>> 16;- $and$i$143 = $shr5$i$142 & 8;- $shl$i$144 = $shr$i$139 << $and$i$143;- $sub6$i = (($shl$i$144) + 520192)|0;- $shr7$i$145 = $sub6$i >>> 16;- $and8$i = $shr7$i$145 & 4;- $add$i$146 = $and8$i | $and$i$143;- $shl9$i = $shl$i$144 << $and8$i;- $sub10$i = (($shl9$i) + 245760)|0;- $shr11$i$147 = $sub10$i >>> 16;- $and12$i = $shr11$i$147 & 2;- $add13$i = $add$i$146 | $and12$i;- $sub14$i = (14 - ($add13$i))|0;- $shl15$i = $shl9$i << $and12$i;- $shr16$i$148 = $shl15$i >>> 15;- $add17$i = (($sub14$i) + ($shr16$i$148))|0;- $shl18$i = $add17$i << 1;- $add19$i = (($add17$i) + 7)|0;- $shr20$i = $and145 >>> $add19$i;- $and21$i$149 = $shr20$i & 1;- $add22$i = $and21$i$149 | $shl18$i;- $idx$0$i = $add22$i;- }- }- $arrayidx$i$150 = (480 + ($idx$0$i<<2)|0);- $52 = HEAP32[$arrayidx$i$150>>2]|0;- $cmp24$i = ($52|0)==(0|0);- L123: do {- if ($cmp24$i) {- $rsize$3$i = $sub$i$138;$t$2$i = 0;$v$3$i = 0;- label = 86;- } else {- $cmp26$i = ($idx$0$i|0)==(31);- $shr27$i = $idx$0$i >>> 1;- $sub30$i = (25 - ($shr27$i))|0;- $cond$i = $cmp26$i ? 0 : $sub30$i;- $shl31$i = $and145 << $cond$i;- $rsize$0$i$152 = $sub$i$138;$rst$0$i = 0;$sizebits$0$i = $shl31$i;$t$0$i$151 = $52;$v$0$i$153 = 0;- while(1) {- $head$i$154 = ((($t$0$i$151)) + 4|0);- $53 = HEAP32[$head$i$154>>2]|0;- $and32$i = $53 & -8;- $sub33$i = (($and32$i) - ($and145))|0;- $cmp34$i = ($sub33$i>>>0)<($rsize$0$i$152>>>0);- if ($cmp34$i) {- $cmp36$i = ($and32$i|0)==($and145|0);- if ($cmp36$i) {- $rsize$49$i = $sub33$i;$t$48$i = $t$0$i$151;$v$410$i = $t$0$i$151;- label = 90;- break L123;- } else {- $rsize$1$i = $sub33$i;$v$1$i = $t$0$i$151;- }- } else {- $rsize$1$i = $rsize$0$i$152;$v$1$i = $v$0$i$153;- }- $arrayidx40$i = ((($t$0$i$151)) + 20|0);- $54 = HEAP32[$arrayidx40$i>>2]|0;- $shr41$i = $sizebits$0$i >>> 31;- $arrayidx44$i = (((($t$0$i$151)) + 16|0) + ($shr41$i<<2)|0);- $55 = HEAP32[$arrayidx44$i>>2]|0;- $cmp45$i$155 = ($54|0)==(0|0);- $cmp46$i = ($54|0)==($55|0);- $or$cond1$i = $cmp45$i$155 | $cmp46$i;- $rst$1$i = $or$cond1$i ? $rst$0$i : $54;- $cmp49$i = ($55|0)==(0|0);- $56 = $cmp49$i&1;- $shl52$i = $56 ^ 1;- $sizebits$0$shl52$i = $sizebits$0$i << $shl52$i;- if ($cmp49$i) {- $rsize$3$i = $rsize$1$i;$t$2$i = $rst$1$i;$v$3$i = $v$1$i;- label = 86;- break;- } else {- $rsize$0$i$152 = $rsize$1$i;$rst$0$i = $rst$1$i;$sizebits$0$i = $sizebits$0$shl52$i;$t$0$i$151 = $55;$v$0$i$153 = $v$1$i;- }- }- }- } while(0);- if ((label|0) == 86) {- $cmp55$i = ($t$2$i|0)==(0|0);- $cmp57$i = ($v$3$i|0)==(0|0);- $or$cond$i = $cmp55$i & $cmp57$i;- if ($or$cond$i) {- $shl60$i = 2 << $idx$0$i;- $sub63$i = (0 - ($shl60$i))|0;- $or$i = $shl60$i | $sub63$i;- $and64$i = $51 & $or$i;- $cmp65$i = ($and64$i|0)==(0);- if ($cmp65$i) {- $nb$0 = $and145;- break;- }- $sub67$i = (0 - ($and64$i))|0;- $and68$i = $and64$i & $sub67$i;- $sub70$i = (($and68$i) + -1)|0;- $shr72$i = $sub70$i >>> 12;- $and73$i = $shr72$i & 16;- $shr75$i = $sub70$i >>> $and73$i;- $shr76$i = $shr75$i >>> 5;- $and77$i = $shr76$i & 8;- $add78$i = $and77$i | $and73$i;- $shr79$i = $shr75$i >>> $and77$i;- $shr80$i = $shr79$i >>> 2;- $and81$i = $shr80$i & 4;- $add82$i = $add78$i | $and81$i;- $shr83$i = $shr79$i >>> $and81$i;- $shr84$i = $shr83$i >>> 1;- $and85$i = $shr84$i & 2;- $add86$i = $add82$i | $and85$i;- $shr87$i = $shr83$i >>> $and85$i;- $shr88$i = $shr87$i >>> 1;- $and89$i = $shr88$i & 1;- $add90$i = $add86$i | $and89$i;- $shr91$i = $shr87$i >>> $and89$i;- $add92$i = (($add90$i) + ($shr91$i))|0;- $arrayidx94$i$156 = (480 + ($add92$i<<2)|0);- $57 = HEAP32[$arrayidx94$i$156>>2]|0;- $t$4$ph$i = $57;- } else {- $t$4$ph$i = $t$2$i;- }- $cmp97$7$i = ($t$4$ph$i|0)==(0|0);- if ($cmp97$7$i) {- $rsize$4$lcssa$i = $rsize$3$i;$v$4$lcssa$i = $v$3$i;- } else {- $rsize$49$i = $rsize$3$i;$t$48$i = $t$4$ph$i;$v$410$i = $v$3$i;- label = 90;- }- }- if ((label|0) == 90) {- while(1) {- label = 0;- $head99$i = ((($t$48$i)) + 4|0);- $58 = HEAP32[$head99$i>>2]|0;- $and100$i = $58 & -8;- $sub101$i = (($and100$i) - ($and145))|0;- $cmp102$i = ($sub101$i>>>0)<($rsize$49$i>>>0);- $sub101$rsize$4$i = $cmp102$i ? $sub101$i : $rsize$49$i;- $t$4$v$4$i = $cmp102$i ? $t$48$i : $v$410$i;- $arrayidx106$i = ((($t$48$i)) + 16|0);- $59 = HEAP32[$arrayidx106$i>>2]|0;- $cmp107$i$157 = ($59|0)==(0|0);- if (!($cmp107$i$157)) {- $rsize$49$i = $sub101$rsize$4$i;$t$48$i = $59;$v$410$i = $t$4$v$4$i;- label = 90;- continue;- }- $arrayidx113$i$159 = ((($t$48$i)) + 20|0);- $60 = HEAP32[$arrayidx113$i$159>>2]|0;- $cmp97$i = ($60|0)==(0|0);- if ($cmp97$i) {- $rsize$4$lcssa$i = $sub101$rsize$4$i;$v$4$lcssa$i = $t$4$v$4$i;- break;- } else {- $rsize$49$i = $sub101$rsize$4$i;$t$48$i = $60;$v$410$i = $t$4$v$4$i;- label = 90;- }- }- }- $cmp116$i = ($v$4$lcssa$i|0)==(0|0);- if ($cmp116$i) {- $nb$0 = $and145;- } else {- $61 = HEAP32[(184)>>2]|0;- $sub118$i = (($61) - ($and145))|0;- $cmp119$i = ($rsize$4$lcssa$i>>>0)<($sub118$i>>>0);- if ($cmp119$i) {- $62 = HEAP32[(192)>>2]|0;- $cmp121$i = ($v$4$lcssa$i>>>0)<($62>>>0);- if ($cmp121$i) {- _abort();- // unreachable;- }- $add$ptr$i$161 = (($v$4$lcssa$i) + ($and145)|0);- $cmp123$i = ($v$4$lcssa$i>>>0)<($add$ptr$i$161>>>0);- if (!($cmp123$i)) {- _abort();- // unreachable;- }- $parent$i$162 = ((($v$4$lcssa$i)) + 24|0);- $63 = HEAP32[$parent$i$162>>2]|0;- $bk$i$163 = ((($v$4$lcssa$i)) + 12|0);- $64 = HEAP32[$bk$i$163>>2]|0;- $cmp128$i = ($64|0)==($v$4$lcssa$i|0);- do {- if ($cmp128$i) {- $arrayidx151$i = ((($v$4$lcssa$i)) + 20|0);- $68 = HEAP32[$arrayidx151$i>>2]|0;- $cmp152$i = ($68|0)==(0|0);- if ($cmp152$i) {- $arrayidx155$i = ((($v$4$lcssa$i)) + 16|0);- $69 = HEAP32[$arrayidx155$i>>2]|0;- $cmp156$i = ($69|0)==(0|0);- if ($cmp156$i) {- $R$3$i$171 = 0;- break;- } else {- $R$1$i$168 = $69;$RP$1$i$167 = $arrayidx155$i;- }- } else {- $R$1$i$168 = $68;$RP$1$i$167 = $arrayidx151$i;- }- while(1) {- $arrayidx161$i = ((($R$1$i$168)) + 20|0);- $70 = HEAP32[$arrayidx161$i>>2]|0;- $cmp162$i = ($70|0)==(0|0);- if (!($cmp162$i)) {- $R$1$i$168 = $70;$RP$1$i$167 = $arrayidx161$i;- continue;- }- $arrayidx165$i$169 = ((($R$1$i$168)) + 16|0);- $71 = HEAP32[$arrayidx165$i$169>>2]|0;- $cmp166$i = ($71|0)==(0|0);- if ($cmp166$i) {- $R$1$i$168$lcssa = $R$1$i$168;$RP$1$i$167$lcssa = $RP$1$i$167;- break;- } else {- $R$1$i$168 = $71;$RP$1$i$167 = $arrayidx165$i$169;- }- }- $cmp171$i = ($RP$1$i$167$lcssa>>>0)<($62>>>0);- if ($cmp171$i) {- _abort();- // unreachable;- } else {- HEAP32[$RP$1$i$167$lcssa>>2] = 0;- $R$3$i$171 = $R$1$i$168$lcssa;- break;- }- } else {- $fd$i$164 = ((($v$4$lcssa$i)) + 8|0);- $65 = HEAP32[$fd$i$164>>2]|0;- $cmp133$i = ($65>>>0)<($62>>>0);- if ($cmp133$i) {- _abort();- // unreachable;- }- $bk136$i = ((($65)) + 12|0);- $66 = HEAP32[$bk136$i>>2]|0;- $cmp137$i = ($66|0)==($v$4$lcssa$i|0);- if (!($cmp137$i)) {- _abort();- // unreachable;- }- $fd139$i = ((($64)) + 8|0);- $67 = HEAP32[$fd139$i>>2]|0;- $cmp140$i = ($67|0)==($v$4$lcssa$i|0);- if ($cmp140$i) {- HEAP32[$bk136$i>>2] = $64;- HEAP32[$fd139$i>>2] = $65;- $R$3$i$171 = $64;- break;- } else {- _abort();- // unreachable;- }- }- } while(0);- $cmp180$i = ($63|0)==(0|0);- do {- if (!($cmp180$i)) {- $index$i$172 = ((($v$4$lcssa$i)) + 28|0);- $72 = HEAP32[$index$i$172>>2]|0;- $arrayidx184$i = (480 + ($72<<2)|0);- $73 = HEAP32[$arrayidx184$i>>2]|0;- $cmp185$i = ($v$4$lcssa$i|0)==($73|0);- if ($cmp185$i) {- HEAP32[$arrayidx184$i>>2] = $R$3$i$171;- $cond3$i = ($R$3$i$171|0)==(0|0);- if ($cond3$i) {- $shl192$i = 1 << $72;- $neg$i$173 = $shl192$i ^ -1;- $74 = HEAP32[(180)>>2]|0;- $and194$i = $74 & $neg$i$173;- HEAP32[(180)>>2] = $and194$i;- break;- }- } else {- $75 = HEAP32[(192)>>2]|0;- $cmp198$i = ($63>>>0)<($75>>>0);- if ($cmp198$i) {- _abort();- // unreachable;- }- $arrayidx204$i = ((($63)) + 16|0);- $76 = HEAP32[$arrayidx204$i>>2]|0;- $cmp205$i = ($76|0)==($v$4$lcssa$i|0);- if ($cmp205$i) {- HEAP32[$arrayidx204$i>>2] = $R$3$i$171;- } else {- $arrayidx212$i = ((($63)) + 20|0);- HEAP32[$arrayidx212$i>>2] = $R$3$i$171;- }- $cmp217$i = ($R$3$i$171|0)==(0|0);- if ($cmp217$i) {- break;- }- }- $77 = HEAP32[(192)>>2]|0;- $cmp221$i = ($R$3$i$171>>>0)<($77>>>0);- if ($cmp221$i) {- _abort();- // unreachable;- }- $parent226$i = ((($R$3$i$171)) + 24|0);- HEAP32[$parent226$i>>2] = $63;- $arrayidx228$i = ((($v$4$lcssa$i)) + 16|0);- $78 = HEAP32[$arrayidx228$i>>2]|0;- $cmp229$i = ($78|0)==(0|0);- do {- if (!($cmp229$i)) {- $cmp233$i = ($78>>>0)<($77>>>0);- if ($cmp233$i) {- _abort();- // unreachable;- } else {- $arrayidx239$i = ((($R$3$i$171)) + 16|0);- HEAP32[$arrayidx239$i>>2] = $78;- $parent240$i = ((($78)) + 24|0);- HEAP32[$parent240$i>>2] = $R$3$i$171;- break;- }- }- } while(0);- $arrayidx245$i = ((($v$4$lcssa$i)) + 20|0);- $79 = HEAP32[$arrayidx245$i>>2]|0;- $cmp246$i = ($79|0)==(0|0);- if (!($cmp246$i)) {- $80 = HEAP32[(192)>>2]|0;- $cmp250$i = ($79>>>0)<($80>>>0);- if ($cmp250$i) {- _abort();- // unreachable;- } else {- $arrayidx256$i = ((($R$3$i$171)) + 20|0);- HEAP32[$arrayidx256$i>>2] = $79;- $parent257$i = ((($79)) + 24|0);- HEAP32[$parent257$i>>2] = $R$3$i$171;- break;- }- }- }- } while(0);- $cmp265$i = ($rsize$4$lcssa$i>>>0)<(16);- do {- if ($cmp265$i) {- $add268$i = (($rsize$4$lcssa$i) + ($and145))|0;- $or270$i = $add268$i | 3;- $head271$i = ((($v$4$lcssa$i)) + 4|0);- HEAP32[$head271$i>>2] = $or270$i;- $add$ptr273$i = (($v$4$lcssa$i) + ($add268$i)|0);- $head274$i = ((($add$ptr273$i)) + 4|0);- $81 = HEAP32[$head274$i>>2]|0;- $or275$i = $81 | 1;- HEAP32[$head274$i>>2] = $or275$i;- } else {- $or278$i = $and145 | 3;- $head279$i = ((($v$4$lcssa$i)) + 4|0);- HEAP32[$head279$i>>2] = $or278$i;- $or280$i = $rsize$4$lcssa$i | 1;- $head281$i = ((($add$ptr$i$161)) + 4|0);- HEAP32[$head281$i>>2] = $or280$i;- $add$ptr282$i = (($add$ptr$i$161) + ($rsize$4$lcssa$i)|0);- HEAP32[$add$ptr282$i>>2] = $rsize$4$lcssa$i;- $shr283$i = $rsize$4$lcssa$i >>> 3;- $cmp284$i = ($rsize$4$lcssa$i>>>0)<(256);- if ($cmp284$i) {- $shl288$i = $shr283$i << 1;- $arrayidx289$i = (216 + ($shl288$i<<2)|0);- $82 = HEAP32[44]|0;- $shl291$i = 1 << $shr283$i;- $and292$i = $82 & $shl291$i;- $tobool293$i = ($and292$i|0)==(0);- if ($tobool293$i) {- $or297$i = $82 | $shl291$i;- HEAP32[44] = $or297$i;- $$pre$i$177 = ((($arrayidx289$i)) + 8|0);- $$pre$phi$i$178Z2D = $$pre$i$177;$F290$0$i = $arrayidx289$i;- } else {- $83 = ((($arrayidx289$i)) + 8|0);- $84 = HEAP32[$83>>2]|0;- $85 = HEAP32[(192)>>2]|0;- $cmp301$i = ($84>>>0)<($85>>>0);- if ($cmp301$i) {- _abort();- // unreachable;- } else {- $$pre$phi$i$178Z2D = $83;$F290$0$i = $84;- }- }- HEAP32[$$pre$phi$i$178Z2D>>2] = $add$ptr$i$161;- $bk311$i = ((($F290$0$i)) + 12|0);- HEAP32[$bk311$i>>2] = $add$ptr$i$161;- $fd312$i = ((($add$ptr$i$161)) + 8|0);- HEAP32[$fd312$i>>2] = $F290$0$i;- $bk313$i = ((($add$ptr$i$161)) + 12|0);- HEAP32[$bk313$i>>2] = $arrayidx289$i;- break;- }- $shr318$i = $rsize$4$lcssa$i >>> 8;- $cmp319$i = ($shr318$i|0)==(0);- if ($cmp319$i) {- $I316$0$i = 0;- } else {- $cmp323$i = ($rsize$4$lcssa$i>>>0)>(16777215);- if ($cmp323$i) {- $I316$0$i = 31;- } else {- $sub329$i = (($shr318$i) + 1048320)|0;- $shr330$i = $sub329$i >>> 16;- $and331$i = $shr330$i & 8;- $shl333$i = $shr318$i << $and331$i;- $sub334$i = (($shl333$i) + 520192)|0;- $shr335$i = $sub334$i >>> 16;- $and336$i = $shr335$i & 4;- $add337$i = $and336$i | $and331$i;- $shl338$i = $shl333$i << $and336$i;- $sub339$i = (($shl338$i) + 245760)|0;- $shr340$i = $sub339$i >>> 16;- $and341$i = $shr340$i & 2;- $add342$i = $add337$i | $and341$i;- $sub343$i = (14 - ($add342$i))|0;- $shl344$i = $shl338$i << $and341$i;- $shr345$i = $shl344$i >>> 15;- $add346$i = (($sub343$i) + ($shr345$i))|0;- $shl347$i = $add346$i << 1;- $add348$i = (($add346$i) + 7)|0;- $shr349$i = $rsize$4$lcssa$i >>> $add348$i;- $and350$i = $shr349$i & 1;- $add351$i = $and350$i | $shl347$i;- $I316$0$i = $add351$i;- }- }- $arrayidx355$i = (480 + ($I316$0$i<<2)|0);- $index356$i = ((($add$ptr$i$161)) + 28|0);- HEAP32[$index356$i>>2] = $I316$0$i;- $child357$i = ((($add$ptr$i$161)) + 16|0);- $arrayidx358$i = ((($child357$i)) + 4|0);- HEAP32[$arrayidx358$i>>2] = 0;- HEAP32[$child357$i>>2] = 0;- $86 = HEAP32[(180)>>2]|0;- $shl362$i = 1 << $I316$0$i;- $and363$i = $86 & $shl362$i;- $tobool364$i = ($and363$i|0)==(0);- if ($tobool364$i) {- $or368$i = $86 | $shl362$i;- HEAP32[(180)>>2] = $or368$i;- HEAP32[$arrayidx355$i>>2] = $add$ptr$i$161;- $parent369$i = ((($add$ptr$i$161)) + 24|0);- HEAP32[$parent369$i>>2] = $arrayidx355$i;- $bk370$i = ((($add$ptr$i$161)) + 12|0);- HEAP32[$bk370$i>>2] = $add$ptr$i$161;- $fd371$i = ((($add$ptr$i$161)) + 8|0);- HEAP32[$fd371$i>>2] = $add$ptr$i$161;- break;- }- $87 = HEAP32[$arrayidx355$i>>2]|0;- $cmp374$i = ($I316$0$i|0)==(31);- $shr378$i = $I316$0$i >>> 1;- $sub381$i = (25 - ($shr378$i))|0;- $cond383$i = $cmp374$i ? 0 : $sub381$i;- $shl384$i = $rsize$4$lcssa$i << $cond383$i;- $K373$0$i = $shl384$i;$T$0$i = $87;- while(1) {- $head386$i = ((($T$0$i)) + 4|0);- $88 = HEAP32[$head386$i>>2]|0;- $and387$i = $88 & -8;- $cmp388$i = ($and387$i|0)==($rsize$4$lcssa$i|0);- if ($cmp388$i) {- $T$0$i$lcssa = $T$0$i;- label = 148;- break;- }- $shr391$i = $K373$0$i >>> 31;- $arrayidx394$i = (((($T$0$i)) + 16|0) + ($shr391$i<<2)|0);- $shl395$i = $K373$0$i << 1;- $89 = HEAP32[$arrayidx394$i>>2]|0;- $cmp396$i = ($89|0)==(0|0);- if ($cmp396$i) {- $T$0$i$lcssa293 = $T$0$i;$arrayidx394$i$lcssa = $arrayidx394$i;- label = 145;- break;- } else {- $K373$0$i = $shl395$i;$T$0$i = $89;- }- }- if ((label|0) == 145) {- $90 = HEAP32[(192)>>2]|0;- $cmp401$i = ($arrayidx394$i$lcssa>>>0)<($90>>>0);- if ($cmp401$i) {- _abort();- // unreachable;- } else {- HEAP32[$arrayidx394$i$lcssa>>2] = $add$ptr$i$161;- $parent406$i = ((($add$ptr$i$161)) + 24|0);- HEAP32[$parent406$i>>2] = $T$0$i$lcssa293;- $bk407$i = ((($add$ptr$i$161)) + 12|0);- HEAP32[$bk407$i>>2] = $add$ptr$i$161;- $fd408$i = ((($add$ptr$i$161)) + 8|0);- HEAP32[$fd408$i>>2] = $add$ptr$i$161;- break;- }- }- else if ((label|0) == 148) {- $fd416$i = ((($T$0$i$lcssa)) + 8|0);- $91 = HEAP32[$fd416$i>>2]|0;- $92 = HEAP32[(192)>>2]|0;- $cmp422$i = ($91>>>0)>=($92>>>0);- $not$cmp418$i = ($T$0$i$lcssa>>>0)>=($92>>>0);- $93 = $cmp422$i & $not$cmp418$i;- if ($93) {- $bk429$i = ((($91)) + 12|0);- HEAP32[$bk429$i>>2] = $add$ptr$i$161;- HEAP32[$fd416$i>>2] = $add$ptr$i$161;- $fd431$i = ((($add$ptr$i$161)) + 8|0);- HEAP32[$fd431$i>>2] = $91;- $bk432$i = ((($add$ptr$i$161)) + 12|0);- HEAP32[$bk432$i>>2] = $T$0$i$lcssa;- $parent433$i = ((($add$ptr$i$161)) + 24|0);- HEAP32[$parent433$i>>2] = 0;- break;- } else {- _abort();- // unreachable;- }- }- }- } while(0);- $add$ptr441$i = ((($v$4$lcssa$i)) + 8|0);- $retval$0 = $add$ptr441$i;- return ($retval$0|0);- } else {- $nb$0 = $and145;- }- }- }- }- }- } while(0);- $94 = HEAP32[(184)>>2]|0;- $cmp156 = ($94>>>0)<($nb$0>>>0);- if (!($cmp156)) {- $sub160 = (($94) - ($nb$0))|0;- $95 = HEAP32[(196)>>2]|0;- $cmp162 = ($sub160>>>0)>(15);- if ($cmp162) {- $add$ptr166 = (($95) + ($nb$0)|0);- HEAP32[(196)>>2] = $add$ptr166;- HEAP32[(184)>>2] = $sub160;- $or167 = $sub160 | 1;- $head168 = ((($add$ptr166)) + 4|0);- HEAP32[$head168>>2] = $or167;- $add$ptr169 = (($add$ptr166) + ($sub160)|0);- HEAP32[$add$ptr169>>2] = $sub160;- $or172 = $nb$0 | 3;- $head173 = ((($95)) + 4|0);- HEAP32[$head173>>2] = $or172;- } else {- HEAP32[(184)>>2] = 0;- HEAP32[(196)>>2] = 0;- $or176 = $94 | 3;- $head177 = ((($95)) + 4|0);- HEAP32[$head177>>2] = $or176;- $add$ptr178 = (($95) + ($94)|0);- $head179 = ((($add$ptr178)) + 4|0);- $96 = HEAP32[$head179>>2]|0;- $or180 = $96 | 1;- HEAP32[$head179>>2] = $or180;- }- $add$ptr182 = ((($95)) + 8|0);- $retval$0 = $add$ptr182;- return ($retval$0|0);- }- $97 = HEAP32[(188)>>2]|0;- $cmp186 = ($97>>>0)>($nb$0>>>0);- if ($cmp186) {- $sub190 = (($97) - ($nb$0))|0;- HEAP32[(188)>>2] = $sub190;- $98 = HEAP32[(200)>>2]|0;- $add$ptr193 = (($98) + ($nb$0)|0);- HEAP32[(200)>>2] = $add$ptr193;- $or194 = $sub190 | 1;- $head195 = ((($add$ptr193)) + 4|0);- HEAP32[$head195>>2] = $or194;- $or197 = $nb$0 | 3;- $head198 = ((($98)) + 4|0);- HEAP32[$head198>>2] = $or197;- $add$ptr199 = ((($98)) + 8|0);- $retval$0 = $add$ptr199;- return ($retval$0|0);- }- $99 = HEAP32[162]|0;- $cmp$i$179 = ($99|0)==(0);- do {- if ($cmp$i$179) {- $call$i$i = (_sysconf(30)|0);- $sub$i$i = (($call$i$i) + -1)|0;- $and$i$i = $sub$i$i & $call$i$i;- $cmp1$i$i = ($and$i$i|0)==(0);- if ($cmp1$i$i) {- HEAP32[(656)>>2] = $call$i$i;- HEAP32[(652)>>2] = $call$i$i;- HEAP32[(660)>>2] = -1;- HEAP32[(664)>>2] = -1;- HEAP32[(668)>>2] = 0;- HEAP32[(620)>>2] = 0;- $call6$i$i = (_time((0|0))|0);- $xor$i$i = $call6$i$i & -16;- $and7$i$i = $xor$i$i ^ 1431655768;- HEAP32[162] = $and7$i$i;- break;- } else {- _abort();- // unreachable;- }- }- } while(0);- $add$i$180 = (($nb$0) + 48)|0;- $100 = HEAP32[(656)>>2]|0;- $sub$i$181 = (($nb$0) + 47)|0;- $add9$i = (($100) + ($sub$i$181))|0;- $neg$i$182 = (0 - ($100))|0;- $and11$i = $add9$i & $neg$i$182;- $cmp12$i = ($and11$i>>>0)>($nb$0>>>0);- if (!($cmp12$i)) {- $retval$0 = 0;- return ($retval$0|0);- }- $101 = HEAP32[(616)>>2]|0;- $cmp15$i = ($101|0)==(0);- if (!($cmp15$i)) {- $102 = HEAP32[(608)>>2]|0;- $add17$i$183 = (($102) + ($and11$i))|0;- $cmp19$i = ($add17$i$183>>>0)<=($102>>>0);- $cmp21$i = ($add17$i$183>>>0)>($101>>>0);- $or$cond1$i$184 = $cmp19$i | $cmp21$i;- if ($or$cond1$i$184) {- $retval$0 = 0;- return ($retval$0|0);- }- }- $103 = HEAP32[(620)>>2]|0;- $and29$i = $103 & 4;- $tobool30$i = ($and29$i|0)==(0);- L257: do {- if ($tobool30$i) {- $104 = HEAP32[(200)>>2]|0;- $cmp32$i$185 = ($104|0)==(0|0);- L259: do {- if ($cmp32$i$185) {- label = 173;- } else {- $sp$0$i$i = (624);- while(1) {- $105 = HEAP32[$sp$0$i$i>>2]|0;- $cmp$i$9$i = ($105>>>0)>($104>>>0);- if (!($cmp$i$9$i)) {- $size$i$i = ((($sp$0$i$i)) + 4|0);- $106 = HEAP32[$size$i$i>>2]|0;- $add$ptr$i$i = (($105) + ($106)|0);- $cmp2$i$i = ($add$ptr$i$i>>>0)>($104>>>0);- if ($cmp2$i$i) {- $base$i$i$lcssa = $sp$0$i$i;$size$i$i$lcssa = $size$i$i;- break;- }- }- $next$i$i = ((($sp$0$i$i)) + 8|0);- $107 = HEAP32[$next$i$i>>2]|0;- $cmp3$i$i = ($107|0)==(0|0);- if ($cmp3$i$i) {- label = 173;- break L259;- } else {- $sp$0$i$i = $107;- }- }- $112 = HEAP32[(188)>>2]|0;- $add77$i = (($add9$i) - ($112))|0;- $and80$i = $add77$i & $neg$i$182;- $cmp81$i$191 = ($and80$i>>>0)<(2147483647);- if ($cmp81$i$191) {- $call83$i = (_sbrk(($and80$i|0))|0);- $113 = HEAP32[$base$i$i$lcssa>>2]|0;- $114 = HEAP32[$size$i$i$lcssa>>2]|0;- $add$ptr$i$193 = (($113) + ($114)|0);- $cmp85$i = ($call83$i|0)==($add$ptr$i$193|0);- if ($cmp85$i) {- $cmp89$i = ($call83$i|0)==((-1)|0);- if (!($cmp89$i)) {- $tbase$796$i = $call83$i;$tsize$795$i = $and80$i;- label = 193;- break L257;- }- } else {- $br$2$ph$i = $call83$i;$ssize$2$ph$i = $and80$i;- label = 183;- }- }- }- } while(0);- do {- if ((label|0) == 173) {- $call37$i = (_sbrk(0)|0);- $cmp38$i = ($call37$i|0)==((-1)|0);- if (!($cmp38$i)) {- $108 = $call37$i;- $109 = HEAP32[(652)>>2]|0;- $sub41$i = (($109) + -1)|0;- $and42$i = $sub41$i & $108;- $cmp43$i = ($and42$i|0)==(0);- if ($cmp43$i) {- $ssize$0$i = $and11$i;- } else {- $add46$i = (($sub41$i) + ($108))|0;- $neg48$i = (0 - ($109))|0;- $and49$i = $add46$i & $neg48$i;- $sub50$i = (($and11$i) - ($108))|0;- $add51$i = (($sub50$i) + ($and49$i))|0;- $ssize$0$i = $add51$i;- }- $110 = HEAP32[(608)>>2]|0;- $add54$i = (($110) + ($ssize$0$i))|0;- $cmp55$i$187 = ($ssize$0$i>>>0)>($nb$0>>>0);- $cmp57$i$188 = ($ssize$0$i>>>0)<(2147483647);- $or$cond$i$189 = $cmp55$i$187 & $cmp57$i$188;- if ($or$cond$i$189) {- $111 = HEAP32[(616)>>2]|0;- $cmp60$i = ($111|0)==(0);- if (!($cmp60$i)) {- $cmp63$i = ($add54$i>>>0)<=($110>>>0);- $cmp66$i$190 = ($add54$i>>>0)>($111>>>0);- $or$cond2$i = $cmp63$i | $cmp66$i$190;- if ($or$cond2$i) {- break;- }- }- $call68$i = (_sbrk(($ssize$0$i|0))|0);- $cmp69$i = ($call68$i|0)==($call37$i|0);- if ($cmp69$i) {- $tbase$796$i = $call37$i;$tsize$795$i = $ssize$0$i;- label = 193;- break L257;- } else {- $br$2$ph$i = $call68$i;$ssize$2$ph$i = $ssize$0$i;- label = 183;- }- }- }- }- } while(0);- L279: do {- if ((label|0) == 183) {- $sub112$i = (0 - ($ssize$2$ph$i))|0;- $cmp91$i = ($br$2$ph$i|0)!=((-1)|0);- $cmp93$i = ($ssize$2$ph$i>>>0)<(2147483647);- $or$cond5$i = $cmp93$i & $cmp91$i;- $cmp96$i = ($add$i$180>>>0)>($ssize$2$ph$i>>>0);- $or$cond3$i = $cmp96$i & $or$cond5$i;- do {- if ($or$cond3$i) {- $115 = HEAP32[(656)>>2]|0;- $sub99$i = (($sub$i$181) - ($ssize$2$ph$i))|0;- $add101$i = (($sub99$i) + ($115))|0;- $neg103$i = (0 - ($115))|0;- $and104$i = $add101$i & $neg103$i;- $cmp105$i = ($and104$i>>>0)<(2147483647);- if ($cmp105$i) {- $call107$i = (_sbrk(($and104$i|0))|0);- $cmp108$i = ($call107$i|0)==((-1)|0);- if ($cmp108$i) {- (_sbrk(($sub112$i|0))|0);- break L279;- } else {- $add110$i = (($and104$i) + ($ssize$2$ph$i))|0;- $ssize$5$i = $add110$i;- break;- }- } else {- $ssize$5$i = $ssize$2$ph$i;- }- } else {- $ssize$5$i = $ssize$2$ph$i;- }- } while(0);- $cmp118$i = ($br$2$ph$i|0)==((-1)|0);- if (!($cmp118$i)) {- $tbase$796$i = $br$2$ph$i;$tsize$795$i = $ssize$5$i;- label = 193;- break L257;- }- }- } while(0);- $116 = HEAP32[(620)>>2]|0;- $or$i$195 = $116 | 4;- HEAP32[(620)>>2] = $or$i$195;- label = 190;- } else {- label = 190;- }- } while(0);- if ((label|0) == 190) {- $cmp127$i = ($and11$i>>>0)<(2147483647);- if ($cmp127$i) {- $call131$i = (_sbrk(($and11$i|0))|0);- $call132$i = (_sbrk(0)|0);- $cmp133$i$196 = ($call131$i|0)!=((-1)|0);- $cmp135$i = ($call132$i|0)!=((-1)|0);- $or$cond4$i = $cmp133$i$196 & $cmp135$i;- $cmp137$i$197 = ($call131$i>>>0)<($call132$i>>>0);- $or$cond7$i = $cmp137$i$197 & $or$cond4$i;- if ($or$cond7$i) {- $sub$ptr$lhs$cast$i = $call132$i;- $sub$ptr$rhs$cast$i = $call131$i;- $sub$ptr$sub$i = (($sub$ptr$lhs$cast$i) - ($sub$ptr$rhs$cast$i))|0;- $add140$i = (($nb$0) + 40)|0;- $cmp141$not$i = ($sub$ptr$sub$i>>>0)>($add140$i>>>0);- if ($cmp141$not$i) {- $tbase$796$i = $call131$i;$tsize$795$i = $sub$ptr$sub$i;- label = 193;- }- }- }- }- if ((label|0) == 193) {- $117 = HEAP32[(608)>>2]|0;- $add150$i = (($117) + ($tsize$795$i))|0;- HEAP32[(608)>>2] = $add150$i;- $118 = HEAP32[(612)>>2]|0;- $cmp151$i = ($add150$i>>>0)>($118>>>0);- if ($cmp151$i) {- HEAP32[(612)>>2] = $add150$i;- }- $119 = HEAP32[(200)>>2]|0;- $cmp157$i = ($119|0)==(0|0);- do {- if ($cmp157$i) {- $120 = HEAP32[(192)>>2]|0;- $cmp159$i$199 = ($120|0)==(0|0);- $cmp162$i$200 = ($tbase$796$i>>>0)<($120>>>0);- $or$cond8$i = $cmp159$i$199 | $cmp162$i$200;- if ($or$cond8$i) {- HEAP32[(192)>>2] = $tbase$796$i;- }- HEAP32[(624)>>2] = $tbase$796$i;- HEAP32[(628)>>2] = $tsize$795$i;- HEAP32[(636)>>2] = 0;- $121 = HEAP32[162]|0;- HEAP32[(212)>>2] = $121;- HEAP32[(208)>>2] = -1;- $i$01$i$i = 0;- while(1) {- $shl$i$i = $i$01$i$i << 1;- $arrayidx$i$i = (216 + ($shl$i$i<<2)|0);- $122 = ((($arrayidx$i$i)) + 12|0);- HEAP32[$122>>2] = $arrayidx$i$i;- $123 = ((($arrayidx$i$i)) + 8|0);- HEAP32[$123>>2] = $arrayidx$i$i;- $inc$i$i = (($i$01$i$i) + 1)|0;- $exitcond$i$i = ($inc$i$i|0)==(32);- if ($exitcond$i$i) {- break;- } else {- $i$01$i$i = $inc$i$i;- }- }- $sub172$i = (($tsize$795$i) + -40)|0;- $add$ptr$i$11$i = ((($tbase$796$i)) + 8|0);- $124 = $add$ptr$i$11$i;- $and$i$12$i = $124 & 7;- $cmp$i$13$i = ($and$i$12$i|0)==(0);- $125 = (0 - ($124))|0;- $and3$i$i = $125 & 7;- $cond$i$i = $cmp$i$13$i ? 0 : $and3$i$i;- $add$ptr4$i$i = (($tbase$796$i) + ($cond$i$i)|0);- $sub5$i$i = (($sub172$i) - ($cond$i$i))|0;- HEAP32[(200)>>2] = $add$ptr4$i$i;- HEAP32[(188)>>2] = $sub5$i$i;- $or$i$i = $sub5$i$i | 1;- $head$i$i = ((($add$ptr4$i$i)) + 4|0);- HEAP32[$head$i$i>>2] = $or$i$i;- $add$ptr6$i$i = (($add$ptr4$i$i) + ($sub5$i$i)|0);- $head7$i$i = ((($add$ptr6$i$i)) + 4|0);- HEAP32[$head7$i$i>>2] = 40;- $126 = HEAP32[(664)>>2]|0;- HEAP32[(204)>>2] = $126;- } else {- $sp$0108$i = (624);- while(1) {- $127 = HEAP32[$sp$0108$i>>2]|0;- $size188$i = ((($sp$0108$i)) + 4|0);- $128 = HEAP32[$size188$i>>2]|0;- $add$ptr189$i = (($127) + ($128)|0);- $cmp190$i = ($tbase$796$i|0)==($add$ptr189$i|0);- if ($cmp190$i) {- $$lcssa = $127;$$lcssa290 = $128;$size188$i$lcssa = $size188$i;$sp$0108$i$lcssa = $sp$0108$i;- label = 203;- break;- }- $next$i = ((($sp$0108$i)) + 8|0);- $129 = HEAP32[$next$i>>2]|0;- $cmp186$i = ($129|0)==(0|0);- if ($cmp186$i) {- break;- } else {- $sp$0108$i = $129;- }- }- if ((label|0) == 203) {- $sflags193$i = ((($sp$0108$i$lcssa)) + 12|0);- $130 = HEAP32[$sflags193$i>>2]|0;- $and194$i$204 = $130 & 8;- $tobool195$i = ($and194$i$204|0)==(0);- if ($tobool195$i) {- $cmp203$i = ($119>>>0)>=($$lcssa>>>0);- $cmp209$i = ($119>>>0)<($tbase$796$i>>>0);- $or$cond98$i = $cmp209$i & $cmp203$i;- if ($or$cond98$i) {- $add212$i = (($$lcssa290) + ($tsize$795$i))|0;- HEAP32[$size188$i$lcssa>>2] = $add212$i;- $131 = HEAP32[(188)>>2]|0;- $add$ptr$i$21$i = ((($119)) + 8|0);- $132 = $add$ptr$i$21$i;- $and$i$22$i = $132 & 7;- $cmp$i$23$i = ($and$i$22$i|0)==(0);- $133 = (0 - ($132))|0;- $and3$i$24$i = $133 & 7;- $cond$i$25$i = $cmp$i$23$i ? 0 : $and3$i$24$i;- $add$ptr4$i$26$i = (($119) + ($cond$i$25$i)|0);- $add215$i = (($tsize$795$i) - ($cond$i$25$i))|0;- $sub5$i$27$i = (($add215$i) + ($131))|0;- HEAP32[(200)>>2] = $add$ptr4$i$26$i;- HEAP32[(188)>>2] = $sub5$i$27$i;- $or$i$28$i = $sub5$i$27$i | 1;- $head$i$29$i = ((($add$ptr4$i$26$i)) + 4|0);- HEAP32[$head$i$29$i>>2] = $or$i$28$i;- $add$ptr6$i$30$i = (($add$ptr4$i$26$i) + ($sub5$i$27$i)|0);- $head7$i$31$i = ((($add$ptr6$i$30$i)) + 4|0);- HEAP32[$head7$i$31$i>>2] = 40;- $134 = HEAP32[(664)>>2]|0;- HEAP32[(204)>>2] = $134;- break;- }- }- }- $135 = HEAP32[(192)>>2]|0;- $cmp218$i = ($tbase$796$i>>>0)<($135>>>0);- if ($cmp218$i) {- HEAP32[(192)>>2] = $tbase$796$i;- $150 = $tbase$796$i;- } else {- $150 = $135;- }- $add$ptr227$i = (($tbase$796$i) + ($tsize$795$i)|0);- $sp$1107$i = (624);- while(1) {- $136 = HEAP32[$sp$1107$i>>2]|0;- $cmp228$i = ($136|0)==($add$ptr227$i|0);- if ($cmp228$i) {- $base226$i$lcssa = $sp$1107$i;$sp$1107$i$lcssa = $sp$1107$i;- label = 211;- break;- }- $next231$i = ((($sp$1107$i)) + 8|0);- $137 = HEAP32[$next231$i>>2]|0;- $cmp224$i = ($137|0)==(0|0);- if ($cmp224$i) {- $sp$0$i$i$i = (624);- break;- } else {- $sp$1107$i = $137;- }- }- if ((label|0) == 211) {- $sflags235$i = ((($sp$1107$i$lcssa)) + 12|0);- $138 = HEAP32[$sflags235$i>>2]|0;- $and236$i = $138 & 8;- $tobool237$i = ($and236$i|0)==(0);- if ($tobool237$i) {- HEAP32[$base226$i$lcssa>>2] = $tbase$796$i;- $size245$i = ((($sp$1107$i$lcssa)) + 4|0);- $139 = HEAP32[$size245$i>>2]|0;- $add246$i = (($139) + ($tsize$795$i))|0;- HEAP32[$size245$i>>2] = $add246$i;- $add$ptr$i$32$i = ((($tbase$796$i)) + 8|0);- $140 = $add$ptr$i$32$i;- $and$i$33$i = $140 & 7;- $cmp$i$34$i = ($and$i$33$i|0)==(0);- $141 = (0 - ($140))|0;- $and3$i$35$i = $141 & 7;- $cond$i$36$i = $cmp$i$34$i ? 0 : $and3$i$35$i;- $add$ptr4$i$37$i = (($tbase$796$i) + ($cond$i$36$i)|0);- $add$ptr5$i$i = ((($add$ptr227$i)) + 8|0);- $142 = $add$ptr5$i$i;- $and6$i$38$i = $142 & 7;- $cmp7$i$i = ($and6$i$38$i|0)==(0);- $143 = (0 - ($142))|0;- $and13$i$i = $143 & 7;- $cond15$i$i = $cmp7$i$i ? 0 : $and13$i$i;- $add$ptr16$i$i = (($add$ptr227$i) + ($cond15$i$i)|0);- $sub$ptr$lhs$cast$i$39$i = $add$ptr16$i$i;- $sub$ptr$rhs$cast$i$40$i = $add$ptr4$i$37$i;- $sub$ptr$sub$i$41$i = (($sub$ptr$lhs$cast$i$39$i) - ($sub$ptr$rhs$cast$i$40$i))|0;- $add$ptr17$i$i = (($add$ptr4$i$37$i) + ($nb$0)|0);- $sub18$i$i = (($sub$ptr$sub$i$41$i) - ($nb$0))|0;- $or19$i$i = $nb$0 | 3;- $head$i$42$i = ((($add$ptr4$i$37$i)) + 4|0);- HEAP32[$head$i$42$i>>2] = $or19$i$i;- $cmp20$i$i = ($add$ptr16$i$i|0)==($119|0);- do {- if ($cmp20$i$i) {- $144 = HEAP32[(188)>>2]|0;- $add$i$i = (($144) + ($sub18$i$i))|0;- HEAP32[(188)>>2] = $add$i$i;- HEAP32[(200)>>2] = $add$ptr17$i$i;- $or22$i$i = $add$i$i | 1;- $head23$i$i = ((($add$ptr17$i$i)) + 4|0);- HEAP32[$head23$i$i>>2] = $or22$i$i;- } else {- $145 = HEAP32[(196)>>2]|0;- $cmp24$i$i = ($add$ptr16$i$i|0)==($145|0);- if ($cmp24$i$i) {- $146 = HEAP32[(184)>>2]|0;- $add26$i$i = (($146) + ($sub18$i$i))|0;- HEAP32[(184)>>2] = $add26$i$i;- HEAP32[(196)>>2] = $add$ptr17$i$i;- $or28$i$i = $add26$i$i | 1;- $head29$i$i = ((($add$ptr17$i$i)) + 4|0);- HEAP32[$head29$i$i>>2] = $or28$i$i;- $add$ptr30$i$i = (($add$ptr17$i$i) + ($add26$i$i)|0);- HEAP32[$add$ptr30$i$i>>2] = $add26$i$i;- break;- }- $head32$i$i = ((($add$ptr16$i$i)) + 4|0);- $147 = HEAP32[$head32$i$i>>2]|0;- $and33$i$i = $147 & 3;- $cmp34$i$i = ($and33$i$i|0)==(1);- if ($cmp34$i$i) {- $and37$i$i = $147 & -8;- $shr$i$45$i = $147 >>> 3;- $cmp38$i$i = ($147>>>0)<(256);- L331: do {- if ($cmp38$i$i) {- $fd$i$i = ((($add$ptr16$i$i)) + 8|0);- $148 = HEAP32[$fd$i$i>>2]|0;- $bk$i$46$i = ((($add$ptr16$i$i)) + 12|0);- $149 = HEAP32[$bk$i$46$i>>2]|0;- $shl$i$47$i = $shr$i$45$i << 1;- $arrayidx$i$48$i = (216 + ($shl$i$47$i<<2)|0);- $cmp41$i$i = ($148|0)==($arrayidx$i$48$i|0);- do {- if (!($cmp41$i$i)) {- $cmp42$i$i = ($148>>>0)<($150>>>0);- if ($cmp42$i$i) {- _abort();- // unreachable;- }- $bk43$i$i = ((($148)) + 12|0);- $151 = HEAP32[$bk43$i$i>>2]|0;- $cmp44$i$i = ($151|0)==($add$ptr16$i$i|0);- if ($cmp44$i$i) {- break;- }- _abort();- // unreachable;- }- } while(0);- $cmp46$i$49$i = ($149|0)==($148|0);- if ($cmp46$i$49$i) {- $shl48$i$i = 1 << $shr$i$45$i;- $neg$i$i = $shl48$i$i ^ -1;- $152 = HEAP32[44]|0;- $and49$i$i = $152 & $neg$i$i;- HEAP32[44] = $and49$i$i;- break;- }- $cmp54$i$i = ($149|0)==($arrayidx$i$48$i|0);- do {- if ($cmp54$i$i) {- $$pre5$i$i = ((($149)) + 8|0);- $fd68$pre$phi$i$iZ2D = $$pre5$i$i;- } else {- $cmp57$i$i = ($149>>>0)<($150>>>0);- if ($cmp57$i$i) {- _abort();- // unreachable;- }- $fd59$i$i = ((($149)) + 8|0);- $153 = HEAP32[$fd59$i$i>>2]|0;- $cmp60$i$i = ($153|0)==($add$ptr16$i$i|0);- if ($cmp60$i$i) {- $fd68$pre$phi$i$iZ2D = $fd59$i$i;- break;- }- _abort();- // unreachable;- }- } while(0);- $bk67$i$i = ((($148)) + 12|0);- HEAP32[$bk67$i$i>>2] = $149;- HEAP32[$fd68$pre$phi$i$iZ2D>>2] = $148;- } else {- $parent$i$51$i = ((($add$ptr16$i$i)) + 24|0);- $154 = HEAP32[$parent$i$51$i>>2]|0;- $bk74$i$i = ((($add$ptr16$i$i)) + 12|0);- $155 = HEAP32[$bk74$i$i>>2]|0;- $cmp75$i$i = ($155|0)==($add$ptr16$i$i|0);- do {- if ($cmp75$i$i) {- $child$i$i = ((($add$ptr16$i$i)) + 16|0);- $arrayidx96$i$i = ((($child$i$i)) + 4|0);- $159 = HEAP32[$arrayidx96$i$i>>2]|0;- $cmp97$i$i = ($159|0)==(0|0);- if ($cmp97$i$i) {- $160 = HEAP32[$child$i$i>>2]|0;- $cmp100$i$i = ($160|0)==(0|0);- if ($cmp100$i$i) {- $R$3$i$i = 0;- break;- } else {- $R$1$i$i = $160;$RP$1$i$i = $child$i$i;- }- } else {- $R$1$i$i = $159;$RP$1$i$i = $arrayidx96$i$i;- }- while(1) {- $arrayidx103$i$i = ((($R$1$i$i)) + 20|0);- $161 = HEAP32[$arrayidx103$i$i>>2]|0;- $cmp104$i$i = ($161|0)==(0|0);- if (!($cmp104$i$i)) {- $R$1$i$i = $161;$RP$1$i$i = $arrayidx103$i$i;- continue;- }- $arrayidx107$i$i = ((($R$1$i$i)) + 16|0);- $162 = HEAP32[$arrayidx107$i$i>>2]|0;- $cmp108$i$i = ($162|0)==(0|0);- if ($cmp108$i$i) {- $R$1$i$i$lcssa = $R$1$i$i;$RP$1$i$i$lcssa = $RP$1$i$i;- break;- } else {- $R$1$i$i = $162;$RP$1$i$i = $arrayidx107$i$i;- }- }- $cmp112$i$i = ($RP$1$i$i$lcssa>>>0)<($150>>>0);- if ($cmp112$i$i) {- _abort();- // unreachable;- } else {- HEAP32[$RP$1$i$i$lcssa>>2] = 0;- $R$3$i$i = $R$1$i$i$lcssa;- break;- }- } else {- $fd78$i$i = ((($add$ptr16$i$i)) + 8|0);- $156 = HEAP32[$fd78$i$i>>2]|0;- $cmp81$i$i = ($156>>>0)<($150>>>0);- if ($cmp81$i$i) {- _abort();- // unreachable;- }- $bk82$i$i = ((($156)) + 12|0);- $157 = HEAP32[$bk82$i$i>>2]|0;- $cmp83$i$i = ($157|0)==($add$ptr16$i$i|0);- if (!($cmp83$i$i)) {- _abort();- // unreachable;- }- $fd85$i$i = ((($155)) + 8|0);- $158 = HEAP32[$fd85$i$i>>2]|0;- $cmp86$i$i = ($158|0)==($add$ptr16$i$i|0);- if ($cmp86$i$i) {- HEAP32[$bk82$i$i>>2] = $155;- HEAP32[$fd85$i$i>>2] = $156;- $R$3$i$i = $155;- break;- } else {- _abort();- // unreachable;- }- }- } while(0);- $cmp120$i$53$i = ($154|0)==(0|0);- if ($cmp120$i$53$i) {- break;- }- $index$i$54$i = ((($add$ptr16$i$i)) + 28|0);- $163 = HEAP32[$index$i$54$i>>2]|0;- $arrayidx123$i$i = (480 + ($163<<2)|0);- $164 = HEAP32[$arrayidx123$i$i>>2]|0;- $cmp124$i$i = ($add$ptr16$i$i|0)==($164|0);- do {- if ($cmp124$i$i) {- HEAP32[$arrayidx123$i$i>>2] = $R$3$i$i;- $cond2$i$i = ($R$3$i$i|0)==(0|0);- if (!($cond2$i$i)) {- break;- }- $shl131$i$i = 1 << $163;- $neg132$i$i = $shl131$i$i ^ -1;- $165 = HEAP32[(180)>>2]|0;- $and133$i$i = $165 & $neg132$i$i;- HEAP32[(180)>>2] = $and133$i$i;- break L331;- } else {- $166 = HEAP32[(192)>>2]|0;- $cmp137$i$i = ($154>>>0)<($166>>>0);- if ($cmp137$i$i) {- _abort();- // unreachable;- }- $arrayidx143$i$i = ((($154)) + 16|0);- $167 = HEAP32[$arrayidx143$i$i>>2]|0;- $cmp144$i$i = ($167|0)==($add$ptr16$i$i|0);- if ($cmp144$i$i) {- HEAP32[$arrayidx143$i$i>>2] = $R$3$i$i;- } else {- $arrayidx151$i$i = ((($154)) + 20|0);- HEAP32[$arrayidx151$i$i>>2] = $R$3$i$i;- }- $cmp156$i$i = ($R$3$i$i|0)==(0|0);- if ($cmp156$i$i) {- break L331;- }- }- } while(0);- $168 = HEAP32[(192)>>2]|0;- $cmp160$i$i = ($R$3$i$i>>>0)<($168>>>0);- if ($cmp160$i$i) {- _abort();- // unreachable;- }- $parent165$i$i = ((($R$3$i$i)) + 24|0);- HEAP32[$parent165$i$i>>2] = $154;- $child166$i$i = ((($add$ptr16$i$i)) + 16|0);- $169 = HEAP32[$child166$i$i>>2]|0;- $cmp168$i$i = ($169|0)==(0|0);- do {- if (!($cmp168$i$i)) {- $cmp172$i$i = ($169>>>0)<($168>>>0);- if ($cmp172$i$i) {- _abort();- // unreachable;- } else {- $arrayidx178$i$i = ((($R$3$i$i)) + 16|0);- HEAP32[$arrayidx178$i$i>>2] = $169;- $parent179$i$i = ((($169)) + 24|0);- HEAP32[$parent179$i$i>>2] = $R$3$i$i;- break;- }- }- } while(0);- $arrayidx184$i$i = ((($child166$i$i)) + 4|0);- $170 = HEAP32[$arrayidx184$i$i>>2]|0;- $cmp185$i$i = ($170|0)==(0|0);- if ($cmp185$i$i) {- break;- }- $171 = HEAP32[(192)>>2]|0;- $cmp189$i$i = ($170>>>0)<($171>>>0);- if ($cmp189$i$i) {- _abort();- // unreachable;- } else {- $arrayidx195$i$i = ((($R$3$i$i)) + 20|0);- HEAP32[$arrayidx195$i$i>>2] = $170;- $parent196$i$i = ((($170)) + 24|0);- HEAP32[$parent196$i$i>>2] = $R$3$i$i;- break;- }- }- } while(0);- $add$ptr205$i$i = (($add$ptr16$i$i) + ($and37$i$i)|0);- $add206$i$i = (($and37$i$i) + ($sub18$i$i))|0;- $oldfirst$0$i$i = $add$ptr205$i$i;$qsize$0$i$i = $add206$i$i;- } else {- $oldfirst$0$i$i = $add$ptr16$i$i;$qsize$0$i$i = $sub18$i$i;- }- $head208$i$i = ((($oldfirst$0$i$i)) + 4|0);- $172 = HEAP32[$head208$i$i>>2]|0;- $and209$i$i = $172 & -2;- HEAP32[$head208$i$i>>2] = $and209$i$i;- $or210$i$i = $qsize$0$i$i | 1;- $head211$i$i = ((($add$ptr17$i$i)) + 4|0);- HEAP32[$head211$i$i>>2] = $or210$i$i;- $add$ptr212$i$i = (($add$ptr17$i$i) + ($qsize$0$i$i)|0);- HEAP32[$add$ptr212$i$i>>2] = $qsize$0$i$i;- $shr214$i$i = $qsize$0$i$i >>> 3;- $cmp215$i$i = ($qsize$0$i$i>>>0)<(256);- if ($cmp215$i$i) {- $shl221$i$i = $shr214$i$i << 1;- $arrayidx223$i$i = (216 + ($shl221$i$i<<2)|0);- $173 = HEAP32[44]|0;- $shl226$i$i = 1 << $shr214$i$i;- $and227$i$i = $173 & $shl226$i$i;- $tobool228$i$i = ($and227$i$i|0)==(0);- do {- if ($tobool228$i$i) {- $or232$i$i = $173 | $shl226$i$i;- HEAP32[44] = $or232$i$i;- $$pre$i$56$i = ((($arrayidx223$i$i)) + 8|0);- $$pre$phi$i$57$iZ2D = $$pre$i$56$i;$F224$0$i$i = $arrayidx223$i$i;- } else {- $174 = ((($arrayidx223$i$i)) + 8|0);- $175 = HEAP32[$174>>2]|0;- $176 = HEAP32[(192)>>2]|0;- $cmp236$i$i = ($175>>>0)<($176>>>0);- if (!($cmp236$i$i)) {- $$pre$phi$i$57$iZ2D = $174;$F224$0$i$i = $175;- break;- }- _abort();- // unreachable;- }- } while(0);- HEAP32[$$pre$phi$i$57$iZ2D>>2] = $add$ptr17$i$i;- $bk246$i$i = ((($F224$0$i$i)) + 12|0);- HEAP32[$bk246$i$i>>2] = $add$ptr17$i$i;- $fd247$i$i = ((($add$ptr17$i$i)) + 8|0);- HEAP32[$fd247$i$i>>2] = $F224$0$i$i;- $bk248$i$i = ((($add$ptr17$i$i)) + 12|0);- HEAP32[$bk248$i$i>>2] = $arrayidx223$i$i;- break;- }- $shr253$i$i = $qsize$0$i$i >>> 8;- $cmp254$i$i = ($shr253$i$i|0)==(0);- do {- if ($cmp254$i$i) {- $I252$0$i$i = 0;- } else {- $cmp258$i$i = ($qsize$0$i$i>>>0)>(16777215);- if ($cmp258$i$i) {- $I252$0$i$i = 31;- break;- }- $sub262$i$i = (($shr253$i$i) + 1048320)|0;- $shr263$i$i = $sub262$i$i >>> 16;- $and264$i$i = $shr263$i$i & 8;- $shl265$i$i = $shr253$i$i << $and264$i$i;- $sub266$i$i = (($shl265$i$i) + 520192)|0;- $shr267$i$i = $sub266$i$i >>> 16;- $and268$i$i = $shr267$i$i & 4;- $add269$i$i = $and268$i$i | $and264$i$i;- $shl270$i$i = $shl265$i$i << $and268$i$i;- $sub271$i$i = (($shl270$i$i) + 245760)|0;- $shr272$i$i = $sub271$i$i >>> 16;- $and273$i$i = $shr272$i$i & 2;- $add274$i$i = $add269$i$i | $and273$i$i;- $sub275$i$i = (14 - ($add274$i$i))|0;- $shl276$i$i = $shl270$i$i << $and273$i$i;- $shr277$i$i = $shl276$i$i >>> 15;- $add278$i$i = (($sub275$i$i) + ($shr277$i$i))|0;- $shl279$i$i = $add278$i$i << 1;- $add280$i$i = (($add278$i$i) + 7)|0;- $shr281$i$i = $qsize$0$i$i >>> $add280$i$i;- $and282$i$i = $shr281$i$i & 1;- $add283$i$i = $and282$i$i | $shl279$i$i;- $I252$0$i$i = $add283$i$i;- }- } while(0);- $arrayidx287$i$i = (480 + ($I252$0$i$i<<2)|0);- $index288$i$i = ((($add$ptr17$i$i)) + 28|0);- HEAP32[$index288$i$i>>2] = $I252$0$i$i;- $child289$i$i = ((($add$ptr17$i$i)) + 16|0);- $arrayidx290$i$i = ((($child289$i$i)) + 4|0);- HEAP32[$arrayidx290$i$i>>2] = 0;- HEAP32[$child289$i$i>>2] = 0;- $177 = HEAP32[(180)>>2]|0;- $shl294$i$i = 1 << $I252$0$i$i;- $and295$i$i = $177 & $shl294$i$i;- $tobool296$i$i = ($and295$i$i|0)==(0);- if ($tobool296$i$i) {- $or300$i$i = $177 | $shl294$i$i;- HEAP32[(180)>>2] = $or300$i$i;- HEAP32[$arrayidx287$i$i>>2] = $add$ptr17$i$i;- $parent301$i$i = ((($add$ptr17$i$i)) + 24|0);- HEAP32[$parent301$i$i>>2] = $arrayidx287$i$i;- $bk302$i$i = ((($add$ptr17$i$i)) + 12|0);- HEAP32[$bk302$i$i>>2] = $add$ptr17$i$i;- $fd303$i$i = ((($add$ptr17$i$i)) + 8|0);- HEAP32[$fd303$i$i>>2] = $add$ptr17$i$i;- break;- }- $178 = HEAP32[$arrayidx287$i$i>>2]|0;- $cmp306$i$i = ($I252$0$i$i|0)==(31);- $shr310$i$i = $I252$0$i$i >>> 1;- $sub313$i$i = (25 - ($shr310$i$i))|0;- $cond315$i$i = $cmp306$i$i ? 0 : $sub313$i$i;- $shl316$i$i = $qsize$0$i$i << $cond315$i$i;- $K305$0$i$i = $shl316$i$i;$T$0$i$58$i = $178;- while(1) {- $head317$i$i = ((($T$0$i$58$i)) + 4|0);- $179 = HEAP32[$head317$i$i>>2]|0;- $and318$i$i = $179 & -8;- $cmp319$i$i = ($and318$i$i|0)==($qsize$0$i$i|0);- if ($cmp319$i$i) {- $T$0$i$58$i$lcssa = $T$0$i$58$i;- label = 281;- break;- }- $shr322$i$i = $K305$0$i$i >>> 31;- $arrayidx325$i$i = (((($T$0$i$58$i)) + 16|0) + ($shr322$i$i<<2)|0);- $shl326$i$i = $K305$0$i$i << 1;- $180 = HEAP32[$arrayidx325$i$i>>2]|0;- $cmp327$i$i = ($180|0)==(0|0);- if ($cmp327$i$i) {- $T$0$i$58$i$lcssa283 = $T$0$i$58$i;$arrayidx325$i$i$lcssa = $arrayidx325$i$i;- label = 278;- break;- } else {- $K305$0$i$i = $shl326$i$i;$T$0$i$58$i = $180;- }- }- if ((label|0) == 278) {- $181 = HEAP32[(192)>>2]|0;- $cmp332$i$i = ($arrayidx325$i$i$lcssa>>>0)<($181>>>0);- if ($cmp332$i$i) {- _abort();- // unreachable;- } else {- HEAP32[$arrayidx325$i$i$lcssa>>2] = $add$ptr17$i$i;- $parent337$i$i = ((($add$ptr17$i$i)) + 24|0);- HEAP32[$parent337$i$i>>2] = $T$0$i$58$i$lcssa283;- $bk338$i$i = ((($add$ptr17$i$i)) + 12|0);- HEAP32[$bk338$i$i>>2] = $add$ptr17$i$i;- $fd339$i$i = ((($add$ptr17$i$i)) + 8|0);- HEAP32[$fd339$i$i>>2] = $add$ptr17$i$i;- break;- }- }- else if ((label|0) == 281) {- $fd344$i$i = ((($T$0$i$58$i$lcssa)) + 8|0);- $182 = HEAP32[$fd344$i$i>>2]|0;- $183 = HEAP32[(192)>>2]|0;- $cmp350$i$i = ($182>>>0)>=($183>>>0);- $not$cmp346$i$i = ($T$0$i$58$i$lcssa>>>0)>=($183>>>0);- $184 = $cmp350$i$i & $not$cmp346$i$i;- if ($184) {- $bk357$i$i = ((($182)) + 12|0);- HEAP32[$bk357$i$i>>2] = $add$ptr17$i$i;- HEAP32[$fd344$i$i>>2] = $add$ptr17$i$i;- $fd359$i$i = ((($add$ptr17$i$i)) + 8|0);- HEAP32[$fd359$i$i>>2] = $182;- $bk360$i$i = ((($add$ptr17$i$i)) + 12|0);- HEAP32[$bk360$i$i>>2] = $T$0$i$58$i$lcssa;- $parent361$i$i = ((($add$ptr17$i$i)) + 24|0);- HEAP32[$parent361$i$i>>2] = 0;- break;- } else {- _abort();- // unreachable;- }- }- }- } while(0);- $add$ptr369$i$i = ((($add$ptr4$i$37$i)) + 8|0);- $retval$0 = $add$ptr369$i$i;- return ($retval$0|0);- } else {- $sp$0$i$i$i = (624);- }- }- while(1) {- $185 = HEAP32[$sp$0$i$i$i>>2]|0;- $cmp$i$i$i = ($185>>>0)>($119>>>0);- if (!($cmp$i$i$i)) {- $size$i$i$i = ((($sp$0$i$i$i)) + 4|0);- $186 = HEAP32[$size$i$i$i>>2]|0;- $add$ptr$i$i$i = (($185) + ($186)|0);- $cmp2$i$i$i = ($add$ptr$i$i$i>>>0)>($119>>>0);- if ($cmp2$i$i$i) {- $add$ptr$i$i$i$lcssa = $add$ptr$i$i$i;- break;- }- }- $next$i$i$i = ((($sp$0$i$i$i)) + 8|0);- $187 = HEAP32[$next$i$i$i>>2]|0;- $sp$0$i$i$i = $187;- }- $add$ptr2$i$i = ((($add$ptr$i$i$i$lcssa)) + -47|0);- $add$ptr3$i$i = ((($add$ptr2$i$i)) + 8|0);- $188 = $add$ptr3$i$i;- $and$i$14$i = $188 & 7;- $cmp$i$15$i = ($and$i$14$i|0)==(0);- $189 = (0 - ($188))|0;- $and6$i$i = $189 & 7;- $cond$i$16$i = $cmp$i$15$i ? 0 : $and6$i$i;- $add$ptr7$i$i = (($add$ptr2$i$i) + ($cond$i$16$i)|0);- $add$ptr8$i122$i = ((($119)) + 16|0);- $cmp9$i$i = ($add$ptr7$i$i>>>0)<($add$ptr8$i122$i>>>0);- $cond13$i$i = $cmp9$i$i ? $119 : $add$ptr7$i$i;- $add$ptr14$i$i = ((($cond13$i$i)) + 8|0);- $add$ptr15$i$i = ((($cond13$i$i)) + 24|0);- $sub16$i$i = (($tsize$795$i) + -40)|0;- $add$ptr$i$1$i$i = ((($tbase$796$i)) + 8|0);- $190 = $add$ptr$i$1$i$i;- $and$i$i$i = $190 & 7;- $cmp$i$2$i$i = ($and$i$i$i|0)==(0);- $191 = (0 - ($190))|0;- $and3$i$i$i = $191 & 7;- $cond$i$i$i = $cmp$i$2$i$i ? 0 : $and3$i$i$i;- $add$ptr4$i$i$i = (($tbase$796$i) + ($cond$i$i$i)|0);- $sub5$i$i$i = (($sub16$i$i) - ($cond$i$i$i))|0;- HEAP32[(200)>>2] = $add$ptr4$i$i$i;- HEAP32[(188)>>2] = $sub5$i$i$i;- $or$i$i$i = $sub5$i$i$i | 1;- $head$i$i$i = ((($add$ptr4$i$i$i)) + 4|0);- HEAP32[$head$i$i$i>>2] = $or$i$i$i;- $add$ptr6$i$i$i = (($add$ptr4$i$i$i) + ($sub5$i$i$i)|0);- $head7$i$i$i = ((($add$ptr6$i$i$i)) + 4|0);- HEAP32[$head7$i$i$i>>2] = 40;- $192 = HEAP32[(664)>>2]|0;- HEAP32[(204)>>2] = $192;- $head$i$17$i = ((($cond13$i$i)) + 4|0);- HEAP32[$head$i$17$i>>2] = 27;- ;HEAP32[$add$ptr14$i$i>>2]=HEAP32[(624)>>2]|0;HEAP32[$add$ptr14$i$i+4>>2]=HEAP32[(624)+4>>2]|0;HEAP32[$add$ptr14$i$i+8>>2]=HEAP32[(624)+8>>2]|0;HEAP32[$add$ptr14$i$i+12>>2]=HEAP32[(624)+12>>2]|0;- HEAP32[(624)>>2] = $tbase$796$i;- HEAP32[(628)>>2] = $tsize$795$i;- HEAP32[(636)>>2] = 0;- HEAP32[(632)>>2] = $add$ptr14$i$i;- $p$0$i$i = $add$ptr15$i$i;- while(1) {- $add$ptr24$i$i = ((($p$0$i$i)) + 4|0);- HEAP32[$add$ptr24$i$i>>2] = 7;- $193 = ((($add$ptr24$i$i)) + 4|0);- $cmp27$i$i = ($193>>>0)<($add$ptr$i$i$i$lcssa>>>0);- if ($cmp27$i$i) {- $p$0$i$i = $add$ptr24$i$i;- } else {- break;- }- }- $cmp28$i$i = ($cond13$i$i|0)==($119|0);- if (!($cmp28$i$i)) {- $sub$ptr$lhs$cast$i$i = $cond13$i$i;- $sub$ptr$rhs$cast$i$i = $119;- $sub$ptr$sub$i$i = (($sub$ptr$lhs$cast$i$i) - ($sub$ptr$rhs$cast$i$i))|0;- $194 = HEAP32[$head$i$17$i>>2]|0;- $and32$i$i = $194 & -2;- HEAP32[$head$i$17$i>>2] = $and32$i$i;- $or33$i$i = $sub$ptr$sub$i$i | 1;- $head34$i$i = ((($119)) + 4|0);- HEAP32[$head34$i$i>>2] = $or33$i$i;- HEAP32[$cond13$i$i>>2] = $sub$ptr$sub$i$i;- $shr$i$i = $sub$ptr$sub$i$i >>> 3;- $cmp36$i$i = ($sub$ptr$sub$i$i>>>0)<(256);- if ($cmp36$i$i) {- $shl$i$19$i = $shr$i$i << 1;- $arrayidx$i$20$i = (216 + ($shl$i$19$i<<2)|0);- $195 = HEAP32[44]|0;- $shl39$i$i = 1 << $shr$i$i;- $and40$i$i = $195 & $shl39$i$i;- $tobool$i$i = ($and40$i$i|0)==(0);- if ($tobool$i$i) {- $or44$i$i = $195 | $shl39$i$i;- HEAP32[44] = $or44$i$i;- $$pre$i$i = ((($arrayidx$i$20$i)) + 8|0);- $$pre$phi$i$iZ2D = $$pre$i$i;$F$0$i$i = $arrayidx$i$20$i;- } else {- $196 = ((($arrayidx$i$20$i)) + 8|0);- $197 = HEAP32[$196>>2]|0;- $198 = HEAP32[(192)>>2]|0;- $cmp46$i$i = ($197>>>0)<($198>>>0);- if ($cmp46$i$i) {- _abort();- // unreachable;- } else {- $$pre$phi$i$iZ2D = $196;$F$0$i$i = $197;- }- }- HEAP32[$$pre$phi$i$iZ2D>>2] = $119;- $bk$i$i = ((($F$0$i$i)) + 12|0);- HEAP32[$bk$i$i>>2] = $119;- $fd54$i$i = ((($119)) + 8|0);- HEAP32[$fd54$i$i>>2] = $F$0$i$i;- $bk55$i$i = ((($119)) + 12|0);- HEAP32[$bk55$i$i>>2] = $arrayidx$i$20$i;- break;- }- $shr58$i$i = $sub$ptr$sub$i$i >>> 8;- $cmp59$i$i = ($shr58$i$i|0)==(0);- if ($cmp59$i$i) {- $I57$0$i$i = 0;- } else {- $cmp63$i$i = ($sub$ptr$sub$i$i>>>0)>(16777215);- if ($cmp63$i$i) {- $I57$0$i$i = 31;- } else {- $sub67$i$i = (($shr58$i$i) + 1048320)|0;- $shr68$i$i = $sub67$i$i >>> 16;- $and69$i$i = $shr68$i$i & 8;- $shl70$i$i = $shr58$i$i << $and69$i$i;- $sub71$i$i = (($shl70$i$i) + 520192)|0;- $shr72$i$i = $sub71$i$i >>> 16;- $and73$i$i = $shr72$i$i & 4;- $add74$i$i = $and73$i$i | $and69$i$i;- $shl75$i$i = $shl70$i$i << $and73$i$i;- $sub76$i$i = (($shl75$i$i) + 245760)|0;- $shr77$i$i = $sub76$i$i >>> 16;- $and78$i$i = $shr77$i$i & 2;- $add79$i$i = $add74$i$i | $and78$i$i;- $sub80$i$i = (14 - ($add79$i$i))|0;- $shl81$i$i = $shl75$i$i << $and78$i$i;- $shr82$i$i = $shl81$i$i >>> 15;- $add83$i$i = (($sub80$i$i) + ($shr82$i$i))|0;- $shl84$i$i = $add83$i$i << 1;- $add85$i$i = (($add83$i$i) + 7)|0;- $shr86$i$i = $sub$ptr$sub$i$i >>> $add85$i$i;- $and87$i$i = $shr86$i$i & 1;- $add88$i$i = $and87$i$i | $shl84$i$i;- $I57$0$i$i = $add88$i$i;- }- }- $arrayidx91$i$i = (480 + ($I57$0$i$i<<2)|0);- $index$i$i = ((($119)) + 28|0);- HEAP32[$index$i$i>>2] = $I57$0$i$i;- $arrayidx92$i$i = ((($119)) + 20|0);- HEAP32[$arrayidx92$i$i>>2] = 0;- HEAP32[$add$ptr8$i122$i>>2] = 0;- $199 = HEAP32[(180)>>2]|0;- $shl95$i$i = 1 << $I57$0$i$i;- $and96$i$i = $199 & $shl95$i$i;- $tobool97$i$i = ($and96$i$i|0)==(0);- if ($tobool97$i$i) {- $or101$i$i = $199 | $shl95$i$i;- HEAP32[(180)>>2] = $or101$i$i;- HEAP32[$arrayidx91$i$i>>2] = $119;- $parent$i$i = ((($119)) + 24|0);- HEAP32[$parent$i$i>>2] = $arrayidx91$i$i;- $bk102$i$i = ((($119)) + 12|0);- HEAP32[$bk102$i$i>>2] = $119;- $fd103$i$i = ((($119)) + 8|0);- HEAP32[$fd103$i$i>>2] = $119;- break;- }- $200 = HEAP32[$arrayidx91$i$i>>2]|0;- $cmp106$i$i = ($I57$0$i$i|0)==(31);- $shr110$i$i = $I57$0$i$i >>> 1;- $sub113$i$i = (25 - ($shr110$i$i))|0;- $cond115$i$i = $cmp106$i$i ? 0 : $sub113$i$i;- $shl116$i$i = $sub$ptr$sub$i$i << $cond115$i$i;- $K105$0$i$i = $shl116$i$i;$T$0$i$i = $200;- while(1) {- $head118$i$i = ((($T$0$i$i)) + 4|0);- $201 = HEAP32[$head118$i$i>>2]|0;- $and119$i$i = $201 & -8;- $cmp120$i$i = ($and119$i$i|0)==($sub$ptr$sub$i$i|0);- if ($cmp120$i$i) {- $T$0$i$i$lcssa = $T$0$i$i;- label = 307;- break;- }- $shr123$i$i = $K105$0$i$i >>> 31;- $arrayidx126$i$i = (((($T$0$i$i)) + 16|0) + ($shr123$i$i<<2)|0);- $shl127$i$i = $K105$0$i$i << 1;- $202 = HEAP32[$arrayidx126$i$i>>2]|0;- $cmp128$i$i = ($202|0)==(0|0);- if ($cmp128$i$i) {- $T$0$i$i$lcssa284 = $T$0$i$i;$arrayidx126$i$i$lcssa = $arrayidx126$i$i;- label = 304;- break;- } else {- $K105$0$i$i = $shl127$i$i;$T$0$i$i = $202;- }- }- if ((label|0) == 304) {- $203 = HEAP32[(192)>>2]|0;- $cmp133$i$i = ($arrayidx126$i$i$lcssa>>>0)<($203>>>0);- if ($cmp133$i$i) {- _abort();- // unreachable;- } else {- HEAP32[$arrayidx126$i$i$lcssa>>2] = $119;- $parent138$i$i = ((($119)) + 24|0);- HEAP32[$parent138$i$i>>2] = $T$0$i$i$lcssa284;- $bk139$i$i = ((($119)) + 12|0);- HEAP32[$bk139$i$i>>2] = $119;- $fd140$i$i = ((($119)) + 8|0);- HEAP32[$fd140$i$i>>2] = $119;- break;- }- }- else if ((label|0) == 307) {- $fd148$i$i = ((($T$0$i$i$lcssa)) + 8|0);- $204 = HEAP32[$fd148$i$i>>2]|0;- $205 = HEAP32[(192)>>2]|0;- $cmp153$i$i = ($204>>>0)>=($205>>>0);- $not$cmp150$i$i = ($T$0$i$i$lcssa>>>0)>=($205>>>0);- $206 = $cmp153$i$i & $not$cmp150$i$i;- if ($206) {- $bk158$i$i = ((($204)) + 12|0);- HEAP32[$bk158$i$i>>2] = $119;- HEAP32[$fd148$i$i>>2] = $119;- $fd160$i$i = ((($119)) + 8|0);- HEAP32[$fd160$i$i>>2] = $204;- $bk161$i$i = ((($119)) + 12|0);- HEAP32[$bk161$i$i>>2] = $T$0$i$i$lcssa;- $parent162$i$i = ((($119)) + 24|0);- HEAP32[$parent162$i$i>>2] = 0;- break;- } else {- _abort();- // unreachable;- }- }- }- }- } while(0);- $207 = HEAP32[(188)>>2]|0;- $cmp257$i = ($207>>>0)>($nb$0>>>0);- if ($cmp257$i) {- $sub260$i = (($207) - ($nb$0))|0;- HEAP32[(188)>>2] = $sub260$i;- $208 = HEAP32[(200)>>2]|0;- $add$ptr262$i = (($208) + ($nb$0)|0);- HEAP32[(200)>>2] = $add$ptr262$i;- $or264$i = $sub260$i | 1;- $head265$i = ((($add$ptr262$i)) + 4|0);- HEAP32[$head265$i>>2] = $or264$i;- $or267$i = $nb$0 | 3;- $head268$i = ((($208)) + 4|0);- HEAP32[$head268$i>>2] = $or267$i;- $add$ptr269$i = ((($208)) + 8|0);- $retval$0 = $add$ptr269$i;- return ($retval$0|0);- }- }- $call275$i = (___errno_location()|0);- HEAP32[$call275$i>>2] = 12;- $retval$0 = 0;- return ($retval$0|0);-}-function _free($mem) {- $mem = $mem|0;- var $$pre = 0, $$pre$phiZ2D = 0, $$pre312 = 0, $$pre313 = 0, $0 = 0, $1 = 0, $10 = 0, $11 = 0, $12 = 0, $13 = 0, $14 = 0, $15 = 0, $16 = 0, $17 = 0, $18 = 0, $19 = 0, $2 = 0, $20 = 0, $21 = 0, $22 = 0;- var $23 = 0, $24 = 0, $25 = 0, $26 = 0, $27 = 0, $28 = 0, $29 = 0, $3 = 0, $30 = 0, $31 = 0, $32 = 0, $33 = 0, $34 = 0, $35 = 0, $36 = 0, $37 = 0, $38 = 0, $39 = 0, $4 = 0, $40 = 0;- var $41 = 0, $42 = 0, $43 = 0, $44 = 0, $45 = 0, $46 = 0, $47 = 0, $48 = 0, $49 = 0, $5 = 0, $50 = 0, $51 = 0, $52 = 0, $53 = 0, $54 = 0, $55 = 0, $56 = 0, $57 = 0, $58 = 0, $59 = 0;- var $6 = 0, $60 = 0, $61 = 0, $62 = 0, $63 = 0, $64 = 0, $65 = 0, $66 = 0, $67 = 0, $68 = 0, $69 = 0, $7 = 0, $70 = 0, $71 = 0, $72 = 0, $73 = 0, $74 = 0, $8 = 0, $9 = 0, $F510$0 = 0;- var $I534$0 = 0, $K583$0 = 0, $R$1 = 0, $R$1$lcssa = 0, $R$3 = 0, $R332$1 = 0, $R332$1$lcssa = 0, $R332$3 = 0, $RP$1 = 0, $RP$1$lcssa = 0, $RP360$1 = 0, $RP360$1$lcssa = 0, $T$0 = 0, $T$0$lcssa = 0, $T$0$lcssa319 = 0, $add$ptr = 0, $add$ptr16 = 0, $add$ptr217 = 0, $add$ptr261 = 0, $add$ptr482 = 0;- var $add$ptr498 = 0, $add$ptr6 = 0, $add17 = 0, $add246 = 0, $add258 = 0, $add267 = 0, $add550 = 0, $add555 = 0, $add559 = 0, $add561 = 0, $add564 = 0, $and = 0, $and140 = 0, $and210 = 0, $and215 = 0, $and232 = 0, $and240 = 0, $and266 = 0, $and301 = 0, $and410 = 0;- var $and46 = 0, $and495 = 0, $and5 = 0, $and512 = 0, $and545 = 0, $and549 = 0, $and554 = 0, $and563 = 0, $and574 = 0, $and592 = 0, $and8 = 0, $arrayidx = 0, $arrayidx108 = 0, $arrayidx113 = 0, $arrayidx130 = 0, $arrayidx149 = 0, $arrayidx157 = 0, $arrayidx182 = 0, $arrayidx188 = 0, $arrayidx198 = 0;- var $arrayidx279 = 0, $arrayidx362 = 0, $arrayidx374 = 0, $arrayidx379 = 0, $arrayidx400 = 0, $arrayidx419 = 0, $arrayidx427 = 0, $arrayidx454 = 0, $arrayidx460 = 0, $arrayidx470 = 0, $arrayidx509 = 0, $arrayidx567 = 0, $arrayidx570 = 0, $arrayidx599 = 0, $arrayidx599$lcssa = 0, $arrayidx99 = 0, $bk = 0, $bk275 = 0, $bk286 = 0, $bk321 = 0;- var $bk333 = 0, $bk34 = 0, $bk343 = 0, $bk529 = 0, $bk531 = 0, $bk580 = 0, $bk611 = 0, $bk631 = 0, $bk634 = 0, $bk66 = 0, $bk73 = 0, $bk82 = 0, $child = 0, $child171 = 0, $child361 = 0, $child443 = 0, $child569 = 0, $cmp = 0, $cmp$i = 0, $cmp1 = 0;- var $cmp100 = 0, $cmp104 = 0, $cmp109 = 0, $cmp114 = 0, $cmp118 = 0, $cmp127 = 0, $cmp13 = 0, $cmp131 = 0, $cmp143 = 0, $cmp150 = 0, $cmp162 = 0, $cmp165 = 0, $cmp173 = 0, $cmp176 = 0, $cmp18 = 0, $cmp189 = 0, $cmp192 = 0, $cmp2 = 0, $cmp211 = 0, $cmp22 = 0;- var $cmp228 = 0, $cmp243 = 0, $cmp249 = 0, $cmp25 = 0, $cmp255 = 0, $cmp269 = 0, $cmp280 = 0, $cmp283 = 0, $cmp287 = 0, $cmp29 = 0, $cmp296 = 0, $cmp305 = 0, $cmp308 = 0, $cmp31 = 0, $cmp312 = 0, $cmp334 = 0, $cmp340 = 0, $cmp344 = 0, $cmp348 = 0, $cmp35 = 0;- var $cmp363 = 0, $cmp368 = 0, $cmp375 = 0, $cmp380 = 0, $cmp386 = 0, $cmp395 = 0, $cmp401 = 0, $cmp413 = 0, $cmp42 = 0, $cmp420 = 0, $cmp432 = 0, $cmp435 = 0, $cmp445 = 0, $cmp448 = 0, $cmp461 = 0, $cmp464 = 0, $cmp484 = 0, $cmp50 = 0, $cmp502 = 0, $cmp519 = 0;- var $cmp53 = 0, $cmp536 = 0, $cmp540 = 0, $cmp57 = 0, $cmp584 = 0, $cmp593 = 0, $cmp601 = 0, $cmp605 = 0, $cmp624 = 0, $cmp640 = 0, $cmp74 = 0, $cmp80 = 0, $cmp83 = 0, $cmp87 = 0, $cond = 0, $cond291 = 0, $cond292 = 0, $dec = 0, $fd = 0, $fd273 = 0;- var $fd311 = 0, $fd322$pre$phiZ2D = 0, $fd338 = 0, $fd347 = 0, $fd530 = 0, $fd56 = 0, $fd581 = 0, $fd612 = 0, $fd620 = 0, $fd633 = 0, $fd67$pre$phiZ2D = 0, $fd78 = 0, $fd86 = 0, $head = 0, $head209 = 0, $head216 = 0, $head231 = 0, $head248 = 0, $head260 = 0, $head481 = 0;- var $head497 = 0, $head591 = 0, $idx$neg = 0, $index = 0, $index399 = 0, $index568 = 0, $neg = 0, $neg139 = 0, $neg300 = 0, $neg409 = 0, $next4$i = 0, $not$cmp621 = 0, $or = 0, $or247 = 0, $or259 = 0, $or480 = 0, $or496 = 0, $or516 = 0, $or578 = 0, $p$1 = 0;- var $parent = 0, $parent170 = 0, $parent183 = 0, $parent199 = 0, $parent331 = 0, $parent442 = 0, $parent455 = 0, $parent471 = 0, $parent579 = 0, $parent610 = 0, $parent635 = 0, $psize$1 = 0, $psize$2 = 0, $shl = 0, $shl138 = 0, $shl278 = 0, $shl299 = 0, $shl408 = 0, $shl45 = 0, $shl508 = 0;- var $shl511 = 0, $shl546 = 0, $shl551 = 0, $shl557 = 0, $shl560 = 0, $shl573 = 0, $shl590 = 0, $shl600 = 0, $shr = 0, $shr268 = 0, $shr501 = 0, $shr535 = 0, $shr544 = 0, $shr548 = 0, $shr553 = 0, $shr558 = 0, $shr562 = 0, $shr586 = 0, $shr596 = 0, $sp$0$i = 0;- var $sp$0$in$i = 0, $sub = 0, $sub547 = 0, $sub552 = 0, $sub556 = 0, $sub589 = 0, $tobool233 = 0, $tobool241 = 0, $tobool513 = 0, $tobool575 = 0, $tobool9 = 0, label = 0, sp = 0;- sp = STACKTOP;- $cmp = ($mem|0)==(0|0);- if ($cmp) {- return;- }- $add$ptr = ((($mem)) + -8|0);- $0 = HEAP32[(192)>>2]|0;- $cmp1 = ($add$ptr>>>0)<($0>>>0);- if ($cmp1) {- _abort();- // unreachable;- }- $head = ((($mem)) + -4|0);- $1 = HEAP32[$head>>2]|0;- $and = $1 & 3;- $cmp2 = ($and|0)==(1);- if ($cmp2) {- _abort();- // unreachable;- }- $and5 = $1 & -8;- $add$ptr6 = (($add$ptr) + ($and5)|0);- $and8 = $1 & 1;- $tobool9 = ($and8|0)==(0);- do {- if ($tobool9) {- $2 = HEAP32[$add$ptr>>2]|0;- $cmp13 = ($and|0)==(0);- if ($cmp13) {- return;- }- $idx$neg = (0 - ($2))|0;- $add$ptr16 = (($add$ptr) + ($idx$neg)|0);- $add17 = (($2) + ($and5))|0;- $cmp18 = ($add$ptr16>>>0)<($0>>>0);- if ($cmp18) {- _abort();- // unreachable;- }- $3 = HEAP32[(196)>>2]|0;- $cmp22 = ($add$ptr16|0)==($3|0);- if ($cmp22) {- $head209 = ((($add$ptr6)) + 4|0);- $27 = HEAP32[$head209>>2]|0;- $and210 = $27 & 3;- $cmp211 = ($and210|0)==(3);- if (!($cmp211)) {- $p$1 = $add$ptr16;$psize$1 = $add17;- break;- }- HEAP32[(184)>>2] = $add17;- $and215 = $27 & -2;- HEAP32[$head209>>2] = $and215;- $or = $add17 | 1;- $head216 = ((($add$ptr16)) + 4|0);- HEAP32[$head216>>2] = $or;- $add$ptr217 = (($add$ptr16) + ($add17)|0);- HEAP32[$add$ptr217>>2] = $add17;- return;- }- $shr = $2 >>> 3;- $cmp25 = ($2>>>0)<(256);- if ($cmp25) {- $fd = ((($add$ptr16)) + 8|0);- $4 = HEAP32[$fd>>2]|0;- $bk = ((($add$ptr16)) + 12|0);- $5 = HEAP32[$bk>>2]|0;- $shl = $shr << 1;- $arrayidx = (216 + ($shl<<2)|0);- $cmp29 = ($4|0)==($arrayidx|0);- if (!($cmp29)) {- $cmp31 = ($4>>>0)<($0>>>0);- if ($cmp31) {- _abort();- // unreachable;- }- $bk34 = ((($4)) + 12|0);- $6 = HEAP32[$bk34>>2]|0;- $cmp35 = ($6|0)==($add$ptr16|0);- if (!($cmp35)) {- _abort();- // unreachable;- }- }- $cmp42 = ($5|0)==($4|0);- if ($cmp42) {- $shl45 = 1 << $shr;- $neg = $shl45 ^ -1;- $7 = HEAP32[44]|0;- $and46 = $7 & $neg;- HEAP32[44] = $and46;- $p$1 = $add$ptr16;$psize$1 = $add17;- break;- }- $cmp50 = ($5|0)==($arrayidx|0);- if ($cmp50) {- $$pre313 = ((($5)) + 8|0);- $fd67$pre$phiZ2D = $$pre313;- } else {- $cmp53 = ($5>>>0)<($0>>>0);- if ($cmp53) {- _abort();- // unreachable;- }- $fd56 = ((($5)) + 8|0);- $8 = HEAP32[$fd56>>2]|0;- $cmp57 = ($8|0)==($add$ptr16|0);- if ($cmp57) {- $fd67$pre$phiZ2D = $fd56;- } else {- _abort();- // unreachable;- }- }- $bk66 = ((($4)) + 12|0);- HEAP32[$bk66>>2] = $5;- HEAP32[$fd67$pre$phiZ2D>>2] = $4;- $p$1 = $add$ptr16;$psize$1 = $add17;- break;- }- $parent = ((($add$ptr16)) + 24|0);- $9 = HEAP32[$parent>>2]|0;- $bk73 = ((($add$ptr16)) + 12|0);- $10 = HEAP32[$bk73>>2]|0;- $cmp74 = ($10|0)==($add$ptr16|0);- do {- if ($cmp74) {- $child = ((($add$ptr16)) + 16|0);- $arrayidx99 = ((($child)) + 4|0);- $14 = HEAP32[$arrayidx99>>2]|0;- $cmp100 = ($14|0)==(0|0);- if ($cmp100) {- $15 = HEAP32[$child>>2]|0;- $cmp104 = ($15|0)==(0|0);- if ($cmp104) {- $R$3 = 0;- break;- } else {- $R$1 = $15;$RP$1 = $child;- }- } else {- $R$1 = $14;$RP$1 = $arrayidx99;- }- while(1) {- $arrayidx108 = ((($R$1)) + 20|0);- $16 = HEAP32[$arrayidx108>>2]|0;- $cmp109 = ($16|0)==(0|0);- if (!($cmp109)) {- $R$1 = $16;$RP$1 = $arrayidx108;- continue;- }- $arrayidx113 = ((($R$1)) + 16|0);- $17 = HEAP32[$arrayidx113>>2]|0;- $cmp114 = ($17|0)==(0|0);- if ($cmp114) {- $R$1$lcssa = $R$1;$RP$1$lcssa = $RP$1;- break;- } else {- $R$1 = $17;$RP$1 = $arrayidx113;- }- }- $cmp118 = ($RP$1$lcssa>>>0)<($0>>>0);- if ($cmp118) {- _abort();- // unreachable;- } else {- HEAP32[$RP$1$lcssa>>2] = 0;- $R$3 = $R$1$lcssa;- break;- }- } else {- $fd78 = ((($add$ptr16)) + 8|0);- $11 = HEAP32[$fd78>>2]|0;- $cmp80 = ($11>>>0)<($0>>>0);- if ($cmp80) {- _abort();- // unreachable;- }- $bk82 = ((($11)) + 12|0);- $12 = HEAP32[$bk82>>2]|0;- $cmp83 = ($12|0)==($add$ptr16|0);- if (!($cmp83)) {- _abort();- // unreachable;- }- $fd86 = ((($10)) + 8|0);- $13 = HEAP32[$fd86>>2]|0;- $cmp87 = ($13|0)==($add$ptr16|0);- if ($cmp87) {- HEAP32[$bk82>>2] = $10;- HEAP32[$fd86>>2] = $11;- $R$3 = $10;- break;- } else {- _abort();- // unreachable;- }- }- } while(0);- $cmp127 = ($9|0)==(0|0);- if ($cmp127) {- $p$1 = $add$ptr16;$psize$1 = $add17;- } else {- $index = ((($add$ptr16)) + 28|0);- $18 = HEAP32[$index>>2]|0;- $arrayidx130 = (480 + ($18<<2)|0);- $19 = HEAP32[$arrayidx130>>2]|0;- $cmp131 = ($add$ptr16|0)==($19|0);- if ($cmp131) {- HEAP32[$arrayidx130>>2] = $R$3;- $cond291 = ($R$3|0)==(0|0);- if ($cond291) {- $shl138 = 1 << $18;- $neg139 = $shl138 ^ -1;- $20 = HEAP32[(180)>>2]|0;- $and140 = $20 & $neg139;- HEAP32[(180)>>2] = $and140;- $p$1 = $add$ptr16;$psize$1 = $add17;- break;- }- } else {- $21 = HEAP32[(192)>>2]|0;- $cmp143 = ($9>>>0)<($21>>>0);- if ($cmp143) {- _abort();- // unreachable;- }- $arrayidx149 = ((($9)) + 16|0);- $22 = HEAP32[$arrayidx149>>2]|0;- $cmp150 = ($22|0)==($add$ptr16|0);- if ($cmp150) {- HEAP32[$arrayidx149>>2] = $R$3;- } else {- $arrayidx157 = ((($9)) + 20|0);- HEAP32[$arrayidx157>>2] = $R$3;- }- $cmp162 = ($R$3|0)==(0|0);- if ($cmp162) {- $p$1 = $add$ptr16;$psize$1 = $add17;- break;- }- }- $23 = HEAP32[(192)>>2]|0;- $cmp165 = ($R$3>>>0)<($23>>>0);- if ($cmp165) {- _abort();- // unreachable;- }- $parent170 = ((($R$3)) + 24|0);- HEAP32[$parent170>>2] = $9;- $child171 = ((($add$ptr16)) + 16|0);- $24 = HEAP32[$child171>>2]|0;- $cmp173 = ($24|0)==(0|0);- do {- if (!($cmp173)) {- $cmp176 = ($24>>>0)<($23>>>0);- if ($cmp176) {- _abort();- // unreachable;- } else {- $arrayidx182 = ((($R$3)) + 16|0);- HEAP32[$arrayidx182>>2] = $24;- $parent183 = ((($24)) + 24|0);- HEAP32[$parent183>>2] = $R$3;- break;- }- }- } while(0);- $arrayidx188 = ((($child171)) + 4|0);- $25 = HEAP32[$arrayidx188>>2]|0;- $cmp189 = ($25|0)==(0|0);- if ($cmp189) {- $p$1 = $add$ptr16;$psize$1 = $add17;- } else {- $26 = HEAP32[(192)>>2]|0;- $cmp192 = ($25>>>0)<($26>>>0);- if ($cmp192) {- _abort();- // unreachable;- } else {- $arrayidx198 = ((($R$3)) + 20|0);- HEAP32[$arrayidx198>>2] = $25;- $parent199 = ((($25)) + 24|0);- HEAP32[$parent199>>2] = $R$3;- $p$1 = $add$ptr16;$psize$1 = $add17;- break;- }- }- }- } else {- $p$1 = $add$ptr;$psize$1 = $and5;- }- } while(0);- $cmp228 = ($p$1>>>0)<($add$ptr6>>>0);- if (!($cmp228)) {- _abort();- // unreachable;- }- $head231 = ((($add$ptr6)) + 4|0);- $28 = HEAP32[$head231>>2]|0;- $and232 = $28 & 1;- $tobool233 = ($and232|0)==(0);- if ($tobool233) {- _abort();- // unreachable;- }- $and240 = $28 & 2;- $tobool241 = ($and240|0)==(0);- if ($tobool241) {- $29 = HEAP32[(200)>>2]|0;- $cmp243 = ($add$ptr6|0)==($29|0);- if ($cmp243) {- $30 = HEAP32[(188)>>2]|0;- $add246 = (($30) + ($psize$1))|0;- HEAP32[(188)>>2] = $add246;- HEAP32[(200)>>2] = $p$1;- $or247 = $add246 | 1;- $head248 = ((($p$1)) + 4|0);- HEAP32[$head248>>2] = $or247;- $31 = HEAP32[(196)>>2]|0;- $cmp249 = ($p$1|0)==($31|0);- if (!($cmp249)) {- return;- }- HEAP32[(196)>>2] = 0;- HEAP32[(184)>>2] = 0;- return;- }- $32 = HEAP32[(196)>>2]|0;- $cmp255 = ($add$ptr6|0)==($32|0);- if ($cmp255) {- $33 = HEAP32[(184)>>2]|0;- $add258 = (($33) + ($psize$1))|0;- HEAP32[(184)>>2] = $add258;- HEAP32[(196)>>2] = $p$1;- $or259 = $add258 | 1;- $head260 = ((($p$1)) + 4|0);- HEAP32[$head260>>2] = $or259;- $add$ptr261 = (($p$1) + ($add258)|0);- HEAP32[$add$ptr261>>2] = $add258;- return;- }- $and266 = $28 & -8;- $add267 = (($and266) + ($psize$1))|0;- $shr268 = $28 >>> 3;- $cmp269 = ($28>>>0)<(256);- do {- if ($cmp269) {- $fd273 = ((($add$ptr6)) + 8|0);- $34 = HEAP32[$fd273>>2]|0;- $bk275 = ((($add$ptr6)) + 12|0);- $35 = HEAP32[$bk275>>2]|0;- $shl278 = $shr268 << 1;- $arrayidx279 = (216 + ($shl278<<2)|0);- $cmp280 = ($34|0)==($arrayidx279|0);- if (!($cmp280)) {- $36 = HEAP32[(192)>>2]|0;- $cmp283 = ($34>>>0)<($36>>>0);- if ($cmp283) {- _abort();- // unreachable;- }- $bk286 = ((($34)) + 12|0);- $37 = HEAP32[$bk286>>2]|0;- $cmp287 = ($37|0)==($add$ptr6|0);- if (!($cmp287)) {- _abort();- // unreachable;- }- }- $cmp296 = ($35|0)==($34|0);- if ($cmp296) {- $shl299 = 1 << $shr268;- $neg300 = $shl299 ^ -1;- $38 = HEAP32[44]|0;- $and301 = $38 & $neg300;- HEAP32[44] = $and301;- break;- }- $cmp305 = ($35|0)==($arrayidx279|0);- if ($cmp305) {- $$pre312 = ((($35)) + 8|0);- $fd322$pre$phiZ2D = $$pre312;- } else {- $39 = HEAP32[(192)>>2]|0;- $cmp308 = ($35>>>0)<($39>>>0);- if ($cmp308) {- _abort();- // unreachable;- }- $fd311 = ((($35)) + 8|0);- $40 = HEAP32[$fd311>>2]|0;- $cmp312 = ($40|0)==($add$ptr6|0);- if ($cmp312) {- $fd322$pre$phiZ2D = $fd311;- } else {- _abort();- // unreachable;- }- }- $bk321 = ((($34)) + 12|0);- HEAP32[$bk321>>2] = $35;- HEAP32[$fd322$pre$phiZ2D>>2] = $34;- } else {- $parent331 = ((($add$ptr6)) + 24|0);- $41 = HEAP32[$parent331>>2]|0;- $bk333 = ((($add$ptr6)) + 12|0);- $42 = HEAP32[$bk333>>2]|0;- $cmp334 = ($42|0)==($add$ptr6|0);- do {- if ($cmp334) {- $child361 = ((($add$ptr6)) + 16|0);- $arrayidx362 = ((($child361)) + 4|0);- $47 = HEAP32[$arrayidx362>>2]|0;- $cmp363 = ($47|0)==(0|0);- if ($cmp363) {- $48 = HEAP32[$child361>>2]|0;- $cmp368 = ($48|0)==(0|0);- if ($cmp368) {- $R332$3 = 0;- break;- } else {- $R332$1 = $48;$RP360$1 = $child361;- }- } else {- $R332$1 = $47;$RP360$1 = $arrayidx362;- }- while(1) {- $arrayidx374 = ((($R332$1)) + 20|0);- $49 = HEAP32[$arrayidx374>>2]|0;- $cmp375 = ($49|0)==(0|0);- if (!($cmp375)) {- $R332$1 = $49;$RP360$1 = $arrayidx374;- continue;- }- $arrayidx379 = ((($R332$1)) + 16|0);- $50 = HEAP32[$arrayidx379>>2]|0;- $cmp380 = ($50|0)==(0|0);- if ($cmp380) {- $R332$1$lcssa = $R332$1;$RP360$1$lcssa = $RP360$1;- break;- } else {- $R332$1 = $50;$RP360$1 = $arrayidx379;- }- }- $51 = HEAP32[(192)>>2]|0;- $cmp386 = ($RP360$1$lcssa>>>0)<($51>>>0);- if ($cmp386) {- _abort();- // unreachable;- } else {- HEAP32[$RP360$1$lcssa>>2] = 0;- $R332$3 = $R332$1$lcssa;- break;- }- } else {- $fd338 = ((($add$ptr6)) + 8|0);- $43 = HEAP32[$fd338>>2]|0;- $44 = HEAP32[(192)>>2]|0;- $cmp340 = ($43>>>0)<($44>>>0);- if ($cmp340) {- _abort();- // unreachable;- }- $bk343 = ((($43)) + 12|0);- $45 = HEAP32[$bk343>>2]|0;- $cmp344 = ($45|0)==($add$ptr6|0);- if (!($cmp344)) {- _abort();- // unreachable;- }- $fd347 = ((($42)) + 8|0);- $46 = HEAP32[$fd347>>2]|0;- $cmp348 = ($46|0)==($add$ptr6|0);- if ($cmp348) {- HEAP32[$bk343>>2] = $42;- HEAP32[$fd347>>2] = $43;- $R332$3 = $42;- break;- } else {- _abort();- // unreachable;- }- }- } while(0);- $cmp395 = ($41|0)==(0|0);- if (!($cmp395)) {- $index399 = ((($add$ptr6)) + 28|0);- $52 = HEAP32[$index399>>2]|0;- $arrayidx400 = (480 + ($52<<2)|0);- $53 = HEAP32[$arrayidx400>>2]|0;- $cmp401 = ($add$ptr6|0)==($53|0);- if ($cmp401) {- HEAP32[$arrayidx400>>2] = $R332$3;- $cond292 = ($R332$3|0)==(0|0);- if ($cond292) {- $shl408 = 1 << $52;- $neg409 = $shl408 ^ -1;- $54 = HEAP32[(180)>>2]|0;- $and410 = $54 & $neg409;- HEAP32[(180)>>2] = $and410;- break;- }- } else {- $55 = HEAP32[(192)>>2]|0;- $cmp413 = ($41>>>0)<($55>>>0);- if ($cmp413) {- _abort();- // unreachable;- }- $arrayidx419 = ((($41)) + 16|0);- $56 = HEAP32[$arrayidx419>>2]|0;- $cmp420 = ($56|0)==($add$ptr6|0);- if ($cmp420) {- HEAP32[$arrayidx419>>2] = $R332$3;- } else {- $arrayidx427 = ((($41)) + 20|0);- HEAP32[$arrayidx427>>2] = $R332$3;- }- $cmp432 = ($R332$3|0)==(0|0);- if ($cmp432) {- break;- }- }- $57 = HEAP32[(192)>>2]|0;- $cmp435 = ($R332$3>>>0)<($57>>>0);- if ($cmp435) {- _abort();- // unreachable;- }- $parent442 = ((($R332$3)) + 24|0);- HEAP32[$parent442>>2] = $41;- $child443 = ((($add$ptr6)) + 16|0);- $58 = HEAP32[$child443>>2]|0;- $cmp445 = ($58|0)==(0|0);- do {- if (!($cmp445)) {- $cmp448 = ($58>>>0)<($57>>>0);- if ($cmp448) {- _abort();- // unreachable;- } else {- $arrayidx454 = ((($R332$3)) + 16|0);- HEAP32[$arrayidx454>>2] = $58;- $parent455 = ((($58)) + 24|0);- HEAP32[$parent455>>2] = $R332$3;- break;- }- }- } while(0);- $arrayidx460 = ((($child443)) + 4|0);- $59 = HEAP32[$arrayidx460>>2]|0;- $cmp461 = ($59|0)==(0|0);- if (!($cmp461)) {- $60 = HEAP32[(192)>>2]|0;- $cmp464 = ($59>>>0)<($60>>>0);- if ($cmp464) {- _abort();- // unreachable;- } else {- $arrayidx470 = ((($R332$3)) + 20|0);- HEAP32[$arrayidx470>>2] = $59;- $parent471 = ((($59)) + 24|0);- HEAP32[$parent471>>2] = $R332$3;- break;- }- }- }- }- } while(0);- $or480 = $add267 | 1;- $head481 = ((($p$1)) + 4|0);- HEAP32[$head481>>2] = $or480;- $add$ptr482 = (($p$1) + ($add267)|0);- HEAP32[$add$ptr482>>2] = $add267;- $61 = HEAP32[(196)>>2]|0;- $cmp484 = ($p$1|0)==($61|0);- if ($cmp484) {- HEAP32[(184)>>2] = $add267;- return;- } else {- $psize$2 = $add267;- }- } else {- $and495 = $28 & -2;- HEAP32[$head231>>2] = $and495;- $or496 = $psize$1 | 1;- $head497 = ((($p$1)) + 4|0);- HEAP32[$head497>>2] = $or496;- $add$ptr498 = (($p$1) + ($psize$1)|0);- HEAP32[$add$ptr498>>2] = $psize$1;- $psize$2 = $psize$1;- }- $shr501 = $psize$2 >>> 3;- $cmp502 = ($psize$2>>>0)<(256);- if ($cmp502) {- $shl508 = $shr501 << 1;- $arrayidx509 = (216 + ($shl508<<2)|0);- $62 = HEAP32[44]|0;- $shl511 = 1 << $shr501;- $and512 = $62 & $shl511;- $tobool513 = ($and512|0)==(0);- if ($tobool513) {- $or516 = $62 | $shl511;- HEAP32[44] = $or516;- $$pre = ((($arrayidx509)) + 8|0);- $$pre$phiZ2D = $$pre;$F510$0 = $arrayidx509;- } else {- $63 = ((($arrayidx509)) + 8|0);- $64 = HEAP32[$63>>2]|0;- $65 = HEAP32[(192)>>2]|0;- $cmp519 = ($64>>>0)<($65>>>0);- if ($cmp519) {- _abort();- // unreachable;- } else {- $$pre$phiZ2D = $63;$F510$0 = $64;- }- }- HEAP32[$$pre$phiZ2D>>2] = $p$1;- $bk529 = ((($F510$0)) + 12|0);- HEAP32[$bk529>>2] = $p$1;- $fd530 = ((($p$1)) + 8|0);- HEAP32[$fd530>>2] = $F510$0;- $bk531 = ((($p$1)) + 12|0);- HEAP32[$bk531>>2] = $arrayidx509;- return;- }- $shr535 = $psize$2 >>> 8;- $cmp536 = ($shr535|0)==(0);- if ($cmp536) {- $I534$0 = 0;- } else {- $cmp540 = ($psize$2>>>0)>(16777215);- if ($cmp540) {- $I534$0 = 31;- } else {- $sub = (($shr535) + 1048320)|0;- $shr544 = $sub >>> 16;- $and545 = $shr544 & 8;- $shl546 = $shr535 << $and545;- $sub547 = (($shl546) + 520192)|0;- $shr548 = $sub547 >>> 16;- $and549 = $shr548 & 4;- $add550 = $and549 | $and545;- $shl551 = $shl546 << $and549;- $sub552 = (($shl551) + 245760)|0;- $shr553 = $sub552 >>> 16;- $and554 = $shr553 & 2;- $add555 = $add550 | $and554;- $sub556 = (14 - ($add555))|0;- $shl557 = $shl551 << $and554;- $shr558 = $shl557 >>> 15;- $add559 = (($sub556) + ($shr558))|0;- $shl560 = $add559 << 1;- $add561 = (($add559) + 7)|0;- $shr562 = $psize$2 >>> $add561;- $and563 = $shr562 & 1;- $add564 = $and563 | $shl560;- $I534$0 = $add564;- }- }- $arrayidx567 = (480 + ($I534$0<<2)|0);- $index568 = ((($p$1)) + 28|0);- HEAP32[$index568>>2] = $I534$0;- $child569 = ((($p$1)) + 16|0);- $arrayidx570 = ((($p$1)) + 20|0);- HEAP32[$arrayidx570>>2] = 0;- HEAP32[$child569>>2] = 0;- $66 = HEAP32[(180)>>2]|0;- $shl573 = 1 << $I534$0;- $and574 = $66 & $shl573;- $tobool575 = ($and574|0)==(0);- do {- if ($tobool575) {- $or578 = $66 | $shl573;- HEAP32[(180)>>2] = $or578;- HEAP32[$arrayidx567>>2] = $p$1;- $parent579 = ((($p$1)) + 24|0);- HEAP32[$parent579>>2] = $arrayidx567;- $bk580 = ((($p$1)) + 12|0);- HEAP32[$bk580>>2] = $p$1;- $fd581 = ((($p$1)) + 8|0);- HEAP32[$fd581>>2] = $p$1;- } else {- $67 = HEAP32[$arrayidx567>>2]|0;- $cmp584 = ($I534$0|0)==(31);- $shr586 = $I534$0 >>> 1;- $sub589 = (25 - ($shr586))|0;- $cond = $cmp584 ? 0 : $sub589;- $shl590 = $psize$2 << $cond;- $K583$0 = $shl590;$T$0 = $67;- while(1) {- $head591 = ((($T$0)) + 4|0);- $68 = HEAP32[$head591>>2]|0;- $and592 = $68 & -8;- $cmp593 = ($and592|0)==($psize$2|0);- if ($cmp593) {- $T$0$lcssa = $T$0;- label = 130;- break;- }- $shr596 = $K583$0 >>> 31;- $arrayidx599 = (((($T$0)) + 16|0) + ($shr596<<2)|0);- $shl600 = $K583$0 << 1;- $69 = HEAP32[$arrayidx599>>2]|0;- $cmp601 = ($69|0)==(0|0);- if ($cmp601) {- $T$0$lcssa319 = $T$0;$arrayidx599$lcssa = $arrayidx599;- label = 127;- break;- } else {- $K583$0 = $shl600;$T$0 = $69;- }- }- if ((label|0) == 127) {- $70 = HEAP32[(192)>>2]|0;- $cmp605 = ($arrayidx599$lcssa>>>0)<($70>>>0);- if ($cmp605) {- _abort();- // unreachable;- } else {- HEAP32[$arrayidx599$lcssa>>2] = $p$1;- $parent610 = ((($p$1)) + 24|0);- HEAP32[$parent610>>2] = $T$0$lcssa319;- $bk611 = ((($p$1)) + 12|0);- HEAP32[$bk611>>2] = $p$1;- $fd612 = ((($p$1)) + 8|0);- HEAP32[$fd612>>2] = $p$1;- break;- }- }- else if ((label|0) == 130) {- $fd620 = ((($T$0$lcssa)) + 8|0);- $71 = HEAP32[$fd620>>2]|0;- $72 = HEAP32[(192)>>2]|0;- $cmp624 = ($71>>>0)>=($72>>>0);- $not$cmp621 = ($T$0$lcssa>>>0)>=($72>>>0);- $73 = $cmp624 & $not$cmp621;- if ($73) {- $bk631 = ((($71)) + 12|0);- HEAP32[$bk631>>2] = $p$1;- HEAP32[$fd620>>2] = $p$1;- $fd633 = ((($p$1)) + 8|0);- HEAP32[$fd633>>2] = $71;- $bk634 = ((($p$1)) + 12|0);- HEAP32[$bk634>>2] = $T$0$lcssa;- $parent635 = ((($p$1)) + 24|0);- HEAP32[$parent635>>2] = 0;- break;- } else {- _abort();- // unreachable;- }- }- }- } while(0);- $74 = HEAP32[(208)>>2]|0;- $dec = (($74) + -1)|0;- HEAP32[(208)>>2] = $dec;- $cmp640 = ($dec|0)==(0);- if ($cmp640) {- $sp$0$in$i = (632);- } else {- return;- }- while(1) {- $sp$0$i = HEAP32[$sp$0$in$i>>2]|0;- $cmp$i = ($sp$0$i|0)==(0|0);- $next4$i = ((($sp$0$i)) + 8|0);- if ($cmp$i) {- break;- } else {- $sp$0$in$i = $next4$i;- }- }- HEAP32[(208)>>2] = -1;- return;-}-function runPostSets() {-}-function _i64Subtract(a, b, c, d) {- a = a|0; b = b|0; c = c|0; d = d|0;- var l = 0, h = 0;- l = (a - c)>>>0;- h = (b - d)>>>0;- h = (b - d - (((c>>>0) > (a>>>0))|0))>>>0; // Borrow one from high word to low word on underflow.- return ((tempRet0 = h,l|0)|0);-}-function _i64Add(a, b, c, d) {- /*- x = a + b*2^32- y = c + d*2^32- result = l + h*2^32- */- a = a|0; b = b|0; c = c|0; d = d|0;- var l = 0, h = 0;- l = (a + c)>>>0;- h = (b + d + (((l>>>0) < (a>>>0))|0))>>>0; // Add carry from low word to high word on overflow.- return ((tempRet0 = h,l|0)|0);-}-function _memset(ptr, value, num) {- ptr = ptr|0; value = value|0; num = num|0;- var stop = 0, value4 = 0, stop4 = 0, unaligned = 0;- stop = (ptr + num)|0;- if ((num|0) >= 20) {- // This is unaligned, but quite large, so work hard to get to aligned settings- value = value & 0xff;- unaligned = ptr & 3;- value4 = value | (value << 8) | (value << 16) | (value << 24);- stop4 = stop & ~3;- if (unaligned) {- unaligned = (ptr + 4 - unaligned)|0;- while ((ptr|0) < (unaligned|0)) { // no need to check for stop, since we have large num- HEAP8[((ptr)>>0)]=value;- ptr = (ptr+1)|0;- }- }- while ((ptr|0) < (stop4|0)) {- HEAP32[((ptr)>>2)]=value4;- ptr = (ptr+4)|0;- }- }- while ((ptr|0) < (stop|0)) {- HEAP8[((ptr)>>0)]=value;- ptr = (ptr+1)|0;- }- return (ptr-num)|0;-}-function _bitshift64Lshr(low, high, bits) {- low = low|0; high = high|0; bits = bits|0;- var ander = 0;- if ((bits|0) < 32) {- ander = ((1 << bits) - 1)|0;- tempRet0 = high >>> bits;- return (low >>> bits) | ((high&ander) << (32 - bits));- }- tempRet0 = 0;- return (high >>> (bits - 32))|0;-}-function _bitshift64Shl(low, high, bits) {- low = low|0; high = high|0; bits = bits|0;- var ander = 0;- if ((bits|0) < 32) {- ander = ((1 << bits) - 1)|0;- tempRet0 = (high << bits) | ((low&(ander << (32 - bits))) >>> (32 - bits));- return low << bits;- }- tempRet0 = low << (bits - 32);- return 0;-}-function _memcpy(dest, src, num) {- dest = dest|0; src = src|0; num = num|0;- var ret = 0;- if ((num|0) >= 4096) return _emscripten_memcpy_big(dest|0, src|0, num|0)|0;- ret = dest|0;- if ((dest&3) == (src&3)) {- while (dest & 3) {- if ((num|0) == 0) return ret|0;- HEAP8[((dest)>>0)]=((HEAP8[((src)>>0)])|0);- dest = (dest+1)|0;- src = (src+1)|0;- num = (num-1)|0;- }- while ((num|0) >= 4) {- HEAP32[((dest)>>2)]=((HEAP32[((src)>>2)])|0);- dest = (dest+4)|0;- src = (src+4)|0;- num = (num-4)|0;- }- }- while ((num|0) > 0) {- HEAP8[((dest)>>0)]=((HEAP8[((src)>>0)])|0);- dest = (dest+1)|0;- src = (src+1)|0;- num = (num-1)|0;- }- return ret|0;-}-function _bitshift64Ashr(low, high, bits) {- low = low|0; high = high|0; bits = bits|0;- var ander = 0;- if ((bits|0) < 32) {- ander = ((1 << bits) - 1)|0;- tempRet0 = high >> bits;- return (low >>> bits) | ((high&ander) << (32 - bits));- }- tempRet0 = (high|0) < 0 ? -1 : 0;- return (high >> (bits - 32))|0;- }--// ======== compiled code from system/lib/compiler-rt , see readme therein-function ___muldsi3($a, $b) {- $a = $a | 0;- $b = $b | 0;- var $1 = 0, $2 = 0, $3 = 0, $6 = 0, $8 = 0, $11 = 0, $12 = 0;- $1 = $a & 65535;- $2 = $b & 65535;- $3 = Math_imul($2, $1) | 0;- $6 = $a >>> 16;- $8 = ($3 >>> 16) + (Math_imul($2, $6) | 0) | 0;- $11 = $b >>> 16;- $12 = Math_imul($11, $1) | 0;- return (tempRet0 = (($8 >>> 16) + (Math_imul($11, $6) | 0) | 0) + ((($8 & 65535) + $12 | 0) >>> 16) | 0, 0 | ($8 + $12 << 16 | $3 & 65535)) | 0;-}-function ___divdi3($a$0, $a$1, $b$0, $b$1) {- $a$0 = $a$0 | 0;- $a$1 = $a$1 | 0;- $b$0 = $b$0 | 0;- $b$1 = $b$1 | 0;- var $1$0 = 0, $1$1 = 0, $2$0 = 0, $2$1 = 0, $4$0 = 0, $4$1 = 0, $6$0 = 0, $7$0 = 0, $7$1 = 0, $8$0 = 0, $10$0 = 0;- $1$0 = $a$1 >> 31 | (($a$1 | 0) < 0 ? -1 : 0) << 1;- $1$1 = (($a$1 | 0) < 0 ? -1 : 0) >> 31 | (($a$1 | 0) < 0 ? -1 : 0) << 1;- $2$0 = $b$1 >> 31 | (($b$1 | 0) < 0 ? -1 : 0) << 1;- $2$1 = (($b$1 | 0) < 0 ? -1 : 0) >> 31 | (($b$1 | 0) < 0 ? -1 : 0) << 1;- $4$0 = _i64Subtract($1$0 ^ $a$0, $1$1 ^ $a$1, $1$0, $1$1) | 0;- $4$1 = tempRet0;- $6$0 = _i64Subtract($2$0 ^ $b$0, $2$1 ^ $b$1, $2$0, $2$1) | 0;- $7$0 = $2$0 ^ $1$0;- $7$1 = $2$1 ^ $1$1;- $8$0 = ___udivmoddi4($4$0, $4$1, $6$0, tempRet0, 0) | 0;- $10$0 = _i64Subtract($8$0 ^ $7$0, tempRet0 ^ $7$1, $7$0, $7$1) | 0;- return $10$0 | 0;-}-function ___remdi3($a$0, $a$1, $b$0, $b$1) {- $a$0 = $a$0 | 0;- $a$1 = $a$1 | 0;- $b$0 = $b$0 | 0;- $b$1 = $b$1 | 0;- var $rem = 0, $1$0 = 0, $1$1 = 0, $2$0 = 0, $2$1 = 0, $4$0 = 0, $4$1 = 0, $6$0 = 0, $10$0 = 0, $10$1 = 0, __stackBase__ = 0;- __stackBase__ = STACKTOP;- STACKTOP = STACKTOP + 16 | 0;- $rem = __stackBase__ | 0;- $1$0 = $a$1 >> 31 | (($a$1 | 0) < 0 ? -1 : 0) << 1;- $1$1 = (($a$1 | 0) < 0 ? -1 : 0) >> 31 | (($a$1 | 0) < 0 ? -1 : 0) << 1;- $2$0 = $b$1 >> 31 | (($b$1 | 0) < 0 ? -1 : 0) << 1;- $2$1 = (($b$1 | 0) < 0 ? -1 : 0) >> 31 | (($b$1 | 0) < 0 ? -1 : 0) << 1;- $4$0 = _i64Subtract($1$0 ^ $a$0, $1$1 ^ $a$1, $1$0, $1$1) | 0;- $4$1 = tempRet0;- $6$0 = _i64Subtract($2$0 ^ $b$0, $2$1 ^ $b$1, $2$0, $2$1) | 0;- ___udivmoddi4($4$0, $4$1, $6$0, tempRet0, $rem) | 0;- $10$0 = _i64Subtract(HEAP32[$rem >> 2] ^ $1$0, HEAP32[$rem + 4 >> 2] ^ $1$1, $1$0, $1$1) | 0;- $10$1 = tempRet0;- STACKTOP = __stackBase__;- return (tempRet0 = $10$1, $10$0) | 0;-}-function ___muldi3($a$0, $a$1, $b$0, $b$1) {- $a$0 = $a$0 | 0;- $a$1 = $a$1 | 0;- $b$0 = $b$0 | 0;- $b$1 = $b$1 | 0;- var $x_sroa_0_0_extract_trunc = 0, $y_sroa_0_0_extract_trunc = 0, $1$0 = 0, $1$1 = 0, $2 = 0;- $x_sroa_0_0_extract_trunc = $a$0;- $y_sroa_0_0_extract_trunc = $b$0;- $1$0 = ___muldsi3($x_sroa_0_0_extract_trunc, $y_sroa_0_0_extract_trunc) | 0;- $1$1 = tempRet0;- $2 = Math_imul($a$1, $y_sroa_0_0_extract_trunc) | 0;- return (tempRet0 = ((Math_imul($b$1, $x_sroa_0_0_extract_trunc) | 0) + $2 | 0) + $1$1 | $1$1 & 0, 0 | $1$0 & -1) | 0;-}-function ___udivdi3($a$0, $a$1, $b$0, $b$1) {- $a$0 = $a$0 | 0;- $a$1 = $a$1 | 0;- $b$0 = $b$0 | 0;- $b$1 = $b$1 | 0;- var $1$0 = 0;- $1$0 = ___udivmoddi4($a$0, $a$1, $b$0, $b$1, 0) | 0;- return $1$0 | 0;-}-function ___uremdi3($a$0, $a$1, $b$0, $b$1) {- $a$0 = $a$0 | 0;- $a$1 = $a$1 | 0;- $b$0 = $b$0 | 0;- $b$1 = $b$1 | 0;- var $rem = 0, __stackBase__ = 0;- __stackBase__ = STACKTOP;- STACKTOP = STACKTOP + 16 | 0;- $rem = __stackBase__ | 0;- ___udivmoddi4($a$0, $a$1, $b$0, $b$1, $rem) | 0;- STACKTOP = __stackBase__;- return (tempRet0 = HEAP32[$rem + 4 >> 2] | 0, HEAP32[$rem >> 2] | 0) | 0;-}-function ___udivmoddi4($a$0, $a$1, $b$0, $b$1, $rem) {- $a$0 = $a$0 | 0;- $a$1 = $a$1 | 0;- $b$0 = $b$0 | 0;- $b$1 = $b$1 | 0;- $rem = $rem | 0;- var $n_sroa_0_0_extract_trunc = 0, $n_sroa_1_4_extract_shift$0 = 0, $n_sroa_1_4_extract_trunc = 0, $d_sroa_0_0_extract_trunc = 0, $d_sroa_1_4_extract_shift$0 = 0, $d_sroa_1_4_extract_trunc = 0, $4 = 0, $17 = 0, $37 = 0, $49 = 0, $51 = 0, $57 = 0, $58 = 0, $66 = 0, $78 = 0, $86 = 0, $88 = 0, $89 = 0, $91 = 0, $92 = 0, $95 = 0, $105 = 0, $117 = 0, $119 = 0, $125 = 0, $126 = 0, $130 = 0, $q_sroa_1_1_ph = 0, $q_sroa_0_1_ph = 0, $r_sroa_1_1_ph = 0, $r_sroa_0_1_ph = 0, $sr_1_ph = 0, $d_sroa_0_0_insert_insert99$0 = 0, $d_sroa_0_0_insert_insert99$1 = 0, $137$0 = 0, $137$1 = 0, $carry_0203 = 0, $sr_1202 = 0, $r_sroa_0_1201 = 0, $r_sroa_1_1200 = 0, $q_sroa_0_1199 = 0, $q_sroa_1_1198 = 0, $147 = 0, $149 = 0, $r_sroa_0_0_insert_insert42$0 = 0, $r_sroa_0_0_insert_insert42$1 = 0, $150$1 = 0, $151$0 = 0, $152 = 0, $154$0 = 0, $r_sroa_0_0_extract_trunc = 0, $r_sroa_1_4_extract_trunc = 0, $155 = 0, $carry_0_lcssa$0 = 0, $carry_0_lcssa$1 = 0, $r_sroa_0_1_lcssa = 0, $r_sroa_1_1_lcssa = 0, $q_sroa_0_1_lcssa = 0, $q_sroa_1_1_lcssa = 0, $q_sroa_0_0_insert_ext75$0 = 0, $q_sroa_0_0_insert_ext75$1 = 0, $q_sroa_0_0_insert_insert77$1 = 0, $_0$0 = 0, $_0$1 = 0;- $n_sroa_0_0_extract_trunc = $a$0;- $n_sroa_1_4_extract_shift$0 = $a$1;- $n_sroa_1_4_extract_trunc = $n_sroa_1_4_extract_shift$0;- $d_sroa_0_0_extract_trunc = $b$0;- $d_sroa_1_4_extract_shift$0 = $b$1;- $d_sroa_1_4_extract_trunc = $d_sroa_1_4_extract_shift$0;- if (($n_sroa_1_4_extract_trunc | 0) == 0) {- $4 = ($rem | 0) != 0;- if (($d_sroa_1_4_extract_trunc | 0) == 0) {- if ($4) {- HEAP32[$rem >> 2] = ($n_sroa_0_0_extract_trunc >>> 0) % ($d_sroa_0_0_extract_trunc >>> 0);- HEAP32[$rem + 4 >> 2] = 0;- }- $_0$1 = 0;- $_0$0 = ($n_sroa_0_0_extract_trunc >>> 0) / ($d_sroa_0_0_extract_trunc >>> 0) >>> 0;- return (tempRet0 = $_0$1, $_0$0) | 0;- } else {- if (!$4) {- $_0$1 = 0;- $_0$0 = 0;- return (tempRet0 = $_0$1, $_0$0) | 0;- }- HEAP32[$rem >> 2] = $a$0 & -1;- HEAP32[$rem + 4 >> 2] = $a$1 & 0;- $_0$1 = 0;- $_0$0 = 0;- return (tempRet0 = $_0$1, $_0$0) | 0;- }- }- $17 = ($d_sroa_1_4_extract_trunc | 0) == 0;- do {- if (($d_sroa_0_0_extract_trunc | 0) == 0) {- if ($17) {- if (($rem | 0) != 0) {- HEAP32[$rem >> 2] = ($n_sroa_1_4_extract_trunc >>> 0) % ($d_sroa_0_0_extract_trunc >>> 0);- HEAP32[$rem + 4 >> 2] = 0;- }- $_0$1 = 0;- $_0$0 = ($n_sroa_1_4_extract_trunc >>> 0) / ($d_sroa_0_0_extract_trunc >>> 0) >>> 0;- return (tempRet0 = $_0$1, $_0$0) | 0;- }- if (($n_sroa_0_0_extract_trunc | 0) == 0) {- if (($rem | 0) != 0) {- HEAP32[$rem >> 2] = 0;- HEAP32[$rem + 4 >> 2] = ($n_sroa_1_4_extract_trunc >>> 0) % ($d_sroa_1_4_extract_trunc >>> 0);- }- $_0$1 = 0;- $_0$0 = ($n_sroa_1_4_extract_trunc >>> 0) / ($d_sroa_1_4_extract_trunc >>> 0) >>> 0;- return (tempRet0 = $_0$1, $_0$0) | 0;- }- $37 = $d_sroa_1_4_extract_trunc - 1 | 0;- if (($37 & $d_sroa_1_4_extract_trunc | 0) == 0) {- if (($rem | 0) != 0) {- HEAP32[$rem >> 2] = 0 | $a$0 & -1;- HEAP32[$rem + 4 >> 2] = $37 & $n_sroa_1_4_extract_trunc | $a$1 & 0;- }- $_0$1 = 0;- $_0$0 = $n_sroa_1_4_extract_trunc >>> ((_llvm_cttz_i32($d_sroa_1_4_extract_trunc | 0) | 0) >>> 0);- return (tempRet0 = $_0$1, $_0$0) | 0;- }- $49 = Math_clz32($d_sroa_1_4_extract_trunc | 0) | 0;- $51 = $49 - (Math_clz32($n_sroa_1_4_extract_trunc | 0) | 0) | 0;- if ($51 >>> 0 <= 30) {- $57 = $51 + 1 | 0;- $58 = 31 - $51 | 0;- $sr_1_ph = $57;- $r_sroa_0_1_ph = $n_sroa_1_4_extract_trunc << $58 | $n_sroa_0_0_extract_trunc >>> ($57 >>> 0);- $r_sroa_1_1_ph = $n_sroa_1_4_extract_trunc >>> ($57 >>> 0);- $q_sroa_0_1_ph = 0;- $q_sroa_1_1_ph = $n_sroa_0_0_extract_trunc << $58;- break;- }- if (($rem | 0) == 0) {- $_0$1 = 0;- $_0$0 = 0;- return (tempRet0 = $_0$1, $_0$0) | 0;- }- HEAP32[$rem >> 2] = 0 | $a$0 & -1;- HEAP32[$rem + 4 >> 2] = $n_sroa_1_4_extract_shift$0 | $a$1 & 0;- $_0$1 = 0;- $_0$0 = 0;- return (tempRet0 = $_0$1, $_0$0) | 0;- } else {- if (!$17) {- $117 = Math_clz32($d_sroa_1_4_extract_trunc | 0) | 0;- $119 = $117 - (Math_clz32($n_sroa_1_4_extract_trunc | 0) | 0) | 0;- if ($119 >>> 0 <= 31) {- $125 = $119 + 1 | 0;- $126 = 31 - $119 | 0;- $130 = $119 - 31 >> 31;- $sr_1_ph = $125;- $r_sroa_0_1_ph = $n_sroa_0_0_extract_trunc >>> ($125 >>> 0) & $130 | $n_sroa_1_4_extract_trunc << $126;- $r_sroa_1_1_ph = $n_sroa_1_4_extract_trunc >>> ($125 >>> 0) & $130;- $q_sroa_0_1_ph = 0;- $q_sroa_1_1_ph = $n_sroa_0_0_extract_trunc << $126;- break;- }- if (($rem | 0) == 0) {- $_0$1 = 0;- $_0$0 = 0;- return (tempRet0 = $_0$1, $_0$0) | 0;- }- HEAP32[$rem >> 2] = 0 | $a$0 & -1;- HEAP32[$rem + 4 >> 2] = $n_sroa_1_4_extract_shift$0 | $a$1 & 0;- $_0$1 = 0;- $_0$0 = 0;- return (tempRet0 = $_0$1, $_0$0) | 0;- }- $66 = $d_sroa_0_0_extract_trunc - 1 | 0;- if (($66 & $d_sroa_0_0_extract_trunc | 0) != 0) {- $86 = (Math_clz32($d_sroa_0_0_extract_trunc | 0) | 0) + 33 | 0;- $88 = $86 - (Math_clz32($n_sroa_1_4_extract_trunc | 0) | 0) | 0;- $89 = 64 - $88 | 0;- $91 = 32 - $88 | 0;- $92 = $91 >> 31;- $95 = $88 - 32 | 0;- $105 = $95 >> 31;- $sr_1_ph = $88;- $r_sroa_0_1_ph = $91 - 1 >> 31 & $n_sroa_1_4_extract_trunc >>> ($95 >>> 0) | ($n_sroa_1_4_extract_trunc << $91 | $n_sroa_0_0_extract_trunc >>> ($88 >>> 0)) & $105;- $r_sroa_1_1_ph = $105 & $n_sroa_1_4_extract_trunc >>> ($88 >>> 0);- $q_sroa_0_1_ph = $n_sroa_0_0_extract_trunc << $89 & $92;- $q_sroa_1_1_ph = ($n_sroa_1_4_extract_trunc << $89 | $n_sroa_0_0_extract_trunc >>> ($95 >>> 0)) & $92 | $n_sroa_0_0_extract_trunc << $91 & $88 - 33 >> 31;- break;- }- if (($rem | 0) != 0) {- HEAP32[$rem >> 2] = $66 & $n_sroa_0_0_extract_trunc;- HEAP32[$rem + 4 >> 2] = 0;- }- if (($d_sroa_0_0_extract_trunc | 0) == 1) {- $_0$1 = $n_sroa_1_4_extract_shift$0 | $a$1 & 0;- $_0$0 = 0 | $a$0 & -1;- return (tempRet0 = $_0$1, $_0$0) | 0;- } else {- $78 = _llvm_cttz_i32($d_sroa_0_0_extract_trunc | 0) | 0;- $_0$1 = 0 | $n_sroa_1_4_extract_trunc >>> ($78 >>> 0);- $_0$0 = $n_sroa_1_4_extract_trunc << 32 - $78 | $n_sroa_0_0_extract_trunc >>> ($78 >>> 0) | 0;- return (tempRet0 = $_0$1, $_0$0) | 0;- }- }- } while (0);- if (($sr_1_ph | 0) == 0) {- $q_sroa_1_1_lcssa = $q_sroa_1_1_ph;- $q_sroa_0_1_lcssa = $q_sroa_0_1_ph;- $r_sroa_1_1_lcssa = $r_sroa_1_1_ph;- $r_sroa_0_1_lcssa = $r_sroa_0_1_ph;- $carry_0_lcssa$1 = 0;- $carry_0_lcssa$0 = 0;- } else {- $d_sroa_0_0_insert_insert99$0 = 0 | $b$0 & -1;- $d_sroa_0_0_insert_insert99$1 = $d_sroa_1_4_extract_shift$0 | $b$1 & 0;- $137$0 = _i64Add($d_sroa_0_0_insert_insert99$0 | 0, $d_sroa_0_0_insert_insert99$1 | 0, -1, -1) | 0;- $137$1 = tempRet0;- $q_sroa_1_1198 = $q_sroa_1_1_ph;- $q_sroa_0_1199 = $q_sroa_0_1_ph;- $r_sroa_1_1200 = $r_sroa_1_1_ph;- $r_sroa_0_1201 = $r_sroa_0_1_ph;- $sr_1202 = $sr_1_ph;- $carry_0203 = 0;- while (1) {- $147 = $q_sroa_0_1199 >>> 31 | $q_sroa_1_1198 << 1;- $149 = $carry_0203 | $q_sroa_0_1199 << 1;- $r_sroa_0_0_insert_insert42$0 = 0 | ($r_sroa_0_1201 << 1 | $q_sroa_1_1198 >>> 31);- $r_sroa_0_0_insert_insert42$1 = $r_sroa_0_1201 >>> 31 | $r_sroa_1_1200 << 1 | 0;- _i64Subtract($137$0, $137$1, $r_sroa_0_0_insert_insert42$0, $r_sroa_0_0_insert_insert42$1) | 0;- $150$1 = tempRet0;- $151$0 = $150$1 >> 31 | (($150$1 | 0) < 0 ? -1 : 0) << 1;- $152 = $151$0 & 1;- $154$0 = _i64Subtract($r_sroa_0_0_insert_insert42$0, $r_sroa_0_0_insert_insert42$1, $151$0 & $d_sroa_0_0_insert_insert99$0, ((($150$1 | 0) < 0 ? -1 : 0) >> 31 | (($150$1 | 0) < 0 ? -1 : 0) << 1) & $d_sroa_0_0_insert_insert99$1) | 0;- $r_sroa_0_0_extract_trunc = $154$0;- $r_sroa_1_4_extract_trunc = tempRet0;- $155 = $sr_1202 - 1 | 0;- if (($155 | 0) == 0) {- break;- } else {- $q_sroa_1_1198 = $147;- $q_sroa_0_1199 = $149;- $r_sroa_1_1200 = $r_sroa_1_4_extract_trunc;- $r_sroa_0_1201 = $r_sroa_0_0_extract_trunc;- $sr_1202 = $155;- $carry_0203 = $152;- }- }- $q_sroa_1_1_lcssa = $147;- $q_sroa_0_1_lcssa = $149;- $r_sroa_1_1_lcssa = $r_sroa_1_4_extract_trunc;- $r_sroa_0_1_lcssa = $r_sroa_0_0_extract_trunc;- $carry_0_lcssa$1 = 0;- $carry_0_lcssa$0 = $152;- }- $q_sroa_0_0_insert_ext75$0 = $q_sroa_0_1_lcssa;- $q_sroa_0_0_insert_ext75$1 = 0;- $q_sroa_0_0_insert_insert77$1 = $q_sroa_1_1_lcssa | $q_sroa_0_0_insert_ext75$1;- if (($rem | 0) != 0) {- HEAP32[$rem >> 2] = 0 | $r_sroa_0_1_lcssa;- HEAP32[$rem + 4 >> 2] = $r_sroa_1_1_lcssa | 0;- }- $_0$1 = (0 | $q_sroa_0_0_insert_ext75$0) >>> 31 | $q_sroa_0_0_insert_insert77$1 << 1 | ($q_sroa_0_0_insert_ext75$1 << 1 | $q_sroa_0_0_insert_ext75$0 >>> 31) & 0 | $carry_0_lcssa$1;- $_0$0 = ($q_sroa_0_0_insert_ext75$0 << 1 | 0 >>> 31) & -2 | $carry_0_lcssa$0;- return (tempRet0 = $_0$1, $_0$0) | 0;-}-// =======================================================================---- -function dynCall_ii(index,a1) {- index = index|0;- a1=a1|0;- return FUNCTION_TABLE_ii[index&1](a1|0)|0;-}---function dynCall_iiii(index,a1,a2,a3) {- index = index|0;- a1=a1|0; a2=a2|0; a3=a3|0;- return FUNCTION_TABLE_iiii[index&7](a1|0,a2|0,a3|0)|0;-}---function dynCall_vi(index,a1) {- index = index|0;- a1=a1|0;- FUNCTION_TABLE_vi[index&7](a1|0);-}--function b0(p0) {- p0 = p0|0; nullFunc_ii(0);return 0;-}-function b1(p0,p1,p2) {- p0 = p0|0;p1 = p1|0;p2 = p2|0; nullFunc_iiii(1);return 0;-}-function b2(p0) {- p0 = p0|0; nullFunc_vi(2);-}--// EMSCRIPTEN_END_FUNCS-var FUNCTION_TABLE_ii = [b0,___stdio_close];-var FUNCTION_TABLE_iiii = [b1,b1,___stdout_write,___stdio_seek,___stdio_write,b1,b1,b1];-var FUNCTION_TABLE_vi = [b2,b2,b2,b2,b2,_cleanup,b2,b2];-- return { _i64Subtract: _i64Subtract, _free: _free, _main: _main, _i64Add: _i64Add, _memset: _memset, _malloc: _malloc, _memcpy: _memcpy, _bitshift64Lshr: _bitshift64Lshr, _fflush: _fflush, ___errno_location: ___errno_location, _bitshift64Shl: _bitshift64Shl, runPostSets: runPostSets, stackAlloc: stackAlloc, stackSave: stackSave, stackRestore: stackRestore, establishStackSpace: establishStackSpace, setThrew: setThrew, setTempRet0: setTempRet0, getTempRet0: getTempRet0, dynCall_ii: dynCall_ii, dynCall_iiii: dynCall_iiii, dynCall_vi: dynCall_vi, ___udivmoddi4: ___udivmoddi4 };-})-;
− binaryen/test/empty.asm.js
@@ -1,4 +0,0 @@-function EmptyModule() {- 'use asm';- return {};-}
− binaryen/test/empty_4GB.asm.js
@@ -1,4 +0,0 @@-function EmptyModule() {- 'use asm';- return {};-}
binaryen/test/example/c-api-kitchen-sink.c view
@@ -310,7 +310,8 @@ temp15 = makeInt32(module, 110), temp16 = makeInt64(module, 111); BinaryenExpressionRef externrefExpr = BinaryenRefNull(module, BinaryenTypeExternref()); BinaryenExpressionRef funcrefExpr = BinaryenRefNull(module, BinaryenTypeFuncref());- funcrefExpr = BinaryenRefFunc(module, "kitchen()sinker");+ funcrefExpr =+ BinaryenRefFunc(module, "kitchen()sinker", BinaryenTypeFuncref()); BinaryenExpressionRef exnrefExpr = BinaryenRefNull(module, BinaryenTypeExnref()); BinaryenExpressionRef i31refExpr = BinaryenI31New(module, makeInt32(module, 1)); @@ -434,8 +435,6 @@ makeUnary(module, BinaryenAllTrueVecI32x4(), v128), makeUnary(module, BinaryenBitmaskVecI32x4(), v128), makeUnary(module, BinaryenNegVecI64x2(), v128),- makeUnary(module, BinaryenAnyTrueVecI64x2(), v128),- makeUnary(module, BinaryenAllTrueVecI64x2(), v128), makeUnary(module, BinaryenAbsVecF32x4(), v128), makeUnary(module, BinaryenNegVecF32x4(), v128), makeUnary(module, BinaryenSqrtVecF32x4(), v128),@@ -580,10 +579,10 @@ makeBinary(module, BinaryenMaxVecF32x4(), v128), makeBinary(module, BinaryenPMinVecF32x4(), v128), makeBinary(module, BinaryenPMaxVecF32x4(), v128),- makeBinary(module, BinaryenCeilVecF32x4(), v128),- makeBinary(module, BinaryenFloorVecF32x4(), v128),- makeBinary(module, BinaryenTruncVecF32x4(), v128),- makeBinary(module, BinaryenNearestVecF32x4(), v128),+ makeUnary(module, BinaryenCeilVecF32x4(), v128),+ makeUnary(module, BinaryenFloorVecF32x4(), v128),+ makeUnary(module, BinaryenTruncVecF32x4(), v128),+ makeUnary(module, BinaryenNearestVecF32x4(), v128), makeBinary(module, BinaryenAddVecF64x2(), v128), makeBinary(module, BinaryenSubVecF64x2(), v128), makeBinary(module, BinaryenMulVecF64x2(), v128),@@ -592,10 +591,10 @@ makeBinary(module, BinaryenMaxVecF64x2(), v128), makeBinary(module, BinaryenPMinVecF64x2(), v128), makeBinary(module, BinaryenPMaxVecF64x2(), v128),- makeBinary(module, BinaryenCeilVecF64x2(), v128),- makeBinary(module, BinaryenFloorVecF64x2(), v128),- makeBinary(module, BinaryenTruncVecF64x2(), v128),- makeBinary(module, BinaryenNearestVecF64x2(), v128),+ makeUnary(module, BinaryenCeilVecF64x2(), v128),+ makeUnary(module, BinaryenFloorVecF64x2(), v128),+ makeUnary(module, BinaryenTruncVecF64x2(), v128),+ makeUnary(module, BinaryenNearestVecF64x2(), v128), makeBinary(module, BinaryenNarrowSVecI16x8ToVecI8x16(), v128), makeBinary(module, BinaryenNarrowUVecI16x8ToVecI8x16(), v128), makeBinary(module, BinaryenNarrowSVecI32x4ToVecI16x8(), v128),@@ -737,15 +736,16 @@ BinaryenRefIsNull(module, externrefExpr), BinaryenRefIsNull(module, funcrefExpr), BinaryenRefIsNull(module, exnrefExpr),- BinaryenSelect(module,- temp10,- BinaryenRefNull(module, BinaryenTypeFuncref()),- BinaryenRefFunc(module, "kitchen()sinker"),- BinaryenTypeFuncref()),+ BinaryenSelect(+ module,+ temp10,+ BinaryenRefNull(module, BinaryenTypeFuncref()),+ BinaryenRefFunc(module, "kitchen()sinker", BinaryenTypeFuncref()),+ BinaryenTypeFuncref()), // GC BinaryenRefEq(module,- BinaryenRefNull(module, BinaryenTypeEqref()),- BinaryenRefNull(module, BinaryenTypeEqref())),+ BinaryenRefNull(module, BinaryenTypeEqref()),+ BinaryenRefNull(module, BinaryenTypeEqref())), // Exception handling BinaryenTry(module, tryBody, catchBody), // Atomics@@ -1365,6 +1365,31 @@ BinaryenModuleDispose(module); } +void test_func_opt() {+ BinaryenModuleRef module = BinaryenModuleCreate();+ BinaryenType ii_[2] = {BinaryenTypeInt32(), BinaryenTypeInt32()};+ BinaryenType ii = BinaryenTypeCreate(ii_, 2);+ BinaryenExpressionRef x = BinaryenConst(module, BinaryenLiteralInt32(1)),+ y = BinaryenConst(module, BinaryenLiteralInt32(3));+ BinaryenExpressionRef add = BinaryenBinary(module, BinaryenAddInt32(), x, y);+ BinaryenFunctionRef adder = BinaryenAddFunction(+ module, "adder", BinaryenTypeNone(), BinaryenTypeInt32(), NULL, 0, add);++ puts("module with a function to optimize:");+ BinaryenModulePrint(module);++ assert(BinaryenModuleValidate(module));++ BinaryenFunctionOptimize(adder, module);++ assert(BinaryenModuleValidate(module));++ puts("optimized:");+ BinaryenModulePrint(module);++ BinaryenModuleDispose(module);+}+ int main() { test_types(); test_features();@@ -1376,6 +1401,7 @@ test_nonvalid(); test_color_status(); test_for_each();+ test_func_opt(); return 0; }
binaryen/test/example/c-api-kitchen-sink.txt view
@@ -25,7 +25,7 @@ BinaryenFeatureMultivalue: 512 BinaryenFeatureGC: 1024 BinaryenFeatureMemory64: 2048-BinaryenFeatureAll: 4095+BinaryenFeatureAll: 8191 (f32.neg (f32.const -33.61199951171875) )@@ -389,16 +389,6 @@ ) ) (drop- (i64x2.any_true- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i64x2.all_true- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop (f32x4.abs (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d) )@@ -1235,26 +1225,22 @@ ) ) (drop- (i16x8.lt_s- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)+ (f32x4.ceil (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d) ) ) (drop- (i16x8.lt_u- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)+ (f32x4.floor (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d) ) ) (drop- (i16x8.gt_s- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)+ (f32x4.trunc (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d) ) ) (drop- (i16x8.gt_u- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)+ (f32x4.nearest (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d) ) )@@ -1307,26 +1293,22 @@ ) ) (drop- (i16x8.ge_u- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)+ (f64x2.ceil (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d) ) ) (drop- (i32x4.eq- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)+ (f64x2.floor (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d) ) ) (drop- (i32x4.ne- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)+ (f64x2.trunc (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d) ) ) (drop- (i32x4.lt_s- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)+ (f64x2.nearest (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d) ) )@@ -1811,14 +1793,14 @@ ) ) (drop- (i32.atomic.wait+ (memory.atomic.wait32 (i32.const 0) (i32.const 0) (i64.const 111) ) ) (drop- (atomic.notify+ (memory.atomic.notify (i32.const 0) (i32.const 0) )@@ -2456,5 +2438,22 @@ ) (func $fn2 (nop)+ )+)+module with a function to optimize:+(module+ (type $none_=>_i32 (func (result i32)))+ (func $adder (result i32)+ (i32.add+ (i32.const 1)+ (i32.const 3)+ )+ )+)+optimized:+(module+ (type $none_=>_i32 (func (result i32)))+ (func $adder (result i32)+ (i32.const 4) ) )
− binaryen/test/example/c-api-kitchen-sink.txt.txt
@@ -1,2236 +0,0 @@-(f32.neg- (f32.const -33.61199951171875)-)-(module- (type $i32_i64_f32_f64_=>_i32 (func (param i32 i64 f32 f64) (result i32)))- (type $none_=>_none (func))- (type $i32_=>_none (func (param i32)))- (type $i32_f64_=>_f32 (func (param i32 f64) (result f32)))- (import "module" "base" (func $an-imported (param i32 f64) (result f32)))- (memory $0 (shared 1 256))- (data (i32.const 10) "hello, world")- (data passive "I am passive")- (table $0 1 1 funcref)- (elem (i32.const 0) "$kitchen()sinker")- (global $a-global i32 (i32.const 7))- (global $a-mutable-global (mut f32) (f32.const 7.5))- (event $a-event (attr 0) (param i32))- (export "kitchen_sinker" (func "$kitchen()sinker"))- (export "mem" (memory $0))- (start $starter)- (func "$kitchen()sinker" (param $0 i32) (param $1 i64) (param $2 f32) (param $3 f64) (result i32)- (local $4 i32)- (local $5 exnref)- (block $the-body (result i32)- (block $the-nothing- (drop- (block $the-value (result i32)- (drop- (i32.clz- (i32.const -10)- )- )- (drop- (i64.ctz- (i64.const -22)- )- )- (drop- (i32.popcnt- (i32.const -10)- )- )- (drop- (f32.neg- (f32.const -33.61199951171875)- )- )- (drop- (f64.abs- (f64.const -9005.84)- )- )- (drop- (f32.ceil- (f32.const -33.61199951171875)- )- )- (drop- (f64.floor- (f64.const -9005.84)- )- )- (drop- (f32.trunc- (f32.const -33.61199951171875)- )- )- (drop- (f32.nearest- (f32.const -33.61199951171875)- )- )- (drop- (f64.sqrt- (f64.const -9005.84)- )- )- (drop- (i32.eqz- (i32.const -10)- )- )- (drop- (i64.extend_i32_s- (i32.const -10)- )- )- (drop- (i64.extend_i32_u- (i32.const -10)- )- )- (drop- (i32.wrap_i64- (i64.const -22)- )- )- (drop- (i32.trunc_f32_s- (f32.const -33.61199951171875)- )- )- (drop- (i64.trunc_f32_s- (f32.const -33.61199951171875)- )- )- (drop- (i32.trunc_f32_u- (f32.const -33.61199951171875)- )- )- (drop- (i64.trunc_f32_u- (f32.const -33.61199951171875)- )- )- (drop- (i32.trunc_f64_s- (f64.const -9005.84)- )- )- (drop- (i64.trunc_f64_s- (f64.const -9005.84)- )- )- (drop- (i32.trunc_f64_u- (f64.const -9005.84)- )- )- (drop- (i64.trunc_f64_u- (f64.const -9005.84)- )- )- (drop- (i32.trunc_sat_f32_s- (f32.const -33.61199951171875)- )- )- (drop- (i64.trunc_sat_f32_s- (f32.const -33.61199951171875)- )- )- (drop- (i32.trunc_sat_f32_u- (f32.const -33.61199951171875)- )- )- (drop- (i64.trunc_sat_f32_u- (f32.const -33.61199951171875)- )- )- (drop- (i32.trunc_sat_f64_s- (f64.const -9005.84)- )- )- (drop- (i64.trunc_sat_f64_s- (f64.const -9005.84)- )- )- (drop- (i32.trunc_sat_f64_u- (f64.const -9005.84)- )- )- (drop- (i64.trunc_sat_f64_u- (f64.const -9005.84)- )- )- (drop- (i32.reinterpret_f32- (f32.const -33.61199951171875)- )- )- (drop- (i64.reinterpret_f64- (f64.const -9005.84)- )- )- (drop- (f32.convert_i32_s- (i32.const -10)- )- )- (drop- (f64.convert_i32_s- (i32.const -10)- )- )- (drop- (f32.convert_i32_u- (i32.const -10)- )- )- (drop- (f64.convert_i32_u- (i32.const -10)- )- )- (drop- (f32.convert_i64_s- (i64.const -22)- )- )- (drop- (f64.convert_i64_s- (i64.const -22)- )- )- (drop- (f32.convert_i64_u- (i64.const -22)- )- )- (drop- (f64.convert_i64_u- (i64.const -22)- )- )- (drop- (f64.promote_f32- (f32.const -33.61199951171875)- )- )- (drop- (f32.demote_f64- (f64.const -9005.84)- )- )- (drop- (f32.reinterpret_i32- (i32.const -10)- )- )- (drop- (f64.reinterpret_i64- (i64.const -22)- )- )- (drop- (i8x16.splat- (i32.const -10)- )- )- (drop- (i16x8.splat- (i32.const -10)- )- )- (drop- (i32x4.splat- (i32.const -10)- )- )- (drop- (i64x2.splat- (i64.const -22)- )- )- (drop- (f32x4.splat- (f32.const -33.61199951171875)- )- )- (drop- (f64x2.splat- (f64.const -9005.84)- )- )- (drop- (v128.not- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i8x16.abs- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i8x16.neg- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i8x16.any_true- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i8x16.all_true- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i8x16.bitmask- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i16x8.abs- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i16x8.neg- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i16x8.any_true- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i16x8.all_true- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i16x8.bitmask- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i32x4.abs- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i32x4.neg- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i32x4.any_true- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i32x4.all_true- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i32x4.bitmask- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i64x2.neg- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i64x2.any_true- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i64x2.all_true- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (f32x4.abs- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (f32x4.neg- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (f32x4.sqrt- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (f64x2.abs- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (f64x2.neg- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (f64x2.sqrt- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i32x4.trunc_sat_f32x4_s- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i32x4.trunc_sat_f32x4_u- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i64x2.trunc_sat_f64x2_s- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i64x2.trunc_sat_f64x2_u- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (f32x4.convert_i32x4_s- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (f32x4.convert_i32x4_u- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (f64x2.convert_i64x2_s- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (f64x2.convert_i64x2_u- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i16x8.widen_low_i8x16_s- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i16x8.widen_high_i8x16_s- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i16x8.widen_low_i8x16_u- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i16x8.widen_high_i8x16_u- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i32x4.widen_low_i16x8_s- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i32x4.widen_high_i16x8_s- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i32x4.widen_low_i16x8_u- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i32x4.widen_high_i16x8_u- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i32.add- (i32.const -10)- (i32.const -11)- )- )- (drop- (f64.sub- (f64.const -9005.84)- (f64.const -9007.33)- )- )- (drop- (i32.div_s- (i32.const -10)- (i32.const -11)- )- )- (drop- (i64.div_u- (i64.const -22)- (i64.const -23)- )- )- (drop- (i64.rem_s- (i64.const -22)- (i64.const -23)- )- )- (drop- (i32.rem_u- (i32.const -10)- (i32.const -11)- )- )- (drop- (i32.and- (i32.const -10)- (i32.const -11)- )- )- (drop- (i64.or- (i64.const -22)- (i64.const -23)- )- )- (drop- (i32.xor- (i32.const -10)- (i32.const -11)- )- )- (drop- (i64.shl- (i64.const -22)- (i64.const -23)- )- )- (drop- (i64.shr_u- (i64.const -22)- (i64.const -23)- )- )- (drop- (i32.shr_s- (i32.const -10)- (i32.const -11)- )- )- (drop- (i32.rotl- (i32.const -10)- (i32.const -11)- )- )- (drop- (i64.rotr- (i64.const -22)- (i64.const -23)- )- )- (drop- (f32.div- (f32.const -33.61199951171875)- (f32.const -62.5)- )- )- (drop- (f64.copysign- (f64.const -9005.84)- (f64.const -9007.33)- )- )- (drop- (f32.min- (f32.const -33.61199951171875)- (f32.const -62.5)- )- )- (drop- (f64.max- (f64.const -9005.84)- (f64.const -9007.33)- )- )- (drop- (i32.eq- (i32.const -10)- (i32.const -11)- )- )- (drop- (f32.ne- (f32.const -33.61199951171875)- (f32.const -62.5)- )- )- (drop- (i32.lt_s- (i32.const -10)- (i32.const -11)- )- )- (drop- (i64.lt_u- (i64.const -22)- (i64.const -23)- )- )- (drop- (i64.le_s- (i64.const -22)- (i64.const -23)- )- )- (drop- (i32.le_u- (i32.const -10)- (i32.const -11)- )- )- (drop- (i64.gt_s- (i64.const -22)- (i64.const -23)- )- )- (drop- (i32.gt_u- (i32.const -10)- (i32.const -11)- )- )- (drop- (i32.ge_s- (i32.const -10)- (i32.const -11)- )- )- (drop- (i64.ge_u- (i64.const -22)- (i64.const -23)- )- )- (drop- (f32.lt- (f32.const -33.61199951171875)- (f32.const -62.5)- )- )- (drop- (f64.le- (f64.const -9005.84)- (f64.const -9007.33)- )- )- (drop- (f64.gt- (f64.const -9005.84)- (f64.const -9007.33)- )- )- (drop- (f32.ge- (f32.const -33.61199951171875)- (f32.const -62.5)- )- )- (drop- (i8x16.eq- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i8x16.ne- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i8x16.lt_s- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i8x16.lt_u- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i8x16.gt_s- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i8x16.gt_u- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i8x16.le_s- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i8x16.le_u- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i8x16.ge_s- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i8x16.ge_u- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i16x8.eq- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i16x8.ne- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i16x8.lt_s- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i16x8.lt_u- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i16x8.gt_s- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i16x8.gt_u- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i16x8.le_s- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i16x8.le_u- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i16x8.ge_s- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i16x8.ge_u- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i32x4.eq- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i32x4.ne- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i32x4.lt_s- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i32x4.lt_u- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i32x4.gt_s- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i32x4.gt_u- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i32x4.le_s- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i32x4.le_u- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i32x4.ge_s- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i32x4.ge_u- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (f32x4.eq- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (f32x4.ne- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (f32x4.lt- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (f32x4.gt- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (f32x4.le- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (f32x4.ge- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (f64x2.eq- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (f64x2.ne- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (f64x2.lt- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (f64x2.gt- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (f64x2.le- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (f64x2.ge- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (v128.and- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (v128.or- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (v128.xor- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (v128.andnot- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i8x16.add- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i8x16.add_saturate_s- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i8x16.add_saturate_u- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i8x16.sub- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i8x16.sub_saturate_s- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i8x16.sub_saturate_u- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i8x16.mul- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i8x16.min_s- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i8x16.min_u- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i8x16.max_s- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i8x16.max_u- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i8x16.avgr_u- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i16x8.add- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i16x8.add_saturate_s- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i16x8.add_saturate_u- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i16x8.sub- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i16x8.sub_saturate_s- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i16x8.sub_saturate_u- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i16x8.mul- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i16x8.min_s- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i16x8.min_u- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i16x8.max_s- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i16x8.max_u- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i16x8.avgr_u- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i32x4.add- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i32x4.sub- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i32x4.mul- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i64x2.add- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i64x2.sub- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (f32x4.add- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (f32x4.sub- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (f32x4.mul- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i32x4.min_s- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i32x4.min_u- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i32x4.max_s- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i32x4.max_u- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i32x4.dot_i16x8_s- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (f32x4.div- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (f32x4.min- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (f32x4.max- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (f64x2.add- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (f64x2.sub- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (f64x2.mul- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (f64x2.div- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (f64x2.min- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (f64x2.max- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i8x16.narrow_i16x8_s- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i8x16.narrow_i16x8_u- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i16x8.narrow_i32x4_s- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i16x8.narrow_i32x4_u- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (v8x16.swizzle- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i8x16.extract_lane_s 0- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i8x16.extract_lane_u 0- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i16x8.extract_lane_s 0- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i16x8.extract_lane_u 0- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i32x4.extract_lane 0- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i64x2.extract_lane 0- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (f32x4.extract_lane 0- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (f64x2.extract_lane 0- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (i8x16.replace_lane 0- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (i32.const 42)- )- )- (drop- (i16x8.replace_lane 0- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (i32.const 42)- )- )- (drop- (i32x4.replace_lane 0- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (i32.const 42)- )- )- (drop- (i64x2.replace_lane 0- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (i64.const 42)- )- )- (drop- (f32x4.replace_lane 0- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (f32.const 42)- )- )- (drop- (f64x2.replace_lane 0- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (f64.const 42)- )- )- (drop- (i8x16.shl- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (i32.const 1)- )- )- (drop- (i8x16.shr_s- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (i32.const 1)- )- )- (drop- (i8x16.shr_u- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (i32.const 1)- )- )- (drop- (i16x8.shl- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (i32.const 1)- )- )- (drop- (i16x8.shr_s- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (i32.const 1)- )- )- (drop- (i16x8.shr_u- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (i32.const 1)- )- )- (drop- (i32x4.shl- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (i32.const 1)- )- )- (drop- (i32x4.shr_s- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (i32.const 1)- )- )- (drop- (i32x4.shr_u- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (i32.const 1)- )- )- (drop- (i64x2.shl- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (i32.const 1)- )- )- (drop- (i64x2.shr_s- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (i32.const 1)- )- )- (drop- (i64x2.shr_u- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (i32.const 1)- )- )- (drop- (v8x16.load_splat- (i32.const 128)- )- )- (drop- (v16x8.load_splat offset=16 align=1- (i32.const 128)- )- )- (drop- (v32x4.load_splat offset=16- (i32.const 128)- )- )- (drop- (v64x2.load_splat align=4- (i32.const 128)- )- )- (drop- (i16x8.load8x8_s- (i32.const 128)- )- )- (drop- (i16x8.load8x8_u- (i32.const 128)- )- )- (drop- (i32x4.load16x4_s- (i32.const 128)- )- )- (drop- (i32x4.load16x4_u- (i32.const 128)- )- )- (drop- (i64x2.load32x2_s- (i32.const 128)- )- )- (drop- (i64x2.load32x2_u- (i32.const 128)- )- )- (drop- (v8x16.shuffle 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (v128.bitselect- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (f32x4.qfma- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (f32x4.qfms- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (f64x2.qfma- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (drop- (f64x2.qfms- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)- )- )- (memory.init 0- (i32.const 1024)- (i32.const 0)- (i32.const 12)- )- (data.drop 0)- (memory.copy- (i32.const 2048)- (i32.const 1024)- (i32.const 12)- )- (memory.fill- (i32.const 0)- (i32.const 42)- (i32.const 1024)- )- (block- )- (if- (i32.const 1)- (drop- (i32.const 2)- )- (drop- (i32.const 3)- )- )- (if- (i32.const 4)- (drop- (i32.const 5)- )- )- (drop- (loop $in (result i32)- (i32.const 0)- )- )- (drop- (loop (result i32)- (i32.const 0)- )- )- (drop- (br_if $the-value- (i32.const 1)- (i32.const 0)- )- )- (br_if $the-nothing- (i32.const 2)- )- (br $the-value- (i32.const 3)- )- (br $the-nothing)- (br_table $the-value $the-value- (i32.const 1)- (i32.const 0)- )- (br_table $the-nothing $the-nothing- (i32.const 2)- )- (drop- (i32.eqz- (call "$kitchen()sinker"- (i32.const 13)- (i64.const 37)- (f32.const 1.2999999523162842)- (f64.const 3.7)- )- )- )- (drop- (i32.eqz- (i32.trunc_f32_s- (call $an-imported- (i32.const 13)- (f64.const 3.7)- )- )- )- )- (drop- (i32.eqz- (call_indirect (type $i32_i64_f32_f64_=>_i32)- (i32.const 13)- (i64.const 37)- (f32.const 1.2999999523162842)- (f64.const 3.7)- (i32.const 2449)- )- )- )- (drop- (local.get $0)- )- (local.set $0- (i32.const 101)- )- (drop- (local.tee $0- (i32.const 102)- )- )- (drop- (i32.load- (i32.const 1)- )- )- (drop- (i64.load16_s offset=2 align=1- (i32.const 8)- )- )- (drop- (f32.load- (i32.const 2)- )- )- (drop- (f64.load offset=2- (i32.const 9)- )- )- (i32.store- (i32.const 10)- (i32.const 11)- )- (i64.store offset=2 align=4- (i32.const 110)- (i64.const 111)- )- (drop- (select- (i32.const 3)- (i32.const 5)- (i32.const 1)- )- )- (return- (i32.const 1337)- )- (return_call "$kitchen()sinker"- (i32.const 13)- (i64.const 37)- (f32.const 1.2999999523162842)- (f64.const 3.7)- )- (return_call_indirect (type $i32_i64_f32_f64_=>_i32)- (i32.const 13)- (i64.const 37)- (f32.const 1.2999999523162842)- (f64.const 3.7)- (i32.const 2449)- )- (drop- (ref.is_null- (ref.null)- )- )- (drop- (ref.is_null- (ref.func "$kitchen()sinker")- )- )- (drop- (select (result funcref)- (ref.null)- (ref.func "$kitchen()sinker")- (i32.const 1)- )- )- (try- (throw $a-event- (i32.const 0)- )- (catch- (local.set $5- (exnref.pop)- )- (drop- (block $try-block (result i32)- (rethrow- (br_on_exn $try-block $a-event- (local.get $5)- )- )- )- )- )- )- (i32.atomic.store- (i32.const 0)- (i32.atomic.load- (i32.const 0)- )- )- (drop- (i32.atomic.wait- (i32.const 0)- (i32.const 0)- (i64.const 111)- )- )- (drop- (atomic.notify- (i32.const 0)- (i32.const 0)- )- )- (atomic.fence)- (drop- (tuple.make- (i32.const 13)- (i64.const 37)- (f32.const 1.2999999523162842)- (f64.const 3.7)- )- )- (drop- (tuple.extract 2- (tuple.make- (i32.const 13)- (i64.const 37)- (f32.const 1.2999999523162842)- (f64.const 3.7)- )- )- )- (push- (i32.pop)- )- (push- (i64.pop)- )- (push- (f32.pop)- )- (push- (f64.pop)- )- (push- (funcref.pop)- )- (push- (externref.pop)- )- (push- (nullref.pop)- )- (push- (exnref.pop)- )- (push- (funcref.pop)- )- (push- (nullref.pop)- )- (push- (exnref.pop)- )- (nop)- (unreachable)- )- )- )- (i32.const 42)- )- )- (func $starter- (nop)- )-)-(module- (type $none_=>_none (func))- (type $i32_=>_none (func (param i32)))- (type $none_=>_i32 (func (result i32)))- (import "module" "check" (func $check (param i32)))- (func $just-one-block- (local $0 i32)- (call $check- (i32.const 1337)- )- )- (func $two-blocks- (local $0 i32)- (block- (call $check- (i32.const 0)- )- (call $check- (i32.const 1)- )- )- )- (func $two-blocks-plus-code- (local $0 i32)- (block- (block- (call $check- (i32.const 0)- )- (drop- (i32.const 77)- )- )- (call $check- (i32.const 1)- )- )- )- (func $loop- (local $0 i32)- (loop $shape$0$continue- (block- (call $check- (i32.const 0)- )- (call $check- (i32.const 1)- )- )- (block- (br $shape$0$continue)- )- )- )- (func $loop-plus-code- (local $0 i32)- (loop $shape$0$continue- (block- (block- (call $check- (i32.const 0)- )- (drop- (i32.const 33)- )- )- (call $check- (i32.const 1)- )- )- (block- (drop- (i32.const -66)- )- (br $shape$0$continue)- )- )- )- (func $split- (local $0 i32)- (call $check- (i32.const 0)- )- (if- (i32.const 55)- (block- (call $check- (i32.const 1)- )- )- (block- (call $check- (i32.const 2)- )- )- )- )- (func $split-plus-code- (local $0 i32)- (call $check- (i32.const 0)- )- (if- (i32.const 55)- (block- (drop- (i32.const 10)- )- (block- (call $check- (i32.const 1)- )- )- )- (block- (drop- (i32.const 20)- )- (block- (call $check- (i32.const 2)- )- )- )- )- )- (func $if- (local $0 i32)- (block $block$3$break- (call $check- (i32.const 0)- )- (if- (i32.const 55)- (block- (call $check- (i32.const 1)- )- (block- (br $block$3$break)- )- )- (br $block$3$break)- )- )- (block- (call $check- (i32.const 2)- )- )- )- (func $if-plus-code- (local $0 i32)- (block $block$3$break- (call $check- (i32.const 0)- )- (if- (i32.const 55)- (block- (drop- (i32.const -1)- )- (block- (call $check- (i32.const 1)- )- (block- (drop- (i32.const -3)- )- (br $block$3$break)- )- )- )- (block- (drop- (i32.const -2)- )- (br $block$3$break)- )- )- )- (block- (call $check- (i32.const 2)- )- )- )- (func $if-else- (local $0 i32)- (block $block$4$break- (call $check- (i32.const 0)- )- (if- (i32.const 55)- (block- (call $check- (i32.const 1)- )- (block- (br $block$4$break)- )- )- (block- (call $check- (i32.const 2)- )- (block- (br $block$4$break)- )- )- )- )- (block- (call $check- (i32.const 3)- )- )- )- (func $loop-tail- (local $0 i32)- (block $block$3$break- (loop $shape$0$continue- (block- (call $check- (i32.const 0)- )- (call $check- (i32.const 1)- )- )- (if- (i32.const 10)- (br $shape$0$continue)- (br $block$3$break)- )- )- )- (block- (call $check- (i32.const 2)- )- )- )- (func $nontrivial-loop-plus-phi-to-head- (local $0 i32)- (block $block$2$break- (call $check- (i32.const 0)- )- (block- (drop- (i32.const 10)- )- (br $block$2$break)- )- )- (block- (block $block$7$break- (block $block$4$break- (loop $shape$1$continue- (block $block$3$break- (call $check- (i32.const 1)- )- (if- (i32.const -2)- (br $block$3$break)- (block- (drop- (i32.const 20)- )- (br $block$7$break)- )- )- )- (block- (call $check- (i32.const 2)- )- (if- (i32.const -6)- (br $block$4$break)- (block- (drop- (i32.const 30)- )- (br $shape$1$continue)- )- )- )- )- )- (block- (block $block$6$break- (call $check- (i32.const 3)- )- (if- (i32.const -10)- (block- (call $check- (i32.const 4)- )- (block- (br $block$6$break)- )- )- (br $block$6$break)- )- )- (block- (call $check- (i32.const 5)- )- (block- (drop- (i32.const 40)- )- (br $block$7$break)- )- )- )- )- (block- (call $check- (i32.const 6)- )- )- )- )- (func $switch- (local $0 i32)- (call $check- (i32.const 0)- )- (block $switch$1$leave- (block $switch$1$default- (block $switch$1$case$3- (block $switch$1$case$2- (br_table $switch$1$default $switch$1$default $switch$1$case$2 $switch$1$default $switch$1$case$3 $switch$1$case$2 $switch$1$default- (i32.const -99)- )- )- (block- (block- (call $check- (i32.const 1)- )- )- )- (br $switch$1$leave)- )- (block- (drop- (i32.const 55)- )- (block- (call $check- (i32.const 2)- )- )- )- (br $switch$1$leave)- )- (block- (block- (call $check- (i32.const 3)- )- )- )- (br $switch$1$leave)- )- )- (func $duffs-device- (local $0 i32)- (local $1 i32)- (local $2 i64)- (local $3 i32)- (local $4 f32)- (local $5 f64)- (local $6 i32)- (block- (block $block$3$break- (block $block$2$break- (call $check- (i32.const 0)- )- (if- (i32.const 10)- (block- (local.set $3- (i32.const 2)- )- (br $block$2$break)- )- (block- (local.set $3- (i32.const 3)- )- (br $block$3$break)- )- )- )- )- )- (loop $shape$1$continue- (if- (i32.eq- (local.get $3)- (i32.const 2)- )- (block- (local.set $3- (i32.const 0)- )- (call $check- (i32.const 1)- )- (block- (local.set $3- (i32.const 3)- )- (br $shape$1$continue)- )- )- (if- (i32.eq- (local.get $3)- (i32.const 3)- )- (block- (local.set $3- (i32.const 0)- )- (call $check- (i32.const 2)- )- (block- (local.set $3- (i32.const 2)- )- (br $shape$1$continue)- )- )- )- )- )- )- (func $return (result i32)- (local $0 i32)- (block- (call $check- (i32.const 42)- )- (return- (i32.const 1337)- )- )- )-)-(module-)
binaryen/test/example/c-api-unused-mem.txt view
@@ -36,7 +36,7 @@ (call $main) ) )-151+145 (module (type $none_=>_none (func)) (memory $0 1024 1024)
binaryen/test/example/cpp-unit.cpp view
@@ -4,6 +4,8 @@ #include <ir/bits.h> #include <ir/cost.h>+#include <ir/effects.h>+#include <pass.h> #include <wasm.h> using namespace wasm;@@ -543,9 +545,21 @@ assert_equal(CostAnalyzer(&get).cost, 0); } +void test_effects() {+ PassOptions options;+ FeatureSet features;+ // Unreachables trap.+ Unreachable unreachable;+ assert_equal(EffectAnalyzer(options, features, &unreachable).trap, true);+ // Nops... do not.+ Nop nop;+ assert_equal(EffectAnalyzer(options, features, &nop).trap, false);+}+ int main() { test_bits(); test_cost();+ test_effects(); if (failsCount > 0) { abort();
+ binaryen/test/example/hash.cpp view
@@ -0,0 +1,142 @@+#include <cassert>+#include <iostream>++#include <ir/utils.h>++using namespace wasm;++#define assertEqual(left, right) \+ assert(ExpressionAnalyzer::hash(&left) == ExpressionAnalyzer::hash(&right));++#define assertNotEqual(left, right) \+ assert(ExpressionAnalyzer::hash(&left) != ExpressionAnalyzer::hash(&right));++int main() {+ {+ Const x, y;+ x.set(Literal(int32_t(10)));+ y.set(Literal(int32_t(10)));+ assertEqual(x, y);+ }+ {+ // The value matters (with extremely high probability...)+ Const x, y;+ x.set(Literal(int32_t(10)));+ y.set(Literal(int32_t(11)));+ assertNotEqual(x, y);+ }+ {+ // The type matters.+ Const x, y;+ x.set(Literal(int32_t(10)));+ y.set(Literal(int64_t(10)));+ assertNotEqual(x, y);+ }+ {+ // Nested child.+ Drop dx, dy;+ Const x, y;+ x.set(Literal(int32_t(10)));+ y.set(Literal(int32_t(10)));+ dx.value = &x;+ dy.value = &y;+ assertEqual(dx, dy);+ }+ {+ // Nested child.+ Drop dx, dy;+ Const x, y;+ x.set(Literal(int32_t(10)));+ y.set(Literal(int32_t(11)));+ dx.value = &x;+ dy.value = &y;+ assertNotEqual(dx, dy);+ }+ MixedArena arena;+ {+ // Blocks+ Block x(arena);+ Block y(arena);+ assertEqual(x, y);+ }+ {+ // Blocks with contents.+ Block x(arena);+ Block y(arena);+ Nop n;+ y.list.push_back(&n);+ assertNotEqual(x, y);+ }+ {+ // Blocks with names.+ Block x(arena);+ x.name = "foo";+ Block y(arena);+ y.name = "foo";+ assertEqual(x, y);+ }+ {+ // Different block names hash equally - we ignore internal name differences+ // intentionally.+ Block x(arena);+ x.name = "foo";+ Block y(arena);+ y.name = "bar";+ assertEqual(x, y);+ }+ {+ // Different br names are checked relatively as well.+ Break x;+ x.name = "foo";+ Break y;+ y.name = "bar";+ Block z(arena);+ z.name = "foo";+ z.list.push_back(&x);+ Block w(arena);+ w.name = "bar";+ w.list.push_back(&y);+ Block outer1(arena);+ outer1.name = "outer1";+ outer1.list.push_back(&z);+ Block outer2(arena);+ outer2.name = "outer2";+ outer2.list.push_back(&w);+ assertEqual(outer1, outer2);+ }+ {+ // But referring to different relative names leads to a difference.+ Break x;+ x.name = "outer1"; // instead of x, go to the outer label this time+ Break y;+ y.name = "bar";+ Block z(arena);+ z.name = "foo";+ z.list.push_back(&x);+ Block w(arena);+ w.name = "bar";+ w.list.push_back(&y);+ Block outer1(arena);+ outer1.name = "outer1";+ outer1.list.push_back(&z);+ Block outer2(arena);+ outer2.name = "outer2";+ outer2.list.push_back(&w);+ assertNotEqual(outer1, outer2);+ }+ {+ // Indexes.+ LocalGet x, y;+ x.index = 10;+ y.index = 10;+ assertEqual(x, y);+ }+ {+ // Indexes.+ LocalGet x, y;+ x.index = 10;+ y.index = 11;+ assertNotEqual(x, y);+ }+ std::cout << "success.\n";+}
+ binaryen/test/example/hash.txt view
@@ -0,0 +1,1 @@+success.
+ binaryen/test/example/module-splitting.cpp view
@@ -0,0 +1,397 @@+#include <cassert>+#include <iostream>++#include "ir/module-splitting.h"+#include "ir/stack-utils.h"+#include "wasm-features.h"+#include "wasm-s-parser.h"+#include "wasm-validator.h"+#include "wasm.h"++using namespace wasm;++std::unique_ptr<Module> parse(char* module) {+ auto wasm = std::make_unique<Module>();+ wasm->features = FeatureSet::All;+ try {+ SExpressionParser parser(module);+ Element& root = *parser.root;+ SExpressionWasmBuilder builder(*wasm, *root[0], IRProfile::Normal);+ } catch (ParseException& p) {+ p.dump(std::cerr);+ Fatal() << "error in parsing wasm text";+ }+ return wasm;+}++void do_test(const std::set<Name>& keptFuncs, std::string&& module) {+ WasmValidator validator;+ bool valid;++ auto primary = parse(&module.front());+ valid = validator.validate(*primary);+ assert(valid && "before invalid!");++ std::cout << "Before:\n";+ std::cout << *primary.get();++ std::cout << "Keeping: ";+ if (keptFuncs.size()) {+ auto it = keptFuncs.begin();+ std::cout << *it++;+ while (it != keptFuncs.end()) {+ std::cout << ", " << *it++;+ }+ } else {+ std::cout << "<none>";+ }+ std::cout << "\n";++ ModuleSplitting::Config config;+ config.primaryFuncs = keptFuncs;+ config.newExportPrefix = "%";+ auto secondary = splitFunctions(*primary, config);++ std::cout << "After:\n";+ std::cout << *primary.get();+ std::cout << "Secondary:\n";+ std::cout << *secondary.get();+ std::cout << "\n\n";++ valid = validator.validate(*primary);+ assert(valid && "after invalid!");+ valid = validator.validate(*secondary);+ assert(valid && "secondary invalid!");+}++int main() {+ // Trivial module+ do_test({}, "(module)");++ // Global stuff+ do_test({}, R"(+ (module+ (memory $mem (shared 3 42))+ (table $tab 3 42 funcref)+ (global $glob (mut i32) (i32.const 7))+ (event $e (attr 0) (param i32))+ ))");++ // Imported global stuff+ do_test({}, R"(+ (module+ (import "env" "mem" (memory $mem (shared 3 42)))+ (import "env" "tab" (table $tab 3 42 funcref))+ (import "env" "glob" (global $glob (mut i32)))+ (import "env" "e" (event $e (attr 0) (param i32)))+ ))");++ // Exported global stuff+ do_test({}, R"(+ (module+ (memory $mem (shared 3 42))+ (table $tab 3 42 funcref)+ (global $glob (mut i32) (i32.const 7))+ (event $e (attr 0) (param i32))+ (export "mem" (memory $mem))+ (export "tab" (table $tab))+ (export "glob" (global $glob))+ (export "e" (event $e))+ ))");++ // Non-deferred function+ do_test({"foo"}, R"(+ (module+ (func $foo (param i32) (result i32)+ (local.get 0)+ )+ ))");++ // Non-deferred exported function+ do_test({"foo"}, R"(+ (module+ (export "foo" (func $foo))+ (func $foo (param i32) (result i32)+ (local.get 0)+ )+ ))");++ // Non-deferred function in table+ do_test({"foo"}, R"(+ (module+ (table $table 1 funcref)+ (elem (i32.const 0) $foo)+ (func $foo (param i32) (result i32)+ (local.get 0)+ )+ ))");++ // Non-deferred function in table at non-const offset+ do_test({"foo"}, R"(+ (module+ (import "env" "base" (global $base i32))+ (table $table 1 funcref)+ (elem (global.get $base) $foo)+ (func $foo (param i32) (result i32)+ (local.get 0)+ )+ ))");++ // Non-deferred imported function+ do_test({"foo"}, R"(+ (module+ (import "env" "foo" (func $foo (param i32) (result i32)))+ ))");++ // Non-deferred exported imported function in table at a weird offset+ do_test({"foo"}, R"(+ (module+ (import "env" "foo" (func $foo (param i32) (result i32)))+ (table $table 1000 funcref)+ (elem (i32.const 42) $foo)+ (export "foo" (func $foo))+ ))");++ // Non-deferred exported imported function in table at a non-const offset+ do_test({"foo"}, R"(+ (module+ (import "env" "base" (global $base i32))+ (import "env" "foo" (func $foo (param i32) (result i32)))+ (table $table 1000 funcref)+ (elem (global.get $base) $foo)+ (export "foo" (func $foo))+ ))");++ // Deferred function+ do_test({}, R"(+ (module+ (func $foo (param i32) (result i32)+ (local.get 0)+ )+ ))");++ // Deferred exported function+ do_test({}, R"(+ (module+ (export "foo" (func $foo))+ (func $foo (param i32) (result i32)+ (local.get 0)+ )+ ))");++ // Deferred function in table+ do_test({}, R"(+ (module+ (table $table 1 funcref)+ (elem (i32.const 0) $foo)+ (func $foo (param i32) (result i32)+ (local.get 0)+ )+ ))");++ // Deferred exported function in table at a weird offset+ do_test({}, R"(+ (module+ (table $table 1000 funcref)+ (elem (i32.const 42) $foo)+ (export "foo" (func $foo))+ (func $foo (param i32) (result i32)+ (local.get 0)+ )+ ))");++ // Deferred exported function in table at a non-const offset+ do_test({}, R"(+ (module+ (import "env" "base" (global $base i32))+ (table $table 1000 funcref)+ (elem (global.get $base) $foo)+ (export "foo" (func $foo))+ (func $foo (param i32) (result i32)+ (local.get 0)+ )+ ))");++ // Deferred exported function in table at an offset from a non-const base+ do_test({"null"}, R"(+ (module+ (import "env" "base" (global $base i32))+ (table $table 1000 funcref)+ (elem (global.get $base) $null $foo)+ (export "foo" (func $foo))+ (func $null)+ (func $foo (param i32) (result i32)+ (local.get 0)+ )+ ))");++ // Non-deferred function calling non-deferred function+ do_test({"foo", "bar"}, R"(+ (module+ (func $foo+ (call $bar)+ )+ (func $bar+ (nop)+ )+ ))");++ // Deferred function calling non-deferred function+ do_test({"bar"}, R"(+ (module+ (func $foo+ (call $bar)+ )+ (func $bar+ (nop)+ )+ ))");++ // Non-deferred function calling deferred function+ do_test({"foo"}, R"(+ (module+ (func $foo+ (call $bar)+ )+ (func $bar+ (nop)+ )+ ))");++ // Deferred function calling deferred function+ do_test({}, R"(+ (module+ (func $foo+ (call $bar)+ )+ (func $bar+ (nop)+ )+ ))");++ // Deferred function calling non-deferred function with clashing export name+ do_test({"foo"}, R"(+ (module+ (export "%foo" (func $bar))+ (func $foo+ (nop)+ )+ (func $bar+ (call $foo)+ )+ ))");++ // Mixed table 1+ do_test({"bar", "quux"}, R"(+ (module+ (table $table 4 funcref)+ (elem (i32.const 0) $foo $bar $baz $quux)+ (func $foo+ (nop)+ )+ (func $bar+ (nop)+ )+ (func $baz+ (nop)+ )+ (func $quux+ (nop)+ )+ ))");++ // Mixed table 1 with non-const offset+ do_test({"bar", "quux"}, R"(+ (module+ (import "env" "base" (global $base i32))+ (table $table 4 funcref)+ (elem (global.get $base) $foo $bar $baz $quux)+ (func $foo+ (nop)+ )+ (func $bar+ (nop)+ )+ (func $baz+ (nop)+ )+ (func $quux+ (nop)+ )+ ))");++ // Mixed table 2+ do_test({"baz"}, R"(+ (module+ (table $table 4 funcref)+ (elem (i32.const 0) $foo $bar $baz $quux)+ (func $foo+ (nop)+ )+ (func $bar+ (nop)+ )+ (func $baz+ (nop)+ )+ (func $quux+ (nop)+ )+ ))");++ // Mixed table 2 with non-const offset+ do_test({"baz"}, R"(+ (module+ (import "env" "base" (global $base i32))+ (table $table 4 funcref)+ (elem (global.get $base) $foo $bar $baz $quux)+ (func $foo+ (nop)+ )+ (func $bar+ (nop)+ )+ (func $baz+ (nop)+ )+ (func $quux+ (nop)+ )+ ))");++ // `foo` is exported both because it is called by `bar` and because it is in a+ // table gap+ do_test({"foo"}, R"(+ (module+ (import "env" "base" (global $base i32))+ (table $table 2 funcref)+ (elem (global.get $base) $foo $bar)+ (func $foo+ (nop)+ )+ (func $bar+ (call $foo)+ )+ ))");++ // Mutual recursion with table growth+ do_test({"foo"}, R"(+ (module+ (table $table 1 1 funcref)+ (elem (i32.const 0) $foo)+ (func $foo (param i32) (result i32)+ (call $bar (i32.const 0))+ )+ (func $bar (param i32) (result i32)+ (call $foo (i32.const 1))+ )+ ))");++ // Multiple exports of a secondary function+ do_test({}, R"(+ (module+ (export "foo1" (func $foo))+ (export "foo2" (func $foo))+ (func $foo)+ ))");+}
+ binaryen/test/example/module-splitting.txt view
@@ -0,0 +1,981 @@+Before:+(module+)+Keeping: <none>+After:+(module+)+Secondary:+(module+)+++Before:+(module+ (type $i32_=>_none (func (param i32)))+ (memory $mem (shared 3 42))+ (table $tab 3 42 funcref)+ (global $glob (mut i32) (i32.const 7))+ (event $e (attr 0) (param i32))+)+Keeping: <none>+After:+(module+ (type $i32_=>_none (func (param i32)))+ (memory $mem (shared 3 42))+ (table $tab 3 42 funcref)+ (global $glob (mut i32) (i32.const 7))+ (event $e (attr 0) (param i32))+ (export "%memory" (memory $mem))+ (export "%table" (table $tab))+ (export "%global" (global $glob))+ (export "%event" (event $e))+)+Secondary:+(module+ (type $i32_=>_none (func (param i32)))+ (import "primary" "%memory" (memory $mem (shared 3 42)))+ (import "primary" "%table" (table $tab 3 42 funcref))+ (import "primary" "%global" (global $glob (mut i32)))+ (import "primary" "%event" (event $e (attr 0) (param i32)))+)+++Before:+(module+ (type $i32_=>_none (func (param i32)))+ (import "env" "mem" (memory $mem (shared 3 42)))+ (import "env" "tab" (table $tab 3 42 funcref))+ (import "env" "glob" (global $glob (mut i32)))+ (import "env" "e" (event $e (attr 0) (param i32)))+)+Keeping: <none>+After:+(module+ (type $i32_=>_none (func (param i32)))+ (import "env" "mem" (memory $mem (shared 3 42)))+ (import "env" "tab" (table $tab 3 42 funcref))+ (import "env" "glob" (global $glob (mut i32)))+ (import "env" "e" (event $e (attr 0) (param i32)))+ (export "%memory" (memory $mem))+ (export "%table" (table $tab))+ (export "%global" (global $glob))+ (export "%event" (event $e))+)+Secondary:+(module+ (type $i32_=>_none (func (param i32)))+ (import "primary" "%memory" (memory $mem (shared 3 42)))+ (import "primary" "%table" (table $tab 3 42 funcref))+ (import "primary" "%global" (global $glob (mut i32)))+ (import "primary" "%event" (event $e (attr 0) (param i32)))+)+++Before:+(module+ (type $i32_=>_none (func (param i32)))+ (memory $mem (shared 3 42))+ (table $tab 3 42 funcref)+ (global $glob (mut i32) (i32.const 7))+ (event $e (attr 0) (param i32))+ (export "mem" (memory $mem))+ (export "tab" (table $tab))+ (export "glob" (global $glob))+ (export "e" (event $e))+)+Keeping: <none>+After:+(module+ (type $i32_=>_none (func (param i32)))+ (memory $mem (shared 3 42))+ (table $tab 3 42 funcref)+ (global $glob (mut i32) (i32.const 7))+ (event $e (attr 0) (param i32))+ (export "mem" (memory $mem))+ (export "tab" (table $tab))+ (export "glob" (global $glob))+ (export "e" (event $e))+)+Secondary:+(module+ (type $i32_=>_none (func (param i32)))+ (import "primary" "mem" (memory $mem (shared 3 42)))+ (import "primary" "tab" (table $tab 3 42 funcref))+ (import "primary" "glob" (global $glob (mut i32)))+ (import "primary" "e" (event $e (attr 0) (param i32)))+)+++Before:+(module+ (type $i32_=>_i32 (func (param i32) (result i32)))+ (func $foo (param $0 i32) (result i32)+ (local.get $0)+ )+)+Keeping: foo+After:+(module+ (type $i32_=>_i32 (func (param i32) (result i32)))+ (func $foo (param $0 i32) (result i32)+ (local.get $0)+ )+)+Secondary:+(module+)+++Before:+(module+ (type $i32_=>_i32 (func (param i32) (result i32)))+ (export "foo" (func $foo))+ (func $foo (param $0 i32) (result i32)+ (local.get $0)+ )+)+Keeping: foo+After:+(module+ (type $i32_=>_i32 (func (param i32) (result i32)))+ (export "foo" (func $foo))+ (func $foo (param $0 i32) (result i32)+ (local.get $0)+ )+)+Secondary:+(module+)+++Before:+(module+ (type $i32_=>_i32 (func (param i32) (result i32)))+ (table $table 1 funcref)+ (elem (i32.const 0) $foo)+ (func $foo (param $0 i32) (result i32)+ (local.get $0)+ )+)+Keeping: foo+After:+(module+ (type $i32_=>_i32 (func (param i32) (result i32)))+ (table $table 1 funcref)+ (elem (i32.const 0) $foo)+ (export "%table" (table $table))+ (func $foo (param $0 i32) (result i32)+ (local.get $0)+ )+)+Secondary:+(module+ (import "primary" "%table" (table $table 1 funcref))+)+++Before:+(module+ (type $i32_=>_i32 (func (param i32) (result i32)))+ (import "env" "base" (global $base i32))+ (table $table 1 funcref)+ (elem (global.get $base) $foo)+ (func $foo (param $0 i32) (result i32)+ (local.get $0)+ )+)+Keeping: foo+After:+(module+ (type $i32_=>_i32 (func (param i32) (result i32)))+ (import "env" "base" (global $base i32))+ (table $table 1 funcref)+ (elem (global.get $base) $foo)+ (export "%table" (table $table))+ (export "%global" (global $base))+ (func $foo (param $0 i32) (result i32)+ (local.get $0)+ )+)+Secondary:+(module+ (import "primary" "%table" (table $table 1 funcref))+ (import "primary" "%global" (global $base i32))+)+++Before:+(module+ (type $i32_=>_i32 (func (param i32) (result i32)))+ (import "env" "foo" (func $foo (param i32) (result i32)))+)+Keeping: foo+After:+(module+ (type $i32_=>_i32 (func (param i32) (result i32)))+ (import "env" "foo" (func $foo (param i32) (result i32)))+)+Secondary:+(module+)+++Before:+(module+ (type $i32_=>_i32 (func (param i32) (result i32)))+ (import "env" "foo" (func $foo (param i32) (result i32)))+ (table $table 1000 funcref)+ (elem (i32.const 42) $foo)+ (export "foo" (func $foo))+)+Keeping: foo+After:+(module+ (type $i32_=>_i32 (func (param i32) (result i32)))+ (import "env" "foo" (func $foo (param i32) (result i32)))+ (table $table 1000 funcref)+ (elem (i32.const 42) $foo)+ (export "foo" (func $foo))+ (export "%table" (table $table))+)+Secondary:+(module+ (import "primary" "%table" (table $table 1000 funcref))+)+++Before:+(module+ (type $i32_=>_i32 (func (param i32) (result i32)))+ (import "env" "base" (global $base i32))+ (import "env" "foo" (func $foo (param i32) (result i32)))+ (table $table 1000 funcref)+ (elem (global.get $base) $foo)+ (export "foo" (func $foo))+)+Keeping: foo+After:+(module+ (type $i32_=>_i32 (func (param i32) (result i32)))+ (import "env" "base" (global $base i32))+ (import "env" "foo" (func $foo (param i32) (result i32)))+ (table $table 1000 funcref)+ (elem (global.get $base) $foo)+ (export "foo" (func $foo))+ (export "%table" (table $table))+ (export "%global" (global $base))+)+Secondary:+(module+ (import "primary" "%table" (table $table 1000 funcref))+ (import "primary" "%global" (global $base i32))+)+++Before:+(module+ (type $i32_=>_i32 (func (param i32) (result i32)))+ (func $foo (param $0 i32) (result i32)+ (local.get $0)+ )+)+Keeping: <none>+After:+(module+)+Secondary:+(module+ (type $i32_=>_i32 (func (param i32) (result i32)))+ (func $foo (param $0 i32) (result i32)+ (local.get $0)+ )+)+++Before:+(module+ (type $i32_=>_i32 (func (param i32) (result i32)))+ (export "foo" (func $foo))+ (func $foo (param $0 i32) (result i32)+ (local.get $0)+ )+)+Keeping: <none>+After:+(module+ (type $i32_=>_i32 (func (param i32) (result i32)))+ (import "placeholder" "0" (func $placeholder_0 (param i32) (result i32)))+ (table $0 1 funcref)+ (elem (i32.const 0) $placeholder_0)+ (export "foo" (func $foo))+ (export "%table" (table $0))+ (func $foo (param $0 i32) (result i32)+ (call_indirect (type $i32_=>_i32)+ (local.get $0)+ (i32.const 0)+ )+ )+)+Secondary:+(module+ (type $i32_=>_i32 (func (param i32) (result i32)))+ (import "primary" "%table" (table $0 1 funcref))+ (elem (i32.const 0) $foo)+ (func $foo (param $0 i32) (result i32)+ (local.get $0)+ )+)+++Before:+(module+ (type $i32_=>_i32 (func (param i32) (result i32)))+ (table $table 1 funcref)+ (elem (i32.const 0) $foo)+ (func $foo (param $0 i32) (result i32)+ (local.get $0)+ )+)+Keeping: <none>+After:+(module+ (type $i32_=>_i32 (func (param i32) (result i32)))+ (import "placeholder" "0" (func $placeholder_0 (param i32) (result i32)))+ (table $table 1 funcref)+ (elem (i32.const 0) $placeholder_0)+ (export "%table" (table $table))+)+Secondary:+(module+ (type $i32_=>_i32 (func (param i32) (result i32)))+ (import "primary" "%table" (table $table 1 funcref))+ (elem (i32.const 0) $foo)+ (func $foo (param $0 i32) (result i32)+ (local.get $0)+ )+)+++Before:+(module+ (type $i32_=>_i32 (func (param i32) (result i32)))+ (table $table 1000 funcref)+ (elem (i32.const 42) $foo)+ (export "foo" (func $foo))+ (func $foo (param $0 i32) (result i32)+ (local.get $0)+ )+)+Keeping: <none>+After:+(module+ (type $i32_=>_i32 (func (param i32) (result i32)))+ (import "placeholder" "42" (func $placeholder_42 (param i32) (result i32)))+ (table $table 1000 funcref)+ (elem (i32.const 42) $placeholder_42)+ (export "foo" (func $foo))+ (export "%table" (table $table))+ (func $foo (param $0 i32) (result i32)+ (call_indirect (type $i32_=>_i32)+ (local.get $0)+ (i32.const 42)+ )+ )+)+Secondary:+(module+ (type $i32_=>_i32 (func (param i32) (result i32)))+ (import "primary" "%table" (table $table 1000 funcref))+ (elem (i32.const 42) $foo)+ (func $foo (param $0 i32) (result i32)+ (local.get $0)+ )+)+++Before:+(module+ (type $i32_=>_i32 (func (param i32) (result i32)))+ (import "env" "base" (global $base i32))+ (table $table 1000 funcref)+ (elem (global.get $base) $foo)+ (export "foo" (func $foo))+ (func $foo (param $0 i32) (result i32)+ (local.get $0)+ )+)+Keeping: <none>+After:+(module+ (type $i32_=>_i32 (func (param i32) (result i32)))+ (import "env" "base" (global $base i32))+ (import "placeholder" "0" (func $placeholder_0 (param i32) (result i32)))+ (table $table 1000 funcref)+ (elem (global.get $base) $placeholder_0)+ (export "foo" (func $foo))+ (export "%table" (table $table))+ (export "%global" (global $base))+ (func $foo (param $0 i32) (result i32)+ (call_indirect (type $i32_=>_i32)+ (local.get $0)+ (global.get $base)+ )+ )+)+Secondary:+(module+ (type $i32_=>_i32 (func (param i32) (result i32)))+ (import "primary" "%table" (table $table 1000 funcref))+ (elem (global.get $base) $foo)+ (import "primary" "%global" (global $base i32))+ (func $foo (param $0 i32) (result i32)+ (local.get $0)+ )+)+++Before:+(module+ (type $none_=>_none (func))+ (type $i32_=>_i32 (func (param i32) (result i32)))+ (import "env" "base" (global $base i32))+ (table $table 1000 funcref)+ (elem (global.get $base) $null $foo)+ (export "foo" (func $foo))+ (func $null+ (nop)+ )+ (func $foo (param $0 i32) (result i32)+ (local.get $0)+ )+)+Keeping: null+After:+(module+ (type $i32_=>_i32 (func (param i32) (result i32)))+ (type $none_=>_none (func))+ (import "env" "base" (global $base i32))+ (import "placeholder" "1" (func $placeholder_1 (param i32) (result i32)))+ (table $table 1000 funcref)+ (elem (global.get $base) $null $placeholder_1)+ (export "foo" (func $foo))+ (export "%null" (func $null))+ (export "%table" (table $table))+ (export "%global" (global $base))+ (func $null+ (nop)+ )+ (func $foo (param $0 i32) (result i32)+ (call_indirect (type $i32_=>_i32)+ (local.get $0)+ (i32.add+ (global.get $base)+ (i32.const 1)+ )+ )+ )+)+Secondary:+(module+ (type $none_=>_none (func))+ (type $i32_=>_i32 (func (param i32) (result i32)))+ (import "primary" "%table" (table $table 1000 funcref))+ (elem (global.get $base) $null $foo)+ (import "primary" "%global" (global $base i32))+ (import "primary" "%null" (func $null))+ (func $foo (param $0 i32) (result i32)+ (local.get $0)+ )+)+++Before:+(module+ (type $none_=>_none (func))+ (func $foo+ (call $bar)+ )+ (func $bar+ (nop)+ )+)+Keeping: bar, foo+After:+(module+ (type $none_=>_none (func))+ (func $foo+ (call $bar)+ )+ (func $bar+ (nop)+ )+)+Secondary:+(module+)+++Before:+(module+ (type $none_=>_none (func))+ (func $foo+ (call $bar)+ )+ (func $bar+ (nop)+ )+)+Keeping: bar+After:+(module+ (type $none_=>_none (func))+ (export "%bar" (func $bar))+ (func $bar+ (nop)+ )+)+Secondary:+(module+ (type $none_=>_none (func))+ (import "primary" "%bar" (func $bar))+ (func $foo+ (call $bar)+ )+)+++Before:+(module+ (type $none_=>_none (func))+ (func $foo+ (call $bar)+ )+ (func $bar+ (nop)+ )+)+Keeping: foo+After:+(module+ (type $none_=>_none (func))+ (import "placeholder" "0" (func $placeholder_0))+ (table $0 1 funcref)+ (elem (i32.const 0) $placeholder_0)+ (export "%table" (table $0))+ (func $foo+ (call_indirect (type $none_=>_none)+ (i32.const 0)+ )+ )+)+Secondary:+(module+ (type $none_=>_none (func))+ (import "primary" "%table" (table $0 1 funcref))+ (elem (i32.const 0) $bar)+ (func $bar+ (nop)+ )+)+++Before:+(module+ (type $none_=>_none (func))+ (func $foo+ (call $bar)+ )+ (func $bar+ (nop)+ )+)+Keeping: <none>+After:+(module+)+Secondary:+(module+ (type $none_=>_none (func))+ (func $bar+ (nop)+ )+ (func $foo+ (call $bar)+ )+)+++Before:+(module+ (type $none_=>_none (func))+ (export "%foo" (func $bar))+ (func $foo+ (nop)+ )+ (func $bar+ (call $foo)+ )+)+Keeping: foo+After:+(module+ (type $none_=>_none (func))+ (import "placeholder" "0" (func $placeholder_0))+ (table $0 1 funcref)+ (elem (i32.const 0) $placeholder_0)+ (export "%foo" (func $bar))+ (export "%foo_0" (func $foo))+ (export "%table" (table $0))+ (func $foo+ (nop)+ )+ (func $bar+ (call_indirect (type $none_=>_none)+ (i32.const 0)+ )+ )+)+Secondary:+(module+ (type $none_=>_none (func))+ (import "primary" "%table" (table $0 1 funcref))+ (elem (i32.const 0) $bar)+ (import "primary" "%foo_0" (func $foo))+ (func $bar+ (call $foo)+ )+)+++Before:+(module+ (type $none_=>_none (func))+ (table $table 4 funcref)+ (elem (i32.const 0) $foo $bar $baz $quux)+ (func $foo+ (nop)+ )+ (func $bar+ (nop)+ )+ (func $baz+ (nop)+ )+ (func $quux+ (nop)+ )+)+Keeping: bar, quux+After:+(module+ (type $none_=>_none (func))+ (import "placeholder" "0" (func $placeholder_0))+ (import "placeholder" "2" (func $placeholder_2))+ (table $table 4 funcref)+ (elem (i32.const 0) $placeholder_0 $bar $placeholder_2 $quux)+ (export "%table" (table $table))+ (func $bar+ (nop)+ )+ (func $quux+ (nop)+ )+)+Secondary:+(module+ (type $none_=>_none (func))+ (import "primary" "%table" (table $table 4 funcref))+ (elem (i32.const 0) $foo)+ (elem (i32.const 2) $baz)+ (func $baz+ (nop)+ )+ (func $foo+ (nop)+ )+)+++Before:+(module+ (type $none_=>_none (func))+ (import "env" "base" (global $base i32))+ (table $table 4 funcref)+ (elem (global.get $base) $foo $bar $baz $quux)+ (func $foo+ (nop)+ )+ (func $bar+ (nop)+ )+ (func $baz+ (nop)+ )+ (func $quux+ (nop)+ )+)+Keeping: bar, quux+After:+(module+ (type $none_=>_none (func))+ (import "env" "base" (global $base i32))+ (import "placeholder" "0" (func $placeholder_0))+ (import "placeholder" "2" (func $placeholder_2))+ (table $table 4 funcref)+ (elem (global.get $base) $placeholder_0 $bar $placeholder_2 $quux)+ (export "%bar" (func $bar))+ (export "%table" (table $table))+ (export "%global" (global $base))+ (func $bar+ (nop)+ )+ (func $quux+ (nop)+ )+)+Secondary:+(module+ (type $none_=>_none (func))+ (import "primary" "%table" (table $table 4 funcref))+ (elem (global.get $base) $foo $bar $baz)+ (import "primary" "%global" (global $base i32))+ (import "primary" "%bar" (func $bar))+ (func $baz+ (nop)+ )+ (func $foo+ (nop)+ )+)+++Before:+(module+ (type $none_=>_none (func))+ (table $table 4 funcref)+ (elem (i32.const 0) $foo $bar $baz $quux)+ (func $foo+ (nop)+ )+ (func $bar+ (nop)+ )+ (func $baz+ (nop)+ )+ (func $quux+ (nop)+ )+)+Keeping: baz+After:+(module+ (type $none_=>_none (func))+ (import "placeholder" "0" (func $placeholder_0))+ (import "placeholder" "1" (func $placeholder_1))+ (import "placeholder" "3" (func $placeholder_3))+ (table $table 4 funcref)+ (elem (i32.const 0) $placeholder_0 $placeholder_1 $baz $placeholder_3)+ (export "%table" (table $table))+ (func $baz+ (nop)+ )+)+Secondary:+(module+ (type $none_=>_none (func))+ (import "primary" "%table" (table $table 4 funcref))+ (elem (i32.const 0) $foo $bar)+ (elem (i32.const 3) $quux)+ (func $bar+ (nop)+ )+ (func $foo+ (nop)+ )+ (func $quux+ (nop)+ )+)+++Before:+(module+ (type $none_=>_none (func))+ (import "env" "base" (global $base i32))+ (table $table 4 funcref)+ (elem (global.get $base) $foo $bar $baz $quux)+ (func $foo+ (nop)+ )+ (func $bar+ (nop)+ )+ (func $baz+ (nop)+ )+ (func $quux+ (nop)+ )+)+Keeping: baz+After:+(module+ (type $none_=>_none (func))+ (import "env" "base" (global $base i32))+ (import "placeholder" "0" (func $placeholder_0))+ (import "placeholder" "1" (func $placeholder_1))+ (import "placeholder" "3" (func $placeholder_3))+ (table $table 4 funcref)+ (elem (global.get $base) $placeholder_0 $placeholder_1 $baz $placeholder_3)+ (export "%baz" (func $baz))+ (export "%table" (table $table))+ (export "%global" (global $base))+ (func $baz+ (nop)+ )+)+Secondary:+(module+ (type $none_=>_none (func))+ (import "primary" "%table" (table $table 4 funcref))+ (elem (global.get $base) $foo $bar $baz $quux)+ (import "primary" "%global" (global $base i32))+ (import "primary" "%baz" (func $baz))+ (func $bar+ (nop)+ )+ (func $foo+ (nop)+ )+ (func $quux+ (nop)+ )+)+++Before:+(module+ (type $none_=>_none (func))+ (import "env" "base" (global $base i32))+ (table $table 2 funcref)+ (elem (global.get $base) $foo $bar)+ (func $foo+ (nop)+ )+ (func $bar+ (call $foo)+ )+)+Keeping: foo+After:+(module+ (type $none_=>_none (func))+ (import "env" "base" (global $base i32))+ (import "placeholder" "1" (func $placeholder_1))+ (table $table 2 funcref)+ (elem (global.get $base) $foo $placeholder_1)+ (export "%foo" (func $foo))+ (export "%table" (table $table))+ (export "%global" (global $base))+ (func $foo+ (nop)+ )+)+Secondary:+(module+ (type $none_=>_none (func))+ (import "primary" "%table" (table $table 2 funcref))+ (elem (global.get $base) $foo $bar)+ (import "primary" "%global" (global $base i32))+ (import "primary" "%foo" (func $foo))+ (func $bar+ (call $foo)+ )+)+++Before:+(module+ (type $i32_=>_i32 (func (param i32) (result i32)))+ (table $table 1 1 funcref)+ (elem (i32.const 0) $foo)+ (func $foo (param $0 i32) (result i32)+ (call $bar+ (i32.const 0)+ )+ )+ (func $bar (param $0 i32) (result i32)+ (call $foo+ (i32.const 1)+ )+ )+)+Keeping: foo+After:+(module+ (type $i32_=>_i32 (func (param i32) (result i32)))+ (import "placeholder" "1" (func $placeholder_1 (param i32) (result i32)))+ (table $table 2 2 funcref)+ (elem (i32.const 0) $foo $placeholder_1)+ (export "%foo" (func $foo))+ (export "%table" (table $table))+ (func $foo (param $0 i32) (result i32)+ (call_indirect (type $i32_=>_i32)+ (i32.const 0)+ (i32.const 1)+ )+ )+)+Secondary:+(module+ (type $i32_=>_i32 (func (param i32) (result i32)))+ (import "primary" "%table" (table $table 2 2 funcref))+ (elem (i32.const 1) $bar)+ (import "primary" "%foo" (func $foo (param i32) (result i32)))+ (func $bar (param $0 i32) (result i32)+ (call $foo+ (i32.const 1)+ )+ )+)+++Before:+(module+ (type $none_=>_none (func))+ (export "foo1" (func $foo))+ (export "foo2" (func $foo))+ (func $foo+ (nop)+ )+)+Keeping: <none>+After:+(module+ (type $none_=>_none (func))+ (import "placeholder" "0" (func $placeholder_0))+ (table $0 1 funcref)+ (elem (i32.const 0) $placeholder_0)+ (export "foo1" (func $foo))+ (export "foo2" (func $foo))+ (export "%table" (table $0))+ (func $foo+ (call_indirect (type $none_=>_none)+ (i32.const 0)+ )+ )+)+Secondary:+(module+ (type $none_=>_none (func))+ (import "primary" "%table" (table $0 1 funcref))+ (elem (i32.const 0) $foo)+ (func $foo+ (nop)+ )+)++
+ binaryen/test/example/space.cpp view
@@ -0,0 +1,115 @@+#include <cassert>+#include <iostream>++#include <support/space.h>++using namespace wasm;++using Span = DisjointSpans::Span;++int main() {+ // No spans+ {+ DisjointSpans root;+ // Nothing in root+ assert(!root.checkOverlap(Span{0, 100}));+ }+ // One span+ {+ DisjointSpans root;+ root.add(Span{0, 100});+ // It is there+ assert(root.checkOverlap(Span{0, 100}));+ }+ {+ DisjointSpans root;+ root.add(Span{40, 60});+ // Exact match+ assert(root.checkOverlap(Span{40, 60}));+ // No overlap+ assert(!root.checkOverlap(Span{20, 30}));+ // Touching, but no overlap+ assert(!root.checkOverlap(Span{20, 40}));+ // Overlap+ assert(root.checkOverlap(Span{20, 41}));+ assert(root.checkOverlap(Span{40, 41}));+ // Internal+ assert(root.checkOverlap(Span{45, 50}));+ // Touches other side+ assert(root.checkOverlap(Span{45, 60}));+ // Overlaps on other side+ assert(root.checkOverlap(Span{45, 70}));+ // Just inside.+ assert(root.checkOverlap(Span{59, 60}));+ // Just outside+ assert(!root.checkOverlap(Span{60, 61}));+ // Totally outside+ assert(!root.checkOverlap(Span{70, 80}));+ }+ // Two spans, different subtrees+ {+ DisjointSpans root;+ root.add(Span{30, 40});+ root.add(Span{60, 70});+ assert(!root.checkOverlap(Span{10, 20}));+ assert(!root.checkOverlap(Span{10, 30}));+ assert(root.checkOverlap(Span{10, 40}));+ assert(root.checkOverlap(Span{35, 40}));+ assert(!root.checkOverlap(Span{40, 60}));+ assert(!root.checkOverlap(Span{45, 55}));+ assert(root.checkOverlap(Span{50, 61}));+ assert(root.checkOverlap(Span{50, 100}));+ assert(root.checkOverlap(Span{60, 70}));+ assert(root.checkOverlap(Span{60, 61}));+ assert(!root.checkOverlap(Span{70, 80}));+ assert(!root.checkOverlap(Span{70, 100}));+ }+ // Two spans, same subtree+ {+ DisjointSpans root;+ root.add(Span{30, 40});+ root.add(Span{40, 45});+ assert(!root.checkOverlap(Span{10, 20}));+ assert(!root.checkOverlap(Span{10, 30}));+ assert(root.checkOverlap(Span{10, 40}));+ assert(root.checkOverlap(Span{35, 40}));+ assert(root.checkOverlap(Span{40, 41}));+ assert(root.checkOverlap(Span{35, 45}));+ assert(!root.checkOverlap(Span{45, 100}));+ }+ // "Pixels"+ {+ const int N = 40;+ for (int i = 0; i < N; i++) {+ DisjointSpans root;+ for (int j = 0; j < N; j++) {+ // add all pixels but the i-th+ if (j != i) {+ root.add(Span{j, j + 1});+ }+ }+ for (int j = 0; j < N; j++) {+ if (j != i) {+ assert(root.checkOverlap(Span{j, j + 1}));+ } else {+ assert(!root.checkOverlap(Span{j, j + 1}));+ }+ }+ assert(root.checkOverlap(Span{10, N + 10}));+ assert(!root.checkOverlap(Span{N + 10, N + 20}));+ }+ }+ // Large numbers.+ {+ DisjointSpans root;+ assert(!root.checkOverlap(Span{2948, 2949}));+ root.add(Span{2948, 2949});+ assert(root.checkOverlap(Span{2948, 2949}));+ assert(root.checkOverlap(Span{2940, 2949}));+ assert(root.checkOverlap(Span{2948, 2959}));+ assert(root.checkOverlap(Span{0, 18766}));+ assert(!root.checkOverlap(Span{2000, 2001}));+ assert(!root.checkOverlap(Span{3000, 3001}));+ }+ std::cout << "success.\n";+}
+ binaryen/test/example/space.txt view
@@ -0,0 +1,1 @@+success.
binaryen/test/example/stack-utils.cpp view
@@ -5,7 +5,6 @@ #include "literal.h" #include "mixed_arena.h" #include "wasm-builder.h"-#include "wasm-printing.h" #include "wasm-type.h" #include "wasm.h" @@ -26,11 +25,9 @@ builder.makeNop(), }, {Type::i32, Type::i64});- WasmPrinter::printExpression(block, std::cout);- std::cout << "\n";+ std::cout << *block << '\n'; StackUtils::removeNops(block);- WasmPrinter::printExpression(block, std::cout);- std::cout << "\n";+ std::cout << *block << '\n'; } void test_stack_signatures() {
+ binaryen/test/example/type-builder.cpp view
@@ -0,0 +1,142 @@+#include <cassert>+#include <iostream>++#include "wasm-type.h"++using namespace wasm;++// Construct Signature, Struct, and Array heap types using undefined types.+void test_builder() {+ std::cout << ";; Test TypeBuilder\n";++ // (type $sig (func (param (ref $struct)) (result (ref $array) i32)))+ // (type $struct (struct (field (ref null $array) (mut rtt 0 $array))))+ // (type $array (array (mut externref)))++ TypeBuilder builder(3);++ Type refSig = builder.getTempRefType(0, NonNullable);+ Type refStruct = builder.getTempRefType(1, NonNullable);+ Type refArray = builder.getTempRefType(2, NonNullable);+ Type refNullArray = builder.getTempRefType(2, Nullable);+ Type rttArray = builder.getTempRttType(2, 0);+ Type refNullExt(HeapType::ext, Nullable);++ Signature sig(refStruct, builder.getTempTupleType({refArray, Type::i32}));+ Struct struct_({Field(refNullArray, Immutable), Field(rttArray, Mutable)});+ Array array(Field(refNullExt, Mutable));++ std::cout << "Before setting heap types:\n";+ std::cout << "(ref $sig) => " << refSig << "\n";+ std::cout << "(ref $struct) => " << refStruct << "\n";+ std::cout << "(ref $array) => " << refArray << "\n";+ std::cout << "(ref null $array) => " << refNullArray << "\n";+ std::cout << "(rtt 0 $array) => " << rttArray << "\n\n";++ builder.setHeapType(0, sig);+ builder.setHeapType(1, struct_);+ builder.setHeapType(2, array);++ std::cout << "After setting heap types:\n";+ std::cout << "(ref $sig) => " << refSig << "\n";+ std::cout << "(ref $struct) => " << refStruct << "\n";+ std::cout << "(ref $array) => " << refArray << "\n";+ std::cout << "(ref null $array) => " << refNullArray << "\n";+ std::cout << "(rtt 0 $array) => " << rttArray << "\n\n";++ std::vector<HeapType> built = builder.build();++ Type newRefSig = Type(built[0], NonNullable);+ Type newRefStruct = Type(built[1], NonNullable);+ Type newRefArray = Type(built[2], NonNullable);+ Type newRefNullArray = Type(built[2], Nullable);+ Type newRttArray = Type(Rtt(0, built[2]));++ assert(refSig != newRefSig);+ assert(refStruct != newRefStruct);+ assert(refArray != newRefArray);+ assert(refNullArray != newRefNullArray);+ assert(rttArray != newRttArray);++ std::cout << "After building types:\n";+ std::cout << "(ref $sig) => " << newRefSig << "\n";+ std::cout << "(ref $struct) => " << newRefStruct << "\n";+ std::cout << "(ref $array) => " << newRefArray << "\n";+ std::cout << "(ref null $array) => " << newRefNullArray << "\n";+ std::cout << "(rtt 0 $array) => " << newRttArray << "\n\n";+}++// Check that the builder works when there are duplicate definitions+void test_canonicalization() {+ std::cout << ";; Test canonicalization\n";++ // (type $struct (struct (field (ref null $sig))))+ // (type $sig (func))+ HeapType sig = Signature(Type::none, Type::none);+ HeapType struct_ = Struct({Field(Type(sig, Nullable), Immutable)});++ TypeBuilder builder(4);++ Type tempSigRef1 = builder.getTempRefType(2, Nullable);+ Type tempSigRef2 = builder.getTempRefType(3, Nullable);++ assert(tempSigRef1 != tempSigRef2);+ assert(tempSigRef1 != Type(sig, Nullable));+ assert(tempSigRef2 != Type(sig, Nullable));++ builder.setHeapType(0, Struct({Field(tempSigRef1, Immutable)}));+ builder.setHeapType(1, Struct({Field(tempSigRef2, Immutable)}));+ builder.setHeapType(2, Signature(Type::none, Type::none));+ builder.setHeapType(3, Signature(Type::none, Type::none));++ std::vector<HeapType> built = builder.build();++ assert(built[0] == struct_);+ assert(built[1] == struct_);+ assert(built[2] == sig);+ assert(built[3] == sig);+}++void test_recursive() {+ std::cout << ";; Test recursive types\n";++ {+ // Trivial recursion+ TypeBuilder builder(1);+ Type temp = builder.getTempRefType(0, Nullable);+ builder.setHeapType(0, Signature(Type::none, temp));+ // std::vector<HeapType> built = builder.build();+ }++ {+ // Mutual recursion+ TypeBuilder builder(2);+ Type temp0 = builder.getTempRefType(0, Nullable);+ Type temp1 = builder.getTempRefType(1, Nullable);+ builder.setHeapType(0, Signature(Type::none, temp1));+ builder.setHeapType(1, Signature(Type::none, temp0));+ // std::vector<HeapType> built = builder.build();+ }++ {+ // A longer chain of recursion+ TypeBuilder builder(5);+ Type temp0 = builder.getTempRefType(0, Nullable);+ Type temp1 = builder.getTempRefType(1, Nullable);+ Type temp2 = builder.getTempRefType(2, Nullable);+ Type temp3 = builder.getTempRefType(3, Nullable);+ Type temp4 = builder.getTempRefType(4, Nullable);+ builder.setHeapType(0, Signature(Type::none, temp1));+ builder.setHeapType(1, Signature(Type::none, temp2));+ builder.setHeapType(2, Signature(Type::none, temp3));+ builder.setHeapType(3, Signature(Type::none, temp4));+ builder.setHeapType(4, Signature(Type::none, temp0));+ // std::vector<HeapType> built = builder.build();+ }+}++int main() {+ test_builder();+ test_canonicalization();+ test_recursive();+}
+ binaryen/test/example/type-builder.txt view
@@ -0,0 +1,24 @@+;; Test TypeBuilder+Before setting heap types:+(ref $sig) => (ref (func))+(ref $struct) => (ref (func))+(ref $array) => (ref (func))+(ref null $array) => (ref null (func))+(rtt 0 $array) => (rtt 0 (func))++After setting heap types:+(ref $sig) => (ref (func (param (ref (struct (field (ref null (array (mut externref))) (mut (rtt 0 (array (mut externref)))))))) (result (ref (array (mut externref))) i32)))+(ref $struct) => (ref (struct (field (ref null (array (mut externref))) (mut (rtt 0 (array (mut externref)))))))+(ref $array) => (ref (array (mut externref)))+(ref null $array) => (ref null (array (mut externref)))+(rtt 0 $array) => (rtt 0 (array (mut externref)))++After building types:+(ref $sig) => (ref (func (param (ref (struct (field (ref null (array (mut externref))) (mut (rtt 0 (array (mut externref)))))))) (result (ref (array (mut externref))) i32)))+(ref $struct) => (ref (struct (field (ref null (array (mut externref))) (mut (rtt 0 (array (mut externref)))))))+(ref $array) => (ref (array (mut externref)))+(ref null $array) => (ref null (array (mut externref)))+(rtt 0 $array) => (rtt 0 (array (mut externref)))++;; Test canonicalization+;; Test recursive types
binaryen/test/example/typeinfo.cpp view
@@ -7,82 +7,98 @@ void test_compound() { {- HeapType func(HeapType::FuncKind);- assert(Type(func, true).getID() == Type::funcref);- assert(Type(func, false).getID() == Type(func, false).getID());- assert(Type(func, false).getID() != Type(func, true).getID());- HeapType sameFunc(HeapType::FuncKind);- assert(Type(func, false).getID() == Type(sameFunc, false).getID());+ HeapType func(HeapType::func);+ assert(Type(func, Nullable).getID() == Type::funcref);+ assert(Type(func, NonNullable).getID() == Type(func, NonNullable).getID());+ assert(Type(func, NonNullable).getID() != Type(func, Nullable).getID());+ HeapType sameFunc(HeapType::func);+ assert(Type(func, NonNullable).getID() ==+ Type(sameFunc, NonNullable).getID()); - HeapType extern_(HeapType::ExternKind);- assert(Type(extern_, true).getID() == Type::externref);- assert(Type(extern_, false).getID() == Type(extern_, false).getID());- assert(Type(extern_, false).getID() != Type(extern_, true).getID());- HeapType sameExtern(HeapType::ExternKind);- assert(Type(extern_, false).getID() == Type(sameExtern, false).getID());+ HeapType extern_(HeapType::ext);+ assert(Type(extern_, Nullable).getID() == Type::externref);+ assert(Type(extern_, NonNullable).getID() ==+ Type(extern_, NonNullable).getID());+ assert(Type(extern_, NonNullable).getID() !=+ Type(extern_, Nullable).getID());+ HeapType sameExtern(HeapType::ext);+ assert(Type(extern_, NonNullable).getID() ==+ Type(sameExtern, NonNullable).getID()); - HeapType exn(HeapType::ExnKind);- assert(Type(exn, true).getID() == Type::exnref);- assert(Type(exn, false).getID() == Type(exn, false).getID());- assert(Type(exn, false).getID() != Type(exn, true).getID());- HeapType sameExn(HeapType::ExnKind);- assert(Type(exn, false).getID() == Type(sameExn, false).getID());+ HeapType exn(HeapType::exn);+ assert(Type(exn, Nullable).getID() == Type::exnref);+ assert(Type(exn, NonNullable).getID() == Type(exn, NonNullable).getID());+ assert(Type(exn, NonNullable).getID() != Type(exn, Nullable).getID());+ HeapType sameExn(HeapType::exn);+ assert(Type(exn, NonNullable).getID() ==+ Type(sameExn, NonNullable).getID()); - HeapType any(HeapType::AnyKind);- assert(Type(any, true).getID() == Type::anyref);- assert(Type(any, false).getID() == Type(any, false).getID());- assert(Type(any, false).getID() != Type(any, true).getID());- HeapType sameAny(HeapType::AnyKind);- assert(Type(any, false).getID() == Type(sameAny, false).getID());+ HeapType any(HeapType::any);+ assert(Type(any, Nullable).getID() == Type::anyref);+ assert(Type(any, NonNullable).getID() == Type(any, NonNullable).getID());+ assert(Type(any, NonNullable).getID() != Type(any, Nullable).getID());+ HeapType sameAny(HeapType::any);+ assert(Type(any, NonNullable).getID() ==+ Type(sameAny, NonNullable).getID()); - HeapType eq(HeapType::EqKind);- // assert(Type(eq, true).getID() == Type::eqref);- assert(Type(eq, false).getID() == Type(eq, false).getID());- assert(Type(eq, false).getID() != Type(eq, true).getID());- HeapType sameEq(HeapType::EqKind);- assert(Type(eq, false).getID() == Type(sameEq, false).getID());+ HeapType eq(HeapType::eq);+ // assert(Type(eq, Nullable).getID() == Type::eqref);+ assert(Type(eq, NonNullable).getID() == Type(eq, NonNullable).getID());+ assert(Type(eq, NonNullable).getID() != Type(eq, Nullable).getID());+ HeapType sameEq(HeapType::eq);+ assert(Type(eq, NonNullable).getID() == Type(sameEq, NonNullable).getID()); - HeapType i31(HeapType::I31Kind);- // assert(Type(i31, false).getID() == Type::i31ref);- assert(Type(i31, false).getID() == Type(i31, false).getID());- assert(Type(i31, false).getID() != Type(i31, true).getID());- HeapType sameI31(HeapType::I31Kind);- assert(Type(i31, false).getID() == Type(sameI31, false).getID());+ HeapType i31(HeapType::i31);+ // assert(Type(i31, NonNullable).getID() == Type::i31ref);+ assert(Type(i31, NonNullable).getID() == Type(i31, NonNullable).getID());+ assert(Type(i31, NonNullable).getID() != Type(i31, Nullable).getID());+ HeapType sameI31(HeapType::i31);+ assert(Type(i31, NonNullable).getID() ==+ Type(sameI31, NonNullable).getID()); } { Signature signature(Type::i32, Type::none);- assert(Type(signature, false).getID() == Type(signature, false).getID());- assert(Type(signature, false).getID() != Type(signature, true).getID());+ assert(Type(signature, NonNullable).getID() ==+ Type(signature, NonNullable).getID());+ assert(Type(signature, NonNullable).getID() !=+ Type(signature, Nullable).getID()); Signature sameSignature(Type::i32, Type::none);- assert(Type(signature, false).getID() ==- Type(sameSignature, false).getID());+ assert(Type(signature, NonNullable).getID() ==+ Type(sameSignature, NonNullable).getID()); Signature otherSignature(Type::f64, Type::none);- assert(Type(signature, false).getID() !=- Type(otherSignature, false).getID());+ assert(Type(signature, NonNullable).getID() !=+ Type(otherSignature, NonNullable).getID()); } { Struct struct_({});- assert(Type(struct_, false).getID() == Type(struct_, false).getID());- assert(Type(struct_, false).getID() != Type(struct_, true).getID());+ assert(Type(struct_, NonNullable).getID() ==+ Type(struct_, NonNullable).getID());+ assert(Type(struct_, NonNullable).getID() !=+ Type(struct_, Nullable).getID()); Struct sameStruct({});- assert(Type(struct_, false).getID() == Type(sameStruct, false).getID());+ assert(Type(struct_, NonNullable).getID() ==+ Type(sameStruct, NonNullable).getID()); - Struct otherStruct({{Type::i32, false}});- assert(Type(struct_, false).getID() != Type(otherStruct, false).getID());+ Struct otherStruct({{Type::i32, Immutable}});+ assert(Type(struct_, NonNullable).getID() !=+ Type(otherStruct, NonNullable).getID()); } {- Array array({Type::i32, false});- assert(Type(array, false).getID() == Type(array, false).getID());- assert(Type(array, false).getID() != Type(array, true).getID());+ Array array({Type::i32, Immutable});+ assert(Type(array, NonNullable).getID() ==+ Type(array, NonNullable).getID());+ assert(Type(array, NonNullable).getID() != Type(array, Nullable).getID()); - Array sameArray({Type::i32, false});- assert(Type(array, false).getID() == Type(sameArray, false).getID());+ Array sameArray({Type::i32, Immutable});+ assert(Type(array, NonNullable).getID() ==+ Type(sameArray, NonNullable).getID()); - Array otherArray({Type::f64, true});- assert(Type(array, false).getID() != Type(otherArray, false).getID());+ Array otherArray({Type::f64, Mutable});+ assert(Type(array, NonNullable).getID() !=+ Type(otherArray, NonNullable).getID()); } { Tuple singleTuple({Type::i32});@@ -98,18 +114,18 @@ assert(Type(tuple).getID() != Type(otherTuple).getID()); } {- Rtt rtt(0, HeapType::FuncKind);+ Rtt rtt(0, HeapType::func); assert(Type(rtt).getID() == Type(rtt).getID()); - Rtt sameRtt(0, HeapType::FuncKind);+ Rtt sameRtt(0, HeapType::func); assert(rtt == sameRtt); assert(Type(rtt).getID() == Type(sameRtt).getID()); - Rtt otherDepthRtt(1, HeapType::FuncKind);+ Rtt otherDepthRtt(1, HeapType::func); assert(rtt != otherDepthRtt); assert(Type(rtt).getID() != Type(otherDepthRtt).getID()); - Rtt otherHeapTypeRtt(0, HeapType::AnyKind);+ Rtt otherHeapTypeRtt(0, HeapType::any); assert(rtt != otherHeapTypeRtt); assert(Type(rtt).getID() != Type(otherHeapTypeRtt).getID()); @@ -120,7 +136,7 @@ assert(structRtt == sameStructRtt); assert(Type(structRtt).getID() == Type(sameStructRtt).getID()); - Rtt otherStructRtt(0, Struct({{Type::i32, false}}));+ Rtt otherStructRtt(0, Struct({{Type::i32, Immutable}})); assert(structRtt != otherStructRtt); assert(Type(structRtt).getID() != Type(otherStructRtt).getID()); }@@ -129,66 +145,66 @@ void test_printing() { { std::cout << ";; Heap types\n";- std::cout << HeapType(HeapType::FuncKind) << "\n";- std::cout << Type(HeapType::FuncKind, true) << "\n";- std::cout << Type(HeapType::FuncKind, false) << "\n";- std::cout << HeapType(HeapType::ExternKind) << "\n";- std::cout << Type(HeapType::ExternKind, true) << "\n";- std::cout << Type(HeapType::ExternKind, false) << "\n";- std::cout << HeapType(HeapType::AnyKind) << "\n";- std::cout << Type(HeapType::AnyKind, true) << "\n";- std::cout << Type(HeapType::AnyKind, false) << "\n";- std::cout << HeapType(HeapType::EqKind) << "\n";- std::cout << Type(HeapType::EqKind, true) << "\n";- std::cout << Type(HeapType::EqKind, false) << "\n";- std::cout << HeapType(HeapType::I31Kind) << "\n";- std::cout << Type(HeapType::I31Kind, true) << "\n";- std::cout << Type(HeapType::I31Kind, false) << "\n";- std::cout << HeapType(HeapType::ExnKind) << "\n";- std::cout << Type(HeapType::ExnKind, true) << "\n";- std::cout << Type(HeapType::ExnKind, false) << "\n";+ std::cout << HeapType(HeapType::func) << "\n";+ std::cout << Type(HeapType::func, Nullable) << "\n";+ std::cout << Type(HeapType::func, NonNullable) << "\n";+ std::cout << HeapType(HeapType::ext) << "\n";+ std::cout << Type(HeapType::ext, Nullable) << "\n";+ std::cout << Type(HeapType::ext, NonNullable) << "\n";+ std::cout << HeapType(HeapType::any) << "\n";+ std::cout << Type(HeapType::any, Nullable) << "\n";+ std::cout << Type(HeapType::any, NonNullable) << "\n";+ std::cout << HeapType(HeapType::eq) << "\n";+ std::cout << Type(HeapType::eq, Nullable) << "\n";+ std::cout << Type(HeapType::eq, NonNullable) << "\n";+ std::cout << HeapType(HeapType::i31) << "\n";+ std::cout << Type(HeapType::i31, Nullable) << "\n";+ std::cout << Type(HeapType::i31, NonNullable) << "\n";+ std::cout << HeapType(HeapType::exn) << "\n";+ std::cout << Type(HeapType::exn, Nullable) << "\n";+ std::cout << Type(HeapType::exn, NonNullable) << "\n"; std::cout << HeapType(Signature(Type::none, Type::none)) << "\n"; std::cout << HeapType(Struct({})) << "\n";- std::cout << HeapType(Array({Type::i32, false})) << "\n";+ std::cout << HeapType(Array({Type::i32, Immutable})) << "\n"; } { std::cout << "\n;; Signature\n"; Signature emptySignature(Type::none, Type::none); std::cout << emptySignature << "\n";- std::cout << Type(emptySignature, false) << "\n";- std::cout << Type(emptySignature, true) << "\n";+ std::cout << Type(emptySignature, NonNullable) << "\n";+ std::cout << Type(emptySignature, Nullable) << "\n"; Signature signature(Type::i32, Type::f64); std::cout << signature << "\n";- std::cout << Type(signature, false) << "\n";- std::cout << Type(signature, true) << "\n";+ std::cout << Type(signature, NonNullable) << "\n";+ std::cout << Type(signature, Nullable) << "\n"; } { std::cout << "\n;; Struct\n"; Struct emptyStruct({}); std::cout << emptyStruct << "\n";- std::cout << Type(emptyStruct, false) << "\n";- std::cout << Type(emptyStruct, true) << "\n";+ std::cout << Type(emptyStruct, NonNullable) << "\n";+ std::cout << Type(emptyStruct, Nullable) << "\n"; Struct struct_({- {Type::i32, false},- {Type::i64, false},- {Type::f32, true},- {Type::f64, true},- {Type::externref, false},+ {Type::i32, Immutable},+ {Type::i64, Immutable},+ {Type::f32, Mutable},+ {Type::f64, Mutable},+ {Type::externref, Immutable}, }); std::cout << struct_ << "\n";- std::cout << Type(struct_, false) << "\n";- std::cout << Type(struct_, true) << "\n";+ std::cout << Type(struct_, NonNullable) << "\n";+ std::cout << Type(struct_, Nullable) << "\n"; } { std::cout << "\n;; Array\n";- Array array({Type::i32, false});+ Array array({Type::i32, Immutable}); std::cout << array << "\n";- std::cout << Type(array, false) << "\n";- std::cout << Type(array, true) << "\n";- Array arrayMut({Type::externref, true});+ std::cout << Type(array, NonNullable) << "\n";+ std::cout << Type(array, Nullable) << "\n";+ Array arrayMut({Type::externref, Mutable}); std::cout << arrayMut << "\n";- std::cout << Type(arrayMut, false) << "\n";- std::cout << Type(arrayMut, true) << "\n";+ std::cout << Type(arrayMut, NonNullable) << "\n";+ std::cout << Type(arrayMut, Nullable) << "\n"; } { std::cout << "\n;; Tuple\n";@@ -205,110 +221,111 @@ } { std::cout << "\n;; Rtt\n";- std::cout << Rtt(0, HeapType::FuncKind) << "\n";- std::cout << Type(Rtt(0, HeapType::FuncKind)) << "\n";- std::cout << Rtt(1, HeapType::ExternKind) << "\n";- std::cout << Type(Rtt(1, HeapType::ExternKind)) << "\n";- std::cout << Rtt(2, HeapType::AnyKind) << "\n";- std::cout << Type(Rtt(2, HeapType::AnyKind)) << "\n";- std::cout << Rtt(3, HeapType::EqKind) << "\n";- std::cout << Type(Rtt(3, HeapType::EqKind)) << "\n";- std::cout << Rtt(4, HeapType::I31Kind) << "\n";- std::cout << Type(Rtt(4, HeapType::I31Kind)) << "\n";- std::cout << Rtt(5, HeapType::ExnKind) << "\n";- std::cout << Type(Rtt(5, HeapType::ExnKind)) << "\n";+ std::cout << Rtt(0, HeapType::func) << "\n";+ std::cout << Type(Rtt(0, HeapType::func)) << "\n";+ std::cout << Rtt(1, HeapType::ext) << "\n";+ std::cout << Type(Rtt(1, HeapType::ext)) << "\n";+ std::cout << Rtt(2, HeapType::any) << "\n";+ std::cout << Type(Rtt(2, HeapType::any)) << "\n";+ std::cout << Rtt(3, HeapType::eq) << "\n";+ std::cout << Type(Rtt(3, HeapType::eq)) << "\n";+ std::cout << Rtt(4, HeapType::i31) << "\n";+ std::cout << Type(Rtt(4, HeapType::i31)) << "\n";+ std::cout << Rtt(5, HeapType::exn) << "\n";+ std::cout << Type(Rtt(5, HeapType::exn)) << "\n"; Rtt signatureRtt(6, Signature(Type::none, Type::none)); std::cout << signatureRtt << "\n"; std::cout << Type(signatureRtt) << "\n"; Rtt structRtt(7, Struct({})); std::cout << structRtt << "\n"; std::cout << Type(structRtt) << "\n";- Rtt arrayRtt(8, Array({Type::i32, false}));+ Rtt arrayRtt(8, Array({Type::i32, Immutable})); std::cout << arrayRtt << "\n"; std::cout << Type(arrayRtt) << "\n"; } { std::cout << "\n;; Signature of references (param/result)\n";- Signature signature(Type(Struct({}), true),- Type(Array({Type::i32, true}), false));+ Signature signature(Type(Struct({}), Nullable),+ Type(Array({Type::i32, Mutable}), NonNullable)); std::cout << signature << "\n"; } { std::cout << "\n;; Signature of references (params/results)\n"; Signature signature(Type({- Type(Struct({}), true),- Type(Array({Type::i32, true}), false),+ Type(Struct({}), Nullable),+ Type(Array({Type::i32, Mutable}), NonNullable), }), Type({- Type(Struct({}), false),- Type(Array({Type::i32, false}), true),+ Type(Struct({}), NonNullable),+ Type(Array({Type::i32, Immutable}), Nullable), })); std::cout << signature << "\n"; } { std::cout << "\n;; Struct of references\n"; Struct structOfSignature({- {Type(Signature(Type::none, Type::none), false), false},- {Type(Signature(Type::none, Type::none), false), true},- {Type(Signature(Type::none, Type::none), true), false},- {Type(Signature(Type::none, Type::none), true), true},+ {Type(Signature(Type::none, Type::none), NonNullable), Immutable},+ {Type(Signature(Type::none, Type::none), NonNullable), Mutable},+ {Type(Signature(Type::none, Type::none), Nullable), Immutable},+ {Type(Signature(Type::none, Type::none), Nullable), Mutable}, }); std::cout << structOfSignature << "\n";- std::cout << Type(structOfSignature, false) << "\n";- std::cout << Type(structOfSignature, true) << "\n";+ std::cout << Type(structOfSignature, NonNullable) << "\n";+ std::cout << Type(structOfSignature, Nullable) << "\n"; Struct structOfStruct({- {Type(Struct({}), false), false},- {Type(Struct({}), false), true},- {Type(Struct({}), true), false},- {Type(Struct({}), true), true},+ {Type(Struct({}), NonNullable), Immutable},+ {Type(Struct({}), NonNullable), Mutable},+ {Type(Struct({}), Nullable), Immutable},+ {Type(Struct({}), Nullable), Mutable}, }); std::cout << structOfStruct << "\n";- std::cout << Type(structOfStruct, false) << "\n";- std::cout << Type(structOfStruct, true) << "\n";+ std::cout << Type(structOfStruct, NonNullable) << "\n";+ std::cout << Type(structOfStruct, Nullable) << "\n"; Struct structOfArray({- {Type(Array({Type::i32, false}), false), false},- {Type(Array({Type::i32, false}), false), true},- {Type(Array({Type::i32, false}), true), false},- {Type(Array({Type::i32, false}), true), true},+ {Type(Array({Type::i32, Immutable}), NonNullable), Immutable},+ {Type(Array({Type::i32, Immutable}), NonNullable), Mutable},+ {Type(Array({Type::i32, Immutable}), Nullable), Immutable},+ {Type(Array({Type::i32, Immutable}), Nullable), Mutable}, }); std::cout << structOfArray << "\n";- std::cout << Type(structOfArray, false) << "\n";- std::cout << Type(structOfArray, true) << "\n";+ std::cout << Type(structOfArray, NonNullable) << "\n";+ std::cout << Type(structOfArray, Nullable) << "\n"; Struct structOfEverything({- {Type::i32, true},- {Type(Signature(Type::none, Type::none), true), true},- {Type(Struct({}), true), true},- {Type(Array({Type::i32, true}), true), true},+ {Type::i32, Mutable},+ {Type(Signature(Type::none, Type::none), Nullable), Mutable},+ {Type(Struct({}), Nullable), Mutable},+ {Type(Array({Type::i32, Mutable}), Nullable), Mutable}, }); std::cout << structOfEverything << "\n";- std::cout << Type(structOfEverything, false) << "\n";- std::cout << Type(structOfEverything, true) << "\n";+ std::cout << Type(structOfEverything, NonNullable) << "\n";+ std::cout << Type(structOfEverything, Nullable) << "\n"; } { std::cout << "\n;; Array of references\n"; Array arrayOfSignature(- {Type(Signature(Type::none, Type::none), true), false});+ {Type(Signature(Type::none, Type::none), Nullable), Immutable}); std::cout << arrayOfSignature << "\n";- std::cout << Type(arrayOfSignature, false) << "\n";- std::cout << Type(arrayOfSignature, true) << "\n";- Array arrayOfStruct({Type(Struct({}), true), true});+ std::cout << Type(arrayOfSignature, NonNullable) << "\n";+ std::cout << Type(arrayOfSignature, Nullable) << "\n";+ Array arrayOfStruct({Type(Struct({}), Nullable), Mutable}); std::cout << arrayOfStruct << "\n";- std::cout << Type(arrayOfStruct, false) << "\n";- std::cout << Type(arrayOfStruct, true) << "\n";- Array arrayOfArray({Type(Array({Type::i32, false}), true), false});+ std::cout << Type(arrayOfStruct, NonNullable) << "\n";+ std::cout << Type(arrayOfStruct, Nullable) << "\n";+ Array arrayOfArray(+ {Type(Array({Type::i32, Immutable}), Nullable), Immutable}); std::cout << arrayOfArray << "\n";- std::cout << Type(arrayOfArray, false) << "\n";- std::cout << Type(arrayOfArray, true) << "\n";+ std::cout << Type(arrayOfArray, NonNullable) << "\n";+ std::cout << Type(arrayOfArray, Nullable) << "\n"; } { std::cout << "\n;; Tuple of references\n"; Tuple tuple({- Type(Signature(Type::none, Type::none), false),- Type(Signature(Type::none, Type::none), true),- Type(Struct({}), false),- Type(Struct({}), true),- Type(Array({Type::i32, false}), false),- Type(Array({Type::i32, false}), true),+ Type(Signature(Type::none, Type::none), NonNullable),+ Type(Signature(Type::none, Type::none), Nullable),+ Type(Struct({}), NonNullable),+ Type(Struct({}), Nullable),+ Type(Array({Type::i32, Immutable}), NonNullable),+ Type(Array({Type::i32, Immutable}), Nullable), }); std::cout << tuple << "\n"; std::cout << Type(tuple) << "\n";@@ -317,16 +334,17 @@ { std::cout << "\n;; Recursive (not really)\n"; Signature signatureSignature(Type::none, Type::none);- signatureSignature.params = Type(signatureSignature, false);+ signatureSignature.params = Type(signatureSignature, NonNullable); // ^ copies std::cout << signatureSignature << "\n";- std::cout << Type(signatureSignature, false) << "\n";+ std::cout << Type(signatureSignature, NonNullable) << "\n"; Signature signatureArraySignature(Type::none, Type::none); signatureArraySignature.params =- Type(Array({Type(signatureArraySignature, false), false}), false);+ Type(Array({Type(signatureArraySignature, NonNullable), Immutable}),+ NonNullable); // ^ copies std::cout << signatureArraySignature << "\n";- std::cout << Type(signatureArraySignature, false) << "\n";+ std::cout << Type(signatureArraySignature, NonNullable) << "\n"; } }
binaryen/test/export-import.wast.fromBinary.noDebugInfo view
@@ -1,8 +1,8 @@ (module (type $none_=>_none (func))- (import "env" "test2" (global $gimport$1 i32))+ (import "env" "test2" (global $gimport$0 i32)) (import "env" "test1" (func $fimport$0)) (export "test1" (func $fimport$0))- (export "test2" (global $gimport$1))+ (export "test2" (global $gimport$0)) )
+ binaryen/test/extended-names.wast view
@@ -0,0 +1,6 @@+(module $foo+ (table $t1 1 funcref)+ (memory $m1 1 1)+ (data $mydata (i32.const 0) "a")+ (data $passive_data passive "b")+)
+ binaryen/test/extended-names.wast.from-wast view
@@ -0,0 +1,6 @@+(module $foo+ (memory $m1 1 1)+ (data $mydata (i32.const 0) "a")+ (data $passive_data passive "b")+ (table $t1 1 funcref)+)
+ binaryen/test/extended-names.wast.fromBinary view
@@ -0,0 +1,7 @@+(module $foo+ (memory $m1 1 1)+ (data $mydata (i32.const 0) "a")+ (data $passive_data passive "b")+ (table $t1 1 funcref)+)+
+ binaryen/test/extended-names.wast.fromBinary.noDebugInfo view
@@ -0,0 +1,7 @@+(module+ (memory $0 1 1)+ (data (i32.const 0) "a")+ (data passive "b")+ (table $0 1 funcref)+)+
binaryen/test/extra-unreachable.wast view
@@ -1,5 +1,5 @@ (module- (type $ii (param i32) (result i32))+ (type $ii (func (param i32) (result i32))) (memory (shared 1 1)) (table 0 funcref) (global $g (mut f32) (f32.const 0))@@ -86,7 +86,7 @@ (call $foo (unreachable)) ) (global.set $g- (call_indirect (type $ii) (unreachable))+ (call_indirect (type $ii) (unreachable) (unreachable)) ) ;; unary@@ -138,16 +138,16 @@ ;; atomic.wait (global.set $g- (i32.atomic.wait+ (memory.atomic.wait32 (unreachable) (i32.const 0) (i64.const 0) ) ) - ;; atomic.notify+ ;; memory.atomic.notify (global.set $g- (atomic.notify+ (memory.atomic.notify (unreachable) (i32.const 0) )
binaryen/test/extra-unreachable.wast.from-wast view
@@ -1,7 +1,7 @@ (module (type $none_=>_none (func))- (type $i32_=>_none (func (param i32))) (type $i32_=>_i32 (func (param i32) (result i32)))+ (type $i32_=>_none (func (param i32))) (memory $0 (shared 1 1)) (table $0 0 funcref) (global $g (mut f32) (f32.const 0))@@ -64,8 +64,9 @@ ) ) (global.set $g- (call_indirect (type $none_=>_none)+ (call_indirect (type $i32_=>_i32) (unreachable)+ (unreachable) ) ) (global.set $g@@ -110,14 +111,14 @@ ) ) (global.set $g- (i32.atomic.wait+ (memory.atomic.wait32 (unreachable) (i32.const 0) (i64.const 0) ) ) (global.set $g- (atomic.notify+ (memory.atomic.notify (unreachable) (i32.const 0) )
binaryen/test/fib-dbg.wasm.fromBinary view
@@ -4,8 +4,8 @@ (type $none_=>_none (func)) (type $i32_=>_none (func (param i32))) (type $none_=>_i32 (func (result i32)))- (import "env" "memory" (memory $mimport$9 256 256))- (import "env" "table" (table $timport$10 0 0 funcref))+ (import "env" "memory" (memory $mimport$0 256 256))+ (import "env" "table" (table $timport$0 0 0 funcref)) (import "env" "DYNAMICTOP_PTR" (global $gimport$0 i32)) (import "env" "tempDoublePtr" (global $gimport$1 i32)) (import "env" "ABORT" (global $gimport$2 i32))@@ -15,8 +15,8 @@ (import "env" "fb" (global $gimport$6 i32)) (import "global" "NaN" (global $gimport$7 f64)) (import "global" "Infinity" (global $gimport$8 f64))- (import "env" "memoryBase" (global $gimport$11 i32))- (import "env" "tableBase" (global $gimport$12 i32))+ (import "env" "memoryBase" (global $gimport$9 i32))+ (import "env" "tableBase" (global $gimport$10 i32)) (global $global$0 (mut i32) (global.get $gimport$0)) (global $global$1 (mut i32) (global.get $gimport$1)) (global $global$2 (mut i32) (global.get $gimport$2))
binaryen/test/gc.wast view
@@ -68,4 +68,9 @@ (local.set $local_i32 (i31.get_s (local.get $local_i31ref))) (local.set $local_i32 (i31.get_u (local.get $local_i31ref))) )++ (func $test-variants+ (local $local_i31refnull (ref null i31))+ (local $local_i31refnonnull (ref i31))+ ) )
binaryen/test/gc.wast.from-wast view
@@ -2,7 +2,7 @@ (type $none_=>_none (func)) (global $global_anyref (mut anyref) (ref.null any)) (global $global_eqref (mut eqref) (ref.null eq))- (global $global_i31ref (mut i31ref) (i31.new+ (global $global_i31ref (mut (ref null i31)) (i31.new (i32.const 0) )) (global $global_anyref2 (mut anyref) (ref.null eq))@@ -16,7 +16,7 @@ (local $local_i32 i32) (local $local_anyref anyref) (local $local_eqref eqref)- (local $local_i31ref i31ref)+ (local $local_i31ref (ref null i31)) (local.set $local_anyref (local.get $local_anyref) )@@ -147,5 +147,10 @@ (local.get $local_i31ref) ) )+ )+ (func $test-variants+ (local $local_i31refnull (ref null i31))+ (local $local_i31refnonnull (ref null i31))+ (nop) ) )
binaryen/test/gc.wast.fromBinary view
@@ -2,7 +2,7 @@ (type $none_=>_none (func)) (global $global_anyref (mut anyref) (ref.null any)) (global $global_eqref (mut eqref) (ref.null eq))- (global $global_i31ref (mut i31ref) (i31.new+ (global $global_i31ref (mut (ref null i31)) (i31.new (i32.const 0) )) (global $global_anyref2 (mut anyref) (ref.null eq))@@ -16,7 +16,7 @@ (local $local_i32 i32) (local $local_anyref anyref) (local $local_eqref eqref)- (local $local_i31ref i31ref)+ (local $local_i31ref (ref null i31)) (local.set $local_anyref (local.get $local_anyref) )@@ -147,6 +147,11 @@ (local.get $local_i31ref) ) )+ )+ (func $test-variants+ (local $local_i31refnull (ref null i31))+ (local $local_i31refnonnull (ref null i31))+ (nop) ) )
binaryen/test/gc.wast.fromBinary.noDebugInfo view
@@ -2,7 +2,7 @@ (type $none_=>_none (func)) (global $global$0 (mut anyref) (ref.null any)) (global $global$1 (mut eqref) (ref.null eq))- (global $global$2 (mut i31ref) (i31.new+ (global $global$2 (mut (ref null i31)) (i31.new (i32.const 0) )) (global $global$3 (mut anyref) (ref.null eq))@@ -16,7 +16,7 @@ (local $0 i32) (local $1 anyref) (local $2 eqref)- (local $3 i31ref)+ (local $3 (ref null i31)) (local.set $1 (local.get $1) )@@ -147,6 +147,11 @@ (local.get $3) ) )+ )+ (func $1+ (local $0 (ref null i31))+ (local $1 (ref null i31))+ (nop) ) )
+ binaryen/test/heap-types.wast view
@@ -0,0 +1,185 @@+;; Test that we can roundtrip struct and array types+(module+ ;; Structs+ (type $struct.A (struct+ i32+ (field f32)+ (field $named f64)+ ))+ (type $struct.B (struct+ (field i8)+ (field (mut i16))+ (field (ref $struct.A))+ (field (mut (ref $struct.A)))+ ))+ (type $struct.C (struct+ (field $named-mut (mut f32))+ ))++ ;; Arrays+ (type $vector (array (mut f64)))+ (type $matrix (array (ref $vector)))+ (type $bytes (array (mut i8)))+ (type $words (array (mut i32)))++ ;; RTT+ (type $parent (struct))+ (type $child (struct i32))+ (type $grandchild (struct i32 i64))+ (global $rttparent (rtt 0 $parent) (rtt.canon $parent))+ (global $rttchild (rtt 1 $child) (rtt.sub $child (global.get $rttparent)))+ (global $rttgrandchild (rtt 2 $grandchild) (rtt.sub $grandchild (global.get $rttchild)))++ (func $structs (param $x (ref $struct.A)) (result (ref $struct.B))+ (local $tA (ref null $struct.A))+ (local $tB (ref null $struct.B))+ (local $tc (ref null $struct.C))+ (local $tv (ref null $vector))+ (local $tm (ref null $matrix))+ (drop+ (local.get $x)+ )+ (drop+ (struct.get $struct.A 0 (local.get $x))+ )+ (drop+ (struct.get $struct.A 1 (local.get $x))+ )+ (drop+ (struct.get $struct.A 2 (local.get $x))+ )+ (drop+ (struct.get $struct.A $named (local.get $x))+ )+ (drop+ (struct.get_u $struct.B 0 (local.get $tB))+ )+ (drop+ (struct.get_s $struct.B 0 (local.get $tB))+ )+ (drop+ (ref.null $struct.A)+ )+ (drop+ (block (result (ref null $struct.A))+ (local.get $x)+ )+ )+ (drop+ (if (result (ref null $struct.A))+ (i32.const 1)+ (local.get $x)+ (local.get $x)+ )+ )+ (drop+ (loop (result (ref null $struct.A))+ (local.get $x)+ )+ )+ (drop+ (select (result (ref null $struct.A))+ (local.get $x)+ (local.get $x)+ (i32.const 1)+ )+ )+ (struct.set $struct.A 0+ (local.get $x)+ (i32.const 100)+ )+ (drop+ (struct.new_default_with_rtt $struct.A+ (rtt.canon $struct.A)+ )+ )+ (drop+ (struct.new_with_rtt $struct.A+ (rtt.canon $struct.A)+ (i32.const 1)+ (f32.const 2.345)+ (f64.const 3.14159)+ )+ )+ (unreachable)+ )+ (func $arrays (param $x (ref $vector)) (result (ref $matrix))+ (local $tv (ref null $vector))+ (local $tm (ref null $matrix))+ (local $tb (ref null $bytes))+ (local $tw (ref null $words))+ (drop+ (array.new_with_rtt $vector+ (rtt.canon $vector)+ (i32.const 3)+ (f64.const 3.14159)+ )+ )+ (drop+ (array.new_default_with_rtt $matrix+ (rtt.canon $matrix)+ (i32.const 10)+ )+ )+ (drop+ (array.get $vector+ (local.get $x)+ (i32.const 2)+ )+ )+ (array.set $vector+ (local.get $x)+ (i32.const 2)+ (f64.const 2.18281828)+ )+ (drop+ (array.len $vector+ (local.get $x)+ )+ )+ (drop+ (array.get $words+ (local.get $tw)+ (i32.const 1)+ )+ )+ (drop+ (array.get_u $bytes+ (local.get $tb)+ (i32.const 2)+ )+ )+ (drop+ (array.get_s $bytes+ (local.get $tb)+ (i32.const 3)+ )+ )+ (unreachable)+ )+ ;; RTT types as parameters+ (func $rtt-param-with-depth (param $rtt (rtt 1 $parent)))+ (func $rtt-param-without-depth (param $rtt (rtt $parent)))+ (func $rtt-operations+ (local $temp.A (ref null $struct.A))+ (drop+ (ref.test $struct.B (ref.null $struct.A) (rtt.canon $struct.B))+ )+ (drop+ (ref.cast $struct.B (ref.null $struct.A) (rtt.canon $struct.B))+ )+ (drop+ (block $out (result (ref $struct.B))+ ;; set the value to a local with type $struct.A, showing that the value+ ;; flowing out has the right type+ (local.set $temp.A+ (br_on_cast $out $struct.B (ref.null $struct.A) (rtt.canon $struct.B))+ )+ ;; an untaken br_on_cast, with unreachable rtt - so we cannot use the+ ;; RTT in binaryen IR to find the cast type.+ (br_on_cast $out $struct.B (ref.null $struct.A) (unreachable))+ (unreachable)+ )+ )+ )+)
+ binaryen/test/heap-types.wast.from-wast view
@@ -0,0 +1,199 @@+(module+ (type ${i32_f32_f64} (struct (field i32) (field f32) (field f64)))+ (type $[mut:f64] (array (mut f64)))+ (type ${} (struct ))+ (type $none_=>_none (func))+ (type ${i32} (struct (field i32)))+ (type ${i32_i64} (struct (field i32) (field i64)))+ (type ${mut:f32} (struct (field (mut f32))))+ (type $[mut:i32] (array (mut i32)))+ (type $[mut:i8] (array (mut i8)))+ (type ${i8_mut:i16_ref?|{i32_f32_f64}|_mut:ref?|{i32_f32_f64}|} (struct (field i8) (field (mut i16)) (field (ref null ${i32_f32_f64})) (field (mut (ref null ${i32_f32_f64})))))+ (type $[ref?|[mut:f64]|] (array (ref null $[mut:f64])))+ (type $rtt_1_${}_=>_none (func (param (rtt 1 ${}))))+ (type $rtt_${}_=>_none (func (param (rtt ${}))))+ (type $ref?|{i32_f32_f64}|_=>_ref?|{i8_mut:i16_ref?|{i32_f32_f64}|_mut:ref?|{i32_f32_f64}|}| (func (param (ref null ${i32_f32_f64})) (result (ref null ${i8_mut:i16_ref?|{i32_f32_f64}|_mut:ref?|{i32_f32_f64}|}))))+ (type $ref?|[mut:f64]|_=>_ref?|[ref?|[mut:f64]|]| (func (param (ref null $[mut:f64])) (result (ref null $[ref?|[mut:f64]|]))))+ (global $rttparent (rtt 0 ${}) (rtt.canon ${}))+ (global $rttchild (rtt 1 ${i32}) (rtt.sub ${i32}+ (global.get $rttparent)+ ))+ (global $rttgrandchild (rtt 2 ${i32_i64}) (rtt.sub ${i32_i64}+ (global.get $rttchild)+ ))+ (func $structs (param $x (ref null ${i32_f32_f64})) (result (ref null ${i8_mut:i16_ref?|{i32_f32_f64}|_mut:ref?|{i32_f32_f64}|}))+ (local $tA (ref null ${i32_f32_f64}))+ (local $tB (ref null ${i8_mut:i16_ref?|{i32_f32_f64}|_mut:ref?|{i32_f32_f64}|}))+ (local $tc (ref null ${mut:f32}))+ (local $tv (ref null $[mut:f64]))+ (local $tm (ref null $[ref?|[mut:f64]|]))+ (drop+ (local.get $x)+ )+ (drop+ (struct.get ${i32_f32_f64} 0+ (local.get $x)+ )+ )+ (drop+ (struct.get ${i32_f32_f64} 1+ (local.get $x)+ )+ )+ (drop+ (struct.get ${i32_f32_f64} 2+ (local.get $x)+ )+ )+ (drop+ (struct.get ${i32_f32_f64} 2+ (local.get $x)+ )+ )+ (drop+ (struct.get_u ${i8_mut:i16_ref?|{i32_f32_f64}|_mut:ref?|{i32_f32_f64}|} 0+ (local.get $tB)+ )+ )+ (drop+ (struct.get_s ${i8_mut:i16_ref?|{i32_f32_f64}|_mut:ref?|{i32_f32_f64}|} 0+ (local.get $tB)+ )+ )+ (drop+ (ref.null ${i32_f32_f64})+ )+ (drop+ (block $block (result (ref null ${i32_f32_f64}))+ (local.get $x)+ )+ )+ (drop+ (if (result (ref null ${i32_f32_f64}))+ (i32.const 1)+ (local.get $x)+ (local.get $x)+ )+ )+ (drop+ (loop $loop-in (result (ref null ${i32_f32_f64}))+ (local.get $x)+ )+ )+ (drop+ (select (result (ref null ${i32_f32_f64}))+ (local.get $x)+ (local.get $x)+ (i32.const 1)+ )+ )+ (struct.set ${i32_f32_f64} 0+ (local.get $x)+ (i32.const 100)+ )+ (drop+ (struct.new_default_with_rtt ${i32_f32_f64}+ (rtt.canon ${i32_f32_f64})+ )+ )+ (drop+ (struct.new_with_rtt ${i32_f32_f64}+ (rtt.canon ${i32_f32_f64})+ (i32.const 1)+ (f32.const 2.3450000286102295)+ (f64.const 3.14159)+ )+ )+ (unreachable)+ )+ (func $arrays (param $x (ref null $[mut:f64])) (result (ref null $[ref?|[mut:f64]|]))+ (local $tv (ref null $[mut:f64]))+ (local $tm (ref null $[ref?|[mut:f64]|]))+ (local $tb (ref null $[mut:i8]))+ (local $tw (ref null $[mut:i32]))+ (drop+ (array.new_with_rtt $[mut:f64]+ (rtt.canon $[mut:f64])+ (i32.const 3)+ (f64.const 3.14159)+ )+ )+ (drop+ (array.new_default_with_rtt $[ref?|[mut:f64]|]+ (rtt.canon $[ref?|[mut:f64]|])+ (i32.const 10)+ )+ )+ (drop+ (array.get $[mut:f64]+ (local.get $x)+ (i32.const 2)+ )+ )+ (array.set $[mut:f64]+ (local.get $x)+ (i32.const 2)+ (f64.const 2.18281828)+ )+ (drop+ (array.len $[mut:f64]+ (local.get $x)+ )+ )+ (drop+ (array.get $[mut:i32]+ (local.get $tw)+ (i32.const 1)+ )+ )+ (drop+ (array.get_u $[mut:i8]+ (local.get $tb)+ (i32.const 2)+ )+ )+ (drop+ (array.get_s $[mut:i8]+ (local.get $tb)+ (i32.const 3)+ )+ )+ (unreachable)+ )+ (func $rtt-param-with-depth (param $rtt (rtt 1 ${}))+ (nop)+ )+ (func $rtt-param-without-depth (param $rtt (rtt ${}))+ (nop)+ )+ (func $rtt-operations+ (local $temp.A (ref null ${i32_f32_f64}))+ (drop+ (ref.test ${i8_mut:i16_ref?|{i32_f32_f64}|_mut:ref?|{i32_f32_f64}|}+ (ref.null ${i32_f32_f64})+ (rtt.canon ${i8_mut:i16_ref?|{i32_f32_f64}|_mut:ref?|{i32_f32_f64}|})+ )+ )+ (drop+ (ref.cast ${i8_mut:i16_ref?|{i32_f32_f64}|_mut:ref?|{i32_f32_f64}|}+ (ref.null ${i32_f32_f64})+ (rtt.canon ${i8_mut:i16_ref?|{i32_f32_f64}|_mut:ref?|{i32_f32_f64}|})+ )+ )+ (drop+ (block $out (result (ref null ${i8_mut:i16_ref?|{i32_f32_f64}|_mut:ref?|{i32_f32_f64}|}))+ (local.set $temp.A+ (br_on_cast $out ${i8_mut:i16_ref?|{i32_f32_f64}|_mut:ref?|{i32_f32_f64}|}+ (ref.null ${i32_f32_f64})+ (rtt.canon ${i8_mut:i16_ref?|{i32_f32_f64}|_mut:ref?|{i32_f32_f64}|})+ )+ )+ (br_on_cast $out ${i8_mut:i16_ref?|{i32_f32_f64}|_mut:ref?|{i32_f32_f64}|}+ (ref.null ${i32_f32_f64})+ (unreachable)+ )+ (unreachable)+ )+ )+ )+)
+ binaryen/test/heap-types.wast.fromBinary view
@@ -0,0 +1,196 @@+(module+ (type ${i32_f32_f64} (struct (field i32) (field f32) (field f64)))+ (type $[mut:f64] (array (mut f64)))+ (type ${} (struct ))+ (type $none_=>_none (func))+ (type ${i32} (struct (field i32)))+ (type ${i32_i64} (struct (field i32) (field i64)))+ (type ${mut:f32} (struct (field (mut f32))))+ (type $[mut:i32] (array (mut i32)))+ (type $[mut:i8] (array (mut i8)))+ (type ${i8_mut:i16_ref?|{i32_f32_f64}|_mut:ref?|{i32_f32_f64}|} (struct (field i8) (field (mut i16)) (field (ref null ${i32_f32_f64})) (field (mut (ref null ${i32_f32_f64})))))+ (type $[ref?|[mut:f64]|] (array (ref null $[mut:f64])))+ (type $rtt_1_${}_=>_none (func (param (rtt 1 ${}))))+ (type $rtt_${}_=>_none (func (param (rtt ${}))))+ (type $ref?|{i32_f32_f64}|_=>_ref?|{i8_mut:i16_ref?|{i32_f32_f64}|_mut:ref?|{i32_f32_f64}|}| (func (param (ref null ${i32_f32_f64})) (result (ref null ${i8_mut:i16_ref?|{i32_f32_f64}|_mut:ref?|{i32_f32_f64}|}))))+ (type $ref?|[mut:f64]|_=>_ref?|[ref?|[mut:f64]|]| (func (param (ref null $[mut:f64])) (result (ref null $[ref?|[mut:f64]|]))))+ (global $rttparent (rtt 0 ${}) (rtt.canon ${}))+ (global $rttchild (rtt 1 ${i32}) (rtt.sub ${i32}+ (global.get $rttparent)+ ))+ (global $rttgrandchild (rtt 2 ${i32_i64}) (rtt.sub ${i32_i64}+ (global.get $rttchild)+ ))+ (func $structs (param $x (ref null ${i32_f32_f64})) (result (ref null ${i8_mut:i16_ref?|{i32_f32_f64}|_mut:ref?|{i32_f32_f64}|}))+ (local $tA (ref null ${i32_f32_f64}))+ (local $tB (ref null ${i8_mut:i16_ref?|{i32_f32_f64}|_mut:ref?|{i32_f32_f64}|}))+ (local $tc (ref null ${mut:f32}))+ (local $tv (ref null $[ref?|[mut:f64]|]))+ (local $tm (ref null $[mut:f64]))+ (drop+ (local.get $x)+ )+ (drop+ (struct.get ${i32_f32_f64} 0+ (local.get $x)+ )+ )+ (drop+ (struct.get ${i32_f32_f64} 1+ (local.get $x)+ )+ )+ (drop+ (struct.get ${i32_f32_f64} 2+ (local.get $x)+ )+ )+ (drop+ (struct.get ${i32_f32_f64} 2+ (local.get $x)+ )+ )+ (drop+ (struct.get_u ${i8_mut:i16_ref?|{i32_f32_f64}|_mut:ref?|{i32_f32_f64}|} 0+ (local.get $tB)+ )+ )+ (drop+ (struct.get_s ${i8_mut:i16_ref?|{i32_f32_f64}|_mut:ref?|{i32_f32_f64}|} 0+ (local.get $tB)+ )+ )+ (drop+ (ref.null ${i32_f32_f64})+ )+ (drop+ (block $label$1 (result (ref null ${i32_f32_f64}))+ (local.get $x)+ )+ )+ (drop+ (if (result (ref null ${i32_f32_f64}))+ (i32.const 1)+ (local.get $x)+ (local.get $x)+ )+ )+ (drop+ (loop $label$4 (result (ref null ${i32_f32_f64}))+ (local.get $x)+ )+ )+ (drop+ (select (result (ref null ${i32_f32_f64}))+ (local.get $x)+ (local.get $x)+ (i32.const 1)+ )+ )+ (struct.set ${i32_f32_f64} 0+ (local.get $x)+ (i32.const 100)+ )+ (drop+ (struct.new_default_with_rtt ${i32_f32_f64}+ (rtt.canon ${i32_f32_f64})+ )+ )+ (drop+ (struct.new_with_rtt ${i32_f32_f64}+ (rtt.canon ${i32_f32_f64})+ (i32.const 1)+ (f32.const 2.3450000286102295)+ (f64.const 3.14159)+ )+ )+ (unreachable)+ )+ (func $arrays (param $x (ref null $[mut:f64])) (result (ref null $[ref?|[mut:f64]|]))+ (local $tv (ref null $[ref?|[mut:f64]|]))+ (local $tm (ref null $[mut:i32]))+ (local $tb (ref null $[mut:i8]))+ (local $tw (ref null $[mut:f64]))+ (drop+ (array.new_with_rtt $[mut:f64]+ (rtt.canon $[mut:f64])+ (i32.const 3)+ (f64.const 3.14159)+ )+ )+ (drop+ (array.new_default_with_rtt $[ref?|[mut:f64]|]+ (rtt.canon $[ref?|[mut:f64]|])+ (i32.const 10)+ )+ )+ (drop+ (array.get $[mut:f64]+ (local.get $x)+ (i32.const 2)+ )+ )+ (array.set $[mut:f64]+ (local.get $x)+ (i32.const 2)+ (f64.const 2.18281828)+ )+ (drop+ (array.len $[mut:f64]+ (local.get $x)+ )+ )+ (drop+ (array.get $[mut:i32]+ (local.get $tm)+ (i32.const 1)+ )+ )+ (drop+ (array.get_u $[mut:i8]+ (local.get $tb)+ (i32.const 2)+ )+ )+ (drop+ (array.get_s $[mut:i8]+ (local.get $tb)+ (i32.const 3)+ )+ )+ (unreachable)+ )+ (func $rtt-param-with-depth (param $rtt (rtt 1 ${}))+ (nop)+ )+ (func $rtt-param-without-depth (param $rtt (rtt ${}))+ (nop)+ )+ (func $rtt-operations+ (local $temp.A (ref null ${i32_f32_f64}))+ (drop+ (ref.test ${i8_mut:i16_ref?|{i32_f32_f64}|_mut:ref?|{i32_f32_f64}|}+ (ref.null ${i32_f32_f64})+ (rtt.canon ${i8_mut:i16_ref?|{i32_f32_f64}|_mut:ref?|{i32_f32_f64}|})+ )+ )+ (drop+ (ref.cast ${i8_mut:i16_ref?|{i32_f32_f64}|_mut:ref?|{i32_f32_f64}|}+ (ref.null ${i32_f32_f64})+ (rtt.canon ${i8_mut:i16_ref?|{i32_f32_f64}|_mut:ref?|{i32_f32_f64}|})+ )+ )+ (drop+ (block $label$1 (result (ref null ${i8_mut:i16_ref?|{i32_f32_f64}|_mut:ref?|{i32_f32_f64}|}))+ (local.set $temp.A+ (br_on_cast $label$1 ${i8_mut:i16_ref?|{i32_f32_f64}|_mut:ref?|{i32_f32_f64}|}+ (ref.null ${i32_f32_f64})+ (rtt.canon ${i8_mut:i16_ref?|{i32_f32_f64}|_mut:ref?|{i32_f32_f64}|})+ )+ )+ (unreachable)+ )+ )+ )+)+
+ binaryen/test/heap-types.wast.fromBinary.noDebugInfo view
@@ -0,0 +1,196 @@+(module+ (type ${i32_f32_f64} (struct (field i32) (field f32) (field f64)))+ (type $[mut:f64] (array (mut f64)))+ (type ${} (struct ))+ (type $none_=>_none (func))+ (type ${i32} (struct (field i32)))+ (type ${i32_i64} (struct (field i32) (field i64)))+ (type ${mut:f32} (struct (field (mut f32))))+ (type $[mut:i32] (array (mut i32)))+ (type $[mut:i8] (array (mut i8)))+ (type ${i8_mut:i16_ref?|{i32_f32_f64}|_mut:ref?|{i32_f32_f64}|} (struct (field i8) (field (mut i16)) (field (ref null ${i32_f32_f64})) (field (mut (ref null ${i32_f32_f64})))))+ (type $[ref?|[mut:f64]|] (array (ref null $[mut:f64])))+ (type $rtt_1_${}_=>_none (func (param (rtt 1 ${}))))+ (type $rtt_${}_=>_none (func (param (rtt ${}))))+ (type $ref?|{i32_f32_f64}|_=>_ref?|{i8_mut:i16_ref?|{i32_f32_f64}|_mut:ref?|{i32_f32_f64}|}| (func (param (ref null ${i32_f32_f64})) (result (ref null ${i8_mut:i16_ref?|{i32_f32_f64}|_mut:ref?|{i32_f32_f64}|}))))+ (type $ref?|[mut:f64]|_=>_ref?|[ref?|[mut:f64]|]| (func (param (ref null $[mut:f64])) (result (ref null $[ref?|[mut:f64]|]))))+ (global $global$0 (rtt 0 ${}) (rtt.canon ${}))+ (global $global$1 (rtt 1 ${i32}) (rtt.sub ${i32}+ (global.get $global$0)+ ))+ (global $global$2 (rtt 2 ${i32_i64}) (rtt.sub ${i32_i64}+ (global.get $global$1)+ ))+ (func $0 (param $0 (ref null ${i32_f32_f64})) (result (ref null ${i8_mut:i16_ref?|{i32_f32_f64}|_mut:ref?|{i32_f32_f64}|}))+ (local $1 (ref null ${i32_f32_f64}))+ (local $2 (ref null ${i8_mut:i16_ref?|{i32_f32_f64}|_mut:ref?|{i32_f32_f64}|}))+ (local $3 (ref null ${mut:f32}))+ (local $4 (ref null $[ref?|[mut:f64]|]))+ (local $5 (ref null $[mut:f64]))+ (drop+ (local.get $0)+ )+ (drop+ (struct.get ${i32_f32_f64} 0+ (local.get $0)+ )+ )+ (drop+ (struct.get ${i32_f32_f64} 1+ (local.get $0)+ )+ )+ (drop+ (struct.get ${i32_f32_f64} 2+ (local.get $0)+ )+ )+ (drop+ (struct.get ${i32_f32_f64} 2+ (local.get $0)+ )+ )+ (drop+ (struct.get_u ${i8_mut:i16_ref?|{i32_f32_f64}|_mut:ref?|{i32_f32_f64}|} 0+ (local.get $2)+ )+ )+ (drop+ (struct.get_s ${i8_mut:i16_ref?|{i32_f32_f64}|_mut:ref?|{i32_f32_f64}|} 0+ (local.get $2)+ )+ )+ (drop+ (ref.null ${i32_f32_f64})+ )+ (drop+ (block $label$1 (result (ref null ${i32_f32_f64}))+ (local.get $0)+ )+ )+ (drop+ (if (result (ref null ${i32_f32_f64}))+ (i32.const 1)+ (local.get $0)+ (local.get $0)+ )+ )+ (drop+ (loop $label$4 (result (ref null ${i32_f32_f64}))+ (local.get $0)+ )+ )+ (drop+ (select (result (ref null ${i32_f32_f64}))+ (local.get $0)+ (local.get $0)+ (i32.const 1)+ )+ )+ (struct.set ${i32_f32_f64} 0+ (local.get $0)+ (i32.const 100)+ )+ (drop+ (struct.new_default_with_rtt ${i32_f32_f64}+ (rtt.canon ${i32_f32_f64})+ )+ )+ (drop+ (struct.new_with_rtt ${i32_f32_f64}+ (rtt.canon ${i32_f32_f64})+ (i32.const 1)+ (f32.const 2.3450000286102295)+ (f64.const 3.14159)+ )+ )+ (unreachable)+ )+ (func $1 (param $0 (ref null $[mut:f64])) (result (ref null $[ref?|[mut:f64]|]))+ (local $1 (ref null $[ref?|[mut:f64]|]))+ (local $2 (ref null $[mut:i32]))+ (local $3 (ref null $[mut:i8]))+ (local $4 (ref null $[mut:f64]))+ (drop+ (array.new_with_rtt $[mut:f64]+ (rtt.canon $[mut:f64])+ (i32.const 3)+ (f64.const 3.14159)+ )+ )+ (drop+ (array.new_default_with_rtt $[ref?|[mut:f64]|]+ (rtt.canon $[ref?|[mut:f64]|])+ (i32.const 10)+ )+ )+ (drop+ (array.get $[mut:f64]+ (local.get $0)+ (i32.const 2)+ )+ )+ (array.set $[mut:f64]+ (local.get $0)+ (i32.const 2)+ (f64.const 2.18281828)+ )+ (drop+ (array.len $[mut:f64]+ (local.get $0)+ )+ )+ (drop+ (array.get $[mut:i32]+ (local.get $2)+ (i32.const 1)+ )+ )+ (drop+ (array.get_u $[mut:i8]+ (local.get $3)+ (i32.const 2)+ )+ )+ (drop+ (array.get_s $[mut:i8]+ (local.get $3)+ (i32.const 3)+ )+ )+ (unreachable)+ )+ (func $2 (param $0 (rtt 1 ${}))+ (nop)+ )+ (func $3 (param $0 (rtt ${}))+ (nop)+ )+ (func $4+ (local $0 (ref null ${i32_f32_f64}))+ (drop+ (ref.test ${i8_mut:i16_ref?|{i32_f32_f64}|_mut:ref?|{i32_f32_f64}|}+ (ref.null ${i32_f32_f64})+ (rtt.canon ${i8_mut:i16_ref?|{i32_f32_f64}|_mut:ref?|{i32_f32_f64}|})+ )+ )+ (drop+ (ref.cast ${i8_mut:i16_ref?|{i32_f32_f64}|_mut:ref?|{i32_f32_f64}|}+ (ref.null ${i32_f32_f64})+ (rtt.canon ${i8_mut:i16_ref?|{i32_f32_f64}|_mut:ref?|{i32_f32_f64}|})+ )+ )+ (drop+ (block $label$1 (result (ref null ${i8_mut:i16_ref?|{i32_f32_f64}|_mut:ref?|{i32_f32_f64}|}))+ (local.set $0+ (br_on_cast $label$1 ${i8_mut:i16_ref?|{i32_f32_f64}|_mut:ref?|{i32_f32_f64}|}+ (ref.null ${i32_f32_f64})+ (rtt.canon ${i8_mut:i16_ref?|{i32_f32_f64}|_mut:ref?|{i32_f32_f64}|})+ )+ )+ (unreachable)+ )+ )+ )+)+
− binaryen/test/hello_world.asm.js
@@ -1,10 +0,0 @@-function () {- "use asm";- function add(x, y) {- x = x | 0;- y = y | 0;- return x + y | 0;- }- return { add: add };-}-
− binaryen/test/i64-setTempRet0.asm.js
@@ -1,24 +0,0 @@-//-// Test i64 support in wasm-only builds. In this case, fastcomp emits code that is-// not asm.js, it will only ever run as wasm, and contains special intrinsics for-// asm2wasm that map LLVM IR into i64s.-//--function asm(global, env, buffer) {- "use asm";-- var illegalImportResult = env.illegalImportResult;-- var tempRet0 = 0; // this should be used to legalize the illegal result-- function illegalResult() { // illegal result, exported- return i64_const(1, 2);- }-- function imports() {- return i64_trunc(i64(illegalImportResult())) | 0;- }-- return { illegalResult: illegalResult, imports: imports };-}-
− binaryen/test/importedSignCast.asm.js
@@ -1,14 +0,0 @@-function asm(global, env, buffer) {- "use asm";-- var gm = env._emscripten_glIsTexture;-- function func() {- gm(0) << 24 >> 24;- }-- var FUNCTION_TABLE_a = [ gm ];-- return { func: func };-}-
binaryen/test/imported_memory.wast.fromBinary.noDebugInfo view
@@ -1,5 +1,5 @@ (module (import "env" "memory" (memory $mimport$0 256 256))- (import "env" "table" (table $timport$1 256 256 funcref))+ (import "env" "table" (table $timport$0 256 256 funcref)) )
binaryen/test/imported_memory_growth.wast.fromBinary.noDebugInfo view
@@ -1,5 +1,5 @@ (module (import "env" "memory" (memory $mimport$0 256))- (import "env" "table" (table $timport$1 256 funcref))+ (import "env" "table" (table $timport$0 256 funcref)) )
+ binaryen/test/lit/CMakeLists.txt view
@@ -0,0 +1,1 @@+configure_file(lit.site.cfg.py.in lit.site.cfg.py @ONLY)
+ binaryen/test/lit/lit.cfg.py view
@@ -0,0 +1,21 @@+import lit.formats++config.name = "Binaryen lit tests"+config.test_format = lit.formats.ShTest(True)++config.suffixes = ['.wat', '.wast']++config.test_source_root = os.path.dirname(__file__)+config.test_exec_root = os.path.join(config.binaryen_build_root, 'test')++# Replace all Binaryen tools with their absolute paths+bin_dir = os.path.join(config.binaryen_build_root, 'bin')+for tool_file in os.listdir(bin_dir):+ tool_path = config.binaryen_build_root + '/bin/' + tool_file+ tool = tool_file[:-4] if tool_file.endswith('.exe') else tool_file+ config.substitutions.append((tool, tool_path))++# Also make the `not` command available+not_file = config.binaryen_src_root + '/scripts/not.py'+python = sys.executable.replace('\\', '/')+config.substitutions.append(('not', python + ' ' + not_file))
+ binaryen/test/lit/lit.site.cfg.py.in view
@@ -0,0 +1,7 @@+import os++config.binaryen_src_root = r'@CMAKE_SOURCE_DIR@'+config.binaryen_build_root = r'@CMAKE_BINARY_DIR@'++lit_config.load_config(+ config, os.path.join(config.binaryen_src_root, 'test', 'lit', 'lit.cfg.py'))
+ binaryen/test/lit/parse-error.wast view
@@ -0,0 +1,10 @@+;; Test that parse errors have helpful messages++;; RUN: not wasm-opt %s 2>&1 | filecheck %s+;; CHECK: [parse exception: abc (at 8:4)]++(module+ (func $foo+ (abc)+ )+)
@@ -0,0 +1,11 @@+;; Test that shared memory requires atomics++;; RUN: not wasm-opt %s 2>&1 | filecheck %s --check-prefix NO-ATOMICS+;; RUN: wasm-opt %s --enable-threads -o - -S | filecheck %s --check-prefix ATOMICS++;; NO-ATOMICS: memory is shared, but atomics are disabled+;; ATOMICS: (memory $0 (shared 10 20))++(module+ (memory (shared 10 20))+)
+ binaryen/test/lit/wasm-emscripten-finalize/bigint.wat view
@@ -0,0 +1,22 @@+;; Test that the --bigint option prevents i64s from being split up++;; Run without --bigint to get a baseline+;; RUN: wasm-emscripten-finalize %s -S | filecheck %s --check-prefix MVP++;; Then run with --bigint to see the difference+;; RUN: wasm-emscripten-finalize %s -S --bigint | filecheck %s --check-prefix BIGINT++;; MVP: (export "dynCall_jj" (func $legalstub$dynCall_jj))+;; MVP: (func $legalstub$dynCall_jj (param $0 i32) (param $1 i32) (param $2 i32) (result i32)++;; BIGINT-NOT: legalstub+;; BIGINT: (export "dynCall_jj" (func $dynCall_jj))+;; BIGINT: (func $dynCall_jj (param $fptr i32) (param $0 i64) (result i64)++(module+ (table $0 1 1 funcref)+ (elem (i32.const 1) $foo)+ (func $foo (param i64) (result i64)+ (unreachable)+ )+)
+ binaryen/test/lit/wasm-emscripten-finalize/passive-pic.wat view
@@ -0,0 +1,38 @@+;; Test that wasm-emscripten-finalize can locate data within passive segments+;; even when compiled with PIC, which means that segment addresses are non-constant.++;; RUN: wasm-emscripten-finalize --enable-bulk-memory %s -o out.wasm | filecheck %s++;; CHECK: "asmConsts": {+;; CHECK: "3": ["hello", ["iii"], [""]]+;; CHECK: },++(module+ (import "env" "memory" (memory $memory 1 1))+ (import "env" "__memory_base" (global $__memory_base i32))+ (import "env" "emscripten_asm_const_int" (func $emscripten_asm_const_int (param i32 i32 i32) (result i32)))+ (data passive "xxxhello\00yyy")+ ;; memory init function similar to those generated by wasm-ld+ (start $__wasm_init_memory)+ (func $__wasm_init_memory+ (memory.init 0+ (i32.add+ (i32.const 0)+ (global.get $__memory_base)+ )+ (i32.const 0)+ (i32.const 12)+ )+ )+ ;; EM_ASM call passing string at address 3 in the passive segment+ (func $foo (result i32)+ (call $emscripten_asm_const_int+ (i32.add+ (global.get $__memory_base)+ (i32.const 3)+ )+ (i32.const 0)+ (i32.const 0)+ )+ )+)
+ binaryen/test/lit/wasm-split/basic.wast view
@@ -0,0 +1,141 @@+;; RUN: wasm-split %s --export-prefix='%' -o1 %t.none.1.wasm -o2 %t.none.2.wasm -v 2>&1 \+;; RUN: | filecheck %s --check-prefix KEEP-NONE+;; RUN: wasm-dis %t.none.1.wasm | filecheck %s --check-prefix KEEP-NONE-PRIMARY+;; RUN: wasm-dis %t.none.2.wasm | filecheck %s --check-prefix KEEP-NONE-SECONDARY++;; RUN: wasm-split %s --export-prefix='%' -o1 %t.foo.1.wasm -o2 %t.foo.2.wasm --keep-funcs=foo -v 2>&1 \+;; RUN: | filecheck %s --check-prefix KEEP-FOO+;; RUN: wasm-dis %t.foo.1.wasm | filecheck %s --check-prefix KEEP-FOO-PRIMARY+;; RUN: wasm-dis %t.foo.2.wasm | filecheck %s --check-prefix KEEP-FOO-SECONDARY++;; RUN: wasm-split %s --export-prefix='%' -o1 %t.bar.1.wasm -o2 %t.bar.2.wasm --keep-funcs=bar -v 2>&1 \+;; RUN: | filecheck %s --check-prefix KEEP-BAR+;; RUN: wasm-dis %t.bar.1.wasm | filecheck %s --check-prefix KEEP-BAR-PRIMARY+;; RUN: wasm-dis %t.bar.2.wasm | filecheck %s --check-prefix KEEP-BAR-SECONDARY++;; RUN: wasm-split %s --export-prefix='%' -o1 %t.both.1.wasm -o2 %t.both.2.wasm --keep-funcs=foo,bar -v 2>&1 \+;; RUN: | filecheck %s --check-prefix KEEP-BOTH+;; RUN: wasm-dis %t.both.1.wasm | filecheck %s --check-prefix KEEP-BOTH-PRIMARY+;; RUN: wasm-dis %t.both.2.wasm | filecheck %s --check-prefix KEEP-BOTH-SECONDARY++(module+ (table $table 1 1 funcref)+ (elem (i32.const 0) $foo)+ (func $foo (param i32) (result i32)+ (call $bar (i32.const 0))+ )+ (func $bar (param i32) (result i32)+ (call $foo (i32.const 1))+ )+)++;; KEEP-NONE: warning: not keeping any functions in the primary module++;; KEEP-NONE-PRIMARY: (module+;; KEEP-NONE-PRIMARY-NEXT: (type $i32_=>_i32 (func (param i32) (result i32)))+;; KEEP-NONE-PRIMARY-NEXT: (import "placeholder" "0" (func $fimport$0 (param i32) (result i32)))+;; KEEP-NONE-PRIMARY-NEXT: (table $0 1 1 funcref)+;; KEEP-NONE-PRIMARY-NEXT: (elem (i32.const 0) $fimport$0)+;; KEEP-NONE-PRIMARY-NEXT: (export "%table" (table $0))+;; KEEP-NONE-PRIMARY-NEXT: )++;; KEEP-NONE-SECONDARY: (module+;; KEEP-NONE-SECONDARY-NEXT: (type $i32_=>_i32 (func (param i32) (result i32)))+;; KEEP-NONE-SECONDARY-NEXT: (import "primary" "%table" (table $timport$0 1 1 funcref))+;; KEEP-NONE-SECONDARY-NEXT: (elem (i32.const 0) $1)+;; KEEP-NONE-SECONDARY-NEXT: (func $0 (param $0 i32) (result i32)+;; KEEP-NONE-SECONDARY-NEXT: (call $1+;; KEEP-NONE-SECONDARY-NEXT: (i32.const 1)+;; KEEP-NONE-SECONDARY-NEXT: )+;; KEEP-NONE-SECONDARY-NEXT: )+;; KEEP-NONE-SECONDARY-NEXT: (func $1 (param $0 i32) (result i32)+;; KEEP-NONE-SECONDARY-NEXT: (call $0+;; KEEP-NONE-SECONDARY-NEXT: (i32.const 0)+;; KEEP-NONE-SECONDARY-NEXT: )+;; KEEP-NONE-SECONDARY-NEXT: )+;; KEEP-NONE-SECONDARY-NEXT: )++;; KEEP-FOO: Keeping functions: foo{{$}}+;; KEEP-FOO-NEXT: Splitting out functions: bar{{$}}++;; KEEP-FOO-PRIMARY: (module+;; KEEP-FOO-PRIMARY-NEXT: (type $i32_=>_i32 (func (param i32) (result i32)))+;; KEEP-FOO-PRIMARY-NEXT: (import "placeholder" "1" (func $fimport$0 (param i32) (result i32)))+;; KEEP-FOO-PRIMARY-NEXT: (table $0 2 2 funcref)+;; KEEP-FOO-PRIMARY-NEXT: (elem (i32.const 0) $0 $fimport$0)+;; KEEP-FOO-PRIMARY-NEXT: (export "%foo" (func $0))+;; KEEP-FOO-PRIMARY-NEXT: (export "%table" (table $0))+;; KEEP-FOO-PRIMARY-NEXT: (func $0 (param $0 i32) (result i32)+;; KEEP-FOO-PRIMARY-NEXT: (call_indirect (type $i32_=>_i32)+;; KEEP-FOO-PRIMARY-NEXT: (i32.const 0)+;; KEEP-FOO-PRIMARY-NEXT: (i32.const 1)+;; KEEP-FOO-PRIMARY-NEXT: )+;; KEEP-FOO-PRIMARY-NEXT: )+;; KEEP-FOO-PRIMARY-NEXT: )++;; KEEP-FOO-SECONDARY: (module+;; KEEP-FOO-SECONDARY-NEXT: (type $i32_=>_i32 (func (param i32) (result i32)))+;; KEEP-FOO-SECONDARY-NEXT: (import "primary" "%table" (table $timport$0 2 2 funcref))+;; KEEP-FOO-SECONDARY-NEXT: (elem (i32.const 1) $0)+;; KEEP-FOO-SECONDARY-NEXT: (import "primary" "%foo" (func $fimport$0 (param i32) (result i32)))+;; KEEP-FOO-SECONDARY-NEXT: (func $0 (param $0 i32) (result i32)+;; KEEP-FOO-SECONDARY-NEXT: (call $fimport$0+;; KEEP-FOO-SECONDARY-NEXT: (i32.const 1)+;; KEEP-FOO-SECONDARY-NEXT: )+;; KEEP-FOO-SECONDARY-NEXT: )+;; KEEP-FOO-SECONDARY-NEXT: )++;; KEEP-BAR: Keeping functions: bar{{$}}+;; KEEP-BAR-NEXT: Splitting out functions: foo{{$}}++;; KEEP-BAR-PRIMARY: (module+;; KEEP-BAR-PRIMARY-NEXT: (type $i32_=>_i32 (func (param i32) (result i32)))+;; KEEP-BAR-PRIMARY-NEXT: (import "placeholder" "0" (func $fimport$0 (param i32) (result i32)))+;; KEEP-BAR-PRIMARY-NEXT: (table $0 1 1 funcref)+;; KEEP-BAR-PRIMARY-NEXT: (elem (i32.const 0) $fimport$0)+;; KEEP-BAR-PRIMARY-NEXT: (export "%bar" (func $0))+;; KEEP-BAR-PRIMARY-NEXT: (export "%table" (table $0))+;; KEEP-BAR-PRIMARY-NEXT: (func $0 (param $0 i32) (result i32)+;; KEEP-BAR-PRIMARY-NEXT: (call_indirect (type $i32_=>_i32)+;; KEEP-BAR-PRIMARY-NEXT: (i32.const 1)+;; KEEP-BAR-PRIMARY-NEXT: (i32.const 0)+;; KEEP-BAR-PRIMARY-NEXT: )+;; KEEP-BAR-PRIMARY-NEXT: )+;; KEEP-BAR-PRIMARY-NEXT: )++;; KEEP-BAR-SECONDARY: (module+;; KEEP-BAR-SECONDARY-NEXT: (type $i32_=>_i32 (func (param i32) (result i32)))+;; KEEP-BAR-SECONDARY-NEXT: (import "primary" "%table" (table $timport$0 1 1 funcref))+;; KEEP-BAR-SECONDARY-NEXT: (elem (i32.const 0) $0)+;; KEEP-BAR-SECONDARY-NEXT: (import "primary" "%bar" (func $fimport$0 (param i32) (result i32)))+;; KEEP-BAR-SECONDARY-NEXT: (func $0 (param $0 i32) (result i32)+;; KEEP-BAR-SECONDARY-NEXT: (call $fimport$0+;; KEEP-BAR-SECONDARY-NEXT: (i32.const 0)+;; KEEP-BAR-SECONDARY-NEXT: )+;; KEEP-BAR-SECONDARY-NEXT: )+;; KEEP-BAR-SECONDARY-NEXT: )++;; KEEP-BOTH: warning: not splitting any functions out to the secondary module+;; KEEP-BOTH-NEXT: Keeping functions: bar, foo{{$}}+;; KEEP-BOTH-NEXT: Splitting out functions:{{$}}++;; KEEP-BOTH-PRIMARY: (module+;; KEEP-BOTH-PRIMARY-NEXT: (type $i32_=>_i32 (func (param i32) (result i32)))+;; KEEP-BOTH-PRIMARY-NEXT: (table $0 1 1 funcref)+;; KEEP-BOTH-PRIMARY-NEXT: (elem (i32.const 0) $0)+;; KEEP-BOTH-PRIMARY-NEXT: (export "%table" (table $0))+;; KEEP-BOTH-PRIMARY-NEXT: (func $0 (param $0 i32) (result i32)+;; KEEP-BOTH-PRIMARY-NEXT: (call $1+;; KEEP-BOTH-PRIMARY-NEXT: (i32.const 0)+;; KEEP-BOTH-PRIMARY-NEXT: )+;; KEEP-BOTH-PRIMARY-NEXT: )+;; KEEP-BOTH-PRIMARY-NEXT: (func $1 (param $0 i32) (result i32)+;; KEEP-BOTH-PRIMARY-NEXT: (call $0+;; KEEP-BOTH-PRIMARY-NEXT: (i32.const 1)+;; KEEP-BOTH-PRIMARY-NEXT: )+;; KEEP-BOTH-PRIMARY-NEXT: )+;; KEEP-BOTH-PRIMARY-NEXT: )++;; KEEP-BOTH-SECONDARY: (module+;; KEEP-BOTH-SECONDARY-NEXT: (import "primary" "%table" (table $timport$0 1 1 funcref))+;; KEEP-BOTH-SECONDARY-NEXT: )
+ binaryen/test/lit/wasm-split/call_exports.mjs view
@@ -0,0 +1,25 @@+// Instantiates an instrumented module, calls the given exports, then collects+// its wasm-split profile and writes it to a given file.+//+// Usage:+//+// node call_exports.mjs <module> <profile> <export>*++import * as fs from 'fs';++let wasm = process.argv[2];+let outFile = process.argv[3];++// Create the Wasm instance+let { _, instance } = await WebAssembly.instantiate(fs.readFileSync(wasm));++// Call the specified exports+for (let i = 4; i < process.argv.length; i++) {+ console.log('calling', process.argv[i]);+ instance.exports[process.argv[i]]();+}++// Create and read the profile+let profileSize = instance.exports['__write_profile'](0, 2**32 - 1);+let profileData = Buffer.from(instance.exports.memory.buffer, 0, profileSize);+fs.writeFileSync(outFile, profileData);
+ binaryen/test/lit/wasm-split/export-name-already-exists.wast view
@@ -0,0 +1,8 @@+;; RUN: not wasm-split %s --instrument --profile-export=foo 2>&1 \+;; RUN: | filecheck %s++;; CHECK: error: Export foo already exists.++(module+ (export "foo" (memory 0 0))+)
+ binaryen/test/lit/wasm-split/initial-table.wast view
@@ -0,0 +1,13 @@+;; Test that the --initial-table flag works as expected++;; RUN: wasm-split %s --instrument --initial-table=1234 -S | filecheck %s++;; RUN: wasm-split %s -g -o1 %t.1.wasm -o2 %t.2.wasm --initial-table=1234+;; RUN: wasm-dis %t.1.wasm | filecheck %s+;; RUN: wasm-dis %t.2.wasm | filecheck %s++;; CHECK: (table $table 1234 funcref)++(module+ (table $table 3 funcref)+)
+ binaryen/test/lit/wasm-split/instrument-funcs.wast view
@@ -0,0 +1,75 @@+;; RUN: wasm-split %s --instrument -S -o - | filecheck %s++;; Check that the output round trips and validates as well+;; RUN: wasm-split %s --instrument -g -o %t+;; RUN: wasm-opt %t --print | filecheck %s++(module+ (import "env" "foo" (func $foo))+ (export "bar" (func $bar))+ (func $bar+ (call $foo)+ )+ (func $baz (param i32) (result i32)+ (local.get 0)+ )+)++;; Check that a memory has been added+;; CHECK: (memory $0 1 1)++;; Check that the counter and timestamps have been added+;; CHECK: (global $monotonic_counter (mut i32) (i32.const 0))+;; CHECK: (global $bar_timestamp (mut i32) (i32.const 0))+;; CHECK: (global $baz_timestamp (mut i32) (i32.const 0))++;; And the profiling function exported+;; CHECK: (export "__write_profile" (func $__write_profile))++;; Check that the function instrumentation is correct++;; CHECK: (func $baz (param $0 i32) (result i32)+;; CHECK-NEXT: (if+;; CHECK-NEXT: (i32.eqz+;; CHECK-NEXT: (global.get $baz_timestamp)+;; CHECK-NEXT: )+;; CHECK-NEXT: (block+;; CHECK-NEXT: (global.set $monotonic_counter+;; CHECK-NEXT: (i32.add+;; CHECK-NEXT: (global.get $monotonic_counter)+;; CHECK-NEXT: (i32.const 1)+;; CHECK-NEXT: )+;; CHECK-NEXT: )+;; CHECK-NEXT: (global.set $baz_timestamp+;; CHECK-NEXT: (global.get $monotonic_counter)+;; CHECK-NEXT: )+;; CHECK-NEXT: )+;; CHECK-NEXT: )+;; CHECK-NEXT: (local.get $0)+;; CHECK-NEXT: )++;; Check that the profiling function is correct.++;; CHECK: (func $__write_profile (param $addr i32) (param $size i32) (result i32)+;; CHECK-NEXT: (if+;; CHECK-NEXT: (i32.ge_u+;; CHECK-NEXT: (local.get $size)+;; CHECK-NEXT: (i32.const 16)+;; CHECK-NEXT: )+;; CHECK-NEXT: (block+;; CHECK-NEXT: (i64.store align=1+;; CHECK-NEXT: (local.get $addr)+;; CHECK-NEXT: (i64.const {{.*}})+;; CHECK-NEXT: )+;; CHECK-NEXT: (i32.store offset=8 align=1+;; CHECK-NEXT: (local.get $addr)+;; CHECK-NEXT: (global.get $bar_timestamp)+;; CHECK-NEXT: )+;; CHECK-NEXT: (i32.store offset=12 align=1+;; CHECK-NEXT: (local.get $addr)+;; CHECK-NEXT: (global.get $baz_timestamp)+;; CHECK-NEXT: )+;; CHECK-NEXT: )+;; CHECK-NEXT: )+;; CHECK-NEXT: (i32.const 16)+;; CHECK-NEXT: )
+ binaryen/test/lit/wasm-split/instrument-memory-too-small.wast view
@@ -0,0 +1,10 @@+;; Test that the instrumentation increases the memory bounds if necessary++;; RUN: wasm-split %s --instrument -S -o - | filecheck %s++;; CHECK: (memory $0 1 1)+;; CHECK: (export "__write_profile" (func $__write_profile))++(module+ (memory $0 0 0)+)
+ binaryen/test/lit/wasm-split/invalid-options.wast view
@@ -0,0 +1,64 @@+;; Test that invalid command line option combinations are properly rejected with+;; helpful error messages.++;; --instrument cannot be used with --profile+;; RUN: not wasm-split %s --instrument --profile %t 2>&1 \+;; RUN: | filecheck %s --check-prefix INSTRUMENT-PROFILE++;; --instrument cannot be used with -o1+;; RUN: not wasm-split %s --instrument -o1 %t 2>&1 \+;; RUN: | filecheck %s --check-prefix INSTRUMENT-OUT1++;; --instrument cannot be used with -o2+;; RUN: not wasm-split %s --instrument -o2 %t 2>&1 \+;; RUN: | filecheck %s --check-prefix INSTRUMENT-OUT2++;; --instrument cannot be used with --import-namespace+;; RUN: not wasm-split %s --instrument --import-namespace=foo 2>&1 \+;; RUN: | filecheck %s --check-prefix INSTRUMENT-IMPORT-NS++;; --instrument cannot be used with --placeholder-namespace+;; RUN: not wasm-split %s --instrument --placeholder-namespace=foo 2>&1 \+;; RUN: | filecheck %s --check-prefix INSTRUMENT-PLACEHOLDER-NS++;; --instrument cannot be used with --export-prefix+;; RUN: not wasm-split %s --instrument --export-prefix=foo 2>&1 \+;; RUN: | filecheck %s --check-prefix INSTRUMENT-EXPORT-PREFIX++;; --instrument cannot be used with --keep-funcs+;; RUN: not wasm-split %s --instrument --keep-funcs=foo 2>&1 \+;; RUN: | filecheck %s --check-prefix INSTRUMENT-KEEP-FUNCS++;; --instrument cannot be used with --split-funcs+;; RUN: not wasm-split %s --instrument --split-funcs=foo 2>&1 \+;; RUN: | filecheck %s --check-prefix INSTRUMENT-SPLIT-FUNCS++;; Split mode requires -o1 and -o2 rather than -o+;; RUN: not wasm-split %s -o %t 2>&1 \+;; RUN: | filecheck %s --check-prefix NO-INSTRUMENT-OUT++;; --instrument is required to use --profile-export+;; RUN: not wasm-split %s --profile-export=foo 2>&1 \+;; RUN: | filecheck %s --check-prefix NO-INSTRUMENT-PROFILE-EXPORT++;; INSTRUMENT-PROFILE: error: --profile cannot be used with --instrument++;; INSTRUMENT-OUT1: error: primary output cannot be used with --instrument++;; INSTRUMENT-OUT2: error: secondary output cannot be used with --instrument++;; INSTRUMENT-IMPORT-NS: error: --import-namespace cannot be used with --instrument++;; INSTRUMENT-PLACEHOLDER-NS: error: --placeholder-namespace cannot be used with --instrument++;; INSTRUMENT-EXPORT-PREFIX: error: --export-prefix cannot be used with --instrument++;; INSTRUMENT-KEEP-FUNCS: error: --keep-funcs cannot be used with --instrument++;; INSTRUMENT-SPLIT-FUNCS: error: --split-funcs cannot be used with --instrument++;; NO-INSTRUMENT-OUT: error: must provide separate primary and secondary output with -o1 and -o2++;; NO-INSTRUMENT-PROFILE-EXPORT: error: --profile-export must be used with --instrument++(module)
+ binaryen/test/lit/wasm-split/mismatched-hashes.wast view
@@ -0,0 +1,23 @@+;; Check that using different inputs for the instrumentation and splitting steps+;; results in an error.++;; Instrument the module+;; RUN: wasm-split --instrument %s -o %t.instrumented.wasm++;; Generate a profile+;; RUN: node %S/call_exports.mjs %t.instrumented.wasm %t.prof++;; Attempt to split the instrumented module+;; RUN: not wasm-split %t.instrumented.wasm --profile=%t.prof -o1 %t.1.wasm -o2 %t.2.wasm \+;; RUN: 2>&1 | filecheck %s++;; CHECK: error: checksum in profile does not match module checksum.+;; CHECK-SAME: The split module must be the original module that was instrumented+;; CHECK-SAME: to generate the profile.++;; Check that the matching module succeeds+;; RUN: wasm-split %s --profile=%t.prof -o1 %t.1.wasm -o2 %t.2.wasm++(module+ (export "memory" (memory 0 0))+)
+ binaryen/test/lit/wasm-split/name-collision.wast view
@@ -0,0 +1,16 @@+;; Regression test for a bug in which colliding internal names between+;; non-function exports would result in the wrong import names being used in the+;; secondary module.++;; RUN: wasm-split %s -o1 %t.1.wasm -o2 %t.2.wasm+;; RUN: wasm-dis %t.2.wasm | filecheck %s++;; CHECK-NOT: (import "primary" "memory" (table+;; CHECK: (import "primary" "table" (table++(module+ (table $collide 1 funcref)+ (memory $collide 1 1)+ (export "table" (table $collide))+ (export "memory" (memory $collide))+)
+ binaryen/test/lit/wasm-split/profile-guided.wast view
@@ -0,0 +1,67 @@+;; Instrument the binary++;; RUN: wasm-split --instrument %s -o %t.instrumented.wasm++;; Create profiles++;; RUN: node %S/call_exports.mjs %t.instrumented.wasm %t.foo.prof foo+;; RUN: node %S/call_exports.mjs %t.instrumented.wasm %t.bar.prof bar+;; RUN: node %S/call_exports.mjs %t.instrumented.wasm %t.both.prof foo bar+;; RUN: node %S/call_exports.mjs %t.instrumented.wasm %t.none.prof++;; Create profile-guided splits++;; RUN: wasm-split %s --profile=%t.foo.prof -v -o1 %t.foo.1.wasm -o2 %t.foo.2.wasm \+;; RUN: | filecheck %s --check-prefix FOO++;; FOO: Keeping functions: deep_foo_callee, foo, foo_callee, shared_callee+;; FOO: Splitting out functions: bar, bar_callee, uncalled++;; RUN: wasm-split %s --profile=%t.bar.prof -v -o1 %t.bar.1.wasm -o2 %t.bar.2.wasm \+;; RUN: | filecheck %s --check-prefix BAR++;; BAR: Keeping functions: bar, bar_callee, shared_callee+;; BAR: Splitting out functions: deep_foo_callee, foo, foo_callee, uncalled++;; RUN: wasm-split %s --profile=%t.both.prof -v -o1 %t.both.1.wasm -o2 %t.both.2.wasm \+;; RUN: | filecheck %s --check-prefix BOTH++;; BOTH: Keeping functions: bar, bar_callee, deep_foo_callee, foo, foo_callee, shared_callee+;; BOTH: Splitting out functions: uncalled++;; RUN: wasm-split %s --profile=%t.none.prof -v -o1 %t.none.1.wasm -o2 %t.none.2.wasm \+;; RUN: | filecheck %s --check-prefix NONE++;; NONE: Keeping functions:+;; NONE: Splitting out functions: bar, bar_callee, deep_foo_callee, foo, foo_callee, shared_callee, uncalled+++(module+ (memory $mem 1 1)+ (export "memory" (memory $mem))+ (export "foo" (func $foo))+ (export "bar" (func $bar))+ (export "uncalled" (func $uncalled))++ (func $foo+ (call $foo_callee)+ (call $shared_callee)+ )++ (func $bar+ (call $shared_callee)+ (call $bar_callee)+ )++ (func $uncalled)++ (func $foo_callee+ (call $deep_foo_callee)+ )++ (func $bar_callee)++ (func $shared_callee)++ (func $deep_foo_callee)+)
+ binaryen/test/lit/wasm-split/verbose.wast view
@@ -0,0 +1,14 @@+;; Test that --verbose mode correctly prints the kept and split funcs++;; RUN: wasm-split %s --keep-funcs=foo,bar --split-funcs=baz --verbose \+;; RUN: -o1 %t1.wasm -o2 %t2.wasm | filecheck %s++;; CHECK: Keeping functions: bar, foo{{$}}+;; CHECK: Splitting out functions: baz, quux{{$}}++(module+ (func $foo)+ (func $bar)+ (func $baz)+ (func $quux)+)
binaryen/test/lld/basic_safe_stack.wat view
@@ -5,13 +5,11 @@ (memory $0 2) (table $0 1 1 funcref) (global $global$0 (mut i32) (i32.const 66112))- (global $global$1 i32 (i32.const 568)) (export "memory" (memory $0)) (export "__wasm_call_ctors" (func $__wasm_call_ctors)) (export "stackRestore" (func $stackRestore)) (export "stackAlloc" (func $stackAlloc)) (export "main" (func $main))- (export "__data_end" (global $global$1)) (func $__wasm_call_ctors ) (func $stackRestore (param $0 i32)
binaryen/test/lld/basic_safe_stack.wat.out view
@@ -7,7 +7,6 @@ (memory $0 2) (table $0 1 1 funcref) (global $global$0 (mut i32) (i32.const 66112))- (global $global$1 i32 (i32.const 568)) (global $__stack_base (mut i32) (i32.const 0)) (global $__stack_limit (mut i32) (i32.const 0)) (export "memory" (memory $0))@@ -15,7 +14,6 @@ (export "stackRestore" (func $stackRestore)) (export "stackAlloc" (func $stackAlloc)) (export "main" (func $main))- (export "__data_end" (global $global$1)) (export "__set_stack_limits" (func $__set_stack_limits)) (func $__wasm_call_ctors (nop)@@ -90,7 +88,6 @@ (; --BEGIN METADATA -- {- "staticBump": 0, "tableSize": 1, "initializers": [ "__wasm_call_ctors"@@ -108,7 +105,6 @@ "__set_stack_limits" ], "namedGlobals": {- "__data_end" : "568" }, "invokeFuncs": [ ],
− binaryen/test/lld/bigint.wat
@@ -1,10 +0,0 @@-(module- (table $0 1 1 funcref)- (elem (i32.const 1) $foo)- (export "__data_end" (global $global$1))- (global $global$0 (mut i32) (i32.const 66208))- (global $global$1 i32 (i32.const 658))- (func $foo (param i64) (result i64)- (unreachable)- )-)
− binaryen/test/lld/bigint.wat.out
@@ -1,42 +0,0 @@-(module- (type $i64_=>_i64 (func (param i64) (result i64)))- (type $i32_i64_=>_i64 (func (param i32 i64) (result i64)))- (table $0 1 1 funcref)- (elem (i32.const 1) $foo)- (global $global$0 (mut i32) (i32.const 66208))- (global $global$1 i32 (i32.const 658))- (export "__data_end" (global $global$1))- (export "dynCall_jj" (func $dynCall_jj))- (func $foo (param $0 i64) (result i64)- (unreachable)- )- (func $dynCall_jj (param $fptr i32) (param $0 i64) (result i64)- (call_indirect (type $i64_=>_i64)- (local.get $0)- (local.get $fptr)- )- )-)-(;---BEGIN METADATA ---{- "staticBump": 90,- "tableSize": 1,- "declares": [- ],- "externs": [- ],- "exports": [- "dynCall_jj"- ],- "namedGlobals": {- "__data_end" : "658"- },- "invokeFuncs": [- ],- "mainReadsParams": 0,- "features": [- ]-}--- END METADATA ---;)
binaryen/test/lld/duplicate_imports.wat.out view
@@ -4,8 +4,8 @@ (type $none_=>_none (func)) (type $none_=>_i32 (func (result i32))) (type $i32_=>_i32 (func (param i32) (result i32)))- (type $i32_i32_=>_i32 (func (param i32 i32) (result i32))) (type $i64_=>_i32 (func (param i64) (result i32)))+ (type $i32_i32_=>_i32 (func (param i32 i32) (result i32))) (type $f32_f64_=>_f32 (func (param f32 f64) (result f32))) (type $f64_f64_=>_f32 (func (param f64 f64) (result f32))) (import "env" "puts" (func $puts1 (param i32) (result i32)))@@ -67,7 +67,6 @@ (; --BEGIN METADATA -- {- "staticBump": 13, "tableSize": 1, "initializers": [ "__wasm_call_ctors"
binaryen/test/lld/em_asm.wat view
@@ -8,11 +8,9 @@ (data (i32.const 568) "{ Module.print(\"Hello world\"); }\00\00{ return $0 + $1; }\00ii\00{ Module.print(\"Got \" + $0); }\00i\00") (table $0 1 1 funcref) (global $global$0 (mut i32) (i32.const 66208))- (global $global$1 i32 (i32.const 658)) (export "memory" (memory $0)) (export "__wasm_call_ctors" (func $__wasm_call_ctors)) (export "main" (func $main))- (export "__data_end" (global $global$1)) (func $__wasm_call_ctors ) (func $__original_main (result i32)
binaryen/test/lld/em_asm.wat.mem.out view
@@ -7,11 +7,9 @@ (memory $0 2) (table $0 1 1 funcref) (global $global$0 (mut i32) (i32.const 66208))- (global $global$1 i32 (i32.const 658)) (export "memory" (memory $0)) (export "__wasm_call_ctors" (func $__wasm_call_ctors)) (export "main" (func $main))- (export "__data_end" (global $global$1)) (func $__wasm_call_ctors (nop) )@@ -74,7 +72,6 @@ "602": ["{ return $0 + $1; }", ["iii"], [""]], "625": ["{ Module.print(\"Got \" + $0); }", ["iii"], [""]] },- "staticBump": 90, "tableSize": 1, "initializers": [ "__wasm_call_ctors"@@ -89,7 +86,6 @@ "main" ], "namedGlobals": {- "__data_end" : "658" }, "invokeFuncs": [ ],
binaryen/test/lld/em_asm.wat.out view
@@ -8,11 +8,9 @@ (data (i32.const 568) "{ Module.print(\"Hello world\"); }\00\00{ return $0 + $1; }\00ii\00{ Module.print(\"Got \" + $0); }\00i\00") (table $0 1 1 funcref) (global $global$0 (mut i32) (i32.const 66208))- (global $global$1 i32 (i32.const 658)) (export "memory" (memory $0)) (export "__wasm_call_ctors" (func $__wasm_call_ctors)) (export "main" (func $main))- (export "__data_end" (global $global$1)) (func $__wasm_call_ctors (nop) )@@ -75,7 +73,6 @@ "602": ["{ return $0 + $1; }", ["iii"], [""]], "625": ["{ Module.print(\"Got \" + $0); }", ["iii"], [""]] },- "staticBump": 90, "tableSize": 1, "initializers": [ "__wasm_call_ctors"@@ -90,7 +87,6 @@ "main" ], "namedGlobals": {- "__data_end" : "658" }, "invokeFuncs": [ ],
+ binaryen/test/lld/em_asm64.cpp view
@@ -0,0 +1,8 @@+#include <emscripten/em_asm.h>++int main() {+ EM_ASM({ Module.print("Hello world"); });+ int x = EM_ASM_INT({ return $0 + $1; }, 13, 27);+ EM_ASM_({ Module.print("Got " + $0); }, x);+ return 0;+}
+ binaryen/test/lld/em_asm64.wat view
@@ -0,0 +1,68 @@+(module+ (type $none_=>_none (func))+ (type $none_=>_i32 (func (result i32)))+ (type $i32_i64_=>_i32 (func (param i32 i64) (result i32)))+ (type $i64_i64_i64_=>_i32 (func (param i64 i64 i64) (result i32)))+ (import "env" "emscripten_asm_const_int" (func $emscripten_asm_const_int (param i64 i64 i64) (result i32)))+ (memory $0 i64 2)+ (data (i32.const 568) "{ Module.print(\"Hello world\"); }\00\00{ return $0 + $1; }\00ii\00{ Module.print(\"Got \" + $0); }\00i\00")+ (table $0 1 1 funcref)+ (global $__stack_pointer (mut i64) (i64.const 66208))+ (export "memory" (memory $0))+ (export "__wasm_call_ctors" (func $__wasm_call_ctors))+ (export "main" (func $main))+ (func $__wasm_call_ctors+ )+ (func $__original_main (result i32)+ (local $0 i64)+ (global.set $__stack_pointer+ (local.tee $0+ (i64.sub+ (global.get $__stack_pointer)+ (i64.const 32)+ )+ )+ )+ (drop+ (call $emscripten_asm_const_int+ (i64.const 568)+ (i64.const 601)+ (i64.const 0)+ )+ )+ (i64.store offset=16+ (local.get $0)+ (i64.const 115964117005)+ )+ (i32.store+ (local.get $0)+ (call $emscripten_asm_const_int+ (i64.const 602)+ (i64.const 622)+ (i64.add+ (local.get $0)+ (i64.const 16)+ )+ )+ )+ (drop+ (call $emscripten_asm_const_int+ (i64.const 625)+ (i64.const 656)+ (local.get $0)+ )+ )+ (global.set $__stack_pointer+ (i64.add+ (local.get $0)+ (i64.const 32)+ )+ )+ (i32.const 0)+ )+ (func $main (param $0 i32) (param $1 i64) (result i32)+ (call $__original_main)+ )+ ;; custom section "producers", size 112+)+
+ binaryen/test/lld/em_asm64.wat.out view
@@ -0,0 +1,99 @@+(module+ (type $none_=>_none (func))+ (type $none_=>_i32 (func (result i32)))+ (type $i32_i64_=>_i32 (func (param i32 i64) (result i32)))+ (type $i64_i64_i64_=>_i32 (func (param i64 i64 i64) (result i32)))+ (import "env" "emscripten_asm_const_int" (func $emscripten_asm_const_int (param i64 i64 i64) (result i32)))+ (memory $0 i64 2)+ (data (i32.const 568) "{ Module.print(\"Hello world\"); }\00\00{ return $0 + $1; }\00ii\00{ Module.print(\"Got \" + $0); }\00i\00")+ (table $0 1 1 funcref)+ (global $__stack_pointer (mut i64) (i64.const 66208))+ (export "memory" (memory $0))+ (export "__wasm_call_ctors" (func $__wasm_call_ctors))+ (export "main" (func $main))+ (func $__wasm_call_ctors+ (nop)+ )+ (func $__original_main (result i32)+ (local $0 i64)+ (global.set $__stack_pointer+ (local.tee $0+ (i64.sub+ (global.get $__stack_pointer)+ (i64.const 32)+ )+ )+ )+ (drop+ (call $emscripten_asm_const_int+ (i64.const 568)+ (i64.const 601)+ (i64.const 0)+ )+ )+ (i64.store offset=16+ (local.get $0)+ (i64.const 115964117005)+ )+ (i32.store+ (local.get $0)+ (call $emscripten_asm_const_int+ (i64.const 602)+ (i64.const 622)+ (i64.add+ (local.get $0)+ (i64.const 16)+ )+ )+ )+ (drop+ (call $emscripten_asm_const_int+ (i64.const 625)+ (i64.const 656)+ (local.get $0)+ )+ )+ (global.set $__stack_pointer+ (i64.add+ (local.get $0)+ (i64.const 32)+ )+ )+ (i32.const 0)+ )+ (func $main (param $0 i32) (param $1 i64) (result i32)+ (call $__original_main)+ )+)+(;+--BEGIN METADATA --+{+ "asmConsts": {+ "568": ["{ Module.print(\"Hello world\"); }", ["ijj"], [""]],+ "602": ["{ return $0 + $1; }", ["ijj"], [""]],+ "625": ["{ Module.print(\"Got \" + $0); }", ["ijj"], [""]]+ },+ "tableSize": 1,+ "initializers": [+ "__wasm_call_ctors"+ ],+ "declares": [+ "emscripten_asm_const_int"+ ],+ "externs": [+ ],+ "exports": [+ "__wasm_call_ctors",+ "main"+ ],+ "namedGlobals": {+ },+ "invokeFuncs": [+ ],+ "mainReadsParams": 0,+ "features": [+ "--enable-memory64"+ ]+}+-- END METADATA --+;)
binaryen/test/lld/em_asm_O0.wat view
@@ -7,11 +7,9 @@ (data (i32.const 568) "{ Module.print(\"Hello world\"); }\00{ return $0 + $1; }\00{ Module.print(\"Got \" + $0); }\00") (table $0 1 1 funcref) (global $global$0 (mut i32) (i32.const 66192))- (global $global$1 i32 (i32.const 652)) (export "memory" (memory $0)) (export "__wasm_call_ctors" (func $__wasm_call_ctors)) (export "main" (func $main))- (export "__data_end" (global $global$1)) (func $__wasm_call_ctors ) (func $main (param $0 i32) (param $1 i32) (result i32)
binaryen/test/lld/em_asm_O0.wat.out view
@@ -7,11 +7,9 @@ (data (i32.const 568) "{ Module.print(\"Hello world\"); }\00{ return $0 + $1; }\00{ Module.print(\"Got \" + $0); }\00") (table $0 1 1 funcref) (global $global$0 (mut i32) (i32.const 66192))- (global $global$1 i32 (i32.const 652)) (export "memory" (memory $0)) (export "__wasm_call_ctors" (func $__wasm_call_ctors)) (export "main" (func $main))- (export "__data_end" (global $global$1)) (func $__wasm_call_ctors (nop) )@@ -100,7 +98,6 @@ "601": ["{ return $0 + $1; }", ["iii"], [""]], "621": ["{ Module.print(\"Got \" + $0); }", ["iii"], [""]] },- "staticBump": 84, "tableSize": 1, "initializers": [ "__wasm_call_ctors"@@ -115,7 +112,6 @@ "main" ], "namedGlobals": {- "__data_end" : "652" }, "invokeFuncs": [ ],
binaryen/test/lld/em_asm_main_thread.wat.out view
@@ -198,7 +198,6 @@ "601": ["{ return $0 + $1; }", ["iii"], ["sync_on_main_thread_"]], "621": ["{ Module.print(\"Got \" + $0); }", ["iii"], ["sync_on_main_thread_"]] },- "staticBump": 84, "tableSize": 1, "initializers": [ "__wasm_call_ctors"
@@ -4,14 +4,14 @@ (type $i32_i32_=>_i32 (func (param i32 i32) (result i32))) (type $i32_i32_i32_=>_i32 (func (param i32 i32 i32) (result i32))) (import "env" "memory" (memory $mimport$0 0))- (data (global.get $gimport$3) "{ Module.print(\"Hello world\"); }\00\00{ return $0 + $1; }\00ii\00{ Module.print(\"Got \" + $0); }\00i\00")- (import "env" "__indirect_function_table" (table $timport$1 0 funcref))- (import "env" "__stack_pointer" (global $gimport$2 (mut i32)))- (import "env" "__memory_base" (global $gimport$3 i32))- (import "env" "__table_base" (global $gimport$4 i32))- (import "GOT.mem" "_ZN20__em_asm_sig_builderI19__em_asm_type_tupleIJEEE6bufferE" (global $gimport$6 (mut i32)))- (import "GOT.mem" "_ZN20__em_asm_sig_builderI19__em_asm_type_tupleIJiiEEE6bufferE" (global $gimport$7 (mut i32)))- (import "GOT.mem" "_ZN20__em_asm_sig_builderI19__em_asm_type_tupleIJiEEE6bufferE" (global $gimport$8 (mut i32)))+ (data (global.get $gimport$1) "{ Module.print(\"Hello world\"); }\00\00{ return $0 + $1; }\00ii\00{ Module.print(\"Got \" + $0); }\00i\00")+ (import "env" "__indirect_function_table" (table $timport$0 0 funcref))+ (import "env" "__stack_pointer" (global $gimport$0 (mut i32)))+ (import "env" "__memory_base" (global $gimport$1 i32))+ (import "env" "__table_base" (global $gimport$2 i32))+ (import "GOT.mem" "_ZN20__em_asm_sig_builderI19__em_asm_type_tupleIJEEE6bufferE" (global $gimport$3 (mut i32)))+ (import "GOT.mem" "_ZN20__em_asm_sig_builderI19__em_asm_type_tupleIJiiEEE6bufferE" (global $gimport$4 (mut i32)))+ (import "GOT.mem" "_ZN20__em_asm_sig_builderI19__em_asm_type_tupleIJiEEE6bufferE" (global $gimport$5 (mut i32))) (import "env" "emscripten_asm_const_int" (func $emscripten_asm_const_int (param i32 i32 i32) (result i32))) (global $global$0 i32 (i32.const 33)) (global $global$1 i32 (i32.const 54))@@ -30,10 +30,10 @@ (func $__original_main (result i32) (local $0 i32) (local $1 i32)- (global.set $gimport$2+ (global.set $gimport$0 (local.tee $0 (i32.sub- (global.get $gimport$2)+ (global.get $gimport$0) (i32.const 32) ) )@@ -42,11 +42,11 @@ (call $emscripten_asm_const_int (i32.add (local.tee $1- (global.get $gimport$3)+ (global.get $gimport$1) ) (i32.const 0) )- (global.get $gimport$6)+ (global.get $gimport$3) (i32.const 0) ) )@@ -61,7 +61,7 @@ (local.get $1) (i32.const 34) )- (global.get $gimport$7)+ (global.get $gimport$4) (i32.add (local.get $0) (i32.const 16)@@ -74,11 +74,11 @@ (local.get $1) (i32.const 57) )- (global.get $gimport$8)+ (global.get $gimport$5) (local.get $0) ) )- (global.set $gimport$2+ (global.set $gimport$0 (i32.add (local.get $0) (i32.const 32)
@@ -1,32 +1,27 @@ (module- (type $none_=>_i32 (func (result i32))) (type $none_=>_none (func))- (type $i32_=>_none (func (param i32)))+ (type $none_=>_i32 (func (result i32))) (type $i32_i32_=>_i32 (func (param i32 i32) (result i32))) (type $i32_i32_i32_=>_i32 (func (param i32 i32 i32) (result i32))) (import "env" "memory" (memory $mimport$0 0))- (data (global.get $gimport$3) "{ Module.print(\"Hello world\"); }\00\00{ return $0 + $1; }\00ii\00{ Module.print(\"Got \" + $0); }\00i\00")- (import "env" "table" (table $timport$1 0 funcref))- (import "env" "__memory_base" (global $gimport$3 i32))- (import "env" "__table_base" (global $gimport$4 i32))+ (data (global.get $gimport$1) "{ Module.print(\"Hello world\"); }\00\00{ return $0 + $1; }\00ii\00{ Module.print(\"Got \" + $0); }\00i\00")+ (import "env" "__indirect_function_table" (table $timport$0 0 funcref))+ (import "env" "__stack_pointer" (global $gimport$0 (mut i32)))+ (import "env" "__memory_base" (global $gimport$1 i32))+ (import "env" "__table_base" (global $gimport$2 i32))+ (import "GOT.mem" "_ZN20__em_asm_sig_builderI19__em_asm_type_tupleIJEEE6bufferE" (global $gimport$3 (mut i32)))+ (import "GOT.mem" "_ZN20__em_asm_sig_builderI19__em_asm_type_tupleIJiiEEE6bufferE" (global $gimport$4 (mut i32)))+ (import "GOT.mem" "_ZN20__em_asm_sig_builderI19__em_asm_type_tupleIJiEEE6bufferE" (global $gimport$5 (mut i32))) (import "env" "emscripten_asm_const_int" (func $emscripten_asm_const_int (param i32 i32 i32) (result i32)))- (import "env" "stackSave" (func $stackSave (result i32)))- (import "env" "stackRestore" (func $stackRestore (param i32)))- (import "env" "g$_ZN20__em_asm_sig_builderI19__em_asm_type_tupleIJEEE6bufferE" (func $g$_ZN20__em_asm_sig_builderI19__em_asm_type_tupleIJEEE6bufferE (result i32)))- (import "env" "g$_ZN20__em_asm_sig_builderI19__em_asm_type_tupleIJiiEEE6bufferE" (func $g$_ZN20__em_asm_sig_builderI19__em_asm_type_tupleIJiiEEE6bufferE (result i32)))- (import "env" "g$_ZN20__em_asm_sig_builderI19__em_asm_type_tupleIJiEEE6bufferE" (func $g$_ZN20__em_asm_sig_builderI19__em_asm_type_tupleIJiEEE6bufferE (result i32)))- (global $gimport$6 (mut i32) (i32.const 0))- (global $gimport$7 (mut i32) (i32.const 0))- (global $gimport$8 (mut i32) (i32.const 0)) (global $global$0 i32 (i32.const 33)) (global $global$1 i32 (i32.const 54)) (global $global$2 i32 (i32.const 88))+ (export "__post_instantiate" (func $__wasm_call_ctors)) (export "__original_main" (func $__original_main)) (export "_ZN20__em_asm_sig_builderI19__em_asm_type_tupleIJEEE6bufferE" (global $global$0)) (export "_ZN20__em_asm_sig_builderI19__em_asm_type_tupleIJiiEEE6bufferE" (global $global$1)) (export "_ZN20__em_asm_sig_builderI19__em_asm_type_tupleIJiEEE6bufferE" (global $global$2)) (export "main" (func $main))- (export "__post_instantiate" (func $__post_instantiate)) (func $__wasm_call_ctors (call $__wasm_apply_relocs) )@@ -36,10 +31,10 @@ (func $__original_main (result i32) (local $0 i32) (local $1 i32)- (call $stackRestore+ (global.set $gimport$0 (local.tee $0 (i32.sub- (call $stackSave)+ (global.get $gimport$0) (i32.const 32) ) )@@ -48,11 +43,11 @@ (call $emscripten_asm_const_int (i32.add (local.tee $1- (global.get $gimport$3)+ (global.get $gimport$1) ) (i32.const 0) )- (global.get $gimport$6)+ (global.get $gimport$3) (i32.const 0) ) )@@ -67,7 +62,7 @@ (local.get $1) (i32.const 34) )- (global.get $gimport$7)+ (global.get $gimport$4) (i32.add (local.get $0) (i32.const 16)@@ -80,11 +75,11 @@ (local.get $1) (i32.const 57) )- (global.get $gimport$8)+ (global.get $gimport$5) (local.get $0) ) )- (call $stackRestore+ (global.set $gimport$0 (i32.add (local.get $0) (i32.const 32)@@ -95,21 +90,6 @@ (func $main (param $0 i32) (param $1 i32) (result i32) (call $__original_main) )- (func $__assign_got_enties- (global.set $gimport$6- (call $g$_ZN20__em_asm_sig_builderI19__em_asm_type_tupleIJEEE6bufferE)- )- (global.set $gimport$7- (call $g$_ZN20__em_asm_sig_builderI19__em_asm_type_tupleIJiiEEE6bufferE)- )- (global.set $gimport$8- (call $g$_ZN20__em_asm_sig_builderI19__em_asm_type_tupleIJiEEE6bufferE)- )- )- (func $__post_instantiate- (call $__assign_got_enties)- (call $__wasm_call_ctors)- ) ) (; --BEGIN METADATA --@@ -119,24 +99,22 @@ "34": ["{ return $0 + $1; }", ["iii"], [""]], "57": ["{ Module.print(\"Got \" + $0); }", ["iii"], [""]] },- "staticBump": 0, "tableSize": 0, "declares": [- "emscripten_asm_const_int",- "stackSave",- "stackRestore",- "g$_ZN20__em_asm_sig_builderI19__em_asm_type_tupleIJEEE6bufferE",- "g$_ZN20__em_asm_sig_builderI19__em_asm_type_tupleIJiiEEE6bufferE",- "g$_ZN20__em_asm_sig_builderI19__em_asm_type_tupleIJiEEE6bufferE"+ "emscripten_asm_const_int" ], "externs": [+ "___stack_pointer", "___memory_base",- "___table_base"+ "___table_base",+ "__ZN20__em_asm_sig_builderI19__em_asm_type_tupleIJEEE6bufferE",+ "__ZN20__em_asm_sig_builderI19__em_asm_type_tupleIJiiEEE6bufferE",+ "__ZN20__em_asm_sig_builderI19__em_asm_type_tupleIJiEEE6bufferE" ], "exports": [+ "__post_instantiate", "__original_main",- "main",- "__post_instantiate"+ "main" ], "namedGlobals": { "_ZN20__em_asm_sig_builderI19__em_asm_type_tupleIJEEE6bufferE" : "33",
binaryen/test/lld/em_asm_table.wat.out view
@@ -32,7 +32,6 @@ (; --BEGIN METADATA -- {- "staticBump": 480, "tableSize": 159609, "declares": [ "emscripten_log",
binaryen/test/lld/em_js_O0.wat.out view
@@ -15,7 +15,6 @@ "emJsFuncs": { "noarg": "(void)<::>{ out(\"no args works\"); }" },- "staticBump": 6664, "tableSize": 0, "declares": [ ],
− binaryen/test/lld/gdollar_mainmodule.wat
@@ -1,20 +0,0 @@-(module- (import "env" "memory" (memory $0 0))- (data (global.get $gimport$3) "")- (import "env" "__indirect_function_table" (table $timport$1 0 funcref))- (import "env" "__stack_pointer" (global $gimport$2 (mut i32)))- (import "env" "__memory_base" (global $gimport$3 i32))- (import "env" "__table_base" (global $gimport$4 i32))- (import "GOT.mem" "someglobal1" (global $gimport$6 (mut i32)))- (import "GOT.mem" "someglobal2" (global $gimport$7 (mut i32)))- (import "GOT.mem" "someglobal3" (global $gimport$8 (mut i32)))- (global $global$1 i32 (i32.const 54))- (global $global$2 i32 (i32.const 0))- (export "someglobal2" (global $global$1))- (export "main" (func $main))- (export "__data_end" (global $global$2))- (func $main (param $0 i32) (param $1 i32) (result i32)- (i32.const 0)- )-)-
− binaryen/test/lld/gdollar_mainmodule.wat.out
@@ -1,73 +0,0 @@-(module- (type $none_=>_i32 (func (result i32)))- (type $none_=>_none (func))- (type $i32_i32_=>_i32 (func (param i32 i32) (result i32)))- (import "env" "memory" (memory $0 0))- (data (global.get $gimport$3) "")- (import "env" "table" (table $timport$1 0 funcref))- (import "env" "__stack_pointer" (global $gimport$2_import i32))- (import "env" "__memory_base" (global $gimport$3 i32))- (import "env" "__table_base" (global $gimport$4 i32))- (import "env" "g$someglobal1" (func $g$someglobal1 (result i32)))- (import "env" "g$someglobal3" (func $g$someglobal3 (result i32)))- (global $gimport$6 (mut i32) (i32.const 0))- (global $gimport$7 (mut i32) (i32.const 0))- (global $gimport$8 (mut i32) (i32.const 0))- (global $global$1 i32 (i32.const 54))- (global $global$2 i32 (i32.const 0))- (global $gimport$2 (mut i32) (global.get $gimport$2_import))- (export "someglobal2" (global $global$1))- (export "main" (func $main))- (export "__data_end" (global $global$2))- (export "__assign_got_enties" (func $__assign_got_enties))- (func $main (param $0 i32) (param $1 i32) (result i32)- (i32.const 0)- )- (func $__assign_got_enties- (global.set $gimport$6- (call $g$someglobal1)- )- (global.set $gimport$7- (i32.add- (global.get $gimport$3)- (global.get $global$1)- )- )- (global.set $gimport$8- (call $g$someglobal3)- )- )-)-(;---BEGIN METADATA ---{- "staticBump": 4294966728,- "tableSize": 0,- "initializers": [- "__assign_got_enties"- ],- "declares": [- "g$someglobal1",- "g$someglobal3"- ],- "externs": [- "___stack_pointer",- "___memory_base",- "___table_base"- ],- "exports": [- "main",- "__assign_got_enties"- ],- "namedGlobals": {- "someglobal2" : "54",- "__data_end" : "0"- },- "invokeFuncs": [- ],- "mainReadsParams": 1,- "features": [- ]-}--- END METADATA ---;)
binaryen/test/lld/hello_world.passive.wat.out view
@@ -40,7 +40,6 @@ (; --BEGIN METADATA -- {- "staticBump": 13, "tableSize": 1, "initializers": [ "__wasm_call_ctors"
binaryen/test/lld/hello_world.wat view
@@ -8,11 +8,9 @@ (data (i32.const 568) "Hello, world\00") (table $0 1 1 funcref) (global $global$0 (mut i32) (i32.const 66128))- (global $global$1 i32 (i32.const 581)) (export "memory" (memory $0)) (export "__wasm_call_ctors" (func $__wasm_call_ctors)) (export "main" (func $main))- (export "__data_end" (global $global$1)) (func $__wasm_call_ctors ) (func $__original_main (result i32)
binaryen/test/lld/hello_world.wat.mem.out view
@@ -7,11 +7,9 @@ (memory $0 2) (table $0 1 1 funcref) (global $global$0 (mut i32) (i32.const 66128))- (global $global$1 i32 (i32.const 581)) (export "memory" (memory $0)) (export "__wasm_call_ctors" (func $__wasm_call_ctors)) (export "main" (func $main))- (export "__data_end" (global $global$1)) (func $__wasm_call_ctors (nop) )@@ -30,7 +28,6 @@ (; --BEGIN METADATA -- {- "staticBump": 13, "tableSize": 1, "initializers": [ "__wasm_call_ctors"@@ -45,7 +42,6 @@ "main" ], "namedGlobals": {- "__data_end" : "581" }, "invokeFuncs": [ ],
binaryen/test/lld/hello_world.wat.out view
@@ -8,11 +8,9 @@ (data (i32.const 568) "Hello, world\00") (table $0 1 1 funcref) (global $global$0 (mut i32) (i32.const 66128))- (global $global$1 i32 (i32.const 581)) (export "memory" (memory $0)) (export "__wasm_call_ctors" (func $__wasm_call_ctors)) (export "main" (func $main))- (export "__data_end" (global $global$1)) (func $__wasm_call_ctors (nop) )@@ -31,7 +29,6 @@ (; --BEGIN METADATA -- {- "staticBump": 13, "tableSize": 1, "initializers": [ "__wasm_call_ctors"@@ -46,7 +43,6 @@ "main" ], "namedGlobals": {- "__data_end" : "581" }, "invokeFuncs": [ ],
binaryen/test/lld/init.wat view
@@ -5,11 +5,9 @@ (memory $0 2) (table $0 1 1 funcref) (global $global$0 (mut i32) (i32.const 66112))- (global $global$1 i32 (i32.const 576)) (export "memory" (memory $0)) (export "__wasm_call_ctors" (func $__wasm_call_ctors)) (export "main" (func $main))- (export "__data_end" (global $global$1)) (func $__wasm_call_ctors (call $init_x) (call $init_y)
binaryen/test/lld/init.wat.out view
@@ -5,11 +5,9 @@ (memory $0 2) (table $0 1 1 funcref) (global $global$0 (mut i32) (i32.const 66112))- (global $global$1 i32 (i32.const 576)) (export "memory" (memory $0)) (export "__wasm_call_ctors" (func $__wasm_call_ctors)) (export "main" (func $main))- (export "__data_end" (global $global$1)) (func $__wasm_call_ctors (call $init_x) (call $init_y)@@ -43,7 +41,6 @@ (; --BEGIN METADATA -- {- "staticBump": 8, "tableSize": 1, "initializers": [ "__wasm_call_ctors"@@ -57,7 +54,6 @@ "main" ], "namedGlobals": {- "__data_end" : "576" }, "invokeFuncs": [ ],
binaryen/test/lld/longjmp.wat view
@@ -20,11 +20,9 @@ (table $0 2 2 funcref) (elem (i32.const 1) $fimport$3) (global $global$0 (mut i32) (i32.const 66112))- (global $global$1 i32 (i32.const 576)) (export "memory" (memory $0)) (export "__wasm_call_ctors" (func $0)) (export "main" (func $2))- (export "__data_end" (global $global$1)) (func $0 ) (func $1 (result i32)
binaryen/test/lld/longjmp.wat.out view
@@ -20,11 +20,9 @@ (table $0 2 2 funcref) (elem (i32.const 1) $fimport$3) (global $global$0 (mut i32) (i32.const 66112))- (global $global$1 i32 (i32.const 576)) (export "memory" (memory $0)) (export "__wasm_call_ctors" (func $0)) (export "main" (func $2))- (export "__data_end" (global $global$1)) (export "dynCall_vii" (func $dynCall_vii)) (func $0 (nop)@@ -143,7 +141,6 @@ (; --BEGIN METADATA -- {- "staticBump": 8, "tableSize": 2, "initializers": [ "__wasm_call_ctors"@@ -165,7 +162,6 @@ "dynCall_vii" ], "namedGlobals": {- "__data_end" : "576" }, "invokeFuncs": [ "invoke_vii"
binaryen/test/lld/main_module.wat.out view
@@ -1,31 +1,25 @@ (module- (type $none_=>_i32 (func (result i32))) (type $none_=>_none (func))+ (type $none_=>_i32 (func (result i32))) (type $i32_=>_i32 (func (param i32) (result i32))) (import "env" "memory" (memory $0 0)) (data (global.get $gimport$2) "Hello, world\00\00\00\00\00\00\00\00\00\00\00\00")- (import "env" "table" (table $timport$1 1 funcref))- (elem (global.get $gimport$3) $print_message\28\29)- (import "env" "__stack_pointer" (global $sp_import i32))+ (import "env" "__indirect_function_table" (table $timport$1 0 funcref))+ (import "env" "__stack_pointer" (global $sp (mut i32))) (import "env" "__memory_base" (global $gimport$2 i32)) (import "env" "__table_base" (global $gimport$3 i32))+ (import "GOT.mem" "external_var" (global $gimport$5 (mut i32)))+ (import "GOT.func" "puts" (global $gimport$6 (mut i32)))+ (import "GOT.func" "_Z13print_messagev" (global $gimport$7 (mut i32))) (import "env" "puts" (func $puts (param i32) (result i32)))- (import "env" "g$external_var" (func $g$external_var (result i32)))- (import "env" "fp$puts$ii" (func $fp$puts$ii (result i32)))- (global $gimport$5 (mut i32) (i32.const 0))- (global $gimport$6 (mut i32) (i32.const 0))- (global $gimport$7 (mut i32) (i32.const 0)) (global $global$0 i32 (i32.const 16)) (global $global$1 i32 (i32.const 20)) (global $global i32 (i32.const 42))- (global $sp (mut i32) (global.get $sp_import)) (export "__wasm_call_ctors" (func $__wasm_call_ctors)) (export "_Z13print_messagev" (func $print_message\28\29)) (export "ptr_puts" (global $global$0)) (export "ptr_local_func" (global $global$1)) (export "__data_end" (global $global))- (export "dynCall_i" (func $dynCall_i))- (export "__assign_got_enties" (func $__assign_got_enties)) (func $__wasm_call_ctors (call $__wasm_apply_relocs) )@@ -58,50 +52,28 @@ (global.get $gimport$5) ) )- (func $__assign_got_enties- (global.set $gimport$5- (call $g$external_var)- )- (global.set $gimport$6- (call $fp$puts$ii)- )- (global.set $gimport$7- (i32.add- (global.get $gimport$3)- (i32.const 0)- )- )- )- (func $dynCall_i (param $fptr i32) (result i32)- (call_indirect (type $none_=>_i32)- (local.get $fptr)- )- ) ) (; --BEGIN METADATA -- {- "staticBump": 4294966770,- "tableSize": 1,+ "tableSize": 0, "initializers": [- "__assign_got_enties", "__wasm_call_ctors" ], "declares": [- "puts",- "g$external_var",- "fp$puts$ii"+ "puts" ], "externs": [ "___stack_pointer", "___memory_base",- "___table_base"+ "___table_base",+ "_external_var",+ "_puts",+ "__Z13print_messagev" ], "exports": [ "__wasm_call_ctors",- "_Z13print_messagev",- "dynCall_i",- "__assign_got_enties"+ "_Z13print_messagev" ], "namedGlobals": { "ptr_puts" : "16",
binaryen/test/lld/main_module_table.wat.out view
@@ -1,52 +1,26 @@ (module (type $none_=>_none (func))- (type $i32_=>_none (func (param i32)))- (import "env" "__stack_pointer" (global $sp_import i32))- (import "env" "__table_base" (global $__table_base i32))- (table $0 1 funcref)- (elem (global.get $__table_base) $__stdio_write)- (global $gimport$9 (mut i32) (i32.const 0))+ (import "env" "__stack_pointer" (global $sp (mut i32)))+ (import "GOT.func" "__stdio_write" (global $gimport$9 (mut i32))) (global $global i32 (i32.const 42))- (global $sp (mut i32) (global.get $sp_import)) (export "__stdio_write" (func $__stdio_write)) (export "__data_end" (global $global))- (export "dynCall_v" (func $dynCall_v))- (export "__assign_got_enties" (func $__assign_got_enties)) (func $__stdio_write (nop) )- (func $__assign_got_enties- (global.set $gimport$9- (i32.add- (global.get $__table_base)- (i32.const 0)- )- )- )- (func $dynCall_v (param $fptr i32)- (call_indirect (type $none_=>_none)- (local.get $fptr)- )- ) ) (; --BEGIN METADATA -- {- "staticBump": 4294966770,- "tableSize": 1,- "initializers": [- "__assign_got_enties"- ],+ "tableSize": 0, "declares": [ ], "externs": [ "___stack_pointer",- "___table_base"+ "___stdio_write" ], "exports": [- "__stdio_write",- "dynCall_v",- "__assign_got_enties"+ "__stdio_write" ], "namedGlobals": { "__data_end" : "42"
binaryen/test/lld/main_module_table_2.wat.out view
@@ -1,52 +1,27 @@ (module (type $none_=>_none (func))- (type $i32_=>_none (func (param i32)))- (import "env" "table" (table $timport$9 2 funcref))- (elem (global.get $__table_base) $__stdio_write)- (import "env" "__stack_pointer" (global $sp_import i32))- (import "env" "__table_base" (global $__table_base i32))- (global $gimport$9 (mut i32) (i32.const 0))+ (import "env" "table" (table $timport$9 1 funcref))+ (import "env" "__stack_pointer" (global $sp (mut i32)))+ (import "GOT.func" "__stdio_write" (global $gimport$9 (mut i32))) (global $global i32 (i32.const 42))- (global $sp (mut i32) (global.get $sp_import)) (export "__stdio_write" (func $__stdio_write)) (export "__data_end" (global $global))- (export "dynCall_v" (func $dynCall_v))- (export "__assign_got_enties" (func $__assign_got_enties)) (func $__stdio_write (nop) )- (func $__assign_got_enties- (global.set $gimport$9- (i32.add- (global.get $__table_base)- (i32.const 0)- )- )- )- (func $dynCall_v (param $fptr i32)- (call_indirect (type $none_=>_none)- (local.get $fptr)- )- ) ) (; --BEGIN METADATA -- {- "staticBump": 4294966770,- "tableSize": 2,- "initializers": [- "__assign_got_enties"- ],+ "tableSize": 1, "declares": [ ], "externs": [ "___stack_pointer",- "___table_base"+ "___stdio_write" ], "exports": [- "__stdio_write",- "dynCall_v",- "__assign_got_enties"+ "__stdio_write" ], "namedGlobals": { "__data_end" : "42"
binaryen/test/lld/main_module_table_3.wat.out view
@@ -1,52 +1,27 @@ (module (type $none_=>_none (func))- (type $i32_=>_none (func (param i32)))- (import "env" "table" (table $timport$9 2 funcref))- (elem (i32.const 0) $__stdio_write)- (import "env" "__stack_pointer" (global $sp_import i32))- (import "env" "__table_base" (global $__table_base i32))- (global $gimport$9 (mut i32) (i32.const 0))+ (import "env" "table" (table $timport$9 1 funcref))+ (import "env" "__stack_pointer" (global $sp (mut i32)))+ (import "GOT.func" "__stdio_write" (global $gimport$9 (mut i32))) (global $global i32 (i32.const 42))- (global $sp (mut i32) (global.get $sp_import)) (export "__stdio_write" (func $__stdio_write)) (export "__data_end" (global $global))- (export "dynCall_v" (func $dynCall_v))- (export "__assign_got_enties" (func $__assign_got_enties)) (func $__stdio_write (nop) )- (func $__assign_got_enties- (global.set $gimport$9- (i32.add- (global.get $__table_base)- (i32.const 0)- )- )- )- (func $dynCall_v (param $fptr i32)- (call_indirect (type $none_=>_none)- (local.get $fptr)- )- ) ) (; --BEGIN METADATA -- {- "staticBump": 4294966770,- "tableSize": 2,- "initializers": [- "__assign_got_enties"- ],+ "tableSize": 1, "declares": [ ], "externs": [ "___stack_pointer",- "___table_base"+ "___stdio_write" ], "exports": [- "__stdio_write",- "dynCall_v",- "__assign_got_enties"+ "__stdio_write" ], "namedGlobals": { "__data_end" : "42"
binaryen/test/lld/main_module_table_4.wat.out view
@@ -1,52 +1,29 @@ (module (type $none_=>_none (func))- (type $i32_=>_none (func (param i32)))- (import "env" "table" (table $timport$9 2 funcref))- (elem (global.get $tb) $__stdio_write)- (import "env" "__stack_pointer" (global $sp_import i32))+ (import "env" "table" (table $timport$9 1 funcref))+ (import "env" "__stack_pointer" (global $sp (mut i32)))+ (import "GOT.func" "__stdio_write" (global $gimport$9 (mut i32))) (import "env" "__table_base" (global $tb i32))- (global $gimport$9 (mut i32) (i32.const 0)) (global $global i32 (i32.const 42))- (global $sp (mut i32) (global.get $sp_import)) (export "__stdio_write" (func $__stdio_write)) (export "__data_end" (global $global))- (export "dynCall_v" (func $dynCall_v))- (export "__assign_got_enties" (func $__assign_got_enties)) (func $__stdio_write (nop) )- (func $__assign_got_enties- (global.set $gimport$9- (i32.add- (global.get $tb)- (i32.const 0)- )- )- )- (func $dynCall_v (param $fptr i32)- (call_indirect (type $none_=>_none)- (local.get $fptr)- )- ) ) (; --BEGIN METADATA -- {- "staticBump": 4294966770,- "tableSize": 2,- "initializers": [- "__assign_got_enties"- ],+ "tableSize": 1, "declares": [ ], "externs": [ "___stack_pointer",+ "___stdio_write", "___table_base" ], "exports": [- "__stdio_write",- "dynCall_v",- "__assign_got_enties"+ "__stdio_write" ], "namedGlobals": { "__data_end" : "42"
binaryen/test/lld/main_module_table_5.wat.out view
@@ -1,17 +1,15 @@ (module (type $none_=>_none (func)) (type $i32_=>_none (func (param i32)))- (import "env" "table" (table $timport$9 2 funcref))- (elem (global.get $tb) $other $stuff $__stdio_write)- (import "env" "__stack_pointer" (global $sp_import i32))+ (import "env" "table" (table $timport$9 1 funcref))+ (elem (global.get $tb) $other $stuff)+ (import "env" "__stack_pointer" (global $sp (mut i32)))+ (import "GOT.func" "__stdio_write" (global $gimport$9 (mut i32))) (import "env" "__table_base" (global $tb i32))- (global $gimport$9 (mut i32) (i32.const 0)) (global $global i32 (i32.const 42))- (global $sp (mut i32) (global.get $sp_import)) (export "__stdio_write" (func $__stdio_write)) (export "__data_end" (global $global)) (export "dynCall_v" (func $dynCall_v))- (export "__assign_got_enties" (func $__assign_got_enties)) (func $__stdio_write (nop) )@@ -21,14 +19,6 @@ (func $stuff (nop) )- (func $__assign_got_enties- (global.set $gimport$9- (i32.add- (global.get $tb)- (i32.const 2)- )- )- ) (func $dynCall_v (param $fptr i32) (call_indirect (type $none_=>_none) (local.get $fptr)@@ -38,21 +28,17 @@ (; --BEGIN METADATA -- {- "staticBump": 4294966770,- "tableSize": 2,- "initializers": [- "__assign_got_enties"- ],+ "tableSize": 1, "declares": [ ], "externs": [ "___stack_pointer",+ "___stdio_write", "___table_base" ], "exports": [ "__stdio_write",- "dynCall_v",- "__assign_got_enties"+ "dynCall_v" ], "namedGlobals": { "__data_end" : "42"
binaryen/test/lld/recursive.wat view
@@ -7,11 +7,9 @@ (data (i32.const 568) "%d:%d\n\00Result: %d\n\00") (table $0 1 1 funcref) (global $global$0 (mut i32) (i32.const 66128))- (global $global$1 i32 (i32.const 587)) (export "memory" (memory $0)) (export "__wasm_call_ctors" (func $__wasm_call_ctors)) (export "main" (func $main))- (export "__data_end" (global $global$1)) (func $__wasm_call_ctors ) (func $foo (param $0 i32) (param $1 i32) (result i32)
binaryen/test/lld/recursive.wat.out view
@@ -7,11 +7,9 @@ (data (i32.const 568) "%d:%d\n\00Result: %d\n\00") (table $0 1 1 funcref) (global $global$0 (mut i32) (i32.const 66128))- (global $global$1 i32 (i32.const 587)) (export "memory" (memory $0)) (export "__wasm_call_ctors" (func $__wasm_call_ctors)) (export "main" (func $main))- (export "__data_end" (global $global$1)) (func $__wasm_call_ctors (nop) )@@ -88,7 +86,6 @@ (; --BEGIN METADATA -- {- "staticBump": 19, "tableSize": 1, "initializers": [ "__wasm_call_ctors"@@ -103,7 +100,6 @@ "main" ], "namedGlobals": {- "__data_end" : "587" }, "invokeFuncs": [ ],
binaryen/test/lld/recursive_safe_stack.wat.out view
@@ -175,7 +175,6 @@ (; --BEGIN METADATA -- {- "staticBump": 19, "tableSize": 1, "initializers": [ "__wasm_call_ctors"
binaryen/test/lld/reserved_func_ptr.wat view
@@ -11,11 +11,9 @@ (table $0 3 3 funcref) (elem (i32.const 1) $address_taken_func\28int\2c\20int\2c\20int\29 $address_taken_func2\28int\2c\20int\2c\20int\29) (global $global$0 (mut i32) (i32.const 66112))- (global $global$1 i32 (i32.const 568)) (export "memory" (memory $0)) (export "__wasm_call_ctors" (func $__wasm_call_ctors)) (export "main" (func $main))- (export "__data_end" (global $global$1)) (func $__wasm_call_ctors ) (func $address_taken_func\28int\2c\20int\2c\20int\29 (param $0 i32) (param $1 i32) (param $2 i32)
binaryen/test/lld/reserved_func_ptr.wat.out view
@@ -12,11 +12,9 @@ (table $0 3 3 funcref) (elem (i32.const 1) $address_taken_func\28int\2c\20int\2c\20int\29 $address_taken_func2\28int\2c\20int\2c\20int\29) (global $global$0 (mut i32) (i32.const 66112))- (global $global$1 i32 (i32.const 568)) (export "memory" (memory $0)) (export "__wasm_call_ctors" (func $__wasm_call_ctors)) (export "main" (func $main))- (export "__data_end" (global $global$1)) (export "dynCall_viii" (func $dynCall_viii)) (func $__wasm_call_ctors (nop)@@ -123,7 +121,6 @@ (; --BEGIN METADATA -- {- "staticBump": 0, "tableSize": 3, "initializers": [ "__wasm_call_ctors"@@ -139,7 +136,6 @@ "dynCall_viii" ], "namedGlobals": {- "__data_end" : "568" }, "invokeFuncs": [ ],
binaryen/test/lld/safe_stack_standalone-wasm.wat.out view
@@ -174,7 +174,6 @@ (; --BEGIN METADATA -- {- "staticBump": 19, "tableSize": 1, "initializers": [ "__wasm_call_ctors"
@@ -3,13 +3,13 @@ (type $none_=>_i32 (func (result i32))) (type $i32_=>_i32 (func (param i32) (result i32))) (import "env" "memory" (memory $mimport$0 0))- (data (global.get $gimport$2) "Hello, world\00\00\00\00\00\00\00\00\00\00\00\00")- (import "env" "__indirect_function_table" (table $timport$1 0 funcref))- (import "env" "__memory_base" (global $gimport$2 i32))- (import "env" "__table_base" (global $gimport$3 i32))- (import "GOT.mem" "external_var" (global $gimport$5 (mut i32)))- (import "GOT.func" "puts" (global $gimport$6 (mut i32)))- (import "GOT.func" "_Z13print_messagev" (global $gimport$7 (mut i32)))+ (data (global.get $gimport$0) "Hello, world\00\00\00\00\00\00\00\00\00\00\00\00")+ (import "env" "__indirect_function_table" (table $timport$0 0 funcref))+ (import "env" "__memory_base" (global $gimport$0 i32))+ (import "env" "__table_base" (global $gimport$1 i32))+ (import "GOT.mem" "external_var" (global $gimport$2 (mut i32)))+ (import "GOT.func" "puts" (global $gimport$3 (mut i32)))+ (import "GOT.func" "_Z13print_messagev" (global $gimport$4 (mut i32))) (import "env" "puts" (func $puts (param i32) (result i32))) (global $global$0 i32 (i32.const 16)) (global $global$1 i32 (i32.const 20))@@ -23,30 +23,30 @@ (func $__wasm_apply_relocs (i32.store (i32.add- (global.get $gimport$2)+ (global.get $gimport$0) (i32.const 16) )- (global.get $gimport$6)+ (global.get $gimport$3) ) (i32.store (i32.add- (global.get $gimport$2)+ (global.get $gimport$0) (i32.const 20) )- (global.get $gimport$7)+ (global.get $gimport$4) ) ) (func $print_message\28\29 (result i32) (drop (call $puts (i32.add- (global.get $gimport$2)+ (global.get $gimport$0) (i32.const 0) ) ) ) (i32.load- (global.get $gimport$5)+ (global.get $gimport$2) ) ) ;; dylink section
@@ -3,89 +3,70 @@ (type $none_=>_i32 (func (result i32))) (type $i32_=>_i32 (func (param i32) (result i32))) (import "env" "memory" (memory $mimport$0 0))- (data (global.get $gimport$2) "Hello, world\00\00\00\00\00\00\00\00\00\00\00\00")- (import "env" "table" (table $timport$1 0 funcref))- (import "env" "__memory_base" (global $gimport$2 i32))- (import "env" "__table_base" (global $gimport$3 i32))+ (data (global.get $gimport$0) "Hello, world\00\00\00\00\00\00\00\00\00\00\00\00")+ (import "env" "__indirect_function_table" (table $timport$0 0 funcref))+ (import "env" "__memory_base" (global $gimport$0 i32))+ (import "env" "__table_base" (global $gimport$1 i32))+ (import "GOT.mem" "external_var" (global $gimport$2 (mut i32)))+ (import "GOT.func" "puts" (global $gimport$3 (mut i32)))+ (import "GOT.func" "_Z13print_messagev" (global $gimport$4 (mut i32))) (import "env" "puts" (func $puts (param i32) (result i32)))- (import "env" "g$external_var" (func $g$external_var (result i32)))- (import "env" "fp$puts$ii" (func $fp$puts$ii (result i32)))- (import "env" "fp$_Z13print_messagev$i" (func $fp$_Z13print_messagev$i (result i32)))- (global $gimport$5 (mut i32) (i32.const 0))- (global $gimport$6 (mut i32) (i32.const 0))- (global $gimport$7 (mut i32) (i32.const 0)) (global $global$0 i32 (i32.const 16)) (global $global$1 i32 (i32.const 20))+ (export "__post_instantiate" (func $__wasm_call_ctors)) (export "_Z13print_messagev" (func $print_message\28\29)) (export "ptr_puts" (global $global$0)) (export "ptr_local_func" (global $global$1))- (export "__post_instantiate" (func $__post_instantiate)) (func $__wasm_call_ctors (call $__wasm_apply_relocs) ) (func $__wasm_apply_relocs (i32.store (i32.add- (global.get $gimport$2)+ (global.get $gimport$0) (i32.const 16) )- (global.get $gimport$6)+ (global.get $gimport$3) ) (i32.store (i32.add- (global.get $gimport$2)+ (global.get $gimport$0) (i32.const 20) )- (global.get $gimport$7)+ (global.get $gimport$4) ) ) (func $print_message\28\29 (result i32) (drop (call $puts (i32.add- (global.get $gimport$2)+ (global.get $gimport$0) (i32.const 0) ) ) ) (i32.load- (global.get $gimport$5)- )- )- (func $__assign_got_enties- (global.set $gimport$5- (call $g$external_var)- )- (global.set $gimport$6- (call $fp$puts$ii)- )- (global.set $gimport$7- (call $fp$_Z13print_messagev$i)+ (global.get $gimport$2) ) )- (func $__post_instantiate- (call $__assign_got_enties)- (call $__wasm_call_ctors)- ) ) (; --BEGIN METADATA -- {- "staticBump": 0, "tableSize": 0, "declares": [- "puts",- "g$external_var",- "fp$puts$ii",- "fp$_Z13print_messagev$i"+ "puts" ], "externs": [ "___memory_base",- "___table_base"+ "___table_base",+ "_external_var",+ "_puts",+ "__Z13print_messagev" ], "exports": [- "_Z13print_messagev",- "__post_instantiate"+ "__post_instantiate",+ "_Z13print_messagev" ], "namedGlobals": { "ptr_puts" : "16",
@@ -1,31 +1,28 @@ (module- (type $none_=>_i32 (func (result i32))) (type $none_=>_none (func)) (type $i32_=>_i32 (func (param i32) (result i32)))+ (type $none_=>_i32 (func (result i32))) (type $i32_i32_=>_i32 (func (param i32 i32) (result i32))) (import "env" "memory" (memory $mimport$0 0))- (data (global.get $gimport$3) "*\00\00\00")- (import "env" "table" (table $timport$1 0 funcref))- (import "env" "__memory_base" (global $gimport$3 i32))- (import "env" "__table_base" (global $gimport$4 i32))+ (data (global.get $gimport$1) "*\00\00\00")+ (import "env" "__indirect_function_table" (table $timport$0 0 funcref))+ (import "env" "__stack_pointer" (global $gimport$0 (mut i32)))+ (import "env" "__memory_base" (global $gimport$1 i32))+ (import "env" "__table_base" (global $gimport$2 i32))+ (import "GOT.func" "_Z16waka_func_theirsi" (global $gimport$3 (mut i32)))+ (import "GOT.func" "_Z14waka_func_minei" (global $gimport$4 (mut i32)))+ (import "GOT.mem" "waka_mine" (global $gimport$5 (mut i32)))+ (import "GOT.mem" "waka_others" (global $gimport$6 (mut i32))) (import "env" "_Z16waka_func_theirsi" (func $waka_func_theirs\28int\29 (param i32) (result i32)))- (import "env" "g$waka_mine" (func $g$waka_mine (result i32)))- (import "env" "g$waka_others" (func $g$waka_others (result i32)))- (import "env" "fp$_Z16waka_func_theirsi$ii" (func $fp$_Z16waka_func_theirsi$ii (result i32)))- (import "env" "fp$_Z14waka_func_minei$ii" (func $fp$_Z14waka_func_minei$ii (result i32)))- (global $gimport$6 (mut i32) (i32.const 0))- (global $gimport$7 (mut i32) (i32.const 0))- (global $gimport$8 (mut i32) (i32.const 0))- (global $gimport$9 (mut i32) (i32.const 0)) (global $global$0 i32 (i32.const 0)) (global $global$1 i32 (i32.const 0))+ (export "__post_instantiate" (func $__wasm_call_ctors)) (export "__wasm_apply_relocs" (func $__wasm_apply_relocs)) (export "_Z14waka_func_minei" (func $waka_func_mine\28int\29)) (export "__original_main" (func $__original_main)) (export "waka_mine" (global $global$0)) (export "main" (func $main)) (export "__dso_handle" (global $global$1))- (export "__post_instantiate" (func $__post_instantiate)) (func $__wasm_call_ctors (call $__wasm_apply_relocs) )@@ -41,15 +38,15 @@ (local $0 i32) (local $1 i32) (local.set $0- (global.get $gimport$6)+ (global.get $gimport$3) ) (local.set $1- (global.get $gimport$7)+ (global.get $gimport$4) ) (i32.add (i32.add (i32.load- (global.get $gimport$8)+ (global.get $gimport$5) ) (i32.add (local.get $1)@@ -57,31 +54,13 @@ ) ) (i32.load- (global.get $gimport$9)+ (global.get $gimport$6) ) ) ) (func $main (param $0 i32) (param $1 i32) (result i32) (call $__original_main) )- (func $__assign_got_enties- (global.set $gimport$8- (call $g$waka_mine)- )- (global.set $gimport$9- (call $g$waka_others)- )- (global.set $gimport$6- (call $fp$_Z16waka_func_theirsi$ii)- )- (global.set $gimport$7- (call $fp$_Z14waka_func_minei$ii)- )- )- (func $__post_instantiate- (call $__assign_got_enties)- (call $__wasm_call_ctors)- ) ;; dylink section ;; memorysize: 4 ;; memoryalignment: 2@@ -92,25 +71,25 @@ (; --BEGIN METADATA -- {- "staticBump": 0, "tableSize": 0, "declares": [- "_Z16waka_func_theirsi",- "g$waka_mine",- "g$waka_others",- "fp$_Z16waka_func_theirsi$ii",- "fp$_Z14waka_func_minei$ii"+ "_Z16waka_func_theirsi" ], "externs": [+ "___stack_pointer", "___memory_base",- "___table_base"+ "___table_base",+ "__Z16waka_func_theirsi",+ "__Z14waka_func_minei",+ "_waka_mine",+ "_waka_others" ], "exports": [+ "__post_instantiate", "__wasm_apply_relocs", "_Z14waka_func_minei", "__original_main",- "main",- "__post_instantiate"+ "main" ], "namedGlobals": { "waka_mine" : "0",
@@ -8,21 +8,21 @@ (type $i32_i32_i32_=>_i32 (func (param i32 i32 i32) (result i32))) (type $i32_i32_i32_i32_=>_i32 (func (param i32 i32 i32 i32) (result i32))) (import "env" "memory" (memory $mimport$0 0))- (data (global.get $gimport$2) "\00\00\00\00\00\00\00\00")- (import "env" "__indirect_function_table" (table $timport$1 0 funcref))- (import "env" "__memory_base" (global $gimport$2 i32))- (import "env" "__table_base" (global $gimport$3 i32))- (import "GOT.mem" "__THREW__" (global $gimport$12 (mut i32)))- (import "GOT.func" "emscripten_longjmp" (global $gimport$13 (mut i32)))- (import "GOT.mem" "__threwValue" (global $gimport$14 (mut i32)))- (import "env" "malloc" (func $fimport$4 (param i32) (result i32)))- (import "env" "saveSetjmp" (func $fimport$5 (param i32 i32 i32 i32) (result i32)))- (import "env" "getTempRet0" (func $fimport$6 (result i32)))- (import "env" "emscripten_longjmp" (func $fimport$7 (param i32 i32)))- (import "env" "invoke_vii" (func $fimport$8 (param i32 i32 i32)))- (import "env" "testSetjmp" (func $fimport$9 (param i32 i32 i32) (result i32)))- (import "env" "setTempRet0" (func $fimport$10 (param i32)))- (import "env" "free" (func $fimport$11 (param i32)))+ (data (global.get $gimport$0) "\00\00\00\00\00\00\00\00")+ (import "env" "__indirect_function_table" (table $timport$0 0 funcref))+ (import "env" "__memory_base" (global $gimport$0 i32))+ (import "env" "__table_base" (global $gimport$1 i32))+ (import "GOT.mem" "__THREW__" (global $gimport$2 (mut i32)))+ (import "GOT.func" "emscripten_longjmp" (global $gimport$3 (mut i32)))+ (import "GOT.mem" "__threwValue" (global $gimport$4 (mut i32)))+ (import "env" "malloc" (func $fimport$0 (param i32) (result i32)))+ (import "env" "saveSetjmp" (func $fimport$1 (param i32 i32 i32 i32) (result i32)))+ (import "env" "getTempRet0" (func $fimport$2 (result i32)))+ (import "env" "emscripten_longjmp" (func $fimport$3 (param i32 i32)))+ (import "env" "invoke_vii" (func $fimport$4 (param i32 i32 i32)))+ (import "env" "testSetjmp" (func $fimport$5 (param i32 i32 i32) (result i32)))+ (import "env" "setTempRet0" (func $fimport$6 (param i32)))+ (import "env" "free" (func $fimport$7 (param i32))) (global $global$0 i32 (i32.const 0)) (global $global$1 i32 (i32.const 4)) (export "__wasm_call_ctors" (func $0))@@ -41,14 +41,14 @@ (local $3 i32) (i32.store (local.tee $0- (call $fimport$4+ (call $fimport$0 (i32.const 40) ) ) (i32.const 0) ) (local.set $1- (call $fimport$5+ (call $fimport$1 (local.get $0) (i32.const 1) (local.get $0)@@ -56,7 +56,7 @@ ) ) (local.set $2- (call $fimport$6)+ (call $fimport$2) ) (local.set $0 (i32.const 0)@@ -69,12 +69,12 @@ ) (i32.store (local.tee $0- (global.get $gimport$12)+ (global.get $gimport$2) ) (i32.const 0) )- (call $fimport$8- (global.get $gimport$13)+ (call $fimport$4+ (global.get $gimport$3) (local.get $0) (i32.const 1) )@@ -88,7 +88,7 @@ (i32.const 0) ) (local.set $0- (global.get $gimport$14)+ (global.get $gimport$4) ) (block $label$4 (br_if $label$4@@ -107,7 +107,7 @@ ) (br_if $label$1 (i32.eqz- (call $fimport$9+ (call $fimport$5 (i32.load (local.get $3) )@@ -116,22 +116,22 @@ ) ) )- (call $fimport$10+ (call $fimport$6 (local.get $0) ) ) (local.set $0- (call $fimport$6)+ (call $fimport$2) ) (br $label$3) ) )- (call $fimport$11+ (call $fimport$7 (local.get $1) ) (return) )- (call $fimport$7+ (call $fimport$3 (local.get $3) (local.get $0) )
@@ -1,38 +1,35 @@ (module (type $none_=>_none (func))- (type $none_=>_i32 (func (result i32))) (type $i32_=>_none (func (param i32))) (type $i32_i32_=>_none (func (param i32 i32))) (type $i32_i32_i32_=>_none (func (param i32 i32 i32)))+ (type $none_=>_i32 (func (result i32))) (type $i32_=>_i32 (func (param i32) (result i32))) (type $i32_i32_i32_=>_i32 (func (param i32 i32 i32) (result i32))) (type $i32_i32_i32_i32_=>_i32 (func (param i32 i32 i32 i32) (result i32))) (import "env" "memory" (memory $mimport$0 0))- (data (global.get $gimport$2) "\00\00\00\00\00\00\00\00")- (import "env" "table" (table $timport$1 0 funcref))- (import "env" "__memory_base" (global $gimport$2 i32))- (import "env" "__table_base" (global $gimport$3 i32))- (import "env" "malloc" (func $fimport$4 (param i32) (result i32)))- (import "env" "saveSetjmp" (func $fimport$5 (param i32 i32 i32 i32) (result i32)))- (import "env" "getTempRet0" (func $fimport$6 (result i32)))- (import "env" "emscripten_longjmp" (func $fimport$7 (param i32 i32)))- (import "env" "invoke_vii" (func $fimport$8 (param i32 i32 i32)))- (import "env" "testSetjmp" (func $fimport$9 (param i32 i32 i32) (result i32)))- (import "env" "setTempRet0" (func $fimport$10 (param i32)))- (import "env" "free" (func $fimport$11 (param i32)))- (import "env" "g$__THREW__" (func $g$__THREW__ (result i32)))- (import "env" "g$__threwValue" (func $g$__threwValue (result i32)))- (import "env" "fp$emscripten_longjmp$vii" (func $fp$emscripten_longjmp$vii (result i32)))- (global $gimport$12 (mut i32) (i32.const 0))- (global $gimport$13 (mut i32) (i32.const 0))- (global $gimport$14 (mut i32) (i32.const 0))+ (data (global.get $gimport$0) "\00\00\00\00\00\00\00\00")+ (import "env" "__indirect_function_table" (table $timport$0 0 funcref))+ (import "env" "__memory_base" (global $gimport$0 i32))+ (import "env" "__table_base" (global $gimport$1 i32))+ (import "GOT.mem" "__THREW__" (global $gimport$2 (mut i32)))+ (import "GOT.func" "emscripten_longjmp" (global $gimport$3 (mut i32)))+ (import "GOT.mem" "__threwValue" (global $gimport$4 (mut i32)))+ (import "env" "malloc" (func $fimport$0 (param i32) (result i32)))+ (import "env" "saveSetjmp" (func $fimport$1 (param i32 i32 i32 i32) (result i32)))+ (import "env" "getTempRet0" (func $fimport$2 (result i32)))+ (import "env" "emscripten_longjmp" (func $fimport$3 (param i32 i32)))+ (import "env" "invoke_vii" (func $fimport$4 (param i32 i32 i32)))+ (import "env" "testSetjmp" (func $fimport$5 (param i32 i32 i32) (result i32)))+ (import "env" "setTempRet0" (func $fimport$6 (param i32)))+ (import "env" "free" (func $fimport$7 (param i32))) (global $global$0 i32 (i32.const 0)) (global $global$1 i32 (i32.const 4))+ (export "__post_instantiate" (func $0)) (export "_start" (func $2)) (export "__THREW__" (global $global$0)) (export "__threwValue" (global $global$1)) (export "dynCall_vii" (func $dynCall_vii))- (export "__post_instantiate" (func $__post_instantiate)) (func $0 (call $1) )@@ -46,14 +43,14 @@ (local $3 i32) (i32.store (local.tee $0- (call $fimport$4+ (call $fimport$0 (i32.const 40) ) ) (i32.const 0) ) (local.set $1- (call $fimport$5+ (call $fimport$1 (local.get $0) (i32.const 1) (local.get $0)@@ -61,7 +58,7 @@ ) ) (local.set $2- (call $fimport$6)+ (call $fimport$2) ) (local.set $0 (i32.const 0)@@ -74,12 +71,12 @@ ) (i32.store (local.tee $0- (global.get $gimport$12)+ (global.get $gimport$2) ) (i32.const 0) )- (call $fimport$8- (global.get $gimport$13)+ (call $fimport$4+ (global.get $gimport$3) (local.get $0) (i32.const 1) )@@ -93,7 +90,7 @@ (i32.const 0) ) (local.set $0- (global.get $gimport$14)+ (global.get $gimport$4) ) (block $label$4 (br_if $label$4@@ -112,7 +109,7 @@ ) (br_if $label$1 (i32.eqz- (call $fimport$9+ (call $fimport$5 (i32.load (local.get $3) )@@ -121,38 +118,27 @@ ) ) )- (call $fimport$10+ (call $fimport$6 (local.get $0) ) ) (local.set $0- (call $fimport$6)+ (call $fimport$2) ) (br $label$3) ) )- (call $fimport$11+ (call $fimport$7 (local.get $1) ) (return) )- (call $fimport$7+ (call $fimport$3 (local.get $3) (local.get $0) ) (unreachable) )- (func $__assign_got_enties- (global.set $gimport$12- (call $g$__THREW__)- )- (global.set $gimport$14- (call $g$__threwValue)- )- (global.set $gimport$13- (call $fp$emscripten_longjmp$vii)- )- ) (func $dynCall_vii (param $fptr i32) (param $0 i32) (param $1 i32) (call_indirect (type $i32_i32_=>_none) (local.get $0)@@ -160,15 +146,10 @@ (local.get $fptr) ) )- (func $__post_instantiate- (call $__assign_got_enties)- (call $0)- ) ) (; --BEGIN METADATA -- {- "staticBump": 0, "tableSize": 0, "declares": [ "malloc",@@ -177,19 +158,19 @@ "emscripten_longjmp", "testSetjmp", "setTempRet0",- "free",- "g$__THREW__",- "g$__threwValue",- "fp$emscripten_longjmp$vii"+ "free" ], "externs": [ "___memory_base",- "___table_base"+ "___table_base",+ "___THREW__",+ "_emscripten_longjmp",+ "___threwValue" ], "exports": [+ "__post_instantiate", "_start",- "dynCall_vii",- "__post_instantiate"+ "dynCall_vii" ], "namedGlobals": { "__THREW__" : "0",
binaryen/test/lld/standalone-wasm-with-start.wat.out view
@@ -20,7 +20,6 @@ (; --BEGIN METADATA -- {- "staticBump": 8, "tableSize": 1, "declares": [ ],
binaryen/test/lld/standalone-wasm.wat.out view
@@ -24,7 +24,6 @@ (; --BEGIN METADATA -- {- "staticBump": 8, "tableSize": 1, "declares": [ ],
binaryen/test/lld/standalone-wasm2.wat.out view
@@ -21,7 +21,6 @@ (; --BEGIN METADATA -- {- "staticBump": 8, "tableSize": 0, "declares": [ ],
binaryen/test/lld/standalone-wasm3.wat.out view
@@ -14,7 +14,6 @@ (; --BEGIN METADATA -- {- "staticBump": 8, "tableSize": 0, "declares": [ ],
− binaryen/test/memorygrowth-minimal.asm.js
@@ -1,41 +0,0 @@-Module["asm"] = (function(global,env,buffer) {-- "almost asm";- var a = global.Int8Array;- var b = global.Int16Array;- var c = global.Int32Array;- var d = global.Uint8Array;- var e = global.Uint16Array;- var f = global.Uint32Array;- var g = global.Float32Array;- var h = global.Float64Array;- var i = new a(buffer);- var j = new b(buffer);- var k = new c(buffer);- var l = new d(buffer);- var m = new e(buffer);- var n = new f(buffer);- var o = new g(buffer);- var p = new h(buffer);- var q = global.byteLength;-- function replaceBuffer(newBuffer) {- if (q(newBuffer) & 16777215 || q(newBuffer) <= 16777215 || q(newBuffer) > 2147483648) return false;- i = new a(newBuffer);- j = new b(newBuffer);- k = new c(newBuffer);- l = new d(newBuffer);- m = new e(newBuffer);- n = new f(newBuffer);- o = new g(newBuffer);- p = new h(newBuffer);- buffer = newBuffer;- return true;- }- return {- _emscripten_replace_memory: replaceBuffer- };-})---;
− binaryen/test/memorygrowth.asm.js
@@ -1,2387 +0,0 @@-Module["asm"] = (function(global,env,buffer) {-- "almost asm";- var a = global.Int8Array;- var b = global.Int16Array;- var c = global.Int32Array;- var d = global.Uint8Array;- var e = global.Uint16Array;- var f = global.Uint32Array;- var g = global.Float32Array;- var h = global.Float64Array;- var i = new a(buffer);- var j = new b(buffer);- var k = new c(buffer);- var l = new d(buffer);- var m = new e(buffer);- var n = new f(buffer);- var o = new g(buffer);- var p = new h(buffer);- var q = global.byteLength;- var r = env.STACKTOP | 0;- var s = env.STACK_MAX | 0;- var t = env.tempDoublePtr | 0;- var u = env.ABORT | 0;- var v = 0;- var w = 0;- var x = 0;- var y = 0;- var z = global.NaN, A = global.Infinity;- var B = 0, C = 0, D = 0, E = 0, F = 0.0, G = 0, H = 0, I = 0, J = 0.0;- var K = 0;- var L = 0;- var M = 0;- var N = 0;- var O = 0;- var P = 0;- var Q = 0;- var R = 0;- var S = 0;- var T = 0;- var U = global.Math.floor;- var V = global.Math.abs;- var W = global.Math.sqrt;- var X = global.Math.pow;- var Y = global.Math.cos;- var Z = global.Math.sin;- var _ = global.Math.tan;- var $ = global.Math.acos;- var aa = global.Math.asin;- var ba = global.Math.atan;- var ca = global.Math.atan2;- var da = global.Math.exp;- var ea = global.Math.log;- var fa = global.Math.ceil;- var ga = global.Math.imul;- var ha = global.Math.min;- var ia = global.Math.clz32;- var ja = env.abort;- var ka = env.assert;- var la = env.invoke_ii;- var ma = env.invoke_iiii;- var na = env.invoke_vi;- var oa = env._pthread_cleanup_pop;- var pa = env.___lock;- var qa = env._abort;- var ra = env._pthread_cleanup_push;- var sa = env.___syscall6;- var ta = env._sbrk;- var ua = env.___syscall140;- var va = env._emscripten_memcpy_big;- var wa = env.___syscall54;- var xa = env.___unlock;- var ya = env.___syscall146;- var za = 0.0;- function Aa(newBuffer) {- if (q(newBuffer) & 16777215 || q(newBuffer) <= 16777215 || q(newBuffer) > 2147483648) return false;- i = new a(newBuffer);- j = new b(newBuffer);- k = new c(newBuffer);- l = new d(newBuffer);- m = new e(newBuffer);- n = new f(newBuffer);- o = new g(newBuffer);- p = new h(newBuffer);- buffer = newBuffer;- return true;- }- -// EMSCRIPTEN_START_FUNCS--function eb(a) {- a = a | 0;- var b = 0, c = 0, d = 0, e = 0, f = 0, g = 0, h = 0, i = 0, j = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0, s = 0, t = 0, u = 0, v = 0, w = 0, x = 0, y = 0, z = 0, A = 0, B = 0, C = 0, D = 0, E = 0, F = 0, G = 0, H = 0, I = 0, J = 0, K = 0, L = 0, M = 0, N = 0, O = 0, P = 0, Q = 0, R = 0, S = 0, T = 0, U = 0, V = 0, W = 0, X = 0, Y = 0, Z = 0, _ = 0, $ = 0, aa = 0, ba = 0, ca = 0, da = 0, ea = 0, fa = 0, ga = 0, ha = 0, ia = 0, ja = 0, ka = 0, la = 0, ma = 0, na = 0, oa = 0, pa = 0, ra = 0, sa = 0, ua = 0, va = 0, wa = 0, xa = 0, ya = 0, za = 0, Aa = 0, Ba = 0, Ca = 0, Da = 0, Ea = 0, Fa = 0, Ga = 0, Ha = 0, Ia = 0, Ja = 0, Ka = 0, La = 0, Ma = 0, Na = 0, Oa = 0, Pa = 0, Ra = 0, Sa = 0;- b = r;- r = r + 16 | 0;- c = b;- do if (a >>> 0 < 245) {- d = a >>> 0 < 11 ? 16 : a + 11 & -8;- e = d >>> 3;- f = k[302] | 0;- g = f >>> e;- if (g & 3 | 0) {- h = (g & 1 ^ 1) + e | 0;- i = 1248 + (h << 1 << 2) | 0;- j = i + 8 | 0;- l = k[j >> 2] | 0;- m = l + 8 | 0;- n = k[m >> 2] | 0;- do if ((i | 0) == (n | 0)) k[302] = f & ~(1 << h); else {- if (n >>> 0 < (k[306] | 0) >>> 0) qa();- o = n + 12 | 0;- if ((k[o >> 2] | 0) == (l | 0)) {- k[o >> 2] = i;- k[j >> 2] = n;- break;- } else qa();- } while (0);- n = h << 3;- k[l + 4 >> 2] = n | 3;- j = l + n + 4 | 0;- k[j >> 2] = k[j >> 2] | 1;- p = m;- r = b;- return p | 0;- }- j = k[304] | 0;- if (d >>> 0 > j >>> 0) {- if (g | 0) {- n = 2 << e;- i = g << e & (n | 0 - n);- n = (i & 0 - i) + -1 | 0;- i = n >>> 12 & 16;- o = n >>> i;- n = o >>> 5 & 8;- q = o >>> n;- o = q >>> 2 & 4;- s = q >>> o;- q = s >>> 1 & 2;- t = s >>> q;- s = t >>> 1 & 1;- u = (n | i | o | q | s) + (t >>> s) | 0;- s = 1248 + (u << 1 << 2) | 0;- t = s + 8 | 0;- q = k[t >> 2] | 0;- o = q + 8 | 0;- i = k[o >> 2] | 0;- do if ((s | 0) == (i | 0)) {- k[302] = f & ~(1 << u);- v = j;- } else {- if (i >>> 0 < (k[306] | 0) >>> 0) qa();- n = i + 12 | 0;- if ((k[n >> 2] | 0) == (q | 0)) {- k[n >> 2] = s;- k[t >> 2] = i;- v = k[304] | 0;- break;- } else qa();- } while (0);- i = (u << 3) - d | 0;- k[q + 4 >> 2] = d | 3;- t = q + d | 0;- k[t + 4 >> 2] = i | 1;- k[t + i >> 2] = i;- if (v | 0) {- s = k[307] | 0;- j = v >>> 3;- f = 1248 + (j << 1 << 2) | 0;- e = k[302] | 0;- g = 1 << j;- if (!(e & g)) {- k[302] = e | g;- w = f + 8 | 0;- x = f;- } else {- g = f + 8 | 0;- e = k[g >> 2] | 0;- if (e >>> 0 < (k[306] | 0) >>> 0) qa(); else {- w = g;- x = e;- }- }- k[w >> 2] = s;- k[x + 12 >> 2] = s;- k[s + 8 >> 2] = x;- k[s + 12 >> 2] = f;- }- k[304] = i;- k[307] = t;- p = o;- r = b;- return p | 0;- }- t = k[303] | 0;- if (!t) y = d; else {- i = (t & 0 - t) + -1 | 0;- t = i >>> 12 & 16;- f = i >>> t;- i = f >>> 5 & 8;- s = f >>> i;- f = s >>> 2 & 4;- e = s >>> f;- s = e >>> 1 & 2;- g = e >>> s;- e = g >>> 1 & 1;- j = k[1512 + ((i | t | f | s | e) + (g >>> e) << 2) >> 2] | 0;- e = (k[j + 4 >> 2] & -8) - d | 0;- g = j;- s = j;- while (1) {- j = k[g + 16 >> 2] | 0;- if (!j) {- f = k[g + 20 >> 2] | 0;- if (!f) {- z = e;- A = s;- break;- } else B = f;- } else B = j;- j = (k[B + 4 >> 2] & -8) - d | 0;- f = j >>> 0 < e >>> 0;- e = f ? j : e;- g = B;- s = f ? B : s;- }- s = k[306] | 0;- if (A >>> 0 < s >>> 0) qa();- g = A + d | 0;- if (A >>> 0 >= g >>> 0) qa();- e = k[A + 24 >> 2] | 0;- o = k[A + 12 >> 2] | 0;- do if ((o | 0) == (A | 0)) {- q = A + 20 | 0;- u = k[q >> 2] | 0;- if (!u) {- f = A + 16 | 0;- j = k[f >> 2] | 0;- if (!j) {- C = 0;- break;- } else {- D = j;- E = f;- }- } else {- D = u;- E = q;- }- while (1) {- q = D + 20 | 0;- u = k[q >> 2] | 0;- if (u | 0) {- D = u;- E = q;- continue;- }- q = D + 16 | 0;- u = k[q >> 2] | 0;- if (!u) {- F = D;- G = E;- break;- } else {- D = u;- E = q;- }- }- if (G >>> 0 < s >>> 0) qa(); else {- k[G >> 2] = 0;- C = F;- break;- }- } else {- q = k[A + 8 >> 2] | 0;- if (q >>> 0 < s >>> 0) qa();- u = q + 12 | 0;- if ((k[u >> 2] | 0) != (A | 0)) qa();- f = o + 8 | 0;- if ((k[f >> 2] | 0) == (A | 0)) {- k[u >> 2] = o;- k[f >> 2] = q;- C = o;- break;- } else qa();- } while (0);- do if (e | 0) {- o = k[A + 28 >> 2] | 0;- s = 1512 + (o << 2) | 0;- if ((A | 0) == (k[s >> 2] | 0)) {- k[s >> 2] = C;- if (!C) {- k[303] = k[303] & ~(1 << o);- break;- }- } else {- if (e >>> 0 < (k[306] | 0) >>> 0) qa();- o = e + 16 | 0;- if ((k[o >> 2] | 0) == (A | 0)) k[o >> 2] = C; else k[e + 20 >> 2] = C;- if (!C) break;- }- o = k[306] | 0;- if (C >>> 0 < o >>> 0) qa();- k[C + 24 >> 2] = e;- s = k[A + 16 >> 2] | 0;- do if (s | 0) if (s >>> 0 < o >>> 0) qa(); else {- k[C + 16 >> 2] = s;- k[s + 24 >> 2] = C;- break;- } while (0);- s = k[A + 20 >> 2] | 0;- if (s | 0) if (s >>> 0 < (k[306] | 0) >>> 0) qa(); else {- k[C + 20 >> 2] = s;- k[s + 24 >> 2] = C;- break;- }- } while (0);- if (z >>> 0 < 16) {- e = z + d | 0;- k[A + 4 >> 2] = e | 3;- s = A + e + 4 | 0;- k[s >> 2] = k[s >> 2] | 1;- } else {- k[A + 4 >> 2] = d | 3;- k[g + 4 >> 2] = z | 1;- k[g + z >> 2] = z;- s = k[304] | 0;- if (s | 0) {- e = k[307] | 0;- o = s >>> 3;- s = 1248 + (o << 1 << 2) | 0;- q = k[302] | 0;- f = 1 << o;- if (!(q & f)) {- k[302] = q | f;- H = s + 8 | 0;- I = s;- } else {- f = s + 8 | 0;- q = k[f >> 2] | 0;- if (q >>> 0 < (k[306] | 0) >>> 0) qa(); else {- H = f;- I = q;- }- }- k[H >> 2] = e;- k[I + 12 >> 2] = e;- k[e + 8 >> 2] = I;- k[e + 12 >> 2] = s;- }- k[304] = z;- k[307] = g;- }- p = A + 8 | 0;- r = b;- return p | 0;- }- } else y = d;- } else if (a >>> 0 > 4294967231) y = -1; else {- s = a + 11 | 0;- e = s & -8;- q = k[303] | 0;- if (!q) y = e; else {- f = 0 - e | 0;- o = s >>> 8;- if (!o) J = 0; else if (e >>> 0 > 16777215) J = 31; else {- s = (o + 1048320 | 0) >>> 16 & 8;- u = o << s;- o = (u + 520192 | 0) >>> 16 & 4;- j = u << o;- u = (j + 245760 | 0) >>> 16 & 2;- t = 14 - (o | s | u) + (j << u >>> 15) | 0;- J = e >>> (t + 7 | 0) & 1 | t << 1;- }- t = k[1512 + (J << 2) >> 2] | 0;- a : do if (!t) {- K = f;- L = 0;- M = 0;- N = 86;- } else {- u = f;- j = 0;- s = e << ((J | 0) == 31 ? 0 : 25 - (J >>> 1) | 0);- o = t;- i = 0;- while (1) {- m = k[o + 4 >> 2] & -8;- l = m - e | 0;- if (l >>> 0 < u >>> 0) if ((m | 0) == (e | 0)) {- O = l;- P = o;- Q = o;- N = 90;- break a;- } else {- R = l;- S = o;- } else {- R = u;- S = i;- }- l = k[o + 20 >> 2] | 0;- o = k[o + 16 + (s >>> 31 << 2) >> 2] | 0;- m = (l | 0) == 0 | (l | 0) == (o | 0) ? j : l;- l = (o | 0) == 0;- if (l) {- K = R;- L = m;- M = S;- N = 86;- break;- } else {- u = R;- j = m;- s = s << (l & 1 ^ 1);- i = S;- }- }- } while (0);- if ((N | 0) == 86) {- if ((L | 0) == 0 & (M | 0) == 0) {- t = 2 << J;- f = q & (t | 0 - t);- if (!f) {- y = e;- break;- }- t = (f & 0 - f) + -1 | 0;- f = t >>> 12 & 16;- d = t >>> f;- t = d >>> 5 & 8;- g = d >>> t;- d = g >>> 2 & 4;- i = g >>> d;- g = i >>> 1 & 2;- s = i >>> g;- i = s >>> 1 & 1;- T = k[1512 + ((t | f | d | g | i) + (s >>> i) << 2) >> 2] | 0;- } else T = L;- if (!T) {- U = K;- V = M;- } else {- O = K;- P = T;- Q = M;- N = 90;- }- }- if ((N | 0) == 90) while (1) {- N = 0;- i = (k[P + 4 >> 2] & -8) - e | 0;- s = i >>> 0 < O >>> 0;- g = s ? i : O;- i = s ? P : Q;- s = k[P + 16 >> 2] | 0;- if (s | 0) {- O = g;- P = s;- Q = i;- N = 90;- continue;- }- P = k[P + 20 >> 2] | 0;- if (!P) {- U = g;- V = i;- break;- } else {- O = g;- Q = i;- N = 90;- }- }- if (!V) y = e; else if (U >>> 0 < ((k[304] | 0) - e | 0) >>> 0) {- q = k[306] | 0;- if (V >>> 0 < q >>> 0) qa();- i = V + e | 0;- if (V >>> 0 >= i >>> 0) qa();- g = k[V + 24 >> 2] | 0;- s = k[V + 12 >> 2] | 0;- do if ((s | 0) == (V | 0)) {- d = V + 20 | 0;- f = k[d >> 2] | 0;- if (!f) {- t = V + 16 | 0;- j = k[t >> 2] | 0;- if (!j) {- W = 0;- break;- } else {- X = j;- Y = t;- }- } else {- X = f;- Y = d;- }- while (1) {- d = X + 20 | 0;- f = k[d >> 2] | 0;- if (f | 0) {- X = f;- Y = d;- continue;- }- d = X + 16 | 0;- f = k[d >> 2] | 0;- if (!f) {- Z = X;- _ = Y;- break;- } else {- X = f;- Y = d;- }- }- if (_ >>> 0 < q >>> 0) qa(); else {- k[_ >> 2] = 0;- W = Z;- break;- }- } else {- d = k[V + 8 >> 2] | 0;- if (d >>> 0 < q >>> 0) qa();- f = d + 12 | 0;- if ((k[f >> 2] | 0) != (V | 0)) qa();- t = s + 8 | 0;- if ((k[t >> 2] | 0) == (V | 0)) {- k[f >> 2] = s;- k[t >> 2] = d;- W = s;- break;- } else qa();- } while (0);- do if (g | 0) {- s = k[V + 28 >> 2] | 0;- q = 1512 + (s << 2) | 0;- if ((V | 0) == (k[q >> 2] | 0)) {- k[q >> 2] = W;- if (!W) {- k[303] = k[303] & ~(1 << s);- break;- }- } else {- if (g >>> 0 < (k[306] | 0) >>> 0) qa();- s = g + 16 | 0;- if ((k[s >> 2] | 0) == (V | 0)) k[s >> 2] = W; else k[g + 20 >> 2] = W;- if (!W) break;- }- s = k[306] | 0;- if (W >>> 0 < s >>> 0) qa();- k[W + 24 >> 2] = g;- q = k[V + 16 >> 2] | 0;- do if (q | 0) if (q >>> 0 < s >>> 0) qa(); else {- k[W + 16 >> 2] = q;- k[q + 24 >> 2] = W;- break;- } while (0);- q = k[V + 20 >> 2] | 0;- if (q | 0) if (q >>> 0 < (k[306] | 0) >>> 0) qa(); else {- k[W + 20 >> 2] = q;- k[q + 24 >> 2] = W;- break;- }- } while (0);- do if (U >>> 0 < 16) {- g = U + e | 0;- k[V + 4 >> 2] = g | 3;- q = V + g + 4 | 0;- k[q >> 2] = k[q >> 2] | 1;- } else {- k[V + 4 >> 2] = e | 3;- k[i + 4 >> 2] = U | 1;- k[i + U >> 2] = U;- q = U >>> 3;- if (U >>> 0 < 256) {- g = 1248 + (q << 1 << 2) | 0;- s = k[302] | 0;- d = 1 << q;- if (!(s & d)) {- k[302] = s | d;- $ = g + 8 | 0;- aa = g;- } else {- d = g + 8 | 0;- s = k[d >> 2] | 0;- if (s >>> 0 < (k[306] | 0) >>> 0) qa(); else {- $ = d;- aa = s;- }- }- k[$ >> 2] = i;- k[aa + 12 >> 2] = i;- k[i + 8 >> 2] = aa;- k[i + 12 >> 2] = g;- break;- }- g = U >>> 8;- if (!g) ba = 0; else if (U >>> 0 > 16777215) ba = 31; else {- s = (g + 1048320 | 0) >>> 16 & 8;- d = g << s;- g = (d + 520192 | 0) >>> 16 & 4;- q = d << g;- d = (q + 245760 | 0) >>> 16 & 2;- t = 14 - (g | s | d) + (q << d >>> 15) | 0;- ba = U >>> (t + 7 | 0) & 1 | t << 1;- }- t = 1512 + (ba << 2) | 0;- k[i + 28 >> 2] = ba;- d = i + 16 | 0;- k[d + 4 >> 2] = 0;- k[d >> 2] = 0;- d = k[303] | 0;- q = 1 << ba;- if (!(d & q)) {- k[303] = d | q;- k[t >> 2] = i;- k[i + 24 >> 2] = t;- k[i + 12 >> 2] = i;- k[i + 8 >> 2] = i;- break;- }- q = U << ((ba | 0) == 31 ? 0 : 25 - (ba >>> 1) | 0);- d = k[t >> 2] | 0;- while (1) {- if ((k[d + 4 >> 2] & -8 | 0) == (U | 0)) {- ca = d;- N = 148;- break;- }- t = d + 16 + (q >>> 31 << 2) | 0;- s = k[t >> 2] | 0;- if (!s) {- da = t;- ea = d;- N = 145;- break;- } else {- q = q << 1;- d = s;- }- }- if ((N | 0) == 145) if (da >>> 0 < (k[306] | 0) >>> 0) qa(); else {- k[da >> 2] = i;- k[i + 24 >> 2] = ea;- k[i + 12 >> 2] = i;- k[i + 8 >> 2] = i;- break;- } else if ((N | 0) == 148) {- d = ca + 8 | 0;- q = k[d >> 2] | 0;- s = k[306] | 0;- if (q >>> 0 >= s >>> 0 & ca >>> 0 >= s >>> 0) {- k[q + 12 >> 2] = i;- k[d >> 2] = i;- k[i + 8 >> 2] = q;- k[i + 12 >> 2] = ca;- k[i + 24 >> 2] = 0;- break;- } else qa();- }- } while (0);- p = V + 8 | 0;- r = b;- return p | 0;- } else y = e;- }- } while (0);- V = k[304] | 0;- if (V >>> 0 >= y >>> 0) {- ca = V - y | 0;- ea = k[307] | 0;- if (ca >>> 0 > 15) {- da = ea + y | 0;- k[307] = da;- k[304] = ca;- k[da + 4 >> 2] = ca | 1;- k[da + ca >> 2] = ca;- k[ea + 4 >> 2] = y | 3;- } else {- k[304] = 0;- k[307] = 0;- k[ea + 4 >> 2] = V | 3;- ca = ea + V + 4 | 0;- k[ca >> 2] = k[ca >> 2] | 1;- }- p = ea + 8 | 0;- r = b;- return p | 0;- }- ea = k[305] | 0;- if (ea >>> 0 > y >>> 0) {- ca = ea - y | 0;- k[305] = ca;- ea = k[308] | 0;- V = ea + y | 0;- k[308] = V;- k[V + 4 >> 2] = ca | 1;- k[ea + 4 >> 2] = y | 3;- p = ea + 8 | 0;- r = b;- return p | 0;- }- if (!(k[420] | 0)) {- k[422] = 4096;- k[421] = 4096;- k[423] = -1;- k[424] = -1;- k[425] = 0;- k[413] = 0;- ea = c & -16 ^ 1431655768;- k[c >> 2] = ea;- k[420] = ea;- }- ea = y + 48 | 0;- c = k[422] | 0;- ca = y + 47 | 0;- V = c + ca | 0;- da = 0 - c | 0;- c = V & da;- if (c >>> 0 <= y >>> 0) {- p = 0;- r = b;- return p | 0;- }- U = k[412] | 0;- if (U | 0) {- ba = k[410] | 0;- aa = ba + c | 0;- if (aa >>> 0 <= ba >>> 0 | aa >>> 0 > U >>> 0) {- p = 0;- r = b;- return p | 0;- }- }- b : do if (!(k[413] & 4)) {- U = k[308] | 0;- c : do if (!U) N = 171; else {- aa = 1656;- while (1) {- ba = k[aa >> 2] | 0;- if (ba >>> 0 <= U >>> 0) {- $ = aa + 4 | 0;- if ((ba + (k[$ >> 2] | 0) | 0) >>> 0 > U >>> 0) {- fa = aa;- ga = $;- break;- }- }- aa = k[aa + 8 >> 2] | 0;- if (!aa) {- N = 171;- break c;- }- }- aa = V - (k[305] | 0) & da;- if (aa >>> 0 < 2147483647) {- $ = ta(aa | 0) | 0;- if (($ | 0) == ((k[fa >> 2] | 0) + (k[ga >> 2] | 0) | 0)) {- if (($ | 0) != (-1 | 0)) {- ha = $;- ia = aa;- N = 191;- break b;- }- } else {- ja = $;- ka = aa;- N = 181;- }- }- } while (0);- do if ((N | 0) == 171) {- U = ta(0) | 0;- if ((U | 0) != (-1 | 0)) {- e = U;- aa = k[421] | 0;- $ = aa + -1 | 0;- if (!($ & e)) la = c; else la = c - e + ($ + e & 0 - aa) | 0;- aa = k[410] | 0;- e = aa + la | 0;- if (la >>> 0 > y >>> 0 & la >>> 0 < 2147483647) {- $ = k[412] | 0;- if ($ | 0) if (e >>> 0 <= aa >>> 0 | e >>> 0 > $ >>> 0) break;- $ = ta(la | 0) | 0;- if (($ | 0) == (U | 0)) {- ha = U;- ia = la;- N = 191;- break b;- } else {- ja = $;- ka = la;- N = 181;- }- }- }- } while (0);- d : do if ((N | 0) == 181) {- $ = 0 - ka | 0;- do if (ea >>> 0 > ka >>> 0 & (ka >>> 0 < 2147483647 & (ja | 0) != (-1 | 0))) {- U = k[422] | 0;- e = ca - ka + U & 0 - U;- if (e >>> 0 < 2147483647) if ((ta(e | 0) | 0) == (-1 | 0)) {- ta($ | 0) | 0;- break d;- } else {- ma = e + ka | 0;- break;- } else ma = ka;- } else ma = ka; while (0);- if ((ja | 0) != (-1 | 0)) {- ha = ja;- ia = ma;- N = 191;- break b;- }- } while (0);- k[413] = k[413] | 4;- N = 188;- } else N = 188; while (0);- if ((N | 0) == 188) if (c >>> 0 < 2147483647) {- ma = ta(c | 0) | 0;- c = ta(0) | 0;- if (ma >>> 0 < c >>> 0 & ((ma | 0) != (-1 | 0) & (c | 0) != (-1 | 0))) {- ja = c - ma | 0;- if (ja >>> 0 > (y + 40 | 0) >>> 0) {- ha = ma;- ia = ja;- N = 191;- }- }- }- if ((N | 0) == 191) {- ja = (k[410] | 0) + ia | 0;- k[410] = ja;- if (ja >>> 0 > (k[411] | 0) >>> 0) k[411] = ja;- ja = k[308] | 0;- do if (!ja) {- ma = k[306] | 0;- if ((ma | 0) == 0 | ha >>> 0 < ma >>> 0) k[306] = ha;- k[414] = ha;- k[415] = ia;- k[417] = 0;- k[311] = k[420];- k[310] = -1;- ma = 0;- do {- c = 1248 + (ma << 1 << 2) | 0;- k[c + 12 >> 2] = c;- k[c + 8 >> 2] = c;- ma = ma + 1 | 0;- } while ((ma | 0) != 32);- ma = ha + 8 | 0;- c = (ma & 7 | 0) == 0 ? 0 : 0 - ma & 7;- ma = ha + c | 0;- ka = ia + -40 - c | 0;- k[308] = ma;- k[305] = ka;- k[ma + 4 >> 2] = ka | 1;- k[ma + ka + 4 >> 2] = 40;- k[309] = k[424];- } else {- ka = 1656;- do {- ma = k[ka >> 2] | 0;- c = ka + 4 | 0;- ca = k[c >> 2] | 0;- if ((ha | 0) == (ma + ca | 0)) {- na = ma;- oa = c;- pa = ca;- ra = ka;- N = 201;- break;- }- ka = k[ka + 8 >> 2] | 0;- } while ((ka | 0) != 0);- if ((N | 0) == 201) if (!(k[ra + 12 >> 2] & 8)) if (ja >>> 0 < ha >>> 0 & ja >>> 0 >= na >>> 0) {- k[oa >> 2] = pa + ia;- ka = ja + 8 | 0;- ca = (ka & 7 | 0) == 0 ? 0 : 0 - ka & 7;- ka = ja + ca | 0;- c = ia - ca + (k[305] | 0) | 0;- k[308] = ka;- k[305] = c;- k[ka + 4 >> 2] = c | 1;- k[ka + c + 4 >> 2] = 40;- k[309] = k[424];- break;- }- c = k[306] | 0;- if (ha >>> 0 < c >>> 0) {- k[306] = ha;- sa = ha;- } else sa = c;- c = ha + ia | 0;- ka = 1656;- while (1) {- if ((k[ka >> 2] | 0) == (c | 0)) {- ua = ka;- va = ka;- N = 209;- break;- }- ka = k[ka + 8 >> 2] | 0;- if (!ka) {- wa = 1656;- break;- }- }- if ((N | 0) == 209) if (!(k[va + 12 >> 2] & 8)) {- k[ua >> 2] = ha;- ka = va + 4 | 0;- k[ka >> 2] = (k[ka >> 2] | 0) + ia;- ka = ha + 8 | 0;- ca = ha + ((ka & 7 | 0) == 0 ? 0 : 0 - ka & 7) | 0;- ka = c + 8 | 0;- ma = c + ((ka & 7 | 0) == 0 ? 0 : 0 - ka & 7) | 0;- ka = ca + y | 0;- ea = ma - ca - y | 0;- k[ca + 4 >> 2] = y | 3;- do if ((ma | 0) == (ja | 0)) {- la = (k[305] | 0) + ea | 0;- k[305] = la;- k[308] = ka;- k[ka + 4 >> 2] = la | 1;- } else {- if ((ma | 0) == (k[307] | 0)) {- la = (k[304] | 0) + ea | 0;- k[304] = la;- k[307] = ka;- k[ka + 4 >> 2] = la | 1;- k[ka + la >> 2] = la;- break;- }- la = k[ma + 4 >> 2] | 0;- if ((la & 3 | 0) == 1) {- ga = la & -8;- fa = la >>> 3;- e : do if (la >>> 0 < 256) {- da = k[ma + 8 >> 2] | 0;- V = k[ma + 12 >> 2] | 0;- $ = 1248 + (fa << 1 << 2) | 0;- do if ((da | 0) != ($ | 0)) {- if (da >>> 0 < sa >>> 0) qa();- if ((k[da + 12 >> 2] | 0) == (ma | 0)) break;- qa();- } while (0);- if ((V | 0) == (da | 0)) {- k[302] = k[302] & ~(1 << fa);- break;- }- do if ((V | 0) == ($ | 0)) xa = V + 8 | 0; else {- if (V >>> 0 < sa >>> 0) qa();- e = V + 8 | 0;- if ((k[e >> 2] | 0) == (ma | 0)) {- xa = e;- break;- }- qa();- } while (0);- k[da + 12 >> 2] = V;- k[xa >> 2] = da;- } else {- $ = k[ma + 24 >> 2] | 0;- e = k[ma + 12 >> 2] | 0;- do if ((e | 0) == (ma | 0)) {- U = ma + 16 | 0;- aa = U + 4 | 0;- ba = k[aa >> 2] | 0;- if (!ba) {- W = k[U >> 2] | 0;- if (!W) {- ya = 0;- break;- } else {- za = W;- Aa = U;- }- } else {- za = ba;- Aa = aa;- }- while (1) {- aa = za + 20 | 0;- ba = k[aa >> 2] | 0;- if (ba | 0) {- za = ba;- Aa = aa;- continue;- }- aa = za + 16 | 0;- ba = k[aa >> 2] | 0;- if (!ba) {- Ba = za;- Ca = Aa;- break;- } else {- za = ba;- Aa = aa;- }- }- if (Ca >>> 0 < sa >>> 0) qa(); else {- k[Ca >> 2] = 0;- ya = Ba;- break;- }- } else {- aa = k[ma + 8 >> 2] | 0;- if (aa >>> 0 < sa >>> 0) qa();- ba = aa + 12 | 0;- if ((k[ba >> 2] | 0) != (ma | 0)) qa();- U = e + 8 | 0;- if ((k[U >> 2] | 0) == (ma | 0)) {- k[ba >> 2] = e;- k[U >> 2] = aa;- ya = e;- break;- } else qa();- } while (0);- if (!$) break;- e = k[ma + 28 >> 2] | 0;- da = 1512 + (e << 2) | 0;- do if ((ma | 0) == (k[da >> 2] | 0)) {- k[da >> 2] = ya;- if (ya | 0) break;- k[303] = k[303] & ~(1 << e);- break e;- } else {- if ($ >>> 0 < (k[306] | 0) >>> 0) qa();- V = $ + 16 | 0;- if ((k[V >> 2] | 0) == (ma | 0)) k[V >> 2] = ya; else k[$ + 20 >> 2] = ya;- if (!ya) break e;- } while (0);- e = k[306] | 0;- if (ya >>> 0 < e >>> 0) qa();- k[ya + 24 >> 2] = $;- da = ma + 16 | 0;- V = k[da >> 2] | 0;- do if (V | 0) if (V >>> 0 < e >>> 0) qa(); else {- k[ya + 16 >> 2] = V;- k[V + 24 >> 2] = ya;- break;- } while (0);- V = k[da + 4 >> 2] | 0;- if (!V) break;- if (V >>> 0 < (k[306] | 0) >>> 0) qa(); else {- k[ya + 20 >> 2] = V;- k[V + 24 >> 2] = ya;- break;- }- } while (0);- Da = ma + ga | 0;- Ea = ga + ea | 0;- } else {- Da = ma;- Ea = ea;- }- fa = Da + 4 | 0;- k[fa >> 2] = k[fa >> 2] & -2;- k[ka + 4 >> 2] = Ea | 1;- k[ka + Ea >> 2] = Ea;- fa = Ea >>> 3;- if (Ea >>> 0 < 256) {- la = 1248 + (fa << 1 << 2) | 0;- V = k[302] | 0;- e = 1 << fa;- do if (!(V & e)) {- k[302] = V | e;- Fa = la + 8 | 0;- Ga = la;- } else {- fa = la + 8 | 0;- $ = k[fa >> 2] | 0;- if ($ >>> 0 >= (k[306] | 0) >>> 0) {- Fa = fa;- Ga = $;- break;- }- qa();- } while (0);- k[Fa >> 2] = ka;- k[Ga + 12 >> 2] = ka;- k[ka + 8 >> 2] = Ga;- k[ka + 12 >> 2] = la;- break;- }- e = Ea >>> 8;- do if (!e) Ha = 0; else {- if (Ea >>> 0 > 16777215) {- Ha = 31;- break;- }- V = (e + 1048320 | 0) >>> 16 & 8;- ga = e << V;- $ = (ga + 520192 | 0) >>> 16 & 4;- fa = ga << $;- ga = (fa + 245760 | 0) >>> 16 & 2;- aa = 14 - ($ | V | ga) + (fa << ga >>> 15) | 0;- Ha = Ea >>> (aa + 7 | 0) & 1 | aa << 1;- } while (0);- e = 1512 + (Ha << 2) | 0;- k[ka + 28 >> 2] = Ha;- la = ka + 16 | 0;- k[la + 4 >> 2] = 0;- k[la >> 2] = 0;- la = k[303] | 0;- aa = 1 << Ha;- if (!(la & aa)) {- k[303] = la | aa;- k[e >> 2] = ka;- k[ka + 24 >> 2] = e;- k[ka + 12 >> 2] = ka;- k[ka + 8 >> 2] = ka;- break;- }- aa = Ea << ((Ha | 0) == 31 ? 0 : 25 - (Ha >>> 1) | 0);- la = k[e >> 2] | 0;- while (1) {- if ((k[la + 4 >> 2] & -8 | 0) == (Ea | 0)) {- Ia = la;- N = 279;- break;- }- e = la + 16 + (aa >>> 31 << 2) | 0;- ga = k[e >> 2] | 0;- if (!ga) {- Ja = e;- Ka = la;- N = 276;- break;- } else {- aa = aa << 1;- la = ga;- }- }- if ((N | 0) == 276) if (Ja >>> 0 < (k[306] | 0) >>> 0) qa(); else {- k[Ja >> 2] = ka;- k[ka + 24 >> 2] = Ka;- k[ka + 12 >> 2] = ka;- k[ka + 8 >> 2] = ka;- break;- } else if ((N | 0) == 279) {- la = Ia + 8 | 0;- aa = k[la >> 2] | 0;- ga = k[306] | 0;- if (aa >>> 0 >= ga >>> 0 & Ia >>> 0 >= ga >>> 0) {- k[aa + 12 >> 2] = ka;- k[la >> 2] = ka;- k[ka + 8 >> 2] = aa;- k[ka + 12 >> 2] = Ia;- k[ka + 24 >> 2] = 0;- break;- } else qa();- }- } while (0);- p = ca + 8 | 0;- r = b;- return p | 0;- } else wa = 1656;- while (1) {- ka = k[wa >> 2] | 0;- if (ka >>> 0 <= ja >>> 0) {- ea = ka + (k[wa + 4 >> 2] | 0) | 0;- if (ea >>> 0 > ja >>> 0) {- La = ea;- break;- }- }- wa = k[wa + 8 >> 2] | 0;- }- ca = La + -47 | 0;- ea = ca + 8 | 0;- ka = ca + ((ea & 7 | 0) == 0 ? 0 : 0 - ea & 7) | 0;- ea = ja + 16 | 0;- ca = ka >>> 0 < ea >>> 0 ? ja : ka;- ka = ca + 8 | 0;- ma = ha + 8 | 0;- c = (ma & 7 | 0) == 0 ? 0 : 0 - ma & 7;- ma = ha + c | 0;- aa = ia + -40 - c | 0;- k[308] = ma;- k[305] = aa;- k[ma + 4 >> 2] = aa | 1;- k[ma + aa + 4 >> 2] = 40;- k[309] = k[424];- aa = ca + 4 | 0;- k[aa >> 2] = 27;- k[ka >> 2] = k[414];- k[ka + 4 >> 2] = k[415];- k[ka + 8 >> 2] = k[416];- k[ka + 12 >> 2] = k[417];- k[414] = ha;- k[415] = ia;- k[417] = 0;- k[416] = ka;- ka = ca + 24 | 0;- do {- ka = ka + 4 | 0;- k[ka >> 2] = 7;- } while ((ka + 4 | 0) >>> 0 < La >>> 0);- if ((ca | 0) != (ja | 0)) {- ka = ca - ja | 0;- k[aa >> 2] = k[aa >> 2] & -2;- k[ja + 4 >> 2] = ka | 1;- k[ca >> 2] = ka;- ma = ka >>> 3;- if (ka >>> 0 < 256) {- c = 1248 + (ma << 1 << 2) | 0;- la = k[302] | 0;- ga = 1 << ma;- if (!(la & ga)) {- k[302] = la | ga;- Ma = c + 8 | 0;- Na = c;- } else {- ga = c + 8 | 0;- la = k[ga >> 2] | 0;- if (la >>> 0 < (k[306] | 0) >>> 0) qa(); else {- Ma = ga;- Na = la;- }- }- k[Ma >> 2] = ja;- k[Na + 12 >> 2] = ja;- k[ja + 8 >> 2] = Na;- k[ja + 12 >> 2] = c;- break;- }- c = ka >>> 8;- if (!c) Oa = 0; else if (ka >>> 0 > 16777215) Oa = 31; else {- la = (c + 1048320 | 0) >>> 16 & 8;- ga = c << la;- c = (ga + 520192 | 0) >>> 16 & 4;- ma = ga << c;- ga = (ma + 245760 | 0) >>> 16 & 2;- e = 14 - (c | la | ga) + (ma << ga >>> 15) | 0;- Oa = ka >>> (e + 7 | 0) & 1 | e << 1;- }- e = 1512 + (Oa << 2) | 0;- k[ja + 28 >> 2] = Oa;- k[ja + 20 >> 2] = 0;- k[ea >> 2] = 0;- ga = k[303] | 0;- ma = 1 << Oa;- if (!(ga & ma)) {- k[303] = ga | ma;- k[e >> 2] = ja;- k[ja + 24 >> 2] = e;- k[ja + 12 >> 2] = ja;- k[ja + 8 >> 2] = ja;- break;- }- ma = ka << ((Oa | 0) == 31 ? 0 : 25 - (Oa >>> 1) | 0);- ga = k[e >> 2] | 0;- while (1) {- if ((k[ga + 4 >> 2] & -8 | 0) == (ka | 0)) {- Pa = ga;- N = 305;- break;- }- e = ga + 16 + (ma >>> 31 << 2) | 0;- la = k[e >> 2] | 0;- if (!la) {- Ra = e;- Sa = ga;- N = 302;- break;- } else {- ma = ma << 1;- ga = la;- }- }- if ((N | 0) == 302) if (Ra >>> 0 < (k[306] | 0) >>> 0) qa(); else {- k[Ra >> 2] = ja;- k[ja + 24 >> 2] = Sa;- k[ja + 12 >> 2] = ja;- k[ja + 8 >> 2] = ja;- break;- } else if ((N | 0) == 305) {- ga = Pa + 8 | 0;- ma = k[ga >> 2] | 0;- ka = k[306] | 0;- if (ma >>> 0 >= ka >>> 0 & Pa >>> 0 >= ka >>> 0) {- k[ma + 12 >> 2] = ja;- k[ga >> 2] = ja;- k[ja + 8 >> 2] = ma;- k[ja + 12 >> 2] = Pa;- k[ja + 24 >> 2] = 0;- break;- } else qa();- }- }- } while (0);- ja = k[305] | 0;- if (ja >>> 0 > y >>> 0) {- Pa = ja - y | 0;- k[305] = Pa;- ja = k[308] | 0;- N = ja + y | 0;- k[308] = N;- k[N + 4 >> 2] = Pa | 1;- k[ja + 4 >> 2] = y | 3;- p = ja + 8 | 0;- r = b;- return p | 0;- }- }- ja = Qa() | 0;- k[ja >> 2] = 12;- p = 0;- r = b;- return p | 0;-}--function fb(a) {- a = a | 0;- var b = 0, c = 0, d = 0, e = 0, f = 0, g = 0, h = 0, i = 0, j = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0, r = 0, s = 0, t = 0, u = 0, v = 0, w = 0, x = 0, y = 0, z = 0, A = 0, B = 0, C = 0, D = 0, E = 0, F = 0, G = 0, H = 0, I = 0, J = 0, K = 0, L = 0;- if (!a) return;- b = a + -8 | 0;- c = k[306] | 0;- if (b >>> 0 < c >>> 0) qa();- d = k[a + -4 >> 2] | 0;- a = d & 3;- if ((a | 0) == 1) qa();- e = d & -8;- f = b + e | 0;- do if (!(d & 1)) {- g = k[b >> 2] | 0;- if (!a) return;- h = b + (0 - g) | 0;- i = g + e | 0;- if (h >>> 0 < c >>> 0) qa();- if ((h | 0) == (k[307] | 0)) {- j = f + 4 | 0;- l = k[j >> 2] | 0;- if ((l & 3 | 0) != 3) {- m = h;- n = i;- break;- }- k[304] = i;- k[j >> 2] = l & -2;- k[h + 4 >> 2] = i | 1;- k[h + i >> 2] = i;- return;- }- l = g >>> 3;- if (g >>> 0 < 256) {- g = k[h + 8 >> 2] | 0;- j = k[h + 12 >> 2] | 0;- o = 1248 + (l << 1 << 2) | 0;- if ((g | 0) != (o | 0)) {- if (g >>> 0 < c >>> 0) qa();- if ((k[g + 12 >> 2] | 0) != (h | 0)) qa();- }- if ((j | 0) == (g | 0)) {- k[302] = k[302] & ~(1 << l);- m = h;- n = i;- break;- }- if ((j | 0) == (o | 0)) p = j + 8 | 0; else {- if (j >>> 0 < c >>> 0) qa();- o = j + 8 | 0;- if ((k[o >> 2] | 0) == (h | 0)) p = o; else qa();- }- k[g + 12 >> 2] = j;- k[p >> 2] = g;- m = h;- n = i;- break;- }- g = k[h + 24 >> 2] | 0;- j = k[h + 12 >> 2] | 0;- do if ((j | 0) == (h | 0)) {- o = h + 16 | 0;- l = o + 4 | 0;- q = k[l >> 2] | 0;- if (!q) {- r = k[o >> 2] | 0;- if (!r) {- s = 0;- break;- } else {- t = r;- u = o;- }- } else {- t = q;- u = l;- }- while (1) {- l = t + 20 | 0;- q = k[l >> 2] | 0;- if (q | 0) {- t = q;- u = l;- continue;- }- l = t + 16 | 0;- q = k[l >> 2] | 0;- if (!q) {- v = t;- w = u;- break;- } else {- t = q;- u = l;- }- }- if (w >>> 0 < c >>> 0) qa(); else {- k[w >> 2] = 0;- s = v;- break;- }- } else {- l = k[h + 8 >> 2] | 0;- if (l >>> 0 < c >>> 0) qa();- q = l + 12 | 0;- if ((k[q >> 2] | 0) != (h | 0)) qa();- o = j + 8 | 0;- if ((k[o >> 2] | 0) == (h | 0)) {- k[q >> 2] = j;- k[o >> 2] = l;- s = j;- break;- } else qa();- } while (0);- if (!g) {- m = h;- n = i;- } else {- j = k[h + 28 >> 2] | 0;- l = 1512 + (j << 2) | 0;- if ((h | 0) == (k[l >> 2] | 0)) {- k[l >> 2] = s;- if (!s) {- k[303] = k[303] & ~(1 << j);- m = h;- n = i;- break;- }- } else {- if (g >>> 0 < (k[306] | 0) >>> 0) qa();- j = g + 16 | 0;- if ((k[j >> 2] | 0) == (h | 0)) k[j >> 2] = s; else k[g + 20 >> 2] = s;- if (!s) {- m = h;- n = i;- break;- }- }- j = k[306] | 0;- if (s >>> 0 < j >>> 0) qa();- k[s + 24 >> 2] = g;- l = h + 16 | 0;- o = k[l >> 2] | 0;- do if (o | 0) if (o >>> 0 < j >>> 0) qa(); else {- k[s + 16 >> 2] = o;- k[o + 24 >> 2] = s;- break;- } while (0);- o = k[l + 4 >> 2] | 0;- if (!o) {- m = h;- n = i;- } else if (o >>> 0 < (k[306] | 0) >>> 0) qa(); else {- k[s + 20 >> 2] = o;- k[o + 24 >> 2] = s;- m = h;- n = i;- break;- }- }- } else {- m = b;- n = e;- } while (0);- if (m >>> 0 >= f >>> 0) qa();- e = f + 4 | 0;- b = k[e >> 2] | 0;- if (!(b & 1)) qa();- if (!(b & 2)) {- if ((f | 0) == (k[308] | 0)) {- s = (k[305] | 0) + n | 0;- k[305] = s;- k[308] = m;- k[m + 4 >> 2] = s | 1;- if ((m | 0) != (k[307] | 0)) return;- k[307] = 0;- k[304] = 0;- return;- }- if ((f | 0) == (k[307] | 0)) {- s = (k[304] | 0) + n | 0;- k[304] = s;- k[307] = m;- k[m + 4 >> 2] = s | 1;- k[m + s >> 2] = s;- return;- }- s = (b & -8) + n | 0;- c = b >>> 3;- do if (b >>> 0 < 256) {- v = k[f + 8 >> 2] | 0;- w = k[f + 12 >> 2] | 0;- u = 1248 + (c << 1 << 2) | 0;- if ((v | 0) != (u | 0)) {- if (v >>> 0 < (k[306] | 0) >>> 0) qa();- if ((k[v + 12 >> 2] | 0) != (f | 0)) qa();- }- if ((w | 0) == (v | 0)) {- k[302] = k[302] & ~(1 << c);- break;- }- if ((w | 0) == (u | 0)) x = w + 8 | 0; else {- if (w >>> 0 < (k[306] | 0) >>> 0) qa();- u = w + 8 | 0;- if ((k[u >> 2] | 0) == (f | 0)) x = u; else qa();- }- k[v + 12 >> 2] = w;- k[x >> 2] = v;- } else {- v = k[f + 24 >> 2] | 0;- w = k[f + 12 >> 2] | 0;- do if ((w | 0) == (f | 0)) {- u = f + 16 | 0;- t = u + 4 | 0;- p = k[t >> 2] | 0;- if (!p) {- a = k[u >> 2] | 0;- if (!a) {- y = 0;- break;- } else {- z = a;- A = u;- }- } else {- z = p;- A = t;- }- while (1) {- t = z + 20 | 0;- p = k[t >> 2] | 0;- if (p | 0) {- z = p;- A = t;- continue;- }- t = z + 16 | 0;- p = k[t >> 2] | 0;- if (!p) {- B = z;- C = A;- break;- } else {- z = p;- A = t;- }- }- if (C >>> 0 < (k[306] | 0) >>> 0) qa(); else {- k[C >> 2] = 0;- y = B;- break;- }- } else {- t = k[f + 8 >> 2] | 0;- if (t >>> 0 < (k[306] | 0) >>> 0) qa();- p = t + 12 | 0;- if ((k[p >> 2] | 0) != (f | 0)) qa();- u = w + 8 | 0;- if ((k[u >> 2] | 0) == (f | 0)) {- k[p >> 2] = w;- k[u >> 2] = t;- y = w;- break;- } else qa();- } while (0);- if (v | 0) {- w = k[f + 28 >> 2] | 0;- i = 1512 + (w << 2) | 0;- if ((f | 0) == (k[i >> 2] | 0)) {- k[i >> 2] = y;- if (!y) {- k[303] = k[303] & ~(1 << w);- break;- }- } else {- if (v >>> 0 < (k[306] | 0) >>> 0) qa();- w = v + 16 | 0;- if ((k[w >> 2] | 0) == (f | 0)) k[w >> 2] = y; else k[v + 20 >> 2] = y;- if (!y) break;- }- w = k[306] | 0;- if (y >>> 0 < w >>> 0) qa();- k[y + 24 >> 2] = v;- i = f + 16 | 0;- h = k[i >> 2] | 0;- do if (h | 0) if (h >>> 0 < w >>> 0) qa(); else {- k[y + 16 >> 2] = h;- k[h + 24 >> 2] = y;- break;- } while (0);- h = k[i + 4 >> 2] | 0;- if (h | 0) if (h >>> 0 < (k[306] | 0) >>> 0) qa(); else {- k[y + 20 >> 2] = h;- k[h + 24 >> 2] = y;- break;- }- }- } while (0);- k[m + 4 >> 2] = s | 1;- k[m + s >> 2] = s;- if ((m | 0) == (k[307] | 0)) {- k[304] = s;- return;- } else D = s;- } else {- k[e >> 2] = b & -2;- k[m + 4 >> 2] = n | 1;- k[m + n >> 2] = n;- D = n;- }- n = D >>> 3;- if (D >>> 0 < 256) {- b = 1248 + (n << 1 << 2) | 0;- e = k[302] | 0;- s = 1 << n;- if (!(e & s)) {- k[302] = e | s;- E = b + 8 | 0;- F = b;- } else {- s = b + 8 | 0;- e = k[s >> 2] | 0;- if (e >>> 0 < (k[306] | 0) >>> 0) qa(); else {- E = s;- F = e;- }- }- k[E >> 2] = m;- k[F + 12 >> 2] = m;- k[m + 8 >> 2] = F;- k[m + 12 >> 2] = b;- return;- }- b = D >>> 8;- if (!b) G = 0; else if (D >>> 0 > 16777215) G = 31; else {- F = (b + 1048320 | 0) >>> 16 & 8;- E = b << F;- b = (E + 520192 | 0) >>> 16 & 4;- e = E << b;- E = (e + 245760 | 0) >>> 16 & 2;- s = 14 - (b | F | E) + (e << E >>> 15) | 0;- G = D >>> (s + 7 | 0) & 1 | s << 1;- }- s = 1512 + (G << 2) | 0;- k[m + 28 >> 2] = G;- k[m + 20 >> 2] = 0;- k[m + 16 >> 2] = 0;- E = k[303] | 0;- e = 1 << G;- do if (!(E & e)) {- k[303] = E | e;- k[s >> 2] = m;- k[m + 24 >> 2] = s;- k[m + 12 >> 2] = m;- k[m + 8 >> 2] = m;- } else {- F = D << ((G | 0) == 31 ? 0 : 25 - (G >>> 1) | 0);- b = k[s >> 2] | 0;- while (1) {- if ((k[b + 4 >> 2] & -8 | 0) == (D | 0)) {- H = b;- I = 130;- break;- }- n = b + 16 + (F >>> 31 << 2) | 0;- y = k[n >> 2] | 0;- if (!y) {- J = n;- K = b;- I = 127;- break;- } else {- F = F << 1;- b = y;- }- }- if ((I | 0) == 127) if (J >>> 0 < (k[306] | 0) >>> 0) qa(); else {- k[J >> 2] = m;- k[m + 24 >> 2] = K;- k[m + 12 >> 2] = m;- k[m + 8 >> 2] = m;- break;- } else if ((I | 0) == 130) {- b = H + 8 | 0;- F = k[b >> 2] | 0;- i = k[306] | 0;- if (F >>> 0 >= i >>> 0 & H >>> 0 >= i >>> 0) {- k[F + 12 >> 2] = m;- k[b >> 2] = m;- k[m + 8 >> 2] = F;- k[m + 12 >> 2] = H;- k[m + 24 >> 2] = 0;- break;- } else qa();- }- } while (0);- m = (k[310] | 0) + -1 | 0;- k[310] = m;- if (!m) L = 1664; else return;- while (1) {- m = k[L >> 2] | 0;- if (!m) break; else L = m + 8 | 0;- }- k[310] = -1;- return;-}--function Ra(a, b, c) {- a = a | 0;- b = b | 0;- c = c | 0;- var d = 0, e = 0, f = 0, g = 0, h = 0, i = 0, j = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0, s = 0, t = 0, u = 0, v = 0, w = 0, x = 0, y = 0, z = 0;- d = r;- r = r + 48 | 0;- e = d + 16 | 0;- f = d;- g = d + 32 | 0;- h = a + 28 | 0;- i = k[h >> 2] | 0;- k[g >> 2] = i;- j = a + 20 | 0;- l = (k[j >> 2] | 0) - i | 0;- k[g + 4 >> 2] = l;- k[g + 8 >> 2] = b;- k[g + 12 >> 2] = c;- b = a + 60 | 0;- i = a + 44 | 0;- m = g;- g = 2;- n = l + c | 0;- while (1) {- if (!(k[290] | 0)) {- k[e >> 2] = k[b >> 2];- k[e + 4 >> 2] = m;- k[e + 8 >> 2] = g;- o = Pa(ya(146, e | 0) | 0) | 0;- } else {- ra(1, a | 0);- k[f >> 2] = k[b >> 2];- k[f + 4 >> 2] = m;- k[f + 8 >> 2] = g;- l = Pa(ya(146, f | 0) | 0) | 0;- oa(0);- o = l;- }- if ((n | 0) == (o | 0)) {- p = 6;- break;- }- if ((o | 0) < 0) {- q = m;- s = g;- p = 8;- break;- }- l = n - o | 0;- t = k[m + 4 >> 2] | 0;- if (o >>> 0 > t >>> 0) {- u = k[i >> 2] | 0;- k[h >> 2] = u;- k[j >> 2] = u;- v = k[m + 12 >> 2] | 0;- w = o - t | 0;- x = m + 8 | 0;- y = g + -1 | 0;- } else if ((g | 0) == 2) {- k[h >> 2] = (k[h >> 2] | 0) + o;- v = t;- w = o;- x = m;- y = 2;- } else {- v = t;- w = o;- x = m;- y = g;- }- k[x >> 2] = (k[x >> 2] | 0) + w;- k[x + 4 >> 2] = v - w;- m = x;- g = y;- n = l;- }- if ((p | 0) == 6) {- n = k[i >> 2] | 0;- k[a + 16 >> 2] = n + (k[a + 48 >> 2] | 0);- i = n;- k[h >> 2] = i;- k[j >> 2] = i;- z = c;- } else if ((p | 0) == 8) {- k[a + 16 >> 2] = 0;- k[h >> 2] = 0;- k[j >> 2] = 0;- k[a >> 2] = k[a >> 2] | 32;- if ((s | 0) == 2) z = 0; else z = c - (k[q + 4 >> 2] | 0) | 0;- }- r = d;- return z | 0;-}--function Wa(a, b, c) {- a = a | 0;- b = b | 0;- c = c | 0;- var d = 0, e = 0, f = 0, g = 0, h = 0, j = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0;- d = c + 16 | 0;- e = k[d >> 2] | 0;- if (!e) if (!(Xa(c) | 0)) {- f = k[d >> 2] | 0;- g = 5;- } else h = 0; else {- f = e;- g = 5;- }- a : do if ((g | 0) == 5) {- e = c + 20 | 0;- d = k[e >> 2] | 0;- j = d;- if ((f - d | 0) >>> 0 < b >>> 0) {- h = Ca[k[c + 36 >> 2] & 3](c, a, b) | 0;- break;- }- b : do if ((i[c + 75 >> 0] | 0) > -1) {- d = b;- while (1) {- if (!d) {- l = b;- m = a;- n = j;- o = 0;- break b;- }- p = d + -1 | 0;- if ((i[a + p >> 0] | 0) == 10) {- q = d;- break;- } else d = p;- }- if ((Ca[k[c + 36 >> 2] & 3](c, a, q) | 0) >>> 0 < q >>> 0) {- h = q;- break a;- }- l = b - q | 0;- m = a + q | 0;- n = k[e >> 2] | 0;- o = q;- } else {- l = b;- m = a;- n = j;- o = 0;- } while (0);- jb(n | 0, m | 0, l | 0) | 0;- k[e >> 2] = (k[e >> 2] | 0) + l;- h = o + l | 0;- } while (0);- return h | 0;-}--function Za(a) {- a = a | 0;- var b = 0, c = 0, d = 0, e = 0, f = 0, g = 0, h = 0, j = 0, l = 0, m = 0;- b = a;- a : do if (!(b & 3)) {- c = a;- d = 4;- } else {- e = a;- f = b;- while (1) {- if (!(i[e >> 0] | 0)) {- g = f;- break a;- }- h = e + 1 | 0;- f = h;- if (!(f & 3)) {- c = h;- d = 4;- break;- } else e = h;- }- } while (0);- if ((d | 0) == 4) {- d = c;- while (1) {- c = k[d >> 2] | 0;- if (!((c & -2139062144 ^ -2139062144) & c + -16843009)) d = d + 4 | 0; else {- j = c;- l = d;- break;- }- }- if (!((j & 255) << 24 >> 24)) m = l; else {- j = l;- while (1) {- l = j + 1 | 0;- if (!(i[l >> 0] | 0)) {- m = l;- break;- } else j = l;- }- }- g = m;- }- return g - b | 0;-}--function _a(a) {- a = a | 0;- var b = 0, c = 0, d = 0, e = 0, f = 0, g = 0, h = 0;- do if (!a) {- if (!(k[285] | 0)) b = 0; else b = _a(k[285] | 0) | 0;- pa(1188);- c = k[296] | 0;- if (!c) d = b; else {- e = c;- c = b;- while (1) {- if ((k[e + 76 >> 2] | 0) > -1) f = Ya(e) | 0; else f = 0;- if ((k[e + 20 >> 2] | 0) >>> 0 > (k[e + 28 >> 2] | 0) >>> 0) g = $a(e) | 0 | c; else g = c;- if (f | 0) Ta(e);- e = k[e + 56 >> 2] | 0;- if (!e) {- d = g;- break;- } else c = g;- }- }- xa(1188);- h = d;- } else {- if ((k[a + 76 >> 2] | 0) <= -1) {- h = $a(a) | 0;- break;- }- c = (Ya(a) | 0) == 0;- e = $a(a) | 0;- if (c) h = e; else {- Ta(a);- h = e;- }- } while (0);- return h | 0;-}--function ab(a, b) {- a = a | 0;- b = b | 0;- var c = 0, d = 0, e = 0, f = 0, g = 0, h = 0, j = 0, m = 0, n = 0;- c = r;- r = r + 16 | 0;- d = c;- e = b & 255;- i[d >> 0] = e;- f = a + 16 | 0;- g = k[f >> 2] | 0;- if (!g) if (!(Xa(a) | 0)) {- h = k[f >> 2] | 0;- j = 4;- } else m = -1; else {- h = g;- j = 4;- }- do if ((j | 0) == 4) {- g = a + 20 | 0;- f = k[g >> 2] | 0;- if (f >>> 0 < h >>> 0) {- n = b & 255;- if ((n | 0) != (i[a + 75 >> 0] | 0)) {- k[g >> 2] = f + 1;- i[f >> 0] = e;- m = n;- break;- }- }- if ((Ca[k[a + 36 >> 2] & 3](a, d, 1) | 0) == 1) m = l[d >> 0] | 0; else m = -1;- } while (0);- r = c;- return m | 0;-}--function $a(a) {- a = a | 0;- var b = 0, c = 0, d = 0, e = 0, f = 0, g = 0, h = 0;- b = a + 20 | 0;- c = a + 28 | 0;- if ((k[b >> 2] | 0) >>> 0 > (k[c >> 2] | 0) >>> 0) {- Ca[k[a + 36 >> 2] & 3](a, 0, 0) | 0;- if (!(k[b >> 2] | 0)) d = -1; else e = 3;- } else e = 3;- if ((e | 0) == 3) {- e = a + 4 | 0;- f = k[e >> 2] | 0;- g = a + 8 | 0;- h = k[g >> 2] | 0;- if (f >>> 0 < h >>> 0) Ca[k[a + 40 >> 2] & 3](a, f - h | 0, 1) | 0;- k[a + 16 >> 2] = 0;- k[c >> 2] = 0;- k[b >> 2] = 0;- k[g >> 2] = 0;- k[e >> 2] = 0;- d = 0;- }- return d | 0;-}--function jb(a, b, c) {- a = a | 0;- b = b | 0;- c = c | 0;- var d = 0;- if ((c | 0) >= 4096) return va(a | 0, b | 0, c | 0) | 0;- d = a | 0;- if ((a & 3) == (b & 3)) {- while (a & 3) {- if (!c) return d | 0;- i[a >> 0] = i[b >> 0] | 0;- a = a + 1 | 0;- b = b + 1 | 0;- c = c - 1 | 0;- }- while ((c | 0) >= 4) {- k[a >> 2] = k[b >> 2];- a = a + 4 | 0;- b = b + 4 | 0;- c = c - 4 | 0;- }- }- while ((c | 0) > 0) {- i[a >> 0] = i[b >> 0] | 0;- a = a + 1 | 0;- b = b + 1 | 0;- c = c - 1 | 0;- }- return d | 0;-}--function gb() {}-function hb(a, b, c) {- a = a | 0;- b = b | 0;- c = c | 0;- var d = 0, e = 0, f = 0, g = 0;- d = a + c | 0;- if ((c | 0) >= 20) {- b = b & 255;- e = a & 3;- f = b | b << 8 | b << 16 | b << 24;- g = d & ~3;- if (e) {- e = a + 4 - e | 0;- while ((a | 0) < (e | 0)) {- i[a >> 0] = b;- a = a + 1 | 0;- }- }- while ((a | 0) < (g | 0)) {- k[a >> 2] = f;- a = a + 4 | 0;- }- }- while ((a | 0) < (d | 0)) {- i[a >> 0] = b;- a = a + 1 | 0;- }- return a - c | 0;-}--function db(a) {- a = a | 0;- var b = 0, c = 0, d = 0, e = 0, f = 0;- b = k[256] | 0;- if ((k[b + 76 >> 2] | 0) > -1) c = Ya(b) | 0; else c = 0;- do if ((cb(a, b) | 0) < 0) d = 1; else {- if ((i[b + 75 >> 0] | 0) != 10) {- e = b + 20 | 0;- f = k[e >> 2] | 0;- if (f >>> 0 < (k[b + 16 >> 2] | 0) >>> 0) {- k[e >> 2] = f + 1;- i[f >> 0] = 10;- d = 0;- break;- }- }- d = (ab(b, 10) | 0) < 0;- } while (0);- if (c | 0) Ta(b);- return d << 31 >> 31 | 0;-}--function Xa(a) {- a = a | 0;- var b = 0, c = 0, d = 0;- b = a + 74 | 0;- c = i[b >> 0] | 0;- i[b >> 0] = c + 255 | c;- c = k[a >> 2] | 0;- if (!(c & 8)) {- k[a + 8 >> 2] = 0;- k[a + 4 >> 2] = 0;- b = k[a + 44 >> 2] | 0;- k[a + 28 >> 2] = b;- k[a + 20 >> 2] = b;- k[a + 16 >> 2] = b + (k[a + 48 >> 2] | 0);- d = 0;- } else {- k[a >> 2] = c | 32;- d = -1;- }- return d | 0;-}--function bb(a, b, c, d) {- a = a | 0;- b = b | 0;- c = c | 0;- d = d | 0;- var e = 0, f = 0, g = 0, h = 0, i = 0;- e = ga(c, b) | 0;- if ((k[d + 76 >> 2] | 0) > -1) {- f = (Ya(d) | 0) == 0;- g = Wa(a, e, d) | 0;- if (f) h = g; else {- Ta(d);- h = g;- }- } else h = Wa(a, e, d) | 0;- if ((h | 0) == (e | 0)) i = c; else i = (h >>> 0) / (b >>> 0) | 0;- return i | 0;-}--function Ua(a, b, c) {- a = a | 0;- b = b | 0;- c = c | 0;- var d = 0, e = 0, f = 0, g = 0;- d = r;- r = r + 32 | 0;- e = d;- f = d + 20 | 0;- k[e >> 2] = k[a + 60 >> 2];- k[e + 4 >> 2] = 0;- k[e + 8 >> 2] = b;- k[e + 12 >> 2] = f;- k[e + 16 >> 2] = c;- if ((Pa(ua(140, e | 0) | 0) | 0) < 0) {- k[f >> 2] = -1;- g = -1;- } else g = k[f >> 2] | 0;- r = d;- return g | 0;-}--function Va(a, b, c) {- a = a | 0;- b = b | 0;- c = c | 0;- var d = 0, e = 0;- d = r;- r = r + 80 | 0;- e = d;- k[a + 36 >> 2] = 3;- if (!(k[a >> 2] & 64)) {- k[e >> 2] = k[a + 60 >> 2];- k[e + 4 >> 2] = 21505;- k[e + 8 >> 2] = d + 12;- if (wa(54, e | 0) | 0) i[a + 75 >> 0] = -1;- }- e = Ra(a, b, c) | 0;- r = d;- return e | 0;-}--function Ka(a) {- a = a | 0;- i[t >> 0] = i[a >> 0];- i[t + 1 >> 0] = i[a + 1 >> 0];- i[t + 2 >> 0] = i[a + 2 >> 0];- i[t + 3 >> 0] = i[a + 3 >> 0];- i[t + 4 >> 0] = i[a + 4 >> 0];- i[t + 5 >> 0] = i[a + 5 >> 0];- i[t + 6 >> 0] = i[a + 6 >> 0];- i[t + 7 >> 0] = i[a + 7 >> 0];-}--function Oa(a) {- a = a | 0;- var b = 0, c = 0;- b = r;- r = r + 16 | 0;- c = b;- k[c >> 2] = k[a + 60 >> 2];- a = Pa(sa(6, c | 0) | 0) | 0;- r = b;- return a | 0;-}--function Pa(a) {- a = a | 0;- var b = 0, c = 0;- if (a >>> 0 > 4294963200) {- b = Qa() | 0;- k[b >> 2] = 0 - a;- c = -1;- } else c = a;- return c | 0;-}--function Ja(a) {- a = a | 0;- i[t >> 0] = i[a >> 0];- i[t + 1 >> 0] = i[a + 1 >> 0];- i[t + 2 >> 0] = i[a + 2 >> 0];- i[t + 3 >> 0] = i[a + 3 >> 0];-}--function Qa() {- var a = 0, b = 0;- if (!(k[290] | 0)) a = 1204; else {- b = (ib() | 0) + 64 | 0;- a = k[b >> 2] | 0;- }- return a | 0;-}--function lb(a, b, c, d) {- a = a | 0;- b = b | 0;- c = c | 0;- d = d | 0;- return Ca[a & 3](b | 0, c | 0, d | 0) | 0;-}-function Ea(a) {- a = a | 0;- var b = 0;- b = r;- r = r + a | 0;- r = r + 15 & -16;- return b | 0;-}--function cb(a, b) {- a = a | 0;- b = b | 0;- return (bb(a, Za(a) | 0, 1, b) | 0) + -1 | 0;-}--function ob(a, b, c) {- a = a | 0;- b = b | 0;- c = c | 0;- ja(1);- return 0;-}--function Ia(a, b) {- a = a | 0;- b = b | 0;- if (!v) {- v = a;- w = b;- }-}--function kb(a, b) {- a = a | 0;- b = b | 0;- return Ba[a & 1](b | 0) | 0;-}--function Sa(a) {- a = a | 0;- if (!(k[a + 68 >> 2] | 0)) Ta(a);- return;-}--function mb(a, b) {- a = a | 0;- b = b | 0;- Da[a & 1](b | 0);-}--function Ha(a, b) {- a = a | 0;- b = b | 0;- r = a;- s = b;-}--function nb(a) {- a = a | 0;- ja(0);- return 0;-}--function Na() {- db(1144) | 0;- return 0;-}--function Ya(a) {- a = a | 0;- return 0;-}--function Ta(a) {- a = a | 0;- return;-}--function pb(a) {- a = a | 0;- ja(2);-}--function La(a) {- a = a | 0;- K = a;-}--function Ga(a) {- a = a | 0;- r = a;-}--function Ma() {- return K | 0;-}--function Fa() {- return r | 0;-}--function ib() {- return 0;-}--// EMSCRIPTEN_END_FUNCS-- var Ba = [ nb, Oa ];- var Ca = [ ob, Va, Ua, Ra ];- var Da = [ pb, Sa ];- return {- _free: fb,- _main: Na,- _pthread_self: ib,- _memset: hb,- _malloc: eb,- _memcpy: jb,- _fflush: _a,- ___errno_location: Qa,- runPostSets: gb,- _emscripten_replace_memory: Aa,- stackAlloc: Ea,- stackSave: Fa,- stackRestore: Ga,- establishStackSpace: Ha,- setThrew: Ia,- setTempRet0: La,- getTempRet0: Ma,- dynCall_ii: kb,- dynCall_iiii: lb,- dynCall_vi: mb- };-})---;
binaryen/test/metadce/outside.wast view
@@ -1,8 +1,6 @@ (module (import "env" "js_func" (func $a_js_func)) (import "env" "js_func_unused" (func $an_unused_js_func))- (import "env" "DYNAMICTOP_PTR" (global $DYNAMICTOP_PTR$asm2wasm$import i32))- (import "env" "DYNAMICTOP_PTR_unused" (global $DYNAMICTOP_PTR$asm2wasm$import_unused i32)) (import "env" "memory" (memory $0 256 256)) (import "env" "table" (table 10 10 funcref)) @@ -21,11 +19,9 @@ (func $a_wasm_func (call $a_js_func)- (drop (global.get $DYNAMICTOP_PTR$asm2wasm$import)) (drop (global.get $__THREW__)) ) (func $an_unused_wasm_func- (drop (global.get $DYNAMICTOP_PTR$asm2wasm$import_unused)) (drop (global.get $__THREW__unused)) ) (func $table_func
binaryen/test/metadce/outside.wast.dced view
@@ -5,7 +5,6 @@ (data (global.get $from_segment) "abcd") (import "env" "table" (table $timport$0 10 10 funcref)) (elem (global.get $from_segment_2) $table_func)- (import "env" "DYNAMICTOP_PTR" (global $DYNAMICTOP_PTR$asm2wasm$import i32)) (import "env" "js_func" (func $a_js_func)) (global $__THREW__ (mut i32) (i32.const 0)) (global $from_segment (mut i32) (i32.const 0))@@ -16,9 +15,6 @@ ) (func $a_wasm_func (call $a_js_func)- (drop- (global.get $DYNAMICTOP_PTR$asm2wasm$import)- ) (drop (global.get $__THREW__) )
binaryen/test/metadce/outside.wast.dced.stdout view
@@ -1,4 +1,4 @@-unused: export$wasm_func_unused$12+unused: export$wasm_func_unused$10 unused: func$an_unused_wasm_func$1 unused: global$__THREW__unused$4 unused: global$from_segment$5
− binaryen/test/min.asm.js
@@ -1,52 +0,0 @@-function (global, env, buffer) {- "use asm";-- var c = new global.Int32Array(buffer);- var g = new global.Float32Array(buffer);-- var fr = global.Math.fround;-- var tDP = env.tempDoublePtr | 0;- var ctz32 = env._llvm_cttz_i32;-- var h8 = new global.Int8Array(buffer);- var h16 = new global.Int16Array(buffer);- var h32 = new global.Int32Array(buffer);- var hU8 = new global.Uint8Array(buffer);- var hU16 = new global.Uint16Array(buffer);- var hU32 = new global.Uint32Array(buffer);- var hF32 = new global.Float32Array(buffer);- var hF64 = new global.Float64Array(buffer);-- var M = 0; // tempRet-- function floats(f) {- f = fr(f);- var t = fr(0);- return fr(t + f);- }- function neg(k, p) {- k = k | 0;- p = p | 0;- var n = fr(0);- n = fr(-(c[k >> 2] = p, fr(g[k >> 2])));- return n;- }- function bitcasts(i, f) {- i = i | 0;- f = Math_fround(f);- (h32[tDP >> 2] = i, fr(hF32[tDP >> 2])); // i32->f32- (h32[tDP >> 2] = i, +hF32[tDP >> 2]); // i32->f32, no fround- (hF32[tDP >> 2] = f, h32[tDP >> 2] | 0); // f32->i32- }- function ctzzzz() {- return ctz32(0x1234) | 0;- }- function ub() {- ub(); // emterpreter assertions mode might add some code here- return M | 0;- }-- return { floats: floats, getTempRet0: ub, neg: neg, bitcasts: bitcasts, ctzzzz: ctzzzz };-}-
binaryen/test/min.wast.from-wast view
@@ -1,8 +1,8 @@ (module (type $i32_=>_i32 (func (param i32) (result i32))) (type $i32_i32_i32_=>_i32 (func (param i32 i32 i32) (result i32)))- (type $i32_i32_=>_f32 (func (param i32 i32) (result f32))) (type $f32_=>_f32 (func (param f32) (result f32)))+ (type $i32_i32_=>_f32 (func (param i32 i32) (result f32))) (memory $0 256 256) (export "floats" (func $floats)) (func $floats (param $f f32) (result f32)
binaryen/test/min.wast.fromBinary view
@@ -1,8 +1,8 @@ (module (type $i32_=>_i32 (func (param i32) (result i32))) (type $i32_i32_i32_=>_i32 (func (param i32 i32 i32) (result i32)))- (type $i32_i32_=>_f32 (func (param i32 i32) (result f32))) (type $f32_=>_f32 (func (param f32) (result f32)))+ (type $i32_i32_=>_f32 (func (param i32 i32) (result f32))) (memory $0 256 256) (export "floats" (func $floats)) (func $floats (param $f f32) (result f32)
binaryen/test/min.wast.fromBinary.noDebugInfo view
@@ -1,8 +1,8 @@ (module (type $i32_=>_i32 (func (param i32) (result i32))) (type $i32_i32_i32_=>_i32 (func (param i32 i32 i32) (result i32)))- (type $i32_i32_=>_f32 (func (param i32 i32) (result f32))) (type $f32_=>_f32 (func (param f32) (result f32)))+ (type $i32_i32_=>_f32 (func (param i32 i32) (result f32))) (memory $0 256 256) (export "floats" (func $0)) (func $0 (param $0 f32) (result f32)
binaryen/test/multivalue.wast.from-wast view
@@ -1,12 +1,12 @@ (module (type $none_=>_i32_i64 (func (result i32 i64))) (type $none_=>_none (func))- (type $none_=>_i32_i64_externref (func (result i32 i64 externref))) (type $none_=>_i64 (func (result i64)))+ (type $none_=>_i32_i64_externref (func (result i32 i64 externref))) (type $none_=>_f32_i64_i32 (func (result f32 i64 i32))) (type $none_=>_i32 (func (result i32)))- (type $none_=>_i32_i64_f32 (func (result i32 i64 f32))) (type $none_=>_f32 (func (result f32)))+ (type $none_=>_i32_i64_f32 (func (result i32 i64 f32))) (import "env" "pair" (func $pair (result i32 i64))) (global $g1 (mut (i32 i64)) (tuple.make (i32.const 0)
binaryen/test/multivalue.wast.fromBinary view
@@ -5,8 +5,8 @@ (type $none_=>_i64 (func (result i64))) (type $none_=>_f32_i64_i32 (func (result f32 i64 i32))) (type $none_=>_i32 (func (result i32)))- (type $none_=>_i32_i64_f32 (func (result i32 i64 f32))) (type $none_=>_f32 (func (result f32)))+ (type $none_=>_i32_i64_f32 (func (result i32 i64 f32))) (import "env" "pair" (func $pair (result i32 i64))) (global $g1 (mut i32) (i32.const 0)) (global $g2 (mut i64) (i64.const 0))
binaryen/test/multivalue.wast.fromBinary.noDebugInfo view
@@ -5,8 +5,8 @@ (type $none_=>_i64 (func (result i64))) (type $none_=>_f32_i64_i32 (func (result f32 i64 i32))) (type $none_=>_i32 (func (result i32)))- (type $none_=>_i32_i64_f32 (func (result i32 i64 f32))) (type $none_=>_f32 (func (result f32)))+ (type $none_=>_i32_i64_f32 (func (result i32 i64 f32))) (import "env" "pair" (func $fimport$0 (result i32 i64))) (global $global$0 (mut i32) (i32.const 0)) (global $global$1 (mut i64) (i64.const 0))
− binaryen/test/noffi_f32.asm.js
@@ -1,21 +0,0 @@-function(global, env, buffer) {- "use asm";- var Math_fround=global.Math.fround;- var importf=env._importf;-- function exportf(a){- a=Math_fround(a);- return Math_fround(a+Math_fround(1.0))- }- function main(){- Math_fround(importf(Math_fround(3.4000000953674316)));- return 0- }-- return{- main:main,- exportf:exportf}-}--;-
− binaryen/test/noffi_i64.asm.js
@@ -1,21 +0,0 @@-function(global, env, buffer) {- "use asm";- var importll=env._importll;-- function add(a,b) {- a = i64(a);- b = i64(b);- var c = i64();- c = i64_add(b,a);- return (i64(c));- }- function main() {- (i64(importll(i64_const(2,0))));- return 0;- }-- return {- _add: add,- _main: main };-}-;
binaryen/test/passes/O.bin.txt view
@@ -93,9 +93,9 @@ (br_if $label$3 (i64.gt_s (local.tee $0- (i64.add+ (i64.sub (local.get $0)- (i64.const -1)+ (i64.const 1) ) ) (i64.const 1)
binaryen/test/passes/O3_inlining.txt view
@@ -13,12 +13,8 @@ ) (if (i32.eqz- (if (result i32)- (i32.load16_u- (i32.const 3)- )- (i32.const 1)- (i32.const 0)+ (i32.load16_u+ (i32.const 3) ) ) (unreachable)
binaryen/test/passes/O3_low-memory-unused_metrics.txt view
@@ -799,14 +799,14 @@ ) ) (local.set $5- (i32.add+ (i32.sub (i32.shl (i32.load offset=48 (local.get $2) ) (i32.const 12) )- (i32.const -30720)+ (i32.const 30720) ) ) (local.set $3@@ -1142,9 +1142,9 @@ ) ) )- (i32.gt_u- (local.get $5)+ (i32.lt_u (local.get $3)+ (local.get $5) ) ) )@@ -1287,8 +1287,7 @@ ) ) (if- (i32.ge_u- (local.get $6)+ (i32.le_u (i32.load16_u offset=20 (local.tee $5 (i32.load offset=28@@ -1296,6 +1295,7 @@ ) ) )+ (local.get $6) ) (block (local.set $3@@ -1482,9 +1482,9 @@ ) ) )- (i32.gt_u- (local.get $5)+ (i32.lt_u (local.get $3)+ (local.get $5) ) ) )@@ -1795,9 +1795,9 @@ ) ) )- (i32.gt_u- (local.get $5)+ (i32.lt_u (local.get $3)+ (local.get $5) ) ) )@@ -2030,16 +2030,16 @@ (block (block $label$52 (br_if $label$52- (i32.le_u+ (i32.ge_u+ (i32.load offset=12+ (local.get $2)+ ) (i32.add (i32.load offset=20 (local.get $2) ) (i32.const 2) )- (i32.load offset=12- (local.get $2)- ) ) ) (br_if $label$52@@ -2060,9 +2060,9 @@ ) ) )- (i32.gt_u- (local.get $5)+ (i32.lt_u (local.get $3)+ (local.get $5) ) ) )@@ -2141,7 +2141,10 @@ ) ) (br_if $label$6- (i32.gt_u+ (i32.lt_u+ (i32.load offset=12+ (local.get $2)+ ) (i32.add (local.tee $3 (i32.load offset=20@@ -2150,9 +2153,6 @@ ) (i32.const 2) )- (i32.load offset=12- (local.get $2)- ) ) ) (local.set $4@@ -2344,9 +2344,9 @@ ) ) (br_if $label$53- (i32.lt_s- (local.get $7)+ (i32.gt_s (local.get $1)+ (local.get $7) ) ) (br_if $label$53@@ -2534,14 +2534,14 @@ ) ) (local.tee $4- (i32.add+ (i32.sub (i32.shl (i32.load offset=76 (local.get $2) ) (i32.const 1) )- (i32.const -2)+ (i32.const 2) ) ) )@@ -3024,9 +3024,9 @@ ) ) )- (i32.gt_u- (local.get $4)+ (i32.lt_u (local.get $1)+ (local.get $4) ) ) )
binaryen/test/passes/O4_disable-bulk-memory.txt view
@@ -14,8 +14,8 @@ (type $none_=>_f64 (func (result f64))) (type $i32_=>_f64 (func (param i32) (result f64))) (import "env" "memory" (memory $1 1))- (data (i32.const 8) "\0d\00\00\00~\00l\00i\00b\00/\00a\00r\00r\00a\00y\00.\00t\00s")- (data (i32.const 40) "\1c\00\00\00~\00l\00i\00b\00/\00i\00n\00t\00e\00r\00n\00a\00l\00/\00a\00r\00r\00a\00y\00b\00u\00f\00f\00e\00r\00.\00t\00s")+ (data (i32.const 8) "\0d\00\00\00~\00l\00i\00b\00/\00a\00r\00r\00a\00y\00.\00t\00s\00")+ (data (i32.const 40) "\1c\00\00\00~\00l\00i\00b\00/\00i\00n\00t\00e\00r\00n\00a\00l\00/\00a\00r\00r\00a\00y\00b\00u\00f\00f\00e\00r\00.\00t\00s\00") (table $0 1 funcref) (elem (i32.const 0) $null) (global $global$0 (mut i32) (i32.const 0))@@ -196,18 +196,15 @@ (f64.store offset=24 (local.tee $1 (if (result i32)- (i32.lt_u- (i32.const 0)- (i32.shr_u- (i32.load- (local.tee $1- (i32.load- (local.get $0)- )+ (i32.shr_u+ (i32.load+ (local.tee $1+ (i32.load+ (local.get $0) ) )- (i32.const 2) )+ (i32.const 2) ) (i32.load offset=8 (local.get $1)@@ -216,28 +213,22 @@ ) ) (f64.div- (f64.neg- (local.get $4)- )- (f64.const 39.47841760435743)+ (local.get $4)+ (f64.const -39.47841760435743) ) ) (f64.store offset=32 (local.get $1) (f64.div- (f64.neg- (local.get $5)- )- (f64.const 39.47841760435743)+ (local.get $5)+ (f64.const -39.47841760435743) ) ) (f64.store offset=40 (local.get $1) (f64.div- (f64.neg- (local.get $6)- )- (f64.const 39.47841760435743)+ (local.get $6)+ (f64.const -39.47841760435743) ) ) (i32.store@@ -1218,9 +1209,9 @@ (block $label$1 (loop $label$2 (br_if $label$1- (i32.ge_u- (local.get $1)+ (i32.le_u (local.get $0)+ (local.get $1) ) ) (call $assembly/index/NBodySystem#advance@@ -1239,8 +1230,7 @@ (func $assembly/index/getBody (; has Stack IR ;) (param $0 i32) (result i32) (local $1 i32) (if (result i32)- (i32.lt_u- (local.get $0)+ (i32.gt_u (i32.load offset=4 (local.tee $1 (i32.load@@ -1248,10 +1238,10 @@ ) ) )+ (local.get $0) ) (if (result i32)- (i32.lt_u- (local.get $0)+ (i32.gt_u (i32.shr_u (i32.load (local.tee $1@@ -1262,6 +1252,7 @@ ) (i32.const 2) )+ (local.get $0) ) (i32.load offset=8 (i32.add
+ binaryen/test/passes/O_all-features.txt view
@@ -0,0 +1,12 @@+(module+ (type ${i32} (struct (field i32)))+ (type $ref?|{i32}|_=>_none (func (param (ref null ${i32}))))+ (export "foo" (func $0))+ (func $0 (; has Stack IR ;) (param $0 (ref null ${i32}))+ (drop+ (struct.get ${i32} 0+ (local.get $0)+ )+ )+ )+)
+ binaryen/test/passes/O_all-features.wast view
@@ -0,0 +1,16 @@+;; Test that we can run GC types through the optimizer+(module+ (type $struct.A (struct i32))++ (func "foo" (param $x (ref null $struct.A))+ ;; get a struct reference+ (drop+ (local.get $x)+ )+ ;; get a struct field value+ ;; (note that since this is a nullable reference, it may trap)+ (drop+ (struct.get $struct.A 0 (local.get $x))+ )+ )+)
+ binaryen/test/passes/O_all-features_ignore-implicit-traps.txt view
@@ -0,0 +1,8 @@+(module+ (type ${i32} (struct (field i32)))+ (type $ref?|{i32}|_=>_none (func (param (ref null ${i32}))))+ (export "foo" (func $0))+ (func $0 (; has Stack IR ;) (param $0 (ref null ${i32}))+ (nop)+ )+)
+ binaryen/test/passes/O_all-features_ignore-implicit-traps.wast view
@@ -0,0 +1,17 @@+;; Test that we can run GC types through the optimizer+(module+ (type $struct.A (struct i32))++ (func "foo" (param $x (ref null $struct.A))+ ;; get a struct reference+ (drop+ (local.get $x)+ )+ ;; get a struct field value+ ;; (note that since this is a nullable reference, it may trap, but we+ ;; are ignoring implicit traps, so it has no side effects)+ (drop+ (struct.get $struct.A 0 (local.get $x))+ )+ )+)
binaryen/test/passes/O_fast-math.txt view
@@ -13,6 +13,8 @@ (export "sub2" (func $2)) (export "mul_neg_one1" (func $9)) (export "mul_neg_one2" (func $10))+ (export "abs_sub_zero1" (func $11))+ (export "abs_sub_zero2" (func $12)) (func $0 (; has Stack IR ;) (result f32) (f32.const -nan:0x23017a) )@@ -20,7 +22,7 @@ (f32.const -nan:0x34546d) ) (func $2 (; has Stack IR ;) (result f32)- (f32.const -nan:0x74546d)+ (f32.const nan:0x400000) ) (func $9 (; has Stack IR ;) (param $0 f32) (result f32) (f32.neg@@ -29,6 +31,16 @@ ) (func $10 (; has Stack IR ;) (param $0 f64) (result f64) (f64.neg+ (local.get $0)+ )+ )+ (func $11 (; has Stack IR ;) (param $0 f32) (result f32)+ (f32.abs+ (local.get $0)+ )+ )+ (func $12 (; has Stack IR ;) (param $0 f64) (result f64)+ (f64.abs (local.get $0) ) )
binaryen/test/passes/O_fast-math.wast view
@@ -66,4 +66,22 @@ (f64.const -1) ) )+ (func "abs_sub_zero1" (param $x f32) (result f32)+ ;; abs(0 - x) ==> abs(x)+ (f32.abs+ (f32.sub+ (f32.const 0)+ (local.get $x)+ )+ )+ )+ (func "abs_sub_zero2" (param $x f64) (result f64)+ ;; abs(0 - x) ==> abs(x)+ (f64.abs+ (f64.sub+ (f64.const 0)+ (local.get $x)+ )+ )+ ) )
binaryen/test/passes/Os_print-stack-ir_all-features.txt view
@@ -39,57 +39,3 @@ ) ) )-(module- (type $none_=>_i32 (func (result i32)))- (type $none_=>_i32_f64 (func (result i32 f64)))- (type $none_=>_i64 (func (result i64)))- (type $none_=>_f32 (func (result f32)))- (type $none_=>_f64 (func (result f64)))- (export "ppi32" (func $0))- (export "ppi64" (func $1))- (export "ppf32" (func $2))- (export "ppf64" (func $3))- (export "pair" (func $4))- (func $0 (result i32)- - )- (func $1 (result i64)- - )- (func $2 (result f32)- - )- (func $3 (result f64)- - )- (func $4 (result i32 f64)- - )-)-(module- (type $none_=>_i32 (func (result i32)))- (type $none_=>_i32_f64 (func (result i32 f64)))- (type $none_=>_i64 (func (result i64)))- (type $none_=>_f32 (func (result f32)))- (type $none_=>_f64 (func (result f64)))- (export "ppi32" (func $0))- (export "ppi64" (func $1))- (export "ppf32" (func $2))- (export "ppf64" (func $3))- (export "pair" (func $4))- (func $0 (; has Stack IR ;) (result i32)- (pop i32)- )- (func $1 (; has Stack IR ;) (result i64)- (pop i64)- )- (func $2 (; has Stack IR ;) (result f32)- (pop f32)- )- (func $3 (; has Stack IR ;) (result f64)- (pop f64)- )- (func $4 (; has Stack IR ;) (result i32 f64)- (pop i32 f64)- )-)
binaryen/test/passes/Os_print-stack-ir_all-features.wast view
@@ -14,23 +14,3 @@ ) ) )-(module- ;; These are not valid usages of pops - they are not meant to be- ;; used alone. This just tests we can emit them/handle them in the- ;; optimizer.- (func "ppi32" (result i32)- (pop i32)- )- (func "ppi64" (result i64)- (pop i64)- )- (func "ppf32" (result f32)- (pop f32)- )- (func "ppf64" (result f64)- (pop f64)- )- (func "pair" (result i32 f64)- (pop i32 f64)- )-)
+ binaryen/test/passes/Oz_fuzz-exec_all-features.txt view
@@ -0,0 +1,220 @@+[fuzz-exec] calling structs+[LoggingExternalInterface logging 0]+[LoggingExternalInterface logging 42]+[LoggingExternalInterface logging 100]+[LoggingExternalInterface logging 100]+[fuzz-exec] calling arrays+[LoggingExternalInterface logging 50]+[LoggingExternalInterface logging 42]+[LoggingExternalInterface logging 128]+[LoggingExternalInterface logging -128]+[LoggingExternalInterface logging 42]+[fuzz-exec] calling rtts+[LoggingExternalInterface logging 1]+[LoggingExternalInterface logging 0]+[LoggingExternalInterface logging 0]+[LoggingExternalInterface logging 1]+[LoggingExternalInterface logging 0]+[LoggingExternalInterface logging 1]+[LoggingExternalInterface logging 0]+[LoggingExternalInterface logging 1]+[fuzz-exec] calling br_on_cast+[LoggingExternalInterface logging 3]+[trap unreachable]+(module+ (type ${i32} (struct (field i32)))+ (type $none_=>_none (func))+ (type ${i32_f64} (struct (field i32) (field f64)))+ (type $[mut:i8] (array (mut i8)))+ (type $i32_=>_none (func (param i32)))+ (import "fuzzing-support" "log-i32" (func $log (param i32)))+ (export "structs" (func $0))+ (export "arrays" (func $1))+ (export "rtts" (func $2))+ (export "br_on_cast" (func $3))+ (func $0 (; has Stack IR ;)+ (local $0 (ref null ${i32}))+ (call $log+ (struct.get ${i32} 0+ (local.tee $0+ (struct.new_default_with_rtt ${i32}+ (rtt.canon ${i32})+ )+ )+ )+ )+ (struct.set ${i32} 0+ (local.get $0)+ (i32.const 42)+ )+ (call $log+ (struct.get ${i32} 0+ (local.get $0)+ )+ )+ (struct.set ${i32} 0+ (local.get $0)+ (i32.const 100)+ )+ (call $log+ (struct.get ${i32} 0+ (local.get $0)+ )+ )+ (call $log+ (struct.get ${i32} 0+ (local.get $0)+ )+ )+ )+ (func $1 (; has Stack IR ;)+ (local $0 (ref null $[mut:i8]))+ (call $log+ (array.len $[mut:i8]+ (local.tee $0+ (array.new_with_rtt $[mut:i8]+ (rtt.canon $[mut:i8])+ (i32.const 50)+ (i32.const 42)+ )+ )+ )+ )+ (call $log+ (array.get_u $[mut:i8]+ (local.get $0)+ (i32.const 10)+ )+ )+ (array.set $[mut:i8]+ (local.get $0)+ (i32.const 10)+ (i32.const 65408)+ )+ (call $log+ (array.get_u $[mut:i8]+ (local.get $0)+ (i32.const 10)+ )+ )+ (call $log+ (array.get_s $[mut:i8]+ (local.get $0)+ (i32.const 10)+ )+ )+ (call $log+ (array.get_s $[mut:i8]+ (local.get $0)+ (i32.const 20)+ )+ )+ )+ (func $2 (; has Stack IR ;)+ (local $0 (rtt ${i32}))+ (local $1 (rtt ${i32_f64}))+ (local $2 (rtt ${i32_f64}))+ (local $3 anyref)+ (local.set $1+ (rtt.sub ${i32_f64}+ (local.tee $0+ (rtt.canon ${i32})+ )+ )+ )+ (local.set $2+ (rtt.canon ${i32_f64})+ )+ (call $log+ (ref.is_null+ (ref.cast ${i32}+ (ref.null ${i32})+ (local.get $0)+ )+ )+ )+ (call $log+ (ref.test ${i32}+ (ref.null ${i32})+ (local.get $0)+ )+ )+ (call $log+ (ref.test ${i32}+ (array.new_with_rtt $[mut:i8]+ (rtt.canon $[mut:i8])+ (i32.const 10)+ (i32.const 20)+ )+ (local.get $0)+ )+ )+ (call $log+ (ref.test ${i32}+ (struct.new_default_with_rtt ${i32}+ (local.get $0)+ )+ (local.get $0)+ )+ )+ (call $log+ (ref.test ${i32_f64}+ (struct.new_default_with_rtt ${i32}+ (local.get $0)+ )+ (local.get $2)+ )+ )+ (call $log+ (ref.test ${i32_f64}+ (local.tee $3+ (struct.new_default_with_rtt ${i32_f64}+ (local.get $1)+ )+ )+ (local.get $1)+ )+ )+ (call $log+ (ref.test ${i32_f64}+ (local.get $3)+ (local.get $2)+ )+ )+ (call $log+ (ref.test ${i32}+ (local.get $3)+ (local.get $0)+ )+ )+ )+ (func $3 (; has Stack IR ;)+ (call $log+ (i32.const 3)+ )+ (unreachable)+ )+)+[fuzz-exec] calling structs+[LoggingExternalInterface logging 0]+[LoggingExternalInterface logging 42]+[LoggingExternalInterface logging 100]+[LoggingExternalInterface logging 100]+[fuzz-exec] calling arrays+[LoggingExternalInterface logging 50]+[LoggingExternalInterface logging 42]+[LoggingExternalInterface logging 128]+[LoggingExternalInterface logging -128]+[LoggingExternalInterface logging 42]+[fuzz-exec] calling rtts+[LoggingExternalInterface logging 1]+[LoggingExternalInterface logging 0]+[LoggingExternalInterface logging 0]+[LoggingExternalInterface logging 1]+[LoggingExternalInterface logging 0]+[LoggingExternalInterface logging 1]+[LoggingExternalInterface logging 0]+[LoggingExternalInterface logging 1]+[fuzz-exec] calling br_on_cast+[LoggingExternalInterface logging 3]+[trap unreachable]
+ binaryen/test/passes/Oz_fuzz-exec_all-features.wast view
@@ -0,0 +1,182 @@+(module+ (type $struct (struct i32))+ (type $extendedstruct (struct i32 f64))+ (type $bytes (array (mut i8)))+ (import "fuzzing-support" "log-i32" (func $log (param i32)))+ (func "structs"+ (local $x (ref null $struct))+ (local $y (ref null $struct))+ (local.set $x+ (struct.new_default_with_rtt $struct+ (rtt.canon $struct)+ )+ )+ ;; The value is initialized to 0+ ;; Note: -Oz will optimize all these to constants thanks to Precompute+ (call $log+ (struct.get $struct 0 (local.get $x))+ )+ ;; Assigning a value works+ (struct.set $struct 0+ (local.get $x)+ (i32.const 42)+ )+ (call $log+ (struct.get $struct 0 (local.get $x))+ )+ ;; References are references, so writing to one's value affects the other's+ (local.set $y (local.get $x))+ (struct.set $struct 0+ (local.get $y)+ (i32.const 100)+ )+ (call $log+ (struct.get $struct 0 (local.get $x))+ )+ (call $log+ (struct.get $struct 0 (local.get $y))+ )+ )+ (func "arrays"+ (local $x (ref null $bytes))+ (local.set $x+ (array.new_with_rtt $bytes+ (rtt.canon $bytes)+ (i32.const 50) ;; size+ (i32.const 42) ;; value to splat into the array+ )+ )+ ;; The length should be 50+ (call $log+ (array.len $bytes (local.get $x))+ )+ ;; The value should be 42+ (call $log+ (array.get_u $bytes (local.get $x) (i32.const 10))+ )+ ;; Write a value that will be truncated into an i8+ (array.set $bytes (local.get $x) (i32.const 10) (i32.const 0xff80))+ ;; The value should be 0x80 (-128 or 128 depending on signed/unsigned)+ (call $log+ (array.get_u $bytes (local.get $x) (i32.const 10))+ )+ (call $log+ (array.get_s $bytes (local.get $x) (i32.const 10))+ )+ ;; Other items than the one at index 10 are unaffected.+ (call $log+ (array.get_s $bytes (local.get $x) (i32.const 20))+ )+ )+ (func "rtts"+ (local $x (rtt $struct))+ (local $y (rtt $extendedstruct))+ (local $z (rtt $extendedstruct))+ (local $any anyref)+ (local.set $x (rtt.canon $struct))+ (local.set $y (rtt.sub $extendedstruct (local.get $x)))+ (local.set $z (rtt.canon $extendedstruct))+ ;; Casting null returns null.+ (call $log (ref.is_null+ (ref.cast $struct (ref.null $struct) (local.get $x))+ ))+ ;; Testing null returns 0.+ (call $log+ (ref.test $struct (ref.null $struct) (local.get $x))+ )+ ;; Testing something completely wrong (struct vs array) returns 0.+ (call $log+ (ref.test $struct+ (array.new_with_rtt $bytes+ (rtt.canon $bytes)+ (i32.const 10)+ (i32.const 20)+ )+ (local.get $x)+ )+ )+ ;; Testing a thing with the same RTT returns 1.+ (call $log+ (ref.test $struct+ (struct.new_default_with_rtt $struct+ (local.get $x)+ )+ (local.get $x)+ )+ )+ ;; A bad downcast returns 0: we create a struct, which is not a extendedstruct.+ (call $log+ (ref.test $extendedstruct+ (struct.new_default_with_rtt $struct+ (local.get $x)+ )+ (local.get $z)+ )+ )+ ;; Create a extendedstruct with RTT y, and upcast statically to anyref.+ (local.set $any+ (struct.new_default_with_rtt $extendedstruct+ (local.get $y)+ )+ )+ ;; Casting to y, the exact same RTT, works.+ (call $log+ (ref.test $extendedstruct+ (local.get $any)+ (local.get $y)+ )+ )+ ;; Casting to z, another RTT of the same data type, fails.+ (call $log+ (ref.test $extendedstruct+ (local.get $any)+ (local.get $z)+ )+ )+ ;; Casting to x, the parent of y, works.+ (call $log+ (ref.test $struct+ (local.get $any)+ (local.get $x)+ )+ )+ )+ (func "br_on_cast"+ (local $any anyref)+ ;; create a simple $struct, store it in an anyref+ (local.set $any+ (struct.new_default_with_rtt $struct (rtt.canon $struct))+ )+ (drop+ (block $block (result ($ref $struct))+ (drop+ (block $extendedblock (result (ref $extendedstruct))+ (drop+ ;; second, try to cast our simple $struct to what it is, which will work+ (br_on_cast $block $struct+ ;; first, try to cast our simple $struct to an extended, which will fail+ (br_on_cast $extendedblock $extendedstruct+ (local.get $any) (rtt.canon $extendedstruct)+ )+ (rtt.canon $struct)+ )+ )+ (call $log (i32.const -1)) ;; we should never get here+ (return)+ )+ )+ (call $log (i32.const -2)) ;; we should never get here either+ (return)+ )+ )+ (call $log (i32.const 3)) ;; we should get here+ (drop+ (block $never (result (ref $extendedstruct))+ ;; an untaken br_on_cast, with unreachable rtt - so we cannot use the+ ;; RTT in binaryen IR to find the cast type.+ (br_on_cast $never $extendedstruct (ref.null $struct) (unreachable))+ (unreachable)+ )+ )+ )+)
binaryen/test/passes/asyncify_enable-multivalue.txt view
@@ -491,55 +491,57 @@ ) ) (block- (if- (if (result i32)- (i32.eq- (global.get $__asyncify_state)- (i32.const 0)- )- (i32.const 1)- (i32.eq- (local.get $6)- (i32.const 0)- )- )- (block- (local.set $7- (call $import2)- )- (if+ (block+ (if+ (if (result i32) (i32.eq (global.get $__asyncify_state)- (i32.const 1)+ (i32.const 0) )- (br $__asyncify_unwind+ (i32.const 1)+ (i32.eq+ (local.get $6) (i32.const 0) )- (local.set $1- (local.get $7)+ )+ (block+ (local.set $7+ (call $import2) )+ (if+ (i32.eq+ (global.get $__asyncify_state)+ (i32.const 1)+ )+ (br $__asyncify_unwind+ (i32.const 0)+ )+ (local.set $1+ (local.get $7)+ )+ ) ) )- )- (if- (i32.eq- (global.get $__asyncify_state)- (i32.const 0)- )- (block- (local.set $temp- (local.get $1)- )- (local.set $2- (local.get $temp)+ (if+ (i32.eq+ (global.get $__asyncify_state)+ (i32.const 0) )- (return- (local.get $2)+ (block+ (local.set $temp+ (local.get $1)+ )+ (local.set $2+ (local.get $temp)+ )+ (return+ (local.get $2)+ ) ) )+ (nop)+ (nop) )- (nop)- (nop) ) (unreachable) )@@ -814,84 +816,86 @@ ) ) (block- (if- (i32.eq- (global.get $__asyncify_state)- (i32.const 0)- )- (loop $l- (local.set $3- (local.get $y)- )- (local.set $4- (i32.add- (local.get $3)- (i32.const 1)- )- )- (local.set $x- (local.get $4)- )- (local.set $5- (local.get $x)- )- (local.set $6- (i32.div_s- (local.get $5)- (i32.const 3)- )- )- (local.set $y- (local.get $6)- )- (local.set $7- (local.get $y)- )- (br_if $l- (local.get $7)- )- )- )- (if- (if (result i32)+ (block+ (if (i32.eq (global.get $__asyncify_state) (i32.const 0) )- (i32.const 1)- (i32.eq- (local.get $12)- (i32.const 0)+ (loop $l+ (local.set $3+ (local.get $y)+ )+ (local.set $4+ (i32.add+ (local.get $3)+ (i32.const 1)+ )+ )+ (local.set $x+ (local.get $4)+ )+ (local.set $5+ (local.get $x)+ )+ (local.set $6+ (i32.div_s+ (local.get $5)+ (i32.const 3)+ )+ )+ (local.set $y+ (local.get $6)+ )+ (local.set $7+ (local.get $y)+ )+ (br_if $l+ (local.get $7)+ ) ) )- (block- (call $import)- (if+ (if+ (if (result i32) (i32.eq (global.get $__asyncify_state)- (i32.const 1)+ (i32.const 0) )- (br $__asyncify_unwind+ (i32.const 1)+ (i32.eq+ (local.get $12) (i32.const 0) ) )- )- )- (if- (i32.eq- (global.get $__asyncify_state)- (i32.const 0)+ (block+ (call $import)+ (if+ (i32.eq+ (global.get $__asyncify_state)+ (i32.const 1)+ )+ (br $__asyncify_unwind+ (i32.const 0)+ )+ )+ ) )- (block- (local.set $8- (local.get $y)+ (if+ (i32.eq+ (global.get $__asyncify_state)+ (i32.const 0) )- (return- (local.get $8)+ (block+ (local.set $8+ (local.get $y)+ )+ (return+ (local.get $8)+ ) ) )+ (nop) )- (nop) ) (unreachable) )@@ -1291,90 +1295,92 @@ ) (block (block- (if- (i32.eq- (global.get $__asyncify_state)- (i32.const 0)- )- (local.set $1- (local.get $x)- )- ) (block (if (i32.eq (global.get $__asyncify_state) (i32.const 0) )- (local.set $4- (local.get $1)+ (local.set $1+ (local.get $x) ) )- (if- (i32.or- (local.get $4)- (i32.eq- (global.get $__asyncify_state)- (i32.const 2)- )- )+ (block (if (i32.eq (global.get $__asyncify_state) (i32.const 0) )- (return- (i32.const 1)- )- )- )- (if- (i32.or- (i32.eqz- (local.get $4)- )- (i32.eq- (global.get $__asyncify_state)- (i32.const 2)+ (local.set $4+ (local.get $1) ) ) (if- (if (result i32)+ (i32.or+ (local.get $4) (i32.eq (global.get $__asyncify_state)- (i32.const 0)+ (i32.const 2) )- (i32.const 1)+ )+ (if (i32.eq- (local.get $6)+ (global.get $__asyncify_state) (i32.const 0) )+ (return+ (i32.const 1)+ ) )- (block- (call $import3+ )+ (if+ (i32.or+ (i32.eqz+ (local.get $4)+ )+ (i32.eq+ (global.get $__asyncify_state) (i32.const 2) )- (if+ )+ (if+ (if (result i32) (i32.eq (global.get $__asyncify_state)- (i32.const 1)+ (i32.const 0) )- (br $__asyncify_unwind+ (i32.const 1)+ (i32.eq+ (local.get $6) (i32.const 0) ) )+ (block+ (call $import3+ (i32.const 2)+ )+ (if+ (i32.eq+ (global.get $__asyncify_state)+ (i32.const 1)+ )+ (br $__asyncify_unwind+ (i32.const 0)+ )+ )+ ) ) ) ) )- )- (if- (i32.eq- (global.get $__asyncify_state)- (i32.const 0)- )- (return- (i32.const 3)+ (if+ (i32.eq+ (global.get $__asyncify_state)+ (i32.const 0)+ )+ (return+ (i32.const 3)+ ) ) ) )@@ -1470,90 +1476,92 @@ ) (block (block- (if- (i32.eq- (global.get $__asyncify_state)- (i32.const 0)- )- (local.set $1- (local.get $x)- )- ) (block (if (i32.eq (global.get $__asyncify_state) (i32.const 0) )- (local.set $4- (local.get $1)+ (local.set $1+ (local.get $x) ) )- (if- (i32.or- (local.get $4)+ (block+ (if (i32.eq (global.get $__asyncify_state)- (i32.const 2)+ (i32.const 0) )+ (local.set $4+ (local.get $1)+ ) ) (if- (if (result i32)+ (i32.or+ (local.get $4) (i32.eq (global.get $__asyncify_state)- (i32.const 0)- )- (i32.const 1)- (i32.eq- (local.get $6)- (i32.const 0)+ (i32.const 2) ) )- (block- (call $import3- (i32.const 1)- )- (if+ (if+ (if (result i32) (i32.eq (global.get $__asyncify_state)- (i32.const 1)+ (i32.const 0) )- (br $__asyncify_unwind+ (i32.const 1)+ (i32.eq+ (local.get $6) (i32.const 0) ) )- )- )- )- (if- (i32.or- (i32.eqz- (local.get $4)- )- (i32.eq- (global.get $__asyncify_state)- (i32.const 2)+ (block+ (call $import3+ (i32.const 1)+ )+ (if+ (i32.eq+ (global.get $__asyncify_state)+ (i32.const 1)+ )+ (br $__asyncify_unwind+ (i32.const 0)+ )+ )+ ) ) ) (if- (i32.eq- (global.get $__asyncify_state)- (i32.const 0)+ (i32.or+ (i32.eqz+ (local.get $4)+ )+ (i32.eq+ (global.get $__asyncify_state)+ (i32.const 2)+ ) )- (return- (i32.const 2)+ (if+ (i32.eq+ (global.get $__asyncify_state)+ (i32.const 0)+ )+ (return+ (i32.const 2)+ ) ) ) ) )- )- (if- (i32.eq- (global.get $__asyncify_state)- (i32.const 0)- )- (return- (i32.const 3)+ (if+ (i32.eq+ (global.get $__asyncify_state)+ (i32.const 0)+ )+ (return+ (i32.const 3)+ ) ) ) )
binaryen/test/passes/asyncify_mod-asyncify-always-and-only-unwind.txt view
@@ -152,52 +152,54 @@ ) ) (block- (if- (if (result i32)- (i32.eq- (global.get $__asyncify_state)- (i32.const 0)- )- (i32.const 1)- (i32.eq- (local.get $6)- (i32.const 0)- )- )- (block- (local.set $7- (call $import2)- )- (if+ (block+ (if+ (if (result i32)+ (i32.eq+ (global.get $__asyncify_state)+ (i32.const 0)+ ) (i32.const 1)- (br $__asyncify_unwind+ (i32.eq+ (local.get $6) (i32.const 0) )- (local.set $1- (local.get $7)+ )+ (block+ (local.set $7+ (call $import2) )+ (if+ (i32.const 1)+ (br $__asyncify_unwind+ (i32.const 0)+ )+ (local.set $1+ (local.get $7)+ )+ ) ) )- )- (if- (i32.eq- (global.get $__asyncify_state)- (i32.const 0)- )- (block- (local.set $temp- (local.get $1)- )- (local.set $2- (local.get $temp)+ (if+ (i32.eq+ (global.get $__asyncify_state)+ (i32.const 0) )- (return- (local.get $2)+ (block+ (local.set $temp+ (local.get $1)+ )+ (local.set $2+ (local.get $temp)+ )+ (return+ (local.get $2)+ ) ) )+ (nop)+ (nop) )- (nop)- (nop) ) (unreachable) )
binaryen/test/passes/asyncify_mod-asyncify-never-unwind.txt view
@@ -164,52 +164,54 @@ ) ) (block- (if- (if (result i32)- (i32.eq- (global.get $__asyncify_state)- (i32.const 0)- )- (i32.const 1)- (i32.eq- (local.get $6)- (i32.const 0)- )- )- (block- (local.set $7- (call $import2)- )- (if- (i32.const 0)- (br $__asyncify_unwind+ (block+ (if+ (if (result i32)+ (i32.eq+ (global.get $__asyncify_state) (i32.const 0) )- (local.set $1- (local.get $7)+ (i32.const 1)+ (i32.eq+ (local.get $6)+ (i32.const 0) ) )- )- )- (if- (i32.eq- (global.get $__asyncify_state)- (i32.const 0)- )- (block- (local.set $temp- (local.get $1)+ (block+ (local.set $7+ (call $import2)+ )+ (if+ (i32.const 0)+ (br $__asyncify_unwind+ (i32.const 0)+ )+ (local.set $1+ (local.get $7)+ )+ ) )- (local.set $2- (local.get $temp)+ )+ (if+ (i32.eq+ (global.get $__asyncify_state)+ (i32.const 0) )- (return- (local.get $2)+ (block+ (local.set $temp+ (local.get $1)+ )+ (local.set $2+ (local.get $temp)+ )+ (return+ (local.get $2)+ ) ) )+ (nop)+ (nop) )- (nop)- (nop) ) (unreachable) )
binaryen/test/passes/asyncify_mod-asyncify-never-unwind_O.txt view
@@ -27,11 +27,11 @@ (block (result i32) (i32.store (global.get $__asyncify_data)- (i32.add+ (i32.sub (i32.load (global.get $__asyncify_data) )- (i32.const -4)+ (i32.const 4) ) ) (i32.load
binaryen/test/passes/asyncify_optimize-level=1.txt view
@@ -29,11 +29,11 @@ (block (result i32) (i32.store (global.get $__asyncify_data)- (i32.add+ (i32.sub (i32.load (global.get $__asyncify_data) )- (i32.const -4)+ (i32.const 4) ) ) (i32.load@@ -91,11 +91,11 @@ (block (i32.store (global.get $__asyncify_data)- (i32.add+ (i32.sub (i32.load (global.get $__asyncify_data) )- (i32.const -4)+ (i32.const 4) ) ) (local.set $0@@ -120,11 +120,11 @@ (block (result i32) (i32.store (global.get $__asyncify_data)- (i32.add+ (i32.sub (i32.load (global.get $__asyncify_data) )- (i32.const -4)+ (i32.const 4) ) ) (i32.load@@ -215,11 +215,11 @@ (block (result i32) (i32.store (global.get $__asyncify_data)- (i32.add+ (i32.sub (i32.load (global.get $__asyncify_data) )- (i32.const -4)+ (i32.const 4) ) ) (i32.load@@ -282,11 +282,11 @@ (block (i32.store (global.get $__asyncify_data)- (i32.add+ (i32.sub (i32.load (global.get $__asyncify_data) )- (i32.const -4)+ (i32.const 4) ) ) (local.set $1@@ -308,11 +308,11 @@ (block (i32.store (global.get $__asyncify_data)- (i32.add+ (i32.sub (i32.load (global.get $__asyncify_data) )- (i32.const -4)+ (i32.const 4) ) ) (local.set $2@@ -418,11 +418,11 @@ (block (i32.store (global.get $__asyncify_data)- (i32.add+ (i32.sub (i32.load (global.get $__asyncify_data) )- (i32.const -4)+ (i32.const 4) ) ) (local.set $1@@ -494,11 +494,11 @@ (block (i32.store (global.get $__asyncify_data)- (i32.add+ (i32.sub (i32.load (global.get $__asyncify_data) )- (i32.const -4)+ (i32.const 4) ) ) (local.set $1@@ -520,11 +520,11 @@ (block (i32.store (global.get $__asyncify_data)- (i32.add+ (i32.sub (i32.load (global.get $__asyncify_data) )- (i32.const -4)+ (i32.const 4) ) ) (local.set $2@@ -656,11 +656,11 @@ (block (i32.store (global.get $__asyncify_data)- (i32.add+ (i32.sub (i32.load (global.get $__asyncify_data) )- (i32.const -4)+ (i32.const 4) ) ) (local.set $1@@ -768,11 +768,11 @@ (block (i32.store (global.get $__asyncify_data)- (i32.add+ (i32.sub (i32.load (global.get $__asyncify_data) )- (i32.const -4)+ (i32.const 4) ) ) (local.set $1@@ -794,11 +794,11 @@ (block (i32.store (global.get $__asyncify_data)- (i32.add+ (i32.sub (i32.load (global.get $__asyncify_data) )- (i32.const -4)+ (i32.const 4) ) ) (local.set $2@@ -920,11 +920,11 @@ (block (i32.store (global.get $__asyncify_data)- (i32.add+ (i32.sub (i32.load (global.get $__asyncify_data) )- (i32.const -4)+ (i32.const 4) ) ) (local.set $0@@ -946,11 +946,11 @@ (block (i32.store (global.get $__asyncify_data)- (i32.add+ (i32.sub (i32.load (global.get $__asyncify_data) )- (i32.const -4)+ (i32.const 4) ) ) (local.set $1@@ -1046,11 +1046,11 @@ (block (i32.store (global.get $__asyncify_data)- (i32.add+ (i32.sub (i32.load (global.get $__asyncify_data) )- (i32.const -4)+ (i32.const 4) ) ) (local.set $0@@ -1072,11 +1072,11 @@ (block (i32.store (global.get $__asyncify_data)- (i32.add+ (i32.sub (i32.load (global.get $__asyncify_data) )- (i32.const -4)+ (i32.const 4) ) ) (local.set $2@@ -1171,11 +1171,11 @@ (block (i32.store (global.get $__asyncify_data)- (i32.add+ (i32.sub (i32.load (global.get $__asyncify_data) )- (i32.const -4)+ (i32.const 4) ) ) (local.set $0@@ -1276,11 +1276,11 @@ (block (i32.store (global.get $__asyncify_data)- (i32.add+ (i32.sub (i32.load (global.get $__asyncify_data) )- (i32.const -4)+ (i32.const 4) ) ) (local.set $0@@ -1384,11 +1384,11 @@ (block (result i32) (i32.store (global.get $__asyncify_data)- (i32.add+ (i32.sub (i32.load (global.get $__asyncify_data) )- (i32.const -4)+ (i32.const 4) ) ) (i32.load
binaryen/test/passes/asyncify_pass-arg=asyncify-imports@env.import,env.import2.txt view
@@ -488,55 +488,57 @@ ) ) (block- (if- (if (result i32)- (i32.eq- (global.get $__asyncify_state)- (i32.const 0)- )- (i32.const 1)- (i32.eq- (local.get $6)- (i32.const 0)- )- )- (block- (local.set $7- (call $import2)- )- (if+ (block+ (if+ (if (result i32) (i32.eq (global.get $__asyncify_state)- (i32.const 1)+ (i32.const 0) )- (br $__asyncify_unwind+ (i32.const 1)+ (i32.eq+ (local.get $6) (i32.const 0) )- (local.set $1- (local.get $7)+ )+ (block+ (local.set $7+ (call $import2) )+ (if+ (i32.eq+ (global.get $__asyncify_state)+ (i32.const 1)+ )+ (br $__asyncify_unwind+ (i32.const 0)+ )+ (local.set $1+ (local.get $7)+ )+ ) ) )- )- (if- (i32.eq- (global.get $__asyncify_state)- (i32.const 0)- )- (block- (local.set $temp- (local.get $1)- )- (local.set $2- (local.get $temp)+ (if+ (i32.eq+ (global.get $__asyncify_state)+ (i32.const 0) )- (return- (local.get $2)+ (block+ (local.set $temp+ (local.get $1)+ )+ (local.set $2+ (local.get $temp)+ )+ (return+ (local.get $2)+ ) ) )+ (nop)+ (nop) )- (nop)- (nop) ) (unreachable) )@@ -810,84 +812,86 @@ ) ) (block- (if- (i32.eq- (global.get $__asyncify_state)- (i32.const 0)- )- (loop $l- (local.set $2- (local.get $y)- )- (local.set $3- (i32.add- (local.get $2)- (i32.const 1)- )- )- (local.set $x- (local.get $3)- )- (local.set $4- (local.get $x)- )- (local.set $5- (i32.div_s- (local.get $4)- (i32.const 3)- )- )- (local.set $y- (local.get $5)- )- (local.set $6- (local.get $y)- )- (br_if $l- (local.get $6)- )- )- )- (if- (if (result i32)+ (block+ (if (i32.eq (global.get $__asyncify_state) (i32.const 0) )- (i32.const 1)- (i32.eq- (local.get $11)- (i32.const 0)+ (loop $l+ (local.set $2+ (local.get $y)+ )+ (local.set $3+ (i32.add+ (local.get $2)+ (i32.const 1)+ )+ )+ (local.set $x+ (local.get $3)+ )+ (local.set $4+ (local.get $x)+ )+ (local.set $5+ (i32.div_s+ (local.get $4)+ (i32.const 3)+ )+ )+ (local.set $y+ (local.get $5)+ )+ (local.set $6+ (local.get $y)+ )+ (br_if $l+ (local.get $6)+ ) ) )- (block- (call $import)- (if+ (if+ (if (result i32) (i32.eq (global.get $__asyncify_state)- (i32.const 1)+ (i32.const 0) )- (br $__asyncify_unwind+ (i32.const 1)+ (i32.eq+ (local.get $11) (i32.const 0) ) )- )- )- (if- (i32.eq- (global.get $__asyncify_state)- (i32.const 0)+ (block+ (call $import)+ (if+ (i32.eq+ (global.get $__asyncify_state)+ (i32.const 1)+ )+ (br $__asyncify_unwind+ (i32.const 0)+ )+ )+ ) )- (block- (local.set $7- (local.get $y)+ (if+ (i32.eq+ (global.get $__asyncify_state)+ (i32.const 0) )- (return- (local.get $7)+ (block+ (local.set $7+ (local.get $y)+ )+ (return+ (local.get $7)+ ) ) )+ (nop) )- (nop) ) (unreachable) )@@ -1062,21 +1066,23 @@ (local $2 i32) (local $3 i32) (block- (local.set $1- (local.get $x)- )- (if- (local.get $1)- (return- (i32.const 1)+ (block+ (local.set $1+ (local.get $x) )- (call $import3- (i32.const 2)+ (if+ (local.get $1)+ (return+ (i32.const 1)+ )+ (call $import3+ (i32.const 2)+ ) ) )- )- (return- (i32.const 3)+ (return+ (i32.const 3)+ ) ) ) (func $calls-import2-if-else-oneside2 (param $x i32) (result i32)@@ -1084,21 +1090,23 @@ (local $2 i32) (local $3 i32) (block- (local.set $1- (local.get $x)- )- (if- (local.get $1)- (call $import3- (i32.const 1)+ (block+ (local.set $1+ (local.get $x) )- (return- (i32.const 2)+ (if+ (local.get $1)+ (call $import3+ (i32.const 1)+ )+ (return+ (i32.const 2)+ ) ) )- )- (return- (i32.const 3)+ (return+ (i32.const 3)+ ) ) ) (func $calls-loop (param $x i32)
binaryen/test/passes/converge_O3_metrics.bin.txt view
@@ -6,18 +6,18 @@ [imports] : 3 [memory-data] : 28 [table-data] : 429 - [total] : 132 + [total] : 129 [vars] : 4 binary : 12 block : 8 break : 3 call : 3 call_indirect : 4 - const : 47 + const : 45 drop : 3 global.get : 1 global.set : 1 - if : 3 + if : 2 load : 16 local.get : 18 local.set : 7 @@ -30,7 +30,7 @@ (type $none_=>_i32 (func (result i32))) (type $i32_=>_i32 (func (param i32) (result i32))) (type $i32_i32_i32_i32_i32_i32_i32_=>_i32 (func (param i32 i32 i32 i32 i32 i32 i32) (result i32)))- (import "env" "memory" (memory $mimport$1 256 256))+ (import "env" "memory" (memory $mimport$0 256 256)) (data (i32.const 2948) "\03") (data (i32.const 6828) "\04") (data (i32.const 7028) "\0d\00\00\00\06")@@ -39,7 +39,7 @@ (data (i32.const 18128) ",I") (data (i32.const 18732) "D\1b") (data (i32.const 18764) "`\0b")- (import "env" "table" (table $timport$2 478 478 funcref))+ (import "env" "table" (table $timport$0 478 478 funcref)) (elem (i32.const 0) $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $___stdout_write $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $__ZNSt3__211__stdoutbufIcE6xsputnEPKci $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $__ZNSt3__211__stdoutbufIcE8overflowEi) (import "env" "___syscall146" (func $import$0 (param i32 i32) (result i32))) (global $global$0 (mut i32) (i32.const 1))@@ -71,13 +71,9 @@ (i32.const 2) ) (drop- (if (result i32)- (call $import$0- (i32.const 146)- (local.get $0)- )- (i32.const -1)- (i32.const 0)+ (call $import$0+ (i32.const 146)+ (local.get $0) ) ) (i32.const 1)@@ -89,11 +85,11 @@ (i32.load offset=24 (i32.add (i32.load- (i32.add+ (i32.sub (i32.load (i32.const 18100) )- (i32.const -12)+ (i32.const 12) ) ) (i32.const 18100)@@ -167,11 +163,11 @@ (i32.load (i32.add (i32.load- (i32.add+ (i32.sub (i32.load (i32.const 18100) )- (i32.const -12)+ (i32.const 12) ) ) (i32.const 18124)@@ -251,18 +247,18 @@ [imports] : 3 [memory-data] : 28 [table-data] : 429 - [total] : 132 + [total] : 129 [vars] : 4 binary : 12 block : 8 break : 3 call : 3 call_indirect : 4 - const : 47 + const : 45 drop : 3 global.get : 1 global.set : 1 - if : 3 + if : 2 load : 16 local.get : 18 local.set : 7 @@ -275,7 +271,7 @@ (type $none_=>_i32 (func (result i32))) (type $i32_=>_i32 (func (param i32) (result i32))) (type $i32_i32_i32_i32_i32_i32_i32_=>_i32 (func (param i32 i32 i32 i32 i32 i32 i32) (result i32)))- (import "env" "memory" (memory $mimport$1 256 256))+ (import "env" "memory" (memory $mimport$0 256 256)) (data (i32.const 2948) "\03") (data (i32.const 6828) "\04") (data (i32.const 7028) "\0d\00\00\00\06")@@ -284,7 +280,7 @@ (data (i32.const 18128) ",I") (data (i32.const 18732) "D\1b") (data (i32.const 18764) "`\0b")- (import "env" "table" (table $timport$2 478 478 funcref))+ (import "env" "table" (table $timport$0 478 478 funcref)) (elem (i32.const 0) $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $___stdout_write $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $__ZNSt3__211__stdoutbufIcE6xsputnEPKci $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $b0 $__ZNSt3__211__stdoutbufIcE8overflowEi) (import "env" "___syscall146" (func $import$0 (param i32 i32) (result i32))) (global $global$0 (mut i32) (i32.const 1))@@ -316,13 +312,9 @@ (i32.const 2) ) (drop- (if (result i32)- (call $import$0- (i32.const 146)- (local.get $0)- )- (i32.const -1)- (i32.const 0)+ (call $import$0+ (i32.const 146)+ (local.get $0) ) ) (i32.const 1)@@ -334,11 +326,11 @@ (i32.load offset=24 (i32.add (i32.load- (i32.add+ (i32.sub (i32.load (i32.const 18100) )- (i32.const -12)+ (i32.const 12) ) ) (i32.const 18100)@@ -412,11 +404,11 @@ (i32.load (i32.add (i32.load- (i32.add+ (i32.sub (i32.load (i32.const 18100) )- (i32.const -12)+ (i32.const 12) ) ) (i32.const 18124)
+ binaryen/test/passes/dae_all-features.txt view
@@ -0,0 +1,293 @@+(module+ (type $none_=>_none (func))+ (type $i32_=>_none (func (param i32)))+ (type $none_=>_i32 (func (result i32)))+ (type $f64_=>_none (func (param f64)))+ (table $0 2 2 funcref)+ (elem (i32.const 0) $a9 $c8)+ (export "a8" (func $a8))+ (func $a+ (local $0 i32)+ (local.set $0+ (i32.const 1)+ )+ (nop)+ )+ (func $b+ (call $a)+ )+ (func $a1+ (local $0 i32)+ (local.set $0+ (i32.const 2)+ )+ (unreachable)+ )+ (func $b1+ (call $a1)+ )+ (func $b11+ (call $a1)+ )+ (func $a2 (param $x i32)+ (drop+ (local.get $x)+ )+ )+ (func $b2+ (call $a2+ (i32.const 3)+ )+ )+ (func $b22+ (call $a2+ (i32.const 4)+ )+ )+ (func $a3+ (local $0 i32)+ (drop+ (i32.const -1)+ )+ )+ (func $b3+ (call $a3)+ )+ (func $b33+ (call $a3)+ )+ (func $a4 (param $x i32)+ (nop)+ )+ (func $b4+ (call $a4+ (unreachable)+ )+ )+ (func $b43+ (call $a4+ (i32.const 4)+ )+ )+ (func $a5+ (local $0 f64)+ (local $1 i32)+ (local.set $0+ (f64.const 3.14159)+ )+ (block+ (local.set $1+ (i32.const 1)+ )+ (block+ (drop+ (local.get $1)+ )+ (drop+ (local.get $0)+ )+ )+ )+ )+ (func $b5+ (call $a5)+ )+ (func $a6 (param $0 i32)+ (local $1 f64)+ (local.set $1+ (f64.const 3.14159)+ )+ (block+ (drop+ (local.get $0)+ )+ (drop+ (local.get $1)+ )+ )+ )+ (func $b6+ (call $a6+ (unreachable)+ )+ )+ (func $a7 (param $0 f64)+ (local $1 i32)+ (local.set $1+ (i32.const 1)+ )+ (block+ (drop+ (local.get $1)+ )+ (drop+ (local.get $0)+ )+ )+ )+ (func $b7+ (call $a7+ (unreachable)+ )+ )+ (func $a8 (param $x i32)+ (nop)+ )+ (func $b8+ (call $a8+ (i32.const 1)+ )+ )+ (func $a9 (param $x i32)+ (nop)+ )+ (func $b9+ (call $a9+ (i32.const 1)+ )+ )+ (func $a10+ (local $0 i32)+ (local.set $0+ (i32.const 1)+ )+ (block+ (call $a10)+ (call $a10)+ )+ )+ (func $a11+ (local $0 i32)+ (call $a11)+ (call $a11)+ )+ (func $a12 (param $x i32)+ (drop+ (local.get $x)+ )+ (call $a12+ (i32.const 1)+ )+ (call $a12+ (i32.const 2)+ )+ )+ (func $c1+ (local $x i32)+ (call $c2)+ (call $c3)+ (call $c3)+ (drop+ (call $c4)+ )+ (local.set $x+ (call $c4)+ )+ (call $c5+ (unreachable)+ )+ (call $c6)+ (call $c7)+ (drop+ (call $c8)+ )+ )+ (func $c2+ (drop+ (i32.const 1)+ )+ )+ (func $c3+ (drop+ (i32.const 2)+ )+ )+ (func $c4 (result i32)+ (i32.const 3)+ )+ (func $c5 (param $x i32)+ (drop+ (local.get $x)+ )+ )+ (func $c6+ (unreachable)+ )+ (func $c7+ (drop+ (i32.const 4)+ )+ (return)+ )+ (func $c8 (result i32)+ (i32.const 5)+ )+)+(module+ (type $none_=>_none (func))+ (export "a" (func $0))+ (func $0+ (call $b)+ )+ (func $b+ (local $0 i32)+ (drop+ (block (result i32)+ (local.set $0+ (i32.const 1)+ )+ (local.get $0)+ )+ )+ )+)+(module+ (type $none_=>_i32 (func (result i32)))+ (type $i32_=>_i32 (func (param i32) (result i32)))+ (func $foo (param $x i32) (result i32)+ (drop+ (return_call $bar)+ )+ (i32.const 42)+ )+ (func $bar (result i32)+ (local $0 i32)+ (local.set $0+ (i32.const 0)+ )+ (i32.const 7)+ )+)+(module+ (type $none_=>_i32 (func (result i32)))+ (type $none_=>_none (func))+ (table $0 1 1 funcref)+ (func $foo (result i32)+ (local $0 i32)+ (local.set $0+ (i32.const 42)+ )+ (drop+ (return_call_indirect (type $none_=>_i32)+ (i32.const 0)+ )+ )+ )+ (func $bar+ (drop+ (call $foo)+ )+ )+)+(module+ (type $funcref_i32_f64_=>_i64 (func (param funcref i32 f64) (result i64)))+ (type $f32_=>_funcref (func (param f32) (result funcref)))+ (export "export" (func $1))+ (func $0 (param $0 funcref) (param $1 i32) (param $2 f64) (result i64)+ (nop)+ (unreachable)+ )+ (func $1 (param $0 f32) (result funcref)+ (ref.func $0)+ )+)
+ binaryen/test/passes/dae_all-features.wast view
@@ -0,0 +1,174 @@+(module+ (export "a8" (func $a8))+ (table 2 2 funcref)+ (elem (i32.const 0) $a9 $c8)+ (func $a (param $x i32))+ (func $b+ (call $a (i32.const 1)) ;; best case scenario+ )+ (func $a1 (param $x i32)+ (unreachable)+ )+ (func $b1+ (call $a1 (i32.const 2)) ;; same value in both, so works+ )+ (func $b11+ (call $a1 (i32.const 2))+ )+ (func $a2 (param $x i32)+ (drop (local.get $x))+ )+ (func $b2+ (call $a2 (i32.const 3)) ;; different value!+ )+ (func $b22+ (call $a2 (i32.const 4))+ )+ (func $a3 (param $x i32)+ (drop (i32.const -1)) ;; diff value, but at least unused, so no need to send+ )+ (func $b3+ (call $a3 (i32.const 3))+ )+ (func $b33+ (call $a3 (i32.const 4))+ )+ (func $a4 (param $x i32) ;; diff value, but with effects+ )+ (func $b4+ (call $a4 (unreachable))+ )+ (func $b43+ (call $a4 (i32.const 4))+ )+ (func $a5 (param $x i32) (param $y f64) ;; optimize two+ (drop (local.get $x))+ (drop (local.get $y))+ )+ (func $b5+ (call $a5 (i32.const 1) (f64.const 3.14159))+ )+ (func $a6 (param $x i32) (param $y f64) ;; optimize just one+ (drop (local.get $x))+ (drop (local.get $y))+ )+ (func $b6+ (call $a6 (unreachable) (f64.const 3.14159))+ )+ (func $a7 (param $x i32) (param $y f64) ;; optimize just the other one+ (drop (local.get $x))+ (drop (local.get $y))+ )+ (func $b7+ (call $a7 (i32.const 1) (unreachable))+ )+ (func $a8 (param $x i32)) ;; exported, do not optimize+ (func $b8+ (call $a8 (i32.const 1))+ )+ (func $a9 (param $x i32)) ;; tabled, do not optimize+ (func $b9+ (call $a9 (i32.const 1))+ )+ (func $a10 (param $x i32) ;; recursion+ (call $a10 (i32.const 1))+ (call $a10 (i32.const 1))+ )+ (func $a11 (param $x i32) ;; partially successful recursion+ (call $a11 (i32.const 1))+ (call $a11 (i32.const 2))+ )+ (func $a12 (param $x i32) ;; unsuccessful recursion+ (drop (local.get $x))+ (call $a12 (i32.const 1))+ (call $a12 (i32.const 2))+ )+ ;; return values+ (func $c1+ (local $x i32)+ (drop (call $c2))+ (drop (call $c3))+ (drop (call $c3))+ (drop (call $c4))+ (local.set $x (call $c4))+ (drop (call $c5 (unreachable)))+ (drop (call $c6))+ (drop (call $c7))+ (drop (call $c8))+ )+ (func $c2 (result i32)+ (i32.const 1)+ )+ (func $c3 (result i32)+ (i32.const 2)+ )+ (func $c4 (result i32)+ (i32.const 3)+ )+ (func $c5 (param $x i32) (result i32)+ (local.get $x)+ )+ (func $c6 (result i32)+ (unreachable)+ )+ (func $c7 (result i32)+ (return (i32.const 4))+ )+ (func $c8 (result i32)+ (i32.const 5)+ )+)+(module ;; both operations at once: remove params and return value+ (func "a"+ (drop+ (call $b+ (i32.const 1)+ )+ )+ )+ (func $b (param $x i32) (result i32)+ (local.get $x)+ )+)+(module ;; tail calls inhibit dropped result removal+ (func $foo (param $x i32) (result i32)+ (drop+ (return_call $bar+ (i32.const 0)+ )+ )+ (i32.const 42)+ )+ (func $bar (param $x i32) (result i32)+ (i32.const 7)+ )+)+(module ;; indirect tail calls inhibit dropped result removal+ (type $T (func (result i32)))+ (table 1 1 funcref)+ (func $foo (param $x i32) (result i32)+ (drop+ (return_call_indirect (type $T)+ (i32.const 0)+ )+ )+ )+ (func $bar+ (drop+ (call $foo+ (i32.const 42)+ )+ )+ )+)+(module+ (func $0 (param $0 funcref) (param $1 i32) (param $2 f64) (result i64)+ (nop)+ (unreachable)+ )+ (func "export" (param $0 f32) (result funcref)+ ;; a ref.func should prevent us from changing the type of a function, as it+ ;; may escape+ (ref.func $0)+ )+)
− binaryen/test/passes/dae_enable-tail-call.txt
@@ -1,281 +0,0 @@-(module- (type $none_=>_none (func))- (type $i32_=>_none (func (param i32)))- (type $none_=>_i32 (func (result i32)))- (type $f64_=>_none (func (param f64)))- (table $0 2 2 funcref)- (elem (i32.const 0) $a9 $c8)- (export "a8" (func $a8))- (func $a- (local $0 i32)- (local.set $0- (i32.const 1)- )- (nop)- )- (func $b- (call $a)- )- (func $a1- (local $0 i32)- (local.set $0- (i32.const 2)- )- (unreachable)- )- (func $b1- (call $a1)- )- (func $b11- (call $a1)- )- (func $a2 (param $x i32)- (drop- (local.get $x)- )- )- (func $b2- (call $a2- (i32.const 3)- )- )- (func $b22- (call $a2- (i32.const 4)- )- )- (func $a3- (local $0 i32)- (drop- (i32.const -1)- )- )- (func $b3- (call $a3)- )- (func $b33- (call $a3)- )- (func $a4 (param $x i32)- (nop)- )- (func $b4- (call $a4- (unreachable)- )- )- (func $b43- (call $a4- (i32.const 4)- )- )- (func $a5- (local $0 f64)- (local $1 i32)- (local.set $0- (f64.const 3.14159)- )- (block- (local.set $1- (i32.const 1)- )- (block- (drop- (local.get $1)- )- (drop- (local.get $0)- )- )- )- )- (func $b5- (call $a5)- )- (func $a6 (param $0 i32)- (local $1 f64)- (local.set $1- (f64.const 3.14159)- )- (block- (drop- (local.get $0)- )- (drop- (local.get $1)- )- )- )- (func $b6- (call $a6- (unreachable)- )- )- (func $a7 (param $0 f64)- (local $1 i32)- (local.set $1- (i32.const 1)- )- (block- (drop- (local.get $1)- )- (drop- (local.get $0)- )- )- )- (func $b7- (call $a7- (unreachable)- )- )- (func $a8 (param $x i32)- (nop)- )- (func $b8- (call $a8- (i32.const 1)- )- )- (func $a9 (param $x i32)- (nop)- )- (func $b9- (call $a9- (i32.const 1)- )- )- (func $a10- (local $0 i32)- (local.set $0- (i32.const 1)- )- (block- (call $a10)- (call $a10)- )- )- (func $a11- (local $0 i32)- (call $a11)- (call $a11)- )- (func $a12 (param $x i32)- (drop- (local.get $x)- )- (call $a12- (i32.const 1)- )- (call $a12- (i32.const 2)- )- )- (func $c1- (local $x i32)- (call $c2)- (call $c3)- (call $c3)- (drop- (call $c4)- )- (local.set $x- (call $c4)- )- (call $c5- (unreachable)- )- (call $c6)- (call $c7)- (drop- (call $c8)- )- )- (func $c2- (drop- (i32.const 1)- )- )- (func $c3- (drop- (i32.const 2)- )- )- (func $c4 (result i32)- (i32.const 3)- )- (func $c5 (param $x i32)- (drop- (local.get $x)- )- )- (func $c6- (unreachable)- )- (func $c7- (drop- (i32.const 4)- )- (return)- )- (func $c8 (result i32)- (i32.const 5)- )-)-(module- (type $none_=>_none (func))- (export "a" (func $0))- (func $0- (call $b)- )- (func $b- (local $0 i32)- (drop- (block (result i32)- (local.set $0- (i32.const 1)- )- (local.get $0)- )- )- )-)-(module- (type $none_=>_i32 (func (result i32)))- (type $i32_=>_i32 (func (param i32) (result i32)))- (func $foo (param $x i32) (result i32)- (drop- (return_call $bar)- )- (i32.const 42)- )- (func $bar (result i32)- (local $0 i32)- (local.set $0- (i32.const 0)- )- (i32.const 7)- )-)-(module- (type $none_=>_i32 (func (result i32)))- (type $none_=>_none (func))- (table $0 1 1 funcref)- (func $foo (result i32)- (local $0 i32)- (local.set $0- (i32.const 42)- )- (drop- (return_call_indirect (type $none_=>_i32)- (i32.const 0)- )- )- )- (func $bar- (drop- (call $foo)- )- )-)
− binaryen/test/passes/dae_enable-tail-call.wast
@@ -1,163 +0,0 @@-(module- (export "a8" (func $a8))- (table 2 2 funcref)- (elem (i32.const 0) $a9 $c8)- (func $a (param $x i32))- (func $b- (call $a (i32.const 1)) ;; best case scenario- )- (func $a1 (param $x i32)- (unreachable)- )- (func $b1- (call $a1 (i32.const 2)) ;; same value in both, so works- )- (func $b11- (call $a1 (i32.const 2))- )- (func $a2 (param $x i32)- (drop (local.get $x))- )- (func $b2- (call $a2 (i32.const 3)) ;; different value!- )- (func $b22- (call $a2 (i32.const 4))- )- (func $a3 (param $x i32)- (drop (i32.const -1)) ;; diff value, but at least unused, so no need to send- )- (func $b3- (call $a3 (i32.const 3))- )- (func $b33- (call $a3 (i32.const 4))- )- (func $a4 (param $x i32) ;; diff value, but with effects- )- (func $b4- (call $a4 (unreachable))- )- (func $b43- (call $a4 (i32.const 4))- )- (func $a5 (param $x i32) (param $y f64) ;; optimize two- (drop (local.get $x))- (drop (local.get $y))- )- (func $b5- (call $a5 (i32.const 1) (f64.const 3.14159))- )- (func $a6 (param $x i32) (param $y f64) ;; optimize just one- (drop (local.get $x))- (drop (local.get $y))- )- (func $b6- (call $a6 (unreachable) (f64.const 3.14159))- )- (func $a7 (param $x i32) (param $y f64) ;; optimize just the other one- (drop (local.get $x))- (drop (local.get $y))- )- (func $b7- (call $a7 (i32.const 1) (unreachable))- )- (func $a8 (param $x i32)) ;; exported, do not optimize- (func $b8- (call $a8 (i32.const 1))- )- (func $a9 (param $x i32)) ;; tabled, do not optimize- (func $b9- (call $a9 (i32.const 1))- )- (func $a10 (param $x i32) ;; recursion- (call $a10 (i32.const 1))- (call $a10 (i32.const 1))- )- (func $a11 (param $x i32) ;; partially successful recursion- (call $a11 (i32.const 1))- (call $a11 (i32.const 2))- )- (func $a12 (param $x i32) ;; unsuccessful recursion- (drop (local.get $x))- (call $a12 (i32.const 1))- (call $a12 (i32.const 2))- )- ;; return values- (func $c1- (local $x i32)- (drop (call $c2))- (drop (call $c3))- (drop (call $c3))- (drop (call $c4))- (local.set $x (call $c4))- (drop (call $c5 (unreachable)))- (drop (call $c6))- (drop (call $c7))- (drop (call $c8))- )- (func $c2 (result i32)- (i32.const 1)- )- (func $c3 (result i32)- (i32.const 2)- )- (func $c4 (result i32)- (i32.const 3)- )- (func $c5 (param $x i32) (result i32)- (local.get $x)- )- (func $c6 (result i32)- (unreachable)- )- (func $c7 (result i32)- (return (i32.const 4))- )- (func $c8 (result i32)- (i32.const 5)- )-)-(module ;; both operations at once: remove params and return value- (func "a"- (drop- (call $b- (i32.const 1)- )- )- )- (func $b (param $x i32) (result i32)- (local.get $x)- )-)-(module ;; tail calls inhibit dropped result removal- (func $foo (param $x i32) (result i32)- (drop- (return_call $bar- (i32.const 0)- )- )- (i32.const 42)- )- (func $bar (param $x i32) (result i32)- (i32.const 7)- )-)-(module ;; indirect tail calls inhibit dropped result removal- (type $T (func (result i32)))- (table 1 1 funcref)- (func $foo (param $x i32) (result i32)- (drop- (return_call_indirect (type $T)- (i32.const 0)- )- )- )- (func $bar- (drop- (call $foo- (i32.const 42)- )- )- )-)
binaryen/test/passes/dce_all-features.txt view
@@ -24,7 +24,9 @@ ) (if (i32.const 0)- (return)+ (block $out3+ (return)+ ) ) (block $out4 (br_table $out4 $out4 $out4 $out4@@ -41,10 +43,12 @@ ) (if (i32.const 0)- (if- (i32.const 0)- (unreachable)- (unreachable)+ (block $block4+ (if+ (i32.const 0)+ (unreachable)+ (unreachable)+ ) ) ) (if@@ -69,13 +73,15 @@ ) (if (i32.const 0)- (block $out18- (block $in19- (br_if $in19- (i32.const 1)+ (block $block11+ (block $out18+ (block $in19+ (br_if $in19+ (i32.const 1)+ ) )+ (unreachable) )- (unreachable) ) ) (block $out20@@ -96,13 +102,15 @@ ) (if (i32.const 0)- (block $out25- (block $in26- (br_table $in26 $in26- (i32.const 1)+ (block $block13+ (block $out25+ (block $in26+ (br_table $in26 $in26+ (i32.const 1)+ ) )+ (unreachable) )- (unreachable) ) ) (if@@ -122,7 +130,7 @@ (unreachable) ) (block $out29- (block+ (loop $in30 (br_if $out29 (i32.const 1) )@@ -131,11 +139,13 @@ ) (if (i32.const 0)- (loop $in32- (br_if $in32- (i32.const 1)+ (block $block20+ (loop $in32+ (br_if $in32+ (i32.const 1)+ )+ (unreachable) )- (unreachable) ) ) (if@@ -273,8 +283,12 @@ ) ) (func $typed-block-none-then-unreachable (result i32)- (return- (i32.const 0)+ (block $top-typed+ (block $switch$0+ (return+ (i32.const 0)+ )+ ) ) ) (func $typed-block-remove-br-changes-type (param $$$0 i32) (result i32)@@ -317,15 +331,19 @@ ) ) (func $unreachable-block-ends-switch (result i32)- (block $label$3- (nop)- (unreachable)+ (block $label$0+ (block $label$3+ (nop)+ (unreachable)+ ) ) ) (func $unreachable-block-ends-br_if (result i32)- (block $label$2- (nop)- (unreachable)+ (block $label$0+ (block $label$2+ (nop)+ (unreachable)+ ) ) ) (func $unreachable-brs-3 (result i32)@@ -339,11 +357,15 @@ (drop (i32.const 1) )- (block- (drop- (i32.const 4104)+ (block $label$0+ (block $label$1+ (block+ (drop+ (i32.const 4104)+ )+ (unreachable)+ ) )- (unreachable) ) ) (func $call-unreach (param $var$0 i64) (param $var$1 i64) (result i64)@@ -355,32 +377,36 @@ (block $label$0 (result i64) (local.get $var$1) )- (block- (drop- (i64.sub- (local.get $var$0)- (i64.const 1)- )- )+ (block $label$1 (block (drop- (block $block (result i64)- (local.set $2- (local.get $var$0)+ (i64.sub+ (local.get $var$0)+ (i64.const 1)+ )+ )+ (block+ (drop+ (block $block (result i64)+ (local.set $2+ (local.get $var$0)+ )+ (nop)+ (local.get $2) )- (nop)- (local.get $2) )+ (unreachable) )- (unreachable) ) ) ) ) (func $br-gone-means-block-type-changes-then-refinalize-at-end-is-too-late (param $var$0 i32) (result i32)- (block $block- (nop)- (unreachable)+ (block $label$0+ (block $block+ (nop)+ (unreachable)+ ) ) ) (func $br-with-unreachable-value-should-not-give-a-block-a-value (param $var$0 i32) (result i32)@@ -397,25 +423,31 @@ ) ) (func $replace-br-value-of-i32-with-unreachable (result i32)- (block $label$1- (nop)- (unreachable)+ (block $label$0+ (block $label$1+ (nop)+ (unreachable)+ ) ) ) (func $shorten-block-requires-sync-refinalize (param $var$0 i32) (param $var$1 i32) (unreachable) ) (func $block-with-type-but-is-unreachable (param $var$0 i32) (result i32)- (block $block- (nop)- (unreachable)+ (block $label$0+ (block $block+ (nop)+ (unreachable)+ ) ) ) (func $if-with-type-but-is-unreachable (param $var$0 i32) (result i32)- (if- (local.get $var$0)- (unreachable)- (unreachable)+ (block $label$0+ (if+ (local.get $var$0)+ (unreachable)+ (unreachable)+ ) ) ) (func $unreachable-loop@@ -423,8 +455,10 @@ ) (func $br-block-from-unary (result i32) (block $label$6 (result i32)- (br $label$6- (i32.const 8)+ (block $label$7+ (br $label$6+ (i32.const 8)+ ) ) ) )@@ -444,19 +478,23 @@ ) ) (func $replace-with-unreachable-affects-parent (param $var$0 f32) (param $var$1 i64)- (drop- (i64.const 0)- )- (if- (block $block (result i32)- (call $replace-with-unreachable-affects-parent- (f32.const 1)- (i64.const -15917430362925035)+ (block $top+ (block+ (drop+ (i64.const 0) )- (i32.const 1)+ (if+ (block $block (result i32)+ (call $replace-with-unreachable-affects-parent+ (f32.const 1)+ (i64.const -15917430362925035)+ )+ (i32.const 1)+ )+ (unreachable)+ (unreachable)+ ) )- (unreachable)- (unreachable) ) ) (func $replace-block-changes-later-when-if-goes@@ -503,6 +541,7 @@ ) (module (type $none_=>_none (func))+ (type $none_=>_i32 (func (result i32))) (event $e (attr 0) (param)) (func $foo (nop)@@ -542,12 +581,68 @@ ) ) (func $throw- (throw $e+ (block $label$0+ (block $label$1+ (throw $e+ )+ ) ) ) (func $rethrow- (rethrow- (ref.null exn)+ (block $label$0+ (block $label$1+ (rethrow+ (ref.null exn)+ )+ )+ )+ )+ (func $unnecessary-concrete-block (result i32)+ (block $foo+ (nop)+ (unreachable)+ )+ )+ (func $necessary-concrete-block (result i32)+ (block $foo (result i32)+ (br $foo+ (i32.const 1)+ )+ )+ )+ (func $unnecessary-concrete-if (result i32)+ (if+ (i32.const 0)+ (return+ (i32.const 1)+ )+ (unreachable)+ )+ )+ (func $unnecessary-concrete-try (result i32)+ (try+ (do+ (unreachable)+ )+ (catch+ (unreachable)+ )+ )+ )+ (func $note-loss-of-if-children+ (block $label$1+ (block $label$2+ (nop)+ (unreachable)+ )+ )+ )+ (func $note-loss-of-non-control-flow-children+ (block $out+ (block $block+ (nop)+ (unreachable)+ ) ) ) )
binaryen/test/passes/dce_all-features.wast view
@@ -810,4 +810,61 @@ ) ) )++ (func $unnecessary-concrete-block (result i32)+ (block $foo (result i32) ;; unnecessary type+ (nop)+ (unreachable)+ )+ )+ (func $necessary-concrete-block (result i32)+ (block $foo (result i32)+ (br $foo (i32.const 1))+ (unreachable)+ )+ )+ (func $unnecessary-concrete-if (result i32)+ (if (result i32) ;; unnecessary type+ (i32.const 0)+ (return (i32.const 1))+ (unreachable)+ )+ )+ (func $unnecessary-concrete-try (result i32)+ (try (result i32)+ (do+ (unreachable)+ )+ (catch+ (unreachable)+ )+ )+ )+ (func $note-loss-of-if-children+ (block $label$1+ (if ;; begins unreachable - type never changes - but after the condition+ ;; becomes unreachable, it will lose the children, which means no more+ ;; br to the outer block, changing that type.+ (block $label$2 (result i32)+ (nop)+ (unreachable)+ )+ (unreachable)+ (br $label$1)+ )+ )+ )+ (func $note-loss-of-non-control-flow-children+ (block $out+ (drop+ (i32.add+ (block (result i32)+ (nop)+ (unreachable)+ )+ (br $out) ;; when this is removed as dead, the block becomes unreachable+ )+ )+ )+ ) )
− binaryen/test/passes/dce_vacuum.bin.txt
@@ -1,98 +0,0 @@-(module- (type $f32_f32_=>_f32 (func (param f32 f32) (result f32)))- (type $f64_f64_=>_f64 (func (param f64 f64) (result f64)))- (export "f32.compute_radix" (func $0))- (export "f64.compute_radix" (func $1))- (func $0 (param $0 f32) (param $1 f32) (result f32)- (block $label$1- (loop $label$2- (br_if $label$2- (f32.eq- (f32.add- (f32.sub- (f32.add- (local.tee $0- (f32.add- (local.get $0)- (local.get $0)- )- )- (f32.const 1)- )- (local.get $0)- )- (f32.const -1)- )- (f32.const 0)- )- )- )- (block- (drop- (call $0- (f32.add- (local.get $0)- (local.tee $1- (f32.add- (local.get $1)- (f32.const 1)- )- )- )- (local.get $0)- )- )- (unreachable)- )- )- )- (func $1 (param $0 f64) (param $1 f64) (result f64)- (block $label$1 (result f64)- (loop $label$2- (br_if $label$2- (f64.eq- (f64.add- (f64.sub- (f64.add- (local.tee $0- (f64.add- (local.get $0)- (local.get $0)- )- )- (f64.const 1)- )- (local.get $0)- )- (f64.const -1)- )- (f64.const 0)- )- )- )- (loop $label$3- (br_if $label$3- (f64.ne- (f64.sub- (f64.sub- (f64.add- (local.get $0)- (local.tee $1- (f64.add- (local.get $1)- (f64.const 1)- )- )- )- (local.get $0)- )- (local.get $1)- )- (f64.const 0)- )- )- )- (local.get $1)- )- )-)
− binaryen/test/passes/dce_vacuum.txt
@@ -1,25 +0,0 @@-(module- (type $none_=>_i32 (func (result i32)))- (type $i64_=>_i64 (func (param i64) (result i64)))- (type $f32_f32_=>_f32 (func (param f32 f32) (result f32)))- (func $__Z12serveroptionPc (result i32)- (return- (i32.const 0)- )- )- (func $drop-unreachable (param $var$0 f32) (param $var$1 f32) (result f32)- (unreachable)- )- (func $set-unreachable (param $var$0 i64) (result i64)- (local $var$1 i64)- (local $var$2 i64)- (if- (i64.eq- (local.get $var$1)- (i64.const 0)- )- (unreachable)- (unreachable)- )- )-)
− binaryen/test/passes/dce_vacuum.wasm
binary file changed (260 → absent bytes)
− binaryen/test/passes/dce_vacuum.wast
@@ -1,51 +0,0 @@-(module- (func $__Z12serveroptionPc (result i32)- (block $switch$0- (return- (i32.const 0)- )- (br $switch$0)- )- (return- (i32.const 0)- )- )- (func $drop-unreachable (param $var$0 f32) (param $var$1 f32) (result f32)- (block $label$0 (result f32)- (loop $label$2- (drop- (unreachable)- )- (unreachable)- )- (local.get $var$1)- )- )-- (func $set-unreachable (param $var$0 i64) (result i64)- (local $var$1 i64)- (local $var$2 i64)- (block $label$0 (result i64)- (block $label$1- (loop $label$2- (if- (i64.eq- (local.get $var$1)- (i64.const 0)- )- (unreachable)- (local.set $var$2- (i64.mul- (unreachable)- (local.get $var$2)- )- )- )- (br $label$2)- )- )- (local.get $var$2)- )- )-)-
+ binaryen/test/passes/dce_vacuum_remove-unused-names.bin.txt view
@@ -0,0 +1,94 @@+(module+ (type $f32_f32_=>_f32 (func (param f32 f32) (result f32)))+ (type $f64_f64_=>_f64 (func (param f64 f64) (result f64)))+ (export "f32.compute_radix" (func $0))+ (export "f64.compute_radix" (func $1))+ (func $0 (param $0 f32) (param $1 f32) (result f32)+ (loop $label$2+ (br_if $label$2+ (f32.eq+ (f32.add+ (f32.sub+ (f32.add+ (local.tee $0+ (f32.add+ (local.get $0)+ (local.get $0)+ )+ )+ (f32.const 1)+ )+ (local.get $0)+ )+ (f32.const -1)+ )+ (f32.const 0)+ )+ )+ )+ (block+ (drop+ (call $0+ (f32.add+ (local.get $0)+ (local.tee $1+ (f32.add+ (local.get $1)+ (f32.const 1)+ )+ )+ )+ (local.get $0)+ )+ )+ (unreachable)+ )+ )+ (func $1 (param $0 f64) (param $1 f64) (result f64)+ (loop $label$2+ (br_if $label$2+ (f64.eq+ (f64.add+ (f64.sub+ (f64.add+ (local.tee $0+ (f64.add+ (local.get $0)+ (local.get $0)+ )+ )+ (f64.const 1)+ )+ (local.get $0)+ )+ (f64.const -1)+ )+ (f64.const 0)+ )+ )+ )+ (loop $label$3+ (br_if $label$3+ (f64.ne+ (f64.sub+ (f64.sub+ (f64.add+ (local.get $0)+ (local.tee $1+ (f64.add+ (local.get $1)+ (f64.const 1)+ )+ )+ )+ (local.get $0)+ )+ (local.get $1)+ )+ (f64.const 0)+ )+ )+ )+ (local.get $1)+ )+)
+ binaryen/test/passes/dce_vacuum_remove-unused-names.txt view
@@ -0,0 +1,25 @@+(module+ (type $none_=>_i32 (func (result i32)))+ (type $i64_=>_i64 (func (param i64) (result i64)))+ (type $f32_f32_=>_f32 (func (param f32 f32) (result f32)))+ (func $__Z12serveroptionPc (result i32)+ (return+ (i32.const 0)+ )+ )+ (func $drop-unreachable (param $var$0 f32) (param $var$1 f32) (result f32)+ (unreachable)+ )+ (func $set-unreachable (param $var$0 i64) (result i64)+ (local $var$1 i64)+ (local $var$2 i64)+ (if+ (i64.eq+ (local.get $var$1)+ (i64.const 0)+ )+ (unreachable)+ (unreachable)+ )+ )+)
+ binaryen/test/passes/dce_vacuum_remove-unused-names.wasm view
binary file changed (absent → 260 bytes)
+ binaryen/test/passes/dce_vacuum_remove-unused-names.wast view
@@ -0,0 +1,51 @@+(module+ (func $__Z12serveroptionPc (result i32)+ (block $switch$0+ (return+ (i32.const 0)+ )+ (br $switch$0)+ )+ (return+ (i32.const 0)+ )+ )+ (func $drop-unreachable (param $var$0 f32) (param $var$1 f32) (result f32)+ (block $label$0 (result f32)+ (loop $label$2+ (drop+ (unreachable)+ )+ (unreachable)+ )+ (local.get $var$1)+ )+ )++ (func $set-unreachable (param $var$0 i64) (result i64)+ (local $var$1 i64)+ (local $var$2 i64)+ (block $label$0 (result i64)+ (block $label$1+ (loop $label$2+ (if+ (i64.eq+ (local.get $var$1)+ (i64.const 0)+ )+ (unreachable)+ (local.set $var$2+ (i64.mul+ (unreachable)+ (local.get $var$2)+ )+ )+ )+ (br $label$2)+ )+ )+ (local.get $var$2)+ )+ )+)+
+ binaryen/test/passes/directize_all-features.txt view
@@ -0,0 +1,223 @@+(module+ (type $i32_i32_=>_none (func (param i32 i32)))+ (table $0 5 5 funcref)+ (elem (i32.const 1) $foo)+ (func $foo (param $0 i32) (param $1 i32)+ (unreachable)+ )+ (func $bar (param $x i32) (param $y i32)+ (call $foo+ (local.get $x)+ (local.get $y)+ )+ )+)+(module+ (type $i32_i32_=>_none (func (param i32 i32)))+ (table $0 5 5 funcref)+ (elem (i32.const 4) $foo)+ (func $foo (param $0 i32) (param $1 i32)+ (unreachable)+ )+ (func $bar (param $x i32) (param $y i32)+ (call $foo+ (local.get $x)+ (local.get $y)+ )+ )+)+(module+ (type $i32_i32_=>_none (func (param i32 i32)))+ (table $0 5 5 funcref)+ (elem (i32.const 0) $foo)+ (func $foo (param $0 i32) (param $1 i32)+ (unreachable)+ )+ (func $bar (param $x i32) (param $y i32)+ (call $foo+ (local.get $x)+ (local.get $y)+ )+ )+)+(module+ (type $i32_i32_=>_none (func (param i32 i32)))+ (table $0 5 5 funcref)+ (elem (i32.const 0) $foo $foo $foo $foo $foo)+ (func $foo (param $0 i32) (param $1 i32)+ (unreachable)+ )+ (func $bar (param $x i32) (param $y i32)+ (call $foo+ (local.get $x)+ (local.get $y)+ )+ )+)+(module+ (type $i32_i32_=>_none (func (param i32 i32)))+ (import "env" "table" (table $table 5 5 funcref))+ (elem (i32.const 1) $foo)+ (func $foo (param $0 i32) (param $1 i32)+ (unreachable)+ )+ (func $bar (param $x i32) (param $y i32)+ (call_indirect (type $i32_i32_=>_none)+ (local.get $x)+ (local.get $y)+ (i32.const 1)+ )+ )+)+(module+ (type $i32_i32_=>_none (func (param i32 i32)))+ (table $0 5 5 funcref)+ (elem (i32.const 1) $foo)+ (export "tab" (table $0))+ (func $foo (param $0 i32) (param $1 i32)+ (unreachable)+ )+ (func $bar (param $x i32) (param $y i32)+ (call_indirect (type $i32_i32_=>_none)+ (local.get $x)+ (local.get $y)+ (i32.const 1)+ )+ )+)+(module+ (type $i32_i32_=>_none (func (param i32 i32)))+ (table $0 5 5 funcref)+ (elem (global.get $g) $foo)+ (global $g (mut i32) (i32.const 1))+ (func $foo (param $0 i32) (param $1 i32)+ (unreachable)+ )+ (func $bar (param $x i32) (param $y i32)+ (call_indirect (type $i32_i32_=>_none)+ (local.get $x)+ (local.get $y)+ (i32.const 1)+ )+ )+)+(module+ (type $i32_i32_=>_none (func (param i32 i32)))+ (type $i32_i32_i32_=>_none (func (param i32 i32 i32)))+ (table $0 5 5 funcref)+ (elem (i32.const 1) $foo)+ (func $foo (param $0 i32) (param $1 i32)+ (unreachable)+ )+ (func $bar (param $x i32) (param $y i32) (param $z i32)+ (call_indirect (type $i32_i32_=>_none)+ (local.get $x)+ (local.get $y)+ (local.get $z)+ )+ )+)+(module+ (type $i32_i32_=>_none (func (param i32 i32)))+ (table $0 5 5 funcref)+ (elem (i32.const 1) $foo)+ (func $foo (param $0 i32) (param $1 i32)+ (unreachable)+ )+ (func $bar (param $x i32) (param $y i32)+ (block+ (drop+ (local.get $x)+ )+ (drop+ (local.get $y)+ )+ )+ (unreachable)+ )+)+(module+ (type $i32_i32_=>_none (func (param i32 i32)))+ (table $0 5 5 funcref)+ (elem (i32.const 1) $foo)+ (func $foo (param $0 i32) (param $1 i32)+ (unreachable)+ )+ (func $bar (param $x i32) (param $y i32)+ (block+ (drop+ (local.get $x)+ )+ (drop+ (local.get $y)+ )+ )+ (unreachable)+ )+)+(module+ (type $i32_=>_none (func (param i32)))+ (type $i32_i32_=>_none (func (param i32 i32)))+ (table $0 5 5 funcref)+ (elem (i32.const 1) $foo)+ (func $foo (param $0 i32)+ (unreachable)+ )+ (func $bar (param $x i32) (param $y i32)+ (block+ (drop+ (local.get $x)+ )+ (drop+ (local.get $y)+ )+ )+ (unreachable)+ )+)+(module+ (type $i32_=>_none (func (param i32)))+ (func $foo (param $0 i32)+ (unreachable)+ )+)+(module+ (type $none_=>_none (func))+ (table $0 8 8 funcref)+ (func $0+ (block $block+ (nop)+ (block+ (block+ )+ (unreachable)+ )+ )+ )+)+(module+ (type $i32_i32_=>_none (func (param i32 i32)))+ (table $0 5 5 funcref)+ (elem (i32.const 1) $foo)+ (func $foo (param $0 i32) (param $1 i32)+ (unreachable)+ )+ (func $bar (param $x i32) (param $y i32)+ (return_call $foo+ (local.get $x)+ (local.get $y)+ )+ )+)+(module+ (type $i32_i32_=>_none (func (param i32 i32)))+ (func $foo (param $0 i32) (param $1 i32)+ (unreachable)+ )+ (func $bar (param $x i32) (param $y i32)+ (call $foo+ (local.get $x)+ (local.get $y)+ )+ )+)
+ binaryen/test/passes/directize_all-features.wast view
@@ -0,0 +1,223 @@+(module+ (type $ii (func (param i32 i32)))+ (table $0 5 5 funcref)+ (elem (i32.const 1) $foo)+ (func $foo (param i32) (param i32)+ (unreachable)+ )+ (func $bar (param $x i32) (param $y i32)+ (call_indirect (type $ii)+ (local.get $x)+ (local.get $y)+ (i32.const 1)+ )+ )+)+;; at table edges+(module+ (type $ii (func (param i32 i32)))+ (table $0 5 5 funcref)+ (elem (i32.const 4) $foo)+ (func $foo (param i32) (param i32)+ (unreachable)+ )+ (func $bar (param $x i32) (param $y i32)+ (call_indirect (type $ii)+ (local.get $x)+ (local.get $y)+ (i32.const 4)+ )+ )+)+(module+ (type $ii (func (param i32 i32)))+ (table $0 5 5 funcref)+ (elem (i32.const 0) $foo)+ (func $foo (param i32) (param i32)+ (unreachable)+ )+ (func $bar (param $x i32) (param $y i32)+ (call_indirect (type $ii)+ (local.get $x)+ (local.get $y)+ (i32.const 0)+ )+ )+)+(module+ (type $ii (func (param i32 i32)))+ (table $0 5 5 funcref)+ (elem (i32.const 0) $foo $foo $foo $foo $foo)+ (func $foo (param i32) (param i32)+ (unreachable)+ )+ (func $bar (param $x i32) (param $y i32)+ (call_indirect (type $ii)+ (local.get $x)+ (local.get $y)+ (i32.const 2)+ )+ )+)+;; imported table+(module+ (type $ii (func (param i32 i32)))+ (import "env" "table" (table $table 5 5 funcref))+ (elem (i32.const 1) $foo)+ (func $foo (param i32) (param i32)+ (unreachable)+ )+ (func $bar (param $x i32) (param $y i32)+ (call_indirect (type $ii)+ (local.get $x)+ (local.get $y)+ (i32.const 1)+ )+ )+)+;; exported table+(module+ (type $ii (func (param i32 i32)))+ (table $0 5 5 funcref)+ (export "tab" (table $0))+ (elem (i32.const 1) $foo)+ (func $foo (param i32) (param i32)+ (unreachable)+ )+ (func $bar (param $x i32) (param $y i32)+ (call_indirect (type $ii)+ (local.get $x)+ (local.get $y)+ (i32.const 1)+ )+ )+)+;; non-constant table offset+(module+ (type $ii (func (param i32 i32)))+ (table $0 5 5 funcref)+ (global $g (mut i32) (i32.const 1))+ (elem (global.get $g) $foo)+ (func $foo (param i32) (param i32)+ (unreachable)+ )+ (func $bar (param $x i32) (param $y i32)+ (call_indirect (type $ii)+ (local.get $x)+ (local.get $y)+ (i32.const 1)+ )+ )+)+;; non-constant call index+(module+ (type $ii (func (param i32 i32)))+ (table $0 5 5 funcref)+ (elem (i32.const 1) $foo)+ (func $foo (param i32) (param i32)+ (unreachable)+ )+ (func $bar (param $x i32) (param $y i32) (param $z i32)+ (call_indirect (type $ii)+ (local.get $x)+ (local.get $y)+ (local.get $z)+ )+ )+)+;; bad index+(module+ (type $ii (func (param i32 i32)))+ (table $0 5 5 funcref)+ (elem (i32.const 1) $foo)+ (func $foo (param i32) (param i32)+ (unreachable)+ )+ (func $bar (param $x i32) (param $y i32)+ (call_indirect (type $ii)+ (local.get $x)+ (local.get $y)+ (i32.const 5)+ )+ )+)+;; missing index+(module+ (type $ii (func (param i32 i32)))+ (table $0 5 5 funcref)+ (elem (i32.const 1) $foo)+ (func $foo (param i32) (param i32)+ (unreachable)+ )+ (func $bar (param $x i32) (param $y i32)+ (call_indirect (type $ii)+ (local.get $x)+ (local.get $y)+ (i32.const 2)+ )+ )+)+;; bad type+(module+ (type $ii (func (param i32 i32)))+ (table $0 5 5 funcref)+ (elem (i32.const 1) $foo)+ (func $foo (param i32)+ (unreachable)+ )+ (func $bar (param $x i32) (param $y i32)+ (call_indirect (type $ii)+ (local.get $x)+ (local.get $y)+ (i32.const 1)+ )+ )+)+;; no table+(module+ (func $foo (param i32)+ (unreachable)+ )+)+;; change types+(module+ (type (func))+ (table $0 8 8 funcref)+ (func $0+ (block ;; the type of this block will change+ (nop)+ (call_indirect (type 0)+ (i32.const 15)+ )+ )+ )+)+(module ;; indirect tail call+ (type $ii (func (param i32 i32)))+ (table $0 5 5 funcref)+ (elem (i32.const 1) $foo)+ (func $foo (param i32) (param i32)+ (unreachable)+ )+ (func $bar (param $x i32) (param $y i32)+ (return_call_indirect (type $ii)+ (local.get $x)+ (local.get $y)+ (i32.const 1)+ )+ )+)+;; call_ref+(module+ (func $foo (param i32) (param i32)+ (unreachable)+ )+ (func $bar (param $x i32) (param $y i32)+ (call_ref+ (local.get $x)+ (local.get $y)+ (ref.func $foo)+ )+ )+)+
− binaryen/test/passes/directize_enable-tail-call.txt
@@ -1,211 +0,0 @@-(module- (type $i32_i32_=>_none (func (param i32 i32)))- (table $0 5 5 funcref)- (elem (i32.const 1) $foo)- (func $foo (param $0 i32) (param $1 i32)- (unreachable)- )- (func $bar (param $x i32) (param $y i32)- (call $foo- (local.get $x)- (local.get $y)- )- )-)-(module- (type $i32_i32_=>_none (func (param i32 i32)))- (table $0 5 5 funcref)- (elem (i32.const 4) $foo)- (func $foo (param $0 i32) (param $1 i32)- (unreachable)- )- (func $bar (param $x i32) (param $y i32)- (call $foo- (local.get $x)- (local.get $y)- )- )-)-(module- (type $i32_i32_=>_none (func (param i32 i32)))- (table $0 5 5 funcref)- (elem (i32.const 0) $foo)- (func $foo (param $0 i32) (param $1 i32)- (unreachable)- )- (func $bar (param $x i32) (param $y i32)- (call $foo- (local.get $x)- (local.get $y)- )- )-)-(module- (type $i32_i32_=>_none (func (param i32 i32)))- (table $0 5 5 funcref)- (elem (i32.const 0) $foo $foo $foo $foo $foo)- (func $foo (param $0 i32) (param $1 i32)- (unreachable)- )- (func $bar (param $x i32) (param $y i32)- (call $foo- (local.get $x)- (local.get $y)- )- )-)-(module- (type $i32_i32_=>_none (func (param i32 i32)))- (import "env" "table" (table $table 5 5 funcref))- (elem (i32.const 1) $foo)- (func $foo (param $0 i32) (param $1 i32)- (unreachable)- )- (func $bar (param $x i32) (param $y i32)- (call_indirect (type $i32_i32_=>_none)- (local.get $x)- (local.get $y)- (i32.const 1)- )- )-)-(module- (type $i32_i32_=>_none (func (param i32 i32)))- (table $0 5 5 funcref)- (elem (i32.const 1) $foo)- (export "tab" (table $0))- (func $foo (param $0 i32) (param $1 i32)- (unreachable)- )- (func $bar (param $x i32) (param $y i32)- (call_indirect (type $i32_i32_=>_none)- (local.get $x)- (local.get $y)- (i32.const 1)- )- )-)-(module- (type $i32_i32_=>_none (func (param i32 i32)))- (table $0 5 5 funcref)- (elem (global.get $g) $foo)- (global $g (mut i32) (i32.const 1))- (func $foo (param $0 i32) (param $1 i32)- (unreachable)- )- (func $bar (param $x i32) (param $y i32)- (call_indirect (type $i32_i32_=>_none)- (local.get $x)- (local.get $y)- (i32.const 1)- )- )-)-(module- (type $i32_i32_=>_none (func (param i32 i32)))- (type $i32_i32_i32_=>_none (func (param i32 i32 i32)))- (table $0 5 5 funcref)- (elem (i32.const 1) $foo)- (func $foo (param $0 i32) (param $1 i32)- (unreachable)- )- (func $bar (param $x i32) (param $y i32) (param $z i32)- (call_indirect (type $i32_i32_=>_none)- (local.get $x)- (local.get $y)- (local.get $z)- )- )-)-(module- (type $i32_i32_=>_none (func (param i32 i32)))- (table $0 5 5 funcref)- (elem (i32.const 1) $foo)- (func $foo (param $0 i32) (param $1 i32)- (unreachable)- )- (func $bar (param $x i32) (param $y i32)- (block- (drop- (local.get $x)- )- (drop- (local.get $y)- )- )- (unreachable)- )-)-(module- (type $i32_i32_=>_none (func (param i32 i32)))- (table $0 5 5 funcref)- (elem (i32.const 1) $foo)- (func $foo (param $0 i32) (param $1 i32)- (unreachable)- )- (func $bar (param $x i32) (param $y i32)- (block- (drop- (local.get $x)- )- (drop- (local.get $y)- )- )- (unreachable)- )-)-(module- (type $i32_=>_none (func (param i32)))- (type $i32_i32_=>_none (func (param i32 i32)))- (table $0 5 5 funcref)- (elem (i32.const 1) $foo)- (func $foo (param $0 i32)- (unreachable)- )- (func $bar (param $x i32) (param $y i32)- (block- (drop- (local.get $x)- )- (drop- (local.get $y)- )- )- (unreachable)- )-)-(module- (type $i32_=>_none (func (param i32)))- (func $foo (param $0 i32)- (unreachable)- )-)-(module- (type $none_=>_none (func))- (table $0 8 8 funcref)- (func $0- (block $block- (nop)- (block- (block- )- (unreachable)- )- )- )-)-(module- (type $i32_i32_=>_none (func (param i32 i32)))- (table $0 5 5 funcref)- (elem (i32.const 1) $foo)- (func $foo (param $0 i32) (param $1 i32)- (unreachable)- )- (func $bar (param $x i32) (param $y i32)- (return_call $foo- (local.get $x)- (local.get $y)- )- )-)
− binaryen/test/passes/directize_enable-tail-call.wast
@@ -1,209 +0,0 @@-(module- (type $ii (func (param i32 i32)))- (table $0 5 5 funcref)- (elem (i32.const 1) $foo)- (func $foo (param i32) (param i32)- (unreachable)- )- (func $bar (param $x i32) (param $y i32)- (call_indirect (type $ii)- (local.get $x)- (local.get $y)- (i32.const 1)- )- )-)-;; at table edges-(module- (type $ii (func (param i32 i32)))- (table $0 5 5 funcref)- (elem (i32.const 4) $foo)- (func $foo (param i32) (param i32)- (unreachable)- )- (func $bar (param $x i32) (param $y i32)- (call_indirect (type $ii)- (local.get $x)- (local.get $y)- (i32.const 4)- )- )-)-(module- (type $ii (func (param i32 i32)))- (table $0 5 5 funcref)- (elem (i32.const 0) $foo)- (func $foo (param i32) (param i32)- (unreachable)- )- (func $bar (param $x i32) (param $y i32)- (call_indirect (type $ii)- (local.get $x)- (local.get $y)- (i32.const 0)- )- )-)-(module- (type $ii (func (param i32 i32)))- (table $0 5 5 funcref)- (elem (i32.const 0) $foo $foo $foo $foo $foo)- (func $foo (param i32) (param i32)- (unreachable)- )- (func $bar (param $x i32) (param $y i32)- (call_indirect (type $ii)- (local.get $x)- (local.get $y)- (i32.const 2)- )- )-)-;; imported table-(module- (type $ii (func (param i32 i32)))- (import "env" "table" (table $table 5 5 funcref))- (elem (i32.const 1) $foo)- (func $foo (param i32) (param i32)- (unreachable)- )- (func $bar (param $x i32) (param $y i32)- (call_indirect (type $ii)- (local.get $x)- (local.get $y)- (i32.const 1)- )- )-)-;; exported table-(module- (type $ii (func (param i32 i32)))- (table $0 5 5 funcref)- (export "tab" (table $0))- (elem (i32.const 1) $foo)- (func $foo (param i32) (param i32)- (unreachable)- )- (func $bar (param $x i32) (param $y i32)- (call_indirect (type $ii)- (local.get $x)- (local.get $y)- (i32.const 1)- )- )-)-;; non-constant table offset-(module- (type $ii (func (param i32 i32)))- (table $0 5 5 funcref)- (global $g (mut i32) (i32.const 1))- (elem (global.get $g) $foo)- (func $foo (param i32) (param i32)- (unreachable)- )- (func $bar (param $x i32) (param $y i32)- (call_indirect (type $ii)- (local.get $x)- (local.get $y)- (i32.const 1)- )- )-)-;; non-constant call index-(module- (type $ii (func (param i32 i32)))- (table $0 5 5 funcref)- (elem (i32.const 1) $foo)- (func $foo (param i32) (param i32)- (unreachable)- )- (func $bar (param $x i32) (param $y i32) (param $z i32)- (call_indirect (type $ii)- (local.get $x)- (local.get $y)- (local.get $z)- )- )-)-;; bad index-(module- (type $ii (func (param i32 i32)))- (table $0 5 5 funcref)- (elem (i32.const 1) $foo)- (func $foo (param i32) (param i32)- (unreachable)- )- (func $bar (param $x i32) (param $y i32)- (call_indirect (type $ii)- (local.get $x)- (local.get $y)- (i32.const 5)- )- )-)-;; missing index-(module- (type $ii (func (param i32 i32)))- (table $0 5 5 funcref)- (elem (i32.const 1) $foo)- (func $foo (param i32) (param i32)- (unreachable)- )- (func $bar (param $x i32) (param $y i32)- (call_indirect (type $ii)- (local.get $x)- (local.get $y)- (i32.const 2)- )- )-)-;; bad type-(module- (type $ii (func (param i32 i32)))- (table $0 5 5 funcref)- (elem (i32.const 1) $foo)- (func $foo (param i32)- (unreachable)- )- (func $bar (param $x i32) (param $y i32)- (call_indirect (type $ii)- (local.get $x)- (local.get $y)- (i32.const 1)- )- )-)-;; no table-(module- (func $foo (param i32)- (unreachable)- )-)-;; change types-(module- (type (func))- (table $0 8 8 funcref)- (func $0- (block ;; the type of this block will change- (nop)- (call_indirect (type 0)- (i32.const 15)- )- )- )-)-(module ;; indirect tail call- (type $ii (func (param i32 i32)))- (table $0 5 5 funcref)- (elem (i32.const 1) $foo)- (func $foo (param i32) (param i32)- (unreachable)- )- (func $bar (param $x i32) (param $y i32)- (return_call_indirect (type $ii)- (local.get $x)- (local.get $y)- (i32.const 1)- )- )-)
binaryen/test/passes/fannkuch0_dwarf.bin.txt view
@@ -5197,7 +5197,7 @@ (type $i32_=>_none (func (param i32))) (import "env" "memory" (memory $mimport$0 256 256)) (data (i32.const 1024) "Wrong argument.\n\00Pfannkuchen(%d) = %d.\n\00%d\00\n\00")- (import "env" "__indirect_function_table" (table $timport$1 1 funcref))+ (import "env" "__indirect_function_table" (table $timport$0 1 funcref)) (import "env" "malloc" (func $malloc (param i32) (result i32))) (import "env" "free" (func $free (param i32))) (import "env" "atoi" (func $atoi (param i32) (result i32)))
binaryen/test/passes/fannkuch3_dwarf.bin.txt view
@@ -2851,7 +2851,7 @@ 0x00000278: DW_TAG_inlined_subroutine [24] * DW_AT_abstract_origin [DW_FORM_ref4] (cu + 0x01a8 => {0x000001a8} "_ZL8fannkuchi") DW_AT_low_pc [DW_FORM_addr] (0x00000000000003ec)- DW_AT_high_pc [DW_FORM_data4] (0x0000026c)+ DW_AT_high_pc [DW_FORM_data4] (0x0000029e) DW_AT_call_file [DW_FORM_data1] ("/usr/local/google/home/azakai/Dev/emscripten/tests/fannkuch.cpp") DW_AT_call_line [DW_FORM_data1] (159) DW_AT_call_column [DW_FORM_data1] (0x29)@@ -4797,7 +4797,7 @@ (type $i32_i32_i32_=>_i32 (func (param i32 i32 i32) (result i32))) (import "env" "memory" (memory $mimport$0 256 256)) (data (i32.const 1024) "Pfannkuchen(%d) = %d.\n\00%d\00Wrong argument.\00")- (import "env" "__indirect_function_table" (table $timport$1 1 funcref))+ (import "env" "__indirect_function_table" (table $timport$0 1 funcref)) (import "env" "malloc" (func $malloc (param i32) (result i32))) (import "env" "memcpy" (func $memcpy (param i32 i32 i32) (result i32))) (import "env" "free" (func $free (param i32)))
binaryen/test/passes/fannkuch3_manyopts_dwarf.bin.txt view
@@ -2303,7 +2303,7 @@ Contains section .debug_loc (1073 bytes) Contains section .debug_ranges (88 bytes) Contains section .debug_abbrev (333 bytes)-Contains section .debug_line (2702 bytes)+Contains section .debug_line (2682 bytes) Contains section .debug_str (434 bytes) .debug_abbrev contents:@@ -3119,7 +3119,7 @@ .debug_line contents: debug_line[0x00000000] Line table prologue:- total_length: 0x00000a8a+ total_length: 0x00000a76 version: 4 prologue_length: 0x000000dd min_inst_length: 1@@ -4364,299 +4364,287 @@ 0x0000000000000547 122 14 1 0 0 -0x000008a5: 00 DW_LNE_set_address (0x000000000000054c)-0x000008ac: 03 DW_LNS_advance_line (130)-0x000008ae: 06 DW_LNS_negate_stmt-0x000008af: 01 DW_LNS_copy- 0x000000000000054c 130 14 1 0 0 is_stmt---0x000008b0: 00 DW_LNE_set_address (0x000000000000054d)-0x000008b7: 03 DW_LNS_advance_line (110)-0x000008b9: 05 DW_LNS_set_column (11)-0x000008bb: 01 DW_LNS_copy+0x000008a5: 00 DW_LNE_set_address (0x000000000000054d)+0x000008ac: 03 DW_LNS_advance_line (110)+0x000008ae: 05 DW_LNS_set_column (11)+0x000008b0: 06 DW_LNS_negate_stmt+0x000008b1: 01 DW_LNS_copy 0x000000000000054d 110 11 1 0 0 is_stmt -0x000008bc: 00 DW_LNE_set_address (0x0000000000000559)-0x000008c3: 03 DW_LNS_advance_line (113)-0x000008c5: 05 DW_LNS_set_column (10)-0x000008c7: 01 DW_LNS_copy+0x000008b2: 00 DW_LNE_set_address (0x0000000000000559)+0x000008b9: 03 DW_LNS_advance_line (113)+0x000008bb: 05 DW_LNS_set_column (10)+0x000008bd: 01 DW_LNS_copy 0x0000000000000559 113 10 1 0 0 is_stmt -0x000008c8: 00 DW_LNE_set_address (0x000000000000055c)-0x000008cf: 03 DW_LNS_advance_line (118)-0x000008d1: 05 DW_LNS_set_column (16)-0x000008d3: 01 DW_LNS_copy+0x000008be: 00 DW_LNE_set_address (0x000000000000055c)+0x000008c5: 03 DW_LNS_advance_line (118)+0x000008c7: 05 DW_LNS_set_column (16)+0x000008c9: 01 DW_LNS_copy 0x000000000000055c 118 16 1 0 0 is_stmt -0x000008d4: 00 DW_LNE_set_address (0x0000000000000565)-0x000008db: 03 DW_LNS_advance_line (119)-0x000008dd: 05 DW_LNS_set_column (10)-0x000008df: 01 DW_LNS_copy+0x000008ca: 00 DW_LNE_set_address (0x0000000000000565)+0x000008d1: 03 DW_LNS_advance_line (119)+0x000008d3: 05 DW_LNS_set_column (10)+0x000008d5: 01 DW_LNS_copy 0x0000000000000565 119 10 1 0 0 is_stmt -0x000008e0: 00 DW_LNE_set_address (0x0000000000000567)-0x000008e7: 05 DW_LNS_set_column (18)-0x000008e9: 06 DW_LNS_negate_stmt-0x000008ea: 01 DW_LNS_copy+0x000008d6: 00 DW_LNE_set_address (0x0000000000000567)+0x000008dd: 05 DW_LNS_set_column (18)+0x000008df: 06 DW_LNS_negate_stmt+0x000008e0: 01 DW_LNS_copy 0x0000000000000567 119 18 1 0 0 -0x000008eb: 00 DW_LNE_set_address (0x0000000000000570)-0x000008f2: 05 DW_LNS_set_column (10)-0x000008f4: 01 DW_LNS_copy+0x000008e1: 00 DW_LNE_set_address (0x0000000000000570)+0x000008e8: 05 DW_LNS_set_column (10)+0x000008ea: 01 DW_LNS_copy 0x0000000000000570 119 10 1 0 0 -0x000008f5: 00 DW_LNE_set_address (0x0000000000000572)-0x000008fc: 05 DW_LNS_set_column (23)-0x000008fe: 01 DW_LNS_copy+0x000008eb: 00 DW_LNE_set_address (0x0000000000000572)+0x000008f2: 05 DW_LNS_set_column (23)+0x000008f4: 01 DW_LNS_copy 0x0000000000000572 119 23 1 0 0 -0x000008ff: 00 DW_LNE_set_address (0x0000000000000577)-0x00000906: 03 DW_LNS_advance_line (118)-0x00000908: 05 DW_LNS_set_column (16)-0x0000090a: 06 DW_LNS_negate_stmt-0x0000090b: 01 DW_LNS_copy+0x000008f5: 00 DW_LNE_set_address (0x0000000000000577)+0x000008fc: 03 DW_LNS_advance_line (118)+0x000008fe: 05 DW_LNS_set_column (16)+0x00000900: 06 DW_LNS_negate_stmt+0x00000901: 01 DW_LNS_copy 0x0000000000000577 118 16 1 0 0 is_stmt -0x0000090c: 00 DW_LNE_set_address (0x0000000000000582)-0x00000913: 05 DW_LNS_set_column (7)-0x00000915: 06 DW_LNS_negate_stmt-0x00000916: 01 DW_LNS_copy+0x00000902: 00 DW_LNE_set_address (0x0000000000000582)+0x00000909: 05 DW_LNS_set_column (7)+0x0000090b: 06 DW_LNS_negate_stmt+0x0000090c: 01 DW_LNS_copy 0x0000000000000582 118 7 1 0 0 -0x00000917: 00 DW_LNE_set_address (0x0000000000000588)-0x0000091e: 03 DW_LNS_advance_line (122)-0x00000920: 05 DW_LNS_set_column (16)-0x00000922: 06 DW_LNS_negate_stmt-0x00000923: 01 DW_LNS_copy+0x0000090d: 00 DW_LNE_set_address (0x0000000000000588)+0x00000914: 03 DW_LNS_advance_line (122)+0x00000916: 05 DW_LNS_set_column (16)+0x00000918: 06 DW_LNS_negate_stmt+0x00000919: 01 DW_LNS_copy 0x0000000000000588 122 16 1 0 0 is_stmt -0x00000924: 00 DW_LNE_set_address (0x000000000000058d)-0x0000092b: 05 DW_LNS_set_column (14)-0x0000092d: 06 DW_LNS_negate_stmt-0x0000092e: 01 DW_LNS_copy+0x0000091a: 00 DW_LNE_set_address (0x000000000000058d)+0x00000921: 05 DW_LNS_set_column (14)+0x00000923: 06 DW_LNS_negate_stmt+0x00000924: 01 DW_LNS_copy 0x000000000000058d 122 14 1 0 0 -0x0000092f: 00 DW_LNE_set_address (0x0000000000000596)-0x00000936: 03 DW_LNS_advance_line (125)-0x00000938: 05 DW_LNS_set_column (22)-0x0000093a: 06 DW_LNS_negate_stmt-0x0000093b: 01 DW_LNS_copy+0x00000925: 00 DW_LNE_set_address (0x0000000000000596)+0x0000092c: 03 DW_LNS_advance_line (125)+0x0000092e: 05 DW_LNS_set_column (22)+0x00000930: 06 DW_LNS_negate_stmt+0x00000931: 01 DW_LNS_copy 0x0000000000000596 125 22 1 0 0 is_stmt -0x0000093c: 00 DW_LNE_set_address (0x00000000000005a3)-0x00000943: 03 DW_LNS_advance_line (126)-0x00000945: 05 DW_LNS_set_column (27)-0x00000947: 01 DW_LNS_copy+0x00000932: 00 DW_LNE_set_address (0x00000000000005a3)+0x00000939: 03 DW_LNS_advance_line (126)+0x0000093b: 05 DW_LNS_set_column (27)+0x0000093d: 01 DW_LNS_copy 0x00000000000005a3 126 27 1 0 0 is_stmt -0x00000948: 00 DW_LNE_set_address (0x00000000000005ac)-0x0000094f: 03 DW_LNS_advance_line (127)-0x00000951: 05 DW_LNS_set_column (16)-0x00000953: 01 DW_LNS_copy+0x0000093e: 00 DW_LNE_set_address (0x00000000000005ac)+0x00000945: 03 DW_LNS_advance_line (127)+0x00000947: 05 DW_LNS_set_column (16)+0x00000949: 01 DW_LNS_copy 0x00000000000005ac 127 16 1 0 0 is_stmt -0x00000954: 00 DW_LNE_set_address (0x00000000000005b4)-0x0000095b: 05 DW_LNS_set_column (27)-0x0000095d: 06 DW_LNS_negate_stmt-0x0000095e: 01 DW_LNS_copy+0x0000094a: 00 DW_LNE_set_address (0x00000000000005b4)+0x00000951: 05 DW_LNS_set_column (27)+0x00000953: 06 DW_LNS_negate_stmt+0x00000954: 01 DW_LNS_copy 0x00000000000005b4 127 27 1 0 0 -0x0000095f: 00 DW_LNE_set_address (0x00000000000005b6)-0x00000966: 05 DW_LNS_set_column (35)-0x00000968: 01 DW_LNS_copy+0x00000955: 00 DW_LNE_set_address (0x00000000000005b6)+0x0000095c: 05 DW_LNS_set_column (35)+0x0000095e: 01 DW_LNS_copy 0x00000000000005b6 127 35 1 0 0 -0x00000969: 00 DW_LNE_set_address (0x00000000000005bf)-0x00000970: 05 DW_LNS_set_column (27)-0x00000972: 01 DW_LNS_copy+0x0000095f: 00 DW_LNE_set_address (0x00000000000005bf)+0x00000966: 05 DW_LNS_set_column (27)+0x00000968: 01 DW_LNS_copy 0x00000000000005bf 127 27 1 0 0 -0x00000973: 00 DW_LNE_set_address (0x00000000000005c4)-0x0000097a: 05 DW_LNS_set_column (25)-0x0000097c: 01 DW_LNS_copy+0x00000969: 00 DW_LNE_set_address (0x00000000000005c4)+0x00000970: 05 DW_LNS_set_column (25)+0x00000972: 01 DW_LNS_copy 0x00000000000005c4 127 25 1 0 0 -0x0000097d: 00 DW_LNE_set_address (0x00000000000005c7)-0x00000984: 03 DW_LNS_advance_line (126)-0x00000986: 05 DW_LNS_set_column (27)-0x00000988: 06 DW_LNS_negate_stmt-0x00000989: 01 DW_LNS_copy+0x00000973: 00 DW_LNE_set_address (0x00000000000005c7)+0x0000097a: 03 DW_LNS_advance_line (126)+0x0000097c: 05 DW_LNS_set_column (27)+0x0000097e: 06 DW_LNS_negate_stmt+0x0000097f: 01 DW_LNS_copy 0x00000000000005c7 126 27 1 0 0 is_stmt -0x0000098a: 00 DW_LNE_set_address (0x00000000000005cc)-0x00000991: 05 DW_LNS_set_column (13)-0x00000993: 06 DW_LNS_negate_stmt-0x00000994: 01 DW_LNS_copy+0x00000980: 00 DW_LNE_set_address (0x00000000000005cc)+0x00000987: 05 DW_LNS_set_column (13)+0x00000989: 06 DW_LNS_negate_stmt+0x0000098a: 01 DW_LNS_copy 0x00000000000005cc 126 13 1 0 0 -0x00000995: 00 DW_LNE_set_address (0x00000000000005d4)-0x0000099c: 03 DW_LNS_advance_line (128)-0x0000099e: 06 DW_LNS_negate_stmt-0x0000099f: 01 DW_LNS_copy+0x0000098b: 00 DW_LNE_set_address (0x00000000000005d4)+0x00000992: 03 DW_LNS_advance_line (128)+0x00000994: 06 DW_LNS_negate_stmt+0x00000995: 01 DW_LNS_copy 0x00000000000005d4 128 13 1 0 0 is_stmt -0x000009a0: 00 DW_LNE_set_address (0x00000000000005dc)-0x000009a7: 05 DW_LNS_set_column (22)-0x000009a9: 06 DW_LNS_negate_stmt-0x000009aa: 01 DW_LNS_copy+0x00000996: 00 DW_LNE_set_address (0x00000000000005dc)+0x0000099d: 05 DW_LNS_set_column (22)+0x0000099f: 06 DW_LNS_negate_stmt+0x000009a0: 01 DW_LNS_copy 0x00000000000005dc 128 22 1 0 0 -0x000009ab: 00 DW_LNE_set_address (0x00000000000005e1)-0x000009b2: 03 DW_LNS_advance_line (130)-0x000009b4: 05 DW_LNS_set_column (16)-0x000009b6: 06 DW_LNS_negate_stmt-0x000009b7: 01 DW_LNS_copy+0x000009a1: 00 DW_LNE_set_address (0x00000000000005e1)+0x000009a8: 03 DW_LNS_advance_line (130)+0x000009aa: 05 DW_LNS_set_column (16)+0x000009ac: 06 DW_LNS_negate_stmt+0x000009ad: 01 DW_LNS_copy 0x00000000000005e1 130 16 1 0 0 is_stmt -0x000009b8: 00 DW_LNE_set_address (0x00000000000005e9)-0x000009bf: 05 DW_LNS_set_column (14)-0x000009c1: 06 DW_LNS_negate_stmt-0x000009c2: 01 DW_LNS_copy+0x000009ae: 00 DW_LNE_set_address (0x00000000000005e9)+0x000009b5: 05 DW_LNS_set_column (14)+0x000009b7: 06 DW_LNS_negate_stmt+0x000009b8: 01 DW_LNS_copy 0x00000000000005e9 130 14 1 0 0 -0x000009c3: 00 DW_LNE_set_address (0x00000000000005f8)-0x000009ca: 05 DW_LNS_set_column (25)-0x000009cc: 01 DW_LNS_copy+0x000009b9: 00 DW_LNE_set_address (0x00000000000005f8)+0x000009c0: 05 DW_LNS_set_column (25)+0x000009c2: 01 DW_LNS_copy 0x00000000000005f8 130 25 1 0 0 -0x000009cd: 00 DW_LNE_set_address (0x00000000000005ff)-0x000009d4: 03 DW_LNS_advance_line (133)-0x000009d6: 05 DW_LNS_set_column (11)-0x000009d8: 06 DW_LNS_negate_stmt-0x000009d9: 01 DW_LNS_copy+0x000009c3: 00 DW_LNE_set_address (0x00000000000005ff)+0x000009ca: 03 DW_LNS_advance_line (133)+0x000009cc: 05 DW_LNS_set_column (11)+0x000009ce: 06 DW_LNS_negate_stmt+0x000009cf: 01 DW_LNS_copy 0x00000000000005ff 133 11 1 0 0 is_stmt -0x000009da: 00 DW_LNE_set_address (0x0000000000000604)-0x000009e1: 03 DW_LNS_advance_line (122)-0x000009e3: 05 DW_LNS_set_column (16)-0x000009e5: 01 DW_LNS_copy+0x000009d0: 00 DW_LNE_set_address (0x0000000000000604)+0x000009d7: 03 DW_LNS_advance_line (122)+0x000009d9: 05 DW_LNS_set_column (16)+0x000009db: 01 DW_LNS_copy 0x0000000000000604 122 16 1 0 0 is_stmt -0x000009e6: 00 DW_LNE_set_address (0x0000000000000609)-0x000009ed: 05 DW_LNS_set_column (14)-0x000009ef: 06 DW_LNS_negate_stmt-0x000009f0: 01 DW_LNS_copy+0x000009dc: 00 DW_LNE_set_address (0x0000000000000609)+0x000009e3: 05 DW_LNS_set_column (14)+0x000009e5: 06 DW_LNS_negate_stmt+0x000009e6: 01 DW_LNS_copy 0x0000000000000609 122 14 1 0 0 -0x000009f1: 00 DW_LNE_set_address (0x000000000000060e)-0x000009f8: 03 DW_LNS_advance_line (130)-0x000009fa: 06 DW_LNS_negate_stmt-0x000009fb: 01 DW_LNS_copy- 0x000000000000060e 130 14 1 0 0 is_stmt---0x000009fc: 00 DW_LNE_set_address (0x000000000000060f)-0x00000a03: 03 DW_LNS_advance_line (110)-0x00000a05: 05 DW_LNS_set_column (11)-0x00000a07: 01 DW_LNS_copy+0x000009e7: 00 DW_LNE_set_address (0x000000000000060f)+0x000009ee: 03 DW_LNS_advance_line (110)+0x000009f0: 05 DW_LNS_set_column (11)+0x000009f2: 06 DW_LNS_negate_stmt+0x000009f3: 01 DW_LNS_copy 0x000000000000060f 110 11 1 0 0 is_stmt -0x00000a08: 00 DW_LNE_set_address (0x0000000000000615)-0x00000a0f: 03 DW_LNS_advance_line (138)-0x00000a11: 05 DW_LNS_set_column (4)-0x00000a13: 01 DW_LNS_copy+0x000009f4: 00 DW_LNE_set_address (0x0000000000000615)+0x000009fb: 03 DW_LNS_advance_line (138)+0x000009fd: 05 DW_LNS_set_column (4)+0x000009ff: 01 DW_LNS_copy 0x0000000000000615 138 4 1 0 0 is_stmt -0x00000a14: 00 DW_LNE_set_address (0x0000000000000619)-0x00000a1b: 03 DW_LNS_advance_line (139)-0x00000a1d: 01 DW_LNS_copy+0x00000a00: 00 DW_LNE_set_address (0x0000000000000619)+0x00000a07: 03 DW_LNS_advance_line (139)+0x00000a09: 01 DW_LNS_copy 0x0000000000000619 139 4 1 0 0 is_stmt -0x00000a1e: 00 DW_LNE_set_address (0x0000000000000629)-0x00000a25: 03 DW_LNS_advance_line (142)-0x00000a27: 05 DW_LNS_set_column (20)-0x00000a29: 01 DW_LNS_copy+0x00000a0a: 00 DW_LNE_set_address (0x0000000000000629)+0x00000a11: 03 DW_LNS_advance_line (142)+0x00000a13: 05 DW_LNS_set_column (20)+0x00000a15: 01 DW_LNS_copy 0x0000000000000629 142 20 1 0 0 is_stmt -0x00000a2a: 00 DW_LNE_set_address (0x0000000000000631)-0x00000a31: 03 DW_LNS_advance_line (146)-0x00000a33: 01 DW_LNS_copy+0x00000a16: 00 DW_LNE_set_address (0x0000000000000631)+0x00000a1d: 03 DW_LNS_advance_line (146)+0x00000a1f: 01 DW_LNS_copy 0x0000000000000631 146 20 1 0 0 is_stmt -0x00000a34: 00 DW_LNE_set_address (0x0000000000000638)-0x00000a3b: 03 DW_LNS_advance_line (147)-0x00000a3d: 05 DW_LNS_set_column (7)-0x00000a3f: 01 DW_LNS_copy+0x00000a20: 00 DW_LNE_set_address (0x0000000000000638)+0x00000a27: 03 DW_LNS_advance_line (147)+0x00000a29: 05 DW_LNS_set_column (7)+0x00000a2b: 01 DW_LNS_copy 0x0000000000000638 147 7 1 0 0 is_stmt -0x00000a40: 00 DW_LNE_set_address (0x000000000000063c)-0x00000a47: 03 DW_LNS_advance_line (143)-0x00000a49: 05 DW_LNS_set_column (11)-0x00000a4b: 01 DW_LNS_copy+0x00000a2c: 00 DW_LNE_set_address (0x000000000000063c)+0x00000a33: 03 DW_LNS_advance_line (143)+0x00000a35: 05 DW_LNS_set_column (11)+0x00000a37: 01 DW_LNS_copy 0x000000000000063c 143 11 1 0 0 is_stmt -0x00000a4c: 00 DW_LNE_set_address (0x0000000000000640)-0x00000a53: 05 DW_LNS_set_column (20)-0x00000a55: 06 DW_LNS_negate_stmt-0x00000a56: 01 DW_LNS_copy+0x00000a38: 00 DW_LNE_set_address (0x0000000000000640)+0x00000a3f: 05 DW_LNS_set_column (20)+0x00000a41: 06 DW_LNS_negate_stmt+0x00000a42: 01 DW_LNS_copy 0x0000000000000640 143 20 1 0 0 -0x00000a57: 00 DW_LNE_set_address (0x0000000000000645)-0x00000a5e: 05 DW_LNS_set_column (11)-0x00000a60: 01 DW_LNS_copy+0x00000a43: 00 DW_LNE_set_address (0x0000000000000645)+0x00000a4a: 05 DW_LNS_set_column (11)+0x00000a4c: 01 DW_LNS_copy 0x0000000000000645 143 11 1 0 0 -0x00000a61: 00 DW_LNE_set_address (0x000000000000064c)-0x00000a68: 03 DW_LNS_advance_line (141)-0x00000a6a: 05 DW_LNS_set_column (4)-0x00000a6c: 06 DW_LNS_negate_stmt-0x00000a6d: 01 DW_LNS_copy+0x00000a4d: 00 DW_LNE_set_address (0x000000000000064c)+0x00000a54: 03 DW_LNS_advance_line (141)+0x00000a56: 05 DW_LNS_set_column (4)+0x00000a58: 06 DW_LNS_negate_stmt+0x00000a59: 01 DW_LNS_copy 0x000000000000064c 141 4 1 0 0 is_stmt -0x00000a6e: 00 DW_LNE_set_address (0x0000000000000652)-0x00000a75: 03 DW_LNS_advance_line (159)-0x00000a77: 01 DW_LNS_copy+0x00000a5a: 00 DW_LNE_set_address (0x0000000000000652)+0x00000a61: 03 DW_LNS_advance_line (159)+0x00000a63: 01 DW_LNS_copy 0x0000000000000652 159 4 1 0 0 is_stmt -0x00000a78: 00 DW_LNE_set_address (0x0000000000000669)-0x00000a7f: 03 DW_LNS_advance_line (161)-0x00000a81: 05 DW_LNS_set_column (1)-0x00000a83: 01 DW_LNS_copy+0x00000a64: 00 DW_LNE_set_address (0x0000000000000669)+0x00000a6b: 03 DW_LNS_advance_line (161)+0x00000a6d: 05 DW_LNS_set_column (1)+0x00000a6f: 01 DW_LNS_copy 0x0000000000000669 161 1 1 0 0 is_stmt -0x00000a84: 00 DW_LNE_set_address (0x0000000000000673)-0x00000a8b: 00 DW_LNE_end_sequence+0x00000a70: 00 DW_LNE_set_address (0x0000000000000673)+0x00000a77: 00 DW_LNE_end_sequence 0x0000000000000673 161 1 1 0 0 is_stmt end_sequence @@ -4716,7 +4704,7 @@ (type $i32_=>_none (func (param i32))) (type $i32_i32_i32_=>_i32 (func (param i32 i32 i32) (result i32))) (import "env" "memory" (memory $mimport$0 256 256))- (data (i32.const 1024) "Pfannkuchen(%d) = %d.\n\00%d\00Wrong argument.")+ (data (i32.const 1024) "Pfannkuchen(%d) = %d.\n\00%d\00Wrong argument.\00") (import "env" "malloc" (func $malloc (param i32) (result i32))) (import "env" "memcpy" (func $memcpy (param i32 i32 i32) (result i32))) (import "env" "free" (func $free (param i32)))@@ -4862,11 +4850,11 @@ ;; code offset: 0x7d (local.tee $4 ;; code offset: 0x7c- (i32.add+ (i32.sub ;; code offset: 0x78 (local.get $2) ;; code offset: 0x7a- (i32.const -1)+ (i32.const 1) ) ) )@@ -4924,11 +4912,11 @@ ;; code offset: 0xaa (local.tee $1 ;; code offset: 0xa9- (i32.add+ (i32.sub ;; code offset: 0xa5 (local.get $2) ;; code offset: 0xa7- (i32.const -1)+ (i32.const 1) ) ) ;; code offset: 0xac@@ -5032,11 +5020,11 @@ ;; code offset: 0x101 (local.set $1 ;; code offset: 0x100- (i32.add+ (i32.sub ;; code offset: 0xfc (local.get $6) ;; code offset: 0xfe- (i32.const -1)+ (i32.const 1) ) ) ;; code offset: 0x105@@ -5114,11 +5102,11 @@ ;; code offset: 0x13d (local.tee $1 ;; code offset: 0x13c- (i32.add+ (i32.sub ;; code offset: 0x138 (local.get $1) ;; code offset: 0x13a- (i32.const -1)+ (i32.const 1) ) ) )@@ -5313,7 +5301,7 @@ ) ) ;; code offset: 0x1d5- (i32.add+ (i32.sub ;; code offset: 0x1d1 (local.tee $1 ;; code offset: 0x1ce@@ -5323,7 +5311,7 @@ ) ) ;; code offset: 0x1d3- (i32.const -1)+ (i32.const 1) ) ) ;; code offset: 0x1de@@ -5391,11 +5379,11 @@ ;; code offset: 0x20c (local.tee $4 ;; code offset: 0x20b- (i32.add+ (i32.sub ;; code offset: 0x207 (local.get $2) ;; code offset: 0x209- (i32.const -1)+ (i32.const 1) ) ) )@@ -5444,11 +5432,11 @@ ;; code offset: 0x233 (local.tee $1 ;; code offset: 0x232- (i32.add+ (i32.sub ;; code offset: 0x22e (local.get $2) ;; code offset: 0x230- (i32.const -1)+ (i32.const 1) ) ) ;; code offset: 0x235@@ -5542,11 +5530,11 @@ ;; code offset: 0x282 (local.set $1 ;; code offset: 0x281- (i32.add+ (i32.sub ;; code offset: 0x27d (local.get $7) ;; code offset: 0x27f- (i32.const -1)+ (i32.const 1) ) ) ;; code offset: 0x286@@ -5624,11 +5612,11 @@ ;; code offset: 0x2be (local.tee $1 ;; code offset: 0x2bd- (i32.add+ (i32.sub ;; code offset: 0x2b9 (local.get $1) ;; code offset: 0x2bb- (i32.const -1)+ (i32.const 1) ) ) )@@ -5823,7 +5811,7 @@ ) ) ;; code offset: 0x356- (i32.add+ (i32.sub ;; code offset: 0x352 (local.tee $1 ;; code offset: 0x34f@@ -5833,7 +5821,7 @@ ) ) ;; code offset: 0x354- (i32.const -1)+ (i32.const 1) ) ) ;; code offset: 0x35f@@ -5977,11 +5965,11 @@ ;; code offset: 0x3d7 (local.set $2 ;; code offset: 0x3d6- (i32.add+ (i32.sub ;; code offset: 0x3d2 (local.get $3) ;; code offset: 0x3d4- (i32.const -1)+ (i32.const 1) ) ) ;; code offset: 0x3db@@ -6255,11 +6243,11 @@ ;; code offset: 0x4aa (local.tee $0 ;; code offset: 0x4a9- (i32.add+ (i32.sub ;; code offset: 0x4a5 (local.get $2) ;; code offset: 0x4a7- (i32.const -1)+ (i32.const 1) ) ) ;; code offset: 0x4ac@@ -6304,11 +6292,11 @@ ;; code offset: 0x4d2 (local.set $6 ;; code offset: 0x4d1- (i32.add+ (i32.sub ;; code offset: 0x4cd (local.get $6) ;; code offset: 0x4cf- (i32.const -1)+ (i32.const 1) ) ) ;; code offset: 0x4d4@@ -6429,7 +6417,7 @@ ) ) ;; code offset: 0x532- (i32.add+ (i32.sub ;; code offset: 0x52e (local.tee $0 ;; code offset: 0x52b@@ -6439,7 +6427,7 @@ ) ) ;; code offset: 0x530- (i32.const -1)+ (i32.const 1) ) ) ;; code offset: 0x53b@@ -6516,11 +6504,11 @@ ;; code offset: 0x56c (local.tee $0 ;; code offset: 0x56b- (i32.add+ (i32.sub ;; code offset: 0x567 (local.get $2) ;; code offset: 0x569- (i32.const -1)+ (i32.const 1) ) ) ;; code offset: 0x56e@@ -6565,11 +6553,11 @@ ;; code offset: 0x594 (local.set $6 ;; code offset: 0x593- (i32.add+ (i32.sub ;; code offset: 0x58f (local.get $6) ;; code offset: 0x591- (i32.const -1)+ (i32.const 1) ) ) ;; code offset: 0x596@@ -6690,7 +6678,7 @@ ) ) ;; code offset: 0x5f4- (i32.add+ (i32.sub ;; code offset: 0x5f0 (local.tee $0 ;; code offset: 0x5ed@@ -6700,7 +6688,7 @@ ) ) ;; code offset: 0x5f2- (i32.const -1)+ (i32.const 1) ) ) ;; code offset: 0x5fd@@ -6861,7 +6849,7 @@ ;; custom section ".debug_loc", size 1073 ;; custom section ".debug_ranges", size 88 ;; custom section ".debug_abbrev", size 333- ;; custom section ".debug_line", size 2702+ ;; custom section ".debug_line", size 2682 ;; custom section ".debug_str", size 434 ;; custom section "producers", size 135 )
binaryen/test/passes/fib2_dwarf.bin.txt view
@@ -618,7 +618,7 @@ (type $i32_=>_i32 (func (param i32) (result i32))) (type $i32_i32_=>_i32 (func (param i32 i32) (result i32))) (import "env" "memory" (memory $mimport$0 256 256))- (import "env" "__indirect_function_table" (table $timport$1 1 funcref))+ (import "env" "__indirect_function_table" (table $timport$0 1 funcref)) (global $global$0 (mut i32) (i32.const 5243904)) (global $global$1 i32 (i32.const 1024)) (export "__wasm_call_ctors" (func $__wasm_call_ctors))
binaryen/test/passes/fib2_emptylocspan_dwarf.bin.txt view
@@ -618,7 +618,7 @@ (type $i32_=>_i32 (func (param i32) (result i32))) (type $i32_i32_=>_i32 (func (param i32 i32) (result i32))) (import "env" "memory" (memory $mimport$0 256 256))- (import "env" "__indirect_function_table" (table $timport$1 1 funcref))+ (import "env" "__indirect_function_table" (table $timport$0 1 funcref)) (global $global$0 (mut i32) (i32.const 5243904)) (global $global$1 i32 (i32.const 1024)) (export "__wasm_call_ctors" (func $__wasm_call_ctors))
binaryen/test/passes/fib_nonzero-low-pc_dwarf.bin.txt view
@@ -365,7 +365,7 @@ 0x00000079: DW_TAG_lexical_block [5] * DW_AT_low_pc [DW_FORM_addr] (0x000000000000001b)- DW_AT_high_pc [DW_FORM_data4] (0x00000000)+ DW_AT_high_pc [DW_FORM_data4] (0x00000033) 0x00000082: DW_TAG_variable [4] DW_AT_location [DW_FORM_sec_offset] (0x00000093: @@ -512,10 +512,10 @@ (type $none_=>_none (func)) (type $i32_=>_i32 (func (param i32) (result i32))) (import "env" "memory" (memory $mimport$0 0))- (import "env" "__indirect_function_table" (table $timport$1 0 funcref))- (import "env" "__stack_pointer" (global $gimport$2 (mut i32)))- (import "env" "__memory_base" (global $gimport$3 i32))- (import "env" "__table_base" (global $gimport$4 i32))+ (import "env" "__indirect_function_table" (table $timport$0 0 funcref))+ (import "env" "__stack_pointer" (global $gimport$0 (mut i32)))+ (import "env" "__memory_base" (global $gimport$1 i32))+ (import "env" "__table_base" (global $gimport$2 i32)) (global $global$0 i32 (i32.const 0)) (export "__wasm_call_ctors" (func $__wasm_call_ctors)) (export "__wasm_apply_relocs" (func $__wasm_apply_relocs))
binaryen/test/passes/flatten.bin.txt view
@@ -7,8 +7,8 @@ (type $none_=>_f32 (func (result f32))) (type $f32_=>_f32 (func (param f32) (result f32))) (type $none_=>_f64 (func (result f64)))- (type $i64_f32_f64_i32_i32_=>_f64 (func (param i64 f32 f64 i32 i32) (result f64))) (type $f64_=>_f64 (func (param f64) (result f64)))+ (type $i64_f32_f64_i32_i32_=>_f64 (func (param i64 f32 f64 i32 i32) (result f64))) (export "type-local-i32" (func $0)) (export "type-local-i64" (func $1)) (export "type-local-f32" (func $2))
binaryen/test/passes/flatten_dfo_O3_enable-threads.txt view
@@ -2,8 +2,8 @@ (type $none_=>_none (func)) (type $none_=>_i32 (func (result i32))) (type $i32_i32_=>_i32 (func (param i32 i32) (result i32)))- (type $i64_i32_=>_f64 (func (param i64 i32) (result f64))) (type $f64_=>_f64 (func (param f64) (result f64)))+ (type $i64_i32_=>_f64 (func (param i64 i32) (result f64))) (memory $0 (shared 1 1)) (export "one" (func $0)) (export "two" (func $1))
binaryen/test/passes/flatten_i64-to-i32-lowering.txt view
@@ -549,3 +549,24 @@ ) ) )+(module+ (type $none_=>_none (func))+ (table $0 37 funcref)+ (global $i64toi32_i32$HIGH_BITS (mut i32) (i32.const 0))+ (func $0+ (unreachable)+ (block+ (unreachable)+ (drop+ (f64.const 1)+ )+ (drop+ (i32.const -32768)+ )+ (drop+ (i32.const 20)+ )+ )+ (unreachable)+ )+)
binaryen/test/passes/flatten_i64-to-i32-lowering.wast view
@@ -63,4 +63,15 @@ (global.set $f (i64.const 0x1122334455667788)) ) )-+(module+ (type $i64_f64_i32_=>_none (func (param i64 f64 i32)))+ (table $0 37 funcref)+ (func $0+ (call_indirect (type $i64_f64_i32_=>_none)+ (unreachable)+ (f64.const 1)+ (i32.const -32768)+ (i32.const 20)+ )+ )+)
binaryen/test/passes/flatten_simplify-locals-nonesting_dfo_O3.txt view
@@ -1,8 +1,8 @@ (module (type $none_=>_none (func)) (type $i64_=>_none (func (param i64)))- (type $i32_f64_f64_=>_i32 (func (param i32 f64 f64) (result i32))) (type $f64_=>_i32 (func (param f64) (result i32)))+ (type $i32_f64_f64_=>_i32 (func (param i32 f64 f64) (result i32))) (type $none_=>_f64 (func (result f64))) (export "if-select" (func $0)) (export "unreachable-body-update-zext" (func $1))
binaryen/test/passes/fpcast-emu.txt view
@@ -235,8 +235,8 @@ ) ) (module- (type $i64_i64_i64_i64_i64_i64_i64_i64_i64_i64_i64_i64_i64_i64_i64_i64_=>_i64 (func (param i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64) (result i64))) (type $f32_=>_i64 (func (param f32) (result i64)))+ (type $i64_i64_i64_i64_i64_i64_i64_i64_i64_i64_i64_i64_i64_i64_i64_i64_=>_i64 (func (param i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64 i64) (result i64))) (table $0 42 42 funcref) (global $global$0 (mut i32) (i32.const 10)) (export "func_106" (func $0))
+ binaryen/test/passes/fpcast-emu_pass-arg=max-func-params@5.txt view
@@ -0,0 +1,43 @@+(module+ (type $i64_i64_i64_i64_i64_=>_i64 (func (param i64 i64 i64 i64 i64) (result i64)))+ (type $i32_i64_f32_f64_=>_none (func (param i32 i64 f32 f64)))+ (table $0 10 10 funcref)+ (elem (i32.const 0) $byn$fpcast-emu$a)+ (func $a (param $x i32) (param $y i64) (param $z f32) (param $w f64)+ (drop+ (call_indirect (type $i64_i64_i64_i64_i64_=>_i64)+ (i64.extend_i32_u+ (i32.const 1)+ )+ (i64.const 2)+ (i64.extend_i32_u+ (i32.reinterpret_f32+ (f32.const 3)+ )+ )+ (i64.reinterpret_f64+ (f64.const 4)+ )+ (i64.const 0)+ (i32.const 1337)+ )+ )+ )+ (func $byn$fpcast-emu$a (param $0 i64) (param $1 i64) (param $2 i64) (param $3 i64) (param $4 i64) (result i64)+ (call $a+ (i32.wrap_i64+ (local.get $0)+ )+ (local.get $1)+ (f32.reinterpret_i32+ (i32.wrap_i64+ (local.get $2)+ )+ )+ (f64.reinterpret_i64+ (local.get $3)+ )+ )+ (i64.const 0)+ )+)
+ binaryen/test/passes/fpcast-emu_pass-arg=max-func-params@5.wast view
@@ -0,0 +1,14 @@+(module+ (type $vijfd (func (param i32) (param i64) (param f32) (param f64)))+ (table 10 10 funcref)+ (elem (i32.const 0) $a)+ (func $a (param $x i32) (param $y i64) (param $z f32) (param $w f64)+ (call_indirect (type $vijfd)+ (i32.const 1)+ (i64.const 2)+ (f32.const 3)+ (f64.const 4)+ (i32.const 1337)+ )+ )+)
binaryen/test/passes/func-metrics.txt view
@@ -247,7 +247,7 @@ [vars] : 0 global.get : 1 export: stackSave (0)- [removable-bytes-without-it]: 70 + [removable-bytes-without-it]: 56 [total] : 0 (module (type $none_=>_i32 (func (result i32)))
binaryen/test/passes/fuzz-exec_O.txt view
@@ -31,59 +31,56 @@ [fuzz-exec] comparing func_0 [fuzz-exec] comparing func_1 [fuzz-exec] calling div-[fuzz-exec] note result: div => -nan:0x63017a+[fuzz-exec] note result: div => nan:0x400000 [fuzz-exec] calling mul1-[fuzz-exec] note result: mul1 => -nan:0x74546d+[fuzz-exec] note result: mul1 => nan:0x400000 [fuzz-exec] calling mul2-[fuzz-exec] note result: mul2 => -nan:0x74546d+[fuzz-exec] note result: mul2 => nan:0x400000 [fuzz-exec] calling add1-[fuzz-exec] note result: add1 => -nan:0x74546d+[fuzz-exec] note result: add1 => nan:0x400000 [fuzz-exec] calling add2-[fuzz-exec] note result: add2 => -nan:0x74546d+[fuzz-exec] note result: add2 => nan:0x400000 [fuzz-exec] calling add3-[fuzz-exec] note result: add3 => -nan:0x74546d+[fuzz-exec] note result: add3 => nan:0x400000 [fuzz-exec] calling add4-[fuzz-exec] note result: add4 => -nan:0x74546d+[fuzz-exec] note result: add4 => nan:0x400000 [fuzz-exec] calling sub1-[fuzz-exec] note result: sub1 => -nan:0x74546d+[fuzz-exec] note result: sub1 => nan:0x400000 [fuzz-exec] calling sub2-[fuzz-exec] note result: sub2 => -nan:0x74546d+[fuzz-exec] note result: sub2 => nan:0x400000 (module (type $none_=>_f32 (func (result f32))) (export "div" (func $0))- (export "mul1" (func $1))- (export "mul2" (func $1))- (export "add1" (func $1))- (export "add2" (func $1))- (export "add3" (func $1))- (export "add4" (func $1))- (export "sub1" (func $1))- (export "sub2" (func $1))+ (export "mul1" (func $0))+ (export "mul2" (func $0))+ (export "add1" (func $0))+ (export "add2" (func $0))+ (export "add3" (func $0))+ (export "add4" (func $0))+ (export "sub1" (func $0))+ (export "sub2" (func $0)) (func $0 (; has Stack IR ;) (result f32)- (f32.const -nan:0x63017a)- )- (func $1 (; has Stack IR ;) (result f32)- (f32.const -nan:0x74546d)+ (f32.const nan:0x400000) ) ) [fuzz-exec] calling div-[fuzz-exec] note result: div => -nan:0x63017a+[fuzz-exec] note result: div => nan:0x400000 [fuzz-exec] calling mul1-[fuzz-exec] note result: mul1 => -nan:0x74546d+[fuzz-exec] note result: mul1 => nan:0x400000 [fuzz-exec] calling mul2-[fuzz-exec] note result: mul2 => -nan:0x74546d+[fuzz-exec] note result: mul2 => nan:0x400000 [fuzz-exec] calling add1-[fuzz-exec] note result: add1 => -nan:0x74546d+[fuzz-exec] note result: add1 => nan:0x400000 [fuzz-exec] calling add2-[fuzz-exec] note result: add2 => -nan:0x74546d+[fuzz-exec] note result: add2 => nan:0x400000 [fuzz-exec] calling add3-[fuzz-exec] note result: add3 => -nan:0x74546d+[fuzz-exec] note result: add3 => nan:0x400000 [fuzz-exec] calling add4-[fuzz-exec] note result: add4 => -nan:0x74546d+[fuzz-exec] note result: add4 => nan:0x400000 [fuzz-exec] calling sub1-[fuzz-exec] note result: sub1 => -nan:0x74546d+[fuzz-exec] note result: sub1 => nan:0x400000 [fuzz-exec] calling sub2-[fuzz-exec] note result: sub2 => -nan:0x74546d+[fuzz-exec] note result: sub2 => nan:0x400000 [fuzz-exec] comparing add1 [fuzz-exec] comparing add2 [fuzz-exec] comparing add3
binaryen/test/passes/fuzz-exec_all-features.txt view
@@ -98,7 +98,7 @@ ) ) (func $3 (result i32)- (atomic.notify+ (memory.atomic.notify (i32.const 1) (i32.const 1) )@@ -119,7 +119,7 @@ ) (func $5 (drop- (atomic.notify offset=22+ (memory.atomic.notify offset=22 (i32.const -104) (i32.const -72) )@@ -207,3 +207,15 @@ ) [fuzz-exec] calling rmw-reads-modifies-and-writes-asymmetrical [LoggingExternalInterface logging 214]+[fuzz-exec] calling func+[fuzz-exec] note result: func => funcref(func)+(module+ (type $none_=>_funcref (func (result funcref)))+ (export "func" (func $func))+ (func $func (result funcref)+ (ref.func $func)+ )+)+[fuzz-exec] calling func+[fuzz-exec] note result: func => funcref(func)+[fuzz-exec] comparing func
binaryen/test/passes/fuzz-exec_all-features.wast view
@@ -51,7 +51,7 @@ ) ) (func "unaligned_notify" (result i32)- (atomic.notify+ (memory.atomic.notify (i32.const 1) ;; unaligned (i32.const 1) )@@ -70,7 +70,7 @@ ) (func "oob_notify" (drop- (atomic.notify offset=22+ (memory.atomic.notify offset=22 (i32.const -104) ;; illegal address (i32.const -72) )@@ -119,5 +119,11 @@ (i32.const 3) ) )+ )+)+(module+ (export "func" (func $func))+ (func $func (result funcref)+ (ref.func $func) ) )
binaryen/test/passes/fuzz_metrics_noprint.bin.txt view
@@ -1,30 +1,30 @@ total [events] : 0 - [exports] : 18 - [funcs] : 22 + [exports] : 51 + [funcs] : 67 [globals] : 7 [imports] : 4 [memory-data] : 4 - [table-data] : 9 - [total] : 4993 - [vars] : 58 - binary : 397 - block : 736 - break : 204 - call : 173 - call_indirect : 32 - const : 823 - drop : 42 - global.get : 421 - global.set : 190 - if : 292 - load : 95 - local.get : 392 - local.set : 297 - loop : 146 - nop : 97 - return : 189 - select : 39 - store : 55 - switch : 1 - unary : 372 + [table-data] : 18 + [total] : 4870 + [vars] : 236 + binary : 368 + block : 699 + break : 191 + call : 300 + call_indirect : 39 + const : 847 + drop : 91 + global.get : 403 + global.set : 171 + if : 260 + load : 85 + local.get : 374 + local.set : 251 + loop : 111 + nop : 86 + return : 187 + select : 30 + store : 36 + unary : 340 + unreachable : 1
binaryen/test/passes/ignore_missing_func_dwarf.bin.txt view
@@ -6,7 +6,7 @@ (import "env" "memory" (memory $mimport$0 256 256)) (data (i32.const 1024) "\nvoid used(int x) {\n x++;\n x--;\n return x;\n}\n\nvoid unused(int x) {\n x >>= 1;\n x <<= 1;\n return x;\n}\n\nint main() {\n return used(42);\n}\n\00") (data (i32.const 1168) "\00\04\00\00")- (import "env" "__indirect_function_table" (table $timport$1 1 funcref))+ (import "env" "__indirect_function_table" (table $timport$0 1 funcref)) (global $global$0 (mut i32) (i32.const 5244064)) (global $global$1 i32 (i32.const 1172)) (export "__wasm_call_ctors" (func $__wasm_call_ctors))@@ -829,7 +829,7 @@ (import "env" "memory" (memory $mimport$0 256 256)) (data (i32.const 1024) "\nvoid used(int x) {\n x++;\n x--;\n return x;\n}\n\nvoid unused(int x) {\n x >>= 1;\n x <<= 1;\n return x;\n}\n\nint main() {\n return used(42);\n}\n\00") (data (i32.const 1168) "\00\04\00\00")- (import "env" "__indirect_function_table" (table $timport$1 1 funcref))+ (import "env" "__indirect_function_table" (table $timport$0 1 funcref)) (global $global$0 (mut i32) (i32.const 5244064)) (global $global$1 i32 (i32.const 1172)) (export "__wasm_call_ctors" (func $__wasm_call_ctors))
binaryen/test/passes/inlining-optimizing_optimize-level=3.txt view
@@ -2467,7 +2467,7 @@ (if (result i32) (i32.lt_u (local.tee $8- (i32.add+ (i32.sub (local.tee $12 (i32.load8_s (local.tee $10@@ -2478,7 +2478,7 @@ ) ) )- (i32.const -48)+ (i32.const 48) ) ) (i32.const 10)@@ -2562,9 +2562,9 @@ (i32.and (i32.shl (i32.const 1)- (i32.add+ (i32.sub (local.get $6)- (i32.const -32)+ (i32.const 32) ) ) (i32.const 75913)@@ -2583,7 +2583,7 @@ (i32.or (i32.shl (i32.const 1)- (i32.add+ (i32.sub (i32.shr_s (i32.shl (local.get $1)@@ -2591,7 +2591,7 @@ ) (i32.const 24) )- (i32.const -32)+ (i32.const 32) ) ) (local.get $12)@@ -2642,7 +2642,7 @@ (br_if $__rjti$0 (i32.ge_u (local.tee $12- (i32.add+ (i32.sub (i32.load8_s (local.tee $6 (i32.add@@ -2651,7 +2651,7 @@ ) ) )- (i32.const -48)+ (i32.const 48) ) ) (i32.const 10)@@ -2681,11 +2681,11 @@ (i32.add (local.get $3) (i32.shl- (i32.add+ (i32.sub (i32.load8_s (local.get $6) )- (i32.const -48)+ (i32.const 48) ) (i32.const 3) )@@ -2790,7 +2790,7 @@ (if (result i32) (i32.lt_u (local.tee $6- (i32.add+ (i32.sub (i32.shr_s (i32.shl (local.get $6)@@ -2798,7 +2798,7 @@ ) (i32.const 24) )- (i32.const -48)+ (i32.const 48) ) ) (i32.const 10)@@ -2820,7 +2820,7 @@ (if (i32.lt_u (local.tee $9- (i32.add+ (i32.sub (i32.load8_s (local.tee $10 (i32.add@@ -2829,7 +2829,7 @@ ) ) )- (i32.const -48)+ (i32.const 48) ) ) (i32.const 10)@@ -2907,9 +2907,9 @@ (if (result i32) (i32.lt_u (local.tee $9- (i32.add+ (i32.sub (local.get $8)- (i32.const -48)+ (i32.const 48) ) ) (i32.const 10)@@ -2947,7 +2947,7 @@ ) (i32.ge_u (local.tee $6- (i32.add+ (i32.sub (i32.load8_s (local.tee $10 (i32.add@@ -2956,7 +2956,7 @@ ) ) )- (i32.const -48)+ (i32.const 48) ) ) (i32.const 10)@@ -2970,7 +2970,7 @@ (if (i32.lt_u (local.tee $8- (i32.add+ (i32.sub (i32.load8_s (local.tee $6 (i32.add@@ -2979,7 +2979,7 @@ ) ) )- (i32.const -48)+ (i32.const 48) ) ) (i32.const 10)@@ -3008,11 +3008,11 @@ (i32.add (local.get $3) (i32.shl- (i32.add+ (i32.sub (i32.load8_s (local.get $6) )- (i32.const -48)+ (i32.const 48) ) (i32.const 3) )@@ -3095,11 +3095,11 @@ (if (i32.gt_u (local.tee $11- (i32.add+ (i32.sub (i32.load8_s (local.get $8) )- (i32.const -65)+ (i32.const 65) ) ) (i32.const 57)@@ -3119,7 +3119,7 @@ ) (if (result i32) (i32.lt_u- (i32.add+ (i32.sub (local.tee $11 (i32.and (local.tee $15@@ -3139,7 +3139,7 @@ (i32.const 255) ) )- (i32.const -1)+ (i32.const 1) ) (i32.const 8) )@@ -3548,9 +3548,9 @@ (loop $while-in32 (i32.store8 (local.tee $8- (i32.add+ (i32.sub (local.get $8)- (i32.const -1)+ (i32.const 1) ) ) (i32.or@@ -3602,9 +3602,9 @@ ) ) (local.get $6)- (i32.lt_s- (local.get $6)+ (i32.gt_s (local.get $5)+ (local.get $6) ) ) )@@ -3645,7 +3645,7 @@ (i32.const 0) (local.get $7) )- (i32.gt_u+ (i32.ne (local.get $5) (i32.const 0) )@@ -3926,11 +3926,11 @@ ) (i32.store (local.get $21)- (i32.add+ (i32.sub (i32.load (local.get $21) )- (i32.const -1)+ (i32.const 1) ) ) )@@ -3990,20 +3990,14 @@ ) (br_if $while-in54 (local.tee $5- (i32.add+ (i32.sub (local.get $5)- (i32.const -1)+ (i32.const 1) ) ) ) )- (if (result f64)- (i32.eq- (i32.load8_s- (local.get $9)- )- (i32.const 45)- )+ (select (f64.neg (f64.add (local.get $14)@@ -4022,6 +4016,12 @@ ) (local.get $14) )+ (i32.eq+ (i32.load8_s+ (local.get $9)+ )+ (i32.const 45)+ ) ) ) )@@ -4079,9 +4079,9 @@ ) ) (i32.store8- (i32.add+ (i32.sub (local.get $5)- (i32.const -1)+ (i32.const 1) ) (i32.add (i32.and@@ -4096,9 +4096,9 @@ ) (i32.store8 (local.tee $8- (i32.add+ (i32.sub (local.get $5)- (i32.const -2)+ (i32.const 2) ) ) (i32.add@@ -4375,11 +4375,11 @@ (i32.store (local.get $21) (local.tee $5- (i32.add+ (i32.sub (i32.load (local.get $21) )- (i32.const -28)+ (i32.const 28) ) ) )@@ -4490,9 +4490,9 @@ (if (i32.ge_u (local.tee $9- (i32.add+ (i32.sub (local.get $7)- (i32.const -4)+ (i32.const 4) ) ) (local.get $5)@@ -4508,22 +4508,22 @@ (block (result i32) (global.set $tempRet0 (i32.add- (i32.lt_u+ (i32.gt_u+ (local.tee $20+ (call $_bitshift64Shl+ (i32.load+ (local.get $9)+ )+ (i32.const 0)+ (local.get $15)+ )+ ) (local.tee $11 (i32.add (local.get $11)- (local.tee $20- (call $_bitshift64Shl- (i32.load- (local.get $9)- )- (i32.const 0)- (local.get $15)- )- )+ (local.get $20) ) )- (local.get $20) ) (global.get $tempRet0) )@@ -4548,9 +4548,9 @@ (br_if $while-in66 (i32.ge_u (local.tee $9- (i32.add+ (i32.sub (local.get $9)- (i32.const -4)+ (i32.const 4) ) ) (local.get $5)@@ -4564,9 +4564,9 @@ ) (i32.store (local.tee $5- (i32.add+ (i32.sub (local.get $5)- (i32.const -4)+ (i32.const 4) ) ) (local.get $11)@@ -4575,17 +4575,17 @@ ) (loop $while-in68 (if- (i32.gt_u- (local.get $7)+ (i32.lt_u (local.get $5)+ (local.get $7) ) (if (i32.eqz (i32.load (local.tee $9- (i32.add+ (i32.sub (local.get $7)- (i32.const -4)+ (i32.const 4) ) ) )@@ -4680,18 +4680,18 @@ ) ) (if- (i32.lt_u- (local.get $6)+ (i32.gt_u (local.get $5)+ (local.get $6) ) (block $do-once71 (local.set $11- (i32.add+ (i32.sub (i32.shl (i32.const 1) (local.get $15) )- (i32.const -1)+ (i32.const 1) ) ) (local.set $35@@ -4946,7 +4946,7 @@ ) ) )- (i32.add+ (i32.sub (i32.mul (i32.shr_s (i32.sub@@ -4957,7 +4957,7 @@ ) (i32.const 9) )- (i32.const -9)+ (i32.const 9) ) ) (block (result i32)@@ -5017,7 +5017,7 @@ (local.tee $8 (i32.load (local.tee $6- (i32.add+ (i32.sub (i32.add (local.get $20) (i32.shl@@ -5025,7 +5025,7 @@ (i32.const 2) ) )- (i32.const -4092)+ (i32.const 4092) ) ) )@@ -5167,18 +5167,18 @@ (if (i32.lt_u (local.tee $6- (i32.add+ (i32.sub (local.get $6)- (i32.const -4)+ (i32.const 4) ) ) (local.get $5) ) (i32.store (local.tee $5- (i32.add+ (i32.sub (local.get $5)- (i32.const -4)+ (i32.const 4) ) ) (i32.const 0)@@ -5263,9 +5263,9 @@ ) ) (local.get $9)- (i32.gt_u- (local.get $9)+ (i32.lt_u (local.get $5)+ (local.get $9) ) ) )@@ -5306,9 +5306,9 @@ (if (result i32) (i32.load (local.tee $7- (i32.add+ (i32.sub (local.get $5)- (i32.const -4)+ (i32.const 4) ) ) )@@ -5363,28 +5363,28 @@ (block (result i32) (local.set $19 (i32.sub- (i32.add+ (i32.sub (local.get $5)- (i32.const -1)+ (i32.const 1) ) (local.get $8) ) )- (i32.add+ (i32.sub (local.get $16)- (i32.const -1)+ (i32.const 1) ) ) (block (result i32) (local.set $19- (i32.add+ (i32.sub (local.get $5)- (i32.const -1)+ (i32.const 1) ) )- (i32.add+ (i32.sub (local.get $16)- (i32.const -2)+ (i32.const 2) ) ) )@@ -5407,9 +5407,9 @@ (i32.eqz (local.tee $16 (i32.load- (i32.add+ (i32.sub (local.get $9)- (i32.const -4)+ (i32.const 4) ) ) )@@ -5474,7 +5474,7 @@ ) ) (local.set $6- (i32.add+ (i32.sub (i32.mul (i32.shr_s (i32.sub@@ -5485,7 +5485,7 @@ ) (i32.const 9) )- (i32.const -9)+ (i32.const 9) ) ) (if (result i32)@@ -5517,9 +5517,9 @@ ) ) )- (i32.lt_s- (local.get $19)+ (i32.gt_s (local.get $5)+ (local.get $19) ) ) )@@ -5547,9 +5547,9 @@ ) ) )- (i32.lt_s- (local.get $19)+ (i32.gt_s (local.get $5)+ (local.get $19) ) ) )@@ -5643,9 +5643,9 @@ (loop $while-in98 (i32.store8 (local.tee $6- (i32.add+ (i32.sub (local.get $6)- (i32.const -1)+ (i32.const 1) ) ) (i32.const 48)@@ -5662,9 +5662,9 @@ ) ) (i32.store8- (i32.add+ (i32.sub (local.get $6)- (i32.const -1)+ (i32.const 1) ) (i32.add (i32.and@@ -5679,9 +5679,9 @@ ) (i32.store8 (local.tee $16- (i32.add+ (i32.sub (local.get $6)- (i32.const -2)+ (i32.const 2) ) ) (local.get $7)@@ -5779,9 +5779,9 @@ (loop $while-in106 (i32.store8 (local.tee $7- (i32.add+ (i32.sub (local.get $7)- (i32.const -1)+ (i32.const 1) ) ) (i32.const 48)@@ -5886,9 +5886,9 @@ (loop $while-in112 (i32.store8 (local.tee $6- (i32.add+ (i32.sub (local.get $6)- (i32.const -1)+ (i32.const 1) ) ) (i32.const 48)@@ -5926,9 +5926,9 @@ ) ) (local.set $6- (i32.add+ (i32.sub (local.get $5)- (i32.const -9)+ (i32.const 9) ) ) (if (result i32)@@ -6085,9 +6085,9 @@ (loop $while-in118 (i32.store8 (local.tee $5- (i32.add+ (i32.sub (local.get $5)- (i32.const -1)+ (i32.const 1) ) ) (i32.const 48)@@ -6359,9 +6359,9 @@ (loop $while-in123 (result i32) (i32.store8 (local.tee $8- (i32.add+ (i32.sub (local.get $8)- (i32.const -1)+ (i32.const 1) ) ) (i32.or@@ -6651,9 +6651,9 @@ ) ) (br_if $while-in127- (i32.lt_u- (local.get $6)+ (i32.gt_u (local.get $5)+ (local.get $6) ) ) (local.get $5)@@ -6675,9 +6675,9 @@ (select (local.get $17) (local.get $7)- (i32.gt_s- (local.get $17)+ (i32.lt_s (local.get $7)+ (local.get $17) ) ) )@@ -6733,9 +6733,9 @@ ) ) )- (i32.gt_s- (local.get $6)+ (i32.lt_s (local.get $5)+ (local.get $6) ) ) (block (result i32)@@ -6762,9 +6762,9 @@ ) ) (local.get $17)- (i32.lt_s- (local.get $17)+ (i32.gt_s (local.get $5)+ (local.get $17) ) ) )@@ -7349,16 +7349,13 @@ (func $_fmt_u (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (local $3 i32) (if- (i32.gt_u- (local.get $1)- (i32.const 0)- )+ (local.get $1) (loop $while-in (i32.store8 (local.tee $2- (i32.add+ (i32.sub (local.get $2)- (i32.const -1)+ (i32.const 1) ) ) (i32.or@@ -7401,9 +7398,9 @@ (loop $while-in1 (i32.store8 (local.tee $2- (i32.add+ (i32.sub (local.get $2)- (i32.const -1)+ (i32.const 1) ) ) (i32.or@@ -7414,18 +7411,22 @@ (i32.const 48) ) )- (local.set $0+ (local.set $1 (i32.div_u- (local.tee $1- (local.get $0)- )+ (local.get $0) (i32.const 10) ) )- (br_if $while-in1+ (if (i32.ge_u- (local.get $1)+ (local.get $0) (i32.const 10)+ )+ (block+ (local.set $0+ (local.get $1)+ )+ (br $while-in1) ) ) )
binaryen/test/passes/inlining_all-features.txt view
@@ -47,3 +47,42 @@ ) ) )+(module+ (type $none_=>_i32 (func (result i32)))+ (global $global$0 (mut funcref) (ref.func $0))+ (func $0 (result i32)+ (i32.const 1337)+ )+ (func $1 (result i32)+ (block $__inlined_func$0 (result i32)+ (i32.const 1337)+ )+ )+)+(module+ (type $none_=>_none (func))+ (start $0)+ (func $0+ (nop)+ )+ (func $1+ (block $__inlined_func$0+ (nop)+ )+ )+)+(module+ (type $none_=>_none (func))+ (export "func_36_invoker" (func $1))+ (func $1+ (block $__inlined_func$0+ (block+ (call_ref+ (ref.null $none_=>_none)+ )+ (br $__inlined_func$0)+ )+ (br $__inlined_func$0)+ )+ )+)
binaryen/test/passes/inlining_all-features.wast view
@@ -36,3 +36,38 @@ ) ) )+(module+ ;; a function reference in a global's init should be noticed, and prevent us+ ;; from removing an inlined function+ (global $global$0 (mut funcref) (ref.func $0))+ (func $0 (result i32)+ (i32.const 1337)+ )+ (func $1 (result i32)+ (call $0)+ )+)+(module+ ;; a function reference in the start should be noticed, and prevent us+ ;; from removing an inlined function+ (start $0)+ (func $0+ (nop)+ )+ (func $1+ (call $0)+ )+)+;; inline a return_call_ref+(module+ (type $none_=>_none (func))+ (export "func_36_invoker" (func $1))+ (func $0+ (return_call_ref+ (ref.null $none_=>_none)+ )+ )+ (func $1+ (call $0)+ )+)
− binaryen/test/passes/instrument-locals_all-features.txt
@@ -1,269 +0,0 @@-(module- (type $i32_i32_i32_=>_i32 (func (param i32 i32 i32) (result i32)))- (type $i32_i32_i64_=>_i64 (func (param i32 i32 i64) (result i64)))- (type $i32_i32_f32_=>_f32 (func (param i32 i32 f32) (result f32)))- (type $i32_i32_f64_=>_f64 (func (param i32 i32 f64) (result f64)))- (type $i32_i32_v128_=>_v128 (func (param i32 i32 v128) (result v128)))- (type $i32_i32_funcref_=>_funcref (func (param i32 i32 funcref) (result funcref)))- (type $i32_i32_externref_=>_externref (func (param i32 i32 externref) (result externref)))- (type $i32_i32_exnref_=>_exnref (func (param i32 i32 exnref) (result exnref)))- (type $i32_i32_anyref_=>_anyref (func (param i32 i32 anyref) (result anyref)))- (type $i32_i32_eqref_=>_eqref (func (param i32 i32 eqref) (result eqref)))- (type $i32_i32_i31ref_=>_i31ref (func (param i32 i32 i31ref) (result i31ref)))- (type $none_=>_none (func))- (import "env" "get_i32" (func $get_i32 (param i32 i32 i32) (result i32)))- (import "env" "get_i64" (func $get_i64 (param i32 i32 i64) (result i64)))- (import "env" "get_f32" (func $get_f32 (param i32 i32 f32) (result f32)))- (import "env" "get_f64" (func $get_f64 (param i32 i32 f64) (result f64)))- (import "env" "set_i32" (func $set_i32 (param i32 i32 i32) (result i32)))- (import "env" "set_i64" (func $set_i64 (param i32 i32 i64) (result i64)))- (import "env" "set_f32" (func $set_f32 (param i32 i32 f32) (result f32)))- (import "env" "set_f64" (func $set_f64 (param i32 i32 f64) (result f64)))- (import "env" "get_funcref" (func $get_funcref (param i32 i32 funcref) (result funcref)))- (import "env" "set_funcref" (func $set_funcref (param i32 i32 funcref) (result funcref)))- (import "env" "get_externref" (func $get_externref (param i32 i32 externref) (result externref)))- (import "env" "set_externref" (func $set_externref (param i32 i32 externref) (result externref)))- (import "env" "get_exnref" (func $get_exnref (param i32 i32 exnref) (result exnref)))- (import "env" "set_exnref" (func $set_exnref (param i32 i32 exnref) (result exnref)))- (import "env" "get_anyref" (func $get_anyref (param i32 i32 anyref) (result anyref)))- (import "env" "set_anyref" (func $set_anyref (param i32 i32 anyref) (result anyref)))- (import "env" "get_eqref" (func $get_eqref (param i32 i32 eqref) (result eqref)))- (import "env" "set_eqref" (func $set_eqref (param i32 i32 eqref) (result eqref)))- (import "env" "get_i31ref" (func $get_i31ref (param i32 i32 i31ref) (result i31ref)))- (import "env" "set_i31ref" (func $set_i31ref (param i32 i32 i31ref) (result i31ref)))- (import "env" "get_v128" (func $get_v128 (param i32 i32 v128) (result v128)))- (import "env" "set_v128" (func $set_v128 (param i32 i32 v128) (result v128)))- (func $test- (local $x i32)- (local $y i64)- (local $z f32)- (local $w f64)- (local $F funcref)- (local $X externref)- (local $E exnref)- (local $S v128)- (drop- (call $get_i32- (i32.const 0)- (i32.const 0)- (local.get $x)- )- )- (drop- (local.get $y)- )- (drop- (call $get_f32- (i32.const 1)- (i32.const 2)- (local.get $z)- )- )- (drop- (call $get_f64- (i32.const 2)- (i32.const 3)- (local.get $w)- )- )- (drop- (call $get_funcref- (i32.const 3)- (i32.const 4)- (local.get $F)- )- )- (drop- (call $get_externref- (i32.const 4)- (i32.const 5)- (local.get $X)- )- )- (drop- (call $get_exnref- (i32.const 5)- (i32.const 6)- (local.get $E)- )- )- (drop- (call $get_i32- (i32.const 6)- (i32.const 0)- (local.get $x)- )- )- (drop- (local.get $y)- )- (drop- (call $get_f32- (i32.const 7)- (i32.const 2)- (local.get $z)- )- )- (drop- (call $get_f64- (i32.const 8)- (i32.const 3)- (local.get $w)- )- )- (drop- (call $get_funcref- (i32.const 9)- (i32.const 4)- (local.get $F)- )- )- (drop- (call $get_externref- (i32.const 10)- (i32.const 5)- (local.get $X)- )- )- (drop- (call $get_exnref- (i32.const 11)- (i32.const 6)- (local.get $E)- )- )- (local.set $x- (call $set_i32- (i32.const 12)- (i32.const 0)- (i32.const 1)- )- )- (local.set $y- (i64.const 2)- )- (local.set $z- (call $set_f32- (i32.const 13)- (i32.const 2)- (f32.const 3.2100000381469727)- )- )- (local.set $w- (call $set_f64- (i32.const 14)- (i32.const 3)- (f64.const 4.321)- )- )- (local.set $F- (call $set_funcref- (i32.const 15)- (i32.const 4)- (ref.func $test)- )- )- (local.set $X- (call $set_externref- (i32.const 17)- (i32.const 5)- (call $get_externref- (i32.const 16)- (i32.const 5)- (local.get $X)- )- )- )- (local.set $E- (call $set_exnref- (i32.const 19)- (i32.const 6)- (call $get_exnref- (i32.const 18)- (i32.const 6)- (local.get $E)- )- )- )- (local.set $x- (call $set_i32- (i32.const 20)- (i32.const 0)- (i32.const 11)- )- )- (local.set $y- (i64.const 22)- )- (local.set $z- (call $set_f32- (i32.const 21)- (i32.const 2)- (f32.const 33.209999084472656)- )- )- (local.set $w- (call $set_f64- (i32.const 22)- (i32.const 3)- (f64.const 44.321)- )- )- (local.set $F- (call $set_funcref- (i32.const 24)- (i32.const 4)- (call $get_funcref- (i32.const 23)- (i32.const 4)- (local.get $F)- )- )- )- (local.set $X- (call $set_externref- (i32.const 26)- (i32.const 5)- (call $get_externref- (i32.const 25)- (i32.const 5)- (local.get $X)- )- )- )- (local.set $E- (call $set_exnref- (i32.const 28)- (i32.const 6)- (call $get_exnref- (i32.const 27)- (i32.const 6)- (local.get $E)- )- )- )- (local.set $F- (pop funcref)- )- (local.set $X- (pop externref)- )- (local.set $E- (pop exnref)- )- (drop- (call $get_v128- (i32.const 29)- (i32.const 7)- (local.get $S)- )- )- (local.set $S- (call $set_v128- (i32.const 30)- (i32.const 7)- (v128.const i32x4 0x00000000 0x00000001 0x00000002 0x00000003)- )- )- )-)
− binaryen/test/passes/instrument-locals_all-features.wast
@@ -1,54 +0,0 @@-(module- (func $test- (local $x i32)- (local $y i64)- (local $z f32)- (local $w f64)- (local $F funcref)- (local $X externref)- (local $E exnref)- (local $S v128)-- (drop (local.get $x))- (drop (local.get $y))- (drop (local.get $z))- (drop (local.get $w))- (drop (local.get $F))- (drop (local.get $X))- (drop (local.get $E))-- (drop (local.get $x))- (drop (local.get $y))- (drop (local.get $z))- (drop (local.get $w))- (drop (local.get $F))- (drop (local.get $X))- (drop (local.get $E))-- (local.set $x (i32.const 1))- (local.set $y (i64.const 2))- (local.set $z (f32.const 3.21))- (local.set $w (f64.const 4.321))- (local.set $F (ref.func $test))- (local.set $X (local.get $X))- (local.set $E (local.get $E))-- (local.set $x (i32.const 11))- (local.set $y (i64.const 22))- (local.set $z (f32.const 33.21))- (local.set $w (f64.const 44.321))- (local.set $F (local.get $F))- (local.set $X (local.get $X))- (local.set $E (local.get $E))-- ;; Pop instructions should not be instrumented- (local.set $F (pop funcref))- (local.set $X (pop externref))- (local.set $E (pop exnref))-- ;; Add new instructions here so expected output doesn't change too much, it- ;; depends on order of instructions in this file.- (drop (local.get $S))- (local.set $S (v128.const i32x4 0x00000000 0x00000001 0x00000002 0x00000003))- )-)
+ binaryen/test/passes/instrument-locals_all-features_disable-typed-function-references.txt view
@@ -0,0 +1,286 @@+(module+ (type $i32_i32_i32_=>_i32 (func (param i32 i32 i32) (result i32)))+ (type $i32_i32_i64_=>_i64 (func (param i32 i32 i64) (result i64)))+ (type $i32_i32_f32_=>_f32 (func (param i32 i32 f32) (result f32)))+ (type $i32_i32_f64_=>_f64 (func (param i32 i32 f64) (result f64)))+ (type $i32_i32_v128_=>_v128 (func (param i32 i32 v128) (result v128)))+ (type $i32_i32_funcref_=>_funcref (func (param i32 i32 funcref) (result funcref)))+ (type $i32_i32_externref_=>_externref (func (param i32 i32 externref) (result externref)))+ (type $i32_i32_exnref_=>_exnref (func (param i32 i32 exnref) (result exnref)))+ (type $i32_i32_anyref_=>_anyref (func (param i32 i32 anyref) (result anyref)))+ (type $i32_i32_eqref_=>_eqref (func (param i32 i32 eqref) (result eqref)))+ (type $i32_i32_i31ref_=>_i31ref (func (param i32 i32 i31ref) (result i31ref)))+ (type $none_=>_none (func))+ (import "env" "get_i32" (func $get_i32 (param i32 i32 i32) (result i32)))+ (import "env" "get_i64" (func $get_i64 (param i32 i32 i64) (result i64)))+ (import "env" "get_f32" (func $get_f32 (param i32 i32 f32) (result f32)))+ (import "env" "get_f64" (func $get_f64 (param i32 i32 f64) (result f64)))+ (import "env" "set_i32" (func $set_i32 (param i32 i32 i32) (result i32)))+ (import "env" "set_i64" (func $set_i64 (param i32 i32 i64) (result i64)))+ (import "env" "set_f32" (func $set_f32 (param i32 i32 f32) (result f32)))+ (import "env" "set_f64" (func $set_f64 (param i32 i32 f64) (result f64)))+ (import "env" "get_funcref" (func $get_funcref (param i32 i32 funcref) (result funcref)))+ (import "env" "set_funcref" (func $set_funcref (param i32 i32 funcref) (result funcref)))+ (import "env" "get_externref" (func $get_externref (param i32 i32 externref) (result externref)))+ (import "env" "set_externref" (func $set_externref (param i32 i32 externref) (result externref)))+ (import "env" "get_exnref" (func $get_exnref (param i32 i32 exnref) (result exnref)))+ (import "env" "set_exnref" (func $set_exnref (param i32 i32 exnref) (result exnref)))+ (import "env" "get_anyref" (func $get_anyref (param i32 i32 anyref) (result anyref)))+ (import "env" "set_anyref" (func $set_anyref (param i32 i32 anyref) (result anyref)))+ (import "env" "get_eqref" (func $get_eqref (param i32 i32 eqref) (result eqref)))+ (import "env" "set_eqref" (func $set_eqref (param i32 i32 eqref) (result eqref)))+ (import "env" "get_i31ref" (func $get_i31ref (param i32 i32 i31ref) (result i31ref)))+ (import "env" "set_i31ref" (func $set_i31ref (param i32 i32 i31ref) (result i31ref)))+ (import "env" "get_v128" (func $get_v128 (param i32 i32 v128) (result v128)))+ (import "env" "set_v128" (func $set_v128 (param i32 i32 v128) (result v128)))+ (func $test+ (local $x i32)+ (local $y i64)+ (local $z f32)+ (local $w f64)+ (local $F funcref)+ (local $X externref)+ (local $E exnref)+ (local $S v128)+ (drop+ (call $get_i32+ (i32.const 0)+ (i32.const 0)+ (local.get $x)+ )+ )+ (drop+ (local.get $y)+ )+ (drop+ (call $get_f32+ (i32.const 1)+ (i32.const 2)+ (local.get $z)+ )+ )+ (drop+ (call $get_f64+ (i32.const 2)+ (i32.const 3)+ (local.get $w)+ )+ )+ (drop+ (call $get_funcref+ (i32.const 3)+ (i32.const 4)+ (local.get $F)+ )+ )+ (drop+ (call $get_externref+ (i32.const 4)+ (i32.const 5)+ (local.get $X)+ )+ )+ (drop+ (call $get_exnref+ (i32.const 5)+ (i32.const 6)+ (local.get $E)+ )+ )+ (drop+ (call $get_i32+ (i32.const 6)+ (i32.const 0)+ (local.get $x)+ )+ )+ (drop+ (local.get $y)+ )+ (drop+ (call $get_f32+ (i32.const 7)+ (i32.const 2)+ (local.get $z)+ )+ )+ (drop+ (call $get_f64+ (i32.const 8)+ (i32.const 3)+ (local.get $w)+ )+ )+ (drop+ (call $get_funcref+ (i32.const 9)+ (i32.const 4)+ (local.get $F)+ )+ )+ (drop+ (call $get_externref+ (i32.const 10)+ (i32.const 5)+ (local.get $X)+ )+ )+ (drop+ (call $get_exnref+ (i32.const 11)+ (i32.const 6)+ (local.get $E)+ )+ )+ (local.set $x+ (call $set_i32+ (i32.const 12)+ (i32.const 0)+ (i32.const 1)+ )+ )+ (local.set $y+ (i64.const 2)+ )+ (local.set $z+ (call $set_f32+ (i32.const 13)+ (i32.const 2)+ (f32.const 3.2100000381469727)+ )+ )+ (local.set $w+ (call $set_f64+ (i32.const 14)+ (i32.const 3)+ (f64.const 4.321)+ )+ )+ (local.set $F+ (ref.func $test)+ )+ (local.set $X+ (call $set_externref+ (i32.const 16)+ (i32.const 5)+ (call $get_externref+ (i32.const 15)+ (i32.const 5)+ (local.get $X)+ )+ )+ )+ (local.set $E+ (call $set_exnref+ (i32.const 18)+ (i32.const 6)+ (call $get_exnref+ (i32.const 17)+ (i32.const 6)+ (local.get $E)+ )+ )+ )+ (local.set $x+ (call $set_i32+ (i32.const 19)+ (i32.const 0)+ (i32.const 11)+ )+ )+ (local.set $y+ (i64.const 22)+ )+ (local.set $z+ (call $set_f32+ (i32.const 20)+ (i32.const 2)+ (f32.const 33.209999084472656)+ )+ )+ (local.set $w+ (call $set_f64+ (i32.const 21)+ (i32.const 3)+ (f64.const 44.321)+ )+ )+ (local.set $F+ (call $set_funcref+ (i32.const 23)+ (i32.const 4)+ (call $get_funcref+ (i32.const 22)+ (i32.const 4)+ (local.get $F)+ )+ )+ )+ (local.set $X+ (call $set_externref+ (i32.const 25)+ (i32.const 5)+ (call $get_externref+ (i32.const 24)+ (i32.const 5)+ (local.get $X)+ )+ )+ )+ (local.set $E+ (call $set_exnref+ (i32.const 27)+ (i32.const 6)+ (call $get_exnref+ (i32.const 26)+ (i32.const 6)+ (local.get $E)+ )+ )+ )+ (try+ (do+ (nop)+ )+ (catch+ (local.set $F+ (pop funcref)+ )+ )+ )+ (try+ (do+ (nop)+ )+ (catch+ (local.set $X+ (pop externref)+ )+ )+ )+ (try+ (do+ (nop)+ )+ (catch+ (local.set $E+ (pop exnref)+ )+ )+ )+ (drop+ (call $get_v128+ (i32.const 28)+ (i32.const 7)+ (local.get $S)+ )+ )+ (local.set $S+ (call $set_v128+ (i32.const 29)+ (i32.const 7)+ (v128.const i32x4 0x00000000 0x00000001 0x00000002 0x00000003)+ )+ )+ )+)
+ binaryen/test/passes/instrument-locals_all-features_disable-typed-function-references.wast view
@@ -0,0 +1,69 @@+(module+ (func $test+ (local $x i32)+ (local $y i64)+ (local $z f32)+ (local $w f64)+ (local $F funcref)+ (local $X externref)+ (local $E exnref)+ (local $S v128)++ (drop (local.get $x))+ (drop (local.get $y))+ (drop (local.get $z))+ (drop (local.get $w))+ (drop (local.get $F))+ (drop (local.get $X))+ (drop (local.get $E))++ (drop (local.get $x))+ (drop (local.get $y))+ (drop (local.get $z))+ (drop (local.get $w))+ (drop (local.get $F))+ (drop (local.get $X))+ (drop (local.get $E))++ (local.set $x (i32.const 1))+ (local.set $y (i64.const 2))+ (local.set $z (f32.const 3.21))+ (local.set $w (f64.const 4.321))+ (local.set $F (ref.func $test))+ (local.set $X (local.get $X))+ (local.set $E (local.get $E))++ (local.set $x (i32.const 11))+ (local.set $y (i64.const 22))+ (local.set $z (f32.const 33.21))+ (local.set $w (f64.const 44.321))+ (local.set $F (local.get $F))+ (local.set $X (local.get $X))+ (local.set $E (local.get $E))++ ;; Pop instructions should not be instrumented+ (try+ (do)+ (catch+ (local.set $F (pop funcref))+ )+ )+ (try+ (do)+ (catch+ (local.set $X (pop externref))+ )+ )+ (try+ (do)+ (catch+ (local.set $E (pop exnref))+ )+ )++ ;; Add new instructions here so expected output doesn't change too much, it+ ;; depends on order of instructions in this file.+ (drop (local.get $S))+ (local.set $S (v128.const i32x4 0x00000000 0x00000001 0x00000002 0x00000003))+ )+)
binaryen/test/passes/interesting-pass-mix.txt view
@@ -17,8 +17,7 @@ (i32.const 1) ) (func $ifs (param $0 i32) (result i32)- (if (result i32)- (local.get $0)+ (select (select (i32.const 2) (i32.const 3)@@ -29,6 +28,7 @@ (i32.const 5) (local.get $0) )+ (local.get $0) ) ) (func $loops (param $0 i32)@@ -41,14 +41,16 @@ ) (loop $shape$4$continue (call $trivial)- (br_if $shape$4$continue+ (if (local.get $0)+ (br $shape$4$continue) ) ) (loop $shape$6$continue (call $trivial)- (br_if $shape$6$continue+ (if (local.get $0)+ (br $shape$6$continue) ) ) )@@ -119,8 +121,9 @@ (call $before-and-after (i32.const 9) )- (br_if $shape$4$continue+ (if (local.get $0)+ (br $shape$4$continue) ) ) (call $before-and-after@@ -187,9 +190,12 @@ ) (block $block$7$break (block $switch$3$default- (br_table $block$7$break $block$7$break $block$7$break $switch$3$default- (local.get $0)+ (block $switch$3$case$7+ (br_table $switch$3$case$7 $switch$3$case$7 $switch$3$case$7 $switch$3$default+ (local.get $0)+ ) )+ (br $block$7$break) ) (call $switch (i32.const 2)@@ -212,8 +218,9 @@ (call $if-br-wat (i32.const 1) )- (br_if $block$2$break+ (if (local.get $0)+ (br $block$2$break) ) ) (call $if-br-wat
binaryen/test/passes/legalize-js-interface-minimally.txt view
@@ -1,8 +1,8 @@ (module (type $none_=>_i64 (func (result i64))) (type $i32_=>_none (func (param i32)))- (type $i32_i32_=>_none (func (param i32 i32))) (type $i64_=>_none (func (param i64)))+ (type $i32_i32_=>_none (func (param i32 i32))) (type $none_=>_i32 (func (result i32))) (import "env" "imported" (func $imported (result i64))) (import "env" "setTempRet0" (func $setTempRet0 (param i32)))
binaryen/test/passes/memory-packing_all-features.txt view
@@ -1,15 +1,19 @@ (module- (import "env" "memory" (memory $0 2048 2048)) (import "env" "memoryBase" (global $memoryBase i32))+ (memory $0 2048 2048) ) (module- (import "env" "memory" (memory $0 2048 2048)) (import "env" "memoryBase" (global $memoryBase i32))+ (memory $0 2048 2048) ) (module- (type $none_=>_none (func))- (import "env" "memory" (memory $0 2048 2048))+ (import "env" "memoryBase" (global $memoryBase i32))+ (memory $0 2048 2048) (data (global.get $memoryBase) "waka this cannot be optimized\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00we don\'t know where it will go")+)+(module+ (type $none_=>_none (func))+ (memory $0 1 1) (data (i32.const 1024) "waka this CAN be optimized") (data (i32.const 1107) "we DO know where it will go") (data (i32.const 2057) "zeros before")@@ -17,7 +21,6 @@ (data (i32.const 4000) "zeros\00in\00the\00middle") (data (i32.const 4035) "nice skip here") (data (i32.const 4066) "another\00but no")- (import "env" "memoryBase" (global $memoryBase i32)) (func $nonzero-size-init-of-active-will-trap (block (drop@@ -64,7 +67,7 @@ ) (module (type $none_=>_none (func))- (import "env" "memory" (memory $0 2048 2048))+ (memory $0 2048 2048) (data passive "zeroes at start") (data passive "\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00zeroes at start") (data passive "\00\00\00few zeroes at start")@@ -82,13 +85,13 @@ (data passive "more") (data passive "zeroes") (data passive "no zeroes")+ (global $__mem_segment_drop_state (mut i32) (i32.const 0)) (global $__mem_segment_drop_state_0 (mut i32) (i32.const 0)) (global $__mem_segment_drop_state_1 (mut i32) (i32.const 0))- (global $__mem_segment_drop_state_2 (mut i32) (i32.const 0)) (func $zeroes-at-start (block (if- (global.get $__mem_segment_drop_state_0)+ (global.get $__mem_segment_drop_state) (unreachable) ) (memory.fill@@ -103,7 +106,7 @@ ) ) (block- (global.set $__mem_segment_drop_state_0+ (global.set $__mem_segment_drop_state (i32.const 1) ) (data.drop 0)@@ -267,7 +270,7 @@ (func $even-more-zeroes (block (if- (global.get $__mem_segment_drop_state_1)+ (global.get $__mem_segment_drop_state_0) (unreachable) ) (memory.fill@@ -307,7 +310,7 @@ ) ) (block- (global.set $__mem_segment_drop_state_1+ (global.set $__mem_segment_drop_state_0 (i32.const 1) ) (data.drop 13)@@ -318,7 +321,7 @@ (func $only-zeroes (block (if- (global.get $__mem_segment_drop_state_2)+ (global.get $__mem_segment_drop_state_1) (unreachable) ) (memory.fill@@ -327,7 +330,7 @@ (i32.const 30) ) )- (global.set $__mem_segment_drop_state_2+ (global.set $__mem_segment_drop_state_1 (i32.const 1) ) )@@ -363,7 +366,8 @@ ) (module (type $none_=>_none (func))- (import "env" "memory" (memory $0 2048 2048))+ (import "env" "param" (global $param i32))+ (memory $0 2048 2048) (data passive "even") (data passive "more") (data passive "zeroes")@@ -396,7 +400,7 @@ (data passive "even") (data passive "more") (data passive "zeroes")- (import "env" "param" (global $param i32))+ (global $__mem_segment_drop_state (mut i32) (i32.const 0)) (global $__mem_segment_drop_state_0 (mut i32) (i32.const 0)) (global $__mem_segment_drop_state_1 (mut i32) (i32.const 0)) (global $__mem_segment_drop_state_2 (mut i32) (i32.const 0))@@ -404,7 +408,6 @@ (global $__mem_segment_drop_state_4 (mut i32) (i32.const 0)) (global $__mem_segment_drop_state_5 (mut i32) (i32.const 0)) (global $__mem_segment_drop_state_6 (mut i32) (i32.const 0))- (global $__mem_segment_drop_state_7 (mut i32) (i32.const 0)) (func $nonconst-dest (local $0 i32) (block@@ -412,7 +415,7 @@ (global.get $param) ) (if- (global.get $__mem_segment_drop_state_0)+ (global.get $__mem_segment_drop_state) (unreachable) ) (memory.fill@@ -470,7 +473,7 @@ ) ) (block- (global.set $__mem_segment_drop_state_0+ (global.set $__mem_segment_drop_state (i32.const 1) ) (data.drop 0)@@ -497,7 +500,7 @@ (func $partial-skip-start (block (if- (global.get $__mem_segment_drop_state_1)+ (global.get $__mem_segment_drop_state_0) (unreachable) ) (memory.fill@@ -537,7 +540,7 @@ ) ) (block- (global.set $__mem_segment_drop_state_1+ (global.set $__mem_segment_drop_state_0 (i32.const 1) ) (data.drop 5)@@ -587,7 +590,7 @@ (func $partial-skip-end (block (if- (global.get $__mem_segment_drop_state_2)+ (global.get $__mem_segment_drop_state_1) (unreachable) ) (memory.fill@@ -627,7 +630,7 @@ ) ) (block- (global.set $__mem_segment_drop_state_2+ (global.set $__mem_segment_drop_state_1 (i32.const 1) ) (data.drop 11)@@ -638,7 +641,7 @@ (func $full-skip-end (block (if- (global.get $__mem_segment_drop_state_3)+ (global.get $__mem_segment_drop_state_2) (unreachable) ) (memory.fill@@ -673,7 +676,7 @@ ) ) (block- (global.set $__mem_segment_drop_state_3+ (global.set $__mem_segment_drop_state_2 (i32.const 1) ) (data.drop 14)@@ -684,7 +687,7 @@ (func $slice-zeroes (block (if- (global.get $__mem_segment_drop_state_4)+ (global.get $__mem_segment_drop_state_3) (unreachable) ) (memory.fill@@ -694,7 +697,7 @@ ) ) (block- (global.set $__mem_segment_drop_state_4+ (global.set $__mem_segment_drop_state_3 (i32.const 1) ) (data.drop 17)@@ -724,12 +727,12 @@ (i32.const 16) ) )- (global.get $__mem_segment_drop_state_5)+ (global.get $__mem_segment_drop_state_4) ) (unreachable) ) (block- (global.set $__mem_segment_drop_state_5+ (global.set $__mem_segment_drop_state_4 (i32.const 1) ) (data.drop 23)@@ -747,7 +750,7 @@ (i32.const 16) ) )- (global.get $__mem_segment_drop_state_6)+ (global.get $__mem_segment_drop_state_5) ) (unreachable) )@@ -807,12 +810,12 @@ (i32.const 16) ) )- (global.get $__mem_segment_drop_state_7)+ (global.get $__mem_segment_drop_state_6) ) (unreachable) ) (block- (global.set $__mem_segment_drop_state_7+ (global.set $__mem_segment_drop_state_6 (i32.const 1) ) (data.drop 29)@@ -823,7 +826,7 @@ ) (module (type $none_=>_none (func))- (import "env" "memory" (memory $0 2048 2048))+ (memory $0 2048 2048) (data passive "hi") (data passive "even") (data passive "hi")@@ -834,10 +837,10 @@ (data passive "hi") (data passive "even") (data passive "hi")+ (global $__mem_segment_drop_state (mut i32) (i32.const 0)) (global $__mem_segment_drop_state_0 (mut i32) (i32.const 0)) (global $__mem_segment_drop_state_1 (mut i32) (i32.const 0)) (global $__mem_segment_drop_state_2 (mut i32) (i32.const 0))- (global $__mem_segment_drop_state_3 (mut i32) (i32.const 0)) (func $zero-length-init-zeroes (if (i32.or@@ -848,12 +851,12 @@ (i32.const 16) ) )- (global.get $__mem_segment_drop_state_0)+ (global.get $__mem_segment_drop_state) ) (unreachable) ) (block- (global.set $__mem_segment_drop_state_0+ (global.set $__mem_segment_drop_state (i32.const 1) ) (data.drop 0)@@ -871,12 +874,12 @@ (i32.const 16) ) )- (global.get $__mem_segment_drop_state_1)+ (global.get $__mem_segment_drop_state_0) ) (unreachable) ) (block- (global.set $__mem_segment_drop_state_1+ (global.set $__mem_segment_drop_state_0 (i32.const 1) ) (data.drop 3)@@ -894,12 +897,12 @@ (i32.const 16) ) )- (global.get $__mem_segment_drop_state_2)+ (global.get $__mem_segment_drop_state_1) ) (unreachable) ) (block- (global.set $__mem_segment_drop_state_2+ (global.set $__mem_segment_drop_state_1 (i32.const 1) ) (data.drop 6)@@ -916,12 +919,12 @@ (i32.const 16) ) )- (global.get $__mem_segment_drop_state_3)+ (global.get $__mem_segment_drop_state_2) ) (unreachable) ) (block- (global.set $__mem_segment_drop_state_3+ (global.set $__mem_segment_drop_state_2 (i32.const 1) ) (data.drop 8)@@ -931,7 +934,7 @@ ) (module (type $none_=>_none (func))- (import "env" "memory" (memory $0 2048 2048))+ (memory $0 2048 2048) (data passive "a") (data passive "a") (data passive "a")@@ -1504,4 +1507,68 @@ (data.drop 62) ) )+)+(module+ (memory $0 1 1)+ (data (i32.const 1024) "x")+ (data (i32.const 1024) "\00")+)+(module+ (memory $0 1 1)+ (data (i32.const 1024) "x")+)+(module+ (memory $0 1 1)+ (data (i32.const 1024) "x")+)+(module+ (memory $0 1 1)+ (data (i32.const 1024) "x")+ (data (i32.const 1024) "\00")+ (data (i32.const 4096) "\00")+)+(module+ (import "env" "memoryBase" (global $memoryBase i32))+ (memory $0 1 1)+ (data (i32.const 1024) "x")+ (data (global.get $memoryBase) "\00")+)+(module+ (import "env" "memoryBase" (global $memoryBase i32))+ (memory $0 1 1)+ (data (i32.const 1024) "\00")+ (data (global.get $memoryBase) "x")+)+(module+ (type $none_=>_none (func))+ (memory $0 1 1)+ (data passive "skipped")+ (data passive "included")+ (global $__mem_segment_drop_state (mut i32) (i32.const 0))+ (export "func_54" (func $0))+ (func $0+ (if+ (global.get $__mem_segment_drop_state)+ (unreachable)+ )+ (memory.fill+ (i32.const 0)+ (i32.const 0)+ (i32.const 30)+ )+ (memory.init 1+ (i32.const 30)+ (i32.const 0)+ (i32.const 8)+ )+ )+)+(module+ (import "env" "memory" (memory $0 1 1))+ (data (i32.const 1024) "x")+ (data (i32.const 2048) "\00")+)+(module+ (memory $0 1 1)+ (data (i32.const 1024) "x") )
binaryen/test/passes/memory-packing_all-features.wast view
@@ -1,21 +1,25 @@ (module- (import "env" "memory" (memory $0 2048 2048))+ (memory $0 2048 2048) (import "env" "memoryBase" (global $memoryBase i32)) ;; nothing ) (module- (import "env" "memory" (memory $0 2048 2048))+ (memory $0 2048 2048) (import "env" "memoryBase" (global $memoryBase i32)) (data (i32.const 4066) "") ;; empty ) (module- (import "env" "memory" (memory $0 2048 2048))+ (memory $0 2048 2048) (import "env" "memoryBase" (global $memoryBase i32)) (data (global.get $memoryBase) "waka this cannot be optimized\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00we don't know where it will go")+) +(module+ (memory 1 1)+ (data (i32.const 1024) "waka this CAN be optimized\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00we DO know where it will go") (data (i32.const 2000) "\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00zeros before")@@ -53,7 +57,7 @@ ) (module- (import "env" "memory" (memory $0 2048 2048))+ (memory $0 2048 2048) (data passive "not referenced, delete me") ;; 0 @@ -267,7 +271,7 @@ ) (module- (import "env" "memory" (memory $0 2048 2048))+ (memory $0 2048 2048) (import "env" "param" (global $param i32)) (data passive "\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00even\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00more\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00zeroes\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00") ;; 0@@ -436,7 +440,7 @@ ) (module- (import "env" "memory" (memory $0 2048 2048))+ (memory $0 2048 2048) (data passive "hi\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00even\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00hi") ;; 0 (func $zero-length-init-zeroes@@ -483,7 +487,7 @@ ) (module- (import "env" "memory" (memory $0 2048 2048))+ (memory $0 2048 2048) (data passive "a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00a") ;; 64 ranges of zeroes (func $init-lots@@ -494,4 +498,61 @@ ) (data.drop 0) )+)+(module+ (memory $0 1 1)+ (data (i32.const 1024) "x")+ (data (i32.const 1024) "\00") ;; this tramples the "x", and so must be kept.+)+(module+ (memory $0 1 1)+ (data (i32.const 1024) "x")+ (data (i32.const 1025) "\00")+)+(module+ (memory $0 1 1)+ (data (i32.const 1024) "x")+ (data (i32.const 1023) "\00")+)+(module+ (memory $0 1 1)+ (data (i32.const 1024) "x")+ (data (i32.const 1024) "\00") ;; when we see one bad thing, we give up+ (data (i32.const 4096) "\00")+)+(module+ (memory $0 1 1)+ (import "env" "memoryBase" (global $memoryBase i32))+ (data (i32.const 1024) "x")+ (data (global.get $memoryBase) "\00") ;; this could trample, or not+)+(module+ (memory $0 1 1)+ (import "env" "memoryBase" (global $memoryBase i32))+ (data (i32.const 1024) "\00") ;; this could trample, or not+ (data (global.get $memoryBase) "x")+)+(module+ (memory $0 1 1)+ (data passive "skipped\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00included")+ (export "func_54" (func $0))+ (func $0+ (memory.init 0+ (i32.const 0)+ (i32.const 7)+ (i32.const 38)+ )+ )+)+(module+ ;; we can't optimize on an imported memory without zeroFilledMemory being set.+ (import "env" "memory" (memory $0 1 1))+ (data (i32.const 1024) "x")+ (data (i32.const 2048) "\00")+)+(module+ ;; we can when not imported+ (memory $0 1 1)+ (data (i32.const 1024) "x")+ (data (i32.const 2048) "\00") )
+ binaryen/test/passes/memory-packing_all-features_zero-filled-memory.txt view
@@ -0,0 +1,4 @@+(module+ (import "env" "memory" (memory $0 1 1))+ (data (i32.const 1024) "x")+)
+ binaryen/test/passes/memory-packing_all-features_zero-filled-memory.wast view
@@ -0,0 +1,6 @@+(module+ ;; we can optimize on an imported memory with zeroFilledMemory being set.+ (import "env" "memory" (memory $0 1 1))+ (data (i32.const 1024) "x")+ (data (i32.const 1023) "\00")+)
+ binaryen/test/passes/memory64-lowering_enable-memory64_enable-bulk-memory.txt view
@@ -0,0 +1,168 @@+(module+ (type $none_=>_none (func))+ (memory $0 1 1)+ (data (i32.const 0) "\00\00\00\00\00\00\00\00\00\00")+ (func $func_1+ (local $0 i64)+ (drop+ (i32.load+ (i32.wrap_i64+ (i64.const 4)+ )+ )+ )+ (drop+ (i32.load align=1+ (i32.wrap_i64+ (i64.const 4)+ )+ )+ )+ (drop+ (i32.load align=2+ (i32.wrap_i64+ (i64.const 4)+ )+ )+ )+ (drop+ (i32.load+ (i32.wrap_i64+ (i64.const 4)+ )+ )+ )+ (drop+ (i32.load offset=100+ (i32.wrap_i64+ (i64.const 4)+ )+ )+ )+ (drop+ (i32.load offset=100 align=1+ (i32.wrap_i64+ (i64.const 4)+ )+ )+ )+ (drop+ (i32.load offset=100 align=2+ (i32.wrap_i64+ (i64.const 4)+ )+ )+ )+ (drop+ (i32.load offset=100+ (i32.wrap_i64+ (i64.const 4)+ )+ )+ )+ (drop+ (i32.load offset=100 align=1+ (unreachable)+ )+ )+ (i32.store+ (i32.wrap_i64+ (i64.const 4)+ )+ (i32.const 8)+ )+ (i32.store align=1+ (i32.wrap_i64+ (i64.const 4)+ )+ (i32.const 8)+ )+ (i32.store align=2+ (i32.wrap_i64+ (i64.const 4)+ )+ (i32.const 8)+ )+ (i32.store+ (i32.wrap_i64+ (i64.const 4)+ )+ (i32.const 8)+ )+ (i32.store offset=100+ (i32.wrap_i64+ (i64.const 4)+ )+ (i32.const 8)+ )+ (i32.store offset=100 align=1+ (i32.wrap_i64+ (i64.const 4)+ )+ (i32.const 8)+ )+ (i32.store offset=100 align=2+ (i32.wrap_i64+ (i64.const 4)+ )+ (i32.const 8)+ )+ (i32.store offset=100+ (i32.wrap_i64+ (i64.const 4)+ )+ (i32.const 8)+ )+ (i32.store offset=100 align=1+ (unreachable)+ (i32.const 8)+ )+ (i32.store offset=100 align=1+ (i32.wrap_i64+ (i64.const 4)+ )+ (unreachable)+ )+ (local.set $0+ (i64.extend_i32_u+ (memory.size)+ )+ )+ (local.set $0+ (i64.extend_i32_u+ (memory.grow+ (i32.wrap_i64+ (i64.const 1)+ )+ )+ )+ )+ (memory.init 0+ (i32.wrap_i64+ (i64.const 1)+ )+ (i32.const 2)+ (i32.const 3)+ )+ (memory.fill+ (i32.wrap_i64+ (i64.const 1)+ )+ (i32.const 2)+ (i32.wrap_i64+ (i64.const 3)+ )+ )+ (memory.copy+ (i32.wrap_i64+ (i64.const 1)+ )+ (i32.wrap_i64+ (i64.const 2)+ )+ (i32.wrap_i64+ (i64.const 3)+ )+ )+ )+)
+ binaryen/test/passes/memory64-lowering_enable-memory64_enable-bulk-memory.wast view
@@ -0,0 +1,31 @@+(module+ (memory $0 i64 1 1)+ (data (i32.const 0) "\00\00\00\00\00\00\00\00\00\00")+ (func $func_1+ (local i64)+ (drop (i32.load (i64.const 4)))+ (drop (i32.load align=1 (i64.const 4)))+ (drop (i32.load align=2 (i64.const 4)))+ (drop (i32.load align=4 (i64.const 4)))+ (drop (i32.load offset=100 (i64.const 4)))+ (drop (i32.load offset=100 align=1 (i64.const 4)))+ (drop (i32.load offset=100 align=2 (i64.const 4)))+ (drop (i32.load offset=100 align=4 (i64.const 4)))+ (drop (i32.load offset=100 align=1 (unreachable)))+ (i32.store (i64.const 4) (i32.const 8))+ (i32.store align=1 (i64.const 4) (i32.const 8))+ (i32.store align=2 (i64.const 4) (i32.const 8))+ (i32.store align=4 (i64.const 4) (i32.const 8))+ (i32.store offset=100 (i64.const 4) (i32.const 8))+ (i32.store offset=100 align=1 (i64.const 4) (i32.const 8))+ (i32.store offset=100 align=2 (i64.const 4) (i32.const 8))+ (i32.store offset=100 align=4 (i64.const 4) (i32.const 8))+ (i32.store offset=100 align=1 (unreachable) (i32.const 8))+ (i32.store offset=100 align=1 (i64.const 4) (unreachable))+ (local.set 0 (memory.size))+ (local.set 0 (memory.grow (i64.const 1)))+ (memory.init 0 (i64.const 1) (i32.const 2) (i32.const 3))+ (memory.fill (i64.const 1) (i32.const 2) (i64.const 3))+ (memory.copy (i64.const 1) (i64.const 2) (i64.const 3))+ )+)
binaryen/test/passes/multi_line_table_dwarf.bin.txt view
@@ -424,10 +424,10 @@ (type $none_=>_none (func)) (type $none_=>_i32 (func (result i32))) (import "env" "memory" (memory $mimport$0 0))- (import "env" "__indirect_function_table" (table $timport$1 0 funcref))- (import "env" "__stack_pointer" (global $gimport$2 (mut i32)))- (import "env" "__memory_base" (global $gimport$3 i32))- (import "env" "__table_base" (global $gimport$4 i32))+ (import "env" "__indirect_function_table" (table $timport$0 0 funcref))+ (import "env" "__stack_pointer" (global $gimport$0 (mut i32)))+ (import "env" "__memory_base" (global $gimport$1 i32))+ (import "env" "__table_base" (global $gimport$2 i32)) (global $global$0 i32 (i32.const 0)) (export "__wasm_call_ctors" (func $__wasm_call_ctors)) (export "__wasm_apply_relocs" (func $__wasm_apply_relocs))
binaryen/test/passes/optimize-instructions_all-features.txt view
@@ -1,4664 +1,5707 @@ (module (type $i32_i32_=>_none (func (param i32 i32)))- (type $i32_=>_i32 (func (param i32) (result i32)))- (type $none_=>_i32 (func (result i32)))- (type $i32_i64_=>_none (func (param i32 i64)))- (type $none_=>_none (func))- (type $i32_i32_=>_i32 (func (param i32 i32) (result i32)))- (type $i32_=>_none (func (param i32)))- (type $none_=>_i64 (func (result i64)))- (type $i64_=>_i64 (func (param i64) (result i64)))- (type $i32_i32_i64_i64_=>_none (func (param i32 i32 i64 i64)))- (type $i32_i64_f32_=>_none (func (param i32 i64 f32)))- (type $i32_i64_f32_f64_=>_none (func (param i32 i64 f32 f64)))- (type $none_=>_anyref (func (result anyref)))- (type $i32_i32_i32_=>_none (func (param i32 i32 i32)))- (type $i32_i32_i32_f64_=>_none (func (param i32 i32 i32 f64)))- (type $i32_i32_f64_f64_=>_none (func (param i32 i32 f64 f64)))- (type $i32_i64_f64_i32_=>_none (func (param i32 i64 f64 i32)))- (type $f32_f64_=>_none (func (param f32 f64)))- (type $none_=>_f64 (func (result f64)))- (memory $0 0)- (export "load-off-2" (func $load-off-2))- (func $f (param $i1 i32) (param $i2 i64)- (if- (i32.eqz- (local.get $i1)- )- (drop- (i32.const 10)- )- )- (if- (local.get $i1)- (drop- (i32.const 12)- )- (drop- (i32.const 11)- )- )- (if- (i64.eqz- (local.get $i2)- )- (drop- (i32.const 11)- )- (drop- (i32.const 12)- )- )- (drop- (i32.le_u- (i32.const 1)- (i32.const 2)- )- )- (drop- (i32.lt_u- (i32.const 1)- (i32.const 2)- )- )- (drop- (i32.ge_u- (i32.const 1)- (i32.const 2)- )- )- (drop- (i32.gt_u- (i32.const 1)- (i32.const 2)- )- )- (drop- (i32.le_u- (i32.const 1)- (i32.const 2)- )- )- (drop- (i32.lt_u- (i32.const 1)- (i32.const 2)- )- )- (drop- (i32.ge_u- (i32.const 1)- (i32.const 2)- )- )- (drop- (i32.gt_u- (i32.const 1)- (i32.const 2)- )- )- (drop- (i32.eqz- (f32.gt- (f32.const 1)- (f32.const 2)- )- )- )- (drop- (i32.eqz- (f32.ge- (f32.const 1)- (f32.const 2)- )- )- )- (drop- (i32.eqz- (f32.lt- (f32.const 1)- (f32.const 2)- )- )- )- (drop- (i32.eqz- (f32.le- (f32.const 1)- (f32.const 2)- )- )- )- (drop- (i32.eqz- (f64.gt- (f64.const 1)- (f64.const 2)- )- )- )- (drop- (i32.eqz- (f64.ge- (f64.const 1)- (f64.const 2)- )- )- )- (drop- (i32.eqz- (f64.lt- (f64.const 1)- (f64.const 2)- )- )- )- (drop- (i32.eqz- (f64.le- (f64.const 1)- (f64.const 2)- )- )- )- (drop- (f32.ne- (f32.const 1)- (f32.const 2)- )- )- (drop- (f32.eq- (f32.const 1)- (f32.const 2)- )- )- (drop- (f64.ne- (f64.const 1)- (f64.const 2)- )- )- (drop- (f64.eq- (f64.const 1)- (f64.const 2)- )- )- (drop- (i32.eqz- (i32.const 100)- )- )- (drop- (i32.eq- (i32.const 0)- (i32.const 100)- )- )- (drop- (i32.eqz- (i32.const 0)- )- )- (drop- (i64.eqz- (i64.const 100)- )- )- (drop- (i64.eq- (i64.const 0)- (i64.const 100)- )- )- (drop- (i64.eqz- (i64.const 0)- )- )- (if- (i32.const 123)- (nop)- )- (if- (try (result i32)- (do- (i32.const 123)- )- (catch- (drop- (pop exnref)- )- (i32.const 456)- )- )- (nop)- )- (drop- (select- (i32.const 102)- (i32.const 101)- (local.get $i1)- )- )- (drop- (select- (local.tee $i1- (i32.const 103)- )- (local.tee $i1- (i32.const 104)- )- (i32.eqz- (local.get $i1)- )- )- )- (drop- (i32.const 0)- )- )- (func $load-store- (drop- (i32.load8_u- (i32.const 0)- )- )- (drop- (i32.load8_u- (i32.const 1)- )- )- (drop- (i32.and- (i32.load8_s- (i32.const 2)- )- (i32.const 254)- )- )- (drop- (i32.and- (i32.load8_u- (i32.const 3)- )- (i32.const 1)- )- )- (drop- (i32.load16_u- (i32.const 4)- )- )- (drop- (i32.load16_u- (i32.const 5)- )- )- (drop- (i32.and- (i32.load16_s- (i32.const 6)- )- (i32.const 65534)- )- )- (drop- (i32.and- (i32.load16_u- (i32.const 7)- )- (i32.const 1)- )- )- (i32.store8- (i32.const 8)- (i32.const -1)- )- (i32.store8- (i32.const 9)- (i32.and- (i32.const -2)- (i32.const 254)- )- )- (i32.store16- (i32.const 10)- (i32.const -3)- )- (i32.store16- (i32.const 11)- (i32.and- (i32.const -4)- (i32.const 65534)- )- )- (i64.store8- (i32.const 11)- (i64.const 1)- )- (i64.store16- (i32.const 11)- (i64.const 2)- )- (i64.store32- (i32.const 11)- (i64.const 3)- )- )- (func $and-neg1- (drop- (i32.const 100)- )- (drop- (i32.and- (i32.const 100)- (i32.const 1)- )- )- )- (func $and-pos1- (drop- (i32.eqz- (i32.const 1000)- )- )- (drop- (i32.eqz- (i32.const 1000)- )- )- (drop- (i32.and- (i32.const 100)- (i32.const 1)- )- )- (drop- (i32.lt_u- (i32.const 2000)- (i32.const 3000)- )- )- )- (func $canonicalize (param $x i32) (param $y i32) (param $fx f64) (param $fy f64)- (drop- (i32.and- (unreachable)- (i32.const 1)- )- )- (drop- (i32.and- (i32.const 1)- (unreachable)- )- )- (drop- (i32.div_s- (unreachable)- (i32.const 1)- )- )- (drop- (i32.div_s- (i32.const 1)- (unreachable)- )- )- (drop- (i32.and- (i32.const 1)- (i32.const 2)- )- )- (drop- (i32.and- (local.get $x)- (i32.const 3)- )- )- (drop- (i32.and- (local.get $x)- (i32.const 4)- )- )- (drop- (i32.and- (local.get $x)- (local.get $y)- )- )- (drop- (i32.and- (local.get $x)- (local.get $y)- )- )- (drop- (i32.and- (local.tee $x- (i32.const -4)- )- (local.get $y)- )- )- (drop- (i32.and- (block $block (result i32)- (i32.const -5)- )- (local.get $x)- )- )- (drop- (i32.and- (block $block4 (result i32)- (i32.const -6)- )- (local.get $x)- )- )- (drop- (i32.and- (block $block5 (result i32)- (i32.const 5)- )- (loop $loop-in (result i32)- (i32.const 6)- )- )- )- (drop- (i32.and- (block $block7 (result i32)- (i32.const 8)- )- (loop $loop-in6 (result i32)- (i32.const 7)- )- )- )- (drop- (i32.and- (block $block9 (result i32)- (i32.const 10)- )- (loop $loop-in8 (result i32)- (call $and-pos1)- (i32.const 9)- )- )- )- (drop- (i32.and- (block $block11 (result i32)- (call $and-pos1)- (i32.const 12)- )- (loop $loop-in10 (result i32)- (i32.const 11)- )- )- )- (drop- (i32.and- (loop $loop-in12 (result i32)- (call $and-pos1)- (i32.const 13)- )- (block $block13 (result i32)- (call $and-pos1)- (i32.const 14)- )- )- )- (drop- (i32.and- (block $block14 (result i32)- (call $and-pos1)- (i32.const 14)- )- (loop $loop-in15 (result i32)- (call $and-pos1)- (i32.const 13)- )- )- )- (drop- (i32.and- (block $block16 (result i32)- (i32.const 15)- )- (local.get $x)- )- )- (drop- (i32.and- (block $block17 (result i32)- (i32.const 15)- )- (local.get $x)- )- )- (drop- (i32.and- (i32.gt_u- (i32.const 16)- (i32.const 17)- )- (i32.gt_u- (i32.const 18)- (i32.const 19)- )- )- )- (drop- (i32.and- (i32.gt_u- (i32.const 20)- (i32.const 21)- )- (i32.gt_u- (i32.const 22)- (i32.const 23)- )- )- )- (drop- (i32.add- (i32.ctz- (local.get $x)- )- (i32.ctz- (local.get $y)- )- )- )- (drop- (i32.add- (i32.ctz- (local.get $y)- )- (i32.ctz- (local.get $x)- )- )- )- (drop- (i32.add- (i32.ctz- (local.get $x)- )- (i32.eqz- (local.get $y)- )- )- )- (drop- (i32.add- (i32.ctz- (local.get $y)- )- (i32.eqz- (local.get $x)- )- )- )- )- (func $ne0 (result i32)- (if- (call $ne0)- (nop)- )- (if- (call $ne0)- (nop)- )- (if- (i32.or- (call $ne0)- (call $ne0)- )- (nop)- )- (if- (i32.and- (i32.ne- (call $ne0)- (i32.const 0)- )- (i32.ne- (call $ne0)- (i32.const 0)- )- )- (nop)- )- (i32.const 1)- )- (func $recurse-bool- (if- (if (result i32)- (i32.const 1)- (call $ne0)- (call $ne1)- )- (nop)- )- (if- (block $block (result i32)- (nop)- (call $ne0)- )- (nop)- )- )- (func $ne1 (result i32)- (unreachable)- )- (func $load-off-2 (param $0 i32) (result i32)- (i32.store- (i32.const 6)- (local.get $0)- )- (i32.store- (i32.const 6)- (local.get $0)- )- (i32.store offset=2- (i32.add- (local.get $0)- (i32.const 5)- )- (local.get $0)- )- (i32.store offset=2- (i32.add- (local.get $0)- (i32.const 7)- )- (local.get $0)- )- (i32.store offset=2- (i32.add- (local.get $0)- (i32.const -11)- )- (local.get $0)- )- (i32.store offset=2- (i32.add- (local.get $0)- (i32.const -13)- )- (local.get $0)- )- (i32.store- (i32.const 4)- (local.get $0)- )- (i32.store offset=2- (i32.const -2)- (local.get $0)- )- (i32.store- (i32.const 25)- (local.get $0)- )- (i32.store offset=2- (i32.const -25)- (local.get $0)- )- (drop- (i32.load- (i32.const 8)- )- )- (drop- (i32.load- (i32.const 8)- )- )- (drop- (i32.load offset=2- (i32.add- (local.get $0)- (i32.const 6)- )- )- )- (drop- (i32.load- (i32.const 10)- )- )- (i32.load offset=2- (i32.add- (local.get $0)- (i32.const 10)- )- )- )- (func $sign-ext (param $0 i32) (param $1 i32)- (drop- (i32.eqz- (i32.and- (local.get $0)- (i32.const 255)- )- )- )- (drop- (i32.eqz- (i32.and- (local.get $0)- (i32.const 65535)- )- )- )- (drop- (i32.eqz- (i32.and- (local.get $0)- (i32.const 134217727)- )- )- )- (drop- (i32.eq- (i32.and- (local.get $0)- (i32.const 255)- )- (i32.const 100)- )- )- (drop- (i32.eq- (i32.and- (local.get $0)- (i32.const 255)- )- (i32.const -2147483648)- )- )- (drop- (i32.eq- (i32.and- (local.get $0)- (i32.const 255)- )- (i32.const 107)- )- )- (drop- (i32.eq- (i32.and- (local.get $0)- (i32.const 255)- )- (i32.and- (local.get $1)- (i32.const 255)- )- )- )- (drop- (i32.eq- (i32.and- (local.get $0)- (i32.const 65535)- )- (i32.and- (local.get $1)- (i32.const 65535)- )- )- )- (drop- (i32.eqz- (i32.shr_s- (i32.shl- (local.get $0)- (i32.const 24)- )- (i32.const 23)- )- )- )- (drop- (i32.eqz- (i32.shr_u- (i32.shl- (local.get $0)- (i32.const 24)- )- (i32.const 24)- )- )- )- (drop- (i32.lt_s- (i32.shr_s- (i32.shl- (local.get $0)- (i32.const 24)- )- (i32.const 24)- )- (i32.const 0)- )- )- )- (func $sign-ext-input (param $0 i32) (param $1 i32)- (drop- (i32.const 100)- )- (drop- (i32.const 127)- )- (drop- (i32.shr_s- (i32.shl- (i32.const 128)- (i32.const 24)- )- (i32.const 24)- )- )- (drop- (i32.shr_s- (i32.shl- (local.get $0)- (i32.const 24)- )- (i32.const 24)- )- )- (drop- (i32.shr_s- (i32.shl- (unreachable)- (i32.const 24)- )- (i32.const 24)- )- )- (drop- (i32.shr_u- (i32.const 1)- (i32.const 1)- )- )- (drop- (i32.and- (i32.const 127)- (i32.const 128)- )- )- (drop- (i32.shr_s- (i32.shl- (i32.and- (i32.const 128)- (i32.const 129)- )- (i32.const 24)- )- (i32.const 24)- )- )- (drop- (i32.xor- (i32.const 127)- (i32.const 126)- )- )- (drop- (i32.shr_s- (i32.shl- (i32.xor- (i32.const 127)- (i32.const 128)- )- (i32.const 24)- )- (i32.const 24)- )- )- (drop- (i32.or- (i32.const 127)- (i32.const 126)- )- )- (drop- (i32.shr_s- (i32.shl- (i32.or- (i32.const 127)- (i32.const 128)- )- (i32.const 24)- )- (i32.const 24)- )- )- (drop- (i32.shr_s- (i32.shl- (i32.const 32)- (i32.const 26)- )- (i32.const 24)- )- )- (drop- (i32.shl- (i32.const 32)- (i32.const 1)- )- )- (drop- (i32.shr_s- (i32.shl- (i32.const 32)- (i32.const 27)- )- (i32.const 24)- )- )- (drop- (i32.shr_s- (i32.shl- (i32.shr_u- (i32.const 256)- (i32.const 1)- )- (i32.const 24)- )- (i32.const 24)- )- )- (drop- (i32.shr_u- (i32.const 256)- (i32.const 2)- )- )- (drop- (i32.shr_u- (i32.const 128)- (i32.const 3)- )- )- (drop- (i32.shr_s- (i32.shl- (i32.shr_u- (i32.const 256)- (i32.const 1)- )- (i32.const 24)- )- (i32.const 24)- )- )- (drop- (i32.shr_u- (i32.const 256)- (i32.const 2)- )- )- (drop- (i32.shr_u- (i32.const 128)- (i32.const 3)- )- )- (drop- (i32.shr_s- (i32.shl- (i32.const -1)- (i32.const 24)- )- (i32.const 24)- )- )- (drop- (i32.shr_u- (i32.and- (i32.const -1)- (i32.const 2147483647)- )- (i32.const 31)- )- )- (drop- (i32.const 0)- )- (drop- (f32.le- (f32.const -1)- (f32.const -1)- )- )- (drop- (i32.clz- (i32.const 0)- )- )- (drop- (i32.shr_s- (i32.shl- (i32.clz- (i32.const 0)- )- (i32.const 26)- )- (i32.const 24)- )- )- (drop- (i32.shr_s- (i32.shl- (i32.clz- (i32.const 0)- )- (i32.const 27)- )- (i32.const 24)- )- )- (drop- (i32.wrap_i64- (i64.clz- (i64.const 0)- )- )- )- (drop- (i32.shr_s- (i32.shl- (i32.wrap_i64- (i64.clz- (i64.const 0)- )- )- (i32.const 25)- )- (i32.const 24)- )- )- (drop- (i32.shr_s- (i32.shl- (i32.wrap_i64- (i64.clz- (i64.const 0)- )- )- (i32.const 26)- )- (i32.const 24)- )- )- (drop- (i32.eqz- (i32.const -1)- )- )- (drop- (i32.shr_s- (i32.shl- (i32.shr_u- (i32.wrap_i64- (i64.const -1)- )- (i32.const 24)- )- (i32.const 24)- )- (i32.const 24)- )- )- (drop- (i32.shr_u- (i32.wrap_i64- (i64.const -1)- )- (i32.const 25)- )- )- (drop- (i32.shr_s- (i32.shl- (i32.shr_u- (i32.wrap_i64- (i64.extend_i32_s- (i32.const -1)- )- )- (i32.const 24)- )- (i32.const 24)- )- (i32.const 24)- )- )- (drop- (i32.shr_u- (i32.wrap_i64- (i64.extend_i32_s- (i32.const -1)- )- )- (i32.const 25)- )- )- (drop- (i32.shr_s- (i32.shl- (i32.xor- (local.get $0)- (i32.le_u- (local.get $0)- (i32.const 2)- )- )- (i32.const 24)- )- (i32.const 24)- )- )- )- (func $linear-sums (param $0 i32) (param $1 i32)- (drop- (i32.add- (i32.shl- (local.get $0)- (i32.const 4)- )- (local.get $1)- )- )- (drop- (i32.add- (i32.add- (local.get $1)- (i32.shl- (local.get $0)- (i32.const 3)- )- )- (i32.const 12)- )- )- (drop- (i32.const 4)- )- (drop- (i32.const 18)- )- (drop- (i32.const 6)- )- (drop- (i32.const -4)- )- (drop- (i32.const 2)- )- (drop- (i32.const 1)- )- (drop- (i32.const 26)- )- (drop- (i32.const -20)- )- (drop- (i32.const 22)- )- (drop- (i32.add- (i32.shl- (i32.const 1)- (local.get $0)- )- (i32.const 14)- )- )- (drop- (i32.add- (i32.shl- (local.get $1)- (i32.const 3)- )- (i32.const -66)- )- )- (drop- (i32.const 44)- )- (drop- (i32.add- (i32.mul- (local.get $0)- (i32.const 10)- )- (i32.const 14)- )- )- (drop- (i32.add- (i32.shl- (local.get $0)- (i32.const 1)- )- (i32.const 34)- )- )- (drop- (local.get $0)- )- )- (func $almost-sign-ext (param $0 i32)- (drop- (i32.shr_s- (i32.shl- (i32.const 100)- (i32.const 25)- )- (i32.const 24)- )- )- (drop- (i32.shl- (i32.const 50)- (i32.const 1)- )- )- )- (func $squaring (param $0 i32) (param $1 i32)- (drop- (i32.and- (local.get $0)- (i32.const 8)- )- )- (drop- (i32.and- (local.get $0)- (i32.const 11)- )- )- (drop- (i32.and- (local.get $0)- (i32.const 8)- )- )- (drop- (i32.or- (local.get $0)- (i32.const 203)- )- )- (drop- (i32.shl- (local.get $0)- (i32.const 19)- )- )- (drop- (i32.shr_s- (local.get $0)- (i32.const 19)- )- )- (drop- (i32.shr_u- (local.get $0)- (i32.const 19)- )- )- (drop- (i32.shr_u- (i32.shr_s- (local.get $0)- (i32.const 11)- )- (i32.const 8)- )- )- )- (func $sign-ext-ne (param $0 i32) (param $1 i32)- (drop- (i32.ne- (i32.and- (local.get $0)- (i32.const 255)- )- (i32.const -2147483648)- )- )- (drop- (i32.ne- (i32.and- (local.get $0)- (i32.const 255)- )- (i32.const -2147483648)- )- )- (drop- (i32.ne- (i32.and- (local.get $0)- (i32.const 255)- )- (i32.const 107)- )- )- (drop- (i32.ne- (i32.and- (local.get $0)- (i32.const 255)- )- (i32.const 111)- )- )- (drop- (i32.ne- (i32.and- (local.get $0)- (i32.const 255)- )- (i32.and- (local.get $1)- (i32.const 255)- )- )- )- )- (func $sign-ext-eqz (param $0 i32) (param $1 i32)- (drop- (i32.eqz- (i32.and- (local.get $0)- (i32.const 255)- )- )- )- )- (func $sign-ext-boolean (param $0 i32) (param $1 i32)- (drop- (if (result i32)- (i32.and- (local.get $0)- (i32.const 255)- )- (i32.const 100)- (i32.const 200)- )- )- )- (func $add-sub-zero (param $0 i32) (param $1 i32)- (drop- (local.get $0)- )- (drop- (local.get $0)- )- )- (func $store-signext (param $0 i32)- (i32.store8- (i32.const 8)- (local.get $0)- )- (i32.store8- (i32.const 8)- (i32.shr_s- (i32.shl- (local.get $0)- (i32.const 25)- )- (i32.const 25)- )- )- (i32.store8- (i32.const 8)- (local.get $0)- )- (i32.store16- (i32.const 8)- (local.get $0)- )- (i32.store16- (i32.const 8)- (i32.shr_s- (i32.shl- (local.get $0)- (i32.const 17)- )- (i32.const 17)- )- )- (i32.store16- (i32.const 8)- (local.get $0)- )- (i32.store- (i32.const 8)- (i32.shr_s- (i32.shl- (local.get $0)- (i32.const 16)- )- (i32.const 16)- )- )- (i32.store- (i32.const 8)- (i32.shr_s- (i32.shl- (local.get $0)- (i32.const 8)- )- (i32.const 8)- )- )- )- (func $sign-ext-tee (param $0 i32) (param $1 i32)- (drop- (i32.shr_s- (i32.shl- (local.tee $0- (i32.const 128)- )- (i32.const 24)- )- (i32.const 24)- )- )- (drop- (local.tee $0- (i32.const 127)- )- )- )- (func $sign-ext-load (param $0 i32) (param $1 i32)- (drop- (i32.load8_s- (i32.const 256)- )- )- (drop- (i32.shr_s- (i32.shl- (i32.shr_u- (i32.load8_s- (i32.const 256)- )- (i32.const 1)- )- (i32.const 24)- )- (i32.const 24)- )- )- (drop- (i32.shr_u- (i32.load8_u- (i32.const 256)- )- (i32.const 1)- )- )- (drop- (i32.load16_s- (i32.const 256)- )- )- (drop- (local.tee $1- (i32.load8_s- (i32.const 1)- )- )- )- (drop- (i32.shr_s- (i32.shl- (local.tee $1- (i32.load8_u- (i32.const 1)- )- )- (i32.const 24)- )- (i32.const 24)- )- )- (drop- (i32.and- (local.tee $1- (i32.load8_s- (i32.const 1)- )- )- (i32.const 255)- )- )- (drop- (local.tee $1- (i32.load8_u- (i32.const 1)- )- )- )- )- (func $mask-bits (param $0 i32) (param $1 i32)- (drop- (local.tee $0- (i32.const 127)- )- )- (drop- (local.tee $0- (i32.const 128)- )- )- (drop- (i32.and- (local.tee $0- (i32.const 128)- )- (i32.const 254)- )- )- (drop- (i32.and- (local.tee $0- (i32.const 128)- )- (i32.const 1279)- )- )- (drop- (i32.and- (local.tee $0- (i32.const 128)- )- (i32.const 1290)- )- )- (drop- (local.tee $0- (i32.const 128)- )- )- (drop- (local.tee $0- (i32.const 128)- )- )- (drop- (i32.and- (local.tee $0- (i32.const 128)- )- (i32.const 127)- )- )- )- (func $local-info-zero-ext (param $0 i32) (param $1 i32)- (local $x i32)- (local $y i32)- (local $z i32)- (local $w i32)- (local.set $x- (i32.const 212)- )- (drop- (local.get $x)- )- (local.set $y- (i32.const 500)- )- (drop- (i32.and- (local.get $y)- (i32.const 255)- )- )- (local.set $0- (i32.const 212)- )- (drop- (i32.and- (local.get $0)- (i32.const 255)- )- )- (local.set $z- (i32.const 212)- )- (local.set $z- (i32.const 220)- )- (drop- (local.get $z)- )- (local.set $w- (i32.const 212)- )- (local.set $w- (i32.const 1000)- )- (drop- (i32.and- (local.get $w)- (i32.const 255)- )- )- )- (func $local-info-sign-ext-bitsize (param $0 i32) (param $1 i32)- (local $x i32)- (local $y i32)- (local $z i32)- (local $w i32)- (local.set $x- (i32.const 127)- )- (drop- (local.get $x)- )- (local.set $y- (i32.const 128)- )- (drop- (i32.shr_s- (i32.shl- (local.get $y)- (i32.const 24)- )- (i32.const 24)- )- )- (local.set $0- (i32.const 127)- )- (drop- (i32.shr_s- (i32.shl- (local.get $0)- (i32.const 24)- )- (i32.const 24)- )- )- (local.set $z- (i32.const 127)- )- (local.set $z- (i32.const 100)- )- (drop- (local.get $z)- )- (local.set $w- (i32.const 127)- )- (local.set $w- (i32.const 150)- )- (drop- (i32.shr_s- (i32.shl- (local.get $w)- (i32.const 24)- )- (i32.const 24)- )- )- )- (func $local-info-sign-ext-already-exted (param $0 i32) (param $1 i32)- (local $x i32)- (local $y i32)- (local $z i32)- (local $w i32)- (local.set $x- (i32.shr_s- (i32.shl- (local.get $0)- (i32.const 24)- )- (i32.const 24)- )- )- (drop- (local.get $x)- )- (local.set $y- (i32.shr_s- (i32.shl- (local.get $0)- (i32.const 16)- )- (i32.const 16)- )- )- (drop- (i32.shr_s- (i32.shl- (local.get $y)- (i32.const 24)- )- (i32.const 24)- )- )- (local.set $0- (i32.shr_s- (i32.shl- (local.get $0)- (i32.const 24)- )- (i32.const 24)- )- )- (drop- (i32.shr_s- (i32.shl- (local.get $0)- (i32.const 24)- )- (i32.const 24)- )- )- (local.set $z- (i32.shr_s- (i32.shl- (local.get $0)- (i32.const 24)- )- (i32.const 24)- )- )- (local.set $z- (i32.shr_s- (i32.shl- (local.get $1)- (i32.const 24)- )- (i32.const 24)- )- )- (drop- (local.get $z)- )- (local.set $w- (i32.shr_s- (i32.shl- (local.get $0)- (i32.const 24)- )- (i32.const 24)- )- )- (local.set $w- (i32.shr_s- (i32.shl- (local.get $0)- (i32.const 23)- )- (i32.const 24)- )- )- (drop- (i32.shr_s- (i32.shl- (local.get $w)- (i32.const 24)- )- (i32.const 24)- )- )- (drop- (i32.shr_s- (i32.shl- (local.get $0)- (i32.const 24)- )- (i32.const 23)- )- )- )- (func $signed-loads-fill-the-bits (param $$e i32) (result i32)- (local $$0 i32)- (local $$conv i32)- (local.set $$0- (i32.load8_s- (i32.const 1024)- )- )- (local.set $$conv- (i32.and- (local.get $$0)- (i32.const 255)- )- )- (return- (i32.eq- (local.get $$e)- (local.get $$conv)- )- )- )- (func $local-info-sign-ext-already-exted-by-load (param $0 i32) (param $1 i32)- (local $x i32)- (local $y i32)- (local $z i32)- (local $w i32)- (local.set $x- (i32.load8_s- (i32.const 1024)- )- )- (drop- (local.get $x)- )- (local.set $y- (i32.load8_u- (i32.const 1024)- )- )- (drop- (i32.shr_s- (i32.shl- (local.get $y)- (i32.const 24)- )- (i32.const 24)- )- )- (local.set $z- (i32.load16_s- (i32.const 1024)- )- )- (drop- (i32.shr_s- (i32.shl- (local.get $z)- (i32.const 24)- )- (i32.const 24)- )- )- )- (func $compare-load-s-sign-extend (param $0 i32) (param $1 i32)- (drop- (i32.eq- (i32.load8_u- (local.get $0)- )- (i32.and- (local.get $1)- (i32.const 255)- )- )- )- (drop- (i32.eq- (i32.load8_u- (local.get $0)- )- (i32.and- (local.get $1)- (i32.const 255)- )- )- )- (drop- (i32.eq- (i32.load8_u- (local.get $0)- )- (i32.shr_s- (i32.shl- (local.get $1)- (i32.const 24)- )- (i32.const 24)- )- )- )- (drop- (i32.eq- (i32.load8_s- (local.get $0)- )- (i32.shr_s- (i32.shl- (local.get $1)- (i32.const 16)- )- (i32.const 16)- )- )- )- (drop- (i32.eq- (i32.load8_u- (local.get $0)- )- (i32.shr_s- (i32.shl- (local.get $1)- (i32.const 24)- )- (i32.const 24)- )- )- )- (drop- (i32.eq- (i32.load8_s- (local.get $0)- )- (i32.shr_s- (i32.shl- (local.get $1)- (i32.const 16)- )- (i32.const 16)- )- )- )- )- (func $unsign-diff-sizes (param $x i32) (param $y i32) (result i32)- (i32.ne- (i32.shr_s- (i32.shl- (call $unsign-diff-sizes- (i32.const -1)- (i32.const 5)- )- (i32.const 24)- )- (i32.const 24)- )- (i32.shr_s- (i32.shl- (call $unsign-diff-sizes- (i32.const 1)- (i32.const 2006)- )- (i32.const 16)- )- (i32.const 16)- )- )- )- (func $unsign-same-sizes (param $x i32) (param $y i32) (result i32)- (i32.ne- (i32.and- (call $unsign-same-sizes- (i32.const -1)- (i32.const 5)- )- (i32.const 255)- )- (i32.and- (call $unsign-same-sizes- (i32.const 1)- (i32.const 2006)- )- (i32.const 255)- )- )- )- (func $fuzz-almost-sign-ext- (drop- (i32.shr_s- (i32.shl- (i32.load16_u- (i32.const 2278)- )- (i32.const 17)- )- (i32.const 16)- )- )- (drop- (i32.shr_s- (i32.shl- (i32.load16_u- (i32.const 2278)- )- (i32.const 17)- )- (i32.const 16)- )- )- )- (func $fuzz-comp-impossible (param $x i32)- (drop- (i32.eq- (i32.and- (local.get $x)- (i32.const 65535)- )- (i32.const -2147483648)- )- )- (drop- (i32.eq- (i32.and- (local.get $x)- (i32.const 255)- )- (i32.const -2147483648)- )- )- (drop- (i32.eq- (i32.and- (local.get $x)- (i32.const 255)- )- (i32.const 127)- )- )- (drop- (i32.eq- (i32.and- (local.get $x)- (i32.const 255)- )- (i32.const -2147483648)- )- )- (drop- (i32.eq- (i32.and- (local.get $x)- (i32.const 255)- )- (i32.const -2147483648)- )- )- (drop- (i32.eq- (i32.and- (local.get $x)- (i32.const 255)- )- (i32.const -2147483648)- )- )- (drop- (i32.eq- (i32.and- (local.get $x)- (i32.const 255)- )- (i32.const 252)- )- )- )- (func $if-parallel (param $0 i32) (param $1 i32)- (drop- (i32.add- (local.get $1)- (i32.const 1)- )- )- (drop- (block (result i32)- (drop- (local.tee $0- (local.get $1)- )- )- (i32.add- (local.get $1)- (i32.const 1)- )- )- )- (drop- (block (result i32)- (i32.add- (local.get $1)- (unreachable)- )- )- )- (drop- (block (result i32)- (drop- (local.tee $0- (local.get $1)- )- )- (i32.add- (local.get $1)- (unreachable)- )- )- )- (drop- (if (result i32)- (unreachable)- (i32.add- (local.get $1)- (unreachable)- )- (i32.add- (local.get $1)- (unreachable)- )- )- )- )- (func $select-parallel (param $0 i32) (param $1 i32)- (drop- (i32.add- (local.get $1)- (i32.const 1)- )- )- (drop- (select- (local.tee $0- (local.get $1)- )- (local.tee $0- (local.get $1)- )- (local.get $0)- )- )- (drop- (block (result i32)- (drop- (local.tee $0- (local.get $1)- )- )- (i32.add- (local.get $1)- (i32.const 1)- )- )- )- (drop- (select- (local.tee $0- (local.get $1)- )- (local.tee $0- (local.get $1)- )- (local.tee $0- (local.get $1)- )- )- )- (drop- (select- (local.tee $0- (local.get $1)- )- (local.tee $0- (local.get $1)- )- (unreachable)- )- )- )- (func $zero-shifts-is-not-sign-ext- (drop- (i32.eq- (i32.load16_s align=1- (i32.const 790656516)- )- (i32.const -5431187)- )- )- (drop- (i32.eq- (i32.shl- (i32.load16_s align=1- (i32.const 790656516)- )- (i32.const 1)- )- (i32.const -5431187)- )- )- )- (func $zero-ops (result i32)- (return- (i32.eq- (i32.load16_s align=1- (i32.const 790656516)- )- (i32.const -1337)- )- )- )- (func $sign-ext-1-and-ne (result i32)- (i32.ne- (i32.and- (call $sign-ext-1-and-ne)- (i32.const 2147483647)- )- (i32.const -2147483648)- )- )- (func $neg-shifts-and-255 (result i32)- (i32.and- (i32.const -99)- (i32.const 255)- )- )- (func $neg-shifts-and-255-b (result i32)- (i32.and- (i32.const -2349025)- (i32.const 255)- )- )- (func $shifts-square-overflow (param $x i32) (result i32)- (i32.shr_u- (i32.shr_u- (local.get $x)- (i32.const 31)- )- (i32.const 31)- )- )- (func $shifts-square-no-overflow-small (param $x i32) (result i32)- (i32.shr_u- (local.get $x)- (i32.const 9)- )- )- (func $shifts-square-overflow-64 (param $x i64) (result i64)- (i64.shr_u- (i64.shr_u- (local.get $x)- (i64.const 63)- )- (i64.const 63)- )- )- (func $shifts-square-no-overflow-small-64 (param $x i64) (result i64)- (i64.shr_u- (local.get $x)- (i64.const 9)- )- )- (func $shifts-square-unreachable (param $x i32) (result i32)- (i32.shr_u- (i32.shr_u- (unreachable)- (i32.const 1031)- )- (i32.const 4098)- )- )- (func $mix-shifts (result i32)- (i32.shr_u- (i32.shl- (i32.const 23)- (i32.const 3)- )- (i32.const 8)- )- )- (func $actually-no-shifts (result i32)- (i32.const 33)- )- (func $less-shifts-than-it-seems (param $x i32) (result i32)- (i32.const 4800)- )- (func $and-popcount32 (result i32)- (i32.and- (i32.popcnt- (i32.const -1)- )- (i32.const 31)- )- )- (func $and-popcount32-big (result i32)- (i32.popcnt- (i32.const -1)- )- )- (func $and-popcount64 (result i64)- (i64.and- (i64.popcnt- (i64.const -1)- )- (i64.const 63)- )- )- (func $and-popcount64-big (result i64)- (i64.and- (i64.popcnt- (i64.const -1)- )- (i64.const 127)- )- )- (func $and-popcount64-bigger (result i64)- (i64.and- (i64.popcnt- (i64.const -1)- )- (i64.const 255)- )- )- (func $optimizeAddedConstants-filters-through-nonzero (result i32)- (i32.add- (i32.shl- (i32.const -536870912)- (i32.wrap_i64- (i64.const 0)- )- )- (i32.const -31744)- )- )- (func $optimizeAddedConstants-filters-through-nonzero-b (result i32)- (i32.add- (i32.shl- (i32.const -536870912)- (i32.wrap_i64- (i64.const -1)- )- )- (i32.const -31744)- )- )- (func $return-proper-value-from-shift-left-by-zero (result i32)- (if (result i32)- (i32.add- (loop $label$0 (result i32)- (block $label$1- (br_if $label$1- (i32.load- (i32.const 0)- )- )- )- (i32.const -62)- )- (i32.const 40)- )- (i32.const 1)- (i32.const 0)- )- )- (func $de-morgan-2 (param $x i32) (param $y i32)- (drop- (i32.eqz- (i32.or- (local.get $x)- (local.get $y)- )- )- )- (drop- (i32.or- (i32.eqz- (local.get $x)- )- (i32.eqz- (local.get $y)- )- )- )- (drop- (i32.xor- (i32.eqz- (local.get $x)- )- (i32.eqz- (local.get $y)- )- )- )- (drop- (i32.and- (local.get $y)- (i32.eqz- (local.get $x)- )- )- )- (drop- (i32.and- (i32.eqz- (local.get $y)- )- (local.get $x)- )- )- (drop- (i32.and- (i32.eqz- (local.get $x)- )- (i32.wrap_i64- (i64.const 2)- )- )- )- (drop- (i32.and- (i32.eqz- (local.get $y)- )- (i32.wrap_i64- (i64.const 1)- )- )- )- )- (func $subzero1 (param $0 i32) (result i32)- (i32.sub- (i32.const 32)- (i32.clz- (local.get $0)- )- )- )- (func $subzero2 (param $0 i32) (result i32)- (i32.sub- (i32.const 32)- (i32.clz- (local.get $0)- )- )- )- (func $subzero3 (param $0 i32) (param $1 i32) (result i32)- (i32.sub- (local.get $1)- (i32.clz- (local.get $0)- )- )- )- (func $subzero4 (param $0 i32) (param $1 i32) (result i32)- (i32.sub- (local.get $0)- (i32.clz- (local.get $1)- )- )- )- (func $mul-32-power-2 (param $x i32) (result i32)- (drop- (call $mul-32-power-2- (i32.shl- (local.get $x)- (i32.const 2)- )- )- )- (drop- (call $mul-32-power-2- (i32.mul- (local.get $x)- (i32.const 5)- )- )- )- (drop- (call $mul-32-power-2- (local.get $x)- )- )- (drop- (call $mul-32-power-2- (i32.const 0)- )- )- (drop- (call $mul-32-power-2- (i32.mul- (call $mul-32-power-2- (i32.const 123)- )- (i32.const 0)- )- )- )- (drop- (call $mul-32-power-2- (i32.sub- (i32.const 0)- (local.get $x)- )- )- )- (drop- (call $mul-32-power-2- (i32.shl- (local.get $x)- (i32.const 31)- )- )- )- (unreachable)- )- (func $mul-64-power-2 (param $x i64) (result i64)- (drop- (call $mul-64-power-2- (i64.shl- (local.get $x)- (i64.const 2)- )- )- )- (drop- (call $mul-64-power-2- (i64.mul- (local.get $x)- (i64.const 5)- )- )- )- (drop- (call $mul-64-power-2- (local.get $x)- )- )- (drop- (call $mul-64-power-2- (i64.const 0)- )- )- (drop- (call $mul-64-power-2- (i64.mul- (call $mul-64-power-2- (i64.const 123)- )- (i64.const 0)- )- )- )- (drop- (call $mul-64-power-2- (i64.sub- (i64.const 0)- (local.get $x)- )- )- )- (drop- (call $mul-64-power-2- (i64.shl- (local.get $x)- (i64.const 63)- )- )- )- (unreachable)- )- (func $div-32-power-2 (param $x i32) (result i32)- (drop- (call $div-32-power-2- (i32.shr_u- (local.get $x)- (i32.const 2)- )- )- )- (drop- (call $div-32-power-2- (i32.div_u- (local.get $x)- (i32.const 5)- )- )- )- (drop- (call $div-32-power-2- (local.get $x)- )- )- (drop- (call $div-32-power-2- (i32.div_u- (local.get $x)- (i32.const 0)- )- )- )- (drop- (call $div-32-power-2- (i32.div_u- (call $div-32-power-2- (i32.const 123)- )- (i32.const 0)- )- )- )- (drop- (call $div-32-power-2- (i32.eq- (local.get $x)- (i32.const -1)- )- )- )- (drop- (call $div-32-power-2- (i32.shr_u- (local.get $x)- (i32.const 31)- )- )- )- (unreachable)- )- (func $urem-32-power-2 (param $x i32) (result i32)- (drop- (call $urem-32-power-2- (i32.and- (local.get $x)- (i32.const 3)- )- )- )- (drop- (call $urem-32-power-2- (i32.rem_u- (local.get $x)- (i32.const 5)- )- )- )- (drop- (call $urem-32-power-2- (i32.const 0)- )- )- (drop- (call $urem-32-power-2- (i32.rem_u- (local.get $x)- (i32.const 0)- )- )- )- (drop- (call $urem-32-power-2- (i32.rem_u- (local.get $x)- (i32.const -1)- )- )- )- (drop- (call $urem-32-power-2- (i32.and- (local.get $x)- (i32.const 2147483647)- )- )- )- (drop- (call $urem-32-power-2- (i32.const 0)- )- )- (unreachable)- )- (func $srem-by-const (param $x i32) (param $y i64)- (drop- (i32.const 0)- )- (drop- (i64.const 0)- )- (drop- (i32.rem_s- (local.get $x)- (i32.const -2147483648)- )- )- (drop- (i64.rem_s- (local.get $y)- (i64.const -9223372036854775808)- )- )- )- (func $srem-by-pot-eq-ne-zero (param $x i32) (param $y i64)- (drop- (i32.eqz- (i32.and- (local.get $x)- (i32.const 3)- )- )- )- (drop- (i64.eqz- (i64.and- (local.get $y)- (i64.const 3)- )- )- )- (drop- (i32.eqz- (i32.and- (local.get $x)- (i32.const 3)- )- )- )- (drop- (i64.eqz- (i64.and- (local.get $y)- (i64.const 3)- )- )- )- (drop- (i32.eqz- (i32.and- (local.get $x)- (i32.const 3)- )- )- )- (drop- (i64.eqz- (i64.and- (local.get $y)- (i64.const 1)- )- )- )- (drop- (i32.eqz- (i32.and- (local.get $x)- (i32.const 3)- )- )- )- (drop- (i64.eqz- (i64.and- (local.get $y)- (i64.const 3)- )- )- )- (drop- (i32.ne- (i32.and- (local.get $x)- (i32.const 1)- )- (i32.const 0)- )- )- (drop- (i32.wrap_i64- (i64.and- (local.get $y)- (i64.const 1)- )- )- )- (drop- (i32.eqz- (i32.const 0)- )- )- (drop- (i32.eqz- (i32.and- (local.get $x)- (i32.const 2147483647)- )- )- )- (drop- (i32.ne- (i32.and- (local.get $x)- (i32.const 2147483647)- )- (i32.const 0)- )- )- (drop- (i64.eqz- (i64.and- (local.get $y)- (i64.const 9223372036854775807)- )- )- )- (drop- (i64.ne- (i64.and- (local.get $y)- (i64.const 9223372036854775807)- )- (i64.const 0)- )- )- (drop- (i32.eqz- (i32.rem_s- (local.get $x)- (i32.const 3)- )- )- )- (drop- (i64.eqz- (i64.rem_s- (local.get $y)- (i64.const 3)- )- )- )- )- (func $orZero (param $0 i32) (result i32)- (local.get $0)- )- (func $andZero (param $0 i32) (result i32)- (drop- (i32.const 0)- )- (drop- (i32.and- (call $andZero- (i32.const 1234)- )- (i32.const 0)- )- )- (unreachable)- )- (func $abstract-additions (param $x32 i32) (param $x64 i64) (param $y32 f32) (param $y64 f64)- (drop- (local.get $x32)- )- (drop- (local.get $x32)- )- (drop- (local.get $x32)- )- (drop- (local.get $x32)- )- (drop- (local.get $x64)- )- (drop- (local.get $x64)- )- (drop- (local.get $x64)- )- (drop- (local.get $x64)- )- (drop- (i32.const 0)- )- (drop- (i64.const 0)- )- (drop- (f32.mul- (local.get $y32)- (f32.const 0)- )- )- (drop- (f64.mul- (local.get $y64)- (f64.const 0)- )- )- (drop- (local.get $x32)- )- (drop- (local.get $x64)- )- (drop- (f32.mul- (local.get $y32)- (f32.const 1)- )- )- (drop- (f64.mul- (local.get $y64)- (f64.const 1)- )- )- (drop- (i32.const 0)- )- (drop- (i64.const 0)- )- (drop- (i32.and- (unreachable)- (i32.const 0)- )- )- (drop- (i64.and- (unreachable)- (i64.const 0)- )- )- (drop- (local.get $x32)- )- (drop- (local.get $x32)- )- (drop- (local.get $x64)- )- (drop- (local.get $x64)- )- (drop- (f32.div- (local.get $y32)- (f32.const 1)- )- )- (drop- (f64.div- (local.get $y64)- (f64.const 1)- )- )- (drop- (f32.div- (local.get $y32)- (f32.const 1.2000000476837158)- )- )- (drop- (i32.sub- (i32.const 0)- (local.get $x32)- )- )- (drop- (i64.sub- (i64.const 0)- (local.get $x64)- )- )- (drop- (f32.mul- (local.get $y32)- (f32.const -1)- )- )- (drop- (f64.mul- (local.get $y64)- (f64.const -1)- )- )- (drop- (i32.eq- (local.get $x32)- (i32.const 10)- )- )- (drop- (i32.le_u- (i32.add- (local.get $x32)- (i32.const 10)- )- (i32.const 20)- )- )- (drop- (i32.eq- (local.get $x32)- (i32.const 30)- )- )- (drop- (i64.eq- (local.get $x64)- (i64.const 10)- )- )- (drop- (i32.eq- (local.get $x32)- (i32.const 10)- )- )- (drop- (i32.eq- (i32.add- (local.get $x32)- (i32.const 10)- )- (local.get $x32)- )- )- (drop- (i32.eq- (local.get $x32)- (i32.const 30)- )- )- (drop- (i32.eq- (i32.sub- (local.get $x32)- (i32.const 30)- )- (local.get $x32)- )- )- (drop- (i32.eq- (i32.sub- (local.get $x32)- (i32.const 30)- )- (local.get $x32)- )- )- (drop- (i32.eq- (i32.sub- (local.get $x32)- (i32.const 10)- )- (local.get $x32)- )- )- (drop- (i64.le_s- (i64.sub- (local.get $x64)- (i64.const 288230376151711744)- )- (i64.const 9223372036854775807)- )- )- )- (func $negatives-are-sometimes-better (param $x i32) (param $y i64) (param $z f32)- (drop- (i32.sub- (local.get $x)- (i32.const -64)- )- )- (drop- (i32.add- (local.get $x)- (i32.const -64)- )- )- (drop- (i32.sub- (local.get $x)- (i32.const -8192)- )- )- (drop- (i32.sub- (local.get $x)- (i32.const -1048576)- )- )- (drop- (i32.sub- (local.get $x)- (i32.const -134217728)- )- )- (drop- (i64.sub- (local.get $y)- (i64.const -64)- )- )- (drop- (i64.add- (local.get $y)- (i64.const -64)- )- )- (drop- (i64.sub- (local.get $y)- (i64.const -8192)- )- )- (drop- (i64.sub- (local.get $y)- (i64.const -1048576)- )- )- (drop- (i64.sub- (local.get $y)- (i64.const -134217728)- )- )- (drop- (i64.sub- (local.get $y)- (i64.const -17179869184)- )- )- (drop- (i64.sub- (local.get $y)- (i64.const -2199023255552)- )- )- (drop- (i64.sub- (local.get $y)- (i64.const -281474976710656)- )- )- (drop- (i64.sub- (local.get $y)- (i64.const -36028797018963968)- )- )- (drop- (i64.sub- (local.get $y)- (i64.const -4611686018427387904)- )- )- (drop- (f32.add- (local.get $z)- (f32.const 64)- )- )- )- (func $shift-a-zero (param $x i32) (param $y i64) (param $z f32)- (drop- (i32.const 0)- )- (drop- (i32.const 0)- )- (drop- (i32.const 0)- )- (drop- (i64.const 0)- )- (drop- (i32.shl- (i32.const 0)- (unreachable)- )- )- )- (func $identical-siblings (param $x i32) (param $y i64) (param $z f64) (param $xx i32)- (drop- (i32.const 0)- )- (drop- (i64.const 0)- )- (drop- (f64.sub- (local.get $z)- (local.get $z)- )- )- (drop- (i32.sub- (local.get $x)- (local.get $xx)- )- )- (drop- (i32.sub- (unreachable)- (unreachable)- )- )- (drop- (i32.add- (local.get $x)- (local.get $x)- )- )- (drop- (i32.const 0)- )- (drop- (i32.const 0)- )- (drop- (i32.const 0)- )- (drop- (i32.const 0)- )- (drop- (i32.const 0)- )- (drop- (i32.const 0)- )- (drop- (local.get $x)- )- (drop- (local.get $x)- )- (drop- (i32.const 1)- )- (drop- (i32.const 1)- )- (drop- (i32.const 1)- )- (drop- (i32.const 1)- )- (drop- (i32.const 1)- )- (drop- (i64.const 0)- )- (drop- (i32.const 0)- )- (drop- (i32.const 0)- )- (drop- (i32.const 0)- )- (drop- (i32.const 0)- )- (drop- (i32.const 0)- )- (drop- (local.get $y)- )- (drop- (local.get $y)- )- (drop- (i32.const 1)- )- (drop- (i32.const 1)- )- (drop- (i32.const 1)- )- (drop- (i32.const 1)- )- (drop- (i32.const 1)- )- )- (func $all_ones (param $x i32) (param $y i64)- (drop- (local.get $x)- )- (drop- (i32.const -1)- )- (drop- (i32.or- (local.tee $x- (i32.const 1337)- )- (i32.const -1)- )- )- (drop- (local.get $y)- )- (drop- (i64.const -1)- )- )- (func $xor (param $x i32) (param $y i64)- (drop- (local.get $x)- )- )- (func $select-on-const (param $x i32) (param $y i64)- (drop- (local.get $x)- )- (drop- (i32.const 3)- )- (drop- (local.tee $x- (i32.const 5)- )- )- (drop- (block (result i32)- (drop- (local.tee $x- (i32.const 6)- )- )- (i32.const 7)- )- )- (drop- (select- (i32.const 4)- (local.tee $x- (i32.const 5)- )- (i32.const 1)- )- )- (drop- (local.tee $x- (i32.const 6)- )- )- (drop- (i32.eqz- (i32.eqz- (local.get $x)- )- )- )- (drop- (i32.eqz- (local.get $x)- )- )- (drop- (i32.ge_s- (local.get $x)- (i32.const 0)- )- )- (drop- (i32.lt_s- (local.get $x)- (i32.const 0)- )- )- (drop- (i32.lt_s- (local.get $x)- (i32.const 0)- )- )- (drop- (i32.gt_s- (local.get $x)- (i32.const 0)- )- )- (drop- (i32.le_s- (local.get $x)- (i32.const 0)- )- )- (drop- (i32.ge_s- (local.get $x)- (i32.const 0)- )- )- (drop- (i64.extend_i32_u- (i32.eqz- (i32.eqz- (local.get $x)- )- )- )- )- (drop- (i64.extend_i32_u- (i32.eqz- (local.get $x)- )- )- )- (drop- (i64.extend_i32_u- (i64.eqz- (local.get $y)- )- )- )- (drop- (i64.extend_i32_u- (i32.eqz- (i64.eqz- (local.get $y)- )- )- )- )- (drop- (i64.extend_i32_u- (i64.ge_s- (local.get $y)- (i64.const 0)- )- )- )- (drop- (i64.extend_i32_u- (i64.lt_s- (local.get $y)- (i64.const 0)- )- )- )- (drop- (i64.extend_i32_u- (i64.lt_s- (local.get $y)- (i64.const 0)- )- )- )- (drop- (i64.extend_i32_u- (i64.ge_s- (local.get $y)- (i64.const 0)- )- )- )- (drop- (select- (i32.const 0)- (local.get $x)- (i32.const 0)- )- )- (drop- (select- (i32.const 2)- (local.get $x)- (i32.const 2)- )- )- (drop- (select- (local.get $x)- (i32.const 2)- (local.get $x)- )- )- (drop- (select- (local.get $y)- (i64.const 0)- (i64.eqz- (i64.const 0)- )- )- )- (drop- (select- (local.get $y)- (i64.const 2)- (i64.eqz- (i64.const 2)- )- )- )- )- (func $optimize-boolean (param $x i32) (param $y i64)- (drop- (select- (i32.const 1)- (i32.const 2)- (local.get $x)- )- )- (drop- (i32.and- (local.get $x)- (i32.const 1)- )- )- (drop- (i32.eqz- (i32.and- (local.get $x)- (i32.const 1)- )- )- )- (drop- (i32.wrap_i64- (i64.shr_u- (local.get $y)- (i64.const 63)- )- )- )- (drop- (i32.eqz- (i32.shr_u- (local.get $x)- (i32.const 31)- )- )- )- (drop- (i64.eqz- (i64.shr_u- (local.get $y)- (i64.const 63)- )- )- )- (drop- (i64.eqz- (i64.shr_u- (local.get $y)- (i64.const 63)- )- )- )- (drop- (i64.eqz- (local.get $y)- )- )- (drop- (i32.eqz- (i32.wrap_i64- (local.get $y)- )- )- )- (drop- (i32.wrap_i64- (i64.and- (local.get $y)- (i64.const 1)- )- )- )- (drop- (i64.eqz- (i64.and- (local.get $y)- (i64.const 1)- )- )- )- (drop- (i32.and- (local.get $x)- (i32.const 1)- )- )- (drop- (i32.const 1)- )- (drop- (i64.and- (local.get $y)- (i64.const 1)- )- )- (drop- (i64.const 1)- )- )- (func $optimize-bitwise-oprations (param $x i32) (param $y i32) (param $z i64) (param $w i64)- (drop- (i32.rotl- (i32.const -2)- (local.get $x)- )- )- (drop- (i64.rotl- (i64.const -2)- (local.get $z)- )- )- )- (func $getFallthrough- (local $x0 i32)- (local $x1 i32)- (local $x2 i32)- (local $x3 i32)- (local $x4 i32)- (local $x5 i32)- (local $x6 i32)- (local $x7 i32)- (local.set $x0- (i32.const 1)- )- (drop- (local.get $x0)- )- (local.set $x1- (local.tee $x2- (i32.const 1)- )- )- (drop- (local.get $x1)- )- (local.set $x3- (loop $loop-in (result i32)- (i32.const 1)- )- )- (drop- (local.get $x3)- )- (local.set $x4- (if (result i32)- (i32.const 1)- (i32.const 2)- (i32.const 3)- )- )- (drop- (i32.and- (local.get $x4)- (i32.const 7)- )- )- (local.set $x5- (if (result i32)- (i32.const 1)- (unreachable)- (i32.const 3)- )- )- (drop- (local.get $x5)- )- (local.set $x6- (if (result i32)- (i32.const 1)- (i32.const 3)- (unreachable)- )- )- (drop- (local.get $x6)- )- (drop- (block $out (result i32)- (local.set $x7- (br_if $out- (i32.const 1)- (i32.const 1)- )- )- (drop- (local.get $x7)- )- (unreachable)- )- )- )- (func $tee-with-unreachable-value (result f64)- (local $var$0 i32)- (block $label$1 (result f64)- (local.tee $var$0- (br_if $label$1- (f64.const 1)- (unreachable)- )- )- )- )- (func $add-sub-zero-reorder-1 (param $temp i32) (result i32)- (i32.add- (i32.add- (i32.sub- (i32.const 0)- (local.get $temp)- )- (local.tee $temp- (i32.const 1)- )- )- (i32.const 2)- )- )- (func $add-sub-zero-reorder-2 (param $temp i32) (result i32)- (i32.add- (i32.sub- (local.tee $temp- (i32.const 1)- )- (local.get $temp)- )- (i32.const 2)- )- )- (func $const-float-zero (param $fx f32) (param $fy f64)- (drop- (f32.sub- (local.get $fx)- (f32.const 0)- )- )- (drop- (f64.sub- (local.get $fy)- (f64.const 0)- )- )- (drop- (f32.add- (local.get $fx)- (f32.const -0)- )- )- (drop- (f64.add- (local.get $fy)- (f64.const -0)- )- )- (drop- (f32.add- (local.get $fx)- (f32.const 0)- )- )- (drop- (f64.add- (local.get $fy)- (f64.const 0)- )- )- (drop- (f32.sub- (f32.const 0)- (local.get $fx)- )- )- (drop- (f64.sub- (f64.const 0)- (local.get $fy)- )- )- (drop- (f32.add- (local.get $fx)- (f32.const 0)- )- )- (drop- (f64.add- (local.get $fy)- (f64.const 0)- )- )- (drop- (f32.sub- (f32.const -nan:0x34546d)- (f32.const 0)- )- )- )- (func $rhs-is-neg-one (param $x i32) (param $y i64) (param $fx f32) (param $fy f64)- (drop- (i32.sub- (local.get $x)- (i32.const -1)- )- )- (drop- (i64.sub- (local.get $y)- (i64.const -1)- )- )- (drop- (i32.const 0)- )- (drop- (i32.const 0)- )- (drop- (i32.gt_s- (local.get $x)- (i32.const -1)- )- )- (drop- (i64.gt_s- (local.get $y)- (i64.const -1)- )- )- (drop- (i64.extend_i32_s- (i32.const 0)- )- )- (drop- (i32.const 1)- )- (drop- (i32.const 1)- )- (drop- (i32.le_s- (local.get $x)- (i32.const -1)- )- )- (drop- (i64.le_s- (local.get $y)- (i64.const -1)- )- )- (drop- (i32.sub- (i32.const 0)- (local.get $x)- )- )- (drop- (i64.sub- (i64.const 0)- (local.get $y)- )- )- (drop- (f32.mul- (local.get $fx)- (f32.const -1)- )- )- (drop- (f64.mul- (local.get $fy)- (f64.const -1)- )- )- (drop- (i32.eq- (local.get $x)- (i32.const -1)- )- )- (drop- (i64.extend_i32_u- (i64.eq- (local.get $y)- (i64.const -1)- )- )- )- )- (func $rhs-is-neg-const (param $x i32) (param $y i64)- (drop- (i32.ge_u- (local.get $x)- (i32.const -2)- )- )- (drop- (i32.eq- (local.get $x)- (i32.const -1)- )- )- (drop- (i32.ge_u- (local.get $x)- (i32.const -2147483647)- )- )- (drop- (i32.shr_u- (local.get $x)- (i32.const 31)- )- )- (drop- (i64.extend_i32_u- (i64.eq- (local.get $y)- (i64.const -1)- )- )- )- (drop- (i64.shr_u- (local.get $y)- (i64.const 63)- )- )- )- (func $pre-combine-or (param $x i32) (param $y i32)- (drop- (i32.ge_s- (local.get $x)- (local.get $y)- )- )- (drop- (i32.ge_s- (local.get $x)- (local.get $y)- )- )- (drop- (i32.or- (i32.eq- (local.get $x)- (i32.const 1)- )- (i32.gt_s- (local.get $x)- (local.get $y)- )- )- )- (drop- (i32.or- (i32.eq- (local.get $x)- (local.get $y)- )- (i32.gt_s- (local.get $x)- (i32.const 1)- )- )- )- (drop- (i32.or- (i32.gt_s- (call $ne0)- (local.get $y)- )- (i32.eq- (call $ne0)- (local.get $y)- )- )- )- (drop- (i32.or- (i32.gt_s- (local.get $y)- (call $ne0)- )- (i32.eq- (call $ne0)- (local.get $y)- )- )- )- )- (func $combine-or (param $x i32) (param $y i32)- (drop- (i32.ge_s- (local.get $x)- (local.get $y)- )- )- )- (func $select-into-arms (param $x i32) (param $y i32)- (if- (select- (local.get $x)- (local.get $y)- (local.get $y)- )- (unreachable)- )- )- (func $if-arms-subtype-fold (result anyref)- (ref.null extern)- )- (func $if-arms-subtype-nofold (result anyref)- (if (result anyref)- (i32.const 0)- (ref.null extern)- (ref.null func)- )- )- (func $optimize-boolean-context (param $x i32) (param $y i32)- (if- (local.get $x)- (unreachable)- )- (drop- (select- (local.get $x)- (local.get $y)- (local.get $x)- )- )- )- (func $unsigned-context (param $x i32) (param $y i64)- (drop- (i32.div_u- (i32.and- (local.get $x)- (i32.const 2147483647)- )- (i32.const 3)- )- )- (drop- (i32.div_s- (i32.and- (local.get $x)- (i32.const 2147483647)- )- (i32.const -3)- )- )- (drop- (i32.div_s- (i32.and- (local.get $x)- (i32.const 2147483647)- )- (i32.const -2147483648)- )- )- (drop- (i64.shr_u- (i64.and- (local.get $y)- (i64.const 9223372036854775807)- )- (i64.const 1)- )- )- (drop- (i64.div_s- (i64.and- (local.get $y)- (i64.const 9223372036854775807)- )- (i64.const -1)- )- )- (drop- (i32.rem_u- (i32.and- (local.get $x)- (i32.const 2147483647)- )- (i32.const 3)- )- )- (drop- (i32.shr_u- (i32.and- (local.get $x)- (i32.const 2147483647)- )- (i32.const 7)- )- )- (drop- (i32.ge_u- (i32.and- (local.get $x)- (i32.const 2147483647)- )- (i32.const 7)- )- )- (drop- (i32.ge_s- (i32.and- (local.get $x)- (i32.const 2147483647)- )- (i32.const -7)- )- )- )- (func $duplicate-elimination (param $x i32) (param $y i32) (param $z i32) (param $w f64)- (drop- (f64.abs- (local.get $w)- )- )- (drop- (f64.ceil- (local.get $w)- )- )- (drop- (f64.floor- (local.get $w)- )- )- (drop- (f64.trunc- (local.get $w)- )- )- (drop- (f64.nearest- (local.get $w)- )- )- (drop- (f64.nearest- (f64.trunc- (local.get $w)- )- )- )- (drop- (f64.trunc- (f64.nearest- (local.get $w)- )- )- )- (drop- (local.get $w)- )- (drop- (f64.neg- (local.get $w)- )- )- (drop- (local.get $w)- )- (drop- (i32.eqz- (i32.eqz- (local.get $x)- )- )- )- (drop- (i32.eqz- (local.get $x)- )- )- (drop- (i64.eqz- (i64.const 1)- )- )- (drop- (i32.ne- (local.get $x)- (i32.const 2)- )- )- (drop- (i32.extend8_s- (local.get $x)- )- )- (drop- (i32.extend16_s- (local.get $x)- )- )- (drop- (i32.and- (local.get $x)- (i32.const 1)- )- )- (drop- (i32.rem_s- (local.get $x)- (local.get $y)- )- )- (drop- (i32.rem_u- (local.get $x)- (local.get $y)- )- )- (drop- (local.get $y)- )- (drop- (local.get $y)- )- (drop- (i32.sub- (local.get $y)- (i32.sub- (local.get $x)- (local.get $y)- )- )- )- (drop- (local.get $y)- )- (drop- (local.get $y)- )- (drop- (local.get $y)- )- (drop- (local.get $y)- )- (drop- (local.get $x)- )- (drop- (i32.and- (local.get $x)- (local.get $y)- )- )- (drop- (i32.and- (local.get $x)- (local.get $y)- )- )- (drop- (i32.and- (local.get $x)- (local.get $y)- )- )- (drop- (i32.and- (local.get $x)- (local.get $y)- )- )- (drop- (i32.or- (local.get $x)- (local.get $y)- )- )- (drop- (i32.or- (local.get $x)- (local.get $y)- )- )- (drop- (i32.or- (local.get $x)- (local.get $y)- )- )- (drop- (i32.or- (local.get $x)- (local.get $y)- )- )- (drop- (i32.or- (local.get $z)- (i32.or- (local.get $x)- (local.get $y)- )- )- )- (drop- (i32.or- (local.get $y)- (i32.or- (local.get $x)- (local.get $z)- )- )- )- (drop- (i32.or- (call $ne0)- (local.get $x)- )- )- (drop- (i32.or- (i32.or- (call $ne0)- (local.get $x)- )- (call $ne0)- )- )- (drop- (i32.or- (call $ne0)- (local.get $x)- )- )- (drop- (i32.or- (call $ne0)- (i32.or- (call $ne0)- (local.get $x)- )- )- )- (drop- (i32.rem_s- (i32.rem_s- (local.get $y)- (local.get $x)- )- (local.get $y)- )- )- (drop- (i32.rem_u- (local.get $y)- (i32.rem_u- (local.get $x)- (local.get $y)- )- )- )- (drop- (i32.or- (local.get $x)- (i32.or- (local.tee $x- (i32.const 1)- )- (local.get $x)- )- )- )- (drop- (i32.or- (i32.or- (local.get $x)- (local.tee $x- (i32.const 1)- )- )- (local.get $x)- )- )- (drop- (i32.xor- (local.get $x)- (i32.xor- (local.tee $x- (i32.const 1)- )- (local.get $x)- )- )- )- (drop- (i32.xor- (i32.xor- (local.get $x)- (local.tee $x- (i32.const 1)- )- )- (local.get $x)- )- )- )- (func $optimize-shifts (param $x i32) (param $y i32) (param $z i64) (param $w i64)- (drop- (local.get $x)- )- (drop- (local.get $x)- )- (drop- (local.get $x)- )- (drop- (local.get $x)- )- (drop- (local.get $x)- )- (drop- (local.get $z)- )- (drop- (local.get $z)- )- (drop- (local.get $z)- )- (drop- (local.get $z)- )- (drop- (local.get $z)- )- (drop- (i32.shl- (local.get $x)- (local.get $y)- )- )- (drop- (i32.shl- (local.get $x)- (local.get $y)- )- )- (drop- (i32.shr_s- (local.get $x)- (local.get $y)- )- )- (drop- (i32.shr_u- (local.get $x)- (local.get $y)- )- )- (drop- (i64.shl- (local.get $z)- (local.get $w)- )- )- (drop- (i64.shl- (local.get $z)- (local.get $w)- )- )- (drop- (i64.shr_s- (local.get $z)- (local.get $w)- )- )- (drop- (i64.shr_u- (local.get $z)- (local.get $w)- )- )- (drop- (i32.shl- (local.get $x)- (i32.and- (local.get $y)- (i32.const 32)- )- )- )- (drop- (i64.shr_u- (local.get $z)- (i64.and- (local.get $w)- (i64.const 31)- )- )- )- )- (func $optimize-bulk-memory-copy (param $dst i32) (param $src i32) (param $sz i32)- (memory.copy- (local.get $dst)- (local.get $dst)- (local.get $sz)- )- (memory.copy- (local.get $dst)- (local.get $src)- (i32.const 0)- )- (i32.store8- (local.get $dst)- (i32.load8_u- (local.get $src)- )- )- (i32.store16 align=1- (local.get $dst)- (i32.load16_u align=1- (local.get $src)- )- )- (memory.copy- (local.get $dst)- (local.get $src)- (i32.const 3)- )- (i32.store align=1- (local.get $dst)- (i32.load align=1- (local.get $src)- )- )- (memory.copy- (local.get $dst)- (local.get $src)- (i32.const 5)- )- (memory.copy- (local.get $dst)- (local.get $src)- (i32.const 6)- )- (memory.copy- (local.get $dst)- (local.get $src)- (i32.const 7)- )- (i64.store align=1- (local.get $dst)- (i64.load align=1- (local.get $src)- )- )- (v128.store align=1- (local.get $dst)- (v128.load align=1- (local.get $src)- )- )- (memory.copy- (local.get $dst)- (local.get $src)- (local.get $sz)- )- (memory.copy- (i32.const 0)- (i32.const 0)- (i32.load- (i32.const 3)- )- )- )-)-(module- (type $none_=>_none (func))- (import "env" "memory" (memory $0 (shared 256 256)))- (func $x- (drop- (i32.shr_s- (i32.shl- (i32.atomic.load8_u- (i32.const 100)- )- (i32.const 24)- )- (i32.const 24)- )- )+ (type $none_=>_i32 (func (result i32)))+ (type $i32_=>_i32 (func (param i32) (result i32)))+ (type $i32_i64_=>_none (func (param i32 i64)))+ (type $none_=>_none (func))+ (type $i32_i32_=>_i32 (func (param i32 i32) (result i32)))+ (type $i32_=>_none (func (param i32)))+ (type $i32_i32_i64_i64_=>_none (func (param i32 i32 i64 i64)))+ (type $i32_i64_f32_f64_=>_none (func (param i32 i64 f32 f64)))+ (type $none_=>_i64 (func (result i64)))+ (type $i64_=>_i64 (func (param i64) (result i64)))+ (type $i32_i64_f32_=>_none (func (param i32 i64 f32)))+ (type $f32_=>_none (func (param f32)))+ (type $f64_=>_none (func (param f64)))+ (type $i32_i32_i32_f64_=>_none (func (param i32 i32 i32 f64)))+ (type $i32_i32_f64_f64_=>_none (func (param i32 i32 f64 f64)))+ (type $i32_i64_f64_i32_=>_none (func (param i32 i64 f64 i32)))+ (type $f32_f64_=>_none (func (param f32 f64)))+ (type $f64_f32_=>_none (func (param f64 f32)))+ (type $f64_f64_f32_f32_=>_none (func (param f64 f64 f32 f32)))+ (type $none_=>_f64 (func (result f64)))+ (memory $0 0)+ (export "load-off-2" (func $load-off-2))+ (func $f (param $i1 i32) (param $i2 i64)+ (drop+ (i32.and+ (local.get $i1)+ (i32.const 1)+ )+ )+ (drop+ (i32.or+ (local.get $i1)+ (i32.const 3)+ )+ )+ (drop+ (i32.xor+ (local.get $i1)+ (i32.const 5)+ )+ )+ (drop+ (i32.mul+ (local.get $i1)+ (i32.const -10)+ )+ )+ (drop+ (i32.mul+ (local.get $i1)+ (i32.const -133169153)+ )+ )+ (if+ (i32.eqz+ (local.get $i1)+ )+ (drop+ (i32.const 10)+ )+ )+ (if+ (local.get $i1)+ (drop+ (i32.const 12)+ )+ (drop+ (i32.const 11)+ )+ )+ (if+ (i64.eqz+ (local.get $i2)+ )+ (drop+ (i32.const 11)+ )+ (drop+ (i32.const 12)+ )+ )+ (drop+ (i32.le_u+ (i32.const 1)+ (i32.const 2)+ )+ )+ (drop+ (i32.lt_u+ (i32.const 1)+ (i32.const 2)+ )+ )+ (drop+ (i32.ge_u+ (i32.const 1)+ (i32.const 2)+ )+ )+ (drop+ (i32.gt_u+ (i32.const 1)+ (i32.const 2)+ )+ )+ (drop+ (i32.le_u+ (i32.const 1)+ (i32.const 2)+ )+ )+ (drop+ (i32.lt_u+ (i32.const 1)+ (i32.const 2)+ )+ )+ (drop+ (i32.ge_u+ (i32.const 1)+ (i32.const 2)+ )+ )+ (drop+ (i32.gt_u+ (i32.const 1)+ (i32.const 2)+ )+ )+ (drop+ (i32.eqz+ (f32.gt+ (f32.const 1)+ (f32.const 2)+ )+ )+ )+ (drop+ (i32.eqz+ (f32.ge+ (f32.const 1)+ (f32.const 2)+ )+ )+ )+ (drop+ (i32.eqz+ (f32.lt+ (f32.const 1)+ (f32.const 2)+ )+ )+ )+ (drop+ (i32.eqz+ (f32.le+ (f32.const 1)+ (f32.const 2)+ )+ )+ )+ (drop+ (i32.eqz+ (f64.gt+ (f64.const 1)+ (f64.const 2)+ )+ )+ )+ (drop+ (i32.eqz+ (f64.ge+ (f64.const 1)+ (f64.const 2)+ )+ )+ )+ (drop+ (i32.eqz+ (f64.lt+ (f64.const 1)+ (f64.const 2)+ )+ )+ )+ (drop+ (i32.eqz+ (f64.le+ (f64.const 1)+ (f64.const 2)+ )+ )+ )+ (drop+ (f32.ne+ (f32.const 1)+ (f32.const 2)+ )+ )+ (drop+ (f32.eq+ (f32.const 1)+ (f32.const 2)+ )+ )+ (drop+ (f64.ne+ (f64.const 1)+ (f64.const 2)+ )+ )+ (drop+ (f64.eq+ (f64.const 1)+ (f64.const 2)+ )+ )+ (drop+ (i32.eqz+ (i32.const 100)+ )+ )+ (drop+ (i32.eq+ (i32.const 0)+ (i32.const 100)+ )+ )+ (drop+ (i32.eqz+ (i32.const 0)+ )+ )+ (drop+ (i64.eqz+ (i64.const 100)+ )+ )+ (drop+ (i64.eq+ (i64.const 0)+ (i64.const 100)+ )+ )+ (drop+ (i64.eqz+ (i64.const 0)+ )+ )+ (if+ (i32.const 123)+ (nop)+ )+ (drop+ (select+ (i32.const 102)+ (i32.const 101)+ (local.get $i1)+ )+ )+ (drop+ (select+ (local.tee $i1+ (i32.const 103)+ )+ (local.tee $i1+ (i32.const 104)+ )+ (i32.eqz+ (local.get $i1)+ )+ )+ )+ (drop+ (i32.const 0)+ )+ )+ (func $load-store+ (drop+ (i32.load8_u+ (i32.const 0)+ )+ )+ (drop+ (i32.load8_u+ (i32.const 1)+ )+ )+ (drop+ (i32.and+ (i32.load8_s+ (i32.const 2)+ )+ (i32.const 254)+ )+ )+ (drop+ (i32.and+ (i32.load8_u+ (i32.const 3)+ )+ (i32.const 1)+ )+ )+ (drop+ (i32.load16_u+ (i32.const 4)+ )+ )+ (drop+ (i32.load16_u+ (i32.const 5)+ )+ )+ (drop+ (i32.and+ (i32.load16_s+ (i32.const 6)+ )+ (i32.const 65534)+ )+ )+ (drop+ (i32.and+ (i32.load16_u+ (i32.const 7)+ )+ (i32.const 1)+ )+ )+ (i32.store8+ (i32.const 8)+ (i32.const -1)+ )+ (i32.store8+ (i32.const 9)+ (i32.and+ (i32.const -2)+ (i32.const 254)+ )+ )+ (i32.store16+ (i32.const 10)+ (i32.const -3)+ )+ (i32.store16+ (i32.const 11)+ (i32.and+ (i32.const -4)+ (i32.const 65534)+ )+ )+ (i64.store8+ (i32.const 11)+ (i64.const 1)+ )+ (i64.store16+ (i32.const 11)+ (i64.const 2)+ )+ (i64.store32+ (i32.const 11)+ (i64.const 3)+ )+ (i32.store8+ (i32.const 7)+ (i32.const 255)+ )+ (i32.store8+ (i32.const 8)+ (i32.const 255)+ )+ (i32.store8+ (i32.const 9)+ (i32.const 0)+ )+ (i32.store16+ (i32.const 10)+ (i32.const 65535)+ )+ (i32.store16+ (i32.const 11)+ (i32.const 0)+ )+ (i32.store16+ (i32.const 13)+ (i32.const 65535)+ )+ (i32.store+ (i32.const 14)+ (i32.const 65536)+ )+ (i64.store8+ (i32.const 8)+ (i64.const 255)+ )+ (i64.store8+ (i32.const 9)+ (i64.const 0)+ )+ (i64.store16+ (i32.const 10)+ (i64.const 65535)+ )+ (i64.store16+ (i32.const 11)+ (i64.const 0)+ )+ (i64.store32+ (i32.const 12)+ (i64.const 4294967295)+ )+ (i64.store32+ (i32.const 13)+ (i64.const 0)+ )+ (i64.store+ (i32.const 14)+ (i64.const 4294967296)+ )+ )+ (func $and-neg1+ (drop+ (i32.const 100)+ )+ (drop+ (i32.and+ (i32.const 100)+ (i32.const 1)+ )+ )+ )+ (func $and-pos1+ (drop+ (i32.eqz+ (i32.const 1000)+ )+ )+ (drop+ (i32.eqz+ (i32.const 1000)+ )+ )+ (drop+ (i32.and+ (i32.const 100)+ (i32.const 1)+ )+ )+ (drop+ (i32.lt_u+ (i32.const 2000)+ (i32.const 3000)+ )+ )+ )+ (func $canonicalize (param $x i32) (param $y i32) (param $fx f64) (param $fy f64)+ (drop+ (i32.and+ (unreachable)+ (i32.const 1)+ )+ )+ (drop+ (i32.and+ (i32.const 1)+ (unreachable)+ )+ )+ (drop+ (i32.div_s+ (unreachable)+ (i32.const 1)+ )+ )+ (drop+ (i32.div_s+ (i32.const 1)+ (unreachable)+ )+ )+ (drop+ (i32.and+ (i32.const 1)+ (i32.const 2)+ )+ )+ (drop+ (i32.and+ (local.get $x)+ (i32.const 3)+ )+ )+ (drop+ (i32.and+ (local.get $x)+ (i32.const 4)+ )+ )+ (drop+ (i32.and+ (local.get $x)+ (local.get $y)+ )+ )+ (drop+ (i32.and+ (local.get $x)+ (local.get $y)+ )+ )+ (drop+ (i32.and+ (local.tee $x+ (i32.const -4)+ )+ (local.get $y)+ )+ )+ (drop+ (i32.and+ (block $block (result i32)+ (i32.const -5)+ )+ (local.get $x)+ )+ )+ (drop+ (i32.and+ (block $block3 (result i32)+ (i32.const -6)+ )+ (local.get $x)+ )+ )+ (drop+ (i32.and+ (block $block4 (result i32)+ (i32.const 5)+ )+ (loop $loop-in (result i32)+ (i32.const 6)+ )+ )+ )+ (drop+ (i32.and+ (block $block6 (result i32)+ (i32.const 8)+ )+ (loop $loop-in5 (result i32)+ (i32.const 7)+ )+ )+ )+ (drop+ (i32.and+ (block $block8 (result i32)+ (i32.const 10)+ )+ (loop $loop-in7 (result i32)+ (call $and-pos1)+ (i32.const 9)+ )+ )+ )+ (drop+ (i32.and+ (block $block10 (result i32)+ (call $and-pos1)+ (i32.const 12)+ )+ (loop $loop-in9 (result i32)+ (i32.const 11)+ )+ )+ )+ (drop+ (i32.and+ (loop $loop-in11 (result i32)+ (call $and-pos1)+ (i32.const 13)+ )+ (block $block12 (result i32)+ (call $and-pos1)+ (i32.const 14)+ )+ )+ )+ (drop+ (i32.and+ (block $block13 (result i32)+ (call $and-pos1)+ (i32.const 14)+ )+ (loop $loop-in14 (result i32)+ (call $and-pos1)+ (i32.const 13)+ )+ )+ )+ (drop+ (i32.and+ (block $block15 (result i32)+ (i32.const 15)+ )+ (local.get $x)+ )+ )+ (drop+ (i32.and+ (block $block16 (result i32)+ (i32.const 15)+ )+ (local.get $x)+ )+ )+ (drop+ (i32.and+ (i32.gt_u+ (i32.const 16)+ (i32.const 17)+ )+ (i32.gt_u+ (i32.const 18)+ (i32.const 19)+ )+ )+ )+ (drop+ (i32.and+ (i32.gt_u+ (i32.const 20)+ (i32.const 21)+ )+ (i32.gt_u+ (i32.const 22)+ (i32.const 23)+ )+ )+ )+ (drop+ (i32.lt_s+ (local.get $x)+ (i32.const 1)+ )+ )+ (drop+ (i32.const 0)+ )+ (drop+ (i32.ne+ (local.get $x)+ (i32.const -1)+ )+ )+ (drop+ (f64.ne+ (local.get $fx)+ (f64.const -1)+ )+ )+ (drop+ (f64.gt+ (local.get $fx)+ (f64.const -2)+ )+ )+ (drop+ (f64.le+ (local.get $fx)+ (f64.const inf)+ )+ )+ (drop+ (f64.ge+ (local.get $fx)+ (f64.const nan:0x8000000000000)+ )+ )+ (drop+ (f64.ge+ (f64.const 1)+ (f64.const 2)+ )+ )+ (drop+ (i32.add+ (i32.ctz+ (local.get $x)+ )+ (i32.ctz+ (local.get $y)+ )+ )+ )+ (drop+ (i32.add+ (i32.ctz+ (local.get $y)+ )+ (i32.ctz+ (local.get $x)+ )+ )+ )+ (drop+ (i32.add+ (i32.ctz+ (local.get $x)+ )+ (i32.eqz+ (local.get $y)+ )+ )+ )+ (drop+ (i32.add+ (i32.ctz+ (local.get $y)+ )+ (i32.eqz+ (local.get $x)+ )+ )+ )+ )+ (func $ne0 (result i32)+ (if+ (call $ne0)+ (nop)+ )+ (if+ (call $ne0)+ (nop)+ )+ (if+ (i32.or+ (call $ne0)+ (call $ne0)+ )+ (nop)+ )+ (if+ (i32.and+ (i32.ne+ (call $ne0)+ (i32.const 0)+ )+ (i32.ne+ (call $ne0)+ (i32.const 0)+ )+ )+ (nop)+ )+ (i32.const 1)+ )+ (func $recurse-bool+ (if+ (if (result i32)+ (i32.const 1)+ (call $ne0)+ (call $ne1)+ )+ (nop)+ )+ (if+ (block $block (result i32)+ (nop)+ (call $ne0)+ )+ (nop)+ )+ )+ (func $ne1 (result i32)+ (unreachable)+ )+ (func $load-off-2 (param $0 i32) (result i32)+ (i32.store+ (i32.const 6)+ (local.get $0)+ )+ (i32.store+ (i32.const 6)+ (local.get $0)+ )+ (i32.store offset=2+ (i32.add+ (local.get $0)+ (i32.const 5)+ )+ (local.get $0)+ )+ (i32.store offset=2+ (i32.add+ (local.get $0)+ (i32.const 7)+ )+ (local.get $0)+ )+ (i32.store offset=2+ (i32.sub+ (local.get $0)+ (i32.const 11)+ )+ (local.get $0)+ )+ (i32.store offset=2+ (i32.sub+ (local.get $0)+ (i32.const 13)+ )+ (local.get $0)+ )+ (i32.store+ (i32.const 4)+ (local.get $0)+ )+ (i32.store offset=2+ (i32.const -2)+ (local.get $0)+ )+ (i32.store+ (i32.const 25)+ (local.get $0)+ )+ (i32.store offset=2+ (i32.const -25)+ (local.get $0)+ )+ (drop+ (i32.load+ (i32.const 8)+ )+ )+ (drop+ (i32.load+ (i32.const 8)+ )+ )+ (drop+ (i32.load offset=2+ (i32.add+ (local.get $0)+ (i32.const 6)+ )+ )+ )+ (drop+ (i32.load+ (i32.const 10)+ )+ )+ (i32.load offset=2+ (i32.add+ (local.get $0)+ (i32.const 10)+ )+ )+ )+ (func $sign-ext (param $0 i32) (param $1 i32)+ (drop+ (i32.eqz+ (i32.and+ (local.get $0)+ (i32.const 255)+ )+ )+ )+ (drop+ (i32.eqz+ (i32.and+ (local.get $0)+ (i32.const 65535)+ )+ )+ )+ (drop+ (i32.eqz+ (i32.and+ (local.get $0)+ (i32.const 134217727)+ )+ )+ )+ (drop+ (i32.eq+ (i32.and+ (local.get $0)+ (i32.const 255)+ )+ (i32.const 100)+ )+ )+ (drop+ (block (result i32)+ (drop+ (local.get $0)+ )+ (i32.const 0)+ )+ )+ (drop+ (block (result i32)+ (drop+ (local.get $0)+ )+ (i32.const 0)+ )+ )+ (drop+ (i32.eq+ (i32.and+ (local.get $0)+ (i32.const 255)+ )+ (i32.and+ (local.get $1)+ (i32.const 255)+ )+ )+ )+ (drop+ (i32.eq+ (i32.and+ (local.get $0)+ (i32.const 65535)+ )+ (i32.and+ (local.get $1)+ (i32.const 65535)+ )+ )+ )+ (drop+ (i32.eqz+ (i32.shr_s+ (i32.shl+ (local.get $0)+ (i32.const 24)+ )+ (i32.const 23)+ )+ )+ )+ (drop+ (i32.eqz+ (i32.shr_u+ (i32.shl+ (local.get $0)+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ )+ (drop+ (i32.lt_s+ (i32.shr_s+ (i32.shl+ (local.get $0)+ (i32.const 24)+ )+ (i32.const 24)+ )+ (i32.const 0)+ )+ )+ (drop+ (if (result i32)+ (i32.shr_s+ (i32.shl+ (unreachable)+ (i32.const 16)+ )+ (i32.const 16)+ )+ (i32.const 111)+ (i32.const 222)+ )+ )+ )+ (func $sign-ext-input (param $0 i32) (param $1 i32)+ (drop+ (i32.const 100)+ )+ (drop+ (i32.const 127)+ )+ (drop+ (i32.shr_s+ (i32.shl+ (i32.const 128)+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (local.get $0)+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (unreachable)+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.shr_u+ (i32.const 1)+ (i32.const 1)+ )+ )+ (drop+ (i32.and+ (i32.const 127)+ (i32.const 128)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (i32.and+ (i32.const 128)+ (i32.const 129)+ )+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.xor+ (i32.const 127)+ (i32.const 126)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (i32.xor+ (i32.const 127)+ (i32.const 128)+ )+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.or+ (i32.const 127)+ (i32.const 126)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (i32.or+ (i32.const 127)+ (i32.const 128)+ )+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (i32.const 32)+ (i32.const 26)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.shl+ (i32.const 32)+ (i32.const 1)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (i32.const 32)+ (i32.const 27)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (i32.shr_u+ (i32.const 256)+ (i32.const 1)+ )+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.shr_u+ (i32.const 256)+ (i32.const 2)+ )+ )+ (drop+ (i32.shr_u+ (i32.const 128)+ (i32.const 3)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (i32.shr_u+ (i32.const 256)+ (i32.const 1)+ )+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.shr_u+ (i32.const 256)+ (i32.const 2)+ )+ )+ (drop+ (i32.shr_u+ (i32.const 128)+ (i32.const 3)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (i32.const -1)+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.shr_u+ (i32.and+ (i32.const -1)+ (i32.const 2147483647)+ )+ (i32.const 31)+ )+ )+ (drop+ (i32.const 0)+ )+ (drop+ (f32.le+ (f32.const -1)+ (f32.const -1)+ )+ )+ (drop+ (i32.clz+ (i32.const 0)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (i32.clz+ (i32.const 0)+ )+ (i32.const 26)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (i32.clz+ (i32.const 0)+ )+ (i32.const 27)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.wrap_i64+ (i64.clz+ (i64.const 0)+ )+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (i32.wrap_i64+ (i64.clz+ (i64.const 0)+ )+ )+ (i32.const 25)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (i32.wrap_i64+ (i64.clz+ (i64.const 0)+ )+ )+ (i32.const 26)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.eqz+ (i32.const -1)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (i32.shr_u+ (i32.wrap_i64+ (i64.const -1)+ )+ (i32.const 24)+ )+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.shr_u+ (i32.wrap_i64+ (i64.const -1)+ )+ (i32.const 25)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (i32.shr_u+ (i32.wrap_i64+ (i64.extend_i32_s+ (i32.const -1)+ )+ )+ (i32.const 24)+ )+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.shr_u+ (i32.wrap_i64+ (i64.extend_i32_s+ (i32.const -1)+ )+ )+ (i32.const 25)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (i32.xor+ (local.get $0)+ (i32.le_u+ (local.get $0)+ (i32.const 2)+ )+ )+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ )+ (func $linear-sums (param $0 i32) (param $1 i32)+ (drop+ (i32.add+ (i32.shl+ (local.get $0)+ (i32.const 4)+ )+ (local.get $1)+ )+ )+ (drop+ (i32.add+ (i32.add+ (local.get $1)+ (i32.shl+ (local.get $0)+ (i32.const 3)+ )+ )+ (i32.const 12)+ )+ )+ (drop+ (i32.const 4)+ )+ (drop+ (i32.const 18)+ )+ (drop+ (i32.const 6)+ )+ (drop+ (i32.const -4)+ )+ (drop+ (i32.const 2)+ )+ (drop+ (i32.const 1)+ )+ (drop+ (i32.const 26)+ )+ (drop+ (i32.const -20)+ )+ (drop+ (i32.const 22)+ )+ (drop+ (i32.add+ (i32.shl+ (i32.const 1)+ (local.get $0)+ )+ (i32.const 14)+ )+ )+ (drop+ (i32.sub+ (i32.shl+ (local.get $1)+ (i32.const 3)+ )+ (i32.const 66)+ )+ )+ (drop+ (i32.const 44)+ )+ (drop+ (i32.add+ (i32.mul+ (local.get $0)+ (i32.const 10)+ )+ (i32.const 14)+ )+ )+ (drop+ (i32.add+ (i32.shl+ (local.get $0)+ (i32.const 1)+ )+ (i32.const 34)+ )+ )+ (drop+ (local.get $0)+ )+ )+ (func $almost-sign-ext (param $0 i32)+ (drop+ (i32.shr_s+ (i32.shl+ (i32.const 100)+ (i32.const 25)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.shl+ (i32.const 50)+ (i32.const 1)+ )+ )+ )+ (func $squaring (param $0 i32) (param $1 i32)+ (drop+ (i32.and+ (local.get $0)+ (i32.const 8)+ )+ )+ (drop+ (i32.and+ (local.get $0)+ (i32.const 11)+ )+ )+ (drop+ (i32.and+ (local.get $0)+ (i32.const 8)+ )+ )+ (drop+ (i32.or+ (local.get $0)+ (i32.const 203)+ )+ )+ (drop+ (i32.shl+ (local.get $0)+ (i32.const 19)+ )+ )+ (drop+ (i32.shr_s+ (local.get $0)+ (i32.const 19)+ )+ )+ (drop+ (i32.shr_u+ (local.get $0)+ (i32.const 19)+ )+ )+ (drop+ (i32.shr_u+ (i32.shr_s+ (local.get $0)+ (i32.const 11)+ )+ (i32.const 8)+ )+ )+ )+ (func $sign-ext-ne (param $0 i32) (param $1 i32)+ (drop+ (block (result i32)+ (drop+ (local.get $0)+ )+ (i32.const 1)+ )+ )+ (drop+ (block (result i32)+ (drop+ (local.get $0)+ )+ (i32.const 1)+ )+ )+ (drop+ (block (result i32)+ (drop+ (local.get $0)+ )+ (i32.const 1)+ )+ )+ (drop+ (i32.ne+ (i32.and+ (local.get $0)+ (i32.const 255)+ )+ (i32.const 111)+ )+ )+ (drop+ (i32.ne+ (i32.and+ (local.get $0)+ (i32.const 255)+ )+ (i32.and+ (local.get $1)+ (i32.const 255)+ )+ )+ )+ )+ (func $sign-ext-eqz (param $0 i32) (param $1 i32)+ (drop+ (i32.eqz+ (i32.and+ (local.get $0)+ (i32.const 255)+ )+ )+ )+ )+ (func $sign-ext-boolean (param $0 i32) (param $1 i32)+ (drop+ (if (result i32)+ (i32.and+ (local.get $0)+ (i32.const 255)+ )+ (i32.const 100)+ (i32.const 200)+ )+ )+ )+ (func $add-sub-zero (param $0 i32) (param $1 i64)+ (drop+ (local.get $0)+ )+ (drop+ (local.get $0)+ )+ (drop+ (local.get $1)+ )+ (drop+ (local.get $1)+ )+ )+ (func $store-signext (param $0 i32)+ (i32.store8+ (i32.const 8)+ (local.get $0)+ )+ (i32.store8+ (i32.const 8)+ (i32.shr_s+ (i32.shl+ (local.get $0)+ (i32.const 25)+ )+ (i32.const 25)+ )+ )+ (i32.store8+ (i32.const 8)+ (local.get $0)+ )+ (i32.store16+ (i32.const 8)+ (local.get $0)+ )+ (i32.store16+ (i32.const 8)+ (i32.shr_s+ (i32.shl+ (local.get $0)+ (i32.const 17)+ )+ (i32.const 17)+ )+ )+ (i32.store16+ (i32.const 8)+ (local.get $0)+ )+ (i32.store+ (i32.const 8)+ (i32.shr_s+ (i32.shl+ (local.get $0)+ (i32.const 16)+ )+ (i32.const 16)+ )+ )+ (i32.store+ (i32.const 8)+ (i32.shr_s+ (i32.shl+ (local.get $0)+ (i32.const 8)+ )+ (i32.const 8)+ )+ )+ )+ (func $sign-ext-tee (param $0 i32) (param $1 i32)+ (drop+ (i32.shr_s+ (i32.shl+ (local.tee $0+ (i32.const 128)+ )+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop+ (local.tee $0+ (i32.const 127)+ )+ )+ )+ (func $sign-ext-load (param $0 i32) (param $1 i32)+ (drop+ (i32.load8_s+ (i32.const 256)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (i32.shr_u+ (i32.load8_s+ (i32.const 256)+ )+ (i32.const 1)+ )+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.shr_u+ (i32.load8_u+ (i32.const 256)+ )+ (i32.const 1)+ )+ )+ (drop+ (i32.load16_s+ (i32.const 256)+ )+ )+ (drop+ (local.tee $1+ (i32.load8_s+ (i32.const 1)+ )+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (local.tee $1+ (i32.load8_u+ (i32.const 1)+ )+ )+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.and+ (local.tee $1+ (i32.load8_s+ (i32.const 1)+ )+ )+ (i32.const 255)+ )+ )+ (drop+ (local.tee $1+ (i32.load8_u+ (i32.const 1)+ )+ )+ )+ )+ (func $mask-bits (param $0 i32) (param $1 i32)+ (drop+ (local.tee $0+ (i32.const 127)+ )+ )+ (drop+ (local.tee $0+ (i32.const 128)+ )+ )+ (drop+ (i32.and+ (local.tee $0+ (i32.const 128)+ )+ (i32.const 254)+ )+ )+ (drop+ (i32.and+ (local.tee $0+ (i32.const 128)+ )+ (i32.const 1279)+ )+ )+ (drop+ (i32.and+ (local.tee $0+ (i32.const 128)+ )+ (i32.const 1290)+ )+ )+ (drop+ (local.tee $0+ (i32.const 128)+ )+ )+ (drop+ (local.tee $0+ (i32.const 128)+ )+ )+ (drop+ (i32.and+ (local.tee $0+ (i32.const 128)+ )+ (i32.const 127)+ )+ )+ )+ (func $local-info-zero-ext (param $0 i32) (param $1 i32)+ (local $x i32)+ (local $y i32)+ (local $z i32)+ (local $w i32)+ (local.set $x+ (i32.const 212)+ )+ (drop+ (local.get $x)+ )+ (local.set $y+ (i32.const 500)+ )+ (drop+ (i32.and+ (local.get $y)+ (i32.const 255)+ )+ )+ (local.set $0+ (i32.const 212)+ )+ (drop+ (i32.and+ (local.get $0)+ (i32.const 255)+ )+ )+ (local.set $z+ (i32.const 212)+ )+ (local.set $z+ (i32.const 220)+ )+ (drop+ (local.get $z)+ )+ (local.set $w+ (i32.const 212)+ )+ (local.set $w+ (i32.const 1000)+ )+ (drop+ (i32.and+ (local.get $w)+ (i32.const 255)+ )+ )+ )+ (func $local-info-sign-ext-bitsize (param $0 i32) (param $1 i32)+ (local $x i32)+ (local $y i32)+ (local $z i32)+ (local $w i32)+ (local.set $x+ (i32.const 127)+ )+ (drop+ (local.get $x)+ )+ (local.set $y+ (i32.const 128)+ )+ (drop+ (i32.shr_s+ (i32.shl+ (local.get $y)+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (local.set $0+ (i32.const 127)+ )+ (drop+ (i32.shr_s+ (i32.shl+ (local.get $0)+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (local.set $z+ (i32.const 127)+ )+ (local.set $z+ (i32.const 100)+ )+ (drop+ (local.get $z)+ )+ (local.set $w+ (i32.const 127)+ )+ (local.set $w+ (i32.const 150)+ )+ (drop+ (i32.shr_s+ (i32.shl+ (local.get $w)+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ )+ (func $local-info-sign-ext-already-exted (param $0 i32) (param $1 i32)+ (local $x i32)+ (local $y i32)+ (local $z i32)+ (local $w i32)+ (local.set $x+ (i32.shr_s+ (i32.shl+ (local.get $0)+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop+ (local.get $x)+ )+ (local.set $y+ (i32.shr_s+ (i32.shl+ (local.get $0)+ (i32.const 16)+ )+ (i32.const 16)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (local.get $y)+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (local.set $0+ (i32.shr_s+ (i32.shl+ (local.get $0)+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (local.get $0)+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (local.set $z+ (i32.shr_s+ (i32.shl+ (local.get $0)+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (local.set $z+ (i32.shr_s+ (i32.shl+ (local.get $1)+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop+ (local.get $z)+ )+ (local.set $w+ (i32.shr_s+ (i32.shl+ (local.get $0)+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (local.set $w+ (i32.shr_s+ (i32.shl+ (local.get $0)+ (i32.const 23)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (local.get $w)+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (local.get $0)+ (i32.const 24)+ )+ (i32.const 23)+ )+ )+ )+ (func $signed-loads-fill-the-bits (param $$e i32) (result i32)+ (local $$0 i32)+ (local $$conv i32)+ (local.set $$0+ (i32.load8_s+ (i32.const 1024)+ )+ )+ (local.set $$conv+ (i32.and+ (local.get $$0)+ (i32.const 255)+ )+ )+ (return+ (i32.eq+ (local.get $$e)+ (local.get $$conv)+ )+ )+ )+ (func $local-info-sign-ext-already-exted-by-load (param $0 i32) (param $1 i32)+ (local $x i32)+ (local $y i32)+ (local $z i32)+ (local $w i32)+ (local.set $x+ (i32.load8_s+ (i32.const 1024)+ )+ )+ (drop+ (local.get $x)+ )+ (local.set $y+ (i32.load8_u+ (i32.const 1024)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (local.get $y)+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (local.set $z+ (i32.load16_s+ (i32.const 1024)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (local.get $z)+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ )+ (func $compare-load-s-sign-extend (param $0 i32) (param $1 i32)+ (drop+ (i32.eq+ (i32.load8_u+ (local.get $0)+ )+ (i32.and+ (local.get $1)+ (i32.const 255)+ )+ )+ )+ (drop+ (i32.eq+ (i32.load8_u+ (local.get $0)+ )+ (i32.and+ (local.get $1)+ (i32.const 255)+ )+ )+ )+ (drop+ (i32.eq+ (i32.load8_u+ (local.get $0)+ )+ (i32.shr_s+ (i32.shl+ (local.get $1)+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ )+ (drop+ (i32.eq+ (i32.load8_s+ (local.get $0)+ )+ (i32.shr_s+ (i32.shl+ (local.get $1)+ (i32.const 16)+ )+ (i32.const 16)+ )+ )+ )+ (drop+ (i32.eq+ (i32.load8_u+ (local.get $0)+ )+ (i32.shr_s+ (i32.shl+ (local.get $1)+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ )+ (drop+ (i32.eq+ (i32.load8_s+ (local.get $0)+ )+ (i32.shr_s+ (i32.shl+ (local.get $1)+ (i32.const 16)+ )+ (i32.const 16)+ )+ )+ )+ )+ (func $unsign-diff-sizes (param $x i32) (param $y i32) (result i32)+ (i32.ne+ (i32.shr_s+ (i32.shl+ (call $unsign-diff-sizes+ (i32.const -1)+ (i32.const 5)+ )+ (i32.const 24)+ )+ (i32.const 24)+ )+ (i32.shr_s+ (i32.shl+ (call $unsign-diff-sizes+ (i32.const 1)+ (i32.const 2006)+ )+ (i32.const 16)+ )+ (i32.const 16)+ )+ )+ )+ (func $unsign-same-sizes (param $x i32) (param $y i32) (result i32)+ (i32.ne+ (i32.and+ (call $unsign-same-sizes+ (i32.const -1)+ (i32.const 5)+ )+ (i32.const 255)+ )+ (i32.and+ (call $unsign-same-sizes+ (i32.const 1)+ (i32.const 2006)+ )+ (i32.const 255)+ )+ )+ )+ (func $fuzz-almost-sign-ext+ (drop+ (i32.shr_s+ (i32.shl+ (i32.load16_u+ (i32.const 2278)+ )+ (i32.const 17)+ )+ (i32.const 16)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (i32.load16_u+ (i32.const 2278)+ )+ (i32.const 17)+ )+ (i32.const 16)+ )+ )+ )+ (func $fuzz-comp-impossible (param $x i32)+ (drop+ (block (result i32)+ (drop+ (local.get $x)+ )+ (i32.const 0)+ )+ )+ (drop+ (block (result i32)+ (drop+ (local.get $x)+ )+ (i32.const 0)+ )+ )+ (drop+ (i32.eq+ (i32.and+ (local.get $x)+ (i32.const 255)+ )+ (i32.const 127)+ )+ )+ (drop+ (block (result i32)+ (drop+ (local.get $x)+ )+ (i32.const 0)+ )+ )+ (drop+ (block (result i32)+ (drop+ (local.get $x)+ )+ (i32.const 0)+ )+ )+ (drop+ (block (result i32)+ (drop+ (local.get $x)+ )+ (i32.const 0)+ )+ )+ (drop+ (i32.eq+ (i32.and+ (local.get $x)+ (i32.const 255)+ )+ (i32.const 252)+ )+ )+ )+ (func $if-parallel (param $0 i32) (param $1 i32)+ (drop+ (i32.add+ (local.get $1)+ (i32.const 1)+ )+ )+ (drop+ (block (result i32)+ (drop+ (local.tee $0+ (local.get $1)+ )+ )+ (i32.add+ (local.get $1)+ (i32.const 1)+ )+ )+ )+ (drop+ (block (result i32)+ (i32.add+ (local.get $1)+ (unreachable)+ )+ )+ )+ (drop+ (block (result i32)+ (drop+ (local.tee $0+ (local.get $1)+ )+ )+ (i32.add+ (local.get $1)+ (unreachable)+ )+ )+ )+ (drop+ (if (result i32)+ (unreachable)+ (i32.add+ (local.get $1)+ (unreachable)+ )+ (i32.add+ (local.get $1)+ (unreachable)+ )+ )+ )+ )+ (func $select-parallel (param $0 i32) (param $1 i32)+ (drop+ (i32.add+ (local.get $1)+ (i32.const 1)+ )+ )+ (drop+ (select+ (local.tee $0+ (local.get $1)+ )+ (local.tee $0+ (local.get $1)+ )+ (local.get $0)+ )+ )+ (drop+ (block (result i32)+ (drop+ (local.tee $0+ (local.get $1)+ )+ )+ (i32.add+ (local.get $1)+ (i32.const 1)+ )+ )+ )+ (drop+ (select+ (local.tee $0+ (local.get $1)+ )+ (local.tee $0+ (local.get $1)+ )+ (local.tee $0+ (local.get $1)+ )+ )+ )+ (drop+ (select+ (local.tee $0+ (local.get $1)+ )+ (local.tee $0+ (local.get $1)+ )+ (unreachable)+ )+ )+ )+ (func $zero-shifts-is-not-sign-ext+ (drop+ (i32.eq+ (i32.load16_s align=1+ (i32.const 790656516)+ )+ (i32.const -5431187)+ )+ )+ (drop+ (i32.eq+ (i32.shl+ (i32.load16_s align=1+ (i32.const 790656516)+ )+ (i32.const 1)+ )+ (i32.const -5431187)+ )+ )+ )+ (func $zero-ops (result i32)+ (return+ (i32.eq+ (i32.load16_s align=1+ (i32.const 790656516)+ )+ (i32.const -1337)+ )+ )+ )+ (func $zero-ops-64 (result i32)+ (return+ (i64.eq+ (i64.load16_s align=1+ (i32.const 790656516)+ )+ (i64.const -1337)+ )+ )+ )+ (func $zero-ops-64-special (result i32)+ (return+ (i32.wrap_i64+ (i64.popcnt+ (i64.const 7377)+ )+ )+ )+ )+ (func $sign-ext-1-and-ne (result i32)+ (drop+ (call $sign-ext-1-and-ne)+ )+ (i32.const 1)+ )+ (func $neg-shifts-and-255 (result i32)+ (i32.and+ (i32.const -99)+ (i32.const 255)+ )+ )+ (func $neg-shifts-and-255-b (result i32)+ (i32.and+ (i32.const -2349025)+ (i32.const 255)+ )+ )+ (func $shifts-square-overflow (param $x i32) (result i32)+ (i32.shr_u+ (i32.shr_u+ (local.get $x)+ (i32.const 31)+ )+ (i32.const 31)+ )+ )+ (func $shifts-square-no-overflow-small (param $x i32) (result i32)+ (i32.shr_u+ (local.get $x)+ (i32.const 9)+ )+ )+ (func $shifts-square-overflow-64 (param $x i64) (result i64)+ (i64.shr_u+ (i64.shr_u+ (local.get $x)+ (i64.const 63)+ )+ (i64.const 63)+ )+ )+ (func $shifts-square-no-overflow-small-64 (param $x i64) (result i64)+ (i64.shr_u+ (local.get $x)+ (i64.const 9)+ )+ )+ (func $shifts-square-unreachable (param $x i32) (result i32)+ (i32.shr_u+ (i32.shr_u+ (unreachable)+ (i32.const 1031)+ )+ (i32.const 4098)+ )+ )+ (func $mix-shifts (result i32)+ (i32.shr_u+ (i32.shl+ (i32.const 23)+ (i32.const 3)+ )+ (i32.const 8)+ )+ )+ (func $actually-no-shifts (result i32)+ (i32.const 33)+ )+ (func $less-shifts-than-it-seems (param $x i32) (result i32)+ (i32.const 4800)+ )+ (func $and-popcount32 (result i32)+ (i32.and+ (i32.popcnt+ (i32.const -1)+ )+ (i32.const 31)+ )+ )+ (func $and-popcount32-big (result i32)+ (i32.popcnt+ (i32.const -1)+ )+ )+ (func $and-popcount64 (result i64)+ (i64.and+ (i64.popcnt+ (i64.const -1)+ )+ (i64.const 63)+ )+ )+ (func $and-popcount64-big (result i64)+ (i64.and+ (i64.popcnt+ (i64.const -1)+ )+ (i64.const 127)+ )+ )+ (func $and-popcount64-bigger (result i64)+ (i64.and+ (i64.popcnt+ (i64.const -1)+ )+ (i64.const 255)+ )+ )+ (func $optimizeAddedConstants-filters-through-nonzero (result i32)+ (i32.sub+ (i32.shl+ (i32.const -536870912)+ (i32.wrap_i64+ (i64.const 0)+ )+ )+ (i32.const 31744)+ )+ )+ (func $optimizeAddedConstants-filters-through-nonzero-b (result i32)+ (i32.sub+ (i32.shl+ (i32.const -536870912)+ (i32.wrap_i64+ (i64.const -1)+ )+ )+ (i32.const 31744)+ )+ )+ (func $return-proper-value-from-shift-left-by-zero (result i32)+ (if (result i32)+ (i32.add+ (loop $label$0 (result i32)+ (block $label$1+ (br_if $label$1+ (i32.load+ (i32.const 0)+ )+ )+ )+ (i32.const -62)+ )+ (i32.const 40)+ )+ (i32.const 1)+ (i32.const 0)+ )+ )+ (func $de-morgan-2 (param $x i32) (param $y i32)+ (drop+ (i32.eqz+ (i32.or+ (local.get $x)+ (local.get $y)+ )+ )+ )+ (drop+ (i32.or+ (i32.eqz+ (local.get $x)+ )+ (i32.eqz+ (local.get $y)+ )+ )+ )+ (drop+ (i32.xor+ (i32.eqz+ (local.get $x)+ )+ (i32.eqz+ (local.get $y)+ )+ )+ )+ (drop+ (i32.and+ (local.get $y)+ (i32.eqz+ (local.get $x)+ )+ )+ )+ (drop+ (i32.and+ (i32.eqz+ (local.get $y)+ )+ (local.get $x)+ )+ )+ (drop+ (i32.and+ (i32.eqz+ (local.get $x)+ )+ (i32.wrap_i64+ (i64.const 2)+ )+ )+ )+ (drop+ (i32.and+ (i32.eqz+ (local.get $y)+ )+ (i32.wrap_i64+ (i64.const 1)+ )+ )+ )+ )+ (func $subzero1 (param $0 i32) (result i32)+ (i32.sub+ (i32.const 32)+ (i32.clz+ (local.get $0)+ )+ )+ )+ (func $subzero2 (param $0 i32) (result i32)+ (i32.sub+ (i32.const 32)+ (i32.clz+ (local.get $0)+ )+ )+ )+ (func $subzero3 (param $0 i32) (param $1 i32) (result i32)+ (i32.sub+ (local.get $1)+ (i32.clz+ (local.get $0)+ )+ )+ )+ (func $subzero4 (param $0 i32) (param $1 i32) (result i32)+ (i32.sub+ (local.get $0)+ (i32.clz+ (local.get $1)+ )+ )+ )+ (func $mul-32-power-2 (param $x i32) (result i32)+ (drop+ (call $mul-32-power-2+ (i32.shl+ (local.get $x)+ (i32.const 2)+ )+ )+ )+ (drop+ (call $mul-32-power-2+ (i32.mul+ (local.get $x)+ (i32.const 5)+ )+ )+ )+ (drop+ (call $mul-32-power-2+ (local.get $x)+ )+ )+ (drop+ (call $mul-32-power-2+ (i32.const 0)+ )+ )+ (drop+ (call $mul-32-power-2+ (i32.mul+ (call $mul-32-power-2+ (i32.const 123)+ )+ (i32.const 0)+ )+ )+ )+ (drop+ (call $mul-32-power-2+ (i32.sub+ (i32.const 0)+ (local.get $x)+ )+ )+ )+ (drop+ (call $mul-32-power-2+ (i32.shl+ (local.get $x)+ (i32.const 31)+ )+ )+ )+ (unreachable)+ )+ (func $mul-64-power-2 (param $x i64) (result i64)+ (drop+ (call $mul-64-power-2+ (i64.shl+ (local.get $x)+ (i64.const 2)+ )+ )+ )+ (drop+ (call $mul-64-power-2+ (i64.mul+ (local.get $x)+ (i64.const 5)+ )+ )+ )+ (drop+ (call $mul-64-power-2+ (local.get $x)+ )+ )+ (drop+ (call $mul-64-power-2+ (i64.const 0)+ )+ )+ (drop+ (call $mul-64-power-2+ (i64.mul+ (call $mul-64-power-2+ (i64.const 123)+ )+ (i64.const 0)+ )+ )+ )+ (drop+ (call $mul-64-power-2+ (i64.sub+ (i64.const 0)+ (local.get $x)+ )+ )+ )+ (drop+ (call $mul-64-power-2+ (i64.shl+ (local.get $x)+ (i64.const 63)+ )+ )+ )+ (unreachable)+ )+ (func $div-32-power-2 (param $x i32) (result i32)+ (drop+ (call $div-32-power-2+ (i32.shr_u+ (local.get $x)+ (i32.const 2)+ )+ )+ )+ (drop+ (call $div-32-power-2+ (i32.div_u+ (local.get $x)+ (i32.const 5)+ )+ )+ )+ (drop+ (call $div-32-power-2+ (local.get $x)+ )+ )+ (drop+ (call $div-32-power-2+ (i32.div_u+ (local.get $x)+ (i32.const 0)+ )+ )+ )+ (drop+ (call $div-32-power-2+ (i32.div_u+ (call $div-32-power-2+ (i32.const 123)+ )+ (i32.const 0)+ )+ )+ )+ (drop+ (call $div-32-power-2+ (i32.eq+ (local.get $x)+ (i32.const -1)+ )+ )+ )+ (drop+ (call $div-32-power-2+ (i32.shr_u+ (local.get $x)+ (i32.const 31)+ )+ )+ )+ (unreachable)+ )+ (func $urem-32-power-2 (param $x i32) (result i32)+ (drop+ (call $urem-32-power-2+ (i32.and+ (local.get $x)+ (i32.const 3)+ )+ )+ )+ (drop+ (call $urem-32-power-2+ (i32.rem_u+ (local.get $x)+ (i32.const 5)+ )+ )+ )+ (drop+ (call $urem-32-power-2+ (i32.const 0)+ )+ )+ (drop+ (call $urem-32-power-2+ (i32.rem_u+ (local.get $x)+ (i32.const 0)+ )+ )+ )+ (drop+ (call $urem-32-power-2+ (i32.rem_u+ (local.get $x)+ (i32.const -1)+ )+ )+ )+ (drop+ (call $urem-32-power-2+ (i32.and+ (local.get $x)+ (i32.const 2147483647)+ )+ )+ )+ (drop+ (call $urem-32-power-2+ (i32.const 0)+ )+ )+ (unreachable)+ )+ (func $fdiv-32-power-2 (param $x f32)+ (drop+ (f32.mul+ (local.get $x)+ (f32.const 0.5)+ )+ )+ (drop+ (f32.mul+ (local.get $x)+ (f32.const -0.5)+ )+ )+ (drop+ (f32.mul+ (local.get $x)+ (f32.const 2.3283064365386963e-10)+ )+ )+ (drop+ (f32.mul+ (local.get $x)+ (f32.const 5.421010862427522e-20)+ )+ )+ (drop+ (f32.mul+ (local.get $x)+ (f32.const 8507059173023461586584365e13)+ )+ )+ (drop+ (f32.mul+ (local.get $x)+ (f32.const 1.1754943508222875e-38)+ )+ )+ (drop+ (f32.mul+ (local.get $x)+ (f32.const -8507059173023461586584365e13)+ )+ )+ (drop+ (f32.mul+ (local.get $x)+ (f32.const -1.1754943508222875e-38)+ )+ )+ (drop+ (f32.div+ (local.get $x)+ (f32.const 5.877471754111438e-39)+ )+ )+ (drop+ (f32.div+ (local.get $x)+ (f32.const 5.877471754111438e-39)+ )+ )+ (drop+ (f32.div+ (local.get $x)+ (f32.const 0)+ )+ )+ (drop+ (f32.div+ (local.get $x)+ (f32.const nan:0x400000)+ )+ )+ (drop+ (f32.div+ (local.get $x)+ (f32.const inf)+ )+ )+ (drop+ (f32.div+ (local.get $x)+ (f32.const -inf)+ )+ )+ )+ (func $fdiv-64-power-2 (param $x f64)+ (drop+ (f64.mul+ (local.get $x)+ (f64.const 0.5)+ )+ )+ (drop+ (f64.mul+ (local.get $x)+ (f64.const -0.5)+ )+ )+ (drop+ (f64.mul+ (local.get $x)+ (f64.const 2.3283064365386963e-10)+ )+ )+ (drop+ (f64.mul+ (local.get $x)+ (f64.const 5.421010862427522e-20)+ )+ )+ (drop+ (f64.mul+ (local.get $x)+ (f64.const 4494232837155789769323262e283)+ )+ )+ (drop+ (f64.mul+ (local.get $x)+ (f64.const 2.2250738585072014e-308)+ )+ )+ (drop+ (f64.mul+ (local.get $x)+ (f64.const -4494232837155789769323262e283)+ )+ )+ (drop+ (f64.mul+ (local.get $x)+ (f64.const -2.2250738585072014e-308)+ )+ )+ (drop+ (f64.div+ (local.get $x)+ (f64.const 1.1125369292536007e-308)+ )+ )+ (drop+ (f64.div+ (local.get $x)+ (f64.const 8988465674311579538646525e283)+ )+ )+ (drop+ (f64.div+ (local.get $x)+ (f64.const 0)+ )+ )+ (drop+ (f64.div+ (local.get $x)+ (f64.const nan:0x8000000000000)+ )+ )+ (drop+ (f64.div+ (local.get $x)+ (f64.const inf)+ )+ )+ (drop+ (f64.div+ (local.get $x)+ (f64.const -inf)+ )+ )+ )+ (func $srem-by-const (param $x i32) (param $y i64)+ (drop+ (i32.const 0)+ )+ (drop+ (i64.const 0)+ )+ (drop+ (i32.rem_s+ (local.get $x)+ (i32.const -2147483648)+ )+ )+ (drop+ (i64.rem_s+ (local.get $y)+ (i64.const -9223372036854775808)+ )+ )+ )+ (func $srem-by-pot-eq-ne-zero (param $x i32) (param $y i64)+ (drop+ (i32.eqz+ (i32.and+ (local.get $x)+ (i32.const 3)+ )+ )+ )+ (drop+ (i64.eqz+ (i64.and+ (local.get $y)+ (i64.const 3)+ )+ )+ )+ (drop+ (i32.eqz+ (i32.and+ (local.get $x)+ (i32.const 3)+ )+ )+ )+ (drop+ (i64.eqz+ (i64.and+ (local.get $y)+ (i64.const 3)+ )+ )+ )+ (drop+ (i32.eqz+ (i32.and+ (local.get $x)+ (i32.const 3)+ )+ )+ )+ (drop+ (i64.eqz+ (i64.and+ (local.get $y)+ (i64.const 1)+ )+ )+ )+ (drop+ (i32.eqz+ (i32.and+ (local.get $x)+ (i32.const 3)+ )+ )+ )+ (drop+ (i64.eqz+ (i64.and+ (local.get $y)+ (i64.const 3)+ )+ )+ )+ (drop+ (i32.and+ (local.get $x)+ (i32.const 1)+ )+ )+ (drop+ (i32.wrap_i64+ (i64.and+ (local.get $y)+ (i64.const 1)+ )+ )+ )+ (drop+ (i32.eqz+ (i32.const 0)+ )+ )+ (drop+ (i32.eqz+ (i32.and+ (local.get $x)+ (i32.const 2147483647)+ )+ )+ )+ (drop+ (i32.ne+ (i32.and+ (local.get $x)+ (i32.const 2147483647)+ )+ (i32.const 0)+ )+ )+ (drop+ (i64.eqz+ (i64.and+ (local.get $y)+ (i64.const 9223372036854775807)+ )+ )+ )+ (drop+ (i64.ne+ (i64.and+ (local.get $y)+ (i64.const 9223372036854775807)+ )+ (i64.const 0)+ )+ )+ (drop+ (i32.eqz+ (i32.rem_s+ (local.get $x)+ (i32.const 3)+ )+ )+ )+ (drop+ (i64.eqz+ (i64.rem_s+ (local.get $y)+ (i64.const 3)+ )+ )+ )+ )+ (func $orZero (param $0 i32) (result i32)+ (local.get $0)+ )+ (func $andZero (param $0 i32) (result i32)+ (drop+ (i32.const 0)+ )+ (drop+ (i32.and+ (call $andZero+ (i32.const 1234)+ )+ (i32.const 0)+ )+ )+ (unreachable)+ )+ (func $abstract-additions (param $x32 i32) (param $x64 i64) (param $y32 f32) (param $y64 f64)+ (drop+ (local.get $x32)+ )+ (drop+ (local.get $x32)+ )+ (drop+ (local.get $x32)+ )+ (drop+ (local.get $x32)+ )+ (drop+ (local.get $x64)+ )+ (drop+ (local.get $x64)+ )+ (drop+ (local.get $x64)+ )+ (drop+ (local.get $x64)+ )+ (drop+ (i32.const 0)+ )+ (drop+ (i64.const 0)+ )+ (drop+ (f32.mul+ (local.get $y32)+ (f32.const 0)+ )+ )+ (drop+ (f64.mul+ (local.get $y64)+ (f64.const 0)+ )+ )+ (drop+ (local.get $x32)+ )+ (drop+ (local.get $x64)+ )+ (drop+ (f32.mul+ (local.get $y32)+ (f32.const 1)+ )+ )+ (drop+ (f64.mul+ (local.get $y64)+ (f64.const 1)+ )+ )+ (drop+ (i32.const 0)+ )+ (drop+ (i64.const 0)+ )+ (drop+ (i32.and+ (unreachable)+ (i32.const 0)+ )+ )+ (drop+ (i64.and+ (unreachable)+ (i64.const 0)+ )+ )+ (drop+ (local.get $x32)+ )+ (drop+ (local.get $x32)+ )+ (drop+ (local.get $x64)+ )+ (drop+ (local.get $x64)+ )+ (drop+ (f32.mul+ (local.get $y32)+ (f32.const 1)+ )+ )+ (drop+ (f64.mul+ (local.get $y64)+ (f64.const 1)+ )+ )+ (drop+ (f32.div+ (local.get $y32)+ (f32.const 1.2000000476837158)+ )+ )+ (drop+ (i32.sub+ (i32.const 0)+ (local.get $x32)+ )+ )+ (drop+ (i64.sub+ (i64.const 0)+ (local.get $x64)+ )+ )+ (drop+ (f32.sub+ (f32.const -0)+ (local.get $y32)+ )+ )+ (drop+ (f64.sub+ (f64.const -0)+ (local.get $y64)+ )+ )+ (drop+ (i32.eq+ (local.get $x32)+ (i32.const 10)+ )+ )+ (drop+ (i32.le_u+ (i32.add+ (local.get $x32)+ (i32.const 10)+ )+ (i32.const 20)+ )+ )+ (drop+ (i32.eq+ (local.get $x32)+ (i32.const 30)+ )+ )+ (drop+ (i64.eq+ (local.get $x64)+ (i64.const 10)+ )+ )+ (drop+ (i32.eq+ (local.get $x32)+ (i32.const 10)+ )+ )+ (drop+ (i32.eq+ (i32.add+ (local.get $x32)+ (i32.const 10)+ )+ (local.get $x32)+ )+ )+ (drop+ (i32.eq+ (local.get $x32)+ (i32.const 30)+ )+ )+ (drop+ (i32.eq+ (i32.sub+ (local.get $x32)+ (i32.const 30)+ )+ (local.get $x32)+ )+ )+ (drop+ (i32.eq+ (i32.add+ (local.get $x32)+ (i32.const 30)+ )+ (local.get $x32)+ )+ )+ (drop+ (i32.eq+ (i32.sub+ (local.get $x32)+ (i32.const 10)+ )+ (local.get $x32)+ )+ )+ (drop+ (i32.const 1)+ )+ )+ (func $negatives-are-sometimes-better (param $x i32) (param $y i64) (param $z f32)+ (drop+ (i32.sub+ (local.get $x)+ (i32.const -64)+ )+ )+ (drop+ (i32.add+ (local.get $x)+ (i32.const -64)+ )+ )+ (drop+ (i32.sub+ (local.get $x)+ (i32.const -8192)+ )+ )+ (drop+ (i32.sub+ (local.get $x)+ (i32.const -1048576)+ )+ )+ (drop+ (i32.sub+ (local.get $x)+ (i32.const -134217728)+ )+ )+ (drop+ (i64.sub+ (local.get $y)+ (i64.const -64)+ )+ )+ (drop+ (i64.add+ (local.get $y)+ (i64.const -64)+ )+ )+ (drop+ (i64.sub+ (local.get $y)+ (i64.const -8192)+ )+ )+ (drop+ (i64.sub+ (local.get $y)+ (i64.const -1048576)+ )+ )+ (drop+ (i64.sub+ (local.get $y)+ (i64.const -134217728)+ )+ )+ (drop+ (i64.sub+ (local.get $y)+ (i64.const -17179869184)+ )+ )+ (drop+ (i64.sub+ (local.get $y)+ (i64.const -2199023255552)+ )+ )+ (drop+ (i64.sub+ (local.get $y)+ (i64.const -281474976710656)+ )+ )+ (drop+ (i64.sub+ (local.get $y)+ (i64.const -36028797018963968)+ )+ )+ (drop+ (i64.sub+ (local.get $y)+ (i64.const -4611686018427387904)+ )+ )+ (drop+ (f32.add+ (local.get $z)+ (f32.const 64)+ )+ )+ )+ (func $shift-a-zero (param $x i32) (param $y i64) (param $z f32)+ (drop+ (i32.const 0)+ )+ (drop+ (i32.const 0)+ )+ (drop+ (i32.const 0)+ )+ (drop+ (i64.const 0)+ )+ (drop+ (i32.shl+ (i32.const 0)+ (unreachable)+ )+ )+ )+ (func $identical-siblings (param $x i32) (param $y i64) (param $z f64) (param $xx i32)+ (drop+ (i32.const 0)+ )+ (drop+ (i64.const 0)+ )+ (drop+ (f64.sub+ (local.get $z)+ (local.get $z)+ )+ )+ (drop+ (i32.sub+ (local.get $x)+ (local.get $xx)+ )+ )+ (drop+ (i32.sub+ (unreachable)+ (unreachable)+ )+ )+ (drop+ (i32.add+ (local.get $x)+ (local.get $x)+ )+ )+ (drop+ (i32.const 0)+ )+ (drop+ (i32.const 0)+ )+ (drop+ (i32.const 0)+ )+ (drop+ (i32.const 0)+ )+ (drop+ (i32.const 0)+ )+ (drop+ (i32.const 0)+ )+ (drop+ (local.get $x)+ )+ (drop+ (local.get $x)+ )+ (drop+ (i32.const 1)+ )+ (drop+ (i32.const 1)+ )+ (drop+ (i32.const 1)+ )+ (drop+ (i32.const 1)+ )+ (drop+ (i32.const 1)+ )+ (drop+ (i64.const 0)+ )+ (drop+ (i32.const 0)+ )+ (drop+ (i32.const 0)+ )+ (drop+ (i32.const 0)+ )+ (drop+ (i32.const 0)+ )+ (drop+ (i32.const 0)+ )+ (drop+ (local.get $y)+ )+ (drop+ (local.get $y)+ )+ (drop+ (i32.const 1)+ )+ (drop+ (i32.const 1)+ )+ (drop+ (i32.const 1)+ )+ (drop+ (i32.const 1)+ )+ (drop+ (i32.const 1)+ )+ )+ (func $all_ones (param $x i32) (param $y i64)+ (drop+ (local.get $x)+ )+ (drop+ (i32.const -1)+ )+ (drop+ (i32.or+ (local.tee $x+ (i32.const 1337)+ )+ (i32.const -1)+ )+ )+ (drop+ (local.get $y)+ )+ (drop+ (i64.const -1)+ )+ )+ (func $xor (param $x i32) (param $y i64)+ (drop+ (local.get $x)+ )+ )+ (func $select-on-const (param $x i32) (param $y i64)+ (drop+ (local.get $x)+ )+ (drop+ (i32.const 3)+ )+ (drop+ (local.tee $x+ (i32.const 5)+ )+ )+ (drop+ (block (result i32)+ (drop+ (local.tee $x+ (i32.const 6)+ )+ )+ (i32.const 7)+ )+ )+ (drop+ (select+ (i32.const 4)+ (local.tee $x+ (i32.const 5)+ )+ (i32.const 1)+ )+ )+ (drop+ (local.tee $x+ (i32.const 6)+ )+ )+ (drop+ (i32.eqz+ (i32.eqz+ (local.get $x)+ )+ )+ )+ (drop+ (i32.eqz+ (local.get $x)+ )+ )+ (drop+ (i32.ge_s+ (local.get $x)+ (i32.const 0)+ )+ )+ (drop+ (i32.lt_s+ (local.get $x)+ (i32.const 0)+ )+ )+ (drop+ (i32.lt_s+ (local.get $x)+ (i32.const 0)+ )+ )+ (drop+ (i32.gt_s+ (local.get $x)+ (i32.const 0)+ )+ )+ (drop+ (i32.le_s+ (local.get $x)+ (i32.const 0)+ )+ )+ (drop+ (i32.ge_s+ (local.get $x)+ (i32.const 0)+ )+ )+ (drop+ (i64.extend_i32_u+ (i32.eqz+ (i32.eqz+ (local.get $x)+ )+ )+ )+ )+ (drop+ (i64.extend_i32_u+ (i32.eqz+ (local.get $x)+ )+ )+ )+ (drop+ (i64.extend_i32_u+ (i64.eqz+ (local.get $y)+ )+ )+ )+ (drop+ (i64.extend_i32_u+ (i32.eqz+ (i64.eqz+ (local.get $y)+ )+ )+ )+ )+ (drop+ (i64.extend_i32_u+ (i64.ge_s+ (local.get $y)+ (i64.const 0)+ )+ )+ )+ (drop+ (i64.extend_i32_u+ (i64.lt_s+ (local.get $y)+ (i64.const 0)+ )+ )+ )+ (drop+ (i64.extend_i32_u+ (i64.lt_s+ (local.get $y)+ (i64.const 0)+ )+ )+ )+ (drop+ (i64.extend_i32_u+ (i64.ge_s+ (local.get $y)+ (i64.const 0)+ )+ )+ )+ (drop+ (select+ (i32.const 0)+ (local.get $x)+ (i32.const 0)+ )+ )+ (drop+ (select+ (i32.const 2)+ (local.get $x)+ (i32.const 2)+ )+ )+ (drop+ (select+ (local.get $x)+ (i32.const 2)+ (local.get $x)+ )+ )+ (drop+ (select+ (local.get $y)+ (i64.const 0)+ (i64.eqz+ (i64.const 0)+ )+ )+ )+ (drop+ (select+ (local.get $y)+ (i64.const 2)+ (i64.eqz+ (i64.const 2)+ )+ )+ )+ )+ (func $optimize-boolean (param $x i32) (param $y i64)+ (drop+ (select+ (i32.const 1)+ (i32.const 2)+ (local.get $x)+ )+ )+ (drop+ (i32.and+ (local.get $x)+ (i32.const 1)+ )+ )+ (drop+ (i32.eqz+ (i32.and+ (local.get $x)+ (i32.const 1)+ )+ )+ )+ (drop+ (i32.wrap_i64+ (i64.shr_u+ (local.get $y)+ (i64.const 63)+ )+ )+ )+ (drop+ (i32.eqz+ (i32.shr_u+ (local.get $x)+ (i32.const 31)+ )+ )+ )+ (drop+ (i64.eqz+ (i64.shr_u+ (local.get $y)+ (i64.const 63)+ )+ )+ )+ (drop+ (i64.eqz+ (i64.shr_u+ (local.get $y)+ (i64.const 63)+ )+ )+ )+ (drop+ (i64.eqz+ (local.get $y)+ )+ )+ (drop+ (i32.eqz+ (i32.wrap_i64+ (local.get $y)+ )+ )+ )+ (drop+ (i32.wrap_i64+ (i64.and+ (local.get $y)+ (i64.const 1)+ )+ )+ )+ (drop+ (i64.eqz+ (i64.and+ (local.get $y)+ (i64.const 1)+ )+ )+ )+ (drop+ (i32.and+ (local.get $x)+ (i32.const 1)+ )+ )+ (drop+ (i32.const 1)+ )+ (drop+ (i64.and+ (local.get $y)+ (i64.const 1)+ )+ )+ (drop+ (i64.const 1)+ )+ (drop+ (i32.and+ (local.get $x)+ (i32.const 1)+ )+ )+ (drop+ (i64.ne+ (local.get $y)+ (i64.const 0)+ )+ )+ (drop+ (i32.ne+ (local.get $x)+ (i32.const 0)+ )+ )+ (drop+ (if (result i32)+ (i32.and+ (local.get $x)+ (i32.const 3)+ )+ (i32.const 1)+ (i32.const 0)+ )+ )+ (drop+ (if (result i32)+ (i32.and+ (local.get $x)+ (i32.const 2147483647)+ )+ (i32.const 1)+ (i32.const 0)+ )+ )+ )+ (func $optimize-bitwise-oprations (param $x i32) (param $y i32) (param $z i64) (param $w i64)+ (drop+ (i32.rotl+ (i32.const -2)+ (local.get $x)+ )+ )+ (drop+ (i64.rotl+ (i64.const -2)+ (local.get $z)+ )+ )+ )+ (func $getFallthrough+ (local $x0 i32)+ (local $x1 i32)+ (local $x2 i32)+ (local $x3 i32)+ (local $x4 i32)+ (local $x5 i32)+ (local $x6 i32)+ (local $x7 i32)+ (local.set $x0+ (i32.const 1)+ )+ (drop+ (local.get $x0)+ )+ (local.set $x1+ (local.tee $x2+ (i32.const 1)+ )+ )+ (drop+ (local.get $x1)+ )+ (local.set $x3+ (loop $loop-in (result i32)+ (i32.const 1)+ )+ )+ (drop+ (local.get $x3)+ )+ (local.set $x4+ (if (result i32)+ (i32.const 1)+ (i32.const 2)+ (i32.const 3)+ )+ )+ (drop+ (i32.and+ (local.get $x4)+ (i32.const 7)+ )+ )+ (local.set $x5+ (if (result i32)+ (i32.const 1)+ (unreachable)+ (i32.const 3)+ )+ )+ (drop+ (local.get $x5)+ )+ (local.set $x6+ (if (result i32)+ (i32.const 1)+ (i32.const 3)+ (unreachable)+ )+ )+ (drop+ (local.get $x6)+ )+ (drop+ (block $out (result i32)+ (local.set $x7+ (br_if $out+ (i32.const 1)+ (i32.const 1)+ )+ )+ (drop+ (local.get $x7)+ )+ (unreachable)+ )+ )+ )+ (func $tee-with-unreachable-value (result f64)+ (local $var$0 i32)+ (block $label$1 (result f64)+ (local.tee $var$0+ (br_if $label$1+ (f64.const 1)+ (unreachable)+ )+ )+ )+ )+ (func $add-sub-zero-reorder-1 (param $temp i32) (result i32)+ (i32.add+ (i32.add+ (i32.sub+ (i32.const 0)+ (local.get $temp)+ )+ (local.tee $temp+ (i32.const 1)+ )+ )+ (i32.const 2)+ )+ )+ (func $add-sub-zero-reorder-2 (param $temp i32) (result i32)+ (i32.add+ (i32.sub+ (local.tee $temp+ (i32.const 1)+ )+ (local.get $temp)+ )+ (i32.const 2)+ )+ )+ (func $const-float-zero (param $fx f32) (param $fy f64)+ (drop+ (f32.sub+ (local.get $fx)+ (f32.const 0)+ )+ )+ (drop+ (f64.sub+ (local.get $fy)+ (f64.const 0)+ )+ )+ (drop+ (f32.add+ (local.get $fx)+ (f32.const -0)+ )+ )+ (drop+ (f64.add+ (local.get $fy)+ (f64.const -0)+ )+ )+ (drop+ (f32.add+ (local.get $fx)+ (f32.const 0)+ )+ )+ (drop+ (f64.add+ (local.get $fy)+ (f64.const 0)+ )+ )+ (drop+ (f32.sub+ (f32.const 0)+ (local.get $fx)+ )+ )+ (drop+ (f64.sub+ (f64.const 0)+ (local.get $fy)+ )+ )+ (drop+ (f32.add+ (local.get $fx)+ (f32.const 0)+ )+ )+ (drop+ (f64.add+ (local.get $fy)+ (f64.const 0)+ )+ )+ (drop+ (f32.sub+ (f32.const -nan:0x34546d)+ (f32.const 0)+ )+ )+ )+ (func $rhs-is-neg-one (param $x i32) (param $y i64) (param $fx f32) (param $fy f64)+ (drop+ (i32.add+ (local.get $x)+ (i32.const 1)+ )+ )+ (drop+ (i64.add+ (local.get $y)+ (i64.const 1)+ )+ )+ (drop+ (i32.const 0)+ )+ (drop+ (i32.const 0)+ )+ (drop+ (i32.gt_s+ (local.get $x)+ (i32.const -1)+ )+ )+ (drop+ (i64.gt_s+ (local.get $y)+ (i64.const -1)+ )+ )+ (drop+ (i64.extend_i32_s+ (i32.const 0)+ )+ )+ (drop+ (i32.const 1)+ )+ (drop+ (i32.const 1)+ )+ (drop+ (i32.le_s+ (local.get $x)+ (i32.const -1)+ )+ )+ (drop+ (i64.le_s+ (local.get $y)+ (i64.const -1)+ )+ )+ (drop+ (i32.eq+ (local.get $x)+ (i32.const -1)+ )+ )+ (drop+ (i64.eq+ (local.get $y)+ (i64.const -1)+ )+ )+ (drop+ (i32.ne+ (local.get $x)+ (i32.const -1)+ )+ )+ (drop+ (i64.ne+ (local.get $y)+ (i64.const -1)+ )+ )+ (drop+ (i32.sub+ (i32.const 0)+ (local.get $x)+ )+ )+ (drop+ (i64.sub+ (i64.const 0)+ (local.get $y)+ )+ )+ (drop+ (f32.sub+ (f32.const -0)+ (local.get $fx)+ )+ )+ (drop+ (f64.sub+ (f64.const -0)+ (local.get $fy)+ )+ )+ (drop+ (i32.eq+ (local.get $x)+ (i32.const -1)+ )+ )+ (drop+ (i64.extend_i32_u+ (i64.eq+ (local.get $y)+ (i64.const -1)+ )+ )+ )+ )+ (func $rhs-is-const (param $x i32) (param $y i64) (param $fx f32) (param $fy f64)+ (drop+ (i32.eq+ (local.get $x)+ (i32.const -2147483648)+ )+ )+ (drop+ (i64.extend_i32_u+ (i64.eq+ (local.get $y)+ (i64.const -9223372036854775808)+ )+ )+ )+ (drop+ (i64.div_s+ (local.get $y)+ (i64.const -2147483648)+ )+ )+ (drop+ (i32.ge_u+ (local.get $x)+ (i32.const -2)+ )+ )+ (drop+ (i32.eq+ (local.get $x)+ (i32.const -1)+ )+ )+ (drop+ (i32.ge_u+ (local.get $x)+ (i32.const -2147483647)+ )+ )+ (drop+ (i32.shr_u+ (local.get $x)+ (i32.const 31)+ )+ )+ (drop+ (i64.extend_i32_u+ (i64.eq+ (local.get $y)+ (i64.const -1)+ )+ )+ )+ (drop+ (i64.shr_u+ (local.get $y)+ (i64.const 63)+ )+ )+ (drop+ (i32.const 1)+ )+ (drop+ (i32.const 1)+ )+ (drop+ (i32.const 0)+ )+ (drop+ (i32.const 0)+ )+ (drop+ (i32.ne+ (local.get $x)+ (i32.const 0)+ )+ )+ (drop+ (i64.ne+ (local.get $y)+ (i64.const 0)+ )+ )+ (drop+ (i32.eqz+ (local.get $x)+ )+ )+ (drop+ (i64.eqz+ (local.get $y)+ )+ )+ (drop+ (i32.const 1)+ )+ (drop+ (i32.const 1)+ )+ (drop+ (i32.const 1)+ )+ (drop+ (i32.const 1)+ )+ (drop+ (i32.const 0)+ )+ (drop+ (i32.const 0)+ )+ (drop+ (i32.const 0)+ )+ (drop+ (i32.const 0)+ )+ (drop+ (i32.ne+ (local.get $x)+ (i32.const 2147483647)+ )+ )+ (drop+ (i64.ne+ (local.get $y)+ (i64.const 9223372036854775807)+ )+ )+ (drop+ (i32.ne+ (local.get $x)+ (i32.const -2147483648)+ )+ )+ (drop+ (i64.ne+ (local.get $y)+ (i64.const -9223372036854775808)+ )+ )+ (drop+ (i32.eq+ (local.get $x)+ (i32.const -2147483648)+ )+ )+ (drop+ (i64.eq+ (local.get $y)+ (i64.const -9223372036854775808)+ )+ )+ (drop+ (i32.eq+ (local.get $x)+ (i32.const 2147483647)+ )+ )+ (drop+ (i64.eq+ (local.get $y)+ (i64.const 9223372036854775807)+ )+ )+ (drop+ (f32.sub+ (f32.const -0)+ (local.get $fx)+ )+ )+ (drop+ (f64.mul+ (local.get $fy)+ (f64.const 2.1)+ )+ )+ (drop+ (f64.mul+ (local.get $fy)+ (f64.const -2)+ )+ )+ (drop+ (f32.div+ (local.get $fx)+ (f32.const -inf)+ )+ )+ (drop+ (f64.div+ (local.get $fy)+ (f64.const 0)+ )+ )+ (drop+ (f64.div+ (local.get $fy)+ (f64.const -nan:0x8000000000000)+ )+ )+ (drop+ (f64.div+ (f64.const -5)+ (local.get $fy)+ )+ )+ )+ (func $lhs-is-neg-one (param $x i32) (param $y i64)+ (drop+ (i32.const -1)+ )+ (drop+ (i64.const -1)+ )+ (drop+ (i32.const -1)+ )+ (drop+ (i64.const -1)+ )+ (drop+ (i32.const -1)+ )+ (drop+ (i64.const -1)+ )+ (drop+ (i32.shr_s+ (i32.const -1)+ (call $ne0)+ )+ )+ (drop+ (i32.shr_u+ (i32.const -1)+ (local.get $x)+ )+ )+ )+ (func $lhs-is-const (param $x i32) (param $y i64)+ (drop+ (i32.sub+ (i32.const 1)+ (local.get $x)+ )+ )+ (drop+ (i64.sub+ (i64.const 1)+ (local.get $y)+ )+ )+ (drop+ (i32.sub+ (i32.const -2)+ (local.get $x)+ )+ )+ (drop+ (i64.sub+ (i64.const -2)+ (local.get $y)+ )+ )+ (drop+ (i32.sub+ (local.get $x)+ (i32.const 1)+ )+ )+ (drop+ (i64.sub+ (local.get $y)+ (i64.const 1)+ )+ )+ (drop+ (i32.sub+ (local.get $x)+ (i32.const -2147483648)+ )+ )+ )+ (func $pre-combine-or (param $x i32) (param $y i32)+ (drop+ (i32.ge_s+ (local.get $x)+ (local.get $y)+ )+ )+ (drop+ (i32.ge_s+ (local.get $x)+ (local.get $y)+ )+ )+ (drop+ (i32.or+ (i32.eq+ (local.get $x)+ (i32.const 1)+ )+ (i32.gt_s+ (local.get $x)+ (local.get $y)+ )+ )+ )+ (drop+ (i32.or+ (i32.eq+ (local.get $x)+ (local.get $y)+ )+ (i32.gt_s+ (local.get $x)+ (i32.const 1)+ )+ )+ )+ (drop+ (i32.or+ (i32.gt_s+ (call $ne0)+ (local.get $y)+ )+ (i32.eq+ (call $ne0)+ (local.get $y)+ )+ )+ )+ (drop+ (i32.or+ (i32.lt_s+ (call $ne0)+ (local.get $y)+ )+ (i32.eq+ (call $ne0)+ (local.get $y)+ )+ )+ )+ )+ (func $combine-or (param $x i32) (param $y i32)+ (drop+ (i32.ge_s+ (local.get $x)+ (local.get $y)+ )+ )+ )+ (func $select-into-arms (param $x i32) (param $y i32)+ (if+ (select+ (local.get $x)+ (local.get $y)+ (local.get $y)+ )+ (unreachable)+ )+ )+ (func $optimize-boolean-context (param $x i32) (param $y i32)+ (if+ (local.get $x)+ (unreachable)+ )+ (drop+ (select+ (local.get $x)+ (local.get $y)+ (local.get $x)+ )+ )+ )+ (func $optimize-relationals (param $x i32) (param $y i32) (param $X i64) (param $Y i64)+ (drop+ (i32.eq+ (local.get $x)+ (i32.const -2147483647)+ )+ )+ (drop+ (i32.eq+ (local.get $x)+ (i32.const -2147483648)+ )+ )+ (drop+ (i32.eq+ (local.get $x)+ (i32.const 2147483647)+ )+ )+ (drop+ (i32.eq+ (local.get $x)+ (local.get $y)+ )+ )+ (drop+ (i64.eq+ (local.get $X)+ (local.get $Y)+ )+ )+ (drop+ (i32.eq+ (local.get $x)+ (local.get $y)+ )+ )+ (drop+ (i64.eq+ (local.get $X)+ (local.get $Y)+ )+ )+ (drop+ (i32.ne+ (local.get $x)+ (local.get $y)+ )+ )+ (drop+ (i64.ne+ (local.get $X)+ (local.get $Y)+ )+ )+ (drop+ (i32.gt_s+ (i32.sub+ (local.get $x)+ (local.get $y)+ )+ (i32.const 0)+ )+ )+ (drop+ (i32.ge_s+ (i32.sub+ (local.get $x)+ (local.get $y)+ )+ (i32.const 0)+ )+ )+ (drop+ (i32.ne+ (local.get $x)+ (local.get $y)+ )+ )+ (drop+ (i32.const 1)+ )+ (drop+ (i32.const 1)+ )+ (drop+ (i32.lt_s+ (i32.sub+ (local.get $x)+ (local.get $y)+ )+ (i32.const 0)+ )+ )+ (drop+ (i32.le_s+ (i32.sub+ (local.get $x)+ (local.get $y)+ )+ (i32.const 0)+ )+ )+ (drop+ (i32.const 0)+ )+ (drop+ (i32.const 0)+ )+ (drop+ (i32.eq+ (local.get $x)+ (local.get $y)+ )+ )+ (drop+ (i32.eq+ (local.get $x)+ (i32.const -2147483648)+ )+ )+ (drop+ (i32.ne+ (local.get $x)+ (i32.const -2147483648)+ )+ )+ (drop+ (i32.lt_s+ (i32.sub+ (local.get $x)+ (i32.const -2147483648)+ )+ (i32.const 0)+ )+ )+ (drop+ (i32.ge_s+ (i32.sub+ (local.get $x)+ (i32.const -2147483648)+ )+ (i32.const 0)+ )+ )+ (drop+ (i32.gt_s+ (i32.sub+ (local.get $x)+ (block $block (result i32)+ (i32.const -2147483648)+ )+ )+ (i32.const 0)+ )+ )+ (drop+ (i32.gt_s+ (i32.sub+ (local.get $x)+ (block $block29 (result i32)+ (i32.const -2147483648)+ )+ )+ (i32.const 0)+ )+ )+ )+ (func $unsigned-context (param $x i32) (param $y i64)+ (drop+ (i32.div_u+ (i32.and+ (local.get $x)+ (i32.const 2147483647)+ )+ (i32.const 3)+ )+ )+ (drop+ (i32.div_s+ (i32.and+ (local.get $x)+ (i32.const 2147483647)+ )+ (i32.const -3)+ )+ )+ (drop+ (i32.eq+ (i32.and+ (local.get $x)+ (i32.const 2147483647)+ )+ (i32.const -2147483648)+ )+ )+ (drop+ (i64.shr_u+ (i64.and+ (local.get $y)+ (i64.const 9223372036854775807)+ )+ (i64.const 1)+ )+ )+ (drop+ (i64.div_s+ (i64.and+ (local.get $y)+ (i64.const 9223372036854775807)+ )+ (i64.const -1)+ )+ )+ (drop+ (i32.rem_u+ (i32.and+ (local.get $x)+ (i32.const 2147483647)+ )+ (i32.const 3)+ )+ )+ (drop+ (i32.shr_u+ (i32.and+ (local.get $x)+ (i32.const 2147483647)+ )+ (i32.const 7)+ )+ )+ (drop+ (i32.ge_u+ (i32.and+ (local.get $x)+ (i32.const 2147483647)+ )+ (i32.const 7)+ )+ )+ (drop+ (i32.ge_s+ (i32.and+ (local.get $x)+ (i32.const 2147483647)+ )+ (i32.const -7)+ )+ )+ )+ (func $optimize-float-mul-by-two (param $0 f64) (param $1 f32)+ (drop+ (f64.add+ (local.get $0)+ (local.get $0)+ )+ )+ (drop+ (f32.add+ (local.get $1)+ (local.get $1)+ )+ )+ (drop+ (f64.mul+ (call $tee-with-unreachable-value)+ (f64.const 2)+ )+ )+ (drop+ (f64.mul+ (local.get $0)+ (f64.const -2)+ )+ )+ )+ (func $duplicate-elimination (param $x i32) (param $y i32) (param $z i32) (param $w f64)+ (drop+ (f64.abs+ (local.get $w)+ )+ )+ (drop+ (f64.ceil+ (local.get $w)+ )+ )+ (drop+ (f64.floor+ (local.get $w)+ )+ )+ (drop+ (f64.trunc+ (local.get $w)+ )+ )+ (drop+ (f64.nearest+ (local.get $w)+ )+ )+ (drop+ (f64.nearest+ (f64.trunc+ (local.get $w)+ )+ )+ )+ (drop+ (f64.trunc+ (f64.nearest+ (local.get $w)+ )+ )+ )+ (drop+ (local.get $w)+ )+ (drop+ (f64.neg+ (local.get $w)+ )+ )+ (drop+ (local.get $w)+ )+ (drop+ (i32.eqz+ (i32.eqz+ (local.get $x)+ )+ )+ )+ (drop+ (i32.eqz+ (local.get $x)+ )+ )+ (drop+ (i64.eqz+ (i64.const 1)+ )+ )+ (drop+ (i32.ne+ (local.get $x)+ (i32.const 2)+ )+ )+ (drop+ (i32.and+ (local.get $x)+ (i32.const 1)+ )+ )+ (drop+ (i32.rem_s+ (local.get $x)+ (local.get $y)+ )+ )+ (drop+ (i32.rem_u+ (local.get $x)+ (local.get $y)+ )+ )+ (drop+ (local.get $y)+ )+ (drop+ (local.get $y)+ )+ (drop+ (i32.sub+ (local.get $y)+ (i32.sub+ (local.get $x)+ (local.get $y)+ )+ )+ )+ (drop+ (local.get $y)+ )+ (drop+ (local.get $y)+ )+ (drop+ (local.get $y)+ )+ (drop+ (local.get $y)+ )+ (drop+ (local.get $x)+ )+ (drop+ (i32.and+ (local.get $x)+ (local.get $y)+ )+ )+ (drop+ (i32.and+ (local.get $x)+ (local.get $y)+ )+ )+ (drop+ (i32.and+ (local.get $x)+ (local.get $y)+ )+ )+ (drop+ (i32.and+ (local.get $x)+ (local.get $y)+ )+ )+ (drop+ (i32.or+ (local.get $x)+ (local.get $y)+ )+ )+ (drop+ (i32.or+ (local.get $x)+ (local.get $y)+ )+ )+ (drop+ (i32.or+ (local.get $x)+ (local.get $y)+ )+ )+ (drop+ (i32.or+ (local.get $x)+ (local.get $y)+ )+ )+ (drop+ (i32.or+ (local.get $z)+ (i32.or+ (local.get $x)+ (local.get $y)+ )+ )+ )+ (drop+ (i32.or+ (local.get $y)+ (i32.or+ (local.get $x)+ (local.get $z)+ )+ )+ )+ (drop+ (i32.or+ (call $ne0)+ (local.get $x)+ )+ )+ (drop+ (i32.or+ (i32.or+ (call $ne0)+ (local.get $x)+ )+ (call $ne0)+ )+ )+ (drop+ (i32.or+ (call $ne0)+ (local.get $x)+ )+ )+ (drop+ (i32.or+ (call $ne0)+ (i32.or+ (call $ne0)+ (local.get $x)+ )+ )+ )+ (drop+ (i32.rem_s+ (i32.rem_s+ (local.get $y)+ (local.get $x)+ )+ (local.get $y)+ )+ )+ (drop+ (i32.rem_u+ (local.get $y)+ (i32.rem_u+ (local.get $x)+ (local.get $y)+ )+ )+ )+ (drop+ (i32.or+ (local.get $x)+ (i32.or+ (local.tee $x+ (i32.const 1)+ )+ (local.get $x)+ )+ )+ )+ (drop+ (i32.or+ (i32.or+ (local.get $x)+ (local.tee $x+ (i32.const 1)+ )+ )+ (local.get $x)+ )+ )+ (drop+ (i32.xor+ (local.get $x)+ (i32.xor+ (local.tee $x+ (i32.const 1)+ )+ (local.get $x)+ )+ )+ )+ (drop+ (i32.xor+ (i32.xor+ (local.get $x)+ (local.tee $x+ (i32.const 1)+ )+ )+ (local.get $x)+ )+ )+ )+ (func $optimize-shifts (param $x i32) (param $y i32) (param $z i64) (param $w i64)+ (drop+ (local.get $x)+ )+ (drop+ (local.get $x)+ )+ (drop+ (local.get $x)+ )+ (drop+ (local.get $x)+ )+ (drop+ (local.get $x)+ )+ (drop+ (local.get $z)+ )+ (drop+ (local.get $z)+ )+ (drop+ (local.get $z)+ )+ (drop+ (local.get $z)+ )+ (drop+ (local.get $z)+ )+ (drop+ (i32.shl+ (local.get $x)+ (local.get $y)+ )+ )+ (drop+ (i32.shl+ (local.get $x)+ (local.get $y)+ )+ )+ (drop+ (i32.shr_s+ (local.get $x)+ (local.get $y)+ )+ )+ (drop+ (i32.shr_u+ (local.get $x)+ (local.get $y)+ )+ )+ (drop+ (i64.shl+ (local.get $z)+ (local.get $w)+ )+ )+ (drop+ (i64.shl+ (local.get $z)+ (local.get $w)+ )+ )+ (drop+ (i64.shr_s+ (local.get $z)+ (local.get $w)+ )+ )+ (drop+ (i64.shr_u+ (local.get $z)+ (local.get $w)+ )+ )+ (drop+ (local.get $x)+ )+ (drop+ (local.get $z)+ )+ (drop+ (i64.shl+ (local.get $z)+ (i64.and+ (local.get $w)+ (i64.const 32)+ )+ )+ )+ (drop+ (i64.shr_u+ (local.get $z)+ (i64.and+ (local.get $w)+ (i64.const 31)+ )+ )+ )+ )+ (func $optimize-float-points (param $x0 f64) (param $x1 f64) (param $y0 f32) (param $y1 f32)+ (drop+ (f64.mul+ (local.get $x0)+ (local.get $x0)+ )+ )+ (drop+ (f32.mul+ (local.get $y0)+ (local.get $y0)+ )+ )+ (drop+ (f64.mul+ (f64.add+ (local.get $x0)+ (local.get $x1)+ )+ (f64.add+ (local.get $x0)+ (local.get $x1)+ )+ )+ )+ (drop+ (f64.abs+ (f64.mul+ (local.get $x0)+ (local.get $x1)+ )+ )+ )+ (drop+ (f32.abs+ (f32.mul+ (local.get $y1)+ (local.get $y0)+ )+ )+ )+ (drop+ (f64.abs+ (f64.mul+ (local.get $x0)+ (f64.const 0)+ )+ )+ )+ (drop+ (f32.abs+ (f32.mul+ (f32.const 0)+ (local.get $y0)+ )+ )+ )+ (drop+ (f64.abs+ (f64.mul+ (f64.add+ (local.get $x0)+ (local.get $x1)+ )+ (f64.add+ (local.get $x0)+ (local.get $x0)+ )+ )+ )+ )+ (drop+ (f64.abs+ (local.get $x0)+ )+ )+ (drop+ (f32.abs+ (local.get $y0)+ )+ )+ (drop+ (f64.abs+ (f64.sub+ (f64.const 0)+ (local.get $x0)+ )+ )+ )+ (drop+ (f32.abs+ (f32.sub+ (f32.const 0)+ (local.get $y0)+ )+ )+ )+ (drop+ (f64.div+ (local.get $x0)+ (local.get $x0)+ )+ )+ (drop+ (f32.div+ (local.get $y0)+ (local.get $y0)+ )+ )+ (drop+ (f64.div+ (f64.add+ (local.get $x0)+ (local.get $x1)+ )+ (f64.add+ (local.get $x0)+ (local.get $x1)+ )+ )+ )+ (drop+ (f64.abs+ (f64.div+ (local.get $x0)+ (local.get $x1)+ )+ )+ )+ (drop+ (f32.abs+ (f32.div+ (local.get $y1)+ (local.get $y0)+ )+ )+ )+ (drop+ (f64.mul+ (local.get $x0)+ (local.get $x0)+ )+ )+ (drop+ (f32.mul+ (local.get $y0)+ (local.get $y0)+ )+ )+ (drop+ (f64.div+ (local.get $x0)+ (local.get $x0)+ )+ )+ (drop+ (f32.div+ (local.get $y0)+ (local.get $y0)+ )+ )+ (drop+ (f64.abs+ (f64.div+ (local.get $x0)+ (f64.const 0)+ )+ )+ )+ (drop+ (f32.abs+ (f32.div+ (f32.const 0)+ (local.get $y0)+ )+ )+ )+ (drop+ (f64.abs+ (f64.div+ (f64.add+ (local.get $x0)+ (local.get $x1)+ )+ (f64.add+ (local.get $x0)+ (local.get $x0)+ )+ )+ )+ )+ )+)+(module+ (type $none_=>_none (func))+ (import "env" "memory" (memory $0 (shared 256 256)))+ (func $x+ (drop+ (i32.shr_s+ (i32.shl+ (i32.atomic.load8_u+ (i32.const 100)+ )+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ )+)+(module+ (type $i32_i32_i32_=>_none (func (param i32 i32 i32)))+ (memory $0 0)+ (func $optimize-bulk-memory-copy (param $dst i32) (param $src i32) (param $sz i32)+ (memory.copy+ (local.get $dst)+ (local.get $dst)+ (local.get $sz)+ )+ (memory.copy+ (local.get $dst)+ (local.get $src)+ (i32.const 0)+ )+ (i32.store8+ (local.get $dst)+ (i32.load8_u+ (local.get $src)+ )+ )+ (i32.store16 align=1+ (local.get $dst)+ (i32.load16_u align=1+ (local.get $src)+ )+ )+ (memory.copy+ (local.get $dst)+ (local.get $src)+ (i32.const 3)+ )+ (i32.store align=1+ (local.get $dst)+ (i32.load align=1+ (local.get $src)+ )+ )+ (memory.copy+ (local.get $dst)+ (local.get $src)+ (i32.const 5)+ )+ (memory.copy+ (local.get $dst)+ (local.get $src)+ (i32.const 6)+ )+ (memory.copy+ (local.get $dst)+ (local.get $src)+ (i32.const 7)+ )+ (i64.store align=1+ (local.get $dst)+ (i64.load align=1+ (local.get $src)+ )+ )+ (v128.store align=1+ (local.get $dst)+ (v128.load align=1+ (local.get $src)+ )+ )+ (memory.copy+ (local.get $dst)+ (local.get $src)+ (local.get $sz)+ )+ (memory.copy+ (i32.const 0)+ (i32.const 0)+ (i32.load+ (i32.const 3)+ )+ )+ )+)+(module+ (type $none_=>_anyref (func (result anyref)))+ (func $if-arms-subtype-fold (result anyref)+ (ref.null extern)+ )+ (func $if-arms-subtype-nofold (result anyref)+ (if (result anyref)+ (i32.const 0)+ (ref.null extern)+ (ref.null func)+ )+ )+)+(module+ (type $i32_i32_i32_f64_=>_none (func (param i32 i32 i32 f64)))+ (func $duplicate-elimination (param $x i32) (param $y i32) (param $z i32) (param $w f64)+ (drop+ (i32.extend8_s+ (local.get $x)+ )+ )+ (drop+ (i32.extend16_s+ (local.get $x)+ )+ )+ )+)+(module+ (type $none_=>_none (func))+ (func $test+ (if+ (try (result i32)+ (do+ (i32.const 123)+ )+ (catch+ (drop+ (pop exnref)+ )+ (i32.const 456)+ )+ )+ (nop)+ )+ )+)+(module+ (type $i32_=>_i32 (func (param i32) (result i32)))+ (type $ref?|i32_->_i32|_=>_i32 (func (param (ref null $i32_=>_i32)) (result i32)))+ (func $call_from-param (param $f (ref null $i32_=>_i32)) (result i32)+ (unreachable) ) )
binaryen/test/passes/optimize-instructions_all-features.wast view
@@ -2,5175 +2,6186 @@ (memory 0) (type $0 (func (param i32 i64))) (func $f (type $0) (param $i1 i32) (param $i2 i64)- (if- (i32.eqz- (local.get $i1)- )- (drop- (i32.const 10)- )- )- (if- (i32.eqz- (local.get $i1)- )- (drop- (i32.const 11)- )- (drop- (i32.const 12)- )- )- (if- (i64.eqz- (local.get $i2)- )- (drop- (i32.const 11)- )- (drop- (i32.const 12)- )- )- (drop- (i32.eqz- (i32.gt_s- (i32.const 1)- (i32.const 2)- )- )- )- (drop- (i32.eqz- (i32.ge_s- (i32.const 1)- (i32.const 2)- )- )- )- (drop- (i32.eqz- (i32.lt_s- (i32.const 1)- (i32.const 2)- )- )- )- (drop- (i32.eqz- (i32.le_s- (i32.const 1)- (i32.const 2)- )- )- )- (drop- (i32.eqz- (i32.gt_u- (i32.const 1)- (i32.const 2)- )- )- )- (drop- (i32.eqz- (i32.ge_u- (i32.const 1)- (i32.const 2)- )- )- )- (drop- (i32.eqz- (i32.lt_u- (i32.const 1)- (i32.const 2)- )- )- )- (drop- (i32.eqz- (i32.le_u- (i32.const 1)- (i32.const 2)- )- )- )- (drop- (i32.eqz- (f32.gt- (f32.const 1)- (f32.const 2)- )- )- )- (drop- (i32.eqz- (f32.ge- (f32.const 1)- (f32.const 2)- )- )- )- (drop- (i32.eqz- (f32.lt- (f32.const 1)- (f32.const 2)- )- )- )- (drop- (i32.eqz- (f32.le- (f32.const 1)- (f32.const 2)- )- )- )- (drop- (i32.eqz- (f64.gt- (f64.const 1)- (f64.const 2)- )- )- )- (drop- (i32.eqz- (f64.ge- (f64.const 1)- (f64.const 2)- )- )- )- (drop- (i32.eqz- (f64.lt- (f64.const 1)- (f64.const 2)- )- )- )- (drop- (i32.eqz- (f64.le- (f64.const 1)- (f64.const 2)- )- )- )- (drop- (i32.eqz- (f32.eq- (f32.const 1)- (f32.const 2)- )- )- )- (drop- (i32.eqz- (f32.ne- (f32.const 1)- (f32.const 2)- )- )- )- (drop- (i32.eqz- (f64.eq- (f64.const 1)- (f64.const 2)- )- )- )- (drop- (i32.eqz- (f64.ne- (f64.const 1)- (f64.const 2)- )- )- )- ;; we handle only 0 in the right position, as we assume a const is there, and don't care about if- ;; both are consts here (precompute does that, so no need)- (drop- (i32.eq- (i32.const 100)- (i32.const 0)- )- )- (drop- (i32.eq- (i32.const 0)- (i32.const 100)- )- )- (drop- (i32.eq- (i32.const 0)- (i32.const 0)- )- )- (drop- (i64.eq- (i64.const 100)- (i64.const 0)- )- )- (drop- (i64.eq- (i64.const 0)- (i64.const 100)- )- )- (drop- (i64.eq- (i64.const 0)- (i64.const 0)- )- )- (if- (i32.eqz- (i32.eqz- (i32.const 123)- )- )- (nop)- )- (if- (try (result i32)- (do- (i32.eqz- (i32.eqz- (i32.const 123)- )- )- )- (catch- (drop- (pop exnref)- )- (i32.eqz- (i32.eqz- (i32.const 456)- )- )- )- )- (nop)- )- (drop- (select- (i32.const 101)- (i32.const 102)- (i32.eqz- (local.get $i1)- )- )- )- (drop- (select- (local.tee $i1- (i32.const 103)- ) ;; these conflict- (local.tee $i1- (i32.const 104)- )- (i32.eqz- (local.get $i1)- )- )- )- (drop- (select- (i32.const 0)- (i32.const 1)- (i32.eqz- (i32.eqz- (i32.const 2)- )- )- )- )- )- (func $load-store- (drop (i32.and (i32.load8_s (i32.const 0)) (i32.const 255)))- (drop (i32.and (i32.load8_u (i32.const 1)) (i32.const 255)))- (drop (i32.and (i32.load8_s (i32.const 2)) (i32.const 254)))- (drop (i32.and (i32.load8_u (i32.const 3)) (i32.const 1)))- (drop (i32.and (i32.load16_s (i32.const 4)) (i32.const 65535)))- (drop (i32.and (i32.load16_u (i32.const 5)) (i32.const 65535)))- (drop (i32.and (i32.load16_s (i32.const 6)) (i32.const 65534)))- (drop (i32.and (i32.load16_u (i32.const 7)) (i32.const 1)))- ;;- (i32.store8 (i32.const 8) (i32.and (i32.const -1) (i32.const 255)))- (i32.store8 (i32.const 9) (i32.and (i32.const -2) (i32.const 254)))- (i32.store16 (i32.const 10) (i32.and (i32.const -3) (i32.const 65535)))- (i32.store16 (i32.const 11) (i32.and (i32.const -4) (i32.const 65534)))- ;;- (i32.store8 (i32.const 11) (i32.wrap_i64 (i64.const 1)))- (i32.store16 (i32.const 11) (i32.wrap_i64 (i64.const 2)))- (i32.store (i32.const 11) (i32.wrap_i64 (i64.const 3)))- )- (func $and-neg1- (drop (i32.and (i32.const 100) (i32.const -1)))- (drop (i32.and (i32.const 100) (i32.const 1)))- )- (func $and-pos1- (drop (i32.and (i32.eqz (i32.const 1000)) (i32.const 1)))- (drop (i32.and (i32.const 1) (i32.eqz (i32.const 1000))))- (drop (i32.and (i32.const 100) (i32.const 1)))- (drop (i32.and (i32.lt_s (i32.const 2000) (i32.const 3000)) (i32.const 1)))- )- (func $canonicalize (param $x i32) (param $y i32) (param $fx f64) (param $fy f64)- (drop (i32.and (unreachable) (i32.const 1))) ;; ok to reorder- (drop (i32.and (i32.const 1) (unreachable)))- (drop (i32.div_s (unreachable) (i32.const 1))) ;; not ok- (drop (i32.div_s (i32.const 1) (unreachable)))- ;; the various orderings- (drop (i32.and (i32.const 1) (i32.const 2)))- (drop (i32.and (local.get $x) (i32.const 3)))- (drop (i32.and (i32.const 4) (local.get $x)))- (drop (i32.and (local.get $x) (local.get $y)))- (drop (i32.and (local.get $y) (local.get $x)))- (drop (i32.and (local.get $y) (local.tee $x (i32.const -4))))- (drop (i32.and- (block (result i32)- (i32.const -5)- )- (local.get $x)- ))- (drop (i32.and- (local.get $x)- (block (result i32)- (i32.const -6)- )- ))- (drop (i32.and- (block (result i32)- (i32.const 5)- )- (loop (result i32)- (i32.const 6)- )- ))- (drop (i32.and- (loop (result i32)- (i32.const 7)- )- (block (result i32)- (i32.const 8)- )- ))- (drop (i32.and- (loop (result i32)- (call $and-pos1)- (i32.const 9)- )- (block (result i32)- (i32.const 10)- )- ))- (drop (i32.and- (loop (result i32)- (i32.const 11)- )- (block (result i32)- (call $and-pos1)- (i32.const 12)- )- ))- (drop (i32.and- (loop (result i32)- (call $and-pos1)- (i32.const 13)- )- (block (result i32)- (call $and-pos1)- (i32.const 14)- )- ))- (drop (i32.and- (block (result i32)- (call $and-pos1)- (i32.const 14)- )- (loop (result i32)- (call $and-pos1)- (i32.const 13)- )- ))- (drop (i32.and- (block (result i32)- (i32.const 15)- )- (local.get $x)- ))- (drop (i32.and- (local.get $x)- (block (result i32)- (i32.const 15)- )- ))- (drop (i32.and- (i32.gt_s- (i32.const 16)- (i32.const 17)- )- (i32.gt_u- (i32.const 18)- (i32.const 19)- )- ))- (drop (i32.and- (i32.gt_u- (i32.const 20)- (i32.const 21)- )- (i32.gt_s- (i32.const 22)- (i32.const 23)- )- ))- (drop (i32.add (i32.ctz (local.get $x)) (i32.ctz (local.get $y))))- (drop (i32.add (i32.ctz (local.get $y)) (i32.ctz (local.get $x))))- (drop (i32.add (i32.ctz (local.get $x)) (i32.eqz (local.get $y))))- (drop (i32.add (i32.eqz (local.get $x)) (i32.ctz (local.get $y))))- )- (func $ne0 (result i32)- (if (i32.ne (call $ne0) (i32.const 0))- (nop)- )- (if (i32.ne (i32.const 0) (call $ne0))- (nop)- )- ;; through an or- (if- (i32.or- (i32.ne (i32.const 0) (call $ne0))- (i32.ne (i32.const 0) (call $ne0))- )- (nop)- )- ;; but not an and- (if- (i32.and- (i32.ne (i32.const 0) (call $ne0))- (i32.ne (i32.const 0) (call $ne0))- )- (nop)- )- (i32.const 1)- )- (func $recurse-bool- (if- (if (result i32)- (i32.const 1)- (i32.ne (call $ne0) (i32.const 0))- (i32.ne (call $ne1) (i32.const 0))- )- (nop)- )- (if- (block (result i32)- (nop)- (i32.ne (call $ne0) (i32.const 0))- )- (nop)- )- )- (func $ne1 (result i32)- (unreachable)- )- (func $load-off-2 "load-off-2" (param $0 i32) (result i32)- (i32.store offset=2- (i32.add- (i32.const 1)- (i32.const 3)- )- (local.get $0)- )- (i32.store offset=2- (i32.add- (i32.const 3)- (i32.const 1)- )- (local.get $0)- )- (i32.store offset=2- (i32.add- (local.get $0)- (i32.const 5)- )- (local.get $0)- )- (i32.store offset=2- (i32.add- (i32.const 7)- (local.get $0)- )- (local.get $0)- )- (i32.store offset=2- (i32.add- (i32.const -11) ;; do not fold this!- (local.get $0)- )- (local.get $0)- )- (i32.store offset=2- (i32.add- (local.get $0)- (i32.const -13) ;; do not fold this!- )- (local.get $0)- )- (i32.store offset=2- (i32.add- (i32.const -15)- (i32.const 17)- )- (local.get $0)- )- (i32.store offset=2- (i32.add- (i32.const -21)- (i32.const 19)- )- (local.get $0)- )- (i32.store offset=2- (i32.const 23)- (local.get $0)- )- (i32.store offset=2- (i32.const -25)- (local.get $0)- )- (drop- (i32.load offset=2- (i32.add- (i32.const 2)- (i32.const 4)- )- )- )- (drop- (i32.load offset=2- (i32.add- (i32.const 4)- (i32.const 2)- )- )- )- (drop- (i32.load offset=2- (i32.add- (local.get $0)- (i32.const 6)- )- )- )- (drop- (i32.load offset=2- (i32.const 8)- )- )- (i32.load offset=2- (i32.add- (i32.const 10)- (local.get $0)- )- )- )- (func $sign-ext (param $0 i32) (param $1 i32)- ;; eq of sign-ext to const, can be a zext- (drop- (i32.eq- (i32.shr_s- (i32.shl- (local.get $0)- (i32.const 24)- )- (i32.const 24)- )- (i32.const 0)- )- )- (drop- (i32.eq- (i32.shr_s- (i32.shl- (local.get $0)- (i32.const 16)- )- (i32.const 16)- )- (i32.const 0)- )- )- (drop- (i32.eq- (i32.shr_s- (i32.shl- (local.get $0)- (i32.const 5) ;; weird size, but still valid- )- (i32.const 5)- )- (i32.const 0)- )- )- (drop- (i32.eq- (i32.shr_s- (i32.shl- (local.get $0)- (i32.const 24)- )- (i32.const 24)- )- (i32.const 100) ;; non-zero- )- )- (drop- (i32.eq- (i32.shr_s- (i32.shl- (local.get $0)- (i32.const 24)- )- (i32.const 24)- )- (i32.const 32767) ;; non-zero and bigger than the mask, with sign bit- )- )- (drop- (i32.eq- (i32.shr_s- (i32.shl- (local.get $0)- (i32.const 24)- )- (i32.const 24)- )- (i32.const -149) ;; non-zero and bigger than the mask, without sign bit- )- )- ;; eq of two sign-ext, can both be a zext- (drop- (i32.eq- (i32.shr_s- (i32.shl- (local.get $0)- (i32.const 24)- )- (i32.const 24)- )- (i32.shr_s- (i32.shl- (local.get $1)- (i32.const 24)- )- (i32.const 24)- )- )- )- (drop- (i32.eq- (i32.shr_s- (i32.shl- (local.get $0)- (i32.const 16)- )- (i32.const 16)- )- (i32.shr_s- (i32.shl- (local.get $1)- (i32.const 16)- )- (i32.const 16)- )- )- )- ;; corner cases we should not opt- (drop- (i32.eq- (i32.shr_s- (i32.shl- (local.get $0)- (i32.const 24)- )- (i32.const 23) ;; different shift, smaller- )- (i32.const 0)- )- )- (drop- (i32.eq- (i32.shr_u ;; unsigned- (i32.shl- (local.get $0)- (i32.const 24)- )- (i32.const 24)- )- (i32.const 0)- )- )- (drop- (i32.lt_s ;; non-eq- (i32.shr_s- (i32.shl- (local.get $0)- (i32.const 24)- )- (i32.const 24)- )- (i32.const 0)- )- )- )- (func $sign-ext-input (param $0 i32) (param $1 i32)- (drop- (i32.shr_s- (i32.shl- (i32.const 100) ;; small!- (i32.const 24)- )- (i32.const 24)- )- )- (drop- (i32.shr_s- (i32.shl- (i32.const 127) ;; just small enough- (i32.const 24)- )- (i32.const 24)- )- )- (drop- (i32.shr_s- (i32.shl- (i32.const 128) ;; just too big- (i32.const 24)- )- (i32.const 24)- )- )- (drop- (i32.shr_s- (i32.shl- (local.get $0) ;; who knows...- (i32.const 24)- )- (i32.const 24)- )- )- (drop- (i32.shr_s- (i32.shl- (unreachable) ;; ignore- (i32.const 24)- )- (i32.const 24)- )- )- (drop- (i32.shr_s- (i32.shl- (i32.div_s ;; this could be optimizable in theory, but currently we don't look into adds etc.- (i32.const 1)- (i32.const 2)- )- (i32.const 24)- )- (i32.const 24)- )- )- (drop- (i32.shr_s- (i32.shl- (i32.and ;; takes the min, here it is ok- (i32.const 127)- (i32.const 128)- )- (i32.const 24)- )- (i32.const 24)- )- )- (drop- (i32.shr_s- (i32.shl- (i32.and ;; takes the min, here it is not- (i32.const 128)- (i32.const 129)- )- (i32.const 24)- )- (i32.const 24)- )- )- (drop- (i32.shr_s- (i32.shl- (i32.xor ;; takes the max, here it is ok- (i32.const 127)- (i32.const 126)- )- (i32.const 24)- )- (i32.const 24)- )- )- (drop- (i32.shr_s- (i32.shl- (i32.xor ;; takes the max, here it is not- (i32.const 127)- (i32.const 128)- )- (i32.const 24)- )- (i32.const 24)- )- )- (drop- (i32.shr_s- (i32.shl- (i32.or ;; takes the max, here it is ok- (i32.const 127)- (i32.const 126)- )- (i32.const 24)- )- (i32.const 24)- )- )- (drop- (i32.shr_s- (i32.shl- (i32.or ;; takes the max, here it is not- (i32.const 127)- (i32.const 128)- )- (i32.const 24)- )- (i32.const 24)- )- )- (drop- (i32.shr_s- (i32.shl- (i32.shl ;; adds, here it is too much- (i32.const 32)- (i32.const 2)- )- (i32.const 24)- )- (i32.const 24)- )- )- (drop- (i32.shr_s- (i32.shl- (i32.shl ;; adds, here it is ok- (i32.const 32)- (i32.const 1)- )- (i32.const 24)- )- (i32.const 24)- )- )- (drop- (i32.shr_s- (i32.shl- (i32.shl ;; adds, here it is too much and "overflows"- (i32.const 32)- (i32.const 35)- )- (i32.const 24)- )- (i32.const 24)- )- )- (drop- (i32.shr_s- (i32.shl- (i32.shr_u ;; subtracts, here it is still too much- (i32.const 256)- (i32.const 1)- )- (i32.const 24)- )- (i32.const 24)- )- )- (drop- (i32.shr_s- (i32.shl- (i32.shr_u ;; subtracts, here it is ok- (i32.const 256)- (i32.const 2)- )- (i32.const 24)- )- (i32.const 24)- )- )- (drop- (i32.shr_s- (i32.shl- (i32.shr_u ;; subtracts, here it "overflows"- (i32.const 128)- (i32.const 35)- )- (i32.const 24)- )- (i32.const 24)- )- )- (drop- (i32.shr_s- (i32.shl- (i32.shr_s ;; subtracts, here it is still too much- (i32.const 256)- (i32.const 1)- )- (i32.const 24)- )- (i32.const 24)- )- )- (drop- (i32.shr_s- (i32.shl- (i32.shr_s ;; subtracts, here it is ok- (i32.const 256)- (i32.const 2)- )- (i32.const 24)- )- (i32.const 24)- )- )- (drop- (i32.shr_s- (i32.shl- (i32.shr_s ;; subtracts, here it "overflows"- (i32.const 128)- (i32.const 35)- )- (i32.const 24)- )- (i32.const 24)- )- )- (drop- (i32.shr_s- (i32.shl- (i32.shr_s ;; subtracts, here there is a sign bit, so it stays 32 bits no matter how much we shift- (i32.const -1)- (i32.const 32)- )- (i32.const 24)- )- (i32.const 24)- )- )- (drop- (i32.shr_s- (i32.shl- (i32.shr_s ;; subtracts, here we mask out that sign bit- (i32.and- (i32.const -1)- (i32.const 2147483647)- )- (i32.const 31) ;; adjusted after we fixed shift computation to just look at lower 5 bits- )- (i32.const 24)- )- (i32.const 24)- )- )- (drop- (i32.shr_s- (i32.shl- (i32.ne ;; 1 bit- (i32.const -1)- (i32.const -1)- )- (i32.const 24)- )- (i32.const 24)- )- )- (drop- (i32.shr_s- (i32.shl- (f32.le- (f32.const -1)- (f32.const -1)- )- (i32.const 24)- )- (i32.const 24)- )- )- (drop- (i32.shr_s- (i32.shl- (i32.clz ;; assumed 5 bits- (i32.const 0)- )- (i32.const 24)- )- (i32.const 24)- )- )- (drop- (i32.shr_s- (i32.shl- (i32.shl- (i32.clz ;; assumed 5 bits- (i32.const 0)- )- (i32.const 2) ;; + 2, so 7- )- (i32.const 24)- )- (i32.const 24)- )- )- (drop- (i32.shr_s- (i32.shl- (i32.shl- (i32.clz ;; assumed 5 bits- (i32.const 0)- )- (i32.const 3) ;; + 3, so 8, too much- )- (i32.const 24)- )- (i32.const 24)- )- )- (drop- (i32.shr_s- (i32.shl- (i32.wrap_i64 ;; preserves 6- (i64.clz ;; assumed 6 bits- (i64.const 0)- )- )- (i32.const 24)- )- (i32.const 24)- )- )- (drop- (i32.shr_s- (i32.shl- (i32.shl- (i32.wrap_i64 ;; preserves 6- (i64.clz ;; assumed 6 bits- (i64.const 0)- )- )- (i32.const 1) ;; + 1, so 7- )- (i32.const 24)- )- (i32.const 24)- )- )- (drop- (i32.shr_s- (i32.shl- (i32.shl- (i32.wrap_i64 ;; preserves 6- (i64.clz ;; assumed 6 bits- (i64.const 0)- )- )- (i32.const 2) ;; + 2, so 8, too much- )- (i32.const 24)- )- (i32.const 24)- )- )- (drop- (i32.shr_s- (i32.shl- (i32.eqz ;; 1 bit- (i32.const -1)- )- (i32.const 24)- )- (i32.const 24)- )- )- (drop- (i32.shr_s- (i32.shl- (i32.shr_u- (i32.wrap_i64 ;; down to 32- (i64.const -1) ;; 64- )- (i32.const 24) ;; 32 - 24 = 8- )- (i32.const 24)- )- (i32.const 24)- )- )- (drop- (i32.shr_s- (i32.shl- (i32.shr_u- (i32.wrap_i64 ;; down to 32- (i64.const -1) ;; 64- )- (i32.const 25) ;; 32 - 25 = 7, ok- )- (i32.const 24)- )- (i32.const 24)- )- )- (drop- (i32.shr_s- (i32.shl- (i32.shr_u- (i32.wrap_i64 ;; stay 32- (i64.extend_i32_s- (i32.const -1)- )- )- (i32.const 24) ;; 32 - 24 = 8- )- (i32.const 24)- )- (i32.const 24)- )- )- (drop- (i32.shr_s- (i32.shl- (i32.shr_u- (i32.wrap_i64 ;; stay 32- (i64.extend_i32_s- (i32.const -1)- )- )- (i32.const 25) ;; 32 - 25 = 7, ok- )- (i32.const 24)- )- (i32.const 24)- )- )- (drop ;; fuzz testcase- (i32.shr_s- (i32.shl- (i32.xor ;; should be 32 bits- (i32.le_u ;; 1 bit- (local.get $0)- (i32.const 2)- )- (local.get $0) ;; unknown, so 32 bits- )- (i32.const 24)- )- (i32.const 24)- )- )- )- (func $linear-sums (param $0 i32) (param $1 i32)- (drop- (i32.add- (i32.add- (local.get $1)- (i32.const 16)- )- (i32.shl- (i32.add- (local.get $0)- (i32.const -1) ;; -16, so cancels out!- )- (i32.const 4)- )- )- )- (drop- (i32.add- (i32.add- (local.get $1)- (i32.const 20)- )- (i32.shl- (i32.add- (local.get $0)- (i32.const -1) ;; -8, so sum is +12- )- (i32.const 3)- )- )- )- (drop- (i32.add ;; simple sum- (i32.const 1)- (i32.const 3)- )- )- (drop- (i32.add ;; nested sum- (i32.add- (i32.const 1)- (i32.const 3)- )- (i32.add- (i32.const 5)- (i32.const 9)- )- )- )- (drop- (i32.add- (i32.add- (i32.const 1)- (i32.const 3)- )- (i32.sub ;; internal sub- (i32.const 5)- (i32.const 3)- )- )- )- (drop- (i32.sub ;; external sub- (i32.add- (i32.const 1)- (i32.const 3)- )- (i32.add- (i32.const 5)- (i32.const 3)- )- )- )- (drop- (i32.sub ;; external sub- (i32.add- (i32.const 1)- (i32.const 3)- )- (i32.sub ;; and also internal sub- (i32.const 5)- (i32.const 3)- )- )- )- (drop- (i32.add- (i32.add- (i32.const 1)- (i32.const 3)- )- (i32.sub ;; negating sub- (i32.const 0)- (i32.const 3)- )- )- )- (drop- (i32.add- (i32.sub- (i32.const 0)- (i32.sub ;; two negating subs- (i32.const 0)- (i32.add- (i32.const 3)- (i32.const 20)- )- )- )- (i32.add- (i32.const 1)- (i32.const 2)- )- )- )- (drop- (i32.add- (i32.add- (i32.const 0)- (i32.sub ;; one negating sub- (i32.const 0)- (i32.add- (i32.const 3)- (i32.const 20)- )- )- )- (i32.add- (i32.const 1)- (i32.const 2)- )- )- )- (drop- (i32.add- (i32.shl ;; shifted value- (i32.const 1)- (i32.const 3)- )- (i32.add- (i32.const 5)- (i32.const 9)- )- )- )- (drop- (i32.add- (i32.shl ;; shifted value- (i32.const 1)- (local.get $0) ;; but not by const- )- (i32.add- (i32.const 5)- (i32.const 9)- )- )- )- (drop- (i32.add- (i32.shl ;; shifted nested value- (i32.sub- (local.get $1)- (i32.const 10)- )- (i32.const 3)- )- (i32.add- (i32.const 5)- (i32.const 9)- )- )- )- (drop- (i32.add- (i32.mul ;; multiplied- (i32.const 10)- (i32.const 3)- )- (i32.add- (i32.const 5)- (i32.const 9)- )- )- )- (drop- (i32.add- (i32.mul ;; multiplied by nonconstant - can't recurse- (i32.const 10)- (local.get $0)- )- (i32.add- (i32.const 5)- (i32.const 9)- )- )- )- (drop- (i32.add- (i32.mul ;; nested mul- (i32.add- (i32.const 10)- (local.get $0)- )- (i32.const 2)- )- (i32.add- (i32.const 5)- (i32.const 9)- )- )- )- (drop- (i32.add- (i32.add- (local.get $0)- (i32.const 10) ;; cancelled out with the below- )- (i32.sub- (i32.const -5)- (i32.const 5)- )- )- )- )- (func $almost-sign-ext (param $0 i32)- (drop- (i32.shr_s- (i32.shl- (i32.const 100) ;; too big, there is a sign bit, due to the extra shift- (i32.const 25)- )- (i32.const 24) ;; different shift, but larger, so ok to opt if we leave a shift, in theory- )- )- (drop- (i32.shr_s- (i32.shl- (i32.const 50) ;; small enough, no sign bit- (i32.const 25)- )- (i32.const 24) ;; different shift, but larger, so ok to opt if we leave a shift- )- )- )- (func $squaring (param $0 i32) (param $1 i32)- (drop- (i32.and- (i32.and- (local.get $0)- (i32.const 11)- )- (i32.const 200)- )- )- (drop- (i32.and- (i32.and- (local.get $0)- (i32.const 11)- )- (local.get $0) ;; non-const, cannot optimize this!- )- )- (drop- (i32.and- (i32.and- (i32.const 11) ;; flipped order- (local.get $0)- )- (i32.const 200)- )- )- (drop- (i32.or- (i32.or- (local.get $0)- (i32.const 11)- )- (i32.const 200)- )- )- (drop- (i32.shl- (i32.shl- (local.get $0)- (i32.const 11)- )- (i32.const 200)- )- )- (drop- (i32.shr_s- (i32.shr_s- (local.get $0)- (i32.const 11)- )- (i32.const 200)- )- )- (drop- (i32.shr_u- (i32.shr_u- (local.get $0)- (i32.const 11)- )- (i32.const 200)- )- )- (drop- (i32.shr_u- (i32.shr_s ;; but do not optimize a mixture or different shifts!- (local.get $0)- (i32.const 11)- )- (i32.const 200)- )- )- )- (func $sign-ext-ne (param $0 i32) (param $1 i32)- ;; ne of sign-ext to const, can be a zext- (drop- (i32.ne- (i32.shr_s- (i32.shl- (local.get $0)- (i32.const 24)- )- (i32.const 24)- )- (i32.const 65000)- )- )- (drop- (i32.ne- (i32.shr_s- (i32.shl- (local.get $0)- (i32.const 24)- )- (i32.const 24)- )- (i32.const 64872) ;; no sign bit- )- )- (drop- (i32.ne- (i32.shr_s- (i32.shl- (local.get $0)- (i32.const 24)- )- (i32.const 24)- )- (i32.const -149) ;; no sign bit, not all ones- )- )- (drop- (i32.ne- (i32.shr_s- (i32.shl- (local.get $0)- (i32.const 24)- )- (i32.const 24)- )- (i32.const 111)- )- )- (drop- (i32.ne- (i32.shr_s- (i32.shl- (local.get $0)- (i32.const 24)- )- (i32.const 24)- )- (i32.shr_s- (i32.shl- (local.get $1)- (i32.const 24)- )- (i32.const 24)- )- )- )- )- (func $sign-ext-eqz (param $0 i32) (param $1 i32)- (drop- (i32.eqz- (i32.shr_s- (i32.shl- (local.get $0)- (i32.const 24)- )- (i32.const 24)- )- )- )- )- (func $sign-ext-boolean (param $0 i32) (param $1 i32)- (drop- (if (result i32)- (i32.shr_s- (i32.shl- (local.get $0)- (i32.const 24)- )- (i32.const 24)- )- (i32.const 100)- (i32.const 200)- )- )- )- (func $add-sub-zero (param $0 i32) (param $1 i32)- (drop- (i32.add- (local.get $0)- (i32.const 0)- )- )- (drop- (i32.sub- (local.get $0)- (i32.const 0)- )- )- )- (func $store-signext (param $0 i32)- (i32.store8- (i32.const 8)- (i32.shr_s- (i32.shl- (local.get $0)- (i32.const 24) ;; exact size we store, sign-ext of 8 bits- )- (i32.const 24)- )- )- (i32.store8- (i32.const 8)- (i32.shr_s- (i32.shl- (local.get $0)- (i32.const 25) ;; 7 bits. so the ext can alter a bit we store, do not optimize- )- (i32.const 25)- )- )- (i32.store8- (i32.const 8)- (i32.shr_s- (i32.shl- (local.get $0)- (i32.const 23) ;; 9 bits, this is good to optimize- )- (i32.const 23)- )- )- (i32.store16- (i32.const 8)- (i32.shr_s- (i32.shl- (local.get $0)- (i32.const 16) ;; exact size we store, sign-ext of 16 bits- )- (i32.const 16)- )- )- (i32.store16- (i32.const 8)- (i32.shr_s- (i32.shl- (local.get $0)- (i32.const 17) ;; 15 bits. so the ext can alter a bit we store, do not optimize- )- (i32.const 17)- )- )- (i32.store16- (i32.const 8)- (i32.shr_s- (i32.shl- (local.get $0)- (i32.const 14) ;; 17 bits, this is good to optimize- )- (i32.const 14)- )- )- (i32.store- (i32.const 8)- (i32.shr_s- (i32.shl- (local.get $0)- (i32.const 16) ;; 4 bytes stored, do nothing- )- (i32.const 16)- )- )- (i32.store- (i32.const 8)- (i32.shr_s- (i32.shl- (local.get $0)- (i32.const 8) ;; 4 bytes stored, do nothing- )- (i32.const 8)- )- )- )- (func $sign-ext-tee (param $0 i32) (param $1 i32)- (drop- (i32.shr_s- (i32.shl- (local.tee $0- (i32.const 128) ;; too big- )- (i32.const 24)- )- (i32.const 24)- )- )- (drop- (i32.shr_s- (i32.shl- (local.tee $0- (i32.const 127) ;; just right- )- (i32.const 24)- )- (i32.const 24)- )- )- )- (func $sign-ext-load (param $0 i32) (param $1 i32)- (drop- (i32.shr_s- (i32.shl- (i32.load8_s ;; one byte, so perfect- (i32.const 256)- )- (i32.const 24)- )- (i32.const 24)- )- )- (drop- (i32.shr_s- (i32.shl- (i32.shr_u- (i32.load8_s ;; one byte, but sexted to 32- (i32.const 256)- )- (i32.const 1)- )- (i32.const 24)- )- (i32.const 24)- )- )- (drop- (i32.shr_s- (i32.shl- (i32.shr_u- (i32.load8_u ;; one byte, but reduced to 7- (i32.const 256)- )- (i32.const 1)- )- (i32.const 24)- )- (i32.const 24)- )- )- (drop- (i32.shr_s- (i32.shl- (i32.load16_s ;; two, so perfect- (i32.const 256)- )- (i32.const 16)- )- (i32.const 16)- )- )- ;; through tees, we cannot alter the load sign- (drop- (i32.shr_s- (i32.shl- (local.tee $1- (i32.load8_s- (i32.const 1)- )- )- (i32.const 24)- )- (i32.const 24)- )- )- (drop- (i32.shr_s- (i32.shl- (local.tee $1- (i32.load8_u- (i32.const 1)- )- )- (i32.const 24)- )- (i32.const 24)- )- )- (drop- (i32.and- (local.tee $1- (i32.load8_s- (i32.const 1)- )- )- (i32.const 255)- )- )- (drop- (i32.and- (local.tee $1- (i32.load8_u- (i32.const 1)- )- )- (i32.const 255)- )- )- )- (func $mask-bits (param $0 i32) (param $1 i32)- (drop- (i32.and- (local.tee $0- (i32.const 127) ;; 7 bits- )- (i32.const 255) ;; mask 8, so we don't need this- )- )- (drop- (i32.and- (local.tee $0- (i32.const 128) ;; 8 bits- )- (i32.const 255) ;; mask 8, so we don't need this- )- )- (drop- (i32.and- (local.tee $0- (i32.const 128)- )- (i32.const 254) ;; improper mask, small- )- )- (drop- (i32.and- (local.tee $0- (i32.const 128)- )- (i32.const 1279) ;; improper mask, large- )- )- (drop- (i32.and- (local.tee $0- (i32.const 128)- )- (i32.const 1290) ;; improper mask, large- )- )- (drop- (i32.and- (local.tee $0- (i32.const 128)- )- (i32.const 4095) ;; proper mask, huge- )- )- (drop- (i32.and- (local.tee $0- (i32.const 128)- )- (i32.const 511) ;; proper mask, large- )- )- (drop- (i32.and- (local.tee $0- (i32.const 128)- )- (i32.const 127) ;; proper mask, just too small- )- )- )- (func $local-info-zero-ext (param $0 i32) (param $1 i32)- (local $x i32)- (local $y i32)- (local $z i32)- (local $w i32)- (local.set $x- (i32.const 212) ;; mask is unneeded, we are small- )- (drop- (i32.and- (local.get $x)- (i32.const 255)- )- )- (local.set $y- (i32.const 500) ;; mask is needed, we are too big- )- (drop- (i32.and- (local.get $y)- (i32.const 255)- )- )- (local.set $0- (i32.const 212) ;; mask is unneeded, but we are a param, not a var, so no- )- (drop- (i32.and- (local.get $0)- (i32.const 255)- )- )- (local.set $z- (i32.const 212) ;; mask is unneeded, we are small- )- (local.set $z- (i32.const 220) ;; mask is still unneeded even with 2 uses- )- (drop- (i32.and- (local.get $z)- (i32.const 255)- )- )- (local.set $w- (i32.const 212) ;; mask is unneeded, we are small- )- (local.set $w- (i32.const 1000) ;; mask is needed, one use is too big- )- (drop- (i32.and- (local.get $w)- (i32.const 255)- )- )- )- (func $local-info-sign-ext-bitsize (param $0 i32) (param $1 i32)- (local $x i32)- (local $y i32)- (local $z i32)- (local $w i32)- (local.set $x- (i32.const 127) ;; mask is unneeded, we are small- )- (drop- (i32.shr_s- (i32.shl- (local.get $x)- (i32.const 24)- )- (i32.const 24)- )- )- (local.set $y- (i32.const 128) ;; mask is needed, we are too big- )- (drop- (i32.shr_s- (i32.shl- (local.get $y)- (i32.const 24)- )- (i32.const 24)- )- )- (local.set $0- (i32.const 127) ;; mask is unneeded, but we are a param, not a var, so no- )- (drop- (i32.shr_s- (i32.shl- (local.get $0)- (i32.const 24)- )- (i32.const 24)- )- )- (local.set $z- (i32.const 127) ;; mask is unneeded, we are small- )- (local.set $z- (i32.const 100) ;; mask is still unneeded even with 2 uses- )- (drop- (i32.shr_s- (i32.shl- (local.get $z)- (i32.const 24)- )- (i32.const 24)- )- )- (local.set $w- (i32.const 127) ;; mask is unneeded, we are small- )- (local.set $w- (i32.const 150) ;; mask is needed, one use is too big- )- (drop- (i32.shr_s- (i32.shl- (local.get $w)- (i32.const 24)- )- (i32.const 24)- )- )- )- (func $local-info-sign-ext-already-exted (param $0 i32) (param $1 i32)- (local $x i32)- (local $y i32)- (local $z i32)- (local $w i32)- (local.set $x- (i32.shr_s- (i32.shl- (local.get $0) ;; already sign-exted here, so no need later- (i32.const 24)- )- (i32.const 24)- )- )- (drop- (i32.shr_s- (i32.shl- (local.get $x)- (i32.const 24)- )- (i32.const 24)- )- )- (local.set $y- (i32.shr_s- (i32.shl- (local.get $0) ;; already sign-exted here, but wrong bit size- (i32.const 16)- )- (i32.const 16)- )- )- (drop- (i32.shr_s- (i32.shl- (local.get $y)- (i32.const 24)- )- (i32.const 24)- )- )- (local.set $0- (i32.shr_s- (i32.shl- (local.get $0) ;; already sign-exted here, so no need later, but we are a param- (i32.const 24)- )- (i32.const 24)- )- )- (drop- (i32.shr_s- (i32.shl- (local.get $0)- (i32.const 24)- )- (i32.const 24)- )- )- (local.set $z- (i32.shr_s- (i32.shl- (local.get $0) ;; already sign-exted here, so no need later- (i32.const 24)- )- (i32.const 24)- )- )- (local.set $z- (i32.shr_s- (i32.shl- (local.get $1) ;; already sign-exted here, so no need later- (i32.const 24)- )- (i32.const 24)- )- )- (drop- (i32.shr_s- (i32.shl- (local.get $z)- (i32.const 24)- )- (i32.const 24)- )- )- (local.set $w- (i32.shr_s- (i32.shl- (local.get $0) ;; already sign-exted here, so no need later- (i32.const 24)- )- (i32.const 24)- )- )- (local.set $w- (i32.shr_s- (i32.shl- (local.get $0) ;; not quite a sign-ext- (i32.const 23)- )- (i32.const 24)- )- )- (drop- (i32.shr_s- (i32.shl- (local.get $w)- (i32.const 24)- )- (i32.const 24)- )- )- (drop ;; odd corner case- (i32.shr_s- (i32.shl- (local.get $0) ;; param, so we should know nothing- (i32.const 24)- )- (i32.const 23) ;; different shift, smaller- )- )- )- (func $signed-loads-fill-the-bits (param $$e i32) (result i32)- (local $$0 i32)- (local $$conv i32)- (local.set $$0- (i32.load8_s ;; one byte, but 32 bits due to sign-extend- (i32.const 1024)- )- )- (local.set $$conv- (i32.and- (local.get $$0)- (i32.const 255) ;; so we need this zexting!- )- )- (return- (i32.eq- (local.get $$conv)- (local.get $$e)- )- )- )- (func $local-info-sign-ext-already-exted-by-load (param $0 i32) (param $1 i32)- (local $x i32)- (local $y i32)- (local $z i32)- (local $w i32)- (local.set $x- (i32.load8_s (i32.const 1024)) ;; 8 bits, sign extended, no need to do it again- )- (drop- (i32.shr_s- (i32.shl- (local.get $x)- (i32.const 24)- )- (i32.const 24)- )- )- (local.set $y- (i32.load8_u (i32.const 1024)) ;; 8 bits, zext, so bad- )- (drop- (i32.shr_s- (i32.shl- (local.get $y)- (i32.const 24)- )- (i32.const 24)- )- )- (local.set $z- (i32.load16_s (i32.const 1024)) ;; 16 bits sign-extended, wrong size- )- (drop- (i32.shr_s- (i32.shl- (local.get $z)- (i32.const 24)- )- (i32.const 24)- )- )- )- (func $compare-load-s-sign-extend (param $0 i32) (param $1 i32)- (drop- (i32.eq- (i32.load8_s- (local.get $0)- )- (i32.shr_s- (i32.shl- (local.get $1)- (i32.const 24)- )- (i32.const 24)- )- )- )- (drop- (i32.eq- (i32.shr_s- (i32.shl- (local.get $1)- (i32.const 24)- )- (i32.const 24)- )- (i32.load8_s- (local.get $0) ;; flip order, we should canonicalize- )- )- )- (drop- (i32.eq- (i32.load8_u ;; unsigned, bad- (local.get $0)- )- (i32.shr_s- (i32.shl- (local.get $1)- (i32.const 24)- )- (i32.const 24)- )- )- )- (drop- (i32.eq- (i32.load8_s- (local.get $0)- )- (i32.shr_s- (i32.shl- (local.get $1)- (i32.const 16) ;; wrong size- )- (i32.const 16)- )- )- )- (drop- (i32.eq- (i32.shr_s- (i32.shl- (local.get $1)- (i32.const 24)- )- (i32.const 24)- )- (i32.load8_u ;; unsigned, bad- (local.get $0)- )- )- )- (drop- (i32.eq- (i32.shr_s- (i32.shl- (local.get $1)- (i32.const 16) ;; wrong size- )- (i32.const 16)- )- (i32.load8_s- (local.get $0)- )- )- )- )- (func $unsign-diff-sizes (param $x i32) (param $y i32) (result i32)- (i32.ne- (i32.shr_s- (i32.shl- (call $unsign-diff-sizes- (i32.const -1)- (i32.const 5)- )- (i32.const 24)- )- (i32.const 24)- )- (i32.shr_s- (i32.shl- (call $unsign-diff-sizes- (i32.const 1)- (i32.const 2006)- )- (i32.const 16)- )- (i32.const 16)- )- )- )- (func $unsign-same-sizes (param $x i32) (param $y i32) (result i32)- (i32.ne- (i32.shr_s- (i32.shl- (call $unsign-same-sizes- (i32.const -1)- (i32.const 5)- )- (i32.const 24)- )- (i32.const 24)- )- (i32.shr_s- (i32.shl- (call $unsign-same-sizes- (i32.const 1)- (i32.const 2006)- )- (i32.const 24)- )- (i32.const 24)- )- )- )- (func $fuzz-almost-sign-ext- (drop- (i32.shr_s- (i32.shl- (i32.load16_u- (i32.const 2278)- )- (i32.const 17)- )- (i32.const 16)- )- )- (drop- (i32.shr_s- (i32.shl- (i32.shl- (i32.load16_u- (i32.const 2278)- )- (i32.const 1)- )- (i32.const 16)- )- (i32.const 16)- )- )- )- (func $fuzz-comp-impossible (param $x i32)- (drop- (i32.eq- (i32.shr_s- (i32.shl- (local.get $x)- (i32.const 16)- )- (i32.const 16)- )- (i32.const 65535) ;; impossible to be equal, the effective sign bit is set, but not the higher bits, which the sign-ext will set on the non-const value- )- )- (drop- (i32.eq- (i32.shr_s- (i32.shl- (local.get $x)- (i32.const 24)- )- (i32.const 24)- )- (i32.const 255)- )- )- (drop- (i32.eq- (i32.shr_s- (i32.shl- (local.get $x)- (i32.const 24)- )- (i32.const 24)- )- (i32.const 127) ;; safe- )- )- (drop- (i32.eq- (i32.shr_s- (i32.shl- (local.get $x)- (i32.const 24)- )- (i32.const 24)- )- (i32.const 128) ;; unsafe again- )- )- (drop- (i32.eq- (i32.shr_s- (i32.shl- (local.get $x)- (i32.const 24)- )- (i32.const 24)- )- (i32.const 4223) ;; more big bits, so sign bit though- )- )- (drop- (i32.eq- (i32.shr_s- (i32.shl- (local.get $x)- (i32.const 24)- )- (i32.const 24)- )- (i32.const 4224) ;; more big bits- )- )- (drop- (i32.eq- (i32.shr_s- (i32.shl- (local.get $x)- (i32.const 24)- )- (i32.const 24)- )- (i32.const -4) ;; safe even with more big bits, as they are all 1s- )- )- )- (func $if-parallel (param $0 i32) (param $1 i32)- (drop- (if (result i32)- (local.get $0)- (i32.add (local.get $1) (i32.const 1))- (i32.add (local.get $1) (i32.const 1))- )- )- (drop- (if (result i32)- (local.tee $0 (local.get $1)) ;; side effects!- (i32.add (local.get $1) (i32.const 1))- (i32.add (local.get $1) (i32.const 1))- )- )- (drop- (if (result i32)- (local.get $0)- (i32.add (local.get $1) (unreachable)) ;; folding them would change the type of the if- (i32.add (local.get $1) (unreachable))- )- )- (drop- (if (result i32)- (local.tee $0 (local.get $1)) ;; side effects!- (i32.add (local.get $1) (unreachable)) ;; folding them would change the type of the if- (i32.add (local.get $1) (unreachable))- )- )- (drop- (if (result i32)- (unreachable) ;; !!!- (i32.add (local.get $1) (unreachable)) ;; folding them would change the type of the if- (i32.add (local.get $1) (unreachable))- )- )- )- (func $select-parallel (param $0 i32) (param $1 i32)- (drop- (select- (i32.add (local.get $1) (i32.const 1))- (i32.add (local.get $1) (i32.const 1))- (local.get $0)- )- )- (drop- (select- (local.tee $0 (local.get $1)) ;; side effects!- (local.tee $0 (local.get $1)) ;; side effects!- (local.get $0)- )- )- (drop- (select- (i32.add (local.get $1) (i32.const 1))- (i32.add (local.get $1) (i32.const 1))- (local.tee $0 (local.get $1)) ;; side effects! (but no interference with values)- )- )- (drop- (select- (local.tee $0 (local.get $1)) ;; side effects! interference!- (local.tee $0 (local.get $1)) ;; side effects! interference!- (local.tee $0 (local.get $1)) ;; side effects! interference!- )- )- (drop- (select- (local.tee $0 (local.get $1)) ;; side effects!- (local.tee $0 (local.get $1)) ;; side effects!- (unreachable) ;; side effects! (but no interference with values)- )- )- )- (func $zero-shifts-is-not-sign-ext- (drop- (i32.eq- (i32.const -5431187)- (i32.add- (i32.const 0)- (i32.shr_s- (i32.shl- (i32.load16_s align=1- (i32.const 790656516)- )- (i32.const 0)- )- (i32.const 0)- )- )- )- )- (drop- (i32.eq- (i32.const -5431187)- (i32.add- (i32.const 0)- (i32.shr_s- (i32.shl- (i32.load16_s align=1- (i32.const 790656516)- )- (i32.const 1)- )- (i32.const 0)- )- )- )- )- )- (func $zero-ops (result i32)- (return- (i32.eq- (i32.const -1337)- (i32.shr_u- (i32.add- (i32.const 0)- (i32.shr_s- (i32.shl- (i32.load16_s align=1- (i32.const 790656516)- )- (i32.const 0)- )- (i32.const 0)- )- )- (i32.const 0)- )- )- )- )- (func $sign-ext-1-and-ne (result i32)- (select- (i32.ne- (i32.const 1333788672)- (i32.shr_s- (i32.shl- (call $sign-ext-1-and-ne)- (i32.const 1)- )- (i32.const 1)- )- )- (i32.const 2)- (i32.const 1)- )- )- (func $neg-shifts-and-255 (result i32)- (i32.and- (i32.shr_u- (i32.const -99)- (i32.const -32) ;; this shift does nothing- )- (i32.const 255)- )- )- (func $neg-shifts-and-255-b (result i32)- (i32.and- (i32.shl- (i32.const -2349025)- (i32.const -32) ;; this shift does nothing- )- (i32.const 255)- )- )- (func $shifts-square-overflow (param $x i32) (result i32)- (i32.shr_u- (i32.shr_u- (local.get $x)- (i32.const 65535) ;; 31 bits effectively- )- (i32.const 32767) ;; also 31 bits, so two shifts that force the value into nothing for sure- )- )- (func $shifts-square-no-overflow-small (param $x i32) (result i32)- (i32.shr_u- (i32.shr_u- (local.get $x)- (i32.const 1031) ;; 7 bits effectively- )- (i32.const 4098) ;; 2 bits effectively- )- )- (func $shifts-square-overflow-64 (param $x i64) (result i64)- (i64.shr_u- (i64.shr_u- (local.get $x)- (i64.const 65535) ;; 63 bits effectively- )- (i64.const 64767) ;; also 63 bits, so two shifts that force the value into nothing for sure- )- )- (func $shifts-square-no-overflow-small-64 (param $x i64) (result i64)- (i64.shr_u- (i64.shr_u- (local.get $x)- (i64.const 1031) ;; 7 bits effectively- )- (i64.const 4098) ;; 2 bits effectively- )- )- (func $shifts-square-unreachable (param $x i32) (result i32)- (i32.shr_u- (i32.shr_u- (unreachable)- (i32.const 1031) ;; 7 bits effectively- )- (i32.const 4098) ;; 2 bits effectively- )- )- (func $mix-shifts (result i32)- (i32.shr_s- (i32.shl- (i32.const 23)- (i32.const -61)- )- (i32.const 168)- )- )- (func $actually-no-shifts (result i32)- (i32.add- (i32.shl- (i32.const 23)- (i32.const 32) ;; really 0- )- (i32.const 10)- )- )- (func $less-shifts-than-it-seems (param $x i32) (result i32)- (i32.add- (i32.shl- (i32.const 200)- (i32.const 36) ;; really 4- )- (i32.shl- (i32.const 100)- (i32.const 4)- )- )- )- (func $and-popcount32 (result i32)- (i32.and- (i32.popcnt- (i32.const -1)- )- (i32.const 31)- )- )- (func $and-popcount32-big (result i32)- (i32.and- (i32.popcnt- (i32.const -1)- )- (i32.const 63)- )- )- (func $and-popcount64 (result i64) ;; these are TODOs- (i64.and- (i64.popcnt- (i64.const -1)- )- (i64.const 63)- )- )- (func $and-popcount64-big (result i64)- (i64.and- (i64.popcnt- (i64.const -1)- )- (i64.const 127)- )- )- (func $and-popcount64-bigger (result i64)- (i64.and- (i64.popcnt- (i64.const -1)- )- (i64.const 255)- )- )- (func $optimizeAddedConstants-filters-through-nonzero (result i32)- (i32.sub- (i32.add- (i32.shl- (i32.const -536870912)- (i32.wrap_i64- (i64.const 0)- )- )- (i32.const -32768)- )- (i32.const -1024)- )- )- (func $optimizeAddedConstants-filters-through-nonzero-b (result i32)- (i32.sub- (i32.add- (i32.shl- (i32.const -536870912)- (i32.wrap_i64- (i64.const -1)- )- )- (i32.const -32768)- )- (i32.const -1024)- )- )- (func $return-proper-value-from-shift-left-by-zero (result i32)- (if (result i32)- (i32.sub- (i32.add- (loop $label$0 (result i32)- (block $label$1- (br_if $label$1- (i32.shl- (i32.load- (i32.const 0)- )- (i32.const -31904) ;; really 0 shifts- )- )- )- (i32.const -62)- )- (i32.const 38)- )- (i32.const -2)- )- (i32.const 1)- (i32.const 0)- )- )- (func $de-morgan-2 (param $x i32) (param $y i32)- (drop- (i32.and (i32.eqz (local.get $x)) (i32.eqz (local.get $y)))- )- (drop- (i32.or (i32.eqz (local.get $x)) (i32.eqz (local.get $y)))- )- (drop- (i32.xor (i32.eqz (local.get $x)) (i32.eqz (local.get $y)))- )- (drop- (i32.and (i32.eqz (local.get $x)) (local.get $y))- )- (drop- (i32.and (local.get $x) (i32.eqz (local.get $y)))- )- (drop- (i32.and (i32.eqz (local.get $x)) (i32.wrap_i64 (i64.const 2)))- )- (drop- (i32.and (i32.wrap_i64 (i64.const 1)) (i32.eqz (local.get $y)))- )- )- (func $subzero1 (param $0 i32) (result i32)- (i32.add- (i32.sub- (i32.const 1)- (i32.clz- (local.get $0)- )- )- (i32.const 31)- )- )- (func $subzero2 (param $0 i32) (result i32)- (i32.add- (i32.const 31)- (i32.sub- (i32.const 1)- (i32.clz- (local.get $0)- )- )- )- )- (func $subzero3 (param $0 i32) (param $1 i32) (result i32)- (i32.add- (i32.sub- (i32.const 0)- (i32.clz- (local.get $0)- )- )- (local.get $1)- )- )- (func $subzero4 (param $0 i32) (param $1 i32) (result i32)- (i32.add- (local.get $0)- (i32.sub- (i32.const 0)- (i32.clz- (local.get $1)- )- )- )- )- (func $mul-32-power-2 (param $x i32) (result i32)- (drop- (call $mul-32-power-2- (i32.mul- (local.get $x)- (i32.const 4)- )- )- )- (drop- (call $mul-32-power-2- (i32.mul- (local.get $x)- (i32.const 5)- )- )- )- (drop- (call $mul-32-power-2- (i32.mul- (local.get $x)- (i32.const 1)- )- )- )- (drop- (call $mul-32-power-2- (i32.mul- (local.get $x)- (i32.const 0)- )- )- )- (drop- (call $mul-32-power-2- (i32.mul- (call $mul-32-power-2 (i32.const 123)) ;; side effects- (i32.const 0)- )- )- )- (drop- (call $mul-32-power-2- (i32.mul- (local.get $x)- (i32.const 0xffffffff)- )- )- )- (drop- (call $mul-32-power-2- (i32.mul- (local.get $x)- (i32.const 0x80000000)- )- )- )- (unreachable)- )- (func $mul-64-power-2 (param $x i64) (result i64)- (drop- (call $mul-64-power-2- (i64.mul- (local.get $x)- (i64.const 4)- )- )- )- (drop- (call $mul-64-power-2- (i64.mul- (local.get $x)- (i64.const 5)- )- )- )- (drop- (call $mul-64-power-2- (i64.mul- (local.get $x)- (i64.const 1)- )- )- )- (drop- (call $mul-64-power-2- (i64.mul- (local.get $x)- (i64.const 0)- )- )- )- (drop- (call $mul-64-power-2- (i64.mul- (call $mul-64-power-2 (i64.const 123)) ;; side effects- (i64.const 0)- )- )- )- (drop- (call $mul-64-power-2- (i64.mul- (local.get $x)- (i64.const 0xffffffffffffffff)- )- )- )- (drop- (call $mul-64-power-2- (i64.mul- (local.get $x)- (i64.const 0x8000000000000000)- )- )- )- (unreachable)- )- (func $div-32-power-2 (param $x i32) (result i32)- (drop- (call $div-32-power-2- (i32.div_u- (local.get $x)- (i32.const 4)- )- )- )- (drop- (call $div-32-power-2- (i32.div_u- (local.get $x)- (i32.const 5)- )- )- )- (drop- (call $div-32-power-2- (i32.div_u- (local.get $x)- (i32.const 1)- )- )- )- (drop- (call $div-32-power-2- (i32.div_u- (local.get $x)- (i32.const 0)- )- )- )- (drop- (call $div-32-power-2- (i32.div_u- (call $div-32-power-2 (i32.const 123)) ;; side effects- (i32.const 0)- )- )- )- (drop- (call $div-32-power-2- (i32.div_u- (local.get $x)- (i32.const 0xffffffff)- )- )- )- (drop- (call $div-32-power-2- (i32.div_u- (local.get $x)- (i32.const 0x80000000)- )- )- )- (unreachable)- )- (func $urem-32-power-2 (param $x i32) (result i32)- (drop- (call $urem-32-power-2- (i32.rem_u- (local.get $x)- (i32.const 4)- )- )- )- (drop- (call $urem-32-power-2- (i32.rem_u- (local.get $x)- (i32.const 5)- )- )- )- (drop- (call $urem-32-power-2- (i32.rem_u- (local.get $x)- (i32.const 1)- )- )- )- (drop- (call $urem-32-power-2- (i32.rem_u- (local.get $x)- (i32.const 0)- )- )- )- (drop- (call $urem-32-power-2- (i32.rem_u- (local.get $x)- (i32.const 0xffffffff)- )- )- )- (drop- (call $urem-32-power-2- (i32.rem_u- (local.get $x)- (i32.const 0x80000000)- )- )- )- ;; (unsigned)x % 1- (drop- (call $urem-32-power-2- (i32.rem_u- (local.get $x)- (i32.const 1)- )- )- )- (unreachable)- )- (func $srem-by-const (param $x i32) (param $y i64)- ;; (signed)x % 1- (drop (i32.rem_s- (local.get $x)- (i32.const 1)- ))- (drop (i64.rem_s- (local.get $y)- (i64.const 1)- ))- ;; (signed)x % 0x80000000 -> x & 0x7FFFFFFF- (drop (i32.rem_s- (local.get $x)- (i32.const 0x80000000)- ))- ;; (signed)x % 0x8000000000000000 -> x & 0x7FFFFFFFFFFFFFFF- (drop (i64.rem_s- (local.get $y)- (i64.const 0x8000000000000000)- ))- )- (func $srem-by-pot-eq-ne-zero (param $x i32) (param $y i64)- ;; eqz((signed)x % 4)- (drop (i32.eqz- (i32.rem_s- (local.get $x)- (i32.const 4)- )- ))- (drop (i64.eqz- (i64.rem_s- (local.get $y)- (i64.const 4)- )- ))- ;; eqz((signed)x % -4)- (drop (i32.eqz- (i32.rem_s- (local.get $x)- (i32.const -4)- )- ))- (drop (i64.eqz- (i64.rem_s- (local.get $y)- (i64.const -4)- )- ))- ;; (signed)x % 4 == 0- (drop (i32.eq- (i32.rem_s- (local.get $x)- (i32.const 4)- )- (i32.const 0)- ))- (drop (i64.eq- (i64.rem_s- (local.get $y)- (i64.const 2)- )- (i64.const 0)- ))- ;; (signed)x % -4 == 0- (drop (i32.eq- (i32.rem_s- (local.get $x)- (i32.const -4)- )- (i32.const 0)- ))- (drop (i64.eq- (i64.rem_s- (local.get $y)- (i64.const -4)- )- (i64.const 0)- ))- ;; (signed)x % 2 != 0- (drop (i32.ne- (i32.rem_s- (local.get $x)- (i32.const 2)- )- (i32.const 0)- ))- (drop (i64.ne- (i64.rem_s- (local.get $y)- (i64.const 2)- )- (i64.const 0)- ))- ;; (signed)x % -1 == 0 -> 0 == 0- (drop (i32.eq- (i32.rem_s- (local.get $x)- (i32.const -1)- )- (i32.const 0)- ))- ;; (signed)x % 0x80000000 == 0- (drop (i32.eq- (i32.rem_s- (local.get $x)- (i32.const 0x80000000)- )- (i32.const 0)- ))- ;; (signed)x % 0x80000000 != 0- (drop (i32.ne- (i32.rem_s- (local.get $x)- (i32.const 0x80000000)- )- (i32.const 0)- ))- ;; (signed)x % 0x8000000000000000 == 0- (drop (i64.eq- (i64.rem_s- (local.get $y)- (i64.const 0x8000000000000000)- )- (i64.const 0)- ))- ;; (signed)x % 0x8000000000000000 != 0- (drop (i64.ne- (i64.rem_s- (local.get $y)- (i64.const 0x8000000000000000)- )- (i64.const 0)- ))- ;;- (drop (i32.eq- (i32.rem_s- (local.get $x)- (i32.const 3) ;; skip- )- (i32.const 0)- ))- (drop (i64.eq- (i64.rem_s- (local.get $y)- (i64.const 3) ;; skip- )- (i64.const 0)- ))- )- (func $orZero (param $0 i32) (result i32)- (i32.or- (local.get $0)- (i32.const 0)- )- )- (func $andZero (param $0 i32) (result i32)- (drop- (i32.and- (local.get $0)- (i32.const 0)- )- )- (drop- (i32.and- (call $andZero (i32.const 1234)) ;; side effects- (i32.const 0)- )- )- (unreachable)- )- (func $abstract-additions (param $x32 i32) (param $x64 i64) (param $y32 f32) (param $y64 f64)- (drop- (i32.or- (i32.const 0)- (local.get $x32)- )- )- (drop- (i32.shl- (local.get $x32)- (i32.const 0)- )- )- (drop- (i32.shr_u- (local.get $x32)- (i32.const 0)- )- )- (drop- (i32.shr_s- (local.get $x32)- (i32.const 0)- )- )- (drop- (i64.or- (i64.const 0)- (local.get $x64)- )- )- (drop- (i64.shl- (local.get $x64)- (i64.const 0)- )- )- (drop- (i64.shr_u- (local.get $x64)- (i64.const 0)- )- )- (drop- (i64.shr_s- (local.get $x64)- (i64.const 0)- )- )- (drop- (i32.mul- (local.get $x32)- (i32.const 0)- )- )- (drop- (i64.mul- (local.get $x64)- (i64.const 0)- )- )- (drop- (f32.mul- (local.get $y32)- (f32.const 0)- )- )- (drop- (f64.mul- (local.get $y64)- (f64.const 0)- )- )- (drop- (i32.mul- (local.get $x32)- (i32.const 1)- )- )- (drop- (i64.mul- (local.get $x64)- (i64.const 1)- )- )- (drop- (f32.mul- (local.get $y32)- (f32.const 1)- )- )- (drop- (f64.mul- (local.get $y64)- (f64.const 1)- )- )- (drop- (i32.and- (local.get $x32)- (i32.const 0)- )- )- (drop- (i64.and- (local.get $x64)- (i64.const 0)- )- )- (drop- (i32.and- (unreachable)- (i32.const 0)- )- )- (drop- (i64.and- (unreachable)- (i64.const 0)- )- )- (drop- (i32.div_s- (local.get $x32)- (i32.const 1)- )- )- (drop- (i32.div_u- (local.get $x32)- (i32.const 1)- )- )- (drop- (i64.div_s- (local.get $x64)- (i64.const 1)- )- )- (drop- (i64.div_u- (local.get $x64)- (i64.const 1)- )- )- (drop- (f32.div- (local.get $y32)- (f32.const 1)- )- )- (drop- (f64.div- (local.get $y64)- (f64.const 1)- )- )- (drop- (f32.div- (local.get $y32)- (f32.const 1.2)- )- )- (drop- (i32.mul- (local.get $x32)- (i32.const -1)- )- )- (drop- (i64.mul- (local.get $x64)- (i64.const -1)- )- )- (drop- (f32.mul- (local.get $y32)- (f32.const -1)- )- )- (drop- (f64.mul- (local.get $y64)- (f64.const -1)- )- )- (drop- (i32.eq- (i32.add- (local.get $x32)- (i32.const 10)- )- (i32.const 20)- )- )- (drop- (i32.le_u- (i32.add- (local.get $x32)- (i32.const 10)- )- (i32.const 20)- )- )- (drop- (i32.eq- (i32.sub- (local.get $x32)- (i32.const 10)- )- (i32.const 20)- )- )- (drop- (i64.eq- (i64.add- (local.get $x64)- (i64.const 10)- )- (i64.const 20)- )- )- (drop- (i32.eq- (i32.const 20)- (i32.add- (local.get $x32)- (i32.const 10)- )- )- )- (drop- (i32.eq- (i32.add- (local.get $x32)- (i32.const 10)- )- (i32.add- (local.get $x32)- (i32.const 20)- )- )- )- (drop- (i32.eq- (i32.sub- (local.get $x32)- (i32.const 10)- )- (i32.const 20)- )- )- (drop- (i32.eq- (i32.add- (local.get $x32)- (i32.const 10)- )- (i32.sub- (local.get $x32)- (i32.const 20)- )- )- )- (drop- (i32.eq- (i32.sub- (local.get $x32)- (i32.const 10)- )- (i32.add- (local.get $x32)- (i32.const 20)- )- )- )- (drop- (i32.eq- (i32.sub- (local.get $x32)- (i32.const 10)- )- (i32.sub- (local.get $x32)- (i32.const 20)- )- )- )- (drop- (i64.le_s- (i64.sub- (local.get $x64)- (i64.const 288230376151711744)- )- (i64.const 9223372036854775807)- )- )- )- (func $negatives-are-sometimes-better (param $x i32) (param $y i64) (param $z f32)- (drop (i32.add (local.get $x) (i32.const 0x40)))- (drop (i32.sub (local.get $x) (i32.const 0x40)))- (drop (i32.add (local.get $x) (i32.const 0x2000)))- (drop (i32.add (local.get $x) (i32.const 0x100000)))- (drop (i32.add (local.get $x) (i32.const 0x8000000)))-- (drop (i64.add (local.get $y) (i64.const 0x40)))- (drop (i64.sub (local.get $y) (i64.const 0x40)))- (drop (i64.add (local.get $y) (i64.const 0x2000)))- (drop (i64.add (local.get $y) (i64.const 0x100000)))- (drop (i64.add (local.get $y) (i64.const 0x8000000)))-- (drop (i64.add (local.get $y) (i64.const 0x400000000)))- (drop (i64.add (local.get $y) (i64.const 0x20000000000)))- (drop (i64.add (local.get $y) (i64.const 0x1000000000000)))- (drop (i64.add (local.get $y) (i64.const 0x80000000000000)))- (drop (i64.add (local.get $y) (i64.const 0x4000000000000000)))-- (drop (f32.add (local.get $z) (f32.const 0x40)))- )- (func $shift-a-zero (param $x i32) (param $y i64) (param $z f32)- (drop- (i32.shl- (i32.const 0)- (local.get $x)- )- )- (drop- (i32.shr_u- (i32.const 0)- (local.get $x)- )- )- (drop- (i32.shr_s- (i32.const 0)- (local.get $x)- )- )- (drop- (i64.shl- (i64.const 0)- (local.get $y)- )- )- (drop- (i32.shl- (i32.const 0)- (unreachable)- )- )- )- (func $identical-siblings (param $x i32) (param $y i64) (param $z f64) (param $xx i32)- (drop- (i32.sub- (local.get $x)- (local.get $x)- )- )- (drop- (i64.sub- (local.get $y)- (local.get $y)- )- )- (drop- (f64.sub- (local.get $z)- (local.get $z)- )- )- (drop- (i32.sub- (local.get $x)- (local.get $xx)- )- )- (drop- (i32.sub- (unreachable)- (unreachable)- )- )- (drop- (i32.add- (local.get $x)- (local.get $x)- )- )- ;; more ops- (drop- (i32.xor- (local.get $x)- (local.get $x)- )- )- (drop- (i32.ne- (local.get $x)- (local.get $x)- )- )- (drop- (i32.lt_s- (local.get $x)- (local.get $x)- )- )- (drop- (i32.lt_u- (local.get $x)- (local.get $x)- )- )- (drop- (i32.gt_s- (local.get $x)- (local.get $x)- )- )- (drop- (i32.gt_u- (local.get $x)- (local.get $x)- )- )- (drop- (i32.and- (local.get $x)- (local.get $x)- )- )- (drop- (i32.or- (local.get $x)- (local.get $x)- )- )- (drop- (i32.eq- (local.get $x)- (local.get $x)- )- )- (drop- (i32.le_s- (local.get $x)- (local.get $x)- )- )- (drop- (i32.le_u- (local.get $x)- (local.get $x)- )- )- (drop- (i32.ge_s- (local.get $x)- (local.get $x)- )- )- (drop- (i32.ge_u- (local.get $x)- (local.get $x)- )- )- (drop- (i64.xor- (local.get $y)- (local.get $y)- )- )- (drop- (i64.ne- (local.get $y)- (local.get $y)- )- )- (drop- (i64.lt_s- (local.get $y)- (local.get $y)- )- )- (drop- (i64.lt_u- (local.get $y)- (local.get $y)- )- )- (drop- (i64.gt_s- (local.get $y)- (local.get $y)- )- )- (drop- (i64.gt_u- (local.get $y)- (local.get $y)- )- )- (drop- (i64.and- (local.get $y)- (local.get $y)- )- )- (drop- (i64.or- (local.get $y)- (local.get $y)- )- )- (drop- (i64.eq- (local.get $y)- (local.get $y)- )- )- (drop- (i64.le_s- (local.get $y)- (local.get $y)- )- )- (drop- (i64.le_u- (local.get $y)- (local.get $y)- )- )- (drop- (i64.ge_s- (local.get $y)- (local.get $y)- )- )- (drop- (i64.ge_u- (local.get $y)- (local.get $y)- )- )- )- (func $all_ones (param $x i32) (param $y i64)- (drop- (i32.and- (local.get $x)- (i32.const -1)- )- )- (drop- (i32.or- (local.get $x)- (i32.const -1)- )- )- (drop- (i32.or- (local.tee $x- (i32.const 1337)- )- (i32.const -1)- )- )- (drop- (i64.and- (local.get $y)- (i64.const -1)- )- )- (drop- (i64.or- (local.get $y)- (i64.const -1)- )- )- )- (func $xor (param $x i32) (param $y i64)- (drop- (i32.xor- (local.get $x)- (i32.const 0)- )- )- )- (func $select-on-const (param $x i32) (param $y i64)- (drop- (select- (i32.const 2)- (local.get $x)- (i32.const 0)- )- )- (drop- (select- (i32.const 3)- (local.get $x)- (i32.const 1)- )- )- (drop- (select- (i32.const 4)- (local.tee $x- (i32.const 5)- )- (i32.const 0)- )- )- (drop- (select- (local.tee $x- (i32.const 6)- )- (i32.const 7)- (i32.const 0)- )- )- (drop- (select- (i32.const 4)- (local.tee $x- (i32.const 5)- )- (i32.const 1)- )- )- (drop- (select- (local.tee $x- (i32.const 6)- )- (i32.const 7)- (i32.const 1)- )- )- (drop- (select- (i32.const 1)- (i32.const 0)- (local.get $x)- )- )- (drop- (select- (i32.const 0)- (i32.const 1)- (local.get $x)- )- )- (drop- (select- (i32.const 0)- (i32.const 1)- (i32.lt_s- (local.get $x)- (i32.const 0)- )- )- )- (drop- (select- (i32.const 1)- (i32.const 0)- (i32.lt_s- (local.get $x)- (i32.const 0)- )- )- )- (drop- (select- (i32.const 0)- (i32.const 1)- (i32.ge_s- (local.get $x)- (i32.const 0)- )- )- )- (drop- (select- (i32.const 1)- (i32.const 0)- (i32.gt_s- (local.get $x)- (i32.const 0)- )- )- )- (drop- (select- (i32.const 0)- (i32.const 1)- (i32.gt_s- (local.get $x)- (i32.const 0)- )- )- )- (drop- (select- (i32.const 1)- (i32.const 0)- (i32.ge_s- (local.get $x)- (i32.const 0)- )- )- )- (drop- (select- (i64.const 1)- (i64.const 0)- (local.get $x)- )- )- (drop- (select- (i64.const 0)- (i64.const 1)- (local.get $x)- )- )- (drop- (select- (i64.const 1)- (i64.const 0)- (i64.eqz- (local.get $y)- )- )- )- (drop- (select- (i64.const 0)- (i64.const 1)- (i64.eqz- (local.get $y)- )- )- )- (drop- (select- (i64.const 0)- (i64.const 1)- (i64.lt_s- (local.get $y)- (i64.const 0)- )- )- )- (drop- (select- (i64.const 1)- (i64.const 0)- (i64.lt_s- (local.get $y)- (i64.const 0)- )- )- )- (drop- (select- (i64.const 0)- (i64.const 1)- (i64.ge_s- (local.get $y)- (i64.const 0)- )- )- )- (drop- (select- (i64.const 1)- (i64.const 0)- (i64.ge_s- (local.get $y)- (i64.const 0)- )- )- )- ;; optimize boolean- (drop- (select- (local.get $x)- (i32.const 0)- (i32.eqz- (i32.const 0)- )- )- )- (drop- (select- (local.get $x)- (i32.const 2)- (i32.eqz- (i32.const 2)- )- )- )- (drop- (select- (local.get $x)- (i32.const 2)- (i32.eqz- (i32.eqz- (local.get $x)- )- )- )- )- (drop- (select- (local.get $y)- (i64.const 0)- (i64.eqz- (i64.const 0)- )- )- )- (drop- (select- (local.get $y)- (i64.const 2)- (i64.eqz- (i64.const 2)- )- )- )- )- (func $optimize-boolean (param $x i32) (param $y i64)- ;; bool(-x) -> bool(x)- (drop- (select- (i32.const 1)- (i32.const 2)- (i32.sub- (i32.const 0)- (local.get $x)- )- )- )- ;; i32(bool(expr)) == 1 -> bool(expr)- (drop (i32.eq- (i32.and- (local.get $x)- (i32.const 1)- )- (i32.const 1)- ))- ;; i32(bool(expr)) != 1 -> !bool(expr)- (drop (i32.ne- (i32.and- (local.get $x)- (i32.const 1)- )- (i32.const 1)- ))- ;; i64(bool(expr)) != 0 -> i32(bool(expr))- (drop (i64.ne- (i64.shr_u- (local.get $y)- (i64.const 63)- )- (i64.const 0)- ))- ;; eqz((i32(bool(expr)) != 0) != 0)- (drop (i32.eqz- (i32.ne- (i32.ne- (i32.shr_u- (local.get $x)- (i32.const 31)- )- (i32.const 0)- )- (i32.const 0)- )- ))- ;; i32.eqz(wrap(i64(x)))- (drop (i32.eqz- (i32.wrap_i64- (i64.shr_u- (local.get $y)- (i64.const 63)- )- )- ))- ;; eqz((i64(bool(expr)) != 0) != 0)- (drop (i32.eqz- (i32.ne- (i64.ne- (i64.shr_u- (local.get $y)- (i64.const 63)- )- (i64.const 0)- )- (i32.const 0)- )- ))- ;; eqz((i64(bool(expr)) != 0) != 0)- (drop (i32.eqz- (i32.ne- (i64.ne- (local.get $y)- (i64.const 0)- )- (i32.const 0)- )- ))- ;; i32.eqz(wrap(i64(x))) -> skip- (drop (i32.eqz- (i32.wrap_i64- (local.get $y)- )- ))- ;; i64(bool(expr)) == 1 -> i32(bool(expr))- (drop (i64.eq- (i64.and- (local.get $y)- (i64.const 1)- )- (i64.const 1)- ))- ;; i64(bool(expr)) != 1 -> !i64(bool(expr))- (drop (i64.ne- (i64.and- (local.get $y)- (i64.const 1)- )- (i64.const 1)- ))- ;; i32(bool(expr)) & 1 -> bool(expr)- (drop (i32.and- (i32.and- (local.get $x)- (i32.const 1)- )- (i32.const 1)- ))- ;; i32(bool(expr)) | 1 -> 1- (drop (i32.or- (i32.and- (local.get $x)- (i32.const 1)- )- (i32.const 1)- ))- ;; i64(bool(expr)) & 1 -> i64(bool(expr))- (drop (i64.and- (i64.and- (local.get $y)- (i64.const 1)- )- (i64.const 1)- ))- ;; i64(bool(expr)) | 1 -> 1- (drop (i64.or- (i64.and- (local.get $y)- (i64.const 1)- )- (i64.const 1)- ))- )- (func $optimize-bitwise-oprations (param $x i32) (param $y i32) (param $z i64) (param $w i64)- ;; ~(1 << x) -> rotl(-2, x)- (drop (i32.xor- (i32.shl- (i32.const 1)- (local.get $x)- )- (i32.const -1)- ))- (drop (i64.xor- (i64.shl- (i64.const 1)- (local.get $z)- )- (i64.const -1)- ))- )- (func $getFallthrough ;; unit tests for Properties::getFallthrough- (local $x0 i32)- (local $x1 i32)- (local $x2 i32)- (local $x3 i32)- (local $x4 i32)- (local $x5 i32)- (local $x6 i32)- (local $x7 i32)- ;; the trivial case- (local.set $x0 (i32.const 1))- (drop (i32.and (local.get $x0) (i32.const 7)))- ;; tees- (local.set $x1 (local.tee $x2 (i32.const 1)))- (drop (i32.and (local.get $x1) (i32.const 7)))- ;; loop- (local.set $x3 (loop (result i32) (i32.const 1)))- (drop (i32.and (local.get $x3) (i32.const 7)))- ;; if - two sides, can't- (local.set $x4 (if (result i32) (i32.const 1) (i32.const 2) (i32.const 3)))- (drop (i32.and (local.get $x4) (i32.const 7)))- ;; if - one side, can- (local.set $x5 (if (result i32) (i32.const 1) (unreachable) (i32.const 3)))- (drop (i32.and (local.get $x5) (i32.const 7)))- ;; if - one side, can- (local.set $x6 (if (result i32) (i32.const 1) (i32.const 3) (unreachable)))- (drop (i32.and (local.get $x6) (i32.const 7)))- ;; br_if with value- (drop- (block $out (result i32)- (local.set $x7 (br_if $out (i32.const 1) (i32.const 1)))- (drop (i32.and (local.get $x7) (i32.const 7)))- (unreachable)- )- )- )- (func $tee-with-unreachable-value (result f64)- (local $var$0 i32)- (block $label$1 (result f64)- (local.tee $var$0- (br_if $label$1 ;; the f64 does not actually flow through this, it's unreachable (and the type is wrong - but unchecked)- (f64.const 1)- (unreachable)- )- )- )- )- (func $add-sub-zero-reorder-1 (param $temp i32) (result i32)- (i32.add- (i32.add- (i32.sub- (i32.const 0) ;; this zero looks like we could remove it by subtracting the get of $temp from the parent, but that would reorder it *after* the tee :(- (local.get $temp)- )- (local.tee $temp ;; cannot move this tee before the get- (i32.const 1)- )- )- (i32.const 2)- )- )- (func $add-sub-zero-reorder-2 (param $temp i32) (result i32)- (i32.add- (i32.add- (local.tee $temp ;; in this order, the tee already comes first, so all is good for the optimization- (i32.const 1)- )- (i32.sub- (i32.const 0)- (local.get $temp)- )- )- (i32.const 2)- )- )- (func $const-float-zero (param $fx f32) (param $fy f64)- ;; x - 0.0 ==> x- (drop (f32.sub- (local.get $fx)- (f32.const 0)- ))- (drop (f64.sub- (local.get $fy)- (f64.const 0)- ))- ;; x + (-0.0) ==> x- (drop (f32.add- (local.get $fx)- (f32.const -0)- ))- (drop (f64.add- (local.get $fy)- (f64.const -0)- ))- ;; x - (-0.0) ==> x + 0.0- (drop (f32.sub- (local.get $fx)- (f32.const -0) ;; skip- ))- (drop (f64.sub- (local.get $fy)- (f64.const -0) ;; skip- ))- ;; 0.0 - x ==> 0.0 - x- (drop (f32.sub- (f32.const 0)- (local.get $fx) ;; skip- ))- (drop (f64.sub- (f64.const 0)- (local.get $fy) ;; skip- ))- ;; x + 0.0 ==> x + 0.0- (drop (f32.add- (local.get $fx) ;; skip- (f32.const 0)- ))- (drop (f64.add- (local.get $fy) ;; skip- (f64.const 0)- ))- (drop (f32.sub- (f32.const -nan:0x34546d) ;; skip- (f32.const 0)- ))- )- (func $rhs-is-neg-one (param $x i32) (param $y i64) (param $fx f32) (param $fy f64)- (drop (i32.sub- (local.get $x)- (i32.const -1)- ))- (drop (i64.sub- (local.get $y)- (i64.const -1)- ))- (drop (i32.gt_u- (local.get $x)- (i32.const -1)- ))- (drop (i64.gt_u- (local.get $y)- (i64.const -1)- ))- (drop (i32.gt_s- (local.get $x)- (i32.const -1)- ))- (drop (i64.gt_s- (local.get $y)- (i64.const -1)- ))- (drop (i64.extend_i32_s- (i64.gt_u- (i64.const 0)- (i64.const -1)- )- ))- ;; (unsigned)x <= -1 ==> 1- (drop (i32.le_u- (local.get $x)- (i32.const -1)- ))- (drop (i64.le_u- (local.get $y)- (i64.const -1)- ))- (drop (i32.le_s- (local.get $x)- (i32.const -1)- ))- (drop (i64.le_s- (local.get $y)- (i64.const -1)- ))- ;; x * -1- (drop (i32.mul- (local.get $x)- (i32.const -1)- ))- (drop (i64.mul- (local.get $y)- (i64.const -1)- ))- (drop (f32.mul ;; skip- (local.get $fx)- (f32.const -1)- ))- (drop (f64.mul ;; skip- (local.get $fy)- (f64.const -1)- ))- ;; (unsigned)x / -1- (drop (i32.div_u- (local.get $x)- (i32.const -1)- ))- (drop (i64.div_u- (local.get $y)- (i64.const -1)- ))- )- (func $rhs-is-neg-const (param $x i32) (param $y i64)- ;; u32(x) / -2 => x >= -2- (drop (i32.div_u- (local.get $x)- (i32.const -2)- ))- ;; u32(x) / -1 => x == -1- (drop (i32.div_u- (local.get $x)- (i32.const -1)- ))- ;; u32(x) / (i32.min + 1)- (drop (i32.div_u- (local.get $x)- (i32.const -2147483647)- ))- ;; u32(x) / i32.min => x >>> 31- (drop (i32.div_u- (local.get $x)- (i32.const -2147483648)- ))- ;; u64(x) / -1 => u64(x == -1)- (drop (i64.div_u- (local.get $y)- (i64.const -1)- ))- ;; u64(x) / i64.min => x >>> 63- (drop (i64.div_u- (local.get $y)- (i64.const -9223372036854775808)- ))- )- (func $pre-combine-or (param $x i32) (param $y i32)- (drop (i32.or- (i32.gt_s- (local.get $x)- (local.get $y)- )- (i32.eq- (local.get $y) ;; ordering should not stop us- (local.get $x)- )- ))- (drop (i32.or- (i32.eq ;; ordering should not stop us- (local.get $y)- (local.get $x)- )- (i32.gt_s- (local.get $x)- (local.get $y)- )- ))- (drop (i32.or- (i32.gt_s- (local.get $x)- (local.get $y)- )- (i32.eq- (local.get $x)- (i32.const 1) ;; not equal- )- ))- (drop (i32.or- (i32.gt_s- (local.get $x)- (i32.const 1) ;; not equal- )- (i32.eq- (local.get $x)- (local.get $y)- )- ))- (drop (i32.or- (i32.gt_s- (call $ne0) ;; side effects- (local.get $y)- )- (i32.eq- (call $ne0)- (local.get $y)- )- ))- (drop (i32.or- (i32.gt_s- (local.get $y)- (call $ne0) ;; side effects- )- (i32.eq- (local.get $y)- (call $ne0)- )- ))- )- (func $combine-or (param $x i32) (param $y i32)- (drop (i32.or- (i32.gt_s- (local.get $x)- (local.get $y)- )- (i32.eq- (local.get $x)- (local.get $y)- )- ))- ;; TODO: more stuff here- )- (func $select-into-arms (param $x i32) (param $y i32)- (if- (select- (i32.eqz (i32.eqz (local.get $x)))- (i32.eqz (i32.eqz (local.get $y)))- (local.get $y)- )- (unreachable)- )- )- ;; These functions test if an `if` with subtyped arms is correctly folded- ;; 1. if its `ifTrue` and `ifFalse` arms are identical (can fold)- (func $if-arms-subtype-fold (result anyref)- (if (result anyref)- (i32.const 0)- (ref.null extern)- (ref.null extern)- )- )- ;; 2. if its `ifTrue` and `ifFalse` arms are not identical (cannot fold)- (func $if-arms-subtype-nofold (result anyref)- (if (result anyref)- (i32.const 0)- (ref.null extern)- (ref.null func)- )- )- (func $optimize-boolean-context (param $x i32) (param $y i32)- ;; 0 - x ==> x- (if- (i32.sub- (i32.const 0)- (local.get $x)- )- (unreachable)- )- (drop (select- (local.get $x)- (local.get $y)- (i32.sub- (i32.const 0)- (local.get $x)- )- ))- )- (func $unsigned-context (param $x i32) (param $y i64)- (drop (i32.div_s- (i32.and- (local.get $x)- (i32.const 0x7fffffff)- )- (i32.const 3)- ))- (drop (i32.div_s- (i32.and- (local.get $x)- (i32.const 0x7fffffff)- )- (i32.const -3) ;; skip- ))- (drop (i32.div_s- (i32.and- (local.get $x)- (i32.const 0x7fffffff)- )- (i32.const 0x80000000) ;; skip- ))- (drop (i64.div_s- (i64.and- (local.get $y)- (i64.const 0x7fffffffffffffff)- )- (i64.const 2)- ))- (drop (i64.div_s- (i64.and- (local.get $y)- (i64.const 0x7fffffffffffffff)- )- (i64.const -1) ;; skip- ))- (drop (i32.rem_s- (i32.and- (local.get $x)- (i32.const 0x7fffffff)- )- (i32.const 3)- ))- (drop (i32.shr_s- (i32.and- (local.get $x)- (i32.const 0x7fffffff)- )- (i32.const 7)- ))- (drop (i32.ge_s- (i32.and- (local.get $x)- (i32.const 0x7fffffff)- )- (i32.const 7)- ))- (drop (i32.ge_s- (i32.and- (local.get $x)- (i32.const 0x7fffffff)- )- (i32.const -7) ;; skip- ))- )- (func $duplicate-elimination (param $x i32) (param $y i32) (param $z i32) (param $w f64)- ;; unary- (drop (f64.abs (f64.abs (local.get $w))))- (drop (f64.ceil (f64.ceil (local.get $w))))- (drop (f64.floor (f64.floor (local.get $w))))- (drop (f64.trunc (f64.trunc (local.get $w))))- (drop (f64.nearest (f64.nearest (local.get $w))))-- (drop (f64.nearest (f64.trunc (local.get $w)))) ;; skip- (drop (f64.trunc (f64.nearest (local.get $w)))) ;; skip-- (drop (f64.neg (f64.neg (local.get $w))))- (drop (f64.neg (f64.neg (f64.neg (local.get $w)))))- (drop (f64.neg (f64.neg (f64.neg (f64.neg (local.get $w))))))-- (drop (i32.eqz (i32.eqz (local.get $x)))) ;; skip- (drop (i32.eqz (i32.eqz (i32.eqz (local.get $x)))))- (drop (i32.eqz (i32.eqz (i64.eqz (i64.const 1)))))- (drop (i32.eqz (i32.eqz (i32.ne (local.get $x) (i32.const 2)))))-- (drop (i32.extend8_s (i32.extend8_s (local.get $x))))- (drop (i32.extend16_s (i32.extend16_s (local.get $x))))- (drop (i32.eqz- (i32.eqz- (i32.and- (local.get $x)- (i32.const 1)- )- )- ))-- ;; binary- ;; ((signed)x % y) % y- (drop (i32.rem_s- (i32.rem_s- (local.get $x)- (local.get $y)- )- (local.get $y)- ))- ;; ((unsigned)x % y) % y- (drop (i32.rem_u- (i32.rem_u- (local.get $x)- (local.get $y)- )- (local.get $y)- ))- ;; 0 - (0 - y)- (drop (i32.sub- (i32.const 0)- (i32.sub- (i32.const 0)- (local.get $y)- )- ))- ;; x - (x - y)- (drop (i32.sub- (local.get $x)- (i32.sub- (local.get $x)- (local.get $y)- )- ))- ;; y - (x - y) - skip- (drop (i32.sub- (local.get $y)- (i32.sub- (local.get $x)- (local.get $y)- )- ))- ;; x ^ (x ^ y)- (drop (i32.xor- (local.get $x)- (i32.xor- (local.get $x)- (local.get $y)- )- ))- ;; x ^ (y ^ x)- (drop (i32.xor- (local.get $x)- (i32.xor- (local.get $y)- (local.get $x)- )- ))- ;; (x ^ y) ^ x- (drop (i32.xor- (i32.xor- (local.get $x)- (local.get $y)- )- (local.get $x)- ))- ;; (y ^ x) ^ x- (drop (i32.xor- (i32.xor- (local.get $y)- (local.get $x)- )- (local.get $x)- ))- ;; x ^ (x ^ x)- (drop (i32.xor- (local.get $x)- (i32.xor- (local.get $x)- (local.get $x)- )- ))- ;; x & (x & y)- (drop (i32.and- (local.get $x)- (i32.and- (local.get $x)- (local.get $y)- )- ))- ;; x & (y & x)- (drop (i32.and- (local.get $x)- (i32.and- (local.get $y)- (local.get $x)- )- ))- ;; (x & y) & x- (drop (i32.and- (i32.and- (local.get $x)- (local.get $y)- )- (local.get $x)- ))- ;; (y & x) & x- (drop (i32.and- (i32.and- (local.get $y)- (local.get $x)- )- (local.get $x)- ))- ;; x | (x | y)- (drop (i32.or- (local.get $x)- (i32.or- (local.get $x)- (local.get $y)- )- ))- ;; x | (y | x)- (drop (i32.or- (local.get $x)- (i32.or- (local.get $y)- (local.get $x)- )- ))- ;; (x | y) | x- (drop (i32.or- (i32.or- (local.get $x)- (local.get $y)- )- (local.get $x)- ))- ;; (y | x) | x- (drop (i32.or- (i32.or- (local.get $y)- (local.get $x)- )- (local.get $x)- ))- ;; (y | x) | z - skip- (drop (i32.or- (i32.or- (local.get $y)- (local.get $x)- )- (local.get $z)- ))- ;; (z | x) | y - skip- (drop (i32.or- (i32.or- (local.get $z)- (local.get $x)- )- (local.get $y)- ))- ;; (SE() | x) | x- (drop (i32.or- (i32.or- (call $ne0) ;; side effect- (local.get $x)- )- (local.get $x)- ))- ;; (x | SE()) | SE() - skip- (drop (i32.or- (i32.or- (local.get $x)- (call $ne0) ;; side effect- )- (call $ne0) ;; side effect- ))- ;; x | (SE() | x)- (drop (i32.or- (local.get $x)- (i32.or- (local.get $x)- (call $ne0) ;; side effect- )- ))- ;; SE() | (x | SE()) - skip- (drop (i32.or- (call $ne0) ;; side effect- (i32.or- (call $ne0) ;; side effect- (local.get $x)- )- ))- ;; (y % x) % y - skip- (drop (i32.rem_s- (i32.rem_s- (local.get $y)- (local.get $x)- )- (local.get $y)- ))- ;; y % (x % y) - skip- (drop (i32.rem_u- (local.get $y)- (i32.rem_u- (local.get $x)- (local.get $y)- )- ))- ;; x | (y | x) where x and y cannot be reordered - skip- (drop- (i32.or- (local.get $x)- (i32.or- (local.tee $x- (i32.const 1)- )- (local.get $x)- )- )- )- (drop- (i32.or- (i32.or- (local.get $x)- (local.tee $x- (i32.const 1)- )- )- (local.get $x)- )- )- ;; x ^ (y ^ x) where x and y cannot be reordered - skip- (drop- (i32.xor- (local.get $x)- (i32.xor- (local.tee $x- (i32.const 1)- )- (local.get $x)- )- )- )- (drop- (i32.xor- (i32.xor- (local.get $x)- (local.tee $x- (i32.const 1)- )- )- (local.get $x)- )- )- )- (func $optimize-shifts (param $x i32) (param $y i32) (param $z i64) (param $w i64)- ;; i32- (drop (i32.shl- (local.get $x)- (i32.const 32)- ))- (drop (i32.shr_s- (local.get $x)- (i32.const 32)- ))- (drop (i32.shr_u- (local.get $x)- (i32.const 64)- ))- (drop (i32.rotl- (local.get $x)- (i32.const 64)- ))- (drop (i32.rotr- (local.get $x)- (i32.const 64)- ))- ;; i64- (drop (i64.shl- (local.get $z)- (i64.const 64)- ))- (drop (i64.shr_s- (local.get $z)- (i64.const 64)- ))- (drop (i64.shr_u- (local.get $z)- (i64.const 128)- ))- (drop (i64.rotl- (local.get $z)- (i64.const 128)- ))- (drop (i64.rotr- (local.get $z)- (i64.const 128)- ))-- ;; i32- (drop (i32.shl- (local.get $x)- (i32.and- (local.get $y)- (i32.const 31)- )- ))- (drop (i32.shl- (local.get $x)- (i32.and- (local.get $y)- (i32.const 63)- )- ))- (drop (i32.shr_s- (local.get $x)- (i32.and- (local.get $y)- (i32.const 31)- )- ))- (drop (i32.shr_u- (local.get $x)- (i32.and- (local.get $y)- (i32.const 31)- )- ))- ;; i64- (drop (i64.shl- (local.get $z)- (i64.and- (local.get $w)- (i64.const 63)- )- ))- (drop (i64.shl- (local.get $z)- (i64.and- (local.get $w)- (i64.const 127)- )- ))- (drop (i64.shr_s- (local.get $z)- (i64.and- (local.get $w)- (i64.const 63)- )- ))- (drop (i64.shr_u- (local.get $z)- (i64.and- (local.get $w)- (i64.const 63)- )- ))-- ;; skip- (drop (i32.shl- (local.get $x)- (i32.and- (local.get $y)- (i32.const 32)- )- ))- ;; skip- (drop (i64.shr_u- (local.get $z)- (i64.and- (local.get $w)- (i64.const 31)- )- ))- )- (func $optimize-bulk-memory-copy (param $dst i32) (param $src i32) (param $sz i32)- (memory.copy ;; skip- (local.get $dst)- (local.get $dst)- (local.get $sz)- )-- (memory.copy ;; skip- (local.get $dst)- (local.get $src)- (i32.const 0)- )-- (memory.copy- (local.get $dst)- (local.get $src)- (i32.const 1)- )-- (memory.copy- (local.get $dst)- (local.get $src)- (i32.const 2)- )-- (memory.copy- (local.get $dst)- (local.get $src)- (i32.const 3)- )-- (memory.copy- (local.get $dst)- (local.get $src)- (i32.const 4)- )-- (memory.copy- (local.get $dst)- (local.get $src)- (i32.const 5)- )-- (memory.copy- (local.get $dst)- (local.get $src)- (i32.const 6)- )-- (memory.copy- (local.get $dst)- (local.get $src)- (i32.const 7)- )-- (memory.copy- (local.get $dst)- (local.get $src)- (i32.const 8)- )-- (memory.copy- (local.get $dst)- (local.get $src)- (i32.const 16)- )-- (memory.copy ;; skip- (local.get $dst)- (local.get $src)- (local.get $sz)- )-- (memory.copy ;; skip- (i32.const 0)- (i32.const 0)- (i32.load- (i32.const 3) ;; side effect- )- )- )-)-(module- (import "env" "memory" (memory $0 (shared 256 256)))- (func $x- (drop- (i32.shr_s- (i32.shl- (i32.atomic.load8_u ;; can't be signed- (i32.const 100)- )- (i32.const 24)- )- (i32.const 24)- )- )+ (drop+ (i32.and+ (i32.and+ (local.get $i1)+ (i32.const 5)+ )+ (i32.const 3)+ )+ )+ (drop+ (i32.or+ (i32.or+ (local.get $i1)+ (i32.const 1)+ )+ (i32.const 2)+ )+ )+ (drop+ (i32.xor+ (i32.xor+ (local.get $i1)+ (i32.const -2)+ )+ (i32.const -5)+ )+ )+ (drop+ (i32.mul+ (i32.mul+ (local.get $i1)+ (i32.const -2)+ )+ (i32.const 5)+ )+ )+ ;; overflow also valid+ (drop+ (i32.mul+ (i32.mul+ (local.get $i1)+ (i32.const 0xfffff)+ )+ (i32.const 0x8000001)+ )+ )+ (if+ (i32.eqz+ (local.get $i1)+ )+ (drop+ (i32.const 10)+ )+ )+ (if+ (i32.eqz+ (local.get $i1)+ )+ (drop+ (i32.const 11)+ )+ (drop+ (i32.const 12)+ )+ )+ (if+ (i64.eqz+ (local.get $i2)+ )+ (drop+ (i32.const 11)+ )+ (drop+ (i32.const 12)+ )+ )+ (drop+ (i32.eqz+ (i32.gt_s+ (i32.const 1)+ (i32.const 2)+ )+ )+ )+ (drop+ (i32.eqz+ (i32.ge_s+ (i32.const 1)+ (i32.const 2)+ )+ )+ )+ (drop+ (i32.eqz+ (i32.lt_s+ (i32.const 1)+ (i32.const 2)+ )+ )+ )+ (drop+ (i32.eqz+ (i32.le_s+ (i32.const 1)+ (i32.const 2)+ )+ )+ )+ (drop+ (i32.eqz+ (i32.gt_u+ (i32.const 1)+ (i32.const 2)+ )+ )+ )+ (drop+ (i32.eqz+ (i32.ge_u+ (i32.const 1)+ (i32.const 2)+ )+ )+ )+ (drop+ (i32.eqz+ (i32.lt_u+ (i32.const 1)+ (i32.const 2)+ )+ )+ )+ (drop+ (i32.eqz+ (i32.le_u+ (i32.const 1)+ (i32.const 2)+ )+ )+ )+ (drop+ (i32.eqz+ (f32.gt+ (f32.const 1)+ (f32.const 2)+ )+ )+ )+ (drop+ (i32.eqz+ (f32.ge+ (f32.const 1)+ (f32.const 2)+ )+ )+ )+ (drop+ (i32.eqz+ (f32.lt+ (f32.const 1)+ (f32.const 2)+ )+ )+ )+ (drop+ (i32.eqz+ (f32.le+ (f32.const 1)+ (f32.const 2)+ )+ )+ )+ (drop+ (i32.eqz+ (f64.gt+ (f64.const 1)+ (f64.const 2)+ )+ )+ )+ (drop+ (i32.eqz+ (f64.ge+ (f64.const 1)+ (f64.const 2)+ )+ )+ )+ (drop+ (i32.eqz+ (f64.lt+ (f64.const 1)+ (f64.const 2)+ )+ )+ )+ (drop+ (i32.eqz+ (f64.le+ (f64.const 1)+ (f64.const 2)+ )+ )+ )+ (drop+ (i32.eqz+ (f32.eq+ (f32.const 1)+ (f32.const 2)+ )+ )+ )+ (drop+ (i32.eqz+ (f32.ne+ (f32.const 1)+ (f32.const 2)+ )+ )+ )+ (drop+ (i32.eqz+ (f64.eq+ (f64.const 1)+ (f64.const 2)+ )+ )+ )+ (drop+ (i32.eqz+ (f64.ne+ (f64.const 1)+ (f64.const 2)+ )+ )+ )+ ;; we handle only 0 in the right position, as we assume a const is there, and don't care about if+ ;; both are consts here (precompute does that, so no need)+ (drop+ (i32.eq+ (i32.const 100)+ (i32.const 0)+ )+ )+ (drop+ (i32.eq+ (i32.const 0)+ (i32.const 100)+ )+ )+ (drop+ (i32.eq+ (i32.const 0)+ (i32.const 0)+ )+ )+ (drop+ (i64.eq+ (i64.const 100)+ (i64.const 0)+ )+ )+ (drop+ (i64.eq+ (i64.const 0)+ (i64.const 100)+ )+ )+ (drop+ (i64.eq+ (i64.const 0)+ (i64.const 0)+ )+ )+ (if+ (i32.eqz+ (i32.eqz+ (i32.const 123)+ )+ )+ (nop)+ )+ (drop+ (select+ (i32.const 101)+ (i32.const 102)+ (i32.eqz+ (local.get $i1)+ )+ )+ )+ (drop+ (select+ (local.tee $i1+ (i32.const 103)+ ) ;; these conflict+ (local.tee $i1+ (i32.const 104)+ )+ (i32.eqz+ (local.get $i1)+ )+ )+ )+ (drop+ (select+ (i32.const 0)+ (i32.const 1)+ (i32.eqz+ (i32.eqz+ (i32.const 2)+ )+ )+ )+ )+ )+ (func $load-store+ (drop (i32.and (i32.load8_s (i32.const 0)) (i32.const 255)))+ (drop (i32.and (i32.load8_u (i32.const 1)) (i32.const 255)))+ (drop (i32.and (i32.load8_s (i32.const 2)) (i32.const 254)))+ (drop (i32.and (i32.load8_u (i32.const 3)) (i32.const 1)))+ (drop (i32.and (i32.load16_s (i32.const 4)) (i32.const 65535)))+ (drop (i32.and (i32.load16_u (i32.const 5)) (i32.const 65535)))+ (drop (i32.and (i32.load16_s (i32.const 6)) (i32.const 65534)))+ (drop (i32.and (i32.load16_u (i32.const 7)) (i32.const 1)))+ ;;+ (i32.store8 (i32.const 8) (i32.and (i32.const -1) (i32.const 255)))+ (i32.store8 (i32.const 9) (i32.and (i32.const -2) (i32.const 254)))+ (i32.store16 (i32.const 10) (i32.and (i32.const -3) (i32.const 65535)))+ (i32.store16 (i32.const 11) (i32.and (i32.const -4) (i32.const 65534)))+ ;;+ (i32.store8 (i32.const 11) (i32.wrap_i64 (i64.const 1)))+ (i32.store16 (i32.const 11) (i32.wrap_i64 (i64.const 2)))+ (i32.store (i32.const 11) (i32.wrap_i64 (i64.const 3)))+ ;;+ (i32.store8 (i32.const 7) (i32.const -1)) ;; 255+ (i32.store8 (i32.const 8) (i32.const 255))+ (i32.store8 (i32.const 9) (i32.const 256)) ;; 0+ (i32.store16 (i32.const 10) (i32.const 65535))+ (i32.store16 (i32.const 11) (i32.const 65536)) ;; 0+ (i32.store16 (i32.const 13) (i32.const -1)) ;; 65535+ (i32.store (i32.const 14) (i32.const 65536))+ ;;+ (i64.store8 (i32.const 8) (i64.const 255))+ (i64.store8 (i32.const 9) (i64.const 256)) ;; 0+ (i64.store16 (i32.const 10) (i64.const 65535))+ (i64.store16 (i32.const 11) (i64.const 65536)) ;; 0+ (i64.store32 (i32.const 12) (i64.const 4294967295))+ (i64.store32 (i32.const 13) (i64.const 4294967296)) ;; 0+ (i64.store (i32.const 14) (i64.const 4294967296))+ )+ (func $and-neg1+ (drop (i32.and (i32.const 100) (i32.const -1)))+ (drop (i32.and (i32.const 100) (i32.const 1)))+ )+ (func $and-pos1+ (drop (i32.and (i32.eqz (i32.const 1000)) (i32.const 1)))+ (drop (i32.and (i32.const 1) (i32.eqz (i32.const 1000))))+ (drop (i32.and (i32.const 100) (i32.const 1)))+ (drop (i32.and (i32.lt_s (i32.const 2000) (i32.const 3000)) (i32.const 1)))+ )+ (func $canonicalize (param $x i32) (param $y i32) (param $fx f64) (param $fy f64)+ (drop (i32.and (unreachable) (i32.const 1))) ;; ok to reorder+ (drop (i32.and (i32.const 1) (unreachable)))+ (drop (i32.div_s (unreachable) (i32.const 1))) ;; not ok+ (drop (i32.div_s (i32.const 1) (unreachable)))+ ;; the various orderings+ (drop (i32.and (i32.const 1) (i32.const 2)))+ (drop (i32.and (local.get $x) (i32.const 3)))+ (drop (i32.and (i32.const 4) (local.get $x)))+ (drop (i32.and (local.get $x) (local.get $y)))+ (drop (i32.and (local.get $y) (local.get $x)))+ (drop (i32.and (local.get $y) (local.tee $x (i32.const -4))))+ (drop (i32.and+ (block (result i32)+ (i32.const -5)+ )+ (local.get $x)+ ))+ (drop (i32.and+ (local.get $x)+ (block (result i32)+ (i32.const -6)+ )+ ))+ (drop (i32.and+ (block (result i32)+ (i32.const 5)+ )+ (loop (result i32)+ (i32.const 6)+ )+ ))+ (drop (i32.and+ (loop (result i32)+ (i32.const 7)+ )+ (block (result i32)+ (i32.const 8)+ )+ ))+ (drop (i32.and+ (loop (result i32)+ (call $and-pos1)+ (i32.const 9)+ )+ (block (result i32)+ (i32.const 10)+ )+ ))+ (drop (i32.and+ (loop (result i32)+ (i32.const 11)+ )+ (block (result i32)+ (call $and-pos1)+ (i32.const 12)+ )+ ))+ (drop (i32.and+ (loop (result i32)+ (call $and-pos1)+ (i32.const 13)+ )+ (block (result i32)+ (call $and-pos1)+ (i32.const 14)+ )+ ))+ (drop (i32.and+ (block (result i32)+ (call $and-pos1)+ (i32.const 14)+ )+ (loop (result i32)+ (call $and-pos1)+ (i32.const 13)+ )+ ))+ (drop (i32.and+ (block (result i32)+ (i32.const 15)+ )+ (local.get $x)+ ))+ (drop (i32.and+ (local.get $x)+ (block (result i32)+ (i32.const 15)+ )+ ))+ (drop (i32.and+ (i32.gt_s+ (i32.const 16)+ (i32.const 17)+ )+ (i32.gt_u+ (i32.const 18)+ (i32.const 19)+ )+ ))+ (drop (i32.and+ (i32.gt_u+ (i32.const 20)+ (i32.const 21)+ )+ (i32.gt_s+ (i32.const 22)+ (i32.const 23)+ )+ ))+ (drop (i32.gt_s+ (i32.const 1)+ (local.get $x)+ ))+ (drop (i32.gt_u+ (i32.const 0)+ (local.get $x)+ ))+ (drop (i32.ne+ (i32.const -1)+ (local.get $x)+ ))+ (drop (f64.ne+ (f64.const -1)+ (local.get $fx)+ ))+ (drop (f64.lt+ (f64.const -2)+ (local.get $fx)+ ))+ (drop (f64.ge+ (f64.const inf)+ (local.get $fx)+ ))+ (drop (f64.le+ (f64.const nan)+ (local.get $fx)+ ))+ ;; skip+ (drop (f64.ge+ (f64.const 1)+ (f64.const 2)+ ))+ (drop (i32.add (i32.ctz (local.get $x)) (i32.ctz (local.get $y))))+ (drop (i32.add (i32.ctz (local.get $y)) (i32.ctz (local.get $x))))+ (drop (i32.add (i32.ctz (local.get $x)) (i32.eqz (local.get $y))))+ (drop (i32.add (i32.eqz (local.get $x)) (i32.ctz (local.get $y))))+ )+ (func $ne0 (result i32)+ (if (i32.ne (call $ne0) (i32.const 0))+ (nop)+ )+ (if (i32.ne (i32.const 0) (call $ne0))+ (nop)+ )+ ;; through an or+ (if+ (i32.or+ (i32.ne (i32.const 0) (call $ne0))+ (i32.ne (i32.const 0) (call $ne0))+ )+ (nop)+ )+ ;; but not an and+ (if+ (i32.and+ (i32.ne (i32.const 0) (call $ne0))+ (i32.ne (i32.const 0) (call $ne0))+ )+ (nop)+ )+ (i32.const 1)+ )+ (func $recurse-bool+ (if+ (if (result i32)+ (i32.const 1)+ (i32.ne (call $ne0) (i32.const 0))+ (i32.ne (call $ne1) (i32.const 0))+ )+ (nop)+ )+ (if+ (block (result i32)+ (nop)+ (i32.ne (call $ne0) (i32.const 0))+ )+ (nop)+ )+ )+ (func $ne1 (result i32)+ (unreachable)+ )+ (func $load-off-2 "load-off-2" (param $0 i32) (result i32)+ (i32.store offset=2+ (i32.add+ (i32.const 1)+ (i32.const 3)+ )+ (local.get $0)+ )+ (i32.store offset=2+ (i32.add+ (i32.const 3)+ (i32.const 1)+ )+ (local.get $0)+ )+ (i32.store offset=2+ (i32.add+ (local.get $0)+ (i32.const 5)+ )+ (local.get $0)+ )+ (i32.store offset=2+ (i32.add+ (i32.const 7)+ (local.get $0)+ )+ (local.get $0)+ )+ (i32.store offset=2+ (i32.add+ (i32.const -11) ;; do not fold this!+ (local.get $0)+ )+ (local.get $0)+ )+ (i32.store offset=2+ (i32.add+ (local.get $0)+ (i32.const -13) ;; do not fold this!+ )+ (local.get $0)+ )+ (i32.store offset=2+ (i32.add+ (i32.const -15)+ (i32.const 17)+ )+ (local.get $0)+ )+ (i32.store offset=2+ (i32.add+ (i32.const -21)+ (i32.const 19)+ )+ (local.get $0)+ )+ (i32.store offset=2+ (i32.const 23)+ (local.get $0)+ )+ (i32.store offset=2+ (i32.const -25)+ (local.get $0)+ )+ (drop+ (i32.load offset=2+ (i32.add+ (i32.const 2)+ (i32.const 4)+ )+ )+ )+ (drop+ (i32.load offset=2+ (i32.add+ (i32.const 4)+ (i32.const 2)+ )+ )+ )+ (drop+ (i32.load offset=2+ (i32.add+ (local.get $0)+ (i32.const 6)+ )+ )+ )+ (drop+ (i32.load offset=2+ (i32.const 8)+ )+ )+ (i32.load offset=2+ (i32.add+ (i32.const 10)+ (local.get $0)+ )+ )+ )+ (func $sign-ext (param $0 i32) (param $1 i32)+ ;; eq of sign-ext to const, can be a zext+ (drop+ (i32.eq+ (i32.shr_s+ (i32.shl+ (local.get $0)+ (i32.const 24)+ )+ (i32.const 24)+ )+ (i32.const 0)+ )+ )+ (drop+ (i32.eq+ (i32.shr_s+ (i32.shl+ (local.get $0)+ (i32.const 16)+ )+ (i32.const 16)+ )+ (i32.const 0)+ )+ )+ (drop+ (i32.eq+ (i32.shr_s+ (i32.shl+ (local.get $0)+ (i32.const 5) ;; weird size, but still valid+ )+ (i32.const 5)+ )+ (i32.const 0)+ )+ )+ (drop+ (i32.eq+ (i32.shr_s+ (i32.shl+ (local.get $0)+ (i32.const 24)+ )+ (i32.const 24)+ )+ (i32.const 100) ;; non-zero+ )+ )+ (drop+ (i32.eq+ (i32.shr_s+ (i32.shl+ (local.get $0)+ (i32.const 24)+ )+ (i32.const 24)+ )+ (i32.const 32767) ;; non-zero and bigger than the mask, with sign bit+ )+ )+ (drop+ (i32.eq+ (i32.shr_s+ (i32.shl+ (local.get $0)+ (i32.const 24)+ )+ (i32.const 24)+ )+ (i32.const -149) ;; non-zero and bigger than the mask, without sign bit+ )+ )+ ;; eq of two sign-ext, can both be a zext+ (drop+ (i32.eq+ (i32.shr_s+ (i32.shl+ (local.get $0)+ (i32.const 24)+ )+ (i32.const 24)+ )+ (i32.shr_s+ (i32.shl+ (local.get $1)+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ )+ (drop+ (i32.eq+ (i32.shr_s+ (i32.shl+ (local.get $0)+ (i32.const 16)+ )+ (i32.const 16)+ )+ (i32.shr_s+ (i32.shl+ (local.get $1)+ (i32.const 16)+ )+ (i32.const 16)+ )+ )+ )+ ;; corner cases we should not opt+ (drop+ (i32.eq+ (i32.shr_s+ (i32.shl+ (local.get $0)+ (i32.const 24)+ )+ (i32.const 23) ;; different shift, smaller+ )+ (i32.const 0)+ )+ )+ (drop+ (i32.eq+ (i32.shr_u ;; unsigned+ (i32.shl+ (local.get $0)+ (i32.const 24)+ )+ (i32.const 24)+ )+ (i32.const 0)+ )+ )+ (drop+ (i32.lt_s ;; non-eq+ (i32.shr_s+ (i32.shl+ (local.get $0)+ (i32.const 24)+ )+ (i32.const 24)+ )+ (i32.const 0)+ )+ )+ (drop+ (if (result i32)+ (i32.shr_s+ (i32.shl+ (unreachable) ;; ignore an unreachable value+ (i32.const 16)+ )+ (i32.const 16)+ )+ (i32.const 111)+ (i32.const 222)+ )+ )+ )+ (func $sign-ext-input (param $0 i32) (param $1 i32)+ (drop+ (i32.shr_s+ (i32.shl+ (i32.const 100) ;; small!+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (i32.const 127) ;; just small enough+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (i32.const 128) ;; just too big+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (local.get $0) ;; who knows...+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (unreachable) ;; ignore+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (i32.div_s ;; this could be optimizable in theory, but currently we don't look into adds etc.+ (i32.const 1)+ (i32.const 2)+ )+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (i32.and ;; takes the min, here it is ok+ (i32.const 127)+ (i32.const 128)+ )+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (i32.and ;; takes the min, here it is not+ (i32.const 128)+ (i32.const 129)+ )+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (i32.xor ;; takes the max, here it is ok+ (i32.const 127)+ (i32.const 126)+ )+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (i32.xor ;; takes the max, here it is not+ (i32.const 127)+ (i32.const 128)+ )+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (i32.or ;; takes the max, here it is ok+ (i32.const 127)+ (i32.const 126)+ )+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (i32.or ;; takes the max, here it is not+ (i32.const 127)+ (i32.const 128)+ )+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (i32.shl ;; adds, here it is too much+ (i32.const 32)+ (i32.const 2)+ )+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (i32.shl ;; adds, here it is ok+ (i32.const 32)+ (i32.const 1)+ )+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (i32.shl ;; adds, here it is too much and "overflows"+ (i32.const 32)+ (i32.const 35)+ )+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (i32.shr_u ;; subtracts, here it is still too much+ (i32.const 256)+ (i32.const 1)+ )+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (i32.shr_u ;; subtracts, here it is ok+ (i32.const 256)+ (i32.const 2)+ )+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (i32.shr_u ;; subtracts, here it "overflows"+ (i32.const 128)+ (i32.const 35)+ )+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (i32.shr_s ;; subtracts, here it is still too much+ (i32.const 256)+ (i32.const 1)+ )+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (i32.shr_s ;; subtracts, here it is ok+ (i32.const 256)+ (i32.const 2)+ )+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (i32.shr_s ;; subtracts, here it "overflows"+ (i32.const 128)+ (i32.const 35)+ )+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (i32.shr_s ;; subtracts, here there is a sign bit, so it stays 32 bits no matter how much we shift+ (i32.const -1)+ (i32.const 32)+ )+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (i32.shr_s ;; subtracts, here we mask out that sign bit+ (i32.and+ (i32.const -1)+ (i32.const 2147483647)+ )+ (i32.const 31) ;; adjusted after we fixed shift computation to just look at lower 5 bits+ )+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (i32.ne ;; 1 bit+ (i32.const -1)+ (i32.const -1)+ )+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (f32.le+ (f32.const -1)+ (f32.const -1)+ )+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (i32.clz ;; assumed 5 bits+ (i32.const 0)+ )+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (i32.shl+ (i32.clz ;; assumed 5 bits+ (i32.const 0)+ )+ (i32.const 2) ;; + 2, so 7+ )+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (i32.shl+ (i32.clz ;; assumed 5 bits+ (i32.const 0)+ )+ (i32.const 3) ;; + 3, so 8, too much+ )+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (i32.wrap_i64 ;; preserves 6+ (i64.clz ;; assumed 6 bits+ (i64.const 0)+ )+ )+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (i32.shl+ (i32.wrap_i64 ;; preserves 6+ (i64.clz ;; assumed 6 bits+ (i64.const 0)+ )+ )+ (i32.const 1) ;; + 1, so 7+ )+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (i32.shl+ (i32.wrap_i64 ;; preserves 6+ (i64.clz ;; assumed 6 bits+ (i64.const 0)+ )+ )+ (i32.const 2) ;; + 2, so 8, too much+ )+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (i32.eqz ;; 1 bit+ (i32.const -1)+ )+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (i32.shr_u+ (i32.wrap_i64 ;; down to 32+ (i64.const -1) ;; 64+ )+ (i32.const 24) ;; 32 - 24 = 8+ )+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (i32.shr_u+ (i32.wrap_i64 ;; down to 32+ (i64.const -1) ;; 64+ )+ (i32.const 25) ;; 32 - 25 = 7, ok+ )+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (i32.shr_u+ (i32.wrap_i64 ;; stay 32+ (i64.extend_i32_s+ (i32.const -1)+ )+ )+ (i32.const 24) ;; 32 - 24 = 8+ )+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (i32.shr_u+ (i32.wrap_i64 ;; stay 32+ (i64.extend_i32_s+ (i32.const -1)+ )+ )+ (i32.const 25) ;; 32 - 25 = 7, ok+ )+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop ;; fuzz testcase+ (i32.shr_s+ (i32.shl+ (i32.xor ;; should be 32 bits+ (i32.le_u ;; 1 bit+ (local.get $0)+ (i32.const 2)+ )+ (local.get $0) ;; unknown, so 32 bits+ )+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ )+ (func $linear-sums (param $0 i32) (param $1 i32)+ (drop+ (i32.add+ (i32.add+ (local.get $1)+ (i32.const 16)+ )+ (i32.shl+ (i32.add+ (local.get $0)+ (i32.const -1) ;; -16, so cancels out!+ )+ (i32.const 4)+ )+ )+ )+ (drop+ (i32.add+ (i32.add+ (local.get $1)+ (i32.const 20)+ )+ (i32.shl+ (i32.add+ (local.get $0)+ (i32.const -1) ;; -8, so sum is +12+ )+ (i32.const 3)+ )+ )+ )+ (drop+ (i32.add ;; simple sum+ (i32.const 1)+ (i32.const 3)+ )+ )+ (drop+ (i32.add ;; nested sum+ (i32.add+ (i32.const 1)+ (i32.const 3)+ )+ (i32.add+ (i32.const 5)+ (i32.const 9)+ )+ )+ )+ (drop+ (i32.add+ (i32.add+ (i32.const 1)+ (i32.const 3)+ )+ (i32.sub ;; internal sub+ (i32.const 5)+ (i32.const 3)+ )+ )+ )+ (drop+ (i32.sub ;; external sub+ (i32.add+ (i32.const 1)+ (i32.const 3)+ )+ (i32.add+ (i32.const 5)+ (i32.const 3)+ )+ )+ )+ (drop+ (i32.sub ;; external sub+ (i32.add+ (i32.const 1)+ (i32.const 3)+ )+ (i32.sub ;; and also internal sub+ (i32.const 5)+ (i32.const 3)+ )+ )+ )+ (drop+ (i32.add+ (i32.add+ (i32.const 1)+ (i32.const 3)+ )+ (i32.sub ;; negating sub+ (i32.const 0)+ (i32.const 3)+ )+ )+ )+ (drop+ (i32.add+ (i32.sub+ (i32.const 0)+ (i32.sub ;; two negating subs+ (i32.const 0)+ (i32.add+ (i32.const 3)+ (i32.const 20)+ )+ )+ )+ (i32.add+ (i32.const 1)+ (i32.const 2)+ )+ )+ )+ (drop+ (i32.add+ (i32.add+ (i32.const 0)+ (i32.sub ;; one negating sub+ (i32.const 0)+ (i32.add+ (i32.const 3)+ (i32.const 20)+ )+ )+ )+ (i32.add+ (i32.const 1)+ (i32.const 2)+ )+ )+ )+ (drop+ (i32.add+ (i32.shl ;; shifted value+ (i32.const 1)+ (i32.const 3)+ )+ (i32.add+ (i32.const 5)+ (i32.const 9)+ )+ )+ )+ (drop+ (i32.add+ (i32.shl ;; shifted value+ (i32.const 1)+ (local.get $0) ;; but not by const+ )+ (i32.add+ (i32.const 5)+ (i32.const 9)+ )+ )+ )+ (drop+ (i32.add+ (i32.shl ;; shifted nested value+ (i32.sub+ (local.get $1)+ (i32.const 10)+ )+ (i32.const 3)+ )+ (i32.add+ (i32.const 5)+ (i32.const 9)+ )+ )+ )+ (drop+ (i32.add+ (i32.mul ;; multiplied+ (i32.const 10)+ (i32.const 3)+ )+ (i32.add+ (i32.const 5)+ (i32.const 9)+ )+ )+ )+ (drop+ (i32.add+ (i32.mul ;; multiplied by nonconstant - can't recurse+ (i32.const 10)+ (local.get $0)+ )+ (i32.add+ (i32.const 5)+ (i32.const 9)+ )+ )+ )+ (drop+ (i32.add+ (i32.mul ;; nested mul+ (i32.add+ (i32.const 10)+ (local.get $0)+ )+ (i32.const 2)+ )+ (i32.add+ (i32.const 5)+ (i32.const 9)+ )+ )+ )+ (drop+ (i32.add+ (i32.add+ (local.get $0)+ (i32.const 10) ;; cancelled out with the below+ )+ (i32.sub+ (i32.const -5)+ (i32.const 5)+ )+ )+ )+ )+ (func $almost-sign-ext (param $0 i32)+ (drop+ (i32.shr_s+ (i32.shl+ (i32.const 100) ;; too big, there is a sign bit, due to the extra shift+ (i32.const 25)+ )+ (i32.const 24) ;; different shift, but larger, so ok to opt if we leave a shift, in theory+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (i32.const 50) ;; small enough, no sign bit+ (i32.const 25)+ )+ (i32.const 24) ;; different shift, but larger, so ok to opt if we leave a shift+ )+ )+ )+ (func $squaring (param $0 i32) (param $1 i32)+ (drop+ (i32.and+ (i32.and+ (local.get $0)+ (i32.const 11)+ )+ (i32.const 200)+ )+ )+ (drop+ (i32.and+ (i32.and+ (local.get $0)+ (i32.const 11)+ )+ (local.get $0) ;; non-const, cannot optimize this!+ )+ )+ (drop+ (i32.and+ (i32.and+ (i32.const 11) ;; flipped order+ (local.get $0)+ )+ (i32.const 200)+ )+ )+ (drop+ (i32.or+ (i32.or+ (local.get $0)+ (i32.const 11)+ )+ (i32.const 200)+ )+ )+ (drop+ (i32.shl+ (i32.shl+ (local.get $0)+ (i32.const 11)+ )+ (i32.const 200)+ )+ )+ (drop+ (i32.shr_s+ (i32.shr_s+ (local.get $0)+ (i32.const 11)+ )+ (i32.const 200)+ )+ )+ (drop+ (i32.shr_u+ (i32.shr_u+ (local.get $0)+ (i32.const 11)+ )+ (i32.const 200)+ )+ )+ (drop+ (i32.shr_u+ (i32.shr_s ;; but do not optimize a mixture or different shifts!+ (local.get $0)+ (i32.const 11)+ )+ (i32.const 200)+ )+ )+ )+ (func $sign-ext-ne (param $0 i32) (param $1 i32)+ ;; ne of sign-ext to const, can be a zext+ (drop+ (i32.ne+ (i32.shr_s+ (i32.shl+ (local.get $0)+ (i32.const 24)+ )+ (i32.const 24)+ )+ (i32.const 65000)+ )+ )+ (drop+ (i32.ne+ (i32.shr_s+ (i32.shl+ (local.get $0)+ (i32.const 24)+ )+ (i32.const 24)+ )+ (i32.const 64872) ;; no sign bit+ )+ )+ (drop+ (i32.ne+ (i32.shr_s+ (i32.shl+ (local.get $0)+ (i32.const 24)+ )+ (i32.const 24)+ )+ (i32.const -149) ;; no sign bit, not all ones+ )+ )+ (drop+ (i32.ne+ (i32.shr_s+ (i32.shl+ (local.get $0)+ (i32.const 24)+ )+ (i32.const 24)+ )+ (i32.const 111)+ )+ )+ (drop+ (i32.ne+ (i32.shr_s+ (i32.shl+ (local.get $0)+ (i32.const 24)+ )+ (i32.const 24)+ )+ (i32.shr_s+ (i32.shl+ (local.get $1)+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ )+ )+ (func $sign-ext-eqz (param $0 i32) (param $1 i32)+ (drop+ (i32.eqz+ (i32.shr_s+ (i32.shl+ (local.get $0)+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ )+ )+ (func $sign-ext-boolean (param $0 i32) (param $1 i32)+ (drop+ (if (result i32)+ (i32.shr_s+ (i32.shl+ (local.get $0)+ (i32.const 24)+ )+ (i32.const 24)+ )+ (i32.const 100)+ (i32.const 200)+ )+ )+ )+ (func $add-sub-zero (param $0 i32) (param $1 i64)+ (drop+ (i32.add+ (local.get $0)+ (i32.const 0)+ )+ )+ (drop+ (i32.sub+ (local.get $0)+ (i32.const 0)+ )+ )+ (drop+ (i64.add+ (local.get $1)+ (i64.const 0)+ )+ )+ (drop+ (i64.sub+ (local.get $1)+ (i64.const 0)+ )+ )+ )+ (func $store-signext (param $0 i32)+ (i32.store8+ (i32.const 8)+ (i32.shr_s+ (i32.shl+ (local.get $0)+ (i32.const 24) ;; exact size we store, sign-ext of 8 bits+ )+ (i32.const 24)+ )+ )+ (i32.store8+ (i32.const 8)+ (i32.shr_s+ (i32.shl+ (local.get $0)+ (i32.const 25) ;; 7 bits. so the ext can alter a bit we store, do not optimize+ )+ (i32.const 25)+ )+ )+ (i32.store8+ (i32.const 8)+ (i32.shr_s+ (i32.shl+ (local.get $0)+ (i32.const 23) ;; 9 bits, this is good to optimize+ )+ (i32.const 23)+ )+ )+ (i32.store16+ (i32.const 8)+ (i32.shr_s+ (i32.shl+ (local.get $0)+ (i32.const 16) ;; exact size we store, sign-ext of 16 bits+ )+ (i32.const 16)+ )+ )+ (i32.store16+ (i32.const 8)+ (i32.shr_s+ (i32.shl+ (local.get $0)+ (i32.const 17) ;; 15 bits. so the ext can alter a bit we store, do not optimize+ )+ (i32.const 17)+ )+ )+ (i32.store16+ (i32.const 8)+ (i32.shr_s+ (i32.shl+ (local.get $0)+ (i32.const 14) ;; 17 bits, this is good to optimize+ )+ (i32.const 14)+ )+ )+ (i32.store+ (i32.const 8)+ (i32.shr_s+ (i32.shl+ (local.get $0)+ (i32.const 16) ;; 4 bytes stored, do nothing+ )+ (i32.const 16)+ )+ )+ (i32.store+ (i32.const 8)+ (i32.shr_s+ (i32.shl+ (local.get $0)+ (i32.const 8) ;; 4 bytes stored, do nothing+ )+ (i32.const 8)+ )+ )+ )+ (func $sign-ext-tee (param $0 i32) (param $1 i32)+ (drop+ (i32.shr_s+ (i32.shl+ (local.tee $0+ (i32.const 128) ;; too big+ )+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (local.tee $0+ (i32.const 127) ;; just right+ )+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ )+ (func $sign-ext-load (param $0 i32) (param $1 i32)+ (drop+ (i32.shr_s+ (i32.shl+ (i32.load8_s ;; one byte, so perfect+ (i32.const 256)+ )+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (i32.shr_u+ (i32.load8_s ;; one byte, but sexted to 32+ (i32.const 256)+ )+ (i32.const 1)+ )+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (i32.shr_u+ (i32.load8_u ;; one byte, but reduced to 7+ (i32.const 256)+ )+ (i32.const 1)+ )+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (i32.load16_s ;; two, so perfect+ (i32.const 256)+ )+ (i32.const 16)+ )+ (i32.const 16)+ )+ )+ ;; through tees, we cannot alter the load sign+ (drop+ (i32.shr_s+ (i32.shl+ (local.tee $1+ (i32.load8_s+ (i32.const 1)+ )+ )+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (local.tee $1+ (i32.load8_u+ (i32.const 1)+ )+ )+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.and+ (local.tee $1+ (i32.load8_s+ (i32.const 1)+ )+ )+ (i32.const 255)+ )+ )+ (drop+ (i32.and+ (local.tee $1+ (i32.load8_u+ (i32.const 1)+ )+ )+ (i32.const 255)+ )+ )+ )+ (func $mask-bits (param $0 i32) (param $1 i32)+ (drop+ (i32.and+ (local.tee $0+ (i32.const 127) ;; 7 bits+ )+ (i32.const 255) ;; mask 8, so we don't need this+ )+ )+ (drop+ (i32.and+ (local.tee $0+ (i32.const 128) ;; 8 bits+ )+ (i32.const 255) ;; mask 8, so we don't need this+ )+ )+ (drop+ (i32.and+ (local.tee $0+ (i32.const 128)+ )+ (i32.const 254) ;; improper mask, small+ )+ )+ (drop+ (i32.and+ (local.tee $0+ (i32.const 128)+ )+ (i32.const 1279) ;; improper mask, large+ )+ )+ (drop+ (i32.and+ (local.tee $0+ (i32.const 128)+ )+ (i32.const 1290) ;; improper mask, large+ )+ )+ (drop+ (i32.and+ (local.tee $0+ (i32.const 128)+ )+ (i32.const 4095) ;; proper mask, huge+ )+ )+ (drop+ (i32.and+ (local.tee $0+ (i32.const 128)+ )+ (i32.const 511) ;; proper mask, large+ )+ )+ (drop+ (i32.and+ (local.tee $0+ (i32.const 128)+ )+ (i32.const 127) ;; proper mask, just too small+ )+ )+ )+ (func $local-info-zero-ext (param $0 i32) (param $1 i32)+ (local $x i32)+ (local $y i32)+ (local $z i32)+ (local $w i32)+ (local.set $x+ (i32.const 212) ;; mask is unneeded, we are small+ )+ (drop+ (i32.and+ (local.get $x)+ (i32.const 255)+ )+ )+ (local.set $y+ (i32.const 500) ;; mask is needed, we are too big+ )+ (drop+ (i32.and+ (local.get $y)+ (i32.const 255)+ )+ )+ (local.set $0+ (i32.const 212) ;; mask is unneeded, but we are a param, not a var, so no+ )+ (drop+ (i32.and+ (local.get $0)+ (i32.const 255)+ )+ )+ (local.set $z+ (i32.const 212) ;; mask is unneeded, we are small+ )+ (local.set $z+ (i32.const 220) ;; mask is still unneeded even with 2 uses+ )+ (drop+ (i32.and+ (local.get $z)+ (i32.const 255)+ )+ )+ (local.set $w+ (i32.const 212) ;; mask is unneeded, we are small+ )+ (local.set $w+ (i32.const 1000) ;; mask is needed, one use is too big+ )+ (drop+ (i32.and+ (local.get $w)+ (i32.const 255)+ )+ )+ )+ (func $local-info-sign-ext-bitsize (param $0 i32) (param $1 i32)+ (local $x i32)+ (local $y i32)+ (local $z i32)+ (local $w i32)+ (local.set $x+ (i32.const 127) ;; mask is unneeded, we are small+ )+ (drop+ (i32.shr_s+ (i32.shl+ (local.get $x)+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (local.set $y+ (i32.const 128) ;; mask is needed, we are too big+ )+ (drop+ (i32.shr_s+ (i32.shl+ (local.get $y)+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (local.set $0+ (i32.const 127) ;; mask is unneeded, but we are a param, not a var, so no+ )+ (drop+ (i32.shr_s+ (i32.shl+ (local.get $0)+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (local.set $z+ (i32.const 127) ;; mask is unneeded, we are small+ )+ (local.set $z+ (i32.const 100) ;; mask is still unneeded even with 2 uses+ )+ (drop+ (i32.shr_s+ (i32.shl+ (local.get $z)+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (local.set $w+ (i32.const 127) ;; mask is unneeded, we are small+ )+ (local.set $w+ (i32.const 150) ;; mask is needed, one use is too big+ )+ (drop+ (i32.shr_s+ (i32.shl+ (local.get $w)+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ )+ (func $local-info-sign-ext-already-exted (param $0 i32) (param $1 i32)+ (local $x i32)+ (local $y i32)+ (local $z i32)+ (local $w i32)+ (local.set $x+ (i32.shr_s+ (i32.shl+ (local.get $0) ;; already sign-exted here, so no need later+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (local.get $x)+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (local.set $y+ (i32.shr_s+ (i32.shl+ (local.get $0) ;; already sign-exted here, but wrong bit size+ (i32.const 16)+ )+ (i32.const 16)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (local.get $y)+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (local.set $0+ (i32.shr_s+ (i32.shl+ (local.get $0) ;; already sign-exted here, so no need later, but we are a param+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (local.get $0)+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (local.set $z+ (i32.shr_s+ (i32.shl+ (local.get $0) ;; already sign-exted here, so no need later+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (local.set $z+ (i32.shr_s+ (i32.shl+ (local.get $1) ;; already sign-exted here, so no need later+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (local.get $z)+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (local.set $w+ (i32.shr_s+ (i32.shl+ (local.get $0) ;; already sign-exted here, so no need later+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (local.set $w+ (i32.shr_s+ (i32.shl+ (local.get $0) ;; not quite a sign-ext+ (i32.const 23)+ )+ (i32.const 24)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (local.get $w)+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (drop ;; odd corner case+ (i32.shr_s+ (i32.shl+ (local.get $0) ;; param, so we should know nothing+ (i32.const 24)+ )+ (i32.const 23) ;; different shift, smaller+ )+ )+ )+ (func $signed-loads-fill-the-bits (param $$e i32) (result i32)+ (local $$0 i32)+ (local $$conv i32)+ (local.set $$0+ (i32.load8_s ;; one byte, but 32 bits due to sign-extend+ (i32.const 1024)+ )+ )+ (local.set $$conv+ (i32.and+ (local.get $$0)+ (i32.const 255) ;; so we need this zexting!+ )+ )+ (return+ (i32.eq+ (local.get $$conv)+ (local.get $$e)+ )+ )+ )+ (func $local-info-sign-ext-already-exted-by-load (param $0 i32) (param $1 i32)+ (local $x i32)+ (local $y i32)+ (local $z i32)+ (local $w i32)+ (local.set $x+ (i32.load8_s (i32.const 1024)) ;; 8 bits, sign extended, no need to do it again+ )+ (drop+ (i32.shr_s+ (i32.shl+ (local.get $x)+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (local.set $y+ (i32.load8_u (i32.const 1024)) ;; 8 bits, zext, so bad+ )+ (drop+ (i32.shr_s+ (i32.shl+ (local.get $y)+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ (local.set $z+ (i32.load16_s (i32.const 1024)) ;; 16 bits sign-extended, wrong size+ )+ (drop+ (i32.shr_s+ (i32.shl+ (local.get $z)+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ )+ (func $compare-load-s-sign-extend (param $0 i32) (param $1 i32)+ (drop+ (i32.eq+ (i32.load8_s+ (local.get $0)+ )+ (i32.shr_s+ (i32.shl+ (local.get $1)+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ )+ (drop+ (i32.eq+ (i32.shr_s+ (i32.shl+ (local.get $1)+ (i32.const 24)+ )+ (i32.const 24)+ )+ (i32.load8_s+ (local.get $0) ;; flip order, we should canonicalize+ )+ )+ )+ (drop+ (i32.eq+ (i32.load8_u ;; unsigned, bad+ (local.get $0)+ )+ (i32.shr_s+ (i32.shl+ (local.get $1)+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ )+ (drop+ (i32.eq+ (i32.load8_s+ (local.get $0)+ )+ (i32.shr_s+ (i32.shl+ (local.get $1)+ (i32.const 16) ;; wrong size+ )+ (i32.const 16)+ )+ )+ )+ (drop+ (i32.eq+ (i32.shr_s+ (i32.shl+ (local.get $1)+ (i32.const 24)+ )+ (i32.const 24)+ )+ (i32.load8_u ;; unsigned, bad+ (local.get $0)+ )+ )+ )+ (drop+ (i32.eq+ (i32.shr_s+ (i32.shl+ (local.get $1)+ (i32.const 16) ;; wrong size+ )+ (i32.const 16)+ )+ (i32.load8_s+ (local.get $0)+ )+ )+ )+ )+ (func $unsign-diff-sizes (param $x i32) (param $y i32) (result i32)+ (i32.ne+ (i32.shr_s+ (i32.shl+ (call $unsign-diff-sizes+ (i32.const -1)+ (i32.const 5)+ )+ (i32.const 24)+ )+ (i32.const 24)+ )+ (i32.shr_s+ (i32.shl+ (call $unsign-diff-sizes+ (i32.const 1)+ (i32.const 2006)+ )+ (i32.const 16)+ )+ (i32.const 16)+ )+ )+ )+ (func $unsign-same-sizes (param $x i32) (param $y i32) (result i32)+ (i32.ne+ (i32.shr_s+ (i32.shl+ (call $unsign-same-sizes+ (i32.const -1)+ (i32.const 5)+ )+ (i32.const 24)+ )+ (i32.const 24)+ )+ (i32.shr_s+ (i32.shl+ (call $unsign-same-sizes+ (i32.const 1)+ (i32.const 2006)+ )+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ )+ (func $fuzz-almost-sign-ext+ (drop+ (i32.shr_s+ (i32.shl+ (i32.load16_u+ (i32.const 2278)+ )+ (i32.const 17)+ )+ (i32.const 16)+ )+ )+ (drop+ (i32.shr_s+ (i32.shl+ (i32.shl+ (i32.load16_u+ (i32.const 2278)+ )+ (i32.const 1)+ )+ (i32.const 16)+ )+ (i32.const 16)+ )+ )+ )+ (func $fuzz-comp-impossible (param $x i32)+ (drop+ (i32.eq+ (i32.shr_s+ (i32.shl+ (local.get $x)+ (i32.const 16)+ )+ (i32.const 16)+ )+ (i32.const 65535) ;; impossible to be equal, the effective sign bit is set, but not the higher bits, which the sign-ext will set on the non-const value+ )+ )+ (drop+ (i32.eq+ (i32.shr_s+ (i32.shl+ (local.get $x)+ (i32.const 24)+ )+ (i32.const 24)+ )+ (i32.const 255)+ )+ )+ (drop+ (i32.eq+ (i32.shr_s+ (i32.shl+ (local.get $x)+ (i32.const 24)+ )+ (i32.const 24)+ )+ (i32.const 127) ;; safe+ )+ )+ (drop+ (i32.eq+ (i32.shr_s+ (i32.shl+ (local.get $x)+ (i32.const 24)+ )+ (i32.const 24)+ )+ (i32.const 128) ;; unsafe again+ )+ )+ (drop+ (i32.eq+ (i32.shr_s+ (i32.shl+ (local.get $x)+ (i32.const 24)+ )+ (i32.const 24)+ )+ (i32.const 4223) ;; more big bits, so sign bit though+ )+ )+ (drop+ (i32.eq+ (i32.shr_s+ (i32.shl+ (local.get $x)+ (i32.const 24)+ )+ (i32.const 24)+ )+ (i32.const 4224) ;; more big bits+ )+ )+ (drop+ (i32.eq+ (i32.shr_s+ (i32.shl+ (local.get $x)+ (i32.const 24)+ )+ (i32.const 24)+ )+ (i32.const -4) ;; safe even with more big bits, as they are all 1s+ )+ )+ )+ (func $if-parallel (param $0 i32) (param $1 i32)+ (drop+ (if (result i32)+ (local.get $0)+ (i32.add (local.get $1) (i32.const 1))+ (i32.add (local.get $1) (i32.const 1))+ )+ )+ (drop+ (if (result i32)+ (local.tee $0 (local.get $1)) ;; side effects!+ (i32.add (local.get $1) (i32.const 1))+ (i32.add (local.get $1) (i32.const 1))+ )+ )+ (drop+ (if (result i32)+ (local.get $0)+ (i32.add (local.get $1) (unreachable)) ;; folding them would change the type of the if+ (i32.add (local.get $1) (unreachable))+ )+ )+ (drop+ (if (result i32)+ (local.tee $0 (local.get $1)) ;; side effects!+ (i32.add (local.get $1) (unreachable)) ;; folding them would change the type of the if+ (i32.add (local.get $1) (unreachable))+ )+ )+ (drop+ (if (result i32)+ (unreachable) ;; !!!+ (i32.add (local.get $1) (unreachable)) ;; folding them would change the type of the if+ (i32.add (local.get $1) (unreachable))+ )+ )+ )+ (func $select-parallel (param $0 i32) (param $1 i32)+ (drop+ (select+ (i32.add (local.get $1) (i32.const 1))+ (i32.add (local.get $1) (i32.const 1))+ (local.get $0)+ )+ )+ (drop+ (select+ (local.tee $0 (local.get $1)) ;; side effects!+ (local.tee $0 (local.get $1)) ;; side effects!+ (local.get $0)+ )+ )+ (drop+ (select+ (i32.add (local.get $1) (i32.const 1))+ (i32.add (local.get $1) (i32.const 1))+ (local.tee $0 (local.get $1)) ;; side effects! (but no interference with values)+ )+ )+ (drop+ (select+ (local.tee $0 (local.get $1)) ;; side effects! interference!+ (local.tee $0 (local.get $1)) ;; side effects! interference!+ (local.tee $0 (local.get $1)) ;; side effects! interference!+ )+ )+ (drop+ (select+ (local.tee $0 (local.get $1)) ;; side effects!+ (local.tee $0 (local.get $1)) ;; side effects!+ (unreachable) ;; side effects! (but no interference with values)+ )+ )+ )+ (func $zero-shifts-is-not-sign-ext+ (drop+ (i32.eq+ (i32.const -5431187)+ (i32.add+ (i32.const 0)+ (i32.shr_s+ (i32.shl+ (i32.load16_s align=1+ (i32.const 790656516)+ )+ (i32.const 0)+ )+ (i32.const 0)+ )+ )+ )+ )+ (drop+ (i32.eq+ (i32.const -5431187)+ (i32.add+ (i32.const 0)+ (i32.shr_s+ (i32.shl+ (i32.load16_s align=1+ (i32.const 790656516)+ )+ (i32.const 1)+ )+ (i32.const 0)+ )+ )+ )+ )+ )+ (func $zero-ops (result i32)+ (return+ (i32.eq+ (i32.const -1337)+ (i32.shr_u+ (i32.add+ (i32.const 0)+ (i32.shr_s+ (i32.shl+ (i32.load16_s align=1+ (i32.const 790656516)+ )+ (i32.const 0)+ )+ (i32.const 0)+ )+ )+ (i32.const 0)+ )+ )+ )+ )+ (func $zero-ops-64 (result i32)+ (return+ (i64.eq+ (i64.const -1337)+ (i64.shr_u+ (i64.add+ (i64.const 0)+ (i64.shr_s+ (i64.shl+ (i64.load16_s align=1+ (i32.const 790656516)+ )+ (i64.const 0)+ )+ (i64.const 0)+ )+ )+ (i64.const 0)+ )+ )+ )+ )+ (func $zero-ops-64-special (result i32)+ (return+ (i32.wrap_i64+ (i64.popcnt+ (i64.sub+ (i64.shl+ (i64.const 4294783828)+ (i64.const 17179869183)+ )+ (i64.const -7377)+ )+ )+ )+ )+ )+ (func $sign-ext-1-and-ne (result i32)+ (select+ (i32.ne+ (i32.const 1333788672)+ (i32.shr_s+ (i32.shl+ (call $sign-ext-1-and-ne)+ (i32.const 1)+ )+ (i32.const 1)+ )+ )+ (i32.const 2)+ (i32.const 1)+ )+ )+ (func $neg-shifts-and-255 (result i32)+ (i32.and+ (i32.shr_u+ (i32.const -99)+ (i32.const -32) ;; this shift does nothing+ )+ (i32.const 255)+ )+ )+ (func $neg-shifts-and-255-b (result i32)+ (i32.and+ (i32.shl+ (i32.const -2349025)+ (i32.const -32) ;; this shift does nothing+ )+ (i32.const 255)+ )+ )+ (func $shifts-square-overflow (param $x i32) (result i32)+ (i32.shr_u+ (i32.shr_u+ (local.get $x)+ (i32.const 65535) ;; 31 bits effectively+ )+ (i32.const 32767) ;; also 31 bits, so two shifts that force the value into nothing for sure+ )+ )+ (func $shifts-square-no-overflow-small (param $x i32) (result i32)+ (i32.shr_u+ (i32.shr_u+ (local.get $x)+ (i32.const 1031) ;; 7 bits effectively+ )+ (i32.const 4098) ;; 2 bits effectively+ )+ )+ (func $shifts-square-overflow-64 (param $x i64) (result i64)+ (i64.shr_u+ (i64.shr_u+ (local.get $x)+ (i64.const 65535) ;; 63 bits effectively+ )+ (i64.const 64767) ;; also 63 bits, so two shifts that force the value into nothing for sure+ )+ )+ (func $shifts-square-no-overflow-small-64 (param $x i64) (result i64)+ (i64.shr_u+ (i64.shr_u+ (local.get $x)+ (i64.const 1031) ;; 7 bits effectively+ )+ (i64.const 4098) ;; 2 bits effectively+ )+ )+ (func $shifts-square-unreachable (param $x i32) (result i32)+ (i32.shr_u+ (i32.shr_u+ (unreachable)+ (i32.const 1031) ;; 7 bits effectively+ )+ (i32.const 4098) ;; 2 bits effectively+ )+ )+ (func $mix-shifts (result i32)+ (i32.shr_s+ (i32.shl+ (i32.const 23)+ (i32.const -61)+ )+ (i32.const 168)+ )+ )+ (func $actually-no-shifts (result i32)+ (i32.add+ (i32.shl+ (i32.const 23)+ (i32.const 32) ;; really 0+ )+ (i32.const 10)+ )+ )+ (func $less-shifts-than-it-seems (param $x i32) (result i32)+ (i32.add+ (i32.shl+ (i32.const 200)+ (i32.const 36) ;; really 4+ )+ (i32.shl+ (i32.const 100)+ (i32.const 4)+ )+ )+ )+ (func $and-popcount32 (result i32)+ (i32.and+ (i32.popcnt+ (i32.const -1)+ )+ (i32.const 31)+ )+ )+ (func $and-popcount32-big (result i32)+ (i32.and+ (i32.popcnt+ (i32.const -1)+ )+ (i32.const 63)+ )+ )+ (func $and-popcount64 (result i64) ;; these are TODOs+ (i64.and+ (i64.popcnt+ (i64.const -1)+ )+ (i64.const 63)+ )+ )+ (func $and-popcount64-big (result i64)+ (i64.and+ (i64.popcnt+ (i64.const -1)+ )+ (i64.const 127)+ )+ )+ (func $and-popcount64-bigger (result i64)+ (i64.and+ (i64.popcnt+ (i64.const -1)+ )+ (i64.const 255)+ )+ )+ (func $optimizeAddedConstants-filters-through-nonzero (result i32)+ (i32.sub+ (i32.add+ (i32.shl+ (i32.const -536870912)+ (i32.wrap_i64+ (i64.const 0)+ )+ )+ (i32.const -32768)+ )+ (i32.const -1024)+ )+ )+ (func $optimizeAddedConstants-filters-through-nonzero-b (result i32)+ (i32.sub+ (i32.add+ (i32.shl+ (i32.const -536870912)+ (i32.wrap_i64+ (i64.const -1)+ )+ )+ (i32.const -32768)+ )+ (i32.const -1024)+ )+ )+ (func $return-proper-value-from-shift-left-by-zero (result i32)+ (if (result i32)+ (i32.sub+ (i32.add+ (loop $label$0 (result i32)+ (block $label$1+ (br_if $label$1+ (i32.shl+ (i32.load+ (i32.const 0)+ )+ (i32.const -31904) ;; really 0 shifts+ )+ )+ )+ (i32.const -62)+ )+ (i32.const 38)+ )+ (i32.const -2)+ )+ (i32.const 1)+ (i32.const 0)+ )+ )+ (func $de-morgan-2 (param $x i32) (param $y i32)+ (drop+ (i32.and (i32.eqz (local.get $x)) (i32.eqz (local.get $y)))+ )+ (drop+ (i32.or (i32.eqz (local.get $x)) (i32.eqz (local.get $y)))+ )+ (drop+ (i32.xor (i32.eqz (local.get $x)) (i32.eqz (local.get $y)))+ )+ (drop+ (i32.and (i32.eqz (local.get $x)) (local.get $y))+ )+ (drop+ (i32.and (local.get $x) (i32.eqz (local.get $y)))+ )+ (drop+ (i32.and (i32.eqz (local.get $x)) (i32.wrap_i64 (i64.const 2)))+ )+ (drop+ (i32.and (i32.wrap_i64 (i64.const 1)) (i32.eqz (local.get $y)))+ )+ )+ (func $subzero1 (param $0 i32) (result i32)+ (i32.add+ (i32.sub+ (i32.const 1)+ (i32.clz+ (local.get $0)+ )+ )+ (i32.const 31)+ )+ )+ (func $subzero2 (param $0 i32) (result i32)+ (i32.add+ (i32.const 31)+ (i32.sub+ (i32.const 1)+ (i32.clz+ (local.get $0)+ )+ )+ )+ )+ (func $subzero3 (param $0 i32) (param $1 i32) (result i32)+ (i32.add+ (i32.sub+ (i32.const 0)+ (i32.clz+ (local.get $0)+ )+ )+ (local.get $1)+ )+ )+ (func $subzero4 (param $0 i32) (param $1 i32) (result i32)+ (i32.add+ (local.get $0)+ (i32.sub+ (i32.const 0)+ (i32.clz+ (local.get $1)+ )+ )+ )+ )+ (func $mul-32-power-2 (param $x i32) (result i32)+ (drop+ (call $mul-32-power-2+ (i32.mul+ (local.get $x)+ (i32.const 4)+ )+ )+ )+ (drop+ (call $mul-32-power-2+ (i32.mul+ (local.get $x)+ (i32.const 5)+ )+ )+ )+ (drop+ (call $mul-32-power-2+ (i32.mul+ (local.get $x)+ (i32.const 1)+ )+ )+ )+ (drop+ (call $mul-32-power-2+ (i32.mul+ (local.get $x)+ (i32.const 0)+ )+ )+ )+ (drop+ (call $mul-32-power-2+ (i32.mul+ (call $mul-32-power-2 (i32.const 123)) ;; side effects+ (i32.const 0)+ )+ )+ )+ (drop+ (call $mul-32-power-2+ (i32.mul+ (local.get $x)+ (i32.const 0xffffffff)+ )+ )+ )+ (drop+ (call $mul-32-power-2+ (i32.mul+ (local.get $x)+ (i32.const 0x80000000)+ )+ )+ )+ (unreachable)+ )+ (func $mul-64-power-2 (param $x i64) (result i64)+ (drop+ (call $mul-64-power-2+ (i64.mul+ (local.get $x)+ (i64.const 4)+ )+ )+ )+ (drop+ (call $mul-64-power-2+ (i64.mul+ (local.get $x)+ (i64.const 5)+ )+ )+ )+ (drop+ (call $mul-64-power-2+ (i64.mul+ (local.get $x)+ (i64.const 1)+ )+ )+ )+ (drop+ (call $mul-64-power-2+ (i64.mul+ (local.get $x)+ (i64.const 0)+ )+ )+ )+ (drop+ (call $mul-64-power-2+ (i64.mul+ (call $mul-64-power-2 (i64.const 123)) ;; side effects+ (i64.const 0)+ )+ )+ )+ (drop+ (call $mul-64-power-2+ (i64.mul+ (local.get $x)+ (i64.const 0xffffffffffffffff)+ )+ )+ )+ (drop+ (call $mul-64-power-2+ (i64.mul+ (local.get $x)+ (i64.const 0x8000000000000000)+ )+ )+ )+ (unreachable)+ )+ (func $div-32-power-2 (param $x i32) (result i32)+ (drop+ (call $div-32-power-2+ (i32.div_u+ (local.get $x)+ (i32.const 4)+ )+ )+ )+ (drop+ (call $div-32-power-2+ (i32.div_u+ (local.get $x)+ (i32.const 5)+ )+ )+ )+ (drop+ (call $div-32-power-2+ (i32.div_u+ (local.get $x)+ (i32.const 1)+ )+ )+ )+ (drop+ (call $div-32-power-2+ (i32.div_u+ (local.get $x)+ (i32.const 0)+ )+ )+ )+ (drop+ (call $div-32-power-2+ (i32.div_u+ (call $div-32-power-2 (i32.const 123)) ;; side effects+ (i32.const 0)+ )+ )+ )+ (drop+ (call $div-32-power-2+ (i32.div_u+ (local.get $x)+ (i32.const 0xffffffff)+ )+ )+ )+ (drop+ (call $div-32-power-2+ (i32.div_u+ (local.get $x)+ (i32.const 0x80000000)+ )+ )+ )+ (unreachable)+ )+ (func $urem-32-power-2 (param $x i32) (result i32)+ (drop+ (call $urem-32-power-2+ (i32.rem_u+ (local.get $x)+ (i32.const 4)+ )+ )+ )+ (drop+ (call $urem-32-power-2+ (i32.rem_u+ (local.get $x)+ (i32.const 5)+ )+ )+ )+ (drop+ (call $urem-32-power-2+ (i32.rem_u+ (local.get $x)+ (i32.const 1)+ )+ )+ )+ (drop+ (call $urem-32-power-2+ (i32.rem_u+ (local.get $x)+ (i32.const 0)+ )+ )+ )+ (drop+ (call $urem-32-power-2+ (i32.rem_u+ (local.get $x)+ (i32.const 0xffffffff)+ )+ )+ )+ (drop+ (call $urem-32-power-2+ (i32.rem_u+ (local.get $x)+ (i32.const 0x80000000)+ )+ )+ )+ ;; (unsigned)x % 1+ (drop+ (call $urem-32-power-2+ (i32.rem_u+ (local.get $x)+ (i32.const 1)+ )+ )+ )+ (unreachable)+ )+ (func $fdiv-32-power-2 (param $x f32)+ (drop (f32.div+ (local.get $x)+ (f32.const 2)+ ))+ (drop (f32.div+ (local.get $x)+ (f32.const -2)+ ))+ (drop (f32.div+ (local.get $x)+ (f32.const 4294967296)+ ))+ (drop (f32.div+ (local.get $x)+ (f32.const 18446744073709551616)+ ))+ (drop (f32.div+ (local.get $x)+ (f32.const 0x1p-126)+ ))+ (drop (f32.div+ (local.get $x)+ (f32.const 0x1p+126)+ ))+ (drop (f32.div+ (local.get $x)+ (f32.const -0x1p-126)+ ))+ (drop (f32.div+ (local.get $x)+ (f32.const -0x1p+126)+ ))+ (drop (f32.div+ (local.get $x)+ (f32.const 0x1p-127) ;; skip+ ))+ (drop (f32.div+ (local.get $x)+ (f32.const 0x1p-127) ;; skip+ ))+ (drop (f32.div+ (local.get $x)+ (f32.const 0) ;; skip+ ))+ (drop (f32.div+ (local.get $x)+ (f32.const nan) ;; skip+ ))+ (drop (f32.div+ (local.get $x)+ (f32.const inf) ;; skip+ ))+ (drop (f32.div+ (local.get $x)+ (f32.const -inf) ;; skip+ ))+ )+ (func $fdiv-64-power-2 (param $x f64)+ (drop (f64.div+ (local.get $x)+ (f64.const 2)+ ))+ (drop (f64.div+ (local.get $x)+ (f64.const -2)+ ))+ (drop (f64.div+ (local.get $x)+ (f64.const 4294967296)+ ))+ (drop (f64.div+ (local.get $x)+ (f64.const 18446744073709551616)+ ))+ (drop (f64.div+ (local.get $x)+ (f64.const 0x1p-1022)+ ))+ (drop (f64.div+ (local.get $x)+ (f64.const 0x1p+1022)+ ))+ (drop (f64.div+ (local.get $x)+ (f64.const -0x1p-1022)+ ))+ (drop (f64.div+ (local.get $x)+ (f64.const -0x1p+1022)+ ))+ (drop (f64.div+ (local.get $x)+ (f64.const 0x1p-1023) ;; skip+ ))+ (drop (f64.div+ (local.get $x)+ (f64.const 0x1p+1023) ;; skip+ ))+ (drop (f64.div+ (local.get $x)+ (f64.const 0) ;; skip+ ))+ (drop (f64.div+ (local.get $x)+ (f64.const nan) ;; skip+ ))+ (drop (f64.div+ (local.get $x)+ (f64.const inf) ;; skip+ ))+ (drop (f64.div+ (local.get $x)+ (f64.const -inf) ;; skip+ ))+ )+ (func $srem-by-const (param $x i32) (param $y i64)+ ;; (signed)x % 1+ (drop (i32.rem_s+ (local.get $x)+ (i32.const 1)+ ))+ (drop (i64.rem_s+ (local.get $y)+ (i64.const 1)+ ))+ ;; (signed)x % 0x80000000 -> x & 0x7FFFFFFF+ (drop (i32.rem_s+ (local.get $x)+ (i32.const 0x80000000)+ ))+ ;; (signed)x % 0x8000000000000000 -> x & 0x7FFFFFFFFFFFFFFF+ (drop (i64.rem_s+ (local.get $y)+ (i64.const 0x8000000000000000)+ ))+ )+ (func $srem-by-pot-eq-ne-zero (param $x i32) (param $y i64)+ ;; eqz((signed)x % 4)+ (drop (i32.eqz+ (i32.rem_s+ (local.get $x)+ (i32.const 4)+ )+ ))+ (drop (i64.eqz+ (i64.rem_s+ (local.get $y)+ (i64.const 4)+ )+ ))+ ;; eqz((signed)x % -4)+ (drop (i32.eqz+ (i32.rem_s+ (local.get $x)+ (i32.const -4)+ )+ ))+ (drop (i64.eqz+ (i64.rem_s+ (local.get $y)+ (i64.const -4)+ )+ ))+ ;; (signed)x % 4 == 0+ (drop (i32.eq+ (i32.rem_s+ (local.get $x)+ (i32.const 4)+ )+ (i32.const 0)+ ))+ (drop (i64.eq+ (i64.rem_s+ (local.get $y)+ (i64.const 2)+ )+ (i64.const 0)+ ))+ ;; (signed)x % -4 == 0+ (drop (i32.eq+ (i32.rem_s+ (local.get $x)+ (i32.const -4)+ )+ (i32.const 0)+ ))+ (drop (i64.eq+ (i64.rem_s+ (local.get $y)+ (i64.const -4)+ )+ (i64.const 0)+ ))+ ;; (signed)x % 2 != 0+ (drop (i32.ne+ (i32.rem_s+ (local.get $x)+ (i32.const 2)+ )+ (i32.const 0)+ ))+ (drop (i64.ne+ (i64.rem_s+ (local.get $y)+ (i64.const 2)+ )+ (i64.const 0)+ ))+ ;; (signed)x % -1 == 0 -> 0 == 0+ (drop (i32.eq+ (i32.rem_s+ (local.get $x)+ (i32.const -1)+ )+ (i32.const 0)+ ))+ ;; (signed)x % 0x80000000 == 0+ (drop (i32.eq+ (i32.rem_s+ (local.get $x)+ (i32.const 0x80000000)+ )+ (i32.const 0)+ ))+ ;; (signed)x % 0x80000000 != 0+ (drop (i32.ne+ (i32.rem_s+ (local.get $x)+ (i32.const 0x80000000)+ )+ (i32.const 0)+ ))+ ;; (signed)x % 0x8000000000000000 == 0+ (drop (i64.eq+ (i64.rem_s+ (local.get $y)+ (i64.const 0x8000000000000000)+ )+ (i64.const 0)+ ))+ ;; (signed)x % 0x8000000000000000 != 0+ (drop (i64.ne+ (i64.rem_s+ (local.get $y)+ (i64.const 0x8000000000000000)+ )+ (i64.const 0)+ ))+ ;;+ (drop (i32.eq+ (i32.rem_s+ (local.get $x)+ (i32.const 3) ;; skip+ )+ (i32.const 0)+ ))+ (drop (i64.eq+ (i64.rem_s+ (local.get $y)+ (i64.const 3) ;; skip+ )+ (i64.const 0)+ ))+ )+ (func $orZero (param $0 i32) (result i32)+ (i32.or+ (local.get $0)+ (i32.const 0)+ )+ )+ (func $andZero (param $0 i32) (result i32)+ (drop+ (i32.and+ (local.get $0)+ (i32.const 0)+ )+ )+ (drop+ (i32.and+ (call $andZero (i32.const 1234)) ;; side effects+ (i32.const 0)+ )+ )+ (unreachable)+ )+ (func $abstract-additions (param $x32 i32) (param $x64 i64) (param $y32 f32) (param $y64 f64)+ (drop+ (i32.or+ (i32.const 0)+ (local.get $x32)+ )+ )+ (drop+ (i32.shl+ (local.get $x32)+ (i32.const 0)+ )+ )+ (drop+ (i32.shr_u+ (local.get $x32)+ (i32.const 0)+ )+ )+ (drop+ (i32.shr_s+ (local.get $x32)+ (i32.const 0)+ )+ )+ (drop+ (i64.or+ (i64.const 0)+ (local.get $x64)+ )+ )+ (drop+ (i64.shl+ (local.get $x64)+ (i64.const 0)+ )+ )+ (drop+ (i64.shr_u+ (local.get $x64)+ (i64.const 0)+ )+ )+ (drop+ (i64.shr_s+ (local.get $x64)+ (i64.const 0)+ )+ )+ (drop+ (i32.mul+ (local.get $x32)+ (i32.const 0)+ )+ )+ (drop+ (i64.mul+ (local.get $x64)+ (i64.const 0)+ )+ )+ (drop+ (f32.mul+ (local.get $y32)+ (f32.const 0)+ )+ )+ (drop+ (f64.mul+ (local.get $y64)+ (f64.const 0)+ )+ )+ (drop+ (i32.mul+ (local.get $x32)+ (i32.const 1)+ )+ )+ (drop+ (i64.mul+ (local.get $x64)+ (i64.const 1)+ )+ )+ (drop+ (f32.mul+ (local.get $y32)+ (f32.const 1)+ )+ )+ (drop+ (f64.mul+ (local.get $y64)+ (f64.const 1)+ )+ )+ (drop+ (i32.and+ (local.get $x32)+ (i32.const 0)+ )+ )+ (drop+ (i64.and+ (local.get $x64)+ (i64.const 0)+ )+ )+ (drop+ (i32.and+ (unreachable)+ (i32.const 0)+ )+ )+ (drop+ (i64.and+ (unreachable)+ (i64.const 0)+ )+ )+ (drop+ (i32.div_s+ (local.get $x32)+ (i32.const 1)+ )+ )+ (drop+ (i32.div_u+ (local.get $x32)+ (i32.const 1)+ )+ )+ (drop+ (i64.div_s+ (local.get $x64)+ (i64.const 1)+ )+ )+ (drop+ (i64.div_u+ (local.get $x64)+ (i64.const 1)+ )+ )+ (drop+ (f32.div+ (local.get $y32)+ (f32.const 1)+ )+ )+ (drop+ (f64.div+ (local.get $y64)+ (f64.const 1)+ )+ )+ (drop+ (f32.div+ (local.get $y32)+ (f32.const 1.2)+ )+ )+ (drop+ (i32.mul+ (local.get $x32)+ (i32.const -1)+ )+ )+ (drop+ (i64.mul+ (local.get $x64)+ (i64.const -1)+ )+ )+ (drop+ (f32.mul+ (local.get $y32)+ (f32.const -1)+ )+ )+ (drop+ (f64.mul+ (local.get $y64)+ (f64.const -1)+ )+ )+ (drop+ (i32.eq+ (i32.add+ (local.get $x32)+ (i32.const 10)+ )+ (i32.const 20)+ )+ )+ (drop+ (i32.le_u+ (i32.add+ (local.get $x32)+ (i32.const 10)+ )+ (i32.const 20)+ )+ )+ (drop+ (i32.eq+ (i32.sub+ (local.get $x32)+ (i32.const 10)+ )+ (i32.const 20)+ )+ )+ (drop+ (i64.eq+ (i64.add+ (local.get $x64)+ (i64.const 10)+ )+ (i64.const 20)+ )+ )+ (drop+ (i32.eq+ (i32.const 20)+ (i32.add+ (local.get $x32)+ (i32.const 10)+ )+ )+ )+ (drop+ (i32.eq+ (i32.add+ (local.get $x32)+ (i32.const 10)+ )+ (i32.add+ (local.get $x32)+ (i32.const 20)+ )+ )+ )+ (drop+ (i32.eq+ (i32.sub+ (local.get $x32)+ (i32.const 10)+ )+ (i32.const 20)+ )+ )+ (drop+ (i32.eq+ (i32.add+ (local.get $x32)+ (i32.const 10)+ )+ (i32.sub+ (local.get $x32)+ (i32.const 20)+ )+ )+ )+ (drop+ (i32.eq+ (i32.sub+ (local.get $x32)+ (i32.const 10)+ )+ (i32.add+ (local.get $x32)+ (i32.const 20)+ )+ )+ )+ (drop+ (i32.eq+ (i32.sub+ (local.get $x32)+ (i32.const 10)+ )+ (i32.sub+ (local.get $x32)+ (i32.const 20)+ )+ )+ )+ (drop+ (i64.le_s+ (i64.sub+ (local.get $x64)+ (i64.const 288230376151711744)+ )+ (i64.const 9223372036854775807)+ )+ )+ )+ (func $negatives-are-sometimes-better (param $x i32) (param $y i64) (param $z f32)+ (drop (i32.add (local.get $x) (i32.const 0x40)))+ (drop (i32.sub (local.get $x) (i32.const 0x40)))+ (drop (i32.add (local.get $x) (i32.const 0x2000)))+ (drop (i32.add (local.get $x) (i32.const 0x100000)))+ (drop (i32.add (local.get $x) (i32.const 0x8000000)))++ (drop (i64.add (local.get $y) (i64.const 0x40)))+ (drop (i64.sub (local.get $y) (i64.const 0x40)))+ (drop (i64.add (local.get $y) (i64.const 0x2000)))+ (drop (i64.add (local.get $y) (i64.const 0x100000)))+ (drop (i64.add (local.get $y) (i64.const 0x8000000)))++ (drop (i64.add (local.get $y) (i64.const 0x400000000)))+ (drop (i64.add (local.get $y) (i64.const 0x20000000000)))+ (drop (i64.add (local.get $y) (i64.const 0x1000000000000)))+ (drop (i64.add (local.get $y) (i64.const 0x80000000000000)))+ (drop (i64.add (local.get $y) (i64.const 0x4000000000000000)))++ (drop (f32.add (local.get $z) (f32.const 0x40)))+ )+ (func $shift-a-zero (param $x i32) (param $y i64) (param $z f32)+ (drop+ (i32.shl+ (i32.const 0)+ (local.get $x)+ )+ )+ (drop+ (i32.shr_u+ (i32.const 0)+ (local.get $x)+ )+ )+ (drop+ (i32.shr_s+ (i32.const 0)+ (local.get $x)+ )+ )+ (drop+ (i64.shl+ (i64.const 0)+ (local.get $y)+ )+ )+ (drop+ (i32.shl+ (i32.const 0)+ (unreachable)+ )+ )+ )+ (func $identical-siblings (param $x i32) (param $y i64) (param $z f64) (param $xx i32)+ (drop+ (i32.sub+ (local.get $x)+ (local.get $x)+ )+ )+ (drop+ (i64.sub+ (local.get $y)+ (local.get $y)+ )+ )+ (drop+ (f64.sub+ (local.get $z)+ (local.get $z)+ )+ )+ (drop+ (i32.sub+ (local.get $x)+ (local.get $xx)+ )+ )+ (drop+ (i32.sub+ (unreachable)+ (unreachable)+ )+ )+ (drop+ (i32.add+ (local.get $x)+ (local.get $x)+ )+ )+ ;; more ops+ (drop+ (i32.xor+ (local.get $x)+ (local.get $x)+ )+ )+ (drop+ (i32.ne+ (local.get $x)+ (local.get $x)+ )+ )+ (drop+ (i32.lt_s+ (local.get $x)+ (local.get $x)+ )+ )+ (drop+ (i32.lt_u+ (local.get $x)+ (local.get $x)+ )+ )+ (drop+ (i32.gt_s+ (local.get $x)+ (local.get $x)+ )+ )+ (drop+ (i32.gt_u+ (local.get $x)+ (local.get $x)+ )+ )+ (drop+ (i32.and+ (local.get $x)+ (local.get $x)+ )+ )+ (drop+ (i32.or+ (local.get $x)+ (local.get $x)+ )+ )+ (drop+ (i32.eq+ (local.get $x)+ (local.get $x)+ )+ )+ (drop+ (i32.le_s+ (local.get $x)+ (local.get $x)+ )+ )+ (drop+ (i32.le_u+ (local.get $x)+ (local.get $x)+ )+ )+ (drop+ (i32.ge_s+ (local.get $x)+ (local.get $x)+ )+ )+ (drop+ (i32.ge_u+ (local.get $x)+ (local.get $x)+ )+ )+ (drop+ (i64.xor+ (local.get $y)+ (local.get $y)+ )+ )+ (drop+ (i64.ne+ (local.get $y)+ (local.get $y)+ )+ )+ (drop+ (i64.lt_s+ (local.get $y)+ (local.get $y)+ )+ )+ (drop+ (i64.lt_u+ (local.get $y)+ (local.get $y)+ )+ )+ (drop+ (i64.gt_s+ (local.get $y)+ (local.get $y)+ )+ )+ (drop+ (i64.gt_u+ (local.get $y)+ (local.get $y)+ )+ )+ (drop+ (i64.and+ (local.get $y)+ (local.get $y)+ )+ )+ (drop+ (i64.or+ (local.get $y)+ (local.get $y)+ )+ )+ (drop+ (i64.eq+ (local.get $y)+ (local.get $y)+ )+ )+ (drop+ (i64.le_s+ (local.get $y)+ (local.get $y)+ )+ )+ (drop+ (i64.le_u+ (local.get $y)+ (local.get $y)+ )+ )+ (drop+ (i64.ge_s+ (local.get $y)+ (local.get $y)+ )+ )+ (drop+ (i64.ge_u+ (local.get $y)+ (local.get $y)+ )+ )+ )+ (func $all_ones (param $x i32) (param $y i64)+ (drop+ (i32.and+ (local.get $x)+ (i32.const -1)+ )+ )+ (drop+ (i32.or+ (local.get $x)+ (i32.const -1)+ )+ )+ (drop+ (i32.or+ (local.tee $x+ (i32.const 1337)+ )+ (i32.const -1)+ )+ )+ (drop+ (i64.and+ (local.get $y)+ (i64.const -1)+ )+ )+ (drop+ (i64.or+ (local.get $y)+ (i64.const -1)+ )+ )+ )+ (func $xor (param $x i32) (param $y i64)+ (drop+ (i32.xor+ (local.get $x)+ (i32.const 0)+ )+ )+ )+ (func $select-on-const (param $x i32) (param $y i64)+ (drop+ (select+ (i32.const 2)+ (local.get $x)+ (i32.const 0)+ )+ )+ (drop+ (select+ (i32.const 3)+ (local.get $x)+ (i32.const 1)+ )+ )+ (drop+ (select+ (i32.const 4)+ (local.tee $x+ (i32.const 5)+ )+ (i32.const 0)+ )+ )+ (drop+ (select+ (local.tee $x+ (i32.const 6)+ )+ (i32.const 7)+ (i32.const 0)+ )+ )+ (drop+ (select+ (i32.const 4)+ (local.tee $x+ (i32.const 5)+ )+ (i32.const 1)+ )+ )+ (drop+ (select+ (local.tee $x+ (i32.const 6)+ )+ (i32.const 7)+ (i32.const 1)+ )+ )+ (drop+ (select+ (i32.const 1)+ (i32.const 0)+ (local.get $x)+ )+ )+ (drop+ (select+ (i32.const 0)+ (i32.const 1)+ (local.get $x)+ )+ )+ (drop+ (select+ (i32.const 0)+ (i32.const 1)+ (i32.lt_s+ (local.get $x)+ (i32.const 0)+ )+ )+ )+ (drop+ (select+ (i32.const 1)+ (i32.const 0)+ (i32.lt_s+ (local.get $x)+ (i32.const 0)+ )+ )+ )+ (drop+ (select+ (i32.const 0)+ (i32.const 1)+ (i32.ge_s+ (local.get $x)+ (i32.const 0)+ )+ )+ )+ (drop+ (select+ (i32.const 1)+ (i32.const 0)+ (i32.gt_s+ (local.get $x)+ (i32.const 0)+ )+ )+ )+ (drop+ (select+ (i32.const 0)+ (i32.const 1)+ (i32.gt_s+ (local.get $x)+ (i32.const 0)+ )+ )+ )+ (drop+ (select+ (i32.const 1)+ (i32.const 0)+ (i32.ge_s+ (local.get $x)+ (i32.const 0)+ )+ )+ )+ (drop+ (select+ (i64.const 1)+ (i64.const 0)+ (local.get $x)+ )+ )+ (drop+ (select+ (i64.const 0)+ (i64.const 1)+ (local.get $x)+ )+ )+ (drop+ (select+ (i64.const 1)+ (i64.const 0)+ (i64.eqz+ (local.get $y)+ )+ )+ )+ (drop+ (select+ (i64.const 0)+ (i64.const 1)+ (i64.eqz+ (local.get $y)+ )+ )+ )+ (drop+ (select+ (i64.const 0)+ (i64.const 1)+ (i64.lt_s+ (local.get $y)+ (i64.const 0)+ )+ )+ )+ (drop+ (select+ (i64.const 1)+ (i64.const 0)+ (i64.lt_s+ (local.get $y)+ (i64.const 0)+ )+ )+ )+ (drop+ (select+ (i64.const 0)+ (i64.const 1)+ (i64.ge_s+ (local.get $y)+ (i64.const 0)+ )+ )+ )+ (drop+ (select+ (i64.const 1)+ (i64.const 0)+ (i64.ge_s+ (local.get $y)+ (i64.const 0)+ )+ )+ )+ ;; optimize boolean+ (drop+ (select+ (local.get $x)+ (i32.const 0)+ (i32.eqz+ (i32.const 0)+ )+ )+ )+ (drop+ (select+ (local.get $x)+ (i32.const 2)+ (i32.eqz+ (i32.const 2)+ )+ )+ )+ (drop+ (select+ (local.get $x)+ (i32.const 2)+ (i32.eqz+ (i32.eqz+ (local.get $x)+ )+ )+ )+ )+ (drop+ (select+ (local.get $y)+ (i64.const 0)+ (i64.eqz+ (i64.const 0)+ )+ )+ )+ (drop+ (select+ (local.get $y)+ (i64.const 2)+ (i64.eqz+ (i64.const 2)+ )+ )+ )+ )+ (func $optimize-boolean (param $x i32) (param $y i64)+ ;; bool(-x) -> bool(x)+ (drop+ (select+ (i32.const 1)+ (i32.const 2)+ (i32.sub+ (i32.const 0)+ (local.get $x)+ )+ )+ )+ ;; i32(bool(expr)) == 1 -> bool(expr)+ (drop (i32.eq+ (i32.and+ (local.get $x)+ (i32.const 1)+ )+ (i32.const 1)+ ))+ ;; i32(bool(expr)) != 1 -> !bool(expr)+ (drop (i32.ne+ (i32.and+ (local.get $x)+ (i32.const 1)+ )+ (i32.const 1)+ ))+ ;; i64(bool(expr)) != 0 -> i32(bool(expr))+ (drop (i64.ne+ (i64.shr_u+ (local.get $y)+ (i64.const 63)+ )+ (i64.const 0)+ ))+ ;; eqz((i32(bool(expr)) != 0) != 0)+ (drop (i32.eqz+ (i32.ne+ (i32.ne+ (i32.shr_u+ (local.get $x)+ (i32.const 31)+ )+ (i32.const 0)+ )+ (i32.const 0)+ )+ ))+ ;; i32.eqz(wrap(i64(x)))+ (drop (i32.eqz+ (i32.wrap_i64+ (i64.shr_u+ (local.get $y)+ (i64.const 63)+ )+ )+ ))+ ;; eqz((i64(bool(expr)) != 0) != 0)+ (drop (i32.eqz+ (i32.ne+ (i64.ne+ (i64.shr_u+ (local.get $y)+ (i64.const 63)+ )+ (i64.const 0)+ )+ (i32.const 0)+ )+ ))+ ;; eqz((i64(bool(expr)) != 0) != 0)+ (drop (i32.eqz+ (i32.ne+ (i64.ne+ (local.get $y)+ (i64.const 0)+ )+ (i32.const 0)+ )+ ))+ ;; i32.eqz(wrap(i64(x))) -> skip+ (drop (i32.eqz+ (i32.wrap_i64+ (local.get $y)+ )+ ))+ ;; i64(bool(expr)) == 1 -> i32(bool(expr))+ (drop (i64.eq+ (i64.and+ (local.get $y)+ (i64.const 1)+ )+ (i64.const 1)+ ))+ ;; i64(bool(expr)) != 1 -> !i64(bool(expr))+ (drop (i64.ne+ (i64.and+ (local.get $y)+ (i64.const 1)+ )+ (i64.const 1)+ ))+ ;; i32(bool(expr)) & 1 -> bool(expr)+ (drop (i32.and+ (i32.and+ (local.get $x)+ (i32.const 1)+ )+ (i32.const 1)+ ))+ ;; i32(bool(expr)) | 1 -> 1+ (drop (i32.or+ (i32.and+ (local.get $x)+ (i32.const 1)+ )+ (i32.const 1)+ ))+ ;; i64(bool(expr)) & 1 -> i64(bool(expr))+ (drop (i64.and+ (i64.and+ (local.get $y)+ (i64.const 1)+ )+ (i64.const 1)+ ))+ ;; i64(bool(expr)) | 1 -> 1+ (drop (i64.or+ (i64.and+ (local.get $y)+ (i64.const 1)+ )+ (i64.const 1)+ ))+ ;; i32(bool(expr)) != 0 -> i32(bool(expr))+ (drop (i32.ne+ (i32.and+ (local.get $x)+ (i32.const 1)+ )+ (i32.const 0)+ ))+ ;; i32(bool(expr)) != 0 -> i32(bool(expr))+ (drop (i32.ne+ (i64.ne+ (local.get $y)+ (i64.const 0)+ )+ (i32.const 0)+ ))+ ;; (i32(expr) != 0) != 0 -> (expr != 0)+ (drop (i32.ne+ (i32.ne+ (local.get $x)+ (i32.const 0)+ )+ (i32.const 0)+ ))+ ;; (signed)x % 4 ? 1 : 0+ (drop (if (result i32)+ (i32.rem_s+ (local.get $x)+ (i32.const 4)+ )+ (i32.const 1)+ (i32.const 0)+ ))+ ;; (signed)x % min_s ? 1 : 0+ (drop (if (result i32)+ (i32.rem_s+ (local.get $x)+ (i32.const 0x80000000)+ )+ (i32.const 1)+ (i32.const 0)+ ))+ )+ (func $optimize-bitwise-oprations (param $x i32) (param $y i32) (param $z i64) (param $w i64)+ ;; ~(1 << x) -> rotl(-2, x)+ (drop (i32.xor+ (i32.shl+ (i32.const 1)+ (local.get $x)+ )+ (i32.const -1)+ ))+ (drop (i64.xor+ (i64.shl+ (i64.const 1)+ (local.get $z)+ )+ (i64.const -1)+ ))+ )+ (func $getFallthrough ;; unit tests for Properties::getFallthrough+ (local $x0 i32)+ (local $x1 i32)+ (local $x2 i32)+ (local $x3 i32)+ (local $x4 i32)+ (local $x5 i32)+ (local $x6 i32)+ (local $x7 i32)+ ;; the trivial case+ (local.set $x0 (i32.const 1))+ (drop (i32.and (local.get $x0) (i32.const 7)))+ ;; tees+ (local.set $x1 (local.tee $x2 (i32.const 1)))+ (drop (i32.and (local.get $x1) (i32.const 7)))+ ;; loop+ (local.set $x3 (loop (result i32) (i32.const 1)))+ (drop (i32.and (local.get $x3) (i32.const 7)))+ ;; if - two sides, can't+ (local.set $x4 (if (result i32) (i32.const 1) (i32.const 2) (i32.const 3)))+ (drop (i32.and (local.get $x4) (i32.const 7)))+ ;; if - one side, can+ (local.set $x5 (if (result i32) (i32.const 1) (unreachable) (i32.const 3)))+ (drop (i32.and (local.get $x5) (i32.const 7)))+ ;; if - one side, can+ (local.set $x6 (if (result i32) (i32.const 1) (i32.const 3) (unreachable)))+ (drop (i32.and (local.get $x6) (i32.const 7)))+ ;; br_if with value+ (drop+ (block $out (result i32)+ (local.set $x7 (br_if $out (i32.const 1) (i32.const 1)))+ (drop (i32.and (local.get $x7) (i32.const 7)))+ (unreachable)+ )+ )+ )+ (func $tee-with-unreachable-value (result f64)+ (local $var$0 i32)+ (block $label$1 (result f64)+ (local.tee $var$0+ (br_if $label$1 ;; the f64 does not actually flow through this, it's unreachable (and the type is wrong - but unchecked)+ (f64.const 1)+ (unreachable)+ )+ )+ )+ )+ (func $add-sub-zero-reorder-1 (param $temp i32) (result i32)+ (i32.add+ (i32.add+ (i32.sub+ (i32.const 0) ;; this zero looks like we could remove it by subtracting the get of $temp from the parent, but that would reorder it *after* the tee :(+ (local.get $temp)+ )+ (local.tee $temp ;; cannot move this tee before the get+ (i32.const 1)+ )+ )+ (i32.const 2)+ )+ )+ (func $add-sub-zero-reorder-2 (param $temp i32) (result i32)+ (i32.add+ (i32.add+ (local.tee $temp ;; in this order, the tee already comes first, so all is good for the optimization+ (i32.const 1)+ )+ (i32.sub+ (i32.const 0)+ (local.get $temp)+ )+ )+ (i32.const 2)+ )+ )+ (func $const-float-zero (param $fx f32) (param $fy f64)+ ;; x - 0.0 ==> x+ (drop (f32.sub+ (local.get $fx)+ (f32.const 0)+ ))+ (drop (f64.sub+ (local.get $fy)+ (f64.const 0)+ ))+ ;; x + (-0.0) ==> x+ (drop (f32.add+ (local.get $fx)+ (f32.const -0)+ ))+ (drop (f64.add+ (local.get $fy)+ (f64.const -0)+ ))+ ;; x - (-0.0) ==> x + 0.0+ (drop (f32.sub+ (local.get $fx)+ (f32.const -0) ;; skip+ ))+ (drop (f64.sub+ (local.get $fy)+ (f64.const -0) ;; skip+ ))+ ;; 0.0 - x ==> 0.0 - x+ (drop (f32.sub+ (f32.const 0)+ (local.get $fx) ;; skip+ ))+ (drop (f64.sub+ (f64.const 0)+ (local.get $fy) ;; skip+ ))+ ;; x + 0.0 ==> x + 0.0+ (drop (f32.add+ (local.get $fx) ;; skip+ (f32.const 0)+ ))+ (drop (f64.add+ (local.get $fy) ;; skip+ (f64.const 0)+ ))+ (drop (f32.sub+ (f32.const -nan:0x34546d) ;; skip+ (f32.const 0)+ ))+ )+ (func $rhs-is-neg-one (param $x i32) (param $y i64) (param $fx f32) (param $fy f64)+ (drop (i32.sub+ (local.get $x)+ (i32.const -1)+ ))+ (drop (i64.sub+ (local.get $y)+ (i64.const -1)+ ))+ ;; (unsigned)x > -1 ==> 0+ (drop (i32.gt_u+ (local.get $x)+ (i32.const -1)+ ))+ (drop (i64.gt_u+ (local.get $y)+ (i64.const -1)+ ))+ (drop (i32.gt_s+ (local.get $x)+ (i32.const -1)+ ))+ (drop (i64.gt_s+ (local.get $y)+ (i64.const -1)+ ))+ (drop (i64.extend_i32_s+ (i64.gt_u+ (i64.const 0)+ (i64.const -1)+ )+ ))+ ;; (unsigned)x <= -1 ==> 1+ (drop (i32.le_u+ (local.get $x)+ (i32.const -1)+ ))+ (drop (i64.le_u+ (local.get $y)+ (i64.const -1)+ ))+ (drop (i32.le_s+ (local.get $x)+ (i32.const -1)+ ))+ (drop (i64.le_s+ (local.get $y)+ (i64.const -1)+ ))+ ;; (unsigned)x >= -1 ==> x == -1+ (drop (i32.ge_u+ (local.get $x)+ (i32.const -1)+ ))+ (drop (i64.ge_u+ (local.get $y)+ (i64.const -1)+ ))+ ;; (unsigned)x < -1 ==> x != -1+ (drop (i32.lt_u+ (local.get $x)+ (i32.const -1)+ ))+ (drop (i64.lt_u+ (local.get $y)+ (i64.const -1)+ ))+ ;; x * -1+ (drop (i32.mul+ (local.get $x)+ (i32.const -1)+ ))+ (drop (i64.mul+ (local.get $y)+ (i64.const -1)+ ))+ (drop (f32.mul ;; skip+ (local.get $fx)+ (f32.const -1)+ ))+ (drop (f64.mul ;; skip+ (local.get $fy)+ (f64.const -1)+ ))+ ;; (unsigned)x / -1+ (drop (i32.div_u+ (local.get $x)+ (i32.const -1)+ ))+ (drop (i64.div_u+ (local.get $y)+ (i64.const -1)+ ))+ )+ (func $rhs-is-const (param $x i32) (param $y i64) (param $fx f32) (param $fy f64)+ ;; signed divs+ ;; i32(x) / -2147483648 -> x == -2147483648+ (drop (i32.div_s+ (local.get $x)+ (i32.const -2147483648)+ ))+ ;; i64(x) / -9223372036854775808 -> x == -9223372036854775808+ (drop (i64.div_s+ (local.get $y)+ (i64.const -9223372036854775808)+ ))+ ;; skip+ (drop (i64.div_s+ (local.get $y)+ (i64.const -2147483648)+ ))++ ;; unsigned divs+ ;; u32(x) / -2 => x >= -2+ (drop (i32.div_u+ (local.get $x)+ (i32.const -2)+ ))+ ;; u32(x) / -1 => x == -1+ (drop (i32.div_u+ (local.get $x)+ (i32.const -1)+ ))+ ;; u32(x) / (i32.min + 1)+ (drop (i32.div_u+ (local.get $x)+ (i32.const -2147483647)+ ))+ ;; u32(x) / i32.min => x >>> 31+ (drop (i32.div_u+ (local.get $x)+ (i32.const -2147483648)+ ))+ ;; u64(x) / -1 => u64(x == -1)+ (drop (i64.div_u+ (local.get $y)+ (i64.const -1)+ ))+ ;; u64(x) / i64.min => x >>> 63+ (drop (i64.div_u+ (local.get $y)+ (i64.const -9223372036854775808)+ ))++ ;; (unsigned)x >= 0 => i32(1)+ (drop (i32.ge_u+ (local.get $x)+ (i32.const 0)+ ))+ (drop (i64.ge_u+ (local.get $y)+ (i64.const 0)+ ))++ ;; (unsigned)x < 0 => i32(0)+ (drop (i32.lt_u+ (local.get $x)+ (i32.const 0)+ ))+ (drop (i64.lt_u+ (local.get $y)+ (i64.const 0)+ ))++ ;; (unsigned)x > 0 => x != 0+ (drop (i32.gt_u+ (local.get $x)+ (i32.const 0)+ ))+ (drop (i64.gt_u+ (local.get $y)+ (i64.const 0)+ ))++ ;; (unsigned)x <= 0 => x == 0+ (drop (i32.le_u+ (local.get $x)+ (i32.const 0)+ ))+ (drop (i64.le_u+ (local.get $y)+ (i64.const 0)+ ))++ ;; i32(x) <= 0x7fffffff => i32(1)+ (drop (i32.le_s+ (local.get $x)+ (i32.const 0x7fffffff)+ ))+ ;; i64(x) <= 0x7fffffffffffffff => i32(1)+ (drop (i64.le_s+ (local.get $y)+ (i64.const 0x7fffffffffffffff)+ ))++ ;; i32(x) >= 0x80000000 => i32(1)+ (drop (i32.ge_s+ (local.get $x)+ (i32.const 0x80000000)+ ))+ ;; i64(x) >= 0x8000000000000000 => i32(1)+ (drop (i64.ge_s+ (local.get $y)+ (i64.const 0x8000000000000000)+ ))++ ;; i32(x) < 0x80000000 => 0+ (drop (i32.lt_s+ (local.get $x)+ (i32.const 0x80000000)+ ))+ ;; i64(x) < 0x8000000000000000 => 0+ (drop (i64.lt_s+ (local.get $y)+ (i64.const 0x8000000000000000)+ ))++ ;; i32(x) > 0x7fffffff => 0+ (drop (i32.gt_s+ (local.get $x)+ (i32.const 0x7fffffff)+ ))+ ;; i64(x) > 0x7fffffffffffffff => 0+ (drop (i64.gt_s+ (local.get $y)+ (i64.const 0x7fffffffffffffff)+ ))++ ;; i32(x) < 0x7fffffff => x != 0x7fffffff+ (drop (i32.lt_s+ (local.get $x)+ (i32.const 0x7fffffff)+ ))+ ;; i64(x) < 0x7fffffffffffffff => x != 0x7fffffffffffffff+ (drop (i64.lt_s+ (local.get $y)+ (i64.const 0x7fffffffffffffff)+ ))++ ;; i32(x) > 0x80000000 => x != 0x80000000+ (drop (i32.gt_s+ (local.get $x)+ (i32.const 0x80000000)+ ))+ ;; i64(x) > 0x8000000000000000 => x != 0x8000000000000000+ (drop (i64.gt_s+ (local.get $y)+ (i64.const 0x8000000000000000)+ ))++ ;; i32(x) <= 0x80000000 => x == 0x80000000+ (drop (i32.le_s+ (local.get $x)+ (i32.const 0x80000000)+ ))+ ;; i64(x) <= 0x8000000000000000 => x == 0x8000000000000000+ (drop (i64.le_s+ (local.get $y)+ (i64.const 0x8000000000000000)+ ))++ ;; i32(x) >= 0x7fffffff => x == 0x7fffffff+ (drop (i32.ge_s+ (local.get $x)+ (i32.const 0x7fffffff)+ ))+ ;; i64(x) >= 0x7fffffffffffffff => x == 0x7fffffffffffffff+ (drop (i64.ge_s+ (local.get $y)+ (i64.const 0x7fffffffffffffff)+ ))++ ;; -x * 1 => x * -1+ (drop (f32.mul+ (f32.neg+ (local.get $fx)+ )+ (f32.const 1)+ ))+ ;; -x * -2.1 => x * 2.1+ (drop (f64.mul+ (f64.neg+ (local.get $fy)+ )+ (f64.const -2.1)+ ))+ ;; 2 * -x => x * -2+ (drop (f64.mul+ (f64.const 2)+ (f64.neg+ (local.get $fy)+ )+ ))+ ;; -x / inf => x / -inf+ (drop (f32.div+ (f32.neg+ (local.get $fx)+ )+ (f32.const inf)+ ))+ ;; -x / -0.0 => x / 0.0+ (drop (f64.div+ (f64.neg+ (local.get $fy)+ )+ (f64.const -0.0)+ ))+ ;; -x / nan => x / -nan+ (drop (f64.div+ (f64.neg+ (local.get $fy)+ )+ (f64.const nan)+ ))+ ;; 5.0 / -x => -5 / x+ (drop (f64.div+ (f64.const 5)+ (f64.neg+ (local.get $fy)+ )+ ))+ )+ (func $lhs-is-neg-one (param $x i32) (param $y i64)+ ;; -1 >> x ==> -1+ (drop (i32.shr_s+ (i32.const -1)+ (local.get $x)+ ))+ (drop (i64.shr_s+ (i64.const -1)+ (local.get $y)+ ))+ ;; rotl(-1, x) ==> -1+ (drop (i32.rotl+ (i32.const -1)+ (local.get $x)+ ))+ (drop (i64.rotl+ (i64.const -1)+ (local.get $y)+ ))+ ;; rotr(-1, x) ==> -1+ (drop (i32.rotr+ (i32.const -1)+ (local.get $x)+ ))+ (drop (i64.rotr+ (i64.const -1)+ (local.get $y)+ ))+ ;; skip+ (drop (i32.shr_s+ (i32.const -1)+ (call $ne0) ;; side effect+ ))+ ;; skip+ (drop (i32.shr_u+ (i32.const -1)+ (local.get $x)+ ))+ )+ (func $lhs-is-const (param $x i32) (param $y i64)+ ;; 0 - (x - 1)+ (drop (i32.sub+ (i32.const 0)+ (i32.sub+ (local.get $x)+ (i32.const 1)+ )+ ))+ (drop (i64.sub+ (i64.const 0)+ (i64.sub+ (local.get $y)+ (i64.const 1)+ )+ ))+ ;; -1 - (x + 1)+ (drop (i32.sub+ (i32.const -1)+ (i32.add+ (local.get $x)+ (i32.const 1)+ )+ ))+ (drop (i64.sub+ (i64.const -1)+ (i64.add+ (local.get $y)+ (i64.const 1)+ )+ ))+ ;; 1 - (2 - x)+ (drop (i32.sub+ (i32.const 1)+ (i32.sub+ (i32.const 2)+ (local.get $x)+ )+ ))+ (drop (i64.sub+ (i64.const 1)+ (i64.sub+ (i64.const 2)+ (local.get $y)+ )+ ))+ ;; 0 - (0x80000000 - x)+ (drop (i32.sub+ (i32.const 0)+ (i32.sub+ (i32.const 0x80000000)+ (local.get $x)+ )+ ))+ )+ (func $pre-combine-or (param $x i32) (param $y i32)+ (drop (i32.or+ (i32.gt_s+ (local.get $x)+ (local.get $y)+ )+ (i32.eq+ (local.get $y) ;; ordering should not stop us+ (local.get $x)+ )+ ))+ (drop (i32.or+ (i32.eq ;; ordering should not stop us+ (local.get $y)+ (local.get $x)+ )+ (i32.gt_s+ (local.get $x)+ (local.get $y)+ )+ ))+ (drop (i32.or+ (i32.gt_s+ (local.get $x)+ (local.get $y)+ )+ (i32.eq+ (local.get $x)+ (i32.const 1) ;; not equal+ )+ ))+ (drop (i32.or+ (i32.gt_s+ (local.get $x)+ (i32.const 1) ;; not equal+ )+ (i32.eq+ (local.get $x)+ (local.get $y)+ )+ ))+ (drop (i32.or+ (i32.gt_s+ (call $ne0) ;; side effects+ (local.get $y)+ )+ (i32.eq+ (call $ne0)+ (local.get $y)+ )+ ))+ (drop (i32.or+ (i32.gt_s+ (local.get $y)+ (call $ne0) ;; side effects+ )+ (i32.eq+ (local.get $y)+ (call $ne0)+ )+ ))+ )+ (func $combine-or (param $x i32) (param $y i32)+ (drop (i32.or+ (i32.gt_s+ (local.get $x)+ (local.get $y)+ )+ (i32.eq+ (local.get $x)+ (local.get $y)+ )+ ))+ ;; TODO: more stuff here+ )+ (func $select-into-arms (param $x i32) (param $y i32)+ (if+ (select+ (i32.eqz (i32.eqz (local.get $x)))+ (i32.eqz (i32.eqz (local.get $y)))+ (local.get $y)+ )+ (unreachable)+ )+ )+ (func $optimize-boolean-context (param $x i32) (param $y i32)+ ;; 0 - x ==> x+ (if+ (i32.sub+ (i32.const 0)+ (local.get $x)+ )+ (unreachable)+ )+ (drop (select+ (local.get $x)+ (local.get $y)+ (i32.sub+ (i32.const 0)+ (local.get $x)+ )+ ))+ )+ (func $optimize-relationals (param $x i32) (param $y i32) (param $X i64) (param $Y i64)+ ;; eqz(x + 0x7FFFFFFF) -> x == -2147483647+ (drop (i32.eqz+ (i32.add+ (local.get $x)+ (i32.const 0x7FFFFFFF)+ )+ ))+ ;; eqz(x + 0x80000000) -> x == -2147483648+ (drop (i32.eqz+ (i32.add+ (local.get $x)+ (i32.const 0x80000000)+ )+ ))+ ;; eqz(x + 0x80000001) -> x == 2147483647+ (drop (i32.eqz+ (i32.add+ (local.get $x)+ (i32.const 0x80000001)+ )+ ))+ ;; eqz(x - y)+ (drop (i32.eqz+ (i32.sub+ (local.get $x)+ (local.get $y)+ )+ ))+ (drop (i64.eqz+ (i64.sub+ (local.get $X)+ (local.get $Y)+ )+ ))+ ;; x - y == 0+ (drop (i32.eq+ (i32.sub+ (local.get $x)+ (local.get $y)+ )+ (i32.const 0)+ ))+ (drop (i64.eq+ (i64.sub+ (local.get $X)+ (local.get $Y)+ )+ (i64.const 0)+ ))+ ;; x - y != 0+ (drop (i32.ne+ (i32.sub+ (local.get $x)+ (local.get $y)+ )+ (i32.const 0)+ ))+ (drop (i64.ne+ (i64.sub+ (local.get $X)+ (local.get $Y)+ )+ (i64.const 0)+ ))+ ;; i32(x - y) > 0 -> x > y+ (drop (i32.gt_s+ (i32.sub+ (local.get $x)+ (local.get $y)+ )+ (i32.const 0)+ ))+ ;; i32(x - y) >= 0 -> x >= y+ (drop (i32.ge_s+ (i32.sub+ (local.get $x)+ (local.get $y)+ )+ (i32.const 0)+ ))+ ;; u32(x - y) > 0 -> x != y+ (drop (i32.gt_u+ (i32.sub+ (local.get $x)+ (local.get $y)+ )+ (i32.const 0)+ ))+ ;; u32(x - y) >= 0 -> 1+ (drop (i32.ge_u+ (i32.sub+ (local.get $x)+ (local.get $y)+ )+ (i32.const 0)+ ))+ ;; u64(x - y) >= 0 -> i32(1)+ (drop (i64.ge_u+ (i64.sub+ (local.get $X)+ (local.get $Y)+ )+ (i64.const 0)+ ))+ ;; i32(x - y) < 0 -> x < y+ (drop (i32.lt_s+ (i32.sub+ (local.get $x)+ (local.get $y)+ )+ (i32.const 0)+ ))+ ;; i32(x - y) <= 0 -> x <= y+ (drop (i32.le_s+ (i32.sub+ (local.get $x)+ (local.get $y)+ )+ (i32.const 0)+ ))+ ;; u32(x - y) < 0 -> 0+ (drop (i32.lt_u+ (i32.sub+ (local.get $x)+ (local.get $y)+ )+ (i32.const 0)+ ))+ ;; u64(x - y) < 0 -> i32(0)+ (drop (i64.lt_u+ (i64.sub+ (local.get $X)+ (local.get $Y)+ )+ (i64.const 0)+ ))+ ;; u32(x - y) <= 0 -> x == y+ (drop (i32.le_u+ (i32.sub+ (local.get $x)+ (local.get $y)+ )+ (i32.const 0)+ ))+ ;; i32(x - 0x80000000) == 0 -> x == 0x80000000+ (drop (i32.eq+ (i32.sub+ (local.get $x)+ (i32.const 0x80000000)+ )+ (i32.const 0)+ ))+ ;; i32(x - 0x80000000) != 0 -> x == 0x80000000+ (drop (i32.ne+ (i32.sub+ (local.get $x)+ (i32.const 0x80000000)+ )+ (i32.const 0)+ ))+ ;; i32(x - { 0x80000000 }) < 0 -> skip+ (drop (i32.lt_s+ (i32.sub+ (local.get $x)+ (i32.const 0x80000000)+ )+ (i32.const 0)+ ))+ ;; i32(x - { 0x80000000 }) >= 0 -> skip+ (drop (i32.ge_s+ (i32.sub+ (local.get $x)+ (i32.const 0x80000000)+ )+ (i32.const 0)+ ))+ ;; i32(x - { 0x80000000 }) > 0 -> skip+ (drop (i32.gt_s+ (i32.sub+ (local.get $x)+ (block (result i32)+ (i32.const 0x80000000)+ )+ )+ (i32.const 0)+ ))+ ;; i32(x - { 0x80000000 }) <= 0 -> skip+ (drop (i32.gt_s+ (i32.sub+ (local.get $x)+ (block (result i32)+ (i32.const 0x80000000)+ )+ )+ (i32.const 0)+ ))+ )+ (func $unsigned-context (param $x i32) (param $y i64)+ (drop (i32.div_s+ (i32.and+ (local.get $x)+ (i32.const 0x7fffffff)+ )+ (i32.const 3)+ ))+ (drop (i32.div_s+ (i32.and+ (local.get $x)+ (i32.const 0x7fffffff)+ )+ (i32.const -3) ;; skip+ ))+ (drop (i32.div_s+ (i32.and+ (local.get $x)+ (i32.const 0x7fffffff)+ )+ (i32.const 0x80000000) ;; skip+ ))+ (drop (i64.div_s+ (i64.and+ (local.get $y)+ (i64.const 0x7fffffffffffffff)+ )+ (i64.const 2)+ ))+ (drop (i64.div_s+ (i64.and+ (local.get $y)+ (i64.const 0x7fffffffffffffff)+ )+ (i64.const -1) ;; skip+ ))+ (drop (i32.rem_s+ (i32.and+ (local.get $x)+ (i32.const 0x7fffffff)+ )+ (i32.const 3)+ ))+ (drop (i32.shr_s+ (i32.and+ (local.get $x)+ (i32.const 0x7fffffff)+ )+ (i32.const 7)+ ))+ (drop (i32.ge_s+ (i32.and+ (local.get $x)+ (i32.const 0x7fffffff)+ )+ (i32.const 7)+ ))+ (drop (i32.ge_s+ (i32.and+ (local.get $x)+ (i32.const 0x7fffffff)+ )+ (i32.const -7) ;; skip+ ))+ )+ (func $optimize-float-mul-by-two (param $0 f64) (param $1 f32)+ (drop (f64.mul+ (local.get $0)+ (f64.const 2)+ ))+ (drop (f32.mul+ (local.get $1)+ (f32.const 2)+ ))++ (drop (f64.mul+ (call $tee-with-unreachable-value) ;; side effect+ (f64.const 2)+ ))+ (drop (f64.mul+ (f64.neg (local.get $0)) ;; complex expression+ (f64.const 2)+ ))+ )+ (func $duplicate-elimination (param $x i32) (param $y i32) (param $z i32) (param $w f64)+ ;; unary+ (drop (f64.abs (f64.abs (local.get $w))))+ (drop (f64.ceil (f64.ceil (local.get $w))))+ (drop (f64.floor (f64.floor (local.get $w))))+ (drop (f64.trunc (f64.trunc (local.get $w))))+ (drop (f64.nearest (f64.nearest (local.get $w))))++ (drop (f64.nearest (f64.trunc (local.get $w)))) ;; skip+ (drop (f64.trunc (f64.nearest (local.get $w)))) ;; skip++ (drop (f64.neg (f64.neg (local.get $w))))+ (drop (f64.neg (f64.neg (f64.neg (local.get $w)))))+ (drop (f64.neg (f64.neg (f64.neg (f64.neg (local.get $w))))))++ (drop (i32.eqz (i32.eqz (local.get $x)))) ;; skip+ (drop (i32.eqz (i32.eqz (i32.eqz (local.get $x)))))+ (drop (i32.eqz (i32.eqz (i64.eqz (i64.const 1)))))+ (drop (i32.eqz (i32.eqz (i32.ne (local.get $x) (i32.const 2)))))++ (drop (i32.eqz+ (i32.eqz+ (i32.and+ (local.get $x)+ (i32.const 1)+ )+ )+ ))++ ;; binary+ ;; ((signed)x % y) % y+ (drop (i32.rem_s+ (i32.rem_s+ (local.get $x)+ (local.get $y)+ )+ (local.get $y)+ ))+ ;; ((unsigned)x % y) % y+ (drop (i32.rem_u+ (i32.rem_u+ (local.get $x)+ (local.get $y)+ )+ (local.get $y)+ ))+ ;; 0 - (0 - y)+ (drop (i32.sub+ (i32.const 0)+ (i32.sub+ (i32.const 0)+ (local.get $y)+ )+ ))+ ;; x - (x - y)+ (drop (i32.sub+ (local.get $x)+ (i32.sub+ (local.get $x)+ (local.get $y)+ )+ ))+ ;; y - (x - y) - skip+ (drop (i32.sub+ (local.get $y)+ (i32.sub+ (local.get $x)+ (local.get $y)+ )+ ))+ ;; x ^ (x ^ y)+ (drop (i32.xor+ (local.get $x)+ (i32.xor+ (local.get $x)+ (local.get $y)+ )+ ))+ ;; x ^ (y ^ x)+ (drop (i32.xor+ (local.get $x)+ (i32.xor+ (local.get $y)+ (local.get $x)+ )+ ))+ ;; (x ^ y) ^ x+ (drop (i32.xor+ (i32.xor+ (local.get $x)+ (local.get $y)+ )+ (local.get $x)+ ))+ ;; (y ^ x) ^ x+ (drop (i32.xor+ (i32.xor+ (local.get $y)+ (local.get $x)+ )+ (local.get $x)+ ))+ ;; x ^ (x ^ x)+ (drop (i32.xor+ (local.get $x)+ (i32.xor+ (local.get $x)+ (local.get $x)+ )+ ))+ ;; x & (x & y)+ (drop (i32.and+ (local.get $x)+ (i32.and+ (local.get $x)+ (local.get $y)+ )+ ))+ ;; x & (y & x)+ (drop (i32.and+ (local.get $x)+ (i32.and+ (local.get $y)+ (local.get $x)+ )+ ))+ ;; (x & y) & x+ (drop (i32.and+ (i32.and+ (local.get $x)+ (local.get $y)+ )+ (local.get $x)+ ))+ ;; (y & x) & x+ (drop (i32.and+ (i32.and+ (local.get $y)+ (local.get $x)+ )+ (local.get $x)+ ))+ ;; x | (x | y)+ (drop (i32.or+ (local.get $x)+ (i32.or+ (local.get $x)+ (local.get $y)+ )+ ))+ ;; x | (y | x)+ (drop (i32.or+ (local.get $x)+ (i32.or+ (local.get $y)+ (local.get $x)+ )+ ))+ ;; (x | y) | x+ (drop (i32.or+ (i32.or+ (local.get $x)+ (local.get $y)+ )+ (local.get $x)+ ))+ ;; (y | x) | x+ (drop (i32.or+ (i32.or+ (local.get $y)+ (local.get $x)+ )+ (local.get $x)+ ))+ ;; (y | x) | z - skip+ (drop (i32.or+ (i32.or+ (local.get $y)+ (local.get $x)+ )+ (local.get $z)+ ))+ ;; (z | x) | y - skip+ (drop (i32.or+ (i32.or+ (local.get $z)+ (local.get $x)+ )+ (local.get $y)+ ))+ ;; (SE() | x) | x+ (drop (i32.or+ (i32.or+ (call $ne0) ;; side effect+ (local.get $x)+ )+ (local.get $x)+ ))+ ;; (x | SE()) | SE() - skip+ (drop (i32.or+ (i32.or+ (local.get $x)+ (call $ne0) ;; side effect+ )+ (call $ne0) ;; side effect+ ))+ ;; x | (SE() | x)+ (drop (i32.or+ (local.get $x)+ (i32.or+ (local.get $x)+ (call $ne0) ;; side effect+ )+ ))+ ;; SE() | (x | SE()) - skip+ (drop (i32.or+ (call $ne0) ;; side effect+ (i32.or+ (call $ne0) ;; side effect+ (local.get $x)+ )+ ))+ ;; (y % x) % y - skip+ (drop (i32.rem_s+ (i32.rem_s+ (local.get $y)+ (local.get $x)+ )+ (local.get $y)+ ))+ ;; y % (x % y) - skip+ (drop (i32.rem_u+ (local.get $y)+ (i32.rem_u+ (local.get $x)+ (local.get $y)+ )+ ))+ ;; x | (y | x) where x and y cannot be reordered - skip+ (drop+ (i32.or+ (local.get $x)+ (i32.or+ (local.tee $x+ (i32.const 1)+ )+ (local.get $x)+ )+ )+ )+ (drop+ (i32.or+ (i32.or+ (local.get $x)+ (local.tee $x+ (i32.const 1)+ )+ )+ (local.get $x)+ )+ )+ ;; x ^ (y ^ x) where x and y cannot be reordered - skip+ (drop+ (i32.xor+ (local.get $x)+ (i32.xor+ (local.tee $x+ (i32.const 1)+ )+ (local.get $x)+ )+ )+ )+ (drop+ (i32.xor+ (i32.xor+ (local.get $x)+ (local.tee $x+ (i32.const 1)+ )+ )+ (local.get $x)+ )+ )+ )+ (func $optimize-shifts (param $x i32) (param $y i32) (param $z i64) (param $w i64)+ ;; i32+ (drop (i32.shl+ (local.get $x)+ (i32.const 32)+ ))+ (drop (i32.shr_s+ (local.get $x)+ (i32.const 32)+ ))+ (drop (i32.shr_u+ (local.get $x)+ (i32.const 64)+ ))+ (drop (i32.rotl+ (local.get $x)+ (i32.const 64)+ ))+ (drop (i32.rotr+ (local.get $x)+ (i32.const 64)+ ))+ ;; i64+ (drop (i64.shl+ (local.get $z)+ (i64.const 64)+ ))+ (drop (i64.shr_s+ (local.get $z)+ (i64.const 64)+ ))+ (drop (i64.shr_u+ (local.get $z)+ (i64.const 128)+ ))+ (drop (i64.rotl+ (local.get $z)+ (i64.const 128)+ ))+ (drop (i64.rotr+ (local.get $z)+ (i64.const 128)+ ))++ ;; i32+ (drop (i32.shl+ (local.get $x)+ (i32.and+ (local.get $y)+ (i32.const 31)+ )+ ))+ (drop (i32.shl+ (local.get $x)+ (i32.and+ (local.get $y)+ (i32.const 63)+ )+ ))+ (drop (i32.shr_s+ (local.get $x)+ (i32.and+ (local.get $y)+ (i32.const 31)+ )+ ))+ (drop (i32.shr_u+ (local.get $x)+ (i32.and+ (local.get $y)+ (i32.const 31)+ )+ ))+ ;; i64+ (drop (i64.shl+ (local.get $z)+ (i64.and+ (local.get $w)+ (i64.const 63)+ )+ ))+ (drop (i64.shl+ (local.get $z)+ (i64.and+ (local.get $w)+ (i64.const 127)+ )+ ))+ (drop (i64.shr_s+ (local.get $z)+ (i64.and+ (local.get $w)+ (i64.const 63)+ )+ ))+ (drop (i64.shr_u+ (local.get $z)+ (i64.and+ (local.get $w)+ (i64.const 63)+ )+ ))+ ;; i32(x) >> (y & 32) -> x+ (drop (i32.shr_u+ (local.get $x)+ (i32.and+ (local.get $y)+ (i32.const 32)+ )+ ))+ ;; i64(x) >> (y & 64) -> x+ (drop (i64.shr_u+ (local.get $z)+ (i64.and+ (local.get $w)+ (i64.const 128)+ )+ ))++ ;; skip+ (drop (i64.shl+ (local.get $z)+ (i64.and+ (local.get $w)+ (i64.const 32)+ )+ ))+ ;; skip+ (drop (i64.shr_u+ (local.get $z)+ (i64.and+ (local.get $w)+ (i64.const 31)+ )+ ))+ )+ (func $optimize-float-points (param $x0 f64) (param $x1 f64) (param $y0 f32) (param $y1 f32)+ ;; abs(x) * abs(x) ==> x * x+ (drop (f64.mul+ (f64.abs (local.get $x0))+ (f64.abs (local.get $x0))+ ))+ (drop (f32.mul+ (f32.abs (local.get $y0))+ (f32.abs (local.get $y0))+ ))+ (drop (f64.mul+ (f64.abs (f64.add (local.get $x0) (local.get $x1)))+ (f64.abs (f64.add (local.get $x0) (local.get $x1)))+ ))++ ;; abs(x) * abs(y) ==> abs(x * y)+ (drop (f64.mul+ (f64.abs (local.get $x0))+ (f64.abs (local.get $x1))+ ))+ (drop (f32.mul+ (f32.abs (local.get $y1))+ (f32.abs (local.get $y0))+ ))++ (drop (f64.mul+ (f64.abs (local.get $x0))+ (f64.abs (f64.const 0)) ;; skip+ ))+ (drop (f32.mul+ (f32.abs (f32.const 0)) ;; skip+ (f32.abs (local.get $y0))+ ))+ (drop (f64.mul+ (f64.abs (f64.add (local.get $x0) (local.get $x1)))+ (f64.abs (f64.add (local.get $x0) (local.get $x0)))+ ))+++ ;; abs(-x) ==> abs(x)+ (drop (f64.abs+ (f64.neg (local.get $x0))+ ))+ (drop (f32.abs+ (f32.neg (local.get $y0))+ ))++ ;; abs(0 - x) ==> skip for non-fast math+ (drop (f64.abs+ (f64.sub+ (f64.const 0)+ (local.get $x0)+ )+ ))+ (drop (f32.abs+ (f32.sub+ (f32.const 0)+ (local.get $y0)+ )+ ))++ ;; abs(x) / abs(x) ==> x / x+ (drop (f64.div+ (f64.abs (local.get $x0))+ (f64.abs (local.get $x0))+ ))+ (drop (f32.div+ (f32.abs (local.get $y0))+ (f32.abs (local.get $y0))+ ))+ (drop (f64.div+ (f64.abs (f64.add (local.get $x0) (local.get $x1)))+ (f64.abs (f64.add (local.get $x0) (local.get $x1)))+ ))++ ;; abs(x) / abs(y) ==> abs(x / y)+ (drop (f64.div+ (f64.abs (local.get $x0))+ (f64.abs (local.get $x1))+ ))+ (drop (f32.div+ (f32.abs (local.get $y1))+ (f32.abs (local.get $y0))+ ))++ ;; abs(x * x) ==> x * x+ (drop (f64.abs+ (f64.mul+ (local.get $x0)+ (local.get $x0)+ )+ ))+ (drop (f32.abs+ (f32.mul+ (local.get $y0)+ (local.get $y0)+ )+ ))++ ;; abs(x / x) ==> x / x+ (drop (f64.abs+ (f64.div+ (local.get $x0)+ (local.get $x0)+ )+ ))+ (drop (f32.abs+ (f32.div+ (local.get $y0)+ (local.get $y0)+ )+ ))++ (drop (f64.div+ (f64.abs (local.get $x0))+ (f64.abs (f64.const 0)) ;; skip+ ))+ (drop (f32.div+ (f32.abs (f32.const 0)) ;; skip+ (f32.abs (local.get $y0))+ ))+ (drop (f64.div+ (f64.abs (f64.add (local.get $x0) (local.get $x1)))+ (f64.abs (f64.add (local.get $x0) (local.get $x0)))+ ))+ )+)+;; atomics+(module+ (import "env" "memory" (memory $0 (shared 256 256)))+ (func $x+ (drop+ (i32.shr_s+ (i32.shl+ (i32.atomic.load8_u ;; can't be signed+ (i32.const 100)+ )+ (i32.const 24)+ )+ (i32.const 24)+ )+ )+ )+)+;; bulk memory+(module+ (memory 0)+ (func $optimize-bulk-memory-copy (param $dst i32) (param $src i32) (param $sz i32)+ (memory.copy ;; skip+ (local.get $dst)+ (local.get $dst)+ (local.get $sz)+ )++ (memory.copy ;; skip+ (local.get $dst)+ (local.get $src)+ (i32.const 0)+ )++ (memory.copy+ (local.get $dst)+ (local.get $src)+ (i32.const 1)+ )++ (memory.copy+ (local.get $dst)+ (local.get $src)+ (i32.const 2)+ )++ (memory.copy+ (local.get $dst)+ (local.get $src)+ (i32.const 3)+ )++ (memory.copy+ (local.get $dst)+ (local.get $src)+ (i32.const 4)+ )++ (memory.copy+ (local.get $dst)+ (local.get $src)+ (i32.const 5)+ )++ (memory.copy+ (local.get $dst)+ (local.get $src)+ (i32.const 6)+ )++ (memory.copy+ (local.get $dst)+ (local.get $src)+ (i32.const 7)+ )++ (memory.copy+ (local.get $dst)+ (local.get $src)+ (i32.const 8)+ )++ (memory.copy+ (local.get $dst)+ (local.get $src)+ (i32.const 16)+ )++ (memory.copy ;; skip+ (local.get $dst)+ (local.get $src)+ (local.get $sz)+ )++ (memory.copy ;; skip+ (i32.const 0)+ (i32.const 0)+ (i32.load+ (i32.const 3) ;; side effect+ )+ )+ )+)+;; reference types+(module+ ;; These functions test if an `if` with subtyped arms is correctly folded+ ;; 1. if its `ifTrue` and `ifFalse` arms are identical (can fold)+ (func $if-arms-subtype-fold (result anyref)+ (if (result anyref)+ (i32.const 0)+ (ref.null extern)+ (ref.null extern)+ )+ )+ ;; 2. if its `ifTrue` and `ifFalse` arms are not identical (cannot fold)+ (func $if-arms-subtype-nofold (result anyref)+ (if (result anyref)+ (i32.const 0)+ (ref.null extern)+ (ref.null func)+ )+ )+)+;; sign-extensions+(module+ (func $duplicate-elimination (param $x i32) (param $y i32) (param $z i32) (param $w f64)+ (drop (i32.extend8_s (i32.extend8_s (local.get $x))))+ (drop (i32.extend16_s (i32.extend16_s (local.get $x))))+ )+)+;; exceptions+(module+ (func $test+ (if+ (try (result i32)+ (do+ (i32.eqz+ (i32.eqz+ (i32.const 123)+ )+ )+ )+ (catch+ (drop+ (pop exnref)+ )+ (i32.eqz+ (i32.eqz+ (i32.const 456)+ )+ )+ )+ )+ (nop)+ )+ )+)+;; typed function references+(module+ (type $i32-i32 (func (param i32) (result i32)))+ ;; this function has a reference parameter. we analyze parameters, and should+ ;; not be confused by a type that has no bit size, in particular. this test+ ;; just verifies that we do not crash on that.+ (func $call_from-param (param $f (ref null $i32-i32)) (result i32)+ (unreachable) ) )
+ binaryen/test/passes/optimize-instructions_fuzz-exec.txt view
@@ -0,0 +1,383 @@+[fuzz-exec] calling test32+[LoggingExternalInterface logging nan:0x400000]+[LoggingExternalInterface logging nan:0x400000]+[LoggingExternalInterface logging nan:0x400000]+[LoggingExternalInterface logging nan:0x400000]+[LoggingExternalInterface logging nan:0x7fff82]+[LoggingExternalInterface logging nan:0x400000]+[LoggingExternalInterface logging nan:0x400000]+[fuzz-exec] calling test64+[LoggingExternalInterface logging nan:0x8000000000000]+[LoggingExternalInterface logging nan:0x8000000000000]+[LoggingExternalInterface logging nan:0x8000000000000]+[LoggingExternalInterface logging nan:0x8000000000000]+[LoggingExternalInterface logging nan:0xfffffffffff82]+[LoggingExternalInterface logging nan:0x8000000000000]+[LoggingExternalInterface logging nan:0x8000000000000]+[fuzz-exec] calling just-one-nan+[LoggingExternalInterface logging nan:0x400000]+[LoggingExternalInterface logging nan:0x400000]+[LoggingExternalInterface logging nan:0x400000]+[LoggingExternalInterface logging nan:0x400000]+[LoggingExternalInterface logging nan:0x400000]+[LoggingExternalInterface logging nan:0x400000]+[fuzz-exec] calling ignore+[LoggingExternalInterface logging nan:0x400000]+[LoggingExternalInterface logging nan:0x400000]+[LoggingExternalInterface logging nan:0x400000]+[LoggingExternalInterface logging nan:0x400000]+(module+ (type $none_=>_none (func))+ (type $f32_=>_none (func (param f32)))+ (type $f64_=>_none (func (param f64)))+ (import "fuzzing-support" "log-f32" (func $logf32 (param f32)))+ (import "fuzzing-support" "log-f64" (func $logf64 (param f64)))+ (export "test32" (func $0))+ (export "test64" (func $1))+ (export "just-one-nan" (func $2))+ (export "ignore" (func $3))+ (func $0+ (call $logf32+ (f32.add+ (f32.const -nan:0x7fff82)+ (f32.neg+ (f32.const -nan:0x7ff622)+ )+ )+ )+ (call $logf32+ (f32.sub+ (f32.const -nan:0x7fff82)+ (f32.neg+ (f32.const -nan:0x7ff622)+ )+ )+ )+ (call $logf32+ (f32.mul+ (f32.const -nan:0x7fff82)+ (f32.neg+ (f32.const -nan:0x7ff622)+ )+ )+ )+ (call $logf32+ (f32.div+ (f32.const nan:0x7fff82)+ (f32.const -nan:0x7ff622)+ )+ )+ (call $logf32+ (f32.copysign+ (f32.const -nan:0x7fff82)+ (f32.neg+ (f32.const -nan:0x7ff622)+ )+ )+ )+ (call $logf32+ (f32.min+ (f32.const -nan:0x7fff82)+ (f32.neg+ (f32.const -nan:0x7ff622)+ )+ )+ )+ (call $logf32+ (f32.max+ (f32.const -nan:0x7fff82)+ (f32.neg+ (f32.const -nan:0x7ff622)+ )+ )+ )+ )+ (func $1+ (call $logf64+ (f64.add+ (f64.const -nan:0xfffffffffff82)+ (f64.neg+ (f64.const -nan:0xfffffffffa622)+ )+ )+ )+ (call $logf64+ (f64.sub+ (f64.const -nan:0xfffffffffff82)+ (f64.neg+ (f64.const -nan:0xfffffffffa622)+ )+ )+ )+ (call $logf64+ (f64.mul+ (f64.const -nan:0xfffffffffff82)+ (f64.neg+ (f64.const -nan:0xfffffffffa622)+ )+ )+ )+ (call $logf64+ (f64.div+ (f64.const nan:0xfffffffffff82)+ (f64.const -nan:0xfffffffffa622)+ )+ )+ (call $logf64+ (f64.copysign+ (f64.const -nan:0xfffffffffff82)+ (f64.neg+ (f64.const -nan:0xfffffffffa622)+ )+ )+ )+ (call $logf64+ (f64.min+ (f64.const -nan:0xfffffffffff82)+ (f64.neg+ (f64.const -nan:0xfffffffffa622)+ )+ )+ )+ (call $logf64+ (f64.max+ (f64.const -nan:0xfffffffffff82)+ (f64.neg+ (f64.const -nan:0xfffffffffa622)+ )+ )+ )+ )+ (func $2+ (call $logf32+ (f32.add+ (f32.neg+ (f32.const -nan:0x7ff622)+ )+ (f32.const 0)+ )+ )+ (call $logf32+ (f32.add+ (f32.const -nan:0x7ff622)+ (f32.neg+ (f32.const 0)+ )+ )+ )+ (call $logf32+ (f32.add+ (f32.neg+ (f32.const -nan:0x7ff622)+ )+ (f32.const -0)+ )+ )+ (call $logf32+ (f32.add+ (f32.const -nan:0x7ff622)+ (f32.neg+ (f32.const -0)+ )+ )+ )+ (call $logf32+ (f32.add+ (f32.neg+ (f32.const nan:0x7ff622)+ )+ (f32.const 0)+ )+ )+ (call $logf32+ (f32.add+ (f32.const nan:0x7ff622)+ (f32.neg+ (f32.const 0)+ )+ )+ )+ )+ (func $3+ (call $logf32+ (f32.div+ (f32.const -0)+ (f32.const 0)+ )+ )+ (call $logf32+ (f32.div+ (f32.const 0)+ (f32.const 0)+ )+ )+ (call $logf32+ (f32.div+ (f32.const -0)+ (f32.const -0)+ )+ )+ (call $logf32+ (f32.div+ (f32.const 0)+ (f32.const -0)+ )+ )+ )+)+[fuzz-exec] calling test32+[LoggingExternalInterface logging nan:0x400000]+[LoggingExternalInterface logging nan:0x400000]+[LoggingExternalInterface logging nan:0x400000]+[LoggingExternalInterface logging nan:0x400000]+[LoggingExternalInterface logging nan:0x7fff82]+[LoggingExternalInterface logging nan:0x400000]+[LoggingExternalInterface logging nan:0x400000]+[fuzz-exec] calling test64+[LoggingExternalInterface logging nan:0x8000000000000]+[LoggingExternalInterface logging nan:0x8000000000000]+[LoggingExternalInterface logging nan:0x8000000000000]+[LoggingExternalInterface logging nan:0x8000000000000]+[LoggingExternalInterface logging nan:0xfffffffffff82]+[LoggingExternalInterface logging nan:0x8000000000000]+[LoggingExternalInterface logging nan:0x8000000000000]+[fuzz-exec] calling just-one-nan+[LoggingExternalInterface logging nan:0x400000]+[LoggingExternalInterface logging nan:0x400000]+[LoggingExternalInterface logging nan:0x400000]+[LoggingExternalInterface logging nan:0x400000]+[LoggingExternalInterface logging nan:0x400000]+[LoggingExternalInterface logging nan:0x400000]+[fuzz-exec] calling ignore+[LoggingExternalInterface logging nan:0x400000]+[LoggingExternalInterface logging nan:0x400000]+[LoggingExternalInterface logging nan:0x400000]+[LoggingExternalInterface logging nan:0x400000]+[fuzz-exec] calling foo+[LoggingExternalInterface logging 1]+[LoggingExternalInterface logging 1]+[LoggingExternalInterface logging 0]+[fuzz-exec] calling do-shift+[LoggingExternalInterface logging -64]+[fuzz-exec] calling call-compare-maybe-signed-eq+[fuzz-exec] note result: call-compare-maybe-signed-eq => 0+[fuzz-exec] calling call-compare-maybe-signed-ne+[fuzz-exec] note result: call-compare-maybe-signed-ne => 1+(module+ (type $i32_=>_none (func (param i32)))+ (type $none_=>_none (func))+ (type $none_=>_i32 (func (result i32)))+ (type $i32_=>_i32 (func (param i32) (result i32)))+ (import "fuzzing-support" "log-i32" (func $log (param i32)))+ (export "foo" (func $1))+ (export "do-shift" (func $3))+ (export "call-compare-maybe-signed-eq" (func $5))+ (export "call-compare-maybe-signed-ne" (func $7))+ (func $signed-comparison-to-unsigned+ (call $log+ (block (result i32)+ (drop+ (i32.const -25749)+ )+ (i32.const 0)+ )+ )+ (call $log+ (block (result i32)+ (drop+ (i32.const -25749)+ )+ (i32.const 0)+ )+ )+ (call $log+ (block (result i32)+ (drop+ (i32.const -25749)+ )+ (i32.const 1)+ )+ )+ )+ (func $1 (param $0 i32)+ (call $log+ (i32.le_s+ (i32.sub+ (i32.const 8)+ (block $label$1 (result i32)+ (i32.const -2147483648)+ )+ )+ (i32.const 0)+ )+ )+ (call $log+ (i32.le_s+ (i32.const -2147483640)+ (i32.const 0)+ )+ )+ (call $log+ (i32.eq+ (i32.const 8)+ (i32.const -2147483648)+ )+ )+ )+ (func $shift (param $0 i32)+ (call $log+ (i32.shr_s+ (i32.shl+ (i32.shr_s+ (i32.shl+ (local.get $0)+ (i32.const 24)+ )+ (i32.const 24)+ )+ (i32.const 30)+ )+ (i32.const 24)+ )+ )+ )+ (func $3+ (call $shift+ (i32.const 65419)+ )+ )+ (func $compare-maybe-signed-eq (param $0 i32) (result i32)+ (drop+ (local.get $0)+ )+ (i32.const 0)+ )+ (func $5 (result i32)+ (call $compare-maybe-signed-eq+ (i32.const 128)+ )+ )+ (func $compare-maybe-signed-ne (param $0 i32) (result i32)+ (drop+ (local.get $0)+ )+ (i32.const 1)+ )+ (func $7 (result i32)+ (call $compare-maybe-signed-ne+ (i32.const 128)+ )+ )+)+[fuzz-exec] calling foo+[LoggingExternalInterface logging 1]+[LoggingExternalInterface logging 1]+[LoggingExternalInterface logging 0]+[fuzz-exec] calling do-shift+[LoggingExternalInterface logging -64]+[fuzz-exec] calling call-compare-maybe-signed-eq+[fuzz-exec] note result: call-compare-maybe-signed-eq => 0+[fuzz-exec] calling call-compare-maybe-signed-ne+[fuzz-exec] note result: call-compare-maybe-signed-ne => 1+[fuzz-exec] comparing call-compare-maybe-signed-eq+[fuzz-exec] comparing call-compare-maybe-signed-ne
+ binaryen/test/passes/optimize-instructions_fuzz-exec.wast view
@@ -0,0 +1,352 @@+(module+ (import "fuzzing-support" "log-f32" (func $logf32 (param f32)))+ (import "fuzzing-support" "log-f64" (func $logf64 (param f64)))+ (func "test32"+ (call $logf32+ (f32.add+ (f32.const -nan:0xffff82)+ (f32.neg+ (f32.const -nan:0xfff622)+ )+ )+ )+ (call $logf32+ (f32.sub+ (f32.const -nan:0xffff82)+ (f32.neg+ (f32.const -nan:0xfff622)+ )+ )+ )+ (call $logf32+ (f32.mul+ (f32.const -nan:0xffff82)+ (f32.neg+ (f32.const -nan:0xfff622)+ )+ )+ )+ (call $logf32+ (f32.div+ (f32.const -nan:0xffff82)+ (f32.neg+ (f32.const -nan:0xfff622)+ )+ )+ )+ (call $logf32+ (f32.copysign+ (f32.const -nan:0xffff82)+ (f32.neg+ (f32.const -nan:0xfff622)+ )+ )+ )+ (call $logf32+ (f32.min+ (f32.const -nan:0xffff82)+ (f32.neg+ (f32.const -nan:0xfff622)+ )+ )+ )+ (call $logf32+ (f32.max+ (f32.const -nan:0xffff82)+ (f32.neg+ (f32.const -nan:0xfff622)+ )+ )+ )+ )+ (func "test64"+ (call $logf64+ (f64.add+ (f64.const -nan:0xfffffffffff82)+ (f64.neg+ (f64.const -nan:0xfffffffffa622)+ )+ )+ )+ (call $logf64+ (f64.sub+ (f64.const -nan:0xfffffffffff82)+ (f64.neg+ (f64.const -nan:0xfffffffffa622)+ )+ )+ )+ (call $logf64+ (f64.mul+ (f64.const -nan:0xfffffffffff82)+ (f64.neg+ (f64.const -nan:0xfffffffffa622)+ )+ )+ )+ (call $logf64+ (f64.div+ (f64.const -nan:0xfffffffffff82)+ (f64.neg+ (f64.const -nan:0xfffffffffa622)+ )+ )+ )+ (call $logf64+ (f64.copysign+ (f64.const -nan:0xfffffffffff82)+ (f64.neg+ (f64.const -nan:0xfffffffffa622)+ )+ )+ )+ (call $logf64+ (f64.min+ (f64.const -nan:0xfffffffffff82)+ (f64.neg+ (f64.const -nan:0xfffffffffa622)+ )+ )+ )+ (call $logf64+ (f64.max+ (f64.const -nan:0xfffffffffff82)+ (f64.neg+ (f64.const -nan:0xfffffffffa622)+ )+ )+ )+ )+ (func "just-one-nan"+ (call $logf32+ (f32.add+ (f32.const 0)+ (f32.neg+ (f32.const -nan:0xfff622)+ )+ )+ )+ (call $logf32+ (f32.add+ (f32.const -nan:0xfff622)+ (f32.neg+ (f32.const 0)+ )+ )+ )+ (call $logf32+ (f32.add+ (f32.const -0)+ (f32.neg+ (f32.const -nan:0xfff622)+ )+ )+ )+ (call $logf32+ (f32.add+ (f32.const -nan:0xfff622)+ (f32.neg+ (f32.const -0)+ )+ )+ )+ (call $logf32+ (f32.add+ (f32.const 0)+ (f32.neg+ (f32.const nan:0xfff622)+ )+ )+ )+ (call $logf32+ (f32.add+ (f32.const nan:0xfff622)+ (f32.neg+ (f32.const 0)+ )+ )+ )+ )+ (func "ignore"+ ;; none of these are nan inputs, so the interpreter must not change the sign+ (call $logf32+ (f32.div+ (f32.const 0)+ (f32.neg+ (f32.const 0)+ )+ )+ )+ (call $logf32+ (f32.div+ (f32.const -0)+ (f32.neg+ (f32.const 0)+ )+ )+ )+ (call $logf32+ (f32.div+ (f32.const 0)+ (f32.neg+ (f32.const -0)+ )+ )+ )+ (call $logf32+ (f32.div+ (f32.const -0)+ (f32.neg+ (f32.const -0)+ )+ )+ )+ )+)+(module+ (import "fuzzing-support" "log-i32" (func $log (param i32)))+ (func $signed-comparison-to-unsigned+ (call $log+ (i32.eq ;; should be false+ (i32.shr_s ;; 0x0000006b after the sign-extend+ (i32.shl+ (i32.const -25749) ;; 0xffff9b6b+ (i32.const 24)+ )+ (i32.const 24)+ )+ (i32.const -149) ;; 0xffffff6b - high bits are set, but not sign bit+ )+ )+ ;; the same, with mixed high bits. mixed bits mean the two sides can never be+ ;; equal, so the eq is always false+ (call $log+ (i32.eq+ (i32.shr_s+ (i32.shl+ (i32.const -25749)+ (i32.const 24)+ )+ (i32.const 24)+ )+ (i32.const 0xffffeb)+ )+ )+ ;; the same, with !=, so the result is always true+ (call $log+ (i32.ne+ (i32.shr_s+ (i32.shl+ (i32.const -25749)+ (i32.const 24)+ )+ (i32.const 24)+ )+ (i32.const 0xffffeb)+ )+ )+ )+ (func "foo" (param $0 i32)+ ;; 8 - 0x80000000 < 0+ ;;+ ;; is not the same as+ ;;+ ;; 8 < 0x80000000+ ;;+ ;; because of overflow. the former is true, the latter is false+ (call $log+ (i32.le_s+ (i32.sub+ (i32.const 8)+ (block $label$1 (result i32) ;; the block prevents us from optimizing this+ ;; which would avoid the issue. a global or a+ ;; call would do the same, all would make the+ ;; value only visible at runtime+ (i32.const 0x80000000)+ )+ )+ (i32.const 0)+ )+ )+ ;; for comparison, without the block.+ (call $log+ (i32.le_s+ (i32.sub+ (i32.const 8)+ (i32.const 0x80000000)+ )+ (i32.const 0)+ )+ )+ ;; for comparison, what X - Y < 0 => X < Y would lead to, which has a+ ;; different value+ (call $log+ (i32.le_s+ (i32.const 8)+ (i32.const 0x80000000)+ )+ )+ )+ (func $shift (param $0 i32)+ (call $log+ ;; x << 24 >> 24 << 30 >> 24 - the extra shifts make it invalid to do the+ ;; optimization of not repeating a sign-extend. That is, this would be valid+ ;; if the 30 were replaced by a 24.+ (i32.shr_s+ (i32.shl+ (i32.shr_s+ (i32.shl+ (local.get $0)+ (i32.const 24)+ )+ (i32.const 24)+ )+ (i32.const 30)+ )+ (i32.const 24)+ )+ )+ )+ (func "do-shift"+ (call $shift+ (i32.const 65419)+ )+ )+ ;; similar, but with the value compared to having the sign bit set but no+ ;; upper bits+ (func $compare-maybe-signed-eq (param $0 i32) (result i32)+ (i32.eq+ (i32.shr_s+ (i32.shl+ (local.get $0)+ (i32.const 24)+ )+ (i32.const 24)+ )+ (i32.const 128)+ )+ )+ (func "call-compare-maybe-signed-eq" (result i32)+ (call $compare-maybe-signed-eq+ (i32.const 128)+ )+ )+ ;; the same with !=+ (func $compare-maybe-signed-ne (param $0 i32) (result i32)+ (i32.ne+ (i32.shr_s+ (i32.shl+ (local.get $0)+ (i32.const 24)+ )+ (i32.const 24)+ )+ (i32.const 128)+ )+ )+ (func "call-compare-maybe-signed-ne" (result i32)+ (call $compare-maybe-signed-ne+ (i32.const 128)+ )+ )+)
binaryen/test/passes/optimize-instructions_optimize-level=2_all-features_ignore-implicit-traps.txt view
@@ -61,14 +61,14 @@ ) ) (br_if $while-in6- (i32.lt_s+ (i32.gt_s+ (local.get $4) (local.tee $3 (i32.add (local.get $3) (i32.const 1) ) )- (local.get $4) ) ) )@@ -144,14 +144,14 @@ ) ) (br_if $while-in6- (i32.lt_s+ (i32.gt_s+ (local.get $4) (local.tee $3 (i32.add (local.get $3) (i32.const 1) ) )- (local.get $4) ) ) )@@ -226,14 +226,14 @@ ) ) (br_if $while-in6- (i32.lt_s+ (i32.gt_s+ (local.get $4) (local.tee $3 (i32.add (local.get $3) (i32.const 1) ) )- (local.get $4) ) ) )@@ -261,9 +261,9 @@ (i32.and (i32.shr_s (i32.shl- (i32.add+ (i32.sub (local.get $1)- (i32.const -1)+ (i32.const 1) ) (i32.const 24) )@@ -300,9 +300,9 @@ (i32.and (i32.shr_s (i32.shl- (i32.add+ (i32.sub (local.get $0)- (i32.const -1)+ (i32.const 1) ) (i32.const 24) )
+ binaryen/test/passes/pick-load-signs_all-features.txt view
@@ -0,0 +1,24 @@+(module+ (type $none_=>_i32 (func (result i32)))+ (memory $0 (shared 16 16))+ (func $atomics-are-always-unsigned (result i32)+ (local $0 i32)+ (drop+ (block $block (result i32)+ (local.set $0+ (i32.atomic.load16_u+ (i32.const 27)+ )+ )+ (i32.shr_s+ (i32.shl+ (local.get $0)+ (i32.const 16)+ )+ (i32.const 16)+ )+ )+ )+ (i32.const -65)+ )+)
+ binaryen/test/passes/pick-load-signs_all-features.wast view
@@ -0,0 +1,23 @@+(module+ (memory $0 (shared 16 16))+ (func $atomics-are-always-unsigned (result i32)+ (local $0 i32)+ (drop+ (block (result i32)+ (local.set $0+ (i32.atomic.load16_u ;; an atomic load cannot become signed+ (i32.const 27)+ )+ )+ (i32.shr_s+ (i32.shl+ (local.get $0)+ (i32.const 16)+ )+ (i32.const 16)+ )+ )+ )+ (i32.const -65)+ )+)
binaryen/test/passes/post-emscripten.txt view
@@ -2,83 +2,19 @@ (type $i32_f32_=>_none (func (param i32 f32))) (type $none_=>_none (func)) (type $i32_i32_f32_=>_none (func (param i32 i32 f32)))- (type $f64_f64_=>_f64 (func (param f64 f64) (result f64)))- (import "global.Math" "pow" (func $Math_pow (param f64 f64) (result f64))) (import "env" "invoke_vif" (func $invoke_vif (param i32 i32 f32))) (memory $0 256 256) (table $0 7 7 funcref)- (elem (i32.const 0) $pow2 $pow.2 $exc $other_safe $other_unsafe $deep_safe $deep_unsafe)- (func $pow2- (local $x f64)- (local $y f64)- (local $2 f64)- (local $3 f64)- (drop- (f64.mul- (local.tee $2- (f64.const 1)- )- (local.get $2)- )- )- (drop- (call $Math_pow- (f64.const 1)- (f64.const 3)- )- )- (drop- (call $Math_pow- (f64.const 2)- (f64.const 1)- )- )- (local.set $x- (f64.const 5)- )- (drop- (f64.mul- (local.get $x)- (local.get $x)- )- )- (drop- (f64.mul- (local.tee $y- (f64.const 7)- )- (local.get $y)- )- )- (drop- (f64.mul- (local.tee $3- (f64.const 8)- )- (local.get $3)- )- )- )- (func $pow.2- (drop- (f64.sqrt- (f64.const 1)- )- )- (drop- (call $Math_pow- (f64.const 1)- (f64.const 0.51)- )- )+ (elem (i32.const 0) $f1 $exc $other_safe $other_unsafe $deep_safe $deep_unsafe)+ (func $f1+ (nop) ) (func $exc (call $other_safe (i32.const 42) (f32.const 3.141590118408203) )- (call $invoke_vif- (i32.const 4)+ (call $other_unsafe (i32.const 55) (f32.const 2.1828181743621826) )@@ -86,8 +22,7 @@ (i32.const 100) (f32.const 1.1109999418258667) )- (call $invoke_vif- (i32.const 6)+ (call $deep_unsafe (i32.const 999) (f32.const 1.4140000343322754) )@@ -104,12 +39,7 @@ (nop) ) (func $other_unsafe (param $0 i32) (param $1 f32)- (drop- (call $Math_pow- (f64.const 1)- (f64.const 3)- )- )+ (nop) ) (func $deep_safe (param $0 i32) (param $1 f32) (call $other_safe@@ -134,9 +64,7 @@ (type $none_=>_none (func)) (type $i32_i32_f32_=>_none (func (param i32 i32 f32))) (type $i32_f32_=>_none (func (param i32 f32)))- (type $f64_f64_=>_f64 (func (param f64 f64) (result f64))) (import "env" "glob" (global $glob i32))- (import "global.Math" "pow" (func $Math_pow (param f64 f64) (result f64))) (import "env" "invoke_vif" (func $invoke_vif (param i32 i32 f32))) (memory $0 256 256) (table $0 7 7 funcref)@@ -156,9 +84,7 @@ (type $none_=>_none (func)) (type $i32_i32_f32_=>_none (func (param i32 i32 f32))) (type $i32_f32_=>_none (func (param i32 f32)))- (type $f64_f64_=>_f64 (func (param f64 f64) (result f64))) (import "env" "glob" (global $glob i32))- (import "global.Math" "pow" (func $Math_pow (param f64 f64) (result f64))) (import "env" "invoke_vif" (func $invoke_vif (param i32 i32 f32))) (memory $0 256 256) (table $0 7 7 funcref)
binaryen/test/passes/post-emscripten.wast view
@@ -1,83 +1,28 @@ (module (type $0 (func (param i32)))- (import "global.Math" "pow" (func $Math_pow (param f64 f64) (result f64))) (import "env" "invoke_vif" (func $invoke_vif (param i32 i32 f32))) (memory 256 256) (table 7 7 funcref)- (elem (i32.const 0) $pow2 $pow.2 $exc $other_safe $other_unsafe $deep_safe $deep_unsafe)- (func $pow2- (local $x f64)- (local $y f64)- (drop- (call $Math_pow- (f64.const 1)- (f64.const 2)- )- )- (drop- (call $Math_pow- (f64.const 1)- (f64.const 3)- )- )- (drop- (call $Math_pow- (f64.const 2)- (f64.const 1)- )- )- (local.set $x (f64.const 5))- (drop- (call $Math_pow- (local.get $x)- (f64.const 2)- )- )- (drop- (call $Math_pow- (local.tee $y (f64.const 7))- (f64.const 2)- )- )- (drop- (call $Math_pow- (f64.const 8)- (f64.const 2)- )- )- )- (func $pow.2- (drop- (call $Math_pow- (f64.const 1)- (f64.const 0.5)- )- )- (drop- (call $Math_pow- (f64.const 1)- (f64.const 0.51)- )- )- )+ (elem (i32.const 0) $f1 $exc $other_safe $other_unsafe $deep_safe $deep_unsafe)+ (func $f1) (func $exc (call $invoke_vif- (i32.const 3) ;; other_safe()+ (i32.const 2) ;; other_safe() (i32.const 42) (f32.const 3.14159) ) (call $invoke_vif- (i32.const 4) ;; other_unsafe()+ (i32.const 3) ;; other_unsafe() (i32.const 55) (f32.const 2.18281828) ) (call $invoke_vif- (i32.const 5) ;; deep_safe()+ (i32.const 4) ;; deep_safe() (i32.const 100) (f32.const 1.111) ) (call $invoke_vif- (i32.const 6) ;; deep_unsafe()+ (i32.const 5) ;; deep_unsafe() (i32.const 999) (f32.const 1.414) )@@ -90,12 +35,6 @@ (func $other_safe (param i32) (param f32) ) (func $other_unsafe (param i32) (param f32)- (drop- (call $Math_pow- (f64.const 1)- (f64.const 3)- )- ) ) (func $deep_safe (param i32) (param f32) (call $other_safe (unreachable) (unreachable))@@ -111,7 +50,6 @@ ) (module ;; non-constant base for elem (type $0 (func (param i32)))- (import "global.Math" "pow" (func $Math_pow (param f64 f64) (result f64))) (import "env" "invoke_vif" (func $invoke_vif (param i32 i32 f32))) (import "env" "glob" (global $glob i32)) ;; non-constant table offset (memory 256 256)@@ -129,7 +67,6 @@ ) (module ;; indirect call in the invoke target, which we assume might throw (type $none_=>_none (func))- (import "global.Math" "pow" (func $Math_pow (param f64 f64) (result f64))) (import "env" "invoke_vif" (func $invoke_vif (param i32 i32 f32))) (import "env" "glob" (global $glob i32)) ;; non-constant table offset (memory 256 256)
binaryen/test/passes/precompute_all-features.txt view
@@ -4,8 +4,8 @@ (type $none_=>_f64 (func (result f64))) (type $none_=>_v128 (func (result v128))) (type $i32_=>_none (func (param i32)))- (type $none_=>_i32_i64 (func (result i32 i64))) (type $none_=>_externref (func (result externref)))+ (type $none_=>_i32_i64 (func (result i32 i64))) (memory $0 512 512) (data (i32.const 0) "passive") (global $global i32 (i32.const 1))
binaryen/test/passes/print-call-graph.txt view
@@ -126,8 +126,6 @@ (elem (i32.const 0) $b0 $___stdio_close $b1 $___stdout_write $___stdio_seek $___stdio_write $b2 $_cleanup_387 $b3) (import "env" "STACKTOP" (global $STACKTOP$asm2wasm$import i32)) (import "env" "STACK_MAX" (global $STACK_MAX$asm2wasm$import i32))- (import "env" "DYNAMICTOP_PTR" (global $DYNAMICTOP_PTR$asm2wasm$import i32))- (import "env" "tempDoublePtr" (global $tempDoublePtr$asm2wasm$import i32)) (import "env" "ABORT" (global $ABORT$asm2wasm$import i32)) (import "global" "NaN" (global $nan$asm2wasm$import f64)) (import "global" "Infinity" (global $inf$asm2wasm$import f64))@@ -145,8 +143,6 @@ (import "env" "___syscall146" (func $___syscall146 (param i32 i32) (result i32))) (global $STACKTOP (mut i32) (global.get $STACKTOP$asm2wasm$import)) (global $STACK_MAX (mut i32) (global.get $STACK_MAX$asm2wasm$import))- (global $DYNAMICTOP_PTR (mut i32) (global.get $DYNAMICTOP_PTR$asm2wasm$import))- (global $tempDoublePtr (mut i32) (global.get $tempDoublePtr$asm2wasm$import)) (global $ABORT (mut i32) (global.get $ABORT$asm2wasm$import)) (global $__THREW__ (mut i32) (i32.const 0)) (global $threwValue (mut i32) (i32.const 0))
binaryen/test/passes/print-call-graph.wast view
@@ -7,8 +7,6 @@ (type $FUNCSIG$vii (func (param i32 i32))) (import "env" "STACKTOP" (global $STACKTOP$asm2wasm$import i32)) (import "env" "STACK_MAX" (global $STACK_MAX$asm2wasm$import i32))- (import "env" "DYNAMICTOP_PTR" (global $DYNAMICTOP_PTR$asm2wasm$import i32))- (import "env" "tempDoublePtr" (global $tempDoublePtr$asm2wasm$import i32)) (import "env" "ABORT" (global $ABORT$asm2wasm$import i32)) (import "global" "NaN" (global $nan$asm2wasm$import f64)) (import "global" "Infinity" (global $inf$asm2wasm$import f64))@@ -30,8 +28,6 @@ (data (global.get $memoryBase) "\05\00\00\00\00\00\00\00\00\00\00\00\01\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\01\00\00\00\02\00\00\00\b0\04\00\00\00\04\00\00\00\00\00\00\00\00\00\00\01\00\00\00\00\00\00\00\00\00\00\00\00\00\00\n\ff\ff\ff\ff\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\04") (global $STACKTOP (mut i32) (global.get $STACKTOP$asm2wasm$import)) (global $STACK_MAX (mut i32) (global.get $STACK_MAX$asm2wasm$import))- (global $DYNAMICTOP_PTR (mut i32) (global.get $DYNAMICTOP_PTR$asm2wasm$import))- (global $tempDoublePtr (mut i32) (global.get $tempDoublePtr$asm2wasm$import)) (global $ABORT (mut i32) (global.get $ABORT$asm2wasm$import)) (global $__THREW__ (mut i32) (i32.const 0)) (global $threwValue (mut i32) (i32.const 0))
binaryen/test/passes/remove-non-js-ops.txt view
@@ -6,10 +6,10 @@ (type $f64_=>_f64 (func (param f64) (result f64))) (type $i32_i32_i32_=>_none (func (param i32 i32 i32))) (type $i32_=>_none (func (param i32)))- (type $i32_i32_=>_none (func (param i32 i32)))- (type $i32_i32_i32_i32_=>_none (func (param i32 i32 i32 i32))) (type $f32_=>_none (func (param f32))) (type $f64_=>_none (func (param f64)))+ (type $i32_i32_=>_none (func (param i32 i32)))+ (type $i32_i32_i32_i32_=>_none (func (param i32 i32 i32 i32))) (type $none_=>_i32 (func (result i32))) (type $i32_i32_i32_i32_=>_i32 (func (param i32 i32 i32 i32) (result i32))) (type $i32_i32_i32_i32_i32_i32_=>_i32 (func (param i32 i32 i32 i32 i32 i32) (result i32)))@@ -103,12 +103,12 @@ ) ) (func $trunc64 (param $0 f64) (result f64)- (call $__wasm_trunc_f64+ (f64.trunc (local.get $0) ) ) (func $trunc32 (param $0 f32) (result f32)- (call $__wasm_trunc_f32+ (f32.trunc (local.get $0) ) )@@ -1108,34 +1108,6 @@ (local.get $var$0) ) (local.get $var$1)- )- )- )- (func $__wasm_trunc_f32 (param $var$0 f32) (result f32)- (select- (f32.ceil- (local.get $var$0)- )- (f32.floor- (local.get $var$0)- )- (f32.lt- (local.get $var$0)- (f32.const 0)- )- )- )- (func $__wasm_trunc_f64 (param $var$0 f64) (result f64)- (select- (f64.ceil- (local.get $var$0)- )- (f64.floor- (local.get $var$0)- )- (f64.lt- (local.get $var$0)- (f64.const 0) ) ) )
binaryen/test/passes/remove-unused-brs_enable-multivalue.txt view
@@ -1,6 +1,6 @@ (module- (type $none_=>_none (func)) (type $i32_=>_none (func (param i32)))+ (type $none_=>_none (func)) (type $none_=>_i32 (func (result i32))) (type $i32_i32_=>_i32 (func (param i32 i32) (result i32))) (type $i32_=>_i32 (func (param i32) (result i32)))@@ -2285,6 +2285,83 @@ ) ) )+ (func $selectify-even-with-condition-side-effects (param $0 i32)+ (drop+ (select+ (i32.const 1)+ (i32.const 0)+ (i32.rem_s+ (local.get $0)+ (i32.const 2)+ )+ )+ )+ )+ (func $no-selectify-when-arm-side-effects (param $0 i32)+ (drop+ (if (result i32)+ (i32.rem_s+ (local.get $0)+ (i32.const 2)+ )+ (local.tee $0+ (i32.const 1)+ )+ (i32.const 0)+ )+ )+ (drop+ (if (result i32)+ (i32.rem_s+ (local.get $0)+ (i32.const 2)+ )+ (i32.const 0)+ (local.tee $0+ (i32.const 1)+ )+ )+ )+ )+ (func $no-selectify-when-effects-invalidate (param $0 i32)+ (local $1 i32)+ (drop+ (if (result i32)+ (i32.rem_s+ (local.tee $0+ (i32.const 3)+ )+ (i32.const 2)+ )+ (local.get $0)+ (i32.const 0)+ )+ )+ (drop+ (if (result i32)+ (i32.rem_s+ (local.tee $0+ (i32.const 3)+ )+ (i32.const 2)+ )+ (i32.const 0)+ (local.get $0)+ )+ )+ (drop+ (select+ (i32.const 0)+ (local.get $1)+ (i32.rem_s+ (local.tee $0+ (i32.const 3)+ )+ (i32.const 2)+ )+ )+ )+ ) (func $if-one-side (result i32) (local $x i32) (local.set $x@@ -2329,9 +2406,8 @@ (i32.const 0) ) (func $ifs-copies-recursive (param $20 i32) (result i32)- (if- (i32.const 1)- (local.set $20+ (local.set $20+ (select (select (select (i32.const 4)@@ -2341,6 +2417,8 @@ (local.get $20) (i32.const 2) )+ (local.get $20)+ (i32.const 1) ) ) (local.get $20)@@ -2522,6 +2600,17 @@ (i32.const 6) ) )+ )+ )+ (func $no-selectify-if-condition-unreachable (result i32)+ (select+ (if (result i32)+ (unreachable)+ (i32.const 3)+ (i32.const 4)+ )+ (i32.const 1)+ (i32.const 2) ) ) )
binaryen/test/passes/remove-unused-brs_enable-multivalue.wast view
@@ -1890,6 +1890,62 @@ ) ) )+ (func $selectify-even-with-condition-side-effects (param $0 i32)+ (drop (if (result i32)+ (i32.rem_s+ (local.get $0)+ (i32.const 2)+ )+ (i32.const 1)+ (i32.const 0)+ ))+ )+ (func $no-selectify-when-arm-side-effects (param $0 i32)+ (drop (if (result i32)+ (i32.rem_s+ (local.get $0)+ (i32.const 2)+ )+ (local.tee $0 (i32.const 1))+ (i32.const 0)+ ))+ (drop (if (result i32)+ (i32.rem_s+ (local.get $0)+ (i32.const 2)+ )+ (i32.const 0)+ (local.tee $0 (i32.const 1))+ ))+ )+ (func $no-selectify-when-effects-invalidate (param $0 i32)+ (local $1 i32)+ (drop (if (result i32)+ (i32.rem_s+ (local.tee $0 (i32.const 3))+ (i32.const 2)+ )+ (local.get $0)+ (i32.const 0)+ ))+ (drop (if (result i32)+ (i32.rem_s+ (local.tee $0 (i32.const 3))+ (i32.const 2)+ )+ (i32.const 0)+ (local.get $0)+ ))+ ;; but different locals do not invalidate+ (drop (if (result i32)+ (i32.rem_s+ (local.tee $0 (i32.const 3))+ (i32.const 2)+ )+ (i32.const 0)+ (local.get $1)+ ))+ ) (func $if-one-side (result i32) (local $x i32) (local.set $x@@ -2126,6 +2182,17 @@ (i32.const 6) ) )+ )+ )+ (func $no-selectify-if-condition-unreachable (result i32)+ (select+ (if (result i32)+ (unreachable)+ (i32.const 3)+ (i32.const 4)+ )+ (i32.const 1)+ (i32.const 2) ) ) )
binaryen/test/passes/remove-unused-brs_shrink-level=1.txt view
@@ -24,13 +24,13 @@ ) ) (drop- (if (result i32)- (i32.const 1)+ (select (i32.rem_s (i32.const 11) (i32.const 12) ) (i32.const 27)+ (i32.const 1) ) ) (drop
binaryen/test/passes/remove-unused-module-elements_all-features.txt view
@@ -157,7 +157,7 @@ (local $0 i32) (local $1 i64) (drop- (i32.atomic.wait+ (memory.atomic.wait32 (local.get $0) (local.get $0) (local.get $1)@@ -170,7 +170,7 @@ (memory $0 (shared 23 256)) (export "user" (func $user)) (func $user (result i32)- (atomic.notify+ (memory.atomic.notify (i32.const 0) (i32.const 0) )
binaryen/test/passes/remove-unused-module-elements_all-features.wast view
@@ -128,7 +128,7 @@ (local $0 i32) (local $1 i64) (drop- (i32.atomic.wait+ (memory.atomic.wait32 (local.get $0) (local.get $0) (local.get $1)@@ -140,7 +140,7 @@ (memory $0 (shared 23 256)) (export "user" $user) (func $user (result i32)- (atomic.notify (i32.const 0) (i32.const 0))+ (memory.atomic.notify (i32.const 0) (i32.const 0)) ) ) (module ;; more use checks
binaryen/test/passes/remove-unused-names_code-folding_all-features.txt view
@@ -1822,9 +1822,6 @@ (block $x (try (do- (local.set $exn- (pop exnref)- ) (call $foo) (call $foo) (call $foo)
binaryen/test/passes/remove-unused-names_code-folding_all-features.wast view
@@ -1273,7 +1273,6 @@ (try (do ;; Expressions that can throw should NOT be taken out of 'try' scope.- (local.set $exn (pop exnref)) (call $foo) (call $foo) (call $foo)
binaryen/test/passes/remove-unused-names_remove-unused-brs_vacuum.txt view
@@ -10,8 +10,6 @@ (type $i32_=>_i64 (func (param i32) (result i64))) (import "env" "memory" (memory $0 256)) (import "env" "table" (table $timport$0 18 18 funcref))- (import "env" "DYNAMICTOP_PTR" (global $import$0 i32))- (import "env" "tempDoublePtr" (global $import$1 i32)) (import "env" "ABORT" (global $import$2 i32)) (import "env" "STACKTOP" (global $import$3 i32)) (import "env" "STACK_MAX" (global $import$4 i32))@@ -42,8 +40,6 @@ (import "asm2wasm" "i32s-rem" (func $import$27 (param i32 i32) (result i32))) (import "asm2wasm" "i32u-rem" (func $import$28 (param i32 i32) (result i32))) (import "asm2wasm" "i32u-div" (func $import$29 (param i32 i32) (result i32)))- (global $global$0 (mut i32) (global.get $import$0))- (global $global$1 (mut i32) (global.get $import$1)) (global $global$2 (mut i32) (global.get $import$2)) (global $global$3 (mut i32) (global.get $import$3)) (global $global$4 (mut i32) (global.get $import$4))
binaryen/test/passes/remove-unused-names_remove-unused-brs_vacuum.wast view
@@ -15,8 +15,6 @@ (type $13 (func (param i32 i32 i32 i32 i32))) (type $14 (func (param f64 i32) (result f64))) (type $15 (func (param i32 i32 i32 i32) (result i32)))- (import "env" "DYNAMICTOP_PTR" (global $import$0 i32))- (import "env" "tempDoublePtr" (global $import$1 i32)) (import "env" "ABORT" (global $import$2 i32)) (import "env" "STACKTOP" (global $import$3 i32)) (import "env" "STACK_MAX" (global $import$4 i32))@@ -49,8 +47,6 @@ (import "env" "table" (table 18 18 funcref)) (import "env" "memoryBase" (global $import$32 i32)) (import "env" "tableBase" (global $import$33 i32))- (global $global$0 (mut i32) (global.get $import$0))- (global $global$1 (mut i32) (global.get $import$1)) (global $global$2 (mut i32) (global.get $import$2)) (global $global$3 (mut i32) (global.get $import$3)) (global $global$4 (mut i32) (global.get $import$4))
binaryen/test/passes/remove-unused-nonfunction-module-elements_all-features.txt view
@@ -172,7 +172,7 @@ (local $0 i32) (local $1 i64) (drop- (i32.atomic.wait+ (memory.atomic.wait32 (local.get $0) (local.get $0) (local.get $1)@@ -185,7 +185,7 @@ (memory $0 (shared 23 256)) (export "user" (func $user)) (func $user (result i32)- (atomic.notify+ (memory.atomic.notify (i32.const 0) (i32.const 0) )
binaryen/test/passes/remove-unused-nonfunction-module-elements_all-features.wast view
@@ -128,7 +128,7 @@ (local $0 i32) (local $1 i64) (drop- (i32.atomic.wait+ (memory.atomic.wait32 (local.get $0) (local.get $0) (local.get $1)@@ -140,7 +140,7 @@ (memory $0 (shared 23 256)) (export "user" $user) (func $user (result i32)- (atomic.notify (i32.const 0) (i32.const 0))+ (memory.atomic.notify (i32.const 0) (i32.const 0)) ) ) (module ;; more use checks
binaryen/test/passes/reverse_dwarf_abbrevs.bin.txt view
@@ -120,14 +120,14 @@ (type $none_=>_none (func)) (type $i32_i32_i32_i32_i32_=>_i32 (func (param i32 i32 i32 i32 i32) (result i32))) (type $i32_i32_i64_i32_=>_i64 (func (param i32 i32 i64 i32) (result i64)))- (import "env" "memory" (memory $mimport$3 256 256))+ (import "env" "memory" (memory $mimport$0 256 256)) (data (i32.const 1024) "hello, world!\00\00\00\18\04") (data (i32.const 1048) "\05") (data (i32.const 1060) "\01") (data (i32.const 1084) "\02\00\00\00\03\00\00\00\c8\04\00\00\00\04") (data (i32.const 1108) "\01") (data (i32.const 1123) "\n\ff\ff\ff\ff")- (import "env" "__indirect_function_table" (table $timport$4 4 funcref))+ (import "env" "__indirect_function_table" (table $timport$0 4 funcref)) (elem (i32.const 1) $6 $5 $7) (import "wasi_snapshot_preview1" "fd_write" (func $fimport$0 (param i32 i32 i32 i32) (result i32))) (import "env" "emscripten_memcpy_big" (func $fimport$1 (param i32 i32 i32) (result i32)))
+ binaryen/test/passes/roundtrip_signed.bin.txt view
@@ -0,0 +1,26 @@+(module+ (type $none_=>_none (func))+ (memory $0 16 17)+ (global $global$0 (mut i32) (i32.const 10))+ (export "as-br_table-index" (func $0))+ (export "as-local.set-value" (func $0))+ (func $0+ (if+ (i32.eqz+ (global.get $global$0)+ )+ (return)+ )+ (global.set $global$0+ (i32.sub+ (global.get $global$0)+ (i32.const 1)+ )+ )+ (drop+ (i32.load+ (i32.const 0)+ )+ )+ )+)
+ binaryen/test/passes/roundtrip_signed.passes view
@@ -0,0 +1,1 @@+remove-unused-module-elements_roundtrip_vacuum_remove-unused-brs_merge-blocks_vacuum_duplicate-function-elimination
+ binaryen/test/passes/roundtrip_signed.wasm view
binary file changed (absent → 151 bytes)
binaryen/test/passes/safe-heap_disable-simd.txt view
@@ -1921,1918 +1921,6 @@ (type $i32_i32_f32_=>_none (func (param i32 i32 f32))) (type $i32_i32_=>_f32 (func (param i32 i32) (result f32))) (type $none_=>_none (func))- (import "env" "DYNAMICTOP_PTR" (global $foo i32))- (import "env" "segfault" (func $segfault))- (import "env" "alignfault" (func $alignfault))- (memory $0 1 1)- (func $SAFE_HEAP_LOAD_i32_1_1 (param $0 i32) (param $1 i32) (result i32)- (local $2 i32)- (local.set $2- (i32.add- (local.get $0)- (local.get $1)- )- )- (if- (i32.or- (i32.eq- (local.get $2)- (i32.const 0)- )- (i32.gt_u- (i32.add- (local.get $2)- (i32.const 1)- )- (i32.load- (global.get $foo)- )- )- )- (call $segfault)- )- (i32.load8_s- (local.get $2)- )- )- (func $SAFE_HEAP_LOAD_i32_1_U_1 (param $0 i32) (param $1 i32) (result i32)- (local $2 i32)- (local.set $2- (i32.add- (local.get $0)- (local.get $1)- )- )- (if- (i32.or- (i32.eq- (local.get $2)- (i32.const 0)- )- (i32.gt_u- (i32.add- (local.get $2)- (i32.const 1)- )- (i32.load- (global.get $foo)- )- )- )- (call $segfault)- )- (i32.load8_u- (local.get $2)- )- )- (func $SAFE_HEAP_LOAD_i32_2_1 (param $0 i32) (param $1 i32) (result i32)- (local $2 i32)- (local.set $2- (i32.add- (local.get $0)- (local.get $1)- )- )- (if- (i32.or- (i32.eq- (local.get $2)- (i32.const 0)- )- (i32.gt_u- (i32.add- (local.get $2)- (i32.const 2)- )- (i32.load- (global.get $foo)- )- )- )- (call $segfault)- )- (i32.load16_s align=1- (local.get $2)- )- )- (func $SAFE_HEAP_LOAD_i32_2_2 (param $0 i32) (param $1 i32) (result i32)- (local $2 i32)- (local.set $2- (i32.add- (local.get $0)- (local.get $1)- )- )- (if- (i32.or- (i32.eq- (local.get $2)- (i32.const 0)- )- (i32.gt_u- (i32.add- (local.get $2)- (i32.const 2)- )- (i32.load- (global.get $foo)- )- )- )- (call $segfault)- )- (if- (i32.and- (local.get $2)- (i32.const 1)- )- (call $alignfault)- )- (i32.load16_s- (local.get $2)- )- )- (func $SAFE_HEAP_LOAD_i32_2_U_1 (param $0 i32) (param $1 i32) (result i32)- (local $2 i32)- (local.set $2- (i32.add- (local.get $0)- (local.get $1)- )- )- (if- (i32.or- (i32.eq- (local.get $2)- (i32.const 0)- )- (i32.gt_u- (i32.add- (local.get $2)- (i32.const 2)- )- (i32.load- (global.get $foo)- )- )- )- (call $segfault)- )- (i32.load16_u align=1- (local.get $2)- )- )- (func $SAFE_HEAP_LOAD_i32_2_U_2 (param $0 i32) (param $1 i32) (result i32)- (local $2 i32)- (local.set $2- (i32.add- (local.get $0)- (local.get $1)- )- )- (if- (i32.or- (i32.eq- (local.get $2)- (i32.const 0)- )- (i32.gt_u- (i32.add- (local.get $2)- (i32.const 2)- )- (i32.load- (global.get $foo)- )- )- )- (call $segfault)- )- (if- (i32.and- (local.get $2)- (i32.const 1)- )- (call $alignfault)- )- (i32.load16_u- (local.get $2)- )- )- (func $SAFE_HEAP_LOAD_i32_4_1 (param $0 i32) (param $1 i32) (result i32)- (local $2 i32)- (local.set $2- (i32.add- (local.get $0)- (local.get $1)- )- )- (if- (i32.or- (i32.eq- (local.get $2)- (i32.const 0)- )- (i32.gt_u- (i32.add- (local.get $2)- (i32.const 4)- )- (i32.load- (global.get $foo)- )- )- )- (call $segfault)- )- (i32.load align=1- (local.get $2)- )- )- (func $SAFE_HEAP_LOAD_i32_4_2 (param $0 i32) (param $1 i32) (result i32)- (local $2 i32)- (local.set $2- (i32.add- (local.get $0)- (local.get $1)- )- )- (if- (i32.or- (i32.eq- (local.get $2)- (i32.const 0)- )- (i32.gt_u- (i32.add- (local.get $2)- (i32.const 4)- )- (i32.load- (global.get $foo)- )- )- )- (call $segfault)- )- (if- (i32.and- (local.get $2)- (i32.const 1)- )- (call $alignfault)- )- (i32.load align=2- (local.get $2)- )- )- (func $SAFE_HEAP_LOAD_i32_4_4 (param $0 i32) (param $1 i32) (result i32)- (local $2 i32)- (local.set $2- (i32.add- (local.get $0)- (local.get $1)- )- )- (if- (i32.or- (i32.eq- (local.get $2)- (i32.const 0)- )- (i32.gt_u- (i32.add- (local.get $2)- (i32.const 4)- )- (i32.load- (global.get $foo)- )- )- )- (call $segfault)- )- (if- (i32.and- (local.get $2)- (i32.const 3)- )- (call $alignfault)- )- (i32.load- (local.get $2)- )- )- (func $SAFE_HEAP_LOAD_i64_1_1 (param $0 i32) (param $1 i32) (result i64)- (local $2 i32)- (local.set $2- (i32.add- (local.get $0)- (local.get $1)- )- )- (if- (i32.or- (i32.eq- (local.get $2)- (i32.const 0)- )- (i32.gt_u- (i32.add- (local.get $2)- (i32.const 1)- )- (i32.load- (global.get $foo)- )- )- )- (call $segfault)- )- (i64.load8_s- (local.get $2)- )- )- (func $SAFE_HEAP_LOAD_i64_1_U_1 (param $0 i32) (param $1 i32) (result i64)- (local $2 i32)- (local.set $2- (i32.add- (local.get $0)- (local.get $1)- )- )- (if- (i32.or- (i32.eq- (local.get $2)- (i32.const 0)- )- (i32.gt_u- (i32.add- (local.get $2)- (i32.const 1)- )- (i32.load- (global.get $foo)- )- )- )- (call $segfault)- )- (i64.load8_u- (local.get $2)- )- )- (func $SAFE_HEAP_LOAD_i64_2_1 (param $0 i32) (param $1 i32) (result i64)- (local $2 i32)- (local.set $2- (i32.add- (local.get $0)- (local.get $1)- )- )- (if- (i32.or- (i32.eq- (local.get $2)- (i32.const 0)- )- (i32.gt_u- (i32.add- (local.get $2)- (i32.const 2)- )- (i32.load- (global.get $foo)- )- )- )- (call $segfault)- )- (i64.load16_s align=1- (local.get $2)- )- )- (func $SAFE_HEAP_LOAD_i64_2_2 (param $0 i32) (param $1 i32) (result i64)- (local $2 i32)- (local.set $2- (i32.add- (local.get $0)- (local.get $1)- )- )- (if- (i32.or- (i32.eq- (local.get $2)- (i32.const 0)- )- (i32.gt_u- (i32.add- (local.get $2)- (i32.const 2)- )- (i32.load- (global.get $foo)- )- )- )- (call $segfault)- )- (if- (i32.and- (local.get $2)- (i32.const 1)- )- (call $alignfault)- )- (i64.load16_s- (local.get $2)- )- )- (func $SAFE_HEAP_LOAD_i64_2_U_1 (param $0 i32) (param $1 i32) (result i64)- (local $2 i32)- (local.set $2- (i32.add- (local.get $0)- (local.get $1)- )- )- (if- (i32.or- (i32.eq- (local.get $2)- (i32.const 0)- )- (i32.gt_u- (i32.add- (local.get $2)- (i32.const 2)- )- (i32.load- (global.get $foo)- )- )- )- (call $segfault)- )- (i64.load16_u align=1- (local.get $2)- )- )- (func $SAFE_HEAP_LOAD_i64_2_U_2 (param $0 i32) (param $1 i32) (result i64)- (local $2 i32)- (local.set $2- (i32.add- (local.get $0)- (local.get $1)- )- )- (if- (i32.or- (i32.eq- (local.get $2)- (i32.const 0)- )- (i32.gt_u- (i32.add- (local.get $2)- (i32.const 2)- )- (i32.load- (global.get $foo)- )- )- )- (call $segfault)- )- (if- (i32.and- (local.get $2)- (i32.const 1)- )- (call $alignfault)- )- (i64.load16_u- (local.get $2)- )- )- (func $SAFE_HEAP_LOAD_i64_4_1 (param $0 i32) (param $1 i32) (result i64)- (local $2 i32)- (local.set $2- (i32.add- (local.get $0)- (local.get $1)- )- )- (if- (i32.or- (i32.eq- (local.get $2)- (i32.const 0)- )- (i32.gt_u- (i32.add- (local.get $2)- (i32.const 4)- )- (i32.load- (global.get $foo)- )- )- )- (call $segfault)- )- (i64.load32_s align=1- (local.get $2)- )- )- (func $SAFE_HEAP_LOAD_i64_4_2 (param $0 i32) (param $1 i32) (result i64)- (local $2 i32)- (local.set $2- (i32.add- (local.get $0)- (local.get $1)- )- )- (if- (i32.or- (i32.eq- (local.get $2)- (i32.const 0)- )- (i32.gt_u- (i32.add- (local.get $2)- (i32.const 4)- )- (i32.load- (global.get $foo)- )- )- )- (call $segfault)- )- (if- (i32.and- (local.get $2)- (i32.const 1)- )- (call $alignfault)- )- (i64.load32_s align=2- (local.get $2)- )- )- (func $SAFE_HEAP_LOAD_i64_4_4 (param $0 i32) (param $1 i32) (result i64)- (local $2 i32)- (local.set $2- (i32.add- (local.get $0)- (local.get $1)- )- )- (if- (i32.or- (i32.eq- (local.get $2)- (i32.const 0)- )- (i32.gt_u- (i32.add- (local.get $2)- (i32.const 4)- )- (i32.load- (global.get $foo)- )- )- )- (call $segfault)- )- (if- (i32.and- (local.get $2)- (i32.const 3)- )- (call $alignfault)- )- (i64.load32_s- (local.get $2)- )- )- (func $SAFE_HEAP_LOAD_i64_4_U_1 (param $0 i32) (param $1 i32) (result i64)- (local $2 i32)- (local.set $2- (i32.add- (local.get $0)- (local.get $1)- )- )- (if- (i32.or- (i32.eq- (local.get $2)- (i32.const 0)- )- (i32.gt_u- (i32.add- (local.get $2)- (i32.const 4)- )- (i32.load- (global.get $foo)- )- )- )- (call $segfault)- )- (i64.load32_u align=1- (local.get $2)- )- )- (func $SAFE_HEAP_LOAD_i64_4_U_2 (param $0 i32) (param $1 i32) (result i64)- (local $2 i32)- (local.set $2- (i32.add- (local.get $0)- (local.get $1)- )- )- (if- (i32.or- (i32.eq- (local.get $2)- (i32.const 0)- )- (i32.gt_u- (i32.add- (local.get $2)- (i32.const 4)- )- (i32.load- (global.get $foo)- )- )- )- (call $segfault)- )- (if- (i32.and- (local.get $2)- (i32.const 1)- )- (call $alignfault)- )- (i64.load32_u align=2- (local.get $2)- )- )- (func $SAFE_HEAP_LOAD_i64_4_U_4 (param $0 i32) (param $1 i32) (result i64)- (local $2 i32)- (local.set $2- (i32.add- (local.get $0)- (local.get $1)- )- )- (if- (i32.or- (i32.eq- (local.get $2)- (i32.const 0)- )- (i32.gt_u- (i32.add- (local.get $2)- (i32.const 4)- )- (i32.load- (global.get $foo)- )- )- )- (call $segfault)- )- (if- (i32.and- (local.get $2)- (i32.const 3)- )- (call $alignfault)- )- (i64.load32_u- (local.get $2)- )- )- (func $SAFE_HEAP_LOAD_i64_8_1 (param $0 i32) (param $1 i32) (result i64)- (local $2 i32)- (local.set $2- (i32.add- (local.get $0)- (local.get $1)- )- )- (if- (i32.or- (i32.eq- (local.get $2)- (i32.const 0)- )- (i32.gt_u- (i32.add- (local.get $2)- (i32.const 8)- )- (i32.load- (global.get $foo)- )- )- )- (call $segfault)- )- (i64.load align=1- (local.get $2)- )- )- (func $SAFE_HEAP_LOAD_i64_8_2 (param $0 i32) (param $1 i32) (result i64)- (local $2 i32)- (local.set $2- (i32.add- (local.get $0)- (local.get $1)- )- )- (if- (i32.or- (i32.eq- (local.get $2)- (i32.const 0)- )- (i32.gt_u- (i32.add- (local.get $2)- (i32.const 8)- )- (i32.load- (global.get $foo)- )- )- )- (call $segfault)- )- (if- (i32.and- (local.get $2)- (i32.const 1)- )- (call $alignfault)- )- (i64.load align=2- (local.get $2)- )- )- (func $SAFE_HEAP_LOAD_i64_8_4 (param $0 i32) (param $1 i32) (result i64)- (local $2 i32)- (local.set $2- (i32.add- (local.get $0)- (local.get $1)- )- )- (if- (i32.or- (i32.eq- (local.get $2)- (i32.const 0)- )- (i32.gt_u- (i32.add- (local.get $2)- (i32.const 8)- )- (i32.load- (global.get $foo)- )- )- )- (call $segfault)- )- (if- (i32.and- (local.get $2)- (i32.const 3)- )- (call $alignfault)- )- (i64.load align=4- (local.get $2)- )- )- (func $SAFE_HEAP_LOAD_i64_8_8 (param $0 i32) (param $1 i32) (result i64)- (local $2 i32)- (local.set $2- (i32.add- (local.get $0)- (local.get $1)- )- )- (if- (i32.or- (i32.eq- (local.get $2)- (i32.const 0)- )- (i32.gt_u- (i32.add- (local.get $2)- (i32.const 8)- )- (i32.load- (global.get $foo)- )- )- )- (call $segfault)- )- (if- (i32.and- (local.get $2)- (i32.const 7)- )- (call $alignfault)- )- (i64.load- (local.get $2)- )- )- (func $SAFE_HEAP_LOAD_f32_4_1 (param $0 i32) (param $1 i32) (result f32)- (local $2 i32)- (local.set $2- (i32.add- (local.get $0)- (local.get $1)- )- )- (if- (i32.or- (i32.eq- (local.get $2)- (i32.const 0)- )- (i32.gt_u- (i32.add- (local.get $2)- (i32.const 4)- )- (i32.load- (global.get $foo)- )- )- )- (call $segfault)- )- (f32.load align=1- (local.get $2)- )- )- (func $SAFE_HEAP_LOAD_f32_4_2 (param $0 i32) (param $1 i32) (result f32)- (local $2 i32)- (local.set $2- (i32.add- (local.get $0)- (local.get $1)- )- )- (if- (i32.or- (i32.eq- (local.get $2)- (i32.const 0)- )- (i32.gt_u- (i32.add- (local.get $2)- (i32.const 4)- )- (i32.load- (global.get $foo)- )- )- )- (call $segfault)- )- (if- (i32.and- (local.get $2)- (i32.const 1)- )- (call $alignfault)- )- (f32.load align=2- (local.get $2)- )- )- (func $SAFE_HEAP_LOAD_f32_4_4 (param $0 i32) (param $1 i32) (result f32)- (local $2 i32)- (local.set $2- (i32.add- (local.get $0)- (local.get $1)- )- )- (if- (i32.or- (i32.eq- (local.get $2)- (i32.const 0)- )- (i32.gt_u- (i32.add- (local.get $2)- (i32.const 4)- )- (i32.load- (global.get $foo)- )- )- )- (call $segfault)- )- (if- (i32.and- (local.get $2)- (i32.const 3)- )- (call $alignfault)- )- (f32.load- (local.get $2)- )- )- (func $SAFE_HEAP_LOAD_f64_8_1 (param $0 i32) (param $1 i32) (result f64)- (local $2 i32)- (local.set $2- (i32.add- (local.get $0)- (local.get $1)- )- )- (if- (i32.or- (i32.eq- (local.get $2)- (i32.const 0)- )- (i32.gt_u- (i32.add- (local.get $2)- (i32.const 8)- )- (i32.load- (global.get $foo)- )- )- )- (call $segfault)- )- (f64.load align=1- (local.get $2)- )- )- (func $SAFE_HEAP_LOAD_f64_8_2 (param $0 i32) (param $1 i32) (result f64)- (local $2 i32)- (local.set $2- (i32.add- (local.get $0)- (local.get $1)- )- )- (if- (i32.or- (i32.eq- (local.get $2)- (i32.const 0)- )- (i32.gt_u- (i32.add- (local.get $2)- (i32.const 8)- )- (i32.load- (global.get $foo)- )- )- )- (call $segfault)- )- (if- (i32.and- (local.get $2)- (i32.const 1)- )- (call $alignfault)- )- (f64.load align=2- (local.get $2)- )- )- (func $SAFE_HEAP_LOAD_f64_8_4 (param $0 i32) (param $1 i32) (result f64)- (local $2 i32)- (local.set $2- (i32.add- (local.get $0)- (local.get $1)- )- )- (if- (i32.or- (i32.eq- (local.get $2)- (i32.const 0)- )- (i32.gt_u- (i32.add- (local.get $2)- (i32.const 8)- )- (i32.load- (global.get $foo)- )- )- )- (call $segfault)- )- (if- (i32.and- (local.get $2)- (i32.const 3)- )- (call $alignfault)- )- (f64.load align=4- (local.get $2)- )- )- (func $SAFE_HEAP_LOAD_f64_8_8 (param $0 i32) (param $1 i32) (result f64)- (local $2 i32)- (local.set $2- (i32.add- (local.get $0)- (local.get $1)- )- )- (if- (i32.or- (i32.eq- (local.get $2)- (i32.const 0)- )- (i32.gt_u- (i32.add- (local.get $2)- (i32.const 8)- )- (i32.load- (global.get $foo)- )- )- )- (call $segfault)- )- (if- (i32.and- (local.get $2)- (i32.const 7)- )- (call $alignfault)- )- (f64.load- (local.get $2)- )- )- (func $SAFE_HEAP_STORE_i32_1_1 (param $0 i32) (param $1 i32) (param $2 i32)- (local $3 i32)- (local.set $3- (i32.add- (local.get $0)- (local.get $1)- )- )- (if- (i32.or- (i32.eq- (local.get $3)- (i32.const 0)- )- (i32.gt_u- (i32.add- (local.get $3)- (i32.const 1)- )- (i32.load- (global.get $foo)- )- )- )- (call $segfault)- )- (i32.store8- (local.get $3)- (local.get $2)- )- )- (func $SAFE_HEAP_STORE_i32_2_1 (param $0 i32) (param $1 i32) (param $2 i32)- (local $3 i32)- (local.set $3- (i32.add- (local.get $0)- (local.get $1)- )- )- (if- (i32.or- (i32.eq- (local.get $3)- (i32.const 0)- )- (i32.gt_u- (i32.add- (local.get $3)- (i32.const 2)- )- (i32.load- (global.get $foo)- )- )- )- (call $segfault)- )- (i32.store16 align=1- (local.get $3)- (local.get $2)- )- )- (func $SAFE_HEAP_STORE_i32_2_2 (param $0 i32) (param $1 i32) (param $2 i32)- (local $3 i32)- (local.set $3- (i32.add- (local.get $0)- (local.get $1)- )- )- (if- (i32.or- (i32.eq- (local.get $3)- (i32.const 0)- )- (i32.gt_u- (i32.add- (local.get $3)- (i32.const 2)- )- (i32.load- (global.get $foo)- )- )- )- (call $segfault)- )- (if- (i32.and- (local.get $3)- (i32.const 1)- )- (call $alignfault)- )- (i32.store16- (local.get $3)- (local.get $2)- )- )- (func $SAFE_HEAP_STORE_i32_4_1 (param $0 i32) (param $1 i32) (param $2 i32)- (local $3 i32)- (local.set $3- (i32.add- (local.get $0)- (local.get $1)- )- )- (if- (i32.or- (i32.eq- (local.get $3)- (i32.const 0)- )- (i32.gt_u- (i32.add- (local.get $3)- (i32.const 4)- )- (i32.load- (global.get $foo)- )- )- )- (call $segfault)- )- (i32.store align=1- (local.get $3)- (local.get $2)- )- )- (func $SAFE_HEAP_STORE_i32_4_2 (param $0 i32) (param $1 i32) (param $2 i32)- (local $3 i32)- (local.set $3- (i32.add- (local.get $0)- (local.get $1)- )- )- (if- (i32.or- (i32.eq- (local.get $3)- (i32.const 0)- )- (i32.gt_u- (i32.add- (local.get $3)- (i32.const 4)- )- (i32.load- (global.get $foo)- )- )- )- (call $segfault)- )- (if- (i32.and- (local.get $3)- (i32.const 1)- )- (call $alignfault)- )- (i32.store align=2- (local.get $3)- (local.get $2)- )- )- (func $SAFE_HEAP_STORE_i32_4_4 (param $0 i32) (param $1 i32) (param $2 i32)- (local $3 i32)- (local.set $3- (i32.add- (local.get $0)- (local.get $1)- )- )- (if- (i32.or- (i32.eq- (local.get $3)- (i32.const 0)- )- (i32.gt_u- (i32.add- (local.get $3)- (i32.const 4)- )- (i32.load- (global.get $foo)- )- )- )- (call $segfault)- )- (if- (i32.and- (local.get $3)- (i32.const 3)- )- (call $alignfault)- )- (i32.store- (local.get $3)- (local.get $2)- )- )- (func $SAFE_HEAP_STORE_i64_1_1 (param $0 i32) (param $1 i32) (param $2 i64)- (local $3 i32)- (local.set $3- (i32.add- (local.get $0)- (local.get $1)- )- )- (if- (i32.or- (i32.eq- (local.get $3)- (i32.const 0)- )- (i32.gt_u- (i32.add- (local.get $3)- (i32.const 1)- )- (i32.load- (global.get $foo)- )- )- )- (call $segfault)- )- (i64.store8- (local.get $3)- (local.get $2)- )- )- (func $SAFE_HEAP_STORE_i64_2_1 (param $0 i32) (param $1 i32) (param $2 i64)- (local $3 i32)- (local.set $3- (i32.add- (local.get $0)- (local.get $1)- )- )- (if- (i32.or- (i32.eq- (local.get $3)- (i32.const 0)- )- (i32.gt_u- (i32.add- (local.get $3)- (i32.const 2)- )- (i32.load- (global.get $foo)- )- )- )- (call $segfault)- )- (i64.store16 align=1- (local.get $3)- (local.get $2)- )- )- (func $SAFE_HEAP_STORE_i64_2_2 (param $0 i32) (param $1 i32) (param $2 i64)- (local $3 i32)- (local.set $3- (i32.add- (local.get $0)- (local.get $1)- )- )- (if- (i32.or- (i32.eq- (local.get $3)- (i32.const 0)- )- (i32.gt_u- (i32.add- (local.get $3)- (i32.const 2)- )- (i32.load- (global.get $foo)- )- )- )- (call $segfault)- )- (if- (i32.and- (local.get $3)- (i32.const 1)- )- (call $alignfault)- )- (i64.store16- (local.get $3)- (local.get $2)- )- )- (func $SAFE_HEAP_STORE_i64_4_1 (param $0 i32) (param $1 i32) (param $2 i64)- (local $3 i32)- (local.set $3- (i32.add- (local.get $0)- (local.get $1)- )- )- (if- (i32.or- (i32.eq- (local.get $3)- (i32.const 0)- )- (i32.gt_u- (i32.add- (local.get $3)- (i32.const 4)- )- (i32.load- (global.get $foo)- )- )- )- (call $segfault)- )- (i64.store32 align=1- (local.get $3)- (local.get $2)- )- )- (func $SAFE_HEAP_STORE_i64_4_2 (param $0 i32) (param $1 i32) (param $2 i64)- (local $3 i32)- (local.set $3- (i32.add- (local.get $0)- (local.get $1)- )- )- (if- (i32.or- (i32.eq- (local.get $3)- (i32.const 0)- )- (i32.gt_u- (i32.add- (local.get $3)- (i32.const 4)- )- (i32.load- (global.get $foo)- )- )- )- (call $segfault)- )- (if- (i32.and- (local.get $3)- (i32.const 1)- )- (call $alignfault)- )- (i64.store32 align=2- (local.get $3)- (local.get $2)- )- )- (func $SAFE_HEAP_STORE_i64_4_4 (param $0 i32) (param $1 i32) (param $2 i64)- (local $3 i32)- (local.set $3- (i32.add- (local.get $0)- (local.get $1)- )- )- (if- (i32.or- (i32.eq- (local.get $3)- (i32.const 0)- )- (i32.gt_u- (i32.add- (local.get $3)- (i32.const 4)- )- (i32.load- (global.get $foo)- )- )- )- (call $segfault)- )- (if- (i32.and- (local.get $3)- (i32.const 3)- )- (call $alignfault)- )- (i64.store32- (local.get $3)- (local.get $2)- )- )- (func $SAFE_HEAP_STORE_i64_8_1 (param $0 i32) (param $1 i32) (param $2 i64)- (local $3 i32)- (local.set $3- (i32.add- (local.get $0)- (local.get $1)- )- )- (if- (i32.or- (i32.eq- (local.get $3)- (i32.const 0)- )- (i32.gt_u- (i32.add- (local.get $3)- (i32.const 8)- )- (i32.load- (global.get $foo)- )- )- )- (call $segfault)- )- (i64.store align=1- (local.get $3)- (local.get $2)- )- )- (func $SAFE_HEAP_STORE_i64_8_2 (param $0 i32) (param $1 i32) (param $2 i64)- (local $3 i32)- (local.set $3- (i32.add- (local.get $0)- (local.get $1)- )- )- (if- (i32.or- (i32.eq- (local.get $3)- (i32.const 0)- )- (i32.gt_u- (i32.add- (local.get $3)- (i32.const 8)- )- (i32.load- (global.get $foo)- )- )- )- (call $segfault)- )- (if- (i32.and- (local.get $3)- (i32.const 1)- )- (call $alignfault)- )- (i64.store align=2- (local.get $3)- (local.get $2)- )- )- (func $SAFE_HEAP_STORE_i64_8_4 (param $0 i32) (param $1 i32) (param $2 i64)- (local $3 i32)- (local.set $3- (i32.add- (local.get $0)- (local.get $1)- )- )- (if- (i32.or- (i32.eq- (local.get $3)- (i32.const 0)- )- (i32.gt_u- (i32.add- (local.get $3)- (i32.const 8)- )- (i32.load- (global.get $foo)- )- )- )- (call $segfault)- )- (if- (i32.and- (local.get $3)- (i32.const 3)- )- (call $alignfault)- )- (i64.store align=4- (local.get $3)- (local.get $2)- )- )- (func $SAFE_HEAP_STORE_i64_8_8 (param $0 i32) (param $1 i32) (param $2 i64)- (local $3 i32)- (local.set $3- (i32.add- (local.get $0)- (local.get $1)- )- )- (if- (i32.or- (i32.eq- (local.get $3)- (i32.const 0)- )- (i32.gt_u- (i32.add- (local.get $3)- (i32.const 8)- )- (i32.load- (global.get $foo)- )- )- )- (call $segfault)- )- (if- (i32.and- (local.get $3)- (i32.const 7)- )- (call $alignfault)- )- (i64.store- (local.get $3)- (local.get $2)- )- )- (func $SAFE_HEAP_STORE_f32_4_1 (param $0 i32) (param $1 i32) (param $2 f32)- (local $3 i32)- (local.set $3- (i32.add- (local.get $0)- (local.get $1)- )- )- (if- (i32.or- (i32.eq- (local.get $3)- (i32.const 0)- )- (i32.gt_u- (i32.add- (local.get $3)- (i32.const 4)- )- (i32.load- (global.get $foo)- )- )- )- (call $segfault)- )- (f32.store align=1- (local.get $3)- (local.get $2)- )- )- (func $SAFE_HEAP_STORE_f32_4_2 (param $0 i32) (param $1 i32) (param $2 f32)- (local $3 i32)- (local.set $3- (i32.add- (local.get $0)- (local.get $1)- )- )- (if- (i32.or- (i32.eq- (local.get $3)- (i32.const 0)- )- (i32.gt_u- (i32.add- (local.get $3)- (i32.const 4)- )- (i32.load- (global.get $foo)- )- )- )- (call $segfault)- )- (if- (i32.and- (local.get $3)- (i32.const 1)- )- (call $alignfault)- )- (f32.store align=2- (local.get $3)- (local.get $2)- )- )- (func $SAFE_HEAP_STORE_f32_4_4 (param $0 i32) (param $1 i32) (param $2 f32)- (local $3 i32)- (local.set $3- (i32.add- (local.get $0)- (local.get $1)- )- )- (if- (i32.or- (i32.eq- (local.get $3)- (i32.const 0)- )- (i32.gt_u- (i32.add- (local.get $3)- (i32.const 4)- )- (i32.load- (global.get $foo)- )- )- )- (call $segfault)- )- (if- (i32.and- (local.get $3)- (i32.const 3)- )- (call $alignfault)- )- (f32.store- (local.get $3)- (local.get $2)- )- )- (func $SAFE_HEAP_STORE_f64_8_1 (param $0 i32) (param $1 i32) (param $2 f64)- (local $3 i32)- (local.set $3- (i32.add- (local.get $0)- (local.get $1)- )- )- (if- (i32.or- (i32.eq- (local.get $3)- (i32.const 0)- )- (i32.gt_u- (i32.add- (local.get $3)- (i32.const 8)- )- (i32.load- (global.get $foo)- )- )- )- (call $segfault)- )- (f64.store align=1- (local.get $3)- (local.get $2)- )- )- (func $SAFE_HEAP_STORE_f64_8_2 (param $0 i32) (param $1 i32) (param $2 f64)- (local $3 i32)- (local.set $3- (i32.add- (local.get $0)- (local.get $1)- )- )- (if- (i32.or- (i32.eq- (local.get $3)- (i32.const 0)- )- (i32.gt_u- (i32.add- (local.get $3)- (i32.const 8)- )- (i32.load- (global.get $foo)- )- )- )- (call $segfault)- )- (if- (i32.and- (local.get $3)- (i32.const 1)- )- (call $alignfault)- )- (f64.store align=2- (local.get $3)- (local.get $2)- )- )- (func $SAFE_HEAP_STORE_f64_8_4 (param $0 i32) (param $1 i32) (param $2 f64)- (local $3 i32)- (local.set $3- (i32.add- (local.get $0)- (local.get $1)- )- )- (if- (i32.or- (i32.eq- (local.get $3)- (i32.const 0)- )- (i32.gt_u- (i32.add- (local.get $3)- (i32.const 8)- )- (i32.load- (global.get $foo)- )- )- )- (call $segfault)- )- (if- (i32.and- (local.get $3)- (i32.const 3)- )- (call $alignfault)- )- (f64.store align=4- (local.get $3)- (local.get $2)- )- )- (func $SAFE_HEAP_STORE_f64_8_8 (param $0 i32) (param $1 i32) (param $2 f64)- (local $3 i32)- (local.set $3- (i32.add- (local.get $0)- (local.get $1)- )- )- (if- (i32.or- (i32.eq- (local.get $3)- (i32.const 0)- )- (i32.gt_u- (i32.add- (local.get $3)- (i32.const 8)- )- (i32.load- (global.get $foo)- )- )- )- (call $segfault)- )- (if- (i32.and- (local.get $3)- (i32.const 7)- )- (call $alignfault)- )- (f64.store- (local.get $3)- (local.get $2)- )- )-)-(module- (type $i32_i32_=>_i64 (func (param i32 i32) (result i64)))- (type $i32_i32_i64_=>_none (func (param i32 i32 i64)))- (type $i32_i32_=>_i32 (func (param i32 i32) (result i32)))- (type $i32_i32_i32_=>_none (func (param i32 i32 i32)))- (type $i32_i32_f64_=>_none (func (param i32 i32 f64)))- (type $i32_i32_=>_f64 (func (param i32 i32) (result f64)))- (type $i32_i32_f32_=>_none (func (param i32 i32 f32)))- (type $i32_i32_=>_f32 (func (param i32 i32) (result f32)))- (type $none_=>_none (func)) (type $none_=>_i32 (func (result i32))) (import "env" "emscripten_get_sbrk_ptr" (func $foo (result i32))) (import "env" "segfault" (func $segfault))
binaryen/test/passes/safe-heap_disable-simd.wast view
@@ -3,10 +3,6 @@ ) (module (memory 1 1)- (import "env" "DYNAMICTOP_PTR" (global $foo i32))-)-(module- (memory 1 1) (import "env" "emscripten_get_sbrk_ptr" (func $foo (result i32))) ) (module
binaryen/test/passes/safe-heap_enable-threads_enable-simd.txt view
@@ -5437,9 +5437,10 @@ (type $none_=>_none (func)) (type $i32_i32_f32_=>_none (func (param i32 i32 f32))) (type $i32_i32_=>_f32 (func (param i32 i32) (result f32)))- (import "env" "DYNAMICTOP_PTR" (global $DYNAMICTOP_PTR i32))+ (type $none_=>_i32 (func (result i32))) (import "env" "segfault" (func $segfault)) (import "env" "alignfault" (func $alignfault))+ (import "env" "emscripten_get_sbrk_ptr" (func $emscripten_get_sbrk_ptr (result i32))) (memory $0 (shared 100 100)) (func $actions (drop@@ -5474,7 +5475,7 @@ (i32.const 1) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -5510,7 +5511,7 @@ (i32.const 1) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -5540,7 +5541,7 @@ (i32.const 1) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -5570,7 +5571,7 @@ (i32.const 1) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -5600,7 +5601,7 @@ (i32.const 2) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -5630,7 +5631,7 @@ (i32.const 2) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -5673,7 +5674,7 @@ (i32.const 2) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -5710,7 +5711,7 @@ (i32.const 2) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -5740,7 +5741,7 @@ (i32.const 2) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -5777,7 +5778,7 @@ (i32.const 2) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -5814,7 +5815,7 @@ (i32.const 4) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -5844,7 +5845,7 @@ (i32.const 4) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -5881,7 +5882,7 @@ (i32.const 4) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -5918,7 +5919,7 @@ (i32.const 4) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -5955,7 +5956,7 @@ (i32.const 1) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -5991,7 +5992,7 @@ (i32.const 1) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -6021,7 +6022,7 @@ (i32.const 1) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -6051,7 +6052,7 @@ (i32.const 1) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -6081,7 +6082,7 @@ (i32.const 2) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -6111,7 +6112,7 @@ (i32.const 2) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -6154,7 +6155,7 @@ (i32.const 2) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -6191,7 +6192,7 @@ (i32.const 2) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -6221,7 +6222,7 @@ (i32.const 2) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -6258,7 +6259,7 @@ (i32.const 2) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -6295,7 +6296,7 @@ (i32.const 4) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -6325,7 +6326,7 @@ (i32.const 4) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -6362,7 +6363,7 @@ (i32.const 4) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -6405,7 +6406,7 @@ (i32.const 4) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -6442,7 +6443,7 @@ (i32.const 4) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -6472,7 +6473,7 @@ (i32.const 4) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -6509,7 +6510,7 @@ (i32.const 4) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -6546,7 +6547,7 @@ (i32.const 4) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -6583,7 +6584,7 @@ (i32.const 8) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -6613,7 +6614,7 @@ (i32.const 8) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -6650,7 +6651,7 @@ (i32.const 8) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -6687,7 +6688,7 @@ (i32.const 8) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -6724,7 +6725,7 @@ (i32.const 8) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -6761,7 +6762,7 @@ (i32.const 4) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -6791,7 +6792,7 @@ (i32.const 4) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -6828,7 +6829,7 @@ (i32.const 4) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -6865,7 +6866,7 @@ (i32.const 8) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -6895,7 +6896,7 @@ (i32.const 8) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -6932,7 +6933,7 @@ (i32.const 8) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -6969,7 +6970,7 @@ (i32.const 8) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -7006,7 +7007,7 @@ (i32.const 16) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -7036,7 +7037,7 @@ (i32.const 16) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -7073,7 +7074,7 @@ (i32.const 16) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -7110,7 +7111,7 @@ (i32.const 16) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -7147,7 +7148,7 @@ (i32.const 16) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -7184,7 +7185,7 @@ (i32.const 1) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -7215,7 +7216,7 @@ (i32.const 1) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -7246,7 +7247,7 @@ (i32.const 2) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -7277,7 +7278,7 @@ (i32.const 2) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -7315,7 +7316,7 @@ (i32.const 2) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -7353,7 +7354,7 @@ (i32.const 4) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -7384,7 +7385,7 @@ (i32.const 4) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -7422,7 +7423,7 @@ (i32.const 4) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -7460,7 +7461,7 @@ (i32.const 4) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -7498,7 +7499,7 @@ (i32.const 1) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -7529,7 +7530,7 @@ (i32.const 1) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -7560,7 +7561,7 @@ (i32.const 2) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -7591,7 +7592,7 @@ (i32.const 2) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -7629,7 +7630,7 @@ (i32.const 2) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -7667,7 +7668,7 @@ (i32.const 4) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -7698,7 +7699,7 @@ (i32.const 4) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -7736,7 +7737,7 @@ (i32.const 4) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -7774,7 +7775,7 @@ (i32.const 4) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -7812,7 +7813,7 @@ (i32.const 8) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -7843,7 +7844,7 @@ (i32.const 8) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -7881,7 +7882,7 @@ (i32.const 8) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -7919,7 +7920,7 @@ (i32.const 8) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -7957,7 +7958,7 @@ (i32.const 8) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -7995,7 +7996,7 @@ (i32.const 4) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -8026,7 +8027,7 @@ (i32.const 4) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -8064,7 +8065,7 @@ (i32.const 4) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -8102,7 +8103,7 @@ (i32.const 8) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -8133,7 +8134,7 @@ (i32.const 8) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -8171,7 +8172,7 @@ (i32.const 8) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -8209,7 +8210,7 @@ (i32.const 8) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -8247,7 +8248,7 @@ (i32.const 16) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -8278,7 +8279,7 @@ (i32.const 16) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -8316,7 +8317,7 @@ (i32.const 16) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -8354,7 +8355,7 @@ (i32.const 16) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )@@ -8392,7 +8393,7 @@ (i32.const 16) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $emscripten_get_sbrk_ptr) ) ) )
binaryen/test/passes/safe-heap_enable-threads_enable-simd.wast view
@@ -45,7 +45,6 @@ ;; pre-existing (module (type $FUNCSIG$v (func))- (import "env" "DYNAMICTOP_PTR" (global $DYNAMICTOP_PTR i32)) (import "env" "segfault" (func $segfault)) (import "env" "alignfault" (func $alignfault)) (memory $0 (shared 100 100))
binaryen/test/passes/safe-heap_enable-threads_enable-simd64.txt view
@@ -5623,7 +5623,8 @@ (type $none_=>_none (func)) (type $i64_i64_f32_=>_none (func (param i64 i64 f32))) (type $i64_i64_=>_f32 (func (param i64 i64) (result f32)))- (import "env" "DYNAMICTOP_PTR" (global $DYNAMICTOP_PTR i32))+ (type $none_=>_i64 (func (result i64)))+ (import "env" "emscripten_get_sbrk_ptr" (func $foo (result i64))) (import "env" "segfault" (func $segfault)) (import "env" "alignfault" (func $alignfault)) (memory $0 (shared i64 100 100))@@ -5660,7 +5661,7 @@ (i64.const 1) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -5696,7 +5697,7 @@ (i64.const 1) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -5726,7 +5727,7 @@ (i64.const 1) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -5756,7 +5757,7 @@ (i64.const 1) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -5786,7 +5787,7 @@ (i64.const 2) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -5816,7 +5817,7 @@ (i64.const 2) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -5861,7 +5862,7 @@ (i64.const 2) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -5900,7 +5901,7 @@ (i64.const 2) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -5930,7 +5931,7 @@ (i64.const 2) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -5969,7 +5970,7 @@ (i64.const 2) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -6008,7 +6009,7 @@ (i64.const 4) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -6038,7 +6039,7 @@ (i64.const 4) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -6077,7 +6078,7 @@ (i64.const 4) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -6116,7 +6117,7 @@ (i64.const 4) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -6155,7 +6156,7 @@ (i64.const 1) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -6191,7 +6192,7 @@ (i64.const 1) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -6221,7 +6222,7 @@ (i64.const 1) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -6251,7 +6252,7 @@ (i64.const 1) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -6281,7 +6282,7 @@ (i64.const 2) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -6311,7 +6312,7 @@ (i64.const 2) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -6356,7 +6357,7 @@ (i64.const 2) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -6395,7 +6396,7 @@ (i64.const 2) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -6425,7 +6426,7 @@ (i64.const 2) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -6464,7 +6465,7 @@ (i64.const 2) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -6503,7 +6504,7 @@ (i64.const 4) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -6533,7 +6534,7 @@ (i64.const 4) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -6572,7 +6573,7 @@ (i64.const 4) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -6617,7 +6618,7 @@ (i64.const 4) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -6656,7 +6657,7 @@ (i64.const 4) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -6686,7 +6687,7 @@ (i64.const 4) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -6725,7 +6726,7 @@ (i64.const 4) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -6764,7 +6765,7 @@ (i64.const 4) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -6803,7 +6804,7 @@ (i64.const 8) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -6833,7 +6834,7 @@ (i64.const 8) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -6872,7 +6873,7 @@ (i64.const 8) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -6911,7 +6912,7 @@ (i64.const 8) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -6950,7 +6951,7 @@ (i64.const 8) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -6989,7 +6990,7 @@ (i64.const 4) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -7019,7 +7020,7 @@ (i64.const 4) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -7058,7 +7059,7 @@ (i64.const 4) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -7097,7 +7098,7 @@ (i64.const 8) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -7127,7 +7128,7 @@ (i64.const 8) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -7166,7 +7167,7 @@ (i64.const 8) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -7205,7 +7206,7 @@ (i64.const 8) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -7244,7 +7245,7 @@ (i64.const 16) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -7274,7 +7275,7 @@ (i64.const 16) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -7313,7 +7314,7 @@ (i64.const 16) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -7352,7 +7353,7 @@ (i64.const 16) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -7391,7 +7392,7 @@ (i64.const 16) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -7430,7 +7431,7 @@ (i64.const 1) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -7461,7 +7462,7 @@ (i64.const 1) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -7492,7 +7493,7 @@ (i64.const 2) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -7523,7 +7524,7 @@ (i64.const 2) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -7563,7 +7564,7 @@ (i64.const 2) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -7603,7 +7604,7 @@ (i64.const 4) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -7634,7 +7635,7 @@ (i64.const 4) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -7674,7 +7675,7 @@ (i64.const 4) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -7714,7 +7715,7 @@ (i64.const 4) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -7754,7 +7755,7 @@ (i64.const 1) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -7785,7 +7786,7 @@ (i64.const 1) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -7816,7 +7817,7 @@ (i64.const 2) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -7847,7 +7848,7 @@ (i64.const 2) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -7887,7 +7888,7 @@ (i64.const 2) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -7927,7 +7928,7 @@ (i64.const 4) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -7958,7 +7959,7 @@ (i64.const 4) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -7998,7 +7999,7 @@ (i64.const 4) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -8038,7 +8039,7 @@ (i64.const 4) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -8078,7 +8079,7 @@ (i64.const 8) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -8109,7 +8110,7 @@ (i64.const 8) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -8149,7 +8150,7 @@ (i64.const 8) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -8189,7 +8190,7 @@ (i64.const 8) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -8229,7 +8230,7 @@ (i64.const 8) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -8269,7 +8270,7 @@ (i64.const 4) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -8300,7 +8301,7 @@ (i64.const 4) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -8340,7 +8341,7 @@ (i64.const 4) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -8380,7 +8381,7 @@ (i64.const 8) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -8411,7 +8412,7 @@ (i64.const 8) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -8451,7 +8452,7 @@ (i64.const 8) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -8491,7 +8492,7 @@ (i64.const 8) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -8531,7 +8532,7 @@ (i64.const 16) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -8562,7 +8563,7 @@ (i64.const 16) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -8602,7 +8603,7 @@ (i64.const 16) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -8642,7 +8643,7 @@ (i64.const 16) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -8682,7 +8683,7 @@ (i64.const 16) ) (i64.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )
binaryen/test/passes/safe-heap_enable-threads_enable-simd64.wast view
@@ -45,7 +45,7 @@ ;; pre-existing (module (type $FUNCSIG$v (func))- (import "env" "DYNAMICTOP_PTR" (global $DYNAMICTOP_PTR i32))+ (import "env" "emscripten_get_sbrk_ptr" (func $foo (result i64))) (import "env" "segfault" (func $segfault)) (import "env" "alignfault" (func $alignfault)) (memory $0 (shared i64 100 100))
binaryen/test/passes/safe-heap_low-memory-unused_enable-threads_enable-simd.txt view
@@ -5437,7 +5437,8 @@ (type $none_=>_none (func)) (type $i32_i32_f32_=>_none (func (param i32 i32 f32))) (type $i32_i32_=>_f32 (func (param i32 i32) (result f32)))- (import "env" "DYNAMICTOP_PTR" (global $DYNAMICTOP_PTR i32))+ (type $none_=>_i32 (func (result i32)))+ (import "env" "emscripten_get_sbrk_ptr" (func $foo (result i32))) (import "env" "segfault" (func $segfault)) (import "env" "alignfault" (func $alignfault)) (memory $0 (shared 100 100))@@ -5474,7 +5475,7 @@ (i32.const 1) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -5510,7 +5511,7 @@ (i32.const 1) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -5540,7 +5541,7 @@ (i32.const 1) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -5570,7 +5571,7 @@ (i32.const 1) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -5600,7 +5601,7 @@ (i32.const 2) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -5630,7 +5631,7 @@ (i32.const 2) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -5673,7 +5674,7 @@ (i32.const 2) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -5710,7 +5711,7 @@ (i32.const 2) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -5740,7 +5741,7 @@ (i32.const 2) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -5777,7 +5778,7 @@ (i32.const 2) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -5814,7 +5815,7 @@ (i32.const 4) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -5844,7 +5845,7 @@ (i32.const 4) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -5881,7 +5882,7 @@ (i32.const 4) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -5918,7 +5919,7 @@ (i32.const 4) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -5955,7 +5956,7 @@ (i32.const 1) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -5991,7 +5992,7 @@ (i32.const 1) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -6021,7 +6022,7 @@ (i32.const 1) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -6051,7 +6052,7 @@ (i32.const 1) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -6081,7 +6082,7 @@ (i32.const 2) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -6111,7 +6112,7 @@ (i32.const 2) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -6154,7 +6155,7 @@ (i32.const 2) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -6191,7 +6192,7 @@ (i32.const 2) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -6221,7 +6222,7 @@ (i32.const 2) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -6258,7 +6259,7 @@ (i32.const 2) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -6295,7 +6296,7 @@ (i32.const 4) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -6325,7 +6326,7 @@ (i32.const 4) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -6362,7 +6363,7 @@ (i32.const 4) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -6405,7 +6406,7 @@ (i32.const 4) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -6442,7 +6443,7 @@ (i32.const 4) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -6472,7 +6473,7 @@ (i32.const 4) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -6509,7 +6510,7 @@ (i32.const 4) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -6546,7 +6547,7 @@ (i32.const 4) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -6583,7 +6584,7 @@ (i32.const 8) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -6613,7 +6614,7 @@ (i32.const 8) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -6650,7 +6651,7 @@ (i32.const 8) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -6687,7 +6688,7 @@ (i32.const 8) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -6724,7 +6725,7 @@ (i32.const 8) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -6761,7 +6762,7 @@ (i32.const 4) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -6791,7 +6792,7 @@ (i32.const 4) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -6828,7 +6829,7 @@ (i32.const 4) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -6865,7 +6866,7 @@ (i32.const 8) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -6895,7 +6896,7 @@ (i32.const 8) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -6932,7 +6933,7 @@ (i32.const 8) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -6969,7 +6970,7 @@ (i32.const 8) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -7006,7 +7007,7 @@ (i32.const 16) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -7036,7 +7037,7 @@ (i32.const 16) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -7073,7 +7074,7 @@ (i32.const 16) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -7110,7 +7111,7 @@ (i32.const 16) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -7147,7 +7148,7 @@ (i32.const 16) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -7184,7 +7185,7 @@ (i32.const 1) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -7215,7 +7216,7 @@ (i32.const 1) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -7246,7 +7247,7 @@ (i32.const 2) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -7277,7 +7278,7 @@ (i32.const 2) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -7315,7 +7316,7 @@ (i32.const 2) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -7353,7 +7354,7 @@ (i32.const 4) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -7384,7 +7385,7 @@ (i32.const 4) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -7422,7 +7423,7 @@ (i32.const 4) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -7460,7 +7461,7 @@ (i32.const 4) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -7498,7 +7499,7 @@ (i32.const 1) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -7529,7 +7530,7 @@ (i32.const 1) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -7560,7 +7561,7 @@ (i32.const 2) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -7591,7 +7592,7 @@ (i32.const 2) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -7629,7 +7630,7 @@ (i32.const 2) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -7667,7 +7668,7 @@ (i32.const 4) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -7698,7 +7699,7 @@ (i32.const 4) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -7736,7 +7737,7 @@ (i32.const 4) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -7774,7 +7775,7 @@ (i32.const 4) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -7812,7 +7813,7 @@ (i32.const 8) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -7843,7 +7844,7 @@ (i32.const 8) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -7881,7 +7882,7 @@ (i32.const 8) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -7919,7 +7920,7 @@ (i32.const 8) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -7957,7 +7958,7 @@ (i32.const 8) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -7995,7 +7996,7 @@ (i32.const 4) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -8026,7 +8027,7 @@ (i32.const 4) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -8064,7 +8065,7 @@ (i32.const 4) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -8102,7 +8103,7 @@ (i32.const 8) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -8133,7 +8134,7 @@ (i32.const 8) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -8171,7 +8172,7 @@ (i32.const 8) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -8209,7 +8210,7 @@ (i32.const 8) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -8247,7 +8248,7 @@ (i32.const 16) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -8278,7 +8279,7 @@ (i32.const 16) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -8316,7 +8317,7 @@ (i32.const 16) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -8354,7 +8355,7 @@ (i32.const 16) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )@@ -8392,7 +8393,7 @@ (i32.const 16) ) (i32.load- (global.get $DYNAMICTOP_PTR)+ (call $foo) ) ) )
binaryen/test/passes/safe-heap_low-memory-unused_enable-threads_enable-simd.wast view
@@ -45,7 +45,7 @@ ;; pre-existing (module (type $FUNCSIG$v (func))- (import "env" "DYNAMICTOP_PTR" (global $DYNAMICTOP_PTR i32))+ (import "env" "emscripten_get_sbrk_ptr" (func $foo (result i32))) (import "env" "segfault" (func $segfault)) (import "env" "alignfault" (func $alignfault)) (memory $0 (shared 100 100))
+ binaryen/test/passes/safe-heap_start-function.passes view
@@ -0,0 +1,1 @@+safe-heap
+ binaryen/test/passes/safe-heap_start-function.txt view
@@ -0,0 +1,1932 @@+(module+ (type $i32_i32_=>_i64 (func (param i32 i32) (result i64)))+ (type $i32_i32_i64_=>_none (func (param i32 i32 i64)))+ (type $i32_i32_=>_i32 (func (param i32 i32) (result i32)))+ (type $i32_i32_i32_=>_none (func (param i32 i32 i32)))+ (type $none_=>_none (func))+ (type $i32_i32_f64_=>_none (func (param i32 i32 f64)))+ (type $i32_i32_=>_f64 (func (param i32 i32) (result f64)))+ (type $i32_i32_f32_=>_none (func (param i32 i32 f32)))+ (type $i32_i32_=>_f32 (func (param i32 i32) (result f32)))+ (type $none_=>_i32 (func (result i32)))+ (import "env" "emscripten_get_sbrk_ptr" (func $emscripten_get_sbrk_ptr (result i32)))+ (import "env" "segfault" (func $segfault))+ (import "env" "alignfault" (func $alignfault))+ (memory $0 1 1)+ (start $foo)+ (func $foo+ (i32.store+ (i32.load+ (i32.const 1234)+ )+ (i32.const 5678)+ )+ )+ (func $bar+ (call $SAFE_HEAP_STORE_i32_4_4+ (call $SAFE_HEAP_LOAD_i32_4_4+ (i32.const 1234)+ (i32.const 0)+ )+ (i32.const 0)+ (i32.const 5678)+ )+ )+ (func $SAFE_HEAP_LOAD_i32_1_1 (param $0 i32) (param $1 i32) (result i32)+ (local $2 i32)+ (local.set $2+ (i32.add+ (local.get $0)+ (local.get $1)+ )+ )+ (if+ (i32.or+ (i32.eq+ (local.get $2)+ (i32.const 0)+ )+ (i32.gt_u+ (i32.add+ (local.get $2)+ (i32.const 1)+ )+ (i32.load+ (call $emscripten_get_sbrk_ptr)+ )+ )+ )+ (call $segfault)+ )+ (i32.load8_s+ (local.get $2)+ )+ )+ (func $SAFE_HEAP_LOAD_i32_1_U_1 (param $0 i32) (param $1 i32) (result i32)+ (local $2 i32)+ (local.set $2+ (i32.add+ (local.get $0)+ (local.get $1)+ )+ )+ (if+ (i32.or+ (i32.eq+ (local.get $2)+ (i32.const 0)+ )+ (i32.gt_u+ (i32.add+ (local.get $2)+ (i32.const 1)+ )+ (i32.load+ (call $emscripten_get_sbrk_ptr)+ )+ )+ )+ (call $segfault)+ )+ (i32.load8_u+ (local.get $2)+ )+ )+ (func $SAFE_HEAP_LOAD_i32_2_1 (param $0 i32) (param $1 i32) (result i32)+ (local $2 i32)+ (local.set $2+ (i32.add+ (local.get $0)+ (local.get $1)+ )+ )+ (if+ (i32.or+ (i32.eq+ (local.get $2)+ (i32.const 0)+ )+ (i32.gt_u+ (i32.add+ (local.get $2)+ (i32.const 2)+ )+ (i32.load+ (call $emscripten_get_sbrk_ptr)+ )+ )+ )+ (call $segfault)+ )+ (i32.load16_s align=1+ (local.get $2)+ )+ )+ (func $SAFE_HEAP_LOAD_i32_2_2 (param $0 i32) (param $1 i32) (result i32)+ (local $2 i32)+ (local.set $2+ (i32.add+ (local.get $0)+ (local.get $1)+ )+ )+ (if+ (i32.or+ (i32.eq+ (local.get $2)+ (i32.const 0)+ )+ (i32.gt_u+ (i32.add+ (local.get $2)+ (i32.const 2)+ )+ (i32.load+ (call $emscripten_get_sbrk_ptr)+ )+ )+ )+ (call $segfault)+ )+ (if+ (i32.and+ (local.get $2)+ (i32.const 1)+ )+ (call $alignfault)+ )+ (i32.load16_s+ (local.get $2)+ )+ )+ (func $SAFE_HEAP_LOAD_i32_2_U_1 (param $0 i32) (param $1 i32) (result i32)+ (local $2 i32)+ (local.set $2+ (i32.add+ (local.get $0)+ (local.get $1)+ )+ )+ (if+ (i32.or+ (i32.eq+ (local.get $2)+ (i32.const 0)+ )+ (i32.gt_u+ (i32.add+ (local.get $2)+ (i32.const 2)+ )+ (i32.load+ (call $emscripten_get_sbrk_ptr)+ )+ )+ )+ (call $segfault)+ )+ (i32.load16_u align=1+ (local.get $2)+ )+ )+ (func $SAFE_HEAP_LOAD_i32_2_U_2 (param $0 i32) (param $1 i32) (result i32)+ (local $2 i32)+ (local.set $2+ (i32.add+ (local.get $0)+ (local.get $1)+ )+ )+ (if+ (i32.or+ (i32.eq+ (local.get $2)+ (i32.const 0)+ )+ (i32.gt_u+ (i32.add+ (local.get $2)+ (i32.const 2)+ )+ (i32.load+ (call $emscripten_get_sbrk_ptr)+ )+ )+ )+ (call $segfault)+ )+ (if+ (i32.and+ (local.get $2)+ (i32.const 1)+ )+ (call $alignfault)+ )+ (i32.load16_u+ (local.get $2)+ )+ )+ (func $SAFE_HEAP_LOAD_i32_4_1 (param $0 i32) (param $1 i32) (result i32)+ (local $2 i32)+ (local.set $2+ (i32.add+ (local.get $0)+ (local.get $1)+ )+ )+ (if+ (i32.or+ (i32.eq+ (local.get $2)+ (i32.const 0)+ )+ (i32.gt_u+ (i32.add+ (local.get $2)+ (i32.const 4)+ )+ (i32.load+ (call $emscripten_get_sbrk_ptr)+ )+ )+ )+ (call $segfault)+ )+ (i32.load align=1+ (local.get $2)+ )+ )+ (func $SAFE_HEAP_LOAD_i32_4_2 (param $0 i32) (param $1 i32) (result i32)+ (local $2 i32)+ (local.set $2+ (i32.add+ (local.get $0)+ (local.get $1)+ )+ )+ (if+ (i32.or+ (i32.eq+ (local.get $2)+ (i32.const 0)+ )+ (i32.gt_u+ (i32.add+ (local.get $2)+ (i32.const 4)+ )+ (i32.load+ (call $emscripten_get_sbrk_ptr)+ )+ )+ )+ (call $segfault)+ )+ (if+ (i32.and+ (local.get $2)+ (i32.const 1)+ )+ (call $alignfault)+ )+ (i32.load align=2+ (local.get $2)+ )+ )+ (func $SAFE_HEAP_LOAD_i32_4_4 (param $0 i32) (param $1 i32) (result i32)+ (local $2 i32)+ (local.set $2+ (i32.add+ (local.get $0)+ (local.get $1)+ )+ )+ (if+ (i32.or+ (i32.eq+ (local.get $2)+ (i32.const 0)+ )+ (i32.gt_u+ (i32.add+ (local.get $2)+ (i32.const 4)+ )+ (i32.load+ (call $emscripten_get_sbrk_ptr)+ )+ )+ )+ (call $segfault)+ )+ (if+ (i32.and+ (local.get $2)+ (i32.const 3)+ )+ (call $alignfault)+ )+ (i32.load+ (local.get $2)+ )+ )+ (func $SAFE_HEAP_LOAD_i64_1_1 (param $0 i32) (param $1 i32) (result i64)+ (local $2 i32)+ (local.set $2+ (i32.add+ (local.get $0)+ (local.get $1)+ )+ )+ (if+ (i32.or+ (i32.eq+ (local.get $2)+ (i32.const 0)+ )+ (i32.gt_u+ (i32.add+ (local.get $2)+ (i32.const 1)+ )+ (i32.load+ (call $emscripten_get_sbrk_ptr)+ )+ )+ )+ (call $segfault)+ )+ (i64.load8_s+ (local.get $2)+ )+ )+ (func $SAFE_HEAP_LOAD_i64_1_U_1 (param $0 i32) (param $1 i32) (result i64)+ (local $2 i32)+ (local.set $2+ (i32.add+ (local.get $0)+ (local.get $1)+ )+ )+ (if+ (i32.or+ (i32.eq+ (local.get $2)+ (i32.const 0)+ )+ (i32.gt_u+ (i32.add+ (local.get $2)+ (i32.const 1)+ )+ (i32.load+ (call $emscripten_get_sbrk_ptr)+ )+ )+ )+ (call $segfault)+ )+ (i64.load8_u+ (local.get $2)+ )+ )+ (func $SAFE_HEAP_LOAD_i64_2_1 (param $0 i32) (param $1 i32) (result i64)+ (local $2 i32)+ (local.set $2+ (i32.add+ (local.get $0)+ (local.get $1)+ )+ )+ (if+ (i32.or+ (i32.eq+ (local.get $2)+ (i32.const 0)+ )+ (i32.gt_u+ (i32.add+ (local.get $2)+ (i32.const 2)+ )+ (i32.load+ (call $emscripten_get_sbrk_ptr)+ )+ )+ )+ (call $segfault)+ )+ (i64.load16_s align=1+ (local.get $2)+ )+ )+ (func $SAFE_HEAP_LOAD_i64_2_2 (param $0 i32) (param $1 i32) (result i64)+ (local $2 i32)+ (local.set $2+ (i32.add+ (local.get $0)+ (local.get $1)+ )+ )+ (if+ (i32.or+ (i32.eq+ (local.get $2)+ (i32.const 0)+ )+ (i32.gt_u+ (i32.add+ (local.get $2)+ (i32.const 2)+ )+ (i32.load+ (call $emscripten_get_sbrk_ptr)+ )+ )+ )+ (call $segfault)+ )+ (if+ (i32.and+ (local.get $2)+ (i32.const 1)+ )+ (call $alignfault)+ )+ (i64.load16_s+ (local.get $2)+ )+ )+ (func $SAFE_HEAP_LOAD_i64_2_U_1 (param $0 i32) (param $1 i32) (result i64)+ (local $2 i32)+ (local.set $2+ (i32.add+ (local.get $0)+ (local.get $1)+ )+ )+ (if+ (i32.or+ (i32.eq+ (local.get $2)+ (i32.const 0)+ )+ (i32.gt_u+ (i32.add+ (local.get $2)+ (i32.const 2)+ )+ (i32.load+ (call $emscripten_get_sbrk_ptr)+ )+ )+ )+ (call $segfault)+ )+ (i64.load16_u align=1+ (local.get $2)+ )+ )+ (func $SAFE_HEAP_LOAD_i64_2_U_2 (param $0 i32) (param $1 i32) (result i64)+ (local $2 i32)+ (local.set $2+ (i32.add+ (local.get $0)+ (local.get $1)+ )+ )+ (if+ (i32.or+ (i32.eq+ (local.get $2)+ (i32.const 0)+ )+ (i32.gt_u+ (i32.add+ (local.get $2)+ (i32.const 2)+ )+ (i32.load+ (call $emscripten_get_sbrk_ptr)+ )+ )+ )+ (call $segfault)+ )+ (if+ (i32.and+ (local.get $2)+ (i32.const 1)+ )+ (call $alignfault)+ )+ (i64.load16_u+ (local.get $2)+ )+ )+ (func $SAFE_HEAP_LOAD_i64_4_1 (param $0 i32) (param $1 i32) (result i64)+ (local $2 i32)+ (local.set $2+ (i32.add+ (local.get $0)+ (local.get $1)+ )+ )+ (if+ (i32.or+ (i32.eq+ (local.get $2)+ (i32.const 0)+ )+ (i32.gt_u+ (i32.add+ (local.get $2)+ (i32.const 4)+ )+ (i32.load+ (call $emscripten_get_sbrk_ptr)+ )+ )+ )+ (call $segfault)+ )+ (i64.load32_s align=1+ (local.get $2)+ )+ )+ (func $SAFE_HEAP_LOAD_i64_4_2 (param $0 i32) (param $1 i32) (result i64)+ (local $2 i32)+ (local.set $2+ (i32.add+ (local.get $0)+ (local.get $1)+ )+ )+ (if+ (i32.or+ (i32.eq+ (local.get $2)+ (i32.const 0)+ )+ (i32.gt_u+ (i32.add+ (local.get $2)+ (i32.const 4)+ )+ (i32.load+ (call $emscripten_get_sbrk_ptr)+ )+ )+ )+ (call $segfault)+ )+ (if+ (i32.and+ (local.get $2)+ (i32.const 1)+ )+ (call $alignfault)+ )+ (i64.load32_s align=2+ (local.get $2)+ )+ )+ (func $SAFE_HEAP_LOAD_i64_4_4 (param $0 i32) (param $1 i32) (result i64)+ (local $2 i32)+ (local.set $2+ (i32.add+ (local.get $0)+ (local.get $1)+ )+ )+ (if+ (i32.or+ (i32.eq+ (local.get $2)+ (i32.const 0)+ )+ (i32.gt_u+ (i32.add+ (local.get $2)+ (i32.const 4)+ )+ (i32.load+ (call $emscripten_get_sbrk_ptr)+ )+ )+ )+ (call $segfault)+ )+ (if+ (i32.and+ (local.get $2)+ (i32.const 3)+ )+ (call $alignfault)+ )+ (i64.load32_s+ (local.get $2)+ )+ )+ (func $SAFE_HEAP_LOAD_i64_4_U_1 (param $0 i32) (param $1 i32) (result i64)+ (local $2 i32)+ (local.set $2+ (i32.add+ (local.get $0)+ (local.get $1)+ )+ )+ (if+ (i32.or+ (i32.eq+ (local.get $2)+ (i32.const 0)+ )+ (i32.gt_u+ (i32.add+ (local.get $2)+ (i32.const 4)+ )+ (i32.load+ (call $emscripten_get_sbrk_ptr)+ )+ )+ )+ (call $segfault)+ )+ (i64.load32_u align=1+ (local.get $2)+ )+ )+ (func $SAFE_HEAP_LOAD_i64_4_U_2 (param $0 i32) (param $1 i32) (result i64)+ (local $2 i32)+ (local.set $2+ (i32.add+ (local.get $0)+ (local.get $1)+ )+ )+ (if+ (i32.or+ (i32.eq+ (local.get $2)+ (i32.const 0)+ )+ (i32.gt_u+ (i32.add+ (local.get $2)+ (i32.const 4)+ )+ (i32.load+ (call $emscripten_get_sbrk_ptr)+ )+ )+ )+ (call $segfault)+ )+ (if+ (i32.and+ (local.get $2)+ (i32.const 1)+ )+ (call $alignfault)+ )+ (i64.load32_u align=2+ (local.get $2)+ )+ )+ (func $SAFE_HEAP_LOAD_i64_4_U_4 (param $0 i32) (param $1 i32) (result i64)+ (local $2 i32)+ (local.set $2+ (i32.add+ (local.get $0)+ (local.get $1)+ )+ )+ (if+ (i32.or+ (i32.eq+ (local.get $2)+ (i32.const 0)+ )+ (i32.gt_u+ (i32.add+ (local.get $2)+ (i32.const 4)+ )+ (i32.load+ (call $emscripten_get_sbrk_ptr)+ )+ )+ )+ (call $segfault)+ )+ (if+ (i32.and+ (local.get $2)+ (i32.const 3)+ )+ (call $alignfault)+ )+ (i64.load32_u+ (local.get $2)+ )+ )+ (func $SAFE_HEAP_LOAD_i64_8_1 (param $0 i32) (param $1 i32) (result i64)+ (local $2 i32)+ (local.set $2+ (i32.add+ (local.get $0)+ (local.get $1)+ )+ )+ (if+ (i32.or+ (i32.eq+ (local.get $2)+ (i32.const 0)+ )+ (i32.gt_u+ (i32.add+ (local.get $2)+ (i32.const 8)+ )+ (i32.load+ (call $emscripten_get_sbrk_ptr)+ )+ )+ )+ (call $segfault)+ )+ (i64.load align=1+ (local.get $2)+ )+ )+ (func $SAFE_HEAP_LOAD_i64_8_2 (param $0 i32) (param $1 i32) (result i64)+ (local $2 i32)+ (local.set $2+ (i32.add+ (local.get $0)+ (local.get $1)+ )+ )+ (if+ (i32.or+ (i32.eq+ (local.get $2)+ (i32.const 0)+ )+ (i32.gt_u+ (i32.add+ (local.get $2)+ (i32.const 8)+ )+ (i32.load+ (call $emscripten_get_sbrk_ptr)+ )+ )+ )+ (call $segfault)+ )+ (if+ (i32.and+ (local.get $2)+ (i32.const 1)+ )+ (call $alignfault)+ )+ (i64.load align=2+ (local.get $2)+ )+ )+ (func $SAFE_HEAP_LOAD_i64_8_4 (param $0 i32) (param $1 i32) (result i64)+ (local $2 i32)+ (local.set $2+ (i32.add+ (local.get $0)+ (local.get $1)+ )+ )+ (if+ (i32.or+ (i32.eq+ (local.get $2)+ (i32.const 0)+ )+ (i32.gt_u+ (i32.add+ (local.get $2)+ (i32.const 8)+ )+ (i32.load+ (call $emscripten_get_sbrk_ptr)+ )+ )+ )+ (call $segfault)+ )+ (if+ (i32.and+ (local.get $2)+ (i32.const 3)+ )+ (call $alignfault)+ )+ (i64.load align=4+ (local.get $2)+ )+ )+ (func $SAFE_HEAP_LOAD_i64_8_8 (param $0 i32) (param $1 i32) (result i64)+ (local $2 i32)+ (local.set $2+ (i32.add+ (local.get $0)+ (local.get $1)+ )+ )+ (if+ (i32.or+ (i32.eq+ (local.get $2)+ (i32.const 0)+ )+ (i32.gt_u+ (i32.add+ (local.get $2)+ (i32.const 8)+ )+ (i32.load+ (call $emscripten_get_sbrk_ptr)+ )+ )+ )+ (call $segfault)+ )+ (if+ (i32.and+ (local.get $2)+ (i32.const 7)+ )+ (call $alignfault)+ )+ (i64.load+ (local.get $2)+ )+ )+ (func $SAFE_HEAP_LOAD_f32_4_1 (param $0 i32) (param $1 i32) (result f32)+ (local $2 i32)+ (local.set $2+ (i32.add+ (local.get $0)+ (local.get $1)+ )+ )+ (if+ (i32.or+ (i32.eq+ (local.get $2)+ (i32.const 0)+ )+ (i32.gt_u+ (i32.add+ (local.get $2)+ (i32.const 4)+ )+ (i32.load+ (call $emscripten_get_sbrk_ptr)+ )+ )+ )+ (call $segfault)+ )+ (f32.load align=1+ (local.get $2)+ )+ )+ (func $SAFE_HEAP_LOAD_f32_4_2 (param $0 i32) (param $1 i32) (result f32)+ (local $2 i32)+ (local.set $2+ (i32.add+ (local.get $0)+ (local.get $1)+ )+ )+ (if+ (i32.or+ (i32.eq+ (local.get $2)+ (i32.const 0)+ )+ (i32.gt_u+ (i32.add+ (local.get $2)+ (i32.const 4)+ )+ (i32.load+ (call $emscripten_get_sbrk_ptr)+ )+ )+ )+ (call $segfault)+ )+ (if+ (i32.and+ (local.get $2)+ (i32.const 1)+ )+ (call $alignfault)+ )+ (f32.load align=2+ (local.get $2)+ )+ )+ (func $SAFE_HEAP_LOAD_f32_4_4 (param $0 i32) (param $1 i32) (result f32)+ (local $2 i32)+ (local.set $2+ (i32.add+ (local.get $0)+ (local.get $1)+ )+ )+ (if+ (i32.or+ (i32.eq+ (local.get $2)+ (i32.const 0)+ )+ (i32.gt_u+ (i32.add+ (local.get $2)+ (i32.const 4)+ )+ (i32.load+ (call $emscripten_get_sbrk_ptr)+ )+ )+ )+ (call $segfault)+ )+ (if+ (i32.and+ (local.get $2)+ (i32.const 3)+ )+ (call $alignfault)+ )+ (f32.load+ (local.get $2)+ )+ )+ (func $SAFE_HEAP_LOAD_f64_8_1 (param $0 i32) (param $1 i32) (result f64)+ (local $2 i32)+ (local.set $2+ (i32.add+ (local.get $0)+ (local.get $1)+ )+ )+ (if+ (i32.or+ (i32.eq+ (local.get $2)+ (i32.const 0)+ )+ (i32.gt_u+ (i32.add+ (local.get $2)+ (i32.const 8)+ )+ (i32.load+ (call $emscripten_get_sbrk_ptr)+ )+ )+ )+ (call $segfault)+ )+ (f64.load align=1+ (local.get $2)+ )+ )+ (func $SAFE_HEAP_LOAD_f64_8_2 (param $0 i32) (param $1 i32) (result f64)+ (local $2 i32)+ (local.set $2+ (i32.add+ (local.get $0)+ (local.get $1)+ )+ )+ (if+ (i32.or+ (i32.eq+ (local.get $2)+ (i32.const 0)+ )+ (i32.gt_u+ (i32.add+ (local.get $2)+ (i32.const 8)+ )+ (i32.load+ (call $emscripten_get_sbrk_ptr)+ )+ )+ )+ (call $segfault)+ )+ (if+ (i32.and+ (local.get $2)+ (i32.const 1)+ )+ (call $alignfault)+ )+ (f64.load align=2+ (local.get $2)+ )+ )+ (func $SAFE_HEAP_LOAD_f64_8_4 (param $0 i32) (param $1 i32) (result f64)+ (local $2 i32)+ (local.set $2+ (i32.add+ (local.get $0)+ (local.get $1)+ )+ )+ (if+ (i32.or+ (i32.eq+ (local.get $2)+ (i32.const 0)+ )+ (i32.gt_u+ (i32.add+ (local.get $2)+ (i32.const 8)+ )+ (i32.load+ (call $emscripten_get_sbrk_ptr)+ )+ )+ )+ (call $segfault)+ )+ (if+ (i32.and+ (local.get $2)+ (i32.const 3)+ )+ (call $alignfault)+ )+ (f64.load align=4+ (local.get $2)+ )+ )+ (func $SAFE_HEAP_LOAD_f64_8_8 (param $0 i32) (param $1 i32) (result f64)+ (local $2 i32)+ (local.set $2+ (i32.add+ (local.get $0)+ (local.get $1)+ )+ )+ (if+ (i32.or+ (i32.eq+ (local.get $2)+ (i32.const 0)+ )+ (i32.gt_u+ (i32.add+ (local.get $2)+ (i32.const 8)+ )+ (i32.load+ (call $emscripten_get_sbrk_ptr)+ )+ )+ )+ (call $segfault)+ )+ (if+ (i32.and+ (local.get $2)+ (i32.const 7)+ )+ (call $alignfault)+ )+ (f64.load+ (local.get $2)+ )+ )+ (func $SAFE_HEAP_STORE_i32_1_1 (param $0 i32) (param $1 i32) (param $2 i32)+ (local $3 i32)+ (local.set $3+ (i32.add+ (local.get $0)+ (local.get $1)+ )+ )+ (if+ (i32.or+ (i32.eq+ (local.get $3)+ (i32.const 0)+ )+ (i32.gt_u+ (i32.add+ (local.get $3)+ (i32.const 1)+ )+ (i32.load+ (call $emscripten_get_sbrk_ptr)+ )+ )+ )+ (call $segfault)+ )+ (i32.store8+ (local.get $3)+ (local.get $2)+ )+ )+ (func $SAFE_HEAP_STORE_i32_2_1 (param $0 i32) (param $1 i32) (param $2 i32)+ (local $3 i32)+ (local.set $3+ (i32.add+ (local.get $0)+ (local.get $1)+ )+ )+ (if+ (i32.or+ (i32.eq+ (local.get $3)+ (i32.const 0)+ )+ (i32.gt_u+ (i32.add+ (local.get $3)+ (i32.const 2)+ )+ (i32.load+ (call $emscripten_get_sbrk_ptr)+ )+ )+ )+ (call $segfault)+ )+ (i32.store16 align=1+ (local.get $3)+ (local.get $2)+ )+ )+ (func $SAFE_HEAP_STORE_i32_2_2 (param $0 i32) (param $1 i32) (param $2 i32)+ (local $3 i32)+ (local.set $3+ (i32.add+ (local.get $0)+ (local.get $1)+ )+ )+ (if+ (i32.or+ (i32.eq+ (local.get $3)+ (i32.const 0)+ )+ (i32.gt_u+ (i32.add+ (local.get $3)+ (i32.const 2)+ )+ (i32.load+ (call $emscripten_get_sbrk_ptr)+ )+ )+ )+ (call $segfault)+ )+ (if+ (i32.and+ (local.get $3)+ (i32.const 1)+ )+ (call $alignfault)+ )+ (i32.store16+ (local.get $3)+ (local.get $2)+ )+ )+ (func $SAFE_HEAP_STORE_i32_4_1 (param $0 i32) (param $1 i32) (param $2 i32)+ (local $3 i32)+ (local.set $3+ (i32.add+ (local.get $0)+ (local.get $1)+ )+ )+ (if+ (i32.or+ (i32.eq+ (local.get $3)+ (i32.const 0)+ )+ (i32.gt_u+ (i32.add+ (local.get $3)+ (i32.const 4)+ )+ (i32.load+ (call $emscripten_get_sbrk_ptr)+ )+ )+ )+ (call $segfault)+ )+ (i32.store align=1+ (local.get $3)+ (local.get $2)+ )+ )+ (func $SAFE_HEAP_STORE_i32_4_2 (param $0 i32) (param $1 i32) (param $2 i32)+ (local $3 i32)+ (local.set $3+ (i32.add+ (local.get $0)+ (local.get $1)+ )+ )+ (if+ (i32.or+ (i32.eq+ (local.get $3)+ (i32.const 0)+ )+ (i32.gt_u+ (i32.add+ (local.get $3)+ (i32.const 4)+ )+ (i32.load+ (call $emscripten_get_sbrk_ptr)+ )+ )+ )+ (call $segfault)+ )+ (if+ (i32.and+ (local.get $3)+ (i32.const 1)+ )+ (call $alignfault)+ )+ (i32.store align=2+ (local.get $3)+ (local.get $2)+ )+ )+ (func $SAFE_HEAP_STORE_i32_4_4 (param $0 i32) (param $1 i32) (param $2 i32)+ (local $3 i32)+ (local.set $3+ (i32.add+ (local.get $0)+ (local.get $1)+ )+ )+ (if+ (i32.or+ (i32.eq+ (local.get $3)+ (i32.const 0)+ )+ (i32.gt_u+ (i32.add+ (local.get $3)+ (i32.const 4)+ )+ (i32.load+ (call $emscripten_get_sbrk_ptr)+ )+ )+ )+ (call $segfault)+ )+ (if+ (i32.and+ (local.get $3)+ (i32.const 3)+ )+ (call $alignfault)+ )+ (i32.store+ (local.get $3)+ (local.get $2)+ )+ )+ (func $SAFE_HEAP_STORE_i64_1_1 (param $0 i32) (param $1 i32) (param $2 i64)+ (local $3 i32)+ (local.set $3+ (i32.add+ (local.get $0)+ (local.get $1)+ )+ )+ (if+ (i32.or+ (i32.eq+ (local.get $3)+ (i32.const 0)+ )+ (i32.gt_u+ (i32.add+ (local.get $3)+ (i32.const 1)+ )+ (i32.load+ (call $emscripten_get_sbrk_ptr)+ )+ )+ )+ (call $segfault)+ )+ (i64.store8+ (local.get $3)+ (local.get $2)+ )+ )+ (func $SAFE_HEAP_STORE_i64_2_1 (param $0 i32) (param $1 i32) (param $2 i64)+ (local $3 i32)+ (local.set $3+ (i32.add+ (local.get $0)+ (local.get $1)+ )+ )+ (if+ (i32.or+ (i32.eq+ (local.get $3)+ (i32.const 0)+ )+ (i32.gt_u+ (i32.add+ (local.get $3)+ (i32.const 2)+ )+ (i32.load+ (call $emscripten_get_sbrk_ptr)+ )+ )+ )+ (call $segfault)+ )+ (i64.store16 align=1+ (local.get $3)+ (local.get $2)+ )+ )+ (func $SAFE_HEAP_STORE_i64_2_2 (param $0 i32) (param $1 i32) (param $2 i64)+ (local $3 i32)+ (local.set $3+ (i32.add+ (local.get $0)+ (local.get $1)+ )+ )+ (if+ (i32.or+ (i32.eq+ (local.get $3)+ (i32.const 0)+ )+ (i32.gt_u+ (i32.add+ (local.get $3)+ (i32.const 2)+ )+ (i32.load+ (call $emscripten_get_sbrk_ptr)+ )+ )+ )+ (call $segfault)+ )+ (if+ (i32.and+ (local.get $3)+ (i32.const 1)+ )+ (call $alignfault)+ )+ (i64.store16+ (local.get $3)+ (local.get $2)+ )+ )+ (func $SAFE_HEAP_STORE_i64_4_1 (param $0 i32) (param $1 i32) (param $2 i64)+ (local $3 i32)+ (local.set $3+ (i32.add+ (local.get $0)+ (local.get $1)+ )+ )+ (if+ (i32.or+ (i32.eq+ (local.get $3)+ (i32.const 0)+ )+ (i32.gt_u+ (i32.add+ (local.get $3)+ (i32.const 4)+ )+ (i32.load+ (call $emscripten_get_sbrk_ptr)+ )+ )+ )+ (call $segfault)+ )+ (i64.store32 align=1+ (local.get $3)+ (local.get $2)+ )+ )+ (func $SAFE_HEAP_STORE_i64_4_2 (param $0 i32) (param $1 i32) (param $2 i64)+ (local $3 i32)+ (local.set $3+ (i32.add+ (local.get $0)+ (local.get $1)+ )+ )+ (if+ (i32.or+ (i32.eq+ (local.get $3)+ (i32.const 0)+ )+ (i32.gt_u+ (i32.add+ (local.get $3)+ (i32.const 4)+ )+ (i32.load+ (call $emscripten_get_sbrk_ptr)+ )+ )+ )+ (call $segfault)+ )+ (if+ (i32.and+ (local.get $3)+ (i32.const 1)+ )+ (call $alignfault)+ )+ (i64.store32 align=2+ (local.get $3)+ (local.get $2)+ )+ )+ (func $SAFE_HEAP_STORE_i64_4_4 (param $0 i32) (param $1 i32) (param $2 i64)+ (local $3 i32)+ (local.set $3+ (i32.add+ (local.get $0)+ (local.get $1)+ )+ )+ (if+ (i32.or+ (i32.eq+ (local.get $3)+ (i32.const 0)+ )+ (i32.gt_u+ (i32.add+ (local.get $3)+ (i32.const 4)+ )+ (i32.load+ (call $emscripten_get_sbrk_ptr)+ )+ )+ )+ (call $segfault)+ )+ (if+ (i32.and+ (local.get $3)+ (i32.const 3)+ )+ (call $alignfault)+ )+ (i64.store32+ (local.get $3)+ (local.get $2)+ )+ )+ (func $SAFE_HEAP_STORE_i64_8_1 (param $0 i32) (param $1 i32) (param $2 i64)+ (local $3 i32)+ (local.set $3+ (i32.add+ (local.get $0)+ (local.get $1)+ )+ )+ (if+ (i32.or+ (i32.eq+ (local.get $3)+ (i32.const 0)+ )+ (i32.gt_u+ (i32.add+ (local.get $3)+ (i32.const 8)+ )+ (i32.load+ (call $emscripten_get_sbrk_ptr)+ )+ )+ )+ (call $segfault)+ )+ (i64.store align=1+ (local.get $3)+ (local.get $2)+ )+ )+ (func $SAFE_HEAP_STORE_i64_8_2 (param $0 i32) (param $1 i32) (param $2 i64)+ (local $3 i32)+ (local.set $3+ (i32.add+ (local.get $0)+ (local.get $1)+ )+ )+ (if+ (i32.or+ (i32.eq+ (local.get $3)+ (i32.const 0)+ )+ (i32.gt_u+ (i32.add+ (local.get $3)+ (i32.const 8)+ )+ (i32.load+ (call $emscripten_get_sbrk_ptr)+ )+ )+ )+ (call $segfault)+ )+ (if+ (i32.and+ (local.get $3)+ (i32.const 1)+ )+ (call $alignfault)+ )+ (i64.store align=2+ (local.get $3)+ (local.get $2)+ )+ )+ (func $SAFE_HEAP_STORE_i64_8_4 (param $0 i32) (param $1 i32) (param $2 i64)+ (local $3 i32)+ (local.set $3+ (i32.add+ (local.get $0)+ (local.get $1)+ )+ )+ (if+ (i32.or+ (i32.eq+ (local.get $3)+ (i32.const 0)+ )+ (i32.gt_u+ (i32.add+ (local.get $3)+ (i32.const 8)+ )+ (i32.load+ (call $emscripten_get_sbrk_ptr)+ )+ )+ )+ (call $segfault)+ )+ (if+ (i32.and+ (local.get $3)+ (i32.const 3)+ )+ (call $alignfault)+ )+ (i64.store align=4+ (local.get $3)+ (local.get $2)+ )+ )+ (func $SAFE_HEAP_STORE_i64_8_8 (param $0 i32) (param $1 i32) (param $2 i64)+ (local $3 i32)+ (local.set $3+ (i32.add+ (local.get $0)+ (local.get $1)+ )+ )+ (if+ (i32.or+ (i32.eq+ (local.get $3)+ (i32.const 0)+ )+ (i32.gt_u+ (i32.add+ (local.get $3)+ (i32.const 8)+ )+ (i32.load+ (call $emscripten_get_sbrk_ptr)+ )+ )+ )+ (call $segfault)+ )+ (if+ (i32.and+ (local.get $3)+ (i32.const 7)+ )+ (call $alignfault)+ )+ (i64.store+ (local.get $3)+ (local.get $2)+ )+ )+ (func $SAFE_HEAP_STORE_f32_4_1 (param $0 i32) (param $1 i32) (param $2 f32)+ (local $3 i32)+ (local.set $3+ (i32.add+ (local.get $0)+ (local.get $1)+ )+ )+ (if+ (i32.or+ (i32.eq+ (local.get $3)+ (i32.const 0)+ )+ (i32.gt_u+ (i32.add+ (local.get $3)+ (i32.const 4)+ )+ (i32.load+ (call $emscripten_get_sbrk_ptr)+ )+ )+ )+ (call $segfault)+ )+ (f32.store align=1+ (local.get $3)+ (local.get $2)+ )+ )+ (func $SAFE_HEAP_STORE_f32_4_2 (param $0 i32) (param $1 i32) (param $2 f32)+ (local $3 i32)+ (local.set $3+ (i32.add+ (local.get $0)+ (local.get $1)+ )+ )+ (if+ (i32.or+ (i32.eq+ (local.get $3)+ (i32.const 0)+ )+ (i32.gt_u+ (i32.add+ (local.get $3)+ (i32.const 4)+ )+ (i32.load+ (call $emscripten_get_sbrk_ptr)+ )+ )+ )+ (call $segfault)+ )+ (if+ (i32.and+ (local.get $3)+ (i32.const 1)+ )+ (call $alignfault)+ )+ (f32.store align=2+ (local.get $3)+ (local.get $2)+ )+ )+ (func $SAFE_HEAP_STORE_f32_4_4 (param $0 i32) (param $1 i32) (param $2 f32)+ (local $3 i32)+ (local.set $3+ (i32.add+ (local.get $0)+ (local.get $1)+ )+ )+ (if+ (i32.or+ (i32.eq+ (local.get $3)+ (i32.const 0)+ )+ (i32.gt_u+ (i32.add+ (local.get $3)+ (i32.const 4)+ )+ (i32.load+ (call $emscripten_get_sbrk_ptr)+ )+ )+ )+ (call $segfault)+ )+ (if+ (i32.and+ (local.get $3)+ (i32.const 3)+ )+ (call $alignfault)+ )+ (f32.store+ (local.get $3)+ (local.get $2)+ )+ )+ (func $SAFE_HEAP_STORE_f64_8_1 (param $0 i32) (param $1 i32) (param $2 f64)+ (local $3 i32)+ (local.set $3+ (i32.add+ (local.get $0)+ (local.get $1)+ )+ )+ (if+ (i32.or+ (i32.eq+ (local.get $3)+ (i32.const 0)+ )+ (i32.gt_u+ (i32.add+ (local.get $3)+ (i32.const 8)+ )+ (i32.load+ (call $emscripten_get_sbrk_ptr)+ )+ )+ )+ (call $segfault)+ )+ (f64.store align=1+ (local.get $3)+ (local.get $2)+ )+ )+ (func $SAFE_HEAP_STORE_f64_8_2 (param $0 i32) (param $1 i32) (param $2 f64)+ (local $3 i32)+ (local.set $3+ (i32.add+ (local.get $0)+ (local.get $1)+ )+ )+ (if+ (i32.or+ (i32.eq+ (local.get $3)+ (i32.const 0)+ )+ (i32.gt_u+ (i32.add+ (local.get $3)+ (i32.const 8)+ )+ (i32.load+ (call $emscripten_get_sbrk_ptr)+ )+ )+ )+ (call $segfault)+ )+ (if+ (i32.and+ (local.get $3)+ (i32.const 1)+ )+ (call $alignfault)+ )+ (f64.store align=2+ (local.get $3)+ (local.get $2)+ )+ )+ (func $SAFE_HEAP_STORE_f64_8_4 (param $0 i32) (param $1 i32) (param $2 f64)+ (local $3 i32)+ (local.set $3+ (i32.add+ (local.get $0)+ (local.get $1)+ )+ )+ (if+ (i32.or+ (i32.eq+ (local.get $3)+ (i32.const 0)+ )+ (i32.gt_u+ (i32.add+ (local.get $3)+ (i32.const 8)+ )+ (i32.load+ (call $emscripten_get_sbrk_ptr)+ )+ )+ )+ (call $segfault)+ )+ (if+ (i32.and+ (local.get $3)+ (i32.const 3)+ )+ (call $alignfault)+ )+ (f64.store align=4+ (local.get $3)+ (local.get $2)+ )+ )+ (func $SAFE_HEAP_STORE_f64_8_8 (param $0 i32) (param $1 i32) (param $2 f64)+ (local $3 i32)+ (local.set $3+ (i32.add+ (local.get $0)+ (local.get $1)+ )+ )+ (if+ (i32.or+ (i32.eq+ (local.get $3)+ (i32.const 0)+ )+ (i32.gt_u+ (i32.add+ (local.get $3)+ (i32.const 8)+ )+ (i32.load+ (call $emscripten_get_sbrk_ptr)+ )+ )+ )+ (call $segfault)+ )+ (if+ (i32.and+ (local.get $3)+ (i32.const 7)+ )+ (call $alignfault)+ )+ (f64.store+ (local.get $3)+ (local.get $2)+ )+ )+)
+ binaryen/test/passes/safe-heap_start-function.wast view
@@ -0,0 +1,11 @@+(module+ (memory 1 1)+ (func $foo+ ;; should not be modified because its the start function+ (i32.store (i32.load (i32.const 1234)) (i32.const 5678))+ )+ (func $bar+ (i32.store (i32.load (i32.const 1234)) (i32.const 5678))+ )+ (start $foo)+)
+ binaryen/test/passes/simplify-globals_all-features_fuzz-exec.txt view
@@ -0,0 +1,20 @@+[fuzz-exec] calling export+[fuzz-exec] note result: export => funcref(0)+(module+ (type $f32_ref?|i31|_i64_f64_funcref_=>_none (func (param f32 (ref null i31) i64 f64 funcref)))+ (type $none_=>_funcref (func (result funcref)))+ (global $global$0 (mut funcref) (ref.null func))+ (export "export" (func $1))+ (func $0 (param $0 f32) (param $1 (ref null i31)) (param $2 i64) (param $3 f64) (param $4 funcref)+ (nop)+ )+ (func $1 (result funcref)+ (global.set $global$0+ (ref.func $0)+ )+ (ref.func $0)+ )+)+[fuzz-exec] calling export+[fuzz-exec] note result: export => funcref(0)+[fuzz-exec] comparing export
+ binaryen/test/passes/simplify-globals_all-features_fuzz-exec.wast view
@@ -0,0 +1,14 @@+(module+ (global $global$0 (mut funcref) (ref.null func))+ (func $0 (param $0 f32) (param $1 i31ref) (param $2 i64) (param $3 f64) (param $4 funcref)+ (nop)+ )+ (func "export" (result funcref)+ ;; this set's value will be applied to the get right after it. we should carry+ ;; over the specific typed function reference type properly while doing so.+ (global.set $global$0+ (ref.func $0)+ )+ (global.get $global$0)+ )+)
binaryen/test/passes/simplify-locals_all-features.txt view
@@ -6,9 +6,9 @@ (type $i32_i32_i32_=>_i32 (func (param i32 i32 i32) (result i32))) (type $i32_i32_i32_i32_=>_i32 (func (param i32 i32 i32 i32) (result i32))) (type $i32_=>_none (func (param i32)))- (type $i32_i32_=>_none (func (param i32 i32))) (type $i64_=>_none (func (param i64))) (type $f32_=>_none (func (param f32)))+ (type $i32_i32_=>_none (func (param i32 i32))) (type $i32_i32_=>_i32 (func (param i32 i32) (result i32))) (type $i32_i32_i32_i32_i32_=>_i32 (func (param i32 i32 i32 i32 i32) (result i32))) (type $i32_f64_f64_f32_i32_=>_f64 (func (param i32 f64 f64 f32 i32) (result f64)))@@ -1127,8 +1127,8 @@ (type $i32_=>_i32 (func (param i32) (result i32))) (type $i32_i32_i32_i32_i32_=>_i32 (func (param i32 i32 i32 i32 i32) (result i32))) (type $i32_=>_none (func (param i32)))- (type $i32_i32_=>_none (func (param i32 i32))) (type $f32_=>_none (func (param f32)))+ (type $i32_i32_=>_none (func (param i32 i32))) (type $i32_i32_=>_i32 (func (param i32 i32) (result i32))) (type $none_=>_f64 (func (result f64))) (type $i32_i32_=>_f64 (func (param i32 i32) (result f64)))@@ -1896,8 +1896,8 @@ ) (module (type $none_=>_none (func))- (type $i32_exnref_=>_none (func (param i32 exnref))) (type $exnref_=>_none (func (param exnref)))+ (type $i32_exnref_=>_none (func (param i32 exnref))) (type $none_=>_i32 (func (result i32))) (type $none_=>_exnref (func (result exnref))) (event $event$0 (attr 0) (param))@@ -2037,6 +2037,24 @@ ) (data.drop 0) (local.get $0)+ )+ )+)+(module+ (type $eqref_ref?|i31|_=>_i32 (func (param eqref (ref null i31)) (result i32)))+ (export "test" (func $0))+ (func $0 (param $0 eqref) (param $1 (ref null i31)) (result i32)+ (local $2 eqref)+ (local $3 (ref null i31))+ (local.set $2+ (local.get $0)+ )+ (local.set $0+ (local.get $3)+ )+ (ref.eq+ (local.get $2)+ (local.get $1) ) ) )
binaryen/test/passes/simplify-locals_all-features.wast view
@@ -1800,3 +1800,23 @@ ) ) )+;; do not be confused by subtyping: when an index is set, even to another type,+;; it is no longer equivalent+;; (see https://github.com/WebAssembly/binaryen/issues/3266)+(module+ (func "test" (param $0 eqref) (param $1 i31ref) (result i32)+ (local $2 eqref)+ (local $3 i31ref)+ (local.set $2+ (local.get $0) ;; $0 and $2 are equivalent+ )+ (local.set $0 ;; set $0 to something with another type+ (local.get $3)+ )+ ;; compares a null eqref and a zero i31ref - should be false+ (ref.eq+ (local.get $2)+ (local.get $1)+ )+ )+)
binaryen/test/passes/simplify-locals_all-features_disable-exception-handling.txt view
@@ -6,9 +6,9 @@ (type $i32_i32_i32_=>_i32 (func (param i32 i32 i32) (result i32))) (type $i32_i32_i32_i32_=>_i32 (func (param i32 i32 i32 i32) (result i32))) (type $i32_=>_none (func (param i32)))- (type $i32_i32_=>_none (func (param i32 i32))) (type $i64_=>_none (func (param i64))) (type $f32_=>_none (func (param f32)))+ (type $i32_i32_=>_none (func (param i32 i32))) (type $i32_i32_=>_i32 (func (param i32 i32) (result i32))) (type $i32_i32_i32_i32_i32_=>_i32 (func (param i32 i32 i32 i32 i32) (result i32))) (type $i32_f64_f64_f32_i32_=>_f64 (func (param i32 f64 f64 f32 i32) (result f64)))@@ -1121,8 +1121,8 @@ (type $i32_=>_i32 (func (param i32) (result i32))) (type $i32_i32_i32_i32_i32_=>_i32 (func (param i32 i32 i32 i32 i32) (result i32))) (type $i32_=>_none (func (param i32)))- (type $i32_i32_=>_none (func (param i32 i32))) (type $f32_=>_none (func (param f32)))+ (type $i32_i32_=>_none (func (param i32 i32))) (type $i32_i32_=>_i32 (func (param i32 i32) (result i32))) (type $none_=>_f64 (func (result f64))) (type $i32_i32_=>_f64 (func (param i32 i32) (result f64)))
− binaryen/test/passes/spill-pointers.txt
@@ -1,1291 +0,0 @@-(module- (type $none_=>_none (func))- (type $i32_=>_i32 (func (param i32) (result i32)))- (type $none_=>_i32 (func (result i32)))- (type $i32_i32_=>_none (func (param i32 i32)))- (type $i32_=>_none (func (param i32)))- (type $f64_=>_none (func (param f64)))- (import "env" "STACKTOP" (global $STACKTOP$asm2wasm$import i32))- (import "env" "segfault" (func $segfault (param i32)))- (memory $0 10)- (table $0 1 1 funcref)- (global $stack_ptr (mut i32) (global.get $STACKTOP$asm2wasm$import))- (func $nothing- (nop)- )- (func $not-alive- (local $x i32)- (local.set $x- (i32.const 1)- )- (call $nothing)- )- (func $spill- (local $x i32)- (local $1 i32)- (local.set $1- (global.get $stack_ptr)- )- (global.set $stack_ptr- (i32.add- (local.get $1)- (i32.const 16)- )- )- (block- (block- (i32.store- (local.get $1)- (local.get $x)- )- (call $nothing)- )- (drop- (local.get $x)- )- )- (global.set $stack_ptr- (local.get $1)- )- )- (func $ignore-non-pointers- (local $x i32)- (local $y i64)- (local $z f32)- (local $w f64)- (local $4 i32)- (local.set $4- (global.get $stack_ptr)- )- (global.set $stack_ptr- (i32.add- (local.get $4)- (i32.const 16)- )- )- (block- (local.set $x- (i32.const 1)- )- (local.set $y- (i64.const 1)- )- (local.set $z- (f32.const 1)- )- (local.set $w- (f64.const 1)- )- (block- (i32.store- (local.get $4)- (local.get $x)- )- (call $nothing)- )- (drop- (local.get $x)- )- (drop- (local.get $y)- )- (drop- (local.get $z)- )- (drop- (local.get $w)- )- )- (global.set $stack_ptr- (local.get $4)- )- )- (func $spill4- (local $x i32)- (local $y i32)- (local $z i32)- (local $w i32)- (local $4 i32)- (local.set $4- (global.get $stack_ptr)- )- (global.set $stack_ptr- (i32.add- (local.get $4)- (i32.const 16)- )- )- (block- (local.set $x- (i32.const 1)- )- (local.set $y- (i32.const 1)- )- (local.set $z- (i32.const 1)- )- (local.set $w- (i32.const 1)- )- (block- (i32.store- (local.get $4)- (local.get $x)- )- (i32.store offset=4- (local.get $4)- (local.get $y)- )- (i32.store offset=8- (local.get $4)- (local.get $z)- )- (i32.store offset=12- (local.get $4)- (local.get $w)- )- (call $nothing)- )- (drop- (local.get $x)- )- (drop- (local.get $y)- )- (drop- (local.get $z)- )- (drop- (local.get $w)- )- )- (global.set $stack_ptr- (local.get $4)- )- )- (func $spill5- (local $x i32)- (local $y i32)- (local $z i32)- (local $w i32)- (local $a i32)- (local $5 i32)- (local.set $5- (global.get $stack_ptr)- )- (global.set $stack_ptr- (i32.add- (local.get $5)- (i32.const 32)- )- )- (block- (local.set $x- (i32.const 1)- )- (local.set $y- (i32.const 1)- )- (local.set $z- (i32.const 1)- )- (local.set $w- (i32.const 1)- )- (local.set $a- (i32.const 1)- )- (block- (i32.store- (local.get $5)- (local.get $x)- )- (i32.store offset=4- (local.get $5)- (local.get $y)- )- (i32.store offset=8- (local.get $5)- (local.get $z)- )- (i32.store offset=12- (local.get $5)- (local.get $w)- )- (i32.store offset=16- (local.get $5)- (local.get $a)- )- (call $nothing)- )- (drop- (local.get $x)- )- (drop- (local.get $y)- )- (drop- (local.get $z)- )- (drop- (local.get $w)- )- (drop- (local.get $a)- )- )- (global.set $stack_ptr- (local.get $5)- )- )- (func $some-alive- (local $x i32)- (local $y i32)- (local $2 i32)- (local.set $2- (global.get $stack_ptr)- )- (global.set $stack_ptr- (i32.add- (local.get $2)- (i32.const 16)- )- )- (block- (block- (i32.store- (local.get $2)- (local.get $x)- )- (call $nothing)- )- (drop- (local.get $x)- )- )- (global.set $stack_ptr- (local.get $2)- )- )- (func $spill-args (param $p i32) (param $q i32)- (local $x i32)- (local $3 i32)- (local $4 i32)- (local $5 i32)- (local.set $3- (global.get $stack_ptr)- )- (global.set $stack_ptr- (i32.add- (local.get $3)- (i32.const 16)- )- )- (block- (block- (local.set $4- (i32.const 1)- )- (local.set $5- (i32.const 2)- )- (i32.store offset=8- (local.get $3)- (local.get $x)- )- (call $spill-args- (local.get $4)- (local.get $5)- )- )- (drop- (local.get $x)- )- )- (global.set $stack_ptr- (local.get $3)- )- )- (func $spill-ret (result i32)- (local $x i32)- (local $1 i32)- (local $2 i32)- (local $3 i32)- (local $4 i32)- (local.set $1- (global.get $stack_ptr)- )- (global.set $stack_ptr- (i32.add- (local.get $1)- (i32.const 16)- )- )- (local.set $4- (block (result i32)- (block- (i32.store- (local.get $1)- (local.get $x)- )- (call $nothing)- )- (drop- (local.get $x)- )- (if- (i32.const 1)- (block- (local.set $2- (i32.const 2)- )- (global.set $stack_ptr- (local.get $1)- )- (return- (local.get $2)- )- )- (block- (local.set $3- (i32.const 3)- )- (global.set $stack_ptr- (local.get $1)- )- (return- (local.get $3)- )- )- )- (i32.const 4)- )- )- (global.set $stack_ptr- (local.get $1)- )- (local.get $4)- )- (func $spill-unreachable (result i32)- (local $x i32)- (local $1 i32)- (local $2 i32)- (local.set $1- (global.get $stack_ptr)- )- (global.set $stack_ptr- (i32.add- (local.get $1)- (i32.const 16)- )- )- (local.set $2- (block (result i32)- (block- (i32.store- (local.get $1)- (local.get $x)- )- (call $nothing)- )- (drop- (local.get $x)- )- (unreachable)- )- )- (global.set $stack_ptr- (local.get $1)- )- (local.get $2)- )- (func $spill-call-call0 (param $p i32) (result i32)- (unreachable)- )- (func $spill-call-call1 (param $p i32) (result i32)- (local $x i32)- (local $2 i32)- (local $3 i32)- (local $4 i32)- (local $5 i32)- (local.set $2- (global.get $stack_ptr)- )- (global.set $stack_ptr- (i32.add- (local.get $2)- (i32.const 16)- )- )- (local.set $5- (block (result i32)- (drop- (block (result i32)- (local.set $3- (block (result i32)- (local.set $4- (i32.const 1)- )- (i32.store offset=4- (local.get $2)- (local.get $x)- )- (call $spill-call-call1- (local.get $4)- )- )- )- (i32.store offset=4- (local.get $2)- (local.get $x)- )- (call $spill-call-call0- (local.get $3)- )- )- )- (local.get $x)- )- )- (global.set $stack_ptr- (local.get $2)- )- (local.get $5)- )- (func $spill-call-ret (param $p i32) (result i32)- (local $x i32)- (drop- (call $spill-call-call0- (return- (i32.const 1)- )- )- )- (i32.const 0)- )- (func $spill-ret-call (param $p i32) (result i32)- (local $x i32)- (drop- (return- (call $spill-call-call0- (i32.const 1)- )- )- )- (i32.const 0)- )- (func $spill-ret-ret (result i32)- (local $x i32)- (local $1 i32)- (local $2 i32)- (local $3 i32)- (local.set $1- (global.get $stack_ptr)- )- (global.set $stack_ptr- (i32.add- (local.get $1)- (i32.const 16)- )- )- (local.set $3- (block (result i32)- (block- (i32.store- (local.get $1)- (local.get $x)- )- (call $nothing)- )- (drop- (local.get $x)- )- (drop- (block- (global.set $stack_ptr- (local.get $1)- )- (return- (block- (local.set $2- (i32.const 1)- )- (global.set $stack_ptr- (local.get $1)- )- (return- (local.get $2)- )- )- )- )- )- (i32.const 0)- )- )- (global.set $stack_ptr- (local.get $1)- )- (local.get $3)- )- (func $spill-call-othertype (param $y f64)- (local $x i32)- (local $2 i32)- (local $3 f64)- (local.set $2- (global.get $stack_ptr)- )- (global.set $stack_ptr- (i32.add- (local.get $2)- (i32.const 16)- )- )- (block- (block- (local.set $3- (f64.const 1)- )- (i32.store- (local.get $2)- (local.get $x)- )- (call $spill-call-othertype- (local.get $3)- )- )- (drop- (local.get $x)- )- )- (global.set $stack_ptr- (local.get $2)- )- )- (func $spill-call_indirect- (local $x i32)- (local $1 i32)- (local $2 i32)- (local $3 i32)- (local $4 i32)- (local.set $1- (global.get $stack_ptr)- )- (global.set $stack_ptr- (i32.add- (local.get $1)- (i32.const 16)- )- )- (block- (block- (local.set $2- (i32.const 123)- )- (local.set $3- (i32.const 456)- )- (local.set $4- (i32.const 789)- )- (i32.store- (local.get $1)- (local.get $x)- )- (call_indirect (type $i32_i32_=>_none)- (local.get $2)- (local.get $3)- (local.get $4)- )- )- (drop- (local.get $x)- )- )- (global.set $stack_ptr- (local.get $1)- )- )- (func $spill-call_import- (local $x i32)- (local $1 i32)- (local $2 i32)- (local.set $1- (global.get $stack_ptr)- )- (global.set $stack_ptr- (i32.add- (local.get $1)- (i32.const 16)- )- )- (block- (block- (local.set $2- (i32.const 200)- )- (i32.store- (local.get $1)- (local.get $x)- )- (call $segfault- (local.get $2)- )- )- (drop- (local.get $x)- )- )- (global.set $stack_ptr- (local.get $1)- )- )-)-(module- (type $none_=>_none (func))- (type $none_=>_i32 (func (result i32)))- (type $i32_=>_i32 (func (param i32) (result i32)))- (type $i32_i32_=>_none (func (param i32 i32)))- (type $i32_=>_none (func (param i32)))- (type $f64_=>_none (func (param f64)))- (import "env" "segfault" (func $segfault (param i32)))- (memory $0 10)- (table $0 1 1 funcref)- (global $stack_ptr (mut i32) (i32.const 1716592))- (export "stackSave" (func $stack_save))- (func $stack_save (result i32)- (global.get $stack_ptr)- )- (func $nothing- (nop)- )- (func $not-alive- (local $x i32)- (local.set $x- (i32.const 1)- )- (call $nothing)- )- (func $spill- (local $x i32)- (local $1 i32)- (local.set $1- (global.get $stack_ptr)- )- (global.set $stack_ptr- (i32.add- (local.get $1)- (i32.const 16)- )- )- (block- (block- (i32.store- (local.get $1)- (local.get $x)- )- (call $nothing)- )- (drop- (local.get $x)- )- )- (global.set $stack_ptr- (local.get $1)- )- )- (func $ignore-non-pointers- (local $x i32)- (local $y i64)- (local $z f32)- (local $w f64)- (local $4 i32)- (local.set $4- (global.get $stack_ptr)- )- (global.set $stack_ptr- (i32.add- (local.get $4)- (i32.const 16)- )- )- (block- (local.set $x- (i32.const 1)- )- (local.set $y- (i64.const 1)- )- (local.set $z- (f32.const 1)- )- (local.set $w- (f64.const 1)- )- (block- (i32.store- (local.get $4)- (local.get $x)- )- (call $nothing)- )- (drop- (local.get $x)- )- (drop- (local.get $y)- )- (drop- (local.get $z)- )- (drop- (local.get $w)- )- )- (global.set $stack_ptr- (local.get $4)- )- )- (func $spill4- (local $x i32)- (local $y i32)- (local $z i32)- (local $w i32)- (local $4 i32)- (local.set $4- (global.get $stack_ptr)- )- (global.set $stack_ptr- (i32.add- (local.get $4)- (i32.const 16)- )- )- (block- (local.set $x- (i32.const 1)- )- (local.set $y- (i32.const 1)- )- (local.set $z- (i32.const 1)- )- (local.set $w- (i32.const 1)- )- (block- (i32.store- (local.get $4)- (local.get $x)- )- (i32.store offset=4- (local.get $4)- (local.get $y)- )- (i32.store offset=8- (local.get $4)- (local.get $z)- )- (i32.store offset=12- (local.get $4)- (local.get $w)- )- (call $nothing)- )- (drop- (local.get $x)- )- (drop- (local.get $y)- )- (drop- (local.get $z)- )- (drop- (local.get $w)- )- )- (global.set $stack_ptr- (local.get $4)- )- )- (func $spill5- (local $x i32)- (local $y i32)- (local $z i32)- (local $w i32)- (local $a i32)- (local $5 i32)- (local.set $5- (global.get $stack_ptr)- )- (global.set $stack_ptr- (i32.add- (local.get $5)- (i32.const 32)- )- )- (block- (local.set $x- (i32.const 1)- )- (local.set $y- (i32.const 1)- )- (local.set $z- (i32.const 1)- )- (local.set $w- (i32.const 1)- )- (local.set $a- (i32.const 1)- )- (block- (i32.store- (local.get $5)- (local.get $x)- )- (i32.store offset=4- (local.get $5)- (local.get $y)- )- (i32.store offset=8- (local.get $5)- (local.get $z)- )- (i32.store offset=12- (local.get $5)- (local.get $w)- )- (i32.store offset=16- (local.get $5)- (local.get $a)- )- (call $nothing)- )- (drop- (local.get $x)- )- (drop- (local.get $y)- )- (drop- (local.get $z)- )- (drop- (local.get $w)- )- (drop- (local.get $a)- )- )- (global.set $stack_ptr- (local.get $5)- )- )- (func $some-alive- (local $x i32)- (local $y i32)- (local $2 i32)- (local.set $2- (global.get $stack_ptr)- )- (global.set $stack_ptr- (i32.add- (local.get $2)- (i32.const 16)- )- )- (block- (block- (i32.store- (local.get $2)- (local.get $x)- )- (call $nothing)- )- (drop- (local.get $x)- )- )- (global.set $stack_ptr- (local.get $2)- )- )- (func $spill-args (param $p i32) (param $q i32)- (local $x i32)- (local $3 i32)- (local $4 i32)- (local $5 i32)- (local.set $3- (global.get $stack_ptr)- )- (global.set $stack_ptr- (i32.add- (local.get $3)- (i32.const 16)- )- )- (block- (block- (local.set $4- (i32.const 1)- )- (local.set $5- (i32.const 2)- )- (i32.store offset=8- (local.get $3)- (local.get $x)- )- (call $spill-args- (local.get $4)- (local.get $5)- )- )- (drop- (local.get $x)- )- )- (global.set $stack_ptr- (local.get $3)- )- )- (func $spill-ret (result i32)- (local $x i32)- (local $1 i32)- (local $2 i32)- (local $3 i32)- (local $4 i32)- (local.set $1- (global.get $stack_ptr)- )- (global.set $stack_ptr- (i32.add- (local.get $1)- (i32.const 16)- )- )- (local.set $4- (block (result i32)- (block- (i32.store- (local.get $1)- (local.get $x)- )- (call $nothing)- )- (drop- (local.get $x)- )- (if- (i32.const 1)- (block- (local.set $2- (i32.const 2)- )- (global.set $stack_ptr- (local.get $1)- )- (return- (local.get $2)- )- )- (block- (local.set $3- (i32.const 3)- )- (global.set $stack_ptr- (local.get $1)- )- (return- (local.get $3)- )- )- )- (i32.const 4)- )- )- (global.set $stack_ptr- (local.get $1)- )- (local.get $4)- )- (func $spill-unreachable (result i32)- (local $x i32)- (local $1 i32)- (local $2 i32)- (local.set $1- (global.get $stack_ptr)- )- (global.set $stack_ptr- (i32.add- (local.get $1)- (i32.const 16)- )- )- (local.set $2- (block (result i32)- (block- (i32.store- (local.get $1)- (local.get $x)- )- (call $nothing)- )- (drop- (local.get $x)- )- (unreachable)- )- )- (global.set $stack_ptr- (local.get $1)- )- (local.get $2)- )- (func $spill-call-call0 (param $p i32) (result i32)- (unreachable)- )- (func $spill-call-call1 (param $p i32) (result i32)- (local $x i32)- (local $2 i32)- (local $3 i32)- (local $4 i32)- (local $5 i32)- (local.set $2- (global.get $stack_ptr)- )- (global.set $stack_ptr- (i32.add- (local.get $2)- (i32.const 16)- )- )- (local.set $5- (block (result i32)- (drop- (block (result i32)- (local.set $3- (block (result i32)- (local.set $4- (i32.const 1)- )- (i32.store offset=4- (local.get $2)- (local.get $x)- )- (call $spill-call-call1- (local.get $4)- )- )- )- (i32.store offset=4- (local.get $2)- (local.get $x)- )- (call $spill-call-call0- (local.get $3)- )- )- )- (local.get $x)- )- )- (global.set $stack_ptr- (local.get $2)- )- (local.get $5)- )- (func $spill-call-ret (param $p i32) (result i32)- (local $x i32)- (drop- (call $spill-call-call0- (return- (i32.const 1)- )- )- )- (i32.const 0)- )- (func $spill-ret-call (param $p i32) (result i32)- (local $x i32)- (drop- (return- (call $spill-call-call0- (i32.const 1)- )- )- )- (i32.const 0)- )- (func $spill-ret-ret (result i32)- (local $x i32)- (local $1 i32)- (local $2 i32)- (local $3 i32)- (local.set $1- (global.get $stack_ptr)- )- (global.set $stack_ptr- (i32.add- (local.get $1)- (i32.const 16)- )- )- (local.set $3- (block (result i32)- (block- (i32.store- (local.get $1)- (local.get $x)- )- (call $nothing)- )- (drop- (local.get $x)- )- (drop- (block- (global.set $stack_ptr- (local.get $1)- )- (return- (block- (local.set $2- (i32.const 1)- )- (global.set $stack_ptr- (local.get $1)- )- (return- (local.get $2)- )- )- )- )- )- (i32.const 0)- )- )- (global.set $stack_ptr- (local.get $1)- )- (local.get $3)- )- (func $spill-call-othertype (param $y f64)- (local $x i32)- (local $2 i32)- (local $3 f64)- (local.set $2- (global.get $stack_ptr)- )- (global.set $stack_ptr- (i32.add- (local.get $2)- (i32.const 16)- )- )- (block- (block- (local.set $3- (f64.const 1)- )- (i32.store- (local.get $2)- (local.get $x)- )- (call $spill-call-othertype- (local.get $3)- )- )- (drop- (local.get $x)- )- )- (global.set $stack_ptr- (local.get $2)- )- )- (func $spill-call_indirect- (local $x i32)- (local $1 i32)- (local $2 i32)- (local $3 i32)- (local $4 i32)- (local.set $1- (global.get $stack_ptr)- )- (global.set $stack_ptr- (i32.add- (local.get $1)- (i32.const 16)- )- )- (block- (block- (local.set $2- (i32.const 123)- )- (local.set $3- (i32.const 456)- )- (local.set $4- (i32.const 789)- )- (i32.store- (local.get $1)- (local.get $x)- )- (call_indirect (type $i32_i32_=>_none)- (local.get $2)- (local.get $3)- (local.get $4)- )- )- (drop- (local.get $x)- )- )- (global.set $stack_ptr- (local.get $1)- )- )- (func $spill-call_import- (local $x i32)- (local $1 i32)- (local $2 i32)- (local.set $1- (global.get $stack_ptr)- )- (global.set $stack_ptr- (i32.add- (local.get $1)- (i32.const 16)- )- )- (block- (block- (local.set $2- (i32.const 200)- )- (i32.store- (local.get $1)- (local.get $x)- )- (call $segfault- (local.get $2)- )- )- (drop- (local.get $x)- )- )- (global.set $stack_ptr- (local.get $1)- )- )-)
− binaryen/test/passes/spill-pointers.wast
@@ -1,338 +0,0 @@-(module- (memory 10)- (type $ii (func (param i32 i32)))- (table 1 1 funcref)- (elem (i32.const 0))- (import "env" "STACKTOP" (global $STACKTOP$asm2wasm$import i32))- (import "env" "segfault" (func $segfault (param i32)))- (global $stack_ptr (mut i32) (global.get $STACKTOP$asm2wasm$import))-- (func $nothing- )- (func $not-alive- (local $x i32)- (local.set $x (i32.const 1))- (call $nothing)- )- (func $spill- (local $x i32)- (call $nothing)- (drop (local.get $x))- )- (func $ignore-non-pointers- (local $x i32)- (local $y i64)- (local $z f32)- (local $w f64)- (local.set $x (i32.const 1))- (local.set $y (i64.const 1))- (local.set $z (f32.const 1))- (local.set $w (f64.const 1))- (call $nothing)- (drop (local.get $x))- (drop (local.get $y))- (drop (local.get $z))- (drop (local.get $w))- )- (func $spill4- (local $x i32)- (local $y i32)- (local $z i32)- (local $w i32)- (local.set $x (i32.const 1))- (local.set $y (i32.const 1))- (local.set $z (i32.const 1))- (local.set $w (i32.const 1))- (call $nothing)- (drop (local.get $x))- (drop (local.get $y))- (drop (local.get $z))- (drop (local.get $w))- )- (func $spill5- (local $x i32)- (local $y i32)- (local $z i32)- (local $w i32)- (local $a i32)- (local.set $x (i32.const 1))- (local.set $y (i32.const 1))- (local.set $z (i32.const 1))- (local.set $w (i32.const 1))- (local.set $a (i32.const 1))- (call $nothing)- (drop (local.get $x))- (drop (local.get $y))- (drop (local.get $z))- (drop (local.get $w))- (drop (local.get $a))- )- (func $some-alive- (local $x i32)- (local $y i32)- (call $nothing)- (drop (local.get $x))- )- (func $spill-args (param $p i32) (param $q i32)- (local $x i32)- (call $spill-args (i32.const 1) (i32.const 2))- (drop (local.get $x))- )- (func $spill-ret (result i32)- (local $x i32)- (call $nothing)- (drop (local.get $x))- (if (i32.const 1)- (return (i32.const 2))- (return (i32.const 3))- )- (i32.const 4)- )- (func $spill-unreachable (result i32)- (local $x i32)- (call $nothing)- (drop (local.get $x))- (unreachable)- )- (func $spill-call-call0 (param $p i32) (result i32)- (unreachable)- )- (func $spill-call-call1 (param $p i32) (result i32)- (local $x i32)- (drop- (call $spill-call-call0- (call $spill-call-call1- (i32.const 1)- )- )- )- (local.get $x)- )- (func $spill-call-ret (param $p i32) (result i32)- (local $x i32)- (drop- (call $spill-call-call0- (return- (i32.const 1)- )- )- )- (local.get $x)- )- (func $spill-ret-call (param $p i32) (result i32)- (local $x i32)- (drop- (return- (call $spill-call-call0- (i32.const 1)- )- )- )- (local.get $x)- )- (func $spill-ret-ret (result i32)- (local $x i32)- (call $nothing)- (drop (local.get $x))- (drop- (return- (return- (i32.const 1)- )- )- )- (local.get $x)- )- (func $spill-call-othertype (param $y f64)- (local $x i32)- (call $spill-call-othertype (f64.const 1))- (drop (local.get $x))- )- (func $spill-call_indirect- (local $x i32)- (call_indirect (type $ii)- (i32.const 123)- (i32.const 456)- (i32.const 789)- )- (drop (local.get $x))- )- (func $spill-call_import- (local $x i32)- (call $segfault- (i32.const 200)- )- (drop (local.get $x))- )-)--(module- (memory 10)- (type $ii (func (param i32 i32)))- (table 1 1 funcref)- (elem (i32.const 0))- (global $stack_ptr (mut i32) (i32.const 1716592))- (export "stackSave" (func $stack_save))- (import "env" "segfault" (func $segfault (param i32)))- (func $stack_save (result i32)- (global.get $stack_ptr)- )-- (func $nothing- )- (func $not-alive- (local $x i32)- (local.set $x (i32.const 1))- (call $nothing)- )- (func $spill- (local $x i32)- (call $nothing)- (drop (local.get $x))- )- (func $ignore-non-pointers- (local $x i32)- (local $y i64)- (local $z f32)- (local $w f64)- (local.set $x (i32.const 1))- (local.set $y (i64.const 1))- (local.set $z (f32.const 1))- (local.set $w (f64.const 1))- (call $nothing)- (drop (local.get $x))- (drop (local.get $y))- (drop (local.get $z))- (drop (local.get $w))- )- (func $spill4- (local $x i32)- (local $y i32)- (local $z i32)- (local $w i32)- (local.set $x (i32.const 1))- (local.set $y (i32.const 1))- (local.set $z (i32.const 1))- (local.set $w (i32.const 1))- (call $nothing)- (drop (local.get $x))- (drop (local.get $y))- (drop (local.get $z))- (drop (local.get $w))- )- (func $spill5- (local $x i32)- (local $y i32)- (local $z i32)- (local $w i32)- (local $a i32)- (local.set $x (i32.const 1))- (local.set $y (i32.const 1))- (local.set $z (i32.const 1))- (local.set $w (i32.const 1))- (local.set $a (i32.const 1))- (call $nothing)- (drop (local.get $x))- (drop (local.get $y))- (drop (local.get $z))- (drop (local.get $w))- (drop (local.get $a))- )- (func $some-alive- (local $x i32)- (local $y i32)- (call $nothing)- (drop (local.get $x))- )- (func $spill-args (param $p i32) (param $q i32)- (local $x i32)- (call $spill-args (i32.const 1) (i32.const 2))- (drop (local.get $x))- )- (func $spill-ret (result i32)- (local $x i32)- (call $nothing)- (drop (local.get $x))- (if (i32.const 1)- (return (i32.const 2))- (return (i32.const 3))- )- (i32.const 4)- )- (func $spill-unreachable (result i32)- (local $x i32)- (call $nothing)- (drop (local.get $x))- (unreachable)- )- (func $spill-call-call0 (param $p i32) (result i32)- (unreachable)- )- (func $spill-call-call1 (param $p i32) (result i32)- (local $x i32)- (drop- (call $spill-call-call0- (call $spill-call-call1- (i32.const 1)- )- )- )- (local.get $x)- )- (func $spill-call-ret (param $p i32) (result i32)- (local $x i32)- (drop- (call $spill-call-call0- (return- (i32.const 1)- )- )- )- (local.get $x)- )- (func $spill-ret-call (param $p i32) (result i32)- (local $x i32)- (drop- (return- (call $spill-call-call0- (i32.const 1)- )- )- )- (local.get $x)- )- (func $spill-ret-ret (result i32)- (local $x i32)- (call $nothing)- (drop (local.get $x))- (drop- (return- (return- (i32.const 1)- )- )- )- (local.get $x)- )- (func $spill-call-othertype (param $y f64)- (local $x i32)- (call $spill-call-othertype (f64.const 1))- (drop (local.get $x))- )- (func $spill-call_indirect- (local $x i32)- (call_indirect (type $ii)- (i32.const 123)- (i32.const 456)- (i32.const 789)- )- (drop (local.get $x))- )- (func $spill-call_import- (local $x i32)- (call $segfault- (i32.const 200)- )- (drop (local.get $x))- )-)
binaryen/test/passes/stack-check_enable-mutable-globals.txt view
@@ -39,3 +39,25 @@ ) ) )+(module+ (type $i32_i32_=>_none (func (param i32 i32)))+ (type $none_=>_i32 (func (result i32)))+ (import "env" "__stack_pointer" (global $sp (mut i32)))+ (global $__stack_base (mut i32) (i32.const 0))+ (global $__stack_limit (mut i32) (i32.const 0))+ (global $__stack_base_0 (mut i32) (i32.const 0))+ (global $__stack_limit_0 (mut i32) (i32.const 0))+ (export "use_stack" (func $0))+ (export "__set_stack_limits" (func $__set_stack_limits))+ (func $0 (result i32)+ (unreachable)+ )+ (func $__set_stack_limits (param $0 i32) (param $1 i32)+ (global.set $__stack_base_0+ (local.get $0)+ )+ (global.set $__stack_limit_0+ (local.get $1)+ )+ )+)
binaryen/test/passes/stack-check_enable-mutable-globals.wast view
@@ -5,3 +5,13 @@ (global.get $sp) ) )+;; if the global names are taken we should not crash+(module+ (import "env" "__stack_pointer" (global $sp (mut i32)))+ (global $__stack_base (mut i32) (i32.const 0))+ (global $__stack_limit (mut i32) (i32.const 0))+ (export "use_stack" (func $0))+ (func $0 (result i32)+ (unreachable)+ )+)
binaryen/test/passes/strip-debug.bin.txt view
@@ -1,7 +1,7 @@ (module (type $none_=>_i32 (func (result i32))) (import "env" "__linear_memory" (memory $mimport$0 0))- (import "env" "__indirect_function_table" (table $timport$1 0 funcref))+ (import "env" "__indirect_function_table" (table $timport$0 0 funcref)) (func $0 (result i32) (local $0 i32) (local.set $0
binaryen/test/passes/strip-producers.bin.txt view
@@ -1,7 +1,7 @@ (module (type $none_=>_i32 (func (result i32))) (import "env" "__linear_memory" (memory $mimport$0 0))- (import "env" "__indirect_function_table" (table $timport$1 0 funcref))+ (import "env" "__indirect_function_table" (table $timport$0 0 funcref)) (func $0 (result i32) (local $0 i32) (local.set $0
binaryen/test/passes/strip-target-features_roundtrip_print-features_all-features.txt view
@@ -10,6 +10,7 @@ --enable-multivalue --enable-gc --enable-memory64+--enable-typed-function-references (module (type $none_=>_v128_externref (func (result v128 externref))) (func $foo (result v128 externref)
binaryen/test/passes/translate-to-fuzz_all-features.txt view
@@ -1,1013 +1,1138 @@ (module- (type $none_=>_none (func))- (type $none_=>_i32 (func (result i32)))- (type $i64_=>_none (func (param i64)))- (type $i32_=>_none (func (param i32)))- (type $f32_=>_none (func (param f32)))- (type $f64_=>_none (func (param f64)))- (type $v128_=>_none (func (param v128)))- (type $exnref_=>_none (func (param exnref)))- (type $funcref_f64_=>_i32 (func (param funcref f64) (result i32)))- (type $none_=>_f32 (func (result f32)))- (type $eqref_i32_=>_funcref (func (param eqref i32) (result funcref)))- (type $i32_i32_f32_exnref_=>_externref (func (param i32 i32 f32 exnref) (result externref)))- (type $externref_f64_f32_eqref_i31ref_anyref_=>_externref (func (param externref f64 f32 eqref i31ref anyref) (result externref)))- (type $exnref_f32_i31ref_externref_funcref_i31ref_i64_=>_exnref (func (param exnref f32 i31ref externref funcref i31ref i64) (result exnref)))- (type $none_=>_eqref_i31ref_i64_v128_eqref (func (result eqref i31ref i64 v128 eqref)))- (type $v128_i31ref_=>_eqref_i31ref_i64_v128_eqref (func (param v128 i31ref) (result eqref i31ref i64 v128 eqref)))- (type $none_=>_i31ref (func (result i31ref)))- (import "fuzzing-support" "log-i32" (func $log-i32 (param i32)))- (import "fuzzing-support" "log-i64" (func $log-i64 (param i64)))- (import "fuzzing-support" "log-f32" (func $log-f32 (param f32)))- (import "fuzzing-support" "log-f64" (func $log-f64 (param f64)))- (import "fuzzing-support" "log-v128" (func $log-v128 (param v128)))- (import "fuzzing-support" "log-exnref" (func $log-exnref (param exnref)))- (memory $0 (shared 1 1))- (data (i32.const 0) "N\0fN\f5\f9\b1\ff\fa\eb\e5\fe\a7\ec\fb\fc\f4\a6\e4\ea\f0\ae\e3")- (table $0 5 5 funcref)- (elem (i32.const 0) $func_9 $func_9 $func_9 $func_10 $func_14)- (global $global$5 (mut eqref) (ref.null eq))- (global $global$4 (mut i32) (i32.const 470177031))- (global $global$3 (mut f64) (f64.const 2147483647))- (global $global$2 (mut (eqref f32 eqref funcref funcref i64)) (tuple.make- (ref.null eq)- (f32.const -2147483648)- (ref.null eq)- (ref.null func)- (ref.null func)- (i64.const -32)- ))- (global $global$1 (mut f32) (f32.const -32769))- (global $hangLimit (mut i32) (i32.const 10))- (export "hashMemory" (func $hashMemory))- (export "memory" (memory $0))- (export "func_7_invoker" (func $func_7_invoker))- (export "func_9" (func $func_9))- (export "func_11_invoker" (func $func_11_invoker))- (export "func_14" (func $func_14))- (export "func_18" (func $func_18))- (export "func_19" (func $func_19))- (export "hangLimitInitializer" (func $hangLimitInitializer))- (func $hashMemory (result i32)- (local $0 i32)- (local.set $0- (i32.const 5381)- )- (local.set $0- (i32.xor- (i32.add- (i32.shl- (local.get $0)- (i32.const 5)- )- (local.get $0)- )- (i32.load8_u- (i32.const 0)- )- )- )- (local.set $0- (i32.xor- (i32.add- (i32.shl- (local.get $0)- (i32.const 5)- )- (local.get $0)- )- (i32.load8_u offset=1- (i32.const 0)- )- )- )- (local.set $0- (i32.xor- (i32.add- (i32.shl- (local.get $0)- (i32.const 5)- )- (local.get $0)- )- (i32.load8_u offset=2- (i32.const 0)- )- )- )- (local.set $0- (i32.xor- (i32.add- (i32.shl- (local.get $0)- (i32.const 5)- )- (local.get $0)- )- (i32.load8_u offset=3- (i32.const 0)- )- )- )- (local.set $0- (i32.xor- (i32.add- (i32.shl- (local.get $0)- (i32.const 5)- )- (local.get $0)- )- (i32.load8_u offset=4- (i32.const 0)- )- )- )- (local.set $0- (i32.xor- (i32.add- (i32.shl- (local.get $0)- (i32.const 5)- )- (local.get $0)- )- (i32.load8_u offset=5- (i32.const 0)- )- )- )- (local.set $0- (i32.xor- (i32.add- (i32.shl- (local.get $0)- (i32.const 5)- )- (local.get $0)- )- (i32.load8_u offset=6- (i32.const 0)- )- )- )- (local.set $0- (i32.xor- (i32.add- (i32.shl- (local.get $0)- (i32.const 5)- )- (local.get $0)- )- (i32.load8_u offset=7- (i32.const 0)- )- )- )- (local.set $0- (i32.xor- (i32.add- (i32.shl- (local.get $0)- (i32.const 5)- )- (local.get $0)- )- (i32.load8_u offset=8- (i32.const 0)- )- )- )- (local.set $0- (i32.xor- (i32.add- (i32.shl- (local.get $0)- (i32.const 5)- )- (local.get $0)- )- (i32.load8_u offset=9- (i32.const 0)- )- )- )- (local.set $0- (i32.xor- (i32.add- (i32.shl- (local.get $0)- (i32.const 5)- )- (local.get $0)- )- (i32.load8_u offset=10- (i32.const 0)- )- )- )- (local.set $0- (i32.xor- (i32.add- (i32.shl- (local.get $0)- (i32.const 5)- )- (local.get $0)- )- (i32.load8_u offset=11- (i32.const 0)- )- )- )- (local.set $0- (i32.xor- (i32.add- (i32.shl- (local.get $0)- (i32.const 5)- )- (local.get $0)- )- (i32.load8_u offset=12- (i32.const 0)- )- )- )- (local.set $0- (i32.xor- (i32.add- (i32.shl- (local.get $0)- (i32.const 5)- )- (local.get $0)- )- (i32.load8_u offset=13- (i32.const 0)- )- )- )- (local.set $0- (i32.xor- (i32.add- (i32.shl- (local.get $0)- (i32.const 5)- )- (local.get $0)- )- (i32.load8_u offset=14- (i32.const 0)- )- )- )- (local.set $0- (i32.xor- (i32.add- (i32.shl- (local.get $0)- (i32.const 5)- )- (local.get $0)- )- (i32.load8_u offset=15- (i32.const 0)- )- )- )- (local.get $0)- )- (func $func_7 (param $0 i32) (param $1 i32) (param $2 f32) (param $3 exnref) (result externref)- (local $4 i32)- (block- (if- (i32.eqz- (global.get $hangLimit)- )- (return- (ref.null extern)- )- )- (global.set $hangLimit- (i32.sub- (global.get $hangLimit)- (i32.const 1)- )- )- )- (ref.null extern)- )- (func $func_7_invoker- (drop- (call $func_7- (i32.const -127)- (i32.const -268435456)- (f32.const 1179405440)- (ref.null exn)- )- )- (call $log-i32- (call $hashMemory)- )- )- (func $func_9 (result f32)- (local $0 anyref)- (local $1 f64)- (local $2 (anyref anyref))- (local $3 eqref)- (local $4 externref)- (block- (if- (i32.eqz- (global.get $hangLimit)- )- (return- (f32.const 1.4949444621624858e-31)- )- )- (global.set $hangLimit- (i32.sub- (global.get $hangLimit)- (i32.const 1)- )- )- )- (block $label$0- (nop)- (block $label$1- (nop)- (return- (f32.const 7.396028525772014e-24)- )- )- )- )- (func $func_10 (param $0 externref) (param $1 f64) (param $2 f32) (param $3 eqref) (param $4 i31ref) (param $5 anyref) (result externref)- (local $6 i64)- (local $7 (anyref exnref f32 f64 f64))- (local $8 eqref)- (local $9 exnref)- (local $10 i64)- (local $11 f64)- (local $12 f32)- (local $13 v128)- (local $14 exnref)- (local $15 (funcref funcref v128 i31ref v128))- (local $16 anyref)- (block- (if- (i32.eqz- (global.get $hangLimit)- )- (return- (ref.null extern)- )- )- (global.set $hangLimit- (i32.sub- (global.get $hangLimit)- (i32.const 1)- )- )- )- (ref.null extern)- )- (func $func_11 (param $0 exnref) (param $1 f32) (param $2 i31ref) (param $3 externref) (param $4 funcref) (param $5 i31ref) (param $6 i64) (result exnref)- (local $7 (i32 i64 anyref externref externref eqref))- (block- (if- (i32.eqz- (global.get $hangLimit)- )- (return- (ref.null exn)- )- )- (global.set $hangLimit- (i32.sub- (global.get $hangLimit)- (i32.const 1)- )- )- )- (ref.null exn)- )- (func $func_11_invoker- (drop- (call $func_11- (ref.null exn)- (f32.const -1022.1400146484375)- (i31.new- (i32.const -32766)- )- (ref.null extern)- (ref.null func)- (i31.new- (i32.const -65535)- )- (i64.const 3)- )- )- (call $log-i32- (call $hashMemory)- )- )- (func $func_13 (result i31ref)- (local $0 i31ref)- (local $1 (funcref f32 anyref f32 externref))- (local $2 f64)- (local $3 f64)- (local $4 (i32 v128))- (local $5 (anyref i64 v128 eqref funcref exnref))- (local $6 i32)- (block- (if- (i32.eqz- (global.get $hangLimit)- )- (return- (i31.new- (i32.const -28)- )- )- )- (global.set $hangLimit- (i32.sub- (global.get $hangLimit)- (i32.const 1)- )- )- )- (i31.new- (i32.const 64)- )- )- (func $func_14 (result i32)- (local $0 i32)- (local $1 funcref)- (local $2 (anyref externref))- (local $3 funcref)- (local $4 i64)- (local $5 externref)- (local $6 (exnref f64))- (local $7 (anyref f64 f64))- (local $8 (i64 i32 eqref exnref))- (local $9 (v128 i64 funcref i32 anyref anyref))- (local $10 (i32 eqref f64 funcref))- (local $11 eqref)- (block- (if- (i32.eqz- (global.get $hangLimit)- )- (return- (local.get $0)- )- )- (global.set $hangLimit- (i32.sub- (global.get $hangLimit)- (i32.const 1)- )- )- )- (block $label$0 (result i32)- (nop)- (local.get $0)- )- )- (func $func_15 (result i32)- (block- (if- (i32.eqz- (global.get $hangLimit)- )- (return- (i32.const 32768)- )- )- (global.set $hangLimit- (i32.sub- (global.get $hangLimit)- (i32.const 1)- )- )- )- (global.get $global$4)- )- (func $func_16 (param $0 eqref) (param $1 i32) (result funcref)- (local $2 v128)- (local $3 funcref)- (local $4 eqref)- (block- (if- (i32.eqz- (global.get $hangLimit)- )- (return- (local.get $3)- )- )- (global.set $hangLimit- (i32.sub- (global.get $hangLimit)- (i32.const 1)- )- )- )- (loop $label$1 (result funcref)- (block- (if- (i32.eqz- (global.get $hangLimit)- )- (return- (local.get $3)- )- )- (global.set $hangLimit- (i32.sub- (global.get $hangLimit)- (i32.const 1)- )- )- )- (block (result funcref)- (block $label$2- (br_if $label$2- (i32.eqz- (block $label$3- (global.set $global$4- (local.tee $1- (local.get $1)- )- )- (block $label$4- (nop)- (br_if $label$1- (i32.eqz- (i31.get_u- (i31.new- (i32.const -90)- )- )- )- )- )- (br $label$1)- )- )- )- (memory.init 0- (i32.and- (local.get $1)- (i32.const 15)- )- (i32.const 16)- (i32.const 3)- )- )- (br_if $label$1- (i32.const 131071)- )- (local.get $3)- )- )- )- (func $func_17 (param $0 i64)- (local $1 externref)- (block- (if- (i32.eqz- (global.get $hangLimit)- )- (return)- )- (global.set $hangLimit- (i32.sub- (global.get $hangLimit)- (i32.const 1)- )- )- )- (block $label$0- (call $log-i32- (call $hashMemory)- )- (if- (i32.eqz- (f64.gt- (f64.const 103)- (f64.max- (f64.const 8388607.124)- (if- (i32.eqz- (global.get $global$4)- )- (block $label$1- (call $log-v128- (f64x2.replace_lane 0- (f32x4.neg- (i8x16.shr_u- (v128.load offset=3- (i32.const 65535)- )- (loop $label$2 (result i32)- (block- (if- (i32.eqz- (global.get $hangLimit)- )- (return)- )- (global.set $hangLimit- (i32.sub- (global.get $hangLimit)- (i32.const 1)- )- )- )- (block (result i32)- (block $label$3- (call $log-exnref- (ref.null exn)- )- (call $log-i32- (i32.atomic.rmw8.sub_u offset=22- (i32.and- (i32.const 6)- (i32.const 15)- )- (i32.const 1852667194)- )- )- )- (br_if $label$2- (tuple.extract 0- (tuple.make- (i32.const -2147483648)- (i31.new- (i32.const -32767)- )- )- )- )- (i32.const -2147483648)- )- )- )- )- (f64.const -nan:0xffffffffffff3)- )- )- (br $label$0)- )- (block $label$4- (br_if $label$0- (i32.eqz- (tuple.extract 2- (block $label$5- (call $log-i32- (call $hashMemory)- )- (br $label$0)- )- )- )- )- (br $label$0)- )- )- )- )- )- (block $label$6- (call $log-i32- (call $hashMemory)- )- (call $log-i32- (call $hashMemory)- )- )- (if- (i32.eqz- (i32.or- (i32.const 65535)- (i32.const 8)- )- )- (call $log-i32- (i32.const 608321884)- )- (atomic.fence)- )- )- )- )- (func $func_18 (param $0 v128) (param $1 i31ref) (result eqref i31ref i64 v128 eqref)- (local $2 i64)- (local $3 v128)- (local $4 f32)- (block- (if- (i32.eqz- (global.get $hangLimit)- )- (return- (tuple.make- (ref.null eq)- (i31.new- (i32.const -2147483648)- )- (i64.const 369041285507055655)- (v128.const i32x4 0xffffffd1 0xffffffff 0x25312936 0x5455263f)- (ref.null eq)- )- )- )- (global.set $hangLimit- (i32.sub- (global.get $hangLimit)- (i32.const 1)- )- )- )- (tuple.make- (ref.null eq)- (local.get $1)- (i64.const -32766)- (v128.bitselect- (local.get $3)- (block $label$2- (atomic.fence)- (return- (tuple.make- (ref.null eq)- (i31.new- (i32.const 19521)- )- (i64.const -32766)- (v128.const i32x4 0x4f800000 0x3e116873 0x46ca0800 0x54000000)- (ref.null eq)- )- )- )- (tuple.extract 2- (tuple.make- (i31.new- (i32.const 1684216173)- )- (ref.null eq)- (v128.const i32x4 0xffa20004 0x00000000 0x2b25ffa6 0x005b0080)- (ref.null eq)- )- )- )- (global.get $global$5)- )- )- (func $func_19 (param $0 funcref) (param $1 f64) (result i32)- (local $2 (funcref f32 exnref exnref externref))- (local $3 externref)- (local $4 v128)- (local $5 f64)- (local $6 i32)- (local $7 (f64 i31ref eqref eqref))- (local $8 anyref)- (local $9 (eqref i31ref i32 i31ref anyref))- (local $10 eqref)- (local $11 exnref)- (local $12 externref)- (local $13 externref)- (local $14 externref)- (local $15 i31ref)- (block- (if- (i32.eqz- (global.get $hangLimit)- )- (return- (i32.const -131072)- )- )- (global.set $hangLimit- (i32.sub- (global.get $hangLimit)- (i32.const 1)- )- )- )- (select- (i32.atomic.load8_u offset=22- (i32.and- (local.get $6)- (i32.const 15)- )- )- (local.tee $6- (select- (i16x8.extract_lane_s 4- (v128.const i32x4 0xfffffff8 0x00008001 0xffffffa0 0x180b1217)- )- (if (result i32)- (if (result i32)- (i32.eqz- (i32.const 524287)- )- (block $label$1- (memory.init 0- (i32.and- (f32.ge- (block $label$2 (result f32)- (call $log-i32- (call $hashMemory)- )- (if (result f32)- (if (result i32)- (i32.eqz- (loop $label$3 (result i32)- (block- (if- (i32.eqz- (global.get $hangLimit)- )- (return- (i32.const -83)- )- )- (global.set $hangLimit- (i32.sub- (global.get $hangLimit)- (i32.const 1)- )- )- )- (block (result i32)- (br_if $label$3- (local.get $6)- )- (br_if $label$3- (local.get $6)- )- (i32.const -33)- )- )- )- (i32.const 2147483647)- (if (result i32)- (i32.eqz- (i32.const 32768)- )- (i32.const 16404)- (i32.const -1024)- )- )- (f32.const -nan:0x7fffa8)- (block $label$4 (result f32)- (call $log-i32- (call $hashMemory)- )- (f32.const 18446744073709551615)- )- )- )- (if (result f32)- (i32.eqz- (ref.is_null- (if (result externref)- (i32.eqz- (i32.const -65535)- )- (ref.null extern)- (local.get $12)- )- )- )- (block $label$5 (result f32)- (call $log-f32- (select- (f32.const 4096)- (f32.const -nan:0x7fffa1)- (i32.const 2097640319)- )- )- (f32.const 8192)- )- (f32.const -1125899906842624)- )- )- (i32.const 15)- )- (i32.const 1)- (i32.const 2)- )- (return- (local.get $6)- )- )- (block $label$6 (result i32)- (loop $label$7- (block- (if- (i32.eqz- (global.get $hangLimit)- )- (return- (i32.const -4096)- )- )- (global.set $hangLimit- (i32.sub- (global.get $hangLimit)- (i32.const 1)- )- )- )- (block $label$8- (nop)- (memory.fill- (i32.and- (i8x16.extract_lane_s 11- (i8x16.max_s- (local.get $4)- (i16x8.add_saturate_u- (v128.const i32x4 0xffea0f4a 0xfdffffec 0xdfff0512 0x1910ffff)- (local.get $4)- )- )- )- (i32.const 15)- )- (i32.const 1326258715)- (local.get $6)- )- )- )- (local.get $6)- )- )- (block $label$9 (result i32)- (i32.const 10353)- )- (local.get $6)- )- (select- (i32.const 33554433)- (i32.trunc_f64_s- (f64.const 3402823466385288598117041e14)- )- (local.tee $6- (select- (local.get $6)- (ref.eq- (loop $label$0 (result i31ref)- (block- (if- (i32.eqz- (global.get $hangLimit)- )- (return- (i32.const -32768)- )- )- (global.set $hangLimit- (i32.sub- (global.get $hangLimit)- (i32.const 1)- )- )- )- (block (result i31ref)- (local.set $5- (f64.const 371920655)- )- (br_if $label$0- (i32.eqz- (local.tee $6- (local.tee $6- (local.tee $6- (local.tee $6- (local.get $6)- )- )- )- )- )- )- (local.get $15)- )- )- (local.get $10)- )- (local.get $6)- )- )- )- )- )- (global.get $global$4)+ (type $none_=>_i32_v128_f64_v128 (func (result i32 v128 f64 v128)))+ (type $none_=>_none (func))+ (type $i32_=>_none (func (param i32)))+ (type $i64_=>_none (func (param i64)))+ (type $i64_i32_=>_none (func (param i64 i32)))+ (type $f32_=>_none (func (param f32)))+ (type $f64_=>_none (func (param f64)))+ (type $v128_=>_none (func (param v128)))+ (type $exnref_=>_none (func (param exnref)))+ (type $none_=>_i32 (func (result i32)))+ (import "fuzzing-support" "log-i32" (func $log-i32 (param i32)))+ (import "fuzzing-support" "log-i64" (func $log-i64 (param i64)))+ (import "fuzzing-support" "log-f32" (func $log-f32 (param f32)))+ (import "fuzzing-support" "log-f64" (func $log-f64 (param f64)))+ (import "fuzzing-support" "log-v128" (func $log-v128 (param v128)))+ (import "fuzzing-support" "log-exnref" (func $log-exnref (param exnref)))+ (memory $0 (shared 16 17))+ (data (i32.const 0) "N\0fN\f5\f9\b1\ff\fa\eb\e5\fe\a7\ec\fb\fc\f4\a6\e4\ea\f0\ae\e3")+ (table $0 0 funcref)+ (global $global$ (mut eqref) (ref.null eq))+ (global $global$_0 (mut externref) (ref.null extern))+ (global $global$_1 (mut v128) (v128.const i32x4 0xfffffff9 0x06071c48 0x3f800000 0xc3800ae1))+ (global $global$_2 (mut eqref) (ref.null eq))+ (global $global$_3 (mut f64) (f64.const 0))+ (global $hangLimit (mut i32) (i32.const 10))+ (event $event$ (attr 0) (param i64 i32))+ (export "hashMemory" (func $hashMemory))+ (export "memory" (memory $0))+ (export "hangLimitInitializer" (func $hangLimitInitializer))+ (func $hashMemory (result i32)+ (local $0 i32)+ (block+ (if+ (i32.eqz+ (global.get $hangLimit)+ )+ (return+ (i32.const 64)+ )+ )+ (global.set $hangLimit+ (i32.sub+ (global.get $hangLimit)+ (i32.const 1)+ )+ )+ )+ (block (result i32)+ (local.set $0+ (i32.const 5381)+ )+ (local.set $0+ (i32.const 1140933654)+ )+ (local.set $0+ (i32.xor+ (i32.add+ (i32.shl+ (local.get $0)+ (i32.const 5)+ )+ (i32.const -127)+ )+ (i32.load8_u offset=1+ (i32.const 0)+ )+ )+ )+ (local.set $0+ (i32.xor+ (i32.add+ (i32.shl+ (i32.const 303045650)+ (i32.const 5)+ )+ (i32.shl+ (ref.eq+ (i31.new+ (i32.const -65535)+ )+ (tuple.extract 2+ (tuple.make+ (f64.const 274877906944)+ (i31.new+ (i32.const -134217728)+ )+ (ref.null eq)+ )+ )+ )+ (i32.const 5)+ )+ )+ (i32.load8_u offset=2+ (i32.const 0)+ )+ )+ )+ (nop)+ (local.set $0+ (i32.xor+ (i32.add+ (loop $label$1 (result i32)+ (block+ (if+ (i32.eqz+ (global.get $hangLimit)+ )+ (return+ (i32.const 4878)+ )+ )+ (global.set $hangLimit+ (i32.sub+ (global.get $hangLimit)+ (i32.const 1)+ )+ )+ )+ (block $label$2 (result i32)+ (drop+ (f64.const 3402823466385288598117041e14)+ )+ (loop $label$6+ (block+ (if+ (i32.eqz+ (global.get $hangLimit)+ )+ (return+ (i32.const -13)+ )+ )+ (global.set $hangLimit+ (i32.sub+ (global.get $hangLimit)+ (i32.const 1)+ )+ )+ )+ (block+ (block $label$7+ (nop)+ (if+ (block $label$8+ (nop)+ (br $label$1)+ )+ (block $label$9+ (f64.store offset=2 align=2+ (i32.and+ (i32.const 118163717)+ (i32.const 15)+ )+ (if (result f64)+ (call $hashMemory)+ (block $label$10 (result f64)+ (memory.copy+ (i32.const -129)+ (i32.and+ (i32.const 1195786829)+ (i32.const 15)+ )+ (i32.const -8)+ )+ (f64.const -562949953421312.2)+ )+ (block $label$11+ (nop)+ (br $label$7)+ )+ )+ )+ (if+ (i32.eqz+ (i32.atomic.load+ (i32.and+ (i32.const 65535)+ (i32.const 15)+ )+ )+ )+ (block $label$12+ (nop)+ (nop)+ )+ (block $label$13+ (br_if $label$7+ (i32.const 10539)+ )+ (loop $label$14+ (block+ (if+ (i32.eqz+ (global.get $hangLimit)+ )+ (return+ (i32.const 1495078923)+ )+ )+ (global.set $hangLimit+ (i32.sub+ (global.get $hangLimit)+ (i32.const 1)+ )+ )+ )+ (atomic.fence)+ )+ )+ )+ )+ (nop)+ )+ )+ (br_if $label$6+ (i32.const -50)+ )+ (loop $label$15+ (block+ (if+ (i32.eqz+ (global.get $hangLimit)+ )+ (return+ (i32.const -96)+ )+ )+ (global.set $hangLimit+ (i32.sub+ (global.get $hangLimit)+ (i32.const 1)+ )+ )+ )+ (block $label$16+ (if+ (i32.eqz+ (br_if $label$2+ (i8x16.extract_lane_s 2+ (f64x2.gt+ (v128.const i32x4 0xffffffc0 0xffffffff 0x60631d62 0x630f6218)+ (if (result v128)+ (i32.eqz+ (f32.ne+ (block $label$18+ (nop)+ (br $label$15)+ )+ (f32.const -nan:0x7fff8a)+ )+ )+ (block $label$19 (result v128)+ (nop)+ (v128.const i32x4 0x00000000 0x38100000 0x00000000 0x40d89880)+ )+ (block $label$20+ (if+ (i32.atomic.rmw8.cmpxchg_u offset=4+ (i32.and+ (i32.const 2)+ (i32.const 15)+ )+ (i32.const 65525)+ (br_if $label$2+ (i32.const -33554432)+ (i64.lt_u+ (i64.const -65536)+ (i64.const 6663)+ )+ )+ )+ (block $label$21+ (br_if $label$21+ (i32.eqz+ (i32.const 65535)+ )+ )+ (nop)+ )+ (block $label$22+ (v128.store offset=4+ (i32.and+ (i32.const 55)+ (i32.const 15)+ )+ (v128.const i32x4 0xfffffe00 0x7fffffff 0x00005b34 0x00000039)+ )+ (nop)+ )+ )+ (br $label$16)+ )+ )+ )+ )+ (i32.eqz+ (i32.const 85459227)+ )+ )+ )+ (block $label$23+ (block $label$24+ (block $label$25+ (nop)+ (nop)+ )+ (nop)+ )+ (nop)+ )+ (block $label$26+ (if+ (br_if $label$2+ (i32.const 1091126348)+ (i32.const 1276841216)+ )+ (br_if $label$26+ (i32.eqz+ (tuple.extract 0+ (if (result i32 v128 f64 v128)+ (i32.load8_u offset=3+ (i32.and+ (f64.ge+ (block $label$27 (result f64)+ (nop)+ (f64.const 41)+ )+ (f64x2.extract_lane 0+ (v128.const i32x4 0xffffc000 0x00000007 0x00000001 0x473f2147)+ )+ )+ (i32.const 15)+ )+ )+ (block $label$28 (result i32 v128 f64 v128)+ (tuple.make+ (i32.const 67308125)+ (v128.const i32x4 0xff00011d 0x0601e545 0x7f0e14ff 0x00b1f843)+ (f64.const 1314148947)+ (v128.const i32x4 0x0000003a 0x42d00000 0x00000000 0x40280000)+ )+ )+ (block $label$29 (result i32 v128 f64 v128)+ (br_if $label$15+ (i32.eqz+ (br_if $label$2+ (i32.const -8192)+ (i32.eqz+ (i32.const -2)+ )+ )+ )+ )+ (tuple.make+ (i32.const 65534)+ (v128.const i32x4 0x41530000 0x008045b2 0x01ff7f00 0xff2d8349)+ (f64.const 1797693134862315708145274e284)+ (v128.const i32x4 0xffbc630d 0xffb6ffbb 0x00015658 0xffb4ffff)+ )+ )+ )+ )+ )+ )+ (block $label$30+ (if+ (loop $label$31 (result i32)+ (block+ (if+ (i32.eqz+ (global.get $hangLimit)+ )+ (return+ (i32.const 1578633994)+ )+ )+ (global.set $hangLimit+ (i32.sub+ (global.get $hangLimit)+ (i32.const 1)+ )+ )+ )+ (block $label$32 (result i32)+ (block $label$33+ (if+ (i32.eqz+ (i32.atomic.rmw.and offset=4+ (i32.const -2147483648)+ (block $label$34+ (loop $label$35+ (block+ (if+ (i32.eqz+ (global.get $hangLimit)+ )+ (return+ (i32.const 403574365)+ )+ )+ (global.set $hangLimit+ (i32.sub+ (global.get $hangLimit)+ (i32.const 1)+ )+ )+ )+ (block+ (nop)+ (br_if $label$35+ (i32.const -65536)+ )+ (nop)+ )+ )+ (br $label$1)+ )+ )+ )+ (block $label$36+ (nop)+ (br_if $label$16+ (i32.const 2136)+ )+ )+ (block $label$37+ (nop)+ (nop)+ )+ )+ (atomic.fence)+ )+ (f32.lt+ (f32.const 2147483648)+ (f32.const 2147483648)+ )+ )+ )+ (block $label$40+ (i32.atomic.store16 offset=2+ (i32.and+ (i31.get_s+ (loop $label$41+ (block+ (if+ (i32.eqz+ (global.get $hangLimit)+ )+ (return+ (i32.const -2)+ )+ )+ (global.set $hangLimit+ (i32.sub+ (global.get $hangLimit)+ (i32.const 1)+ )+ )+ )+ (block $label$42+ (loop $label$43+ (block+ (if+ (i32.eqz+ (global.get $hangLimit)+ )+ (return+ (i32.const -13)+ )+ )+ (global.set $hangLimit+ (i32.sub+ (global.get $hangLimit)+ (i32.const 1)+ )+ )+ )+ (block $label$44+ (nop)+ (nop)+ )+ )+ (block $label$45+ (nop)+ (br $label$16)+ )+ )+ )+ )+ (i32.const 15)+ )+ (block $label$46+ (nop)+ (ref.is_null+ (if+ (i32.eqz+ (if (result i32)+ (i32.eqz+ (block $label$47+ (nop)+ (br $label$16)+ )+ )+ (i32.const -4194304)+ (i32.const 5140)+ )+ )+ (block $label$48+ (block $label$49+ (nop)+ (br_if $label$15+ (i32.eqz+ (loop $label$50 (result i32)+ (block+ (if+ (i32.eqz+ (global.get $hangLimit)+ )+ (return+ (i32.const 112)+ )+ )+ (global.set $hangLimit+ (i32.sub+ (global.get $hangLimit)+ (i32.const 1)+ )+ )+ )+ (block (result i32)+ (nop)+ (br_if $label$50+ (i32.eqz+ (i32.const 3)+ )+ )+ (i31.get_s+ (i31.new+ (i32.const 4095)+ )+ )+ )+ )+ )+ )+ )+ (br $label$40)+ )+ (block $label$51+ (drop+ (ref.null exn)+ )+ (br $label$16)+ )+ )+ )+ )+ )+ )+ (block $label$52+ (loop $label$53+ (block+ (if+ (i32.eqz+ (global.get $hangLimit)+ )+ (return+ (i32.const 7506)+ )+ )+ (global.set $hangLimit+ (i32.sub+ (global.get $hangLimit)+ (i32.const 1)+ )+ )+ )+ (block+ (nop)+ (br_if $label$53+ (loop $label$54 (result i32)+ (block+ (if+ (i32.eqz+ (global.get $hangLimit)+ )+ (return+ (i32.const 50922251)+ )+ )+ (global.set $hangLimit+ (i32.sub+ (global.get $hangLimit)+ (i32.const 1)+ )+ )+ )+ (i32.const 6912)+ )+ )+ (br_if $label$6+ (br_if $label$2+ (call $hashMemory)+ (loop $label$55 (result i32)+ (block+ (if+ (i32.eqz+ (global.get $hangLimit)+ )+ (return+ (i32.const 319820056)+ )+ )+ (global.set $hangLimit+ (i32.sub+ (global.get $hangLimit)+ (i32.const 1)+ )+ )+ )+ (i32.const 2147483647)+ )+ )+ )+ )+ )+ (memory.copy+ (i32.and+ (i32.atomic.load offset=3+ (i32.and+ (loop $label$56 (result i32)+ (block+ (if+ (i32.eqz+ (global.get $hangLimit)+ )+ (return+ (i32.const -2147483648)+ )+ )+ (global.set $hangLimit+ (i32.sub+ (global.get $hangLimit)+ (i32.const 1)+ )+ )+ )+ (loop $label$57 (result i32)+ (block+ (if+ (i32.eqz+ (global.get $hangLimit)+ )+ (return+ (i32.const 262143)+ )+ )+ (global.set $hangLimit+ (i32.sub+ (global.get $hangLimit)+ (i32.const 1)+ )+ )+ )+ (block (result i32)+ (block $label$58+ (if+ (i32.eqz+ (i32.const 775321902)+ )+ (nop)+ (if+ (i32.eqz+ (i32.const -18)+ )+ (nop)+ (nop)+ )+ )+ (nop)+ )+ (br_if $label$57+ (i32.const 4194304)+ )+ (f32.le+ (f32.const 18446744073709551615)+ (f32.const -nan:0x7fff87)+ )+ )+ )+ )+ (i32.const 15)+ )+ )+ (i32.const 15)+ )+ (i32.and+ (block $label$59 (result i32)+ (loop $label$60+ (block+ (if+ (i32.eqz+ (global.get $hangLimit)+ )+ (return+ (i32.const -32768)+ )+ )+ (global.set $hangLimit+ (i32.sub+ (global.get $hangLimit)+ (i32.const 1)+ )+ )+ )+ (block+ (block $label$61+ (drop+ (i31.new+ (i32.const -8192)+ )+ )+ (nop)+ )+ (br_if $label$60+ (i32.eqz+ (loop $label$62 (result i32)+ (block+ (if+ (i32.eqz+ (global.get $hangLimit)+ )+ (return+ (i32.const 7)+ )+ )+ (global.set $hangLimit+ (i32.sub+ (global.get $hangLimit)+ (i32.const 1)+ )+ )+ )+ (block $label$63 (result i32)+ (nop)+ (i32.const 65521)+ )+ )+ )+ )+ (memory.fill+ (i32.trunc_f32_u+ (f32.const 256)+ )+ (i64.eq+ (i64.const 256)+ (i64.const -16384)+ )+ (i32.const 387455770)+ )+ )+ )+ (i32.const 4627)+ )+ (i32.const 15)+ )+ (i32.load8_s offset=3+ (i32.and+ (br_if $label$2+ (loop $label$64 (result i32)+ (block+ (if+ (i32.eqz+ (global.get $hangLimit)+ )+ (return+ (i32.const -96)+ )+ )+ (global.set $hangLimit+ (i32.sub+ (global.get $hangLimit)+ (i32.const 1)+ )+ )+ )+ (block (result i32)+ (block $label$65+ (loop $label$66+ (block+ (if+ (i32.eqz+ (global.get $hangLimit)+ )+ (return+ (i32.const 65518)+ )+ )+ (global.set $hangLimit+ (i32.sub+ (global.get $hangLimit)+ (i32.const 1)+ )+ )+ )+ (nop)+ )+ (nop)+ )+ (br_if $label$64+ (tuple.extract 1+ (tuple.make+ (v128.const i32x4 0x0606ff82 0xfffe0000 0x04052000 0xfffe0000)+ (i32.const 1529028702)+ )+ )+ )+ (loop $label$67 (result i32)+ (block+ (if+ (i32.eqz+ (global.get $hangLimit)+ )+ (return+ (i32.const -1073741825)+ )+ )+ (global.set $hangLimit+ (i32.sub+ (global.get $hangLimit)+ (i32.const 1)+ )+ )+ )+ (i32.const 128)+ )+ )+ )+ (i32.eqz+ (ref.is_null+ (select (result anyref)+ (ref.null eq)+ (ref.null extern)+ (i32.const 129)+ )+ )+ )+ )+ (i32.const 15)+ )+ )+ )+ )+ )+ (nop)+ )+ )+ (block $label$68+ (nop)+ (nop)+ )+ )+ )+ (nop)+ )+ )+ )+ )+ (if (result i32)+ (block $label$69 (result i32)+ (if+ (if (result i32)+ (br_if $label$2+ (loop $label$71 (result i32)+ (block+ (if+ (i32.eqz+ (global.get $hangLimit)+ )+ (return+ (i32.const 15)+ )+ )+ (global.set $hangLimit+ (i32.sub+ (global.get $hangLimit)+ (i32.const 1)+ )+ )+ )+ (block (result i32)+ (block $label$72+ (br_if $label$72+ (i32.const -1)+ )+ (nop)+ )+ (br_if $label$71+ (i32.eqz+ (i32.const -2147483648)+ )+ )+ (if (result i32)+ (i32.eqz+ (i32.const -32766)+ )+ (block $label$73 (result i32)+ (br_if $label$71+ (i32.eqz+ (tuple.extract 1+ (block $label$74+ (nop)+ (br $label$1)+ )+ )+ )+ )+ (ref.is_null+ (global.get $global$_0)+ )+ )+ (i32x4.all_true+ (v128.const i32x4 0x3c800c01 0x193fff27 0x52a20001 0x970000ff)+ )+ )+ )+ )+ (i32.eqz+ (loop $label$70 (result i32)+ (block+ (if+ (i32.eqz+ (global.get $hangLimit)+ )+ (return+ (i32.const 1048576)+ )+ )+ (global.set $hangLimit+ (i32.sub+ (global.get $hangLimit)+ (i32.const 1)+ )+ )+ )+ (i32.const 256)+ )+ )+ )+ (i32.atomic.load8_u offset=22+ (i32.const 858607703)+ )+ (block $label$75 (result i32)+ (nop)+ (br_if $label$75+ (i32.const 7)+ (i31.get_s+ (tuple.extract 0+ (tuple.make+ (i31.new+ (i32.const 219815443)+ )+ (v128.const i32x4 0x00000001 0x151b1e13 0x00000001 0x1a5f0000)+ )+ )+ )+ )+ )+ )+ (block $label$76+ (nop)+ )+ (nop)+ )+ (i32.const 2097152)+ )+ (i32.const -84)+ (block $label$77 (result i32)+ (i32.const -16)+ )+ )+ )+ )+ (local.get $0)+ )+ (i32.load8_u offset=4+ (i32.const 0)+ )+ )+ )+ (local.set $0+ (i32.xor+ (i32.add+ (i32.shl+ (local.get $0)+ (i32.const 5)+ )+ (local.get $0)+ )+ (i32.load8_u offset=5+ (i32.const 0)+ )+ )+ )+ (local.set $0+ (i32.xor+ (i32.add+ (i32.shl+ (local.get $0)+ (i32.const 5)+ )+ (local.get $0)+ )+ (i32.const 6506)+ )+ )+ (nop)+ (local.set $0+ (i32.xor+ (i32.add+ (i32.shl+ (local.get $0)+ (i32.const 5)+ )+ (local.get $0)+ )+ (i32.load8_u offset=6+ (i32.const 0)+ )+ )+ )+ (local.set $0+ (i32.xor+ (i32.add+ (i32.shl+ (i32.const 1633371484)+ (i32.const 5)+ )+ (i32.xor+ (i32.add+ (i32.shl+ (local.get $0)+ (i32.const 5)+ )+ (local.get $0)+ )+ (i32.load8_u offset=8+ (i32.const 0)+ )+ )+ )+ (i32.load8_u offset=9+ (i32.const 0)+ )+ )+ )+ (local.set $0+ (i32.xor+ (i32.add+ (i32.shl+ (local.get $0)+ (i32.const 5)+ )+ (local.get $0)+ )+ (i32.load8_u offset=10+ (i32.const 0)+ )+ )+ )+ (local.set $0+ (i32.xor+ (i32.const 1937132399)+ (i32.load8_u offset=11+ (i32.const 0)+ )+ )+ )+ (local.set $0+ (i32.xor+ (i32.add+ (i32.shl+ (i32.const -85)+ (i32.const 5)+ )+ (local.get $0)+ )+ (i32.shl+ (local.get $0)+ (i32.const 5)+ )+ )+ )+ (local.set $0+ (i32.xor+ (i32.add+ (i32.shl+ (local.get $0)+ (i32.const 5)+ )+ (local.get $0)+ )+ (i32.load8_u offset=13+ (i32.const 0)+ )+ )+ )+ (local.set $0+ (i32.xor+ (i32.add+ (i32.const 5)+ (local.get $0)+ )+ (i32.load8_u offset=14+ (i32.const 0)+ )+ )+ )+ (local.set $0+ (i32.xor+ (i32.add+ (i32.shl+ (local.get $0)+ (i32.const 5)+ )+ (local.get $0)+ )+ (i32.load8_u offset=12+ (i32.const 0)+ )+ )+ )+ (local.get $0) ) ) (func $hangLimitInitializer
− binaryen/test/passes/translate-to-fuzz_all-features.wast
@@ -1,101 +0,0 @@-(module # fake module here, for test harness, but it is really not needed-..-any-3INPUT-h e r e-*will*-d0-0.753538467597066-2.2339337309978227-.................-lorem ipsum whatever--through the darkness of future past-the magician longs to see-one [chants|chance] out between two worlds-fire, walk with me---h e r e-*will*-d0-0.753538467597066-2.2339337309978227-.................-lorem ipsum whatever--through the darkness of future past-the magician longs to see-one [chants|chance] out between two worlds-fire, walk with me---(&!*^@$*&@!^*&@#^$*&@#$*&@#$^*&@^#$)(&)(!&$(*&^@&#*$--MOAR testing09237861235980723894570389yfskdjhgfm13jo847rtnjcsjjdhfgnc12o387456vb1p98364vlaisutfvlKUYASDOV*&Q@$%VOUAYFROVLUKSYDFP(*A^*&%DFASF________-<>?><?><?><>?>>?<>??><A?S>D<?A>S<D?><G?S><DG?S><G--2.2339337309978227-.................-lorem ipsum whatever--through the darkness of future past-the magician longs to see-one [chants|chance] out between two worlds-fire, walk with me---(&!*^@$*&@!^*&@#^$*&@#$*&@#$^*&@^#$)(&)(!&$(*&^@&#*$--MOAR testing09237861235980723894570389yfskdjhgfm13jo847rtnjcsjjdhfgnc12o387456vb1p98364vlaisutfvlKUYASDOV*&Q@$%VOUAYFROVLUKSYDFP(*A^*&%DFASF________-<>?><?><?><>?>>?<>??><A?S>D<?A>S<D?><G?S><DG?S><G--INPUT-h e r e-*will*-d0-0.753538467597066-2.2339337309978227-.................-lorem ipsum whatever--through the darkness of future past-the magician longs to see-one [chants|chance] out between two worlds-fire, walk with me---h e r e-*will*-d0-0.753538467597066-2.2339337309978227-.................-lorem ipsum whatever--through the darkness of future past-the magician longs to see-one [chants|chance] out between two worlds-fire, walk with me---(&!*^@$*&@!^*&@#^$*&@#$*&@#$^*&@^#$)(&)(!&$(*&^@&#*$--MOAR testing09237861235980723894570389yfskdjhgfm13jo847rtnjcsjjdhfgnc12o387456vb1p98364vlaisutfvlKUYASDOV*&Q@$%VOUAYFROVLUKSYDFP(*A^*&%DFASF________-<>?><?><?><>?>>?<>??><A?S>D<?A>S<D?><G?S><DG?S><G--2.2339337309978227-.................-lorem ipsum whatever--through the darkness of future past-the magician longs to see-one [chants|chance] out between two worlds-fire, walk with me---(&!*^@$*&@!^*&@#^$*&@#$*&@#$^*&@^#$)(&)(!&$(*&^@&#*$--) # this isn't really needed either--bleh
+ binaryen/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt view
@@ -0,0 +1,42 @@+total+ [events] : 1 + [exports] : 3 + [funcs] : 2 + [globals] : 6 + [imports] : 6 + [memory-data] : 22 + [table-data] : 0 + [total] : 592 + [vars] : 1 + atomic.cmpxchg : 1 + atomic.fence : 3 + binary : 58 + block : 84 + break : 26 + call : 4 + call_ref : 1 + const : 149 + data.drop : 1 + drop : 3 + global.get : 29 + global.set : 17 + i31.get : 2 + i31.new : 7 + if : 35 + load : 15 + local.get : 10 + local.set : 14 + loop : 13 + memory.init : 1 + nop : 36 + ref.eq : 2 + ref.func : 2 + ref.is_null : 3 + ref.null : 8 + return : 14 + select : 2 + simd_extract : 2 + store : 8 + tuple.extract : 5 + tuple.make : 4 + unary : 33
+ binaryen/test/passes/translate-to-fuzz_all-features_metrics_noprint.wast view
@@ -0,0 +1,101 @@+(module # fake module here, for test harness, but it is really not needed+..+any+3INPUT+h e r e+*will*+d0+0.753538467597066+2.2339337309978227+.................+lorem ipsum whatever++through the darkness of future past+the magician longs to see+one [chants|chance] out between two worlds+fire, walk with me+++h e r e+*will*+d0+0.753538467597066+2.2339337309978227+.................+lorem ipsum whatever++through the darkness of future past+the magician longs to see+one [chants|chance] out between two worlds+fire, walk with me+++(&!*^@$*&@!^*&@#^$*&@#$*&@#$^*&@^#$)(&)(!&$(*&^@&#*$++MOAR testing09237861235980723894570389yfskdjhgfm13jo847rtnjcsjjdhfgnc12o387456vb1p98364vlaisutfvlKUYASDOV*&Q@$%VOUAYFROVLUKSYDFP(*A^*&%DFASF________+<>?><?><?><>?>>?<>??><A?S>D<?A>S<D?><G?S><DG?S><G++2.2339337309978227+.................+lorem ipsum whatever++through the darkness of future past+the magician longs to see+one [chants|chance] out between two worlds+fire, walk with me+++(&!*^@$*&@!^*&@#^$*&@#$*&@#$^*&@^#$)(&)(!&$(*&^@&#*$++MOAR testing09237861235980723894570389yfskdjhgfm13jo847rtnjcsjjdhfgnc12o387456vb1p98364vlaisutfvlKUYASDOV*&Q@$%VOUAYFROVLUKSYDFP(*A^*&%DFASF________+<>?><?><?><>?>>?<>??><A?S>D<?A>S<D?><G?S><DG?S><G++INPUT+h e r e+*will*+d0+0.753538467597066+2.2339337309978227+.................+lorem ipsum whatever++through the darkness of future past+the magician longs to see+one [chants|chance] out between two worlds+fire, walk with me+++h e r e+*will*+d0+0.753538467597066+2.2339337309978227+.................+lorem ipsum whatever++through the darkness of future past+the magician longs to see+one [chants|chance] out between two worlds+fire, walk with me+++(&!*^@$*&@!^*&@#^$*&@#$*&@#$^*&@^#$)(&)(!&$(*&^@&#*$++MOAR testing09237861235980723894570389yfskdjhgfm13jo847rtnjcsjjdhfgnc12o387456vb1p98364vlaisutfvlKUYASDOV*&Q@$%VOUAYFROVLUKSYDFP(*A^*&%DFASF________+<>?><?><?><>?>>?<>??><A?S>D<?A>S<D?><G?S><DG?S><G++2.2339337309978227+.................+lorem ipsum whatever++through the darkness of future past+the magician longs to see+one [chants|chance] out between two worlds+fire, walk with me+++(&!*^@$*&@!^*&@#^$*&@#$*&@#$^*&@^#$)(&)(!&$(*&^@&#*$++) # this isn't really needed either++bleh
binaryen/test/passes/vacuum_all-features.txt view
@@ -261,12 +261,6 @@ ) (func $unary-binary-may-trap (drop- (i64.div_s- (i64.const -1)- (i64.const 729618461987467893)- )- )- (drop (i64.trunc_f32_u (f32.const 70847791997969805621592064) )
binaryen/test/print/min.minified.txt view
@@ -1,4 +1,4 @@-(module(type $i32_=>_i32 (func(param i32)(result i32)))(type $i32_i32_i32_=>_i32 (func(param i32 i32 i32)(result i32)))(type $i32_i32_=>_f32 (func(param i32 i32)(result f32)))(type $f32_=>_f32 (func(param f32)(result f32)))(memory $0 256 256)+(module(type $i32_=>_i32 (func(param i32)(result i32)))(type $i32_i32_i32_=>_i32 (func(param i32 i32 i32)(result i32)))(type $f32_=>_f32 (func(param f32)(result f32)))(type $i32_i32_=>_f32 (func(param i32 i32)(result f32)))(memory $0 256 256) (export "floats" (func $floats))(func $floats(param $f f32)(result f32)(local $t f32)(f32.add(local.get $t)(local.get $f)))(func $neg(param $k i32)(param $p i32)(result f32)(local $n f32)(local.tee $n(f32.neg(block $block0 (result f32)(i32.store(local.get $k)(local.get $p))(f32.load(local.get $k))))))(func $littleswitch(param $x i32)(result i32)(block $topmost (result i32)(block $switch-case$2(block $switch-case$1(br_table $switch-case$1 $switch-case$2 $switch-case$1(i32.sub(local.get $x)(i32.const 1)))) (br $topmost(i32.const 1))) (br $topmost(i32.const 2))(i32.const 0)))(func $f1(param $i1 i32)(param $i2 i32)(param $i3 i32)(result i32)(block $topmost (result i32)(local.get $i3))))
binaryen/test/print/min.txt view
@@ -1,8 +1,8 @@ (module (type $i32_=>_i32 (func (param i32) (result i32))) (type $i32_i32_i32_=>_i32 (func (param i32 i32 i32) (result i32)))- (type $i32_i32_=>_f32 (func (param i32 i32) (result f32))) (type $f32_=>_f32 (func (param f32) (result f32)))+ (type $i32_i32_=>_f32 (func (param i32 i32) (result f32))) (memory $0 256 256) (export "floats" (func $floats)) (func $floats (param $f f32) (result f32)
binaryen/test/reference-types.wast.fromBinary.noDebugInfo view
@@ -9,7 +9,7 @@ (type $none_=>_exnref (func (result exnref))) (type $none_=>_none (func)) (type $externref_=>_funcref (func (param externref) (result funcref)))- (import "env" "import_global" (global $gimport$1 externref))+ (import "env" "import_global" (global $gimport$0 externref)) (import "env" "import_func" (func $fimport$0 (param externref) (result funcref))) (table $0 4 4 funcref) (elem (i32.const 0) $0 $1 $2 $3)@@ -23,7 +23,7 @@ (global $global$7 (mut anyref) (ref.func $4)) (global $global$8 (mut anyref) (ref.null exn)) (export "export_func" (func $fimport$0))- (export "export_global" (global $gimport$1))+ (export "export_global" (global $gimport$0)) (func $0 (param $0 externref) (nop) )
binaryen/test/simd.wast view
@@ -316,6 +316,12 @@ (local.get $1) ) )+ (func $i64x2.eq (param $0 v128) (param $1 v128) (result v128)+ (i64x2.eq+ (local.get $0)+ (local.get $1)+ )+ ) (func $f32x4.eq (param $0 v128) (param $1 v128) (result v128) (f32x4.eq (local.get $0)@@ -424,6 +430,123 @@ (local.get $2) ) )+ (func $v8x16.signselect (param $0 v128) (param $1 v128) (param $2 v128) (result v128)+ (v8x16.signselect+ (local.get $0)+ (local.get $1)+ (local.get $2)+ )+ )+ (func $v16x8.signselect (param $0 v128) (param $1 v128) (param $2 v128) (result v128)+ (v16x8.signselect+ (local.get $0)+ (local.get $1)+ (local.get $2)+ )+ )+ (func $v32x4.signselect (param $0 v128) (param $1 v128) (param $2 v128) (result v128)+ (v32x4.signselect+ (local.get $0)+ (local.get $1)+ (local.get $2)+ )+ )+ (func $v64x2.signselect (param $0 v128) (param $1 v128) (param $2 v128) (result v128)+ (v64x2.signselect+ (local.get $0)+ (local.get $1)+ (local.get $2)+ )+ )+ (func $v128.load8_lane (param $0 i32) (param $1 v128) (result v128)+ (v128.load8_lane 0+ (local.get $0)+ (local.get $1)+ )+ )+ (func $v128.load16_lane (param $0 i32) (param $1 v128) (result v128)+ (v128.load16_lane 0+ (local.get $0)+ (local.get $1)+ )+ )+ (func $v128.load32_lane (param $0 i32) (param $1 v128) (result v128)+ (v128.load32_lane 0+ (local.get $0)+ (local.get $1)+ )+ )+ (func $v128.load64_lane (param $0 i32) (param $1 v128) (result v128)+ (v128.load64_lane 0+ (local.get $0)+ (local.get $1)+ )+ )+ (func $v128.load64_lane_align (param $0 i32) (param $1 v128) (result v128)+ (v128.load64_lane align=1 0+ (local.get $0)+ (local.get $1)+ )+ )+ (func $v128.load64_lane_offset (param $0 i32) (param $1 v128) (result v128)+ (v128.load64_lane offset=32 0+ (local.get $0)+ (local.get $1)+ )+ )+ (func $v128.load64_lane_align_offset (param $0 i32) (param $1 v128) (result v128)+ (v128.load64_lane align=1 offset=32 0+ (local.get $0)+ (local.get $1)+ )+ )+ (func $v128.store8_lane (param $0 i32) (param $1 v128)+ (v128.store8_lane 0+ (local.get $0)+ (local.get $1)+ )+ )+ (func $v128.store16_lane (param $0 i32) (param $1 v128)+ (v128.store16_lane 0+ (local.get $0)+ (local.get $1)+ )+ )+ (func $v128.store32_lane (param $0 i32) (param $1 v128)+ (v128.store32_lane 0+ (local.get $0)+ (local.get $1)+ )+ )+ (func $v128.store64_lane (param $0 i32) (param $1 v128)+ (v128.store64_lane 0+ (local.get $0)+ (local.get $1)+ )+ )+ (func $v128.store64_lane_align (param $0 i32) (param $1 v128)+ (v128.store64_lane align=1 0+ (local.get $0)+ (local.get $1)+ )+ )+ (func $v128.store64_lane_offset (param $0 i32) (param $1 v128)+ (v128.store64_lane offset=32 0+ (local.get $0)+ (local.get $1)+ )+ )+ (func $v128.store64_lane_align_offset (param $0 i32) (param $1 v128)+ (v128.store64_lane align=1 offset=32 0+ (local.get $0)+ (local.get $1)+ )+ )+ (func $i8x16.popcnt (param $0 v128) (result v128)+ (i8x16.popcnt+ (local.get $0)+ )+ ) (func $i8x16.abs (param $0 v128) (result v128) (i8x16.abs (local.get $0)@@ -654,6 +777,36 @@ (local.get $1) ) )+ (func $i16x8.q15mulr_sat_s (param $0 v128) (param $1 v128) (result v128)+ (i16x8.q15mulr_sat_s+ (local.get $0)+ (local.get $1)+ )+ )+ (func $i16x8.extmul_low_i8x16_s (param $0 v128) (param $1 v128) (result v128)+ (i16x8.extmul_low_i8x16_s+ (local.get $0)+ (local.get $1)+ )+ )+ (func $i16x8.extmul_high_i8x16_s (param $0 v128) (param $1 v128) (result v128)+ (i16x8.extmul_high_i8x16_s+ (local.get $0)+ (local.get $1)+ )+ )+ (func $i16x8.extmul_low_i8x16_u (param $0 v128) (param $1 v128) (result v128)+ (i16x8.extmul_low_i8x16_u+ (local.get $0)+ (local.get $1)+ )+ )+ (func $i16x8.extmul_high_i8x16_u (param $0 v128) (param $1 v128) (result v128)+ (i16x8.extmul_high_i8x16_u+ (local.get $0)+ (local.get $1)+ )+ ) (func $i32x4.abs (param $0 v128) (result v128) (i32x4.abs (local.get $0)@@ -745,21 +898,40 @@ (local.get $1) ) )- (func $i64x2.neg (param $0 v128) (result v128)- (i64x2.neg+ (func $i32x4.extmul_low_i16x8_s (param $0 v128) (param $1 v128) (result v128)+ (i32x4.extmul_low_i16x8_s (local.get $0)+ (local.get $1) ) )- (func $i64x2.any_true (param $0 v128) (result i32)- (i64x2.any_true+ (func $i32x4.extmul_high_i16x8_s (param $0 v128) (param $1 v128) (result v128)+ (i32x4.extmul_high_i16x8_s (local.get $0)+ (local.get $1) ) )- (func $i64x2.all_true (param $0 v128) (result i32)- (i64x2.all_true+ (func $i32x4.extmul_low_i16x8_u (param $0 v128) (param $1 v128) (result v128)+ (i32x4.extmul_low_i16x8_u (local.get $0)+ (local.get $1) ) )+ (func $i32x4.extmul_high_i16x8_u (param $0 v128) (param $1 v128) (result v128)+ (i32x4.extmul_high_i16x8_u+ (local.get $0)+ (local.get $1)+ )+ )+ (func $i64x2.neg (param $0 v128) (result v128)+ (i64x2.neg+ (local.get $0)+ )+ )+ (func $i64x2.bitmask (param $0 v128) (result i32)+ (i64x2.bitmask+ (local.get $0)+ )+ ) (func $i64x2.shl (param $0 v128) (param $1 i32) (result v128) (i64x2.shl (local.get $0)@@ -796,6 +968,30 @@ (local.get $1) ) )+ (func $i64x2.extmul_low_i32x4_s (param $0 v128) (param $1 v128) (result v128)+ (i64x2.extmul_low_i32x4_s+ (local.get $0)+ (local.get $1)+ )+ )+ (func $i64x2.extmul_high_i32x4_s (param $0 v128) (param $1 v128) (result v128)+ (i64x2.extmul_high_i32x4_s+ (local.get $0)+ (local.get $1)+ )+ )+ (func $i64x2.extmul_low_i32x4_u (param $0 v128) (param $1 v128) (result v128)+ (i64x2.extmul_low_i32x4_u+ (local.get $0)+ (local.get $1)+ )+ )+ (func $i64x2.extmul_high_i32x4_u (param $0 v128) (param $1 v128) (result v128)+ (i64x2.extmul_high_i32x4_u+ (local.get $0)+ (local.get $1)+ )+ ) (func $f32x4.add (param $0 v128) (param $1 v128) (result v128) (f32x4.add (local.get $0)@@ -990,6 +1186,26 @@ (local.get $2) ) )+ (func $i16x8.extadd_pairwise_i8x16_s (param $0 v128) (result v128)+ (i16x8.extadd_pairwise_i8x16_s+ (local.get $0)+ )+ )+ (func $i16x8.extadd_pairwise_i8x16_u (param $0 v128) (result v128)+ (i16x8.extadd_pairwise_i8x16_u+ (local.get $0)+ )+ )+ (func $i32x4.extadd_pairwise_i16x8_s (param $0 v128) (result v128)+ (i32x4.extadd_pairwise_i16x8_s+ (local.get $0)+ )+ )+ (func $i32x4.extadd_pairwise_i16x8_u (param $0 v128) (result v128)+ (i32x4.extadd_pairwise_i16x8_u+ (local.get $0)+ )+ ) (func $i32x4.trunc_sat_f32x4_s (param $0 v128) (result v128) (i32x4.trunc_sat_f32x4_s (local.get $0)@@ -1114,6 +1330,26 @@ (local.get $0) ) )+ (func $i64x2.widen_low_i32x4_s (param $0 v128) (result v128)+ (i64x2.widen_low_i32x4_s+ (local.get $0)+ )+ )+ (func $i64x2.widen_high_i32x4_s (param $0 v128) (result v128)+ (i64x2.widen_high_i32x4_s+ (local.get $0)+ )+ )+ (func $i64x2.widen_low_i32x4_u (param $0 v128) (result v128)+ (i64x2.widen_low_i32x4_u+ (local.get $0)+ )+ )+ (func $i64x2.widen_high_i32x4_u (param $0 v128) (result v128)+ (i64x2.widen_high_i32x4_u+ (local.get $0)+ )+ ) (func $i16x8.load8x8_u (param $0 i32) (result v128) (i16x8.load8x8_u (local.get $0)@@ -1158,6 +1394,16 @@ (v8x16.swizzle (local.get $0) (local.get $1)+ )+ )+ (func $prefetch.t (param $0 i32)+ (prefetch.t offset=3 align=2+ (local.get $0)+ )+ )+ (func $prefetch.nt (param $0 i32)+ (prefetch.nt offset=3 align=2+ (local.get $0) ) ) )
binaryen/test/simd.wast.from-wast view
@@ -1,12 +1,14 @@ (module (type $v128_v128_=>_v128 (func (param v128 v128) (result v128))) (type $v128_=>_v128 (func (param v128) (result v128)))- (type $v128_=>_i32 (func (param v128) (result i32))) (type $i32_=>_v128 (func (param i32) (result v128)))+ (type $v128_=>_i32 (func (param v128) (result i32))) (type $v128_i32_=>_v128 (func (param v128 i32) (result v128)))- (type $none_=>_v128 (func (result v128))) (type $v128_v128_v128_=>_v128 (func (param v128 v128 v128) (result v128))) (type $i32_v128_=>_none (func (param i32 v128)))+ (type $i32_v128_=>_v128 (func (param i32 v128) (result v128)))+ (type $none_=>_v128 (func (result v128)))+ (type $i32_=>_none (func (param i32))) (type $v128_=>_i64 (func (param v128) (result i64))) (type $v128_=>_f32 (func (param v128) (result f32))) (type $v128_=>_f64 (func (param v128) (result f64)))@@ -332,6 +334,12 @@ (local.get $1) ) )+ (func $i64x2.eq (param $0 v128) (param $1 v128) (result v128)+ (i64x2.eq+ (local.get $0)+ (local.get $1)+ )+ ) (func $f32x4.eq (param $0 v128) (param $1 v128) (result v128) (f32x4.eq (local.get $0)@@ -440,6 +448,123 @@ (local.get $2) ) )+ (func $v8x16.signselect (param $0 v128) (param $1 v128) (param $2 v128) (result v128)+ (v8x16.signselect+ (local.get $0)+ (local.get $1)+ (local.get $2)+ )+ )+ (func $v16x8.signselect (param $0 v128) (param $1 v128) (param $2 v128) (result v128)+ (v16x8.signselect+ (local.get $0)+ (local.get $1)+ (local.get $2)+ )+ )+ (func $v32x4.signselect (param $0 v128) (param $1 v128) (param $2 v128) (result v128)+ (v32x4.signselect+ (local.get $0)+ (local.get $1)+ (local.get $2)+ )+ )+ (func $v64x2.signselect (param $0 v128) (param $1 v128) (param $2 v128) (result v128)+ (v64x2.signselect+ (local.get $0)+ (local.get $1)+ (local.get $2)+ )+ )+ (func $v128.load8_lane (param $0 i32) (param $1 v128) (result v128)+ (v128.load8_lane 0+ (local.get $0)+ (local.get $1)+ )+ )+ (func $v128.load16_lane (param $0 i32) (param $1 v128) (result v128)+ (v128.load16_lane 0+ (local.get $0)+ (local.get $1)+ )+ )+ (func $v128.load32_lane (param $0 i32) (param $1 v128) (result v128)+ (v128.load32_lane 0+ (local.get $0)+ (local.get $1)+ )+ )+ (func $v128.load64_lane (param $0 i32) (param $1 v128) (result v128)+ (v128.load64_lane 0+ (local.get $0)+ (local.get $1)+ )+ )+ (func $v128.load64_lane_align (param $0 i32) (param $1 v128) (result v128)+ (v128.load64_lane align=1 0+ (local.get $0)+ (local.get $1)+ )+ )+ (func $v128.load64_lane_offset (param $0 i32) (param $1 v128) (result v128)+ (v128.load64_lane offset=32 0+ (local.get $0)+ (local.get $1)+ )+ )+ (func $v128.load64_lane_align_offset (param $0 i32) (param $1 v128) (result v128)+ (v128.load64_lane offset=32 align=1 0+ (local.get $0)+ (local.get $1)+ )+ )+ (func $v128.store8_lane (param $0 i32) (param $1 v128)+ (v128.store8_lane 0+ (local.get $0)+ (local.get $1)+ )+ )+ (func $v128.store16_lane (param $0 i32) (param $1 v128)+ (v128.store16_lane 0+ (local.get $0)+ (local.get $1)+ )+ )+ (func $v128.store32_lane (param $0 i32) (param $1 v128)+ (v128.store32_lane 0+ (local.get $0)+ (local.get $1)+ )+ )+ (func $v128.store64_lane (param $0 i32) (param $1 v128)+ (v128.store64_lane 0+ (local.get $0)+ (local.get $1)+ )+ )+ (func $v128.store64_lane_align (param $0 i32) (param $1 v128)+ (v128.store64_lane align=1 0+ (local.get $0)+ (local.get $1)+ )+ )+ (func $v128.store64_lane_offset (param $0 i32) (param $1 v128)+ (v128.store64_lane offset=32 0+ (local.get $0)+ (local.get $1)+ )+ )+ (func $v128.store64_lane_align_offset (param $0 i32) (param $1 v128)+ (v128.store64_lane offset=32 align=1 0+ (local.get $0)+ (local.get $1)+ )+ )+ (func $i8x16.popcnt (param $0 v128) (result v128)+ (i8x16.popcnt+ (local.get $0)+ )+ ) (func $i8x16.abs (param $0 v128) (result v128) (i8x16.abs (local.get $0)@@ -670,6 +795,36 @@ (local.get $1) ) )+ (func $i16x8.q15mulr_sat_s (param $0 v128) (param $1 v128) (result v128)+ (i16x8.q15mulr_sat_s+ (local.get $0)+ (local.get $1)+ )+ )+ (func $i16x8.extmul_low_i8x16_s (param $0 v128) (param $1 v128) (result v128)+ (i16x8.extmul_low_i8x16_s+ (local.get $0)+ (local.get $1)+ )+ )+ (func $i16x8.extmul_high_i8x16_s (param $0 v128) (param $1 v128) (result v128)+ (i16x8.extmul_high_i8x16_s+ (local.get $0)+ (local.get $1)+ )+ )+ (func $i16x8.extmul_low_i8x16_u (param $0 v128) (param $1 v128) (result v128)+ (i16x8.extmul_low_i8x16_u+ (local.get $0)+ (local.get $1)+ )+ )+ (func $i16x8.extmul_high_i8x16_u (param $0 v128) (param $1 v128) (result v128)+ (i16x8.extmul_high_i8x16_u+ (local.get $0)+ (local.get $1)+ )+ ) (func $i32x4.abs (param $0 v128) (result v128) (i32x4.abs (local.get $0)@@ -761,21 +916,40 @@ (local.get $1) ) )- (func $i64x2.neg (param $0 v128) (result v128)- (i64x2.neg+ (func $i32x4.extmul_low_i16x8_s (param $0 v128) (param $1 v128) (result v128)+ (i32x4.extmul_low_i16x8_s (local.get $0)+ (local.get $1) ) )- (func $i64x2.any_true (param $0 v128) (result i32)- (i64x2.any_true+ (func $i32x4.extmul_high_i16x8_s (param $0 v128) (param $1 v128) (result v128)+ (i32x4.extmul_high_i16x8_s (local.get $0)+ (local.get $1) ) )- (func $i64x2.all_true (param $0 v128) (result i32)- (i64x2.all_true+ (func $i32x4.extmul_low_i16x8_u (param $0 v128) (param $1 v128) (result v128)+ (i32x4.extmul_low_i16x8_u (local.get $0)+ (local.get $1) ) )+ (func $i32x4.extmul_high_i16x8_u (param $0 v128) (param $1 v128) (result v128)+ (i32x4.extmul_high_i16x8_u+ (local.get $0)+ (local.get $1)+ )+ )+ (func $i64x2.neg (param $0 v128) (result v128)+ (i64x2.neg+ (local.get $0)+ )+ )+ (func $i64x2.bitmask (param $0 v128) (result i32)+ (i64x2.bitmask+ (local.get $0)+ )+ ) (func $i64x2.shl (param $0 v128) (param $1 i32) (result v128) (i64x2.shl (local.get $0)@@ -812,6 +986,30 @@ (local.get $1) ) )+ (func $i64x2.extmul_low_i32x4_s (param $0 v128) (param $1 v128) (result v128)+ (i64x2.extmul_low_i32x4_s+ (local.get $0)+ (local.get $1)+ )+ )+ (func $i64x2.extmul_high_i32x4_s (param $0 v128) (param $1 v128) (result v128)+ (i64x2.extmul_high_i32x4_s+ (local.get $0)+ (local.get $1)+ )+ )+ (func $i64x2.extmul_low_i32x4_u (param $0 v128) (param $1 v128) (result v128)+ (i64x2.extmul_low_i32x4_u+ (local.get $0)+ (local.get $1)+ )+ )+ (func $i64x2.extmul_high_i32x4_u (param $0 v128) (param $1 v128) (result v128)+ (i64x2.extmul_high_i32x4_u+ (local.get $0)+ (local.get $1)+ )+ ) (func $f32x4.add (param $0 v128) (param $1 v128) (result v128) (f32x4.add (local.get $0)@@ -1006,6 +1204,26 @@ (local.get $2) ) )+ (func $i16x8.extadd_pairwise_i8x16_s (param $0 v128) (result v128)+ (i16x8.extadd_pairwise_i8x16_s+ (local.get $0)+ )+ )+ (func $i16x8.extadd_pairwise_i8x16_u (param $0 v128) (result v128)+ (i16x8.extadd_pairwise_i8x16_u+ (local.get $0)+ )+ )+ (func $i32x4.extadd_pairwise_i16x8_s (param $0 v128) (result v128)+ (i32x4.extadd_pairwise_i16x8_s+ (local.get $0)+ )+ )+ (func $i32x4.extadd_pairwise_i16x8_u (param $0 v128) (result v128)+ (i32x4.extadd_pairwise_i16x8_u+ (local.get $0)+ )+ ) (func $i32x4.trunc_sat_f32x4_s (param $0 v128) (result v128) (i32x4.trunc_sat_f32x4_s (local.get $0)@@ -1130,6 +1348,26 @@ (local.get $0) ) )+ (func $i64x2.widen_low_i32x4_s (param $0 v128) (result v128)+ (i64x2.widen_low_i32x4_s+ (local.get $0)+ )+ )+ (func $i64x2.widen_high_i32x4_s (param $0 v128) (result v128)+ (i64x2.widen_high_i32x4_s+ (local.get $0)+ )+ )+ (func $i64x2.widen_low_i32x4_u (param $0 v128) (result v128)+ (i64x2.widen_low_i32x4_u+ (local.get $0)+ )+ )+ (func $i64x2.widen_high_i32x4_u (param $0 v128) (result v128)+ (i64x2.widen_high_i32x4_u+ (local.get $0)+ )+ ) (func $i16x8.load8x8_u (param $0 i32) (result v128) (i16x8.load8x8_u (local.get $0)@@ -1174,6 +1412,16 @@ (v8x16.swizzle (local.get $0) (local.get $1)+ )+ )+ (func $prefetch.t (param $0 i32)+ (prefetch.t offset=3 align=2+ (local.get $0)+ )+ )+ (func $prefetch.nt (param $0 i32)+ (prefetch.nt offset=3 align=2+ (local.get $0) ) ) )
binaryen/test/simd.wast.fromBinary view
@@ -1,12 +1,14 @@ (module (type $v128_v128_=>_v128 (func (param v128 v128) (result v128))) (type $v128_=>_v128 (func (param v128) (result v128)))- (type $v128_=>_i32 (func (param v128) (result i32))) (type $i32_=>_v128 (func (param i32) (result v128)))+ (type $v128_=>_i32 (func (param v128) (result i32))) (type $v128_i32_=>_v128 (func (param v128 i32) (result v128)))- (type $none_=>_v128 (func (result v128))) (type $v128_v128_v128_=>_v128 (func (param v128 v128 v128) (result v128))) (type $i32_v128_=>_none (func (param i32 v128)))+ (type $i32_v128_=>_v128 (func (param i32 v128) (result v128)))+ (type $none_=>_v128 (func (result v128)))+ (type $i32_=>_none (func (param i32))) (type $v128_=>_i64 (func (param v128) (result i64))) (type $v128_=>_f32 (func (param v128) (result f32))) (type $v128_=>_f64 (func (param v128) (result f64)))@@ -332,6 +334,12 @@ (local.get $1) ) )+ (func $i64x2.eq (param $0 v128) (param $1 v128) (result v128)+ (i64x2.eq+ (local.get $0)+ (local.get $1)+ )+ ) (func $f32x4.eq (param $0 v128) (param $1 v128) (result v128) (f32x4.eq (local.get $0)@@ -440,6 +448,123 @@ (local.get $2) ) )+ (func $v8x16.signselect (param $0 v128) (param $1 v128) (param $2 v128) (result v128)+ (v8x16.signselect+ (local.get $0)+ (local.get $1)+ (local.get $2)+ )+ )+ (func $v16x8.signselect (param $0 v128) (param $1 v128) (param $2 v128) (result v128)+ (v16x8.signselect+ (local.get $0)+ (local.get $1)+ (local.get $2)+ )+ )+ (func $v32x4.signselect (param $0 v128) (param $1 v128) (param $2 v128) (result v128)+ (v32x4.signselect+ (local.get $0)+ (local.get $1)+ (local.get $2)+ )+ )+ (func $v64x2.signselect (param $0 v128) (param $1 v128) (param $2 v128) (result v128)+ (v64x2.signselect+ (local.get $0)+ (local.get $1)+ (local.get $2)+ )+ )+ (func $v128.load8_lane (param $0 i32) (param $1 v128) (result v128)+ (v128.load8_lane 0+ (local.get $0)+ (local.get $1)+ )+ )+ (func $v128.load16_lane (param $0 i32) (param $1 v128) (result v128)+ (v128.load16_lane 0+ (local.get $0)+ (local.get $1)+ )+ )+ (func $v128.load32_lane (param $0 i32) (param $1 v128) (result v128)+ (v128.load32_lane 0+ (local.get $0)+ (local.get $1)+ )+ )+ (func $v128.load64_lane (param $0 i32) (param $1 v128) (result v128)+ (v128.load64_lane 0+ (local.get $0)+ (local.get $1)+ )+ )+ (func $v128.load64_lane_align (param $0 i32) (param $1 v128) (result v128)+ (v128.load64_lane align=1 0+ (local.get $0)+ (local.get $1)+ )+ )+ (func $v128.load64_lane_offset (param $0 i32) (param $1 v128) (result v128)+ (v128.load64_lane offset=32 0+ (local.get $0)+ (local.get $1)+ )+ )+ (func $v128.load64_lane_align_offset (param $0 i32) (param $1 v128) (result v128)+ (v128.load64_lane offset=32 align=1 0+ (local.get $0)+ (local.get $1)+ )+ )+ (func $v128.store8_lane (param $0 i32) (param $1 v128)+ (v128.store8_lane 0+ (local.get $0)+ (local.get $1)+ )+ )+ (func $v128.store16_lane (param $0 i32) (param $1 v128)+ (v128.store16_lane 0+ (local.get $0)+ (local.get $1)+ )+ )+ (func $v128.store32_lane (param $0 i32) (param $1 v128)+ (v128.store32_lane 0+ (local.get $0)+ (local.get $1)+ )+ )+ (func $v128.store64_lane (param $0 i32) (param $1 v128)+ (v128.store64_lane 0+ (local.get $0)+ (local.get $1)+ )+ )+ (func $v128.store64_lane_align (param $0 i32) (param $1 v128)+ (v128.store64_lane align=1 0+ (local.get $0)+ (local.get $1)+ )+ )+ (func $v128.store64_lane_offset (param $0 i32) (param $1 v128)+ (v128.store64_lane offset=32 0+ (local.get $0)+ (local.get $1)+ )+ )+ (func $v128.store64_lane_align_offset (param $0 i32) (param $1 v128)+ (v128.store64_lane offset=32 align=1 0+ (local.get $0)+ (local.get $1)+ )+ )+ (func $i8x16.popcnt (param $0 v128) (result v128)+ (i8x16.popcnt+ (local.get $0)+ )+ ) (func $i8x16.abs (param $0 v128) (result v128) (i8x16.abs (local.get $0)@@ -670,6 +795,36 @@ (local.get $1) ) )+ (func $i16x8.q15mulr_sat_s (param $0 v128) (param $1 v128) (result v128)+ (i16x8.q15mulr_sat_s+ (local.get $0)+ (local.get $1)+ )+ )+ (func $i16x8.extmul_low_i8x16_s (param $0 v128) (param $1 v128) (result v128)+ (i16x8.extmul_low_i8x16_s+ (local.get $0)+ (local.get $1)+ )+ )+ (func $i16x8.extmul_high_i8x16_s (param $0 v128) (param $1 v128) (result v128)+ (i16x8.extmul_high_i8x16_s+ (local.get $0)+ (local.get $1)+ )+ )+ (func $i16x8.extmul_low_i8x16_u (param $0 v128) (param $1 v128) (result v128)+ (i16x8.extmul_low_i8x16_u+ (local.get $0)+ (local.get $1)+ )+ )+ (func $i16x8.extmul_high_i8x16_u (param $0 v128) (param $1 v128) (result v128)+ (i16x8.extmul_high_i8x16_u+ (local.get $0)+ (local.get $1)+ )+ ) (func $i32x4.abs (param $0 v128) (result v128) (i32x4.abs (local.get $0)@@ -761,21 +916,40 @@ (local.get $1) ) )- (func $i64x2.neg (param $0 v128) (result v128)- (i64x2.neg+ (func $i32x4.extmul_low_i16x8_s (param $0 v128) (param $1 v128) (result v128)+ (i32x4.extmul_low_i16x8_s (local.get $0)+ (local.get $1) ) )- (func $i64x2.any_true (param $0 v128) (result i32)- (i64x2.any_true+ (func $i32x4.extmul_high_i16x8_s (param $0 v128) (param $1 v128) (result v128)+ (i32x4.extmul_high_i16x8_s (local.get $0)+ (local.get $1) ) )- (func $i64x2.all_true (param $0 v128) (result i32)- (i64x2.all_true+ (func $i32x4.extmul_low_i16x8_u (param $0 v128) (param $1 v128) (result v128)+ (i32x4.extmul_low_i16x8_u (local.get $0)+ (local.get $1) ) )+ (func $i32x4.extmul_high_i16x8_u (param $0 v128) (param $1 v128) (result v128)+ (i32x4.extmul_high_i16x8_u+ (local.get $0)+ (local.get $1)+ )+ )+ (func $i64x2.neg (param $0 v128) (result v128)+ (i64x2.neg+ (local.get $0)+ )+ )+ (func $i64x2.bitmask (param $0 v128) (result i32)+ (i64x2.bitmask+ (local.get $0)+ )+ ) (func $i64x2.shl (param $0 v128) (param $1 i32) (result v128) (i64x2.shl (local.get $0)@@ -812,6 +986,30 @@ (local.get $1) ) )+ (func $i64x2.extmul_low_i32x4_s (param $0 v128) (param $1 v128) (result v128)+ (i64x2.extmul_low_i32x4_s+ (local.get $0)+ (local.get $1)+ )+ )+ (func $i64x2.extmul_high_i32x4_s (param $0 v128) (param $1 v128) (result v128)+ (i64x2.extmul_high_i32x4_s+ (local.get $0)+ (local.get $1)+ )+ )+ (func $i64x2.extmul_low_i32x4_u (param $0 v128) (param $1 v128) (result v128)+ (i64x2.extmul_low_i32x4_u+ (local.get $0)+ (local.get $1)+ )+ )+ (func $i64x2.extmul_high_i32x4_u (param $0 v128) (param $1 v128) (result v128)+ (i64x2.extmul_high_i32x4_u+ (local.get $0)+ (local.get $1)+ )+ ) (func $f32x4.add (param $0 v128) (param $1 v128) (result v128) (f32x4.add (local.get $0)@@ -1006,6 +1204,26 @@ (local.get $2) ) )+ (func $i16x8.extadd_pairwise_i8x16_s (param $0 v128) (result v128)+ (i16x8.extadd_pairwise_i8x16_s+ (local.get $0)+ )+ )+ (func $i16x8.extadd_pairwise_i8x16_u (param $0 v128) (result v128)+ (i16x8.extadd_pairwise_i8x16_u+ (local.get $0)+ )+ )+ (func $i32x4.extadd_pairwise_i16x8_s (param $0 v128) (result v128)+ (i32x4.extadd_pairwise_i16x8_s+ (local.get $0)+ )+ )+ (func $i32x4.extadd_pairwise_i16x8_u (param $0 v128) (result v128)+ (i32x4.extadd_pairwise_i16x8_u+ (local.get $0)+ )+ ) (func $i32x4.trunc_sat_f32x4_s (param $0 v128) (result v128) (i32x4.trunc_sat_f32x4_s (local.get $0)@@ -1130,6 +1348,26 @@ (local.get $0) ) )+ (func $i64x2.widen_low_i32x4_s (param $0 v128) (result v128)+ (i64x2.widen_low_i32x4_s+ (local.get $0)+ )+ )+ (func $i64x2.widen_high_i32x4_s (param $0 v128) (result v128)+ (i64x2.widen_high_i32x4_s+ (local.get $0)+ )+ )+ (func $i64x2.widen_low_i32x4_u (param $0 v128) (result v128)+ (i64x2.widen_low_i32x4_u+ (local.get $0)+ )+ )+ (func $i64x2.widen_high_i32x4_u (param $0 v128) (result v128)+ (i64x2.widen_high_i32x4_u+ (local.get $0)+ )+ ) (func $i16x8.load8x8_u (param $0 i32) (result v128) (i16x8.load8x8_u (local.get $0)@@ -1174,6 +1412,16 @@ (v8x16.swizzle (local.get $0) (local.get $1)+ )+ )+ (func $prefetch.t (param $0 i32)+ (prefetch.t offset=3 align=2+ (local.get $0)+ )+ )+ (func $prefetch.nt (param $0 i32)+ (prefetch.nt offset=3 align=2+ (local.get $0) ) ) )
binaryen/test/simd.wast.fromBinary.noDebugInfo view
@@ -1,12 +1,14 @@ (module (type $v128_v128_=>_v128 (func (param v128 v128) (result v128))) (type $v128_=>_v128 (func (param v128) (result v128)))- (type $v128_=>_i32 (func (param v128) (result i32))) (type $i32_=>_v128 (func (param i32) (result v128)))+ (type $v128_=>_i32 (func (param v128) (result i32))) (type $v128_i32_=>_v128 (func (param v128 i32) (result v128)))- (type $none_=>_v128 (func (result v128))) (type $v128_v128_v128_=>_v128 (func (param v128 v128 v128) (result v128))) (type $i32_v128_=>_none (func (param i32 v128)))+ (type $i32_v128_=>_v128 (func (param i32 v128) (result v128)))+ (type $none_=>_v128 (func (result v128)))+ (type $i32_=>_none (func (param i32))) (type $v128_=>_i64 (func (param v128) (result i64))) (type $v128_=>_f32 (func (param v128) (result f32))) (type $v128_=>_f64 (func (param v128) (result f64)))@@ -333,847 +335,1093 @@ ) ) (func $58 (param $0 v128) (param $1 v128) (result v128)- (f32x4.eq+ (i64x2.eq (local.get $0) (local.get $1) ) ) (func $59 (param $0 v128) (param $1 v128) (result v128)- (f32x4.ne+ (f32x4.eq (local.get $0) (local.get $1) ) ) (func $60 (param $0 v128) (param $1 v128) (result v128)- (f32x4.lt+ (f32x4.ne (local.get $0) (local.get $1) ) ) (func $61 (param $0 v128) (param $1 v128) (result v128)- (f32x4.gt+ (f32x4.lt (local.get $0) (local.get $1) ) ) (func $62 (param $0 v128) (param $1 v128) (result v128)- (f32x4.le+ (f32x4.gt (local.get $0) (local.get $1) ) ) (func $63 (param $0 v128) (param $1 v128) (result v128)- (f32x4.ge+ (f32x4.le (local.get $0) (local.get $1) ) ) (func $64 (param $0 v128) (param $1 v128) (result v128)- (f64x2.eq+ (f32x4.ge (local.get $0) (local.get $1) ) ) (func $65 (param $0 v128) (param $1 v128) (result v128)- (f64x2.ne+ (f64x2.eq (local.get $0) (local.get $1) ) ) (func $66 (param $0 v128) (param $1 v128) (result v128)- (f64x2.lt+ (f64x2.ne (local.get $0) (local.get $1) ) ) (func $67 (param $0 v128) (param $1 v128) (result v128)- (f64x2.gt+ (f64x2.lt (local.get $0) (local.get $1) ) ) (func $68 (param $0 v128) (param $1 v128) (result v128)- (f64x2.le+ (f64x2.gt (local.get $0) (local.get $1) ) ) (func $69 (param $0 v128) (param $1 v128) (result v128)+ (f64x2.le+ (local.get $0)+ (local.get $1)+ )+ )+ (func $70 (param $0 v128) (param $1 v128) (result v128) (f64x2.ge (local.get $0) (local.get $1) ) )- (func $70 (param $0 v128) (result v128)+ (func $71 (param $0 v128) (result v128) (v128.not (local.get $0) ) )- (func $71 (param $0 v128) (param $1 v128) (result v128)+ (func $72 (param $0 v128) (param $1 v128) (result v128) (v128.and (local.get $0) (local.get $1) ) )- (func $72 (param $0 v128) (param $1 v128) (result v128)+ (func $73 (param $0 v128) (param $1 v128) (result v128) (v128.or (local.get $0) (local.get $1) ) )- (func $73 (param $0 v128) (param $1 v128) (result v128)+ (func $74 (param $0 v128) (param $1 v128) (result v128) (v128.xor (local.get $0) (local.get $1) ) )- (func $74 (param $0 v128) (param $1 v128) (result v128)+ (func $75 (param $0 v128) (param $1 v128) (result v128) (v128.andnot (local.get $0) (local.get $1) ) )- (func $75 (param $0 v128) (param $1 v128) (param $2 v128) (result v128)+ (func $76 (param $0 v128) (param $1 v128) (param $2 v128) (result v128) (v128.bitselect (local.get $0) (local.get $1) (local.get $2) ) )- (func $76 (param $0 v128) (result v128)+ (func $77 (param $0 v128) (param $1 v128) (param $2 v128) (result v128)+ (v8x16.signselect+ (local.get $0)+ (local.get $1)+ (local.get $2)+ )+ )+ (func $78 (param $0 v128) (param $1 v128) (param $2 v128) (result v128)+ (v16x8.signselect+ (local.get $0)+ (local.get $1)+ (local.get $2)+ )+ )+ (func $79 (param $0 v128) (param $1 v128) (param $2 v128) (result v128)+ (v32x4.signselect+ (local.get $0)+ (local.get $1)+ (local.get $2)+ )+ )+ (func $80 (param $0 v128) (param $1 v128) (param $2 v128) (result v128)+ (v64x2.signselect+ (local.get $0)+ (local.get $1)+ (local.get $2)+ )+ )+ (func $81 (param $0 i32) (param $1 v128) (result v128)+ (v128.load8_lane 0+ (local.get $0)+ (local.get $1)+ )+ )+ (func $82 (param $0 i32) (param $1 v128) (result v128)+ (v128.load16_lane 0+ (local.get $0)+ (local.get $1)+ )+ )+ (func $83 (param $0 i32) (param $1 v128) (result v128)+ (v128.load32_lane 0+ (local.get $0)+ (local.get $1)+ )+ )+ (func $84 (param $0 i32) (param $1 v128) (result v128)+ (v128.load64_lane 0+ (local.get $0)+ (local.get $1)+ )+ )+ (func $85 (param $0 i32) (param $1 v128) (result v128)+ (v128.load64_lane align=1 0+ (local.get $0)+ (local.get $1)+ )+ )+ (func $86 (param $0 i32) (param $1 v128) (result v128)+ (v128.load64_lane offset=32 0+ (local.get $0)+ (local.get $1)+ )+ )+ (func $87 (param $0 i32) (param $1 v128) (result v128)+ (v128.load64_lane offset=32 align=1 0+ (local.get $0)+ (local.get $1)+ )+ )+ (func $88 (param $0 i32) (param $1 v128)+ (v128.store8_lane 0+ (local.get $0)+ (local.get $1)+ )+ )+ (func $89 (param $0 i32) (param $1 v128)+ (v128.store16_lane 0+ (local.get $0)+ (local.get $1)+ )+ )+ (func $90 (param $0 i32) (param $1 v128)+ (v128.store32_lane 0+ (local.get $0)+ (local.get $1)+ )+ )+ (func $91 (param $0 i32) (param $1 v128)+ (v128.store64_lane 0+ (local.get $0)+ (local.get $1)+ )+ )+ (func $92 (param $0 i32) (param $1 v128)+ (v128.store64_lane align=1 0+ (local.get $0)+ (local.get $1)+ )+ )+ (func $93 (param $0 i32) (param $1 v128)+ (v128.store64_lane offset=32 0+ (local.get $0)+ (local.get $1)+ )+ )+ (func $94 (param $0 i32) (param $1 v128)+ (v128.store64_lane offset=32 align=1 0+ (local.get $0)+ (local.get $1)+ )+ )+ (func $95 (param $0 v128) (result v128)+ (i8x16.popcnt+ (local.get $0)+ )+ )+ (func $96 (param $0 v128) (result v128) (i8x16.abs (local.get $0) ) )- (func $77 (param $0 v128) (result v128)+ (func $97 (param $0 v128) (result v128) (i8x16.neg (local.get $0) ) )- (func $78 (param $0 v128) (result i32)+ (func $98 (param $0 v128) (result i32) (i8x16.any_true (local.get $0) ) )- (func $79 (param $0 v128) (result i32)+ (func $99 (param $0 v128) (result i32) (i8x16.all_true (local.get $0) ) )- (func $80 (param $0 v128) (result i32)+ (func $100 (param $0 v128) (result i32) (i8x16.bitmask (local.get $0) ) )- (func $81 (param $0 v128) (param $1 i32) (result v128)+ (func $101 (param $0 v128) (param $1 i32) (result v128) (i8x16.shl (local.get $0) (local.get $1) ) )- (func $82 (param $0 v128) (param $1 i32) (result v128)+ (func $102 (param $0 v128) (param $1 i32) (result v128) (i8x16.shr_s (local.get $0) (local.get $1) ) )- (func $83 (param $0 v128) (param $1 i32) (result v128)+ (func $103 (param $0 v128) (param $1 i32) (result v128) (i8x16.shr_u (local.get $0) (local.get $1) ) )- (func $84 (param $0 v128) (param $1 v128) (result v128)+ (func $104 (param $0 v128) (param $1 v128) (result v128) (i8x16.add (local.get $0) (local.get $1) ) )- (func $85 (param $0 v128) (param $1 v128) (result v128)+ (func $105 (param $0 v128) (param $1 v128) (result v128) (i8x16.add_saturate_s (local.get $0) (local.get $1) ) )- (func $86 (param $0 v128) (param $1 v128) (result v128)+ (func $106 (param $0 v128) (param $1 v128) (result v128) (i8x16.add_saturate_u (local.get $0) (local.get $1) ) )- (func $87 (param $0 v128) (param $1 v128) (result v128)+ (func $107 (param $0 v128) (param $1 v128) (result v128) (i8x16.sub (local.get $0) (local.get $1) ) )- (func $88 (param $0 v128) (param $1 v128) (result v128)+ (func $108 (param $0 v128) (param $1 v128) (result v128) (i8x16.sub_saturate_s (local.get $0) (local.get $1) ) )- (func $89 (param $0 v128) (param $1 v128) (result v128)+ (func $109 (param $0 v128) (param $1 v128) (result v128) (i8x16.sub_saturate_u (local.get $0) (local.get $1) ) )- (func $90 (param $0 v128) (param $1 v128) (result v128)+ (func $110 (param $0 v128) (param $1 v128) (result v128) (i8x16.mul (local.get $0) (local.get $1) ) )- (func $91 (param $0 v128) (param $1 v128) (result v128)+ (func $111 (param $0 v128) (param $1 v128) (result v128) (i8x16.min_s (local.get $0) (local.get $1) ) )- (func $92 (param $0 v128) (param $1 v128) (result v128)+ (func $112 (param $0 v128) (param $1 v128) (result v128) (i8x16.min_u (local.get $0) (local.get $1) ) )- (func $93 (param $0 v128) (param $1 v128) (result v128)+ (func $113 (param $0 v128) (param $1 v128) (result v128) (i8x16.max_s (local.get $0) (local.get $1) ) )- (func $94 (param $0 v128) (param $1 v128) (result v128)+ (func $114 (param $0 v128) (param $1 v128) (result v128) (i8x16.max_u (local.get $0) (local.get $1) ) )- (func $95 (param $0 v128) (param $1 v128) (result v128)+ (func $115 (param $0 v128) (param $1 v128) (result v128) (i8x16.avgr_u (local.get $0) (local.get $1) ) )- (func $96 (param $0 v128) (result v128)+ (func $116 (param $0 v128) (result v128) (i16x8.abs (local.get $0) ) )- (func $97 (param $0 v128) (result v128)+ (func $117 (param $0 v128) (result v128) (i16x8.neg (local.get $0) ) )- (func $98 (param $0 v128) (result i32)+ (func $118 (param $0 v128) (result i32) (i16x8.any_true (local.get $0) ) )- (func $99 (param $0 v128) (result i32)+ (func $119 (param $0 v128) (result i32) (i16x8.all_true (local.get $0) ) )- (func $100 (param $0 v128) (result i32)+ (func $120 (param $0 v128) (result i32) (i16x8.bitmask (local.get $0) ) )- (func $101 (param $0 v128) (param $1 i32) (result v128)+ (func $121 (param $0 v128) (param $1 i32) (result v128) (i16x8.shl (local.get $0) (local.get $1) ) )- (func $102 (param $0 v128) (param $1 i32) (result v128)+ (func $122 (param $0 v128) (param $1 i32) (result v128) (i16x8.shr_s (local.get $0) (local.get $1) ) )- (func $103 (param $0 v128) (param $1 i32) (result v128)+ (func $123 (param $0 v128) (param $1 i32) (result v128) (i16x8.shr_u (local.get $0) (local.get $1) ) )- (func $104 (param $0 v128) (param $1 v128) (result v128)+ (func $124 (param $0 v128) (param $1 v128) (result v128) (i16x8.add (local.get $0) (local.get $1) ) )- (func $105 (param $0 v128) (param $1 v128) (result v128)+ (func $125 (param $0 v128) (param $1 v128) (result v128) (i16x8.add_saturate_s (local.get $0) (local.get $1) ) )- (func $106 (param $0 v128) (param $1 v128) (result v128)+ (func $126 (param $0 v128) (param $1 v128) (result v128) (i16x8.add_saturate_u (local.get $0) (local.get $1) ) )- (func $107 (param $0 v128) (param $1 v128) (result v128)+ (func $127 (param $0 v128) (param $1 v128) (result v128) (i16x8.sub (local.get $0) (local.get $1) ) )- (func $108 (param $0 v128) (param $1 v128) (result v128)+ (func $128 (param $0 v128) (param $1 v128) (result v128) (i16x8.sub_saturate_s (local.get $0) (local.get $1) ) )- (func $109 (param $0 v128) (param $1 v128) (result v128)+ (func $129 (param $0 v128) (param $1 v128) (result v128) (i16x8.sub_saturate_u (local.get $0) (local.get $1) ) )- (func $110 (param $0 v128) (param $1 v128) (result v128)+ (func $130 (param $0 v128) (param $1 v128) (result v128) (i16x8.mul (local.get $0) (local.get $1) ) )- (func $111 (param $0 v128) (param $1 v128) (result v128)+ (func $131 (param $0 v128) (param $1 v128) (result v128) (i16x8.min_s (local.get $0) (local.get $1) ) )- (func $112 (param $0 v128) (param $1 v128) (result v128)+ (func $132 (param $0 v128) (param $1 v128) (result v128) (i16x8.min_u (local.get $0) (local.get $1) ) )- (func $113 (param $0 v128) (param $1 v128) (result v128)+ (func $133 (param $0 v128) (param $1 v128) (result v128) (i16x8.max_s (local.get $0) (local.get $1) ) )- (func $114 (param $0 v128) (param $1 v128) (result v128)+ (func $134 (param $0 v128) (param $1 v128) (result v128) (i16x8.max_u (local.get $0) (local.get $1) ) )- (func $115 (param $0 v128) (param $1 v128) (result v128)+ (func $135 (param $0 v128) (param $1 v128) (result v128) (i16x8.avgr_u (local.get $0) (local.get $1) ) )- (func $116 (param $0 v128) (result v128)+ (func $136 (param $0 v128) (param $1 v128) (result v128)+ (i16x8.q15mulr_sat_s+ (local.get $0)+ (local.get $1)+ )+ )+ (func $137 (param $0 v128) (param $1 v128) (result v128)+ (i16x8.extmul_low_i8x16_s+ (local.get $0)+ (local.get $1)+ )+ )+ (func $138 (param $0 v128) (param $1 v128) (result v128)+ (i16x8.extmul_high_i8x16_s+ (local.get $0)+ (local.get $1)+ )+ )+ (func $139 (param $0 v128) (param $1 v128) (result v128)+ (i16x8.extmul_low_i8x16_u+ (local.get $0)+ (local.get $1)+ )+ )+ (func $140 (param $0 v128) (param $1 v128) (result v128)+ (i16x8.extmul_high_i8x16_u+ (local.get $0)+ (local.get $1)+ )+ )+ (func $141 (param $0 v128) (result v128) (i32x4.abs (local.get $0) ) )- (func $117 (param $0 v128) (result v128)+ (func $142 (param $0 v128) (result v128) (i32x4.neg (local.get $0) ) )- (func $118 (param $0 v128) (result i32)+ (func $143 (param $0 v128) (result i32) (i32x4.any_true (local.get $0) ) )- (func $119 (param $0 v128) (result i32)+ (func $144 (param $0 v128) (result i32) (i32x4.all_true (local.get $0) ) )- (func $120 (param $0 v128) (result i32)+ (func $145 (param $0 v128) (result i32) (i32x4.bitmask (local.get $0) ) )- (func $121 (param $0 v128) (param $1 i32) (result v128)+ (func $146 (param $0 v128) (param $1 i32) (result v128) (i32x4.shl (local.get $0) (local.get $1) ) )- (func $122 (param $0 v128) (param $1 i32) (result v128)+ (func $147 (param $0 v128) (param $1 i32) (result v128) (i32x4.shr_s (local.get $0) (local.get $1) ) )- (func $123 (param $0 v128) (param $1 i32) (result v128)+ (func $148 (param $0 v128) (param $1 i32) (result v128) (i32x4.shr_u (local.get $0) (local.get $1) ) )- (func $124 (param $0 v128) (param $1 v128) (result v128)+ (func $149 (param $0 v128) (param $1 v128) (result v128) (i32x4.add (local.get $0) (local.get $1) ) )- (func $125 (param $0 v128) (param $1 v128) (result v128)+ (func $150 (param $0 v128) (param $1 v128) (result v128) (i32x4.sub (local.get $0) (local.get $1) ) )- (func $126 (param $0 v128) (param $1 v128) (result v128)+ (func $151 (param $0 v128) (param $1 v128) (result v128) (i32x4.mul (local.get $0) (local.get $1) ) )- (func $127 (param $0 v128) (param $1 v128) (result v128)+ (func $152 (param $0 v128) (param $1 v128) (result v128) (i32x4.min_s (local.get $0) (local.get $1) ) )- (func $128 (param $0 v128) (param $1 v128) (result v128)+ (func $153 (param $0 v128) (param $1 v128) (result v128) (i32x4.min_u (local.get $0) (local.get $1) ) )- (func $129 (param $0 v128) (param $1 v128) (result v128)+ (func $154 (param $0 v128) (param $1 v128) (result v128) (i32x4.max_s (local.get $0) (local.get $1) ) )- (func $130 (param $0 v128) (param $1 v128) (result v128)+ (func $155 (param $0 v128) (param $1 v128) (result v128) (i32x4.max_u (local.get $0) (local.get $1) ) )- (func $131 (param $0 v128) (param $1 v128) (result v128)+ (func $156 (param $0 v128) (param $1 v128) (result v128) (i32x4.dot_i16x8_s (local.get $0) (local.get $1) ) )- (func $132 (param $0 v128) (result v128)- (i64x2.neg+ (func $157 (param $0 v128) (param $1 v128) (result v128)+ (i32x4.extmul_low_i16x8_s (local.get $0)+ (local.get $1) ) )- (func $133 (param $0 v128) (result i32)- (i64x2.any_true+ (func $158 (param $0 v128) (param $1 v128) (result v128)+ (i32x4.extmul_high_i16x8_s (local.get $0)+ (local.get $1) ) )- (func $134 (param $0 v128) (result i32)- (i64x2.all_true+ (func $159 (param $0 v128) (param $1 v128) (result v128)+ (i32x4.extmul_low_i16x8_u (local.get $0)+ (local.get $1) ) )- (func $135 (param $0 v128) (param $1 i32) (result v128)+ (func $160 (param $0 v128) (param $1 v128) (result v128)+ (i32x4.extmul_high_i16x8_u+ (local.get $0)+ (local.get $1)+ )+ )+ (func $161 (param $0 v128) (result v128)+ (i64x2.neg+ (local.get $0)+ )+ )+ (func $162 (param $0 v128) (result i32)+ (i64x2.bitmask+ (local.get $0)+ )+ )+ (func $163 (param $0 v128) (param $1 i32) (result v128) (i64x2.shl (local.get $0) (local.get $1) ) )- (func $136 (param $0 v128) (param $1 i32) (result v128)+ (func $164 (param $0 v128) (param $1 i32) (result v128) (i64x2.shr_s (local.get $0) (local.get $1) ) )- (func $137 (param $0 v128) (param $1 i32) (result v128)+ (func $165 (param $0 v128) (param $1 i32) (result v128) (i64x2.shr_u (local.get $0) (local.get $1) ) )- (func $138 (param $0 v128) (param $1 v128) (result v128)+ (func $166 (param $0 v128) (param $1 v128) (result v128) (i64x2.add (local.get $0) (local.get $1) ) )- (func $139 (param $0 v128) (param $1 v128) (result v128)+ (func $167 (param $0 v128) (param $1 v128) (result v128) (i64x2.sub (local.get $0) (local.get $1) ) )- (func $140 (param $0 v128) (param $1 v128) (result v128)+ (func $168 (param $0 v128) (param $1 v128) (result v128) (i64x2.mul (local.get $0) (local.get $1) ) )- (func $141 (param $0 v128) (param $1 v128) (result v128)+ (func $169 (param $0 v128) (param $1 v128) (result v128)+ (i64x2.extmul_low_i32x4_s+ (local.get $0)+ (local.get $1)+ )+ )+ (func $170 (param $0 v128) (param $1 v128) (result v128)+ (i64x2.extmul_high_i32x4_s+ (local.get $0)+ (local.get $1)+ )+ )+ (func $171 (param $0 v128) (param $1 v128) (result v128)+ (i64x2.extmul_low_i32x4_u+ (local.get $0)+ (local.get $1)+ )+ )+ (func $172 (param $0 v128) (param $1 v128) (result v128)+ (i64x2.extmul_high_i32x4_u+ (local.get $0)+ (local.get $1)+ )+ )+ (func $173 (param $0 v128) (param $1 v128) (result v128) (f32x4.add (local.get $0) (local.get $1) ) )- (func $142 (param $0 v128) (param $1 v128) (result v128)+ (func $174 (param $0 v128) (param $1 v128) (result v128) (f32x4.sub (local.get $0) (local.get $1) ) )- (func $143 (param $0 v128) (param $1 v128) (result v128)+ (func $175 (param $0 v128) (param $1 v128) (result v128) (f32x4.mul (local.get $0) (local.get $1) ) )- (func $144 (param $0 v128) (param $1 v128) (result v128)+ (func $176 (param $0 v128) (param $1 v128) (result v128) (f32x4.div (local.get $0) (local.get $1) ) )- (func $145 (param $0 v128) (param $1 v128) (result v128)+ (func $177 (param $0 v128) (param $1 v128) (result v128) (f32x4.min (local.get $0) (local.get $1) ) )- (func $146 (param $0 v128) (param $1 v128) (result v128)+ (func $178 (param $0 v128) (param $1 v128) (result v128) (f32x4.max (local.get $0) (local.get $1) ) )- (func $147 (param $0 v128) (param $1 v128) (result v128)+ (func $179 (param $0 v128) (param $1 v128) (result v128) (f32x4.pmin (local.get $0) (local.get $1) ) )- (func $148 (param $0 v128) (param $1 v128) (result v128)+ (func $180 (param $0 v128) (param $1 v128) (result v128) (f32x4.pmax (local.get $0) (local.get $1) ) )- (func $149 (param $0 v128) (result v128)+ (func $181 (param $0 v128) (result v128) (f32x4.ceil (local.get $0) ) )- (func $150 (param $0 v128) (result v128)+ (func $182 (param $0 v128) (result v128) (f32x4.floor (local.get $0) ) )- (func $151 (param $0 v128) (result v128)+ (func $183 (param $0 v128) (result v128) (f32x4.trunc (local.get $0) ) )- (func $152 (param $0 v128) (result v128)+ (func $184 (param $0 v128) (result v128) (f32x4.nearest (local.get $0) ) )- (func $153 (param $0 v128) (result v128)+ (func $185 (param $0 v128) (result v128) (f32x4.abs (local.get $0) ) )- (func $154 (param $0 v128) (result v128)+ (func $186 (param $0 v128) (result v128) (f32x4.neg (local.get $0) ) )- (func $155 (param $0 v128) (result v128)+ (func $187 (param $0 v128) (result v128) (f32x4.sqrt (local.get $0) ) )- (func $156 (param $0 v128) (param $1 v128) (param $2 v128) (result v128)+ (func $188 (param $0 v128) (param $1 v128) (param $2 v128) (result v128) (f32x4.qfma (local.get $0) (local.get $1) (local.get $2) ) )- (func $157 (param $0 v128) (param $1 v128) (param $2 v128) (result v128)+ (func $189 (param $0 v128) (param $1 v128) (param $2 v128) (result v128) (f32x4.qfms (local.get $0) (local.get $1) (local.get $2) ) )- (func $158 (param $0 v128) (param $1 v128) (result v128)+ (func $190 (param $0 v128) (param $1 v128) (result v128) (f64x2.add (local.get $0) (local.get $1) ) )- (func $159 (param $0 v128) (param $1 v128) (result v128)+ (func $191 (param $0 v128) (param $1 v128) (result v128) (f64x2.sub (local.get $0) (local.get $1) ) )- (func $160 (param $0 v128) (param $1 v128) (result v128)+ (func $192 (param $0 v128) (param $1 v128) (result v128) (f64x2.mul (local.get $0) (local.get $1) ) )- (func $161 (param $0 v128) (param $1 v128) (result v128)+ (func $193 (param $0 v128) (param $1 v128) (result v128) (f64x2.div (local.get $0) (local.get $1) ) )- (func $162 (param $0 v128) (param $1 v128) (result v128)+ (func $194 (param $0 v128) (param $1 v128) (result v128) (f64x2.min (local.get $0) (local.get $1) ) )- (func $163 (param $0 v128) (param $1 v128) (result v128)+ (func $195 (param $0 v128) (param $1 v128) (result v128) (f64x2.max (local.get $0) (local.get $1) ) )- (func $164 (param $0 v128) (param $1 v128) (result v128)+ (func $196 (param $0 v128) (param $1 v128) (result v128) (f64x2.pmin (local.get $0) (local.get $1) ) )- (func $165 (param $0 v128) (param $1 v128) (result v128)+ (func $197 (param $0 v128) (param $1 v128) (result v128) (f64x2.pmax (local.get $0) (local.get $1) ) )- (func $166 (param $0 v128) (result v128)+ (func $198 (param $0 v128) (result v128) (f64x2.ceil (local.get $0) ) )- (func $167 (param $0 v128) (result v128)+ (func $199 (param $0 v128) (result v128) (f64x2.floor (local.get $0) ) )- (func $168 (param $0 v128) (result v128)+ (func $200 (param $0 v128) (result v128) (f64x2.trunc (local.get $0) ) )- (func $169 (param $0 v128) (result v128)+ (func $201 (param $0 v128) (result v128) (f64x2.nearest (local.get $0) ) )- (func $170 (param $0 v128) (result v128)+ (func $202 (param $0 v128) (result v128) (f64x2.abs (local.get $0) ) )- (func $171 (param $0 v128) (result v128)+ (func $203 (param $0 v128) (result v128) (f64x2.neg (local.get $0) ) )- (func $172 (param $0 v128) (result v128)+ (func $204 (param $0 v128) (result v128) (f64x2.sqrt (local.get $0) ) )- (func $173 (param $0 v128) (param $1 v128) (param $2 v128) (result v128)+ (func $205 (param $0 v128) (param $1 v128) (param $2 v128) (result v128) (f64x2.qfma (local.get $0) (local.get $1) (local.get $2) ) )- (func $174 (param $0 v128) (param $1 v128) (param $2 v128) (result v128)+ (func $206 (param $0 v128) (param $1 v128) (param $2 v128) (result v128) (f64x2.qfms (local.get $0) (local.get $1) (local.get $2) ) )- (func $175 (param $0 v128) (result v128)+ (func $207 (param $0 v128) (result v128)+ (i16x8.extadd_pairwise_i8x16_s+ (local.get $0)+ )+ )+ (func $208 (param $0 v128) (result v128)+ (i16x8.extadd_pairwise_i8x16_u+ (local.get $0)+ )+ )+ (func $209 (param $0 v128) (result v128)+ (i32x4.extadd_pairwise_i16x8_s+ (local.get $0)+ )+ )+ (func $210 (param $0 v128) (result v128)+ (i32x4.extadd_pairwise_i16x8_u+ (local.get $0)+ )+ )+ (func $211 (param $0 v128) (result v128) (i32x4.trunc_sat_f32x4_s (local.get $0) ) )- (func $176 (param $0 v128) (result v128)+ (func $212 (param $0 v128) (result v128) (i32x4.trunc_sat_f32x4_u (local.get $0) ) )- (func $177 (param $0 v128) (result v128)+ (func $213 (param $0 v128) (result v128) (i64x2.trunc_sat_f64x2_s (local.get $0) ) )- (func $178 (param $0 v128) (result v128)+ (func $214 (param $0 v128) (result v128) (i64x2.trunc_sat_f64x2_u (local.get $0) ) )- (func $179 (param $0 v128) (result v128)+ (func $215 (param $0 v128) (result v128) (f32x4.convert_i32x4_s (local.get $0) ) )- (func $180 (param $0 v128) (result v128)+ (func $216 (param $0 v128) (result v128) (f32x4.convert_i32x4_u (local.get $0) ) )- (func $181 (param $0 v128) (result v128)+ (func $217 (param $0 v128) (result v128) (f64x2.convert_i64x2_s (local.get $0) ) )- (func $182 (param $0 v128) (result v128)+ (func $218 (param $0 v128) (result v128) (f64x2.convert_i64x2_u (local.get $0) ) )- (func $183 (param $0 i32) (result v128)+ (func $219 (param $0 i32) (result v128) (v8x16.load_splat (local.get $0) ) )- (func $184 (param $0 i32) (result v128)+ (func $220 (param $0 i32) (result v128) (v16x8.load_splat (local.get $0) ) )- (func $185 (param $0 i32) (result v128)+ (func $221 (param $0 i32) (result v128) (v32x4.load_splat (local.get $0) ) )- (func $186 (param $0 i32) (result v128)+ (func $222 (param $0 i32) (result v128) (v64x2.load_splat (local.get $0) ) )- (func $187 (param $0 v128) (param $1 v128) (result v128)+ (func $223 (param $0 v128) (param $1 v128) (result v128) (i8x16.narrow_i16x8_s (local.get $0) (local.get $1) ) )- (func $188 (param $0 v128) (param $1 v128) (result v128)+ (func $224 (param $0 v128) (param $1 v128) (result v128) (i8x16.narrow_i16x8_u (local.get $0) (local.get $1) ) )- (func $189 (param $0 v128) (param $1 v128) (result v128)+ (func $225 (param $0 v128) (param $1 v128) (result v128) (i16x8.narrow_i32x4_s (local.get $0) (local.get $1) ) )- (func $190 (param $0 v128) (param $1 v128) (result v128)+ (func $226 (param $0 v128) (param $1 v128) (result v128) (i16x8.narrow_i32x4_u (local.get $0) (local.get $1) ) )- (func $191 (param $0 v128) (result v128)+ (func $227 (param $0 v128) (result v128) (i16x8.widen_low_i8x16_s (local.get $0) ) )- (func $192 (param $0 v128) (result v128)+ (func $228 (param $0 v128) (result v128) (i16x8.widen_high_i8x16_s (local.get $0) ) )- (func $193 (param $0 v128) (result v128)+ (func $229 (param $0 v128) (result v128) (i16x8.widen_low_i8x16_u (local.get $0) ) )- (func $194 (param $0 v128) (result v128)+ (func $230 (param $0 v128) (result v128) (i16x8.widen_high_i8x16_u (local.get $0) ) )- (func $195 (param $0 v128) (result v128)+ (func $231 (param $0 v128) (result v128) (i32x4.widen_low_i16x8_s (local.get $0) ) )- (func $196 (param $0 v128) (result v128)+ (func $232 (param $0 v128) (result v128) (i32x4.widen_high_i16x8_s (local.get $0) ) )- (func $197 (param $0 v128) (result v128)+ (func $233 (param $0 v128) (result v128) (i32x4.widen_low_i16x8_u (local.get $0) ) )- (func $198 (param $0 v128) (result v128)+ (func $234 (param $0 v128) (result v128) (i32x4.widen_high_i16x8_u (local.get $0) ) )- (func $199 (param $0 i32) (result v128)+ (func $235 (param $0 v128) (result v128)+ (i64x2.widen_low_i32x4_s+ (local.get $0)+ )+ )+ (func $236 (param $0 v128) (result v128)+ (i64x2.widen_high_i32x4_s+ (local.get $0)+ )+ )+ (func $237 (param $0 v128) (result v128)+ (i64x2.widen_low_i32x4_u+ (local.get $0)+ )+ )+ (func $238 (param $0 v128) (result v128)+ (i64x2.widen_high_i32x4_u+ (local.get $0)+ )+ )+ (func $239 (param $0 i32) (result v128) (i16x8.load8x8_u (local.get $0) ) )- (func $200 (param $0 i32) (result v128)+ (func $240 (param $0 i32) (result v128) (i16x8.load8x8_s (local.get $0) ) )- (func $201 (param $0 i32) (result v128)+ (func $241 (param $0 i32) (result v128) (i32x4.load16x4_s (local.get $0) ) )- (func $202 (param $0 i32) (result v128)+ (func $242 (param $0 i32) (result v128) (i32x4.load16x4_u (local.get $0) ) )- (func $203 (param $0 i32) (result v128)+ (func $243 (param $0 i32) (result v128) (i64x2.load32x2_s (local.get $0) ) )- (func $204 (param $0 i32) (result v128)+ (func $244 (param $0 i32) (result v128) (i64x2.load32x2_u (local.get $0) ) )- (func $205 (param $0 i32) (result v128)+ (func $245 (param $0 i32) (result v128) (v128.load32_zero (local.get $0) ) )- (func $206 (param $0 i32) (result v128)+ (func $246 (param $0 i32) (result v128) (v128.load64_zero (local.get $0) ) )- (func $207 (param $0 v128) (param $1 v128) (result v128)+ (func $247 (param $0 v128) (param $1 v128) (result v128) (v8x16.swizzle (local.get $0) (local.get $1)+ )+ )+ (func $248 (param $0 i32)+ (prefetch.t offset=3 align=2+ (local.get $0)+ )+ )+ (func $249 (param $0 i32)+ (prefetch.nt offset=3 align=2+ (local.get $0) ) ) )
binaryen/test/spec/old_float_exprs.wast view
@@ -46,8 +46,8 @@ (assert_return (invoke "f32.no_fold_add_zero" (f32.const -0.0)) (f32.const 0.0)) (assert_return (invoke "f64.no_fold_add_zero" (f64.const -0.0)) (f64.const 0.0))-(assert_return (invoke "f32.no_fold_add_zero" (f32.const nan:0x200000)) (f32.const nan:0x600000))-(assert_return (invoke "f64.no_fold_add_zero" (f64.const nan:0x4000000000000)) (f64.const nan:0xc000000000000))+(assert_return (invoke "f32.no_fold_add_zero" (f32.const nan:0x200000)) (f32.const nan:0x400000))+(assert_return (invoke "f64.no_fold_add_zero" (f64.const nan:0x4000000000000)) (f64.const nan:0x8000000000000)) ;; Test that 0.0 - x is not folded to -x. @@ -60,8 +60,8 @@ (assert_return (invoke "f32.no_fold_zero_sub" (f32.const 0.0)) (f32.const 0.0)) (assert_return (invoke "f64.no_fold_zero_sub" (f64.const 0.0)) (f64.const 0.0))-(assert_return (invoke "f32.no_fold_zero_sub" (f32.const nan:0x200000)) (f32.const nan:0x600000))-(assert_return (invoke "f64.no_fold_zero_sub" (f64.const nan:0x4000000000000)) (f64.const nan:0xc000000000000))+(assert_return (invoke "f32.no_fold_zero_sub" (f32.const nan:0x200000)) (f32.const nan:0x400000))+(assert_return (invoke "f64.no_fold_zero_sub" (f64.const nan:0x4000000000000)) (f64.const nan:0x8000000000000)) ;; Test that x - 0.0 is not folded to x. @@ -72,8 +72,8 @@ (f64.sub (local.get $x) (f64.const 0.0))) ) -(assert_return (invoke "f32.no_fold_sub_zero" (f32.const nan:0x200000)) (f32.const nan:0x600000))-(assert_return (invoke "f64.no_fold_sub_zero" (f64.const nan:0x4000000000000)) (f64.const nan:0xc000000000000))+(assert_return (invoke "f32.no_fold_sub_zero" (f32.const nan:0x200000)) (f32.const nan:0x400000))+(assert_return (invoke "f64.no_fold_sub_zero" (f64.const nan:0x4000000000000)) (f64.const nan:0x8000000000000)) ;; Test that x*0.0 is not folded to 0.0. @@ -87,11 +87,11 @@ (assert_return (invoke "f32.no_fold_mul_zero" (f32.const -0.0)) (f32.const -0.0)) (assert_return (invoke "f32.no_fold_mul_zero" (f32.const -1.0)) (f32.const -0.0)) (assert_return (invoke "f32.no_fold_mul_zero" (f32.const -2.0)) (f32.const -0.0))-(assert_return (invoke "f32.no_fold_mul_zero" (f32.const nan:0x200000)) (f32.const nan:0x600000))+(assert_return (invoke "f32.no_fold_mul_zero" (f32.const nan:0x200000)) (f32.const nan:0x400000)) (assert_return (invoke "f64.no_fold_mul_zero" (f64.const -0.0)) (f64.const -0.0)) (assert_return (invoke "f64.no_fold_mul_zero" (f64.const -1.0)) (f64.const -0.0)) (assert_return (invoke "f64.no_fold_mul_zero" (f64.const -2.0)) (f64.const -0.0))-(assert_return (invoke "f64.no_fold_mul_zero" (f64.const nan:0x4000000000000)) (f64.const nan:0xc000000000000))+(assert_return (invoke "f64.no_fold_mul_zero" (f64.const nan:0x4000000000000)) (f64.const nan:0x8000000000000)) ;; Test that x*1.0 is not folded to x. ;; See IEEE 754-2008 10.4 "Literal meaning and value-changing optimizations".@@ -103,8 +103,8 @@ (f64.mul (local.get $x) (f64.const 1.0))) ) -(assert_return (invoke "f32.no_fold_mul_one" (f32.const nan:0x200000)) (f32.const nan:0x600000))-(assert_return (invoke "f64.no_fold_mul_one" (f64.const nan:0x4000000000000)) (f64.const nan:0xc000000000000))+(assert_return (invoke "f32.no_fold_mul_one" (f32.const nan:0x200000)) (f32.const nan:0x400000))+(assert_return (invoke "f64.no_fold_mul_one" (f64.const nan:0x4000000000000)) (f64.const nan:0x8000000000000)) ;; Test that 0.0/x is not folded to 0.0. @@ -118,11 +118,11 @@ (assert_return_nan (invoke "f32.no_fold_zero_div" (f32.const 0.0))) (assert_return_nan (invoke "f32.no_fold_zero_div" (f32.const -0.0))) (assert_return (invoke "f32.no_fold_zero_div" (f32.const nan)) (f32.const nan))-(assert_return (invoke "f32.no_fold_zero_div" (f32.const nan:0x200000)) (f32.const nan:0x600000))+(assert_return (invoke "f32.no_fold_zero_div" (f32.const nan:0x200000)) (f32.const nan:0x400000)) (assert_return_nan (invoke "f64.no_fold_zero_div" (f64.const 0.0))) (assert_return_nan (invoke "f64.no_fold_zero_div" (f64.const -0.0))) (assert_return (invoke "f64.no_fold_zero_div" (f64.const nan)) (f64.const nan))-(assert_return (invoke "f64.no_fold_zero_div" (f64.const nan:0x4000000000000)) (f64.const nan:0xc000000000000))+(assert_return (invoke "f64.no_fold_zero_div" (f64.const nan:0x4000000000000)) (f64.const nan:0x8000000000000)) ;; Test that x/1.0 is not folded to x. @@ -133,8 +133,8 @@ (f64.div (local.get $x) (f64.const 1.0))) ) -(assert_return (invoke "f32.no_fold_div_one" (f32.const nan:0x200000)) (f32.const nan:0x600000))-(assert_return (invoke "f64.no_fold_div_one" (f64.const nan:0x4000000000000)) (f64.const nan:0xc000000000000))+(assert_return (invoke "f32.no_fold_div_one" (f32.const nan:0x200000)) (f32.const nan:0x400000))+(assert_return (invoke "f64.no_fold_div_one" (f64.const nan:0x4000000000000)) (f64.const nan:0x8000000000000)) ;; Test that x/-1.0 is not folded to -x. @@ -145,8 +145,8 @@ (f64.div (local.get $x) (f64.const -1.0))) ) -(assert_return (invoke "f32.no_fold_div_neg1" (f32.const nan:0x200000)) (f32.const nan:0x600000))-(assert_return (invoke "f64.no_fold_div_neg1" (f64.const nan:0x4000000000000)) (f64.const nan:0xc000000000000))+(assert_return (invoke "f32.no_fold_div_neg1" (f32.const nan:0x200000)) (f32.const nan:0x400000))+(assert_return (invoke "f64.no_fold_div_neg1" (f64.const nan:0x4000000000000)) (f64.const nan:0x8000000000000)) ;; Test that -0.0 - x is not folded to -x. @@ -157,8 +157,8 @@ (f64.sub (f64.const -0.0) (local.get $x))) ) -(assert_return (invoke "f32.no_fold_neg0_sub" (f32.const nan:0x200000)) (f32.const nan:0x600000))-(assert_return (invoke "f64.no_fold_neg0_sub" (f64.const nan:0x4000000000000)) (f64.const nan:0xc000000000000))+(assert_return (invoke "f32.no_fold_neg0_sub" (f32.const nan:0x200000)) (f32.const nan:0x400000))+(assert_return (invoke "f64.no_fold_neg0_sub" (f64.const nan:0x4000000000000)) (f64.const nan:0x8000000000000)) ;; Test that -1.0 * x is not folded to -x. @@ -169,8 +169,8 @@ (f64.mul (f64.const -1.0) (local.get $x))) ) -(assert_return (invoke "f32.no_fold_neg1_mul" (f32.const nan:0x200000)) (f32.const nan:0x600000))-(assert_return (invoke "f64.no_fold_neg1_mul" (f64.const nan:0x4000000000000)) (f64.const nan:0xc000000000000))+(assert_return (invoke "f32.no_fold_neg1_mul" (f32.const nan:0x200000)) (f32.const nan:0x400000))+(assert_return (invoke "f64.no_fold_neg1_mul" (f64.const nan:0x4000000000000)) (f64.const nan:0x8000000000000)) ;; Test that x == x is not folded to true. @@ -365,7 +365,7 @@ (assert_return (invoke "f32.no_fold_div_0" (f32.const -infinity)) (f32.const -infinity)) (assert_return_nan (invoke "f32.no_fold_div_0" (f32.const 0))) (assert_return_nan (invoke "f32.no_fold_div_0" (f32.const -0)))-(assert_return (invoke "f32.no_fold_div_0" (f32.const nan:0x200000)) (f32.const nan:0x600000))+(assert_return (invoke "f32.no_fold_div_0" (f32.const nan:0x200000)) (f32.const nan:0x400000)) (assert_return (invoke "f32.no_fold_div_0" (f32.const nan)) (f32.const nan)) (assert_return (invoke "f64.no_fold_div_0" (f64.const 1.0)) (f64.const infinity)) (assert_return (invoke "f64.no_fold_div_0" (f64.const -1.0)) (f64.const -infinity))@@ -374,7 +374,7 @@ (assert_return_nan (invoke "f64.no_fold_div_0" (f64.const 0))) (assert_return_nan (invoke "f64.no_fold_div_0" (f64.const -0))) (assert_return (invoke "f64.no_fold_div_0" (f64.const nan)) (f64.const nan))-(assert_return (invoke "f64.no_fold_div_0" (f64.const nan:0x4000000000000)) (f64.const nan:0xc000000000000))+(assert_return (invoke "f64.no_fold_div_0" (f64.const nan:0x4000000000000)) (f64.const nan:0x8000000000000)) ;; Test that x/-0 is not folded away. @@ -391,7 +391,7 @@ (assert_return (invoke "f32.no_fold_div_neg0" (f32.const -infinity)) (f32.const infinity)) (assert_return_nan (invoke "f32.no_fold_div_neg0" (f32.const 0))) (assert_return_nan (invoke "f32.no_fold_div_neg0" (f32.const -0)))-(assert_return (invoke "f32.no_fold_div_neg0" (f32.const nan:0x200000)) (f32.const nan:0x600000))+(assert_return (invoke "f32.no_fold_div_neg0" (f32.const nan:0x200000)) (f32.const nan:0x400000)) (assert_return (invoke "f32.no_fold_div_neg0" (f32.const nan)) (f32.const nan)) (assert_return (invoke "f64.no_fold_div_neg0" (f64.const 1.0)) (f64.const -infinity)) (assert_return (invoke "f64.no_fold_div_neg0" (f64.const -1.0)) (f64.const infinity))@@ -400,7 +400,7 @@ (assert_return_nan (invoke "f64.no_fold_div_neg0" (f64.const 0))) (assert_return_nan (invoke "f64.no_fold_div_neg0" (f64.const -0))) (assert_return (invoke "f64.no_fold_div_neg0" (f64.const nan)) (f64.const nan))-(assert_return (invoke "f64.no_fold_div_neg0" (f64.const nan:0x4000000000000)) (f64.const nan:0xc000000000000))+(assert_return (invoke "f64.no_fold_div_neg0" (f64.const nan:0x4000000000000)) (f64.const nan:0x8000000000000)) ;; Test that sqrt(x*x+y*y) is not folded to hypot.
binaryen/test/spec/old_import.wast view
@@ -54,11 +54,11 @@ ;; Globals (module- (import "spectest" "global" (global i32))- (global (import "spectest" "global") i32)+ (import "spectest" "global_i32" (global i32))+ (global (import "spectest" "global_i32") i32) - (import "spectest" "global" (global $x i32))- (global $y (import "spectest" "global") i32)+ (import "spectest" "global_i32" (global $x i32))+ (global $y (import "spectest" "global_i32") i32) (func (export "get-0") (result i32) (global.get 0)) (func (export "get-1") (result i32) (global.get 1))@@ -86,9 +86,9 @@ "type mismatch" ) -(module (import "spectest" "global" (global i64)))-(module (import "spectest" "global" (global f32)))-(module (import "spectest" "global" (global f64)))+(module (import "spectest" "global_i64" (global i64)))+(module (import "spectest" "global_i64" (global f32)))+(module (import "spectest" "global_i64" (global f64))) ;; Tables
binaryen/test/spec/simd.wast view
@@ -2,6 +2,7 @@ (memory 1) (data (i32.const 128) "WASMSIMDGOESFAST") (data (i32.const 256) "\80\90\a0\b0\c0\d0\e0\f0")+ (data (i32.const 1024) "\ff\ff\ff\ff\ff\ff\ff\ff") (func (export "v128.load") (param $0 i32) (result v128) (v128.load (local.get $0))) (func (export "v128.store") (param $0 i32) (param $1 v128) (result v128) (v128.store offset=0 align=16 (local.get $0) (local.get $1))@@ -83,6 +84,7 @@ (func (export "i32x4.le_u") (param $0 v128) (param $1 v128) (result v128) (i32x4.le_u (local.get $0) (local.get $1))) (func (export "i32x4.ge_s") (param $0 v128) (param $1 v128) (result v128) (i32x4.ge_s (local.get $0) (local.get $1))) (func (export "i32x4.ge_u") (param $0 v128) (param $1 v128) (result v128) (i32x4.ge_u (local.get $0) (local.get $1)))+ (func (export "i64x2.eq") (param $0 v128) (param $1 v128) (result v128) (i64x2.eq (local.get $0) (local.get $1))) (func (export "f32x4.eq") (param $0 v128) (param $1 v128) (result v128) (f32x4.eq (local.get $0) (local.get $1))) (func (export "f32x4.ne") (param $0 v128) (param $1 v128) (result v128) (f32x4.ne (local.get $0) (local.get $1))) (func (export "f32x4.lt") (param $0 v128) (param $1 v128) (result v128) (f32x4.lt (local.get $0) (local.get $1)))@@ -103,6 +105,27 @@ (func (export "v128.bitselect") (param $0 v128) (param $1 v128) (param $2 v128) (result v128) (v128.bitselect (local.get $0) (local.get $1) (local.get $2)) )+ (func (export "v8x16.signselect") (param $0 v128) (param $1 v128) (param $2 v128) (result v128)+ (v8x16.signselect (local.get $0) (local.get $1) (local.get $2))+ )+ (func (export "v16x8.signselect") (param $0 v128) (param $1 v128) (param $2 v128) (result v128)+ (v16x8.signselect (local.get $0) (local.get $1) (local.get $2))+ )+ (func (export "v32x4.signselect") (param $0 v128) (param $1 v128) (param $2 v128) (result v128)+ (v32x4.signselect (local.get $0) (local.get $1) (local.get $2))+ )+ (func (export "v64x2.signselect") (param $0 v128) (param $1 v128) (param $2 v128) (result v128)+ (v64x2.signselect (local.get $0) (local.get $1) (local.get $2))+ )+ (func (export "v128.load8_lane") (param $0 i32) (param $1 v128) (result v128) (v128.load8_lane 0 (local.get $0) (local.get $1)))+ (func (export "v128.load16_lane") (param $0 i32) (param $1 v128) (result v128) (v128.load16_lane 0 (local.get $0) (local.get $1)))+ (func (export "v128.load32_lane") (param $0 i32) (param $1 v128) (result v128) (v128.load32_lane 0 (local.get $0) (local.get $1)))+ (func (export "v128.load64_lane") (param $0 i32) (param $1 v128) (result v128) (v128.load64_lane 0 (local.get $0) (local.get $1)))+ (func (export "v128.store8_lane") (param $0 i32) (param $1 v128) (v128.store8_lane 0 (local.get $0) (local.get $1)))+ (func (export "v128.store16_lane") (param $0 i32) (param $1 v128) (v128.store16_lane 0 (local.get $0) (local.get $1)))+ (func (export "v128.store32_lane") (param $0 i32) (param $1 v128) (v128.store32_lane 0 (local.get $0) (local.get $1)))+ (func (export "v128.store64_lane") (param $0 i32) (param $1 v128) (v128.store64_lane 0 (local.get $0) (local.get $1)))+ (func (export "i8x16.popcnt") (param $0 v128) (result v128) (i8x16.popcnt (local.get $0))) (func (export "i8x16.abs") (param $0 v128) (result v128) (i8x16.abs (local.get $0))) (func (export "i8x16.neg") (param $0 v128) (result v128) (i8x16.neg (local.get $0))) (func (export "i8x16.any_true") (param $0 v128) (result i32) (i8x16.any_true (local.get $0)))@@ -143,6 +166,8 @@ (func (export "i16x8.max_s") (param $0 v128) (param $1 v128) (result v128) (i16x8.max_s (local.get $0) (local.get $1))) (func (export "i16x8.max_u") (param $0 v128) (param $1 v128) (result v128) (i16x8.max_u (local.get $0) (local.get $1))) (func (export "i16x8.avgr_u") (param $0 v128) (param $1 v128) (result v128) (i16x8.avgr_u (local.get $0) (local.get $1)))+ ;; TODO: Q15 rounding, saturating multiplication+ ;; TODO: extending multiplications (func (export "i32x4.abs") (param $0 v128) (result v128) (i32x4.abs (local.get $0))) (func (export "i32x4.neg") (param $0 v128) (result v128) (i32x4.neg (local.get $0))) (func (export "i32x4.any_true") (param $0 v128) (result i32) (i32x4.any_true (local.get $0)))@@ -160,8 +185,7 @@ (func (export "i32x4.max_u") (param $0 v128) (param $1 v128) (result v128) (i32x4.max_u (local.get $0) (local.get $1))) (func (export "i32x4.dot_i16x8_s") (param $0 v128) (param $1 v128) (result v128) (i32x4.dot_i16x8_s (local.get $0) (local.get $1))) (func (export "i64x2.neg") (param $0 v128) (result v128) (i64x2.neg (local.get $0)))- (func (export "i64x2.any_true") (param $0 v128) (result i32) (i64x2.any_true (local.get $0)))- (func (export "i64x2.all_true") (param $0 v128) (result i32) (i64x2.all_true (local.get $0)))+ (func (export "i64x2.bitmask") (param $0 v128) (result i32) (i64x2.bitmask (local.get $0))) (func (export "i64x2.shl") (param $0 v128) (param $1 i32) (result v128) (i64x2.shl (local.get $0) (local.get $1))) (func (export "i64x2.shr_s") (param $0 v128) (param $1 i32) (result v128) (i64x2.shr_s (local.get $0) (local.get $1))) (func (export "i64x2.shr_u") (param $0 v128) (param $1 i32) (result v128) (i64x2.shr_u (local.get $0) (local.get $1)))@@ -202,6 +226,7 @@ (func (export "f64x2.floor") (param $0 v128) (result v128) (f64x2.floor (local.get $0))) (func (export "f64x2.trunc") (param $0 v128) (result v128) (f64x2.trunc (local.get $0))) (func (export "f64x2.nearest") (param $0 v128) (result v128) (f64x2.nearest (local.get $0)))+ ;; TODO: Extending pairwise adds once they have interpreter support (func (export "i32x4.trunc_sat_f32x4_s") (param $0 v128) (result v128) (i32x4.trunc_sat_f32x4_s (local.get $0))) (func (export "i32x4.trunc_sat_f32x4_u") (param $0 v128) (result v128) (i32x4.trunc_sat_f32x4_u (local.get $0))) (func (export "i64x2.trunc_sat_f64x2_s") (param $0 v128) (result v128) (i64x2.trunc_sat_f64x2_s (local.get $0)))@@ -226,6 +251,10 @@ (func (export "i32x4.widen_high_i16x8_s") (param $0 v128) (result v128) (i32x4.widen_high_i16x8_s (local.get $0))) (func (export "i32x4.widen_low_i16x8_u") (param $0 v128) (result v128) (i32x4.widen_low_i16x8_u (local.get $0))) (func (export "i32x4.widen_high_i16x8_u") (param $0 v128) (result v128) (i32x4.widen_high_i16x8_u (local.get $0)))+ (func (export "i64x2.widen_low_i32x4_s") (param $0 v128) (result v128) (i64x2.widen_low_i32x4_s (local.get $0)))+ (func (export "i64x2.widen_high_i32x4_s") (param $0 v128) (result v128) (i64x2.widen_high_i32x4_s (local.get $0)))+ (func (export "i64x2.widen_low_i32x4_u") (param $0 v128) (result v128) (i64x2.widen_low_i32x4_u (local.get $0)))+ (func (export "i64x2.widen_high_i32x4_u") (param $0 v128) (result v128) (i64x2.widen_high_i32x4_u (local.get $0))) (func (export "i16x8.load8x8_u") (param $0 i32) (result v128) (i16x8.load8x8_u (local.get $0))) (func (export "i16x8.load8x8_s") (param $0 i32) (result v128) (i16x8.load8x8_s (local.get $0))) (func (export "i32x4.load16x4_u") (param $0 i32) (result v128) (i32x4.load16x4_u (local.get $0)))@@ -462,6 +491,9 @@ (assert_return (invoke "i32x4.ge_s" (v128.const i32x4 0 -1 53 -7) (v128.const i32x4 0 53 -7 -1)) (v128.const i32x4 -1 0 -1 0)) (assert_return (invoke "i32x4.ge_u" (v128.const i32x4 0 -1 53 -7) (v128.const i32x4 0 53 -7 -1)) (v128.const i32x4 -1 -1 0 0)) +;; i64x2 comparisons+(assert_return (invoke "i64x2.eq" (v128.const i64x2 0 -1) (v128.const i64x2 -1 -1)) (v128.const i64x2 0 -1))+ ;; f32x4 comparisons (assert_return (invoke "f32x4.eq" (v128.const f32x4 0 -1 1 0) (v128.const f32x4 0 0 -1 1)) (v128.const i32x4 -1 0 0 0)) (assert_return (invoke "f32x4.ne" (v128.const f32x4 0 -1 1 0) (v128.const f32x4 0 0 -1 1)) (v128.const i32x4 0 -1 -1 -1))@@ -509,8 +541,62 @@ ) (v128.const i32x4 0xABABABAB 0xAAAAAAAA 0xBBBBBBBB 0xAABBAABB) )+;; TODO: signselect tests +;; load/store lane+(assert_return (invoke "v128.load8_lane"+ (i32.const 1024)+ (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)+ )+ (v128.const i32x4 0x040302ff 0x08070605 0x0c0b0a09 0x100f0e0d)+)+(assert_return (invoke "v128.load16_lane"+ (i32.const 1024)+ (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)+ )+ (v128.const i32x4 0x0403ffff 0x08070605 0x0c0b0a09 0x100f0e0d)+)+(assert_return (invoke "v128.load32_lane"+ (i32.const 1024)+ (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)+ )+ (v128.const i32x4 0xffffffff 0x08070605 0x0c0b0a09 0x100f0e0d)+)+(assert_return (invoke "v128.load64_lane"+ (i32.const 1024)+ (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)+ )+ (v128.const i32x4 0xffffffff 0xffffffff 0x0c0b0a09 0x100f0e0d)+)+(assert_return (invoke "v128.store8_lane"+ (i32.const 1024)+ (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)+ )+)+(assert_return (invoke "v128.load" (i32.const 1024)) (v128.const i32x4 0xffffff01 0xffffffff 0x00000000 0x00000000))+(assert_return (invoke "v128.store16_lane"+ (i32.const 1024)+ (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)+ )+)+(assert_return (invoke "v128.load" (i32.const 1024)) (v128.const i32x4 0xffff0201 0xffffffff 0x00000000 0x00000000))+(assert_return (invoke "v128.store32_lane"+ (i32.const 1024)+ (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)+ )+)+(assert_return (invoke "v128.load" (i32.const 1024)) (v128.const i32x4 0x04030201 0xffffffff 0x00000000 0x00000000))+(assert_return (invoke "v128.store64_lane"+ (i32.const 1024)+ (v128.const i32x4 0x04030201 0x08070605 0x0c0b0a09 0x100f0e0d)+ )+)+(assert_return (invoke "v128.load" (i32.const 1024)) (v128.const i32x4 0x04030201 0x08070605 0x00000000 0x00000000))+ ;; i8x16 arithmetic+(assert_return (invoke "i8x16.popcnt" (v128.const i8x16 0 1 42 -3 -56 127 -128 -126 0 -1 -42 3 56 -127 -128 126))+ (v128.const i8x16 0 1 3 7 3 7 1 2 0 8 5 2 3 2 1 6)+) (assert_return (invoke "i8x16.abs" (v128.const i8x16 0 1 42 -3 -56 127 -128 -126 0 -1 -42 3 56 -127 -128 126)) (v128.const i8x16 0 1 42 3 56 127 -128 126 0 1 42 3 56 127 -128 126) )@@ -780,12 +866,7 @@ ;; i64x2 arithmetic (assert_return (invoke "i64x2.neg" (v128.const i64x2 0x8000000000000000 42)) (v128.const i64x2 0x8000000000000000 -42))-(assert_return (invoke "i64x2.any_true" (v128.const i64x2 0 0)) (i32.const 0))-(assert_return (invoke "i64x2.any_true" (v128.const i64x2 1 0)) (i32.const 1))-(assert_return (invoke "i64x2.any_true" (v128.const i64x2 1 1)) (i32.const 1))-(assert_return (invoke "i64x2.all_true" (v128.const i64x2 0 0)) (i32.const 0))-(assert_return (invoke "i64x2.all_true" (v128.const i64x2 1 0)) (i32.const 0))-(assert_return (invoke "i64x2.all_true" (v128.const i64x2 1 1)) (i32.const 1))+;; TODO: test i64x2.bitmask (assert_return (invoke "i64x2.shl" (v128.const i64x2 1 0x8000000000000000) (i32.const 1)) (v128.const i64x2 2 0)) (assert_return (invoke "i64x2.shl" (v128.const i64x2 1 0x8000000000000000) (i32.const 64)) (v128.const i64x2 1 0x8000000000000000)) (assert_return (invoke "i64x2.shr_s" (v128.const i64x2 1 0x8000000000000000) (i32.const 1)) (v128.const i64x2 0 0xc000000000000000))@@ -801,10 +882,10 @@ (assert_return (invoke "f32x4.neg" (v128.const f32x4 -0 nan -infinity 5)) (v128.const f32x4 0 -nan infinity -5)) (assert_return (invoke "f32x4.sqrt" (v128.const f32x4 -0 nan infinity 4)) (v128.const f32x4 -0 nan infinity 2)) ;; TODO: qfma/qfms tests-(assert_return (invoke "f32x4.add" (v128.const f32x4 nan -nan infinity 42) (v128.const f32x4 42 infinity infinity 1)) (v128.const f32x4 nan -nan infinity 43))-(assert_return (invoke "f32x4.sub" (v128.const f32x4 nan -nan infinity 42) (v128.const f32x4 42 infinity -infinity 1)) (v128.const f32x4 nan -nan infinity 41))-(assert_return (invoke "f32x4.mul" (v128.const f32x4 nan -nan infinity 42) (v128.const f32x4 42 infinity infinity 2)) (v128.const f32x4 nan -nan infinity 84))-(assert_return (invoke "f32x4.div" (v128.const f32x4 nan -nan infinity 42) (v128.const f32x4 42 infinity 2 2)) (v128.const f32x4 nan -nan infinity 21))+(assert_return (invoke "f32x4.add" (v128.const f32x4 nan -nan infinity 42) (v128.const f32x4 42 infinity infinity 1)) (v128.const f32x4 nan nan infinity 43))+(assert_return (invoke "f32x4.sub" (v128.const f32x4 nan -nan infinity 42) (v128.const f32x4 42 infinity -infinity 1)) (v128.const f32x4 nan nan infinity 41))+(assert_return (invoke "f32x4.mul" (v128.const f32x4 nan -nan infinity 42) (v128.const f32x4 42 infinity infinity 2)) (v128.const f32x4 nan nan infinity 84))+(assert_return (invoke "f32x4.div" (v128.const f32x4 nan -nan infinity 42) (v128.const f32x4 42 infinity 2 2)) (v128.const f32x4 nan nan infinity 21)) (assert_return (invoke "f32x4.min" (v128.const f32x4 -0 0 nan 5) (v128.const f32x4 0 -0 5 nan)) (v128.const f32x4 -0 -0 nan nan)) (assert_return (invoke "f32x4.max" (v128.const f32x4 -0 0 nan 5) (v128.const f32x4 0 -0 5 nan)) (v128.const f32x4 0 0 nan nan)) (assert_return (invoke "f32x4.pmin" (v128.const f32x4 -0 0 nan 5) (v128.const f32x4 0 -0 5 nan)) (v128.const f32x4 -0 0 nan 5))@@ -830,13 +911,13 @@ (assert_return (invoke "f64x2.sqrt" (v128.const f64x2 -0 nan)) (v128.const f64x2 -0 nan)) (assert_return (invoke "f64x2.sqrt" (v128.const f64x2 infinity 4)) (v128.const f64x2 infinity 2)) ;; TODO: qfma/qfms tests-(assert_return (invoke "f64x2.add" (v128.const f64x2 nan -nan) (v128.const f64x2 42 infinity)) (v128.const f64x2 nan -nan))+(assert_return (invoke "f64x2.add" (v128.const f64x2 nan -nan) (v128.const f64x2 42 infinity)) (v128.const f64x2 nan nan)) (assert_return (invoke "f64x2.add" (v128.const f64x2 infinity 42) (v128.const f64x2 infinity 1)) (v128.const f64x2 infinity 43))-(assert_return (invoke "f64x2.sub" (v128.const f64x2 nan -nan) (v128.const f64x2 42 infinity)) (v128.const f64x2 nan -nan))+(assert_return (invoke "f64x2.sub" (v128.const f64x2 nan -nan) (v128.const f64x2 42 infinity)) (v128.const f64x2 nan nan)) (assert_return (invoke "f64x2.sub" (v128.const f64x2 infinity 42) (v128.const f64x2 -infinity 1)) (v128.const f64x2 infinity 41))-(assert_return (invoke "f64x2.mul" (v128.const f64x2 nan -nan) (v128.const f64x2 42 infinity)) (v128.const f64x2 nan -nan))+(assert_return (invoke "f64x2.mul" (v128.const f64x2 nan -nan) (v128.const f64x2 42 infinity)) (v128.const f64x2 nan nan)) (assert_return (invoke "f64x2.mul" (v128.const f64x2 infinity 42) (v128.const f64x2 infinity 2)) (v128.const f64x2 infinity 84))-(assert_return (invoke "f64x2.div" (v128.const f64x2 nan -nan) (v128.const f64x2 42 infinity)) (v128.const f64x2 nan -nan))+(assert_return (invoke "f64x2.div" (v128.const f64x2 nan -nan) (v128.const f64x2 42 infinity)) (v128.const f64x2 nan nan)) (assert_return (invoke "f64x2.div" (v128.const f64x2 infinity 42) (v128.const f64x2 2 2)) (v128.const f64x2 infinity 21)) (assert_return (invoke "f64x2.min" (v128.const f64x2 -0 0) (v128.const f64x2 0 -0)) (v128.const f64x2 -0 -0)) (assert_return (invoke "f64x2.min" (v128.const f64x2 nan 5) (v128.const f64x2 5 nan)) (v128.const f64x2 nan nan))@@ -940,6 +1021,7 @@ (assert_return (invoke "i32x4.widen_high_i16x8_s" (v128.const i16x8 0 1 -1 32768 32767 32769 16384 -16384)) (v128.const i32x4 32767 -32767 16384 -16384)) (assert_return (invoke "i32x4.widen_low_i16x8_u" (v128.const i16x8 0 1 -1 32768 32767 32769 16384 -16384)) (v128.const i32x4 0 1 65535 32768)) (assert_return (invoke "i32x4.widen_high_i16x8_u" (v128.const i16x8 0 1 -1 32768 32767 32769 16384 -16384)) (v128.const i32x4 32767 32769 16384 49152))+;; TODO: test i64x2 widens (assert_return (invoke "i16x8.load8x8_s" (i32.const 256)) (v128.const i16x8 0xff80 0xff90 0xffa0 0xffb0 0xffc0 0xffd0 0xffe0 0xfff0)) (assert_return (invoke "i16x8.load8x8_u" (i32.const 256)) (v128.const i16x8 0x0080 0x0090 0x00a0 0x00b0 0x00c0 0x00d0 0x00e0 0x00f0)) (assert_return (invoke "i32x4.load16x4_s" (i32.const 256)) (v128.const i32x4 0xffff9080 0xffffb0a0 0xffffd0c0 0xfffff0e0))
− binaryen/test/threads.asm.js
@@ -1,147 +0,0 @@-Module["asm"] = (function(global, env, buffer) {- 'use asm';--- var HEAP8 = new global.Int8Array(buffer);- var HEAP16 = new global.Int16Array(buffer);- var HEAP32 = new global.Int32Array(buffer);- var HEAPU8 = new global.Uint8Array(buffer);- var HEAPU16 = new global.Uint16Array(buffer);- var HEAPU32 = new global.Uint32Array(buffer);- var HEAPF32 = new global.Float32Array(buffer);- var HEAPF64 = new global.Float64Array(buffer);-- var DYNAMICTOP_PTR=env.DYNAMICTOP_PTR|0;- var tempDoublePtr=env.tempDoublePtr|0;- var ABORT=env.ABORT|0;- var STACKTOP=env.STACKTOP|0;- var STACK_MAX=env.STACK_MAX|0;-- var __THREW__ = 0;- var threwValue = 0;- var setjmpId = 0;- var undef = 0;- var nan = global.NaN, inf = global.Infinity;- var tempInt = 0, tempBigInt = 0, tempBigIntS = 0, tempValue = 0, tempDouble = 0.0;- var tempRet0 = 0;-- var __pthread_ptr = 0;- var __pthread_is_main_runtime_thread = 0;- var __pthread_is_main_browser_thread = 0;-- var Math_floor=global.Math.floor;- var Math_abs=global.Math.abs;- var Math_sqrt=global.Math.sqrt;- var Math_pow=global.Math.pow;- var Math_cos=global.Math.cos;- var Math_sin=global.Math.sin;- var Math_tan=global.Math.tan;- var Math_acos=global.Math.acos;- var Math_asin=global.Math.asin;- var Math_atan=global.Math.atan;- var Math_atan2=global.Math.atan2;- var Math_exp=global.Math.exp;- var Math_log=global.Math.log;- var Math_ceil=global.Math.ceil;- var Math_imul=global.Math.imul;- var Math_min=global.Math.min;- var Math_max=global.Math.max;- var Math_clz32=global.Math.clz32;- var Math_fround=global.Math.fround;- var abort=env.abort;- var assert=env.assert;- var enlargeMemory=env.enlargeMemory;- var getTotalMemory=env.getTotalMemory;- var abortOnCannotGrowMemory=env.abortOnCannotGrowMemory;- var abortStackOverflow=env.abortStackOverflow;- var nullFunc_iiii=env.nullFunc_iiii;- var nullFunc_i=env.nullFunc_i;- var nullFunc_vi=env.nullFunc_vi;- var nullFunc_vii=env.nullFunc_vii;- var nullFunc_ii=env.nullFunc_ii;- var nullFunc_viii=env.nullFunc_viii;- var nullFunc_v=env.nullFunc_v;- var nullFunc_iii=env.nullFunc_iii;- var invoke_iiii=env.invoke_iiii;- var invoke_i=env.invoke_i;- var invoke_vi=env.invoke_vi;- var invoke_vii=env.invoke_vii;- var invoke_ii=env.invoke_ii;- var invoke_viii=env.invoke_viii;- var invoke_v=env.invoke_v;- var invoke_iii=env.invoke_iii;- var __spawn_thread=env.__spawn_thread;- var _putenv=env._putenv;- var _emscripten_get_now_is_monotonic=env._emscripten_get_now_is_monotonic;- var _fpathconf=env._fpathconf;- var ___unlock=env.___unlock;- var _emscripten_syscall=env._emscripten_syscall;- var ___assert_fail=env.___assert_fail;- var _utimes=env._utimes;- var ___buildEnvironment=env.___buildEnvironment;- var _emscripten_asm_const_i=env._emscripten_asm_const_i;- var _clock_gettime=env._clock_gettime;- var _emscripten_futex_wait=env._emscripten_futex_wait;- var _tzset=env._tzset;- var ___setErrNo=env.___setErrNo;- var _emscripten_set_current_thread_status_js=env._emscripten_set_current_thread_status_js;- var _pthread_getschedparam=env._pthread_getschedparam;- var _clearenv=env._clearenv;- var _emscripten_futex_wake=env._emscripten_futex_wake;- var _sysconf=env._sysconf;- var _utime=env._utime;- var ___call_main=env.___call_main;- var _emscripten_memcpy_big=env._emscripten_memcpy_big;- var _confstr=env._confstr;- var _getenv=env._getenv;- var ___syscall54=env.___syscall54;- var _emscripten_has_threading_support=env._emscripten_has_threading_support;- var _pthread_create=env._pthread_create;- var _emscripten_get_now=env._emscripten_get_now;- var _chroot=env._chroot;- var ___lock=env.___lock;- var ___syscall6=env.___syscall6;- var _unsetenv=env._unsetenv;- var ___clock_gettime=env.___clock_gettime;- var _gettimeofday=env._gettimeofday;- var _atexit=env._atexit;- var ___syscall140=env.___syscall140;- var _emscripten_set_thread_name_js=env._emscripten_set_thread_name_js;- var _setenv=env._setenv;- var ___syscall146=env.___syscall146;- var _emscripten_conditional_set_current_thread_status_js=env._emscripten_conditional_set_current_thread_status_js;- var Atomics_load=global.Atomics.load;- var Atomics_store=global.Atomics.store;- var Atomics_exchange=global.Atomics.exchange;- var Atomics_compareExchange=global.Atomics.compareExchange;- var Atomics_add=global.Atomics.add;- var Atomics_sub=global.Atomics.sub;- var Atomics_and=global.Atomics.and;- var Atomics_or=global.Atomics.or;- var Atomics_xor=global.Atomics.xor;- var tempFloat = Math_fround(0);- const f0 = Math_fround(0);-- function test() {- var $temp = 0;- $temp = (Atomics_load(HEAP32, 1229)|0);- $temp = (Atomics_load(HEAPU16, 1229)|0);- $temp = (Atomics_store(HEAP32, $temp>>2, 0)|0);- $temp = (Atomics_exchange(HEAP32, $temp>>2, 1)|0);- $temp = (Atomics_compareExchange(HEAP32, $temp>>2, 1, 2)|0);- $temp = (Atomics_add(HEAP32, $temp>>2, 0)|0);- $temp = (Atomics_sub(HEAP32, $temp>>2, 0)|0);- $temp = (Atomics_and(HEAP32, $temp>>2, 0)|0);- $temp = (Atomics_or(HEAP32, $temp>>2, 0)|0);- $temp = (Atomics_xor(HEAP32, $temp>>2, 0)|0);- $temp = (Atomics_xor(HEAPU32, 1024, 0)|0);- $temp = (Atomics_xor(HEAP16, 1024, 0)|0);- $temp = (Atomics_xor(HEAPU8, 1024, 0)|0);- // corner cases- $temp = (Atomics_compareExchange(HEAP8, $temp | 0, 1, 2)|0);- $temp = (Atomics_compareExchange(HEAP8, $temp >> 2, 1, 2)|0);- }-- return { test: test };-})-;
− binaryen/test/threads.wasm-only.asm.js
@@ -1,48 +0,0 @@-//-// Test wasm-only builds. In this case, fastcomp emits code that is-// not asm.js, it will only ever run as wasm, and contains special intrinsics for-// asm2wasm that map LLVM IR into i64s.-//--function asm(global, env, buffer) {- "use asm";-- var HEAP8 = new global.Int8Array(buffer);- var HEAP16 = new global.Int16Array(buffer);- var HEAP32 = new global.Int32Array(buffer);- var HEAPU8 = new global.Uint8Array(buffer);- var HEAPU16 = new global.Uint16Array(buffer);- var HEAPU32 = new global.Uint32Array(buffer);- var HEAPF32 = new global.Float32Array(buffer);- var HEAPF64 = new global.Float64Array(buffer);-- var STACKTOP = env.STACKTOP | 0;-- var fround = global.Math.fround;- var Math_imul = global.Math.imul;-- var illegalImport = env.illegalImport;- var illegalImportResult = env.illegalImportResult;-- var _fabsf = env._fabsf;- var do_i64 = env.do_i64;- var abort = env.abort;-- function test64() {- var x = i64(), y = i64(), z = 0; // define i64 variables using special intrinsic- var int32 = 0, float32 = fround(0), float64 = +0;- i64_atomics_store(4656, i64_const(92, 0))|0;- x = i64_atomics_load(4656);- y = i64_atomics_add(int32, i64_const(26, 0))|0;- x = i64_atomics_sub(1024, y)|0;- y = i64_atomics_and(1024, x)|0;- x = i64_atomics_or(1024, y)|0;- y = i64_atomics_xor(1024, x)|0;- x = i64_atomics_exchange(1024, y)|0;- y = i64_atomics_compareExchange(1024, x, y)|0;- return x;- }-- return { test64: test64 };-}-
− binaryen/test/try-body-multiple-insts.wasm
binary file changed (49 → absent bytes)
− binaryen/test/try-body-multiple-insts.wasm.fromBinary
@@ -1,26 +0,0 @@-(module- (type $none_=>_none (func))- (func $0- (nop)- )- (func $1- (nop)- )- (func $2- (local $0 exnref)- (try- (do- (call $0)- (call $1)- )- (catch- (drop- (pop exnref)- )- (call $0)- (call $1)- )- )- )-)-
− binaryen/test/two_sides.asm.js
@@ -1,30 +0,0 @@-Module["asm"] = (function(global, env, buffer) {- "use asm";- var Math_imul = global.Math.imul;- function _test(i1, i2, i3, i4, i5) {- i1 = i1 | 0;- i2 = i2 | 0;- i3 = i3 | 0;- i4 = i4 | 0;- i5 = i5 | 0;- var d6 = 0.0;- if (!i5) {- d6 = +(Math_imul(i4, i3) | 0);- d6 = (+(i3 | 0) + d6) * (+(i4 | 0) + d6);- i5 = ~~d6;- return i5 | 0;- } else {- d6 = +(Math_imul(i2, i1) | 0);- d6 = (+(i3 | 0) + d6) * (d6 + +(i4 | 0));- i5 = ~~d6;- return i5 | 0;- }- return 0;- }- return {- _test: _test- };-});---
+ binaryen/test/typed-function-references.wast view
@@ -0,0 +1,44 @@+(module+ ;; inline ref type in result+ (type $f64_=>_ref_null<_->_eqref> (func (param f64) (result (ref null (func (result eqref))))))+ (type $=>eqref (func (result eqref)))++ (type $i32-i32 (func (param i32) (result i32)))++ (func $call-ref+ (call_ref (ref.func $call-ref))+ )+ (func $return-call-ref+ (return_call_ref (ref.func $call-ref))+ )+ (func $call-ref-more (param i32) (result i32)+ (call_ref (i32.const 42) (ref.func $call-ref-more))+ )+ (func $call_from-param (param $f (ref $i32-i32)) (result i32)+ (call_ref (i32.const 42) (local.get $f))+ )+ (func $call_from-param-null (param $f (ref null $i32-i32)) (result i32)+ (call_ref (i32.const 42) (local.get $f))+ )+ (func $call_from-local-null (result i32)+ (local $f (ref null $i32-i32))+ (local.set $f (ref.func $call-ref-more))+ (call_ref (i32.const 42) (local.get $f))+ )+ (func $ref-in-sig (param $0 f64) (result (ref null (func (result eqref))))+ (ref.null $=>eqref)+ )+ (func $type-only-in-tuple-local+ (local $x (i32 (ref null (func (result anyref))) f64))+ )+ (func $type-only-in-tuple-block+ (drop+ (block (result i32 (ref null (func (result anyref f32 anyref f32))) f64)+ (unreachable)+ )+ )+ )+ (func $nested-type-only-there (result (ref (func (result (ref (func (param i32 i32 i32 i32 i32)))))))+ (unreachable)+ )+)
+ binaryen/test/typed-function-references.wast.from-wast view
@@ -0,0 +1,69 @@+(module+ (type $none_=>_none (func))+ (type $i32_=>_i32 (func (param i32) (result i32)))+ (type $none_=>_eqref (func (result eqref)))+ (type $i32_i32_i32_i32_i32_=>_none (func (param i32 i32 i32 i32 i32)))+ (type $none_=>_i32 (func (result i32)))+ (type $none_=>_anyref (func (result anyref)))+ (type $none_=>_anyref_f32_anyref_f32 (func (result anyref f32 anyref f32)))+ (type $ref?|i32_->_i32|_=>_i32 (func (param (ref null $i32_=>_i32)) (result i32)))+ (type $none_=>_i32_ref?|none_->_anyref_f32_anyref_f32|_f64 (func (result i32 (ref null $none_=>_anyref_f32_anyref_f32) f64)))+ (type $none_=>_ref?|i32_i32_i32_i32_i32_->_none| (func (result (ref null $i32_i32_i32_i32_i32_=>_none))))+ (type $f64_=>_ref?|none_->_eqref| (func (param f64) (result (ref null $none_=>_eqref))))+ (type $none_=>_ref?|none_->_ref?|i32_i32_i32_i32_i32_->_none|| (func (result (ref null $none_=>_ref?|i32_i32_i32_i32_i32_->_none|))))+ (func $call-ref+ (call_ref+ (ref.func $call-ref)+ )+ )+ (func $return-call-ref+ (return_call_ref+ (ref.func $call-ref)+ )+ )+ (func $call-ref-more (param $0 i32) (result i32)+ (call_ref+ (i32.const 42)+ (ref.func $call-ref-more)+ )+ )+ (func $call_from-param (param $f (ref null $i32_=>_i32)) (result i32)+ (call_ref+ (i32.const 42)+ (local.get $f)+ )+ )+ (func $call_from-param-null (param $f (ref null $i32_=>_i32)) (result i32)+ (call_ref+ (i32.const 42)+ (local.get $f)+ )+ )+ (func $call_from-local-null (result i32)+ (local $f (ref null $i32_=>_i32))+ (local.set $f+ (ref.func $call-ref-more)+ )+ (call_ref+ (i32.const 42)+ (local.get $f)+ )+ )+ (func $ref-in-sig (param $0 f64) (result (ref null $none_=>_eqref))+ (ref.null $none_=>_eqref)+ )+ (func $type-only-in-tuple-local+ (local $x (i32 (ref null (func (result anyref))) f64))+ (nop)+ )+ (func $type-only-in-tuple-block+ (drop+ (block $block (result i32 (ref null $none_=>_anyref_f32_anyref_f32) f64)+ (unreachable)+ )+ )+ )+ (func $nested-type-only-there (result (ref null $none_=>_ref?|i32_i32_i32_i32_i32_->_none|))+ (unreachable)+ )+)
+ binaryen/test/typed-function-references.wast.fromBinary view
@@ -0,0 +1,100 @@+(module+ (type $none_=>_none (func))+ (type $none_=>_anyref_f32_anyref_f32 (func (result anyref f32 anyref f32)))+ (type $i32_=>_i32 (func (param i32) (result i32)))+ (type $none_=>_eqref (func (result eqref)))+ (type $i32_i32_i32_i32_i32_=>_none (func (param i32 i32 i32 i32 i32)))+ (type $none_=>_i32 (func (result i32)))+ (type $none_=>_anyref (func (result anyref)))+ (type $ref?|i32_->_i32|_=>_i32 (func (param (ref null $i32_=>_i32)) (result i32)))+ (type $none_=>_i32_ref?|none_->_anyref_f32_anyref_f32|_f64 (func (result i32 (ref null $none_=>_anyref_f32_anyref_f32) f64)))+ (type $none_=>_ref?|i32_i32_i32_i32_i32_->_none| (func (result (ref null $i32_i32_i32_i32_i32_=>_none))))+ (type $f64_=>_ref?|none_->_eqref| (func (param f64) (result (ref null $none_=>_eqref))))+ (type $none_=>_ref?|none_->_ref?|i32_i32_i32_i32_i32_->_none|| (func (result (ref null $none_=>_ref?|i32_i32_i32_i32_i32_->_none|))))+ (func $call-ref+ (call_ref+ (ref.func $call-ref)+ )+ )+ (func $return-call-ref+ (return_call_ref+ (ref.func $call-ref)+ )+ )+ (func $call-ref-more (param $0 i32) (result i32)+ (call_ref+ (i32.const 42)+ (ref.func $call-ref-more)+ )+ )+ (func $call_from-param (param $f (ref null $i32_=>_i32)) (result i32)+ (call_ref+ (i32.const 42)+ (local.get $f)+ )+ )+ (func $call_from-param-null (param $f (ref null $i32_=>_i32)) (result i32)+ (call_ref+ (i32.const 42)+ (local.get $f)+ )+ )+ (func $call_from-local-null (result i32)+ (local $f (ref null $i32_=>_i32))+ (local.set $f+ (ref.func $call-ref-more)+ )+ (call_ref+ (i32.const 42)+ (local.get $f)+ )+ )+ (func $ref-in-sig (param $0 f64) (result (ref null $none_=>_eqref))+ (ref.null $none_=>_eqref)+ )+ (func $type-only-in-tuple-local+ (local $x i32)+ (local $1 f64)+ (local $2 (ref null $none_=>_anyref))+ (nop)+ )+ (func $type-only-in-tuple-block+ (local $0 (i32 (ref null (func (result anyref f32 anyref f32))) f64))+ (local $1 (ref null $none_=>_anyref_f32_anyref_f32))+ (local $2 i32)+ (local.set $0+ (block $label$1 (result i32 (ref null $none_=>_anyref_f32_anyref_f32) f64)+ (unreachable)+ )+ )+ (drop+ (block (result i32)+ (local.set $2+ (tuple.extract 0+ (local.get $0)+ )+ )+ (drop+ (block (result (ref null $none_=>_anyref_f32_anyref_f32))+ (local.set $1+ (tuple.extract 1+ (local.get $0)+ )+ )+ (drop+ (tuple.extract 2+ (local.get $0)+ )+ )+ (local.get $1)+ )+ )+ (local.get $2)+ )+ )+ )+ (func $nested-type-only-there (result (ref null $none_=>_ref?|i32_i32_i32_i32_i32_->_none|))+ (unreachable)+ )+)+
+ binaryen/test/typed-function-references.wast.fromBinary.noDebugInfo view
@@ -0,0 +1,100 @@+(module+ (type $none_=>_none (func))+ (type $none_=>_anyref_f32_anyref_f32 (func (result anyref f32 anyref f32)))+ (type $i32_=>_i32 (func (param i32) (result i32)))+ (type $none_=>_eqref (func (result eqref)))+ (type $i32_i32_i32_i32_i32_=>_none (func (param i32 i32 i32 i32 i32)))+ (type $none_=>_i32 (func (result i32)))+ (type $none_=>_anyref (func (result anyref)))+ (type $ref?|i32_->_i32|_=>_i32 (func (param (ref null $i32_=>_i32)) (result i32)))+ (type $none_=>_i32_ref?|none_->_anyref_f32_anyref_f32|_f64 (func (result i32 (ref null $none_=>_anyref_f32_anyref_f32) f64)))+ (type $none_=>_ref?|i32_i32_i32_i32_i32_->_none| (func (result (ref null $i32_i32_i32_i32_i32_=>_none))))+ (type $f64_=>_ref?|none_->_eqref| (func (param f64) (result (ref null $none_=>_eqref))))+ (type $none_=>_ref?|none_->_ref?|i32_i32_i32_i32_i32_->_none|| (func (result (ref null $none_=>_ref?|i32_i32_i32_i32_i32_->_none|))))+ (func $0+ (call_ref+ (ref.func $0)+ )+ )+ (func $1+ (return_call_ref+ (ref.func $0)+ )+ )+ (func $2 (param $0 i32) (result i32)+ (call_ref+ (i32.const 42)+ (ref.func $2)+ )+ )+ (func $3 (param $0 (ref null $i32_=>_i32)) (result i32)+ (call_ref+ (i32.const 42)+ (local.get $0)+ )+ )+ (func $4 (param $0 (ref null $i32_=>_i32)) (result i32)+ (call_ref+ (i32.const 42)+ (local.get $0)+ )+ )+ (func $5 (result i32)+ (local $0 (ref null $i32_=>_i32))+ (local.set $0+ (ref.func $2)+ )+ (call_ref+ (i32.const 42)+ (local.get $0)+ )+ )+ (func $6 (param $0 f64) (result (ref null $none_=>_eqref))+ (ref.null $none_=>_eqref)+ )+ (func $7+ (local $0 i32)+ (local $1 f64)+ (local $2 (ref null $none_=>_anyref))+ (nop)+ )+ (func $8+ (local $0 (i32 (ref null (func (result anyref f32 anyref f32))) f64))+ (local $1 (ref null $none_=>_anyref_f32_anyref_f32))+ (local $2 i32)+ (local.set $0+ (block $label$1 (result i32 (ref null $none_=>_anyref_f32_anyref_f32) f64)+ (unreachable)+ )+ )+ (drop+ (block (result i32)+ (local.set $2+ (tuple.extract 0+ (local.get $0)+ )+ )+ (drop+ (block (result (ref null $none_=>_anyref_f32_anyref_f32))+ (local.set $1+ (tuple.extract 1+ (local.get $0)+ )+ )+ (drop+ (tuple.extract 2+ (local.get $0)+ )+ )+ (local.get $1)+ )+ )+ (local.get $2)+ )+ )+ )+ (func $9 (result (ref null $none_=>_ref?|i32_i32_i32_i32_i32_->_none|))+ (unreachable)+ )+)+
− binaryen/test/unit.asm.js
@@ -1,811 +0,0 @@-function asm(global, env, buffer) {- "use asm";-- var t = global.NaN, u = global.Infinity;- var Int = 0;- var Double = 0.0;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_ceil = global.Math.ceil;- var Math_max = global.Math.max;- var Math_min = global.Math.min;- var Math_sqrt = global.Math.sqrt;- var tempDoublePtr = env.tempDoublePtr | 0;- var n = env.gb | 0;- var STACKTOP = env.STACKTOP | 0;- var setTempRet0=env.setTempRet0;-- var abort = env.abort;- var print = env.print;- var h = env.h;- var return_int = env.return_int;- var emscripten_log = env.emscripten_log;-- var HEAP8 = new global.Int8Array(buffer);- var HEAP16 = new global.Int16Array(buffer);- var HEAP32 = new global.Int32Array(buffer);- var HEAPU8 = new global.Uint8Array(buffer);- var HEAPU16 = new global.Uint16Array(buffer);- var HEAPU32 = new global.Uint32Array(buffer);- var HEAPF32 = new global.Float32Array(buffer);- var HEAPF64 = new global.Float64Array(buffer);-- var nonZero = 1337;-- function big_negative() {- var temp = 0.0;- temp = +-2147483648;- temp = -2147483648.0;- temp = -21474836480.0;- temp = 0.039625;- temp = -0.039625;- }- function importedDoubles() {- var temp = 0.0;- temp = t + u + (-u) + (-t);- if ((Int | 0) > 0) return -3.4;- if (Double > 0.0) return 5.6;- return 1.2;- }- function doubleCompares(x, y) {- x = +x;- y = +y;- var t = 0.0;- var Int = 0.0, Double = 0; // confusing with globals- if (x > 0.0) return 1.2;- Int = x;- Double = n;- if (Int > 0.0) return -3.4;- if ((Double|0) > 0) return 5.6;- if (x < y) return +x;- return +y;- }- function intOps(x) {- x = x | 0;- return (!x) | 0;- }- function hexLiterals() {- var i = 0;- i = 0x0 + 0x12ABCdef + 0xFEDcba90 | 0;- }- function conversions(i, d, f) {- i = i | 0;- d = +d;- f = Math_fround(f);- i = ~~d;- i = ~~f;- d = +(i | 0);- d = +(i >>> 0);- }- function seq() {- var J = 0.0;- J = (0.1, 5.1) - (3.2, 4.2);- }- function switcher(x) {- x = x | 0;- var waka = 0;- switch (x | 0) {- case 1: return 1;- case 2: return 2;- }- switch (x | 0) {- case 12: return 121;- case 5: return 51;- }- Lout: switch (x | 0) {- case 12: break;- case 10: break Lout;- case 5: {- while (1) {- break;- }- break;- }- case 2: {- while (1) {- break Lout;- }- break;- }- }-- L1 : while (1) {- L3 : while (1) switch (x | 0) {- case -1:- {- break L1;- break;- }- case 116:- {- waka = 1;- break;- }- case 110:- {- break L3;- break;- }- default:- {- break L1;- }- }- h(120);- }-- return 0;- }- function blocker() {- L: {- break L;- }- }- function frem() {- return +(5.5 % 1.2);- }- function frem_float() {- return Math_fround(Math_fround(5.5) % Math_fround(1.2));- }- function big_uint_div_u() {- var x = 0;- x = (4294967295 / 2)&-1;- return x | 0;- }- function trapping_sint_div_s() {- var x = 0;- x = (-2147483648 / -1);- return x | 0;- }- function fr(x) {- x = Math_fround(x);- var y = Math_fround(0), z = 0.0;- Math_fround(z);- Math_fround(y);- Math_fround(5);- Math_fround(0);- Math_fround(5.0);- Math_fround(0.0);- }- function negZero() {- return +-0;- }- function abs() {- var x = 0, y = 0.0, z = Math_fround(0);- x = Math_abs(0) | 0;- y = +Math_abs(0.0);- z = Math_fround(Math_abs(Math_fround(0)));- }- function minmax() {- var x = 0.0, y = 0.0, z = Math_fround(0), w = Math_fround(0);- x = +Math_min(+x, +y);- y = +Math_max(+x, +y);- z = Math_fround(Math_min(Math_fround(z), Math_fround(w)));- w = Math_fround(Math_max(Math_fround(z), Math_fround(w)));- }- function neg() {- var x = Math_fround(0);- x = Math_fround(-x);- FUNCTION_TABLE_c[1 & 7](x);- }- function cneg(x) {- x = Math_fround(x);- FUNCTION_TABLE_c[1 & 7](x);- }- function ___syscall_ret() {- var $0 = 0;- ($0>>>0) > 4294963200; // -4096- }- function smallCompare(i, j) {- i = i | 0;- j = j | 0;- if ((i | 0) < (j | 0)) i = i + 1 | 0;- if ((i >>> 0) < (j >>> 0)) i = i + 1 | 0;- return i | 0;- }- function cneg_nosemicolon() {- FUNCTION_TABLE_vi[1 & 7](1) // no semicolon- }- function forLoop() {- var i = 0;- for (i = 1; (i | 0) < 200; i = i + 1 | 0) {- h(i | 0);- }- }- function ceiling_32_64(u, B) {- u = Math_fround(u);- B = +B;- var temp = Math_fround(0);- temp = Math_fround(Math_ceil(B));- temp = Math_fround(u * Math_fround(Math_ceil(Math_fround(B))));- }- function aborts() {- abort();- abort(55);- abort();- abort(12.34);- abort(+Math_fround(56.78));- }- function continues() {- while (1) {- print(1);- do {- print(5);- if (return_int() | 0) continue;- } while (0);- print(2);- }- }- function bitcasts(i, f) {- i = i | 0;- f = Math_fround(f);- var d = 0.0;- (HEAP32[tempDoublePtr >> 2] = i, Math_fround(HEAPF32[tempDoublePtr >> 2])); // i32->f32- (HEAP32[tempDoublePtr >> 2] = i, +HEAPF32[tempDoublePtr >> 2]); // i32->f32, no fround- (HEAPF32[tempDoublePtr >> 2] = f, HEAP32[tempDoublePtr >> 2] | 0); // f32->i32- (HEAPF32[tempDoublePtr >> 2] = d, HEAP32[tempDoublePtr >> 2] | 0); // f64 with implict f32 conversion, ->i32- }- function recursiveBlockMerging(x) {- x = x | 0;- lb((1, x) + (2, 3) + (((4, 5), 6), 7) + (8, (9, (10, (11, 12)))) | 0) | 0;- x = (lb(1) | 0, x) + (lb(2) | 0, lb(3) | 0) + (((lb(4) | 0, lb(5) | 0), lb(6) | 0), lb(7) | 0) + (lb(8) | 0, (lb(9) | 0, (lb(10) | 0, (lb(11) | 0, lb(12) | 0)))) | 0;- return x | 0;- }-- function lb(a) {- a = a | 0;- HEAP32[a >> 2] = n + 136 + 8;- return 0;- }-- function forgetMe() {- 123.456;- }- function exportMe() {- -3.14159;- }-- function zeroInit(x) {- x = x | 0;- var y = 0; // reusing this with x is dangerous - x has a value, and y needs to start at 0!- if (lb(0) | 0) {- if (lb(1) | 0) y = 3;- } else {- y = 3;- }- if ((y | 0) == 3) {- lb(2) | 0;- }- }-- function phi() {- var x = 0;- do {- if (lb(1) | 0) {- x = 0;- break;- }- x = 1;- } while (0);- return x | 0;- }-- function smallIf() {- do {- if (return_int() | 0) {- lb(3) | 0;- } else {- break;- }- } while (0);- }-- function dropCall() {- if (return_int() | 0) {- phi() | 0; // drop this- setTempRet0(10); // this too- zeroInit(setTempRet0(10) | 0);- }- return phi() | 0;- }-- function useGlobalSet() {- var x = 0;- x = (Int = 10);- Int = 20;- return (Int = 30) | 0;- }-- function usesGlobalSet2() {- return (Int = 40, 50) | 0;- }-- function breakThroughMany($s) {- $s = $s|0;- L1: do {- if ($s) {- while(1) {- if (!($s)) {- break L1;- }- zeroInit(0);- }- } else {- 1337;- }- } while(0);- }-- function ifChainEmpty(label) {- label = label | 0;- if ((label|0) == 4) {- return 0;- }- else if ((label|0) == 7) {- // unreachable;- }- return 0;- }-- function heap8NoShift(x) {- x = x | 0;- return HEAP8[x | 0] | 0;- }-- function conditionalTypeFun() {- var x = 0, y = 0.0;- x = return_int() | 0 ? abort(5) | 0 : 2;- y = return_int() | 0 ? +abort(7) : 4.5;- }-- function loadSigned(x) {- x = x | 0;- loadSigned(HEAP8[x >> 0] << 24 >> 24);- loadSigned(HEAPU8[x >> 0] << 24 >> 24);- loadSigned(HEAP16[x >> 1] << 16 >> 16);- loadSigned(HEAPU16[x >> 1] << 16 >> 16);- loadSigned(HEAP8[x >> 0] << 24 >> 16);- loadSigned(HEAPU8[x >> 0] << 16 >> 24);- loadSigned(HEAP16[x >> 1] << 16 >> 24);- loadSigned(HEAPU16[x >> 1] << 24 >> 16);- }-- function z(x) {- x = Math_fround(x);- }- function w() {- return 0.0;- }-- function globalOpts() {- var x = 0, y = 0.0;- x = Int;- y = Double;- HEAP8[13] = HEAP32[3]; // access memory, should not confuse the global writes- Double = y;- Int = x;- globalOpts();- x = Int;- if (return_int() | 0) Int = 20; // but this does interfere- Int = x;- globalOpts();- x = Int;- globalOpts(); // this too- Int = x;- }-- function dropCallImport() {- if (return_int() | 0) return_int() | 0;- }-- function loophi(x, y) {- x = x | 0;- y = y | 0;- var temp = 0, inc = 0, loopvar = 0; // this order matters- loopvar = x;- while(1) {- loophi(loopvar | 0, 0);- temp = loopvar;- if (temp) {- if (temp) {- break;- }- }- inc = loopvar + 1 | 0;- if ((inc|0) == (y|0)) {- loopvar = inc;- } else {- break;- }- }- }-- function loophi2() {- var jnc = 0, i = 0, i$lcssa = 0, temp = 0, j = 0;- i = 0;- L7: while(1) {- j = 0;- while(1) {- temp = j;- if (return_int() | 0) {- if (temp) {- i$lcssa = i;- break L7;- }- }- jnc = j + 1 | 0;- if (jnc) {- j = jnc;- } else {- break;- }- }- }- return i$lcssa | 0- }-- function loophi2b() {- var jnc = 0, i = 0, i$lcssa = 0, temp = 0, j = 0;- i = 0;- L7: while(1) {- j = 0;- while(1) {- temp = j;- if (return_int() | 0) {- if (temp) {- i$lcssa = j;- break L7;- }- }- jnc = j + 1 | 0;- if (jnc) {- j = jnc;- } else {- break;- }- }- }- return i$lcssa | 0- }-- function relooperJumpThreading(x) {- x = x | 0;- var label = 0;- // from if- if (x) {- h(0);- label = 1;- }- if ((label|0) == 1) {- h(1);- }- h(-1);- // from loop- while (1) {- x = x + 1 | 0;- if (x) {- h(2);- label = 2;- break;- }- }- if ((label|0) == 2) {- h(3);- }- h(-2);- // if-else afterward- if (x) {- h(4);- if ((x|0) == 3) {- label = 3;- } else {- label = 4;- }- }- if ((label|0) == 3) {- h(5);- } else if ((label|0) == 4) {- h(6);- }- h(-3);- // two ifs afterward- if (x) {- h(7);- if ((x|0) == 5) {- label = 5;- } else {- label = 6;- }- }- if ((label|0) == 5) {- h(8);- if ((x|0) == 6) {- label = 6;- }- }- if ((label|0) == 6) {- h(9);- }- h(-4);- // labeled if after- if (x) {- h(10);- label = 7;- }- L1: do {- if ((label|0) == 7) {- h(11);- break L1;- }- } while (0);- h(-5);- // labeled if after normal if- if (x) {- h(12);- if ((x|0) == 8) {- label = 8;- } else {- label = 9;- }- }- if ((label|0) == 8) {- h(13);- if (x) label = 9;- }- L1: do {- if ((label|0) == 9) {- h(14);- break L1;- }- } while (0);- h(-6);- // TODO- // labeled if after a first if- // do-enclosed if after (?)- // test multiple labels, some should be ignored initially by JumpUpdater- return x | 0;- }-- function relooperJumpThreading__ZN4game14preloadweaponsEv($12, $14, $or$cond8, $or$cond6, $vararg_ptr5, $11, $exitcond) {- $12 = $12 | 0;- $14 = $14 | 0;- $or$cond8 = $or$cond8 | 0;- $or$cond6 = $or$cond6 | 0;- $vararg_ptr5 = $vararg_ptr5 | 0;- $11 = $11 | 0;- $exitcond = $exitcond | 0;- var label = 0;- while(1) {- if ($14) {- if ($or$cond8) {- label = 7;- } else {- label = 8;- }- } else {- if ($or$cond6) {- label = 7;- } else {- label = 8;- }- }- if ((label|0) == 7) {- label = 0;- }- else if ((label|0) == 8) {- label = 0;- HEAP32[$vararg_ptr5>>2] = $11;- }- }- }-- function relooperJumpThreading_irreducible(x) {- x = x | 0;- var label = 0;- if ((x|0) == 100) {- label = 1;- } else {- label = 10;- }- if ((label|0) == 1) {- while (1) {- relooperJumpThreading_irreducible(1337);- label = 1; // this is ok - the if means the body of the if begins with the block for 1. so a setting inside the body of the if must return to the top of the if- }- }- // too many settings, we just look one back, so this one will not be optimized- if ((x|0) == 200) {- label = 2;- } else {- label = 10;- }- if ((x|0) == 300) {- label = 2;- }- if ((label|0) == 2) {- relooperJumpThreading_irreducible(1448);- }- if ((label|0) == 10) {- relooperJumpThreading_irreducible(2000);- }- }-- function __Z12multi_varargiz($0, $$06$i4, $exitcond$i6, $2) {- $0 = $0|0;- $$06$i4 = $$06$i4 | 0;- $exitcond$i6 = $exitcond$i6 | 0;- $2 = $2 | 0;- var $12 = 0, $20 = 0;- if ($2) {- while(1) {- $12 = $$06$i4;- if ($exitcond$i6) {- break;- } else {- $$06$i4 = $20;- }- }- } else {- lb(1) | 0; // returns a value, and the while is unreachable- }- }-- function jumpThreadDrop() {- var label = 0, temp = 0;- temp = return_int() | 0;- while (1) {- label = 14;- break;- }- if ((label | 0) == 10) {- } else if ((label | 0) == 12) {- return_int() | 0; // drop in the middle of an if-else chain for threading- } else if ((label | 0) == 14) {- }- return temp | 0;- }-- function dropIgnoredImportInIf($0,$1,$2) {- $0 = $0|0;- $1 = $1|0;- $2 = $2|0;- do {- if ($0) {- $0 = 1;- lb($2 | 0) | 0;- } else {- break;- }- } while(0);- return;- }-- function big_fround() {- return Math_fround(4294967295);- }-- function dropIgnoredImportsInIf($0,$1,$2) {- $0 = $0|0;- $1 = $1|0;- $2 = $2|0;- do {- if ($0) {- lb($1 | 0) | 0;- } else {- lb($2 | 0) | 0;- }- } while(0);- return;- }-- function f32_ucast(x) {- x = x | 0;- return Math_fround(x>>>0);- }- function f32_scast(x) {- x = x | 0;- return Math_fround(x|0);- }-- function store_fround(x) {- x = x | 0;- HEAPF64[10] = Math_fround(x|0);- }-- function relocatableAndModules() {- ftCall_v(10); // function table call- mftCall_v(20); // possible inter-module function table call- return ftCall_idi(30, 1.5, 200) | 0; // with args- }-- function exported_f32_user(x, y, z) {- x = x | 0;- y = Math_fround(y);- z = +z;- return Math_fround(y);- }-- function sqrts(x) {- x = +x;- return +(+Math_sqrt(x) + +Math_fround(Math_sqrt(Math_fround(x))));- }-- function f2u(x) {- x = +x;- return (~~x>>>0) | 0;- }- function f2s(x) {- x = +x;- return (~~x) | 0;- }-- function autoDrop(x) {- x = x | 0;- while (1) {- if ((x | 0) == 17) {- return 5;- autoDrop(1) | 0;- } else {- break;- x = autoDrop(2) | 0;- }- }- return x | 0;- }-- function indirectInSequence() {- var i1 = 0;- // this indirect call should have the right type, vi- i1 = (FUNCTION_TABLE_vi[1 & 7](0), 1);- }-- function emterpretify_assertions_safeHeap() {- var i1 = 0;- // assignment into the function table param, optimizer can do things there- FUNCTION_TABLE_vi[(Int = 1) & 7](i1 | 0);- }-- function call_emscripten_log() {- // emscripten_log has no return value, don't let the conditional after the comma confuse you- emscripten_log(), 2 ? abort() | 0 : 3;- }-- function mod_detectSign(d1, d2, d8) {- d1 = +d1;- d2 = +d2;- d8 = +d8;- return ~~(d2 - d8 % d1 / d1 * d2);- }-- function keepAlive() {- sqrts(3.14159);- sqrts(2.18281); // don't inline it either- f2u(100.0);- f2s(100.0);- autoDrop(52) | 0;- indirectInSequence();- emterpretify_assertions_safeHeap();- call_emscripten_log();- mod_detectSign(1.0, 2.31, 9.78);- nonZero = nonZero + 1 | 0;- }-- function v() {- }- function vi(x) {- x = x | 0;- }- function ii(x) {- x = x | 0;- return x | 0;- }-- var FUNCTION_TABLE_a = [ v, big_negative, v, v ];- var FUNCTION_TABLE_b = [ w, w, importedDoubles, w ];- var FUNCTION_TABLE_c = [ z, cneg, z, z, z, z, z, z ];- var FUNCTION_TABLE_vi = [ vi, vi, vi, vi, vi, vi, vi, vi ];- var FUNCTION_TABLE_ii = [ ii ];-- return { big_negative: big_negative, pick: forgetMe, pick: exportMe, doubleCompares: doubleCompares, intOps: intOps, conversions: conversions, switcher: switcher, frem: frem, frem_float: frem_float, big_uint_div_u: big_uint_div_u, trapping_sint_div_s: trapping_sint_div_s, fr: fr, negZero: negZero, neg: neg, smallCompare: smallCompare, cneg_nosemicolon: cneg_nosemicolon, forLoop: forLoop, ceiling_32_64: ceiling_32_64, aborts: aborts, continues: continues, bitcasts: bitcasts, recursiveBlockMerging: recursiveBlockMerging, lb: lb, zeroInit: zeroInit, phi: phi, smallIf: smallIf, dropCall: dropCall, useGlobalSet: useGlobalSet, usesGlobalSet2: usesGlobalSet2, breakThroughMany: breakThroughMany, ifChainEmpty: ifChainEmpty, heap8NoShift: heap8NoShift, conditionalTypeFun: conditionalTypeFun, loadSigned: loadSigned, globalOpts: globalOpts, dropCallImport: dropCallImport, loophi: loophi, loophi2: loophi2, loophi2b: loophi2b, relooperJumpThreading: relooperJumpThreading, relooperJumpThreading__ZN4game14preloadweaponsEv: relooperJumpThreading__ZN4game14preloadweaponsEv, __Z12multi_varargiz: __Z12multi_varargiz, jumpThreadDrop: jumpThreadDrop, dropIgnoredImportInIf: dropIgnoredImportInIf, dropIgnoredImportsInIf: dropIgnoredImportsInIf, relooperJumpThreading_irreducible: relooperJumpThreading_irreducible, store_fround: store_fround, exportedNumber: 42, relocatableAndModules: relocatableAndModules, exported_f32_user: exported_f32_user, keepAlive: keepAlive };-}-
+ binaryen/test/unit/input/hello_world.wat view
@@ -0,0 +1,11 @@+(module+ (type $i32_i32_=>_i32 (func (param i32 i32) (result i32)))+ (memory $0 256 256)+ (export "add" (func $add))+ (func $add (param $x i32) (param $y i32) (result i32)+ (i32.add+ (local.get $x)+ (local.get $y)+ )+ )+)
+ binaryen/test/unit/input/random_data.txt view
@@ -0,0 +1,1 @@+6sgkjdfghk34589n-947-vn98f2yr-nb8f7t08b7gv*~&!%&^@}{PASD kjgsdf768
− binaryen/test/unit/test_errors.py
@@ -1,40 +0,0 @@-import os--from scripts.test import shared-from . import utils---class ErrorsTest(utils.BinaryenTestCase):- def test_parsing_error_msg(self):- module = '''-(module- (func $foo- (abc)- )-)-'''- p = shared.run_process(shared.WASM_OPT + ['--print', '-o', os.devnull],- input=module, check=False, capture_output=True)- self.assertNotEqual(p.returncode, 0)- self.assertIn("parse exception: abc (at 4:4)", p.stderr)-- def test_validation_error_msg(self):- def test(args=[], extra_expected=None):- module = '''-(module- (memory (shared 10 20))-)-'''- p = shared.run_process(shared.WASM_OPT + ['-o', os.devnull] + args,- input=module, check=False, capture_output=True)- self.assertNotEqual(p.returncode, 0)- self.assertIn('memory is shared, but atomics are disabled', p.stderr)- if extra_expected:- self.assertIn(extra_expected, p.stdout)-- test()- # when the user asks to print the module, we print it even if it is- # invalid, for debugging (otherwise, an invalid module would not reach- # the stage of runnning passes, and print is a pass, so nothing would- # be printed)- test(['--print'], '(module')
binaryen/test/unit/test_features.py view
@@ -153,7 +153,7 @@ ) ) '''- self.check_tail_call(module, 'return_call requires tail calls to be enabled')+ self.check_tail_call(module, 'return_call* requires tail calls to be enabled') def test_tail_call_indirect(self): module = '''@@ -167,7 +167,7 @@ ) ) '''- self.check_tail_call(module, 'return_call_indirect requires tail calls to be enabled')+ self.check_tail_call(module, 'return_call* requires tail calls to be enabled') def test_reference_types_externref(self): module = '''@@ -408,5 +408,6 @@ '--enable-reference-types', '--enable-multivalue', '--enable-gc',- '--enable-memory64'+ '--enable-memory64',+ '--enable-typed-function-references', ], p2.stdout.splitlines())
+ binaryen/test/unit/test_initial_fuzz.py view
@@ -0,0 +1,35 @@+import subprocess+from scripts.test import shared+from . import utils+++class InitialFuzzTest(utils.BinaryenTestCase):+ def test_empty_initial(self):+ # generate fuzz from random data+ data = self.input_path('random_data.txt')+ a = shared.run_process(shared.WASM_OPT + ['-ttf', '--print', data],+ stdout=subprocess.PIPE).stdout++ # generate fuzz from random data with initial empty wasm+ empty_wasm = self.input_path('empty.wasm')+ b = shared.run_process(+ shared.WASM_OPT + ['-ttf', '--print', data,+ '--initial-fuzz=' + empty_wasm],+ stdout=subprocess.PIPE).stdout++ # an empty initial wasm causes no changes+ self.assertEqual(a, b)++ def test_small_initial(self):+ data = self.input_path('random_data.txt')+ hello_wat = self.input_path('hello_world.wat')+ out = shared.run_process(shared.WASM_OPT + ['-ttf', '--print', data,+ '--initial-fuzz=' + hello_wat],+ stdout=subprocess.PIPE).stdout++ # the function should be there (perhaps with modified contents - don't+ # check that)+ self.assertIn('(export "add" (func $add))', out)++ # there should be other fuzz contents added as well+ self.assertGreater(out.count('(export '), 1)
binaryen/test/unit/test_memory_packing.py view
@@ -13,7 +13,7 @@ module = ''' (module (memory 256 256)- (data (i32.const 0) %s)+ (data $d (i32.const 0) %s) ) ''' % data opts = ['--memory-packing', '--disable-bulk-memory', '--print',@@ -21,9 +21,10 @@ p = shared.run_process(shared.WASM_OPT + opts, input=module, check=False, capture_output=True) output = [- '(data (i32.const 999970) "A")',- '(data (i32.const 999980) "A")',- '(data (i32.const 999990) "A' + ('\\00' * 9) + 'A")'+ '(data $d (i32.const 0) "A")',+ '(data $d.1 (i32.const 10) "A")',+ '(data $d.99998 (i32.const 999980) "A")',+ '(data $d.99999 (i32.const 999990) "A' + ('\\00' * 9) + 'A")' ] self.assertEqual(p.returncode, 0) for line in output:
binaryen/test/unit/test_tail_call_type.py view
@@ -21,7 +21,7 @@ input=module, check=False, capture_output=True) self.assertNotEqual(p.returncode, 0) self.assertIn(- 'return_call callee return type must match caller return type',+ 'return_call* callee return type must match caller return type', p.stderr) def test_return_call_indirect(self):@@ -41,5 +41,5 @@ input=module, check=False, capture_output=True) self.assertNotEqual(p.returncode, 0) self.assertIn(- 'return_call_indirect callee return type must match caller return type',+ 'return_call* callee return type must match caller return type', p.stderr)
− binaryen/test/unreachable-import_wasm-only.asm.js
@@ -1,107 +0,0 @@-function asm(global, env, buffer) {- "use asm";-- var HEAP8 = new global.Int8Array(buffer);- var HEAP16 = new global.Int16Array(buffer);- var HEAP32 = new global.Int32Array(buffer);- var HEAPU8 = new global.Uint8Array(buffer);- var HEAPU16 = new global.Uint16Array(buffer);- var HEAPU32 = new global.Uint32Array(buffer);- var HEAPF32 = new global.Float32Array(buffer);- var HEAPF64 = new global.Float64Array(buffer);-- var DYNAMICTOP_PTR=env.DYNAMICTOP_PTR|0;- var tempDoublePtr=env.tempDoublePtr|0;- var ABORT=env.ABORT|0;- var STACKTOP=env.STACKTOP|0;- var STACK_MAX=env.STACK_MAX|0;- var ___async=env.___async|0;- var ___async_unwind=env.___async_unwind|0;- var ___async_retval=env.___async_retval|0;- var ___async_cur_frame=env.___async_cur_frame|0;-- var __THREW__ = 0;- var threwValue = 0;- var setjmpId = 0;- var undef = 0;- var nan = global.NaN, inf = global.Infinity;- var tempInt = 0, tempBigInt = 0, tempBigIntP = 0, tempBigIntS = 0, tempBigIntR = 0.0, tempBigIntI = 0, tempBigIntD = 0, tempValue = 0, tempDouble = 0.0;- var tempRet0 = 0;-- var Math_floor=global.Math.floor;- var Math_abs=global.Math.abs;- var Math_sqrt=global.Math.sqrt;- var Math_pow=global.Math.pow;- var Math_cos=global.Math.cos;- var Math_sin=global.Math.sin;- var Math_tan=global.Math.tan;- var Math_acos=global.Math.acos;- var Math_asin=global.Math.asin;- var Math_atan=global.Math.atan;- var Math_atan2=global.Math.atan2;- var Math_exp=global.Math.exp;- var Math_log=global.Math.log;- var Math_ceil=global.Math.ceil;- var Math_imul=global.Math.imul;- var Math_min=global.Math.min;- var Math_max=global.Math.max;- var Math_clz32=global.Math.clz32;- var Math_fround=global.Math.fround;- var abort=env.abort;- var assert=env.assert;- var enlargeMemory=env.enlargeMemory;- var getTotalMemory=env.getTotalMemory;- var abortOnCannotGrowMemory=env.abortOnCannotGrowMemory;- var invoke_iiii=env.invoke_iiii;- var invoke_viiiii=env.invoke_viiiii;- var invoke_vi=env.invoke_vi;- var invoke_ii=env.invoke_ii;- var invoke_v=env.invoke_v;- var invoke_viiiiii=env.invoke_viiiiii;- var invoke_viiii=env.invoke_viiii;- var _pthread_cleanup_pop=env._pthread_cleanup_pop;- var _pthread_key_create=env._pthread_key_create;- var ___syscall6=env.___syscall6;- var ___gxx_personality_v0=env.___gxx_personality_v0;- var ___assert_fail=env.___assert_fail;- var ___cxa_allocate_exception=env.___cxa_allocate_exception;- var __ZSt18uncaught_exceptionv=env.__ZSt18uncaught_exceptionv;- var ___setErrNo=env.___setErrNo;- var ___cxa_begin_catch=env.___cxa_begin_catch;- var _emscripten_memcpy_big=env._emscripten_memcpy_big;- var ___resumeException=env.___resumeException;- var ___cxa_find_matching_catch=env.___cxa_find_matching_catch;- var _pthread_getspecific=env._pthread_getspecific;- var _pthread_once=env._pthread_once;- var ___syscall54=env.___syscall54;- var ___unlock=env.___unlock;- var _pthread_setspecific=env._pthread_setspecific;- var ___cxa_throw=env.___cxa_throw;- var ___lock=env.___lock;- var _abort=env._abort;- var _pthread_cleanup_push=env._pthread_cleanup_push;- var ___syscall140=env.___syscall140;- var ___cxa_pure_virtual=env.___cxa_pure_virtual;- var ___syscall146=env.___syscall146;- var tempFloat = Math_fround(0);- const f0 = Math_fround(0);--function __ZN10WasmAssertC2Ev__async_cb($0) {- $0 = $0|0;- switch (0) {- case 0: {- store4(12,26);- return;- break;- }- default: {- $0 = (___cxa_allocate_exception(4)|0);- store4($0,1);- ___cxa_throw(($0|0),(1280|0),(0|0));- }- }-}-- return { __ZN10WasmAssertC2Ev__async_cb: __ZN10WasmAssertC2Ev__async_cb };-}-
binaryen/test/unreachable-instr-type.wast view
@@ -19,7 +19,7 @@ (i64.const 1) ) - (i64.atomic.wait+ (memory.atomic.wait64 (unreachable) (i64.const 0) (i64.const 0)
binaryen/test/unreachable-instr-type.wast.from-wast view
@@ -18,7 +18,7 @@ (i64.const 0) (i64.const 1) )- (i64.atomic.wait+ (memory.atomic.wait64 (unreachable) (i64.const 0) (i64.const 0)
− binaryen/test/use-import-and-drop.asm.js
@@ -1,19 +0,0 @@-Module["asm"] = (function(global, env, buffer) {- "use asm";- var setTempRet0=env.setTempRet0;- var Math_imul = global.Math.imul;- function test1() {- var $b$1 = 0, $x_sroa_0_0_extract_trunc = 0, $2 = 0, $1$1 = 0, $1$0 = 0;- // Here we use setTempRet0 as if it returns i32, and later as if no return value.- // We should *not* expand the return type to f64, as this is not an overloaded return value- return (setTempRet0((((Math_imul($b$1, $x_sroa_0_0_extract_trunc) | 0) + $2 | 0) + $1$1 | $1$1 & 0) | 0), 0 | $1$0 & -1) | 0;- }- function test2() {- setTempRet0(10);- }- return {- };-});---
− binaryen/test/wasm-only.asm.js
@@ -1,484 +0,0 @@-//-// Test wasm-only builds. In this case, fastcomp emits code that is-// not asm.js, it will only ever run as wasm, and contains special intrinsics for-// asm2wasm that map LLVM IR into i64s.-//--function asm(global, env, buffer) {- "use asm";-- var HEAP8 = new global.Int8Array(buffer);- var HEAP16 = new global.Int16Array(buffer);- var HEAP32 = new global.Int32Array(buffer);- var HEAPU8 = new global.Uint8Array(buffer);- var HEAPU16 = new global.Uint16Array(buffer);- var HEAPU32 = new global.Uint32Array(buffer);- var HEAPF32 = new global.Float32Array(buffer);- var HEAPF64 = new global.Float64Array(buffer);-- var STACKTOP = env.STACKTOP | 0;-- var fround = global.Math.fround;- var Math_imul = global.Math.imul;-- var illegalImport = env.illegalImport;- var illegalImportResult = env.illegalImportResult;-- var _fabsf = env._fabsf;- var do_i64 = env.do_i64;- var abort = env.abort;-- function loads() {- var i = 0, f = fround(0), d = +0;- i = load1(100);- i = load1(101, 0);- i = load2(102);- i = load2(103, 0);- i = load2(104, 1);- i = load2(105, 2);- i = load4(106);- i = load4(107, 0);- i = load4(108, 1);- i = load4(109, 2);- i = load4(110, 4);- f = loadf(111);- f = loadf(112, 0);- f = loadf(113, 1);- f = loadf(114, 2);- f = loadf(115, 4);- d = loadd(116);- d = loadd(117, 0);- d = loadd(118, 1);- d = loadd(119, 2);- d = loadd(120, 4);- d = loadd(121, 8);- }-- function stores() {- var i = 0, f = fround(0), d = +0;- store1(100, i);- store1(101, i, 0);- store2(102, i);- store2(103, i, 0);- store2(104, i, 1);- store2(105, i, 2);- store4(106, i);- store4(107, i, 0);- store4(108, i, 1);- store4(109, i, 2);- store4(110, i, 4);- storef(111, f);- storef(112, f, 0);- storef(113, f, 1);- storef(114, f, 2);- storef(115, f, 4);- stored(116, d);- stored(117, d, 0);- stored(118, d, 1);- stored(119, d, 2);- stored(120, d, 4);- stored(121, d, 8);- }-- function test() {- var i = 0, j = i64(), f = fround(0), f1 = fround(0), f2 = fround(0), d1 = +0, d2 = +0;- // bitcasts- i = i32_bc2i(f);- f = i32_bc2f(i);- i = i32_cttz(i);- i = i32_ctpop(i);- j = i64_ctpop(j);- f1 = f32_copysign(f1, f2);- d1 = f64_copysign(d1, d2);- }-- function test64() {- var x = i64(), y = i64(), z = 0; // define i64 variables using special intrinsic- var int32 = 0, float32 = fround(0), float64 = +0;- x = i64_const(100, 0); // i64 constant- y = i64_const(17, 30);- x = i64_add(x, y); // binaries- x = i64_sub(x, y);- x = i64_mul(x, y);- x = i64_udiv(x, y);- x = i64_sdiv(x, y);- x = i64_urem(x, y);- x = i64_srem(x, y);- x = i64_and(x, y);- x = i64_or(x, y);- x = i64_xor(x, y);- x = i64_shl(x, y);- x = i64_ashr(x, y);- x = i64_lshr(x, y);- x = load8(120, 0); // load and store- x = load8(120);- x = load8(120, 2);- x = load8(120, 4);- x = load8(120, 8);- store8(120, x, 0);- store8(120, x);- store8(120, x, 2);- store8(120, x, 4);- store8(120, x, 8);- // comps- z = i64_eq(x, y);- z = i64_ne(x, y);- z = i64_ule(x, y);- z = i64_sle(x, y);- z = i64_uge(x, y);- z = i64_sge(x, y);- z = i64_ult(x, y);- z = i64_slt(x, y);- z = i64_ugt(x, y);- z = i64_sgt(x, y);- // convs- int32 = i64_trunc(x);- x = i64_sext(int32);- x = i64_zext(int32);- float32 = i64_s2f(x);- float64 = i64_s2d(x);- float32 = i64_u2f(x);- float64 = i64_u2d(x);- x = i64_f2s(float32);- x = i64_d2s(float64);- x = i64_f2u(float32);- x = i64_d2u(float64);- // bitcasts- x = i64_bc2i(float64);- float64 = i64_bc2d(x);- // intrinsics- x = i64_ctlz(y);- y = i64_cttz(x);- }- function imports() {- illegalImport(-3.13159, i64_const(11, 22), -33); // this call must be legalized- return i64(illegalImportResult());- }- function arg(x) { // illegal param, but not exported- x = i64(x);- store8(100, x, 0);- arg(i64(x)); // "coercion"/"cast"- }- function illegalParam(a, x, c) {- a = 0;- x = i64(x);- b = +0;- store4(50, a, 0);- store8(100, x, 0);- stored(200, b, 0);- illegalParam(0, i64(x), 12.34); // "coercion"/"cast"- }- function result() { // illegal result, but not exported- return i64_const(1, 2);- }- function illegalResult() { // illegal result, exported- return i64_const(1, 2);- }- function call1(x) {- x = i64(x);- var y = i64();- y = i64(call1(x));- return i64(y); // return i64 with a "cast"- }- function call2(x) {- x = i64(x);- i64(call2(i64(call2(x))));- return i64_const(591726473, 57073); // return an i64 const- }- function returnCastConst() {- return i64(0);- }- function ifValue64($4, $6) {- $4 = i64($4);- $6 = i64($6);- var $$0 = i64(), $9 = i64(), $10 = i64();- if ($6) {- $9 = i64(call2($4));- $$0 = $9;- } else {- $10 = i64(call2($4));- $$0 = $10;- }- return i64($$0);- }- function ifValue32($4, $6) {- $4 = $4 | 0;- $6 = $6 | 0;- var $$0 = 0, $9 = 0, $10 = 0;- if ($6) {- $9 = ifValue32($4 | 0, $6 | 0) | 0;- $$0 = $9;- } else {- $10 = ifValue32($4 | 0, $6 | 0) | 0;- $$0 = $10;- }- return $$0 | 0;- }- function switch64($a444) {- $a444 = i64($a444);- var $waka = 0;- switch (i64($a444)) {- case i64_const(7,10): {- $waka = 11000;- break;- }- case i64_const(5,10): {- $waka = 10;- break;- }- default: {- $waka = 1;- }- }- return $waka | 0;- }- function unreachable_leftovers($0,$1,$2) {- $0 = $0|0;- $1 = $1|0;- $2 = $2|0;- var label = 0;- L1: do {- if ($1) {- label = 10;- } else {- if ($2) {- break L1;- return;- }- store4($0,-2);- return;- }- } while(0);- if ((label|0) == 10) {- store4($0,-1);- }- return;- }- function switch64TOOMUCH($a444) {- $a444 = i64($a444);- var $waka = 0;- switch (i64($a444)) {- case i64_const(0,1073741824): // spread is huge here, we should not make a jump table!- case i64_const(0,2147483648): {- return 40;- }- default: {- $waka = 1;- }- }- switch (100) {- case 107374182: // similar, but 32-bit- case 214748364: {- return 41;- }- default: {- $waka = 1001;- }- }- // no defaults- switch (i64($a444)) {- case i64_const(0,1073741824): // spread is huge here, we should not make a jump table!- case i64_const(0,2147483648): {- return 42;- }- }- switch (100) {- case 107374182: // similar, but 32-bit- case 214748364: {- return 43;- }- }- return 44;- }- function _memchr($src,$c,$n) {- $src = $src|0;- $c = $c|0;- $n = $n|0;- var $0 = 0, $1 = 0, $2 = 0, $3 = 0, $4 = 0, $5 = 0, $6 = 0, $7 = 0, $and = 0, $and15 = 0, $and16 = 0, $and39 = 0, $cmp = 0, $cmp11 = 0, $cmp1132 = 0, $cmp28 = 0, $cmp8 = 0, $cond = 0, $conv1 = 0, $dec = 0;- var $dec34 = 0, $incdec$ptr = 0, $incdec$ptr21 = 0, $incdec$ptr33 = 0, $lnot = 0, $mul = 0, $n$addr$0$lcssa = 0, $n$addr$0$lcssa52 = 0, $n$addr$043 = 0, $n$addr$1$lcssa = 0, $n$addr$133 = 0, $n$addr$227 = 0, $n$addr$3 = 0, $neg = 0, $or$cond = 0, $or$cond42 = 0, $s$0$lcssa = 0, $s$0$lcssa53 = 0, $s$044 = 0, $s$128 = 0;- var $s$2 = 0, $sub = 0, $sub22 = 0, $tobool = 0, $tobool2 = 0, $tobool2$lcssa = 0, $tobool241 = 0, $tobool25 = 0, $tobool2526 = 0, $tobool36 = 0, $tobool40 = 0, $w$0$lcssa = 0, $w$034 = 0, $xor = 0, label = 0, sp = 0;- sp = STACKTOP;- $conv1 = $c & 255;- $0 = $src;- $and39 = $0 & 3;- $tobool40 = ($and39|0)!=(0);- $tobool241 = ($n|0)!=(0);- $or$cond42 = $tobool241 & $tobool40;- L1: do {- if ($or$cond42) {- $1 = $c&255;- $n$addr$043 = $n;$s$044 = $src;- while(1) {- $2 = load1($s$044);- $cmp = ($2<<24>>24)==($1<<24>>24);- if ($cmp) {- $n$addr$0$lcssa52 = $n$addr$043;$s$0$lcssa53 = $s$044;- label = 6;- break L1;- }- $incdec$ptr = ((($s$044)) + 1|0);- $dec = (($n$addr$043) + -1)|0;- $3 = $incdec$ptr;- $and = $3 & 3;- $tobool = ($and|0)!=(0);- $tobool2 = ($dec|0)!=(0);- $or$cond = $tobool2 & $tobool;- if ($or$cond) {- $n$addr$043 = $dec;$s$044 = $incdec$ptr;- } else {- $n$addr$0$lcssa = $dec;$s$0$lcssa = $incdec$ptr;$tobool2$lcssa = $tobool2;- label = 5;- break;- }- }- } else {- $n$addr$0$lcssa = $n;$s$0$lcssa = $src;$tobool2$lcssa = $tobool241;- label = 5;- }- } while(0);- if ((label|0) == 5) {- if ($tobool2$lcssa) {- $n$addr$0$lcssa52 = $n$addr$0$lcssa;$s$0$lcssa53 = $s$0$lcssa;- label = 6;- } else {- $n$addr$3 = 0;$s$2 = $s$0$lcssa;- }- }- L8: do {- if ((label|0) == 6) {- $4 = load1($s$0$lcssa53);- $5 = $c&255;- $cmp8 = ($4<<24>>24)==($5<<24>>24);- if ($cmp8) {- $n$addr$3 = $n$addr$0$lcssa52;$s$2 = $s$0$lcssa53;- } else {- $mul = Math_imul($conv1, 16843009)|0;- $cmp1132 = ($n$addr$0$lcssa52>>>0)>(3);- L11: do {- if ($cmp1132) {- $n$addr$133 = $n$addr$0$lcssa52;$w$034 = $s$0$lcssa53;- while(1) {- $6 = load4($w$034);- $xor = $6 ^ $mul;- $sub = (($xor) + -16843009)|0;- $neg = $xor & -2139062144;- $and15 = $neg ^ -2139062144;- $and16 = $and15 & $sub;- $lnot = ($and16|0)==(0);- if (!($lnot)) {- break;- }- $incdec$ptr21 = ((($w$034)) + 4|0);- $sub22 = (($n$addr$133) + -4)|0;- $cmp11 = ($sub22>>>0)>(3);- if ($cmp11) {- $n$addr$133 = $sub22;$w$034 = $incdec$ptr21;- } else {- $n$addr$1$lcssa = $sub22;$w$0$lcssa = $incdec$ptr21;- label = 11;- break L11;- }- }- $n$addr$227 = $n$addr$133;$s$128 = $w$034;- } else {- $n$addr$1$lcssa = $n$addr$0$lcssa52;$w$0$lcssa = $s$0$lcssa53;- label = 11;- }- } while(0);- if ((label|0) == 11) {- $tobool2526 = ($n$addr$1$lcssa|0)==(0);- if ($tobool2526) {- $n$addr$3 = 0;$s$2 = $w$0$lcssa;- break;- } else {- $n$addr$227 = $n$addr$1$lcssa;$s$128 = $w$0$lcssa;- }- }- while(1) {- $7 = load1($s$128);- $cmp28 = ($7<<24>>24)==($5<<24>>24);- if ($cmp28) {- $n$addr$3 = $n$addr$227;$s$2 = $s$128;- break L8;- }- $incdec$ptr33 = ((($s$128)) + 1|0);- $dec34 = (($n$addr$227) + -1)|0;- $tobool25 = ($dec34|0)==(0);- if ($tobool25) {- $n$addr$3 = 0;$s$2 = $incdec$ptr33;- break;- } else {- $n$addr$227 = $dec34;$s$128 = $incdec$ptr33;- }- }- }- }- } while(0);- $tobool36 = ($n$addr$3|0)!=(0);- $cond = $tobool36 ? $s$2 : 0;- return ($cond|0);- }-- function switch64_big_condition1($x) {- $x = i64($x);- switch (i64($x)) {- case i64_const(0,2146435072): {- abort();- break;- }- default: {- return;- }- }- }- function switch64_big_condition2($x) {- $x = i64($x);- switch (i64($x)) {- case i64_const(0,2146435072): {- abort();- break;- }- }- }-- function keepAlive() {- loads();- loads();- stores();- stores();- test();- test();- i64(imports());- i64(imports());- arg(i64(0));- arg(i64(0));- i64(call1(i64(0)));- i64(call1(i64(0)));- i64(call2(i64(0)));- i64(call2(i64(0)));- i64(returnCastConst());- i64(returnCastConst());- i64(ifValue64(i64(0), i64(0)));- i64(ifValue64(i64(0), i64(0)));- ifValue32(0, 0) | 0;- ifValue32(0, 0) | 0;- switch64(i64(0)) | 0;- switch64(i64(0)) | 0;- unreachable_leftovers(0, 0, 0);- unreachable_leftovers(0, 0, 0);- _memchr(0, 0, 0) | 0;- switch64TOOMUCH(i64(0)) | 0;- switch64_big_condition1(i64(0));- switch64_big_condition2(i64(0));- }-- function __emscripten_dceable_type_decls() { // dce-able, but this defines the type of fabsf which has no other use- fround(_fabsf(fround(0.0)));- i64(do_i64());- }-- var FUNCTION_TABLE_X = [illegalImport, _fabsf, do_i64]; // must stay ok in the table, not legalized, as it will be called internally by the true type-- return { test64: test64, illegalParam : illegalParam, illegalResult: illegalResult, keepAlive: keepAlive };-}-
binaryen/test/wasm2js.asserts.js view
@@ -30,19 +30,20 @@ return (actual_lo | 0) == (expected_lo | 0) && (actual_hi | 0) == (expected_hi | 0); } -function asmFunc0(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc0(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function $0() { }@@ -66,20 +67,7 @@ }; } -var retasmFunc0 = asmFunc0({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc0 = asmFunc0( { abort: function() { throw new Error('abort'); } }); function check1() { retasmFunc0.empty();
binaryen/test/wasm2js.traps.js view
@@ -30,19 +30,20 @@ return (actual_lo | 0) == (expected_lo | 0) && (actual_hi | 0) == (expected_hi | 0); } -function asmFunc0(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc0(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function $0() { }@@ -66,20 +67,7 @@ }; } -var retasmFunc0 = asmFunc0({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc0 = asmFunc0( { abort: function() { throw new Error('abort'); } }); function check1() { retasmFunc0.empty();
binaryen/test/wasm2js/add_div.2asm.js view
@@ -1,17 +1,18 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function foo($0) { $0 = $0 | 0; return (($0 >>> 0) / (100 >>> 0) | 0) + (($0 | 0) / (-100 | 0) | 0) | 0 | 0;@@ -22,19 +23,6 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } }); export var foo = retasmFunc.foo;
binaryen/test/wasm2js/add_div.2asm.js.opt view
@@ -1,17 +1,18 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function foo($0) { $0 = $0 | 0; return (($0 | 0) / -100 | 0) + (($0 >>> 0) / 100 | 0) | 0;@@ -22,19 +23,6 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } }); export var foo = retasmFunc.foo;
binaryen/test/wasm2js/atomic_fence.2asm.js view
@@ -1,25 +1,27 @@ -function asmFunc(global, env, buffer) {- var HEAP8 = new global.Int8Array(buffer);- var HEAP16 = new global.Int16Array(buffer);- var HEAP32 = new global.Int32Array(buffer);- var HEAPU8 = new global.Uint8Array(buffer);- var HEAPU16 = new global.Uint16Array(buffer);- var HEAPU32 = new global.Uint32Array(buffer);- var HEAPF32 = new global.Float32Array(buffer);- var HEAPF64 = new global.Float64Array(buffer);- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var buffer = new ArrayBuffer(1507328);+ var HEAP8 = new Int8Array(buffer);+ var HEAP16 = new Int16Array(buffer);+ var HEAP32 = new Int32Array(buffer);+ var HEAPU8 = new Uint8Array(buffer);+ var HEAPU16 = new Uint16Array(buffer);+ var HEAPU32 = new Uint32Array(buffer);+ var HEAPF32 = new Float32Array(buffer);+ var HEAPF64 = new Float64Array(buffer);+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function $0() { }@@ -34,17 +36,16 @@ var newPages = oldPages + pagesToAdd | 0; if ((oldPages < newPages) && (newPages < 65536)) { var newBuffer = new ArrayBuffer(Math_imul(newPages, 65536));- var newHEAP8 = new global.Int8Array(newBuffer);+ var newHEAP8 = new Int8Array(newBuffer); newHEAP8.set(HEAP8);- HEAP8 = newHEAP8;- HEAP8 = new global.Int8Array(newBuffer);- HEAP16 = new global.Int16Array(newBuffer);- HEAP32 = new global.Int32Array(newBuffer);- HEAPU8 = new global.Uint8Array(newBuffer);- HEAPU16 = new global.Uint16Array(newBuffer);- HEAPU32 = new global.Uint32Array(newBuffer);- HEAPF32 = new global.Float32Array(newBuffer);- HEAPF64 = new global.Float64Array(newBuffer);+ HEAP8 = new Int8Array(newBuffer);+ HEAP16 = new Int16Array(newBuffer);+ HEAP32 = new Int32Array(newBuffer);+ HEAPU8 = new Uint8Array(newBuffer);+ HEAPU16 = new Uint16Array(newBuffer);+ HEAPU32 = new Uint32Array(newBuffer);+ HEAPF32 = new Float32Array(newBuffer);+ HEAPF64 = new Float64Array(newBuffer); buffer = newBuffer; } return oldPages;@@ -55,23 +56,6 @@ }; } -var memasmFunc = new ArrayBuffer(1507328);-var bufferView = new Uint8Array(memasmFunc);-var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }- },- memasmFunc-);+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }+ }); export var atomic_fence = retasmFunc.atomic_fence;
binaryen/test/wasm2js/atomic_fence.2asm.js.opt view
@@ -1,17 +1,18 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function $0() { }@@ -21,19 +22,6 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } }); export var atomic_fence = retasmFunc.atomic_fence;
binaryen/test/wasm2js/atomics_32.2asm.js view
@@ -1,4 +1,28 @@ + var bufferView;+ var memorySegments = {};+ var base64ReverseLookup = new Uint8Array(123/*'z'+1*/);+ for (var i = 25; i >= 0; --i) {+ base64ReverseLookup[48+i] = 52+i; // '0-9'+ base64ReverseLookup[65+i] = i; // 'A-Z'+ base64ReverseLookup[97+i] = 26+i; // 'a-z'+ }+ base64ReverseLookup[43] = 62; // '+'+ base64ReverseLookup[47] = 63; // '/'+ /** @noinline Inlining this function would mean expanding the base64 string 4x times in the source code, which Closure seems to be happy to do. */+ function base64DecodeToExistingUint8Array(uint8Array, offset, b64) {+ var b1, b2, i = 0, j = offset, bLength = b64.length, end = offset + (bLength*3>>2) - (b64[bLength-2] == '=') - (b64[bLength-1] == '=');+ for (; i < bLength; i += 4) {+ b1 = base64ReverseLookup[b64.charCodeAt(i+1)];+ b2 = base64ReverseLookup[b64.charCodeAt(i+2)];+ uint8Array[j++] = base64ReverseLookup[b64.charCodeAt(i)] << 2 | b1 >> 4;+ if (j < end) uint8Array[j++] = b1 << 4 | b2 >> 2;+ if (j < end) uint8Array[j++] = b2 << 6 | base64ReverseLookup[b64.charCodeAt(i+3)];+ }+ return uint8Array;+ }+memorySegments[0] = base64DecodeToExistingUint8Array(new Uint8Array(6), 0, "aGVsbG8s");+memorySegments[1] = base64DecodeToExistingUint8Array(new Uint8Array(6), 0, "d29ybGQh"); var scratchBuffer = new ArrayBuffer(16); var i32ScratchView = new Int32Array(scratchBuffer);@@ -65,29 +89,29 @@ bufferView.set(memorySegments[segment].subarray(offset, offset + size), dest); } - var memorySegments = {};- -function asmFunc(global, env, buffer) {- var HEAP8 = new global.Int8Array(buffer);- var HEAP16 = new global.Int16Array(buffer);- var HEAP32 = new global.Int32Array(buffer);- var HEAPU8 = new global.Uint8Array(buffer);- var HEAPU16 = new global.Uint16Array(buffer);- var HEAPU32 = new global.Uint32Array(buffer);- var HEAPF32 = new global.Float32Array(buffer);- var HEAPF64 = new global.Float64Array(buffer);- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var buffer = new ArrayBuffer(16777216);+ var HEAP8 = new Int8Array(buffer);+ var HEAP16 = new Int16Array(buffer);+ var HEAP32 = new Int32Array(buffer);+ var HEAPU8 = new Uint8Array(buffer);+ var HEAPU16 = new Uint16Array(buffer);+ var HEAPU32 = new Uint32Array(buffer);+ var HEAPF32 = new Float32Array(buffer);+ var HEAPF64 = new Float64Array(buffer);+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function $0() { var i64toi32_i32$0 = 0, i64toi32_i32$2 = 0, i64toi32_i32$1 = 0; Atomics.compareExchange(HEAP8, 1024, 1, 2) | 0;@@ -119,6 +143,7 @@ i64toi32_i32$0 = wasm2js_get_stashed_bits() | 0; } + bufferView = HEAPU8; function __wasm_memory_size() { return buffer.byteLength / 65536 | 0; }@@ -128,44 +153,6 @@ }; } -var memasmFunc = new ArrayBuffer(16777216);-var bufferView = new Uint8Array(memasmFunc);-for (var base64ReverseLookup = new Uint8Array(123/*'z'+1*/), i = 25; i >= 0; --i) {- base64ReverseLookup[48+i] = 52+i; // '0-9'- base64ReverseLookup[65+i] = i; // 'A-Z'- base64ReverseLookup[97+i] = 26+i; // 'a-z'- }- base64ReverseLookup[43] = 62; // '+'- base64ReverseLookup[47] = 63; // '/'- /** @noinline Inlining this function would mean expanding the base64 string 4x times in the source code, which Closure seems to be happy to do. */- function base64DecodeToExistingUint8Array(uint8Array, offset, b64) {- var b1, b2, i = 0, j = offset, bLength = b64.length, end = offset + (bLength*3>>2) - (b64[bLength-2] == '=') - (b64[bLength-1] == '=');- for (; i < bLength; i += 4) {- b1 = base64ReverseLookup[b64.charCodeAt(i+1)];- b2 = base64ReverseLookup[b64.charCodeAt(i+2)];- uint8Array[j++] = base64ReverseLookup[b64.charCodeAt(i)] << 2 | b1 >> 4;- if (j < end) uint8Array[j++] = b1 << 4 | b2 >> 2;- if (j < end) uint8Array[j++] = b2 << 6 | base64ReverseLookup[b64.charCodeAt(i+3)];- }- return uint8Array; - }- memorySegments[0] = base64DecodeToExistingUint8Array(new Uint8Array(6), 0, "aGVsbG8s");-memorySegments[1] = base64DecodeToExistingUint8Array(new Uint8Array(6), 0, "d29ybGQh");-var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }- },- memasmFunc-);+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }+ }); export var test = retasmFunc.test;
binaryen/test/wasm2js/atomics_32.2asm.js.opt view
@@ -1,4 +1,28 @@ + var bufferView;+ var memorySegments = {};+ var base64ReverseLookup = new Uint8Array(123/*'z'+1*/);+ for (var i = 25; i >= 0; --i) {+ base64ReverseLookup[48+i] = 52+i; // '0-9'+ base64ReverseLookup[65+i] = i; // 'A-Z'+ base64ReverseLookup[97+i] = 26+i; // 'a-z'+ }+ base64ReverseLookup[43] = 62; // '+'+ base64ReverseLookup[47] = 63; // '/'+ /** @noinline Inlining this function would mean expanding the base64 string 4x times in the source code, which Closure seems to be happy to do. */+ function base64DecodeToExistingUint8Array(uint8Array, offset, b64) {+ var b1, b2, i = 0, j = offset, bLength = b64.length, end = offset + (bLength*3>>2) - (b64[bLength-2] == '=') - (b64[bLength-1] == '=');+ for (; i < bLength; i += 4) {+ b1 = base64ReverseLookup[b64.charCodeAt(i+1)];+ b2 = base64ReverseLookup[b64.charCodeAt(i+2)];+ uint8Array[j++] = base64ReverseLookup[b64.charCodeAt(i)] << 2 | b1 >> 4;+ if (j < end) uint8Array[j++] = b1 << 4 | b2 >> 2;+ if (j < end) uint8Array[j++] = b2 << 6 | base64ReverseLookup[b64.charCodeAt(i+3)];+ }+ return uint8Array;+ }+memorySegments[0] = base64DecodeToExistingUint8Array(new Uint8Array(6), 0, "aGVsbG8s");+memorySegments[1] = base64DecodeToExistingUint8Array(new Uint8Array(6), 0, "d29ybGQh"); var scratchBuffer = new ArrayBuffer(16); var i32ScratchView = new Int32Array(scratchBuffer);@@ -65,29 +89,29 @@ bufferView.set(memorySegments[segment].subarray(offset, offset + size), dest); } - var memorySegments = {};- -function asmFunc(global, env, buffer) {- var HEAP8 = new global.Int8Array(buffer);- var HEAP16 = new global.Int16Array(buffer);- var HEAP32 = new global.Int32Array(buffer);- var HEAPU8 = new global.Uint8Array(buffer);- var HEAPU16 = new global.Uint16Array(buffer);- var HEAPU32 = new global.Uint32Array(buffer);- var HEAPF32 = new global.Float32Array(buffer);- var HEAPF64 = new global.Float64Array(buffer);- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var buffer = new ArrayBuffer(16777216);+ var HEAP8 = new Int8Array(buffer);+ var HEAP16 = new Int16Array(buffer);+ var HEAP32 = new Int32Array(buffer);+ var HEAPU8 = new Uint8Array(buffer);+ var HEAPU16 = new Uint16Array(buffer);+ var HEAPU32 = new Uint32Array(buffer);+ var HEAPF32 = new Float32Array(buffer);+ var HEAPF64 = new Float64Array(buffer);+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function $0() { Atomics.compareExchange(HEAP8, 1024, 1, 2) | 0; Atomics.compareExchange(HEAP16, 512, 1, 2) | 0;@@ -115,6 +139,7 @@ wasm2js_get_stashed_bits() | 0; } + bufferView = HEAPU8; function __wasm_memory_size() { return buffer.byteLength / 65536 | 0; }@@ -124,44 +149,6 @@ }; } -var memasmFunc = new ArrayBuffer(16777216);-var bufferView = new Uint8Array(memasmFunc);-for (var base64ReverseLookup = new Uint8Array(123/*'z'+1*/), i = 25; i >= 0; --i) {- base64ReverseLookup[48+i] = 52+i; // '0-9'- base64ReverseLookup[65+i] = i; // 'A-Z'- base64ReverseLookup[97+i] = 26+i; // 'a-z'- }- base64ReverseLookup[43] = 62; // '+'- base64ReverseLookup[47] = 63; // '/'- /** @noinline Inlining this function would mean expanding the base64 string 4x times in the source code, which Closure seems to be happy to do. */- function base64DecodeToExistingUint8Array(uint8Array, offset, b64) {- var b1, b2, i = 0, j = offset, bLength = b64.length, end = offset + (bLength*3>>2) - (b64[bLength-2] == '=') - (b64[bLength-1] == '=');- for (; i < bLength; i += 4) {- b1 = base64ReverseLookup[b64.charCodeAt(i+1)];- b2 = base64ReverseLookup[b64.charCodeAt(i+2)];- uint8Array[j++] = base64ReverseLookup[b64.charCodeAt(i)] << 2 | b1 >> 4;- if (j < end) uint8Array[j++] = b1 << 4 | b2 >> 2;- if (j < end) uint8Array[j++] = b2 << 6 | base64ReverseLookup[b64.charCodeAt(i+3)];- }- return uint8Array; - }- memorySegments[0] = base64DecodeToExistingUint8Array(new Uint8Array(6), 0, "aGVsbG8s");-memorySegments[1] = base64DecodeToExistingUint8Array(new Uint8Array(6), 0, "d29ybGQh");-var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }- },- memasmFunc-);+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }+ }); export var test = retasmFunc.test;
binaryen/test/wasm2js/atomics_32.wast view
@@ -12,11 +12,11 @@ (local.set $x (i32.atomic.load16_u (i32.const 1028))) (local.set $x (i32.atomic.load (i32.const 1028))) (i32.atomic.store (i32.const 100) (i32.const 200))- (local.set $x (i32.atomic.wait (i32.const 4) (i32.const 8) (i64.const -1)))+ (local.set $x (memory.atomic.wait32 (i32.const 4) (i32.const 8) (i64.const -1))) (memory.init 0 (i32.const 512) (i32.const 0) (i32.const 4)) (memory.init 1 (i32.const 1024) (i32.const 4) (i32.const 2))- (local.set $x (atomic.notify (i32.const 4) (i32.const 2)))- (local.set $x (atomic.notify offset=20 (i32.const 4) (i32.const 2)))+ (local.set $x (memory.atomic.notify (i32.const 4) (i32.const 2)))+ (local.set $x (memory.atomic.notify offset=20 (i32.const 4) (i32.const 2))) (local.set $x (i32.atomic.rmw.add (i32.const 8) (i32.const 12))) (local.set $x (i32.atomic.rmw.sub (i32.const 8) (i32.const 12))) (local.set $x (i32.atomic.rmw.and (i32.const 8) (i32.const 12)))
binaryen/test/wasm2js/base64.2asm.js view
@@ -1,34 +1,22 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; return { }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } });
binaryen/test/wasm2js/base64.2asm.js.opt view
@@ -1,34 +1,22 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; return { }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } });
binaryen/test/wasm2js/br.2asm.js view
@@ -1,18 +1,19 @@ import { setTempRet0 } from 'env'; -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; var setTempRet0 = env.setTempRet0; var i64toi32_i32$HIGH_BITS = 0; function dummy() {@@ -106,8 +107,10 @@ function $13() { var $0 = 0, $1_1 = 0, $3_1 = 0; block : {- $0 = 3;- break block;+ loop_in : while (1) {+ $0 = 3;+ break block;+ }; } return $0 | 0; }@@ -115,9 +118,11 @@ function $14() { var $0 = 0, $1_1 = 0, $3_1 = 0; block : {- dummy();- $0 = 4;- break block;+ loop_in : while (1) {+ dummy();+ $0 = 4;+ break block;+ }; } return $0 | 0; }@@ -125,9 +130,11 @@ function $15() { var $0 = 0; block : {- dummy();- $0 = 5;- break block;+ loop_in : while (1) {+ dummy();+ $0 = 5;+ break block;+ }; } return $0 | 0; }@@ -709,20 +716,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); },+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }, setTempRet0 }); export var type_i32 = retasmFunc.type_i32;
binaryen/test/wasm2js/br_table.2asm.js view
@@ -1,18 +1,19 @@ import { setTempRet0 } from 'env'; -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; var setTempRet0 = env.setTempRet0; var i64toi32_i32$HIGH_BITS = 0; function dummy() {@@ -12560,10 +12561,12 @@ function $20() { var $1_1 = 0, $2_1 = 0, $4_1 = 0; fake_return_waka123 : {- $1_1 = 3;- switch (0 | 0) {- default:- break fake_return_waka123;+ loop_in : while (1) {+ $1_1 = 3;+ switch (0 | 0) {+ default:+ break fake_return_waka123;+ }; }; } return $1_1 | 0;@@ -12572,11 +12575,13 @@ function $21() { var $1_1 = 0, $2_1 = 0, $4_1 = 0; fake_return_waka123 : {- dummy();- $1_1 = 4;- switch (-1 | 0) {- default:- break fake_return_waka123;+ loop_in : while (1) {+ dummy();+ $1_1 = 4;+ switch (-1 | 0) {+ default:+ break fake_return_waka123;+ }; }; } return $1_1 | 0;@@ -12585,11 +12590,13 @@ function $22() { var $1_1 = 0; fake_return_waka123 : {- dummy();- $1_1 = 5;- switch (1 | 0) {- default:- break fake_return_waka123;+ loop_in : while (1) {+ dummy();+ $1_1 = 5;+ switch (1 | 0) {+ default:+ break fake_return_waka123;+ }; }; } return $1_1 | 0;@@ -13414,20 +13421,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); },+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }, setTempRet0 }); export var type_i32 = retasmFunc.type_i32;
binaryen/test/wasm2js/br_table_hoisting.2asm.js view
@@ -1,17 +1,18 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function zed($0) { $0 = $0 | 0; zed($0 | 0);@@ -176,20 +177,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } }); export var foo1 = retasmFunc.foo1; export var foo2 = retasmFunc.foo2;
binaryen/test/wasm2js/br_table_hoisting.2asm.js.opt view
@@ -1,17 +1,18 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function zed($0) { zed($0); }@@ -166,20 +167,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } }); export var foo1 = retasmFunc.foo1; export var foo2 = retasmFunc.foo2;
binaryen/test/wasm2js/br_table_temp.2asm.js view
@@ -1,17 +1,18 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function dummy() { }@@ -12556,10 +12557,12 @@ function $20() { var $1_1 = 0, $2_1 = 0, $4_1 = 0; fake_return_waka123 : {- $1_1 = 3;- switch (0 | 0) {- default:- break fake_return_waka123;+ loop_in : while (1) {+ $1_1 = 3;+ switch (0 | 0) {+ default:+ break fake_return_waka123;+ }; }; } return $1_1 | 0;@@ -12568,11 +12571,13 @@ function $21() { var $1_1 = 0, $2_1 = 0, $4_1 = 0; fake_return_waka123 : {- dummy();- $1_1 = 4;- switch (-1 | 0) {- default:- break fake_return_waka123;+ loop_in : while (1) {+ dummy();+ $1_1 = 4;+ switch (-1 | 0) {+ default:+ break fake_return_waka123;+ }; }; } return $1_1 | 0;@@ -12581,11 +12586,13 @@ function $22() { var $1_1 = 0; fake_return_waka123 : {- dummy();- $1_1 = 5;- switch (1 | 0) {- default:- break fake_return_waka123;+ loop_in : while (1) {+ dummy();+ $1_1 = 5;+ switch (1 | 0) {+ default:+ break fake_return_waka123;+ }; }; } return $1_1 | 0;@@ -13257,20 +13264,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } }); export var type_i32 = retasmFunc.type_i32; export var type_i64 = retasmFunc.type_i64;
binaryen/test/wasm2js/br_table_temp.2asm.js.opt view
@@ -1,17 +1,18 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function dummy() { }@@ -12611,10 +12612,10 @@ function $63($0) { $0 = $0 | 0;- if ($0 - 1 | 0) {- $0 = 9- } else {+ if (($0 | 0) == 1) { $0 = 8+ } else {+ $0 = 9 } return $0 | 0; }@@ -12687,20 +12688,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } }); export var type_i32 = retasmFunc.type_i32; export var type_i64 = retasmFunc.type_i64;
binaryen/test/wasm2js/br_table_to_loop.2asm.js view
@@ -1,17 +1,18 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function $0() { block : { loop : while (1) switch (1 | 0) {@@ -40,20 +41,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } }); export var exp1 = retasmFunc.exp1; export var exp2 = retasmFunc.exp2;
binaryen/test/wasm2js/br_table_to_loop.2asm.js.opt view
@@ -1,17 +1,18 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function $0() { while (1) continue; }@@ -26,20 +27,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } }); export var exp1 = retasmFunc.exp1; export var exp2 = retasmFunc.exp2;
binaryen/test/wasm2js/break-drop.2asm.js view
@@ -1,17 +1,18 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function $0() { }@@ -31,20 +32,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } }); export var br = retasmFunc.br; export var br_if = retasmFunc.br_if;
binaryen/test/wasm2js/bulk-memory.2asm.js view
@@ -1,38 +1,27 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; return { }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } }); + var bufferView; var scratchBuffer = new ArrayBuffer(16); var i32ScratchView = new Int32Array(scratchBuffer);@@ -46,27 +35,29 @@ bufferView.fill(value, dest, dest + size); } -function asmFunc(global, env, buffer) {- var HEAP8 = new global.Int8Array(buffer);- var HEAP16 = new global.Int16Array(buffer);- var HEAP32 = new global.Int32Array(buffer);- var HEAPU8 = new global.Uint8Array(buffer);- var HEAPU16 = new global.Uint16Array(buffer);- var HEAPU32 = new global.Uint32Array(buffer);- var HEAPF32 = new global.Float32Array(buffer);- var HEAPF64 = new global.Float64Array(buffer);- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var buffer = new ArrayBuffer(65536);+ var HEAP8 = new Int8Array(buffer);+ var HEAP16 = new Int16Array(buffer);+ var HEAP32 = new Int32Array(buffer);+ var HEAPU8 = new Uint8Array(buffer);+ var HEAPU16 = new Uint16Array(buffer);+ var HEAPU32 = new Uint32Array(buffer);+ var HEAPF32 = new Float32Array(buffer);+ var HEAPF64 = new Float64Array(buffer);+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function $0($0_1, $1_1, $2) { $0_1 = $0_1 | 0; $1_1 = $1_1 | 0;@@ -79,6 +70,7 @@ return HEAPU8[$0_1 >> 0] | 0 | 0; } + bufferView = HEAPU8; function __wasm_memory_size() { return buffer.byteLength / 65536 | 0; }@@ -89,18 +81,18 @@ var newPages = oldPages + pagesToAdd | 0; if ((oldPages < newPages) && (newPages < 65536)) { var newBuffer = new ArrayBuffer(Math_imul(newPages, 65536));- var newHEAP8 = new global.Int8Array(newBuffer);+ var newHEAP8 = new Int8Array(newBuffer); newHEAP8.set(HEAP8);- HEAP8 = newHEAP8;- HEAP8 = new global.Int8Array(newBuffer);- HEAP16 = new global.Int16Array(newBuffer);- HEAP32 = new global.Int32Array(newBuffer);- HEAPU8 = new global.Uint8Array(newBuffer);- HEAPU16 = new global.Uint16Array(newBuffer);- HEAPU32 = new global.Uint32Array(newBuffer);- HEAPF32 = new global.Float32Array(newBuffer);- HEAPF64 = new global.Float64Array(newBuffer);+ HEAP8 = new Int8Array(newBuffer);+ HEAP16 = new Int16Array(newBuffer);+ HEAP32 = new Int32Array(newBuffer);+ HEAPU8 = new Uint8Array(newBuffer);+ HEAPU16 = new Uint16Array(newBuffer);+ HEAPU32 = new Uint32Array(newBuffer);+ HEAPF32 = new Float32Array(newBuffer);+ HEAPF64 = new Float64Array(newBuffer); buffer = newBuffer;+ bufferView = HEAPU8; } return oldPages; }@@ -111,28 +103,35 @@ }; } -var memasmFunc = new ArrayBuffer(65536);-var bufferView = new Uint8Array(memasmFunc);-var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }- },- memasmFunc-);+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }+ }); export var fill = retasmFunc.fill; export var load8_u = retasmFunc.load8_u; + var bufferView;+ var base64ReverseLookup = new Uint8Array(123/*'z'+1*/);+ for (var i = 25; i >= 0; --i) {+ base64ReverseLookup[48+i] = 52+i; // '0-9'+ base64ReverseLookup[65+i] = i; // 'A-Z'+ base64ReverseLookup[97+i] = 26+i; // 'a-z'+ }+ base64ReverseLookup[43] = 62; // '+'+ base64ReverseLookup[47] = 63; // '/'+ /** @noinline Inlining this function would mean expanding the base64 string 4x times in the source code, which Closure seems to be happy to do. */+ function base64DecodeToExistingUint8Array(uint8Array, offset, b64) {+ var b1, b2, i = 0, j = offset, bLength = b64.length, end = offset + (bLength*3>>2) - (b64[bLength-2] == '=') - (b64[bLength-1] == '=');+ for (; i < bLength; i += 4) {+ b1 = base64ReverseLookup[b64.charCodeAt(i+1)];+ b2 = base64ReverseLookup[b64.charCodeAt(i+2)];+ uint8Array[j++] = base64ReverseLookup[b64.charCodeAt(i)] << 2 | b1 >> 4;+ if (j < end) uint8Array[j++] = b1 << 4 | b2 >> 2;+ if (j < end) uint8Array[j++] = b2 << 6 | base64ReverseLookup[b64.charCodeAt(i+3)];+ }+ return uint8Array;+ }+function initActiveSegments(imports) {+ base64DecodeToExistingUint8Array(bufferView, 0, "qrvM3Q==");+} var scratchBuffer = new ArrayBuffer(16); var i32ScratchView = new Int32Array(scratchBuffer);@@ -144,27 +143,29 @@ bufferView.copyWithin(dest, source, source + size); } -function asmFunc(global, env, buffer) {- var HEAP8 = new global.Int8Array(buffer);- var HEAP16 = new global.Int16Array(buffer);- var HEAP32 = new global.Int32Array(buffer);- var HEAPU8 = new global.Uint8Array(buffer);- var HEAPU16 = new global.Uint16Array(buffer);- var HEAPU32 = new global.Uint32Array(buffer);- var HEAPF32 = new global.Float32Array(buffer);- var HEAPF64 = new global.Float64Array(buffer);- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var buffer = new ArrayBuffer(65536);+ var HEAP8 = new Int8Array(buffer);+ var HEAP16 = new Int16Array(buffer);+ var HEAP32 = new Int32Array(buffer);+ var HEAPU8 = new Uint8Array(buffer);+ var HEAPU16 = new Uint16Array(buffer);+ var HEAPU32 = new Uint32Array(buffer);+ var HEAPF32 = new Float32Array(buffer);+ var HEAPF64 = new Float64Array(buffer);+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function $0($0_1, $1_1, $2) { $0_1 = $0_1 | 0; $1_1 = $1_1 | 0;@@ -177,6 +178,8 @@ return HEAPU8[$0_1 >> 0] | 0 | 0; } + bufferView = HEAPU8;+ initActiveSegments(env); function __wasm_memory_size() { return buffer.byteLength / 65536 | 0; }@@ -187,9 +190,15 @@ }; } -var memasmFunc = new ArrayBuffer(65536);-var bufferView = new Uint8Array(memasmFunc);-for (var base64ReverseLookup = new Uint8Array(123/*'z'+1*/), i = 25; i >= 0; --i) {+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }+ });+export var copy = retasmFunc.copy;+export var load8_u = retasmFunc.load8_u;++ var bufferView;+ var memorySegments = {};+ var base64ReverseLookup = new Uint8Array(123/*'z'+1*/);+ for (var i = 25; i >= 0; --i) { base64ReverseLookup[48+i] = 52+i; // '0-9' base64ReverseLookup[65+i] = i; // 'A-Z' base64ReverseLookup[97+i] = 26+i; // 'a-z'@@ -206,29 +215,9 @@ if (j < end) uint8Array[j++] = b1 << 4 | b2 >> 2; if (j < end) uint8Array[j++] = b2 << 6 | base64ReverseLookup[b64.charCodeAt(i+3)]; }- return uint8Array; + return uint8Array; }- base64DecodeToExistingUint8Array(bufferView, 0, "qrvM3Q==");-var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }- },- memasmFunc-);-export var copy = retasmFunc.copy;-export var load8_u = retasmFunc.load8_u;-+memorySegments[0] = base64DecodeToExistingUint8Array(new Uint8Array(4), 0, "qrvM3Q=="); var scratchBuffer = new ArrayBuffer(16); var i32ScratchView = new Int32Array(scratchBuffer);@@ -240,29 +229,29 @@ bufferView.set(memorySegments[segment].subarray(offset, offset + size), dest); } - var memorySegments = {};- -function asmFunc(global, env, buffer) {- var HEAP8 = new global.Int8Array(buffer);- var HEAP16 = new global.Int16Array(buffer);- var HEAP32 = new global.Int32Array(buffer);- var HEAPU8 = new global.Uint8Array(buffer);- var HEAPU16 = new global.Uint16Array(buffer);- var HEAPU32 = new global.Uint32Array(buffer);- var HEAPF32 = new global.Float32Array(buffer);- var HEAPF64 = new global.Float64Array(buffer);- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var buffer = new ArrayBuffer(65536);+ var HEAP8 = new Int8Array(buffer);+ var HEAP16 = new Int16Array(buffer);+ var HEAP32 = new Int32Array(buffer);+ var HEAPU8 = new Uint8Array(buffer);+ var HEAPU16 = new Uint16Array(buffer);+ var HEAPU32 = new Uint32Array(buffer);+ var HEAPF32 = new Float32Array(buffer);+ var HEAPF64 = new Float64Array(buffer);+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function $0($0_1, $1_1, $2) { $0_1 = $0_1 | 0; $1_1 = $1_1 | 0;@@ -275,6 +264,7 @@ return HEAPU8[$0_1 >> 0] | 0 | 0; } + bufferView = HEAPU8; function __wasm_memory_size() { return buffer.byteLength / 65536 | 0; }@@ -285,18 +275,18 @@ var newPages = oldPages + pagesToAdd | 0; if ((oldPages < newPages) && (newPages < 65536)) { var newBuffer = new ArrayBuffer(Math_imul(newPages, 65536));- var newHEAP8 = new global.Int8Array(newBuffer);+ var newHEAP8 = new Int8Array(newBuffer); newHEAP8.set(HEAP8);- HEAP8 = newHEAP8;- HEAP8 = new global.Int8Array(newBuffer);- HEAP16 = new global.Int16Array(newBuffer);- HEAP32 = new global.Int32Array(newBuffer);- HEAPU8 = new global.Uint8Array(newBuffer);- HEAPU16 = new global.Uint16Array(newBuffer);- HEAPU32 = new global.Uint32Array(newBuffer);- HEAPF32 = new global.Float32Array(newBuffer);- HEAPF64 = new global.Float64Array(newBuffer);+ HEAP8 = new Int8Array(newBuffer);+ HEAP16 = new Int16Array(newBuffer);+ HEAP32 = new Int32Array(newBuffer);+ HEAPU8 = new Uint8Array(newBuffer);+ HEAPU16 = new Uint16Array(newBuffer);+ HEAPU32 = new Uint32Array(newBuffer);+ HEAPF32 = new Float32Array(newBuffer);+ HEAPF64 = new Float64Array(newBuffer); buffer = newBuffer;+ bufferView = HEAPU8; } return oldPages; }@@ -307,9 +297,15 @@ }; } -var memasmFunc = new ArrayBuffer(65536);-var bufferView = new Uint8Array(memasmFunc);-for (var base64ReverseLookup = new Uint8Array(123/*'z'+1*/), i = 25; i >= 0; --i) {+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }+ });+export var init = retasmFunc.init;+export var load8_u = retasmFunc.load8_u;++ var bufferView;+ var memorySegments = {};+ var base64ReverseLookup = new Uint8Array(123/*'z'+1*/);+ for (var i = 25; i >= 0; --i) { base64ReverseLookup[48+i] = 52+i; // '0-9' base64ReverseLookup[65+i] = i; // 'A-Z' base64ReverseLookup[97+i] = 26+i; // 'a-z'@@ -326,29 +322,12 @@ if (j < end) uint8Array[j++] = b1 << 4 | b2 >> 2; if (j < end) uint8Array[j++] = b2 << 6 | base64ReverseLookup[b64.charCodeAt(i+3)]; }- return uint8Array; + return uint8Array; }- memorySegments[0] = base64DecodeToExistingUint8Array(new Uint8Array(4), 0, "qrvM3Q==");-var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }- },- memasmFunc-);-export var init = retasmFunc.init;-export var load8_u = retasmFunc.load8_u;-+memorySegments[0] = base64DecodeToExistingUint8Array(new Uint8Array(0), 0, "");+function initActiveSegments(imports) {+ base64DecodeToExistingUint8Array(bufferView, 0, "");+} var scratchBuffer = new ArrayBuffer(16); var i32ScratchView = new Int32Array(scratchBuffer);@@ -365,29 +344,29 @@ bufferView.set(memorySegments[segment].subarray(offset, offset + size), dest); } - var memorySegments = {};- -function asmFunc(global, env, buffer) {- var HEAP8 = new global.Int8Array(buffer);- var HEAP16 = new global.Int16Array(buffer);- var HEAP32 = new global.Int32Array(buffer);- var HEAPU8 = new global.Uint8Array(buffer);- var HEAPU16 = new global.Uint16Array(buffer);- var HEAPU32 = new global.Uint32Array(buffer);- var HEAPF32 = new global.Float32Array(buffer);- var HEAPF64 = new global.Float64Array(buffer);- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var buffer = new ArrayBuffer(65536);+ var HEAP8 = new Int8Array(buffer);+ var HEAP16 = new Int16Array(buffer);+ var HEAP32 = new Int32Array(buffer);+ var HEAPU8 = new Uint8Array(buffer);+ var HEAPU16 = new Uint16Array(buffer);+ var HEAPU32 = new Uint32Array(buffer);+ var HEAPF32 = new Float32Array(buffer);+ var HEAPF64 = new Float64Array(buffer);+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function $0() { wasm2js_data_drop(0); }@@ -404,6 +383,8 @@ wasm2js_memory_init(1, 0, 0, 0); } + bufferView = HEAPU8;+ initActiveSegments(env); function __wasm_memory_size() { return buffer.byteLength / 65536 | 0; }@@ -414,18 +395,18 @@ var newPages = oldPages + pagesToAdd | 0; if ((oldPages < newPages) && (newPages < 65536)) { var newBuffer = new ArrayBuffer(Math_imul(newPages, 65536));- var newHEAP8 = new global.Int8Array(newBuffer);+ var newHEAP8 = new Int8Array(newBuffer); newHEAP8.set(HEAP8);- HEAP8 = newHEAP8;- HEAP8 = new global.Int8Array(newBuffer);- HEAP16 = new global.Int16Array(newBuffer);- HEAP32 = new global.Int32Array(newBuffer);- HEAPU8 = new global.Uint8Array(newBuffer);- HEAPU16 = new global.Uint16Array(newBuffer);- HEAPU32 = new global.Uint32Array(newBuffer);- HEAPF32 = new global.Float32Array(newBuffer);- HEAPF64 = new global.Float64Array(newBuffer);+ HEAP8 = new Int8Array(newBuffer);+ HEAP16 = new Int16Array(newBuffer);+ HEAP32 = new Int32Array(newBuffer);+ HEAPU8 = new Uint8Array(newBuffer);+ HEAPU16 = new Uint16Array(newBuffer);+ HEAPU32 = new Uint32Array(newBuffer);+ HEAPF32 = new Float32Array(newBuffer);+ HEAPF64 = new Float64Array(newBuffer); buffer = newBuffer;+ bufferView = HEAPU8; } return oldPages; }@@ -438,46 +419,8 @@ }; } -var memasmFunc = new ArrayBuffer(65536);-var bufferView = new Uint8Array(memasmFunc);-for (var base64ReverseLookup = new Uint8Array(123/*'z'+1*/), i = 25; i >= 0; --i) {- base64ReverseLookup[48+i] = 52+i; // '0-9'- base64ReverseLookup[65+i] = i; // 'A-Z'- base64ReverseLookup[97+i] = 26+i; // 'a-z'- }- base64ReverseLookup[43] = 62; // '+'- base64ReverseLookup[47] = 63; // '/'- /** @noinline Inlining this function would mean expanding the base64 string 4x times in the source code, which Closure seems to be happy to do. */- function base64DecodeToExistingUint8Array(uint8Array, offset, b64) {- var b1, b2, i = 0, j = offset, bLength = b64.length, end = offset + (bLength*3>>2) - (b64[bLength-2] == '=') - (b64[bLength-1] == '=');- for (; i < bLength; i += 4) {- b1 = base64ReverseLookup[b64.charCodeAt(i+1)];- b2 = base64ReverseLookup[b64.charCodeAt(i+2)];- uint8Array[j++] = base64ReverseLookup[b64.charCodeAt(i)] << 2 | b1 >> 4;- if (j < end) uint8Array[j++] = b1 << 4 | b2 >> 2;- if (j < end) uint8Array[j++] = b2 << 6 | base64ReverseLookup[b64.charCodeAt(i+3)];- }- return uint8Array; - }- memorySegments[0] = base64DecodeToExistingUint8Array(new Uint8Array(0), 0, "");-base64DecodeToExistingUint8Array(bufferView, 0, "");-var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }- },- memasmFunc-);+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }+ }); export var drop_passive = retasmFunc.drop_passive; export var init_passive = retasmFunc.init_passive; export var drop_active = retasmFunc.drop_active;
binaryen/test/wasm2js/bulk-memory.2asm.js.opt view
@@ -1,38 +1,27 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; return { }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } }); + var bufferView; var scratchBuffer = new ArrayBuffer(16); var i32ScratchView = new Int32Array(scratchBuffer);@@ -46,27 +35,29 @@ bufferView.fill(value, dest, dest + size); } -function asmFunc(global, env, buffer) {- var HEAP8 = new global.Int8Array(buffer);- var HEAP16 = new global.Int16Array(buffer);- var HEAP32 = new global.Int32Array(buffer);- var HEAPU8 = new global.Uint8Array(buffer);- var HEAPU16 = new global.Uint16Array(buffer);- var HEAPU32 = new global.Uint32Array(buffer);- var HEAPF32 = new global.Float32Array(buffer);- var HEAPF64 = new global.Float64Array(buffer);- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var buffer = new ArrayBuffer(65536);+ var HEAP8 = new Int8Array(buffer);+ var HEAP16 = new Int16Array(buffer);+ var HEAP32 = new Int32Array(buffer);+ var HEAPU8 = new Uint8Array(buffer);+ var HEAPU16 = new Uint16Array(buffer);+ var HEAPU32 = new Uint32Array(buffer);+ var HEAPF32 = new Float32Array(buffer);+ var HEAPF64 = new Float64Array(buffer);+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function $0($0_1, $1_1, $2) { $0_1 = $0_1 | 0; $1_1 = $1_1 | 0;@@ -79,6 +70,7 @@ return HEAPU8[$0_1 | 0]; } + bufferView = HEAPU8; function __wasm_memory_size() { return buffer.byteLength / 65536 | 0; }@@ -89,18 +81,18 @@ var newPages = oldPages + pagesToAdd | 0; if ((oldPages < newPages) && (newPages < 65536)) { var newBuffer = new ArrayBuffer(Math_imul(newPages, 65536));- var newHEAP8 = new global.Int8Array(newBuffer);+ var newHEAP8 = new Int8Array(newBuffer); newHEAP8.set(HEAP8);- HEAP8 = newHEAP8;- HEAP8 = new global.Int8Array(newBuffer);- HEAP16 = new global.Int16Array(newBuffer);- HEAP32 = new global.Int32Array(newBuffer);- HEAPU8 = new global.Uint8Array(newBuffer);- HEAPU16 = new global.Uint16Array(newBuffer);- HEAPU32 = new global.Uint32Array(newBuffer);- HEAPF32 = new global.Float32Array(newBuffer);- HEAPF64 = new global.Float64Array(newBuffer);+ HEAP8 = new Int8Array(newBuffer);+ HEAP16 = new Int16Array(newBuffer);+ HEAP32 = new Int32Array(newBuffer);+ HEAPU8 = new Uint8Array(newBuffer);+ HEAPU16 = new Uint16Array(newBuffer);+ HEAPU32 = new Uint32Array(newBuffer);+ HEAPF32 = new Float32Array(newBuffer);+ HEAPF64 = new Float64Array(newBuffer); buffer = newBuffer;+ bufferView = HEAPU8; } return oldPages; }@@ -111,28 +103,35 @@ }; } -var memasmFunc = new ArrayBuffer(65536);-var bufferView = new Uint8Array(memasmFunc);-var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }- },- memasmFunc-);+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }+ }); export var fill = retasmFunc.fill; export var load8_u = retasmFunc.load8_u; + var bufferView;+ var base64ReverseLookup = new Uint8Array(123/*'z'+1*/);+ for (var i = 25; i >= 0; --i) {+ base64ReverseLookup[48+i] = 52+i; // '0-9'+ base64ReverseLookup[65+i] = i; // 'A-Z'+ base64ReverseLookup[97+i] = 26+i; // 'a-z'+ }+ base64ReverseLookup[43] = 62; // '+'+ base64ReverseLookup[47] = 63; // '/'+ /** @noinline Inlining this function would mean expanding the base64 string 4x times in the source code, which Closure seems to be happy to do. */+ function base64DecodeToExistingUint8Array(uint8Array, offset, b64) {+ var b1, b2, i = 0, j = offset, bLength = b64.length, end = offset + (bLength*3>>2) - (b64[bLength-2] == '=') - (b64[bLength-1] == '=');+ for (; i < bLength; i += 4) {+ b1 = base64ReverseLookup[b64.charCodeAt(i+1)];+ b2 = base64ReverseLookup[b64.charCodeAt(i+2)];+ uint8Array[j++] = base64ReverseLookup[b64.charCodeAt(i)] << 2 | b1 >> 4;+ if (j < end) uint8Array[j++] = b1 << 4 | b2 >> 2;+ if (j < end) uint8Array[j++] = b2 << 6 | base64ReverseLookup[b64.charCodeAt(i+3)];+ }+ return uint8Array;+ }+function initActiveSegments(imports) {+ base64DecodeToExistingUint8Array(bufferView, 0, "qrvM3Q==");+} var scratchBuffer = new ArrayBuffer(16); var i32ScratchView = new Int32Array(scratchBuffer);@@ -144,27 +143,29 @@ bufferView.copyWithin(dest, source, source + size); } -function asmFunc(global, env, buffer) {- var HEAP8 = new global.Int8Array(buffer);- var HEAP16 = new global.Int16Array(buffer);- var HEAP32 = new global.Int32Array(buffer);- var HEAPU8 = new global.Uint8Array(buffer);- var HEAPU16 = new global.Uint16Array(buffer);- var HEAPU32 = new global.Uint32Array(buffer);- var HEAPF32 = new global.Float32Array(buffer);- var HEAPF64 = new global.Float64Array(buffer);- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var buffer = new ArrayBuffer(65536);+ var HEAP8 = new Int8Array(buffer);+ var HEAP16 = new Int16Array(buffer);+ var HEAP32 = new Int32Array(buffer);+ var HEAPU8 = new Uint8Array(buffer);+ var HEAPU16 = new Uint16Array(buffer);+ var HEAPU32 = new Uint32Array(buffer);+ var HEAPF32 = new Float32Array(buffer);+ var HEAPF64 = new Float64Array(buffer);+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function $0($0_1, $1_1, $2) { $0_1 = $0_1 | 0; $1_1 = $1_1 | 0;@@ -177,6 +178,8 @@ return HEAPU8[$0_1 | 0]; } + bufferView = HEAPU8;+ initActiveSegments(env); function __wasm_memory_size() { return buffer.byteLength / 65536 | 0; }@@ -187,9 +190,15 @@ }; } -var memasmFunc = new ArrayBuffer(65536);-var bufferView = new Uint8Array(memasmFunc);-for (var base64ReverseLookup = new Uint8Array(123/*'z'+1*/), i = 25; i >= 0; --i) {+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }+ });+export var copy = retasmFunc.copy;+export var load8_u = retasmFunc.load8_u;++ var bufferView;+ var memorySegments = {};+ var base64ReverseLookup = new Uint8Array(123/*'z'+1*/);+ for (var i = 25; i >= 0; --i) { base64ReverseLookup[48+i] = 52+i; // '0-9' base64ReverseLookup[65+i] = i; // 'A-Z' base64ReverseLookup[97+i] = 26+i; // 'a-z'@@ -206,29 +215,9 @@ if (j < end) uint8Array[j++] = b1 << 4 | b2 >> 2; if (j < end) uint8Array[j++] = b2 << 6 | base64ReverseLookup[b64.charCodeAt(i+3)]; }- return uint8Array; + return uint8Array; }- base64DecodeToExistingUint8Array(bufferView, 0, "qrvM3Q==");-var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }- },- memasmFunc-);-export var copy = retasmFunc.copy;-export var load8_u = retasmFunc.load8_u;-+memorySegments[0] = base64DecodeToExistingUint8Array(new Uint8Array(4), 0, "qrvM3Q=="); var scratchBuffer = new ArrayBuffer(16); var i32ScratchView = new Int32Array(scratchBuffer);@@ -240,29 +229,29 @@ bufferView.set(memorySegments[segment].subarray(offset, offset + size), dest); } - var memorySegments = {};- -function asmFunc(global, env, buffer) {- var HEAP8 = new global.Int8Array(buffer);- var HEAP16 = new global.Int16Array(buffer);- var HEAP32 = new global.Int32Array(buffer);- var HEAPU8 = new global.Uint8Array(buffer);- var HEAPU16 = new global.Uint16Array(buffer);- var HEAPU32 = new global.Uint32Array(buffer);- var HEAPF32 = new global.Float32Array(buffer);- var HEAPF64 = new global.Float64Array(buffer);- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var buffer = new ArrayBuffer(65536);+ var HEAP8 = new Int8Array(buffer);+ var HEAP16 = new Int16Array(buffer);+ var HEAP32 = new Int32Array(buffer);+ var HEAPU8 = new Uint8Array(buffer);+ var HEAPU16 = new Uint16Array(buffer);+ var HEAPU32 = new Uint32Array(buffer);+ var HEAPF32 = new Float32Array(buffer);+ var HEAPF64 = new Float64Array(buffer);+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function $0($0_1, $1_1, $2) { $0_1 = $0_1 | 0; $1_1 = $1_1 | 0;@@ -275,6 +264,7 @@ return HEAPU8[$0_1 | 0]; } + bufferView = HEAPU8; function __wasm_memory_size() { return buffer.byteLength / 65536 | 0; }@@ -285,18 +275,18 @@ var newPages = oldPages + pagesToAdd | 0; if ((oldPages < newPages) && (newPages < 65536)) { var newBuffer = new ArrayBuffer(Math_imul(newPages, 65536));- var newHEAP8 = new global.Int8Array(newBuffer);+ var newHEAP8 = new Int8Array(newBuffer); newHEAP8.set(HEAP8);- HEAP8 = newHEAP8;- HEAP8 = new global.Int8Array(newBuffer);- HEAP16 = new global.Int16Array(newBuffer);- HEAP32 = new global.Int32Array(newBuffer);- HEAPU8 = new global.Uint8Array(newBuffer);- HEAPU16 = new global.Uint16Array(newBuffer);- HEAPU32 = new global.Uint32Array(newBuffer);- HEAPF32 = new global.Float32Array(newBuffer);- HEAPF64 = new global.Float64Array(newBuffer);+ HEAP8 = new Int8Array(newBuffer);+ HEAP16 = new Int16Array(newBuffer);+ HEAP32 = new Int32Array(newBuffer);+ HEAPU8 = new Uint8Array(newBuffer);+ HEAPU16 = new Uint16Array(newBuffer);+ HEAPU32 = new Uint32Array(newBuffer);+ HEAPF32 = new Float32Array(newBuffer);+ HEAPF64 = new Float64Array(newBuffer); buffer = newBuffer;+ bufferView = HEAPU8; } return oldPages; }@@ -307,75 +297,40 @@ }; } -var memasmFunc = new ArrayBuffer(65536);-var bufferView = new Uint8Array(memasmFunc);-for (var base64ReverseLookup = new Uint8Array(123/*'z'+1*/), i = 25; i >= 0; --i) {- base64ReverseLookup[48+i] = 52+i; // '0-9'- base64ReverseLookup[65+i] = i; // 'A-Z'- base64ReverseLookup[97+i] = 26+i; // 'a-z'- }- base64ReverseLookup[43] = 62; // '+'- base64ReverseLookup[47] = 63; // '/'- /** @noinline Inlining this function would mean expanding the base64 string 4x times in the source code, which Closure seems to be happy to do. */- function base64DecodeToExistingUint8Array(uint8Array, offset, b64) {- var b1, b2, i = 0, j = offset, bLength = b64.length, end = offset + (bLength*3>>2) - (b64[bLength-2] == '=') - (b64[bLength-1] == '=');- for (; i < bLength; i += 4) {- b1 = base64ReverseLookup[b64.charCodeAt(i+1)];- b2 = base64ReverseLookup[b64.charCodeAt(i+2)];- uint8Array[j++] = base64ReverseLookup[b64.charCodeAt(i)] << 2 | b1 >> 4;- if (j < end) uint8Array[j++] = b1 << 4 | b2 >> 2;- if (j < end) uint8Array[j++] = b2 << 6 | base64ReverseLookup[b64.charCodeAt(i+3)];- }- return uint8Array; - }- memorySegments[0] = base64DecodeToExistingUint8Array(new Uint8Array(4), 0, "qrvM3Q==");-var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }- },- memasmFunc-);+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }+ }); export var init = retasmFunc.init; export var load8_u = retasmFunc.load8_u; -function asmFunc(global, env, buffer) {- var HEAP8 = new global.Int8Array(buffer);- var HEAP16 = new global.Int16Array(buffer);- var HEAP32 = new global.Int32Array(buffer);- var HEAPU8 = new global.Uint8Array(buffer);- var HEAPU16 = new global.Uint16Array(buffer);- var HEAPU32 = new global.Uint32Array(buffer);- var HEAPF32 = new global.Float32Array(buffer);- var HEAPF64 = new global.Float64Array(buffer);- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var buffer = new ArrayBuffer(65536);+ var HEAP8 = new Int8Array(buffer);+ var HEAP16 = new Int16Array(buffer);+ var HEAP32 = new Int32Array(buffer);+ var HEAPU8 = new Uint8Array(buffer);+ var HEAPU16 = new Uint16Array(buffer);+ var HEAPU32 = new Uint32Array(buffer);+ var HEAPF32 = new Float32Array(buffer);+ var HEAPF64 = new Float64Array(buffer);+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function $0() { } function $1() {- if (0 > __wasm_memory_size() << 16 >>> 0) {+ if (__wasm_memory_size() << 16 >>> 0 < 0) { abort() } }@@ -390,17 +345,16 @@ var newPages = oldPages + pagesToAdd | 0; if ((oldPages < newPages) && (newPages < 65536)) { var newBuffer = new ArrayBuffer(Math_imul(newPages, 65536));- var newHEAP8 = new global.Int8Array(newBuffer);+ var newHEAP8 = new Int8Array(newBuffer); newHEAP8.set(HEAP8);- HEAP8 = newHEAP8;- HEAP8 = new global.Int8Array(newBuffer);- HEAP16 = new global.Int16Array(newBuffer);- HEAP32 = new global.Int32Array(newBuffer);- HEAPU8 = new global.Uint8Array(newBuffer);- HEAPU16 = new global.Uint16Array(newBuffer);- HEAPU32 = new global.Uint32Array(newBuffer);- HEAPF32 = new global.Float32Array(newBuffer);- HEAPF64 = new global.Float64Array(newBuffer);+ HEAP8 = new Int8Array(newBuffer);+ HEAP16 = new Int16Array(newBuffer);+ HEAP32 = new Int32Array(newBuffer);+ HEAPU8 = new Uint8Array(newBuffer);+ HEAPU16 = new Uint16Array(newBuffer);+ HEAPU32 = new Uint32Array(newBuffer);+ HEAPF32 = new Float32Array(newBuffer);+ HEAPF64 = new Float64Array(newBuffer); buffer = newBuffer; } return oldPages;@@ -414,25 +368,8 @@ }; } -var memasmFunc = new ArrayBuffer(65536);-var bufferView = new Uint8Array(memasmFunc);-var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }- },- memasmFunc-);+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }+ }); export var drop_passive = retasmFunc.drop_passive; export var init_passive = retasmFunc.init_passive; export var drop_active = retasmFunc.drop_active;
binaryen/test/wasm2js/comments.2asm.js view
@@ -1,68 +1,44 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; return { }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } }); -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; return { }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } });
binaryen/test/wasm2js/conversions-modified.2asm.js view
@@ -30,19 +30,20 @@ f32ScratchView[2] = value; } -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; var setTempRet0 = env.setTempRet0; var i64toi32_i32$HIGH_BITS = 0; function $0(x) {@@ -618,20 +619,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); },+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }, setTempRet0 }); export var i64_extend_s_i32 = retasmFunc.i64_extend_s_i32;
binaryen/test/wasm2js/conversions-modified.2asm.js.opt view
@@ -30,19 +30,20 @@ f32ScratchView[2] = value; } -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; var setTempRet0 = env.setTempRet0; var i64toi32_i32$HIGH_BITS = 0; function $3($0) {@@ -67,13 +68,13 @@ function $7($0) { $0 = Math_fround($0);- i64toi32_i32$HIGH_BITS = Math_fround(Math_abs($0)) >= Math_fround(1.0) ? ($0 > Math_fround(0.0) ? ~~Math_fround(Math_min(Math_fround(Math_floor(Math_fround($0 / Math_fround(4294967296.0)))), Math_fround(4294967296.0))) >>> 0 : ~~Math_fround(Math_ceil(Math_fround(Math_fround($0 - Math_fround(~~$0 >>> 0 >>> 0)) / Math_fround(4294967296.0)))) >>> 0) : 0;+ i64toi32_i32$HIGH_BITS = Math_fround(Math_abs($0)) >= Math_fround(1.0) ? ($0 > Math_fround(0.0) ? ~~Math_fround(Math_min(Math_fround(Math_floor(Math_fround($0 * Math_fround(2.3283064365386963e-10)))), Math_fround(4294967296.0))) >>> 0 : ~~Math_fround(Math_ceil(Math_fround(Math_fround($0 - Math_fround(~~$0 >>> 0 >>> 0)) * Math_fround(2.3283064365386963e-10)))) >>> 0) : 0; return ~~$0 >>> 0 | 0; } function $9($0) { $0 = +$0;- i64toi32_i32$HIGH_BITS = Math_abs($0) >= 1.0 ? ($0 > 0.0 ? ~~Math_min(Math_floor($0 / 4294967296.0), 4294967295.0) >>> 0 : ~~Math_ceil(($0 - +(~~$0 >>> 0 >>> 0)) / 4294967296.0) >>> 0) : 0;+ i64toi32_i32$HIGH_BITS = Math_abs($0) >= 1.0 ? ($0 > 0.0 ? ~~Math_min(Math_floor($0 * 2.3283064365386963e-10), 4294967295.0) >>> 0 : ~~Math_ceil(($0 - +(~~$0 >>> 0 >>> 0)) * 2.3283064365386963e-10) >>> 0) : 0; return ~~$0 >>> 0 | 0; } @@ -209,20 +210,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); },+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }, setTempRet0 }); export var i64_extend_s_i32 = retasmFunc.i64_extend_s_i32;
binaryen/test/wasm2js/deterministic.2asm.js view
@@ -1,27 +1,28 @@ -function asmFunc(global, env) {+function asmFunc(env) { var memory = env.memory; var buffer = memory.buffer;- var HEAP8 = new global.Int8Array(buffer);- var HEAP16 = new global.Int16Array(buffer);- var HEAP32 = new global.Int32Array(buffer);- var HEAPU8 = new global.Uint8Array(buffer);- var HEAPU16 = new global.Uint16Array(buffer);- var HEAPU32 = new global.Uint32Array(buffer);- var HEAPF32 = new global.Float32Array(buffer);- var HEAPF64 = new global.Float64Array(buffer);- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+ var HEAP8 = new Int8Array(buffer);+ var HEAP16 = new Int16Array(buffer);+ var HEAP32 = new Int32Array(buffer);+ var HEAPU8 = new Uint8Array(buffer);+ var HEAPU16 = new Uint16Array(buffer);+ var HEAPU32 = new Uint32Array(buffer);+ var HEAPF32 = new Float32Array(buffer);+ var HEAPF64 = new Float64Array(buffer);+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; var global$0 = -44; function $0() { if ((global$0 >>> 0) / ((HEAP32[0 >> 2] | 0) >>> 0) | 0) {@@ -40,21 +41,7 @@ } var memasmFunc = new ArrayBuffer(65536);-var bufferView = new Uint8Array(memasmFunc);-var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); },+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }, memory: { buffer : memasmFunc } }); export var foo = retasmFunc.foo;
binaryen/test/wasm2js/deterministic.2asm.js.opt view
@@ -1,27 +1,28 @@ -function asmFunc(global, env) {+function asmFunc(env) { var memory = env.memory; var buffer = memory.buffer;- var HEAP8 = new global.Int8Array(buffer);- var HEAP16 = new global.Int16Array(buffer);- var HEAP32 = new global.Int32Array(buffer);- var HEAPU8 = new global.Uint8Array(buffer);- var HEAPU16 = new global.Uint16Array(buffer);- var HEAPU32 = new global.Uint32Array(buffer);- var HEAPF32 = new global.Float32Array(buffer);- var HEAPF64 = new global.Float64Array(buffer);- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+ var HEAP8 = new Int8Array(buffer);+ var HEAP16 = new Int16Array(buffer);+ var HEAP32 = new Int32Array(buffer);+ var HEAPU8 = new Uint8Array(buffer);+ var HEAPU16 = new Uint16Array(buffer);+ var HEAPU32 = new Uint32Array(buffer);+ var HEAPF32 = new Float32Array(buffer);+ var HEAPF64 = new Float64Array(buffer);+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function $0() { if (4294967252 / HEAPU32[0] | 0) { abort()@@ -39,21 +40,7 @@ } var memasmFunc = new ArrayBuffer(65536);-var bufferView = new Uint8Array(memasmFunc);-var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); },+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }, memory: { buffer : memasmFunc } }); export var foo = retasmFunc.foo;
binaryen/test/wasm2js/dot_import.2asm.js view
@@ -1,18 +1,19 @@ import { ba_se } from 'mod.ule'; -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; var base = env.ba_se; function $0() { base();@@ -23,20 +24,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); },+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }, ba_se }); export var exported = retasmFunc.exported;
binaryen/test/wasm2js/dot_import.2asm.js.opt view
@@ -1,18 +1,19 @@ import { ba_se } from 'mod.ule'; -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; var base = env.ba_se; function $0() { base();@@ -23,20 +24,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); },+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }, ba_se }); export var exported = retasmFunc.exported;
binaryen/test/wasm2js/dynamicLibrary.2asm.js view
@@ -12,29 +12,54 @@ return ret; } -function asmFunc(global, env) {+ var bufferView;+ var base64ReverseLookup = new Uint8Array(123/*'z'+1*/);+ for (var i = 25; i >= 0; --i) {+ base64ReverseLookup[48+i] = 52+i; // '0-9'+ base64ReverseLookup[65+i] = i; // 'A-Z'+ base64ReverseLookup[97+i] = 26+i; // 'a-z'+ }+ base64ReverseLookup[43] = 62; // '+'+ base64ReverseLookup[47] = 63; // '/'+ /** @noinline Inlining this function would mean expanding the base64 string 4x times in the source code, which Closure seems to be happy to do. */+ function base64DecodeToExistingUint8Array(uint8Array, offset, b64) {+ var b1, b2, i = 0, j = offset, bLength = b64.length, end = offset + (bLength*3>>2) - (b64[bLength-2] == '=') - (b64[bLength-1] == '=');+ for (; i < bLength; i += 4) {+ b1 = base64ReverseLookup[b64.charCodeAt(i+1)];+ b2 = base64ReverseLookup[b64.charCodeAt(i+2)];+ uint8Array[j++] = base64ReverseLookup[b64.charCodeAt(i)] << 2 | b1 >> 4;+ if (j < end) uint8Array[j++] = b1 << 4 | b2 >> 2;+ if (j < end) uint8Array[j++] = b2 << 6 | base64ReverseLookup[b64.charCodeAt(i+3)];+ }+ return uint8Array;+ }+function initActiveSegments(imports) {+ base64DecodeToExistingUint8Array(bufferView, imports[memoryBase], "ZHluYW1pYyBkYXRh");+}+function asmFunc(env) { var memory = env.memory; var buffer = memory.buffer;- var HEAP8 = new global.Int8Array(buffer);- var HEAP16 = new global.Int16Array(buffer);- var HEAP32 = new global.Int32Array(buffer);- var HEAPU8 = new global.Uint8Array(buffer);- var HEAPU16 = new global.Uint16Array(buffer);- var HEAPU32 = new global.Uint32Array(buffer);- var HEAPF32 = new global.Float32Array(buffer);- var HEAPF64 = new global.Float64Array(buffer);- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+ var HEAP8 = new Int8Array(buffer);+ var HEAP16 = new Int16Array(buffer);+ var HEAP32 = new Int32Array(buffer);+ var HEAPU8 = new Uint8Array(buffer);+ var HEAPU16 = new Uint16Array(buffer);+ var HEAPU32 = new Uint32Array(buffer);+ var HEAPF32 = new Float32Array(buffer);+ var HEAPF64 = new Float64Array(buffer);+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; var import$memoryBase = env.memoryBase | 0; var import$tableBase = env.tableBase | 0; function foo() {@@ -49,6 +74,8 @@ } + bufferView = HEAPU8;+ initActiveSegments(env); var FUNCTION_TABLE = Table(new Array(10)); FUNCTION_TABLE[import$tableBase + 0] = foo; FUNCTION_TABLE[import$tableBase + 1] = bar;@@ -63,41 +90,7 @@ } var memasmFunc = new ArrayBuffer(16777216);-var bufferView = new Uint8Array(memasmFunc);-for (var base64ReverseLookup = new Uint8Array(123/*'z'+1*/), i = 25; i >= 0; --i) {- base64ReverseLookup[48+i] = 52+i; // '0-9'- base64ReverseLookup[65+i] = i; // 'A-Z'- base64ReverseLookup[97+i] = 26+i; // 'a-z'- }- base64ReverseLookup[43] = 62; // '+'- base64ReverseLookup[47] = 63; // '/'- /** @noinline Inlining this function would mean expanding the base64 string 4x times in the source code, which Closure seems to be happy to do. */- function base64DecodeToExistingUint8Array(uint8Array, offset, b64) {- var b1, b2, i = 0, j = offset, bLength = b64.length, end = offset + (bLength*3>>2) - (b64[bLength-2] == '=') - (b64[bLength-1] == '=');- for (; i < bLength; i += 4) {- b1 = base64ReverseLookup[b64.charCodeAt(i+1)];- b2 = base64ReverseLookup[b64.charCodeAt(i+2)];- uint8Array[j++] = base64ReverseLookup[b64.charCodeAt(i)] << 2 | b1 >> 4;- if (j < end) uint8Array[j++] = b1 << 4 | b2 >> 2;- if (j < end) uint8Array[j++] = b2 << 6 | base64ReverseLookup[b64.charCodeAt(i+3)];- }- return uint8Array; - }- base64DecodeToExistingUint8Array(bufferView, memoryBase, "ZHluYW1pYyBkYXRh");-var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); },+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }, memory: { buffer : memasmFunc } }); export var baz = retasmFunc.baz;
binaryen/test/wasm2js/dynamicLibrary.2asm.js.opt view
@@ -12,35 +12,62 @@ return ret; } -function asmFunc(global, env) {+ var bufferView;+ var base64ReverseLookup = new Uint8Array(123/*'z'+1*/);+ for (var i = 25; i >= 0; --i) {+ base64ReverseLookup[48+i] = 52+i; // '0-9'+ base64ReverseLookup[65+i] = i; // 'A-Z'+ base64ReverseLookup[97+i] = 26+i; // 'a-z'+ }+ base64ReverseLookup[43] = 62; // '+'+ base64ReverseLookup[47] = 63; // '/'+ /** @noinline Inlining this function would mean expanding the base64 string 4x times in the source code, which Closure seems to be happy to do. */+ function base64DecodeToExistingUint8Array(uint8Array, offset, b64) {+ var b1, b2, i = 0, j = offset, bLength = b64.length, end = offset + (bLength*3>>2) - (b64[bLength-2] == '=') - (b64[bLength-1] == '=');+ for (; i < bLength; i += 4) {+ b1 = base64ReverseLookup[b64.charCodeAt(i+1)];+ b2 = base64ReverseLookup[b64.charCodeAt(i+2)];+ uint8Array[j++] = base64ReverseLookup[b64.charCodeAt(i)] << 2 | b1 >> 4;+ if (j < end) uint8Array[j++] = b1 << 4 | b2 >> 2;+ if (j < end) uint8Array[j++] = b2 << 6 | base64ReverseLookup[b64.charCodeAt(i+3)];+ }+ return uint8Array;+ }+function initActiveSegments(imports) {+ base64DecodeToExistingUint8Array(bufferView, imports[memoryBase], "ZHluYW1pYyBkYXRh");+}+function asmFunc(env) { var memory = env.memory; var buffer = memory.buffer;- var HEAP8 = new global.Int8Array(buffer);- var HEAP16 = new global.Int16Array(buffer);- var HEAP32 = new global.Int32Array(buffer);- var HEAPU8 = new global.Uint8Array(buffer);- var HEAPU16 = new global.Uint16Array(buffer);- var HEAPU32 = new global.Uint32Array(buffer);- var HEAPF32 = new global.Float32Array(buffer);- var HEAPF64 = new global.Float64Array(buffer);- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+ var HEAP8 = new Int8Array(buffer);+ var HEAP16 = new Int16Array(buffer);+ var HEAP32 = new Int32Array(buffer);+ var HEAPU8 = new Uint8Array(buffer);+ var HEAPU16 = new Uint16Array(buffer);+ var HEAPU32 = new Uint32Array(buffer);+ var HEAPF32 = new Float32Array(buffer);+ var HEAPF64 = new Float64Array(buffer);+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; var import$memoryBase = env.memoryBase | 0; var import$tableBase = env.tableBase | 0; function foo() { } + bufferView = HEAPU8;+ initActiveSegments(env); var FUNCTION_TABLE = Table(new Array(10)); FUNCTION_TABLE[import$tableBase + 0] = foo; FUNCTION_TABLE[import$tableBase + 1] = foo;@@ -55,41 +82,7 @@ } var memasmFunc = new ArrayBuffer(16777216);-var bufferView = new Uint8Array(memasmFunc);-for (var base64ReverseLookup = new Uint8Array(123/*'z'+1*/), i = 25; i >= 0; --i) {- base64ReverseLookup[48+i] = 52+i; // '0-9'- base64ReverseLookup[65+i] = i; // 'A-Z'- base64ReverseLookup[97+i] = 26+i; // 'a-z'- }- base64ReverseLookup[43] = 62; // '+'- base64ReverseLookup[47] = 63; // '/'- /** @noinline Inlining this function would mean expanding the base64 string 4x times in the source code, which Closure seems to be happy to do. */- function base64DecodeToExistingUint8Array(uint8Array, offset, b64) {- var b1, b2, i = 0, j = offset, bLength = b64.length, end = offset + (bLength*3>>2) - (b64[bLength-2] == '=') - (b64[bLength-1] == '=');- for (; i < bLength; i += 4) {- b1 = base64ReverseLookup[b64.charCodeAt(i+1)];- b2 = base64ReverseLookup[b64.charCodeAt(i+2)];- uint8Array[j++] = base64ReverseLookup[b64.charCodeAt(i)] << 2 | b1 >> 4;- if (j < end) uint8Array[j++] = b1 << 4 | b2 >> 2;- if (j < end) uint8Array[j++] = b2 << 6 | base64ReverseLookup[b64.charCodeAt(i+3)];- }- return uint8Array; - }- base64DecodeToExistingUint8Array(bufferView, memoryBase, "ZHluYW1pYyBkYXRh");-var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); },+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }, memory: { buffer : memasmFunc } }); export var baz = retasmFunc.baz;
binaryen/test/wasm2js/empty_export.2asm.js view
@@ -1,17 +1,18 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function foo() { }@@ -21,19 +22,6 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } }); export var $ = retasmFunc.$;
binaryen/test/wasm2js/empty_export.2asm.js.opt view
@@ -1,17 +1,18 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function foo() { }@@ -21,19 +22,6 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } }); export var $ = retasmFunc.$;
binaryen/test/wasm2js/empty_table.2asm.js view
@@ -1,34 +1,22 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; return { }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } });
binaryen/test/wasm2js/emscripten-grow-no.2asm.js view
@@ -1,31 +1,58 @@-function instantiate(asmLibraryArg, wasmMemory) {-function asmFunc(global, env) {+function instantiate(asmLibraryArg) {+ var bufferView;+ var base64ReverseLookup = new Uint8Array(123/*'z'+1*/);+ for (var i = 25; i >= 0; --i) {+ base64ReverseLookup[48+i] = 52+i; // '0-9'+ base64ReverseLookup[65+i] = i; // 'A-Z'+ base64ReverseLookup[97+i] = 26+i; // 'a-z'+ }+ base64ReverseLookup[43] = 62; // '+'+ base64ReverseLookup[47] = 63; // '/'+ /** @noinline Inlining this function would mean expanding the base64 string 4x times in the source code, which Closure seems to be happy to do. */+ function base64DecodeToExistingUint8Array(uint8Array, offset, b64) {+ var b1, b2, i = 0, j = offset, bLength = b64.length, end = offset + (bLength*3>>2) - (b64[bLength-2] == '=') - (b64[bLength-1] == '=');+ for (; i < bLength; i += 4) {+ b1 = base64ReverseLookup[b64.charCodeAt(i+1)];+ b2 = base64ReverseLookup[b64.charCodeAt(i+2)];+ uint8Array[j++] = base64ReverseLookup[b64.charCodeAt(i)] << 2 | b1 >> 4;+ if (j < end) uint8Array[j++] = b1 << 4 | b2 >> 2;+ if (j < end) uint8Array[j++] = b2 << 6 | base64ReverseLookup[b64.charCodeAt(i+3)];+ }+ return uint8Array;+ }+function initActiveSegments(imports) {+ base64DecodeToExistingUint8Array(bufferView, 1600, "YWJj");+}+function asmFunc(env) { var memory = env.memory; var buffer = memory.buffer;- var HEAP8 = new global.Int8Array(buffer);- var HEAP16 = new global.Int16Array(buffer);- var HEAP32 = new global.Int32Array(buffer);- var HEAPU8 = new global.Uint8Array(buffer);- var HEAPU16 = new global.Uint16Array(buffer);- var HEAPU32 = new global.Uint32Array(buffer);- var HEAPF32 = new global.Float32Array(buffer);- var HEAPF64 = new global.Float64Array(buffer);- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+ var HEAP8 = new Int8Array(buffer);+ var HEAP16 = new Int16Array(buffer);+ var HEAP32 = new Int32Array(buffer);+ var HEAPU8 = new Uint8Array(buffer);+ var HEAPU16 = new Uint16Array(buffer);+ var HEAPU32 = new Uint32Array(buffer);+ var HEAPF32 = new Float32Array(buffer);+ var HEAPF64 = new Float64Array(buffer);+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; // EMSCRIPTEN_START_FUNCS ; // EMSCRIPTEN_END_FUNCS ;+ bufferView = HEAPU8;+ initActiveSegments(env); function __wasm_memory_size() { return buffer.byteLength / 65536 | 0; }@@ -45,42 +72,5 @@ }; } -var bufferView = new Uint8Array(wasmMemory.buffer);-for (var base64ReverseLookup = new Uint8Array(123/*'z'+1*/), i = 25; i >= 0; --i) {- base64ReverseLookup[48+i] = 52+i; // '0-9'- base64ReverseLookup[65+i] = i; // 'A-Z'- base64ReverseLookup[97+i] = 26+i; // 'a-z'- }- base64ReverseLookup[43] = 62; // '+'- base64ReverseLookup[47] = 63; // '/'- /** @noinline Inlining this function would mean expanding the base64 string 4x times in the source code, which Closure seems to be happy to do. */- function base64DecodeToExistingUint8Array(uint8Array, offset, b64) {- var b1, b2, i = 0, j = offset, bLength = b64.length, end = offset + (bLength*3>>2) - (b64[bLength-2] == '=') - (b64[bLength-1] == '=');- for (; i < bLength; i += 4) {- b1 = base64ReverseLookup[b64.charCodeAt(i+1)];- b2 = base64ReverseLookup[b64.charCodeAt(i+2)];- uint8Array[j++] = base64ReverseLookup[b64.charCodeAt(i)] << 2 | b1 >> 4;- if (j < end) uint8Array[j++] = b1 << 4 | b2 >> 2;- if (j < end) uint8Array[j++] = b2 << 6 | base64ReverseLookup[b64.charCodeAt(i+3)];- }- return uint8Array; - }- base64DecodeToExistingUint8Array(bufferView, 1600, "YWJj");-return asmFunc({- 'Int8Array': Int8Array,- 'Int16Array': Int16Array,- 'Int32Array': Int32Array,- 'Uint8Array': Uint8Array,- 'Uint16Array': Uint16Array,- 'Uint32Array': Uint32Array,- 'Float32Array': Float32Array,- 'Float64Array': Float64Array,- 'NaN': NaN,- 'Infinity': Infinity,- 'Math': Math- },- asmLibraryArg,- wasmMemory.buffer-)-+ return asmFunc(asmLibraryArg); }
binaryen/test/wasm2js/emscripten-grow-no.2asm.js.opt view
@@ -1,31 +1,58 @@-function instantiate(asmLibraryArg, wasmMemory) {-function asmFunc(global, env) {+function instantiate(asmLibraryArg) {+ var bufferView;+ var base64ReverseLookup = new Uint8Array(123/*'z'+1*/);+ for (var i = 25; i >= 0; --i) {+ base64ReverseLookup[48+i] = 52+i; // '0-9'+ base64ReverseLookup[65+i] = i; // 'A-Z'+ base64ReverseLookup[97+i] = 26+i; // 'a-z'+ }+ base64ReverseLookup[43] = 62; // '+'+ base64ReverseLookup[47] = 63; // '/'+ /** @noinline Inlining this function would mean expanding the base64 string 4x times in the source code, which Closure seems to be happy to do. */+ function base64DecodeToExistingUint8Array(uint8Array, offset, b64) {+ var b1, b2, i = 0, j = offset, bLength = b64.length, end = offset + (bLength*3>>2) - (b64[bLength-2] == '=') - (b64[bLength-1] == '=');+ for (; i < bLength; i += 4) {+ b1 = base64ReverseLookup[b64.charCodeAt(i+1)];+ b2 = base64ReverseLookup[b64.charCodeAt(i+2)];+ uint8Array[j++] = base64ReverseLookup[b64.charCodeAt(i)] << 2 | b1 >> 4;+ if (j < end) uint8Array[j++] = b1 << 4 | b2 >> 2;+ if (j < end) uint8Array[j++] = b2 << 6 | base64ReverseLookup[b64.charCodeAt(i+3)];+ }+ return uint8Array;+ }+function initActiveSegments(imports) {+ base64DecodeToExistingUint8Array(bufferView, 1600, "YWJj");+}+function asmFunc(env) { var memory = env.memory; var buffer = memory.buffer;- var HEAP8 = new global.Int8Array(buffer);- var HEAP16 = new global.Int16Array(buffer);- var HEAP32 = new global.Int32Array(buffer);- var HEAPU8 = new global.Uint8Array(buffer);- var HEAPU16 = new global.Uint16Array(buffer);- var HEAPU32 = new global.Uint32Array(buffer);- var HEAPF32 = new global.Float32Array(buffer);- var HEAPF64 = new global.Float64Array(buffer);- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+ var HEAP8 = new Int8Array(buffer);+ var HEAP16 = new Int16Array(buffer);+ var HEAP32 = new Int32Array(buffer);+ var HEAPU8 = new Uint8Array(buffer);+ var HEAPU16 = new Uint16Array(buffer);+ var HEAPU32 = new Uint32Array(buffer);+ var HEAPF32 = new Float32Array(buffer);+ var HEAPF64 = new Float64Array(buffer);+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; // EMSCRIPTEN_START_FUNCS ; // EMSCRIPTEN_END_FUNCS ;+ bufferView = HEAPU8;+ initActiveSegments(env); function __wasm_memory_size() { return buffer.byteLength / 65536 | 0; }@@ -45,42 +72,5 @@ }; } -var bufferView = new Uint8Array(wasmMemory.buffer);-for (var base64ReverseLookup = new Uint8Array(123/*'z'+1*/), i = 25; i >= 0; --i) {- base64ReverseLookup[48+i] = 52+i; // '0-9'- base64ReverseLookup[65+i] = i; // 'A-Z'- base64ReverseLookup[97+i] = 26+i; // 'a-z'- }- base64ReverseLookup[43] = 62; // '+'- base64ReverseLookup[47] = 63; // '/'- /** @noinline Inlining this function would mean expanding the base64 string 4x times in the source code, which Closure seems to be happy to do. */- function base64DecodeToExistingUint8Array(uint8Array, offset, b64) {- var b1, b2, i = 0, j = offset, bLength = b64.length, end = offset + (bLength*3>>2) - (b64[bLength-2] == '=') - (b64[bLength-1] == '=');- for (; i < bLength; i += 4) {- b1 = base64ReverseLookup[b64.charCodeAt(i+1)];- b2 = base64ReverseLookup[b64.charCodeAt(i+2)];- uint8Array[j++] = base64ReverseLookup[b64.charCodeAt(i)] << 2 | b1 >> 4;- if (j < end) uint8Array[j++] = b1 << 4 | b2 >> 2;- if (j < end) uint8Array[j++] = b2 << 6 | base64ReverseLookup[b64.charCodeAt(i+3)];- }- return uint8Array; - }- base64DecodeToExistingUint8Array(bufferView, 1600, "YWJj");-return asmFunc({- 'Int8Array': Int8Array,- 'Int16Array': Int16Array,- 'Int32Array': Int32Array,- 'Uint8Array': Uint8Array,- 'Uint16Array': Uint16Array,- 'Uint32Array': Uint32Array,- 'Float32Array': Float32Array,- 'Float64Array': Float64Array,- 'NaN': NaN,- 'Infinity': Infinity,- 'Math': Math- },- asmLibraryArg,- wasmMemory.buffer-)-+ return asmFunc(asmLibraryArg); }
binaryen/test/wasm2js/emscripten-grow-yes.2asm.js view
@@ -1,32 +1,59 @@-function instantiate(asmLibraryArg, wasmMemory) {-function asmFunc(global, env) {+function instantiate(asmLibraryArg) {+ var bufferView;+ var base64ReverseLookup = new Uint8Array(123/*'z'+1*/);+ for (var i = 25; i >= 0; --i) {+ base64ReverseLookup[48+i] = 52+i; // '0-9'+ base64ReverseLookup[65+i] = i; // 'A-Z'+ base64ReverseLookup[97+i] = 26+i; // 'a-z'+ }+ base64ReverseLookup[43] = 62; // '+'+ base64ReverseLookup[47] = 63; // '/'+ /** @noinline Inlining this function would mean expanding the base64 string 4x times in the source code, which Closure seems to be happy to do. */+ function base64DecodeToExistingUint8Array(uint8Array, offset, b64) {+ var b1, b2, i = 0, j = offset, bLength = b64.length, end = offset + (bLength*3>>2) - (b64[bLength-2] == '=') - (b64[bLength-1] == '=');+ for (; i < bLength; i += 4) {+ b1 = base64ReverseLookup[b64.charCodeAt(i+1)];+ b2 = base64ReverseLookup[b64.charCodeAt(i+2)];+ uint8Array[j++] = base64ReverseLookup[b64.charCodeAt(i)] << 2 | b1 >> 4;+ if (j < end) uint8Array[j++] = b1 << 4 | b2 >> 2;+ if (j < end) uint8Array[j++] = b2 << 6 | base64ReverseLookup[b64.charCodeAt(i+3)];+ }+ return uint8Array;+ }+function initActiveSegments(imports) {+ base64DecodeToExistingUint8Array(bufferView, 1600, "YWJj");+}+function asmFunc(env) { var memory = env.memory; var buffer = memory.buffer; memory.grow = __wasm_memory_grow;- var HEAP8 = new global.Int8Array(buffer);- var HEAP16 = new global.Int16Array(buffer);- var HEAP32 = new global.Int32Array(buffer);- var HEAPU8 = new global.Uint8Array(buffer);- var HEAPU16 = new global.Uint16Array(buffer);- var HEAPU32 = new global.Uint32Array(buffer);- var HEAPF32 = new global.Float32Array(buffer);- var HEAPF64 = new global.Float64Array(buffer);- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+ var HEAP8 = new Int8Array(buffer);+ var HEAP16 = new Int16Array(buffer);+ var HEAP32 = new Int32Array(buffer);+ var HEAPU8 = new Uint8Array(buffer);+ var HEAPU16 = new Uint16Array(buffer);+ var HEAPU32 = new Uint32Array(buffer);+ var HEAPF32 = new Float32Array(buffer);+ var HEAPF64 = new Float64Array(buffer);+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; // EMSCRIPTEN_START_FUNCS ; // EMSCRIPTEN_END_FUNCS ;+ bufferView = HEAPU8;+ initActiveSegments(env); function __wasm_memory_size() { return buffer.byteLength / 65536 | 0; }@@ -37,19 +64,19 @@ var newPages = oldPages + pagesToAdd | 0; if ((oldPages < newPages) && (newPages < 65536)) { var newBuffer = new ArrayBuffer(Math_imul(newPages, 65536));- var newHEAP8 = new global.Int8Array(newBuffer);+ var newHEAP8 = new Int8Array(newBuffer); newHEAP8.set(HEAP8);- HEAP8 = newHEAP8;- HEAP8 = new global.Int8Array(newBuffer);- HEAP16 = new global.Int16Array(newBuffer);- HEAP32 = new global.Int32Array(newBuffer);- HEAPU8 = new global.Uint8Array(newBuffer);- HEAPU16 = new global.Uint16Array(newBuffer);- HEAPU32 = new global.Uint32Array(newBuffer);- HEAPF32 = new global.Float32Array(newBuffer);- HEAPF64 = new global.Float64Array(newBuffer);+ HEAP8 = new Int8Array(newBuffer);+ HEAP16 = new Int16Array(newBuffer);+ HEAP32 = new Int32Array(newBuffer);+ HEAPU8 = new Uint8Array(newBuffer);+ HEAPU16 = new Uint16Array(newBuffer);+ HEAPU32 = new Uint32Array(newBuffer);+ HEAPF32 = new Float32Array(newBuffer);+ HEAPF64 = new Float64Array(newBuffer); buffer = newBuffer;- memory.buffer = newBuffer;+ memory.buffer = buffer;+ bufferView = HEAPU8; } return oldPages; }@@ -69,42 +96,5 @@ }; } -var bufferView = new Uint8Array(wasmMemory.buffer);-for (var base64ReverseLookup = new Uint8Array(123/*'z'+1*/), i = 25; i >= 0; --i) {- base64ReverseLookup[48+i] = 52+i; // '0-9'- base64ReverseLookup[65+i] = i; // 'A-Z'- base64ReverseLookup[97+i] = 26+i; // 'a-z'- }- base64ReverseLookup[43] = 62; // '+'- base64ReverseLookup[47] = 63; // '/'- /** @noinline Inlining this function would mean expanding the base64 string 4x times in the source code, which Closure seems to be happy to do. */- function base64DecodeToExistingUint8Array(uint8Array, offset, b64) {- var b1, b2, i = 0, j = offset, bLength = b64.length, end = offset + (bLength*3>>2) - (b64[bLength-2] == '=') - (b64[bLength-1] == '=');- for (; i < bLength; i += 4) {- b1 = base64ReverseLookup[b64.charCodeAt(i+1)];- b2 = base64ReverseLookup[b64.charCodeAt(i+2)];- uint8Array[j++] = base64ReverseLookup[b64.charCodeAt(i)] << 2 | b1 >> 4;- if (j < end) uint8Array[j++] = b1 << 4 | b2 >> 2;- if (j < end) uint8Array[j++] = b2 << 6 | base64ReverseLookup[b64.charCodeAt(i+3)];- }- return uint8Array; - }- base64DecodeToExistingUint8Array(bufferView, 1600, "YWJj");-return asmFunc({- 'Int8Array': Int8Array,- 'Int16Array': Int16Array,- 'Int32Array': Int32Array,- 'Uint8Array': Uint8Array,- 'Uint16Array': Uint16Array,- 'Uint32Array': Uint32Array,- 'Float32Array': Float32Array,- 'Float64Array': Float64Array,- 'NaN': NaN,- 'Infinity': Infinity,- 'Math': Math- },- asmLibraryArg,- wasmMemory.buffer-)-+ return asmFunc(asmLibraryArg); }
binaryen/test/wasm2js/emscripten-grow-yes.2asm.js.opt view
@@ -1,32 +1,59 @@-function instantiate(asmLibraryArg, wasmMemory) {-function asmFunc(global, env) {+function instantiate(asmLibraryArg) {+ var bufferView;+ var base64ReverseLookup = new Uint8Array(123/*'z'+1*/);+ for (var i = 25; i >= 0; --i) {+ base64ReverseLookup[48+i] = 52+i; // '0-9'+ base64ReverseLookup[65+i] = i; // 'A-Z'+ base64ReverseLookup[97+i] = 26+i; // 'a-z'+ }+ base64ReverseLookup[43] = 62; // '+'+ base64ReverseLookup[47] = 63; // '/'+ /** @noinline Inlining this function would mean expanding the base64 string 4x times in the source code, which Closure seems to be happy to do. */+ function base64DecodeToExistingUint8Array(uint8Array, offset, b64) {+ var b1, b2, i = 0, j = offset, bLength = b64.length, end = offset + (bLength*3>>2) - (b64[bLength-2] == '=') - (b64[bLength-1] == '=');+ for (; i < bLength; i += 4) {+ b1 = base64ReverseLookup[b64.charCodeAt(i+1)];+ b2 = base64ReverseLookup[b64.charCodeAt(i+2)];+ uint8Array[j++] = base64ReverseLookup[b64.charCodeAt(i)] << 2 | b1 >> 4;+ if (j < end) uint8Array[j++] = b1 << 4 | b2 >> 2;+ if (j < end) uint8Array[j++] = b2 << 6 | base64ReverseLookup[b64.charCodeAt(i+3)];+ }+ return uint8Array;+ }+function initActiveSegments(imports) {+ base64DecodeToExistingUint8Array(bufferView, 1600, "YWJj");+}+function asmFunc(env) { var memory = env.memory; var buffer = memory.buffer; memory.grow = __wasm_memory_grow;- var HEAP8 = new global.Int8Array(buffer);- var HEAP16 = new global.Int16Array(buffer);- var HEAP32 = new global.Int32Array(buffer);- var HEAPU8 = new global.Uint8Array(buffer);- var HEAPU16 = new global.Uint16Array(buffer);- var HEAPU32 = new global.Uint32Array(buffer);- var HEAPF32 = new global.Float32Array(buffer);- var HEAPF64 = new global.Float64Array(buffer);- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+ var HEAP8 = new Int8Array(buffer);+ var HEAP16 = new Int16Array(buffer);+ var HEAP32 = new Int32Array(buffer);+ var HEAPU8 = new Uint8Array(buffer);+ var HEAPU16 = new Uint16Array(buffer);+ var HEAPU32 = new Uint32Array(buffer);+ var HEAPF32 = new Float32Array(buffer);+ var HEAPF64 = new Float64Array(buffer);+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; // EMSCRIPTEN_START_FUNCS ; // EMSCRIPTEN_END_FUNCS ;+ bufferView = HEAPU8;+ initActiveSegments(env); function __wasm_memory_size() { return buffer.byteLength / 65536 | 0; }@@ -37,19 +64,19 @@ var newPages = oldPages + pagesToAdd | 0; if ((oldPages < newPages) && (newPages < 65536)) { var newBuffer = new ArrayBuffer(Math_imul(newPages, 65536));- var newHEAP8 = new global.Int8Array(newBuffer);+ var newHEAP8 = new Int8Array(newBuffer); newHEAP8.set(HEAP8);- HEAP8 = newHEAP8;- HEAP8 = new global.Int8Array(newBuffer);- HEAP16 = new global.Int16Array(newBuffer);- HEAP32 = new global.Int32Array(newBuffer);- HEAPU8 = new global.Uint8Array(newBuffer);- HEAPU16 = new global.Uint16Array(newBuffer);- HEAPU32 = new global.Uint32Array(newBuffer);- HEAPF32 = new global.Float32Array(newBuffer);- HEAPF64 = new global.Float64Array(newBuffer);+ HEAP8 = new Int8Array(newBuffer);+ HEAP16 = new Int16Array(newBuffer);+ HEAP32 = new Int32Array(newBuffer);+ HEAPU8 = new Uint8Array(newBuffer);+ HEAPU16 = new Uint16Array(newBuffer);+ HEAPU32 = new Uint32Array(newBuffer);+ HEAPF32 = new Float32Array(newBuffer);+ HEAPF64 = new Float64Array(newBuffer); buffer = newBuffer;- memory.buffer = newBuffer;+ memory.buffer = buffer;+ bufferView = HEAPU8; } return oldPages; }@@ -69,42 +96,5 @@ }; } -var bufferView = new Uint8Array(wasmMemory.buffer);-for (var base64ReverseLookup = new Uint8Array(123/*'z'+1*/), i = 25; i >= 0; --i) {- base64ReverseLookup[48+i] = 52+i; // '0-9'- base64ReverseLookup[65+i] = i; // 'A-Z'- base64ReverseLookup[97+i] = 26+i; // 'a-z'- }- base64ReverseLookup[43] = 62; // '+'- base64ReverseLookup[47] = 63; // '/'- /** @noinline Inlining this function would mean expanding the base64 string 4x times in the source code, which Closure seems to be happy to do. */- function base64DecodeToExistingUint8Array(uint8Array, offset, b64) {- var b1, b2, i = 0, j = offset, bLength = b64.length, end = offset + (bLength*3>>2) - (b64[bLength-2] == '=') - (b64[bLength-1] == '=');- for (; i < bLength; i += 4) {- b1 = base64ReverseLookup[b64.charCodeAt(i+1)];- b2 = base64ReverseLookup[b64.charCodeAt(i+2)];- uint8Array[j++] = base64ReverseLookup[b64.charCodeAt(i)] << 2 | b1 >> 4;- if (j < end) uint8Array[j++] = b1 << 4 | b2 >> 2;- if (j < end) uint8Array[j++] = b2 << 6 | base64ReverseLookup[b64.charCodeAt(i+3)];- }- return uint8Array; - }- base64DecodeToExistingUint8Array(bufferView, 1600, "YWJj");-return asmFunc({- 'Int8Array': Int8Array,- 'Int16Array': Int16Array,- 'Int32Array': Int32Array,- 'Uint8Array': Uint8Array,- 'Uint16Array': Uint16Array,- 'Uint32Array': Uint32Array,- 'Float32Array': Float32Array,- 'Float64Array': Float64Array,- 'NaN': NaN,- 'Infinity': Infinity,- 'Math': Math- },- asmLibraryArg,- wasmMemory.buffer-)-+ return asmFunc(asmLibraryArg); }
binaryen/test/wasm2js/emscripten.2asm.js view
@@ -1,28 +1,53 @@-function instantiate(asmLibraryArg, wasmMemory) {-function asmFunc(global, env) {- var memory = env.memory;- var buffer = memory.buffer;+function instantiate(asmLibraryArg) {+ var bufferView;+ var base64ReverseLookup = new Uint8Array(123/*'z'+1*/);+ for (var i = 25; i >= 0; --i) {+ base64ReverseLookup[48+i] = 52+i; // '0-9'+ base64ReverseLookup[65+i] = i; // 'A-Z'+ base64ReverseLookup[97+i] = 26+i; // 'a-z'+ }+ base64ReverseLookup[43] = 62; // '+'+ base64ReverseLookup[47] = 63; // '/'+ /** @noinline Inlining this function would mean expanding the base64 string 4x times in the source code, which Closure seems to be happy to do. */+ function base64DecodeToExistingUint8Array(uint8Array, offset, b64) {+ var b1, b2, i = 0, j = offset, bLength = b64.length, end = offset + (bLength*3>>2) - (b64[bLength-2] == '=') - (b64[bLength-1] == '=');+ for (; i < bLength; i += 4) {+ b1 = base64ReverseLookup[b64.charCodeAt(i+1)];+ b2 = base64ReverseLookup[b64.charCodeAt(i+2)];+ uint8Array[j++] = base64ReverseLookup[b64.charCodeAt(i)] << 2 | b1 >> 4;+ if (j < end) uint8Array[j++] = b1 << 4 | b2 >> 2;+ if (j < end) uint8Array[j++] = b2 << 6 | base64ReverseLookup[b64.charCodeAt(i+3)];+ }+ return uint8Array;+ }+function initActiveSegments(imports) {+ base64DecodeToExistingUint8Array(bufferView, 1024, "aGVsbG8sIHdvcmxkIQoAAJwMAAAtKyAgIDBYMHgAKG51bGwpAAAAAAAAAAAAAAAAEQAKABEREQAAAAAFAAAAAAAACQAAAAALAAAAAAAAAAARAA8KERERAwoHAAETCQsLAAAJBgsAAAsABhEAAAAREREAAAAAAAAAAAAAAAAAAAAACwAAAAAAAAAAEQAKChEREQAKAAACAAkLAAAACQALAAALAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAAAAAAAAAAAAwAAAAADAAAAAAJDAAAAAAADAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAANAAAABA0AAAAACQ4AAAAAAA4AAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAADwAAAAAPAAAAAAkQAAAAAAAQAAAQAAASAAAAEhISAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAASEhIAAAAAAAAJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALAAAAAAAAAAAAAAAKAAAAAAoAAAAACQsAAAAAAAsAAAsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAADAAAAAAMAAAAAAkMAAAAAAAMAAAMAAAwMTIzNDU2Nzg5QUJDREVGLTBYKzBYIDBYLTB4KzB4IDB4AGluZgBJTkYAbmFuAE5BTgAuAA==");+ base64DecodeToExistingUint8Array(bufferView, 1600, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=");+}+function asmFunc(env) {+ var buffer = new ArrayBuffer(16777216); var FUNCTION_TABLE = env.table;- var HEAP8 = new global.Int8Array(buffer);- var HEAP16 = new global.Int16Array(buffer);- var HEAP32 = new global.Int32Array(buffer);- var HEAPU8 = new global.Uint8Array(buffer);- var HEAPU16 = new global.Uint16Array(buffer);- var HEAPU32 = new global.Uint32Array(buffer);- var HEAPF32 = new global.Float32Array(buffer);- var HEAPF64 = new global.Float64Array(buffer);- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+ var HEAP8 = new Int8Array(buffer);+ var HEAP16 = new Int16Array(buffer);+ var HEAP32 = new Int32Array(buffer);+ var HEAPU8 = new Uint8Array(buffer);+ var HEAPU16 = new Uint16Array(buffer);+ var HEAPU32 = new Uint32Array(buffer);+ var HEAPF32 = new Float32Array(buffer);+ var HEAPF64 = new Float64Array(buffer);+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; var syscall$6 = env.__syscall6; var syscall$54 = env.__syscall54; // EMSCRIPTEN_START_FUNCS@@ -186,6 +211,8 @@ // EMSCRIPTEN_END_FUNCS ;+ bufferView = HEAPU8;+ initActiveSegments(env); FUNCTION_TABLE[1] = foo; FUNCTION_TABLE[2] = bar; FUNCTION_TABLE[3] = tabled;@@ -204,43 +231,5 @@ }; } -var bufferView = new Uint8Array(wasmMemory.buffer);-for (var base64ReverseLookup = new Uint8Array(123/*'z'+1*/), i = 25; i >= 0; --i) {- base64ReverseLookup[48+i] = 52+i; // '0-9'- base64ReverseLookup[65+i] = i; // 'A-Z'- base64ReverseLookup[97+i] = 26+i; // 'a-z'- }- base64ReverseLookup[43] = 62; // '+'- base64ReverseLookup[47] = 63; // '/'- /** @noinline Inlining this function would mean expanding the base64 string 4x times in the source code, which Closure seems to be happy to do. */- function base64DecodeToExistingUint8Array(uint8Array, offset, b64) {- var b1, b2, i = 0, j = offset, bLength = b64.length, end = offset + (bLength*3>>2) - (b64[bLength-2] == '=') - (b64[bLength-1] == '=');- for (; i < bLength; i += 4) {- b1 = base64ReverseLookup[b64.charCodeAt(i+1)];- b2 = base64ReverseLookup[b64.charCodeAt(i+2)];- uint8Array[j++] = base64ReverseLookup[b64.charCodeAt(i)] << 2 | b1 >> 4;- if (j < end) uint8Array[j++] = b1 << 4 | b2 >> 2;- if (j < end) uint8Array[j++] = b2 << 6 | base64ReverseLookup[b64.charCodeAt(i+3)];- }- return uint8Array; - }- base64DecodeToExistingUint8Array(bufferView, 1024, "aGVsbG8sIHdvcmxkIQoAAJwMAAAtKyAgIDBYMHgAKG51bGwpAAAAAAAAAAAAAAAAEQAKABEREQAAAAAFAAAAAAAACQAAAAALAAAAAAAAAAARAA8KERERAwoHAAETCQsLAAAJBgsAAAsABhEAAAAREREAAAAAAAAAAAAAAAAAAAAACwAAAAAAAAAAEQAKChEREQAKAAACAAkLAAAACQALAAALAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAAAAAAAAAAAAwAAAAADAAAAAAJDAAAAAAADAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAANAAAABA0AAAAACQ4AAAAAAA4AAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAADwAAAAAPAAAAAAkQAAAAAAAQAAAQAAASAAAAEhISAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAASEhIAAAAAAAAJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALAAAAAAAAAAAAAAAKAAAAAAoAAAAACQsAAAAAAAsAAAsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAADAAAAAAMAAAAAAkMAAAAAAAMAAAMAAAwMTIzNDU2Nzg5QUJDREVGLTBYKzBYIDBYLTB4KzB4IDB4AGluZgBJTkYAbmFuAE5BTgAuAA==");-base64DecodeToExistingUint8Array(bufferView, 1600, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=");-return asmFunc({- 'Int8Array': Int8Array,- 'Int16Array': Int16Array,- 'Int32Array': Int32Array,- 'Uint8Array': Uint8Array,- 'Uint16Array': Uint16Array,- 'Uint32Array': Uint32Array,- 'Float32Array': Float32Array,- 'Float64Array': Float64Array,- 'NaN': NaN,- 'Infinity': Infinity,- 'Math': Math- },- asmLibraryArg,- wasmMemory.buffer-)-+ return asmFunc(asmLibraryArg); }
binaryen/test/wasm2js/emscripten.2asm.js.opt view
@@ -1,28 +1,65 @@-function instantiate(asmLibraryArg, wasmMemory) {-function asmFunc(global, env) {- var memory = env.memory;- var buffer = memory.buffer;+function instantiate(asmLibraryArg) {+ var bufferView;+ var base64ReverseLookup = new Uint8Array(123/*'z'+1*/);+ for (var i = 25; i >= 0; --i) {+ base64ReverseLookup[48+i] = 52+i; // '0-9'+ base64ReverseLookup[65+i] = i; // 'A-Z'+ base64ReverseLookup[97+i] = 26+i; // 'a-z'+ }+ base64ReverseLookup[43] = 62; // '+'+ base64ReverseLookup[47] = 63; // '/'+ /** @noinline Inlining this function would mean expanding the base64 string 4x times in the source code, which Closure seems to be happy to do. */+ function base64DecodeToExistingUint8Array(uint8Array, offset, b64) {+ var b1, b2, i = 0, j = offset, bLength = b64.length, end = offset + (bLength*3>>2) - (b64[bLength-2] == '=') - (b64[bLength-1] == '=');+ for (; i < bLength; i += 4) {+ b1 = base64ReverseLookup[b64.charCodeAt(i+1)];+ b2 = base64ReverseLookup[b64.charCodeAt(i+2)];+ uint8Array[j++] = base64ReverseLookup[b64.charCodeAt(i)] << 2 | b1 >> 4;+ if (j < end) uint8Array[j++] = b1 << 4 | b2 >> 2;+ if (j < end) uint8Array[j++] = b2 << 6 | base64ReverseLookup[b64.charCodeAt(i+3)];+ }+ return uint8Array;+ }+function initActiveSegments(imports) {+ base64DecodeToExistingUint8Array(bufferView, 1024, "aGVsbG8sIHdvcmxkIQoAAJwMAAAtKyAgIDBYMHgAKG51bGwp");+ base64DecodeToExistingUint8Array(bufferView, 1072, "EQAKABEREQAAAAAFAAAAAAAACQAAAAALAAAAAAAAAAARAA8KERERAwoHAAETCQsLAAAJBgsAAAsABhEAAAARERE=");+ base64DecodeToExistingUint8Array(bufferView, 1153, "CwAAAAAAAAAAEQAKChEREQAKAAACAAkLAAAACQALAAAL");+ base64DecodeToExistingUint8Array(bufferView, 1211, "DA==");+ base64DecodeToExistingUint8Array(bufferView, 1223, "DAAAAAAMAAAAAAkMAAAAAAAMAAAM");+ base64DecodeToExistingUint8Array(bufferView, 1269, "Dg==");+ base64DecodeToExistingUint8Array(bufferView, 1281, "DQAAAAQNAAAAAAkOAAAAAAAOAAAO");+ base64DecodeToExistingUint8Array(bufferView, 1327, "EA==");+ base64DecodeToExistingUint8Array(bufferView, 1339, "DwAAAAAPAAAAAAkQAAAAAAAQAAAQAAASAAAAEhIS");+ base64DecodeToExistingUint8Array(bufferView, 1394, "EgAAABISEgAAAAAAAAk=");+ base64DecodeToExistingUint8Array(bufferView, 1443, "Cw==");+ base64DecodeToExistingUint8Array(bufferView, 1455, "CgAAAAAKAAAAAAkLAAAAAAALAAAL");+ base64DecodeToExistingUint8Array(bufferView, 1501, "DA==");+ base64DecodeToExistingUint8Array(bufferView, 1513, "DAAAAAAMAAAAAAkMAAAAAAAMAAAMAAAwMTIzNDU2Nzg5QUJDREVGLTBYKzBYIDBYLTB4KzB4IDB4AGluZgBJTkYAbmFuAE5BTgAu");+}+function asmFunc(env) {+ var buffer = new ArrayBuffer(16777216); var FUNCTION_TABLE = env.table;- var HEAP8 = new global.Int8Array(buffer);- var HEAP16 = new global.Int16Array(buffer);- var HEAP32 = new global.Int32Array(buffer);- var HEAPU8 = new global.Uint8Array(buffer);- var HEAPU16 = new global.Uint16Array(buffer);- var HEAPU32 = new global.Uint32Array(buffer);- var HEAPF32 = new global.Float32Array(buffer);- var HEAPF64 = new global.Float64Array(buffer);- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+ var HEAP8 = new Int8Array(buffer);+ var HEAP16 = new Int16Array(buffer);+ var HEAP32 = new Int32Array(buffer);+ var HEAPU8 = new Uint8Array(buffer);+ var HEAPU16 = new Uint16Array(buffer);+ var HEAPU32 = new Uint32Array(buffer);+ var HEAPF32 = new Float32Array(buffer);+ var HEAPF64 = new Float64Array(buffer);+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; var syscall$6 = env.__syscall6; var syscall$54 = env.__syscall54; // EMSCRIPTEN_START_FUNCS@@ -167,6 +204,8 @@ // EMSCRIPTEN_END_FUNCS ;+ bufferView = HEAPU8;+ initActiveSegments(env); FUNCTION_TABLE[1] = foo; FUNCTION_TABLE[2] = bar; FUNCTION_TABLE[3] = internal;@@ -185,55 +224,5 @@ }; } -var bufferView = new Uint8Array(wasmMemory.buffer);-for (var base64ReverseLookup = new Uint8Array(123/*'z'+1*/), i = 25; i >= 0; --i) {- base64ReverseLookup[48+i] = 52+i; // '0-9'- base64ReverseLookup[65+i] = i; // 'A-Z'- base64ReverseLookup[97+i] = 26+i; // 'a-z'- }- base64ReverseLookup[43] = 62; // '+'- base64ReverseLookup[47] = 63; // '/'- /** @noinline Inlining this function would mean expanding the base64 string 4x times in the source code, which Closure seems to be happy to do. */- function base64DecodeToExistingUint8Array(uint8Array, offset, b64) {- var b1, b2, i = 0, j = offset, bLength = b64.length, end = offset + (bLength*3>>2) - (b64[bLength-2] == '=') - (b64[bLength-1] == '=');- for (; i < bLength; i += 4) {- b1 = base64ReverseLookup[b64.charCodeAt(i+1)];- b2 = base64ReverseLookup[b64.charCodeAt(i+2)];- uint8Array[j++] = base64ReverseLookup[b64.charCodeAt(i)] << 2 | b1 >> 4;- if (j < end) uint8Array[j++] = b1 << 4 | b2 >> 2;- if (j < end) uint8Array[j++] = b2 << 6 | base64ReverseLookup[b64.charCodeAt(i+3)];- }- return uint8Array; - }- base64DecodeToExistingUint8Array(bufferView, 1024, "aGVsbG8sIHdvcmxkIQoAAJwMAAAtKyAgIDBYMHgAKG51bGwp");-base64DecodeToExistingUint8Array(bufferView, 1072, "EQAKABEREQAAAAAFAAAAAAAACQAAAAALAAAAAAAAAAARAA8KERERAwoHAAETCQsLAAAJBgsAAAsABhEAAAARERE=");-base64DecodeToExistingUint8Array(bufferView, 1153, "CwAAAAAAAAAAEQAKChEREQAKAAACAAkLAAAACQALAAAL");-base64DecodeToExistingUint8Array(bufferView, 1211, "DA==");-base64DecodeToExistingUint8Array(bufferView, 1223, "DAAAAAAMAAAAAAkMAAAAAAAMAAAM");-base64DecodeToExistingUint8Array(bufferView, 1269, "Dg==");-base64DecodeToExistingUint8Array(bufferView, 1281, "DQAAAAQNAAAAAAkOAAAAAAAOAAAO");-base64DecodeToExistingUint8Array(bufferView, 1327, "EA==");-base64DecodeToExistingUint8Array(bufferView, 1339, "DwAAAAAPAAAAAAkQAAAAAAAQAAAQAAASAAAAEhIS");-base64DecodeToExistingUint8Array(bufferView, 1394, "EgAAABISEgAAAAAAAAk=");-base64DecodeToExistingUint8Array(bufferView, 1443, "Cw==");-base64DecodeToExistingUint8Array(bufferView, 1455, "CgAAAAAKAAAAAAkLAAAAAAALAAAL");-base64DecodeToExistingUint8Array(bufferView, 1501, "DA==");-base64DecodeToExistingUint8Array(bufferView, 1513, "DAAAAAAMAAAAAAkMAAAAAAAMAAAMAAAwMTIzNDU2Nzg5QUJDREVGLTBYKzBYIDBYLTB4KzB4IDB4AGluZgBJTkYAbmFuAE5BTgAu");-return asmFunc({- 'Int8Array': Int8Array,- 'Int16Array': Int16Array,- 'Int32Array': Int32Array,- 'Uint8Array': Uint8Array,- 'Uint16Array': Uint16Array,- 'Uint32Array': Uint32Array,- 'Float32Array': Float32Array,- 'Float64Array': Float64Array,- 'NaN': NaN,- 'Infinity': Infinity,- 'Math': Math- },- asmLibraryArg,- wasmMemory.buffer-)-+ return asmFunc(asmLibraryArg); }
binaryen/test/wasm2js/emscripten.wast view
@@ -1,6 +1,6 @@ (module (type $0 (func))- (import "env" "memory" (memory $8 256 256))+ (memory $8 256 256) (data (i32.const 1024) "hello, world!\n\00\00\9c\0c\00\00-+ 0X0x\00(null)\00\00\00\00\00\00\00\00\00\00\00\00\11\00\n\00\11\11\11\00\00\00\00\05\00\00\00\00\00\00\t\00\00\00\00\0b\00\00\00\00\00\00\00\00\11\00\0f\n\11\11\11\03\n\07\00\01\13\t\0b\0b\00\00\t\06\0b\00\00\0b\00\06\11\00\00\00\11\11\11\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\0b\00\00\00\00\00\00\00\00\11\00\n\n\11\11\11\00\n\00\00\02\00\t\0b\00\00\00\t\00\0b\00\00\0b\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\0c\00\00\00\00\00\00\00\00\00\00\00\0c\00\00\00\00\0c\00\00\00\00\t\0c\00\00\00\00\00\0c\00\00\0c\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\0e\00\00\00\00\00\00\00\00\00\00\00\0d\00\00\00\04\0d\00\00\00\00\t\0e\00\00\00\00\00\0e\00\00\0e\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\10\00\00\00\00\00\00\00\00\00\00\00\0f\00\00\00\00\0f\00\00\00\00\t\10\00\00\00\00\00\10\00\00\10\00\00\12\00\00\00\12\12\12\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\12\00\00\00\12\12\12\00\00\00\00\00\00\t\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\0b\00\00\00\00\00\00\00\00\00\00\00\n\00\00\00\00\n\00\00\00\00\t\0b\00\00\00\00\00\0b\00\00\0b\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\0c\00\00\00\00\00\00\00\00\00\00\00\0c\00\00\00\00\0c\00\00\00\00\t\0c\00\00\00\00\00\0c\00\00\0c\00\000123456789ABCDEF-0X+0X 0X-0x+0x 0x\00inf\00INF\00nan\00NAN\00.\00") (data (i32.const 1600) "\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00") (import "env" "table" (table $timport$9 7 funcref))
binaryen/test/wasm2js/endianness.2asm.js view
@@ -1,5 +1,6 @@ import { setTempRet0 } from 'env'; + var bufferView; var scratchBuffer = new ArrayBuffer(16); var i32ScratchView = new Int32Array(scratchBuffer);@@ -30,27 +31,29 @@ return f32ScratchView[2]; } -function asmFunc(global, env, buffer) {- var HEAP8 = new global.Int8Array(buffer);- var HEAP16 = new global.Int16Array(buffer);- var HEAP32 = new global.Int32Array(buffer);- var HEAPU8 = new global.Uint8Array(buffer);- var HEAPU16 = new global.Uint16Array(buffer);- var HEAPU32 = new global.Uint32Array(buffer);- var HEAPF32 = new global.Float32Array(buffer);- var HEAPF64 = new global.Float64Array(buffer);- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var buffer = new ArrayBuffer(65536);+ var HEAP8 = new Int8Array(buffer);+ var HEAP16 = new Int16Array(buffer);+ var HEAP32 = new Int32Array(buffer);+ var HEAPU8 = new Uint8Array(buffer);+ var HEAPU16 = new Uint16Array(buffer);+ var HEAPU32 = new Uint32Array(buffer);+ var HEAPF32 = new Float32Array(buffer);+ var HEAPF64 = new Float64Array(buffer);+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; var setTempRet0 = env.setTempRet0; var i64toi32_i32$HIGH_BITS = 0; function i16_store_little(address, value) {@@ -649,6 +652,7 @@ return $2 | 0; } + bufferView = HEAPU8; function __wasm_memory_size() { return buffer.byteLength / 65536 | 0; }@@ -659,18 +663,18 @@ var newPages = oldPages + pagesToAdd | 0; if ((oldPages < newPages) && (newPages < 65536)) { var newBuffer = new ArrayBuffer(Math_imul(newPages, 65536));- var newHEAP8 = new global.Int8Array(newBuffer);+ var newHEAP8 = new Int8Array(newBuffer); newHEAP8.set(HEAP8);- HEAP8 = newHEAP8;- HEAP8 = new global.Int8Array(newBuffer);- HEAP16 = new global.Int16Array(newBuffer);- HEAP32 = new global.Int32Array(newBuffer);- HEAPU8 = new global.Uint8Array(newBuffer);- HEAPU16 = new global.Uint16Array(newBuffer);- HEAPU32 = new global.Uint32Array(newBuffer);- HEAPF32 = new global.Float32Array(newBuffer);- HEAPF64 = new global.Float64Array(newBuffer);+ HEAP8 = new Int8Array(newBuffer);+ HEAP16 = new Int16Array(newBuffer);+ HEAP32 = new Int32Array(newBuffer);+ HEAPU8 = new Uint8Array(newBuffer);+ HEAPU16 = new Uint16Array(newBuffer);+ HEAPU32 = new Uint32Array(newBuffer);+ HEAPF32 = new Float32Array(newBuffer);+ HEAPF64 = new Float64Array(newBuffer); buffer = newBuffer;+ bufferView = HEAPU8; } return oldPages; }@@ -696,26 +700,9 @@ }; } -var memasmFunc = new ArrayBuffer(65536);-var bufferView = new Uint8Array(memasmFunc);-var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); },+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }, setTempRet0- },- memasmFunc-);+ }); export var i32_load16_s = retasmFunc.i32_load16_s; export var i32_load16_u = retasmFunc.i32_load16_u; export var i32_load = retasmFunc.i32_load;
binaryen/test/wasm2js/excess_fallthrough.2asm.js view
@@ -1,37 +1,40 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function bar() { } function foo($0) { $0 = $0 | 0;- label$5 : {- bar();- block : {- switch (123 | 0) {- case 0:- bar();- break;- default:- break label$5;- };+ label$4 : while (1) {+ label$5 : {+ bar();+ block : {+ switch (123 | 0) {+ case 0:+ bar();+ break;+ default:+ break label$5;+ };+ }+ return; }- return;- }- abort();+ abort();+ }; } return {@@ -39,19 +42,6 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } }); export var foo = retasmFunc.foo;
binaryen/test/wasm2js/excess_fallthrough.2asm.js.opt view
@@ -1,17 +1,18 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function foo($0) { $0 = $0 | 0; abort();@@ -22,19 +23,6 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } }); export var foo = retasmFunc.foo;
binaryen/test/wasm2js/f32.2asm.js view
@@ -1,17 +1,18 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function $0(x, y) { x = Math_fround(x); y = Math_fround(y);@@ -65,7 +66,7 @@ function $9(x) { x = Math_fround(x);- return Math_fround(Math_fround(__wasm_trunc_f32(Math_fround(x))));+ return Math_fround(Math_fround(Math_trunc(x))); } function $10(x) {@@ -91,11 +92,6 @@ return Math_fround(var$1); } - function __wasm_trunc_f32(var$0) {- var$0 = Math_fround(var$0);- return Math_fround(var$0 < Math_fround(0.0) ? Math_fround(Math_ceil(var$0)) : Math_fround(Math_floor(var$0)));- }- return { "add": $0, "sub": $1, @@ -111,20 +107,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } }); export var add = retasmFunc.add; export var sub = retasmFunc.sub;
binaryen/test/wasm2js/f32_cmp.2asm.js view
@@ -1,17 +1,18 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function $0(x, y) { x = Math_fround(x); y = Math_fround(y);@@ -58,20 +59,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } }); export var eq = retasmFunc.eq; export var ne = retasmFunc.ne;
binaryen/test/wasm2js/f64_cmp.2asm.js view
@@ -1,17 +1,18 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function $0(x, y) { x = +x; y = +y;@@ -58,20 +59,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } }); export var eq = retasmFunc.eq; export var ne = retasmFunc.ne;
binaryen/test/wasm2js/fac.2asm.js view
@@ -1,18 +1,19 @@ import { setTempRet0 } from 'env'; -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; var setTempRet0 = env.setTempRet0; var i64toi32_i32$HIGH_BITS = 0; function $0($0_1, $0$hi) {@@ -573,20 +574,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); },+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }, setTempRet0 }); export var fac_rec = retasmFunc.fac_rec;
binaryen/test/wasm2js/float-ops.2asm.js view
@@ -1,17 +1,18 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function $1($0, $1_1) { $0 = Math_fround($0); $1_1 = Math_fround($1_1);@@ -504,20 +505,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } }); export var f32_add = retasmFunc.f32_add; export var f32_sub = retasmFunc.f32_sub;
binaryen/test/wasm2js/float-ops.2asm.js.opt view
@@ -1,17 +1,18 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function $1($0, $1_1) { $0 = Math_fround($0); $1_1 = Math_fround($1_1);@@ -238,12 +239,12 @@ function $47($0) { $0 = Math_fround($0);- return !(~~$0 >>> 0 | (Math_fround(Math_abs($0)) >= Math_fround(1.0) ? ($0 > Math_fround(0.0) ? ~~Math_fround(Math_min(Math_fround(Math_floor(Math_fround($0 / Math_fround(4294967296.0)))), Math_fround(4294967296.0))) >>> 0 : ~~Math_fround(Math_ceil(Math_fround(Math_fround($0 - Math_fround(~~$0 >>> 0 >>> 0)) / Math_fround(4294967296.0)))) >>> 0) : 0)) | 0;+ return !(~~$0 >>> 0 | (Math_fround(Math_abs($0)) >= Math_fround(1.0) ? ($0 > Math_fround(0.0) ? ~~Math_fround(Math_min(Math_fround(Math_floor(Math_fround($0 * Math_fround(2.3283064365386963e-10)))), Math_fround(4294967296.0))) >>> 0 : ~~Math_fround(Math_ceil(Math_fround(Math_fround($0 - Math_fround(~~$0 >>> 0 >>> 0)) * Math_fround(2.3283064365386963e-10)))) >>> 0) : 0)) | 0; } function $48($0) { $0 = +$0;- return !(~~$0 >>> 0 | (Math_abs($0) >= 1.0 ? ($0 > 0.0 ? ~~Math_min(Math_floor($0 / 4294967296.0), 4294967295.0) >>> 0 : ~~Math_ceil(($0 - +(~~$0 >>> 0 >>> 0)) / 4294967296.0) >>> 0) : 0)) | 0;+ return !(~~$0 >>> 0 | (Math_abs($0) >= 1.0 ? ($0 > 0.0 ? ~~Math_min(Math_floor($0 * 2.3283064365386963e-10), 4294967295.0) >>> 0 : ~~Math_ceil(($0 - +(~~$0 >>> 0 >>> 0)) * 2.3283064365386963e-10) >>> 0) : 0)) | 0; } function legalstub$43($0, $1_1) {@@ -314,20 +315,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } }); export var f32_add = retasmFunc.f32_add; export var f32_sub = retasmFunc.f32_sub;
binaryen/test/wasm2js/float_literals-modified.2asm.js view
@@ -18,19 +18,20 @@ f32ScratchView[2] = value; } -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; var setTempRet0 = env.setTempRet0; var i64toi32_i32$HIGH_BITS = 0; function $0() {@@ -1147,20 +1148,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); },+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }, setTempRet0 }); export var f32_nan = retasmFunc.f32_nan;
binaryen/test/wasm2js/float_literals-modified.2asm.js.opt view
@@ -14,19 +14,20 @@ f64ScratchView[0] = value; } -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; var setTempRet0 = env.setTempRet0; var i64toi32_i32$HIGH_BITS = 0; function $0() {@@ -363,20 +364,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); },+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }, setTempRet0 }); export var f32_nan = retasmFunc.f32_nan;
binaryen/test/wasm2js/float_misc.2asm.js view
@@ -29,19 +29,20 @@ f32ScratchView[2] = value; } -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function $0(x, y) { x = Math_fround(x); y = Math_fround(y);@@ -99,7 +100,7 @@ function $10(x) { x = Math_fround(x);- return Math_fround(Math_fround(__wasm_trunc_f32(Math_fround(x))));+ return Math_fround(Math_fround(Math_trunc(x))); } function $11(x) {@@ -200,7 +201,7 @@ function $24(x) { x = +x;- return +(+__wasm_trunc_f64(+x));+ return +Math_trunc(x); } function $25(x) {@@ -256,16 +257,6 @@ return +var$1; } - function __wasm_trunc_f32(var$0) {- var$0 = Math_fround(var$0);- return Math_fround(var$0 < Math_fround(0.0) ? Math_fround(Math_ceil(var$0)) : Math_fround(Math_floor(var$0)));- }- - function __wasm_trunc_f64(var$0) {- var$0 = +var$0;- return +(var$0 < 0.0 ? Math_ceil(var$0) : Math_floor(var$0));- }- return { "f32_add": $0, "f32_sub": $1, @@ -298,20 +289,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } }); export var f32_add = retasmFunc.f32_add; export var f32_sub = retasmFunc.f32_sub;
binaryen/test/wasm2js/forward.2asm.js view
@@ -1,17 +1,18 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function even(n) { n = n | 0; var $10 = 0;@@ -40,20 +41,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } }); export var even = retasmFunc.even; export var odd = retasmFunc.odd;
binaryen/test/wasm2js/func-ptr-offset.2asm.js view
@@ -1,17 +1,18 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function t1() { return 1 | 0; }@@ -35,19 +36,6 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } }); export var call = retasmFunc.call;
binaryen/test/wasm2js/func-ptr-offset.2asm.js.opt view
@@ -1,17 +1,18 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function t1() { return 1; }@@ -35,19 +36,6 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } }); export var call = retasmFunc.call;
binaryen/test/wasm2js/func_ptrs.2asm.js view
@@ -1,18 +1,19 @@ import { print_i32 } from 'spectest'; -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; var print = env.print_i32; function $3() { return 13 | 0;@@ -41,20 +42,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); },+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }, print_i32 }); export var one = retasmFunc.one;@@ -62,19 +50,20 @@ export var three = retasmFunc.three; export var four = retasmFunc.four; -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function t1() { return 1 | 0; }@@ -112,37 +101,25 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } }); export var callt = retasmFunc.callt; export var callu = retasmFunc.callu; -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function t1() { return 1 | 0; }@@ -162,19 +139,6 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } }); export var callt = retasmFunc.callt;
binaryen/test/wasm2js/get-set-local.2asm.js view
@@ -1,17 +1,18 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function $1($0, r, r$hi) { $0 = $0 | 0; r = r | 0;@@ -60,19 +61,6 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } }); export var check_extend_ui32 = retasmFunc.check_extend_ui32;
binaryen/test/wasm2js/get-set-local.2asm.js.opt view
@@ -1,17 +1,18 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function legalstub$1($0, $1, $2) { return !$2 & ($0 | 0) == ($1 | 0); }@@ -21,19 +22,6 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } }); export var check_extend_ui32 = retasmFunc.check_extend_ui32;
binaryen/test/wasm2js/get_local.2asm.js view
@@ -1,18 +1,19 @@ import { setTempRet0 } from 'env'; -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; var setTempRet0 = env.setTempRet0; var i64toi32_i32$HIGH_BITS = 0; function $0() {@@ -240,20 +241,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); },+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }, setTempRet0 }); export var type_local_i32 = retasmFunc.type_local_i32;
binaryen/test/wasm2js/global_i64.2asm.js view
@@ -1,17 +1,18 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; var f = -1412567121; var f$hi = 305419896; function call($0, $0$hi) {@@ -33,19 +34,6 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } }); export var exp = retasmFunc.exp;
binaryen/test/wasm2js/global_i64.2asm.js.opt view
@@ -1,17 +1,18 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function $1() { }@@ -21,19 +22,6 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } }); export var exp = retasmFunc.exp;
binaryen/test/wasm2js/grow-memory-tricky.2asm.js view
@@ -1,25 +1,27 @@ -function asmFunc(global, env, buffer) {- var HEAP8 = new global.Int8Array(buffer);- var HEAP16 = new global.Int16Array(buffer);- var HEAP32 = new global.Int32Array(buffer);- var HEAPU8 = new global.Uint8Array(buffer);- var HEAPU16 = new global.Uint16Array(buffer);- var HEAPU32 = new global.Uint32Array(buffer);- var HEAPF32 = new global.Float32Array(buffer);- var HEAPF64 = new global.Float64Array(buffer);- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var buffer = new ArrayBuffer(65536);+ var HEAP8 = new Int8Array(buffer);+ var HEAP16 = new Int16Array(buffer);+ var HEAP32 = new Int32Array(buffer);+ var HEAPU8 = new Uint8Array(buffer);+ var HEAPU16 = new Uint16Array(buffer);+ var HEAPU32 = new Uint32Array(buffer);+ var HEAPF32 = new Float32Array(buffer);+ var HEAPF64 = new Float64Array(buffer);+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function $0() { var wasm2js_i32$0 = 0, wasm2js_i32$1 = 0; (wasm2js_i32$0 = 0, wasm2js_i32$1 = __wasm_memory_grow(1 | 0)), HEAP32[wasm2js_i32$0 >> 2] = wasm2js_i32$1;@@ -46,17 +48,16 @@ var newPages = oldPages + pagesToAdd | 0; if ((oldPages < newPages) && (newPages < 65536)) { var newBuffer = new ArrayBuffer(Math_imul(newPages, 65536));- var newHEAP8 = new global.Int8Array(newBuffer);+ var newHEAP8 = new Int8Array(newBuffer); newHEAP8.set(HEAP8);- HEAP8 = newHEAP8;- HEAP8 = new global.Int8Array(newBuffer);- HEAP16 = new global.Int16Array(newBuffer);- HEAP32 = new global.Int32Array(newBuffer);- HEAPU8 = new global.Uint8Array(newBuffer);- HEAPU16 = new global.Uint16Array(newBuffer);- HEAPU32 = new global.Uint32Array(newBuffer);- HEAPF32 = new global.Float32Array(newBuffer);- HEAPF64 = new global.Float64Array(newBuffer);+ HEAP8 = new Int8Array(newBuffer);+ HEAP16 = new Int16Array(newBuffer);+ HEAP32 = new Int32Array(newBuffer);+ HEAPU8 = new Uint8Array(newBuffer);+ HEAPU16 = new Uint16Array(newBuffer);+ HEAPU32 = new Uint32Array(newBuffer);+ HEAPF32 = new Float32Array(newBuffer);+ HEAPF64 = new Float64Array(newBuffer); buffer = newBuffer; } return oldPages;@@ -79,25 +80,8 @@ }; } -var memasmFunc = new ArrayBuffer(65536);-var bufferView = new Uint8Array(memasmFunc);-var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }- },- memasmFunc-);+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }+ }); export var memory = retasmFunc.memory; export var f1 = retasmFunc.f1; export var f2 = retasmFunc.f2;
binaryen/test/wasm2js/grow-memory-tricky.2asm.js.opt view
@@ -1,25 +1,27 @@ -function asmFunc(global, env, buffer) {- var HEAP8 = new global.Int8Array(buffer);- var HEAP16 = new global.Int16Array(buffer);- var HEAP32 = new global.Int32Array(buffer);- var HEAPU8 = new global.Uint8Array(buffer);- var HEAPU16 = new global.Uint16Array(buffer);- var HEAPU32 = new global.Uint32Array(buffer);- var HEAPF32 = new global.Float32Array(buffer);- var HEAPF64 = new global.Float64Array(buffer);- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var buffer = new ArrayBuffer(65536);+ var HEAP8 = new Int8Array(buffer);+ var HEAP16 = new Int16Array(buffer);+ var HEAP32 = new Int32Array(buffer);+ var HEAPU8 = new Uint8Array(buffer);+ var HEAPU16 = new Uint16Array(buffer);+ var HEAPU32 = new Uint32Array(buffer);+ var HEAPF32 = new Float32Array(buffer);+ var HEAPF64 = new Float64Array(buffer);+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function $0() { var wasm2js_i32$0 = 0, wasm2js_i32$1 = 0; (wasm2js_i32$0 = 0, wasm2js_i32$1 = __wasm_memory_grow(1)), HEAP32[wasm2js_i32$0 >> 2] = wasm2js_i32$1;@@ -36,17 +38,16 @@ var newPages = oldPages + pagesToAdd | 0; if ((oldPages < newPages) && (newPages < 65536)) { var newBuffer = new ArrayBuffer(Math_imul(newPages, 65536));- var newHEAP8 = new global.Int8Array(newBuffer);+ var newHEAP8 = new Int8Array(newBuffer); newHEAP8.set(HEAP8);- HEAP8 = newHEAP8;- HEAP8 = new global.Int8Array(newBuffer);- HEAP16 = new global.Int16Array(newBuffer);- HEAP32 = new global.Int32Array(newBuffer);- HEAPU8 = new global.Uint8Array(newBuffer);- HEAPU16 = new global.Uint16Array(newBuffer);- HEAPU32 = new global.Uint32Array(newBuffer);- HEAPF32 = new global.Float32Array(newBuffer);- HEAPF64 = new global.Float64Array(newBuffer);+ HEAP8 = new Int8Array(newBuffer);+ HEAP16 = new Int16Array(newBuffer);+ HEAP32 = new Int32Array(newBuffer);+ HEAPU8 = new Uint8Array(newBuffer);+ HEAPU16 = new Uint16Array(newBuffer);+ HEAPU32 = new Uint32Array(newBuffer);+ HEAPF32 = new Float32Array(newBuffer);+ HEAPF64 = new Float64Array(newBuffer); buffer = newBuffer; } return oldPages;@@ -69,25 +70,8 @@ }; } -var memasmFunc = new ArrayBuffer(65536);-var bufferView = new Uint8Array(memasmFunc);-var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }- },- memasmFunc-);+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }+ }); export var memory = retasmFunc.memory; export var f1 = retasmFunc.f1; export var f2 = retasmFunc.f2;
binaryen/test/wasm2js/grow_memory.2asm.js view
@@ -1,25 +1,27 @@ -function asmFunc(global, env, buffer) {- var HEAP8 = new global.Int8Array(buffer);- var HEAP16 = new global.Int16Array(buffer);- var HEAP32 = new global.Int32Array(buffer);- var HEAPU8 = new global.Uint8Array(buffer);- var HEAPU16 = new global.Uint16Array(buffer);- var HEAPU32 = new global.Uint32Array(buffer);- var HEAPF32 = new global.Float32Array(buffer);- var HEAPF64 = new global.Float64Array(buffer);- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var buffer = new ArrayBuffer(65536);+ var HEAP8 = new Int8Array(buffer);+ var HEAP16 = new Int16Array(buffer);+ var HEAP32 = new Int32Array(buffer);+ var HEAPU8 = new Uint8Array(buffer);+ var HEAPU16 = new Uint16Array(buffer);+ var HEAPU32 = new Uint32Array(buffer);+ var HEAPF32 = new Float32Array(buffer);+ var HEAPF64 = new Float64Array(buffer);+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function $0(var$0) { var$0 = var$0 | 0; return __wasm_memory_grow(var$0 | 0) | 0;@@ -39,17 +41,16 @@ var newPages = oldPages + pagesToAdd | 0; if ((oldPages < newPages) && (newPages < 65536)) { var newBuffer = new ArrayBuffer(Math_imul(newPages, 65536));- var newHEAP8 = new global.Int8Array(newBuffer);+ var newHEAP8 = new Int8Array(newBuffer); newHEAP8.set(HEAP8);- HEAP8 = newHEAP8;- HEAP8 = new global.Int8Array(newBuffer);- HEAP16 = new global.Int16Array(newBuffer);- HEAP32 = new global.Int32Array(newBuffer);- HEAPU8 = new global.Uint8Array(newBuffer);- HEAPU16 = new global.Uint16Array(newBuffer);- HEAPU32 = new global.Uint32Array(newBuffer);- HEAPF32 = new global.Float32Array(newBuffer);- HEAPF64 = new global.Float64Array(newBuffer);+ HEAP8 = new Int8Array(newBuffer);+ HEAP16 = new Int16Array(newBuffer);+ HEAP32 = new Int32Array(newBuffer);+ HEAPU8 = new Uint8Array(newBuffer);+ HEAPU16 = new Uint16Array(newBuffer);+ HEAPU32 = new Uint32Array(newBuffer);+ HEAPF32 = new Float32Array(newBuffer);+ HEAPF64 = new Float64Array(newBuffer); buffer = newBuffer; } return oldPages;@@ -72,25 +73,8 @@ }; } -var memasmFunc = new ArrayBuffer(65536);-var bufferView = new Uint8Array(memasmFunc);-var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }- },- memasmFunc-);+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }+ }); export var memory = retasmFunc.memory; export var grow = retasmFunc.grow; export var current = retasmFunc.current;
binaryen/test/wasm2js/i32.2asm.js view
@@ -1,17 +1,18 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function $0(x, y) { x = x | 0; y = y | 0;@@ -258,20 +259,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } }); export var add = retasmFunc.add; export var sub = retasmFunc.sub;
binaryen/test/wasm2js/i64-add-sub.2asm.js view
@@ -1,17 +1,18 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function $1($0, $0$hi, $1_1, $1$hi, r, r$hi) { $0 = $0 | 0; $0$hi = $0$hi | 0;@@ -229,20 +230,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } }); export var check_add_i64 = retasmFunc.check_add_i64; export var check_sub_i64 = retasmFunc.check_sub_i64;
binaryen/test/wasm2js/i64-add-sub.2asm.js.opt view
@@ -1,17 +1,18 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function $1($0, $1_1, $2, $3, $4, $5) { $0 = $0 | 0; $1_1 = $1_1 | 0;@@ -21,9 +22,7 @@ $5 = $5 | 0; $1_1 = $1_1 + $3 | 0; $0 = $0 + $2 | 0;- if ($0 >>> 0 < $2 >>> 0) {- $1_1 = $1_1 + 1 | 0- }+ $1_1 = $2 >>> 0 > $0 >>> 0 ? $1_1 + 1 | 0 : $1_1; return ($0 | 0) == ($4 | 0) & ($1_1 | 0) == ($5 | 0); } @@ -41,20 +40,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } }); export var check_add_i64 = retasmFunc.check_add_i64; export var check_sub_i64 = retasmFunc.check_sub_i64;
binaryen/test/wasm2js/i64-ctz.2asm.js view
@@ -1,18 +1,19 @@ import { setTempRet0 } from 'env'; -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; var setTempRet0 = env.setTempRet0; var i64toi32_i32$HIGH_BITS = 0; function popcnt64($0, $0$hi) {@@ -232,20 +233,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); },+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }, setTempRet0 }); export var a = retasmFunc.a;
binaryen/test/wasm2js/i64-ctz.2asm.js.opt view
@@ -1,18 +1,19 @@ import { setTempRet0 } from 'env'; -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; var setTempRet0 = env.setTempRet0; var i64toi32_i32$HIGH_BITS = 0; function legalstub$popcnt64($0, $1) {@@ -30,16 +31,14 @@ function __wasm_ctz_i64($0, $1) { var $2 = 0, $3 = 0; if ($0 | $1) {- $3 = $1 + -1 | 0;- $2 = $0 + -1 | 0;- if (($2 | 0) != -1) {- $3 = $3 + 1 | 0- }- $2 = Math_clz32($0 ^ $2) + 32 | 0;- $0 = Math_clz32($1 ^ $3);- $0 = ($0 | 0) == 32 ? $2 : $0;+ $2 = $1 - 1 | 0;+ $3 = $0 - 1 | 0;+ $2 = ($3 | 0) != -1 ? $2 + 1 | 0 : $2;+ $3 = Math_clz32($0 ^ $3) + 32 | 0;+ $0 = Math_clz32($1 ^ $2);+ $0 = ($0 | 0) == 32 ? $3 : $0; $1 = 63 - $0 | 0;- i64toi32_i32$HIGH_BITS = 0 - (63 < $0 >>> 0) | 0;+ i64toi32_i32$HIGH_BITS = 0 - ($0 >>> 0 > 63) | 0; return $1; } i64toi32_i32$HIGH_BITS = 0;@@ -49,17 +48,15 @@ function __wasm_popcnt_i64($0, $1) { var $2 = 0, $3 = 0, $4 = 0, $5 = 0; while (1) {- $5 = $3;- $2 = $4;+ $5 = $4;+ $2 = $3; if ($0 | $1) { $2 = $0; $0 = $2 - 1 & $2; $1 = $1 - ($2 >>> 0 < 1) & $1;- $2 = $3 + 1 | 0;- if ($2 >>> 0 < 1) {- $4 = $4 + 1 | 0- }- $3 = $2;+ $2 = $4 + 1 | 0;+ $3 = $2 >>> 0 < 1 ? $3 + 1 | 0 : $3;+ $4 = $2; continue; } break;@@ -74,20 +71,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); },+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }, setTempRet0 }); export var a = retasmFunc.a;
binaryen/test/wasm2js/i64-lowering.2asm.js view
@@ -1,17 +1,18 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function $1($0, $0$hi, $1_1, $1$hi) { $0 = $0 | 0; $0$hi = $0$hi | 0;@@ -788,20 +789,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } }); export var eq_i64 = retasmFunc.eq_i64; export var ne_i64 = retasmFunc.ne_i64;
binaryen/test/wasm2js/i64-lowering.2asm.js.opt view
@@ -1,17 +1,18 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function legalstub$1($0, $1, $2, $3) { return ($0 | 0) == ($2 | 0) & ($1 | 0) == ($3 | 0); }@@ -66,20 +67,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } }); export var eq_i64 = retasmFunc.eq_i64; export var ne_i64 = retasmFunc.ne_i64;
binaryen/test/wasm2js/i64-rotate.2asm.js view
@@ -1,17 +1,18 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; var i64toi32_i32$HIGH_BITS = 0; function $1($0, $0$hi, $1_1, $1$hi, $2_1, $2$hi) { $0 = $0 | 0;@@ -441,20 +442,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } }); export var rotl = retasmFunc.rotl; export var rotr = retasmFunc.rotr;
binaryen/test/wasm2js/i64-rotate.2asm.js.opt view
@@ -1,17 +1,18 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; var i64toi32_i32$HIGH_BITS = 0; function legalstub$1($0, $1, $2, $3, $4, $5) { return (__wasm_rotl_i64($0, $1, $2) | 0) == ($4 | 0) & ($5 | 0) == (i64toi32_i32$HIGH_BITS | 0);@@ -26,7 +27,7 @@ $6 = $2 & 63; $5 = $6; $3 = $5 & 31;- if (32 <= $5 >>> 0) {+ if ($5 >>> 0 >= 32) { $3 = -1 >>> $3 | 0 } else { $4 = -1 >>> $3 | 0;@@ -35,7 +36,7 @@ $5 = $3 & $0; $3 = $1 & $4; $4 = $6 & 31;- if (32 <= $6 >>> 0) {+ if ($6 >>> 0 >= 32) { $3 = $5 << $4; $6 = 0; } else {@@ -46,7 +47,7 @@ $4 = 0 - $2 & 63; $3 = $4; $2 = $3 & 31;- if (32 <= $3 >>> 0) {+ if ($3 >>> 0 >= 32) { $3 = -1 << $2; $2 = 0; } else {@@ -56,7 +57,7 @@ $0 = $2 & $0; $3 = $1 & $3; $1 = $4 & 31;- if (32 <= $4 >>> 0) {+ if ($4 >>> 0 >= 32) { $2 = 0; $0 = $3 >>> $1 | 0; } else {@@ -72,7 +73,7 @@ var $3 = 0, $4 = 0, $5 = 0, $6 = 0, $7 = 0; $6 = $2 & 63; $3 = $6 & 31;- if (32 <= $6 >>> 0) {+ if ($6 >>> 0 >= 32) { $4 = -1 << $3; $7 = 0; } else {@@ -82,7 +83,7 @@ $7 = $7 & $0; $3 = $1 & $4; $5 = $6 & 31;- if (32 <= $6 >>> 0) {+ if ($6 >>> 0 >= 32) { $4 = 0; $6 = $3 >>> $5 | 0; } else {@@ -92,7 +93,7 @@ $7 = $4; $3 = 0 - $2 & 63; $5 = $3 & 31;- if (32 <= $3 >>> 0) {+ if ($3 >>> 0 >= 32) { $4 = 0; $2 = -1 >>> $5 | 0; } else {@@ -102,7 +103,7 @@ $0 = $2 & $0; $1 = $1 & $4; $4 = $3 & 31;- if (32 <= $3 >>> 0) {+ if ($3 >>> 0 >= 32) { $2 = $0 << $4; $0 = 0; } else {@@ -120,20 +121,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } }); export var rotl = retasmFunc.rotl; export var rotr = retasmFunc.rotr;
binaryen/test/wasm2js/i64-select.2asm.js view
@@ -1,34 +1,22 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; return { }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } });
binaryen/test/wasm2js/i64-select.2asm.js.opt view
@@ -1,34 +1,22 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; return { }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } });
binaryen/test/wasm2js/i64-shifts.2asm.js view
@@ -1,17 +1,18 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function $1($0, $0$hi, $1_1, $1$hi, $2_1, $2$hi) { $0 = $0 | 0; $0$hi = $0$hi | 0;@@ -246,20 +247,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } }); export var shl_i64 = retasmFunc.shl_i64; export var shr_i64 = retasmFunc.shr_i64;
binaryen/test/wasm2js/i64-shifts.2asm.js.opt view
@@ -1,17 +1,18 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function $1($0, $1_1, $2_1, $3, $4) { $0 = $0 | 0; $1_1 = $1_1 | 0;@@ -20,7 +21,7 @@ $4 = $4 | 0; var $5 = 0; $5 = $2_1 & 31;- if (32 <= ($2_1 & 63) >>> 0) {+ if (($2_1 & 63) >>> 0 >= 32) { $1_1 = $0 << $5; $0 = 0; } else {@@ -38,7 +39,7 @@ $4 = $4 | 0; var $5 = 0; $5 = $2_1 & 31;- if (32 <= ($2_1 & 63) >>> 0) {+ if (($2_1 & 63) >>> 0 >= 32) { $2_1 = $1_1 >> 31; $0 = $1_1 >> $5; } else {@@ -62,20 +63,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } }); export var shl_i64 = retasmFunc.shl_i64; export var shr_i64 = retasmFunc.shr_i64;
binaryen/test/wasm2js/if_unreachable.2asm.js view
@@ -1,34 +1,22 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; return { }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } });
binaryen/test/wasm2js/if_unreachable.2asm.js.opt view
@@ -1,34 +1,22 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; return { }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } });
binaryen/test/wasm2js/indirect-select.2asm.js view
@@ -1,19 +1,20 @@ import { table } from 'env'; -function asmFunc(global, env) {+function asmFunc(env) { var FUNCTION_TABLE = env.table;- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function $0(x) { x = x | 0; return FUNCTION_TABLE[(x ? 1 : 0) | 0]() | 0 | 0;@@ -30,20 +31,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); },+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }, table }); export var foo_true = retasmFunc.foo_true;
binaryen/test/wasm2js/indirect-select.2asm.js.opt view
@@ -1,19 +1,20 @@ import { table } from 'env'; -function asmFunc(global, env) {+function asmFunc(env) { var FUNCTION_TABLE = env.table;- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function $0($0_1) { $0_1 = $0_1 | 0; return FUNCTION_TABLE[!!$0_1 | 0]() | 0;@@ -30,20 +31,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); },+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }, table }); export var foo_true = retasmFunc.foo_true;
binaryen/test/wasm2js/int_exprs.2asm.js view
@@ -1,17 +1,18 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function $0(x, y) { x = x | 0; y = y | 0;@@ -229,20 +230,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } }); export var i32_no_fold_cmp_s_offset = retasmFunc.i32_no_fold_cmp_s_offset; export var i32_no_fold_cmp_u_offset = retasmFunc.i32_no_fold_cmp_u_offset;@@ -250,19 +238,20 @@ export var i64_no_fold_cmp_u_offset = retasmFunc.i64_no_fold_cmp_u_offset; import { setTempRet0 } from 'env'; -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; var setTempRet0 = env.setTempRet0; var i64toi32_i32$HIGH_BITS = 0; function $0(x, x$hi) {@@ -326,38 +315,26 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); },+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }, setTempRet0 }); export var i64_no_fold_wrap_extend_s = retasmFunc.i64_no_fold_wrap_extend_s; import { setTempRet0 } from 'env'; -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; var setTempRet0 = env.setTempRet0; var i64toi32_i32$HIGH_BITS = 0; function $0(x, x$hi) {@@ -420,38 +397,26 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); },+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }, setTempRet0 }); export var i64_no_fold_wrap_extend_u = retasmFunc.i64_no_fold_wrap_extend_u; import { setTempRet0 } from 'env'; -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; var setTempRet0 = env.setTempRet0; var i64toi32_i32$HIGH_BITS = 0; function $0(x) {@@ -626,20 +591,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); },+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }, setTempRet0 }); export var i32_no_fold_shl_shr_s = retasmFunc.i32_no_fold_shl_shr_s;@@ -648,19 +600,20 @@ export var i64_no_fold_shl_shr_u = retasmFunc.i64_no_fold_shl_shr_u; import { setTempRet0 } from 'env'; -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; var setTempRet0 = env.setTempRet0; var i64toi32_i32$HIGH_BITS = 0; function $0(x) {@@ -835,20 +788,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); },+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }, setTempRet0 }); export var i32_no_fold_shr_s_shl = retasmFunc.i32_no_fold_shr_s_shl;@@ -857,19 +797,20 @@ export var i64_no_fold_shr_u_shl = retasmFunc.i64_no_fold_shr_u_shl; import { setTempRet0 } from 'env'; -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; var setTempRet0 = env.setTempRet0; var __wasm_intrinsics_temp_i64 = 0; var __wasm_intrinsics_temp_i64$hi = 0;@@ -1663,20 +1604,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); },+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }, setTempRet0 }); export var i32_no_fold_div_s_mul = retasmFunc.i32_no_fold_div_s_mul;@@ -1685,19 +1613,20 @@ export var i64_no_fold_div_u_mul = retasmFunc.i64_no_fold_div_u_mul; import { setTempRet0 } from 'env'; -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; var setTempRet0 = env.setTempRet0; var __wasm_intrinsics_temp_i64 = 0; var __wasm_intrinsics_temp_i64$hi = 0;@@ -2397,20 +2326,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); },+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }, setTempRet0 }); export var i32_no_fold_div_s_self = retasmFunc.i32_no_fold_div_s_self;@@ -2419,19 +2335,20 @@ export var i64_no_fold_div_u_self = retasmFunc.i64_no_fold_div_u_self; import { setTempRet0 } from 'env'; -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; var setTempRet0 = env.setTempRet0; var __wasm_intrinsics_temp_i64 = 0; var __wasm_intrinsics_temp_i64$hi = 0;@@ -3113,20 +3030,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); },+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }, setTempRet0 }); export var i32_no_fold_rem_s_self = retasmFunc.i32_no_fold_rem_s_self;@@ -3135,19 +3039,20 @@ export var i64_no_fold_rem_u_self = retasmFunc.i64_no_fold_rem_u_self; import { setTempRet0 } from 'env'; -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; var setTempRet0 = env.setTempRet0; var __wasm_intrinsics_temp_i64 = 0; var __wasm_intrinsics_temp_i64$hi = 0;@@ -3941,20 +3846,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); },+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }, setTempRet0 }); export var i32_no_fold_mul_div_s = retasmFunc.i32_no_fold_mul_div_s;@@ -3963,19 +3855,20 @@ export var i64_no_fold_mul_div_u = retasmFunc.i64_no_fold_mul_div_u; import { setTempRet0 } from 'env'; -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; var setTempRet0 = env.setTempRet0; var __wasm_intrinsics_temp_i64 = 0; var __wasm_intrinsics_temp_i64$hi = 0;@@ -4611,39 +4504,27 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); },+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }, setTempRet0 }); export var i32_no_fold_div_s_2 = retasmFunc.i32_no_fold_div_s_2; export var i64_no_fold_div_s_2 = retasmFunc.i64_no_fold_div_s_2; import { setTempRet0 } from 'env'; -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; var setTempRet0 = env.setTempRet0; var __wasm_intrinsics_temp_i64 = 0; var __wasm_intrinsics_temp_i64$hi = 0;@@ -5261,39 +5142,27 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); },+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }, setTempRet0 }); export var i32_no_fold_rem_s_2 = retasmFunc.i32_no_fold_rem_s_2; export var i64_no_fold_rem_s_2 = retasmFunc.i64_no_fold_rem_s_2; import { setTempRet0 } from 'env'; -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; var setTempRet0 = env.setTempRet0; var __wasm_intrinsics_temp_i64 = 0; var __wasm_intrinsics_temp_i64$hi = 0;@@ -5993,20 +5862,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); },+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }, setTempRet0 }); export var i32_div_s_0 = retasmFunc.i32_div_s_0;@@ -6015,19 +5871,20 @@ export var i64_div_u_0 = retasmFunc.i64_div_u_0; import { setTempRet0 } from 'env'; -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; var setTempRet0 = env.setTempRet0; var __wasm_intrinsics_temp_i64 = 0; var __wasm_intrinsics_temp_i64$hi = 0;@@ -6727,20 +6584,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); },+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }, setTempRet0 }); export var i32_div_s_3 = retasmFunc.i32_div_s_3;@@ -6749,19 +6593,20 @@ export var i64_div_u_3 = retasmFunc.i64_div_u_3; import { setTempRet0 } from 'env'; -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; var setTempRet0 = env.setTempRet0; var __wasm_intrinsics_temp_i64 = 0; var __wasm_intrinsics_temp_i64$hi = 0;@@ -7461,20 +7306,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); },+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }, setTempRet0 }); export var i32_div_s_5 = retasmFunc.i32_div_s_5;@@ -7483,19 +7315,20 @@ export var i64_div_u_5 = retasmFunc.i64_div_u_5; import { setTempRet0 } from 'env'; -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; var setTempRet0 = env.setTempRet0; var __wasm_intrinsics_temp_i64 = 0; var __wasm_intrinsics_temp_i64$hi = 0;@@ -8195,20 +8028,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); },+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }, setTempRet0 }); export var i32_div_s_7 = retasmFunc.i32_div_s_7;@@ -8217,19 +8037,20 @@ export var i64_div_u_7 = retasmFunc.i64_div_u_7; import { setTempRet0 } from 'env'; -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; var setTempRet0 = env.setTempRet0; var __wasm_intrinsics_temp_i64 = 0; var __wasm_intrinsics_temp_i64$hi = 0;@@ -8911,20 +8732,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); },+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }, setTempRet0 }); export var i32_rem_s_3 = retasmFunc.i32_rem_s_3;@@ -8933,19 +8741,20 @@ export var i64_rem_u_3 = retasmFunc.i64_rem_u_3; import { setTempRet0 } from 'env'; -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; var setTempRet0 = env.setTempRet0; var __wasm_intrinsics_temp_i64 = 0; var __wasm_intrinsics_temp_i64$hi = 0;@@ -9627,20 +9436,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); },+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }, setTempRet0 }); export var i32_rem_s_5 = retasmFunc.i32_rem_s_5;@@ -9649,19 +9445,20 @@ export var i64_rem_u_5 = retasmFunc.i64_rem_u_5; import { setTempRet0 } from 'env'; -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; var setTempRet0 = env.setTempRet0; var __wasm_intrinsics_temp_i64 = 0; var __wasm_intrinsics_temp_i64$hi = 0;@@ -10343,20 +10140,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); },+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }, setTempRet0 }); export var i32_rem_s_7 = retasmFunc.i32_rem_s_7;@@ -10365,19 +10149,20 @@ export var i64_rem_u_7 = retasmFunc.i64_rem_u_7; import { setTempRet0 } from 'env'; -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; var setTempRet0 = env.setTempRet0; var __wasm_intrinsics_temp_i64 = 0; var __wasm_intrinsics_temp_i64$hi = 0;@@ -11013,20 +10798,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); },+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }, setTempRet0 }); export var i32_no_fold_div_neg1 = retasmFunc.i32_no_fold_div_neg1;
binaryen/test/wasm2js/labels.2asm.js view
@@ -1,17 +1,18 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function $0() { var $0_1 = 0; exit : {@@ -341,20 +342,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } }); export var block = retasmFunc.block; export var loop1 = retasmFunc.loop1;
binaryen/test/wasm2js/left-to-right.2asm.js view
@@ -1,4 +1,5 @@ + var bufferView; var scratchBuffer = new ArrayBuffer(16); var i32ScratchView = new Int32Array(scratchBuffer);@@ -25,27 +26,29 @@ f32ScratchView[2] = value; } -function asmFunc(global, env, buffer) {- var HEAP8 = new global.Int8Array(buffer);- var HEAP16 = new global.Int16Array(buffer);- var HEAP32 = new global.Int32Array(buffer);- var HEAPU8 = new global.Uint8Array(buffer);- var HEAPU16 = new global.Uint16Array(buffer);- var HEAPU32 = new global.Uint32Array(buffer);- var HEAPF32 = new global.Float32Array(buffer);- var HEAPF64 = new global.Float64Array(buffer);- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var buffer = new ArrayBuffer(65536);+ var HEAP8 = new Int8Array(buffer);+ var HEAP16 = new Int16Array(buffer);+ var HEAP32 = new Int32Array(buffer);+ var HEAPU8 = new Uint8Array(buffer);+ var HEAPU16 = new Uint16Array(buffer);+ var HEAPU32 = new Uint32Array(buffer);+ var HEAPF32 = new Float32Array(buffer);+ var HEAPF64 = new Float64Array(buffer);+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; var __wasm_intrinsics_temp_i64 = 0; var __wasm_intrinsics_temp_i64$hi = 0; var i64toi32_i32$HIGH_BITS = 0;@@ -2037,6 +2040,7 @@ return 32 | 0; } + bufferView = HEAPU8; var FUNCTION_TABLE = [i32_t0, i32_t1, i64_t0, i64_t1, f32_t0, f32_t1, f64_t0, f64_t1]; function __wasm_memory_size() { return buffer.byteLength / 65536 | 0;@@ -2048,18 +2052,18 @@ var newPages = oldPages + pagesToAdd | 0; if ((oldPages < newPages) && (newPages < 65536)) { var newBuffer = new ArrayBuffer(Math_imul(newPages, 65536));- var newHEAP8 = new global.Int8Array(newBuffer);+ var newHEAP8 = new Int8Array(newBuffer); newHEAP8.set(HEAP8);- HEAP8 = newHEAP8;- HEAP8 = new global.Int8Array(newBuffer);- HEAP16 = new global.Int16Array(newBuffer);- HEAP32 = new global.Int32Array(newBuffer);- HEAPU8 = new global.Uint8Array(newBuffer);- HEAPU16 = new global.Uint16Array(newBuffer);- HEAPU32 = new global.Uint32Array(newBuffer);- HEAPF32 = new global.Float32Array(newBuffer);- HEAPF64 = new global.Float64Array(newBuffer);+ HEAP8 = new Int8Array(newBuffer);+ HEAP16 = new Int16Array(newBuffer);+ HEAP32 = new Int32Array(newBuffer);+ HEAPU8 = new Uint8Array(newBuffer);+ HEAPU16 = new Uint16Array(newBuffer);+ HEAPU32 = new Uint32Array(newBuffer);+ HEAPF32 = new Float32Array(newBuffer);+ HEAPF64 = new Float64Array(newBuffer); buffer = newBuffer;+ bufferView = HEAPU8; } return oldPages; }@@ -2163,25 +2167,8 @@ }; } -var memasmFunc = new ArrayBuffer(65536);-var bufferView = new Uint8Array(memasmFunc);-var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }- },- memasmFunc-);+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }+ }); export var i32_add = retasmFunc.i32_add; export var i32_sub = retasmFunc.i32_sub; export var i32_mul = retasmFunc.i32_mul;
binaryen/test/wasm2js/minified-memory.2asm.js view
@@ -1,28 +1,29 @@ -function asmFunc(global, env) {+function asmFunc(env) { var memory = env.a; var buffer = memory.buffer; memory.grow = __wasm_memory_grow;- var HEAP8 = new global.Int8Array(buffer);- var HEAP16 = new global.Int16Array(buffer);- var HEAP32 = new global.Int32Array(buffer);- var HEAPU8 = new global.Uint8Array(buffer);- var HEAPU16 = new global.Uint16Array(buffer);- var HEAPU32 = new global.Uint32Array(buffer);- var HEAPF32 = new global.Float32Array(buffer);- var HEAPF64 = new global.Float64Array(buffer);- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+ var HEAP8 = new Int8Array(buffer);+ var HEAP16 = new Int16Array(buffer);+ var HEAP32 = new Int32Array(buffer);+ var HEAPU8 = new Uint8Array(buffer);+ var HEAPU16 = new Uint16Array(buffer);+ var HEAPU32 = new Uint32Array(buffer);+ var HEAPF32 = new Float32Array(buffer);+ var HEAPF64 = new Float64Array(buffer);+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function $0() { return HEAP32[0 >> 2] | 0 | 0; }@@ -37,19 +38,18 @@ var newPages = oldPages + pagesToAdd | 0; if ((oldPages < newPages) && (newPages < 65536)) { var newBuffer = new ArrayBuffer(Math_imul(newPages, 65536));- var newHEAP8 = new global.Int8Array(newBuffer);+ var newHEAP8 = new Int8Array(newBuffer); newHEAP8.set(HEAP8);- HEAP8 = newHEAP8;- HEAP8 = new global.Int8Array(newBuffer);- HEAP16 = new global.Int16Array(newBuffer);- HEAP32 = new global.Int32Array(newBuffer);- HEAPU8 = new global.Uint8Array(newBuffer);- HEAPU16 = new global.Uint16Array(newBuffer);- HEAPU32 = new global.Uint32Array(newBuffer);- HEAPF32 = new global.Float32Array(newBuffer);- HEAPF64 = new global.Float64Array(newBuffer);+ HEAP8 = new Int8Array(newBuffer);+ HEAP16 = new Int16Array(newBuffer);+ HEAP32 = new Int32Array(newBuffer);+ HEAPU8 = new Uint8Array(newBuffer);+ HEAPU16 = new Uint16Array(newBuffer);+ HEAPU32 = new Uint32Array(newBuffer);+ HEAPF32 = new Float32Array(newBuffer);+ HEAPF64 = new Float64Array(newBuffer); buffer = newBuffer;- memory.buffer = newBuffer;+ memory.buffer = buffer; } return oldPages; }@@ -60,21 +60,7 @@ } var memasmFunc = new ArrayBuffer(65536);-var bufferView = new Uint8Array(memasmFunc);-var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); },+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }, a: { buffer : memasmFunc } }); export var foo = retasmFunc.foo;
binaryen/test/wasm2js/minified-memory.2asm.js.opt view
@@ -1,28 +1,29 @@ -function asmFunc(global, env) {+function asmFunc(env) { var memory = env.a; var buffer = memory.buffer; memory.grow = __wasm_memory_grow;- var HEAP8 = new global.Int8Array(buffer);- var HEAP16 = new global.Int16Array(buffer);- var HEAP32 = new global.Int32Array(buffer);- var HEAPU8 = new global.Uint8Array(buffer);- var HEAPU16 = new global.Uint16Array(buffer);- var HEAPU32 = new global.Uint32Array(buffer);- var HEAPF32 = new global.Float32Array(buffer);- var HEAPF64 = new global.Float64Array(buffer);- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+ var HEAP8 = new Int8Array(buffer);+ var HEAP16 = new Int16Array(buffer);+ var HEAP32 = new Int32Array(buffer);+ var HEAPU8 = new Uint8Array(buffer);+ var HEAPU16 = new Uint16Array(buffer);+ var HEAPU32 = new Uint32Array(buffer);+ var HEAPF32 = new Float32Array(buffer);+ var HEAPF64 = new Float64Array(buffer);+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function $0() { return HEAP32[0]; }@@ -37,19 +38,18 @@ var newPages = oldPages + pagesToAdd | 0; if ((oldPages < newPages) && (newPages < 65536)) { var newBuffer = new ArrayBuffer(Math_imul(newPages, 65536));- var newHEAP8 = new global.Int8Array(newBuffer);+ var newHEAP8 = new Int8Array(newBuffer); newHEAP8.set(HEAP8);- HEAP8 = newHEAP8;- HEAP8 = new global.Int8Array(newBuffer);- HEAP16 = new global.Int16Array(newBuffer);- HEAP32 = new global.Int32Array(newBuffer);- HEAPU8 = new global.Uint8Array(newBuffer);- HEAPU16 = new global.Uint16Array(newBuffer);- HEAPU32 = new global.Uint32Array(newBuffer);- HEAPF32 = new global.Float32Array(newBuffer);- HEAPF64 = new global.Float64Array(newBuffer);+ HEAP8 = new Int8Array(newBuffer);+ HEAP16 = new Int16Array(newBuffer);+ HEAP32 = new Int32Array(newBuffer);+ HEAPU8 = new Uint8Array(newBuffer);+ HEAPU16 = new Uint16Array(newBuffer);+ HEAPU32 = new Uint32Array(newBuffer);+ HEAPF32 = new Float32Array(newBuffer);+ HEAPF64 = new Float64Array(newBuffer); buffer = newBuffer;- memory.buffer = newBuffer;+ memory.buffer = buffer; } return oldPages; }@@ -60,21 +60,7 @@ } var memasmFunc = new ArrayBuffer(65536);-var bufferView = new Uint8Array(memasmFunc);-var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); },+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }, a: { buffer : memasmFunc } }); export var foo = retasmFunc.foo;
binaryen/test/wasm2js/minus_minus.2asm.js view
@@ -1,17 +1,18 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function $0() { return ~~- -7094.0 | 0; }@@ -25,19 +26,6 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } }); export var func_44_invoker = retasmFunc.func_44_invoker;
binaryen/test/wasm2js/minus_minus.2asm.js.opt view
@@ -1,17 +1,18 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function $1() { }@@ -21,19 +22,6 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } }); export var func_44_invoker = retasmFunc.func_44_invoker;
binaryen/test/wasm2js/nested-selects.2asm.js view
@@ -1,17 +1,18 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function $1($0) { $0 = $0 | 0; return (($0 | 0) < (0 | 0) ? -1 : ($0 | 0) > (0 | 0) ? 1 : 0) | 0;@@ -22,19 +23,6 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } }); export var sign = retasmFunc.sign;
binaryen/test/wasm2js/nested-selects.2asm.js.opt view
@@ -1,17 +1,18 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function $1($0) { $0 = $0 | 0; return (($0 | 0) < 0 ? -1 : ($0 | 0) > 0) | 0;@@ -22,19 +23,6 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } }); export var sign = retasmFunc.sign;
binaryen/test/wasm2js/ordering.2asm.js view
@@ -1,19 +1,20 @@ import { table } from 'env'; -function asmFunc(global, env) {+function asmFunc(env) { var FUNCTION_TABLE = env.table;- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function main() { var wasm2js_i32$0 = 0, wasm2js_i32$1 = 0, wasm2js_i32$2 = 0; FUNCTION_TABLE[foo(2 | 0) | 0 | 0](1) | 0;@@ -53,20 +54,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); },+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }, table }); export var main = retasmFunc.main;
binaryen/test/wasm2js/ordering.2asm.js.opt view
@@ -1,19 +1,20 @@ import { table } from 'env'; -function asmFunc(global, env) {+function asmFunc(env) { var FUNCTION_TABLE = env.table;- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function main() { FUNCTION_TABLE[1](1) | 0; FUNCTION_TABLE[4](1) | 0;@@ -44,20 +45,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); },+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }, table }); export var main = retasmFunc.main;
binaryen/test/wasm2js/reinterpret.2asm.js view
@@ -29,19 +29,20 @@ return f32ScratchView[2]; } -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function $1($0) { $0 = $0 | 0; return ((wasm2js_scratch_store_f32((wasm2js_scratch_store_i32(2, $0), wasm2js_scratch_load_f32())), wasm2js_scratch_load_i32(2)) | 0) == ($0 | 0) | 0;@@ -96,20 +97,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } }); export var i32_roundtrip = retasmFunc.i32_roundtrip; export var i64_roundtrip = retasmFunc.i64_roundtrip;
binaryen/test/wasm2js/reinterpret.2asm.js.opt view
@@ -29,19 +29,20 @@ return f32ScratchView[2]; } -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function $1($0) { $0 = $0 | 0; return ((wasm2js_scratch_store_f32((wasm2js_scratch_store_i32(2, $0), wasm2js_scratch_load_f32())), wasm2js_scratch_load_i32(2)) | 0) == ($0 | 0) | 0;@@ -68,20 +69,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } }); export var i32_roundtrip = retasmFunc.i32_roundtrip; export var i64_roundtrip = retasmFunc.i64_roundtrip;
binaryen/test/wasm2js/reinterpret_scratch.2asm.js view
@@ -1,4 +1,5 @@ + var bufferView; var scratchBuffer = new ArrayBuffer(16); var i32ScratchView = new Int32Array(scratchBuffer);@@ -17,27 +18,29 @@ f32ScratchView[2] = value; } -function asmFunc(global, env, buffer) {- var HEAP8 = new global.Int8Array(buffer);- var HEAP16 = new global.Int16Array(buffer);- var HEAP32 = new global.Int32Array(buffer);- var HEAPU8 = new global.Uint8Array(buffer);- var HEAPU16 = new global.Uint16Array(buffer);- var HEAPU32 = new global.Uint32Array(buffer);- var HEAPF32 = new global.Float32Array(buffer);- var HEAPF64 = new global.Float64Array(buffer);- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var buffer = new ArrayBuffer(65536);+ var HEAP8 = new Int8Array(buffer);+ var HEAP16 = new Int16Array(buffer);+ var HEAP32 = new Int32Array(buffer);+ var HEAPU8 = new Uint8Array(buffer);+ var HEAPU16 = new Uint16Array(buffer);+ var HEAPU32 = new Uint32Array(buffer);+ var HEAPF32 = new Float32Array(buffer);+ var HEAPF64 = new Float64Array(buffer);+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function $0() { var i64toi32_i32$1 = 0, i64toi32_i32$0 = 0, $0_1 = Math_fround(0); wasm2js_scratch_store_f64(+(305419896.0));@@ -48,6 +51,7 @@ return HEAP32[0 >> 2] | 0 | 0; } + bufferView = HEAPU8; function __wasm_memory_size() { return buffer.byteLength / 65536 | 0; }@@ -57,23 +61,6 @@ }; } -var memasmFunc = new ArrayBuffer(65536);-var bufferView = new Uint8Array(memasmFunc);-var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }- },- memasmFunc-);+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }+ }); export var foo = retasmFunc.foo;
binaryen/test/wasm2js/reinterpret_scratch.2asm.js.opt view
@@ -1,4 +1,5 @@ + var bufferView; var scratchBuffer = new ArrayBuffer(16); var i32ScratchView = new Int32Array(scratchBuffer);@@ -13,27 +14,29 @@ f64ScratchView[0] = value; } -function asmFunc(global, env, buffer) {- var HEAP8 = new global.Int8Array(buffer);- var HEAP16 = new global.Int16Array(buffer);- var HEAP32 = new global.Int32Array(buffer);- var HEAPU8 = new global.Uint8Array(buffer);- var HEAPU16 = new global.Uint16Array(buffer);- var HEAPU32 = new global.Uint32Array(buffer);- var HEAPF32 = new global.Float32Array(buffer);- var HEAPF64 = new global.Float64Array(buffer);- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var buffer = new ArrayBuffer(65536);+ var HEAP8 = new Int8Array(buffer);+ var HEAP16 = new Int16Array(buffer);+ var HEAP32 = new Int32Array(buffer);+ var HEAPU8 = new Uint8Array(buffer);+ var HEAPU16 = new Uint16Array(buffer);+ var HEAPU32 = new Uint32Array(buffer);+ var HEAPF32 = new Float32Array(buffer);+ var HEAPF64 = new Float64Array(buffer);+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function $0() { var $0_1 = 0; wasm2js_scratch_store_f64(305419896.0);@@ -43,6 +46,7 @@ return HEAP32[0]; } + bufferView = HEAPU8; function __wasm_memory_size() { return buffer.byteLength / 65536 | 0; }@@ -52,23 +56,6 @@ }; } -var memasmFunc = new ArrayBuffer(65536);-var bufferView = new Uint8Array(memasmFunc);-var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }- },- memasmFunc-);+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }+ }); export var foo = retasmFunc.foo;
binaryen/test/wasm2js/set_local.2asm.js view
@@ -1,18 +1,19 @@ import { setTempRet0 } from 'env'; -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; var setTempRet0 = env.setTempRet0; var i64toi32_i32$HIGH_BITS = 0; function $0() {@@ -219,20 +220,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); },+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }, setTempRet0 }); export var type_local_i32 = retasmFunc.type_local_i32;
binaryen/test/wasm2js/sign_ext.2asm.js view
@@ -1,17 +1,18 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function $0(x) { x = x | 0; return x << 24 >> 24 | 0;@@ -28,20 +29,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } }); export var test8 = retasmFunc.test8; export var test16 = retasmFunc.test16;
binaryen/test/wasm2js/sign_ext.2asm.js.opt view
@@ -1,17 +1,18 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function $0($0_1) { $0_1 = $0_1 | 0; return $0_1 << 24 >> 24;@@ -28,20 +29,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } }); export var test8 = retasmFunc.test8; export var test16 = retasmFunc.test16;
binaryen/test/wasm2js/stack-modified.2asm.js view
@@ -1,18 +1,19 @@ import { setTempRet0 } from 'env'; -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; var setTempRet0 = env.setTempRet0; var i64toi32_i32$HIGH_BITS = 0; function $0(var$0, var$0$hi) {@@ -570,20 +571,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); },+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }, setTempRet0 }); export var fac_expr = retasmFunc.fac_expr;
binaryen/test/wasm2js/stack-modified.2asm.js.opt view
@@ -1,18 +1,19 @@ import { setTempRet0 } from 'env'; -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; var setTempRet0 = env.setTempRet0; var i64toi32_i32$HIGH_BITS = 0; function $0($0_1, $1) {@@ -67,20 +68,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); },+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }, setTempRet0 }); export var fac_expr = retasmFunc.fac_expr;
binaryen/test/wasm2js/start_func.2asm.js view
@@ -1,25 +1,27 @@ -function asmFunc(global, env, buffer) {- var HEAP8 = new global.Int8Array(buffer);- var HEAP16 = new global.Int16Array(buffer);- var HEAP32 = new global.Int32Array(buffer);- var HEAPU8 = new global.Uint8Array(buffer);- var HEAPU16 = new global.Uint16Array(buffer);- var HEAPU32 = new global.Uint32Array(buffer);- var HEAPF32 = new global.Float32Array(buffer);- var HEAPF64 = new global.Float64Array(buffer);- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var buffer = new ArrayBuffer(65536);+ var HEAP8 = new Int8Array(buffer);+ var HEAP16 = new Int16Array(buffer);+ var HEAP32 = new Int32Array(buffer);+ var HEAPU8 = new Uint8Array(buffer);+ var HEAPU16 = new Uint16Array(buffer);+ var HEAPU32 = new Uint32Array(buffer);+ var HEAPF32 = new Float32Array(buffer);+ var HEAPF64 = new Float64Array(buffer);+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function foo() { HEAP32[1 >> 2] = 2; }@@ -35,17 +37,16 @@ var newPages = oldPages + pagesToAdd | 0; if ((oldPages < newPages) && (newPages < 65536)) { var newBuffer = new ArrayBuffer(Math_imul(newPages, 65536));- var newHEAP8 = new global.Int8Array(newBuffer);+ var newHEAP8 = new Int8Array(newBuffer); newHEAP8.set(HEAP8);- HEAP8 = newHEAP8;- HEAP8 = new global.Int8Array(newBuffer);- HEAP16 = new global.Int16Array(newBuffer);- HEAP32 = new global.Int32Array(newBuffer);- HEAPU8 = new global.Uint8Array(newBuffer);- HEAPU16 = new global.Uint16Array(newBuffer);- HEAPU32 = new global.Uint32Array(newBuffer);- HEAPF32 = new global.Float32Array(newBuffer);- HEAPF64 = new global.Float64Array(newBuffer);+ HEAP8 = new Int8Array(newBuffer);+ HEAP16 = new Int16Array(newBuffer);+ HEAP32 = new Int32Array(newBuffer);+ HEAPU8 = new Uint8Array(newBuffer);+ HEAPU16 = new Uint16Array(newBuffer);+ HEAPU32 = new Uint32Array(newBuffer);+ HEAPF32 = new Float32Array(newBuffer);+ HEAPF64 = new Float64Array(newBuffer); buffer = newBuffer; } return oldPages;@@ -56,22 +57,5 @@ }; } -var memasmFunc = new ArrayBuffer(65536);-var bufferView = new Uint8Array(memasmFunc);-var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }- },- memasmFunc-);+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }+ });
binaryen/test/wasm2js/start_func.2asm.js.opt view
@@ -1,25 +1,27 @@ -function asmFunc(global, env, buffer) {- var HEAP8 = new global.Int8Array(buffer);- var HEAP16 = new global.Int16Array(buffer);- var HEAP32 = new global.Int32Array(buffer);- var HEAPU8 = new global.Uint8Array(buffer);- var HEAPU16 = new global.Uint16Array(buffer);- var HEAPU32 = new global.Uint32Array(buffer);- var HEAPF32 = new global.Float32Array(buffer);- var HEAPF64 = new global.Float64Array(buffer);- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var buffer = new ArrayBuffer(65536);+ var HEAP8 = new Int8Array(buffer);+ var HEAP16 = new Int16Array(buffer);+ var HEAP32 = new Int32Array(buffer);+ var HEAPU8 = new Uint8Array(buffer);+ var HEAPU16 = new Uint16Array(buffer);+ var HEAPU32 = new Uint32Array(buffer);+ var HEAPF32 = new Float32Array(buffer);+ var HEAPF64 = new Float64Array(buffer);+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function foo() { HEAP32[0] = 2; }@@ -35,17 +37,16 @@ var newPages = oldPages + pagesToAdd | 0; if ((oldPages < newPages) && (newPages < 65536)) { var newBuffer = new ArrayBuffer(Math_imul(newPages, 65536));- var newHEAP8 = new global.Int8Array(newBuffer);+ var newHEAP8 = new Int8Array(newBuffer); newHEAP8.set(HEAP8);- HEAP8 = newHEAP8;- HEAP8 = new global.Int8Array(newBuffer);- HEAP16 = new global.Int16Array(newBuffer);- HEAP32 = new global.Int32Array(newBuffer);- HEAPU8 = new global.Uint8Array(newBuffer);- HEAPU16 = new global.Uint16Array(newBuffer);- HEAPU32 = new global.Uint32Array(newBuffer);- HEAPF32 = new global.Float32Array(newBuffer);- HEAPF64 = new global.Float64Array(newBuffer);+ HEAP8 = new Int8Array(newBuffer);+ HEAP16 = new Int16Array(newBuffer);+ HEAP32 = new Int32Array(newBuffer);+ HEAPU8 = new Uint8Array(newBuffer);+ HEAPU16 = new Uint16Array(newBuffer);+ HEAPU32 = new Uint32Array(newBuffer);+ HEAPF32 = new Float32Array(newBuffer);+ HEAPF64 = new Float64Array(newBuffer); buffer = newBuffer; } return oldPages;@@ -56,22 +57,5 @@ }; } -var memasmFunc = new ArrayBuffer(65536);-var bufferView = new Uint8Array(memasmFunc);-var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }- },- memasmFunc-);+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }+ });
binaryen/test/wasm2js/switch.2asm.js view
@@ -1,18 +1,19 @@ import { setTempRet0 } from 'env'; -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; var setTempRet0 = env.setTempRet0; var i64toi32_i32$HIGH_BITS = 0; function $0(i) {@@ -182,20 +183,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); },+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }, setTempRet0 }); export var stmt = retasmFunc.stmt;
binaryen/test/wasm2js/tee_local.2asm.js view
@@ -1,18 +1,19 @@ import { setTempRet0 } from 'env'; -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; var setTempRet0 = env.setTempRet0; var i64toi32_i32$HIGH_BITS = 0; function $0() {@@ -326,20 +327,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); },+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }, setTempRet0 }); export var type_local_i32 = retasmFunc.type_local_i32;
binaryen/test/wasm2js/traps.2asm.js view
@@ -1,17 +1,18 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; var __wasm_intrinsics_temp_i64 = 0; var __wasm_intrinsics_temp_i64$hi = 0; var i64toi32_i32$HIGH_BITS = 0;@@ -728,39 +729,27 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } }); export var no_dce_i32_div_s = retasmFunc.no_dce_i32_div_s; export var no_dce_i32_div_u = retasmFunc.no_dce_i32_div_u; export var no_dce_i64_div_s = retasmFunc.no_dce_i64_div_s; export var no_dce_i64_div_u = retasmFunc.no_dce_i64_div_u; -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; var __wasm_intrinsics_temp_i64 = 0; var __wasm_intrinsics_temp_i64$hi = 0; var i64toi32_i32$HIGH_BITS = 0;@@ -1459,39 +1448,27 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } }); export var no_dce_i32_rem_s = retasmFunc.no_dce_i32_rem_s; export var no_dce_i32_rem_u = retasmFunc.no_dce_i32_rem_u; export var no_dce_i64_rem_s = retasmFunc.no_dce_i64_rem_s; export var no_dce_i64_rem_u = retasmFunc.no_dce_i64_rem_u; -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function $0(x) { x = Math_fround(x); ~~x;@@ -1592,20 +1569,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } }); export var no_dce_i32_trunc_f32_s = retasmFunc.no_dce_i32_trunc_f32_s; export var no_dce_i32_trunc_f32_u = retasmFunc.no_dce_i32_trunc_f32_u;@@ -1616,27 +1580,29 @@ export var no_dce_i64_trunc_f64_s = retasmFunc.no_dce_i64_trunc_f64_s; export var no_dce_i64_trunc_f64_u = retasmFunc.no_dce_i64_trunc_f64_u; -function asmFunc(global, env, buffer) {- var HEAP8 = new global.Int8Array(buffer);- var HEAP16 = new global.Int16Array(buffer);- var HEAP32 = new global.Int32Array(buffer);- var HEAPU8 = new global.Uint8Array(buffer);- var HEAPU16 = new global.Uint16Array(buffer);- var HEAPU32 = new global.Uint32Array(buffer);- var HEAPF32 = new global.Float32Array(buffer);- var HEAPF64 = new global.Float64Array(buffer);- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var buffer = new ArrayBuffer(65536);+ var HEAP8 = new Int8Array(buffer);+ var HEAP16 = new Int16Array(buffer);+ var HEAP32 = new Int32Array(buffer);+ var HEAPU8 = new Uint8Array(buffer);+ var HEAPU16 = new Uint16Array(buffer);+ var HEAPU32 = new Uint32Array(buffer);+ var HEAPF32 = new Float32Array(buffer);+ var HEAPF64 = new Float64Array(buffer);+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; function $0(i) { i = i | 0; HEAP32[i >> 2] | 0;@@ -1723,17 +1689,16 @@ var newPages = oldPages + pagesToAdd | 0; if ((oldPages < newPages) && (newPages < 65536)) { var newBuffer = new ArrayBuffer(Math_imul(newPages, 65536));- var newHEAP8 = new global.Int8Array(newBuffer);+ var newHEAP8 = new Int8Array(newBuffer); newHEAP8.set(HEAP8);- HEAP8 = newHEAP8;- HEAP8 = new global.Int8Array(newBuffer);- HEAP16 = new global.Int16Array(newBuffer);- HEAP32 = new global.Int32Array(newBuffer);- HEAPU8 = new global.Uint8Array(newBuffer);- HEAPU16 = new global.Uint16Array(newBuffer);- HEAPU32 = new global.Uint32Array(newBuffer);- HEAPF32 = new global.Float32Array(newBuffer);- HEAPF64 = new global.Float64Array(newBuffer);+ HEAP8 = new Int8Array(newBuffer);+ HEAP16 = new Int16Array(newBuffer);+ HEAP32 = new Int32Array(newBuffer);+ HEAPU8 = new Uint8Array(newBuffer);+ HEAPU16 = new Uint16Array(newBuffer);+ HEAPU32 = new Uint32Array(newBuffer);+ HEAPF32 = new Float32Array(newBuffer);+ HEAPF64 = new Float64Array(newBuffer); buffer = newBuffer; } return oldPages;@@ -1757,25 +1722,8 @@ }; } -var memasmFunc = new ArrayBuffer(65536);-var bufferView = new Uint8Array(memasmFunc);-var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }- },- memasmFunc-);+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }+ }); export var no_dce_i32_load = retasmFunc.no_dce_i32_load; export var no_dce_i32_load16_s = retasmFunc.no_dce_i32_load16_s; export var no_dce_i32_load16_u = retasmFunc.no_dce_i32_load16_u;
binaryen/test/wasm2js/unaligned.2asm.js view
@@ -1,5 +1,6 @@ import { setTempRet0 } from 'env'; + var bufferView; var scratchBuffer = new ArrayBuffer(16); var i32ScratchView = new Int32Array(scratchBuffer);@@ -30,27 +31,29 @@ f32ScratchView[2] = value; } -function asmFunc(global, env, buffer) {- var HEAP8 = new global.Int8Array(buffer);- var HEAP16 = new global.Int16Array(buffer);- var HEAP32 = new global.Int32Array(buffer);- var HEAPU8 = new global.Uint8Array(buffer);- var HEAPU16 = new global.Uint16Array(buffer);- var HEAPU32 = new global.Uint32Array(buffer);- var HEAPF32 = new global.Float32Array(buffer);- var HEAPF64 = new global.Float64Array(buffer);- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var buffer = new ArrayBuffer(65536);+ var HEAP8 = new Int8Array(buffer);+ var HEAP16 = new Int16Array(buffer);+ var HEAP32 = new Int32Array(buffer);+ var HEAPU8 = new Uint8Array(buffer);+ var HEAPU16 = new Uint16Array(buffer);+ var HEAPU32 = new Uint32Array(buffer);+ var HEAPF32 = new Float32Array(buffer);+ var HEAPF64 = new Float64Array(buffer);+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; var setTempRet0 = env.setTempRet0; var i64toi32_i32$HIGH_BITS = 0; function $0() {@@ -157,6 +160,7 @@ return $0_1 | 0; } + bufferView = HEAPU8; function __wasm_memory_size() { return buffer.byteLength / 65536 | 0; }@@ -173,26 +177,9 @@ }; } -var memasmFunc = new ArrayBuffer(65536);-var bufferView = new Uint8Array(memasmFunc);-var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); },+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }, setTempRet0- },- memasmFunc-);+ }); export var i32_load = retasmFunc.i32_load; export var i64_load = retasmFunc.i64_load; export var f32_load = retasmFunc.f32_load;
binaryen/test/wasm2js/unaligned.2asm.js.opt view
@@ -1,5 +1,6 @@ import { setTempRet0 } from 'env'; + var bufferView; var scratchBuffer = new ArrayBuffer(16); var i32ScratchView = new Int32Array(scratchBuffer);@@ -26,27 +27,29 @@ return f32ScratchView[2]; } -function asmFunc(global, env, buffer) {- var HEAP8 = new global.Int8Array(buffer);- var HEAP16 = new global.Int16Array(buffer);- var HEAP32 = new global.Int32Array(buffer);- var HEAPU8 = new global.Uint8Array(buffer);- var HEAPU16 = new global.Uint16Array(buffer);- var HEAPU32 = new global.Uint32Array(buffer);- var HEAPF32 = new global.Float32Array(buffer);- var HEAPF64 = new global.Float64Array(buffer);- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var buffer = new ArrayBuffer(65536);+ var HEAP8 = new Int8Array(buffer);+ var HEAP16 = new Int16Array(buffer);+ var HEAP32 = new Int32Array(buffer);+ var HEAPU8 = new Uint8Array(buffer);+ var HEAPU16 = new Uint16Array(buffer);+ var HEAPU32 = new Uint32Array(buffer);+ var HEAPF32 = new Float32Array(buffer);+ var HEAPF64 = new Float64Array(buffer);+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; var setTempRet0 = env.setTempRet0; var i64toi32_i32$HIGH_BITS = 0; function $0() {@@ -110,6 +113,7 @@ return $0_1; } + bufferView = HEAPU8; function __wasm_memory_size() { return buffer.byteLength / 65536 | 0; }@@ -126,26 +130,9 @@ }; } -var memasmFunc = new ArrayBuffer(65536);-var bufferView = new Uint8Array(memasmFunc);-var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); },+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }, setTempRet0- },- memasmFunc-);+ }); export var i32_load = retasmFunc.i32_load; export var i64_load = retasmFunc.i64_load; export var f32_load = retasmFunc.f32_load;
binaryen/test/wasm2js/unary-ops.2asm.js view
@@ -1,17 +1,18 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; var i64toi32_i32$HIGH_BITS = 0; function $1($0) { $0 = $0 | 0;@@ -516,20 +517,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } }); export var i32_popcnt = retasmFunc.i32_popcnt; export var check_popcnt_i64 = retasmFunc.check_popcnt_i64;
binaryen/test/wasm2js/unary-ops.2asm.js.opt view
@@ -1,17 +1,18 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; var i64toi32_i32$HIGH_BITS = 0; function $1($0) { $0 = $0 | 0;@@ -26,7 +27,7 @@ function $7($0) { $0 = $0 | 0; if ($0) {- $0 = 31 - Math_clz32($0 + -1 ^ $0) | 0+ $0 = 31 - Math_clz32($0 - 1 ^ $0) | 0 } else { $0 = 32 }@@ -71,16 +72,14 @@ function __wasm_ctz_i64($0, $1_1) { var $2 = 0, $3 = 0; if ($0 | $1_1) {- $3 = $1_1 + -1 | 0;- $2 = $0 + -1 | 0;- if (($2 | 0) != -1) {- $3 = $3 + 1 | 0- }- $2 = Math_clz32($0 ^ $2) + 32 | 0;- $0 = Math_clz32($1_1 ^ $3);- $0 = ($0 | 0) == 32 ? $2 : $0;+ $2 = $1_1 - 1 | 0;+ $3 = $0 - 1 | 0;+ $2 = ($3 | 0) != -1 ? $2 + 1 | 0 : $2;+ $3 = Math_clz32($0 ^ $3) + 32 | 0;+ $0 = Math_clz32($1_1 ^ $2);+ $0 = ($0 | 0) == 32 ? $3 : $0; $1_1 = 63 - $0 | 0;- i64toi32_i32$HIGH_BITS = 0 - (63 < $0 >>> 0) | 0;+ i64toi32_i32$HIGH_BITS = 0 - ($0 >>> 0 > 63) | 0; return $1_1; } i64toi32_i32$HIGH_BITS = 0;@@ -104,17 +103,15 @@ function __wasm_popcnt_i64($0, $1_1) { var $2 = 0, $3 = 0, $4 = 0, $5 = 0; while (1) {- $5 = $3;- $2 = $4;+ $5 = $4;+ $2 = $3; if ($0 | $1_1) { $2 = $0; $0 = $2 - 1 & $2; $1_1 = $1_1 - ($2 >>> 0 < 1) & $1_1;- $2 = $3 + 1 | 0;- if ($2 >>> 0 < 1) {- $4 = $4 + 1 | 0- }- $3 = $2;+ $2 = $4 + 1 | 0;+ $3 = $2 >>> 0 < 1 ? $3 + 1 | 0 : $3;+ $4 = $2; continue; } break;@@ -136,20 +133,7 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } }); export var i32_popcnt = retasmFunc.i32_popcnt; export var check_popcnt_i64 = retasmFunc.check_popcnt_i64;
binaryen/test/wasm2js/unreachable-get-cycle.2asm.js view
@@ -1,34 +1,22 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; return { }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } });
binaryen/test/wasm2js/unreachable-get-cycle.2asm.js.opt view
@@ -1,34 +1,22 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; return { }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } });
binaryen/test/wasm2js/unreachable-insts.2asm.js view
@@ -1,34 +1,22 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; return { }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } });
binaryen/test/wasm2js/unreachable-insts.2asm.js.opt view
@@ -1,34 +1,22 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; return { }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } });
binaryen/test/wasm2js/unreachable-later.2asm.js view
@@ -1,17 +1,18 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; var global$0 = 10; function $0($0_1) { $0_1 = $0_1 | 0;@@ -63,19 +64,6 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } }); export var func_50 = retasmFunc.func_50;
binaryen/test/wasm2js/unreachable-later.2asm.js.opt view
@@ -1,17 +1,18 @@ -function asmFunc(global, env) {- var Math_imul = global.Math.imul;- var Math_fround = global.Math.fround;- var Math_abs = global.Math.abs;- var Math_clz32 = global.Math.clz32;- var Math_min = global.Math.min;- var Math_max = global.Math.max;- var Math_floor = global.Math.floor;- var Math_ceil = global.Math.ceil;- var Math_sqrt = global.Math.sqrt;+function asmFunc(env) {+ var Math_imul = Math.imul;+ var Math_fround = Math.fround;+ var Math_abs = Math.abs;+ var Math_clz32 = Math.clz32;+ var Math_min = Math.min;+ var Math_max = Math.max;+ var Math_floor = Math.floor;+ var Math_ceil = Math.ceil;+ var Math_trunc = Math.trunc;+ var Math_sqrt = Math.sqrt; var abort = env.abort;- var nan = global.NaN;- var infinity = global.Infinity;+ var nan = NaN;+ var infinity = Infinity; var global$0 = 10; function $0($0_1) { $0_1 = $0_1 | 0;@@ -36,19 +37,6 @@ }; } -var retasmFunc = asmFunc({- Math,- Int8Array,- Uint8Array,- Int16Array,- Uint16Array,- Int32Array,- Uint32Array,- Float32Array,- Float64Array,- NaN,- Infinity- }, {- abort: function() { throw new Error('abort'); }+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); } }); export var func_50 = retasmFunc.func_50;
binaryen/third_party/llvm-project/DWARFEmitter.cpp view
@@ -190,9 +190,11 @@ // XXX BINARYEN Make sure we emit the right size. We should not change the // size as we only modify relocatable fields like addresses, and such fields // have a fixed size, so any change is a bug.+ // We make an exception for AddrSizeChanged, which happens when we have run+ // the Memory64Lowering pass to turn wasm64 into wasm32. void onEndCompileUnit(const DWARFYAML::Unit &CU) { size_t EndPos = OS.tell();- if (EndPos - StartPos != CU.Length.getLength()) {+ if (EndPos - StartPos != CU.Length.getLength() && !CU.AddrSizeChanged) { llvm_unreachable("compile unit size was incorrect"); } }
binaryen/third_party/llvm-project/include/llvm/ObjectYAML/DWARFYAML.h view
@@ -128,6 +128,7 @@ llvm::dwarf::UnitType Type; // Added in DWARF 5 uint32_t AbbrOffset; uint8_t AddrSize;+ bool AddrSizeChanged = false; // XXX BINARYEN std::vector<Entry> Entries; };
src/Binaryen/Expression.hs view
@@ -406,7 +406,7 @@ foreign import ccall unsafe "BinaryenRefFunc" refFunc ::- Module -> Ptr CChar -> IO Expression+ Module -> Ptr CChar -> Type -> IO Expression foreign import ccall unsafe "BinaryenTry" try ::
src/Binaryen/Index.hs view
@@ -1,17 +1,25 @@+{-# LANGUAGE DerivingStrategies #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+ -- | The Binaryen index type. -- -- See <https://github.com/WebAssembly/binaryen/blob/master/src/binaryen-c.h> -- for API documentation. -- -- This module is intended to be imported qualified.--{-# LANGUAGE DerivingStrategies #-}-{-# LANGUAGE GeneralizedNewtypeDeriving #-}- module Binaryen.Index where import Data.Word (Word32) import Foreign (Storable) newtype Index = Index Word32- deriving newtype (Eq, Num, Show, Storable)+ deriving newtype+ ( Enum,+ Eq,+ Integral,+ Num,+ Ord,+ Real,+ Show,+ Storable+ )
src/Binaryen/Module.hs view
@@ -1,26 +1,36 @@+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+ -- | Modules. -- -- See <https://github.com/WebAssembly/binaryen/blob/master/src/binaryen-c.h> -- for API documentation. -- -- This module is intended to be imported qualified.--{-# LANGUAGE GeneralizedNewtypeDeriving #-}- module Binaryen.Module where -import Binaryen.Index import Binaryen.Event import Binaryen.Export import Binaryen.Expression import Binaryen.Features import Binaryen.Function import Binaryen.Global+import Binaryen.Index import Binaryen.Type import Data.Int (Int8)-import Data.Word (Word8, Word32)-import Foreign (Ptr, Storable)-import Foreign.C (CChar(..), CInt(..), CSize(..), CUIntPtr(..))+import Data.Word+ ( Word32,+ Word8,+ )+import Foreign+ ( Ptr,+ Storable,+ )+import Foreign.C+ ( CChar (..),+ CInt (..),+ CSize (..),+ CUIntPtr (..),+ ) newtype Module = Module (Ptr Module) deriving (Eq, Show, Storable)@@ -54,7 +64,7 @@ foreign import ccall unsafe "BinaryenGetNumFunctions" getNumFunctions ::- Module -> IO Word32+ Module -> IO Index foreign import ccall unsafe "BinaryenGetFunctionByIndex" getFunctionByIndex ::@@ -258,7 +268,7 @@ foreign import ccall unsafe "BinaryenGetNumExports" getNumExports ::- Module -> IO Word32+ Module -> IO Index foreign import ccall unsafe "BinaryenGetExportByIndex" getExportByIndex ::
src/Binaryen/Op.hs view
@@ -536,10 +536,6 @@ foreign import ccall unsafe "BinaryenNegVecI64x2" negVecI64x2 :: Op -foreign import ccall unsafe "BinaryenAnyTrueVecI64x2" anyTrueVecI64x2 :: Op--foreign import ccall unsafe "BinaryenAllTrueVecI64x2" allTrueVecI64x2 :: Op- foreign import ccall unsafe "BinaryenShlVecI64x2" shlVecI64x2 :: Op foreign import ccall unsafe "BinaryenShrSVecI64x2" shrSVecI64x2 :: Op