From 8827830aba96b5f9a99cf98f8b94eff2a7e5f6f5 Mon Sep 17 00:00:00 2001 From: Lachlan Sneff Date: Thu, 14 Feb 2019 15:13:58 -0800 Subject: [PATCH] implement load* and store* instructions --- Cargo.lock | 126 ++++---- lib/llvm-backend/src/code.rs | 463 +++++++++++++++++++++++++++-- lib/llvm-backend/src/intrinsics.rs | 334 +++++++++++++++++++-- lib/llvm-backend/src/lib.rs | 19 +- lib/llvm-backend/src/state.rs | 1 + 5 files changed, 811 insertions(+), 132 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6adb5581c..758c7ac56 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3,7 +3,7 @@ name = "aho-corasick" version = "0.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "memchr 2.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -70,7 +70,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "cc" -version = "1.0.28" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -105,7 +105,7 @@ name = "cmake" version = "0.1.35" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -232,7 +232,7 @@ name = "failure_derive" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.26 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)", "synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -249,17 +249,8 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "fuchsia-zircon" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "fuchsia-zircon-sys" -version = "0.3.3" +name = "fuchsia-cprng" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -287,7 +278,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.87 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -306,7 +297,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "inkwell" version = "0.1.0" -source = "git+https://github.com/TheDan64/inkwell?branch=llvm7-0#83b9188bad1e098f97e6aad8f6d45becb6d1ccdd" +source = "git+https://github.com/TheDan64/inkwell?branch=llvm7-0#715423bc67f46518ec489343b52455a27c1ff761" dependencies = [ "either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "enum-methods 0.0.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -318,7 +309,7 @@ dependencies = [ [[package]] name = "inkwell_internal_macros" version = "0.1.0" -source = "git+https://github.com/TheDan64/inkwell?branch=llvm7-0#83b9188bad1e098f97e6aad8f6d45becb6d1ccdd" +source = "git+https://github.com/TheDan64/inkwell?branch=llvm7-0#715423bc67f46518ec489343b52455a27c1ff761" dependencies = [ "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)", @@ -346,12 +337,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "libc" version = "0.2.48" -source = "git+https://github.com/rust-lang/libc#42cd3ba27254c423e03f6f4324de57075047f6a0" +source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "libc" -version = "0.2.48" -source = "registry+https://github.com/rust-lang/crates.io-index" +version = "0.2.49" +source = "git+https://github.com/rust-lang/libc#9a9e2e05c9532557362e5b24b0622259851392fa" [[package]] name = "llvm-backend" @@ -370,7 +361,7 @@ name = "llvm-sys" version = "70.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -396,12 +387,8 @@ dependencies = [ [[package]] name = "memchr" -version = "2.1.3" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] name = "memmap" @@ -418,7 +405,7 @@ version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -430,7 +417,7 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -482,7 +469,7 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "0.4.26" +version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -498,7 +485,7 @@ name = "quote" version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.26 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -512,8 +499,8 @@ dependencies = [ "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_jitter 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_os 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_jitter 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_os 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand_pcg 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -559,7 +546,7 @@ dependencies = [ [[package]] name = "rand_jitter" -version = "0.1.0" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", @@ -569,13 +556,13 @@ dependencies = [ [[package]] name = "rand_os" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -603,7 +590,7 @@ version = "6.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -634,7 +621,7 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "aho-corasick 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "regex-syntax 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -681,7 +668,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde" -version = "1.0.85" +version = "1.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -690,7 +677,7 @@ version = "0.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.87 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -698,27 +685,27 @@ name = "serde_bytes" version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.87 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_derive" -version = "1.0.85" +version = "1.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.26 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_json" -version = "1.0.37" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.87 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -765,7 +752,7 @@ version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 0.4.26 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -785,7 +772,7 @@ name = "syn" version = "0.15.26" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.26 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -803,7 +790,7 @@ name = "synstructure" version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.26 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -816,7 +803,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -913,9 +900,9 @@ name = "wabt" version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.87 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.87 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", "wabt-sys 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -924,7 +911,7 @@ name = "wabt-sys" version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", "cmake 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -954,10 +941,10 @@ dependencies = [ "hashbrown 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", "nix 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.87 (registry+https://github.com/rust-lang/crates.io-index)", "serde-bench 0.0.7 (registry+https://github.com/rust-lang/crates.io-index)", "serde_bytes 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.87 (registry+https://github.com/rust-lang/crates.io-index)", "target-lexicon 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "wasmer-runtime-core 0.1.2", "wasmparser 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -969,7 +956,7 @@ version = "0.1.0" dependencies = [ "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.48 (git+https://github.com/rust-lang/libc)", + "libc 0.2.49 (git+https://github.com/rust-lang/libc)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", "wabt 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", "wasmer-clif-backend 0.1.2", @@ -999,10 +986,10 @@ dependencies = [ "nix 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "page_size 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.87 (registry+https://github.com/rust-lang/crates.io-index)", "serde-bench 0.0.7 (registry+https://github.com/rust-lang/crates.io-index)", "serde_bytes 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.87 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "wasmer-clif-backend 0.1.2", "wasmparser 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1073,7 +1060,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" "checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb" "checksum cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "926013f2860c46252efceabb19f4a6b308197505082c609025aa6706c011d427" -"checksum cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4a8b715cb4597106ea87c7c84b2f1d452c7492033765df7f32651e66fcf749" +"checksum cc 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)" = "4390a3b5f4f6bce9c1d0c00128379df433e53777fdd30e92f16a529332baec4e" "checksum cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4" "checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e" "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" @@ -1094,8 +1081,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1" "checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" "checksum field-offset 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "64e9bc339e426139e02601fa69d101e96a92aee71b58bc01697ec2a63a5c9e68" -"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" -"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" +"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" "checksum gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)" = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2" "checksum generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c0f28c2f5bfb5960175af447a2da7c18900693738343dc896ffbcabd9839592" "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" @@ -1107,12 +1093,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1" -"checksum libc 0.2.48 (git+https://github.com/rust-lang/libc)" = "" "checksum libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)" = "e962c7641008ac010fa60a7dfdc1712449f29c44ef2d4702394aea943ee75047" +"checksum libc 0.2.49 (git+https://github.com/rust-lang/libc)" = "" "checksum llvm-sys 70.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "60a9ee82fe0fa72ae6ef6d018b407296085863836451c7a97384f84ed7e26b9f" "checksum lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c" "checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6" -"checksum memchr 2.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e1dd4eaac298c32ce07eb6ed9242eda7d82955b9170b7d6db59b2e02cc63fcb8" +"checksum memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2efc7bc57c883d4a4d6e3246905283d8dae951bb3bd32f49d6ef297f546e1c39" "checksum memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b" "checksum nix 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "921f61dc817b379d0834e45d5ec45beaacfae97082090a49c2cf30dcbc30206f" "checksum nix 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "46f0f3210768d796e8fa79ec70ee6af172dacbe7147f5e69be5240a47778302b" @@ -1121,7 +1107,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum page_size 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f89ef58b3d32420dbd1a43d2f38ae92f6239ef12bb556ab09ca55445f5a67242" "checksum parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab41b4aed082705d1056416ae4468b6ea99d52599ecf3169b00088d43113e337" "checksum parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94c8c7923936b28d546dfd14d4472eaf34c99b14e1c973a32b3e6d4eb04298c9" -"checksum proc-macro2 0.4.26 (registry+https://github.com/rust-lang/crates.io-index)" = "38fddd23d98b2144d197c0eca5705632d4fe2667d14a6be5df8934f8d74f1978" +"checksum proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)" = "4d317f9caece796be1980837fd5cb3dfec5613ebdb04ad0956deea83ce168915" "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" "checksum quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "cdd8e04bd9c52e0342b406469d494fcb033be4bdbe5c606016defbb1681411e1" "checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" @@ -1130,8 +1116,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d0e7a549d590831370895ab7ba4ea0c1b6b011d106b5ff2da6eee112615e6dc0" "checksum rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" "checksum rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" -"checksum rand_jitter 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f47842851e13bd803b506bdd1345328e0a1394733ee58e627b5e39332b9afafe" -"checksum rand_os 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f46fbd5550acf75b0c2730f5dd1873751daf9beb8f11b44027778fae50d7feca" +"checksum rand_jitter 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b9ea758282efe12823e0d952ddb269d2e1897227e464919a554f2a03ef1b832" +"checksum rand_os 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b7c690732391ae0abafced5015ffb53656abfaec61b342290e5eb56b286a679d" "checksum rand_pcg 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "086bd09a33c7044e56bb44d5bdde5a60e7f119a9e95b0775f545de759a32fe05" "checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" "checksum raw-cpuid 6.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "30a9d219c32c9132f7be513c18be77c9881c7107d2ab5569d205a6a0f0e6dc7d" @@ -1145,11 +1131,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" -"checksum serde 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)" = "534b8b91a95e0f71bca3ed5824752d558da048d4248c91af873b63bd60519752" +"checksum serde 1.0.87 (registry+https://github.com/rust-lang/crates.io-index)" = "2e20fde37801e83c891a2dc4ebd3b81f0da4d1fb67a9e0a2a3b921e2536a58ee" "checksum serde-bench 0.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "d733da87e79faaac25616e33d26299a41143fd4cd42746cbb0e91d8feea243fd" "checksum serde_bytes 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)" = "adb6e51a6b3696b301bc221d785f898b4457c619b51d7ce195a6d20baecb37b3" -"checksum serde_derive 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)" = "a915306b0f1ac5607797697148c223bedeaa36bcc2e28a01441cd638cc6567b4" -"checksum serde_json 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)" = "4b90a9fbe1211e57d3e1c15670f1cb00802988fb23a1a4aad7a2b63544f1920e" +"checksum serde_derive 1.0.87 (registry+https://github.com/rust-lang/crates.io-index)" = "633e97856567e518b59ffb2ad7c7a4fd4c5d91d9c7f32dd38a27b2bf7e8114ea" +"checksum serde_json 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)" = "27dce848e7467aa0e2fcaf0a413641499c0b745452aaca1194d24dedde9e13c9" "checksum sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b4d8bfd0e469f417657573d8451fb33d16cfe0989359b93baf3a1ffc639543d" "checksum smallvec 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "88aea073965ab29f6edb5493faf96ad662fb18aa9eeb186a3b7057951605ed15" "checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" diff --git a/lib/llvm-backend/src/code.rs b/lib/llvm-backend/src/code.rs index e177cc375..fb9e53520 100644 --- a/lib/llvm-backend/src/code.rs +++ b/lib/llvm-backend/src/code.rs @@ -3,30 +3,35 @@ use inkwell::{ context::Context, module::Module, passes::PassManager, - types::{BasicType, BasicTypeEnum, FunctionType}, - values::{BasicValue, FunctionValue, PhiValue}, + types::{BasicType, BasicTypeEnum, FunctionType, PointerType}, + values::{BasicValue, FunctionValue, PhiValue, PointerValue}, FloatPredicate, IntPredicate, }; use smallvec::SmallVec; use wasmer_runtime_core::{ + memory::MemoryType, module::ModuleInfo, structures::{Map, SliceMap, TypedIndex}, - types::{FuncIndex, MemoryIndex, FuncSig, LocalFuncIndex, LocalOrImport, SigIndex, Type, MemoryType}, + types::{FuncIndex, FuncSig, LocalFuncIndex, LocalOrImport, MemoryIndex, SigIndex, Type}, +}; +use wasmparser::{ + BinaryReaderError, CodeSectionReader, LocalsReader, MemoryImmediate, Operator, OperatorsReader, }; -use wasmparser::{BinaryReaderError, CodeSectionReader, LocalsReader, Operator, OperatorsReader}; -use crate::intrinsics::Intrinsics; +use crate::intrinsics::{CtxType, Intrinsics}; use crate::read_info::type_to_type; use crate::state::{ControlFrame, IfElseState, State}; fn func_sig_to_llvm(context: &Context, intrinsics: &Intrinsics, sig: &FuncSig) -> FunctionType { let user_param_types = sig.params().iter().map(|&ty| type_to_llvm(intrinsics, ty)); - let param_types: Vec<_> = user_param_types.collect(); + let param_types: Vec<_> = std::iter::once(intrinsics.ctx_ptr_ty.as_basic_type_enum()) + .chain(user_param_types) + .collect(); match sig.returns() { - [] => intrinsics.void_ty.fn_type(¶m_types, false), - [single_value] => type_to_llvm(intrinsics, *single_value).fn_type(¶m_types, false), + &[] => intrinsics.void_ty.fn_type(¶m_types, false), + &[single_value] => type_to_llvm(intrinsics, single_value).fn_type(¶m_types, false), returns @ _ => { let basic_types: Vec<_> = returns .iter() @@ -149,14 +154,22 @@ fn parse_function( state.push_block(return_block, phis); builder.position_at_end(&entry_block); - let mut locals = Vec::with_capacity(locals_reader.get_count() as usize); - locals.extend(function.get_param_iter().enumerate().map(|(index, param)| { - let ty = param.get_type(); + let mut ctx = intrinsics.ctx(info, builder, &function); - let alloca = builder.build_alloca(ty, &format!("local{}", index)); - builder.build_store(alloca, param); - alloca - })); + let mut locals = Vec::with_capacity(locals_reader.get_count() as usize); + locals.extend( + function + .get_param_iter() + .skip(1) + .enumerate() + .map(|(index, param)| { + let ty = param.get_type(); + + let alloca = builder.build_alloca(ty, &format!("local{}", index)); + builder.build_store(alloca, param); + alloca + }), + ); for (index, local) in locals_reader.into_iter().enumerate().skip(locals.len()) { let (_, ty) = local?; @@ -520,11 +533,13 @@ fn parse_function( LocalOrImport::Local(local_func_index) => { let func_sig = &info.signatures[sigindex]; let func_value = functions[local_func_index]; - let call_site = builder.build_call( - func_value, - &state.peekn(func_sig.params().len())?.to_vec(), - &state.var_name(), - ); + let params: Vec<_> = [ctx.basic()] + .iter() + .chain(state.peekn(func_sig.params().len())?.iter()) + .map(|v| *v) + .collect(); + + let call_site = builder.build_call(func_value, ¶ms, &state.var_name()); if let Some(basic_value) = call_site.try_as_basic_value().left() { match func_sig.returns().len() { 1 => state.push1(basic_value), @@ -1179,24 +1194,378 @@ fn parse_function( unimplemented!("waiting on better bitcasting support in inkwell") } + /*************************** + * Load and Store instructions. + * https://github.com/sunfishcode/wasm-reference-manual/blob/master/WebAssembly.md#load-and-store-instructions + ***************************/ + Operator::I32Load { memarg } => { + let effective_address = resolve_memory_ptr( + builder, + intrinsics, + &mut state, + &mut ctx, + memarg, + intrinsics.i32_ptr_ty, + )?; + let result = builder.build_load(effective_address, &state.var_name()); + state.push1(result); + } + Operator::I64Load { memarg } => { + let effective_address = resolve_memory_ptr( + builder, + intrinsics, + &mut state, + &mut ctx, + memarg, + intrinsics.i64_ptr_ty, + )?; + let result = builder.build_load(effective_address, &state.var_name()); + state.push1(result); + } + Operator::F32Load { memarg } => { + let effective_address = resolve_memory_ptr( + builder, + intrinsics, + &mut state, + &mut ctx, + memarg, + intrinsics.i32_ptr_ty, + )?; + let result = builder.build_load(effective_address, &state.var_name()); + state.push1(result); + } + Operator::F64Load { memarg } => { + let effective_address = resolve_memory_ptr( + builder, + intrinsics, + &mut state, + &mut ctx, + memarg, + intrinsics.f64_ptr_ty, + )?; + let result = builder.build_load(effective_address, &state.var_name()); + state.push1(result); + } + + Operator::I32Store { memarg } => { + let value = state.pop1()?; + let effective_address = resolve_memory_ptr( + builder, + intrinsics, + &mut state, + &mut ctx, + memarg, + intrinsics.i32_ptr_ty, + )?; + builder.build_store(effective_address, value); + } + Operator::I64Store { memarg } => { + let value = state.pop1()?; + let effective_address = resolve_memory_ptr( + builder, + intrinsics, + &mut state, + &mut ctx, + memarg, + intrinsics.i64_ptr_ty, + )?; + builder.build_store(effective_address, value); + } + Operator::F32Store { memarg } => { + let value = state.pop1()?; + let effective_address = resolve_memory_ptr( + builder, + intrinsics, + &mut state, + &mut ctx, + memarg, + intrinsics.f32_ptr_ty, + )?; + builder.build_store(effective_address, value); + } + Operator::F64Store { memarg } => { + let value = state.pop1()?; + let effective_address = resolve_memory_ptr( + builder, + intrinsics, + &mut state, + &mut ctx, + memarg, + intrinsics.f64_ptr_ty, + )?; + builder.build_store(effective_address, value); + } + + Operator::I32Load8S { memarg } => { + let effective_address = resolve_memory_ptr( + builder, + intrinsics, + &mut state, + &mut ctx, + memarg, + intrinsics.i8_ptr_ty, + )?; + let narrow_result = builder + .build_load(effective_address, &state.var_name()) + .into_int_value(); + let result = + builder.build_int_s_extend(narrow_result, intrinsics.i32_ty, &state.var_name()); + state.push1(result); + } + Operator::I32Load16S { memarg } => { + let effective_address = resolve_memory_ptr( + builder, + intrinsics, + &mut state, + &mut ctx, + memarg, + intrinsics.i16_ptr_ty, + )?; + let narrow_result = builder + .build_load(effective_address, &state.var_name()) + .into_int_value(); + let result = + builder.build_int_s_extend(narrow_result, intrinsics.i32_ty, &state.var_name()); + state.push1(result); + } + Operator::I64Load8S { memarg } => { + let effective_address = resolve_memory_ptr( + builder, + intrinsics, + &mut state, + &mut ctx, + memarg, + intrinsics.i8_ptr_ty, + )?; + let narrow_result = builder + .build_load(effective_address, &state.var_name()) + .into_int_value(); + let result = + builder.build_int_s_extend(narrow_result, intrinsics.i64_ty, &state.var_name()); + state.push1(result); + } + Operator::I64Load16S { memarg } => { + let effective_address = resolve_memory_ptr( + builder, + intrinsics, + &mut state, + &mut ctx, + memarg, + intrinsics.i16_ptr_ty, + )?; + let narrow_result = builder + .build_load(effective_address, &state.var_name()) + .into_int_value(); + let result = + builder.build_int_s_extend(narrow_result, intrinsics.i64_ty, &state.var_name()); + state.push1(result); + } + Operator::I64Load32S { memarg } => { + let effective_address = resolve_memory_ptr( + builder, + intrinsics, + &mut state, + &mut ctx, + memarg, + intrinsics.i32_ptr_ty, + )?; + let narrow_result = builder + .build_load(effective_address, &state.var_name()) + .into_int_value(); + let result = + builder.build_int_s_extend(narrow_result, intrinsics.i64_ty, &state.var_name()); + state.push1(result); + } + + Operator::I32Load8U { memarg } => { + let effective_address = resolve_memory_ptr( + builder, + intrinsics, + &mut state, + &mut ctx, + memarg, + intrinsics.i8_ptr_ty, + )?; + let narrow_result = builder + .build_load(effective_address, &state.var_name()) + .into_int_value(); + let result = + builder.build_int_z_extend(narrow_result, intrinsics.i32_ty, &state.var_name()); + state.push1(result); + } + Operator::I32Load16U { memarg } => { + let effective_address = resolve_memory_ptr( + builder, + intrinsics, + &mut state, + &mut ctx, + memarg, + intrinsics.i16_ptr_ty, + )?; + let narrow_result = builder + .build_load(effective_address, &state.var_name()) + .into_int_value(); + let result = + builder.build_int_z_extend(narrow_result, intrinsics.i32_ty, &state.var_name()); + state.push1(result); + } + Operator::I64Load8U { memarg } => { + let effective_address = resolve_memory_ptr( + builder, + intrinsics, + &mut state, + &mut ctx, + memarg, + intrinsics.i8_ptr_ty, + )?; + let narrow_result = builder + .build_load(effective_address, &state.var_name()) + .into_int_value(); + let result = + builder.build_int_z_extend(narrow_result, intrinsics.i64_ty, &state.var_name()); + state.push1(result); + } + Operator::I64Load16U { memarg } => { + let effective_address = resolve_memory_ptr( + builder, + intrinsics, + &mut state, + &mut ctx, + memarg, + intrinsics.i16_ptr_ty, + )?; + let narrow_result = builder + .build_load(effective_address, &state.var_name()) + .into_int_value(); + let result = + builder.build_int_z_extend(narrow_result, intrinsics.i64_ty, &state.var_name()); + state.push1(result); + } + Operator::I64Load32U { memarg } => { + let effective_address = resolve_memory_ptr( + builder, + intrinsics, + &mut state, + &mut ctx, + memarg, + intrinsics.i32_ptr_ty, + )?; + let narrow_result = builder + .build_load(effective_address, &state.var_name()) + .into_int_value(); + let result = + builder.build_int_z_extend(narrow_result, intrinsics.i64_ty, &state.var_name()); + state.push1(result); + } + + Operator::I32Store8 { memarg } | Operator::I64Store8 { memarg } => { + let value = state.pop1()?.into_int_value(); + let effective_address = resolve_memory_ptr( + builder, + intrinsics, + &mut state, + &mut ctx, + memarg, + intrinsics.i8_ptr_ty, + )?; + let narrow_value = + builder.build_int_truncate(value, intrinsics.i8_ty, &state.var_name()); + builder.build_store(effective_address, narrow_value); + } + Operator::I32Store16 { memarg } | Operator::I64Store16 { memarg } => { + let value = state.pop1()?.into_int_value(); + let effective_address = resolve_memory_ptr( + builder, + intrinsics, + &mut state, + &mut ctx, + memarg, + intrinsics.i16_ptr_ty, + )?; + let narrow_value = + builder.build_int_truncate(value, intrinsics.i16_ty, &state.var_name()); + builder.build_store(effective_address, narrow_value); + } + Operator::I64Store32 { memarg } => { + let value = state.pop1()?.into_int_value(); + let effective_address = resolve_memory_ptr( + builder, + intrinsics, + &mut state, + &mut ctx, + memarg, + intrinsics.i32_ptr_ty, + )?; + let narrow_value = + builder.build_int_truncate(value, intrinsics.i32_ty, &state.var_name()); + builder.build_store(effective_address, narrow_value); + } + Operator::MemoryGrow { reserved } => { - - let memory_grow_const = intrinsics.i32_ty.const_int(reserved as u64, false); - - let memory_index = MemoryIndex::new(reserved); - match memory_index.local_or_import(info) { + let memory_index = MemoryIndex::new(reserved as usize); + let func_value = match memory_index.local_or_import(info) { LocalOrImport::Local(local_mem_index) => { let mem_desc = &info.memories[local_mem_index]; match mem_desc.memory_type() { - MemoryType::Dynamic => { - - } + MemoryType::Dynamic => intrinsics.memory_grow_dynamic_local, + MemoryType::Static => intrinsics.memory_grow_static_local, + MemoryType::SharedStatic => intrinsics.memory_grow_shared_local, } - }, + } LocalOrImport::Import(import_mem_index) => { + let mem_desc = &info.imported_memories[import_mem_index].1; + match mem_desc.memory_type() { + MemoryType::Dynamic => intrinsics.memory_grow_dynamic_import, + MemoryType::Static => intrinsics.memory_grow_static_import, + MemoryType::SharedStatic => intrinsics.memory_grow_shared_import, + } + } + }; - }, - } + let memory_index_const = intrinsics + .i32_ty + .const_int(reserved as u64, false) + .as_basic_value_enum(); + let delta = state.pop1()?; + + let result = builder.build_call( + func_value, + &[ctx.basic(), memory_index_const, delta], + &state.var_name(), + ); + state.push1(result.try_as_basic_value().left().unwrap()); + } + Operator::MemorySize { reserved } => { + let memory_index = MemoryIndex::new(reserved as usize); + let func_value = match memory_index.local_or_import(info) { + LocalOrImport::Local(local_mem_index) => { + let mem_desc = &info.memories[local_mem_index]; + match mem_desc.memory_type() { + MemoryType::Dynamic => intrinsics.memory_size_dynamic_local, + MemoryType::Static => intrinsics.memory_size_static_local, + MemoryType::SharedStatic => intrinsics.memory_size_shared_local, + } + } + LocalOrImport::Import(import_mem_index) => { + let mem_desc = &info.imported_memories[import_mem_index].1; + match mem_desc.memory_type() { + MemoryType::Dynamic => intrinsics.memory_size_dynamic_import, + MemoryType::Static => intrinsics.memory_size_static_import, + MemoryType::SharedStatic => intrinsics.memory_size_shared_import, + } + } + }; + + let memory_index_const = intrinsics + .i32_ty + .const_int(reserved as u64, false) + .as_basic_value_enum(); + let result = builder.build_call( + func_value, + &[ctx.basic(), memory_index_const], + &state.var_name(), + ); + state.push1(result.try_as_basic_value().left().unwrap()); } op @ _ => { @@ -1209,9 +1578,41 @@ fn parse_function( let pass_manager = PassManager::create_for_module(); pass_manager.add_promote_memory_to_register_pass(); pass_manager.add_cfg_simplification_pass(); + pass_manager.add_instruction_combining_pass(); + // pass_manager.add_aggressive_inst_combiner_pass(); + // pass_manager.add_merged_load_store_motion_pass(); + // pass_manager.add_sccp_pass(); + pass_manager.add_gvn_pass(); + pass_manager.add_new_gvn_pass(); + pass_manager.add_aggressive_dce_pass(); pass_manager.run_on_module(module); println!("{}", module.print_to_string().to_string()); Ok(()) } + +fn resolve_memory_ptr( + builder: &Builder, + intrinsics: &Intrinsics, + state: &mut State, + ctx: &mut CtxType, + memarg: MemoryImmediate, + ptr_ty: PointerType, +) -> Result { + // Ignore alignment hint for the time being. + let imm_offset = intrinsics.i64_ty.const_int(memarg.offset as u64, false); + let var_offset_i32 = state.pop1()?.into_int_value(); + let var_offset = + builder.build_int_z_extend(var_offset_i32, intrinsics.i64_ty, &state.var_name()); + let effective_offset = builder.build_int_add(var_offset, imm_offset, &state.var_name()); + let (mem_base, mem_bound) = ctx.memory(MemoryIndex::new(0)); + let mem_base_int = builder.build_ptr_to_int(mem_base, intrinsics.i64_ty, &state.var_name()); + let effective_address_int = + builder.build_int_add(mem_base_int, effective_offset, &state.var_name()); + Ok(builder.build_int_to_ptr( + effective_address_int, + intrinsics.i32_ptr_ty, + &state.var_name(), + )) +} diff --git a/lib/llvm-backend/src/intrinsics.rs b/lib/llvm-backend/src/intrinsics.rs index ff6847b3b..f2e681f38 100644 --- a/lib/llvm-backend/src/intrinsics.rs +++ b/lib/llvm-backend/src/intrinsics.rs @@ -1,8 +1,18 @@ +use hashbrown::HashMap; use inkwell::{ + builder::Builder, context::Context, module::Module, - types::{BasicType, FloatType, IntType, VoidType}, - values::{FloatValue, FunctionValue, IntValue}, + types::{BasicType, FloatType, IntType, PointerType, StructType, VoidType}, + values::{BasicValue, BasicValueEnum, FloatValue, FunctionValue, IntValue, PointerValue}, + AddressSpace, +}; +use std::marker::PhantomData; +use wasmer_runtime_core::{ + memory::MemoryType, + module::ModuleInfo, + structures::TypedIndex, + types::{LocalOrImport, MemoryIndex}, }; pub struct Intrinsics { @@ -44,11 +54,20 @@ pub struct Intrinsics { pub void_ty: VoidType, pub i1_ty: IntType, + pub i8_ty: IntType, + pub i16_ty: IntType, pub i32_ty: IntType, pub i64_ty: IntType, pub f32_ty: FloatType, pub f64_ty: FloatType, + pub i8_ptr_ty: PointerType, + pub i16_ptr_ty: PointerType, + pub i32_ptr_ty: PointerType, + pub i64_ptr_ty: PointerType, + pub f32_ptr_ty: PointerType, + pub f64_ptr_ty: PointerType, + pub i1_zero: IntValue, pub i32_zero: IntValue, pub i64_zero: IntValue, @@ -69,18 +88,30 @@ pub struct Intrinsics { pub memory_size_dynamic_import: FunctionValue, pub memory_size_static_import: FunctionValue, pub memory_size_shared_import: FunctionValue, - // pub ctx_ty: StructType, + + ctx_ty: StructType, + pub ctx_ptr_ty: PointerType, } impl Intrinsics { pub fn declare(module: &Module, context: &Context) -> Self { let void_ty = context.void_type(); let i1_ty = context.bool_type(); + let i8_ty = context.i8_type(); + let i16_ty = context.i16_type(); let i32_ty = context.i32_type(); let i64_ty = context.i64_type(); let f32_ty = context.f32_type(); let f64_ty = context.f64_type(); - // let ctx_ty = context.struct_type(&[], false); + + let i8_ptr_ty = i8_ty.ptr_type(AddressSpace::Generic); + let i16_ptr_ty = i16_ty.ptr_type(AddressSpace::Generic); + let i32_ptr_ty = i32_ty.ptr_type(AddressSpace::Generic); + let i64_ptr_ty = i64_ty.ptr_type(AddressSpace::Generic); + let f32_ptr_ty = f32_ty.ptr_type(AddressSpace::Generic); + let f64_ptr_ty = f64_ty.ptr_type(AddressSpace::Generic); + + let opaque_ptr_ty = void_ty.ptr_type(AddressSpace::Generic); let i1_zero = i1_ty.const_int(0, false); let i32_zero = i32_ty.const_int(0, false); @@ -93,6 +124,53 @@ impl Intrinsics { let i64_ty_basic = i64_ty.as_basic_type_enum(); let f32_ty_basic = f32_ty.as_basic_type_enum(); let f64_ty_basic = f64_ty.as_basic_type_enum(); + let i8_ptr_ty_basic = i8_ptr_ty.as_basic_type_enum(); + let opaque_ptr_ty_basic = opaque_ptr_ty.as_basic_type_enum(); + + let ctx_ty = context.opaque_struct_type("ctx"); + let ctx_ptr_ty = ctx_ty.ptr_type(AddressSpace::Generic); + + let local_memory_ty = + context.struct_type(&[i8_ptr_ty_basic, i64_ty_basic, opaque_ptr_ty_basic], false); + let local_table_ty = local_memory_ty; + let local_global_ty = i64_ty; + let imported_func_ty = context.struct_type( + &[opaque_ptr_ty_basic, ctx_ptr_ty.as_basic_type_enum()], + false, + ); + ctx_ty.set_body( + &[ + local_memory_ty + .ptr_type(AddressSpace::Generic) + .ptr_type(AddressSpace::Generic) + .as_basic_type_enum(), + local_table_ty + .ptr_type(AddressSpace::Generic) + .ptr_type(AddressSpace::Generic) + .as_basic_type_enum(), + local_global_ty + .ptr_type(AddressSpace::Generic) + .ptr_type(AddressSpace::Generic) + .as_basic_type_enum(), + local_memory_ty + .ptr_type(AddressSpace::Generic) + .ptr_type(AddressSpace::Generic) + .as_basic_type_enum(), + local_table_ty + .ptr_type(AddressSpace::Generic) + .ptr_type(AddressSpace::Generic) + .as_basic_type_enum(), + local_global_ty + .ptr_type(AddressSpace::Generic) + .ptr_type(AddressSpace::Generic) + .as_basic_type_enum(), + imported_func_ty + .ptr_type(AddressSpace::Generic) + .ptr_type(AddressSpace::Generic) + .as_basic_type_enum(), + ], + false, + ); let ret_i32_take_i32_i1 = i32_ty.fn_type(&[i32_ty_basic, i1_ty_basic], false); let ret_i64_take_i64_i1 = i64_ty.fn_type(&[i64_ty_basic, i1_ty_basic], false); @@ -106,8 +184,9 @@ impl Intrinsics { let ret_f32_take_f32_f32 = f32_ty.fn_type(&[f32_ty_basic, f32_ty_basic], false); let ret_f64_take_f64_f64 = f64_ty.fn_type(&[f64_ty_basic, f64_ty_basic], false); - let ret_i32_take_i64_i32_i32 = i32_ty.fn_type(&[i64_ty, i32_ty, i32_ty], false); - let ret_i32_take_i64_i32 = i32_ty.fn_type(&[i64_ty, i32_ty], false); + let ret_i32_take_i64_i32_i32 = + i32_ty.fn_type(&[i64_ty_basic, i32_ty_basic, i32_ty_basic], false); + let ret_i32_take_i64_i32 = i32_ty.fn_type(&[i64_ty_basic, i32_ty_basic], false); Self { ctlz_i32: module.add_function("llvm.ctlz.i32", ret_i32_take_i32_i1, None), @@ -148,11 +227,20 @@ impl Intrinsics { void_ty, i1_ty, + i8_ty, + i16_ty, i32_ty, i64_ty, f32_ty, f64_ty, + i8_ptr_ty, + i16_ptr_ty, + i32_ptr_ty, + i64_ptr_ty, + f32_ptr_ty, + f64_ptr_ty, + i1_zero, i32_zero, i64_zero, @@ -160,23 +248,229 @@ impl Intrinsics { f64_zero, // VM intrinsics. - memory_grow_dynamic_local: module.add_function("vm.memory.grow.dynamic.local", ret_i32_take_i64_i32_i32, None), - memory_grow_static_local: module.add_function("vm.memory.grow.static.local", ret_i32_take_i64_i32_i32, None), - memory_grow_shared_local: module.add_function("vm.memory.grow.shared.local", ret_i32_take_i64_i32_i32, None), - memory_grow_dynamic_import: module.add_function("vm.memory.grow.dynamic.import", ret_i32_take_i64_i32_i32, None), - memory_grow_static_import: module.add_function("vm.memory.grow.static.import", ret_i32_take_i64_i32_i32, None), - memory_grow_shared_import: module.add_function("vm.memory.grow.shared.import", ret_i32_take_i64_i32_i32, None), + memory_grow_dynamic_local: module.add_function( + "vm.memory.grow.dynamic.local", + ret_i32_take_i64_i32_i32, + None, + ), + memory_grow_static_local: module.add_function( + "vm.memory.grow.static.local", + ret_i32_take_i64_i32_i32, + None, + ), + memory_grow_shared_local: module.add_function( + "vm.memory.grow.shared.local", + ret_i32_take_i64_i32_i32, + None, + ), + memory_grow_dynamic_import: module.add_function( + "vm.memory.grow.dynamic.import", + ret_i32_take_i64_i32_i32, + None, + ), + memory_grow_static_import: module.add_function( + "vm.memory.grow.static.import", + ret_i32_take_i64_i32_i32, + None, + ), + memory_grow_shared_import: module.add_function( + "vm.memory.grow.shared.import", + ret_i32_take_i64_i32_i32, + None, + ), - memory_size_dynamic_local: module.add_function("vm.memory.size.dynamic.local", ret_i32_take_i64_i32, None), - memory_size_static_local: module.add_function("vm.memory.size.static.local", ret_i32_take_i64_i32, None), - memory_size_shared_local: module.add_function("vm.memory.size.shared.local", ret_i32_take_i64_i32, None), - memory_size_dynamic_import: module.add_function("vm.memory.size.dynamic.import", ret_i32_take_i64_i32, None), - memory_size_static_import: module.add_function("vm.memory.size.static.import", ret_i32_take_i64_i32, None), - memory_size_shared_import: module.add_function("vm.memory.size.shared.import", ret_i32_take_i64_i32, None), + memory_size_dynamic_local: module.add_function( + "vm.memory.size.dynamic.local", + ret_i32_take_i64_i32, + None, + ), + memory_size_static_local: module.add_function( + "vm.memory.size.static.local", + ret_i32_take_i64_i32, + None, + ), + memory_size_shared_local: module.add_function( + "vm.memory.size.shared.local", + ret_i32_take_i64_i32, + None, + ), + memory_size_dynamic_import: module.add_function( + "vm.memory.size.dynamic.import", + ret_i32_take_i64_i32, + None, + ), + memory_size_static_import: module.add_function( + "vm.memory.size.static.import", + ret_i32_take_i64_i32, + None, + ), + memory_size_shared_import: module.add_function( + "vm.memory.size.shared.import", + ret_i32_take_i64_i32, + None, + ), + + ctx_ty, + ctx_ptr_ty, + } + } + + pub fn ctx<'a>( + &'a self, + info: &'a ModuleInfo, + builder: &'a Builder, + func_value: &'a FunctionValue, + ) -> CtxType<'a> { + CtxType { + ctx_ty: self.ctx_ty, + ctx_ptr_ty: self.ctx_ptr_ty, + + ctx_ptr_value: func_value.get_nth_param(0).unwrap().into_pointer_value(), + + builder, + intrinsics: self, + info, + + cached_memories: HashMap::new(), + + _phantom: PhantomData, } } } -// pub struct CtxType { -// ctx_ty: StructType, +enum MemoryCache { + /// The memory moves around. + Dynamic { + ptr_to_base_ptr: PointerValue, + ptr_to_bounds: PointerValue, + }, + /// The memory is always in the same place. + Static { + base_ptr: PointerValue, + bounds: IntValue, + }, +} + +pub struct CtxType<'a> { + ctx_ty: StructType, + ctx_ptr_ty: PointerType, + + ctx_ptr_value: PointerValue, + + builder: &'a Builder, + intrinsics: &'a Intrinsics, + info: &'a ModuleInfo, + + cached_memories: HashMap, + + _phantom: PhantomData<&'a FunctionValue>, +} + +impl<'a> CtxType<'a> { + pub fn basic(&self) -> BasicValueEnum { + self.ctx_ptr_value.as_basic_value_enum() + } + + pub fn memory(&mut self, index: MemoryIndex) -> (PointerValue, IntValue) { + let (cached_memories, builder, info, ctx_ptr_value, intrinsics) = ( + &mut self.cached_memories, + self.builder, + self.info, + self.ctx_ptr_value, + self.intrinsics, + ); + + let memory_cache = cached_memories.entry(index).or_insert_with(|| { + let (memory_array_ptr_ptr, index, memory_type) = match index.local_or_import(info) { + LocalOrImport::Local(local_mem_index) => ( + unsafe { builder.build_struct_gep(ctx_ptr_value, 0, "memory_array_ptr_ptr") }, + local_mem_index.index() as u64, + info.memories[local_mem_index].memory_type(), + ), + LocalOrImport::Import(import_mem_index) => ( + unsafe { builder.build_struct_gep(ctx_ptr_value, 3, "memory_array_ptr_ptr") }, + import_mem_index.index() as u64, + info.imported_memories[import_mem_index].1.memory_type(), + ), + }; + + let memory_array_ptr = builder + .build_load(memory_array_ptr_ptr, "memory_array_ptr") + .into_pointer_value(); + let const_index = intrinsics.i32_ty.const_int(index, false); + let memory_ptr_ptr = unsafe { + builder.build_in_bounds_gep(memory_array_ptr, &[const_index], "memory_ptr_ptr") + }; + let memory_ptr = builder + .build_load(memory_ptr_ptr, "memory_ptr") + .into_pointer_value(); + + let (ptr_to_base_ptr, ptr_to_bounds) = unsafe { + ( + builder.build_struct_gep(memory_ptr, 0, "base_ptr"), + builder.build_struct_gep(memory_ptr, 1, "bounds_ptr"), + ) + }; + + match memory_type { + MemoryType::Dynamic => MemoryCache::Dynamic { + ptr_to_base_ptr, + ptr_to_bounds, + }, + MemoryType::Static | MemoryType::SharedStatic => MemoryCache::Static { + base_ptr: builder + .build_load(ptr_to_base_ptr, "base") + .into_pointer_value(), + bounds: builder.build_load(ptr_to_bounds, "bounds").into_int_value(), + }, + } + }); + + match memory_cache { + MemoryCache::Dynamic { + ptr_to_base_ptr, + ptr_to_bounds, + } => { + let base = builder + .build_load(*ptr_to_base_ptr, "base") + .into_pointer_value(); + let bounds = builder + .build_load(*ptr_to_bounds, "bounds") + .into_int_value(); + + (base, bounds) + } + MemoryCache::Static { base_ptr, bounds } => (*base_ptr, *bounds), + } + } +} + +// pub struct Ctx { +// /// A pointer to an array of locally-defined memories, indexed by `MemoryIndex`. +// pub(crate) memories: *mut *mut LocalMemory, + +// /// A pointer to an array of locally-defined tables, indexed by `TableIndex`. +// pub(crate) tables: *mut *mut LocalTable, + +// /// A pointer to an array of locally-defined globals, indexed by `GlobalIndex`. +// pub(crate) globals: *mut *mut LocalGlobal, + +// /// A pointer to an array of imported memories, indexed by `MemoryIndex, +// pub(crate) imported_memories: *mut *mut LocalMemory, + +// /// A pointer to an array of imported tables, indexed by `TableIndex`. +// pub(crate) imported_tables: *mut *mut LocalTable, + +// /// A pointer to an array of imported globals, indexed by `GlobalIndex`. +// pub(crate) imported_globals: *mut *mut LocalGlobal, + +// /// A pointer to an array of imported functions, indexed by `FuncIndex`. +// pub(crate) imported_funcs: *mut ImportedFunc, + +// local_backing: *mut LocalBacking, +// import_backing: *mut ImportBacking, +// module: *const ModuleInner, + +// pub data: *mut c_void, +// pub data_finalizer: Option, // } diff --git a/lib/llvm-backend/src/lib.rs b/lib/llvm-backend/src/lib.rs index b02b39cbf..e691acebb 100644 --- a/lib/llvm-backend/src/lib.rs +++ b/lib/llvm-backend/src/lib.rs @@ -34,19 +34,16 @@ fn test_read_module() { (module (type $t0 (func (param i32) (result i32))) (type $t1 (func (result i32))) + (memory 1) (func $foo (type $t0) (param i32) (result i32) get_local 0 - (if - (then - i32.const 42 - set_local 0 - ) - (else - i32.const 24 - set_local 0 - ) - ) - get_local 0 + i32.load offset=16 + i32.const 1 + memory.grow + drop + i32.const 0 + i32.load offset=4 + i32.add )) "#; let wasm = wat2wasm(wat).unwrap(); diff --git a/lib/llvm-backend/src/state.rs b/lib/llvm-backend/src/state.rs index 674eee04c..47da54a6d 100644 --- a/lib/llvm-backend/src/state.rs +++ b/lib/llvm-backend/src/state.rs @@ -72,6 +72,7 @@ pub struct State { stack: Vec, control_stack: Vec, value_counter: Cell, + pub reachable: bool, }