├── .clang-format ├── .gitattributes ├── .github └── workflows │ ├── compile.yml │ ├── releaser.yml │ └── test.yml ├── .gitignore ├── .gitmodules ├── CITATION.cff ├── CMakeLists.txt ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── benchmarks ├── .gitignore ├── README.md ├── all_bench.sh ├── bench.list ├── benchmarks.cpp ├── c.ino.template ├── descriptions │ ├── Gabriel.pdf │ └── README.md ├── edward.ino.template ├── edward_bench.sh ├── espruino_bench.sh ├── flash-espruino-esp32.sh ├── flash_and_check.py ├── makefile ├── native_bench.sh ├── rebench.conf ├── tasks │ ├── .gitignore │ ├── catalan │ │ ├── espruino │ │ │ └── impl.js │ │ └── wast │ │ │ └── impl.c │ ├── fac │ │ ├── espruino │ │ │ └── impl.js │ │ └── wast │ │ │ └── impl.c │ ├── fib │ │ ├── espruino │ │ │ └── impl.js │ │ └── wast │ │ │ └── impl.c │ ├── gcd │ │ ├── espruino │ │ │ └── impl.js │ │ └── wast │ │ │ └── impl.c │ ├── makefile │ ├── primes │ │ ├── espruino │ │ │ └── impl.js │ │ └── wast │ │ │ └── impl.c │ ├── tak-mem │ │ ├── espruino │ │ │ └── impl.js │ │ └── wast │ │ │ └── impl.c │ └── tak │ │ ├── espruino │ │ └── impl.js │ │ └── wast │ │ └── impl.c ├── timer.h ├── upload ├── warduino.ino.template ├── warduino_bench.sh ├── wasm3.ino.template └── wasm3_bench.sh ├── documentation ├── DumpFormat.md ├── InstallArduinoESP32.md ├── Interrupts.md ├── OutOfPlaceDebugging.md └── decompile.txt ├── keywords.txt ├── library.properties ├── platforms ├── Arduino │ ├── .gitignore │ ├── Arduino.ino.template │ ├── Makefile │ └── README.md ├── CLI-Emulator │ ├── README.md │ └── main.cpp ├── ESP-IDF │ ├── CMakeLists.txt │ ├── main.cpp │ └── upload.h ├── README.md └── Zephyr │ ├── .gitignore │ ├── CMakeLists.txt │ ├── Kconfig │ ├── app.overlay │ ├── boards │ ├── rpi_pico.overlay │ └── stm32l496g_disco.overlay │ ├── main.cpp │ └── prj.conf ├── sdkconfig ├── src ├── Debug │ ├── debugger.cpp │ └── debugger.h ├── Edward │ ├── RFC.cpp │ ├── RFC.h │ ├── proxy.cpp │ ├── proxy.h │ ├── proxy_supervisor.cpp │ └── proxy_supervisor.h ├── Interpreter │ ├── instructions.cpp │ ├── instructions.h │ ├── interpreter.cpp │ └── interpreter.h ├── Memory │ ├── mem.cpp │ └── mem.h ├── Primitives │ ├── arduino.cpp │ ├── emulated.cpp │ ├── idf.cpp │ ├── primitives.h │ └── zephyr.cpp ├── Threading │ └── warduino-thread.h ├── Utils │ ├── macros.cpp │ ├── macros.h │ ├── sockets.cpp │ ├── sockets.h │ ├── util.cpp │ ├── util.h │ ├── util_arduino.cpp │ └── util_arduino.h ├── WARDuino.h ├── WARDuino │ ├── CallbackHandler.cpp │ ├── CallbackHandler.h │ ├── WARDuino.cpp │ └── internals.h └── config.h.in ├── tests ├── compilation │ └── esp32 │ │ └── esp32.ino ├── latch │ ├── .gitignore │ ├── README.md │ ├── clean.sh │ ├── core │ │ ├── .gitignore │ │ ├── address_0.asserts.wast │ │ ├── address_0.wast │ │ ├── address_1.asserts.wast │ │ ├── address_1.wast │ │ ├── address_2.asserts.wast │ │ ├── address_2.wast │ │ ├── address_3.asserts.wast │ │ ├── address_3.wast │ │ ├── align_23.asserts.wast │ │ ├── align_23.wast │ │ ├── align_24.asserts.wast │ │ ├── align_24.wast │ │ ├── call_0.asserts.wast │ │ ├── call_0.wast │ │ ├── call_indirect_0.asserts.wast │ │ ├── call_indirect_0.wast │ │ ├── call_indirect_1.wast │ │ ├── const_102.asserts.wast │ │ ├── const_102.wast │ │ ├── const_103.asserts.wast │ │ ├── const_103.wast │ │ ├── const_104.asserts.wast │ │ ├── const_104.wast │ │ ├── const_105.asserts.wast │ │ ├── const_105.wast │ │ ├── const_106.asserts.wast │ │ ├── const_106.wast │ │ ├── const_107.asserts.wast │ │ ├── const_107.wast │ │ ├── const_108.asserts.wast │ │ ├── const_108.wast │ │ ├── const_109.asserts.wast │ │ ├── const_109.wast │ │ ├── const_110.asserts.wast │ │ ├── const_110.wast │ │ ├── const_111.asserts.wast │ │ ├── const_111.wast │ │ ├── const_112.asserts.wast │ │ ├── const_112.wast │ │ ├── const_113.asserts.wast │ │ ├── const_113.wast │ │ ├── const_114.asserts.wast │ │ ├── const_114.wast │ │ ├── const_115.asserts.wast │ │ ├── const_115.wast │ │ ├── const_116.asserts.wast │ │ ├── const_116.wast │ │ ├── const_117.asserts.wast │ │ ├── const_117.wast │ │ ├── const_118.asserts.wast │ │ ├── const_118.wast │ │ ├── const_119.asserts.wast │ │ ├── const_119.wast │ │ ├── const_120.asserts.wast │ │ ├── const_120.wast │ │ ├── const_121.asserts.wast │ │ ├── const_121.wast │ │ ├── const_122.asserts.wast │ │ ├── const_122.wast │ │ ├── const_123.asserts.wast │ │ ├── const_123.wast │ │ ├── const_124.asserts.wast │ │ ├── const_124.wast │ │ ├── const_125.asserts.wast │ │ ├── const_125.wast │ │ ├── const_126.asserts.wast │ │ ├── const_126.wast │ │ ├── const_127.asserts.wast │ │ ├── const_127.wast │ │ ├── const_128.asserts.wast │ │ ├── const_128.wast │ │ ├── const_129.asserts.wast │ │ ├── const_129.wast │ │ ├── const_130.asserts.wast │ │ ├── const_130.wast │ │ ├── const_131.asserts.wast │ │ ├── const_131.wast │ │ ├── const_132.asserts.wast │ │ ├── const_132.wast │ │ ├── const_133.asserts.wast │ │ ├── const_133.wast │ │ ├── const_134.asserts.wast │ │ ├── const_134.wast │ │ ├── const_135.asserts.wast │ │ ├── const_135.wast │ │ ├── const_136.asserts.wast │ │ ├── const_136.wast │ │ ├── const_137.asserts.wast │ │ ├── const_137.wast │ │ ├── const_138.asserts.wast │ │ ├── const_138.wast │ │ ├── const_139.asserts.wast │ │ ├── const_139.wast │ │ ├── const_140.asserts.wast │ │ ├── const_140.wast │ │ ├── const_141.asserts.wast │ │ ├── const_141.wast │ │ ├── const_142.asserts.wast │ │ ├── const_142.wast │ │ ├── const_143.asserts.wast │ │ ├── const_143.wast │ │ ├── const_144.asserts.wast │ │ ├── const_144.wast │ │ ├── const_145.asserts.wast │ │ ├── const_145.wast │ │ ├── const_146.asserts.wast │ │ ├── const_146.wast │ │ ├── const_147.asserts.wast │ │ ├── const_147.wast │ │ ├── const_148.asserts.wast │ │ ├── const_148.wast │ │ ├── const_149.asserts.wast │ │ ├── const_149.wast │ │ ├── const_150.asserts.wast │ │ ├── const_150.wast │ │ ├── const_151.asserts.wast │ │ ├── const_151.wast │ │ ├── const_152.asserts.wast │ │ ├── const_152.wast │ │ ├── const_153.asserts.wast │ │ ├── const_153.wast │ │ ├── const_154.asserts.wast │ │ ├── const_154.wast │ │ ├── const_155.asserts.wast │ │ ├── const_155.wast │ │ ├── const_156.asserts.wast │ │ ├── const_156.wast │ │ ├── const_157.asserts.wast │ │ ├── const_157.wast │ │ ├── const_158.asserts.wast │ │ ├── const_158.wast │ │ ├── const_159.asserts.wast │ │ ├── const_159.wast │ │ ├── const_160.asserts.wast │ │ ├── const_160.wast │ │ ├── const_161.asserts.wast │ │ ├── const_161.wast │ │ ├── const_162.asserts.wast │ │ ├── const_162.wast │ │ ├── const_163.asserts.wast │ │ ├── const_163.wast │ │ ├── const_164.asserts.wast │ │ ├── const_164.wast │ │ ├── const_165.asserts.wast │ │ ├── const_165.wast │ │ ├── const_166.asserts.wast │ │ ├── const_166.wast │ │ ├── const_167.asserts.wast │ │ ├── const_167.wast │ │ ├── const_168.asserts.wast │ │ ├── const_168.wast │ │ ├── const_169.asserts.wast │ │ ├── const_169.wast │ │ ├── const_170.asserts.wast │ │ ├── const_170.wast │ │ ├── const_171.asserts.wast │ │ ├── const_171.wast │ │ ├── const_172.asserts.wast │ │ ├── const_172.wast │ │ ├── const_173.asserts.wast │ │ ├── const_173.wast │ │ ├── const_174.asserts.wast │ │ ├── const_174.wast │ │ ├── const_175.asserts.wast │ │ ├── const_175.wast │ │ ├── const_176.asserts.wast │ │ ├── const_176.wast │ │ ├── const_177.asserts.wast │ │ ├── const_177.wast │ │ ├── const_178.asserts.wast │ │ ├── const_178.wast │ │ ├── const_179.asserts.wast │ │ ├── const_179.wast │ │ ├── const_180.asserts.wast │ │ ├── const_180.wast │ │ ├── const_181.asserts.wast │ │ ├── const_181.wast │ │ ├── const_182.asserts.wast │ │ ├── const_182.wast │ │ ├── const_183.asserts.wast │ │ ├── const_183.wast │ │ ├── const_184.asserts.wast │ │ ├── const_184.wast │ │ ├── const_185.asserts.wast │ │ ├── const_185.wast │ │ ├── const_186.asserts.wast │ │ ├── const_186.wast │ │ ├── const_187.asserts.wast │ │ ├── const_187.wast │ │ ├── const_188.asserts.wast │ │ ├── const_188.wast │ │ ├── const_189.asserts.wast │ │ ├── const_189.wast │ │ ├── const_190.asserts.wast │ │ ├── const_190.wast │ │ ├── const_191.asserts.wast │ │ ├── const_191.wast │ │ ├── const_192.asserts.wast │ │ ├── const_192.wast │ │ ├── const_193.asserts.wast │ │ ├── const_193.wast │ │ ├── const_194.asserts.wast │ │ ├── const_194.wast │ │ ├── const_195.asserts.wast │ │ ├── const_195.wast │ │ ├── const_196.asserts.wast │ │ ├── const_196.wast │ │ ├── const_197.asserts.wast │ │ ├── const_197.wast │ │ ├── const_198.asserts.wast │ │ ├── const_198.wast │ │ ├── const_199.asserts.wast │ │ ├── const_199.wast │ │ ├── endianness_0.asserts.wast │ │ ├── endianness_0.wast │ │ ├── f32_0.asserts.wast │ │ ├── f32_0.wast │ │ ├── f32_bitwise_0.asserts.wast │ │ ├── f32_bitwise_0.wast │ │ ├── f32_cmp_0.asserts.wast │ │ ├── f32_cmp_0.wast │ │ ├── f64.asserts.wast │ │ ├── f64.wast │ │ ├── f64_bitwise.asserts.wast │ │ ├── f64_bitwise.wast │ │ ├── f64_cmp.asserts.wast │ │ ├── f64_cmp.wast │ │ ├── float_exprs_45.asserts.wast │ │ ├── float_exprs_45.wast │ │ ├── float_exprs_46.asserts.wast │ │ ├── float_exprs_46.wast │ │ ├── float_exprs_63.asserts.wast │ │ ├── float_exprs_63.wast │ │ ├── float_exprs_64.asserts.wast │ │ ├── float_exprs_64.wast │ │ ├── float_exprs_65.asserts.wast │ │ ├── float_exprs_65.wast │ │ ├── float_exprs_89.asserts.wast │ │ ├── float_exprs_89.wast │ │ ├── float_exprs_93.asserts.wast │ │ ├── float_exprs_93.wast │ │ ├── forward_0.asserts.wast │ │ ├── forward_0.wast │ │ ├── func_2.asserts.wast │ │ ├── func_2.wast │ │ ├── func_3.asserts.wast │ │ ├── func_3.wast │ │ ├── func_ptrs_1.asserts.wast │ │ ├── func_ptrs_1.wast │ │ ├── func_ptrs_2.asserts.wast │ │ ├── func_ptrs_2.wast │ │ ├── i32_0.asserts.wast │ │ ├── i32_0.wast │ │ ├── i64_0.asserts.wast │ │ ├── i64_0.wast │ │ ├── int_exprs_10.asserts.wast │ │ ├── int_exprs_10.wast │ │ ├── int_exprs_15.asserts.wast │ │ ├── int_exprs_15.wast │ │ ├── int_exprs_16.asserts.wast │ │ ├── int_exprs_16.wast │ │ ├── int_exprs_17.asserts.wast │ │ ├── int_exprs_17.wast │ │ ├── int_exprs_2.asserts.wast │ │ ├── int_exprs_2.wast │ │ ├── int_exprs_3.asserts.wast │ │ ├── int_exprs_3.wast │ │ ├── int_exprs_4.asserts.wast │ │ ├── int_exprs_4.wast │ │ ├── int_exprs_5.asserts.wast │ │ ├── int_exprs_5.wast │ │ ├── int_exprs_8.asserts.wast │ │ ├── int_exprs_8.wast │ │ ├── int_exprs_9.asserts.wast │ │ ├── int_exprs_9.wast │ │ ├── int_literals_0.asserts.wast │ │ ├── int_literals_0.wast │ │ ├── labels_0.asserts.wast │ │ ├── labels_0.wast │ │ ├── left-to-right_0.asserts.wast │ │ ├── left-to-right_0.wast │ │ ├── load_0.asserts.wast │ │ ├── load_0.wast │ │ ├── local_get_0.asserts.wast │ │ ├── local_get_0.wast │ │ ├── local_set_0.asserts.wast │ │ ├── local_set_0.wast │ │ ├── local_tee_0.asserts.wast │ │ ├── local_tee_0.wast │ │ ├── memory_copy_0.asserts.wast │ │ ├── memory_copy_0.wast │ │ ├── memory_copy_1.asserts.wast │ │ ├── memory_copy_1.wast │ │ ├── memory_copy_10.asserts.wast │ │ ├── memory_copy_10.wast │ │ ├── memory_copy_11.asserts.wast │ │ ├── memory_copy_11.wast │ │ ├── memory_copy_12.asserts.wast │ │ ├── memory_copy_12.wast │ │ ├── memory_copy_13.asserts.wast │ │ ├── memory_copy_13.wast │ │ ├── memory_copy_14.asserts.wast │ │ ├── memory_copy_14.wast │ │ ├── memory_copy_15.asserts.wast │ │ ├── memory_copy_15.wast │ │ ├── memory_copy_16.asserts.wast │ │ ├── memory_copy_16.wast │ │ ├── memory_copy_17.asserts.wast │ │ ├── memory_copy_17.wast │ │ ├── memory_copy_18.asserts.wast │ │ ├── memory_copy_18.wast │ │ ├── memory_copy_2.asserts.wast │ │ ├── memory_copy_2.wast │ │ ├── memory_copy_3.asserts.wast │ │ ├── memory_copy_3.wast │ │ ├── memory_copy_4.asserts.wast │ │ ├── memory_copy_4.wast │ │ ├── memory_copy_5.asserts.wast │ │ ├── memory_copy_5.wast │ │ ├── memory_copy_6.asserts.wast │ │ ├── memory_copy_6.wast │ │ ├── memory_copy_7.asserts.wast │ │ ├── memory_copy_7.wast │ │ ├── memory_copy_8.asserts.wast │ │ ├── memory_copy_8.wast │ │ ├── memory_copy_9.asserts.wast │ │ ├── memory_copy_9.wast │ │ ├── memory_grow.wast │ │ ├── memory_grow_0.wast │ │ ├── memory_grow_1.asserts.wast │ │ ├── memory_grow_1.wast │ │ ├── memory_grow_2.wast │ │ ├── memory_grow_3.asserts.wast │ │ ├── memory_grow_3.wast │ │ ├── memory_grow_4.asserts.wast │ │ ├── memory_grow_4.wast │ │ ├── memory_size.wast │ │ ├── memory_size_0.wast │ │ ├── memory_size_1.wast │ │ ├── memory_size_2.wast │ │ ├── memory_size_3.wast │ │ ├── names_0.asserts.wast │ │ ├── names_0.wast │ │ ├── names_1.asserts.wast │ │ ├── names_1.wast │ │ ├── names_2.asserts.wast │ │ ├── names_2.wast │ │ ├── names_3.wast │ │ ├── nop_0.asserts.wast │ │ ├── nop_0.wast │ │ ├── return_0.asserts.wast │ │ ├── return_0.wast │ │ ├── switch_0.asserts.wast │ │ ├── switch_0.wast │ │ ├── unwind.asserts.wast │ │ ├── unwind.wast │ │ ├── unwind_0.asserts.wast │ │ └── unwind_0.wast │ ├── examples │ │ ├── blink.wast │ │ ├── button.wast │ │ ├── call.wast │ │ └── factorial.wast │ ├── latch-0.3.1.tgz │ ├── output │ ├── package-lock.json │ ├── package.json │ ├── src │ │ ├── comp.test.ts │ │ ├── computations.wast │ │ ├── debugger.test.ts │ │ ├── maths.wast │ │ ├── primitives.test.ts │ │ ├── spec.test.ts │ │ └── util │ │ │ ├── spec.util.ts │ │ │ └── warduino.bridge.ts │ └── tsconfig.json └── unit │ ├── README.md │ ├── addresconversions_test.cpp │ ├── example_code │ ├── blink │ │ ├── blink.wasm │ │ ├── blink.wast │ │ └── blink_wasm.h │ ├── dimmer │ │ ├── dimmer.wasm │ │ ├── dimmer.wast │ │ └── dimmer_wasm.h │ └── fac │ │ ├── fac.wasm │ │ ├── fac.wast │ │ └── fac_wasm.h │ ├── freeingmodule_test.cpp │ ├── instantiatemodule_test.cpp │ ├── serialisation_test.cpp │ └── shared │ ├── callstackbuilder.cpp │ ├── callstackbuilder.h │ ├── serialisation.cpp │ └── serialisation.h └── tutorials ├── .gitignore ├── README.md ├── assemblyscript ├── .gitignore ├── CMakeLists.txt ├── README.md ├── as-warduino-0.1.1.tgz ├── asconfig.json ├── main │ ├── CMakeLists.txt │ ├── analog-io.ts │ ├── analog.ts │ ├── ascii.ts │ ├── blink-without-delay.ts │ ├── blink.ts │ ├── button.ts │ ├── config.ts │ ├── configuration.ts │ ├── main.cpp │ ├── smartlamp.ts │ └── wifi.ts ├── package-lock.json └── package.json ├── rust ├── .gitignore ├── README.md ├── build.sh ├── examples │ ├── analog-io │ │ ├── .cargo │ │ │ └── config │ │ ├── Cargo.toml │ │ ├── button.wat │ │ └── main │ │ │ └── main.rs │ ├── analog │ │ ├── .cargo │ │ │ └── config │ │ ├── Cargo.toml │ │ ├── button.wat │ │ └── main │ │ │ └── main.rs │ ├── ascii │ │ ├── .cargo │ │ │ └── config │ │ ├── Cargo.toml │ │ └── main │ │ │ └── main.rs │ ├── button │ │ ├── .cargo │ │ │ └── config │ │ ├── Cargo.toml │ │ ├── button.wat │ │ └── main │ │ │ └── main.rs │ └── configuration │ │ ├── .cargo │ │ └── config │ │ ├── Cargo.toml │ │ ├── button.wat │ │ └── main │ │ ├── config.rs │ │ └── main.rs └── lib │ └── warduino │ ├── .gitignore │ ├── Cargo.toml │ └── src │ ├── lib.rs │ └── linking.rs └── wat ├── CMakeLists.txt ├── README.md ├── build.sh └── main ├── CMakeLists.txt ├── blink.wat ├── fac.wat └── main.cpp /.clang-format: -------------------------------------------------------------------------------- 1 | BasedOnStyle: Google 2 | IndentWidth: 4 3 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | benchmarks/*.sh linguist-vendored 2 | *.wast linguist-vendored 3 | -------------------------------------------------------------------------------- /.github/workflows/releaser.yml: -------------------------------------------------------------------------------- 1 | name: Publish new release 2 | 3 | on: 4 | workflow_dispatch: 5 | inputs: 6 | version: 7 | description: 'Release version' 8 | required: true 9 | default: 'warning' 10 | type: string 11 | 12 | jobs: 13 | create-release: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/checkout@v4 17 | 18 | - name: "Update version" 19 | run: | 20 | sed -i "s/\(project(WARDuino VERSION \)[0-9]\+\.[0-9]\+\.[0-9]\+/\1$VERSION/" CMakeLists.txt 21 | sed -i "s/\(version=\)[0-9]\+\.[0-9]\+\.[0-9]\+/\1$VERSION/" library.properties 22 | env: 23 | VERSION: ${{ inputs.version }} 24 | 25 | - name: Update metadata 26 | run: | 27 | git config user.name "github-actions[bot]" 28 | git config user.email "github-actions[bot]@users.noreply.github.com" 29 | #git add CMakeLists.txt library.properties 30 | 31 | - name: Create pull request 32 | uses: peter-evans/create-pull-request@v7 33 | with: 34 | commit-message: "🔖 Bump version to ${{ inputs.version }}" 35 | branch: release 36 | title: "Release for ${{ inputs.version }}" 37 | body: "This is an automated PR for the next release, version: ${{ inputs.version }}." 38 | 39 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | .vscode/ 3 | .ccls 4 | 5 | *.bin 6 | *.ipch 7 | *.o 8 | 9 | # Build folders 10 | build/ 11 | cmake-build-* 12 | build* 13 | 14 | # CMake 15 | CMakeLists.txt.user 16 | CMakeCache.txt 17 | CMakeFiles 18 | CMakeScripts 19 | Testing 20 | Makefile 21 | cmake_install.cmake 22 | install_manifest.txt 23 | compile_commands.json 24 | CTestTestfile.cmake 25 | _deps 26 | 27 | # MacOS 28 | .DS_Store 29 | .AppleDouble 30 | .LSOverride 31 | 32 | *.old 33 | 34 | core 35 | venv 36 | 37 | *.wasm 38 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "lib/json"] 2 | path = lib/json 3 | url = https://github.com/nlohmann/json 4 | [submodule "lib/wabt"] 5 | path = lib/wabt 6 | url = git@github.com:TOPLLab/wabt.git 7 | -------------------------------------------------------------------------------- /CITATION.cff: -------------------------------------------------------------------------------- 1 | cff-version: 1.2.0 2 | message: You can also find a BibTeX in the README.md 3 | title: >- 4 | WARDuino: An Embedded WebAssembly Virtual Machine 5 | doi: 10.1016/j.cola.2024.101268 6 | authors: 7 | - family-names: Lauwaerts 8 | given-names: Tom 9 | affiliation: Ghent University 10 | - family-names: Gurdeep Singh 11 | given-names: Robbert 12 | affiliation: IMEC 13 | - family-names: Scholliers 14 | given-names: Christophe 15 | affiliation: Ghent University 16 | identifiers: 17 | - description: Research paper you should be citing 18 | type: doi 19 | value: 10.1016/j.cola.2024.101268 20 | preferred-citation: 21 | authors: 22 | - family-names: Lauwaerts 23 | given-names: Tom 24 | affiliation: Ghent University 25 | - family-names: Gurdeep Singh 26 | given-names: Robbert 27 | affiliation: IMEC 28 | - family-names: Scholliers 29 | given-names: Christophe 30 | affiliation: Ghent University 31 | title: >- 32 | WARDuino: An Embedded WebAssembly Virtual Machine 33 | doi: 10.1016/j.cola.2024.101268 34 | type: article 35 | year: 2024 36 | issn: "2590-1184" 37 | journal: Journal of Computer Languages 38 | publisher: 39 | name: Elsevier 40 | keywords: 41 | - Internet-of-Things 42 | - Language symbiosis 43 | - Virtual machine 44 | - WARDuino 45 | - WebAssembly 46 | 47 | -------------------------------------------------------------------------------- /benchmarks/.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | bin/ 3 | 4 | output 5 | *.csv 6 | 7 | *.json 8 | *.data 9 | -------------------------------------------------------------------------------- /benchmarks/all_bench.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Name: Test WARDuino, Espruino and native code 3 | # By Robbert Gurdeep Singh 4 | ################################################################################ 5 | set -e 6 | file=${1?Give an output file as argument} 7 | tmpdir="$(mktemp --tmpdir -d)" 8 | trap "rm -rf '$tmpdir'" EXIT 9 | 10 | echo -e "tip:\ntail -f $tmpdir/*" 11 | 12 | echo "Not started yet" >$tmpdir/espruino 13 | echo "Not started yet" >$tmpdir/warduino 14 | echo "Not started yet" >$tmpdir/wasm3 15 | echo "Not started yet" >$tmpdir/native 16 | 17 | to_csv() { 18 | sed -i -n '0~2{N;s/\n/,/p}' $1 19 | } 20 | 21 | #sleep 5 22 | #./espruino_bench.sh $tmpdir/espruino 23 | #to_csv $tmpdir/espruino 24 | 25 | sleep 5 26 | ./warduino_bench.sh $tmpdir/warduino 27 | to_csv $tmpdir/warduino 28 | 29 | sleep 5 30 | ./edward_bench.sh $tmpdir/edward 31 | to_csv $tmpdir/edward 32 | 33 | sleep 5 34 | ./wasm3_bench.sh $tmpdir/wasm3 35 | to_csv $tmpdir/wasm3 36 | 37 | sleep 5 38 | ./native_bench.sh $tmpdir/native 39 | to_csv $tmpdir/native 40 | 41 | echo "# Espruino" 42 | cat $tmpdir/espruino 43 | echo "# Warduino" 44 | cat $tmpdir/warduino 45 | echo "# Edward" 46 | cat $tmpdir/edward 47 | echo "# Wasm3" 48 | cat $tmpdir/wasm3 49 | echo "# Native" 50 | cat $tmpdir/native 51 | 52 | sizes() { 53 | find tasks -iname "*.$1" -exec du -b '{}' \+ | sed 's:\s*tasks/:,:;s:/.*::;s:\(.*\),\(.*\):\2,\1:' | sort 54 | } 55 | 56 | echo "name,espruino,warduino,wasm3,native,espruinoSize,warduinoSize" >$file.csv 57 | sort $tmpdir/espruino | 58 | join -j 1 -t',' - <(sort $tmpdir/warduino) | 59 | join -j 1 -t',' - <(sort $tmpdir/wasm3) | 60 | join -j 1 -t',' - <(sort $tmpdir/native) | 61 | join -j 1 -t',' - <(sizes js) | 62 | join -j 1 -t',' - <(sizes wasm) >>$file.csv 63 | sed 's/,/ /g' $file.csv >$file 64 | 65 | cat $file.csv | 66 | sed 's/[0-9]\+\./ &/g;s/ *\([0-9 ]\{3\}\.\)/\1/g;s/\.\([0-9]\{4\}\)[0-9]*/.\1/g' | 67 | column -t -s',' 68 | -------------------------------------------------------------------------------- /benchmarks/bench.list: -------------------------------------------------------------------------------- 1 | catalan 2 | fac 3 | fib 4 | gcd 5 | primes 6 | tak 7 | -------------------------------------------------------------------------------- /benchmarks/c.ino.template: -------------------------------------------------------------------------------- 1 | void setup() { 2 | Serial.begin(115200); 3 | } 4 | 5 | void __attribute__((optimize("no-unroll-loops"))) loop() { 6 | delay(1000); 7 | printf("START\n\n"); 8 | for (int i = 0; i < 10; i++) { 9 | printf("%d: %u\n", i, bench()); 10 | } 11 | printf("DONE\n\n"); 12 | } 13 | -------------------------------------------------------------------------------- /benchmarks/descriptions/Gabriel.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOPLLab/WARDuino/9f6baefd4a45e2a90fe6ae6fb2643b877aa4d98b/benchmarks/descriptions/Gabriel.pdf -------------------------------------------------------------------------------- /benchmarks/descriptions/README.md: -------------------------------------------------------------------------------- 1 | TODO: remove this directory and place a README in each task -------------------------------------------------------------------------------- /benchmarks/edward_bench.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/sh 2 | # Name: Upload all programs in bench.list to arduino (WARDuino) and time 3 | # By Robbert Gurdeep Singh 4 | ################################################################################ 5 | tmpfile="$(mktemp --tmpdir)" 6 | trap "rm '$tmpfile'" EXIT 7 | cd "$(dirname "$0")" 8 | date >$1 9 | make clean all 10 | make -C tasks all 11 | 12 | cat bench.list | while read l; do 13 | echo $l | tee -a $1 14 | ../scripts/upload ${BOARD:-ESP32WROVER} ./tasks/$l/wast/edward/edward.ino -p /dev/ttyUSB0 2>&1 >"$tmpfile" 15 | if [ "$?" -eq "0" ]; then 16 | echo "flashed" 17 | python3 flash_and_check.py | tee -a $1 18 | else 19 | cat $tmpfile 20 | echo "FAILED!" 21 | exit 1 22 | fi 23 | done 24 | -------------------------------------------------------------------------------- /benchmarks/espruino_bench.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/sh 2 | # Name: Upload all programs in bench.list to arduino and time 3 | # By Robbert Gurdeep Singh 4 | ################################################################################ 5 | set -e 6 | 7 | file=${1:-/tmp/res} 8 | cd "$(dirname "$0")" 9 | date >$file 10 | 11 | ./flash-espruino-esp32.sh 12 | 13 | echo "Sleep 5 sec till espruino boots" 14 | sleep 5 15 | 16 | cat bench.list | while read l; do 17 | echo $l | tee -a $file 18 | python flash_and_check.py tasks/$l/espruino/impl.js | tee -a $file 19 | done 20 | -------------------------------------------------------------------------------- /benchmarks/native_bench.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/sh 2 | # This scripts takes the name of a benchmark from the tasks folder and uploads 3 | # it to arduino and times the execution 4 | ################################################################################ 5 | 6 | tmpfile="$(mktemp --tmpdir)" 7 | trap "rm '$tmpfile'" EXIT 8 | cd "$(dirname "$0")" 9 | outloc=${2:--} 10 | 11 | echo $1 | tee -a $2 12 | ./upload ${BOARD:-ESP32WROVER} ./tasks/$1/c/c.ino 2>&1 >"$tmpfile" 13 | if [ "$?" -eq "0" ]; then 14 | echo "flashed" 15 | python3 flash_and_check.py $1 | tee -a $2 16 | else 17 | cat $tmpfile 18 | echo "FAILED!" 19 | exit 1 20 | fi 21 | -------------------------------------------------------------------------------- /benchmarks/rebench.conf: -------------------------------------------------------------------------------- 1 | # this run definition will be chosen if no parameters are given to rebench 2 | default_experiment: all 3 | default_data_file: 'example.data' 4 | 5 | reporting: 6 | rebenchdb: 7 | db_url: https://rebench.stefan-marr.de/rebenchdb 8 | repo_url: https://github.com/TOPLLab/WARDuino 9 | record_all: true 10 | project_name: WARDuino 11 | 12 | # a set of suites with different benchmarks and possibly different settings 13 | benchmark_suites: 14 | Microbenchmarks: 15 | gauge_adapter: RebenchLog 16 | command: "" 17 | benchmarks: 18 | - catalan 19 | - fac 20 | - fib 21 | - gcd 22 | - primes 23 | - tak 24 | - tak-mem 25 | 26 | # a set of executables for the benchmark execution 27 | executors: 28 | warduino: 29 | path: . 30 | executable: warduino_bench.sh 31 | env: 32 | PATH: /snap/bin/:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin 33 | args: " %(benchmark)s" 34 | build: 35 | - cd tasks; make 36 | 37 | 38 | # combining benchmark suites and executions 39 | experiments: 40 | Example: 41 | suites: 42 | - Microbenchmarks 43 | executions: 44 | - warduino 45 | 46 | -------------------------------------------------------------------------------- /benchmarks/tasks/.gitignore: -------------------------------------------------------------------------------- 1 | */wast/warduino/ 2 | */wast/edward/ 3 | */wast/wasm3/ 4 | */wast/*.wasm 5 | */wast/*.wast 6 | */wast/*.html 7 | */wast/*.js 8 | */c/*.ino 9 | 10 | -------------------------------------------------------------------------------- /benchmarks/tasks/catalan/espruino/impl.js: -------------------------------------------------------------------------------- 1 | function binomial(m, n){ 2 | var r = 1, d = m - n; 3 | if (d > n) { n = d; d = m - n; } 4 | 5 | while (m > n) { 6 | r *= m--; 7 | while (d > 1 && ! (r%d) ) r /= d--; 8 | } 9 | 10 | return r; 11 | } 12 | 13 | function catalan(n) { 14 | return binomial(2 * n, n) / (1 + n); 15 | } 16 | 17 | function main(){ 18 | var sum = 0; 19 | for (let i = 0; i < 10000; ++i) { 20 | sum += catalan((i + sum) % 18) % 100; 21 | } 22 | return sum % 256 23 | } 24 | 25 | console.log("START") 26 | for (let index = 0; index < 10; index++) { 27 | 28 | console.log( main()); // 113 29 | } 30 | console.log("DONE") 31 | -------------------------------------------------------------------------------- /benchmarks/tasks/catalan/wast/impl.c: -------------------------------------------------------------------------------- 1 | typedef unsigned long ull; 2 | 3 | ull binomial(ull m, ull n) { 4 | ull r = 1, d = m - n; 5 | if (d > n) { 6 | n = d; 7 | d = m - n; 8 | } 9 | 10 | while (m > n) { 11 | r *= m--; 12 | while (d > 1 && !(r % d)) r /= d--; 13 | } 14 | 15 | return r; 16 | } 17 | 18 | ull __attribute__((noinline)) catalan(int n) { 19 | return binomial(2 * n, n) / (1 + n); 20 | } 21 | 22 | int bench() { 23 | // printf("%lu!!",catalan(17) ); 24 | int sum = 0; 25 | 26 | #pragma clang loop unroll(disable) 27 | for (int i = 0; i < 10000; ++i) { 28 | sum += catalan((i + sum) % 18) % 100; 29 | } 30 | return sum % 256; // 113 31 | } 32 | -------------------------------------------------------------------------------- /benchmarks/tasks/fac/espruino/impl.js: -------------------------------------------------------------------------------- 1 | function fac(x) { 2 | if ( x <= 1 ){ 3 | return 1; 4 | } 5 | else { 6 | return (x*fac(x-1)); 7 | } 8 | 9 | } 10 | 11 | 12 | function main() { 13 | let sum = 0; 14 | for(let i = 0; i < 10000; i++){ 15 | sum += fac(i % 12); 16 | sum %= 97; 17 | } 18 | return sum; 19 | } 20 | 21 | 22 | 23 | console.log("START") 24 | for (let index = 0; index < 10; index++) { 25 | 26 | console.log(main()); // 228 27 | } 28 | console.log("DONE") 29 | -------------------------------------------------------------------------------- /benchmarks/tasks/fac/wast/impl.c: -------------------------------------------------------------------------------- 1 | unsigned long __attribute__((noinline)) fac(int x) { 2 | if (x <= 1) { 3 | return 1; 4 | } else { 5 | return (x * fac(x - 1)); 6 | } 7 | } 8 | 9 | int bench() { 10 | int sum = 0; 11 | #pragma clang loop unroll(disable) 12 | for (int i = 0; i < 10000; i++) { 13 | sum += fac(i % 12); 14 | sum %= 97; 15 | } 16 | return sum; 17 | } 18 | -------------------------------------------------------------------------------- /benchmarks/tasks/fib/espruino/impl.js: -------------------------------------------------------------------------------- 1 | function fib(n) { 2 | let first = 0, second = 1, next = 0; 3 | for (let c = 0; c < n; c++) { 4 | if (c <= 1) { 5 | next = c; 6 | } else { 7 | next = (first + second) % 100000000; 8 | first = second; 9 | second = next; 10 | } 11 | } 12 | return next; 13 | } 14 | 15 | function main(){ 16 | let sum = 0; 17 | for(let i = 1000; i < 1050; i++){ 18 | sum += fib(i); 19 | sum %= 97; 20 | } 21 | return sum; 22 | } 23 | 24 | console.log("START") 25 | for (let index = 0; index < 10; index++) { 26 | 27 | console.log(index,main()) 28 | } 29 | console.log("DONE") -------------------------------------------------------------------------------- /benchmarks/tasks/fib/wast/impl.c: -------------------------------------------------------------------------------- 1 | long __attribute__((noinline)) fib(int n) { 2 | unsigned long first = 0, second = 1, next = 0; 3 | for (unsigned c = 0; c < n; c++) { 4 | if (c <= 1) { 5 | next = c; 6 | } else { 7 | next = (first + second) % 100000000; 8 | first = second; 9 | second = next; 10 | } 11 | } 12 | return next; 13 | } 14 | 15 | int bench() { 16 | int sum = 0; 17 | #pragma clang loop unroll(disable) 18 | for (int i = 1000; i < 1050; i++) { 19 | sum += fib(i); 20 | sum %= 97; 21 | } 22 | return sum; 23 | // . ..122583354898000 24 | } 25 | -------------------------------------------------------------------------------- /benchmarks/tasks/gcd/espruino/impl.js: -------------------------------------------------------------------------------- 1 | function gcd(u, v) { 2 | return (v != 0) ? gcd(v, u % v) : u; 3 | } 4 | 5 | function main() { 6 | let sum = 0; 7 | for (let i = 40000; i < 50000; i++) { 8 | sum += gcd(i, 12345); 9 | } 10 | return sum; 11 | } 12 | 13 | console.log("START") 14 | for (let index = 0; index < 10; index++) { 15 | 16 | console.log(main()) 17 | } 18 | console.log("DONE") -------------------------------------------------------------------------------- /benchmarks/tasks/gcd/wast/impl.c: -------------------------------------------------------------------------------- 1 | int __attribute__((noinline)) gcd(int u, int v) { 2 | return (v != 0) ? gcd(v, u % v) : u; 3 | } 4 | 5 | int bench() { 6 | int sum = 0; 7 | for (int i = 40000; i < 50000; i++) { 8 | sum += gcd(i, 12345); 9 | } 10 | return sum; 11 | } 12 | -------------------------------------------------------------------------------- /benchmarks/tasks/makefile: -------------------------------------------------------------------------------- 1 | TASKS=$(patsubst %/.,%,$(wildcard */.)) 2 | 3 | all: $(addsuffix /wast/warduino/warduino.ino,$(TASKS)) $(addsuffix /wast/edward/edward.ino,$(TASKS)) $(addsuffix /wast/wasm3/wasm3.ino,$(TASKS)) $(addsuffix /wast/impl.wast,$(TASKS)) $(addsuffix /wast/impl.wasm,$(TASKS)) $(addsuffix /c/c.ino,$(TASKS)) 4 | 5 | echo $(TASKS) 6 | 7 | 8 | %/wast/warduino/warduino.ino: %/wast/impl.wasm 9 | -mkdir $(@D) 10 | xxd -i $< $@ 11 | sed -i 's/[^ ]*_impl_wasm/impl_wasm/' $@ 12 | cat ../warduino.ino.template >> $@ 13 | 14 | %/wast/edward/edward.ino: %/wast/impl.wasm 15 | -mkdir $(@D) 16 | xxd -i $< $@ 17 | sed -i 's/[^ ]*_impl_wasm/impl_wasm/' $@ 18 | cat ../edward.ino.template >> $@ 19 | 20 | %/wast/wasm3/wasm3.ino: %/wast/impl.wasm 21 | -mkdir $(@D) 22 | xxd -i $< $@ 23 | sed -i 's/[^ ]*_impl_wasm/impl_wasm/' $@ 24 | cat ../wasm3.ino.template >> $@ 25 | 26 | %/c/c.ino: %/wast/impl.c ../c.ino.template 27 | -mkdir $(@D) 28 | echo '#include "Arduino.h"' > $@ 29 | echo '#pragma GCC optimize ("O0")' >> $@ 30 | cat $^ | \ 31 | sed '/#pragma \+nounroll/d' | \ 32 | sed '/int *main() */s/int/int __attribute__((optimize("no-unroll-loops")))/' | \ 33 | sed '/#include \+"Arduino.h"/d'>> $@ 34 | 35 | %/wast/impl.wasm: %/wast/impl.c 36 | clang $< \ 37 | --target=wasm32 \ 38 | -Oz \ 39 | -flto \ 40 | -nostdlib \ 41 | -Wl,--export-all \ 42 | -Wl,--no-entry \ 43 | -Wl,--strip-all \ 44 | -Wl,--lto-O3 \ 45 | -o $@ 46 | cat $@ > /dev/null 47 | 48 | %/wast/impl.wast: %/wast/impl.wasm 49 | wasm2wat -f $< > $@ 50 | 51 | clean: 52 | -find -iname "impl.wast" -o -iname "impl.wasm" -o -iname "c.ino" -o -iname "warduino.ino" -o -iname "edward.ino" -o -iname "wasm3.ino" | xargs rm 53 | 54 | -------------------------------------------------------------------------------- /benchmarks/tasks/primes/espruino/impl.js: -------------------------------------------------------------------------------- 1 | 2 | function is_prime(n) { 3 | if (n < 3) { 4 | return n > 1; 5 | } else { 6 | if ((n % 2 == 0) || (n % 3 == 0)) { 7 | return false; 8 | } else { 9 | let i = 5; 10 | while (i * i <= n) { 11 | if ((n % i == 0) || (n % (i + 2) == 0)) { 12 | return false; 13 | } 14 | i += 6; 15 | } 16 | return true; 17 | 18 | } 19 | } 20 | } 21 | 22 | function main() { 23 | let sum = 0; 24 | let count = 0; 25 | for (let i = 1; sum < 13374242; i++) { 26 | if (is_prime(i)){ 27 | sum += i; 28 | count++; 29 | } 30 | } 31 | return count; 32 | } 33 | 34 | 35 | 36 | console.log("START") 37 | for (let index = 0; index < 10; index++) { 38 | 39 | console.log(main()) 40 | } 41 | console.log("DONE") 42 | -------------------------------------------------------------------------------- /benchmarks/tasks/primes/wast/impl.c: -------------------------------------------------------------------------------- 1 | int __attribute__((noinline)) is_prime(unsigned n) { 2 | if (n < 3) { 3 | return n > 1; 4 | } else { 5 | if ((n % 2 == 0) || (n % 3 == 0)) { 6 | return 0; 7 | } else { 8 | unsigned i = 5; 9 | while (i * i <= n) { 10 | if ((n % i == 0) || (n % (i + 2) == 0)) { 11 | return 0; 12 | } 13 | i += 6; 14 | } 15 | return 1; 16 | } 17 | } 18 | } 19 | 20 | /* 21 | * 22 | * function is_prime(n) 23 | if n ≤ 3 24 | return n > 1 25 | else if n mod 2 = 0 or n mod 3 = 0 26 | return false 27 | let i ← 5 28 | while i * i ≤ n 29 | if n mod i = 0 or n mod (i + 2) = 0 30 | return false 31 | i ← i + 6 32 | return true 33 | * */ 34 | int bench() { 35 | unsigned sum = 0; 36 | int count = 0; 37 | for (unsigned i = 1; sum < 13374242; i++) { 38 | if (is_prime(i)) { 39 | sum += i; 40 | count++; 41 | } 42 | } 43 | return count; 44 | } 45 | -------------------------------------------------------------------------------- /benchmarks/tasks/tak-mem/espruino/impl.js: -------------------------------------------------------------------------------- 1 | function tak(x, y, z) { 2 | if (!(y < x)) { 3 | return z; 4 | } 5 | else { 6 | return tak(tak(x - 1, y, z), 7 | tak(y - 1, z, x), 8 | tak(z - 1, x, y)); 9 | } 10 | 11 | } 12 | 13 | 14 | 15 | console.log("START") 16 | for (let index = 0; index < 10; index++) { 17 | 18 | console.log(tak(18, 12, 6)) 19 | } 20 | console.log("DONE") -------------------------------------------------------------------------------- /benchmarks/tasks/tak-mem/wast/impl.c: -------------------------------------------------------------------------------- 1 | int tak(int x, int y, int z) { 2 | if (!(y < x)) { 3 | return z; 4 | } else { 5 | return tak(tak(x - 1, y, z), tak(y - 1, z, x), tak(z - 1, x, y)); 6 | } 7 | } 8 | 9 | int bench() { return tak(18, 12, 6); } 10 | -------------------------------------------------------------------------------- /benchmarks/tasks/tak/espruino/impl.js: -------------------------------------------------------------------------------- 1 | function tak(x, y, z) { 2 | if (!(y < x)) { 3 | return z; 4 | } 5 | else { 6 | return tak(tak(x - 1, y, z), 7 | tak(y - 1, z, x), 8 | tak(z - 1, x, y)); 9 | } 10 | 11 | } 12 | 13 | 14 | 15 | console.log("START") 16 | for (let index = 0; index < 10; index++) { 17 | 18 | console.log(tak(18, 12, 6)) 19 | } 20 | console.log("DONE") -------------------------------------------------------------------------------- /benchmarks/tasks/tak/wast/impl.c: -------------------------------------------------------------------------------- 1 | int __attribute__((noinline)) tak(int x, int y, int z) { 2 | if (!(y < x)) { 3 | return z; 4 | } else { 5 | return tak(tak(x - 1, y, z), tak(y - 1, z, x), tak(z - 1, x, y)); 6 | } 7 | } 8 | 9 | int bench() { return tak(18, 12, 6); } 10 | -------------------------------------------------------------------------------- /benchmarks/timer.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | class Timer { 5 | public: 6 | Timer() : beg_(clock_::now()) {} 7 | 8 | void reset() { beg_ = clock_::now(); } 9 | 10 | double elapsed() const { 11 | return std::chrono::duration_cast(clock_::now() - beg_) 12 | .count(); 13 | } 14 | 15 | private: 16 | typedef std::chrono::high_resolution_clock clock_; 17 | typedef std::chrono::duration > second_; 18 | std::chrono::time_point beg_; 19 | }; 20 | -------------------------------------------------------------------------------- /benchmarks/upload: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Name: 3 | # By Robbert Gurdeep Singh 4 | # --pref build.path=/tmp/build 5 | # The above extra arguments allows specifying a build loc 6 | ################################################################################ 7 | set -x -e 8 | 9 | device="$(echo "${1?-Please specify a device type}" | tr '[:lower:]' '[:upper:]')" 10 | file=${2?-No file to upload} 11 | shift 2 12 | 13 | if [ -n "$USE_TMPDIR" ]; then 14 | tmpfile="$(mktemp -d --tmpdir)" 15 | trap "rm -rf '$tmpfile'" EXIT 16 | cp "$file" "$tmpfile/prog.c" 17 | cd "$tmpfile" 18 | file="prog.c" 19 | fi 20 | 21 | case "$device" in 22 | "ESP32") 23 | exec arduino --upload "$file" --board "esp32:esp32:esp32doit-devkit-v1:FlashFreq=80,UploadSpeed=921600,DebugLevel=none" "$@" 24 | ;; 25 | "ESP32WROVER") 26 | exec arduino --upload "$file" --board "esp32:esp32:esp32wrover:FlashFreq=80,UploadSpeed=921600,DebugLevel=none" "$@" 27 | ;; 28 | "ESP8266") 29 | exec arduino --upload "$file" --board "esp8266:esp8266:nodemcu:xtal=80,vt=flash,exception=disabled,ssl=all,eesz=4M,ip=lm2f,dbg=Disabled,lvl=None____,wipe=all,baud=115200" "$@" 30 | ;; 31 | *) 32 | echo "Unknown device: $device" 33 | exit 1 34 | esac 35 | 36 | echo "done" 37 | -------------------------------------------------------------------------------- /benchmarks/warduino.ino.template: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "WARDuino.h" 3 | 4 | WARDuino* wac = WARDuino::instance(); 5 | 6 | #define D1 5 7 | 8 | volatile bool handelingInterrupt = false; 9 | uint8_t buff[100] = {0}; 10 | uint8_t buff_len = 0; 11 | 12 | void ICACHE_RAM_ATTR handleInput() { 13 | if (handelingInterrupt) return; 14 | handelingInterrupt = true; 15 | interrupts(); 16 | 17 | while (Serial.available()) { 18 | size_t buff_len = 0; 19 | while (Serial.available()) { 20 | buff[buff_len++] = (int8_t)Serial.read(); 21 | } 22 | if (buff_len) { 23 | wac->handleInterrupt(buff_len, buff); 24 | } 25 | } 26 | handelingInterrupt = false; 27 | } 28 | 29 | void setup() { 30 | Serial.begin(115200); 31 | attachInterrupt(D1, handleInput, CHANGE); 32 | } 33 | 34 | void loop() { 35 | Module *m = wac->load_module(impl_wasm, impl_wasm_len, {}); 36 | delay(1000); 37 | printf("START\n\n"); 38 | for (int i = 0; i < 10; i++) { 39 | wac->run_module(m); 40 | printf("%d: %u\n", i, m->stack->value.uint32); 41 | } 42 | wac->unload_module(m); 43 | printf("DONE\n\n"); 44 | } 45 | -------------------------------------------------------------------------------- /benchmarks/warduino_bench.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/sh 2 | # This scripts takes the name of a benchmark from the tasks folder and uploads 3 | # it to arduino and times the execution 4 | ################################################################################ 5 | 6 | tmpfile="$(mktemp --tmpdir)" 7 | trap "rm '$tmpfile'" EXIT 8 | cd "$(dirname "$0")" 9 | outloc=${2:--} 10 | 11 | echo $1 | tee -a $2 12 | ./upload ${BOARD:-ESP32WROVER} ./tasks/$1/wast/warduino/warduino.ino 2>&1 >"$tmpfile" 13 | if [ "$?" -eq "0" ]; then 14 | echo "flashed" 15 | python3 flash_and_check.py $1 | tee -a $2 16 | else 17 | cat $tmpfile 18 | echo "FAILED!" 19 | exit 1 20 | fi 21 | -------------------------------------------------------------------------------- /benchmarks/wasm3.ino.template: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "wasm3.h" 3 | 4 | #define FATAL(func, msg) { \ 5 | Serial.print("Fatal: " func ": "); \ 6 | Serial.println(msg); return; } 7 | 8 | void setup() 9 | { 10 | 11 | Serial.begin(115200); 12 | delay(10); 13 | while (!Serial) {} 14 | } 15 | 16 | void loop() 17 | { 18 | // Load module 19 | M3Result result = m3Err_none; 20 | 21 | uint8_t* wasm = (uint8_t*)impl_wasm; 22 | size_t fsize = impl_wasm_len; 23 | 24 | IM3Environment env = m3_NewEnvironment (); 25 | if (!env) FATAL("m3_NewEnvironment", "failed"); 26 | 27 | IM3Runtime runtime = m3_NewRuntime (env, 1024, NULL); 28 | if (!runtime) FATAL("m3_NewRuntime", "failed"); 29 | 30 | IM3Module module; 31 | result = m3_ParseModule (env, &module, wasm, fsize); 32 | if (result) FATAL("m3_ParseModule", result); 33 | 34 | result = m3_LoadModule (runtime, module); 35 | if (result) FATAL("m3_LoadModule", result); 36 | 37 | IM3Function f; 38 | result = m3_FindFunction (&f, runtime, "bench"); 39 | if (result) FATAL("m3_FindFunction", result); 40 | 41 | // Run benchmark 42 | delay(1000); 43 | printf("START\n\n"); 44 | for (int i = 0; i < 10; i++) { 45 | result = m3_CallV(f); 46 | if (result) FATAL("m3_Call", result); 47 | 48 | uint32_t value = 0; 49 | result = m3_GetResultsV (f, &value); 50 | if (result) FATAL("m3_GetResults: %s", result); 51 | 52 | printf("%d: %u\n", i, value); 53 | } 54 | m3_FreeModule(module); 55 | printf("DONE\n\n"); 56 | } 57 | -------------------------------------------------------------------------------- /benchmarks/wasm3_bench.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/sh 2 | # Name: Upload all programs in bench.list to arduino (Wasm3) and time 3 | ################################################################################ 4 | tmpfile="$(mktemp --tmpdir)" 5 | trap "rm '$tmpfile'" EXIT 6 | cd "$(dirname "$0")" 7 | date >$1 8 | make clean all 9 | make -C tasks all 10 | 11 | cat bench.list | while read l; do 12 | echo $l | tee -a $1 13 | ../scripts/upload ${BOARD:-ESP32WROVER} ./tasks/$l/wast/wasm3/wasm3.ino 2>&1 >"$tmpfile" 14 | if [ "$?" -eq "0" ]; then 15 | echo "flashed" 16 | python flash_and_check.py | tee -a $1 17 | else 18 | cat $tmpfile 19 | echo "FAILED!" 20 | exit 1 21 | fi 22 | done 23 | -------------------------------------------------------------------------------- /documentation/InstallArduinoESP32.md: -------------------------------------------------------------------------------- 1 | # Install instructions for Arduino ESP32 2 | 3 | To use ESP32 boards with the WARDuino project you need to install the correct board manager for ESP32. 4 | 5 | ## Installing the board manager for ESP32 6 | 7 | To use the ESP32 boards with `arduino-cli` perform the following steps: 8 | 9 | 1. Init the config file, if you have not done so yet. 10 | 11 | ``` 12 | arduino-cli config init 13 | ``` 14 | 15 | 2. To find the location of your config file you can run: 16 | 17 | ``` 18 | arduino-cli config dump --verbose 19 | ``` 20 | 21 | 3. Add the ESP32 board manager URL to the config file: 22 | 23 | ``` 24 | board_manager: 25 | additional_urls: 26 | - https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_dev_index.json 27 | ``` 28 | 29 | 4. Update index 30 | 31 | ``` 32 | arduino-cli core update-index 33 | ``` 34 | 35 | 5. Install the ESP32 platform: 36 | 37 | ``` 38 | arduino-cli core install esp32:esp32 39 | ``` 40 | 41 | To use ESP32 boards with the WARDuino Project you need at least version 2.0.2 of the board manager. 42 | you can check your version with: 43 | 44 | ``` 45 | arduino-cli core list 46 | ``` 47 | 48 | ## Additional information 49 | 50 | More information on how to use `arduino-cli` can be found [here](https://arduino.github.io/arduino-cli/0.21/getting-started/). 51 | 52 | -------------------------------------------------------------------------------- /documentation/Interrupts.md: -------------------------------------------------------------------------------- 1 | # Interrupts 2 | 3 | Warduino reacts to interrups sent via the serial port. To hook onto these changes, 4 | we need to connect the RX pin to the D1 pin. We then set an interrupt handler on 5 | chnages of this pin. 6 | 7 | The interrupt handler, reads the input and passes it on to WARDuino trough the 8 | `handleInterrupt()` method. This method read the incomming data as HEX and 9 | transformes it into binary data (`uint8_t[]`). A HEX sequence may be ended with 10 | any non-hex character (`[^0-9A-F]`). A HEX sequence must not contain a non-hex 11 | character, it should match `([0-9A-F][0-9A-F])+` 12 | 13 | The first two character of the HEX sequence (that is the first byte of the 14 | translated binary data) differentiates between the various interrup types. 15 | 16 | See: [src/Debug/Debugger.cpp](../src/Debug/Debugger.cpp) 17 | -------------------------------------------------------------------------------- /documentation/OutOfPlaceDebugging.md: -------------------------------------------------------------------------------- 1 | # Out-of-place debugging 2 | 3 | Aside from traditional remote debugging, the WARDuino virtual machine also supports pull-push debugging. 4 | 5 | ## Pull-based OOP Debugging 6 | 7 | With pull debugging the current application is debugged in a local emulated WARDuino instance, but with live actuator 8 | and sensor values from a drone device. To get current values, the emulated debugger initiates proxy calls to the drone 9 | device. The debugger will wait until this call has completed and the result is returned by the drone. 10 | 11 | Communication happens through a minimal byte format. 12 | 13 | ## Push-based OOP Debugging 14 | 15 | A drone device can also push live values to the emulated debugger. These will typically be asynchronous events such as 16 | hardware interrupts, exceptions, ... 17 | 18 | Those are represented by `Events` in WARDuino and send by the drone device as simple json: 19 | 20 | ```json 21 | { 22 | "topic": "topic string", 23 | "payload": "payload as a string" 24 | } 25 | ``` 26 | 27 | The supported interrupt messages: 28 | 29 | 1. `interruptDUMPAllEvents (0x70)` dumps all events. 30 | 2. `interruptDUMPEvents (0x71)` this message' code is followed by two bytes, `a` and `b`. The command dumps at most `b` 31 | events, starting in the event queue from index `a`. 32 | 3. `interruptPOPEvent (0x72)` tells the VM to remove the event at the front of the queue and process it. 33 | 4. `interruptPUSHEvent (0x73)` this messages' code is followed by a json representation of an event to be pushed on the 34 | stack. 35 | 5. `interruptDUMPCallbackmapping (0x74)` requests a dump of the current callback mapping as json. 36 | 6. `interruptRecvCallbackmapping (0x75)` sends a callback mapping as json to replace the current callback mapping. 37 | 38 | -------------------------------------------------------------------------------- /documentation/decompile.txt: -------------------------------------------------------------------------------- 1 | MAGIC NUMBER: 00 61 73 6d 2 | VERSION: 01 00 00 00 3 | 4 | ;----------------------------------------------------- 5 | TYPE SECTION : 01 == Section 1 6 | CONTENT SIZE : 0a == 10 bytes 7 | 8 | VECTOR SIZE : 02 == Size of the vector is 2 9 | 10 | START FUNTYPE : 60 11 | VECTOR SIZE : 02 == Two arguments 12 | VALTYPE : 7f == I32 13 | VALTYPE : 7f == I32 14 | VECTOR SIZE : 01 == One return type 15 | VALTYPE : 7f == I32 16 | 17 | START FUNTYPE : 60 18 | VECTOR SIZE : 00 == No argument types 19 | VECTOR SIZE : 00 == No return type 20 | 21 | ;----------------------------------------------------- 22 | IMPORT SECTION : 02 == Section 2 23 | CONTENT SIZE : 11 == 17 bytes 24 | 25 | VECTOR SIZE : 01 26 | VECTOR SIZE : 07 == Module name 27 | [65,73,70,38,32,36,36] == “esp8266” 28 | VECTOR SIZE : 05 == Import name 29 | [62,6c,69,6e,6b] == "blink” 30 | FUN x : 00 31 | TYPE IDX : 01 32 | ;----------------------------------------------------- 33 | FUNCTION SECTION : 03 34 | CONTENT SIZE : 02 == 2 bytes 35 | VECTOR SIZE : 01 36 | TYPE INDEX : 00 37 | 38 | 39 | 40 | ;----------------------------------------------------- 41 | MEMORY SECTION : 05 42 | CONTENT SIZE : 06 == 6 bytes 43 | VECTOR LENGTH : 01 44 | LIMIT : 01 45 | MIN : 80 02 == ??? should be 256 46 | MAX : 80 02 == ??? should be 256 47 | 48 | ;----------------------------------------------------- 49 | EXPORT SECTION : 07 50 | CONTENT SIZE : 07 == 7 bytes 51 | VECTOR LENGTH : 01 52 | NAME : 03 53 | [61, 64, 64] == “add” 54 | FUNCTION : 00 55 | FUN INDEX : 01 56 | 57 | 58 | ;----------------------------------------------------- 59 | CODE SECTION : 0a 60 | CONTENT SIZE : 09 61 | VEC : 01 62 | SIZE : 07 (size code) 63 | VEC_LOCAL : 00 (no locals) 64 | 20 00 20 01 6a 0b 65 | -------------------------------------------------------------------------------- /keywords.txt: -------------------------------------------------------------------------------- 1 | WARDuino KEYWORD1 2 | load_module KEYWORD2 3 | run_module KEYWORD2 4 | invoke KEYWORD2 5 | unload_module KEYWORD2 6 | addBreakpoint KEYWORD2 7 | deleteBreakpoint KEYWORD2 8 | isBreakpoint KEYWORD2 9 | handleInterrupt KEYWORD2 -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=WARDuino 2 | version=0.6.1 3 | author=Robbert Gurdeep Singh, Christophe Scholliers , Tom Lauwaerts , Carlos Rojas Castillo , Maarten Steevens , Joel Martin 4 | maintainer=Tom Lauwaerts , Maarten Steevens , Christophe Scholliers 5 | sentence=A library that enables the use of WebAssembly on Arduino boards with debugging support 6 | paragraph= 7 | category=Communication 8 | url=https://github.com/TOPLLab/WARDuino 9 | architectures=esp8266,esp32 10 | -------------------------------------------------------------------------------- /platforms/Arduino/.gitignore: -------------------------------------------------------------------------------- 1 | bin/ 2 | .config 3 | Arduino.ino 4 | *.wasm 5 | -------------------------------------------------------------------------------- /platforms/Arduino/Arduino.ino.template: -------------------------------------------------------------------------------- 1 | // 2 | // WARDuino - WebAssembly interpreter for embedded devices. 3 | // 4 | // 5 | #include 6 | 7 | #include "Arduino.h" 8 | #include "bin/upload.h" 9 | 10 | unsigned int wasm_len = upload_wasm_len; 11 | unsigned char* wasm = upload_wasm; 12 | 13 | WARDuino* wac = WARDuino::instance(); 14 | Module* m; 15 | 16 | #define UART_PIN 3 17 | 18 | void startDebuggerStd(void* pvParameter) { 19 | Channel* sink = new Sink(stdout); 20 | wac->debugger->setChannel(sink); 21 | sink->open(); 22 | 23 | uint8_t buffer[1024] = {0}; 24 | while (true) { 25 | yield(); 26 | 27 | while (Serial.available()) { 28 | size_t buff_len = 0; 29 | while (Serial.available()) { 30 | buffer[buff_len++] = (int8_t)Serial.read(); 31 | } 32 | if (buff_len) { 33 | buffer[buff_len] = '\0'; 34 | wac->handleInterrupt(buff_len, buffer); 35 | } 36 | } 37 | } 38 | } 39 | 40 | void setup(void) { 41 | Serial.begin(115200); 42 | // attachInterrupt(UART_PIN, handleInput, CHANGE); 43 | 44 | Serial.println(ESP.getFreeHeap()); 45 | Serial.println("Total heap:"); 46 | Serial.println(ESP.getHeapSize()); 47 | Serial.println("\nFree heap:"); 48 | Serial.println(ESP.getFreeHeap()); 49 | Serial.println("\nTotal PSRAM:"); 50 | Serial.println(ESP.getPsramSize()); 51 | Serial.println("\nFree PSRAM: "); 52 | Serial.println(ESP.getFreePsram()); 53 | } 54 | 55 | void loop() { 56 | m = wac->load_module(wasm, wasm_len, {}); 57 | 58 | printf("LOADED \n\n"); 59 | {{PAUSED}} 60 | xTaskCreate(startDebuggerStd, "Debug Thread", 5000, NULL, 1, NULL); 61 | 62 | disableCore0WDT(); 63 | printf("START\n\n"); 64 | 65 | Serial.println("\nFree heap:"); 66 | Serial.println(ESP.getFreeHeap()); 67 | 68 | wac->run_module(m); 69 | printf("END\n\n"); 70 | wac->unload_module(m); 71 | } 72 | -------------------------------------------------------------------------------- /platforms/Arduino/Makefile: -------------------------------------------------------------------------------- 1 | # Arduino Platform 2 | 3 | # default values 4 | PORT = /dev/ttyUSB0 5 | FQBN = esp32:esp32:esp32wrover 6 | 7 | # possible config file 8 | CONFIG = .config 9 | -include ${CONFIG} 10 | 11 | ifdef PAUSED 12 | COMMAND := uint8_t command[] = {'0', '3', '\\\n'}; wac->handleInterrupt(3, command); 13 | else 14 | COMMAND := 15 | endif 16 | 17 | clean: 18 | rm -f Arduino.ino 19 | rm -rf bin 20 | 21 | bin: 22 | mkdir bin 23 | 24 | bin/upload.h: bin 25 | ifndef BINARY 26 | $(error BINARY is not set. Use a .config file) 27 | endif 28 | cp $(BINARY) bin/upload.wasm 29 | cd bin; xxd -i upload.wasm > upload.h 30 | 31 | Arduino.ino: bin/upload.h Arduino.ino.template 32 | cat Arduino.ino.template > $@ 33 | sed "s/{{PAUSED}}/$(COMMAND)/" $@ > Arduino.tmp 34 | mv Arduino.tmp $@ 35 | 36 | 37 | flash: Arduino.ino 38 | ifndef PORT 39 | $(error PORT is not set. Use a .config file) 40 | endif 41 | ifndef FQBN 42 | $(error FQBN is not set. Use a .config file) 43 | endif 44 | arduino-cli upload -p $(PORT) --fqbn $(FQBN) Arduino.ino 45 | 46 | recompile: Arduino.ino 47 | ifndef FQBN 48 | $(error FQBN is not set. Use a .config file) 49 | endif 50 | arduino-cli compile --fqbn $(FQBN) Arduino.ino 51 | 52 | compile: clean recompile 53 | 54 | monitor: 55 | ifndef PORT 56 | $(error PORT is not set. Use a .config file) 57 | endif 58 | arduino-cli monitor -p $(PORT) -c baudrate=115200 59 | 60 | -------------------------------------------------------------------------------- /platforms/Arduino/README.md: -------------------------------------------------------------------------------- 1 | # Arduino platform for WARDuino 2 | 3 | This folder contains the code for staging and flashing WARDuino with the `arduino-cli`. 4 | 5 | To upload a program take the following steps: 6 | 7 | 1. compile your program to a `.wasm` WebAssembly binary 8 | 2. compile Arduino hexfile with: 9 | ```bash 10 | make compile BINARY={{Path to .wasm file}} FQBN={{fqbn of target device}} 11 | ``` 12 | 3. flash to device 13 | ```bash 14 | make flash PORT={{serial port}} FQBN={{fqbn of target device}} 15 | ``` 16 | 17 | Alternatively you can pass the make arguments via a `.config` file that looks like this: 18 | 19 | ```make 20 | PORT = /dev/ttyUSB0 21 | FQBN = esp32:esp32:esp32wrover 22 | PAUSED = true 23 | BINARY = test.wasm 24 | ``` 25 | 26 | Place this file in the same directory as the `Makefile`, you can now just run `make compile`. 27 | 28 | -------------------------------------------------------------------------------- /platforms/CLI-Emulator/README.md: -------------------------------------------------------------------------------- 1 | # Command Line Interface for WARDuino 2 | 3 | This folder contains a command line interface for running the WARDuino virtual machine in a desktop environment. 4 | 5 | 6 | ```bash 7 | $ wdcli --help 8 | ``` 9 | 10 | -------------------------------------------------------------------------------- /platforms/ESP-IDF/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(SOURCE_FILES 2 | ../../src/Debug/debugger.cpp 3 | ../../src/Interpreter/instructions.cpp 4 | ../../src/Interpreter/interpreter.cpp 5 | ../../src/Memory/mem.cpp 6 | ../../src/Primitives/idf.cpp 7 | ../../src/Edward/proxy.cpp 8 | ../../src/Edward/proxy_supervisor.cpp 9 | ../../src/Edward/RFC.cpp 10 | ../../src/Utils/macros.cpp 11 | ../../src/Utils/sockets.cpp 12 | ../../src/Utils/util.cpp 13 | ../../src/Utils/util_arduino.cpp 14 | ../../src/WARDuino/CallbackHandler.cpp 15 | ../../src/WARDuino/WARDuino.cpp 16 | ) 17 | 18 | idf_component_register(SRCS "main.cpp" ${SOURCE_FILES} INCLUDE_DIRS ../../lib/json/single_include/ REQUIRES driver) 19 | 20 | add_definitions(-DINFO=0) 21 | add_definitions(-DDEBUG=0) 22 | add_definitions(-DTRACE=0) 23 | add_definitions(-DWARN=0) 24 | add_definitions(-DESP=1) 25 | -------------------------------------------------------------------------------- /platforms/ESP-IDF/main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // WARDuino - WebAssembly interpreter for embedded devices. 3 | // 4 | // 5 | #include 6 | 7 | #include "../../src/WARDuino.h" 8 | #include "driver/gpio.h" 9 | #include "driver/uart.h" 10 | #include "esp_err.h" 11 | #include "esp_task_wdt.h" 12 | #include "freertos/FreeRTOS.h" 13 | #include "freertos/task.h" 14 | #include "sdkconfig.h" 15 | #include "upload.h" 16 | 17 | volatile bool handelingInterrupt = false; 18 | 19 | unsigned int wasm_len = upload_wasm_len; 20 | unsigned char* wasm = upload_wasm; 21 | 22 | extern "C" { 23 | extern void app_main(void); 24 | } 25 | 26 | WARDuino* wac = WARDuino::instance(); 27 | Module* m; 28 | 29 | void startDebuggerStd(void* pvParameter) { 30 | Channel* duplex = new Duplex(stdin, stdout); 31 | wac->debugger->setChannel(duplex); 32 | duplex->open(); 33 | 34 | int valread; 35 | uint8_t buffer[1024] = {0}; 36 | while (true) { 37 | taskYIELD(); 38 | vTaskDelay(1000 / portTICK_PERIOD_MS); 39 | 40 | while ((valread = duplex->read(buffer, 1024)) != -1) { 41 | wac->handleInterrupt(valread, buffer); 42 | } 43 | } 44 | } 45 | 46 | void app_main(void) { 47 | m = wac->load_module(wasm, wasm_len, {}); 48 | // uint8_t command[] = {'0', '3', '\n'}; 49 | // wac->handleInterrupt(3, command); 50 | xTaskCreate(startDebuggerStd, "Debug Thread", 5000, NULL, 51 | 10 /**tskIDLE_PRIORITY*/, NULL); 52 | printf("START\n\n"); 53 | wac->run_module(m); 54 | printf("END\n\n"); 55 | wac->unload_module(m); 56 | } 57 | -------------------------------------------------------------------------------- /platforms/ESP-IDF/upload.h: -------------------------------------------------------------------------------- 1 | unsigned char upload_wasm[] = { 2 | 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0d, 0x03, 0x60, 3 | 0x02, 0x7f, 0x7f, 0x00, 0x60, 0x01, 0x7f, 0x00, 0x60, 0x00, 0x00, 0x02, 4 | 0x3f, 0x03, 0x03, 0x65, 0x6e, 0x76, 0x0a, 0x63, 0x68, 0x69, 0x70, 0x5f, 5 | 0x64, 0x65, 0x6c, 0x61, 0x79, 0x00, 0x01, 0x03, 0x65, 0x6e, 0x76, 0x0d, 6 | 0x63, 0x68, 0x69, 0x70, 0x5f, 0x70, 0x69, 0x6e, 0x5f, 0x6d, 0x6f, 0x64, 7 | 0x65, 0x00, 0x00, 0x03, 0x65, 0x6e, 0x76, 0x12, 0x63, 0x68, 0x69, 0x70, 8 | 0x5f, 0x64, 0x69, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x5f, 0x77, 0x72, 0x69, 9 | 0x74, 0x65, 0x00, 0x00, 0x03, 0x03, 0x02, 0x02, 0x02, 0x06, 0x10, 0x03, 10 | 0x7f, 0x00, 0x41, 0x17, 0x0b, 0x7f, 0x00, 0x41, 0x01, 0x0b, 0x7f, 0x00, 11 | 0x41, 0x00, 0x0b, 0x07, 0x08, 0x01, 0x04, 0x6d, 0x61, 0x69, 0x6e, 0x00, 12 | 0x04, 0x0a, 0x2f, 0x02, 0x08, 0x00, 0x23, 0x00, 0x41, 0x02, 0x10, 0x01, 13 | 0x0b, 0x24, 0x01, 0x01, 0x7f, 0x41, 0xe8, 0x07, 0x21, 0x00, 0x10, 0x03, 14 | 0x03, 0x40, 0x23, 0x00, 0x23, 0x01, 0x10, 0x02, 0x20, 0x00, 0x10, 0x00, 15 | 0x23, 0x00, 0x23, 0x02, 0x10, 0x02, 0x20, 0x00, 0x10, 0x00, 0x0c, 0x00, 16 | 0x0b, 0x0b}; 17 | unsigned int upload_wasm_len = 170; 18 | -------------------------------------------------------------------------------- /platforms/README.md: -------------------------------------------------------------------------------- 1 | # Platforms 2 | 3 | This folder contains the code necessary to compile WARDuino for the different supported platforms. 4 | 5 | - Arduino: WARDuino with primitives implemented for the Arduino platform 6 | - Arduino-socket: WARDuino with primitives implemented for the Arduino platform and a socket server to debug over Wi-Fi 7 | - CLI-EMULATOR: a cli for WARDuino with emulated primitives, to run on desktop environments 8 | - ESP-IDF: WARDuino compiled with the ESP-IDF toolchain 9 | 10 | -------------------------------------------------------------------------------- /platforms/Zephyr/.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | upload.h 3 | *.wasm 4 | *.wat 5 | .cache 6 | -------------------------------------------------------------------------------- /platforms/Zephyr/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.20.0) 2 | find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) 3 | project(warduino) 4 | 5 | # Note on _POSIX_C_SOURCE: If you define this macro to a value greater than or equal to 200809L, then the functionality from the 2008 edition of the POSIX standard (IEEE Standard 1003.1-2008) is made available. 6 | target_compile_definitions(app PRIVATE _POSIX_C_SOURCE=200809L) 7 | 8 | add_custom_command( 9 | OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/upload.h 10 | COMMAND xxd -i upload.wasm > upload.h 11 | DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/upload.wasm 12 | WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} 13 | ) 14 | 15 | target_sources(app PRIVATE 16 | main.cpp 17 | ../../src/WARDuino/WARDuino.cpp 18 | ../../src/WARDuino/CallbackHandler.cpp 19 | ../../src/Interpreter/instructions.cpp 20 | ../../src/Interpreter/interpreter.cpp 21 | ../../src/Primitives/zephyr.cpp 22 | ../../src/Memory/mem.cpp 23 | ../../src/Utils/util.cpp 24 | ../../src/Utils/util_arduino.cpp 25 | ../../src/Utils/macros.cpp 26 | ../../src/Utils/sockets.cpp 27 | ../../src/Debug/debugger.cpp 28 | ../../src/Edward/proxy.cpp 29 | ../../src/Edward/proxy_supervisor.cpp 30 | ../../src/Edward/RFC.cpp 31 | upload.h 32 | ) 33 | 34 | include_directories(../../lib/json/single_include/) 35 | -------------------------------------------------------------------------------- /platforms/Zephyr/Kconfig: -------------------------------------------------------------------------------- 1 | source "samples/subsys/usb/common/Kconfig.sample_usbd" 2 | 3 | source "Kconfig.zephyr" 4 | -------------------------------------------------------------------------------- /platforms/Zephyr/app.overlay: -------------------------------------------------------------------------------- 1 | / { 2 | chosen { 3 | zephyr,console = &cdc_acm_uart0; 4 | }; 5 | }; 6 | 7 | &zephyr_udc0 { 8 | cdc_acm_uart0: cdc_acm_uart0 { 9 | compatible = "zephyr,cdc-acm-uart"; 10 | }; 11 | }; 12 | -------------------------------------------------------------------------------- /platforms/Zephyr/boards/rpi_pico.overlay: -------------------------------------------------------------------------------- 1 | #include "../app.overlay" 2 | 3 | / { 4 | zephyr,user { 5 | warduino-gpios = 6 | <&gpio0 0 0>, 7 | <&gpio0 1 0>, 8 | <&gpio0 2 0>, 9 | <&gpio0 3 0>, 10 | <&gpio0 4 0>, 11 | <&gpio0 5 0>, 12 | <&gpio0 6 0>, 13 | <&gpio0 7 0>, 14 | <&gpio0 8 0>, 15 | <&gpio0 9 0>, 16 | <&gpio0 10 0>, 17 | <&gpio0 11 0>, 18 | <&gpio0 12 0>, 19 | <&gpio0 13 0>, 20 | <&gpio0 14 0>, 21 | <&gpio0 15 0>, 22 | <&gpio0 16 0>, 23 | <&gpio0 17 0>, 24 | <&gpio0 18 0>, 25 | <&gpio0 19 0>, 26 | <&gpio0 20 0>, 27 | <&gpio0 21 0>, 28 | <&gpio0 22 0>, 29 | <&gpio0 23 0>, 30 | <&gpio0 24 0>, 31 | <&gpio0 25 0>, 32 | <&gpio0 26 0>, 33 | <&gpio0 27 0>, 34 | <&gpio0 28 0>, 35 | <&gpio0 29 0>; 36 | }; 37 | }; 38 | -------------------------------------------------------------------------------- /platforms/Zephyr/prj.conf: -------------------------------------------------------------------------------- 1 | CONFIG_GPIO=y 2 | CONFIG_PWM=y 3 | CONFIG_CPP=y 4 | CONFIG_STD_CPP17=y 5 | CONFIG_REQUIRES_FULL_LIBCPP=y 6 | CONFIG_GLIBCXX_LIBCPP=y 7 | CONFIG_CPP_EXCEPTIONS=y 8 | 9 | CONFIG_REQUIRES_FLOAT_PRINTF=y 10 | 11 | CONFIG_USB_DEVICE_STACK=y 12 | CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=y 13 | CONFIG_USB_DEVICE_VID=0x2e8a 14 | CONFIG_USB_DEVICE_PID=0x000a 15 | 16 | CONFIG_SERIAL=y 17 | CONFIG_CONSOLE=y 18 | CONFIG_UART_CONSOLE=y 19 | CONFIG_UART_LINE_CTRL=y 20 | 21 | CONFIG_UART_INTERRUPT_DRIVEN=n 22 | CONFIG_UART_ASYNC_API=n 23 | CONFIG_UART_WIDE_DATA=y 24 | CONFIG_UART_USE_RUNTIME_CONFIGURE=y 25 | 26 | CONFIG_CONSOLE_SUBSYS=y 27 | CONFIG_CONSOLE_GETCHAR=y 28 | CONFIG_CONSOLE_GETCHAR_BUFSIZE=4096 29 | CONFIG_CONSOLE_PUTCHAR_BUFSIZE=4096 30 | 31 | CONFIG_POSIX_API=y 32 | CONFIG_MAIN_STACK_SIZE=8192 33 | -------------------------------------------------------------------------------- /src/Edward/RFC.cpp: -------------------------------------------------------------------------------- 1 | #include "RFC.h" 2 | 3 | RFC::RFC(uint32_t id, Type *t_type, StackValue *t_args) 4 | : fidx(id), args(t_args), type(t_type) {} 5 | -------------------------------------------------------------------------------- /src/Edward/RFC.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | struct StackValue; 5 | struct Type; 6 | 7 | struct SerializeData { 8 | const unsigned char *raw; 9 | uint32_t size; 10 | }; 11 | 12 | class RFC { 13 | public: 14 | const uint32_t fidx; 15 | StackValue *args; 16 | const Type *type; 17 | StackValue *result; 18 | 19 | bool success = true; 20 | char *exception; 21 | uint16_t exception_size; 22 | 23 | RFC(uint32_t id, Type *t_type, StackValue *t_args = nullptr); 24 | }; 25 | -------------------------------------------------------------------------------- /src/Edward/proxy.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | #include "RFC.h" 9 | struct Module; 10 | struct Block; 11 | 12 | class Proxy { 13 | private: 14 | std::stack *calls = new std::stack(); // lifo queue 15 | 16 | void setupCalleeArgs(Module *m, RFC *callee); 17 | void pushProxyGuard(Module *m); 18 | 19 | public: 20 | Proxy(); 21 | 22 | void pushRFC(Module *m, RFC *rfc); 23 | RFC *topRFC(); 24 | void returnResult(Module *m); 25 | 26 | // Server side ( arduino side ) 27 | static StackValue *readRFCArgs(Block *func, uint8_t *data); 28 | }; 29 | -------------------------------------------------------------------------------- /src/Edward/proxy_supervisor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | // #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "../Threading/warduino-thread.h" 10 | #include "../Utils/sockets.h" 11 | #include "RFC.h" 12 | #ifndef ARDUINO 13 | #include 14 | #else 15 | #include "../../lib/json/single_include/nlohmann/json.hpp" 16 | #endif 17 | #include "sys/types.h" 18 | 19 | class ProxySupervisor { 20 | private: 21 | Channel *channel; 22 | warduino::mutex *mutex; 23 | std::set *proxied = new std::set(); 24 | 25 | bool hasReplied = false; 26 | nlohmann::basic_json<> proxyResult; 27 | 28 | struct SerializeData *serializeRFC(RFC *callee); 29 | void deserializeRFCResult(RFC *rfc); 30 | 31 | public: 32 | warduino::thread thread; 33 | 34 | ProxySupervisor(Channel *duplex, warduino::mutex *mutex); 35 | 36 | void listenToSocket(); 37 | 38 | bool send(void *t_buffer, int t_size); 39 | nlohmann::basic_json<> readReply(); 40 | 41 | bool call(RFC *callee); 42 | 43 | void registerProxiedCall(uint32_t fidx); 44 | void unregisterProxiedCall(uint32_t fidx); 45 | void unregisterAllProxiedCalls(); 46 | bool isProxied(uint32_t fidx); 47 | }; 48 | -------------------------------------------------------------------------------- /src/Interpreter/interpreter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "../WARDuino/internals.h" 6 | 7 | class Interpreter { 8 | public: 9 | /** 10 | * Push a new frame on to the call stack 11 | * @param m module 12 | * @param block 13 | * @param sp stack pointer to return to 14 | */ 15 | void push_block(Module *m, Block *block, int sp); 16 | 17 | /** 18 | * Restore the top frame from the call stack of a module. 19 | * 20 | * Sets stack pointer and call stack pointer, verifies type of return 21 | * 22 | * @param m module 23 | * @return block that was on top of the stack (the one that we just returned 24 | * to) 25 | */ 26 | Block *pop_block(Module *m); 27 | 28 | /** 29 | * Setup a function 30 | * 31 | * Push params and locals on the stack and save a call frame on the call 32 | * stack Sets new pc value for the start of the function 33 | * 34 | * @param m module to work on 35 | * @param fidx function id (index in m->functions) 36 | */ 37 | void setup_call(Module *m, uint32_t fidx); 38 | 39 | /** 40 | * Start interpretation of the module that has a call set up for it. 41 | * See #setup_call 42 | * @param m module that has been set up for a call 43 | * @param return_exception whether to save the exception method or not 44 | * @return true if the interpretation ended as expected 45 | */ 46 | bool interpret(Module *m, bool waiting = false); 47 | 48 | /* Stateful operations 49 | * ************************************************************************/ 50 | 51 | bool store(Module *m, uint8_t type, uint32_t addr, StackValue &sval); 52 | 53 | bool load(Module *m, uint8_t type, uint32_t addr, uint32_t offset); 54 | 55 | static void report_overflow(Module *m, uint8_t *maddr); 56 | 57 | protected: 58 | private: 59 | }; 60 | -------------------------------------------------------------------------------- /src/Memory/mem.cpp: -------------------------------------------------------------------------------- 1 | #include "mem.h" 2 | 3 | #include 4 | #include 5 | 6 | #include "../Utils/macros.h" 7 | 8 | #ifdef ARDUINO 9 | #include "Arduino.h" 10 | #endif 11 | 12 | // Assert calloc 13 | void *acalloc(size_t nmemb, size_t size, const char *name, 14 | [[maybe_unused]] bool psram) { 15 | if (static_cast(nmemb * size) == 0) { 16 | return nullptr; 17 | } else { 18 | debug("IN Acalloc count: %zu, size: %zu for %s \n", nmemb, size, name); 19 | #ifdef ARDUINO 20 | void *res; 21 | if (psramInit() && psram) { 22 | res = ps_calloc(nmemb, size); 23 | } else { 24 | res = calloc(nmemb, size); 25 | } 26 | #else 27 | void *res = calloc(nmemb, size); 28 | #endif 29 | debug("Done ... Acalloc\n"); 30 | if (res == nullptr) { 31 | debug("FAILED ... Acalloc\n"); 32 | FATAL("Could not allocate %d bytes for %s \n", 33 | static_cast(nmemb * size), name); 34 | } 35 | debug("NOT FAILED ... Acalloc\n"); 36 | return res; 37 | } 38 | } 39 | 40 | // Assert realloc/calloc 41 | void *arecalloc(void *ptr, size_t old_nmemb, size_t nmemb, size_t size, 42 | const char *name, [[maybe_unused]] bool psram) { 43 | #ifdef ARDUINO 44 | void *res; 45 | if (psramInit() && psram) { 46 | res = (size_t *)ps_calloc(nmemb, size); 47 | } else { 48 | res = (size_t *)calloc(nmemb, size); 49 | } 50 | #else 51 | auto *res = static_cast(calloc(nmemb, size)); 52 | #endif 53 | if (res == nullptr) { 54 | FATAL("Could not allocate %d bytes for %s", 55 | static_cast(nmemb * size), name); 56 | } 57 | memset(res, 0, nmemb * size); // initialize memory with 0 58 | memmove(res, ptr, old_nmemb * size); 59 | free(ptr); 60 | return res; 61 | } 62 | -------------------------------------------------------------------------------- /src/Memory/mem.h: -------------------------------------------------------------------------------- 1 | #ifndef MEM_H 2 | #define MEM_H 3 | 4 | #include 5 | 6 | void *acalloc(size_t nmemb, size_t size, const char *name, bool psram = false); 7 | 8 | void *arecalloc(void *ptr, size_t old_nmemb, size_t nmemb, size_t size, 9 | const char *name, bool psram = false); 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /src/Utils/util_arduino.cpp: -------------------------------------------------------------------------------- 1 | #include "util_arduino.h" 2 | 3 | #ifdef ARDUINO 4 | #include "Arduino.h" 5 | void reset_wdt() { yield(); } 6 | 7 | #else 8 | 9 | #ifdef ESP 10 | #include "esp_task_wdt.h" 11 | #include "freertos/task.h" 12 | void reset_wdt() { 13 | // taskYIELD(); 14 | // esp_task_wdt_reset(); 15 | esp_task_wdt_reset(); 16 | // printf("reset wdt \n"); 17 | } 18 | #else 19 | 20 | void reset_wdt() {} 21 | #endif 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /src/Utils/util_arduino.h: -------------------------------------------------------------------------------- 1 | #ifndef UTIL_ARDUINO_H 2 | #define UTIL_ARDUINO_H 3 | 4 | /** 5 | * Reset the watch dog timer. 6 | * 7 | * Should be called once every 6 seconds at least 8 | */ 9 | void reset_wdt(); 10 | 11 | #endif -------------------------------------------------------------------------------- /src/WARDuino/CallbackHandler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | struct Module; 10 | 11 | class Callback; 12 | 13 | class Event { 14 | public: 15 | std::string topic; 16 | std::string payload; 17 | 18 | Event(std::string topic, std::string payload); 19 | 20 | std::string serialized() const; 21 | }; 22 | 23 | class CallbackHandler { 24 | private: 25 | static std::unordered_map *> *callbacks; 26 | static std::deque *events; 27 | 28 | CallbackHandler() = default; // Disallow creation 29 | 30 | public: 31 | static size_t pushed_cursor; 32 | 33 | static size_t event_count(); 34 | static std::deque::const_iterator event_begin(); 35 | static std::deque::const_iterator event_end(); 36 | 37 | static bool resolving_event; 38 | 39 | static void add_callback(const Callback &c); 40 | static void remove_callback(const Callback &c); 41 | static void clear_callbacks(); 42 | static std::string dump_callbacks(); 43 | static std::string dump_callbacksV2(bool includeOuterCurlyBraces = true); 44 | static size_t callback_count(const std::string &topic); 45 | static void push_event(std::string topic, const char *payload, 46 | unsigned int length); 47 | static void push_event(Event *event); 48 | static bool resolve_event(bool force = false); 49 | 50 | static bool manual_event_resolution; // do not resolve event automatically 51 | }; 52 | 53 | class Callback { 54 | public: 55 | Module *module; // reference to module 56 | std::string topic; 57 | uint32_t table_index{}; 58 | 59 | explicit Callback(Module *m, std::string id, uint32_t tidx); 60 | Callback(const Callback &c); 61 | 62 | void resolve_event(const Event &e); 63 | }; 64 | -------------------------------------------------------------------------------- /src/config.h.in: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #cmakedefine PROJECT_VERSION "@WARDUINO_VERSION_STRING@" 4 | -------------------------------------------------------------------------------- /tests/latch/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | 6 | # Runtime data 7 | pids 8 | *.pid 9 | *.seed 10 | 11 | # Directory for instrumented libs generated by jscoverage/JSCover 12 | lib-cov 13 | 14 | # Coverage directory used by tools like istanbul 15 | coverage 16 | .nyc_output 17 | coverage.* 18 | 19 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 20 | .grunt 21 | 22 | # node-waf configuration 23 | .lock-wscript 24 | 25 | # Compiled binary addons (http://nodejs.org/api/addons.html) 26 | build/Release 27 | 28 | # Dependency directory 29 | node_modules 30 | 31 | # Optional npm cache directory 32 | .npm 33 | 34 | # Optional REPL history 35 | .node_repl_history 36 | 37 | typings/ 38 | lib/*.js 39 | test/*.js 40 | *.map 41 | 42 | WABT 43 | !core 44 | 45 | .idea 46 | 47 | *.wasm 48 | -------------------------------------------------------------------------------- /tests/latch/README.md: -------------------------------------------------------------------------------- 1 | # Latch test suites for WARDuino 2 | 3 | Run test with the following commands: 4 | 5 | ```bash 6 | npm run spectest 7 | npm run primtest 8 | npm run debugtest 9 | npm run comptest 10 | ``` 11 | 12 | Make sure the EMULATOR environment variable is set when you run the tests on the emulator. 13 | 14 | For the spectests be sure the WABT is also set, so the `wat2wasm` command can be found. 15 | 16 | -------------------------------------------------------------------------------- /tests/latch/clean.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | mkdir -p cleaned 4 | 5 | for file in /home/tom/Documents/TOPL/plugin/entire/*.asserts.wast; do 6 | base=$(basename -- "$file") 7 | base="${base%%.*}" 8 | 9 | echo "copying $file and $base" 10 | 11 | mkdir -p tmp 12 | cp $file tmp/ 13 | cp $(dirname $file)/${base}.wast tmp/ 14 | 15 | ls tmp/ 16 | 17 | WABT=/home/tom/Documents/TOPL/plugin/WABT/build/ CORESUITE=$(realpath tmp)/ npm run spectest > output 18 | 19 | while read line; do 20 | 21 | if grep -q "✔" <<< "$line"; then 22 | echo "$line" | grep -o "(.*$" | sed "s/(/&assert_return /" >> cleaned/${base}.asserts.wast 23 | elif grep -q "✖" <<< "$line"; then 24 | echo "removing $line" 25 | fi 26 | done < output 27 | 28 | rm -rf tmp 29 | rm output 30 | done 31 | -------------------------------------------------------------------------------- /tests/latch/core/.gitignore: -------------------------------------------------------------------------------- 1 | /commit_message 2 | /repos/ 3 | -------------------------------------------------------------------------------- /tests/latch/core/address_2.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "32_good1" (i32.const 0)) (f32.const 0.0)) 2 | (assert_return (invoke "32_good2" (i32.const 0)) (f32.const 0.0)) 3 | (assert_return (invoke "32_good3" (i32.const 0)) (f32.const 0.0)) 4 | (assert_return (invoke "32_good4" (i32.const 0)) (f32.const 0.0)) 5 | (assert_return (invoke "32_good1" (i32.const 65524)) (f32.const 0.0)) 6 | (assert_return (invoke "32_good2" (i32.const 65524)) (f32.const 0.0)) 7 | (assert_return (invoke "32_good3" (i32.const 65524)) (f32.const 0.0)) 8 | (assert_return (invoke "32_good4" (i32.const 65524)) (f32.const 0.0)) 9 | (assert_return (invoke "32_good5" (i32.const 65524)) (f32.const 0.0)) 10 | (assert_return (invoke "32_good1" (i32.const 65525)) (f32.const 0.0)) 11 | (assert_return (invoke "32_good2" (i32.const 65525)) (f32.const 0.0)) 12 | (assert_return (invoke "32_good3" (i32.const 65525)) (f32.const 0.0)) 13 | (assert_return (invoke "32_good4" (i32.const 65525)) (f32.const 0.0)) 14 | -------------------------------------------------------------------------------- /tests/latch/core/address_2.wast: -------------------------------------------------------------------------------- 1 | (module 2 | (memory 1) 3 | (data (i32.const 0) "\00\00\00\00\00\00\a0\7f\01\00\d0\7f") 4 | 5 | (func (export "32_good1") (param $i i32) (result f32) 6 | (f32.load offset=0 (local.get $i)) ;; 0.0 '\00\00\00\00' 7 | ) 8 | (func (export "32_good2") (param $i i32) (result f32) 9 | (f32.load align=1 (local.get $i)) ;; 0.0 '\00\00\00\00' 10 | ) 11 | (func (export "32_good3") (param $i i32) (result f32) 12 | (f32.load offset=1 align=1 (local.get $i)) ;; 0.0 '\00\00\00\00' 13 | ) 14 | (func (export "32_good4") (param $i i32) (result f32) 15 | (f32.load offset=2 align=2 (local.get $i)) ;; 0.0 '\00\00\00\00' 16 | ) 17 | (func (export "32_good5") (param $i i32) (result f32) 18 | (f32.load offset=8 align=4 (local.get $i)) ;; nan:0x500001 '\01\00\d0\7f' 19 | ) 20 | (func (export "32_bad") (param $i i32) 21 | (drop (f32.load offset=4294967295 (local.get $i))) 22 | ) 23 | ) 24 | 25 | -------------------------------------------------------------------------------- /tests/latch/core/address_3.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "64_good1" (i32.const 0)) (f64.const 0.0)) 2 | (assert_return (invoke "64_good2" (i32.const 0)) (f64.const 0.0)) 3 | (assert_return (invoke "64_good3" (i32.const 0)) (f64.const 0.0)) 4 | (assert_return (invoke "64_good4" (i32.const 0)) (f64.const 0.0)) 5 | (assert_return (invoke "64_good1" (i32.const 65510)) (f64.const 0.0)) 6 | (assert_return (invoke "64_good2" (i32.const 65510)) (f64.const 0.0)) 7 | (assert_return (invoke "64_good3" (i32.const 65510)) (f64.const 0.0)) 8 | (assert_return (invoke "64_good4" (i32.const 65510)) (f64.const 0.0)) 9 | (assert_return (invoke "64_good5" (i32.const 65510)) (f64.const 0.0)) 10 | (assert_return (invoke "64_good1" (i32.const 65511)) (f64.const 0.0)) 11 | (assert_return (invoke "64_good2" (i32.const 65511)) (f64.const 0.0)) 12 | (assert_return (invoke "64_good3" (i32.const 65511)) (f64.const 0.0)) 13 | (assert_return (invoke "64_good4" (i32.const 65511)) (f64.const 0.0)) 14 | -------------------------------------------------------------------------------- /tests/latch/core/address_3.wast: -------------------------------------------------------------------------------- 1 | (module 2 | (memory 1) 3 | (data (i32.const 0) "\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\f4\7f\01\00\00\00\00\00\fc\7f") 4 | 5 | (func (export "64_good1") (param $i i32) (result f64) 6 | (f64.load offset=0 (local.get $i)) ;; 0.0 '\00\00\00\00\00\00\00\00' 7 | ) 8 | (func (export "64_good2") (param $i i32) (result f64) 9 | (f64.load align=1 (local.get $i)) ;; 0.0 '\00\00\00\00\00\00\00\00' 10 | ) 11 | (func (export "64_good3") (param $i i32) (result f64) 12 | (f64.load offset=1 align=1 (local.get $i)) ;; 0.0 '\00\00\00\00\00\00\00\00' 13 | ) 14 | (func (export "64_good4") (param $i i32) (result f64) 15 | (f64.load offset=2 align=2 (local.get $i)) ;; 0.0 '\00\00\00\00\00\00\00\00' 16 | ) 17 | (func (export "64_good5") (param $i i32) (result f64) 18 | (f64.load offset=18 align=8 (local.get $i)) ;; nan:0xc000000000001 '\01\00\00\00\00\00\fc\7f' 19 | ) 20 | (func (export "64_bad") (param $i i32) 21 | (drop (f64.load offset=4294967295 (local.get $i))) 22 | ) 23 | ) 24 | 25 | -------------------------------------------------------------------------------- /tests/latch/core/align_24.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "load" (i32.const 65532)) (i32.const 0)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/align_24.wast: -------------------------------------------------------------------------------- 1 | (module 2 | (memory 1) 3 | (func (export "store") (param i32 i64) 4 | (i64.store align=4 (local.get 0) (local.get 1)) 5 | ) 6 | (func (export "load") (param i32) (result i32) 7 | (i32.load (local.get 0)) 8 | ) 9 | ) 10 | 11 | -------------------------------------------------------------------------------- /tests/latch/core/call_indirect_1.wast: -------------------------------------------------------------------------------- 1 | (module 2 | (type $ii-i (func (param i32 i32) (result i32))) 3 | 4 | (table $t1 funcref (elem $f $g)) 5 | (table $t2 funcref (elem $h $i $j)) 6 | (table $t3 4 funcref) 7 | (elem (table $t3) (i32.const 0) func $g $h) 8 | (elem (table $t3) (i32.const 3) func $z) 9 | 10 | (func $f (type $ii-i) (i32.add (local.get 0) (local.get 1))) 11 | (func $g (type $ii-i) (i32.sub (local.get 0) (local.get 1))) 12 | (func $h (type $ii-i) (i32.mul (local.get 0) (local.get 1))) 13 | (func $i (type $ii-i) (i32.div_u (local.get 0) (local.get 1))) 14 | (func $j (type $ii-i) (i32.rem_u (local.get 0) (local.get 1))) 15 | (func $z) 16 | 17 | (func (export "call-1") (param i32 i32 i32) (result i32) 18 | (call_indirect $t1 (type $ii-i) (local.get 0) (local.get 1) (local.get 2)) 19 | ) 20 | (func (export "call-2") (param i32 i32 i32) (result i32) 21 | (call_indirect $t2 (type $ii-i) (local.get 0) (local.get 1) (local.get 2)) 22 | ) 23 | (func (export "call-3") (param i32 i32 i32) (result i32) 24 | (call_indirect $t3 (type $ii-i) (local.get 0) (local.get 1) (local.get 2)) 25 | ) 26 | ) 27 | 28 | -------------------------------------------------------------------------------- /tests/latch/core/const_102.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const +0x1.000000p-50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_102.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const +0x1.00000100000000000p-50))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_103.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const -0x1.000000p-50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_103.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const -0x1.00000100000000000p-50))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_104.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const +0x1.000002p-50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_104.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const +0x1.00000100000000001p-50))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_105.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const -0x1.000002p-50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_105.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const -0x1.00000100000000001p-50))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_106.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const +0x1.000002p-50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_106.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const +0x1.000001fffffffffffp-50))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_107.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const -0x1.000002p-50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_107.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const -0x1.000001fffffffffffp-50))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_108.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const +0x1.000002p-50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_108.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const +0x1.00000200000000000p-50))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_109.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const -0x1.000002p-50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_109.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const -0x1.00000200000000000p-50))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_110.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const +0x1.000002p-50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_110.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const +0x1.00000200000000001p-50))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_111.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const -0x1.000002p-50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_111.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const -0x1.00000200000000001p-50))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_112.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const +0x1.000002p-50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_112.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const +0x1.000002fffffffffffp-50))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_113.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const -0x1.000002p-50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_113.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const -0x1.000002fffffffffffp-50))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_114.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const +0x1.000004p-50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_114.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const +0x1.00000300000000000p-50))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_115.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const -0x1.000004p-50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_115.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const -0x1.00000300000000000p-50))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_116.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const +0x1.000004p-50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_116.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const +0x1.00000300000000001p-50))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_117.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const -0x1.000004p-50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_117.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const -0x1.00000300000000001p-50))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_118.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const +0x1.000004p-50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_118.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const +0x1.000003fffffffffffp-50))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_119.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const -0x1.000004p-50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_119.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const -0x1.000003fffffffffffp-50))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_120.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const +0x1.000004p-50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_120.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const +0x1.00000400000000000p-50))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_121.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const -0x1.000004p-50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_121.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const -0x1.00000400000000000p-50))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_122.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const +0x1.000004p-50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_122.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const +0x1.00000400000000001p-50))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_123.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const -0x1.000004p-50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_123.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const -0x1.00000400000000001p-50))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_124.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const +0x1.000004p-50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_124.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const +0x1.000004fffffffffffp-50))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_125.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const -0x1.000004p-50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_125.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const -0x1.000004fffffffffffp-50))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_126.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const +0x1.000004p-50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_126.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const +0x1.00000500000000000p-50))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_127.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const -0x1.000004p-50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_127.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const -0x1.00000500000000000p-50))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_128.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const +0x1.000006p-50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_128.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const +0x1.00000500000000001p-50))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_129.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const -0x1.000006p-50)) 2 | 3 | -------------------------------------------------------------------------------- /tests/latch/core/const_129.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const -0x1.00000500000000001p-50))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_130.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const +0x1.000000p-50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_130.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const +0x4000.004000000p-64))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_131.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const -0x1.000000p-50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_131.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const -0x4000.004000000p-64))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_132.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const +0x1.000002p-50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_132.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const +0x4000.004000001p-64))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_133.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const -0x1.000002p-50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_133.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const -0x4000.004000001p-64))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_134.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const +0x1.000002p-50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_134.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const +0x4000.007ffffffp-64))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_135.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const -0x1.000002p-50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_135.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const -0x4000.007ffffffp-64))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_136.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const +0x1.000002p-50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_136.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const +0x4000.008000000p-64))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_137.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const -0x1.000002p-50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_137.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const -0x4000.008000000p-64))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_138.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const +0x1.000002p-50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_138.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const +0x4000.008000001p-64))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_139.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const -0x1.000002p-50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_139.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const -0x4000.008000001p-64))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_140.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const +0x1.000002p-50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_140.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const +0x4000.00bffffffp-64))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_141.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const -0x1.000002p-50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_141.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const -0x4000.00bffffffp-64))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_142.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const +0x1.000004p-50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_142.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const +0x4000.00c000000p-64))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_143.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const -0x1.000004p-50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_143.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const -0x4000.00c000000p-64))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_144.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const +0x1.000004p-50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_144.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const +0x4000.00c000001p-64))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_145.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const -0x1.000004p-50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_145.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const -0x4000.00c000001p-64))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_146.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const +0x1.000004p-50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_146.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const +0x4000.00fffffffp-64))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_147.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const -0x1.000004p-50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_147.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const -0x4000.00fffffffp-64))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_148.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const +0x1.000004p-50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_148.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const +0x4000.010000001p-64))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_149.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const -0x1.000004p-50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_149.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const -0x4000.010000001p-64))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_150.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const +0x1.000004p-50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_150.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const +0x4000.013ffffffp-64))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_151.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const -0x1.000004p-50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_151.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const -0x4000.013ffffffp-64))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_152.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const +0x1.000006p-50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_152.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const +0x4000.014000001p-64))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_153.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const -0x1.000006p-50)) 2 | 3 | -------------------------------------------------------------------------------- /tests/latch/core/const_153.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const -0x4000.014000001p-64))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_154.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const +0x1.000000p-50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_154.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const +8.8817847263968443573e-16))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_155.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const -0x1.000000p-50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_155.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const -8.8817847263968443573e-16))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_156.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const +0x1.000002p-50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_156.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const +8.8817847263968443574e-16))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_157.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const -0x1.000002p-50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_157.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const -8.8817847263968443574e-16))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_158.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const +0x1.000002p-50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_158.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const +8.8817857851880284252e-16))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_159.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const -0x1.000002p-50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_159.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const -8.8817857851880284252e-16))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_160.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const +0x1.000004p-50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_160.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const +8.8817857851880284253e-16))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_161.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const -0x1.000004p-50)) 2 | 3 | -------------------------------------------------------------------------------- /tests/latch/core/const_161.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const -8.8817857851880284253e-16))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_162.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const +0x1.000000p+50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_162.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const +0x1.00000100000000000p+50))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_163.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const -0x1.000000p+50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_163.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const -0x1.00000100000000000p+50))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_164.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const +0x1.000002p+50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_164.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const +0x1.00000100000000001p+50))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_165.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const -0x1.000002p+50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_165.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const -0x1.00000100000000001p+50))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_166.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const +0x1.000002p+50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_166.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const +0x1.000001fffffffffffp+50))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_167.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const -0x1.000002p+50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_167.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const -0x1.000001fffffffffffp+50))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_168.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const +0x1.000002p+50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_168.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const +0x1.00000200000000000p+50))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_169.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const -0x1.000002p+50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_169.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const -0x1.00000200000000000p+50))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_170.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const +0x1.000002p+50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_170.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const +0x1.00000200000000001p+50))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_171.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const -0x1.000002p+50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_171.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const -0x1.00000200000000001p+50))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_172.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const +0x1.000002p+50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_172.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const +0x1.000002fffffffffffp+50))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_173.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const -0x1.000002p+50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_173.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const -0x1.000002fffffffffffp+50))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_174.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const +0x1.000004p+50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_174.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const +0x1.00000300000000000p+50))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_175.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const -0x1.000004p+50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_175.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const -0x1.00000300000000000p+50))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_176.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const +0x1.000004p+50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_176.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const +0x1.00000300000000001p+50))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_177.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const -0x1.000004p+50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_177.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const -0x1.00000300000000001p+50))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_178.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const +0x1.000004p+50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_178.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const +0x1.000003fffffffffffp+50))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_179.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const -0x1.000004p+50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_179.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const -0x1.000003fffffffffffp+50))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_180.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const +0x1.000004p+50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_180.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const +0x1.00000400000000000p+50))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_181.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const -0x1.000004p+50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_181.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const -0x1.00000400000000000p+50))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_182.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const +0x1.000004p+50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_182.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const +0x1.00000400000000001p+50))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_183.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const -0x1.000004p+50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_183.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const -0x1.00000400000000001p+50))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_184.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const +0x1.000004p+50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_184.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const +0x1.000004fffffffffffp+50))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_185.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const -0x1.000004p+50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_185.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const -0x1.000004fffffffffffp+50))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_186.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const +0x1.000004p+50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_186.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const +0x1.00000500000000000p+50))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_187.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const -0x1.000004p+50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_187.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const -0x1.00000500000000000p+50))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_188.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const +0x1.000006p+50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_188.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const +0x1.00000500000000001p+50))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_189.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const -0x1.000006p+50)) 2 | 3 | -------------------------------------------------------------------------------- /tests/latch/core/const_189.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const -0x1.00000500000000001p+50))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_190.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const +0x1.000000p+50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_190.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const +0x4000004000000))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_191.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const -0x1.000000p+50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_191.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const -0x4000004000000))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_192.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const +0x1.000002p+50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_192.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const +0x4000004000001))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_193.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const -0x1.000002p+50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_193.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const -0x4000004000001))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_194.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const +0x1.000002p+50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_194.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const +0x4000007ffffff))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_195.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const -0x1.000002p+50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_195.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const -0x4000007ffffff))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_196.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const +0x1.000002p+50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_196.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const +0x4000008000000))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_197.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const -0x1.000002p+50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_197.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const -0x4000008000000))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_198.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const +0x1.000002p+50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_198.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const +0x4000008000001))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_199.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f") (f32.const -0x1.000002p+50)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/const_199.wast: -------------------------------------------------------------------------------- 1 | (module (func (export "f") (result f32) (f32.const -0x4000008000001))) 2 | -------------------------------------------------------------------------------- /tests/latch/core/f32_0.wast: -------------------------------------------------------------------------------- 1 | 2 | (module 3 | (func (export "add") (param $x f32) (param $y f32) (result f32) (f32.add (local.get $x) (local.get $y))) 4 | (func (export "sub") (param $x f32) (param $y f32) (result f32) (f32.sub (local.get $x) (local.get $y))) 5 | (func (export "mul") (param $x f32) (param $y f32) (result f32) (f32.mul (local.get $x) (local.get $y))) 6 | (func (export "div") (param $x f32) (param $y f32) (result f32) (f32.div (local.get $x) (local.get $y))) 7 | (func (export "sqrt") (param $x f32) (result f32) (f32.sqrt (local.get $x))) 8 | (func (export "min") (param $x f32) (param $y f32) (result f32) (f32.min (local.get $x) (local.get $y))) 9 | (func (export "max") (param $x f32) (param $y f32) (result f32) (f32.max (local.get $x) (local.get $y))) 10 | (func (export "ceil") (param $x f32) (result f32) (f32.ceil (local.get $x))) 11 | (func (export "floor") (param $x f32) (result f32) (f32.floor (local.get $x))) 12 | (func (export "trunc") (param $x f32) (result f32) (f32.trunc (local.get $x))) 13 | (func (export "nearest") (param $x f32) (result f32) (f32.nearest (local.get $x))) 14 | ) 15 | 16 | -------------------------------------------------------------------------------- /tests/latch/core/f32_bitwise_0.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "copysign" (f32.const -0x0p+0) (f32.const 0x0p+0)) (f32.const 0x0p+0)) 2 | (assert_return (invoke "copysign" (f32.const 0x0p+0) (f32.const 0x0p+0)) (f32.const 0x0p+0)) 3 | (assert_return (invoke "copysign" (f32.const -0x0p+0) (f32.const 0x1p-149)) (f32.const 0x0p+0)) 4 | (assert_return (invoke "copysign" (f32.const 0x0p+0) (f32.const 0x1p-149)) (f32.const 0x0p+0)) 5 | (assert_return (invoke "copysign" (f32.const -0x0p+0) (f32.const 0x1p-126)) (f32.const 0x0p+0)) 6 | (assert_return (invoke "copysign" (f32.const 0x0p+0) (f32.const 0x1p-126)) (f32.const 0x0p+0)) 7 | (assert_return (invoke "copysign" (f32.const -0x0p+0) (f32.const 0x1p+0)) (f32.const 0x0p+0)) 8 | (assert_return (invoke "copysign" (f32.const 0x0p+0) (f32.const 0x1p+0)) (f32.const 0x0p+0)) 9 | (assert_return (invoke "copysign" (f32.const -0x0p+0) (f32.const 0x1.921fb6p+2)) (f32.const 0x0p+0)) 10 | (assert_return (invoke "copysign" (f32.const 0x0p+0) (f32.const 0x1.921fb6p+2)) (f32.const 0x0p+0)) 11 | (assert_return (invoke "copysign" (f32.const -0x0p+0) (f32.const 0x1.fffffep+127)) (f32.const 0x0p+0)) 12 | (assert_return (invoke "copysign" (f32.const 0x0p+0) (f32.const 0x1.fffffep+127)) (f32.const 0x0p+0)) 13 | (assert_return (invoke "abs" (f32.const -0x0p+0)) (f32.const 0x0p+0)) 14 | (assert_return (invoke "abs" (f32.const 0x0p+0)) (f32.const 0x0p+0)) 15 | -------------------------------------------------------------------------------- /tests/latch/core/f32_bitwise_0.wast: -------------------------------------------------------------------------------- 1 | 2 | (module 3 | (func (export "abs") (param $x f32) (result f32) (f32.abs (local.get $x))) 4 | (func (export "neg") (param $x f32) (result f32) (f32.neg (local.get $x))) 5 | (func (export "copysign") (param $x f32) (param $y f32) (result f32) (f32.copysign (local.get $x) (local.get $y))) 6 | ) 7 | 8 | -------------------------------------------------------------------------------- /tests/latch/core/f32_cmp_0.wast: -------------------------------------------------------------------------------- 1 | 2 | (module 3 | (func (export "eq") (param $x f32) (param $y f32) (result i32) (f32.eq (local.get $x) (local.get $y))) 4 | (func (export "ne") (param $x f32) (param $y f32) (result i32) (f32.ne (local.get $x) (local.get $y))) 5 | (func (export "lt") (param $x f32) (param $y f32) (result i32) (f32.lt (local.get $x) (local.get $y))) 6 | (func (export "le") (param $x f32) (param $y f32) (result i32) (f32.le (local.get $x) (local.get $y))) 7 | (func (export "gt") (param $x f32) (param $y f32) (result i32) (f32.gt (local.get $x) (local.get $y))) 8 | (func (export "ge") (param $x f32) (param $y f32) (result i32) (f32.ge (local.get $x) (local.get $y))) 9 | ) 10 | 11 | -------------------------------------------------------------------------------- /tests/latch/core/f64.wast: -------------------------------------------------------------------------------- 1 | 2 | (module 3 | (func (export "add") (param $x f64) (param $y f64) (result f64) (f64.add (local.get $x) (local.get $y))) 4 | (func (export "sub") (param $x f64) (param $y f64) (result f64) (f64.sub (local.get $x) (local.get $y))) 5 | (func (export "mul") (param $x f64) (param $y f64) (result f64) (f64.mul (local.get $x) (local.get $y))) 6 | (func (export "div") (param $x f64) (param $y f64) (result f64) (f64.div (local.get $x) (local.get $y))) 7 | (func (export "sqrt") (param $x f64) (result f64) (f64.sqrt (local.get $x))) 8 | (func (export "min") (param $x f64) (param $y f64) (result f64) (f64.min (local.get $x) (local.get $y))) 9 | (func (export "max") (param $x f64) (param $y f64) (result f64) (f64.max (local.get $x) (local.get $y))) 10 | (func (export "ceil") (param $x f64) (result f64) (f64.ceil (local.get $x))) 11 | (func (export "floor") (param $x f64) (result f64) (f64.floor (local.get $x))) 12 | (func (export "trunc") (param $x f64) (result f64) (f64.trunc (local.get $x))) 13 | (func (export "nearest") (param $x f64) (result f64) (f64.nearest (local.get $x))) 14 | ) 15 | 16 | -------------------------------------------------------------------------------- /tests/latch/core/f64_bitwise.wast: -------------------------------------------------------------------------------- 1 | 2 | (module 3 | (func (export "abs") (param $x f64) (result f64) (f64.abs (local.get $x))) 4 | (func (export "neg") (param $x f64) (result f64) (f64.neg (local.get $x))) 5 | (func (export "copysign") (param $x f64) (param $y f64) (result f64) (f64.copysign (local.get $x) (local.get $y))) 6 | ) 7 | 8 | -------------------------------------------------------------------------------- /tests/latch/core/f64_cmp.wast: -------------------------------------------------------------------------------- 1 | 2 | (module 3 | (func (export "eq") (param $x f64) (param $y f64) (result i32) (f64.eq (local.get $x) (local.get $y))) 4 | (func (export "ne") (param $x f64) (param $y f64) (result i32) (f64.ne (local.get $x) (local.get $y))) 5 | (func (export "lt") (param $x f64) (param $y f64) (result i32) (f64.lt (local.get $x) (local.get $y))) 6 | (func (export "le") (param $x f64) (param $y f64) (result i32) (f64.le (local.get $x) (local.get $y))) 7 | (func (export "gt") (param $x f64) (param $y f64) (result i32) (f64.gt (local.get $x) (local.get $y))) 8 | (func (export "ge") (param $x f64) (param $y f64) (result i32) (f64.ge (local.get $x) (local.get $y))) 9 | ) 10 | 11 | -------------------------------------------------------------------------------- /tests/latch/core/float_exprs_45.wast: -------------------------------------------------------------------------------- 1 | (module 2 | (func (export "f32.no_fold_lt_select_to_abs") (param $x f32) (result f32) (select (f32.neg (local.get $x)) (local.get $x) (f32.lt (local.get $x) (f32.const 0.0)))) 3 | (func (export "f32.no_fold_le_select_to_abs") (param $x f32) (result f32) (select (f32.neg (local.get $x)) (local.get $x) (f32.le (local.get $x) (f32.const -0.0)))) 4 | (func (export "f32.no_fold_gt_select_to_abs") (param $x f32) (result f32) (select (local.get $x) (f32.neg (local.get $x)) (f32.gt (local.get $x) (f32.const -0.0)))) 5 | (func (export "f32.no_fold_ge_select_to_abs") (param $x f32) (result f32) (select (local.get $x) (f32.neg (local.get $x)) (f32.ge (local.get $x) (f32.const 0.0)))) 6 | 7 | (func (export "f64.no_fold_lt_select_to_abs") (param $x f64) (result f64) (select (f64.neg (local.get $x)) (local.get $x) (f64.lt (local.get $x) (f64.const 0.0)))) 8 | (func (export "f64.no_fold_le_select_to_abs") (param $x f64) (result f64) (select (f64.neg (local.get $x)) (local.get $x) (f64.le (local.get $x) (f64.const -0.0)))) 9 | (func (export "f64.no_fold_gt_select_to_abs") (param $x f64) (result f64) (select (local.get $x) (f64.neg (local.get $x)) (f64.gt (local.get $x) (f64.const -0.0)))) 10 | (func (export "f64.no_fold_ge_select_to_abs") (param $x f64) (result f64) (select (local.get $x) (f64.neg (local.get $x)) (f64.ge (local.get $x) (f64.const 0.0)))) 11 | ) 12 | 13 | -------------------------------------------------------------------------------- /tests/latch/core/float_exprs_46.wast: -------------------------------------------------------------------------------- 1 | (module 2 | (func (export "f32.no_fold_lt_if_to_abs") (param $x f32) (result f32) 3 | (if (result f32) (f32.lt (local.get $x) (f32.const 0.0)) 4 | (then (f32.neg (local.get $x))) (else (local.get $x)) 5 | ) 6 | ) 7 | (func (export "f32.no_fold_le_if_to_abs") (param $x f32) (result f32) 8 | (if (result f32) (f32.le (local.get $x) (f32.const -0.0)) 9 | (then (f32.neg (local.get $x))) (else (local.get $x)) 10 | ) 11 | ) 12 | (func (export "f32.no_fold_gt_if_to_abs") (param $x f32) (result f32) 13 | (if (result f32) (f32.gt (local.get $x) (f32.const -0.0)) 14 | (then (local.get $x)) (else (f32.neg (local.get $x))) 15 | ) 16 | ) 17 | (func (export "f32.no_fold_ge_if_to_abs") (param $x f32) (result f32) 18 | (if (result f32) (f32.ge (local.get $x) (f32.const 0.0)) 19 | (then (local.get $x)) (else (f32.neg (local.get $x))) 20 | ) 21 | ) 22 | 23 | (func (export "f64.no_fold_lt_if_to_abs") (param $x f64) (result f64) 24 | (if (result f64) (f64.lt (local.get $x) (f64.const 0.0)) 25 | (then (f64.neg (local.get $x))) (else (local.get $x)) 26 | ) 27 | ) 28 | (func (export "f64.no_fold_le_if_to_abs") (param $x f64) (result f64) 29 | (if (result f64) (f64.le (local.get $x) (f64.const -0.0)) 30 | (then (f64.neg (local.get $x))) (else (local.get $x)) 31 | ) 32 | ) 33 | (func (export "f64.no_fold_gt_if_to_abs") (param $x f64) (result f64) 34 | (if (result f64) (f64.gt (local.get $x) (f64.const -0.0)) 35 | (then (local.get $x)) (else (f64.neg (local.get $x))) 36 | ) 37 | ) 38 | (func (export "f64.no_fold_ge_if_to_abs") (param $x f64) (result f64) 39 | (if (result f64) (f64.ge (local.get $x) (f64.const 0.0)) 40 | (then (local.get $x)) (else (f64.neg (local.get $x))) 41 | ) 42 | ) 43 | ) 44 | 45 | -------------------------------------------------------------------------------- /tests/latch/core/float_exprs_63.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f32.no_fold_neg_sub" (f32.const -0.0) (f32.const -0.0)) (f32.const -0.0)) 2 | (assert_return (invoke "f32.no_fold_neg_sub" (f32.const 0.0) (f32.const -0.0)) (f32.const -0.0)) 3 | (assert_return (invoke "f32.no_fold_neg_sub" (f32.const -0.0) (f32.const 0.0)) (f32.const 0.0)) 4 | (assert_return (invoke "f32.no_fold_neg_sub" (f32.const 0.0) (f32.const 0.0)) (f32.const -0.0)) 5 | 6 | (assert_return (invoke "f64.no_fold_neg_sub" (f64.const -0.0) (f64.const -0.0)) (f64.const -0.0)) 7 | (assert_return (invoke "f64.no_fold_neg_sub" (f64.const 0.0) (f64.const -0.0)) (f64.const -0.0)) 8 | (assert_return (invoke "f64.no_fold_neg_sub" (f64.const -0.0) (f64.const 0.0)) (f64.const 0.0)) 9 | (assert_return (invoke "f64.no_fold_neg_sub" (f64.const 0.0) (f64.const 0.0)) (f64.const -0.0)) 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/latch/core/float_exprs_63.wast: -------------------------------------------------------------------------------- 1 | (module 2 | (func (export "f32.no_fold_neg_sub") (param $x f32) (param $y f32) (result f32) 3 | (f32.neg (f32.sub (local.get $x) (local.get $y)))) 4 | 5 | (func (export "f64.no_fold_neg_sub") (param $x f64) (param $y f64) (result f64) 6 | (f64.neg (f64.sub (local.get $x) (local.get $y)))) 7 | ) 8 | 9 | -------------------------------------------------------------------------------- /tests/latch/core/float_exprs_64.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f32.no_fold_neg_add" (f32.const -0.0) (f32.const -0.0)) (f32.const 0.0)) 2 | (assert_return (invoke "f32.no_fold_neg_add" (f32.const 0.0) (f32.const -0.0)) (f32.const -0.0)) 3 | (assert_return (invoke "f32.no_fold_neg_add" (f32.const -0.0) (f32.const 0.0)) (f32.const -0.0)) 4 | (assert_return (invoke "f32.no_fold_neg_add" (f32.const 0.0) (f32.const 0.0)) (f32.const -0.0)) 5 | 6 | (assert_return (invoke "f64.no_fold_neg_add" (f64.const -0.0) (f64.const -0.0)) (f64.const 0.0)) 7 | (assert_return (invoke "f64.no_fold_neg_add" (f64.const 0.0) (f64.const -0.0)) (f64.const -0.0)) 8 | (assert_return (invoke "f64.no_fold_neg_add" (f64.const -0.0) (f64.const 0.0)) (f64.const -0.0)) 9 | (assert_return (invoke "f64.no_fold_neg_add" (f64.const 0.0) (f64.const 0.0)) (f64.const -0.0)) 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/latch/core/float_exprs_64.wast: -------------------------------------------------------------------------------- 1 | (module 2 | (func (export "f32.no_fold_neg_add") (param $x f32) (param $y f32) (result f32) 3 | (f32.neg (f32.add (local.get $x) (local.get $y)))) 4 | 5 | (func (export "f64.no_fold_neg_add") (param $x f64) (param $y f64) (result f64) 6 | (f64.neg (f64.add (local.get $x) (local.get $y)))) 7 | ) 8 | 9 | -------------------------------------------------------------------------------- /tests/latch/core/float_exprs_65.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f32.no_fold_add_neg_neg" (f32.const -0.0) (f32.const -0.0)) (f32.const 0.0)) 2 | (assert_return (invoke "f32.no_fold_add_neg_neg" (f32.const 0.0) (f32.const -0.0)) (f32.const 0.0)) 3 | (assert_return (invoke "f32.no_fold_add_neg_neg" (f32.const -0.0) (f32.const 0.0)) (f32.const 0.0)) 4 | (assert_return (invoke "f32.no_fold_add_neg_neg" (f32.const 0.0) (f32.const 0.0)) (f32.const -0.0)) 5 | 6 | (assert_return (invoke "f64.no_fold_add_neg_neg" (f64.const -0.0) (f64.const -0.0)) (f64.const 0.0)) 7 | (assert_return (invoke "f64.no_fold_add_neg_neg" (f64.const 0.0) (f64.const -0.0)) (f64.const 0.0)) 8 | (assert_return (invoke "f64.no_fold_add_neg_neg" (f64.const -0.0) (f64.const 0.0)) (f64.const 0.0)) 9 | (assert_return (invoke "f64.no_fold_add_neg_neg" (f64.const 0.0) (f64.const 0.0)) (f64.const -0.0)) 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/latch/core/float_exprs_65.wast: -------------------------------------------------------------------------------- 1 | (module 2 | (func (export "f32.no_fold_add_neg_neg") (param $x f32) (param $y f32) (result f32) 3 | (f32.add (f32.neg (local.get $x)) (f32.neg (local.get $y)))) 4 | 5 | (func (export "f64.no_fold_add_neg_neg") (param $x f64) (param $y f64) (result f64) 6 | (f64.add (f64.neg (local.get $x)) (f64.neg (local.get $y)))) 7 | ) 8 | 9 | -------------------------------------------------------------------------------- /tests/latch/core/float_exprs_89.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f32.contract2fma" (f32.const 1.0) (f32.const 1.0)) (f32.const 0.0)) 2 | (assert_return (invoke "f32.contract2fma" (f32.const 0x1.19999ap+0) (f32.const 0x1.19999ap+0)) (f32.const 0.0)) 3 | (assert_return (invoke "f32.contract2fma" (f32.const 0x1.333332p+0) (f32.const 0x1.333332p+0)) (f32.const 0.0)) 4 | (assert_return (invoke "f64.contract2fma" (f64.const 1.0) (f64.const 1.0)) (f64.const 0.0)) 5 | (assert_return (invoke "f64.contract2fma" (f64.const 0x1.199999999999ap+0) (f64.const 0x1.199999999999ap+0)) (f64.const 0.0)) 6 | (assert_return (invoke "f64.contract2fma" (f64.const 0x1.3333333333333p+0) (f64.const 0x1.3333333333333p+0)) (f64.const 0.0)) 7 | 8 | 9 | -------------------------------------------------------------------------------- /tests/latch/core/float_exprs_89.wast: -------------------------------------------------------------------------------- 1 | (module 2 | (func (export "f32.contract2fma") 3 | (param $x f32) (param $y f32) (result f32) 4 | (f32.sqrt (f32.sub (f32.mul (local.get $x) (local.get $x)) 5 | (f32.mul (local.get $y) (local.get $y))))) 6 | (func (export "f64.contract2fma") 7 | (param $x f64) (param $y f64) (result f64) 8 | (f64.sqrt (f64.sub (f64.mul (local.get $x) (local.get $x)) 9 | (f64.mul (local.get $y) (local.get $y))))) 10 | ) 11 | 12 | -------------------------------------------------------------------------------- /tests/latch/core/float_exprs_93.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "point_four" (f64.const 4.0) (f64.const 10.0)) (i32.const 0)) 2 | 3 | 4 | -------------------------------------------------------------------------------- /tests/latch/core/float_exprs_93.wast: -------------------------------------------------------------------------------- 1 | (module 2 | (func (export "point_four") (param $four f64) (param $ten f64) (result i32) 3 | (f64.lt (f64.div (local.get $four) (local.get $ten)) (f64.const 0.4))) 4 | ) 5 | 6 | -------------------------------------------------------------------------------- /tests/latch/core/forward_0.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "even" (i32.const 13)) (i32.const 0)) 2 | (assert_return (invoke "even" (i32.const 20)) (i32.const 1)) 3 | (assert_return (invoke "odd" (i32.const 13)) (i32.const 1)) 4 | (assert_return (invoke "odd" (i32.const 20)) (i32.const 0)) 5 | -------------------------------------------------------------------------------- /tests/latch/core/forward_0.wast: -------------------------------------------------------------------------------- 1 | (module 2 | (func $even (export "even") (param $n i32) (result i32) 3 | (if (result i32) (i32.eq (local.get $n) (i32.const 0)) 4 | (then (i32.const 1)) 5 | (else (call $odd (i32.sub (local.get $n) (i32.const 1)))) 6 | ) 7 | ) 8 | 9 | (func $odd (export "odd") (param $n i32) (result i32) 10 | (if (result i32) (i32.eq (local.get $n) (i32.const 0)) 11 | (then (i32.const 0)) 12 | (else (call $even (i32.sub (local.get $n) (i32.const 1)))) 13 | ) 14 | ) 15 | ) 16 | 17 | -------------------------------------------------------------------------------- /tests/latch/core/func_2.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "f" (i32.const 42)) (i32.const 0)) 2 | (assert_return (invoke "g" (i32.const 42)) (i32.const 0)) 3 | (assert_return (invoke "p") (i32.const 42)) 4 | 5 | 6 | -------------------------------------------------------------------------------- /tests/latch/core/func_2.wast: -------------------------------------------------------------------------------- 1 | (module 2 | (type $proc (func (result i32))) 3 | (type $sig (func (param i32) (result i32))) 4 | 5 | (func (export "f") (type $sig) 6 | (local $var i32) 7 | (local.get $var) 8 | ) 9 | 10 | (func $g (type $sig) 11 | (local $var i32) 12 | (local.get $var) 13 | ) 14 | (func (export "g") (type $sig) 15 | (call $g (local.get 0)) 16 | ) 17 | 18 | (func (export "p") (type $proc) 19 | (local $var i32) 20 | (local.set 0 (i32.const 42)) 21 | (local.get $var) 22 | ) 23 | ) 24 | 25 | -------------------------------------------------------------------------------- /tests/latch/core/func_3.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "signature-explicit-reused")) 2 | (assert_return (invoke "signature-implicit-reused")) 3 | (assert_return (invoke "signature-explicit-duplicate")) 4 | (assert_return (invoke "signature-implicit-duplicate")) 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /tests/latch/core/func_ptrs_1.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "callt" (i32.const 0)) (i32.const 1)) 2 | (assert_return (invoke "callt" (i32.const 1)) (i32.const 2)) 3 | (assert_return (invoke "callt" (i32.const 2)) (i32.const 3)) 4 | (assert_return (invoke "callt" (i32.const 3)) (i32.const 4)) 5 | (assert_return (invoke "callt" (i32.const 4)) (i32.const 5)) 6 | (assert_return (invoke "callt" (i32.const 5)) (i32.const 1)) 7 | (assert_return (invoke "callt" (i32.const 6)) (i32.const 3)) 8 | 9 | (assert_return (invoke "callu" (i32.const 0)) (i32.const 1)) 10 | (assert_return (invoke "callu" (i32.const 1)) (i32.const 2)) 11 | (assert_return (invoke "callu" (i32.const 2)) (i32.const 3)) 12 | (assert_return (invoke "callu" (i32.const 3)) (i32.const 4)) 13 | (assert_return (invoke "callu" (i32.const 4)) (i32.const 5)) 14 | (assert_return (invoke "callu" (i32.const 5)) (i32.const 1)) 15 | (assert_return (invoke "callu" (i32.const 6)) (i32.const 3)) 16 | 17 | -------------------------------------------------------------------------------- /tests/latch/core/func_ptrs_1.wast: -------------------------------------------------------------------------------- 1 | (module 2 | (type $T (func (param) (result i32))) 3 | (type $U (func (param) (result i32))) 4 | (table funcref (elem $t1 $t2 $t3 $u1 $u2 $t1 $t3)) 5 | 6 | (func $t1 (type $T) (i32.const 1)) 7 | (func $t2 (type $T) (i32.const 2)) 8 | (func $t3 (type $T) (i32.const 3)) 9 | (func $u1 (type $U) (i32.const 4)) 10 | (func $u2 (type $U) (i32.const 5)) 11 | 12 | (func (export "callt") (param $i i32) (result i32) 13 | (call_indirect (type $T) (local.get $i)) 14 | ) 15 | 16 | (func (export "callu") (param $i i32) (result i32) 17 | (call_indirect (type $U) (local.get $i)) 18 | ) 19 | ) 20 | 21 | -------------------------------------------------------------------------------- /tests/latch/core/func_ptrs_2.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "callt" (i32.const 0)) (i32.const 1)) 2 | (assert_return (invoke "callt" (i32.const 1)) (i32.const 2)) 3 | -------------------------------------------------------------------------------- /tests/latch/core/func_ptrs_2.wast: -------------------------------------------------------------------------------- 1 | (module 2 | (type $T (func (result i32))) 3 | (table funcref (elem 0 1)) 4 | 5 | (func $t1 (type $T) (i32.const 1)) 6 | (func $t2 (type $T) (i32.const 2)) 7 | 8 | (func (export "callt") (param $i i32) (result i32) 9 | (call_indirect (type $T) (local.get $i)) 10 | ) 11 | ) 12 | 13 | -------------------------------------------------------------------------------- /tests/latch/core/int_exprs_10.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "i32.no_fold_rem_s_2" (i32.const -11)) (i32.const -1)) 2 | (assert_return (invoke "i64.no_fold_rem_s_2" (i64.const -11)) (i64.const -1)) 3 | 4 | 5 | -------------------------------------------------------------------------------- /tests/latch/core/int_exprs_10.wast: -------------------------------------------------------------------------------- 1 | (module 2 | (func (export "i32.no_fold_rem_s_2") (param $x i32) (result i32) 3 | (i32.rem_s (local.get $x) (i32.const 2))) 4 | 5 | (func (export "i64.no_fold_rem_s_2") (param $x i64) (result i64) 6 | (i64.rem_s (local.get $x) (i64.const 2))) 7 | ) 8 | 9 | -------------------------------------------------------------------------------- /tests/latch/core/int_exprs_15.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "i32.rem_s_3" (i32.const 71)) (i32.const 2)) 2 | (assert_return (invoke "i32.rem_s_3" (i32.const 0x60000000)) (i32.const 0)) 3 | (assert_return (invoke "i32.rem_u_3" (i32.const 71)) (i32.const 2)) 4 | (assert_return (invoke "i32.rem_u_3" (i32.const 0xc0000000)) (i32.const 0)) 5 | (assert_return (invoke "i64.rem_s_3" (i64.const 71)) (i64.const 2)) 6 | (assert_return (invoke "i64.rem_s_3" (i64.const 0x3000000000000000)) (i64.const 0)) 7 | (assert_return (invoke "i64.rem_u_3" (i64.const 71)) (i64.const 2)) 8 | (assert_return (invoke "i64.rem_u_3" (i64.const 0xc000000000000000)) (i64.const 0)) 9 | 10 | 11 | -------------------------------------------------------------------------------- /tests/latch/core/int_exprs_15.wast: -------------------------------------------------------------------------------- 1 | (module 2 | (func (export "i32.rem_s_3") (param $x i32) (result i32) 3 | (i32.rem_s (local.get $x) (i32.const 3))) 4 | (func (export "i32.rem_u_3") (param $x i32) (result i32) 5 | (i32.rem_u (local.get $x) (i32.const 3))) 6 | 7 | (func (export "i64.rem_s_3") (param $x i64) (result i64) 8 | (i64.rem_s (local.get $x) (i64.const 3))) 9 | (func (export "i64.rem_u_3") (param $x i64) (result i64) 10 | (i64.rem_u (local.get $x) (i64.const 3))) 11 | ) 12 | 13 | -------------------------------------------------------------------------------- /tests/latch/core/int_exprs_16.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "i32.rem_s_5" (i32.const 71)) (i32.const 1)) 2 | (assert_return (invoke "i32.rem_s_5" (i32.const 0x50000000)) (i32.const 0)) 3 | (assert_return (invoke "i32.rem_u_5" (i32.const 71)) (i32.const 1)) 4 | (assert_return (invoke "i32.rem_u_5" (i32.const 0xa0000000)) (i32.const 0)) 5 | (assert_return (invoke "i64.rem_s_5" (i64.const 71)) (i64.const 1)) 6 | (assert_return (invoke "i64.rem_s_5" (i64.const 0x5000000000000000)) (i64.const 0)) 7 | (assert_return (invoke "i64.rem_u_5" (i64.const 71)) (i64.const 1)) 8 | (assert_return (invoke "i64.rem_u_5" (i64.const 0xa000000000000000)) (i64.const 0)) 9 | 10 | 11 | -------------------------------------------------------------------------------- /tests/latch/core/int_exprs_16.wast: -------------------------------------------------------------------------------- 1 | (module 2 | (func (export "i32.rem_s_5") (param $x i32) (result i32) 3 | (i32.rem_s (local.get $x) (i32.const 5))) 4 | (func (export "i32.rem_u_5") (param $x i32) (result i32) 5 | (i32.rem_u (local.get $x) (i32.const 5))) 6 | 7 | (func (export "i64.rem_s_5") (param $x i64) (result i64) 8 | (i64.rem_s (local.get $x) (i64.const 5))) 9 | (func (export "i64.rem_u_5") (param $x i64) (result i64) 10 | (i64.rem_u (local.get $x) (i64.const 5))) 11 | ) 12 | 13 | -------------------------------------------------------------------------------- /tests/latch/core/int_exprs_17.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "i32.rem_s_7" (i32.const 71)) (i32.const 1)) 2 | (assert_return (invoke "i32.rem_s_7" (i32.const 0x70000000)) (i32.const 0)) 3 | (assert_return (invoke "i32.rem_u_7" (i32.const 71)) (i32.const 1)) 4 | (assert_return (invoke "i32.rem_u_7" (i32.const 0xe0000000)) (i32.const 0)) 5 | (assert_return (invoke "i64.rem_s_7" (i64.const 71)) (i64.const 1)) 6 | (assert_return (invoke "i64.rem_s_7" (i64.const 0x7000000000000000)) (i64.const 0)) 7 | (assert_return (invoke "i64.rem_u_7" (i64.const 71)) (i64.const 1)) 8 | (assert_return (invoke "i64.rem_u_7" (i64.const 0xe000000000000000)) (i64.const 0)) 9 | 10 | 11 | -------------------------------------------------------------------------------- /tests/latch/core/int_exprs_17.wast: -------------------------------------------------------------------------------- 1 | (module 2 | (func (export "i32.rem_s_7") (param $x i32) (result i32) 3 | (i32.rem_s (local.get $x) (i32.const 7))) 4 | (func (export "i32.rem_u_7") (param $x i32) (result i32) 5 | (i32.rem_u (local.get $x) (i32.const 7))) 6 | 7 | (func (export "i64.rem_s_7") (param $x i64) (result i64) 8 | (i64.rem_s (local.get $x) (i64.const 7))) 9 | (func (export "i64.rem_u_7") (param $x i64) (result i64) 10 | (i64.rem_u (local.get $x) (i64.const 7))) 11 | ) 12 | 13 | -------------------------------------------------------------------------------- /tests/latch/core/int_exprs_2.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "i64.no_fold_wrap_extend_u" (i64.const 0x0010203040506070)) (i64.const 0x0000000040506070)) 2 | 3 | 4 | -------------------------------------------------------------------------------- /tests/latch/core/int_exprs_2.wast: -------------------------------------------------------------------------------- 1 | (module 2 | (func (export "i64.no_fold_wrap_extend_u") (param $x i64) (result i64) 3 | (i64.extend_i32_u (i32.wrap_i64 (local.get $x)))) 4 | ) 5 | 6 | -------------------------------------------------------------------------------- /tests/latch/core/int_exprs_3.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "i32.no_fold_shl_shr_s" (i32.const 0x80000000)) (i32.const 0)) 2 | (assert_return (invoke "i32.no_fold_shl_shr_u" (i32.const 0x80000000)) (i32.const 0)) 3 | (assert_return (invoke "i64.no_fold_shl_shr_s" (i64.const 0x8000000000000000)) (i64.const 0)) 4 | (assert_return (invoke "i64.no_fold_shl_shr_u" (i64.const 0x8000000000000000)) (i64.const 0)) 5 | 6 | 7 | -------------------------------------------------------------------------------- /tests/latch/core/int_exprs_3.wast: -------------------------------------------------------------------------------- 1 | (module 2 | (func (export "i32.no_fold_shl_shr_s") (param $x i32) (result i32) 3 | (i32.shr_s (i32.shl (local.get $x) (i32.const 1)) (i32.const 1))) 4 | (func (export "i32.no_fold_shl_shr_u") (param $x i32) (result i32) 5 | (i32.shr_u (i32.shl (local.get $x) (i32.const 1)) (i32.const 1))) 6 | 7 | (func (export "i64.no_fold_shl_shr_s") (param $x i64) (result i64) 8 | (i64.shr_s (i64.shl (local.get $x) (i64.const 1)) (i64.const 1))) 9 | (func (export "i64.no_fold_shl_shr_u") (param $x i64) (result i64) 10 | (i64.shr_u (i64.shl (local.get $x) (i64.const 1)) (i64.const 1))) 11 | ) 12 | 13 | -------------------------------------------------------------------------------- /tests/latch/core/int_exprs_4.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "i32.no_fold_shr_s_shl" (i32.const 1)) (i32.const 0)) 2 | (assert_return (invoke "i32.no_fold_shr_u_shl" (i32.const 1)) (i32.const 0)) 3 | (assert_return (invoke "i64.no_fold_shr_s_shl" (i64.const 1)) (i64.const 0)) 4 | (assert_return (invoke "i64.no_fold_shr_u_shl" (i64.const 1)) (i64.const 0)) 5 | 6 | 7 | -------------------------------------------------------------------------------- /tests/latch/core/int_exprs_4.wast: -------------------------------------------------------------------------------- 1 | (module 2 | (func (export "i32.no_fold_shr_s_shl") (param $x i32) (result i32) 3 | (i32.shl (i32.shr_s (local.get $x) (i32.const 1)) (i32.const 1))) 4 | (func (export "i32.no_fold_shr_u_shl") (param $x i32) (result i32) 5 | (i32.shl (i32.shr_u (local.get $x) (i32.const 1)) (i32.const 1))) 6 | 7 | (func (export "i64.no_fold_shr_s_shl") (param $x i64) (result i64) 8 | (i64.shl (i64.shr_s (local.get $x) (i64.const 1)) (i64.const 1))) 9 | (func (export "i64.no_fold_shr_u_shl") (param $x i64) (result i64) 10 | (i64.shl (i64.shr_u (local.get $x) (i64.const 1)) (i64.const 1))) 11 | ) 12 | 13 | -------------------------------------------------------------------------------- /tests/latch/core/int_exprs_5.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "i32.no_fold_div_s_mul" (i32.const 1)) (i32.const 0)) 2 | (assert_return (invoke "i32.no_fold_div_u_mul" (i32.const 1)) (i32.const 0)) 3 | (assert_return (invoke "i64.no_fold_div_s_mul" (i64.const 1)) (i64.const 0)) 4 | (assert_return (invoke "i64.no_fold_div_u_mul" (i64.const 1)) (i64.const 0)) 5 | 6 | 7 | -------------------------------------------------------------------------------- /tests/latch/core/int_exprs_5.wast: -------------------------------------------------------------------------------- 1 | (module 2 | (func (export "i32.no_fold_div_s_mul") (param $x i32) (result i32) 3 | (i32.mul (i32.div_s (local.get $x) (i32.const 6)) (i32.const 6))) 4 | (func (export "i32.no_fold_div_u_mul") (param $x i32) (result i32) 5 | (i32.mul (i32.div_u (local.get $x) (i32.const 6)) (i32.const 6))) 6 | 7 | (func (export "i64.no_fold_div_s_mul") (param $x i64) (result i64) 8 | (i64.mul (i64.div_s (local.get $x) (i64.const 6)) (i64.const 6))) 9 | (func (export "i64.no_fold_div_u_mul") (param $x i64) (result i64) 10 | (i64.mul (i64.div_u (local.get $x) (i64.const 6)) (i64.const 6))) 11 | ) 12 | 13 | -------------------------------------------------------------------------------- /tests/latch/core/int_exprs_8.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "i32.no_fold_mul_div_s" (i32.const 0x80000000)) (i32.const 0)) 2 | (assert_return (invoke "i32.no_fold_mul_div_u" (i32.const 0x80000000)) (i32.const 0)) 3 | (assert_return (invoke "i64.no_fold_mul_div_s" (i64.const 0x8000000000000000)) (i64.const 0)) 4 | (assert_return (invoke "i64.no_fold_mul_div_u" (i64.const 0x8000000000000000)) (i64.const 0)) 5 | 6 | 7 | -------------------------------------------------------------------------------- /tests/latch/core/int_exprs_8.wast: -------------------------------------------------------------------------------- 1 | (module 2 | (func (export "i32.no_fold_mul_div_s") (param $x i32) (result i32) 3 | (i32.div_s (i32.mul (local.get $x) (i32.const 6)) (i32.const 6))) 4 | (func (export "i32.no_fold_mul_div_u") (param $x i32) (result i32) 5 | (i32.div_u (i32.mul (local.get $x) (i32.const 6)) (i32.const 6))) 6 | 7 | (func (export "i64.no_fold_mul_div_s") (param $x i64) (result i64) 8 | (i64.div_s (i64.mul (local.get $x) (i64.const 6)) (i64.const 6))) 9 | (func (export "i64.no_fold_mul_div_u") (param $x i64) (result i64) 10 | (i64.div_u (i64.mul (local.get $x) (i64.const 6)) (i64.const 6))) 11 | ) 12 | 13 | -------------------------------------------------------------------------------- /tests/latch/core/int_exprs_9.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "i32.no_fold_div_s_2" (i32.const -11)) (i32.const -5)) 2 | (assert_return (invoke "i64.no_fold_div_s_2" (i64.const -11)) (i64.const -5)) 3 | 4 | 5 | -------------------------------------------------------------------------------- /tests/latch/core/int_exprs_9.wast: -------------------------------------------------------------------------------- 1 | (module 2 | (func (export "i32.no_fold_div_s_2") (param $x i32) (result i32) 3 | (i32.div_s (local.get $x) (i32.const 2))) 4 | 5 | (func (export "i64.no_fold_div_s_2") (param $x i64) (result i64) 6 | (i64.div_s (local.get $x) (i64.const 2))) 7 | ) 8 | 9 | -------------------------------------------------------------------------------- /tests/latch/core/labels_0.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "block") (i32.const 1)) 2 | (assert_return (invoke "loop1") (i32.const 5)) 3 | (assert_return (invoke "loop2") (i32.const 8)) 4 | (assert_return (invoke "loop3") (i32.const 1)) 5 | (assert_return (invoke "loop4" (i32.const 8)) (i32.const 16)) 6 | (assert_return (invoke "loop5") (i32.const 2)) 7 | (assert_return (invoke "loop6") (i32.const 3)) 8 | (assert_return (invoke "if") (i32.const 5)) 9 | (assert_return (invoke "if2") (i32.const 5)) 10 | (assert_return (invoke "switch" (i32.const 0)) (i32.const 50)) 11 | (assert_return (invoke "switch" (i32.const 1)) (i32.const 20)) 12 | (assert_return (invoke "switch" (i32.const 2)) (i32.const 20)) 13 | (assert_return (invoke "switch" (i32.const 3)) (i32.const 3)) 14 | (assert_return (invoke "switch" (i32.const 4)) (i32.const 50)) 15 | (assert_return (invoke "switch" (i32.const 5)) (i32.const 50)) 16 | (assert_return (invoke "return" (i32.const 0)) (i32.const 0)) 17 | (assert_return (invoke "return" (i32.const 1)) (i32.const 2)) 18 | (assert_return (invoke "return" (i32.const 2)) (i32.const 2)) 19 | (assert_return (invoke "br_if0") (i32.const 0x1d)) 20 | (assert_return (invoke "br_if1") (i32.const 1)) 21 | (assert_return (invoke "br_if2") (i32.const 1)) 22 | (assert_return (invoke "br_if3") (i32.const 2)) 23 | (assert_return (invoke "br") (i32.const 1)) 24 | (assert_return (invoke "shadowing") (i32.const 1)) 25 | (assert_return (invoke "redefinition") (i32.const 5)) 26 | -------------------------------------------------------------------------------- /tests/latch/core/local_get_0.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "type-local-i32") (i32.const 0)) 2 | (assert_return (invoke "type-local-i64") (i64.const 0)) 3 | (assert_return (invoke "type-local-f32") (f32.const 0)) 4 | (assert_return (invoke "type-local-f64") (f64.const 0)) 5 | (assert_return (invoke "type-param-i32" (i32.const 2)) (i32.const 2)) 6 | (assert_return (invoke "type-param-i64" (i64.const 3)) (i64.const 3)) 7 | (assert_return (invoke "as-block-value" (i32.const 6)) (i32.const 6)) 8 | (assert_return (invoke "as-loop-value" (i32.const 7)) (i32.const 7)) 9 | (assert_return (invoke "as-br-value" (i32.const 8)) (i32.const 8)) 10 | (assert_return (invoke "as-br_if-value" (i32.const 9)) (i32.const 9)) 11 | (assert_return (invoke "as-br_if-value-cond" (i32.const 10)) (i32.const 10)) 12 | (assert_return (invoke "as-br_table-value" (i32.const 1)) (i32.const 2)) 13 | (assert_return (invoke "as-return-value" (i32.const 0)) (i32.const 0)) 14 | (assert_return (invoke "as-if-then" (i32.const 1)) (i32.const 1)) 15 | (assert_return (invoke "as-if-else" (i32.const 0)) (i32.const 0)) 16 | -------------------------------------------------------------------------------- /tests/latch/core/local_set_0.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "type-local-i32")) 2 | (assert_return (invoke "type-local-i64")) 3 | (assert_return (invoke "type-local-f32")) 4 | (assert_return (invoke "type-local-f64")) 5 | (assert_return (invoke "type-param-i32" (i32.const 2))) 6 | (assert_return (invoke "type-param-i64" (i64.const 3))) 7 | (assert_return (invoke "type-param-f32" (f32.const 4.4))) 8 | (assert_return (invoke "type-param-f64" (f64.const 5.5))) 9 | (assert_return (invoke "as-block-value" (i32.const 0))) 10 | (assert_return (invoke "as-loop-value" (i32.const 0))) 11 | (assert_return (invoke "as-br-value" (i32.const 0))) 12 | (assert_return (invoke "as-br_if-value" (i32.const 0))) 13 | (assert_return (invoke "as-br_if-value-cond" (i32.const 0))) 14 | (assert_return (invoke "as-br_table-value" (i32.const 0))) 15 | (assert_return (invoke "as-return-value" (i32.const 0))) 16 | (assert_return (invoke "as-if-then" (i32.const 1))) 17 | (assert_return (invoke "as-if-else" (i32.const 0))) 18 | (assert_return 19 | (assert_return 20 | -------------------------------------------------------------------------------- /tests/latch/core/memory_copy_0.wast: -------------------------------------------------------------------------------- 1 | 2 | (module 3 | (memory (export "memory0") 1 1) 4 | (data (i32.const 2) "\03\01\04\01") 5 | (data (i32.const 12) "\07\05\02\03\06") 6 | (func (export "test") 7 | (nop)) 8 | (func (export "load8_u") (param i32) (result i32) 9 | (i32.load8_u (local.get 0)))) 10 | 11 | -------------------------------------------------------------------------------- /tests/latch/core/memory_copy_1.wast: -------------------------------------------------------------------------------- 1 | (module 2 | (memory (export "memory0") 1 1) 3 | (data (i32.const 2) "\03\01\04\01") 4 | (data (i32.const 12) "\07\05\02\03\06") 5 | (func (export "load8_u") (param i32) (result i32) 6 | (i32.load8_u (local.get 0)))) 7 | 8 | -------------------------------------------------------------------------------- /tests/latch/core/memory_copy_10.wast: -------------------------------------------------------------------------------- 1 | (module 2 | (memory (export "mem") 1 1 ) 3 | (data (i32.const 65516) "\00\01\02\03\04\05\06\07\08\09\0a\0b\0c\0d\0e\0f\10\11\12\13") 4 | (func (export "load8_u") (param i32) (result i32) 5 | (i32.load8_u (local.get 0)))) 6 | 7 | -------------------------------------------------------------------------------- /tests/latch/core/memory_copy_11.wast: -------------------------------------------------------------------------------- 1 | (module 2 | (memory (export "mem") 1 1 ) 3 | (data (i32.const 65515) "\00\01\02\03\04\05\06\07\08\09\0a\0b\0c\0d\0e\0f\10\11\12\13\14") 4 | (func (export "load8_u") (param i32) (result i32) 5 | (i32.load8_u (local.get 0)))) 6 | 7 | -------------------------------------------------------------------------------- /tests/latch/core/memory_copy_12.wast: -------------------------------------------------------------------------------- 1 | (module 2 | (memory (export "mem") 1 1 ) 3 | (data (i32.const 65486) "\00\01\02\03\04\05\06\07\08\09\0a\0b\0c\0d\0e\0f\10\11\12\13") 4 | (func (export "load8_u") (param i32) (result i32) 5 | (i32.load8_u (local.get 0)))) 6 | 7 | -------------------------------------------------------------------------------- /tests/latch/core/memory_copy_13.wast: -------------------------------------------------------------------------------- 1 | (module 2 | (memory (export "mem") 1 1 ) 3 | (data (i32.const 65516) "\00\01\02\03\04\05\06\07\08\09\0a\0b\0c\0d\0e\0f\10\11\12\13") 4 | (func (export "load8_u") (param i32) (result i32) 5 | (i32.load8_u (local.get 0)))) 6 | 7 | -------------------------------------------------------------------------------- /tests/latch/core/memory_copy_14.wast: -------------------------------------------------------------------------------- 1 | (module 2 | (memory (export "mem") 1 1 ) 3 | (data (i32.const 65506) "\00\01\02\03\04\05\06\07\08\09\0a\0b\0c\0d\0e\0f\10\11\12\13") 4 | (func (export "load8_u") (param i32) (result i32) 5 | (i32.load8_u (local.get 0)))) 6 | 7 | -------------------------------------------------------------------------------- /tests/latch/core/memory_copy_15.wast: -------------------------------------------------------------------------------- 1 | (module 2 | (memory (export "mem") 1 1 ) 3 | (data (i32.const 65516) "\00\01\02\03\04\05\06\07\08\09\0a\0b\0c\0d\0e\0f\10\11\12\13") 4 | (func (export "load8_u") (param i32) (result i32) 5 | (i32.load8_u (local.get 0)))) 6 | 7 | -------------------------------------------------------------------------------- /tests/latch/core/memory_copy_16.wast: -------------------------------------------------------------------------------- 1 | (module 2 | (memory (export "mem") 1 1 ) 3 | (data (i32.const 65516) "\00\01\02\03\04\05\06\07\08\09\0a\0b\0c\0d\0e\0f\10\11\12\13") 4 | (func (export "load8_u") (param i32) (result i32) 5 | (i32.load8_u (local.get 0)))) 6 | 7 | -------------------------------------------------------------------------------- /tests/latch/core/memory_copy_17.wast: -------------------------------------------------------------------------------- 1 | (module 2 | (memory (export "mem") 1 ) 3 | (data (i32.const 65516) "\00\01\02\03\04\05\06\07\08\09\0a\0b\0c\0d\0e\0f\10\11\12\13") 4 | (func (export "load8_u") (param i32) (result i32) 5 | (i32.load8_u (local.get 0)))) 6 | 7 | -------------------------------------------------------------------------------- /tests/latch/core/memory_copy_18.wast: -------------------------------------------------------------------------------- 1 | (module 2 | (memory (export "mem") 1 1 ) 3 | (data (i32.const 61440) "\00\01\02\03\04\05\06\07\08\09\0a\0b\0c\0d\0e\0f\10\11\12\13") 4 | (func (export "load8_u") (param i32) (result i32) 5 | (i32.load8_u (local.get 0)))) 6 | 7 | -------------------------------------------------------------------------------- /tests/latch/core/memory_copy_2.wast: -------------------------------------------------------------------------------- 1 | (module 2 | (memory (export "memory0") 1 1) 3 | (data (i32.const 2) "\03\01\04\01") 4 | (data (i32.const 12) "\07\05\02\03\06") 5 | (func (export "load8_u") (param i32) (result i32) 6 | (i32.load8_u (local.get 0)))) 7 | 8 | -------------------------------------------------------------------------------- /tests/latch/core/memory_copy_3.wast: -------------------------------------------------------------------------------- 1 | (module 2 | (memory (export "memory0") 1 1) 3 | (data (i32.const 2) "\03\01\04\01") 4 | (data (i32.const 12) "\07\05\02\03\06") 5 | (func (export "load8_u") (param i32) (result i32) 6 | (i32.load8_u (local.get 0)))) 7 | 8 | -------------------------------------------------------------------------------- /tests/latch/core/memory_copy_4.wast: -------------------------------------------------------------------------------- 1 | (module 2 | (memory (export "memory0") 1 1) 3 | (data (i32.const 2) "\03\01\04\01") 4 | (data (i32.const 12) "\07\05\02\03\06") 5 | (func (export "load8_u") (param i32) (result i32) 6 | (i32.load8_u (local.get 0)))) 7 | 8 | -------------------------------------------------------------------------------- /tests/latch/core/memory_copy_5.wast: -------------------------------------------------------------------------------- 1 | (module 2 | (memory (export "memory0") 1 1) 3 | (data (i32.const 2) "\03\01\04\01") 4 | (data (i32.const 12) "\07\05\02\03\06") 5 | (func (export "load8_u") (param i32) (result i32) 6 | (i32.load8_u (local.get 0)))) 7 | 8 | -------------------------------------------------------------------------------- /tests/latch/core/memory_copy_6.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "load8_u" (i32.const 0)) (i32.const 0)) 2 | (assert_return (invoke "load8_u" (i32.const 1)) (i32.const 0)) 3 | (assert_return (invoke "load8_u" (i32.const 2)) (i32.const 3)) 4 | (assert_return (invoke "load8_u" (i32.const 3)) (i32.const 1)) 5 | (assert_return (invoke "load8_u" (i32.const 4)) (i32.const 4)) 6 | (assert_return (invoke "load8_u" (i32.const 5)) (i32.const 1)) 7 | (assert_return (invoke "load8_u" (i32.const 6)) (i32.const 0)) 8 | (assert_return (invoke "load8_u" (i32.const 7)) (i32.const 0)) 9 | (assert_return (invoke "load8_u" (i32.const 8)) (i32.const 0)) 10 | (assert_return (invoke "load8_u" (i32.const 9)) (i32.const 0)) 11 | (assert_return (invoke "load8_u" (i32.const 17)) (i32.const 0)) 12 | (assert_return (invoke "load8_u" (i32.const 18)) (i32.const 0)) 13 | (assert_return (invoke "load8_u" (i32.const 19)) (i32.const 0)) 14 | (assert_return (invoke "load8_u" (i32.const 20)) (i32.const 0)) 15 | (assert_return (invoke "load8_u" (i32.const 21)) (i32.const 0)) 16 | (assert_return (invoke "load8_u" (i32.const 22)) (i32.const 0)) 17 | (assert_return (invoke "load8_u" (i32.const 23)) (i32.const 0)) 18 | (assert_return (invoke "load8_u" (i32.const 24)) (i32.const 0)) 19 | (assert_return (invoke "load8_u" (i32.const 25)) (i32.const 0)) 20 | (assert_return (invoke "load8_u" (i32.const 26)) (i32.const 0)) 21 | (assert_return (invoke "load8_u" (i32.const 27)) (i32.const 0)) 22 | (assert_return (invoke "load8_u" (i32.const 28)) (i32.const 0)) 23 | (assert_return (invoke "load8_u" (i32.const 29)) (i32.const 0)) 24 | -------------------------------------------------------------------------------- /tests/latch/core/memory_copy_6.wast: -------------------------------------------------------------------------------- 1 | (module 2 | (memory (export "memory0") 1 1) 3 | (data (i32.const 2) "\03\01\04\01") 4 | (data (i32.const 12) "\07\05\02\03\06") 5 | (func (export "load8_u") (param i32) (result i32) 6 | (i32.load8_u (local.get 0)))) 7 | 8 | -------------------------------------------------------------------------------- /tests/latch/core/memory_copy_7.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "load8_u" (i32.const 0)) (i32.const 0)) 2 | (assert_return (invoke "load8_u" (i32.const 1)) (i32.const 0)) 3 | (assert_return (invoke "load8_u" (i32.const 2)) (i32.const 3)) 4 | (assert_return (invoke "load8_u" (i32.const 3)) (i32.const 1)) 5 | (assert_return (invoke "load8_u" (i32.const 4)) (i32.const 4)) 6 | (assert_return (invoke "load8_u" (i32.const 5)) (i32.const 1)) 7 | (assert_return (invoke "load8_u" (i32.const 6)) (i32.const 0)) 8 | (assert_return (invoke "load8_u" (i32.const 7)) (i32.const 0)) 9 | (assert_return (invoke "load8_u" (i32.const 8)) (i32.const 0)) 10 | (assert_return (invoke "load8_u" (i32.const 9)) (i32.const 0)) 11 | (assert_return (invoke "load8_u" (i32.const 10)) (i32.const 0)) 12 | (assert_return (invoke "load8_u" (i32.const 11)) (i32.const 0)) 13 | (assert_return (invoke "load8_u" (i32.const 19)) (i32.const 0)) 14 | (assert_return (invoke "load8_u" (i32.const 20)) (i32.const 0)) 15 | (assert_return (invoke "load8_u" (i32.const 21)) (i32.const 0)) 16 | (assert_return (invoke "load8_u" (i32.const 22)) (i32.const 0)) 17 | (assert_return (invoke "load8_u" (i32.const 23)) (i32.const 0)) 18 | (assert_return (invoke "load8_u" (i32.const 24)) (i32.const 0)) 19 | (assert_return (invoke "load8_u" (i32.const 25)) (i32.const 0)) 20 | (assert_return (invoke "load8_u" (i32.const 26)) (i32.const 0)) 21 | (assert_return (invoke "load8_u" (i32.const 27)) (i32.const 0)) 22 | (assert_return (invoke "load8_u" (i32.const 28)) (i32.const 0)) 23 | (assert_return (invoke "load8_u" (i32.const 29)) (i32.const 0)) 24 | -------------------------------------------------------------------------------- /tests/latch/core/memory_copy_7.wast: -------------------------------------------------------------------------------- 1 | (module 2 | (memory (export "memory0") 1 1) 3 | (data (i32.const 2) "\03\01\04\01") 4 | (data (i32.const 12) "\07\05\02\03\06") 5 | (func (export "load8_u") (param i32) (result i32) 6 | (i32.load8_u (local.get 0)))) 7 | 8 | -------------------------------------------------------------------------------- /tests/latch/core/memory_copy_8.wast: -------------------------------------------------------------------------------- 1 | (module 2 | (memory (export "mem") 1 1 ) 3 | (data (i32.const 0) "\00\01\02\03\04\05\06\07\08\09\0a\0b\0c\0d\0e\0f\10\11\12\13") 4 | (func (export "load8_u") (param i32) (result i32) 5 | (i32.load8_u (local.get 0)))) 6 | 7 | -------------------------------------------------------------------------------- /tests/latch/core/memory_copy_9.wast: -------------------------------------------------------------------------------- 1 | (module 2 | (memory (export "mem") 1 1 ) 3 | (data (i32.const 0) "\00\01\02\03\04\05\06\07\08\09\0a\0b\0c\0d\0e\0f\10\11\12\13\14") 4 | (func (export "load8_u") (param i32) (result i32) 5 | (i32.load8_u (local.get 0)))) 6 | 7 | -------------------------------------------------------------------------------- /tests/latch/core/memory_grow_0.wast: -------------------------------------------------------------------------------- 1 | (module 2 | (memory 0) 3 | 4 | (func (export "load_at_zero") (result i32) (i32.load (i32.const 0))) 5 | (func (export "store_at_zero") (i32.store (i32.const 0) (i32.const 2))) 6 | 7 | (func (export "load_at_page_size") (result i32) (i32.load (i32.const 0x10000))) 8 | (func (export "store_at_page_size") (i32.store (i32.const 0x10000) (i32.const 3))) 9 | 10 | (func (export "grow") (param $sz i32) (result i32) (memory.grow (local.get $sz))) 11 | (func (export "size") (result i32) (memory.size)) 12 | ) 13 | 14 | -------------------------------------------------------------------------------- /tests/latch/core/memory_grow_1.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "grow" (i32.const 0)) (i32.const 0)) 2 | (assert_return (invoke "grow" (i32.const 1)) (i32.const 0)) 3 | (assert_return (invoke "grow" (i32.const 0)) (i32.const 1)) 4 | (assert_return (invoke "grow" (i32.const 2)) (i32.const 1)) 5 | (assert_return (invoke "grow" (i32.const 800)) (i32.const 3)) 6 | (assert_return (invoke "grow" (i32.const 0x10000)) (i32.const -1)) 7 | (assert_return (invoke "grow" (i32.const 64736)) (i32.const -1)) 8 | (assert_return (invoke "grow" (i32.const 1)) (i32.const 803)) 9 | 10 | -------------------------------------------------------------------------------- /tests/latch/core/memory_grow_1.wast: -------------------------------------------------------------------------------- 1 | (module 2 | (memory 0) 3 | (func (export "grow") (param i32) (result i32) (memory.grow (local.get 0))) 4 | ) 5 | 6 | -------------------------------------------------------------------------------- /tests/latch/core/memory_grow_2.wast: -------------------------------------------------------------------------------- 1 | (module 2 | (memory 0 10) 3 | (func (export "grow") (param i32) (result i32) (memory.grow (local.get 0))) 4 | ) 5 | 6 | -------------------------------------------------------------------------------- /tests/latch/core/memory_grow_3.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "check-memory-zero" (i32.const 0) (i32.const 0xffff)) (i32.const 0)) 2 | (assert_return (invoke "grow" (i32.const 1)) (i32.const 1)) 3 | (assert_return (invoke "check-memory-zero" (i32.const 0x10000) (i32.const 0x1_ffff)) (i32.const 0)) 4 | (assert_return (invoke "grow" (i32.const 1)) (i32.const 2)) 5 | (assert_return (invoke "check-memory-zero" (i32.const 0x20000) (i32.const 0x2_ffff)) (i32.const 0)) 6 | (assert_return (invoke "grow" (i32.const 1)) (i32.const 3)) 7 | (assert_return (invoke "check-memory-zero" (i32.const 0x30000) (i32.const 0x3_ffff)) (i32.const 0)) 8 | (assert_return (invoke "grow" (i32.const 1)) (i32.const 4)) 9 | (assert_return (invoke "check-memory-zero" (i32.const 0x40000) (i32.const 0x4_ffff)) (i32.const 0)) 10 | (assert_return (invoke "grow" (i32.const 1)) (i32.const 5)) 11 | (assert_return (invoke "check-memory-zero" (i32.const 0x50000) (i32.const 0x5_ffff)) (i32.const 0)) 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/latch/core/memory_grow_3.wast: -------------------------------------------------------------------------------- 1 | (module 2 | (memory 1) 3 | (func (export "grow") (param i32) (result i32) 4 | (memory.grow (local.get 0)) 5 | ) 6 | (func (export "check-memory-zero") (param i32 i32) (result i32) 7 | (local i32) 8 | (local.set 2 (i32.const 1)) 9 | (block 10 | (loop 11 | (local.set 2 (i32.load8_u (local.get 0))) 12 | (br_if 1 (i32.ne (local.get 2) (i32.const 0))) 13 | (br_if 1 (i32.ge_u (local.get 0) (local.get 1))) 14 | (local.set 0 (i32.add (local.get 0) (i32.const 1))) 15 | (br_if 0 (i32.le_u (local.get 0) (local.get 1))) 16 | ) 17 | ) 18 | (local.get 2) 19 | ) 20 | ) 21 | 22 | -------------------------------------------------------------------------------- /tests/latch/core/memory_size_0.wast: -------------------------------------------------------------------------------- 1 | (module 2 | (memory 0) 3 | (func (export "size") (result i32) (memory.size)) 4 | (func (export "grow") (param $sz i32) (drop (memory.grow (local.get $sz)))) 5 | ) 6 | 7 | -------------------------------------------------------------------------------- /tests/latch/core/memory_size_1.wast: -------------------------------------------------------------------------------- 1 | (module 2 | (memory 1) 3 | (func (export "size") (result i32) (memory.size)) 4 | (func (export "grow") (param $sz i32) (drop (memory.grow (local.get $sz)))) 5 | ) 6 | 7 | -------------------------------------------------------------------------------- /tests/latch/core/memory_size_2.wast: -------------------------------------------------------------------------------- 1 | (module 2 | (memory 0 2) 3 | (func (export "size") (result i32) (memory.size)) 4 | (func (export "grow") (param $sz i32) (drop (memory.grow (local.get $sz)))) 5 | ) 6 | 7 | -------------------------------------------------------------------------------- /tests/latch/core/memory_size_3.wast: -------------------------------------------------------------------------------- 1 | (module 2 | (memory 3 8) 3 | (func (export "size") (result i32) (memory.size)) 4 | (func (export "grow") (param $sz i32) (drop (memory.grow (local.get $sz)))) 5 | ) 6 | 7 | -------------------------------------------------------------------------------- /tests/latch/core/names_0.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "foo") (i32.const 0)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/names_0.wast: -------------------------------------------------------------------------------- 1 | 2 | (module 3 | (func (export "foo") (result i32) (i32.const 0)) 4 | ) 5 | 6 | -------------------------------------------------------------------------------- /tests/latch/core/names_1.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "foo") (i32.const 1)) 2 | -------------------------------------------------------------------------------- /tests/latch/core/names_1.wast: -------------------------------------------------------------------------------- 1 | (module 2 | (func (export "foo") (result i32) (i32.const 1)) 3 | ) 4 | 5 | -------------------------------------------------------------------------------- /tests/latch/core/names_3.wast: -------------------------------------------------------------------------------- 1 | (module 2 | ;; Test that we can use indices instead of names to reference imports, 3 | ;; exports, functions and parameters. 4 | (import "spectest" "print_i32" (func (param i32))) 5 | (func (import "spectest" "print_i32") (param i32)) 6 | (func (param i32) (param i32) 7 | (call 0 (local.get 0)) 8 | (call 1 (local.get 1)) 9 | ) 10 | (export "print32" (func 2)) 11 | ) 12 | 13 | -------------------------------------------------------------------------------- /tests/latch/core/switch_0.asserts.wast: -------------------------------------------------------------------------------- 1 | (assert_return (invoke "stmt" (i32.const 0)) (i32.const 0)) 2 | (assert_return (invoke "stmt" (i32.const 1)) (i32.const -1)) 3 | (assert_return (invoke "stmt" (i32.const 2)) (i32.const -2)) 4 | (assert_return (invoke "stmt" (i32.const 3)) (i32.const -3)) 5 | (assert_return (invoke "stmt" (i32.const 4)) (i32.const 100)) 6 | (assert_return (invoke "stmt" (i32.const 5)) (i32.const 101)) 7 | (assert_return (invoke "stmt" (i32.const 6)) (i32.const 102)) 8 | (assert_return (invoke "stmt" (i32.const 7)) (i32.const 100)) 9 | (assert_return (invoke "stmt" (i32.const -10)) (i32.const 102)) 10 | (assert_return (invoke "expr" (i64.const 0)) (i64.const 0)) 11 | (assert_return (invoke "expr" (i64.const 1)) (i64.const -1)) 12 | (assert_return (invoke "expr" (i64.const 2)) (i64.const -2)) 13 | (assert_return (invoke "expr" (i64.const 3)) (i64.const -3)) 14 | (assert_return (invoke "expr" (i64.const 6)) (i64.const 101)) 15 | (assert_return (invoke "expr" (i64.const 7)) (i64.const -5)) 16 | (assert_return (invoke "expr" (i64.const -10)) (i64.const 100)) 17 | (assert_return (invoke "arg" (i32.const 0)) (i32.const 110)) 18 | (assert_return (invoke "arg" (i32.const 1)) (i32.const 12)) 19 | (assert_return (invoke "arg" (i32.const 2)) (i32.const 4)) 20 | (assert_return (invoke "arg" (i32.const 3)) (i32.const 1116)) 21 | (assert_return (invoke "arg" (i32.const 4)) (i32.const 118)) 22 | (assert_return (invoke "arg" (i32.const 5)) (i32.const 20)) 23 | (assert_return (invoke "arg" (i32.const 6)) (i32.const 12)) 24 | (assert_return (invoke "arg" (i32.const 7)) (i32.const 1124)) 25 | (assert_return (invoke "arg" (i32.const 8)) (i32.const 126)) 26 | (assert_return (invoke "corner") (i32.const 1)) 27 | -------------------------------------------------------------------------------- /tests/latch/examples/blink.wast: -------------------------------------------------------------------------------- 1 | (module 2 | ;; Type declarations 3 | (type $int32->int32->void (func (param i32 i32))) 4 | (type $int32->void (func (param i32))) 5 | (type $void->void (func)) 6 | 7 | ;; Imports from the WARDuino VM 8 | (import "env" "chip_delay" (func $env.chip_delay (type $int32->void))) 9 | (import "env" "chip_pin_mode" (func $env.chip_pin_mode (type $int32->int32->void))) 10 | (import "env" "chip_digital_write" (func $env.chip_digital_write (type $int32->int32->void))) 11 | 12 | ;; Non-mutable globals 13 | (global $led i32 (i32.const 26)) 14 | (global $on i32 (i32.const 1)) 15 | (global $off i32 (i32.const 0)) 16 | 17 | (func $init (type $void->void) ;; Set pin mode function (private) 18 | global.get $led 19 | i32.const 2 20 | call $env.chip_pin_mode) 21 | 22 | (func $blink (type $void->void) ;; Blink function (public) 23 | ;; Declare local $delay 24 | (local $delay i32) 25 | i32.const 1000 26 | local.set $delay 27 | 28 | call $init ;; initialise 29 | 30 | ;; Blink in infinite loop 31 | loop $infinite 32 | global.get $led 33 | global.get $on 34 | call $env.chip_digital_write ;; turn led on 35 | local.get $delay 36 | call $env.chip_delay ;; wait 37 | global.get $led 38 | global.get $off 39 | call $env.chip_digital_write ;; turn led off 40 | local.get $delay 41 | call $env.chip_delay ;; wait 42 | br $infinite ;; jump back to start of loop 43 | end) 44 | 45 | ;; Export blink as function 46 | (export "main" (func $blink))) 47 | -------------------------------------------------------------------------------- /tests/latch/examples/call.wast: -------------------------------------------------------------------------------- 1 | (module 2 | ;; Type declarations 3 | (type $int32->int32->void (func (param i32 i32))) 4 | (type $int32->void (func (param i32))) 5 | (type $void->void (func)) 6 | 7 | ;; Imports from the WARDuino VM 8 | (import "env" "chip_pin_mode" (func $env.chip_pin_mode (type $int32->int32->void))) 9 | (import "env" "print_int" (func $env.print_int (type $int32->void))) 10 | 11 | ;; Non-mutable globals 12 | (global $led i32 (i32.const 26)) 13 | 14 | (func $init (type $void->void) ;; Set pin mode function (private) 15 | global.get $led 16 | i32.const 2 17 | call $env.chip_pin_mode) 18 | 19 | (func $on (type $void->void) 20 | i32.const 42 21 | call $env.print_int) ;; print 42 22 | 23 | 24 | (func $blink (type $void->void) ;; Blink function (public) 25 | call $init ;; initialise 26 | (i32.const 4) 27 | call_indirect (type $void->void) ) 28 | 29 | (table 5 5 funcref) 30 | (elem (i32.const 4) func $on) 31 | 32 | ;; Export blink as function 33 | (export "main" (func $blink))) 34 | -------------------------------------------------------------------------------- /tests/latch/examples/factorial.wast: -------------------------------------------------------------------------------- 1 | (module 2 | 3 | (; Imports from the WARDuino VM ;) 4 | (import "env" "print_string" (func $print.string (type $i32->i32->void))) 5 | (import "env" "print_int" (func $print.int (type $i32->void))) 6 | 7 | (; Type declarations ;) 8 | (type $i32->i32->void (func (param i32 i32))) 9 | (type $i32->void (func (param i32))) 10 | (type $i32->i32 (func (param i32) (result i32))) 11 | (type $void->void (func (param) (result))) 12 | 13 | (; Export two functions ;) 14 | (export "main" (func $main)) 15 | (export "fac" (func $fac)) 16 | 17 | (memory $mem 1) 18 | (data (i32.const 0) "\nCalculating fac(20) ... ") 19 | (func $fac (type $i32->i32) 20 | (i32.gt_s 21 | (local.get 0) 22 | (i32.const 1)) 23 | (if (result i32) 24 | (then 25 | (i32.sub 26 | (local.get 0) 27 | (i32.const 1)) 28 | (call $fac) 29 | (local.get 0) 30 | i32.mul) 31 | (else 32 | (i32.const 1)))) 33 | 34 | (func $main (type $void->void) 35 | (local $arg i32) 36 | (local.set $arg (i32.const 30)) 37 | (call $print.string (i32.const 0) (i32.const 25)) 38 | (local.get $arg) 39 | (call $fac) 40 | (call $print.int) 41 | (br 0)) 42 | ) 43 | -------------------------------------------------------------------------------- /tests/latch/latch-0.3.1.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOPLLab/WARDuino/9f6baefd4a45e2a90fe6ae6fb2643b877aa4d98b/tests/latch/latch-0.3.1.tgz -------------------------------------------------------------------------------- /tests/latch/output: -------------------------------------------------------------------------------- 1 | 2 | > warduino-testsuite@1.0.0 spectest 3 | > latch ./src/spec.test.ts 4 | 5 | -------------------------------------------------------------------------------- /tests/latch/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "warduino-testsuite", 3 | "version": "1.0.0", 4 | "scripts": { 5 | "debugtest": "npx ts-node ./src/debugger.test.ts", 6 | "primtest": "npx ts-node ./src/primitives.test.ts", 7 | "spectest": "npx ts-node ./src/spec.test.ts", 8 | "comptest": "npx ts-node ./src/comp.test.ts" 9 | }, 10 | "devDependencies": { 11 | "latch": "file:./latch-0.3.1.tgz", 12 | "mqtt": "^4.3.7", 13 | "serialport": "^10.4.0", 14 | "typescript": "^4.5.5" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/latch/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "ES2020", 5 | "outDir": "out", 6 | "resolveJsonModule": true, 7 | "lib": [ 8 | "ES2020" 9 | ], 10 | "rootDir": "src", 11 | "sourceMap": true, 12 | "strict": true 13 | }, 14 | "exclude": [ 15 | "WABT" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /tests/unit/README.md: -------------------------------------------------------------------------------- 1 | # Virtual Machine Internals Tests 2 | 3 | The tests in this folder are designed to test the internals of the virtual machine. 4 | The current test suite contains tests for the following components: 5 | 6 | 1. Physical to virtual address translation 7 | 2. WebAssembly module loading 8 | 3. WebAssembly module unloading 9 | 10 | ## Running the tests 11 | 12 | To run the tests, execute the following command from the root of the repository: 13 | 14 | ```bash 15 | $ mkdir tests/build ; cd tests/build ; cmake ../../ -D BUILD_UNITTEST=ON ; cmake --build . ; ctest -VV 16 | ``` 17 | 18 | -------------------------------------------------------------------------------- /tests/unit/example_code/blink/blink.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOPLLab/WARDuino/9f6baefd4a45e2a90fe6ae6fb2643b877aa4d98b/tests/unit/example_code/blink/blink.wasm -------------------------------------------------------------------------------- /tests/unit/example_code/blink/blink.wast: -------------------------------------------------------------------------------- 1 | (module 2 | ;; Type declarations 3 | (type $int32->int32->void (func (param i32 i32))) 4 | (type $int32->void (func (param i32))) 5 | (type $void->void (func)) 6 | 7 | ;; Imports from the WARDuino VM 8 | (import "env" "chip_delay" (func $env.chip_delay (type $int32->void))) 9 | (import "env" "chip_pin_mode" (func $env.chip_pin_mode (type $int32->int32->void))) 10 | (import "env" "chip_digital_write" (func $env.chip_digital_write (type $int32->int32->void))) 11 | 12 | ;; Non-mutable globals 13 | (global $led i32 (i32.const 26)) 14 | (global $on i32 (i32.const 1)) 15 | (global $off i32 (i32.const 0)) 16 | 17 | (func $init (type $void->void) ;; Set pin mode function (private) 18 | global.get $led 19 | i32.const 2 20 | call $env.chip_pin_mode) 21 | 22 | (func $blink (type $void->void) ;; Blink function (public) 23 | ;; Declare local $delay 24 | (local $delay i32) 25 | i32.const 1000 26 | local.set $delay 27 | 28 | call $init ;; initialise 29 | 30 | ;; Blink in infinite loop 31 | loop $infinite 32 | global.get $led 33 | global.get $on 34 | call $env.chip_digital_write ;; turn led on 35 | local.get $delay 36 | call $env.chip_delay ;; wait 37 | global.get $led 38 | global.get $off 39 | call $env.chip_digital_write ;; turn led off 40 | local.get $delay 41 | call $env.chip_delay ;; wait 42 | br $infinite ;; jump back to start of loop 43 | end) 44 | 45 | ;; Export blink as function 46 | (export "main" (func $blink))) 47 | 48 | -------------------------------------------------------------------------------- /tests/unit/example_code/blink/blink_wasm.h: -------------------------------------------------------------------------------- 1 | unsigned char blink_wasm[] = { 2 | 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0d, 0x03, 0x60, 3 | 0x02, 0x7f, 0x7f, 0x00, 0x60, 0x01, 0x7f, 0x00, 0x60, 0x00, 0x00, 0x02, 4 | 0x3f, 0x03, 0x03, 0x65, 0x6e, 0x76, 0x0a, 0x63, 0x68, 0x69, 0x70, 0x5f, 5 | 0x64, 0x65, 0x6c, 0x61, 0x79, 0x00, 0x01, 0x03, 0x65, 0x6e, 0x76, 0x0d, 6 | 0x63, 0x68, 0x69, 0x70, 0x5f, 0x70, 0x69, 0x6e, 0x5f, 0x6d, 0x6f, 0x64, 7 | 0x65, 0x00, 0x00, 0x03, 0x65, 0x6e, 0x76, 0x12, 0x63, 0x68, 0x69, 0x70, 8 | 0x5f, 0x64, 0x69, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x5f, 0x77, 0x72, 0x69, 9 | 0x74, 0x65, 0x00, 0x00, 0x03, 0x03, 0x02, 0x02, 0x02, 0x06, 0x10, 0x03, 10 | 0x7f, 0x00, 0x41, 0x1a, 0x0b, 0x7f, 0x00, 0x41, 0x01, 0x0b, 0x7f, 0x00, 11 | 0x41, 0x00, 0x0b, 0x07, 0x08, 0x01, 0x04, 0x6d, 0x61, 0x69, 0x6e, 0x00, 12 | 0x04, 0x0a, 0x2f, 0x02, 0x08, 0x00, 0x23, 0x00, 0x41, 0x02, 0x10, 0x01, 13 | 0x0b, 0x24, 0x01, 0x01, 0x7f, 0x41, 0xe8, 0x07, 0x21, 0x00, 0x10, 0x03, 14 | 0x03, 0x40, 0x23, 0x00, 0x23, 0x01, 0x10, 0x02, 0x20, 0x00, 0x10, 0x00, 15 | 0x23, 0x00, 0x23, 0x02, 0x10, 0x02, 0x20, 0x00, 0x10, 0x00, 0x0c, 0x00, 16 | 0x0b, 0x0b}; 17 | unsigned int blink_wasm_len = 170; 18 | -------------------------------------------------------------------------------- /tests/unit/example_code/dimmer/dimmer.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOPLLab/WARDuino/9f6baefd4a45e2a90fe6ae6fb2643b877aa4d98b/tests/unit/example_code/dimmer/dimmer.wasm -------------------------------------------------------------------------------- /tests/unit/example_code/fac/fac.wasm: -------------------------------------------------------------------------------- 1 | asm ```main 2 | , AJ Ak lA A!@  -------------------------------------------------------------------------------- /tests/unit/example_code/fac/fac.wast: -------------------------------------------------------------------------------- 1 | (module 2 | 3 | (; Type declarations ;) 4 | (type $i2v (func (param i32) (result))) 5 | (type $i32toi32 (func (param i32) (result i32))) 6 | (type $v2v (func (param) (result))) 7 | 8 | (; Define one function ;) 9 | (export "main" (func $main)) 10 | 11 | (func $fac (type $i32toi32) 12 | (i32.gt_s 13 | (local.get 0) 14 | (i32.const 1)) 15 | (if (result i32) 16 | (then 17 | (i32.sub 18 | (local.get 0) 19 | (i32.const 1)) 20 | (call $fac) 21 | (local.get 0) 22 | i32.mul) 23 | (else 24 | (i32.const 1)))) 25 | 26 | (func $main (type $v2v) 27 | (local $arg i32) 28 | (local.set $arg (i32.const 5)) 29 | (loop 30 | (local.get $arg) 31 | (call $fac) 32 | drop 33 | (br 0))) 34 | ) 35 | -------------------------------------------------------------------------------- /tests/unit/example_code/fac/fac_wasm.h: -------------------------------------------------------------------------------- 1 | unsigned char fac_wasm[] = { 2 | 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0d, 0x03, 0x60, 3 | 0x01, 0x7f, 0x00, 0x60, 0x01, 0x7f, 0x01, 0x7f, 0x60, 0x00, 0x00, 0x03, 4 | 0x03, 0x02, 0x01, 0x02, 0x07, 0x08, 0x01, 0x04, 0x6d, 0x61, 0x69, 0x6e, 5 | 0x00, 0x01, 0x0a, 0x2c, 0x02, 0x17, 0x00, 0x20, 0x00, 0x41, 0x01, 0x4a, 6 | 0x04, 0x7f, 0x20, 0x00, 0x41, 0x01, 0x6b, 0x10, 0x00, 0x20, 0x00, 0x6c, 7 | 0x05, 0x41, 0x01, 0x0b, 0x0b, 0x12, 0x01, 0x01, 0x7f, 0x41, 0x05, 0x21, 8 | 0x00, 0x03, 0x40, 0x20, 0x00, 0x10, 0x00, 0x01, 0x0c, 0x00, 0x0b, 0x0b}; 9 | unsigned int fac_wasm_len = 84; 10 | -------------------------------------------------------------------------------- /tests/unit/shared/callstackbuilder.cpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "callstackbuilder.h" 3 | 4 | CallstackBuilder::CallstackBuilder(Module* wasm_module) : m{wasm_module} {} 5 | 6 | void CallstackBuilder::pushBlock(Block* block, int sp) { 7 | // copy of push_block instructions.cpp 8 | m->csp += 1; 9 | m->callstack[m->csp].block = block; 10 | m->callstack[m->csp].sp = sp; 11 | m->callstack[m->csp].fp = m->fp; 12 | m->callstack[m->csp].ra_ptr = m->pc_ptr; 13 | } 14 | 15 | void CallstackBuilder::pushFunctionCall(uint32_t fidx) { 16 | // copy of setup_call from instructions.cpp 17 | Block* func = &m->functions[fidx]; 18 | Type* type = func->type; 19 | 20 | // Push current frame on the call stack 21 | this->pushBlock(func, m->sp - type->param_count); 22 | 23 | // Push locals (dropping extras) 24 | m->fp = m->sp - ((int)type->param_count) + 1; 25 | 26 | // Push function locals 27 | for (uint32_t lidx = 0; lidx < func->local_count; lidx++) { 28 | m->sp += 1; 29 | m->stack[m->sp].value_type = func->local_value_type[lidx]; 30 | m->stack[m->sp].value.uint64 = 0; // Initialize whole union to 0 31 | } 32 | 33 | // Set program counter to start of function 34 | m->pc_ptr = func->start_ptr; 35 | } 36 | 37 | void CallstackBuilder::pushGuard(uint8_t guard_type) { 38 | auto* guard = (Block*)malloc(sizeof(struct Block)); 39 | guard->block_type = guard_type; 40 | guard->type = nullptr; 41 | guard->local_value_type = nullptr; 42 | guard->start_ptr = nullptr; 43 | guard->end_ptr = nullptr; 44 | guard->else_ptr = nullptr; 45 | guard->export_name = nullptr; 46 | guard->import_field = nullptr; 47 | guard->import_module = nullptr; 48 | guard->func_ptr = nullptr; 49 | this->pushBlock(guard, m->sp); 50 | } -------------------------------------------------------------------------------- /tests/unit/shared/callstackbuilder.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../../src/WARDuino.h" 3 | 4 | class CallstackBuilder { 5 | private: 6 | void pushBlock(Block* b, int sp); 7 | 8 | Module* m{}; 9 | 10 | public: 11 | CallstackBuilder(Module* wasm_module); 12 | 13 | void pushFunctionCall(uint32_t fidx); 14 | 15 | void pushGuard(uint8_t guard_type); 16 | }; -------------------------------------------------------------------------------- /tests/unit/shared/serialisation.cpp: -------------------------------------------------------------------------------- 1 | #include "serialisation.h" 2 | 3 | #include "../../../src/Utils/util.h" 4 | 5 | uint8_t* Serialiser::encodeUInt32(uint32_t value, uint8_t* dest) { 6 | uint8_t* buff = dest == nullptr ? (uint8_t*)malloc(4) : dest; 7 | buff[0] = static_cast((value >> 24) & 0xFF); 8 | buff[1] = static_cast((value >> 16) & 0xFF); 9 | buff[2] = static_cast((value >> 8) & 0xFF); 10 | buff[3] = static_cast(value & 0xFF); 11 | return buff; 12 | } 13 | 14 | void Serialiser::uint32ToHexString(uint32_t value, std::string& dest) { 15 | uint8_t buff[4] = {'\0'}; 16 | Serialiser::encodeUInt32(value, buff); 17 | char hexa[9] = {'\0'}; 18 | chars_as_hexa((unsigned char*)hexa, buff, 4); 19 | hexa[8] = '\0'; 20 | dest = hexa; 21 | } 22 | 23 | void Serialiser::uint8ToHexString(uint8_t value, std::string& dest) { 24 | char hexa[3] = {'\0'}; 25 | chars_as_hexa((unsigned char*)hexa, &value, 1); 26 | hexa[2] = '\0'; 27 | dest = hexa; 28 | } -------------------------------------------------------------------------------- /tests/unit/shared/serialisation.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | class Serialiser { 6 | public: 7 | static void uint32ToHexString(uint32_t value, std::string& dest); 8 | 9 | static void uint8ToHexString(uint8_t value, std::string& dest); 10 | 11 | static uint8_t* encodeUInt32(uint32_t value, uint8_t* dest = nullptr); 12 | }; -------------------------------------------------------------------------------- /tutorials/.gitignore: -------------------------------------------------------------------------------- 1 | sdkconfig 2 | *.wasm 3 | *.wasm.h 4 | 5 | !build.sh 6 | -------------------------------------------------------------------------------- /tutorials/README.md: -------------------------------------------------------------------------------- 1 | # Examples 2 | 3 | This folder contains the code for all examples from the [tutorials](https://topllab.github.io/WARDuino/guide/examples/) from the documentation website. 4 | 5 | Additionally, the `wat` folder contains a simple example in textual WebAssembly, which relies on no other higher-level languages. 6 | 7 | ## Running the examples 8 | 9 | All WebAssembly binaries (.wasm) from the examples can be run without additional hardware, by using the emulated version of WARDuino. 10 | This version is packaged as a command line interface. 11 | 12 | ```bash 13 | ./wdcli --file example.wasm 14 | ``` 15 | 16 | -------------------------------------------------------------------------------- /tutorials/assemblyscript/.gitignore: -------------------------------------------------------------------------------- 1 | npm-debug.* 2 | dist/ 3 | docs/ 4 | node_modules/ 5 | out/ 6 | build/ 7 | raw/ 8 | .history 9 | *.backup 10 | .vscode 11 | .idea 12 | idf/ 13 | bin/ 14 | -------------------------------------------------------------------------------- /tutorials/assemblyscript/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | 3 | include($ENV{IDF_PATH}/tools/cmake/project.cmake) 4 | project(assemblyscript) 5 | 6 | -------------------------------------------------------------------------------- /tutorials/assemblyscript/README.md: -------------------------------------------------------------------------------- 1 | # AssemblyScript: Smartlamp App 2 | 3 | This example implements a simple smartlamp app in AssemblyScript. 4 | 5 | Before running the example, make sure to run: 6 | 7 | ```bash 8 | npm install 9 | ``` 10 | 11 | To compile and flash to an ESP32 with the ESP-IDF toolchain simple run: 12 | 13 | ```bash 14 | npm run build 15 | ``` 16 | 17 | -------------------------------------------------------------------------------- /tutorials/assemblyscript/as-warduino-0.1.1.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TOPLLab/WARDuino/9f6baefd4a45e2a90fe6ae6fb2643b877aa4d98b/tutorials/assemblyscript/as-warduino-0.1.1.tgz -------------------------------------------------------------------------------- /tutorials/assemblyscript/asconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "entries": [ 3 | "main/ascii.ts" 4 | ], 5 | "targets": { 6 | "debug": { 7 | "debug": true, 8 | "outFile": "bin/main.debug.wasm", 9 | "textFile": "bin/main.debug.wast" 10 | }, 11 | "release": { 12 | "converge": true, 13 | "optimizeLevel": 3, 14 | "outFile": "bin/main.wasm", 15 | "shrinkLevel": 2 16 | } 17 | }, 18 | "options": { 19 | "disable": [ 20 | "mutable-globals", 21 | "sign-extension", 22 | "nontrapping-f2i", 23 | "bulk-memory" 24 | ], 25 | "exportTable": true, 26 | "exportRuntime": false, 27 | "maximumMemory": 2, 28 | "noAssert": false, 29 | "runtime": "stub", 30 | "sourceMap": true 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /tutorials/assemblyscript/main/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(SOURCE_FILES 2 | ../../../src/Memory/mem.cpp 3 | ../../../src/Utils/util.cpp 4 | ../../../src/Utils/util_arduino.cpp 5 | ../../../src/Utils/sockets.cpp 6 | ../../../src/Debug/debugger.cpp 7 | ../../../src/Edward/proxy.cpp 8 | ../../../src/Edward/proxy_supervisor.cpp 9 | ../../../src/Edward/RFC.cpp 10 | ../../../src/Utils/macros.cpp 11 | ../../../src/WARDuino/WARDuino.cpp 12 | ../../../src/Primitives/emulated.cpp 13 | ../../../src/Interpreter/instructions.cpp 14 | ../../../src/WARDuino/CallbackHandler.cpp 15 | ) 16 | 17 | idf_component_register(SRCS "main.cpp" ${SOURCE_FILES} INCLUDE_DIRS ../../../lib/json/single_include/ REQUIRES driver) 18 | 19 | add_definitions(-DESP=1) 20 | 21 | -------------------------------------------------------------------------------- /tutorials/assemblyscript/main/analog-io.ts: -------------------------------------------------------------------------------- 1 | import {analogRead, 2 | analogWrite, 3 | delay, 4 | print} from "as-warduino/assembly"; 5 | 6 | const IN: u32 = 13; 7 | const OUT: u32 = 9; 8 | 9 | function map(value: u32, x1: u32, y1: u32, x2: u32, y2: u32): u32 { 10 | return ((value - x1) * (y2 - x2) / (y1 - x1) + x2); 11 | } 12 | 13 | export function main(): void { 14 | const value = analogRead(IN); 15 | 16 | const output = map(value, 0, 1023, 0, 255); 17 | 18 | analogWrite(OUT, output); 19 | 20 | print(`sensor = ${value}\t output = ${output}`); 21 | delay(1); 22 | } 23 | -------------------------------------------------------------------------------- /tutorials/assemblyscript/main/analog.ts: -------------------------------------------------------------------------------- 1 | import {analogRead, delay, print} from "as-warduino/assembly"; 2 | 3 | export function main(): void { 4 | const value = analogRead(13); 5 | print(value); 6 | delay(1); 7 | } 8 | -------------------------------------------------------------------------------- /tutorials/assemblyscript/main/ascii.ts: -------------------------------------------------------------------------------- 1 | import {print} from "as-warduino/assembly"; 2 | 3 | export function main(): void { 4 | print("ASCII Table ~ Character Map\n"); 5 | let byte: i32 = 33; 6 | 7 | while (byte !== 126) { 8 | print(String.fromCharCode(byte)); 9 | 10 | print(", dec: " + byte.toString()); 11 | print(", hex: " + byte.toString(16)); 12 | print(", oct: " + byte.toString(8)); 13 | print(", bin: " + byte.toString(2) + "\n"); 14 | 15 | if (byte == 126) { 16 | while (true) { 17 | continue; 18 | } 19 | } 20 | 21 | byte++; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /tutorials/assemblyscript/main/blink-without-delay.ts: -------------------------------------------------------------------------------- 1 | // Blinking LED example 2 | import {pinMode, PinMode, PinVoltage, 3 | digitalWrite, delay} from "as-warduino/assembly"; 4 | 5 | export function main(): void { 6 | const led = 26; 7 | const pause: u32 = 1000; 8 | 9 | pinMode(led, PinMode.OUTPUT); 10 | 11 | while (true) { 12 | digitalWrite(led, PinVoltage.HIGH); 13 | delay(pause); 14 | digitalWrite(led, PinVoltage.LOW); 15 | delay(pause); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /tutorials/assemblyscript/main/blink.ts: -------------------------------------------------------------------------------- 1 | // Blinking LED example 2 | import {pinMode, PinMode, PinVoltage, 3 | digitalWrite, delay} from "as-warduino/assembly"; 4 | 5 | export function main(): void { 6 | const led: u32 = 26; 7 | const pause: u32 = 1000; 8 | 9 | pinMode(led, PinMode.OUTPUT); 10 | 11 | while (true) { 12 | digitalWrite(led, PinVoltage.HIGH); 13 | delay(pause); 14 | digitalWrite(led, PinVoltage.LOW); 15 | delay(pause); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /tutorials/assemblyscript/main/button.ts: -------------------------------------------------------------------------------- 1 | import { 2 | delay, 3 | digitalRead, 4 | digitalWrite, 5 | InterruptMode, 6 | interruptOn, 7 | pinMode, 8 | PinMode, 9 | PinVoltage 10 | } from "as-warduino/assembly"; 11 | 12 | const button = 25; 13 | const led = 26; 14 | 15 | function invert(voltage: PinVoltage): PinVoltage { 16 | switch (voltage) { 17 | case PinVoltage.LOW: 18 | return PinVoltage.HIGH; 19 | case PinVoltage.HIGH: 20 | default: 21 | return PinVoltage.LOW; 22 | } 23 | } 24 | 25 | function toggleLED(_topic: string, _payload: string): void { 26 | // Get current status of LED 27 | let status = digitalRead(led); 28 | // Toggle LED 29 | digitalWrite(led, invert(status)); 30 | } 31 | 32 | export function main(): void { 33 | pinMode(button, PinMode.INPUT); 34 | pinMode(led, PinMode.OUTPUT); 35 | 36 | interruptOn(button, InterruptMode.FALLING, toggleLED); 37 | 38 | while (true) { 39 | delay(1000); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /tutorials/assemblyscript/main/config.ts: -------------------------------------------------------------------------------- 1 | export const BUTTON = 25; 2 | export const LED = 26; 3 | export const SSID = "local-network"; 4 | export const PASSWORD = "network-password"; 5 | export const CLIENT_ID = "random-mqtt-client-id"; 6 | -------------------------------------------------------------------------------- /tutorials/assemblyscript/main/configuration.ts: -------------------------------------------------------------------------------- 1 | import {pinMode, PinMode} from "as-warduino/assembly"; 2 | import * as config from "./config"; 3 | 4 | export function main(): void { 5 | let led = config.LED; 6 | pinMode(led, PinMode.OUTPUT); 7 | } 8 | -------------------------------------------------------------------------------- /tutorials/assemblyscript/main/main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // WARDuino - WebAssembly interpreter for embedded devices. 3 | // 4 | // 5 | #include 6 | 7 | #include "../../../../src/WARDuino.h" 8 | #include "driver/gpio.h" 9 | #include "driver/uart.h" 10 | #include "esp_err.h" 11 | #include "esp_task_wdt.h" 12 | #include "esp_vfs_dev.h" 13 | #include "freertos/FreeRTOS.h" 14 | #include "freertos/task.h" 15 | #include "sdkconfig.h" 16 | 17 | volatile bool handelingInterrupt = false; 18 | 19 | #include "src.wasm.h" 20 | 21 | extern "C" { 22 | extern void app_main(void); 23 | } 24 | 25 | Module* m; 26 | 27 | void startDebuggerStd(void* pvParameter) { 28 | int valread; 29 | uint8_t buffer[1024] = {0}; 30 | Channel* duplex = new Duplex(stdin, stdout); 31 | WARDuino::instance()->debugger->channel = duplex; 32 | while (true) { 33 | taskYIELD(); 34 | vTaskDelay(1000 / portTICK_PERIOD_MS); 35 | 36 | while ((valread = duplex->read(buffer, 1024)) != -1) { 37 | WARDuino::instance()->handleInterrupt(valread, buffer); 38 | } 39 | } 40 | } 41 | 42 | void app_main(void) { 43 | m = WARDuino::instance()->load_module(src_wasm, src_wasm_len, {}); 44 | xTaskCreate(startDebuggerStd, "Debug Thread", 5000, NULL, 1, NULL); 45 | printf("START\n\n"); 46 | WARDuino::instance()->run_module(m); 47 | printf("END\n\n"); 48 | WARDuino::instance()->unload_module(m); 49 | } 50 | -------------------------------------------------------------------------------- /tutorials/assemblyscript/main/wifi.ts: -------------------------------------------------------------------------------- 1 | import {sleep, WiFi} from "as-warduino/assembly"; 2 | import * as config from "./config"; 3 | 4 | function until(attempt: () => void, 5 | done: () => boolean): void { 6 | while (!done()) { 7 | sleep(1); 8 | attempt(); 9 | } 10 | } 11 | 12 | export function main(): void { 13 | // Connect to Wi-Fi 14 | until( 15 | () => { WiFi.connect(config.SSID, config.PASSWORD); }, 16 | WiFi.connected); 17 | let message = "Connected to wifi network with ip: "; 18 | print(message.concat(WiFi.localip())); 19 | 20 | while (true) { 21 | sleep(5); // Sleep for 5 seconds 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /tutorials/assemblyscript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "as-examples", 3 | "version": "1.0.0", 4 | "description": "WARDuino examples in AssemblyScript", 5 | "main": "main/blink.ts", 6 | "type": "module", 7 | "scripts": { 8 | "build": "npm run build:debug && npm run build:release", 9 | "build:debug": "npx asc --config asconfig.json --target debug", 10 | "build:release": "npx asc --config asconfig.json --target release" 11 | }, 12 | "author": "", 13 | "license": "ISC", 14 | "devDependencies": { 15 | "as-warduino": "file:./as-warduino-0.1.1.tgz", 16 | "assemblyscript": "^0.27.5", 17 | "typescript": "^5.1.6" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tutorials/rust/.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | idf/ 3 | 4 | # Generated by Cargo 5 | # will have compiled files and executables 6 | debug/ 7 | target/ 8 | 9 | # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries 10 | # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html 11 | Cargo.lock 12 | 13 | # These are backup files generated by rustfmt 14 | **/*.rs.bk 15 | 16 | # MSVC Windows builds of rustc generate these, which store debugging information 17 | *.pdb 18 | -------------------------------------------------------------------------------- /tutorials/rust/README.md: -------------------------------------------------------------------------------- 1 | # Rust demos 2 | 3 | ## Running the demo 4 | 5 | Flash the wasm code and WARDuino VM onto the esp with the following commands: 6 | 7 | ``` 8 | ./build.sh (example name} 9 | ``` 10 | 11 | -------------------------------------------------------------------------------- /tutorials/rust/build.sh: -------------------------------------------------------------------------------- 1 | set -e 2 | 3 | args=${1?Give an example as argument} 4 | echo -e "Building example: ${args}" 5 | 6 | example="examples/${args}" 7 | 8 | cd ${example} 9 | 10 | cargo build 11 | cp target/wasm32-unknown-unknown/debug/examples.wasm ../../../../platforms/ESP-IDF/upload.wasm 12 | 13 | cd ../../../../platforms/ESP-IDF/ 14 | xxd -i upload.wasm > upload.h 15 | 16 | cd ../../ 17 | 18 | idf.py build 19 | 20 | idf.py flash 21 | 22 | -------------------------------------------------------------------------------- /tutorials/rust/examples/analog-io/.cargo/config: -------------------------------------------------------------------------------- 1 | [build] 2 | target = "wasm32-unknown-unknown" 3 | rustflags = [ 4 | "-C", "link-args=-zstack-size=2048 -s", 5 | ] 6 | -------------------------------------------------------------------------------- /tutorials/rust/examples/analog-io/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "examples" 3 | version = "0.1.0" 4 | authors = ["Tom Lauwaerts "] 5 | edition = "2018" 6 | 7 | [lib] 8 | path = "main/main.rs" 9 | crate-type = ["cdylib"] 10 | 11 | [dependencies] 12 | warduino = { path = "../../lib/warduino" } 13 | 14 | [profile.dev] 15 | panic = "abort" 16 | opt-level = 2 17 | 18 | [profile.release] 19 | panic = "abort" 20 | opt-level = 3 21 | debug = true 22 | -------------------------------------------------------------------------------- /tutorials/rust/examples/analog-io/main/main.rs: -------------------------------------------------------------------------------- 1 | use warduino::{analog_read, analog_write, delay, print}; 2 | 3 | static IN: u32 = 13; 4 | static OUT: u32 = 9; 5 | 6 | fn map(value: u32, x1: u32, y1: u32, x2: u32, y2: u32) -> u32 { 7 | (value - x1) * (y2 - x2) / (y1 - x1) + x2 8 | } 9 | 10 | #[no_mangle] 11 | pub fn main() { 12 | let value: u32 = analog_read(IN); 13 | let output: u32 = map(value, 0, 1023, 0, 255); 14 | 15 | analog_write(OUT, output); 16 | 17 | print(&format!("sensor = {:#?}\t output = {:#?}", value, output).to_string()); 18 | delay(1); 19 | } 20 | -------------------------------------------------------------------------------- /tutorials/rust/examples/analog/.cargo/config: -------------------------------------------------------------------------------- 1 | [build] 2 | target = "wasm32-unknown-unknown" 3 | rustflags = [ 4 | "-C", "link-args=-zstack-size=2048 -s", 5 | ] 6 | -------------------------------------------------------------------------------- /tutorials/rust/examples/analog/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "examples" 3 | version = "0.1.0" 4 | authors = ["Tom Lauwaerts "] 5 | edition = "2018" 6 | 7 | [lib] 8 | path = "main/main.rs" 9 | crate-type = ["cdylib"] 10 | 11 | [dependencies] 12 | warduino = { path = "../../lib/warduino" } 13 | 14 | [profile.dev] 15 | panic = "abort" 16 | opt-level = 2 17 | 18 | [profile.release] 19 | panic = "abort" 20 | opt-level = 3 21 | debug = true 22 | -------------------------------------------------------------------------------- /tutorials/rust/examples/analog/main/main.rs: -------------------------------------------------------------------------------- 1 | use warduino::{analog_read, delay, print}; 2 | 3 | #[no_mangle] 4 | pub fn main() { 5 | let value: u32 = analog_read(13); 6 | print(&value.to_string()); 7 | delay(1); 8 | } 9 | -------------------------------------------------------------------------------- /tutorials/rust/examples/ascii/.cargo/config: -------------------------------------------------------------------------------- 1 | [build] 2 | target = "wasm32-unknown-unknown" 3 | rustflags = [ 4 | "-C", "link-args=-zstack-size=2048 -s", 5 | ] 6 | -------------------------------------------------------------------------------- /tutorials/rust/examples/ascii/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "examples" 3 | version = "0.1.0" 4 | authors = ["Tom Lauwaerts "] 5 | edition = "2018" 6 | 7 | [lib] 8 | path = "main/main.rs" 9 | crate-type = ["cdylib"] 10 | 11 | [dependencies] 12 | warduino = { path = "../../lib/warduino" } 13 | 14 | [profile.dev] 15 | panic = "abort" 16 | opt-level = 2 17 | 18 | [profile.release] 19 | panic = "abort" 20 | opt-level = 3 21 | debug = true 22 | -------------------------------------------------------------------------------- /tutorials/rust/examples/ascii/main/main.rs: -------------------------------------------------------------------------------- 1 | use warduino::{print}; 2 | 3 | #[no_mangle] 4 | pub fn main() { 5 | print("ASCII Table ~ Character Map\n"); 6 | 7 | for byte in 33..=125 { 8 | print(&format!("{}, dec: {}, hex: {:x}, oct: {:o}, bin: {:b}\n", char::from_u32(byte).unwrap(), byte, byte, byte, byte).to_string()); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tutorials/rust/examples/button/.cargo/config: -------------------------------------------------------------------------------- 1 | [build] 2 | target = "wasm32-unknown-unknown" 3 | rustflags = [ 4 | "-C", "link-args=-zstack-size=2048 -s", 5 | ] 6 | -------------------------------------------------------------------------------- /tutorials/rust/examples/button/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "examples" 3 | version = "0.1.0" 4 | authors = ["Tom Lauwaerts "] 5 | edition = "2018" 6 | 7 | [lib] 8 | path = "main/main.rs" 9 | crate-type = ["cdylib"] 10 | 11 | [dependencies] 12 | warduino = { path = "../../lib/warduino" } 13 | 14 | [profile.dev] 15 | panic = "abort" 16 | opt-level = 2 17 | 18 | [profile.release] 19 | panic = "abort" 20 | opt-level = 3 21 | debug = true 22 | -------------------------------------------------------------------------------- /tutorials/rust/examples/button/main/main.rs: -------------------------------------------------------------------------------- 1 | use warduino::{delay, 2 | digital_read, 3 | digital_write, 4 | InterruptMode, 5 | pin_mode, 6 | PinMode, 7 | PinVoltage, 8 | sub_interrupt}; 9 | 10 | static BUTTON: u32 = 25; 11 | static LED: u32 = 26; 12 | 13 | fn callback(_topic: &str, _payload: &str, _length: u32) { 14 | let voltage = digital_read(LED); 15 | match voltage { 16 | PinVoltage::HIGH => digital_write(LED, PinVoltage::LOW), 17 | PinVoltage::LOW => digital_write(LED, PinVoltage::HIGH) 18 | } 19 | } 20 | 21 | #[no_mangle] 22 | pub fn main() { 23 | pin_mode(BUTTON, PinMode::INPUT); 24 | pin_mode(LED, PinMode::OUTPUT); 25 | 26 | sub_interrupt(BUTTON, InterruptMode::FALLING, callback); 27 | 28 | loop { 29 | delay(1000); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /tutorials/rust/examples/configuration/.cargo/config: -------------------------------------------------------------------------------- 1 | [build] 2 | target = "wasm32-unknown-unknown" 3 | rustflags = [ 4 | "-C", "link-args=-zstack-size=2048 -s", 5 | ] 6 | -------------------------------------------------------------------------------- /tutorials/rust/examples/configuration/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "examples" 3 | version = "0.1.0" 4 | authors = ["Tom Lauwaerts "] 5 | edition = "2018" 6 | 7 | [lib] 8 | path = "main/main.rs" 9 | crate-type = ["cdylib"] 10 | 11 | [dependencies] 12 | warduino = { path = "../../lib/warduino" } 13 | 14 | [profile.dev] 15 | panic = "abort" 16 | opt-level = 2 17 | 18 | [profile.release] 19 | panic = "abort" 20 | opt-level = 3 21 | debug = true 22 | -------------------------------------------------------------------------------- /tutorials/rust/examples/configuration/main/config.rs: -------------------------------------------------------------------------------- 1 | pub static BUTTON: u32 = 25; 2 | pub static LED: u32 = 26; 3 | pub static SSID: &str = "local-network"; 4 | pub static PASSWORD: &str = "network-password"; 5 | pub static CLIENT_ID: &str = "random-mqtt-client-id"; 6 | -------------------------------------------------------------------------------- /tutorials/rust/examples/configuration/main/main.rs: -------------------------------------------------------------------------------- 1 | use warduino::{pin_mode, PinMode}; 2 | 3 | mod config; 4 | 5 | #[no_mangle] 6 | pub fn main() { 7 | let led: u32 = config::LED; 8 | pin_mode(led, PinMode::OUTPUT); 9 | } 10 | -------------------------------------------------------------------------------- /tutorials/rust/lib/warduino/.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | *.wasm* 3 | *.wat 4 | *.log 5 | *.h 6 | -------------------------------------------------------------------------------- /tutorials/rust/lib/warduino/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "warduino" 3 | version = "0.1.0" 4 | authors = ["Tom Lauwaerts "] 5 | description = "Library for WARDuino primitives" 6 | edition = "2018" 7 | keywords = ["warduino", "wasm"] 8 | license = "MPL-2.0" 9 | 10 | [dependencies] 11 | num = "0.4" 12 | num-traits = "0.2" 13 | num-derive = "0.3" 14 | -------------------------------------------------------------------------------- /tutorials/wat/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | 3 | if (NOT EXISTS $ENV{IDF_PATH}/tools/cmake/project.cmake) 4 | message(FATAL_ERROR 5 | "Cannot find global project.cmake file. Make sure ESP-IDF is installed.") 6 | endif () 7 | 8 | include($ENV{IDF_PATH}/tools/cmake/project.cmake) 9 | project(wat) 10 | 11 | -------------------------------------------------------------------------------- /tutorials/wat/README.md: -------------------------------------------------------------------------------- 1 | # Examples in Textual WebAssembly 2 | 3 | The `main` folder contains example programs written in textual WebAssembly. 4 | 5 | ## Compiling and Running the Examples 6 | 7 | To compile and flash to an ESP32 with the ESP-IDF toolchain simply run the build script: 8 | 9 | ```bash 10 | bash ./build.sh blink 11 | ``` 12 | 13 | The script takes the name of a wat file from the main folder as argument (without extension). 14 | 15 | ## Blink example 16 | 17 | The `blink.wat` file implements the traditional "blinking LED" example for microcontrollers in WebAssembly Text Format (WAT). 18 | 19 | ## Factorial example 20 | 21 | The `fac.wat` file implements the traditional wasm example. The program prints `5!` to the serial port in an infinite loop. 22 | 23 | This is also an interesting example to run with the commandline interface: 24 | 25 | ```bash 26 | wdcli fac.wasm --invoke fac 10 27 | ``` 28 | 29 | -------------------------------------------------------------------------------- /tutorials/wat/build.sh: -------------------------------------------------------------------------------- 1 | # Compile and flash WAT examples 2 | 3 | set -e 4 | 5 | example=${1?Give an example as argument} 6 | echo -e "Building example: ${example}" 7 | 8 | src="main/${example}.wat" 9 | 10 | dir=$(dirname $src) 11 | cd ${dir} 12 | src=$(basename -- "$src") 13 | 14 | # Compile WAT 15 | echo -e "> compiling ${src} ..." 16 | 17 | if [[ $src == *.wat ]] || [[ $extension == *.wast ]]; then 18 | wat2wasm --no-canonicalize-leb128s --disable-bulk-memory --debug-names $src 19 | src="${src%.*}" 20 | echo -e "> created ${src}.wasm" 21 | fi 22 | 23 | # Optimize (optional) 24 | cp "${src}.wasm" "src.wasm" 25 | wasm-strip "src.wasm" 26 | echo -e "> optimized src.wasm" 27 | 28 | # Convert to C header 29 | xxd -i "src.wasm" > src.wasm.h 30 | echo -e "> created src.wasm.h" 31 | 32 | echo -e "\n> output files written to ${dir}/" 33 | 34 | # Compile and Flash WARDuino 35 | cd .. 36 | mkdir -p build 37 | cd build 38 | cmake .. 39 | make flash 40 | -------------------------------------------------------------------------------- /tutorials/wat/main/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(SOURCE_FILES 2 | ../../../src/Debug/debugger.cpp 3 | ../../../src/Interpreter/instructions.cpp 4 | ../../../src/Memory/mem.cpp 5 | ../../../src/Primitives/idf.cpp 6 | ../../../src/Edward/proxy.cpp 7 | ../../../src/Edward/proxy_supervisor.cpp 8 | ../../../src/Edward/RFC.cpp 9 | ../../../src/Utils/macros.cpp 10 | ../../../src/Utils/sockets.cpp 11 | ../../../src/Utils/util.cpp 12 | ../../../src/Utils/util_arduino.cpp 13 | ../../../src/WARDuino/CallbackHandler.cpp 14 | ../../../src/WARDuino/WARDuino.cpp 15 | ) 16 | 17 | idf_component_register(SRCS "main.cpp" ${SOURCE_FILES} INCLUDE_DIRS ../../../lib/json/single_include/ REQUIRES driver) 18 | 19 | add_definitions(-DESP=1) 20 | 21 | -------------------------------------------------------------------------------- /tutorials/wat/main/blink.wat: -------------------------------------------------------------------------------- 1 | (module 2 | ;; Type declarations 3 | (type $int32->int32->void (func (param i32 i32))) 4 | (type $int32->void (func (param i32))) 5 | (type $void->void (func)) 6 | 7 | ;; Imports from the WARDuino VM 8 | (import "env" "chip_delay" (func $env.chip_delay (type $int32->void))) 9 | (import "env" "chip_pin_mode" (func $env.chip_pin_mode (type $int32->int32->void))) 10 | (import "env" "chip_digital_write" (func $env.chip_digital_write (type $int32->int32->void))) 11 | 12 | ;; Non-mutable globals 13 | (global $led i32 (i32.const 23)) 14 | (global $on i32 (i32.const 1)) 15 | (global $off i32 (i32.const 0)) 16 | 17 | ;; Initialise function (private) 18 | (func $init (type $void->void) 19 | ;; Set pin mode 20 | global.get $led 21 | i32.const 2 22 | call $env.chip_pin_mode) 23 | 24 | ;; Blink function (public) 25 | (func $blink (type $void->void) 26 | ;; Declare local $delay 27 | (local $delay i32) 28 | i32.const 1000 29 | local.set $delay 30 | 31 | ;; Initialise 32 | call $init 33 | 34 | ;; Blink in infinite loop 35 | loop $infinite 36 | global.get $led 37 | global.get $on 38 | call $env.chip_digital_write ;; turn led on 39 | local.get $delay 40 | call $env.chip_delay ;; wait 41 | global.get $led 42 | global.get $off 43 | call $env.chip_digital_write ;; turn led off 44 | local.get $delay 45 | call $env.chip_delay ;; wait 46 | br $infinite ;; jump back to start of loop 47 | end) 48 | 49 | ;; Export blink as function 50 | (export "main" (func $blink))) 51 | -------------------------------------------------------------------------------- /tutorials/wat/main/fac.wat: -------------------------------------------------------------------------------- 1 | (module 2 | 3 | (; Imports from the WARDuino VM ;) 4 | (import "env" "print_string" (func $print.string (type $i32->i32->void))) 5 | (import "env" "print_int" (func $print.int (type $i32->void))) 6 | 7 | (; Type declarations ;) 8 | (type $i32->i32->void (func (param i32 i32))) 9 | (type $i32->void (func (param i32))) 10 | (type $i32->i32 (func (param i32) (result i32))) 11 | (type $void->void (func (param) (result))) 12 | 13 | (; Export two functions ;) 14 | (export "main" (func $main)) 15 | (export "fac" (func $fac)) 16 | 17 | (memory $mem 1) 18 | (data (i32.const 0) "\nCalculating fac(5) ... ") 19 | (func $fac (type $i32->i32) 20 | (i32.gt_s 21 | (local.get 0) 22 | (i32.const 1)) 23 | (if (result i32) 24 | (then 25 | (i32.sub 26 | (local.get 0) 27 | (i32.const 1)) 28 | (call $fac) 29 | (local.get 0) 30 | i32.mul) 31 | (else 32 | (i32.const 1)))) 33 | 34 | (func $main (type $void->void) 35 | (local $arg i32) 36 | (local.set $arg (i32.const 5)) 37 | (loop 38 | (call $print.string (i32.const 0) (i32.const 24)) 39 | (local.get $arg) 40 | (call $fac) 41 | (call $print.int) 42 | (br 0))) 43 | ) 44 | -------------------------------------------------------------------------------- /tutorials/wat/main/main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // WARDuino - WebAssembly interpreter for embedded devices. 3 | // 4 | // 5 | #include 6 | 7 | #include "../../../../src/WARDuino.h" 8 | #include "driver/gpio.h" 9 | #include "driver/uart.h" 10 | #include "esp_err.h" 11 | #include "esp_task_wdt.h" 12 | #include "freertos/FreeRTOS.h" 13 | #include "freertos/task.h" 14 | #include "sdkconfig.h" 15 | 16 | volatile bool handelingInterrupt = false; 17 | 18 | #include "src.wasm.h" 19 | 20 | extern "C" { 21 | extern void app_main(void); 22 | } 23 | 24 | WARDuino* wac = WARDuino::instance(); 25 | Module* m; 26 | 27 | void startDebuggerStd(void* pvParameter) { 28 | Channel* duplex = new Duplex(stdin, stdout); 29 | wac->debugger->setChannel(duplex); 30 | duplex->open(); 31 | 32 | int valread; 33 | uint8_t buffer[1024] = {0}; 34 | while (true) { 35 | taskYIELD(); 36 | vTaskDelay(1000 / portTICK_PERIOD_MS); 37 | 38 | while ((valread = duplex->read(buffer, 1024)) != -1) { 39 | wac->handleInterrupt(valread - 1, buffer); 40 | } 41 | } 42 | } 43 | 44 | void app_main(void) { 45 | m = wac->load_module(src_wasm, src_wasm_len, {}); 46 | // uint8_t command[] = {'0', '3', '\n'}; 47 | // wac->handleInterrupt(3, command); 48 | xTaskCreate(startDebuggerStd, "Debug Thread", 5000, NULL, 1, NULL); 49 | printf("START\n\n"); 50 | wac->run_module(m); 51 | printf("END\n\n"); 52 | wac->unload_module(m); 53 | } 54 | --------------------------------------------------------------------------------