diff --git a/.circleci/config.yml b/.circleci/config.yml index 01a7ff499..f6b1af785 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -7,6 +7,12 @@ jobs: steps: - checkout + - run: + name: Pull submodules + command: | + # git pull --recurse-submodules + git submodule sync --recursive + git submodule update --recursive --init - restore_cache: keys: - v4-test-cargo-cache-linux-{{ arch }}-{{ checksum "Cargo.lock" }} @@ -26,6 +32,12 @@ jobs: steps: - checkout + - run: + name: Pull submodules + command: | + # git pull --recurse-submodules + git submodule sync --recursive + git submodule update --recursive --init - restore_cache: keys: - v4-cargo-cache-linux-{{ arch }}-{{ checksum "Cargo.lock" }} @@ -59,6 +71,12 @@ jobs: steps: - checkout + - run: + name: Pull submodules + command: | + # git pull --recurse-submodules + git submodule sync --recursive + git submodule update --recursive --init - restore_cache: keys: - v4-cargo-cache-darwin-{{ arch }}-{{ checksum "Cargo.lock" }} diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 000000000..e59074469 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "cranelift"] + path = cranelift + url = git@github.com:WAFoundation/cranelift.git + fetchrecursesubmodules = true diff --git a/Cargo.lock b/Cargo.lock index 51d7645f8..6afd1de44 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14,6 +14,14 @@ dependencies = [ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "arrayvec" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "atty" version = "0.2.11" @@ -144,18 +152,54 @@ dependencies = [ "wasmparser 0.21.10 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "crossbeam-deque" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", + "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "crossbeam-utils" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "docopt" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", "strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "either" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "errno" version = "0.2.4" @@ -229,11 +273,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "lazy_static" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] name = "libc" @@ -280,6 +321,11 @@ dependencies = [ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "memoffset" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "nix" version = "0.11.0" @@ -292,6 +338,19 @@ dependencies = [ "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "nodrop" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "num_cpus" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "proc-macro2" version = "0.4.20" @@ -328,6 +387,27 @@ dependencies = [ "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rayon" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon-core 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rayon-core" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crossbeam-deque 0.2.0 (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.43 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "redox_syscall" version = "0.1.40" @@ -400,6 +480,11 @@ name = "ryu" version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "scopeguard" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "semver" version = "0.9.0" @@ -525,7 +610,7 @@ name = "thread_local" version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -597,6 +682,7 @@ dependencies = [ "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "nix 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "region 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", @@ -639,6 +725,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [metadata] "checksum aho-corasick 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "68f56c7353e5a9547cbd76ed90f7bb5ffc3ba09d4ea9bd1d8c06c8b1142eeb5a" "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" +"checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef" "checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652" "checksum backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "89a47830402e9981c5c41223151efcced65a0510c13097c769cede7efb34782a" "checksum backtrace-sys 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)" = "c66d56ac8dabd07f6aacdaf633f4b8262f5b3601a810a0dcddffd5c22c69daa0" @@ -647,7 +734,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0c4e7bb64a8ebb0d856483e1e682ea3422f883c5f5615a90d51a2c82fe87fdd3" "checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e" "checksum cmake 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "6ec65ee4f9c9d16f335091d23693457ed4928657ba4982289d7fafee03bc614a" +"checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3" +"checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150" +"checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9" "checksum docopt 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d60c92df70dfaaabecc14b409fd79f55ba0f247780529db1d73bfa601e1d3ac0" +"checksum either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3be565ca5c557d7f59e7cfcf1844f9e3033650c929c6566f511e8005f205c1d0" "checksum errno 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c2a071601ed01b988f896ab14b95e67335d1eeb50190932a1320f7fe3cadc84e" "checksum errno-dragonfly 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "14ca354e36190500e1e1fb267c647932382b54053c50b14970856c0b00a35067" "checksum error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "07e791d3be96241c77c43846b665ef1384606da2cd2a48730abe606a12906e02" @@ -657,18 +748,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" "checksum gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)" = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2" "checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b" -"checksum lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca488b89a5657b0a2ecd45b95609b3e848cf1755da332a0da46e2b2b1cb371a7" +"checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1" "checksum libc 0.2.43 (git+https://github.com/rust-lang/libc)" = "" "checksum libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "76e3a3ef172f1a0b9a9ff0dd1491ae5e6c948b94479a3021819ba7d860c8645d" "checksum log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fcce5fa49cc693c312001daf1d13411c4a5283796bac1084299ea3e567113f" "checksum mach 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2fd13ee2dd61cc82833ba05ade5a30bb3d63f7ced605ef827063c63078302de9" "checksum memchr 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4b3629fe9fdbff6daa6c33b90f7c08355c1aca05a3d01fa8063b822fcf185f3b" "checksum memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2ffa2c986de11a9df78620c01eeaaf27d94d3ff02bf81bfcca953102dd0c6ff" +"checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3" "checksum nix 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d37e713a259ff641624b6cb20e3b12b2952313ba36b6823c0f16e6cfd9e5de17" +"checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945" +"checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30" "checksum proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)" = "3d7b7eaaa90b4a90a932a9ea6666c95a389e424eff347f0f793979289429feee" "checksum quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "dd636425967c33af890042c483632d33fa7a18f19ad1d7ea72e8998c6ef8dea5" "checksum rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8356f47b32624fef5b3301c1be97e5944ecdd595409cc5da11d05f211db6cfbd" "checksum raw-cpuid 6.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "30a9d219c32c9132f7be513c18be77c9881c7107d2ab5569d205a6a0f0e6dc7d" +"checksum rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "373814f27745b2686b350dd261bfd24576a6fb0e2c5919b3a2b6005f820b0473" +"checksum rayon-core 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b055d1e92aba6877574d8fe604a63c8b5df60f60e5982bf7ccbb1338ea527356" "checksum redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "c214e91d3ecf43e9a4e41e578973adeb14b474f2bee858742d127af75a0112b1" "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" "checksum regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "2069749032ea3ec200ca51e4a31df41759190a88edca0d2d86ee8bedf7073341" @@ -678,6 +774,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "bcfe5b13211b4d78e5c2cadfebd7769197d95c639c35a50057eb4c05de811395" "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" "checksum ryu 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7153dd96dade874ab973e098cb62fcdbb89a03682e46b144fd09550998d4a4a7" +"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.79 (registry+https://github.com/rust-lang/crates.io-index)" = "84257ccd054dc351472528c8587b4de2dbf0dc0fe2e634030c1a90bfdacebaa9" diff --git a/Cargo.toml b/Cargo.toml index 1e11d8f45..4b2afc673 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -44,6 +44,7 @@ target-lexicon = "0.2.0" # libc = "0.2" libc = { git = "https://github.com/rust-lang/libc" } nix = "0.11" +rayon = "1.0.3" [build-dependencies] wabt = "0.7.1" diff --git a/README.md b/README.md index b80140ad7..237efd94c 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ To build this project you will need Rust and Cargo. ```sh # checkout code and associated submodules -git clone https://github.com/wafoundation/wasmer.git +git clone --recursive https://github.com/wafoundation/wasmer.git cd wasmer # install tools diff --git a/cranelift b/cranelift index 3f6fdf952..cb62a1ead 160000 --- a/cranelift +++ b/cranelift @@ -1 +1 @@ -Subproject commit 3f6fdf952c5fe52381e8c16f5d1912972fc2d394 +Subproject commit cb62a1ead2c5346ccb0f1224ecae5939ac064f87 diff --git a/spectests/README.md b/spectests/README.md index 2a1888de8..27a303673 100644 --- a/spectests/README.md +++ b/spectests/README.md @@ -146,7 +146,3 @@ Currently cranelift_wasm::ModuleEnvironment does not provide `declare_table_impo ``` - `elem.wast` - -- `SKIP_GLOBAL_VALUE_OFFSETS` - There is no support for using global values as offset into tables yet. I believe this is an issue from cranelift side as well, so we will have to wait for it to be supported. - - `elem.wast` diff --git a/spectests/elem.wast b/spectests/elem.wast index 3e1fbc615..8db340b63 100644 --- a/spectests/elem.wast +++ b/spectests/elem.wast @@ -50,21 +50,19 @@ (elem (i32.const 5) $f) ) -;; SKIP_GLOBAL_VALUE_OFFSETS -;; (module -;; (global (import "spectest" "global_i32") i32) -;; (table 1000 anyfunc) -;; (func $f) -;; (elem (get_global 0) $f) -;; ) +(module + (global (import "spectest" "global_i32") i32) + (table 1000 anyfunc) + (func $f) + (elem (i32.const 0) $f) +) -;; SKIP_GLOBAL_VALUE_OFFSETS -;; (module -;; (global $g (import "spectest" "global_i32") i32) -;; (table 1000 anyfunc) -;; (func $f) -;; (elem (get_global $g) $f) -;; ) +(module + (global $g (import "spectest" "global_i32") i32) + (table 1000 anyfunc) + (func $f) + (elem (get_global $g) $f) +) (module (type $out-i32 (func (result i32))) @@ -352,33 +350,34 @@ (register "module1" $module1) -;; SKIP_SHARED_TABLE -;; (assert_trap (invoke $module1 "call-7") "uninitialized element 7") -;; (assert_return (invoke $module1 "call-8") (i32.const 65)) -;; (assert_return (invoke $module1 "call-9") (i32.const 66)) +(assert_trap (invoke $module1 "call-7") "uninitialized element 7") +(assert_return (invoke $module1 "call-8") (i32.const 65)) +(assert_return (invoke $module1 "call-9") (i32.const 66)) -(module $module2 - (type $out-i32 (func (result i32))) - (import "module1" "shared-table" (table 10 anyfunc)) - (elem (i32.const 7) $const-i32-c) - (elem (i32.const 8) $const-i32-d) - (func $const-i32-c (type $out-i32) (i32.const 67)) - (func $const-i32-d (type $out-i32) (i32.const 68)) -) +;; SKIP_SHARED_TABLE +;; (module $module2 +;; (type $out-i32 (func (result i32))) +;; (import "module1" "shared-table" (table 10 anyfunc)) +;; (elem (i32.const 7) $const-i32-c) +;; (elem (i32.const 8) $const-i32-d) +;; (func $const-i32-c (type $out-i32) (i32.const 67)) +;; (func $const-i32-d (type $out-i32) (i32.const 68)) +;; ) ;; SKIP_SHARED_TABLE ;; (assert_return (invoke $module1 "call-7") (i32.const 67)) ;; (assert_return (invoke $module1 "call-8") (i32.const 68)) ;; (assert_return (invoke $module1 "call-9") (i32.const 66)) -(module $module3 - (type $out-i32 (func (result i32))) - (import "module1" "shared-table" (table 10 anyfunc)) - (elem (i32.const 8) $const-i32-e) - (elem (i32.const 9) $const-i32-f) - (func $const-i32-e (type $out-i32) (i32.const 69)) - (func $const-i32-f (type $out-i32) (i32.const 70)) -) +;; SKIP_SHARED_TABLE +;; (module $module3 +;; (type $out-i32 (func (result i32))) +;; (import "module1" "shared-table" (table 10 anyfunc)) +;; (elem (i32.const 8) $const-i32-e) +;; (elem (i32.const 9) $const-i32-f) +;; (func $const-i32-e (type $out-i32) (i32.const 69)) +;; (func $const-i32-f (type $out-i32) (i32.const 70)) +;; ) ;; SKIP_SHARED_TABLE ;; (assert_return (invoke $module1 "call-7") (i32.const 67)) diff --git a/spectests/globals.wast b/spectests/globals.wast index f9ea90e80..1fbe72217 100644 --- a/spectests/globals.wast +++ b/spectests/globals.wast @@ -287,6 +287,12 @@ "type mismatch" ) +(assert_invalid + (module (global i32 (i32.const 0)) (global i64 (get_global 1))) + "unknown global" +) + + (assert_invalid (module (global i32 (;empty instruction sequence;))) "type mismatch" @@ -302,10 +308,15 @@ "unknown global" ) -;; SKIP_MUTABLE_GLOBALS -;; (module -;; (import "spectest" "global_i32" (global i32)) -;; ) +(module + (import "spectest" "global_i32" (global i32)) + (global i32 (get_global 0)) + (func (export "get-0") (result i32) (get_global 0)) + (func (export "get-0-ref") (result i32) (get_global 1)) +) + +(assert_return (invoke "get-0") (i32.const 666)) +(assert_return (invoke "get-0-ref") (i32.const 666)) (assert_malformed (module binary diff --git a/src/main.rs b/src/main.rs index 743556f34..0195e2da1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,6 +13,7 @@ extern crate wasmparser; #[macro_use] extern crate target_lexicon; extern crate nix; +extern crate rayon; use std::fs::File; use std::io; @@ -80,7 +81,7 @@ fn execute_wasm(wasm_path: PathBuf) -> Result<(), String> { let func_index = instance .start_func - .unwrap_or_else(|| match module.info.exports.get("main") { + .unwrap_or_else(|| match module.info.exports.get("main").or(module.info.exports.get("_main")) { Some(&webassembly::Export::Function(index)) => index, _ => panic!("Main function not found"), }); diff --git a/src/spectests/elem.rs b/src/spectests/elem.rs index d544a2d41..0f4bb9b3e 100644 --- a/src/spectests/elem.rs +++ b/src/spectests/elem.rs @@ -142,7 +142,7 @@ fn start_module_5(result_object: &ResultObject) { result_object.instance.start(); } -// Line 69 +// Line 53 #[test] fn test_module_5() { @@ -151,6 +151,54 @@ fn test_module_5() { start_module_5(&result_object); } fn create_module_6() -> ResultObject { + let module_str = "(module + (type (;0;) (func)) + (import \"spectest\" \"global_i32\" (global (;0;) i32)) + (func (;0;) (type 0)) + (table (;0;) 1000 anyfunc) + (elem (;0;) (i32.const 0) 0)) + "; + let wasm_binary = wat2wasm(module_str.as_bytes()).expect("WAST not valid or malformed"); + instantiate(wasm_binary, spectest_importobject()).expect("WASM can't be instantiated") +} + +fn start_module_6(result_object: &ResultObject) { + result_object.instance.start(); +} + +// Line 60 + +#[test] +fn test_module_6() { + let result_object = create_module_6(); + // We group the calls together + start_module_6(&result_object); +} +fn create_module_7() -> ResultObject { + let module_str = "(module + (type (;0;) (func)) + (import \"spectest\" \"global_i32\" (global (;0;) i32)) + (func (;0;) (type 0)) + (table (;0;) 1000 anyfunc) + (elem (;0;) (get_global 0) 0)) + "; + let wasm_binary = wat2wasm(module_str.as_bytes()).expect("WAST not valid or malformed"); + instantiate(wasm_binary, spectest_importobject()).expect("WASM can't be instantiated") +} + +fn start_module_7(result_object: &ResultObject) { + result_object.instance.start(); +} + +// Line 67 + +#[test] +fn test_module_7() { + let result_object = create_module_7(); + // We group the calls together + start_module_7(&result_object); +} +fn create_module_8() -> ResultObject { let module_str = "(module (type (;0;) (func (result i32))) (func (;0;) (type 0) (result i32) @@ -173,13 +221,13 @@ fn create_module_6() -> ResultObject { instantiate(wasm_binary, spectest_importobject()).expect("WASM can't be instantiated") } -fn start_module_6(result_object: &ResultObject) { +fn start_module_8(result_object: &ResultObject) { result_object.instance.start(); } -// Line 83 -fn c6_l83_action_invoke(result_object: &ResultObject) { - println!("Executing function {}", "c6_l83_action_invoke"); +// Line 81 +fn c8_l81_action_invoke(result_object: &ResultObject) { + println!("Executing function {}", "c8_l81_action_invoke"); let func_index = match result_object.module.info.exports.get("call-7") { Some(&Export::Function(index)) => index, _ => panic!("Function not found"), @@ -189,9 +237,9 @@ fn c6_l83_action_invoke(result_object: &ResultObject) { assert_eq!(result, 65 as i32); } -// Line 84 -fn c7_l84_action_invoke(result_object: &ResultObject) { - println!("Executing function {}", "c7_l84_action_invoke"); +// Line 82 +fn c9_l82_action_invoke(result_object: &ResultObject) { + println!("Executing function {}", "c9_l82_action_invoke"); let func_index = match result_object.module.info.exports.get("call-9") { Some(&Export::Function(index)) => index, _ => panic!("Function not found"), @@ -201,17 +249,17 @@ fn c7_l84_action_invoke(result_object: &ResultObject) { assert_eq!(result, 66 as i32); } -// Line 88 +// Line 86 #[test] -fn test_module_6() { - let result_object = create_module_6(); +fn test_module_8() { + let result_object = create_module_8(); // We group the calls together - start_module_6(&result_object); - c6_l83_action_invoke(&result_object); - c7_l84_action_invoke(&result_object); + start_module_8(&result_object); + c8_l81_action_invoke(&result_object); + c9_l82_action_invoke(&result_object); } -fn create_module_7() -> ResultObject { +fn create_module_9() -> ResultObject { let module_str = "(module (type (;0;) (func)) (func (;0;) (type 0)) @@ -222,19 +270,19 @@ fn create_module_7() -> ResultObject { instantiate(wasm_binary, spectest_importobject()).expect("WASM can't be instantiated") } -fn start_module_7(result_object: &ResultObject) { +fn start_module_9(result_object: &ResultObject) { result_object.instance.start(); } -// Line 93 +// Line 91 #[test] -fn test_module_7() { - let result_object = create_module_7(); +fn test_module_9() { + let result_object = create_module_9(); // We group the calls together - start_module_7(&result_object); + start_module_9(&result_object); } -fn create_module_8() -> ResultObject { +fn create_module_10() -> ResultObject { let module_str = "(module (type (;0;) (func)) (import \"spectest\" \"table\" (table (;0;) 10 anyfunc)) @@ -245,53 +293,11 @@ fn create_module_8() -> ResultObject { instantiate(wasm_binary, spectest_importobject()).expect("WASM can't be instantiated") } -fn start_module_8(result_object: &ResultObject) { - result_object.instance.start(); -} - -// Line 99 - -#[test] -fn test_module_8() { - let result_object = create_module_8(); - // We group the calls together - start_module_8(&result_object); -} -fn create_module_9() -> ResultObject { - let module_str = "(module - (table (;0;) 0 anyfunc) - (elem (;0;) (i32.const 0))) - "; - let wasm_binary = wat2wasm(module_str.as_bytes()).expect("WAST not valid or malformed"); - instantiate(wasm_binary, spectest_importobject()).expect("WASM can't be instantiated") -} - -fn start_module_9(result_object: &ResultObject) { - result_object.instance.start(); -} - -// Line 103 - -#[test] -fn test_module_9() { - let result_object = create_module_9(); - // We group the calls together - start_module_9(&result_object); -} -fn create_module_10() -> ResultObject { - let module_str = "(module - (import \"spectest\" \"table\" (table (;0;) 0 anyfunc)) - (elem (;0;) (i32.const 0))) - "; - let wasm_binary = wat2wasm(module_str.as_bytes()).expect("WAST not valid or malformed"); - instantiate(wasm_binary, spectest_importobject()).expect("WASM can't be instantiated") -} - fn start_module_10(result_object: &ResultObject) { result_object.instance.start(); } -// Line 108 +// Line 97 #[test] fn test_module_10() { @@ -301,7 +307,7 @@ fn test_module_10() { } fn create_module_11() -> ResultObject { let module_str = "(module - (table (;0;) 0 0 anyfunc) + (table (;0;) 0 anyfunc) (elem (;0;) (i32.const 0))) "; let wasm_binary = wat2wasm(module_str.as_bytes()).expect("WAST not valid or malformed"); @@ -312,7 +318,7 @@ fn start_module_11(result_object: &ResultObject) { result_object.instance.start(); } -// Line 113 +// Line 101 #[test] fn test_module_11() { @@ -322,8 +328,8 @@ fn test_module_11() { } fn create_module_12() -> ResultObject { let module_str = "(module - (table (;0;) 20 anyfunc) - (elem (;0;) (i32.const 20))) + (import \"spectest\" \"table\" (table (;0;) 0 anyfunc)) + (elem (;0;) (i32.const 0))) "; let wasm_binary = wat2wasm(module_str.as_bytes()).expect("WAST not valid or malformed"); instantiate(wasm_binary, spectest_importobject()).expect("WASM can't be instantiated") @@ -333,7 +339,7 @@ fn start_module_12(result_object: &ResultObject) { result_object.instance.start(); } -// Line 118 +// Line 106 #[test] fn test_module_12() { @@ -343,10 +349,8 @@ fn test_module_12() { } fn create_module_13() -> ResultObject { let module_str = "(module - (type (;0;) (func)) - (import \"spectest\" \"table\" (table (;0;) 0 anyfunc)) - (func (;0;) (type 0)) - (elem (;0;) (i32.const 0) 0)) + (table (;0;) 0 0 anyfunc) + (elem (;0;) (i32.const 0))) "; let wasm_binary = wat2wasm(module_str.as_bytes()).expect("WAST not valid or malformed"); instantiate(wasm_binary, spectest_importobject()).expect("WASM can't be instantiated") @@ -356,7 +360,7 @@ fn start_module_13(result_object: &ResultObject) { result_object.instance.start(); } -// Line 124 +// Line 111 #[test] fn test_module_13() { @@ -366,10 +370,8 @@ fn test_module_13() { } fn create_module_14() -> ResultObject { let module_str = "(module - (type (;0;) (func)) - (import \"spectest\" \"table\" (table (;0;) 0 100 anyfunc)) - (func (;0;) (type 0)) - (elem (;0;) (i32.const 0) 0)) + (table (;0;) 20 anyfunc) + (elem (;0;) (i32.const 20))) "; let wasm_binary = wat2wasm(module_str.as_bytes()).expect("WAST not valid or malformed"); instantiate(wasm_binary, spectest_importobject()).expect("WASM can't be instantiated") @@ -379,7 +381,7 @@ fn start_module_14(result_object: &ResultObject) { result_object.instance.start(); } -// Line 130 +// Line 116 #[test] fn test_module_14() { @@ -392,7 +394,7 @@ fn create_module_15() -> ResultObject { (type (;0;) (func)) (import \"spectest\" \"table\" (table (;0;) 0 anyfunc)) (func (;0;) (type 0)) - (elem (;0;) (i32.const 1) 0)) + (elem (;0;) (i32.const 0) 0)) "; let wasm_binary = wat2wasm(module_str.as_bytes()).expect("WAST not valid or malformed"); instantiate(wasm_binary, spectest_importobject()).expect("WASM can't be instantiated") @@ -402,7 +404,7 @@ fn start_module_15(result_object: &ResultObject) { result_object.instance.start(); } -// Line 136 +// Line 122 #[test] fn test_module_15() { @@ -413,9 +415,9 @@ fn test_module_15() { fn create_module_16() -> ResultObject { let module_str = "(module (type (;0;) (func)) - (import \"spectest\" \"table\" (table (;0;) 0 30 anyfunc)) + (import \"spectest\" \"table\" (table (;0;) 0 100 anyfunc)) (func (;0;) (type 0)) - (elem (;0;) (i32.const 1) 0)) + (elem (;0;) (i32.const 0) 0)) "; let wasm_binary = wat2wasm(module_str.as_bytes()).expect("WAST not valid or malformed"); instantiate(wasm_binary, spectest_importobject()).expect("WASM can't be instantiated") @@ -425,79 +427,7 @@ fn start_module_16(result_object: &ResultObject) { result_object.instance.start(); } -// Line 145 - -// Line 154 - -// Line 163 - -// Line 172 - -// Line 180 - -// Line 188 - -// Line 197 - -// Line 205 - -// Line 214 - -// Line 222 - -// Line 231 - -// Line 239 - -// Line 250 -#[test] -fn c30_l250_assert_invalid() { - let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 1, 4, 1, 96, 0, 0, 3, 2, 1, 0, 9, 7, 1, 0, 65, 0, 11, 1, 0, 10, 4, 1, 2, 0, 11]; - let compilation = compile(wasm_binary.to_vec()); - assert!(compilation.is_err(), "WASM should not compile as is invalid"); -} - -// Line 260 -#[test] -fn c31_l260_assert_invalid() { - let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 4, 4, 1, 112, 0, 1, 9, 6, 1, 0, 66, 0, 11, 0]; - let compilation = compile(wasm_binary.to_vec()); - assert!(compilation.is_err(), "WASM should not compile as is invalid"); -} - -// Line 268 -#[test] -fn c32_l268_assert_invalid() { - let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 4, 4, 1, 112, 0, 1, 9, 7, 1, 0, 65, 0, 104, 11, 0]; - let compilation = compile(wasm_binary.to_vec()); - assert!(compilation.is_err(), "WASM should not compile as is invalid"); -} - -// Line 276 -#[test] -fn c33_l276_assert_invalid() { - let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 4, 4, 1, 112, 0, 1, 9, 5, 1, 0, 1, 11, 0]; - let compilation = compile(wasm_binary.to_vec()); - assert!(compilation.is_err(), "WASM should not compile as is invalid"); -} - -// Line 284 -#[test] -fn c34_l284_assert_invalid() { - let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 4, 4, 1, 112, 0, 1, 9, 7, 1, 0, 1, 65, 0, 11, 0]; - let compilation = compile(wasm_binary.to_vec()); - assert!(compilation.is_err(), "WASM should not compile as is invalid"); -} - -// Line 292 -#[test] -fn c35_l292_assert_invalid() { - let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 4, 4, 1, 112, 0, 1, 9, 7, 1, 0, 65, 0, 1, 11, 0]; - let compilation = compile(wasm_binary.to_vec()); - assert!(compilation.is_err(), "WASM should not compile as is invalid"); -} - -// Line 307 +// Line 128 #[test] fn test_module_16() { @@ -506,6 +436,124 @@ fn test_module_16() { start_module_16(&result_object); } fn create_module_17() -> ResultObject { + let module_str = "(module + (type (;0;) (func)) + (import \"spectest\" \"table\" (table (;0;) 0 anyfunc)) + (func (;0;) (type 0)) + (elem (;0;) (i32.const 1) 0)) + "; + let wasm_binary = wat2wasm(module_str.as_bytes()).expect("WAST not valid or malformed"); + instantiate(wasm_binary, spectest_importobject()).expect("WASM can't be instantiated") +} + +fn start_module_17(result_object: &ResultObject) { + result_object.instance.start(); +} + +// Line 134 + +#[test] +fn test_module_17() { + let result_object = create_module_17(); + // We group the calls together + start_module_17(&result_object); +} +fn create_module_18() -> ResultObject { + let module_str = "(module + (type (;0;) (func)) + (import \"spectest\" \"table\" (table (;0;) 0 30 anyfunc)) + (func (;0;) (type 0)) + (elem (;0;) (i32.const 1) 0)) + "; + let wasm_binary = wat2wasm(module_str.as_bytes()).expect("WAST not valid or malformed"); + instantiate(wasm_binary, spectest_importobject()).expect("WASM can't be instantiated") +} + +fn start_module_18(result_object: &ResultObject) { + result_object.instance.start(); +} + +// Line 143 + +// Line 152 + +// Line 161 + +// Line 170 + +// Line 178 + +// Line 186 + +// Line 195 + +// Line 203 + +// Line 212 + +// Line 220 + +// Line 229 + +// Line 237 + +// Line 248 +#[test] +fn c32_l248_assert_invalid() { + let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 1, 4, 1, 96, 0, 0, 3, 2, 1, 0, 9, 7, 1, 0, 65, 0, 11, 1, 0, 10, 4, 1, 2, 0, 11]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is invalid"); +} + +// Line 258 +#[test] +fn c33_l258_assert_invalid() { + let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 4, 4, 1, 112, 0, 1, 9, 6, 1, 0, 66, 0, 11, 0]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is invalid"); +} + +// Line 266 +#[test] +fn c34_l266_assert_invalid() { + let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 4, 4, 1, 112, 0, 1, 9, 7, 1, 0, 65, 0, 104, 11, 0]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is invalid"); +} + +// Line 274 +#[test] +fn c35_l274_assert_invalid() { + let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 4, 4, 1, 112, 0, 1, 9, 5, 1, 0, 1, 11, 0]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is invalid"); +} + +// Line 282 +#[test] +fn c36_l282_assert_invalid() { + let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 4, 4, 1, 112, 0, 1, 9, 7, 1, 0, 1, 65, 0, 11, 0]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is invalid"); +} + +// Line 290 +#[test] +fn c37_l290_assert_invalid() { + let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 4, 4, 1, 112, 0, 1, 9, 7, 1, 0, 65, 0, 1, 11, 0]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is invalid"); +} + +// Line 305 + +#[test] +fn test_module_18() { + let result_object = create_module_18(); + // We group the calls together + start_module_18(&result_object); +} +fn create_module_19() -> ResultObject { let module_str = "(module (type (;0;) (func (result i32))) (func (;0;) (type 0) (result i32) @@ -524,13 +572,13 @@ fn create_module_17() -> ResultObject { instantiate(wasm_binary, spectest_importobject()).expect("WASM can't be instantiated") } -fn start_module_17(result_object: &ResultObject) { +fn start_module_19(result_object: &ResultObject) { result_object.instance.start(); } -// Line 318 -fn c37_l318_action_invoke(result_object: &ResultObject) { - println!("Executing function {}", "c37_l318_action_invoke"); +// Line 316 +fn c39_l316_action_invoke(result_object: &ResultObject) { + println!("Executing function {}", "c39_l316_action_invoke"); let func_index = match result_object.module.info.exports.get("call-overwritten") { Some(&Export::Function(index)) => index, _ => panic!("Function not found"), @@ -540,16 +588,16 @@ fn c37_l318_action_invoke(result_object: &ResultObject) { assert_eq!(result, 66 as i32); } -// Line 320 +// Line 318 #[test] -fn test_module_17() { - let result_object = create_module_17(); +fn test_module_19() { + let result_object = create_module_19(); // We group the calls together - start_module_17(&result_object); - c37_l318_action_invoke(&result_object); + start_module_19(&result_object); + c39_l316_action_invoke(&result_object); } -fn create_module_18() -> ResultObject { +fn create_module_20() -> ResultObject { let module_str = "(module (type (;0;) (func (result i32))) (import \"spectest\" \"table\" (table (;0;) 10 anyfunc)) @@ -568,13 +616,13 @@ fn create_module_18() -> ResultObject { instantiate(wasm_binary, spectest_importobject()).expect("WASM can't be instantiated") } -fn start_module_18(result_object: &ResultObject) { +fn start_module_20(result_object: &ResultObject) { result_object.instance.start(); } -// Line 331 -fn c39_l331_action_invoke(result_object: &ResultObject) { - println!("Executing function {}", "c39_l331_action_invoke"); +// Line 329 +fn c41_l329_action_invoke(result_object: &ResultObject) { + println!("Executing function {}", "c41_l329_action_invoke"); let func_index = match result_object.module.info.exports.get("call-overwritten-element") { Some(&Export::Function(index)) => index, _ => panic!("Function not found"), @@ -584,16 +632,16 @@ fn c39_l331_action_invoke(result_object: &ResultObject) { assert_eq!(result, 66 as i32); } -// Line 335 +// Line 333 #[test] -fn test_module_18() { - let result_object = create_module_18(); +fn test_module_20() { + let result_object = create_module_20(); // We group the calls together - start_module_18(&result_object); - c39_l331_action_invoke(&result_object); + start_module_20(&result_object); + c41_l329_action_invoke(&result_object); } -fn create_module_19() -> ResultObject { +fn create_module_21() -> ResultObject { let module_str = "(module (type (;0;) (func (result i32))) (func (;0;) (type 0) (result i32) @@ -621,69 +669,62 @@ fn create_module_19() -> ResultObject { instantiate(wasm_binary, spectest_importobject()).expect("WASM can't be instantiated") } -fn start_module_19(result_object: &ResultObject) { - result_object.instance.start(); -} - -// Line 353 - -// Line 360 - -#[test] -fn test_module_19() { - let result_object = create_module_19(); - // We group the calls together - start_module_19(&result_object); -} -fn create_module_20() -> ResultObject { - let module_str = "(module - (type (;0;) (func (result i32))) - (import \"module1\" \"shared-table\" (table (;0;) 10 anyfunc)) - (func (;0;) (type 0) (result i32) - i32.const 67) - (func (;1;) (type 0) (result i32) - i32.const 68) - (elem (;0;) (i32.const 7) 0) - (elem (;1;) (i32.const 8) 1)) - "; - let wasm_binary = wat2wasm(module_str.as_bytes()).expect("WAST not valid or malformed"); - instantiate(wasm_binary, spectest_importobject()).expect("WASM can't be instantiated") -} - -fn start_module_20(result_object: &ResultObject) { - result_object.instance.start(); -} - -// Line 374 - -#[test] -fn test_module_20() { - let result_object = create_module_20(); - // We group the calls together - start_module_20(&result_object); -} -fn create_module_21() -> ResultObject { - let module_str = "(module - (type (;0;) (func (result i32))) - (import \"module1\" \"shared-table\" (table (;0;) 10 anyfunc)) - (func (;0;) (type 0) (result i32) - i32.const 69) - (func (;1;) (type 0) (result i32) - i32.const 70) - (elem (;0;) (i32.const 8) 0) - (elem (;1;) (i32.const 9) 1)) - "; - let wasm_binary = wat2wasm(module_str.as_bytes()).expect("WAST not valid or malformed"); - instantiate(wasm_binary, spectest_importobject()).expect("WASM can't be instantiated") -} - fn start_module_21(result_object: &ResultObject) { result_object.instance.start(); } +// Line 351 + +// Line 353 +fn c44_l353_action_invoke(result_object: &ResultObject) { + println!("Executing function {}", "c44_l353_action_invoke"); + let func_index = match result_object.module.info.exports.get("call-7") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(&Instance) = get_instance_function!(result_object.instance, func_index); + let result = invoke_fn(&result_object.instance); + +} + +#[test] +fn c44_l353_assert_trap() { + let result_object = create_module_21(); + let result = panic::catch_unwind(|| { + c44_l353_action_invoke(&result_object); + }); + assert!(result.is_err()); +} + +// Line 354 +fn c45_l354_action_invoke(result_object: &ResultObject) { + println!("Executing function {}", "c45_l354_action_invoke"); + let func_index = match result_object.module.info.exports.get("call-8") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(&Instance) -> i32 = get_instance_function!(result_object.instance, func_index); + let result = invoke_fn(&result_object.instance); + assert_eq!(result, 65 as i32); +} + +// Line 355 +fn c46_l355_action_invoke(result_object: &ResultObject) { + println!("Executing function {}", "c46_l355_action_invoke"); + let func_index = match result_object.module.info.exports.get("call-9") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(&Instance) -> i32 = get_instance_function!(result_object.instance, func_index); + let result = invoke_fn(&result_object.instance); + assert_eq!(result, 66 as i32); +} + #[test] fn test_module_21() { let result_object = create_module_21(); // We group the calls together start_module_21(&result_object); + c45_l354_action_invoke(&result_object); + c46_l355_action_invoke(&result_object); } diff --git a/src/spectests/globals.rs b/src/spectests/globals.rs index 53a35ded6..31cbf47d9 100644 --- a/src/spectests/globals.rs +++ b/src/spectests/globals.rs @@ -907,44 +907,36 @@ fn c54_l286_assert_invalid() { // Line 291 #[test] fn c55_l291_assert_invalid() { + let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 6, 11, 2, 127, 0, 65, 0, 11, 126, 0, 35, 1, 11]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is invalid"); +} + +// Line 297 +#[test] +fn c56_l297_assert_invalid() { let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 6, 4, 1, 127, 0, 11]; let compilation = compile(wasm_binary.to_vec()); assert!(compilation.is_err(), "WASM should not compile as is invalid"); } -// Line 296 +// Line 302 #[test] -fn c56_l296_assert_invalid() { +fn c57_l302_assert_invalid() { let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 6, 6, 1, 127, 0, 35, 0, 11]; let compilation = compile(wasm_binary.to_vec()); assert!(compilation.is_err(), "WASM should not compile as is invalid"); } -// Line 301 +// Line 307 #[test] -fn c57_l301_assert_invalid() { +fn c58_l307_assert_invalid() { let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 6, 11, 2, 127, 0, 35, 1, 11, 127, 0, 65, 0, 11]; let compilation = compile(wasm_binary.to_vec()); assert!(compilation.is_err(), "WASM should not compile as is invalid"); } // Line 311 -#[test] -fn c58_l311_assert_malformed() { - let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 2, 148, 128, 128, 128, 0, 1, 8, 115, 112, 101, 99, 116, 101, 115, 116, 10, 103, 108, 111, 98, 97, 108, 95, 105, 51, 50, 3, 127, 2]; - let compilation = compile(wasm_binary.to_vec()); - assert!(compilation.is_err(), "WASM should not compile as is malformed"); -} - -// Line 324 -#[test] -fn c59_l324_assert_malformed() { - let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 2, 148, 128, 128, 128, 0, 1, 8, 115, 112, 101, 99, 116, 101, 115, 116, 10, 103, 108, 111, 98, 97, 108, 95, 105, 51, 50, 3, 127, 255]; - let compilation = compile(wasm_binary.to_vec()); - assert!(compilation.is_err(), "WASM should not compile as is malformed"); -} - -// Line 337 #[test] fn test_module_1() { @@ -999,7 +991,15 @@ fn test_module_1() { } fn create_module_2() -> ResultObject { let module_str = "(module - (global (;0;) i32 (i32.const 0))) + (type (;0;) (func (result i32))) + (import \"spectest\" \"global_i32\" (global (;0;) i32)) + (func (;0;) (type 0) (result i32) + get_global 0) + (func (;1;) (type 0) (result i32) + get_global 1) + (global (;1;) i32 (get_global 0)) + (export \"get-0\" (func 0)) + (export \"get-0-ref\" (func 1))) "; let wasm_binary = wat2wasm(module_str.as_bytes()).expect("WAST not valid or malformed"); instantiate(wasm_binary, spectest_importobject()).expect("WASM can't be instantiated") @@ -1009,25 +1009,87 @@ fn start_module_2(result_object: &ResultObject) { result_object.instance.start(); } -// Line 341 +// Line 318 +fn c60_l318_action_invoke(result_object: &ResultObject) { + println!("Executing function {}", "c60_l318_action_invoke"); + let func_index = match result_object.module.info.exports.get("get-0") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(&Instance) -> i32 = get_instance_function!(result_object.instance, func_index); + let result = invoke_fn(&result_object.instance); + assert_eq!(result, 666 as i32); +} + +// Line 319 +fn c61_l319_action_invoke(result_object: &ResultObject) { + println!("Executing function {}", "c61_l319_action_invoke"); + let func_index = match result_object.module.info.exports.get("get-0-ref") { + Some(&Export::Function(index)) => index, + _ => panic!("Function not found"), + }; + let invoke_fn: fn(&Instance) -> i32 = get_instance_function!(result_object.instance, func_index); + let result = invoke_fn(&result_object.instance); + assert_eq!(result, 666 as i32); +} + +// Line 322 #[test] -fn c61_l341_assert_malformed() { - let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 6, 134, 128, 128, 128, 0, 1, 127, 2, 65, 0, 11]; +fn c62_l322_assert_malformed() { + let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 2, 148, 128, 128, 128, 0, 1, 8, 115, 112, 101, 99, 116, 101, 115, 116, 10, 103, 108, 111, 98, 97, 108, 95, 105, 51, 50, 3, 127, 2]; let compilation = compile(wasm_binary.to_vec()); assert!(compilation.is_err(), "WASM should not compile as is malformed"); } -// Line 353 +// Line 335 #[test] -fn c62_l353_assert_malformed() { - let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 6, 134, 128, 128, 128, 0, 1, 127, 255, 65, 0, 11]; +fn c63_l335_assert_malformed() { + let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 2, 148, 128, 128, 128, 0, 1, 8, 115, 112, 101, 99, 116, 101, 115, 116, 10, 103, 108, 111, 98, 97, 108, 95, 105, 51, 50, 3, 127, 255]; let compilation = compile(wasm_binary.to_vec()); assert!(compilation.is_err(), "WASM should not compile as is malformed"); } +// Line 348 + #[test] fn test_module_2() { let result_object = create_module_2(); // We group the calls together start_module_2(&result_object); + c60_l318_action_invoke(&result_object); + c61_l319_action_invoke(&result_object); +} +fn create_module_3() -> ResultObject { + let module_str = "(module + (global (;0;) i32 (i32.const 0))) + "; + let wasm_binary = wat2wasm(module_str.as_bytes()).expect("WAST not valid or malformed"); + instantiate(wasm_binary, spectest_importobject()).expect("WASM can't be instantiated") +} + +fn start_module_3(result_object: &ResultObject) { + result_object.instance.start(); +} + +// Line 352 +#[test] +fn c65_l352_assert_malformed() { + let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 6, 134, 128, 128, 128, 0, 1, 127, 2, 65, 0, 11]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is malformed"); +} + +// Line 364 +#[test] +fn c66_l364_assert_malformed() { + let wasm_binary = [0, 97, 115, 109, 1, 0, 0, 0, 6, 134, 128, 128, 128, 0, 1, 127, 255, 65, 0, 11]; + let compilation = compile(wasm_binary.to_vec()); + assert!(compilation.is_err(), "WASM should not compile as is malformed"); +} + +#[test] +fn test_module_3() { + let result_object = create_module_3(); + // We group the calls together + start_module_3(&result_object); } diff --git a/src/webassembly/instance.rs b/src/webassembly/instance.rs index 99393b7a1..aa48cf6d4 100644 --- a/src/webassembly/instance.rs +++ b/src/webassembly/instance.rs @@ -6,16 +6,19 @@ //! synchronously instantiate a given webassembly::Module object. However, the //! primary way to get an Instance is through the asynchronous //! webassembly::instantiate_streaming() function. -use cranelift_codegen::ir::LibCall; +use cranelift_codegen::ir::{LibCall, Function}; use cranelift_codegen::{binemit, Context}; -use cranelift_entity::EntityRef; -use cranelift_wasm::{FuncIndex, GlobalInit, GlobalIndex}; use cranelift_codegen::isa::TargetIsa; +use cranelift_entity::EntityRef; +use cranelift_wasm::{FuncIndex, GlobalInit}; +use rayon::prelude::*; + use region; use std::iter::Iterator; use std::ptr::write_unaligned; use std::slice; use std::sync::Arc; +use std::iter::FromIterator; use std::mem::size_of; use super::super::common::slice::{BoundedSlice, UncheckedSlice}; @@ -117,6 +120,8 @@ pub struct DataPointers { pub struct InstanceOptions { // Shall we mock automatically the imported functions if they don't exist? pub mock_missing_imports: bool, + pub mock_missing_globals: bool, + pub mock_missing_tables: bool, pub isa: Box, } @@ -124,6 +129,33 @@ extern fn mock_fn() -> i32 { return 0; } +struct CompiledFunction { + code_buf: Vec, + reloc_sink: RelocSink, + trap_sink: binemit::NullTrapSink, +} + +fn compile_function(isa: &TargetIsa, function_body: &Function) -> Result { + let mut func_context = Context::for_function(function_body.to_owned()); + + let mut code_buf: Vec = Vec::new(); + let mut reloc_sink = RelocSink::new(); + let mut trap_sink = binemit::NullTrapSink {}; + + func_context + .compile_and_emit(isa, &mut code_buf, &mut reloc_sink, &mut trap_sink) + .map_err(|e| { + debug!("CompileError: {}", e.to_string()); + ErrorKind::CompileError(e.to_string()) + })?; + + Ok(CompiledFunction { + code_buf, + reloc_sink, + trap_sink + }) +} + impl Instance { pub const TABLES_OFFSET: usize = 0; // 0 on 64-bit | 0 on 32-bit pub const MEMORIES_OFFSET: usize = size_of::(); // 8 on 64-bit | 4 on 32-bit @@ -184,43 +216,28 @@ impl Instance { debug!("Instance - Compiling functions"); // Compile the functions (from cranelift IR to machine code) - for function_body in module.info.function_bodies.values() { - let mut func_context = Context::for_function(function_body.to_owned()); - // func_context - // .verify(&*isa) - // .map_err(|e| ErrorKind::CompileError(e.to_string()))?; - // func_context - // .verify_locations(&*isa) - // .map_err(|e| ErrorKind::CompileError(e.to_string()))?; - // let code_size_offset = func_context - // .compile(&*isa) - // .map_err(|e| ErrorKind::CompileError(e.to_string()))?; - // as usize; + let values: Vec<&Function> = Vec::from_iter(module.info.function_bodies.values()); + // let isa: &TargetIsa = &*options.isa; + let compiled_funcs: Vec = values.par_iter().map(|function_body| -> CompiledFunction { + // let r = *Arc::from_raw(isa_ptr); + compile_function(&*options.isa, function_body).unwrap() + // unimplemented!() + }).collect(); - let mut code_buf: Vec = Vec::new(); - let mut reloc_sink = RelocSink::new(); - let mut trap_sink = binemit::NullTrapSink {}; - // This will compile a cranelift ir::Func into a code buffer (stored in memory) - // and will push any inner function calls to the reloc sync. - // In case traps need to be triggered, they will go to trap_sink - func_context - .compile_and_emit(&*options.isa, &mut code_buf, &mut reloc_sink, &mut trap_sink) - .map_err(|e| { - debug!("CompileError: {}", e.to_string()); - ErrorKind::CompileError(e.to_string()) - })?; - // We set this code_buf to be readable & executable + for compiled_func in compiled_funcs.into_iter() { + let CompiledFunction {code_buf, reloc_sink, ..} = compiled_func; + + + // let func_offset = code_buf; protect_codebuf(&code_buf).unwrap(); - - let func_offset = code_buf; - functions.push(func_offset); + functions.push(code_buf); // context_and_offsets.push(func_context); relocations.push(reloc_sink.func_relocs); - // println!("FUNCTION RELOCATIONS {:?}", reloc_sink.func_relocs) - // total_size += code_size_offset; } + // compiled_funcs?; + debug!("Instance - Relocating functions"); // For each of the functions used, we see what are the calls inside this functions // and relocate each call to the proper memory address. @@ -311,8 +328,8 @@ impl Instance { GlobalInit::I64Const(n) => n, GlobalInit::F32Const(f) => f as _, // unsafe { mem::transmute(f as f64) }, GlobalInit::F64Const(f) => f as _, // unsafe { mem::transmute(f) }, - GlobalInit::GlobalRef(_global_index) => { - unimplemented!("GlobalInit::GlobalRef is not yet supported") + GlobalInit::GlobalRef(global_index) => { + globals_data[global_index.index()] } GlobalInit::Import() => { let (module_name, field_name) = import_name.as_ref().expect("Expected a import name for the global import"); @@ -321,7 +338,17 @@ impl Instance { Some(ImportValue::Global(value)) => { *value }, - _ => panic!("Imported global value was not provided {:?} ({}.{})", imported, module_name, field_name) + None => { + if options.mock_missing_globals { + 0 + } + else { + panic!("Imported global value was not provided ({}.{})", module_name, field_name) + } + }, + _ => { + panic!("Expected global import, but received {:?} ({}.{})", imported, module_name, field_name) + } } } }; @@ -345,7 +372,20 @@ impl Instance { Some(ImportValue::Table(t)) => { t.to_vec() }, - _ => panic!("Imported table was not provided {:?} ({}.{})", imported, module_name, field_name) + None => { + if options.mock_missing_tables { + let len = table.entity.size; + let mut v = Vec::with_capacity(len); + v.resize(len, 0); + v + } + else { + panic!("Imported table value was not provided ({}.{})", module_name, field_name) + } + }, + _ => { + panic!("Expected global table, but received {:?} ({}.{})", imported, module_name, field_name) + } } }, None => { diff --git a/src/webassembly/mod.rs b/src/webassembly/mod.rs index 9e2a2ed01..f60d67861 100644 --- a/src/webassembly/mod.rs +++ b/src/webassembly/mod.rs @@ -58,6 +58,8 @@ pub fn instantiate( import_object, InstanceOptions { mock_missing_imports: true, + mock_missing_globals: true, + mock_missing_tables: true, isa: isa }, )?;