├── .gitattributes ├── .github └── workflows │ ├── deploy.yml │ └── test.yml ├── .gitignore ├── Cargo.toml ├── README.md ├── build.rs ├── demo ├── README.md ├── app.wat ├── branch-monitor.mm └── calls-monitor.mm ├── docs ├── .gitignore ├── book.toml ├── logos │ └── whamm!_logo.png └── src │ ├── 404.md │ ├── SUMMARY.md │ ├── devs │ ├── cli.md │ ├── compiler_phases.md │ ├── contributors.md │ ├── core_lib.md │ ├── emit │ │ ├── emitting.md │ │ ├── engine_target.md │ │ └── rewriting_target.md │ ├── error_handling.md │ ├── intro.md │ ├── parsing.md │ ├── testing.md │ ├── translate.md │ └── verifying.md │ ├── examples │ ├── branch_monitor.md │ └── intro.md │ ├── images │ ├── anatomy.png │ ├── engine.png │ └── rewriting.png │ ├── intro.md │ └── intro │ ├── events.md │ ├── getting_started.md │ ├── injection_strategies.md │ ├── language.md │ ├── libraries.md │ ├── syntax │ ├── arith.md │ ├── conditionals.md │ ├── functions.md │ ├── logop.md │ ├── maps.md │ ├── primitives.md │ ├── probes.md │ ├── report_vars.md │ ├── scripts.md │ ├── shared_vars.md │ ├── strings.md │ ├── ternary.md │ ├── tuples.md │ ├── unshared_vars.md │ └── variables.md │ └── testing.md ├── ideas ├── events.md ├── frame_vars.md ├── front-end-configurability.md ├── monitors.md ├── querying_state.md ├── system_api.md └── wizard-target.md ├── providers ├── packages │ ├── events │ │ └── wasm:opcode:*.yaml │ ├── wasm:begin.yaml │ ├── wasm:end.yaml │ └── wasm:opcode.yaml └── wasm.yaml ├── rust-toolchain.toml ├── src ├── cli.rs ├── common.rs ├── common │ ├── error.rs │ ├── instr.rs │ ├── metrics.rs │ └── terminal.rs ├── emitter │ ├── locals_tracker.rs │ ├── memory_allocator.rs │ ├── mod.rs │ ├── module_emitter.rs │ ├── rewriting │ │ ├── mod.rs │ │ ├── rules │ │ │ └── mod.rs │ │ └── visiting_emitter.rs │ ├── tests.rs │ └── utils.rs ├── generator │ ├── ast.rs │ ├── folding.rs │ ├── metadata_collector.rs │ ├── mod.rs │ ├── rewriting │ │ ├── init_generator.rs │ │ ├── instr_generator.rs │ │ ├── mod.rs │ │ └── simple_ast.rs │ ├── tests.rs │ └── wizard │ │ └── mod.rs ├── lang_features │ ├── alloc_vars │ │ ├── mod.rs │ │ ├── rewriting.rs │ │ └── wizard.rs │ ├── libraries │ │ ├── actions.rs │ │ ├── core │ │ │ ├── io │ │ │ │ ├── io_adapter.rs │ │ │ │ └── mod.rs │ │ │ ├── maps │ │ │ │ ├── map_adapter.rs │ │ │ │ └── mod.rs │ │ │ └── mod.rs │ │ ├── linking │ │ │ ├── import_lib.rs │ │ │ └── mod.rs │ │ └── mod.rs │ ├── mod.rs │ └── report_vars.rs ├── lib.rs ├── main.rs ├── parser.rs ├── parser │ ├── provider_handler.rs │ ├── tests.rs │ ├── tests │ │ ├── numerics.rs │ │ └── whamm_scripts.rs │ ├── types.rs │ ├── whamm.pest │ └── whamm_parser.rs ├── verifier.rs ├── verifier │ ├── builder_visitor.rs │ ├── tests.rs │ ├── types.rs │ └── verifier.rs ├── wast.rs └── wast │ └── test_harness.rs ├── tests ├── apps │ ├── core_suite │ │ ├── clang │ │ │ ├── malloc_init.wasm │ │ │ └── malloc_init.wat │ │ ├── handwritten │ │ │ ├── add.wasm │ │ │ ├── add.wat │ │ │ ├── basic.wasm │ │ │ ├── basic.wat │ │ │ ├── branches-no-br_table.wasm │ │ │ ├── branches-no-br_table.wat │ │ │ ├── branches.wasm │ │ │ ├── branches.wat │ │ │ ├── for_numerics-skip_ExprFolder.wasm │ │ │ ├── for_numerics-skip_ExprFolder.wat │ │ │ ├── for_numerics.wasm │ │ │ ├── for_numerics.wat │ │ │ ├── mem-ops.wasm │ │ │ ├── mem-ops.wat │ │ │ ├── no_matched_events.wasm │ │ │ └── no_matched_events.wat │ │ ├── ostrich │ │ │ └── nw.wasm │ │ ├── polybench │ │ │ └── 2mm.wasm │ │ └── rust │ │ │ ├── cf.wasm │ │ │ └── cf.wat │ └── dfinity │ │ └── users.wasm ├── common │ └── mod.rs ├── integration_test.rs ├── scripts │ ├── README.md │ ├── core_suite │ │ ├── branch-monitor │ │ │ ├── app │ │ │ │ ├── branch-br__br_if__br_table.mm.app │ │ │ │ ├── branch-on_hw-br__br_if.mm.app │ │ │ │ ├── branch-on_rust-br__br_if.mm.app │ │ │ │ ├── branch_with_allocs-on_hw-br__br_if.mm.app │ │ │ │ ├── branch_with_allocs-on_hw-br__br_if__br_table.mm.app │ │ │ │ └── branch_with_allocs-on_rust-br__br_if__br_table.mm.app │ │ │ ├── branch-on_hw-br__br_if.mm │ │ │ ├── branch-on_rust-br__br_if.mm │ │ │ ├── branch_with_allocs-on_hw-br__br_if.mm │ │ │ └── expected │ │ │ │ ├── rewriting │ │ │ │ ├── branch-br__br_if__br_table.mm.exp │ │ │ │ ├── branch-on_hw-br__br_if.mm.exp │ │ │ │ ├── branch-on_rust-br__br_if.mm.exp │ │ │ │ ├── branch_with_allocs-on_hw-br__br_if.mm.exp │ │ │ │ ├── branch_with_allocs-on_hw-br__br_if__br_table.mm.exp │ │ │ │ └── branch_with_allocs-on_rust-br__br_if__br_table.mm.exp │ │ │ │ └── wizard │ │ │ │ ├── branch-on_hw-br__br_if.mm.exp │ │ │ │ ├── branch-on_rust-br__br_if.mm.exp │ │ │ │ ├── branch_with_allocs-on_hw-br__br_if.mm.exp │ │ │ │ └── branch_with_allocs-on_hw-br__br_if__br_table.mm.exp │ │ ├── branch-monitor_rewriting │ │ │ ├── app │ │ │ │ ├── branch-br__br_if__br_table.mm.app │ │ │ │ ├── branch_with_allocs-on_hw-br__br_if__br_table.mm.app │ │ │ │ └── branch_with_allocs-on_rust-br__br_if__br_table.mm.app │ │ │ ├── branch-br__br_if__br_table.mm │ │ │ ├── branch_with_allocs-on_hw-br__br_if__br_table.mm │ │ │ ├── branch_with_allocs-on_rust-br__br_if__br_table.mm │ │ │ └── expected │ │ │ │ └── rewriting │ │ │ │ ├── branch-br__br_if__br_table.mm.exp │ │ │ │ ├── branch_with_allocs-on_hw-br__br_if__br_table.mm.exp │ │ │ │ └── branch_with_allocs-on_rust-br__br_if__br_table.mm.exp │ │ ├── calls-monitor │ │ │ ├── app │ │ │ │ ├── basic-alloc-hw.mm.app │ │ │ │ ├── basic-hw.mm.app │ │ │ │ ├── basic-rust.mm.app │ │ │ │ └── basic_global-hw.mm.app │ │ │ ├── basic-alloc-hw.mm │ │ │ ├── basic-hw.mm │ │ │ ├── basic-rust.mm │ │ │ ├── basic_global-hw.mm │ │ │ └── expected │ │ │ │ ├── rewriting │ │ │ │ ├── basic-alloc-hw.mm.exp │ │ │ │ ├── basic-hw.mm.exp │ │ │ │ ├── basic-rust.mm.exp │ │ │ │ └── basic_global-hw.mm.exp │ │ │ │ └── wizard │ │ │ │ ├── basic-alloc-hw.mm.exp │ │ │ │ ├── basic-hw.mm.exp │ │ │ │ ├── basic-rust.mm.exp │ │ │ │ └── basic_global-hw.mm.exp │ │ ├── calls-monitor_rewriting │ │ │ ├── app │ │ │ │ └── basic-alloc-rust.mm.app │ │ │ ├── basic-alloc-rust.mm │ │ │ └── expected │ │ │ │ ├── rewriting │ │ │ │ └── basic-alloc-rust.mm.exp │ │ │ │ └── wizard │ │ │ │ └── basic-alloc-rust.mm.exp │ │ └── numerics │ │ │ ├── app │ │ │ ├── basic_operations-skip_ExprFolder.mm.app │ │ │ ├── basic_operations.mm.app │ │ │ ├── floats-skip_ExprFolder.mm.app │ │ │ ├── floats.mm.app │ │ │ ├── ints_signed-skip_ExprFolder.mm.app │ │ │ ├── ints_signed.mm.app │ │ │ ├── ints_unsigned-skip_ExprFolder.mm.app │ │ │ ├── ints_unsigned.mm.app │ │ │ ├── mixed_types-skip_ExprFolder.mm.app │ │ │ └── mixed_types.mm.app │ │ │ ├── basic_operations-skip_ExprFolder.mm │ │ │ ├── basic_operations.mm │ │ │ ├── expected │ │ │ ├── rewriting │ │ │ │ ├── basic_operations-skip_ExprFolder.mm.exp │ │ │ │ ├── basic_operations.mm.exp │ │ │ │ ├── floats-skip_ExprFolder.mm.exp │ │ │ │ ├── floats.mm.exp │ │ │ │ ├── ints_signed-skip_ExprFolder.mm.exp │ │ │ │ ├── ints_signed.mm.exp │ │ │ │ ├── ints_unsigned-skip_ExprFolder.mm.exp │ │ │ │ ├── ints_unsigned.mm.exp │ │ │ │ ├── mixed_types-skip_ExprFolder.mm.exp │ │ │ │ └── mixed_types.mm.exp │ │ │ └── wizard │ │ │ │ ├── basic_operations-skip_ExprFolder.mm.exp │ │ │ │ ├── basic_operations.mm.exp │ │ │ │ ├── floats-skip_ExprFolder.mm.exp │ │ │ │ ├── floats.mm.exp │ │ │ │ ├── ints_signed-skip_ExprFolder.mm.exp │ │ │ │ ├── ints_signed.mm.exp │ │ │ │ ├── ints_unsigned-skip_ExprFolder.mm.exp │ │ │ │ ├── ints_unsigned.mm.exp │ │ │ │ ├── mixed_types-skip_ExprFolder.mm.exp │ │ │ │ └── mixed_types.mm.exp │ │ │ ├── floats-skip_ExprFolder.mm │ │ │ ├── floats.mm │ │ │ ├── ints_signed-skip_ExprFolder.mm │ │ │ ├── ints_signed.mm │ │ │ ├── ints_unsigned-skip_ExprFolder.mm │ │ │ ├── ints_unsigned.mm │ │ │ ├── mixed_types-skip_ExprFolder.mm │ │ │ └── mixed_types.mm │ ├── error │ │ └── bad.mm │ ├── fault_injection │ │ ├── dfinity │ │ │ ├── dfinity_async_strcmp_fn.mm │ │ │ ├── dfinity_dei-integration.mm.TODO │ │ │ ├── dfinity_sync-with-pred.mm.TODO │ │ │ └── dfinity_sync.mm │ │ └── spin │ │ │ └── filibuster-with-spin.mm.TODO │ ├── functionality_test │ │ ├── dfinity_testing_access_global_after.mm │ │ ├── dfinity_testing_access_global_before.mm │ │ └── dfinity_testing_var_init.mm │ ├── instr.mm │ ├── lang_features │ │ └── report_and_alloc_vars.mm │ ├── paper_eval │ │ ├── branches │ │ │ ├── app │ │ │ │ ├── branches-hw.mm.app │ │ │ │ ├── branches-ostrich.mm.app │ │ │ │ ├── branches-polybench.mm.app │ │ │ │ ├── branches-rust.mm.app │ │ │ │ └── branches-subset.mm.app │ │ │ ├── branches-hw.mm │ │ │ ├── branches-ostrich.mm │ │ │ ├── branches-polybench.mm │ │ │ ├── branches-rust.mm │ │ │ ├── branches-subset.mm │ │ │ └── expected │ │ │ │ ├── rewriting │ │ │ │ ├── branches-hw.mm.exp │ │ │ │ ├── branches-ostrich.mm.exp │ │ │ │ ├── branches-polybench.mm.exp │ │ │ │ ├── branches-rust.mm.exp │ │ │ │ └── branches-subset.mm.exp │ │ │ │ └── wizard │ │ │ │ ├── branches-hw.mm.exp │ │ │ │ ├── branches-ostrich.mm.exp │ │ │ │ ├── branches-polybench.mm.exp │ │ │ │ ├── branches-rust.mm.exp │ │ │ │ └── branches-subset.mm.exp │ │ ├── cache_sim │ │ │ ├── app │ │ │ │ ├── cache_sim-clang.mm.app │ │ │ │ └── cache_sim-hw.mm.app │ │ │ ├── cache_sim-clang.mm │ │ │ ├── cache_sim-hw.mm │ │ │ ├── expected │ │ │ │ ├── rewriting │ │ │ │ │ ├── cache_sim-clang.mm.exp │ │ │ │ │ └── cache_sim-hw.mm.exp │ │ │ │ └── wizard │ │ │ │ │ ├── cache_sim-clang.mm.exp │ │ │ │ │ └── cache_sim-hw.mm.exp │ │ │ └── libs │ │ │ │ ├── cache_sim-clang.mm.libs │ │ │ │ └── cache_sim-hw.mm.libs │ │ ├── categories │ │ │ ├── app │ │ │ │ ├── category-hw.mm.app │ │ │ │ ├── category-rust.mm.app │ │ │ │ ├── category_as_allocs-hw.mm.app │ │ │ │ ├── category_as_allocs-rust.mm.app │ │ │ │ ├── category_fastest-hw.mm.app │ │ │ │ └── category_fastest-rust.mm.app │ │ │ ├── category-hw.mm │ │ │ ├── category-rust.mm │ │ │ ├── category_as_allocs-hw.mm │ │ │ ├── category_as_allocs-rust.mm │ │ │ ├── category_fastest-hw.mm │ │ │ ├── category_fastest-rust.mm │ │ │ └── expected │ │ │ │ ├── rewriting │ │ │ │ ├── category-hw.mm.exp │ │ │ │ ├── category-rust.mm.exp │ │ │ │ ├── category_as_allocs-hw.mm.exp │ │ │ │ ├── category_as_allocs-rust.mm.exp │ │ │ │ ├── category_fastest-hw.mm.exp │ │ │ │ └── category_fastest-rust.mm.exp │ │ │ │ └── wizard │ │ │ │ ├── category-hw.mm.exp │ │ │ │ ├── category-rust.mm.exp │ │ │ │ ├── category_as_allocs-hw.mm.exp │ │ │ │ ├── category_as_allocs-rust.mm.exp │ │ │ │ ├── category_fastest-hw.mm.exp │ │ │ │ └── category_fastest-rust.mm.exp │ │ ├── hotness │ │ │ ├── app │ │ │ │ ├── hotness-hw.mm.app │ │ │ │ └── hotness-rust.mm.app │ │ │ ├── expected │ │ │ │ ├── rewriting │ │ │ │ │ ├── hotness-hw.mm.exp │ │ │ │ │ └── hotness-rust.mm.exp │ │ │ │ └── wizard │ │ │ │ │ ├── hotness-hw.mm.exp │ │ │ │ │ └── hotness-rust.mm.exp │ │ │ ├── hotness-hw.mm │ │ │ └── hotness-rust.mm │ │ └── ins_count │ │ │ ├── app │ │ │ ├── ins_count-hw.mm.app │ │ │ ├── ins_count-polybench.mm.app │ │ │ └── ins_count-rust.mm.app │ │ │ ├── expected │ │ │ ├── rewriting │ │ │ │ ├── ins_count-hw.mm.exp │ │ │ │ ├── ins_count-polybench.mm.exp │ │ │ │ └── ins_count-rust.mm.exp │ │ │ └── wizard │ │ │ │ ├── ins_count-hw.mm.exp │ │ │ │ ├── ins_count-polybench.mm.exp │ │ │ │ └── ins_count-rust.mm.exp │ │ │ ├── ins_count-hw.mm │ │ │ ├── ins_count-polybench.mm │ │ │ └── ins_count-rust.mm │ └── wizard_monitors │ │ ├── basic.mm │ │ ├── branch-allocs.mm │ │ ├── branch-br_table.mm │ │ ├── branch-nulls.mm.TODO │ │ ├── branch-report_allocs.mm │ │ ├── loop.mm.TODO │ │ └── opcodes.mm.TODO └── wast_suite │ ├── control_flow │ ├── if.wast │ └── if_else.wast │ └── events │ └── wasm_opcodes │ ├── TODO │ └── i64_const.wast.todo │ ├── block.wast │ ├── br.wast │ ├── br_if.wast │ ├── br_table.wast.TODO │ ├── call │ ├── import │ │ ├── args.wast │ │ ├── imms.wast │ │ ├── prov-fns.wast │ │ └── prov-globals.wast │ └── local │ │ ├── args.wast │ │ ├── args_mul-calls.wast │ │ ├── imms.wast │ │ ├── in_loop.wast │ │ ├── prov-fns.wast │ │ └── prov-globals.wast │ ├── else.wast │ ├── end.wast │ ├── global_get.wast │ ├── global_set.wast │ ├── i32_const.wast │ ├── if.wast │ ├── local_get.wast │ ├── local_set.wast │ ├── local_tee.wast │ ├── loop.wast │ ├── nop.wast │ ├── return.wast │ ├── unreachable.wast │ └── unreachable_target_loc.wast ├── user_libs └── cache │ ├── Cargo.toml │ ├── README.md │ ├── rust-toolchain.toml │ └── src │ └── lib.rs ├── wasm_playground ├── README.md ├── control_flow │ ├── Cargo.toml │ ├── demo_scripts │ │ └── branch-monitor.mm │ ├── rust-toolchain.toml │ ├── src │ │ └── main.rs │ └── whamm │ │ ├── basic-alloc.mm │ │ ├── basic.mm │ │ ├── branch-allocs.mm │ │ ├── branch-br_table.mm │ │ └── branch-report_allocs.mm ├── example │ ├── Cargo.toml │ ├── README.md │ ├── add_map.mm │ ├── rust-toolchain.toml │ └── src │ │ └── main.rs └── strcmp │ ├── strcmp-roundtrip.wat │ ├── strcmp.wasm │ └── strcmp.wat ├── wasmtime-runner ├── Cargo.toml ├── README.md └── src │ └── main.rs └── whamm_core ├── Cargo.toml ├── README.md ├── rust-toolchain.toml └── src ├── io ├── mod.rs └── print.rs ├── lib.rs ├── maps └── mod.rs └── tests.rs /.gitattributes: -------------------------------------------------------------------------------- 1 | tests/apps/* linguist-vendored=false 2 | tests/**/*.exp linguist-vendored=false -------------------------------------------------------------------------------- /.github/workflows/deploy.yml: -------------------------------------------------------------------------------- 1 | name: Deploy 2 | on: 3 | push: 4 | branches: [ "master" ] 5 | 6 | jobs: 7 | deploy: 8 | runs-on: ubuntu-latest 9 | permissions: 10 | contents: write # To push a branch 11 | pages: write # To push to a GitHub Pages site 12 | id-token: write # To update the deployment status 13 | steps: 14 | - uses: actions/checkout@v4 15 | with: 16 | fetch-depth: 0 17 | - name: Install latest mdbook 18 | run: | 19 | tag=$(curl 'https://api.github.com/repos/rust-lang/mdbook/releases/latest' | jq -r '.tag_name') 20 | url="https://github.com/rust-lang/mdbook/releases/download/${tag}/mdbook-${tag}-x86_64-unknown-linux-gnu.tar.gz" 21 | mkdir mdbook 22 | curl -sSL $url | tar -xz --directory=./mdbook 23 | echo `pwd`/mdbook >> $GITHUB_PATH 24 | - name: Build Book 25 | run: | 26 | # This assumes your book is in the root of your repository. 27 | # Just add a `cd` here if you need to change to another directory. 28 | cd docs 29 | mdbook build 30 | - name: Setup Pages 31 | uses: actions/configure-pages@v4 32 | - name: Upload artifact 33 | uses: actions/upload-pages-artifact@v3 34 | with: 35 | # Upload entire repository 36 | path: 'docs/book' 37 | - name: Deploy to GitHub Pages 38 | id: deployment 39 | uses: actions/deploy-pages@v4 -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # IntelliJ configuration 2 | .idea/ 3 | #vscode settings 4 | .vscode/ 5 | 6 | # Generated by Cargo 7 | # will have compiled files and executables 8 | debug/ 9 | target/ 10 | 11 | # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries 12 | # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html 13 | Cargo.lock 14 | 15 | # These are backup files generated by rustfmt 16 | **/*.rs.bk 17 | 18 | # MSVC Windows builds of rustc generate these, which store debugging information 19 | *.pdb 20 | 21 | # Ignore the huge test files 22 | tests/apps/**/*.wat 23 | tests/apps/core_suite/**/*.wasm 24 | !tests/apps/core_suite/**/*.wat 25 | demo/**/*.wasm 26 | output/ 27 | 28 | # Ignore the wasm playground files 29 | wasm_playground/**/*.wat 30 | wasm_playground/**/*.wasm 31 | 32 | # Ignore mac files 33 | .DS_Store 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "whamm" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [[bin]] 7 | doc = false 8 | name = "whamm" 9 | path = "src/main.rs" 10 | #required-features = ["exe"] 11 | 12 | [dependencies] 13 | failure = "0.1.5" 14 | glob = "0.3.1" 15 | lazy_static = "1.4.0" 16 | itertools = "0.14.0" 17 | #orca-wasm = { path = "../orca" } 18 | orca-wasm = "=0.9.0" 19 | wasmparser = "0.224.0" 20 | 21 | # Logging 22 | env_logger = "0.10.2" 23 | log = "0.4.20" 24 | termcolor = "1.4.1" 25 | 26 | # Pest 27 | pest = "2.7.7" 28 | pest_derive = "2.7.7" 29 | 30 | # Provider YAML configs 31 | serde = { version = "1.0", features = ["derive"] } 32 | serde_yml = "0.0.12" 33 | 34 | # CLI 35 | clap = { version = "4.5.4", features = ["derive", "cargo", "env"] } 36 | clap_complete = "4.5.2" 37 | 38 | wat = "1.214.0" 39 | 40 | [build-dependencies] 41 | clap = { version = "4.5.4", features = ["derive", "cargo", "env"] } 42 | clap_complete = "4.5.2" 43 | clap_mangen = "0.2.20" 44 | project-root = "0.2.2" 45 | -------------------------------------------------------------------------------- /build.rs: -------------------------------------------------------------------------------- 1 | use clap::CommandFactory; 2 | use clap_mangen::Man; 3 | use project_root::get_project_root; 4 | use std::fs::File; 5 | use std::io::Error; 6 | use std::path::{Path, PathBuf}; 7 | use std::process::exit; 8 | 9 | include!("src/cli.rs"); 10 | 11 | fn build_man(out_dir: &Path) -> Result<(), Error> { 12 | let app = WhammCli::command(); 13 | 14 | let file = Path::new(&out_dir).join("example.1"); 15 | let mut file = File::create(file)?; 16 | 17 | Man::new(app).render(&mut file)?; 18 | 19 | Ok(()) 20 | } 21 | 22 | fn main() -> Result<(), Box> { 23 | println!("cargo:rerun-if-changed=src/cli.rs"); 24 | println!("cargo:rerun-if-changed=man"); 25 | 26 | // Create `target/assets/` folder. 27 | let mut path = match get_pb(&PathBuf::from("target")) { 28 | Ok(pb) => pb, 29 | Err(_) => exit(1), 30 | }; 31 | path.push("assets"); 32 | std::fs::create_dir_all(&path).unwrap(); 33 | 34 | // build_shell_completion(&path)?; 35 | build_man(&path)?; 36 | 37 | Ok(()) 38 | } 39 | 40 | fn get_pb(file_pb: &PathBuf) -> Result { 41 | if file_pb.is_relative() { 42 | match get_project_root() { 43 | Ok(r) => { 44 | let mut full_path = r.clone(); 45 | full_path.push(file_pb); 46 | Ok(full_path) 47 | } 48 | Err(e) => Err(format!("the root folder does not exist: {:?}", e)), 49 | } 50 | } else { 51 | Ok(file_pb.clone()) 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /demo/README.md: -------------------------------------------------------------------------------- 1 | # Whamm Demo # 2 | 3 | These demo instructions assume that the `whamm` command has been added to your `PATH`. 4 | 5 | This can be done via: 6 | ```shell 7 | cargo build 8 | alias whamm=$(pwd)/target/debug/whamm 9 | ``` 10 | 11 | ## Bytecode Rewriting Target ## 12 | 13 | Example running the `branch-monitor` script: 14 | ```shell 15 | # Setup 16 | pushd whamm_core 17 | cargo build --target wasm32-wasip1 --release 18 | popd 19 | WHAMM_CORE=whamm_core/target/wasm32-wasip1/release/whamm_core.wasm 20 | cd demo/ 21 | mkdir output/ 22 | 23 | # Instrument the application 24 | whamm instr --script branch-monitor.mm --app app.wasm --core-lib $WHAMM_CORE -o output/app-instr.wasm 25 | 26 | # Run the monitor (must be on wizard since it depends on the engine `puts` host function) 27 | ``` 28 | 29 | ## Wizard Target ## 30 | 31 | Example running the `branch-monitor` script: 32 | ```shell 33 | # Setup 34 | pushd whamm_core 35 | cargo build --target wasm32-wasip1 --release 36 | popd 37 | WHAMM_CORE=whamm_core/target/wasm32-wasip1/release/whamm_core.wasm 38 | cd demo/ 39 | mkdir output/ 40 | 41 | # Compile the monitor to a Wasm module that targets the Wizard engine extension 42 | whamm instr --script branch-monitor.mm --core-lib $WHAMM_CORE -o output/wiz-mon.wasm --wizard 43 | 44 | # Run the monitor (must be on wizard) 45 | wizard --env=TO_CONSOLE=true --monitors=output/wiz-mon.wasm+$WHAMM_CORE app.wasm 46 | ``` -------------------------------------------------------------------------------- /demo/app.wat: -------------------------------------------------------------------------------- 1 | (module 2 | (import "wizeng" "puts" (func $puts (param i32 i32))) 3 | (func $main (export "main") 4 | (local i32) 5 | (local.set 0 (call $call_target (i32.const 0))) 6 | (block 7 | (br_if 1 (local.get 0)) 8 | ) 9 | ) 10 | (func $call_target (param i32) (result i32) 11 | (block 12 | (br_if 0 (local.get 0)) 13 | call $foo 14 | ) 15 | call $bar 16 | (local.get 0) 17 | ) 18 | (func $foo 19 | (call $puts (i32.const 0) (i32.const 4)) 20 | br 0 21 | ) 22 | (func $bar 23 | (call $puts (i32.const 4) (i32.const 4)) 24 | br 0 25 | ) 26 | (memory 1) 27 | (export "memory" (memory 0)) 28 | (data (;0;) (i32.const 0) "foo\n") 29 | (data (;1;) (i32.const 4) "bar\n") 30 | ) 31 | -------------------------------------------------------------------------------- /demo/branch-monitor.mm: -------------------------------------------------------------------------------- 1 | wasm::br:before { 2 | report var taken: i32; 3 | // branch always taken for `br` 4 | taken++; 5 | } 6 | 7 | wasm::br_if:before { 8 | report var taken: i32; 9 | report var not_taken: i32; 10 | 11 | // which branch was taken? 12 | if (arg0 != 0) { 13 | taken++; 14 | } else { 15 | not_taken++; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /demo/calls-monitor.mm: -------------------------------------------------------------------------------- 1 | wasm:opcode:call(arg0: i32):before 2 | / imm0 == 2 && arg0 == 0 / 3 | { 4 | report var count: i32; 5 | 6 | count++; 7 | } -------------------------------------------------------------------------------- /docs/.gitignore: -------------------------------------------------------------------------------- 1 | book 2 | -------------------------------------------------------------------------------- /docs/book.toml: -------------------------------------------------------------------------------- 1 | [book] 2 | title = "whamm!" 3 | description = "An introduction to the `whamm!` DSL." 4 | authors = ["ahuoguo", "ejrgilbert", "wavid-b"] 5 | language = "en" 6 | multilingual = false 7 | src = "src" 8 | 9 | [output.html] 10 | git-repository-url = "https://github.com/ejrgilbert/whamm/" 11 | edit-url-template = "https://github.com/ejrgilbert/whamm/edit/master/docs/{path}" 12 | # TODO -- add highlighting here (see https://github.com/pest-parser/book/blob/master/highlight-pest.js) 13 | #additional-js = ["highlight-pest.js"] 14 | -------------------------------------------------------------------------------- /docs/logos/whamm!_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ejrgilbert/whamm/2bc891519c0c657e591fc75971441d556f1e2223/docs/logos/whamm!_logo.png -------------------------------------------------------------------------------- /docs/src/404.md: -------------------------------------------------------------------------------- 1 | # Document not found (404) 2 | 3 | This URL is invalid, sorry. Try the search instead! -------------------------------------------------------------------------------- /docs/src/SUMMARY.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | 3 | - [Introduction](intro.md) 4 | 5 | - [Getting Started](intro/getting_started.md) 6 | - [Language](intro/language.md) 7 | - [Variables](intro/syntax/variables.md) 8 | - [Logical Operations](intro/syntax/logop.md) 9 | - [Ternary Expressions](intro/syntax/ternary.md) 10 | - [Primitives](intro/syntax/primitives.md) 11 | - [Arithmetic](intro/syntax/arith.md) 12 | - [WIP - Strings](intro/syntax/strings.md) 13 | - [WIP - Tuples](intro/syntax/tuples.md) 14 | - [WIP - Maps](intro/syntax/maps.md) 15 | - [WIP - Functions](intro/syntax/functions.md) 16 | - [Report Variables](intro/syntax/report_vars.md) 17 | - [Unshared Variables](intro/syntax/unshared_vars.md) 18 | - [Shared Variables](intro/syntax/shared_vars.md) 19 | - [Probes](intro/syntax/probes.md) 20 | - [Scripts](intro/syntax/scripts.md) 21 | - [Events](intro/events.md) 22 | - [WIP - Libraries](intro/libraries.md) 23 | - [WIP - Testing](intro/testing.md) 24 | - [Injection Strategies](intro/injection_strategies.md) 25 | 26 | - [Example Use Cases](examples/intro.md) 27 | - [Branch Monitor](examples/branch_monitor.md) 28 | 29 | - [Developers](devs/intro.md) 30 | - [Phases of Compilation](devs/compiler_phases.md) 31 | - [Parse](devs/parsing.md) 32 | - [TODO - Core Library](devs/core_lib.md) 33 | - [Verify](devs/verifying.md) 34 | - [TODO - Translate](devs/translate.md) 35 | - [Emit](devs/emit/emitting.md) 36 | - [Rewriting](devs/emit/rewriting_target.md) 37 | - [TODO - Engine](devs/emit/engine_target.md) 38 | - [CLI](devs/cli.md) 39 | - [Testing](devs/testing.md) 40 | - [Error Handling](devs/error_handling.md) 41 | - [Contributors to `whamm!`](devs/contributors.md) 42 | -------------------------------------------------------------------------------- /docs/src/devs/cli.md: -------------------------------------------------------------------------------- 1 | # The `whamm!` CLI # 2 | 3 | The CLI is defined using the `clap` Rust crate. 4 | -------------------------------------------------------------------------------- /docs/src/devs/compiler_phases.md: -------------------------------------------------------------------------------- 1 | # The Four Phases of Compilation # 2 | 3 | First, what is meant by the term "compilation" depends on the selected injection strategy. 4 | 5 | For **bytecode rewriting**, compilation means generating a new _instrumented_ variation of the application's bytecode. 6 | 7 | For **direct engine support**, compilation means compiling the `.mm` script to a new Wasm module that interfaces with an engine to instrument the program dynamically. 8 | The original program is _not touched_ **and** _not provided_ when using this strategy. 9 | 10 | The first three phases of `whamm!` compilation are identical for both strategies. 11 | The `translate` and `emit` phases vary between injection strategy. 12 | This is because "emitting" for **bytecode rewriting** means using the `orcs` library to insert new instructions into the program. 13 | Whereas "emitting" for **direct engine support** means emitting a Wasm module encoding _where to instrument_ and the callbacks to attach at the probed sites by interfacing with the engine at application runtime. 14 | 15 | These are the four phases of compilation: 16 | 1. [Parse](parsing.md) 17 | 2. Configure the `Whamm!` [Core Library](./core_lib.md) (if needed) 18 | 3. [Verify](verifying.md) 19 | 4. [Translate](translate.md) AST into the injection strategy's representation 20 | 5. [Emit](emit/emitting.md) 21 | -------------------------------------------------------------------------------- /docs/src/devs/contributors.md: -------------------------------------------------------------------------------- 1 | # Contributors # 2 | 3 | These are the people to thank when you're using `whamm!`...either genuinely or sarcastically...if you have problems, you should let them know in a [GH issue](https://github.com/ejrgilbert/whamm/issues) ;) 4 | 5 | [**Elizabeth Gilbert**](https://se-phd.s3d.cmu.edu/People/students/student-bios/gilbert-elizabeth.html), PhD student at **Carnegie Mellon University (CMU)**. 6 | 7 | [**Alex Bai**](https://www.eecs.tufts.edu/~abai02/), undergrad student at **Tufts University**. 8 | 9 | [**Wavid Bowman**](), undergrad student at **University of Florida**. 10 | -------------------------------------------------------------------------------- /docs/src/devs/core_lib.md: -------------------------------------------------------------------------------- 1 | # Phase 2: Configure The `Whamm!` Core Library # 2 | 3 | TODO 4 | -------------------------------------------------------------------------------- /docs/src/devs/emit/emitting.md: -------------------------------------------------------------------------------- 1 | # Phase 5: Emit # 2 | 3 | Here is documentation describing how we _emit_ `.mm` scripts. 4 | 5 | ## Some Helpful Concepts ## 6 | 7 | **What is a `generator`?** 8 | A `generator` is used to traverse some representation of logic in an abstract way. 9 | It then calls the `emitter` when appropriate to actually emit the code in the target representation. 10 | 11 | **What is an `emitter`?** 12 | The `emitter` exposes an API that can be called to emit code in the target representation. 13 | There will be as many emitters as there are target representations supported by the language. 14 | 15 | ## The Injection Strategies ## 16 | 17 | The code that is emitted, and the methodology in which emitting happens, depends on the injection strategy specified by the user. 18 | 19 | There are currently two supported injection strategies: 20 | 1. [Bytecode Rewriting](./engine_target.md) 21 | 2. Interfacing with an [engine](./rewriting_target.md) 22 | -------------------------------------------------------------------------------- /docs/src/devs/emit/engine_target.md: -------------------------------------------------------------------------------- 1 | # Interfacing with an Engine # 2 | 3 | TODO 4 | -------------------------------------------------------------------------------- /docs/src/devs/error_handling.md: -------------------------------------------------------------------------------- 1 | # Error Handling # 2 | 3 | Errors are added to `ErrorGen`, defined in [`error.rs`], and reported between compiler phases. 4 | If an error occurs during a compilation phase, the errors are reported and the compilation is aborted. 5 | 6 | [`error.rs`]: https://github.com/ejrgilbert/whamm/blob/master/src/common/error.rs 7 | -------------------------------------------------------------------------------- /docs/src/devs/intro.md: -------------------------------------------------------------------------------- 1 | # For `whamm!` Developers # 2 | 3 | Do you want to contribute to `whamm!` or just learn about the low-level details for fun? 4 | Then you're in the right place. 5 | 6 | ## Resources ## 7 | 8 | Parsing: 9 | - The [Pest book](https://pest.rs/book/) 10 | 11 | ## `whamm!` Implementation Concepts ## 12 | 13 | The [_four phases_ of compilation](compiler_phases.md): 14 | 1. [Parse](parsing.md) 15 | 2. Configure the `Whamm!` [Core Library](./core_lib.md) (if needed) 16 | 3. [Verify](verifying.md) 17 | 4. [Translate](translate.md) AST into the injection strategy's representation 18 | 5. [Emit](emit/emitting.md) 19 | 20 | Other helpful concepts: 21 | - The `whamm!` [CLI](cli.md) 22 | - [Testing](testing.md) 23 | - [Error Handling](error_handling.md) 24 | -------------------------------------------------------------------------------- /docs/src/devs/parsing.md: -------------------------------------------------------------------------------- 1 | # Phase 1: Parse # 2 | 3 | Here is documentation describing how we _parse_ `.mm` scripts. 4 | 5 | ## The Grammar ## 6 | [whamm.pest] 7 | 8 | `whamm!`'s grammar is written using the [Pest] parser generator Rust library, which uses Parsing Expression Grammars (PEG) as input. 9 | Reading the [Pest] book first will inform how to read the [whamm.pest] grammar. 10 | 11 | Pest parses a passed `.mm` script and creates a set of matched `Rule`s that are then traversed in the [`whamm_parser.rs`] to generate `whamm!`'s Abstract Syntax Tree (AST). 12 | These `Rule`s correspond to the naming used in the `whamm.pest` grammar. 13 | 14 | The logic for creating the AST from the Pest `Rule`s can be followed by starting at the parsing entrypoint: the `parse_script` function found in the [`whamm_parser.rs`] file. 15 | 16 | [whamm.pest]: https://github.com/ejrgilbert/whamm/blob/master/src/parser/whamm.pest 17 | [Pest]: https://pest.rs/book/ 18 | 19 | [`whamm_parser.rs`]: https://github.com/ejrgilbert/whamm/blob/master/src/parser/whamm_parser.rs 20 | 21 | ## The Abstract Syntax Tree (AST) ## 22 | 23 | We use an AST to represent the `.mm` script after parsing. 24 | This AST is leveraged in different ways for each of the subsequent compiler phases. 25 | 26 | During [**verification**](verifying.md), the AST is used to build the `SymbolTable` and perform type checking. 27 | 28 | While [**translating the AST**](translate.md) into the injection strategy's representation, the AST is visited and restructured in a way that is simpler to compile for each strategy. 29 | Each node contains new data unique to each strategy that is helpful while emitting. 30 | 31 | While [**emitting**](emit/emitting.md), the _simpler AST variation_ mentioned above is used to lookup global statements and iterate over probe definitions to inject them into locations-of-interest in the Wasm program. 32 | -------------------------------------------------------------------------------- /docs/src/devs/translate.md: -------------------------------------------------------------------------------- 1 | # Phase 4: AST Translation # 2 | 3 | TODO 4 | -------------------------------------------------------------------------------- /docs/src/examples/branch_monitor.md: -------------------------------------------------------------------------------- 1 | # Branch Monitor # 2 | 3 | Here is an example monitor that can be written in `Whamm!`, it does not require an instrumentation library. 4 | Rather, it uses the DSL to express all of its monitoring logic. 5 | 6 | ``` 7 | wasm::br:before { 8 | report unshared i32 taken; 9 | // branch always taken for `br` 10 | // count stores an array of counters 11 | taken++; 12 | } 13 | 14 | wasm::br_if:before { 15 | report unshared i32 taken; 16 | report unshared i32 not_taken; 17 | 18 | // which branch was taken? 19 | if (arg0 != 0) { // arg0: Wasm top-of-stack 20 | taken++; 21 | } else { 22 | not_taken++; 23 | } 24 | } 25 | 26 | wasm::br_table:before { 27 | report unshared map taken_branches; 28 | 29 | // which branch was taken? 30 | i32 index; 31 | 32 | // arg0: the Wasm top-of-stack 33 | // num_targets: the number of targets for this br_table 34 | // targets: the branches that can be targeted by this br_table 35 | // default_target: the default target for this br_table 36 | index = arg0 < (num_targets - 1) ? targets[arg0] : default_target; 37 | 38 | taken_branches[index]++; 39 | } 40 | ``` 41 | -------------------------------------------------------------------------------- /docs/src/examples/intro.md: -------------------------------------------------------------------------------- 1 | # Examples # 2 | 3 | Here are some documented examples of probes written in the language. 4 | -------------------------------------------------------------------------------- /docs/src/images/anatomy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ejrgilbert/whamm/2bc891519c0c657e591fc75971441d556f1e2223/docs/src/images/anatomy.png -------------------------------------------------------------------------------- /docs/src/images/engine.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ejrgilbert/whamm/2bc891519c0c657e591fc75971441d556f1e2223/docs/src/images/engine.png -------------------------------------------------------------------------------- /docs/src/images/rewriting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ejrgilbert/whamm/2bc891519c0c657e591fc75971441d556f1e2223/docs/src/images/rewriting.png -------------------------------------------------------------------------------- /docs/src/intro/events.md: -------------------------------------------------------------------------------- 1 | # Instrumentable Events # 2 | 3 | Currently available `packages`: 4 | - `wasm:opcode`, e.g. `wasm:opcode:call:alt` 5 | 6 | `Packages` to be added: 7 | - `thread` operation events 8 | - `gc` operation events 9 | - `function` enter/exit/unwind events, e.g. `wasm:fn:enter:before` 10 | - `memory` access (read/write) events 11 | - `table` access (read/write) events 12 | - WASI `component` operation events, e.g. `wasi:http:send_req:alt` 13 | - `wasm:begin`/`wasm:end` events 14 | - `traps` 15 | - `exception` throw/rethrow/catch events 16 | -------------------------------------------------------------------------------- /docs/src/intro/language.md: -------------------------------------------------------------------------------- 1 | # The Language # 2 | 3 | `whamm!` enables tool implementers to express their instrumentation in terms of program _events_ and corresponding _predicated actions_; 4 | "When _this event_ occurs during program execution, do _these actions_ if _this predicate_ (or conditional) evaluates to `true`." 5 | This abstraction provides a high-level and intuitive syntax that can target events at various granularities in the instrumented program. 6 | 7 | Read on for an overview of the syntax and semantics of the language. 8 | 9 | ## Language Concepts ## 10 | - [Variables](syntax/variables.md) are used to store data. 11 | - [Logical operations](syntax/logop.md) can be used to combine boolean expressions. 12 | - [Ternary Expressions](syntax/ternary.md) can be used for succinct conditional variable assignments. 13 | - [Primitive types](syntax/primitives.md) are numbers, booleans, and strings. 14 | - Various [arithmetic](syntax/arith.md) operations can be used with numbers. 15 | - [Strings](syntax/strings.md) are key for dealing with text, etc. 16 | - [Tuples](syntax/tuples.md) allow using multiple values where one value is expected. 17 | - [Maps](syntax/maps.md) are key for storing large amounts of data, but they're implemented quite differently in `whamm!`. 18 | - [Function](syntax/functions.md) definitions can be used to reuse code snippets. 19 | - [Conditionals](syntax/conditionals.md) are if/else/elif statements used for simple control flow 20 | - `Whamm!` also provides helpful features to enable instrumentation expressiveness 21 | - [Report](syntax/report_vars.md) variables are key for flushing the dynamic data collected by instrumentation during an application's run 22 | - [Unshared](syntax/unshared_vars.md) variables are used to create an instance of a variable per probe match-site whose value is retained across site visits 23 | - [Shared](syntax/shared_vars.md) variables are used to create an instance of a variable that is _shared_ by every probe match-site 24 | - And finally, [probes](syntax/probes.md) are used to express instrumentation. 25 | - All of this syntax is used to write `whamm!` [scripts](syntax/scripts.md). 26 | -------------------------------------------------------------------------------- /docs/src/intro/libraries.md: -------------------------------------------------------------------------------- 1 | # Libraries # 2 | 3 | NOTE: This functionality hasn't been fully implemented! More docs to come post-implementation! 4 | 5 | [//]: # (Libraries are used to define instrumentation behavior when it goes beyond the scope of the core DSL grammar.) 6 | 7 | [//]: # () 8 | [//]: # (## How does `whamm!` use libraries? ##) 9 | 10 | [//]: # (TODO) 11 | 12 | [//]: # () 13 | [//]: # (## Provided libraries ##) 14 | 15 | [//]: # (TODO) 16 | 17 | [//]: # () 18 | [//]: # (## Building and using custom libraries ##) 19 | 20 | [//]: # (TODO) 21 | -------------------------------------------------------------------------------- /docs/src/intro/syntax/arith.md: -------------------------------------------------------------------------------- 1 | # Arithmetic # 2 | 3 | Arithmetic is fundamental to computation. 4 | `whamm!` defines a number of arithmetic operators on the primitive types. 5 | 6 | ## Integer types ## 7 | 8 | ``` 9 | i32 a; 10 | a = 0; 11 | a++; // increment == 1 12 | a--; // decrement == 0 13 | a = 9 + 3; // add == 12 14 | a = 8 - 2; // subtract == 6 15 | a = 7 * 4; // multiply == 28 16 | a = 9 / 2; // divide == 4 17 | a = 5 % 3; // modulus == 2 18 | ``` 19 | -------------------------------------------------------------------------------- /docs/src/intro/syntax/conditionals.md: -------------------------------------------------------------------------------- 1 | # Conditionals # 2 | Conditional statements are useful for controlling the way a program executes 3 | 4 | ## Syntax ## 5 | `whamm!` supports 3 different signifiers for conditional statements: 6 | All `if`/`else` blocks must begin with an `if` statement, which is then followed by any number of `elif` statments and either 0 or 1 `else` statments. Finally, the whole chain must be closed with a `;`. 7 | 8 | ### Formal Syntax ### 9 | "if" ~ "(" ~ expr ~ ")" ~ "{" ~ statement* ~ "}" ~ (else | elif) ? ~ ";" 10 | 11 | Where elif is: "elif" ~ "(" ~ expr ~ ")" ~ "{" ~ statement* ~ "}" ~ (else| elif) ? 12 | 13 | And else is: "else" ~ "{" ~ statement* ~ "}" 14 | 15 | ### Examples of Conditional Statements 16 | ``` 17 | i32 a = 5; 18 | if (a == 5) { 19 | a = 3; 20 | }; 21 | ``` 22 | ``` 23 | i32 a = 5; 24 | if (a == 4){ 25 | a = 3; 26 | }elif (a == 3){ 27 | a = 2; 28 | }elif (a == 5){ 29 | a = 1; 30 | }; 31 | ``` 32 | ``` 33 | //This is an example in a function that returns a bool 34 | my_fn (i32 param) -> bool { 35 | return (param/10 == 0); 36 | } 37 | i32 a = 5; 38 | if(my_fn(a)) { 39 | a = 3; 40 | }else{ 41 | a = 2; 42 | }; 43 | ``` 44 | ## Short-circuit evaluation ## 45 | 46 | Conditional expressions will only evaluate the branch corresponding to the value of the condition. 47 | In other words, it short-circuits. 48 | 49 | -------------------------------------------------------------------------------- /docs/src/intro/syntax/logop.md: -------------------------------------------------------------------------------- 1 | # Logical Operators # 2 | 3 | Logical operators allow joining multiple boolean expressions. 4 | Like C/C++ and Java, the `&&` and `||` operators provide for logical-and and logical-or. 5 | Both operators have _short-circuit evaluation_; they only evaluate the right-hand-side expression if the left-hand-side evaluates to `true` or `false`, respectively. 6 | 7 | ``` 8 | bool a; 9 | a = false && false; // == false 10 | a = false && true; // == false 11 | a = true && false; // == false 12 | a = true && true; // == true 13 | ``` 14 | 15 | ``` 16 | bool a; 17 | a = false || false; // == false 18 | a = false || true; // == true 19 | a = true || false; // == true 20 | a = true || true; // == true 21 | ``` 22 | -------------------------------------------------------------------------------- /docs/src/intro/syntax/maps.md: -------------------------------------------------------------------------------- 1 | # Maps # 2 | 3 | `Whamm!` provides maps for storage of key-value pairs. 4 | This is similar to `java`'s `Map` and `python`'s `dict` types. 5 | In fact, it is exactly `Rust`'s `HashMap` type...since `whamm!` leverages this `Rust` type under-the-hood! 6 | If you are interested in how this works, see the Developer's [Core Library](../../devs/core_lib.md) documentation. 7 | 8 | ## Instantiation ## 9 | 10 | ``` 11 | // No need to instantiate a map, it is automatically created as an empty map. 12 | map a; 13 | ``` 14 | 15 | ## Reading and writing elements ## 16 | 17 | Reading and writing elements of maps uses the `[ ... ]` syntax like maps in many other languages. 18 | ``` 19 | map a; 20 | a[0] = 3; // map write 21 | i32 b = a[0]; // map read 22 | 23 | // maps can also contain tuples! 24 | map<(i32, i32, i32), i32> c; 25 | c[(0, 0, 0)] = 3; // map write 26 | i32 b = c[(0, 0, 0)]; // map read 27 | ``` 28 | 29 | ## Bounds and null checks ## 30 | 31 | Accesses of `Whamm!` maps are dynamically checked against the bounds. 32 | 33 | ``` 34 | map a; 35 | i32 b = a[0]; // produces Wasm trap through Rust 36 | ``` 37 | -------------------------------------------------------------------------------- /docs/src/intro/syntax/primitives.md: -------------------------------------------------------------------------------- 1 | # Primitives # 2 | 3 | `whamm!` offers a small set of primitive types that are useful for performing arithmetic and representing data. 4 | 5 | ## Booleans ## 6 | 7 | With only two values, `true`, and `false`, booleans are represented in `whamm!` with the type `bool`. 8 | 9 | ``` 10 | bool x; // default == false 11 | x = true; 12 | x = false; 13 | ``` 14 | 15 | ## Integers ## 16 | 17 | Right now, `whamm!` supports `i32` (_signed_ 32-bit values) and `u32` (_unsigned_ 32-bit values) integers, but will be supporting all numeric types provided by Wasm in the future. 18 | 19 | ``` 20 | // with declared types 21 | i32 d; // default == 0 22 | d = 0; 23 | d = 9993; 24 | d = -42; 25 | ``` 26 | 27 | The minimum decimal value for type `i32` is `-2147483648` (equal to `-2^31`) and the maximum value is `2147483647` (equal to `2^31 - 1`). 28 | 29 | The minimum decimal value for type `u32` is `0` and the maximum value is `4294967295` (equal to `2^32 - 1`). 30 | -------------------------------------------------------------------------------- /docs/src/intro/syntax/report_vars.md: -------------------------------------------------------------------------------- 1 | # `report` Variables # 2 | 3 | The `report` keyword specifies variables whose values should be flushed. 4 | When monitoring an application execution, data describing observations should be stored in a `report` variable to make use of this flushing feature. 5 | 6 | Using `report` is really shorthand for `report unshared`, see [[`unshared`] variable](./unshared_vars.md) documentation. 7 | 8 | The default behavior of this "flush" is to print to the console (the core `Whamm!` library uses WASI to do this). 9 | Currently, this will be done _on each write_ to at least one of the `report` variables; however, there are plans to make this configurable. 10 | 11 | [//]: # (When using bytecode rewriting, this will be done _on each write_ to at least one of the `report` variables.) 12 | [//]: # (When using an engine, this will be done _at the end of program execution_ with the final values of the variables.) 13 | 14 | For example: 15 | ``` 16 | report var count; 17 | wasm:opcode:call:before { 18 | // count the number of times the `call` opcode was used during the application's dynamic execution. 19 | // (a single global count) 20 | count++; 21 | } 22 | ``` 23 | -------------------------------------------------------------------------------- /docs/src/intro/syntax/scripts.md: -------------------------------------------------------------------------------- 1 | # `whamm!` Scripts # 2 | 3 | Instrumentation (aka a monitor) is expressed as a set of predicated probes in a script with the `.mm` extension. 4 | 5 | Here is a high-level view of the grammar for a `whamm!` script: 6 | ``` 7 | // Statements to initialize the global state of the instrumentation 8 | global_statements; 9 | ... 10 | 11 | // Function definitions to reuse code snippets 12 | fn_name(fn_args) -> ret_val { fn_body; ... } 13 | ... 14 | 15 | // An example of what a `probe` would look. 16 | // There can be many of these in a monitor. 17 | provider:package:event:mode / predicate / { 18 | probe_actions; 19 | ... 20 | } 21 | ``` 22 | 23 | ## Instrumenting with the CLI ## 24 | `whamm instr --help` 25 | 26 | The `instr` command provided by the CLI enables developers to actually instrument programs. 27 | -------------------------------------------------------------------------------- /docs/src/intro/syntax/shared_vars.md: -------------------------------------------------------------------------------- 1 | # `shared` Variables # 2 | 3 | NOTE: This functionality hasn't been fully implemented! More docs to come post-implementation! 4 | 5 | If a variable is marked as `shared`, a single instance of this variable is available to _every match site_ for a probe. 6 | The scope of this variable is limited to _all match sites_ of a probe. 7 | The value of this variable will be stable on each entry into the probe's logic, meaning that it will not be reinitialized each time. 8 | 9 | This can be used to collect data for some probed event _over time_. 10 | 11 | For example: 12 | ``` 13 | wasm:opcode:call:before { 14 | // collect the number of times the `call` opcode is executed during dynamic execution. 15 | // (a single count tied to the wasm:opcode:call event in the program) 16 | // This variable will not be reinitialized each time this probe's body is executed, 17 | // rather, it will be the value it was the last time it ran! 18 | shared var count: i32; 19 | count++; 20 | 21 | // This variable will be reinitialized to 0 each time this probe's body is executed 22 | i32 local_variable; 23 | local_variable++; 24 | } 25 | ``` 26 | -------------------------------------------------------------------------------- /docs/src/intro/syntax/strings.md: -------------------------------------------------------------------------------- 1 | # Strings # 2 | 3 | NOTE: This functionality hasn't been fully implemented! More docs to come post-implementation! 4 | 5 | [//]: # (`whamm!` has very basic support for strings; they are injected into the instrumented Wasm program and are represented as the tuple: `(memory_address, length)`.) 6 | 7 | [//]: # (Follows are the strings docs from the Virgil repo that I can customize to this context.) 8 | [//]: # (String literals are translated into arrays of bytes and usable as arrays of bytes in your program. 9 | In fact, the `string` type is just an alias for `Array`. The two types are completely interchangeable.) 10 | 11 | [//]: # () 12 | [//]: # (```) 13 | 14 | [//]: # (var a: string = "";) 15 | 16 | [//]: # (var b: string = "The quick brown fox";) 17 | 18 | [//]: # (var c: string = null;) 19 | 20 | [//]: # (```) 21 | 22 | [//]: # () 23 | [//]: # (## Escapes ##) 24 | 25 | [//]: # () 26 | [//]: # (Strings can use the '\' character to escape some characters, such as carriage return, newline, tab, and quotes within strings.) 27 | 28 | [//]: # () 29 | [//]: # (```) 30 | 31 | [//]: # (// newline, tab, carriage-return, backslash, single-quote and double-quote) 32 | 33 | [//]: # (var a: string = "\n\t\r\\\'\"";) 34 | 35 | [//]: # (```) 36 | 37 | [//]: # (## Strings are arrays ##) 38 | 39 | [//]: # () 40 | [//]: # (Remember that strings are simply arrays of bytes. The individual bytes can be accessed just as a normal byte array, as can the length. Out of bounds accesses cause exceptions as well.) 41 | 42 | [//]: # () 43 | [//]: # (```) 44 | 45 | [//]: # (var a: string = "abcvar";) 46 | 47 | [//]: # (var b: byte = a[0]; // strings are just arrays of bytes) 48 | 49 | [//]: # (```) 50 | 51 | [//]: # () 52 | [//]: # (```) 53 | 54 | [//]: # (def main() {) 55 | 56 | [//]: # ( var a = "abcvar";) 57 | 58 | [//]: # ( var x = a[11]; // produces !BoundsCheckException) 59 | 60 | [//]: # (}) 61 | 62 | [//]: # (```) 63 | -------------------------------------------------------------------------------- /docs/src/intro/syntax/ternary.md: -------------------------------------------------------------------------------- 1 | # Ternary Expressions # 2 | 3 | `whamm!` supports a version of the "conditional" expression that chooses one of two values based on a condition. 4 | The syntax follows C, C++, and Java, which uses `? :`. 5 | 6 | ``` 7 | // with declared types 8 | int a; 9 | a = 1 > 0 ? 16 : 27; // == 16 10 | a = 1 < 0 ? 17 : 29; // == 29 11 | ``` 12 | 13 | ## Short-circuit evaluation ## 14 | 15 | The ternary expression will only evaluate the branch corresponding to the value of the condition. 16 | In other words, it short-circuits. 17 | -------------------------------------------------------------------------------- /docs/src/intro/syntax/tuples.md: -------------------------------------------------------------------------------- 1 | # Tuples # 2 | 3 | NOTE: This functionality hasn't been fully implemented! More docs to come post-implementation! 4 | 5 | [//]: # (Tuples provide a quick and easy way to combine one or more values into a composite value.) 6 | 7 | [//]: # () 8 | [//]: # (```) 9 | 10 | [//]: # ((i32, i32) a;) 11 | 12 | [//]: # (a = (0, 1);) 13 | 14 | [//]: # () 15 | [//]: # ((bool, i32) b;) 16 | 17 | [//]: # (b = (true, 78);) 18 | 19 | [//]: # (```) 20 | 21 | [//]: # () 22 | [//]: # (## Member access ##) 23 | 24 | [//]: # () 25 | [//]: # (Tuple elements can be accessed as if they were fields of the tuple value.) 26 | 27 | [//]: # (Instead of field names, the elements are named as integer literals, starting with `0`.) 28 | 29 | [//]: # () 30 | [//]: # (```) 31 | 32 | [//]: # (// tuple members are accessed with '.' and numbered from 0) 33 | 34 | [//]: # ((bool, i32) a;) 35 | 36 | [//]: # (a = (true, 1);) 37 | 38 | [//]: # () 39 | [//]: # (bool b;) 40 | 41 | [//]: # (b = a.0; // == true) 42 | 43 | [//]: # () 44 | [//]: # (i32 c;) 45 | 46 | [//]: # (c = a.1; // == 1) 47 | 48 | [//]: # () 49 | [//]: # ((i32, (i32, i32)) d;) 50 | 51 | [//]: # (d = (1, (12, 13));) 52 | 53 | [//]: # (i32 e;) 54 | 55 | [//]: # (e = d.1.0; // == 12) 56 | 57 | [//]: # (```) 58 | -------------------------------------------------------------------------------- /docs/src/intro/syntax/unshared_vars.md: -------------------------------------------------------------------------------- 1 | # `unshared` Variables # 2 | 3 | If a variable is marked as `unshared`, an instance of this variable is made available to _every match site_ for a probe. 4 | The scope of this variable is limited to the specific _match site_. 5 | The value of this variable will be stable on each entry into the probe's logic, meaning that it will not be reinitialized each time. 6 | 7 | This can be used to collect data at a specific program point _over time_. 8 | 9 | For example: 10 | ``` 11 | wasm:opcode:call:before { 12 | // collect the number of times each `call` opcode is executed during dynamic execution. 13 | // (as many counts as there are `call` opcodes in the program) 14 | // This variable will not be reinitialized each time this probe's body is executed, 15 | // rather, it will be the value it was the last time it ran! 16 | unshared var count: i32; 17 | count++; 18 | 19 | // This variable will be reinitialized to 0 each time this probe's body is executed 20 | i32 local_variable; 21 | local_variable++; 22 | } 23 | ``` 24 | -------------------------------------------------------------------------------- /docs/src/intro/syntax/variables.md: -------------------------------------------------------------------------------- 1 | # Variables # 2 | 3 | Variables store data, such as numbers and strings. 4 | 5 | ``` 6 | // Declaring a new variable ` ;`: 7 | i32 i; 8 | ``` 9 | 10 | ``` 11 | // Assigning a value to a variable ` = ;`: 12 | i = 0; 13 | 14 | // Variables can also be set to the result of an expression ` = ;`: 15 | i = 1 + 2; 16 | i = add(1, 2) + 9; // (assuming that the `add` fn is in scope and returns an `i32`) 17 | ``` 18 | 19 | ## Scopes ## 20 | 21 | Each variable is associated with some _scope_, which is the range of the program in which it is active and accessible. 22 | We will see how there are scopes tied to [functions](functions.md), [probes](probes.md), and [scripts](scripts.md). 23 | The syntax for declaring and assigning to variables is consistent across these contexts. 24 | -------------------------------------------------------------------------------- /docs/src/intro/testing.md: -------------------------------------------------------------------------------- 1 | # Testing Your Instrumentation # 2 | 3 | NOTE: This functionality hasn't been fully implemented! More docs to come post-implementation! 4 | This is a **future research goal** of ours. 5 | -------------------------------------------------------------------------------- /ideas/events.md: -------------------------------------------------------------------------------- 1 | - [ ] Function entry/exit/unwind, e.g. wasm:fn:enter:before 2 | - [ ] wasm:pc: 3 | - [ ] wasm:fid: 4 | - [ ] thread operation events 5 | - [ ] gc operation events 6 | - [ ] memory access (read/write) events 7 | - [ ] table access (read/write) events 8 | - [ ] WASI component operation events, e.g. wasi:http:send_req:alt 9 | - [ ] wasm:begin/wasm:end events 10 | - [ ] traps 11 | - [ ] exception throw/rethrow/catch events 12 | -------------------------------------------------------------------------------- /ideas/frame_vars.md: -------------------------------------------------------------------------------- 1 | # Frame Variables # 2 | 3 | Consider the following Whamm script: 4 | ``` 5 | map total_time; 6 | i32 enter_time; // NEW IDEA: `frame i32 enter_time;` 7 | 8 | wasm:func:entry { 9 | enter_time = clock(); 10 | } 11 | 12 | wasm:func:exit { 13 | total_time[fid] += (clock() - enter_time); 14 | } 15 | ``` 16 | 17 | This actually wouldn't work correctly for recursive functions since the `total_time` is dependent on global state. 18 | This also wouldn't work using a local variable inside a probe body since it wouldn't be accessible by another probe... 19 | 20 | Thus enter `frame` variables. 21 | This type of variable actually attaches its scope to the function that an event matches. 22 | Meaning, that for all probe bodies executing inside a specific function, they all have access to that function's `frame` variables. 23 | The implementation for bytecode rewriting would be straightforward since it can just be a Wasm `local` variable. 24 | However, the implementation in Wizard would be a bit more complex since we would need a new datastructure to store the state that hangs off a function. 25 | 26 | Another example: 27 | ``` 28 | wasm:func:entry { 29 | frame var start: u32; 30 | start = time.now(); 31 | } 32 | wasm:func:exit { 33 | frame var start: u32; 34 | report var profiles: vec; 35 | profiles.push(time.now() - start); 36 | } 37 | ``` 38 | -------------------------------------------------------------------------------- /ideas/front-end-configurability.md: -------------------------------------------------------------------------------- 1 | # Front-End Configurability # 2 | 3 | It would be nice to be able to configure the front end of the compiler easily (could support wizeng interface smoothly this way with no other changes). 4 | 5 | ```bash 6 | whamm --provider provider.txt 7 | ``` 8 | 9 | Where `provider.txt`: 10 | ```text 11 | linux:syscall:open(path: u32, mode:u32) 12 | linux:syscall:read(static pid: u32) 13 | 14 | ... 15 | ``` 16 | 17 | There would need to be a way to define **variables** that are: 18 | - static 19 | - dynamic 20 | - at what point they're supplied 21 | 22 | There would need to be a way to define **functions** that are: 23 | - static 24 | - dynamic 25 | - at what point they're supplied -------------------------------------------------------------------------------- /ideas/monitors.md: -------------------------------------------------------------------------------- 1 | # Monitors TODO # 2 | 3 | - [ ] GRP 4 | - [ ] path profiling 5 | - [ ] call stack 6 | - [ ] calls: Tallies direct and indirect calls. 7 | - [ ] blocks: Tallies basic block counts per function. 8 | - [ ] breakpoints: Triggers an external debugger (e.g. gdb) at specified points. 9 | - [ ] const: Tracks constants in various places in the program. 10 | - [ ] control: Tallies execution counts and shows a control-flow graph. 11 | - [ ] coverage: Tallies instruction and basic block coverage. 12 | - [ ] debug: An interactive synchronous debugger with breakpoints and stepping. 13 | - [ ] fprofile: Reports execution time spent in individual functions. 14 | - [ ] globals: Tallies reads and writes to Wasm globals. 15 | - [ ] icount: Tallies instruction counts per function. 16 | - [ ] loops: Tallies counts of loops. 17 | - [ ] memstats: Tallies stats on memory accesses. 18 | - [ ] opcodes: Tallies static and dynamic counts of each Wasm opcode. 19 | - [ ] profile: Reports execution time for entire calling context trees. 20 | - [ ] profile_bytecode: Recovers source level information from bytecode execution 21 | - [ ] r3: Generates a reduced set of event traces for wasm r3 replay module creation. 22 | - [ ] r3-replay: Replays a module from an R3 trace file. 23 | - [ ] timeout: Enforces a limit on the number of instructions executed. 24 | - [ ] tracepoints: Traces value stack at given points. 25 | - [x] branches: Tallies direct and indirect branches. 26 | - [x] hotness: Tallies "hot" execution path counts. 27 | - [x] icount: Tallies the total number of instructions that ran during program execution. 28 | - [x] cache simulator: Simulates a cache lookup per memory operation 29 | - [x] imix: classifies each Wasm instruction and outputs a trace of instruction classes for offline analysis. 30 | -------------------------------------------------------------------------------- /ideas/querying_state.md: -------------------------------------------------------------------------------- 1 | # How to get state while an application is running? # 2 | 3 | Answer: Adding query capabilities to the system API (could be the answer to bytecode rewriting as well). 4 | 5 | Example: 6 | ```webassembly 7 | (module 8 | ;; Call this function any time this specific syscall occurs 9 | ;; (for instrumenting wasm running in the kernel) 10 | (export "linux:syscall:open" (func 0)) 11 | 12 | ;; Hook up this call to the VM with some query string 13 | ;; to be handled by this function (gives monitor status 14 | ;; before wasm:exit) 15 | (export "query:foobar" (func 3)) 16 | 17 | ;; Hook up this call to the VM to render some visualization 18 | ;; of monitor state (maybe interesting to do with Wasm threads?) 19 | ;; may also be better to just have external visualization app 20 | ;; do this that queries the "query:foobar" above. 21 | (export "render@fps" (func 4)) 22 | 23 | ;; normal instrumentation capabilities: 24 | (export "wasm:opcode:..." (func 1)) 25 | (export "wasm:exit" (func 2)) 26 | ) 27 | ``` -------------------------------------------------------------------------------- /ideas/system_api.md: -------------------------------------------------------------------------------- 1 | # System API # 2 | 3 | ## Reflection 4 | 5 | Since the engine will already need to decode the module bytes, we can ask it to provide some information about the module OR have it pass bytes for a specific item. 6 | The `Whamm` module can then decode this subset of the application using its own library provided as a linked module. 7 | This would simplify the instrumentation module and make it quite readable by splitting out the bytecode decoding into a library. 8 | 9 | ``` 10 | get_num_funcs(); 11 | get_num_globals(); 12 | get_num_memories(); 13 | get_num_...(); 14 | get_memory_size(mid: i32); 15 | get_func_name(fid: i32) -> (start: i32, end: i32); 16 | get_func_code(fid: i32, region: (i32, i32)) -> (start: i32, end: i32); 17 | 18 | // places declarations/signatures in my memory to decode 19 | get_mem_decl(mid: i32) -> (start: i32, end: i32) 20 | get_global_decl(gid: i32) -> (start: i32, end: i32) 21 | get_..._decl(...) -> (start: i32, end: i32) 22 | get_func_sig(fid: i32) -> tid: i32 23 | get_type_def(tid: i32) -> (start: i32, end: i32) 24 | ``` 25 | 26 | ## Get state ## 27 | Call these to get some state from the application module. 28 | They will basically create a _wormhole_ into the application to be called when needed. 29 | They can be used in bytecode-level or VM-level probe callbacks. 30 | 31 | ``` 32 | // use this to get values of global data 33 | add_func(sig:i32,(start:i32, end:i32)) -> (funcref) 34 | 35 | // use these to get access to specific global data 36 | // (keeps from having to add_func for each of these) 37 | global_accessor(gid:i32) -> funcref 38 | memory_accessor(mid:i32) -> funcref: ((offset:i32) -> value:i32) 39 | ..._accessor(...) -> funcref 40 | ``` 41 | 42 | ## Dynamically Add/Remove Probes ## 43 | The API to dynamically add and remove probes from the co-module. 44 | 45 | ``` 46 | // BASE CASE 47 | // uses standardized API for FrameAccessor (passed to callback) 48 | insert_probe(fid:i32,pc:i32,funcref) 49 | remove_probe(fid:i32,pc:i32,funcref) 50 | 51 | // OPTIMIZED CASE (one of the two following options) 52 | insert_whamm_probe_with_args(fid:i32,pc:i32,funcref,vec) 53 | // passes wasm bytes that execute as a trampoline (constructs the args), callback MUST RETURN requested argN 54 | // can consume all or none of the arguments 55 | // can also use custom opcodes for stack manipulation (dup, swap) to manage argument passing 56 | insert_whamm_probe_with_trampoline(fid:i32,pc:i32,funcref,(start:i32,end:i32)) 57 | ``` 58 | -------------------------------------------------------------------------------- /ideas/wizard-target.md: -------------------------------------------------------------------------------- 1 | # The Wizard Target ([#54](https://github.com/ejrgilbert/whamm/issues/54)) # 2 | 3 | Keeping track of the basic functionality to add. 4 | - [ ] split out dynamic and static parts of the predicate 5 | - [ ] `special_decl_init` needs to do something different (the assignment needs to happen a SINGLE time, probably in something like the `global_map_init` function) 6 | 7 | Now, making it nice/fast/AWESOME: 8 | - [ ] Predicate optimizations, [#163](https://github.com/ejrgilbert/whamm/issues/163) 9 | - [ ] System API, [#137](https://github.com/ejrgilbert/whamm/issues/137) 10 | - [ ] Reflection 11 | - [ ] Dynamic match re-evaluation 12 | -------------------------------------------------------------------------------- /providers/packages/wasm:begin.yaml: -------------------------------------------------------------------------------- 1 | # ==================== 2 | # ==== wasm:begin ==== 3 | # ==================== 4 | 5 | begin: &begin 6 | name: begin 7 | docs: Executes on wasm startup. 8 | bound_vars: [] 9 | bound_fns: [] 10 | events: [] 11 | -------------------------------------------------------------------------------- /providers/packages/wasm:end.yaml: -------------------------------------------------------------------------------- 1 | # ==================== 2 | # ==== wasm:end ==== 3 | # ==================== 4 | 5 | wasm_end: &wasm_end 6 | name: end 7 | docs: Executes on wasm termination. 8 | bound_vars: [] 9 | bound_fns: [] 10 | events: [] 11 | -------------------------------------------------------------------------------- /providers/wasm.yaml: -------------------------------------------------------------------------------- 1 | providers: 2 | - name: wasm 3 | docs: This provides various events to instrument that are specific to WebAssembly. 4 | bound_vars: 5 | - name: fid 6 | type: u32 7 | derived_from: null 8 | lifetime: static 9 | docs: The ID of the function the probe is located in (zero-based indexing). 10 | - name: pc 11 | type: u32 12 | derived_from: null 13 | lifetime: static 14 | docs: The instruction offset of the probe within the function (zero-based indexing). 15 | - name: fname 16 | type: str 17 | derived_from: null 18 | lifetime: static 19 | docs: The name of the function the probe is located in. Empty string if not defined. 20 | bound_fns: [] 21 | packages: 22 | - *begin 23 | - *wasm_end 24 | - *opcode 25 | -------------------------------------------------------------------------------- /rust-toolchain.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | channel = "1.82.0" 3 | components = ["rustc", "cargo", "rustfmt", "clippy"] -------------------------------------------------------------------------------- /src/common.rs: -------------------------------------------------------------------------------- 1 | pub mod error; 2 | pub mod instr; 3 | pub mod metrics; 4 | pub mod terminal; 5 | -------------------------------------------------------------------------------- /src/common/metrics.rs: -------------------------------------------------------------------------------- 1 | use std::collections::HashMap; 2 | use std::time::{Duration, SystemTime}; 3 | 4 | #[derive(Default)] 5 | pub struct Metrics { 6 | profiles: HashMap, 7 | } 8 | impl Metrics { 9 | pub fn start(&mut self, name: &str) { 10 | self.profiles.insert(name.to_owned(), Profile::start()); 11 | } 12 | pub fn end(&mut self, name: &str) { 13 | if let Some(prof) = self.profiles.get_mut(name) { 14 | prof.end(); 15 | } else { 16 | panic!("Unknown profile: {name}"); 17 | } 18 | } 19 | pub fn flush(&self) { 20 | for (metric_name, prof) in &self.profiles { 21 | print!("{metric_name}\t: "); 22 | println!("{:?}", prof.elapsed()) 23 | } 24 | } 25 | } 26 | 27 | #[derive(Default)] 28 | struct Profile { 29 | start: Option, 30 | end: Option, 31 | } 32 | impl Profile { 33 | pub(crate) fn start() -> Self { 34 | Self { 35 | start: Some(SystemTime::now()), 36 | end: None, 37 | } 38 | } 39 | pub(crate) fn end(&mut self) { 40 | self.end = Some(SystemTime::now()); 41 | } 42 | pub(crate) fn elapsed(&self) -> Duration { 43 | if let (Some(start), Some(end)) = (self.start, self.end) { 44 | match end.duration_since(start) { 45 | Ok(dur) => dur, 46 | Err(e) => panic!("Could not count duration of system time: {:?}", e), 47 | } 48 | } else { 49 | panic!("must have start and end times") 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/common/terminal.rs: -------------------------------------------------------------------------------- 1 | use std::io::Write; 2 | use termcolor::{Buffer, Color, ColorSpec, WriteColor}; 3 | 4 | // =========================== 5 | // = Terminal Printing Logic = 6 | // =========================== 7 | 8 | const WRITE_ERR: &str = "Uh oh, something went wrong while printing to terminal"; 9 | 10 | pub fn color(s: String, buffer: &mut Buffer, bold: bool, italics: bool, c: Color) { 11 | buffer 12 | .set_color( 13 | ColorSpec::new() 14 | .set_bold(bold) 15 | .set_italic(italics) 16 | .set_fg(Some(c)), 17 | ) 18 | .expect(WRITE_ERR); 19 | write!(buffer, "{}", s.as_str()).expect(WRITE_ERR); 20 | } 21 | 22 | pub fn black(bold: bool, s: String, buffer: &mut Buffer) { 23 | color(s, buffer, bold, false, Color::Black) 24 | } 25 | pub fn blue(bold: bool, s: String, buffer: &mut Buffer) { 26 | color(s, buffer, bold, false, Color::Blue) 27 | } 28 | pub fn cyan(bold: bool, s: String, buffer: &mut Buffer) { 29 | color(s, buffer, bold, false, Color::Cyan) 30 | } 31 | pub fn green(bold: bool, s: String, buffer: &mut Buffer) { 32 | color(s, buffer, bold, false, Color::Green) 33 | } 34 | pub fn magenta(bold: bool, s: String, buffer: &mut Buffer) { 35 | color(s, buffer, bold, false, Color::Magenta) 36 | } 37 | pub fn magenta_italics(bold: bool, s: String, buffer: &mut Buffer) { 38 | color(s, buffer, bold, true, Color::Magenta) 39 | } 40 | pub fn red(bold: bool, s: String, buffer: &mut Buffer) { 41 | color(s, buffer, bold, false, Color::Red) 42 | } 43 | pub fn white(bold: bool, s: String, buffer: &mut Buffer) { 44 | color(s, buffer, bold, false, Color::Rgb(193, 193, 193)) 45 | } 46 | pub fn grey(bold: bool, s: String, buffer: &mut Buffer) { 47 | color(s, buffer, bold, false, Color::White) 48 | } 49 | pub fn grey_italics(bold: bool, s: String, buffer: &mut Buffer) { 50 | color(s, buffer, bold, true, Color::White) 51 | } 52 | pub fn yellow(bold: bool, s: String, buffer: &mut Buffer) { 53 | color(s, buffer, bold, false, Color::Yellow) 54 | } 55 | pub fn long_line(buffer: &mut Buffer) { 56 | let s = "--".repeat(50); 57 | color(s, buffer, false, false, Color::White); 58 | } 59 | -------------------------------------------------------------------------------- /src/emitter/mod.rs: -------------------------------------------------------------------------------- 1 | #![allow(clippy::too_many_arguments)] 2 | mod locals_tracker; 3 | pub mod memory_allocator; 4 | pub mod module_emitter; 5 | pub mod rewriting; 6 | #[cfg(test)] 7 | pub mod tests; 8 | pub mod utils; 9 | 10 | use crate::common::error::ErrorGen; 11 | use crate::emitter::memory_allocator::MemoryAllocator; 12 | use crate::emitter::rewriting::rules::Arg; 13 | use crate::lang_features::alloc_vars::rewriting::UnsharedVarHandler; 14 | use crate::lang_features::libraries::core::io::io_adapter::IOAdapter; 15 | use crate::lang_features::libraries::core::maps::map_adapter::MapLibAdapter; 16 | use crate::lang_features::report_vars::{Metadata, ReportVars}; 17 | use crate::parser::types::{Block, Expr, Statement}; 18 | use orca_wasm::ir::function::FunctionBuilder; 19 | use orca_wasm::Module; 20 | 21 | #[derive(Copy, Clone)] 22 | pub enum InjectStrategy { 23 | Wizard, 24 | Rewriting, 25 | } 26 | 27 | // ================================================= 28 | // ==== Emitter Trait --> Used By All Emitters! ==== 29 | // ================================================= 30 | 31 | pub trait Emitter { 32 | fn reset_locals_for_probe(&mut self); 33 | fn reset_locals_for_function(&mut self); 34 | fn emit_body(&mut self, curr_instr_args: &[Arg], body: &mut Block, err: &mut ErrorGen) -> bool; 35 | fn emit_stmt( 36 | &mut self, 37 | curr_instr_args: &[Arg], 38 | stmt: &mut Statement, 39 | err: &mut ErrorGen, 40 | ) -> bool; 41 | fn emit_expr(&mut self, expr: &mut Expr, err: &mut ErrorGen) -> bool; 42 | } 43 | 44 | /// This should run AFTER emitting the full AST 45 | pub fn configure_flush_routines( 46 | wasm: &mut Module, 47 | var_handler: &mut UnsharedVarHandler, 48 | report_vars: &mut ReportVars, 49 | map_lib_adapter: &mut MapLibAdapter, 50 | mem_allocator: &mut MemoryAllocator, 51 | io_adapter: &mut IOAdapter, 52 | err: &mut ErrorGen, 53 | ) -> Option { 54 | // at this point, I want to use the collected metadata in UnsharedVars 55 | // to generate a new data segment AND generate the necessary globals! 56 | if report_vars.variable_metadata.is_empty() && report_vars.all_used_report_dts.is_empty() { 57 | return None; 58 | } 59 | 60 | let mut flush_reports = FunctionBuilder::new(&[], &[]); 61 | 62 | // call the report_vars to emit calls to all report var flushers 63 | let (header_addr, header_len) = Metadata::setup_csv_header(wasm, mem_allocator); 64 | let var_meta = report_vars.setup_flush_data_segments(wasm, mem_allocator); 65 | 66 | let trackers = var_handler.setup_module(wasm); 67 | report_vars.configure_trackers(trackers); 68 | report_vars.emit_flush_logic( 69 | &mut flush_reports, 70 | &var_meta, 71 | mem_allocator, 72 | io_adapter, 73 | map_lib_adapter, 74 | (header_addr, header_len), 75 | var_handler.get_mem_id(), 76 | wasm, 77 | err, 78 | ); 79 | 80 | let on_exit = flush_reports.finish_module(wasm); 81 | wasm.set_fn_name(on_exit, "flush_reports".to_string()); 82 | 83 | Some(*on_exit) 84 | } 85 | -------------------------------------------------------------------------------- /src/emitter/rewriting/mod.rs: -------------------------------------------------------------------------------- 1 | #![allow(clippy::too_many_arguments)] 2 | pub mod rules; 3 | pub mod visiting_emitter; 4 | -------------------------------------------------------------------------------- /src/emitter/tests.rs: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/generator/rewriting/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod init_generator; 2 | pub mod instr_generator; 3 | pub mod simple_ast; 4 | -------------------------------------------------------------------------------- /src/lang_features/alloc_vars/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod rewriting; 2 | pub mod wizard; 3 | -------------------------------------------------------------------------------- /src/lang_features/libraries/actions.rs: -------------------------------------------------------------------------------- 1 | use crate::common::error::ErrorGen; 2 | use crate::common::instr::LibraryLinkStrategy; 3 | use crate::emitter::memory_allocator::MemoryAllocator; 4 | use crate::generator::ast::Script; 5 | use crate::lang_features::libraries::core::LibPackage; 6 | use crate::verifier::types::SymbolTable; 7 | use orca_wasm::ir::id::FunctionID; 8 | use orca_wasm::Module; 9 | use std::collections::{HashMap, HashSet}; 10 | 11 | pub fn link_core_lib( 12 | method: LibraryLinkStrategy, 13 | ast: &[Script], 14 | app_wasm: &mut Module, 15 | core_wasm_path: &str, 16 | mem_allocator: &mut MemoryAllocator, 17 | packages: &mut [&mut dyn LibPackage], 18 | err: &mut ErrorGen, 19 | ) -> Vec { 20 | match method { 21 | LibraryLinkStrategy::Imported => { 22 | crate::lang_features::libraries::linking::import_lib::link_core_lib( 23 | ast, 24 | app_wasm, 25 | core_wasm_path, 26 | mem_allocator, 27 | packages, 28 | err, 29 | ) 30 | } 31 | LibraryLinkStrategy::Merged => { 32 | unimplemented!("Have not implemented support for merging core library code."); 33 | } 34 | } 35 | } 36 | 37 | pub fn link_user_libs( 38 | method: LibraryLinkStrategy, 39 | app_wasm: &mut Module, 40 | used_user_lib_fns: &HashSet<(String, String)>, 41 | user_lib_modules: &HashMap, 42 | table: &mut SymbolTable, 43 | err: &mut ErrorGen, 44 | ) -> Vec { 45 | match method { 46 | LibraryLinkStrategy::Imported => { 47 | // Link the user libs 48 | let mut used_fns_per_lib: HashMap> = HashMap::default(); 49 | for (used_lib, used_fn) in used_user_lib_fns.iter() { 50 | used_fns_per_lib 51 | .entry(used_lib.clone()) 52 | .and_modify(|set| { 53 | set.insert(used_fn.clone()); 54 | }) 55 | .or_insert(HashSet::from_iter([used_fn.clone()].iter().cloned())); 56 | } 57 | 58 | let mut added_funcs = vec![]; 59 | for (used_lib, lib_fns) in used_fns_per_lib.iter() { 60 | let Some(lib_wasm) = user_lib_modules.get(used_lib) else { 61 | panic!("Could not find wasm module for library '{used_lib}'"); 62 | }; 63 | added_funcs.extend( 64 | crate::lang_features::libraries::linking::import_lib::link_user_lib( 65 | app_wasm, 66 | lib_wasm, 67 | used_lib.clone(), 68 | lib_fns, 69 | table, 70 | err, 71 | ), 72 | ); 73 | } 74 | added_funcs 75 | } 76 | LibraryLinkStrategy::Merged => { 77 | unimplemented!("Have not implemented support for merging user library code."); 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/lang_features/libraries/core/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod io; 2 | pub mod maps; 3 | 4 | use crate::common::error::ErrorGen; 5 | use crate::generator::ast::AstVisitor; 6 | use orca_wasm::ir::id::FunctionID; 7 | use orca_wasm::Module; 8 | use std::collections::HashMap; 9 | 10 | pub const WHAMM_CORE_LIB_NAME: &str = "whamm_core"; 11 | pub const WHAMM_CORE_LIB_MEM_NAME: &str = "memory"; 12 | const UNEXPECTED_ERR_MSG: &str = 13 | "Adapter: Looks like you've found a bug...please report this behavior! Exiting now..."; 14 | 15 | // A lib package needs to be able to visit the AST and determine if it's needed (should be linked) 16 | pub trait LibPackage: AstVisitor { 17 | fn is_used(&self) -> bool; 18 | fn is_used_in_global_scope(&self) -> bool; 19 | fn import_memory(&self) -> bool; 20 | fn set_lib_mem_id(&mut self, mem_id: i32); 21 | fn set_instr_mem_id(&mut self, mem_id: i32); 22 | fn get_fn_names(&self) -> Vec; 23 | fn add_fid_to_adapter(&mut self, fname: &str, fid: u32); 24 | fn set_adapter_usage(&mut self, is_used: bool); 25 | fn set_global_adapter_usage(&mut self, is_used: bool); 26 | fn define_helper_funcs(&mut self, app_wasm: &mut Module, err: &mut ErrorGen) 27 | -> Vec; 28 | } 29 | pub trait LibAdapter { 30 | fn get_funcs(&self) -> &HashMap; 31 | fn get_funcs_mut(&mut self) -> &mut HashMap; 32 | fn define_helper_funcs(&mut self, app_wasm: &mut Module, err: &mut ErrorGen) 33 | -> Vec; 34 | fn get_fn_names(&self) -> Vec { 35 | self.get_funcs().keys().cloned().collect() 36 | } 37 | fn get_fid(&self, fname: &str, err: &mut ErrorGen) -> u32 { 38 | if let Some(fid) = self.get_funcs().get(fname) { 39 | *fid 40 | } else { 41 | err.unexpected_error( 42 | true, 43 | Some(format!( 44 | "{UNEXPECTED_ERR_MSG} Could not find expected configured library function: {fname}" 45 | )), 46 | None, 47 | ); 48 | 0 49 | } 50 | } 51 | 52 | fn add_fid(&mut self, fname: &str, fid: u32) { 53 | self.get_funcs_mut().insert(fname.to_string(), fid); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/lang_features/libraries/linking/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod import_lib; 2 | -------------------------------------------------------------------------------- /src/lang_features/libraries/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod actions; 2 | pub(crate) mod core; 3 | pub mod linking; 4 | -------------------------------------------------------------------------------- /src/lang_features/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod alloc_vars; 2 | pub mod libraries; 3 | pub mod report_vars; 4 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod common; 2 | pub mod emitter; 3 | pub mod generator; 4 | pub mod lang_features; 5 | pub mod parser; 6 | pub mod verifier; 7 | pub mod wast; 8 | 9 | pub(crate) mod cli; 10 | -------------------------------------------------------------------------------- /src/parser.rs: -------------------------------------------------------------------------------- 1 | pub mod provider_handler; 2 | #[cfg(test)] 3 | pub mod tests; 4 | pub mod types; 5 | pub mod whamm_parser; 6 | -------------------------------------------------------------------------------- /src/parser/tests.rs: -------------------------------------------------------------------------------- 1 | use crate::common::error::ErrorGen; 2 | use crate::parser::types::Whamm; 3 | use crate::parser::whamm_parser::parse_script; 4 | use log::{error, info}; 5 | 6 | pub mod numerics; 7 | pub mod whamm_scripts; 8 | 9 | pub fn setup_logger() { 10 | let _ = env_logger::builder().is_test(true).try_init(); 11 | } 12 | 13 | pub fn get_ast(script: &str, err: &mut ErrorGen) -> Whamm { 14 | info!("Getting the AST"); 15 | match parse_script("./", &script.to_string(), err) { 16 | Some(ast) => { 17 | // print_ast(&ast); 18 | ast 19 | } 20 | None => { 21 | error!("Could not get ast from script: {}", script); 22 | if err.has_errors { 23 | err.report(); 24 | } 25 | assert!(!err.has_errors); 26 | panic!(); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/verifier.rs: -------------------------------------------------------------------------------- 1 | pub mod builder_visitor; 2 | pub mod types; 3 | #[allow(clippy::module_inception)] 4 | // TODO: rename this 5 | pub mod verifier; 6 | 7 | #[cfg(test)] 8 | pub mod tests; 9 | -------------------------------------------------------------------------------- /src/wast.rs: -------------------------------------------------------------------------------- 1 | pub mod test_harness; 2 | -------------------------------------------------------------------------------- /tests/apps/core_suite/clang/malloc_init.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ejrgilbert/whamm/2bc891519c0c657e591fc75971441d556f1e2223/tests/apps/core_suite/clang/malloc_init.wasm -------------------------------------------------------------------------------- /tests/apps/core_suite/handwritten/add.wasm: -------------------------------------------------------------------------------- 1 | asm 2 | `` 3 |   -------------------------------------------------------------------------------- /tests/apps/core_suite/handwritten/add.wat: -------------------------------------------------------------------------------- 1 | (module 2 | (type (;0;) (func)) 3 | (type (;1;) (func (param i32 i32) (result i32))) 4 | (func (;0;) (type 0)) 5 | (func (;1;) (type 0) 6 | call 0 7 | call 0 8 | call 0 9 | ) 10 | (start 1) 11 | (memory (;0;) 1) 12 | ) -------------------------------------------------------------------------------- /tests/apps/core_suite/handwritten/basic.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ejrgilbert/whamm/2bc891519c0c657e591fc75971441d556f1e2223/tests/apps/core_suite/handwritten/basic.wasm -------------------------------------------------------------------------------- /tests/apps/core_suite/handwritten/basic.wat: -------------------------------------------------------------------------------- 1 | (module 2 | (type (;0;) (func (param i32 i32))) 3 | (type (;1;) (func (param i32 i32 i32 i32 i32 i32 i32 i32))) 4 | (type (;2;) (func (result i32))) 5 | (import "ic0" "debug_print" (func $_ZN3ic03ic011debug_print17h185bba3b3a7fc989E (type 0))) 6 | (import "ic0" "call_new" (func $_ZN3ic03ic08call_new17h9ec0b706f1330e5bE (type 1))) 7 | 8 | (func $should_not_instrument 9 | i32.const 0 10 | i32.const 0 11 | i32.const 0 12 | i32.const 0 13 | i32.const 0 14 | i32.const 0 15 | i32.const 0 16 | i32.const 0 17 | call $_ZN3ic03ic08call_new17h9ec0b706f1330e5bE 18 | ) 19 | 20 | (func $should 21 | i32.const 0 22 | i32.const 0 23 | call $_ZN3ic03ic011debug_print17h185bba3b3a7fc989E 24 | ) 25 | 26 | (func $inject_synchronous_fault (type 2) (result i32) 27 | i32.const 1647358 28 | i32.const 51 29 | call $_ZN3ic03ic011debug_print17h185bba3b3a7fc989E 30 | i32.const -1 31 | ) 32 | 33 | (func $instr_redirect_to_fault_injector (type 1) 34 | i32.const 0 35 | drop 36 | ) 37 | 38 | (func $main (export "main") 39 | call $should_not_instrument 40 | call $should 41 | call $inject_synchronous_fault 42 | drop 43 | ) 44 | 45 | (memory (export "memory") 1) 46 | ) -------------------------------------------------------------------------------- /tests/apps/core_suite/handwritten/branches-no-br_table.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ejrgilbert/whamm/2bc891519c0c657e591fc75971441d556f1e2223/tests/apps/core_suite/handwritten/branches-no-br_table.wasm -------------------------------------------------------------------------------- /tests/apps/core_suite/handwritten/branches-no-br_table.wat: -------------------------------------------------------------------------------- 1 | 2 | (module 3 | ;; Globals 4 | (global $var0 (mut i32) (i32.const 0)) 5 | (global $var1 (mut i32) (i32.const 0)) 6 | 7 | ;; Test case functions 8 | (func $basic_br (param i32) (result i32) 9 | block $eq 10 | block $neq 11 | (i32.eq (local.get 0) (i32.const 1)) 12 | br_if $eq 13 | br $neq 14 | end 15 | ;; they are not equal, return '0' 16 | i32.const 0 17 | return 18 | end 19 | ;; they are equal, return '1' 20 | i32.const 1 21 | return 22 | ) 23 | (func $more_nesting (param i32) (result i32) 24 | block $gt 25 | block $neq 26 | block $eq 27 | (i32.eq (local.get 0) (i32.const 0)) 28 | br_if $eq 29 | 30 | (i32.gt_u (local.get 0) (i32.const 2)) 31 | br_if $gt 32 | 33 | br $neq 34 | end 35 | ;; they are equal, return '1' 36 | i32.const 1 37 | return 38 | end 39 | ;; they are not equal, return '0' 40 | i32.const 0 41 | return 42 | end 43 | ;; param is greater than 2, return 2 44 | i32.const 2 45 | return 46 | ) 47 | (func $if_stmt (param i32) (result i32) 48 | (if (i32.eq (local.get 0) (i32.const 1)) 49 | (then 50 | ;; they are equal, return '1' 51 | i32.const 1 52 | return 53 | ) 54 | (else 55 | ;; they are not equal, return '0' 56 | i32.const 0 57 | return 58 | ) 59 | ) 60 | i32.const 0 61 | ) 62 | (func $select_stmt (param i32) (result i32) 63 | (select (i32.const 1) (i32.const 0) (i32.eqz (local.get 0))) 64 | ) 65 | 66 | (func $main (export "main") 67 | (call $basic_br (i32.const 0)) 68 | global.set $var0 69 | (call $more_nesting (i32.const 0)) ;; eq 70 | global.get $var1 71 | i32.add 72 | global.set $var1 73 | (call $more_nesting (i32.const 1)) ;; neq 74 | global.get $var1 75 | i32.add 76 | global.set $var1 77 | (call $more_nesting (i32.const 1)) ;; neq 78 | global.get $var1 79 | i32.add 80 | global.set $var1 81 | (call $more_nesting (i32.const 3)) ;; gt 2 82 | global.get $var1 83 | i32.add 84 | global.set $var1 85 | (call $if_stmt (i32.const 0)) 86 | drop 87 | (call $select_stmt (i32.const 0)) 88 | drop 89 | ) 90 | 91 | ;; hacky thing to make this work on BOTH wasmtime and Wizard 92 | (func $start (export "_start") 93 | call $main 94 | ) 95 | ) -------------------------------------------------------------------------------- /tests/apps/core_suite/handwritten/branches.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ejrgilbert/whamm/2bc891519c0c657e591fc75971441d556f1e2223/tests/apps/core_suite/handwritten/branches.wasm -------------------------------------------------------------------------------- /tests/apps/core_suite/handwritten/for_numerics-skip_ExprFolder.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ejrgilbert/whamm/2bc891519c0c657e591fc75971441d556f1e2223/tests/apps/core_suite/handwritten/for_numerics-skip_ExprFolder.wasm -------------------------------------------------------------------------------- /tests/apps/core_suite/handwritten/for_numerics-skip_ExprFolder.wat: -------------------------------------------------------------------------------- 1 | (module 2 | ;; Call target, parameters are used as type values: 3 | ;; (u8, i8, u16, i16, u32, i32, u64, i64, f32, f64) 4 | (func $call_target (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i64) (param i64) (param f32) (param f64) (result i32) 5 | local.get 0 6 | ) 7 | (func $start (export "main") 8 | (call $call_target (i32.const 1) (i32.const 1) (i32.const 1) (i32.const 1) (i32.const 1) (i32.const 1) (i64.const 1) (i64.const 1) (f32.const 1) (f64.const 1)) 9 | drop 10 | ) 11 | (start $start) 12 | ) -------------------------------------------------------------------------------- /tests/apps/core_suite/handwritten/for_numerics.wasm: -------------------------------------------------------------------------------- 1 | asm ``main 2 |  A name call_targetstart -------------------------------------------------------------------------------- /tests/apps/core_suite/handwritten/for_numerics.wat: -------------------------------------------------------------------------------- 1 | (module 2 | ;; Test case functions 3 | (func $call_target (param i32) (result i32) 4 | local.get 0 5 | ) 6 | (func $start (export "main") 7 | (call $call_target (i32.const 0)) 8 | drop 9 | ) 10 | (start $start) 11 | ) -------------------------------------------------------------------------------- /tests/apps/core_suite/handwritten/mem-ops.wasm: -------------------------------------------------------------------------------- 1 | asm`main_start 2 | AB7A((  namemainstart -------------------------------------------------------------------------------- /tests/apps/core_suite/handwritten/mem-ops.wat: -------------------------------------------------------------------------------- 1 | 2 | (module 3 | (func $main (export "main") 4 | (i64.store (i32.const 5) (i64.const 1)) 5 | (i32.load (i32.const 0)) 6 | i32.load offset=8 7 | drop 8 | ) 9 | 10 | ;; hacky thing to make this work on BOTH wasmtime and Wizard 11 | (func $start (export "_start") 12 | call $main 13 | ) 14 | 15 | (memory 1) 16 | ) -------------------------------------------------------------------------------- /tests/apps/core_suite/handwritten/no_matched_events.wasm: -------------------------------------------------------------------------------- 1 | asm 2 | `` 3 | 4 |  A -------------------------------------------------------------------------------- /tests/apps/core_suite/handwritten/no_matched_events.wat: -------------------------------------------------------------------------------- 1 | (module 2 | (type (;0;) (func)) 3 | (type (;1;) (func (param i32 i32) (result i32))) 4 | (func (;0;) (type 0)) 5 | (func (;1;) (type 0) 6 | i32.const 0 7 | drop 8 | ) 9 | (start 1) 10 | (memory (;0;) 1) 11 | ) -------------------------------------------------------------------------------- /tests/apps/core_suite/ostrich/nw.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ejrgilbert/whamm/2bc891519c0c657e591fc75971441d556f1e2223/tests/apps/core_suite/ostrich/nw.wasm -------------------------------------------------------------------------------- /tests/apps/core_suite/polybench/2mm.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ejrgilbert/whamm/2bc891519c0c657e591fc75971441d556f1e2223/tests/apps/core_suite/polybench/2mm.wasm -------------------------------------------------------------------------------- /tests/apps/core_suite/rust/cf.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ejrgilbert/whamm/2bc891519c0c657e591fc75971441d556f1e2223/tests/apps/core_suite/rust/cf.wasm -------------------------------------------------------------------------------- /tests/apps/dfinity/users.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ejrgilbert/whamm/2bc891519c0c657e591fc75971441d556f1e2223/tests/apps/dfinity/users.wasm -------------------------------------------------------------------------------- /tests/scripts/README.md: -------------------------------------------------------------------------------- 1 | # Example Scripts for Testing # 2 | 3 | ## Fault Injection ## 4 | 5 | See [link](https://github.com/composablesys/dfinity_corpus/tree/main/instrumentation/instrumenter) 6 | 7 | TODO -- add description here 8 | 9 | ## Replay ## 10 | 11 | See [link](https://github.com/jakobgetz/wasm-r3) 12 | 13 | TODO -- add description here 14 | 15 | ## Wizard Monitors ## 16 | 17 | See [link](https://github.com/titzer/wizard-engine/blob/master/doc/Instrumentation.md) 18 | 19 | TODO -- add description here 20 | -------------------------------------------------------------------------------- /tests/scripts/core_suite/branch-monitor/app/branch-br__br_if__br_table.mm.app: -------------------------------------------------------------------------------- 1 | tests/apps/core_suite/rust/cf.wasm -------------------------------------------------------------------------------- /tests/scripts/core_suite/branch-monitor/app/branch-on_hw-br__br_if.mm.app: -------------------------------------------------------------------------------- 1 | tests/apps/core_suite/handwritten/branches.wasm -------------------------------------------------------------------------------- /tests/scripts/core_suite/branch-monitor/app/branch-on_rust-br__br_if.mm.app: -------------------------------------------------------------------------------- 1 | tests/apps/core_suite/rust/cf.wasm -------------------------------------------------------------------------------- /tests/scripts/core_suite/branch-monitor/app/branch_with_allocs-on_hw-br__br_if.mm.app: -------------------------------------------------------------------------------- 1 | tests/apps/core_suite/handwritten/branches.wasm -------------------------------------------------------------------------------- /tests/scripts/core_suite/branch-monitor/app/branch_with_allocs-on_hw-br__br_if__br_table.mm.app: -------------------------------------------------------------------------------- 1 | tests/apps/core_suite/handwritten/branches.wasm -------------------------------------------------------------------------------- /tests/scripts/core_suite/branch-monitor/app/branch_with_allocs-on_rust-br__br_if__br_table.mm.app: -------------------------------------------------------------------------------- 1 | tests/apps/core_suite/rust/cf.wasm -------------------------------------------------------------------------------- /tests/scripts/core_suite/branch-monitor/branch-on_hw-br__br_if.mm: -------------------------------------------------------------------------------- 1 | // TODO -- support pulling fname on Wizard target! 2 | report var count: map<(u32, u32, u32), i32>; 3 | 4 | wasm::br:before / 5 | fid == 0 || 6 | fid == 1 || 7 | fid == 2 8 | / { 9 | // branch always taken for `br` 10 | // count stores an array of counters 11 | count[(fid, pc, 1)]++; 12 | } 13 | 14 | wasm::br_if:before / 15 | fid == 0 || 16 | fid == 1 || 17 | fid == 2 18 | / { 19 | // which branch was taken? 20 | var index: u32; 21 | index = arg0 != 0 ? 1 : 0; 22 | 23 | // count stores an array of counters 24 | count[(fid, pc, index)]++; 25 | } 26 | -------------------------------------------------------------------------------- /tests/scripts/core_suite/branch-monitor/branch-on_rust-br__br_if.mm: -------------------------------------------------------------------------------- 1 | wasm::br:before / 2 | fid == 27 || // calc 3 | fid == 28 // print_x 4 | / { 5 | report unshared var taken: i32; 6 | // branch always taken for `br` 7 | taken++; 8 | } 9 | 10 | wasm::br_if:before / 11 | fid == 27 || // calc 12 | fid == 28 // print_x 13 | / { 14 | report unshared var taken: i32; 15 | report unshared var not_taken: i32; 16 | 17 | // which branch was taken? 18 | if (arg0 != 0) { 19 | taken++; 20 | } else { 21 | not_taken++; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /tests/scripts/core_suite/branch-monitor/branch_with_allocs-on_hw-br__br_if.mm: -------------------------------------------------------------------------------- 1 | // TODO -- support pulling fname on Wizard target! 2 | 3 | wasm::br:before / 4 | fid == 0 || 5 | fid == 1 || 6 | fid == 2 7 | / { 8 | report unshared var taken: i32; 9 | // branch always taken for `br` 10 | taken++; 11 | } 12 | 13 | wasm::br_if:before / 14 | fid == 0 || 15 | fid == 1 || 16 | fid == 2 17 | / { 18 | report unshared var taken: i32; 19 | report unshared var not_taken: i32; 20 | 21 | // which branch was taken? 22 | if (arg0 != 0) { 23 | taken++; 24 | } else { 25 | not_taken++; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /tests/scripts/core_suite/branch-monitor/expected/rewriting/branch-br__br_if__br_table.mm.exp: -------------------------------------------------------------------------------- 1 | ==== CALC ==== 2 | calc(9, 0) -> 9 3 | calc(8, 1) -> 9 4 | calc(7, 2) -> 9 5 | calc(6, 3) -> 9 6 | calc(5, 4) -> 20 7 | calc(4, 5) -> 20 8 | calc(3, 6) -> 18 9 | calc(2, 7) -> 14 10 | calc(1, 8) -> 8 11 | calc(0, 9) -> 0 12 | 13 | ==== PRINT ==== 14 | hi world! 15 | hi world! 16 | hi world! 17 | hi world! 18 | hi world! 19 | hi world! 20 | hi world! 21 | hi world! 22 | hi world! 23 | hi world! 24 | hello world! 25 | hello world! 26 | hello world! 27 | hello world! 28 | hello world! 29 | hello world! 30 | hello world! 31 | hello world! 32 | hello world! 33 | hello world! 34 | 'sup world! 35 | 'sup world! 36 | 'sup world! 37 | 'sup world! 38 | 'sup world! 39 | 'sup world! 40 | 'sup world! 41 | 'sup world! 42 | 'sup world! 43 | 'sup world! 44 | 45 | ============================= REPORT CSV FLUSH ================================ 46 | id, id_type, name, whamm_type, wasm_type, script_id, fid:pc, probe_id, value(s) 47 | 0, map_id, count, map<(u32,u32,u32),i32>, i32, script0, , , (61, 35, 0)->6;(61, 35, 1)->4;(61, 75, 0)->6;(61, 76, 1)->6;(61, 103, 0)->4;(61, 104, 1)->4;(61, 109, 1)->6;(61, 120, 1)->4;(62, 67, 0)->3;(62, 67, 1)->30;(62, 172, 1)->30;(63, 21, 0)->10;(63, 21, 1)->10;(63, 21, 2)->10;(63, 31, 1)->10;(63, 41, 1)->10 -------------------------------------------------------------------------------- /tests/scripts/core_suite/branch-monitor/expected/rewriting/branch-on_hw-br__br_if.mm.exp: -------------------------------------------------------------------------------- 1 | ============================= REPORT CSV FLUSH ================================ 2 | id, id_type, name, whamm_type, wasm_type, script_id, fid:pc, probe_id, value(s) 3 | 0, map_id, count, map<(u32,u32,u32),i32>, i32, script0, , , (0, 5, 0)->1;(0, 6, 1)->1;(1, 6, 0)->3;(1, 6, 1)->1;(1, 10, 0)->2;(1, 10, 1)->1;(1, 11, 1)->2 -------------------------------------------------------------------------------- /tests/scripts/core_suite/branch-monitor/expected/rewriting/branch-on_rust-br__br_if.mm.exp: -------------------------------------------------------------------------------- 1 | ==== CALC ==== 2 | calc(9, 0) -> 9 3 | calc(8, 1) -> 9 4 | calc(7, 2) -> 9 5 | calc(6, 3) -> 9 6 | calc(5, 4) -> 20 7 | calc(4, 5) -> 20 8 | calc(3, 6) -> 18 9 | calc(2, 7) -> 14 10 | calc(1, 8) -> 8 11 | calc(0, 9) -> 0 12 | 13 | ==== PRINT ==== 14 | hi world! 15 | hi world! 16 | hi world! 17 | hi world! 18 | hi world! 19 | hi world! 20 | hi world! 21 | hi world! 22 | hi world! 23 | hi world! 24 | hello world! 25 | hello world! 26 | hello world! 27 | hello world! 28 | hello world! 29 | hello world! 30 | hello world! 31 | hello world! 32 | hello world! 33 | hello world! 34 | 'sup world! 35 | 'sup world! 36 | 'sup world! 37 | 'sup world! 38 | 'sup world! 39 | 'sup world! 40 | 'sup world! 41 | 'sup world! 42 | 'sup world! 43 | 'sup world! 44 | 45 | ============================= REPORT CSV FLUSH ================================ 46 | id, id_type, name, whamm_type, wasm_type, script_id, fid:pc, probe_id, value(s) 47 | 4, memaddr, taken, i32, i32, script0, 27:39, 1_wasm:opcode:br_if:before, 4 48 | 31, memaddr, not_taken, i32, i32, script0, 27:39, 1_wasm:opcode:br_if:before, 6 49 | 58, memaddr, taken, i32, i32, script0, 27:79, 1_wasm:opcode:br_if:before, 0 50 | 85, memaddr, not_taken, i32, i32, script0, 27:79, 1_wasm:opcode:br_if:before, 6 51 | 112, memaddr, taken, i32, i32, script0, 27:80, 0_wasm:opcode:br:before, 6 52 | 139, memaddr, taken, i32, i32, script0, 27:107, 1_wasm:opcode:br_if:before, 0 53 | 166, memaddr, not_taken, i32, i32, script0, 27:107, 1_wasm:opcode:br_if:before, 4 54 | 193, memaddr, taken, i32, i32, script0, 27:108, 0_wasm:opcode:br:before, 4 55 | 220, memaddr, taken, i32, i32, script0, 27:113, 0_wasm:opcode:br:before, 6 56 | 247, memaddr, taken, i32, i32, script0, 27:124, 0_wasm:opcode:br:before, 4 57 | 274, memaddr, taken, i32, i32, script0, 28:67, 1_wasm:opcode:br_if:before, 30 58 | 301, memaddr, not_taken, i32, i32, script0, 28:67, 1_wasm:opcode:br_if:before, 3 59 | 328, memaddr, taken, i32, i32, script0, 28:191, 0_wasm:opcode:br:before, 30 -------------------------------------------------------------------------------- /tests/scripts/core_suite/branch-monitor/expected/rewriting/branch_with_allocs-on_hw-br__br_if.mm.exp: -------------------------------------------------------------------------------- 1 | ============================= REPORT CSV FLUSH ================================ 2 | id, id_type, name, whamm_type, wasm_type, script_id, fid:pc, probe_id, value(s) 3 | 4, memaddr, taken, i32, i32, script0, 0:5, 1_wasm:opcode:br_if:before, 0 4 | 31, memaddr, not_taken, i32, i32, script0, 0:5, 1_wasm:opcode:br_if:before, 1 5 | 58, memaddr, taken, i32, i32, script0, 0:6, 0_wasm:opcode:br:before, 1 6 | 85, memaddr, taken, i32, i32, script0, 1:6, 1_wasm:opcode:br_if:before, 1 7 | 112, memaddr, not_taken, i32, i32, script0, 1:6, 1_wasm:opcode:br_if:before, 3 8 | 139, memaddr, taken, i32, i32, script0, 1:10, 1_wasm:opcode:br_if:before, 1 9 | 166, memaddr, not_taken, i32, i32, script0, 1:10, 1_wasm:opcode:br_if:before, 2 10 | 193, memaddr, taken, i32, i32, script0, 1:11, 0_wasm:opcode:br:before, 2 -------------------------------------------------------------------------------- /tests/scripts/core_suite/branch-monitor/expected/rewriting/branch_with_allocs-on_hw-br__br_if__br_table.mm.exp: -------------------------------------------------------------------------------- 1 | ============================= REPORT CSV FLUSH ================================ 2 | id, id_type, name, whamm_type, wasm_type, script_id, fid:pc, probe_id, value(s) 3 | 4, memaddr, taken, i32, i32, script0, 0:5, 1_wasm:opcode:br_if:before, 0 4 | 31, memaddr, not_taken, i32, i32, script0, 0:5, 1_wasm:opcode:br_if:before, 1 5 | 58, memaddr, taken, i32, i32, script0, 0:6, 0_wasm:opcode:br:before, 1 6 | 85, memaddr, taken, i32, i32, script0, 1:6, 1_wasm:opcode:br_if:before, 1 7 | 112, memaddr, not_taken, i32, i32, script0, 1:6, 1_wasm:opcode:br_if:before, 3 8 | 139, memaddr, taken, i32, i32, script0, 1:10, 1_wasm:opcode:br_if:before, 1 9 | 166, memaddr, not_taken, i32, i32, script0, 1:10, 1_wasm:opcode:br_if:before, 2 10 | 193, memaddr, taken, i32, i32, script0, 1:11, 0_wasm:opcode:br:before, 2 11 | 220, memaddr, taken_branches, map, i32, script0, 2:4, 2_wasm:opcode:br_table:before, 0->1;1->1;2->1 -------------------------------------------------------------------------------- /tests/scripts/core_suite/branch-monitor/expected/rewriting/branch_with_allocs-on_rust-br__br_if__br_table.mm.exp: -------------------------------------------------------------------------------- 1 | ==== CALC ==== 2 | calc(9, 0) -> 9 3 | calc(8, 1) -> 9 4 | calc(7, 2) -> 9 5 | calc(6, 3) -> 9 6 | calc(5, 4) -> 20 7 | calc(4, 5) -> 20 8 | calc(3, 6) -> 18 9 | calc(2, 7) -> 14 10 | calc(1, 8) -> 8 11 | calc(0, 9) -> 0 12 | 13 | ==== PRINT ==== 14 | hi world! 15 | hi world! 16 | hi world! 17 | hi world! 18 | hi world! 19 | hi world! 20 | hi world! 21 | hi world! 22 | hi world! 23 | hi world! 24 | hello world! 25 | hello world! 26 | hello world! 27 | hello world! 28 | hello world! 29 | hello world! 30 | hello world! 31 | hello world! 32 | hello world! 33 | hello world! 34 | 'sup world! 35 | 'sup world! 36 | 'sup world! 37 | 'sup world! 38 | 'sup world! 39 | 'sup world! 40 | 'sup world! 41 | 'sup world! 42 | 'sup world! 43 | 'sup world! 44 | 45 | ============================= REPORT CSV FLUSH ================================ 46 | id, id_type, name, whamm_type, wasm_type, script_id, fid:pc, probe_id, value(s) 47 | 4, global_id, taken, i32, i32, script0, 61:35, 1_wasm:opcode:br_if:before, 4 48 | 5, global_id, not_taken, i32, i32, script0, 61:35, 1_wasm:opcode:br_if:before, 6 49 | 6, global_id, taken, i32, i32, script0, 61:75, 1_wasm:opcode:br_if:before, 0 50 | 7, global_id, not_taken, i32, i32, script0, 61:75, 1_wasm:opcode:br_if:before, 6 51 | 8, global_id, taken, i32, i32, script0, 61:76, 0_wasm:opcode:br:before, 6 52 | 9, global_id, taken, i32, i32, script0, 61:103, 1_wasm:opcode:br_if:before, 0 53 | 10, global_id, not_taken, i32, i32, script0, 61:103, 1_wasm:opcode:br_if:before, 4 54 | 11, global_id, taken, i32, i32, script0, 61:104, 0_wasm:opcode:br:before, 4 55 | 12, global_id, taken, i32, i32, script0, 61:109, 0_wasm:opcode:br:before, 6 56 | 13, global_id, taken, i32, i32, script0, 61:120, 0_wasm:opcode:br:before, 4 57 | 14, global_id, taken, i32, i32, script0, 62:67, 1_wasm:opcode:br_if:before, 30 58 | 15, global_id, not_taken, i32, i32, script0, 62:67, 1_wasm:opcode:br_if:before, 3 59 | 16, global_id, taken, i32, i32, script0, 62:172, 0_wasm:opcode:br:before, 30 60 | 17, global_id, taken, i32, i32, script0, 63:31, 0_wasm:opcode:br:before, 10 61 | 18, global_id, taken, i32, i32, script0, 63:41, 0_wasm:opcode:br:before, 10 62 | 1, map_id, taken_branches, map, i32, script0, 63:21, 2_wasm:opcode:br_table:before, 0->10;1->10;2->10 -------------------------------------------------------------------------------- /tests/scripts/core_suite/branch-monitor/expected/wizard/branch-on_hw-br__br_if.mm.exp: -------------------------------------------------------------------------------- 1 | ============================= REPORT CSV FLUSH ================================ 2 | id, id_type, name, whamm_type, wasm_type, script_id, fid:pc, probe_id, value(s) 3 | 0, map_id, count, map<(u32,u32,u32),i32>, i32, script0, , , (0, 10, 0)->1;(0, 12, 1)->1;(1, 12, 0)->3;(1, 12, 1)->1;(1, 19, 0)->2;(1, 19, 1)->1;(1, 21, 1)->2 -------------------------------------------------------------------------------- /tests/scripts/core_suite/branch-monitor/expected/wizard/branch-on_rust-br__br_if.mm.exp: -------------------------------------------------------------------------------- 1 | ==== CALC ==== 2 | calc(9, 0) -> 9 3 | calc(8, 1) -> 9 4 | calc(7, 2) -> 9 5 | calc(6, 3) -> 9 6 | calc(5, 4) -> 20 7 | calc(4, 5) -> 20 8 | calc(3, 6) -> 18 9 | calc(2, 7) -> 14 10 | calc(1, 8) -> 8 11 | calc(0, 9) -> 0 12 | 13 | ==== PRINT ==== 14 | hi world! 15 | hi world! 16 | hi world! 17 | hi world! 18 | hi world! 19 | hi world! 20 | hi world! 21 | hi world! 22 | hi world! 23 | hi world! 24 | hello world! 25 | hello world! 26 | hello world! 27 | hello world! 28 | hello world! 29 | hello world! 30 | hello world! 31 | hello world! 32 | hello world! 33 | hello world! 34 | 'sup world! 35 | 'sup world! 36 | 'sup world! 37 | 'sup world! 38 | 'sup world! 39 | 'sup world! 40 | 'sup world! 41 | 'sup world! 42 | 'sup world! 43 | 'sup world! 44 | 45 | ============================= REPORT CSV FLUSH ================================ 46 | id, id_type, name, whamm_type, wasm_type, script_id, fid:pc, probe_id, value(s) 47 | 238, memaddr, taken, i32, i32, script0, 27:88, 1_wasm:opcode:br_if, 4 48 | 265, memaddr, not_taken, i32, i32, script0, 27:88, 1_wasm:opcode:br_if, 6 49 | 292, memaddr, taken, i32, i32, script0, 27:159, 1_wasm:opcode:br_if, 0 50 | 319, memaddr, not_taken, i32, i32, script0, 27:159, 1_wasm:opcode:br_if, 6 51 | 346, memaddr, taken, i32, i32, script0, 27:161, 0_wasm:opcode:br, 6 52 | 373, memaddr, taken, i32, i32, script0, 27:209, 1_wasm:opcode:br_if, 0 53 | 400, memaddr, not_taken, i32, i32, script0, 27:209, 1_wasm:opcode:br_if, 4 54 | 427, memaddr, taken, i32, i32, script0, 27:211, 0_wasm:opcode:br, 4 55 | 454, memaddr, taken, i32, i32, script0, 27:221, 0_wasm:opcode:br, 6 56 | 481, memaddr, taken, i32, i32, script0, 27:245, 0_wasm:opcode:br, 4 57 | 508, memaddr, taken, i32, i32, script0, 28:154, 1_wasm:opcode:br_if, 30 58 | 535, memaddr, not_taken, i32, i32, script0, 28:154, 1_wasm:opcode:br_if, 3 59 | 562, memaddr, taken, i32, i32, script0, 28:408, 0_wasm:opcode:br, 30 -------------------------------------------------------------------------------- /tests/scripts/core_suite/branch-monitor/expected/wizard/branch_with_allocs-on_hw-br__br_if.mm.exp: -------------------------------------------------------------------------------- 1 | ============================= REPORT CSV FLUSH ================================ 2 | id, id_type, name, whamm_type, wasm_type, script_id, fid:pc, probe_id, value(s) 3 | 238, memaddr, taken, i32, i32, script0, 0:10, 1_wasm:opcode:br_if, 0 4 | 265, memaddr, not_taken, i32, i32, script0, 0:10, 1_wasm:opcode:br_if, 1 5 | 292, memaddr, taken, i32, i32, script0, 0:12, 0_wasm:opcode:br, 1 6 | 319, memaddr, taken, i32, i32, script0, 1:12, 1_wasm:opcode:br_if, 1 7 | 346, memaddr, not_taken, i32, i32, script0, 1:12, 1_wasm:opcode:br_if, 3 8 | 373, memaddr, taken, i32, i32, script0, 1:19, 1_wasm:opcode:br_if, 1 9 | 400, memaddr, not_taken, i32, i32, script0, 1:19, 1_wasm:opcode:br_if, 2 10 | 427, memaddr, taken, i32, i32, script0, 1:21, 0_wasm:opcode:br, 2 -------------------------------------------------------------------------------- /tests/scripts/core_suite/branch-monitor/expected/wizard/branch_with_allocs-on_hw-br__br_if__br_table.mm.exp: -------------------------------------------------------------------------------- 1 | ============================= REPORT CSV FLUSH ================================ 2 | id, id_type, name, whamm_type, wasm_type, script_id, fid:pc, probe_id, value(s) 3 | 4, global_id, taken, i32, i32, script0, 0:5, 1_wasm:opcode:br_if:before, 0 4 | 5, global_id, not_taken, i32, i32, script0, 0:5, 1_wasm:opcode:br_if:before, 1 5 | 6, global_id, taken, i32, i32, script0, 0:6, 0_wasm:opcode:br:before, 1 6 | 7, global_id, taken, i32, i32, script0, 1:6, 1_wasm:opcode:br_if:before, 1 7 | 8, global_id, not_taken, i32, i32, script0, 1:6, 1_wasm:opcode:br_if:before, 3 8 | 9, global_id, taken, i32, i32, script0, 1:10, 1_wasm:opcode:br_if:before, 1 9 | 10, global_id, not_taken, i32, i32, script0, 1:10, 1_wasm:opcode:br_if:before, 2 10 | 11, global_id, taken, i32, i32, script0, 1:11, 0_wasm:opcode:br:before, 2 11 | 1, map_id, taken_branches, map, i32, script0, 2:4, 2_wasm:opcode:br_table:before, 0->1;1->1;2->1 -------------------------------------------------------------------------------- /tests/scripts/core_suite/branch-monitor_rewriting/app/branch-br__br_if__br_table.mm.app: -------------------------------------------------------------------------------- 1 | tests/apps/core_suite/rust/cf.wasm -------------------------------------------------------------------------------- /tests/scripts/core_suite/branch-monitor_rewriting/app/branch_with_allocs-on_hw-br__br_if__br_table.mm.app: -------------------------------------------------------------------------------- 1 | tests/apps/core_suite/handwritten/branches.wasm -------------------------------------------------------------------------------- /tests/scripts/core_suite/branch-monitor_rewriting/app/branch_with_allocs-on_rust-br__br_if__br_table.mm.app: -------------------------------------------------------------------------------- 1 | tests/apps/core_suite/rust/cf.wasm -------------------------------------------------------------------------------- /tests/scripts/core_suite/branch-monitor_rewriting/branch-br__br_if__br_table.mm: -------------------------------------------------------------------------------- 1 | // TODO -- cannot flush global report variables yet on Wizard target 2 | // TODO -- support pulling fname on Wizard target! 3 | // TODO -- support flushing map types on Wizard target 4 | report var count: map<(u32, u32, u32), i32>; 5 | 6 | wasm::br:before / 7 | fname == "calc" || 8 | fname == "print_x" || 9 | fname == "opt_str" 10 | / { 11 | // branch always taken for `br` 12 | // count stores an array of counters 13 | count[(fid, pc, 1)]++; 14 | } 15 | 16 | wasm::br_if:before / 17 | fid == 27 || // calc 18 | fid == 28 || // print_x 19 | fid == 29 // opt_str 20 | / { 21 | // which branch was taken? 22 | var index: u32; 23 | index = arg0 != 0 ? 1 : 0; 24 | 25 | // count stores an array of counters 26 | count[(fid, pc, index)]++; 27 | } 28 | 29 | wasm::br_table:before / 30 | fname == "calc" || 31 | fname == "print_x" || 32 | fname == "opt_str" 33 | / { 34 | // which branch was taken? 35 | var index: u32; 36 | index = arg0 <= (num_targets - 1) ? targets[arg0] : default_target; 37 | 38 | // count stores an array of counters 39 | count[(fid, pc, index)]++; 40 | } 41 | -------------------------------------------------------------------------------- /tests/scripts/core_suite/branch-monitor_rewriting/branch_with_allocs-on_hw-br__br_if__br_table.mm: -------------------------------------------------------------------------------- 1 | // TODO -- support pulling `fname` on Wizard target! 2 | // TODO -- support pulling br_table `targets` on Wizard target! 3 | 4 | wasm::br:before / 5 | fid == 0 || 6 | fid == 1 || 7 | fid == 2 8 | / { 9 | // branch always taken for `br` 10 | report unshared var taken: i32; 11 | taken++; 12 | } 13 | 14 | wasm::br_if:before / 15 | fid == 0 || 16 | fid == 1 || 17 | fid == 2 18 | / { 19 | report unshared var taken: i32; 20 | report unshared var not_taken: i32; 21 | 22 | // which branch was taken? 23 | if (arg0 != 0) { 24 | taken++; 25 | } else { 26 | not_taken++; 27 | } 28 | } 29 | 30 | wasm::br_table:before / 31 | fid == 0 || 32 | fid == 1 || 33 | fid == 2 34 | / { 35 | report unshared var taken_branches: map; 36 | 37 | // which branch was taken? 38 | var index: u32; 39 | index = arg0 <= (num_targets - 1) ? targets[arg0] : default_target; 40 | 41 | // count stores an array of counters 42 | taken_branches[index]++; 43 | } 44 | -------------------------------------------------------------------------------- /tests/scripts/core_suite/branch-monitor_rewriting/branch_with_allocs-on_rust-br__br_if__br_table.mm: -------------------------------------------------------------------------------- 1 | // TODO -- cannot flush global report variables yet on Wizard target 2 | // TODO -- support pulling fname on Wizard target! 3 | 4 | wasm::br:before / 5 | fname == "calc" || 6 | fname == "print_x" || 7 | fname == "opt_str" 8 | / { 9 | // branch always taken for `br` 10 | report unshared var taken: i32; 11 | taken++; 12 | } 13 | 14 | wasm::br_if:before / 15 | fid == 27 || // calc 16 | fid == 28 || // print_x 17 | fid == 29 // opt_str 18 | / { 19 | report unshared var taken: i32; 20 | report unshared var not_taken: i32; 21 | 22 | // which branch was taken? 23 | if (arg0 != 0) { 24 | taken++; 25 | } else { 26 | not_taken++; 27 | } 28 | } 29 | 30 | wasm::br_table:before / 31 | fid == 27 || // calc 32 | fid == 28 || // print_x 33 | fid == 29 // opt_str 34 | / { 35 | report unshared var taken_branches: map; 36 | 37 | // which branch was taken? 38 | var index: u32; 39 | index = arg0 <= (num_targets - 1) ? targets[arg0] : default_target; 40 | 41 | // count stores an array of counters 42 | taken_branches[index]++; 43 | } 44 | -------------------------------------------------------------------------------- /tests/scripts/core_suite/branch-monitor_rewriting/expected/rewriting/branch-br__br_if__br_table.mm.exp: -------------------------------------------------------------------------------- 1 | ==== CALC ==== 2 | calc(9, 0) -> 9 3 | calc(8, 1) -> 9 4 | calc(7, 2) -> 9 5 | calc(6, 3) -> 9 6 | calc(5, 4) -> 20 7 | calc(4, 5) -> 20 8 | calc(3, 6) -> 18 9 | calc(2, 7) -> 14 10 | calc(1, 8) -> 8 11 | calc(0, 9) -> 0 12 | 13 | ==== PRINT ==== 14 | hi world! 15 | hi world! 16 | hi world! 17 | hi world! 18 | hi world! 19 | hi world! 20 | hi world! 21 | hi world! 22 | hi world! 23 | hi world! 24 | hello world! 25 | hello world! 26 | hello world! 27 | hello world! 28 | hello world! 29 | hello world! 30 | hello world! 31 | hello world! 32 | hello world! 33 | hello world! 34 | 'sup world! 35 | 'sup world! 36 | 'sup world! 37 | 'sup world! 38 | 'sup world! 39 | 'sup world! 40 | 'sup world! 41 | 'sup world! 42 | 'sup world! 43 | 'sup world! 44 | 45 | ============================= REPORT CSV FLUSH ================================ 46 | id, id_type, name, whamm_type, wasm_type, script_id, fid:pc, probe_id, value(s) 47 | 0, map_id, count, map<(u32,u32,u32),i32>, i32, script0, , , (27, 39, 0)->6;(27, 39, 1)->4;(27, 79, 0)->6;(27, 80, 1)->6;(27, 107, 0)->4;(27, 108, 1)->4;(27, 113, 1)->6;(27, 124, 1)->4;(28, 67, 0)->3;(28, 67, 1)->30;(28, 191, 1)->30;(29, 21, 0)->10;(29, 21, 1)->10;(29, 21, 2)->10;(29, 31, 1)->10;(29, 41, 1)->10 -------------------------------------------------------------------------------- /tests/scripts/core_suite/branch-monitor_rewriting/expected/rewriting/branch_with_allocs-on_hw-br__br_if__br_table.mm.exp: -------------------------------------------------------------------------------- 1 | ============================= REPORT CSV FLUSH ================================ 2 | id, id_type, name, whamm_type, wasm_type, script_id, fid:pc, probe_id, value(s) 3 | 4, memaddr, taken, i32, i32, script0, 0:5, 1_wasm:opcode:br_if:before, 0 4 | 31, memaddr, not_taken, i32, i32, script0, 0:5, 1_wasm:opcode:br_if:before, 1 5 | 58, memaddr, taken, i32, i32, script0, 0:6, 0_wasm:opcode:br:before, 1 6 | 85, memaddr, taken, i32, i32, script0, 1:6, 1_wasm:opcode:br_if:before, 1 7 | 112, memaddr, not_taken, i32, i32, script0, 1:6, 1_wasm:opcode:br_if:before, 3 8 | 139, memaddr, taken, i32, i32, script0, 1:10, 1_wasm:opcode:br_if:before, 1 9 | 166, memaddr, not_taken, i32, i32, script0, 1:10, 1_wasm:opcode:br_if:before, 2 10 | 193, memaddr, taken, i32, i32, script0, 1:11, 0_wasm:opcode:br:before, 2 11 | 220, memaddr, taken_branches, map, i32, script0, 2:4, 2_wasm:opcode:br_table:before, 0->1;1->1;2->1 -------------------------------------------------------------------------------- /tests/scripts/core_suite/branch-monitor_rewriting/expected/rewriting/branch_with_allocs-on_rust-br__br_if__br_table.mm.exp: -------------------------------------------------------------------------------- 1 | ==== CALC ==== 2 | calc(9, 0) -> 9 3 | calc(8, 1) -> 9 4 | calc(7, 2) -> 9 5 | calc(6, 3) -> 9 6 | calc(5, 4) -> 20 7 | calc(4, 5) -> 20 8 | calc(3, 6) -> 18 9 | calc(2, 7) -> 14 10 | calc(1, 8) -> 8 11 | calc(0, 9) -> 0 12 | 13 | ==== PRINT ==== 14 | hi world! 15 | hi world! 16 | hi world! 17 | hi world! 18 | hi world! 19 | hi world! 20 | hi world! 21 | hi world! 22 | hi world! 23 | hi world! 24 | hello world! 25 | hello world! 26 | hello world! 27 | hello world! 28 | hello world! 29 | hello world! 30 | hello world! 31 | hello world! 32 | hello world! 33 | hello world! 34 | 'sup world! 35 | 'sup world! 36 | 'sup world! 37 | 'sup world! 38 | 'sup world! 39 | 'sup world! 40 | 'sup world! 41 | 'sup world! 42 | 'sup world! 43 | 'sup world! 44 | 45 | ============================= REPORT CSV FLUSH ================================ 46 | id, id_type, name, whamm_type, wasm_type, script_id, fid:pc, probe_id, value(s) 47 | 4, memaddr, taken, i32, i32, script0, 27:39, 1_wasm:opcode:br_if:before, 4 48 | 31, memaddr, not_taken, i32, i32, script0, 27:39, 1_wasm:opcode:br_if:before, 6 49 | 58, memaddr, taken, i32, i32, script0, 27:79, 1_wasm:opcode:br_if:before, 0 50 | 85, memaddr, not_taken, i32, i32, script0, 27:79, 1_wasm:opcode:br_if:before, 6 51 | 112, memaddr, taken, i32, i32, script0, 27:80, 0_wasm:opcode:br:before, 6 52 | 139, memaddr, taken, i32, i32, script0, 27:107, 1_wasm:opcode:br_if:before, 0 53 | 166, memaddr, not_taken, i32, i32, script0, 27:107, 1_wasm:opcode:br_if:before, 4 54 | 193, memaddr, taken, i32, i32, script0, 27:108, 0_wasm:opcode:br:before, 4 55 | 220, memaddr, taken, i32, i32, script0, 27:113, 0_wasm:opcode:br:before, 6 56 | 247, memaddr, taken, i32, i32, script0, 27:124, 0_wasm:opcode:br:before, 4 57 | 274, memaddr, taken, i32, i32, script0, 28:67, 1_wasm:opcode:br_if:before, 30 58 | 301, memaddr, not_taken, i32, i32, script0, 28:67, 1_wasm:opcode:br_if:before, 3 59 | 328, memaddr, taken, i32, i32, script0, 28:191, 0_wasm:opcode:br:before, 30 60 | 382, memaddr, taken, i32, i32, script0, 29:31, 0_wasm:opcode:br:before, 10 61 | 409, memaddr, taken, i32, i32, script0, 29:41, 0_wasm:opcode:br:before, 10 62 | 355, memaddr, taken_branches, map, i32, script0, 29:21, 2_wasm:opcode:br_table:before, 0->10;1->10;2->10 -------------------------------------------------------------------------------- /tests/scripts/core_suite/calls-monitor/app/basic-alloc-hw.mm.app: -------------------------------------------------------------------------------- 1 | tests/apps/core_suite/handwritten/branches.wasm -------------------------------------------------------------------------------- /tests/scripts/core_suite/calls-monitor/app/basic-hw.mm.app: -------------------------------------------------------------------------------- 1 | tests/apps/core_suite/handwritten/branches.wasm -------------------------------------------------------------------------------- /tests/scripts/core_suite/calls-monitor/app/basic-rust.mm.app: -------------------------------------------------------------------------------- 1 | tests/apps/core_suite/rust/cf.wasm -------------------------------------------------------------------------------- /tests/scripts/core_suite/calls-monitor/app/basic_global-hw.mm.app: -------------------------------------------------------------------------------- 1 | tests/apps/core_suite/handwritten/branches.wasm -------------------------------------------------------------------------------- /tests/scripts/core_suite/calls-monitor/basic-alloc-hw.mm: -------------------------------------------------------------------------------- 1 | wasm:opcode:call(arg0: i32):before / 2 | fid == 5 3 | // && (pc == 1 || pc == 4 || pc == 9) 4 | / { 5 | report var count: u32; 6 | if (arg0 == 0) { 7 | count++; 8 | } 9 | } -------------------------------------------------------------------------------- /tests/scripts/core_suite/calls-monitor/basic-hw.mm: -------------------------------------------------------------------------------- 1 | wasm:opcode:call(arg0: i32):before / 2 | fid == 5 3 | / { 4 | report unshared var count: u32; 5 | count = count + 1; 6 | } 7 | -------------------------------------------------------------------------------- /tests/scripts/core_suite/calls-monitor/basic-rust.mm: -------------------------------------------------------------------------------- 1 | // Only instrument if it's calling 'print_x' or 'calc' 2 | 3 | wasm:opcode:call:before / 4 | imm0 == 27 || // calc 5 | imm0 == 28 // print_x 6 | / { 7 | report unshared var count: u32; 8 | count = count + 1; 9 | } 10 | -------------------------------------------------------------------------------- /tests/scripts/core_suite/calls-monitor/basic_global-hw.mm: -------------------------------------------------------------------------------- 1 | report var count: u32; 2 | 3 | wasm:opcode:call(arg0: i32):before / 4 | fid == 5 5 | / { 6 | count = count + 1; 7 | } 8 | -------------------------------------------------------------------------------- /tests/scripts/core_suite/calls-monitor/expected/rewriting/basic-alloc-hw.mm.exp: -------------------------------------------------------------------------------- 1 | ============================= REPORT CSV FLUSH ================================ 2 | id, id_type, name, whamm_type, wasm_type, script_id, fid:pc, probe_id, value(s) 3 | 4, memaddr, count, u32, i32, script0, 5:1, 0_wasm:opcode:call:before, 1 4 | 31, memaddr, count, u32, i32, script0, 5:4, 0_wasm:opcode:call:before, 1 5 | 58, memaddr, count, u32, i32, script0, 5:9, 0_wasm:opcode:call:before, 0 6 | 85, memaddr, count, u32, i32, script0, 5:14, 0_wasm:opcode:call:before, 0 7 | 112, memaddr, count, u32, i32, script0, 5:19, 0_wasm:opcode:call:before, 0 8 | 139, memaddr, count, u32, i32, script0, 5:24, 0_wasm:opcode:call:before, 1 9 | 166, memaddr, count, u32, i32, script0, 5:27, 0_wasm:opcode:call:before, 0 10 | 193, memaddr, count, u32, i32, script0, 5:30, 0_wasm:opcode:call:before, 0 11 | 220, memaddr, count, u32, i32, script0, 5:33, 0_wasm:opcode:call:before, 1 12 | 247, memaddr, count, u32, i32, script0, 5:36, 0_wasm:opcode:call:before, 1 -------------------------------------------------------------------------------- /tests/scripts/core_suite/calls-monitor/expected/rewriting/basic-hw.mm.exp: -------------------------------------------------------------------------------- 1 | ============================= REPORT CSV FLUSH ================================ 2 | id, id_type, name, whamm_type, wasm_type, script_id, fid:pc, probe_id, value(s) 3 | 4, memaddr, count, u32, i32, script0, 5:1, 0_wasm:opcode:call:before, 1 4 | 31, memaddr, count, u32, i32, script0, 5:4, 0_wasm:opcode:call:before, 1 5 | 58, memaddr, count, u32, i32, script0, 5:9, 0_wasm:opcode:call:before, 1 6 | 85, memaddr, count, u32, i32, script0, 5:14, 0_wasm:opcode:call:before, 1 7 | 112, memaddr, count, u32, i32, script0, 5:19, 0_wasm:opcode:call:before, 1 8 | 139, memaddr, count, u32, i32, script0, 5:24, 0_wasm:opcode:call:before, 1 9 | 166, memaddr, count, u32, i32, script0, 5:27, 0_wasm:opcode:call:before, 1 10 | 193, memaddr, count, u32, i32, script0, 5:30, 0_wasm:opcode:call:before, 1 11 | 220, memaddr, count, u32, i32, script0, 5:33, 0_wasm:opcode:call:before, 1 12 | 247, memaddr, count, u32, i32, script0, 5:36, 0_wasm:opcode:call:before, 1 -------------------------------------------------------------------------------- /tests/scripts/core_suite/calls-monitor/expected/rewriting/basic-rust.mm.exp: -------------------------------------------------------------------------------- 1 | ==== CALC ==== 2 | calc(9, 0) -> 9 3 | calc(8, 1) -> 9 4 | calc(7, 2) -> 9 5 | calc(6, 3) -> 9 6 | calc(5, 4) -> 20 7 | calc(4, 5) -> 20 8 | calc(3, 6) -> 18 9 | calc(2, 7) -> 14 10 | calc(1, 8) -> 8 11 | calc(0, 9) -> 0 12 | 13 | ==== PRINT ==== 14 | hi world! 15 | hi world! 16 | hi world! 17 | hi world! 18 | hi world! 19 | hi world! 20 | hi world! 21 | hi world! 22 | hi world! 23 | hi world! 24 | hello world! 25 | hello world! 26 | hello world! 27 | hello world! 28 | hello world! 29 | hello world! 30 | hello world! 31 | hello world! 32 | hello world! 33 | hello world! 34 | 'sup world! 35 | 'sup world! 36 | 'sup world! 37 | 'sup world! 38 | 'sup world! 39 | 'sup world! 40 | 'sup world! 41 | 'sup world! 42 | 'sup world! 43 | 'sup world! 44 | 45 | ============================= REPORT CSV FLUSH ================================ 46 | id, id_type, name, whamm_type, wasm_type, script_id, fid:pc, probe_id, value(s) 47 | 4, memaddr, count, u32, i32, script0, 30:262, 0_wasm:opcode:call:before, 1 48 | 31, memaddr, count, u32, i32, script0, 30:275, 0_wasm:opcode:call:before, 1 49 | 58, memaddr, count, u32, i32, script0, 30:288, 0_wasm:opcode:call:before, 1 50 | 85, memaddr, count, u32, i32, script0, 30:319, 0_wasm:opcode:call:before, 10 -------------------------------------------------------------------------------- /tests/scripts/core_suite/calls-monitor/expected/rewriting/basic_global-hw.mm.exp: -------------------------------------------------------------------------------- 1 | ============================= REPORT CSV FLUSH ================================ 2 | id, id_type, name, whamm_type, wasm_type, script_id, fid:pc, probe_id, value(s) 3 | 3, global_id, count, u32, i32, script0, , , 10 -------------------------------------------------------------------------------- /tests/scripts/core_suite/calls-monitor/expected/wizard/basic-alloc-hw.mm.exp: -------------------------------------------------------------------------------- 1 | ============================= REPORT CSV FLUSH ================================ 2 | id, id_type, name, whamm_type, wasm_type, script_id, fid:pc, probe_id, value(s) 3 | 217, memaddr, count, u32, i32, script0, 5:3, 0_wasm:opcode:call, 1 4 | 244, memaddr, count, u32, i32, script0, 5:9, 0_wasm:opcode:call, 1 5 | 271, memaddr, count, u32, i32, script0, 5:18, 0_wasm:opcode:call, 0 6 | 298, memaddr, count, u32, i32, script0, 5:27, 0_wasm:opcode:call, 0 7 | 325, memaddr, count, u32, i32, script0, 5:36, 0_wasm:opcode:call, 0 8 | 352, memaddr, count, u32, i32, script0, 5:45, 0_wasm:opcode:call, 1 9 | 379, memaddr, count, u32, i32, script0, 5:50, 0_wasm:opcode:call, 0 10 | 406, memaddr, count, u32, i32, script0, 5:55, 0_wasm:opcode:call, 0 11 | 433, memaddr, count, u32, i32, script0, 5:60, 0_wasm:opcode:call, 1 12 | 460, memaddr, count, u32, i32, script0, 5:65, 0_wasm:opcode:call, 1 -------------------------------------------------------------------------------- /tests/scripts/core_suite/calls-monitor/expected/wizard/basic-hw.mm.exp: -------------------------------------------------------------------------------- 1 | ============================= REPORT CSV FLUSH ================================ 2 | id, id_type, name, whamm_type, wasm_type, script_id, fid:pc, probe_id, value(s) 3 | 217, memaddr, count, u32, i32, script0, 5:3, 0_wasm:opcode:call, 1 4 | 244, memaddr, count, u32, i32, script0, 5:9, 0_wasm:opcode:call, 1 5 | 271, memaddr, count, u32, i32, script0, 5:18, 0_wasm:opcode:call, 1 6 | 298, memaddr, count, u32, i32, script0, 5:27, 0_wasm:opcode:call, 1 7 | 325, memaddr, count, u32, i32, script0, 5:36, 0_wasm:opcode:call, 1 8 | 352, memaddr, count, u32, i32, script0, 5:45, 0_wasm:opcode:call, 1 9 | 379, memaddr, count, u32, i32, script0, 5:50, 0_wasm:opcode:call, 1 10 | 406, memaddr, count, u32, i32, script0, 5:55, 0_wasm:opcode:call, 1 11 | 433, memaddr, count, u32, i32, script0, 5:60, 0_wasm:opcode:call, 1 12 | 460, memaddr, count, u32, i32, script0, 5:65, 0_wasm:opcode:call, 1 -------------------------------------------------------------------------------- /tests/scripts/core_suite/calls-monitor/expected/wizard/basic-rust.mm.exp: -------------------------------------------------------------------------------- 1 | ==== CALC ==== 2 | calc(9, 0) -> 9 3 | calc(8, 1) -> 9 4 | calc(7, 2) -> 9 5 | calc(6, 3) -> 9 6 | calc(5, 4) -> 20 7 | calc(4, 5) -> 20 8 | calc(3, 6) -> 18 9 | calc(2, 7) -> 14 10 | calc(1, 8) -> 8 11 | calc(0, 9) -> 0 12 | 13 | ==== PRINT ==== 14 | hi world! 15 | hi world! 16 | hi world! 17 | hi world! 18 | hi world! 19 | hi world! 20 | hi world! 21 | hi world! 22 | hi world! 23 | hi world! 24 | hello world! 25 | hello world! 26 | hello world! 27 | hello world! 28 | hello world! 29 | hello world! 30 | hello world! 31 | hello world! 32 | hello world! 33 | hello world! 34 | 'sup world! 35 | 'sup world! 36 | 'sup world! 37 | 'sup world! 38 | 'sup world! 39 | 'sup world! 40 | 'sup world! 41 | 'sup world! 42 | 'sup world! 43 | 'sup world! 44 | 45 | ============================= REPORT CSV FLUSH ================================ 46 | id, id_type, name, whamm_type, wasm_type, script_id, fid:pc, probe_id, value(s) 47 | 217, memaddr, count, u32, i32, script0, 30:577, 0_wasm:opcode:call, 1 48 | 244, memaddr, count, u32, i32, script0, 30:607, 0_wasm:opcode:call, 1 49 | 271, memaddr, count, u32, i32, script0, 30:637, 0_wasm:opcode:call, 1 50 | 298, memaddr, count, u32, i32, script0, 30:709, 0_wasm:opcode:call, 10 -------------------------------------------------------------------------------- /tests/scripts/core_suite/calls-monitor/expected/wizard/basic_global-hw.mm.exp: -------------------------------------------------------------------------------- 1 | ============================= REPORT CSV FLUSH ================================ 2 | id, id_type, name, whamm_type, wasm_type, script_id, fid:pc, probe_id, value(s) 3 | 1, global_id, count, u32, i32, script0, , , 10 -------------------------------------------------------------------------------- /tests/scripts/core_suite/calls-monitor_rewriting/app/basic-alloc-rust.mm.app: -------------------------------------------------------------------------------- 1 | tests/apps/core_suite/rust/cf.wasm -------------------------------------------------------------------------------- /tests/scripts/core_suite/calls-monitor_rewriting/basic-alloc-rust.mm: -------------------------------------------------------------------------------- 1 | // Only instrument if it's calling 'print_x' or 'calc' 2 | // TODO -- support pulling fname on Wizard target! 3 | wasm:opcode:call(arg0: i32, arg1: i32):before / 4 | target_fn_name == "print_x" || 5 | target_fn_name == "calc" 6 | / { 7 | report var count: u32; 8 | if (arg0 == 0 || arg1 == 1) { 9 | count++; 10 | } 11 | } -------------------------------------------------------------------------------- /tests/scripts/core_suite/calls-monitor_rewriting/expected/rewriting/basic-alloc-rust.mm.exp: -------------------------------------------------------------------------------- 1 | ==== CALC ==== 2 | calc(9, 0) -> 9 3 | calc(8, 1) -> 9 4 | calc(7, 2) -> 9 5 | calc(6, 3) -> 9 6 | calc(5, 4) -> 20 7 | calc(4, 5) -> 20 8 | calc(3, 6) -> 18 9 | calc(2, 7) -> 14 10 | calc(1, 8) -> 8 11 | calc(0, 9) -> 0 12 | 13 | ==== PRINT ==== 14 | hi world! 15 | hi world! 16 | hi world! 17 | hi world! 18 | hi world! 19 | hi world! 20 | hi world! 21 | hi world! 22 | hi world! 23 | hi world! 24 | hello world! 25 | hello world! 26 | hello world! 27 | hello world! 28 | hello world! 29 | hello world! 30 | hello world! 31 | hello world! 32 | hello world! 33 | hello world! 34 | 'sup world! 35 | 'sup world! 36 | 'sup world! 37 | 'sup world! 38 | 'sup world! 39 | 'sup world! 40 | 'sup world! 41 | 'sup world! 42 | 'sup world! 43 | 'sup world! 44 | 45 | ============================= REPORT CSV FLUSH ================================ 46 | id, id_type, name, whamm_type, wasm_type, script_id, fid:pc, probe_id, value(s) 47 | 4, memaddr, count, u32, i32, script0, 30:262, 0_wasm:opcode:call:before, 0 48 | 31, memaddr, count, u32, i32, script0, 30:275, 0_wasm:opcode:call:before, 1 49 | 58, memaddr, count, u32, i32, script0, 30:288, 0_wasm:opcode:call:before, 0 50 | 85, memaddr, count, u32, i32, script0, 30:319, 0_wasm:opcode:call:before, 2 -------------------------------------------------------------------------------- /tests/scripts/core_suite/calls-monitor_rewriting/expected/wizard/basic-alloc-rust.mm.exp: -------------------------------------------------------------------------------- 1 | ==== CALC ==== 2 | calc(9, 0) -> 9 3 | calc(8, 1) -> 9 4 | calc(7, 2) -> 9 5 | calc(6, 3) -> 9 6 | calc(5, 4) -> 20 7 | calc(4, 5) -> 20 8 | calc(3, 6) -> 18 9 | calc(2, 7) -> 14 10 | calc(1, 8) -> 8 11 | calc(0, 9) -> 0 12 | 13 | ==== PRINT ==== 14 | hi world! 15 | hi world! 16 | hi world! 17 | hi world! 18 | hi world! 19 | hi world! 20 | hi world! 21 | hi world! 22 | hi world! 23 | hi world! 24 | hello world! 25 | hello world! 26 | hello world! 27 | hello world! 28 | hello world! 29 | hello world! 30 | hello world! 31 | hello world! 32 | hello world! 33 | hello world! 34 | 'sup world! 35 | 'sup world! 36 | 'sup world! 37 | 'sup world! 38 | 'sup world! 39 | 'sup world! 40 | 'sup world! 41 | 'sup world! 42 | 'sup world! 43 | 'sup world! 44 | 45 | ============================= REPORT CSV FLUSH ================================ 46 | id, id_type, name, whamm_type, wasm_type, script_id, fid:pc, probe_id, value(s) 47 | 3, global_id, count, u32, i32, script0, 30:256, 0_wasm:opcode:call:before, 0 48 | 4, global_id, count, u32, i32, script0, 30:269, 0_wasm:opcode:call:before, 1 49 | 5, global_id, count, u32, i32, script0, 30:282, 0_wasm:opcode:call:before, 0 50 | 6, global_id, count, u32, i32, script0, 30:313, 0_wasm:opcode:call:before, 2 -------------------------------------------------------------------------------- /tests/scripts/core_suite/numerics/app/basic_operations-skip_ExprFolder.mm.app: -------------------------------------------------------------------------------- 1 | tests/apps/core_suite/handwritten/for_numerics-skip_ExprFolder.wasm -------------------------------------------------------------------------------- /tests/scripts/core_suite/numerics/app/basic_operations.mm.app: -------------------------------------------------------------------------------- 1 | tests/apps/core_suite/handwritten/for_numerics.wasm -------------------------------------------------------------------------------- /tests/scripts/core_suite/numerics/app/floats-skip_ExprFolder.mm.app: -------------------------------------------------------------------------------- 1 | tests/apps/core_suite/handwritten/for_numerics-skip_ExprFolder.wasm -------------------------------------------------------------------------------- /tests/scripts/core_suite/numerics/app/floats.mm.app: -------------------------------------------------------------------------------- 1 | tests/apps/core_suite/handwritten/for_numerics.wasm -------------------------------------------------------------------------------- /tests/scripts/core_suite/numerics/app/ints_signed-skip_ExprFolder.mm.app: -------------------------------------------------------------------------------- 1 | tests/apps/core_suite/handwritten/for_numerics-skip_ExprFolder.wasm -------------------------------------------------------------------------------- /tests/scripts/core_suite/numerics/app/ints_signed.mm.app: -------------------------------------------------------------------------------- 1 | tests/apps/core_suite/handwritten/for_numerics.wasm -------------------------------------------------------------------------------- /tests/scripts/core_suite/numerics/app/ints_unsigned-skip_ExprFolder.mm.app: -------------------------------------------------------------------------------- 1 | tests/apps/core_suite/handwritten/for_numerics-skip_ExprFolder.wasm -------------------------------------------------------------------------------- /tests/scripts/core_suite/numerics/app/ints_unsigned.mm.app: -------------------------------------------------------------------------------- 1 | tests/apps/core_suite/handwritten/for_numerics.wasm -------------------------------------------------------------------------------- /tests/scripts/core_suite/numerics/app/mixed_types-skip_ExprFolder.mm.app: -------------------------------------------------------------------------------- 1 | tests/apps/core_suite/handwritten/for_numerics-skip_ExprFolder.wasm -------------------------------------------------------------------------------- /tests/scripts/core_suite/numerics/app/mixed_types.mm.app: -------------------------------------------------------------------------------- 1 | tests/apps/core_suite/handwritten/for_numerics.wasm -------------------------------------------------------------------------------- /tests/scripts/error/bad.mm: -------------------------------------------------------------------------------- 1 | wasm:bytecode:call:altm { } -------------------------------------------------------------------------------- /tests/scripts/fault_injection/dfinity/dfinity_async_strcmp_fn.mm: -------------------------------------------------------------------------------- 1 | /* 2 | * This will perform an asynchronous fault in Dfinity (redirect call to fault_injector canister endpoint). 3 | */ 4 | wasm::call(arg0: i32, arg1: i32, arg2: i32, arg3: i32):alt / 5 | target_fn_type == "import" && 6 | target_imp_module == "ic0" && 7 | target_fn_name == "call_new" && 8 | strcmp((arg0, arg1), "bookings") && 9 | strcmp((arg2, arg3), "record") 10 | / { 11 | alt_call_by_name("instr_redirect_to_fault_injector"); 12 | } 13 | -------------------------------------------------------------------------------- /tests/scripts/fault_injection/dfinity/dfinity_dei-integration.mm.TODO: -------------------------------------------------------------------------------- 1 | /* 2 | * TODO -- this script should interface with Chris' DEI server to determine if a fault should be injected at some point. 3 | * Instrument all calls to call_new and call_perform, get metadata to ID the RPC, pass this to the DEI server. 4 | * Eventually will collect enough information to generate fault scenarios. 5 | * SEE: https://github.com/filibuster-testing 6 | * Docker Image: https://hub.docker.com/layers/filibustertesting/filibuster/0.34/images/sha256-4732074f7abf9b6a07a30e33b83d7196f4976e27deccbad05555e0038f594d12?context=explore 7 | * Use of image: https://github.com/filibuster-testing/filibuster-java-instrumentation/blob/e3d8d247825b7192ff6d939c76d96b134747dcc1/src/main/java/cloud/filibuster/junit/server/backends/FilibusterDockerServerBackend.java#L24 8 | * API: 9 | * - https://github.com/filibuster-testing/filibuster-java-instrumentation/blob/main/src/main/java/cloud/filibuster/junit/server/local/FilibusterServer.java 10 | * - https://github.com/filibuster-testing/filibuster-java-instrumentation/blob/main/src/main/java/cloud/filibuster/junit/server/FilibusterServerAPI.java 11 | */ -------------------------------------------------------------------------------- /tests/scripts/fault_injection/dfinity/dfinity_sync-with-pred.mm.TODO: -------------------------------------------------------------------------------- 1 | /* 2 | * This will perform a synchronous fault in Dfinity (return non-zero on call_perform). 3 | */ 4 | 5 | char canister_name 6 | char endpoint 7 | 8 | /* 9 | * Collect information about what the target canister/endpoint is! 10 | * call_new args: (callee_src, callee_size, name_src, name_size, reply_fun, reply_env, reject_fun, reject_env) 11 | */ 12 | fault_injection:ic0:call_new:before { 13 | canister_name = copy(arg0, arg1); // calling library: copy(src, len) 14 | endpoint = copy(arg2, arg3); // calling library: copy(src, len) 15 | } 16 | 17 | /* 18 | * Use collected information (above) to conditionally inject a synchronous fault. 19 | */ 20 | fault_injection:ic0:call_perform:alt / (canister_name == "bookings") && (endpoint == "record") / { 21 | inject_synchronous_fault; 22 | } -------------------------------------------------------------------------------- /tests/scripts/fault_injection/dfinity/dfinity_sync.mm: -------------------------------------------------------------------------------- 1 | /* 2 | * This will perform a synchronous fault in Dfinity (return non-zero on call_perform). 3 | * NOTE: This will instrument and fail EVERY call_perform as there is no predicate on 4 | * the target canister, to add granularity, another probe on call_new will need 5 | * to be added to collect call site/target canister info. 6 | * See file: `dfinity_sync-with-pred.d` 7 | */ 8 | wasm:opcode:call:alt / 9 | target_fn_type == "import" && 10 | target_imp_module == "ic0" && 11 | target_fn_name == "call_perform" 12 | / { 13 | alt_call_by_name("instr_inject_synchronous_fault"); 14 | } -------------------------------------------------------------------------------- /tests/scripts/fault_injection/spin/filibuster-with-spin.mm.TODO: -------------------------------------------------------------------------------- 1 | use fi; 2 | 3 | wasi:http:call:alt { 4 | // Call WASI HTTP with new arguments that redirect to Filibuster 5 | fi.create_fb_args(); 6 | whamm.call_orig_instr(); 7 | 8 | // Collect Filibuster's response 9 | i32 fb_resp = fi.get_fb_resp(); 10 | 11 | // Check if Filibuster said to inject a fault. 12 | // If it returned a fault, leave it on the stack to propagate through the program. 13 | // If it did not return a fault, call the original endpoint with the original args. 14 | if (fi.is_fault(fb_resp)) { 15 | // Leave Filibuster's response on the stack 16 | fb_resp; 17 | } else { 18 | // Call the original endpoint with the original arguments 19 | whamm.orig_params(); 20 | whamm.call_orig_instr(); 21 | } 22 | } -------------------------------------------------------------------------------- /tests/scripts/functionality_test/dfinity_testing_access_global_after.mm: -------------------------------------------------------------------------------- 1 | bool i; 2 | wasm:bytecode:call:after / 3 | target_fn_type == "import" && 4 | target_imp_module == "ic0" && 5 | target_fn_name == "call_new" 6 | / { 7 | i = 0; 8 | } -------------------------------------------------------------------------------- /tests/scripts/functionality_test/dfinity_testing_access_global_before.mm: -------------------------------------------------------------------------------- 1 | bool i; 2 | 3 | wasm:bytecode:call:before / 4 | target_fn_type == "import" && 5 | target_imp_module == "ic0" && 6 | target_fn_name == "call_new" 7 | / { 8 | i = 0; 9 | } -------------------------------------------------------------------------------- /tests/scripts/functionality_test/dfinity_testing_var_init.mm: -------------------------------------------------------------------------------- 1 | wasm:bytecode:call:after / 2 | target_fn_type == "import" && 3 | target_imp_module == "ic0" && 4 | target_fn_name == "call_perform" 5 | / { 6 | var i: i32; 7 | i = 0; 8 | i++; 9 | } -------------------------------------------------------------------------------- /tests/scripts/instr.mm: -------------------------------------------------------------------------------- 1 | var i: i32; 2 | wasm:opcode:call:before { 3 | i = 10; 4 | } -------------------------------------------------------------------------------- /tests/scripts/lang_features/report_and_alloc_vars.mm: -------------------------------------------------------------------------------- 1 | wasm:opcode:call:before { 2 | unshared var count: i32; 3 | report var rep_count; 4 | 5 | count++; 6 | 7 | rep_count = count; 8 | } 9 | -------------------------------------------------------------------------------- /tests/scripts/paper_eval/branches/app/branches-hw.mm.app: -------------------------------------------------------------------------------- 1 | tests/apps/core_suite/handwritten/branches.wasm -------------------------------------------------------------------------------- /tests/scripts/paper_eval/branches/app/branches-ostrich.mm.app: -------------------------------------------------------------------------------- 1 | tests/apps/core_suite/ostrich/nw.wasm -------------------------------------------------------------------------------- /tests/scripts/paper_eval/branches/app/branches-polybench.mm.app: -------------------------------------------------------------------------------- 1 | tests/apps/core_suite/polybench/2mm.wasm -------------------------------------------------------------------------------- /tests/scripts/paper_eval/branches/app/branches-rust.mm.app: -------------------------------------------------------------------------------- 1 | tests/apps/core_suite/rust/cf.wasm -------------------------------------------------------------------------------- /tests/scripts/paper_eval/branches/app/branches-subset.mm.app: -------------------------------------------------------------------------------- 1 | tests/apps/core_suite/handwritten/branches-no-br_table.wasm -------------------------------------------------------------------------------- /tests/scripts/paper_eval/branches/branches-hw.mm: -------------------------------------------------------------------------------- 1 | // Matches _if and br_if events 2 | wasm::*if:before { 3 | report unshared var taken: u32; 4 | report unshared var total: u32; 5 | 6 | // which branch was taken? 7 | var was_taken: bool = arg0 != 0; 8 | taken = taken + (was_taken as u32); 9 | total++; 10 | } 11 | 12 | wasm::br_table:before { 13 | report unshared var taken_branches: map; 14 | 15 | // which branch was taken? 16 | // default branch is at 'num_targets' in the map 17 | var index: u32 = arg0 <= (num_targets - 1) ? arg0 : num_targets; 18 | 19 | // count stores an array of counters 20 | taken_branches[index]++; 21 | } 22 | 23 | wasm::select(arg0: i32):before { 24 | report unshared var selected_first: u32; 25 | report unshared var total: u32; 26 | 27 | // which branch was taken? 28 | var was_taken: bool = arg0 != 0; 29 | selected_first = selected_first + (was_taken as u32); 30 | total++; 31 | } 32 | -------------------------------------------------------------------------------- /tests/scripts/paper_eval/branches/branches-ostrich.mm: -------------------------------------------------------------------------------- 1 | // Matches _if and br_if events 2 | wasm::*if:before { 3 | report unshared var taken: i32; 4 | report unshared var not_taken: i32; 5 | 6 | // which branch was taken? 7 | if (arg0 != 0) { 8 | taken++; 9 | } else { 10 | not_taken++; 11 | } 12 | } 13 | 14 | wasm::br_table:before { 15 | report unshared var taken_branches: map; 16 | 17 | // which branch was taken? 18 | // default branch is at 'num_targets' in the map 19 | var index: u32 = arg0 <= (num_targets - 1) ? arg0 : num_targets; 20 | 21 | // count stores an array of counters 22 | taken_branches[index]++; 23 | } 24 | 25 | wasm::select(arg0: i32):before { 26 | report unshared var selected_first: u32; 27 | report unshared var selected_second: u32; 28 | 29 | // which branch was taken? 30 | if (arg0 != 0) { 31 | selected_first++; 32 | } else { 33 | selected_second++; 34 | } 35 | } -------------------------------------------------------------------------------- /tests/scripts/paper_eval/branches/branches-polybench.mm: -------------------------------------------------------------------------------- 1 | // Matches _if and br_if events 2 | wasm::*if:before { 3 | report unshared var taken: i32; 4 | report unshared var not_taken: i32; 5 | 6 | // which branch was taken? 7 | if (arg0 != 0) { 8 | taken++; 9 | } else { 10 | not_taken++; 11 | } 12 | } 13 | 14 | wasm::br_table:before { 15 | report unshared var taken_branches: map; 16 | 17 | // which branch was taken? 18 | // default branch is at 'num_targets' in the map 19 | var index: u32 = arg0 <= (num_targets - 1) ? arg0 : num_targets; 20 | 21 | // count stores an array of counters 22 | taken_branches[index]++; 23 | } 24 | 25 | wasm::select(arg0: i32):before { 26 | report unshared var selected_first: u32; 27 | report unshared var selected_second: u32; 28 | 29 | // which branch was taken? 30 | if (arg0 != 0) { 31 | selected_first++; 32 | } else { 33 | selected_second++; 34 | } 35 | } -------------------------------------------------------------------------------- /tests/scripts/paper_eval/branches/branches-rust.mm: -------------------------------------------------------------------------------- 1 | // Matches _if and br_if events 2 | wasm::*if:before { 3 | report unshared var taken: i32; 4 | report unshared var not_taken: i32; 5 | 6 | // which branch was taken? 7 | if (arg0 != 0) { 8 | taken++; 9 | } else { 10 | not_taken++; 11 | } 12 | } 13 | 14 | wasm::br_table:before { 15 | report unshared var taken_branches: map; 16 | 17 | // which branch was taken? 18 | // default branch is at 'num_targets' in the map 19 | var index: u32 = arg0 <= (num_targets - 1) ? arg0 : num_targets; 20 | 21 | // count stores an array of counters 22 | taken_branches[index]++; 23 | } 24 | 25 | wasm::select(arg0: i32):before { 26 | report unshared var selected_first: u32; 27 | report unshared var selected_second: u32; 28 | 29 | // which branch was taken? 30 | if (arg0 != 0) { 31 | selected_first++; 32 | } else { 33 | selected_second++; 34 | } 35 | } -------------------------------------------------------------------------------- /tests/scripts/paper_eval/branches/branches-subset.mm: -------------------------------------------------------------------------------- 1 | // Matches _if and br_if events 2 | wasm::*if:before { 3 | report unshared var taken: i32; 4 | report unshared var not_taken: i32; 5 | 6 | // which branch was taken? 7 | if (arg0 != 0) { 8 | taken++; 9 | } else { 10 | not_taken++; 11 | } 12 | } 13 | 14 | wasm::br_table:before { 15 | report unshared var taken_branches: map; 16 | 17 | // which branch was taken? 18 | // default branch is at 'num_targets' in the map 19 | var index: u32 = arg0 <= (num_targets - 1) ? arg0 : num_targets; 20 | 21 | // count stores an array of counters 22 | taken_branches[index]++; 23 | } 24 | 25 | wasm::select(arg0: i32):before { 26 | report unshared var selected_first: u32; 27 | report unshared var selected_second: u32; 28 | 29 | // which branch was taken? 30 | if (arg0 != 0) { 31 | selected_first++; 32 | } else { 33 | selected_second++; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /tests/scripts/paper_eval/branches/expected/rewriting/branches-hw.mm.exp: -------------------------------------------------------------------------------- 1 | ============================= REPORT CSV FLUSH ================================ 2 | id, id_type, name, whamm_type, wasm_type, script_id, fid:pc, probe_id, value(s) 3 | 4, memaddr, taken, u32, i32, script0, 0:5, 1_wasm:opcode:br_if:before, 0 4 | 31, memaddr, total, u32, i32, script0, 0:5, 1_wasm:opcode:br_if:before, 1 5 | 58, memaddr, taken, u32, i32, script0, 1:6, 1_wasm:opcode:br_if:before, 1 6 | 85, memaddr, total, u32, i32, script0, 1:6, 1_wasm:opcode:br_if:before, 4 7 | 112, memaddr, taken, u32, i32, script0, 1:10, 1_wasm:opcode:br_if:before, 1 8 | 139, memaddr, total, u32, i32, script0, 1:10, 1_wasm:opcode:br_if:before, 3 9 | 193, memaddr, taken, u32, i32, script0, 3:3, 0_wasm:opcode:if:before, 0 10 | 220, memaddr, total, u32, i32, script0, 3:3, 0_wasm:opcode:if:before, 1 11 | 247, memaddr, selected_first, u32, i32, script0, 4:4, 3_wasm:opcode:select:before, 1 12 | 274, memaddr, total, u32, i32, script0, 4:4, 3_wasm:opcode:select:before, 1 13 | 166, memaddr, taken_branches, map, i32, script0, 2:4, 2_wasm:opcode:br_table:before, 0->1;1->1;2->1 -------------------------------------------------------------------------------- /tests/scripts/paper_eval/branches/expected/rewriting/branches-subset.mm.exp: -------------------------------------------------------------------------------- 1 | ============================= REPORT CSV FLUSH ================================ 2 | id, id_type, name, whamm_type, wasm_type, script_id, fid:pc, probe_id, value(s) 3 | 220, memaddr, selected_first, u32, i32, script0, 3:4, 3_wasm:opcode:select:before, 1 4 | 247, memaddr, selected_second, u32, i32, script0, 3:4, 3_wasm:opcode:select:before, 0 5 | 4, memaddr, taken, i32, i32, script0, 0:5, 1_wasm:opcode:br_if:before, 0 6 | 31, memaddr, not_taken, i32, i32, script0, 0:5, 1_wasm:opcode:br_if:before, 1 7 | 58, memaddr, taken, i32, i32, script0, 1:6, 1_wasm:opcode:br_if:before, 1 8 | 85, memaddr, not_taken, i32, i32, script0, 1:6, 1_wasm:opcode:br_if:before, 3 9 | 112, memaddr, taken, i32, i32, script0, 1:10, 1_wasm:opcode:br_if:before, 1 10 | 139, memaddr, not_taken, i32, i32, script0, 1:10, 1_wasm:opcode:br_if:before, 2 11 | 166, memaddr, taken, i32, i32, script0, 2:3, 0_wasm:opcode:if:before, 0 12 | 193, memaddr, not_taken, i32, i32, script0, 2:3, 0_wasm:opcode:if:before, 1 -------------------------------------------------------------------------------- /tests/scripts/paper_eval/branches/expected/wizard/branches-hw.mm.exp: -------------------------------------------------------------------------------- 1 | ============================= REPORT CSV FLUSH ================================ 2 | id, id_type, name, whamm_type, wasm_type, script_id, fid:pc, probe_id, value(s) 3 | 323, memaddr, taken, u32, i32, script0, 0:10, 1_wasm:opcode:br_if, 0 4 | 350, memaddr, total, u32, i32, script0, 0:10, 1_wasm:opcode:br_if, 1 5 | 377, memaddr, taken, u32, i32, script0, 1:12, 1_wasm:opcode:br_if, 1 6 | 404, memaddr, total, u32, i32, script0, 1:12, 1_wasm:opcode:br_if, 4 7 | 431, memaddr, taken, u32, i32, script0, 1:19, 1_wasm:opcode:br_if, 1 8 | 458, memaddr, total, u32, i32, script0, 1:19, 1_wasm:opcode:br_if, 3 9 | 512, memaddr, taken, u32, i32, script0, 3:6, 0_wasm:opcode:if, 0 10 | 539, memaddr, total, u32, i32, script0, 3:6, 0_wasm:opcode:if, 1 11 | 566, memaddr, selected_first, u32, i32, script0, 4:8, 3_wasm:opcode:select, 1 12 | 593, memaddr, total, u32, i32, script0, 4:8, 3_wasm:opcode:select, 1 13 | 485, memaddr, taken_branches, map, i32, script0, 2:9, 2_wasm:opcode:br_table, 0->1;1->1;2->1 -------------------------------------------------------------------------------- /tests/scripts/paper_eval/branches/expected/wizard/branches-subset.mm.exp: -------------------------------------------------------------------------------- 1 | ============================= REPORT CSV FLUSH ================================ 2 | id, id_type, name, whamm_type, wasm_type, script_id, fid:pc, probe_id, value(s) 3 | 558, memaddr, selected_first, u32, i32, script0, 3:8, 3_wasm:opcode:select, 1 4 | 585, memaddr, selected_second, u32, i32, script0, 3:8, 3_wasm:opcode:select, 0 5 | 342, memaddr, taken, i32, i32, script0, 0:10, 1_wasm:opcode:br_if, 0 6 | 369, memaddr, not_taken, i32, i32, script0, 0:10, 1_wasm:opcode:br_if, 1 7 | 396, memaddr, taken, i32, i32, script0, 1:12, 1_wasm:opcode:br_if, 1 8 | 423, memaddr, not_taken, i32, i32, script0, 1:12, 1_wasm:opcode:br_if, 3 9 | 450, memaddr, taken, i32, i32, script0, 1:19, 1_wasm:opcode:br_if, 1 10 | 477, memaddr, not_taken, i32, i32, script0, 1:19, 1_wasm:opcode:br_if, 2 11 | 504, memaddr, taken, i32, i32, script0, 2:6, 0_wasm:opcode:if, 0 12 | 531, memaddr, not_taken, i32, i32, script0, 2:6, 0_wasm:opcode:if, 1 -------------------------------------------------------------------------------- /tests/scripts/paper_eval/cache_sim/app/cache_sim-clang.mm.app: -------------------------------------------------------------------------------- 1 | tests/apps/core_suite/clang/malloc_init.wasm -------------------------------------------------------------------------------- /tests/scripts/paper_eval/cache_sim/app/cache_sim-hw.mm.app: -------------------------------------------------------------------------------- 1 | tests/apps/core_suite/handwritten/mem-ops.wasm -------------------------------------------------------------------------------- /tests/scripts/paper_eval/cache_sim/cache_sim-clang.mm: -------------------------------------------------------------------------------- 1 | // ================== 2 | // ---- CacheSim ---- 3 | // ================== 4 | 5 | // CacheSim: instruments memory accesses and simulates a cache attached to the memory. 6 | 7 | use cache; 8 | 9 | wasm:opcode:*load*|*store*:before { 10 | report var hit: u32; 11 | report var miss: u32; 12 | 13 | var result: i32 = cache.check_access(effective_addr as i32, data_size as i32); 14 | var num_hits: i32 = (result & 0xFFFF0000) >> 16; 15 | var num_misses: i32 = (result & 0x0000FFFF); 16 | 17 | hit = hit + (num_hits as u32); 18 | miss = miss + (num_misses as u32); 19 | } -------------------------------------------------------------------------------- /tests/scripts/paper_eval/cache_sim/cache_sim-hw.mm: -------------------------------------------------------------------------------- 1 | // ================== 2 | // ---- CacheSim ---- 3 | // ================== 4 | 5 | // CacheSim: instruments memory accesses and simulates a cache attached to the memory. 6 | 7 | use cache; 8 | 9 | wasm:opcode:*load*|*store*:before { 10 | report var hit: u32; 11 | report var miss: u32; 12 | 13 | var result: i32 = cache.check_access(effective_addr as i32, data_size as i32); 14 | var num_hits: i32 = (result & 0xFFFF0000) >> 16; 15 | var num_misses: i32 = (result & 0x0000FFFF); 16 | 17 | hit = hit + (num_hits as u32); 18 | miss = miss + (num_misses as u32); 19 | } -------------------------------------------------------------------------------- /tests/scripts/paper_eval/cache_sim/expected/rewriting/cache_sim-hw.mm.exp: -------------------------------------------------------------------------------- 1 | ============================= REPORT CSV FLUSH ================================ 2 | id, id_type, name, whamm_type, wasm_type, script_id, fid:pc, probe_id, value(s) 3 | 4, memaddr, hit, u32, i32, script0, 0:2, 15_wasm:opcode:i64.store:before, 0 4 | 31, memaddr, miss, u32, i32, script0, 0:2, 15_wasm:opcode:i64.store:before, 1 5 | 58, memaddr, hit, u32, i32, script0, 0:4, 0_wasm:opcode:i32.load:before, 1 6 | 85, memaddr, miss, u32, i32, script0, 0:4, 0_wasm:opcode:i32.load:before, 0 7 | 112, memaddr, hit, u32, i32, script0, 0:5, 0_wasm:opcode:i32.load:before, 1 8 | 139, memaddr, miss, u32, i32, script0, 0:5, 0_wasm:opcode:i32.load:before, 0 -------------------------------------------------------------------------------- /tests/scripts/paper_eval/cache_sim/expected/wizard/cache_sim-hw.mm.exp: -------------------------------------------------------------------------------- 1 | ============================= REPORT CSV FLUSH ================================ 2 | id, id_type, name, whamm_type, wasm_type, script_id, fid:pc, probe_id, value(s) 3 | 1226, memaddr, hit, u32, i32, script0, 0:5, 15_wasm:opcode:i64.store, 0 4 | 1253, memaddr, miss, u32, i32, script0, 0:5, 15_wasm:opcode:i64.store, 1 5 | 1280, memaddr, hit, u32, i32, script0, 0:10, 0_wasm:opcode:i32.load, 1 6 | 1307, memaddr, miss, u32, i32, script0, 0:10, 0_wasm:opcode:i32.load, 0 7 | 1334, memaddr, hit, u32, i32, script0, 0:13, 0_wasm:opcode:i32.load, 1 8 | 1361, memaddr, miss, u32, i32, script0, 0:13, 0_wasm:opcode:i32.load, 0 -------------------------------------------------------------------------------- /tests/scripts/paper_eval/cache_sim/libs/cache_sim-clang.mm.libs: -------------------------------------------------------------------------------- 1 | cache=user_libs/cache/target/wasm32-wasip1/release/cache.wasm -------------------------------------------------------------------------------- /tests/scripts/paper_eval/cache_sim/libs/cache_sim-hw.mm.libs: -------------------------------------------------------------------------------- 1 | cache=user_libs/cache/target/wasm32-wasip1/release/cache.wasm -------------------------------------------------------------------------------- /tests/scripts/paper_eval/categories/app/category-hw.mm.app: -------------------------------------------------------------------------------- 1 | tests/apps/core_suite/handwritten/branches.wasm -------------------------------------------------------------------------------- /tests/scripts/paper_eval/categories/app/category-rust.mm.app: -------------------------------------------------------------------------------- 1 | tests/apps/core_suite/rust/cf.wasm -------------------------------------------------------------------------------- /tests/scripts/paper_eval/categories/app/category_as_allocs-hw.mm.app: -------------------------------------------------------------------------------- 1 | tests/apps/core_suite/handwritten/branches.wasm -------------------------------------------------------------------------------- /tests/scripts/paper_eval/categories/app/category_as_allocs-rust.mm.app: -------------------------------------------------------------------------------- 1 | tests/apps/core_suite/rust/cf.wasm -------------------------------------------------------------------------------- /tests/scripts/paper_eval/categories/app/category_fastest-hw.mm.app: -------------------------------------------------------------------------------- 1 | tests/apps/core_suite/handwritten/branches.wasm -------------------------------------------------------------------------------- /tests/scripts/paper_eval/categories/app/category_fastest-rust.mm.app: -------------------------------------------------------------------------------- 1 | tests/apps/core_suite/rust/cf.wasm -------------------------------------------------------------------------------- /tests/scripts/paper_eval/categories/category-hw.mm: -------------------------------------------------------------------------------- 1 | report var dyn_categories: map; 2 | 3 | wasm:opcode:*:before { 4 | dyn_categories[category_id]++; 5 | } -------------------------------------------------------------------------------- /tests/scripts/paper_eval/categories/category-rust.mm: -------------------------------------------------------------------------------- 1 | report var dyn_categories: map; 2 | 3 | wasm:opcode:*:before { 4 | dyn_categories[category_id]++; 5 | } -------------------------------------------------------------------------------- /tests/scripts/paper_eval/categories/expected/rewriting/category-hw.mm.exp: -------------------------------------------------------------------------------- 1 | ============================= REPORT CSV FLUSH ================================ 2 | id, id_type, name, whamm_type, wasm_type, script_id, fid:pc, probe_id, value(s) 3 | 0, map_id, dyn_categories, map, i32, script0, , , 0->4;2->10;3->30;4->58;8->9;10->13;12->5 -------------------------------------------------------------------------------- /tests/scripts/paper_eval/categories/expected/rewriting/category-rust.mm.exp: -------------------------------------------------------------------------------- 1 | ==== CALC ==== 2 | calc(9, 0) -> 9 3 | calc(8, 1) -> 9 4 | calc(7, 2) -> 9 5 | calc(6, 3) -> 9 6 | calc(5, 4) -> 20 7 | calc(4, 5) -> 20 8 | calc(3, 6) -> 18 9 | calc(2, 7) -> 14 10 | calc(1, 8) -> 8 11 | calc(0, 9) -> 0 12 | 13 | ==== PRINT ==== 14 | hi world! 15 | hi world! 16 | hi world! 17 | hi world! 18 | hi world! 19 | hi world! 20 | hi world! 21 | hi world! 22 | hi world! 23 | hi world! 24 | hello world! 25 | hello world! 26 | hello world! 27 | hello world! 28 | hello world! 29 | hello world! 30 | hello world! 31 | hello world! 32 | hello world! 33 | hello world! 34 | 'sup world! 35 | 'sup world! 36 | 'sup world! 37 | 'sup world! 38 | 'sup world! 39 | 'sup world! 40 | 'sup world! 41 | 'sup world! 42 | 'sup world! 43 | 'sup world! 44 | 45 | ============================= REPORT CSV FLUSH ================================ 46 | id, id_type, name, whamm_type, wasm_type, script_id, fid:pc, probe_id, value(s) 47 | 0, map_id, dyn_categories, map, i32, script0, , , 0->14160;2->5575;3->17583;4->24356;5->444;8->4582;9->7303;10->85339;12->204;15->10803 -------------------------------------------------------------------------------- /tests/scripts/paper_eval/categories/expected/rewriting/category_as_allocs-hw.mm.exp: -------------------------------------------------------------------------------- 1 | ============================= REPORT CSV FLUSH ================================ 2 | id, id_type, name, whamm_type, wasm_type, script_id, fid:pc, probe_id, value(s) 3 | 3, global_id, arith, u32, i32, script0, , , 4 4 | 4, global_id, atomic, u32, i32, script0, , , 0 5 | 5, global_id, compare, u32, i32, script0, , , 10 6 | 6, global_id, const, u32, i32, script0, , , 30 7 | 7, global_id, control, u32, i32, script0, , , 58 8 | 8, global_id, convert, u32, i32, script0, , , 0 9 | 9, global_id, exn, u32, i32, script0, , , 0 10 | 10, global_id, gc, u32, i32, script0, , , 0 11 | 11, global_id, global, u32, i32, script0, , , 9 12 | 12, global_id, load, u32, i32, script0, , , 0 13 | 13, global_id, local, u32, i32, script0, , , 13 14 | 14, global_id, mem, u32, i32, script0, , , 0 15 | 15, global_id, misc, u32, i32, script0, , , 5 16 | 16, global_id, ref, u32, i32, script0, , , 0 17 | 17, global_id, simd, u32, i32, script0, , , 0 18 | 18, global_id, store, u32, i32, script0, , , 0 19 | 19, global_id, table, u32, i32, script0, , , 0 -------------------------------------------------------------------------------- /tests/scripts/paper_eval/categories/expected/rewriting/category_as_allocs-rust.mm.exp: -------------------------------------------------------------------------------- 1 | ==== CALC ==== 2 | calc(9, 0) -> 9 3 | calc(8, 1) -> 9 4 | calc(7, 2) -> 9 5 | calc(6, 3) -> 9 6 | calc(5, 4) -> 20 7 | calc(4, 5) -> 20 8 | calc(3, 6) -> 18 9 | calc(2, 7) -> 14 10 | calc(1, 8) -> 8 11 | calc(0, 9) -> 0 12 | 13 | ==== PRINT ==== 14 | hi world! 15 | hi world! 16 | hi world! 17 | hi world! 18 | hi world! 19 | hi world! 20 | hi world! 21 | hi world! 22 | hi world! 23 | hi world! 24 | hello world! 25 | hello world! 26 | hello world! 27 | hello world! 28 | hello world! 29 | hello world! 30 | hello world! 31 | hello world! 32 | hello world! 33 | hello world! 34 | 'sup world! 35 | 'sup world! 36 | 'sup world! 37 | 'sup world! 38 | 'sup world! 39 | 'sup world! 40 | 'sup world! 41 | 'sup world! 42 | 'sup world! 43 | 'sup world! 44 | 45 | ============================= REPORT CSV FLUSH ================================ 46 | id, id_type, name, whamm_type, wasm_type, script_id, fid:pc, probe_id, value(s) 47 | 3, global_id, arith, u32, i32, script0, , , 14160 48 | 4, global_id, atomic, u32, i32, script0, , , 0 49 | 5, global_id, compare, u32, i32, script0, , , 5575 50 | 6, global_id, const, u32, i32, script0, , , 17583 51 | 7, global_id, control, u32, i32, script0, , , 24356 52 | 8, global_id, convert, u32, i32, script0, , , 444 53 | 9, global_id, exn, u32, i32, script0, , , 0 54 | 10, global_id, gc, u32, i32, script0, , , 0 55 | 11, global_id, global, u32, i32, script0, , , 4582 56 | 12, global_id, load, u32, i32, script0, , , 7303 57 | 13, global_id, local, u32, i32, script0, , , 85339 58 | 14, global_id, mem, u32, i32, script0, , , 0 59 | 15, global_id, misc, u32, i32, script0, , , 204 60 | 16, global_id, ref, u32, i32, script0, , , 0 61 | 17, global_id, simd, u32, i32, script0, , , 0 62 | 18, global_id, store, u32, i32, script0, , , 10803 63 | 19, global_id, table, u32, i32, script0, , , 0 -------------------------------------------------------------------------------- /tests/scripts/paper_eval/categories/expected/rewriting/category_fastest-hw.mm.exp: -------------------------------------------------------------------------------- 1 | ============================= REPORT CSV FLUSH ================================ 2 | id, id_type, name, whamm_type, wasm_type, script_id, fid:pc, probe_id, value(s) 3 | 3, global_id, arith, u32, i32, script0, , , 4 4 | 4, global_id, atomic, u32, i32, script0, , , 0 5 | 5, global_id, compare, u32, i32, script0, , , 10 6 | 6, global_id, const, u32, i32, script0, , , 30 7 | 7, global_id, control, u32, i32, script0, , , 58 8 | 8, global_id, convert, u32, i32, script0, , , 0 9 | 9, global_id, exn, u32, i32, script0, , , 0 10 | 10, global_id, gc, u32, i32, script0, , , 0 11 | 11, global_id, global, u32, i32, script0, , , 9 12 | 12, global_id, load, u32, i32, script0, , , 0 13 | 13, global_id, local, u32, i32, script0, , , 13 14 | 14, global_id, mem, u32, i32, script0, , , 0 15 | 15, global_id, misc, u32, i32, script0, , , 5 16 | 16, global_id, store, u32, i32, script0, , , 0 17 | 17, global_id, table, u32, i32, script0, , , 0 -------------------------------------------------------------------------------- /tests/scripts/paper_eval/categories/expected/rewriting/category_fastest-rust.mm.exp: -------------------------------------------------------------------------------- 1 | ==== CALC ==== 2 | calc(9, 0) -> 9 3 | calc(8, 1) -> 9 4 | calc(7, 2) -> 9 5 | calc(6, 3) -> 9 6 | calc(5, 4) -> 20 7 | calc(4, 5) -> 20 8 | calc(3, 6) -> 18 9 | calc(2, 7) -> 14 10 | calc(1, 8) -> 8 11 | calc(0, 9) -> 0 12 | 13 | ==== PRINT ==== 14 | hi world! 15 | hi world! 16 | hi world! 17 | hi world! 18 | hi world! 19 | hi world! 20 | hi world! 21 | hi world! 22 | hi world! 23 | hi world! 24 | hello world! 25 | hello world! 26 | hello world! 27 | hello world! 28 | hello world! 29 | hello world! 30 | hello world! 31 | hello world! 32 | hello world! 33 | hello world! 34 | 'sup world! 35 | 'sup world! 36 | 'sup world! 37 | 'sup world! 38 | 'sup world! 39 | 'sup world! 40 | 'sup world! 41 | 'sup world! 42 | 'sup world! 43 | 'sup world! 44 | 45 | ============================= REPORT CSV FLUSH ================================ 46 | id, id_type, name, whamm_type, wasm_type, script_id, fid:pc, probe_id, value(s) 47 | 3, global_id, arith, u32, i32, script0, , , 14160 48 | 4, global_id, atomic, u32, i32, script0, , , 0 49 | 5, global_id, compare, u32, i32, script0, , , 5575 50 | 6, global_id, const, u32, i32, script0, , , 17583 51 | 7, global_id, control, u32, i32, script0, , , 24356 52 | 8, global_id, convert, u32, i32, script0, , , 444 53 | 9, global_id, exn, u32, i32, script0, , , 0 54 | 10, global_id, gc, u32, i32, script0, , , 0 55 | 11, global_id, global, u32, i32, script0, , , 4582 56 | 12, global_id, load, u32, i32, script0, , , 7303 57 | 13, global_id, local, u32, i32, script0, , , 85339 58 | 14, global_id, mem, u32, i32, script0, , , 0 59 | 15, global_id, misc, u32, i32, script0, , , 204 60 | 16, global_id, store, u32, i32, script0, , , 10803 61 | 17, global_id, table, u32, i32, script0, , , 0 -------------------------------------------------------------------------------- /tests/scripts/paper_eval/categories/expected/wizard/category-hw.mm.exp: -------------------------------------------------------------------------------- 1 | ============================= REPORT CSV FLUSH ================================ 2 | id, id_type, name, whamm_type, wasm_type, script_id, fid:pc, probe_id, value(s) 3 | 0, map_id, dyn_categories, map, i32, script0, , , 0->4;2->10;3->30;4->68;8->9;10->13;12->5 -------------------------------------------------------------------------------- /tests/scripts/paper_eval/categories/expected/wizard/category-rust.mm.exp: -------------------------------------------------------------------------------- 1 | ==== CALC ==== 2 | calc(9, 0) -> 9 3 | calc(8, 1) -> 9 4 | calc(7, 2) -> 9 5 | calc(6, 3) -> 9 6 | calc(5, 4) -> 20 7 | calc(4, 5) -> 20 8 | calc(3, 6) -> 18 9 | calc(2, 7) -> 14 10 | calc(1, 8) -> 8 11 | calc(0, 9) -> 0 12 | 13 | ==== PRINT ==== 14 | hi world! 15 | hi world! 16 | hi world! 17 | hi world! 18 | hi world! 19 | hi world! 20 | hi world! 21 | hi world! 22 | hi world! 23 | hi world! 24 | hello world! 25 | hello world! 26 | hello world! 27 | hello world! 28 | hello world! 29 | hello world! 30 | hello world! 31 | hello world! 32 | hello world! 33 | hello world! 34 | 'sup world! 35 | 'sup world! 36 | 'sup world! 37 | 'sup world! 38 | 'sup world! 39 | 'sup world! 40 | 'sup world! 41 | 'sup world! 42 | 'sup world! 43 | 'sup world! 44 | 45 | ============================= REPORT CSV FLUSH ================================ 46 | id, id_type, name, whamm_type, wasm_type, script_id, fid:pc, probe_id, value(s) 47 | 0, map_id, dyn_categories, map, i32, script0, , , 0->14184;2->5586;3->17655;4->29901;5->444;8->4591;9->7323;10->85450;12->205;15->10826 -------------------------------------------------------------------------------- /tests/scripts/paper_eval/categories/expected/wizard/category_as_allocs-hw.mm.exp: -------------------------------------------------------------------------------- 1 | ============================= REPORT CSV FLUSH ================================ 2 | id, id_type, name, whamm_type, wasm_type, script_id, fid:pc, probe_id, value(s) 3 | 1, global_id, arith, u32, i32, script0, , , 4 4 | 2, global_id, atomic, u32, i32, script0, , , 0 5 | 3, global_id, compare, u32, i32, script0, , , 10 6 | 4, global_id, const, u32, i32, script0, , , 30 7 | 5, global_id, control, u32, i32, script0, , , 68 8 | 6, global_id, convert, u32, i32, script0, , , 0 9 | 7, global_id, exn, u32, i32, script0, , , 0 10 | 8, global_id, gc, u32, i32, script0, , , 0 11 | 9, global_id, global, u32, i32, script0, , , 9 12 | 10, global_id, load, u32, i32, script0, , , 0 13 | 11, global_id, local, u32, i32, script0, , , 13 14 | 12, global_id, mem, u32, i32, script0, , , 0 15 | 13, global_id, misc, u32, i32, script0, , , 5 16 | 14, global_id, ref, u32, i32, script0, , , 0 17 | 15, global_id, simd, u32, i32, script0, , , 0 18 | 16, global_id, store, u32, i32, script0, , , 0 19 | 17, global_id, table, u32, i32, script0, , , 0 -------------------------------------------------------------------------------- /tests/scripts/paper_eval/categories/expected/wizard/category_as_allocs-rust.mm.exp: -------------------------------------------------------------------------------- 1 | ==== CALC ==== 2 | calc(9, 0) -> 9 3 | calc(8, 1) -> 9 4 | calc(7, 2) -> 9 5 | calc(6, 3) -> 9 6 | calc(5, 4) -> 20 7 | calc(4, 5) -> 20 8 | calc(3, 6) -> 18 9 | calc(2, 7) -> 14 10 | calc(1, 8) -> 8 11 | calc(0, 9) -> 0 12 | 13 | ==== PRINT ==== 14 | hi world! 15 | hi world! 16 | hi world! 17 | hi world! 18 | hi world! 19 | hi world! 20 | hi world! 21 | hi world! 22 | hi world! 23 | hi world! 24 | hello world! 25 | hello world! 26 | hello world! 27 | hello world! 28 | hello world! 29 | hello world! 30 | hello world! 31 | hello world! 32 | hello world! 33 | hello world! 34 | 'sup world! 35 | 'sup world! 36 | 'sup world! 37 | 'sup world! 38 | 'sup world! 39 | 'sup world! 40 | 'sup world! 41 | 'sup world! 42 | 'sup world! 43 | 'sup world! 44 | 45 | ============================= REPORT CSV FLUSH ================================ 46 | id, id_type, name, whamm_type, wasm_type, script_id, fid:pc, probe_id, value(s) 47 | 1, global_id, arith, u32, i32, script0, , , 14184 48 | 2, global_id, atomic, u32, i32, script0, , , 0 49 | 3, global_id, compare, u32, i32, script0, , , 5586 50 | 4, global_id, const, u32, i32, script0, , , 17655 51 | 5, global_id, control, u32, i32, script0, , , 29901 52 | 6, global_id, convert, u32, i32, script0, , , 444 53 | 7, global_id, exn, u32, i32, script0, , , 0 54 | 8, global_id, gc, u32, i32, script0, , , 0 55 | 9, global_id, global, u32, i32, script0, , , 4591 56 | 10, global_id, load, u32, i32, script0, , , 7323 57 | 11, global_id, local, u32, i32, script0, , , 85450 58 | 12, global_id, mem, u32, i32, script0, , , 0 59 | 13, global_id, misc, u32, i32, script0, , , 205 60 | 14, global_id, ref, u32, i32, script0, , , 0 61 | 15, global_id, simd, u32, i32, script0, , , 0 62 | 16, global_id, store, u32, i32, script0, , , 10826 63 | 17, global_id, table, u32, i32, script0, , , 0 -------------------------------------------------------------------------------- /tests/scripts/paper_eval/categories/expected/wizard/category_fastest-hw.mm.exp: -------------------------------------------------------------------------------- 1 | ============================= REPORT CSV FLUSH ================================ 2 | id, id_type, name, whamm_type, wasm_type, script_id, fid:pc, probe_id, value(s) 3 | 1, global_id, arith, u32, i32, script0, , , 4 4 | 2, global_id, atomic, u32, i32, script0, , , 0 5 | 3, global_id, compare, u32, i32, script0, , , 10 6 | 4, global_id, const, u32, i32, script0, , , 30 7 | 5, global_id, control, u32, i32, script0, , , 68 8 | 6, global_id, convert, u32, i32, script0, , , 0 9 | 7, global_id, exn, u32, i32, script0, , , 0 10 | 8, global_id, gc, u32, i32, script0, , , 0 11 | 9, global_id, global, u32, i32, script0, , , 9 12 | 10, global_id, load, u32, i32, script0, , , 0 13 | 11, global_id, local, u32, i32, script0, , , 13 14 | 12, global_id, mem, u32, i32, script0, , , 0 15 | 13, global_id, misc, u32, i32, script0, , , 5 16 | 14, global_id, store, u32, i32, script0, , , 0 17 | 15, global_id, table, u32, i32, script0, , , 0 -------------------------------------------------------------------------------- /tests/scripts/paper_eval/categories/expected/wizard/category_fastest-rust.mm.exp: -------------------------------------------------------------------------------- 1 | ==== CALC ==== 2 | calc(9, 0) -> 9 3 | calc(8, 1) -> 9 4 | calc(7, 2) -> 9 5 | calc(6, 3) -> 9 6 | calc(5, 4) -> 20 7 | calc(4, 5) -> 20 8 | calc(3, 6) -> 18 9 | calc(2, 7) -> 14 10 | calc(1, 8) -> 8 11 | calc(0, 9) -> 0 12 | 13 | ==== PRINT ==== 14 | hi world! 15 | hi world! 16 | hi world! 17 | hi world! 18 | hi world! 19 | hi world! 20 | hi world! 21 | hi world! 22 | hi world! 23 | hi world! 24 | hello world! 25 | hello world! 26 | hello world! 27 | hello world! 28 | hello world! 29 | hello world! 30 | hello world! 31 | hello world! 32 | hello world! 33 | hello world! 34 | 'sup world! 35 | 'sup world! 36 | 'sup world! 37 | 'sup world! 38 | 'sup world! 39 | 'sup world! 40 | 'sup world! 41 | 'sup world! 42 | 'sup world! 43 | 'sup world! 44 | 45 | ============================= REPORT CSV FLUSH ================================ 46 | id, id_type, name, whamm_type, wasm_type, script_id, fid:pc, probe_id, value(s) 47 | 1, global_id, arith, u32, i32, script0, , , 14184 48 | 2, global_id, atomic, u32, i32, script0, , , 0 49 | 3, global_id, compare, u32, i32, script0, , , 5586 50 | 4, global_id, const, u32, i32, script0, , , 17655 51 | 5, global_id, control, u32, i32, script0, , , 29901 52 | 6, global_id, convert, u32, i32, script0, , , 444 53 | 7, global_id, exn, u32, i32, script0, , , 0 54 | 8, global_id, gc, u32, i32, script0, , , 0 55 | 9, global_id, global, u32, i32, script0, , , 4591 56 | 10, global_id, load, u32, i32, script0, , , 7323 57 | 11, global_id, local, u32, i32, script0, , , 85450 58 | 12, global_id, mem, u32, i32, script0, , , 0 59 | 13, global_id, misc, u32, i32, script0, , , 205 60 | 14, global_id, store, u32, i32, script0, , , 10826 61 | 15, global_id, table, u32, i32, script0, , , 0 -------------------------------------------------------------------------------- /tests/scripts/paper_eval/hotness/app/hotness-hw.mm.app: -------------------------------------------------------------------------------- 1 | tests/apps/core_suite/handwritten/branches.wasm -------------------------------------------------------------------------------- /tests/scripts/paper_eval/hotness/app/hotness-rust.mm.app: -------------------------------------------------------------------------------- 1 | tests/apps/core_suite/rust/cf.wasm -------------------------------------------------------------------------------- /tests/scripts/paper_eval/hotness/hotness-hw.mm: -------------------------------------------------------------------------------- 1 | wasm:opcode:*:before { 2 | report var count: u32; 3 | count++; 4 | } -------------------------------------------------------------------------------- /tests/scripts/paper_eval/hotness/hotness-rust.mm: -------------------------------------------------------------------------------- 1 | wasm:opcode:*:before { 2 | report var count: u32; 3 | count++; 4 | } -------------------------------------------------------------------------------- /tests/scripts/paper_eval/ins_count/app/ins_count-hw.mm.app: -------------------------------------------------------------------------------- 1 | tests/apps/core_suite/handwritten/branches.wasm -------------------------------------------------------------------------------- /tests/scripts/paper_eval/ins_count/app/ins_count-polybench.mm.app: -------------------------------------------------------------------------------- 1 | tests/apps/core_suite/polybench/2mm.wasm -------------------------------------------------------------------------------- /tests/scripts/paper_eval/ins_count/app/ins_count-rust.mm.app: -------------------------------------------------------------------------------- 1 | tests/apps/core_suite/rust/cf.wasm -------------------------------------------------------------------------------- /tests/scripts/paper_eval/ins_count/expected/rewriting/ins_count-hw.mm.exp: -------------------------------------------------------------------------------- 1 | ============================= REPORT CSV FLUSH ================================ 2 | id, id_type, name, whamm_type, wasm_type, script_id, fid:pc, probe_id, value(s) 3 | 3, global_id, count, u32, i32, script0, , , 129 -------------------------------------------------------------------------------- /tests/scripts/paper_eval/ins_count/expected/rewriting/ins_count-polybench.mm.exp: -------------------------------------------------------------------------------- 1 | ============================= REPORT CSV FLUSH ================================ 2 | id, id_type, name, whamm_type, wasm_type, script_id, fid:pc, probe_id, value(s) 3 | 2, global_id, count, u32, i32, script0, , , 363578021 -------------------------------------------------------------------------------- /tests/scripts/paper_eval/ins_count/expected/rewriting/ins_count-rust.mm.exp: -------------------------------------------------------------------------------- 1 | ==== CALC ==== 2 | calc(9, 0) -> 9 3 | calc(8, 1) -> 9 4 | calc(7, 2) -> 9 5 | calc(6, 3) -> 9 6 | calc(5, 4) -> 20 7 | calc(4, 5) -> 20 8 | calc(3, 6) -> 18 9 | calc(2, 7) -> 14 10 | calc(1, 8) -> 8 11 | calc(0, 9) -> 0 12 | 13 | ==== PRINT ==== 14 | hi world! 15 | hi world! 16 | hi world! 17 | hi world! 18 | hi world! 19 | hi world! 20 | hi world! 21 | hi world! 22 | hi world! 23 | hi world! 24 | hello world! 25 | hello world! 26 | hello world! 27 | hello world! 28 | hello world! 29 | hello world! 30 | hello world! 31 | hello world! 32 | hello world! 33 | hello world! 34 | 'sup world! 35 | 'sup world! 36 | 'sup world! 37 | 'sup world! 38 | 'sup world! 39 | 'sup world! 40 | 'sup world! 41 | 'sup world! 42 | 'sup world! 43 | 'sup world! 44 | 45 | ============================= REPORT CSV FLUSH ================================ 46 | id, id_type, name, whamm_type, wasm_type, script_id, fid:pc, probe_id, value(s) 47 | 3, global_id, count, u32, i32, script0, , , 170349 -------------------------------------------------------------------------------- /tests/scripts/paper_eval/ins_count/expected/wizard/ins_count-hw.mm.exp: -------------------------------------------------------------------------------- 1 | ============================= REPORT CSV FLUSH ================================ 2 | id, id_type, name, whamm_type, wasm_type, script_id, fid:pc, probe_id, value(s) 3 | 1, global_id, count, u32, i32, script0, , , 139 -------------------------------------------------------------------------------- /tests/scripts/paper_eval/ins_count/expected/wizard/ins_count-polybench.mm.exp: -------------------------------------------------------------------------------- 1 | ============================= REPORT CSV FLUSH ================================ 2 | id, id_type, name, whamm_type, wasm_type, script_id, fid:pc, probe_id, value(s) 3 | 1, global_id, count, u32, i32, script0, , , 369834696 -------------------------------------------------------------------------------- /tests/scripts/paper_eval/ins_count/expected/wizard/ins_count-rust.mm.exp: -------------------------------------------------------------------------------- 1 | ==== CALC ==== 2 | calc(9, 0) -> 9 3 | calc(8, 1) -> 9 4 | calc(7, 2) -> 9 5 | calc(6, 3) -> 9 6 | calc(5, 4) -> 20 7 | calc(4, 5) -> 20 8 | calc(3, 6) -> 18 9 | calc(2, 7) -> 14 10 | calc(1, 8) -> 8 11 | calc(0, 9) -> 0 12 | 13 | ==== PRINT ==== 14 | hi world! 15 | hi world! 16 | hi world! 17 | hi world! 18 | hi world! 19 | hi world! 20 | hi world! 21 | hi world! 22 | hi world! 23 | hi world! 24 | hello world! 25 | hello world! 26 | hello world! 27 | hello world! 28 | hello world! 29 | hello world! 30 | hello world! 31 | hello world! 32 | hello world! 33 | hello world! 34 | 'sup world! 35 | 'sup world! 36 | 'sup world! 37 | 'sup world! 38 | 'sup world! 39 | 'sup world! 40 | 'sup world! 41 | 'sup world! 42 | 'sup world! 43 | 'sup world! 44 | 45 | ============================= REPORT CSV FLUSH ================================ 46 | id, id_type, name, whamm_type, wasm_type, script_id, fid:pc, probe_id, value(s) 47 | 1, global_id, count, u32, i32, script0, , , 176165 -------------------------------------------------------------------------------- /tests/scripts/paper_eval/ins_count/ins_count-hw.mm: -------------------------------------------------------------------------------- 1 | report var count: u32; 2 | 3 | wasm:opcode:*:before { 4 | count++; 5 | } -------------------------------------------------------------------------------- /tests/scripts/paper_eval/ins_count/ins_count-polybench.mm: -------------------------------------------------------------------------------- 1 | report var count: u32; 2 | 3 | wasm:opcode:*:before { 4 | count++; 5 | } -------------------------------------------------------------------------------- /tests/scripts/paper_eval/ins_count/ins_count-rust.mm: -------------------------------------------------------------------------------- 1 | report var count: u32; 2 | 3 | wasm:opcode:*:before { 4 | count++; 5 | } -------------------------------------------------------------------------------- /tests/scripts/wizard_monitors/basic.mm: -------------------------------------------------------------------------------- 1 | var count: i32; 2 | 3 | wasm:opcode:call(arg0: i32):before / (fid == 3 && pc != 2) / { 4 | if (arg0 == 1) { 5 | count++; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /tests/scripts/wizard_monitors/branch-allocs.mm: -------------------------------------------------------------------------------- 1 | /* Facts: 2 | * Bytecode names are probe types 3 | * Bound variables 4 | * - probe_func : (whamm standard) is the Wasm function 5 | * - tos : Wasm top-of-stack 6 | * - pc : Wasm program counter 7 | * - local0...N : Wasm locals 8 | * - 9 | * need to access top-of-stack, locals, program counter 10 | * need a handle to the function ("func") 11 | */ 12 | 13 | wasm::br:before { 14 | unshared var taken: i32; 15 | // branch always taken for `br` 16 | // count stores an array of counters 17 | taken++; 18 | } 19 | 20 | wasm::br_if:before { 21 | unshared var taken: i32; 22 | unshared var not_taken: i32; 23 | 24 | // which branch was taken? 25 | if (arg0 != 0) { 26 | taken++; 27 | } else { 28 | not_taken++; 29 | } 30 | } 31 | 32 | wasm::br_table:before { 33 | unshared var taken_branches: map ; 34 | // which branch was taken? 35 | var index: i32; 36 | index = arg0 < (num_targets - 1) ? targets[arg0 as u32] as i32 : default_target as i32; 37 | 38 | // count stores an array of counters 39 | taken_branches[index]++; 40 | } 41 | -------------------------------------------------------------------------------- /tests/scripts/wizard_monitors/branch-br_table.mm: -------------------------------------------------------------------------------- 1 | /* Facts: 2 | * Bytecode names are probe types 3 | * Bound variables 4 | * - probe_func : (whamm standard) is the Wasm function 5 | * - tos : Wasm top-of-stack 6 | * - pc : Wasm program counter 7 | * - local0...N : Wasm locals 8 | * - 9 | * need to access top-of-stack, locals, program counter 10 | * need a handle to the function ("func") 11 | */ 12 | 13 | report var count: map<(u32, u32, i32), i32>; 14 | 15 | wasm::br:before { 16 | // branch always taken for `br` 17 | // count stores an array of counters 18 | count[(fid, pc, 1)]++; 19 | } 20 | 21 | wasm::br_if:before { 22 | // which branch was taken? 23 | var index: i32; 24 | index = arg0 != 0 ? 1 : 0; 25 | 26 | // count stores an array of counters 27 | count[(fid, pc, index)]++; 28 | } 29 | 30 | wasm::br_table:before { 31 | // which branch was taken? 32 | var index: i32; 33 | index = arg0 < (num_targets - 1) ? targets[arg0 as u32] as i32 : default_target as i32; 34 | 35 | // count stores an array of counters 36 | count[(fid, pc, index)]++; 37 | } 38 | -------------------------------------------------------------------------------- /tests/scripts/wizard_monitors/branch-nulls.mm.TODO: -------------------------------------------------------------------------------- 1 | /* Facts: 2 | * Bytecode names are probe types 3 | * Bound variables 4 | * - probe_func : (whamm standard) is the Wasm function 5 | * - tos : Wasm top-of-stack 6 | * - pc : Wasm program counter 7 | * - local0...N : Wasm locals 8 | * - 9 | * need to access top-of-stack, locals, program counter 10 | * need a handle to the function ("func") 11 | */ 12 | report var count: map<(u32, u32, i32), i32>; 13 | 14 | wasm::br:before { 15 | // count stores an array of counters 16 | count[(fid, pc, 1)]++; 17 | } 18 | 19 | wasm::br_if:before { 20 | var index: i32; 21 | // "arg0" is defined as the top-of-stack 22 | index = arg0 != 0 ? 1 : 0; 23 | // count stores an array of counters 24 | count[(fid, pc, index)]++; 25 | } 26 | 27 | wasm:::br_table { 28 | // "num_targets" is the number of targets of a br_table 29 | // "tos" is defined as the top-of-stack 30 | var index: i32 = tos >= num_targets ? num_targets : tos; 31 | // count stores an array of counters 32 | count[probe_func, pc, index]++; 33 | } 34 | 35 | // matches br_on_null 36 | wasm:::br_on_null { 37 | // tos is defined as the top-of-stack 38 | var index: i32 = tos == null ? 1 : 0; 39 | // count stores an array of counters 40 | count[probe_func, pc, index]++; 41 | } 42 | 43 | // matches br_on_null 44 | wasm:::br_on_non_null { 45 | // tos is defined as the top-of-stack 46 | var index: i32 = tos != null ? 1 : 0; 47 | // count stores an array of counters 48 | count[probe_func, pc, index]++; 49 | } 50 | -------------------------------------------------------------------------------- /tests/scripts/wizard_monitors/branch-report_allocs.mm: -------------------------------------------------------------------------------- 1 | /* Facts: 2 | * Bytecode names are probe types 3 | * Bound variables 4 | * - probe_func : (whamm standard) is the Wasm function 5 | * - tos : Wasm top-of-stack 6 | * - pc : Wasm program counter 7 | * - local0...N : Wasm locals 8 | * - 9 | * need to access top-of-stack, locals, program counter 10 | * need a handle to the function ("func") 11 | */ 12 | 13 | wasm::br:before { 14 | report unshared var taken: i32; 15 | // branch always taken for `br` 16 | // count stores an array of counters 17 | taken++; 18 | } 19 | 20 | wasm::br_if:before { 21 | report unshared var taken: i32; 22 | report unshared var not_taken: i32; 23 | 24 | // which branch was taken? 25 | if (arg0 != 0) { 26 | taken++; 27 | } else { 28 | not_taken++; 29 | } 30 | } 31 | 32 | wasm::br_table:before { 33 | report unshared var taken_branches: map; 34 | // which branch was taken? 35 | var index: i32; 36 | index = arg0 < (num_targets - 1) ? targets[arg0 as u32] as i32 : default_target as i32; 37 | 38 | // count stores an array of counters 39 | taken_branches[index]++; 40 | } 41 | -------------------------------------------------------------------------------- /tests/scripts/wizard_monitors/loop.mm.TODO: -------------------------------------------------------------------------------- 1 | // matches "loop" bytecode 2 | wasm:::loop { 3 | count[probe_func, pc]++; 4 | } -------------------------------------------------------------------------------- /tests/scripts/wizard_monitors/opcodes.mm.TODO: -------------------------------------------------------------------------------- 1 | Map counts; 2 | 3 | // `*` matches all pc's, which effectively instruments every opcode. 4 | wasm:pc:*:before { 5 | // `opcode_name` is a provided global which equals the name of the opcode at the current pc 6 | counts[opcode_name]++; 7 | } 8 | 9 | // if they wanted to do “every other loc”, they could use the predicate, e.g.: 10 | // wasm:pc:*:before / pc % 2 == 0 / { .. } -------------------------------------------------------------------------------- /tests/wast_suite/control_flow/if.wast: -------------------------------------------------------------------------------- 1 | ;; Test `if` control flow 2 | 3 | ;; @instrument 4 | (module 5 | ;; Globals 6 | (global $var (mut i32) (i32.const 0)) 7 | 8 | ;; Global getters 9 | (func $get_global_var (result i32) 10 | (global.get $var) 11 | ) 12 | 13 | ;; Auxiliary definitions 14 | (func $dummy_five_params (param i32 i32 i32 i32 i32) 15 | local.get 0 16 | local.get 1 17 | i32.add 18 | local.get 2 19 | i32.add 20 | local.get 3 21 | i32.add 22 | local.get 4 23 | i32.add 24 | global.set $var 25 | ) 26 | 27 | ;; Test case functions 28 | (func $five_params 29 | (call $dummy_five_params (i32.const 0) (i32.const 1) (i32.const 2) (i32.const 3) (i32.const 4)) 30 | ) 31 | 32 | (start $five_params) 33 | (export "five_params" (func $five_params)) 34 | (export "get_global_var" (func $get_global_var)) 35 | (memory (;0;) 1) 36 | ) 37 | 38 | ;; WHAMM --> var count: i32; wasm:opcode:call:before / target_fn_name == "dummy_five_params" / { if(true) { count = 3; } } 39 | (assert_return (invoke "get_count") (i32.const 3)) 40 | ;; WHAMM --> var count: i32; wasm:opcode:call:before / target_fn_name == "dummy_five_params" / { if(false) { count = 3; } } 41 | (assert_return (invoke "get_count") (i32.const 0)) 42 | 43 | ;; WHAMM --> var count: i32; wasm:opcode:call:before / target_fn_name == "dummy_five_params" / { var a: i32; if(a == 0) { count = 3; } } 44 | (assert_return (invoke "get_count") (i32.const 3)) 45 | ;; WHAMM --> var count: i32; wasm:opcode:call:before / target_fn_name == "dummy_five_params" / { var a: i32; if(a != 0) { count = 3; } } 46 | (assert_return (invoke "get_count") (i32.const 0)) 47 | -------------------------------------------------------------------------------- /tests/wast_suite/control_flow/if_else.wast: -------------------------------------------------------------------------------- 1 | ;; Test `if/else` control flow 2 | 3 | ;; @instrument 4 | (module 5 | ;; Globals 6 | (global $var (mut i32) (i32.const 0)) 7 | 8 | ;; Global getters 9 | (func $get_global_var (result i32) 10 | (global.get $var) 11 | ) 12 | 13 | ;; Auxiliary definitions 14 | (func $dummy_five_params (param i32 i32 i32 i32 i32) 15 | local.get 0 16 | local.get 1 17 | i32.add 18 | local.get 2 19 | i32.add 20 | local.get 3 21 | i32.add 22 | local.get 4 23 | i32.add 24 | global.set $var 25 | ) 26 | 27 | ;; Test case functions 28 | (func $five_params 29 | (call $dummy_five_params (i32.const 0) (i32.const 1) (i32.const 2) (i32.const 3) (i32.const 4)) 30 | ) 31 | 32 | (start $five_params) 33 | (export "five_params" (func $five_params)) 34 | (export "get_global_var" (func $get_global_var)) 35 | (memory (;0;) 1) 36 | ) 37 | 38 | ;; WHAMM --> var count: i32; wasm:opcode:call:before / target_fn_name == "dummy_five_params" / { if(true) { count = 3; } else { count = 4; } } 39 | (assert_return (invoke "get_count") (i32.const 3)) 40 | ;; WHAMM --> var count: i32; wasm:opcode:call:before / target_fn_name == "dummy_five_params" / { if(false) { count = 3; } else { count = 4; } } 41 | (assert_return (invoke "get_count") (i32.const 4)) 42 | 43 | ;; WHAMM --> var count: i32; wasm:opcode:call:before / target_fn_name == "dummy_five_params" / { var a: i32; if(a == 0) { count = 3; } else { count = 4; } } 44 | (assert_return (invoke "get_count") (i32.const 3)) 45 | ;; WHAMM --> var count: i32; wasm:opcode:call:before / target_fn_name == "dummy_five_params" / { var a: i32; if(a != 0) { count = 3; } else { count = 4; } } 46 | (assert_return (invoke "get_count") (i32.const 4)) 47 | -------------------------------------------------------------------------------- /tests/wast_suite/events/wasm_opcodes/call/import/imms.wast: -------------------------------------------------------------------------------- 1 | ;; Test `wasm:opcode:call` event 2 | 3 | ;; Auxiliary module to import from 4 | 5 | (module 6 | (func (export "dummy_five_params") (param i32 i32 i32 i32 i32) (result i32) 7 | local.get 0 8 | local.get 1 9 | i32.add 10 | local.get 2 11 | i32.add 12 | local.get 3 13 | i32.add 14 | local.get 4 15 | i32.add 16 | ) 17 | ) 18 | 19 | (register "test") 20 | 21 | ;; @instrument 22 | (module 23 | ;; Imports 24 | (type (;0;) (func (param i32 i32 i32 i32 i32) (result i32))) 25 | (import "test" "dummy_five_params" (func $dummy_five_params (type 0))) 26 | 27 | ;; Globals 28 | (global $var (mut i32) (i32.const 0)) 29 | 30 | ;; Global getters 31 | (func $get_global_var (result i32) 32 | (global.get $var) 33 | ) 34 | 35 | ;; Test case functions 36 | (func $five_params 37 | (call $dummy_five_params (i32.const 0) (i32.const 1) (i32.const 2) (i32.const 3) (i32.const 4)) 38 | global.set $var 39 | ) 40 | 41 | (start $five_params) 42 | (export "five_params" (func $five_params)) 43 | (export "get_global_var" (func $get_global_var)) 44 | (memory (;0;) 1) 45 | ) 46 | 47 | ;; --------------------------------- 48 | ;; ==== IMMS, predicate, `imm0` ==== 49 | ;; WHAMM --> var count: i32; wasm:opcode:call:before / imm0 == 1 / { count++; } 50 | (assert_return (invoke "get_count") (i32.const 0)) ;; predicate is 'false' 51 | ;; WHAMM --> var count: i32; wasm:opcode:call:before / imm0 == 0 / { count++; } 52 | (assert_return (invoke "get_count") (i32.const 1)) ;; predicate is 'true' 53 | 54 | ;; ---------------------------- 55 | ;; ==== IMMS, body, `imm0` ==== 56 | ;; WHAMM --> var count: i32; wasm:opcode:call:before { count = imm0 == 1 ? 1 : 0; } 57 | (assert_return (invoke "get_count") (i32.const 0)) ;; condition is 'false' 58 | ;; WHAMM --> var count: i32; wasm:opcode:call:before { count = imm0 == 0 ? 1 : 0; } 59 | (assert_return (invoke "get_count") (i32.const 1)) ;; condition is 'true' 60 | -------------------------------------------------------------------------------- /tests/wast_suite/events/wasm_opcodes/call/import/prov-fns.wast: -------------------------------------------------------------------------------- 1 | ;; Test `wasm:opcode:call` event 2 | 3 | ;; Auxiliary module to import from 4 | 5 | (module 6 | (func (export "add_all") (param i32 i32 i32 i32 i32) (result i32) 7 | local.get 0 8 | local.get 1 9 | i32.add 10 | local.get 2 11 | i32.add 12 | local.get 3 13 | i32.add 14 | local.get 4 15 | i32.add 16 | ) 17 | ) 18 | 19 | (register "test") 20 | 21 | ;; @instrument 22 | (module 23 | ;; Imports 24 | (type (;0;) (func (param i32 i32 i32 i32 i32) (result i32))) 25 | (import "test" "add_all" (func $add_all (type 0))) 26 | 27 | ;; Globals 28 | (global $var (mut i32) (i32.const 0)) 29 | 30 | ;; Global getters 31 | (func $get_global_var (result i32) 32 | (global.get $var) 33 | ) 34 | 35 | (func $mult_all (type 0) 36 | ;; local.get 0 ;; ignore to avoid result being 0 37 | local.get 1 38 | local.get 2 39 | i32.mul 40 | local.get 3 41 | i32.mul 42 | local.get 4 43 | i32.mul 44 | ) 45 | 46 | ;; Test case functions 47 | (func $five_params 48 | (call $add_all (i32.const 0) (i32.const 1) (i32.const 2) (i32.const 3) (i32.const 4)) 49 | global.set $var 50 | ) 51 | 52 | (start $five_params) 53 | (export "five_params" (func $five_params)) 54 | (export "get_global_var" (func $get_global_var)) 55 | (memory (;0;) 1) 56 | ) 57 | 58 | ;; ------------------------------------------------- 59 | ;; ==== FUNCS, with predicate, `alt_call_by_id` ==== 60 | ;; WHAMM --> wasm:opcode:call(arg4: i32):alt / arg4 == 0 / { alt_call_by_id(2); } 61 | (assert_return (invoke "get_global_var") (i32.const 24)) ;; global should be what's calculated by the new func 62 | 63 | ;; ---------------------------------------------------- 64 | ;; ==== FUNCS, without predicate, `alt_call_by_id` ==== 65 | ;; WHAMM --> wasm:opcode:call:alt { alt_call_by_id(2); } 66 | (assert_return (invoke "get_global_var") (i32.const 24)) ;; global should be what's calculated by the new func 67 | 68 | ;; --------------------------------------------------- 69 | ;; ==== FUNCS, with predicate, `alt_call_by_name` ==== 70 | ;; WHAMM --> wasm:opcode:call(arg4: i32):alt / arg4 == 0 / { alt_call_by_name("mult_all"); } 71 | (assert_return (invoke "get_global_var") (i32.const 24)) ;; global should be what's calculated by the new func 72 | 73 | ;; ------------------------------------------------------ 74 | ;; ==== FUNCS, without predicate, `alt_call_by_name` ==== 75 | ;; WHAMM --> wasm:opcode:call:alt { alt_call_by_name("mult_all"); } 76 | (assert_return (invoke "get_global_var") (i32.const 24)) ;; global should be what's calculated by the new func 77 | -------------------------------------------------------------------------------- /tests/wast_suite/events/wasm_opcodes/call/local/args_mul-calls.wast: -------------------------------------------------------------------------------- 1 | ;; Test `wasm:opcode:call` event 2 | 3 | ;; @instrument 4 | (module 5 | ;; Globals 6 | (global $var (mut i64) (i64.const 0)) 7 | 8 | ;; Global getters 9 | (func $get_global_var (result i64) 10 | (global.get $var) 11 | ) 12 | 13 | (func $other (param i32) 14 | local.get 0 15 | drop 16 | ) 17 | 18 | ;; Auxiliary definitions 19 | (func $dummy_five_params (param i32 i32 i32 i32 i64) 20 | local.get 0 21 | local.get 1 22 | i32.add 23 | local.get 2 24 | i32.add 25 | local.get 3 26 | i32.add 27 | i64.extend_i32_s 28 | local.get 4 29 | i64.add 30 | global.set $var 31 | (call $other (local.get 0)) 32 | ) 33 | (func $dummy_no_params 34 | ;; function with no params and no returns 35 | i32.const 1 36 | drop 37 | ) 38 | 39 | ;; Test case functions 40 | (func $five_params 41 | (call $dummy_five_params (i32.const 0) (i32.const 1) (i32.const 2) (i32.const 3) (i64.const 4)) 42 | (call $dummy_no_params) 43 | ) 44 | 45 | (start $five_params) 46 | (export "five_params" (func $five_params)) 47 | (export "get_global_var" (func $get_global_var)) 48 | (memory (;0;) 1) 49 | ) 50 | 51 | ;; ================================= 52 | ;; ---- `CALL`: local functions ---- 53 | ;; ================================= 54 | 55 | ;; ------------------------------- 56 | ;; ==== ARGS, predicate, arg0 ==== 57 | ;; WHAMM --> var count: i32; wasm:opcode:call:before { count = 1; } 58 | (assert_return (invoke "get_count") (i32.const 1)) 59 | ;; @passes_uninstr 60 | (assert_return (invoke "get_global_var") (i64.const 10)) 61 | -------------------------------------------------------------------------------- /tests/wast_suite/events/wasm_opcodes/call/local/imms.wast: -------------------------------------------------------------------------------- 1 | ;; Test `wasm:opcode:call` event 2 | 3 | ;; @instrument 4 | (module 5 | ;; Globals 6 | (global $var (mut i32) (i32.const 0)) 7 | 8 | ;; Global getters 9 | (func $get_global_var (result i32) 10 | (global.get $var) 11 | ) 12 | 13 | ;; Auxiliary definitions 14 | (func $dummy_five_params (param i32 i32 i32 i32 i32) 15 | local.get 0 16 | local.get 1 17 | i32.add 18 | local.get 2 19 | i32.add 20 | local.get 3 21 | i32.add 22 | local.get 4 23 | i32.add 24 | global.set $var 25 | ) 26 | 27 | ;; Test case functions 28 | (func $five_params 29 | (call $dummy_five_params (i32.const 0) (i32.const 1) (i32.const 2) (i32.const 3) (i32.const 4)) 30 | ) 31 | 32 | (start $five_params) 33 | (export "five_params" (func $five_params)) 34 | (export "get_global_var" (func $get_global_var)) 35 | (memory (;0;) 1) 36 | ) 37 | 38 | ;; --------------------------------- 39 | ;; ==== IMMS, predicate, `imm0` ==== 40 | ;; WHAMM --> var count: i32; wasm:opcode:call:before / imm0 == 0 / { count++; } 41 | (assert_return (invoke "get_count") (i32.const 0)) ;; predicate is 'false' 42 | ;; WHAMM --> var count: i32; wasm:opcode:call:before / imm0 == 1 / { count++; } 43 | (assert_return (invoke "get_count") (i32.const 1)) ;; predicate is 'true' 44 | 45 | ;; ---------------------------- 46 | ;; ==== IMMS, body, `imm0` ==== 47 | ;; WHAMM --> var count: i32; wasm:opcode:call:before { count = imm0 == 0 ? 1 : 0; } 48 | (assert_return (invoke "get_count") (i32.const 0)) ;; condition is 'false' 49 | ;; WHAMM --> var count: i32; wasm:opcode:call:before { count = imm0 == 1 ? 1 : 0; } 50 | (assert_return (invoke "get_count") (i32.const 1)) ;; condition is 'true' 51 | -------------------------------------------------------------------------------- /tests/wast_suite/events/wasm_opcodes/call/local/in_loop.wast: -------------------------------------------------------------------------------- 1 | ;; Test `wasm:opcode:call` event 2 | ;; modified from https://github.com/titzer/wizard-engine/blob/master/test/monitors/profile_monitor0.wat 3 | ;; `wizeng --monitors=opcodes test/monitors/profile_monitor0.wasm` 4 | 5 | ;; @instrument 6 | (module 7 | (type (;0;) (func)) 8 | (func $foo (type 0) 9 | call $bar 10 | ) 11 | (func $bar (type 0) 12 | call $baz 13 | ) 14 | (func $baz (type 0)) 15 | 16 | (func $start 17 | (local $cnt i32) 18 | (local.set $cnt (i32.const 50)) 19 | loop $l 20 | call $foo 21 | call $bar 22 | call $foo 23 | call $baz 24 | call $foo 25 | call $foo 26 | call $foo 27 | call $bar 28 | call $bar 29 | call $foo 30 | (local.set $cnt (i32.sub (local.get $cnt) (i32.const 1))) 31 | (br_if $l (local.get $cnt)) 32 | end 33 | ) 34 | (memory 1) 35 | (start $start) 36 | ) 37 | 38 | ;; ================================= 39 | ;; ---- `CALL`: local functions ---- 40 | ;; ================================= 41 | 42 | ;; WHAMM --> var count: i32; wasm:opcode:call:before { count++; } 43 | (assert_return (invoke "get_count") (i32.const 1250)) -------------------------------------------------------------------------------- /tests/wast_suite/events/wasm_opcodes/call/local/prov-fns.wast: -------------------------------------------------------------------------------- 1 | ;; Test `wasm:opcode:call` event 2 | 3 | ;; @instrument 4 | (module 5 | ;; Imports 6 | (type (;0;) (func (param i32 i32 i32 i32 i32) (result i32))) 7 | 8 | ;; Globals 9 | (global $var (mut i32) (i32.const 0)) 10 | 11 | ;; Global getters 12 | (func $get_global_var (result i32) 13 | (global.get $var) 14 | ) 15 | 16 | (func $add_all (type 0) 17 | local.get 0 18 | local.get 1 19 | i32.add 20 | local.get 2 21 | i32.add 22 | local.get 3 23 | i32.add 24 | local.get 4 25 | i32.add 26 | ) 27 | 28 | (func $mult_all (type 0) 29 | ;; local.get 0 ;; ignore to avoid result being 0 30 | local.get 1 31 | local.get 2 32 | i32.mul 33 | local.get 3 34 | i32.mul 35 | local.get 4 36 | i32.mul 37 | ) 38 | 39 | ;; Test case functions 40 | (func $five_params 41 | (call $add_all (i32.const 0) (i32.const 1) (i32.const 2) (i32.const 3) (i32.const 4)) 42 | global.set $var 43 | ) 44 | 45 | (start $five_params) 46 | (export "five_params" (func $five_params)) 47 | (export "get_global_var" (func $get_global_var)) 48 | (memory (;0;) 1) 49 | ) 50 | 51 | ;; ------------------------------------------------- 52 | ;; ==== FUNCS, with predicate, `alt_call_by_id` ==== 53 | ;; WHAMM --> wasm:opcode:call(arg4: i32):alt / arg4 == 0 / { alt_call_by_id(2); } 54 | (assert_return (invoke "get_global_var") (i32.const 24)) ;; global should be what's calculated by the new func 55 | 56 | ;; ---------------------------------------------------- 57 | ;; ==== FUNCS, without predicate, `alt_call_by_id` ==== 58 | ;; WHAMM --> wasm:opcode:call:alt { alt_call_by_id(2); } 59 | (assert_return (invoke "get_global_var") (i32.const 24)) ;; global should be what's calculated by the new func 60 | 61 | ;; --------------------------------------------------- 62 | ;; ==== FUNCS, with predicate, `alt_call_by_name` ==== 63 | ;; WHAMM --> wasm:opcode:call(arg4: i32):alt / arg4 == 0 / { alt_call_by_name("mult_all"); } 64 | (assert_return (invoke "get_global_var") (i32.const 24)) ;; global should be what's calculated by the new func 65 | 66 | ;; ------------------------------------------------------ 67 | ;; ==== FUNCS, without predicate, `alt_call_by_name` ==== 68 | ;; WHAMM --> wasm:opcode:call:alt { alt_call_by_name("mult_all"); } 69 | (assert_return (invoke "get_global_var") (i32.const 24)) ;; global should be what's calculated by the new func 70 | -------------------------------------------------------------------------------- /tests/wast_suite/events/wasm_opcodes/call/local/prov-globals.wast: -------------------------------------------------------------------------------- 1 | ;; Test `wasm:opcode:call` event 2 | 3 | ;; @instrument 4 | (module 5 | ;; Globals 6 | (global $var (mut i32) (i32.const 0)) 7 | 8 | ;; Global getters 9 | (func $get_global_var (result i32) 10 | (global.get $var) 11 | ) 12 | 13 | ;; Auxiliary definitions 14 | (func $dummy_five_params (param i32 i32 i32 i32 i32) 15 | local.get 0 16 | local.get 1 17 | i32.add 18 | local.get 2 19 | i32.add 20 | local.get 3 21 | i32.add 22 | local.get 4 23 | i32.add 24 | global.set $var 25 | ) 26 | 27 | ;; Test case functions 28 | (func $five_params 29 | (call $dummy_five_params (i32.const 0) (i32.const 1) (i32.const 2) (i32.const 3) (i32.const 4)) 30 | ) 31 | 32 | (start $five_params) 33 | (export "five_params" (func $five_params)) 34 | (export "get_global_var" (func $get_global_var)) 35 | (memory (;0;) 1) 36 | ) 37 | 38 | ;; ---------------------------------------------- 39 | ;; ==== GLOBALS, predicate, `target_fn_type` ==== 40 | ;; WHAMM --> var count: i32; wasm:opcode:call:before / target_fn_type == "import" / { count++; } 41 | (assert_return (invoke "get_count") (i32.const 0)) ;; predicate is 'false' 42 | ;; WHAMM --> var count: i32; wasm:opcode:call:before / target_fn_type == "local" / { count++; } 43 | (assert_return (invoke "get_count") (i32.const 1)) ;; predicate is 'true' 44 | 45 | ;; ------------------------------------------------- 46 | ;; ==== GLOBALS, predicate, `target_imp_module` ==== 47 | ;; WHAMM --> var count: i32; wasm:opcode:call:before / target_imp_module == "test" / { count++; } 48 | (assert_return (invoke "get_count") (i32.const 0)) ;; predicate is 'false' 49 | 50 | ;; ----------------------------------------------- 51 | ;; ==== GLOBALS, predicate, `target_fn_name` ==== 52 | ;; WHAMM --> var count: i32; wasm:opcode:call:before / target_fn_name == "wrong" / { count++; } 53 | (assert_return (invoke "get_count") (i32.const 0)) ;; predicate is 'false' 54 | ;; WHAMM --> var count: i32; wasm:opcode:call:before / target_fn_name == "dummy_five_params" / { count++; } 55 | (assert_return (invoke "get_count") (i32.const 1)) ;; predicate is 'true' 56 | 57 | ;; ----------------------------------------- 58 | ;; ==== GLOBALS, body, `target_fn_type` ==== 59 | ;; WHAMM --> var count: i32; wasm:opcode:call:before { count = target_fn_type == "import" ? 1 : 0; } 60 | (assert_return (invoke "get_count") (i32.const 0)) ;; condition is 'false' 61 | ;; WHAMM --> var count: i32; wasm:opcode:call:before { count = target_fn_type == "local" ? 1 : 0; } 62 | (assert_return (invoke "get_count") (i32.const 1)) ;; predicate is 'true' 63 | 64 | ;; -------------------------------------------- 65 | ;; ==== GLOBALS, body, `target_imp_module` ==== 66 | ;; WHAMM --> var count: i32; wasm:opcode:call:before { count = target_imp_module == "import" ? 1 : 0; } 67 | (assert_return (invoke "get_count") (i32.const 0)) ;; condition is 'false' 68 | 69 | ;; ------------------------------------------ 70 | ;; ==== GLOBALS, body, `target_fn_name` ==== 71 | ;; WHAMM --> var count: i32; wasm:opcode:call:before { count = target_fn_name == "wrong" ? 1 : 0; } 72 | (assert_return (invoke "get_count") (i32.const 0)) ;; condition is 'false' 73 | ;; WHAMM --> var count: i32; wasm:opcode:call:before { count = target_fn_name == "dummy_five_params" ? 1 : 0; } 74 | (assert_return (invoke "get_count") (i32.const 1)) ;; condition is 'true' 75 | -------------------------------------------------------------------------------- /tests/wast_suite/events/wasm_opcodes/end.wast: -------------------------------------------------------------------------------- 1 | ;; @instrument 2 | (module 3 | ;; Globals 4 | (global $var (mut i32) (i32.const 0)) 5 | 6 | ;; Global getters 7 | (func $get_global_var (result i32) 8 | (global.get $var) 9 | ) 10 | 11 | (func $cond_logic (param i32) 12 | local.get 0 13 | if 14 | i32.const 1 15 | block (result i32) 16 | global.get $var 17 | end 18 | i32.add 19 | global.set $var 20 | else 21 | i32.const 2 22 | global.get $var 23 | i32.add 24 | global.set $var 25 | end 26 | ) 27 | 28 | (func $run 29 | i32.const 1 ;; true 30 | call $cond_logic 31 | 32 | i32.const 0 ;; false 33 | call $cond_logic 34 | ) 35 | 36 | (memory 1) 37 | (export "get_global_var" (func $get_global_var)) 38 | (start $run) ;; run the first function automatically 39 | ) 40 | 41 | ;; ---------------------- 42 | ;; ==== unpredicated ==== 43 | ;; WHAMM --> var count: i32; wasm:opcode:end:before { count++; } 44 | ;; @passes_uninstr 45 | (assert_return (invoke "get_global_var") (i32.const 3)) 46 | (assert_return (invoke "get_count") (i32.const 2)) 47 | ;; WHAMM --> var count: i32; wasm:opcode:end:after { count = count + 2; } 48 | (assert_return (invoke "get_count") (i32.const 6)) 49 | 50 | ;; WHAMM --> var count: i32; wasm:opcode:end:before /fid == 1 && pc == 5/ { count++; } 51 | ;; @passes_uninstr 52 | (assert_return (invoke "get_global_var") (i32.const 3)) 53 | (assert_return (invoke "get_count") (i32.const 1)) ;; only enter else 1 out of 2 times 54 | -------------------------------------------------------------------------------- /tests/wast_suite/events/wasm_opcodes/unreachable.wast: -------------------------------------------------------------------------------- 1 | ;; Test `wasm:opcode:br` event 2 | 3 | ;; @instrument 4 | (module 5 | ;; Globals 6 | (global $var0 (mut i32) (i32.const 0)) 7 | (global $var1 (mut i32) (i32.const 0)) 8 | 9 | ;; Global getters 10 | (func $get_global_var0 (result i32) 11 | (global.get $var0) 12 | ) 13 | (func $get_global_var1 (result i32) 14 | (global.get $var1) 15 | ) 16 | 17 | ;; Test case functions 18 | (func $basic_br (param i32) (result i32) 19 | block $eq 20 | block $neq 21 | (i32.eq (local.get 0) (i32.const 1)) 22 | br_if $eq 23 | unreachable 24 | end 25 | ;; they are not equal, return '0' 26 | i32.const 0 27 | return 28 | end 29 | ;; they are equal, return '1' 30 | i32.const 1 31 | return 32 | ) 33 | 34 | (func $start 35 | (call $basic_br (i32.const 0)) 36 | global.set $var0 37 | ) 38 | 39 | (export "get_global_var0" (func $get_global_var0)) 40 | (export "get_global_var1" (func $get_global_var1)) 41 | (memory (;0;) 1) 42 | (start $start) 43 | ) 44 | 45 | ;; WHAMM --> var count: i32; wasm:opcode:unreachable:alt { count++; } 46 | (assert_return (invoke "get_count") (i32.const 1)) 47 | 48 | ;; Need to do alt on unreachable so we can actually run the test! 49 | ;; WHAMM --> var count: i32; wasm:opcode:unreachable:alt { count = count + 2; } wasm:opcode:unreachable:before { count++; } 50 | (assert_return (invoke "get_count") (i32.const 3)) 51 | -------------------------------------------------------------------------------- /tests/wast_suite/events/wasm_opcodes/unreachable_target_loc.wast: -------------------------------------------------------------------------------- 1 | ;; Test `wasm:opcode:br` event 2 | 3 | ;; @instrument 4 | (module 5 | ;; Globals 6 | (global $var (mut i32) (i32.const 0)) 7 | 8 | ;; Global getters 9 | (func $get_global_var (result i32) 10 | (global.get $var) 11 | ) 12 | 13 | ;; Test case functions 14 | (func $target_func (param i32) (result i32) 15 | block $eq 16 | block $neq 17 | (i32.eq (local.get 0) (i32.const 1)) 18 | unreachable 19 | br_if $eq 20 | end 21 | ;; they are not equal, return '0' 22 | i32.const 0 23 | return 24 | end 25 | ;; they are equal, return '1' 26 | i32.const 1 27 | return 28 | ) 29 | 30 | ;; Test case functions 31 | (func $basic_br (param i32) (result i32) 32 | block $eq 33 | block $neq 34 | (i32.eq (local.get 0) (i32.const 1)) 35 | br_if $eq 36 | unreachable 37 | end 38 | ;; they are not equal, return '0' 39 | i32.const 0 40 | return 41 | end 42 | ;; they are equal, return '1' 43 | i32.const 1 44 | return 45 | ) 46 | 47 | (func $start 48 | (call $basic_br (i32.const 0)) 49 | global.set $var 50 | (call $target_func (i32.const 1)) 51 | global.get $var 52 | i32.add 53 | global.set $var 54 | (call $target_func (i32.const 1)) 55 | global.get $var 56 | i32.add 57 | global.set $var 58 | ) 59 | 60 | (export "get_global_var" (func $get_global_var)) 61 | (memory (;0;) 1) 62 | (start $start) 63 | ) 64 | 65 | ;; WHAMM --> var count: i32; wasm:opcode:unreachable:alt { count++; } 66 | ;; @passes_uninstr 67 | (assert_return (invoke "get_global_var") (i32.const 2)) 68 | (assert_return (invoke "get_count") (i32.const 3)) 69 | 70 | ;; TODO with targeting (fid), see Issue#106 71 | ;;;; WHAMM --> var count: i32; wasm:opcode:unreachable:alt /fid == 1/ { count++; } wasm:opcode:unreachable:alt /fid == 2/ { count = count + 2; } 72 | ;;;; @passes_uninstr 73 | ;;(assert_return (invoke "get_global_var") (i32.const 2)) 74 | ;;(assert_return (invoke "get_count") (i32.const 4)) 75 | 76 | ;; TODO with targeting (pc), see Issue#106 77 | ;;;; WHAMM --> var count: i32; wasm:opcode:unreachable:alt /pc == 4/ { count++; } wasm:opcode:unreachable:alt /pc == 5/ { count = count + 2; } 78 | ;;;; @passes_uninstr 79 | ;;(assert_return (invoke "get_global_var") (i32.const 2)) 80 | ;;(assert_return (invoke "get_count") (i32.const 4)) 81 | 82 | ;; TODO with targeting (fid/pc), see Issue#106 83 | ;;;; WHAMM --> var count: i32; wasm:opcode:unreachable:alt /fid == 1 && pc == 4/ { count++; } wasm:opcode:unreachable:alt /fid == 2 && pc == 5/ { count = count + 2; } 84 | ;;;; @passes_uninstr 85 | ;;(assert_return (invoke "get_global_var") (i32.const 2)) 86 | ;;(assert_return (invoke "get_count") (i32.const 4)) 87 | -------------------------------------------------------------------------------- /user_libs/cache/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "cache" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [lib] 7 | crate-type = ["cdylib", "rlib"] 8 | 9 | [dependencies] 10 | log = "0.4.20" 11 | once_cell = "1.3.1" 12 | wasm-bindgen = "0.2" 13 | -------------------------------------------------------------------------------- /user_libs/cache/README.md: -------------------------------------------------------------------------------- 1 | # Whamm! User Library -- CacheSimulator # 2 | 3 | ## Cache Specifications ## 4 | 5 | - Size: 1 MB 6 | - Associativity: 4 way set-associative 7 | - Block Size: 128 byte block 8 | - Replacement Policy: LRU 9 | 10 | ## To Build ## 11 | 12 | To build: 13 | - In the base of this project (`whamm/user_libs/cache`), execute: `cargo build --release --target wasm32-wasip1` 14 | - The built `wasm` binary will be located at `whamm/user_libs/cache/target/wasm32-wasip1/release/cache.wasm` 15 | -------------------------------------------------------------------------------- /user_libs/cache/rust-toolchain.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | channel = "nightly" 3 | components = ["rustc", "cargo", "rustfmt", "clippy"] 4 | targets = [ "wasm32-wasip1" ] -------------------------------------------------------------------------------- /wasm_playground/README.md: -------------------------------------------------------------------------------- 1 | # The Wasm Playground # 2 | 3 | The `.wat` files here are used to write out the code for dsl-provided functions. 4 | Each `.wat` file provides the dsl-provided function along with a test function. To 5 | run the tests, simply run: `wasmtime `. If there is an error from hitting `unreachable`, 6 | the test has failed. No output means that the tests passed. The reason for this structure 7 | is that it keeps us from having to define and link a `logger`, which feels like overkill 8 | for this purpose. 9 | -------------------------------------------------------------------------------- /wasm_playground/control_flow/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "add" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [[bin]] 9 | doc = false 10 | name = "cf" 11 | path = "src/main.rs" 12 | 13 | [dependencies] 14 | wasm-bindgen = "0.2" -------------------------------------------------------------------------------- /wasm_playground/control_flow/demo_scripts/branch-monitor.mm: -------------------------------------------------------------------------------- 1 | // Branch Monitor Demo Agenda: 2 | // - basic implementation with global `map` 3 | // - add `report` variables 4 | // - add `unshared` variables 5 | 6 | // Profile the branches taken by `br` 7 | // TODO 8 | 9 | // Profile the branches taken by `br_if` 10 | // TODO -------------------------------------------------------------------------------- /wasm_playground/control_flow/rust-toolchain.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | channel = "nightly" 3 | components = ["rustc", "cargo", "rustfmt", "clippy"] 4 | targets = [ "wasm32-wasip1" ] -------------------------------------------------------------------------------- /wasm_playground/control_flow/src/main.rs: -------------------------------------------------------------------------------- 1 | use std::iter::zip; 2 | 3 | #[no_mangle] 4 | pub fn calc(a: i32, b: i32) -> i32 { 5 | if a > 5 { 6 | a + b 7 | } else { 8 | a * b 9 | } 10 | } 11 | 12 | #[no_mangle] 13 | fn print_x(opt: Opt, x: u32) { 14 | for _ in 0..x { 15 | println!("{} world!", opt_str(&opt)) 16 | } 17 | } 18 | 19 | #[no_mangle] 20 | fn opt_str(opt: &Opt) -> String { 21 | match opt { 22 | Opt::Hi => "hi".to_string(), 23 | Opt::Hello => "hello".to_string(), 24 | Opt::Sup => "'sup".to_string() 25 | } 26 | } 27 | 28 | #[no_mangle] 29 | fn main() { 30 | println!("==== CALC ===="); 31 | let times = 10; 32 | let aspan = (0..times).rev(); 33 | let bspan = 0..times; 34 | for (a, b) in zip(aspan, bspan) { 35 | // a: times to 0 36 | // b: 0 to times 37 | println!("calc({a}, {b}) -> {}", calc(a, b)); 38 | } 39 | 40 | println!("\n==== PRINT ===="); 41 | print_x(Opt::Hi, times as u32); 42 | print_x(Opt::Hello, times as u32); 43 | print_x(Opt::Sup, times as u32); 44 | } 45 | 46 | enum Opt { 47 | Hi, 48 | Hello, 49 | Sup 50 | } -------------------------------------------------------------------------------- /wasm_playground/control_flow/whamm/basic-alloc.mm: -------------------------------------------------------------------------------- 1 | wasm:opcode:call:before / fname == "main" && target_fn_name == "calc" / { 2 | report var count; 3 | if (arg0 == 1 || arg1 == 1) { 4 | count++; 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /wasm_playground/control_flow/whamm/basic.mm: -------------------------------------------------------------------------------- 1 | 2 | // To get report variables working on wizard target: 3 | // - create a "wasm:end" $end function 4 | // - 5 | 6 | wasm:opcode:call:before { // fid of "calc" 7 | report unshared var count: i32; 8 | // if (arg0 == 1 || arg1 == 1) { 9 | // count++; 10 | // } 11 | count++; 12 | } 13 | -------------------------------------------------------------------------------- /wasm_playground/control_flow/whamm/branch-allocs.mm: -------------------------------------------------------------------------------- 1 | /* Facts: 2 | * Bytecode names are probe types 3 | * Bound variables 4 | * - probe_func : (whamm standard) is the Wasm function 5 | * - tos : Wasm top-of-stack 6 | * - pc : Wasm program counter 7 | * - local0...N : Wasm locals 8 | * - 9 | * need to access top-of-stack, locals, program counter 10 | * need a handle to the function ("func") 11 | */ 12 | 13 | wasm::br:before / fname == "calc" || fname == "print_x" / { 14 | report unshared var taken: i32; 15 | // branch always taken for `br` 16 | // count stores an array of counters 17 | taken++; 18 | } 19 | 20 | wasm::br_if:before / fname == "calc" || fname == "print_x" / { 21 | report unshared var taken: i32; 22 | report unshared var not_taken: i32; 23 | 24 | // which branch was taken? 25 | if (arg0 != 0) { 26 | taken++; 27 | } else { 28 | not_taken++; 29 | } 30 | } 31 | 32 | // wasm::br_table:before / fname == "calc" || fname == "print_x" / { 33 | // report unshared map taken_branches; 34 | // // which branch was taken? 35 | // i32 index; 36 | // index = arg0 < (num_targets - 1) ? targets[arg0] : default_target; 37 | // 38 | // // count stores an array of counters 39 | // taken_branches[index]++; 40 | // } 41 | -------------------------------------------------------------------------------- /wasm_playground/control_flow/whamm/branch-br_table.mm: -------------------------------------------------------------------------------- 1 | /* Facts: 2 | * Bytecode names are probe types 3 | * Bound variables 4 | * - probe_func : (whamm standard) is the Wasm function 5 | * - tos : Wasm top-of-stack 6 | * - pc : Wasm program counter 7 | * - local0...N : Wasm locals 8 | * - 9 | * need to access top-of-stack, locals, program counter 10 | * need a handle to the function ("func") 11 | */ 12 | 13 | report map<(u32, u32, i32), i32> count; 14 | 15 | wasm::br:before / fname == "calc" || fname == "print_x" / { 16 | // branch always taken for `br` 17 | // count stores an array of counters 18 | count[(fid, pc, 1)]++; 19 | } 20 | 21 | wasm::br_if:before / fname == "calc" || fname == "print_x" / { 22 | // which branch was taken? 23 | i32 index; 24 | index = arg0 != 0 ? 1 : 0; 25 | 26 | // count stores an array of counters 27 | count[(fid, pc, index)]++; 28 | } 29 | 30 | wasm::br_table:before / fname == "calc" || fname == "print_x" / { 31 | // which branch was taken? 32 | i32 index; 33 | index = arg0 < (num_targets - 1) ? targets[arg0] : default_target; 34 | 35 | // count stores an array of counters 36 | count[(fid, pc, index)]++; 37 | } 38 | -------------------------------------------------------------------------------- /wasm_playground/control_flow/whamm/branch-report_allocs.mm: -------------------------------------------------------------------------------- 1 | /* Facts: 2 | * Bytecode names are probe types 3 | * Bound variables 4 | * - probe_func : (whamm standard) is the Wasm function 5 | * - tos : Wasm top-of-stack 6 | * - pc : Wasm program counter 7 | * - local0...N : Wasm locals 8 | * - 9 | * need to access top-of-stack, locals, program counter 10 | * need a handle to the function ("func") 11 | */ 12 | 13 | wasm::br:before / fname == "calc" || fname == "print_x" / { 14 | // branch always taken for `br` 15 | report unshared i32 taken; 16 | taken++; 17 | } 18 | 19 | wasm::br_if:before / fname == "calc" || fname == "print_x" / { 20 | report unshared i32 taken; 21 | report unshared i32 not_taken; 22 | 23 | // which branch was taken? 24 | if (arg0 != 0) { 25 | taken++; 26 | } else { 27 | not_taken++; 28 | } 29 | } 30 | 31 | wasm::br_table:before / fname == "calc" || fname == "print_x" / { 32 | report unshared map taken_branches; 33 | 34 | // which branch was taken? 35 | i32 index; 36 | index = arg0 < (num_targets - 1) ? targets[arg0] : default_target; 37 | 38 | // count stores an array of counters 39 | taken_branches[index]++; 40 | } 41 | -------------------------------------------------------------------------------- /wasm_playground/example/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "example" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [[bin]] 9 | doc = false 10 | name = "example" 11 | path = "src/main.rs" 12 | 13 | [dependencies] 14 | wasm-bindgen = "0.2" 15 | -------------------------------------------------------------------------------- /wasm_playground/example/README.md: -------------------------------------------------------------------------------- 1 | # Test Rust Project for Instrumentation # 2 | 3 | Build: 4 | ```shell 5 | cargo build --target wasm32-wasip1 6 | ``` -------------------------------------------------------------------------------- /wasm_playground/example/add_map.mm: -------------------------------------------------------------------------------- 1 | report var blah; 2 | report map m0; 3 | // wasm:opcode:call:before / 4 | // target_fn_name == "bar" 5 | // / 6 | wasm:opcode:call:before 7 | { 8 | unshared var count: i32; 9 | report var rep_count; 10 | 11 | count++; 12 | // if(strcmp((0, 1), "lsdjflaksjdf")) { 13 | // report var c; 14 | // } 15 | // // report var a; 16 | // // report map m; 17 | // // a = 5; 18 | // m0[1] = 2; 19 | // // m[1] = 2; 20 | // // m[2] = 3; 21 | // blah = 3; 22 | // arg0 = 5; 23 | 24 | rep_count = count; 25 | } 26 | // wasm:opcode:call:after / 27 | // target_fn_name == "foo" 28 | // / 29 | // wasm:opcode:call:after 30 | // { 31 | // report var b; 32 | // b = 3; 33 | // } -------------------------------------------------------------------------------- /wasm_playground/example/rust-toolchain.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | channel = "nightly" 3 | components = ["rustc", "cargo", "rustfmt", "clippy"] 4 | targets = [ "wasm32-wasip1" ] -------------------------------------------------------------------------------- /wasm_playground/example/src/main.rs: -------------------------------------------------------------------------------- 1 | #[no_mangle] 2 | pub fn foo(a: i32) -> i32 { 3 | a - 3 4 | } 5 | 6 | #[no_mangle] 7 | pub fn bar(a: i32) -> i32 { 8 | let b = foo(a); 9 | for i in 0..b { 10 | println!("hello: {i}") 11 | } 12 | 13 | b 14 | } 15 | 16 | #[no_mangle] 17 | fn main() { 18 | let b = bar(15); 19 | println!("b = {b}"); 20 | } 21 | -------------------------------------------------------------------------------- /wasm_playground/strcmp/strcmp-roundtrip.wat: -------------------------------------------------------------------------------- 1 | (module 2 | (type (;0;) (func (param i32 i32 i32 i32) (result i32))) 3 | (type (;1;) (func)) 4 | (func (;0;) (type 0) (param i32 i32 i32 i32) (result i32) 5 | (local i32 i32 i32) 6 | block ;; label = @1 7 | block ;; label = @2 8 | local.get 1 9 | local.get 3 10 | i32.ne 11 | br_if 1 (;@1;) 12 | local.get 0 13 | local.get 2 14 | i32.eq 15 | br_if 0 (;@2;) 16 | i32.const 0 17 | local.set 4 18 | loop ;; label = @3 19 | local.get 4 20 | local.get 1 21 | i32.lt_u 22 | i32.eqz 23 | br_if 1 (;@2;) 24 | local.get 0 25 | local.get 4 26 | i32.add 27 | i32.load8_u 28 | local.set 5 29 | local.get 2 30 | local.get 4 31 | i32.add 32 | i32.load8_u 33 | local.set 6 34 | local.get 5 35 | local.get 6 36 | i32.ne 37 | br_if 2 (;@1;) 38 | local.get 4 39 | i32.const 1 40 | i32.add 41 | local.set 4 42 | br 0 (;@3;) 43 | end 44 | br 0 (;@2;) 45 | end 46 | i32.const 1 47 | return 48 | end 49 | i32.const 0 50 | return) 51 | (func (;1;) (type 1) 52 | block ;; label = @1 53 | block ;; label = @2 54 | i32.const 0 55 | i32.const 0 56 | i32.const 0 57 | i32.const 0 58 | call 0 59 | i32.const 1 60 | i32.ne 61 | br_if 1 (;@1;) 62 | i32.const 0 63 | i32.const 1 64 | i32.const 0 65 | i32.const 1 66 | call 0 67 | i32.const 1 68 | i32.ne 69 | br_if 1 (;@1;) 70 | i32.const 0 71 | i32.const 1 72 | i32.const 1 73 | i32.const 1 74 | call 0 75 | i32.const 0 76 | i32.ne 77 | br_if 1 (;@1;) 78 | i32.const 0 79 | i32.const 3 80 | i32.const 3 81 | i32.const 3 82 | call 0 83 | i32.const 0 84 | i32.ne 85 | br_if 1 (;@1;) 86 | br 0 (;@2;) 87 | end 88 | return 89 | end 90 | unreachable 91 | return) 92 | (memory (;0;) 1) 93 | (export "memory" (memory 0)) 94 | (start 1) 95 | (data (;0;) (i32.const 0) "abcabd")) 96 | -------------------------------------------------------------------------------- /wasm_playground/strcmp/strcmp.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ejrgilbert/whamm/2bc891519c0c657e591fc75971441d556f1e2223/wasm_playground/strcmp/strcmp.wasm -------------------------------------------------------------------------------- /wasmtime-runner/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "wasm_runner" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [[bin]] 7 | doc = false 8 | name = "wasm_runner" 9 | path = "src/main.rs" 10 | #required-features = ["exe"] 11 | 12 | [dependencies] 13 | wasmtime = "24.0.0" 14 | wasmtime-wasi = "24.0.0" 15 | wasi-common = "24.0.0" -------------------------------------------------------------------------------- /wasmtime-runner/README.md: -------------------------------------------------------------------------------- 1 | # The `wasmtime-runner` # 2 | 3 | This runner enables us to run a module that prints to the console by running on `wasmtime`'s `wasi-preview1`. 4 | This lets us run things that depend on this functionality (like the report variable API). 5 | 6 | To run an instrumented module on this runtime: 7 | - The module should be at `output/output.wasm` 8 | - In the base of this directory, execute: `cargo run` 9 | -------------------------------------------------------------------------------- /wasmtime-runner/src/main.rs: -------------------------------------------------------------------------------- 1 | use std::fs::File; 2 | use std::env; 3 | use wasi_common::sync::{Dir, WasiCtxBuilder}; 4 | use wasmtime::*; 5 | 6 | const WASM_MODULE: &str = "../output/output.wasm"; 7 | const CORE_LIB_NAME: &str = "whamm_core"; 8 | const CORE_LIB_MODULE: &str = "../whamm_core/target/wasm32-wasip1/release/whamm_core.wasm"; 9 | 10 | fn main() -> Result<()> { 11 | let args: Vec = env::args().collect(); 12 | let mut libs: Vec<(String, String)> = vec![]; 13 | let mut core_lib = false; 14 | for arg in args.iter() { 15 | let parts: Vec<&str> = arg.split('=').collect(); 16 | if parts.len() == 2 { 17 | let lib_name = parts[0]; 18 | let lib_path = parts[1]; 19 | libs.push((lib_name.to_string(), lib_path.to_string())); 20 | 21 | if lib_name == CORE_LIB_NAME { 22 | core_lib = true; 23 | } 24 | } 25 | } 26 | if !core_lib { 27 | libs.push((CORE_LIB_NAME.to_string(), CORE_LIB_MODULE.to_string())); 28 | } 29 | 30 | // Define the WASI functions globally on the `Config`. 31 | let engine = Engine::default(); 32 | // let config = engine.config(); 33 | // println!("{:?}", config); 34 | // config.wasm_multi_memory(true); 35 | let mut linker = Linker::new(&engine); 36 | wasi_common::sync::add_to_linker(&mut linker, |s| s)?; 37 | 38 | // Create a WASI context and put it in a Store; all instances in the store 39 | // share this context. `WasiCtxBuilder` provides a number of ways to 40 | // configure what the target program will have access to. 41 | let wasi = WasiCtxBuilder::new() 42 | .inherit_stdio() 43 | .inherit_args()? 44 | .inherit_env()? 45 | .preopened_dir(Dir::from_std_file(File::open("../")?), "./")? 46 | .build(); 47 | let mut store = Store::new(&engine, wasi); 48 | 49 | // Instantiate our module with the imports we've created, and run it. 50 | for (lib_name, lib_path) in libs.iter() { 51 | let lib_wasm = if let Ok(wasm) = Module::from_file(&engine, lib_path) { 52 | wasm 53 | } else { 54 | Module::from_file(&engine, format!("../{lib_path}"))? 55 | }; 56 | linker.module(&mut store, lib_name, &lib_wasm)?; 57 | } 58 | let wasm_module = match env::var("WASM_MODULE") { 59 | Ok(val) => val, 60 | Err(_) => WASM_MODULE.to_string(), 61 | }; 62 | let app_wasm = Module::from_file(&engine, wasm_module)?; 63 | linker.module(&mut store, "", &app_wasm)?; 64 | linker 65 | .get_default(&mut store, "")? 66 | .typed::<(), ()>(&store)? 67 | .call(&mut store, ())?; 68 | 69 | Ok(()) 70 | } -------------------------------------------------------------------------------- /whamm_core/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "whamm_core" 3 | version = "0.0.1" 4 | edition = "2021" 5 | 6 | [lib] 7 | crate-type = ["cdylib", "rlib"] 8 | 9 | [dependencies] 10 | once_cell = "1.3.1" 11 | wasm-bindgen = "0.2" 12 | log = "0.4.20" 13 | itertools = "0.14.0" 14 | -------------------------------------------------------------------------------- /whamm_core/README.md: -------------------------------------------------------------------------------- 1 | # Whamm's Core Library # 2 | 3 | ## Maps Package ## 4 | 5 | This provides the `maps` functionality for `whamm!` and depends on running on `wasi-preview1` to log `report` variables. 6 | We enable running on `wasi` through the `wasmtime-runner` Rust project at the base of the `whamm!` project directory. 7 | 8 | ## To Run ## 9 | 10 | To run: 11 | - In the base of this project (`whamm/whamm_core`), execute: `cargo build --release --target wasm32-wasip1` 12 | - The built `wasm` binary will be located at `whamm/whamm_core/target/wasm32-wasip1/release/whamm_core.wasm` 13 | - An example `whamm!` script lives at `./src/add_map.mm` 14 | 15 | ## Issues: ## 16 | 17 | When building with `wasi-preview1`, the test `main` function gets optimized to where there are no `call` instrument-able events as targeted in the `add_map.mm` file. 18 | > We will need to fix this by actually getting to where we can instrument by 'merging' modules, whether that be through: 19 | > - linking (link and import the library), 20 | > - merging with single memory (merge two modules with the library pointing to some memory offset), or 21 | > - merging with multiple memories (merge two modules with the library memory living in a second memory). 22 | -------------------------------------------------------------------------------- /whamm_core/rust-toolchain.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | channel = "nightly" 3 | components = ["rustc", "cargo", "rustfmt", "clippy"] 4 | targets = [ "wasm32-wasip1" ] -------------------------------------------------------------------------------- /whamm_core/src/io/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod print; -------------------------------------------------------------------------------- /whamm_core/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod maps; 2 | pub mod io; 3 | -------------------------------------------------------------------------------- /whamm_core/src/tests.rs: -------------------------------------------------------------------------------- 1 | //to test, use RUST_TEST_THREADS=1 cargo test 2 | //Necessary because the mutex expects a single thread of acessors (or at least 1 thread per name in the map) 3 | 4 | #[allow(unused_imports)] 5 | use crate::*; 6 | //testing map functionality 7 | #[test] 8 | fn test_i32_i32() { 9 | create_i32_i32(0); 10 | insert_i32_i32(0, 1, 2); 11 | insert_i32_i32(0, 2, 3); 12 | println!("{:?}", get_i32_optional(0, &1)); 13 | let a = get_i32_optional(0, &1); 14 | println!("{:?}", get_i32_optional(0, &a.unwrap())); 15 | assert!(a == Some(2)); 16 | } 17 | #[test] 18 | fn test_string_bool() { 19 | create_string_bool(1); 20 | insert_string_bool(1, "hello".to_string(), true); 21 | insert_string_bool(1, "world".to_string(), false); 22 | println!("{:?}", get_bool_optional(1, &"hello".to_string())); 23 | let a = get_bool_optional(1, &"hello".to_string()); 24 | println!("{:?}", get_bool_optional(1, &a.unwrap())); 25 | assert!(a == Some(true)); 26 | } 27 | //test the ones including tuples and maps especially 28 | #[test] 29 | fn test_i32_tuple() { 30 | create_i32_tuple(2); 31 | insert_i32_tuple(2, 1, TupleVariant::i32_i32(2, 3)); 32 | insert_i32_tuple(2, 2, TupleVariant::i32_i32(3, 4)); 33 | println!("{:?}", get_tuple_optional(2, &1)); 34 | let a = get_tuple_optional(2, &1); 35 | assert!(*(a.unwrap()) == TupleVariant::i32_i32(2, 3)); 36 | } 37 | #[test] 38 | fn test_i32_map() { 39 | create_i32_map(3); 40 | insert_i32_map(3, 1, AnyMap::i32_i32_Map(HashMap::new())); 41 | //to change the stuff in the map, lock the mutex then get mut on that lock 42 | { 43 | let mut my_maps = MY_MAPS.lock().unwrap(); 44 | let map = get_map_mut(&mut my_maps, 3, &1).unwrap(); 45 | map.insert(Box::new(2), Box::new(3)); 46 | } 47 | let mut map = get_map_optional(3, &1).unwrap(); 48 | //otherwise, you can just get the map for its contents -- Inserting on map from this get does not change the global map 49 | map.insert(Box::new(3), Box::new(4)); //does nothing 50 | println!("{:?}", get_map_optional(3, &1).unwrap().get_i32(&2)); 51 | assert!(get_map_optional(3, &1).unwrap().get_i32(&2) == Some(3)); 52 | assert!(get_map_optional(3, &1).unwrap().get_i32(&3) == None); 53 | } 54 | //tuple as key 55 | #[test] 56 | fn test_tuple_i32() { 57 | create_tuple_i32(4); 58 | insert_tuple_i32(4, TupleVariant::i32_i32(1, 2), 3); 59 | insert_tuple_i32(4, TupleVariant::i32_i32(2, 3), 4); 60 | println!( 61 | "{:?}", 62 | get_i32_optional(4, &Box::new(TupleVariant::i32_i32(1, 2))) 63 | ); 64 | let a = get_i32_optional(4, &Box::new(TupleVariant::i32_i32(1, 2))); 65 | assert!(a == Some(3)); 66 | } 67 | 68 | //testing new non-optional getters 69 | #[test] 70 | fn test_i32_i32_notopt() { 71 | create_i32_i32(5); 72 | insert_i32_i32(5, 1, 2); 73 | insert_i32_i32(5, 2, 3); 74 | println!("{:?}", get_i32(5, &1)); 75 | let a = get_i32(5, &1); 76 | println!("{:?}", get_i32(5, &a)); 77 | assert!(a == 2); 78 | } 79 | 80 | #[test] 81 | fn i32i32i32_i32case() { 82 | let a = 6; 83 | let b = a; 84 | create_map_i32i32i32tuple_i32(a); 85 | insert_map_i32i32i32tuple_i32(b, 1, 2, 3, 4); 86 | let c = get_i32_from_i32i32i32tuple(b, 1, 2, 3); 87 | println!("{}", c); 88 | } 89 | --------------------------------------------------------------------------------