From 234e72a5b317a8c77ce21fea28b238644ff20868 Mon Sep 17 00:00:00 2001 From: Denis Merigoux Date: Thu, 10 Aug 2017 16:05:04 -0700 Subject: [PATCH] Dumped code from the wasm2cretonne repo --- Cargo.toml | 3 +- lib/wasm2cretonne-util/Cargo.toml | 22 + lib/wasm2cretonne-util/README.md | 62 + lib/wasm2cretonne-util/filetests/arith.wasm | Bin 0 -> 57 bytes lib/wasm2cretonne-util/filetests/arith.wast | 13 + lib/wasm2cretonne-util/filetests/call.wasm | Bin 0 -> 46 bytes lib/wasm2cretonne-util/filetests/call.wast | 10 + lib/wasm2cretonne-util/filetests/globals.wasm | Bin 0 -> 49 bytes lib/wasm2cretonne-util/filetests/globals.wast | 8 + lib/wasm2cretonne-util/filetests/memory.wasm | Bin 0 -> 76 bytes lib/wasm2cretonne-util/filetests/memory.wast | 11 + lib/wasm2cretonne-util/filetests/sample.wasm | Bin 0 -> 45 bytes lib/wasm2cretonne-util/src/main.rs | 440 ++++++ .../testsuite/address.wast.0.wasm | Bin 0 -> 205 bytes .../testsuite/binary.wast.0.wasm | Bin 0 -> 8 bytes .../testsuite/binary.wast.1.wasm | Bin 0 -> 8 bytes .../testsuite/binary.wast.2.wasm | Bin 0 -> 8 bytes .../testsuite/binary.wast.3.wasm | Bin 0 -> 8 bytes .../testsuite/block.wast.0.wasm | Bin 0 -> 709 bytes .../testsuite/br.wast.0.wasm | Bin 0 -> 2093 bytes .../testsuite/br_if.wast.0.wasm | Bin 0 -> 746 bytes .../testsuite/br_table.wast.0.wasm | Bin 0 -> 27334 bytes .../testsuite/break-drop.wast.0.wasm | Bin 0 -> 79 bytes .../testsuite/call.wast.0.wasm | Bin 0 -> 692 bytes .../testsuite/call_indirect.wast.0.wasm | Bin 0 -> 873 bytes .../testsuite/comments.wast.0.wasm | Bin 0 -> 8 bytes .../testsuite/comments.wast.1.wasm | Bin 0 -> 8 bytes .../testsuite/comments.wast.2.wasm | Bin 0 -> 8 bytes .../testsuite/comments.wast.3.wasm | Bin 0 -> 8 bytes .../testsuite/conversions.wast.0.wasm | Bin 0 -> 737 bytes .../testsuite/custom_section.wast.0.wasm | Bin 0 -> 8 bytes .../testsuite/custom_section.wast.1.wasm | Bin 0 -> 8 bytes .../testsuite/custom_section.wast.2.wasm | Bin 0 -> 44 bytes .../testsuite/endianness.wast.0.wasm | Bin 0 -> 682 bytes .../testsuite/exports.wast.0.wasm | Bin 0 -> 31 bytes .../testsuite/exports.wast.1.wasm | Bin 0 -> 35 bytes .../testsuite/exports.wast.10.wasm | Bin 0 -> 8 bytes .../testsuite/exports.wast.11.wasm | Bin 0 -> 8 bytes .../testsuite/exports.wast.18.wasm | Bin 0 -> 23 bytes .../testsuite/exports.wast.19.wasm | Bin 0 -> 27 bytes .../testsuite/exports.wast.2.wasm | Bin 0 -> 39 bytes .../testsuite/exports.wast.20.wasm | Bin 0 -> 32 bytes .../testsuite/exports.wast.21.wasm | Bin 0 -> 23 bytes .../testsuite/exports.wast.22.wasm | Bin 0 -> 23 bytes .../testsuite/exports.wast.23.wasm | Bin 0 -> 23 bytes .../testsuite/exports.wast.24.wasm | Bin 0 -> 23 bytes .../testsuite/exports.wast.25.wasm | Bin 0 -> 23 bytes .../testsuite/exports.wast.26.wasm | Bin 0 -> 23 bytes .../testsuite/exports.wast.27.wasm | Bin 0 -> 23 bytes .../testsuite/exports.wast.28.wasm | Bin 0 -> 8 bytes .../testsuite/exports.wast.29.wasm | Bin 0 -> 8 bytes .../testsuite/exports.wast.3.wasm | Bin 0 -> 31 bytes .../testsuite/exports.wast.36.wasm | Bin 0 -> 21 bytes .../testsuite/exports.wast.37.wasm | Bin 0 -> 25 bytes .../testsuite/exports.wast.38.wasm | Bin 0 -> 21 bytes .../testsuite/exports.wast.39.wasm | Bin 0 -> 22 bytes .../testsuite/exports.wast.4.wasm | Bin 0 -> 31 bytes .../testsuite/exports.wast.40.wasm | Bin 0 -> 21 bytes .../testsuite/exports.wast.41.wasm | Bin 0 -> 22 bytes .../testsuite/exports.wast.42.wasm | Bin 0 -> 21 bytes .../testsuite/exports.wast.43.wasm | Bin 0 -> 22 bytes .../testsuite/exports.wast.44.wasm | Bin 0 -> 21 bytes .../testsuite/exports.wast.45.wasm | Bin 0 -> 22 bytes .../testsuite/exports.wast.46.wasm | Bin 0 -> 21 bytes .../testsuite/exports.wast.47.wasm | Bin 0 -> 22 bytes .../testsuite/exports.wast.48.wasm | Bin 0 -> 21 bytes .../testsuite/exports.wast.49.wasm | Bin 0 -> 22 bytes .../testsuite/exports.wast.5.wasm | Bin 0 -> 31 bytes .../testsuite/exports.wast.55.wasm | Bin 0 -> 20 bytes .../testsuite/exports.wast.56.wasm | Bin 0 -> 24 bytes .../testsuite/exports.wast.57.wasm | Bin 0 -> 20 bytes .../testsuite/exports.wast.58.wasm | Bin 0 -> 21 bytes .../testsuite/exports.wast.59.wasm | Bin 0 -> 20 bytes .../testsuite/exports.wast.6.wasm | Bin 0 -> 31 bytes .../testsuite/exports.wast.60.wasm | Bin 0 -> 21 bytes .../testsuite/exports.wast.61.wasm | Bin 0 -> 20 bytes .../testsuite/exports.wast.62.wasm | Bin 0 -> 21 bytes .../testsuite/exports.wast.63.wasm | Bin 0 -> 20 bytes .../testsuite/exports.wast.64.wasm | Bin 0 -> 21 bytes .../testsuite/exports.wast.65.wasm | Bin 0 -> 20 bytes .../testsuite/exports.wast.66.wasm | Bin 0 -> 21 bytes .../testsuite/exports.wast.67.wasm | Bin 0 -> 20 bytes .../testsuite/exports.wast.68.wasm | Bin 0 -> 21 bytes .../testsuite/exports.wast.7.wasm | Bin 0 -> 31 bytes .../testsuite/exports.wast.8.wasm | Bin 0 -> 31 bytes .../testsuite/exports.wast.9.wasm | Bin 0 -> 39 bytes .../testsuite/f32.wast.0.wasm | Bin 0 -> 196 bytes .../testsuite/f32_bitwise.wast.0.wasm | Bin 0 -> 77 bytes .../testsuite/f32_cmp.wast.0.wasm | Bin 0 -> 110 bytes .../testsuite/f64.wast.0.wasm | Bin 0 -> 196 bytes .../testsuite/f64_bitwise.wast.0.wasm | Bin 0 -> 77 bytes .../testsuite/f64_cmp.wast.0.wasm | Bin 0 -> 110 bytes .../testsuite/fac.wast.0.wasm | Bin 0 -> 290 bytes .../testsuite/float_exprs.wast.0.wasm | Bin 0 -> 60 bytes .../testsuite/float_exprs.wast.1.wasm | Bin 0 -> 84 bytes .../testsuite/float_exprs.wast.10.wasm | Bin 0 -> 104 bytes .../testsuite/float_exprs.wast.11.wasm | Bin 0 -> 104 bytes .../testsuite/float_exprs.wast.12.wasm | Bin 0 -> 92 bytes .../testsuite/float_exprs.wast.13.wasm | Bin 0 -> 92 bytes .../testsuite/float_exprs.wast.14.wasm | Bin 0 -> 94 bytes .../testsuite/float_exprs.wast.15.wasm | Bin 0 -> 94 bytes .../testsuite/float_exprs.wast.16.wasm | Bin 0 -> 98 bytes .../testsuite/float_exprs.wast.17.wasm | Bin 0 -> 96 bytes .../testsuite/float_exprs.wast.18.wasm | Bin 0 -> 98 bytes .../testsuite/float_exprs.wast.19.wasm | Bin 0 -> 108 bytes .../testsuite/float_exprs.wast.2.wasm | Bin 0 -> 104 bytes .../testsuite/float_exprs.wast.20.wasm | Bin 0 -> 108 bytes .../testsuite/float_exprs.wast.21.wasm | Bin 0 -> 116 bytes .../testsuite/float_exprs.wast.22.wasm | Bin 0 -> 116 bytes .../testsuite/float_exprs.wast.23.wasm | Bin 0 -> 98 bytes .../testsuite/float_exprs.wast.24.wasm | Bin 0 -> 104 bytes .../testsuite/float_exprs.wast.25.wasm | Bin 0 -> 110 bytes .../testsuite/float_exprs.wast.26.wasm | Bin 0 -> 69 bytes .../testsuite/float_exprs.wast.27.wasm | Bin 0 -> 127 bytes .../testsuite/float_exprs.wast.28.wasm | Bin 0 -> 75 bytes .../testsuite/float_exprs.wast.29.wasm | Bin 0 -> 142 bytes .../testsuite/float_exprs.wast.3.wasm | Bin 0 -> 104 bytes .../testsuite/float_exprs.wast.30.wasm | Bin 0 -> 100 bytes .../testsuite/float_exprs.wast.31.wasm | Bin 0 -> 100 bytes .../testsuite/float_exprs.wast.32.wasm | Bin 0 -> 100 bytes .../testsuite/float_exprs.wast.33.wasm | Bin 0 -> 100 bytes .../testsuite/float_exprs.wast.34.wasm | Bin 0 -> 122 bytes .../testsuite/float_exprs.wast.35.wasm | Bin 0 -> 58 bytes .../testsuite/float_exprs.wast.36.wasm | Bin 0 -> 58 bytes .../testsuite/float_exprs.wast.37.wasm | Bin 0 -> 107 bytes .../testsuite/float_exprs.wast.38.wasm | Bin 0 -> 59 bytes .../testsuite/float_exprs.wast.39.wasm | Bin 0 -> 735 bytes .../testsuite/float_exprs.wast.4.wasm | Bin 0 -> 104 bytes .../testsuite/float_exprs.wast.40.wasm | Bin 0 -> 116 bytes .../testsuite/float_exprs.wast.41.wasm | Bin 0 -> 116 bytes .../testsuite/float_exprs.wast.42.wasm | Bin 0 -> 192 bytes .../testsuite/float_exprs.wast.43.wasm | Bin 0 -> 337 bytes .../testsuite/float_exprs.wast.44.wasm | Bin 0 -> 330 bytes .../testsuite/float_exprs.wast.45.wasm | Bin 0 -> 440 bytes .../testsuite/float_exprs.wast.46.wasm | Bin 0 -> 432 bytes .../testsuite/float_exprs.wast.47.wasm | Bin 0 -> 152 bytes .../testsuite/float_exprs.wast.48.wasm | Bin 0 -> 110 bytes .../testsuite/float_exprs.wast.49.wasm | Bin 0 -> 122 bytes .../testsuite/float_exprs.wast.5.wasm | Bin 0 -> 104 bytes .../testsuite/float_exprs.wast.50.wasm | Bin 0 -> 58 bytes .../testsuite/float_exprs.wast.51.wasm | Bin 0 -> 60 bytes .../testsuite/float_exprs.wast.52.wasm | Bin 0 -> 64 bytes .../testsuite/float_exprs.wast.53.wasm | Bin 0 -> 114 bytes .../testsuite/float_exprs.wast.54.wasm | Bin 0 -> 47 bytes .../testsuite/float_exprs.wast.55.wasm | Bin 0 -> 98 bytes .../testsuite/float_exprs.wast.56.wasm | Bin 0 -> 126 bytes .../testsuite/float_exprs.wast.57.wasm | Bin 0 -> 120 bytes .../testsuite/float_exprs.wast.58.wasm | Bin 0 -> 120 bytes .../testsuite/float_exprs.wast.59.wasm | Bin 0 -> 235 bytes .../testsuite/float_exprs.wast.6.wasm | Bin 0 -> 102 bytes .../testsuite/float_exprs.wast.60.wasm | Bin 0 -> 283 bytes .../testsuite/float_exprs.wast.61.wasm | Bin 0 -> 1197 bytes .../testsuite/float_exprs.wast.62.wasm | Bin 0 -> 2221 bytes .../testsuite/float_exprs.wast.63.wasm | Bin 0 -> 96 bytes .../testsuite/float_exprs.wast.64.wasm | Bin 0 -> 96 bytes .../testsuite/float_exprs.wast.65.wasm | Bin 0 -> 106 bytes .../testsuite/float_exprs.wast.66.wasm | Bin 0 -> 94 bytes .../testsuite/float_exprs.wast.67.wasm | Bin 0 -> 122 bytes .../testsuite/float_exprs.wast.68.wasm | Bin 0 -> 102 bytes .../testsuite/float_exprs.wast.69.wasm | Bin 0 -> 112 bytes .../testsuite/float_exprs.wast.7.wasm | Bin 0 -> 104 bytes .../testsuite/float_exprs.wast.70.wasm | Bin 0 -> 110 bytes .../testsuite/float_exprs.wast.71.wasm | Bin 0 -> 102 bytes .../testsuite/float_exprs.wast.72.wasm | Bin 0 -> 102 bytes .../testsuite/float_exprs.wast.73.wasm | Bin 0 -> 102 bytes .../testsuite/float_exprs.wast.74.wasm | Bin 0 -> 112 bytes .../testsuite/float_exprs.wast.75.wasm | Bin 0 -> 134 bytes .../testsuite/float_exprs.wast.76.wasm | Bin 0 -> 246 bytes .../testsuite/float_exprs.wast.77.wasm | Bin 0 -> 122 bytes .../testsuite/float_exprs.wast.78.wasm | Bin 0 -> 132 bytes .../testsuite/float_exprs.wast.79.wasm | Bin 0 -> 388 bytes .../testsuite/float_exprs.wast.8.wasm | Bin 0 -> 102 bytes .../testsuite/float_exprs.wast.80.wasm | Bin 0 -> 231 bytes .../testsuite/float_exprs.wast.81.wasm | Bin 0 -> 126 bytes .../testsuite/float_exprs.wast.82.wasm | Bin 0 -> 231 bytes .../testsuite/float_exprs.wast.83.wasm | Bin 0 -> 216 bytes .../testsuite/float_exprs.wast.84.wasm | Bin 0 -> 142 bytes .../testsuite/float_exprs.wast.85.wasm | Bin 0 -> 160 bytes .../testsuite/float_exprs.wast.86.wasm | Bin 0 -> 337 bytes .../testsuite/float_exprs.wast.87.wasm | Bin 0 -> 964 bytes .../testsuite/float_exprs.wast.88.wasm | Bin 0 -> 135 bytes .../testsuite/float_exprs.wast.89.wasm | Bin 0 -> 102 bytes .../testsuite/float_exprs.wast.9.wasm | Bin 0 -> 104 bytes .../testsuite/float_exprs.wast.90.wasm | Bin 0 -> 120 bytes .../testsuite/float_exprs.wast.91.wasm | Bin 0 -> 98 bytes .../testsuite/float_exprs.wast.92.wasm | Bin 0 -> 126 bytes .../testsuite/float_exprs.wast.93.wasm | Bin 0 -> 58 bytes .../testsuite/float_exprs.wast.94.wasm | Bin 0 -> 235 bytes .../testsuite/float_exprs.wast.95.wasm | Bin 0 -> 146 bytes .../testsuite/float_literals.wast.0.wasm | Bin 0 -> 1930 bytes .../testsuite/float_memory.wast.0.wasm | Bin 0 -> 161 bytes .../testsuite/float_memory.wast.1.wasm | Bin 0 -> 174 bytes .../testsuite/float_memory.wast.2.wasm | Bin 0 -> 162 bytes .../testsuite/float_memory.wast.3.wasm | Bin 0 -> 175 bytes .../testsuite/float_memory.wast.4.wasm | Bin 0 -> 161 bytes .../testsuite/float_memory.wast.5.wasm | Bin 0 -> 174 bytes .../testsuite/float_misc.wast.0.wasm | Bin 0 -> 578 bytes .../testsuite/forward.wast.0.wasm | Bin 0 -> 82 bytes .../testsuite/func.wast.0.wasm | Bin 0 -> 1951 bytes .../testsuite/func_ptrs.wast.0.wasm | Bin 0 -> 133 bytes .../testsuite/func_ptrs.wast.8.wasm | Bin 0 -> 119 bytes .../testsuite/func_ptrs.wast.9.wasm | Bin 0 -> 75 bytes .../testsuite/get_local.wast.0.wasm | Bin 0 -> 398 bytes .../testsuite/globals.wast.0.wasm | Bin 0 -> 291 bytes .../testsuite/globals.wast.16.wasm | Bin 0 -> 30 bytes .../testsuite/globals.wast.19.wasm | Bin 0 -> 16 bytes .../testsuite/i32.wast.0.wasm | Bin 0 -> 482 bytes .../testsuite/i64.wast.0.wasm | Bin 0 -> 493 bytes .../testsuite/if.wast.0.wasm | Bin 0 -> 706 bytes .../testsuite/imports.wast.0.wasm | Bin 0 -> 257 bytes .../testsuite/imports.wast.1.wasm | Bin 0 -> 346 bytes .../testsuite/imports.wast.10.wasm | Bin 0 -> 36 bytes .../testsuite/imports.wast.11.wasm | Bin 0 -> 30 bytes .../testsuite/imports.wast.12.wasm | Bin 0 -> 30 bytes .../testsuite/imports.wast.13.wasm | Bin 0 -> 31 bytes .../testsuite/imports.wast.14.wasm | Bin 0 -> 33 bytes .../testsuite/imports.wast.15.wasm | Bin 0 -> 34 bytes .../testsuite/imports.wast.16.wasm | Bin 0 -> 34 bytes .../testsuite/imports.wast.17.wasm | Bin 0 -> 34 bytes .../testsuite/imports.wast.18.wasm | Bin 0 -> 35 bytes .../testsuite/imports.wast.19.wasm | Bin 0 -> 34 bytes .../testsuite/imports.wast.2.wasm | Bin 0 -> 29 bytes .../testsuite/imports.wast.20.wasm | Bin 0 -> 35 bytes .../testsuite/imports.wast.21.wasm | Bin 0 -> 35 bytes .../testsuite/imports.wast.22.wasm | Bin 0 -> 35 bytes .../testsuite/imports.wast.23.wasm | Bin 0 -> 36 bytes .../testsuite/imports.wast.24.wasm | Bin 0 -> 38 bytes .../testsuite/imports.wast.25.wasm | Bin 0 -> 39 bytes .../testsuite/imports.wast.26.wasm | Bin 0 -> 39 bytes .../testsuite/imports.wast.27.wasm | Bin 0 -> 36 bytes .../testsuite/imports.wast.28.wasm | Bin 0 -> 37 bytes .../testsuite/imports.wast.29.wasm | Bin 0 -> 37 bytes .../testsuite/imports.wast.3.wasm | Bin 0 -> 34 bytes .../testsuite/imports.wast.30.wasm | Bin 0 -> 35 bytes .../testsuite/imports.wast.31.wasm | Bin 0 -> 34 bytes .../testsuite/imports.wast.32.wasm | Bin 0 -> 35 bytes .../testsuite/imports.wast.33.wasm | Bin 0 -> 197 bytes .../testsuite/imports.wast.34.wasm | Bin 0 -> 30 bytes .../testsuite/imports.wast.35.wasm | Bin 0 -> 30 bytes .../testsuite/imports.wast.36.wasm | Bin 0 -> 27 bytes .../testsuite/imports.wast.37.wasm | Bin 0 -> 31 bytes .../testsuite/imports.wast.38.wasm | Bin 0 -> 24 bytes .../testsuite/imports.wast.39.wasm | Bin 0 -> 32 bytes .../testsuite/imports.wast.4.wasm | Bin 0 -> 34 bytes .../testsuite/imports.wast.40.wasm | Bin 0 -> 32 bytes .../testsuite/imports.wast.41.wasm | Bin 0 -> 29 bytes .../testsuite/imports.wast.42.wasm | Bin 0 -> 29 bytes .../testsuite/imports.wast.43.wasm | Bin 0 -> 30 bytes .../testsuite/imports.wast.44.wasm | Bin 0 -> 90 bytes .../testsuite/imports.wast.45.wasm | Bin 0 -> 90 bytes .../testsuite/imports.wast.49.wasm | Bin 0 -> 33 bytes .../testsuite/imports.wast.5.wasm | Bin 0 -> 35 bytes .../testsuite/imports.wast.50.wasm | Bin 0 -> 33 bytes .../testsuite/imports.wast.51.wasm | Bin 0 -> 33 bytes .../testsuite/imports.wast.52.wasm | Bin 0 -> 30 bytes .../testsuite/imports.wast.53.wasm | Bin 0 -> 30 bytes .../testsuite/imports.wast.54.wasm | Bin 0 -> 30 bytes .../testsuite/imports.wast.55.wasm | Bin 0 -> 31 bytes .../testsuite/imports.wast.56.wasm | Bin 0 -> 31 bytes .../testsuite/imports.wast.57.wasm | Bin 0 -> 31 bytes .../testsuite/imports.wast.58.wasm | Bin 0 -> 31 bytes .../testsuite/imports.wast.59.wasm | Bin 0 -> 31 bytes .../testsuite/imports.wast.6.wasm | Bin 0 -> 35 bytes .../testsuite/imports.wast.60.wasm | Bin 0 -> 28 bytes .../testsuite/imports.wast.61.wasm | Bin 0 -> 32 bytes .../testsuite/imports.wast.62.wasm | Bin 0 -> 33 bytes .../testsuite/imports.wast.63.wasm | Bin 0 -> 34 bytes .../testsuite/imports.wast.64.wasm | Bin 0 -> 30 bytes .../testsuite/imports.wast.65.wasm | Bin 0 -> 31 bytes .../testsuite/imports.wast.66.wasm | Bin 0 -> 25 bytes .../testsuite/imports.wast.67.wasm | Bin 0 -> 31 bytes .../testsuite/imports.wast.68.wasm | Bin 0 -> 33 bytes .../testsuite/imports.wast.69.wasm | Bin 0 -> 30 bytes .../testsuite/imports.wast.7.wasm | Bin 0 -> 40 bytes .../testsuite/imports.wast.70.wasm | Bin 0 -> 73 bytes .../testsuite/imports.wast.71.wasm | Bin 0 -> 73 bytes .../testsuite/imports.wast.75.wasm | Bin 0 -> 32 bytes .../testsuite/imports.wast.76.wasm | Bin 0 -> 32 bytes .../testsuite/imports.wast.77.wasm | Bin 0 -> 32 bytes .../testsuite/imports.wast.78.wasm | Bin 0 -> 30 bytes .../testsuite/imports.wast.79.wasm | Bin 0 -> 30 bytes .../testsuite/imports.wast.8.wasm | Bin 0 -> 40 bytes .../testsuite/imports.wast.80.wasm | Bin 0 -> 31 bytes .../testsuite/imports.wast.81.wasm | Bin 0 -> 31 bytes .../testsuite/imports.wast.82.wasm | Bin 0 -> 31 bytes .../testsuite/imports.wast.83.wasm | Bin 0 -> 31 bytes .../testsuite/imports.wast.84.wasm | Bin 0 -> 27 bytes .../testsuite/imports.wast.85.wasm | Bin 0 -> 31 bytes .../testsuite/imports.wast.86.wasm | Bin 0 -> 32 bytes .../testsuite/imports.wast.87.wasm | Bin 0 -> 33 bytes .../testsuite/imports.wast.88.wasm | Bin 0 -> 30 bytes .../testsuite/imports.wast.89.wasm | Bin 0 -> 31 bytes .../testsuite/imports.wast.9.wasm | Bin 0 -> 32 bytes .../testsuite/imports.wast.90.wasm | Bin 0 -> 28 bytes .../testsuite/imports.wast.91.wasm | Bin 0 -> 30 bytes .../testsuite/imports.wast.92.wasm | Bin 0 -> 32 bytes .../testsuite/imports.wast.93.wasm | Bin 0 -> 29 bytes .../testsuite/imports.wast.94.wasm | Bin 0 -> 30 bytes .../testsuite/imports.wast.95.wasm | Bin 0 -> 29 bytes .../testsuite/imports.wast.96.wasm | Bin 0 -> 30 bytes .../testsuite/imports.wast.97.wasm | Bin 0 -> 31 bytes .../testsuite/imports.wast.98.wasm | Bin 0 -> 63 bytes .../testsuite/int_exprs.wast.0.wasm | Bin 0 -> 200 bytes .../testsuite/int_exprs.wast.1.wasm | Bin 0 -> 61 bytes .../testsuite/int_exprs.wast.10.wasm | Bin 0 -> 92 bytes .../testsuite/int_exprs.wast.11.wasm | Bin 0 -> 122 bytes .../testsuite/int_exprs.wast.12.wasm | Bin 0 -> 122 bytes .../testsuite/int_exprs.wast.13.wasm | Bin 0 -> 122 bytes .../testsuite/int_exprs.wast.14.wasm | Bin 0 -> 122 bytes .../testsuite/int_exprs.wast.15.wasm | Bin 0 -> 122 bytes .../testsuite/int_exprs.wast.16.wasm | Bin 0 -> 122 bytes .../testsuite/int_exprs.wast.17.wasm | Bin 0 -> 122 bytes .../testsuite/int_exprs.wast.18.wasm | Bin 0 -> 94 bytes .../testsuite/int_exprs.wast.2.wasm | Bin 0 -> 61 bytes .../testsuite/int_exprs.wast.3.wasm | Bin 0 -> 174 bytes .../testsuite/int_exprs.wast.4.wasm | Bin 0 -> 174 bytes .../testsuite/int_exprs.wast.5.wasm | Bin 0 -> 174 bytes .../testsuite/int_exprs.wast.6.wasm | Bin 0 -> 166 bytes .../testsuite/int_exprs.wast.7.wasm | Bin 0 -> 166 bytes .../testsuite/int_exprs.wast.8.wasm | Bin 0 -> 174 bytes .../testsuite/int_exprs.wast.9.wasm | Bin 0 -> 92 bytes .../testsuite/int_literals.wast.0.wasm | Bin 0 -> 585 bytes .../testsuite/labels.wast.0.wasm | Bin 0 -> 948 bytes .../testsuite/left-to-right.wast.0.wasm | Bin 0 -> 3015 bytes .../testsuite/linking.wast.0.wasm | Bin 0 -> 43 bytes .../testsuite/linking.wast.1.wasm | Bin 0 -> 87 bytes .../testsuite/linking.wast.15.wasm | Bin 0 -> 71 bytes .../testsuite/linking.wast.16.wasm | Bin 0 -> 83 bytes .../testsuite/linking.wast.17.wasm | Bin 0 -> 70 bytes .../testsuite/linking.wast.2.wasm | Bin 0 -> 46 bytes .../testsuite/linking.wast.3.wasm | Bin 0 -> 37 bytes .../testsuite/linking.wast.4.wasm | Bin 0 -> 38 bytes .../testsuite/linking.wast.5.wasm | Bin 0 -> 51 bytes .../testsuite/linking.wast.6.wasm | Bin 0 -> 93 bytes .../testsuite/linking.wast.7.wasm | Bin 0 -> 88 bytes .../testsuite/linking.wast.8.wasm | Bin 0 -> 127 bytes .../testsuite/linking.wast.9.wasm | Bin 0 -> 82 bytes .../testsuite/loop.wast.0.wasm | Bin 0 -> 1060 bytes .../testsuite/memory.wast.0.wasm | Bin 0 -> 14 bytes .../testsuite/memory.wast.1.wasm | Bin 0 -> 14 bytes .../testsuite/memory.wast.15.wasm | Bin 0 -> 55 bytes .../testsuite/memory.wast.2.wasm | Bin 0 -> 15 bytes .../testsuite/memory.wast.3.wasm | Bin 0 -> 16 bytes .../testsuite/memory.wast.39.wasm | Bin 0 -> 33 bytes .../testsuite/memory.wast.40.wasm | Bin 0 -> 31 bytes .../testsuite/memory.wast.41.wasm | Bin 0 -> 35 bytes .../testsuite/memory.wast.49.wasm | Bin 0 -> 35 bytes .../testsuite/memory.wast.50.wasm | Bin 0 -> 35 bytes .../testsuite/memory.wast.51.wasm | Bin 0 -> 35 bytes .../testsuite/memory.wast.52.wasm | Bin 0 -> 35 bytes .../testsuite/memory.wast.6.wasm | Bin 0 -> 23 bytes .../testsuite/memory.wast.62.wasm | Bin 0 -> 685 bytes .../testsuite/memory.wast.8.wasm | Bin 0 -> 35 bytes .../testsuite/memory_redundancy.wast.0.wasm | Bin 0 -> 319 bytes .../testsuite/memory_trap.wast.0.wasm | Bin 0 -> 113 bytes .../testsuite/memory_trap.wast.1.wasm | Bin 0 -> 629 bytes .../testsuite/names.wast.0.wasm | Bin 0 -> 36 bytes .../testsuite/names.wast.1.wasm | Bin 0 -> 36 bytes .../testsuite/names.wast.2.wasm | Bin 0 -> 7488 bytes .../testsuite/names.wast.3.wasm | Bin 0 -> 88 bytes .../testsuite/nop.wast.0.wasm | Bin 0 -> 1496 bytes lib/wasm2cretonne-util/testsuite/reloc.wasm | Bin 0 -> 563 bytes .../testsuite/resizing.wast.0.wasm | Bin 0 -> 181 bytes .../testsuite/resizing.wast.1.wasm | Bin 0 -> 45 bytes .../testsuite/resizing.wast.2.wasm | Bin 0 -> 46 bytes .../testsuite/return.wast.0.wasm | Bin 0 -> 1653 bytes .../testsuite/select.wast.0.wasm | Bin 0 -> 249 bytes .../testsuite/set_local.wast.0.wasm | Bin 0 -> 454 bytes lib/wasm2cretonne-util/testsuite/simple.wasm | Bin 0 -> 41 bytes .../skip-stack-guard-page.wast.0.wasm | Bin 0 -> 18586 bytes .../testsuite/stack.wast.0.wasm | Bin 0 -> 341 bytes .../testsuite/start.wast.3.wasm | Bin 0 -> 94 bytes .../testsuite/start.wast.4.wasm | Bin 0 -> 94 bytes .../testsuite/start.wast.5.wasm | Bin 0 -> 55 bytes .../testsuite/start.wast.6.wasm | Bin 0 -> 55 bytes .../testsuite/start.wast.7.wasm | Bin 0 -> 37 bytes .../testsuite/start.wast.8.wasm | Bin 0 -> 28 bytes .../testsuite/switch.wast.0.wasm | Bin 0 -> 289 bytes .../testsuite/tee_local.wast.0.wasm | Bin 0 -> 594 bytes .../testsuite/traps.wast.0.wasm | Bin 0 -> 146 bytes .../testsuite/traps.wast.1.wasm | Bin 0 -> 146 bytes .../testsuite/traps.wast.2.wasm | Bin 0 -> 293 bytes .../testsuite/traps.wast.3.wasm | Bin 0 -> 458 bytes .../testsuite/unreachable.wast.0.wasm | Bin 0 -> 1647 bytes .../testsuite/unwind.wast.0.wasm | Bin 0 -> 1713 bytes lib/wasm2cretonne/.gitignore | 3 + lib/wasm2cretonne/Cargo.toml | 10 + lib/wasm2cretonne/src/code_translator.rs | 1375 +++++++++++++++++ lib/wasm2cretonne/src/lib.rs | 27 + lib/wasm2cretonne/src/module_translator.rs | 288 ++++ lib/wasm2cretonne/src/runtime/dummy.rs | 93 ++ lib/wasm2cretonne/src/runtime/mod.rs | 5 + lib/wasm2cretonne/src/runtime/spec.rs | 61 + lib/wasm2cretonne/src/sections_translator.rs | 367 +++++ lib/wasm2cretonne/src/translation_utils.rs | 138 ++ lib/wasmstandalone/.gitignore | 3 + lib/wasmstandalone/Cargo.toml | 11 + lib/wasmstandalone/src/execution.rs | 256 +++ lib/wasmstandalone/src/lib.rs | 15 + lib/wasmstandalone/src/standalone.rs | 332 ++++ 400 files changed, 3552 insertions(+), 1 deletion(-) create mode 100644 lib/wasm2cretonne-util/Cargo.toml create mode 100644 lib/wasm2cretonne-util/README.md create mode 100644 lib/wasm2cretonne-util/filetests/arith.wasm create mode 100644 lib/wasm2cretonne-util/filetests/arith.wast create mode 100644 lib/wasm2cretonne-util/filetests/call.wasm create mode 100644 lib/wasm2cretonne-util/filetests/call.wast create mode 100644 lib/wasm2cretonne-util/filetests/globals.wasm create mode 100644 lib/wasm2cretonne-util/filetests/globals.wast create mode 100644 lib/wasm2cretonne-util/filetests/memory.wasm create mode 100644 lib/wasm2cretonne-util/filetests/memory.wast create mode 100644 lib/wasm2cretonne-util/filetests/sample.wasm create mode 100644 lib/wasm2cretonne-util/src/main.rs create mode 100644 lib/wasm2cretonne-util/testsuite/address.wast.0.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/binary.wast.0.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/binary.wast.1.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/binary.wast.2.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/binary.wast.3.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/block.wast.0.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/br.wast.0.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/br_if.wast.0.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/br_table.wast.0.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/break-drop.wast.0.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/call.wast.0.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/call_indirect.wast.0.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/comments.wast.0.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/comments.wast.1.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/comments.wast.2.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/comments.wast.3.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/conversions.wast.0.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/custom_section.wast.0.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/custom_section.wast.1.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/custom_section.wast.2.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/endianness.wast.0.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/exports.wast.0.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/exports.wast.1.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/exports.wast.10.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/exports.wast.11.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/exports.wast.18.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/exports.wast.19.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/exports.wast.2.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/exports.wast.20.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/exports.wast.21.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/exports.wast.22.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/exports.wast.23.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/exports.wast.24.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/exports.wast.25.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/exports.wast.26.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/exports.wast.27.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/exports.wast.28.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/exports.wast.29.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/exports.wast.3.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/exports.wast.36.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/exports.wast.37.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/exports.wast.38.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/exports.wast.39.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/exports.wast.4.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/exports.wast.40.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/exports.wast.41.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/exports.wast.42.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/exports.wast.43.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/exports.wast.44.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/exports.wast.45.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/exports.wast.46.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/exports.wast.47.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/exports.wast.48.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/exports.wast.49.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/exports.wast.5.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/exports.wast.55.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/exports.wast.56.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/exports.wast.57.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/exports.wast.58.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/exports.wast.59.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/exports.wast.6.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/exports.wast.60.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/exports.wast.61.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/exports.wast.62.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/exports.wast.63.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/exports.wast.64.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/exports.wast.65.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/exports.wast.66.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/exports.wast.67.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/exports.wast.68.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/exports.wast.7.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/exports.wast.8.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/exports.wast.9.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/f32.wast.0.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/f32_bitwise.wast.0.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/f32_cmp.wast.0.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/f64.wast.0.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/f64_bitwise.wast.0.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/f64_cmp.wast.0.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/fac.wast.0.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.0.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.1.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.10.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.11.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.12.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.13.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.14.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.15.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.16.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.17.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.18.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.19.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.2.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.20.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.21.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.22.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.23.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.24.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.25.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.26.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.27.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.28.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.29.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.3.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.30.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.31.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.32.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.33.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.34.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.35.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.36.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.37.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.38.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.39.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.4.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.40.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.41.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.42.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.43.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.44.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.45.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.46.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.47.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.48.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.49.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.5.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.50.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.51.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.52.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.53.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.54.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.55.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.56.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.57.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.58.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.59.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.6.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.60.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.61.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.62.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.63.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.64.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.65.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.66.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.67.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.68.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.69.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.7.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.70.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.71.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.72.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.73.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.74.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.75.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.76.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.77.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.78.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.79.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.8.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.80.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.81.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.82.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.83.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.84.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.85.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.86.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.87.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.88.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.89.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.9.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.90.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.91.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.92.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.93.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.94.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_exprs.wast.95.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_literals.wast.0.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_memory.wast.0.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_memory.wast.1.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_memory.wast.2.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_memory.wast.3.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_memory.wast.4.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_memory.wast.5.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/float_misc.wast.0.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/forward.wast.0.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/func.wast.0.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/func_ptrs.wast.0.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/func_ptrs.wast.8.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/func_ptrs.wast.9.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/get_local.wast.0.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/globals.wast.0.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/globals.wast.16.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/globals.wast.19.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/i32.wast.0.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/i64.wast.0.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/if.wast.0.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.0.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.1.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.10.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.11.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.12.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.13.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.14.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.15.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.16.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.17.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.18.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.19.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.2.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.20.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.21.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.22.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.23.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.24.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.25.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.26.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.27.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.28.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.29.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.3.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.30.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.31.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.32.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.33.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.34.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.35.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.36.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.37.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.38.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.39.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.4.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.40.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.41.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.42.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.43.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.44.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.45.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.49.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.5.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.50.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.51.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.52.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.53.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.54.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.55.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.56.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.57.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.58.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.59.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.6.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.60.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.61.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.62.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.63.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.64.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.65.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.66.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.67.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.68.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.69.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.7.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.70.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.71.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.75.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.76.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.77.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.78.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.79.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.8.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.80.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.81.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.82.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.83.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.84.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.85.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.86.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.87.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.88.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.89.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.9.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.90.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.91.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.92.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.93.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.94.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.95.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.96.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.97.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/imports.wast.98.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/int_exprs.wast.0.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/int_exprs.wast.1.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/int_exprs.wast.10.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/int_exprs.wast.11.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/int_exprs.wast.12.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/int_exprs.wast.13.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/int_exprs.wast.14.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/int_exprs.wast.15.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/int_exprs.wast.16.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/int_exprs.wast.17.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/int_exprs.wast.18.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/int_exprs.wast.2.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/int_exprs.wast.3.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/int_exprs.wast.4.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/int_exprs.wast.5.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/int_exprs.wast.6.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/int_exprs.wast.7.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/int_exprs.wast.8.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/int_exprs.wast.9.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/int_literals.wast.0.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/labels.wast.0.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/left-to-right.wast.0.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/linking.wast.0.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/linking.wast.1.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/linking.wast.15.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/linking.wast.16.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/linking.wast.17.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/linking.wast.2.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/linking.wast.3.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/linking.wast.4.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/linking.wast.5.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/linking.wast.6.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/linking.wast.7.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/linking.wast.8.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/linking.wast.9.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/loop.wast.0.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/memory.wast.0.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/memory.wast.1.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/memory.wast.15.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/memory.wast.2.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/memory.wast.3.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/memory.wast.39.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/memory.wast.40.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/memory.wast.41.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/memory.wast.49.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/memory.wast.50.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/memory.wast.51.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/memory.wast.52.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/memory.wast.6.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/memory.wast.62.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/memory.wast.8.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/memory_redundancy.wast.0.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/memory_trap.wast.0.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/memory_trap.wast.1.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/names.wast.0.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/names.wast.1.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/names.wast.2.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/names.wast.3.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/nop.wast.0.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/reloc.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/resizing.wast.0.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/resizing.wast.1.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/resizing.wast.2.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/return.wast.0.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/select.wast.0.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/set_local.wast.0.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/simple.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/skip-stack-guard-page.wast.0.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/stack.wast.0.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/start.wast.3.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/start.wast.4.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/start.wast.5.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/start.wast.6.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/start.wast.7.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/start.wast.8.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/switch.wast.0.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/tee_local.wast.0.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/traps.wast.0.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/traps.wast.1.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/traps.wast.2.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/traps.wast.3.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/unreachable.wast.0.wasm create mode 100644 lib/wasm2cretonne-util/testsuite/unwind.wast.0.wasm create mode 100644 lib/wasm2cretonne/.gitignore create mode 100644 lib/wasm2cretonne/Cargo.toml create mode 100644 lib/wasm2cretonne/src/code_translator.rs create mode 100644 lib/wasm2cretonne/src/lib.rs create mode 100644 lib/wasm2cretonne/src/module_translator.rs create mode 100644 lib/wasm2cretonne/src/runtime/dummy.rs create mode 100644 lib/wasm2cretonne/src/runtime/mod.rs create mode 100644 lib/wasm2cretonne/src/runtime/spec.rs create mode 100644 lib/wasm2cretonne/src/sections_translator.rs create mode 100644 lib/wasm2cretonne/src/translation_utils.rs create mode 100644 lib/wasmstandalone/.gitignore create mode 100644 lib/wasmstandalone/Cargo.toml create mode 100644 lib/wasmstandalone/src/execution.rs create mode 100644 lib/wasmstandalone/src/lib.rs create mode 100644 lib/wasmstandalone/src/standalone.rs diff --git a/Cargo.toml b/Cargo.toml index 6df15bd86c..7fdbee1e07 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,8 @@ path = "src/cton-util.rs" [dependencies] cretonne = { path = "lib/cretonne" } cretonne-reader = { path = "lib/reader" } -cretonne-frontend = { path ="lib/frontend" } +cretonne-frontend = { path = "lib/frontend" } +wasm2cretonne-util = { path = "lib/wasm2cretonne-util" } filecheck = { path = "lib/filecheck" } docopt = "0.8.0" serde = "1.0.8" diff --git a/lib/wasm2cretonne-util/Cargo.toml b/lib/wasm2cretonne-util/Cargo.toml new file mode 100644 index 0000000000..a4f3eb94a6 --- /dev/null +++ b/lib/wasm2cretonne-util/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "wasm2cretonne-util" +version = "0.0.0" +authors = ["The Cretonne Project Developers"] +publish = false + +[[bin]] +name = "wasm2cretonne-util" +path = "src/main.rs" + +[dependencies] +wasm2cretonne = { path = "../wasm2cretonne" } +wasmstandalone = { path = "../wasmstandalone" } +wasmparser = "0.6.1" +cretonne = { path = "../cretonne" } +cretonne-frontend = { path = "../frontend" } +wasmtext = { git = "https://github.com/yurydelendik/wasmtext" } +docopt = "0.8.0" +serde = "1.0.8" +serde_derive = "1.0.8" +term = "*" +tempdir="*" diff --git a/lib/wasm2cretonne-util/README.md b/lib/wasm2cretonne-util/README.md new file mode 100644 index 0000000000..a3f63c05c6 --- /dev/null +++ b/lib/wasm2cretonne-util/README.md @@ -0,0 +1,62 @@ +# wasm2cretonne + +[Cretonne](https://github.com/stoklund/cretonne) frontend for WebAssembly. Reads wasm binary modules and translate the functions it contains into Cretonne IL functions. + +The translation needs some info about the runtime in order to handle the wasm instructions `get_global`, `set_global`, and `call_indirect`. These informations are included in structs implementing the `WasmRuntime` trait like `DummyRuntime` or `StandaloneRuntime`. + + +The `StandaloneRuntime` is a setup for in-memory execution of the module just after translation to Cretonne IL. It allocates memory for the wasm linear memories, the globals and the tables and embeds the addresses of these memories inside the generated Cretonne IL functions. Then it runs Cretonne's compilation, emits the code to memory and executes the `start` function of the module. + +## API + +Use the functions defined in the crates `wasm2cretonne` and `wasmruntime`. + +### Example + +```rust +use wasm2cretonne::translate_module; +use wasmruntime::{StandaloneRuntime, compile_module, execute}; +use std::path::{Path, PathBuf}; + +fn read_wasm_file(path: PathBuf) -> Result, io::Error> { + let mut buf: Vec = Vec::new(); + let file = File::open(path)?; + let mut buf_reader = BufReader::new(file); + buf_reader.read_to_end(&mut buf)?; + Ok(buf) +} + +let path = Path::new("filetests/arith.wasm"); +let data = match read_wasm_file(path.to_path_buf()) { + Ok(data) => data, + Err(err) => { + panic!("Error: {}", err); + } +}; +let mut runtime = StandaloneRuntime::new(); +let translation = match translate_module(&data, &mut runtime) { + Ok(x) => x, + Err(string) => { + panic!(string); + } +}; +let exec = compile_module(&translation, "intel"); +execute(exec); +println!("Memory after execution: {:?}", runtime.inspect_memory(0,0,4)); +``` + +## CLI tool + +The binary created by the root crate of this repo is an utility to parse, translate, compile and execute wasm binaries using Cretonne. Usage: + +``` +wasm2cretonne-util + -v, --verbose displays info on the different steps + -p, --print displays the module and translated functions + -c, --check checks the corectness of the translated functions + -o, --optimize runs optimization passes on the translated functions + -e, --execute enable the standalone runtime and executes the start function of the module + -m, --memory interactive memory inspector after execution +``` + +The tool reads `.wasm` files but also `.wast` as long as the [WebAssembly binary toolkit](https://github.com/WebAssembly/wabt)'s `wast2wasm` executable is accessible in your `PATH`. For now, only the 64 bits Intel architecture is supported for execution. diff --git a/lib/wasm2cretonne-util/filetests/arith.wasm b/lib/wasm2cretonne-util/filetests/arith.wasm new file mode 100644 index 0000000000000000000000000000000000000000..a393264a2aac2aad3e262823b3d9549905c3c226 GIT binary patch literal 57 zcmV~$+YNvq5Jkar1rp*$d!UrK{GtF`cZND%0gBonOdHxUPF CcmwJH literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/filetests/globals.wast b/lib/wasm2cretonne-util/filetests/globals.wast new file mode 100644 index 0000000000..646e5f0f45 --- /dev/null +++ b/lib/wasm2cretonne-util/filetests/globals.wast @@ -0,0 +1,8 @@ +(module + (global $x (mut i32) (i32.const 4)) + (memory 1) + (func $main (local i32) + (i32.store (i32.const 0) (get_global $x)) + ) + (start $main) +) diff --git a/lib/wasm2cretonne-util/filetests/memory.wasm b/lib/wasm2cretonne-util/filetests/memory.wasm new file mode 100644 index 0000000000000000000000000000000000000000..0d3074bb7e10f30983be06f9012938252ac944db GIT binary patch literal 76 zcmWNGu?>JQ5X5}RM?(265CtU_HQ6K#K*a#8&Rt>4I_~!opwNU`M5{uJ=$lsQ8w}23 S?1i{o-PP>0GqcNI#^L<|0tUwb literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/filetests/memory.wast b/lib/wasm2cretonne-util/filetests/memory.wast new file mode 100644 index 0000000000..0c81bad174 --- /dev/null +++ b/lib/wasm2cretonne-util/filetests/memory.wast @@ -0,0 +1,11 @@ +(module + (memory 1) + (func $main (local i32) + (i32.store (i32.const 0) (i32.const 0x0)) + (if (i32.load (i32.const 0)) + (then (i32.store (i32.const 0) (i32.const 0xa))) + (else (i32.store (i32.const 0) (i32.const 0xb)))) + ) + (start $main) + (data (i32.const 0) "0000") +) diff --git a/lib/wasm2cretonne-util/filetests/sample.wasm b/lib/wasm2cretonne-util/filetests/sample.wasm new file mode 100644 index 0000000000000000000000000000000000000000..0126305329e95ec56ce7952d525b25ea7acb1045 GIT binary patch literal 45 ycmZQbEY4+QU|?WmV@zPIXRK#tVr1YFXB1^nU~pv2W~o;IGO`?5a#$T1xVZs}Z3XWD literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/src/main.rs b/lib/wasm2cretonne-util/src/main.rs new file mode 100644 index 0000000000..8a1c7c95d3 --- /dev/null +++ b/lib/wasm2cretonne-util/src/main.rs @@ -0,0 +1,440 @@ +//! CLI tool to use the functions provided by crates [wasm2cretonne](../wasm2cretonne/index.html) +//! and [wasmstandalone](../wasmstandalone/index.html). +//! +//! Reads Wasm binary files (one Wasm module per file), translates the functions' code to Cretonne +//! IL. Can also executes the `start` function of the module by laying out the memories, globals +//! and tables, then emitting the translated code with hardcoded addresses to memory. + +extern crate wasm2cretonne; +extern crate wasmstandalone; +extern crate wasmparser; +extern crate cretonne; +extern crate wasmtext; +extern crate docopt; +extern crate serde; +#[macro_use] +extern crate serde_derive; +extern crate term; +extern crate tempdir; + +use wasm2cretonne::{translate_module, TranslationResult, FunctionTranslation, DummyRuntime, + WasmRuntime}; +use wasmstandalone::{StandaloneRuntime, compile_module, execute}; +use std::path::PathBuf; +use wasmparser::{Parser, ParserState, WasmDecoder, SectionCode}; +use wasmtext::Writer; +use cretonne::loop_analysis::LoopAnalysis; +use cretonne::flowgraph::ControlFlowGraph; +use cretonne::dominator_tree::DominatorTree; +use cretonne::Context; +use cretonne::result::CtonError; +use cretonne::ir; +use cretonne::ir::entities::AnyEntity; +use cretonne::isa::TargetIsa; +use cretonne::verifier; +use std::fs::File; +use std::error::Error; +use std::io; +use std::io::{BufReader, stdout}; +use std::io::prelude::*; +use docopt::Docopt; +use std::path::Path; +use std::process::Command; +use tempdir::TempDir; + +macro_rules! vprintln { + ($x: expr, $($tts:tt)*) => { + if $x { + println!($($tts)*); + } + } +} + +macro_rules! vprint { + ($x: expr, $($tts:tt)*) => { + if $x { + print!($($tts)*); + } + } +} + +const USAGE: &str = " +Wasm to Cretonne IL translation utility. +Takes a binary WebAssembly module and returns its functions in Cretonne IL format. +The translation is dependent on the runtime chosen. +The default is a dummy runtime that produces placeholder values. + +Usage: + wasm2cretonne-util [-vcop] ... + wasm2cretonne-util -e [-mvcop] ... + wasm2cretonne-util --help | --version + +Options: + -v, --verbose displays info on the different steps + -p, --print displays the module and translated functions + -c, --check checks the corectness of the translated functions + -o, --optimize runs optimization passes on the translated functions + -e, --execute enable the standalone runtime and executes the start function of the module + -m, --memory interactive memory inspector after execution + -h, --help print this help message + --version print the Cretonne version +"; + +#[derive(Deserialize, Debug, Clone)] +struct Args { + arg_file: Vec, + flag_verbose: bool, + flag_execute: bool, + flag_memory: bool, + flag_check: bool, + flag_optimize: bool, + flag_print: bool, +} + +fn read_wasm_file(path: PathBuf) -> Result, io::Error> { + let mut buf: Vec = Vec::new(); + let file = File::open(path)?; + let mut buf_reader = BufReader::new(file); + buf_reader.read_to_end(&mut buf)?; + Ok(buf) +} + + +fn main() { + let args: Args = Docopt::new(USAGE) + .and_then(|d| d.help(true).version(Some(format!("0.0.0"))).deserialize()) + .unwrap_or_else(|e| e.exit()); + let mut terminal = term::stdout().unwrap(); + for filename in args.arg_file.iter() { + let path = Path::new(&filename); + let name = String::from(path.as_os_str().to_string_lossy()); + match handle_module(&args, path.to_path_buf(), name) { + Ok(()) => {} + Err(message) => { + terminal.fg(term::color::RED).unwrap(); + vprintln!(args.flag_verbose, "error"); + terminal.reset().unwrap(); + vprintln!(args.flag_verbose, "{}", message) + } + } + } +} + +fn handle_module(args: &Args, path: PathBuf, name: String) -> Result<(), String> { + let mut terminal = term::stdout().unwrap(); + terminal.fg(term::color::YELLOW).unwrap(); + vprint!(args.flag_verbose, "Handling: "); + terminal.reset().unwrap(); + vprintln!(args.flag_verbose, "\"{}\"", name); + terminal.fg(term::color::MAGENTA).unwrap(); + vprint!(args.flag_verbose, "Translating..."); + terminal.reset().unwrap(); + let data = match path.extension() { + None => { + return Err(String::from("the file extension is not wasm or wast")); + } + Some(ext) => { + match ext.to_str() { + Some("wasm") => { + match read_wasm_file(path.clone()) { + Ok(data) => data, + Err(err) => { + return Err(String::from(err.description())); + } + } + } + Some("wast") => { + let tmp_dir = TempDir::new("wasm2cretonne").unwrap(); + let file_path = tmp_dir.path().join("module.wasm"); + File::create(file_path.clone()).unwrap(); + Command::new("wast2wasm") + .arg(path.clone()) + .arg("-o") + .arg(file_path.to_str().unwrap()) + .output() + .or_else(|e| if let io::ErrorKind::NotFound = e.kind() { + return Err(String::from("wast2wasm not found")); + } else { + return Err(String::from(e.description())); + }) + .unwrap(); + match read_wasm_file(file_path) { + Ok(data) => data, + Err(err) => { + return Err(String::from(err.description())); + } + } + } + None | Some(&_) => { + return Err(String::from("the file extension is not wasm or wast")); + } + } + } + }; + let mut dummy_runtime = DummyRuntime::new(); + let mut standalone_runtime = StandaloneRuntime::new(); + let translation = { + let mut runtime: &mut WasmRuntime = if args.flag_execute { + &mut standalone_runtime + } else { + &mut dummy_runtime + }; + match translate_module(&data, runtime) { + Ok(x) => x, + Err(string) => { + return Err(string); + } + } + }; + terminal.fg(term::color::GREEN).unwrap(); + vprintln!(args.flag_verbose, " ok"); + terminal.reset().unwrap(); + if args.flag_check { + terminal.fg(term::color::MAGENTA).unwrap(); + vprint!(args.flag_verbose, "Checking... "); + terminal.reset().unwrap(); + for func in translation.functions.iter() { + let il = match func { + &FunctionTranslation::Import() => continue, + &FunctionTranslation::Code { ref il, .. } => il.clone(), + }; + match verifier::verify_function(&il, None) { + Ok(()) => (), + Err(err) => return Err(pretty_verifier_error(&il, None, err)), + } + } + terminal.fg(term::color::GREEN).unwrap(); + vprintln!(args.flag_verbose, " ok"); + terminal.reset().unwrap(); + } + if args.flag_print { + let mut writer1 = stdout(); + let mut writer2 = stdout(); + match pretty_print_translation(&name, &data, &translation, &mut writer1, &mut writer2) { + Err(error) => return Err(String::from(error.description())), + Ok(()) => (), + } + } + if args.flag_optimize { + terminal.fg(term::color::MAGENTA).unwrap(); + vprint!(args.flag_verbose, "Optimizing... "); + terminal.reset().unwrap(); + for func in translation.functions.iter() { + let mut il = match func { + &FunctionTranslation::Import() => continue, + &FunctionTranslation::Code { ref il, .. } => il.clone(), + }; + let mut loop_analysis = LoopAnalysis::new(); + let mut cfg = ControlFlowGraph::new(); + cfg.compute(&il); + let mut domtree = DominatorTree::new(); + domtree.compute(&mut il, &cfg); + loop_analysis.compute(&mut il, &mut cfg, &mut domtree); + let mut context = Context::new(); + context.func = il; + context.cfg = cfg; + context.domtree = domtree; + context.loop_analysis = loop_analysis; + match verifier::verify_context(&context.func, &context.cfg, &context.domtree, None) { + Ok(()) => (), + Err(err) => { + return Err(pretty_verifier_error(&context.func, None, err)); + } + }; + match context.licm() { + Ok(())=> (), + Err(error) => { + match error { + CtonError::Verifier(err) => { + return Err(pretty_verifier_error(&context.func, None, err)); + } + CtonError::ImplLimitExceeded | + CtonError::CodeTooLarge => return Err(String::from(error.description())), + } + } + }; + match verifier::verify_context(&context.func, &context.cfg, &context.domtree, None) { + Ok(()) => (), + Err(err) => return Err(pretty_verifier_error(&context.func, None, err)), + } + } + terminal.fg(term::color::GREEN).unwrap(); + vprintln!(args.flag_verbose, " ok"); + terminal.reset().unwrap(); + } + if args.flag_execute { + terminal.fg(term::color::MAGENTA).unwrap(); + vprint!(args.flag_verbose, "Compiling... "); + terminal.reset().unwrap(); + match compile_module(&translation) { + Ok(exec) => { + terminal.fg(term::color::GREEN).unwrap(); + vprintln!(args.flag_verbose, "ok"); + terminal.reset().unwrap(); + terminal.fg(term::color::MAGENTA).unwrap(); + vprint!(args.flag_verbose, "Executing... "); + terminal.reset().unwrap(); + match execute(exec) { + Ok(()) => { + terminal.fg(term::color::GREEN).unwrap(); + vprintln!(args.flag_verbose, "ok"); + terminal.reset().unwrap(); + } + Err(s) => { + return Err(s); + } + } + } + Err(s) => { + return Err(s); + } + }; + if args.flag_memory { + let mut input = String::new(); + terminal.fg(term::color::YELLOW).unwrap(); + println!("Inspecting memory"); + terminal.fg(term::color::MAGENTA).unwrap(); + println!("Type 'quit' to exit."); + terminal.reset().unwrap(); + loop { + input.clear(); + terminal.fg(term::color::YELLOW).unwrap(); + print!("Memory index, offset, length (e.g. 0,0,4): "); + terminal.reset().unwrap(); + let _ = stdout().flush(); + match io::stdin().read_line(&mut input) { + Ok(_) => { + input.pop(); + if input == "quit" { + break; + } + let split: Vec<&str> = input.split(",").collect(); + if split.len() != 3 { + break; + } + let memory = standalone_runtime + .inspect_memory(str::parse(split[0]).unwrap(), + str::parse(split[1]).unwrap(), + str::parse(split[2]).unwrap()); + let mut s = memory + .iter() + .fold(String::from("#"), |mut acc, byte| { + acc.push_str(format!("{:02x}_", byte).as_str()); + acc + }); + s.pop(); + println!("{}", s); + } + Err(error) => return Err(String::from(error.description())), + } + } + } + } + Ok(()) +} + +// Prints out a Wasm module, and for each function the corresponding translation in Cretonne IL. +fn pretty_print_translation(filename: &String, + data: &Vec, + translation: &TranslationResult, + writer_wast: &mut Write, + writer_cretonne: &mut Write) + -> Result<(), io::Error> { + let mut terminal = term::stdout().unwrap(); + let mut parser = Parser::new(data.as_slice()); + let mut parser_writer = Writer::new(writer_wast); + let imports_count = translation + .functions + .iter() + .fold(0, |acc, &ref f| match f { + &FunctionTranslation::Import() => acc + 1, + &FunctionTranslation::Code { .. } => acc, + }); + match parser.read() { + s @ &ParserState::BeginWasm { .. } => parser_writer.write(&s)?, + _ => panic!("modules should begin properly"), + } + loop { + match parser.read() { + s @ &ParserState::BeginSection { code: SectionCode::Code, .. } => { + // The code section begins + parser_writer.write(&s)?; + break; + } + &ParserState::EndWasm => return Ok(()), + s @ _ => parser_writer.write(&s)?, + } + } + let mut function_index = 0; + loop { + match parser.read() { + s @ &ParserState::BeginFunctionBody { .. } => { + terminal.fg(term::color::BLUE).unwrap(); + write!(writer_cretonne, + "====== Function No. {} of module \"{}\" ======\n", + function_index, + filename)?; + terminal.fg(term::color::CYAN).unwrap(); + write!(writer_cretonne, "Wast ---------->\n")?; + terminal.reset().unwrap(); + parser_writer.write(&s)?; + } + s @ &ParserState::EndSection => { + parser_writer.write(&s)?; + break; + } + _ => panic!("wrong content in code section"), + } + { + loop { + match parser.read() { + s @ &ParserState::EndFunctionBody => { + parser_writer.write(&s)?; + break; + } + s @ _ => { + parser_writer.write(&s)?; + } + }; + } + } + let mut function_string = + format!(" {}", + match translation.functions[function_index + imports_count] { + FunctionTranslation::Code { ref il, .. } => il, + FunctionTranslation::Import() => panic!("should not happen"), + } + .display(None)); + function_string.pop(); + let function_str = str::replace(function_string.as_str(), "\n", "\n "); + terminal.fg(term::color::CYAN).unwrap(); + write!(writer_cretonne, "Cretonne IL --->\n")?; + terminal.reset().unwrap(); + write!(writer_cretonne, "{}\n", function_str)?; + function_index += 1; + } + loop { + match parser.read() { + &ParserState::EndWasm => return Ok(()), + s @ _ => parser_writer.write(&s)?, + } + } +} + +/// Pretty-print a verifier error. +pub fn pretty_verifier_error(func: &ir::Function, + isa: Option<&TargetIsa>, + err: verifier::Error) + -> String { + let msg = err.to_string(); + let str1 = match err.location { + AnyEntity::Inst(inst) => { + format!("{}\n{}: {}\n\n", + msg, + inst, + func.dfg.display_inst(inst, isa)) + } + _ => String::from(format!("{}\n", msg)), + }; + format!("{}{}", str1, func.display(isa)) +} diff --git a/lib/wasm2cretonne-util/testsuite/address.wast.0.wasm b/lib/wasm2cretonne-util/testsuite/address.wast.0.wasm new file mode 100644 index 0000000000000000000000000000000000000000..bf81db7cc8f13a06d581d82873b6f57bc6e97c6b GIT binary patch literal 205 zcmXAhIS#@w6b0Y^CIVpuh>lb#-5{TVgCLQO5XeSs)`p`)V!vjJ89l_NCIA%Bk-p#! z%}kf4Ha9lt`m(Wr5DWx@K+`2pinh%_B8fBbyy62Q?0~fcd9cTJgeK>-Pc&Sj$t4;t vQS1`so$^kNPA-NA#lK;zP|Ap~hYaH+&GJ)mE-%-rZrbkF8+(5|U+>Q!DTW~i literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/binary.wast.0.wasm b/lib/wasm2cretonne-util/testsuite/binary.wast.0.wasm new file mode 100644 index 0000000000000000000000000000000000000000..d8fc92d022fbf4d1072da17bc8e0840054b51ddc GIT binary patch literal 8 PcmZQbEY4+QU|;|M2ZjMd literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/binary.wast.1.wasm b/lib/wasm2cretonne-util/testsuite/binary.wast.1.wasm new file mode 100644 index 0000000000000000000000000000000000000000..d8fc92d022fbf4d1072da17bc8e0840054b51ddc GIT binary patch literal 8 PcmZQbEY4+QU|;|M2ZjMd literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/binary.wast.2.wasm b/lib/wasm2cretonne-util/testsuite/binary.wast.2.wasm new file mode 100644 index 0000000000000000000000000000000000000000..d8fc92d022fbf4d1072da17bc8e0840054b51ddc GIT binary patch literal 8 PcmZQbEY4+QU|;|M2ZjMd literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/binary.wast.3.wasm b/lib/wasm2cretonne-util/testsuite/binary.wast.3.wasm new file mode 100644 index 0000000000000000000000000000000000000000..d8fc92d022fbf4d1072da17bc8e0840054b51ddc GIT binary patch literal 8 PcmZQbEY4+QU|;|M2ZjMd literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/block.wast.0.wasm b/lib/wasm2cretonne-util/testsuite/block.wast.0.wasm new file mode 100644 index 0000000000000000000000000000000000000000..a5f96555a0c18309543fb6c1dcaaa1719031347d GIT binary patch literal 709 zcmb_YOHSiJ6s&GL*yK5m`2-NFnGL%LaRXW-<`{?$X&~Sj%XW~mK)waX;U=@2gG_ZC zEM~`o?v`Fvy;rYaH*CFB0934RfE%bb$i}3fSM;vZfm@c%nq~E(xL@VAf*vead9y&U zQ@FZubA;jCxe|lS*3(sCtM&A`bd@dU*x92rTl}X*V`>eZeO0_q<@R}5+RF9f?r>H) z`!t8u|h*`^mo;VO(GcX#J*n;PlxPcYVy82VCpLkwGHZaFV zZR}bLv@q1b*S literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/br.wast.0.wasm b/lib/wasm2cretonne-util/testsuite/br.wast.0.wasm new file mode 100644 index 0000000000000000000000000000000000000000..f4131e83b634efecf57d1868f781e9c45f8dcf96 GIT binary patch literal 2093 zcmZux+j1L45bc@O&6?58H-VhkYY5;t5ro7zIDtargje3FqRL)N<5*^;b?vSLaYf#D zDjz`n1AG&IL-)+=N{QL>O5LYVpXu&t3xZ_A0D$e(jscE=W%yp>JHz+wG0!qYylmmi z`{6nA0T}m6^hFPT;vZ*ad|1Um_~CJ~JjCZusmw0WD|?tw{i}9ROW$1R{`kpbV9wm% z18&VzL_KFBT59Ip{_7yT)KGT7{+0JGU^-9?@iukPM-pw?xI=9?k^$~gpTi&wUCtIw!T2;HpGIUnGotM^=N@6L zZIUT}h>$h=pVV|$w3Xtr*+d4-7i)ExIIz7TW4?@@em(*7n1*3j28pS$E;4A8j zkY5UD$F!P8u`Zzdrd0#kneWm)Bm~U!9+;t7%(5Pm(&aRW-}Ivk9S3;#eRKC?gN6Du zg|8{=!~*g7)maMP5R&R7Es`D)GK?k{0oG))z9r=xv1yN~VZ4XeI-X}fq0M>~M}Hhm z^d!PMlJS*>z2zy&>yi71u*H7Y%E5eZ_Y2y>u0HJ+w2$`n`?Yz*?yMC)*!W-EZS=FH zDgyA2;hS@NFW=v28*@I$owc$rQ(owsA37azM)fL@!H* z1k}vbk~BiLj|QqxnyN`qtN}e$bwGuP4!}dPye7vwg;*wfo#+Oj1neVI6@|q$@i&_g ztoZt{Dxu|qSZ*m(P*zk1(S7o<@Up*%_^eFDBZpeUs=)`JZCKX_RY4$k6;`0|2#l6M zWrCVj66@m1Yi|ncGu1$3(dVj(L&do1W0m@#j7~Lg4b++yS%jEcC!G%=uDTKo)M9Lg zr*|Z5Qz>-z?8VLde}9s&i#tQNc73=h;Smk6ONFB2ZvM{Tz%xna9=O_)@N@z2@!aY& zoGQvX#vZ$}SG*luC)y31DX99nJF%MfwrT< zt@M@JmGGOR-=I2S#GDBeTOQV&sFc+pdB3~k*C+5Pfe cd_9j_HQF>vyPLy>BJLSZ%|<^;!hlKo54g<9Gynhq literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/br_if.wast.0.wasm b/lib/wasm2cretonne-util/testsuite/br_if.wast.0.wasm new file mode 100644 index 0000000000000000000000000000000000000000..3c91d8350b51941f3a7fc209e1ec763b9c80a695 GIT binary patch literal 746 zcmZvXVQzvz5QS$JtdG89Dj-VEUlA$Q5{~BV}7n1z^MhNJOkm| zu}DdFmUiy;laI7`*WgALlgq%-!b0{MddG=HRlS+Qu^eXZn{a)nc6Ik2jrlQYo^=VH z8FW!=kWs1YMrY>o{WYe+0MDk)w`=Do%IVi;4|dJMu>{d16M34(dkPJbESlV^o|X<+YS0S3MqnHD8VJqh#`>}6w*yZtXw)K93QJtzRJFnDRk=NElnZ+4V$feor?0Ge4VUt27khTy9fCPQ%IH) literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/br_table.wast.0.wasm b/lib/wasm2cretonne-util/testsuite/br_table.wast.0.wasm new file mode 100644 index 0000000000000000000000000000000000000000..09b895d2b020efc7fb0771c73b608f00d8577845 GIT binary patch literal 27334 zcmeI5+j1L45QckprAXFT2RlB165@3Zhy9UrLr26 z5PsdTGf8#nRH@tNdJUiS$)ptWwOO3*}^CXP-BPcuJ)=eiIvjWCBq2h#z zN3|Rc#@SPt)BNk)YIA9SxEn{=Xb8GF8N1o}>R><4`r|l)dZQS+xkfn-lidiKjWF$O z#iQ+SIy?O&&7d_u5eEGpEYv4v9OCri)ZebB6S)Wy;309KAx5TZyY- zm2)SX{hiMCXxM{yI5*oi_q)g0og7%OZtVrDX5m(hJ231;-@%C^nvFiWI_qZ>Snv0m zIFm%#elm2WoT{Nx)UoD_>~S=Nz!_1TMzBtSX%t7>nOpAZ)>KI&Ud9<(hI3-!EUj}p zjAIw`K2czs5S=GPY%!t>E6&`+TKmcLP8XNnn4s`W%Wue>=klBS&i-&4t}LQ|8fBZf z=V9!Y-=THIqp;Trd%Yw|Q}}?^Maq{G=|f&>HcFz2bd{INl4X94_8}!<8h4$cSy8an#3@ zxlnA_9a=E%!;>hPM&6~9wVRB--5f-N5!R9RpGEM=;t#NyoEo4C!K z)z4NZZm*r!`^(cAduDCo?uobR?nImR>$Chf;=d|v%vBT^(CS?6hhNkK4|E;8u7L(V z9v`>$jP>k@_2P*260HV!xlt~X&BG1Pn$NUe0Pg@Fo?Vyvh1Sd9J%30~Q-GFJUuxY1 zuNy!Ez$`blS+QByt+J-|3Qn^FK5p4#iM>$H@$Te@4^^|))NK=JeT}^-f@4bfIEIq> z4KU_+y8Jz$OWxbqmcF%m~yjK}{5HvyhYRIUj1M;OEAtJ`743 zrS&4(=uk3wgSyffkAi#-DjUU`)|z@b%+13*-jhqf2`r(G=5d;;Vm@rqpz6>z6|I*@ zJ7(tSF66}`m4*qyR?qz&a#M4GoNgu*7fYTPO(M3SINYePYtv#Qy+b%2={ zSXrkMsi1=gFTelwK5Lh-g9kOyINUhJ_EkW;P1RW2b=)}Fz2kEMM0*!lL17BDbV zxrr!Fq&t5_Clml%dZ6IW8V1$&Tp_iM4m%w1#^&YzG4=`xjJd?FU%SAIY`t==MlP_`#pRu$JbBwF{PFNxYU2TIVbcu{J2mZT zdh65V!wzldLGzxXBi=SGaykE27ffN#c~JPBn)=}>tJ?eUssFDuND14LxZAxw4Y_cd Y)A*naSkqH^29qg6j_i0EpB4Ifyw`NEJ}c&c&R72#JV*keCsZ0Yf=w zDrbyk81XRjLXH4!&juki-AI|~Ocr_mEn~^ZX zs1=Vy^H$_~{jooZHdF$TvHTbC_DTYfQOHLbey?*i>_#E0NkYzAf^f`wl902Zd2Rt8@o?_KwXu&rHnyHGO6)1iCg-a^?LOea(KvhoXdvQN@Bpz$ct0Ov!Z z2~Dv56GUjye*k!WsG|-x{L=)pWK--ZW=e9?Fa-@;=@jccgEBA!&6m&nno3~~TGi~^ z-KhFqQzjkP^gM9LO_S5G+0Nifdzh@+DwVjD-o(K#8Tv(#l9m0Ra`6;XGq6!)V#63SW+d#LX6%aX4}Z$Rpz$KZ3lk< DRUwL> literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/call_indirect.wast.0.wasm b/lib/wasm2cretonne-util/testsuite/call_indirect.wast.0.wasm new file mode 100644 index 0000000000000000000000000000000000000000..974170480d6e1e5141097c849762179588f4f02e GIT binary patch literal 873 zcmZvYy>in)5Xb+g59{L;*=OT8e1s@Y2n}w4q07W4JH1QjENpAyA#psG3}nWZ--3pc zhKhnGV1|Y_-~r$jXsFnel^G1t%--((?!UX*MU-4H0PIDz5A?xSWEt6#Y|&>c0xToK zmW0@Xn6^|(K=J`sHwlrZt;SqBqeM4*ZLGI*-m<*Wl3EWsu+v6gzco?(7Bo&4a@S z9Y$A3DDnhOT1E1A%8uL(W( zx-h_9>I!L!61W2yNJE%8{8B&p2(80z$@q;yWc-dkAI&?OW5E(I&qAU@@(ON zdsHE$Oh>rj^+|9%)RuCK9@Y{SEjV=!aB8gNBg&QRl`N~7_;x{mpum2PX)zUnd?D4s H3+4X+%%7up literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/comments.wast.0.wasm b/lib/wasm2cretonne-util/testsuite/comments.wast.0.wasm new file mode 100644 index 0000000000000000000000000000000000000000..d8fc92d022fbf4d1072da17bc8e0840054b51ddc GIT binary patch literal 8 PcmZQbEY4+QU|;|M2ZjMd literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/comments.wast.1.wasm b/lib/wasm2cretonne-util/testsuite/comments.wast.1.wasm new file mode 100644 index 0000000000000000000000000000000000000000..d8fc92d022fbf4d1072da17bc8e0840054b51ddc GIT binary patch literal 8 PcmZQbEY4+QU|;|M2ZjMd literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/comments.wast.2.wasm b/lib/wasm2cretonne-util/testsuite/comments.wast.2.wasm new file mode 100644 index 0000000000000000000000000000000000000000..d8fc92d022fbf4d1072da17bc8e0840054b51ddc GIT binary patch literal 8 PcmZQbEY4+QU|;|M2ZjMd literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/comments.wast.3.wasm b/lib/wasm2cretonne-util/testsuite/comments.wast.3.wasm new file mode 100644 index 0000000000000000000000000000000000000000..d8fc92d022fbf4d1072da17bc8e0840054b51ddc GIT binary patch literal 8 PcmZQbEY4+QU|;|M2ZjMd literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/conversions.wast.0.wasm b/lib/wasm2cretonne-util/testsuite/conversions.wast.0.wasm new file mode 100644 index 0000000000000000000000000000000000000000..ddebe20d3da3c434a4ef856e29e9b07b63265bd8 GIT binary patch literal 737 zcmZ9JNm9Z<6o$JK!W1N6oN(m{Sg7UBvj7Ec6$=8@1a*;+V|WB7oagy0-o*F*xaee& zuR34KUBr@h*LLwtx5n@IpV|%kjJuJ(% z3kAn1mdX`=s&27jIi+8_)fn#Ww$*W{fyFU&Nl@9;E!p%E6 zuhyhfbGfCwqg*{xn~uQCJIXaOwP~)Ica&T9_}qyekH(?Gbo@Hsc%V{2krkhXR>L4v zdZJZ`xv%y^LhNHc2|Sh&n9@Dw})&%q1u61)a)z+3PR dyayk_7w`>y0H45D@E!aBpTTeN2mA!T+&^ASy5Il+ literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/custom_section.wast.0.wasm b/lib/wasm2cretonne-util/testsuite/custom_section.wast.0.wasm new file mode 100644 index 0000000000000000000000000000000000000000..d8fc92d022fbf4d1072da17bc8e0840054b51ddc GIT binary patch literal 8 PcmZQbEY4+QU|;|M2ZjMd literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/custom_section.wast.1.wasm b/lib/wasm2cretonne-util/testsuite/custom_section.wast.1.wasm new file mode 100644 index 0000000000000000000000000000000000000000..d8fc92d022fbf4d1072da17bc8e0840054b51ddc GIT binary patch literal 8 PcmZQbEY4+QU|;|M2ZjMd literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/custom_section.wast.2.wasm b/lib/wasm2cretonne-util/testsuite/custom_section.wast.2.wasm new file mode 100644 index 0000000000000000000000000000000000000000..8b19588df228b76c6747d04aee091cbe268592d0 GIT binary patch literal 44 zcmZQbEY4+QU|?WmXG~zKuV<`hW@2Pu=VD|_Oi2kT&u3uZ;$&oJP+(AC%;E+BoDK$l literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/endianness.wast.0.wasm b/lib/wasm2cretonne-util/testsuite/endianness.wast.0.wasm new file mode 100644 index 0000000000000000000000000000000000000000..d26c99d06ca8963854764317f8cb4a9080570374 GIT binary patch literal 682 zcmYj~+fKqj5Qb-VTiCLoiy(N}3okrG4F~Hfnv@rzBuawOkWkWecK>BOcx-w75DIymK~bbGi1NtmZi7x9XHd$JwuK<`ID@iCXQ3j7 z<{s>bq1gz#Qr`)uN~=t(YOX*g*|kDaEmC{#2Z5|n>dY*l?u+R}R!LJlo>tsfr0A5g zHt{I+p8NhLE8uID>N!G=F1Ca|95IkPadNGrZ8CG%$svWixiH}+p}E3*IOgf-ry}zt u%YG?xPsvTPcSv^>H{>x*mN|N#cpHNciMcV^E3UJ)F|QNz+u%)N{>XpzRCK%m literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/exports.wast.0.wasm b/lib/wasm2cretonne-util/testsuite/exports.wast.0.wasm new file mode 100644 index 0000000000000000000000000000000000000000..fff82363ca62dc4496fb9301cf6962c5c76f789f GIT binary patch literal 31 mcmZQbEY4+QU|?WmVN76PU}j=uU}t4yOk`l-Vqs)r;06FOYXUj| literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/exports.wast.1.wasm b/lib/wasm2cretonne-util/testsuite/exports.wast.1.wasm new file mode 100644 index 0000000000000000000000000000000000000000..505f4fe7a4c9c1e252f2b27dbd01f94db0dffd1c GIT binary patch literal 35 pcmZQbEY4+QU|?WmVN76PU}j=uVCQ6FOauxfF)(nkFfuW40{}g)0-^u_ literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/exports.wast.10.wasm b/lib/wasm2cretonne-util/testsuite/exports.wast.10.wasm new file mode 100644 index 0000000000000000000000000000000000000000..d8fc92d022fbf4d1072da17bc8e0840054b51ddc GIT binary patch literal 8 PcmZQbEY4+QU|;|M2ZjMd literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/exports.wast.11.wasm b/lib/wasm2cretonne-util/testsuite/exports.wast.11.wasm new file mode 100644 index 0000000000000000000000000000000000000000..d8fc92d022fbf4d1072da17bc8e0840054b51ddc GIT binary patch literal 8 PcmZQbEY4+QU|;|M2ZjMd literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/exports.wast.18.wasm b/lib/wasm2cretonne-util/testsuite/exports.wast.18.wasm new file mode 100644 index 0000000000000000000000000000000000000000..a2f90fe1130c8556d4a774932ad9fc3d753a85d6 GIT binary patch literal 23 ecmZQbEY4+QU|?WlW2|RzWZ-6JWn@fbW&i*sg#wKL literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/exports.wast.19.wasm b/lib/wasm2cretonne-util/testsuite/exports.wast.19.wasm new file mode 100644 index 0000000000000000000000000000000000000000..f1bae6aa2461d7e46b66fb2f05a8136f367c1af1 GIT binary patch literal 27 icmZQbEY4+QU|?WlW2|RzWZ-7!WMWKYW?)QWW&i*&8UpwL literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/exports.wast.2.wasm b/lib/wasm2cretonne-util/testsuite/exports.wast.2.wasm new file mode 100644 index 0000000000000000000000000000000000000000..0ec4916edc579c4262a52224fe1d7778b0289417 GIT binary patch literal 39 rcmZQbEY4+QU|?WmVN76PU}k1wU|{EDVoU^zBrz~@u`@9-a03wlN2~(2 literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/exports.wast.20.wasm b/lib/wasm2cretonne-util/testsuite/exports.wast.20.wasm new file mode 100644 index 0000000000000000000000000000000000000000..3c2410be16b0f8e9b19e9f2ff2b3f14be1e95c81 GIT binary patch literal 32 jcmZQbEY4+QU|?Y5W~yg!WZ(u9?3_%DiOdX)Nz9A@NG$`( literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/exports.wast.21.wasm b/lib/wasm2cretonne-util/testsuite/exports.wast.21.wasm new file mode 100644 index 0000000000000000000000000000000000000000..a2f90fe1130c8556d4a774932ad9fc3d753a85d6 GIT binary patch literal 23 ecmZQbEY4+QU|?WlW2|RzWZ-6JWn@fbW&i*sg#wKL literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/exports.wast.22.wasm b/lib/wasm2cretonne-util/testsuite/exports.wast.22.wasm new file mode 100644 index 0000000000000000000000000000000000000000..a2f90fe1130c8556d4a774932ad9fc3d753a85d6 GIT binary patch literal 23 ecmZQbEY4+QU|?WlW2|RzWZ-6JWn@fbW&i*sg#wKL literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/exports.wast.23.wasm b/lib/wasm2cretonne-util/testsuite/exports.wast.23.wasm new file mode 100644 index 0000000000000000000000000000000000000000..a2f90fe1130c8556d4a774932ad9fc3d753a85d6 GIT binary patch literal 23 ecmZQbEY4+QU|?WlW2|RzWZ-6JWn@fbW&i*sg#wKL literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/exports.wast.24.wasm b/lib/wasm2cretonne-util/testsuite/exports.wast.24.wasm new file mode 100644 index 0000000000000000000000000000000000000000..a2f90fe1130c8556d4a774932ad9fc3d753a85d6 GIT binary patch literal 23 ecmZQbEY4+QU|?WlW2|RzWZ-6JWn@fbW&i*sg#wKL literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/exports.wast.25.wasm b/lib/wasm2cretonne-util/testsuite/exports.wast.25.wasm new file mode 100644 index 0000000000000000000000000000000000000000..a2f90fe1130c8556d4a774932ad9fc3d753a85d6 GIT binary patch literal 23 ecmZQbEY4+QU|?WlW2|RzWZ-6JWn@fbW&i*sg#wKL literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/exports.wast.26.wasm b/lib/wasm2cretonne-util/testsuite/exports.wast.26.wasm new file mode 100644 index 0000000000000000000000000000000000000000..a2f90fe1130c8556d4a774932ad9fc3d753a85d6 GIT binary patch literal 23 ecmZQbEY4+QU|?WlW2|RzWZ-6JWn@fbW&i*sg#wKL literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/exports.wast.27.wasm b/lib/wasm2cretonne-util/testsuite/exports.wast.27.wasm new file mode 100644 index 0000000000000000000000000000000000000000..a9893a2a7e14e8b2070bf911beb21f4019e2ade4 GIT binary patch literal 23 ecmZQbEY4+QU|?WlW2|Rz)Z%7mWn@fcW&i*u3j(_U literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/exports.wast.28.wasm b/lib/wasm2cretonne-util/testsuite/exports.wast.28.wasm new file mode 100644 index 0000000000000000000000000000000000000000..d8fc92d022fbf4d1072da17bc8e0840054b51ddc GIT binary patch literal 8 PcmZQbEY4+QU|;|M2ZjMd literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/exports.wast.29.wasm b/lib/wasm2cretonne-util/testsuite/exports.wast.29.wasm new file mode 100644 index 0000000000000000000000000000000000000000..d8fc92d022fbf4d1072da17bc8e0840054b51ddc GIT binary patch literal 8 PcmZQbEY4+QU|;|M2ZjMd literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/exports.wast.3.wasm b/lib/wasm2cretonne-util/testsuite/exports.wast.3.wasm new file mode 100644 index 0000000000000000000000000000000000000000..fff82363ca62dc4496fb9301cf6962c5c76f789f GIT binary patch literal 31 mcmZQbEY4+QU|?WmVN76PU}j=uU}t4yOk`l-Vqs)r;06FOYXUj| literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/exports.wast.36.wasm b/lib/wasm2cretonne-util/testsuite/exports.wast.36.wasm new file mode 100644 index 0000000000000000000000000000000000000000..539a89bf190ae897dfed7d0ee431aada5c83d162 GIT binary patch literal 21 ccmZQbEY4+QU|?WjVJu)^U}t4yOk`vL03JC4EC2ui literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/exports.wast.37.wasm b/lib/wasm2cretonne-util/testsuite/exports.wast.37.wasm new file mode 100644 index 0000000000000000000000000000000000000000..1f2cfccf74d67b516d42994740aeaf9a74955374 GIT binary patch literal 25 gcmZQbEY4+QU|?WjVJu)^VCQ6FOk`wWOk!jJ04PQRl>h($ literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/exports.wast.38.wasm b/lib/wasm2cretonne-util/testsuite/exports.wast.38.wasm new file mode 100644 index 0000000000000000000000000000000000000000..539a89bf190ae897dfed7d0ee431aada5c83d162 GIT binary patch literal 21 ccmZQbEY4+QU|?WjVJu)^U}t4yOk`vL03JC4EC2ui literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/exports.wast.39.wasm b/lib/wasm2cretonne-util/testsuite/exports.wast.39.wasm new file mode 100644 index 0000000000000000000000000000000000000000..48fb7293d12811b4118adf016e2d1eb6ac262a4b GIT binary patch literal 22 dcmZQbEY4+QU|?WjWh`K1U}R@yWK3ja001Bq0xtjn literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/exports.wast.4.wasm b/lib/wasm2cretonne-util/testsuite/exports.wast.4.wasm new file mode 100644 index 0000000000000000000000000000000000000000..fff82363ca62dc4496fb9301cf6962c5c76f789f GIT binary patch literal 31 mcmZQbEY4+QU|?WmVN76PU}j=uU}t4yOk`l-Vqs)r;06FOYXUj| literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/exports.wast.40.wasm b/lib/wasm2cretonne-util/testsuite/exports.wast.40.wasm new file mode 100644 index 0000000000000000000000000000000000000000..539a89bf190ae897dfed7d0ee431aada5c83d162 GIT binary patch literal 21 ccmZQbEY4+QU|?WjVJu)^U}t4yOk`vL03JC4EC2ui literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/exports.wast.41.wasm b/lib/wasm2cretonne-util/testsuite/exports.wast.41.wasm new file mode 100644 index 0000000000000000000000000000000000000000..48fb7293d12811b4118adf016e2d1eb6ac262a4b GIT binary patch literal 22 dcmZQbEY4+QU|?WjWh`K1U}R@yWK3ja001Bq0xtjn literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/exports.wast.42.wasm b/lib/wasm2cretonne-util/testsuite/exports.wast.42.wasm new file mode 100644 index 0000000000000000000000000000000000000000..539a89bf190ae897dfed7d0ee431aada5c83d162 GIT binary patch literal 21 ccmZQbEY4+QU|?WjVJu)^U}t4yOk`vL03JC4EC2ui literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/exports.wast.43.wasm b/lib/wasm2cretonne-util/testsuite/exports.wast.43.wasm new file mode 100644 index 0000000000000000000000000000000000000000..48fb7293d12811b4118adf016e2d1eb6ac262a4b GIT binary patch literal 22 dcmZQbEY4+QU|?WjWh`K1U}R@yWK3ja001Bq0xtjn literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/exports.wast.44.wasm b/lib/wasm2cretonne-util/testsuite/exports.wast.44.wasm new file mode 100644 index 0000000000000000000000000000000000000000..539a89bf190ae897dfed7d0ee431aada5c83d162 GIT binary patch literal 21 ccmZQbEY4+QU|?WjVJu)^U}t4yOk`vL03JC4EC2ui literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/exports.wast.45.wasm b/lib/wasm2cretonne-util/testsuite/exports.wast.45.wasm new file mode 100644 index 0000000000000000000000000000000000000000..48fb7293d12811b4118adf016e2d1eb6ac262a4b GIT binary patch literal 22 dcmZQbEY4+QU|?WjWh`K1U}R@yWK3ja001Bq0xtjn literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/exports.wast.46.wasm b/lib/wasm2cretonne-util/testsuite/exports.wast.46.wasm new file mode 100644 index 0000000000000000000000000000000000000000..539a89bf190ae897dfed7d0ee431aada5c83d162 GIT binary patch literal 21 ccmZQbEY4+QU|?WjVJu)^U}t4yOk`vL03JC4EC2ui literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/exports.wast.47.wasm b/lib/wasm2cretonne-util/testsuite/exports.wast.47.wasm new file mode 100644 index 0000000000000000000000000000000000000000..48fb7293d12811b4118adf016e2d1eb6ac262a4b GIT binary patch literal 22 dcmZQbEY4+QU|?WjWh`K1U}R@yWK3ja001Bq0xtjn literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/exports.wast.48.wasm b/lib/wasm2cretonne-util/testsuite/exports.wast.48.wasm new file mode 100644 index 0000000000000000000000000000000000000000..539a89bf190ae897dfed7d0ee431aada5c83d162 GIT binary patch literal 21 ccmZQbEY4+QU|?WjVJu)^U}t4yOk`vL03JC4EC2ui literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/exports.wast.49.wasm b/lib/wasm2cretonne-util/testsuite/exports.wast.49.wasm new file mode 100644 index 0000000000000000000000000000000000000000..48fb7293d12811b4118adf016e2d1eb6ac262a4b GIT binary patch literal 22 dcmZQbEY4+QU|?WjWh`K1U}R@yWK3ja001Bq0xtjn literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/exports.wast.5.wasm b/lib/wasm2cretonne-util/testsuite/exports.wast.5.wasm new file mode 100644 index 0000000000000000000000000000000000000000..fff82363ca62dc4496fb9301cf6962c5c76f789f GIT binary patch literal 31 mcmZQbEY4+QU|?WmVN76PU}j=uU}t4yOk`l-Vqs)r;06FOYXUj| literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/exports.wast.55.wasm b/lib/wasm2cretonne-util/testsuite/exports.wast.55.wasm new file mode 100644 index 0000000000000000000000000000000000000000..2981c2461cd601057c5978198cb8df7c23f69791 GIT binary patch literal 20 ZcmZQbEY4+QU|?Wn29oTojEsp)3;-CA0lfeK literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/exports.wast.56.wasm b/lib/wasm2cretonne-util/testsuite/exports.wast.56.wasm new file mode 100644 index 0000000000000000000000000000000000000000..6696dc1f5fc9b94f45aefa88f80c275fa40f0a4a GIT binary patch literal 24 dcmZQbEY4+QU|?Wn29oTYOpJ+442(%k3;-bG0w(|f literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/exports.wast.57.wasm b/lib/wasm2cretonne-util/testsuite/exports.wast.57.wasm new file mode 100644 index 0000000000000000000000000000000000000000..2981c2461cd601057c5978198cb8df7c23f69791 GIT binary patch literal 20 ZcmZQbEY4+QU|?Wn29oTojEsp)3;-CA0lfeK literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/exports.wast.58.wasm b/lib/wasm2cretonne-util/testsuite/exports.wast.58.wasm new file mode 100644 index 0000000000000000000000000000000000000000..f6bda9d18c5c0b1982ac2aefce047cd2aff19860 GIT binary patch literal 21 ccmZQbEY4+QU|?WnVPs@rWM^e$Ok`pJ02%rLzyJUM literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/exports.wast.59.wasm b/lib/wasm2cretonne-util/testsuite/exports.wast.59.wasm new file mode 100644 index 0000000000000000000000000000000000000000..2981c2461cd601057c5978198cb8df7c23f69791 GIT binary patch literal 20 ZcmZQbEY4+QU|?Wn29oTojEsp)3;-CA0lfeK literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/exports.wast.6.wasm b/lib/wasm2cretonne-util/testsuite/exports.wast.6.wasm new file mode 100644 index 0000000000000000000000000000000000000000..fff82363ca62dc4496fb9301cf6962c5c76f789f GIT binary patch literal 31 mcmZQbEY4+QU|?WmVN76PU}j=uU}t4yOk`l-Vqs)r;06FOYXUj| literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/exports.wast.60.wasm b/lib/wasm2cretonne-util/testsuite/exports.wast.60.wasm new file mode 100644 index 0000000000000000000000000000000000000000..f6bda9d18c5c0b1982ac2aefce047cd2aff19860 GIT binary patch literal 21 ccmZQbEY4+QU|?WnVPs@rWM^e$Ok`pJ02%rLzyJUM literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/exports.wast.61.wasm b/lib/wasm2cretonne-util/testsuite/exports.wast.61.wasm new file mode 100644 index 0000000000000000000000000000000000000000..2981c2461cd601057c5978198cb8df7c23f69791 GIT binary patch literal 20 ZcmZQbEY4+QU|?Wn29oTojEsp)3;-CA0lfeK literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/exports.wast.62.wasm b/lib/wasm2cretonne-util/testsuite/exports.wast.62.wasm new file mode 100644 index 0000000000000000000000000000000000000000..f6bda9d18c5c0b1982ac2aefce047cd2aff19860 GIT binary patch literal 21 ccmZQbEY4+QU|?WnVPs@rWM^e$Ok`pJ02%rLzyJUM literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/exports.wast.63.wasm b/lib/wasm2cretonne-util/testsuite/exports.wast.63.wasm new file mode 100644 index 0000000000000000000000000000000000000000..2981c2461cd601057c5978198cb8df7c23f69791 GIT binary patch literal 20 ZcmZQbEY4+QU|?Wn29oTojEsp)3;-CA0lfeK literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/exports.wast.64.wasm b/lib/wasm2cretonne-util/testsuite/exports.wast.64.wasm new file mode 100644 index 0000000000000000000000000000000000000000..f6bda9d18c5c0b1982ac2aefce047cd2aff19860 GIT binary patch literal 21 ccmZQbEY4+QU|?WnVPs@rWM^e$Ok`pJ02%rLzyJUM literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/exports.wast.65.wasm b/lib/wasm2cretonne-util/testsuite/exports.wast.65.wasm new file mode 100644 index 0000000000000000000000000000000000000000..2981c2461cd601057c5978198cb8df7c23f69791 GIT binary patch literal 20 ZcmZQbEY4+QU|?Wn29oTojEsp)3;-CA0lfeK literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/exports.wast.66.wasm b/lib/wasm2cretonne-util/testsuite/exports.wast.66.wasm new file mode 100644 index 0000000000000000000000000000000000000000..f6bda9d18c5c0b1982ac2aefce047cd2aff19860 GIT binary patch literal 21 ccmZQbEY4+QU|?WnVPs@rWM^e$Ok`pJ02%rLzyJUM literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/exports.wast.67.wasm b/lib/wasm2cretonne-util/testsuite/exports.wast.67.wasm new file mode 100644 index 0000000000000000000000000000000000000000..2981c2461cd601057c5978198cb8df7c23f69791 GIT binary patch literal 20 ZcmZQbEY4+QU|?Wn29oTojEsp)3;-CA0lfeK literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/exports.wast.68.wasm b/lib/wasm2cretonne-util/testsuite/exports.wast.68.wasm new file mode 100644 index 0000000000000000000000000000000000000000..f6bda9d18c5c0b1982ac2aefce047cd2aff19860 GIT binary patch literal 21 ccmZQbEY4+QU|?WnVPs@rWM^e$Ok`pJ02%rLzyJUM literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/exports.wast.7.wasm b/lib/wasm2cretonne-util/testsuite/exports.wast.7.wasm new file mode 100644 index 0000000000000000000000000000000000000000..fff82363ca62dc4496fb9301cf6962c5c76f789f GIT binary patch literal 31 mcmZQbEY4+QU|?WmVN76PU}j=uU}t4yOk`l-Vqs)r;06FOYXUj| literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/exports.wast.8.wasm b/lib/wasm2cretonne-util/testsuite/exports.wast.8.wasm new file mode 100644 index 0000000000000000000000000000000000000000..fff82363ca62dc4496fb9301cf6962c5c76f789f GIT binary patch literal 31 mcmZQbEY4+QU|?WmVN76PU}j=uU}t4yOk`l-Vqs)r;06FOYXUj| literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/exports.wast.9.wasm b/lib/wasm2cretonne-util/testsuite/exports.wast.9.wasm new file mode 100644 index 0000000000000000000000000000000000000000..615bb04c6f314a50e4422b82631aed6d05fb6479 GIT binary patch literal 39 ucmZQbEY4+QU|?WmV@zPIXRK#tVq{=vWn@fcVBq3naAeHl=LP^@P6Q_a literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/f32.wast.0.wasm b/lib/wasm2cretonne-util/testsuite/f32.wast.0.wasm new file mode 100644 index 0000000000000000000000000000000000000000..9bde5ff26087b744a6b50fcfeb472786caa95e30 GIT binary patch literal 196 zcmXYmTMmLS6h!B8sa47%*pP7xRKSFULTst=hb8!aZP%vhe4LY+fp&%fP?^=)vd~gf z0GBFk2nU78tzzA_06V`2vGD^kZu=8BcSk!TXVZ@mZ1fqcyy^M@QXGb9vRI4R`mw=A nj-9rhn^6=yB~hWGXYwogo%~TE{EyVW$-lT>BCnCR$h-Ojj4UB3 literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/f32_bitwise.wast.0.wasm b/lib/wasm2cretonne-util/testsuite/f32_bitwise.wast.0.wasm new file mode 100644 index 0000000000000000000000000000000000000000..76817cfe134b8a57861c606f077212d1ac52e42c GIT binary patch literal 77 zcmZQbEY4+QU|?Y6VM<`EWvoqLss)nFEX+V5b_r(Y#H3;d2IjofbOuI_`3s a1|}|1W>y9ThHh>U*~85aBo!EEa037mo((1d literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/f32_cmp.wast.0.wasm b/lib/wasm2cretonne-util/testsuite/f32_cmp.wast.0.wasm new file mode 100644 index 0000000000000000000000000000000000000000..54042ae83968bec6813c29f2ca3c13325db9bde4 GIT binary patch literal 110 zcmXZPO$vY@5QgDz#&RGJkyq$E{n=u0V?pFrx_Uysn}-+2a}od&3S0`kMr_@hjF$BV h_)-w34CbUT95XtOihh`^z{At*ewXIj+?!i7xDOT54CDX+ literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/f64.wast.0.wasm b/lib/wasm2cretonne-util/testsuite/f64.wast.0.wasm new file mode 100644 index 0000000000000000000000000000000000000000..69c3e69ca4513c6e95ad5ec8dbe488a082514ca8 GIT binary patch literal 196 zcmXYmTMmLS6h!B8sa47%*pP7xRKSFULTst=gPr((?bD{|e4LY+fp&%fP?^=)vd~gf z0GBFk2nU78tzzA_06V`2vGD^kZu=8BcSk!TXVZ@mZ1fqcyy^M@QXGb9vRI4R`mw=A nj-9rhn^6=yB~hWGXYwogo%~TE{EyVW$-lT>BCnCR$h-OjoyQ@* literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/f64_bitwise.wast.0.wasm b/lib/wasm2cretonne-util/testsuite/f64_bitwise.wast.0.wasm new file mode 100644 index 0000000000000000000000000000000000000000..8c71ce01a4ac3579aa39b9ff8890516f14d1a8b6 GIT binary patch literal 77 zcmZQbEY4+QU|?Y6VM<`EVXR4DssWPBEX+V5b_r(Y#H3;d2IjofbOuI_`3s a1|}|1W>y9ThMC+Tauzo`kW^q?#ti@x`wdF~ literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/f64_cmp.wast.0.wasm b/lib/wasm2cretonne-util/testsuite/f64_cmp.wast.0.wasm new file mode 100644 index 0000000000000000000000000000000000000000..db5c2f565fb6b779ff6788368df5e1511f271365 GIT binary patch literal 110 zcmXZPK?;B{361)_4aiq2Kh(|Q+BQHr(Bf2g?H(M({djM$kjWQ^ThhDEmpjt&n`#CFhjr>5 zm5I#f6kh9JI)lEXcmqpED^ewuVRTo8C<$!DTL}`MmRc9k+Q>haIT;FBhD9=0#KEn`0Q2fSu2d;kCd literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/float_exprs.wast.0.wasm b/lib/wasm2cretonne-util/testsuite/float_exprs.wast.0.wasm new file mode 100644 index 0000000000000000000000000000000000000000..93fc9ddbc27a18126091b9d552a760220b50dca9 GIT binary patch literal 60 zcmZQbEY4+QU|?Y6U`$}Hsi|SCVP;}vU>9Q)N;5Oj%gc{X&d)0;N=z=v%+F(B;NoHA PVo+dEU|giYw167`aMBEh literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/float_exprs.wast.1.wasm b/lib/wasm2cretonne-util/testsuite/float_exprs.wast.1.wasm new file mode 100644 index 0000000000000000000000000000000000000000..638a2124f4b5c7ebfaed6f86914390b9710fdf14 GIT binary patch literal 84 zcmZQbEY4+QU|?Y6XG&nMt*vFOO<=C6sbQ>PW@chwWS3^*N;5Xn%gc{X%S~ip;7T(y dfpHkQ#F@Al6c`j3rzkK@;)XC6DKIVI1_0YY5S0J` literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/float_exprs.wast.10.wasm b/lib/wasm2cretonne-util/testsuite/float_exprs.wast.10.wasm new file mode 100644 index 0000000000000000000000000000000000000000..63bf9ab6eaa04e48967b4283962655316ca69c0c GIT binary patch literal 104 zcmZQbEY4+QU|?Y6W=deJWvoqLtYNHSW@chwWY=dBNi#Om%gc{X%g;%P&r3}=h%YWp lVqg$SGc&;yX5^A);$mzoY!n~> literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/float_exprs.wast.14.wasm b/lib/wasm2cretonne-util/testsuite/float_exprs.wast.14.wasm new file mode 100644 index 0000000000000000000000000000000000000000..6ec49ca9fa77ad46a76298f37a81d305eadd2786 GIT binary patch literal 94 zcmZQbEY4+QU|?Y6W=deJWvoqLtYNHSW@chwWY=dBNi#Om%gc{X%g;%PFD^}rFHX%# bV_*PW@chwWLIS3O*1yq%gc{XOH3}wFJfTe iO*1n=;xlr|GVwAfFeorhQD6iTlei(gMIhdy1>6Ap*%ZA1 literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/float_exprs.wast.18.wasm b/lib/wasm2cretonne-util/testsuite/float_exprs.wast.18.wasm new file mode 100644 index 0000000000000000000000000000000000000000..ed67b7aff3095184fcc67d84fd8acc1bbfc8feba GIT binary patch literal 98 zcmZQbEY4+QU|?Y6XG&nMt*vFOO<=C6sbQ>PW@chwWY=U8Ofxpp%gc{X$t*4@%1kOP kNo8OVOfxe<6Jz8OXX0W|U{GM3q`)+V8^TPW@chwWH)9KOEWgo%gc{1N=+}yFD-~q n$t;V{EzMzI5KA*N!6w1TCCa0Z&jFo~NF$aDcQL0|zl0K{4q#sB~S literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/float_exprs.wast.20.wasm b/lib/wasm2cretonne-util/testsuite/float_exprs.wast.20.wasm new file mode 100644 index 0000000000000000000000000000000000000000..054222cdcfcdde1978025d78129a1bec29bbc3ec GIT binary patch literal 108 zcmZQbEY4+QU|?Y6XG&nMt*vFOO<=C6sbQ>PW@chwWH)9KOEWgo%gc{1N=+}yFD;1A pEzOBf$t+`F5KA*N!6w1TCCy}1eO{gV60(gW@2DuH)aw`Gd9x8%a1QgO)M_XPtHs% uNsUiTNnv0ROEWXUCc(%h%f!o|z@Wf5Nr7pS0`nwp2ycM`(*gzN1>6A6L>&+S literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/float_exprs.wast.22.wasm b/lib/wasm2cretonne-util/testsuite/float_exprs.wast.22.wasm new file mode 100644 index 0000000000000000000000000000000000000000..4d5a0ac68ebaebfbed7b6b58cc87090a57c5c672 GIT binary patch literal 116 zcmZQbEY4+QU|?VrWJ+ME1p>y}1eO{gV60(gW@2DuH)aw`Gd9x8%a1QgO)M_XPtHs% uNsZ4f&0$~=OEWXUCc(%h%f!o|z@Wf5MS*FG0`nAZ2yc-B(;@}tMce?~mmOvR literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/float_exprs.wast.23.wasm b/lib/wasm2cretonne-util/testsuite/float_exprs.wast.23.wasm new file mode 100644 index 0000000000000000000000000000000000000000..fe96aa795bf511a85e66ea51fb07c66d66ef2b85 GIT binary patch literal 98 zcmZQbEY4+QU|?Y6W=deJWvoqLtYNHSW@chwWY=U8Ofxpp%gc{X%g;%PPsuEcH(+28 hOfxe<6Jz9(X5wN{U~mSS!!VVb56E-@F+pH4HvsN#64U?y literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/float_exprs.wast.24.wasm b/lib/wasm2cretonne-util/testsuite/float_exprs.wast.24.wasm new file mode 100644 index 0000000000000000000000000000000000000000..37810664073f476ae40e58f55f9aa1464aa9c841 GIT binary patch literal 104 zcmZQbEY4+QU|?Y6W=deJWvoqLtYNHSW@chwWY=dBNi#Om%gc{X%g;%PPsuEc&r3}= lU|a0Z&zFqNAR$aDcRL7-tVHvqe97E}NL literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/float_exprs.wast.25.wasm b/lib/wasm2cretonne-util/testsuite/float_exprs.wast.25.wasm new file mode 100644 index 0000000000000000000000000000000000000000..57ab86234e67ee64a16c80ea20b710622cccdfc2 GIT binary patch literal 110 zcmZQbEY4+QU|?Y6WlCVGt!1oDV5+HMtYKzmVqj#~XA(&>Hqy(>k59|bNr^AXkI$$q q$S+}F5J@vL!4ziXl4s&$PyoUy3XBSjQzlL1hHw{wxQiCd=LP_|qZk54QpD9W$M%uOswjW0?~&IIz3 X6LT0CxOf=37@Qdx8tfGqrg8%S6SNRG literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/float_exprs.wast.27.wasm b/lib/wasm2cretonne-util/testsuite/float_exprs.wast.27.wasm new file mode 100644 index 0000000000000000000000000000000000000000..a5b348cb7dd9a311876fb4c796278178188167cd GIT binary patch literal 127 zcmZQbEY4+QU|?Y6W=deJWvoqLtYNHSW@chwWOrdwN;5Xn%gc{XEGQ_-ugJ_zEJ=+o zN=?oL@{$vC;)@H5N*EZV)67gjiqcApF=ZLKWSO`boEaDz>=hU$PUYrjZ~ H`HQ&$a1$am literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/float_exprs.wast.28.wasm b/lib/wasm2cretonne-util/testsuite/float_exprs.wast.28.wasm new file mode 100644 index 0000000000000000000000000000000000000000..72c035d96fae7570475a8b64a0c154f7a8cbe878 GIT binary patch literal 75 zcmZQbEY4+QU|?WmV@zPIWvpdpVq{=fV^m5rHqy(>k54QpD9W$M%uOswjV~@NDv2*j dP0j=gB`4-EFmUlQax*wHFf`aJFif4u4FH=L68-=H literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/float_exprs.wast.29.wasm b/lib/wasm2cretonne-util/testsuite/float_exprs.wast.29.wasm new file mode 100644 index 0000000000000000000000000000000000000000..9e81c03093af4485ff5feda9f83a2d3db6c05277 GIT binary patch literal 142 zcmZQbEY4+QU|?Y6W=deJXRJ?PtYfTWW@Q12FtP`-2xb}^>E-3er{(9Q#HSe>#TPR$ wV2G76FbZaxnIP1enE=%>VThG7FmuVWurVkwY+At$qBgGtQ#&_+sa+en0YlCrxBvhE literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/float_exprs.wast.3.wasm b/lib/wasm2cretonne-util/testsuite/float_exprs.wast.3.wasm new file mode 100644 index 0000000000000000000000000000000000000000..58fb0986884a79f15972b59b0100bb8afc4279d5 GIT binary patch literal 104 zcmZQbEY4+QU|?Y6W=deJWvoqLtYNHSW@chwWY=dBNi#Om%gc{X%g;%PuSzY-k1sAw lVqg$SGc&;yX5^A);$mk59|bNr_KPNr^8m kO=4gWPBSyX5M|^NXX0W|U{GM3q`)|t8^Tk59|bNr^8mO^Q!U kNnv0RPBSyX5M|^NXX0W|U{GM3tiU*l8^Tk59|bNr}%b&52LR kEMs60PBSyX5M|^NXX0W|U{GM3qQE$n8^Tk59|bNr_L%EQ`-A k&0$~=PBSyX5M|^NXX0W|U{GM3s=zpf8^TR literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/float_exprs.wast.35.wasm b/lib/wasm2cretonne-util/testsuite/float_exprs.wast.35.wasm new file mode 100644 index 0000000000000000000000000000000000000000..c3abad956d3e0ee07dc9aaa551bf97be6a266cc2 GIT binary patch literal 58 zcmZQbEY4+QU|?WmV@zPIVXR?hVq{>KVie2Ek59|bNr_KM&CM@KjV~z52hj`+TpWyS L3KVie2Ek59|bNr^8g%FoR&NsUiQ1yKwPTpWyS L3%`Zuf&&{kzO^HuT qNnv1+!6F);oS&OpT9TT=z{n-a#L1w*puo6$!8UFXYqtU;kOcthEghEt literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/float_exprs.wast.38.wasm b/lib/wasm2cretonne-util/testsuite/float_exprs.wast.38.wasm new file mode 100644 index 0000000000000000000000000000000000000000..ca28d5e4d1e170825cd7cfae31423d0f24dfd1ab GIT binary patch literal 59 zcmZQbEY4+QU|?WmXG~zKsb#EXW@2Pu7iSdC%a2b<&CM@KjnB=jNKJ_^E=^)!;NoWF OWKdvGVBEcM8#e%R84a@l literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/float_exprs.wast.39.wasm b/lib/wasm2cretonne-util/testsuite/float_exprs.wast.39.wasm new file mode 100644 index 0000000000000000000000000000000000000000..20d1715bd5bdb4f594f44836068c1196493db446 GIT binary patch literal 735 zcmaiwSqj216h&{Wa~<0W$aXV4ef}kxL<5%5}12~JrpF6YmA?eT4KselRxLkss zng{^GPIbjnEW08Up;dFDCy3~LnR}%j*K0K!qv-m9^n&p~&S%>1OC|e(zZlNuQUQ#k z6OLdU)1#4M9Mhv=xn8IJXHS}OOpii_aguwojAMEP|3MIEb?{lS{BI#VKSZgJWYHg`&d-6c+Y!tP3m OaCpS&NH{zxJ?%F@l;|1& literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/float_exprs.wast.4.wasm b/lib/wasm2cretonne-util/testsuite/float_exprs.wast.4.wasm new file mode 100644 index 0000000000000000000000000000000000000000..8c4561e20503025aba87bff65fd53ef00ea3909a GIT binary patch literal 104 zcmZQbEY4+QU|?Y6W=deJWvoqLtYNHSW@chwWY=dBNi#Om%gc{X%g;%PFD^}ruSzY- kXJ8OXGc&;yX5^A);$l!>a0Z&jFqxYV$aDcQL0};_0MS?$3IG5A literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/float_exprs.wast.40.wasm b/lib/wasm2cretonne-util/testsuite/float_exprs.wast.40.wasm new file mode 100644 index 0000000000000000000000000000000000000000..d363f76fb0a43cf6ef7c1a7f7fca2bd6e9da7b16 GIT binary patch literal 116 zcmWN{F%E)I5QO2`*=GoDXsOr2#uG>frMJKk63|E?T9S7P?#oX3&5!5$5ddQBnK$&3 zWz(b~rzEkW)-*5k576&_2_2?!c!TFgOE_Hagk424TWy`r8w2-HXO~`=5XYl}nHAB; FYX{304#ofg literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/float_exprs.wast.41.wasm b/lib/wasm2cretonne-util/testsuite/float_exprs.wast.41.wasm new file mode 100644 index 0000000000000000000000000000000000000000..c6b9e24fb7b90a707195412ae109802208c32db9 GIT binary patch literal 116 zcmWN{F%E)25QX74Giz3z*jf(-l_#Ksl3OexB(4Su!ETd1j2CrY`Mn?0z7haZPFxET zRVot1K-_?Wk^_)9O4eyY1#}>;jum^SdK!Ja=7|8%OtTZ=*6OYV^L*^tPbCQucsmPoZWKNniHvnz{Ph0>1 literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/float_exprs.wast.44.wasm b/lib/wasm2cretonne-util/testsuite/float_exprs.wast.44.wasm new file mode 100644 index 0000000000000000000000000000000000000000..9650b94d6ef65a3ed6edc4a56b8550fa2bc39553 GIT binary patch literal 330 zcmZ9EK?=e!5Jmr_sf`wq-XJG%q2g^c5!*}l?DS28#6 mEx5~FwR)4;z{1i=CyUZjUC-`%Ek$tv literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/float_exprs.wast.45.wasm b/lib/wasm2cretonne-util/testsuite/float_exprs.wast.45.wasm new file mode 100644 index 0000000000000000000000000000000000000000..d8d69bbb208ff97d2db8a8348d6f5c3452258c67 GIT binary patch literal 440 zcmZQbEY4+QU|?Y6W=deJWvoqLtYNHS=HvhhF)#uF`%gv=nKWY~y}bPRwEUcu_?(jX z;?$hfM&8Z`bqwg}Kp^u{>R+s*n}DP5JhDjRjzs;N|VsR6huh(e}rwB>O{ zTYjSVyXjj2SF{x}#cs{GqOEB0!gvW14({1g&`Rh-2}1l>rzY6hF&pd09Hb*#*?mX1 a&&@S35{Ba0Z&jFol~B$aDcQL0}O#0MgeM6aWAK literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/float_exprs.wast.50.wasm b/lib/wasm2cretonne-util/testsuite/float_exprs.wast.50.wasm new file mode 100644 index 0000000000000000000000000000000000000000..3fd1baca496625adba491b9fe2af1d256e473c7a GIT binary patch literal 58 zcmZQbEY4+QU|?WmV@zPIWvpdpVq{m;1XdJVo+dk{0{^S Ng`1p#8ct8*1^`)u4lMux literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/float_exprs.wast.52.wasm b/lib/wasm2cretonne-util/testsuite/float_exprs.wast.52.wasm new file mode 100644 index 0000000000000000000000000000000000000000..61021fcf69b5e7178ae277b781687fcc6733b75c GIT binary patch literal 64 zcmZQbEY4+QU|?WmXG~zKuV<`fW@2Pu7hvSc$tlZ?FDNoHH!wD1VBivG6lG9ga6J9L Ty`*T90;6L?!vyxiO_R6*m}d`+ literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/float_exprs.wast.53.wasm b/lib/wasm2cretonne-util/testsuite/float_exprs.wast.53.wasm new file mode 100644 index 0000000000000000000000000000000000000000..4e3bde4866aefd2f84b6e59332e20a971ced7609 GIT binary patch literal 114 zcmZQbEY4+QU|?VrXHHrQ?1C7- literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/float_exprs.wast.54.wasm b/lib/wasm2cretonne-util/testsuite/float_exprs.wast.54.wasm new file mode 100644 index 0000000000000000000000000000000000000000..1572cc4298e33508637510149314629e6fb1a604 GIT binary patch literal 47 zcmZQbEY4+QU|?WmV@zPIWvpdpVq{?FW@OLID@!dZPGw-=;$h@saAsg=uvcK1$_)Up C-Up@t literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/float_exprs.wast.55.wasm b/lib/wasm2cretonne-util/testsuite/float_exprs.wast.55.wasm new file mode 100644 index 0000000000000000000000000000000000000000..fa832af0e49353c352a5b5eecd9f8f7cd14d35ff GIT binary patch literal 98 zcmZQbEY4+QU|?Y6W=deJWvoqLtYNHSW@chwWLIYrNHaEyFD@)9iOghlSh#8OIcg literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/float_exprs.wast.56.wasm b/lib/wasm2cretonne-util/testsuite/float_exprs.wast.56.wasm new file mode 100644 index 0000000000000000000000000000000000000000..ef8bec6e156ac2617059afc1f00c76b2f50d6e43 GIT binary patch literal 126 zcmZQbEY4+QU|?Y6W=deJWvoqLtYNHSW@chwWH)6JPct^s%gc{X%g;%PFG@|$EP#*< t4B}~KCRk+{xwM%C7@Qdx8tlP@0>jj)+!72fKr4XYgFT#~z_55RHvoI?9t{8h literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/float_exprs.wast.57.wasm b/lib/wasm2cretonne-util/testsuite/float_exprs.wast.57.wasm new file mode 100644 index 0000000000000000000000000000000000000000..15959e63292825423f6021762c1cd8f0cf0fed51 GIT binary patch literal 120 zcmZQbEY4+QU|?Y6WlCVGt!1oDV5+HMtYKzmVqj#qW|B%XHqy(>k59}=PfaRH%uJ3? tOH3}wFUrhIXJC*@Gc&;@$;c(k#LJ+-puji@L`S@fI%P1^_Ru9$EkZ literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/float_exprs.wast.58.wasm b/lib/wasm2cretonne-util/testsuite/float_exprs.wast.58.wasm new file mode 100644 index 0000000000000000000000000000000000000000..b8870a873c7cea29be912ef9733d076a4b814ef0 GIT binary patch literal 120 zcmZQbEY4+QU|?Y6WlCVGt!1oDV5+HMtYKzmVqj#qW|B%XHqy(>k59}=PfaRH%uJ3? uOH3}wFUrhIXJC*@Gc&;@$;c(k#LJ)ngi{n46&R;X=7#VVfq07+asvP_M3>=WnGs^eiZ$EMQ9;bG6Ek83mtszA!IfC>7V`@44}=r^Wg{}*uH&(}*UfyJ04u%m()FO?ta`EwW251l1d<{GAOn*i1d|~I zAOJxGY9Rn10wDt+0YQIiA^{Bm3kx6u3n&2reF8uOKp+Aj04f3ik|6>h06_$5Apjr& zL4Rr?0U!Yl01FEs0t*X=2mt^=01JQ!#Kl)6rG&@}ZMaJ=@^%*-%1Txq8*XtTT^Am1 zzs(d}$01cwIh-G|QShUa*TF2VeyAuq0U`7XSd;idcb|hfYG1nd3fNI4iVt*WnnZP$qJ2KXVWG5|bk|VRjNoz?%h=>#T;}ls;AHjOg9u{FO((Rs$g* zOy<9P_J7s7a~#1GkHjaIv%NF_ctKylTF&-oZgZL!W^e=e&L^W%vY$J@`>yTNTKG3t z@bzx*u}yG2RHp%&g$PKI^_>i0hg;cH9#L(GjtGpUaXMBAXGV{Y6Dln1EFZLDD{nyx z#AQOFF>5S+KD%|ShLa2S62P7N?gEU?9P%Eacq7}y9!Ue!am)x%#n@c! z)wN};waFpU$tiZ;@Gu%%Jn}o+Iyr(m76@;s@xEzknQ^8C(-e~`7V<9<$9^EYkwotJ zD_pZ78Ae`@+mX|Jcx$&30FUdviuKek#K9ilb7NUY zNdpSE&m_;B4n%sM6#GKIojEX`psO#@uAXXxL*rF_g}-Bp_?8eK{%z+X8{uh2ibTlB z`3x%=2c-f&@-PsZg^FMAfkmKqu>%luORkumN57gaI@J#YX5&3m*+9-8Z!#|-DlBSVzto%`P=mK>Hw(h(V286-PSbKC9y``oT_p4V6ceD z;0sw=B~K}4`QtAB>DuKOPbXsZ&ZHrgbjMd@Cz?$CRDEI2!>or!ocjL>%6XS(By`Hu zA%i9*84@>S8Rcc*bajs1$nSK=*dZ%<1W`t1U;|zH*z{$jo?Ro_*NT#Wq~3Tu@mE4^ z&B-s-q@Jrl^vfI9qssj2rvb8>X--C)7*5@Jr>dq>IUesY%$vPi?o1(VFaUC}Mqdce z#kt@O)^H{hRdw&`tBZRP+-(}NYQ!bas^gzYNr}rhn+m4^U~t^G$b;cR L^}elQl&y`SSTY!m literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/float_exprs.wast.62.wasm b/lib/wasm2cretonne-util/testsuite/float_exprs.wast.62.wasm new file mode 100644 index 0000000000000000000000000000000000000000..3e6561f5f4e9f2fbfe3b38a9f7ef777700d530ec GIT binary patch literal 2221 zcmV;e2vYX|VRLN(000012LWILe}4gd0|Np800jgA0RaIAAp#9%HZ(44VQ67)UvqVB z000eUHZ(49Y+-3`UvqVB009bO0yhBzd;&lNKp+Dk04oCkAOxWz1fU`UAOoQw1fd}W zAOJxKY9Rn10wDt+0YQIiA^{Bm3kx6u3n&2rd;&lNKp+Aj04oCkpdkVv06_?9Apjr& zL4Rr?0U!Yl01FEs0t*X=5CH%|01JQ+69t4qU7{?;L)%rU&DvGtbNpD=y43*vgEc~k zixXWqN=FTHbD7 zD3TcL2(IT<+Oei(rE*Y58@Q=d*QN$r4?$5JRBAE^WM8g;R2Wtwg*qJXNwJ znshpz;n)vw{HZ$4lS}O5e%)Os&G?|591*}*F8#<8GR!&}eWO8D?ZbjeDg++ybGa@q z<6rdO=CU&kIX`biY6HPSx%#ol?WI_mf95$8o%!zz$5t&| z@SR=W{J5+_%NHAM6$^A-(=PaHhP1kKQd60!b|6K`K!9r$?V5c=9t7+zr-A*ka{+h6uK3OZswdfjP%|TB3+?*P-hK2dg;`vE`KU|Fg@yB5=j2x z7|oOVv^3zI_R9WDJ9uphTo|8Wx!ttj4|d=iX$@Xjb8ub` zEunq?AnTDdlB_s#Dj$wyyJRP|3@MO>2uD+wpJ|cZiX(3}5?E?Z- znh#J;6IwN)BBbAj!gP5SxM^viQe6>by<3y~X`u8I(1B6i`V1ArddXsXsU6AYTC-c1 z0z70Q5(0+sdvKG4LCG#OAK z3cOI-JTTTeF_euu{_hl5olBDdmLv>s{k$V~0&MG2a)1$jfI1TrI2|}il|UzoM0@Dm zZH$bLJhihJ4)zEdgh4g`i@1|O>fuoxiKUG~XesJ1!Fp2bkX=pIfaBM7NY3rk0UV86 zrIZbL&+!HmFPH+PZ7yu`)pRL|O!))##~7`8@M!p4)>(&c);|Wmh9KiXks|YMi|}Y1 zSEu~2e4d#LmKup)<_&xZQJ|t{nnwVWYxyYfXxn1(;AJdRGvKGn5kfHbuK~ejJu(4r zt1iCNi@p@Y|Lptl`Na$cZvhEw<1{f0A7-XPyc&l|78Z=KkPS493gHP}5Tt8X%<##( z+_+rM_RNiSezOON1TVB+$>T~Ra~Wc6nge!3hMZvh+j5U5pxv{@+W-0NYO#CM&rmnX zdUy=vI=1!Z^q6i!eKm87MZi{<&27%ltueF1RQm7L!1QWgROd-PGYT*`{n-Wor9W3j z6t$5T%4?V-dS$b00<_F|U0B$&)s(LEZFOb$lD~dOOg!$}tno5k`)@%UG{}Qb!dL;m z1wLjLrUY$WPlgF6f+Z5oI?c{&yvnR7o9=2QhMq-m#?rkzeM03Yug4wqfylFVil{cD zt}5mj;Wi?z_9b$#Ig0_BB720xEnjk^n5-3W=hPVDebO*|GYHMf#3F@=b%Dl8bXbkx z=&Z%7bz1Z&67U#BQu3FwlRBX+kc%G>Ytg}Qy z;JjTMoJm+p92rT$I_mZ7JAtW7a16|z8q+VgQZFDo>tsvt@wUy$i;ucsFx=S+4Lc5>H`V;_m(?@d0%`>FrQX6 z-n4VnmGBh9bT18~9ZrogB(oZXg<@KJJQO(>=56aY!T?xX3*$VBV&V8TOIG5CV2i$| zIFWZ$sahl@ke{VOck^61-~V(6cA?E5Vhe$RXs-pqz<(z0z>%YBeJNo@C*@a&+zpom z8Z)UxirNAYML&*Jrgn@?bwx~I?3W>`%`7m$F!&W)CE%|(9J1`09GX=eOE+ggSB(xO&+e3FtW5CQk&;195JOM0;F;S)9`3!@60fHnS?@H;ycA& z5?m-vwhm6nT<8Ic#pmRmLhfCh#Ov#52`7@3nh{iU#1eq}eg4G=V1G72;1IgjD{S$! z7yc$R<4gFci7@!wxQ?CRD2hj#e*y vuOftKrHhyLr2VMObwQSf{U<#shK+wr)Q)pO^d92fSSOdxoRrUc1TWm}vyure literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/float_exprs.wast.63.wasm b/lib/wasm2cretonne-util/testsuite/float_exprs.wast.63.wasm new file mode 100644 index 0000000000000000000000000000000000000000..fba3bcf97217a9467b201796bb7c348e74fda8c4 GIT binary patch literal 96 zcmZQbEY4+QU|?Y6WlCVGt!1oDV5+HMtYKzmVqj#~WfD#^Hqy(>k59|bNr}%(O^+`w gO=4gWPBSyX5M|^NX5wH_U{GM3+`|oFES$v+06Z}k$N&HU literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/float_exprs.wast.64.wasm b/lib/wasm2cretonne-util/testsuite/float_exprs.wast.64.wasm new file mode 100644 index 0000000000000000000000000000000000000000..ca400ce4cbd33d821ad612c36af1202a58e92329 GIT binary patch literal 96 zcmZQbEY4+QU|?Y6WlCVGt!1oDV5+HMtYKzmVqj#~WfD#^Hqy(>k59|bNr}%(O^;7Z gNnv0RPBSyX5M|^NX5wH_U{GM3)WZ#7ESSX&05Y-`ga7~l literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/float_exprs.wast.65.wasm b/lib/wasm2cretonne-util/testsuite/float_exprs.wast.65.wasm new file mode 100644 index 0000000000000000000000000000000000000000..f5ddcf462e2d66abb79febbabceb49e097bcb3e9 GIT binary patch literal 106 zcmZQbEY4+QU|?Y6WlCVGt!1oDV5+HMtYKzmVqj!9WfD&_Hqy(>k59|bNr_KPNr}%( mO$T8H2JtjA6Ra|fT%t^z3-#*%S?<< jOi5v25KA*N!6w1TrO71Bpa6uEkP$aTY=Hs;0&xQX%@!Pm literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/float_exprs.wast.68.wasm b/lib/wasm2cretonne-util/testsuite/float_exprs.wast.68.wasm new file mode 100644 index 0000000000000000000000000000000000000000..39d64d72d6e88914668280d5438f7331fb02796e GIT binary patch literal 102 zcmZQbEY4+QU|?Y6XG&nMt*vFOO<=C6sbQ>PW@chwWY=X9PBS*r%gc{X%g;%PPsuC; jVFm`_G&2(nQARFtCN2gA1_j2c3QSYEAy}1eO{gV60(gW@2Du*Jlz*Gd9x8%a2dX&q;~TEzOBf q$t){oU=T?&Gr<&QPW@chwWY=dBNi#Om%gc{X%g;%PPfSUP pPsuDRW?&FWGc&;yX5^A(;$=`^P+*#>zz8HJaYJ~ELA=EaxBk59|bNr}%b&518A mEGj8xU=U3+Gr=Ox$R*0e$)Lb6QGs#d6mAe}z5?U?Mce=dV;UX+ literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/float_exprs.wast.73.wasm b/lib/wasm2cretonne-util/testsuite/float_exprs.wast.73.wasm new file mode 100644 index 0000000000000000000000000000000000000000..abbf750b18416c151980a101b1cfcfc01fb23a08 GIT binary patch literal 102 zcmZQbEY4+QU|?Y6WlCVGt!1oDV5+HMtYKzmVqj!9WD-p?Hqy(>k59|bNr_L%EQ>EL mEGj8xU=U3+Gr=Ox$R*0e$)Lb6QGs#dRBjM!z5?U?#oPb^Z5j#y literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/float_exprs.wast.74.wasm b/lib/wasm2cretonne-util/testsuite/float_exprs.wast.74.wasm new file mode 100644 index 0000000000000000000000000000000000000000..add2c0ab20d3b2a7c5e23a087b68ea431c1d32ca GIT binary patch literal 112 zcmZQbEY4+QU|?Y6WlCVGt!1oDV5+HMtYKzmVqj!9XOc)WHqy(>k59|bNr}%b&518A rEGmgl$t+`FkVrE#!7jzfCCS9ipunKOIB|*s<5X@4d;TH?#>LzKK6xD4 literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/float_exprs.wast.75.wasm b/lib/wasm2cretonne-util/testsuite/float_exprs.wast.75.wasm new file mode 100644 index 0000000000000000000000000000000000000000..315d6494e24c4eeefa1b1bc9b2af9640fc61e974 GIT binary patch literal 134 zcmZQbEY4+QU|?Y6XG&nMt*vFOO<=C6sbQ>PW@chwWcOuKPBS*r%gc{X%PB3+h|kO` zNiE7vP036wNsTWqP0GtJ%1z8+U{FpoGa;yokxQJ3i$Q@wfpLlg(-dw9bCCkmB5nW; C_9gKE literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/float_exprs.wast.76.wasm b/lib/wasm2cretonne-util/testsuite/float_exprs.wast.76.wasm new file mode 100644 index 0000000000000000000000000000000000000000..10b819568083a14070762737ec43c0c904f28500 GIT binary patch literal 246 zcmZQbEY4+QU|?VrW=>$Lt!1oFV5+GBleLVs%pB|>DMm&n_Ih^yG-D&ZqSWO4l+3*J z_|!rM22_!pR0c*gkrDVW@chwWOrneO*1yq%gc{Xttd&&OG!p*8^T@- literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/float_exprs.wast.79.wasm b/lib/wasm2cretonne-util/testsuite/float_exprs.wast.79.wasm new file mode 100644 index 0000000000000000000000000000000000000000..687aad0de19a7254dd9173177f7fbddeef36ad8e GIT binary patch literal 388 zcmZ9HJ#NB45QX3DuEBVPK#D}YZJHD~<~o=k(?lr(E>hSBpbXeG#y&&tmszi|h^N>$ z^WMxSEjFi50zj{$m~zTvm2$TLDaqAe3W89mnW7I}89m8he N;K8UX$Efd({sS*FUoZdw literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/float_exprs.wast.8.wasm b/lib/wasm2cretonne-util/testsuite/float_exprs.wast.8.wasm new file mode 100644 index 0000000000000000000000000000000000000000..bac9a68a7761684d6bf72a7cc05a40dc7f0655eb GIT binary patch literal 102 zcmZQbEY4+QU|?Y6W=deJWvoqLtYNHSW@chwWY=X9PBS*r%gc{X%g;%PPsuEc&(BL` mU=U6-Gr zC^bUh9+ZNI4OLlRVCljA3T&vR6@=CSRy7s6i+00k%xw+410#5KPi5K!#J{}`21e7$ K!p;Xa&F%*`N-Pur literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/float_exprs.wast.81.wasm b/lib/wasm2cretonne-util/testsuite/float_exprs.wast.81.wasm new file mode 100644 index 0000000000000000000000000000000000000000..e6489b12ee5f94834103f420882da096349644eb GIT binary patch literal 126 zcmZQbEY4+QU|?Y6WlCVGt!1oDV5+HMtYKzmVqj!9XOc)WHqy(>k59|bNr^8mO)`wn zEzOBfOi5v2kVrE#!7jzfrOqV4puphFz|denS%Gni0^=lZ5uktz&>|rCV82j-aghS! G0&W1RydIYT literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/float_exprs.wast.82.wasm b/lib/wasm2cretonne-util/testsuite/float_exprs.wast.82.wasm new file mode 100644 index 0000000000000000000000000000000000000000..b0ba33f992bc218bf25d314f61cda63f94a8aa44 GIT binary patch literal 231 zcmZQbEY4+QU|?Y6XG&nMt*vFOPhhU8sbQ>VW@Q12GO~9vvdE_y8|mfc$EW4zq{Jtt zq{Qc>#^>he<(K5=WhQ5qR5CDNs7Oas!6=_*W`frYCJYtmW-xPEvhXq}FeorhQeXrU U@!ZI~1SoF-NNzzY3NMWt0OamKtN;K2 literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/float_exprs.wast.83.wasm b/lib/wasm2cretonne-util/testsuite/float_exprs.wast.83.wasm new file mode 100644 index 0000000000000000000000000000000000000000..b34801139900aa6d2f8c94eda5c7b4052dd641c7 GIT binary patch literal 216 zcmYMrK@Ng25QX74twJgB4xE667;nIWLnt*mH6#KHyM%Cco0y@q`u<5C9^a7w&`CM9 zuCzI|EVSvu#3v|TJ{aqpb3M(W{{$cfgZ6j_s1yus{q-W7Lkh-mkGRQFFml@&g9;Vh T+VYQHa2GhiQ^10kz_;ZOzk@13 literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/float_exprs.wast.84.wasm b/lib/wasm2cretonne-util/testsuite/float_exprs.wast.84.wasm new file mode 100644 index 0000000000000000000000000000000000000000..413a38416431151746f4521c3fb2caa8d2eec396 GIT binary patch literal 142 zcmZQbEY4+QU|?Y6WJ+LQtOep4W@aV^Ms`^y?lfZ~z0`u@%$)o@1_tglGZQ$Ekt>u* zp23-cp}`(VI5>bQuWeC6+91e@&iWV+f$PEBf CcNzHr literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/float_exprs.wast.85.wasm b/lib/wasm2cretonne-util/testsuite/float_exprs.wast.85.wasm new file mode 100644 index 0000000000000000000000000000000000000000..7f542c9297aa9a9530157bd4cb97115c413501cf GIT binary patch literal 160 zcmZQbEY4+QU|?Y6WJ+LQtOep4W@aV^Ms`^y?lfZ~z0`u@%$)o@1_tglGZQ$Ekt>}^ zi;=0;nSr6fUXg*>L4iSu5y)Y%pQ6M77Muho<9Hdk6&Sg#7@2BZfU-dF0j?Y>@W6hN O5(8Xv0i2Zr(Fy?h*&CSv literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/float_exprs.wast.86.wasm b/lib/wasm2cretonne-util/testsuite/float_exprs.wast.86.wasm new file mode 100644 index 0000000000000000000000000000000000000000..f8608e0c5977cf2e814203b70f8e4a4b0a3ff5d2 GIT binary patch literal 337 zcmZw9K@Ng25QX74MFl17H~=Sbp~l-tYoJvUkyyJifp9KwXGhbOoy8>IpUL3->E@9Ys8G>~m$La!l2r%QEE%M}=Rpn21Zh?q)UtGtVKp}Y0DqlRl>h($ literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/float_exprs.wast.87.wasm b/lib/wasm2cretonne-util/testsuite/float_exprs.wast.87.wasm new file mode 100644 index 0000000000000000000000000000000000000000..8bc5cd88ff1b4c67167a2381f05278920fecddb5 GIT binary patch literal 964 zcmaKq%}&BV6ov1!Xcbh%65N!ePhk9uTjI}q3jkPPbt4{0zUgF4}dTvoX&Niqpb4vQ#1 zvRZAQ93L32<=xn(XEiA^7;RWy*YG^kWdIubO@leiY8suaO?0%mx%>sG+CDp7F+tYQ zUpgVDqrGy%S~-HCZKucNVD})n{QiVAYL)Ud|$1`cm#0&QF zud-SK9VR-Nyo}C$-~Ur?3n^vBiz^Cd9!G@=zXP2FpW_Rj#rmDWLt4g$u(*s}!P~f? zV)rHg9pNdNp#lm%H_}>^^J~vy&JVbe*5cfpIiBGMb4|nfS2!2zU1ZiEb~r?^V9q=KK(rSGrg%l`phzeQO9 literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/float_exprs.wast.88.wasm b/lib/wasm2cretonne-util/testsuite/float_exprs.wast.88.wasm new file mode 100644 index 0000000000000000000000000000000000000000..66f2bfa699669a5fa735908740e7e27aeb3d94b3 GIT binary patch literal 135 zcmZQbEY4+QU|?Y6WlZ3xfda-FW@aV^26iJR;gtN6_=2MRl+xsq_|%HT+=84`1_p`p z%#w`wq|Cg;qRRN<(%ksu{G6P`g5p#LMlMq(Nd^T51(rn$j0&ua7AP<&umMSC1@=V? LxG`lQ5(~Hi(Gw&O literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/float_exprs.wast.89.wasm b/lib/wasm2cretonne-util/testsuite/float_exprs.wast.89.wasm new file mode 100644 index 0000000000000000000000000000000000000000..7fefd64cbeba5d8bc2773f324c0d3aa463cef60f GIT binary patch literal 102 zcmZQbEY4+QU|?Y6WlCVGt!1oDV5+HMtYKzmVqj!fXA(#=HquMZ&nqcPOfE4>%S~ip m5J)pKK^0=;l4s&$PyoUy3XBSjQzlR3hHw{wxQiCf=LP_Urxy+Y literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/float_exprs.wast.9.wasm b/lib/wasm2cretonne-util/testsuite/float_exprs.wast.9.wasm new file mode 100644 index 0000000000000000000000000000000000000000..1f070302c4d6093d1a6190e1bce9ec807df7097f GIT binary patch literal 104 zcmZQbEY4+QU|?Y6W=deJWvoqLtYNHSW@chwWY=dBNi#Om%gc{X%g;%PPsuEc&r3}= oWMB|UGc&;yX5^A);$l!>aAsg=*gut<56E-@8Vm#<_AllJ0M0EKL;wH) literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/float_exprs.wast.90.wasm b/lib/wasm2cretonne-util/testsuite/float_exprs.wast.90.wasm new file mode 100644 index 0000000000000000000000000000000000000000..7e53886a4c2031b9f68b603142681332a1d1d0c8 GIT binary patch literal 120 zcmZQbEY4+QU|?Y6XG&nMt*vFOO<=C6sbQ>PW@chwWVdIMNi#OmOUW$DEY8f&i%+VI tFV0QO$%)S^%}q)zVqlO-Gc&<0&B!Ir#KoY%puniWG<7mJjJbFrHvpXCAO8RV literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/float_exprs.wast.91.wasm b/lib/wasm2cretonne-util/testsuite/float_exprs.wast.91.wasm new file mode 100644 index 0000000000000000000000000000000000000000..97da0e6c0445c979ad40717aa8c476a3f5079b3a GIT binary patch literal 98 zcmZQbEY4+QU|?Y6XG&nMt*vFOO<=C6sbQ>PW@chwWLIYrNHaFlOV7_qNzIEdN-W9D jXJ8OWGc!RIV&sx!;$~1_P+(MGnmB0+H;g@h!6I$|WK|aL literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/float_exprs.wast.92.wasm b/lib/wasm2cretonne-util/testsuite/float_exprs.wast.92.wasm new file mode 100644 index 0000000000000000000000000000000000000000..be60329b83218b39c9dc5db26eff89a5c83da1b8 GIT binary patch literal 126 zcmZQbEY4+QU|?Y6W=deJWvoqLtYNHSW@chwWLIYrNHaFlE6&U*OD&4eO-;-zW?&FV zGc!RIV&t-95@&D*nqjZN0D@D1>;{KP6DLjKmS=DQiUYv|sN5nbU%+9(`~{1+0k;Di AH2?qr literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/float_exprs.wast.93.wasm b/lib/wasm2cretonne-util/testsuite/float_exprs.wast.93.wasm new file mode 100644 index 0000000000000000000000000000000000000000..da5cc6ed34e98a76be577cd9c040721080466d65 GIT binary patch literal 58 zcmZQbEY4+QU|?WmXG~zKsbQ>VW@2Pu=VRn5$j{6xiBHQfEn;Bc5@r-+P+(ACT#s#PX3=|oe926KF z89jIzpkg2F6`2sy%*+l7j0!LT1qTIYsGNesA|)2MmIaHUOaTW4n5clmg2fAACLx4H qunS9ogcmJPWQ5!B!G3`vGu-M8_KOsmfG(}iQexm`;O16fk59|bNr_L+&r8WH z$;{77%!$v;OJ-n@PBSyXDa*)Z$|TC50EEsA3=Q^^6c~Xt14FDdw=7uH1;k@u_+Y<4 Nff34PU`Uqc1^|0LAj$v$ literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/float_literals.wast.0.wasm b/lib/wasm2cretonne-util/testsuite/float_literals.wast.0.wasm new file mode 100644 index 0000000000000000000000000000000000000000..7ce5d39c8355ca57acfe5eedb272fe99785c5c7e GIT binary patch literal 1930 zcmb_cOKTHR6h4zSP13w$qOI>X)^}@dV|_&kG!@)+QQVGWJ1K+7OvyxT1ejFA)3-6?LJwh;z=(oS7Tj>cR^H=X~dU-~H~rhXKuQC;*_uLbpI^yWgXM zYh@SMWhuL^$n#h^Qk$KbGBpz*gVCC08!h9Wt|FumWa_ILL!l&f)iuMUmVt514YOu7 z8(O`-q24jA`=+Yd>KgUfs53}9ZdtWV-6mc*fxL!cFH<^H;8b!D@o~vUl<4lZhH11m zAVzJ>WPF%#W-=a+;&u=8rUi*ChD;?aNf^@zOA!SPLz<4$aBsk)K_(^qyO%;20a*cP z>nd5)AxD}G7qIW%?ltWpp;l8f>V~UdCmY`8mHh0LF^Zyqe<%GX&M{H z{4diqPCC*w6%)wgX*yQmRB|xkK{5@37mfr>{I?3 zDlB&538;#{{g3wMPDyvC%6GxR8^T3xooDMeOSvzi5{pKL!h_#LvQSjEKEC=Y+Qg>4 zw(XK&8$iH;oH$e&nXE4T8XK)pg13n)z{!Y2*h~kLE#XZtrmqJ$l7O5z|7X*O@1IP( KzVUWxGyWT-L^E>$ literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/float_memory.wast.0.wasm b/lib/wasm2cretonne-util/testsuite/float_memory.wast.0.wasm new file mode 100644 index 0000000000000000000000000000000000000000..05258ff16bc89f23b1929feea06daf07c2ad791d GIT binary patch literal 161 zcmXwvK?=e!5Jmqa8PhcN9^%4~EQO|9X^!GW1!oWkKL5SXV8|l@pvLx~ zmt^e$yJ3(qh8@ZIGgtT1@$j668&Ey|NI}=UOml(>I{(=6oN`*=>Xtn^>1O^6XHdY2kCMG6U7DgaoH)rKYGc(c4$xlpSVBpAv zF&Q~QqQxcoMX3x-oFHKco0+vJwK%nefrZPSm7T$nL7SO@8$@dYX#pVZ0<;eZzSLU+ f1%!YCP7M(7>pz1zP>2&G1ZHvbF#_4#954+49fKZX literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/float_memory.wast.2.wasm b/lib/wasm2cretonne-util/testsuite/float_memory.wast.2.wasm new file mode 100644 index 0000000000000000000000000000000000000000..9174f1c7b776064fd1c0af4b6a3b2900510b6a70 GIT binary patch literal 162 zcmXwzK?=e!5Jmqa9n+Y44{_nbLUkLwNDD>~EQO|9NsiKs7MvgseExfXH5lSZ0I1PD z=p#uzpmz*XN^wPU=F0W6y`10E@Br%9AIX+AF4G*KY?*(oc@8lwsP-KjcseP#(nsk= c`VOq=CUOw*Ip@uEVzw9xIY;ntEPt)(3yLHflK=n! literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/float_memory.wast.3.wasm b/lib/wasm2cretonne-util/testsuite/float_memory.wast.3.wasm new file mode 100644 index 0000000000000000000000000000000000000000..3e56542a049e005200b433cf5617e63b67fb8235 GIT binary patch literal 175 zcmXwy!3u&v5QhKRb<)kC=q)7Z6iKHrdJu&+2ok~d7}-O6>QXZ;eK7nV-(}E*mH^Pg z)}V*nvj*&pLB<$PNJvZ0uKV5g-Zd8>yZx1%)-ZIvhjE&tTkd`E1CsfXQ&hCE$aM?Z fmF!vm3DbCxu$FLoMcyBjlANZW~D21k5X}y_8@I>Ma;=t#>_Zjs0P5`K~ z9q1vMJHW0OWQ<`)a{j=@Wnb@ZLw^Q}>mMoTnx|n*FhS=ZTOLzR6I|J_M~kgN)ZR!} c(kH@uK8mbG+UN56_(m+KK`E9b6rKKk0e`g{FaQ7m literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/float_memory.wast.5.wasm b/lib/wasm2cretonne-util/testsuite/float_memory.wast.5.wasm new file mode 100644 index 0000000000000000000000000000000000000000..d384d39e300707e00579c5969f78b7311002aba4 GIT binary patch literal 174 zcmXwy+X})k5JYE_u1$=H_!lDhBo?1U@k3fL1wkn^eH1VME$VKi1H&8+EQ=~#2>?xO z3A#z|C16JkGRAO5lDuG7Z`P|zQ=I^J9+14+)HQ8{@v8r9xs54y$i_R)vB%OP=q_Yu fvPXRgydPT;a}kHvv(M*?LX=n4Q<#!)aKph5AQ&Eb literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/float_misc.wast.0.wasm b/lib/wasm2cretonne-util/testsuite/float_misc.wast.0.wasm new file mode 100644 index 0000000000000000000000000000000000000000..351164b0a8ffedc505b68a2908cc3aef09e0346c GIT binary patch literal 578 zcmX|*X->m16oj9hmNZS+m$DS8C*TJl&eOC_sz_-HSrAC=34pTi`+5aVz`gJr8!UNd z?0J?y^0S^GB2gBu1M;VzlWB&jD>lKT&A2 zNQ^e;as7`rk7=MSINWHo8nQ-Pbou@dZApKr(3W*lXe-qpQMai<4RPjbKR141{L(F} z{uFuuJv7Y?PDjuY^cZ?#`YYqt#$SxT8hzHqvSK0qI#Pp1Dc{^|Y# DlvQuc literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/forward.wast.0.wasm b/lib/wasm2cretonne-util/testsuite/forward.wast.0.wasm new file mode 100644 index 0000000000000000000000000000000000000000..7ac7c552c444e26f403cf100d61212c5cb3f85c9 GIT binary patch literal 82 zcmZQbEY4+QU|?WmV@zPIXRK#tW@2Dq=VM|?ElbT~U|`NqNnv2*(q+X=)_d9dP&WzJY;PKpZ&Ue1^o%SB0;35!9* zPY7}JIE)G(Z=-eQCxlke4Jwkcuvp@^RF;(`ewQi1$WSRY3X>n^kwuopLb@RigkdcF zval(-q=_4(o4x%#w^#4_!_m0zZ>-Z}d1UiEJ)T3l;H=~kaB7y)8F_pAgH9rJdJY0> zH4m}W6LSz)XQa~V`?tLgJ!u}eL${xqp`Axi@l+0B*{AaeIL}y0Co{vda}Ze1<{_4P zZVm$Ld8xG24A%^=e=z=%UMSykdlRpIYv1qCizOBCmcBIgQTlS~vvPgv1AoO*{9Ua5 zrjj^kW+4`OwKDX^li{GQ8opLeL(Z+w0;p|F18#GE79jJwmDZ?6T)8QChn{;g6@8a*h8Qy=&{rs5y!U8ttW@H4-gs$QJ35^ON()1^~0*4W+cc`5PT6LTi<%Z#4EgX^FG)=qy(@m;Hf1uB#7~111zv5*#fAQlLc9DuNa(BCa@+M}VTxVw)sPq)ezxpiFEF zl}k*hq5x(sr)<-=HCtS++1hr^F2L$P)NF&T)Co#Q2f*`-**}&gr+4Xx>X1roO{YPf4zjbL|b?7{M>}MM6EynUHkOAe|8#(Dzica zMXX~96Ch`uotm?OI-8a?T+(1Nx-5tQqpXo61n4KBk>oVOx3M7|?Q?9rP-i35*$8zu zg3o5|)FCXYP}MQWZv?f_E%`N%akn_@;Hg^2FftNTvi5(-1(10QMYT%u+<$LE)e|Hi E0ykHxxc~qF literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/func_ptrs.wast.0.wasm b/lib/wasm2cretonne-util/testsuite/func_ptrs.wast.0.wasm new file mode 100644 index 0000000000000000000000000000000000000000..8916eb2579094336e567358da3e6e353dbca43d8 GIT binary patch literal 133 zcmXws%L>9U5Jm4KGm~Nv#I0Qjeo6nNA|pPqDM`d-f4xBw&OMidb9oT}I)oAUL(7OZ zTE2qYQ&(oYR4Y~He4i@R2L-W+hMs+z4BppI0!zJRGYDVPJ3}`ob%+hdu#Evn4D|TD Kdq!=&LtFt}85PU` literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/func_ptrs.wast.8.wasm b/lib/wasm2cretonne-util/testsuite/func_ptrs.wast.8.wasm new file mode 100644 index 0000000000000000000000000000000000000000..6826a72c9a9b70f8386c5c97e819fac54ff1fbbd GIT binary patch literal 119 zcmW-X!3lsc5CnHGiKhkyJMe86>BQhSf}p;1#ZB2L`qyobmspE1uIY~Vj*7ze2U literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/get_local.wast.0.wasm b/lib/wasm2cretonne-util/testsuite/get_local.wast.0.wasm new file mode 100644 index 0000000000000000000000000000000000000000..cb39060eec6acd4b843df6af0c1fe6b13dc35b31 GIT binary patch literal 398 zcmZXQO-chn5QVGyZ#q5T0eV%lHyf2~4gTysLK-tdAcG;gQ0VEtfF}qj9>JY5xtwKY z78xvf{iv@WMNtr*8Uz5GxdmWmC05Id3(O2KF~OD*MrJy-F=rSYqbwbukV>1vPKtMQ zC(o~&db)nR59{gb{0v|OW*30R;DHlj1UMmkunF7H9A>By;DkN~e>2PoaH4RBJ(|@^ zy#%Yaby&j0eV{XlnV@7#y|ukXHU6-NRa literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/i32.wast.0.wasm b/lib/wasm2cretonne-util/testsuite/i32.wast.0.wasm new file mode 100644 index 0000000000000000000000000000000000000000..b516c4dfd026fdb00acb7ef688f4de8d712f7141 GIT binary patch literal 482 zcmYk#Sx&<+6a~=hAq_NTo`<4trp&_Y>2hVP0?lwW3SB`b1iUcOk`7b3R{*2+agjuc0|8}gRCBOl2p@}7JkpUIct2Yww&umAu6 literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/i64.wast.0.wasm b/lib/wasm2cretonne-util/testsuite/i64.wast.0.wasm new file mode 100644 index 0000000000000000000000000000000000000000..1eeba31df4f1fef71760d620e7cb503a1e0479c9 GIT binary patch literal 493 zcmYk#XHLUF5C!13#WBS67Ftk_L~nnHv8@EjC9%B-4A}H`FAl;@*j+}5`SCuD-f9Pa zkuU(PBm2CrS>0z8jollu)z$U?VT^I{H|`hf3O@`1QK)k;k*FBl2`?_s3J9x$bn+@_~FLpU7wOg?uI7$anIC{PY}s_u6J<^Ty^j^*iJ)xkv7kN8~YiKpv7OWyT5QX1RVq|ON)cI)(bQ5P?_zoh99-uuyVL4$^BeG*ia)BTSm}BHPIZPKl zKo8Iv%68f;Dngt$-y4odLa5p$0igGG2FxhvOJQb$&Y+Nt3Xn00j?|d!iP-w(y1N4n z+QsU6Q&$a)U2f`bf#hK2+sFwG#)#?)VNYH%o4?B1xtdk}Cs_adHW z)(x0HMr#Zm(YG%;sC0u!+>rUJ)`khCyYeJgCh_el>Cws#rt*wCN}Bo zHUtf_Fp^DscW-SzYU_*Hzgzb;XXH3C97k}yOIhbxY4>sb!Ax@UUs+zB^(N5QTS4%v cb5%b+I<&~(ttEpRo+W-In literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/imports.wast.1.wasm b/lib/wasm2cretonne-util/testsuite/imports.wast.1.wasm new file mode 100644 index 0000000000000000000000000000000000000000..44cafbbedabac1176c00766de3706f929aea1828 GIT binary patch literal 346 zcmaiwF^a-q5QX2HKQW16Ar|((orM;<%a*HAD^C#-1qCIT*u}Uf5zk=ftvrIGcCm2a z4R1ak%rKZ`8v>y95+0GTR2@_W5;>}oLLEz%a$?|T>0+KQvfNE~t8ET^1X4|yDsZa6 zt%A2L#(CWEwcKy#-PP|;_fH#Y#t7)ROex|u#e1Ik-AC|p8mR|95hE0udLkY2U~y^D zB7#NC^%!W6B1h*3t64^(91S4sk%cn)V_*OPdwB>- literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/imports.wast.11.wasm b/lib/wasm2cretonne-util/testsuite/imports.wast.11.wasm new file mode 100644 index 0000000000000000000000000000000000000000..fd7a0a7965454fdd097633ff377774d493866c97 GIT binary patch literal 30 lcmZQbEY4+QU|?WmWlUhKXJF!GWGP84E@4S4%}Zur002zT1+D-9 literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/imports.wast.12.wasm b/lib/wasm2cretonne-util/testsuite/imports.wast.12.wasm new file mode 100644 index 0000000000000000000000000000000000000000..a67a230aa16745f38fb0f7f2428c613055117a60 GIT binary patch literal 30 lcmZQbEY4+QU|?WmWlUgTtY_k7WGP84E@4S4%}Zur002x-1+D-9 literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/imports.wast.13.wasm b/lib/wasm2cretonne-util/testsuite/imports.wast.13.wasm new file mode 100644 index 0000000000000000000000000000000000000000..fc0333420aacbab37436d83f2756ed050877fc85 GIT binary patch literal 31 mcmZQbEY4+QU|?WmV@zPIXRK%9Wn?KyEiPe6E6q!0U;qGD5e6>+ literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/imports.wast.14.wasm b/lib/wasm2cretonne-util/testsuite/imports.wast.14.wasm new file mode 100644 index 0000000000000000000000000000000000000000..1b10aa7138f035af20a3a4c72622f34ef80a3275 GIT binary patch literal 33 ocmZQbEY4+QU|?WmVN76PU=n0xDM>9Z;YcgZOV-UaHez4^09-Z(FaQ7m literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/imports.wast.15.wasm b/lib/wasm2cretonne-util/testsuite/imports.wast.15.wasm new file mode 100644 index 0000000000000000000000000000000000000000..1d576d9bd1add2f661601ae960c53700431b5fac GIT binary patch literal 34 pcmZQbEY4+QU|?WmWlUgTtY;ErWGP84F5yTk%}dtJG&W*j003wC2C)DD literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/imports.wast.16.wasm b/lib/wasm2cretonne-util/testsuite/imports.wast.16.wasm new file mode 100644 index 0000000000000000000000000000000000000000..01e697f21c789b5ad41f9f1a5e8746880ee446e4 GIT binary patch literal 34 pcmZQbEY4+QU|?WmWlUhKWndCyWGP84F5yTk%}dtJG&W*j003xD2Co1B literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/imports.wast.17.wasm b/lib/wasm2cretonne-util/testsuite/imports.wast.17.wasm new file mode 100644 index 0000000000000000000000000000000000000000..885d5bd9b212d3be421a93ee19cfafd1cc906e3b GIT binary patch literal 34 pcmZQbEY4+QU|?WmWlUhKV_*_wWGP84F5yTk%}dtJG&W*j003xY2Cx7C literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/imports.wast.18.wasm b/lib/wasm2cretonne-util/testsuite/imports.wast.18.wasm new file mode 100644 index 0000000000000000000000000000000000000000..d6647f6b58fb03298663a7aaf7400a06012d302e GIT binary patch literal 35 qcmZQbEY4+QU|?WmV@zPIXRK!uWMnBxEiU0mE6q#R%``S*U;qGgz6UY@ literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/imports.wast.19.wasm b/lib/wasm2cretonne-util/testsuite/imports.wast.19.wasm new file mode 100644 index 0000000000000000000000000000000000000000..55f8407e748c00be75fd9fac9ad0fa72f7e9040b GIT binary patch literal 34 pcmZQbEY4+QU|?WmVN76PU=m_vDM>9Z;Y=&dOV+i^G&W*j003hv259ZVM!~^OJ-mI078)kEdT%j literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/imports.wast.20.wasm b/lib/wasm2cretonne-util/testsuite/imports.wast.20.wasm new file mode 100644 index 0000000000000000000000000000000000000000..83d154c9d5f4ad28dadd5d347acab6c7b335f957 GIT binary patch literal 35 qcmZQbEY4+QU|?WmWlUhKXJ8UyWGP84F5yfo%}ds`%QQA(U;qGb?*{Pz literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/imports.wast.21.wasm b/lib/wasm2cretonne-util/testsuite/imports.wast.21.wasm new file mode 100644 index 0000000000000000000000000000000000000000..6072362cc60810f621a72d931330c0638da21012 GIT binary patch literal 35 qcmZQbEY4+QU|?WmWlUgTtYs2nWGP84F5yfo%}ds`%QQA(U;qGbMF#Hx literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/imports.wast.22.wasm b/lib/wasm2cretonne-util/testsuite/imports.wast.22.wasm new file mode 100644 index 0000000000000000000000000000000000000000..dd6531f10bf2356143f91e3ecb4f80f411be7b68 GIT binary patch literal 35 qcmZQbEY4+QU|?WmWlUgTtYZ>lWGP84F5yfo%}ds`%QQA(U;qGbS_bd{ literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/imports.wast.23.wasm b/lib/wasm2cretonne-util/testsuite/imports.wast.23.wasm new file mode 100644 index 0000000000000000000000000000000000000000..1104039dad71f1c3b81535ffcb3afdc81f56860c GIT binary patch literal 36 rcmZQbEY4+QU|?WmV@zPIXRK!uVq_^vEiU0qE6q#RwaYX%VqgFOe69Z;Y};eOV-UaHqx~N5)2Fgf(Hk4 literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/imports.wast.25.wasm b/lib/wasm2cretonne-util/testsuite/imports.wast.25.wasm new file mode 100644 index 0000000000000000000000000000000000000000..76bf13a6c0d60d90589926418439114bf3fd5c79 GIT binary patch literal 39 scmZQbEY4+QU|?WmWlUhKXJ8UzWGP84F5yip%}dtJG&a(;0}>1j0FciI^Z)<= literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/imports.wast.26.wasm b/lib/wasm2cretonne-util/testsuite/imports.wast.26.wasm new file mode 100644 index 0000000000000000000000000000000000000000..dd4e01d42dc6b7ba83158344d15147ba43793075 GIT binary patch literal 39 scmZQbEY4+QU|?WmWlUgTtY;EqWGP84F5yip%}dtJG&a(;0}>1j0FX}y^Z)<= literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/imports.wast.27.wasm b/lib/wasm2cretonne-util/testsuite/imports.wast.27.wasm new file mode 100644 index 0000000000000000000000000000000000000000..23488f40a8777ed2f66246c8442492c5bd883ad7 GIT binary patch literal 36 rcmZQbEY4+QU|?WmWlUgTtY;EtWGP84F5ybg$xlkm(akhAVqgFOc})j; literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/imports.wast.28.wasm b/lib/wasm2cretonne-util/testsuite/imports.wast.28.wasm new file mode 100644 index 0000000000000000000000000000000000000000..7b046aaa672cbefe0c15a68e8625c10c657da97c GIT binary patch literal 37 scmZQbEY4+QU|?WmVN76PU=n3yDM>9Z;VDT>%1PBVG|9Z;mJ+S%`d9dHPX$@OJiUF0Dh|n^8f$< literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/imports.wast.3.wasm b/lib/wasm2cretonne-util/testsuite/imports.wast.3.wasm new file mode 100644 index 0000000000000000000000000000000000000000..8d7f4e4af60e1c7e48f1e97a45a4f29fa69a22cd GIT binary patch literal 34 pcmZQbEY4+QU|?WmWlUhKXJ8U!WGP84F5yTk%}dtJG&W*j003xt2C)DD literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/imports.wast.30.wasm b/lib/wasm2cretonne-util/testsuite/imports.wast.30.wasm new file mode 100644 index 0000000000000000000000000000000000000000..c2c821468ffd90d7101995e9d8029c6cbe2232b9 GIT binary patch literal 35 qcmZQbEY4+QU|?WmVN76PU=n8JC@x4%E=eseVN1`+PfE;TU;qGdI|r!% literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/imports.wast.31.wasm b/lib/wasm2cretonne-util/testsuite/imports.wast.31.wasm new file mode 100644 index 0000000000000000000000000000000000000000..638e1684612483b20fdefc62d40e5ef91b8980bb GIT binary patch literal 34 pcmZQbEY4+QU|?WmVN76PU=m{FC@x4%E=eseVJ%5a%1LEl003yK2R;A* literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/imports.wast.32.wasm b/lib/wasm2cretonne-util/testsuite/imports.wast.32.wasm new file mode 100644 index 0000000000000000000000000000000000000000..89bfb0a9bf051d5f46c2f51a202f0e05c2c82587 GIT binary patch literal 35 qcmZQbEY4+QU|?WmVN76PU=n8JC@x4%E=eseVarX;%`d8CU;qGd+6U19 literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/imports.wast.33.wasm b/lib/wasm2cretonne-util/testsuite/imports.wast.33.wasm new file mode 100644 index 0000000000000000000000000000000000000000..ab0911f6fab0c527cd2f10db7105923b999ccb2b GIT binary patch literal 197 zcmZQbEY4+QU|?WmWlUgTtY<1_<0vjjO)g0-E@4a0$xlkmVXkMOo=`2OSv3sItSmqm wFt97Ku%@S$=o&CEfN4XZqd@!$1|~3F$-vAd%EH2+%)kvK7(oORh+yUh0H--IaR2}S literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/imports.wast.34.wasm b/lib/wasm2cretonne-util/testsuite/imports.wast.34.wasm new file mode 100644 index 0000000000000000000000000000000000000000..e382fa9b0f2745e97c381fa9539448e6ec2ea48e GIT binary patch literal 30 lcmZQbEY4+QU|?VpVPq*uEiU0o&&f|p%+bv>He#-4003hN2NnPT literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/imports.wast.35.wasm b/lib/wasm2cretonne-util/testsuite/imports.wast.35.wasm new file mode 100644 index 0000000000000000000000000000000000000000..bf0e2b1528426308e7d2489f93b8582bc75e70d9 GIT binary patch literal 30 lcmZQbEY4+QU|?VpVPq*uEiU0o&&f|p%+XCVHe#-2003h12N3`O literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/imports.wast.36.wasm b/lib/wasm2cretonne-util/testsuite/imports.wast.36.wasm new file mode 100644 index 0000000000000000000000000000000000000000..0bd2ff71c43675c84e39506d9609badf07f148f2 GIT binary patch literal 27 icmZQbEY4+QU|?VpWMnBxEiPd%&CAZqFVADHX8-_Cga)(# literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/imports.wast.37.wasm b/lib/wasm2cretonne-util/testsuite/imports.wast.37.wasm new file mode 100644 index 0000000000000000000000000000000000000000..82f7f25d0a18a808734d6cb9bc5c90bfeac375a8 GIT binary patch literal 31 mcmZQbEY4+QU|?VpW#lL>NKGzDEiPd%&CAZqFVADHX8-_l<_Kp1 literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/imports.wast.38.wasm b/lib/wasm2cretonne-util/testsuite/imports.wast.38.wasm new file mode 100644 index 0000000000000000000000000000000000000000..cd5a9c959feddc8557c46be05143a99523e5b973 GIT binary patch literal 24 fcmZQbEY4+QU|?Y4V`M2wEiPe6E6q!0u4e!MIiv+j literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/imports.wast.39.wasm b/lib/wasm2cretonne-util/testsuite/imports.wast.39.wasm new file mode 100644 index 0000000000000000000000000000000000000000..4760358307c087d21a858807389bd4a940a44486 GIT binary patch literal 32 ncmZQbEY4+QU|?VpV`M2wEiU0HNleN~)ipHG&CE+ literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/imports.wast.44.wasm b/lib/wasm2cretonne-util/testsuite/imports.wast.44.wasm new file mode 100644 index 0000000000000000000000000000000000000000..27aa8136efeeb19e8dc618b28e6161c149418c86 GIT binary patch literal 90 zcmWm4I}Ua>Isz=*uc_^G`LHvtJ9CM3{vb+wsl5ZgllbSi)&aB!%Dw$+?^Zhh+U hE}4~X*G7MHwlpc00xXvB6h-AWJ>$X(h=G@%Q(oC%4Eq28 literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/imports.wast.45.wasm b/lib/wasm2cretonne-util/testsuite/imports.wast.45.wasm new file mode 100644 index 0000000000000000000000000000000000000000..27aa8136efeeb19e8dc618b28e6161c149418c86 GIT binary patch literal 90 zcmWm4I}Ua>Isz=*uc_^G`LHvtJ9CM3{vb+wsl5ZgllbSi)&aB!%Dw$+?^Zhh+U hE}4~X*G7MHwlpc00xXvB6h-AWJ>$X(h=G@%Q(oC%4Eq28 literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/imports.wast.49.wasm b/lib/wasm2cretonne-util/testsuite/imports.wast.49.wasm new file mode 100644 index 0000000000000000000000000000000000000000..3cf0083692a28d5522187d3c699aae1a5b04acb7 GIT binary patch literal 33 ocmZQbEY4+QU|?VpXJjc!EiU0HNleN~)ipHG&CE+NKGzDEiPd#NleN~Wh`Li5&-~iod;_G literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/imports.wast.56.wasm b/lib/wasm2cretonne-util/testsuite/imports.wast.56.wasm new file mode 100644 index 0000000000000000000000000000000000000000..2a6b158a1aa9910060f48a85ce6a1aabc00882a2 GIT binary patch literal 31 mcmZQbEY4+QU|?VpW#lL>NKGzDEiPd#NleN~Wh`K16#)QllLux1 literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/imports.wast.57.wasm b/lib/wasm2cretonne-util/testsuite/imports.wast.57.wasm new file mode 100644 index 0000000000000000000000000000000000000000..a098343f396baf0c4502176a215b7ab483661c99 GIT binary patch literal 31 mcmZQbEY4+QU|?VpW#lL>NKGzDEiPd#NleN~Wh`K15CH&gi3ec- literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/imports.wast.58.wasm b/lib/wasm2cretonne-util/testsuite/imports.wast.58.wasm new file mode 100644 index 0000000000000000000000000000000000000000..bf2cd933c84051f581046235381f96caf1df49fa GIT binary patch literal 31 mcmZQbEY4+QU|?VpW#lL>NKGzDEiPd#NleN~Wh`Lik^}&5q6csQ literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/imports.wast.59.wasm b/lib/wasm2cretonne-util/testsuite/imports.wast.59.wasm new file mode 100644 index 0000000000000000000000000000000000000000..60cf1991dd29d3738e98402af8ece66d804efef0 GIT binary patch literal 31 mcmZQbEY4+QU|?VpW#lL>NKGzDEiPd#NleN~Wh`K1l>`88mNKGzDEiPd#NleN~Wh`Li;s*e3mHexJb-~s?@3I`AX literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/imports.wast.68.wasm b/lib/wasm2cretonne-util/testsuite/imports.wast.68.wasm new file mode 100644 index 0000000000000000000000000000000000000000..5101c52d66b73fbcad66e1df54196070ba292079 GIT binary patch literal 33 ocmZQbEY4+QU|?VpXJjc!EiU27P0h_Os?;^o&CE+^*2z3Ae literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/imports.wast.70.wasm b/lib/wasm2cretonne-util/testsuite/imports.wast.70.wasm new file mode 100644 index 0000000000000000000000000000000000000000..551315ad8233d4773f0b20536f93da678981879c GIT binary patch literal 73 zcmV~$F%Ezr5Cp*8({RW&Hujc&!=Ff$PJ$5{E57awV$B3V$Ag_+7W(?6v!&WxPPx3F YkTM9Np5tBO1%!!;6`R0Ji9HzSAO8gle*gdg literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/imports.wast.71.wasm b/lib/wasm2cretonne-util/testsuite/imports.wast.71.wasm new file mode 100644 index 0000000000000000000000000000000000000000..551315ad8233d4773f0b20536f93da678981879c GIT binary patch literal 73 zcmV~$F%Ezr5Cp*8({RW&Hujc&!=Ff$PJ$5{E57awV$B3V$Ag_+7W(?6v!&WxPPx3F YkTM9Np5tBO1%!!;6`R0Ji9HzSAO8gle*gdg literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/imports.wast.75.wasm b/lib/wasm2cretonne-util/testsuite/imports.wast.75.wasm new file mode 100644 index 0000000000000000000000000000000000000000..01e7c8deb2f995231c3aa6283127e235e6ea3355 GIT binary patch literal 32 ncmZQbEY4+QU|?VpV`M2wEiU27P0h_Os?;^o&CE+^^2z>wm literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/imports.wast.80.wasm b/lib/wasm2cretonne-util/testsuite/imports.wast.80.wasm new file mode 100644 index 0000000000000000000000000000000000000000..9c81a86595df6f746cb8e5632cb0e2d3d085f435 GIT binary patch literal 31 mcmZQbEY4+QU|?VpW#lL>NKGzDEiPfpP0h_Os$^nhWC8$hy$5pu literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/imports.wast.81.wasm b/lib/wasm2cretonne-util/testsuite/imports.wast.81.wasm new file mode 100644 index 0000000000000000000000000000000000000000..4d0cb1a9d4f6d472673254295726db393750765c GIT binary patch literal 31 mcmZQbEY4+QU|?VpW#lL>NKGzDEiPfpP0h_Os$^nhU;+Sdy9aUr literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/imports.wast.82.wasm b/lib/wasm2cretonne-util/testsuite/imports.wast.82.wasm new file mode 100644 index 0000000000000000000000000000000000000000..0fd00827c512650270b5f27d82b75f68de954576 GIT binary patch literal 31 mcmZQbEY4+QU|?VpW#lL>NKGzDEiPfpP0h_Os$^nhWCj3lz6W#w literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/imports.wast.83.wasm b/lib/wasm2cretonne-util/testsuite/imports.wast.83.wasm new file mode 100644 index 0000000000000000000000000000000000000000..1d55b9bcff678d277efb014e255330b94424c0a2 GIT binary patch literal 31 mcmZQbEY4+QU|?VpW#lL>NKGzDEiPfpP0h_Os$^nhUNKGzDEiPd%&CAZqFVACQU<3eh<_G8i literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/imports.wast.86.wasm b/lib/wasm2cretonne-util/testsuite/imports.wast.86.wasm new file mode 100644 index 0000000000000000000000000000000000000000..969740f29a7ac7551c10d5d4ded6f25529495c7d GIT binary patch literal 32 ncmZQbEY4+QU|?VpV`M2wEiU27P0h_Os?;^o&CE+NKGzDEiPfpP0h_Os$^nhWCQ?jya#ds literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/imports.wast.9.wasm b/lib/wasm2cretonne-util/testsuite/imports.wast.9.wasm new file mode 100644 index 0000000000000000000000000000000000000000..2a48ca29583ce4245deac137896095a7dabf0eb9 GIT binary patch literal 32 ncmZQbEY4+QU|?WmVN76PU=m9ZVK2?g&dV>)V_*OPST+Wi literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/imports.wast.90.wasm b/lib/wasm2cretonne-util/testsuite/imports.wast.90.wasm new file mode 100644 index 0000000000000000000000000000000000000000..3c7cc625f820e7439e60f04b0bdba1df8f3aca80 GIT binary patch literal 28 jcmZQbEY4+QU|?VpVq_^vEiU0mE6q#R%``S*VqgRSQMd)p literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/imports.wast.91.wasm b/lib/wasm2cretonne-util/testsuite/imports.wast.91.wasm new file mode 100644 index 0000000000000000000000000000000000000000..788006a408489e88f485b7c8d743b9e72079b219 GIT binary patch literal 30 lcmZQbEY4+QU|?VpVPq*uEiU0o&&f|p%+bv>HezC61OQ?Q2A2Q; literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/imports.wast.92.wasm b/lib/wasm2cretonne-util/testsuite/imports.wast.92.wasm new file mode 100644 index 0000000000000000000000000000000000000000..de0a76f947b68ec70adc83506da19e0000008388 GIT binary patch literal 32 ncmZQbEY4+QU|?VpV`M2wEiU0HNleN~)ipHG&CE+NKGzDEiPfpP0h_Os$^nhWCQ?jya#ds literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/imports.wast.98.wasm b/lib/wasm2cretonne-util/testsuite/imports.wast.98.wasm new file mode 100644 index 0000000000000000000000000000000000000000..2b92957d10272188d5e24a0fec80601105bd46f1 GIT binary patch literal 63 zcmZQbEY4+QU|?WmV@zPIXRK!uW#lL>NKGzDEiPfpP0h_Os$^nhU}gpq>>P|N=|%bF Q3=CWxjBE@F3=Rz30FY-3H~;_u literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/int_exprs.wast.0.wasm b/lib/wasm2cretonne-util/testsuite/int_exprs.wast.0.wasm new file mode 100644 index 0000000000000000000000000000000000000000..363ee730eb2b0ab82a57cc9898c4a75ef186f1ea GIT binary patch literal 200 zcmZQbEY4+QU|?Y6WlCVGuV<`JV5+NQtY>Cr0g5rQ=dws-8XM{5<;SPx=cL3Z=N7~l z$LFV|6{nUkFkncP!lW1_GR;h|>te!?g6m@DvSi_9P+)Lm%u-+k5+2;hJWnvsiLpk3 L5l951@Itr&c|$X5 literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/int_exprs.wast.1.wasm b/lib/wasm2cretonne-util/testsuite/int_exprs.wast.1.wasm new file mode 100644 index 0000000000000000000000000000000000000000..b764f351817e745ea824fab5357307d72e14adfd GIT binary patch literal 61 zcmZQbEY4+QU|?WmV@zPIW2|FlVq{>KWt7Y`GttY-k59|bNr^8nN-T&^ttd&&ONlRL QVBq3lWMfcZSiXiE0Eo~IH~;_u literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/int_exprs.wast.10.wasm b/lib/wasm2cretonne-util/testsuite/int_exprs.wast.10.wasm new file mode 100644 index 0000000000000000000000000000000000000000..f83f6b8d3dc83049e3eca9413401db0840036534 GIT binary patch literal 92 zcmZQbEY4+QU|?Y6W=deJXRJ?PtYfTWW@chwWY=X9&NMdC%gc{X%g;%PFG|ggFOD~2 dU=YqUGr7`_r#TUmLFfhP*r9d7d lccz&MT#gCO1IaOSDYCFLC@?rO7`_r#TUmLGcdq;r9d7d lccz&MT#gCO1IaOSDYCFLC@?rO=W;{nJTUFVTo0uixB<+o7Z3md literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/int_exprs.wast.13.wasm b/lib/wasm2cretonne-util/testsuite/int_exprs.wast.13.wasm new file mode 100644 index 0000000000000000000000000000000000000000..d07ab17528f51e82e866397d33ae788e7a181671 GIT binary patch literal 122 zcmZQbEY4+QU|?Y6W=deJXRJ?PtYfTWW@Q12FtS^+aAz7D>7`_r#TUn$GBCh-r9d7d lccz&MT#gCO1IaOSDYCFLC@?s(=5j;mJTUFVS`VcgxB<@l7a#xt literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/int_exprs.wast.14.wasm b/lib/wasm2cretonne-util/testsuite/int_exprs.wast.14.wasm new file mode 100644 index 0000000000000000000000000000000000000000..0df895aa46346078cd4cb1b97eeea8f852361968 GIT binary patch literal 122 zcmZQbEY4+QU|?Y6W=deJXRJ?PtYfTWW@Q12FtS^+aAz7D>7`_r#TUn$Gcdq;r9d7d lccz&MT#gCO1IaOSDYCFLC@?s(=W;{nJTUFVUJs=kxB<~i7cc+- literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/int_exprs.wast.15.wasm b/lib/wasm2cretonne-util/testsuite/int_exprs.wast.15.wasm new file mode 100644 index 0000000000000000000000000000000000000000..ef7d53fd6c88d06bd86138988d0d25865cc62302 GIT binary patch literal 122 zcmZQbEY4+QU|?Y6W=deJXRJ?PtYfTWW@Q12FtS^+aAz7D=@q5s#uvvMGcdq;r9d7d lccz&MT#gCO1IaOSDYCFLC@?rO=W|2o0x<2w+z6$cxBKWt7Y`GttY-k59|bNr^8nN-T&^ttd&&ONlRK QVBq3lWMfcZSiY7U0Ep}kI{*Lx literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/int_exprs.wast.3.wasm b/lib/wasm2cretonne-util/testsuite/int_exprs.wast.3.wasm new file mode 100644 index 0000000000000000000000000000000000000000..df82315c1faba269feb56bc4b0444aeae4d1c4d5 GIT binary patch literal 174 zcmZQbEY4+QU|?Y6W=deJXRJ?PtYfTWW@Q12FtR7Ih-Mla>E-3er{(9Q#207e0C7=# zF#`iu@lpmx(M&TFEb5uCikC7lbLp~hF(@!NGL|?pmU6?HWniWgW1ACWJA&E44FHB^ BECv7o literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/int_exprs.wast.4.wasm b/lib/wasm2cretonne-util/testsuite/int_exprs.wast.4.wasm new file mode 100644 index 0000000000000000000000000000000000000000..0ac75120194976576a507dd4230f36629da528cd GIT binary patch literal 174 zcmZQbEY4+QU|?Y6W=deJXRJ?PtYfTWW@Q12FtR7Ih-Mla>E-3er{(9Q#2052#TNs~ z90mpq@lvojqiCj?2^RHC7~&B1%v`!GTnq{fj*O*_j3wL#Mth{*ajALV(b7h E0fyHs1^@s6 literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/int_exprs.wast.5.wasm b/lib/wasm2cretonne-util/testsuite/int_exprs.wast.5.wasm new file mode 100644 index 0000000000000000000000000000000000000000..8321359ba15df4ee42556a92f9ced07e4a9cf69d GIT binary patch literal 174 zcmZQbEY4+QU|?Y6W=deJXRJ?PtYfTWW@Q12FtR7Ih-Mla>E-3er{(9Q#HVDI#TUot zmgX=pV2GE3#Ti92%}lVUXTlJNsAuNVW#M8_U~pv1b!5xohA{JBOeeN_C$>7Us1sWQ GhzS6Hw=3cR literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/int_exprs.wast.6.wasm b/lib/wasm2cretonne-util/testsuite/int_exprs.wast.6.wasm new file mode 100644 index 0000000000000000000000000000000000000000..d29c13d5157703ae2f8c89c8c37be38efaa497c5 GIT binary patch literal 166 zcmZQbEY4+QU|?Y6W=deJXRJ?PtYfTWW@Q12FtVqzh-DfZ>E-3er{(9Q#HVDI#TUmH ur{<(FFkncOLL?Z)GR;h|>0rW;fa+l8QeE-3er{(9Q#22OJ#uvvI ur{<(FFkncOLL?Z)GR;h|>0rW;fa+l8QeE-3er{(9Q#OIdg#HVDI z#TPR$U==TAU=+&voS6q^IReDmJSP*`Syh=ew}Cb8o8I6iUtqZ=`d@;-9aZS!KSE!BC5iaR7dhUFOx+c&x3g! zB^iHfSi4Q@GLQ=CYI1ei)-wQ6&jdst%ajX!z3EorJ~ouT-T`P|Z`R+T-k}AXzTS}| z`A$6tYeT(b{ad&idC#wJYqE_Ac`Mss{>!5PJvB|U1Y+5h0 z`YZub1SPh#GyCT4%-fy8)#i%;klbBDx=ZP#OHRf_5Mf*F+xsqKKU+1|p8>yWny+V& zXs2+|o+F9&0%^2w;a$Bzmeh+W_Oi`gy}iE0C~N22Z|xfU*{uCoFWw;Uoik|fOi}dC zIS$;c#o_+u_Ufj&tJj}!RJ8M(`J!Ie+qzlfIDhbCh3kS82vB_~(gjS2BwdLh%L!=w zyR<4%I4wxgizhjSDA}Wdy-N@e{Uvc}i6ciQ5{pa8;#^9+XK@*d=SV14sZ8%>5K;w6 zD_-D-pTHED>|Y=s9y=pX#%Fx0meF-|)!AI6^muopoN_zjHsZ%SoP5K}eyh(I z?PrXQV~7pZ=cbr#+uUo_w!g|VUFijB|Y@^$# Po^WG{D4mZ0U8?>B1TBno literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/left-to-right.wast.0.wasm b/lib/wasm2cretonne-util/testsuite/left-to-right.wast.0.wasm new file mode 100644 index 0000000000000000000000000000000000000000..29a2475c866eaacfd301d1d169b28e01f679cce5 GIT binary patch literal 3015 zcmcJQS63TX5Xa|ATJ1_J$nJ4Di8<-TPH_^0gK@=+9rqIVZq*gYmIO#zf)f>to${Ri znEv2TmyeK{xm!kl$Xj&a^8d}wotgW;3qZNsQUIWiPLxukks6g!!y&DM0j>Q$t^g&V zA8Lr-1N`n&Do`dag8?r6KBS+jO{}C;DwR%WG6sLL*{orhrfC?KWf?{;Zx{4~|830} zYDHnMv;t*5vx;V8X1Z9e)!AI7>1AMqxC6+ULs_F<1jWtu(gGp(hM zawdufus4bZ@CnOB%AM7ca`#2i0Oq1-0Q+^<-g3u>19|GvB|QfR?HKmV!Xe&KEjOER z*rf*~i;Z@z(ebN2IHGs@O@eu|F}s(YJj#lk^jMLT3pskKojexn0FJZPPJSBe08Z#? z=;X;P?L_}hafqBets9_|XLyTt@@%ZTaE>>jljm8WlNT&1!%kk*lHB<$iUx2giUx3* zB|CXVOUk_(MFY4NMFY65yRwrv^3)@A@}?aFI(aLhnQ6Gq``On!E~Sn8dRN!czTPwI zXgs~4_gRszMONf%i52<^OAGncB1|Q}* zRS!NgDxG4Z4jals(JNP)K0H>rNd+F*7N}G@V`Rm&-g?ZfjERIF+N19R{gn82o2G z3R2l5C`)IbD~-m*Uj=Y1$94)2b~yO&C4`3(ni5(P+7gx}tVmdu(2>xU(37wxA&_uF z!bu6IB%G6QTEck=XCz#Za8|-a0<@H^!WUH#x-RITB8q%;UPZvyfVVl5E&$b;i~=uA z#XTIy?MoO)7)lsP*pTp8!lr~L5}r!pUZc4Z&;g*E! z5^fWOH{k9|3(ws{@&??)d;?MD5xy(F546~MExHeaEv`!Lg92NV``G4e|1NHi@V$f| zB>X7h7YTPH+?8-oLQ%qf2_*?XN%)x{JmdDc#gGxcj+ z6yY}szf1T-!rv0g5-Jj^5_}0Y33Um7O8AQ)Jmb`UzHz=soYZ+EIwQf$ZaO(51zzDZ dZh_QD|K@qHI>8zCHjZH&|Kd$51vd4t{{_&4-24Cl literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/linking.wast.0.wasm b/lib/wasm2cretonne-util/testsuite/linking.wast.0.wasm new file mode 100644 index 0000000000000000000000000000000000000000..f9137a286a8e2a6913d63985e87228f3d64069ec GIT binary patch literal 43 ycmZQbEY4+QU|?WmWlUgTtY>CsVqjqBU}Q;7%*kP3;NoUtVGv;CW?^t-;syY4w*+ed literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/linking.wast.1.wasm b/lib/wasm2cretonne-util/testsuite/linking.wast.1.wasm new file mode 100644 index 0000000000000000000000000000000000000000..8d2a6f57629d0d977b4f751c574c99da9ee4bfe1 GIT binary patch literal 87 zcmZQbEY4+QU|?WmWlUgTtY_k8Wb#d8NlwhkVPIfpVFt>uD>AeDrs+Y1ctDf_jLQg7 V$iyYU%)%hRzzrmrfrKM7HvoX24c`C& literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/linking.wast.15.wasm b/lib/wasm2cretonne-util/testsuite/linking.wast.15.wasm new file mode 100644 index 0000000000000000000000000000000000000000..4616241323dd4671fbf3fdb250f17e304e00a2f4 GIT binary patch literal 71 zcmV~$%ME}a6h*;vA3uS_Sb_~ugq=vDJBbSmpmk^H-w>dvQ&ZEK2wqZ1tGRIx!#{7o UpkyU>8q~Upqtt@T`4H2Re=Ohz-2eap literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/linking.wast.16.wasm b/lib/wasm2cretonne-util/testsuite/linking.wast.16.wasm new file mode 100644 index 0000000000000000000000000000000000000000..5d1cf1eb973c72f36eac9e966b0bae0f52352430 GIT binary patch literal 83 zcmZQbEY4+QU|?WmV@zPIXRK%9W@PfsWy#4;OkrSPW@2PuWoBexWEWy$_s!LVh(aV8 exi}fw859_F85p>^c^DZSxwzRreEjtJ%U1vt$`B3! literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/linking.wast.17.wasm b/lib/wasm2cretonne-util/testsuite/linking.wast.17.wasm new file mode 100644 index 0000000000000000000000000000000000000000..f61d36722bbca02e2f012d85eaf4f53fa3ac4ddc GIT binary patch literal 70 zcmZQbEY4+QU|?WmV@zPIXRK%9W@PfsWzJ2_Wny4tW@2Pu=U`;X$xlpSVBq3pWM@!d a&}CrY=H_E$aAf7?Sg>%>;w4L$Ee8N(i41lC literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/linking.wast.2.wasm b/lib/wasm2cretonne-util/testsuite/linking.wast.2.wasm new file mode 100644 index 0000000000000000000000000000000000000000..2aba3e42d79a1fa9db9a9337f80e17ff6b4ef7d1 GIT binary patch literal 46 ucmZQbEY4+QU|?WmWlUhKXJ8UyCoWME@stY>i4;%4V#VoA@*Phw_ZPERdiVBlh7WMNQd G;06G$js|)F literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/linking.wast.6.wasm b/lib/wasm2cretonne-util/testsuite/linking.wast.6.wasm new file mode 100644 index 0000000000000000000000000000000000000000..7b2e142a3bf48779a10c6cbb3ebec580c9b87935 GIT binary patch literal 93 zcmZQbEY4+QU|?WmWlUgTtY;EsV)9LANzchoVy9JRUG g6T7jabW^NGNbrHMC e?5V5Jj(n@fLFl8%A^AUvvpLy+59$3b5N4Y(gK;2m;+++l*7EJg^J{ajrWaaCQ=h3Wkw0G_n~1#E?l zO?r`WwdYhTw#6A#Q;L{#p?kV(8rR2uK(`_PRezZsgBTDlBE;#YhQZ^2j0+-taV6pd DHX{;H literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/linking.wast.9.wasm b/lib/wasm2cretonne-util/testsuite/linking.wast.9.wasm new file mode 100644 index 0000000000000000000000000000000000000000..c881d376680b525a3a27db866688bc2586350cf9 GIT binary patch literal 82 zcmWN?%L#xm6h*;vU*azTL2STQEWjR&Zd^nV%s#E_Y=-pS0u*dVbyroj*=#Gi;LnwG d=%I1WP}j?!DQ9fx#j0o`jOJO}*s(A{`~d#y3KjqW literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/loop.wast.0.wasm b/lib/wasm2cretonne-util/testsuite/loop.wast.0.wasm new file mode 100644 index 0000000000000000000000000000000000000000..3e69bf667d73ea91a92e440003e0d04ca1df9229 GIT binary patch literal 1060 zcmcIi&yUhT6n<|8D9dZv0*h<*)E+z;l8y1c3`WnMJZLl&7zDSJrWDO4Tk6ron;ZQH z^$+n)Tbgk5V)-%O``-7x_hzOL>^2AhIA}}(rhxer4|tf0EW=D*3^;T02qCTC*l+4h zoZbPpckAfmJ`55N&CNbc*C1Pw-lcj0jmARj7@BUd8||YYxf^X`odnSWT0N#_>l4m8 zXD(%Dt!np~nQu37km#B`>&y}z+>T~ULWj!Wa}e$|P`8W{9qYghU{~pN6zK$<&U_oC zqcZ4Pdb!l|bO-0nFROK^!IjHx0zJzN&s&0i=UZzafZ8C(#9tx?NHSLz(PPFglpm%_ zpxQ)3khw{TF&V83>WrP=k!g|tj~{pVh1}xbpAOH$E{9gsE1@hWZBR&c@+Dn@%v^W@ zFy{T&=mS0H&B?KiHUN=<3LQK`=t7OLEBMXfj2aN12yb8Yjg3PxRVqRaY*ZHt9K7O% zYh9@!Gmn(1r7l%jMh)4tM9dZV;1y<(E3^gEpN$(kJW^T-dl_9K-u;8nRp0S}k2{Vb3VX-uCi^bx|MyCG&BO*r0D|&)>n4piw=D}-+ z1s)!JUM85a!3dF_q9{}o;fq2kJb1%e^n}rh3Eumn(!NEJmDTvp0Nxqd(N!~|K<^#t cNl*On`OgsJhpLM7;3t#j*1z67RAWf`3l;vdZ~y=R literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/memory.wast.0.wasm b/lib/wasm2cretonne-util/testsuite/memory.wast.0.wasm new file mode 100644 index 0000000000000000000000000000000000000000..93b6da7662850205693eaed349c8fcfa08400f8f GIT binary patch literal 14 TcmZQbEY4+QU|?WnVFXeD4^aV5 literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/memory.wast.1.wasm b/lib/wasm2cretonne-util/testsuite/memory.wast.1.wasm new file mode 100644 index 0000000000000000000000000000000000000000..e47e0cf8d471811f2d7a9e1fb7d07ab015c58f72 GIT binary patch literal 14 VcmZQbEY4+QU|?WnVPs@r1ON|G0Z#w` literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/memory.wast.15.wasm b/lib/wasm2cretonne-util/testsuite/memory.wast.15.wasm new file mode 100644 index 0000000000000000000000000000000000000000..6591570f72fe0964d2a0dad182461854f82ab4f4 GIT binary patch literal 55 zcmWN;Ar62r5CFklXlcSditrN<6^K(c1jE;1hI6EV)dSyol3M(=uw~D2JssA?!bU`s Ho$&qux=RL# literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/memory.wast.2.wasm b/lib/wasm2cretonne-util/testsuite/memory.wast.2.wasm new file mode 100644 index 0000000000000000000000000000000000000000..64ffe0388be981dbeeed2b03985a55a4c5258356 GIT binary patch literal 15 WcmZQbEY4+QU|?WnWn^S*U;+RUssYjf literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/memory.wast.3.wasm b/lib/wasm2cretonne-util/testsuite/memory.wast.3.wasm new file mode 100644 index 0000000000000000000000000000000000000000..d3e64161468541fa78f435bd9d7243d4b0904fde GIT binary patch literal 16 XcmZQbEY4+QU|?WnV`OA#XkY;V6n_F# literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/memory.wast.39.wasm b/lib/wasm2cretonne-util/testsuite/memory.wast.39.wasm new file mode 100644 index 0000000000000000000000000000000000000000..77ba1f041e07a1a024c1751761567ebd9a3df91d GIT binary patch literal 33 kcmZQbEY4+QU|?WnVPs@v;ud6LaAe?SPE1M$(!aAf9YN=#yKWZ-5>Nd*8j+XI*Y literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/memory.wast.41.wasm b/lib/wasm2cretonne-util/testsuite/memory.wast.41.wasm new file mode 100644 index 0000000000000000000000000000000000000000..8b535ce73c7ddbdf4c65d9d79719bd8f860d4015 GIT binary patch literal 35 qcmZQbEY4+QU|?WnVPs@v;udCRaAe?SOk{9m;$}=@aAf3WOa=fyP6L7f literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/memory.wast.49.wasm b/lib/wasm2cretonne-util/testsuite/memory.wast.49.wasm new file mode 100644 index 0000000000000000000000000000000000000000..60ae51fd8b28e2ff62e4643a3c0d2a53343088b8 GIT binary patch literal 35 ocmZQbEY4+QU|?WmVN76PU}j=uU}XmKxwsfP7#taN85pFv0XSd+XaE2J literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/memory.wast.50.wasm b/lib/wasm2cretonne-util/testsuite/memory.wast.50.wasm new file mode 100644 index 0000000000000000000000000000000000000000..ebf4341625bc5ea73d0354b3216f92dc08625ba4 GIT binary patch literal 35 ocmZQbEY4+QU|?WmVN76PU}j=uU}XmKxwsfP7#tb&85yLw0XS{~YXATM literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/memory.wast.51.wasm b/lib/wasm2cretonne-util/testsuite/memory.wast.51.wasm new file mode 100644 index 0000000000000000000000000000000000000000..2da5f34088248d0ba151ae9abd7d25400957c3cc GIT binary patch literal 35 ocmZQbEY4+QU|?WmVN76PU}j=uU}XmKxwsfP7#tZim>8tE0XR8tE0XSI#X8-^I literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/memory.wast.6.wasm b/lib/wasm2cretonne-util/testsuite/memory.wast.6.wasm new file mode 100644 index 0000000000000000000000000000000000000000..f9528a2f711bce5020e44b08c6b80b77639a9cef GIT binary patch literal 23 ccmZQbEY4+QU|?WnVFUthc18wA25!bg03DA45dZ)H literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/memory.wast.62.wasm b/lib/wasm2cretonne-util/testsuite/memory.wast.62.wasm new file mode 100644 index 0000000000000000000000000000000000000000..b59b22057569e514dd964064f9baf55a87171c45 GIT binary patch literal 685 zcmZvZyH3ME6h!ClZk}tBf=EzqIwal!!W(%L1Qj$Cl*AB(A_6E1?hxirDDw%Fhyqbj z^Eq(WV9SxXlI1x&bH`d4!SIFv(4^{sB7Pn^6tSR3dX&|QvjmTfCnpJ1c%h2w2KNC_ z2>QLN+siJf6y7FUsEc5D52<@AjkEq;(A_v2LS-mK&P%-ICY$*zhA8M>b2Z&8W++6- zOT2iqoW&42MgH^#3wj3 z{TKQ!B&mUJlZ9V*|V>U_Gc!-LkAbX!m) z9{y{2;SOHk1Po^3I)tI~|2j5ci>;66XkD_Hm2mnsQ2svuz<8?KmReZnyHxG_6K%67 zaiy+s-e8NdI5&=b$v=0S*j=D8TugDt?JlL^7?)Grb-Rr;9OFugdxG6nku=A+#;9v- SK<8|$J=%w@X?1E(j(z})d~)^x literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/memory.wast.8.wasm b/lib/wasm2cretonne-util/testsuite/memory.wast.8.wasm new file mode 100644 index 0000000000000000000000000000000000000000..1d5ecb7b107e5c958b16aafbd1762b79b27fe6f4 GIT binary patch literal 35 qcmZQbEY4+QU|?WnVPs@v;udCRaAe?SOk{9m8cT^mfK;Uq-~*fyU*TP>6IjbT ztC`uc4BKxB03FF1s6hkYT}=ZG*{lGO$S9Y@HG3+`ci#o$Uwro#A2#hhu#CQsrjMcX zCI-_4>p;gN*?ITeI@`vH73Ih}Z{6faR%~t4ggeM`8jNi=wokeF!8aAB(0r~1w47i* z!Qlw%1p1H2Z}|iJ8#c}_1=Kl-VVqXbx!!ZVrjVqqs6s`L>WpZ|+h0E)pCV~$&Dwun b1tp;u>LTUHg=8UhUe#+hSER2JAiebq`u0Eo literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/memory_trap.wast.0.wasm b/lib/wasm2cretonne-util/testsuite/memory_trap.wast.0.wasm new file mode 100644 index 0000000000000000000000000000000000000000..7171e8856684b398d90b693a69d1c60d9ac2b6ec GIT binary patch literal 113 zcmXBIK?=e!6h+bZ{!f%P1zmx3C@#Qh?Mj-0MUaL-Do97aOSjb&3hnY7s ze(%}H%NYScdUQl;Qgc{wSaMj5jJgJc6^A8<1j!8hAZzH7B zB<_FA^D#iD=|Gf(7RohfpQ73p;ID!SU5--bq`kf*Yu;>GayN zg0E!~v(}(3D{Q!YYxy<*oM6-Cb40!6^7o5++vOh+^^T|SXV`5%&;(J6Jx{l1*l%8_ zqJy$+7ek$pbm>nz76FbV;hK v8@5Aunf7kAcgH4*^q$QU)r0mPwfDq&{bK_|_%wfc9Z!n4cMO03%(eUnNr-Y^ literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/names.wast.0.wasm b/lib/wasm2cretonne-util/testsuite/names.wast.0.wasm new file mode 100644 index 0000000000000000000000000000000000000000..6e34bb08ade7aa8df7fe1137d25695d04ab90f61 GIT binary patch literal 36 rcmZQbEY4+QU|?WmWlUgTtY>CoWMF4!WKPS^XJFuBV`O1)WZ(t>QX2#3 literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/names.wast.1.wasm b/lib/wasm2cretonne-util/testsuite/names.wast.1.wasm new file mode 100644 index 0000000000000000000000000000000000000000..c6ac4b4d26130d129c85309670546552139cb3cd GIT binary patch literal 36 rcmZQbEY4+QU|?WmWlUgTtY>CoWMF4!WKPS^XJFuBV`O1)WaI__QXK>6 literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/names.wast.2.wasm b/lib/wasm2cretonne-util/testsuite/names.wast.2.wasm new file mode 100644 index 0000000000000000000000000000000000000000..cadc3c568dff04cc449a02fb458449116f1a96cd GIT binary patch literal 7488 zcmeI#_kSDreaG=PaI`E-^4@mh$noB?<4h;9-JK41rX$Oi-8yya(KhKwGkhQc?s41` z1h~LWf*asE>9nPT_VSj#@|4F>lK1TA^KSc7AN>dVs2-1dzHrC;-hFYv9Vx8+$zve^ zq0>SSAoQg5v~}2$)&KwZfA9*N{_$#lxS=%&g>PAdaOi$mp{tP>x(BCS`Kv4Mx$5d` zest}P*WYmeO%L4it)Kt$7vKNk55DomyRQ4@x9`6B*4tKNnRVaV`*8a5?>zqSBac7w z)1P5^_>qTk#>t4SU z=UOH@i1Vyqr~v2ZJsb>0aDnyk!;j#?b7Xc_-f7EDUw+1lm8;G?>ug+f&N=6vcm4$z zUUcy#mtJ=H=RSYM7jSWS^^>?{wP$+~FW)QhqF&4^^oqPb(Z9(QERWy%w+4YxCk>yO+RamjrG)aK{37Ja8uhcQSCN0(UxaXK=av zC=hfHQRBpnQ)rwb;}jdG#5kqKDKk#F zaVm^cX`Cv2UWPcvsWwiHacYfIXPkQDG#IDRI8DZBHcpFiT8-0YoVan?jg!C?%Z!sW zP6xhlq{BoyO{B|2x^dI0CC9c;C0zIID!FzyN5bFpt8#^YVXie- z?oZ~La_zYyf6(vo2XeK!;#^&>(r@(J{aJt1ACoqVZGMBFT$^jm_4$>4RE9SCZmuJj z$l3mME+RwI{)9iAYxc)w=d2%>L(D&#i{?uG78#V1SA%|$>^SYu;H~C52vg&9oaWs}Z z7V8cclepCiGB$1#qga!7DjBtLyQF9ocZB_7d?~a7cUs2j#+T(|?Za0>XX2~jGgshi z;T31%>!B;~jnGQm65sV!YTZQ z*pJ_|OnEnc%QD^5_-)xTj^DA&NFTl_r+@bfmnn4#9I8JScg9n z>+#281O7y8#Gi^y_%pE?-xXW%=VB}VLTtldigEmv*pBas34C8n;s;^}ekgY0M`9Q5 z7rXI**n_oV3J;3Ccu4HSUyJ?t8*u;+i-Y*FIE23yhw+Fwg1-|-@%QpB7V)U);<3D? zgseQSaq&dn(x|NcgT}=_<}JCh_D>oYKgl~$C2K#`xcKM16FTl+G%o%%?}U!~H;s#* z<(<%R|E_WI^SqNf?iU&tzsx(S<9?-a@nqgf9cPEME+SGLna{c?2<4s9u~F7VOsb;` zSr=_7X{6-c zCL9O&XJ-@CF-GVg%D-K4!!MWW*@4q3}i%4@a+(-+N_xhzOOlFVx1=wIJ(7VK_DY6g*e4l@VZS6D!vV>73Yaw2hwApw~lf-dJ+{WvgB;JrDlXz3oS%kMF-AM$Jo-Qm& z`s#5)(qD#?nhut)>}unikY+TG1dW89}3F6iu2mnl)o+(Tt;2 zGl4eEB;uMWv}>l3(99sI$)H1%MW<#KU79&`OXNfC30ueQQluocBj}aXm!MD5l0?5G zX=6asg+WP297B@Md<;vv1~4M&?!>61rx0mLDvB{lpN;Xb6)cQlLgMCQGAuWpEw`Jt z)W$TM#EiDwMn)@NudKGF0khgV8*^Iu`pj!(HVaz$$}DPAHe5D|by_*=dhL)6Pn))} zfsJ6JcHG7$X|)~0W^H}}wrHch*s7Ih$2M(Y0k&(4ZS2s>e0?^JoVHx9^_bKgo6`p2C@r<-auG_QH zhTeKSr|mDq^V-2)yr5mE!x3rgSOiDeZWw91d~C<0iJ}x<49g>O7%zpxJ6rLxuB7ow zIP4AJRaucY`kEwv0>@>4r(14US(VH6hOU;U@urL`#9LxD0=Yxxi?O6B!3j+%PHM_< zN>h%vH5GVAQ;ByqRd`RbSd8~ICHO#7iVrnq_()TZk2MweL{o`RHC6ablYwnXvWRGA zk*}FUfo2|2OMcVHb10^5mHSoO)`lW&yaC19b_XSvWh$mos+mQZq`wX2a*W0pDkPNy zsI=NbH|&_*F~3yTShW<7P0BJYOGcJi6InF*l_uVA;)5nJ8ce!DW;)2W1oI`qLh@8n z{+fLq6J(l#OeV<82ATOFvlwLUAe$d#qd~Sf z$hHO9_F#S?ScnG;UGjS{F3W;9XY6KU$BjK};-jdN30}V=yJJo!SSgd5kY!4i8CkL> zvS9KnOuWy;2TWolm|P4pQ$e;lm@f_%5;8&g!MKS}nncPZ`bDxnQ9+Sm>0=waPN*$^RajjNNAJ ztcj1nv6e5z2g+pWMzvn}fil!sVQ&Go)@iq!Nc0ZWS=Q~h-GO?`Ix;+g2FcVU8s+1d zSU{5{&zmtc%Sa~{K?^&DR(2X~+SCH#+Uy+KE%`el9|3+TFmsHeXKvRc7O(%vlgBZ3#mtjO+J1LB6T9B5r zy7L&bLU&`_3VSXlGE6bHL zloiTKWtDQKa+Y$oa*lGYa-MR&a)EN8a*=Yea*1-Oa+z|u@;T-6$`#5Nl-0_W$`_TZ zl&h6%lxvmilE*s(elPy7CR>F6Eob zx0G)ycdtAR_pXDwo_cfx-AFgl&2$UhO1IJNbO-fmj_#zp=x(})?xp+aetLi&q=)EX z`V@VdK0}|S&(Y`U3-ky*N)0_mU!*V5m+33?Rr(q|PG6^Q&^PH@G@wiL1U*Sl(YNV4 z^j-QMeV=|nKcpYgkLf4$Q~DXTLwfxqG@lmGD2>rVT11O!2`!~%w47GZN?Ju7T1{(c zEv=*Vw1GC#CfZC}Xe(`_aoSE3G)X&XC+(u$w1=i>FYTlKbbt=hAv#P)=qOFoF*;5s z=p>z@({zSrXqL{>IXX`l=puFLI=Y^EbOYT;H_^>>3*Ab$(d~2x^=Xdoq`T;Dx`*zi z`{;gpfF7iW=wbR4eVRT)pQX>y=jjXd2t7&-Jw{)oFVUCjEA&030Q zOY{UiNl($Y={xjY`W}6sen3B@AJLELC-hVL8MVXw{?mL~K%+E93uzH8rX{qLmeF!r zK`Ut$b!auMp|!M**3$;sNSkOgZK18SjmBv^P0%Fmpq;dfcGDi3qP?___R|46NQdY! z9igK%O~>dsouHF+icZrRnxR=bOXui3U7(B9rR(T=>d_5!Bi%$d(=Bu>-A1?59n_~e zx|8mryXhXfm+qtc=>d9>9-@coQ}k*241Jb9N1vxJ&?EFHHS`#Lk-kJ1*^j zeVx8R-=uHRfG*J!^dvn+-=^=-cj1Wio`2DB(w17rwj26-& zT1-o5DJ`Srw1QUBD(cW`T0?7T9j&Jgw2?N^X4*nqX&a5xcAB6`+Ce*M7wx7!G(~%9 zAMK|DbdV0wVLC!bX_}7FaXLXK=@gx&Gc-f9be7K1dAdLssY}<<_0*#q=tjDUZl+u4 hR=SODr#q-mb95)&MR(IZbT8dU_tOLPAU$NQ{13W=fyV#< literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/names.wast.3.wasm b/lib/wasm2cretonne-util/testsuite/names.wast.3.wasm new file mode 100644 index 0000000000000000000000000000000000000000..bb835113839ad841652cea588b9a81cf446b3247 GIT binary patch literal 88 zcmZQbEY4+QU|?Y6VoG4FXGmbGuV-LVX5uI=NKGzDEiPd#D9X$$VPL=zU}j=uWanmN Z2g@59F)(rQFmf>{FbFUxFbXho0|14i5<~z1 literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/nop.wast.0.wasm b/lib/wasm2cretonne-util/testsuite/nop.wast.0.wasm new file mode 100644 index 0000000000000000000000000000000000000000..c59a8cd83c39d23f4969b87ff5eed73b65d520bf GIT binary patch literal 1496 zcmZ8hS#sJy5be$kZsz%3L7pR zQpE}OEK~b5HDmHPB1=YW(WQwP8Vw=-@Cb~Jq&_t;ODB0ai#6vx73Uqpsn1SLk&*qJ)|l#i zn{K477qspjVdw&CZ63z4ytbDn9Kov!a<$jAC>9$IZ)lqBCQKis&|8{Du%UX#Ge<0= z9lYn)ESSANP=7NajJ%K3L9Vl0%s){F3=Pd^@|q{>yD*hSeWBHr1iKGT48}j3as0e=YqOYULAaVTKv4SmFIy{#NaQ}tD#t3 zc!x+~fDvV57(ic)2$Uh7^gYZZWqJ3#1F#CRN4-@@B`krQ4_vKHaa9oIb}6?@c>}ph zjmLX6x8sa`@X#{=XRO?P?1PKbP+9DziINtVqSgpC?Aa;>DT<_I?@=V#h2~Tm7OUh|_ z;XI_l4Qa+`EUv{ZX&P?Iw2eAFlo`9-S<9RqN}JpBz%z+iM!(3EKvpIYWUR8-aboIF z)wXByW3TPJ9@<@ai7_{hi0;TWxaZkvJ>ESWV0kABaD_v@ ghX?x?d?D&bB7heH_2!BXLMW$$(ZM)B81EzEH|i2#U;qFB literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/resizing.wast.0.wasm b/lib/wasm2cretonne-util/testsuite/resizing.wast.0.wasm new file mode 100644 index 0000000000000000000000000000000000000000..44fec0b34207b8d431a24fe281b352a216b71d13 GIT binary patch literal 181 zcmYLc)0gD)3&G9E&$xj=D5oAssm zZ4}QnG}^R%5+{SdO1EUaCD`6%y@kf#TIp?qHVfh;nU#LzryI=n4repSxVyZ0l7`lL z$>dIt#-nhMOoy;$avN*~>uW~N0z+8YM%S`=bP`k3rbGQ6HoxPndu!{w&L*(x%Sbz^ z&gbd0Jj#^@F^h9-mmojYQ`jkijx!Bc*_i2A5Aw3yYn>I7X;a27mr;rgah>ZNL~&et z_P7fMbBk_piwrU?`eCDlM|9S4YMw;1g`1lfc{A=G*Dq{v+FKX%nEbadkv!A+5zRb` z%kuZRt~iN?VKf}3I?Lb=*Tu~5OX|RsnkT7VQg=DFKSwv?tu7{j?!C2cP zE|})W^2K^C|L zIVc-F!!3xd7$6C-#xokHP<3ol5|g+^0a6ZCLnT_Ut^5*KNwvbgejVHVPbK?>?6ST= zdc&}z!%S64Y||eh6IJN@h_b~8s}u@6B_yE$2)O74OB4u?PRVDd;{_0i9SQ?bRkWd^ z{wN=JWCc_~)v6|yq})!xu~04Q*dlgR8!2vsTBozIs#^typf-$Y35D7u-#O^0Eo3N# zI8$BRv(I|*<@5i~@qorzgZ?hwr|Q>0?P58;tG#C~3!7A=x{ikn5TNpZr8bm1d-xl@ z8wJgb^8L}nPn3nqt`q7sjS0Yk0y*ruo+?$?n9AgBdOz%eMNUW1R|=ari`azM z^G#c4ue5^u<2Ag^oWGy7$@0?N;D=YWLV|=6CyxG80G#b=90hhxumxhvV~zb{U!5TO E0Kcj;P5=M^ literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/set_local.wast.0.wasm b/lib/wasm2cretonne-util/testsuite/set_local.wast.0.wasm new file mode 100644 index 0000000000000000000000000000000000000000..6f60f4507b5573666eec5159a2a262c1f07bcc4d GIT binary patch literal 454 zcmY*UOKQU~5S_6s*^y{_1!+;pCX0UP+IF(<6>M4u3^5I9pbhwQj&xCagzQ=z=y7_E zj$}jPfycagdh;Yf_F5tU;B}A!q}UP~LQSY3IKl z*yb>ie<(x5HUy!2Dx>6BE0D#nRO@qA6ln zdkt1Lu1~^Kh)1_Eg5RHTG6_O(a)jz}2%z}=ufcdq8#}jghzw7J5rbPtCe+YrJZev~ TAMJl@e$=AVL8rs7p$_UF|H@!_ literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/simple.wasm b/lib/wasm2cretonne-util/testsuite/simple.wasm new file mode 100644 index 0000000000000000000000000000000000000000..4e7c773ae2c432bc10c47603cac2c1d0b352955e GIT binary patch literal 41 ncmZQbEY4+QU|?WuX=rF*U`$|OU~U4l7`QsYbTf!#VB`h>$!Q7F literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/skip-stack-guard-page.wast.0.wasm b/lib/wasm2cretonne-util/testsuite/skip-stack-guard-page.wast.0.wasm new file mode 100644 index 0000000000000000000000000000000000000000..79d487b41b604eb92ab819e354973332562b9273 GIT binary patch literal 18586 zcmW;SWt42uS%l%^XGo9$0fK)O4-h;YoOpt3aES{c5F$9_+T6MB?(XjH?(XjHu2j{p zdU~yyKeJZ%ncn+NKK1plq)C#bE!ij2ZzZ2hl046nw9L~at>2Qq`5T}6`ZwPDg>Qc9 zYoC4ZS3mWI&%O8SU;ffpljIF&`lQ*LlSn?0e6)D~o6?d>zx<};jc?rCCr!t+{NJ0> z4g(^^9H;@^G3W;^X>R{&3E8C zG~bEu)O;7dOYr^W*q&O&~M?G;hUQHE+Y)G;hb-HSfSXH1EVaHSfZ^ zH1Ec{HSfWDG(Ul#(EKERQu9;zDb0KFUd>PAr!_x=pV9m*epd5y_&Lqb-creZ{RmHzlq<}{1$#o^M1Tv z^8tK7^Fe%2^C5gl^I?2g^AUVR^HF?M^D%r(^KpD!^V|4s&F|oMG{1}A)%+fQPxJfu zea#=>4>W&>Kh*pY{z&u3_+!nV;7>Gvia*u-8U9T334B8H=lFBYU*In^e~G`;{1yI6 z^Vj%m&EMc}G=Gb~)%+d)PV@Kpd(A)KA2grDCpDkKr!=3&r!}9!XEdM1XEmS0=QN+k z=QUrz7c^hQ7d2nPmo)!~f7E;#U)KB+{z>x{d`0um_-D<(;9oRf#aA`|ihtF74PVoI z9beac1K-em6W`SQ8~#o6@A!Akf8akf|B3(9{1^U9^WXSy&HvzkH2;hL)%+j+PxCE& zOVchzJHPeXr)Y047M!yvOjQ%P58v{}dFb1X=Xbeg*$QYbrurVaX z5MyYHp~kQj!;Il6h8rVNj4(!~7-@`3G0GU7Vze&x$XJ|Wv9Tn@5@TtKrN*)p%Z%kImK!TltT0xlSZS`JlA*qvgxu_whIV{eMR#=aE$jQuJ08wXMxFb<|TXdFs$$T*zh zuyG{C5#wlzqsFlm$Bg4CjvFUZoG?zNIBA?pamqNI;nW}qH&Wa%Zl<_t+)8oFxSis*aVNzc z<8F$(#=R8xjQc6>8xK-EFdn9OXgo^s$atLMvGF9u6XR)$r^d4s&y43Oo*OSxyf9v- zcxk*!@yd9e;3@`>}7-$U2 zFvu93VX!eI!w_R=hM~r=48x4!8HO7pGK?@rW*BLV$}q|ponf>wCc_wGY=*JMxD4Zr z@fpS&6EaLNCT5suOv*6Hn4DpVxyHN<^Njf!<{Jw#EHD;kSZFNDu*g`PVX?6!!xCd@hNZ@`49kq=8I~I> zGORFGW>{&g%CO2S18!~J#HfGppY|607*qmXru_eP6 zV{3-3#954=M zIA|QoaL72E;jnQe!x7_XhNH%@49AS)8IBt#GMq3@W;kh_%5cg!o#C``Cc_!yY=*PO zxeVuw^BK+?7cyKhE@rrBT*`3CxSZj#aV5hQ<7$Sh#yT-i?_l)})?i&v>JTM++cxXJz@W^g;M=zsyj^0L}9DR(wIrV|0$u#+V#q zjIlY!8sl<|Gsfo_Z%oKB!I+q1qA@AQBx7=p$;Ol%Q;exOrW(_7Of#nEm~PC-F~gXd zW2P}H$1G!Zj@ibX9CM7hIp!Mka?CU4=a_FS$g#j!m}8-_D90jWagN2tk{nBnr8$-w z%W^C;mgiV*tjMv#Seav`u`0(ZV|9+z#+n>!jI}w|8tZbbGuG!=Z*0i1!PuB%qp>N+ zCS!As&Bm4-Ta2wawi?@VY%{j!*lz5|vBTJzW2dnz$1Y=cj@`zd9D9ttIrbX+a_lqq z=h$x?$Z^0pnB$;vD90h=aE`;qksL>iqdATm$8sDqj^{XToXBy)IGN+5aVp0t<8+SG z#+e*vjI%k;8s~DHGtTEYZ(PW6!MK>?qH!t5CF63A%f^))SB$GUt{T^JTr;lcxNh9Y zal^Qovp`RySAkwe?*hGzJ_Y(1eGBw8 z`W5JB^e@og7*JqX0+Wp?1*RBN3rsbp6_{pB zFEHJhQDBBKv%pMaR)JZ@>;kimIR)kza|_Hh<`tM{%r7wCSWsYrv9Q2GV^M)c#^M5t zjU@$^7)uK*HI@}vW-KqT+*nayg|V{0N@G=lRmSQ9tBo}U));FGtTomZSZAy+u-@2E zV1u!-z(!+JflbEd0-KF31-2Ml3v4yE71(BMFR@Tq2I8fk#aj?Ka<4}P^#^C~ojUxq)7)J{nHI5ZHW*jeY+&EF-gmJRK zN#j(3Q^x56r;RfO&KPG4oHfoBIA@$MaNf93;DT|nz(wOyflJ2a0+)>|1+ExZ3tTm> z6}V2R(Ut+v5p~M7ZVu^{yq!N>i$t5NmQ%X!R zrk0p$Oe-N}MsymN;viD{;;^U*f!Rp~MB_Vu_2!r4pBn%Ox%w zS4vzlu9moJTq|+SxL)GAaihcy<7SDQ#;p>!jN2t{8+S_FG47VQYuqbw&$wUWzVV>M z1LI+dhsL84kBrA99ve?eJTab@cxpT=@yvK$;<@pn#0%qPiI>K!60eNcC0-ltDzx*x zPWuY&jSdw$7#%BgG&)u2WVBXjH9A-5Y_wHqGrCmhVsx$0)#z5Co6)^OccVvz9!Ad! zJ&j%!dKtYd^fvlb=wtM)(AVf!p`X#eLVsgGg#pIE3ImNn6$TlDD-1SK?$O5H}jY$CGmTjlW*M_9%r@p!m}AVXFxQw@VV*I+ z!hB;vg$2gK3JZ-z6&4wbD=apaR9Ipxt+3QsR$-a3yuxy0MTHf{$_guuRTWklt1GNF z)>K$ytgW!tSXW`4vA)83V?%`v#>NU8jZGCc8JjC?HnvpQVr;Fj)!0^Ho3XvZc4J3{ z9mdWIJB?ixb{V@X>^AmP*kkOiu-DjEVV|+T!hYjGg#*UH3I~lt6%HAPD;zeCR5)TB zt#H&hR^ga&yuxwgM1>Q^$qFZpQx#4brz@N`&Qv&KoUL%yI9K7EalXQN<3fcC#>EO3 zjY}0S8J8l{b8^+BFH;r2rZW*^L+&1o1xMSR{aM!q3 z;hu57!hPdGg$KsN3J;A(6&@LnD?B!yRCr=Mt?<-%R^gfPyux$iMTHl}%L*@zR~23v zuPeMZ+SO?13+47T+8Z5ebTB&B=xB7R(aC77(Q0(A(b;IL(Pnh1(Z%RmqpQ)aMmM8- zjqXN|8a<4jHF_GoYV#)ujtjFB})8l!5AGDg=JZH%cg#u!^;tTC>}IAeT`@y3K2 z6O4&9CK{7!Ofn|dm~2d`F~yi#W2!N&#x!Gkjp@dW8Z(TUHD(&KYRocb*O+b0sWHcx zTVt*>P z#x`SnjqS#c8as@gHFg@iYV0z0*Vt|Bsj)5jqApZ8aIraHEtTWYTPnz*SKxm zsd2}+TjQ>Auf{#&evSLagBlNvhczA=k7_(J9@ltmJgM=-cv|DB@vO!(<9Ute#)}#+ zjF&ZD8n0@+GG5nsZM17aJC`i&ThQL<(1H#|#};%nI<=sa(b|GmqjL*78*MFUGrF{( zi_x_OU5#!n=w@_pL3g7^3wjtmThPk$=p!lICVILGf+$8LS;zyc^R6a& z7w6qg@@~$1nuL8&{6v$m4~m~`681syQ%%A?DBjy7?1SQ`n}mH({7jRu4~m~{681sy zb4|iND1N?4*ayWgGzt5l_{An+9~AFvlJ{|bsY%!eMbjkggW{K)gndx_N|Ue;ieGIK z_CfJ$O~O7Xe!WT92gPqR3HzY<%_d5za@O~A8(S6bAG!?*ayY$Gzt5l_}wO99~8gWBkp!m}!VILHK)+FqM;uB5s3C^E43HzY< zizZpKFrOaX#N9pXYp`Nxs1OVv~H4^Q9(X9~A%C zBJ?1SQKO~O7XzTPD4 zgW?-a!agXz*(BfO{9BW-4~lrMf4JS6TO8#L?59q(O2k4^b`6M{e=O<0AV08P#8oE z5(X24g(1WcVJI`>CNWc(Ma&Xr6SIXm#2jHRF;|#J z%oFAl^MwV(0%0MsP*_AP5*8DSg(buiVJWdxSVk-pmJ`c`6~qc*C9zUiMXVB56RU+a z#2R5Ou~t||tP|D~>xB)(24N$yQP@Om5;hZ?g)PJuVJop!*hXv=X7A`-KC<0pTEVP&h;!5)KoGg(Jif;V5xbI7S>3juXd) z6T}JOBymzWMVt~&6Q_kU#2Mi%aaK4-oDqubQMg205-t;$g)77r;VN-e zxJFzPt`paV8^jIaCUH}^Mcfi@6Ssvs#2w)-aaXuU+!O8-_k{<<1K}a@PtMZ6MT6R(AKeB`&&Grv92Ug$t{5IPbag-%2# zp_OPAIuo6RHlj`FLZ}alu7vua=tigyitdE^py)xU4~m|I`k?4Vs1J(Xg!-W9L#Pjm zzJ&Uq=trmzivEQ9pcp`?4~l_=`k)v@s1J(4#9(0vp*|>v66%9u7@L>VskoF-90mj1|TaD5etX zgJK$?J}9OW>Vskip*|>P66%9u7NI^UW)tdzVh*7`DCQFCgJK?`J}BlB>Vskdp*|=U z66%9u5urXP788qwC4~B*SW2i5ie-fQpjb|*4~i9p`k+`zs1J%&g!-UZO{fowHN+ZW zEwNTuN30Xp6YGTy#0Fs_u~FDWY!WsTn}sce`k>fKs1J&5g!-V^PN)xx9fbOz*h#1l zid}^Ipx8~Q4~jj6`k>fLs1J&Lg!-V^PpA)y1BCjZI7p}uibI6@pg2q%7LE|=gW@Qm zJ}8b6>Vx7qp*|>15bA^CB%wYiP7&&Z;xwT?D9#XPgtNq1;T&;JI8U4xE)W-li^N6Y z5^+hmOk5VO5bA^CDxp3ot`X{k;yR%|C~gqygW@KkJ}7Px>Vx7op*|??5bA^CE}=ds z?h)#P;y$51C>{{%gW@5fJ}4d$>Vx7j@mP35s1J&#g!-U(MyL;p=Y;y8ctNNSikF1? zpm;^74~o}>`k-jX?;7oLqCL@G=sVsk!p*|>v6Y7Iv1ff1CMiT0SVici1C`J?NgJKLZMi@(s z6~+Vsky zp*|>P6Y7Iv4xv6M<`U|IVjiJBDCQIDgJJ=pJ}4Fv>Vsktp*|=U6N`lxB)(24N$yQP@Om z5;hZ?g)M~opx8>N4~lJs`k>fOs1J%Ag!-V^NvIEsU4;6e*iEPpiamt-px8^O4~l(+ z`k>fPs1J$*g!-U3NT?5rLxlREI7}QCju7gD;wYg$D2@^8gW@=$J}6EQ>Vx7Wp*|>1 z5$c2DG@(8y&JbsWv&3299C1!KPn;Jn5Eq1t#6{r}aY?vLTo$en>Vx7cp*|?C5$c2D zI-x!&ZV>8&;wGU!C~gtzgW@)!J}B-G>Vx7gp*|??5$c2DKA}D+9uVq-;vu0vC>{~& zgW@sqSa?FH4~nOR`k;75s1J(gg!-U(L8uRkmxTJDctxlWir0ktplHWKj&?fbXiu~k zIuIR%jzmYH6VXX%C0d2fL}#ImXcM{+U4*VgSD_oxP3TT^7kUsqgq}oCp%>9h=uPw% z`Vf7DzC>T4AJI?fPxKcC5CepP#6V#XF-RCp3>JnELxiEkP+=G`Oc+iK7e){xgptHZ zVH7b+7)^{8#t>tKvBX$m95GH9PmC8P5EF!n#6)2dF-e$AOctgPQ-rC+RACx1O_)wh z7iJJMgqg%lVHPnau}D}C5C?>V z#6jT@aY#5!92SlcM}(uqQQ;VIOgK&)7fui-gpp zcul+(+VOO?osL)A6YYf#LrMf4JS6TO8#L?59q(O2k4^b`6M{e=O<0AV08P#8oE5(X24g(1WcVJI`>CNWc(Ma&Xr6SIXm#2jHRF;|#J%oFAl^MwV(0%0Ms zP*_AP5*8DSg(buiVJWdxSVk-pmJ`c`6~qc*C9zUiMXVB56RU+a#2R5Ou~t||tP|D~ z>xB)(24N$yQP@Om5;hZ?g)PJuVJop!*hXv=X7A`-KC<0pTEVP&h;!5)KoGg(Jif;V5xbI7S>3juXd)6T}JOBymzWMVt~& z6Q_kU#2Mi%aaK4-oDqubQMg205-t;$g)77r;VN-exJFzPt`paV8^jIa zCUH}^Mcfi@6Ssvs#2w)-aaXuU+!O8-_k{<<1K}a@PtMZ6MT6R(AKyw+)_d!6<~d!Yl-LFhVu*ep*|>j6Y7Ja51~FN`V#7cq936?DEbrX zgJJ-oJ}3qf>Vsksp*|=E6N7~zg!-TuN~jNtVTAgi7*41UiV=kRpcqN04~kKQ`k)w1 zs1J%U#28^LF;*Byj1$HaVsk>p*|>95$c0tHK9Hz)(~riwZvLs9kEVWPplU< z5F3Pz#71Egu}RoWY!Vsk{p*|?K5$c0tJE1-(b`a`=VkeVsl0p*|?~5$c0tKcPM-4iM^t;vk_uC=L%F?;XH9(xIkPGE)o}oOT;DNGI3eBLZ}al ztAzTXxJIZCitB{>ptwP(4~m{66%BE8KFKXo)hYW;sv2TC|(lkgW?sTJ}6!j>Vu*k z?~~iVu*Wp*|@366%AZAE7=d`V;DdVgR8&CVsl7p*|?)5bA?s zE}=ds<`L?HVm_fhC>9XvgJL0}J}4Fu>Vsl2u~=9_s1J&zg!-UZMyL;p<%Ig6SV5={ zij{==pjbty4~o@<`k+`ttP$1{YlU^hI$=GrUf4iv5H=DUg-ygJVKcE=*g~ieimk*} zVH=@7D7F*ogJK7vJ}7n)>Vskzp*|>f6Y7Iv51~FN_7duYVjrPCDE1TTgW>?8J}3?n z>Vx7Cp*|=M6NiN(g!-U3N~jNtV}$ykI8LY!iW7wTpg2jW4~kQS`k**Xs1J%W#2Mi% zaaK4-oDqubQMg205-t;$g)4;mptwq06|NELgW@`&J}7Pw>Vx7Yp*|>X z5$c2DHlaQ!?hxvO;x3^+DDDyJgW^7+J}4d#>Vx7Tp*|=c5$c2DG4WV#ID{{nGAG9Ul| literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/start.wast.3.wasm b/lib/wasm2cretonne-util/testsuite/start.wast.3.wasm new file mode 100644 index 0000000000000000000000000000000000000000..21b795c5e456f72e117567ac86df7b36b83996a9 GIT binary patch literal 94 zcmXAfK@LDb5Cp4t2(c0V;Oql#`x7D}BwV=rx(QvEu1+&uhX9pfgb_WK86wZ*De7R` fIfJds?H`4zvxemKkhBjF%ikI=?MIA-e2Ypi%;pH2 literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/start.wast.4.wasm b/lib/wasm2cretonne-util/testsuite/start.wast.4.wasm new file mode 100644 index 0000000000000000000000000000000000000000..21b795c5e456f72e117567ac86df7b36b83996a9 GIT binary patch literal 94 zcmXAfK@LDb5Cp4t2(c0V;Oql#`x7D}BwV=rx(QvEu1+&uhX9pfgb_WK86wZ*De7R` fIfJds?H`4zvxemKkhBjF%ikI=?MIA-e2Ypi%;pH2 literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/start.wast.5.wasm b/lib/wasm2cretonne-util/testsuite/start.wast.5.wasm new file mode 100644 index 0000000000000000000000000000000000000000..7a4b81947e28de963076ea16a4048e9bc64c62a1 GIT binary patch literal 55 zcmZQbEY4+QU|?Y6U`k-DXGmaRU=m{FC@x4%E=eseVJ#@i%qwAFU}j=u#i}5VfzvL!C>qV* zVm=L4yA1&_*q)iW=g6@Kv#lHm(_A^X+i&)OTfe;wpj{33F!kN@uw4(Z^DnwvGN%I; zG|S6~XlJ0YuBvB^B7!I-L_99&D|x5%T~56{b)}!ONs&P}CD;xj- literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/tee_local.wast.0.wasm b/lib/wasm2cretonne-util/testsuite/tee_local.wast.0.wasm new file mode 100644 index 0000000000000000000000000000000000000000..c7490e67c6e10d3f775572d7836ee41b4fc4f7ad GIT binary patch literal 594 zcmY+Ay>7xl49D$UatXP9>^GfmVqxfqx;CLO7gg#`)CLI&R0LElQa)aQ7l5f-S2j>0 z^%43^^@X5(PDokQqXp)Dvh;9&Y-epK({A`sg+@3Ynpio#UOR=4@x5_CM xFO*v-@2j?rcswkM8Va*#ps}o9;s@FaZOwL}qwQ@yr8H9tvtUub#*8`$ia$G9g((04 literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/traps.wast.0.wasm b/lib/wasm2cretonne-util/testsuite/traps.wast.0.wasm new file mode 100644 index 0000000000000000000000000000000000000000..6b36d5c04320db66a3ef0400b2ad626ae571db10 GIT binary patch literal 146 zcmZQbEY4+QU|?Y6W=deHuV+YLs;gsQW@Q12FtYoy2;}9*rzEH9Wf~jlrDT@H7c(%R r3zaf3!iCICpsJYAg-RKixl~y=7!(*37;~k#A&fj2qaMa+km3damH!_q literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/traps.wast.1.wasm b/lib/wasm2cretonne-util/testsuite/traps.wast.1.wasm new file mode 100644 index 0000000000000000000000000000000000000000..31d416dfdffdb1eae3655f0a08d2aa34c28155e3 GIT binary patch literal 146 zcmZQbEY4+QU|?Y6W=deHuV+YLs;gsQW@Q12FtYoy2;}9*rzEH9Wf~jl6{Y6J7c(%R r3zaf3!iCICpsJYAg-RKixl~y=7!(*381tpLA&deTqY=hvlHvvcm<1m; literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/traps.wast.2.wasm b/lib/wasm2cretonne-util/testsuite/traps.wast.2.wasm new file mode 100644 index 0000000000000000000000000000000000000000..74e1fe5bf30c8b03371f76e5571bdf3dab1ec5f8 GIT binary patch literal 293 zcmZQbEY4+QU|?Y6WJ+MHWk_JGVPNLu0P=x?jEw9j89BuA^5avIQ}r^9jr2;2O7oKA zi{sObjTjg(B}%~(jF=KY9cCsBOqdct9Y6_YxP+MriXAMN5)eCBF(n{&uwhC->|p1z i;s8tYZHH2CRq1HpF4G?Oh6gL2huS(7U literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/traps.wast.3.wasm b/lib/wasm2cretonne-util/testsuite/traps.wast.3.wasm new file mode 100644 index 0000000000000000000000000000000000000000..6d98e644425f6e1d27a8bd0662053b468af29788 GIT binary patch literal 458 zcmZvXOAdlS5JamP5d?)qcdlIeMfpg)4HD7BL}fu{%~`yupwq+vtR632-8D#yCjlUx z&QwCUPWAKm>4HGUTXWo3o@AG+cMk*ak*66jYZ*UI3Q&)g(59`~Q#C5OQex2DiKE{g zz1gTt7*ye5kCiam_S?zqu@a-^yxLoLvbs{j=1w<$`?xXOa$=Q^i3OG#=5`GpDcCb? cq0Ek9C6tLcbz}%Q6*3$+l}_1VVtYn0+;bu!K-WmBsSQ38+eBdmIe1<&u=J6hRl@2>f#y z4#n#p*@lYBviiM#uV=bPC5p1KA|iFOx=*z46-7b&qzc^MasSxYMFBM9kG&VWq_p-t ztx3C^1NYOqqJ3N%1?37V{0KnvRq@qSDdl^LRPZO*spem&wljLXO}Y%9Jt5D9L$H-H z1nW1VtTQ~E^gF{*n&q@)W_UarP*9(tI6|^I7av9Op{3;}(!Dt8e=6NI);ogjhV>4L zzrN7B0*wXHOOsEQn(T;^WLg$%@pc4ry%jDmNXo6w#m>CO;$GTuwNJ_7>E3AA=_iu` zotCu(JHh%Xk+VPuCp)w1*gWdRnBin#ztF~ioO7Qo-A?BUY}2`of8CCCHO_CI%tVtx zxx!`(+0^ET>7?BLg&LUI-Y=FQ|6nI{sRTC8EL~<}W@FpW%aOHL7EETP^()+ZDH7r; z&!!*6ap}3nlM~EizRqJ7BxAm@UcxA7yfAe0%t>C}ptUs}zR)Xu4nv?`Q4rw4p?850ZNLm8Um zoN9|J9ZsV3YbTl76bD0(jzFN0igNM+d6L;Oo~i zhNx16JkBj zPCNsmUjSGb1WFy#6*5aicX3X5Y@yK>(Hk_3>q2+eBkTn79SP9b3n+wniE*N>pKJ?j hAMtoqqhqGtVx+SY*Si+meT`N^de6za;yLV literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne-util/testsuite/unwind.wast.0.wasm b/lib/wasm2cretonne-util/testsuite/unwind.wast.0.wasm new file mode 100644 index 0000000000000000000000000000000000000000..6057472111dbec2219224e1dd44312a62868469a GIT binary patch literal 1713 zcmaJ>%W~R45S#@kAO?^@5)aAPi4&6(-w=!B1K8j#NN!_$~lIv>Oiq4Bfrb|Ju^KyG3X;}W*`8SK&!8fE57qI{aOl14MEyl@J9942WT!7FdG+i$zDncVy-$G9EhxgqnkgVv-OOZrC#m||7%+>Gt1ME8@CGPNpJWS%xZYt z+pFDv|3g3WifOl2iKb!irWGj9dOt34JnF9V_hQ}xzqu5EZS~s)?5M&ws6<^t9{_s{ z`|4!y$)xtiy>_4$U6Rr_|?(;C9=88DH>jeD64aiGNV)D`GTbFG#L z*$Zm1&n>>_19w@+>(ac~p2o3lI^0QKms%7F8qEz#lBGO+gVW_)(!(8D|*PoRf zet(2DPEL|DD81H*UIn4{Y-cta&geq+o5K9K1V*0T0RaZi^%N>iS|w!nvVDn2; literal 0 HcmV?d00001 diff --git a/lib/wasm2cretonne/.gitignore b/lib/wasm2cretonne/.gitignore new file mode 100644 index 0000000000..4308d82204 --- /dev/null +++ b/lib/wasm2cretonne/.gitignore @@ -0,0 +1,3 @@ +target/ +**/*.rs.bk +Cargo.lock diff --git a/lib/wasm2cretonne/Cargo.toml b/lib/wasm2cretonne/Cargo.toml new file mode 100644 index 0000000000..ef82b76118 --- /dev/null +++ b/lib/wasm2cretonne/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "wasm2cretonne" +version = "0.0.0" +authors = ["The Cretonne Project Developers"] +publish = false + +[dependencies] +wasmparser = "0.6.1" +cretonne = { path = "../cretonne" } +cretonne-frontend = { path = "../frontend" } diff --git a/lib/wasm2cretonne/src/code_translator.rs b/lib/wasm2cretonne/src/code_translator.rs new file mode 100644 index 0000000000..208c531812 --- /dev/null +++ b/lib/wasm2cretonne/src/code_translator.rs @@ -0,0 +1,1375 @@ +//! This module contains the bulk of the interesting code performing the translation between +//! WebAssembly and Cretonne IL. +//! +//! The translation is done in one pass, opcode by opcode. Two main data structures are used during +//! code translations: the value stack and the control stack. The value stack mimics the execution +//! of the WebAssembly stack machine: each instruction result is pushed onto the stack and +//! instruction arguments are popped off the stack. Similarly, when encountering a control flow +//! block, it is pushed onto the control stack and popped off when encountering the corresponding +//! `End`. +//! +//! Another data structure, the translation state, records information concerning unreachable code +//! status and about if inserting a return at the end of the function is necessary. +//! +//! Some of the WebAssembly instructions need information about the runtime to be translated: +//! +//! - the loads and stores need the memory base address; +//! - the `get_global` et `set_global` instructions depends on how the globals are implemented; +//! - `current_memory` and `grow_memory` are runtime functions; +//! - `call_indirect` has to translate the function index into the address of where this +//! is; +//! +//! That is why `translate_function_body` takes an object having the `WasmRuntime` trait as +//! argument. +use cretonne::ir::{Function, Signature, Value, Type, InstBuilder, FunctionName, Ebb, FuncRef, + SigRef, ExtFuncData, Inst, MemFlags}; +use cretonne::ir::types::*; +use cretonne::ir::immediates::{Ieee32, Ieee64, Offset32}; +use cretonne::ir::condcodes::{IntCC, FloatCC}; +use cton_frontend::{ILBuilder, FunctionBuilder}; +use wasmparser::{Parser, ParserState, Operator, WasmDecoder, MemoryImmediate}; +use translation_utils::{f32_translation, f64_translation, type_to_type, translate_type, Local, + GlobalIndex, FunctionIndex, SignatureIndex}; +use std::collections::HashMap; +use runtime::WasmRuntime; +use std::u32; + + +/// A control stack frame can be an `if`, a `block` or a `loop`, each one having the following +/// fields: +/// +/// - `destination`: reference to the `Ebb` that will hold the code after the control block; +/// - `return_values`: types of the values returned by the control block; +/// - `original_stack_size`: size of the value stack at the beginning of the control block. +/// +/// Moreover, the `if` frame has the `branch_inst` field that points to the `brz` instruction +/// separating the `true` and `false` branch. The `loop` frame has a `header` field that references +/// the `Ebb` that contains the beginning of the body of the loop. +#[derive(Debug)] +enum ControlStackFrame { + If { + destination: Ebb, + branch_inst: Inst, + return_values: Vec, + original_stack_size: usize, + reachable: bool, + }, + Block { + destination: Ebb, + return_values: Vec, + original_stack_size: usize, + reachable: bool, + }, + Loop { + destination: Ebb, + header: Ebb, + return_values: Vec, + original_stack_size: usize, + reachable: bool, + }, +} + +/// Helper methods for the control stack objects. +impl ControlStackFrame { + fn return_values(&self) -> &[Type] { + match self { + &ControlStackFrame::If { ref return_values, .. } | + &ControlStackFrame::Block { ref return_values, .. } | + &ControlStackFrame::Loop { ref return_values, .. } => return_values.as_slice(), + } + } + fn following_code(&self) -> Ebb { + match self { + &ControlStackFrame::If { destination, .. } | + &ControlStackFrame::Block { destination, .. } | + &ControlStackFrame::Loop { destination, .. } => destination, + } + } + fn br_destination(&self) -> Ebb { + match self { + &ControlStackFrame::If { destination, .. } | + &ControlStackFrame::Block { destination, .. } => destination, + &ControlStackFrame::Loop { header, .. } => header, + } + } + fn original_stack_size(&self) -> usize { + match self { + &ControlStackFrame::If { original_stack_size, .. } | + &ControlStackFrame::Block { original_stack_size, .. } | + &ControlStackFrame::Loop { original_stack_size, .. } => original_stack_size, + } + } + fn is_loop(&self) -> bool { + match self { + &ControlStackFrame::If { .. } | + &ControlStackFrame::Block { .. } => false, + &ControlStackFrame::Loop { .. } => true, + } + } + + fn is_reachable(&self) -> bool { + match self { + &ControlStackFrame::If { reachable, .. } | + &ControlStackFrame::Block { reachable, .. } | + &ControlStackFrame::Loop { reachable, .. } => reachable, + } + } + + fn set_reachable(&mut self) { + match self { + &mut ControlStackFrame::If { ref mut reachable, .. } | + &mut ControlStackFrame::Block { ref mut reachable, .. } | + &mut ControlStackFrame::Loop { ref mut reachable, .. } => *reachable = true, + } + } +} + +/// Contains information passed along during the translation and that records: +/// +/// - if the last instruction added was a `return`; +/// - the depth of the two unreachable control blocks stacks, that are manipulated when translating +/// unreachable code; +/// - all the `Ebb`s referenced by `br_table` instructions, because those are always reachable even +/// if they are at a point of the code that would have been unreachable otherwise. +struct TranslationState { + last_inst_return: bool, + phantom_unreachable_stack_depth: usize, + real_unreachable_stack_depth: usize, +} + +/// Holds mappings between the function and signatures indexes in the Wasm module and their +/// references as imports of the Cretonne IL function. +#[derive(Clone,Debug)] +pub struct FunctionImports { + /// Mappings index in function index space -> index in function local imports + pub functions: HashMap, + /// Mappings index in signature index space -> index in signature local imports + pub signatures: HashMap, +} + +impl FunctionImports { + fn new() -> FunctionImports { + FunctionImports { + functions: HashMap::new(), + signatures: HashMap::new(), + } + } +} + +/// Returns a well-formed Cretonne IL function from a wasm function body and a signature. +pub fn translate_function_body(parser: &mut Parser, + function_index: FunctionIndex, + sig: Signature, + locals: &Vec<(usize, Type)>, + exports: &Option>, + signatures: &Vec, + functions: &Vec, + il_builder: &mut ILBuilder, + runtime: &mut WasmRuntime) + -> Result<(Function, FunctionImports), String> { + runtime.next_function(); + // First we build the Function object with its name and signature + let mut func = Function::new(); + let args_num: usize = sig.argument_types.len(); + let args_types: Vec = sig.argument_types + .iter() + .map(|arg| arg.value_type) + .collect(); + func.signature = sig.clone(); + match exports { + &None => (), + &Some(ref exports) => { + match exports.get(&function_index) { + None => (), + Some(name) => func.name = FunctionName::new(name.clone()), + } + } + } + let mut func_imports = FunctionImports::new(); + let mut stack: Vec = Vec::new(); + let mut control_stack: Vec = Vec::new(); + // We introduce a arbitrary scope for the FunctionBuilder object + { + let mut builder = FunctionBuilder::new(&mut func, il_builder); + let first_ebb = builder.create_ebb(); + builder.switch_to_block(first_ebb, &[]); + builder.seal_block(first_ebb); + for i in 0..args_num { + // First we declare the function arguments' as non-SSA vars because they will be + // accessed by get_local + let arg_value = builder.arg_value(i as usize); + builder.declare_var(Local(i as u32), args_types[i]); + builder.def_var(Local(i as u32), arg_value); + } + // We also declare and initialize to 0 the local variables + let mut local_index = args_num; + for &(loc_count, ty) in locals { + let val = match ty { + I32 => builder.ins().iconst(ty, 0), + I64 => builder.ins().iconst(ty, 0), + F32 => builder.ins().f32const(Ieee32::with_bits(0)), + F64 => builder.ins().f64const(Ieee64::with_bits(0)), + _ => panic!("should not happen"), + }; + for _ in 0..loc_count { + builder.declare_var(Local(local_index as u32), ty); + builder.def_var(Local(local_index as u32), val); + local_index += 1; + } + } + let mut state = TranslationState { + last_inst_return: false, + phantom_unreachable_stack_depth: 0, + real_unreachable_stack_depth: 0, + }; + // We initialize the control stack with the implicit function block + let end_ebb = builder.create_ebb(); + control_stack.push(ControlStackFrame::Block { + destination: end_ebb, + original_stack_size: 0, + return_values: sig.return_types + .iter() + .map(|argty| argty.value_type) + .collect(), + reachable: false, + }); + // Now the main loop that reads every wasm instruction and translates it + loop { + let parser_state = parser.read(); + match *parser_state { + ParserState::CodeOperator(ref op) => { + if state.phantom_unreachable_stack_depth + + state.real_unreachable_stack_depth > 0 { + translate_unreachable_operator(op, + &mut builder, + &mut stack, + &mut control_stack, + &mut state) + } else { + translate_operator(op, + &mut builder, + runtime, + &mut stack, + &mut control_stack, + &mut state, + &sig, + &functions, + &signatures, + &exports, + &mut func_imports) + } + } + + ParserState::EndFunctionBody => break, + _ => return Err(String::from("wrong content in function body")), + } + } + // In WebAssembly, the final return instruction is implicit so we need to build it + // explicitely in Cretonne IL. + if !state.last_inst_return && !builder.is_filled() && + (!builder.is_unreachable() || !builder.is_pristine()) { + let cut_index = stack.len() - sig.return_types.len(); + let return_vals = stack.split_off(cut_index); + builder.ins().return_(return_vals.as_slice()); + } + // Because the function has an implicit block as body, we need to explicitely close it. + let frame = control_stack.pop().unwrap(); + builder.switch_to_block(frame.following_code(), frame.return_values()); + builder.seal_block(frame.following_code()); + // If the block is reachable we also have to include a return instruction in it. + if !builder.is_unreachable() { + stack.truncate(frame.original_stack_size()); + stack.extend_from_slice(builder.ebb_args(frame.following_code())); + let cut_index = stack.len() - sig.return_types.len(); + let return_vals = stack.split_off(cut_index); + builder.ins().return_(return_vals.as_slice()); + } + } + Ok((func, func_imports)) +} + +/// Translates wasm operators into Cretonne IL instructions. Returns `true` if it inserted +/// a return. +fn translate_operator(op: &Operator, + builder: &mut FunctionBuilder, + runtime: &mut WasmRuntime, + stack: &mut Vec, + control_stack: &mut Vec, + state: &mut TranslationState, + sig: &Signature, + functions: &Vec, + signatures: &Vec, + exports: &Option>, + func_imports: &mut FunctionImports) { + state.last_inst_return = false; + // This big match treats all Wasm code operators. + match *op { + /********************************** Locals **************************************** + * `get_local` and `set_local` are treated as non-SSA variables and will completely + * diseappear in the Cretonne Code + ***********************************************************************************/ + Operator::GetLocal { local_index } => stack.push(builder.use_var(Local(local_index))), + Operator::SetLocal { local_index } => { + let val = stack.pop().unwrap(); + builder.def_var(Local(local_index), val); + } + Operator::TeeLocal { local_index } => { + let val = stack.last().unwrap(); + builder.def_var(Local(local_index), *val); + } + /********************************** Globals **************************************** + * `get_global` and `set_global` are handled by the runtime. + ***********************************************************************************/ + Operator::GetGlobal { global_index } => { + let val = runtime.translate_get_global(builder, global_index as GlobalIndex); + stack.push(val); + } + Operator::SetGlobal { global_index } => { + let val = stack.pop().unwrap(); + runtime.translate_set_global(builder, global_index as GlobalIndex, val); + } + /********************************* Stack misc *************************************** + * `drop`, `nop`, `unreachable` and `select`. + ***********************************************************************************/ + Operator::Drop => { + stack.pop(); + } + Operator::Select => { + let cond = stack.pop().unwrap(); + let arg2 = stack.pop().unwrap(); + let arg1 = stack.pop().unwrap(); + stack.push(builder.ins().select(cond, arg2, arg1)); + } + Operator::Nop => { + // We do nothing + } + Operator::Unreachable => { + builder.ins().trap(); + state.real_unreachable_stack_depth = 1; + } + /***************************** Control flow blocks ********************************** + * When starting a control flow block, we create a new `Ebb` that will hold the code + * after the block, and we push a frame on the control stack. Depending on the type + * of block, we create a new `Ebb` for the body of the block with an associated + * jump instruction. + * + * The `End` instruction pops the last control frame from the control stack, seals + * the destination block (since `br` instructions targeting it only appear inside the + * block and have already been translated) and modify the value stack to use the + * possible `Ebb`'s arguments values. + ***********************************************************************************/ + Operator::Block { ty } => { + let next = builder.create_ebb(); + match type_to_type(&ty) { + Ok(ty_cre) => { + builder.append_ebb_arg(next, ty_cre); + } + Err(_) => {} + } + control_stack.push(ControlStackFrame::Block { + destination: next, + return_values: translate_type(ty).unwrap(), + original_stack_size: stack.len(), + reachable: false, + }); + } + Operator::Loop { ty } => { + let loop_body = builder.create_ebb(); + let next = builder.create_ebb(); + match type_to_type(&ty) { + Ok(ty_cre) => { + builder.append_ebb_arg(next, ty_cre); + } + Err(_) => {} + } + builder.ins().jump(loop_body, &[]); + control_stack.push(ControlStackFrame::Loop { + destination: next, + header: loop_body, + return_values: translate_type(ty).unwrap(), + original_stack_size: stack.len(), + reachable: false, + }); + builder.switch_to_block(loop_body, &[]); + } + Operator::If { ty } => { + let val = stack.pop().unwrap(); + let if_not = builder.create_ebb(); + let jump_inst = builder.ins().brz(val, if_not, &[]); + // Here we append an argument to an Ebb targeted by an argumentless jump instruction + // But in fact there are two cases: + // - either the If does not have a Else clause, in that case ty = EmptyBlock + // and we add nothing; + // - either the If have an Else clause, in that case the destination of this jump + // instruction will be changed later when we translate the Else operator. + match type_to_type(&ty) { + Ok(ty_cre) => { + builder.append_ebb_arg(if_not, ty_cre); + } + Err(_) => {} + } + control_stack.push(ControlStackFrame::If { + destination: if_not, + branch_inst: jump_inst, + return_values: translate_type(ty).unwrap(), + original_stack_size: stack.len(), + reachable: false, + }); + } + Operator::Else => { + // We take the control frame pushed by the if, use its ebb as the else body + // and push a new control frame with a new ebb for the code after the if/then/else + // At the end of the then clause we jump to the destination + let (destination, return_values, branch_inst) = match &control_stack[control_stack.len() - + 1] { + &ControlStackFrame::If { + destination, + ref return_values, + branch_inst, + .. + } => (destination, return_values, branch_inst), + _ => panic!("should not happen"), + }; + let cut_index = stack.len() - return_values.len(); + let jump_args = stack.split_off(cut_index); + builder.ins().jump(destination, jump_args.as_slice()); + // We change the target of the branch instruction + let else_ebb = builder.create_ebb(); + builder.change_jump_destination(branch_inst, else_ebb); + builder.seal_block(else_ebb); + builder.switch_to_block(else_ebb, &[]); + } + Operator::End => { + let frame = control_stack.pop().unwrap(); + if !builder.is_unreachable() || !builder.is_pristine() { + let cut_index = stack.len() - frame.return_values().len(); + let jump_args = stack.split_off(cut_index); + builder + .ins() + .jump(frame.following_code(), jump_args.as_slice()); + } + builder.switch_to_block(frame.following_code(), frame.return_values()); + builder.seal_block(frame.following_code()); + // If it is a loop we also have to seal the body loop block + match frame { + ControlStackFrame::Loop { header, .. } => builder.seal_block(header), + _ => {} + } + stack.truncate(frame.original_stack_size()); + stack.extend_from_slice(builder.ebb_args(frame.following_code())); + } + /**************************** Branch instructions ********************************* + * The branch instructions all have as arguments a target nesting level, which + * corresponds to how many control stack frames do we have to pop to get the + * destination `Ebb`. + * + * Once the destination `Ebb` is found, we sometimes have to declare a certain depth + * of the stack unreachable, because some branch instructions are terminator. + * + * The `br_table` case is much more complicated because Cretonne's `br_table` instruction + * does not support jump arguments like all the other branch instructions. That is why, in + * the case where we would use jump arguments for every other branch instructions, we + * need to split the critical edges leaving the `br_tables` by creating one `Ebb` per + * table destination; the `br_table` will point to these newly created `Ebbs` and these + * `Ebb`s contain only a jump instruction pointing to the final destination, this time with + * jump arguments. + * + * This system is also implemented in Cretonne's SSA construction algorithm, because + * `use_var` located in a destination `Ebb` of a `br_table` might trigger the addition + * of jump arguments in each predecessor branch instruction, one of which might be a + * `br_table`. + ***********************************************************************************/ + Operator::Br { relative_depth } => { + let i = control_stack.len() - 1 - (relative_depth as usize); + let frame = &mut control_stack[i]; + let jump_args = if frame.is_loop() { + Vec::new() + } else { + let cut_index = stack.len() - frame.return_values().len(); + stack.split_off(cut_index) + }; + builder + .ins() + .jump(frame.br_destination(), jump_args.as_slice()); + // We signal that all the code that follows until the next End is unreachable + frame.set_reachable(); + state.real_unreachable_stack_depth = 1 + relative_depth as usize; + } + Operator::BrIf { relative_depth } => { + let val = stack.pop().unwrap(); + let i = control_stack.len() - 1 - (relative_depth as usize); + let frame = &mut control_stack[i]; + let cut_index = stack.len() - frame.return_values().len(); + let jump_args = stack.split_off(cut_index); + builder + .ins() + .brnz(val, frame.br_destination(), jump_args.as_slice()); + // The values returned by the branch are still available for the reachable + // code that comes after it + frame.set_reachable(); + stack.extend(jump_args); + } + Operator::BrTable { ref table } => { + let (depths, default) = table.read_table(); + let mut min_depth = default; + for depth in depths.iter() { + if *depth < min_depth { + min_depth = *depth; + } + } + let jump_args_count = control_stack[control_stack.len() - 1 - (min_depth as usize)] + .return_values() + .len(); + if jump_args_count == 0 { + // No jump arguments + let val = stack.pop().unwrap(); + if depths.len() > 0 { + let jt = builder.create_jump_table(); + for (index, depth) in depths.iter().enumerate() { + let i = control_stack.len() - 1 - (*depth as usize); + let frame = &mut control_stack[i]; + let ebb = frame.br_destination(); + builder.insert_jump_table_entry(jt, index, ebb); + frame.set_reachable(); + } + builder.ins().br_table(val, jt); + } + let i = control_stack.len() - 1 - (default as usize); + let frame = &mut control_stack[i]; + let ebb = frame.br_destination(); + builder.ins().jump(ebb, &[]); + state.real_unreachable_stack_depth = 1 + min_depth as usize; + frame.set_reachable(); + } else { + // Here we have jump arguments, but Cretonne's br_table doesn't support them + // We then proceed to split the edges going out of the br_table + let val = stack.pop().unwrap(); + let cut_index = stack.len() - jump_args_count; + let jump_args = stack.split_off(cut_index); + if depths.len() > 0 { + let jt = builder.create_jump_table(); + let dest_ebbs: HashMap = depths + .iter() + .enumerate() + .fold(HashMap::new(), |mut acc, (index, &depth)| { + if acc.get(&(depth as usize)).is_none() { + let branch_ebb = builder.create_ebb(); + builder.insert_jump_table_entry(jt, index, branch_ebb); + acc.insert(depth as usize, branch_ebb); + return acc; + }; + let branch_ebb = acc.get(&(depth as usize)).unwrap().clone(); + builder.insert_jump_table_entry(jt, index, branch_ebb); + acc + }); + builder.ins().br_table(val, jt); + let default_ebb = control_stack[control_stack.len() - 1 - (default as usize)] + .br_destination(); + builder.ins().jump(default_ebb, jump_args.as_slice()); + stack.extend(jump_args.clone()); + for (depth, dest_ebb) in dest_ebbs { + builder.switch_to_block(dest_ebb, &[]); + builder.seal_block(dest_ebb); + let i = control_stack.len() - 1 - (depth as usize); + let frame = &mut control_stack[i]; + let real_dest_ebb = frame.br_destination(); + builder.ins().jump(real_dest_ebb, jump_args.as_slice()); + frame.set_reachable(); + } + state.real_unreachable_stack_depth = 1 + min_depth as usize; + } else { + let ebb = control_stack[control_stack.len() - 1 - (default as usize)] + .br_destination(); + builder.ins().jump(ebb, jump_args.as_slice()); + stack.extend(jump_args); + state.real_unreachable_stack_depth = 1 + min_depth as usize; + } + } + } + Operator::Return => { + let return_count = sig.return_types.len(); + let cut_index = stack.len() - return_count; + let return_args = stack.split_off(cut_index); + builder.ins().return_(return_args.as_slice()); + state.last_inst_return = true; + state.real_unreachable_stack_depth = 1; + } + /************************************ Calls **************************************** + * The call instructions pop off their arguments from the stack and append their + * return values to it. `call_indirect` needs runtime support because there is an + * argument referring to an index in the external functions table of the module. + ************************************************************************************/ + Operator::Call { function_index } => { + let args_num = args_count(function_index as usize, functions, signatures); + let cut_index = stack.len() - args_num; + let call_args = stack.split_off(cut_index); + let internal_function_index = find_function_import(function_index as usize, + builder, + func_imports, + functions, + exports, + signatures); + let call_inst = builder + .ins() + .call(internal_function_index, call_args.as_slice()); + let ret_values = builder.inst_results(call_inst); + for val in ret_values { + stack.push(*val); + } + } + Operator::CallIndirect { + index, + table_index: _, + } => { + // index is the index of the function's signature and table_index is the index + // of the table to search the function in + // TODO: have runtime support for tables + let sigref = find_signature_import(index as usize, builder, func_imports, signatures); + let args_num = builder.signature(sigref).unwrap().argument_types.len(); + let index_val = stack.pop().unwrap(); + let cut_index = stack.len() - args_num; + let call_args = stack.split_off(cut_index); + let ret_values = + runtime.translate_call_indirect(builder, sigref, index_val, call_args.as_slice()); + for val in ret_values { + stack.push(*val); + } + } + /******************************* Memory management *********************************** + * Memory management is handled by runtime. It is usually translated into calls to + * special functions. + ************************************************************************************/ + Operator::GrowMemory { reserved: _ } => { + let val = stack.pop().unwrap(); + stack.push(runtime.translate_grow_memory(builder, val)); + } + Operator::CurrentMemory { reserved: _ } => { + stack.push(runtime.translate_current_memory(builder)); + } + /******************************* Load instructions *********************************** + * Wasm specifies an integer alignment flag but we drop it in Cretonne. + * The memory base address is provided by the runtime. + * TODO: differentiate between 32 bit and 64 bit architecture, to put the uextend or not + ************************************************************************************/ + Operator::I32Load8U { memory_immediate: MemoryImmediate { flags: _, offset } } => { + let address_i32 = stack.pop().unwrap(); + let base = runtime.translate_memory_base_address(builder, 0); + let address_i64 = builder.ins().uextend(I64, address_i32); + let addr = builder.ins().iadd(base, address_i64); + let memflags = MemFlags::new(); + let memoffset = Offset32::new(offset as i32); + stack.push(builder.ins().uload8(I32, memflags, addr, memoffset)) + } + Operator::I32Load16U { memory_immediate: MemoryImmediate { flags: _, offset } } => { + let address_i32 = stack.pop().unwrap(); + let base = runtime.translate_memory_base_address(builder, 0); + let address_i64 = builder.ins().uextend(I64, address_i32); + let addr = builder.ins().iadd(base, address_i64); + let memflags = MemFlags::new(); + let memoffset = Offset32::new(offset as i32); + stack.push(builder.ins().uload8(I32, memflags, addr, memoffset)) + } + Operator::I32Load8S { memory_immediate: MemoryImmediate { flags: _, offset } } => { + let address_i32 = stack.pop().unwrap(); + let base = runtime.translate_memory_base_address(builder, 0); + let address_i64 = builder.ins().uextend(I64, address_i32); + let addr = builder.ins().iadd(base, address_i64); + let memflags = MemFlags::new(); + let memoffset = Offset32::new(offset as i32); + stack.push(builder.ins().sload8(I32, memflags, addr, memoffset)) + } + Operator::I32Load16S { memory_immediate: MemoryImmediate { flags: _, offset } } => { + let address_i32 = stack.pop().unwrap(); + let base = runtime.translate_memory_base_address(builder, 0); + let address_i64 = builder.ins().uextend(I64, address_i32); + let addr = builder.ins().iadd(base, address_i64); + let memflags = MemFlags::new(); + let memoffset = Offset32::new(offset as i32); + stack.push(builder.ins().sload8(I32, memflags, addr, memoffset)) + } + Operator::I64Load8U { memory_immediate: MemoryImmediate { flags: _, offset } } => { + let address_i32 = stack.pop().unwrap(); + let base = runtime.translate_memory_base_address(builder, 0); + let address_i64 = builder.ins().uextend(I64, address_i32); + let addr = builder.ins().iadd(base, address_i64); + let memflags = MemFlags::new(); + let memoffset = Offset32::new(offset as i32); + stack.push(builder.ins().uload8(I64, memflags, addr, memoffset)) + } + Operator::I64Load16U { memory_immediate: MemoryImmediate { flags: _, offset } } => { + let address_i32 = stack.pop().unwrap(); + let base = runtime.translate_memory_base_address(builder, 0); + let address_i64 = builder.ins().uextend(I64, address_i32); + let addr = builder.ins().iadd(base, address_i64); + let memflags = MemFlags::new(); + let memoffset = Offset32::new(offset as i32); + stack.push(builder.ins().uload16(I64, memflags, addr, memoffset)) + } + Operator::I64Load8S { memory_immediate: MemoryImmediate { flags: _, offset } } => { + let address_i32 = stack.pop().unwrap(); + let base = runtime.translate_memory_base_address(builder, 0); + let address_i64 = builder.ins().uextend(I64, address_i32); + let addr = builder.ins().iadd(base, address_i64); + let memflags = MemFlags::new(); + let memoffset = Offset32::new(offset as i32); + stack.push(builder.ins().sload8(I64, memflags, addr, memoffset)) + } + Operator::I64Load16S { memory_immediate: MemoryImmediate { flags: _, offset } } => { + let address_i32 = stack.pop().unwrap(); + let base = runtime.translate_memory_base_address(builder, 0); + let address_i64 = builder.ins().uextend(I64, address_i32); + let addr = builder.ins().iadd(base, address_i64); + let memflags = MemFlags::new(); + let memoffset = Offset32::new(offset as i32); + stack.push(builder.ins().sload16(I64, memflags, addr, memoffset)) + } + Operator::I64Load32S { memory_immediate: MemoryImmediate { flags: _, offset } } => { + let address_i32 = stack.pop().unwrap(); + let base = runtime.translate_memory_base_address(builder, 0); + let address_i64 = builder.ins().uextend(I64, address_i32); + let addr = builder.ins().iadd(base, address_i64); + let memflags = MemFlags::new(); + let memoffset = Offset32::new(offset as i32); + stack.push(builder.ins().sload32(memflags, addr, memoffset)) + } + Operator::I64Load32U { memory_immediate: MemoryImmediate { flags: _, offset } } => { + let address_i32 = stack.pop().unwrap(); + let base = runtime.translate_memory_base_address(builder, 0); + let address_i64 = builder.ins().uextend(I64, address_i32); + let addr = builder.ins().iadd(base, address_i64); + let memflags = MemFlags::new(); + let memoffset = Offset32::new(offset as i32); + stack.push(builder.ins().uload32(memflags, addr, memoffset)) + } + Operator::I32Load { memory_immediate: MemoryImmediate { flags: _, offset } } => { + let address_i32 = stack.pop().unwrap(); + let base = runtime.translate_memory_base_address(builder, 0); + let address_i64 = builder.ins().uextend(I64, address_i32); + let addr = builder.ins().iadd(base, address_i64); + let memflags = MemFlags::new(); + let memoffset = Offset32::new(offset as i32); + stack.push(builder.ins().load(I32, memflags, addr, memoffset)) + } + Operator::F32Load { memory_immediate: MemoryImmediate { flags: _, offset } } => { + let address_i32 = stack.pop().unwrap(); + let base = runtime.translate_memory_base_address(builder, 0); + let address_i64 = builder.ins().uextend(I64, address_i32); + let addr = builder.ins().iadd(base, address_i64); + let memflags = MemFlags::new(); + let memoffset = Offset32::new(offset as i32); + stack.push(builder.ins().load(F32, memflags, addr, memoffset)) + } + Operator::I64Load { memory_immediate: MemoryImmediate { flags: _, offset } } => { + let address_i32 = stack.pop().unwrap(); + let base = runtime.translate_memory_base_address(builder, 0); + let address_i64 = builder.ins().uextend(I64, address_i32); + let addr = builder.ins().iadd(base, address_i64); + let memflags = MemFlags::new(); + let memoffset = Offset32::new(offset as i32); + stack.push(builder.ins().load(I64, memflags, addr, memoffset)) + } + Operator::F64Load { memory_immediate: MemoryImmediate { flags: _, offset } } => { + let address_i32 = stack.pop().unwrap(); + let base = runtime.translate_memory_base_address(builder, 0); + let address_i64 = builder.ins().uextend(I64, address_i32); + let addr = builder.ins().iadd(base, address_i64); + let memflags = MemFlags::new(); + let memoffset = Offset32::new(offset as i32); + stack.push(builder.ins().load(F64, memflags, addr, memoffset)) + } + /****************************** Store instructions *********************************** + * Wasm specifies an integer alignment flag but we drop it in Cretonne. + * The memory base address is provided by the runtime. + * TODO: differentiate between 32 bit and 64 bit architecture, to put the uextend or not + ************************************************************************************/ + Operator::I32Store { memory_immediate: MemoryImmediate { flags: _, offset } } | + Operator::I64Store { memory_immediate: MemoryImmediate { flags: _, offset } } | + Operator::F32Store { memory_immediate: MemoryImmediate { flags: _, offset } } | + Operator::F64Store { memory_immediate: MemoryImmediate { flags: _, offset } } => { + let val = stack.pop().unwrap(); + let address_i32 = stack.pop().unwrap(); + let base = runtime.translate_memory_base_address(builder, 0); + let address_i64 = builder.ins().uextend(I64, address_i32); + let addr = builder.ins().iadd(base, address_i64); + let memflags = MemFlags::new(); + let memoffset = Offset32::new(offset as i32); + builder.ins().store(memflags, val, addr, memoffset); + } + Operator::I32Store8 { memory_immediate: MemoryImmediate { flags: _, offset } } | + Operator::I64Store8 { memory_immediate: MemoryImmediate { flags: _, offset } } => { + let val = stack.pop().unwrap(); + let address_i32 = stack.pop().unwrap(); + let base = runtime.translate_memory_base_address(builder, 0); + let address_i64 = builder.ins().uextend(I64, address_i32); + let addr = builder.ins().iadd(base, address_i64); + let memflags = MemFlags::new(); + let memoffset = Offset32::new(offset as i32); + builder.ins().istore8(memflags, val, addr, memoffset); + } + Operator::I32Store16 { memory_immediate: MemoryImmediate { flags: _, offset } } | + Operator::I64Store16 { memory_immediate: MemoryImmediate { flags: _, offset } } => { + let val = stack.pop().unwrap(); + let address_i32 = stack.pop().unwrap(); + let base = runtime.translate_memory_base_address(builder, 0); + let address_i64 = builder.ins().uextend(I64, address_i32); + let addr = builder.ins().iadd(base, address_i64); + let memflags = MemFlags::new(); + let memoffset = Offset32::new(offset as i32); + builder.ins().istore16(memflags, val, addr, memoffset); + } + Operator::I64Store32 { memory_immediate: MemoryImmediate { flags: _, offset } } => { + let val = stack.pop().unwrap(); + let address_i32 = stack.pop().unwrap(); + let base = runtime.translate_memory_base_address(builder, 0); + let address_i64 = builder.ins().uextend(I64, address_i32); + let addr = builder.ins().iadd(base, address_i64); + let memflags = MemFlags::new(); + let memoffset = Offset32::new(offset as i32); + builder.ins().istore32(memflags, val, addr, memoffset); + } + /****************************** Nullary Operators ************************************/ + Operator::I32Const { value } => stack.push(builder.ins().iconst(I32, value as i64)), + Operator::I64Const { value } => stack.push(builder.ins().iconst(I64, value)), + Operator::F32Const { value } => { + stack.push(builder.ins().f32const(f32_translation(value))); + } + Operator::F64Const { value } => { + stack.push(builder.ins().f64const(f64_translation(value))); + } + /******************************* Unary Operators *************************************/ + Operator::I32Clz => { + let arg = stack.pop().unwrap(); + let val = builder.ins().clz(arg); + stack.push(builder.ins().sextend(I32, val)); + } + Operator::I64Clz => { + let arg = stack.pop().unwrap(); + let val = builder.ins().clz(arg); + stack.push(builder.ins().sextend(I64, val)); + } + Operator::I32Ctz => { + let val = stack.pop().unwrap(); + let short_res = builder.ins().ctz(val); + stack.push(builder.ins().sextend(I32, short_res)); + } + Operator::I64Ctz => { + let val = stack.pop().unwrap(); + let short_res = builder.ins().ctz(val); + stack.push(builder.ins().sextend(I64, short_res)); + } + Operator::I32Popcnt => { + let arg = stack.pop().unwrap(); + let val = builder.ins().popcnt(arg); + stack.push(builder.ins().sextend(I32, val)); + } + Operator::I64Popcnt => { + let arg = stack.pop().unwrap(); + let val = builder.ins().popcnt(arg); + stack.push(builder.ins().sextend(I64, val)); + } + Operator::I64ExtendSI32 => { + let val = stack.pop().unwrap(); + stack.push(builder.ins().sextend(I64, val)); + } + Operator::I64ExtendUI32 => { + let val = stack.pop().unwrap(); + stack.push(builder.ins().uextend(I64, val)); + } + Operator::I32WrapI64 => { + let val = stack.pop().unwrap(); + stack.push(builder.ins().ireduce(I32, val)); + } + Operator::F32Sqrt | + Operator::F64Sqrt => { + let arg = stack.pop().unwrap(); + stack.push(builder.ins().sqrt(arg)); + } + Operator::F32Ceil | + Operator::F64Ceil => { + let arg = stack.pop().unwrap(); + stack.push(builder.ins().ceil(arg)); + } + Operator::F32Floor | + Operator::F64Floor => { + let arg = stack.pop().unwrap(); + stack.push(builder.ins().floor(arg)); + } + Operator::F32Trunc | + Operator::F64Trunc => { + let arg = stack.pop().unwrap(); + stack.push(builder.ins().trunc(arg)); + } + Operator::F32Nearest | + Operator::F64Nearest => { + let arg = stack.pop().unwrap(); + stack.push(builder.ins().nearest(arg)); + } + Operator::F32Abs | Operator::F64Abs => { + let val = stack.pop().unwrap(); + stack.push(builder.ins().fabs(val)); + } + Operator::F32Neg | Operator::F64Neg => { + let arg = stack.pop().unwrap(); + stack.push(builder.ins().fneg(arg)); + } + Operator::F64ConvertUI64 | + Operator::F64ConvertUI32 => { + let val = stack.pop().unwrap(); + stack.push(builder.ins().fcvt_from_uint(F64, val)); + } + Operator::F64ConvertSI64 | + Operator::F64ConvertSI32 => { + let val = stack.pop().unwrap(); + stack.push(builder.ins().fcvt_from_sint(F64, val)); + } + Operator::F32ConvertSI64 | + Operator::F32ConvertSI32 => { + let val = stack.pop().unwrap(); + stack.push(builder.ins().fcvt_from_sint(F32, val)); + } + Operator::F32ConvertUI64 | + Operator::F32ConvertUI32 => { + let val = stack.pop().unwrap(); + stack.push(builder.ins().fcvt_from_uint(F32, val)); + } + Operator::F64PromoteF32 => { + let val = stack.pop().unwrap(); + stack.push(builder.ins().fpromote(F64, val)); + } + Operator::F32DemoteF64 => { + let val = stack.pop().unwrap(); + stack.push(builder.ins().fdemote(F32, val)); + } + Operator::I64TruncSF64 | + Operator::I64TruncSF32 => { + let val = stack.pop().unwrap(); + stack.push(builder.ins().fcvt_to_sint(I64, val)); + } + Operator::I32TruncSF64 | + Operator::I32TruncSF32 => { + let val = stack.pop().unwrap(); + stack.push(builder.ins().fcvt_to_sint(I32, val)); + } + Operator::I64TruncUF64 | + Operator::I64TruncUF32 => { + let val = stack.pop().unwrap(); + stack.push(builder.ins().fcvt_to_uint(I64, val)); + } + Operator::I32TruncUF64 | + Operator::I32TruncUF32 => { + let val = stack.pop().unwrap(); + stack.push(builder.ins().fcvt_to_uint(I32, val)); + } + Operator::F32ReinterpretI32 => { + let val = stack.pop().unwrap(); + stack.push(builder.ins().bitcast(F32, val)); + } + Operator::F64ReinterpretI64 => { + let val = stack.pop().unwrap(); + stack.push(builder.ins().bitcast(F64, val)); + } + Operator::I32ReinterpretF32 => { + let val = stack.pop().unwrap(); + stack.push(builder.ins().bitcast(I32, val)); + } + Operator::I64ReinterpretF64 => { + let val = stack.pop().unwrap(); + stack.push(builder.ins().bitcast(I64, val)); + } + /****************************** Binary Operators ************************************/ + Operator::I32Add | Operator::I64Add => { + let arg2 = stack.pop().unwrap(); + let arg1 = stack.pop().unwrap(); + stack.push(builder.ins().iadd(arg1, arg2)); + } + Operator::I32And | Operator::I64And => { + let arg2 = stack.pop().unwrap(); + let arg1 = stack.pop().unwrap(); + stack.push(builder.ins().band(arg1, arg2)); + } + Operator::I32Or | Operator::I64Or => { + let arg2 = stack.pop().unwrap(); + let arg1 = stack.pop().unwrap(); + stack.push(builder.ins().bor(arg1, arg2)); + } + Operator::I32Xor | Operator::I64Xor => { + let arg2 = stack.pop().unwrap(); + let arg1 = stack.pop().unwrap(); + stack.push(builder.ins().bxor(arg1, arg2)); + } + Operator::I32Shl | Operator::I64Shl => { + let arg2 = stack.pop().unwrap(); + let arg1 = stack.pop().unwrap(); + stack.push(builder.ins().ishl(arg1, arg2)); + } + Operator::I32ShrS | + Operator::I64ShrS => { + let arg2 = stack.pop().unwrap(); + let arg1 = stack.pop().unwrap(); + stack.push(builder.ins().sshr(arg1, arg2)); + } + Operator::I32ShrU | + Operator::I64ShrU => { + let arg2 = stack.pop().unwrap(); + let arg1 = stack.pop().unwrap(); + stack.push(builder.ins().ushr(arg1, arg2)); + } + Operator::I32Rotl | + Operator::I64Rotl => { + let arg2 = stack.pop().unwrap(); + let arg1 = stack.pop().unwrap(); + stack.push(builder.ins().rotl(arg1, arg2)); + } + Operator::I32Rotr | + Operator::I64Rotr => { + let arg2 = stack.pop().unwrap(); + let arg1 = stack.pop().unwrap(); + stack.push(builder.ins().rotr(arg1, arg2)); + } + Operator::F32Add | Operator::F64Add => { + let arg2 = stack.pop().unwrap(); + let arg1 = stack.pop().unwrap(); + stack.push(builder.ins().fadd(arg1, arg2)); + } + Operator::I32Sub | Operator::I64Sub => { + let arg2 = stack.pop().unwrap(); + let arg1 = stack.pop().unwrap(); + stack.push(builder.ins().isub(arg1, arg2)); + } + Operator::F32Sub | Operator::F64Sub => { + let arg2 = stack.pop().unwrap(); + let arg1 = stack.pop().unwrap(); + stack.push(builder.ins().fsub(arg1, arg2)); + } + Operator::I32Mul | Operator::I64Mul => { + let arg2 = stack.pop().unwrap(); + let arg1 = stack.pop().unwrap(); + stack.push(builder.ins().imul(arg1, arg2)); + } + Operator::F32Mul | Operator::F64Mul => { + let arg2 = stack.pop().unwrap(); + let arg1 = stack.pop().unwrap(); + stack.push(builder.ins().fmul(arg1, arg2)); + } + Operator::F32Div | Operator::F64Div => { + let arg2 = stack.pop().unwrap(); + let arg1 = stack.pop().unwrap(); + stack.push(builder.ins().fdiv(arg1, arg2)); + } + Operator::I32DivS | + Operator::I64DivS => { + let arg2 = stack.pop().unwrap(); + let arg1 = stack.pop().unwrap(); + stack.push(builder.ins().sdiv(arg1, arg2)); + } + Operator::I32DivU | + Operator::I64DivU => { + let arg2 = stack.pop().unwrap(); + let arg1 = stack.pop().unwrap(); + stack.push(builder.ins().udiv(arg1, arg2)); + } + Operator::I32RemS | + Operator::I64RemS => { + let arg2 = stack.pop().unwrap(); + let arg1 = stack.pop().unwrap(); + stack.push(builder.ins().srem(arg1, arg2)); + } + Operator::I32RemU | + Operator::I64RemU => { + let arg2 = stack.pop().unwrap(); + let arg1 = stack.pop().unwrap(); + stack.push(builder.ins().urem(arg1, arg2)); + } + Operator::F32Min | Operator::F64Min => { + let arg2 = stack.pop().unwrap(); + let arg1 = stack.pop().unwrap(); + stack.push(builder.ins().fmin(arg1, arg2)); + } + Operator::F32Max | Operator::F64Max => { + let arg2 = stack.pop().unwrap(); + let arg1 = stack.pop().unwrap(); + stack.push(builder.ins().fmax(arg1, arg2)); + } + Operator::F32Copysign | + Operator::F64Copysign => { + let arg2 = stack.pop().unwrap(); + let arg1 = stack.pop().unwrap(); + stack.push(builder.ins().fcopysign(arg1, arg2)); + } + /**************************** Comparison Operators **********************************/ + Operator::I32LtS | Operator::I64LtS => { + let arg2 = stack.pop().unwrap(); + let arg1 = stack.pop().unwrap(); + let val = builder.ins().icmp(IntCC::SignedLessThan, arg1, arg2); + stack.push(builder.ins().bint(I32, val)); + } + Operator::I32LtU | Operator::I64LtU => { + let arg2 = stack.pop().unwrap(); + let arg1 = stack.pop().unwrap(); + let val = builder.ins().icmp(IntCC::UnsignedLessThan, arg1, arg2); + stack.push(builder.ins().bint(I32, val)); + } + Operator::I32LeS | Operator::I64LeS => { + let arg2 = stack.pop().unwrap(); + let arg1 = stack.pop().unwrap(); + let val = builder.ins().icmp(IntCC::SignedLessThanOrEqual, arg1, arg2); + stack.push(builder.ins().bint(I32, val)); + } + Operator::I32LeU | Operator::I64LeU => { + let arg2 = stack.pop().unwrap(); + let arg1 = stack.pop().unwrap(); + let val = builder + .ins() + .icmp(IntCC::UnsignedLessThanOrEqual, arg1, arg2); + stack.push(builder.ins().bint(I32, val)); + } + Operator::I32GtS | Operator::I64GtS => { + let arg2 = stack.pop().unwrap(); + let arg1 = stack.pop().unwrap(); + let val = builder.ins().icmp(IntCC::SignedGreaterThan, arg1, arg2); + stack.push(builder.ins().bint(I32, val)); + } + Operator::I32GtU | Operator::I64GtU => { + let arg2 = stack.pop().unwrap(); + let arg1 = stack.pop().unwrap(); + let val = builder.ins().icmp(IntCC::UnsignedGreaterThan, arg1, arg2); + stack.push(builder.ins().bint(I32, val)); + } + Operator::I32GeS | Operator::I64GeS => { + let arg2 = stack.pop().unwrap(); + let arg1 = stack.pop().unwrap(); + let val = builder + .ins() + .icmp(IntCC::SignedGreaterThanOrEqual, arg1, arg2); + stack.push(builder.ins().bint(I32, val)); + } + Operator::I32GeU | Operator::I64GeU => { + let arg2 = stack.pop().unwrap(); + let arg1 = stack.pop().unwrap(); + let val = builder + .ins() + .icmp(IntCC::UnsignedGreaterThanOrEqual, arg1, arg2); + stack.push(builder.ins().bint(I32, val)); + } + Operator::I32Eqz | Operator::I64Eqz => { + let arg = stack.pop().unwrap(); + let val = builder.ins().icmp_imm(IntCC::Equal, arg, 0); + stack.push(builder.ins().bint(I32, val)); + } + Operator::I32Eq | Operator::I64Eq => { + let arg2 = stack.pop().unwrap(); + let arg1 = stack.pop().unwrap(); + let val = builder.ins().icmp(IntCC::Equal, arg1, arg2); + stack.push(builder.ins().bint(I32, val)); + } + Operator::F32Eq | Operator::F64Eq => { + let arg2 = stack.pop().unwrap(); + let arg1 = stack.pop().unwrap(); + let val = builder.ins().fcmp(FloatCC::Equal, arg1, arg2); + stack.push(builder.ins().bint(I32, val)); + } + Operator::I32Ne | Operator::I64Ne => { + let arg2 = stack.pop().unwrap(); + let arg1 = stack.pop().unwrap(); + let val = builder.ins().icmp(IntCC::NotEqual, arg1, arg2); + stack.push(builder.ins().bint(I32, val)); + } + Operator::F32Ne | Operator::F64Ne => { + let arg2 = stack.pop().unwrap(); + let arg1 = stack.pop().unwrap(); + let val = builder.ins().fcmp(FloatCC::NotEqual, arg1, arg2); + stack.push(builder.ins().bint(I32, val)); + } + Operator::F32Gt | Operator::F64Gt => { + let arg2 = stack.pop().unwrap(); + let arg1 = stack.pop().unwrap(); + let val = builder.ins().fcmp(FloatCC::GreaterThan, arg1, arg2); + stack.push(builder.ins().bint(I32, val)); + } + Operator::F32Ge | Operator::F64Ge => { + let arg2 = stack.pop().unwrap(); + let arg1 = stack.pop().unwrap(); + let val = builder.ins().fcmp(FloatCC::GreaterThanOrEqual, arg1, arg2); + stack.push(builder.ins().bint(I32, val)); + } + Operator::F32Lt | Operator::F64Lt => { + let arg2 = stack.pop().unwrap(); + let arg1 = stack.pop().unwrap(); + let val = builder.ins().fcmp(FloatCC::LessThan, arg1, arg2); + stack.push(builder.ins().bint(I32, val)); + } + Operator::F32Le | Operator::F64Le => { + let arg2 = stack.pop().unwrap(); + let arg1 = stack.pop().unwrap(); + let val = builder.ins().fcmp(FloatCC::LessThanOrEqual, arg1, arg2); + stack.push(builder.ins().bint(I32, val)); + } + } +} + +/// Deals with a Wasm instruction located in an unreachable portion of the code. Most of them +/// are dropped but special ones like `End` or `Else` signal the potential end of the unreachable +/// portion so the translation state muts be updated accordingly. +fn translate_unreachable_operator(op: &Operator, + builder: &mut FunctionBuilder, + stack: &mut Vec, + control_stack: &mut Vec, + state: &mut TranslationState) { + // We don't translate because the code is unreachable + // Nevertheless we have to record a phantom stack for this code + // to know when the unreachable code ends + match *op { + Operator::If { ty: _ } | + Operator::Loop { ty: _ } | + Operator::Block { ty: _ } => { + state.phantom_unreachable_stack_depth += 1; + } + Operator::End => { + if state.phantom_unreachable_stack_depth > 0 { + state.phantom_unreachable_stack_depth -= 1; + } else { + // This End corresponds to a real control stack frame + // We switch to the destination block but we don't insert + // a jump instruction since the code is still unreachable + let frame = control_stack.pop().unwrap(); + + builder.switch_to_block(frame.following_code(), &[]); + builder.seal_block(frame.following_code()); + match frame { + // If it is a loop we also have to seal the body loop block + ControlStackFrame::Loop { header, .. } => builder.seal_block(header), + // If it is a if then the code after is reachable again + ControlStackFrame::If { .. } => { + state.real_unreachable_stack_depth = 1; + } + _ => {} + } + if frame.is_reachable() { + state.real_unreachable_stack_depth = 1; + } + // Now we have to split off the stack the values not used + // by unreachable code that hasn't been translated + stack.truncate(frame.original_stack_size()); + // And add the return values of the block but only if the next block is reachble + // (which corresponds to testing if the stack depth is 1) + if state.real_unreachable_stack_depth == 1 { + stack.extend_from_slice(builder.ebb_args(frame.following_code())); + } + state.real_unreachable_stack_depth -= 1; + state.last_inst_return = false; + } + } + Operator::Else => { + if state.phantom_unreachable_stack_depth > 0 { + // This is part of a phantom if-then-else, we do nothing + } else { + // Encountering an real else means that the code in the else + // clause is reachable again + let (branch_inst, original_stack_size) = match &control_stack[control_stack.len() - + 1] { + &ControlStackFrame::If { + branch_inst, + original_stack_size, + .. + } => (branch_inst, original_stack_size), + _ => panic!("should not happen"), + }; + // We change the target of the branch instruction + let else_ebb = builder.create_ebb(); + builder.change_jump_destination(branch_inst, else_ebb); + builder.seal_block(else_ebb); + builder.switch_to_block(else_ebb, &[]); + // Now we have to split off the stack the values not used + // by unreachable code that hasn't been translated + stack.truncate(original_stack_size); + state.real_unreachable_stack_depth = 0; + state.last_inst_return = false; + } + } + _ => { + // We don't translate because this is unreachable code + } + } +} + +fn args_count(index: FunctionIndex, + functions: &Vec, + signatures: &Vec) + -> usize { + signatures[functions[index] as usize].argument_types.len() +} + +// Given a index in the function index space, search for it in the function imports and if it is +// not there add it to the function imports. +fn find_function_import(index: FunctionIndex, + builder: &mut FunctionBuilder, + func_imports: &mut FunctionImports, + functions: &Vec, + exports: &Option>, + signatures: &Vec) + -> FuncRef { + match func_imports.functions.get(&index) { + Some(local_index) => return *local_index, + None => {} + } + // We have to import the function + let sig_index = functions[index]; + match func_imports.signatures.get(&(sig_index as usize)) { + Some(local_sig_index) => { + let local_func_index = + builder.import_function(ExtFuncData { + name: match exports { + &None => FunctionName::new(""), + &Some(ref exports) => { + match exports.get(&index) { + None => FunctionName::new(""), + Some(name) => { + FunctionName::new(name.clone()) + } + } + } + }, + signature: *local_sig_index, + }); + func_imports.functions.insert(index, local_func_index); + return local_func_index; + } + None => {} + }; + // We have to import the signature + let sig_local_index = builder.import_signature(signatures[sig_index as usize].clone()); + func_imports + .signatures + .insert(sig_index as usize, sig_local_index); + let local_func_index = + builder.import_function(ExtFuncData { + name: match exports { + &None => FunctionName::new(""), + &Some(ref exports) => { + match exports.get(&index) { + None => FunctionName::new(""), + Some(name) => FunctionName::new(name.clone()), + } + } + }, + signature: sig_local_index, + }); + func_imports.functions.insert(index, local_func_index); + local_func_index +} + +fn find_signature_import(sig_index: SignatureIndex, + builder: &mut FunctionBuilder, + func_imports: &mut FunctionImports, + signatures: &Vec) + -> SigRef { + match func_imports.signatures.get(&(sig_index as usize)) { + Some(local_sig_index) => return *local_sig_index, + None => {} + } + let sig_local_index = builder.import_signature(signatures[sig_index as usize].clone()); + func_imports + .signatures + .insert(sig_index as usize, sig_local_index); + sig_local_index +} diff --git a/lib/wasm2cretonne/src/lib.rs b/lib/wasm2cretonne/src/lib.rs new file mode 100644 index 0000000000..5006e5c9aa --- /dev/null +++ b/lib/wasm2cretonne/src/lib.rs @@ -0,0 +1,27 @@ +//! Performs the translation from a wasm module in binary format to the in-memory representation +//! of the Cretonne IL. More particularly, it translates the code of all the functions bodies and +//! interacts with a runtime implementing the [`WasmRuntime`](trait.WasmRuntime.html) trait to +//! deal with tables, globals and linear memory. +//! +//! The crate provides a `DummyRuntime` trait that will allow to translate the code of the +//! functions but will fail at execution. You should use +//! [`wasmstandalone::StandaloneRuntime`](../wasmstandalone/struct.StandaloneRuntime.html) to be +//! able to execute the translated code. +//! +//! The main function of this module is [`translate_module`](fn.translate_module.html). + +extern crate wasmparser; +extern crate cton_frontend; +extern crate cretonne; + +mod module_translator; +mod translation_utils; +mod code_translator; +mod runtime; +mod sections_translator; + +pub use module_translator::{translate_module, TranslationResult, FunctionTranslation, + ImportMappings}; +pub use runtime::{WasmRuntime, DummyRuntime}; +pub use translation_utils::{Local, FunctionIndex, GlobalIndex, TableIndex, MemoryIndex, RawByte, + MemoryAddress, SignatureIndex, Global, GlobalInit, Table, Memory}; diff --git a/lib/wasm2cretonne/src/module_translator.rs b/lib/wasm2cretonne/src/module_translator.rs new file mode 100644 index 0000000000..1c22655300 --- /dev/null +++ b/lib/wasm2cretonne/src/module_translator.rs @@ -0,0 +1,288 @@ +//! Translation skeletton that traverses the whole WebAssembly module and call helper functions +//! to deal with each part of it. +use wasmparser::{ParserState, SectionCode, ParserInput, Parser, WasmDecoder}; +use sections_translator::{SectionParsingError, parse_function_signatures, parse_import_section, + parse_function_section, parse_export_section, parse_memory_section, + parse_global_section, parse_table_section, parse_elements_section, + parse_data_section}; +use translation_utils::{type_to_type, Import, SignatureIndex, FunctionIndex, invert_hashmaps}; +use cretonne::ir::{Function, Type, FuncRef, SigRef}; +use code_translator::translate_function_body; +use cton_frontend::ILBuilder; +use std::collections::HashMap; +use runtime::WasmRuntime; + +/// Output of the [`translate_module`](fn.translate_module.html) function. Contains the translated +/// functions and when present the index of the function defined as `start` of the module. +pub struct TranslationResult { + pub functions: Vec, + pub start_index: Option, +} + +/// A function in a WebAssembly module can be either imported, or defined inside it. If it is +/// defined inside it, then the translation in Cretonne IL is available as well as the mappings +/// between Cretonne imports and indexes in the function index space. +#[derive(Clone)] +pub enum FunctionTranslation { + Code { + il: Function, + imports: ImportMappings, + }, + Import(), +} + +#[derive(Clone,Debug)] +/// Mappings describing the relations between imports of the Cretonne IL functions and the +/// functions in the WebAssembly module. +pub struct ImportMappings { + /// Find the index of a function in the WebAssembly module thanks to a `FuncRef`. + pub functions: HashMap, + /// Find the index of a signature in the WebAssembly module thanks to a `SigRef`. + pub signatures: HashMap, +} + +impl ImportMappings { + pub fn new() -> ImportMappings { + ImportMappings { + functions: HashMap::new(), + signatures: HashMap::new(), + } + } +} + +/// Translate a sequence of bytes forming a valid Wasm binary into a list of valid Cretonne IL +/// [`Function`](../cretonne/ir/function/struct.Function.html). +/// Returns the functions and also the mappings for imported functions and signature between the +/// indexes in the wasm module and the indexes inside each functions. +pub fn translate_module(data: &Vec, + runtime: &mut WasmRuntime) + -> Result { + let mut parser = Parser::new(data.as_slice()); + match *parser.read() { + ParserState::BeginWasm { .. } => {} + ref s @ _ => panic!("modules should begin properly: {:?}", s), + } + let mut signatures = None; + let mut functions: Option> = None; + let mut globals = Vec::new(); + let mut exports: Option> = None; + let mut next_input = ParserInput::Default; + let mut function_index: FunctionIndex = 0; + let mut function_imports_count = 0; + let mut start_index: Option = None; + loop { + match *parser.read_with_input(next_input) { + ParserState::BeginSection { code: SectionCode::Type, .. } => { + match parse_function_signatures(&mut parser) { + Ok(sigs) => signatures = Some(sigs), + Err(SectionParsingError::WrongSectionContent(s)) => { + return Err(format!("wrong content in the type section: {}", s)) + } + }; + next_input = ParserInput::Default; + } + ParserState::BeginSection { code: SectionCode::Import, .. } => { + match parse_import_section(&mut parser) { + Ok(imps) => { + for import in imps { + match import { + Import::Function { sig_index } => { + functions = match functions { + None => Some(vec![sig_index as SignatureIndex]), + Some(mut funcs) => { + funcs.push(sig_index as SignatureIndex); + Some(funcs) + } + }; + function_index += 1; + } + Import::Memory(mem) => { + runtime.declare_memory(mem); + } + Import::Global(glob) => { + runtime.declare_global(glob.clone()); + globals.push(glob); + } + Import::Table(tab) => { + runtime.declare_table(tab); + } + } + } + } + Err(SectionParsingError::WrongSectionContent(s)) => { + return Err(format!("wrong content in the import section: {}", s)) + } + } + function_imports_count = function_index; + next_input = ParserInput::Default; + } + ParserState::BeginSection { code: SectionCode::Function, .. } => { + match parse_function_section(&mut parser) { + Ok(funcs) => { + match functions { + None => functions = Some(funcs), + Some(ref mut imps) => imps.extend(funcs), + } + } + Err(SectionParsingError::WrongSectionContent(s)) => { + return Err(format!("wrong content in the function section: {}", s)) + } + } + next_input = ParserInput::Default; + } + ParserState::BeginSection { code: SectionCode::Table, .. } => { + match parse_table_section(&mut parser, runtime) { + Ok(()) => (), + Err(SectionParsingError::WrongSectionContent(s)) => { + return Err(format!("wrong content in the table section: {}", s)) + } + } + } + ParserState::BeginSection { code: SectionCode::Memory, .. } => { + match parse_memory_section(&mut parser) { + Ok(mems) => { + for mem in mems { + runtime.declare_memory(mem); + } + } + Err(SectionParsingError::WrongSectionContent(s)) => { + return Err(format!("wrong content in the memory section: {}", s)) + } + } + next_input = ParserInput::Default; + } + ParserState::BeginSection { code: SectionCode::Global, .. } => { + match parse_global_section(&mut parser, runtime) { + Ok(mut globs) => globals.append(&mut globs), + Err(SectionParsingError::WrongSectionContent(s)) => { + return Err(format!("wrong content in the global section: {}", s)) + } + } + next_input = ParserInput::Default; + } + ParserState::BeginSection { code: SectionCode::Export, .. } => { + match parse_export_section(&mut parser) { + Ok(exps) => exports = Some(exps), + Err(SectionParsingError::WrongSectionContent(s)) => { + return Err(format!("wrong content in the export section: {}", s)) + } + } + next_input = ParserInput::Default; + } + ParserState::BeginSection { code: SectionCode::Start, .. } => { + match *parser.read() { + ParserState::StartSectionEntry(index) => { + start_index = Some(index as FunctionIndex) + } + _ => return Err(String::from("wrong content in the start section")), + } + match *parser.read() { + ParserState::EndSection => {} + _ => return Err(String::from("wrong content in the start section")), + } + next_input = ParserInput::Default; + } + ParserState::BeginSection { code: SectionCode::Element, .. } => { + match parse_elements_section(&mut parser, runtime, &globals) { + Ok(()) => (), + Err(SectionParsingError::WrongSectionContent(s)) => { + return Err(format!("wrong content in the element section: {}", s)) + } + } + next_input = ParserInput::Default; + } + ParserState::BeginSection { code: SectionCode::Code, .. } => { + // The code section begins + break; + } + ParserState::EndSection => { + next_input = ParserInput::Default; + } + ParserState::EndWasm => { + return Ok(TranslationResult { + functions: Vec::new(), + start_index: None, + }) + } + ParserState::BeginSection { code: SectionCode::Data, .. } => { + match parse_data_section(&mut parser, runtime, &globals) { + Ok(()) => (), + Err(SectionParsingError::WrongSectionContent(s)) => { + return Err(format!("wrong content in the data section: {}", s)) + } + } + } + _ => return Err(String::from("wrong content in the preamble")), + }; + } + // At this point we've entered the code section + // First we check that we have all that is necessary to translate a function. + let signatures = match signatures { + None => Vec::new(), + Some(sigs) => sigs, + }; + let functions = match functions { + None => return Err(String::from("missing a function section")), + Some(functions) => functions, + }; + let mut il_functions: Vec = Vec::new(); + il_functions.resize(function_imports_count, FunctionTranslation::Import()); + let mut il_builder = ILBuilder::new(); + runtime.begin_translation(); + loop { + let locals: Vec<(usize, Type)> = match *parser.read() { + ParserState::BeginFunctionBody { ref locals, .. } => { + locals + .iter() + .map(|&(index, ref ty)| { + (index as usize, + match type_to_type(ty) { + Ok(ty) => ty, + Err(()) => panic!("unsupported type for local variable"), + }) + }) + .collect() + } + ParserState::EndSection => break, + _ => return Err(String::from(format!("wrong content in code section"))), + }; + let signature = signatures[functions[function_index as usize] as usize].clone(); + match translate_function_body(&mut parser, + function_index, + signature, + &locals, + &exports, + &signatures, + &functions, + &mut il_builder, + runtime) { + Ok((il_func, imports)) => { + il_functions.push(FunctionTranslation::Code { + il: il_func, + imports: invert_hashmaps(imports), + }) + } + Err(s) => return Err(s), + } + function_index += 1; + } + loop { + match *parser.read() { + ParserState::BeginSection { code: SectionCode::Data, .. } => { + match parse_data_section(&mut parser, runtime, &globals) { + Ok(()) => (), + Err(SectionParsingError::WrongSectionContent(s)) => { + return Err(format!("wrong content in the data section: {}", s)) + } + } + } + ParserState::EndWasm => { + return Ok(TranslationResult { + functions: il_functions, + start_index, + }) + } + _ => (), + } + } +} diff --git a/lib/wasm2cretonne/src/runtime/dummy.rs b/lib/wasm2cretonne/src/runtime/dummy.rs new file mode 100644 index 0000000000..5969c0ee8f --- /dev/null +++ b/lib/wasm2cretonne/src/runtime/dummy.rs @@ -0,0 +1,93 @@ +use runtime::WasmRuntime; +use translation_utils::{Local, Global, Memory, Table, GlobalIndex, TableIndex, FunctionIndex, + MemoryIndex}; +use cton_frontend::FunctionBuilder; +use cretonne::ir::{Value, InstBuilder, SigRef}; +use cretonne::ir::immediates::{Ieee32, Ieee64}; +use cretonne::ir::types::*; + +/// This runtime implementation is a "naïve" one, doing essentially nothing and emitting +/// placeholders when forced to. Don't try to execute code translated with this runtime, it is +/// essentially here for translation debug purposes. +pub struct DummyRuntime { + globals: Vec, +} + +impl DummyRuntime { + /// Allocates the runtime data structures. + pub fn new() -> DummyRuntime { + DummyRuntime { globals: Vec::new() } + } +} + +impl WasmRuntime for DummyRuntime { + fn translate_get_global(&self, + builder: &mut FunctionBuilder, + global_index: GlobalIndex) + -> Value { + let ref glob = self.globals.get(global_index as usize).unwrap(); + match glob.ty { + I32 => builder.ins().iconst(glob.ty, -1), + I64 => builder.ins().iconst(glob.ty, -1), + F32 => builder.ins().f32const(Ieee32::with_bits(0xbf800000)), // -1.0 + F64 => { + builder + .ins() + .f64const(Ieee64::with_bits(0xbff0000000000000)) + } // -1.0 + _ => panic!("should not happen"), + } + } + + fn translate_set_global(&self, _: &mut FunctionBuilder, _: GlobalIndex, _: Value) { + // We do nothing + } + fn translate_grow_memory(&mut self, builder: &mut FunctionBuilder, _: Value) -> Value { + builder.ins().iconst(I32, -1) + } + fn translate_current_memory(&mut self, builder: &mut FunctionBuilder) -> Value { + builder.ins().iconst(I32, -1) + } + fn translate_call_indirect<'a>(&self, + builder: &'a mut FunctionBuilder, + sig_ref: SigRef, + index_val: Value, + call_args: &[Value]) + -> &'a [Value] { + let call_inst = builder.ins().call_indirect(sig_ref, index_val, call_args); + builder.inst_results(call_inst) + } + fn translate_memory_base_address(&self, + builder: &mut FunctionBuilder, + _: MemoryIndex) + -> Value { + builder.ins().iconst(I64, 0) + } + fn declare_global(&mut self, global: Global) { + self.globals.push(global); + } + fn declare_table(&mut self, _: Table) { + //We do nothing + } + fn declare_table_elements(&mut self, _: TableIndex, _: usize, _: &[FunctionIndex]) { + //We do nothing + } + fn declare_memory(&mut self, _: Memory) { + //We do nothing + } + fn declare_data_initialization(&mut self, + _: MemoryIndex, + _: usize, + _: &[u8]) + -> Result<(), String> { + // We do nothing + Ok(()) + } + + fn begin_translation(&mut self) { + // We do nothing + } + fn next_function(&mut self) { + // We do nothing + } +} diff --git a/lib/wasm2cretonne/src/runtime/mod.rs b/lib/wasm2cretonne/src/runtime/mod.rs new file mode 100644 index 0000000000..9f2a41d4f9 --- /dev/null +++ b/lib/wasm2cretonne/src/runtime/mod.rs @@ -0,0 +1,5 @@ +mod spec; +mod dummy; + +pub use runtime::spec::WasmRuntime; +pub use runtime::dummy::DummyRuntime; diff --git a/lib/wasm2cretonne/src/runtime/spec.rs b/lib/wasm2cretonne/src/runtime/spec.rs new file mode 100644 index 0000000000..24e98b0d58 --- /dev/null +++ b/lib/wasm2cretonne/src/runtime/spec.rs @@ -0,0 +1,61 @@ +//! All the runtime support necessary for the wasm to cretonne translation is formalized by the +//! trait `WasmRuntime`. +use cton_frontend::FunctionBuilder; +use cretonne::ir::{Value, SigRef}; +use translation_utils::{Local, FunctionIndex, TableIndex, GlobalIndex, MemoryIndex, Global, Table, + Memory}; + +/// An object satisfyng the `WasmRuntime` trait can be passed as argument to the +/// [`translate_module`](fn.translate_module.html) function. These methods should not be called +/// by the user, they are only for the `wasm2cretonne` internal use. +pub trait WasmRuntime { + /// Declares a global to the runtime. + fn declare_global(&mut self, global: Global); + /// Declares a table to the runtime. + fn declare_table(&mut self, table: Table); + /// Fills a declared table with references to functions in the module. + fn declare_table_elements(&mut self, + table_index: TableIndex, + offset: usize, + elements: &[FunctionIndex]); + /// Declares a memory to the runtime + fn declare_memory(&mut self, memory: Memory); + /// Fills a declared memory with bytes at module instantiation. + fn declare_data_initialization(&mut self, + memory_index: MemoryIndex, + offset: usize, + data: &[u8]) + -> Result<(), String>; + /// Call this function after having declared all the runtime elements but prior to the + /// function body translation. + fn begin_translation(&mut self); + /// Call this function between each function body translation. + fn next_function(&mut self); + /// Translates a `get_global` wasm instruction. + fn translate_get_global(&self, + builder: &mut FunctionBuilder, + global_index: GlobalIndex) + -> Value; + /// Translates a `set_global` wasm instruction. + fn translate_set_global(&self, + builder: &mut FunctionBuilder, + global_index: GlobalIndex, + val: Value); + /// Translates a `grow_memory` wasm instruction. Returns the old size (in pages) of the memory. + fn translate_grow_memory(&mut self, builder: &mut FunctionBuilder, val: Value) -> Value; + /// Translates a `current_memory` wasm instruction. Returns the size in pages of the memory. + fn translate_current_memory(&mut self, builder: &mut FunctionBuilder) -> Value; + /// Returns the base address of a wasm memory as a Cretonne `Value`. + fn translate_memory_base_address(&self, + builder: &mut FunctionBuilder, + index: MemoryIndex) + -> Value; + /// Translates a `call_indirect` wasm instruction. It involves looking up the value contained + /// it the table at location `index_val` and calling the corresponding function. + fn translate_call_indirect<'a>(&self, + builder: &'a mut FunctionBuilder, + sig_ref: SigRef, + index_val: Value, + call_args: &[Value]) + -> &'a [Value]; +} diff --git a/lib/wasm2cretonne/src/sections_translator.rs b/lib/wasm2cretonne/src/sections_translator.rs new file mode 100644 index 0000000000..11edd08f30 --- /dev/null +++ b/lib/wasm2cretonne/src/sections_translator.rs @@ -0,0 +1,367 @@ +//! Helper functions to gather information for each of the non-function sections of a +//! WebAssembly module. +//! +//! The code of theses helper function is straightforward since it is only about reading metadata +//! about linear memories, tables, globals, etc. and storing them for later use. +//! +//! The special case of the initialize expressions for table elements offsets or global variables +//! is handled, according to the semantics of WebAssembly, to only specific expressions that are +//! interpreted on the fly. +use translation_utils::{type_to_type, Import, TableIndex, FunctionIndex, GlobalIndex, + SignatureIndex, MemoryIndex, Global, GlobalInit, Table, TableElementType, + Memory}; +use cretonne::ir::{Signature, ArgumentType, CallConv}; +use cretonne; +use wasmparser::{Parser, ParserState, FuncType, ImportSectionEntryType, ExternalKind, WasmDecoder, + MemoryType, Operator}; +use wasmparser; +use std::collections::HashMap; +use std::str::from_utf8; +use runtime::WasmRuntime; + +pub enum SectionParsingError { + WrongSectionContent(String), +} + +/// Reads the Type Section of the wasm module and returns the corresponding function signatures. +pub fn parse_function_signatures(parser: &mut Parser) + -> Result, SectionParsingError> { + let mut signatures: Vec = Vec::new(); + loop { + match *parser.read() { + ParserState::EndSection => break, + ParserState::TypeSectionEntry(FuncType { + form: wasmparser::Type::Func, + ref params, + ref returns, + }) => { + let mut sig = Signature::new(CallConv::Native); + sig.argument_types + .extend(params + .iter() + .map(|ty| { + let cret_arg: cretonne::ir::Type = match type_to_type(ty) { + Ok(ty) => ty, + Err(()) => panic!("only numeric types are supported in\ + function signatures"), + }; + ArgumentType::new(cret_arg) + })); + sig.return_types + .extend(returns + .iter() + .map(|ty| { + let cret_arg: cretonne::ir::Type = match type_to_type(ty) { + Ok(ty) => ty, + Err(()) => panic!("only numeric types are supported in\ + function signatures"), + }; + ArgumentType::new(cret_arg) + })); + signatures.push(sig); + } + ref s @ _ => return Err(SectionParsingError::WrongSectionContent(format!("{:?}", s))), + } + } + Ok(signatures) +} + +/// Retrieves the imports from the imports section of the binary. +pub fn parse_import_section(parser: &mut Parser) -> Result, SectionParsingError> { + let mut imports = Vec::new(); + loop { + match *parser.read() { + ParserState::ImportSectionEntry { + ty: ImportSectionEntryType::Function(sig), .. + } => imports.push(Import::Function { sig_index: sig }), + ParserState::ImportSectionEntry { + ty: ImportSectionEntryType::Memory(MemoryType { limits: ref memlimits }), .. + } => { + imports.push(Import::Memory(Memory { + pages_count: memlimits.initial as usize, + maximum: memlimits.maximum.map(|x| x as usize), + })) + } + ParserState::ImportSectionEntry { + ty: ImportSectionEntryType::Global(ref ty), .. + } => { + imports.push(Import::Global(Global { + ty: type_to_type(&ty.content_type).unwrap(), + mutability: ty.mutability != 0, + initializer: GlobalInit::Import(), + })); + } + ParserState::ImportSectionEntry { + ty: ImportSectionEntryType::Table(ref tab), .. + } => { + imports.push(Import::Table(Table { + ty: match type_to_type(&tab.element_type) { + Ok(t) => TableElementType::Val(t), + Err(()) => TableElementType::Func(), + }, + size: tab.limits.initial as usize, + maximum: tab.limits.maximum.map(|x| x as usize), + })); + } + ParserState::EndSection => break, + ref s @ _ => return Err(SectionParsingError::WrongSectionContent(format!("{:?}", s))), + }; + } + Ok(imports) +} + +/// Retrieves the correspondances between functions and signatures from the function section +pub fn parse_function_section(parser: &mut Parser) + -> Result, SectionParsingError> { + let mut funcs = Vec::new(); + loop { + match *parser.read() { + ParserState::FunctionSectionEntry(sigindex) => funcs.push(sigindex as SignatureIndex), + ParserState::EndSection => break, + ref s @ _ => return Err(SectionParsingError::WrongSectionContent(format!("{:?}", s))), + }; + } + Ok(funcs) +} + +/// Retrieves the names of the functions from the export section +pub fn parse_export_section(parser: &mut Parser) + -> Result, SectionParsingError> { + let mut exports: HashMap = HashMap::new(); + loop { + match *parser.read() { + ParserState::ExportSectionEntry { + field, + ref kind, + index, + } => { + match kind { + &ExternalKind::Function => { + exports.insert(index as FunctionIndex, + String::from(from_utf8(field).unwrap())); + () + } + _ => (),//TODO: deal with other kind of exports + } + } + ParserState::EndSection => break, + ref s @ _ => return Err(SectionParsingError::WrongSectionContent(format!("{:?}", s))), + }; + } + Ok(exports) +} + +/// Retrieves the size and maximum fields of memories from the memory section +pub fn parse_memory_section(parser: &mut Parser) -> Result, SectionParsingError> { + let mut memories: Vec = Vec::new(); + loop { + match *parser.read() { + ParserState::MemorySectionEntry(ref ty) => { + memories.push(Memory { + pages_count: ty.limits.initial as usize, + maximum: ty.limits.maximum.map(|x| x as usize), + }) + } + ParserState::EndSection => break, + ref s @ _ => return Err(SectionParsingError::WrongSectionContent(format!("{:?}", s))), + }; + } + Ok(memories) +} + +/// Retrieves the size and maximum fields of memories from the memory section +pub fn parse_global_section(parser: &mut Parser, + runtime: &mut WasmRuntime) + -> Result, SectionParsingError> { + let mut globals = Vec::new(); + loop { + let (content_type, mutability) = match *parser.read() { + ParserState::BeginGlobalSectionEntry(ref ty) => (ty.content_type, ty.mutability), + ParserState::EndSection => break, + ref s @ _ => return Err(SectionParsingError::WrongSectionContent(format!("{:?}", s))), + }; + match *parser.read() { + ParserState::BeginInitExpressionBody => (), + ref s @ _ => return Err(SectionParsingError::WrongSectionContent(format!("{:?}", s))), + } + let initializer = match *parser.read() { + ParserState::InitExpressionOperator(Operator::I32Const { value }) => { + GlobalInit::I32Const(value) + } + ParserState::InitExpressionOperator(Operator::I64Const { value }) => { + GlobalInit::I64Const(value) + } + ParserState::InitExpressionOperator(Operator::F32Const { value }) => { + GlobalInit::F32Const(value.bits()) + } + ParserState::InitExpressionOperator(Operator::F64Const { value }) => { + GlobalInit::F64Const(value.bits()) + } + ParserState::InitExpressionOperator(Operator::GetGlobal { global_index }) => { + GlobalInit::GlobalRef(global_index as GlobalIndex) + } + ref s @ _ => return Err(SectionParsingError::WrongSectionContent(format!("{:?}", s))), + + }; + match *parser.read() { + ParserState::EndInitExpressionBody => (), + ref s @ _ => return Err(SectionParsingError::WrongSectionContent(format!("{:?}", s))), + } + let global = Global { + ty: type_to_type(&content_type).unwrap(), + mutability: mutability != 0, + initializer: initializer, + }; + runtime.declare_global(global.clone()); + globals.push(global); + match *parser.read() { + ParserState::EndGlobalSectionEntry => (), + ref s @ _ => return Err(SectionParsingError::WrongSectionContent(format!("{:?}", s))), + } + } + Ok(globals) +} + +pub fn parse_data_section(parser: &mut Parser, + runtime: &mut WasmRuntime, + globals: &Vec) + -> Result<(), SectionParsingError> { + loop { + let memory_index = match *parser.read() { + ParserState::BeginDataSectionEntry(memory_index) => memory_index, + ParserState::EndSection => break, + ref s @ _ => return Err(SectionParsingError::WrongSectionContent(format!("{:?}", s))), + }; + match *parser.read() { + ParserState::BeginInitExpressionBody => (), + ref s @ _ => return Err(SectionParsingError::WrongSectionContent(format!("{:?}", s))), + }; + let offset = match *parser.read() { + ParserState::InitExpressionOperator(Operator::I32Const { value }) => { + if value < 0 { + return Err(SectionParsingError::WrongSectionContent(String::from("negative offset value",),),); + } else { + value as usize + } + } + ParserState::InitExpressionOperator(Operator::GetGlobal { global_index }) => { + match globals[global_index as usize].initializer { + GlobalInit::I32Const(value) => { + if value < 0 { + return Err(SectionParsingError::WrongSectionContent(String::from("negative offset value",),),); + } else { + value as usize + } + } + GlobalInit::Import() => { + return Err(SectionParsingError::WrongSectionContent(String::from("imported globals not supported",),),) + } // TODO: add runtime support + _ => panic!("should not happen"), + } + } + ref s @ _ => return Err(SectionParsingError::WrongSectionContent(format!("{:?}", s))), + }; + match *parser.read() { + ParserState::EndInitExpressionBody => (), + ref s @ _ => return Err(SectionParsingError::WrongSectionContent(format!("{:?}", s))), + }; + { + let data = match *parser.read() { + ParserState::DataSectionEntryBody(data) => data, + ref s @ _ => { + return Err(SectionParsingError::WrongSectionContent(format!("{:?}", s))) + } + }; + match runtime.declare_data_initialization(memory_index as MemoryIndex, offset, data) { + Ok(()) => (), + Err(s) => return Err(SectionParsingError::WrongSectionContent(format!("{}", s))), + }; + } + match *parser.read() { + ParserState::EndDataSectionEntry => (), + ref s @ _ => return Err(SectionParsingError::WrongSectionContent(format!("{:?}", s))), + }; + } + Ok(()) +} + +/// Retrieves the tables from the table section +pub fn parse_table_section(parser: &mut Parser, + runtime: &mut WasmRuntime) + -> Result<(), SectionParsingError> { + loop { + match *parser.read() { + ParserState::TableSectionEntry(ref table) => { + runtime.declare_table(Table { + ty: match type_to_type(&table.element_type) { + Ok(t) => TableElementType::Val(t), + Err(()) => TableElementType::Func(), + }, + size: table.limits.initial as usize, + maximum: table.limits.maximum.map(|x| x as usize), + }) + } + ParserState::EndSection => break, + ref s @ _ => return Err(SectionParsingError::WrongSectionContent(format!("{:?}", s))), + }; + } + Ok(()) +} + +/// Retrieves the tables from the table section +pub fn parse_elements_section(parser: &mut Parser, + runtime: &mut WasmRuntime, + globals: &Vec) + -> Result<(), SectionParsingError> { + loop { + let table_index = match *parser.read() { + ParserState::BeginElementSectionEntry(ref table_index) => *table_index as TableIndex, + ParserState::EndSection => break, + ref s @ _ => return Err(SectionParsingError::WrongSectionContent(format!("{:?}", s))), + }; + match *parser.read() { + ParserState::BeginInitExpressionBody => (), + ref s @ _ => return Err(SectionParsingError::WrongSectionContent(format!("{:?}", s))), + }; + let offset = match *parser.read() { + ParserState::InitExpressionOperator(Operator::I32Const { value }) => { + if value < 0 { + return Err(SectionParsingError::WrongSectionContent(String::from("negative offset value",),),); + } else { + value as usize + } + } + ParserState::InitExpressionOperator(Operator::GetGlobal { global_index }) => { + match globals[global_index as usize].initializer { + GlobalInit::I32Const(value) => { + if value < 0 { + return Err(SectionParsingError::WrongSectionContent(String::from("negative offset value",),),); + } else { + value as usize + } + } + GlobalInit::Import() => 0, // TODO: add runtime support + _ => panic!("should not happen"), + } + } + ref s @ _ => return Err(SectionParsingError::WrongSectionContent(format!("{:?}", s))), + }; + match *parser.read() { + ParserState::EndInitExpressionBody => (), + ref s @ _ => return Err(SectionParsingError::WrongSectionContent(format!("{:?}", s))), + }; + match *parser.read() { + ParserState::ElementSectionEntryBody(ref elements) => { + let elems: Vec = + elements.iter().map(|&x| x as FunctionIndex).collect(); + runtime.declare_table_elements(table_index, offset, elems.as_slice()) + } + ref s @ _ => return Err(SectionParsingError::WrongSectionContent(format!("{:?}", s))), + }; + match *parser.read() { + ParserState::EndElementSectionEntry => (), + ref s @ _ => return Err(SectionParsingError::WrongSectionContent(format!("{:?}", s))), + }; + } + Ok(()) +} diff --git a/lib/wasm2cretonne/src/translation_utils.rs b/lib/wasm2cretonne/src/translation_utils.rs new file mode 100644 index 0000000000..840e568787 --- /dev/null +++ b/lib/wasm2cretonne/src/translation_utils.rs @@ -0,0 +1,138 @@ +///! Helper functions and structures for the translation. +use wasmparser; +use cretonne; +use std::u32; +use code_translator; +use module_translator; + +/// Index of a function (imported or defined) inside the WebAssembly module. +pub type FunctionIndex = usize; +/// Index of a table (imported or defined) inside the WebAssembly module. +pub type TableIndex = usize; +/// Index of a global variable (imported or defined) inside the WebAssembly module. +pub type GlobalIndex = usize; +/// Index of a linear memory (imported or defined) inside the WebAssembly module. +pub type MemoryIndex = usize; +/// Index of a signature (imported or defined) inside the WebAssembly module. +pub type SignatureIndex = usize; +/// Raw byte read from memory. +pub type RawByte = u8; +/// Pointer referring to a memory address. +pub type MemoryAddress = usize; + +/// WebAssembly import. +#[derive(Debug,Clone,Copy)] +pub enum Import { + Function { sig_index: u32 }, + Memory(Memory), + Global(Global), + Table(Table), +} + +/// WebAssembly global. +#[derive(Debug,Clone,Copy)] +pub struct Global { + pub ty: cretonne::ir::Type, + pub mutability: bool, + pub initializer: GlobalInit, +} + +/// Globals are initialized via the four `const` operators or by referring to another import. +#[derive(Debug,Clone,Copy)] +pub enum GlobalInit { + I32Const(i32), + I64Const(i64), + F32Const(u32), + F64Const(u64), + Import(), + GlobalRef(GlobalIndex), +} + +/// WebAssembly table. +#[derive(Debug,Clone,Copy)] +pub struct Table { + pub ty: TableElementType, + pub size: usize, + pub maximum: Option, +} + +/// WebAssembly table element. Can be a function or a scalar type. +#[derive(Debug,Clone,Copy)] +pub enum TableElementType { + Val(cretonne::ir::Type), + Func(), +} + +/// WebAssembly linear memory. +#[derive(Debug,Clone,Copy)] +pub struct Memory { + pub pages_count: usize, + pub maximum: Option, +} + +/// Wrapper to a `get_local` and `set_local` index. They are WebAssembly's non-SSA variables. +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] +pub struct Local(pub u32); +impl cretonne::entity_ref::EntityRef for Local { + fn new(index: usize) -> Self { + assert!(index < (u32::MAX as usize)); + Local(index as u32) + } + + fn index(self) -> usize { + self.0 as usize + } +} +impl Default for Local { + fn default() -> Local { + Local(u32::MAX) + } +} + +/// Helper function translating wasmparser types to Cretonne types when possible. +pub fn type_to_type(ty: &wasmparser::Type) -> Result { + match *ty { + wasmparser::Type::I32 => Ok(cretonne::ir::types::I32), + wasmparser::Type::I64 => Ok(cretonne::ir::types::I64), + wasmparser::Type::F32 => Ok(cretonne::ir::types::F32), + wasmparser::Type::F64 => Ok(cretonne::ir::types::F64), + _ => Err(()), + } +} + +/// Turns a `wasmparser` `f32` into a `Cretonne` one. +pub fn f32_translation(x: wasmparser::Ieee32) -> cretonne::ir::immediates::Ieee32 { + cretonne::ir::immediates::Ieee32::with_bits(x.bits()) +} + +/// Turns a `wasmparser` `f64` into a `Cretonne` one. +pub fn f64_translation(x: wasmparser::Ieee64) -> cretonne::ir::immediates::Ieee64 { + cretonne::ir::immediates::Ieee64::with_bits(x.bits()) +} + +/// Translate a `wasmparser` type into its `Cretonne` equivalent, when possible +pub fn translate_type(ty: wasmparser::Type) -> Result, ()> { + match ty { + wasmparser::Type::EmptyBlockType => Ok(Vec::new()), + wasmparser::Type::I32 => Ok(vec![cretonne::ir::types::I32]), + wasmparser::Type::F32 => Ok(vec![cretonne::ir::types::F32]), + wasmparser::Type::I64 => Ok(vec![cretonne::ir::types::I64]), + wasmparser::Type::F64 => Ok(vec![cretonne::ir::types::F64]), + _ => panic!("unsupported return value type"), + } +} + +/// Inverts the key-value relation in the imports hashmap. Indeed, these hashmaps are built by +/// feeding the function indexes in the module but are used by the runtime with the `FuncRef` as +/// keys. +pub fn invert_hashmaps(imports: code_translator::FunctionImports) + -> module_translator::ImportMappings { + let mut new_imports = module_translator::ImportMappings::new(); + for (func_index, func_ref) in imports.functions.iter() { + new_imports.functions.insert(*func_ref, *func_index); + } + for (sig_index, sig_ref) in imports.signatures.iter() { + new_imports.signatures.insert(*sig_ref, *sig_index); + } + new_imports +} diff --git a/lib/wasmstandalone/.gitignore b/lib/wasmstandalone/.gitignore new file mode 100644 index 0000000000..4308d82204 --- /dev/null +++ b/lib/wasmstandalone/.gitignore @@ -0,0 +1,3 @@ +target/ +**/*.rs.bk +Cargo.lock diff --git a/lib/wasmstandalone/Cargo.toml b/lib/wasmstandalone/Cargo.toml new file mode 100644 index 0000000000..a1f35f92ff --- /dev/null +++ b/lib/wasmstandalone/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "wasmstandalone" +version = "0.0.0" +authors = ["The Cretonne Project Developers"] +publish = false + +[dependencies] +cretonne = { path = "../cretonne" } +cretonne-frontend = { path = "../frontend" } +wasm2cretonne = { path = "../wasm2cretonne" } +region = "0.0.8" diff --git a/lib/wasmstandalone/src/execution.rs b/lib/wasmstandalone/src/execution.rs new file mode 100644 index 0000000000..9d8a3f2839 --- /dev/null +++ b/lib/wasmstandalone/src/execution.rs @@ -0,0 +1,256 @@ +use cretonne::Context; +use cretonne::settings; +use cretonne::isa::{self, TargetIsa}; +use cretonne::verify_function; +use cretonne::verifier; +use cretonne::settings::Configurable; +use cretonne::result::CtonError; +use cretonne::ir::entities::AnyEntity; +use cretonne::ir::{self, Ebb, FuncRef, JumpTable, Function}; +use cretonne::binemit::{RelocSink, Reloc, CodeOffset}; +use wasm2cretonne::{TranslationResult, FunctionTranslation, ImportMappings, FunctionIndex}; +use std::mem::transmute; +use region::Protection; +use region::protect; +use std::collections::HashMap; +use std::ptr::write_unaligned; +use std::fmt::Write; + +type RelocRef = u16; + +// Implementation of a relocation sink that just saves all the information for later +struct StandaloneRelocSink { + ebbs: HashMap, + funcs: HashMap, + jts: HashMap, +} + +// Contains all the metadata necessary to perform relocations +enum FunctionMetaData { + Import(), + Local { + relocs: StandaloneRelocSink, + imports: ImportMappings, + il_func: Function, + }, +} + +impl RelocSink for StandaloneRelocSink { + fn reloc_ebb(&mut self, offset: CodeOffset, reloc: Reloc, ebb: Ebb) { + self.ebbs.insert(reloc.0, (ebb, offset)); + } + fn reloc_func(&mut self, offset: CodeOffset, reloc: Reloc, func: FuncRef) { + self.funcs.insert(reloc.0, (func, offset)); + } + fn reloc_jt(&mut self, offset: CodeOffset, reloc: Reloc, jt: JumpTable) { + self.jts.insert(reloc.0, (jt, offset)); + } +} + +impl StandaloneRelocSink { + fn new() -> StandaloneRelocSink { + StandaloneRelocSink { + ebbs: HashMap::new(), + funcs: HashMap::new(), + jts: HashMap::new(), + } + } +} + +/// Structure containing the compiled code of the functions, ready to be executed. +pub struct ExecutableCode { + functions_code: Vec>, + start_index: FunctionIndex, +} + +/// Executes a module that has been translated with the `StandaloneRuntime` runtime implementation. +pub fn compile_module(trans_result: &TranslationResult) -> Result { + let mut shared_builder = settings::builder(); + shared_builder + .enable("enable_verifier") + .expect("Missing enable_verifier setting"); + shared_builder + .set("is_64bit", "1") + .expect("Missing 64bits setting"); + let isa = match isa::lookup("intel") { + Err(_) => { + panic!() // The target ISA is not available. + } + Ok(mut isa_builder) => { + isa_builder + .enable("haswell") + .expect("Missing haswell setting"); + isa_builder.finish(settings::Flags::new(&shared_builder)) + } + }; + let mut functions_metatada = Vec::new(); + let mut functions_code = Vec::new(); + for (function_index, function) in trans_result.functions.iter().enumerate() { + let mut context = Context::new(); + let (il, imports) = match function { + &FunctionTranslation::Import() => { + if trans_result.start_index.is_some() && + trans_result.start_index.unwrap() == function_index { + return Err(String::from("start function should not be an import")); + } else { + functions_code.push(Vec::new()); + functions_metatada.push(FunctionMetaData::Import()); + continue; + } + } + &FunctionTranslation::Code { + ref il, + ref imports, + .. + } => (il.clone(), imports.clone()), + }; + verify_function(&il, None).unwrap(); + context.func = il; + let code_size = context + .compile(&*isa) + .map_err(|e| pretty_error(&context.func, Some(&*isa), e))? as + usize; + if code_size == 0 { + return Err(String::from("no code generated by Cretonne")); + } + let mut code_buf: Vec = Vec::with_capacity(code_size); + code_buf.resize(code_size, 0); + let mut relocsink = StandaloneRelocSink::new(); + context.emit_to_memory(code_buf.as_mut_ptr(), &mut relocsink, &*isa); + functions_metatada.push(FunctionMetaData::Local { + relocs: relocsink, + imports: imports, + il_func: context.func, + }); + functions_code.push(code_buf); + } + relocate(&functions_metatada, &mut functions_code); + // After having emmitted the code to memory, we deal with relocations + match trans_result.start_index { + None => Err(String::from("No start function defined, aborting execution")), + Some(index) => { + Ok(ExecutableCode { + functions_code, + start_index: index, + }) + } + } +} + +// Jumps to the code region of memory and execute the start function of the module. +pub fn execute(exec: ExecutableCode) -> Result<(), String> { + let code_buf = &exec.functions_code[exec.start_index]; + unsafe { + match protect(code_buf.as_ptr(), + code_buf.len(), + Protection::ReadWriteExecute) { + Ok(()) => (), + Err(err) => { + return Err(format!("failed to give executable permission to code: {}", + err.description())) + } + }; + // Rather than writing inline assembly to jump to the code region, we use the fact that + // the Rust ABI for calling a function with no arguments and no return matches the one of + // the generated code.Thanks to this, we can transmute the code region into a first-class + // Rust function and call it. + // TODO: the Rust callee-saved registers will be overwritten by the executed code, inline + // assembly spilling these registers to the stack and restoring them after the call is + // needed. + let start_func = transmute::<_, fn()>(code_buf.as_ptr()); + // The code below saves the Intel callee-saved registers. It is not activate because + // inline ASM is not supported in the release version of the Rust compiler. + /*asm!("push rax + push rcx + push rdx + push rsi + push rdi + push r8 + push r9 + push r10 + push r11 + " :::: "intel", "volatile");*/ + start_func(); + /*asm!("pop r11 + pop r10 + pop r9 + pop r8 + pop rdi + pop rsi + pop rdx + pop rcx + pop rax + " :::: "intel", "volatile");*/ + Ok(()) + } +} + +/// Performs the relocations inside the function bytecode, provided the necessary metadata +fn relocate(functions_metatada: &Vec, functions_code: &mut Vec>) { + // The relocations are relative to the relocation's address plus four bytes + for (func_index, function_in_memory) in functions_metatada.iter().enumerate() { + match function_in_memory { + &FunctionMetaData::Import() => continue, + &FunctionMetaData::Local { + ref relocs, + ref imports, + ref il_func, + } => { + for (_, &(func_ref, offset)) in relocs.funcs.iter() { + let target_func_index = imports.functions[&func_ref]; + let target_func_address: isize = functions_code[target_func_index].as_ptr() as + isize; + unsafe { + let reloc_address: isize = functions_code[func_index] + .as_mut_ptr() + .offset(offset as isize + 4) as + isize; + let reloc_delta_i32: i32 = (target_func_address - reloc_address) as i32; + write_unaligned(reloc_address as *mut i32, reloc_delta_i32); + } + } + for (_, &(ebb, offset)) in relocs.ebbs.iter() { + unsafe { + let reloc_address: isize = functions_code[func_index] + .as_mut_ptr() + .offset(offset as isize + 4) as + isize; + let target_ebb_address: isize = + functions_code[func_index] + .as_ptr() + .offset(il_func.offsets[ebb] as isize) as + isize; + let reloc_delta_i32: i32 = (target_ebb_address - reloc_address) as i32; + write_unaligned(reloc_address as *mut i32, reloc_delta_i32); + } + } + // TODO: deal with jumptable relocations + } + } + } +} + +/// Pretty-print a verifier error. +pub fn pretty_verifier_error(func: &Function, + isa: Option<&TargetIsa>, + err: verifier::Error) + -> String { + let mut msg = err.to_string(); + match err.location { + AnyEntity::Inst(inst) => { + write!(msg, "\n{}: {}\n\n", inst, func.dfg.display_inst(inst, isa)).unwrap() + } + _ => msg.push('\n'), + } + write!(msg, "{}", func.display(isa)).unwrap(); + msg +} + +/// Pretty-print a Cretonne error. +pub fn pretty_error(func: &ir::Function, isa: Option<&TargetIsa>, err: CtonError) -> String { + if let CtonError::Verifier(e) = err { + pretty_verifier_error(func, isa, e) + } else { + err.to_string() + } +} diff --git a/lib/wasmstandalone/src/lib.rs b/lib/wasmstandalone/src/lib.rs new file mode 100644 index 0000000000..75479a33a5 --- /dev/null +++ b/lib/wasmstandalone/src/lib.rs @@ -0,0 +1,15 @@ +//! Standalone JIT-style runtime for WebAssembly using Cretonne. Provides functions to translate +//! `get_global`, `set_global`, `current_memory`, `grow_memory`, `call_indirect` that hardcode in +//! the translation the base addresses of regions of memory that will hold the globals, tables and +//! linear memories. + +extern crate cretonne; +extern crate wasm2cretonne; +extern crate cton_frontend; +extern crate region; + +mod execution; +mod standalone; + +pub use execution::{compile_module, execute, ExecutableCode}; +pub use standalone::StandaloneRuntime; diff --git a/lib/wasmstandalone/src/standalone.rs b/lib/wasmstandalone/src/standalone.rs new file mode 100644 index 0000000000..1c3fd79bf8 --- /dev/null +++ b/lib/wasmstandalone/src/standalone.rs @@ -0,0 +1,332 @@ +use wasm2cretonne::{Local, FunctionIndex, GlobalIndex, TableIndex, MemoryIndex, RawByte, + MemoryAddress, Global, GlobalInit, Table, Memory, WasmRuntime}; +use cton_frontend::FunctionBuilder; +use cretonne::ir::{MemFlags, Value, InstBuilder, SigRef, FuncRef, ExtFuncData, FunctionName, + Signature, ArgumentType, CallConv}; +use cretonne::ir::types::*; +use cretonne::ir::condcodes::IntCC; +use cretonne::ir::immediates::Offset32; +use std::mem::transmute; +use std::ptr::copy_nonoverlapping; +use std::ptr::write; + +#[derive(Clone, Debug)] +enum TableElement { + Trap(), + Function(FunctionIndex), +} + +struct GlobalInfo { + global: Global, + offset: usize, +} + +struct GlobalsData { + data: Vec, + info: Vec, +} + +struct TableData { + data: Vec, + elements: Vec, + info: Table, +} + +struct MemoryData { + data: Vec, + info: Memory, +} + +const PAGE_SIZE: usize = 65536; + +/// Object containing the standalone runtime information. To be passed after creation as argument +/// to [`wasm2cretonne::translatemodule`](../wasm2cretonne/fn.translate_module.html). +pub struct StandaloneRuntime { + globals: GlobalsData, + tables: Vec, + memories: Vec, + instantiated: bool, + has_current_memory: Option, + has_grow_memory: Option, +} + +impl StandaloneRuntime { + /// Allocates the runtime data structures. + pub fn new() -> StandaloneRuntime { + StandaloneRuntime { + globals: GlobalsData { + data: Vec::new(), + info: Vec::new(), + }, + tables: Vec::new(), + memories: Vec::new(), + instantiated: false, + has_current_memory: None, + has_grow_memory: None, + } + } +} + +/// This trait is useful for +/// [`wasm2cretonne::translatemodule`](../wasm2cretonne/fn.translate_module.html) because it +/// tells how to translate runtime-dependent wasm instructions. These functions should not be +/// called by the user. +impl WasmRuntime for StandaloneRuntime { + fn translate_get_global(&self, + builder: &mut FunctionBuilder, + global_index: GlobalIndex) + -> Value { + debug_assert!(self.instantiated); + let ty = self.globals.info[global_index as usize].global.ty; + let offset = self.globals.info[global_index as usize].offset; + let memflags = MemFlags::new(); + let memoffset = Offset32::new(offset as i32); + let addr: i64 = unsafe { transmute(self.globals.data.as_ptr()) }; + let addr_val = builder.ins().iconst(I64, addr); + builder.ins().load(ty, memflags, addr_val, memoffset) + } + fn translate_set_global(&self, + builder: &mut FunctionBuilder, + global_index: GlobalIndex, + val: Value) { + let offset = self.globals.info[global_index as usize].offset; + let memflags = MemFlags::new(); + let memoffset = Offset32::new(offset as i32); + let addr: i64 = unsafe { transmute(self.globals.data.as_ptr()) }; + let addr_val = builder.ins().iconst(I64, addr); + builder.ins().store(memflags, val, addr_val, memoffset); + } + fn translate_memory_base_address(&self, + builder: &mut FunctionBuilder, + memory_index: MemoryIndex) + -> Value { + let addr: i64 = unsafe { transmute(self.memories[memory_index].data.as_ptr()) }; + builder.ins().iconst(I64, addr) + } + fn translate_grow_memory(&mut self, + builder: &mut FunctionBuilder, + pages: Value) + -> Value { + debug_assert!(self.instantiated); + let grow_mem_func = match self.has_grow_memory { + Some(grow_mem_func) => grow_mem_func, + None => { + let sig_ref = + builder.import_signature(Signature { + call_conv: CallConv::Native, + argument_bytes: None, + argument_types: vec![ArgumentType::new(I32)], + return_types: vec![ArgumentType::new(I32)], + }); + builder.import_function(ExtFuncData { + name: FunctionName::new("grow_memory"), + signature: sig_ref, + }) + } + }; + self.has_grow_memory = Some(grow_mem_func); + let call_inst = builder.ins().call(grow_mem_func, &[pages]); + *builder.inst_results(call_inst).first().unwrap() + } + fn translate_current_memory(&mut self, builder: &mut FunctionBuilder) -> Value { + debug_assert!(self.instantiated); + let cur_mem_func = match self.has_current_memory { + Some(cur_mem_func) => cur_mem_func, + None => { + let sig_ref = builder.import_signature(Signature { + call_conv: CallConv::Native, + argument_bytes: None, + argument_types: Vec::new(), + return_types: + vec![ArgumentType::new(I32)], + }); + builder.import_function(ExtFuncData { + name: FunctionName::new("current_memory"), + signature: sig_ref, + }) + } + }; + self.has_current_memory = Some(cur_mem_func); + let call_inst = builder.ins().call(cur_mem_func, &[]); + *builder.inst_results(call_inst).first().unwrap() + } + fn translate_call_indirect<'a>(&self, + builder: &'a mut FunctionBuilder, + sig_ref: SigRef, + index_val: Value, + call_args: &[Value]) + -> &'a [Value] { + let trap_ebb = builder.create_ebb(); + let continue_ebb = builder.create_ebb(); + let size_val = builder.ins().iconst(I32, self.tables[0].info.size as i64); + let zero_val = builder.ins().iconst(I32, 0); + builder + .ins() + .br_icmp(IntCC::UnsignedLessThan, index_val, zero_val, trap_ebb, &[]); + builder + .ins() + .br_icmp(IntCC::UnsignedGreaterThanOrEqual, + index_val, + size_val, + trap_ebb, + &[]); + builder.seal_block(trap_ebb); + let offset_val = builder.ins().imul_imm(index_val, 4); + let base_table_addr: i64 = unsafe { transmute(self.tables[0].data.as_ptr()) }; + let table_addr_val = builder.ins().iconst(I32, base_table_addr); + let table_entry_addr_val = builder.ins().iadd(table_addr_val, offset_val); + let memflags = MemFlags::new(); + let memoffset = Offset32::new(0); + let table_entry_val = builder + .ins() + .load(I32, memflags, table_entry_addr_val, memoffset); + let call_inst = builder + .ins() + .call_indirect(sig_ref, table_entry_val, call_args); + builder.ins().jump(continue_ebb, &[]); + builder.seal_block(continue_ebb); + builder.switch_to_block(trap_ebb, &[]); + builder.ins().trap(); + builder.switch_to_block(continue_ebb, &[]); + builder.inst_results(call_inst) + } + + fn begin_translation(&mut self) { + debug_assert!(!self.instantiated); + self.instantiated = true; + // At instantiation, we allocate memory for the globals, the memories and the tables + // First the globals + let mut globals_data_size = 0; + for globalinfo in self.globals.info.iter_mut() { + globalinfo.offset = globals_data_size; + globals_data_size += globalinfo.global.ty.bytes() as usize; + } + self.globals.data.resize(globals_data_size as usize, 0); + for globalinfo in self.globals.info.iter() { + match globalinfo.global.initializer { + GlobalInit::I32Const(val) => unsafe { + write(self.globals + .data + .as_mut_ptr() + .offset(globalinfo.offset as isize) as + *mut i32, + val) + }, + GlobalInit::I64Const(val) => unsafe { + write(self.globals + .data + .as_mut_ptr() + .offset(globalinfo.offset as isize) as + *mut i64, + val) + }, + GlobalInit::F32Const(val) => unsafe { + write(self.globals + .data + .as_mut_ptr() + .offset(globalinfo.offset as isize) as + *mut f32, + transmute(val)) + }, + GlobalInit::F64Const(val) => unsafe { + write(self.globals + .data + .as_mut_ptr() + .offset(globalinfo.offset as isize) as + *mut f64, + transmute(val)) + }, + GlobalInit::Import() => { + // We don't initialize, this is inter-module linking + // TODO: support inter-module imports + } + GlobalInit::GlobalRef(index) => { + let ref_offset = self.globals.info[index].offset; + let size = globalinfo.global.ty.bytes(); + unsafe { + let dst = self.globals + .data + .as_mut_ptr() + .offset(globalinfo.offset as isize); + let src = self.globals.data.as_ptr().offset(ref_offset as isize); + copy_nonoverlapping(src, dst, size as usize) + } + } + } + } + } + fn next_function(&mut self) { + self.has_current_memory = None; + self.has_grow_memory = None; + } + fn declare_global(&mut self, global: Global) { + debug_assert!(!self.instantiated); + self.globals + .info + .push(GlobalInfo { + global: global, + offset: 0, + }); + } + fn declare_table(&mut self, table: Table) { + debug_assert!(!self.instantiated); + let mut elements_vec = Vec::with_capacity(table.size as usize); + elements_vec.resize(table.size as usize, TableElement::Trap()); + let mut addresses_vec = Vec::with_capacity(table.size as usize); + addresses_vec.resize(table.size as usize, 0); + self.tables + .push(TableData { + info: table, + data: addresses_vec, + elements: elements_vec, + }); + } + fn declare_table_elements(&mut self, + table_index: TableIndex, + offset: usize, + elements: &[FunctionIndex]) { + debug_assert!(!self.instantiated); + for (i, elt) in elements.iter().enumerate() { + self.tables[table_index].elements[offset as usize + i] = TableElement::Function(*elt); + } + } + fn declare_memory(&mut self, memory: Memory) { + debug_assert!(!self.instantiated); + let mut memory_vec = Vec::with_capacity(memory.pages_count as usize * PAGE_SIZE); + memory_vec.resize(memory.pages_count as usize * PAGE_SIZE, 0); + self.memories + .push(MemoryData { + info: memory, + data: memory_vec, + }); + } + fn declare_data_initialization(&mut self, + memory_index: MemoryIndex, + offset: usize, + data: &[u8]) + -> Result<(), String> { + if offset + data.len() > self.memories[memory_index].info.pages_count * PAGE_SIZE { + return Err(String::from("initialization data out of bounds")); + } + self.memories[memory_index].data[offset..offset + data.len()].copy_from_slice(data); + Ok(()) + } +} + +/// Convenience functions for the user to be called after execution for debug purposes. +impl StandaloneRuntime { + /// Returns a slice of the contents of allocated linear memory. + pub fn inspect_memory(&self, memory_index: usize, address: usize, len: usize) -> &[u8] { + &self.memories + .get(memory_index) + .expect(format!("no memory for index {}", memory_index).as_str()) + .data + [address..address + len] + } + /// Shows the value of a global variable. + pub fn inspect_global(&self, global_index: usize) -> &[u8] { + let (offset, len) = (self.globals.info[global_index].offset, + self.globals.info[global_index].global.ty.bytes() as usize); + &self.globals.data[offset..offset + len] + } +}